@pyric/cli 0.1.0-alpha.10 → 0.1.0-alpha.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (498) hide show
  1. package/README.md.orig +2 -2
  2. package/dist/assurance/.generated/conformance-verdicts.d.ts +16 -0
  3. package/dist/assurance/.generated/conformance-verdicts.d.ts.map +1 -1
  4. package/dist/assurance/.generated/conformance-verdicts.js +16 -0
  5. package/dist/assurance/.generated/conformance-verdicts.js.map +1 -1
  6. package/dist/bridge/server/peer.d.ts +1 -1
  7. package/dist/bridge/server.d.ts +1 -1
  8. package/dist/bridge/server.js +1 -1
  9. package/dist/cli/index.d.ts +11 -0
  10. package/dist/cli/index.d.ts.map +1 -1
  11. package/dist/cli/index.js +13 -1
  12. package/dist/cli/index.js.map +1 -1
  13. package/dist/cli/init.d.ts +3 -3
  14. package/dist/cli/init.d.ts.map +1 -1
  15. package/dist/cli/init.js +5 -5
  16. package/dist/cli/init.js.map +1 -1
  17. package/dist/cli/serve.d.ts.map +1 -1
  18. package/dist/cli/serve.js +8 -2
  19. package/dist/cli/serve.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 +2 -2
  25. package/dist/conformance/.generated/can-i-use.js.map +1 -1
  26. package/dist/conformance/.generated/conformance-docs.d.ts +12 -0
  27. package/dist/conformance/.generated/conformance-docs.d.ts.map +1 -0
  28. package/dist/conformance/.generated/conformance-docs.js +2 -0
  29. package/dist/conformance/.generated/conformance-docs.js.map +1 -0
  30. package/dist/conformance/docs.d.ts +6 -0
  31. package/dist/conformance/docs.d.ts.map +1 -0
  32. package/dist/conformance/docs.js +6 -0
  33. package/dist/conformance/docs.js.map +1 -0
  34. package/dist/remote/index.d.ts.map +1 -1
  35. package/dist/remote/index.js +1 -0
  36. package/dist/remote/index.js.map +1 -1
  37. package/dist/serve/activity-guard.d.ts +4 -0
  38. package/dist/serve/activity-guard.d.ts.map +1 -0
  39. package/dist/serve/activity-guard.js +22 -0
  40. package/dist/serve/activity-guard.js.map +1 -0
  41. package/dist/serve/activity-route.d.ts +4 -0
  42. package/dist/serve/activity-route.d.ts.map +1 -0
  43. package/dist/serve/activity-route.js +157 -0
  44. package/dist/serve/activity-route.js.map +1 -0
  45. package/dist/serve/activity-warning.d.ts +4 -0
  46. package/dist/serve/activity-warning.d.ts.map +1 -0
  47. package/dist/serve/activity-warning.js +21 -0
  48. package/dist/serve/activity-warning.js.map +1 -0
  49. package/dist/serve/bridge-mount.d.ts +5 -0
  50. package/dist/serve/bridge-mount.d.ts.map +1 -1
  51. package/dist/serve/bridge-mount.js +1 -0
  52. package/dist/serve/bridge-mount.js.map +1 -1
  53. package/dist/serve/docs-ui/404.html +3 -0
  54. package/dist/serve/docs-ui/_astro/{_slug_.DPUwShm2.css → _slug_.CXh9yTP1.css} +1 -1
  55. package/dist/serve/docs-ui/_astro/_slug_.DUci-duz.css +1 -0
  56. package/dist/serve/docs-ui/docs/_rhythm/index.html +2 -1
  57. package/dist/serve/docs-ui/docs/agent/set-up-your-agent/index.html +3 -2
  58. package/dist/serve/docs-ui/docs/agent/set-up-your-agent.md +1 -1
  59. package/dist/serve/docs-ui/docs/agent/watch-and-review/index.html +2 -1
  60. package/dist/serve/docs-ui/docs/agent/work-with-an-agent/index.html +2 -1
  61. package/dist/serve/docs-ui/docs/ai-compat/index.html +2 -1
  62. package/dist/serve/docs-ui/docs/api-reference/index.html +51 -49
  63. package/dist/serve/docs-ui/docs/api-reference.md +3 -3
  64. package/dist/serve/docs-ui/docs/app-compat/index.html +2 -1
  65. package/dist/serve/docs-ui/docs/auth-compat/index.html +2 -1
  66. package/dist/serve/docs-ui/docs/build/ai-logic/index.html +18 -3
  67. package/dist/serve/docs-ui/docs/build/ai-logic.md +30 -2
  68. package/dist/serve/docs-ui/docs/build/authentication/index.html +2 -1
  69. package/dist/serve/docs-ui/docs/build/authentication.md +1 -1
  70. package/dist/serve/docs-ui/docs/build/cloud-firestore/index.html +2 -1
  71. package/dist/serve/docs-ui/docs/build/cloud-messaging/index.html +46 -2
  72. package/dist/serve/docs-ui/docs/build/cloud-messaging.md +56 -1
  73. package/dist/serve/docs-ui/docs/build/cloud-storage/index.html +2 -1
  74. package/dist/serve/docs-ui/docs/build/cloud-storage.md +1 -1
  75. package/dist/serve/docs-ui/docs/build/realtime-database/index.html +21 -3
  76. package/dist/serve/docs-ui/docs/build/realtime-database.md +25 -1
  77. package/dist/serve/docs-ui/docs/conformance-scores/index.html +2 -1
  78. package/dist/serve/docs-ui/docs/create-pyric-reference-api/index.html +61 -28
  79. package/dist/serve/docs-ui/docs/create-pyric-reference-api.md +65 -20
  80. package/dist/serve/docs-ui/docs/database-compat/index.html +2 -1
  81. package/dist/serve/docs-ui/docs/firestore-compat/index.html +6 -5
  82. package/dist/serve/docs-ui/docs/firestore-compat.md +4 -4
  83. package/dist/serve/docs-ui/docs/functions-rtdb-compat/index.html +2 -1
  84. package/dist/serve/docs-ui/docs/get-started/how-the-swap-works/index.html +2 -1
  85. package/dist/serve/docs-ui/docs/get-started/start-building/index.html +4 -3
  86. package/dist/serve/docs-ui/docs/get-started/start-building.md +2 -2
  87. package/dist/serve/docs-ui/docs/index.json +979 -579
  88. package/dist/serve/docs-ui/docs/messaging-compat/index.html +2 -1
  89. package/dist/serve/docs-ui/docs/observe/see-whats-happening/index.html +2 -1
  90. package/dist/serve/docs-ui/docs/observe/shape-your-data/index.html +2 -1
  91. package/dist/serve/docs-ui/docs/overview/index.html +2 -1
  92. package/dist/serve/docs-ui/docs/pyric-admin-app-reference-api/index.html +5 -4
  93. package/dist/serve/docs-ui/docs/pyric-admin-app-reference-api.md +3 -4
  94. package/dist/serve/docs-ui/docs/pyric-admin-auth-reference-api/index.html +5 -4
  95. package/dist/serve/docs-ui/docs/pyric-admin-auth-reference-api.md +3 -4
  96. package/dist/serve/docs-ui/docs/pyric-admin-database-reference-api/index.html +5 -4
  97. package/dist/serve/docs-ui/docs/pyric-admin-database-reference-api.md +3 -4
  98. package/dist/serve/docs-ui/docs/pyric-admin-firestore-reference-api/index.html +2503 -12
  99. package/dist/serve/docs-ui/docs/pyric-admin-firestore-reference-api.md +2219 -8
  100. package/dist/serve/docs-ui/docs/pyric-admin-messaging-reference-api/index.html +916 -0
  101. package/dist/serve/docs-ui/docs/pyric-admin-messaging-reference-api.md +706 -0
  102. package/dist/serve/docs-ui/docs/pyric-admin-storage-reference-api/index.html +4 -3
  103. package/dist/serve/docs-ui/docs/pyric-admin-storage-reference-api.md +2 -3
  104. package/dist/serve/docs-ui/docs/pyric-ai-reference-api/index.html +16 -11
  105. package/dist/serve/docs-ui/docs/pyric-ai-reference-api.md +14 -13
  106. package/dist/serve/docs-ui/docs/pyric-ai-scripting-reference-api/index.html +4 -3
  107. package/dist/serve/docs-ui/docs/pyric-ai-scripting-reference-api.md +2 -3
  108. package/dist/serve/docs-ui/docs/pyric-app-reference-api/index.html +7 -2
  109. package/dist/serve/docs-ui/docs/pyric-app-reference-api.md +5 -2
  110. package/dist/serve/docs-ui/docs/pyric-auth-reference-api/index.html +23 -12
  111. package/dist/serve/docs-ui/docs/pyric-auth-reference-api.md +15 -12
  112. package/dist/serve/docs-ui/docs/pyric-cli-assurance-browser-reference-api/index.html +10 -48
  113. package/dist/serve/docs-ui/docs/pyric-cli-assurance-browser-reference-api.md +11 -24
  114. package/dist/serve/docs-ui/docs/pyric-cli-assurance-reference-api/index.html +87 -97
  115. package/dist/serve/docs-ui/docs/pyric-cli-assurance-reference-api.md +53 -65
  116. package/dist/serve/docs-ui/docs/pyric-cli-bridge-client-reference-api/index.html +14 -15
  117. package/dist/serve/docs-ui/docs/pyric-cli-bridge-client-reference-api.md +19 -28
  118. package/dist/serve/docs-ui/docs/pyric-cli-bridge-reference-api/index.html +4 -3
  119. package/dist/serve/docs-ui/docs/pyric-cli-bridge-reference-api.md +2 -3
  120. package/dist/serve/docs-ui/docs/pyric-cli-conformance-browser-reference-api/index.html +3 -2
  121. package/dist/serve/docs-ui/docs/pyric-cli-conformance-browser-reference-api.md +1 -2
  122. package/dist/serve/docs-ui/docs/pyric-cli-conformance-docs-reference-api/index.html +51 -0
  123. package/dist/serve/docs-ui/docs/pyric-cli-conformance-docs-reference-api.md +36 -0
  124. package/dist/serve/docs-ui/docs/pyric-cli-conformance-reference-api/index.html +3 -2
  125. package/dist/serve/docs-ui/docs/pyric-cli-conformance-reference-api.md +1 -2
  126. package/dist/serve/docs-ui/docs/pyric-cli-credentials-node-reference-api/index.html +3 -2
  127. package/dist/serve/docs-ui/docs/pyric-cli-credentials-node-reference-api.md +1 -2
  128. package/dist/serve/docs-ui/docs/pyric-cli-discover-reference-api/index.html +3 -2
  129. package/dist/serve/docs-ui/docs/pyric-cli-discover-reference-api.md +1 -2
  130. package/dist/serve/docs-ui/docs/pyric-cli-register-reference-api/index.html +3 -2
  131. package/dist/serve/docs-ui/docs/pyric-cli-register-reference-api.md +1 -2
  132. package/dist/serve/docs-ui/docs/pyric-cli-remote-reference-api/index.html +1067 -83
  133. package/dist/serve/docs-ui/docs/pyric-cli-remote-reference-api.md +1291 -160
  134. package/dist/serve/docs-ui/docs/pyric-cli-serve-worker-reference-api/index.html +253 -157
  135. package/dist/serve/docs-ui/docs/pyric-cli-serve-worker-reference-api.md +179 -85
  136. package/dist/serve/docs-ui/docs/pyric-cli-verify-reference-api/index.html +72 -7
  137. package/dist/serve/docs-ui/docs/pyric-cli-verify-reference-api.md +22 -7
  138. package/dist/serve/docs-ui/docs/pyric-cli-vite-reference-api/index.html +33 -12
  139. package/dist/serve/docs-ui/docs/pyric-cli-vite-reference-api.md +15 -12
  140. package/dist/serve/docs-ui/docs/pyric-database-reference-api/index.html +18 -17
  141. package/dist/serve/docs-ui/docs/pyric-database-reference-api.md +19 -22
  142. package/dist/serve/docs-ui/docs/pyric-firestore-reference-api/index.html +1512 -545
  143. package/dist/serve/docs-ui/docs/pyric-firestore-reference-api.md +1311 -316
  144. package/dist/serve/docs-ui/docs/pyric-messaging-reference-api/index.html +5 -4
  145. package/dist/serve/docs-ui/docs/pyric-messaging-reference-api.md +3 -4
  146. package/dist/serve/docs-ui/docs/pyric-messaging-sw-reference-api/index.html +69 -369
  147. package/dist/serve/docs-ui/docs/pyric-messaging-sw-reference-api.md +103 -216
  148. package/dist/serve/docs-ui/docs/pyric-rules-reference-api/index.html +10 -9
  149. package/dist/serve/docs-ui/docs/pyric-rules-reference-api.md +9 -10
  150. package/dist/serve/docs-ui/docs/pyric-sandbox-database-reference-api/index.html +8 -7
  151. package/dist/serve/docs-ui/docs/pyric-sandbox-database-reference-api.md +6 -7
  152. package/dist/serve/docs-ui/docs/pyric-sandbox-firestore-reference-api/index.html +10 -9
  153. package/dist/serve/docs-ui/docs/pyric-sandbox-firestore-reference-api.md +9 -10
  154. package/dist/serve/docs-ui/docs/pyric-sandbox-reference-api/index.html +371 -884
  155. package/dist/serve/docs-ui/docs/pyric-sandbox-reference-api.md +369 -883
  156. package/dist/serve/docs-ui/docs/pyric-storage-reference-api/index.html +25 -17
  157. package/dist/serve/docs-ui/docs/pyric-storage-reference-api.md +21 -19
  158. package/dist/serve/docs-ui/docs/pyric-ui-agents-reference-api/index.html +3 -2
  159. package/dist/serve/docs-ui/docs/pyric-ui-agents-reference-api.md +1 -2
  160. package/dist/serve/docs-ui/docs/pyric-ui-auth-hooks-reference-api/index.html +63 -776
  161. package/dist/serve/docs-ui/docs/pyric-ui-auth-hooks-reference-api.md +69 -510
  162. package/dist/serve/docs-ui/docs/pyric-ui-auth-reference-api/index.html +22 -21
  163. package/dist/serve/docs-ui/docs/pyric-ui-auth-reference-api.md +29 -30
  164. package/dist/serve/docs-ui/docs/pyric-ui-events-hooks-reference-api/index.html +15 -168
  165. package/dist/serve/docs-ui/docs/pyric-ui-events-hooks-reference-api.md +17 -87
  166. package/dist/serve/docs-ui/docs/pyric-ui-events-reference-api/index.html +6 -5
  167. package/dist/serve/docs-ui/docs/pyric-ui-events-reference-api.md +5 -6
  168. package/dist/serve/docs-ui/docs/pyric-ui-firestore-hooks-reference-api/index.html +82 -970
  169. package/dist/serve/docs-ui/docs/pyric-ui-firestore-hooks-reference-api.md +104 -479
  170. package/dist/serve/docs-ui/docs/pyric-ui-firestore-reference-api/index.html +30 -29
  171. package/dist/serve/docs-ui/docs/pyric-ui-firestore-reference-api.md +54 -55
  172. package/dist/serve/docs-ui/docs/pyric-ui-primitives-reference-api/index.html +3 -2
  173. package/dist/serve/docs-ui/docs/pyric-ui-primitives-reference-api.md +1 -2
  174. package/dist/serve/docs-ui/docs/pyric-ui-rtdb-reference-api/index.html +5 -4
  175. package/dist/serve/docs-ui/docs/pyric-ui-rtdb-reference-api.md +3 -4
  176. package/dist/serve/docs-ui/docs/pyric-ui-rules-hooks-reference-api/index.html +9 -124
  177. package/dist/serve/docs-ui/docs/pyric-ui-rules-hooks-reference-api.md +7 -58
  178. package/dist/serve/docs-ui/docs/pyric-ui-rules-reference-api/index.html +24 -23
  179. package/dist/serve/docs-ui/docs/pyric-ui-rules-reference-api.md +31 -34
  180. package/dist/serve/docs-ui/docs/pyric-ui-storage-hooks-reference-api/index.html +104 -1385
  181. package/dist/serve/docs-ui/docs/pyric-ui-storage-hooks-reference-api.md +133 -817
  182. package/dist/serve/docs-ui/docs/pyric-ui-storage-reference-api/index.html +34 -33
  183. package/dist/serve/docs-ui/docs/pyric-ui-storage-reference-api.md +37 -38
  184. package/dist/serve/docs-ui/docs/pyric-ui-traffic-hooks-reference-api/index.html +116 -1169
  185. package/dist/serve/docs-ui/docs/pyric-ui-traffic-hooks-reference-api.md +142 -590
  186. package/dist/serve/docs-ui/docs/pyric-ui-traffic-reference-api/index.html +4 -3
  187. package/dist/serve/docs-ui/docs/pyric-ui-traffic-reference-api.md +3 -4
  188. package/dist/serve/docs-ui/docs/rules-compat/index.html +34 -1
  189. package/dist/serve/docs-ui/docs/rules-compat.md +32 -0
  190. package/dist/serve/docs-ui/docs/secure/audit-your-rules/index.html +19 -2
  191. package/dist/serve/docs-ui/docs/secure/audit-your-rules.md +32 -0
  192. package/dist/serve/docs-ui/docs/secure/firestore-rules-limits/index.html +2 -1
  193. package/dist/serve/docs-ui/docs/secure/read-a-denial/index.html +2 -1
  194. package/dist/serve/docs-ui/docs/secure/rtdb-rules-in-typescript/index.html +2 -1
  195. package/dist/serve/docs-ui/docs/secure/rtdb-rules-in-typescript.md +1 -1
  196. package/dist/serve/docs-ui/docs/secure/rules-standard-library/index.html +2 -1
  197. package/dist/serve/docs-ui/docs/secure/secure-it-with-rules/index.html +2 -1
  198. package/dist/serve/docs-ui/docs/secure/simulate-and-lint/index.html +2 -1
  199. package/dist/serve/docs-ui/docs/secure/write-a-rules-test-suite/index.html +2 -1
  200. package/dist/serve/docs-ui/docs/ship/ship-to-production/index.html +2 -1
  201. package/dist/serve/docs-ui/docs/ship/test-in-node/index.html +2 -1
  202. package/dist/serve/docs-ui/docs/storage-compat/index.html +2 -1
  203. package/dist/serve/docs-ui/docs/trust/how-we-know-it-matches-firebase/index.html +2 -1
  204. package/dist/serve/docs-ui/docs/trust/versioning-and-compatibility/index.html +2 -1
  205. package/dist/serve/docs-ui/llms.txt +2 -1
  206. package/dist/serve/entries/ai.d.ts.map +1 -1
  207. package/dist/serve/entries/ai.js +39 -1
  208. package/dist/serve/entries/ai.js.map +1 -1
  209. package/dist/serve/entries/messaging-sw.d.ts.map +1 -1
  210. package/dist/serve/entries/messaging-sw.js +5 -1
  211. package/dist/serve/entries/messaging-sw.js.map +1 -1
  212. package/dist/serve/entries/messaging.d.ts.map +1 -1
  213. package/dist/serve/entries/messaging.js +7 -1
  214. package/dist/serve/entries/messaging.js.map +1 -1
  215. package/dist/serve/entries/runtime.d.ts.map +1 -1
  216. package/dist/serve/entries/runtime.js +20 -1
  217. package/dist/serve/entries/runtime.js.map +1 -1
  218. package/dist/serve/init-payload.d.ts +25 -0
  219. package/dist/serve/init-payload.d.ts.map +1 -1
  220. package/dist/serve/namespace.d.ts +39 -0
  221. package/dist/serve/namespace.d.ts.map +1 -1
  222. package/dist/serve/namespace.js +80 -1
  223. package/dist/serve/namespace.js.map +1 -1
  224. package/dist/serve/standalone-assets.d.ts +11 -9
  225. package/dist/serve/standalone-assets.d.ts.map +1 -1
  226. package/dist/serve/standalone-assets.js +6 -5
  227. package/dist/serve/standalone-assets.js.map +1 -1
  228. package/dist/serve/studio-ui/assets/{RulesCodeEditor-CXdSLKhO.js → RulesCodeEditor-CxVYcZXw.js} +1 -1
  229. package/dist/serve/studio-ui/assets/index-cpSfgQ7H.js +1218 -0
  230. package/dist/serve/studio-ui/assets/seed-DeuFKi4J.js +20 -0
  231. package/dist/serve/studio-ui/index.html +1 -1
  232. package/dist/serve/vite-plugin.d.ts +92 -15
  233. package/dist/serve/vite-plugin.d.ts.map +1 -1
  234. package/dist/serve/vite-plugin.js +281 -11
  235. package/dist/serve/vite-plugin.js.map +1 -1
  236. package/dist/serve/worker/activity-bootstrap.d.ts +8 -0
  237. package/dist/serve/worker/activity-bootstrap.d.ts.map +1 -0
  238. package/dist/serve/worker/activity-bootstrap.js +11 -0
  239. package/dist/serve/worker/activity-bootstrap.js.map +1 -0
  240. package/dist/serve/worker/client/connection.d.ts.map +1 -1
  241. package/dist/serve/worker/client/connection.js +17 -5
  242. package/dist/serve/worker/client/connection.js.map +1 -1
  243. package/dist/serve/worker/client/core.d.ts +2 -2
  244. package/dist/serve/worker/client/core.d.ts.map +1 -1
  245. package/dist/serve/worker/client/core.js +33 -5
  246. package/dist/serve/worker/client/core.js.map +1 -1
  247. package/dist/serve/worker/client/firestore-writes.d.ts.map +1 -1
  248. package/dist/serve/worker/client/firestore-writes.js +1 -0
  249. package/dist/serve/worker/client/firestore-writes.js.map +1 -1
  250. package/dist/serve/worker/client/messaging.d.ts +9 -1
  251. package/dist/serve/worker/client/messaging.d.ts.map +1 -1
  252. package/dist/serve/worker/client/messaging.js +15 -0
  253. package/dist/serve/worker/client/messaging.js.map +1 -1
  254. package/dist/serve/worker/client/studio.d.ts +10 -0
  255. package/dist/serve/worker/client/studio.d.ts.map +1 -1
  256. package/dist/serve/worker/client/studio.js +11 -0
  257. package/dist/serve/worker/client/studio.js.map +1 -1
  258. package/dist/serve/worker/durable-persistence.d.ts +12 -0
  259. package/dist/serve/worker/durable-persistence.d.ts.map +1 -0
  260. package/dist/serve/worker/durable-persistence.js +118 -0
  261. package/dist/serve/worker/durable-persistence.js.map +1 -0
  262. package/dist/serve/worker/entry.d.ts +7 -3
  263. package/dist/serve/worker/entry.d.ts.map +1 -1
  264. package/dist/serve/worker/entry.js +7 -3
  265. package/dist/serve/worker/entry.js.map +1 -1
  266. package/dist/serve/worker/host/core.d.ts +9 -5
  267. package/dist/serve/worker/host/core.d.ts.map +1 -1
  268. package/dist/serve/worker/host/core.js +34 -9
  269. package/dist/serve/worker/host/core.js.map +1 -1
  270. package/dist/serve/worker/host/dispatch.d.ts.map +1 -1
  271. package/dist/serve/worker/host/dispatch.js +9 -2
  272. package/dist/serve/worker/host/dispatch.js.map +1 -1
  273. package/dist/serve/worker/host/firestore-writes.d.ts.map +1 -1
  274. package/dist/serve/worker/host/firestore-writes.js +3 -2
  275. package/dist/serve/worker/host/firestore-writes.js.map +1 -1
  276. package/dist/serve/worker/host/studio.d.ts +1 -1
  277. package/dist/serve/worker/host/studio.d.ts.map +1 -1
  278. package/dist/serve/worker/host/studio.js +36 -1
  279. package/dist/serve/worker/host/studio.js.map +1 -1
  280. package/dist/serve/worker/host/subscriptions.d.ts.map +1 -1
  281. package/dist/serve/worker/host/subscriptions.js +27 -7
  282. package/dist/serve/worker/host/subscriptions.js.map +1 -1
  283. package/dist/serve/worker/host-context.d.ts +15 -0
  284. package/dist/serve/worker/host-context.d.ts.map +1 -1
  285. package/dist/serve/worker/host-context.js +10 -0
  286. package/dist/serve/worker/host-context.js.map +1 -1
  287. package/dist/serve/worker/host-messaging.d.ts.map +1 -1
  288. package/dist/serve/worker/host-messaging.js +9 -2
  289. package/dist/serve/worker/host-messaging.js.map +1 -1
  290. package/dist/serve/worker/index.d.ts +3 -2
  291. package/dist/serve/worker/index.d.ts.map +1 -1
  292. package/dist/serve/worker/index.js +4 -1
  293. package/dist/serve/worker/index.js.map +1 -1
  294. package/dist/serve/worker/protocol.d.ts +25 -3
  295. package/dist/serve/worker/protocol.d.ts.map +1 -1
  296. package/dist/serve/worker/protocol.js +2 -2
  297. package/dist/serve/worker/protocol.js.map +1 -1
  298. package/dist/serve/worker/serve-init.d.ts +23 -37
  299. package/dist/serve/worker/serve-init.d.ts.map +1 -1
  300. package/dist/serve/worker/serve-init.js +95 -172
  301. package/dist/serve/worker/serve-init.js.map +1 -1
  302. package/dist/vite.d.ts +4 -4
  303. package/dist/vite.d.ts.map +1 -1
  304. package/dist/vite.js +3 -3
  305. package/dist/vite.js.map +1 -1
  306. package/package.json +9 -4
  307. package/src/assurance/.generated/conformance-verdicts.ts +1090 -0
  308. package/src/assurance/attachment.ts +211 -0
  309. package/src/assurance/browser.ts +80 -0
  310. package/src/assurance/campaign.ts +496 -0
  311. package/src/assurance/capabilities.ts +446 -0
  312. package/src/assurance/cases.ts +43 -0
  313. package/src/assurance/index.ts +75 -0
  314. package/src/assurance/runner.ts +885 -0
  315. package/src/assurance/tool-names.ts +15 -0
  316. package/src/assurance/tools.ts +830 -0
  317. package/src/assurance/types.ts +352 -0
  318. package/src/assurance/validation.ts +434 -0
  319. package/src/bridge/client/bridge.ts +550 -0
  320. package/src/bridge/client/dispatch.ts +137 -0
  321. package/src/bridge/client.ts +45 -0
  322. package/src/bridge/protocol.ts +351 -0
  323. package/src/bridge/server/audit.ts +53 -0
  324. package/src/bridge/server/bridge.ts +597 -0
  325. package/src/bridge/server/headless.ts +160 -0
  326. package/src/bridge/server/json-schema-to-zod.ts +108 -0
  327. package/src/bridge/server/local-bridge.ts +66 -0
  328. package/src/bridge/server/logger.ts +50 -0
  329. package/src/bridge/server/mcp-contract.ts +93 -0
  330. package/src/bridge/server/mcp.ts +129 -0
  331. package/src/bridge/server/peer.ts +232 -0
  332. package/src/bridge/server/standalone.ts +347 -0
  333. package/src/bridge/server/tool-metadata.ts +99 -0
  334. package/src/bridge/server.ts +28 -0
  335. package/src/cli/can-i-use.ts +50 -0
  336. package/src/cli/cli.test.ts +493 -0
  337. package/src/cli/database-rules.ts +329 -0
  338. package/src/cli/dev-runner.ts +282 -0
  339. package/src/cli/firebase-json.ts +100 -0
  340. package/src/cli/firestore-indexes.ts +70 -0
  341. package/src/cli/index.ts +425 -0
  342. package/src/cli/init.ts +260 -0
  343. package/src/cli/mcp-proxy.ts +196 -0
  344. package/src/cli/parse-args.ts +80 -0
  345. package/src/cli/rules.ts +259 -0
  346. package/src/cli/scope.ts +67 -0
  347. package/src/cli/serve.ts +996 -0
  348. package/src/cli/service-commands.ts +73 -0
  349. package/src/cli/snapshot.ts +164 -0
  350. package/src/cli/storage-rules.ts +172 -0
  351. package/src/cli/verify.ts +416 -0
  352. package/src/conformance/.generated/can-i-use-browser.ts +113 -0
  353. package/src/conformance/.generated/can-i-use.ts +117 -0
  354. package/src/conformance/.generated/conformance-docs.ts +14 -0
  355. package/src/conformance/browser.ts +24 -0
  356. package/src/conformance/can-i-use-tool.ts +51 -0
  357. package/src/conformance/can-i-use.ts +18 -0
  358. package/src/conformance/docs.ts +8 -0
  359. package/src/conformance/index.ts +20 -0
  360. package/src/conformance/tools.ts +16 -0
  361. package/src/credentials/core/memoize-ttl.ts +142 -0
  362. package/src/credentials/core/types.ts +10 -0
  363. package/src/credentials/node/from-adc.ts +96 -0
  364. package/src/credentials/node/from-service-account.ts +133 -0
  365. package/src/credentials/node/index.ts +6 -0
  366. package/src/discover/concurrency.ts +127 -0
  367. package/src/discover/crawler-adapter.ts +142 -0
  368. package/src/discover/crawler.ts +1127 -0
  369. package/src/discover/credential-free.ts +27 -0
  370. package/src/discover/findCollectionGroup.ts +131 -0
  371. package/src/discover/firestore-source.ts +59 -0
  372. package/src/discover/index.ts +5 -0
  373. package/src/discover/merge.ts +523 -0
  374. package/src/discover/session.ts +402 -0
  375. package/src/discover/tools.ts +201 -0
  376. package/src/discover/types.ts +187 -0
  377. package/src/discover/wire.ts +324 -0
  378. package/src/functions-rtdb/child.ts +382 -0
  379. package/src/functions-rtdb/delivery.ts +7 -0
  380. package/src/functions-rtdb/discovery.ts +136 -0
  381. package/src/functions-rtdb/event.ts +64 -0
  382. package/src/functions-rtdb/execution.ts +111 -0
  383. package/src/functions-rtdb/in-memory-delivery.ts +40 -0
  384. package/src/functions-rtdb/project.ts +74 -0
  385. package/src/functions-rtdb/projection.ts +104 -0
  386. package/src/functions-rtdb/reference-pattern.ts +20 -0
  387. package/src/functions-rtdb/remote-delivery.ts +23 -0
  388. package/src/pkg-version.ts +49 -0
  389. package/src/register/esm-exports.ts +63 -0
  390. package/src/register/hooks.ts +30 -0
  391. package/src/register/index.ts +150 -0
  392. package/src/register/mapping.ts +33 -0
  393. package/src/remote/index.ts +1050 -0
  394. package/src/rtdb/crawl-snapshot.ts +118 -0
  395. package/src/rtdb/inspection.ts +137 -0
  396. package/src/rtdb/load-rules-document.ts +56 -0
  397. package/src/rtdb/rules-generation-tool.ts +38 -0
  398. package/src/rtdb/rules-json.ts +29 -0
  399. package/src/serve/activity-guard.ts +29 -0
  400. package/src/serve/activity-route.ts +164 -0
  401. package/src/serve/activity-warning.ts +26 -0
  402. package/src/serve/bridge-mount.ts +200 -0
  403. package/src/serve/bundler.ts +493 -0
  404. package/src/serve/capture-store.ts +65 -0
  405. package/src/serve/discovery.ts +199 -0
  406. package/src/serve/entries/ai.ts +292 -0
  407. package/src/serve/entries/app-backend.ts +4 -0
  408. package/src/serve/entries/app-client.ts +26 -0
  409. package/src/serve/entries/app-session-store.ts +47 -0
  410. package/src/serve/entries/app.ts +11 -0
  411. package/src/serve/entries/auth-helper-core.ts +181 -0
  412. package/src/serve/entries/auth-helper-dom.ts +134 -0
  413. package/src/serve/entries/auth-helper-runtime.ts +20 -0
  414. package/src/serve/entries/auth.ts +255 -0
  415. package/src/serve/entries/bridge-url.ts +31 -0
  416. package/src/serve/entries/database.ts +129 -0
  417. package/src/serve/entries/firestore.ts +232 -0
  418. package/src/serve/entries/init.ts +46 -0
  419. package/src/serve/entries/keepalive.ts +46 -0
  420. package/src/serve/entries/messaging-sw.ts +75 -0
  421. package/src/serve/entries/messaging.ts +96 -0
  422. package/src/serve/entries/runtime.ts +540 -0
  423. package/src/serve/entries/session-store.ts +97 -0
  424. package/src/serve/entries/storage.ts +92 -0
  425. package/src/serve/entries/tab-sync-wiring.ts +274 -0
  426. package/src/serve/entries/worker-runtime.ts +75 -0
  427. package/src/serve/init-payload.ts +42 -0
  428. package/src/serve/namespace.ts +675 -0
  429. package/src/serve/open-browser.ts +68 -0
  430. package/src/serve/rules.ts +272 -0
  431. package/src/serve/sandbox-marker.ts +31 -0
  432. package/src/serve/server.ts +428 -0
  433. package/src/serve/standalone-assets.ts +180 -0
  434. package/src/serve/state-store.ts +166 -0
  435. package/src/serve/studio/disk-project-store.ts +185 -0
  436. package/src/serve/studio/disk-workspace.ts +162 -0
  437. package/src/serve/studio/index.ts +20 -0
  438. package/src/serve/studio/routes.ts +237 -0
  439. package/src/serve/studio/store-types.ts +48 -0
  440. package/src/serve/studio/studio-storage.test.ts +289 -0
  441. package/src/serve/vite-plugin.ts +1102 -0
  442. package/src/serve/worker/activity-bootstrap.ts +24 -0
  443. package/src/serve/worker/client/admin-firestore.ts +38 -0
  444. package/src/serve/worker/client/ai.ts +124 -0
  445. package/src/serve/worker/client/auth.ts +489 -0
  446. package/src/serve/worker/client/connection.ts +202 -0
  447. package/src/serve/worker/client/core.ts +350 -0
  448. package/src/serve/worker/client/disconnect.ts +45 -0
  449. package/src/serve/worker/client/firestore-reads.ts +181 -0
  450. package/src/serve/worker/client/firestore-refs.ts +226 -0
  451. package/src/serve/worker/client/firestore-writes.ts +232 -0
  452. package/src/serve/worker/client/handles.ts +91 -0
  453. package/src/serve/worker/client/messaging.ts +119 -0
  454. package/src/serve/worker/client/presence.ts +174 -0
  455. package/src/serve/worker/client/rtdb.ts +311 -0
  456. package/src/serve/worker/client/rules.ts +63 -0
  457. package/src/serve/worker/client/service-worker-connection.ts +59 -0
  458. package/src/serve/worker/client/snapshots.ts +86 -0
  459. package/src/serve/worker/client/storage.ts +195 -0
  460. package/src/serve/worker/client/studio.ts +88 -0
  461. package/src/serve/worker/client.ts +57 -0
  462. package/src/serve/worker/durable-persistence.ts +137 -0
  463. package/src/serve/worker/entry.ts +179 -0
  464. package/src/serve/worker/host/admin-firestore.ts +88 -0
  465. package/src/serve/worker/host/connection.ts +179 -0
  466. package/src/serve/worker/host/core.ts +387 -0
  467. package/src/serve/worker/host/dispatch.ts +316 -0
  468. package/src/serve/worker/host/firestore-reads.ts +117 -0
  469. package/src/serve/worker/host/firestore-writes.ts +456 -0
  470. package/src/serve/worker/host/presence.ts +312 -0
  471. package/src/serve/worker/host/rtdb.ts +136 -0
  472. package/src/serve/worker/host/rules.ts +128 -0
  473. package/src/serve/worker/host/storage.ts +312 -0
  474. package/src/serve/worker/host/studio.ts +75 -0
  475. package/src/serve/worker/host/subscriptions.ts +238 -0
  476. package/src/serve/worker/host-ai.ts +165 -0
  477. package/src/serve/worker/host-auth.ts +469 -0
  478. package/src/serve/worker/host-context.ts +273 -0
  479. package/src/serve/worker/host-events.ts +94 -0
  480. package/src/serve/worker/host-messaging.ts +240 -0
  481. package/src/serve/worker/host.ts +47 -0
  482. package/src/serve/worker/index.ts +196 -0
  483. package/src/serve/worker/presence-timing.ts +15 -0
  484. package/src/serve/worker/protocol.ts +1112 -0
  485. package/src/serve/worker/serve-init.ts +606 -0
  486. package/src/serve/worker/service-worker-channel.ts +33 -0
  487. package/src/serve/worker/service-worker-relay.ts +86 -0
  488. package/src/serve/writer-lock.ts +53 -0
  489. package/src/verify/cases.ts +233 -0
  490. package/src/verify/fixture.ts +258 -0
  491. package/src/verify/index.ts +519 -0
  492. package/src/verify/tools.ts +108 -0
  493. package/src/version/compat-target.ts +17 -0
  494. package/src/vite.ts +17 -0
  495. package/dist/serve/docs-ui/docs/pyric-firestore-values-reference-api/index.html +0 -30
  496. package/dist/serve/docs-ui/docs/pyric-firestore-values-reference-api.md +0 -30
  497. package/dist/serve/studio-ui/assets/index-BvtQIpGn.js +0 -1211
  498. package/dist/serve/studio-ui/assets/seed-3DMedLL3.js +0 -2
