UNPKG

@wordpress/interactivity

Version:

Package that provides a standard and simple way to handle the frontend interactivity of Gutenberg blocks.

129 lines (128 loc) 4.01 kB
// packages/interactivity/src/store.ts import { proxifyState, proxifyStore, deepMerge, peek } from "./proxies"; import { PENDING_GETTER } from "./proxies/state"; import { getNamespace } from "./namespaces"; import { isPlainObject, navigationSignal, deepClone } from "./utils"; var stores = /* @__PURE__ */ new Map(); var rawStores = /* @__PURE__ */ new Map(); var storeLocks = /* @__PURE__ */ new Map(); var storeConfigs = /* @__PURE__ */ new Map(); var serverStates = /* @__PURE__ */ new Map(); var getConfig = (namespace) => storeConfigs.get(namespace || getNamespace()) || {}; function getServerState(namespace) { const ns = namespace || getNamespace(); if (!serverStates.has(ns)) { serverStates.set(ns, {}); } getServerState.subscribe = navigationSignal.value; return deepClone(serverStates.get(ns)); } getServerState.subscribe = 0; var universalUnlock = "I acknowledge that using a private store means my plugin will inevitably break on the next store release."; function store(namespace, { state = {}, ...block } = {}, { lock = false } = {}) { if (!stores.has(namespace)) { if (lock !== universalUnlock) { storeLocks.set(namespace, lock); } const rawStore = { state: proxifyState( namespace, isPlainObject(state) ? state : {} ), ...block }; const proxifiedStore = proxifyStore(namespace, rawStore); rawStores.set(namespace, rawStore); stores.set(namespace, proxifiedStore); } else { if (lock !== universalUnlock && !storeLocks.has(namespace)) { storeLocks.set(namespace, lock); } else { const storeLock = storeLocks.get(namespace); const isLockValid = lock === universalUnlock || lock !== true && lock === storeLock; if (!isLockValid) { if (!storeLock) { throw Error("Cannot lock a public store"); } else { throw Error( "Cannot unlock a private store with an invalid lock code" ); } } } const target = rawStores.get(namespace); deepMerge(target, block); deepMerge(target.state, state); } return stores.get(namespace); } var parseServerData = (dom = document) => { const jsonDataScriptTag = ( // Preferred Script Module data passing form dom.getElementById( "wp-script-module-data-@wordpress/interactivity" ) ?? // Legacy form dom.getElementById("wp-interactivity-data") ); if (jsonDataScriptTag?.textContent) { try { return JSON.parse(jsonDataScriptTag.textContent); } catch { } } return {}; }; var populateServerData = (data2) => { serverStates.clear(); storeConfigs.clear(); if (isPlainObject(data2?.state)) { Object.entries(data2.state).forEach(([namespace, state]) => { const st = store(namespace, {}, { lock: universalUnlock }); deepMerge(st.state, state, false); serverStates.set(namespace, state); }); } if (isPlainObject(data2?.config)) { Object.entries(data2.config).forEach(([namespace, config]) => { storeConfigs.set(namespace, config); }); } if (isPlainObject(data2?.derivedStateClosures)) { Object.entries(data2.derivedStateClosures).forEach( ([namespace, paths]) => { const st = store( namespace, {}, { lock: universalUnlock } ); paths.forEach((path) => { const pathParts = path.split("."); const prop = pathParts.splice(-1, 1)[0]; const parent = pathParts.reduce( (prev, key) => peek(prev, key), st ); const desc = Object.getOwnPropertyDescriptor( parent, prop ); if (isPlainObject(desc?.value)) { parent[prop] = PENDING_GETTER; } }); } ); } }; var data = parseServerData(); populateServerData(data); export { getConfig, getServerState, parseServerData, populateServerData, store, stores, universalUnlock }; //# sourceMappingURL=store.js.map