Simply logic around handling runtime reloading of custom components

This commit is contained in:
Andrew Kingston 2022-08-12 14:02:11 +01:00
parent 860c75c0bc
commit a7c424550c
1 changed files with 32 additions and 34 deletions

View File

@ -12,7 +12,7 @@ const budibasePrefix = "@budibase/standard-components/"
const createComponentStore = () => { const createComponentStore = () => {
const store = writable({ const store = writable({
customComponentManifest: {}, customComponentManifest: {},
componentsAwaitingConstructors: {}, customComponentMap: {},
mountedComponents: {}, mountedComponents: {},
}) })
@ -54,30 +54,37 @@ const createComponentStore = () => {
const registerInstance = (id, instance) => { const registerInstance = (id, instance) => {
store.update(state => { store.update(state => {
// If this is a custom component and does not have an implementation yet, // If this is a custom component, flag it so we can reload this component
// store so we can reload this component later // later if required
const component = instance.component const component = instance.component
let cac = state.componentsAwaitingConstructors if (component?.startsWith("plugin")) {
if (!getComponentConstructor(component)) { if (!state.customComponentMap[component]) {
if (!cac[component]) { state.customComponentMap[component] = [id]
cac[component] = [] } else {
state.customComponentMap[component].push(id)
} }
cac[component].push(id)
} }
return { // Register to mounted components
...state, state.mountedComponents[id] = instance
componentsAwaitingConstructors: cac, return state
mountedComponents: {
...state.mountedComponents,
[id]: instance,
},
}
}) })
} }
const unregisterInstance = id => { const unregisterInstance = id => {
store.update(state => { store.update(state => {
// Remove from custom component map if required
const component = state.mountedComponents[id]?.instance?.component
let customComponentMap = state.customComponentMap
if (component?.startsWith("plugin")) {
customComponentMap[component] = customComponentMap[component].filter(
x => {
return x !== id
}
)
}
// Remove from mounted components
delete state.mountedComponents[id] delete state.mountedComponents[id]
return state return state
}) })
@ -133,34 +140,25 @@ const createComponentStore = () => {
return customComponentManifest?.[type]?.Component return customComponentManifest?.[type]?.Component
} }
const registerCustomComponent = ({ Component, schema }) => { const registerCustomComponent = ({ Component, schema, version }) => {
if (!Component || !schema?.schema?.name) { if (!Component || !schema?.schema?.name) {
return return
} }
const componentName = `plugin/${schema.schema.name}/1.0.0` const component = `plugin/${schema.schema.name}/${version}`
store.update(state => { store.update(state => {
if (!state.customComponentManifest) { state.customComponentManifest[component] = {
state.customComponentManifest = {}
}
state.customComponentManifest[componentName] = {
schema,
Component, Component,
schema,
version,
} }
return state return state
}) })
// Reload any mounted components which depend on this definition // Reload any mounted instances of this custom component
const state = get(store) const state = get(store)
if (state.componentsAwaitingConstructors[componentName]?.length) { if (state.customComponentMap[component]?.length) {
state.componentsAwaitingConstructors[componentName].forEach(id => { state.customComponentMap[component].forEach(id => {
const instance = state.mountedComponents[id] state.mountedComponents[id]?.reload()
if (instance) {
instance.reload()
}
})
store.update(state => {
delete state.componentsAwaitingConstructors[componentName]
return state
}) })
} }
} }