pyric 0.0.1 → 0.1.0-alpha.7

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 (786) hide show
  1. package/README.md +52 -1
  2. package/dist/app/index.d.ts +81 -0
  3. package/dist/app/index.d.ts.map +1 -0
  4. package/dist/app/index.js +78 -0
  5. package/dist/app/index.js.map +1 -0
  6. package/dist/auth/index.d.ts +346 -0
  7. package/dist/auth/index.d.ts.map +1 -0
  8. package/dist/auth/index.js +701 -0
  9. package/dist/auth/index.js.map +1 -0
  10. package/dist/auth/prod-backend.d.ts +39 -0
  11. package/dist/auth/prod-backend.d.ts.map +1 -0
  12. package/dist/auth/prod-backend.js +179 -0
  13. package/dist/auth/prod-backend.js.map +1 -0
  14. package/dist/auth/providers.d.ts +107 -0
  15. package/dist/auth/providers.d.ts.map +1 -0
  16. package/dist/auth/providers.js +138 -0
  17. package/dist/auth/providers.js.map +1 -0
  18. package/dist/auth/sandbox-backend.d.ts +769 -0
  19. package/dist/auth/sandbox-backend.d.ts.map +1 -0
  20. package/dist/auth/sandbox-backend.js +1598 -0
  21. package/dist/auth/sandbox-backend.js.map +1 -0
  22. package/dist/auth/target.d.ts +40 -0
  23. package/dist/auth/target.d.ts.map +1 -0
  24. package/dist/auth/target.js +28 -0
  25. package/dist/auth/target.js.map +1 -0
  26. package/dist/auth/types.d.ts +252 -0
  27. package/dist/auth/types.d.ts.map +1 -0
  28. package/dist/auth/types.js +26 -0
  29. package/dist/auth/types.js.map +1 -0
  30. package/dist/database/constraints/atoms.d.ts +29 -0
  31. package/dist/database/constraints/atoms.d.ts.map +1 -0
  32. package/dist/database/constraints/atoms.js +43 -0
  33. package/dist/database/constraints/atoms.js.map +1 -0
  34. package/dist/database/constraints/compose.d.ts +16 -0
  35. package/dist/database/constraints/compose.d.ts.map +1 -0
  36. package/dist/database/constraints/compose.js +15 -0
  37. package/dist/database/constraints/compose.js.map +1 -0
  38. package/dist/database/constraints/data.d.ts +30 -0
  39. package/dist/database/constraints/data.d.ts.map +1 -0
  40. package/dist/database/constraints/data.js +46 -0
  41. package/dist/database/constraints/data.js.map +1 -0
  42. package/dist/database/constraints/document.d.ts +42 -0
  43. package/dist/database/constraints/document.d.ts.map +1 -0
  44. package/dist/database/constraints/document.js +86 -0
  45. package/dist/database/constraints/document.js.map +1 -0
  46. package/dist/database/constraints/game.d.ts +30 -0
  47. package/dist/database/constraints/game.d.ts.map +1 -0
  48. package/dist/database/constraints/game.js +49 -0
  49. package/dist/database/constraints/game.js.map +1 -0
  50. package/dist/database/constraints/index.d.ts +12 -0
  51. package/dist/database/constraints/index.d.ts.map +1 -0
  52. package/dist/database/constraints/index.js +9 -0
  53. package/dist/database/constraints/index.js.map +1 -0
  54. package/dist/database/constraints/policies.d.ts +16 -0
  55. package/dist/database/constraints/policies.d.ts.map +1 -0
  56. package/dist/database/constraints/policies.js +17 -0
  57. package/dist/database/constraints/policies.js.map +1 -0
  58. package/dist/database/constraints/ruleset.d.ts +5 -0
  59. package/dist/database/constraints/ruleset.d.ts.map +1 -0
  60. package/dist/database/constraints/ruleset.js +132 -0
  61. package/dist/database/constraints/ruleset.js.map +1 -0
  62. package/dist/database/constraints/schema.d.ts +17 -0
  63. package/dist/database/constraints/schema.d.ts.map +1 -0
  64. package/dist/database/constraints/schema.js +74 -0
  65. package/dist/database/constraints/schema.js.map +1 -0
  66. package/dist/database/constraints/types.d.ts +22 -0
  67. package/dist/database/constraints/types.d.ts.map +1 -0
  68. package/dist/database/constraints/types.js +2 -0
  69. package/dist/database/constraints/types.js.map +1 -0
  70. package/dist/database/crawl/handler.d.ts +7 -0
  71. package/dist/database/crawl/handler.d.ts.map +1 -0
  72. package/dist/database/crawl/handler.js +91 -0
  73. package/dist/database/crawl/handler.js.map +1 -0
  74. package/dist/database/crawl/semaphore.d.ts +9 -0
  75. package/dist/database/crawl/semaphore.d.ts.map +1 -0
  76. package/dist/database/crawl/semaphore.js +27 -0
  77. package/dist/database/crawl/semaphore.js.map +1 -0
  78. package/dist/database/crawl/spec.d.ts +33 -0
  79. package/dist/database/crawl/spec.d.ts.map +1 -0
  80. package/dist/database/crawl/spec.js +12 -0
  81. package/dist/database/crawl/spec.js.map +1 -0
  82. package/dist/database/data/handler.d.ts +9 -0
  83. package/dist/database/data/handler.d.ts.map +1 -0
  84. package/dist/database/data/handler.js +96 -0
  85. package/dist/database/data/handler.js.map +1 -0
  86. package/dist/database/data/spec.d.ts +77 -0
  87. package/dist/database/data/spec.d.ts.map +1 -0
  88. package/dist/database/data/spec.js +17 -0
  89. package/dist/database/data/spec.js.map +1 -0
  90. package/dist/database/data/validated.d.ts +8 -0
  91. package/dist/database/data/validated.d.ts.map +1 -0
  92. package/dist/database/data/validated.js +99 -0
  93. package/dist/database/data/validated.js.map +1 -0
  94. package/dist/database/grammar/RtdbExpr.ohm +98 -0
  95. package/dist/database/grammar/RtdbExpr.ohm.generated.d.ts +2 -0
  96. package/dist/database/grammar/RtdbExpr.ohm.generated.d.ts.map +1 -0
  97. package/dist/database/grammar/RtdbExpr.ohm.generated.js +103 -0
  98. package/dist/database/grammar/RtdbExpr.ohm.generated.js.map +1 -0
  99. package/dist/database/grammar/RtdbExprParser.d.ts +5 -0
  100. package/dist/database/grammar/RtdbExprParser.d.ts.map +1 -0
  101. package/dist/database/grammar/RtdbExprParser.js +53 -0
  102. package/dist/database/grammar/RtdbExprParser.js.map +1 -0
  103. package/dist/database/grammar/linter.d.ts +3 -0
  104. package/dist/database/grammar/linter.d.ts.map +1 -0
  105. package/dist/database/grammar/linter.js +66 -0
  106. package/dist/database/grammar/linter.js.map +1 -0
  107. package/dist/database/grammar/simulator.d.ts +31 -0
  108. package/dist/database/grammar/simulator.d.ts.map +1 -0
  109. package/dist/database/grammar/simulator.js +255 -0
  110. package/dist/database/grammar/simulator.js.map +1 -0
  111. package/dist/database/grammar/validator.d.ts +3 -0
  112. package/dist/database/grammar/validator.d.ts.map +1 -0
  113. package/dist/database/grammar/validator.js +84 -0
  114. package/dist/database/grammar/validator.js.map +1 -0
  115. package/dist/database/host.d.ts +50 -0
  116. package/dist/database/host.d.ts.map +1 -0
  117. package/dist/database/host.js +41 -0
  118. package/dist/database/host.js.map +1 -0
  119. package/dist/database/index.d.ts +40 -0
  120. package/dist/database/index.d.ts.map +1 -0
  121. package/dist/database/index.js +47 -0
  122. package/dist/database/index.js.map +1 -0
  123. package/dist/database/initialize-from-app.d.ts +28 -0
  124. package/dist/database/initialize-from-app.d.ts.map +1 -0
  125. package/dist/database/initialize-from-app.js +23 -0
  126. package/dist/database/initialize-from-app.js.map +1 -0
  127. package/dist/database/ir/handler.d.ts +6 -0
  128. package/dist/database/ir/handler.d.ts.map +1 -0
  129. package/dist/database/ir/handler.js +52 -0
  130. package/dist/database/ir/handler.js.map +1 -0
  131. package/dist/database/ir/spec.d.ts +25 -0
  132. package/dist/database/ir/spec.d.ts.map +1 -0
  133. package/dist/database/ir/spec.js +11 -0
  134. package/dist/database/ir/spec.js.map +1 -0
  135. package/dist/database/mapper.d.ts +9 -0
  136. package/dist/database/mapper.d.ts.map +1 -0
  137. package/dist/database/mapper.js +115 -0
  138. package/dist/database/mapper.js.map +1 -0
  139. package/dist/database/modular.d.ts +604 -0
  140. package/dist/database/modular.d.ts.map +1 -0
  141. package/dist/database/modular.js +1226 -0
  142. package/dist/database/modular.js.map +1 -0
  143. package/dist/database/replay.d.ts +33 -0
  144. package/dist/database/replay.d.ts.map +1 -0
  145. package/dist/database/replay.js +124 -0
  146. package/dist/database/replay.js.map +1 -0
  147. package/dist/database/resolver.d.ts +4 -0
  148. package/dist/database/resolver.d.ts.map +1 -0
  149. package/dist/database/resolver.js +66 -0
  150. package/dist/database/resolver.js.map +1 -0
  151. package/dist/database/sandbox/backend.d.ts +403 -0
  152. package/dist/database/sandbox/backend.d.ts.map +1 -0
  153. package/dist/database/sandbox/backend.js +1467 -0
  154. package/dist/database/sandbox/backend.js.map +1 -0
  155. package/dist/database/sandbox/data-tree.d.ts +123 -0
  156. package/dist/database/sandbox/data-tree.d.ts.map +1 -0
  157. package/dist/database/sandbox/data-tree.js +310 -0
  158. package/dist/database/sandbox/data-tree.js.map +1 -0
  159. package/dist/database/sandbox/normalize.d.ts +77 -0
  160. package/dist/database/sandbox/normalize.d.ts.map +1 -0
  161. package/dist/database/sandbox/normalize.js +165 -0
  162. package/dist/database/sandbox/normalize.js.map +1 -0
  163. package/dist/database/sandbox/push-id.d.ts +32 -0
  164. package/dist/database/sandbox/push-id.d.ts.map +1 -0
  165. package/dist/database/sandbox/push-id.js +82 -0
  166. package/dist/database/sandbox/push-id.js.map +1 -0
  167. package/dist/database/sandbox/query.d.ts +175 -0
  168. package/dist/database/sandbox/query.d.ts.map +1 -0
  169. package/dist/database/sandbox/query.js +269 -0
  170. package/dist/database/sandbox/query.js.map +1 -0
  171. package/dist/database/sandbox/rules-eval.d.ts +69 -0
  172. package/dist/database/sandbox/rules-eval.d.ts.map +1 -0
  173. package/dist/database/sandbox/rules-eval.js +124 -0
  174. package/dist/database/sandbox/rules-eval.js.map +1 -0
  175. package/dist/database/sandbox/sentinels.d.ts +71 -0
  176. package/dist/database/sandbox/sentinels.d.ts.map +1 -0
  177. package/dist/database/sandbox/sentinels.js +92 -0
  178. package/dist/database/sandbox/sentinels.js.map +1 -0
  179. package/dist/database/simulation/handler.d.ts +6 -0
  180. package/dist/database/simulation/handler.d.ts.map +1 -0
  181. package/dist/database/simulation/handler.js +236 -0
  182. package/dist/database/simulation/handler.js.map +1 -0
  183. package/dist/database/simulation/spec.d.ts +69 -0
  184. package/dist/database/simulation/spec.d.ts.map +1 -0
  185. package/dist/database/simulation/spec.js +25 -0
  186. package/dist/database/simulation/spec.js.map +1 -0
  187. package/dist/database/tools.d.ts +22 -0
  188. package/dist/database/tools.d.ts.map +1 -0
  189. package/dist/database/tools.js +272 -0
  190. package/dist/database/tools.js.map +1 -0
  191. package/dist/database/types.d.ts +210 -0
  192. package/dist/database/types.d.ts.map +1 -0
  193. package/dist/database/types.js +26 -0
  194. package/dist/database/types.js.map +1 -0
  195. package/dist/database/write/handler.d.ts +7 -0
  196. package/dist/database/write/handler.d.ts.map +1 -0
  197. package/dist/database/write/handler.js +42 -0
  198. package/dist/database/write/handler.js.map +1 -0
  199. package/dist/database/write/spec.d.ts +18 -0
  200. package/dist/database/write/spec.d.ts.map +1 -0
  201. package/dist/database/write/spec.js +7 -0
  202. package/dist/database/write/spec.js.map +1 -0
  203. package/dist/firestore/index.d.ts +533 -0
  204. package/dist/firestore/index.d.ts.map +1 -0
  205. package/dist/firestore/index.js +1536 -0
  206. package/dist/firestore/index.js.map +1 -0
  207. package/dist/firestore/tools.d.ts +67 -0
  208. package/dist/firestore/tools.d.ts.map +1 -0
  209. package/dist/firestore/tools.js +318 -0
  210. package/dist/firestore/tools.js.map +1 -0
  211. package/dist/firestore-values/index.d.ts +63 -0
  212. package/dist/firestore-values/index.d.ts.map +1 -0
  213. package/dist/firestore-values/index.js +148 -0
  214. package/dist/firestore-values/index.js.map +1 -0
  215. package/dist/project-scope.d.ts +5 -0
  216. package/dist/project-scope.d.ts.map +1 -0
  217. package/dist/project-scope.js +2 -0
  218. package/dist/project-scope.js.map +1 -0
  219. package/dist/rules/extract.d.ts +28 -0
  220. package/dist/rules/extract.d.ts.map +1 -0
  221. package/dist/rules/extract.js +25 -0
  222. package/dist/rules/extract.js.map +1 -0
  223. package/dist/rules/generators/assembler.d.ts +19 -0
  224. package/dist/rules/generators/assembler.d.ts.map +1 -0
  225. package/dist/rules/generators/assembler.js +292 -0
  226. package/dist/rules/generators/assembler.js.map +1 -0
  227. package/dist/rules/generators/expressions.d.ts +52 -0
  228. package/dist/rules/generators/expressions.d.ts.map +1 -0
  229. package/dist/rules/generators/expressions.js +117 -0
  230. package/dist/rules/generators/expressions.js.map +1 -0
  231. package/dist/rules/generators/grid.d.ts +22 -0
  232. package/dist/rules/generators/grid.d.ts.map +1 -0
  233. package/dist/rules/generators/grid.js +52 -0
  234. package/dist/rules/generators/grid.js.map +1 -0
  235. package/dist/rules/grammar/FirestoreAST.d.ts +129 -0
  236. package/dist/rules/grammar/FirestoreAST.d.ts.map +1 -0
  237. package/dist/rules/grammar/FirestoreAST.js +3 -0
  238. package/dist/rules/grammar/FirestoreAST.js.map +1 -0
  239. package/dist/rules/grammar/FirestoreAssembler.d.ts +5 -0
  240. package/dist/rules/grammar/FirestoreAssembler.d.ts.map +1 -0
  241. package/dist/rules/grammar/FirestoreAssembler.js +158 -0
  242. package/dist/rules/grammar/FirestoreAssembler.js.map +1 -0
  243. package/dist/rules/grammar/FirestoreParser.d.ts +46 -0
  244. package/dist/rules/grammar/FirestoreParser.d.ts.map +1 -0
  245. package/dist/rules/grammar/FirestoreParser.js +409 -0
  246. package/dist/rules/grammar/FirestoreParser.js.map +1 -0
  247. package/dist/rules/grammar/FirestoreRules.ohm +229 -0
  248. package/dist/rules/grammar/FirestoreRules.ohm.generated.d.ts +2 -0
  249. package/dist/rules/grammar/FirestoreRules.ohm.generated.d.ts.map +1 -0
  250. package/dist/rules/grammar/FirestoreRules.ohm.generated.js +234 -0
  251. package/dist/rules/grammar/FirestoreRules.ohm.generated.js.map +1 -0
  252. package/dist/rules/grammar/FirestoreValidator.d.ts +10 -0
  253. package/dist/rules/grammar/FirestoreValidator.d.ts.map +1 -0
  254. package/dist/rules/grammar/FirestoreValidator.js +482 -0
  255. package/dist/rules/grammar/FirestoreValidator.js.map +1 -0
  256. package/dist/rules/index.d.ts +67 -0
  257. package/dist/rules/index.d.ts.map +1 -0
  258. package/dist/rules/index.js +80 -0
  259. package/dist/rules/index.js.map +1 -0
  260. package/dist/rules/indexes/extract/annotation-collect.d.ts +42 -0
  261. package/dist/rules/indexes/extract/annotation-collect.d.ts.map +1 -0
  262. package/dist/rules/indexes/extract/annotation-collect.js +69 -0
  263. package/dist/rules/indexes/extract/annotation-collect.js.map +1 -0
  264. package/dist/rules/indexes/extract/annotations.d.ts +50 -0
  265. package/dist/rules/indexes/extract/annotations.d.ts.map +1 -0
  266. package/dist/rules/indexes/extract/annotations.js +144 -0
  267. package/dist/rules/indexes/extract/annotations.js.map +1 -0
  268. package/dist/rules/indexes/extract/ast.d.ts +54 -0
  269. package/dist/rules/indexes/extract/ast.d.ts.map +1 -0
  270. package/dist/rules/indexes/extract/ast.js +119 -0
  271. package/dist/rules/indexes/extract/ast.js.map +1 -0
  272. package/dist/rules/indexes/extract/classify.d.ts +41 -0
  273. package/dist/rules/indexes/extract/classify.d.ts.map +1 -0
  274. package/dist/rules/indexes/extract/classify.js +138 -0
  275. package/dist/rules/indexes/extract/classify.js.map +1 -0
  276. package/dist/rules/indexes/extract/composite.d.ts +38 -0
  277. package/dist/rules/indexes/extract/composite.d.ts.map +1 -0
  278. package/dist/rules/indexes/extract/composite.js +85 -0
  279. package/dist/rules/indexes/extract/composite.js.map +1 -0
  280. package/dist/rules/indexes/extract/dataflow.d.ts +45 -0
  281. package/dist/rules/indexes/extract/dataflow.d.ts.map +1 -0
  282. package/dist/rules/indexes/extract/dataflow.js +200 -0
  283. package/dist/rules/indexes/extract/dataflow.js.map +1 -0
  284. package/dist/rules/indexes/extract/enumerate.d.ts +41 -0
  285. package/dist/rules/indexes/extract/enumerate.d.ts.map +1 -0
  286. package/dist/rules/indexes/extract/enumerate.js +163 -0
  287. package/dist/rules/indexes/extract/enumerate.js.map +1 -0
  288. package/dist/rules/indexes/extract/extractor.d.ts +3 -0
  289. package/dist/rules/indexes/extract/extractor.d.ts.map +1 -0
  290. package/dist/rules/indexes/extract/extractor.js +274 -0
  291. package/dist/rules/indexes/extract/extractor.js.map +1 -0
  292. package/dist/rules/indexes/extract/types.d.ts +211 -0
  293. package/dist/rules/indexes/extract/types.d.ts.map +1 -0
  294. package/dist/rules/indexes/extract/types.js +14 -0
  295. package/dist/rules/indexes/extract/types.js.map +1 -0
  296. package/dist/rules/indexes/extractHandler.d.ts +16 -0
  297. package/dist/rules/indexes/extractHandler.d.ts.map +1 -0
  298. package/dist/rules/indexes/extractHandler.js +100 -0
  299. package/dist/rules/indexes/extractHandler.js.map +1 -0
  300. package/dist/rules/indexes/extractTool.d.ts +15 -0
  301. package/dist/rules/indexes/extractTool.d.ts.map +1 -0
  302. package/dist/rules/indexes/extractTool.js +55 -0
  303. package/dist/rules/indexes/extractTool.js.map +1 -0
  304. package/dist/rules/indexes/types.d.ts +71 -0
  305. package/dist/rules/indexes/types.d.ts.map +1 -0
  306. package/dist/rules/indexes/types.js +15 -0
  307. package/dist/rules/indexes/types.js.map +1 -0
  308. package/dist/rules/inspect/handler.d.ts +6 -0
  309. package/dist/rules/inspect/handler.d.ts.map +1 -0
  310. package/dist/rules/inspect/handler.js +144 -0
  311. package/dist/rules/inspect/handler.js.map +1 -0
  312. package/dist/rules/inspect/spec.d.ts +37 -0
  313. package/dist/rules/inspect/spec.d.ts.map +1 -0
  314. package/dist/rules/inspect/spec.js +2 -0
  315. package/dist/rules/inspect/spec.js.map +1 -0
  316. package/dist/rules/inspect/tools.d.ts +21 -0
  317. package/dist/rules/inspect/tools.d.ts.map +1 -0
  318. package/dist/rules/inspect/tools.js +21 -0
  319. package/dist/rules/inspect/tools.js.map +1 -0
  320. package/dist/rules/linter/ast-utils.d.ts +97 -0
  321. package/dist/rules/linter/ast-utils.d.ts.map +1 -0
  322. package/dist/rules/linter/ast-utils.js +491 -0
  323. package/dist/rules/linter/ast-utils.js.map +1 -0
  324. package/dist/rules/linter/hallucinations.d.ts +34 -0
  325. package/dist/rules/linter/hallucinations.d.ts.map +1 -0
  326. package/dist/rules/linter/hallucinations.js +334 -0
  327. package/dist/rules/linter/hallucinations.js.map +1 -0
  328. package/dist/rules/linter/linter.d.ts +84 -0
  329. package/dist/rules/linter/linter.d.ts.map +1 -0
  330. package/dist/rules/linter/linter.js +784 -0
  331. package/dist/rules/linter/linter.js.map +1 -0
  332. package/dist/rules/modules/resolver-browser.d.ts +41 -0
  333. package/dist/rules/modules/resolver-browser.d.ts.map +1 -0
  334. package/dist/rules/modules/resolver-browser.js +63 -0
  335. package/dist/rules/modules/resolver-browser.js.map +1 -0
  336. package/dist/rules/modules/resolver-core.d.ts +51 -0
  337. package/dist/rules/modules/resolver-core.d.ts.map +1 -0
  338. package/dist/rules/modules/resolver-core.js +338 -0
  339. package/dist/rules/modules/resolver-core.js.map +1 -0
  340. package/dist/rules/modules/resolver.d.ts +17 -0
  341. package/dist/rules/modules/resolver.d.ts.map +1 -0
  342. package/dist/rules/modules/resolver.js +49 -0
  343. package/dist/rules/modules/resolver.js.map +1 -0
  344. package/dist/rules/modules/stdlib/atomic.rules +52 -0
  345. package/dist/rules/modules/stdlib/atomic.test.json +152 -0
  346. package/dist/rules/modules/stdlib/auth.rules +7 -0
  347. package/dist/rules/modules/stdlib/auth.test.json +53 -0
  348. package/dist/rules/modules/stdlib/content.rules +50 -0
  349. package/dist/rules/modules/stdlib/content.test.json +238 -0
  350. package/dist/rules/modules/stdlib/counters.rules +41 -0
  351. package/dist/rules/modules/stdlib/counters.test.json +254 -0
  352. package/dist/rules/modules/stdlib/geometry.rules +43 -0
  353. package/dist/rules/modules/stdlib/geometry.test.json +200 -0
  354. package/dist/rules/modules/stdlib/joining.rules +49 -0
  355. package/dist/rules/modules/stdlib/joining.test.json +287 -0
  356. package/dist/rules/modules/stdlib/lifecycle.rules +51 -0
  357. package/dist/rules/modules/stdlib/lifecycle.test.json +288 -0
  358. package/dist/rules/modules/stdlib/lobby.rules +44 -0
  359. package/dist/rules/modules/stdlib/lobby.test.json +32 -0
  360. package/dist/rules/modules/stdlib/membership.rules +40 -0
  361. package/dist/rules/modules/stdlib/membership.test.json +107 -0
  362. package/dist/rules/modules/stdlib/spaces.rules +46 -0
  363. package/dist/rules/modules/stdlib/spaces.test.json +392 -0
  364. package/dist/rules/modules/stdlib/state.rules +28 -0
  365. package/dist/rules/modules/stdlib/state.test.json +55 -0
  366. package/dist/rules/modules/stdlib/timing.rules +20 -0
  367. package/dist/rules/modules/stdlib/timing.test.json +106 -0
  368. package/dist/rules/modules/stdlib/transitions.rules +34 -0
  369. package/dist/rules/modules/stdlib/transitions.test.json +86 -0
  370. package/dist/rules/modules/stdlib/turns.rules +27 -0
  371. package/dist/rules/modules/stdlib/turns.test.json +64 -0
  372. package/dist/rules/modules/stdlib/validation.rules +31 -0
  373. package/dist/rules/modules/stdlib/validation.test.json +184 -0
  374. package/dist/rules/modules/stdlib-content.d.ts +11 -0
  375. package/dist/rules/modules/stdlib-content.d.ts.map +1 -0
  376. package/dist/rules/modules/stdlib-content.js +590 -0
  377. package/dist/rules/modules/stdlib-content.js.map +1 -0
  378. package/dist/rules/node.d.ts +17 -0
  379. package/dist/rules/node.d.ts.map +1 -0
  380. package/dist/rules/node.js +21 -0
  381. package/dist/rules/node.js.map +1 -0
  382. package/dist/rules/rtdb.d.ts +28 -0
  383. package/dist/rules/rtdb.d.ts.map +1 -0
  384. package/dist/rules/rtdb.js +15 -0
  385. package/dist/rules/rtdb.js.map +1 -0
  386. package/dist/rules/simulator/evaluator.d.ts +179 -0
  387. package/dist/rules/simulator/evaluator.d.ts.map +1 -0
  388. package/dist/rules/simulator/evaluator.js +1221 -0
  389. package/dist/rules/simulator/evaluator.js.map +1 -0
  390. package/dist/rules/simulator/expression/eval-errors.d.ts +86 -0
  391. package/dist/rules/simulator/expression/eval-errors.d.ts.map +1 -0
  392. package/dist/rules/simulator/expression/eval-errors.js +68 -0
  393. package/dist/rules/simulator/expression/eval-errors.js.map +1 -0
  394. package/dist/rules/simulator/expression/evaluator.d.ts +43 -0
  395. package/dist/rules/simulator/expression/evaluator.d.ts.map +1 -0
  396. package/dist/rules/simulator/expression/evaluator.js +298 -0
  397. package/dist/rules/simulator/expression/evaluator.js.map +1 -0
  398. package/dist/rules/simulator/expression/lexer.d.ts +36 -0
  399. package/dist/rules/simulator/expression/lexer.d.ts.map +1 -0
  400. package/dist/rules/simulator/expression/lexer.js +318 -0
  401. package/dist/rules/simulator/expression/lexer.js.map +1 -0
  402. package/dist/rules/simulator/expression/parser.d.ts +39 -0
  403. package/dist/rules/simulator/expression/parser.d.ts.map +1 -0
  404. package/dist/rules/simulator/expression/parser.js +329 -0
  405. package/dist/rules/simulator/expression/parser.js.map +1 -0
  406. package/dist/rules/simulator/expression/types.d.ts +137 -0
  407. package/dist/rules/simulator/expression/types.d.ts.map +1 -0
  408. package/dist/rules/simulator/expression/types.js +90 -0
  409. package/dist/rules/simulator/expression/types.js.map +1 -0
  410. package/dist/rules/simulator/expression/walk-data.d.ts +52 -0
  411. package/dist/rules/simulator/expression/walk-data.d.ts.map +1 -0
  412. package/dist/rules/simulator/expression/walk-data.js +167 -0
  413. package/dist/rules/simulator/expression/walk-data.js.map +1 -0
  414. package/dist/rules/simulator/firestore-set.d.ts +25 -0
  415. package/dist/rules/simulator/firestore-set.d.ts.map +1 -0
  416. package/dist/rules/simulator/firestore-set.js +89 -0
  417. package/dist/rules/simulator/firestore-set.js.map +1 -0
  418. package/dist/rules/simulator/handler.d.ts +36 -0
  419. package/dist/rules/simulator/handler.d.ts.map +1 -0
  420. package/dist/rules/simulator/handler.js +583 -0
  421. package/dist/rules/simulator/handler.js.map +1 -0
  422. package/dist/rules/simulator/mapdiff.d.ts +29 -0
  423. package/dist/rules/simulator/mapdiff.d.ts.map +1 -0
  424. package/dist/rules/simulator/mapdiff.js +72 -0
  425. package/dist/rules/simulator/mapdiff.js.map +1 -0
  426. package/dist/rules/simulator/project-after-state.d.ts +33 -0
  427. package/dist/rules/simulator/project-after-state.d.ts.map +1 -0
  428. package/dist/rules/simulator/project-after-state.js +88 -0
  429. package/dist/rules/simulator/project-after-state.js.map +1 -0
  430. package/dist/rules/simulator/query-proof.d.ts +80 -0
  431. package/dist/rules/simulator/query-proof.d.ts.map +1 -0
  432. package/dist/rules/simulator/query-proof.js +142 -0
  433. package/dist/rules/simulator/query-proof.js.map +1 -0
  434. package/dist/rules/simulator/value-equality.d.ts +8 -0
  435. package/dist/rules/simulator/value-equality.d.ts.map +1 -0
  436. package/dist/rules/simulator/value-equality.js +40 -0
  437. package/dist/rules/simulator/value-equality.js.map +1 -0
  438. package/dist/rules/simulator/wrappers/base.d.ts +129 -0
  439. package/dist/rules/simulator/wrappers/base.d.ts.map +1 -0
  440. package/dist/rules/simulator/wrappers/base.js +90 -0
  441. package/dist/rules/simulator/wrappers/base.js.map +1 -0
  442. package/dist/rules/simulator/wrappers/bytes.d.ts +45 -0
  443. package/dist/rules/simulator/wrappers/bytes.d.ts.map +1 -0
  444. package/dist/rules/simulator/wrappers/bytes.js +130 -0
  445. package/dist/rules/simulator/wrappers/bytes.js.map +1 -0
  446. package/dist/rules/simulator/wrappers/duration.d.ts +76 -0
  447. package/dist/rules/simulator/wrappers/duration.d.ts.map +1 -0
  448. package/dist/rules/simulator/wrappers/duration.js +176 -0
  449. package/dist/rules/simulator/wrappers/duration.js.map +1 -0
  450. package/dist/rules/simulator/wrappers/float.d.ts +52 -0
  451. package/dist/rules/simulator/wrappers/float.d.ts.map +1 -0
  452. package/dist/rules/simulator/wrappers/float.js +88 -0
  453. package/dist/rules/simulator/wrappers/float.js.map +1 -0
  454. package/dist/rules/simulator/wrappers/latlng.d.ts +40 -0
  455. package/dist/rules/simulator/wrappers/latlng.d.ts.map +1 -0
  456. package/dist/rules/simulator/wrappers/latlng.js +100 -0
  457. package/dist/rules/simulator/wrappers/latlng.js.map +1 -0
  458. package/dist/rules/simulator/wrappers/path.d.ts +75 -0
  459. package/dist/rules/simulator/wrappers/path.d.ts.map +1 -0
  460. package/dist/rules/simulator/wrappers/path.js +158 -0
  461. package/dist/rules/simulator/wrappers/path.js.map +1 -0
  462. package/dist/rules/simulator/wrappers/reference.d.ts +82 -0
  463. package/dist/rules/simulator/wrappers/reference.d.ts.map +1 -0
  464. package/dist/rules/simulator/wrappers/reference.js +145 -0
  465. package/dist/rules/simulator/wrappers/reference.js.map +1 -0
  466. package/dist/rules/simulator/wrappers/timestamp.d.ts +86 -0
  467. package/dist/rules/simulator/wrappers/timestamp.d.ts.map +1 -0
  468. package/dist/rules/simulator/wrappers/timestamp.js +207 -0
  469. package/dist/rules/simulator/wrappers/timestamp.js.map +1 -0
  470. package/dist/rules/simulator/wrappers/vector.d.ts +43 -0
  471. package/dist/rules/simulator/wrappers/vector.d.ts.map +1 -0
  472. package/dist/rules/simulator/wrappers/vector.js +80 -0
  473. package/dist/rules/simulator/wrappers/vector.js.map +1 -0
  474. package/dist/rules/simulator-tools-impl.d.ts +64 -0
  475. package/dist/rules/simulator-tools-impl.d.ts.map +1 -0
  476. package/dist/rules/simulator-tools-impl.js +462 -0
  477. package/dist/rules/simulator-tools-impl.js.map +1 -0
  478. package/dist/rules/simulator.d.ts +20 -0
  479. package/dist/rules/simulator.d.ts.map +1 -0
  480. package/dist/rules/simulator.js +24 -0
  481. package/dist/rules/simulator.js.map +1 -0
  482. package/dist/rules/stdlib-modules.d.ts +73 -0
  483. package/dist/rules/stdlib-modules.d.ts.map +1 -0
  484. package/dist/rules/stdlib-modules.js +849 -0
  485. package/dist/rules/stdlib-modules.js.map +1 -0
  486. package/dist/rules/stdlib-tools.d.ts +19 -0
  487. package/dist/rules/stdlib-tools.d.ts.map +1 -0
  488. package/dist/rules/stdlib-tools.js +164 -0
  489. package/dist/rules/stdlib-tools.js.map +1 -0
  490. package/dist/rules/test/handler.d.ts +9 -0
  491. package/dist/rules/test/handler.d.ts.map +1 -0
  492. package/dist/rules/test/handler.js +124 -0
  493. package/dist/rules/test/handler.js.map +1 -0
  494. package/dist/rules/test/spec.d.ts +517 -0
  495. package/dist/rules/test/spec.d.ts.map +1 -0
  496. package/dist/rules/test/spec.js +227 -0
  497. package/dist/rules/test/spec.js.map +1 -0
  498. package/dist/rules/tools.d.ts +41 -0
  499. package/dist/rules/tools.d.ts.map +1 -0
  500. package/dist/rules/tools.js +124 -0
  501. package/dist/rules/tools.js.map +1 -0
  502. package/dist/rules/write/handler.d.ts +6 -0
  503. package/dist/rules/write/handler.d.ts.map +1 -0
  504. package/dist/rules/write/handler.js +126 -0
  505. package/dist/rules/write/handler.js.map +1 -0
  506. package/dist/rules/write/spec.d.ts +28 -0
  507. package/dist/rules/write/spec.d.ts.map +1 -0
  508. package/dist/rules/write/spec.js +2 -0
  509. package/dist/rules/write/spec.js.map +1 -0
  510. package/dist/sandbox/admin-compat.d.ts +20 -0
  511. package/dist/sandbox/admin-compat.d.ts.map +1 -0
  512. package/dist/sandbox/admin-compat.js +19 -0
  513. package/dist/sandbox/admin-compat.js.map +1 -0
  514. package/dist/sandbox/admin-firestore/error-translation.d.ts +86 -0
  515. package/dist/sandbox/admin-firestore/error-translation.d.ts.map +1 -0
  516. package/dist/sandbox/admin-firestore/error-translation.js +204 -0
  517. package/dist/sandbox/admin-firestore/error-translation.js.map +1 -0
  518. package/dist/sandbox/admin-firestore/index.d.ts +169 -0
  519. package/dist/sandbox/admin-firestore/index.d.ts.map +1 -0
  520. package/dist/sandbox/admin-firestore/index.js +456 -0
  521. package/dist/sandbox/admin-firestore/index.js.map +1 -0
  522. package/dist/sandbox/admin-firestore/remote.d.ts +97 -0
  523. package/dist/sandbox/admin-firestore/remote.d.ts.map +1 -0
  524. package/dist/sandbox/admin-firestore/remote.js +735 -0
  525. package/dist/sandbox/admin-firestore/remote.js.map +1 -0
  526. package/dist/sandbox/branches/index.d.ts +141 -0
  527. package/dist/sandbox/branches/index.d.ts.map +1 -0
  528. package/dist/sandbox/branches/index.js +327 -0
  529. package/dist/sandbox/branches/index.js.map +1 -0
  530. package/dist/sandbox/firestore/admin-compat/batch.d.ts +34 -0
  531. package/dist/sandbox/firestore/admin-compat/batch.d.ts.map +1 -0
  532. package/dist/sandbox/firestore/admin-compat/batch.js +73 -0
  533. package/dist/sandbox/firestore/admin-compat/batch.js.map +1 -0
  534. package/dist/sandbox/firestore/admin-compat/doc-ref.d.ts +38 -0
  535. package/dist/sandbox/firestore/admin-compat/doc-ref.d.ts.map +1 -0
  536. package/dist/sandbox/firestore/admin-compat/doc-ref.js +154 -0
  537. package/dist/sandbox/firestore/admin-compat/doc-ref.js.map +1 -0
  538. package/dist/sandbox/firestore/admin-compat/firestore.d.ts +45 -0
  539. package/dist/sandbox/firestore/admin-compat/firestore.d.ts.map +1 -0
  540. package/dist/sandbox/firestore/admin-compat/firestore.js +114 -0
  541. package/dist/sandbox/firestore/admin-compat/firestore.js.map +1 -0
  542. package/dist/sandbox/firestore/admin-compat/index.d.ts +45 -0
  543. package/dist/sandbox/firestore/admin-compat/index.d.ts.map +1 -0
  544. package/dist/sandbox/firestore/admin-compat/index.js +27 -0
  545. package/dist/sandbox/firestore/admin-compat/index.js.map +1 -0
  546. package/dist/sandbox/firestore/admin-compat/paths.d.ts +37 -0
  547. package/dist/sandbox/firestore/admin-compat/paths.d.ts.map +1 -0
  548. package/dist/sandbox/firestore/admin-compat/paths.js +49 -0
  549. package/dist/sandbox/firestore/admin-compat/paths.js.map +1 -0
  550. package/dist/sandbox/firestore/admin-compat/query.d.ts +261 -0
  551. package/dist/sandbox/firestore/admin-compat/query.d.ts.map +1 -0
  552. package/dist/sandbox/firestore/admin-compat/query.js +704 -0
  553. package/dist/sandbox/firestore/admin-compat/query.js.map +1 -0
  554. package/dist/sandbox/firestore/admin-compat/read-translation.d.ts +8 -0
  555. package/dist/sandbox/firestore/admin-compat/read-translation.d.ts.map +1 -0
  556. package/dist/sandbox/firestore/admin-compat/read-translation.js +59 -0
  557. package/dist/sandbox/firestore/admin-compat/read-translation.js.map +1 -0
  558. package/dist/sandbox/firestore/admin-compat/snapshots.d.ts +39 -0
  559. package/dist/sandbox/firestore/admin-compat/snapshots.d.ts.map +1 -0
  560. package/dist/sandbox/firestore/admin-compat/snapshots.js +50 -0
  561. package/dist/sandbox/firestore/admin-compat/snapshots.js.map +1 -0
  562. package/dist/sandbox/firestore/admin-compat/transaction.d.ts +35 -0
  563. package/dist/sandbox/firestore/admin-compat/transaction.d.ts.map +1 -0
  564. package/dist/sandbox/firestore/admin-compat/transaction.js +88 -0
  565. package/dist/sandbox/firestore/admin-compat/transaction.js.map +1 -0
  566. package/dist/sandbox/firestore/admin-compat/types.d.ts +297 -0
  567. package/dist/sandbox/firestore/admin-compat/types.d.ts.map +1 -0
  568. package/dist/sandbox/firestore/admin-compat/types.js +127 -0
  569. package/dist/sandbox/firestore/admin-compat/types.js.map +1 -0
  570. package/dist/sandbox/firestore/admin-compat/value-order.d.ts +49 -0
  571. package/dist/sandbox/firestore/admin-compat/value-order.d.ts.map +1 -0
  572. package/dist/sandbox/firestore/admin-compat/value-order.js +172 -0
  573. package/dist/sandbox/firestore/admin-compat/value-order.js.map +1 -0
  574. package/dist/sandbox/firestore/auto-id.d.ts +26 -0
  575. package/dist/sandbox/firestore/auto-id.d.ts.map +1 -0
  576. package/dist/sandbox/firestore/auto-id.js +36 -0
  577. package/dist/sandbox/firestore/auto-id.js.map +1 -0
  578. package/dist/sandbox/firestore/converters/bytes-geopoint.d.ts +48 -0
  579. package/dist/sandbox/firestore/converters/bytes-geopoint.d.ts.map +1 -0
  580. package/dist/sandbox/firestore/converters/bytes-geopoint.js +85 -0
  581. package/dist/sandbox/firestore/converters/bytes-geopoint.js.map +1 -0
  582. package/dist/sandbox/firestore/converters/fieldvalue.d.ts +69 -0
  583. package/dist/sandbox/firestore/converters/fieldvalue.d.ts.map +1 -0
  584. package/dist/sandbox/firestore/converters/fieldvalue.js +166 -0
  585. package/dist/sandbox/firestore/converters/fieldvalue.js.map +1 -0
  586. package/dist/sandbox/firestore/converters/reference.d.ts +31 -0
  587. package/dist/sandbox/firestore/converters/reference.d.ts.map +1 -0
  588. package/dist/sandbox/firestore/converters/reference.js +51 -0
  589. package/dist/sandbox/firestore/converters/reference.js.map +1 -0
  590. package/dist/sandbox/firestore/converters/timestamp.d.ts +32 -0
  591. package/dist/sandbox/firestore/converters/timestamp.d.ts.map +1 -0
  592. package/dist/sandbox/firestore/converters/timestamp.js +63 -0
  593. package/dist/sandbox/firestore/converters/timestamp.js.map +1 -0
  594. package/dist/sandbox/firestore/converters/user-timestamp.d.ts +46 -0
  595. package/dist/sandbox/firestore/converters/user-timestamp.d.ts.map +1 -0
  596. package/dist/sandbox/firestore/converters/user-timestamp.js +65 -0
  597. package/dist/sandbox/firestore/converters/user-timestamp.js.map +1 -0
  598. package/dist/sandbox/firestore/converters/vector.d.ts +24 -0
  599. package/dist/sandbox/firestore/converters/vector.d.ts.map +1 -0
  600. package/dist/sandbox/firestore/converters/vector.js +53 -0
  601. package/dist/sandbox/firestore/converters/vector.js.map +1 -0
  602. package/dist/sandbox/firestore/errors.d.ts +82 -0
  603. package/dist/sandbox/firestore/errors.d.ts.map +1 -0
  604. package/dist/sandbox/firestore/errors.js +54 -0
  605. package/dist/sandbox/firestore/errors.js.map +1 -0
  606. package/dist/sandbox/firestore/event-log.d.ts +99 -0
  607. package/dist/sandbox/firestore/event-log.d.ts.map +1 -0
  608. package/dist/sandbox/firestore/event-log.js +67 -0
  609. package/dist/sandbox/firestore/event-log.js.map +1 -0
  610. package/dist/sandbox/firestore/field-merge.d.ts +64 -0
  611. package/dist/sandbox/firestore/field-merge.d.ts.map +1 -0
  612. package/dist/sandbox/firestore/field-merge.js +221 -0
  613. package/dist/sandbox/firestore/field-merge.js.map +1 -0
  614. package/dist/sandbox/firestore/list-query-proof.d.ts +77 -0
  615. package/dist/sandbox/firestore/list-query-proof.d.ts.map +1 -0
  616. package/dist/sandbox/firestore/list-query-proof.js +170 -0
  617. package/dist/sandbox/firestore/list-query-proof.js.map +1 -0
  618. package/dist/sandbox/firestore/local-environment.d.ts +806 -0
  619. package/dist/sandbox/firestore/local-environment.d.ts.map +1 -0
  620. package/dist/sandbox/firestore/local-environment.js +3028 -0
  621. package/dist/sandbox/firestore/local-environment.js.map +1 -0
  622. package/dist/sandbox/firestore/local-state.d.ts +196 -0
  623. package/dist/sandbox/firestore/local-state.d.ts.map +1 -0
  624. package/dist/sandbox/firestore/local-state.js +413 -0
  625. package/dist/sandbox/firestore/local-state.js.map +1 -0
  626. package/dist/sandbox/firestore/overlay-backing.d.ts +44 -0
  627. package/dist/sandbox/firestore/overlay-backing.d.ts.map +1 -0
  628. package/dist/sandbox/firestore/overlay-backing.js +82 -0
  629. package/dist/sandbox/firestore/overlay-backing.js.map +1 -0
  630. package/dist/sandbox/firestore/sentinel-capture.d.ts +30 -0
  631. package/dist/sandbox/firestore/sentinel-capture.d.ts.map +1 -0
  632. package/dist/sandbox/firestore/sentinel-capture.js +61 -0
  633. package/dist/sandbox/firestore/sentinel-capture.js.map +1 -0
  634. package/dist/sandbox/firestore/snapshot-listeners.d.ts +284 -0
  635. package/dist/sandbox/firestore/snapshot-listeners.d.ts.map +1 -0
  636. package/dist/sandbox/firestore/snapshot-listeners.js +194 -0
  637. package/dist/sandbox/firestore/snapshot-listeners.js.map +1 -0
  638. package/dist/sandbox/firestore/topk.d.ts +12 -0
  639. package/dist/sandbox/firestore/topk.d.ts.map +1 -0
  640. package/dist/sandbox/firestore/topk.js +42 -0
  641. package/dist/sandbox/firestore/topk.js.map +1 -0
  642. package/dist/sandbox/firestore/transaction-merge.d.ts +55 -0
  643. package/dist/sandbox/firestore/transaction-merge.d.ts.map +1 -0
  644. package/dist/sandbox/firestore/transaction-merge.js +107 -0
  645. package/dist/sandbox/firestore/transaction-merge.js.map +1 -0
  646. package/dist/sandbox/firestore/transaction-types.d.ts +152 -0
  647. package/dist/sandbox/firestore/transaction-types.d.ts.map +1 -0
  648. package/dist/sandbox/firestore/transaction-types.js +10 -0
  649. package/dist/sandbox/firestore/transaction-types.js.map +1 -0
  650. package/dist/sandbox/firestore/transaction.d.ts +79 -0
  651. package/dist/sandbox/firestore/transaction.d.ts.map +1 -0
  652. package/dist/sandbox/firestore/transaction.js +95 -0
  653. package/dist/sandbox/firestore/transaction.js.map +1 -0
  654. package/dist/sandbox/firestore/value-equality.d.ts +2 -0
  655. package/dist/sandbox/firestore/value-equality.d.ts.map +1 -0
  656. package/dist/sandbox/firestore/value-equality.js +35 -0
  657. package/dist/sandbox/firestore/value-equality.js.map +1 -0
  658. package/dist/sandbox/firestore/value-resolver.d.ts +172 -0
  659. package/dist/sandbox/firestore/value-resolver.d.ts.map +1 -0
  660. package/dist/sandbox/firestore/value-resolver.js +221 -0
  661. package/dist/sandbox/firestore/value-resolver.js.map +1 -0
  662. package/dist/sandbox/firestore/wire-encoder.d.ts +14 -0
  663. package/dist/sandbox/firestore/wire-encoder.d.ts.map +1 -0
  664. package/dist/sandbox/firestore/wire-encoder.js +130 -0
  665. package/dist/sandbox/firestore/wire-encoder.js.map +1 -0
  666. package/dist/sandbox/index.d.ts +50 -0
  667. package/dist/sandbox/index.d.ts.map +1 -0
  668. package/dist/sandbox/index.js +63 -0
  669. package/dist/sandbox/index.js.map +1 -0
  670. package/dist/sandbox/internal/index.d.ts +36 -0
  671. package/dist/sandbox/internal/index.d.ts.map +1 -0
  672. package/dist/sandbox/internal/index.js +72 -0
  673. package/dist/sandbox/internal/index.js.map +1 -0
  674. package/dist/sandbox/internal/sandbox-impl.d.ts +343 -0
  675. package/dist/sandbox/internal/sandbox-impl.d.ts.map +1 -0
  676. package/dist/sandbox/internal/sandbox-impl.js +718 -0
  677. package/dist/sandbox/internal/sandbox-impl.js.map +1 -0
  678. package/dist/sandbox/persistence/backends.d.ts +37 -0
  679. package/dist/sandbox/persistence/backends.d.ts.map +1 -0
  680. package/dist/sandbox/persistence/backends.js +202 -0
  681. package/dist/sandbox/persistence/backends.js.map +1 -0
  682. package/dist/sandbox/persistence/chunk-format.d.ts +58 -0
  683. package/dist/sandbox/persistence/chunk-format.d.ts.map +1 -0
  684. package/dist/sandbox/persistence/chunk-format.js +163 -0
  685. package/dist/sandbox/persistence/chunk-format.js.map +1 -0
  686. package/dist/sandbox/persistence/controller.d.ts +39 -0
  687. package/dist/sandbox/persistence/controller.d.ts.map +1 -0
  688. package/dist/sandbox/persistence/controller.js +605 -0
  689. package/dist/sandbox/persistence/controller.js.map +1 -0
  690. package/dist/sandbox/persistence/index.d.ts +13 -0
  691. package/dist/sandbox/persistence/index.d.ts.map +1 -0
  692. package/dist/sandbox/persistence/index.js +5 -0
  693. package/dist/sandbox/persistence/index.js.map +1 -0
  694. package/dist/sandbox/persistence/serialize.d.ts +53 -0
  695. package/dist/sandbox/persistence/serialize.d.ts.map +1 -0
  696. package/dist/sandbox/persistence/serialize.js +98 -0
  697. package/dist/sandbox/persistence/serialize.js.map +1 -0
  698. package/dist/sandbox/persistence/types.d.ts +118 -0
  699. package/dist/sandbox/persistence/types.d.ts.map +1 -0
  700. package/dist/sandbox/persistence/types.js +15 -0
  701. package/dist/sandbox/persistence/types.js.map +1 -0
  702. package/dist/sandbox/remote.d.ts +118 -0
  703. package/dist/sandbox/remote.d.ts.map +1 -0
  704. package/dist/sandbox/remote.js +60 -0
  705. package/dist/sandbox/remote.js.map +1 -0
  706. package/dist/sandbox/replay/index.d.ts +106 -0
  707. package/dist/sandbox/replay/index.d.ts.map +1 -0
  708. package/dist/sandbox/replay/index.js +246 -0
  709. package/dist/sandbox/replay/index.js.map +1 -0
  710. package/dist/sandbox/sandbox-context.d.ts +40 -0
  711. package/dist/sandbox/sandbox-context.d.ts.map +1 -0
  712. package/dist/sandbox/sandbox-context.js +72 -0
  713. package/dist/sandbox/sandbox-context.js.map +1 -0
  714. package/dist/sandbox/tab-sync/index.d.ts +120 -0
  715. package/dist/sandbox/tab-sync/index.d.ts.map +1 -0
  716. package/dist/sandbox/tab-sync/index.js +272 -0
  717. package/dist/sandbox/tab-sync/index.js.map +1 -0
  718. package/dist/sandbox/types.d.ts +1235 -0
  719. package/dist/sandbox/types.d.ts.map +1 -0
  720. package/dist/sandbox/types.js +46 -0
  721. package/dist/sandbox/types.js.map +1 -0
  722. package/dist/storage/admin/api.d.ts +206 -0
  723. package/dist/storage/admin/api.d.ts.map +1 -0
  724. package/dist/storage/admin/api.js +349 -0
  725. package/dist/storage/admin/api.js.map +1 -0
  726. package/dist/storage/admin/handler.d.ts +29 -0
  727. package/dist/storage/admin/handler.d.ts.map +1 -0
  728. package/dist/storage/admin/handler.js +82 -0
  729. package/dist/storage/admin/handler.js.map +1 -0
  730. package/dist/storage/admin/spec.d.ts +64 -0
  731. package/dist/storage/admin/spec.d.ts.map +1 -0
  732. package/dist/storage/admin/spec.js +8 -0
  733. package/dist/storage/admin/spec.js.map +1 -0
  734. package/dist/storage/admin/tools.d.ts +23 -0
  735. package/dist/storage/admin/tools.d.ts.map +1 -0
  736. package/dist/storage/admin/tools.js +90 -0
  737. package/dist/storage/admin/tools.js.map +1 -0
  738. package/dist/storage/download.d.ts +27 -0
  739. package/dist/storage/download.d.ts.map +1 -0
  740. package/dist/storage/download.js +136 -0
  741. package/dist/storage/download.js.map +1 -0
  742. package/dist/storage/enforce.d.ts +26 -0
  743. package/dist/storage/enforce.d.ts.map +1 -0
  744. package/dist/storage/enforce.js +16 -0
  745. package/dist/storage/enforce.js.map +1 -0
  746. package/dist/storage/errors.d.ts +46 -0
  747. package/dist/storage/errors.d.ts.map +1 -0
  748. package/dist/storage/errors.js +62 -0
  749. package/dist/storage/errors.js.map +1 -0
  750. package/dist/storage/index.d.ts +49 -0
  751. package/dist/storage/index.d.ts.map +1 -0
  752. package/dist/storage/index.js +60 -0
  753. package/dist/storage/index.js.map +1 -0
  754. package/dist/storage/internal.d.ts +18 -0
  755. package/dist/storage/internal.d.ts.map +1 -0
  756. package/dist/storage/internal.js +18 -0
  757. package/dist/storage/internal.js.map +1 -0
  758. package/dist/storage/list.d.ts +17 -0
  759. package/dist/storage/list.d.ts.map +1 -0
  760. package/dist/storage/list.js +91 -0
  761. package/dist/storage/list.js.map +1 -0
  762. package/dist/storage/metadata.d.ts +86 -0
  763. package/dist/storage/metadata.d.ts.map +1 -0
  764. package/dist/storage/metadata.js +167 -0
  765. package/dist/storage/metadata.js.map +1 -0
  766. package/dist/storage/persistence.d.ts +134 -0
  767. package/dist/storage/persistence.d.ts.map +1 -0
  768. package/dist/storage/persistence.js +132 -0
  769. package/dist/storage/persistence.js.map +1 -0
  770. package/dist/storage/reference.d.ts +63 -0
  771. package/dist/storage/reference.d.ts.map +1 -0
  772. package/dist/storage/reference.js +156 -0
  773. package/dist/storage/reference.js.map +1 -0
  774. package/dist/storage/rules.d.ts +176 -0
  775. package/dist/storage/rules.d.ts.map +1 -0
  776. package/dist/storage/rules.js +621 -0
  777. package/dist/storage/rules.js.map +1 -0
  778. package/dist/storage/service.d.ts +139 -0
  779. package/dist/storage/service.d.ts.map +1 -0
  780. package/dist/storage/service.js +241 -0
  781. package/dist/storage/service.js.map +1 -0
  782. package/dist/storage/upload.d.ts +43 -0
  783. package/dist/storage/upload.d.ts.map +1 -0
  784. package/dist/storage/upload.js +235 -0
  785. package/dist/storage/upload.js.map +1 -0
  786. package/package.json +109 -3