@@ -0,0 +1,382 @@
1
+ import { spawn, type ChildProcess } from 'node:child_process';
2
+ import { randomUUID } from 'node:crypto';
3
+ import { existsSync, readFileSync } from 'node:fs';
4
+ import { createRequire } from 'node:module';
5
+ import { dirname, extname, join, resolve } from 'node:path';
6
+ import { fileURLToPath, pathToFileURL } from 'node:url';
7
+ import type { RemoteSandbox } from '../remote/index.js';
8
+ import {
9
+ startOnValueCreatedExecution,
10
+ type OnValueCreatedExecutionHost,
11
+ } from './execution.js';
12
+ import {
13
+ inspectOnValueCreated,
14
+ listFirebaseEndpoints,
15
+ } from './discovery.js';
16
+ import type { CreatedExecutionResult } from './event.js';
17
+ import { RemoteRtdbTriggerDelivery } from './remote-delivery.js';
18
+
19
+ export interface SerializedFunctionsRtdbError {
20
+ name: string;
21
+ message: string;
22
+ stack?: string;
23
+ }
24
+
25
+ export type FunctionsRtdbChildEvent =
26
+ | {
27
+ type: 'execution';
28
+ exportName: string;
29
+ ref: string;
30
+ params: Record<string, string>;
31
+ status: 'fulfilled';
32
+ }
33
+ | {
34
+ type: 'execution';
35
+ exportName: string;
36
+ ref: string;
37
+ params: Record<string, string>;
38
+ status: 'rejected';
39
+ error: SerializedFunctionsRtdbError;
40
+ }
41
+ | {
42
+ type: 'delivery-error';
43
+ exportName: string;
44
+ error: SerializedFunctionsRtdbError;
45
+ };
46
+
47
+ export interface FunctionsRtdbChildReady {
48
+ triggerCount: number;
49
+ unsupportedTriggers: UnsupportedFunctionsTrigger[];
50
+ }
51
+
52
+ export interface UnsupportedFunctionsTrigger {
53
+ exportName: string;
54
+ eventType: string;
55
+ }
56
+
57
+ export interface SpawnFunctionsRtdbChildOptions {
58
+ cwd: string;
59
+ entry: string;
60
+ env: NodeJS.ProcessEnv;
61
+ instance: string;
62
+ location: string;
63
+ databaseHost?: string;
64
+ childModuleUrl?: string | URL;
65
+ nodeExecutable?: string;
66
+ onEvent?(event: FunctionsRtdbChildEvent): void;
67
+ }
68
+
69
+ export interface FunctionsRtdbChildHandle {
70
+ child: ChildProcess;
71
+ ready: Promise<FunctionsRtdbChildReady>;
72
+ exited: Promise<number>;
73
+ stop(): Promise<number>;
74
+ }
75
+
76
+ type FunctionsRtdbChildMessage =
77
+ | ({ type: 'ready' } & FunctionsRtdbChildReady)
78
+ | FunctionsRtdbChildEvent
79
+ | { type: 'fatal'; error: SerializedFunctionsRtdbError }
80
+ | { type: 'stopped' };
81
+
82
+ const FORCE_KILL_AFTER_MS = 2_000;
83
+
84
+ function serializeError(error: unknown): SerializedFunctionsRtdbError {
85
+ if (error instanceof Error) {
86
+ return {
87
+ name: error.name,
88
+ message: error.message,
89
+ ...(error.stack === undefined ? {} : { stack: error.stack }),
90
+ };
91
+ }
92
+ return { name: 'Error', message: String(error) };
93
+ }
94
+
95
+ function isChildMessage(value: unknown): value is FunctionsRtdbChildMessage {
96
+ return typeof value === 'object' && value !== null && 'type' in value;
97
+ }
98
+
99
+ /** Spawn the real Firebase Functions SDK in an isolated Node process. */
100
+ export function spawnFunctionsRtdbChild(
101
+ options: SpawnFunctionsRtdbChildOptions,
102
+ ): FunctionsRtdbChildHandle {
103
+ const childModuleUrl = options.childModuleUrl ?? new URL('./child.js', import.meta.url);
104
+ const childModulePath = typeof childModuleUrl === 'string' && !childModuleUrl.startsWith('file:')
105
+ ? resolve(childModuleUrl)
106
+ : fileURLToPath(childModuleUrl);
107
+ const child = spawn(options.nodeExecutable ?? 'node', [childModulePath], {
108
+ cwd: options.cwd,
109
+ env: {
110
+ ...options.env,
111
+ PYRIC_FUNCTIONS_RTDB_CHILD: '1',
112
+ PYRIC_FUNCTIONS_ENTRY: resolve(options.entry),
113
+ PYRIC_FUNCTIONS_INSTANCE: options.instance,
114
+ PYRIC_FUNCTIONS_LOCATION: options.location,
115
+ PYRIC_FUNCTIONS_DATABASE_HOST: options.databaseHost ?? 'firebasedatabase.app',
116
+ },
117
+ stdio: ['ignore', 'pipe', 'pipe', 'ipc'],
118
+ });
119
+
120
+ let readySettled = false;
121
+ let stopping = false;
122
+ let stderr = '';
123
+ child.stderr?.setEncoding('utf8');
124
+ child.stderr?.on('data', (chunk: string) => {
125
+ stderr = `${stderr}${chunk}`.slice(-8_192);
126
+ });
127
+
128
+ let resolveReady!: (ready: FunctionsRtdbChildReady) => void;
129
+ let rejectReady!: (error: Error) => void;
130
+ const ready = new Promise<FunctionsRtdbChildReady>((resolvePromise, rejectPromise) => {
131
+ resolveReady = resolvePromise;
132
+ rejectReady = rejectPromise;
133
+ });
134
+
135
+ child.on('message', (raw: unknown) => {
136
+ if (!isChildMessage(raw)) return;
137
+ if (raw.type === 'ready') {
138
+ readySettled = true;
139
+ resolveReady({
140
+ triggerCount: raw.triggerCount,
141
+ unsupportedTriggers: raw.unsupportedTriggers,
142
+ });
143
+ } else if (raw.type === 'fatal') {
144
+ if (!readySettled) {
145
+ readySettled = true;
146
+ rejectReady(new Error(
147
+ `Functions RTDB child failed: ${raw.error.stack ?? raw.error.message}`,
148
+ ));
149
+ }
150
+ } else if (raw.type === 'execution' || raw.type === 'delivery-error') {
151
+ options.onEvent?.(raw);
152
+ }
153
+ });
154
+
155
+ let forceTimer: ReturnType<typeof setTimeout> | undefined;
156
+ const exited = new Promise<number>((resolveExited) => {
157
+ child.once('error', (error) => {
158
+ if (!readySettled) {
159
+ readySettled = true;
160
+ rejectReady(error);
161
+ }
162
+ });
163
+ child.once('close', (code, signal) => {
164
+ if (forceTimer !== undefined) clearTimeout(forceTimer);
165
+ const exitCode = typeof code === 'number' ? code : signal ? 1 : 0;
166
+ if (!readySettled) {
167
+ readySettled = true;
168
+ const diagnostic = stderr.trim();
169
+ rejectReady(new Error(
170
+ `Functions RTDB child exited before ready (code ${exitCode})` +
171
+ (diagnostic ? `\n${diagnostic}` : ''),
172
+ ));
173
+ }
174
+ resolveExited(exitCode);
175
+ });
176
+ });
177
+
178
+ return {
179
+ child,
180
+ ready,
181
+ exited,
182
+ async stop(): Promise<number> {
183
+ if (child.exitCode !== null || child.signalCode !== null) return exited;
184
+ if (!stopping) {
185
+ stopping = true;
186
+ if (child.connected) child.send({ type: 'stop' });
187
+ else child.kill('SIGTERM');
188
+ forceTimer = setTimeout(() => {
189
+ if (child.exitCode === null && child.signalCode === null) child.kill('SIGKILL');
190
+ }, FORCE_KILL_AFTER_MS);
191
+ forceTimer.unref();
192
+ }
193
+ return exited;
194
+ },
195
+ };
196
+ }
197
+
198
+ interface AdminAppModule {
199
+ initializeApp(): { sandbox: RemoteSandbox };
200
+ deleteApp(app: unknown): Promise<void>;
201
+ }
202
+
203
+ function send(message: FunctionsRtdbChildMessage): void {
204
+ process.send?.(message);
205
+ }
206
+
207
+ function usesCommonJs(entry: string): boolean {
208
+ const extension = extname(entry);
209
+ if (extension === '.cjs') return true;
210
+ if (extension === '.mjs') return false;
211
+
212
+ let directory = dirname(entry);
213
+ while (true) {
214
+ const packageJsonPath = join(directory, 'package.json');
215
+ if (existsSync(packageJsonPath)) {
216
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8')) as {
217
+ type?: unknown;
218
+ };
219
+ return packageJson.type !== 'module';
220
+ }
221
+ const parent = dirname(directory);
222
+ if (parent === directory) return true;
223
+ directory = parent;
224
+ }
225
+ }
226
+
227
+ /** Load the entry with the semantics selected by its extension and package scope. */
228
+ async function loadFunctionsExports(entry: string): Promise<Record<string, unknown>> {
229
+ if (usesCommonJs(entry)) {
230
+ return createRequire(entry)(entry) as Record<string, unknown>;
231
+ }
232
+ return await import(pathToFileURL(entry).href) as Record<string, unknown>;
233
+ }
234
+
235
+ async function runFunctionsRtdbChild(): Promise<void> {
236
+ const entry = process.env.PYRIC_FUNCTIONS_ENTRY;
237
+ const instance = process.env.PYRIC_FUNCTIONS_INSTANCE;
238
+ const location = process.env.PYRIC_FUNCTIONS_LOCATION;
239
+ const databaseHost = process.env.PYRIC_FUNCTIONS_DATABASE_HOST;
240
+ if (!entry || !instance || !location || !databaseHost) {
241
+ throw new Error('Functions RTDB child is missing its required environment');
242
+ }
243
+
244
+ const requireFromEntry = createRequire(entry);
245
+ const adminApp = requireFromEntry('firebase-admin/app') as AdminAppModule;
246
+ const app = adminApp.initializeApp();
247
+ let host: OnValueCreatedExecutionHost | undefined;
248
+ let closing: Promise<void> | undefined;
249
+
250
+ const close = (): Promise<void> => {
251
+ if (closing) return closing;
252
+ closing = (async () => {
253
+ host?.close();
254
+ await host?.idle();
255
+ app.sandbox.close();
256
+ await adminApp.deleteApp(app);
257
+ })();
258
+ return closing;
259
+ };
260
+
261
+ const shutdown = async (): Promise<void> => {
262
+ await close();
263
+ send({ type: 'stopped' });
264
+ process.disconnect?.();
265
+ };
266
+
267
+ process.once('message', (raw: unknown) => {
268
+ if (isChildMessage(raw) && raw.type === 'stopped') return;
269
+ if (typeof raw === 'object' && raw !== null && 'type' in raw && raw.type === 'stop') {
270
+ void shutdown().catch((error) => {
271
+ send({ type: 'fatal', error: serializeError(error) });
272
+ process.exitCode = 1;
273
+ process.disconnect?.();
274
+ });
275
+ }
276
+ });
277
+ process.once('SIGINT', () => void shutdown());
278
+ process.once('SIGTERM', () => void shutdown());
279
+
280
+ try {
281
+ // The real database provider asks firebase-admin/app for its default app
282
+ // when it wraps a raw CloudEvent. Initializing that app before loading the
283
+ // user's module avoids importing the broad firebase-functions/v2 barrel.
284
+ const exported = await loadFunctionsExports(entry);
285
+ const effectiveInstances = [...new Set(
286
+ inspectOnValueCreated(exported).triggers.map((trigger) =>
287
+ trigger.instance === '*' ? instance : trigger.instance,
288
+ ),
289
+ )].sort();
290
+ if (effectiveInstances.length > 1) {
291
+ throw new Error(
292
+ 'Functions RTDB first slice supports one database instance; found ' +
293
+ effectiveInstances.join(', '),
294
+ );
295
+ }
296
+ host = startOnValueCreatedExecution({
297
+ exported,
298
+ delivery: new RemoteRtdbTriggerDelivery(app.sandbox.rtdb),
299
+ eventOptions: (_projection, sequence, trigger) => ({
300
+ id: `${randomUUID()}-${sequence}`,
301
+ time: new Date().toISOString(),
302
+ instance: trigger.instance === '*' ? instance : trigger.instance,
303
+ location: trigger.location ?? location,
304
+ databaseHost,
305
+ }),
306
+ onExecution(result, trigger, projection) {
307
+ sendExecution(result, trigger.exportName, projection.ref, projection.params);
308
+ },
309
+ onDeliveryError(error, trigger) {
310
+ send({
311
+ type: 'delivery-error',
312
+ exportName: trigger.exportName,
313
+ error: serializeError(error),
314
+ });
315
+ },
316
+ });
317
+ await host.ready;
318
+ send({
319
+ type: 'ready',
320
+ triggerCount: host.triggerCount,
321
+ unsupportedTriggers: findUnsupportedTriggers(exported),
322
+ });
323
+ } catch (error) {
324
+ await close();
325
+ throw error;
326
+ }
327
+ }
328
+
329
+ function findUnsupportedTriggers(exported: Record<string, unknown>): UnsupportedFunctionsTrigger[] {
330
+ const unsupported: UnsupportedFunctionsTrigger[] = [
331
+ ...inspectOnValueCreated(exported).unsupported,
332
+ ];
333
+ for (const { exportName, callable } of listFirebaseEndpoints(exported)) {
334
+ const endpoint = callable.__endpoint;
335
+ if (!endpoint) continue;
336
+ const eventType = endpoint.eventTrigger?.eventType;
337
+ if (eventType === 'google.firebase.database.ref.v1.created') continue;
338
+ const label = typeof eventType === 'string'
339
+ ? eventType
340
+ : endpoint.callableTrigger !== undefined
341
+ ? 'callable'
342
+ : endpoint.httpsTrigger !== undefined
343
+ ? 'https'
344
+ : endpoint.scheduleTrigger !== undefined
345
+ ? 'schedule'
346
+ : endpoint.taskQueueTrigger !== undefined
347
+ ? 'task-queue'
348
+ : 'unknown';
349
+ unsupported.push({ exportName, eventType: label });
350
+ }
351
+ return unsupported;
352
+ }
353
+
354
+ function sendExecution(
355
+ result: CreatedExecutionResult,
356
+ exportName: string,
357
+ ref: string,
358
+ params: Record<string, string>,
359
+ ): void {
360
+ if (result.status === 'fulfilled') {
361
+ send({ type: 'execution', exportName, ref, params, status: 'fulfilled' });
362
+ } else {
363
+ send({
364
+ type: 'execution',
365
+ exportName,
366
+ ref,
367
+ params,
368
+ status: 'rejected',
369
+ error: serializeError(result.error),
370
+ });
371
+ }
372
+ }
373
+
374
+ if (process.env.PYRIC_FUNCTIONS_RTDB_CHILD === '1') {
375
+ void runFunctionsRtdbChild().catch((error) => {
376
+ const serialized = serializeError(error);
377
+ send({ type: 'fatal', error: serialized });
378
+ process.stderr.write(`${serialized.stack ?? `${serialized.name}: ${serialized.message}`}\n`);
379
+ process.exitCode = 1;
380
+ process.disconnect?.();
381
+ });
382
+ }
@@ -0,0 +1,7 @@
1
+ export interface RtdbTriggerDelivery {
2
+ subscribe(
3
+ path: string,
4
+ listener: (value: unknown) => void,
5
+ onError?: (error: unknown) => void,
6
+ ): () => void;
7
+ }
@@ -0,0 +1,136 @@
1
+ import {
2
+ normalizeRtdbReference,
3
+ supportsRtdbReference,
4
+ } from './reference-pattern.js';
5
+
6
+ export type RtdbCreatedCallable = (
7
+ rawEvent: Record<string, unknown>,
8
+ ) => unknown | Promise<unknown>;
9
+
10
+ export interface DiscoveredOnValueCreated {
11
+ exportName: string;
12
+ reference: string;
13
+ instance: string;
14
+ location?: string;
15
+ callable: RtdbCreatedCallable;
16
+ }
17
+
18
+ export interface UnsupportedOnValueCreated {
19
+ exportName: string;
20
+ eventType: string;
21
+ }
22
+
23
+ export interface OnValueCreatedInspection {
24
+ triggers: DiscoveredOnValueCreated[];
25
+ unsupported: UnsupportedOnValueCreated[];
26
+ }
27
+
28
+ export const CREATED_EVENT_TYPE = 'google.firebase.database.ref.v1.created';
29
+
30
+ export type FirebaseEndpointFunction = RtdbCreatedCallable & {
31
+ __endpoint?: {
32
+ omit?: unknown;
33
+ region?: unknown;
34
+ eventTrigger?: {
35
+ eventType?: unknown;
36
+ eventFilters?: Record<string, unknown>;
37
+ eventFilterPathPatterns?: Record<string, unknown>;
38
+ };
39
+ callableTrigger?: unknown;
40
+ httpsTrigger?: unknown;
41
+ scheduleTrigger?: unknown;
42
+ taskQueueTrigger?: unknown;
43
+ };
44
+ };
45
+
46
+ /** Walk exports using the same hyphenated nested names as Firebase's loader. */
47
+ export function listFirebaseEndpoints(
48
+ exported: Record<string, unknown>,
49
+ ): Array<{ exportName: string; callable: FirebaseEndpointFunction }> {
50
+ const endpoints: Array<{ exportName: string; callable: FirebaseEndpointFunction }> = [];
51
+ const visit = (
52
+ value: Record<string, unknown>,
53
+ prefix: string,
54
+ ancestors: ReadonlySet<object>,
55
+ ): void => {
56
+ if (ancestors.has(value)) return;
57
+ const nestedAncestors = new Set(ancestors).add(value);
58
+ for (const [name, candidate] of Object.entries(value)) {
59
+ const exportName = `${prefix}${name}`;
60
+ const callable = candidate as FirebaseEndpointFunction;
61
+ if (typeof candidate === 'function' && callable.__endpoint) {
62
+ endpoints.push({ exportName, callable });
63
+ } else if (typeof candidate === 'object' && candidate !== null) {
64
+ visit(candidate as Record<string, unknown>, `${exportName}-`, nestedAncestors);
65
+ }
66
+ }
67
+ };
68
+ visit(exported, '', new Set());
69
+ return endpoints;
70
+ }
71
+
72
+ /** Classify unchanged v2 RTDB create exports against the admitted first slice. */
73
+ export function inspectOnValueCreated(
74
+ exported: Record<string, unknown>,
75
+ ): OnValueCreatedInspection {
76
+ const triggers: DiscoveredOnValueCreated[] = [];
77
+ const unsupported: UnsupportedOnValueCreated[] = [];
78
+ for (const { exportName, callable } of listFirebaseEndpoints(exported)) {
79
+ const endpoint = callable.__endpoint;
80
+ const trigger = endpoint?.eventTrigger;
81
+ if (trigger?.eventType !== CREATED_EVENT_TYPE) continue;
82
+ if (endpoint?.omit === true) {
83
+ unsupported.push({
84
+ exportName,
85
+ eventType: `${CREATED_EVENT_TYPE} (omitted from emulation)`,
86
+ });
87
+ continue;
88
+ }
89
+ if (endpoint?.omit !== undefined && endpoint.omit !== false) {
90
+ unsupported.push({
91
+ exportName,
92
+ eventType: `${CREATED_EVENT_TYPE} (unsupported dynamic omit option)`,
93
+ });
94
+ continue;
95
+ }
96
+ const reference = trigger.eventFilterPathPatterns?.ref;
97
+ const exactInstance = trigger.eventFilters?.instance;
98
+ const instancePattern = trigger.eventFilterPathPatterns?.instance;
99
+ if (typeof reference !== 'string') continue;
100
+ if (typeof exactInstance !== 'string' && instancePattern !== '*') {
101
+ if (typeof instancePattern === 'string') {
102
+ unsupported.push({
103
+ exportName,
104
+ eventType: `${CREATED_EVENT_TYPE} (unsupported instance pattern: ${instancePattern})`,
105
+ });
106
+ }
107
+ continue;
108
+ }
109
+ const instance = typeof exactInstance === 'string' ? exactInstance : '*';
110
+ if (!supportsRtdbReference(reference)) {
111
+ unsupported.push({
112
+ exportName,
113
+ eventType: `${CREATED_EVENT_TYPE} (unsupported ref pattern: ${reference})`,
114
+ });
115
+ continue;
116
+ }
117
+ const region = endpoint?.region;
118
+ const location = Array.isArray(region) && typeof region[0] === 'string'
119
+ ? region[0]
120
+ : undefined;
121
+ triggers.push({
122
+ exportName,
123
+ reference: normalizeRtdbReference(reference),
124
+ instance,
125
+ ...(location === undefined ? {} : { location }),
126
+ callable,
127
+ });
128
+ }
129
+ return { triggers, unsupported };
130
+ }
131
+
132
+ export function discoverOnValueCreated(
133
+ exported: Record<string, unknown>,
134
+ ): DiscoveredOnValueCreated[] {
135
+ return inspectOnValueCreated(exported).triggers;
136
+ }
@@ -0,0 +1,64 @@
1
+ import { CREATED_EVENT_TYPE, type DiscoveredOnValueCreated } from './discovery.js';
2
+ import type { CreatedValueProjection } from './projection.js';
3
+
4
+ export interface CreatedEventOptions {
5
+ id: string;
6
+ time: string;
7
+ instance: string;
8
+ location: string;
9
+ databaseHost: string;
10
+ }
11
+
12
+ export type CreatedExecutionResult =
13
+ | { status: 'fulfilled'; event: Record<string, unknown> }
14
+ | { status: 'rejected'; event: Record<string, unknown>; error: unknown };
15
+
16
+ function canonicalizeRtdbValue(value: unknown): unknown {
17
+ if (Array.isArray(value)) return value.map(canonicalizeRtdbValue);
18
+ if (typeof value !== 'object' || value === null) return value;
19
+ return Object.fromEntries(
20
+ Object.keys(value as Record<string, unknown>)
21
+ .sort()
22
+ .map((key) => [
23
+ key,
24
+ canonicalizeRtdbValue((value as Record<string, unknown>)[key]),
25
+ ]),
26
+ );
27
+ }
28
+
29
+ /** Invoke the real Firebase Functions wrapper and await the user's result. */
30
+ export async function executeOnValueCreated(
31
+ trigger: DiscoveredOnValueCreated,
32
+ projection: CreatedValueProjection,
33
+ options: CreatedEventOptions,
34
+ ): Promise<CreatedExecutionResult> {
35
+ const event: Record<string, unknown> = {
36
+ specversion: '1.0',
37
+ id: options.id,
38
+ // RTDB CloudEvents use the provider resource and a `_` project segment;
39
+ // the concrete database identity lives in `instances/<instance>`.
40
+ source:
41
+ '//firebasedatabase.googleapis.com/projects/_' +
42
+ `/locations/${options.location}/instances/${options.instance}`,
43
+ subject: `refs/${projection.ref}`,
44
+ type: CREATED_EVENT_TYPE,
45
+ time: options.time,
46
+ location: options.location,
47
+ instance: options.instance,
48
+ ref: projection.ref,
49
+ firebasedatabasehost: options.databaseHost,
50
+ authtype: 'unknown',
51
+ authid: null,
52
+ data: {
53
+ data: null,
54
+ delta: canonicalizeRtdbValue(projection.value),
55
+ },
56
+ };
57
+
58
+ try {
59
+ await trigger.callable(event);
60
+ return { status: 'fulfilled', event };
61
+ } catch (error) {
62
+ return { status: 'rejected', event, error };
63
+ }
64
+ }
@@ -0,0 +1,111 @@
1
+ import { discoverOnValueCreated, type DiscoveredOnValueCreated } from './discovery.js';
2
+ import type { RtdbTriggerDelivery } from './delivery.js';
3
+ import {
4
+ executeOnValueCreated,
5
+ type CreatedEventOptions,
6
+ type CreatedExecutionResult,
7
+ } from './event.js';
8
+ import {
9
+ projectValueCreates,
10
+ watchPath,
11
+ type CreatedValueProjection,
12
+ } from './projection.js';
13
+
14
+ export interface OnValueCreatedExecutionOptions {
15
+ exported: Record<string, unknown>;
16
+ delivery: RtdbTriggerDelivery;
17
+ eventOptions(
18
+ projection: CreatedValueProjection,
19
+ sequence: number,
20
+ trigger: DiscoveredOnValueCreated,
21
+ ): CreatedEventOptions;
22
+ onExecution?(
23
+ result: CreatedExecutionResult,
24
+ trigger: DiscoveredOnValueCreated,
25
+ projection: CreatedValueProjection,
26
+ ): void;
27
+ onDeliveryError?(error: unknown, trigger: DiscoveredOnValueCreated): void;
28
+ }
29
+
30
+ export interface OnValueCreatedExecutionHost {
31
+ readonly triggerCount: number;
32
+ readonly ready: Promise<void>;
33
+ idle(): Promise<void>;
34
+ close(): void;
35
+ }
36
+
37
+ /** Subscribe discovered functions and serialize their snapshot executions. */
38
+ export function startOnValueCreatedExecution(
39
+ options: OnValueCreatedExecutionOptions,
40
+ ): OnValueCreatedExecutionHost {
41
+ const triggers = discoverOnValueCreated(options.exported);
42
+ const unsubscribe: Array<() => void> = [];
43
+ let closed = false;
44
+ let sequence = 0;
45
+ let tail = Promise.resolve();
46
+ let baselinesRemaining = triggers.length;
47
+ let readinessFailed = false;
48
+ let markReady!: () => void;
49
+ let failReady!: (error: unknown) => void;
50
+ const ready = new Promise<void>((resolve, reject) => {
51
+ markReady = resolve;
52
+ failReady = reject;
53
+ });
54
+ if (baselinesRemaining === 0) markReady();
55
+
56
+ for (const trigger of triggers) {
57
+ const path = watchPath(trigger.reference);
58
+ let hasBaseline = false;
59
+ let previous: unknown;
60
+ unsubscribe.push(
61
+ options.delivery.subscribe(
62
+ path,
63
+ (next) => {
64
+ if (closed) return;
65
+ if (!hasBaseline) {
66
+ previous = next;
67
+ hasBaseline = true;
68
+ baselinesRemaining -= 1;
69
+ if (baselinesRemaining === 0 && !readinessFailed) markReady();
70
+ return;
71
+ }
72
+ const before = previous;
73
+ previous = next;
74
+ for (const projection of projectValueCreates(trigger.reference, {
75
+ path,
76
+ before,
77
+ after: next,
78
+ })) {
79
+ const deliverySequence = ++sequence;
80
+ tail = tail.then(async () => {
81
+ const result = await executeOnValueCreated(
82
+ trigger,
83
+ projection,
84
+ options.eventOptions(projection, deliverySequence, trigger),
85
+ );
86
+ options.onExecution?.(result, trigger, projection);
87
+ });
88
+ }
89
+ },
90
+ (error) => {
91
+ if (!hasBaseline && !readinessFailed) {
92
+ readinessFailed = true;
93
+ failReady(error);
94
+ }
95
+ options.onDeliveryError?.(error, trigger);
96
+ },
97
+ ),
98
+ );
99
+ }
100
+
101
+ return {
102
+ triggerCount: triggers.length,
103
+ ready,
104
+ idle: () => tail,
105
+ close() {
106
+ if (closed) return;
107
+ closed = true;
108
+ for (const stop of unsubscribe.splice(0)) stop();
109
+ },
110
+ };
111
+ }