@pyric/cli 0.1.0-alpha.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +216 -0
- package/README.md +180 -0
- package/README.md.orig +141 -0
- package/dist/assurance/.generated/conformance-verdicts.d.ts +1071 -0
- package/dist/assurance/.generated/conformance-verdicts.d.ts.map +1 -0
- package/dist/assurance/.generated/conformance-verdicts.js +1070 -0
- package/dist/assurance/.generated/conformance-verdicts.js.map +1 -0
- package/dist/assurance/attachment.d.ts +24 -0
- package/dist/assurance/attachment.d.ts.map +1 -0
- package/dist/assurance/attachment.js +138 -0
- package/dist/assurance/attachment.js.map +1 -0
- package/dist/assurance/browser.d.ts +7 -0
- package/dist/assurance/browser.d.ts.map +1 -0
- package/dist/assurance/browser.js +68 -0
- package/dist/assurance/browser.js.map +1 -0
- package/dist/assurance/campaign.d.ts +41 -0
- package/dist/assurance/campaign.d.ts.map +1 -0
- package/dist/assurance/campaign.js +364 -0
- package/dist/assurance/campaign.js.map +1 -0
- package/dist/assurance/capabilities.d.ts +11 -0
- package/dist/assurance/capabilities.d.ts.map +1 -0
- package/dist/assurance/capabilities.js +282 -0
- package/dist/assurance/capabilities.js.map +1 -0
- package/dist/assurance/cases.d.ts +14 -0
- package/dist/assurance/cases.d.ts.map +1 -0
- package/dist/assurance/cases.js +27 -0
- package/dist/assurance/cases.js.map +1 -0
- package/dist/assurance/index.d.ts +10 -0
- package/dist/assurance/index.d.ts.map +1 -0
- package/dist/assurance/index.js +9 -0
- package/dist/assurance/index.js.map +1 -0
- package/dist/assurance/runner.d.ts +3 -0
- package/dist/assurance/runner.d.ts.map +1 -0
- package/dist/assurance/runner.js +633 -0
- package/dist/assurance/runner.js.map +1 -0
- package/dist/assurance/tool-names.d.ts +4 -0
- package/dist/assurance/tool-names.d.ts.map +1 -0
- package/dist/assurance/tool-names.js +14 -0
- package/dist/assurance/tool-names.js.map +1 -0
- package/dist/assurance/tools.d.ts +19 -0
- package/dist/assurance/tools.d.ts.map +1 -0
- package/dist/assurance/tools.js +737 -0
- package/dist/assurance/tools.js.map +1 -0
- package/dist/assurance/types.d.ts +347 -0
- package/dist/assurance/types.d.ts.map +1 -0
- package/dist/assurance/types.js +7 -0
- package/dist/assurance/types.js.map +1 -0
- package/dist/assurance/validation.d.ts +8 -0
- package/dist/assurance/validation.d.ts.map +1 -0
- package/dist/assurance/validation.js +269 -0
- package/dist/assurance/validation.js.map +1 -0
- package/dist/bridge/client/bridge.d.ts +133 -0
- package/dist/bridge/client/bridge.d.ts.map +1 -0
- package/dist/bridge/client/bridge.js +429 -0
- package/dist/bridge/client/bridge.js.map +1 -0
- package/dist/bridge/client/dispatch.d.ts +41 -0
- package/dist/bridge/client/dispatch.d.ts.map +1 -0
- package/dist/bridge/client/dispatch.js +111 -0
- package/dist/bridge/client/dispatch.js.map +1 -0
- package/dist/bridge/client.d.ts +24 -0
- package/dist/bridge/client.d.ts.map +1 -0
- package/dist/bridge/client.js +26 -0
- package/dist/bridge/client.js.map +1 -0
- package/dist/bridge/protocol.d.ts +227 -0
- package/dist/bridge/protocol.d.ts.map +1 -0
- package/dist/bridge/protocol.js +131 -0
- package/dist/bridge/protocol.js.map +1 -0
- package/dist/bridge/server/audit.d.ts +19 -0
- package/dist/bridge/server/audit.d.ts.map +1 -0
- package/dist/bridge/server/audit.js +46 -0
- package/dist/bridge/server/audit.js.map +1 -0
- package/dist/bridge/server/bridge.d.ts +126 -0
- package/dist/bridge/server/bridge.d.ts.map +1 -0
- package/dist/bridge/server/bridge.js +383 -0
- package/dist/bridge/server/bridge.js.map +1 -0
- package/dist/bridge/server/headless.d.ts +36 -0
- package/dist/bridge/server/headless.d.ts.map +1 -0
- package/dist/bridge/server/headless.js +142 -0
- package/dist/bridge/server/headless.js.map +1 -0
- package/dist/bridge/server/json-schema-to-zod.d.ts +37 -0
- package/dist/bridge/server/json-schema-to-zod.d.ts.map +1 -0
- package/dist/bridge/server/json-schema-to-zod.js +93 -0
- package/dist/bridge/server/json-schema-to-zod.js.map +1 -0
- package/dist/bridge/server/local-bridge.d.ts +33 -0
- package/dist/bridge/server/local-bridge.d.ts.map +1 -0
- package/dist/bridge/server/local-bridge.js +41 -0
- package/dist/bridge/server/local-bridge.js.map +1 -0
- package/dist/bridge/server/logger.d.ts +28 -0
- package/dist/bridge/server/logger.d.ts.map +1 -0
- package/dist/bridge/server/logger.js +42 -0
- package/dist/bridge/server/logger.js.map +1 -0
- package/dist/bridge/server/mcp-contract.d.ts +21 -0
- package/dist/bridge/server/mcp-contract.d.ts.map +1 -0
- package/dist/bridge/server/mcp-contract.js +63 -0
- package/dist/bridge/server/mcp-contract.js.map +1 -0
- package/dist/bridge/server/mcp.d.ts +26 -0
- package/dist/bridge/server/mcp.d.ts.map +1 -0
- package/dist/bridge/server/mcp.js +102 -0
- package/dist/bridge/server/mcp.js.map +1 -0
- package/dist/bridge/server/peer.d.ts +39 -0
- package/dist/bridge/server/peer.d.ts.map +1 -0
- package/dist/bridge/server/peer.js +189 -0
- package/dist/bridge/server/peer.js.map +1 -0
- package/dist/bridge/server/standalone.d.ts +49 -0
- package/dist/bridge/server/standalone.d.ts.map +1 -0
- package/dist/bridge/server/standalone.js +267 -0
- package/dist/bridge/server/standalone.js.map +1 -0
- package/dist/bridge/server/tool-metadata.d.ts +38 -0
- package/dist/bridge/server/tool-metadata.d.ts.map +1 -0
- package/dist/bridge/server/tool-metadata.js +84 -0
- package/dist/bridge/server/tool-metadata.js.map +1 -0
- package/dist/bridge/server.d.ts +21 -0
- package/dist/bridge/server.d.ts.map +1 -0
- package/dist/bridge/server.js +18 -0
- package/dist/bridge/server.js.map +1 -0
- package/dist/cli/can-i-use.d.ts +5 -0
- package/dist/cli/can-i-use.d.ts.map +1 -0
- package/dist/cli/can-i-use.js +49 -0
- package/dist/cli/can-i-use.js.map +1 -0
- package/dist/cli/database-rules.d.ts +43 -0
- package/dist/cli/database-rules.d.ts.map +1 -0
- package/dist/cli/database-rules.js +261 -0
- package/dist/cli/database-rules.js.map +1 -0
- package/dist/cli/dev-runner.d.ts +112 -0
- package/dist/cli/dev-runner.d.ts.map +1 -0
- package/dist/cli/dev-runner.js +239 -0
- package/dist/cli/dev-runner.js.map +1 -0
- package/dist/cli/firebase-json.d.ts +66 -0
- package/dist/cli/firebase-json.d.ts.map +1 -0
- package/dist/cli/firebase-json.js +60 -0
- package/dist/cli/firebase-json.js.map +1 -0
- package/dist/cli/firestore-indexes.d.ts +21 -0
- package/dist/cli/firestore-indexes.d.ts.map +1 -0
- package/dist/cli/firestore-indexes.js +39 -0
- package/dist/cli/firestore-indexes.js.map +1 -0
- package/dist/cli/index.d.ts +56 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +387 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init.d.ts +50 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +182 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/mcp-proxy.d.ts +10 -0
- package/dist/cli/mcp-proxy.d.ts.map +1 -0
- package/dist/cli/mcp-proxy.js +129 -0
- package/dist/cli/mcp-proxy.js.map +1 -0
- package/dist/cli/parse-args.d.ts +20 -0
- package/dist/cli/parse-args.d.ts.map +1 -0
- package/dist/cli/parse-args.js +74 -0
- package/dist/cli/parse-args.js.map +1 -0
- package/dist/cli/rules.d.ts +55 -0
- package/dist/cli/rules.d.ts.map +1 -0
- package/dist/cli/rules.js +199 -0
- package/dist/cli/rules.js.map +1 -0
- package/dist/cli/scope.d.ts +12 -0
- package/dist/cli/scope.d.ts.map +1 -0
- package/dist/cli/scope.js +44 -0
- package/dist/cli/scope.js.map +1 -0
- package/dist/cli/serve.d.ts +122 -0
- package/dist/cli/serve.d.ts.map +1 -0
- package/dist/cli/serve.js +844 -0
- package/dist/cli/serve.js.map +1 -0
- package/dist/cli/service-commands.d.ts +8 -0
- package/dist/cli/service-commands.d.ts.map +1 -0
- package/dist/cli/service-commands.js +58 -0
- package/dist/cli/service-commands.js.map +1 -0
- package/dist/cli/snapshot.d.ts +22 -0
- package/dist/cli/snapshot.d.ts.map +1 -0
- package/dist/cli/snapshot.js +139 -0
- package/dist/cli/snapshot.js.map +1 -0
- package/dist/cli/storage-rules.d.ts +21 -0
- package/dist/cli/storage-rules.d.ts.map +1 -0
- package/dist/cli/storage-rules.js +121 -0
- package/dist/cli/storage-rules.js.map +1 -0
- package/dist/cli/verify.d.ts +23 -0
- package/dist/cli/verify.d.ts.map +1 -0
- package/dist/cli/verify.js +349 -0
- package/dist/cli/verify.js.map +1 -0
- package/dist/conformance/.generated/can-i-use-browser.d.ts +44 -0
- package/dist/conformance/.generated/can-i-use-browser.d.ts.map +1 -0
- package/dist/conformance/.generated/can-i-use-browser.js +67 -0
- package/dist/conformance/.generated/can-i-use-browser.js.map +1 -0
- package/dist/conformance/.generated/can-i-use.d.ts +61 -0
- package/dist/conformance/.generated/can-i-use.d.ts.map +1 -0
- package/dist/conformance/.generated/can-i-use.js +68 -0
- package/dist/conformance/.generated/can-i-use.js.map +1 -0
- package/dist/conformance/browser.d.ts +7 -0
- package/dist/conformance/browser.d.ts.map +1 -0
- package/dist/conformance/browser.js +8 -0
- package/dist/conformance/browser.js.map +1 -0
- package/dist/conformance/can-i-use-tool.d.ts +21 -0
- package/dist/conformance/can-i-use-tool.d.ts.map +1 -0
- package/dist/conformance/can-i-use-tool.js +40 -0
- package/dist/conformance/can-i-use-tool.js.map +1 -0
- package/dist/conformance/can-i-use.d.ts +6 -0
- package/dist/conformance/can-i-use.d.ts.map +1 -0
- package/dist/conformance/can-i-use.js +10 -0
- package/dist/conformance/can-i-use.js.map +1 -0
- package/dist/conformance/index.d.ts +8 -0
- package/dist/conformance/index.d.ts.map +1 -0
- package/dist/conformance/index.js +2 -0
- package/dist/conformance/index.js.map +1 -0
- package/dist/conformance/tools.d.ts +4 -0
- package/dist/conformance/tools.d.ts.map +1 -0
- package/dist/conformance/tools.js +14 -0
- package/dist/conformance/tools.js.map +1 -0
- package/dist/credentials/core/memoize-ttl.d.ts +58 -0
- package/dist/credentials/core/memoize-ttl.d.ts.map +1 -0
- package/dist/credentials/core/memoize-ttl.js +88 -0
- package/dist/credentials/core/memoize-ttl.js.map +1 -0
- package/dist/credentials/core/types.d.ts +11 -0
- package/dist/credentials/core/types.d.ts.map +1 -0
- package/dist/credentials/core/types.js +2 -0
- package/dist/credentials/core/types.js.map +1 -0
- package/dist/credentials/node/from-adc.d.ts +10 -0
- package/dist/credentials/node/from-adc.d.ts.map +1 -0
- package/dist/credentials/node/from-adc.js +76 -0
- package/dist/credentials/node/from-adc.js.map +1 -0
- package/dist/credentials/node/from-service-account.d.ts +24 -0
- package/dist/credentials/node/from-service-account.d.ts.map +1 -0
- package/dist/credentials/node/from-service-account.js +108 -0
- package/dist/credentials/node/from-service-account.js.map +1 -0
- package/dist/credentials/node/index.d.ts +7 -0
- package/dist/credentials/node/index.d.ts.map +1 -0
- package/dist/credentials/node/index.js +7 -0
- package/dist/credentials/node/index.js.map +1 -0
- package/dist/discover/concurrency.d.ts +42 -0
- package/dist/discover/concurrency.d.ts.map +1 -0
- package/dist/discover/concurrency.js +113 -0
- package/dist/discover/concurrency.js.map +1 -0
- package/dist/discover/crawler-adapter.d.ts +48 -0
- package/dist/discover/crawler-adapter.d.ts.map +1 -0
- package/dist/discover/crawler-adapter.js +92 -0
- package/dist/discover/crawler-adapter.js.map +1 -0
- package/dist/discover/crawler.d.ts +294 -0
- package/dist/discover/crawler.d.ts.map +1 -0
- package/dist/discover/crawler.js +764 -0
- package/dist/discover/crawler.js.map +1 -0
- package/dist/discover/credential-free.d.ts +19 -0
- package/dist/discover/credential-free.d.ts.map +1 -0
- package/dist/discover/credential-free.js +18 -0
- package/dist/discover/credential-free.js.map +1 -0
- package/dist/discover/findCollectionGroup.d.ts +44 -0
- package/dist/discover/findCollectionGroup.d.ts.map +1 -0
- package/dist/discover/findCollectionGroup.js +81 -0
- package/dist/discover/findCollectionGroup.js.map +1 -0
- package/dist/discover/firestore-source.d.ts +60 -0
- package/dist/discover/firestore-source.d.ts.map +1 -0
- package/dist/discover/firestore-source.js +11 -0
- package/dist/discover/firestore-source.js.map +1 -0
- package/dist/discover/index.d.ts +3 -0
- package/dist/discover/index.d.ts.map +1 -0
- package/dist/discover/index.js +5 -0
- package/dist/discover/index.js.map +1 -0
- package/dist/discover/merge.d.ts +108 -0
- package/dist/discover/merge.d.ts.map +1 -0
- package/dist/discover/merge.js +394 -0
- package/dist/discover/merge.js.map +1 -0
- package/dist/discover/session.d.ts +116 -0
- package/dist/discover/session.d.ts.map +1 -0
- package/dist/discover/session.js +331 -0
- package/dist/discover/session.js.map +1 -0
- package/dist/discover/tools.d.ts +58 -0
- package/dist/discover/tools.d.ts.map +1 -0
- package/dist/discover/tools.js +115 -0
- package/dist/discover/tools.js.map +1 -0
- package/dist/discover/types.d.ts +190 -0
- package/dist/discover/types.d.ts.map +1 -0
- package/dist/discover/types.js +12 -0
- package/dist/discover/types.js.map +1 -0
- package/dist/discover/wire.d.ts +70 -0
- package/dist/discover/wire.d.ts.map +1 -0
- package/dist/discover/wire.js +309 -0
- package/dist/discover/wire.js.map +1 -0
- package/dist/functions-rtdb/child.d.ts +52 -0
- package/dist/functions-rtdb/child.d.ts.map +1 -0
- package/dist/functions-rtdb/child.js +283 -0
- package/dist/functions-rtdb/child.js.map +1 -0
- package/dist/functions-rtdb/delivery.d.ts +4 -0
- package/dist/functions-rtdb/delivery.d.ts.map +1 -0
- package/dist/functions-rtdb/delivery.js +2 -0
- package/dist/functions-rtdb/delivery.js.map +1 -0
- package/dist/functions-rtdb/discovery.d.ts +41 -0
- package/dist/functions-rtdb/discovery.d.ts.map +1 -0
- package/dist/functions-rtdb/discovery.js +86 -0
- package/dist/functions-rtdb/discovery.js.map +1 -0
- package/dist/functions-rtdb/event.d.ts +20 -0
- package/dist/functions-rtdb/event.d.ts.map +1 -0
- package/dist/functions-rtdb/event.js +45 -0
- package/dist/functions-rtdb/event.js.map +1 -0
- package/dist/functions-rtdb/execution.d.ts +20 -0
- package/dist/functions-rtdb/execution.d.ts.map +1 -0
- package/dist/functions-rtdb/execution.js +70 -0
- package/dist/functions-rtdb/execution.js.map +1 -0
- package/dist/functions-rtdb/in-memory-delivery.d.ts +9 -0
- package/dist/functions-rtdb/in-memory-delivery.d.ts.map +1 -0
- package/dist/functions-rtdb/in-memory-delivery.js +36 -0
- package/dist/functions-rtdb/in-memory-delivery.js.map +1 -0
- package/dist/functions-rtdb/project.d.ts +7 -0
- package/dist/functions-rtdb/project.d.ts.map +1 -0
- package/dist/functions-rtdb/project.js +54 -0
- package/dist/functions-rtdb/project.js.map +1 -0
- package/dist/functions-rtdb/projection.d.ts +14 -0
- package/dist/functions-rtdb/projection.d.ts.map +1 -0
- package/dist/functions-rtdb/projection.js +65 -0
- package/dist/functions-rtdb/projection.js.map +1 -0
- package/dist/functions-rtdb/reference-pattern.d.ts +5 -0
- package/dist/functions-rtdb/reference-pattern.d.ts.map +1 -0
- package/dist/functions-rtdb/reference-pattern.js +14 -0
- package/dist/functions-rtdb/reference-pattern.js.map +1 -0
- package/dist/functions-rtdb/remote-delivery.d.ts +9 -0
- package/dist/functions-rtdb/remote-delivery.d.ts.map +1 -0
- package/dist/functions-rtdb/remote-delivery.js +11 -0
- package/dist/functions-rtdb/remote-delivery.js.map +1 -0
- package/dist/pkg-version.d.ts +2 -0
- package/dist/pkg-version.d.ts.map +1 -0
- package/dist/pkg-version.js +47 -0
- package/dist/pkg-version.js.map +1 -0
- package/dist/register/esm-exports.d.ts +26 -0
- package/dist/register/esm-exports.d.ts.map +1 -0
- package/dist/register/esm-exports.js +61 -0
- package/dist/register/esm-exports.js.map +1 -0
- package/dist/register/hooks.d.ts +13 -0
- package/dist/register/hooks.d.ts.map +1 -0
- package/dist/register/hooks.js +15 -0
- package/dist/register/hooks.js.map +1 -0
- package/dist/register/index.d.ts +5 -0
- package/dist/register/index.d.ts.map +1 -0
- package/dist/register/index.js +124 -0
- package/dist/register/index.js.map +1 -0
- package/dist/register/mapping.d.ts +19 -0
- package/dist/register/mapping.d.ts.map +1 -0
- package/dist/register/mapping.js +35 -0
- package/dist/register/mapping.js.map +1 -0
- package/dist/remote/index.d.ts +232 -0
- package/dist/remote/index.d.ts.map +1 -0
- package/dist/remote/index.js +720 -0
- package/dist/remote/index.js.map +1 -0
- package/dist/rtdb/crawl-snapshot.d.ts +17 -0
- package/dist/rtdb/crawl-snapshot.d.ts.map +1 -0
- package/dist/rtdb/crawl-snapshot.js +72 -0
- package/dist/rtdb/crawl-snapshot.js.map +1 -0
- package/dist/rtdb/inspection.d.ts +8 -0
- package/dist/rtdb/inspection.d.ts.map +1 -0
- package/dist/rtdb/inspection.js +111 -0
- package/dist/rtdb/inspection.js.map +1 -0
- package/dist/rtdb/load-rules-document.d.ts +25 -0
- package/dist/rtdb/load-rules-document.d.ts.map +1 -0
- package/dist/rtdb/load-rules-document.js +38 -0
- package/dist/rtdb/load-rules-document.js.map +1 -0
- package/dist/rtdb/rules-generation-tool.d.ts +4 -0
- package/dist/rtdb/rules-generation-tool.d.ts.map +1 -0
- package/dist/rtdb/rules-generation-tool.js +35 -0
- package/dist/rtdb/rules-generation-tool.js.map +1 -0
- package/dist/rtdb/rules-json.d.ts +8 -0
- package/dist/rtdb/rules-json.d.ts.map +1 -0
- package/dist/rtdb/rules-json.js +17 -0
- package/dist/rtdb/rules-json.js.map +1 -0
- package/dist/serve/bridge-mount.d.ts +36 -0
- package/dist/serve/bridge-mount.d.ts.map +1 -0
- package/dist/serve/bridge-mount.js +162 -0
- package/dist/serve/bridge-mount.js.map +1 -0
- package/dist/serve/bundler.d.ts +110 -0
- package/dist/serve/bundler.d.ts.map +1 -0
- package/dist/serve/bundler.js +432 -0
- package/dist/serve/bundler.js.map +1 -0
- package/dist/serve/capture-store.d.ts +27 -0
- package/dist/serve/capture-store.d.ts.map +1 -0
- package/dist/serve/capture-store.js +47 -0
- package/dist/serve/capture-store.js.map +1 -0
- package/dist/serve/discovery.d.ts +71 -0
- package/dist/serve/discovery.d.ts.map +1 -0
- package/dist/serve/discovery.js +158 -0
- package/dist/serve/discovery.js.map +1 -0
- package/dist/serve/docs-ui/_astro/_slug_.DPUwShm2.css +1 -0
- package/dist/serve/docs-ui/docs/_rhythm/index.html +99 -0
- package/dist/serve/docs-ui/docs/_rhythm.md +97 -0
- package/dist/serve/docs-ui/docs/agent/set-up-your-agent/index.html +42 -0
- package/dist/serve/docs-ui/docs/agent/set-up-your-agent.md +72 -0
- package/dist/serve/docs-ui/docs/agent/watch-and-review/index.html +25 -0
- package/dist/serve/docs-ui/docs/agent/watch-and-review.md +38 -0
- package/dist/serve/docs-ui/docs/agent/work-with-an-agent/index.html +69 -0
- package/dist/serve/docs-ui/docs/agent/work-with-an-agent.md +74 -0
- package/dist/serve/docs-ui/docs/ai-compat/index.html +423 -0
- package/dist/serve/docs-ui/docs/ai-compat.md +456 -0
- package/dist/serve/docs-ui/docs/api-reference/index.html +66 -0
- package/dist/serve/docs-ui/docs/api-reference.md +69 -0
- package/dist/serve/docs-ui/docs/app-compat/index.html +159 -0
- package/dist/serve/docs-ui/docs/app-compat.md +178 -0
- package/dist/serve/docs-ui/docs/auth-compat/index.html +644 -0
- package/dist/serve/docs-ui/docs/auth-compat.md +701 -0
- package/dist/serve/docs-ui/docs/build/ai-logic/index.html +27 -0
- package/dist/serve/docs-ui/docs/build/ai-logic.md +39 -0
- package/dist/serve/docs-ui/docs/build/authentication/index.html +65 -0
- package/dist/serve/docs-ui/docs/build/authentication.md +95 -0
- package/dist/serve/docs-ui/docs/build/cloud-firestore/index.html +69 -0
- package/dist/serve/docs-ui/docs/build/cloud-firestore.md +93 -0
- package/dist/serve/docs-ui/docs/build/cloud-messaging/index.html +27 -0
- package/dist/serve/docs-ui/docs/build/cloud-messaging.md +37 -0
- package/dist/serve/docs-ui/docs/build/cloud-storage/index.html +65 -0
- package/dist/serve/docs-ui/docs/build/cloud-storage.md +86 -0
- package/dist/serve/docs-ui/docs/build/realtime-database/index.html +49 -0
- package/dist/serve/docs-ui/docs/build/realtime-database.md +67 -0
- package/dist/serve/docs-ui/docs/conformance-scores/index.html +49 -0
- package/dist/serve/docs-ui/docs/conformance-scores.md +53 -0
- package/dist/serve/docs-ui/docs/create-pyric-reference-api/index.html +498 -0
- package/dist/serve/docs-ui/docs/create-pyric-reference-api.md +345 -0
- package/dist/serve/docs-ui/docs/database-compat/index.html +1037 -0
- package/dist/serve/docs-ui/docs/database-compat.md +1099 -0
- package/dist/serve/docs-ui/docs/firestore-compat/index.html +823 -0
- package/dist/serve/docs-ui/docs/firestore-compat.md +881 -0
- package/dist/serve/docs-ui/docs/functions-rtdb-compat/index.html +72 -0
- package/dist/serve/docs-ui/docs/functions-rtdb-compat.md +83 -0
- package/dist/serve/docs-ui/docs/get-started/how-the-swap-works/index.html +27 -0
- package/dist/serve/docs-ui/docs/get-started/how-the-swap-works.md +50 -0
- package/dist/serve/docs-ui/docs/get-started/start-building/index.html +31 -0
- package/dist/serve/docs-ui/docs/get-started/start-building.md +53 -0
- package/dist/serve/docs-ui/docs/index.html +2 -0
- package/dist/serve/docs-ui/docs/index.json +11719 -0
- package/dist/serve/docs-ui/docs/messaging-compat/index.html +264 -0
- package/dist/serve/docs-ui/docs/messaging-compat.md +285 -0
- package/dist/serve/docs-ui/docs/observe/see-whats-happening/index.html +73 -0
- package/dist/serve/docs-ui/docs/observe/see-whats-happening.md +69 -0
- package/dist/serve/docs-ui/docs/observe/shape-your-data/index.html +44 -0
- package/dist/serve/docs-ui/docs/observe/shape-your-data.md +74 -0
- package/dist/serve/docs-ui/docs/overview/index.html +16 -0
- package/dist/serve/docs-ui/docs/overview.md +31 -0
- package/dist/serve/docs-ui/docs/pyric-admin-app-reference-api/index.html +185 -0
- package/dist/serve/docs-ui/docs/pyric-admin-app-reference-api.md +206 -0
- package/dist/serve/docs-ui/docs/pyric-admin-auth-reference-api/index.html +617 -0
- package/dist/serve/docs-ui/docs/pyric-admin-auth-reference-api.md +441 -0
- package/dist/serve/docs-ui/docs/pyric-admin-database-reference-api/index.html +583 -0
- package/dist/serve/docs-ui/docs/pyric-admin-database-reference-api.md +597 -0
- package/dist/serve/docs-ui/docs/pyric-admin-firestore-reference-api/index.html +32 -0
- package/dist/serve/docs-ui/docs/pyric-admin-firestore-reference-api.md +30 -0
- package/dist/serve/docs-ui/docs/pyric-admin-storage-reference-api/index.html +317 -0
- package/dist/serve/docs-ui/docs/pyric-admin-storage-reference-api.md +285 -0
- package/dist/serve/docs-ui/docs/pyric-ai-reference-api/index.html +5830 -0
- package/dist/serve/docs-ui/docs/pyric-ai-reference-api.md +5439 -0
- package/dist/serve/docs-ui/docs/pyric-ai-scripting-reference-api/index.html +159 -0
- package/dist/serve/docs-ui/docs/pyric-ai-scripting-reference-api.md +122 -0
- package/dist/serve/docs-ui/docs/pyric-app-reference-api/index.html +420 -0
- package/dist/serve/docs-ui/docs/pyric-app-reference-api.md +326 -0
- package/dist/serve/docs-ui/docs/pyric-auth-reference-api/index.html +5452 -0
- package/dist/serve/docs-ui/docs/pyric-auth-reference-api.md +5271 -0
- package/dist/serve/docs-ui/docs/pyric-cli-assurance-browser-reference-api/index.html +98 -0
- package/dist/serve/docs-ui/docs/pyric-cli-assurance-browser-reference-api.md +88 -0
- package/dist/serve/docs-ui/docs/pyric-cli-assurance-reference-api/index.html +2263 -0
- package/dist/serve/docs-ui/docs/pyric-cli-assurance-reference-api.md +1477 -0
- package/dist/serve/docs-ui/docs/pyric-cli-bridge-client-reference-api/index.html +546 -0
- package/dist/serve/docs-ui/docs/pyric-cli-bridge-client-reference-api.md +485 -0
- package/dist/serve/docs-ui/docs/pyric-cli-bridge-reference-api/index.html +506 -0
- package/dist/serve/docs-ui/docs/pyric-cli-bridge-reference-api.md +419 -0
- package/dist/serve/docs-ui/docs/pyric-cli-conformance-browser-reference-api/index.html +257 -0
- package/dist/serve/docs-ui/docs/pyric-cli-conformance-browser-reference-api.md +197 -0
- package/dist/serve/docs-ui/docs/pyric-cli-conformance-reference-api/index.html +307 -0
- package/dist/serve/docs-ui/docs/pyric-cli-conformance-reference-api.md +254 -0
- package/dist/serve/docs-ui/docs/pyric-cli-credentials-node-reference-api/index.html +67 -0
- package/dist/serve/docs-ui/docs/pyric-cli-credentials-node-reference-api.md +59 -0
- package/dist/serve/docs-ui/docs/pyric-cli-discover-reference-api/index.html +2355 -0
- package/dist/serve/docs-ui/docs/pyric-cli-discover-reference-api.md +2036 -0
- package/dist/serve/docs-ui/docs/pyric-cli-register-reference-api/index.html +10 -0
- package/dist/serve/docs-ui/docs/pyric-cli-register-reference-api.md +16 -0
- package/dist/serve/docs-ui/docs/pyric-cli-remote-reference-api/index.html +1044 -0
- package/dist/serve/docs-ui/docs/pyric-cli-remote-reference-api.md +952 -0
- package/dist/serve/docs-ui/docs/pyric-cli-serve-worker-reference-api/index.html +5041 -0
- package/dist/serve/docs-ui/docs/pyric-cli-serve-worker-reference-api.md +4739 -0
- package/dist/serve/docs-ui/docs/pyric-cli-verify-reference-api/index.html +926 -0
- package/dist/serve/docs-ui/docs/pyric-cli-verify-reference-api.md +586 -0
- package/dist/serve/docs-ui/docs/pyric-cli-vite-reference-api/index.html +102 -0
- package/dist/serve/docs-ui/docs/pyric-cli-vite-reference-api.md +76 -0
- package/dist/serve/docs-ui/docs/pyric-database-reference-api/index.html +1851 -0
- package/dist/serve/docs-ui/docs/pyric-database-reference-api.md +1842 -0
- package/dist/serve/docs-ui/docs/pyric-firestore-reference-api/index.html +3623 -0
- package/dist/serve/docs-ui/docs/pyric-firestore-reference-api.md +3399 -0
- package/dist/serve/docs-ui/docs/pyric-firestore-values-reference-api/index.html +30 -0
- package/dist/serve/docs-ui/docs/pyric-firestore-values-reference-api.md +30 -0
- package/dist/serve/docs-ui/docs/pyric-messaging-reference-api/index.html +508 -0
- package/dist/serve/docs-ui/docs/pyric-messaging-reference-api.md +374 -0
- package/dist/serve/docs-ui/docs/pyric-messaging-sw-reference-api/index.html +482 -0
- package/dist/serve/docs-ui/docs/pyric-messaging-sw-reference-api.md +348 -0
- package/dist/serve/docs-ui/docs/pyric-rules-reference-api/index.html +2629 -0
- package/dist/serve/docs-ui/docs/pyric-rules-reference-api.md +2213 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-database-reference-api/index.html +120 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-database-reference-api.md +110 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-firestore-reference-api/index.html +202 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-firestore-reference-api.md +134 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-reference-api/index.html +5019 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-reference-api.md +4060 -0
- package/dist/serve/docs-ui/docs/pyric-storage-reference-api/index.html +2120 -0
- package/dist/serve/docs-ui/docs/pyric-storage-reference-api.md +1687 -0
- package/dist/serve/docs-ui/docs/pyric-ui-agents-reference-api/index.html +638 -0
- package/dist/serve/docs-ui/docs/pyric-ui-agents-reference-api.md +430 -0
- package/dist/serve/docs-ui/docs/pyric-ui-auth-hooks-reference-api/index.html +813 -0
- package/dist/serve/docs-ui/docs/pyric-ui-auth-hooks-reference-api.md +634 -0
- package/dist/serve/docs-ui/docs/pyric-ui-auth-reference-api/index.html +1708 -0
- package/dist/serve/docs-ui/docs/pyric-ui-auth-reference-api.md +1300 -0
- package/dist/serve/docs-ui/docs/pyric-ui-events-hooks-reference-api/index.html +177 -0
- package/dist/serve/docs-ui/docs/pyric-ui-events-hooks-reference-api.md +111 -0
- package/dist/serve/docs-ui/docs/pyric-ui-events-reference-api/index.html +1542 -0
- package/dist/serve/docs-ui/docs/pyric-ui-events-reference-api.md +903 -0
- package/dist/serve/docs-ui/docs/pyric-ui-firestore-hooks-reference-api/index.html +1024 -0
- package/dist/serve/docs-ui/docs/pyric-ui-firestore-hooks-reference-api.md +640 -0
- package/dist/serve/docs-ui/docs/pyric-ui-firestore-reference-api/index.html +2753 -0
- package/dist/serve/docs-ui/docs/pyric-ui-firestore-reference-api.md +2171 -0
- package/dist/serve/docs-ui/docs/pyric-ui-primitives-reference-api/index.html +1005 -0
- package/dist/serve/docs-ui/docs/pyric-ui-primitives-reference-api.md +693 -0
- package/dist/serve/docs-ui/docs/pyric-ui-rtdb-reference-api/index.html +1388 -0
- package/dist/serve/docs-ui/docs/pyric-ui-rtdb-reference-api.md +1340 -0
- package/dist/serve/docs-ui/docs/pyric-ui-rules-hooks-reference-api/index.html +131 -0
- package/dist/serve/docs-ui/docs/pyric-ui-rules-hooks-reference-api.md +76 -0
- package/dist/serve/docs-ui/docs/pyric-ui-rules-reference-api/index.html +648 -0
- package/dist/serve/docs-ui/docs/pyric-ui-rules-reference-api.md +508 -0
- package/dist/serve/docs-ui/docs/pyric-ui-storage-hooks-reference-api/index.html +1457 -0
- package/dist/serve/docs-ui/docs/pyric-ui-storage-hooks-reference-api.md +1029 -0
- package/dist/serve/docs-ui/docs/pyric-ui-storage-reference-api/index.html +2476 -0
- package/dist/serve/docs-ui/docs/pyric-ui-storage-reference-api.md +1919 -0
- package/dist/serve/docs-ui/docs/pyric-ui-traffic-hooks-reference-api/index.html +1241 -0
- package/dist/serve/docs-ui/docs/pyric-ui-traffic-hooks-reference-api.md +817 -0
- package/dist/serve/docs-ui/docs/pyric-ui-traffic-reference-api/index.html +2289 -0
- package/dist/serve/docs-ui/docs/pyric-ui-traffic-reference-api.md +1489 -0
- package/dist/serve/docs-ui/docs/rules-compat/index.html +272 -0
- package/dist/serve/docs-ui/docs/rules-compat.md +287 -0
- package/dist/serve/docs-ui/docs/secure/audit-your-rules/index.html +34 -0
- package/dist/serve/docs-ui/docs/secure/audit-your-rules.md +67 -0
- package/dist/serve/docs-ui/docs/secure/firestore-rules-limits/index.html +105 -0
- package/dist/serve/docs-ui/docs/secure/firestore-rules-limits.md +152 -0
- package/dist/serve/docs-ui/docs/secure/read-a-denial/index.html +40 -0
- package/dist/serve/docs-ui/docs/secure/read-a-denial.md +58 -0
- package/dist/serve/docs-ui/docs/secure/rtdb-rules-in-typescript/index.html +66 -0
- package/dist/serve/docs-ui/docs/secure/rtdb-rules-in-typescript.md +89 -0
- package/dist/serve/docs-ui/docs/secure/rules-standard-library/index.html +158 -0
- package/dist/serve/docs-ui/docs/secure/rules-standard-library.md +116 -0
- package/dist/serve/docs-ui/docs/secure/secure-it-with-rules/index.html +46 -0
- package/dist/serve/docs-ui/docs/secure/secure-it-with-rules.md +51 -0
- package/dist/serve/docs-ui/docs/secure/simulate-and-lint/index.html +94 -0
- package/dist/serve/docs-ui/docs/secure/simulate-and-lint.md +86 -0
- package/dist/serve/docs-ui/docs/secure/write-a-rules-test-suite/index.html +81 -0
- package/dist/serve/docs-ui/docs/secure/write-a-rules-test-suite.md +105 -0
- package/dist/serve/docs-ui/docs/ship/ship-to-production/index.html +36 -0
- package/dist/serve/docs-ui/docs/ship/ship-to-production.md +64 -0
- package/dist/serve/docs-ui/docs/ship/test-in-node/index.html +74 -0
- package/dist/serve/docs-ui/docs/ship/test-in-node.md +94 -0
- package/dist/serve/docs-ui/docs/storage-compat/index.html +532 -0
- package/dist/serve/docs-ui/docs/storage-compat.md +577 -0
- package/dist/serve/docs-ui/docs/trust/how-we-know-it-matches-firebase/index.html +131 -0
- package/dist/serve/docs-ui/docs/trust/how-we-know-it-matches-firebase.md +155 -0
- package/dist/serve/docs-ui/docs/trust/versioning-and-compatibility/index.html +13 -0
- package/dist/serve/docs-ui/docs/trust/versioning-and-compatibility.md +21 -0
- package/dist/serve/docs-ui/index.html +1 -0
- package/dist/serve/docs-ui/llms.txt +123 -0
- package/dist/serve/entries/ai.d.ts +4 -0
- package/dist/serve/entries/ai.d.ts.map +1 -0
- package/dist/serve/entries/ai.js +184 -0
- package/dist/serve/entries/ai.js.map +1 -0
- package/dist/serve/entries/app-backend.d.ts +2 -0
- package/dist/serve/entries/app-backend.d.ts.map +1 -0
- package/dist/serve/entries/app-backend.js +4 -0
- package/dist/serve/entries/app-backend.js.map +1 -0
- package/dist/serve/entries/app-client.d.ts +5 -0
- package/dist/serve/entries/app-client.d.ts.map +1 -0
- package/dist/serve/entries/app-client.js +23 -0
- package/dist/serve/entries/app-client.js.map +1 -0
- package/dist/serve/entries/app-session-store.d.ts +14 -0
- package/dist/serve/entries/app-session-store.d.ts.map +1 -0
- package/dist/serve/entries/app-session-store.js +37 -0
- package/dist/serve/entries/app-session-store.js.map +1 -0
- package/dist/serve/entries/app.d.ts +2 -0
- package/dist/serve/entries/app.d.ts.map +1 -0
- package/dist/serve/entries/app.js +10 -0
- package/dist/serve/entries/app.js.map +1 -0
- package/dist/serve/entries/auth-helper-core.d.ts +52 -0
- package/dist/serve/entries/auth-helper-core.d.ts.map +1 -0
- package/dist/serve/entries/auth-helper-core.js +118 -0
- package/dist/serve/entries/auth-helper-core.js.map +1 -0
- package/dist/serve/entries/auth-helper-dom.d.ts +14 -0
- package/dist/serve/entries/auth-helper-dom.d.ts.map +1 -0
- package/dist/serve/entries/auth-helper-dom.js +116 -0
- package/dist/serve/entries/auth-helper-dom.js.map +1 -0
- package/dist/serve/entries/auth-helper-runtime.d.ts +5 -0
- package/dist/serve/entries/auth-helper-runtime.d.ts.map +1 -0
- package/dist/serve/entries/auth-helper-runtime.js +11 -0
- package/dist/serve/entries/auth-helper-runtime.js.map +1 -0
- package/dist/serve/entries/auth.d.ts +77 -0
- package/dist/serve/entries/auth.d.ts.map +1 -0
- package/dist/serve/entries/auth.js +201 -0
- package/dist/serve/entries/auth.js.map +1 -0
- package/dist/serve/entries/bridge-url.d.ts +25 -0
- package/dist/serve/entries/bridge-url.d.ts.map +1 -0
- package/dist/serve/entries/bridge-url.js +30 -0
- package/dist/serve/entries/bridge-url.js.map +1 -0
- package/dist/serve/entries/database.d.ts +46 -0
- package/dist/serve/entries/database.d.ts.map +1 -0
- package/dist/serve/entries/database.js +80 -0
- package/dist/serve/entries/database.js.map +1 -0
- package/dist/serve/entries/firestore.d.ts +104 -0
- package/dist/serve/entries/firestore.d.ts.map +1 -0
- package/dist/serve/entries/firestore.js +202 -0
- package/dist/serve/entries/firestore.js.map +1 -0
- package/dist/serve/entries/init.d.ts +2 -0
- package/dist/serve/entries/init.d.ts.map +1 -0
- package/dist/serve/entries/init.js +40 -0
- package/dist/serve/entries/init.js.map +1 -0
- package/dist/serve/entries/keepalive.d.ts +20 -0
- package/dist/serve/entries/keepalive.d.ts.map +1 -0
- package/dist/serve/entries/keepalive.js +38 -0
- package/dist/serve/entries/keepalive.js.map +1 -0
- package/dist/serve/entries/messaging-sw.d.ts +10 -0
- package/dist/serve/entries/messaging-sw.d.ts.map +1 -0
- package/dist/serve/entries/messaging-sw.js +36 -0
- package/dist/serve/entries/messaging-sw.js.map +1 -0
- package/dist/serve/entries/messaging.d.ts +11 -0
- package/dist/serve/entries/messaging.d.ts.map +1 -0
- package/dist/serve/entries/messaging.js +53 -0
- package/dist/serve/entries/messaging.js.map +1 -0
- package/dist/serve/entries/runtime.d.ts +46 -0
- package/dist/serve/entries/runtime.d.ts.map +1 -0
- package/dist/serve/entries/runtime.js +435 -0
- package/dist/serve/entries/runtime.js.map +1 -0
- package/dist/serve/entries/session-store.d.ts +48 -0
- package/dist/serve/entries/session-store.d.ts.map +1 -0
- package/dist/serve/entries/session-store.js +82 -0
- package/dist/serve/entries/session-store.js.map +1 -0
- package/dist/serve/entries/storage.d.ts +25 -0
- package/dist/serve/entries/storage.d.ts.map +1 -0
- package/dist/serve/entries/storage.js +61 -0
- package/dist/serve/entries/storage.js.map +1 -0
- package/dist/serve/entries/tab-sync-wiring.d.ts +88 -0
- package/dist/serve/entries/tab-sync-wiring.d.ts.map +1 -0
- package/dist/serve/entries/tab-sync-wiring.js +217 -0
- package/dist/serve/entries/tab-sync-wiring.js.map +1 -0
- package/dist/serve/entries/worker-runtime.d.ts +10 -0
- package/dist/serve/entries/worker-runtime.d.ts.map +1 -0
- package/dist/serve/entries/worker-runtime.js +59 -0
- package/dist/serve/entries/worker-runtime.js.map +1 -0
- package/dist/serve/init-payload.d.ts +21 -0
- package/dist/serve/init-payload.d.ts.map +1 -0
- package/dist/serve/init-payload.js +2 -0
- package/dist/serve/init-payload.js.map +1 -0
- package/dist/serve/namespace.d.ts +73 -0
- package/dist/serve/namespace.d.ts.map +1 -0
- package/dist/serve/namespace.js +470 -0
- package/dist/serve/namespace.js.map +1 -0
- package/dist/serve/open-browser.d.ts +23 -0
- package/dist/serve/open-browser.d.ts.map +1 -0
- package/dist/serve/open-browser.js +58 -0
- package/dist/serve/open-browser.js.map +1 -0
- package/dist/serve/rules.d.ts +77 -0
- package/dist/serve/rules.d.ts.map +1 -0
- package/dist/serve/rules.js +202 -0
- package/dist/serve/rules.js.map +1 -0
- package/dist/serve/sandbox-marker.d.ts +9 -0
- package/dist/serve/sandbox-marker.d.ts.map +1 -0
- package/dist/serve/sandbox-marker.js +31 -0
- package/dist/serve/sandbox-marker.js.map +1 -0
- package/dist/serve/server.d.ts +135 -0
- package/dist/serve/server.d.ts.map +1 -0
- package/dist/serve/server.js +328 -0
- package/dist/serve/server.js.map +1 -0
- package/dist/serve/standalone-assets.d.ts +67 -0
- package/dist/serve/standalone-assets.d.ts.map +1 -0
- package/dist/serve/standalone-assets.js +134 -0
- package/dist/serve/standalone-assets.js.map +1 -0
- package/dist/serve/state-store.d.ts +45 -0
- package/dist/serve/state-store.d.ts.map +1 -0
- package/dist/serve/state-store.js +120 -0
- package/dist/serve/state-store.js.map +1 -0
- package/dist/serve/studio/disk-project-store.d.ts +9 -0
- package/dist/serve/studio/disk-project-store.d.ts.map +1 -0
- package/dist/serve/studio/disk-project-store.js +173 -0
- package/dist/serve/studio/disk-project-store.js.map +1 -0
- package/dist/serve/studio/disk-workspace.d.ts +14 -0
- package/dist/serve/studio/disk-workspace.d.ts.map +1 -0
- package/dist/serve/studio/disk-workspace.js +152 -0
- package/dist/serve/studio/disk-workspace.js.map +1 -0
- package/dist/serve/studio/index.d.ts +10 -0
- package/dist/serve/studio/index.d.ts.map +1 -0
- package/dist/serve/studio/index.js +9 -0
- package/dist/serve/studio/index.js.map +1 -0
- package/dist/serve/studio/routes.d.ts +40 -0
- package/dist/serve/studio/routes.d.ts.map +1 -0
- package/dist/serve/studio/routes.js +182 -0
- package/dist/serve/studio/routes.js.map +1 -0
- package/dist/serve/studio/store-types.d.ts +45 -0
- package/dist/serve/studio/store-types.d.ts.map +1 -0
- package/dist/serve/studio/store-types.js +11 -0
- package/dist/serve/studio/store-types.js.map +1 -0
- package/dist/serve/studio-ui/assets/RulesCodeEditor-CXdSLKhO.js +23 -0
- package/dist/serve/studio-ui/assets/index-BlSGru_r.css +1 -0
- package/dist/serve/studio-ui/assets/index-BvtQIpGn.js +1211 -0
- package/dist/serve/studio-ui/assets/seed-3DMedLL3.js +2 -0
- package/dist/serve/studio-ui/index.html +32 -0
- package/dist/serve/studio-ui/pyric-logo.svg +76 -0
- package/dist/serve/vite-plugin.d.ts +57 -0
- package/dist/serve/vite-plugin.d.ts.map +1 -0
- package/dist/serve/vite-plugin.js +664 -0
- package/dist/serve/vite-plugin.js.map +1 -0
- package/dist/serve/worker/client/admin-firestore.d.ts +18 -0
- package/dist/serve/worker/client/admin-firestore.d.ts.map +1 -0
- package/dist/serve/worker/client/admin-firestore.js +26 -0
- package/dist/serve/worker/client/admin-firestore.js.map +1 -0
- package/dist/serve/worker/client/ai.d.ts +31 -0
- package/dist/serve/worker/client/ai.d.ts.map +1 -0
- package/dist/serve/worker/client/ai.js +89 -0
- package/dist/serve/worker/client/ai.js.map +1 -0
- package/dist/serve/worker/client/auth.d.ts +168 -0
- package/dist/serve/worker/client/auth.d.ts.map +1 -0
- package/dist/serve/worker/client/auth.js +322 -0
- package/dist/serve/worker/client/auth.js.map +1 -0
- package/dist/serve/worker/client/connection.d.ts +80 -0
- package/dist/serve/worker/client/connection.d.ts.map +1 -0
- package/dist/serve/worker/client/connection.js +148 -0
- package/dist/serve/worker/client/connection.js.map +1 -0
- package/dist/serve/worker/client/core.d.ts +109 -0
- package/dist/serve/worker/client/core.d.ts.map +1 -0
- package/dist/serve/worker/client/core.js +248 -0
- package/dist/serve/worker/client/core.js.map +1 -0
- package/dist/serve/worker/client/disconnect.d.ts +7 -0
- package/dist/serve/worker/client/disconnect.d.ts.map +1 -0
- package/dist/serve/worker/client/disconnect.js +26 -0
- package/dist/serve/worker/client/disconnect.js.map +1 -0
- package/dist/serve/worker/client/firestore-reads.d.ts +49 -0
- package/dist/serve/worker/client/firestore-reads.d.ts.map +1 -0
- package/dist/serve/worker/client/firestore-reads.js +139 -0
- package/dist/serve/worker/client/firestore-reads.js.map +1 -0
- package/dist/serve/worker/client/firestore-refs.d.ts +54 -0
- package/dist/serve/worker/client/firestore-refs.d.ts.map +1 -0
- package/dist/serve/worker/client/firestore-refs.js +167 -0
- package/dist/serve/worker/client/firestore-refs.js.map +1 -0
- package/dist/serve/worker/client/firestore-writes.d.ts +70 -0
- package/dist/serve/worker/client/firestore-writes.d.ts.map +1 -0
- package/dist/serve/worker/client/firestore-writes.js +169 -0
- package/dist/serve/worker/client/firestore-writes.js.map +1 -0
- package/dist/serve/worker/client/handles.d.ts +73 -0
- package/dist/serve/worker/client/handles.d.ts.map +1 -0
- package/dist/serve/worker/client/handles.js +4 -0
- package/dist/serve/worker/client/handles.js.map +1 -0
- package/dist/serve/worker/client/messaging.d.ts +16 -0
- package/dist/serve/worker/client/messaging.d.ts.map +1 -0
- package/dist/serve/worker/client/messaging.js +60 -0
- package/dist/serve/worker/client/messaging.js.map +1 -0
- package/dist/serve/worker/client/presence.d.ts +43 -0
- package/dist/serve/worker/client/presence.d.ts.map +1 -0
- package/dist/serve/worker/client/presence.js +132 -0
- package/dist/serve/worker/client/presence.js.map +1 -0
- package/dist/serve/worker/client/rtdb.d.ts +36 -0
- package/dist/serve/worker/client/rtdb.d.ts.map +1 -0
- package/dist/serve/worker/client/rtdb.js +241 -0
- package/dist/serve/worker/client/rtdb.js.map +1 -0
- package/dist/serve/worker/client/rules.d.ts +24 -0
- package/dist/serve/worker/client/rules.d.ts.map +1 -0
- package/dist/serve/worker/client/rules.js +44 -0
- package/dist/serve/worker/client/rules.js.map +1 -0
- package/dist/serve/worker/client/service-worker-connection.d.ts +3 -0
- package/dist/serve/worker/client/service-worker-connection.d.ts.map +1 -0
- package/dist/serve/worker/client/service-worker-connection.js +53 -0
- package/dist/serve/worker/client/service-worker-connection.js.map +1 -0
- package/dist/serve/worker/client/snapshots.d.ts +32 -0
- package/dist/serve/worker/client/snapshots.d.ts.map +1 -0
- package/dist/serve/worker/client/snapshots.js +46 -0
- package/dist/serve/worker/client/snapshots.js.map +1 -0
- package/dist/serve/worker/client/storage.d.ts +64 -0
- package/dist/serve/worker/client/storage.d.ts.map +1 -0
- package/dist/serve/worker/client/storage.js +125 -0
- package/dist/serve/worker/client/storage.js.map +1 -0
- package/dist/serve/worker/client/studio.d.ts +32 -0
- package/dist/serve/worker/client/studio.d.ts.map +1 -0
- package/dist/serve/worker/client/studio.js +61 -0
- package/dist/serve/worker/client/studio.js.map +1 -0
- package/dist/serve/worker/client.d.ts +43 -0
- package/dist/serve/worker/client.d.ts.map +1 -0
- package/dist/serve/worker/client.js +44 -0
- package/dist/serve/worker/client.js.map +1 -0
- package/dist/serve/worker/entry.d.ts +40 -0
- package/dist/serve/worker/entry.d.ts.map +1 -0
- package/dist/serve/worker/entry.js +144 -0
- package/dist/serve/worker/entry.js.map +1 -0
- package/dist/serve/worker/host/admin-firestore.d.ts +17 -0
- package/dist/serve/worker/host/admin-firestore.d.ts.map +1 -0
- package/dist/serve/worker/host/admin-firestore.js +92 -0
- package/dist/serve/worker/host/admin-firestore.js.map +1 -0
- package/dist/serve/worker/host/connection.d.ts +40 -0
- package/dist/serve/worker/host/connection.d.ts.map +1 -0
- package/dist/serve/worker/host/connection.js +153 -0
- package/dist/serve/worker/host/connection.js.map +1 -0
- package/dist/serve/worker/host/core.d.ts +159 -0
- package/dist/serve/worker/host/core.d.ts.map +1 -0
- package/dist/serve/worker/host/core.js +296 -0
- package/dist/serve/worker/host/core.js.map +1 -0
- package/dist/serve/worker/host/dispatch.d.ts +34 -0
- package/dist/serve/worker/host/dispatch.d.ts.map +1 -0
- package/dist/serve/worker/host/dispatch.js +267 -0
- package/dist/serve/worker/host/dispatch.js.map +1 -0
- package/dist/serve/worker/host/firestore-reads.d.ts +17 -0
- package/dist/serve/worker/host/firestore-reads.d.ts.map +1 -0
- package/dist/serve/worker/host/firestore-reads.js +108 -0
- package/dist/serve/worker/host/firestore-reads.js.map +1 -0
- package/dist/serve/worker/host/firestore-writes.d.ts +37 -0
- package/dist/serve/worker/host/firestore-writes.d.ts.map +1 -0
- package/dist/serve/worker/host/firestore-writes.js +409 -0
- package/dist/serve/worker/host/firestore-writes.js.map +1 -0
- package/dist/serve/worker/host/presence.d.ts +38 -0
- package/dist/serve/worker/host/presence.d.ts.map +1 -0
- package/dist/serve/worker/host/presence.js +280 -0
- package/dist/serve/worker/host/presence.js.map +1 -0
- package/dist/serve/worker/host/rtdb.d.ts +18 -0
- package/dist/serve/worker/host/rtdb.d.ts.map +1 -0
- package/dist/serve/worker/host/rtdb.js +128 -0
- package/dist/serve/worker/host/rtdb.js.map +1 -0
- package/dist/serve/worker/host/rules.d.ts +17 -0
- package/dist/serve/worker/host/rules.d.ts.map +1 -0
- package/dist/serve/worker/host/rules.js +118 -0
- package/dist/serve/worker/host/rules.js.map +1 -0
- package/dist/serve/worker/host/storage.d.ts +19 -0
- package/dist/serve/worker/host/storage.d.ts.map +1 -0
- package/dist/serve/worker/host/storage.js +260 -0
- package/dist/serve/worker/host/storage.js.map +1 -0
- package/dist/serve/worker/host/studio.d.ts +13 -0
- package/dist/serve/worker/host/studio.d.ts.map +1 -0
- package/dist/serve/worker/host/studio.js +30 -0
- package/dist/serve/worker/host/studio.js.map +1 -0
- package/dist/serve/worker/host/subscriptions.d.ts +21 -0
- package/dist/serve/worker/host/subscriptions.d.ts.map +1 -0
- package/dist/serve/worker/host/subscriptions.js +162 -0
- package/dist/serve/worker/host/subscriptions.js.map +1 -0
- package/dist/serve/worker/host-ai.d.ts +59 -0
- package/dist/serve/worker/host-ai.d.ts.map +1 -0
- package/dist/serve/worker/host-ai.js +158 -0
- package/dist/serve/worker/host-ai.js.map +1 -0
- package/dist/serve/worker/host-auth.d.ts +47 -0
- package/dist/serve/worker/host-auth.d.ts.map +1 -0
- package/dist/serve/worker/host-auth.js +464 -0
- package/dist/serve/worker/host-auth.js.map +1 -0
- package/dist/serve/worker/host-context.d.ts +220 -0
- package/dist/serve/worker/host-context.d.ts.map +1 -0
- package/dist/serve/worker/host-context.js +45 -0
- package/dist/serve/worker/host-context.js.map +1 -0
- package/dist/serve/worker/host-events.d.ts +21 -0
- package/dist/serve/worker/host-events.d.ts.map +1 -0
- package/dist/serve/worker/host-events.js +87 -0
- package/dist/serve/worker/host-events.js.map +1 -0
- package/dist/serve/worker/host-messaging.d.ts +60 -0
- package/dist/serve/worker/host-messaging.d.ts.map +1 -0
- package/dist/serve/worker/host-messaging.js +226 -0
- package/dist/serve/worker/host-messaging.js.map +1 -0
- package/dist/serve/worker/host.d.ts +36 -0
- package/dist/serve/worker/host.d.ts.map +1 -0
- package/dist/serve/worker/host.js +39 -0
- package/dist/serve/worker/host.js.map +1 -0
- package/dist/serve/worker/index.d.ts +22 -0
- package/dist/serve/worker/index.d.ts.map +1 -0
- package/dist/serve/worker/index.js +61 -0
- package/dist/serve/worker/index.js.map +1 -0
- package/dist/serve/worker/presence-timing.d.ts +14 -0
- package/dist/serve/worker/presence-timing.d.ts.map +1 -0
- package/dist/serve/worker/presence-timing.js +14 -0
- package/dist/serve/worker/presence-timing.js.map +1 -0
- package/dist/serve/worker/protocol.d.ts +1150 -0
- package/dist/serve/worker/protocol.d.ts.map +1 -0
- package/dist/serve/worker/protocol.js +228 -0
- package/dist/serve/worker/protocol.js.map +1 -0
- package/dist/serve/worker/serve-init.d.ts +201 -0
- package/dist/serve/worker/serve-init.d.ts.map +1 -0
- package/dist/serve/worker/serve-init.js +579 -0
- package/dist/serve/worker/serve-init.js.map +1 -0
- package/dist/serve/worker/service-worker-channel.d.ts +23 -0
- package/dist/serve/worker/service-worker-channel.d.ts.map +1 -0
- package/dist/serve/worker/service-worker-channel.js +9 -0
- package/dist/serve/worker/service-worker-channel.js.map +1 -0
- package/dist/serve/worker/service-worker-relay.d.ts +22 -0
- package/dist/serve/worker/service-worker-relay.d.ts.map +1 -0
- package/dist/serve/worker/service-worker-relay.js +63 -0
- package/dist/serve/worker/service-worker-relay.js.map +1 -0
- package/dist/serve/writer-lock.d.ts +32 -0
- package/dist/serve/writer-lock.d.ts.map +1 -0
- package/dist/serve/writer-lock.js +43 -0
- package/dist/serve/writer-lock.js.map +1 -0
- package/dist/verify/cases.d.ts +37 -0
- package/dist/verify/cases.d.ts.map +1 -0
- package/dist/verify/cases.js +173 -0
- package/dist/verify/cases.js.map +1 -0
- package/dist/verify/fixture.d.ts +100 -0
- package/dist/verify/fixture.d.ts.map +1 -0
- package/dist/verify/fixture.js +156 -0
- package/dist/verify/fixture.js.map +1 -0
- package/dist/verify/index.d.ts +102 -0
- package/dist/verify/index.d.ts.map +1 -0
- package/dist/verify/index.js +318 -0
- package/dist/verify/index.js.map +1 -0
- package/dist/verify/tools.d.ts +7 -0
- package/dist/verify/tools.d.ts.map +1 -0
- package/dist/verify/tools.js +83 -0
- package/dist/verify/tools.js.map +1 -0
- package/dist/version/compat-target.d.ts +18 -0
- package/dist/version/compat-target.d.ts.map +1 -0
- package/dist/version/compat-target.js +18 -0
- package/dist/version/compat-target.js.map +1 -0
- package/dist/vite.d.ts +12 -0
- package/dist/vite.d.ts.map +1 -0
- package/dist/vite.js +16 -0
- package/dist/vite.js.map +1 -0
- package/package.json +144 -0
|
@@ -0,0 +1,764 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BFS-layer crawler for `firestore_discover_paths`.
|
|
3
|
+
*
|
|
4
|
+
* Phase 0.3 of the validation plan locked layered BFS with bounded
|
|
5
|
+
* concurrency as the production strategy (38× faster than serial DFS on a
|
|
6
|
+
* 416-doc corpus). This module owns the structure-discovery half of the
|
|
7
|
+
* crawl: enumerate every collection reachable from the root via
|
|
8
|
+
* `listCollections` + `listDocuments` + per-doc `listCollections`. Document
|
|
9
|
+
* sampling and merge integration land in Item 2.3; permission-error
|
|
10
|
+
* resilience lands in Item 2.4.
|
|
11
|
+
*
|
|
12
|
+
* Output of this skeleton:
|
|
13
|
+
* - `collection_discovered` events emitted as each collection enters the
|
|
14
|
+
* frontier (depth-tagged so agents can render a tree)
|
|
15
|
+
* - `discoveredCollections` map with the collection refs collected per
|
|
16
|
+
* templatePath, ready for Item 2.3 to feed through sampling
|
|
17
|
+
*
|
|
18
|
+
* What this module deliberately does NOT do (yet):
|
|
19
|
+
* - read any document fields (no `.get()` calls)
|
|
20
|
+
* - emit `schema_updated` (no merge integration)
|
|
21
|
+
* - tolerate permission errors (any RPC throw aborts the crawl)
|
|
22
|
+
* - adaptive sampling, continuation, or dryRun
|
|
23
|
+
*/
|
|
24
|
+
'use strict';
|
|
25
|
+
import { runWithLimit } from './concurrency.js';
|
|
26
|
+
import { emptySchema, mergeDoc } from './merge.js';
|
|
27
|
+
import { snapshotToObservations } from './wire.js';
|
|
28
|
+
const DEFAULT_MAX_CONCURRENCY = 32;
|
|
29
|
+
const DEFAULT_MAX_DEPTH = 10;
|
|
30
|
+
const DEFAULT_MAX_SAMPLES = 50;
|
|
31
|
+
const DEFAULT_MAX_ERRORS_PER_COLLECTION = 3;
|
|
32
|
+
/**
|
|
33
|
+
* Default subtree multiplier for the dryRun projection. 3 = "each root
|
|
34
|
+
* collection has, on average, itself + ~2 descendant collections."
|
|
35
|
+
* Conservative for typical app schemas; configurable via
|
|
36
|
+
* `CrawlOptions.dryRunSubtreeMultiplier`.
|
|
37
|
+
*/
|
|
38
|
+
const DEFAULT_DRY_RUN_SUBTREE_MULTIPLIER = 3;
|
|
39
|
+
/**
|
|
40
|
+
* Phase 2.1 lock — `stopOnStable=8` was validated against the real corpus
|
|
41
|
+
* (Phase 2.2) with 0 false positives. Optimistic early-exit signal; the
|
|
42
|
+
* `maxSamples` hard cap remains the absolute ceiling.
|
|
43
|
+
*/
|
|
44
|
+
const DEFAULT_STOP_ON_STABLE = 8;
|
|
45
|
+
/**
|
|
46
|
+
* Default batch payload threshold — pause when the persisted state
|
|
47
|
+
* crosses this many bytes. 1 MB matches Phase 0.4's per-batch budget;
|
|
48
|
+
* leaves ~31 MB of headroom against `maxSessionBytes`.
|
|
49
|
+
*/
|
|
50
|
+
const DEFAULT_MAX_BATCH_BYTES = 1024 * 1024;
|
|
51
|
+
// ─── Template-path inference ──────────────────────────────────────────────
|
|
52
|
+
/**
|
|
53
|
+
* Map a concrete collection path to its template-path form per Phase 3.1
|
|
54
|
+
* lock. Doc-id segments become `{singular(parentColl)Id}` so the result
|
|
55
|
+
* matches Firestore rules' `path.raw` segments under typical naming
|
|
56
|
+
* conventions (TTT corpus verified: `ttt_lobbies` → `{lobbyId}`).
|
|
57
|
+
*
|
|
58
|
+
* Inputs alternate `coll/doc/coll/doc/.../coll`. Length is always odd (a
|
|
59
|
+
* collection path ends on a collection segment).
|
|
60
|
+
*
|
|
61
|
+
* Heuristic — agents needing strict alignment with rules should normalize
|
|
62
|
+
* both sides before joining. See Risk 6 in the implementation plan.
|
|
63
|
+
*
|
|
64
|
+
* Examples:
|
|
65
|
+
* `users` → `users`
|
|
66
|
+
* `users/uid_1/posts` → `users/{userId}/posts`
|
|
67
|
+
* `ttt_lobbies/abc/games/g1/moves` → `ttt_lobbies/{lobbyId}/games/{gameId}/moves`
|
|
68
|
+
*/
|
|
69
|
+
export function toTemplatePath(concretePath) {
|
|
70
|
+
const segs = concretePath.split('/');
|
|
71
|
+
if (segs.length % 2 === 0) {
|
|
72
|
+
throw new Error(`toTemplatePath: expected odd-length collection path, got ${segs.length} segments: ${concretePath}`);
|
|
73
|
+
}
|
|
74
|
+
const out = [];
|
|
75
|
+
for (let i = 0; i < segs.length; i++) {
|
|
76
|
+
if (i % 2 === 0) {
|
|
77
|
+
out.push(segs[i]); // collection segment
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
const parentColl = segs[i - 1];
|
|
81
|
+
out.push(`{${inferTemplateVariable(parentColl)}}`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return out.join('/');
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Convert a collection ID to the conventional template-variable name a
|
|
88
|
+
* Firestore rules author would write for its docs. Strips a trailing
|
|
89
|
+
* snake/dot-cased prefix word so `ttt_lobbies` → `lobbyId` (not
|
|
90
|
+
* `ttt_lobbieId`).
|
|
91
|
+
*/
|
|
92
|
+
export function inferTemplateVariable(collectionId) {
|
|
93
|
+
// Take the last underscore-separated word — `ttt_lobbies` → `lobbies`,
|
|
94
|
+
// `users` → `users`. Lets compound prefixes (test harness, app
|
|
95
|
+
// namespace) drop out of the derived variable name.
|
|
96
|
+
const lastWord = collectionId.split('_').pop() ?? collectionId;
|
|
97
|
+
const singular = singularize(lastWord);
|
|
98
|
+
return `${singular}Id`;
|
|
99
|
+
}
|
|
100
|
+
/** Trivial English singularizer covering the cases the corpus exercises. */
|
|
101
|
+
function singularize(word) {
|
|
102
|
+
if (word.length <= 2)
|
|
103
|
+
return word; // too short to safely strip
|
|
104
|
+
if (word.endsWith('ies'))
|
|
105
|
+
return word.slice(0, -3) + 'y'; // lobbies → lobby
|
|
106
|
+
if (word.endsWith('ses'))
|
|
107
|
+
return word.slice(0, -2); // classes → class
|
|
108
|
+
if (word.endsWith('s') && !word.endsWith('ss'))
|
|
109
|
+
return word.slice(0, -1); // users → user
|
|
110
|
+
return word;
|
|
111
|
+
}
|
|
112
|
+
// ─── Error classification (0.E) ───────────────────────────────────────────
|
|
113
|
+
/**
|
|
114
|
+
* gRPC status codes (and stringified equivalents) that the crawler treats
|
|
115
|
+
* as recoverable per prerequisite 0.E. Any other thrown error escapes —
|
|
116
|
+
* silent swallowing of structural errors would mask real bugs.
|
|
117
|
+
*
|
|
118
|
+
* - PERMISSION_DENIED (7): the canonical "subcollection has restricted IAM"
|
|
119
|
+
* - UNAVAILABLE (14): transient — tool surfaces it, agent retries
|
|
120
|
+
* - DEADLINE_EXCEEDED (4): transient — same
|
|
121
|
+
* - ABORTED (10): transient — same
|
|
122
|
+
*
|
|
123
|
+
* firebase-admin throws errors with `code` either as a numeric gRPC code
|
|
124
|
+
* or as a string ('permission-denied'); match both.
|
|
125
|
+
*/
|
|
126
|
+
const RETRYABLE_NUMERIC_CODES = new Set([4, 7, 10, 14]);
|
|
127
|
+
const RETRYABLE_STRING_CODES = new Set([
|
|
128
|
+
'PERMISSION_DENIED',
|
|
129
|
+
'UNAVAILABLE',
|
|
130
|
+
'DEADLINE_EXCEEDED',
|
|
131
|
+
'ABORTED',
|
|
132
|
+
'permission-denied',
|
|
133
|
+
'unavailable',
|
|
134
|
+
'deadline-exceeded',
|
|
135
|
+
'aborted',
|
|
136
|
+
]);
|
|
137
|
+
function classifyRpcError(err) {
|
|
138
|
+
if (err === null || typeof err !== 'object')
|
|
139
|
+
return null;
|
|
140
|
+
const e = err;
|
|
141
|
+
let codeStr = null;
|
|
142
|
+
if (typeof e.code === 'number' && RETRYABLE_NUMERIC_CODES.has(e.code)) {
|
|
143
|
+
codeStr = numericCodeToString(e.code);
|
|
144
|
+
}
|
|
145
|
+
else if (typeof e.code === 'string' && RETRYABLE_STRING_CODES.has(e.code)) {
|
|
146
|
+
codeStr = e.code.toUpperCase().replace(/-/g, '_');
|
|
147
|
+
}
|
|
148
|
+
if (codeStr === null)
|
|
149
|
+
return null;
|
|
150
|
+
const message = typeof e.message === 'string' ? e.message : String(err);
|
|
151
|
+
return { code: codeStr, message };
|
|
152
|
+
}
|
|
153
|
+
function numericCodeToString(code) {
|
|
154
|
+
switch (code) {
|
|
155
|
+
case 4: return 'DEADLINE_EXCEEDED';
|
|
156
|
+
case 7: return 'PERMISSION_DENIED';
|
|
157
|
+
case 10: return 'ABORTED';
|
|
158
|
+
case 14: return 'UNAVAILABLE';
|
|
159
|
+
default: return `CODE_${code}`;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Run an RPC, returning the value on success or null on a classified error
|
|
164
|
+
* (which is also pushed as an `error` event onto the events array).
|
|
165
|
+
*
|
|
166
|
+
* Any unrecognized error re-throws — only the codes in `RETRYABLE_*` are
|
|
167
|
+
* tolerated. This keeps SDK-contract bugs (the 0.A class of failures) loud.
|
|
168
|
+
*/
|
|
169
|
+
async function safeRpc(fn, templatePath, events) {
|
|
170
|
+
try {
|
|
171
|
+
return await fn();
|
|
172
|
+
}
|
|
173
|
+
catch (err) {
|
|
174
|
+
const classified = classifyRpcError(err);
|
|
175
|
+
if (classified === null)
|
|
176
|
+
throw err;
|
|
177
|
+
events.push({
|
|
178
|
+
kind: 'error',
|
|
179
|
+
templatePath,
|
|
180
|
+
code: classified.code,
|
|
181
|
+
message: classified.message,
|
|
182
|
+
});
|
|
183
|
+
return null;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
// ─── BFS crawler ──────────────────────────────────────────────────────────
|
|
187
|
+
/**
|
|
188
|
+
* Walk the Firestore tree breadth-first. Each layer issues its
|
|
189
|
+
* `listDocuments` + per-doc `listCollections` calls in parallel under a
|
|
190
|
+
* shared concurrency cap.
|
|
191
|
+
*
|
|
192
|
+
* Returns once every reachable collection (within `maxDepth`) is recorded.
|
|
193
|
+
* The returned `discovered` map is keyed by templatePath; `events` is the
|
|
194
|
+
* ordered event log emitted during the walk (currently only
|
|
195
|
+
* `collection_discovered`).
|
|
196
|
+
*/
|
|
197
|
+
export async function crawlStructure(db, options = {}) {
|
|
198
|
+
const maxConcurrency = options.maxConcurrency ?? DEFAULT_MAX_CONCURRENCY;
|
|
199
|
+
const maxDepth = options.maxDepth ?? DEFAULT_MAX_DEPTH;
|
|
200
|
+
const rootFilter = options.rootFilter;
|
|
201
|
+
const events = [];
|
|
202
|
+
const discovered = new Map();
|
|
203
|
+
let listOps = 0;
|
|
204
|
+
// Layer 0 — root collections. A failure here means the agent has no
|
|
205
|
+
// listCollections permission at the database root; emit `error` and
|
|
206
|
+
// return an empty result rather than throwing.
|
|
207
|
+
listOps++;
|
|
208
|
+
const rootsResult = await safeRpc(() => db.listCollections(), '', events);
|
|
209
|
+
let roots = rootsResult ?? [];
|
|
210
|
+
if (rootFilter) {
|
|
211
|
+
roots = roots.filter((c) => rootFilter(c.id));
|
|
212
|
+
}
|
|
213
|
+
for (const root of roots) {
|
|
214
|
+
recordCollection(discovered, events, root, /* depth */ 0, /* parentPath */ undefined);
|
|
215
|
+
}
|
|
216
|
+
// BFS across layers. `frontier` always holds the collection refs entering
|
|
217
|
+
// this layer; we expand each to the doc set, then per-doc subcollections,
|
|
218
|
+
// and the union of new collection refs becomes the next frontier.
|
|
219
|
+
let frontier = roots;
|
|
220
|
+
for (let depth = 0; depth < maxDepth && frontier.length > 0; depth++) {
|
|
221
|
+
// Step 1: list docs of each collection in the layer (parallel, capped).
|
|
222
|
+
// A per-collection failure surfaces as an `error` event and that
|
|
223
|
+
// collection contributes zero docs to the layer.
|
|
224
|
+
const docsByColl = await runWithLimit(frontier, maxConcurrency, async (coll) => {
|
|
225
|
+
listOps++;
|
|
226
|
+
const tpl = toTemplatePath(coll.path);
|
|
227
|
+
const docs = await safeRpc(() => coll.listDocuments(), tpl, events);
|
|
228
|
+
return docs ?? [];
|
|
229
|
+
});
|
|
230
|
+
// Attach docs to each frontier collection's discovered entry so the
|
|
231
|
+
// sampling pass can draw from them without re-listing.
|
|
232
|
+
for (let i = 0; i < frontier.length; i++) {
|
|
233
|
+
const coll = frontier[i];
|
|
234
|
+
const docs = docsByColl[i] ?? [];
|
|
235
|
+
const tpl = toTemplatePath(coll.path);
|
|
236
|
+
const entry = discovered.get(tpl);
|
|
237
|
+
if (entry)
|
|
238
|
+
entry.docRefs.push(...docs);
|
|
239
|
+
}
|
|
240
|
+
const allDocs = docsByColl.flat();
|
|
241
|
+
if (allDocs.length === 0) {
|
|
242
|
+
frontier = [];
|
|
243
|
+
break;
|
|
244
|
+
}
|
|
245
|
+
// Step 2: list subcollections under each doc (parallel, capped). A
|
|
246
|
+
// per-doc failure attributes to the parent collection's templatePath.
|
|
247
|
+
const subsByDoc = await runWithLimit(allDocs, maxConcurrency, async (doc) => {
|
|
248
|
+
listOps++;
|
|
249
|
+
// Parent collection path = doc.path with last segment stripped.
|
|
250
|
+
const parentCollPath = doc.path.slice(0, doc.path.lastIndexOf('/'));
|
|
251
|
+
const tpl = parentCollPath ? toTemplatePath(parentCollPath) : '';
|
|
252
|
+
const subs = await safeRpc(() => doc.listCollections(), tpl, events);
|
|
253
|
+
return subs ?? [];
|
|
254
|
+
});
|
|
255
|
+
// Step 3: record + accumulate into next frontier.
|
|
256
|
+
const next = [];
|
|
257
|
+
for (let i = 0; i < allDocs.length; i++) {
|
|
258
|
+
const parentDoc = allDocs[i];
|
|
259
|
+
const subs = subsByDoc[i] ?? [];
|
|
260
|
+
for (const sub of subs) {
|
|
261
|
+
recordCollection(discovered, events, sub, depth + 1, parentDoc.path);
|
|
262
|
+
next.push(sub);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
frontier = next;
|
|
266
|
+
}
|
|
267
|
+
return { events, discovered, listOps };
|
|
268
|
+
}
|
|
269
|
+
// ─── Sampling + merge integration (Item 2.3) ──────────────────────────────
|
|
270
|
+
/**
|
|
271
|
+
* Full crawl: discover structure, then sample up to `maxSamples` docs per
|
|
272
|
+
* discovered templatePath and feed them through the merge layer. Emits
|
|
273
|
+
* `schema_updated` events for every non-empty merge and `sampling_complete`
|
|
274
|
+
* once per templatePath.
|
|
275
|
+
*
|
|
276
|
+
* **Pause/resume (Item 4.2).** When a `SessionStore` is supplied, the
|
|
277
|
+
* crawler measures the persisted-state size at two pause boundaries:
|
|
278
|
+
*
|
|
279
|
+
* 1. End of every BFS layer in the structure phase
|
|
280
|
+
* 2. End of every templatePath in the sampling phase
|
|
281
|
+
*
|
|
282
|
+
* If the persisted state exceeds `maxBatchBytes` (default 1 MB), the
|
|
283
|
+
* crawler persists state and returns a `continuation` token. The agent
|
|
284
|
+
* resumes by passing `{ continuation }` on the next call. Counters
|
|
285
|
+
* (`listOps`, `readOps`) are cumulative across batches; events are
|
|
286
|
+
* per-batch only (agents accumulate them themselves).
|
|
287
|
+
*
|
|
288
|
+
* Without a `SessionStore`, the crawler runs to completion regardless of
|
|
289
|
+
* size — single-call mode is unchanged.
|
|
290
|
+
*
|
|
291
|
+
* **Continuation lifecycle.** Continuation handles are minted/validated by
|
|
292
|
+
* the supplied `SessionStore` (see `discover/session.ts`). Malformed,
|
|
293
|
+
* expired, or evicted tokens surface as a single `error` event and an
|
|
294
|
+
* otherwise-empty result — agents can re-issue without continuation
|
|
295
|
+
* per the recovery hint.
|
|
296
|
+
*/
|
|
297
|
+
export async function crawl(db, options = {}, sessions) {
|
|
298
|
+
const maxConcurrency = options.maxConcurrency ?? DEFAULT_MAX_CONCURRENCY;
|
|
299
|
+
const maxSamples = options.maxSamples ?? DEFAULT_MAX_SAMPLES;
|
|
300
|
+
const maxErrorsPerCollection = options.maxErrorsPerCollection ?? DEFAULT_MAX_ERRORS_PER_COLLECTION;
|
|
301
|
+
const stopOnStable = options.stopOnStable ?? DEFAULT_STOP_ON_STABLE;
|
|
302
|
+
const maxDepth = options.maxDepth ?? DEFAULT_MAX_DEPTH;
|
|
303
|
+
const rootFilter = options.rootFilter;
|
|
304
|
+
const maxBatchBytes = options.maxBatchBytes ?? DEFAULT_MAX_BATCH_BYTES;
|
|
305
|
+
const subtreeMultiplier = options.dryRunSubtreeMultiplier ?? DEFAULT_DRY_RUN_SUBTREE_MULTIPLIER;
|
|
306
|
+
const events = [];
|
|
307
|
+
// ─── dryRun branch (Item 5.1) ───────────────────────────────────────
|
|
308
|
+
// Issues exactly one RPC (root listCollections) and returns a heuristic
|
|
309
|
+
// projection. No documents are read, no per-doc listCollections, no
|
|
310
|
+
// sampling. Continuation pattern intentionally not supported — see the
|
|
311
|
+
// dryRun JSDoc for the agent-semantics rationale.
|
|
312
|
+
if (options.dryRun === true) {
|
|
313
|
+
if (options.continuation !== undefined) {
|
|
314
|
+
events.push({
|
|
315
|
+
kind: 'error',
|
|
316
|
+
templatePath: '',
|
|
317
|
+
code: 'DRYRUN_NO_CONTINUATION',
|
|
318
|
+
message: 'dryRun: true does not accept a continuation token — it issues no real crawl. ' +
|
|
319
|
+
'To resume a paused crawl, omit dryRun (or pass false).',
|
|
320
|
+
});
|
|
321
|
+
return emptyResult(events);
|
|
322
|
+
}
|
|
323
|
+
const rootsResult = await safeRpc(() => db.listCollections(), '', events);
|
|
324
|
+
const allRoots = rootsResult ?? [];
|
|
325
|
+
const filteredRoots = rootFilter ? allRoots.filter((c) => rootFilter(c.id)) : allRoots;
|
|
326
|
+
const rootCollectionIds = filteredRoots.map((c) => c.id);
|
|
327
|
+
for (const root of filteredRoots) {
|
|
328
|
+
events.push({ kind: 'collection_discovered', templatePath: root.id, depth: 0 });
|
|
329
|
+
}
|
|
330
|
+
const rootCount = filteredRoots.length;
|
|
331
|
+
const estimate = {
|
|
332
|
+
rootCollectionCount: rootCount,
|
|
333
|
+
rootCollectionIds,
|
|
334
|
+
maxSamples,
|
|
335
|
+
subtreeMultiplier,
|
|
336
|
+
estimatedListOps: 1 + rootCount * subtreeMultiplier,
|
|
337
|
+
estimatedReadOps: rootCount * subtreeMultiplier * maxSamples,
|
|
338
|
+
};
|
|
339
|
+
return {
|
|
340
|
+
events,
|
|
341
|
+
discovered: new Map(),
|
|
342
|
+
listOps: 1,
|
|
343
|
+
readOps: 0,
|
|
344
|
+
finalizedSchemas: new Map(),
|
|
345
|
+
complete: true,
|
|
346
|
+
dryRunCostEstimate: estimate,
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
// ─── State acquisition: resume or init ──────────────────────────────
|
|
350
|
+
let state;
|
|
351
|
+
if (options.continuation !== undefined) {
|
|
352
|
+
if (!sessions) {
|
|
353
|
+
events.push({
|
|
354
|
+
kind: 'error',
|
|
355
|
+
templatePath: '',
|
|
356
|
+
code: 'NO_SESSION_STORE',
|
|
357
|
+
message: 'Continuation token provided but no SessionStore was passed to crawl().',
|
|
358
|
+
});
|
|
359
|
+
return emptyResult(events);
|
|
360
|
+
}
|
|
361
|
+
const lookup = sessions.get(options.continuation);
|
|
362
|
+
if (!lookup.ok) {
|
|
363
|
+
events.push(sessionErrorToEvent(lookup.error));
|
|
364
|
+
return emptyResult(events);
|
|
365
|
+
}
|
|
366
|
+
state = lookup.value.state;
|
|
367
|
+
}
|
|
368
|
+
else {
|
|
369
|
+
state = {
|
|
370
|
+
phase: 'structure',
|
|
371
|
+
currentDepth: 0,
|
|
372
|
+
maxDepth,
|
|
373
|
+
frontierPaths: [],
|
|
374
|
+
discovered: {},
|
|
375
|
+
samplingQueue: [],
|
|
376
|
+
finalizedSchemas: {},
|
|
377
|
+
listOps: 0,
|
|
378
|
+
readOps: 0,
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
// Hydrate the persisted view into in-memory refs. Done once per batch.
|
|
382
|
+
const discovered = hydrateDiscovered(state.discovered, db);
|
|
383
|
+
let frontier = state.phase === 'structure' && state.frontierPaths.length > 0
|
|
384
|
+
? state.frontierPaths.map((p) => requireCollection(db, p))
|
|
385
|
+
: [];
|
|
386
|
+
// ─── Structure phase ────────────────────────────────────────────────
|
|
387
|
+
if (state.phase === 'structure') {
|
|
388
|
+
// Layer 0 bootstrap: only on a brand-new crawl (no continuation).
|
|
389
|
+
// Resumes never enter this branch — frontierPaths is restored.
|
|
390
|
+
if (state.currentDepth === 0 && frontier.length === 0 && discovered.size === 0) {
|
|
391
|
+
state.listOps++;
|
|
392
|
+
const rootsResult = await safeRpc(() => db.listCollections(), '', events);
|
|
393
|
+
let roots = rootsResult ?? [];
|
|
394
|
+
if (rootFilter)
|
|
395
|
+
roots = roots.filter((c) => rootFilter(c.id));
|
|
396
|
+
for (const root of roots) {
|
|
397
|
+
recordCollection(discovered, events, root, 0, undefined);
|
|
398
|
+
}
|
|
399
|
+
frontier = roots;
|
|
400
|
+
}
|
|
401
|
+
while (frontier.length > 0 && state.currentDepth < state.maxDepth) {
|
|
402
|
+
const depth = state.currentDepth;
|
|
403
|
+
// Step 1: list docs of each collection in this layer.
|
|
404
|
+
const docsByColl = await runWithLimit(frontier, maxConcurrency, async (coll) => {
|
|
405
|
+
state.listOps++;
|
|
406
|
+
const tpl = toTemplatePath(coll.path);
|
|
407
|
+
const docs = await safeRpc(() => coll.listDocuments(), tpl, events);
|
|
408
|
+
return docs ?? [];
|
|
409
|
+
});
|
|
410
|
+
for (let i = 0; i < frontier.length; i++) {
|
|
411
|
+
const coll = frontier[i];
|
|
412
|
+
const docs = docsByColl[i] ?? [];
|
|
413
|
+
const tpl = toTemplatePath(coll.path);
|
|
414
|
+
const entry = discovered.get(tpl);
|
|
415
|
+
if (entry)
|
|
416
|
+
entry.docRefs.push(...docs);
|
|
417
|
+
}
|
|
418
|
+
const allDocs = docsByColl.flat();
|
|
419
|
+
if (allDocs.length === 0) {
|
|
420
|
+
frontier = [];
|
|
421
|
+
state.currentDepth++;
|
|
422
|
+
break;
|
|
423
|
+
}
|
|
424
|
+
// Step 2: list subcollections under each doc.
|
|
425
|
+
const subsByDoc = await runWithLimit(allDocs, maxConcurrency, async (doc) => {
|
|
426
|
+
state.listOps++;
|
|
427
|
+
const parentCollPath = doc.path.slice(0, doc.path.lastIndexOf('/'));
|
|
428
|
+
const tpl = parentCollPath ? toTemplatePath(parentCollPath) : '';
|
|
429
|
+
const subs = await safeRpc(() => doc.listCollections(), tpl, events);
|
|
430
|
+
return subs ?? [];
|
|
431
|
+
});
|
|
432
|
+
// Step 3: record + accumulate next frontier.
|
|
433
|
+
const next = [];
|
|
434
|
+
for (let i = 0; i < allDocs.length; i++) {
|
|
435
|
+
const parentDoc = allDocs[i];
|
|
436
|
+
const subs = subsByDoc[i] ?? [];
|
|
437
|
+
for (const sub of subs) {
|
|
438
|
+
recordCollection(discovered, events, sub, depth + 1, parentDoc.path);
|
|
439
|
+
next.push(sub);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
frontier = next;
|
|
443
|
+
state.currentDepth++;
|
|
444
|
+
// Pause check: persisted-state size after this layer's work.
|
|
445
|
+
// We rebuild the persisted view first so the measurement matches
|
|
446
|
+
// what we'd actually store.
|
|
447
|
+
state.frontierPaths = frontier.map((c) => c.path);
|
|
448
|
+
state.discovered = serializeDiscovered(discovered);
|
|
449
|
+
const pause = checkPause(state, sessions, maxBatchBytes);
|
|
450
|
+
if (pause !== null) {
|
|
451
|
+
return pauseAndPersist(pause, state, events, discovered, sessions, options);
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
// Structure phase complete; transition to sampling.
|
|
455
|
+
state.phase = 'sampling';
|
|
456
|
+
state.frontierPaths = [];
|
|
457
|
+
state.samplingQueue = Array.from(discovered.keys()).filter((tpl) => !(tpl in state.finalizedSchemas));
|
|
458
|
+
}
|
|
459
|
+
// ─── Sampling phase ─────────────────────────────────────────────────
|
|
460
|
+
while (state.samplingQueue.length > 0) {
|
|
461
|
+
const tpl = state.samplingQueue[0];
|
|
462
|
+
const entry = discovered.get(tpl);
|
|
463
|
+
if (!entry) {
|
|
464
|
+
// Defensive — shouldn't happen since samplingQueue is built from
|
|
465
|
+
// discovered. Skip rather than throw.
|
|
466
|
+
state.samplingQueue.shift();
|
|
467
|
+
continue;
|
|
468
|
+
}
|
|
469
|
+
const { schema: finalizedSchema, readOps: tplReadOps } = await sampleOneTemplate(entry, { maxConcurrency, maxSamples, stopOnStable, maxErrorsPerCollection }, events);
|
|
470
|
+
state.readOps += tplReadOps;
|
|
471
|
+
// Build the CollectionSchema with subcollectionTemplatePaths populated
|
|
472
|
+
// now (rather than as a final pass) — `discovered` is fixed once the
|
|
473
|
+
// structure phase ends, so the subcollection set is knowable here.
|
|
474
|
+
state.finalizedSchemas[tpl] = {
|
|
475
|
+
templatePath: tpl,
|
|
476
|
+
examplePath: entry.examplePath,
|
|
477
|
+
schema: finalizedSchema.schema,
|
|
478
|
+
samplingComplete: finalizedSchema.samplingComplete,
|
|
479
|
+
declaredAt: finalizedSchema.declaredAt,
|
|
480
|
+
subcollectionTemplatePaths: directChildTemplatePaths(tpl, discovered),
|
|
481
|
+
};
|
|
482
|
+
state.samplingQueue.shift();
|
|
483
|
+
state.discovered = serializeDiscovered(discovered);
|
|
484
|
+
if (state.samplingQueue.length > 0) {
|
|
485
|
+
const pause = checkPause(state, sessions, maxBatchBytes);
|
|
486
|
+
if (pause !== null) {
|
|
487
|
+
return pauseAndPersist(pause, state, events, discovered, sessions, options);
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
// ─── Crawl complete ─────────────────────────────────────────────────
|
|
492
|
+
// Clean up the session if one was provided + we resumed at least once
|
|
493
|
+
// (so the agent doesn't have a stale token). Best-effort.
|
|
494
|
+
if (sessions && options.continuation)
|
|
495
|
+
sessions.delete(options.continuation);
|
|
496
|
+
const finalizedSchemas = new Map();
|
|
497
|
+
for (const [k, v] of Object.entries(state.finalizedSchemas)) {
|
|
498
|
+
finalizedSchemas.set(k, v);
|
|
499
|
+
}
|
|
500
|
+
return {
|
|
501
|
+
events,
|
|
502
|
+
discovered,
|
|
503
|
+
listOps: state.listOps,
|
|
504
|
+
readOps: state.readOps,
|
|
505
|
+
finalizedSchemas,
|
|
506
|
+
complete: true,
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
/**
|
|
510
|
+
* Sample one templatePath: read up to `maxSamples` docs in chunks of
|
|
511
|
+
* `stopOnStable`, feed each through `mergeDoc`, classify the termination
|
|
512
|
+
* via the 4-state enum. Returns the finalized schema bundle + the read
|
|
513
|
+
* count so the caller can accumulate it onto the cumulative `readOps`.
|
|
514
|
+
*
|
|
515
|
+
* Emits `schema_updated`, `error`, and `sampling_complete` events into
|
|
516
|
+
* the shared event list.
|
|
517
|
+
*/
|
|
518
|
+
async function sampleOneTemplate(entry, opts, events) {
|
|
519
|
+
const { maxConcurrency, maxSamples, stopOnStable, maxErrorsPerCollection } = opts;
|
|
520
|
+
const capRefs = entry.docRefs.slice(0, maxSamples);
|
|
521
|
+
const cappedByMax = entry.docRefs.length > maxSamples;
|
|
522
|
+
let schema = emptySchema();
|
|
523
|
+
let errorsThisCollection = 0;
|
|
524
|
+
let errorBudgetExhausted = false;
|
|
525
|
+
let consecutiveStable = 0;
|
|
526
|
+
let declaredAt = null;
|
|
527
|
+
let earlyExitViaStable = false;
|
|
528
|
+
let readOps = 0;
|
|
529
|
+
const chunkSize = Math.max(1, stopOnStable);
|
|
530
|
+
let i = 0;
|
|
531
|
+
while (i < capRefs.length && !earlyExitViaStable && !errorBudgetExhausted) {
|
|
532
|
+
const chunk = capRefs.slice(i, i + chunkSize);
|
|
533
|
+
const snaps = await runWithLimit(chunk, maxConcurrency, async (ref) => {
|
|
534
|
+
if (errorBudgetExhausted)
|
|
535
|
+
return null;
|
|
536
|
+
readOps++;
|
|
537
|
+
try {
|
|
538
|
+
return await ref.get();
|
|
539
|
+
}
|
|
540
|
+
catch (err) {
|
|
541
|
+
const classified = classifyRpcError(err);
|
|
542
|
+
if (classified === null)
|
|
543
|
+
throw err;
|
|
544
|
+
errorsThisCollection++;
|
|
545
|
+
events.push({
|
|
546
|
+
kind: 'error',
|
|
547
|
+
templatePath: entry.templatePath,
|
|
548
|
+
code: classified.code,
|
|
549
|
+
message: classified.message,
|
|
550
|
+
});
|
|
551
|
+
if (errorsThisCollection >= maxErrorsPerCollection) {
|
|
552
|
+
errorBudgetExhausted = true;
|
|
553
|
+
}
|
|
554
|
+
return null;
|
|
555
|
+
}
|
|
556
|
+
});
|
|
557
|
+
for (const snap of snaps) {
|
|
558
|
+
if (errorBudgetExhausted)
|
|
559
|
+
break;
|
|
560
|
+
if (snap === null) {
|
|
561
|
+
i++;
|
|
562
|
+
continue;
|
|
563
|
+
}
|
|
564
|
+
if (snap._fieldsProto === undefined || snap._fieldsProto === null) {
|
|
565
|
+
i++;
|
|
566
|
+
continue;
|
|
567
|
+
}
|
|
568
|
+
const { observations, reservedNames } = snapshotToObservations(snap);
|
|
569
|
+
if (Object.keys(observations).length === 0) {
|
|
570
|
+
i++;
|
|
571
|
+
continue;
|
|
572
|
+
}
|
|
573
|
+
const { next, changes } = mergeDoc(schema, observations);
|
|
574
|
+
for (const [k, reason] of Object.entries(reservedNames)) {
|
|
575
|
+
const desc = next.fields[k];
|
|
576
|
+
if (desc)
|
|
577
|
+
desc.reservedReason = reason;
|
|
578
|
+
}
|
|
579
|
+
schema = next;
|
|
580
|
+
if (changes.length > 0) {
|
|
581
|
+
events.push({
|
|
582
|
+
kind: 'schema_updated',
|
|
583
|
+
templatePath: entry.templatePath,
|
|
584
|
+
changes,
|
|
585
|
+
});
|
|
586
|
+
consecutiveStable = 0;
|
|
587
|
+
}
|
|
588
|
+
else {
|
|
589
|
+
consecutiveStable++;
|
|
590
|
+
if (declaredAt === null && consecutiveStable >= stopOnStable) {
|
|
591
|
+
declaredAt = next.samplesSeen - 1;
|
|
592
|
+
earlyExitViaStable = true;
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
i++;
|
|
596
|
+
if (earlyExitViaStable)
|
|
597
|
+
break;
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
const consumedAll = i >= capRefs.length;
|
|
601
|
+
const samplingComplete = errorBudgetExhausted
|
|
602
|
+
? 'sampling_open'
|
|
603
|
+
: earlyExitViaStable
|
|
604
|
+
? 'converged_via_stable'
|
|
605
|
+
: consumedAll && !cappedByMax
|
|
606
|
+
? 'converged_via_exhausted'
|
|
607
|
+
: 'converged_via_max';
|
|
608
|
+
events.push({
|
|
609
|
+
kind: 'sampling_complete',
|
|
610
|
+
templatePath: entry.templatePath,
|
|
611
|
+
samplingComplete,
|
|
612
|
+
samplesSeen: schema.samplesSeen,
|
|
613
|
+
declaredAt,
|
|
614
|
+
});
|
|
615
|
+
return {
|
|
616
|
+
schema: { schema, samplingComplete, declaredAt },
|
|
617
|
+
readOps,
|
|
618
|
+
};
|
|
619
|
+
}
|
|
620
|
+
// ─── Persistence helpers (Item 4.2) ───────────────────────────────────────
|
|
621
|
+
function serializeDiscovered(map) {
|
|
622
|
+
const out = {};
|
|
623
|
+
for (const [tpl, d] of map) {
|
|
624
|
+
out[tpl] = {
|
|
625
|
+
templatePath: d.templatePath,
|
|
626
|
+
depth: d.depth,
|
|
627
|
+
examplePath: d.examplePath,
|
|
628
|
+
refPaths: d.refs.map((r) => r.path),
|
|
629
|
+
docRefPaths: d.docRefs.map((r) => r.path),
|
|
630
|
+
};
|
|
631
|
+
}
|
|
632
|
+
return out;
|
|
633
|
+
}
|
|
634
|
+
function hydrateDiscovered(record, db) {
|
|
635
|
+
const map = new Map();
|
|
636
|
+
for (const [tpl, p] of Object.entries(record)) {
|
|
637
|
+
map.set(tpl, {
|
|
638
|
+
templatePath: p.templatePath,
|
|
639
|
+
depth: p.depth,
|
|
640
|
+
examplePath: p.examplePath,
|
|
641
|
+
refs: p.refPaths.map((rp) => requireCollection(db, rp)),
|
|
642
|
+
docRefs: p.docRefPaths.map((dp) => requireDoc(db, dp)),
|
|
643
|
+
});
|
|
644
|
+
}
|
|
645
|
+
return map;
|
|
646
|
+
}
|
|
647
|
+
function requireCollection(db, path) {
|
|
648
|
+
if (typeof db.collection !== 'function') {
|
|
649
|
+
throw new Error(`Cannot resume crawl: db.collection(path) is required to reconstruct refs ` +
|
|
650
|
+
`but the supplied Firestore does not implement it.`);
|
|
651
|
+
}
|
|
652
|
+
return db.collection(path);
|
|
653
|
+
}
|
|
654
|
+
function requireDoc(db, path) {
|
|
655
|
+
if (typeof db.doc !== 'function') {
|
|
656
|
+
throw new Error(`Cannot resume crawl: db.doc(path) is required to reconstruct refs ` +
|
|
657
|
+
`but the supplied Firestore does not implement it.`);
|
|
658
|
+
}
|
|
659
|
+
return db.doc(path);
|
|
660
|
+
}
|
|
661
|
+
/**
|
|
662
|
+
* Returns `{ bytes }` if the crawl should pause now, else `null`.
|
|
663
|
+
* Re-uses the same `JSON.stringify` work for both the threshold check
|
|
664
|
+
* and the eventual `update`/`create` call so we don't serialize twice.
|
|
665
|
+
*/
|
|
666
|
+
function checkPause(state, sessions, maxBatchBytes) {
|
|
667
|
+
if (!sessions)
|
|
668
|
+
return null;
|
|
669
|
+
const serialized = JSON.stringify(state);
|
|
670
|
+
const bytes = serialized.length;
|
|
671
|
+
if (bytes < maxBatchBytes)
|
|
672
|
+
return null;
|
|
673
|
+
return { bytes, serialized };
|
|
674
|
+
}
|
|
675
|
+
function pauseAndPersist(pause, state, events, discovered, sessions, options) {
|
|
676
|
+
// Reuse-or-create: if the agent passed a continuation, keep the same
|
|
677
|
+
// session id (so the agent's existing handle stays valid). Otherwise
|
|
678
|
+
// mint a fresh session.
|
|
679
|
+
let token;
|
|
680
|
+
if (options.continuation !== undefined) {
|
|
681
|
+
const r = sessions.update(options.continuation, state, pause.bytes);
|
|
682
|
+
if (!r.ok) {
|
|
683
|
+
events.push(sessionErrorToEvent(r.error));
|
|
684
|
+
return emptyResult(events);
|
|
685
|
+
}
|
|
686
|
+
token = r.value.token;
|
|
687
|
+
}
|
|
688
|
+
else {
|
|
689
|
+
const r = sessions.create(state, pause.bytes);
|
|
690
|
+
if (!r.ok) {
|
|
691
|
+
events.push(sessionErrorToEvent(r.error));
|
|
692
|
+
return emptyResult(events);
|
|
693
|
+
}
|
|
694
|
+
token = r.value.token;
|
|
695
|
+
}
|
|
696
|
+
const finalizedSchemas = new Map();
|
|
697
|
+
for (const [k, v] of Object.entries(state.finalizedSchemas)) {
|
|
698
|
+
finalizedSchemas.set(k, v);
|
|
699
|
+
}
|
|
700
|
+
return {
|
|
701
|
+
events,
|
|
702
|
+
discovered,
|
|
703
|
+
listOps: state.listOps,
|
|
704
|
+
readOps: state.readOps,
|
|
705
|
+
finalizedSchemas,
|
|
706
|
+
continuation: token,
|
|
707
|
+
complete: false,
|
|
708
|
+
};
|
|
709
|
+
}
|
|
710
|
+
function sessionErrorToEvent(err) {
|
|
711
|
+
return {
|
|
712
|
+
kind: 'error',
|
|
713
|
+
templatePath: '',
|
|
714
|
+
code: err.code,
|
|
715
|
+
message: `${err.message} (recoveryHint: ${err.recoveryHint})`,
|
|
716
|
+
};
|
|
717
|
+
}
|
|
718
|
+
function emptyResult(events) {
|
|
719
|
+
return {
|
|
720
|
+
events,
|
|
721
|
+
discovered: new Map(),
|
|
722
|
+
listOps: 0,
|
|
723
|
+
readOps: 0,
|
|
724
|
+
finalizedSchemas: new Map(),
|
|
725
|
+
complete: true,
|
|
726
|
+
};
|
|
727
|
+
}
|
|
728
|
+
function directChildTemplatePaths(parentTpl, discovered) {
|
|
729
|
+
const prefix = parentTpl + '/';
|
|
730
|
+
const out = [];
|
|
731
|
+
for (const tpl of discovered.keys()) {
|
|
732
|
+
if (!tpl.startsWith(prefix))
|
|
733
|
+
continue;
|
|
734
|
+
const tail = tpl.slice(prefix.length);
|
|
735
|
+
if (tail.split('/').length === 2)
|
|
736
|
+
out.push(tpl); // {docId}/childColl
|
|
737
|
+
}
|
|
738
|
+
return out;
|
|
739
|
+
}
|
|
740
|
+
/**
|
|
741
|
+
* Emit `collection_discovered` once per distinct templatePath, but
|
|
742
|
+
* accumulate all concrete refs (so Item 2.3 can sample across every
|
|
743
|
+
* concrete instance of a template, not just the first one encountered).
|
|
744
|
+
*/
|
|
745
|
+
function recordCollection(discovered, events, ref, depth, parentPath) {
|
|
746
|
+
const templatePath = toTemplatePath(ref.path);
|
|
747
|
+
const existing = discovered.get(templatePath);
|
|
748
|
+
if (existing) {
|
|
749
|
+
existing.refs.push(ref);
|
|
750
|
+
return;
|
|
751
|
+
}
|
|
752
|
+
discovered.set(templatePath, {
|
|
753
|
+
templatePath,
|
|
754
|
+
depth,
|
|
755
|
+
examplePath: ref.path,
|
|
756
|
+
refs: [ref],
|
|
757
|
+
docRefs: [],
|
|
758
|
+
});
|
|
759
|
+
const event = parentPath
|
|
760
|
+
? { kind: 'collection_discovered', templatePath, depth, parentPath }
|
|
761
|
+
: { kind: 'collection_discovered', templatePath, depth };
|
|
762
|
+
events.push(event);
|
|
763
|
+
}
|
|
764
|
+
//# sourceMappingURL=crawler.js.map
|