UNPKG

@wordpress/block-library

Version:
60 lines (59 loc) 1.75 kB
// packages/block-library/src/pattern/recursion-detector.js import { useRegistry } from "@wordpress/data"; var cachedParsers = /* @__PURE__ */ new WeakMap(); function useParsePatternDependencies() { const registry = useRegistry(); if (!cachedParsers.has(registry)) { const deps = /* @__PURE__ */ new Map(); cachedParsers.set( registry, parsePatternDependencies.bind(null, deps) ); } return cachedParsers.get(registry); } function parsePatternDependencies(deps, { name, blocks }) { const queue = [...blocks]; while (queue.length) { const block = queue.shift(); for (const innerBlock of block.innerBlocks ?? []) { queue.unshift(innerBlock); } if (block.name === "core/pattern") { registerDependency(deps, name, block.attributes.slug); } } } function registerDependency(deps, a, b) { if (!deps.has(a)) { deps.set(a, /* @__PURE__ */ new Set()); } deps.get(a).add(b); if (hasCycle(deps, a)) { throw new TypeError( `Pattern ${a} has a circular dependency and cannot be rendered.` ); } } function hasCycle(deps, slug, visitedNodes = /* @__PURE__ */ new Set(), currentPath = /* @__PURE__ */ new Set()) { visitedNodes.add(slug); currentPath.add(slug); const dependencies = deps.get(slug) ?? /* @__PURE__ */ new Set(); for (const dependency of dependencies) { if (!visitedNodes.has(dependency)) { if (hasCycle(deps, dependency, visitedNodes, currentPath)) { return true; } } else if (currentPath.has(dependency)) { return true; } } currentPath.delete(slug); return false; } export { parsePatternDependencies, registerDependency, useParsePatternDependencies }; //# sourceMappingURL=recursion-detector.js.map