@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
JavaScript
// 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