@pyric/cli 0.1.0-alpha.20 → 0.1.0-alpha.22
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 +64 -89
- package/dist/assurance/.generated/conformance-verdicts.d.ts +238 -1
- package/dist/assurance/.generated/conformance-verdicts.d.ts.map +1 -1
- package/dist/assurance/.generated/conformance-verdicts.js +238 -1
- package/dist/assurance/.generated/conformance-verdicts.js.map +1 -1
- package/dist/bridge/client/dispatch.d.ts +25 -19
- package/dist/bridge/client/dispatch.d.ts.map +1 -1
- package/dist/bridge/client/dispatch.js +41 -48
- package/dist/bridge/client/dispatch.js.map +1 -1
- package/dist/bridge/client/tool-family-factories.d.ts +26 -0
- package/dist/bridge/client/tool-family-factories.d.ts.map +1 -0
- package/dist/bridge/client/tool-family-factories.js +10 -0
- package/dist/bridge/client/tool-family-factories.js.map +1 -0
- package/dist/bridge/server/mcp-contract.d.ts +7 -6
- package/dist/bridge/server/mcp-contract.d.ts.map +1 -1
- package/dist/bridge/server/mcp-contract.js +9 -48
- package/dist/bridge/server/mcp-contract.js.map +1 -1
- package/dist/bridge/server/peer.d.ts +11 -1
- package/dist/bridge/server/peer.d.ts.map +1 -1
- package/dist/bridge/server/peer.js +22 -1
- package/dist/bridge/server/peer.js.map +1 -1
- package/dist/bridge/server/tool-family-factories.d.ts +30 -0
- package/dist/bridge/server/tool-family-factories.d.ts.map +1 -0
- package/dist/bridge/server/tool-family-factories.js +22 -0
- package/dist/bridge/server/tool-family-factories.js.map +1 -0
- package/dist/bridge/server/tool-metadata.d.ts +17 -18
- package/dist/bridge/server/tool-metadata.d.ts.map +1 -1
- package/dist/bridge/server/tool-metadata.js +24 -59
- package/dist/bridge/server/tool-metadata.js.map +1 -1
- package/dist/bridge/tool-families.d.ts +48 -0
- package/dist/bridge/tool-families.d.ts.map +1 -0
- package/dist/bridge/tool-families.generated.d.ts +32 -0
- package/dist/bridge/tool-families.generated.d.ts.map +1 -0
- package/dist/bridge/tool-families.generated.js +15 -0
- package/dist/bridge/tool-families.generated.js.map +1 -0
- package/dist/bridge/tool-families.js +51 -0
- package/dist/bridge/tool-families.js.map +1 -0
- package/dist/bridge/tool-family-records/conformance.d.ts +7 -0
- package/dist/bridge/tool-family-records/conformance.d.ts.map +1 -0
- package/dist/bridge/tool-family-records/conformance.js +6 -0
- package/dist/bridge/tool-family-records/conformance.js.map +1 -0
- package/dist/bridge/tool-family-records/firestore-data.d.ts +7 -0
- package/dist/bridge/tool-family-records/firestore-data.d.ts.map +1 -0
- package/dist/bridge/tool-family-records/firestore-data.js +15 -0
- package/dist/bridge/tool-family-records/firestore-data.js.map +1 -0
- package/dist/bridge/tool-family-records/firestore-inspect.d.ts +7 -0
- package/dist/bridge/tool-family-records/firestore-inspect.d.ts.map +1 -0
- package/dist/bridge/tool-family-records/firestore-inspect.js +6 -0
- package/dist/bridge/tool-family-records/firestore-inspect.js.map +1 -0
- package/dist/bridge/tool-family-records/firestore-rules.d.ts +7 -0
- package/dist/bridge/tool-family-records/firestore-rules.d.ts.map +1 -0
- package/dist/bridge/tool-family-records/firestore-rules.js +15 -0
- package/dist/bridge/tool-family-records/firestore-rules.js.map +1 -0
- package/dist/bridge/tool-family-records/firestore-simulator.d.ts +7 -0
- package/dist/bridge/tool-family-records/firestore-simulator.d.ts.map +1 -0
- package/dist/bridge/tool-family-records/firestore-simulator.js +16 -0
- package/dist/bridge/tool-family-records/firestore-simulator.js.map +1 -0
- package/dist/bridge/tool-family-records/rtdb-inspection.d.ts +7 -0
- package/dist/bridge/tool-family-records/rtdb-inspection.d.ts.map +1 -0
- package/dist/bridge/tool-family-records/rtdb-inspection.js +6 -0
- package/dist/bridge/tool-family-records/rtdb-inspection.js.map +1 -0
- package/dist/bundler/externals.d.ts +37 -0
- package/dist/bundler/externals.d.ts.map +1 -0
- package/dist/bundler/externals.js +52 -0
- package/dist/bundler/externals.js.map +1 -0
- package/dist/bundler/index.d.ts +17 -0
- package/dist/bundler/index.d.ts.map +1 -0
- package/dist/bundler/index.js +17 -0
- package/dist/bundler/index.js.map +1 -0
- package/dist/cli/inlined-sdk-scanner.d.ts +6 -0
- package/dist/cli/inlined-sdk-scanner.d.ts.map +1 -0
- package/dist/cli/inlined-sdk-scanner.js +82 -0
- package/dist/cli/inlined-sdk-scanner.js.map +1 -0
- package/dist/cli/sandbox-interlock.d.ts +97 -0
- package/dist/cli/sandbox-interlock.d.ts.map +1 -0
- package/dist/cli/sandbox-interlock.js +112 -0
- package/dist/cli/sandbox-interlock.js.map +1 -0
- package/dist/cli/sandbox-runner.d.ts +20 -12
- package/dist/cli/sandbox-runner.d.ts.map +1 -1
- package/dist/cli/sandbox-runner.js +24 -21
- package/dist/cli/sandbox-runner.js.map +1 -1
- package/dist/cli/serve.d.ts +6 -10
- package/dist/cli/serve.d.ts.map +1 -1
- package/dist/cli/serve.js +57 -77
- package/dist/cli/serve.js.map +1 -1
- package/dist/cli/unsupported-runtime.d.ts +27 -0
- package/dist/cli/unsupported-runtime.d.ts.map +1 -0
- package/dist/cli/unsupported-runtime.js +63 -0
- package/dist/cli/unsupported-runtime.js.map +1 -0
- package/dist/conformance/.generated/can-i-use-browser.d.ts +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 +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.map +1 -1
- package/dist/conformance/.generated/conformance-docs.js +1 -1
- package/dist/conformance/.generated/conformance-docs.js.map +1 -1
- package/dist/functions-rtdb/child.d.ts +37 -0
- package/dist/functions-rtdb/child.d.ts.map +1 -1
- package/dist/functions-rtdb/child.js +90 -21
- package/dist/functions-rtdb/child.js.map +1 -1
- package/dist/functions-rtdb/development-runtime.d.ts +3 -0
- package/dist/functions-rtdb/development-runtime.d.ts.map +1 -1
- package/dist/functions-rtdb/development-runtime.js +1 -0
- package/dist/functions-rtdb/development-runtime.js.map +1 -1
- package/dist/google-endpoints.d.ts +67 -0
- package/dist/google-endpoints.d.ts.map +1 -0
- package/dist/google-endpoints.js +119 -0
- package/dist/google-endpoints.js.map +1 -0
- package/dist/next/runtime-env.d.ts.map +1 -1
- package/dist/next/runtime-env.js +5 -0
- package/dist/next/runtime-env.js.map +1 -1
- package/dist/next/with-pyric.d.ts +1 -1
- package/dist/next/with-pyric.js +1 -1
- package/dist/register/beacon.d.ts +69 -0
- package/dist/register/beacon.d.ts.map +1 -0
- package/dist/register/beacon.js +199 -0
- package/dist/register/beacon.js.map +1 -0
- package/dist/register/index.d.ts.map +1 -1
- package/dist/register/index.js +65 -6
- package/dist/register/index.js.map +1 -1
- package/dist/register/net-guard.d.ts +110 -0
- package/dist/register/net-guard.d.ts.map +1 -0
- package/dist/register/net-guard.js +462 -0
- package/dist/register/net-guard.js.map +1 -0
- package/dist/serve/ai-diagnostics-relay.d.ts +63 -0
- package/dist/serve/ai-diagnostics-relay.d.ts.map +1 -0
- package/dist/serve/ai-diagnostics-relay.js +125 -0
- package/dist/serve/ai-diagnostics-relay.js.map +1 -0
- package/dist/serve/ai-proxy.d.ts +92 -0
- package/dist/serve/ai-proxy.d.ts.map +1 -0
- package/dist/serve/ai-proxy.js +269 -0
- package/dist/serve/ai-proxy.js.map +1 -0
- package/dist/serve/ai-status.d.ts +44 -0
- package/dist/serve/ai-status.d.ts.map +1 -0
- package/dist/serve/ai-status.js +77 -0
- package/dist/serve/ai-status.js.map +1 -0
- package/dist/serve/ai-terminal-blocks.d.ts +97 -0
- package/dist/serve/ai-terminal-blocks.d.ts.map +1 -0
- package/dist/serve/ai-terminal-blocks.js +128 -0
- package/dist/serve/ai-terminal-blocks.js.map +1 -0
- package/dist/serve/ai-terminal-text.d.ts +36 -0
- package/dist/serve/ai-terminal-text.d.ts.map +1 -0
- package/dist/serve/ai-terminal-text.js +48 -0
- package/dist/serve/ai-terminal-text.js.map +1 -0
- package/dist/serve/beacon-route.d.ts +53 -0
- package/dist/serve/beacon-route.d.ts.map +1 -0
- package/dist/serve/beacon-route.js +101 -0
- package/dist/serve/beacon-route.js.map +1 -0
- package/dist/serve/entries/active-auth-registry.d.ts +16 -0
- package/dist/serve/entries/active-auth-registry.d.ts.map +1 -0
- package/dist/serve/entries/active-auth-registry.js +48 -0
- package/dist/serve/entries/active-auth-registry.js.map +1 -0
- package/dist/serve/entries/active-auth.d.ts +18 -0
- package/dist/serve/entries/active-auth.d.ts.map +1 -0
- package/dist/serve/entries/active-auth.js +84 -0
- package/dist/serve/entries/active-auth.js.map +1 -0
- package/dist/serve/entries/auth-helper-core.d.ts +1 -0
- package/dist/serve/entries/auth-helper-core.d.ts.map +1 -1
- package/dist/serve/entries/auth-helper-core.js +4 -0
- package/dist/serve/entries/auth-helper-core.js.map +1 -1
- package/dist/serve/entries/auth-helper-dom.d.ts.map +1 -1
- package/dist/serve/entries/auth-helper-dom.js +28 -2
- package/dist/serve/entries/auth-helper-dom.js.map +1 -1
- package/dist/serve/entries/auth.d.ts.map +1 -1
- package/dist/serve/entries/auth.js +8 -0
- package/dist/serve/entries/auth.js.map +1 -1
- package/dist/serve/entries/bridge-url.d.ts +1 -1
- package/dist/serve/entries/bridge-url.js +1 -1
- package/dist/serve/entries/init.d.ts.map +1 -1
- package/dist/serve/entries/init.js +70 -4
- package/dist/serve/entries/init.js.map +1 -1
- package/dist/serve/entries/runtime.d.ts.map +1 -1
- package/dist/serve/entries/runtime.js +9 -0
- package/dist/serve/entries/runtime.js.map +1 -1
- package/dist/serve/namespace.d.ts +14 -5
- package/dist/serve/namespace.d.ts.map +1 -1
- package/dist/serve/namespace.js +57 -124
- package/dist/serve/namespace.js.map +1 -1
- package/dist/serve/runtime/chip-config.d.ts.map +1 -1
- package/dist/serve/runtime/chip-config.js +16 -2
- package/dist/serve/runtime/chip-config.js.map +1 -1
- package/dist/serve/runtime/chip-dialog.d.ts +18 -0
- package/dist/serve/runtime/chip-dialog.d.ts.map +1 -0
- package/dist/serve/runtime/chip-dialog.js +315 -0
- package/dist/serve/runtime/chip-dialog.js.map +1 -0
- package/dist/serve/runtime/chip-install.d.ts +2 -0
- package/dist/serve/runtime/chip-install.d.ts.map +1 -1
- package/dist/serve/runtime/chip-install.js +9 -4
- package/dist/serve/runtime/chip-install.js.map +1 -1
- package/dist/serve/runtime/chip-user-search.d.ts +16 -0
- package/dist/serve/runtime/chip-user-search.d.ts.map +1 -0
- package/dist/serve/runtime/chip-user-search.js +354 -0
- package/dist/serve/runtime/chip-user-search.js.map +1 -0
- package/dist/serve/runtime/chip.d.ts +10 -0
- package/dist/serve/runtime/chip.d.ts.map +1 -1
- package/dist/serve/runtime/chip.js +118 -15
- package/dist/serve/runtime/chip.js.map +1 -1
- package/dist/serve/runtime/identity.d.ts +17 -0
- package/dist/serve/runtime/identity.d.ts.map +1 -0
- package/dist/serve/runtime/identity.js +10 -0
- package/dist/serve/runtime/identity.js.map +1 -0
- package/dist/serve/sandbox-session.d.ts +7 -0
- package/dist/serve/sandbox-session.d.ts.map +1 -1
- package/dist/serve/sandbox-session.js +2 -0
- package/dist/serve/sandbox-session.js.map +1 -1
- package/dist/serve/site-ui/_astro/{RulesCodeEditor.XtDmHOlN.js → RulesCodeEditor.DsTAsKIa.js} +1 -1
- package/dist/serve/site-ui/_astro/app.CMmTxyhL.js +1 -0
- package/dist/serve/site-ui/_astro/app.DhALsVii.js +115 -0
- package/dist/serve/site-ui/_astro/{chess-showcase.B72XYeoh.js → chess-showcase.Bn_pP6UJ.js} +2 -2
- package/dist/serve/site-ui/_astro/{example-runtime.C25_lx6Z.js → example-runtime.CXopTGv7.js} +1 -1
- package/dist/serve/site-ui/_astro/sandbox-controls.rOuZTOUG.js +510 -0
- package/dist/serve/site-ui/_astro/{seed.Co0yUJY5.js → seed.lywYbXZ0.js} +2 -2
- package/dist/serve/site-ui/_astro/writes.BsPBG3dp.js +653 -0
- package/dist/serve/site-ui/auth/index.html +1 -1
- package/dist/serve/site-ui/docs/_rhythm/index.html +1 -1
- package/dist/serve/site-ui/docs/agent/set-up-your-agent/index.html +1 -1
- package/dist/serve/site-ui/docs/agent/watch-and-review/index.html +1 -1
- package/dist/serve/site-ui/docs/agent/work-with-an-agent/index.html +1 -1
- package/dist/serve/site-ui/docs/ai-compat/index.html +1 -1
- package/dist/serve/site-ui/docs/api-reference/index.html +8 -1
- package/dist/serve/site-ui/docs/api-reference.md +7 -0
- package/dist/serve/site-ui/docs/app-compat/index.html +1 -1
- package/dist/serve/site-ui/docs/auth-compat/index.html +3 -3
- package/dist/serve/site-ui/docs/auth-compat.md +2 -2
- package/dist/serve/site-ui/docs/build/ai-logic/index.html +6 -1
- package/dist/serve/site-ui/docs/build/ai-logic.md +6 -0
- package/dist/serve/site-ui/docs/build/authentication/index.html +2 -2
- package/dist/serve/site-ui/docs/build/authentication.md +1 -1
- package/dist/serve/site-ui/docs/build/cloud-firestore/index.html +4 -2
- package/dist/serve/site-ui/docs/build/cloud-firestore.md +4 -0
- package/dist/serve/site-ui/docs/build/cloud-messaging/index.html +1 -1
- package/dist/serve/site-ui/docs/build/cloud-storage/index.html +1 -1
- package/dist/serve/site-ui/docs/build/realtime-database/index.html +1 -1
- package/dist/serve/site-ui/docs/conformance-scores/index.html +14 -2
- package/dist/serve/site-ui/docs/conformance-scores.md +13 -1
- package/dist/serve/site-ui/docs/create-pyric-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/database-compat/index.html +44 -44
- package/dist/serve/site-ui/docs/database-compat.md +43 -43
- package/dist/serve/site-ui/docs/examples/chess/index.html +1 -1
- package/dist/serve/site-ui/docs/examples/index.html +1 -1
- package/dist/serve/site-ui/docs/firestore-compat/index.html +4 -4
- package/dist/serve/site-ui/docs/firestore-compat.md +3 -3
- package/dist/serve/site-ui/docs/firestore-flutter-compat/index.html +319 -0
- package/dist/serve/site-ui/docs/firestore-flutter-compat.md +344 -0
- package/dist/serve/site-ui/docs/firestore-kotlin-compat/index.html +319 -0
- package/dist/serve/site-ui/docs/firestore-kotlin-compat.md +344 -0
- package/dist/serve/site-ui/docs/firestore-swift-compat/index.html +490 -0
- package/dist/serve/site-ui/docs/firestore-swift-compat.md +517 -0
- package/dist/serve/site-ui/docs/functions-rtdb-compat/index.html +1 -1
- package/dist/serve/site-ui/docs/get-started/backend-bundlers/index.html +105 -0
- package/dist/serve/site-ui/docs/get-started/backend-bundlers.md +165 -0
- package/dist/serve/site-ui/docs/get-started/flutter/index.html +98 -0
- package/dist/serve/site-ui/docs/get-started/flutter.md +105 -0
- package/dist/serve/site-ui/docs/get-started/how-the-swap-works/index.html +1 -1
- package/dist/serve/site-ui/docs/get-started/nextjs/index.html +1 -1
- package/dist/serve/site-ui/docs/get-started/start-building/index.html +1 -1
- package/dist/serve/site-ui/docs/get-started/vite/index.html +1 -1
- package/dist/serve/site-ui/docs/index.json +3211 -1471
- package/dist/serve/site-ui/docs/messaging-compat/index.html +1 -1
- package/dist/serve/site-ui/docs/observe/resolve-runtime-status/index.html +4 -3
- package/dist/serve/site-ui/docs/observe/resolve-runtime-status.md +3 -1
- package/dist/serve/site-ui/docs/observe/see-whats-happening/index.html +1 -1
- package/dist/serve/site-ui/docs/observe/shape-your-data/index.html +1 -1
- package/dist/serve/site-ui/docs/observe/switch-and-impersonate-identities/index.html +110 -0
- package/dist/serve/site-ui/docs/observe/switch-and-impersonate-identities.md +134 -0
- package/dist/serve/site-ui/docs/overview/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-admin-app-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-admin-auth-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-admin-database-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-admin-firestore-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-admin-messaging-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-admin-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-admin-storage-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-ai-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-ai-scripting-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-analytics-reference-api/index.html +124 -0
- package/dist/serve/site-ui/docs/pyric-analytics-reference-api.md +287 -0
- package/dist/serve/site-ui/docs/pyric-app-check-reference-api/index.html +87 -0
- package/dist/serve/site-ui/docs/pyric-app-check-reference-api.md +199 -0
- package/dist/serve/site-ui/docs/pyric-app-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-auth-reference-api/index.html +6 -2
- package/dist/serve/site-ui/docs/pyric-auth-reference-api.md +2 -1
- package/dist/serve/site-ui/docs/pyric-cli-assurance-browser-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-cli-assurance-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-cli-bridge-client-reference-api/index.html +2 -2
- package/dist/serve/site-ui/docs/pyric-cli-bridge-client-reference-api.md +1 -1
- package/dist/serve/site-ui/docs/pyric-cli-bridge-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-cli-bundler-reference-api/index.html +56 -0
- package/dist/serve/site-ui/docs/pyric-cli-bundler-reference-api.md +72 -0
- package/dist/serve/site-ui/docs/pyric-cli-conformance-browser-reference-api/index.html +4 -1
- package/dist/serve/site-ui/docs/pyric-cli-conformance-browser-reference-api.md +3 -0
- package/dist/serve/site-ui/docs/pyric-cli-conformance-docs-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-cli-conformance-reference-api/index.html +4 -1
- package/dist/serve/site-ui/docs/pyric-cli-conformance-reference-api.md +3 -0
- package/dist/serve/site-ui/docs/pyric-cli-credentials-node-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-cli-discover-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-cli-next-reference-api/index.html +2 -2
- package/dist/serve/site-ui/docs/pyric-cli-next-reference-api.md +1 -1
- package/dist/serve/site-ui/docs/pyric-cli-register-app-bridge-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-cli-register-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-cli-remote-reference-api/index.html +34 -9
- package/dist/serve/site-ui/docs/pyric-cli-remote-reference-api.md +16 -8
- package/dist/serve/site-ui/docs/pyric-cli-serve-worker-reference-api/index.html +133 -93
- package/dist/serve/site-ui/docs/pyric-cli-serve-worker-reference-api.md +61 -1
- package/dist/serve/site-ui/docs/pyric-cli-verify-reference-api/index.html +2 -2
- package/dist/serve/site-ui/docs/pyric-cli-verify-reference-api.md +1 -1
- package/dist/serve/site-ui/docs/pyric-cli-vite-reference-api/index.html +2 -2
- package/dist/serve/site-ui/docs/pyric-cli-vite-reference-api.md +2 -2
- package/dist/serve/site-ui/docs/pyric-database-reference-api/index.html +2 -2
- package/dist/serve/site-ui/docs/pyric-database-reference-api.md +1 -1
- package/dist/serve/site-ui/docs/pyric-firestore-lite-reference-api/index.html +559 -0
- package/dist/serve/site-ui/docs/pyric-firestore-lite-reference-api.md +1240 -0
- package/dist/serve/site-ui/docs/pyric-firestore-reference-api/index.html +40 -11
- package/dist/serve/site-ui/docs/pyric-firestore-reference-api.md +18 -8
- package/dist/serve/site-ui/docs/pyric-functions-reference-api/index.html +67 -0
- package/dist/serve/site-ui/docs/pyric-functions-reference-api.md +149 -0
- package/dist/serve/site-ui/docs/pyric-messaging-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-messaging-sw-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-performance-reference-api/index.html +35 -0
- package/dist/serve/site-ui/docs/pyric-performance-reference-api.md +69 -0
- package/dist/serve/site-ui/docs/pyric-remote-config-reference-api/index.html +132 -0
- package/dist/serve/site-ui/docs/pyric-remote-config-reference-api.md +307 -0
- package/dist/serve/site-ui/docs/pyric-rules-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-sandbox-database-reference-api/index.html +52 -17
- package/dist/serve/site-ui/docs/pyric-sandbox-database-reference-api.md +48 -9
- package/dist/serve/site-ui/docs/pyric-sandbox-firestore-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-sandbox-reference-api/index.html +239 -49
- package/dist/serve/site-ui/docs/pyric-sandbox-reference-api.md +148 -31
- package/dist/serve/site-ui/docs/pyric-storage-reference-api/index.html +22 -4
- package/dist/serve/site-ui/docs/pyric-storage-reference-api.md +25 -3
- package/dist/serve/site-ui/docs/pyric-ui-agents-reference-api/index.html +26 -96
- package/dist/serve/site-ui/docs/pyric-ui-agents-reference-api.md +20 -51
- package/dist/serve/site-ui/docs/pyric-ui-auth-hooks-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-ui-auth-reference-api/index.html +2 -2
- package/dist/serve/site-ui/docs/pyric-ui-auth-reference-api.md +1 -1
- package/dist/serve/site-ui/docs/pyric-ui-events-hooks-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-ui-events-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-ui-firestore-hooks-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-ui-firestore-reference-api/index.html +2 -2
- package/dist/serve/site-ui/docs/pyric-ui-firestore-reference-api.md +1 -1
- package/dist/serve/site-ui/docs/pyric-ui-primitives-reference-api/index.html +124 -26
- package/dist/serve/site-ui/docs/pyric-ui-primitives-reference-api.md +58 -5
- package/dist/serve/site-ui/docs/pyric-ui-rtdb-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-ui-rules-hooks-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-ui-rules-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-ui-storage-hooks-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-ui-storage-reference-api/index.html +4 -5
- package/dist/serve/site-ui/docs/pyric-ui-storage-reference-api.md +3 -4
- package/dist/serve/site-ui/docs/pyric-ui-traffic-hooks-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-ui-traffic-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/reference/cli/index.html +6 -3
- package/dist/serve/site-ui/docs/reference/cli.md +8 -2
- package/dist/serve/site-ui/docs/rules-compat/index.html +10 -2
- package/dist/serve/site-ui/docs/rules-compat.md +9 -1
- package/dist/serve/site-ui/docs/secure/audit-your-rules/index.html +1 -1
- package/dist/serve/site-ui/docs/secure/firestore-rules-limits/index.html +1 -1
- package/dist/serve/site-ui/docs/secure/read-a-denial/index.html +1 -1
- package/dist/serve/site-ui/docs/secure/rtdb-rules-in-typescript/index.html +1 -1
- package/dist/serve/site-ui/docs/secure/rules-standard-library/index.html +1 -1
- package/dist/serve/site-ui/docs/secure/secure-it-with-rules/index.html +1 -1
- package/dist/serve/site-ui/docs/secure/simulate-and-lint/index.html +1 -1
- package/dist/serve/site-ui/docs/secure/write-a-rules-test-suite/index.html +1 -1
- package/dist/serve/site-ui/docs/ship/ship-to-production/index.html +1 -1
- package/dist/serve/site-ui/docs/ship/test-in-node/index.html +1 -1
- package/dist/serve/site-ui/docs/storage-compat/index.html +13 -13
- package/dist/serve/site-ui/docs/storage-compat.md +12 -12
- package/dist/serve/site-ui/docs/trust/how-we-know-it-matches-firebase/index.html +1 -1
- package/dist/serve/site-ui/docs/trust/rules-standard-library/index.html +1 -1
- package/dist/serve/site-ui/docs/trust/versioning-and-compatibility/index.html +1 -1
- package/dist/serve/site-ui/docs/tutorial/index.html +1 -1
- package/dist/serve/site-ui/examples/chess/index.html +1 -1
- package/dist/serve/site-ui/firestore/index.html +1 -1
- package/dist/serve/site-ui/llms.txt +13 -0
- package/dist/serve/site-ui/rtdb/index.html +1 -1
- package/dist/serve/site-ui/settings/index.html +1 -1
- package/dist/serve/site-ui/storage/index.html +1 -1
- package/dist/serve/site-ui/studio/index.html +1 -1
- package/dist/serve/site-ui/traffic/index.html +1 -1
- package/dist/serve/studio/disk-workspace.d.ts.map +1 -1
- package/dist/serve/studio/disk-workspace.js +64 -2
- package/dist/serve/studio/disk-workspace.js.map +1 -1
- package/dist/serve/vite-plugin.d.ts +7 -7
- package/dist/serve/vite-plugin.js +1 -1
- package/dist/serve/vite-plugin.js.map +1 -1
- package/dist/serve/vite-sandbox-generation.d.ts.map +1 -1
- package/dist/serve/vite-sandbox-generation.js +12 -0
- package/dist/serve/vite-sandbox-generation.js.map +1 -1
- package/dist/serve/worker/client/auth.js +1 -2
- package/dist/serve/worker/client/auth.js.map +1 -1
- package/dist/serve/worker/client/core.d.ts +21 -1
- package/dist/serve/worker/client/core.d.ts.map +1 -1
- package/dist/serve/worker/client/core.js +79 -3
- package/dist/serve/worker/client/core.js.map +1 -1
- package/dist/serve/worker/client.d.ts +1 -1
- package/dist/serve/worker/client.d.ts.map +1 -1
- package/dist/serve/worker/client.js +1 -1
- package/dist/serve/worker/client.js.map +1 -1
- package/dist/serve/worker/context-resolver.d.ts +30 -0
- package/dist/serve/worker/context-resolver.d.ts.map +1 -0
- package/dist/serve/worker/context-resolver.js +44 -0
- package/dist/serve/worker/context-resolver.js.map +1 -0
- package/dist/serve/worker/entry.js +23 -19
- package/dist/serve/worker/entry.js.map +1 -1
- package/dist/serve/worker/host/core.d.ts +1 -0
- package/dist/serve/worker/host/core.d.ts.map +1 -1
- package/dist/serve/worker/host/core.js +12 -6
- package/dist/serve/worker/host/core.js.map +1 -1
- package/dist/serve/worker/host/storage.js +2 -2
- package/dist/serve/worker/host-auth.js +1 -2
- package/dist/serve/worker/host-auth.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 -2
- package/dist/serve/worker/index.js.map +1 -1
- package/dist/serve/worker/port-lifecycle.d.ts +18 -0
- package/dist/serve/worker/port-lifecycle.d.ts.map +1 -0
- package/dist/serve/worker/port-lifecycle.js +28 -0
- package/dist/serve/worker/port-lifecycle.js.map +1 -0
- package/dist/serve/worker/serve-init.d.ts.map +1 -1
- package/dist/serve/worker/serve-init.js +8 -2
- package/dist/serve/worker/serve-init.js.map +1 -1
- package/dist/verify/fixture.d.ts +1 -1
- package/package.json +16 -5
- package/src/assurance/.generated/conformance-verdicts.ts +238 -1
- package/src/bridge/client/dispatch.ts +52 -56
- package/src/bridge/client/tool-family-factories.ts +34 -0
- package/src/bridge/server/mcp-contract.ts +15 -59
- package/src/bridge/server/peer.ts +24 -1
- package/src/bridge/server/tool-family-factories.ts +40 -0
- package/src/bridge/server/tool-metadata.ts +29 -61
- package/src/bridge/tool-families.generated.ts +17 -0
- package/src/bridge/tool-families.ts +87 -0
- package/src/bridge/tool-family-records/conformance.ts +6 -0
- package/src/bridge/tool-family-records/firestore-data.ts +15 -0
- package/src/bridge/tool-family-records/firestore-inspect.ts +6 -0
- package/src/bridge/tool-family-records/firestore-rules.ts +15 -0
- package/src/bridge/tool-family-records/firestore-simulator.ts +16 -0
- package/src/bridge/tool-family-records/rtdb-inspection.ts +6 -0
- package/src/bundler/externals.ts +55 -0
- package/src/bundler/index.ts +21 -0
- package/src/cli/cli.test.ts +0 -44
- package/src/cli/inlined-sdk-scanner.ts +77 -0
- package/src/cli/sandbox-interlock.ts +167 -0
- package/src/cli/sandbox-runner.ts +37 -26
- package/src/cli/serve.ts +68 -69
- package/src/cli/unsupported-runtime.ts +68 -0
- package/src/conformance/.generated/can-i-use-browser.ts +2 -2
- package/src/conformance/.generated/can-i-use.ts +2 -2
- package/src/conformance/.generated/conformance-docs.ts +1 -1
- package/src/functions-rtdb/child.ts +115 -21
- package/src/functions-rtdb/development-runtime.ts +4 -0
- package/src/google-endpoints.ts +155 -0
- package/src/next/runtime-env.ts +5 -0
- package/src/next/with-pyric.ts +1 -1
- package/src/register/beacon.ts +232 -0
- package/src/register/index.ts +68 -6
- package/src/register/net-guard.ts +567 -0
- package/src/serve/ai-diagnostics-relay.ts +243 -0
- package/src/serve/ai-proxy.ts +327 -0
- package/src/serve/ai-status.ts +109 -0
- package/src/serve/ai-terminal-blocks.ts +210 -0
- package/src/serve/ai-terminal-text.ts +52 -0
- package/src/serve/beacon-route.ts +141 -0
- package/src/serve/entries/active-auth-registry.ts +56 -0
- package/src/serve/entries/active-auth.ts +100 -0
- package/src/serve/entries/auth-helper-core.ts +5 -0
- package/src/serve/entries/auth-helper-dom.ts +26 -2
- package/src/serve/entries/auth.ts +8 -0
- package/src/serve/entries/bridge-url.ts +1 -1
- package/src/serve/entries/init.ts +78 -3
- package/src/serve/entries/runtime.ts +10 -0
- package/src/serve/namespace.ts +73 -140
- package/src/serve/runtime/chip-config.ts +16 -2
- package/src/serve/runtime/chip-dialog.ts +366 -0
- package/src/serve/runtime/chip-install.ts +10 -4
- package/src/serve/runtime/chip-user-search.ts +391 -0
- package/src/serve/runtime/chip.ts +140 -15
- package/src/serve/runtime/identity.ts +26 -0
- package/src/serve/sandbox-session.ts +9 -0
- package/src/serve/studio/disk-workspace.ts +76 -2
- package/src/serve/vite-plugin.ts +8 -8
- package/src/serve/vite-sandbox-generation.ts +15 -0
- package/src/serve/worker/client/auth.ts +1 -1
- package/src/serve/worker/client/core.ts +80 -3
- package/src/serve/worker/client.ts +1 -1
- package/src/serve/worker/context-resolver.ts +60 -0
- package/src/serve/worker/entry.ts +22 -18
- package/src/serve/worker/host/core.ts +9 -7
- package/src/serve/worker/host/storage.ts +2 -2
- package/src/serve/worker/host-auth.ts +1 -1
- package/src/serve/worker/index.ts +4 -1
- package/src/serve/worker/port-lifecycle.ts +45 -0
- package/src/serve/worker/serve-init.ts +9 -2
- package/src/verify/fixture.ts +1 -1
- package/dist/serve/site-ui/_astro/app.B52xr-DK.js +0 -1
- package/dist/serve/site-ui/_astro/app.DWBraPUw.js +0 -12
- package/dist/serve/site-ui/_astro/sandbox-controls.DEpnKg-O.js +0 -1169
- package/dist/serve/site-ui/_astro/writes.rpjrFzmu.js +0 -102
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
|
|
2
|
+
# Backend bundlers & Node dev tools
|
|
3
|
+
|
|
4
|
+
When you run `pyric sandbox [command...]`, Pyric injects `NODE_OPTIONS="--import @pyric/cli/register"` into your development process. This Node.js runtime loader intercepts calls to `firebase-admin` and `firebase`, transparently routing them into your local sandbox.
|
|
5
|
+
|
|
6
|
+
If your backend uses a bundler (such as Rolldown, esbuild, or tsup) during development, dependencies are compiled inline by default. When `firebase-admin` is bundled inline into an output file (such as `dist/server.js`), Node never resolves the package at runtime, and sandbox interception is bypassed.
|
|
7
|
+
|
|
8
|
+
This guide shows you how to configure your bundler to keep Firebase packages external so that `pyric sandbox` intercepts your backend services.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 1. Import the externalisation presets
|
|
13
|
+
|
|
14
|
+
Install `@pyric/cli` as a development dependency if you have not already:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install -D @pyric/cli
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Import `pyricExternals` from `@pyric/cli/bundler`:
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
import { pyricExternals } from '@pyric/cli/bundler';
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## 2. Configure your bundler
|
|
29
|
+
|
|
30
|
+
Add the appropriate preset to your bundler's `external` configuration.
|
|
31
|
+
|
|
32
|
+
### If you use Rolldown (`rolldown.config.ts`)
|
|
33
|
+
|
|
34
|
+
Rolldown accepts regular expression patterns. Use the `rolldown` preset:
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
import { defineConfig } from 'rolldown';
|
|
38
|
+
import { pyricExternals } from '@pyric/cli/bundler';
|
|
39
|
+
|
|
40
|
+
export default defineConfig({
|
|
41
|
+
input: 'src/server.ts',
|
|
42
|
+
output: {
|
|
43
|
+
dir: 'dist',
|
|
44
|
+
format: 'esm',
|
|
45
|
+
},
|
|
46
|
+
external: pyricExternals.rolldown,
|
|
47
|
+
});
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### If you use esbuild (`esbuild.config.mjs`)
|
|
51
|
+
|
|
52
|
+
esbuild requires string arrays with wildcard patterns (`*`). Use the `esbuild` preset:
|
|
53
|
+
|
|
54
|
+
```js
|
|
55
|
+
import esbuild from 'esbuild';
|
|
56
|
+
import { pyricExternals } from '@pyric/cli/bundler';
|
|
57
|
+
|
|
58
|
+
await esbuild.build({
|
|
59
|
+
entryPoints: ['src/server.ts'],
|
|
60
|
+
bundle: true,
|
|
61
|
+
platform: 'node',
|
|
62
|
+
format: 'esm',
|
|
63
|
+
outfile: 'dist/server.js',
|
|
64
|
+
external: pyricExternals.esbuild,
|
|
65
|
+
});
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### If you use tsup (`tsup.config.ts`)
|
|
69
|
+
|
|
70
|
+
tsup uses esbuild under the hood. Use the `tsup` preset:
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
import { defineConfig } from 'tsup';
|
|
74
|
+
import { pyricExternals } from '@pyric/cli/bundler';
|
|
75
|
+
|
|
76
|
+
export default defineConfig({
|
|
77
|
+
entry: ['src/server.ts'],
|
|
78
|
+
format: ['esm'],
|
|
79
|
+
external: pyricExternals.tsup,
|
|
80
|
+
});
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### If you use Vite for Node backend builds (`vite.config.ts`)
|
|
84
|
+
|
|
85
|
+
In Vite, external dependencies for SSR / Node backend builds are configured under `build.rollupOptions.external`:
|
|
86
|
+
|
|
87
|
+
```ts
|
|
88
|
+
import { defineConfig } from 'vite';
|
|
89
|
+
import { pyricExternals } from '@pyric/cli/bundler';
|
|
90
|
+
|
|
91
|
+
export default defineConfig({
|
|
92
|
+
build: {
|
|
93
|
+
rollupOptions: {
|
|
94
|
+
external: pyricExternals.vite,
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
> [!NOTE]
|
|
101
|
+
> For standard frontend Vite applications, use the dedicated [`@pyric/cli/vite`](/docs/get-started/vite) plugin instead, which handles dev-server interception automatically.
|
|
102
|
+
|
|
103
|
+
### If you use Webpack (`webpack.config.js`)
|
|
104
|
+
|
|
105
|
+
Webpack accepts regular expression arrays under `externals`:
|
|
106
|
+
|
|
107
|
+
```js
|
|
108
|
+
import { pyricExternals } from '@pyric/cli/bundler';
|
|
109
|
+
|
|
110
|
+
export default {
|
|
111
|
+
target: 'node',
|
|
112
|
+
externals: pyricExternals.webpack,
|
|
113
|
+
};
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### If you use a custom predicate
|
|
117
|
+
|
|
118
|
+
For bundlers that support function-based external resolution (such as Rollup or Rolldown), use `isPyricExternal`:
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
import { isPyricExternal } from '@pyric/cli/bundler';
|
|
122
|
+
|
|
123
|
+
export default {
|
|
124
|
+
external: (id) => isPyricExternal(id),
|
|
125
|
+
};
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## 3. Run your development server under `pyric sandbox`
|
|
131
|
+
|
|
132
|
+
Add your bundler watch script and server runner to `package.json`:
|
|
133
|
+
|
|
134
|
+
```json
|
|
135
|
+
{
|
|
136
|
+
"scripts": {
|
|
137
|
+
"dev": "rolldown -c -w & node --watch dist/server.js",
|
|
138
|
+
"build": "rolldown -c"
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Launch your application with `pyric sandbox`:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
npx pyric sandbox
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
`pyric sandbox` starts the local sandbox, opens Pyric Studio, and executes your `dev` script. Because `firebase-admin` is externalised, your server's database, auth, and messaging operations route directly to the Pyric sandbox without requiring Google Cloud credentials or network access.
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## 4. Unbundled workflows (no bundler needed)
|
|
154
|
+
|
|
155
|
+
If your development workflow does not bundle dependencies into an intermediate file—for example, if you run TypeScript files directly with `tsx` or native Node:
|
|
156
|
+
|
|
157
|
+
```json
|
|
158
|
+
{
|
|
159
|
+
"scripts": {
|
|
160
|
+
"dev": "tsx watch src/server.ts"
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
No bundler configuration is required. `pyric sandbox` intercepts your `firebase-admin` imports automatically out of the box.
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
<!DOCTYPE html><html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover"><title>Flutter development setup · Pyric Studio</title><meta name="description" content="Route cloud_firestore calls from Flutter apps to a local Pyric sandbox bridge during development."><link rel="icon" type="image/svg+xml" href="/__pyric/ui/pyric-logo.svg"><link rel="preconnect" href="https://use.typekit.net" crossorigin><link rel="stylesheet" href="https://use.typekit.net/jwb3ycu.css"><link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet"><link rel="stylesheet" href="/__pyric/ui/_astro/index.UkCBr-_0.css">
|
|
2
|
+
<link rel="stylesheet" href="/__pyric/ui/_astro/_slug_.Da5VLhW1.css">
|
|
3
|
+
<style>:root{--rhythm-para: .875rem;--rhythm-group: 1.5rem;--rhythm-subsection: 2.25rem;--rhythm-section: 3.25rem;--rhythm-list: calc(var(--rhythm-para) * .75)}.prose>*,.prose blockquote>*,.prose li>*,.prose .compat-stat>*{margin-block:0}.prose>*+*{margin-block-start:var(--rhythm-group)}.prose>*+h2{margin-block-start:var(--rhythm-section)}.prose>*+h3,.prose>*+h4{margin-block-start:var(--rhythm-subsection)}.prose>h1+*,.prose>h2+*,.prose>h3+*,.prose>h4+*{margin-block-start:var(--rhythm-para)}.prose>p+p{margin-block-start:var(--rhythm-para)}.prose>p+ul,.prose>p+ol,.prose>p+blockquote{margin-block-start:var(--rhythm-para)}.prose li+li{margin-block-start:var(--rhythm-list)}.prose li>ul,.prose li>ol{margin-block-start:var(--rhythm-list)}.prose li>*+*,.prose blockquote>*+*{margin-block-start:var(--rhythm-para)}
|
|
4
|
+
html{scrollbar-gutter:stable}
|
|
5
|
+
</style></head> <body> <header class="studio__chrome"> <div class="studio__bar"> <div class="studio__chrome-inner"> <nav class="studio__nav" aria-label="Site"> <a class="studio__brand" href="/__pyric/ui/" aria-label="Pyric">pyric</a> <a class="studio__nav-tab" href="/__pyric/ui/"> Home </a><a class="studio__nav-tab" href="/__pyric/ui/docs" aria-current="page"> Docs </a><a class="studio__nav-tab" href="/__pyric/ui/studio"> Studio </a> </nav> </div> </div> </header> <div class="docs-shell" data-astro-cid-mw7aashj> <details class="docs-nav-drawer" data-astro-cid-mw7aashj> <summary data-astro-cid-mw7aashj>Navigate</summary> <nav class="docs-nav" aria-label="Documentation"> <div class="docs-search" data-index-url="/__pyric/ui/docs/index.json"> <div class="docs-search-field"> <svg class="docs-search-icon" viewBox="0 0 16 16" width="14" height="14" aria-hidden="true"> <path d="M11.5 11.5 15 15M13 7A6 6 0 1 1 1 7a6 6 0 0 1 12 0Z" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"></path> </svg> <input type="text" class="docs-search-input" placeholder="Search docs" aria-label="Search docs" autocomplete="off" spellcheck="false"> <kbd class="docs-search-kbd">⌘K</kbd> </div> <ul class="docs-search-results" hidden></ul> </div> <script type="module">let i=null;function d(t){return i||(i=fetch(t).then(e=>e.json())),i}function l(t,e){return t.title.toLowerCase().includes(e)||t.excerpt.toLowerCase().includes(e)?!0:t.headings.some(r=>r.text.toLowerCase().includes(e))}function u(t,e,r){if(e.innerHTML="",t.length===0){e.hidden=!1;{const n=document.createElement("li");n.className="docs-search-empty",n.textContent="No matches",e.appendChild(n)}return}e.hidden=!1;for(const n of t.slice(0,8)){const s=document.createElement("li"),c=document.createElement("a");c.href=n.path;const o=document.createElement("span");o.className="docs-search-result-title",o.textContent=n.title;const a=document.createElement("span");a.className="docs-search-result-meta",a.textContent=[n.group,n.section].filter(Boolean).join(" / "),c.append(o,a),s.appendChild(c),e.appendChild(s)}}document.querySelectorAll(".docs-search").forEach(t=>{const e=t.dataset.indexUrl,r=t.querySelector(".docs-search-input"),n=t.querySelector(".docs-search-results");r.addEventListener("input",async()=>{const s=r.value.trim().toLowerCase();if(!s){n.hidden=!0,n.innerHTML="";return}const{pages:c}=await d(e);r.value.trim().toLowerCase()===s&&u(c.filter(o=>l(o,s)),n)}),r.addEventListener("focus",()=>{d(e),n.childElementCount>0&&(n.hidden=!1)}),r.addEventListener("keydown",s=>{s.key==="Escape"&&(r.value="",n.hidden=!0,n.innerHTML="",r.blur())}),r.addEventListener("blur",()=>{window.setTimeout(()=>{n.hidden=!0},150)})});document.addEventListener("keydown",t=>{if(!(t.metaKey||t.ctrlKey)||t.key.toLowerCase()!=="k")return;const e=[...document.querySelectorAll(".docs-search-input")].find(r=>r.offsetParent!==null);e&&(t.preventDefault(),e.focus(),e.select())});</script> <details class="docs-nav-group"> <summary>Overview</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/overview/"> Overview </a> </li><li> <a href="/__pyric/ui/docs/tutorial/"> Tutorial </a> </li><li> <a href="/__pyric/ui/docs/examples/"> Examples </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" open> <summary>Get started</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/get-started/start-building/"> Quickstart </a> </li><li> <a href="/__pyric/ui/docs/get-started/vite/"> Vite </a> </li><li> <a href="/__pyric/ui/docs/get-started/nextjs/"> Next.js </a> </li><li> <a href="/__pyric/ui/docs/get-started/backend-bundlers/"> Backend bundlers </a> </li><li> <a href="/__pyric/ui/docs/get-started/flutter/" aria-current="page"> Flutter </a> </li><li> <a href="/__pyric/ui/docs/get-started/how-the-swap-works/"> How the swap works </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Build</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/build/authentication/"> Authentication </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-firestore/"> Cloud Firestore </a> </li><li> <a href="/__pyric/ui/docs/build/realtime-database/"> Realtime Database </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-storage/"> Cloud Storage </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-messaging/"> Cloud Messaging </a> </li><li> <a href="/__pyric/ui/docs/build/ai-logic/"> AI Logic </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Secure & debug</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/secure/secure-it-with-rules/"> Security Rules </a> </li><li> <a href="/__pyric/ui/docs/secure/simulate-and-lint/"> Simulate and lint before you deploy </a> </li><li> <a href="/__pyric/ui/docs/secure/write-a-rules-test-suite/"> Write a rules test suite </a> </li><li> <a href="/__pyric/ui/docs/secure/read-a-denial/"> Read a denial and understand it </a> </li><li> <a href="/__pyric/ui/docs/secure/rules-standard-library/"> The rules standard library </a> </li><li> <a href="/__pyric/ui/docs/secure/rtdb-rules-in-typescript/"> RTDB rules in TypeScript </a> </li><li> <a href="/__pyric/ui/docs/secure/firestore-rules-limits/"> Rules limits </a> </li><li> <a href="/__pyric/ui/docs/secure/audit-your-rules/"> Audit rules and data </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading"> Examples </h2> <ul> <li> <a href="/__pyric/ui/docs/examples/chess/"> Chess showcase </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Observe & shape</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/observe/see-whats-happening/"> Traffic & rule verdicts </a> </li><li> <a href="/__pyric/ui/docs/observe/resolve-runtime-status/"> Runtime status </a> </li><li> <a href="/__pyric/ui/docs/observe/switch-and-impersonate-identities/"> Impersonate & tenants </a> </li><li> <a href="/__pyric/ui/docs/observe/shape-your-data/"> Seed, snapshot, replay </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Ship & test</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/ship/ship-to-production/"> Ship to production </a> </li><li> <a href="/__pyric/ui/docs/ship/test-in-node/"> Test in Node </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Work with an agent</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/agent/set-up-your-agent/"> Connect an agent </a> </li><li> <a href="/__pyric/ui/docs/agent/work-with-an-agent/"> Use the MCP tools </a> </li><li> <a href="/__pyric/ui/docs/agent/watch-and-review/"> Watch in Pyric Studio </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Trust</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/trust/versioning-and-compatibility/"> Versioning and the fb tag </a> </li><li> <a href="/__pyric/ui/docs/trust/rules-standard-library/"> Rules standard library reference </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Conformance</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/conformance-scores/"> Conformance scores </a> </li><li> <a href="/__pyric/ui/docs/trust/how-we-know-it-matches-firebase/"> How we know it matches Firebase </a> </li><li> <a href="/__pyric/ui/docs/app-compat/"> App </a> </li><li> <a href="/__pyric/ui/docs/ai-compat/"> AI Logic </a> </li><li> <a href="/__pyric/ui/docs/auth-compat/"> Auth </a> </li><li> <a href="/__pyric/ui/docs/firestore-compat/"> Firestore </a> </li><li> <a href="/__pyric/ui/docs/database-compat/"> Realtime Database </a> </li><li> <a href="/__pyric/ui/docs/storage-compat/"> Storage </a> </li><li> <a href="/__pyric/ui/docs/messaging-compat/"> Messaging </a> </li><li> <a href="/__pyric/ui/docs/functions-rtdb-compat/"> Functions · RTDB </a> </li><li> <a href="/__pyric/ui/docs/rules-compat/"> Rules </a> </li><li> <a href="/__pyric/ui/docs/firestore-flutter-compat/"> Firestore · Flutter </a> </li><li> <a href="/__pyric/ui/docs/firestore-kotlin-compat/"> Firestore · Kotlin </a> </li><li> <a href="/__pyric/ui/docs/firestore-swift-compat/"> Firestore · Swift </a> </li> </ul> </div> </div> </details> <details class="docs-nav-group"> <summary>Reference</summary> <div class="docs-nav-group-body docs-nav-group-body--reference"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/api-reference/"> API reference </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">pyric</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-app-reference-api/"> pyric/app </a> </li><li> <a href="/__pyric/ui/docs/pyric-firestore-reference-api/"> pyric/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-firestore-lite-reference-api/"> pyric/firestore/lite </a> </li><li> <a href="/__pyric/ui/docs/pyric-auth-reference-api/"> pyric/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-ai-reference-api/"> pyric/ai </a> </li><li> <a href="/__pyric/ui/docs/pyric-ai-scripting-reference-api/"> pyric/ai/scripting </a> </li><li> <a href="/__pyric/ui/docs/pyric-database-reference-api/"> pyric/database </a> </li><li> <a href="/__pyric/ui/docs/pyric-storage-reference-api/"> pyric/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-messaging-reference-api/"> pyric/messaging </a> </li><li> <a href="/__pyric/ui/docs/pyric-messaging-sw-reference-api/"> pyric/messaging/sw </a> </li><li> <a href="/__pyric/ui/docs/pyric-rules-reference-api/"> pyric/rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-reference-api/"> pyric/sandbox </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-firestore-reference-api/"> pyric/sandbox/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-database-reference-api/"> pyric/sandbox/database </a> </li><li> <a href="/__pyric/ui/docs/pyric-app-check-reference-api/"> pyric/app-check </a> </li><li> <a href="/__pyric/ui/docs/pyric-functions-reference-api/"> pyric/functions </a> </li><li> <a href="/__pyric/ui/docs/pyric-analytics-reference-api/"> pyric/analytics </a> </li><li> <a href="/__pyric/ui/docs/pyric-performance-reference-api/"> pyric/performance </a> </li><li> <a href="/__pyric/ui/docs/pyric-remote-config-reference-api/"> pyric/remote-config </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">pyric-admin</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-admin-reference-api/"> pyric-admin </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-app-reference-api/"> pyric-admin/app </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-firestore-reference-api/"> pyric-admin/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-auth-reference-api/"> pyric-admin/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-database-reference-api/"> pyric-admin/database </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-storage-reference-api/"> pyric-admin/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-messaging-reference-api/"> pyric-admin/messaging </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">create-pyric</h2> <ul> <li> <a href="/__pyric/ui/docs/create-pyric-reference-api/"> create-pyric </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">@pyric/cli</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-cli-credentials-node-reference-api/"> @pyric/cli/credentials/node </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-verify-reference-api/"> @pyric/cli/verify </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-reference-api/"> @pyric/cli/conformance </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-browser-reference-api/"> @pyric/cli/conformance/browser </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-docs-reference-api/"> @pyric/cli/conformance/docs </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-assurance-reference-api/"> @pyric/cli/assurance </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-assurance-browser-reference-api/"> @pyric/cli/assurance/browser </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-bridge-reference-api/"> @pyric/cli/bridge </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-bridge-client-reference-api/"> @pyric/cli/bridge/client </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-discover-reference-api/"> @pyric/cli/discover </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-vite-reference-api/"> @pyric/cli/vite </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-next-reference-api/"> @pyric/cli/next </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-bundler-reference-api/"> @pyric/cli/bundler </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-serve-worker-reference-api/"> @pyric/cli/serve/worker </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-remote-reference-api/"> @pyric/cli/remote </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-reference-api/"> @pyric/cli/register </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-app-bridge-reference-api/"> @pyric/cli/register/app-bridge </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">@pyric/ui</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-ui-auth-reference-api/"> @pyric/ui/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-auth-hooks-reference-api/"> @pyric/ui/auth/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-primitives-reference-api/"> @pyric/ui/primitives </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-firestore-reference-api/"> @pyric/ui/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-firestore-hooks-reference-api/"> @pyric/ui/firestore/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rtdb-reference-api/"> @pyric/ui/rtdb </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-storage-reference-api/"> @pyric/ui/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-storage-hooks-reference-api/"> @pyric/ui/storage/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-traffic-reference-api/"> @pyric/ui/traffic </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-traffic-hooks-reference-api/"> @pyric/ui/traffic/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-events-reference-api/"> @pyric/ui/events </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-events-hooks-reference-api/"> @pyric/ui/events/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-agents-reference-api/"> @pyric/ui/agents </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rules-reference-api/"> @pyric/ui/rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rules-hooks-reference-api/"> @pyric/ui/rules/hooks </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">@pyric/cli</h2> <ul> <li> <a href="/__pyric/ui/docs/reference/cli/"> CLI </a> </li> </ul> </div> </div> </details> </nav> </details> <nav class="docs-nav" aria-label="Documentation"> <div class="docs-search" data-index-url="/__pyric/ui/docs/index.json"> <div class="docs-search-field"> <svg class="docs-search-icon" viewBox="0 0 16 16" width="14" height="14" aria-hidden="true"> <path d="M11.5 11.5 15 15M13 7A6 6 0 1 1 1 7a6 6 0 0 1 12 0Z" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"></path> </svg> <input type="text" class="docs-search-input" placeholder="Search docs" aria-label="Search docs" autocomplete="off" spellcheck="false"> <kbd class="docs-search-kbd">⌘K</kbd> </div> <ul class="docs-search-results" hidden></ul> </div> <details class="docs-nav-group" id="nav-group-overview"> <summary>Overview</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/overview/"> Overview </a> </li><li> <a href="/__pyric/ui/docs/tutorial/"> Tutorial </a> </li><li> <a href="/__pyric/ui/docs/examples/"> Examples </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-get-started" open> <summary>Get started</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/get-started/start-building/"> Quickstart </a> </li><li> <a href="/__pyric/ui/docs/get-started/vite/"> Vite </a> </li><li> <a href="/__pyric/ui/docs/get-started/nextjs/"> Next.js </a> </li><li> <a href="/__pyric/ui/docs/get-started/backend-bundlers/"> Backend bundlers </a> </li><li> <a href="/__pyric/ui/docs/get-started/flutter/" aria-current="page"> Flutter </a> </li><li> <a href="/__pyric/ui/docs/get-started/how-the-swap-works/"> How the swap works </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-build"> <summary>Build</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/build/authentication/"> Authentication </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-firestore/"> Cloud Firestore </a> </li><li> <a href="/__pyric/ui/docs/build/realtime-database/"> Realtime Database </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-storage/"> Cloud Storage </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-messaging/"> Cloud Messaging </a> </li><li> <a href="/__pyric/ui/docs/build/ai-logic/"> AI Logic </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-secure-debug"> <summary>Secure & debug</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/secure/secure-it-with-rules/"> Security Rules </a> </li><li> <a href="/__pyric/ui/docs/secure/simulate-and-lint/"> Simulate and lint before you deploy </a> </li><li> <a href="/__pyric/ui/docs/secure/write-a-rules-test-suite/"> Write a rules test suite </a> </li><li> <a href="/__pyric/ui/docs/secure/read-a-denial/"> Read a denial and understand it </a> </li><li> <a href="/__pyric/ui/docs/secure/rules-standard-library/"> The rules standard library </a> </li><li> <a href="/__pyric/ui/docs/secure/rtdb-rules-in-typescript/"> RTDB rules in TypeScript </a> </li><li> <a href="/__pyric/ui/docs/secure/firestore-rules-limits/"> Rules limits </a> </li><li> <a href="/__pyric/ui/docs/secure/audit-your-rules/"> Audit rules and data </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading" id="nav-section-secure-debug-examples"> Examples </h2> <ul> <li> <a href="/__pyric/ui/docs/examples/chess/"> Chess showcase </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-observe-shape"> <summary>Observe & shape</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/observe/see-whats-happening/"> Traffic & rule verdicts </a> </li><li> <a href="/__pyric/ui/docs/observe/resolve-runtime-status/"> Runtime status </a> </li><li> <a href="/__pyric/ui/docs/observe/switch-and-impersonate-identities/"> Impersonate & tenants </a> </li><li> <a href="/__pyric/ui/docs/observe/shape-your-data/"> Seed, snapshot, replay </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-ship-test"> <summary>Ship & test</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/ship/ship-to-production/"> Ship to production </a> </li><li> <a href="/__pyric/ui/docs/ship/test-in-node/"> Test in Node </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-work-with-an-agent"> <summary>Work with an agent</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/agent/set-up-your-agent/"> Connect an agent </a> </li><li> <a href="/__pyric/ui/docs/agent/work-with-an-agent/"> Use the MCP tools </a> </li><li> <a href="/__pyric/ui/docs/agent/watch-and-review/"> Watch in Pyric Studio </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-trust"> <summary>Trust</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/trust/versioning-and-compatibility/"> Versioning and the fb tag </a> </li><li> <a href="/__pyric/ui/docs/trust/rules-standard-library/"> Rules standard library reference </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-conformance"> <summary>Conformance</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/conformance-scores/"> Conformance scores </a> </li><li> <a href="/__pyric/ui/docs/trust/how-we-know-it-matches-firebase/"> How we know it matches Firebase </a> </li><li> <a href="/__pyric/ui/docs/app-compat/"> App </a> </li><li> <a href="/__pyric/ui/docs/ai-compat/"> AI Logic </a> </li><li> <a href="/__pyric/ui/docs/auth-compat/"> Auth </a> </li><li> <a href="/__pyric/ui/docs/firestore-compat/"> Firestore </a> </li><li> <a href="/__pyric/ui/docs/database-compat/"> Realtime Database </a> </li><li> <a href="/__pyric/ui/docs/storage-compat/"> Storage </a> </li><li> <a href="/__pyric/ui/docs/messaging-compat/"> Messaging </a> </li><li> <a href="/__pyric/ui/docs/functions-rtdb-compat/"> Functions · RTDB </a> </li><li> <a href="/__pyric/ui/docs/rules-compat/"> Rules </a> </li><li> <a href="/__pyric/ui/docs/firestore-flutter-compat/"> Firestore · Flutter </a> </li><li> <a href="/__pyric/ui/docs/firestore-kotlin-compat/"> Firestore · Kotlin </a> </li><li> <a href="/__pyric/ui/docs/firestore-swift-compat/"> Firestore · Swift </a> </li> </ul> </div> </div> </details> <details class="docs-nav-group" id="nav-group-reference"> <summary>Reference</summary> <div class="docs-nav-group-body docs-nav-group-body--reference"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/api-reference/"> API reference </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">pyric</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-app-reference-api/"> pyric/app </a> </li><li> <a href="/__pyric/ui/docs/pyric-firestore-reference-api/"> pyric/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-firestore-lite-reference-api/"> pyric/firestore/lite </a> </li><li> <a href="/__pyric/ui/docs/pyric-auth-reference-api/"> pyric/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-ai-reference-api/"> pyric/ai </a> </li><li> <a href="/__pyric/ui/docs/pyric-ai-scripting-reference-api/"> pyric/ai/scripting </a> </li><li> <a href="/__pyric/ui/docs/pyric-database-reference-api/"> pyric/database </a> </li><li> <a href="/__pyric/ui/docs/pyric-storage-reference-api/"> pyric/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-messaging-reference-api/"> pyric/messaging </a> </li><li> <a href="/__pyric/ui/docs/pyric-messaging-sw-reference-api/"> pyric/messaging/sw </a> </li><li> <a href="/__pyric/ui/docs/pyric-rules-reference-api/"> pyric/rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-reference-api/"> pyric/sandbox </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-firestore-reference-api/"> pyric/sandbox/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-database-reference-api/"> pyric/sandbox/database </a> </li><li> <a href="/__pyric/ui/docs/pyric-app-check-reference-api/"> pyric/app-check </a> </li><li> <a href="/__pyric/ui/docs/pyric-functions-reference-api/"> pyric/functions </a> </li><li> <a href="/__pyric/ui/docs/pyric-analytics-reference-api/"> pyric/analytics </a> </li><li> <a href="/__pyric/ui/docs/pyric-performance-reference-api/"> pyric/performance </a> </li><li> <a href="/__pyric/ui/docs/pyric-remote-config-reference-api/"> pyric/remote-config </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">pyric-admin</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-admin-reference-api/"> pyric-admin </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-app-reference-api/"> pyric-admin/app </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-firestore-reference-api/"> pyric-admin/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-auth-reference-api/"> pyric-admin/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-database-reference-api/"> pyric-admin/database </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-storage-reference-api/"> pyric-admin/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-messaging-reference-api/"> pyric-admin/messaging </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">create-pyric</h2> <ul> <li> <a href="/__pyric/ui/docs/create-pyric-reference-api/"> create-pyric </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">@pyric/cli</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-cli-credentials-node-reference-api/"> @pyric/cli/credentials/node </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-verify-reference-api/"> @pyric/cli/verify </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-reference-api/"> @pyric/cli/conformance </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-browser-reference-api/"> @pyric/cli/conformance/browser </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-docs-reference-api/"> @pyric/cli/conformance/docs </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-assurance-reference-api/"> @pyric/cli/assurance </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-assurance-browser-reference-api/"> @pyric/cli/assurance/browser </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-bridge-reference-api/"> @pyric/cli/bridge </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-bridge-client-reference-api/"> @pyric/cli/bridge/client </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-discover-reference-api/"> @pyric/cli/discover </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-vite-reference-api/"> @pyric/cli/vite </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-next-reference-api/"> @pyric/cli/next </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-bundler-reference-api/"> @pyric/cli/bundler </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-serve-worker-reference-api/"> @pyric/cli/serve/worker </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-remote-reference-api/"> @pyric/cli/remote </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-reference-api/"> @pyric/cli/register </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-app-bridge-reference-api/"> @pyric/cli/register/app-bridge </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">@pyric/ui</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-ui-auth-reference-api/"> @pyric/ui/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-auth-hooks-reference-api/"> @pyric/ui/auth/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-primitives-reference-api/"> @pyric/ui/primitives </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-firestore-reference-api/"> @pyric/ui/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-firestore-hooks-reference-api/"> @pyric/ui/firestore/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rtdb-reference-api/"> @pyric/ui/rtdb </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-storage-reference-api/"> @pyric/ui/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-storage-hooks-reference-api/"> @pyric/ui/storage/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-traffic-reference-api/"> @pyric/ui/traffic </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-traffic-hooks-reference-api/"> @pyric/ui/traffic/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-events-reference-api/"> @pyric/ui/events </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-events-hooks-reference-api/"> @pyric/ui/events/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-agents-reference-api/"> @pyric/ui/agents </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rules-reference-api/"> @pyric/ui/rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rules-hooks-reference-api/"> @pyric/ui/rules/hooks </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">@pyric/cli</h2> <ul> <li> <a href="/__pyric/ui/docs/reference/cli/"> CLI </a> </li> </ul> </div> </div> </details> </nav> <main class="doc-main" data-astro-cid-mw7aashj> <nav class="docs-breadcrumbs" aria-label="Breadcrumb"> <ol> <li> <a href="/__pyric/ui/docs/get-started/start-building/">Get started</a> </li><li> <span class="docs-breadcrumbs-sep" aria-hidden="true">/</span> <span aria-current="page">Flutter</span> </li> </ol> </nav> <article class="prose" data-astro-cid-mw7aashj> <h1 id="flutter-development-setup">Flutter development setup</h1>
|
|
6
|
+
<p>Use Pyric with Flutter and FlutterFire without modifying your application data code.</p>
|
|
7
|
+
<p><code>pyric_firestore</code> is a platform interface implementation for <a href="https://pub.dev/packages/cloud_firestore" target="_blank" rel="noopener noreferrer" class="external-link"><code>cloud_firestore</code></a>. In debug mode, it routes standard Firestore reads, writes, queries, and listeners across a local WebSocket bridge to your Pyric sandbox. In release builds, normal Firebase Cloud Firestore executes unchanged.</p>
|
|
8
|
+
<h2 id="add-the-dependency">Add the dependency</h2>
|
|
9
|
+
<p>Add <code>pyric_firestore</code> to your Flutter project’s <code>pubspec.yaml</code>:</p>
|
|
10
|
+
<pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="bash"><code><span class="line"><span style="color:#61AFEF">flutter</span><span style="color:#98C379"> pub</span><span style="color:#98C379"> add</span><span style="color:#98C379"> pyric_firestore</span></span></code></pre>
|
|
11
|
+
<h2 id="register-the-platform-interface">Register the platform interface</h2>
|
|
12
|
+
<p>In your application entry point (<code>lib/main.dart</code>), register <code>PyricFirestorePlatform</code> inside a <code>kDebugMode</code> guard before initializing UI or accessing Firestore:</p>
|
|
13
|
+
<pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="dart"><code><span class="line"><span style="color:#C678DD">import</span><span style="color:#98C379"> 'package:flutter/foundation.dart'</span><span style="color:#ABB2BF">;</span></span>
|
|
14
|
+
<span class="line"><span style="color:#C678DD">import</span><span style="color:#98C379"> 'package:flutter/material.dart'</span><span style="color:#ABB2BF">;</span></span>
|
|
15
|
+
<span class="line"><span style="color:#C678DD">import</span><span style="color:#98C379"> 'package:firebase_core/firebase_core.dart'</span><span style="color:#ABB2BF">;</span></span>
|
|
16
|
+
<span class="line"><span style="color:#C678DD">import</span><span style="color:#98C379"> 'package:cloud_firestore/cloud_firestore.dart'</span><span style="color:#ABB2BF">;</span></span>
|
|
17
|
+
<span class="line"><span style="color:#C678DD">import</span><span style="color:#98C379"> 'package:pyric_firestore/pyric_firestore.dart'</span><span style="color:#ABB2BF">;</span></span>
|
|
18
|
+
<span class="line"></span>
|
|
19
|
+
<span class="line"><span style="color:#E5C07B">Future</span><span style="color:#ABB2BF"><</span><span style="color:#C678DD">void</span><span style="color:#ABB2BF">> </span><span style="color:#61AFEF">main</span><span style="color:#ABB2BF">() </span><span style="color:#C678DD">async</span><span style="color:#ABB2BF"> {</span></span>
|
|
20
|
+
<span class="line"><span style="color:#E5C07B"> WidgetsFlutterBinding</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">ensureInitialized</span><span style="color:#ABB2BF">();</span></span>
|
|
21
|
+
<span class="line"><span style="color:#C678DD"> await</span><span style="color:#E5C07B"> Firebase</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">initializeApp</span><span style="color:#ABB2BF">();</span></span>
|
|
22
|
+
<span class="line"></span>
|
|
23
|
+
<span class="line"><span style="color:#7F848E;font-style:italic"> // In debug builds, redirect Firestore calls to the local Pyric sandbox</span></span>
|
|
24
|
+
<span class="line"><span style="color:#C678DD"> if</span><span style="color:#ABB2BF"> (kDebugMode) {</span></span>
|
|
25
|
+
<span class="line"><span style="color:#E5C07B"> PyricFirestorePlatform</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">registerWith</span><span style="color:#ABB2BF">(</span></span>
|
|
26
|
+
<span class="line"><span style="color:#ABB2BF"> bridgeClient</span><span style="color:#C678DD">:</span><span style="color:#E5C07B"> PyricBridgeClient</span><span style="color:#ABB2BF">(</span></span>
|
|
27
|
+
<span class="line"><span style="color:#ABB2BF"> uri</span><span style="color:#C678DD">:</span><span style="color:#E5C07B"> Uri</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">parse</span><span style="color:#ABB2BF">(</span><span style="color:#98C379">'ws://127.0.0.1:5174/__pyric/sandbox'</span><span style="color:#ABB2BF">),</span></span>
|
|
28
|
+
<span class="line"><span style="color:#ABB2BF"> ),</span></span>
|
|
29
|
+
<span class="line"><span style="color:#ABB2BF"> );</span></span>
|
|
30
|
+
<span class="line"><span style="color:#ABB2BF"> }</span></span>
|
|
31
|
+
<span class="line"></span>
|
|
32
|
+
<span class="line"><span style="color:#61AFEF"> runApp</span><span style="color:#ABB2BF">(</span><span style="color:#C678DD">const</span><span style="color:#E5C07B"> MyApp</span><span style="color:#ABB2BF">());</span></span>
|
|
33
|
+
<span class="line"><span style="color:#ABB2BF">}</span></span></code></pre>
|
|
34
|
+
<p>Every standard <code>FirebaseFirestore.instance</code> call (<code>collection()</code>, <code>doc()</code>, <code>snapshots()</code>, transactions, batches) now executes against the local Pyric backend.</p>
|
|
35
|
+
<h2 id="start-the-pyric-sandbox-bridge">Start the Pyric sandbox bridge</h2>
|
|
36
|
+
<p>Start the Pyric sandbox with the bridge enabled and listen on your designated port:</p>
|
|
37
|
+
<pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="bash"><code><span class="line"><span style="color:#61AFEF">npx</span><span style="color:#98C379"> pyric</span><span style="color:#98C379"> sandbox</span><span style="color:#D19A66"> --bridge</span><span style="color:#D19A66"> --port</span><span style="color:#D19A66"> 5174</span></span></code></pre>
|
|
38
|
+
<p>Alternatively, if you run a Vite web application alongside Flutter, enable the bridge in <code>vite.config.ts</code>:</p>
|
|
39
|
+
<pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">import</span><span style="color:#ABB2BF"> { </span><span style="color:#E06C75">defineConfig</span><span style="color:#ABB2BF"> } </span><span style="color:#C678DD">from</span><span style="color:#98C379"> 'vite'</span><span style="color:#ABB2BF">;</span></span>
|
|
40
|
+
<span class="line"><span style="color:#C678DD">import</span><span style="color:#ABB2BF"> { </span><span style="color:#E06C75">pyric</span><span style="color:#ABB2BF"> } </span><span style="color:#C678DD">from</span><span style="color:#98C379"> '@pyric/cli/vite'</span><span style="color:#ABB2BF">;</span></span>
|
|
41
|
+
<span class="line"></span>
|
|
42
|
+
<span class="line"><span style="color:#C678DD">export</span><span style="color:#C678DD"> default</span><span style="color:#61AFEF"> defineConfig</span><span style="color:#ABB2BF">({</span></span>
|
|
43
|
+
<span class="line"><span style="color:#E06C75"> plugins</span><span style="color:#ABB2BF">: [</span></span>
|
|
44
|
+
<span class="line"><span style="color:#61AFEF"> pyric</span><span style="color:#ABB2BF">({</span></span>
|
|
45
|
+
<span class="line"><span style="color:#E06C75"> bridge</span><span style="color:#ABB2BF">: </span><span style="color:#D19A66">true</span><span style="color:#ABB2BF">,</span></span>
|
|
46
|
+
<span class="line"><span style="color:#ABB2BF"> }),</span></span>
|
|
47
|
+
<span class="line"><span style="color:#ABB2BF"> ],</span></span>
|
|
48
|
+
<span class="line"><span style="color:#ABB2BF">});</span></span></code></pre>
|
|
49
|
+
<p>The bridge accepts WebSocket connections at <code>/__pyric/sandbox</code> on the development server origin.</p>
|
|
50
|
+
<h2 id="connect-from-devices-and-emulators">Connect from devices and emulators</h2>
|
|
51
|
+
<p>The connection URI depends on where your Flutter application is running:</p>
|
|
52
|
+
<div class="table-scroll">
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
<table><thead><tr><th align="left">Target Platform</th><th align="left">Bridge URI</th><th align="left">Setup Command</th></tr></thead><tbody><tr><td align="left"><strong>macOS / Windows / Linux desktop</strong></td><td align="left"><code>ws://127.0.0.1:5174/__pyric/sandbox</code></td><td align="left">None</td></tr><tr><td align="left"><strong>iOS Simulator</strong></td><td align="left"><code>ws://127.0.0.1:5174/__pyric/sandbox</code></td><td align="left">None</td></tr><tr><td align="left"><strong>Android Emulator</strong></td><td align="left"><code>ws://127.0.0.1:5174/__pyric/sandbox</code></td><td align="left"><code>adb reverse tcp:5174 tcp:5174</code></td></tr><tr><td align="left"><strong>Physical Device (iOS / Android)</strong></td><td align="left"><code>ws://<HOST-LAN-IP>:5174/__pyric/sandbox</code></td><td align="left">Connect to same Wi-Fi / local network</td></tr></tbody></table></div>
|
|
83
|
+
<h3 id="android-emulator-setup">Android Emulator setup</h3>
|
|
84
|
+
<p>Pyric enforces a DNS-rebinding security guard on incoming HTTP and WebSocket requests. When an Android emulator connects through the standard virtual router (<code>10.0.2.2:5174</code>), the request header carries <code>Host: 10.0.2.2:5174</code>, which the guard rejects.</p>
|
|
85
|
+
<p>Run <code>adb reverse</code> to forward port 5174 over the emulator’s loopback interface:</p>
|
|
86
|
+
<pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="bash"><code><span class="line"><span style="color:#61AFEF">adb</span><span style="color:#98C379"> reverse</span><span style="color:#98C379"> tcp:5174</span><span style="color:#98C379"> tcp:5174</span></span></code></pre>
|
|
87
|
+
<p>With reverse forwarding active, connect to <code>ws://127.0.0.1:5174/__pyric/sandbox</code>.</p>
|
|
88
|
+
<h2 id="supported-firestore-capabilities">Supported Firestore capabilities</h2>
|
|
89
|
+
<p><code>pyric_firestore</code> mirrors FlutterFire’s core API surface:</p>
|
|
90
|
+
<ul>
|
|
91
|
+
<li><strong>Documents & Collections</strong>: <code>doc()</code>, <code>collection()</code>, <code>get()</code>, <code>set()</code>, <code>update()</code>, <code>delete()</code>, and real-time <code>snapshots()</code>.</li>
|
|
92
|
+
<li><strong>Queries</strong>: <code>where()</code>, <code>whereFilter()</code> (<code>Filter.and</code>, <code>Filter.or</code>), <code>orderBy()</code>, <code>limit()</code>, <code>limitToLast()</code>, and cursor pagination (<code>startAt</code>, <code>startAfter</code>, <code>endAt</code>, <code>endBefore</code>).</li>
|
|
93
|
+
<li><strong>Aggregations</strong>: <code>count()</code>, <code>aggregate()</code>.</li>
|
|
94
|
+
<li><strong>Field Values</strong>: <code>FieldValue.serverTimestamp()</code>, <code>FieldValue.increment()</code>, <code>FieldValue.arrayUnion()</code>, <code>FieldValue.arrayRemove()</code>, and <code>FieldValue.delete()</code>.</li>
|
|
95
|
+
<li><strong>Batched Writes</strong>: Atomic <code>FirebaseFirestore.instance.batch()</code> commits.</li>
|
|
96
|
+
<li><strong>Transactions</strong>: Interactive <code>FirebaseFirestore.instance.runTransaction()</code> reads and writes.</li>
|
|
97
|
+
</ul>
|
|
98
|
+
<p>Check the <a href="/docs/firestore-flutter-compat/">Flutter Firestore conformance scorecard</a> for detailed behavioral coverage and parity status.</p> </article> </main> <aside class="doc-toc" aria-label="On this page" data-astro-cid-mw7aashj> <h2 class="doc-toc-heading" data-astro-cid-mw7aashj>On this page</h2> <ul data-astro-cid-mw7aashj> <li data-depth="2" data-astro-cid-mw7aashj> <a href="#add-the-dependency" data-astro-cid-mw7aashj>Add the dependency</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#register-the-platform-interface" data-astro-cid-mw7aashj>Register the platform interface</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#start-the-pyric-sandbox-bridge" data-astro-cid-mw7aashj>Start the Pyric sandbox bridge</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#connect-from-devices-and-emulators" data-astro-cid-mw7aashj>Connect from devices and emulators</a> </li><li data-depth="3" data-astro-cid-mw7aashj> <a href="#android-emulator-setup" data-astro-cid-mw7aashj>Android Emulator setup</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#supported-firestore-capabilities" data-astro-cid-mw7aashj>Supported Firestore capabilities</a> </li> </ul> </aside> </div> <script type="module">const a=document.querySelector("[data-api-symbol-filter]"),d=[...document.querySelectorAll("[data-api-symbol-group]")],n=document.querySelector("[data-api-symbol-empty]");a?.addEventListener("input",()=>{const t=a.value.trim().toLowerCase();let o=0;for(const i of d){let e=0;i.querySelectorAll("[data-api-symbol]").forEach(l=>{const r=!t||(l.dataset.apiSymbol??"").includes(t);l.hidden=!r,r&&e++}),i.hidden=e===0,o+=e}n&&(n.hidden=o>0)});</script> <script type="module">const s=new Map;document.querySelectorAll('.doc-toc a[href^="#"]').forEach(t=>s.set(decodeURIComponent(t.hash.slice(1)),t));if(s.size>0){const t=new Set,n=()=>{let o=null;for(const e of s.keys())if(t.has(e)){o=e;break}s.forEach((e,c)=>e.classList.toggle("active",c===o))},r=new IntersectionObserver(o=>{for(const e of o)e.isIntersecting?t.add(e.target.id):t.delete(e.target.id);n()},{rootMargin:"-72px 0px -60% 0px"});s.forEach((o,e)=>{const c=document.getElementById(e);c&&r.observe(c)})}</script> <script type="module">document.querySelector('.studio__nav [aria-current="page"]')?.scrollIntoView({block:"nearest",inline:"center"});</script> </body></html>
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
|
|
2
|
+
# Flutter development setup
|
|
3
|
+
|
|
4
|
+
Use Pyric with Flutter and FlutterFire without modifying your application data code.
|
|
5
|
+
|
|
6
|
+
`pyric_firestore` is a platform interface implementation for [`cloud_firestore`](https://pub.dev/packages/cloud_firestore). In debug mode, it routes standard Firestore reads, writes, queries, and listeners across a local WebSocket bridge to your Pyric sandbox. In release builds, normal Firebase Cloud Firestore executes unchanged.
|
|
7
|
+
|
|
8
|
+
## Add the dependency
|
|
9
|
+
|
|
10
|
+
Add `pyric_firestore` to your Flutter project's `pubspec.yaml`:
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
flutter pub add pyric_firestore
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Register the platform interface
|
|
17
|
+
|
|
18
|
+
In your application entry point (`lib/main.dart`), register `PyricFirestorePlatform` inside a `kDebugMode` guard before initializing UI or accessing Firestore:
|
|
19
|
+
|
|
20
|
+
```dart
|
|
21
|
+
import 'package:flutter/foundation.dart';
|
|
22
|
+
import 'package:flutter/material.dart';
|
|
23
|
+
import 'package:firebase_core/firebase_core.dart';
|
|
24
|
+
import 'package:cloud_firestore/cloud_firestore.dart';
|
|
25
|
+
import 'package:pyric_firestore/pyric_firestore.dart';
|
|
26
|
+
|
|
27
|
+
Future<void> main() async {
|
|
28
|
+
WidgetsFlutterBinding.ensureInitialized();
|
|
29
|
+
await Firebase.initializeApp();
|
|
30
|
+
|
|
31
|
+
// In debug builds, redirect Firestore calls to the local Pyric sandbox
|
|
32
|
+
if (kDebugMode) {
|
|
33
|
+
PyricFirestorePlatform.registerWith(
|
|
34
|
+
bridgeClient: PyricBridgeClient(
|
|
35
|
+
uri: Uri.parse('ws://127.0.0.1:5174/__pyric/sandbox'),
|
|
36
|
+
),
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
runApp(const MyApp());
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Every standard `FirebaseFirestore.instance` call (`collection()`, `doc()`, `snapshots()`, transactions, batches) now executes against the local Pyric backend.
|
|
45
|
+
|
|
46
|
+
## Start the Pyric sandbox bridge
|
|
47
|
+
|
|
48
|
+
Start the Pyric sandbox with the bridge enabled and listen on your designated port:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
npx pyric sandbox --bridge --port 5174
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Alternatively, if you run a Vite web application alongside Flutter, enable the bridge in `vite.config.ts`:
|
|
55
|
+
|
|
56
|
+
```ts
|
|
57
|
+
import { defineConfig } from 'vite';
|
|
58
|
+
import { pyric } from '@pyric/cli/vite';
|
|
59
|
+
|
|
60
|
+
export default defineConfig({
|
|
61
|
+
plugins: [
|
|
62
|
+
pyric({
|
|
63
|
+
bridge: true,
|
|
64
|
+
}),
|
|
65
|
+
],
|
|
66
|
+
});
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
The bridge accepts WebSocket connections at `/__pyric/sandbox` on the development server origin.
|
|
70
|
+
|
|
71
|
+
## Connect from devices and emulators
|
|
72
|
+
|
|
73
|
+
The connection URI depends on where your Flutter application is running:
|
|
74
|
+
|
|
75
|
+
| Target Platform | Bridge URI | Setup Command |
|
|
76
|
+
| :--- | :--- | :--- |
|
|
77
|
+
| **macOS / Windows / Linux desktop** | `ws://127.0.0.1:5174/__pyric/sandbox` | None |
|
|
78
|
+
| **iOS Simulator** | `ws://127.0.0.1:5174/__pyric/sandbox` | None |
|
|
79
|
+
| **Android Emulator** | `ws://127.0.0.1:5174/__pyric/sandbox` | `adb reverse tcp:5174 tcp:5174` |
|
|
80
|
+
| **Physical Device (iOS / Android)** | `ws://<HOST-LAN-IP>:5174/__pyric/sandbox` | Connect to same Wi-Fi / local network |
|
|
81
|
+
|
|
82
|
+
### Android Emulator setup
|
|
83
|
+
|
|
84
|
+
Pyric enforces a DNS-rebinding security guard on incoming HTTP and WebSocket requests. When an Android emulator connects through the standard virtual router (`10.0.2.2:5174`), the request header carries `Host: 10.0.2.2:5174`, which the guard rejects.
|
|
85
|
+
|
|
86
|
+
Run `adb reverse` to forward port 5174 over the emulator's loopback interface:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
adb reverse tcp:5174 tcp:5174
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
With reverse forwarding active, connect to `ws://127.0.0.1:5174/__pyric/sandbox`.
|
|
93
|
+
|
|
94
|
+
## Supported Firestore capabilities
|
|
95
|
+
|
|
96
|
+
`pyric_firestore` mirrors FlutterFire's core API surface:
|
|
97
|
+
|
|
98
|
+
- **Documents & Collections**: `doc()`, `collection()`, `get()`, `set()`, `update()`, `delete()`, and real-time `snapshots()`.
|
|
99
|
+
- **Queries**: `where()`, `whereFilter()` (`Filter.and`, `Filter.or`), `orderBy()`, `limit()`, `limitToLast()`, and cursor pagination (`startAt`, `startAfter`, `endAt`, `endBefore`).
|
|
100
|
+
- **Aggregations**: `count()`, `aggregate()`.
|
|
101
|
+
- **Field Values**: `FieldValue.serverTimestamp()`, `FieldValue.increment()`, `FieldValue.arrayUnion()`, `FieldValue.arrayRemove()`, and `FieldValue.delete()`.
|
|
102
|
+
- **Batched Writes**: Atomic `FirebaseFirestore.instance.batch()` commits.
|
|
103
|
+
- **Transactions**: Interactive `FirebaseFirestore.instance.runTransaction()` reads and writes.
|
|
104
|
+
|
|
105
|
+
Check the [Flutter Firestore conformance scorecard](/docs/firestore-flutter-compat/) for detailed behavioral coverage and parity status.
|