@pyric/cli 0.1.0-alpha.10 → 0.1.0-alpha.12
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/README.md.orig +2 -2
- package/dist/assurance/.generated/conformance-verdicts.d.ts +16 -0
- package/dist/assurance/.generated/conformance-verdicts.d.ts.map +1 -1
- package/dist/assurance/.generated/conformance-verdicts.js +16 -0
- package/dist/assurance/.generated/conformance-verdicts.js.map +1 -1
- package/dist/bridge/server/peer.d.ts +1 -1
- package/dist/bridge/server.d.ts +1 -1
- package/dist/bridge/server.js +1 -1
- package/dist/cli/index.d.ts +11 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +13 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/init.d.ts +3 -3
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +5 -5
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/serve.d.ts.map +1 -1
- package/dist/cli/serve.js +8 -2
- package/dist/cli/serve.js.map +1 -1
- package/dist/conformance/.generated/can-i-use-browser.d.ts.map +1 -1
- package/dist/conformance/.generated/can-i-use-browser.js +1 -1
- package/dist/conformance/.generated/can-i-use-browser.js.map +1 -1
- package/dist/conformance/.generated/can-i-use.d.ts.map +1 -1
- package/dist/conformance/.generated/can-i-use.js +2 -2
- package/dist/conformance/.generated/can-i-use.js.map +1 -1
- package/dist/conformance/.generated/conformance-docs.d.ts +12 -0
- package/dist/conformance/.generated/conformance-docs.d.ts.map +1 -0
- package/dist/conformance/.generated/conformance-docs.js +2 -0
- package/dist/conformance/.generated/conformance-docs.js.map +1 -0
- package/dist/conformance/docs.d.ts +6 -0
- package/dist/conformance/docs.d.ts.map +1 -0
- package/dist/conformance/docs.js +6 -0
- package/dist/conformance/docs.js.map +1 -0
- package/dist/remote/index.d.ts.map +1 -1
- package/dist/remote/index.js +1 -0
- package/dist/remote/index.js.map +1 -1
- package/dist/serve/activity-guard.d.ts +4 -0
- package/dist/serve/activity-guard.d.ts.map +1 -0
- package/dist/serve/activity-guard.js +22 -0
- package/dist/serve/activity-guard.js.map +1 -0
- package/dist/serve/activity-route.d.ts +4 -0
- package/dist/serve/activity-route.d.ts.map +1 -0
- package/dist/serve/activity-route.js +157 -0
- package/dist/serve/activity-route.js.map +1 -0
- package/dist/serve/activity-warning.d.ts +4 -0
- package/dist/serve/activity-warning.d.ts.map +1 -0
- package/dist/serve/activity-warning.js +21 -0
- package/dist/serve/activity-warning.js.map +1 -0
- package/dist/serve/bridge-mount.d.ts +5 -0
- package/dist/serve/bridge-mount.d.ts.map +1 -1
- package/dist/serve/bridge-mount.js +1 -0
- package/dist/serve/bridge-mount.js.map +1 -1
- package/dist/serve/docs-ui/404.html +3 -0
- package/dist/serve/docs-ui/_astro/{_slug_.DPUwShm2.css → _slug_.CXh9yTP1.css} +1 -1
- package/dist/serve/docs-ui/_astro/_slug_.DUci-duz.css +1 -0
- package/dist/serve/docs-ui/docs/_rhythm/index.html +2 -1
- package/dist/serve/docs-ui/docs/agent/set-up-your-agent/index.html +3 -2
- package/dist/serve/docs-ui/docs/agent/set-up-your-agent.md +1 -1
- package/dist/serve/docs-ui/docs/agent/watch-and-review/index.html +2 -1
- package/dist/serve/docs-ui/docs/agent/work-with-an-agent/index.html +2 -1
- package/dist/serve/docs-ui/docs/ai-compat/index.html +2 -1
- package/dist/serve/docs-ui/docs/api-reference/index.html +51 -49
- package/dist/serve/docs-ui/docs/api-reference.md +3 -3
- package/dist/serve/docs-ui/docs/app-compat/index.html +2 -1
- package/dist/serve/docs-ui/docs/auth-compat/index.html +2 -1
- package/dist/serve/docs-ui/docs/build/ai-logic/index.html +18 -3
- package/dist/serve/docs-ui/docs/build/ai-logic.md +30 -2
- package/dist/serve/docs-ui/docs/build/authentication/index.html +2 -1
- package/dist/serve/docs-ui/docs/build/authentication.md +1 -1
- package/dist/serve/docs-ui/docs/build/cloud-firestore/index.html +2 -1
- package/dist/serve/docs-ui/docs/build/cloud-messaging/index.html +46 -2
- package/dist/serve/docs-ui/docs/build/cloud-messaging.md +56 -1
- package/dist/serve/docs-ui/docs/build/cloud-storage/index.html +2 -1
- package/dist/serve/docs-ui/docs/build/cloud-storage.md +1 -1
- package/dist/serve/docs-ui/docs/build/realtime-database/index.html +21 -3
- package/dist/serve/docs-ui/docs/build/realtime-database.md +25 -1
- package/dist/serve/docs-ui/docs/conformance-scores/index.html +2 -1
- package/dist/serve/docs-ui/docs/create-pyric-reference-api/index.html +61 -28
- package/dist/serve/docs-ui/docs/create-pyric-reference-api.md +65 -20
- package/dist/serve/docs-ui/docs/database-compat/index.html +2 -1
- package/dist/serve/docs-ui/docs/firestore-compat/index.html +6 -5
- package/dist/serve/docs-ui/docs/firestore-compat.md +4 -4
- package/dist/serve/docs-ui/docs/functions-rtdb-compat/index.html +2 -1
- package/dist/serve/docs-ui/docs/get-started/how-the-swap-works/index.html +2 -1
- package/dist/serve/docs-ui/docs/get-started/start-building/index.html +4 -3
- package/dist/serve/docs-ui/docs/get-started/start-building.md +2 -2
- package/dist/serve/docs-ui/docs/index.json +979 -579
- package/dist/serve/docs-ui/docs/messaging-compat/index.html +2 -1
- package/dist/serve/docs-ui/docs/observe/see-whats-happening/index.html +2 -1
- package/dist/serve/docs-ui/docs/observe/shape-your-data/index.html +2 -1
- package/dist/serve/docs-ui/docs/overview/index.html +2 -1
- package/dist/serve/docs-ui/docs/pyric-admin-app-reference-api/index.html +5 -4
- package/dist/serve/docs-ui/docs/pyric-admin-app-reference-api.md +3 -4
- package/dist/serve/docs-ui/docs/pyric-admin-auth-reference-api/index.html +5 -4
- package/dist/serve/docs-ui/docs/pyric-admin-auth-reference-api.md +3 -4
- package/dist/serve/docs-ui/docs/pyric-admin-database-reference-api/index.html +5 -4
- package/dist/serve/docs-ui/docs/pyric-admin-database-reference-api.md +3 -4
- package/dist/serve/docs-ui/docs/pyric-admin-firestore-reference-api/index.html +2503 -12
- package/dist/serve/docs-ui/docs/pyric-admin-firestore-reference-api.md +2219 -8
- package/dist/serve/docs-ui/docs/pyric-admin-messaging-reference-api/index.html +916 -0
- package/dist/serve/docs-ui/docs/pyric-admin-messaging-reference-api.md +706 -0
- package/dist/serve/docs-ui/docs/pyric-admin-storage-reference-api/index.html +4 -3
- package/dist/serve/docs-ui/docs/pyric-admin-storage-reference-api.md +2 -3
- package/dist/serve/docs-ui/docs/pyric-ai-reference-api/index.html +16 -11
- package/dist/serve/docs-ui/docs/pyric-ai-reference-api.md +14 -13
- package/dist/serve/docs-ui/docs/pyric-ai-scripting-reference-api/index.html +4 -3
- package/dist/serve/docs-ui/docs/pyric-ai-scripting-reference-api.md +2 -3
- package/dist/serve/docs-ui/docs/pyric-app-reference-api/index.html +7 -2
- package/dist/serve/docs-ui/docs/pyric-app-reference-api.md +5 -2
- package/dist/serve/docs-ui/docs/pyric-auth-reference-api/index.html +23 -12
- package/dist/serve/docs-ui/docs/pyric-auth-reference-api.md +15 -12
- package/dist/serve/docs-ui/docs/pyric-cli-assurance-browser-reference-api/index.html +10 -48
- package/dist/serve/docs-ui/docs/pyric-cli-assurance-browser-reference-api.md +11 -24
- package/dist/serve/docs-ui/docs/pyric-cli-assurance-reference-api/index.html +87 -97
- package/dist/serve/docs-ui/docs/pyric-cli-assurance-reference-api.md +53 -65
- package/dist/serve/docs-ui/docs/pyric-cli-bridge-client-reference-api/index.html +14 -15
- package/dist/serve/docs-ui/docs/pyric-cli-bridge-client-reference-api.md +19 -28
- package/dist/serve/docs-ui/docs/pyric-cli-bridge-reference-api/index.html +4 -3
- package/dist/serve/docs-ui/docs/pyric-cli-bridge-reference-api.md +2 -3
- package/dist/serve/docs-ui/docs/pyric-cli-conformance-browser-reference-api/index.html +3 -2
- package/dist/serve/docs-ui/docs/pyric-cli-conformance-browser-reference-api.md +1 -2
- package/dist/serve/docs-ui/docs/pyric-cli-conformance-docs-reference-api/index.html +51 -0
- package/dist/serve/docs-ui/docs/pyric-cli-conformance-docs-reference-api.md +36 -0
- package/dist/serve/docs-ui/docs/pyric-cli-conformance-reference-api/index.html +3 -2
- package/dist/serve/docs-ui/docs/pyric-cli-conformance-reference-api.md +1 -2
- package/dist/serve/docs-ui/docs/pyric-cli-credentials-node-reference-api/index.html +3 -2
- package/dist/serve/docs-ui/docs/pyric-cli-credentials-node-reference-api.md +1 -2
- package/dist/serve/docs-ui/docs/pyric-cli-discover-reference-api/index.html +3 -2
- package/dist/serve/docs-ui/docs/pyric-cli-discover-reference-api.md +1 -2
- package/dist/serve/docs-ui/docs/pyric-cli-register-reference-api/index.html +3 -2
- package/dist/serve/docs-ui/docs/pyric-cli-register-reference-api.md +1 -2
- package/dist/serve/docs-ui/docs/pyric-cli-remote-reference-api/index.html +1067 -83
- package/dist/serve/docs-ui/docs/pyric-cli-remote-reference-api.md +1291 -160
- package/dist/serve/docs-ui/docs/pyric-cli-serve-worker-reference-api/index.html +253 -157
- package/dist/serve/docs-ui/docs/pyric-cli-serve-worker-reference-api.md +179 -85
- package/dist/serve/docs-ui/docs/pyric-cli-verify-reference-api/index.html +72 -7
- package/dist/serve/docs-ui/docs/pyric-cli-verify-reference-api.md +22 -7
- package/dist/serve/docs-ui/docs/pyric-cli-vite-reference-api/index.html +33 -12
- package/dist/serve/docs-ui/docs/pyric-cli-vite-reference-api.md +15 -12
- package/dist/serve/docs-ui/docs/pyric-database-reference-api/index.html +18 -17
- package/dist/serve/docs-ui/docs/pyric-database-reference-api.md +19 -22
- package/dist/serve/docs-ui/docs/pyric-firestore-reference-api/index.html +1512 -545
- package/dist/serve/docs-ui/docs/pyric-firestore-reference-api.md +1311 -316
- package/dist/serve/docs-ui/docs/pyric-messaging-reference-api/index.html +5 -4
- package/dist/serve/docs-ui/docs/pyric-messaging-reference-api.md +3 -4
- package/dist/serve/docs-ui/docs/pyric-messaging-sw-reference-api/index.html +69 -369
- package/dist/serve/docs-ui/docs/pyric-messaging-sw-reference-api.md +103 -216
- package/dist/serve/docs-ui/docs/pyric-rules-reference-api/index.html +10 -9
- package/dist/serve/docs-ui/docs/pyric-rules-reference-api.md +9 -10
- package/dist/serve/docs-ui/docs/pyric-sandbox-database-reference-api/index.html +8 -7
- package/dist/serve/docs-ui/docs/pyric-sandbox-database-reference-api.md +6 -7
- package/dist/serve/docs-ui/docs/pyric-sandbox-firestore-reference-api/index.html +10 -9
- package/dist/serve/docs-ui/docs/pyric-sandbox-firestore-reference-api.md +9 -10
- package/dist/serve/docs-ui/docs/pyric-sandbox-reference-api/index.html +371 -884
- package/dist/serve/docs-ui/docs/pyric-sandbox-reference-api.md +369 -883
- package/dist/serve/docs-ui/docs/pyric-storage-reference-api/index.html +25 -17
- package/dist/serve/docs-ui/docs/pyric-storage-reference-api.md +21 -19
- package/dist/serve/docs-ui/docs/pyric-ui-agents-reference-api/index.html +3 -2
- package/dist/serve/docs-ui/docs/pyric-ui-agents-reference-api.md +1 -2
- package/dist/serve/docs-ui/docs/pyric-ui-auth-hooks-reference-api/index.html +63 -776
- package/dist/serve/docs-ui/docs/pyric-ui-auth-hooks-reference-api.md +69 -510
- package/dist/serve/docs-ui/docs/pyric-ui-auth-reference-api/index.html +22 -21
- package/dist/serve/docs-ui/docs/pyric-ui-auth-reference-api.md +29 -30
- package/dist/serve/docs-ui/docs/pyric-ui-events-hooks-reference-api/index.html +15 -168
- package/dist/serve/docs-ui/docs/pyric-ui-events-hooks-reference-api.md +17 -87
- package/dist/serve/docs-ui/docs/pyric-ui-events-reference-api/index.html +6 -5
- package/dist/serve/docs-ui/docs/pyric-ui-events-reference-api.md +5 -6
- package/dist/serve/docs-ui/docs/pyric-ui-firestore-hooks-reference-api/index.html +82 -970
- package/dist/serve/docs-ui/docs/pyric-ui-firestore-hooks-reference-api.md +104 -479
- package/dist/serve/docs-ui/docs/pyric-ui-firestore-reference-api/index.html +30 -29
- package/dist/serve/docs-ui/docs/pyric-ui-firestore-reference-api.md +54 -55
- package/dist/serve/docs-ui/docs/pyric-ui-primitives-reference-api/index.html +3 -2
- package/dist/serve/docs-ui/docs/pyric-ui-primitives-reference-api.md +1 -2
- package/dist/serve/docs-ui/docs/pyric-ui-rtdb-reference-api/index.html +5 -4
- package/dist/serve/docs-ui/docs/pyric-ui-rtdb-reference-api.md +3 -4
- package/dist/serve/docs-ui/docs/pyric-ui-rules-hooks-reference-api/index.html +9 -124
- package/dist/serve/docs-ui/docs/pyric-ui-rules-hooks-reference-api.md +7 -58
- package/dist/serve/docs-ui/docs/pyric-ui-rules-reference-api/index.html +24 -23
- package/dist/serve/docs-ui/docs/pyric-ui-rules-reference-api.md +31 -34
- package/dist/serve/docs-ui/docs/pyric-ui-storage-hooks-reference-api/index.html +104 -1385
- package/dist/serve/docs-ui/docs/pyric-ui-storage-hooks-reference-api.md +133 -817
- package/dist/serve/docs-ui/docs/pyric-ui-storage-reference-api/index.html +34 -33
- package/dist/serve/docs-ui/docs/pyric-ui-storage-reference-api.md +37 -38
- package/dist/serve/docs-ui/docs/pyric-ui-traffic-hooks-reference-api/index.html +116 -1169
- package/dist/serve/docs-ui/docs/pyric-ui-traffic-hooks-reference-api.md +142 -590
- package/dist/serve/docs-ui/docs/pyric-ui-traffic-reference-api/index.html +4 -3
- package/dist/serve/docs-ui/docs/pyric-ui-traffic-reference-api.md +3 -4
- package/dist/serve/docs-ui/docs/rules-compat/index.html +34 -1
- package/dist/serve/docs-ui/docs/rules-compat.md +32 -0
- package/dist/serve/docs-ui/docs/secure/audit-your-rules/index.html +19 -2
- package/dist/serve/docs-ui/docs/secure/audit-your-rules.md +32 -0
- package/dist/serve/docs-ui/docs/secure/firestore-rules-limits/index.html +2 -1
- package/dist/serve/docs-ui/docs/secure/read-a-denial/index.html +2 -1
- package/dist/serve/docs-ui/docs/secure/rtdb-rules-in-typescript/index.html +2 -1
- package/dist/serve/docs-ui/docs/secure/rtdb-rules-in-typescript.md +1 -1
- package/dist/serve/docs-ui/docs/secure/rules-standard-library/index.html +2 -1
- package/dist/serve/docs-ui/docs/secure/secure-it-with-rules/index.html +2 -1
- package/dist/serve/docs-ui/docs/secure/simulate-and-lint/index.html +2 -1
- package/dist/serve/docs-ui/docs/secure/write-a-rules-test-suite/index.html +2 -1
- package/dist/serve/docs-ui/docs/ship/ship-to-production/index.html +2 -1
- package/dist/serve/docs-ui/docs/ship/test-in-node/index.html +2 -1
- package/dist/serve/docs-ui/docs/storage-compat/index.html +2 -1
- package/dist/serve/docs-ui/docs/trust/how-we-know-it-matches-firebase/index.html +2 -1
- package/dist/serve/docs-ui/docs/trust/versioning-and-compatibility/index.html +2 -1
- package/dist/serve/docs-ui/llms.txt +2 -1
- package/dist/serve/entries/ai.d.ts.map +1 -1
- package/dist/serve/entries/ai.js +39 -1
- package/dist/serve/entries/ai.js.map +1 -1
- package/dist/serve/entries/messaging-sw.d.ts.map +1 -1
- package/dist/serve/entries/messaging-sw.js +5 -1
- package/dist/serve/entries/messaging-sw.js.map +1 -1
- package/dist/serve/entries/messaging.d.ts.map +1 -1
- package/dist/serve/entries/messaging.js +7 -1
- package/dist/serve/entries/messaging.js.map +1 -1
- package/dist/serve/entries/runtime.d.ts.map +1 -1
- package/dist/serve/entries/runtime.js +20 -1
- package/dist/serve/entries/runtime.js.map +1 -1
- package/dist/serve/init-payload.d.ts +25 -0
- package/dist/serve/init-payload.d.ts.map +1 -1
- package/dist/serve/namespace.d.ts +39 -0
- package/dist/serve/namespace.d.ts.map +1 -1
- package/dist/serve/namespace.js +80 -1
- package/dist/serve/namespace.js.map +1 -1
- package/dist/serve/standalone-assets.d.ts +11 -9
- package/dist/serve/standalone-assets.d.ts.map +1 -1
- package/dist/serve/standalone-assets.js +6 -5
- package/dist/serve/standalone-assets.js.map +1 -1
- package/dist/serve/studio-ui/assets/{RulesCodeEditor-CXdSLKhO.js → RulesCodeEditor-CxVYcZXw.js} +1 -1
- package/dist/serve/studio-ui/assets/index-cpSfgQ7H.js +1218 -0
- package/dist/serve/studio-ui/assets/seed-DeuFKi4J.js +20 -0
- package/dist/serve/studio-ui/index.html +1 -1
- package/dist/serve/vite-plugin.d.ts +92 -15
- package/dist/serve/vite-plugin.d.ts.map +1 -1
- package/dist/serve/vite-plugin.js +281 -11
- package/dist/serve/vite-plugin.js.map +1 -1
- package/dist/serve/worker/activity-bootstrap.d.ts +8 -0
- package/dist/serve/worker/activity-bootstrap.d.ts.map +1 -0
- package/dist/serve/worker/activity-bootstrap.js +11 -0
- package/dist/serve/worker/activity-bootstrap.js.map +1 -0
- package/dist/serve/worker/client/connection.d.ts.map +1 -1
- package/dist/serve/worker/client/connection.js +17 -5
- package/dist/serve/worker/client/connection.js.map +1 -1
- package/dist/serve/worker/client/core.d.ts +2 -2
- package/dist/serve/worker/client/core.d.ts.map +1 -1
- package/dist/serve/worker/client/core.js +33 -5
- package/dist/serve/worker/client/core.js.map +1 -1
- package/dist/serve/worker/client/firestore-writes.d.ts.map +1 -1
- package/dist/serve/worker/client/firestore-writes.js +1 -0
- package/dist/serve/worker/client/firestore-writes.js.map +1 -1
- package/dist/serve/worker/client/messaging.d.ts +9 -1
- package/dist/serve/worker/client/messaging.d.ts.map +1 -1
- package/dist/serve/worker/client/messaging.js +15 -0
- package/dist/serve/worker/client/messaging.js.map +1 -1
- package/dist/serve/worker/client/studio.d.ts +10 -0
- package/dist/serve/worker/client/studio.d.ts.map +1 -1
- package/dist/serve/worker/client/studio.js +11 -0
- package/dist/serve/worker/client/studio.js.map +1 -1
- package/dist/serve/worker/durable-persistence.d.ts +12 -0
- package/dist/serve/worker/durable-persistence.d.ts.map +1 -0
- package/dist/serve/worker/durable-persistence.js +118 -0
- package/dist/serve/worker/durable-persistence.js.map +1 -0
- package/dist/serve/worker/entry.d.ts +7 -3
- package/dist/serve/worker/entry.d.ts.map +1 -1
- package/dist/serve/worker/entry.js +7 -3
- package/dist/serve/worker/entry.js.map +1 -1
- package/dist/serve/worker/host/core.d.ts +9 -5
- package/dist/serve/worker/host/core.d.ts.map +1 -1
- package/dist/serve/worker/host/core.js +34 -9
- package/dist/serve/worker/host/core.js.map +1 -1
- package/dist/serve/worker/host/dispatch.d.ts.map +1 -1
- package/dist/serve/worker/host/dispatch.js +9 -2
- package/dist/serve/worker/host/dispatch.js.map +1 -1
- package/dist/serve/worker/host/firestore-writes.d.ts.map +1 -1
- package/dist/serve/worker/host/firestore-writes.js +3 -2
- package/dist/serve/worker/host/firestore-writes.js.map +1 -1
- package/dist/serve/worker/host/studio.d.ts +1 -1
- package/dist/serve/worker/host/studio.d.ts.map +1 -1
- package/dist/serve/worker/host/studio.js +36 -1
- package/dist/serve/worker/host/studio.js.map +1 -1
- package/dist/serve/worker/host/subscriptions.d.ts.map +1 -1
- package/dist/serve/worker/host/subscriptions.js +27 -7
- package/dist/serve/worker/host/subscriptions.js.map +1 -1
- package/dist/serve/worker/host-context.d.ts +15 -0
- package/dist/serve/worker/host-context.d.ts.map +1 -1
- package/dist/serve/worker/host-context.js +10 -0
- package/dist/serve/worker/host-context.js.map +1 -1
- package/dist/serve/worker/host-messaging.d.ts.map +1 -1
- package/dist/serve/worker/host-messaging.js +9 -2
- package/dist/serve/worker/host-messaging.js.map +1 -1
- package/dist/serve/worker/index.d.ts +3 -2
- package/dist/serve/worker/index.d.ts.map +1 -1
- package/dist/serve/worker/index.js +4 -1
- package/dist/serve/worker/index.js.map +1 -1
- package/dist/serve/worker/protocol.d.ts +25 -3
- package/dist/serve/worker/protocol.d.ts.map +1 -1
- package/dist/serve/worker/protocol.js +2 -2
- package/dist/serve/worker/protocol.js.map +1 -1
- package/dist/serve/worker/serve-init.d.ts +23 -37
- package/dist/serve/worker/serve-init.d.ts.map +1 -1
- package/dist/serve/worker/serve-init.js +95 -172
- package/dist/serve/worker/serve-init.js.map +1 -1
- package/dist/vite.d.ts +4 -4
- package/dist/vite.d.ts.map +1 -1
- package/dist/vite.js +3 -3
- package/dist/vite.js.map +1 -1
- package/package.json +9 -4
- package/src/assurance/.generated/conformance-verdicts.ts +1090 -0
- package/src/assurance/attachment.ts +211 -0
- package/src/assurance/browser.ts +80 -0
- package/src/assurance/campaign.ts +496 -0
- package/src/assurance/capabilities.ts +446 -0
- package/src/assurance/cases.ts +43 -0
- package/src/assurance/index.ts +75 -0
- package/src/assurance/runner.ts +885 -0
- package/src/assurance/tool-names.ts +15 -0
- package/src/assurance/tools.ts +830 -0
- package/src/assurance/types.ts +352 -0
- package/src/assurance/validation.ts +434 -0
- package/src/bridge/client/bridge.ts +550 -0
- package/src/bridge/client/dispatch.ts +137 -0
- package/src/bridge/client.ts +45 -0
- package/src/bridge/protocol.ts +351 -0
- package/src/bridge/server/audit.ts +53 -0
- package/src/bridge/server/bridge.ts +597 -0
- package/src/bridge/server/headless.ts +160 -0
- package/src/bridge/server/json-schema-to-zod.ts +108 -0
- package/src/bridge/server/local-bridge.ts +66 -0
- package/src/bridge/server/logger.ts +50 -0
- package/src/bridge/server/mcp-contract.ts +93 -0
- package/src/bridge/server/mcp.ts +129 -0
- package/src/bridge/server/peer.ts +232 -0
- package/src/bridge/server/standalone.ts +347 -0
- package/src/bridge/server/tool-metadata.ts +99 -0
- package/src/bridge/server.ts +28 -0
- package/src/cli/can-i-use.ts +50 -0
- package/src/cli/cli.test.ts +493 -0
- package/src/cli/database-rules.ts +329 -0
- package/src/cli/dev-runner.ts +282 -0
- package/src/cli/firebase-json.ts +100 -0
- package/src/cli/firestore-indexes.ts +70 -0
- package/src/cli/index.ts +425 -0
- package/src/cli/init.ts +260 -0
- package/src/cli/mcp-proxy.ts +196 -0
- package/src/cli/parse-args.ts +80 -0
- package/src/cli/rules.ts +259 -0
- package/src/cli/scope.ts +67 -0
- package/src/cli/serve.ts +996 -0
- package/src/cli/service-commands.ts +73 -0
- package/src/cli/snapshot.ts +164 -0
- package/src/cli/storage-rules.ts +172 -0
- package/src/cli/verify.ts +416 -0
- package/src/conformance/.generated/can-i-use-browser.ts +113 -0
- package/src/conformance/.generated/can-i-use.ts +117 -0
- package/src/conformance/.generated/conformance-docs.ts +14 -0
- package/src/conformance/browser.ts +24 -0
- package/src/conformance/can-i-use-tool.ts +51 -0
- package/src/conformance/can-i-use.ts +18 -0
- package/src/conformance/docs.ts +8 -0
- package/src/conformance/index.ts +20 -0
- package/src/conformance/tools.ts +16 -0
- package/src/credentials/core/memoize-ttl.ts +142 -0
- package/src/credentials/core/types.ts +10 -0
- package/src/credentials/node/from-adc.ts +96 -0
- package/src/credentials/node/from-service-account.ts +133 -0
- package/src/credentials/node/index.ts +6 -0
- package/src/discover/concurrency.ts +127 -0
- package/src/discover/crawler-adapter.ts +142 -0
- package/src/discover/crawler.ts +1127 -0
- package/src/discover/credential-free.ts +27 -0
- package/src/discover/findCollectionGroup.ts +131 -0
- package/src/discover/firestore-source.ts +59 -0
- package/src/discover/index.ts +5 -0
- package/src/discover/merge.ts +523 -0
- package/src/discover/session.ts +402 -0
- package/src/discover/tools.ts +201 -0
- package/src/discover/types.ts +187 -0
- package/src/discover/wire.ts +324 -0
- package/src/functions-rtdb/child.ts +382 -0
- package/src/functions-rtdb/delivery.ts +7 -0
- package/src/functions-rtdb/discovery.ts +136 -0
- package/src/functions-rtdb/event.ts +64 -0
- package/src/functions-rtdb/execution.ts +111 -0
- package/src/functions-rtdb/in-memory-delivery.ts +40 -0
- package/src/functions-rtdb/project.ts +74 -0
- package/src/functions-rtdb/projection.ts +104 -0
- package/src/functions-rtdb/reference-pattern.ts +20 -0
- package/src/functions-rtdb/remote-delivery.ts +23 -0
- package/src/pkg-version.ts +49 -0
- package/src/register/esm-exports.ts +63 -0
- package/src/register/hooks.ts +30 -0
- package/src/register/index.ts +150 -0
- package/src/register/mapping.ts +33 -0
- package/src/remote/index.ts +1050 -0
- package/src/rtdb/crawl-snapshot.ts +118 -0
- package/src/rtdb/inspection.ts +137 -0
- package/src/rtdb/load-rules-document.ts +56 -0
- package/src/rtdb/rules-generation-tool.ts +38 -0
- package/src/rtdb/rules-json.ts +29 -0
- package/src/serve/activity-guard.ts +29 -0
- package/src/serve/activity-route.ts +164 -0
- package/src/serve/activity-warning.ts +26 -0
- package/src/serve/bridge-mount.ts +200 -0
- package/src/serve/bundler.ts +493 -0
- package/src/serve/capture-store.ts +65 -0
- package/src/serve/discovery.ts +199 -0
- package/src/serve/entries/ai.ts +292 -0
- package/src/serve/entries/app-backend.ts +4 -0
- package/src/serve/entries/app-client.ts +26 -0
- package/src/serve/entries/app-session-store.ts +47 -0
- package/src/serve/entries/app.ts +11 -0
- package/src/serve/entries/auth-helper-core.ts +181 -0
- package/src/serve/entries/auth-helper-dom.ts +134 -0
- package/src/serve/entries/auth-helper-runtime.ts +20 -0
- package/src/serve/entries/auth.ts +255 -0
- package/src/serve/entries/bridge-url.ts +31 -0
- package/src/serve/entries/database.ts +129 -0
- package/src/serve/entries/firestore.ts +232 -0
- package/src/serve/entries/init.ts +46 -0
- package/src/serve/entries/keepalive.ts +46 -0
- package/src/serve/entries/messaging-sw.ts +75 -0
- package/src/serve/entries/messaging.ts +96 -0
- package/src/serve/entries/runtime.ts +540 -0
- package/src/serve/entries/session-store.ts +97 -0
- package/src/serve/entries/storage.ts +92 -0
- package/src/serve/entries/tab-sync-wiring.ts +274 -0
- package/src/serve/entries/worker-runtime.ts +75 -0
- package/src/serve/init-payload.ts +42 -0
- package/src/serve/namespace.ts +675 -0
- package/src/serve/open-browser.ts +68 -0
- package/src/serve/rules.ts +272 -0
- package/src/serve/sandbox-marker.ts +31 -0
- package/src/serve/server.ts +428 -0
- package/src/serve/standalone-assets.ts +180 -0
- package/src/serve/state-store.ts +166 -0
- package/src/serve/studio/disk-project-store.ts +185 -0
- package/src/serve/studio/disk-workspace.ts +162 -0
- package/src/serve/studio/index.ts +20 -0
- package/src/serve/studio/routes.ts +237 -0
- package/src/serve/studio/store-types.ts +48 -0
- package/src/serve/studio/studio-storage.test.ts +289 -0
- package/src/serve/vite-plugin.ts +1102 -0
- package/src/serve/worker/activity-bootstrap.ts +24 -0
- package/src/serve/worker/client/admin-firestore.ts +38 -0
- package/src/serve/worker/client/ai.ts +124 -0
- package/src/serve/worker/client/auth.ts +489 -0
- package/src/serve/worker/client/connection.ts +202 -0
- package/src/serve/worker/client/core.ts +350 -0
- package/src/serve/worker/client/disconnect.ts +45 -0
- package/src/serve/worker/client/firestore-reads.ts +181 -0
- package/src/serve/worker/client/firestore-refs.ts +226 -0
- package/src/serve/worker/client/firestore-writes.ts +232 -0
- package/src/serve/worker/client/handles.ts +91 -0
- package/src/serve/worker/client/messaging.ts +119 -0
- package/src/serve/worker/client/presence.ts +174 -0
- package/src/serve/worker/client/rtdb.ts +311 -0
- package/src/serve/worker/client/rules.ts +63 -0
- package/src/serve/worker/client/service-worker-connection.ts +59 -0
- package/src/serve/worker/client/snapshots.ts +86 -0
- package/src/serve/worker/client/storage.ts +195 -0
- package/src/serve/worker/client/studio.ts +88 -0
- package/src/serve/worker/client.ts +57 -0
- package/src/serve/worker/durable-persistence.ts +137 -0
- package/src/serve/worker/entry.ts +179 -0
- package/src/serve/worker/host/admin-firestore.ts +88 -0
- package/src/serve/worker/host/connection.ts +179 -0
- package/src/serve/worker/host/core.ts +387 -0
- package/src/serve/worker/host/dispatch.ts +316 -0
- package/src/serve/worker/host/firestore-reads.ts +117 -0
- package/src/serve/worker/host/firestore-writes.ts +456 -0
- package/src/serve/worker/host/presence.ts +312 -0
- package/src/serve/worker/host/rtdb.ts +136 -0
- package/src/serve/worker/host/rules.ts +128 -0
- package/src/serve/worker/host/storage.ts +312 -0
- package/src/serve/worker/host/studio.ts +75 -0
- package/src/serve/worker/host/subscriptions.ts +238 -0
- package/src/serve/worker/host-ai.ts +165 -0
- package/src/serve/worker/host-auth.ts +469 -0
- package/src/serve/worker/host-context.ts +273 -0
- package/src/serve/worker/host-events.ts +94 -0
- package/src/serve/worker/host-messaging.ts +240 -0
- package/src/serve/worker/host.ts +47 -0
- package/src/serve/worker/index.ts +196 -0
- package/src/serve/worker/presence-timing.ts +15 -0
- package/src/serve/worker/protocol.ts +1112 -0
- package/src/serve/worker/serve-init.ts +606 -0
- package/src/serve/worker/service-worker-channel.ts +33 -0
- package/src/serve/worker/service-worker-relay.ts +86 -0
- package/src/serve/writer-lock.ts +53 -0
- package/src/verify/cases.ts +233 -0
- package/src/verify/fixture.ts +258 -0
- package/src/verify/index.ts +519 -0
- package/src/verify/tools.ts +108 -0
- package/src/version/compat-target.ts +17 -0
- package/src/vite.ts +17 -0
- package/dist/serve/docs-ui/docs/pyric-firestore-values-reference-api/index.html +0 -30
- package/dist/serve/docs-ui/docs/pyric-firestore-values-reference-api.md +0 -30
- package/dist/serve/studio-ui/assets/index-BvtQIpGn.js +0 -1211
- package/dist/serve/studio-ui/assets/seed-3DMedLL3.js +0 -2
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SharedWorker entry point — the actual SharedWorker script.
|
|
3
|
+
*
|
|
4
|
+
* WHY A SEPARATE ENTRY
|
|
5
|
+
* --------------------
|
|
6
|
+
* `host.ts` is pure-ish: it accepts an injected `{ db, sandbox }` and
|
|
7
|
+
* fake ports, so tests can drive it without a real SharedWorker runtime.
|
|
8
|
+
* This file is the integration shell: it creates the ONE real sandbox,
|
|
9
|
+
* attaches IDB persistence, deploys permissive starter rules, and wires
|
|
10
|
+
* every connecting port to `handleMessage`.
|
|
11
|
+
*
|
|
12
|
+
* Do NOT import this file in tests — import `host.ts` directly.
|
|
13
|
+
*
|
|
14
|
+
* LIFECYCLE
|
|
15
|
+
* ---------
|
|
16
|
+
* The SharedWorker lives while at least one tab holds a port. When all
|
|
17
|
+
* tabs close or navigate away, the worker is GC'd. IDB persistence means
|
|
18
|
+
* data survives full close → reopen cycles: on the next connect the sandbox
|
|
19
|
+
* restores from IDB, and the tab reconnects to a warm state.
|
|
20
|
+
*
|
|
21
|
+
* PERSISTENCE KEY
|
|
22
|
+
* ---------------
|
|
23
|
+
* Project-scoped: `'pyric-shared-worker:<projectKey>'`, derived inside
|
|
24
|
+
* `buildWorkerCtx` from the init payload's `projectKey` (issue #359 family —
|
|
25
|
+
* IndexedDB is origin-scoped, so the old fixed key shared one sandbox
|
|
26
|
+
* snapshot database across every project on a localhost port). The legacy
|
|
27
|
+
* `'pyric-shared-worker'` key applies only when no project identity exists
|
|
28
|
+
* (older servers, standalone workers); see `workerPersistenceKey` in
|
|
29
|
+
* serve-init.ts for the orphan-don't-delete migration decision.
|
|
30
|
+
*
|
|
31
|
+
* RULES
|
|
32
|
+
* -----
|
|
33
|
+
* We deploy a permissive starter ruleset on first init. Callers change
|
|
34
|
+
* rules at runtime via `{ t:'op', method:'setRules', source }` messages.
|
|
35
|
+
*
|
|
36
|
+
* SINGLE SANDBOX GUARANTEE
|
|
37
|
+
* ------------------------
|
|
38
|
+
* `_ctx` is module-level. The first `connect` event lazily creates it;
|
|
39
|
+
* all subsequent ports reuse the same ctx — one sandbox, one Firestore
|
|
40
|
+
* backend for all tabs. This is the architectural invariant the whole
|
|
41
|
+
* SharedWorker approach depends on.
|
|
42
|
+
*/
|
|
43
|
+
|
|
44
|
+
// SharedWorkerGlobalScope is not in the default TypeScript lib (it's in
|
|
45
|
+
// lib.webworker.d.ts which conflicts with lib.dom.d.ts). This entry file is
|
|
46
|
+
// browser-only and only bundled with esbuild (never compiled by tsc for
|
|
47
|
+
// production). We declare the minimal interface we need so tsc can type-check
|
|
48
|
+
// without enabling the full webworker lib.
|
|
49
|
+
interface SharedWorkerGlobalScope {
|
|
50
|
+
onconnect: ((e: MessageEvent) => void) | null;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
import { createIndexedDBBackend } from 'pyric/sandbox';
|
|
54
|
+
|
|
55
|
+
import {
|
|
56
|
+
handleMessage,
|
|
57
|
+
cleanupPort,
|
|
58
|
+
type HostCtx,
|
|
59
|
+
type PortLike,
|
|
60
|
+
} from './host.js';
|
|
61
|
+
import { buildWorkerCtx, type EventSourceLike } from './serve-init.js';
|
|
62
|
+
import type { InboundMessage } from './protocol.js';
|
|
63
|
+
import {
|
|
64
|
+
SERVICE_WORKER_CHANNEL,
|
|
65
|
+
type ServiceWorkerChannelMessage,
|
|
66
|
+
} from './service-worker-channel.js';
|
|
67
|
+
import { createServiceWorkerRelay } from './service-worker-relay.js';
|
|
68
|
+
|
|
69
|
+
// ─── Singleton context ────────────────────────────────────────────────────
|
|
70
|
+
|
|
71
|
+
// `_ctx` is the RESOLVED context, kept for the synchronous `close` handler.
|
|
72
|
+
// The build is memoized as a PROMISE (`_ctxPromise`) — NOT as the resolved
|
|
73
|
+
// value — because init is async (it awaits `/__pyric/init.json` + persistence
|
|
74
|
+
// restore). The first messages arrive in a BURST (the authState sub, the first
|
|
75
|
+
// firestore sub, an op — possibly across two tabs at once); if each re-checked
|
|
76
|
+
// only the resolved `_ctx` they would every one start a fresh init and build a
|
|
77
|
+
// SEPARATE sandbox, so a listener and a write could bind to different
|
|
78
|
+
// instances and never see each other. The promise memo guarantees ONE init.
|
|
79
|
+
let _ctx: HostCtx | null = null;
|
|
80
|
+
let _ctxPromise: Promise<HostCtx> | null = null;
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Return the shared context, memoizing the in-flight init promise so
|
|
84
|
+
* concurrent first messages await ONE build (see `_ctxPromise` above).
|
|
85
|
+
*/
|
|
86
|
+
function getCtx(): Promise<HostCtx> {
|
|
87
|
+
return (_ctxPromise ??= buildCtx());
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Build the ONE shared sandbox + Firestore handle. Invoked exactly once per
|
|
92
|
+
* worker lifetime via the `getCtx` memo — never concurrently. The real boot
|
|
93
|
+
* logic lives in `buildWorkerCtx` (serve-init.ts) so it is testable without
|
|
94
|
+
* a SharedWorker runtime; this shell only supplies the real ambients.
|
|
95
|
+
*
|
|
96
|
+
* NOTE (#754): no worker-side session restore. Sessions are per-port; each
|
|
97
|
+
* PAGE re-establishes its own session from web storage via
|
|
98
|
+
* `auth.restorePortSession` (runtime.ts). The user DB itself is restored
|
|
99
|
+
* from the persisted snapshot inside buildWorkerCtx (#629).
|
|
100
|
+
*/
|
|
101
|
+
async function buildCtx(): Promise<HostCtx> {
|
|
102
|
+
// ONE IDB backend for the whole worker. createIndexedDBBackend's guard
|
|
103
|
+
// checks `typeof indexedDB === 'undefined'` — SharedWorkers have full
|
|
104
|
+
// IndexedDB access, so this succeeds. The persistence controller's
|
|
105
|
+
// window.addEventListener('beforeunload', ...) is guarded by
|
|
106
|
+
// `typeof window !== 'undefined'`, so enablePersistence is worker-safe.
|
|
107
|
+
const ctx = await buildWorkerCtx({
|
|
108
|
+
fetch,
|
|
109
|
+
idb: createIndexedDBBackend(),
|
|
110
|
+
// EventSource is available in workers; guard anyway for exotic hosts.
|
|
111
|
+
makeEventSource:
|
|
112
|
+
typeof EventSource !== 'undefined'
|
|
113
|
+
? (url) => new EventSource(url) as unknown as EventSourceLike
|
|
114
|
+
: null,
|
|
115
|
+
});
|
|
116
|
+
_ctx = ctx; // publish the resolved ctx for the synchronous close handler
|
|
117
|
+
return ctx;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// ─── SharedWorker connect handler ─────────────────────────────────────────
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* `self` in a SharedWorker is `SharedWorkerGlobalScope`, not `Window`.
|
|
124
|
+
* Each tab that opens the SharedWorker fires one `connect` event.
|
|
125
|
+
* Each tab gets its own `MessagePort`; we start() it (required for
|
|
126
|
+
* classic-mode workers to un-pause the message queue) and wire onmessage.
|
|
127
|
+
*/
|
|
128
|
+
(self as unknown as SharedWorkerGlobalScope).onconnect = (e: MessageEvent) => {
|
|
129
|
+
const port = e.ports[0];
|
|
130
|
+
port.start();
|
|
131
|
+
|
|
132
|
+
let messageQueue = Promise.resolve();
|
|
133
|
+
port.onmessage = (ev: MessageEvent<InboundMessage>) => {
|
|
134
|
+
// Serialize each port's frames. A disconnect acknowledgement therefore
|
|
135
|
+
// cannot overtake an already-posted mutation, and later frames see the
|
|
136
|
+
// disconnected-port tombstone instead of touching the shared backend.
|
|
137
|
+
messageQueue = messageQueue.then(async () => {
|
|
138
|
+
try {
|
|
139
|
+
const ctx = await getCtx();
|
|
140
|
+
await handleMessage(ctx, port as unknown as PortLike, ev.data);
|
|
141
|
+
} catch (e) {
|
|
142
|
+
// eslint-disable-next-line no-console
|
|
143
|
+
console.error('[pyric worker] message handler error:', (e as Error)?.stack ?? e, 'msg:', ev.data);
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
// Best-effort port cleanup on tab close/navigation.
|
|
149
|
+
// Chrome doesn't reliably fire 'close' on MessagePort — handled as
|
|
150
|
+
// best-effort; subscriptions also GC when the worker itself dies.
|
|
151
|
+
port.addEventListener('close', () => {
|
|
152
|
+
if (_ctx) cleanupPort(_ctx, port as unknown as PortLike);
|
|
153
|
+
});
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
// ServiceWorkerGlobalScope cannot construct a SharedWorker, but both worker
|
|
157
|
+
// kinds share BroadcastChannel. Adapt each SW app connection to the host's
|
|
158
|
+
// existing PortLike seam so it reaches this exact context/broker instead of
|
|
159
|
+
// constructing a second in-Service-Worker sandbox.
|
|
160
|
+
if (typeof BroadcastChannel !== 'undefined') {
|
|
161
|
+
const channel = new BroadcastChannel(SERVICE_WORKER_CHANNEL);
|
|
162
|
+
const relay = createServiceWorkerRelay({
|
|
163
|
+
getCtx,
|
|
164
|
+
send(message) { channel.postMessage(message); },
|
|
165
|
+
onError(error, envelope) {
|
|
166
|
+
console.error(
|
|
167
|
+
'[pyric worker] service-worker relay error:',
|
|
168
|
+
(error as Error)?.stack ?? error,
|
|
169
|
+
'msg:',
|
|
170
|
+
envelope,
|
|
171
|
+
);
|
|
172
|
+
},
|
|
173
|
+
});
|
|
174
|
+
channel.onmessage = (event: MessageEvent<ServiceWorkerChannelMessage>) => {
|
|
175
|
+
const envelope = event.data;
|
|
176
|
+
if (envelope.direction !== 'host') return;
|
|
177
|
+
void relay.handle(envelope);
|
|
178
|
+
};
|
|
179
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SharedWorker host — admin-lens Firestore document ops (rules bypass).
|
|
3
|
+
*
|
|
4
|
+
* The `admin.*` surface used by the pyric-admin remote arm + Pyric Studio's
|
|
5
|
+
* "edit anything as admin": direct document get/list/set/delete against the
|
|
6
|
+
* sandbox admin plane, plus `admin.readState` (a prefix/depth-scoped snapshot
|
|
7
|
+
* of the whole store through the cached admin handle).
|
|
8
|
+
*
|
|
9
|
+
* Routed here by the host dispatcher. These ops act on `ctx.sandbox.admin` /
|
|
10
|
+
* the admin handle directly, so they take no resolved `db`. Never imports the
|
|
11
|
+
* dispatcher.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import type { OpMessage } from '../protocol.js';
|
|
15
|
+
import { snapshotDocuments } from 'pyric/sandbox/firestore';
|
|
16
|
+
import { type HostCtx, type PortLike, ok, fail, bestEffortFlush } from '../host-context.js';
|
|
17
|
+
|
|
18
|
+
/** The admin-lens op methods routed to {@link handleAdminFirestoreOp}. */
|
|
19
|
+
const ADMIN_METHODS = new Set<string>([
|
|
20
|
+
'admin.getDocument',
|
|
21
|
+
'admin.listDocuments',
|
|
22
|
+
'admin.setDocument',
|
|
23
|
+
'admin.deleteDocument',
|
|
24
|
+
'admin.readState',
|
|
25
|
+
]);
|
|
26
|
+
|
|
27
|
+
export function isAdminFirestoreOp(method: OpMessage['method']): boolean {
|
|
28
|
+
return ADMIN_METHODS.has(method);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export async function handleAdminFirestoreOp(
|
|
32
|
+
ctx: HostCtx,
|
|
33
|
+
port: PortLike,
|
|
34
|
+
msg: OpMessage,
|
|
35
|
+
): Promise<void> {
|
|
36
|
+
switch (msg.method) {
|
|
37
|
+
case 'admin.getDocument': {
|
|
38
|
+
try {
|
|
39
|
+
ok(port, msg.id, ctx.sandbox.admin.getDocument(msg.path));
|
|
40
|
+
} catch (e) { fail(port, msg.id, e); }
|
|
41
|
+
break;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
case 'admin.listDocuments': {
|
|
45
|
+
try {
|
|
46
|
+
ok(port, msg.id, ctx.sandbox.admin.listDocuments(msg.path));
|
|
47
|
+
} catch (e) { fail(port, msg.id, e); }
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
case 'admin.setDocument': {
|
|
52
|
+
try {
|
|
53
|
+
ctx.sandbox.admin.setDocument(msg.path, msg.data as Record<string, unknown>);
|
|
54
|
+
await bestEffortFlush(ctx);
|
|
55
|
+
ok(port, msg.id, null);
|
|
56
|
+
} catch (e) { fail(port, msg.id, e); }
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
case 'admin.deleteDocument': {
|
|
61
|
+
try {
|
|
62
|
+
const deleted = ctx.sandbox.admin.deleteDocument(msg.path);
|
|
63
|
+
await bestEffortFlush(ctx);
|
|
64
|
+
ok(port, msg.id, deleted);
|
|
65
|
+
} catch (e) { fail(port, msg.id, e); }
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
case 'admin.readState': {
|
|
70
|
+
try {
|
|
71
|
+
const snap = snapshotDocuments(ctx.sandbox);
|
|
72
|
+
const out: Record<string, unknown> = {};
|
|
73
|
+
const prefix = msg.path ?? '';
|
|
74
|
+
for (const [path, data] of Object.entries(snap)) {
|
|
75
|
+
if (prefix && !path.startsWith(prefix)) continue;
|
|
76
|
+
if (msg.maxDepth !== undefined && path.split('/').length > msg.maxDepth) continue;
|
|
77
|
+
out[path] = data;
|
|
78
|
+
}
|
|
79
|
+
ok(port, msg.id, out);
|
|
80
|
+
} catch (e) { fail(port, msg.id, e); }
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
default: {
|
|
85
|
+
fail(port, msg.id, new Error(`Unknown method: ${String((msg as { method: unknown }).method)}`));
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SharedWorker host — connection / instance / state-transfer ops.
|
|
3
|
+
*
|
|
4
|
+
* The worker-lifecycle surface the client's `connection` family talks to:
|
|
5
|
+
* - `getVersion` (build hash + per-worker instance id),
|
|
6
|
+
* - full-state transfer (`exportState`/`importState`, the portable bundle),
|
|
7
|
+
* - named branches (`saveBranch`/`listBranches`/`switchBranch`/`deleteBranch`,
|
|
8
|
+
* saved-state bundles in the RAW idb).
|
|
9
|
+
*
|
|
10
|
+
* Owns the stable per-worker instance id (persisted to the raw idb) and the
|
|
11
|
+
* branch registry helpers. `getOrCreateInstanceId` is imported by serve-init;
|
|
12
|
+
* the instance-id + branch constants/helpers are part of the host's public
|
|
13
|
+
* surface (re-exported by the host barrel). Never imports the dispatcher.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import type { PersistenceBackend } from 'pyric/sandbox';
|
|
17
|
+
import { serializeToBuckets, bundleRecords, parseBundle, deserializeFromBuckets } from 'pyric/sandbox';
|
|
18
|
+
|
|
19
|
+
import type { OpMessage } from '../protocol.js';
|
|
20
|
+
import { type HostCtx, type PortLike, ok, fail } from '../host-context.js';
|
|
21
|
+
|
|
22
|
+
/** Build hash injected by the bundler's esbuild `define`. Undefined when the
|
|
23
|
+
* compiled host is imported directly (tests) — guarded with `typeof`. */
|
|
24
|
+
declare const __PYRIC_WORKER_VERSION__: string;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Per-SharedWorker instance id — generated once and persisted to the RAW idb
|
|
28
|
+
* (local-only, like the session record above; it must NEVER reach the
|
|
29
|
+
* committable server file). Because IndexedDB is per (origin + browser profile),
|
|
30
|
+
* two profiles on the same `localhost:<port>` get two distinct ids — which is
|
|
31
|
+
* exactly how the UI tells same-port-different-profile sandboxes apart.
|
|
32
|
+
*/
|
|
33
|
+
export const INSTANCE_ID_KEY = 'pyric:worker:instance';
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* `crypto.randomUUID()` is secure-context-only (https or localhost), so it is
|
|
37
|
+
* `undefined` over plain http on a non-localhost host (a Tailscale or LAN
|
|
38
|
+
* hostname). `crypto.getRandomValues` is NOT gated, so build a v4 UUID from it as
|
|
39
|
+
* the fallback. Without this the worker throws on init over Tailscale and the
|
|
40
|
+
* whole sandbox (auth, firestore, bridge) silently fails to come up.
|
|
41
|
+
*/
|
|
42
|
+
export function randomUuid(): string {
|
|
43
|
+
if (typeof crypto.randomUUID === 'function') return crypto.randomUUID();
|
|
44
|
+
const b = crypto.getRandomValues(new Uint8Array(16));
|
|
45
|
+
b[6] = (b[6] & 0x0f) | 0x40;
|
|
46
|
+
b[8] = (b[8] & 0x3f) | 0x80;
|
|
47
|
+
const h = Array.from(b, (x) => x.toString(16).padStart(2, '0'));
|
|
48
|
+
return `${h.slice(0, 4).join('')}-${h.slice(4, 6).join('')}-${h.slice(6, 8).join('')}-${h.slice(8, 10).join('')}-${h.slice(10, 16).join('')}`;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export async function getOrCreateInstanceId(idb: PersistenceBackend): Promise<string> {
|
|
52
|
+
const rec = (await idb.getRecord(INSTANCE_ID_KEY, 'id')) as { value?: string } | undefined;
|
|
53
|
+
if (rec && typeof rec.value === 'string') return rec.value;
|
|
54
|
+
const id = randomUuid();
|
|
55
|
+
await idb.putRecords(INSTANCE_ID_KEY, new Map([['id', { value: id }]]));
|
|
56
|
+
return id;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// ── Phase 3: named branches ─────────────────────────────────────────────────
|
|
60
|
+
// A branch is a named saved state bundle in the RAW idb (local-only, like the
|
|
61
|
+
// instance id + session; it must NEVER reach the committable server file). They
|
|
62
|
+
// let one instance keep several named states it can switch between
|
|
63
|
+
// (switchBranch = loadSnapshot the bundle, a clobber). A registry record holds
|
|
64
|
+
// the ordered name list, since the backend lists records WITHIN a key, not keys.
|
|
65
|
+
export const BRANCH_PREFIX = 'pyric:worker:branch:';
|
|
66
|
+
export const BRANCH_REGISTRY_KEY = 'pyric:worker:branches';
|
|
67
|
+
|
|
68
|
+
export async function listBranchNames(idb?: PersistenceBackend): Promise<string[]> {
|
|
69
|
+
if (!idb) return [];
|
|
70
|
+
const rec = (await idb.getRecord(BRANCH_REGISTRY_KEY, 'names')) as { value?: string[] } | undefined;
|
|
71
|
+
return Array.isArray(rec?.value) ? rec.value : [];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async function writeBranchRegistry(idb: PersistenceBackend, names: string[]): Promise<void> {
|
|
75
|
+
await idb.putRecords(BRANCH_REGISTRY_KEY, new Map([['names', { value: names }]]));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** The connection/state/branch op methods routed to {@link handleConnectionOp}. */
|
|
79
|
+
const CONNECTION_METHODS = new Set<string>([
|
|
80
|
+
'getVersion',
|
|
81
|
+
'exportState',
|
|
82
|
+
'importState',
|
|
83
|
+
'saveBranch',
|
|
84
|
+
'listBranches',
|
|
85
|
+
'switchBranch',
|
|
86
|
+
'deleteBranch',
|
|
87
|
+
]);
|
|
88
|
+
|
|
89
|
+
export function isConnectionOp(method: OpMessage['method']): boolean {
|
|
90
|
+
return CONNECTION_METHODS.has(method);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export async function handleConnectionOp(
|
|
94
|
+
ctx: HostCtx,
|
|
95
|
+
port: PortLike,
|
|
96
|
+
msg: OpMessage,
|
|
97
|
+
): Promise<void> {
|
|
98
|
+
switch (msg.method) {
|
|
99
|
+
case 'getVersion': {
|
|
100
|
+
// The build hash is injected by the bundler (esbuild `define`). `typeof`
|
|
101
|
+
// guards the non-bundled path (tests import the compiled host directly,
|
|
102
|
+
// where the global is undefined) → reports 'dev'.
|
|
103
|
+
ok(port, msg.id, {
|
|
104
|
+
version: typeof __PYRIC_WORKER_VERSION__ !== 'undefined' ? __PYRIC_WORKER_VERSION__ : 'dev',
|
|
105
|
+
instanceId: ctx.instanceId,
|
|
106
|
+
});
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
case 'exportState': {
|
|
111
|
+
// Phase 2 (transfer): serialize the FULL sandbox state to a portable bundle
|
|
112
|
+
// string using the SAME chunk format the persist layer uses, so wrapper
|
|
113
|
+
// types (Timestamp / Bytes / GeoPoint / VectorValue) round-trip. The string
|
|
114
|
+
// crosses the MessagePort cleanly (unlike the raw snapshot object).
|
|
115
|
+
const snap = ctx.sandbox.snapshot();
|
|
116
|
+
ok(port, msg.id, { bundle: bundleRecords(serializeToBuckets(snap.firestore, snap.services, 0)) });
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
case 'importState': {
|
|
121
|
+
// Phase 2 (clobber): replace this sandbox's ENTIRE state with the imported
|
|
122
|
+
// bundle via the public loadSnapshot() (reset + rebuild firestore + restore
|
|
123
|
+
// services; listeners re-evaluate, persist re-flushes).
|
|
124
|
+
ctx.sandbox.loadSnapshot(deserializeFromBuckets(parseBundle(msg.bundle)));
|
|
125
|
+
ok(port, msg.id, { ok: true });
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
case 'saveBranch': {
|
|
130
|
+
// Phase 3: snapshot the live sandbox into a named branch bundle (raw idb).
|
|
131
|
+
if (!ctx.sessionBackend) {
|
|
132
|
+
ok(port, msg.id, { ok: false, error: 'no persistence backend' });
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
const snap = ctx.sandbox.snapshot();
|
|
136
|
+
const bundle = bundleRecords(serializeToBuckets(snap.firestore, snap.services, 0));
|
|
137
|
+
await ctx.sessionBackend.putRecords(BRANCH_PREFIX + msg.name, new Map([['bundle', { value: bundle }]]));
|
|
138
|
+
const names = await listBranchNames(ctx.sessionBackend);
|
|
139
|
+
if (!names.includes(msg.name)) await writeBranchRegistry(ctx.sessionBackend, [...names, msg.name]);
|
|
140
|
+
ok(port, msg.id, { ok: true });
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
case 'listBranches': {
|
|
145
|
+
ok(port, msg.id, { branches: await listBranchNames(ctx.sessionBackend) });
|
|
146
|
+
break;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
case 'switchBranch': {
|
|
150
|
+
// Phase 3: loadSnapshot the named branch bundle (a clobber).
|
|
151
|
+
const rec = ctx.sessionBackend
|
|
152
|
+
? ((await ctx.sessionBackend.getRecord(BRANCH_PREFIX + msg.name, 'bundle')) as { value?: string } | undefined)
|
|
153
|
+
: undefined;
|
|
154
|
+
if (!rec?.value) {
|
|
155
|
+
ok(port, msg.id, { ok: false, error: `no such branch: ${msg.name}` });
|
|
156
|
+
break;
|
|
157
|
+
}
|
|
158
|
+
ctx.sandbox.loadSnapshot(deserializeFromBuckets(parseBundle(rec.value)));
|
|
159
|
+
ok(port, msg.id, { ok: true });
|
|
160
|
+
break;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
case 'deleteBranch': {
|
|
164
|
+
if (ctx.sessionBackend) {
|
|
165
|
+
await ctx.sessionBackend.clear(BRANCH_PREFIX + msg.name);
|
|
166
|
+
await writeBranchRegistry(
|
|
167
|
+
ctx.sessionBackend,
|
|
168
|
+
(await listBranchNames(ctx.sessionBackend)).filter((n) => n !== msg.name),
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
ok(port, msg.id, { ok: true });
|
|
172
|
+
break;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
default: {
|
|
176
|
+
fail(port, msg.id, new Error(`Unknown method: ${String((msg as { method: unknown }).method)}`));
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|