@pyric/cli 0.1.0-alpha.15 → 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.
Files changed (384) hide show
  1. package/README.md +13 -9
  2. package/dist/assurance/.generated/conformance-verdicts.d.ts +80 -72
  3. package/dist/assurance/.generated/conformance-verdicts.d.ts.map +1 -1
  4. package/dist/assurance/.generated/conformance-verdicts.js +80 -72
  5. package/dist/assurance/.generated/conformance-verdicts.js.map +1 -1
  6. package/dist/bridge/client/dispatch.js +1 -1
  7. package/dist/bridge/client/dispatch.js.map +1 -1
  8. package/dist/cli/database-rules.d.ts.map +1 -1
  9. package/dist/cli/database-rules.js +6 -4
  10. package/dist/cli/database-rules.js.map +1 -1
  11. package/dist/cli/dev-runner.d.ts +9 -0
  12. package/dist/cli/dev-runner.d.ts.map +1 -1
  13. package/dist/cli/dev-runner.js +18 -0
  14. package/dist/cli/dev-runner.js.map +1 -1
  15. package/dist/cli/serve.d.ts.map +1 -1
  16. package/dist/cli/serve.js +61 -6
  17. package/dist/cli/serve.js.map +1 -1
  18. package/dist/cli/verify.js +2 -2
  19. package/dist/cli/verify.js.map +1 -1
  20. package/dist/conformance/.generated/can-i-use-browser.d.ts.map +1 -1
  21. package/dist/conformance/.generated/can-i-use-browser.js +1 -1
  22. package/dist/conformance/.generated/can-i-use-browser.js.map +1 -1
  23. package/dist/conformance/.generated/can-i-use.d.ts.map +1 -1
  24. package/dist/conformance/.generated/can-i-use.js +1 -1
  25. package/dist/conformance/.generated/can-i-use.js.map +1 -1
  26. package/dist/conformance/.generated/conformance-docs.d.ts.map +1 -1
  27. package/dist/conformance/.generated/conformance-docs.js +1 -1
  28. package/dist/conformance/.generated/conformance-docs.js.map +1 -1
  29. package/dist/next/client-aliases.d.ts +11 -0
  30. package/dist/next/client-aliases.d.ts.map +1 -0
  31. package/dist/next/client-aliases.js +38 -0
  32. package/dist/next/client-aliases.js.map +1 -0
  33. package/dist/next/dev-rewrites.d.ts +9 -0
  34. package/dist/next/dev-rewrites.d.ts.map +1 -0
  35. package/dist/next/dev-rewrites.js +53 -0
  36. package/dist/next/dev-rewrites.js.map +1 -0
  37. package/dist/next/guard.d.ts +15 -0
  38. package/dist/next/guard.d.ts.map +1 -0
  39. package/dist/next/guard.js +52 -0
  40. package/dist/next/guard.js.map +1 -0
  41. package/dist/next/index.d.ts +12 -0
  42. package/dist/next/index.d.ts.map +1 -0
  43. package/dist/next/index.js +11 -0
  44. package/dist/next/index.js.map +1 -0
  45. package/dist/next/runtime-env.d.ts +7 -0
  46. package/dist/next/runtime-env.d.ts.map +1 -0
  47. package/dist/next/runtime-env.js +13 -0
  48. package/dist/next/runtime-env.js.map +1 -0
  49. package/dist/next/server-external-packages.d.ts +10 -0
  50. package/dist/next/server-external-packages.d.ts.map +1 -0
  51. package/dist/next/server-external-packages.js +34 -0
  52. package/dist/next/server-external-packages.js.map +1 -0
  53. package/dist/next/target-url.d.ts +11 -0
  54. package/dist/next/target-url.d.ts.map +1 -0
  55. package/dist/next/target-url.js +36 -0
  56. package/dist/next/target-url.js.map +1 -0
  57. package/dist/next/turbopack-config.d.ts +9 -0
  58. package/dist/next/turbopack-config.d.ts.map +1 -0
  59. package/dist/next/turbopack-config.js +39 -0
  60. package/dist/next/turbopack-config.js.map +1 -0
  61. package/dist/next/types.d.ts +40 -0
  62. package/dist/next/types.d.ts.map +1 -0
  63. package/dist/next/types.js +5 -0
  64. package/dist/next/types.js.map +1 -0
  65. package/dist/next/webpack-config.d.ts +11 -0
  66. package/dist/next/webpack-config.d.ts.map +1 -0
  67. package/dist/next/webpack-config.js +51 -0
  68. package/dist/next/webpack-config.js.map +1 -0
  69. package/dist/next/with-pyric.d.ts +22 -0
  70. package/dist/next/with-pyric.d.ts.map +1 -0
  71. package/dist/next/with-pyric.js +49 -0
  72. package/dist/next/with-pyric.js.map +1 -0
  73. package/dist/register/app-bridge.d.ts +9 -0
  74. package/dist/register/app-bridge.d.ts.map +1 -0
  75. package/dist/register/app-bridge.js +56 -0
  76. package/dist/register/app-bridge.js.map +1 -0
  77. package/dist/register/hooks.d.ts.map +1 -1
  78. package/dist/register/hooks.js +6 -1
  79. package/dist/register/hooks.js.map +1 -1
  80. package/dist/register/index.js +1 -1
  81. package/dist/register/index.js.map +1 -1
  82. package/dist/register/mapping.d.ts +3 -1
  83. package/dist/register/mapping.d.ts.map +1 -1
  84. package/dist/register/mapping.js +41 -5
  85. package/dist/register/mapping.js.map +1 -1
  86. package/dist/rtdb/rules-json.d.ts +12 -0
  87. package/dist/rtdb/rules-json.d.ts.map +1 -1
  88. package/dist/rtdb/rules-json.js +98 -0
  89. package/dist/rtdb/rules-json.js.map +1 -1
  90. package/dist/serve/bundler.d.ts.map +1 -1
  91. package/dist/serve/bundler.js +2 -0
  92. package/dist/serve/bundler.js.map +1 -1
  93. package/dist/serve/discovery.d.ts +4 -4
  94. package/dist/serve/discovery.d.ts.map +1 -1
  95. package/dist/serve/discovery.js +59 -38
  96. package/dist/serve/discovery.js.map +1 -1
  97. package/dist/serve/entries/app-ai-passthrough.d.ts +8 -0
  98. package/dist/serve/entries/app-ai-passthrough.d.ts.map +1 -0
  99. package/dist/serve/entries/app-ai-passthrough.js +59 -0
  100. package/dist/serve/entries/app-ai-passthrough.js.map +1 -0
  101. package/dist/serve/entries/auth-helper-core.d.ts +9 -0
  102. package/dist/serve/entries/auth-helper-core.d.ts.map +1 -1
  103. package/dist/serve/entries/auth-helper-core.js +37 -8
  104. package/dist/serve/entries/auth-helper-core.js.map +1 -1
  105. package/dist/serve/entries/auth.d.ts +1 -0
  106. package/dist/serve/entries/auth.d.ts.map +1 -1
  107. package/dist/serve/entries/auth.js +7 -4
  108. package/dist/serve/entries/auth.js.map +1 -1
  109. package/dist/serve/entries/bridge-url.d.ts.map +1 -1
  110. package/dist/serve/entries/bridge-url.js +7 -2
  111. package/dist/serve/entries/bridge-url.js.map +1 -1
  112. package/dist/serve/entries/database.d.ts +1 -0
  113. package/dist/serve/entries/database.d.ts.map +1 -1
  114. package/dist/serve/entries/database.js +1 -0
  115. package/dist/serve/entries/database.js.map +1 -1
  116. package/dist/serve/entries/firestore.d.ts +1 -0
  117. package/dist/serve/entries/firestore.d.ts.map +1 -1
  118. package/dist/serve/entries/firestore.js +1 -0
  119. package/dist/serve/entries/firestore.js.map +1 -1
  120. package/dist/serve/entries/init.d.ts.map +1 -1
  121. package/dist/serve/entries/init.js +4 -2
  122. package/dist/serve/entries/init.js.map +1 -1
  123. package/dist/serve/entries/runtime.js +23 -0
  124. package/dist/serve/entries/runtime.js.map +1 -1
  125. package/dist/serve/entries/storage.d.ts +2 -0
  126. package/dist/serve/entries/storage.d.ts.map +1 -1
  127. package/dist/serve/entries/storage.js +9 -2
  128. package/dist/serve/entries/storage.js.map +1 -1
  129. package/dist/serve/html-injection.d.ts +3 -1
  130. package/dist/serve/html-injection.d.ts.map +1 -1
  131. package/dist/serve/html-injection.js +27 -1
  132. package/dist/serve/html-injection.js.map +1 -1
  133. package/dist/serve/rules.js +2 -2
  134. package/dist/serve/rules.js.map +1 -1
  135. package/dist/serve/runtime/chip-config.d.ts +1 -1
  136. package/dist/serve/runtime/chip-config.d.ts.map +1 -1
  137. package/dist/serve/runtime/chip-config.js +16 -8
  138. package/dist/serve/runtime/chip-config.js.map +1 -1
  139. package/dist/serve/sandbox-session.d.ts +1 -0
  140. package/dist/serve/sandbox-session.d.ts.map +1 -1
  141. package/dist/serve/sandbox-session.js +30 -2
  142. package/dist/serve/sandbox-session.js.map +1 -1
  143. package/dist/serve/site-ui/_astro/_studio_.B6b_G1ev.css +1 -0
  144. package/dist/serve/site-ui/_astro/app.bnmVTkIY.js +11 -0
  145. package/dist/serve/site-ui/_astro/app.t6u-adB_.js +1 -0
  146. package/dist/serve/site-ui/_astro/{chess-showcase.DzPO6kz0.js → chess-showcase.kC8dXLKY.js} +1 -1
  147. package/dist/serve/site-ui/_astro/{example-runtime.CM0H02rx.js → example-runtime.D79PnoSk.js} +1 -1
  148. package/dist/serve/site-ui/_astro/index.DzVde04M.js +1 -0
  149. package/dist/serve/site-ui/_astro/reads.BYBRLbsE.js +1 -0
  150. package/dist/serve/site-ui/_astro/sandbox-controls.C9Aaazt8.js +1252 -0
  151. package/dist/serve/site-ui/_astro/{seed.BCn5DhHS.js → seed.DANAIyRw.js} +1 -1
  152. package/dist/serve/site-ui/auth/index.html +2 -2
  153. package/dist/serve/site-ui/docs/_rhythm/index.html +1 -1
  154. package/dist/serve/site-ui/docs/agent/set-up-your-agent/index.html +1 -1
  155. package/dist/serve/site-ui/docs/agent/watch-and-review/index.html +1 -1
  156. package/dist/serve/site-ui/docs/agent/work-with-an-agent/index.html +1 -1
  157. package/dist/serve/site-ui/docs/ai-compat/index.html +85 -85
  158. package/dist/serve/site-ui/docs/ai-compat.md +84 -84
  159. package/dist/serve/site-ui/docs/api-reference/index.html +3 -1
  160. package/dist/serve/site-ui/docs/api-reference.md +2 -0
  161. package/dist/serve/site-ui/docs/app-compat/index.html +28 -28
  162. package/dist/serve/site-ui/docs/app-compat.md +27 -27
  163. package/dist/serve/site-ui/docs/auth-compat/index.html +122 -122
  164. package/dist/serve/site-ui/docs/auth-compat.md +121 -121
  165. package/dist/serve/site-ui/docs/build/ai-logic/index.html +1 -1
  166. package/dist/serve/site-ui/docs/build/authentication/index.html +1 -1
  167. package/dist/serve/site-ui/docs/build/cloud-firestore/index.html +1 -1
  168. package/dist/serve/site-ui/docs/build/cloud-messaging/index.html +1 -1
  169. package/dist/serve/site-ui/docs/build/cloud-storage/index.html +1 -1
  170. package/dist/serve/site-ui/docs/build/realtime-database/index.html +1 -1
  171. package/dist/serve/site-ui/docs/conformance-scores/index.html +4 -4
  172. package/dist/serve/site-ui/docs/conformance-scores.md +3 -3
  173. package/dist/serve/site-ui/docs/create-pyric-reference-api/index.html +6 -6
  174. package/dist/serve/site-ui/docs/create-pyric-reference-api.md +5 -5
  175. package/dist/serve/site-ui/docs/database-compat/index.html +200 -448
  176. package/dist/serve/site-ui/docs/database-compat.md +198 -461
  177. package/dist/serve/site-ui/docs/examples/chess/index.html +2 -2
  178. package/dist/serve/site-ui/docs/examples/index.html +1 -1
  179. package/dist/serve/site-ui/docs/firestore-compat/index.html +186 -195
  180. package/dist/serve/site-ui/docs/firestore-compat.md +184 -195
  181. package/dist/serve/site-ui/docs/functions-rtdb-compat/index.html +15 -15
  182. package/dist/serve/site-ui/docs/functions-rtdb-compat.md +14 -14
  183. package/dist/serve/site-ui/docs/get-started/how-the-swap-works/index.html +1 -1
  184. package/dist/serve/site-ui/docs/get-started/nextjs/index.html +57 -0
  185. package/dist/serve/site-ui/docs/get-started/nextjs.md +86 -0
  186. package/dist/serve/site-ui/docs/get-started/start-building/index.html +25 -8
  187. package/dist/serve/site-ui/docs/get-started/start-building.md +34 -5
  188. package/dist/serve/site-ui/docs/get-started/vite/index.html +26 -0
  189. package/dist/serve/site-ui/docs/get-started/vite.md +45 -0
  190. package/dist/serve/site-ui/docs/index.json +668 -103
  191. package/dist/serve/site-ui/docs/messaging-compat/index.html +56 -56
  192. package/dist/serve/site-ui/docs/messaging-compat.md +55 -55
  193. package/dist/serve/site-ui/docs/observe/resolve-runtime-status/index.html +1 -1
  194. package/dist/serve/site-ui/docs/observe/see-whats-happening/index.html +1 -1
  195. package/dist/serve/site-ui/docs/observe/shape-your-data/index.html +1 -1
  196. package/dist/serve/site-ui/docs/overview/index.html +1 -1
  197. package/dist/serve/site-ui/docs/pyric-admin-app-reference-api/index.html +39 -13
  198. package/dist/serve/site-ui/docs/pyric-admin-app-reference-api.md +28 -2
  199. package/dist/serve/site-ui/docs/pyric-admin-auth-reference-api/index.html +1 -1
  200. package/dist/serve/site-ui/docs/pyric-admin-database-reference-api/index.html +38 -6
  201. package/dist/serve/site-ui/docs/pyric-admin-database-reference-api.md +43 -0
  202. package/dist/serve/site-ui/docs/pyric-admin-firestore-reference-api/index.html +9 -1
  203. package/dist/serve/site-ui/docs/pyric-admin-firestore-reference-api.md +8 -0
  204. package/dist/serve/site-ui/docs/pyric-admin-messaging-reference-api/index.html +1 -1
  205. package/dist/serve/site-ui/docs/pyric-admin-storage-reference-api/index.html +27 -4
  206. package/dist/serve/site-ui/docs/pyric-admin-storage-reference-api.md +23 -0
  207. package/dist/serve/site-ui/docs/pyric-ai-reference-api/index.html +1 -1
  208. package/dist/serve/site-ui/docs/pyric-ai-scripting-reference-api/index.html +1 -1
  209. package/dist/serve/site-ui/docs/pyric-app-reference-api/index.html +1 -1
  210. package/dist/serve/site-ui/docs/pyric-auth-reference-api/index.html +2 -2
  211. package/dist/serve/site-ui/docs/pyric-auth-reference-api.md +1 -1
  212. package/dist/serve/site-ui/docs/pyric-cli-assurance-browser-reference-api/index.html +1 -1
  213. package/dist/serve/site-ui/docs/pyric-cli-assurance-reference-api/index.html +1 -1
  214. package/dist/serve/site-ui/docs/pyric-cli-bridge-client-reference-api/index.html +1 -1
  215. package/dist/serve/site-ui/docs/pyric-cli-bridge-reference-api/index.html +1 -1
  216. package/dist/serve/site-ui/docs/pyric-cli-conformance-browser-reference-api/index.html +1 -1
  217. package/dist/serve/site-ui/docs/pyric-cli-conformance-docs-reference-api/index.html +1 -1
  218. package/dist/serve/site-ui/docs/pyric-cli-conformance-reference-api/index.html +1 -1
  219. package/dist/serve/site-ui/docs/pyric-cli-credentials-node-reference-api/index.html +1 -1
  220. package/dist/serve/site-ui/docs/pyric-cli-discover-reference-api/index.html +1 -1
  221. package/dist/serve/site-ui/docs/pyric-cli-next-reference-api/index.html +123 -0
  222. package/dist/serve/site-ui/docs/pyric-cli-next-reference-api.md +99 -0
  223. package/dist/serve/site-ui/docs/pyric-cli-register-app-bridge-reference-api/index.html +127 -0
  224. package/dist/serve/site-ui/docs/pyric-cli-register-app-bridge-reference-api.md +174 -0
  225. package/dist/serve/site-ui/docs/pyric-cli-register-reference-api/index.html +1 -1
  226. package/dist/serve/site-ui/docs/pyric-cli-remote-reference-api/index.html +1 -1
  227. package/dist/serve/site-ui/docs/pyric-cli-serve-worker-reference-api/index.html +570 -326
  228. package/dist/serve/site-ui/docs/pyric-cli-serve-worker-reference-api.md +198 -6
  229. package/dist/serve/site-ui/docs/pyric-cli-verify-reference-api/index.html +1 -1
  230. package/dist/serve/site-ui/docs/pyric-cli-vite-reference-api/index.html +1 -1
  231. package/dist/serve/site-ui/docs/pyric-database-reference-api/index.html +1 -1
  232. package/dist/serve/site-ui/docs/pyric-firestore-reference-api/index.html +2971 -627
  233. package/dist/serve/site-ui/docs/pyric-firestore-reference-api.md +2873 -517
  234. package/dist/serve/site-ui/docs/pyric-messaging-reference-api/index.html +1 -1
  235. package/dist/serve/site-ui/docs/pyric-messaging-sw-reference-api/index.html +1 -1
  236. package/dist/serve/site-ui/docs/pyric-rules-reference-api/index.html +43 -3
  237. package/dist/serve/site-ui/docs/pyric-rules-reference-api.md +8 -0
  238. package/dist/serve/site-ui/docs/pyric-sandbox-database-reference-api/index.html +26 -2
  239. package/dist/serve/site-ui/docs/pyric-sandbox-database-reference-api.md +24 -0
  240. package/dist/serve/site-ui/docs/pyric-sandbox-firestore-reference-api/index.html +1 -1
  241. package/dist/serve/site-ui/docs/pyric-sandbox-reference-api/index.html +77 -9
  242. package/dist/serve/site-ui/docs/pyric-sandbox-reference-api.md +28 -13
  243. package/dist/serve/site-ui/docs/pyric-storage-reference-api/index.html +240 -63
  244. package/dist/serve/site-ui/docs/pyric-storage-reference-api.md +164 -5
  245. package/dist/serve/site-ui/docs/pyric-ui-agents-reference-api/index.html +1 -1
  246. package/dist/serve/site-ui/docs/pyric-ui-auth-hooks-reference-api/index.html +1 -1
  247. package/dist/serve/site-ui/docs/pyric-ui-auth-reference-api/index.html +1 -1
  248. package/dist/serve/site-ui/docs/pyric-ui-events-hooks-reference-api/index.html +1 -1
  249. package/dist/serve/site-ui/docs/pyric-ui-events-reference-api/index.html +1 -1
  250. package/dist/serve/site-ui/docs/pyric-ui-firestore-hooks-reference-api/index.html +1 -1
  251. package/dist/serve/site-ui/docs/pyric-ui-firestore-reference-api/index.html +1 -1
  252. package/dist/serve/site-ui/docs/pyric-ui-primitives-reference-api/index.html +1 -1
  253. package/dist/serve/site-ui/docs/pyric-ui-rtdb-reference-api/index.html +1 -1
  254. package/dist/serve/site-ui/docs/pyric-ui-rules-hooks-reference-api/index.html +1 -1
  255. package/dist/serve/site-ui/docs/pyric-ui-rules-reference-api/index.html +1 -1
  256. package/dist/serve/site-ui/docs/pyric-ui-storage-hooks-reference-api/index.html +1 -1
  257. package/dist/serve/site-ui/docs/pyric-ui-storage-reference-api/index.html +2 -1
  258. package/dist/serve/site-ui/docs/pyric-ui-storage-reference-api.md +1 -0
  259. package/dist/serve/site-ui/docs/pyric-ui-traffic-hooks-reference-api/index.html +1 -1
  260. package/dist/serve/site-ui/docs/pyric-ui-traffic-reference-api/index.html +1 -1
  261. package/dist/serve/site-ui/docs/rules-compat/index.html +87 -79
  262. package/dist/serve/site-ui/docs/rules-compat.md +86 -78
  263. package/dist/serve/site-ui/docs/secure/audit-your-rules/index.html +1 -1
  264. package/dist/serve/site-ui/docs/secure/firestore-rules-limits/index.html +1 -1
  265. package/dist/serve/site-ui/docs/secure/read-a-denial/index.html +1 -1
  266. package/dist/serve/site-ui/docs/secure/rtdb-rules-in-typescript/index.html +1 -1
  267. package/dist/serve/site-ui/docs/secure/rules-standard-library/index.html +1 -1
  268. package/dist/serve/site-ui/docs/secure/secure-it-with-rules/index.html +1 -1
  269. package/dist/serve/site-ui/docs/secure/simulate-and-lint/index.html +1 -1
  270. package/dist/serve/site-ui/docs/secure/write-a-rules-test-suite/index.html +1 -1
  271. package/dist/serve/site-ui/docs/ship/ship-to-production/index.html +1 -1
  272. package/dist/serve/site-ui/docs/ship/test-in-node/index.html +1 -1
  273. package/dist/serve/site-ui/docs/storage-compat/index.html +119 -125
  274. package/dist/serve/site-ui/docs/storage-compat.md +118 -124
  275. package/dist/serve/site-ui/docs/trust/how-we-know-it-matches-firebase/index.html +1 -1
  276. package/dist/serve/site-ui/docs/trust/rules-standard-library/index.html +1 -1
  277. package/dist/serve/site-ui/docs/trust/storage-rules-stdlib-research/index.html +1 -1
  278. package/dist/serve/site-ui/docs/trust/versioning-and-compatibility/index.html +1 -1
  279. package/dist/serve/site-ui/docs/tutorial/index.html +1 -1
  280. package/dist/serve/site-ui/examples/chess/index.html +1 -1
  281. package/dist/serve/site-ui/examples/firestore-first-write/index.html +1 -1
  282. package/dist/serve/site-ui/firestore/index.html +2 -2
  283. package/dist/serve/site-ui/index.html +2 -2
  284. package/dist/serve/site-ui/llms.txt +6 -2
  285. package/dist/serve/site-ui/rtdb/index.html +2 -2
  286. package/dist/serve/site-ui/settings/index.html +2 -2
  287. package/dist/serve/site-ui/storage/index.html +2 -2
  288. package/dist/serve/site-ui/traffic/index.html +2 -2
  289. package/dist/serve/vite-ai-config.d.ts +4 -1
  290. package/dist/serve/vite-ai-config.d.ts.map +1 -1
  291. package/dist/serve/vite-ai-config.js +83 -19
  292. package/dist/serve/vite-ai-config.js.map +1 -1
  293. package/dist/serve/vite-generation-rules-watch.d.ts.map +1 -1
  294. package/dist/serve/vite-generation-rules-watch.js +61 -14
  295. package/dist/serve/vite-generation-rules-watch.js.map +1 -1
  296. package/dist/serve/vite-module-swap.d.ts +4 -1
  297. package/dist/serve/vite-module-swap.d.ts.map +1 -1
  298. package/dist/serve/vite-module-swap.js +106 -21
  299. package/dist/serve/vite-module-swap.js.map +1 -1
  300. package/dist/serve/vite-plugin.d.ts.map +1 -1
  301. package/dist/serve/vite-plugin.js +45 -5
  302. package/dist/serve/vite-plugin.js.map +1 -1
  303. package/dist/serve/vite-sandbox-generation.js +1 -1
  304. package/dist/serve/vite-sandbox-generation.js.map +1 -1
  305. package/dist/serve/worker/client/resumable.d.ts +30 -0
  306. package/dist/serve/worker/client/resumable.d.ts.map +1 -0
  307. package/dist/serve/worker/client/resumable.js +416 -0
  308. package/dist/serve/worker/client/resumable.js.map +1 -0
  309. package/dist/serve/worker/client/rtdb-references.d.ts.map +1 -1
  310. package/dist/serve/worker/client/rtdb-references.js +4 -1
  311. package/dist/serve/worker/client/rtdb-references.js.map +1 -1
  312. package/dist/serve/worker/client/storage.d.ts +16 -2
  313. package/dist/serve/worker/client/storage.d.ts.map +1 -1
  314. package/dist/serve/worker/client/storage.js +57 -6
  315. package/dist/serve/worker/client/storage.js.map +1 -1
  316. package/dist/serve/worker/host/rules.d.ts.map +1 -1
  317. package/dist/serve/worker/host/rules.js +2 -1
  318. package/dist/serve/worker/host/rules.js.map +1 -1
  319. package/dist/serve/worker/index.d.ts +1 -1
  320. package/dist/serve/worker/index.d.ts.map +1 -1
  321. package/dist/serve/worker/index.js +1 -1
  322. package/dist/serve/worker/index.js.map +1 -1
  323. package/dist/serve/worker/serve-init.d.ts.map +1 -1
  324. package/dist/serve/worker/serve-init.js +31 -0
  325. package/dist/serve/worker/serve-init.js.map +1 -1
  326. package/package.json +15 -4
  327. package/src/assurance/.generated/conformance-verdicts.ts +80 -72
  328. package/src/bridge/client/dispatch.ts +1 -1
  329. package/src/cli/cli.test.ts +14 -0
  330. package/src/cli/database-rules.ts +6 -4
  331. package/src/cli/dev-runner.ts +21 -0
  332. package/src/cli/serve.ts +62 -5
  333. package/src/cli/verify.ts +2 -2
  334. package/src/conformance/.generated/can-i-use-browser.ts +1 -1
  335. package/src/conformance/.generated/can-i-use.ts +1 -1
  336. package/src/conformance/.generated/conformance-docs.ts +1 -1
  337. package/src/next/client-aliases.ts +39 -0
  338. package/src/next/dev-rewrites.ts +77 -0
  339. package/src/next/guard.ts +61 -0
  340. package/src/next/index.ts +16 -0
  341. package/src/next/runtime-env.ts +18 -0
  342. package/src/next/server-external-packages.ts +43 -0
  343. package/src/next/target-url.ts +46 -0
  344. package/src/next/turbopack-config.ts +54 -0
  345. package/src/next/types.ts +47 -0
  346. package/src/next/webpack-config.ts +71 -0
  347. package/src/next/with-pyric.ts +58 -0
  348. package/src/register/app-bridge.ts +79 -0
  349. package/src/register/hooks.ts +6 -1
  350. package/src/register/index.ts +1 -1
  351. package/src/register/mapping.ts +50 -4
  352. package/src/rtdb/rules-json.ts +110 -0
  353. package/src/serve/bundler.ts +2 -0
  354. package/src/serve/discovery.ts +65 -44
  355. package/src/serve/entries/app-ai-passthrough.ts +83 -0
  356. package/src/serve/entries/auth-helper-core.ts +44 -8
  357. package/src/serve/entries/auth.ts +9 -4
  358. package/src/serve/entries/bridge-url.ts +9 -2
  359. package/src/serve/entries/database.ts +1 -0
  360. package/src/serve/entries/firestore.ts +1 -0
  361. package/src/serve/entries/init.ts +5 -2
  362. package/src/serve/entries/runtime.ts +25 -0
  363. package/src/serve/entries/storage.ts +12 -1
  364. package/src/serve/html-injection.ts +26 -1
  365. package/src/serve/rules.ts +2 -2
  366. package/src/serve/runtime/chip-config.ts +19 -6
  367. package/src/serve/sandbox-session.ts +31 -2
  368. package/src/serve/vite-ai-config.ts +86 -19
  369. package/src/serve/vite-generation-rules-watch.ts +67 -15
  370. package/src/serve/vite-module-swap.ts +121 -21
  371. package/src/serve/vite-plugin.ts +44 -6
  372. package/src/serve/vite-sandbox-generation.ts +1 -1
  373. package/src/serve/worker/client/resumable.ts +506 -0
  374. package/src/serve/worker/client/rtdb-references.ts +4 -1
  375. package/src/serve/worker/client/storage.ts +77 -7
  376. package/src/serve/worker/host/rules.ts +2 -1
  377. package/src/serve/worker/index.ts +4 -0
  378. package/src/serve/worker/serve-init.ts +30 -0
  379. package/dist/serve/site-ui/_astro/_studio_.BtYpqe1A.css +0 -1
  380. package/dist/serve/site-ui/_astro/app.BnMC0ywl.js +0 -109
  381. package/dist/serve/site-ui/_astro/app.DVXXR-WI.js +0 -1
  382. package/dist/serve/site-ui/_astro/index.B4Kh80he.js +0 -1
  383. package/dist/serve/site-ui/_astro/reads.D1exkX1-.js +0 -1
  384. package/dist/serve/site-ui/_astro/sandbox-controls.BqMePr5V.js +0 -1153
