@pyric/cli 0.1.0-alpha.10 → 0.1.0-alpha.11
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 +1 -1
- 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 +2 -2
- 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 +800 -575
- 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-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 +123 -92
- package/dist/serve/docs-ui/docs/pyric-cli-serve-worker-reference-api.md +49 -20
- 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-firestore-values-reference-api/index.html +3 -2
- package/dist/serve/docs-ui/docs/pyric-firestore-values-reference-api.md +1 -2
- 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 +374 -910
- package/dist/serve/docs-ui/docs/pyric-sandbox-reference-api.md +377 -911
- 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 +1 -0
- 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 +33 -8
- 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/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 +1 -1
- package/dist/serve/worker/index.d.ts.map +1 -1
- package/dist/serve/worker/index.js +2 -0
- 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.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 +8 -4
- package/dist/serve/studio-ui/assets/index-BvtQIpGn.js +0 -1211
- package/dist/serve/studio-ui/assets/seed-3DMedLL3.js +0 -2
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
<!-- Generated from published package declarations via TypeDoc. Do not edit by hand; run bun run docs:api:generate. -->
|
|
1
|
+
<!-- Generated from published package declarations via TypeDoc. Rendered by the api-reference content loader. -->
|
|
3
2
|
|
|
4
3
|
## Classes
|
|
5
4
|
|
|
@@ -43,7 +42,7 @@ Error.constructor
|
|
|
43
42
|
|
|
44
43
|
### SandboxContextImpl
|
|
45
44
|
|
|
46
|
-
Identity-bearing handle on a [Sandbox](#sandbox
|
|
45
|
+
Identity-bearing handle on a [Sandbox](pyric-firestore-reference-api.md#sandbox). A
|
|
47
46
|
`(sandbox, auth, operationContext)`
|
|
48
47
|
tuple — cheap to create, immutable, freely shareable. Service
|
|
49
48
|
factories require a `SandboxContext`; bare `Sandbox` is a type
|
|
@@ -56,7 +55,7 @@ factories; consumers don't construct it directly.
|
|
|
56
55
|
|
|
57
56
|
#### Implements
|
|
58
57
|
|
|
59
|
-
- [`SandboxContext`](#sandboxcontext)
|
|
58
|
+
- [`SandboxContext`](pyric-firestore-reference-api.md#sandboxcontext)
|
|
60
59
|
|
|
61
60
|
#### Constructors
|
|
62
61
|
|
|
@@ -78,7 +77,7 @@ new SandboxContextImpl(
|
|
|
78
77
|
|
|
79
78
|
| Parameter | Type |
|
|
80
79
|
| :------ | :------ |
|
|
81
|
-
| `sandbox` | [`Sandbox`](#sandbox
|
|
80
|
+
| `sandbox` | [`Sandbox`](pyric-firestore-reference-api.md#sandbox) |
|
|
82
81
|
| `auth` | \{ `token?`: `Record`\<`string`, `unknown`\>; `uid`: `string`; \} |
|
|
83
82
|
| `auth.token?` | `Record`\<`string`, `unknown`\> |
|
|
84
83
|
| `auth.uid?` | `string` |
|
|
@@ -96,7 +95,7 @@ new SandboxContextImpl(
|
|
|
96
95
|
| `auth.token?` | `public` | `Record`\<`string`, `unknown`\> | - |
|
|
97
96
|
| `auth.uid` | `public` | `string` | - |
|
|
98
97
|
| <a id="operationcontext"></a> `operationContext` | `readonly` | [`OperationContext`](#operationcontext-2) | Immutable provenance bound to every operation issued through this handle. |
|
|
99
|
-
| <a id="sandbox"></a> `sandbox` | `readonly` | [`Sandbox`](#sandbox
|
|
98
|
+
| <a id="sandbox"></a> `sandbox` | `readonly` | [`Sandbox`](pyric-firestore-reference-api.md#sandbox) | The data foundation this context operates against. |
|
|
100
99
|
|
|
101
100
|
#### Methods
|
|
102
101
|
|
|
@@ -125,101 +124,37 @@ optional plan identity.
|
|
|
125
124
|
|
|
126
125
|
###### Returns
|
|
127
126
|
|
|
128
|
-
[`SandboxContext`](#sandboxcontext)
|
|
127
|
+
[`SandboxContext`](pyric-firestore-reference-api.md#sandboxcontext)
|
|
129
128
|
|
|
130
129
|
###### Implementation of
|
|
131
130
|
|
|
132
|
-
[`SandboxContext`](#sandboxcontext).[`withAuth`](#withauth-
|
|
133
|
-
|
|
134
|
-
***
|
|
135
|
-
|
|
136
|
-
<a id="sandboxerror"></a>
|
|
137
|
-
|
|
138
|
-
### SandboxError
|
|
139
|
-
|
|
140
|
-
Sandbox-layer error. Catch with `instanceof SandboxError` and switch
|
|
141
|
-
on `code`. `denialContext` is populated for `permission-denied` only
|
|
142
|
-
(and only after Slice 4 wires it through).
|
|
143
|
-
|
|
144
|
-
Two construction forms are supported:
|
|
145
|
-
- Positional: `new SandboxError(code, message, denialContext?)` —
|
|
146
|
-
the original signature, kept for backward compatibility with
|
|
147
|
-
existing internal call sites.
|
|
148
|
-
- Options bag: `new SandboxError({ code, message, remediation? })` —
|
|
149
|
-
used when attaching remediation guidance.
|
|
150
|
-
|
|
151
|
-
#### Extends
|
|
152
|
-
|
|
153
|
-
- `Error`
|
|
154
|
-
|
|
155
|
-
#### Constructors
|
|
156
|
-
|
|
157
|
-
<a id="constructor-2"></a>
|
|
158
|
-
|
|
159
|
-
##### Constructor
|
|
160
|
-
|
|
161
|
-
```ts
|
|
162
|
-
new SandboxError(
|
|
163
|
-
code: SandboxErrorCode,
|
|
164
|
-
message: string,
|
|
165
|
-
denialContext?: DenialContext): SandboxError;
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
###### Parameters
|
|
169
|
-
|
|
170
|
-
| Parameter | Type |
|
|
171
|
-
| :------ | :------ |
|
|
172
|
-
| `code` | [`SandboxErrorCode`](#sandboxerrorcode-1) |
|
|
173
|
-
| `message` | `string` |
|
|
174
|
-
| `denialContext?` | [`DenialContext`](#denialcontext-1) |
|
|
175
|
-
|
|
176
|
-
###### Returns
|
|
177
|
-
|
|
178
|
-
[`SandboxError`](#sandboxerror)
|
|
179
|
-
|
|
180
|
-
###### Overrides
|
|
181
|
-
|
|
182
|
-
```ts
|
|
183
|
-
Error.constructor
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
##### Constructor
|
|
187
|
-
|
|
188
|
-
```ts
|
|
189
|
-
new SandboxError(options: SandboxErrorOptions): SandboxError;
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
###### Parameters
|
|
193
|
-
|
|
194
|
-
| Parameter | Type |
|
|
195
|
-
| :------ | :------ |
|
|
196
|
-
| `options` | `SandboxErrorOptions` |
|
|
131
|
+
[`SandboxContext`](pyric-firestore-reference-api.md#sandboxcontext).[`withAuth`](pyric-firestore-reference-api.md#withauth-2)
|
|
197
132
|
|
|
198
|
-
|
|
133
|
+
## Interfaces
|
|
199
134
|
|
|
200
|
-
|
|
135
|
+
<a id="activityeventprovenance"></a>
|
|
201
136
|
|
|
202
|
-
|
|
137
|
+
### ActivityEventProvenance
|
|
203
138
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
139
|
+
Provenance consumed only by the firestore activity diagnostics. Bundled in
|
|
140
|
+
one optional record so the shared operation type carries a single
|
|
141
|
+
activity-owned seam rather than loose per-feature fields.
|
|
207
142
|
|
|
208
143
|
#### Properties
|
|
209
144
|
|
|
210
|
-
| Property |
|
|
145
|
+
| Property | Type | Description |
|
|
211
146
|
| :------ | :------ | :------ |
|
|
212
|
-
| <a id="
|
|
213
|
-
| <a id="
|
|
214
|
-
| <a id="
|
|
147
|
+
| <a id="groupkind"></a> `groupKind?` | `"transaction"` | Marks worker-split operations that belong to a transaction for activity diagnostics. |
|
|
148
|
+
| <a id="listenerid"></a> `listenerId?` | `string` | Stable host subscription identity used only by activity diagnostics. |
|
|
149
|
+
| <a id="listenerlifecycle"></a> `listenerLifecycle?` | `"reauthorize"` | Marks lifecycle caused by transparent auth reauthorization, not app code. |
|
|
215
150
|
|
|
216
|
-
|
|
151
|
+
***
|
|
217
152
|
|
|
218
153
|
<a id="branch"></a>
|
|
219
154
|
|
|
220
155
|
### Branch
|
|
221
156
|
|
|
222
|
-
An isolated, in-memory experiment seeded from a [SandboxSnapshot](#sandboxsnapshot
|
|
157
|
+
An isolated, in-memory experiment seeded from a [SandboxSnapshot](#sandboxsnapshot).
|
|
223
158
|
|
|
224
159
|
A branch owns its own [LocalSandbox](#localsandbox) (fully isolated from the source —
|
|
225
160
|
separate `LocalEnvironment`, separate event history) plus the
|
|
@@ -230,7 +165,7 @@ applied events are what [promote](#promote) replays onto the target.
|
|
|
230
165
|
|
|
231
166
|
| Property | Modifier | Type | Description |
|
|
232
167
|
| :------ | :------ | :------ | :------ |
|
|
233
|
-
| <a id="base"></a> `base` | `readonly` | [`SandboxSnapshot`](#sandboxsnapshot
|
|
168
|
+
| <a id="base"></a> `base` | `readonly` | [`SandboxSnapshot`](#sandboxsnapshot) | The snapshot this branch was forked from. Retained so [diff](#diff) and [promote](#promote) can reason about the baseline. |
|
|
234
169
|
| <a id="discarded"></a> `discarded` | `public` | `boolean` | Flipped by [discard](#discard); subsequent [apply](#apply)/[promote](#promote) calls throw. |
|
|
235
170
|
| <a id="events"></a> `events` | `readonly` | [`SandboxEvent`](#sandboxevent)[] | Write/op events applied to this branch since fork, in order. These are replayed onto the target by [promote](#promote). |
|
|
236
171
|
| <a id="rules"></a> `rules` | `readonly` | `string` | Rules the branch was forked with — carried so [promote](#promote) can re-seed a replay target identically. |
|
|
@@ -335,7 +270,7 @@ removeEventListener(type: "message", listener: (ev: {
|
|
|
335
270
|
|
|
336
271
|
***
|
|
337
272
|
|
|
338
|
-
<a id="denialcontext
|
|
273
|
+
<a id="denialcontext"></a>
|
|
339
274
|
|
|
340
275
|
### DenialContext
|
|
341
276
|
|
|
@@ -358,9 +293,14 @@ reference traces.
|
|
|
358
293
|
| `auth.token?` | `Record`\<`string`, `unknown`\> | - |
|
|
359
294
|
| `auth.uid` | `string` | - |
|
|
360
295
|
| <a id="failedfields"></a> `failedFields?` | `string`[] | Field paths in `request.resource.data` that the rule referenced and that failed. |
|
|
296
|
+
| <a id="query"></a> `query?` | \{ `limit?`: `number`; `offset?`: `number`; `orderBy?`: `string`; `where?`: \{ `field`: `string`; `op`: `string`; `value`: `string` \| `number` \| `boolean`; \}[]; \} | Machine-readable descriptor of the denied query's where/orderBy/limit shape (RULES-B11). Populated when a `list`/query is denied as statically unprovable ("rules are not filters"), so consumers can render the exact query the engine rejected without re-deriving it. Absent for single-doc and non-query denials. |
|
|
297
|
+
| `query.limit?` | `number` | - |
|
|
298
|
+
| `query.offset?` | `number` | - |
|
|
299
|
+
| `query.orderBy?` | `string` | - |
|
|
300
|
+
| `query.where?` | \{ `field`: `string`; `op`: `string`; `value`: `string` \| `number` \| `boolean`; \}[] | - |
|
|
361
301
|
| <a id="reasons"></a> `reasons?` | `string`[] | Raw simulator reasoning lines (the underlying engine's `debugMessages`). Always present on `permission-denied`. Stable enough for log surfacing; not stable as machine-parseable data. |
|
|
362
|
-
| <a id="request"></a> `request?` | \{ `method`: `"
|
|
363
|
-
| `request.method` | `"
|
|
302
|
+
| <a id="request"></a> `request?` | \{ `method`: `"delete"` \| `"get"` \| `"list"` \| `"create"` \| `"update"`; `path`: `string`; `resourceData?`: `Record`\<`string`, `unknown`\>; \} | Eval-time request shape — what the rule saw on `request.*`. Lets callers render a "why did this deny" frame (auth, method, path, `request.resource.data` with sentinels resolved) without re-deriving any of it from out-of-band state. |
|
|
303
|
+
| `request.method` | `"delete"` \| `"get"` \| `"list"` \| `"create"` \| `"update"` | - |
|
|
364
304
|
| `request.path` | `string` | - |
|
|
365
305
|
| `request.resourceData?` | `Record`\<`string`, `unknown`\> | The user's proposed `request.resource.data` — pre-resolution. `FieldValue.*` sentinels are preserved as their marker shapes (`{ __type: 'serverTimestamp' }`, etc.). The rule engine evaluated against the resolved form; what surfaces here is the caller's INTENT so consumers see what they tried to write. Absent for reads (no proposed write) and for `delete` (no payload). |
|
|
366
306
|
| <a id="resource"></a> `resource?` | \{ `data`: `Record`\<`string`, `unknown`\>; `exists`: `boolean`; \} | Eval-time existing-document snapshot — what the rule saw on `resource.data`. `null` data with `exists: false` mirrors how the rule sees an absent doc. Absent for collection ops (`list`). |
|
|
@@ -378,7 +318,7 @@ reference traces.
|
|
|
378
318
|
|
|
379
319
|
Eval-time payload emitted to Sandbox.onDenial subscribers.
|
|
380
320
|
|
|
381
|
-
Mirrors the structured fields [DenialContext](#denialcontext
|
|
321
|
+
Mirrors the structured fields [DenialContext](#denialcontext) carries (`request`
|
|
382
322
|
+ `resource` + `reasons` + `auth`) so a host environment that wants
|
|
383
323
|
to surface denials independent of try/catch behavior gets the same
|
|
384
324
|
frame either way.
|
|
@@ -390,11 +330,11 @@ frame either way.
|
|
|
390
330
|
| <a id="auth-2"></a> `auth?` | \{ `token?`: `Record`\<`string`, `unknown`\>; `uid`: `string`; \} |
|
|
391
331
|
| `auth.token?` | `Record`\<`string`, `unknown`\> |
|
|
392
332
|
| `auth.uid` | `string` |
|
|
393
|
-
| <a id="code
|
|
333
|
+
| <a id="code"></a> `code` | `"permission-denied"` |
|
|
394
334
|
| <a id="message"></a> `message` | `string` |
|
|
395
335
|
| <a id="reasons-1"></a> `reasons?` | `string`[] |
|
|
396
|
-
| <a id="request-1"></a> `request?` | \{ `method`: `"
|
|
397
|
-
| `request.method` | `"
|
|
336
|
+
| <a id="request-1"></a> `request?` | \{ `method`: `"delete"` \| `"get"` \| `"list"` \| `"create"` \| `"update"`; `path`: `string`; `resourceData?`: `Record`\<`string`, `unknown`\>; \} |
|
|
337
|
+
| `request.method` | `"delete"` \| `"get"` \| `"list"` \| `"create"` \| `"update"` |
|
|
398
338
|
| `request.path` | `string` |
|
|
399
339
|
| `request.resourceData?` | `Record`\<`string`, `unknown`\> |
|
|
400
340
|
| <a id="resource-1"></a> `resource?` | \{ `data`: `Record`\<`string`, `unknown`\>; `exists`: `boolean`; \} |
|
|
@@ -414,6 +354,7 @@ consumers migrate to the canonical `operationContext`.
|
|
|
414
354
|
|
|
415
355
|
| Property | Type | Description |
|
|
416
356
|
| :------ | :------ | :------ |
|
|
357
|
+
| <a id="activity"></a> `activity?` | [`ActivityEventProvenance`](#activityeventprovenance) | Firestore activity-diagnostics provenance; absent outside that flow. |
|
|
417
358
|
| <a id="actor"></a> `actor?` | [`EventActor`](#eventactor) | - |
|
|
418
359
|
| <a id="authlens"></a> `authLens?` | [`AuthLens`](#authlens-2) | - |
|
|
419
360
|
| <a id="operationcontext-1"></a> `operationContext?` | [`OperationContext`](#operationcontext-2) | - |
|
|
@@ -444,8 +385,8 @@ on the errored phase only.
|
|
|
444
385
|
| `error.reasons?` | `string`[] | - |
|
|
445
386
|
| <a id="id"></a> `id` | `string` | - |
|
|
446
387
|
| <a id="kind"></a> `kind` | `"listener_attach"` \| `"listener_detach"` \| `"listener_errored"` | - |
|
|
447
|
-
| <a id="listenerid"></a> `listenerId` | `string` | - |
|
|
448
|
-
| <a id="target"></a> `target` | \| \{ `kind`: `"doc"`; `path`: `string`; \} \| \{ `collection`: `string`; `kind`: `"query"`; \} | - |
|
|
388
|
+
| <a id="listenerid-1"></a> `listenerId` | `string` | - |
|
|
389
|
+
| <a id="target"></a> `target` | \| \{ `kind`: `"doc"`; `path`: `string`; \} \| \{ `collection`: `string`; `kind`: `"query"`; `query?`: `unknown`; \} | - |
|
|
449
390
|
|
|
450
391
|
***
|
|
451
392
|
|
|
@@ -456,12 +397,12 @@ on the errored phase only.
|
|
|
456
397
|
An in-process sandbox created by [initializeSandbox](#initializesandbox).
|
|
457
398
|
|
|
458
399
|
Service controls whose implementation requires synchronous access to local
|
|
459
|
-
state accept this type. Remote worker handles remain [Sandbox](#sandbox
|
|
400
|
+
state accept this type. Remote worker handles remain [Sandbox](pyric-firestore-reference-api.md#sandbox)s, but
|
|
460
401
|
are deliberately not assignable to this local-only interface.
|
|
461
402
|
|
|
462
403
|
#### Extends
|
|
463
404
|
|
|
464
|
-
- [`Sandbox`](#sandbox
|
|
405
|
+
- [`Sandbox`](pyric-firestore-reference-api.md#sandbox)
|
|
465
406
|
|
|
466
407
|
#### Properties
|
|
467
408
|
|
|
@@ -469,7 +410,7 @@ are deliberately not assignable to this local-only interface.
|
|
|
469
410
|
| :------ | :------ | :------ | :------ |
|
|
470
411
|
| <a id="local_sandbox"></a> `[LOCAL_SANDBOX]` | `readonly` | `true` | - |
|
|
471
412
|
| <a id="admin"></a> `admin` | `readonly` | `SandboxAdmin` | Admin-plane access (rule-bypass reads). Identity-agnostic by design — admin reads aren't gated on auth, so they live on the sandbox, not on a context. See SandboxAdmin. |
|
|
472
|
-
| <a id="currentuser"></a> `currentUser` | `public` | \{ `token?`: `Record`\<`string`, `unknown`\>; `uid`: `string`; \} | Current authenticated user across the sandbox. Mutated by `pyric/auth`'s `signInAnonymously` / `signInWithEmailAndPassword` / `signOut` / `sandbox.setUser`. Read per-call by service factories (e.g. a future `getFirestore(sandbox)` overload) so they see auth state changes without re-binding handles. Defaults to `null` (anonymous / signed out). **Independent of `withAuth({uid})`** — `withAuth` still produces a frozen [SandboxContext](#sandboxcontext) that carries its own identity for the runner's test code (the existing pattern: explicit identity per service call). `currentUser` exists for the `pyric/auth` mirror, where consumer app code drives identity through a stateful `Auth` handle rather than naming it per call. |
|
|
413
|
+
| <a id="currentuser"></a> `currentUser` | `public` | \{ `token?`: `Record`\<`string`, `unknown`\>; `uid`: `string`; \} | Current authenticated user across the sandbox. Mutated by `pyric/auth`'s `signInAnonymously` / `signInWithEmailAndPassword` / `signOut` / `sandbox.setUser`. Read per-call by service factories (e.g. a future `getFirestore(sandbox)` overload) so they see auth state changes without re-binding handles. Defaults to `null` (anonymous / signed out). **Independent of `withAuth({uid})`** — `withAuth` still produces a frozen [SandboxContext](pyric-firestore-reference-api.md#sandboxcontext) that carries its own identity for the runner's test code (the existing pattern: explicit identity per service call). `currentUser` exists for the `pyric/auth` mirror, where consumer app code drives identity through a stateful `Auth` handle rather than naming it per call. |
|
|
473
414
|
| `currentUser.token?` | `public` | `Record`\<`string`, `unknown`\> | - |
|
|
474
415
|
| `currentUser.uid` | `public` | `string` | - |
|
|
475
416
|
|
|
@@ -495,7 +436,7 @@ No-op when persistence is not enabled.
|
|
|
495
436
|
|
|
496
437
|
###### Inherited from
|
|
497
438
|
|
|
498
|
-
[`Sandbox`](#sandbox
|
|
439
|
+
[`Sandbox`](pyric-firestore-reference-api.md#sandbox).[`clearPersistence`](pyric-firestore-reference-api.md#clearpersistence)
|
|
499
440
|
|
|
500
441
|
<a id="dispose"></a>
|
|
501
442
|
|
|
@@ -517,7 +458,7 @@ outgoing instance defensively. Idempotent. Does not touch data.
|
|
|
517
458
|
|
|
518
459
|
###### Inherited from
|
|
519
460
|
|
|
520
|
-
[`Sandbox`](#sandbox
|
|
461
|
+
[`Sandbox`](pyric-firestore-reference-api.md#sandbox).[`dispose`](pyric-firestore-reference-api.md#dispose)
|
|
521
462
|
|
|
522
463
|
<a id="enablepersistence"></a>
|
|
523
464
|
|
|
@@ -561,7 +502,7 @@ tuning.
|
|
|
561
502
|
|
|
562
503
|
###### Inherited from
|
|
563
504
|
|
|
564
|
-
[`Sandbox`](#sandbox
|
|
505
|
+
[`Sandbox`](pyric-firestore-reference-api.md#sandbox).[`enablePersistence`](pyric-firestore-reference-api.md#enablepersistence)
|
|
565
506
|
|
|
566
507
|
<a id="enabletabsync"></a>
|
|
567
508
|
|
|
@@ -621,7 +562,7 @@ disableSync();
|
|
|
621
562
|
|
|
622
563
|
###### Inherited from
|
|
623
564
|
|
|
624
|
-
[`Sandbox`](#sandbox
|
|
565
|
+
[`Sandbox`](pyric-firestore-reference-api.md#sandbox).[`enableTabSync`](pyric-firestore-reference-api.md#enabletabsync)
|
|
625
566
|
|
|
626
567
|
<a id="flush"></a>
|
|
627
568
|
|
|
@@ -644,7 +585,7 @@ Throws if persistence is not enabled.
|
|
|
644
585
|
|
|
645
586
|
###### Inherited from
|
|
646
587
|
|
|
647
|
-
[`Sandbox`](#sandbox
|
|
588
|
+
[`Sandbox`](pyric-firestore-reference-api.md#sandbox).[`flush`](pyric-firestore-reference-api.md#flush)
|
|
648
589
|
|
|
649
590
|
<a id="history"></a>
|
|
650
591
|
|
|
@@ -661,7 +602,7 @@ Use this for replay: hand the array to `replay(events, rules)`
|
|
|
661
602
|
from `pyric/sandbox` and the engine re-issues every
|
|
662
603
|
captured write against a fresh sandbox.
|
|
663
604
|
|
|
664
|
-
Unlike [onEvent](#onevent
|
|
605
|
+
Unlike [onEvent](pyric-firestore-reference-api.md#onevent) (live stream from the moment of subscribe),
|
|
665
606
|
`history()` returns *every* event the sandbox has seen — useful
|
|
666
607
|
for consumers that attach late (e.g., loading a saved session
|
|
667
608
|
before subscribing) or that need a snapshot at a particular moment.
|
|
@@ -676,7 +617,7 @@ snapshot *before* reset retain the boundary in their copy.
|
|
|
676
617
|
|
|
677
618
|
###### Inherited from
|
|
678
619
|
|
|
679
|
-
[`Sandbox`](#sandbox
|
|
620
|
+
[`Sandbox`](pyric-firestore-reference-api.md#sandbox).[`history`](pyric-firestore-reference-api.md#history)
|
|
680
621
|
|
|
681
622
|
<a id="loadsnapshot"></a>
|
|
682
623
|
|
|
@@ -686,17 +627,17 @@ snapshot *before* reset retain the boundary in their copy.
|
|
|
686
627
|
loadSnapshot(data: SandboxSnapshot): void;
|
|
687
628
|
```
|
|
688
629
|
|
|
689
|
-
CLOBBER-restore the sandbox's entire state from a prior [snapshot](#snapshot
|
|
630
|
+
CLOBBER-restore the sandbox's entire state from a prior [snapshot](pyric-firestore-reference-api.md#snapshot):
|
|
690
631
|
`reset()` (clears firestore + the signed-in session), then rebuild firestore
|
|
691
632
|
from `data` and restore each registered service. This is a TOTAL replace —
|
|
692
633
|
documents absent from `data` do NOT survive — and is the counterpart to
|
|
693
|
-
[snapshot](#snapshot
|
|
634
|
+
[snapshot](pyric-firestore-reference-api.md#snapshot). It is what makes "transfer (clobber) one instance's data
|
|
694
635
|
into another" and named-branch switching possible.
|
|
695
636
|
|
|
696
637
|
Fires a `session_boundary` (reset phase), re-evaluates live listeners against
|
|
697
638
|
the loaded state, and the next persistence flush writes the loaded state.
|
|
698
639
|
Services present in `data` but not currently registered are skipped (a
|
|
699
|
-
snapshot taken via [snapshot](#snapshot
|
|
640
|
+
snapshot taken via [snapshot](pyric-firestore-reference-api.md#snapshot) always includes every registered
|
|
700
641
|
service, so this only affects cross-instance imports from a sandbox that had
|
|
701
642
|
a service this one lacks).
|
|
702
643
|
|
|
@@ -704,7 +645,7 @@ a service this one lacks).
|
|
|
704
645
|
|
|
705
646
|
| Parameter | Type |
|
|
706
647
|
| :------ | :------ |
|
|
707
|
-
| `data` | [`SandboxSnapshot`](#sandboxsnapshot
|
|
648
|
+
| `data` | [`SandboxSnapshot`](#sandboxsnapshot) |
|
|
708
649
|
|
|
709
650
|
###### Returns
|
|
710
651
|
|
|
@@ -712,7 +653,7 @@ a service this one lacks).
|
|
|
712
653
|
|
|
713
654
|
###### Inherited from
|
|
714
655
|
|
|
715
|
-
[`Sandbox`](#sandbox
|
|
656
|
+
[`Sandbox`](pyric-firestore-reference-api.md#sandbox).[`loadSnapshot`](pyric-firestore-reference-api.md#loadsnapshot)
|
|
716
657
|
|
|
717
658
|
<a id="oncurrentuserchanged"></a>
|
|
718
659
|
|
|
@@ -755,7 +696,7 @@ their errors.
|
|
|
755
696
|
|
|
756
697
|
###### Inherited from
|
|
757
698
|
|
|
758
|
-
[`Sandbox`](#sandbox
|
|
699
|
+
[`Sandbox`](pyric-firestore-reference-api.md#sandbox).[`onCurrentUserChanged`](pyric-firestore-reference-api.md#oncurrentuserchanged)
|
|
759
700
|
|
|
760
701
|
<a id="onevent"></a>
|
|
761
702
|
|
|
@@ -805,7 +746,7 @@ sandbox doesn't await them and doesn't propagate their errors.
|
|
|
805
746
|
|
|
806
747
|
###### Inherited from
|
|
807
748
|
|
|
808
|
-
[`Sandbox`](#sandbox
|
|
749
|
+
[`Sandbox`](pyric-firestore-reference-api.md#sandbox).[`onEvent`](pyric-firestore-reference-api.md#onevent)
|
|
809
750
|
|
|
810
751
|
<a id="registerpersistableservice"></a>
|
|
811
752
|
|
|
@@ -854,7 +795,7 @@ not need to call this directly.
|
|
|
854
795
|
|
|
855
796
|
###### Inherited from
|
|
856
797
|
|
|
857
|
-
[`Sandbox`](#sandbox
|
|
798
|
+
[`Sandbox`](pyric-firestore-reference-api.md#sandbox).[`registerPersistableService`](pyric-firestore-reference-api.md#registerpersistableservice)
|
|
858
799
|
|
|
859
800
|
<a id="reset"></a>
|
|
860
801
|
|
|
@@ -872,7 +813,7 @@ the swap — they can't survive because their target docs have been
|
|
|
872
813
|
wiped. `onEvent` subscribers DO survive — the registry lives on
|
|
873
814
|
the sandbox, and a `session_boundary` event with `phase: 'reset'`
|
|
874
815
|
fires before the swap so subscribers know the rollover happened.
|
|
875
|
-
Existing [SandboxContext](#sandboxcontext)s continue to work — their sandbox
|
|
816
|
+
Existing [SandboxContext](pyric-firestore-reference-api.md#sandboxcontext)s continue to work — their sandbox
|
|
876
817
|
reference is stable; subsequent operations resolve to the new env.
|
|
877
818
|
|
|
878
819
|
###### Returns
|
|
@@ -881,7 +822,41 @@ reference is stable; subsequent operations resolve to the new env.
|
|
|
881
822
|
|
|
882
823
|
###### Inherited from
|
|
883
824
|
|
|
884
|
-
[`Sandbox`](#sandbox
|
|
825
|
+
[`Sandbox`](pyric-firestore-reference-api.md#sandbox).[`reset`](pyric-firestore-reference-api.md#reset)
|
|
826
|
+
|
|
827
|
+
<a id="resetall"></a>
|
|
828
|
+
|
|
829
|
+
##### resetAll()
|
|
830
|
+
|
|
831
|
+
```ts
|
|
832
|
+
resetAll(): Promise<{
|
|
833
|
+
errors: string[];
|
|
834
|
+
}>;
|
|
835
|
+
```
|
|
836
|
+
|
|
837
|
+
Reset the WHOLE sandbox: [reset](pyric-firestore-reference-api.md#reset) (Firestore env + signed-in
|
|
838
|
+
session), then clear every registered persistable service that
|
|
839
|
+
provides a [PersistableService.reset](#reset-2) hook — auth users, the
|
|
840
|
+
RTDB tree, storage objects. This is the one sandbox-owned "wipe
|
|
841
|
+
everything" path: because it iterates the service registry, a new
|
|
842
|
+
service that registers with a `reset` hook is cleared automatically,
|
|
843
|
+
and a consumer (Pyric Studio's reset) cannot forget one.
|
|
844
|
+
|
|
845
|
+
Service resets may be async (storage clears IndexedDB stores); the
|
|
846
|
+
returned promise resolves when every service has finished clearing.
|
|
847
|
+
A service whose `reset` throws is isolated (others still clear) and
|
|
848
|
+
REPORTED in the returned `errors` (as `name: message`) — a reset that
|
|
849
|
+
leaves data behind must never look successful to the caller.
|
|
850
|
+
|
|
851
|
+
###### Returns
|
|
852
|
+
|
|
853
|
+
`Promise`\<\{
|
|
854
|
+
`errors`: `string`[];
|
|
855
|
+
\}\>
|
|
856
|
+
|
|
857
|
+
###### Inherited from
|
|
858
|
+
|
|
859
|
+
[`Sandbox`](pyric-firestore-reference-api.md#sandbox).[`resetAll`](pyric-firestore-reference-api.md#resetall)
|
|
885
860
|
|
|
886
861
|
<a id="runwithprovenance"></a>
|
|
887
862
|
|
|
@@ -934,7 +909,7 @@ spell `sandbox.runWithProvenance?.(prov, fn) ?? fn()`.
|
|
|
934
909
|
|
|
935
910
|
###### Inherited from
|
|
936
911
|
|
|
937
|
-
[`Sandbox`](#sandbox
|
|
912
|
+
[`Sandbox`](pyric-firestore-reference-api.md#sandbox).[`runWithProvenance`](pyric-firestore-reference-api.md#runwithprovenance)
|
|
938
913
|
|
|
939
914
|
<a id="snapshot"></a>
|
|
940
915
|
|
|
@@ -950,11 +925,11 @@ paths to data. Future services will add their own keys.
|
|
|
950
925
|
|
|
951
926
|
###### Returns
|
|
952
927
|
|
|
953
|
-
[`SandboxSnapshot`](#sandboxsnapshot
|
|
928
|
+
[`SandboxSnapshot`](#sandboxsnapshot)
|
|
954
929
|
|
|
955
930
|
###### Inherited from
|
|
956
931
|
|
|
957
|
-
[`Sandbox`](#sandbox
|
|
932
|
+
[`Sandbox`](pyric-firestore-reference-api.md#sandbox).[`snapshot`](pyric-firestore-reference-api.md#snapshot)
|
|
958
933
|
|
|
959
934
|
<a id="withauth-2"></a>
|
|
960
935
|
|
|
@@ -987,7 +962,7 @@ unambiguous.
|
|
|
987
962
|
|
|
988
963
|
###### Returns
|
|
989
964
|
|
|
990
|
-
[`SandboxContext`](#sandboxcontext)
|
|
965
|
+
[`SandboxContext`](pyric-firestore-reference-api.md#sandboxcontext)
|
|
991
966
|
|
|
992
967
|
###### Example
|
|
993
968
|
|
|
@@ -999,7 +974,7 @@ const dbAnon = getFirestore(sandbox.withAuth(null));
|
|
|
999
974
|
|
|
1000
975
|
###### Inherited from
|
|
1001
976
|
|
|
1002
|
-
[`Sandbox`](#sandbox
|
|
977
|
+
[`Sandbox`](pyric-firestore-reference-api.md#sandbox).[`withAuth`](pyric-firestore-reference-api.md#withauth)
|
|
1003
978
|
|
|
1004
979
|
***
|
|
1005
980
|
|
|
@@ -1038,7 +1013,7 @@ as a user, while an app or agent may use an admin lens.
|
|
|
1038
1013
|
| <a id="id-1"></a> `id` | `readonly` | `string` |
|
|
1039
1014
|
| <a id="method"></a> `method` | `readonly` | `string` |
|
|
1040
1015
|
| <a id="path"></a> `path?` | `readonly` | `string` |
|
|
1041
|
-
| <a id="result"></a> `result` | `readonly` | `"
|
|
1016
|
+
| <a id="result"></a> `result` | `readonly` | `"unsupported"` \| `"error"` \| `"allow"` \| `"deny"` \| `"not-applicable"` |
|
|
1042
1017
|
| <a id="rules-1"></a> `rules` | `readonly` | [`RulesDisposition`](#rulesdisposition-2) |
|
|
1043
1018
|
| <a id="service-1"></a> `service` | `readonly` | [`EventService`](#eventservice) |
|
|
1044
1019
|
|
|
@@ -1050,7 +1025,7 @@ as a user, while an app or agent may use an admin lens.
|
|
|
1050
1025
|
|
|
1051
1026
|
Contract for a service that can contribute its state to the sandbox
|
|
1052
1027
|
persistence layer. Services (auth, storage, database) register
|
|
1053
|
-
themselves via [Sandbox.registerPersistableService](#registerpersistableservice
|
|
1028
|
+
themselves via [Sandbox.registerPersistableService](pyric-firestore-reference-api.md#registerpersistableservice) so the
|
|
1054
1029
|
sandbox core stays service-agnostic — the sandbox doesn't know what
|
|
1055
1030
|
auth or storage look like; it just calls `snapshot()` / `restore()`.
|
|
1056
1031
|
|
|
@@ -1064,15 +1039,37 @@ as Firestore writes.
|
|
|
1064
1039
|
|
|
1065
1040
|
| Property | Type | Description |
|
|
1066
1041
|
| :------ | :------ | :------ |
|
|
1067
|
-
| <a id="session"></a> `session?` | \{ `currentUid`: `string`; `mode`: `"
|
|
1042
|
+
| <a id="session"></a> `session?` | \{ `currentUid`: `string`; `mode`: `"NONE"` \| `"SESSION"` \| `"LOCAL"`; `restore`: `void`; `subscribe`: () => `void`; \} | Optional: session-level persistence hooks. When provided, the persistence controller uses these to save and restore the CURRENTLY SIGNED-IN user (not the user database — that's `snapshot`/`restore`). The controller calls `session.subscribe` so it hears every sign-in / sign-out, then writes the uid to the appropriate web-storage slot (determined by `session.mode()`). On init, the controller reads the stored uid and its storage-derived mode, then calls `session.restore(uid, mode)` to re-establish both before firing `onAuthStateChanged` as if the user just signed in. Only active when `SandboxPersistenceOptions.sessionStorage` is provided; omitting `sessionStorage` causes the controller to skip session persistence entirely (no fake durability). Auth is the only service that provides session hooks today. The field is on the generic interface so the controller stays service-agnostic — if a second service ever needs session-style semantics it can add its own hooks without changing the controller. |
|
|
1068
1043
|
| `session.currentUid` | `string` | - |
|
|
1069
|
-
| `session.mode` | `"
|
|
1044
|
+
| `session.mode` | `"NONE"` \| `"SESSION"` \| `"LOCAL"` | - |
|
|
1070
1045
|
| `session.restore` | `void` | - |
|
|
1071
1046
|
| `session.subscribe` | () => `void` | - |
|
|
1072
1047
|
| <a id="subscribe"></a> `subscribe?` | (`onChange`: () => `void`) => () => `void` | Optional: subscribe to changes in this service's state. When provided, the persistence controller hooks it up and schedules a debounced flush on each change — ensuring auth-user edits reach the backend promptly, not only on the next Firestore write. Must return an unsubscribe function. The controller unsubscribes on `dispose()`. |
|
|
1073
1048
|
|
|
1074
1049
|
#### Methods
|
|
1075
1050
|
|
|
1051
|
+
<a id="reset-2"></a>
|
|
1052
|
+
|
|
1053
|
+
##### reset()?
|
|
1054
|
+
|
|
1055
|
+
```ts
|
|
1056
|
+
optional reset(): void | Promise<void>;
|
|
1057
|
+
```
|
|
1058
|
+
|
|
1059
|
+
Optional: clear this service's state to empty. Called by
|
|
1060
|
+
[Sandbox.resetAll](pyric-firestore-reference-api.md#resetall) after the Firestore environment swap, so a
|
|
1061
|
+
single sandbox-owned call wipes EVERY registered service (auth users,
|
|
1062
|
+
RTDB tree, storage objects) — a consumer (Pyric Studio's reset) can't
|
|
1063
|
+
forget a service it never knew about. May be async (storage clears an
|
|
1064
|
+
IndexedDB store); `resetAll` awaits it. A service that omits `reset`
|
|
1065
|
+
is skipped — its state deliberately survives `resetAll` (e.g. the
|
|
1066
|
+
per-app auth-session hooks, whose signed-in identity the sandbox core
|
|
1067
|
+
already clears in `reset()`).
|
|
1068
|
+
|
|
1069
|
+
###### Returns
|
|
1070
|
+
|
|
1071
|
+
`void` \| `Promise`\<`void`\>
|
|
1072
|
+
|
|
1076
1073
|
<a id="restore"></a>
|
|
1077
1074
|
|
|
1078
1075
|
##### restore()
|
|
@@ -1316,7 +1313,7 @@ Force a flush of the current sandbox state to the backend.
|
|
|
1316
1313
|
|
|
1317
1314
|
### RemoteSandbox
|
|
1318
1315
|
|
|
1319
|
-
A branded remote sandbox handle. Structurally a [Sandbox](#sandbox
|
|
1316
|
+
A branded remote sandbox handle. Structurally a [Sandbox](pyric-firestore-reference-api.md#sandbox) — it can
|
|
1320
1317
|
be passed anywhere a `Sandbox` is accepted (notably
|
|
1321
1318
|
`pyric-admin/app`'s `initializeApp({ sandbox })`) — but sync-only members
|
|
1322
1319
|
that cannot be mirrored over the wire (`admin`, `snapshot()`,
|
|
@@ -1325,7 +1322,11 @@ dispatch on [isRemoteSandbox](#isremotesandbox) and use [channel](#channel) inst
|
|
|
1325
1322
|
|
|
1326
1323
|
#### Extends
|
|
1327
1324
|
|
|
1328
|
-
- [`Sandbox`](#sandbox
|
|
1325
|
+
- [`Sandbox`](pyric-firestore-reference-api.md#sandbox)
|
|
1326
|
+
|
|
1327
|
+
#### Extended by
|
|
1328
|
+
|
|
1329
|
+
- [`RemoteSandbox`](pyric-cli-remote-reference-api.md#remotesandbox)
|
|
1329
1330
|
|
|
1330
1331
|
#### Properties
|
|
1331
1332
|
|
|
@@ -1334,7 +1335,7 @@ dispatch on [isRemoteSandbox](#isremotesandbox) and use [channel](#channel) inst
|
|
|
1334
1335
|
| <a id="remote_sandbox"></a> `[REMOTE_SANDBOX]` | `readonly` | `true` | - |
|
|
1335
1336
|
| <a id="admin-1"></a> `admin` | `readonly` | `SandboxAdmin` | Admin-plane access (rule-bypass reads). Identity-agnostic by design — admin reads aren't gated on auth, so they live on the sandbox, not on a context. See SandboxAdmin. |
|
|
1336
1337
|
| <a id="channel"></a> `channel` | `readonly` | [`RemoteSandboxChannel`](#remotesandboxchannel-1) | The raw worker op/sub relay channel. |
|
|
1337
|
-
| <a id="currentuser-1"></a> `currentUser` | `public` | \{ `token?`: `Record`\<`string`, `unknown`\>; `uid`: `string`; \} | Current authenticated user across the sandbox. Mutated by `pyric/auth`'s `signInAnonymously` / `signInWithEmailAndPassword` / `signOut` / `sandbox.setUser`. Read per-call by service factories (e.g. a future `getFirestore(sandbox)` overload) so they see auth state changes without re-binding handles. Defaults to `null` (anonymous / signed out). **Independent of `withAuth({uid})`** — `withAuth` still produces a frozen [SandboxContext](#sandboxcontext) that carries its own identity for the runner's test code (the existing pattern: explicit identity per service call). `currentUser` exists for the `pyric/auth` mirror, where consumer app code drives identity through a stateful `Auth` handle rather than naming it per call. |
|
|
1338
|
+
| <a id="currentuser-1"></a> `currentUser` | `public` | \{ `token?`: `Record`\<`string`, `unknown`\>; `uid`: `string`; \} | Current authenticated user across the sandbox. Mutated by `pyric/auth`'s `signInAnonymously` / `signInWithEmailAndPassword` / `signOut` / `sandbox.setUser`. Read per-call by service factories (e.g. a future `getFirestore(sandbox)` overload) so they see auth state changes without re-binding handles. Defaults to `null` (anonymous / signed out). **Independent of `withAuth({uid})`** — `withAuth` still produces a frozen [SandboxContext](pyric-firestore-reference-api.md#sandboxcontext) that carries its own identity for the runner's test code (the existing pattern: explicit identity per service call). `currentUser` exists for the `pyric/auth` mirror, where consumer app code drives identity through a stateful `Auth` handle rather than naming it per call. |
|
|
1338
1339
|
| `currentUser.token?` | `public` | `Record`\<`string`, `unknown`\> | - |
|
|
1339
1340
|
| `currentUser.uid` | `public` | `string` | - |
|
|
1340
1341
|
| <a id="serveurl"></a> `serveUrl` | `readonly` | `string` | Base URL of the `pyric dev` this handle is attached to (used in error guidance: "open <serveUrl> in a browser and retry"). |
|
|
@@ -1361,7 +1362,7 @@ No-op when persistence is not enabled.
|
|
|
1361
1362
|
|
|
1362
1363
|
###### Inherited from
|
|
1363
1364
|
|
|
1364
|
-
[`Sandbox`](#sandbox
|
|
1365
|
+
[`Sandbox`](pyric-firestore-reference-api.md#sandbox).[`clearPersistence`](pyric-firestore-reference-api.md#clearpersistence)
|
|
1365
1366
|
|
|
1366
1367
|
<a id="dispose-4"></a>
|
|
1367
1368
|
|
|
@@ -1383,7 +1384,7 @@ outgoing instance defensively. Idempotent. Does not touch data.
|
|
|
1383
1384
|
|
|
1384
1385
|
###### Inherited from
|
|
1385
1386
|
|
|
1386
|
-
[`Sandbox`](#sandbox
|
|
1387
|
+
[`Sandbox`](pyric-firestore-reference-api.md#sandbox).[`dispose`](pyric-firestore-reference-api.md#dispose)
|
|
1387
1388
|
|
|
1388
1389
|
<a id="enablepersistence-2"></a>
|
|
1389
1390
|
|
|
@@ -1427,7 +1428,7 @@ tuning.
|
|
|
1427
1428
|
|
|
1428
1429
|
###### Inherited from
|
|
1429
1430
|
|
|
1430
|
-
[`Sandbox`](#sandbox
|
|
1431
|
+
[`Sandbox`](pyric-firestore-reference-api.md#sandbox).[`enablePersistence`](pyric-firestore-reference-api.md#enablepersistence)
|
|
1431
1432
|
|
|
1432
1433
|
<a id="enabletabsync-2"></a>
|
|
1433
1434
|
|
|
@@ -1487,7 +1488,7 @@ disableSync();
|
|
|
1487
1488
|
|
|
1488
1489
|
###### Inherited from
|
|
1489
1490
|
|
|
1490
|
-
[`Sandbox`](#sandbox
|
|
1491
|
+
[`Sandbox`](pyric-firestore-reference-api.md#sandbox).[`enableTabSync`](pyric-firestore-reference-api.md#enabletabsync)
|
|
1491
1492
|
|
|
1492
1493
|
<a id="flush-4"></a>
|
|
1493
1494
|
|
|
@@ -1510,7 +1511,7 @@ Throws if persistence is not enabled.
|
|
|
1510
1511
|
|
|
1511
1512
|
###### Inherited from
|
|
1512
1513
|
|
|
1513
|
-
[`Sandbox`](#sandbox
|
|
1514
|
+
[`Sandbox`](pyric-firestore-reference-api.md#sandbox).[`flush`](pyric-firestore-reference-api.md#flush)
|
|
1514
1515
|
|
|
1515
1516
|
<a id="history-2"></a>
|
|
1516
1517
|
|
|
@@ -1527,7 +1528,7 @@ Use this for replay: hand the array to `replay(events, rules)`
|
|
|
1527
1528
|
from `pyric/sandbox` and the engine re-issues every
|
|
1528
1529
|
captured write against a fresh sandbox.
|
|
1529
1530
|
|
|
1530
|
-
Unlike [onEvent](#onevent
|
|
1531
|
+
Unlike [onEvent](pyric-firestore-reference-api.md#onevent) (live stream from the moment of subscribe),
|
|
1531
1532
|
`history()` returns *every* event the sandbox has seen — useful
|
|
1532
1533
|
for consumers that attach late (e.g., loading a saved session
|
|
1533
1534
|
before subscribing) or that need a snapshot at a particular moment.
|
|
@@ -1542,7 +1543,7 @@ snapshot *before* reset retain the boundary in their copy.
|
|
|
1542
1543
|
|
|
1543
1544
|
###### Inherited from
|
|
1544
1545
|
|
|
1545
|
-
[`Sandbox`](#sandbox
|
|
1546
|
+
[`Sandbox`](pyric-firestore-reference-api.md#sandbox).[`history`](pyric-firestore-reference-api.md#history)
|
|
1546
1547
|
|
|
1547
1548
|
<a id="loadsnapshot-2"></a>
|
|
1548
1549
|
|
|
@@ -1552,17 +1553,17 @@ snapshot *before* reset retain the boundary in their copy.
|
|
|
1552
1553
|
loadSnapshot(data: SandboxSnapshot): void;
|
|
1553
1554
|
```
|
|
1554
1555
|
|
|
1555
|
-
CLOBBER-restore the sandbox's entire state from a prior [snapshot](#snapshot
|
|
1556
|
+
CLOBBER-restore the sandbox's entire state from a prior [snapshot](pyric-firestore-reference-api.md#snapshot):
|
|
1556
1557
|
`reset()` (clears firestore + the signed-in session), then rebuild firestore
|
|
1557
1558
|
from `data` and restore each registered service. This is a TOTAL replace —
|
|
1558
1559
|
documents absent from `data` do NOT survive — and is the counterpart to
|
|
1559
|
-
[snapshot](#snapshot
|
|
1560
|
+
[snapshot](pyric-firestore-reference-api.md#snapshot). It is what makes "transfer (clobber) one instance's data
|
|
1560
1561
|
into another" and named-branch switching possible.
|
|
1561
1562
|
|
|
1562
1563
|
Fires a `session_boundary` (reset phase), re-evaluates live listeners against
|
|
1563
1564
|
the loaded state, and the next persistence flush writes the loaded state.
|
|
1564
1565
|
Services present in `data` but not currently registered are skipped (a
|
|
1565
|
-
snapshot taken via [snapshot](#snapshot
|
|
1566
|
+
snapshot taken via [snapshot](pyric-firestore-reference-api.md#snapshot) always includes every registered
|
|
1566
1567
|
service, so this only affects cross-instance imports from a sandbox that had
|
|
1567
1568
|
a service this one lacks).
|
|
1568
1569
|
|
|
@@ -1570,7 +1571,7 @@ a service this one lacks).
|
|
|
1570
1571
|
|
|
1571
1572
|
| Parameter | Type |
|
|
1572
1573
|
| :------ | :------ |
|
|
1573
|
-
| `data` | [`SandboxSnapshot`](#sandboxsnapshot
|
|
1574
|
+
| `data` | [`SandboxSnapshot`](#sandboxsnapshot) |
|
|
1574
1575
|
|
|
1575
1576
|
###### Returns
|
|
1576
1577
|
|
|
@@ -1578,7 +1579,7 @@ a service this one lacks).
|
|
|
1578
1579
|
|
|
1579
1580
|
###### Inherited from
|
|
1580
1581
|
|
|
1581
|
-
[`Sandbox`](#sandbox
|
|
1582
|
+
[`Sandbox`](pyric-firestore-reference-api.md#sandbox).[`loadSnapshot`](pyric-firestore-reference-api.md#loadsnapshot)
|
|
1582
1583
|
|
|
1583
1584
|
<a id="oncurrentuserchanged-2"></a>
|
|
1584
1585
|
|
|
@@ -1621,7 +1622,7 @@ their errors.
|
|
|
1621
1622
|
|
|
1622
1623
|
###### Inherited from
|
|
1623
1624
|
|
|
1624
|
-
[`Sandbox`](#sandbox
|
|
1625
|
+
[`Sandbox`](pyric-firestore-reference-api.md#sandbox).[`onCurrentUserChanged`](pyric-firestore-reference-api.md#oncurrentuserchanged)
|
|
1625
1626
|
|
|
1626
1627
|
<a id="onevent-2"></a>
|
|
1627
1628
|
|
|
@@ -1671,7 +1672,7 @@ sandbox doesn't await them and doesn't propagate their errors.
|
|
|
1671
1672
|
|
|
1672
1673
|
###### Inherited from
|
|
1673
1674
|
|
|
1674
|
-
[`Sandbox`](#sandbox
|
|
1675
|
+
[`Sandbox`](pyric-firestore-reference-api.md#sandbox).[`onEvent`](pyric-firestore-reference-api.md#onevent)
|
|
1675
1676
|
|
|
1676
1677
|
<a id="registerpersistableservice-2"></a>
|
|
1677
1678
|
|
|
@@ -1720,9 +1721,9 @@ not need to call this directly.
|
|
|
1720
1721
|
|
|
1721
1722
|
###### Inherited from
|
|
1722
1723
|
|
|
1723
|
-
[`Sandbox`](#sandbox
|
|
1724
|
+
[`Sandbox`](pyric-firestore-reference-api.md#sandbox).[`registerPersistableService`](pyric-firestore-reference-api.md#registerpersistableservice)
|
|
1724
1725
|
|
|
1725
|
-
<a id="reset-
|
|
1726
|
+
<a id="reset-4"></a>
|
|
1726
1727
|
|
|
1727
1728
|
##### reset()
|
|
1728
1729
|
|
|
@@ -1738,7 +1739,7 @@ the swap — they can't survive because their target docs have been
|
|
|
1738
1739
|
wiped. `onEvent` subscribers DO survive — the registry lives on
|
|
1739
1740
|
the sandbox, and a `session_boundary` event with `phase: 'reset'`
|
|
1740
1741
|
fires before the swap so subscribers know the rollover happened.
|
|
1741
|
-
Existing [SandboxContext](#sandboxcontext)s continue to work — their sandbox
|
|
1742
|
+
Existing [SandboxContext](pyric-firestore-reference-api.md#sandboxcontext)s continue to work — their sandbox
|
|
1742
1743
|
reference is stable; subsequent operations resolve to the new env.
|
|
1743
1744
|
|
|
1744
1745
|
###### Returns
|
|
@@ -1747,7 +1748,41 @@ reference is stable; subsequent operations resolve to the new env.
|
|
|
1747
1748
|
|
|
1748
1749
|
###### Inherited from
|
|
1749
1750
|
|
|
1750
|
-
[`Sandbox`](#sandbox
|
|
1751
|
+
[`Sandbox`](pyric-firestore-reference-api.md#sandbox).[`reset`](pyric-firestore-reference-api.md#reset)
|
|
1752
|
+
|
|
1753
|
+
<a id="resetall-2"></a>
|
|
1754
|
+
|
|
1755
|
+
##### resetAll()
|
|
1756
|
+
|
|
1757
|
+
```ts
|
|
1758
|
+
resetAll(): Promise<{
|
|
1759
|
+
errors: string[];
|
|
1760
|
+
}>;
|
|
1761
|
+
```
|
|
1762
|
+
|
|
1763
|
+
Reset the WHOLE sandbox: [reset](pyric-firestore-reference-api.md#reset) (Firestore env + signed-in
|
|
1764
|
+
session), then clear every registered persistable service that
|
|
1765
|
+
provides a [PersistableService.reset](#reset-2) hook — auth users, the
|
|
1766
|
+
RTDB tree, storage objects. This is the one sandbox-owned "wipe
|
|
1767
|
+
everything" path: because it iterates the service registry, a new
|
|
1768
|
+
service that registers with a `reset` hook is cleared automatically,
|
|
1769
|
+
and a consumer (Pyric Studio's reset) cannot forget one.
|
|
1770
|
+
|
|
1771
|
+
Service resets may be async (storage clears IndexedDB stores); the
|
|
1772
|
+
returned promise resolves when every service has finished clearing.
|
|
1773
|
+
A service whose `reset` throws is isolated (others still clear) and
|
|
1774
|
+
REPORTED in the returned `errors` (as `name: message`) — a reset that
|
|
1775
|
+
leaves data behind must never look successful to the caller.
|
|
1776
|
+
|
|
1777
|
+
###### Returns
|
|
1778
|
+
|
|
1779
|
+
`Promise`\<\{
|
|
1780
|
+
`errors`: `string`[];
|
|
1781
|
+
\}\>
|
|
1782
|
+
|
|
1783
|
+
###### Inherited from
|
|
1784
|
+
|
|
1785
|
+
[`Sandbox`](pyric-firestore-reference-api.md#sandbox).[`resetAll`](pyric-firestore-reference-api.md#resetall)
|
|
1751
1786
|
|
|
1752
1787
|
<a id="runwithprovenance-2"></a>
|
|
1753
1788
|
|
|
@@ -1800,7 +1835,7 @@ spell `sandbox.runWithProvenance?.(prov, fn) ?? fn()`.
|
|
|
1800
1835
|
|
|
1801
1836
|
###### Inherited from
|
|
1802
1837
|
|
|
1803
|
-
[`Sandbox`](#sandbox
|
|
1838
|
+
[`Sandbox`](pyric-firestore-reference-api.md#sandbox).[`runWithProvenance`](pyric-firestore-reference-api.md#runwithprovenance)
|
|
1804
1839
|
|
|
1805
1840
|
<a id="snapshot-4"></a>
|
|
1806
1841
|
|
|
@@ -1816,11 +1851,11 @@ paths to data. Future services will add their own keys.
|
|
|
1816
1851
|
|
|
1817
1852
|
###### Returns
|
|
1818
1853
|
|
|
1819
|
-
[`SandboxSnapshot`](#sandboxsnapshot
|
|
1854
|
+
[`SandboxSnapshot`](#sandboxsnapshot)
|
|
1820
1855
|
|
|
1821
1856
|
###### Inherited from
|
|
1822
1857
|
|
|
1823
|
-
[`Sandbox`](#sandbox
|
|
1858
|
+
[`Sandbox`](pyric-firestore-reference-api.md#sandbox).[`snapshot`](pyric-firestore-reference-api.md#snapshot)
|
|
1824
1859
|
|
|
1825
1860
|
<a id="withauth-4"></a>
|
|
1826
1861
|
|
|
@@ -1853,7 +1888,7 @@ unambiguous.
|
|
|
1853
1888
|
|
|
1854
1889
|
###### Returns
|
|
1855
1890
|
|
|
1856
|
-
[`SandboxContext`](#sandboxcontext)
|
|
1891
|
+
[`SandboxContext`](pyric-firestore-reference-api.md#sandboxcontext)
|
|
1857
1892
|
|
|
1858
1893
|
###### Example
|
|
1859
1894
|
|
|
@@ -1865,7 +1900,7 @@ const dbAnon = getFirestore(sandbox.withAuth(null));
|
|
|
1865
1900
|
|
|
1866
1901
|
###### Inherited from
|
|
1867
1902
|
|
|
1868
|
-
[`Sandbox`](#sandbox
|
|
1903
|
+
[`Sandbox`](pyric-firestore-reference-api.md#sandbox).[`withAuth`](pyric-firestore-reference-api.md#withauth)
|
|
1869
1904
|
|
|
1870
1905
|
***
|
|
1871
1906
|
|
|
@@ -2033,16 +2068,16 @@ traffic-monitor-decision.md for the field-by-field rationale.
|
|
|
2033
2068
|
| `auth.uid` | `string` | - |
|
|
2034
2069
|
| <a id="detail"></a> `detail?` | \{ `admin?`: `boolean`; \} & `Record`\<`string`, `unknown`\> | Free-form operation metadata. `admin: true` marks a rules-bypassing setup/admin operation so fixture tooling can exclude it from protected behavior while still preserving it as replay context. |
|
|
2035
2070
|
| <a id="evalms"></a> `evalMs` | `number` | Wall-clock duration of the simulator.simulate(...) call, in ms. |
|
|
2036
|
-
| <a id="evaluatedrule"></a> `evaluatedRule?` | `EvaluatedRuleInfo` | The DECIDING rule's verdict + 1-indexed source line + full sub-expression trace, projected from the simulator's structured `RuleEvaluation` (additive: present on `result: 'allow' | 'deny'` Firestore events when the simulator produced a per-rule trace — the allowing rule on an allow, the denying rule on a deny). Studio's rules inspector reads this to mark the deciding line and render the evaluation step-through ("show the work"). Absent on an implicit deny (no rule evaluated), a simulator-error deny, and unsupported results. |
|
|
2071
|
+
| <a id="evaluatedrule"></a> `evaluatedRule?` | [`EvaluatedRuleInfo`](pyric-rules-reference-api.md#evaluatedruleinfo) | The DECIDING rule's verdict + 1-indexed source line + full sub-expression trace, projected from the simulator's structured `RuleEvaluation` (additive: present on `result: 'allow' | 'deny'` Firestore events when the simulator produced a per-rule trace — the allowing rule on an allow, the denying rule on a deny). Studio's rules inspector reads this to mark the deciding line and render the evaluation step-through ("show the work"). Absent on an implicit deny (no rule evaluated), a simulator-error deny, and unsupported results. |
|
|
2037
2072
|
| <a id="groupid"></a> `groupId?` | `string` | Shared across ops in one batch or transaction. Opaque to consumers. |
|
|
2038
|
-
| <a id="groupkind"></a> `groupKind?` | `"transaction"` \| `"batch"` | Disambiguates `origin: 'transaction' | 'batch'` cases when consumers need to tell them apart without inspecting `origin` directly. |
|
|
2073
|
+
| <a id="groupkind-1"></a> `groupKind?` | `"transaction"` \| `"batch"` | Disambiguates `origin: 'transaction' | 'batch'` cases when consumers need to tell them apart without inspecting `origin` directly. |
|
|
2039
2074
|
| <a id="id-2"></a> `id` | `string` | Unique within a sandbox process. Useful for React list keys. |
|
|
2040
2075
|
| <a id="kind-1"></a> `kind` | `"request"` | Discriminator. |
|
|
2041
2076
|
| <a id="matchedrule"></a> `matchedRule?` | \{ `operations`: `string`[]; `ruleIndex`: `number`; \} | Parsed from the simulator's "Rule #N → …" debug line. Absent when no rule matched (e.g. no allow rules at the path — implicit deny). |
|
|
2042
2077
|
| `matchedRule.operations` | `string`[] | - |
|
|
2043
2078
|
| `matchedRule.ruleIndex` | `number` | - |
|
|
2044
|
-
| <a id="method-1"></a> `method` | `"
|
|
2045
|
-
| <a id="origin"></a> `origin` | `"user"` \| `"
|
|
2079
|
+
| <a id="method-1"></a> `method` | `"delete"` \| `"get"` \| `"list"` \| `"create"` \| `"update"` \| `"set"` | - |
|
|
2080
|
+
| <a id="origin"></a> `origin` | `"user"` \| `"transaction"` \| `"listener"` \| `"batch"` | - |
|
|
2046
2081
|
| <a id="path-1"></a> `path` | `string` | - |
|
|
2047
2082
|
| <a id="reasons-2"></a> `reasons` | `string`[] | Simulator debug messages — the per-rule trace (`Rule #0 (read) → ALLOW`). Same shape as `DenialEvent.reasons` so consumer code can share rendering. |
|
|
2048
2083
|
| <a id="request-2"></a> `request?` | \{ `resourceData?`: `Record`\<`string`, `unknown`\>; \} | Proposed write payload, for create/update/set. Absent on reads + delete. Pre-resolution: `FieldValue.*` sentinels are preserved as their marker shapes (`{ __type: 'serverTimestamp' }`, etc.) so the replay engine can re-resolve them. The rule engine evaluated against the resolved form internally; that resolved form lives on [WriteSandboxEvent.nextState](#nextstate-1), not here. |
|
|
@@ -2053,7 +2088,7 @@ traffic-monitor-decision.md for the field-by-field rationale.
|
|
|
2053
2088
|
| <a id="resourcebefore"></a> `resourceBefore?` | \{ `data`: `Record`\<`string`, `unknown`\>; `exists`: `boolean`; \} | Existing document state before the write (or read target for get). |
|
|
2054
2089
|
| `resourceBefore.data` | `Record`\<`string`, `unknown`\> | - |
|
|
2055
2090
|
| `resourceBefore.exists` | `boolean` | - |
|
|
2056
|
-
| <a id="result-1"></a> `result` | `"
|
|
2091
|
+
| <a id="result-1"></a> `result` | `"unsupported"` \| `"allow"` \| `"deny"` | `'unsupported'` fires when the simulator hit an unmodelled feature and the sandbox upgraded it (today: thrown as SimulatorUnsupportedError, surfaced here as a discrete result so the panel can show it distinctly from a real denial). |
|
|
2057
2092
|
| <a id="rulesdisposition"></a> `rulesDisposition?` | [`RulesDisposition`](#rulesdisposition-2) | Canonical statement of whether Security Rules evaluated this request. Added by the sandbox event recorder when an older emitter omits it. |
|
|
2058
2093
|
| <a id="triggeredby"></a> `triggeredBy?` | \{ `method`: `string`; `path`: `string`; \} | For listener re-evals: the originating user op that triggered this re-evaluation. Absent on the initial-snapshot fire. |
|
|
2059
2094
|
| `triggeredBy.method` | `string` | - |
|
|
@@ -2061,719 +2096,163 @@ traffic-monitor-decision.md for the field-by-field rationale.
|
|
|
2061
2096
|
|
|
2062
2097
|
***
|
|
2063
2098
|
|
|
2064
|
-
<a id="
|
|
2099
|
+
<a id="sandboxcommitevent"></a>
|
|
2065
2100
|
|
|
2066
|
-
###
|
|
2101
|
+
### SandboxCommitEvent
|
|
2067
2102
|
|
|
2068
|
-
|
|
2103
|
+
Canonical committed mutation event. Unlike `operation`, this fires only when
|
|
2104
|
+
state actually changed. Replay and branch tooling should eventually consume
|
|
2105
|
+
these service adapters instead of filtering Firestore-only `write` events.
|
|
2069
2106
|
|
|
2070
|
-
|
|
2071
|
-
derive a new sandbox with a different identity that shares the
|
|
2072
|
-
underlying environment (rules, data, state). Fork is the only
|
|
2073
|
-
identity-switching mechanism — there are no per-op auth overrides
|
|
2074
|
-
and no in-place mutation.
|
|
2107
|
+
#### Properties
|
|
2075
2108
|
|
|
2076
|
-
|
|
2109
|
+
| Property | Type |
|
|
2110
|
+
| :------ | :------ |
|
|
2111
|
+
| <a id="at-3"></a> `at` | `number` |
|
|
2112
|
+
| <a id="auth-6"></a> `auth` | \{ `token?`: `Record`\<`string`, `unknown`\>; `uid`: `string`; \} |
|
|
2113
|
+
| `auth.token?` | `Record`\<`string`, `unknown`\> |
|
|
2114
|
+
| `auth.uid` | `string` |
|
|
2115
|
+
| <a id="data"></a> `data?` | `unknown` |
|
|
2116
|
+
| <a id="detail-1"></a> `detail?` | `Record`\<`string`, `unknown`\> |
|
|
2117
|
+
| <a id="groupid-1"></a> `groupId?` | `string` |
|
|
2118
|
+
| <a id="groupkind-2"></a> `groupKind?` | `"transaction"` \| `"batch"` |
|
|
2119
|
+
| <a id="id-3"></a> `id` | `string` |
|
|
2120
|
+
| <a id="kind-2"></a> `kind` | `"commit"` |
|
|
2121
|
+
| <a id="method-2"></a> `method` | `string` |
|
|
2122
|
+
| <a id="nextstate"></a> `nextState?` | `unknown` |
|
|
2123
|
+
| <a id="path-2"></a> `path?` | `string` |
|
|
2124
|
+
| <a id="priorstate"></a> `priorState?` | `unknown` |
|
|
2125
|
+
| <a id="replay"></a> `replay?` | \{ `autoId?`: `string`; `requestTime?`: `number`; `sentinels?`: \{ `field`: `string`; `kind`: `string`; \}[]; \} |
|
|
2126
|
+
| `replay.autoId?` | `string` |
|
|
2127
|
+
| `replay.requestTime?` | `number` |
|
|
2128
|
+
| `replay.sentinels?` | \{ `field`: `string`; `kind`: `string`; \}[] |
|
|
2129
|
+
| <a id="service-2"></a> `service` | [`EventService`](#eventservice) |
|
|
2077
2130
|
|
|
2078
|
-
|
|
2079
|
-
- [`RemoteSandbox`](#remotesandbox)
|
|
2131
|
+
***
|
|
2080
2132
|
|
|
2081
|
-
|
|
2133
|
+
<a id="sandboxconfig"></a>
|
|
2082
2134
|
|
|
2083
|
-
|
|
2084
|
-
| :------ | :------ | :------ | :------ |
|
|
2085
|
-
| <a id="admin-2"></a> `admin` | `readonly` | `SandboxAdmin` | Admin-plane access (rule-bypass reads). Identity-agnostic by design — admin reads aren't gated on auth, so they live on the sandbox, not on a context. See SandboxAdmin. |
|
|
2086
|
-
| <a id="currentuser-2"></a> `currentUser` | `public` | \{ `token?`: `Record`\<`string`, `unknown`\>; `uid`: `string`; \} | Current authenticated user across the sandbox. Mutated by `pyric/auth`'s `signInAnonymously` / `signInWithEmailAndPassword` / `signOut` / `sandbox.setUser`. Read per-call by service factories (e.g. a future `getFirestore(sandbox)` overload) so they see auth state changes without re-binding handles. Defaults to `null` (anonymous / signed out). **Independent of `withAuth({uid})`** — `withAuth` still produces a frozen [SandboxContext](#sandboxcontext) that carries its own identity for the runner's test code (the existing pattern: explicit identity per service call). `currentUser` exists for the `pyric/auth` mirror, where consumer app code drives identity through a stateful `Auth` handle rather than naming it per call. |
|
|
2087
|
-
| `currentUser.token?` | `public` | `Record`\<`string`, `unknown`\> | - |
|
|
2088
|
-
| `currentUser.uid` | `public` | `string` | - |
|
|
2135
|
+
### SandboxConfig
|
|
2089
2136
|
|
|
2090
|
-
|
|
2137
|
+
Initialization config for a sandbox. All fields are optional; an
|
|
2138
|
+
empty config produces a sandbox with no rules and no seeded data.
|
|
2091
2139
|
|
|
2092
|
-
|
|
2140
|
+
**No `auth` field.** Identity belongs to [SandboxContext](pyric-firestore-reference-api.md#sandboxcontext), not
|
|
2141
|
+
the sandbox. Service handles always require an explicit context.
|
|
2093
2142
|
|
|
2094
|
-
|
|
2143
|
+
***
|
|
2095
2144
|
|
|
2096
|
-
|
|
2097
|
-
clearPersistence(): Promise<void>;
|
|
2098
|
-
```
|
|
2145
|
+
<a id="sandboxlistenerevent"></a>
|
|
2099
2146
|
|
|
2100
|
-
|
|
2101
|
-
is left intact — call `reset()` if you want both. Useful for
|
|
2102
|
-
"sign out and forget" flows.
|
|
2147
|
+
### SandboxListenerEvent
|
|
2103
2148
|
|
|
2104
|
-
|
|
2149
|
+
Canonical listener lifecycle/delivery event. Firestore's existing snapshot
|
|
2150
|
+
delivery/lifecycle variants are preserved; this shape gives RTDB and future
|
|
2151
|
+
service listeners the same debuggable surface.
|
|
2105
2152
|
|
|
2106
|
-
|
|
2153
|
+
#### Properties
|
|
2107
2154
|
|
|
2108
|
-
|
|
2155
|
+
| Property | Type |
|
|
2156
|
+
| :------ | :------ |
|
|
2157
|
+
| <a id="at-4"></a> `at` | `number` |
|
|
2158
|
+
| <a id="auth-7"></a> `auth` | \{ `token?`: `Record`\<`string`, `unknown`\>; `uid`: `string`; \} |
|
|
2159
|
+
| `auth.token?` | `Record`\<`string`, `unknown`\> |
|
|
2160
|
+
| `auth.uid` | `string` |
|
|
2161
|
+
| <a id="detail-2"></a> `detail?` | `Record`\<`string`, `unknown`\> |
|
|
2162
|
+
| <a id="error-1"></a> `error?` | \{ `code?`: `string`; `message`: `string`; `reasons?`: `string`[]; \} |
|
|
2163
|
+
| `error.code?` | `string` |
|
|
2164
|
+
| `error.message` | `string` |
|
|
2165
|
+
| `error.reasons?` | `string`[] |
|
|
2166
|
+
| <a id="id-4"></a> `id` | `string` |
|
|
2167
|
+
| <a id="kind-3"></a> `kind` | `"listener"` |
|
|
2168
|
+
| <a id="listenerid-2"></a> `listenerId` | `string` |
|
|
2169
|
+
| <a id="phase"></a> `phase` | `"attach"` \| `"detach"` \| `"delivery"` \| `"suppressed"` \| `"errored"` |
|
|
2170
|
+
| <a id="reason"></a> `reason?` | `string` |
|
|
2171
|
+
| <a id="result-2"></a> `result?` | `"unsupported"` \| `"error"` \| `"allow"` \| `"deny"` |
|
|
2172
|
+
| <a id="sample"></a> `sample?` | `unknown` |
|
|
2173
|
+
| <a id="service-3"></a> `service` | [`EventService`](#eventservice) |
|
|
2174
|
+
| <a id="size"></a> `size?` | `number` |
|
|
2175
|
+
| <a id="target-1"></a> `target` | \{ `kind`: `string`; `path?`: `string`; `query?`: `unknown`; \} |
|
|
2176
|
+
| `target.kind` | `string` |
|
|
2177
|
+
| `target.path?` | `string` |
|
|
2178
|
+
| `target.query?` | `unknown` |
|
|
2179
|
+
| <a id="triggeredby-1"></a> `triggeredBy?` | \{ `method`: `string`; `path?`: `string`; \} |
|
|
2180
|
+
| `triggeredBy.method` | `string` |
|
|
2181
|
+
| `triggeredBy.path?` | `string` |
|
|
2109
2182
|
|
|
2110
|
-
|
|
2183
|
+
***
|
|
2111
2184
|
|
|
2112
|
-
|
|
2185
|
+
<a id="sandboxoperationevent"></a>
|
|
2113
2186
|
|
|
2114
|
-
|
|
2115
|
-
dispose(): void;
|
|
2116
|
-
```
|
|
2187
|
+
### SandboxOperationEvent
|
|
2117
2188
|
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
outgoing instance defensively. Idempotent. Does not touch data.
|
|
2189
|
+
Canonical service operation event. This is the service-neutral successor to
|
|
2190
|
+
Firestore's `request` traffic shape: every user-visible operation can be
|
|
2191
|
+
represented here, whether it is backed by security rules (Firestore/RTDB/
|
|
2192
|
+
Storage) or by a service control plane (Auth).
|
|
2123
2193
|
|
|
2124
|
-
|
|
2194
|
+
Existing Firestore `request` events remain for compatibility. New cross-
|
|
2195
|
+
service consumers should prefer `operation` because it carries an explicit
|
|
2196
|
+
`service` discriminator and does not require RTDB/Storage/Auth to pretend
|
|
2197
|
+
their state is a Firestore document.
|
|
2125
2198
|
|
|
2126
|
-
|
|
2199
|
+
#### Properties
|
|
2127
2200
|
|
|
2128
|
-
|
|
2201
|
+
| Property | Type | Description |
|
|
2202
|
+
| :------ | :------ | :------ |
|
|
2203
|
+
| <a id="at-5"></a> `at` | `number` | - |
|
|
2204
|
+
| <a id="auth-8"></a> `auth` | \{ `token?`: `Record`\<`string`, `unknown`\>; `uid`: `string`; \} | - |
|
|
2205
|
+
| `auth.token?` | `Record`\<`string`, `unknown`\> | - |
|
|
2206
|
+
| `auth.uid` | `string` | - |
|
|
2207
|
+
| <a id="detail-3"></a> `detail?` | `Record`\<`string`, `unknown`\> | - |
|
|
2208
|
+
| <a id="durationms"></a> `durationMs?` | `number` | - |
|
|
2209
|
+
| <a id="groupid-2"></a> `groupId?` | `string` | - |
|
|
2210
|
+
| <a id="groupkind-3"></a> `groupKind?` | `"transaction"` \| `"batch"` | - |
|
|
2211
|
+
| <a id="id-5"></a> `id` | `string` | - |
|
|
2212
|
+
| <a id="kind-4"></a> `kind` | `"operation"` | - |
|
|
2213
|
+
| <a id="method-3"></a> `method` | `string` | - |
|
|
2214
|
+
| <a id="origin-1"></a> `origin` | `"admin"` \| `"user"` \| `"system"` \| `"transaction"` \| `"listener"` \| `"batch"` | - |
|
|
2215
|
+
| <a id="path-3"></a> `path?` | `string` | - |
|
|
2216
|
+
| <a id="reasons-3"></a> `reasons?` | `string`[] | - |
|
|
2217
|
+
| <a id="request-3"></a> `request?` | \{ `data?`: `unknown`; `query?`: `unknown`; `resourceData?`: `unknown`; \} | - |
|
|
2218
|
+
| `request.data?` | `unknown` | - |
|
|
2219
|
+
| `request.query?` | `unknown` | - |
|
|
2220
|
+
| `request.resourceData?` | `unknown` | - |
|
|
2221
|
+
| <a id="resourceafter-1"></a> `resourceAfter?` | \{ `data`: `unknown`; `exists`: `boolean`; \} | - |
|
|
2222
|
+
| `resourceAfter.data` | `unknown` | - |
|
|
2223
|
+
| `resourceAfter.exists` | `boolean` | - |
|
|
2224
|
+
| <a id="resourcebefore-1"></a> `resourceBefore?` | \{ `data`: `unknown`; `exists`: `boolean`; \} | - |
|
|
2225
|
+
| `resourceBefore.data` | `unknown` | - |
|
|
2226
|
+
| `resourceBefore.exists` | `boolean` | - |
|
|
2227
|
+
| <a id="result-3"></a> `result` | `"unsupported"` \| `"error"` \| `"allow"` \| `"deny"` \| `"not-applicable"` | - |
|
|
2228
|
+
| <a id="rules-2"></a> `rules?` | \{ `engine`: `"firestore"` \| `"rtdb"` \| `"storage"`; `errorCode?`: `string`; `matchedPath?`: `string`; `matchedRule?`: `string`; `operations?`: `string`[]; `pathVariableBindings?`: `Record`\<`string`, `string`\>; `reason?`: `string`; `ruleIndex?`: `number`; \} | - |
|
|
2229
|
+
| `rules.engine` | `"firestore"` \| `"rtdb"` \| `"storage"` | - |
|
|
2230
|
+
| `rules.errorCode?` | `string` | - |
|
|
2231
|
+
| `rules.matchedPath?` | `string` | - |
|
|
2232
|
+
| `rules.matchedRule?` | `string` | - |
|
|
2233
|
+
| `rules.operations?` | `string`[] | - |
|
|
2234
|
+
| `rules.pathVariableBindings?` | `Record`\<`string`, `string`\> | - |
|
|
2235
|
+
| `rules.reason?` | `string` | - |
|
|
2236
|
+
| `rules.ruleIndex?` | `number` | - |
|
|
2237
|
+
| <a id="rulesdisposition-1"></a> `rulesDisposition?` | [`RulesDisposition`](#rulesdisposition-2) | Canonical statement of whether Security Rules evaluated this operation. Service emitters may provide it directly; the recorder normalizes legacy operation shapes at the unified stream seam. |
|
|
2238
|
+
| <a id="service-4"></a> `service` | [`EventService`](#eventservice) | - |
|
|
2239
|
+
| <a id="triggeredby-2"></a> `triggeredBy?` | \{ `method`: `string`; `path?`: `string`; \} | - |
|
|
2240
|
+
| `triggeredBy.method` | `string` | - |
|
|
2241
|
+
| `triggeredBy.path?` | `string` | - |
|
|
2129
2242
|
|
|
2130
|
-
|
|
2243
|
+
***
|
|
2131
2244
|
|
|
2132
|
-
|
|
2133
|
-
enablePersistence(options: SandboxPersistenceOptions): Promise<void>;
|
|
2134
|
-
```
|
|
2135
|
-
|
|
2136
|
-
Persist the sandbox's data to a backend and restore it on next
|
|
2137
|
-
`enablePersistence` call. The default `'indexedDB'` backend turns
|
|
2138
|
-
the sandbox into the host page's local Firestore — writes flush
|
|
2139
|
-
automatically and a fresh `initializeSandbox()` rehydrates from
|
|
2140
|
-
the prior session.
|
|
2141
|
-
|
|
2142
|
-
Restoration happens before the promise resolves; awaiting this
|
|
2143
|
-
call is sufficient to guarantee in-memory state matches the
|
|
2144
|
-
persisted blob.
|
|
2145
|
-
|
|
2146
|
-
Idempotent across the same `key` — calling twice in one process
|
|
2147
|
-
is a no-op on the second call. Different keys are rejected as an
|
|
2148
|
-
error (a sandbox can persist to at most one backend at a time).
|
|
2149
|
-
|
|
2150
|
-
Listener semantics: every write event the sandbox emits triggers
|
|
2151
|
-
a debounced flush (default 250ms). Browser hosts additionally
|
|
2152
|
-
flush on `beforeunload` so a page navigation doesn't lose the
|
|
2153
|
-
tail of the debounce window.
|
|
2154
|
-
|
|
2155
|
-
See [SandboxPersistenceOptions](#sandboxpersistenceoptions) for backend selection and
|
|
2156
|
-
tuning.
|
|
2157
|
-
|
|
2158
|
-
###### Parameters
|
|
2159
|
-
|
|
2160
|
-
| Parameter | Type |
|
|
2161
|
-
| :------ | :------ |
|
|
2162
|
-
| `options` | [`SandboxPersistenceOptions`](#sandboxpersistenceoptions) |
|
|
2163
|
-
|
|
2164
|
-
###### Returns
|
|
2165
|
-
|
|
2166
|
-
`Promise`\<`void`\>
|
|
2167
|
-
|
|
2168
|
-
<a id="enabletabsync-4"></a>
|
|
2169
|
-
|
|
2170
|
-
##### enableTabSync()
|
|
2171
|
-
|
|
2172
|
-
```ts
|
|
2173
|
-
enableTabSync(options?: TabSyncOptions): () => void;
|
|
2174
|
-
```
|
|
2175
|
-
|
|
2176
|
-
Enable cross-tab realtime sync via `BroadcastChannel`. A write in
|
|
2177
|
-
this tab will propagate to every OTHER tab of the same origin that
|
|
2178
|
-
also called `enableTabSync`, causing their `onSnapshot` listeners to
|
|
2179
|
-
re-evaluate — restoring production's cross-client realtime behavior.
|
|
2180
|
-
|
|
2181
|
-
**Opt-in, OFF by default.** Firestore only (RTDB is a follow-on).
|
|
2182
|
-
|
|
2183
|
-
Returns a disable function. Calling it removes the `onEvent`
|
|
2184
|
-
subscription, the channel message listener, and closes the channel
|
|
2185
|
-
(when it was created internally). After disable, no further propagation
|
|
2186
|
-
occurs in either direction.
|
|
2187
|
-
|
|
2188
|
-
**Multi-writer note:** concurrent writes from two tabs to the same doc
|
|
2189
|
-
produce last-write-wins divergence — there is no conflict resolution.
|
|
2190
|
-
The intended model is one active writer (one user, one tab) with
|
|
2191
|
-
observers in other tabs; this covers the overwhelming majority of
|
|
2192
|
-
local development scenarios.
|
|
2193
|
-
|
|
2194
|
-
###### Parameters
|
|
2195
|
-
|
|
2196
|
-
| Parameter | Type |
|
|
2197
|
-
| :------ | :------ |
|
|
2198
|
-
| `options?` | [`TabSyncOptions`](#tabsyncoptions) |
|
|
2199
|
-
|
|
2200
|
-
###### Returns
|
|
2201
|
-
|
|
2202
|
-
```ts
|
|
2203
|
-
(): void;
|
|
2204
|
-
```
|
|
2205
|
-
|
|
2206
|
-
###### Returns
|
|
2207
|
-
|
|
2208
|
-
`void`
|
|
2209
|
-
|
|
2210
|
-
###### See
|
|
2211
|
-
|
|
2212
|
-
[TabSyncOptions](#tabsyncoptions) for channel injection (tests) and originId.
|
|
2213
|
-
|
|
2214
|
-
###### Example
|
|
2215
|
-
|
|
2216
|
-
```ts
|
|
2217
|
-
// In every tab that should participate in realtime:
|
|
2218
|
-
const sandbox = initializeSandbox();
|
|
2219
|
-
const disableSync = sandbox.enableTabSync();
|
|
2220
|
-
// Later, to stop syncing:
|
|
2221
|
-
disableSync();
|
|
2222
|
-
```
|
|
2223
|
-
|
|
2224
|
-
<a id="flush-6"></a>
|
|
2225
|
-
|
|
2226
|
-
##### flush()
|
|
2227
|
-
|
|
2228
|
-
```ts
|
|
2229
|
-
flush(): Promise<void>;
|
|
2230
|
-
```
|
|
2231
|
-
|
|
2232
|
-
Force a snapshot to the configured persistence backend right now.
|
|
2233
|
-
Useful before a manual navigation, or in tests that need
|
|
2234
|
-
deterministic ordering against the debounce window. Resolves once
|
|
2235
|
-
the write hits the backend.
|
|
2236
|
-
|
|
2237
|
-
Throws if persistence is not enabled.
|
|
2238
|
-
|
|
2239
|
-
###### Returns
|
|
2240
|
-
|
|
2241
|
-
`Promise`\<`void`\>
|
|
2242
|
-
|
|
2243
|
-
<a id="history-4"></a>
|
|
2244
|
-
|
|
2245
|
-
##### history()
|
|
2246
|
-
|
|
2247
|
-
```ts
|
|
2248
|
-
history(): SandboxEvent[];
|
|
2249
|
-
```
|
|
2250
|
-
|
|
2251
|
-
Every [SandboxEvent](#sandboxevent) this sandbox has emitted since init or
|
|
2252
|
-
the last `reset()`. Returns a defensive copy.
|
|
2253
|
-
|
|
2254
|
-
Use this for replay: hand the array to `replay(events, rules)`
|
|
2255
|
-
from `pyric/sandbox` and the engine re-issues every
|
|
2256
|
-
captured write against a fresh sandbox.
|
|
2257
|
-
|
|
2258
|
-
Unlike [onEvent](#onevent-4) (live stream from the moment of subscribe),
|
|
2259
|
-
`history()` returns *every* event the sandbox has seen — useful
|
|
2260
|
-
for consumers that attach late (e.g., loading a saved session
|
|
2261
|
-
before subscribing) or that need a snapshot at a particular moment.
|
|
2262
|
-
|
|
2263
|
-
`reset()` and `dispose()` each append a closing `session_boundary`
|
|
2264
|
-
event; `reset()` then clears the history. Consumers that took a
|
|
2265
|
-
snapshot *before* reset retain the boundary in their copy.
|
|
2266
|
-
|
|
2267
|
-
###### Returns
|
|
2268
|
-
|
|
2269
|
-
[`SandboxEvent`](#sandboxevent)[]
|
|
2270
|
-
|
|
2271
|
-
<a id="loadsnapshot-4"></a>
|
|
2272
|
-
|
|
2273
|
-
##### loadSnapshot()
|
|
2274
|
-
|
|
2275
|
-
```ts
|
|
2276
|
-
loadSnapshot(data: SandboxSnapshot): void;
|
|
2277
|
-
```
|
|
2278
|
-
|
|
2279
|
-
CLOBBER-restore the sandbox's entire state from a prior [snapshot](#snapshot-6):
|
|
2280
|
-
`reset()` (clears firestore + the signed-in session), then rebuild firestore
|
|
2281
|
-
from `data` and restore each registered service. This is a TOTAL replace —
|
|
2282
|
-
documents absent from `data` do NOT survive — and is the counterpart to
|
|
2283
|
-
[snapshot](#snapshot-6). It is what makes "transfer (clobber) one instance's data
|
|
2284
|
-
into another" and named-branch switching possible.
|
|
2285
|
-
|
|
2286
|
-
Fires a `session_boundary` (reset phase), re-evaluates live listeners against
|
|
2287
|
-
the loaded state, and the next persistence flush writes the loaded state.
|
|
2288
|
-
Services present in `data` but not currently registered are skipped (a
|
|
2289
|
-
snapshot taken via [snapshot](#snapshot-6) always includes every registered
|
|
2290
|
-
service, so this only affects cross-instance imports from a sandbox that had
|
|
2291
|
-
a service this one lacks).
|
|
2292
|
-
|
|
2293
|
-
###### Parameters
|
|
2294
|
-
|
|
2295
|
-
| Parameter | Type |
|
|
2296
|
-
| :------ | :------ |
|
|
2297
|
-
| `data` | [`SandboxSnapshot`](#sandboxsnapshot-2) |
|
|
2298
|
-
|
|
2299
|
-
###### Returns
|
|
2300
|
-
|
|
2301
|
-
`void`
|
|
2302
|
-
|
|
2303
|
-
<a id="oncurrentuserchanged-4"></a>
|
|
2304
|
-
|
|
2305
|
-
##### onCurrentUserChanged()
|
|
2306
|
-
|
|
2307
|
-
```ts
|
|
2308
|
-
onCurrentUserChanged(cb: (user: {
|
|
2309
|
-
token?: Record<string, unknown>;
|
|
2310
|
-
uid: string;
|
|
2311
|
-
}) => void): () => void;
|
|
2312
|
-
```
|
|
2313
|
-
|
|
2314
|
-
Subscribe to `currentUser` changes. Fires on every mutation —
|
|
2315
|
-
sign-in, sign-out, user swap. Does NOT fire on subscribe.
|
|
2316
|
-
|
|
2317
|
-
Survives `reset()` and `dispose()` only as a no-op: a disposed
|
|
2318
|
-
sandbox emits nothing further; a reset sandbox clears
|
|
2319
|
-
`currentUser` to `null` (and fires the change) before swapping
|
|
2320
|
-
the env.
|
|
2321
|
-
|
|
2322
|
-
Returns an unsubscribe function. Listener errors are swallowed —
|
|
2323
|
-
subscribers are observational, the sandbox does not propagate
|
|
2324
|
-
their errors.
|
|
2325
|
-
|
|
2326
|
-
###### Parameters
|
|
2327
|
-
|
|
2328
|
-
| Parameter | Type |
|
|
2329
|
-
| :------ | :------ |
|
|
2330
|
-
| `cb` | (`user`: \{ `token?`: `Record`\<`string`, `unknown`\>; `uid`: `string`; \}) => `void` |
|
|
2331
|
-
|
|
2332
|
-
###### Returns
|
|
2333
|
-
|
|
2334
|
-
```ts
|
|
2335
|
-
(): void;
|
|
2336
|
-
```
|
|
2337
|
-
|
|
2338
|
-
###### Returns
|
|
2339
|
-
|
|
2340
|
-
`void`
|
|
2341
|
-
|
|
2342
|
-
<a id="onevent-4"></a>
|
|
2343
|
-
|
|
2344
|
-
##### onEvent()
|
|
2345
|
-
|
|
2346
|
-
```ts
|
|
2347
|
-
onEvent(cb: (event: SandboxEvent) => void): () => void;
|
|
2348
|
-
```
|
|
2349
|
-
|
|
2350
|
-
Subscribe to every event the sandbox emits — see [SandboxEvent](#sandboxevent)
|
|
2351
|
-
for the discriminated-union shape. One subscription covers
|
|
2352
|
-
request/denial/snapshot-error/listener-lifecycle/session-boundary;
|
|
2353
|
-
filter on `event.kind` to recover individual streams.
|
|
2354
|
-
|
|
2355
|
-
Replaces the prior three-channel surface (`onRequest` / `onDenial`
|
|
2356
|
-
/ `onSnapshotError`) — see issue #307. Filter cookbook:
|
|
2357
|
-
- All denials: `event.kind === 'request' && event.result === 'deny'`
|
|
2358
|
-
- Stream errors: `event.kind === 'listener_errored'`
|
|
2359
|
-
- Per-op traffic: `event.kind === 'request'`
|
|
2360
|
-
|
|
2361
|
-
Survives `sandbox.reset()` — the subscription is held on the
|
|
2362
|
-
sandbox, not on the underlying environment. A `session_boundary`
|
|
2363
|
-
event with `phase: 'reset'` fires before the env swap so consumers
|
|
2364
|
-
can segment their stream.
|
|
2365
|
-
|
|
2366
|
-
Returns an unsubscribe function. Listener errors are swallowed so a
|
|
2367
|
-
faulty subscriber can't change rule semantics or hide other events.
|
|
2368
|
-
Both synchronous throws and rejected Promises from async callbacks
|
|
2369
|
-
are silently discarded — subscribers are **observational**, the
|
|
2370
|
-
sandbox doesn't await them and doesn't propagate their errors.
|
|
2371
|
-
|
|
2372
|
-
###### Parameters
|
|
2373
|
-
|
|
2374
|
-
| Parameter | Type |
|
|
2375
|
-
| :------ | :------ |
|
|
2376
|
-
| `cb` | (`event`: [`SandboxEvent`](#sandboxevent)) => `void` |
|
|
2377
|
-
|
|
2378
|
-
###### Returns
|
|
2379
|
-
|
|
2380
|
-
```ts
|
|
2381
|
-
(): void;
|
|
2382
|
-
```
|
|
2383
|
-
|
|
2384
|
-
###### Returns
|
|
2385
|
-
|
|
2386
|
-
`void`
|
|
2387
|
-
|
|
2388
|
-
<a id="registerpersistableservice-4"></a>
|
|
2389
|
-
|
|
2390
|
-
##### registerPersistableService()
|
|
2391
|
-
|
|
2392
|
-
```ts
|
|
2393
|
-
registerPersistableService(name: string, hooks: PersistableService): () => void;
|
|
2394
|
-
```
|
|
2395
|
-
|
|
2396
|
-
Register a service (auth, storage, …) as a persistence participant.
|
|
2397
|
-
The sandbox calls `hooks.snapshot()` on every flush and
|
|
2398
|
-
`hooks.restore(data)` on restore. If `hooks.subscribe` is provided,
|
|
2399
|
-
the persistence controller subscribes and schedules a debounced
|
|
2400
|
-
flush on each change — so auth-user edits flush promptly, not only
|
|
2401
|
-
on the next Firestore write.
|
|
2402
|
-
|
|
2403
|
-
Returns an unregister function — call it if the service is torn
|
|
2404
|
-
down before the sandbox is disposed (uncommon in practice; the
|
|
2405
|
-
sandbox's `dispose()` clears the registry anyway).
|
|
2406
|
-
|
|
2407
|
-
Throws `failed-precondition` when a service with the same `name` is
|
|
2408
|
-
already registered — the auth package registers `'auth'` once when
|
|
2409
|
-
`getAuth(sandbox)` first creates a backend, so accidental double-
|
|
2410
|
-
registration is a caller bug, not a no-op.
|
|
2411
|
-
|
|
2412
|
-
**Advanced / internal API.** Service packages (auth, storage) call
|
|
2413
|
-
this when they first attach to a sandbox. Consumer app code should
|
|
2414
|
-
not need to call this directly.
|
|
2415
|
-
|
|
2416
|
-
###### Parameters
|
|
2417
|
-
|
|
2418
|
-
| Parameter | Type |
|
|
2419
|
-
| :------ | :------ |
|
|
2420
|
-
| `name` | `string` |
|
|
2421
|
-
| `hooks` | [`PersistableService`](#persistableservice) |
|
|
2422
|
-
|
|
2423
|
-
###### Returns
|
|
2424
|
-
|
|
2425
|
-
```ts
|
|
2426
|
-
(): void;
|
|
2427
|
-
```
|
|
2428
|
-
|
|
2429
|
-
###### Returns
|
|
2430
|
-
|
|
2431
|
-
`void`
|
|
2432
|
-
|
|
2433
|
-
<a id="reset-4"></a>
|
|
2434
|
-
|
|
2435
|
-
##### reset()
|
|
2436
|
-
|
|
2437
|
-
```ts
|
|
2438
|
-
reset(): void;
|
|
2439
|
-
```
|
|
2440
|
-
|
|
2441
|
-
Reset the underlying environment to a fresh state — wipes data,
|
|
2442
|
-
rules, and any service-specific configuration.
|
|
2443
|
-
|
|
2444
|
-
Snapshot listeners attached to the OLD environment are dropped at
|
|
2445
|
-
the swap — they can't survive because their target docs have been
|
|
2446
|
-
wiped. `onEvent` subscribers DO survive — the registry lives on
|
|
2447
|
-
the sandbox, and a `session_boundary` event with `phase: 'reset'`
|
|
2448
|
-
fires before the swap so subscribers know the rollover happened.
|
|
2449
|
-
Existing [SandboxContext](#sandboxcontext)s continue to work — their sandbox
|
|
2450
|
-
reference is stable; subsequent operations resolve to the new env.
|
|
2451
|
-
|
|
2452
|
-
###### Returns
|
|
2453
|
-
|
|
2454
|
-
`void`
|
|
2455
|
-
|
|
2456
|
-
<a id="runwithprovenance-4"></a>
|
|
2457
|
-
|
|
2458
|
-
##### runWithProvenance()?
|
|
2459
|
-
|
|
2460
|
-
```ts
|
|
2461
|
-
optional runWithProvenance<T>(provenance: EventProvenance, fn: () => T): T;
|
|
2462
|
-
```
|
|
2463
|
-
|
|
2464
|
-
Run `fn` with ambient [EventProvenance](#eventprovenance) defaults: every event
|
|
2465
|
-
emitted SYNCHRONOUSLY during `fn` that doesn't already carry a
|
|
2466
|
-
provenance field (on the event itself or via an explicit per-emit
|
|
2467
|
-
override) is stamped with these values instead of the global
|
|
2468
|
-
defaults. This is the mechanical "who issued this op" seam the
|
|
2469
|
-
serve worker uses to tag Studio-issued ops (`actor: { kind:
|
|
2470
|
-
'studio' }`) and to stamp the auth lens an op ran under
|
|
2471
|
-
(`authLens`) — declared by the caller that issues the op, never
|
|
2472
|
-
inferred from the op's shape.
|
|
2473
|
-
|
|
2474
|
-
SYNCHRONOUS WINDOW: the ambient values apply only until `fn`
|
|
2475
|
-
returns (for an async `fn`, its synchronous prefix — which covers
|
|
2476
|
-
the local environment's rules eval + event emission, since those
|
|
2477
|
-
run before the op's promise is handed back). Work an op DEFERS
|
|
2478
|
-
(snapshot-listener deliveries and re-evals drain on a microtask,
|
|
2479
|
-
off-stack) is intentionally OUTSIDE the window: a listener re-eval
|
|
2480
|
-
belongs to the listener's owner, not to whoever's write triggered
|
|
2481
|
-
it. Nested calls stack — the innermost window wins per field, and
|
|
2482
|
-
each window restores the previous one on exit (including on throw).
|
|
2483
|
-
|
|
2484
|
-
OPTIONAL because remote sandbox proxies can't provide an ambient
|
|
2485
|
-
emit window (events are emitted in the worker they front). Callers
|
|
2486
|
-
spell `sandbox.runWithProvenance?.(prov, fn) ?? fn()`.
|
|
2487
|
-
|
|
2488
|
-
###### Type Parameters
|
|
2489
|
-
|
|
2490
|
-
| Type Parameter |
|
|
2491
|
-
| :------ |
|
|
2492
|
-
| `T` |
|
|
2493
|
-
|
|
2494
|
-
###### Parameters
|
|
2495
|
-
|
|
2496
|
-
| Parameter | Type |
|
|
2497
|
-
| :------ | :------ |
|
|
2498
|
-
| `provenance` | [`EventProvenance`](#eventprovenance) |
|
|
2499
|
-
| `fn` | () => `T` |
|
|
2500
|
-
|
|
2501
|
-
###### Returns
|
|
2502
|
-
|
|
2503
|
-
`T`
|
|
2504
|
-
|
|
2505
|
-
<a id="snapshot-6"></a>
|
|
2506
|
-
|
|
2507
|
-
##### snapshot()
|
|
2508
|
-
|
|
2509
|
-
```ts
|
|
2510
|
-
snapshot(): SandboxSnapshot;
|
|
2511
|
-
```
|
|
2512
|
-
|
|
2513
|
-
Capture a snapshot of every service's state. For v1 with only
|
|
2514
|
-
Firestore, the return value carries a `firestore` key mapping doc
|
|
2515
|
-
paths to data. Future services will add their own keys.
|
|
2516
|
-
|
|
2517
|
-
###### Returns
|
|
2518
|
-
|
|
2519
|
-
[`SandboxSnapshot`](#sandboxsnapshot-2)
|
|
2520
|
-
|
|
2521
|
-
<a id="withauth-6"></a>
|
|
2522
|
-
|
|
2523
|
-
##### withAuth()
|
|
2524
|
-
|
|
2525
|
-
```ts
|
|
2526
|
-
withAuth(auth: {
|
|
2527
|
-
token?: Record<string, unknown>;
|
|
2528
|
-
uid: string;
|
|
2529
|
-
}): SandboxContext;
|
|
2530
|
-
```
|
|
2531
|
-
|
|
2532
|
-
Derive a context bound to this sandbox under the given auth
|
|
2533
|
-
identity. Operations through services attached to the returned
|
|
2534
|
-
context evaluate rules under that identity. Many contexts can
|
|
2535
|
-
coexist for one sandbox; data is shared.
|
|
2536
|
-
|
|
2537
|
-
`null` is anonymous; an `AuthState` object names the user (and
|
|
2538
|
-
optional custom claims). Passing `undefined` is a deliberate
|
|
2539
|
-
error — say `withAuth(null)` for anonymous so the call site is
|
|
2540
|
-
unambiguous.
|
|
2541
|
-
|
|
2542
|
-
###### Parameters
|
|
2543
|
-
|
|
2544
|
-
| Parameter | Type |
|
|
2545
|
-
| :------ | :------ |
|
|
2546
|
-
| `auth` | \{ `token?`: `Record`\<`string`, `unknown`\>; `uid`: `string`; \} |
|
|
2547
|
-
| `auth.token?` | `Record`\<`string`, `unknown`\> |
|
|
2548
|
-
| `auth.uid` | `string` |
|
|
2549
|
-
|
|
2550
|
-
###### Returns
|
|
2551
|
-
|
|
2552
|
-
[`SandboxContext`](#sandboxcontext)
|
|
2553
|
-
|
|
2554
|
-
###### Example
|
|
2555
|
-
|
|
2556
|
-
```ts
|
|
2557
|
-
const sandbox = initializeSandbox();
|
|
2558
|
-
const dbAlice = getFirestore(sandbox.withAuth({ uid: 'alice' }));
|
|
2559
|
-
const dbAnon = getFirestore(sandbox.withAuth(null));
|
|
2560
|
-
```
|
|
2561
|
-
|
|
2562
|
-
***
|
|
2563
|
-
|
|
2564
|
-
<a id="sandboxcommitevent"></a>
|
|
2565
|
-
|
|
2566
|
-
### SandboxCommitEvent
|
|
2567
|
-
|
|
2568
|
-
Canonical committed mutation event. Unlike `operation`, this fires only when
|
|
2569
|
-
state actually changed. Replay and branch tooling should eventually consume
|
|
2570
|
-
these service adapters instead of filtering Firestore-only `write` events.
|
|
2571
|
-
|
|
2572
|
-
#### Properties
|
|
2573
|
-
|
|
2574
|
-
| Property | Type |
|
|
2575
|
-
| :------ | :------ |
|
|
2576
|
-
| <a id="at-3"></a> `at` | `number` |
|
|
2577
|
-
| <a id="auth-6"></a> `auth` | \{ `token?`: `Record`\<`string`, `unknown`\>; `uid`: `string`; \} |
|
|
2578
|
-
| `auth.token?` | `Record`\<`string`, `unknown`\> |
|
|
2579
|
-
| `auth.uid` | `string` |
|
|
2580
|
-
| <a id="data"></a> `data?` | `unknown` |
|
|
2581
|
-
| <a id="detail-1"></a> `detail?` | `Record`\<`string`, `unknown`\> |
|
|
2582
|
-
| <a id="groupid-1"></a> `groupId?` | `string` |
|
|
2583
|
-
| <a id="groupkind-1"></a> `groupKind?` | `"transaction"` \| `"batch"` |
|
|
2584
|
-
| <a id="id-3"></a> `id` | `string` |
|
|
2585
|
-
| <a id="kind-2"></a> `kind` | `"commit"` |
|
|
2586
|
-
| <a id="method-2"></a> `method` | `string` |
|
|
2587
|
-
| <a id="nextstate"></a> `nextState?` | `unknown` |
|
|
2588
|
-
| <a id="path-2"></a> `path?` | `string` |
|
|
2589
|
-
| <a id="priorstate"></a> `priorState?` | `unknown` |
|
|
2590
|
-
| <a id="replay"></a> `replay?` | \{ `autoId?`: `string`; `requestTime?`: `number`; `sentinels?`: \{ `field`: `string`; `kind`: `string`; \}[]; \} |
|
|
2591
|
-
| `replay.autoId?` | `string` |
|
|
2592
|
-
| `replay.requestTime?` | `number` |
|
|
2593
|
-
| `replay.sentinels?` | \{ `field`: `string`; `kind`: `string`; \}[] |
|
|
2594
|
-
| <a id="service-2"></a> `service` | [`EventService`](#eventservice) |
|
|
2595
|
-
|
|
2596
|
-
***
|
|
2597
|
-
|
|
2598
|
-
<a id="sandboxconfig"></a>
|
|
2599
|
-
|
|
2600
|
-
### SandboxConfig
|
|
2601
|
-
|
|
2602
|
-
Initialization config for a sandbox. All fields are optional; an
|
|
2603
|
-
empty config produces a sandbox with no rules and no seeded data.
|
|
2604
|
-
|
|
2605
|
-
**No `auth` field.** Identity belongs to [SandboxContext](#sandboxcontext), not
|
|
2606
|
-
the sandbox. Service handles always require an explicit context.
|
|
2607
|
-
|
|
2608
|
-
***
|
|
2609
|
-
|
|
2610
|
-
<a id="sandboxcontext"></a>
|
|
2611
|
-
|
|
2612
|
-
### SandboxContext
|
|
2613
|
-
|
|
2614
|
-
Identity-bearing handle on a [Sandbox](#sandbox-3). A
|
|
2615
|
-
`(sandbox, auth, operationContext)`
|
|
2616
|
-
tuple — cheap to create, immutable, freely shareable. Service
|
|
2617
|
-
factories require a `SandboxContext`; bare `Sandbox` is a type
|
|
2618
|
-
error so every call site states identity explicitly.
|
|
2619
|
-
|
|
2620
|
-
Constructed via `Sandbox.withAuth(auth)` or chained via
|
|
2621
|
-
`SandboxContext.withAuth(auth)`. The concrete class is exported
|
|
2622
|
-
from `pyric/sandbox` for `instanceof` routing in service
|
|
2623
|
-
factories; consumers don't construct it directly.
|
|
2624
|
-
|
|
2625
|
-
#### Properties
|
|
2626
|
-
|
|
2627
|
-
| Property | Modifier | Type | Description |
|
|
2628
|
-
| :------ | :------ | :------ | :------ |
|
|
2629
|
-
| <a id="auth-7"></a> `auth` | `readonly` | \{ `token?`: `Record`\<`string`, `unknown`\>; `uid`: `string`; \} | The identity rules evaluate under for operations through this context. |
|
|
2630
|
-
| `auth.token?` | `public` | `Record`\<`string`, `unknown`\> | - |
|
|
2631
|
-
| `auth.uid` | `public` | `string` | - |
|
|
2632
|
-
| <a id="operationcontext-3"></a> `operationContext` | `readonly` | [`OperationContext`](#operationcontext-2) | Immutable provenance bound to every operation issued through this handle. |
|
|
2633
|
-
| <a id="sandbox-4"></a> `sandbox` | `readonly` | [`Sandbox`](#sandbox-3) | The data foundation this context operates against. |
|
|
2634
|
-
|
|
2635
|
-
#### Methods
|
|
2636
|
-
|
|
2637
|
-
<a id="withauth-8"></a>
|
|
2638
|
-
|
|
2639
|
-
##### withAuth()
|
|
2640
|
-
|
|
2641
|
-
```ts
|
|
2642
|
-
withAuth(auth: {
|
|
2643
|
-
token?: Record<string, unknown>;
|
|
2644
|
-
uid: string;
|
|
2645
|
-
}): SandboxContext;
|
|
2646
|
-
```
|
|
2647
|
-
|
|
2648
|
-
Derive a sibling context on the same sandbox with different auth.
|
|
2649
|
-
Replaces auth and its lens while preserving the operation source and
|
|
2650
|
-
optional plan identity.
|
|
2651
|
-
|
|
2652
|
-
###### Parameters
|
|
2653
|
-
|
|
2654
|
-
| Parameter | Type |
|
|
2655
|
-
| :------ | :------ |
|
|
2656
|
-
| `auth` | \{ `token?`: `Record`\<`string`, `unknown`\>; `uid`: `string`; \} |
|
|
2657
|
-
| `auth.token?` | `Record`\<`string`, `unknown`\> |
|
|
2658
|
-
| `auth.uid` | `string` |
|
|
2659
|
-
|
|
2660
|
-
###### Returns
|
|
2661
|
-
|
|
2662
|
-
[`SandboxContext`](#sandboxcontext)
|
|
2663
|
-
|
|
2664
|
-
***
|
|
2665
|
-
|
|
2666
|
-
<a id="sandboxlistenerevent"></a>
|
|
2667
|
-
|
|
2668
|
-
### SandboxListenerEvent
|
|
2669
|
-
|
|
2670
|
-
Canonical listener lifecycle/delivery event. Firestore's existing snapshot
|
|
2671
|
-
delivery/lifecycle variants are preserved; this shape gives RTDB and future
|
|
2672
|
-
service listeners the same debuggable surface.
|
|
2673
|
-
|
|
2674
|
-
#### Properties
|
|
2675
|
-
|
|
2676
|
-
| Property | Type |
|
|
2677
|
-
| :------ | :------ |
|
|
2678
|
-
| <a id="at-4"></a> `at` | `number` |
|
|
2679
|
-
| <a id="auth-8"></a> `auth` | \{ `token?`: `Record`\<`string`, `unknown`\>; `uid`: `string`; \} |
|
|
2680
|
-
| `auth.token?` | `Record`\<`string`, `unknown`\> |
|
|
2681
|
-
| `auth.uid` | `string` |
|
|
2682
|
-
| <a id="detail-2"></a> `detail?` | `Record`\<`string`, `unknown`\> |
|
|
2683
|
-
| <a id="error-1"></a> `error?` | \{ `code?`: `string`; `message`: `string`; `reasons?`: `string`[]; \} |
|
|
2684
|
-
| `error.code?` | `string` |
|
|
2685
|
-
| `error.message` | `string` |
|
|
2686
|
-
| `error.reasons?` | `string`[] |
|
|
2687
|
-
| <a id="id-4"></a> `id` | `string` |
|
|
2688
|
-
| <a id="kind-3"></a> `kind` | `"listener"` |
|
|
2689
|
-
| <a id="listenerid-1"></a> `listenerId` | `string` |
|
|
2690
|
-
| <a id="phase"></a> `phase` | `"attach"` \| `"detach"` \| `"delivery"` \| `"suppressed"` \| `"errored"` |
|
|
2691
|
-
| <a id="reason"></a> `reason?` | `string` |
|
|
2692
|
-
| <a id="result-2"></a> `result?` | `"allow"` \| `"deny"` \| `"unsupported"` \| `"error"` |
|
|
2693
|
-
| <a id="sample"></a> `sample?` | `unknown` |
|
|
2694
|
-
| <a id="service-3"></a> `service` | [`EventService`](#eventservice) |
|
|
2695
|
-
| <a id="size"></a> `size?` | `number` |
|
|
2696
|
-
| <a id="target-1"></a> `target` | \{ `kind`: `string`; `path?`: `string`; `query?`: `unknown`; \} |
|
|
2697
|
-
| `target.kind` | `string` |
|
|
2698
|
-
| `target.path?` | `string` |
|
|
2699
|
-
| `target.query?` | `unknown` |
|
|
2700
|
-
| <a id="triggeredby-1"></a> `triggeredBy?` | \{ `method`: `string`; `path?`: `string`; \} |
|
|
2701
|
-
| `triggeredBy.method` | `string` |
|
|
2702
|
-
| `triggeredBy.path?` | `string` |
|
|
2703
|
-
|
|
2704
|
-
***
|
|
2705
|
-
|
|
2706
|
-
<a id="sandboxoperationevent"></a>
|
|
2707
|
-
|
|
2708
|
-
### SandboxOperationEvent
|
|
2709
|
-
|
|
2710
|
-
Canonical service operation event. This is the service-neutral successor to
|
|
2711
|
-
Firestore's `request` traffic shape: every user-visible operation can be
|
|
2712
|
-
represented here, whether it is backed by security rules (Firestore/RTDB/
|
|
2713
|
-
Storage) or by a service control plane (Auth).
|
|
2714
|
-
|
|
2715
|
-
Existing Firestore `request` events remain for compatibility. New cross-
|
|
2716
|
-
service consumers should prefer `operation` because it carries an explicit
|
|
2717
|
-
`service` discriminator and does not require RTDB/Storage/Auth to pretend
|
|
2718
|
-
their state is a Firestore document.
|
|
2719
|
-
|
|
2720
|
-
#### Properties
|
|
2721
|
-
|
|
2722
|
-
| Property | Type | Description |
|
|
2723
|
-
| :------ | :------ | :------ |
|
|
2724
|
-
| <a id="at-5"></a> `at` | `number` | - |
|
|
2725
|
-
| <a id="auth-9"></a> `auth` | \{ `token?`: `Record`\<`string`, `unknown`\>; `uid`: `string`; \} | - |
|
|
2726
|
-
| `auth.token?` | `Record`\<`string`, `unknown`\> | - |
|
|
2727
|
-
| `auth.uid` | `string` | - |
|
|
2728
|
-
| <a id="detail-3"></a> `detail?` | `Record`\<`string`, `unknown`\> | - |
|
|
2729
|
-
| <a id="durationms"></a> `durationMs?` | `number` | - |
|
|
2730
|
-
| <a id="groupid-2"></a> `groupId?` | `string` | - |
|
|
2731
|
-
| <a id="groupkind-2"></a> `groupKind?` | `"transaction"` \| `"batch"` | - |
|
|
2732
|
-
| <a id="id-5"></a> `id` | `string` | - |
|
|
2733
|
-
| <a id="kind-4"></a> `kind` | `"operation"` | - |
|
|
2734
|
-
| <a id="method-3"></a> `method` | `string` | - |
|
|
2735
|
-
| <a id="origin-1"></a> `origin` | `"admin"` \| `"user"` \| `"listener"` \| `"transaction"` \| `"batch"` \| `"system"` | - |
|
|
2736
|
-
| <a id="path-3"></a> `path?` | `string` | - |
|
|
2737
|
-
| <a id="reasons-3"></a> `reasons?` | `string`[] | - |
|
|
2738
|
-
| <a id="request-3"></a> `request?` | \{ `data?`: `unknown`; `query?`: `unknown`; `resourceData?`: `unknown`; \} | - |
|
|
2739
|
-
| `request.data?` | `unknown` | - |
|
|
2740
|
-
| `request.query?` | `unknown` | - |
|
|
2741
|
-
| `request.resourceData?` | `unknown` | - |
|
|
2742
|
-
| <a id="resourceafter-1"></a> `resourceAfter?` | \{ `data`: `unknown`; `exists`: `boolean`; \} | - |
|
|
2743
|
-
| `resourceAfter.data` | `unknown` | - |
|
|
2744
|
-
| `resourceAfter.exists` | `boolean` | - |
|
|
2745
|
-
| <a id="resourcebefore-1"></a> `resourceBefore?` | \{ `data`: `unknown`; `exists`: `boolean`; \} | - |
|
|
2746
|
-
| `resourceBefore.data` | `unknown` | - |
|
|
2747
|
-
| `resourceBefore.exists` | `boolean` | - |
|
|
2748
|
-
| <a id="result-3"></a> `result` | `"allow"` \| `"deny"` \| `"unsupported"` \| `"error"` \| `"not-applicable"` | - |
|
|
2749
|
-
| <a id="rules-2"></a> `rules?` | \{ `engine`: `"firestore"` \| `"storage"` \| `"rtdb"`; `errorCode?`: `string`; `matchedPath?`: `string`; `matchedRule?`: `string`; `operations?`: `string`[]; `pathVariableBindings?`: `Record`\<`string`, `string`\>; `reason?`: `string`; `ruleIndex?`: `number`; \} | - |
|
|
2750
|
-
| `rules.engine` | `"firestore"` \| `"storage"` \| `"rtdb"` | - |
|
|
2751
|
-
| `rules.errorCode?` | `string` | - |
|
|
2752
|
-
| `rules.matchedPath?` | `string` | - |
|
|
2753
|
-
| `rules.matchedRule?` | `string` | - |
|
|
2754
|
-
| `rules.operations?` | `string`[] | - |
|
|
2755
|
-
| `rules.pathVariableBindings?` | `Record`\<`string`, `string`\> | - |
|
|
2756
|
-
| `rules.reason?` | `string` | - |
|
|
2757
|
-
| `rules.ruleIndex?` | `number` | - |
|
|
2758
|
-
| <a id="rulesdisposition-1"></a> `rulesDisposition?` | [`RulesDisposition`](#rulesdisposition-2) | Canonical statement of whether Security Rules evaluated this operation. Service emitters may provide it directly; the recorder normalizes legacy operation shapes at the unified stream seam. |
|
|
2759
|
-
| <a id="service-4"></a> `service` | [`EventService`](#eventservice) | - |
|
|
2760
|
-
| <a id="triggeredby-2"></a> `triggeredBy?` | \{ `method`: `string`; `path?`: `string`; \} | - |
|
|
2761
|
-
| `triggeredBy.method` | `string` | - |
|
|
2762
|
-
| `triggeredBy.path?` | `string` | - |
|
|
2763
|
-
|
|
2764
|
-
***
|
|
2765
|
-
|
|
2766
|
-
<a id="sandboxpersistenceoptions"></a>
|
|
2245
|
+
<a id="sandboxpersistenceoptions"></a>
|
|
2767
2246
|
|
|
2768
2247
|
### SandboxPersistenceOptions
|
|
2769
2248
|
|
|
2770
|
-
Controller options. See [Sandbox.enablePersistence](#enablepersistence
|
|
2249
|
+
Controller options. See [Sandbox.enablePersistence](pyric-firestore-reference-api.md#enablepersistence).
|
|
2771
2250
|
|
|
2772
2251
|
#### Properties
|
|
2773
2252
|
|
|
2774
2253
|
| Property | Type | Description |
|
|
2775
2254
|
| :------ | :------ | :------ |
|
|
2776
|
-
| <a id="backend"></a> `backend?` | `"
|
|
2255
|
+
| <a id="backend"></a> `backend?` | `"memory"` \| `"indexedDB"` | Storage backend. `indexedDB` requires a browser environment; in non-browser hosts (Bun, Node, tests) the controller falls back to `memory` automatically unless an `injectedBackend` is supplied. Default: `indexedDB`. |
|
|
2777
2256
|
| <a id="flushintervalms"></a> `flushIntervalMs?` | `number` | Debounce window before write events are flushed to the backend. Buffers rapid bursts (e.g., a batch of seed writes) into one flush. Default: 250ms. |
|
|
2778
2257
|
| <a id="injectedbackend"></a> `injectedBackend?` | [`PersistenceBackend`](#persistencebackend) | Override the backend with an injected implementation. Used by tests and hosts that have their own storage adapter. When set, `backend` is ignored. |
|
|
2779
2258
|
| <a id="key"></a> `key` | `string` | IndexedDB database name (or generic bucket key for other backends). Different keys persist to different storage locations — use one key per logical sandbox if you run several in parallel. |
|
|
@@ -2794,7 +2273,7 @@ Canonical non-rules operational failure.
|
|
|
2794
2273
|
| Property | Type |
|
|
2795
2274
|
| :------ | :------ |
|
|
2796
2275
|
| <a id="at-6"></a> `at` | `number` |
|
|
2797
|
-
| <a id="auth-
|
|
2276
|
+
| <a id="auth-9"></a> `auth` | \{ `token?`: `Record`\<`string`, `unknown`\>; `uid`: `string`; \} |
|
|
2798
2277
|
| `auth.token?` | `Record`\<`string`, `unknown`\> |
|
|
2799
2278
|
| `auth.uid` | `string` |
|
|
2800
2279
|
| <a id="detail-4"></a> `detail?` | `Record`\<`string`, `unknown`\> |
|
|
@@ -2809,7 +2288,7 @@ Canonical non-rules operational failure.
|
|
|
2809
2288
|
|
|
2810
2289
|
***
|
|
2811
2290
|
|
|
2812
|
-
<a id="sandboxsnapshot
|
|
2291
|
+
<a id="sandboxsnapshot"></a>
|
|
2813
2292
|
|
|
2814
2293
|
### SandboxSnapshot
|
|
2815
2294
|
|
|
@@ -2865,7 +2344,7 @@ diff `before`→`after` when both are present.
|
|
|
2865
2344
|
| :------ | :------ | :------ |
|
|
2866
2345
|
| <a id="after"></a> `after?` | `unknown` | Best-effort serializable snapshot of the state AFTER the mutation. Absent on deletes / sign-outs (nothing remains). |
|
|
2867
2346
|
| <a id="at-7"></a> `at` | `number` | - |
|
|
2868
|
-
| <a id="auth-
|
|
2347
|
+
| <a id="auth-10"></a> `auth` | \{ `token?`: `Record`\<`string`, `unknown`\>; `uid`: `string`; \} | Identity in effect when the op ran (the service's `request.auth` equivalent). `null` for admin/anonymous-driven mutations (e.g. `sandbox.createUser`, an unauthenticated RTDB write). |
|
|
2869
2348
|
| `auth.token?` | `Record`\<`string`, `unknown`\> | - |
|
|
2870
2349
|
| `auth.uid` | `string` | - |
|
|
2871
2350
|
| <a id="before"></a> `before?` | `unknown` | Best-effort serializable snapshot of the state BEFORE the mutation. Absent when there was no prior state (a create) or it isn't cheap to capture. |
|
|
@@ -2874,7 +2353,7 @@ diff `before`→`after` when both are present.
|
|
|
2874
2353
|
| <a id="kind-6"></a> `kind` | `"service_mutation"` | - |
|
|
2875
2354
|
| <a id="op-2"></a> `op` | `string` | Service-scoped operation name. Stable, lowercase, snake/kebab-free: - auth: `user_create` | `user_update` | `user_delete` | `users_clear` | `sign_in` | `sign_out` - storage: `object_put` | `object_delete` | `metadata_update` - rtdb: `set` | `update` | `remove` | `transaction` - ai: `generate_content` | `stream_generate_content` | `count_tokens` | `request_rejected` New ops can be added without a breaking change (consumers switch with a default branch). |
|
|
2876
2355
|
| <a id="path-5"></a> `path?` | `string` | The thing mutated, in the service's own addressing scheme: - auth: the user `uid` (or `'*'` for a clear-all). Absent for a sign-out with no prior user. - storage: the object `fullPath` (e.g. `avatars/alice.png`). - rtdb: the database path (e.g. `/rooms/r1/messages`), or for a multi-path `update` the ref path the call targeted. |
|
|
2877
|
-
| <a id="service-6"></a> `service` | `"
|
|
2356
|
+
| <a id="service-6"></a> `service` | `"rtdb"` \| `"auth"` \| `"storage"` \| `"messaging"` \| `"ai"` | Which service performed the mutation. Always one of the non-Firestore services — Firestore rides its own `request`/`write` path. (The provenance `service` field on the stamped event mirrors this; it is set redundantly here so a consumer matching purely on `kind` still gets the discriminator without reaching into provenance.) |
|
|
2878
2357
|
|
|
2879
2358
|
***
|
|
2880
2359
|
|
|
@@ -2920,12 +2399,12 @@ scenario produces large snapshots.
|
|
|
2920
2399
|
| :------ | :------ | :------ |
|
|
2921
2400
|
| <a id="addedcount"></a> `addedCount` | `number` | - |
|
|
2922
2401
|
| <a id="at-9"></a> `at` | `number` | - |
|
|
2923
|
-
| <a id="auth-
|
|
2402
|
+
| <a id="auth-11"></a> `auth` | \{ `token?`: `Record`\<`string`, `unknown`\>; `uid`: `string`; \} | - |
|
|
2924
2403
|
| `auth.token?` | `Record`\<`string`, `unknown`\> | - |
|
|
2925
2404
|
| `auth.uid` | `string` | - |
|
|
2926
2405
|
| <a id="id-9"></a> `id` | `string` | - |
|
|
2927
2406
|
| <a id="kind-8"></a> `kind` | `"snapshot_delivery"` | - |
|
|
2928
|
-
| <a id="listenerid-
|
|
2407
|
+
| <a id="listenerid-3"></a> `listenerId` | `string` | Opaque listener id assigned at attach time. |
|
|
2929
2408
|
| <a id="modifiedcount"></a> `modifiedCount` | `number` | - |
|
|
2930
2409
|
| <a id="removedcount"></a> `removedCount` | `number` | - |
|
|
2931
2410
|
| <a id="sample-1"></a> `sample?` | \{ `docs`: \{ `data`: `Record`\<`string`, `unknown`\>; `path`: `string`; \}[]; \} | Doc payloads, in the order the user callback saw them. |
|
|
@@ -2962,20 +2441,20 @@ scenario surfaces them.
|
|
|
2962
2441
|
|
|
2963
2442
|
| Property | Type |
|
|
2964
2443
|
| :------ | :------ |
|
|
2965
|
-
| <a id="auth-
|
|
2444
|
+
| <a id="auth-12"></a> `auth?` | \{ `token?`: `Record`\<`string`, `unknown`\>; `uid`: `string`; \} |
|
|
2966
2445
|
| `auth.token?` | `Record`\<`string`, `unknown`\> |
|
|
2967
2446
|
| `auth.uid` | `string` |
|
|
2968
|
-
| <a id="code-
|
|
2447
|
+
| <a id="code-1"></a> `code` | `"permission-denied"` |
|
|
2969
2448
|
| <a id="message-1"></a> `message` | `string` |
|
|
2970
2449
|
| <a id="reasons-4"></a> `reasons?` | `string`[] |
|
|
2971
|
-
| <a id="request-4"></a> `request?` | \{ `method`: `"
|
|
2972
|
-
| `request.method` | `"
|
|
2450
|
+
| <a id="request-4"></a> `request?` | \{ `method`: `"delete"` \| `"get"` \| `"list"` \| `"create"` \| `"update"`; `path`: `string`; `resourceData?`: `Record`\<`string`, `unknown`\>; \} |
|
|
2451
|
+
| `request.method` | `"delete"` \| `"get"` \| `"list"` \| `"create"` \| `"update"` |
|
|
2973
2452
|
| `request.path` | `string` |
|
|
2974
2453
|
| `request.resourceData?` | `Record`\<`string`, `unknown`\> |
|
|
2975
2454
|
| <a id="resource-2"></a> `resource?` | \{ `data`: `Record`\<`string`, `unknown`\>; `exists`: `boolean`; \} |
|
|
2976
2455
|
| `resource.data` | `Record`\<`string`, `unknown`\> |
|
|
2977
2456
|
| `resource.exists` | `boolean` |
|
|
2978
|
-
| <a id="target-3"></a> `target` | \| \{ `kind`: `"doc"`; `path`: `string`; \} \| \{ `collection`: `string`; `kind`: `"query"`; \} |
|
|
2457
|
+
| <a id="target-3"></a> `target` | \| \{ `kind`: `"doc"`; `path`: `string`; \} \| \{ `collection`: `string`; `kind`: `"query"`; `query?`: `unknown`; \} |
|
|
2979
2458
|
|
|
2980
2459
|
***
|
|
2981
2460
|
|
|
@@ -2996,12 +2475,12 @@ them.
|
|
|
2996
2475
|
| Property | Type | Description |
|
|
2997
2476
|
| :------ | :------ | :------ |
|
|
2998
2477
|
| <a id="at-10"></a> `at` | `number` | - |
|
|
2999
|
-
| <a id="auth-
|
|
2478
|
+
| <a id="auth-13"></a> `auth` | \{ `token?`: `Record`\<`string`, `unknown`\>; `uid`: `string`; \} | - |
|
|
3000
2479
|
| `auth.token?` | `Record`\<`string`, `unknown`\> | - |
|
|
3001
2480
|
| `auth.uid` | `string` | - |
|
|
3002
2481
|
| <a id="id-10"></a> `id` | `string` | - |
|
|
3003
2482
|
| <a id="kind-9"></a> `kind` | `"snapshot_suppressed"` | - |
|
|
3004
|
-
| <a id="listenerid-
|
|
2483
|
+
| <a id="listenerid-4"></a> `listenerId` | `string` | - |
|
|
3005
2484
|
| <a id="reason-1"></a> `reason` | `"no-op"` | Why this re-eval was suppressed. v1 only emits `'no-op'`. |
|
|
3006
2485
|
| <a id="target-4"></a> `target` | \| \{ `kind`: `"doc"`; `path`: `string`; \} \| \{ `collection`: `string`; `kind`: `"query"`; \} | - |
|
|
3007
2486
|
| <a id="triggeredby-4"></a> `triggeredBy?` | \{ `method`: `string`; `path`: `string`; \} | - |
|
|
@@ -3124,17 +2603,17 @@ sentinel/auto-id capture lands.
|
|
|
3124
2603
|
| Property | Type | Description |
|
|
3125
2604
|
| :------ | :------ | :------ |
|
|
3126
2605
|
| <a id="at-11"></a> `at` | `number` | - |
|
|
3127
|
-
| <a id="auth-
|
|
2606
|
+
| <a id="auth-14"></a> `auth` | \{ `token?`: `Record`\<`string`, `unknown`\>; `uid`: `string`; \} | - |
|
|
3128
2607
|
| `auth.token?` | `Record`\<`string`, `unknown`\> | - |
|
|
3129
2608
|
| `auth.uid` | `string` | - |
|
|
3130
2609
|
| <a id="autoid"></a> `autoId?` | `string` | Minted document ID when this write came from `collection.add()` / `LocalEnvironment.createWithAutoId`. The replay engine aliases the path's last segment to a fresh mint on replay (rather than preserving the original auto-ID). |
|
|
3131
2610
|
| <a id="data-1"></a> `data?` | `Record`\<`string`, `unknown`\> | Pre-resolution write payload — `FieldValue.*` sentinels preserved as marker shapes (`{ __type: 'serverTimestamp' }`, etc.) so the replay engine can re-resolve them. The rule engine evaluated against the resolved form internally; the resolved form lives on [nextState](#nextstate-1). Absent on `delete`. |
|
|
3132
2611
|
| <a id="detail-6"></a> `detail?` | \{ `admin?`: `boolean`; \} & `Record`\<`string`, `unknown`\> | Free-form write metadata. `admin: true` marks a rules-bypassing setup/admin commit so replay can apply it as context without asking candidate rules to permit it. |
|
|
3133
2612
|
| <a id="groupid-3"></a> `groupId?` | `string` | - |
|
|
3134
|
-
| <a id="groupkind-
|
|
2613
|
+
| <a id="groupkind-4"></a> `groupKind?` | `"transaction"` \| `"batch"` | - |
|
|
3135
2614
|
| <a id="id-11"></a> `id` | `string` | - |
|
|
3136
2615
|
| <a id="kind-10"></a> `kind` | `"write"` | - |
|
|
3137
|
-
| <a id="method-5"></a> `method` | `"
|
|
2616
|
+
| <a id="method-5"></a> `method` | `"delete"` \| `"create"` \| `"update"` \| `"set"` | - |
|
|
3138
2617
|
| <a id="nextstate-1"></a> `nextState` | `Record`\<`string`, `unknown`\> | State AFTER this write. `null` on `delete`. |
|
|
3139
2618
|
| <a id="path-6"></a> `path` | `string` | - |
|
|
3140
2619
|
| <a id="priorstate-1"></a> `priorState` | `Record`\<`string`, `unknown`\> | State BEFORE this write. `null` for a non-existent doc. |
|
|
@@ -3171,32 +2650,6 @@ The identity/rules lens an operation actually ran under.
|
|
|
3171
2650
|
|
|
3172
2651
|
***
|
|
3173
2652
|
|
|
3174
|
-
<a id="authstate"></a>
|
|
3175
|
-
|
|
3176
|
-
### AuthState
|
|
3177
|
-
|
|
3178
|
-
```ts
|
|
3179
|
-
type AuthState =
|
|
3180
|
-
| {
|
|
3181
|
-
token?: Record<string, unknown>;
|
|
3182
|
-
uid: string;
|
|
3183
|
-
}
|
|
3184
|
-
| null;
|
|
3185
|
-
```
|
|
3186
|
-
|
|
3187
|
-
A signed-in identity for sandbox operations. `null` is anonymous.
|
|
3188
|
-
|
|
3189
|
-
`token` is the Firebase Auth token claims map (custom claims plus
|
|
3190
|
-
standard ones). It surfaces the same way it does in production rules
|
|
3191
|
-
via `request.auth.token.*`. Omit it for plain UID-only auth.
|
|
3192
|
-
|
|
3193
|
-
Renamed from `AuthContext` (pre-multi-context) so the data type
|
|
3194
|
-
doesn't visually collide with `SandboxContext` (the identity-bearing
|
|
3195
|
-
handle). They sit at different layers — payload vs. handle — and the
|
|
3196
|
-
names should reflect that.
|
|
3197
|
-
|
|
3198
|
-
***
|
|
3199
|
-
|
|
3200
2653
|
<a id="difftarget"></a>
|
|
3201
2654
|
|
|
3202
2655
|
### DiffTarget
|
|
@@ -3257,6 +2710,7 @@ type Divergence =
|
|
|
3257
2710
|
```ts
|
|
3258
2711
|
type EventActor =
|
|
3259
2712
|
| {
|
|
2713
|
+
journeyId?: string;
|
|
3260
2714
|
kind: "app";
|
|
3261
2715
|
}
|
|
3262
2716
|
| {
|
|
@@ -3342,7 +2796,7 @@ the rules disposition.
|
|
|
3342
2796
|
|
|
3343
2797
|
***
|
|
3344
2798
|
|
|
3345
|
-
<a id="sandboxerrorcode
|
|
2799
|
+
<a id="sandboxerrorcode"></a>
|
|
3346
2800
|
|
|
3347
2801
|
### SandboxErrorCode
|
|
3348
2802
|
|
|
@@ -3390,7 +2844,7 @@ type SandboxEvent =
|
|
|
3390
2844
|
```
|
|
3391
2845
|
|
|
3392
2846
|
Discriminated union of every event the sandbox emits to
|
|
3393
|
-
[Sandbox.onEvent](#onevent
|
|
2847
|
+
[Sandbox.onEvent](pyric-firestore-reference-api.md#onevent) subscribers.
|
|
3394
2848
|
|
|
3395
2849
|
Issue #307 — replaces the prior three-channel surface
|
|
3396
2850
|
(`onRequest` / `onDenial` / `onSnapshotError`). Filter on `kind`
|
|
@@ -3500,7 +2954,7 @@ We handle this in two parts:
|
|
|
3500
2954
|
|
|
3501
2955
|
| Parameter | Type |
|
|
3502
2956
|
| :------ | :------ |
|
|
3503
|
-
| `sandbox` | [`Sandbox`](#sandbox
|
|
2957
|
+
| `sandbox` | [`Sandbox`](pyric-firestore-reference-api.md#sandbox) |
|
|
3504
2958
|
| `rawOptions` | [`SandboxPersistenceOptions`](#sandboxpersistenceoptions) |
|
|
3505
2959
|
|
|
3506
2960
|
#### Returns
|
|
@@ -3715,7 +3169,7 @@ touch the source sandbox.
|
|
|
3715
3169
|
|
|
3716
3170
|
| Parameter | Type | Description |
|
|
3717
3171
|
| :------ | :------ | :------ |
|
|
3718
|
-
| `snapshot` | [`SandboxSnapshot`](#sandboxsnapshot
|
|
3172
|
+
| `snapshot` | [`SandboxSnapshot`](#sandboxsnapshot) | Baseline state — typically `liveSandbox.snapshot()`. |
|
|
3719
3173
|
| `rules?` | `string` | Rules source for the branch. Pass the live rules to reproduce production behaviour, or an *edited* ruleset to test a rules change in isolation (Studio F4). |
|
|
3720
3174
|
|
|
3721
3175
|
#### Returns
|
|
@@ -3735,7 +3189,7 @@ function initializeSandbox(_config?: SandboxConfig): LocalSandbox;
|
|
|
3735
3189
|
Create a sandbox.
|
|
3736
3190
|
|
|
3737
3191
|
Identity is **not** part of init — call `sandbox.withAuth(...)` to
|
|
3738
|
-
derive a [SandboxContext](#sandboxcontext) for service operations. Service-
|
|
3192
|
+
derive a [SandboxContext](pyric-firestore-reference-api.md#sandboxcontext) for service operations. Service-
|
|
3739
3193
|
specific configuration (rules, seed data) happens through service-specific
|
|
3740
3194
|
sandbox controls — for example, `setRules(sandbox, source)` from
|
|
3741
3195
|
`pyric/sandbox/firestore`.
|
|
@@ -3800,7 +3254,7 @@ than into process-local state.
|
|
|
3800
3254
|
|
|
3801
3255
|
| Parameter | Type |
|
|
3802
3256
|
| :------ | :------ |
|
|
3803
|
-
| `sandbox` | [`Sandbox`](#sandbox
|
|
3257
|
+
| `sandbox` | [`Sandbox`](pyric-firestore-reference-api.md#sandbox) |
|
|
3804
3258
|
|
|
3805
3259
|
#### Returns
|
|
3806
3260
|
|
|
@@ -3924,34 +3378,6 @@ cached, so a restore (list + per-record get) costs one read, not one per record.
|
|
|
3924
3378
|
|
|
3925
3379
|
***
|
|
3926
3380
|
|
|
3927
|
-
<a id="rehydratedocvalue"></a>
|
|
3928
|
-
|
|
3929
|
-
### rehydrateDocValue()
|
|
3930
|
-
|
|
3931
|
-
```ts
|
|
3932
|
-
function rehydrateDocValue(value: unknown): unknown;
|
|
3933
|
-
```
|
|
3934
|
-
|
|
3935
|
-
Walk a parsed JSON tree and re-wrap any marker shape back into its real
|
|
3936
|
-
wrapper-class instance. Visits arrays and plain objects recursively. Plain
|
|
3937
|
-
values (and plain objects without a recognized discriminator) pass through.
|
|
3938
|
-
|
|
3939
|
-
This is the canonical rehydrate used by BOTH the sandbox persistence
|
|
3940
|
-
serializer and the SharedWorker wire protocol, so the IDB format and the
|
|
3941
|
-
MessagePort wire format are guaranteed identical.
|
|
3942
|
-
|
|
3943
|
-
#### Parameters
|
|
3944
|
-
|
|
3945
|
-
| Parameter | Type |
|
|
3946
|
-
| :------ | :------ |
|
|
3947
|
-
| `value` | `unknown` |
|
|
3948
|
-
|
|
3949
|
-
#### Returns
|
|
3950
|
-
|
|
3951
|
-
`unknown`
|
|
3952
|
-
|
|
3953
|
-
***
|
|
3954
|
-
|
|
3955
3381
|
<a id="replay-1"></a>
|
|
3956
3382
|
|
|
3957
3383
|
### replay()
|
|
@@ -4058,3 +3484,43 @@ Project either traffic event family into the canonical record.
|
|
|
4058
3484
|
#### Returns
|
|
4059
3485
|
|
|
4060
3486
|
[`OperationRecord`](#operationrecord)
|
|
3487
|
+
|
|
3488
|
+
## References
|
|
3489
|
+
|
|
3490
|
+
<a id="authstate"></a>
|
|
3491
|
+
|
|
3492
|
+
### AuthState
|
|
3493
|
+
|
|
3494
|
+
Re-exports [AuthState](pyric-firestore-reference-api.md#authstate)
|
|
3495
|
+
|
|
3496
|
+
***
|
|
3497
|
+
|
|
3498
|
+
<a id="rehydratedocvalue"></a>
|
|
3499
|
+
|
|
3500
|
+
### rehydrateDocValue
|
|
3501
|
+
|
|
3502
|
+
Re-exports [rehydrateDocValue](pyric-firestore-values-reference-api.md#rehydratedocvalue)
|
|
3503
|
+
|
|
3504
|
+
***
|
|
3505
|
+
|
|
3506
|
+
<a id="sandbox-3"></a>
|
|
3507
|
+
|
|
3508
|
+
### Sandbox
|
|
3509
|
+
|
|
3510
|
+
Re-exports [Sandbox](pyric-firestore-reference-api.md#sandbox)
|
|
3511
|
+
|
|
3512
|
+
***
|
|
3513
|
+
|
|
3514
|
+
<a id="sandboxcontext"></a>
|
|
3515
|
+
|
|
3516
|
+
### SandboxContext
|
|
3517
|
+
|
|
3518
|
+
Re-exports [SandboxContext](pyric-firestore-reference-api.md#sandboxcontext)
|
|
3519
|
+
|
|
3520
|
+
***
|
|
3521
|
+
|
|
3522
|
+
<a id="sandboxerror"></a>
|
|
3523
|
+
|
|
3524
|
+
### SandboxError
|
|
3525
|
+
|
|
3526
|
+
Re-exports [SandboxError](pyric-firestore-reference-api.md#sandboxerror)
|