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