@@ -0,0 +1,1235 @@
1
+ /**
2
+ * Public type surface for `pyric/sandbox`.
3
+ *
4
+ * Kept service-agnostic on purpose: `/app` is the host the rest of the
5
+ * library plugs into. Service modules (`/firestore`, future `/storage`,
6
+ * `/auth`, `/database`) depend on these types; they don't ship from
7
+ * here. See design rationale for the dependency-direction
8
+ * argument.
9
+ */
10
+ import type { SandboxPersistenceOptions } from './persistence/types.js';
11
+ import type { TabSyncOptions } from './tab-sync/index.js';
12
+ /**
13
+ * A signed-in identity for sandbox operations. `null` is anonymous.
14
+ *
15
+ * `token` is the Firebase Auth token claims map (custom claims plus
16
+ * standard ones). It surfaces the same way it does in production rules
17
+ * via `request.auth.token.*`. Omit it for plain UID-only auth.
18
+ *
19
+ * Renamed from `AuthContext` (pre-multi-context) so the data type
20
+ * doesn't visually collide with `SandboxContext` (the identity-bearing
21
+ * handle). They sit at different layers — payload vs. handle — and the
22
+ * names should reflect that.
23
+ */
24
+ export type AuthState = {
25
+ uid: string;
26
+ token?: Record<string, unknown>;
27
+ } | null;
28
+ /**
29
+ * Initialization config for a sandbox. All fields are optional; an
30
+ * empty config produces a sandbox with no rules and no seeded data.
31
+ *
32
+ * **No `auth` field.** Identity belongs to {@link SandboxContext}, not
33
+ * the sandbox. Service handles always require an explicit context.
34
+ */
35
+ export interface SandboxConfig {
36
+ }
37
+ /**
38
+ * Error codes raised by the sandbox layer.
39
+ *
40
+ * The first batch matches Firebase / gRPC conventions so existing
41
+ * `if (e.code === 'permission-denied')` code from production paths
42
+ * keeps working. The second batch is sandbox-specific and exists so
43
+ * agents can distinguish "sandbox doesn't simulate this" from "your
44
+ * code is wrong" without parsing message strings.
45
+ */
46
+ export type SandboxErrorCode = 'invalid-argument' | 'permission-denied' | 'not-found' | 'already-exists' | 'failed-precondition' | 'aborted' | 'unavailable' | 'unimplemented' | 'not-seeded' | 'rules-not-loaded';
47
+ /**
48
+ * Structured denial context emitted alongside a `permission-denied`
49
+ * error. Real Firebase strips this server-side for security; the
50
+ * sandbox can expose it because it's a development tool.
51
+ *
52
+ * `auth` and `reasons` are populated whenever the sandbox raises a
53
+ * `permission-denied` error. `rule` (line + expression) requires
54
+ * source-position tracking in the rules AST and is deferred — see
55
+ * design rationale "Open questions" for the follow-up.
56
+ * `failedFields` will be filled in once the evaluator surfaces field-
57
+ * reference traces.
58
+ */
59
+ export interface DenialContext {
60
+ /** The rule whose evaluation produced the denial. Best effort; may be absent until source positions land in the AST. */
61
+ rule?: {
62
+ line: number;
63
+ expression: string;
64
+ };
65
+ /** Auth identity that was active when the denial fired. */
66
+ auth?: AuthState;
67
+ /** Field paths in `request.resource.data` that the rule referenced and that failed. */
68
+ failedFields?: string[];
69
+ /**
70
+ * Raw simulator reasoning lines (the underlying engine's
71
+ * `debugMessages`). Always present on `permission-denied`. Stable
72
+ * enough for log surfacing; not stable as machine-parseable data.
73
+ */
74
+ reasons?: string[];
75
+ /**
76
+ * Eval-time request shape — what the rule saw on `request.*`. Lets
77
+ * callers render a "why did this deny" frame (auth, method, path,
78
+ * `request.resource.data` with sentinels resolved) without re-deriving
79
+ * any of it from out-of-band state.
80
+ */
81
+ request?: {
82
+ method: 'get' | 'list' | 'create' | 'update' | 'delete';
83
+ path: string;
84
+ /**
85
+ * The user's proposed `request.resource.data` — pre-resolution.
86
+ * `FieldValue.*` sentinels are preserved as their marker shapes
87
+ * (`{ __type: 'serverTimestamp' }`, etc.). The rule engine
88
+ * evaluated against the resolved form; what surfaces here is the
89
+ * caller's INTENT so consumers see what they tried to write.
90
+ * Absent for reads (no proposed write) and for `delete` (no payload).
91
+ */
92
+ resourceData?: Record<string, unknown>;
93
+ };
94
+ /**
95
+ * Eval-time existing-document snapshot — what the rule saw on
96
+ * `resource.data`. `null` data with `exists: false` mirrors how the
97
+ * rule sees an absent doc. Absent for collection ops (`list`).
98
+ */
99
+ resource?: {
100
+ data: Record<string, unknown> | null;
101
+ exists: boolean;
102
+ };
103
+ }
104
+ /**
105
+ * Options bag for `SandboxError`. Used by call sites that want to
106
+ * attach actionable remediation text (or both denial context and
107
+ * remediation) without juggling positional argument order.
108
+ */
109
+ export interface SandboxErrorOptions {
110
+ code: SandboxErrorCode;
111
+ message: string;
112
+ denialContext?: DenialContext;
113
+ /**
114
+ * Optional human-readable guidance appended to the error's
115
+ * `.message` so existing consumers that surface `error.message`
116
+ * (logs, UIs) see the remediation without an API change. Stored on
117
+ * the instance as well so structured callers can read it directly.
118
+ */
119
+ remediation?: string;
120
+ }
121
+ /**
122
+ * Sandbox-layer error. Catch with `instanceof SandboxError` and switch
123
+ * on `code`. `denialContext` is populated for `permission-denied` only
124
+ * (and only after Slice 4 wires it through).
125
+ *
126
+ * Two construction forms are supported:
127
+ * - Positional: `new SandboxError(code, message, denialContext?)` —
128
+ * the original signature, kept for backward compatibility with
129
+ * existing internal call sites.
130
+ * - Options bag: `new SandboxError({ code, message, remediation? })` —
131
+ * used when attaching remediation guidance.
132
+ */
133
+ export declare class SandboxError extends Error {
134
+ readonly code: SandboxErrorCode;
135
+ readonly denialContext?: DenialContext;
136
+ readonly remediation?: string;
137
+ constructor(code: SandboxErrorCode, message: string, denialContext?: DenialContext);
138
+ constructor(options: SandboxErrorOptions);
139
+ }
140
+ /**
141
+ * Contract for a service that can contribute its state to the sandbox
142
+ * persistence layer. Services (auth, storage, database) register
143
+ * themselves via {@link Sandbox.registerPersistableService} so the
144
+ * sandbox core stays service-agnostic — the sandbox doesn't know what
145
+ * auth or storage look like; it just calls `snapshot()` / `restore()`.
146
+ *
147
+ * `subscribe` is optional but strongly recommended: without it, a
148
+ * service's changes (e.g. new users created via auth) only reach the
149
+ * persisted blob on the next Firestore write. With `subscribe`, the
150
+ * controller debounces a flush on every user-DB change — same latency
151
+ * as Firestore writes.
152
+ */
153
+ export interface PersistableService {
154
+ /**
155
+ * Return a plain-JSON-serializable snapshot of this service's state.
156
+ * Called by the persistence controller on every flush. The return
157
+ * value is stored under the service's registered name in the
158
+ * `services` map of the persisted blob.
159
+ */
160
+ snapshot(): unknown;
161
+ /**
162
+ * Restore previously snapshotted state. Called once during
163
+ * `enablePersistence`, AFTER Firestore docs have been restored (so
164
+ * any service that needs Firestore to be hydrated first can rely on
165
+ * that ordering). Guard against bad data — the blob came from disk
166
+ * and may be stale or from a schema migration.
167
+ */
168
+ restore(data: unknown): void;
169
+ /**
170
+ * Optional: subscribe to changes in this service's state. When
171
+ * provided, the persistence controller hooks it up and schedules
172
+ * a debounced flush on each change — ensuring auth-user edits reach
173
+ * the backend promptly, not only on the next Firestore write.
174
+ *
175
+ * Must return an unsubscribe function. The controller unsubscribes
176
+ * on `dispose()`.
177
+ */
178
+ subscribe?: (onChange: () => void) => () => void;
179
+ /**
180
+ * Optional: session-level persistence hooks. When provided, the
181
+ * persistence controller uses these to save and restore the CURRENTLY
182
+ * SIGNED-IN user (not the user database — that's `snapshot`/`restore`).
183
+ *
184
+ * The controller calls `session.subscribe` so it hears every sign-in /
185
+ * sign-out, then writes the uid to the appropriate web-storage slot
186
+ * (determined by `session.mode()`). On init, the controller reads the
187
+ * stored uid and calls `session.restore(uid)` to re-establish the
188
+ * session, firing `onAuthStateChanged` as if the user just signed in.
189
+ *
190
+ * Only active when `SandboxPersistenceOptions.sessionStorage` is
191
+ * provided; omitting `sessionStorage` causes the controller to skip
192
+ * session persistence entirely (no fake durability).
193
+ *
194
+ * Auth is the only service that provides session hooks today. The
195
+ * field is on the generic interface so the controller stays
196
+ * service-agnostic — if a second service ever needs session-style
197
+ * semantics it can add its own hooks without changing the controller.
198
+ */
199
+ session?: {
200
+ /**
201
+ * The uid of the currently signed-in user, or null when signed out.
202
+ * Read by the controller after a subscription fires, and before a
203
+ * save, to snapshot the current state.
204
+ */
205
+ currentUid(): string | null;
206
+ /**
207
+ * Re-establish the signed-in session for `uid`. Fires
208
+ * `onAuthStateChanged` as if the user just signed in. May throw
209
+ * `auth/user-not-found` or `auth/user-disabled` — the controller
210
+ * catches and clears the stored session so a stale uid (user deleted
211
+ * between sessions) doesn't crash init.
212
+ */
213
+ restore(uid: string): void;
214
+ /**
215
+ * Current persistence mode. Determines which web-storage slot the
216
+ * controller writes to:
217
+ * LOCAL → localStorage (survives reload + restart; Firebase default)
218
+ * SESSION → sessionStorage (survives reload, cleared on tab close)
219
+ * NONE → not stored
220
+ *
221
+ * Read on every save so a `setPersistence` call is reflected in the
222
+ * next write without an explicit migration step.
223
+ */
224
+ mode(): 'LOCAL' | 'SESSION' | 'NONE';
225
+ /**
226
+ * Subscribe to sign-in / sign-out changes. The controller installs
227
+ * exactly one subscription here and uses it to drive session saves.
228
+ * Must return an unsubscribe function.
229
+ *
230
+ * Note: this fires on any currentUser change, including external
231
+ * mutations (sandbox.reset(), another handle's sign-in). The
232
+ * controller reads `currentUid()` + `mode()` on each fire and
233
+ * re-computes the correct storage slot — no stale references.
234
+ */
235
+ subscribe(onChange: () => void): () => void;
236
+ };
237
+ }
238
+ /**
239
+ * Sandbox-level snapshot — a coarse capture of every service's state
240
+ * keyed by service name. The `firestore` key is always present; the
241
+ * `services` map holds one entry per registered persistable service
242
+ * (auth users, future storage objects, etc.). Service-specific
243
+ * snapshot types live in their service modules; `/app` keeps the index
244
+ * structural so it stays decoupled from service implementations.
245
+ *
246
+ * v2 shape — `services` was added when the persistable-service registry
247
+ * landed. Prior `{ firestore }` v1 blobs are treated as having an empty
248
+ * `services` map on restore.
249
+ */
250
+ export interface SandboxSnapshot {
251
+ /** Firestore documents, keyed by full path. Always present — empty
252
+ * `{}` for a fresh or just-reset sandbox. Per-document values are
253
+ * the post-resolution state the keyspace stored. */
254
+ firestore: Record<string, Record<string, unknown>>;
255
+ /**
256
+ * Per-service opaque state, keyed by service name (e.g. `'auth'`).
257
+ * Each entry is whatever the service's `PersistableService.snapshot()`
258
+ * returned. May be `{}` when no services are registered.
259
+ */
260
+ services: Record<string, unknown>;
261
+ }
262
+ /**
263
+ * Admin-plane access — bypasses rules, intended for test assertions
264
+ * ("did the write actually land?"). Surfaced only on the root sandbox
265
+ * because admin reads are identity-agnostic and presenting them on a
266
+ * fork (which exists to *carry* an identity) is conceptually muddled.
267
+ *
268
+ * The shape is intentionally flat for v1 since only Firestore exists.
269
+ * When other services land, this surface namespaces by service
270
+ * (`admin.firestore.getDocument`, `admin.storage.getObject`) and the
271
+ * current flat methods will move under `admin.firestore.*`. Document
272
+ * the migration loudly when it happens.
273
+ */
274
+ export interface SandboxAdmin {
275
+ /**
276
+ * Read a Firestore document by full path, ignoring rules. Returns
277
+ * `null` if the document doesn't exist.
278
+ */
279
+ getDocument(path: string): unknown | null;
280
+ /**
281
+ * List Firestore documents under a collection path, ignoring rules.
282
+ * Returns `{ path, data, phantom? }` records — `phantom: true` marks
283
+ * synthesized parent docs that have descendants but no stored data
284
+ * of their own (matches what a live Firestore listing would expose).
285
+ */
286
+ listDocuments(prefix: string): {
287
+ path: string;
288
+ data: unknown;
289
+ phantom?: true;
290
+ }[];
291
+ /**
292
+ * Write a Firestore document by full path, ignoring rules. Creates
293
+ * or overwrites the doc — same "replace" semantics as the user-plane
294
+ * `setDoc(ref, data)` (no merge). Intended for admin tools like the
295
+ * playground's Firestore explorer where the operator should be able
296
+ * to seed/edit data regardless of what rules say.
297
+ *
298
+ * Listeners fire as if the write had gone through the rules path,
299
+ * so subscriptions see the change live. Emits a `request` event with
300
+ * `result: 'allow'` and an `auth: null` shape — admin writes leave
301
+ * a trace in the event log, but aren't gated.
302
+ */
303
+ setDocument(path: string, data: Record<string, unknown>): void;
304
+ /**
305
+ * Delete a Firestore document by full path, ignoring rules. Returns
306
+ * `{ deleted }` reflecting whether a doc was actually removed
307
+ * (`false` if the path didn't exist). Idempotent.
308
+ *
309
+ * Same listener / event-log semantics as {@link setDocument}.
310
+ */
311
+ deleteDocument(path: string): {
312
+ deleted: boolean;
313
+ };
314
+ }
315
+ /**
316
+ * A Firebase sandbox — an isolated environment with one auth identity.
317
+ *
318
+ * Created via `initializeSandbox(config)`. Use `fork({ auth })` to
319
+ * derive a new sandbox with a different identity that shares the
320
+ * underlying environment (rules, data, state). Fork is the only
321
+ * identity-switching mechanism — there are no per-op auth overrides
322
+ * and no in-place mutation.
323
+ */
324
+ /**
325
+ * Eval-time payload emitted to {@link Sandbox.onDenial} subscribers.
326
+ *
327
+ * Mirrors the structured fields {@link DenialContext} carries (`request`
328
+ * + `resource` + `reasons` + `auth`) so a host environment that wants
329
+ * to surface denials independent of try/catch behavior gets the same
330
+ * frame either way.
331
+ */
332
+ export interface DenialEvent {
333
+ code: 'permission-denied';
334
+ message: string;
335
+ auth?: AuthState;
336
+ request?: {
337
+ method: 'get' | 'list' | 'create' | 'update' | 'delete';
338
+ path: string;
339
+ resourceData?: Record<string, unknown>;
340
+ };
341
+ resource?: {
342
+ data: Record<string, unknown> | null;
343
+ exists: boolean;
344
+ };
345
+ reasons?: string[];
346
+ }
347
+ /**
348
+ * Eval-time payload emitted to {@link Sandbox.onSnapshotError} subscribers.
349
+ *
350
+ * Stream-level error from a Firestore `onSnapshot` listener — the
351
+ * listener has been silently terminated and will deliver no further
352
+ * snapshots (matches production: a stream error is once-per-stream and
353
+ * the listener stays "subscribed" from the consumer's perspective but
354
+ * receives nothing further). Carries the `target` so the host UI can
355
+ * attribute the error to a specific watch.
356
+ *
357
+ * Currently `permission-denied` is the only code the sandbox produces
358
+ * (production also emits `unavailable`, `aborted`, `resource-exhausted`
359
+ * — none of which have a sandbox analog: no network stream to drop, no
360
+ * quota, no concurrent transactions to conflict). Documented divergence
361
+ * from production; new codes can be added if a sandbox-specific
362
+ * scenario surfaces them.
363
+ */
364
+ export interface SnapshotErrorEvent {
365
+ code: 'permission-denied';
366
+ message: string;
367
+ target: {
368
+ kind: 'doc';
369
+ path: string;
370
+ } | {
371
+ kind: 'query';
372
+ collection: string;
373
+ };
374
+ auth?: AuthState;
375
+ request?: {
376
+ method: 'get' | 'list' | 'create' | 'update' | 'delete';
377
+ path: string;
378
+ resourceData?: Record<string, unknown>;
379
+ };
380
+ resource?: {
381
+ data: Record<string, unknown> | null;
382
+ exists: boolean;
383
+ };
384
+ reasons?: string[];
385
+ }
386
+ /**
387
+ * Eval-time payload emitted to {@link Sandbox.onRequest} subscribers —
388
+ * one per evaluated op, regardless of outcome.
389
+ *
390
+ * Issue #307: the playground today only renders denials, but every op
391
+ * the simulator evaluates is a request worth seeing. This event is the
392
+ * source of truth; {@link DenialEvent} is a filtered projection over
393
+ * the `result === 'deny'` subset.
394
+ *
395
+ * Origin tells the consumer who initiated the eval:
396
+ * - `user` single op via the data-plane adapter (admin / firestore).
397
+ * - `batch` part of a multi-op batch — shares `groupId` with siblings.
398
+ * - `transaction` part of a transaction commit — shares `groupId`.
399
+ * - `listener` a write or `deployRules` triggered a snapshot listener
400
+ * to re-evaluate. Carries `triggeredBy` naming the
401
+ * originating user op (when knowable).
402
+ *
403
+ * `evalMs` measures the wall-clock duration of the simulator's
404
+ * `simulate(...)` call. Sub-millisecond is normal for simple rules;
405
+ * rule-engine-heavy rules (deep boolean chains, many get() calls) can
406
+ * reach tens of milliseconds; a traffic-monitor validation probe measured
407
+ * connect-four rules at ~95ms p99. Surface this in your UI when it matters.
408
+ *
409
+ * Listener throws are swallowed by the dispatcher so a faulty
410
+ * subscriber can't change rule semantics or hide other events.
411
+ *
412
+ * @see traffic-monitor-decision.md for the field-by-field rationale.
413
+ */
414
+ export interface RequestEvent {
415
+ /** Discriminator. */
416
+ kind: 'request';
417
+ /** Unique within a sandbox process. Useful for React list keys. */
418
+ id: string;
419
+ /** Wall-clock at op start, ms since epoch. */
420
+ at: number;
421
+ /** Wall-clock duration of the simulator.simulate(...) call, in ms. */
422
+ evalMs: number;
423
+ method: 'get' | 'list' | 'create' | 'update' | 'set' | 'delete';
424
+ path: string;
425
+ auth: AuthState;
426
+ /** `'unsupported'` fires when the simulator hit an unmodelled feature
427
+ * and the sandbox upgraded it (today: thrown as SimulatorUnsupportedError,
428
+ * surfaced here as a discrete result so the panel can show it distinctly
429
+ * from a real denial). */
430
+ result: 'allow' | 'deny' | 'unsupported';
431
+ /** Simulator debug messages — the per-rule trace (`Rule #0 (read) → ALLOW`).
432
+ * Same shape as `DenialEvent.reasons` so consumer code can share rendering. */
433
+ reasons: string[];
434
+ /** Proposed write payload, for create/update/set. Absent on reads + delete.
435
+ * Pre-resolution: `FieldValue.*` sentinels are preserved as their marker
436
+ * shapes (`{ __type: 'serverTimestamp' }`, etc.) so the replay engine
437
+ * can re-resolve them. The rule engine evaluated against the resolved
438
+ * form internally; that resolved form lives on
439
+ * {@link WriteSandboxEvent.nextState}, not here. */
440
+ request?: {
441
+ resourceData?: Record<string, unknown>;
442
+ };
443
+ /** Existing document state before the write (or read target for get). */
444
+ resourceBefore?: {
445
+ data: Record<string, unknown> | null;
446
+ exists: boolean;
447
+ };
448
+ /** Projected document state after the write. Absent on reads. */
449
+ resourceAfter?: {
450
+ data: Record<string, unknown> | null;
451
+ exists: boolean;
452
+ };
453
+ /** Parsed from the simulator's "Rule #N → …" debug line. Absent when no
454
+ * rule matched (e.g. no allow rules at the path — implicit deny). */
455
+ matchedRule?: {
456
+ ruleIndex: number;
457
+ operations: string[];
458
+ };
459
+ /** The DECIDING rule's verdict + 1-indexed source line + full sub-expression
460
+ * trace, projected from the simulator's structured `RuleEvaluation`
461
+ * (additive: present on `result: 'allow' | 'deny'` Firestore events when the
462
+ * simulator produced a per-rule trace — the allowing rule on an allow, the
463
+ * denying rule on a deny). Studio's rules inspector reads this to mark the
464
+ * deciding line and render the evaluation step-through ("show the work").
465
+ * Absent on an implicit deny (no rule evaluated), a simulator-error deny,
466
+ * and unsupported results. */
467
+ evaluatedRule?: import('../rules/test/spec.js').EvaluatedRuleInfo;
468
+ origin: 'user' | 'listener' | 'transaction' | 'batch';
469
+ /** Shared across ops in one batch or transaction. Opaque to consumers. */
470
+ groupId?: string;
471
+ /** Disambiguates `origin: 'transaction' | 'batch'` cases when consumers
472
+ * need to tell them apart without inspecting `origin` directly. */
473
+ groupKind?: 'batch' | 'transaction';
474
+ /** For listener re-evals: the originating user op that triggered this
475
+ * re-evaluation. Absent on the initial-snapshot fire. */
476
+ triggeredBy?: {
477
+ method: string;
478
+ path: string;
479
+ };
480
+ /** Free-form operation metadata. `admin: true` marks a rules-bypassing
481
+ * setup/admin operation so fixture tooling can exclude it from protected
482
+ * behavior while still preserving it as replay context. */
483
+ detail?: {
484
+ admin?: boolean;
485
+ } & Record<string, unknown>;
486
+ }
487
+ /**
488
+ * Committed write — a `create`/`update`/`set`/`delete` that the rule
489
+ * engine allowed AND that the keyspace successfully applied. Includes
490
+ * pre- and post-state so consumers can render diffs and (in a future
491
+ * `sandbox.history()` API) reconstruct state by replay.
492
+ *
493
+ * Fires AFTER the corresponding `kind: 'request'` event for the same
494
+ * op. A denied or rolled-back write surfaces as a request-deny only;
495
+ * `write` events only fire for committed writes.
496
+ *
497
+ * `sentinels` and `autoId` are placeholders for the eventual replay
498
+ * engine — v1 of the unified channel leaves them undefined. The shape
499
+ * is locked so consumers can build against it without churn when
500
+ * sentinel/auto-id capture lands.
501
+ */
502
+ export interface WriteSandboxEvent {
503
+ kind: 'write';
504
+ id: string;
505
+ at: number;
506
+ method: 'create' | 'update' | 'set' | 'delete';
507
+ path: string;
508
+ auth: AuthState;
509
+ /** Pre-resolution write payload — `FieldValue.*` sentinels preserved
510
+ * as marker shapes (`{ __type: 'serverTimestamp' }`, etc.) so the
511
+ * replay engine can re-resolve them. The rule engine evaluated
512
+ * against the resolved form internally; the resolved form lives on
513
+ * {@link nextState}. Absent on `delete`. */
514
+ data?: Record<string, unknown>;
515
+ /** State BEFORE this write. `null` for a non-existent doc. */
516
+ priorState: Record<string, unknown> | null;
517
+ /** State AFTER this write. `null` on `delete`. */
518
+ nextState: Record<string, unknown> | null;
519
+ groupId?: string;
520
+ groupKind?: 'batch' | 'transaction';
521
+ /** FieldValue sentinels (serverTimestamp / increment / arrayUnion /
522
+ * arrayRemove / deleteField → 'delete') extracted from the
523
+ * pre-resolution write payload. The replay engine consumes this
524
+ * to re-issue the same sentinels at replay time without consulting
525
+ * resolved values that would have drifted. Path syntax: dotted
526
+ * with bracket-indices ('a.b[0].c'). Absent when the write
527
+ * contained no sentinels. */
528
+ sentinels?: Array<{
529
+ field: string;
530
+ kind: 'serverTimestamp' | 'increment' | 'arrayUnion' | 'arrayRemove' | 'delete';
531
+ }>;
532
+ /** Minted document ID when this write came from `collection.add()` /
533
+ * `LocalEnvironment.createWithAutoId`. The replay engine aliases
534
+ * the path's last segment to a fresh mint on replay (rather than
535
+ * preserving the original auto-ID). */
536
+ autoId?: string;
537
+ /** Server time at which the rule engine evaluated this write —
538
+ * pinned per op (or shared across sub-ops in a batch / transaction).
539
+ * The replay engine re-issues this exact value when re-resolving
540
+ * `serverTimestamp()` sentinels so resolved fields are bit-identical
541
+ * on replay. Shape mirrors the Firestore Web SDK Timestamp
542
+ * (`{ seconds, nanoseconds }`). */
543
+ requestTime: {
544
+ seconds: number;
545
+ nanoseconds: number;
546
+ };
547
+ /** Free-form write metadata. `admin: true` marks a rules-bypassing
548
+ * setup/admin commit so replay can apply it as context without asking
549
+ * candidate rules to permit it. */
550
+ detail?: {
551
+ admin?: boolean;
552
+ } & Record<string, unknown>;
553
+ }
554
+ /**
555
+ * Snapshot delivered to a `onSnapshot` listener's user callback.
556
+ *
557
+ * Fires AFTER the no-op suppression check — every `snapshot_delivery`
558
+ * event corresponds to an actual user-callback invocation. Listener
559
+ * re-evals that resolved to no-ops emit {@link SnapshotSuppressedEvent}
560
+ * instead.
561
+ *
562
+ * `sample` carries best-effort serializable views of the docs the
563
+ * callback received; consumers truncate before persisting if the
564
+ * scenario produces large snapshots.
565
+ */
566
+ export interface SnapshotDeliveryEvent {
567
+ kind: 'snapshot_delivery';
568
+ id: string;
569
+ at: number;
570
+ /** Opaque listener id assigned at attach time. */
571
+ listenerId: string;
572
+ target: {
573
+ kind: 'doc';
574
+ path: string;
575
+ } | {
576
+ kind: 'query';
577
+ collection: string;
578
+ };
579
+ auth: AuthState;
580
+ addedCount: number;
581
+ modifiedCount: number;
582
+ removedCount: number;
583
+ /** `1` for doc-kind (exists) / `0` (deleted), `n` for query-kind. */
584
+ size: number;
585
+ /** Doc payloads, in the order the user callback saw them. */
586
+ sample?: {
587
+ docs: Array<{
588
+ path: string;
589
+ data: Record<string, unknown> | null;
590
+ }>;
591
+ };
592
+ /** The user op that triggered this re-eval. Absent on initial fire
593
+ * and on `deployRules`-driven re-evals. */
594
+ triggeredBy?: {
595
+ method: string;
596
+ path: string;
597
+ };
598
+ }
599
+ /**
600
+ * Listener re-eval that was suppressed before delivery — the re-eval
601
+ * ran but produced no observable change vs the prior snapshot, so the
602
+ * user callback wasn't invoked.
603
+ *
604
+ * Useful for "why didn't my listener fire" debugging. Default UIs
605
+ * should filter these out; only the inspector-style consumer needs
606
+ * them.
607
+ */
608
+ export interface SnapshotSuppressedEvent {
609
+ kind: 'snapshot_suppressed';
610
+ id: string;
611
+ at: number;
612
+ listenerId: string;
613
+ target: {
614
+ kind: 'doc';
615
+ path: string;
616
+ } | {
617
+ kind: 'query';
618
+ collection: string;
619
+ };
620
+ auth: AuthState;
621
+ /** Why this re-eval was suppressed. v1 only emits `'no-op'`. */
622
+ reason: 'no-op';
623
+ triggeredBy?: {
624
+ method: string;
625
+ path: string;
626
+ };
627
+ }
628
+ /**
629
+ * Listener lifecycle event — attach, detach, or errored. Errored
630
+ * supersedes the prior `onSnapshotError` channel; `error` is populated
631
+ * on the errored phase only.
632
+ */
633
+ export interface ListenerLifecycleEvent {
634
+ kind: 'listener_attach' | 'listener_detach' | 'listener_errored';
635
+ id: string;
636
+ at: number;
637
+ listenerId: string;
638
+ target: {
639
+ kind: 'doc';
640
+ path: string;
641
+ } | {
642
+ kind: 'query';
643
+ collection: string;
644
+ };
645
+ auth: AuthState;
646
+ /** Populated on `listener_errored` only. */
647
+ error?: {
648
+ code: 'permission-denied';
649
+ message: string;
650
+ reasons?: string[];
651
+ };
652
+ }
653
+ /**
654
+ * Session boundary — emitted before `sandbox.reset()` swaps the env,
655
+ * and before `sandbox.dispose()` tears it down. Lets consumers segment
656
+ * a persisted event stream into "session N pre-reset" / "session N+1
657
+ * post-reset" runs.
658
+ */
659
+ export interface SessionBoundaryEvent {
660
+ kind: 'session_boundary';
661
+ id: string;
662
+ at: number;
663
+ phase: 'reset' | 'dispose';
664
+ /** Total events emitted on this sandbox before the boundary. */
665
+ priorOpCount: number;
666
+ }
667
+ /**
668
+ * Cross-service mutation event — the unified envelope the NON-Firestore
669
+ * services (`auth` / `storage` / `rtdb`) emit into the single
670
+ * `onEvent`/`history()` stream (Pyric Studio keystone, track T1).
671
+ *
672
+ * **Why a new variant rather than reusing `request`/`write`.** Firestore's
673
+ * existing kinds are tightly coupled to the rules-simulator: `RequestEvent`
674
+ * carries `result: 'allow'|'deny'`, `evalMs`, the simulator's `reasons[]`,
675
+ * and `matchedRule`; `WriteSandboxEvent` carries Firestore-specific
676
+ * `sentinels`, `autoId`, and a Firestore `requestTime` Timestamp. Auth user-
677
+ * DB mutations (no path, no rule eval), Storage object puts, and RTDB tree
678
+ * writes don't have those concepts, and bending them into the Firestore
679
+ * shapes would either lie (synthesize a fake `result`/`requestTime`) or
680
+ * pollute the Firestore consumer contract. So this is ONE small, additive
681
+ * variant the three services share — Firestore consumers filter on their
682
+ * existing `kind`s and never see it. See the design rationale.
683
+ *
684
+ * It is intentionally generic: `op` is a free-ish string discriminated by
685
+ * `service`, and `before`/`after` are best-effort serializable snapshots
686
+ * (omitted when not meaningful — e.g. a sign-out has no `after`). Studio's
687
+ * data grids / Action Center render `service` + `op` + `path` directly and
688
+ * diff `before`→`after` when both are present.
689
+ */
690
+ export interface ServiceMutationEvent {
691
+ kind: 'service_mutation';
692
+ id: string;
693
+ at: number;
694
+ /**
695
+ * Which service performed the mutation. Always one of the non-Firestore
696
+ * services — Firestore rides its own `request`/`write` path. (The
697
+ * provenance `service` field on the stamped event mirrors this; it is set
698
+ * redundantly here so a consumer matching purely on `kind` still gets the
699
+ * discriminator without reaching into provenance.)
700
+ */
701
+ service: 'auth' | 'storage' | 'rtdb';
702
+ /**
703
+ * Service-scoped operation name. Stable, lowercase, snake/kebab-free:
704
+ * - auth: `user_create` | `user_update` | `user_delete` |
705
+ * `users_clear` | `sign_in` | `sign_out`
706
+ * - storage: `object_put` | `object_delete` | `metadata_update`
707
+ * - rtdb: `set` | `update` | `remove` | `transaction`
708
+ * New ops can be added without a breaking change (consumers switch with a
709
+ * default branch).
710
+ */
711
+ op: string;
712
+ /**
713
+ * The thing mutated, in the service's own addressing scheme:
714
+ * - auth: the user `uid` (or `'*'` for a clear-all). Absent for a
715
+ * sign-out with no prior user.
716
+ * - storage: the object `fullPath` (e.g. `avatars/alice.png`).
717
+ * - rtdb: the database path (e.g. `/rooms/r1/messages`), or for a
718
+ * multi-path `update` the ref path the call targeted.
719
+ */
720
+ path?: string;
721
+ /** Identity in effect when the op ran (the service's `request.auth`
722
+ * equivalent). `null` for admin/anonymous-driven mutations (e.g.
723
+ * `sandbox.createUser`, an unauthenticated RTDB write). */
724
+ auth: AuthState;
725
+ /** Best-effort serializable snapshot of the state BEFORE the mutation.
726
+ * Absent when there was no prior state (a create) or it isn't cheap to
727
+ * capture. */
728
+ before?: unknown;
729
+ /** Best-effort serializable snapshot of the state AFTER the mutation.
730
+ * Absent on deletes / sign-outs (nothing remains). */
731
+ after?: unknown;
732
+ /** Free-form, service-specific extras a consumer may surface without
733
+ * re-deriving (e.g. storage `{ size, contentType }`, rtdb
734
+ * `{ committed }` for a transaction). Kept loose on purpose — it's a
735
+ * display hint, not a contract. */
736
+ detail?: Record<string, unknown>;
737
+ }
738
+ /**
739
+ * Canonical service operation event. This is the service-neutral successor to
740
+ * Firestore's `request` traffic shape: every user-visible operation can be
741
+ * represented here, whether it is backed by security rules (Firestore/RTDB/
742
+ * Storage) or by a service control plane (Auth).
743
+ *
744
+ * Existing Firestore `request` events remain for compatibility. New cross-
745
+ * service consumers should prefer `operation` because it carries an explicit
746
+ * `service` discriminator and does not require RTDB/Storage/Auth to pretend
747
+ * their state is a Firestore document.
748
+ */
749
+ export interface SandboxOperationEvent {
750
+ kind: 'operation';
751
+ id: string;
752
+ at: number;
753
+ service: EventService;
754
+ method: string;
755
+ path?: string;
756
+ auth: AuthState;
757
+ result: 'allow' | 'deny' | 'unsupported' | 'error' | 'not-applicable';
758
+ origin: 'user' | 'listener' | 'transaction' | 'batch' | 'admin' | 'system';
759
+ durationMs?: number;
760
+ reasons?: string[];
761
+ rules?: {
762
+ engine: 'firestore' | 'rtdb' | 'storage';
763
+ matchedPath?: string;
764
+ matchedRule?: string;
765
+ ruleIndex?: number;
766
+ operations?: string[];
767
+ pathVariableBindings?: Record<string, string>;
768
+ reason?: string;
769
+ errorCode?: string;
770
+ };
771
+ request?: {
772
+ data?: unknown;
773
+ resourceData?: unknown;
774
+ query?: unknown;
775
+ };
776
+ resourceBefore?: {
777
+ data: unknown;
778
+ exists: boolean;
779
+ };
780
+ resourceAfter?: {
781
+ data: unknown;
782
+ exists: boolean;
783
+ };
784
+ groupId?: string;
785
+ groupKind?: 'batch' | 'transaction';
786
+ triggeredBy?: {
787
+ method: string;
788
+ path?: string;
789
+ };
790
+ detail?: Record<string, unknown>;
791
+ }
792
+ /**
793
+ * Canonical committed mutation event. Unlike `operation`, this fires only when
794
+ * state actually changed. Replay and branch tooling should eventually consume
795
+ * these service adapters instead of filtering Firestore-only `write` events.
796
+ */
797
+ export interface SandboxCommitEvent {
798
+ kind: 'commit';
799
+ id: string;
800
+ at: number;
801
+ service: EventService;
802
+ method: string;
803
+ path?: string;
804
+ auth: AuthState;
805
+ data?: unknown;
806
+ priorState?: unknown;
807
+ nextState?: unknown;
808
+ groupId?: string;
809
+ groupKind?: 'batch' | 'transaction';
810
+ replay?: {
811
+ requestTime?: number;
812
+ autoId?: string;
813
+ sentinels?: Array<{
814
+ field: string;
815
+ kind: string;
816
+ }>;
817
+ };
818
+ detail?: Record<string, unknown>;
819
+ }
820
+ /**
821
+ * Canonical listener lifecycle/delivery event. Firestore's existing snapshot
822
+ * delivery/lifecycle variants are preserved; this shape gives RTDB and future
823
+ * service listeners the same debuggable surface.
824
+ */
825
+ export interface SandboxListenerEvent {
826
+ kind: 'listener';
827
+ id: string;
828
+ at: number;
829
+ service: EventService;
830
+ phase: 'attach' | 'detach' | 'delivery' | 'suppressed' | 'errored';
831
+ listenerId: string;
832
+ target: {
833
+ kind: string;
834
+ path?: string;
835
+ query?: unknown;
836
+ };
837
+ auth: AuthState;
838
+ result?: 'allow' | 'deny' | 'unsupported' | 'error';
839
+ size?: number;
840
+ sample?: unknown;
841
+ reason?: string;
842
+ error?: {
843
+ code?: string;
844
+ message: string;
845
+ reasons?: string[];
846
+ };
847
+ triggeredBy?: {
848
+ method: string;
849
+ path?: string;
850
+ };
851
+ detail?: Record<string, unknown>;
852
+ }
853
+ /** Canonical non-rules operational failure. */
854
+ export interface SandboxRuntimeErrorEvent {
855
+ kind: 'runtime_error';
856
+ id: string;
857
+ at: number;
858
+ service: EventService;
859
+ method: string;
860
+ path?: string;
861
+ auth: AuthState;
862
+ error: {
863
+ code?: string;
864
+ message: string;
865
+ };
866
+ detail?: Record<string, unknown>;
867
+ }
868
+ /**
869
+ * Discriminated union of every event the sandbox emits to
870
+ * {@link Sandbox.onEvent} subscribers.
871
+ *
872
+ * Issue #307 — replaces the prior three-channel surface
873
+ * (`onRequest` / `onDenial` / `onSnapshotError`). Filter on `kind`
874
+ * to recover the subset each old channel covered:
875
+ * - request: `kind === 'request'`
876
+ * - denial: `kind === 'request' && result === 'deny'`
877
+ * - snapshotError: `kind === 'listener_errored'`
878
+ *
879
+ * See the design rationale for the
880
+ * field-by-field rationale.
881
+ */
882
+ /**
883
+ * Which sandbox service emitted an event. Today only Firestore emits (events
884
+ * omit `service`, read as `'firestore'`); Pyric Studio's keystone track makes
885
+ * Auth/Storage/RTDB emit into this same stream. See the design rationale.
886
+ */
887
+ export type EventService = 'firestore' | 'auth' | 'storage' | 'rtdb';
888
+ /** Who initiated the operation behind an event (Studio attributes activity to
889
+ * the human, the app, or a specific agent). Absent ⇒ the served app. */
890
+ export type EventActor = {
891
+ kind: 'app';
892
+ } | {
893
+ kind: 'studio';
894
+ } | {
895
+ kind: 'agent';
896
+ name: string;
897
+ } | {
898
+ kind: 'app-builder';
899
+ };
900
+ /**
901
+ * The auth lens an operation ran under: `admin` bypasses rules, `as` evaluates
902
+ * rules as a specific uid (impersonation — the rules-debugging primitive),
903
+ * `app-session` is the app's own signed-in user, and `anon` is a genuinely
904
+ * UNAUTHENTICATED context (`withAuth(null)` — `request.auth == null` in rules).
905
+ * Mirrors the worker's per-op `actAs`. Absent ⇒ `app-session`.
906
+ *
907
+ * `anon` vs absent matters for RELAYED ops (the remote sandbox): an op with no
908
+ * lens resolves to the browser tab's port session — whoever happens to be
909
+ * signed in in the tab. Remote code that means "no auth" must pin
910
+ * `{ mode: 'anon' }` explicitly, or it silently runs as the tab's user.
911
+ */
912
+ export type AuthLens = {
913
+ mode: 'admin';
914
+ } | {
915
+ mode: 'as';
916
+ uid: string;
917
+ token?: Record<string, unknown>;
918
+ } | {
919
+ mode: 'app-session';
920
+ } | {
921
+ mode: 'anon';
922
+ };
923
+ /**
924
+ * Provenance carried by every {@link SandboxEvent}. All fields are OPTIONAL and
925
+ * additive: pre-provenance emitters omit them (treated as
926
+ * firestore / app / app-session), so nothing breaks. The Pyric Studio event
927
+ * unification track stamps them at emit across all services, which is what
928
+ * turns the log into "who did what" (Action Center, audit, agent attribution).
929
+ */
930
+ export interface EventProvenance {
931
+ service?: EventService;
932
+ actor?: EventActor;
933
+ authLens?: AuthLens;
934
+ /** Set when the op is part of an agent plan (Pyric Agent dry-run / accept). */
935
+ planId?: string;
936
+ }
937
+ export type SandboxEvent = (RequestEvent | WriteSandboxEvent | SnapshotDeliveryEvent | SnapshotSuppressedEvent | ListenerLifecycleEvent | SessionBoundaryEvent | ServiceMutationEvent | SandboxOperationEvent | SandboxCommitEvent | SandboxListenerEvent | SandboxRuntimeErrorEvent) & EventProvenance;
938
+ /**
939
+ * The data + rules + lifecycle foundation. **Identity-agnostic** —
940
+ * operations through services attached to a `Sandbox` always go via a
941
+ * {@link SandboxContext} that names the auth identity for that
942
+ * operation. Multiple contexts can share one sandbox.
943
+ *
944
+ * Mental model: sandboxes hold the data, contexts carry identity,
945
+ * services attach via factories. See
946
+ * the design rationale for the design rationale.
947
+ */
948
+ export interface Sandbox {
949
+ /**
950
+ * Derive a context bound to this sandbox under the given auth
951
+ * identity. Operations through services attached to the returned
952
+ * context evaluate rules under that identity. Many contexts can
953
+ * coexist for one sandbox; data is shared.
954
+ *
955
+ * `null` is anonymous; an `AuthState` object names the user (and
956
+ * optional custom claims). Passing `undefined` is a deliberate
957
+ * error — say `withAuth(null)` for anonymous so the call site is
958
+ * unambiguous.
959
+ *
960
+ * @example
961
+ * ```ts
962
+ * const sandbox = initializeSandbox();
963
+ * const dbAlice = getFirestore(sandbox.withAuth({ uid: 'alice' }));
964
+ * const dbAnon = getFirestore(sandbox.withAuth(null));
965
+ * ```
966
+ */
967
+ withAuth(auth: AuthState): SandboxContext;
968
+ /**
969
+ * Subscribe to every event the sandbox emits — see {@link SandboxEvent}
970
+ * for the discriminated-union shape. One subscription covers
971
+ * request/denial/snapshot-error/listener-lifecycle/session-boundary;
972
+ * filter on `event.kind` to recover individual streams.
973
+ *
974
+ * Replaces the prior three-channel surface (`onRequest` / `onDenial`
975
+ * / `onSnapshotError`) — see issue #307. Filter cookbook:
976
+ * - All denials: `event.kind === 'request' && event.result === 'deny'`
977
+ * - Stream errors: `event.kind === 'listener_errored'`
978
+ * - Per-op traffic: `event.kind === 'request'`
979
+ *
980
+ * Survives `sandbox.reset()` — the subscription is held on the
981
+ * sandbox, not on the underlying environment. A `session_boundary`
982
+ * event with `phase: 'reset'` fires before the env swap so consumers
983
+ * can segment their stream.
984
+ *
985
+ * Returns an unsubscribe function. Listener errors are swallowed so a
986
+ * faulty subscriber can't change rule semantics or hide other events.
987
+ * Both synchronous throws and rejected Promises from async callbacks
988
+ * are silently discarded — subscribers are **observational**, the
989
+ * sandbox doesn't await them and doesn't propagate their errors.
990
+ */
991
+ onEvent(cb: (event: SandboxEvent) => void): () => void;
992
+ /**
993
+ * Run `fn` with ambient {@link EventProvenance} defaults: every event
994
+ * emitted SYNCHRONOUSLY during `fn` that doesn't already carry a
995
+ * provenance field (on the event itself or via an explicit per-emit
996
+ * override) is stamped with these values instead of the global
997
+ * defaults. This is the mechanical "who issued this op" seam the
998
+ * serve worker uses to tag Studio-issued ops (`actor: { kind:
999
+ * 'studio' }`) and to stamp the auth lens an op ran under
1000
+ * (`authLens`) — declared by the caller that issues the op, never
1001
+ * inferred from the op's shape.
1002
+ *
1003
+ * SYNCHRONOUS WINDOW: the ambient values apply only until `fn`
1004
+ * returns (for an async `fn`, its synchronous prefix — which covers
1005
+ * the local environment's rules eval + event emission, since those
1006
+ * run before the op's promise is handed back). Work an op DEFERS
1007
+ * (snapshot-listener deliveries and re-evals drain on a microtask,
1008
+ * off-stack) is intentionally OUTSIDE the window: a listener re-eval
1009
+ * belongs to the listener's owner, not to whoever's write triggered
1010
+ * it. Nested calls stack — the innermost window wins per field, and
1011
+ * each window restores the previous one on exit (including on throw).
1012
+ *
1013
+ * OPTIONAL because remote sandbox proxies can't provide an ambient
1014
+ * emit window (events are emitted in the worker they front). Callers
1015
+ * spell `sandbox.runWithProvenance?.(prov, fn) ?? fn()`.
1016
+ */
1017
+ runWithProvenance?<T>(provenance: EventProvenance, fn: () => T): T;
1018
+ /**
1019
+ * Every {@link SandboxEvent} this sandbox has emitted since init or
1020
+ * the last `reset()`. Returns a defensive copy.
1021
+ *
1022
+ * Use this for replay: hand the array to `replay(events, rules)`
1023
+ * from `pyric/sandbox` and the engine re-issues every
1024
+ * captured write against a fresh sandbox.
1025
+ *
1026
+ * Unlike {@link onEvent} (live stream from the moment of subscribe),
1027
+ * `history()` returns *every* event the sandbox has seen — useful
1028
+ * for consumers that attach late (e.g., loading a saved session
1029
+ * before subscribing) or that need a snapshot at a particular moment.
1030
+ *
1031
+ * `reset()` and `dispose()` each append a closing `session_boundary`
1032
+ * event; `reset()` then clears the history. Consumers that took a
1033
+ * snapshot *before* reset retain the boundary in their copy.
1034
+ */
1035
+ history(): SandboxEvent[];
1036
+ /**
1037
+ * Admin-plane access (rule-bypass reads). Identity-agnostic by
1038
+ * design — admin reads aren't gated on auth, so they live on the
1039
+ * sandbox, not on a context. See {@link SandboxAdmin}.
1040
+ */
1041
+ readonly admin: SandboxAdmin;
1042
+ /**
1043
+ * Reset the underlying environment to a fresh state — wipes data,
1044
+ * rules, and any service-specific configuration.
1045
+ *
1046
+ * Snapshot listeners attached to the OLD environment are dropped at
1047
+ * the swap — they can't survive because their target docs have been
1048
+ * wiped. `onEvent` subscribers DO survive — the registry lives on
1049
+ * the sandbox, and a `session_boundary` event with `phase: 'reset'`
1050
+ * fires before the swap so subscribers know the rollover happened.
1051
+ * Existing {@link SandboxContext}s continue to work — their sandbox
1052
+ * reference is stable; subsequent operations resolve to the new env.
1053
+ */
1054
+ reset(): void;
1055
+ /**
1056
+ * Tear down listener registries on this sandbox's environment without
1057
+ * replacing it. Use this when you're about to discard the sandbox
1058
+ * itself (e.g. `runner.reseed()` builds a fresh sandbox rather than
1059
+ * calling `reset()`) and want to drop callback references on the
1060
+ * outgoing instance defensively. Idempotent. Does not touch data.
1061
+ */
1062
+ dispose(): void;
1063
+ /**
1064
+ * Capture a snapshot of every service's state. For v1 with only
1065
+ * Firestore, the return value carries a `firestore` key mapping doc
1066
+ * paths to data. Future services will add their own keys.
1067
+ */
1068
+ snapshot(): SandboxSnapshot;
1069
+ /**
1070
+ * CLOBBER-restore the sandbox's entire state from a prior {@link snapshot}:
1071
+ * `reset()` (clears firestore + the signed-in session), then rebuild firestore
1072
+ * from `data` and restore each registered service. This is a TOTAL replace —
1073
+ * documents absent from `data` do NOT survive — and is the counterpart to
1074
+ * {@link snapshot}. It is what makes "transfer (clobber) one instance's data
1075
+ * into another" and named-branch switching possible.
1076
+ *
1077
+ * Fires a `session_boundary` (reset phase), re-evaluates live listeners against
1078
+ * the loaded state, and the next persistence flush writes the loaded state.
1079
+ * Services present in `data` but not currently registered are skipped (a
1080
+ * snapshot taken via {@link snapshot} always includes every registered
1081
+ * service, so this only affects cross-instance imports from a sandbox that had
1082
+ * a service this one lacks).
1083
+ */
1084
+ loadSnapshot(data: SandboxSnapshot): void;
1085
+ /**
1086
+ * Current authenticated user across the sandbox.
1087
+ *
1088
+ * Mutated by `pyric/auth`'s `signInAnonymously` /
1089
+ * `signInWithEmailAndPassword` / `signOut` / `sandbox.setUser`. Read
1090
+ * per-call by service factories (e.g. a future
1091
+ * `getFirestore(sandbox)` overload) so they see auth state changes
1092
+ * without re-binding handles. Defaults to `null` (anonymous /
1093
+ * signed out).
1094
+ *
1095
+ * **Independent of `withAuth({uid})`** — `withAuth` still produces a
1096
+ * frozen {@link SandboxContext} that carries its own identity for
1097
+ * the runner's test code (the existing pattern: explicit identity
1098
+ * per service call). `currentUser` exists for the `pyric/auth`
1099
+ * mirror, where consumer app code drives identity through a
1100
+ * stateful `Auth` handle rather than naming it per call.
1101
+ */
1102
+ currentUser: AuthState;
1103
+ /**
1104
+ * Subscribe to `currentUser` changes. Fires on every mutation —
1105
+ * sign-in, sign-out, user swap. Does NOT fire on subscribe.
1106
+ *
1107
+ * Survives `reset()` and `dispose()` only as a no-op: a disposed
1108
+ * sandbox emits nothing further; a reset sandbox clears
1109
+ * `currentUser` to `null` (and fires the change) before swapping
1110
+ * the env.
1111
+ *
1112
+ * Returns an unsubscribe function. Listener errors are swallowed —
1113
+ * subscribers are observational, the sandbox does not propagate
1114
+ * their errors.
1115
+ */
1116
+ onCurrentUserChanged(cb: (user: AuthState) => void): () => void;
1117
+ /**
1118
+ * Enable cross-tab realtime sync via `BroadcastChannel`. A write in
1119
+ * this tab will propagate to every OTHER tab of the same origin that
1120
+ * also called `enableTabSync`, causing their `onSnapshot` listeners to
1121
+ * re-evaluate — restoring production's cross-client realtime behavior.
1122
+ *
1123
+ * **Opt-in, OFF by default.** Firestore only (RTDB is a follow-on).
1124
+ *
1125
+ * Returns a disable function. Calling it removes the `onEvent`
1126
+ * subscription, the channel message listener, and closes the channel
1127
+ * (when it was created internally). After disable, no further propagation
1128
+ * occurs in either direction.
1129
+ *
1130
+ * **Multi-writer note:** concurrent writes from two tabs to the same doc
1131
+ * produce last-write-wins divergence — there is no conflict resolution.
1132
+ * The intended model is one active writer (one user, one tab) with
1133
+ * observers in other tabs; this covers the overwhelming majority of
1134
+ * local development scenarios.
1135
+ *
1136
+ * @see {@link TabSyncOptions} for channel injection (tests) and originId.
1137
+ *
1138
+ * @example
1139
+ * ```ts
1140
+ * // In every tab that should participate in realtime:
1141
+ * const sandbox = initializeSandbox();
1142
+ * const disableSync = sandbox.enableTabSync();
1143
+ * // Later, to stop syncing:
1144
+ * disableSync();
1145
+ * ```
1146
+ */
1147
+ enableTabSync(options?: TabSyncOptions): () => void;
1148
+ /**
1149
+ * Persist the sandbox's data to a backend and restore it on next
1150
+ * `enablePersistence` call. The default `'indexedDB'` backend turns
1151
+ * the sandbox into the host page's local Firestore — writes flush
1152
+ * automatically and a fresh `initializeSandbox()` rehydrates from
1153
+ * the prior session.
1154
+ *
1155
+ * Restoration happens before the promise resolves; awaiting this
1156
+ * call is sufficient to guarantee in-memory state matches the
1157
+ * persisted blob.
1158
+ *
1159
+ * Idempotent across the same `key` — calling twice in one process
1160
+ * is a no-op on the second call. Different keys are rejected as an
1161
+ * error (a sandbox can persist to at most one backend at a time).
1162
+ *
1163
+ * Listener semantics: every write event the sandbox emits triggers
1164
+ * a debounced flush (default 250ms). Browser hosts additionally
1165
+ * flush on `beforeunload` so a page navigation doesn't lose the
1166
+ * tail of the debounce window.
1167
+ *
1168
+ * See {@link SandboxPersistenceOptions} for backend selection and
1169
+ * tuning.
1170
+ */
1171
+ enablePersistence(options: SandboxPersistenceOptions): Promise<void>;
1172
+ /**
1173
+ * Force a snapshot to the configured persistence backend right now.
1174
+ * Useful before a manual navigation, or in tests that need
1175
+ * deterministic ordering against the debounce window. Resolves once
1176
+ * the write hits the backend.
1177
+ *
1178
+ * Throws if persistence is not enabled.
1179
+ */
1180
+ flush(): Promise<void>;
1181
+ /**
1182
+ * Wipe the persisted blob for this sandbox's `key`. In-memory state
1183
+ * is left intact — call `reset()` if you want both. Useful for
1184
+ * "sign out and forget" flows.
1185
+ *
1186
+ * No-op when persistence is not enabled.
1187
+ */
1188
+ clearPersistence(): Promise<void>;
1189
+ /**
1190
+ * Register a service (auth, storage, …) as a persistence participant.
1191
+ * The sandbox calls `hooks.snapshot()` on every flush and
1192
+ * `hooks.restore(data)` on restore. If `hooks.subscribe` is provided,
1193
+ * the persistence controller subscribes and schedules a debounced
1194
+ * flush on each change — so auth-user edits flush promptly, not only
1195
+ * on the next Firestore write.
1196
+ *
1197
+ * Returns an unregister function — call it if the service is torn
1198
+ * down before the sandbox is disposed (uncommon in practice; the
1199
+ * sandbox's `dispose()` clears the registry anyway).
1200
+ *
1201
+ * Throws `failed-precondition` when a service with the same `name` is
1202
+ * already registered — the auth package registers `'auth'` once when
1203
+ * `getAuth(sandbox)` first creates a backend, so accidental double-
1204
+ * registration is a caller bug, not a no-op.
1205
+ *
1206
+ * **Advanced / internal API.** Service packages (auth, storage) call
1207
+ * this when they first attach to a sandbox. Consumer app code should
1208
+ * not need to call this directly.
1209
+ */
1210
+ registerPersistableService(name: string, hooks: PersistableService): () => void;
1211
+ }
1212
+ /**
1213
+ * Identity-bearing handle on a {@link Sandbox}. A `(sandbox, auth)`
1214
+ * pair — cheap to create, immutable, freely shareable. Service
1215
+ * factories require a `SandboxContext`; bare `Sandbox` is a type
1216
+ * error so every call site states identity explicitly.
1217
+ *
1218
+ * Constructed via `Sandbox.withAuth(auth)` or chained via
1219
+ * `SandboxContext.withAuth(auth)`. The concrete class is exported
1220
+ * from `pyric/sandbox` for `instanceof` routing in service
1221
+ * factories; consumers don't construct it directly.
1222
+ */
1223
+ export interface SandboxContext {
1224
+ /** The data foundation this context operates against. */
1225
+ readonly sandbox: Sandbox;
1226
+ /** The identity rules evaluate under for operations through this context. */
1227
+ readonly auth: AuthState;
1228
+ /**
1229
+ * Derive a sibling context on the same sandbox with different auth.
1230
+ * Replaces, doesn't merge — the new context carries only the new
1231
+ * auth, regardless of any prior context's auth.
1232
+ */
1233
+ withAuth(auth: AuthState): SandboxContext;
1234
+ }
1235
+ //# sourceMappingURL=types.d.ts.map