Fix reactive store derivation overriding actions

This commit is contained in:
Andrew Kingston 2021-02-10 19:42:56 +00:00
parent fb79a78164
commit 2e9122ca81
2 changed files with 22 additions and 21 deletions

View File

@ -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 @@
})
</script>
{#if initiated}
<slot />
{/if}
<slot />

View File

@ -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 },
}
}