WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content
Open
Changes from 12 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
5871a71
app js edited
SpliiT Nov 25, 2025
ab5e187
App.js changes
SpliiT Nov 26, 2025
9e4a435
changes app.js
SpliiT Nov 26, 2025
2f9743c
Merge branch 'next' of https://github.com/Geode-solutions/OpenGeodeWe…
SpliiT Nov 26, 2025
c337845
app.js changes
SpliiT Nov 26, 2025
28250e1
aoi
SpliiT Nov 26, 2025
9afa9d0
rm app.js from stores out of /app
SpliiT Nov 26, 2025
76e949b
change log
SpliiT Nov 27, 2025
68c5a44
rm comments
SpliiT Nov 27, 2025
374a4f6
transform code
SpliiT Nov 27, 2025
f7d45e9
move logic & refacto
SpliiT Nov 28, 2025
c66dc70
move feature
SpliiT Dec 1, 2025
7a8393e
transformer edit
SpliiT Dec 1, 2025
4302d90
add extensionID
SpliiT Dec 1, 2025
e2a93e1
rm useless extensionID
SpliiT Dec 2, 2025
007e1a6
Merge branch 'next' of https://github.com/Geode-solutions/OpenGeodeWe…
SpliiT Dec 2, 2025
63727d5
Apply prepare changes
SpliiT Dec 2, 2025
5f2c995
from next
SpliiT Dec 5, 2025
45afffd
Apply prepare changes
SpliiT Dec 5, 2025
9bf35d2
backendPath added
MaxNumerique Dec 8, 2025
24d5703
Merge branch 'feat/extensions' of https://github.com/Geode-solutions/…
MaxNumerique Dec 8, 2025
6428818
feat: dynamically adjust chat input textarea rows, character limit, a…
SpliiT Dec 8, 2025
7a70c67
Merge branch 'feat/extensions' of https://github.com/Geode-solutions/…
SpliiT Dec 8, 2025
b145f33
Apply prepare changes
SpliiT Dec 8, 2025
f8e3287
lauchExtensionMicroservice with backendPath
MaxNumerique Dec 8, 2025
a9468f9
test
MaxNumerique Dec 8, 2025
ed49890
demo mode and debug
MaxNumerique Dec 9, 2025
cf06595
Merge branch 'next' of https://github.com/Geode-solutions/OpenGeodeWe…
JulienChampagnol Dec 15, 2025
f2f5355
Apply prepare changes
JulienChampagnol Dec 15, 2025
f34b918
Merge branch 'next' of https://github.com/Geode-solutions/OpenGeodeWe…
JulienChampagnol Dec 31, 2025
809d597
merge
JulienChampagnol Dec 31, 2025
d2776ab
Apply prepare changes
JulienChampagnol Dec 31, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 130 additions & 0 deletions app/stores/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,140 @@ export const useAppStore = defineStore("app", () => {
console.log(`[AppStore] Imported ${importedCount} stores`)
}

const loadedExtensions = ref(new Map())
const extensionAPI = ref(null)

function setExtensionAPI(api) {
extensionAPI.value = api
}

function getExtension(path) {
return loadedExtensions.value.get(path)
}

async function loadExtension(path, codeTransformer = null) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Est-ce que le transformer doit être donné par l'extension ou fourni par OGW?

try {
if (loadedExtensions.value.has(path)) {
console.warn(`[AppStore] Extension already loaded from this path: ${path}`)
throw new Error('This extension file is already loaded')
}

if (!extensionAPI.value) {
throw new Error("Extension API not initialized")
}

let finalURL = path

if (codeTransformer && path.startsWith('blob:')) {
const response = await fetch(path)
const code = await response.text()
const transformedCode = codeTransformer(code)

const newBlob = new Blob([transformedCode], { type: 'application/javascript' })
finalURL = URL.createObjectURL(newBlob)
}

const extensionModule = await import(finalURL)

if (finalURL !== path && finalURL.startsWith('blob:')) {
URL.revokeObjectURL(finalURL)
}

const extensionName = extensionModule.metadata?.name
if (extensionName) {
const alreadyLoaded = Array.from(loadedExtensions.value.values()).find(
ext => ext.metadata?.name === extensionName
)
if (alreadyLoaded) {
console.warn(`[AppStore] Extension "${extensionName}" is already loaded`)
throw new Error(`Extension "${extensionName}" is already loaded.`)
}
}

if (typeof extensionModule.install === 'function') {
await extensionModule.install(extensionAPI.value, path)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tu as besoin de path lors du install ? Ça 'r me semble pas approprié


const extensionData = {
module: extensionModule,
path,
loadedAt: new Date().toISOString(),
metadata: extensionModule.metadata || {},
enabled: true,
}
loadedExtensions.value.set(path, extensionData)

console.log(`[AppStore] Extension loaded successfully: ${path}`)

return extensionModule
} else {
throw new Error('Extension must export an install function')
}
} catch (error) {
console.error(`[AppStore] Failed to load extension from ${path}:`, error)
throw error
}
}

function getLoadedExtensions() {
return Array.from(loadedExtensions.value.values())
}

function unloadExtension(path) {
const extensionData = getExtension(path)
if (!extensionData) return false

if (extensionData.module && typeof extensionData.module.uninstall === 'function') {
try {
extensionData.module.uninstall(extensionAPI.value, path)
console.log(`[AppStore] Extension uninstall called: ${path}`)
} catch (error) {
console.error(`[AppStore] Error calling uninstall for ${path}:`, error)
}
}

if (extensionAPI.value && typeof extensionAPI.value.unregisterToolsByExtension === 'function') {
extensionAPI.value.unregisterToolsByExtension(path)
}

loadedExtensions.value.delete(path)
console.log(`[AppStore] Extension unloaded: ${path}`)
return true
}

function toggleExtension(path) {
const extensionData = getExtension(path)
if (!extensionData) return false

extensionData.enabled = !extensionData.enabled
console.log(`[AppStore] Extension ${extensionData.enabled ? 'enabled' : 'disabled'}: ${path}`)
return extensionData.enabled
}

function setExtensionEnabled(path, enabled) {
const extensionData = getExtension(path)
if (!extensionData) return false

extensionData.enabled = enabled
console.log(`[AppStore] Extension ${enabled ? 'enabled' : 'disabled'}: ${path}`)
return true
}

function getExtensionEnabled(path) {
return getExtension(path)?.enabled ?? false
}

return {
stores,
registerStore,
exportStores,
importStores,
loadedExtensions,
setExtensionAPI,
loadExtension,
getLoadedExtensions,
unloadExtension,
toggleExtension,
setExtensionEnabled,
getExtensionEnabled,
}
})