From 17953d95b07cdc140d5cbad98bb585fcd572cde1 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 13 Mar 2024 18:52:11 +0100 Subject: [PATCH] Ensure stores exist for vdom namespaces --- packages/interactivity/src/init.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/packages/interactivity/src/init.js b/packages/interactivity/src/init.js index fb510a9c00fce..7575f8827676d 100644 --- a/packages/interactivity/src/init.js +++ b/packages/interactivity/src/init.js @@ -8,6 +8,7 @@ import { hydrate } from 'preact'; import { toVdom, hydratedIslands } from './vdom'; import { createRootFragment } from './utils'; import { directivePrefix } from './constants'; +import { store, stores, universalUnlock } from './store'; // Keep the same root fragment for each interactive region node. const regionRootFragments = new WeakMap(); @@ -33,10 +34,29 @@ export const initialVdom = new WeakMap(); // Initialize the router with the initial DOM. export const init = async () => { + /** @type { NodeListOf} */ const nodes = document.querySelectorAll( `[data-${ directivePrefix }-interactive]` ); + for ( const node of nodes ) { + // Before initializing the vdom, make sure a store exists for the namespace. + // This ensures that directives can subscribe to the store even if it has + // not yet been created on the client so that directives can be updated when + // stores are later created. + let namespace = /** @type {HTMLElement} */ ( node ).dataset[ + `${ directivePrefix }Interactive` + ]; + try { + namespace = JSON.parse( namespace ).namespace; + } catch {} + if ( ! stores.has( namespace ) ) { + store( namespace, undefined, { + lock: universalUnlock, + } ); + } + } + for ( const node of nodes ) { if ( ! hydratedIslands.has( node ) ) { await yieldToMain();