From a7c424550c75bb42f525d9c6d8395b946c8a6442 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Fri, 12 Aug 2022 14:02:11 +0100 Subject: [PATCH] Simply logic around handling runtime reloading of custom components --- packages/client/src/stores/components.js | 66 ++++++++++++------------ 1 file changed, 32 insertions(+), 34 deletions(-) diff --git a/packages/client/src/stores/components.js b/packages/client/src/stores/components.js index 94dd16a957..8512a371d8 100644 --- a/packages/client/src/stores/components.js +++ b/packages/client/src/stores/components.js @@ -12,7 +12,7 @@ const budibasePrefix = "@budibase/standard-components/" const createComponentStore = () => { const store = writable({ customComponentManifest: {}, - componentsAwaitingConstructors: {}, + customComponentMap: {}, mountedComponents: {}, }) @@ -54,30 +54,37 @@ const createComponentStore = () => { const registerInstance = (id, instance) => { store.update(state => { - // If this is a custom component and does not have an implementation yet, - // store so we can reload this component later + // If this is a custom component, flag it so we can reload this component + // later if required const component = instance.component - let cac = state.componentsAwaitingConstructors - if (!getComponentConstructor(component)) { - if (!cac[component]) { - cac[component] = [] + if (component?.startsWith("plugin")) { + if (!state.customComponentMap[component]) { + state.customComponentMap[component] = [id] + } else { + state.customComponentMap[component].push(id) } - cac[component].push(id) } - return { - ...state, - componentsAwaitingConstructors: cac, - mountedComponents: { - ...state.mountedComponents, - [id]: instance, - }, - } + // Register to mounted components + state.mountedComponents[id] = instance + return state }) } const unregisterInstance = id => { 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] return state }) @@ -133,34 +140,25 @@ const createComponentStore = () => { return customComponentManifest?.[type]?.Component } - const registerCustomComponent = ({ Component, schema }) => { + const registerCustomComponent = ({ Component, schema, version }) => { if (!Component || !schema?.schema?.name) { return } - const componentName = `plugin/${schema.schema.name}/1.0.0` + const component = `plugin/${schema.schema.name}/${version}` store.update(state => { - if (!state.customComponentManifest) { - state.customComponentManifest = {} - } - state.customComponentManifest[componentName] = { - schema, + state.customComponentManifest[component] = { Component, + schema, + version, } return state }) - // Reload any mounted components which depend on this definition + // Reload any mounted instances of this custom component const state = get(store) - if (state.componentsAwaitingConstructors[componentName]?.length) { - state.componentsAwaitingConstructors[componentName].forEach(id => { - const instance = state.mountedComponents[id] - if (instance) { - instance.reload() - } - }) - store.update(state => { - delete state.componentsAwaitingConstructors[componentName] - return state + if (state.customComponentMap[component]?.length) { + state.customComponentMap[component].forEach(id => { + state.mountedComponents[id]?.reload() }) } }