diff --git a/packages/client/src/components/Provider.svelte b/packages/client/src/components/Provider.svelte index 3c894f6723..6f56e62abe 100644 --- a/packages/client/src/components/Provider.svelte +++ b/packages/client/src/components/Provider.svelte @@ -11,17 +11,13 @@ // Clone and create new data context for this component tree const context = getContext("context") const component = getContext("component") - const newContext = createContextStore() + const newContext = createContextStore(context) setContext("context", newContext) - let initiated = false $: providerKey = key || $component.id // Add data context - $: { - newContext.actions.provideData(providerKey, $context, data) - initiated = true - } + $: newContext.actions.provideData(providerKey, data) // Instance ID is unique to each instance of a provider let instanceId @@ -56,6 +52,4 @@ }) -{#if initiated} - -{/if} + diff --git a/packages/client/src/store/context.js b/packages/client/src/store/context.js index 5725f94231..e9d307d4f3 100644 --- a/packages/client/src/store/context.js +++ b/packages/client/src/store/context.js @@ -1,20 +1,27 @@ -import { writable } from "svelte/store" +import { writable, derived } from "svelte/store" -export const createContextStore = () => { - const store = writable({}) +export const createContextStore = oldContext => { + const newContext = writable({}) + const contexts = oldContext ? [oldContext, newContext] : [newContext] + const totalContext = derived(contexts, $contexts => { + return $contexts.reduce((total, context) => ({ ...total, ...context }), {}) + }) // Adds a data context layer to the tree - const provideData = (providerId, context, data) => { - let newData = { ...context } - if (providerId && data !== undefined) { - newData[providerId] = data + const provideData = (providerId, data) => { + if (!providerId || data === undefined) { + return + } + newContext.update(state => { + state[providerId] = data // Keep track of the closest component ID so we can later hydrate a "data" prop. // This is only required for legacy bindings that used "data" rather than a // component ID. - newData.closestComponentId = providerId - } - store.set(newData) + state.closestComponentId = providerId + + return state + }) } // Adds an action context layer to the tree @@ -22,14 +29,14 @@ export const createContextStore = () => { if (!providerId || !actionType) { return } - store.update(state => { + newContext.update(state => { state[`${providerId}_${actionType}`] = callback return state }) } return { - subscribe: store.subscribe, + subscribe: totalContext.subscribe, actions: { provideData, provideAction }, } }