@@ -39,6 +39,8 @@
39
39
  * to the in-page sandbox (single-tab, ephemeral).
40
40
  */
41
41
  import type { Plugin, UserConfig } from 'vite';
42
+ import { existsSync } from 'node:fs';
43
+ import { dirname, join, resolve } from 'node:path';
42
44
  import { createViteWorkerRuntime } from './vite-worker-runtime.js';
43
45
  import type { PyricAiOptions } from './vite-ai-config.js';
44
46
  import type { PyricRuntimeChipOption } from './runtime/chip-config.js';
@@ -157,6 +159,29 @@ function resolveFunctionsOptions(
157
159
  return {};
158
160
  }
159
161
 
162
+ /**
163
+ * Resolves the Firebase project root directory from Vite's server root. In
164
+ * split-directory or full-stack monorepo layouts where Vite operates inside a
165
+ * subdirectory (e.g. `/web` or `/frontend`) while hosting and security rules
166
+ * configuration (`firebase.json`) resides in an ancestor workspace directory,
167
+ * this ascends to locate the authoritative configuration root.
168
+ */
169
+ function resolveFirebaseProjectDir(defaultRoot: string, explicitRoot?: string): string {
170
+ const hasExplicitRoot = explicitRoot !== undefined && explicitRoot.length > 0;
171
+ if (hasExplicitRoot) return explicitRoot as string;
172
+ let current = resolve(defaultRoot);
173
+ while (true) {
174
+ const candidateConfig = join(current, 'firebase.json');
175
+ const configExists = existsSync(candidateConfig);
176
+ if (configExists) return current;
177
+ const parent = dirname(current);
178
+ const isRootOfFilesystem = parent === current;
179
+ if (isRootOfFilesystem) break;
180
+ current = parent;
181
+ }
182
+ return defaultRoot;
183
+ }
184
+
160
185
  /**
161
186
  * The dev-only Vite plugin. Add to `vite.config`:
162
187
  *
@@ -165,7 +190,6 @@ function resolveFunctionsOptions(
165
190
  */
