@pyric/cli 0.1.0-alpha.16 → 0.1.0-alpha.17
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 +13 -9
- package/dist/assurance/.generated/conformance-verdicts.d.ts +80 -72
- package/dist/assurance/.generated/conformance-verdicts.d.ts.map +1 -1
- package/dist/assurance/.generated/conformance-verdicts.js +80 -72
- package/dist/assurance/.generated/conformance-verdicts.js.map +1 -1
- package/dist/cli/database-rules.d.ts.map +1 -1
- package/dist/cli/database-rules.js +6 -4
- package/dist/cli/database-rules.js.map +1 -1
- package/dist/cli/dev-runner.d.ts +9 -0
- package/dist/cli/dev-runner.d.ts.map +1 -1
- package/dist/cli/dev-runner.js +18 -0
- package/dist/cli/dev-runner.js.map +1 -1
- package/dist/cli/serve.d.ts.map +1 -1
- package/dist/cli/serve.js +61 -6
- package/dist/cli/serve.js.map +1 -1
- package/dist/cli/verify.js +2 -2
- package/dist/cli/verify.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.map +1 -1
- package/dist/conformance/.generated/conformance-docs.js +1 -1
- package/dist/conformance/.generated/conformance-docs.js.map +1 -1
- package/dist/next/client-aliases.d.ts +11 -0
- package/dist/next/client-aliases.d.ts.map +1 -0
- package/dist/next/client-aliases.js +38 -0
- package/dist/next/client-aliases.js.map +1 -0
- package/dist/next/dev-rewrites.d.ts +9 -0
- package/dist/next/dev-rewrites.d.ts.map +1 -0
- package/dist/next/dev-rewrites.js +53 -0
- package/dist/next/dev-rewrites.js.map +1 -0
- package/dist/next/guard.d.ts +15 -0
- package/dist/next/guard.d.ts.map +1 -0
- package/dist/next/guard.js +52 -0
- package/dist/next/guard.js.map +1 -0
- package/dist/next/index.d.ts +12 -0
- package/dist/next/index.d.ts.map +1 -0
- package/dist/next/index.js +11 -0
- package/dist/next/index.js.map +1 -0
- package/dist/next/runtime-env.d.ts +7 -0
- package/dist/next/runtime-env.d.ts.map +1 -0
- package/dist/next/runtime-env.js +13 -0
- package/dist/next/runtime-env.js.map +1 -0
- package/dist/next/server-external-packages.d.ts +10 -0
- package/dist/next/server-external-packages.d.ts.map +1 -0
- package/dist/next/server-external-packages.js +34 -0
- package/dist/next/server-external-packages.js.map +1 -0
- package/dist/next/target-url.d.ts +11 -0
- package/dist/next/target-url.d.ts.map +1 -0
- package/dist/next/target-url.js +36 -0
- package/dist/next/target-url.js.map +1 -0
- package/dist/next/turbopack-config.d.ts +9 -0
- package/dist/next/turbopack-config.d.ts.map +1 -0
- package/dist/next/turbopack-config.js +39 -0
- package/dist/next/turbopack-config.js.map +1 -0
- package/dist/next/types.d.ts +40 -0
- package/dist/next/types.d.ts.map +1 -0
- package/dist/next/types.js +5 -0
- package/dist/next/types.js.map +1 -0
- package/dist/next/webpack-config.d.ts +11 -0
- package/dist/next/webpack-config.d.ts.map +1 -0
- package/dist/next/webpack-config.js +51 -0
- package/dist/next/webpack-config.js.map +1 -0
- package/dist/next/with-pyric.d.ts +22 -0
- package/dist/next/with-pyric.d.ts.map +1 -0
- package/dist/next/with-pyric.js +49 -0
- package/dist/next/with-pyric.js.map +1 -0
- package/dist/register/app-bridge.d.ts +9 -0
- package/dist/register/app-bridge.d.ts.map +1 -0
- package/dist/register/app-bridge.js +56 -0
- package/dist/register/app-bridge.js.map +1 -0
- package/dist/register/hooks.d.ts.map +1 -1
- package/dist/register/hooks.js +6 -1
- package/dist/register/hooks.js.map +1 -1
- package/dist/register/index.js +1 -1
- package/dist/register/index.js.map +1 -1
- package/dist/register/mapping.d.ts +3 -1
- package/dist/register/mapping.d.ts.map +1 -1
- package/dist/register/mapping.js +41 -5
- package/dist/register/mapping.js.map +1 -1
- package/dist/rtdb/rules-json.d.ts +12 -0
- package/dist/rtdb/rules-json.d.ts.map +1 -1
- package/dist/rtdb/rules-json.js +98 -0
- package/dist/rtdb/rules-json.js.map +1 -1
- package/dist/serve/bundler.d.ts.map +1 -1
- package/dist/serve/bundler.js +2 -0
- package/dist/serve/bundler.js.map +1 -1
- package/dist/serve/discovery.d.ts +4 -4
- package/dist/serve/discovery.d.ts.map +1 -1
- package/dist/serve/discovery.js +59 -38
- package/dist/serve/discovery.js.map +1 -1
- package/dist/serve/entries/app-ai-passthrough.d.ts +8 -0
- package/dist/serve/entries/app-ai-passthrough.d.ts.map +1 -0
- package/dist/serve/entries/app-ai-passthrough.js +59 -0
- package/dist/serve/entries/app-ai-passthrough.js.map +1 -0
- package/dist/serve/entries/auth-helper-core.js +9 -7
- package/dist/serve/entries/auth-helper-core.js.map +1 -1
- package/dist/serve/entries/auth.d.ts +1 -0
- package/dist/serve/entries/auth.d.ts.map +1 -1
- package/dist/serve/entries/auth.js +1 -0
- package/dist/serve/entries/auth.js.map +1 -1
- package/dist/serve/entries/bridge-url.d.ts.map +1 -1
- package/dist/serve/entries/bridge-url.js +7 -2
- package/dist/serve/entries/bridge-url.js.map +1 -1
- package/dist/serve/entries/database.d.ts +1 -0
- package/dist/serve/entries/database.d.ts.map +1 -1
- package/dist/serve/entries/database.js +1 -0
- package/dist/serve/entries/database.js.map +1 -1
- package/dist/serve/entries/firestore.d.ts +1 -0
- package/dist/serve/entries/firestore.d.ts.map +1 -1
- package/dist/serve/entries/firestore.js +1 -0
- package/dist/serve/entries/firestore.js.map +1 -1
- package/dist/serve/entries/init.d.ts.map +1 -1
- package/dist/serve/entries/init.js +4 -2
- package/dist/serve/entries/init.js.map +1 -1
- package/dist/serve/entries/runtime.js +23 -0
- package/dist/serve/entries/runtime.js.map +1 -1
- package/dist/serve/entries/storage.d.ts +2 -0
- package/dist/serve/entries/storage.d.ts.map +1 -1
- package/dist/serve/entries/storage.js +9 -2
- package/dist/serve/entries/storage.js.map +1 -1
- package/dist/serve/html-injection.d.ts +3 -1
- package/dist/serve/html-injection.d.ts.map +1 -1
- package/dist/serve/html-injection.js +27 -1
- package/dist/serve/html-injection.js.map +1 -1
- package/dist/serve/rules.js +2 -2
- package/dist/serve/rules.js.map +1 -1
- package/dist/serve/runtime/chip-config.d.ts +1 -1
- package/dist/serve/runtime/chip-config.d.ts.map +1 -1
- package/dist/serve/runtime/chip-config.js +16 -8
- package/dist/serve/runtime/chip-config.js.map +1 -1
- package/dist/serve/sandbox-session.d.ts +1 -0
- package/dist/serve/sandbox-session.d.ts.map +1 -1
- package/dist/serve/sandbox-session.js +30 -2
- package/dist/serve/sandbox-session.js.map +1 -1
- package/dist/serve/site-ui/_astro/_studio_.B6b_G1ev.css +1 -0
- package/dist/serve/site-ui/_astro/app.bnmVTkIY.js +11 -0
- package/dist/serve/site-ui/_astro/app.t6u-adB_.js +1 -0
- package/dist/serve/site-ui/_astro/{chess-showcase.CnoxIle5.js → chess-showcase.kC8dXLKY.js} +1 -1
- package/dist/serve/site-ui/_astro/{example-runtime.R1d96L6-.js → example-runtime.D79PnoSk.js} +1 -1
- package/dist/serve/site-ui/_astro/index.DzVde04M.js +1 -0
- package/dist/serve/site-ui/_astro/reads.BYBRLbsE.js +1 -0
- package/dist/serve/site-ui/_astro/sandbox-controls.C9Aaazt8.js +1252 -0
- package/dist/serve/site-ui/_astro/{seed.EyI3VYEu.js → seed.DANAIyRw.js} +1 -1
- package/dist/serve/site-ui/auth/index.html +2 -2
- 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 +85 -85
- package/dist/serve/site-ui/docs/ai-compat.md +84 -84
- package/dist/serve/site-ui/docs/api-reference/index.html +3 -1
- package/dist/serve/site-ui/docs/api-reference.md +2 -0
- package/dist/serve/site-ui/docs/app-compat/index.html +28 -28
- package/dist/serve/site-ui/docs/app-compat.md +27 -27
- package/dist/serve/site-ui/docs/auth-compat/index.html +122 -122
- package/dist/serve/site-ui/docs/auth-compat.md +121 -121
- package/dist/serve/site-ui/docs/build/ai-logic/index.html +1 -1
- package/dist/serve/site-ui/docs/build/authentication/index.html +1 -1
- package/dist/serve/site-ui/docs/build/cloud-firestore/index.html +1 -1
- 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 +4 -4
- package/dist/serve/site-ui/docs/conformance-scores.md +3 -3
- package/dist/serve/site-ui/docs/create-pyric-reference-api/index.html +6 -6
- package/dist/serve/site-ui/docs/create-pyric-reference-api.md +5 -5
- package/dist/serve/site-ui/docs/database-compat/index.html +200 -448
- package/dist/serve/site-ui/docs/database-compat.md +198 -461
- package/dist/serve/site-ui/docs/examples/chess/index.html +2 -2
- package/dist/serve/site-ui/docs/examples/index.html +1 -1
- package/dist/serve/site-ui/docs/firestore-compat/index.html +186 -195
- package/dist/serve/site-ui/docs/firestore-compat.md +184 -195
- package/dist/serve/site-ui/docs/functions-rtdb-compat/index.html +15 -15
- package/dist/serve/site-ui/docs/functions-rtdb-compat.md +14 -14
- 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 +57 -0
- package/dist/serve/site-ui/docs/get-started/nextjs.md +86 -0
- package/dist/serve/site-ui/docs/get-started/start-building/index.html +25 -8
- package/dist/serve/site-ui/docs/get-started/start-building.md +34 -5
- package/dist/serve/site-ui/docs/get-started/vite/index.html +26 -0
- package/dist/serve/site-ui/docs/get-started/vite.md +45 -0
- package/dist/serve/site-ui/docs/index.json +668 -103
- package/dist/serve/site-ui/docs/messaging-compat/index.html +56 -56
- package/dist/serve/site-ui/docs/messaging-compat.md +55 -55
- package/dist/serve/site-ui/docs/observe/resolve-runtime-status/index.html +1 -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/overview/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-admin-app-reference-api/index.html +39 -13
- package/dist/serve/site-ui/docs/pyric-admin-app-reference-api.md +28 -2
- 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 +38 -6
- package/dist/serve/site-ui/docs/pyric-admin-database-reference-api.md +43 -0
- package/dist/serve/site-ui/docs/pyric-admin-firestore-reference-api/index.html +9 -1
- package/dist/serve/site-ui/docs/pyric-admin-firestore-reference-api.md +8 -0
- package/dist/serve/site-ui/docs/pyric-admin-messaging-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-admin-storage-reference-api/index.html +27 -4
- package/dist/serve/site-ui/docs/pyric-admin-storage-reference-api.md +23 -0
- 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-app-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-auth-reference-api/index.html +1 -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 +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-conformance-browser-reference-api/index.html +1 -1
- 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 +1 -1
- 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 +123 -0
- package/dist/serve/site-ui/docs/pyric-cli-next-reference-api.md +99 -0
- package/dist/serve/site-ui/docs/pyric-cli-register-app-bridge-reference-api/index.html +127 -0
- package/dist/serve/site-ui/docs/pyric-cli-register-app-bridge-reference-api.md +174 -0
- 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 +1 -1
- package/dist/serve/site-ui/docs/pyric-cli-serve-worker-reference-api/index.html +570 -326
- package/dist/serve/site-ui/docs/pyric-cli-serve-worker-reference-api.md +198 -6
- package/dist/serve/site-ui/docs/pyric-cli-verify-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-cli-vite-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-database-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-firestore-reference-api/index.html +2971 -627
- package/dist/serve/site-ui/docs/pyric-firestore-reference-api.md +2873 -517
- 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-rules-reference-api/index.html +43 -3
- package/dist/serve/site-ui/docs/pyric-rules-reference-api.md +8 -0
- package/dist/serve/site-ui/docs/pyric-sandbox-database-reference-api/index.html +26 -2
- package/dist/serve/site-ui/docs/pyric-sandbox-database-reference-api.md +24 -0
- 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 +77 -9
- package/dist/serve/site-ui/docs/pyric-sandbox-reference-api.md +28 -13
- package/dist/serve/site-ui/docs/pyric-storage-reference-api/index.html +240 -63
- package/dist/serve/site-ui/docs/pyric-storage-reference-api.md +164 -5
- package/dist/serve/site-ui/docs/pyric-ui-agents-reference-api/index.html +1 -1
- 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 +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 +1 -1
- package/dist/serve/site-ui/docs/pyric-ui-primitives-reference-api/index.html +1 -1
- 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 +2 -1
- package/dist/serve/site-ui/docs/pyric-ui-storage-reference-api.md +1 -0
- 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/rules-compat/index.html +87 -79
- package/dist/serve/site-ui/docs/rules-compat.md +86 -78
- 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 +119 -125
- package/dist/serve/site-ui/docs/storage-compat.md +118 -124
- 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/storage-rules-stdlib-research/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/examples/firestore-first-write/index.html +1 -1
- package/dist/serve/site-ui/firestore/index.html +2 -2
- package/dist/serve/site-ui/index.html +2 -2
- package/dist/serve/site-ui/llms.txt +6 -2
- package/dist/serve/site-ui/rtdb/index.html +2 -2
- package/dist/serve/site-ui/settings/index.html +2 -2
- package/dist/serve/site-ui/storage/index.html +2 -2
- package/dist/serve/site-ui/traffic/index.html +2 -2
- package/dist/serve/vite-ai-config.d.ts +4 -1
- package/dist/serve/vite-ai-config.d.ts.map +1 -1
- package/dist/serve/vite-ai-config.js +83 -19
- package/dist/serve/vite-ai-config.js.map +1 -1
- package/dist/serve/vite-generation-rules-watch.d.ts.map +1 -1
- package/dist/serve/vite-generation-rules-watch.js +61 -14
- package/dist/serve/vite-generation-rules-watch.js.map +1 -1
- package/dist/serve/vite-module-swap.d.ts +4 -1
- package/dist/serve/vite-module-swap.d.ts.map +1 -1
- package/dist/serve/vite-module-swap.js +106 -21
- package/dist/serve/vite-module-swap.js.map +1 -1
- package/dist/serve/vite-plugin.d.ts.map +1 -1
- package/dist/serve/vite-plugin.js +45 -5
- package/dist/serve/vite-plugin.js.map +1 -1
- package/dist/serve/vite-sandbox-generation.js +1 -1
- package/dist/serve/vite-sandbox-generation.js.map +1 -1
- package/dist/serve/worker/client/resumable.d.ts +30 -0
- package/dist/serve/worker/client/resumable.d.ts.map +1 -0
- package/dist/serve/worker/client/resumable.js +416 -0
- package/dist/serve/worker/client/resumable.js.map +1 -0
- package/dist/serve/worker/client/rtdb-references.d.ts.map +1 -1
- package/dist/serve/worker/client/rtdb-references.js +4 -1
- package/dist/serve/worker/client/rtdb-references.js.map +1 -1
- package/dist/serve/worker/client/storage.d.ts +16 -2
- package/dist/serve/worker/client/storage.d.ts.map +1 -1
- package/dist/serve/worker/client/storage.js +57 -6
- package/dist/serve/worker/client/storage.js.map +1 -1
- package/dist/serve/worker/host/rules.d.ts.map +1 -1
- package/dist/serve/worker/host/rules.js +2 -1
- package/dist/serve/worker/host/rules.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 +1 -1
- package/dist/serve/worker/index.js.map +1 -1
- package/dist/serve/worker/serve-init.d.ts.map +1 -1
- package/dist/serve/worker/serve-init.js +31 -0
- package/dist/serve/worker/serve-init.js.map +1 -1
- package/package.json +15 -4
- package/src/assurance/.generated/conformance-verdicts.ts +80 -72
- package/src/cli/cli.test.ts +14 -0
- package/src/cli/database-rules.ts +6 -4
- package/src/cli/dev-runner.ts +21 -0
- package/src/cli/serve.ts +62 -5
- package/src/cli/verify.ts +2 -2
- package/src/conformance/.generated/can-i-use-browser.ts +1 -1
- package/src/conformance/.generated/can-i-use.ts +1 -1
- package/src/conformance/.generated/conformance-docs.ts +1 -1
- package/src/next/client-aliases.ts +39 -0
- package/src/next/dev-rewrites.ts +77 -0
- package/src/next/guard.ts +61 -0
- package/src/next/index.ts +16 -0
- package/src/next/runtime-env.ts +18 -0
- package/src/next/server-external-packages.ts +43 -0
- package/src/next/target-url.ts +46 -0
- package/src/next/turbopack-config.ts +54 -0
- package/src/next/types.ts +47 -0
- package/src/next/webpack-config.ts +71 -0
- package/src/next/with-pyric.ts +58 -0
- package/src/register/app-bridge.ts +79 -0
- package/src/register/hooks.ts +6 -1
- package/src/register/index.ts +1 -1
- package/src/register/mapping.ts +50 -4
- package/src/rtdb/rules-json.ts +110 -0
- package/src/serve/bundler.ts +2 -0
- package/src/serve/discovery.ts +65 -44
- package/src/serve/entries/app-ai-passthrough.ts +83 -0
- package/src/serve/entries/auth-helper-core.ts +9 -7
- package/src/serve/entries/auth.ts +1 -0
- package/src/serve/entries/bridge-url.ts +9 -2
- package/src/serve/entries/database.ts +1 -0
- package/src/serve/entries/firestore.ts +1 -0
- package/src/serve/entries/init.ts +5 -2
- package/src/serve/entries/runtime.ts +25 -0
- package/src/serve/entries/storage.ts +12 -1
- package/src/serve/html-injection.ts +26 -1
- package/src/serve/rules.ts +2 -2
- package/src/serve/runtime/chip-config.ts +19 -6
- package/src/serve/sandbox-session.ts +31 -2
- package/src/serve/vite-ai-config.ts +86 -19
- package/src/serve/vite-generation-rules-watch.ts +67 -15
- package/src/serve/vite-module-swap.ts +121 -21
- package/src/serve/vite-plugin.ts +44 -6
- package/src/serve/vite-sandbox-generation.ts +1 -1
- package/src/serve/worker/client/resumable.ts +506 -0
- package/src/serve/worker/client/rtdb-references.ts +4 -1
- package/src/serve/worker/client/storage.ts +77 -7
- package/src/serve/worker/host/rules.ts +2 -1
- package/src/serve/worker/index.ts +4 -0
- package/src/serve/worker/serve-init.ts +30 -0
- package/dist/serve/site-ui/_astro/_studio_.BtYpqe1A.css +0 -1
- package/dist/serve/site-ui/_astro/app.4HeLP_FA.js +0 -109
- package/dist/serve/site-ui/_astro/app.BgSnCR5G.js +0 -1
- package/dist/serve/site-ui/_astro/index.BJiOemMX.js +0 -1
- package/dist/serve/site-ui/_astro/reads.BrKNdKAa.js +0 -1
- package/dist/serve/site-ui/_astro/sandbox-controls.BTb3EbQp.js +0 -1153
|
@@ -0,0 +1,506 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Worker-mode resumable upload operations: `uploadBytesResumable` and observer tasks.
|
|
3
|
+
*
|
|
4
|
+
* Emits synthetic/mock progress events before invoking the worker client's base64
|
|
5
|
+
* `uploadBytes` RPC to commit the file to the shared storage backend.
|
|
6
|
+
*/
|
|
7
|
+
import type { FullMetadata } from 'pyric/storage';
|
|
8
|
+
import type { ClientStorageReference, ClientSettableMetadata } from './storage.js';
|
|
9
|
+
import { uploadBytes, deleteObject } from './storage.js';
|
|
10
|
+
|
|
11
|
+
export type ClientTaskState = 'running' | 'paused' | 'success' | 'canceled' | 'error';
|
|
12
|
+
|
|
13
|
+
export interface ClientUploadTaskSnapshot {
|
|
14
|
+
readonly bytesTransferred: number;
|
|
15
|
+
readonly totalBytes: number;
|
|
16
|
+
readonly state: ClientTaskState;
|
|
17
|
+
readonly metadata: FullMetadata;
|
|
18
|
+
readonly ref: ClientStorageReference;
|
|
19
|
+
readonly task: ClientUploadTask;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface ClientUploadTask extends Promise<ClientUploadTaskSnapshot> {
|
|
23
|
+
readonly snapshot: ClientUploadTaskSnapshot;
|
|
24
|
+
cancel(): boolean;
|
|
25
|
+
pause(): boolean;
|
|
26
|
+
resume(): boolean;
|
|
27
|
+
on(
|
|
28
|
+
event: string,
|
|
29
|
+
nextOrObserver?:
|
|
30
|
+
| null
|
|
31
|
+
| ((snapshot: ClientUploadTaskSnapshot) => unknown)
|
|
32
|
+
| {
|
|
33
|
+
next?: (snapshot: ClientUploadTaskSnapshot) => unknown;
|
|
34
|
+
error?: (error: Error) => unknown;
|
|
35
|
+
complete?: () => unknown;
|
|
36
|
+
},
|
|
37
|
+
error?: null | ((error: Error) => unknown),
|
|
38
|
+
complete?: null | (() => unknown),
|
|
39
|
+
): () => void;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
interface ClientTaskObserver {
|
|
43
|
+
next: ((snapshot: ClientUploadTaskSnapshot) => unknown) | undefined;
|
|
44
|
+
error: ((error: Error) => unknown) | undefined;
|
|
45
|
+
complete: (() => unknown) | undefined;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function computePayloadSize(data: Blob | Uint8Array | ArrayBuffer): number {
|
|
49
|
+
const isBlob = data instanceof Blob;
|
|
50
|
+
if (isBlob) {
|
|
51
|
+
return data.size;
|
|
52
|
+
}
|
|
53
|
+
return data.byteLength;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function createCanceledError(): Error & { code: string } {
|
|
57
|
+
const err = new Error('storage/canceled: User canceled the upload/download.') as Error & { code: string };
|
|
58
|
+
err.code = 'storage/canceled';
|
|
59
|
+
return err;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function createRootOpError(): Error & { code: string } {
|
|
63
|
+
const err = new Error('storage/invalid-root-operation: uploadBytesResumable cannot operate on root reference.') as Error & { code: string };
|
|
64
|
+
err.code = 'storage/invalid-root-operation';
|
|
65
|
+
return err;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
class ClientUploadTaskImpl implements ClientUploadTask {
|
|
69
|
+
readonly [Symbol.toStringTag] = 'UploadTask';
|
|
70
|
+
private _snapshot: ClientUploadTaskSnapshot;
|
|
71
|
+
private _promise: Promise<ClientUploadTaskSnapshot>;
|
|
72
|
+
private _resolve!: (snapshot: ClientUploadTaskSnapshot) => void;
|
|
73
|
+
private _reject!: (error: Error) => void;
|
|
74
|
+
private _observers: ClientTaskObserver[] = [];
|
|
75
|
+
private _didIntermediateProgress = false;
|
|
76
|
+
private _error: Error | undefined;
|
|
77
|
+
private readonly _ref: ClientStorageReference;
|
|
78
|
+
private readonly _data: Blob | Uint8Array | ArrayBuffer;
|
|
79
|
+
private readonly _metadata: ClientSettableMetadata | undefined;
|
|
80
|
+
|
|
81
|
+
constructor(
|
|
82
|
+
ref: ClientStorageReference,
|
|
83
|
+
data: Blob | Uint8Array | ArrayBuffer,
|
|
84
|
+
metadata?: ClientSettableMetadata,
|
|
85
|
+
) {
|
|
86
|
+
this._ref = ref;
|
|
87
|
+
this._data = data;
|
|
88
|
+
this._metadata = metadata;
|
|
89
|
+
|
|
90
|
+
const size = computePayloadSize(data);
|
|
91
|
+
const now = new Date().toISOString();
|
|
92
|
+
|
|
93
|
+
let contentType = 'application/octet-stream';
|
|
94
|
+
const isBlob = data instanceof Blob;
|
|
95
|
+
if (isBlob) {
|
|
96
|
+
const hasBlobType = data.type !== '';
|
|
97
|
+
if (hasBlobType) {
|
|
98
|
+
contentType = data.type;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
const hasMetadata = metadata !== undefined;
|
|
102
|
+
if (hasMetadata) {
|
|
103
|
+
const hasMetaType = metadata.contentType !== undefined;
|
|
104
|
+
if (hasMetaType) {
|
|
105
|
+
const metaTypeDefined = metadata.contentType;
|
|
106
|
+
if (metaTypeDefined !== undefined) {
|
|
107
|
+
contentType = metaTypeDefined;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const initialMetadata: FullMetadata = {
|
|
113
|
+
fullPath: ref.fullPath,
|
|
114
|
+
name: ref.name,
|
|
115
|
+
bucket: 'default',
|
|
116
|
+
generation: '1',
|
|
117
|
+
metageneration: '1',
|
|
118
|
+
timeCreated: now,
|
|
119
|
+
updated: now,
|
|
120
|
+
size,
|
|
121
|
+
contentType,
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
this._promise = new Promise<ClientUploadTaskSnapshot>((resolve, reject) => {
|
|
125
|
+
this._resolve = resolve;
|
|
126
|
+
this._reject = reject;
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
this._promise.catch(() => {});
|
|
130
|
+
|
|
131
|
+
this._snapshot = {
|
|
132
|
+
bytesTransferred: 0,
|
|
133
|
+
totalBytes: size,
|
|
134
|
+
state: 'running',
|
|
135
|
+
metadata: initialMetadata,
|
|
136
|
+
ref: this._ref,
|
|
137
|
+
task: this,
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
queueMicrotask(() => {
|
|
141
|
+
this._runStep();
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
get snapshot(): ClientUploadTaskSnapshot {
|
|
146
|
+
return this._snapshot;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
then<TResult1 = ClientUploadTaskSnapshot, TResult2 = never>(
|
|
150
|
+
onFulfilled?: null | ((value: ClientUploadTaskSnapshot) => TResult1 | PromiseLike<TResult1>),
|
|
151
|
+
onRejected?: null | ((reason: unknown) => TResult2 | PromiseLike<TResult2>),
|
|
152
|
+
): Promise<TResult1 | TResult2> {
|
|
153
|
+
return this._promise.then(onFulfilled, onRejected);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
catch<TResult = never>(
|
|
157
|
+
onRejected?: null | ((reason: unknown) => TResult | PromiseLike<TResult>),
|
|
158
|
+
): Promise<ClientUploadTaskSnapshot | TResult> {
|
|
159
|
+
return this._promise.catch(onRejected);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
finally(onFinally?: null | (() => void)): Promise<ClientUploadTaskSnapshot> {
|
|
163
|
+
return this._promise.finally(onFinally);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
pause(): boolean {
|
|
167
|
+
const isRunning = this._snapshot.state === 'running';
|
|
168
|
+
if (isRunning) {
|
|
169
|
+
this._updateSnapshot('paused', this._snapshot.bytesTransferred);
|
|
170
|
+
this._notifyObservers('next');
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
173
|
+
return false;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
resume(): boolean {
|
|
177
|
+
const isPaused = this._snapshot.state === 'paused';
|
|
178
|
+
if (isPaused) {
|
|
179
|
+
this._updateSnapshot('running', this._snapshot.bytesTransferred);
|
|
180
|
+
this._notifyObservers('next');
|
|
181
|
+
queueMicrotask(() => {
|
|
182
|
+
this._runStep();
|
|
183
|
+
});
|
|
184
|
+
return true;
|
|
185
|
+
}
|
|
186
|
+
return false;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
cancel(): boolean {
|
|
190
|
+
let canCancel = false;
|
|
191
|
+
const isRunning = this._snapshot.state === 'running';
|
|
192
|
+
if (isRunning) {
|
|
193
|
+
canCancel = true;
|
|
194
|
+
} else {
|
|
195
|
+
const isPaused = this._snapshot.state === 'paused';
|
|
196
|
+
if (isPaused) {
|
|
197
|
+
canCancel = true;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (canCancel) {
|
|
202
|
+
this._error = createCanceledError();
|
|
203
|
+
this._updateSnapshot('canceled', this._snapshot.bytesTransferred);
|
|
204
|
+
this._notifyObservers('error');
|
|
205
|
+
this._reject(this._error);
|
|
206
|
+
return true;
|
|
207
|
+
}
|
|
208
|
+
return false;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
on(
|
|
212
|
+
event: string,
|
|
213
|
+
nextOrObserver?:
|
|
214
|
+
| null
|
|
215
|
+
| ((snapshot: ClientUploadTaskSnapshot) => unknown)
|
|
216
|
+
| {
|
|
217
|
+
next?: (snapshot: ClientUploadTaskSnapshot) => unknown;
|
|
218
|
+
error?: (error: Error) => unknown;
|
|
219
|
+
complete?: () => unknown;
|
|
220
|
+
},
|
|
221
|
+
error?: null | ((error: Error) => unknown),
|
|
222
|
+
complete?: null | (() => unknown),
|
|
223
|
+
): () => void {
|
|
224
|
+
let nextCb: ((snapshot: ClientUploadTaskSnapshot) => unknown) | undefined;
|
|
225
|
+
let errCb: ((error: Error) => unknown) | undefined;
|
|
226
|
+
let compCb: (() => unknown) | undefined;
|
|
227
|
+
|
|
228
|
+
let isObjectObserver = false;
|
|
229
|
+
const isObject = typeof nextOrObserver === 'object';
|
|
230
|
+
if (isObject) {
|
|
231
|
+
const isNotNull = nextOrObserver !== null;
|
|
232
|
+
if (isNotNull) {
|
|
233
|
+
isObjectObserver = true;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
if (isObjectObserver) {
|
|
238
|
+
const observerObj = nextOrObserver as {
|
|
239
|
+
next?: (snapshot: ClientUploadTaskSnapshot) => unknown;
|
|
240
|
+
error?: (error: Error) => unknown;
|
|
241
|
+
complete?: () => unknown;
|
|
242
|
+
};
|
|
243
|
+
const hasNext = observerObj.next !== undefined;
|
|
244
|
+
if (hasNext) {
|
|
245
|
+
nextCb = observerObj.next;
|
|
246
|
+
}
|
|
247
|
+
const hasError = observerObj.error !== undefined;
|
|
248
|
+
if (hasError) {
|
|
249
|
+
errCb = observerObj.error;
|
|
250
|
+
}
|
|
251
|
+
const hasComplete = observerObj.complete !== undefined;
|
|
252
|
+
if (hasComplete) {
|
|
253
|
+
compCb = observerObj.complete;
|
|
254
|
+
}
|
|
255
|
+
} else {
|
|
256
|
+
const isFunction = typeof nextOrObserver === 'function';
|
|
257
|
+
if (isFunction) {
|
|
258
|
+
nextCb = nextOrObserver as (snapshot: ClientUploadTaskSnapshot) => unknown;
|
|
259
|
+
}
|
|
260
|
+
const isErrorFunction = typeof error === 'function';
|
|
261
|
+
if (isErrorFunction) {
|
|
262
|
+
errCb = error as (error: Error) => unknown;
|
|
263
|
+
}
|
|
264
|
+
const isCompleteFunction = typeof complete === 'function';
|
|
265
|
+
if (isCompleteFunction) {
|
|
266
|
+
compCb = complete as () => unknown;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
const observer: ClientTaskObserver = { next: nextCb, error: errCb, complete: compCb };
|
|
271
|
+
this._observers.push(observer);
|
|
272
|
+
|
|
273
|
+
const isCurrentlyRunning = this._snapshot.state === 'running';
|
|
274
|
+
if (isCurrentlyRunning) {
|
|
275
|
+
const hasNextCb = nextCb !== undefined;
|
|
276
|
+
if (hasNextCb) {
|
|
277
|
+
const fn = nextCb as (snapshot: ClientUploadTaskSnapshot) => unknown;
|
|
278
|
+
try {
|
|
279
|
+
fn(this._snapshot);
|
|
280
|
+
} catch {
|
|
281
|
+
// Observational
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
} else {
|
|
285
|
+
const isCurrentlyPaused = this._snapshot.state === 'paused';
|
|
286
|
+
if (isCurrentlyPaused) {
|
|
287
|
+
const hasNextCb = nextCb !== undefined;
|
|
288
|
+
if (hasNextCb) {
|
|
289
|
+
const fn = nextCb as (snapshot: ClientUploadTaskSnapshot) => unknown;
|
|
290
|
+
try {
|
|
291
|
+
fn(this._snapshot);
|
|
292
|
+
} catch {
|
|
293
|
+
// Observational
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
} else {
|
|
297
|
+
const isAlreadySuccess = this._snapshot.state === 'success';
|
|
298
|
+
if (isAlreadySuccess) {
|
|
299
|
+
const hasNextCb = nextCb !== undefined;
|
|
300
|
+
if (hasNextCb) {
|
|
301
|
+
const fn = nextCb as (snapshot: ClientUploadTaskSnapshot) => unknown;
|
|
302
|
+
try {
|
|
303
|
+
fn(this._snapshot);
|
|
304
|
+
} catch {
|
|
305
|
+
// Observational
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
const hasCompleteCb = compCb !== undefined;
|
|
309
|
+
if (hasCompleteCb) {
|
|
310
|
+
const fn = compCb as () => unknown;
|
|
311
|
+
try {
|
|
312
|
+
fn();
|
|
313
|
+
} catch {
|
|
314
|
+
// Observational
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
} else {
|
|
318
|
+
const isAlreadyError = this._snapshot.state === 'error';
|
|
319
|
+
if (isAlreadyError) {
|
|
320
|
+
const hasErrCb = errCb !== undefined;
|
|
321
|
+
if (hasErrCb) {
|
|
322
|
+
const hasStoredError = this._error !== undefined;
|
|
323
|
+
if (hasStoredError) {
|
|
324
|
+
const fn = errCb as (error: Error) => unknown;
|
|
325
|
+
const err = this._error as Error;
|
|
326
|
+
try {
|
|
327
|
+
fn(err);
|
|
328
|
+
} catch {
|
|
329
|
+
// Observational
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
} else {
|
|
334
|
+
const isAlreadyCanceled = this._snapshot.state === 'canceled';
|
|
335
|
+
if (isAlreadyCanceled) {
|
|
336
|
+
const hasErrCb = errCb !== undefined;
|
|
337
|
+
if (hasErrCb) {
|
|
338
|
+
const hasStoredError = this._error !== undefined;
|
|
339
|
+
if (hasStoredError) {
|
|
340
|
+
const fn = errCb as (error: Error) => unknown;
|
|
341
|
+
const err = this._error as Error;
|
|
342
|
+
try {
|
|
343
|
+
fn(err);
|
|
344
|
+
} catch {
|
|
345
|
+
// Observational
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
return () => {
|
|
356
|
+
const index = this._observers.indexOf(observer);
|
|
357
|
+
const isFound = index !== -1;
|
|
358
|
+
if (isFound) {
|
|
359
|
+
this._observers.splice(index, 1);
|
|
360
|
+
}
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
private _updateSnapshot(state: ClientTaskState, bytesTransferred: number, metadata?: FullMetadata): void {
|
|
365
|
+
let nextMetadata = this._snapshot.metadata;
|
|
366
|
+
const isNewMetadata = metadata !== undefined;
|
|
367
|
+
if (isNewMetadata) {
|
|
368
|
+
nextMetadata = metadata;
|
|
369
|
+
}
|
|
370
|
+
this._snapshot = {
|
|
371
|
+
bytesTransferred,
|
|
372
|
+
totalBytes: this._snapshot.totalBytes,
|
|
373
|
+
state,
|
|
374
|
+
metadata: nextMetadata,
|
|
375
|
+
ref: this._ref,
|
|
376
|
+
task: this,
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
private _notifyObservers(kind: 'next' | 'error' | 'complete'): void {
|
|
381
|
+
const isNext = kind === 'next';
|
|
382
|
+
if (isNext) {
|
|
383
|
+
for (const obs of this._observers) {
|
|
384
|
+
const hasNext = obs.next !== undefined;
|
|
385
|
+
if (hasNext) {
|
|
386
|
+
const fn = obs.next as (snapshot: ClientUploadTaskSnapshot) => unknown;
|
|
387
|
+
try {
|
|
388
|
+
fn(this._snapshot);
|
|
389
|
+
} catch {
|
|
390
|
+
// Ignore observer exceptions
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
const isError = kind === 'error';
|
|
397
|
+
if (isError) {
|
|
398
|
+
for (const obs of this._observers) {
|
|
399
|
+
const hasError = obs.error !== undefined;
|
|
400
|
+
if (hasError) {
|
|
401
|
+
const isErrorDefined = this._error !== undefined;
|
|
402
|
+
if (isErrorDefined) {
|
|
403
|
+
const fn = obs.error as (error: Error) => unknown;
|
|
404
|
+
const err = this._error as Error;
|
|
405
|
+
try {
|
|
406
|
+
fn(err);
|
|
407
|
+
} catch {
|
|
408
|
+
// Ignore observer exceptions
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
const isComplete = kind === 'complete';
|
|
416
|
+
if (isComplete) {
|
|
417
|
+
for (const obs of this._observers) {
|
|
418
|
+
const hasComplete = obs.complete !== undefined;
|
|
419
|
+
if (hasComplete) {
|
|
420
|
+
const fn = obs.complete as () => unknown;
|
|
421
|
+
try {
|
|
422
|
+
fn();
|
|
423
|
+
} catch {
|
|
424
|
+
// Ignore observer exceptions
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
private _runStep(): void {
|
|
432
|
+
const isNotRunning = this._snapshot.state !== 'running';
|
|
433
|
+
if (isNotRunning) {
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
const needsIntermediate = this._didIntermediateProgress === false;
|
|
438
|
+
if (needsIntermediate) {
|
|
439
|
+
this._didIntermediateProgress = true;
|
|
440
|
+
let middleBytes = 0;
|
|
441
|
+
const hasBytes = this._snapshot.totalBytes > 0;
|
|
442
|
+
if (hasBytes) {
|
|
443
|
+
middleBytes = Math.floor(this._snapshot.totalBytes / 2);
|
|
444
|
+
}
|
|
445
|
+
this._updateSnapshot('running', middleBytes);
|
|
446
|
+
this._notifyObservers('next');
|
|
447
|
+
queueMicrotask(() => {
|
|
448
|
+
this._runStep();
|
|
449
|
+
});
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
this._commitUpload();
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
private async _commitUpload(): Promise<void> {
|
|
457
|
+
const isNotRunning = this._snapshot.state !== 'running';
|
|
458
|
+
if (isNotRunning) {
|
|
459
|
+
return;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
try {
|
|
463
|
+
const result = await uploadBytes(this._ref, this._data, this._metadata);
|
|
464
|
+
const isStillRunning = this._snapshot.state === 'running';
|
|
465
|
+
if (isStillRunning) {
|
|
466
|
+
this._updateSnapshot('success', this._snapshot.totalBytes, result.metadata);
|
|
467
|
+
this._notifyObservers('next');
|
|
468
|
+
this._notifyObservers('complete');
|
|
469
|
+
this._resolve(this._snapshot);
|
|
470
|
+
} else {
|
|
471
|
+
try {
|
|
472
|
+
await deleteObject(this._ref);
|
|
473
|
+
} catch {
|
|
474
|
+
// Best-effort rollback
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
} catch (err: unknown) {
|
|
478
|
+
const isStillRunning = this._snapshot.state === 'running';
|
|
479
|
+
if (isStillRunning) {
|
|
480
|
+
let errObj: Error;
|
|
481
|
+
const isInstanceOfError = err instanceof Error;
|
|
482
|
+
if (isInstanceOfError) {
|
|
483
|
+
errObj = err as Error;
|
|
484
|
+
} else {
|
|
485
|
+
errObj = new Error(String(err));
|
|
486
|
+
}
|
|
487
|
+
this._error = errObj;
|
|
488
|
+
this._updateSnapshot('error', this._snapshot.bytesTransferred);
|
|
489
|
+
this._notifyObservers('error');
|
|
490
|
+
this._reject(this._error);
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
export function uploadBytesResumable(
|
|
497
|
+
reference: ClientStorageReference,
|
|
498
|
+
data: Blob | Uint8Array | ArrayBuffer,
|
|
499
|
+
metadata?: ClientSettableMetadata,
|
|
500
|
+
): ClientUploadTask {
|
|
501
|
+
const isRoot = reference.fullPath === '';
|
|
502
|
+
if (isRoot) {
|
|
503
|
+
throw createRootOpError();
|
|
504
|
+
}
|
|
505
|
+
return new ClientUploadTaskImpl(reference, data, metadata);
|
|
506
|
+
}
|
|
@@ -51,7 +51,10 @@ export function makeRtdbRef(port: ClientPort, path: string): RtdbRefHandle {
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
function validateRtdbPath(path: string, allowEmpty: boolean): void {
|
|
54
|
-
|
|
54
|
+
const normalized = path.replace(/^\/*\.info(\/|$)/, '/');
|
|
55
|
+
const isInvalidLength = !allowEmpty && path.length === 0;
|
|
56
|
+
const containsForbiddenChars = /[.#$[\]]/.test(normalized);
|
|
57
|
+
if (isInvalidLength || containsForbiddenChars) {
|
|
55
58
|
throw new Error(
|
|
56
59
|
`child failed: path argument was an invalid path = "${path}". Paths must be non-empty strings and can't contain ".", "#", "$", "[", or "]"`,
|
|
57
60
|
);
|
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { bytesToBase64, base64ToBytes, storagePayloadTooLarge, MAX_STORAGE_OP_BYTES } from '../protocol.js';
|
|
8
|
-
import type { FullMetadata } from 'pyric/storage';
|
|
8
|
+
import type { FullMetadata, StringFormat } from 'pyric/storage';
|
|
9
|
+
import { decodeString, defaultRawContentType } from 'pyric/storage/internal';
|
|
9
10
|
import { dataRpc, nextId, wirePort } from './core.js';
|
|
10
11
|
import { lastSegment } from './handles.js';
|
|
11
12
|
import type { ClientDb, ClientPort } from './handles.js';
|
|
@@ -19,14 +20,55 @@ import type { ClientDb, ClientPort } from './handles.js';
|
|
|
19
20
|
export interface ClientFirebaseStorage {
|
|
20
21
|
readonly __kind: 'client-storage';
|
|
21
22
|
readonly port: ClientPort;
|
|
23
|
+
readonly bucket: string;
|
|
22
24
|
}
|
|
23
25
|
|
|
24
26
|
/** Worker-backed Storage reference (path + name; carries the port for ops). */
|
|
25
27
|
export interface ClientStorageReference {
|
|
26
28
|
readonly __kind: 'storage-ref';
|
|
27
29
|
readonly port: ClientPort;
|
|
30
|
+
readonly storage?: ClientFirebaseStorage;
|
|
31
|
+
readonly bucket: string;
|
|
28
32
|
readonly fullPath: string;
|
|
29
33
|
readonly name: string;
|
|
34
|
+
readonly parent: ClientStorageReference | null;
|
|
35
|
+
readonly root: ClientStorageReference;
|
|
36
|
+
toString(): string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
class ClientStorageReferenceImpl implements ClientStorageReference {
|
|
40
|
+
readonly __kind = 'storage-ref';
|
|
41
|
+
readonly port: ClientPort;
|
|
42
|
+
readonly storage?: ClientFirebaseStorage;
|
|
43
|
+
readonly bucket: string;
|
|
44
|
+
readonly fullPath: string;
|
|
45
|
+
readonly name: string;
|
|
46
|
+
|
|
47
|
+
constructor(port: ClientPort, bucket: string, fullPath: string, storage?: ClientFirebaseStorage) {
|
|
48
|
+
this.port = port;
|
|
49
|
+
this.bucket = bucket;
|
|
50
|
+
this.fullPath = fullPath;
|
|
51
|
+
this.name = lastSegment(fullPath);
|
|
52
|
+
if (storage) {
|
|
53
|
+
this.storage = storage;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
get parent(): ClientStorageReference | null {
|
|
58
|
+
if (this.fullPath === '') return null;
|
|
59
|
+
const idx = this.fullPath.lastIndexOf('/');
|
|
60
|
+
const parentPath = idx === -1 ? '' : this.fullPath.slice(0, idx);
|
|
61
|
+
return new ClientStorageReferenceImpl(this.port, this.bucket, parentPath, this.storage);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
get root(): ClientStorageReference {
|
|
65
|
+
if (this.fullPath === '') return this;
|
|
66
|
+
return new ClientStorageReferenceImpl(this.port, this.bucket, '', this.storage);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
toString(): string {
|
|
70
|
+
return `gs://${this.bucket}/${this.fullPath}`;
|
|
71
|
+
}
|
|
30
72
|
}
|
|
31
73
|
|
|
32
74
|
/** Strip leading/trailing slashes (the worker keyspace uses bare paths). */
|
|
@@ -38,7 +80,7 @@ function normalizeStorageRefPath(path: string): string {
|
|
|
38
80
|
* Get the worker-backed Storage handle. Like `getAuth`, accepts an existing
|
|
39
81
|
* `ClientDb` (reusing its port) or a worker URL (standalone).
|
|
40
82
|
*/
|
|
41
|
-
export function getStorage(source: ClientDb | string | URL, name?: string): ClientFirebaseStorage {
|
|
83
|
+
export function getStorage(source: ClientDb | string | URL, name?: string, bucketUrl?: string): ClientFirebaseStorage {
|
|
42
84
|
let port: ClientPort;
|
|
43
85
|
if (typeof source === 'object' && '__kind' in source && source.__kind === 'client-db') {
|
|
44
86
|
port = source.port;
|
|
@@ -57,7 +99,7 @@ export function getStorage(source: ClientDb | string | URL, name?: string): Clie
|
|
|
57
99
|
port.start();
|
|
58
100
|
wirePort(port);
|
|
59
101
|
}
|
|
60
|
-
return { __kind: 'client-storage', port };
|
|
102
|
+
return { __kind: 'client-storage', port, bucket: bucketUrl ?? 'pyric-default' };
|
|
61
103
|
}
|
|
62
104
|
|
|
63
105
|
/** Build a Storage reference. Mirrors `pyric/storage`'s `ref(storage, path?)` /
|
|
@@ -68,13 +110,23 @@ export function ref(
|
|
|
68
110
|
): ClientStorageReference {
|
|
69
111
|
const rel = normalizeStorageRefPath(path ?? '');
|
|
70
112
|
let fullPath: string;
|
|
113
|
+
let port: ClientPort;
|
|
114
|
+
let bucket = 'pyric-default';
|
|
115
|
+
let storage: ClientFirebaseStorage | undefined;
|
|
116
|
+
|
|
71
117
|
if (parent.__kind === 'client-storage') {
|
|
72
118
|
fullPath = rel;
|
|
119
|
+
port = parent.port;
|
|
120
|
+
bucket = parent.bucket;
|
|
121
|
+
storage = parent;
|
|
73
122
|
} else {
|
|
74
123
|
const base = parent.fullPath;
|
|
75
124
|
fullPath = rel ? (base ? `${base}/${rel}` : rel) : base;
|
|
125
|
+
port = parent.port;
|
|
126
|
+
bucket = parent.bucket;
|
|
127
|
+
storage = parent.storage;
|
|
76
128
|
}
|
|
77
|
-
return
|
|
129
|
+
return new ClientStorageReferenceImpl(port, bucket, fullPath, storage);
|
|
78
130
|
}
|
|
79
131
|
|
|
80
132
|
/** Enumerate immediate child items + sub-prefixes under a ref (Pyric Studio
|
|
@@ -85,9 +137,8 @@ export async function listAll(
|
|
|
85
137
|
const r = (await dataRpc(reference.port, {
|
|
86
138
|
t: 'op', id: nextId(), method: 'storage.listAll', path: reference.fullPath,
|
|
87
139
|
})) as { items: Array<{ fullPath: string; name: string }>; prefixes: Array<{ fullPath: string; name: string }> };
|
|
88
|
-
const mk = (e: { fullPath: string; name: string }): ClientStorageReference =>
|
|
89
|
-
|
|
90
|
-
});
|
|
140
|
+
const mk = (e: { fullPath: string; name: string }): ClientStorageReference =>
|
|
141
|
+
new ClientStorageReferenceImpl(reference.port, reference.bucket, e.fullPath, reference.storage);
|
|
91
142
|
return { items: r.items.map(mk), prefixes: r.prefixes.map(mk) };
|
|
92
143
|
}
|
|
93
144
|
|
|
@@ -165,6 +216,22 @@ export async function uploadBytes(
|
|
|
165
216
|
return { ref: reference, metadata: stored };
|
|
166
217
|
}
|
|
167
218
|
|
|
219
|
+
/** Upload string payload at the reference's path.
|
|
220
|
+
* Mirrors `pyric/storage`'s `uploadString` result shape. */
|
|
221
|
+
export async function uploadString(
|
|
222
|
+
reference: ClientStorageReference,
|
|
223
|
+
value: string,
|
|
224
|
+
format: StringFormat = 'raw',
|
|
225
|
+
metadata?: ClientSettableMetadata,
|
|
226
|
+
): Promise<{ ref: ClientStorageReference; metadata: FullMetadata }> {
|
|
227
|
+
const { bytes, inferredType } = decodeString(value, format);
|
|
228
|
+
const effective: ClientSettableMetadata = {
|
|
229
|
+
...metadata,
|
|
230
|
+
contentType: metadata?.contentType ?? inferredType ?? defaultRawContentType(format),
|
|
231
|
+
};
|
|
232
|
+
return uploadBytes(reference, bytes, effective);
|
|
233
|
+
}
|
|
234
|
+
|
|
168
235
|
/** Read an object's bytes (JSON-safe base64 op → `ArrayBuffer`). Mirrors
|
|
169
236
|
* `pyric/storage`'s `getBytes`, including the optional client-side cap. */
|
|
170
237
|
export async function getBytes(
|
|
@@ -193,3 +260,6 @@ export async function deleteObject(reference: ClientStorageReference): Promise<v
|
|
|
193
260
|
t: 'op', id: nextId(), method: 'storage.deleteObject', path: reference.fullPath,
|
|
194
261
|
});
|
|
195
262
|
}
|
|
263
|
+
|
|
264
|
+
export { uploadBytesResumable } from './resumable.js';
|
|
265
|
+
export type { ClientUploadTask, ClientUploadTaskSnapshot } from './resumable.js';
|
|
@@ -14,6 +14,7 @@ import type { Firestore } from 'pyric/firestore';
|
|
|
14
14
|
import { setRules } from 'pyric/sandbox/firestore';
|
|
15
15
|
import { sandbox as rtdbSandbox } from 'pyric/database';
|
|
16
16
|
|
|
17
|
+
import { stripJsonComments } from '../../../rtdb/rules-json.js';
|
|
17
18
|
import type { OpMessage } from '../protocol.js';
|
|
18
19
|
import { type HostCtx, type PortLike, ok, fail } from '../host-context.js';
|
|
19
20
|
import { ensureRtdb } from './core.js';
|
|
@@ -21,7 +22,7 @@ import { ensureRtdb } from './core.js';
|
|
|
21
22
|
function normalizeDatabaseRules(source: unknown): { rules: Record<string, unknown> } | null {
|
|
22
23
|
if (source === null) return null;
|
|
23
24
|
if (typeof source === 'string') {
|
|
24
|
-
return JSON.parse(source) as { rules: Record<string, unknown> };
|
|
25
|
+
return JSON.parse(stripJsonComments(source)) as { rules: Record<string, unknown> };
|
|
25
26
|
}
|
|
26
27
|
if (typeof source === 'object' && source !== null) {
|
|
27
28
|
return source as { rules: Record<string, unknown> };
|
|
@@ -167,11 +167,15 @@ export {
|
|
|
167
167
|
getDownloadURL,
|
|
168
168
|
// Storage byte ops (worker-mode uploads/reads via the base64 protocol)
|
|
169
169
|
uploadBytes,
|
|
170
|
+
uploadString,
|
|
171
|
+
uploadBytesResumable,
|
|
170
172
|
getBytes,
|
|
171
173
|
deleteObject,
|
|
172
174
|
type ClientFirebaseStorage,
|
|
173
175
|
type ClientStorageReference,
|
|
174
176
|
type ClientSettableMetadata,
|
|
177
|
+
type ClientUploadTask,
|
|
178
|
+
type ClientUploadTaskSnapshot,
|
|
175
179
|
// Event stream (Pyric Studio keystone — onEvent/history over the port)
|
|
176
180
|
subscribeEvents,
|
|
177
181
|
eventHistory,
|