166
191
  export function pyric(options: PyricOptions = {}): Plugin {
167
192
  const moduleContext = createViteModuleContext();
168
- const moduleSwap = createViteModuleSwap(moduleContext);
169
193
  const { entries, cliRoot } = moduleContext;
170
194
  const workerRuntime = createViteWorkerRuntime();
171
195
  const studioEnabled = options.ui !== false;
@@ -176,6 +200,9 @@ export function pyric(options: PyricOptions = {}): Plugin {
176
200
  workerRuntime,
177
201
  };
178
202
  const pageRuntime = createVitePageRuntime(pageRuntimeInput);
203
+ const moduleSwap = createViteModuleSwap(moduleContext, {
204
+ getAiMode: () => pageRuntime.ai().mode,
205
+ });
179
206
 
180
207
  // Normalize the public bridge shorthand once. The active generation owns the
181
208
  // bridge/session attachment and routes the peer through the SharedWorker.
@@ -197,10 +224,21 @@ export function pyric(options: PyricOptions = {}): Plugin {
197
224
  enforce: 'pre',
198
225
 
199
226
  config(config, env) {
200
- return {
201
- ...moduleSwap.config(),
202
- ...pageRuntime.config(config, env),
203
- } as UserConfig;
227
+ const moduleConfig = moduleSwap.config();
228
+ const pageConfig = pageRuntime.config(config, env);
229
+ const serverWatchConfig: UserConfig = {
230
+ server: {
231
+ watch: {
232
+ ignored: ['**/.pyric/**'],
233
+ },
234
+ },
235
+ };
236
+ const finalizedConfig: UserConfig = {
237
+ ...moduleConfig,
238
+ ...pageConfig,
239
+ ...serverWatchConfig,
240
+ };
241
+ return finalizedConfig;
204
242
  },
205
243
 
206
244
  configResolved(resolved) {
@@ -220,7 +258,7 @@ export function pyric(options: PyricOptions = {}): Plugin {
220
258
  activeGeneration = null;
221
259
  await priorGeneration?.close();
222
260
 
223
- const projectDir = options.root ?? server.config.root;
261
+ const projectDir = resolveFirebaseProjectDir(server.config.root, options.root);
224
262
  const uiEnabled = options.ui ?? true;
225
263
  const functionsOptions = resolveFunctionsOptions(options.functions);
226
264
  const ai = pageRuntime.ai();
@@ -134,7 +134,7 @@ export async function createViteSandboxGeneration(
134
134
  const rulesConfig = dependencies.resolveRulesConfig(cwd, options.rules, firebaseConfig);
135
135
 
136
136
  try {
137
- const epochSalt = viteWorkerEpochSalt(cwd, ai.engineWire);
137
+ const epochSalt = viteWorkerEpochSalt(cwd, ai.engineWire, ai.mode);
138
138
  await dependencies.prepareWorker(workerRuntime, epochSalt);
139
139
  } catch (error) {
140
140
  server.config.logger.warn(
@@ -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
- if ((!allowEmpty && path.length === 0) || /[.#$[\]]/.test(path)) {
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
  );