@tier0/sdk-v2 0.9.9 → 0.10.0

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 (250) hide show
  1. package/CHANGELOG.md +102 -0
  2. package/LICENSE +21 -21
  3. package/README.md +165 -27
  4. package/dist/cjs/client.d.ts +79 -3
  5. package/dist/cjs/client.js +4 -6
  6. package/dist/cjs/client.js.map +1 -1
  7. package/dist/cjs/cloud-server.d.ts +33 -26
  8. package/dist/cjs/cloud-server.js +102 -100
  9. package/dist/cjs/cloud-server.js.map +1 -1
  10. package/dist/cjs/cloud-transport.d.ts +15 -20
  11. package/dist/cjs/cloud-transport.js +87 -68
  12. package/dist/cjs/cloud-transport.js.map +1 -1
  13. package/dist/cjs/connection-diagnostics.d.ts +2 -0
  14. package/dist/cjs/connection-diagnostics.js +20 -0
  15. package/dist/cjs/connection-diagnostics.js.map +1 -0
  16. package/dist/cjs/data/bootstrap.js +3 -4
  17. package/dist/cjs/data/bootstrap.js.map +1 -1
  18. package/dist/cjs/data/call.d.ts +1 -3
  19. package/dist/cjs/data/call.js +8 -12
  20. package/dist/cjs/data/call.js.map +1 -1
  21. package/dist/cjs/data/client.d.ts +8 -7
  22. package/dist/cjs/data/client.js +24 -11
  23. package/dist/cjs/data/client.js.map +1 -1
  24. package/dist/cjs/data/collection.d.ts +3 -5
  25. package/dist/cjs/data/collection.js +3 -4
  26. package/dist/cjs/data/collection.js.map +1 -1
  27. package/dist/cjs/data/context.d.ts +5 -11
  28. package/dist/cjs/data/context.js +21 -36
  29. package/dist/cjs/data/context.js.map +1 -1
  30. package/dist/cjs/data/error.d.ts +1 -1
  31. package/dist/cjs/data/error.js +3 -3
  32. package/dist/cjs/data/error.js.map +1 -1
  33. package/dist/cjs/data/index.d.ts +5 -3
  34. package/dist/cjs/data/index.js +5 -5
  35. package/dist/cjs/data/index.js.map +1 -1
  36. package/dist/cjs/data/relay.d.ts +51 -0
  37. package/dist/cjs/data/relay.js +371 -0
  38. package/dist/cjs/data/relay.js.map +1 -0
  39. package/dist/cjs/data/subscribe.d.ts +22 -38
  40. package/dist/cjs/data/subscribe.js +22 -28
  41. package/dist/cjs/data/subscribe.js.map +1 -1
  42. package/dist/cjs/event-stream.d.ts +28 -0
  43. package/dist/cjs/event-stream.js +222 -0
  44. package/dist/cjs/event-stream.js.map +1 -0
  45. package/dist/cjs/mq/client.d.ts +32 -1
  46. package/dist/cjs/mq/client.js +404 -69
  47. package/dist/cjs/mq/client.js.map +1 -1
  48. package/dist/cjs/mq/index.d.ts +1 -0
  49. package/dist/cjs/mq/index.js +3 -1
  50. package/dist/cjs/mq/index.js.map +1 -1
  51. package/dist/cjs/mq/topic.d.ts +29 -0
  52. package/dist/cjs/mq/topic.js +48 -0
  53. package/dist/cjs/mq/topic.js.map +1 -0
  54. package/dist/cjs/mq/types.d.ts +21 -1
  55. package/dist/cjs/mq/types.js.map +1 -1
  56. package/dist/cjs/openapi/api.generated.d.ts +20 -0
  57. package/dist/cjs/openapi/api.generated.js +11 -0
  58. package/dist/cjs/openapi/api.generated.js.map +1 -1
  59. package/dist/cjs/openapi/client.d.ts +46 -0
  60. package/dist/cjs/openapi/client.js +161 -12
  61. package/dist/cjs/openapi/client.js.map +1 -1
  62. package/dist/cjs/openapi/codecs.generated.d.ts +74 -0
  63. package/dist/cjs/openapi/codecs.generated.js +1 -1
  64. package/dist/cjs/openapi/codecs.generated.js.map +1 -1
  65. package/dist/cjs/openapi/types.generated.d.ts +205 -1
  66. package/dist/cjs/openapi/types.generated.js.map +1 -1
  67. package/dist/cjs/page-runtime.d.ts +48 -0
  68. package/dist/cjs/page-runtime.js +74 -0
  69. package/dist/cjs/page-runtime.js.map +1 -0
  70. package/dist/cjs/platform-proxy.d.ts +17 -0
  71. package/dist/cjs/platform-proxy.js +52 -0
  72. package/dist/cjs/platform-proxy.js.map +1 -0
  73. package/dist/cjs/runtime-context.d.ts +2 -1
  74. package/dist/cjs/runtime-context.js +6 -2
  75. package/dist/cjs/runtime-context.js.map +1 -1
  76. package/dist/cjs/runtime-env.js.map +1 -1
  77. package/dist/cjs/source.d.ts +19 -1
  78. package/dist/cjs/source.js +9 -3
  79. package/dist/cjs/source.js.map +1 -1
  80. package/dist/cjs/stream.js +3 -2
  81. package/dist/cjs/stream.js.map +1 -1
  82. package/dist/cjs/streams/contract.generated.d.ts +7 -1
  83. package/dist/cjs/streams/contract.generated.js.map +1 -1
  84. package/dist/cjs/streams/messages.js +1 -10
  85. package/dist/cjs/streams/messages.js.map +1 -1
  86. package/dist/cjs/streams/requests.d.ts +3 -0
  87. package/dist/cjs/streams/requests.js +5 -2
  88. package/dist/cjs/streams/requests.js.map +1 -1
  89. package/dist/cjs/streams/transport.d.ts +1 -13
  90. package/dist/cjs/streams/transport.js +2 -18
  91. package/dist/cjs/streams/transport.js.map +1 -1
  92. package/dist/cjs/uns-v2/client.d.ts +1 -6
  93. package/dist/cjs/uns-v2/client.js +33 -8
  94. package/dist/cjs/uns-v2/client.js.map +1 -1
  95. package/dist/cjs/uns-v2/data-client.d.ts +5 -2
  96. package/dist/cjs/uns-v2/data-client.js +7 -4
  97. package/dist/cjs/uns-v2/data-client.js.map +1 -1
  98. package/dist/cjs/uns-v2/generated.d.ts +6783 -4655
  99. package/dist/cjs/uns-v2/generated.js +221 -65
  100. package/dist/cjs/uns-v2/generated.js.map +1 -1
  101. package/dist/cjs/uns-v2/sse.d.ts +7 -1
  102. package/dist/cjs/uns-v2/sse.js +12 -2
  103. package/dist/cjs/uns-v2/sse.js.map +1 -1
  104. package/dist/esm/client.d.ts +79 -3
  105. package/dist/esm/client.js +5 -7
  106. package/dist/esm/client.js.map +1 -1
  107. package/dist/esm/cloud-server.d.ts +33 -26
  108. package/dist/esm/cloud-server.js +99 -97
  109. package/dist/esm/cloud-server.js.map +1 -1
  110. package/dist/esm/cloud-transport.d.ts +15 -20
  111. package/dist/esm/cloud-transport.js +86 -67
  112. package/dist/esm/cloud-transport.js.map +1 -1
  113. package/dist/esm/connection-diagnostics.d.ts +2 -0
  114. package/dist/esm/connection-diagnostics.js +17 -0
  115. package/dist/esm/connection-diagnostics.js.map +1 -0
  116. package/dist/esm/data/bootstrap.js +3 -4
  117. package/dist/esm/data/bootstrap.js.map +1 -1
  118. package/dist/esm/data/call.d.ts +1 -3
  119. package/dist/esm/data/call.js +9 -13
  120. package/dist/esm/data/call.js.map +1 -1
  121. package/dist/esm/data/client.d.ts +8 -7
  122. package/dist/esm/data/client.js +22 -9
  123. package/dist/esm/data/client.js.map +1 -1
  124. package/dist/esm/data/collection.d.ts +3 -5
  125. package/dist/esm/data/collection.js +3 -4
  126. package/dist/esm/data/collection.js.map +1 -1
  127. package/dist/esm/data/context.d.ts +5 -11
  128. package/dist/esm/data/context.js +19 -33
  129. package/dist/esm/data/context.js.map +1 -1
  130. package/dist/esm/data/error.d.ts +1 -1
  131. package/dist/esm/data/error.js +3 -3
  132. package/dist/esm/data/error.js.map +1 -1
  133. package/dist/esm/data/index.d.ts +5 -3
  134. package/dist/esm/data/index.js +3 -2
  135. package/dist/esm/data/index.js.map +1 -1
  136. package/dist/esm/data/relay.d.ts +51 -0
  137. package/dist/esm/data/relay.js +368 -0
  138. package/dist/esm/data/relay.js.map +1 -0
  139. package/dist/esm/data/subscribe.d.ts +22 -38
  140. package/dist/esm/data/subscribe.js +22 -27
  141. package/dist/esm/data/subscribe.js.map +1 -1
  142. package/dist/esm/event-stream.d.ts +28 -0
  143. package/dist/esm/event-stream.js +217 -0
  144. package/dist/esm/event-stream.js.map +1 -0
  145. package/dist/esm/mq/client.d.ts +32 -1
  146. package/dist/esm/mq/client.js +404 -69
  147. package/dist/esm/mq/client.js.map +1 -1
  148. package/dist/esm/mq/index.d.ts +1 -0
  149. package/dist/esm/mq/index.js +1 -0
  150. package/dist/esm/mq/index.js.map +1 -1
  151. package/dist/esm/mq/topic.d.ts +29 -0
  152. package/dist/esm/mq/topic.js +44 -0
  153. package/dist/esm/mq/topic.js.map +1 -0
  154. package/dist/esm/mq/types.d.ts +21 -1
  155. package/dist/esm/mq/types.js.map +1 -1
  156. package/dist/esm/openapi/api.generated.d.ts +20 -0
  157. package/dist/esm/openapi/api.generated.js +11 -0
  158. package/dist/esm/openapi/api.generated.js.map +1 -1
  159. package/dist/esm/openapi/client.d.ts +46 -0
  160. package/dist/esm/openapi/client.js +160 -12
  161. package/dist/esm/openapi/client.js.map +1 -1
  162. package/dist/esm/openapi/codecs.generated.d.ts +74 -0
  163. package/dist/esm/openapi/codecs.generated.js +1 -1
  164. package/dist/esm/openapi/codecs.generated.js.map +1 -1
  165. package/dist/esm/openapi/types.generated.d.ts +205 -1
  166. package/dist/esm/openapi/types.generated.js.map +1 -1
  167. package/dist/esm/page-runtime.d.ts +48 -0
  168. package/dist/esm/page-runtime.js +65 -0
  169. package/dist/esm/page-runtime.js.map +1 -0
  170. package/dist/esm/platform-proxy.d.ts +17 -0
  171. package/dist/esm/platform-proxy.js +47 -0
  172. package/dist/esm/platform-proxy.js.map +1 -0
  173. package/dist/esm/runtime-context.d.ts +2 -1
  174. package/dist/esm/runtime-context.js +6 -2
  175. package/dist/esm/runtime-context.js.map +1 -1
  176. package/dist/esm/runtime-env.js.map +1 -1
  177. package/dist/esm/source.d.ts +19 -1
  178. package/dist/esm/source.js +10 -4
  179. package/dist/esm/source.js.map +1 -1
  180. package/dist/esm/stream.js +4 -3
  181. package/dist/esm/stream.js.map +1 -1
  182. package/dist/esm/streams/contract.generated.d.ts +7 -1
  183. package/dist/esm/streams/contract.generated.js.map +1 -1
  184. package/dist/esm/streams/messages.js +1 -10
  185. package/dist/esm/streams/messages.js.map +1 -1
  186. package/dist/esm/streams/requests.d.ts +3 -0
  187. package/dist/esm/streams/requests.js +5 -2
  188. package/dist/esm/streams/requests.js.map +1 -1
  189. package/dist/esm/streams/transport.d.ts +1 -13
  190. package/dist/esm/streams/transport.js +1 -17
  191. package/dist/esm/streams/transport.js.map +1 -1
  192. package/dist/esm/uns-v2/client.d.ts +1 -6
  193. package/dist/esm/uns-v2/client.js +33 -8
  194. package/dist/esm/uns-v2/client.js.map +1 -1
  195. package/dist/esm/uns-v2/data-client.d.ts +5 -2
  196. package/dist/esm/uns-v2/data-client.js +8 -5
  197. package/dist/esm/uns-v2/data-client.js.map +1 -1
  198. package/dist/esm/uns-v2/generated.d.ts +6783 -4655
  199. package/dist/esm/uns-v2/generated.js +221 -65
  200. package/dist/esm/uns-v2/generated.js.map +1 -1
  201. package/dist/esm/uns-v2/sse.d.ts +7 -1
  202. package/dist/esm/uns-v2/sse.js +12 -2
  203. package/dist/esm/uns-v2/sse.js.map +1 -1
  204. package/package.json +25 -12
  205. package/skills/tier0-sdk-v2/SKILL.md +13 -5
  206. package/skills/tier0-sdk-v2/references/integration.md +14 -24
  207. package/skills/tier0-sdk-v2/references/local-connection.md +61 -0
  208. package/skills/tier0-sdk-v2/tier0-sdk-v2-data/SKILL.md +11 -5
  209. package/skills/tier0-sdk-v2/tier0-sdk-v2-data/references/consistency.md +8 -12
  210. package/skills/tier0-sdk-v2/tier0-sdk-v2-data/references/errors.md +24 -5
  211. package/skills/tier0-sdk-v2/tier0-sdk-v2-data/references/modeling.md +3 -1
  212. package/skills/tier0-sdk-v2/tier0-sdk-v2-data/references/read-write.md +46 -13
  213. package/skills/tier0-sdk-v2/tier0-sdk-v2-data/references/schema-evolution.md +2 -0
  214. package/skills/tier0-sdk-v2/tier0-sdk-v2-members/SKILL.md +2 -2
  215. package/skills/tier0-sdk-v2/tier0-sdk-v2-members/references/app-members.md +5 -1
  216. package/skills/tier0-sdk-v2/tier0-sdk-v2-mq/SKILL.md +25 -0
  217. package/skills/tier0-sdk-v2/tier0-sdk-v2-mq/references/quickstart.md +1 -1
  218. package/skills/tier0-sdk-v2/tier0-sdk-v2-notifications/SKILL.md +3 -3
  219. package/skills/tier0-sdk-v2/tier0-sdk-v2-notifications/references/send.md +6 -6
  220. package/skills/tier0-sdk-v2/tier0-sdk-v2-source/SKILL.md +4 -4
  221. package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/changes.md +2 -2
  222. package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/create.md +26 -36
  223. package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/delete.md +9 -23
  224. package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/protocols.md +12 -29
  225. package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/read.md +4 -5
  226. package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/update.md +5 -5
  227. package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/SKILL.md +3 -3
  228. package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/references/create.md +23 -9
  229. package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/references/deploy.md +14 -12
  230. package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/references/http-server.md +4 -4
  231. package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/references/read.md +4 -3
  232. package/skills/tier0-sdk-v2/tier0-sdk-v2-streams/SKILL.md +12 -12
  233. package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/SKILL.md +3 -2
  234. package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/create.md +2 -2
  235. package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/delete.md +47 -20
  236. package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/namespace.md +3 -3
  237. package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/read.md +11 -6
  238. package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/restore.md +12 -13
  239. package/dist/cjs/app-identity-contract.generated.d.ts +0 -22
  240. package/dist/cjs/app-identity-contract.generated.js +0 -51
  241. package/dist/cjs/app-identity-contract.generated.js.map +0 -1
  242. package/dist/cjs/runtime.d.ts +0 -13
  243. package/dist/cjs/runtime.js +0 -51
  244. package/dist/cjs/runtime.js.map +0 -1
  245. package/dist/esm/app-identity-contract.generated.d.ts +0 -22
  246. package/dist/esm/app-identity-contract.generated.js +0 -48
  247. package/dist/esm/app-identity-contract.generated.js.map +0 -1
  248. package/dist/esm/runtime.d.ts +0 -13
  249. package/dist/esm/runtime.js +0 -46
  250. package/dist/esm/runtime.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../../src/data/bootstrap.ts"],"names":[],"mappings":";;;AAwGA,wDAKC;AAsDD,0CAiNC;AApXD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,6CAAyC;AAEzC,mDAAwE;AAExE,yCAAuD;AACvD,2CAA2F;AAyD3F,MAAM,aAAa,GAAG,CAAC,CAAC;AACxB,8DAA8D;AACjD,QAAA,aAAa,GAAG,KAAK,CAAC;AAEnC,kEAAkE;AACrD,QAAA,mBAAmB,GAAG,MAAM,CAAC;AAE1C;;;;;;GAMG;AACH,SAAgB,sBAAsB,CAAC,KAAc;IACnD,OAAO,CACL,KAAK,YAAY,oBAAS;QAC1B,CAAC,KAAK,CAAC,MAAM,KAAK,yBAAc,CAAC,UAAU,IAAI,KAAK,CAAC,MAAM,KAAK,yBAAc,CAAC,QAAQ,CAAC,CACzF,CAAC;AACJ,CAAC;AAED,SAAS,iBAAiB,CAAC,CAAc,EAAE,CAAc;IACvD,IAAI,CAAC,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,CAAC,aAAa,CAAC,IAAI;QAAE,OAAO,KAAK,CAAC;IAChE,KAAK,MAAM,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,CAAC;QAC1C,IAAI,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE;YAAE,OAAO,KAAK,CAAC;IACtD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,8EAA8E;AAC9E,SAAS,YAAY,CAAC,YAAoB,EAAE,KAAa;IACvD,OAAO,QAAQ,IAAA,wBAAU,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC;AACjG,CAAC;AAED,wFAAwF;AACxF,MAAM,cAAc,GAA2B;IAC7C,aAAa,EAAE,iFAAiF;IAChG,cAAc,EAAE,wGAAwG;IACxH,WAAW,EAAE,uDAAuD;IACpE,YAAY,EAAE,6DAA6D;IAC3E,WAAW,EAAE,6GAA6G;IAC1H,aAAa,EAAE,2BAA2B;IAC1C,gBAAgB,EACd,mJAAmJ;IACrJ,eAAe,EACb,mJAAmJ;CACtJ,CAAC;AAEF,SAAS,iBAAiB,CAAC,SAA2B;IACpD,OAAO,SAAS;SACb,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE;QAChB,MAAM,KAAK,GAAG,GAAG,QAAQ,CAAC,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QAC7E,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,YAAY,QAAQ,CAAC,OAAO,IAAI,GAAG,cAAc,QAAQ,CAAC,QAAQ,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QACxI,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,IAAI,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/G,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,MAAM,IAAI,UAAU,GAAG,KAAK,GAAG,IAAI,EAAE,CAAC;IACzE,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAED,SAAS,QAAQ,CAAC,KAAa,EAAE,IAAgB;IAC/C,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,KAAK,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;AACrD,CAAC;AAED,SAAS,gBAAgB,CAAC,OAAuB;IAC/C,OAAO,OAAO;SACX,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CAClB,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,GAAG,CACzB,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,MAAM,CAAC,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAC9I,CACF;SACA,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAED,SAAgB,eAAe,CAAC,MAAuB;IACrD,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IAC1D,IAAI,OAAO,GAAgC,IAAI,CAAC;IAChD,IAAI,WAAW,GAAG,MAAM,CAAC,iBAAiB,CAAC;IAE3C,KAAK,UAAU,aAAa,CAAC,KAA2B;QACtD,wEAAwE;QACxE,OAAO,IAAI,CAA8C,sBAAsB,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,CAAC;IAC3G,CAAC;IAED,KAAK,UAAU,eAAe,CAAC,YAAoB,EAAE,KAAa,EAAE,SAA2D;QAC7H,KAAK,IAAI,OAAO,GAAG,CAAC,GAAI,OAAO,IAAI,CAAC,EAAE,CAAC;YACrC,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAA8C,iBAAiB,EAAE;oBACxF,YAAY;oBACZ,UAAU,EAAE,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;oBAChE,OAAO,EAAE,IAAI;oBACb,MAAM,EAAE,IAAI;oBACZ,cAAc,EAAE,YAAY,CAAC,YAAY,EAAE,KAAK,CAAC;iBAClD,CAAC,CAAC;gBACH,IAAA,mCAAmB,EAAC,MAAM,EAAE,MAAM,CAAC,CAAC;gBACpC,OAAO;YACT,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,0FAA0F;gBAC1F,wFAAwF;gBACxF,IAAI,CAAC,CAAC,KAAK,YAAY,oBAAS,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,cAAc,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,OAAO,IAAI,aAAa;oBAAE,MAAM,KAAK,CAAC;gBAC1H,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,qBAAa,GAAG,OAAO,CAAC,CAAC,CAAC;YAC/E,CAAC;QACH,CAAC;IACH,CAAC;IAED,KAAK,UAAU,UAAU,CAAC,OAAuB;QAC/C,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS;gBAAE,SAAS;YAC1C,MAAM,UAAU,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;YACjH,MAAM,IAAI,GAAG,UAAU,EAAE,IAAI,CAAC;YAC9B,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;gBAAE,SAAS;YACxD,IAAI,CAAC;gBACH,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE;oBACtC,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,IAAA,4BAAgB,EAAC,UAAU,EAAE,QAAmC,CAAC,CAAC;oBACvF,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;gBACtB,CAAC,CAAC,CAAC;gBACH,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,SAAS,CAAC,MAAM,EAAE,KAAK,IAAI,gCAAgB,EAAE,CAAC;oBACxE,MAAM,eAAe,CAAC,MAAM,CAAC,YAAY,EAAE,KAAK,GAAG,gCAAgB,EAAE,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,gCAAgB,CAAC,CAAC,CAAC;gBACzH,CAAC;gBACD,MAAM,CAAC,IAAI,CAAC,iBAAiB,SAAS,CAAC,MAAM,oBAAoB,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC;YACpF,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,oEAAoE;gBACpE,oEAAoE;gBACpE,MAAM,CAAC,KAAK,CAAC,mCAAmC,MAAM,CAAC,KAAK,+CAA+C,EAAE,KAAK,CAAC,CAAC;YACtH,CAAC;QACH,CAAC;IACH,CAAC;IAED,KAAK,UAAU,GAAG,CAAC,OAA6B;QAC9C,MAAM,SAAS,GAAqB,EAAE,CAAC;QACvC,IAAI,SAAS,GAAG,OAAO,CAAC;QACxB,IAAI,QAAQ,GAAgD,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;QAC5E,OAAO,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5B,IAAI,CAAC;gBACH,QAAQ,GAAG,MAAM,aAAa,CAAC,SAAS,CAAC,CAAC;gBAC1C,MAAM;YACR,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,CAAC,CAAC,KAAK,YAAY,oBAAS,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB;oBAAE,MAAM,KAAK,CAAC;gBACnF,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAE,KAAK,CAAC,OAAO,CAAC,SAA8B,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC7G,MAAM,OAAO,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;gBAC5C,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;oBAC9B,MAAM,IAAI,oBAAS,CAAC;wBAClB,OAAO,EACL,kGAAkG,OAAO,EAAE;wBAC7G,MAAM,EAAE,GAAG;wBACX,IAAI,EAAE,iBAAiB;wBACvB,cAAc,EAAE,KAAK,CAAC,cAAc;wBACpC,SAAS,EAAE,KAAK,CAAC,SAAS;wBAC1B,SAAS,EAAE,KAAK,CAAC,SAAS;wBAC1B,QAAQ,EAAE,KAAK,CAAC,QAAQ;wBACxB,OAAO,EAAE,KAAK,CAAC,OAAO;qBACvB,CAAC,CAAC;gBACL,CAAC;gBACD,qEAAqE;gBACrE,uDAAuD;gBACvD,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;gBACtF,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;gBACpF,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,MAAM;oBAAE,MAAM,KAAK,CAAC;gBAClD,MAAM,CAAC,KAAK,CAAC,sFAAsF,OAAO,EAAE,CAAC,CAAC;gBAC9G,SAAS,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAC;gBAC5B,SAAS,GAAG,IAAI,CAAC;YACnB,CAAC;QACH,CAAC;QAED,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,IAAI,EAAE,CAAC;QACvC,MAAM,aAAa,GAAG,IAAI,GAAG,EAAkB,CAAC;QAChD,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YACjC,IAAI,QAAQ,CAAC,YAAY;gBAAE,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,QAAQ,CAAC,YAAY,CAAC,CAAC;QACpG,CAAC;QACD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,MAAM,CAAC,YAAY,CAAC,CAAC;YACnE,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC;YACnC,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,wBAAwB,CAAC,CAAC;YACrF,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,4BAA4B,CAAC,CAAC;YACzF,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,wBAAwB,IAAI,IAAI,CAAC,MAAM,KAAK,4BAA4B,CAAC,CAAC;YAC/H,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC3B,MAAM,CAAC,IAAI,CACT,mEAAmE,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;oBACvI,6IAA6I,CAChJ,CAAC;YACJ,CAAC;YACD,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACrB,MAAM,CAAC,IAAI,CACT,WAAW,MAAM,CAAC,KAAK,4EAA4E;oBACjG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,IAAI,QAAQ,IAAI,IAAI,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CACzF,CAAC;YACJ,CAAC;YACD,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC3B,4EAA4E;gBAC5E,MAAM,CAAC,IAAI,CACT,gFAAgF,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;oBACpJ,qLAAqL,CACxL,CAAC;YACJ,CAAC;QACH,CAAC;QAED,MAAM,UAAU,CAAC,OAAO,CAAC,CAAC;QAE1B,MAAM,QAAQ,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAC3C,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;gBAC9B,MAAM,IAAI,oBAAS,CAAC;oBAClB,OAAO,EACL,4CAA4C,QAAQ,IAAI;wBACxD,mHAAmH;wBACnH,gGAAgG;oBAClG,MAAM,EAAE,GAAG;oBACX,IAAI,EAAE,iBAAiB;oBACvB,gEAAgE;oBAChE,SAAS,EAAE,WAAW;oBACtB,OAAO,EAAE,EAAE,OAAO,EAAE;iBACrB,CAAC,CAAC;YACL,CAAC;YACD,MAAM,CAAC,IAAI,CAAC,4BAA4B,QAAQ,EAAE,CAAC,CAAC;QACtD,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,CAAC;IACtE,CAAC;IAED,kGAAkG;IAClG,SAAS,MAAM;QACb,OAAO,KAAK,OAAO,CAAC,OAAO,EAAE;aAC1B,IAAI,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,6BAAiB,CAAC,CAAC,CAAC;aACnD,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;YACf,OAAO,GAAG,IAAI,CAAC;YACf,MAAM,KAAK,CAAC;QACd,CAAC,CAAC,CAAC;QACL,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;;;;OAKG;IACH,KAAK,UAAU,OAAO,CAAC,MAAmB,EAAE,KAAgB;QAC1D,+FAA+F;QAC/F,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC;QAC5C,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAAE,OAAO,KAAK,CAAC;QACzG,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC;QACzB,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC;QAC7B,IAAI,MAAM,KAAK,MAAM;YAAE,OAAO,CAAC,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACjE,IAAI,OAAO,KAAK,OAAO;YAAE,OAAO,CAAC,iBAAiB,CAAC,MAAM,EAAE,MAAM,MAAM,EAAE,CAAC,CAAC;QAC3E,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,IAAI,GAAG,GAAG,WAAW,GAAG,2BAAmB;YAAE,OAAO,KAAK,CAAC;QAC1D,WAAW,GAAG,GAAG,CAAC;QAClB,MAAM,CAAC,IAAI,CAAC,+CAA+C,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,OAAO,+BAA+B,CAAC,CAAC;QACxH,OAAO,GAAG,IAAI,CAAC;QACf,OAAO,CAAC,iBAAiB,CAAC,MAAM,EAAE,MAAM,MAAM,EAAE,CAAC,CAAC;IACpD,CAAC;IAED;;;;OAIG;IACH,KAAK,UAAU,OAAO,CAAI,EAAoB,EAAE,UAA+B,EAAE;QAC/E,MAAM,MAAM,GAAG,MAAM,MAAM,EAAE,CAAC;QAC9B,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,EAAE,CAAC;QACpB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,sBAAsB,CAAC,KAAK,CAAC;gBAAE,MAAM,KAAK,CAAC;YAChD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,MAAM,EAAE,KAAkB,CAAC,CAAC;YAC1D,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,KAAK,KAAK,KAAK;gBAAE,MAAM,KAAK,CAAC;YACrD,OAAO,EAAE,EAAE,CAAC;QACd,CAAC;IACH,CAAC;IAED,KAAK,UAAU,OAAO,CAAC,UAAgC;QACrD,MAAM,KAAK,GAAG,MAAM,MAAM,EAAE,CAAC;QAC7B,MAAM,EAAE,GAAG,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;QACnE,IAAI,CAAC,EAAE,EAAE,CAAC;YACR,MAAM,IAAI,oBAAS,CAAC;gBAClB,OAAO,EAAE,eAAe,UAAU,CAAC,KAAK,kEAAkE;gBAC1G,MAAM,EAAE,GAAG;gBACX,IAAI,EAAE,wBAAwB;aAC/B,CAAC,CAAC;QACL,CAAC;QACD,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;AAC/C,CAAC","sourcesContent":["/**\n * First-access bootstrap: one batched `ensure` of every declared collection.\n *\n * - ensure only creates or widens; storage never narrows from here, so old\n * and new code may cold-start in any order.\n * - The result is memoized per client, i.e. per server process; a client\n * built from edited declarations ensures again.\n * Failures are not memoized: a later call retries (an imported App may\n * answer \"hosted App is not ready\").\n * - Seed documents are inserted only for collections ensure reports as\n * `created`: fixed `_id`s, atomic chunks of 200 with a stable idempotency\n * key per chunk, so a failed chunk (outcome unknown, or marked safe to\n * resend) is replayed after a short wait instead of duplicated. Seed writes\n * never carry a data subject.\n * - Preview throws on SCHEMA_CONFLICT and warnings so the worker sees them;\n * a deployment logs them and keeps serving with the IDs it has.\n * - Self-healing: a Preview reset hard-deletes collections, and a worker or\n * admin may archive one, while this process still holds the old IDs. A\n * record call that fails with `data.reason` COLLECTION_NOT_FOUND or\n * COLLECTION_NOT_GRANTED drops the memo, ensures again (seeding what is created)\n * and retries the call once, but only when a collection ID actually\n * changed. Rebuilds are limited to one per REBUILD_INTERVAL_MS per client;\n * APP_GRANT_REVOKED is never retried (ensure itself reports it).\n * - `ignored` notes never fail a request. ensure never writes annotations, so\n * an edited name, `.describe()` or collection description comes back as\n * ANNOTATION_NOT_APPLIED; it is logged as a warning pointing at\n * metadata:updateOne for names, or schema:replace for schema annotations.\n */\nimport { createHash } from 'node:crypto';\nimport type { DataCall } from './call.js';\nimport { assertNoWriteErrors, MAX_ATOMIC_ITEMS } from './collection.js';\nimport type { CollectionDefinition } from './define.js';\nimport { ACCESS_REASONS, DataError } from './error.js';\nimport { compileCollection, validateDocument, type CompiledCollection } from './schema.js';\n\nexport type DataEnvironment = 'preview' | 'deployed';\n\nexport interface EnsureWarning {\n code: string;\n path?: string;\n message?: string;\n}\n\nexport interface EnsureNote {\n path: string;\n reason?: string;\n message?: string;\n}\n\nexport interface EnsureResult {\n alias: string;\n collectionId: string;\n revision: number;\n status: 'created' | 'unchanged' | 'widened';\n ignored?: EnsureNote[];\n warnings?: EnsureWarning[];\n indexStatus?: unknown[];\n}\n\nexport interface EnsureConflict {\n alias: string;\n collectionId?: string;\n path?: string;\n reason?: string;\n current?: string;\n declared?: string;\n}\n\nexport interface EnsureState {\n appId?: string;\n results: EnsureResult[];\n /** Lower-cased alias → collection ID. */\n collectionIds: Map<string, string>;\n /** Declarations that conflicted in a deployment (served with their existing ID, if any). */\n conflicts: EnsureConflict[];\n}\n\nexport interface Logger {\n info(...args: unknown[]): void;\n warn(...args: unknown[]): void;\n error(...args: unknown[]): void;\n}\n\nexport interface BootstrapConfig {\n call: DataCall;\n collections: readonly CollectionDefinition[];\n environment: DataEnvironment;\n logger: Logger;\n}\n\nconst SEED_ATTEMPTS = 3;\n/** Wait before replaying seed chunk attempt n+1: n × this. */\nexport const SEED_RETRY_MS = 1_000;\n\n/** At most one self-healing rebuild per client in this window. */\nexport const REBUILD_INTERVAL_MS = 30_000;\n\n/**\n * Whether a record call failed because the collection ID it used is gone or\n * no longer granted, by UNS's stable `data.reason` code. Archive and Preview\n * purge also remove the App grant, so most stale IDs answer\n * COLLECTION_NOT_GRANTED or COLLECTION_NOT_FOUND. APP_PERMISSION_MISSING (the\n * key lacks e.g. `uns.delete`) and APP_GRANT_REVOKED are not stale IDs.\n */\nexport function isStaleCollectionError(error: unknown): boolean {\n return (\n error instanceof DataError &&\n (error.reason === ACCESS_REASONS.notGranted || error.reason === ACCESS_REASONS.notFound)\n );\n}\n\nfunction sameCollectionIds(a: EnsureState, b: EnsureState): boolean {\n if (a.collectionIds.size !== b.collectionIds.size) return false;\n for (const [alias, id] of a.collectionIds) {\n if (b.collectionIds.get(alias) !== id) return false;\n }\n return true;\n}\n\n/** Idempotency key of one seed chunk (UNS keys are at most 96 characters). */\nfunction seedChunkKey(collectionId: string, chunk: number): string {\n return `seed-${createHash('sha256').update(collectionId).digest('hex').slice(0, 40)}-${chunk}`;\n}\n\n/** What to do about each SCHEMA_CONFLICT reason (CloudAppCollectionConflict.reason). */\nconst CONFLICT_HINTS: Record<string, string> = {\n TYPE_CONFLICT: \"a field's type cannot change; use a new field name and backfill with updateMany\",\n LIMIT_EXCEEDED: 'the joined schema exceeds a UNS limit (depth, properties, enum values or indexes); split the structure',\n OPEN_OBJECT: 'every object must be closed; declare it with z.object',\n ALIAS_IN_USE: 'the alias belongs to another collection; pick another alias',\n NAME_IN_USE: 'the business name belongs to another collection in this folder; pick another name and keep the stable alias',\n INVALID_INDEX: 'fix the index declaration',\n JOIN_UNSUPPORTED:\n 'the stored schema holds a node the declaration cannot widen (e.g. enum values outside its range); repair it with schema:replace via the tier0 MCP',\n DATA_RULE_FIELD:\n 'an employee data rule (ownerField / stateField) uses this field; keep it required with the same type, or ask a workspace admin to change the rule',\n};\n\nfunction describeConflicts(conflicts: EnsureConflict[]): string {\n return conflicts\n .map((conflict) => {\n const where = `${conflict.alias}${conflict.path ? `.${conflict.path}` : ''}`;\n const types = conflict.current || conflict.declared ? ` (stored ${conflict.current ?? '?'}, declared ${conflict.declared ?? '?'})` : '';\n const hint = conflict.reason && CONFLICT_HINTS[conflict.reason] ? ` — ${CONFLICT_HINTS[conflict.reason]}` : '';\n return ` - ${where}: ${conflict.reason ?? 'conflict'}${types}${hint}`;\n })\n .join('\\n');\n}\n\nfunction notePath(alias: string, note: EnsureNote): string {\n return note.path ? `${alias}.${note.path}` : alias;\n}\n\nfunction describeWarnings(results: EnsureResult[]): string {\n return results\n .flatMap((result) =>\n (result.warnings ?? []).map(\n (warning) => ` - ${result.alias}${warning.path ? `.${warning.path}` : ''}: ${warning.code}${warning.message ? ` — ${warning.message}` : ''}`,\n ),\n )\n .join('\\n');\n}\n\nexport function createBootstrap(config: BootstrapConfig) {\n const { call, collections, environment, logger } = config;\n let pending: Promise<EnsureState> | null = null;\n let lastRebuild = Number.NEGATIVE_INFINITY;\n\n async function requestEnsure(items: CompiledCollection[]) {\n // ensure is App-level work: it never carries the employee data subject.\n return call<{ appId?: string; results: EnsureResult[] }>('appCollectionsEnsure', { collections: items });\n }\n\n async function insertSeedChunk(collectionId: string, chunk: number, documents: { id?: string; data: Record<string, unknown> }[]) {\n for (let attempt = 1; ; attempt += 1) {\n try {\n const result = await call<{ writeErrors?: Record<string, unknown>[] }>('recordBulkWrite', {\n collectionId,\n operations: documents.map(document => ({ insertOne: document })),\n ordered: true,\n atomic: true,\n idempotencyKey: seedChunkKey(collectionId, chunk),\n });\n assertNoWriteErrors(result, 'seed');\n return;\n } catch (error) {\n // The chunk key is stable, so replaying is safe even when the outcome is unknown: a chunk\n // that did commit replays its receipt. Wait first, so a write still running can finish.\n if (!(error instanceof DataError) || !(error.outcomeUnknown || error.retry.safe) || attempt >= SEED_ATTEMPTS) throw error;\n await new Promise((resolve) => setTimeout(resolve, SEED_RETRY_MS * attempt));\n }\n }\n }\n\n async function writeSeeds(results: EnsureResult[]) {\n for (const result of results) {\n if (result.status !== 'created') continue;\n const definition = collections.find((candidate) => candidate.alias.toLowerCase() === result.alias.toLowerCase());\n const seed = definition?.seed;\n if (!definition || !seed || seed.length === 0) continue;\n try {\n const documents = seed.map((document) => {\n const { id, data } = validateDocument(definition, document as Record<string, unknown>);\n return { id, data };\n });\n for (let start = 0; start < documents.length; start += MAX_ATOMIC_ITEMS) {\n await insertSeedChunk(result.collectionId, start / MAX_ATOMIC_ITEMS, documents.slice(start, start + MAX_ATOMIC_ITEMS));\n }\n logger.info(`[data] seeded ${documents.length} record(s) into \"${result.alias}\"`);\n } catch (error) {\n // The collection exists now; a later ensure reports \"unchanged\" and\n // never re-seeds, so the failure must be visible in the server log.\n logger.error(`[data] seed for new collection \"${result.alias}\" failed; it keeps the chunks written so far:`, error);\n }\n }\n }\n\n async function run(payload: CompiledCollection[]): Promise<EnsureState> {\n const conflicts: EnsureConflict[] = [];\n let remaining = payload;\n let response: { appId?: string; results: EnsureResult[] } = { results: [] };\n while (remaining.length > 0) {\n try {\n response = await requestEnsure(remaining);\n break;\n } catch (error) {\n if (!(error instanceof DataError) || error.code !== 'SCHEMA_CONFLICT') throw error;\n const reported = Array.isArray(error.details.conflicts) ? (error.details.conflicts as EnsureConflict[]) : [];\n const summary = describeConflicts(reported);\n if (environment === 'preview') {\n throw new DataError({\n message:\n `The collection declarations conflict with the stored collection schemas; nothing was changed:\\n${summary}`,\n status: 409,\n code: 'SCHEMA_CONFLICT',\n upstreamStatus: error.upstreamStatus,\n requestId: error.requestId,\n execution: error.execution,\n attempts: error.attempts,\n details: error.details,\n });\n }\n // A deployment keeps serving: drop the conflicting declarations (the\n // whole batch was rejected) and ensure the rest again.\n const conflicting = new Set(reported.map((conflict) => conflict.alias.toLowerCase()));\n const next = remaining.filter((item) => !conflicting.has(item.alias.toLowerCase()));\n if (next.length === remaining.length) throw error;\n logger.error(`[data] ensure: declarations conflict with stored schemas; serving them unchanged:\\n${summary}`);\n conflicts.push(...reported);\n remaining = next;\n }\n }\n\n const results = response.results ?? [];\n const collectionIds = new Map<string, string>();\n for (const conflict of conflicts) {\n if (conflict.collectionId) collectionIds.set(conflict.alias.toLowerCase(), conflict.collectionId);\n }\n for (const result of results) {\n collectionIds.set(result.alias.toLowerCase(), result.collectionId);\n const notes = result.ignored ?? [];\n const annotations = notes.filter((note) => note.reason === 'ANNOTATION_NOT_APPLIED');\n const directories = notes.filter((note) => note.reason === 'DIRECTORY_PATH_NOT_APPLIED');\n const wider = notes.filter((note) => note.reason !== 'ANNOTATION_NOT_APPLIED' && note.reason !== 'DIRECTORY_PATH_NOT_APPLIED');\n if (directories.length > 0) {\n logger.warn(\n `[data] ensure keeps existing collection locations; not applied: ${directories.map((note) => notePath(result.alias, note)).join(', ')}. ` +\n 'A directoryPath declaration only places a new collection. Move existing collections explicitly through metadata operations when authorized.',\n );\n }\n if (wider.length > 0) {\n logger.info(\n `[data] \"${result.alias}\" storage is wider than this declaration (or has retired parts); ignored: ` +\n wider.map((note) => `${note.path || '(root)'} ${note.reason ?? ''}`.trim()).join(', '),\n );\n }\n if (annotations.length > 0) {\n // A hint, not an error: storage keeps its annotations and serves as before.\n logger.warn(\n `[data] ensure does not change stored names/titles/descriptions; not applied: ${annotations.map((note) => notePath(result.alias, note)).join(', ')}. ` +\n `Rename with metadata:updateOne via the tier0 MCP; apply schema annotations with schema:replace, selecting alias, recordSchema, indexes and description from compileCollection(...).`,\n );\n }\n }\n\n await writeSeeds(results);\n\n const warnings = describeWarnings(results);\n if (warnings) {\n if (environment === 'preview') {\n throw new DataError({\n message:\n `Collections were ensured with warnings:\\n${warnings}\\n` +\n 'REQUIRED_NOT_ENFORCED: make the field optional again or narrow explicitly with schema:replace via the tier0 MCP. ' +\n 'INDEX_BUILD_FAILED: fix the duplicate or invalid data, then the next ensure retries the index.',\n status: 500,\n code: 'SCHEMA_WARNINGS',\n // ensure did apply; only the warnings fail the Preview request.\n execution: 'committed',\n details: { results },\n });\n }\n logger.warn(`[data] ensure warnings:\\n${warnings}`);\n }\n\n return { appId: response.appId, results, collectionIds, conflicts };\n }\n\n /** Ensures every declaration once per client; a failure is forgotten so the next call retries. */\n function ensure(): Promise<EnsureState> {\n pending ??= Promise.resolve()\n .then(() => run(collections.map(compileCollection)))\n .catch((error) => {\n pending = null;\n throw error;\n });\n return pending;\n }\n\n /**\n * Re-ensures after `before` turned out stale. Joins a rebuild already in\n * flight; otherwise rebuilds at most once per REBUILD_INTERVAL_MS. Resolves\n * whether any collection ID changed; ensure errors (APP_GRANT_REVOKED, …)\n * propagate.\n */\n async function rebuild(before: EnsureState, cause: DataError): Promise<boolean> {\n // Only owned IDs can be recovered by ensure; shared references must keep their original error.\n const failedId = cause.details.collectionId;\n if (typeof failedId === 'string' && ![...before.collectionIds.values()].includes(failedId)) return false;\n const current = ensure();\n const latest = await current;\n if (latest !== before) return !sameCollectionIds(before, latest);\n if (pending !== current) return !sameCollectionIds(before, await ensure());\n const now = Date.now();\n if (now - lastRebuild < REBUILD_INTERVAL_MS) return false;\n lastRebuild = now;\n logger.warn(`[data] a collection ID is no longer usable (${cause.code}: ${cause.message}); ensuring collections again`);\n pending = null;\n return !sameCollectionIds(before, await ensure());\n }\n\n /**\n * Runs one data call; when it fails on a stale collection ID, rebuilds and\n * runs it once more if an ID changed. `retry: false` (calls continuing a\n * cursor or resumeAfter token of the old collection) only rebuilds.\n */\n async function recover<R>(fn: () => Promise<R>, options: { retry?: boolean } = {}): Promise<R> {\n const before = await ensure();\n try {\n return await fn();\n } catch (error) {\n if (!isStaleCollectionError(error)) throw error;\n const changed = await rebuild(before, error as DataError);\n if (!changed || options.retry === false) throw error;\n return fn();\n }\n }\n\n async function resolve(definition: CollectionDefinition): Promise<string> {\n const state = await ensure();\n const id = state.collectionIds.get(definition.alias.toLowerCase());\n if (!id) {\n throw new DataError({\n message: `Collection \"${definition.alias}\" is unavailable: ensure did not return it (see the server log).`,\n status: 503,\n code: 'COLLECTION_UNAVAILABLE',\n });\n }\n return id;\n }\n\n return { ensure, resolve, recover, rebuild };\n}\n"]}
1
+ {"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../../src/data/bootstrap.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * First-access bootstrap: one batched `ensure` of every declared collection.\n *\n * - ensure only creates or widens; storage never narrows from here, so old\n * and new code may cold-start in any order.\n * - The result is memoized per client, i.e. per server process; a client\n * built from edited declarations ensures again.\n * Failures are not memoized: a later call retries (an imported App may\n * answer \"hosted App is not ready\").\n * - Seed documents are inserted only for collections ensure reports as\n * `created`: fixed `_id`s, atomic chunks of 200 with a stable idempotency\n * key per chunk, so a failed chunk (outcome unknown, or marked safe to\n * resend) is replayed after a short wait instead of duplicated. Preview and\n * deployments write them the same way, as the App, with the App's key\n * the platform provides.\n * - Preview throws on SCHEMA_CONFLICT and warnings so the worker sees them;\n * a deployment logs them and keeps serving with the IDs it has.\n * - Self-healing: a Preview reset hard-deletes collections, and a worker or\n * admin may archive one, while this process still holds the old IDs. A\n * record call that fails with `data.reason` COLLECTION_NOT_FOUND or\n * COLLECTION_NOT_GRANTED drops the memo, ensures again (seeding what is created)\n * and retries the call once, but only when a collection ID actually\n * changed. Rebuilds are limited to one per REBUILD_INTERVAL_MS per client;\n * APP_GRANT_REVOKED is never retried (ensure itself reports it).\n * - `ignored` notes never fail a request. ensure never writes annotations, so\n * an edited name, `.describe()` or collection description comes back as\n * ANNOTATION_NOT_APPLIED; it is logged as a warning pointing at\n * metadata:updateOne for names, or schema:replace for schema annotations.\n */\nimport { createHash } from 'node:crypto';\nimport type { DataCall } from './call.js';\nimport { assertNoWriteErrors, MAX_ATOMIC_ITEMS } from './collection.js';\nimport type { CollectionDefinition } from './define.js';\nimport { ACCESS_REASONS, DataError } from './error.js';\nimport { compileCollection, validateDocument, type CompiledCollection } from './schema.js';\n\nexport type DataEnvironment = 'preview' | 'deployed';\n\nexport interface EnsureWarning {\n code: string;\n path?: string;\n message?: string;\n}\n\nexport interface EnsureNote {\n path: string;\n reason?: string;\n message?: string;\n}\n\nexport interface EnsureResult {\n alias: string;\n collectionId: string;\n revision: number;\n status: 'created' | 'unchanged' | 'widened';\n ignored?: EnsureNote[];\n warnings?: EnsureWarning[];\n indexStatus?: unknown[];\n}\n\nexport interface EnsureConflict {\n alias: string;\n collectionId?: string;\n path?: string;\n reason?: string;\n current?: string;\n declared?: string;\n}\n\nexport interface EnsureState {\n appId?: string;\n results: EnsureResult[];\n /** Lower-cased alias → collection ID. */\n collectionIds: Map<string, string>;\n /** Declarations that conflicted in a deployment (served with their existing ID, if any). */\n conflicts: EnsureConflict[];\n}\n\nexport interface Logger {\n info(...args: unknown[]): void;\n warn(...args: unknown[]): void;\n error(...args: unknown[]): void;\n}\n\nexport interface BootstrapConfig {\n call: DataCall;\n collections: readonly CollectionDefinition[];\n environment: DataEnvironment;\n logger: Logger;\n}\n\nconst SEED_ATTEMPTS = 3;\n/** Wait before replaying seed chunk attempt n+1: n × this. */\nexport const SEED_RETRY_MS = 1_000;\n\n/** At most one self-healing rebuild per client in this window. */\nexport const REBUILD_INTERVAL_MS = 30_000;\n\n/**\n * Whether a record call failed because the collection ID it used is gone or\n * no longer granted, by UNS's stable `data.reason` code. Archive and Preview\n * purge also remove the App grant, so most stale IDs answer\n * COLLECTION_NOT_GRANTED or COLLECTION_NOT_FOUND. APP_PERMISSION_MISSING (the\n * key lacks e.g. `uns.delete`) and APP_GRANT_REVOKED are not stale IDs.\n */\nexport function isStaleCollectionError(error: unknown): boolean {\n return (\n error instanceof DataError &&\n (error.reason === ACCESS_REASONS.notGranted || error.reason === ACCESS_REASONS.notFound)\n );\n}\n\nfunction sameCollectionIds(a: EnsureState, b: EnsureState): boolean {\n if (a.collectionIds.size !== b.collectionIds.size) return false;\n for (const [alias, id] of a.collectionIds) {\n if (b.collectionIds.get(alias) !== id) return false;\n }\n return true;\n}\n\n/** Idempotency key of one seed chunk (UNS keys are at most 96 characters). */\nfunction seedChunkKey(collectionId: string, chunk: number): string {\n return `seed-${createHash('sha256').update(collectionId).digest('hex').slice(0, 40)}-${chunk}`;\n}\n\n/** What to do about each SCHEMA_CONFLICT reason (CloudAppCollectionConflict.reason). */\nconst CONFLICT_HINTS: Record<string, string> = {\n TYPE_CONFLICT: \"a field's type cannot change; use a new field name and backfill with updateMany\",\n LIMIT_EXCEEDED: 'the joined schema exceeds a UNS limit (depth, properties, enum values or indexes); split the structure',\n OPEN_OBJECT: 'every object must be closed; declare it with z.object',\n ALIAS_IN_USE: 'the alias belongs to another collection; pick another alias',\n NAME_IN_USE: 'the business name belongs to another collection in this folder; pick another name and keep the stable alias',\n INVALID_INDEX: 'fix the index declaration',\n JOIN_UNSUPPORTED:\n 'the stored schema holds a node the declaration cannot widen (e.g. enum values outside its range); repair it with schema:replace via the tier0 MCP',\n};\n\nfunction describeConflicts(conflicts: EnsureConflict[]): string {\n return conflicts\n .map((conflict) => {\n const where = `${conflict.alias}${conflict.path ? `.${conflict.path}` : ''}`;\n const types = conflict.current || conflict.declared ? ` (stored ${conflict.current ?? '?'}, declared ${conflict.declared ?? '?'})` : '';\n const hint = conflict.reason && CONFLICT_HINTS[conflict.reason] ? ` — ${CONFLICT_HINTS[conflict.reason]}` : '';\n return ` - ${where}: ${conflict.reason ?? 'conflict'}${types}${hint}`;\n })\n .join('\\n');\n}\n\nfunction notePath(alias: string, note: EnsureNote): string {\n return note.path ? `${alias}.${note.path}` : alias;\n}\n\nfunction describeWarnings(results: EnsureResult[]): string {\n return results\n .flatMap((result) =>\n (result.warnings ?? []).map(\n (warning) => ` - ${result.alias}${warning.path ? `.${warning.path}` : ''}: ${warning.code}${warning.message ? ` — ${warning.message}` : ''}`,\n ),\n )\n .join('\\n');\n}\n\nexport function createBootstrap(config: BootstrapConfig) {\n const { call, collections, environment, logger } = config;\n let pending: Promise<EnsureState> | null = null;\n let lastRebuild = Number.NEGATIVE_INFINITY;\n\n async function requestEnsure(items: CompiledCollection[]) {\n return call<{ appId?: string; results: EnsureResult[] }>('appCollectionsEnsure', { collections: items });\n }\n\n async function insertSeedChunk(collectionId: string, chunk: number, documents: { id?: string; data: Record<string, unknown> }[]) {\n for (let attempt = 1; ; attempt += 1) {\n try {\n const result = await call<{ writeErrors?: Record<string, unknown>[] }>('recordBulkWrite', {\n collectionId,\n operations: documents.map(document => ({ insertOne: document })),\n ordered: true,\n atomic: true,\n idempotencyKey: seedChunkKey(collectionId, chunk),\n });\n assertNoWriteErrors(result, 'seed');\n return;\n } catch (error) {\n // The chunk key is stable, so replaying is safe even when the outcome is unknown: a chunk\n // that did commit replays its receipt. Wait first, so a write still running can finish.\n if (!(error instanceof DataError) || !(error.outcomeUnknown || error.retry.safe) || attempt >= SEED_ATTEMPTS) throw error;\n await new Promise((resolve) => setTimeout(resolve, SEED_RETRY_MS * attempt));\n }\n }\n }\n\n async function writeSeeds(results: EnsureResult[]) {\n for (const result of results) {\n if (result.status !== 'created') continue;\n const definition = collections.find((candidate) => candidate.alias.toLowerCase() === result.alias.toLowerCase());\n const seed = definition?.seed;\n if (!definition || !seed || seed.length === 0) continue;\n try {\n const documents = seed.map((document) => {\n const { id, data } = validateDocument(definition, document as Record<string, unknown>);\n return { id, data };\n });\n for (let start = 0; start < documents.length; start += MAX_ATOMIC_ITEMS) {\n await insertSeedChunk(result.collectionId, start / MAX_ATOMIC_ITEMS, documents.slice(start, start + MAX_ATOMIC_ITEMS));\n }\n logger.info(`[data] seeded ${documents.length} record(s) into \"${result.alias}\"`);\n } catch (error) {\n // The collection exists now; a later ensure reports \"unchanged\" and\n // never re-seeds, so the failure must be visible in the server log.\n logger.error(`[data] seed for new collection \"${result.alias}\" failed; it keeps the chunks written so far:`, error);\n }\n }\n }\n\n async function run(payload: CompiledCollection[]): Promise<EnsureState> {\n const conflicts: EnsureConflict[] = [];\n let remaining = payload;\n let response: { appId?: string; results: EnsureResult[] } = { results: [] };\n while (remaining.length > 0) {\n try {\n response = await requestEnsure(remaining);\n break;\n } catch (error) {\n if (!(error instanceof DataError) || error.code !== 'SCHEMA_CONFLICT') throw error;\n const reported = Array.isArray(error.details.conflicts) ? (error.details.conflicts as EnsureConflict[]) : [];\n const summary = describeConflicts(reported);\n if (environment === 'preview') {\n throw new DataError({\n message:\n `The collection declarations conflict with the stored collection schemas; nothing was changed:\\n${summary}`,\n status: 409,\n code: 'SCHEMA_CONFLICT',\n upstreamStatus: error.upstreamStatus,\n requestId: error.requestId,\n execution: error.execution,\n attempts: error.attempts,\n details: error.details,\n });\n }\n // A deployment keeps serving: drop the conflicting declarations (the\n // whole batch was rejected) and ensure the rest again.\n const conflicting = new Set(reported.map((conflict) => conflict.alias.toLowerCase()));\n const next = remaining.filter((item) => !conflicting.has(item.alias.toLowerCase()));\n if (next.length === remaining.length) throw error;\n logger.error(`[data] ensure: declarations conflict with stored schemas; serving them unchanged:\\n${summary}`);\n conflicts.push(...reported);\n remaining = next;\n }\n }\n\n const results = response.results ?? [];\n const collectionIds = new Map<string, string>();\n for (const conflict of conflicts) {\n if (conflict.collectionId) collectionIds.set(conflict.alias.toLowerCase(), conflict.collectionId);\n }\n for (const result of results) {\n collectionIds.set(result.alias.toLowerCase(), result.collectionId);\n const notes = result.ignored ?? [];\n const annotations = notes.filter((note) => note.reason === 'ANNOTATION_NOT_APPLIED');\n const directories = notes.filter((note) => note.reason === 'DIRECTORY_PATH_NOT_APPLIED');\n const wider = notes.filter((note) => note.reason !== 'ANNOTATION_NOT_APPLIED' && note.reason !== 'DIRECTORY_PATH_NOT_APPLIED');\n if (directories.length > 0) {\n logger.warn(\n `[data] ensure keeps existing collection locations; not applied: ${directories.map((note) => notePath(result.alias, note)).join(', ')}. ` +\n 'A directoryPath declaration only places a new collection. Move existing collections explicitly through metadata operations when authorized.',\n );\n }\n if (wider.length > 0) {\n logger.info(\n `[data] \"${result.alias}\" storage is wider than this declaration (or has retired parts); ignored: ` +\n wider.map((note) => `${note.path || '(root)'} ${note.reason ?? ''}`.trim()).join(', '),\n );\n }\n if (annotations.length > 0) {\n // A hint, not an error: storage keeps its annotations and serves as before.\n logger.warn(\n `[data] ensure does not change stored names/titles/descriptions; not applied: ${annotations.map((note) => notePath(result.alias, note)).join(', ')}. ` +\n `Rename with metadata:updateOne via the tier0 MCP; apply schema annotations with schema:replace, selecting alias, recordSchema, indexes and description from compileCollection(...).`,\n );\n }\n }\n\n await writeSeeds(results);\n\n const warnings = describeWarnings(results);\n if (warnings) {\n if (environment === 'preview') {\n throw new DataError({\n message:\n `Collections were ensured with warnings:\\n${warnings}\\n` +\n 'REQUIRED_NOT_ENFORCED: make the field optional again or narrow explicitly with schema:replace via the tier0 MCP. ' +\n 'INDEX_BUILD_FAILED: fix the duplicate or invalid data, then the next ensure retries the index.',\n status: 500,\n code: 'SCHEMA_WARNINGS',\n // ensure did apply; only the warnings fail the Preview request.\n execution: 'committed',\n details: { results },\n });\n }\n logger.warn(`[data] ensure warnings:\\n${warnings}`);\n }\n\n return { appId: response.appId, results, collectionIds, conflicts };\n }\n\n /** Ensures every declaration once per client; a failure is forgotten so the next call retries. */\n function ensure(): Promise<EnsureState> {\n pending ??= Promise.resolve()\n .then(() => run(collections.map(compileCollection)))\n .catch((error) => {\n pending = null;\n throw error;\n });\n return pending;\n }\n\n /**\n * Re-ensures after `before` turned out stale. Joins a rebuild already in\n * flight; otherwise rebuilds at most once per REBUILD_INTERVAL_MS. Resolves\n * whether any collection ID changed; ensure errors (APP_GRANT_REVOKED, …)\n * propagate.\n */\n async function rebuild(before: EnsureState, cause: DataError): Promise<boolean> {\n // Only owned IDs can be recovered by ensure; shared references must keep their original error.\n const failedId = cause.details.collectionId;\n if (typeof failedId === 'string' && ![...before.collectionIds.values()].includes(failedId)) return false;\n const current = ensure();\n const latest = await current;\n if (latest !== before) return !sameCollectionIds(before, latest);\n if (pending !== current) return !sameCollectionIds(before, await ensure());\n const now = Date.now();\n if (now - lastRebuild < REBUILD_INTERVAL_MS) return false;\n lastRebuild = now;\n logger.warn(`[data] a collection ID is no longer usable (${cause.code}: ${cause.message}); ensuring collections again`);\n pending = null;\n return !sameCollectionIds(before, await ensure());\n }\n\n /**\n * Runs one data call; when it fails on a stale collection ID, rebuilds and\n * runs it once more if an ID changed. `retry: false` (calls continuing a\n * cursor or resumeAfter token of the old collection) only rebuilds.\n */\n async function recover<R>(fn: () => Promise<R>, options: { retry?: boolean } = {}): Promise<R> {\n const before = await ensure();\n try {\n return await fn();\n } catch (error) {\n if (!isStaleCollectionError(error)) throw error;\n const changed = await rebuild(before, error as DataError);\n if (!changed || options.retry === false) throw error;\n return fn();\n }\n }\n\n async function resolve(definition: CollectionDefinition): Promise<string> {\n const state = await ensure();\n const id = state.collectionIds.get(definition.alias.toLowerCase());\n if (!id) {\n throw new DataError({\n message: `Collection \"${definition.alias}\" is unavailable: ensure did not return it (see the server log).`,\n status: 503,\n code: 'COLLECTION_UNAVAILABLE',\n });\n }\n return id;\n }\n\n return { ensure, resolve, recover, rebuild };\n}\n"]}
@@ -10,8 +10,6 @@ export declare const MAX_RETRIES = 2;
10
10
  /** A retry waits at most this long; a longer `retry.afterMs` surfaces the error instead. */
11
11
  export declare const MAX_RETRY_WAIT_MS = 5000;
12
12
  export interface CallOptions {
13
- /** Employee assertion forwarded from the current business request. */
14
- dataSubject?: string;
15
13
  /** Abort of the current business request: a queued call leaves the queue, an in-flight one is cancelled. */
16
14
  signal?: AbortSignal;
17
15
  }
@@ -21,7 +19,7 @@ export type DataCall = <T>(operation: UnsV2OperationName, request: Record<string
21
19
  * Opens one `records:subscribe` stream (outside the concurrency gate: it is
22
20
  * long-lived and holds no UNS connection while it waits). Failures are DataErrors.
23
21
  */
24
- export type DataOpenStream = (request: UnsV2RecordSubscribeRequest, options: CallOptions & {
22
+ export type DataOpenStream = (request: UnsV2RecordSubscribeRequest, options: {
25
23
  lastEventId?: string;
26
24
  signal: AbortSignal;
27
25
  }) => AsyncGenerator<UnsV2SubscriptionEvent>;
@@ -8,7 +8,7 @@ exports.createDataTransport = createDataTransport;
8
8
  * sends the request and checks the envelope; this adds the App runtime policy
9
9
  * around it and turns every failure into a `DataError`:
10
10
  *
11
- * - binds the employee data subject and the abort signal of the current call;
11
+ * - binds the abort signal of the current call;
12
12
  * - gives every write that takes an idempotency key a fresh UUID unless the
13
13
  * caller set one, and keeps it for the retries of that call;
14
14
  * - sends at most MAX_CONCURRENT_CALLS requests per process at a time; the
@@ -118,16 +118,17 @@ function pause(ms, signal) {
118
118
  });
119
119
  }
120
120
  function createDataTransport(config) {
121
- const http = new client_js_1.HttpClient(config);
121
+ const snapshot = (0, client_js_1.snapshotClientConfig)(config, ['transportTimeoutMs']);
122
+ const http = new client_js_1.HttpClient(snapshot);
122
123
  const resolve = () => http;
123
- const timeoutMs = config.transportTimeoutMs ?? exports.DEFAULT_DATA_TIMEOUT_MS;
124
+ const timeoutMs = snapshot.transportTimeoutMs ?? exports.DEFAULT_DATA_TIMEOUT_MS;
124
125
  const transport = { transportTimeoutMs: timeoutMs };
125
126
  const app = new client_js_2.UnsV2ClientCore(resolve, transport);
126
127
  function assertConfigured() {
127
128
  let problem;
128
129
  try {
129
130
  http.getBaseURL();
130
- if (!http.getApiKey()?.trim())
131
+ if (!http.usesAppCredential() && !http.getApiKey()?.trim())
131
132
  problem = 'TIER0_API_KEY is not set';
132
133
  }
133
134
  catch (error) {
@@ -135,14 +136,12 @@ function createDataTransport(config) {
135
136
  }
136
137
  if (problem) {
137
138
  throw new error_js_1.DataError({
138
- message: `${problem}. The platform injects TIER0_API_HOST and TIER0_API_KEY in Preview and deployments; for local development set them before starting the App.`,
139
+ message: `${problem}. Check the runtime configuration and your access with the workspace administrator. In a Tier0 Preview or deployment the platform sets TIER0_API_HOST and the App's key TIER0_API_KEY in the App's process; for local development, configure the API host and an authorized key before starting the App.`,
139
140
  status: 503,
140
141
  code: 'DATA_NOT_CONFIGURED',
141
142
  });
142
143
  }
143
144
  }
144
- // The SDK binds a data subject to one client; App-level calls use the shared one without it.
145
- const coreFor = (dataSubject) => dataSubject ? new client_js_2.UnsV2ClientCore(resolve, { ...transport, unsV2AppDataSubject: dataSubject }) : app;
146
145
  async function call(operation, request, options = {}) {
147
146
  assertConfigured();
148
147
  const key = generated_js_1.UNS_V2_OPERATIONS[operation].idempotencyKey
@@ -176,10 +175,7 @@ function createDataTransport(config) {
176
175
  const response = await gate.run(() => {
177
176
  // Each attempt gets the time left of the call as its transport deadline.
178
177
  const remaining = Math.max(1, deadline - Date.now());
179
- const core = new client_js_2.UnsV2ClientCore(resolve, {
180
- transportTimeoutMs: remaining,
181
- ...(options.dataSubject ? { unsV2AppDataSubject: options.dataSubject } : {}),
182
- });
178
+ const core = new client_js_2.UnsV2ClientCore(resolve, { transportTimeoutMs: remaining });
183
179
  // In flight, only the business request's abort cancels; the transport deadline covers the time.
184
180
  return core.call(operation, body, { signal: options.signal });
185
181
  }, stop.signal);
@@ -205,7 +201,7 @@ function createDataTransport(config) {
205
201
  async function* openStream(request, options) {
206
202
  assertConfigured();
207
203
  try {
208
- yield* coreFor(options.dataSubject).subscribeRecords(request, options);
204
+ yield* app.subscribeRecords(request, options);
209
205
  }
210
206
  catch (error) {
211
207
  throw error instanceof client_js_2.UnsV2Error ? (0, error_js_1.toDataError)(error) : error;
@@ -1 +1 @@
1
- {"version":3,"file":"call.js","sourceRoot":"","sources":["../../../src/data/call.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * One UNS call of the data layer. The SDK's UNS client resolves host and key,\n * sends the request and checks the envelope; this adds the App runtime policy\n * around it and turns every failure into a `DataError`:\n *\n * - binds the employee data subject and the abort signal of the current call;\n * - gives every write that takes an idempotency key a fresh UUID unless the\n * caller set one, and keeps it for the retries of that call;\n * - sends at most MAX_CONCURRENT_CALLS requests per process at a time; the\n * rest wait in line;\n * - resends a failed request (same body, same key) at most MAX_RETRIES times,\n * only when its `retry.safe` says so, after `retry.afterMs` or a jittered\n * exponential backoff. UNS sets `retry.safe` (429 overload, 503 temporary\n * failure, a rolled-back write …); for failures without a UNS answer the\n * client sets it for reads only (timeout, network, ingress 502/503/504), so\n * a write whose outcome is unknown is never resent here;\n * - bounds the whole call, queueing, attempts and waits included, by one\n * deadline from its start. A call that runs out of time or is aborted\n * while it waits in line leaves the queue and is never sent\n * (`DATA_OVERLOADED` / `DATA_ABORTED`, `execution: notStarted`).\n *\n * `openStream` opens one `records:subscribe` event stream for `data.subscribe`,\n * which owns reconnects.\n */\nimport { randomUUID } from 'node:crypto';\nimport { HttpClient, type ClientConfig } from '../openapi/client.js';\nimport {\n UnsV2ClientCore,\n UnsV2Error,\n type UnsV2RecordSubscribeRequest,\n type UnsV2SubscriptionEvent,\n} from '../uns-v2/client.js';\nimport { UNS_V2_OPERATIONS, type UnsV2OperationName, type UnsV2Request } from '../uns-v2/generated.js';\nimport { DataError, toDataError } from './error.js';\n\n/** Whole call, from its start. The gateway gives UNS at most 20 s, so a data call ends within 25 s. */\nexport const DEFAULT_DATA_TIMEOUT_MS = 25_000;\n/** Data requests in flight per process, across every data client. */\nexport const MAX_CONCURRENT_CALLS = 6;\n/** Resends of one call after its first attempt. */\nexport const MAX_RETRIES = 2;\n/** A retry waits at most this long; a longer `retry.afterMs` surfaces the error instead. */\nexport const MAX_RETRY_WAIT_MS = 5_000;\nconst BACKOFF_BASE_MS = 250;\n\nexport interface CallOptions {\n /** Employee assertion forwarded from the current business request. */\n dataSubject?: string;\n /** Abort of the current business request: a queued call leaves the queue, an in-flight one is cancelled. */\n signal?: AbortSignal;\n}\n\n/** Sends one operation and resolves with the envelope's `data`. */\nexport type DataCall = <T>(operation: UnsV2OperationName, request: Record<string, unknown>, options?: CallOptions) => Promise<T>;\n\n/**\n * Opens one `records:subscribe` stream (outside the concurrency gate: it is\n * long-lived and holds no UNS connection while it waits). Failures are DataErrors.\n */\nexport type DataOpenStream = (\n request: UnsV2RecordSubscribeRequest,\n options: CallOptions & { lastEventId?: string; signal: AbortSignal },\n) => AsyncGenerator<UnsV2SubscriptionEvent>;\n\n/** Why a waiter left the queue without a slot. */\nclass Abandoned extends Error {}\n\n/** FIFO counting semaphore whose waiters can leave the line. */\nclass Gate {\n private active = 0;\n private readonly waiting: { grant: () => void }[] = [];\n\n constructor(private readonly limit: number) {}\n\n /** Runs `fn` with a slot; rejects with Abandoned if `signal` aborts while still waiting. */\n async run<T>(fn: () => Promise<T>, signal: AbortSignal): Promise<T> {\n if (this.active < this.limit) {\n this.active += 1;\n } else {\n await new Promise<void>((resolve, reject) => {\n const waiter = {\n grant: () => {\n signal.removeEventListener('abort', leave);\n resolve();\n },\n };\n const leave = () => {\n const index = this.waiting.indexOf(waiter);\n if (index >= 0) this.waiting.splice(index, 1);\n reject(new Abandoned());\n };\n if (signal.aborted) return leave();\n signal.addEventListener('abort', leave, { once: true });\n this.waiting.push(waiter);\n });\n }\n try {\n return await fn();\n } finally {\n // Hand the slot straight to the next waiter, so the count never dips below the queue.\n const next = this.waiting.shift();\n if (next) next.grant();\n else this.active -= 1;\n }\n }\n}\n\n// One gate per process, shared across data clients and dev-server module reloads.\nconst GATE_KEY = Symbol.for('tier0.sdk-v2.data.call-gate/2');\nconst globalGate = globalThis as typeof globalThis & { [GATE_KEY]?: Gate };\nconst gate = (globalGate[GATE_KEY] ??= new Gate(MAX_CONCURRENT_CALLS));\n\n/** Wait before resend `attempt` (1-based), or undefined when the error must surface. */\nexport function retryDelay(error: UnsV2Error, attempt: number): number | undefined {\n if (!error.retry.safe || attempt > MAX_RETRIES) return undefined;\n if (error.retry.afterMs !== undefined) return error.retry.afterMs <= MAX_RETRY_WAIT_MS ? error.retry.afterMs : undefined;\n const ceiling = Math.min(MAX_RETRY_WAIT_MS, BACKOFF_BASE_MS * 2 ** (attempt - 1));\n return ceiling / 2 + Math.random() * (ceiling / 2);\n}\n\n/** Resolves after `ms`, or early (false) when `signal` aborts. */\nfunction pause(ms: number, signal: AbortSignal): Promise<boolean> {\n return new Promise((resolve) => {\n if (signal.aborted) return resolve(false);\n const done = () => {\n clearTimeout(timer);\n signal.removeEventListener('abort', done);\n resolve(!signal.aborted);\n };\n const timer = setTimeout(done, ms);\n signal.addEventListener('abort', done, { once: true });\n });\n}\n\nexport function createDataTransport(config: ClientConfig): { call: DataCall; openStream: DataOpenStream } {\n const http = new HttpClient(config);\n const resolve = () => http;\n const timeoutMs = config.transportTimeoutMs ?? DEFAULT_DATA_TIMEOUT_MS;\n const transport = { transportTimeoutMs: timeoutMs };\n const app = new UnsV2ClientCore(resolve, transport);\n\n function assertConfigured() {\n let problem: string | undefined;\n try {\n http.getBaseURL();\n if (!http.getApiKey()?.trim()) problem = 'TIER0_API_KEY is not set';\n } catch (error) {\n problem = error instanceof Error ? error.message : String(error);\n }\n if (problem) {\n throw new DataError({\n message: `${problem}. The platform injects TIER0_API_HOST and TIER0_API_KEY in Preview and deployments; for local development set them before starting the App.`,\n status: 503,\n code: 'DATA_NOT_CONFIGURED',\n });\n }\n }\n\n // The SDK binds a data subject to one client; App-level calls use the shared one without it.\n const coreFor = (dataSubject: string | undefined) =>\n dataSubject ? new UnsV2ClientCore(resolve, { ...transport, unsV2AppDataSubject: dataSubject }) : app;\n\n async function call<T>(operation: UnsV2OperationName, request: Record<string, unknown>, options: CallOptions = {}): Promise<T> {\n assertConfigured();\n const key = UNS_V2_OPERATIONS[operation].idempotencyKey\n ? (typeof request.idempotencyKey === 'string' ? request.idempotencyKey : randomUUID())\n : undefined;\n const body = key === undefined || request.idempotencyKey !== undefined ? request : { ...request, idempotencyKey: key };\n const deadline = Date.now() + timeoutMs;\n // Aborts when the call runs out of time or its business request is aborted.\n const stop = new AbortController();\n const expire = setTimeout(() => stop.abort(), timeoutMs);\n const relay = () => stop.abort();\n options.signal?.addEventListener('abort', relay, { once: true });\n if (options.signal?.aborted) stop.abort();\n const notSent = (attempts: number) => new DataError({\n ...(options.signal?.aborted\n ? { message: `The data call ${operation} was aborted before it was sent.`, status: 499, code: 'DATA_ABORTED' }\n : {\n message: `The data call ${operation} waited ${timeoutMs} ms for one of the ${MAX_CONCURRENT_CALLS} request slots of this process and was not sent.`,\n status: 503,\n code: 'DATA_OVERLOADED',\n }),\n execution: 'notStarted',\n retry: { safe: !options.signal?.aborted },\n attempts,\n idempotencyKey: key,\n });\n try {\n for (let attempt = 1; ; attempt += 1) {\n try {\n const response = await gate.run(() => {\n // Each attempt gets the time left of the call as its transport deadline.\n const remaining = Math.max(1, deadline - Date.now());\n const core = new UnsV2ClientCore(resolve, {\n transportTimeoutMs: remaining,\n ...(options.dataSubject ? { unsV2AppDataSubject: options.dataSubject } : {}),\n });\n // In flight, only the business request's abort cancels; the transport deadline covers the time.\n return core.call(operation, body as UnsV2Request<typeof operation>, { signal: options.signal });\n }, stop.signal);\n return response.data as T;\n } catch (error) {\n if (error instanceof Abandoned) throw notSent(attempt - 1);\n if (!(error instanceof UnsV2Error)) throw error;\n const delay = retryDelay(error, attempt);\n if (delay === undefined || Date.now() + delay >= deadline || !(await pause(delay, stop.signal))) {\n throw toDataError(error, attempt, key);\n }\n }\n }\n } finally {\n clearTimeout(expire);\n options.signal?.removeEventListener('abort', relay);\n }\n }\n\n async function* openStream(\n request: UnsV2RecordSubscribeRequest,\n options: CallOptions & { lastEventId?: string; signal: AbortSignal },\n ): AsyncGenerator<UnsV2SubscriptionEvent> {\n assertConfigured();\n try {\n yield* coreFor(options.dataSubject).subscribeRecords(request, options);\n } catch (error) {\n throw error instanceof UnsV2Error ? toDataError(error) : error;\n }\n }\n\n return { call, openStream };\n}\n"]}
1
+ {"version":3,"file":"call.js","sourceRoot":"","sources":["../../../src/data/call.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * One UNS call of the data layer. The SDK's UNS client resolves host and key,\n * sends the request and checks the envelope; this adds the App runtime policy\n * around it and turns every failure into a `DataError`:\n *\n * - binds the abort signal of the current call;\n * - gives every write that takes an idempotency key a fresh UUID unless the\n * caller set one, and keeps it for the retries of that call;\n * - sends at most MAX_CONCURRENT_CALLS requests per process at a time; the\n * rest wait in line;\n * - resends a failed request (same body, same key) at most MAX_RETRIES times,\n * only when its `retry.safe` says so, after `retry.afterMs` or a jittered\n * exponential backoff. UNS sets `retry.safe` (429 overload, 503 temporary\n * failure, a rolled-back write …); for failures without a UNS answer the\n * client sets it for reads only (timeout, network, ingress 502/503/504), so\n * a write whose outcome is unknown is never resent here;\n * - bounds the whole call, queueing, attempts and waits included, by one\n * deadline from its start. A call that runs out of time or is aborted\n * while it waits in line leaves the queue and is never sent\n * (`DATA_OVERLOADED` / `DATA_ABORTED`, `execution: notStarted`).\n *\n * `openStream` opens one `records:subscribe` event stream for `data.subscribe`,\n * which owns reconnects.\n */\nimport { randomUUID } from 'node:crypto';\nimport { HttpClient, snapshotClientConfig, type ClientConfig } from '../openapi/client.js';\nimport {\n UnsV2ClientCore,\n UnsV2Error,\n type UnsV2RecordSubscribeRequest,\n type UnsV2SubscriptionEvent,\n} from '../uns-v2/client.js';\nimport { UNS_V2_OPERATIONS, type UnsV2OperationName, type UnsV2Request } from '../uns-v2/generated.js';\nimport { DataError, toDataError } from './error.js';\n\n/** Whole call, from its start. The gateway gives UNS at most 20 s, so a data call ends within 25 s. */\nexport const DEFAULT_DATA_TIMEOUT_MS = 25_000;\n/** Data requests in flight per process, across every data client. */\nexport const MAX_CONCURRENT_CALLS = 6;\n/** Resends of one call after its first attempt. */\nexport const MAX_RETRIES = 2;\n/** A retry waits at most this long; a longer `retry.afterMs` surfaces the error instead. */\nexport const MAX_RETRY_WAIT_MS = 5_000;\nconst BACKOFF_BASE_MS = 250;\n\nexport interface CallOptions {\n /** Abort of the current business request: a queued call leaves the queue, an in-flight one is cancelled. */\n signal?: AbortSignal;\n}\n\n/** Sends one operation and resolves with the envelope's `data`. */\nexport type DataCall = <T>(operation: UnsV2OperationName, request: Record<string, unknown>, options?: CallOptions) => Promise<T>;\n\n/**\n * Opens one `records:subscribe` stream (outside the concurrency gate: it is\n * long-lived and holds no UNS connection while it waits). Failures are DataErrors.\n */\nexport type DataOpenStream = (\n request: UnsV2RecordSubscribeRequest,\n options: { lastEventId?: string; signal: AbortSignal },\n) => AsyncGenerator<UnsV2SubscriptionEvent>;\n\n/** Why a waiter left the queue without a slot. */\nclass Abandoned extends Error {}\n\n/** FIFO counting semaphore whose waiters can leave the line. */\nclass Gate {\n private active = 0;\n private readonly waiting: { grant: () => void }[] = [];\n\n constructor(private readonly limit: number) {}\n\n /** Runs `fn` with a slot; rejects with Abandoned if `signal` aborts while still waiting. */\n async run<T>(fn: () => Promise<T>, signal: AbortSignal): Promise<T> {\n if (this.active < this.limit) {\n this.active += 1;\n } else {\n await new Promise<void>((resolve, reject) => {\n const waiter = {\n grant: () => {\n signal.removeEventListener('abort', leave);\n resolve();\n },\n };\n const leave = () => {\n const index = this.waiting.indexOf(waiter);\n if (index >= 0) this.waiting.splice(index, 1);\n reject(new Abandoned());\n };\n if (signal.aborted) return leave();\n signal.addEventListener('abort', leave, { once: true });\n this.waiting.push(waiter);\n });\n }\n try {\n return await fn();\n } finally {\n // Hand the slot straight to the next waiter, so the count never dips below the queue.\n const next = this.waiting.shift();\n if (next) next.grant();\n else this.active -= 1;\n }\n }\n}\n\n// One gate per process, shared across data clients and dev-server module reloads.\nconst GATE_KEY = Symbol.for('tier0.sdk-v2.data.call-gate/2');\nconst globalGate = globalThis as typeof globalThis & { [GATE_KEY]?: Gate };\nconst gate = (globalGate[GATE_KEY] ??= new Gate(MAX_CONCURRENT_CALLS));\n\n/** Wait before resend `attempt` (1-based), or undefined when the error must surface. */\nexport function retryDelay(error: UnsV2Error, attempt: number): number | undefined {\n if (!error.retry.safe || attempt > MAX_RETRIES) return undefined;\n if (error.retry.afterMs !== undefined) return error.retry.afterMs <= MAX_RETRY_WAIT_MS ? error.retry.afterMs : undefined;\n const ceiling = Math.min(MAX_RETRY_WAIT_MS, BACKOFF_BASE_MS * 2 ** (attempt - 1));\n return ceiling / 2 + Math.random() * (ceiling / 2);\n}\n\n/** Resolves after `ms`, or early (false) when `signal` aborts. */\nfunction pause(ms: number, signal: AbortSignal): Promise<boolean> {\n return new Promise((resolve) => {\n if (signal.aborted) return resolve(false);\n const done = () => {\n clearTimeout(timer);\n signal.removeEventListener('abort', done);\n resolve(!signal.aborted);\n };\n const timer = setTimeout(done, ms);\n signal.addEventListener('abort', done, { once: true });\n });\n}\n\nexport function createDataTransport(config: ClientConfig): { call: DataCall; openStream: DataOpenStream } {\n const snapshot = snapshotClientConfig(config, ['transportTimeoutMs']);\n const http = new HttpClient(snapshot);\n const resolve = () => http;\n const timeoutMs = snapshot.transportTimeoutMs ?? DEFAULT_DATA_TIMEOUT_MS;\n const transport = { transportTimeoutMs: timeoutMs };\n const app = new UnsV2ClientCore(resolve, transport);\n\n function assertConfigured() {\n let problem: string | undefined;\n try {\n http.getBaseURL();\n if (!http.usesAppCredential() && !http.getApiKey()?.trim()) problem = 'TIER0_API_KEY is not set';\n } catch (error) {\n problem = error instanceof Error ? error.message : String(error);\n }\n if (problem) {\n throw new DataError({\n message: `${problem}. Check the runtime configuration and your access with the workspace administrator. In a Tier0 Preview or deployment the platform sets TIER0_API_HOST and the App's key TIER0_API_KEY in the App's process; for local development, configure the API host and an authorized key before starting the App.`,\n status: 503,\n code: 'DATA_NOT_CONFIGURED',\n });\n }\n }\n\n async function call<T>(operation: UnsV2OperationName, request: Record<string, unknown>, options: CallOptions = {}): Promise<T> {\n assertConfigured();\n const key = UNS_V2_OPERATIONS[operation].idempotencyKey\n ? (typeof request.idempotencyKey === 'string' ? request.idempotencyKey : randomUUID())\n : undefined;\n const body = key === undefined || request.idempotencyKey !== undefined ? request : { ...request, idempotencyKey: key };\n const deadline = Date.now() + timeoutMs;\n // Aborts when the call runs out of time or its business request is aborted.\n const stop = new AbortController();\n const expire = setTimeout(() => stop.abort(), timeoutMs);\n const relay = () => stop.abort();\n options.signal?.addEventListener('abort', relay, { once: true });\n if (options.signal?.aborted) stop.abort();\n const notSent = (attempts: number) => new DataError({\n ...(options.signal?.aborted\n ? { message: `The data call ${operation} was aborted before it was sent.`, status: 499, code: 'DATA_ABORTED' }\n : {\n message: `The data call ${operation} waited ${timeoutMs} ms for one of the ${MAX_CONCURRENT_CALLS} request slots of this process and was not sent.`,\n status: 503,\n code: 'DATA_OVERLOADED',\n }),\n execution: 'notStarted',\n retry: { safe: !options.signal?.aborted },\n attempts,\n idempotencyKey: key,\n });\n try {\n for (let attempt = 1; ; attempt += 1) {\n try {\n const response = await gate.run(() => {\n // Each attempt gets the time left of the call as its transport deadline.\n const remaining = Math.max(1, deadline - Date.now());\n const core = new UnsV2ClientCore(resolve, { transportTimeoutMs: remaining });\n // In flight, only the business request's abort cancels; the transport deadline covers the time.\n return core.call(operation, body as UnsV2Request<typeof operation>, { signal: options.signal });\n }, stop.signal);\n return response.data as T;\n } catch (error) {\n if (error instanceof Abandoned) throw notSent(attempt - 1);\n if (!(error instanceof UnsV2Error)) throw error;\n const delay = retryDelay(error, attempt);\n if (delay === undefined || Date.now() + delay >= deadline || !(await pause(delay, stop.signal))) {\n throw toDataError(error, attempt, key);\n }\n }\n }\n } finally {\n clearTimeout(expire);\n options.signal?.removeEventListener('abort', relay);\n }\n }\n\n async function* openStream(\n request: UnsV2RecordSubscribeRequest,\n options: { lastEventId?: string; signal: AbortSignal },\n ): AsyncGenerator<UnsV2SubscriptionEvent> {\n assertConfigured();\n try {\n yield* app.subscribeRecords(request, options);\n } catch (error) {\n throw error instanceof UnsV2Error ? toDataError(error) : error;\n }\n }\n\n return { call, openStream };\n}\n"]}
@@ -4,7 +4,7 @@
4
4
  * collection declarations; tests build their own with a mock `fetch`.
5
5
  */
6
6
  import type { z } from 'zod';
7
- import type { ClientConfig } from '../openapi/client.js';
7
+ import { type ClientConfig } from '../openapi/client.js';
8
8
  import { type DataEnvironment, type EnsureState, type Logger } from './bootstrap.js';
9
9
  import { Collection, type BatchQuery, type WithMeta } from './collection.js';
10
10
  import { type CollectionDefinition, type CollectionReference, type CollectionSchema, type CollectionTarget } from './define.js';
@@ -82,8 +82,11 @@ export type SettledBatchResults<Q extends BatchQueries> = {
82
82
  };
83
83
  /** Contract limit of `records:queryBatch`. */
84
84
  export declare const MAX_BATCH_QUERIES = 20;
85
- /** Credentials as for `createClient`; `transportTimeoutMs` (per attempt) defaults to 25 s here, see DEFAULT_DATA_TIMEOUT_MS. */
86
- export interface DataClientConfig extends ClientConfig {
85
+ /** Data client state is bound to one static host and credential for its lifetime. */
86
+ export interface DataClientConfig extends Omit<ClientConfig, 'getApiKey' | 'apiKeyProvider'> {
87
+ /** Dynamic credentials are unsupported while bootstrap and subscriptions share client state. */
88
+ getApiKey?: never;
89
+ apiKeyProvider?: never;
87
90
  collections?: readonly CollectionDefinition[];
88
91
  /** Defaults to "deployed" when NODE_ENV is production, otherwise "preview". */
89
92
  environment?: DataEnvironment;
@@ -112,10 +115,8 @@ export interface DataClient {
112
115
  /**
113
116
  * Committed record changes of declared collections (all by default), as
114
117
  * one async iterable that reconnects and resumes by itself; see
115
- * `SubscribeOptions`. Events carry identities only; changes in collections
116
- * with employee data rules arrive as collection-level notices unless
117
- * `restricted: "record"` is asked for. Open it inside a request to watch as
118
- * that employee, or in `runAsApp` for one App-wide stream a server fans out.
118
+ * `SubscribeOptions`. Events carry identities only. Open one per server
119
+ * process and fan it out to browsers with `createChangeRelay`.
119
120
  */
120
121
  subscribe(options?: SubscribeOptions): AsyncIterable<SubscriptionEvent>;
121
122
  /**
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MAX_BATCH_QUERIES = void 0;
4
4
  exports.createDataClient = createDataClient;
5
+ const client_js_1 = require("../openapi/client.js");
5
6
  const runtime_env_js_1 = require("../runtime-env.js");
6
7
  const bootstrap_js_1 = require("./bootstrap.js");
7
8
  const call_js_1 = require("./call.js");
@@ -9,7 +10,7 @@ const collection_js_1 = require("./collection.js");
9
10
  const context_js_1 = require("./context.js");
10
11
  const define_js_1 = require("./define.js");
11
12
  const subscribe_js_1 = require("./subscribe.js");
12
- const client_js_1 = require("../uns-v2/client.js");
13
+ const client_js_2 = require("../uns-v2/client.js");
13
14
  const error_js_1 = require("./error.js");
14
15
  const schema_js_1 = require("./schema.js");
15
16
  const sort_js_1 = require("./sort.js");
@@ -17,9 +18,22 @@ const sort_js_1 = require("./sort.js");
17
18
  exports.MAX_BATCH_QUERIES = 20;
18
19
  const QUERY_NAME = /^[A-Za-z0-9_.-]{1,64}$/;
19
20
  function createDataClient(config) {
20
- const { call, openStream } = (0, call_js_1.createDataTransport)(config);
21
- const environment = config.environment ?? ((0, runtime_env_js_1.getEnvVar)('NODE_ENV') === 'production' ? 'deployed' : 'preview');
22
- const declared = [...(config.collections ?? [])];
21
+ const snapshot = (0, client_js_1.snapshotClientConfig)(config, ['environment', 'collections', 'logger']);
22
+ if (Object.hasOwn(snapshot, 'apiKeyProvider')) {
23
+ throw new TypeError('Tier0 SDK: apiKeyProvider is not supported by createDataClient.');
24
+ }
25
+ if (Object.hasOwn(snapshot, 'getApiKey')) {
26
+ throw new TypeError('Tier0 SDK: getApiKey is not supported by createDataClient.');
27
+ }
28
+ // Never let bootstrap state, retries or SSE reconnect under a later identity or host.
29
+ const fixed = {
30
+ ...snapshot,
31
+ apiKey: Object.hasOwn(snapshot, 'apiKey') ? snapshot.apiKey : (0, runtime_env_js_1.getEnvVar)('TIER0_API_KEY'),
32
+ apiHost: snapshot.apiHost ?? snapshot.getApiHost?.() ?? (0, runtime_env_js_1.getEnvVar)('TIER0_API_HOST') ?? '',
33
+ };
34
+ const { call, openStream } = (0, call_js_1.createDataTransport)(fixed);
35
+ const environment = snapshot.environment ?? ((0, runtime_env_js_1.getEnvVar)('NODE_ENV') === 'production' ? 'deployed' : 'preview');
36
+ const declared = [...(snapshot.collections ?? [])];
23
37
  if (declared.length > define_js_1.MAX_COLLECTIONS) {
24
38
  throw new Error(`An App declares at most ${define_js_1.MAX_COLLECTIONS} collections; got ${declared.length}.`);
25
39
  }
@@ -30,7 +44,8 @@ function createDataClient(config) {
30
44
  throw new Error(`Collection alias "${definition.alias}" is declared twice (aliases are case-insensitive).`);
31
45
  seen.add(key);
32
46
  }
33
- const bootstrap = (0, bootstrap_js_1.createBootstrap)({ call, collections: declared, environment, logger: config.logger ?? console });
47
+ // Ensure and seed writes pass no signal: they are shared by every request, and the one that triggers them must not cancel them.
48
+ const bootstrap = (0, bootstrap_js_1.createBootstrap)({ call, collections: declared, environment, logger: snapshot.logger ?? console });
34
49
  const runtime = {
35
50
  call,
36
51
  resolve: async (target) => {
@@ -38,7 +53,6 @@ function createDataClient(config) {
38
53
  return 'collectionId' in definition ? definition.collectionId : bootstrap.resolve(definition);
39
54
  },
40
55
  recover: (fn, options) => options.collections.every(target => 'collectionId' in target) ? fn() : bootstrap.recover(fn, options),
41
- subject: context_js_1.currentDataSubject,
42
56
  signal: context_js_1.currentSignal,
43
57
  };
44
58
  const handles = new WeakMap();
@@ -115,7 +129,7 @@ function createDataClient(config) {
115
129
  mode: 'sync',
116
130
  ...(options.dryRun ? { dryRun: true } : {}),
117
131
  ...(options.idempotencyKey ? { idempotencyKey: options.idempotencyKey } : {}),
118
- }, { dataSubject: (0, context_js_1.currentDataSubject)(), signal: (0, context_js_1.currentSignal)() });
132
+ }, { signal: (0, context_js_1.currentSignal)() });
119
133
  }
120
134
  async function queryBatch(queries, options = {}) {
121
135
  const names = Object.keys(queries);
@@ -133,7 +147,7 @@ function createDataClient(config) {
133
147
  collectionId: await runtime.resolve(queries[name].collection),
134
148
  ...(await queries[name].prepare()),
135
149
  })));
136
- return call('recordQueryBatch', { queries: items }, { dataSubject: (0, context_js_1.currentDataSubject)(), signal: (0, context_js_1.currentSignal)() });
150
+ return call('recordQueryBatch', { queries: items }, { signal: (0, context_js_1.currentSignal)() });
137
151
  }, { collections });
138
152
  const settled = Object.fromEntries(names.map((name) => {
139
153
  const result = results[name];
@@ -159,7 +173,6 @@ function createDataClient(config) {
159
173
  resolve: runtime.resolve,
160
174
  lookup,
161
175
  declared,
162
- subject: context_js_1.currentDataSubject,
163
176
  });
164
177
  return {
165
178
  collection: collection,
@@ -173,7 +186,7 @@ function createDataClient(config) {
173
186
  const ITEM_STATUS = { FORBIDDEN: 403, NOT_FOUND: 404 };
174
187
  /** A queryBatch item's error as a DataError; its `upstreamStatus` is the status its code stands for. */
175
188
  function itemError(name, value) {
176
- const fault = (0, client_js_1.parseUnsV2Fault)(value);
189
+ const fault = (0, client_js_2.parseUnsV2Fault)(value);
177
190
  if (!fault) {
178
191
  return new error_js_1.DataError({
179
192
  message: `UNS answered query "${name}" of recordQueryBatch with an invalid result.`,
@@ -184,7 +197,7 @@ function itemError(name, value) {
184
197
  attempts: 1,
185
198
  });
186
199
  }
187
- const error = new client_js_1.UnsV2Error(fault.reason ?? fault.code, {
200
+ const error = new client_js_2.UnsV2Error(fault.reason ?? fault.code, {
188
201
  ...fault,
189
202
  // The items are reads: never an unknown outcome.
190
203
  execution: fault.execution === 'unknown' ? 'rolledBack' : fault.execution,
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/data/client.ts"],"names":[],"mappings":";;;AAoIA,4CAkKC;AA/RD,sDAA8C;AAC9C,iDAAsG;AACtG,uCAAgD;AAChD,mDAAuH;AACvH,6CAAiE;AACjE,2CAAiJ;AACjJ,iDAAgG;AAChG,mDAAkE;AAClE,yCAAoD;AACpD,2CAA+D;AAC/D,uCAAgE;AA8DhE,8CAA8C;AACjC,QAAA,iBAAiB,GAAG,EAAE,CAAC;AACpC,MAAM,UAAU,GAAG,wBAAwB,CAAC;AAmD5C,SAAgB,gBAAgB,CAAC,MAAwB;IACvD,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,IAAA,6BAAmB,EAAC,MAAM,CAAC,CAAC;IACzD,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,IAAI,CAAC,IAAA,0BAAS,EAAC,UAAU,CAAC,KAAK,YAAY,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAC5G,MAAM,QAAQ,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,CAAC;IACjD,IAAI,QAAQ,CAAC,MAAM,GAAG,2BAAe,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,2BAA2B,2BAAe,qBAAqB,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;IACrG,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,UAAU,IAAI,QAAQ,EAAE,CAAC;QAClC,MAAM,GAAG,GAAG,UAAU,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;QAC3C,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,UAAU,CAAC,KAAK,qDAAqD,CAAC,CAAC;QAC/H,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAChB,CAAC;IAED,MAAM,SAAS,GAAG,IAAA,8BAAe,EAAC,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,OAAO,EAAE,CAAC,CAAC;IAClH,MAAM,OAAO,GAAG;QACd,IAAI;QACJ,OAAO,EAAE,KAAK,EAAE,MAAiC,EAAE,EAAE;YACnD,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;YAClC,OAAO,cAAc,IAAI,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAChG,CAAC;QACD,OAAO,EAAE,CAAI,EAAoB,EAAE,OAAsE,EAAE,EAAE,CAC3G,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,cAAc,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC;QACvG,OAAO,EAAE,+BAAkB;QAC3B,MAAM,EAAE,0BAAa;KACtB,CAAC;IACF,MAAM,OAAO,GAAG,IAAI,OAAO,EAAwC,CAAC;IAEpE,SAAS,MAAM,CAAC,MAAiC;QAC/C,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC/B,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;YACrG,IAAI,CAAC,KAAK;gBAAE,MAAM,IAAI,KAAK,CAAC,eAAe,MAAM,sDAAsD,CAAC,CAAC;YACzG,OAAO,KAAK,CAAC;QACf,CAAC;QACD,IAAI,cAAc,IAAI,MAAM,EAAE,CAAC;YAC7B,IAAI,OAAO,MAAM,CAAC,YAAY,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,YAAY,IAAI,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,MAAM,CAAC,YAAY,EAAE,CAAC;gBAC1H,MAAM,IAAI,SAAS,CAAC,gGAAgG,CAAC,CAAC;YACxH,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,eAAe,MAAM,CAAC,KAAK,gFAAgF,CAAC,CAAC;QAC/H,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,SAAS,UAAU,CAAC,MAAiC;QACnD,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;QAClC,IAAI,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACrC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,GAAG,IAAI,0BAAU,CAAS,UAAU,EAAE,OAAO,CAAC,CAAC;YACrD,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QAClC,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,UAAU,QAAQ,CACrB,KAA8B,EAC9B,UAAyD,EAAE;QAE3D,IAAA,iCAAiB,EAAC,eAAe,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QACjD,2FAA2F;QAC3F,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,EAAE,WAAW,EAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC;QACzI,MAAM,OAAO,GAAG,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;YACrE,GAAG,IAAI;YACP,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAA,qBAAK,EAA0B,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC5E,CAAC,CAAC,CAAC;QACJ,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC;QAC5D,IAAI,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC/B,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACpD,0FAA0F;YAC1F,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,KAAK,oBAAoB,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC;YAChI,MAAM,IAAI,oBAAS,CAAC;gBAClB,OAAO,EAAE,eAAe,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,mBAAmB,EAAE;gBAChJ,MAAM,EAAE,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;gBAC3C,IAAI,EAAE,oBAAoB;gBAC1B,SAAS;gBACT,QAAQ,EAAE,CAAC;gBACX,OAAO,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE;aAC5C,CAAC,CAAC;QACL,CAAC;QACD,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;IAC5C,CAAC;IAED,KAAK,UAAU,eAAe,CAAC,KAA8B,EAAE,OAAsD;QACnH,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,GAAG,CAC7B,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE;YAC/D,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;YAClC,MAAM,IAAI,GAA4B,EAAE,GAAG,IAAI,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;YACnG,IAAI,IAAI;gBAAE,IAAI,CAAC,IAAI,GAAG,IAAA,qBAAW,EAAC,IAAI,CAAC,CAAC;YACxC,IAAI,KAAK;gBAAE,IAAI,CAAC,KAAK,GAAG,EAAE,GAAG,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAA,qBAAW,EAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;YAC/F,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACd,iGAAiG;gBACjG,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC1I,IAAI,CAAC,IAAI,GAAG,IAAA,4BAAgB,EAAC,UAAU,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YAC7D,CAAC;YACD,IAAI,IAAI,CAAC,MAAM;gBAAE,IAAI,CAAC,MAAM,GAAG,IAAA,0BAAc,EAAC,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;YACvE,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CACH,CAAC;QACF,OAAO,IAAI,CACT,0BAA0B,EAC1B;YACE,KAAK;YACL,IAAI,EAAE,MAAM;YACZ,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3C,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC9E,EACD,EAAE,WAAW,EAAE,IAAA,+BAAkB,GAAE,EAAE,MAAM,EAAE,IAAA,0BAAa,GAAE,EAAE,CAC/D,CAAC;IACJ,CAAC;IAED,KAAK,UAAU,UAAU,CAAyB,OAAU,EAAE,UAAgC,EAAE;QAC9F,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACnC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,yBAAiB,EAAE,CAAC;YACzD,MAAM,IAAI,SAAS,CAAC,2BAA2B,yBAAiB,iBAAiB,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;QACpG,CAAC;QACD,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACzD,IAAI,GAAG,KAAK,SAAS;YAAE,MAAM,IAAI,SAAS,CAAC,+BAA+B,GAAG,gBAAgB,UAAU,GAAG,CAAC,CAAC;QAC5G,MAAM,WAAW,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;QACxE,2FAA2F;QAC3F,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE;YACnD,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;gBACzD,EAAE,EAAE,IAAI;gBACR,YAAY,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC;gBAC7D,GAAG,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;aACnC,CAAC,CAAC,CAAC,CAAC;YACL,OAAO,IAAI,CACT,kBAAkB,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,WAAW,EAAE,IAAA,+BAAkB,GAAE,EAAE,MAAM,EAAE,IAAA,0BAAa,GAAE,EAAE,CAAC,CAAC;QAC5G,CAAC,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC;QACpB,MAAM,OAAO,GAAG,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;YACpD,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;YAC7B,IAAI,MAAM,EAAE,EAAE,KAAK,IAAI;gBAAE,OAAO,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC9F,OAAO,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;QACtE,CAAC,CAAC,CAAmF,CAAC;QACtF,IAAI,OAAO,CAAC,MAAM;YAAE,OAAO,OAAO,CAAC;QACnC,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC;QACvD,IAAI,MAAM,KAAK,SAAS;YAAE,MAAO,OAAO,CAAC,MAAM,CAA0B,CAAC,KAAK,CAAC;QAChF,OAAO,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAG,OAAO,CAAC,IAAI,CAAwB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACtG,CAAC;IAED,MAAM,SAAS,GAAG,IAAA,8BAAe,EAAC;QAChC,UAAU;QACV,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc,IAAI,MAAM,CAAC,CAAC;YACtE,CAAC,CAAC,SAAS,CAAC,MAAM,EAAE;YACpB,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,aAAa,EAAE,IAAI,GAAG,EAAkB,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;QAC7F,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,cAAc,IAAI,MAAM,CAAC;YACnF,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC;YACxB,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;QACnC,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,MAAM;QACN,QAAQ;QACR,OAAO,EAAE,+BAAkB;KAC5B,CAAC,CAAC;IAEH,OAAO;QACL,UAAU,EAAE,UAAsC;QAClD,QAAQ;QACR,UAAU,EAAE,UAAsC;QAClD,SAAS;QACT,MAAM,EAAE,SAAS,CAAC,MAAM;KACzB,CAAC;AACJ,CAAC;AAED,+EAA+E;AAC/E,MAAM,WAAW,GAA2B,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC;AAE/E,wGAAwG;AACxG,SAAS,SAAS,CAAC,IAAY,EAAE,KAAc;IAC7C,MAAM,KAAK,GAAG,IAAA,2BAAe,EAAC,KAAK,CAAC,CAAC;IACrC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,IAAI,oBAAS,CAAC;YACnB,OAAO,EAAE,uBAAuB,IAAI,+CAA+C;YACnF,MAAM,EAAE,GAAG;YACX,IAAI,EAAE,mBAAmB;YACzB,cAAc,EAAE,GAAG;YACnB,SAAS,EAAE,YAAY;YACvB,QAAQ,EAAE,CAAC;SACZ,CAAC,CAAC;IACL,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,sBAAU,CAAC,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,IAAI,EAAE;QACvD,GAAG,KAAK;QACR,iDAAiD;QACjD,SAAS,EAAE,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS;QACzE,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,IAAI;QAC9B,MAAM,EAAE,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG;QACtC,SAAS,EAAE,kBAAkB;QAC7B,IAAI,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,EAAE,EAAE;KACvE,CAAC,CAAC;IACH,OAAO,IAAA,sBAAW,EAAC,KAAK,CAAC,CAAC;AAC5B,CAAC","sourcesContent":["/**\n * Data client factory: collection handles, cross-collection transactions and\n * the shared bootstrap. An App builds one client per process from its\n * collection declarations; tests build their own with a mock `fetch`.\n */\nimport type { z } from 'zod';\nimport type { ClientConfig } from '../openapi/client.js';\nimport { getEnvVar } from '../runtime-env.js';\nimport { createBootstrap, type DataEnvironment, type EnsureState, type Logger } from './bootstrap.js';\nimport { createDataTransport } from './call.js';\nimport { assertAtomicBatch, Collection, toDoc, type BatchQuery, type UnsRecord, type WithMeta } from './collection.js';\nimport { currentDataSubject, currentSignal } from './context.js';\nimport { MAX_COLLECTIONS, type CollectionDefinition, type CollectionReference, type CollectionSchema, type CollectionTarget } from './define.js';\nimport { createSubscribe, type SubscribeOptions, type SubscriptionEvent } from './subscribe.js';\nimport { parseUnsV2Fault, UnsV2Error } from '../uns-v2/client.js';\nimport { DataError, toDataError } from './error.js';\nimport { validateStepData, validateUpdate } from './schema.js';\nimport { toSortPairs, type Filter, type Sort } from './sort.js';\n\nexport type TransactAction =\n | 'record.create'\n | 'record.check'\n | 'record.read'\n | 'record.update'\n | 'record.modify'\n | 'record.replace'\n | 'record.delete'\n | 'record.query';\n\n/** One `recordTransactionExecute` item; `collection` is a declaration, declared alias, or existing-ID reference. */\nexport interface TransactStep {\n opId: string;\n action: TransactAction;\n collection: CollectionTarget | string;\n id?: string | { ref: string };\n filter?: Filter;\n data?: Record<string, unknown>;\n update?: Record<string, unknown>;\n upsert?: boolean;\n expectedRevision?: number;\n dependsOn?: string[];\n bindings?: { path: string; ref: string; resultPath: string }[];\n selection?: 'exactOne' | 'first';\n sort?: Sort;\n returnDocument?: 'before' | 'after';\n exists?: boolean;\n operations?: Record<string, unknown>[];\n conditions?: Filter[];\n /** `record.query`: rows to bind from; `expectCount` asserts the match count before `limit`. */\n query?: { filter?: Filter; sort?: Sort; limit?: number; expectCount?: { min?: number; max?: number } };\n arrayFilters?: Record<string, unknown>[];\n}\n\nexport interface TransactResultItem {\n opId: string;\n action: string;\n id: string;\n status: string;\n collectionId?: string;\n revision?: number;\n /** Before/after snapshot when requested, as a flat document. */\n document?: WithMeta<Record<string, unknown>>;\n data?: unknown;\n query?: unknown;\n error?: unknown;\n}\n\nexport interface TransactResult {\n status: string;\n results: TransactResultItem[];\n}\n\n/** Named reads for `data.queryBatch`: 1–20 entries, names matching `[A-Za-z0-9_.-]{1,64}`. */\nexport type BatchQueries = Record<string, BatchQuery<unknown>>;\nexport type BatchResults<Q extends BatchQueries> = { [K in keyof Q]: Q[K] extends BatchQuery<infer R> ? R : never };\nexport type SettledBatchResults<Q extends BatchQueries> = {\n [K in keyof Q]: Q[K] extends BatchQuery<infer R> ? { ok: true; value: R } | { ok: false; error: DataError } : never;\n};\n\n/** Contract limit of `records:queryBatch`. */\nexport const MAX_BATCH_QUERIES = 20;\nconst QUERY_NAME = /^[A-Za-z0-9_.-]{1,64}$/;\n\n/** Credentials as for `createClient`; `transportTimeoutMs` (per attempt) defaults to 25 s here, see DEFAULT_DATA_TIMEOUT_MS. */\nexport interface DataClientConfig extends ClientConfig {\n collections?: readonly CollectionDefinition[];\n /** Defaults to \"deployed\" when NODE_ENV is production, otherwise \"preview\". */\n environment?: DataEnvironment;\n logger?: Logger;\n}\n\nexport interface DataClient {\n /** Typed handle for a declaration listed in `collections`. */\n collection<C extends CollectionDefinition>(definition: C): Collection<z.output<C['schema']>, z.input<C['schema']>>;\n /** Existing collection, with optional local write validation. Never ensured, seeded, or granted by the SDK. */\n collection<S extends CollectionSchema>(reference: CollectionReference<S> & { schema: S }): Collection<z.output<S>, z.input<S>>;\n collection<T extends object = Record<string, unknown>>(reference: CollectionReference): Collection<T>;\n /** Handle by alias, typed by the caller. */\n collection<T extends object = Record<string, unknown>>(alias: string): Collection<T>;\n /**\n * Atomic multi-record, multi-collection write (`recordTransactionExecute`, sync),\n * at most 200 steps. Steps can depend on each other (`dependsOn`) and bind\n * earlier results (`bindings`). This is not a Mongo session: everything is\n * sent at once.\n */\n transact(steps: readonly TransactStep[], options?: { dryRun?: boolean; idempotencyKey?: string }): Promise<TransactResult>;\n /**\n * Committed record changes of declared collections (all by default), as\n * one async iterable that reconnects and resumes by itself; see\n * `SubscribeOptions`. Events carry identities only; changes in collections\n * with employee data rules arrive as collection-level notices unless\n * `restricted: \"record\"` is asked for. Open it inside a request to watch as\n * that employee, or in `runAsApp` for one App-wide stream a server fans out.\n */\n subscribe(options?: SubscribeOptions): AsyncIterable<SubscriptionEvent>;\n /**\n * Up to 20 reads of declared collections in one request, answered from one\n * snapshot: what a page shows (a list page with its total, counters, a\n * lookup by ID) in one round trip. Build each read with\n * `collection.query.*`; results come back under the same names.\n *\n * A read UNS refuses on its own (invalid filter, no grant) rejects the\n * whole call with its DataError; with `{ settle: true }` every result is\n * `{ ok, value }` or `{ ok: false, error }` instead. A statement timeout or\n * a batch over 2000 rows / 8 MiB always fails the whole call.\n */\n queryBatch<Q extends BatchQueries>(queries: Q): Promise<BatchResults<Q>>;\n queryBatch<Q extends BatchQueries>(queries: Q, options: { settle: true }): Promise<SettledBatchResults<Q>>;\n /** Ensures every declaration now (normally lazy on first access). */\n ensure(): Promise<EnsureState>;\n}\n\nexport function createDataClient(config: DataClientConfig): DataClient {\n const { call, openStream } = createDataTransport(config);\n const environment = config.environment ?? (getEnvVar('NODE_ENV') === 'production' ? 'deployed' : 'preview');\n const declared = [...(config.collections ?? [])];\n if (declared.length > MAX_COLLECTIONS) {\n throw new Error(`An App declares at most ${MAX_COLLECTIONS} collections; got ${declared.length}.`);\n }\n const seen = new Set<string>();\n for (const definition of declared) {\n const key = definition.alias.toLowerCase();\n if (seen.has(key)) throw new Error(`Collection alias \"${definition.alias}\" is declared twice (aliases are case-insensitive).`);\n seen.add(key);\n }\n\n const bootstrap = createBootstrap({ call, collections: declared, environment, logger: config.logger ?? console });\n const runtime = {\n call,\n resolve: async (target: CollectionTarget | string) => {\n const definition = lookup(target);\n return 'collectionId' in definition ? definition.collectionId : bootstrap.resolve(definition);\n },\n recover: <R>(fn: () => Promise<R>, options: { collections: readonly CollectionTarget[]; retry?: boolean }) =>\n options.collections.every(target => 'collectionId' in target) ? fn() : bootstrap.recover(fn, options),\n subject: currentDataSubject,\n signal: currentSignal,\n };\n const handles = new WeakMap<CollectionTarget, Collection<object>>();\n\n function lookup(target: CollectionTarget | string): CollectionTarget {\n if (typeof target === 'string') {\n const found = declared.find((definition) => definition.alias.toLowerCase() === target.toLowerCase());\n if (!found) throw new Error(`Collection \"${target}\" is not declared in this data client's collections.`);\n return found;\n }\n if ('collectionId' in target) {\n if (typeof target.collectionId !== 'string' || !target.collectionId || target.collectionId.trim() !== target.collectionId) {\n throw new TypeError('An existing collection reference needs a nonempty collectionId without surrounding whitespace.');\n }\n return target;\n }\n if (!declared.includes(target)) {\n throw new Error(`Collection \"${target.alias}\" is declared but missing from the \\`collections\\` passed to createDataClient.`);\n }\n return target;\n }\n\n function collection(target: CollectionTarget | string) {\n const definition = lookup(target);\n let handle = handles.get(definition);\n if (!handle) {\n handle = new Collection<object>(definition, runtime);\n handles.set(definition, handle);\n }\n return handle;\n }\n\n async function transact(\n steps: readonly TransactStep[],\n options: { dryRun?: boolean; idempotencyKey?: string } = {},\n ): Promise<TransactResult> {\n assertAtomicBatch('data.transact', steps.length);\n // Steps resolve their collection IDs inside the recovered call, so a retry uses fresh IDs.\n const result = await runtime.recover(() => sendTransaction(steps, options), { collections: steps.map(step => lookup(step.collection)) });\n const results = (result.results ?? []).map(({ document, ...item }) => ({\n ...item,\n ...(document ? { document: toDoc<Record<string, unknown>>(document) } : {}),\n }));\n const expected = options.dryRun ? 'validated' : 'committed';\n if (result.status !== expected) {\n const failed = results.filter((item) => item.error);\n // A sync transaction should only fail whole; map the rest of the Outcome statuses anyway.\n const execution = result.status === 'unknown' ? 'unknown' : result.status === 'partiallyCommitted' ? 'committed' : 'rolledBack';\n throw new DataError({\n message: `Transaction ${result.status}: ${failed.map((item) => `${item.opId} ${JSON.stringify(item.error)}`).join('; ') || 'no step committed'}`,\n status: execution === 'unknown' ? 503 : 409,\n code: 'TRANSACTION_FAILED',\n execution,\n attempts: 1,\n details: { status: result.status, results },\n });\n }\n return { status: result.status, results };\n }\n\n async function sendTransaction(steps: readonly TransactStep[], options: { dryRun?: boolean; idempotencyKey?: string }) {\n const items = await Promise.all(\n steps.map(async ({ collection: target, sort, query, ...step }) => {\n const definition = lookup(target);\n const item: Record<string, unknown> = { ...step, collectionId: await runtime.resolve(definition) };\n if (sort) item.sort = toSortPairs(sort);\n if (query) item.query = { ...query, ...(query.sort ? { sort: toSortPairs(query.sort) } : {}) };\n if (step.data) {\n // Fields bound to earlier results are filled by UNS at commit; everything literal validates now.\n const bound = (step.bindings ?? []).flatMap((binding) => (binding.path.startsWith('data.') ? [binding.path.slice(5).split('.')[0]] : []));\n item.data = validateStepData(definition, step.data, bound);\n }\n if (step.update) item.update = validateUpdate(definition, step.update);\n return item;\n }),\n );\n return call<{ status: string; results?: (Omit<TransactResultItem, 'document'> & { document?: UnsRecord })[] }>(\n 'recordTransactionExecute',\n {\n items,\n mode: 'sync',\n ...(options.dryRun ? { dryRun: true } : {}),\n ...(options.idempotencyKey ? { idempotencyKey: options.idempotencyKey } : {}),\n },\n { dataSubject: currentDataSubject(), signal: currentSignal() },\n );\n }\n\n async function queryBatch<Q extends BatchQueries>(queries: Q, options: { settle?: boolean } = {}) {\n const names = Object.keys(queries);\n if (names.length < 1 || names.length > MAX_BATCH_QUERIES) {\n throw new TypeError(`data.queryBatch takes 1–${MAX_BATCH_QUERIES} queries; got ${names.length}.`);\n }\n const bad = names.find((name) => !QUERY_NAME.test(name));\n if (bad !== undefined) throw new TypeError(`data.queryBatch query name \"${bad}\" must match ${QUERY_NAME}.`);\n const collections = names.map(name => lookup(queries[name].collection));\n // Items resolve their collection IDs inside the recovered call, so a retry uses fresh IDs.\n const { results } = await runtime.recover(async () => {\n const items = await Promise.all(names.map(async (name) => ({\n id: name,\n collectionId: await runtime.resolve(queries[name].collection),\n ...(await queries[name].prepare()),\n })));\n return call<{ results: Record<string, { ok: true; data: unknown } | { ok: false; error: unknown }> }>(\n 'recordQueryBatch', { queries: items }, { dataSubject: currentDataSubject(), signal: currentSignal() });\n }, { collections });\n const settled = Object.fromEntries(names.map((name) => {\n const result = results[name];\n if (result?.ok === true) return [name, { ok: true, value: queries[name].parse(result.data) }];\n return [name, { ok: false, error: itemError(name, result?.error) }];\n })) as Record<string, { ok: true; value: unknown } | { ok: false; error: DataError }>;\n if (options.settle) return settled;\n const failed = names.find((name) => !settled[name].ok);\n if (failed !== undefined) throw (settled[failed] as { error: DataError }).error;\n return Object.fromEntries(names.map((name) => [name, (settled[name] as { value: unknown }).value]));\n }\n\n const subscribe = createSubscribe({\n openStream,\n ensure: (targets) => targets.some(target => !('collectionId' in target))\n ? bootstrap.ensure()\n : Promise.resolve({ results: [], collectionIds: new Map<string, string>(), conflicts: [] }),\n rebuild: (state, error, targets) => targets.every(target => 'collectionId' in target)\n ? Promise.resolve(false)\n : bootstrap.rebuild(state, error),\n resolve: runtime.resolve,\n lookup,\n declared,\n subject: currentDataSubject,\n });\n\n return {\n collection: collection as DataClient['collection'],\n transact,\n queryBatch: queryBatch as DataClient['queryBatch'],\n subscribe,\n ensure: bootstrap.ensure,\n };\n}\n\n/** Item errors carry no HTTP status of their own; it follows from the code. */\nconst ITEM_STATUS: Record<string, number> = { FORBIDDEN: 403, NOT_FOUND: 404 };\n\n/** A queryBatch item's error as a DataError; its `upstreamStatus` is the status its code stands for. */\nfunction itemError(name: string, value: unknown): DataError {\n const fault = parseUnsV2Fault(value);\n if (!fault) {\n return new DataError({\n message: `UNS answered query \"${name}\" of recordQueryBatch with an invalid result.`,\n status: 502,\n code: 'DATA_BAD_RESPONSE',\n upstreamStatus: 200,\n execution: 'rolledBack',\n attempts: 1,\n });\n }\n const error = new UnsV2Error(fault.reason ?? fault.code, {\n ...fault,\n // The items are reads: never an unknown outcome.\n execution: fault.execution === 'unknown' ? 'rolledBack' : fault.execution,\n queryId: fault.queryId ?? name,\n status: ITEM_STATUS[fault.code] ?? 400,\n operation: 'recordQueryBatch',\n data: { queryId: fault.queryId ?? name, details: fault.details ?? [] },\n });\n return toDataError(error);\n}\n\n"]}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/data/client.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Data client factory: collection handles, cross-collection transactions and\n * the shared bootstrap. An App builds one client per process from its\n * collection declarations; tests build their own with a mock `fetch`.\n */\nimport type { z } from 'zod';\nimport { snapshotClientConfig, type ClientConfig } from '../openapi/client.js';\nimport { getEnvVar } from '../runtime-env.js';\nimport { createBootstrap, type DataEnvironment, type EnsureState, type Logger } from './bootstrap.js';\nimport { createDataTransport } from './call.js';\nimport { assertAtomicBatch, Collection, toDoc, type BatchQuery, type UnsRecord, type WithMeta } from './collection.js';\nimport { currentSignal } from './context.js';\nimport { MAX_COLLECTIONS, type CollectionDefinition, type CollectionReference, type CollectionSchema, type CollectionTarget } from './define.js';\nimport { createSubscribe, type SubscribeOptions, type SubscriptionEvent } from './subscribe.js';\nimport { parseUnsV2Fault, UnsV2Error } from '../uns-v2/client.js';\nimport { DataError, toDataError } from './error.js';\nimport { validateStepData, validateUpdate } from './schema.js';\nimport { toSortPairs, type Filter, type Sort } from './sort.js';\n\nexport type TransactAction =\n | 'record.create'\n | 'record.check'\n | 'record.read'\n | 'record.update'\n | 'record.modify'\n | 'record.replace'\n | 'record.delete'\n | 'record.query';\n\n/** One `recordTransactionExecute` item; `collection` is a declaration, declared alias, or existing-ID reference. */\nexport interface TransactStep {\n opId: string;\n action: TransactAction;\n collection: CollectionTarget | string;\n id?: string | { ref: string };\n filter?: Filter;\n data?: Record<string, unknown>;\n update?: Record<string, unknown>;\n upsert?: boolean;\n expectedRevision?: number;\n dependsOn?: string[];\n bindings?: { path: string; ref: string; resultPath: string }[];\n selection?: 'exactOne' | 'first';\n sort?: Sort;\n returnDocument?: 'before' | 'after';\n exists?: boolean;\n operations?: Record<string, unknown>[];\n conditions?: Filter[];\n /** `record.query`: rows to bind from; `expectCount` asserts the match count before `limit`. */\n query?: { filter?: Filter; sort?: Sort; limit?: number; expectCount?: { min?: number; max?: number } };\n arrayFilters?: Record<string, unknown>[];\n}\n\nexport interface TransactResultItem {\n opId: string;\n action: string;\n id: string;\n status: string;\n collectionId?: string;\n revision?: number;\n /** Before/after snapshot when requested, as a flat document. */\n document?: WithMeta<Record<string, unknown>>;\n data?: unknown;\n query?: unknown;\n error?: unknown;\n}\n\nexport interface TransactResult {\n status: string;\n results: TransactResultItem[];\n}\n\n/** Named reads for `data.queryBatch`: 1–20 entries, names matching `[A-Za-z0-9_.-]{1,64}`. */\nexport type BatchQueries = Record<string, BatchQuery<unknown>>;\nexport type BatchResults<Q extends BatchQueries> = { [K in keyof Q]: Q[K] extends BatchQuery<infer R> ? R : never };\nexport type SettledBatchResults<Q extends BatchQueries> = {\n [K in keyof Q]: Q[K] extends BatchQuery<infer R> ? { ok: true; value: R } | { ok: false; error: DataError } : never;\n};\n\n/** Contract limit of `records:queryBatch`. */\nexport const MAX_BATCH_QUERIES = 20;\nconst QUERY_NAME = /^[A-Za-z0-9_.-]{1,64}$/;\n\n/** Data client state is bound to one static host and credential for its lifetime. */\nexport interface DataClientConfig extends Omit<ClientConfig, 'getApiKey' | 'apiKeyProvider'> {\n /** Dynamic credentials are unsupported while bootstrap and subscriptions share client state. */\n getApiKey?: never;\n apiKeyProvider?: never;\n collections?: readonly CollectionDefinition[];\n /** Defaults to \"deployed\" when NODE_ENV is production, otherwise \"preview\". */\n environment?: DataEnvironment;\n logger?: Logger;\n}\n\nexport interface DataClient {\n /** Typed handle for a declaration listed in `collections`. */\n collection<C extends CollectionDefinition>(definition: C): Collection<z.output<C['schema']>, z.input<C['schema']>>;\n /** Existing collection, with optional local write validation. Never ensured, seeded, or granted by the SDK. */\n collection<S extends CollectionSchema>(reference: CollectionReference<S> & { schema: S }): Collection<z.output<S>, z.input<S>>;\n collection<T extends object = Record<string, unknown>>(reference: CollectionReference): Collection<T>;\n /** Handle by alias, typed by the caller. */\n collection<T extends object = Record<string, unknown>>(alias: string): Collection<T>;\n /**\n * Atomic multi-record, multi-collection write (`recordTransactionExecute`, sync),\n * at most 200 steps. Steps can depend on each other (`dependsOn`) and bind\n * earlier results (`bindings`). This is not a Mongo session: everything is\n * sent at once.\n */\n transact(steps: readonly TransactStep[], options?: { dryRun?: boolean; idempotencyKey?: string }): Promise<TransactResult>;\n /**\n * Committed record changes of declared collections (all by default), as\n * one async iterable that reconnects and resumes by itself; see\n * `SubscribeOptions`. Events carry identities only. Open one per server\n * process and fan it out to browsers with `createChangeRelay`.\n */\n subscribe(options?: SubscribeOptions): AsyncIterable<SubscriptionEvent>;\n /**\n * Up to 20 reads of declared collections in one request, answered from one\n * snapshot: what a page shows (a list page with its total, counters, a\n * lookup by ID) in one round trip. Build each read with\n * `collection.query.*`; results come back under the same names.\n *\n * A read UNS refuses on its own (invalid filter, no grant) rejects the\n * whole call with its DataError; with `{ settle: true }` every result is\n * `{ ok, value }` or `{ ok: false, error }` instead. A statement timeout or\n * a batch over 2000 rows / 8 MiB always fails the whole call.\n */\n queryBatch<Q extends BatchQueries>(queries: Q): Promise<BatchResults<Q>>;\n queryBatch<Q extends BatchQueries>(queries: Q, options: { settle: true }): Promise<SettledBatchResults<Q>>;\n /** Ensures every declaration now (normally lazy on first access). */\n ensure(): Promise<EnsureState>;\n}\n\nexport function createDataClient(config: DataClientConfig): DataClient {\n const snapshot = snapshotClientConfig(config, ['environment', 'collections', 'logger']);\n if (Object.hasOwn(snapshot, 'apiKeyProvider')) {\n throw new TypeError('Tier0 SDK: apiKeyProvider is not supported by createDataClient.');\n }\n if (Object.hasOwn(snapshot, 'getApiKey')) {\n throw new TypeError('Tier0 SDK: getApiKey is not supported by createDataClient.');\n }\n // Never let bootstrap state, retries or SSE reconnect under a later identity or host.\n const fixed = {\n ...snapshot,\n apiKey: Object.hasOwn(snapshot, 'apiKey') ? snapshot.apiKey : getEnvVar('TIER0_API_KEY'),\n apiHost: snapshot.apiHost ?? snapshot.getApiHost?.() ?? getEnvVar('TIER0_API_HOST') ?? '',\n };\n const { call, openStream } = createDataTransport(fixed);\n const environment = snapshot.environment ?? (getEnvVar('NODE_ENV') === 'production' ? 'deployed' : 'preview');\n const declared = [...(snapshot.collections ?? [])];\n if (declared.length > MAX_COLLECTIONS) {\n throw new Error(`An App declares at most ${MAX_COLLECTIONS} collections; got ${declared.length}.`);\n }\n const seen = new Set<string>();\n for (const definition of declared) {\n const key = definition.alias.toLowerCase();\n if (seen.has(key)) throw new Error(`Collection alias \"${definition.alias}\" is declared twice (aliases are case-insensitive).`);\n seen.add(key);\n }\n\n // Ensure and seed writes pass no signal: they are shared by every request, and the one that triggers them must not cancel them.\n const bootstrap = createBootstrap({ call, collections: declared, environment, logger: snapshot.logger ?? console });\n const runtime = {\n call,\n resolve: async (target: CollectionTarget | string) => {\n const definition = lookup(target);\n return 'collectionId' in definition ? definition.collectionId : bootstrap.resolve(definition);\n },\n recover: <R>(fn: () => Promise<R>, options: { collections: readonly CollectionTarget[]; retry?: boolean }) =>\n options.collections.every(target => 'collectionId' in target) ? fn() : bootstrap.recover(fn, options),\n signal: currentSignal,\n };\n const handles = new WeakMap<CollectionTarget, Collection<object>>();\n\n function lookup(target: CollectionTarget | string): CollectionTarget {\n if (typeof target === 'string') {\n const found = declared.find((definition) => definition.alias.toLowerCase() === target.toLowerCase());\n if (!found) throw new Error(`Collection \"${target}\" is not declared in this data client's collections.`);\n return found;\n }\n if ('collectionId' in target) {\n if (typeof target.collectionId !== 'string' || !target.collectionId || target.collectionId.trim() !== target.collectionId) {\n throw new TypeError('An existing collection reference needs a nonempty collectionId without surrounding whitespace.');\n }\n return target;\n }\n if (!declared.includes(target)) {\n throw new Error(`Collection \"${target.alias}\" is declared but missing from the \\`collections\\` passed to createDataClient.`);\n }\n return target;\n }\n\n function collection(target: CollectionTarget | string) {\n const definition = lookup(target);\n let handle = handles.get(definition);\n if (!handle) {\n handle = new Collection<object>(definition, runtime);\n handles.set(definition, handle);\n }\n return handle;\n }\n\n async function transact(\n steps: readonly TransactStep[],\n options: { dryRun?: boolean; idempotencyKey?: string } = {},\n ): Promise<TransactResult> {\n assertAtomicBatch('data.transact', steps.length);\n // Steps resolve their collection IDs inside the recovered call, so a retry uses fresh IDs.\n const result = await runtime.recover(() => sendTransaction(steps, options), { collections: steps.map(step => lookup(step.collection)) });\n const results = (result.results ?? []).map(({ document, ...item }) => ({\n ...item,\n ...(document ? { document: toDoc<Record<string, unknown>>(document) } : {}),\n }));\n const expected = options.dryRun ? 'validated' : 'committed';\n if (result.status !== expected) {\n const failed = results.filter((item) => item.error);\n // A sync transaction should only fail whole; map the rest of the Outcome statuses anyway.\n const execution = result.status === 'unknown' ? 'unknown' : result.status === 'partiallyCommitted' ? 'committed' : 'rolledBack';\n throw new DataError({\n message: `Transaction ${result.status}: ${failed.map((item) => `${item.opId} ${JSON.stringify(item.error)}`).join('; ') || 'no step committed'}`,\n status: execution === 'unknown' ? 503 : 409,\n code: 'TRANSACTION_FAILED',\n execution,\n attempts: 1,\n details: { status: result.status, results },\n });\n }\n return { status: result.status, results };\n }\n\n async function sendTransaction(steps: readonly TransactStep[], options: { dryRun?: boolean; idempotencyKey?: string }) {\n const items = await Promise.all(\n steps.map(async ({ collection: target, sort, query, ...step }) => {\n const definition = lookup(target);\n const item: Record<string, unknown> = { ...step, collectionId: await runtime.resolve(definition) };\n if (sort) item.sort = toSortPairs(sort);\n if (query) item.query = { ...query, ...(query.sort ? { sort: toSortPairs(query.sort) } : {}) };\n if (step.data) {\n // Fields bound to earlier results are filled by UNS at commit; everything literal validates now.\n const bound = (step.bindings ?? []).flatMap((binding) => (binding.path.startsWith('data.') ? [binding.path.slice(5).split('.')[0]] : []));\n item.data = validateStepData(definition, step.data, bound);\n }\n if (step.update) item.update = validateUpdate(definition, step.update);\n return item;\n }),\n );\n return call<{ status: string; results?: (Omit<TransactResultItem, 'document'> & { document?: UnsRecord })[] }>(\n 'recordTransactionExecute',\n {\n items,\n mode: 'sync',\n ...(options.dryRun ? { dryRun: true } : {}),\n ...(options.idempotencyKey ? { idempotencyKey: options.idempotencyKey } : {}),\n },\n { signal: currentSignal() },\n );\n }\n\n async function queryBatch<Q extends BatchQueries>(queries: Q, options: { settle?: boolean } = {}) {\n const names = Object.keys(queries);\n if (names.length < 1 || names.length > MAX_BATCH_QUERIES) {\n throw new TypeError(`data.queryBatch takes 1–${MAX_BATCH_QUERIES} queries; got ${names.length}.`);\n }\n const bad = names.find((name) => !QUERY_NAME.test(name));\n if (bad !== undefined) throw new TypeError(`data.queryBatch query name \"${bad}\" must match ${QUERY_NAME}.`);\n const collections = names.map(name => lookup(queries[name].collection));\n // Items resolve their collection IDs inside the recovered call, so a retry uses fresh IDs.\n const { results } = await runtime.recover(async () => {\n const items = await Promise.all(names.map(async (name) => ({\n id: name,\n collectionId: await runtime.resolve(queries[name].collection),\n ...(await queries[name].prepare()),\n })));\n return call<{ results: Record<string, { ok: true; data: unknown } | { ok: false; error: unknown }> }>(\n 'recordQueryBatch', { queries: items }, { signal: currentSignal() });\n }, { collections });\n const settled = Object.fromEntries(names.map((name) => {\n const result = results[name];\n if (result?.ok === true) return [name, { ok: true, value: queries[name].parse(result.data) }];\n return [name, { ok: false, error: itemError(name, result?.error) }];\n })) as Record<string, { ok: true; value: unknown } | { ok: false; error: DataError }>;\n if (options.settle) return settled;\n const failed = names.find((name) => !settled[name].ok);\n if (failed !== undefined) throw (settled[failed] as { error: DataError }).error;\n return Object.fromEntries(names.map((name) => [name, (settled[name] as { value: unknown }).value]));\n }\n\n const subscribe = createSubscribe({\n openStream,\n ensure: (targets) => targets.some(target => !('collectionId' in target))\n ? bootstrap.ensure()\n : Promise.resolve({ results: [], collectionIds: new Map<string, string>(), conflicts: [] }),\n rebuild: (state, error, targets) => targets.every(target => 'collectionId' in target)\n ? Promise.resolve(false)\n : bootstrap.rebuild(state, error),\n resolve: runtime.resolve,\n lookup,\n declared,\n });\n\n return {\n collection: collection as DataClient['collection'],\n transact,\n queryBatch: queryBatch as DataClient['queryBatch'],\n subscribe,\n ensure: bootstrap.ensure,\n };\n}\n\n/** Item errors carry no HTTP status of their own; it follows from the code. */\nconst ITEM_STATUS: Record<string, number> = { FORBIDDEN: 403, NOT_FOUND: 404 };\n\n/** A queryBatch item's error as a DataError; its `upstreamStatus` is the status its code stands for. */\nfunction itemError(name: string, value: unknown): DataError {\n const fault = parseUnsV2Fault(value);\n if (!fault) {\n return new DataError({\n message: `UNS answered query \"${name}\" of recordQueryBatch with an invalid result.`,\n status: 502,\n code: 'DATA_BAD_RESPONSE',\n upstreamStatus: 200,\n execution: 'rolledBack',\n attempts: 1,\n });\n }\n const error = new UnsV2Error(fault.reason ?? fault.code, {\n ...fault,\n // The items are reads: never an unknown outcome.\n execution: fault.execution === 'unknown' ? 'rolledBack' : fault.execution,\n queryId: fault.queryId ?? name,\n status: ITEM_STATUS[fault.code] ?? 400,\n operation: 'recordQueryBatch',\n data: { queryId: fault.queryId ?? name, details: fault.details ?? [] },\n });\n return toDataError(error);\n}\n\n"]}
@@ -60,8 +60,6 @@ export interface CollectionRuntime {
60
60
  collections: readonly CollectionTarget[];
61
61
  retry?: boolean;
62
62
  }): Promise<R>;
63
- /** Data subject of the request being served. */
64
- subject(): string | undefined;
65
63
  /** Abort signal of the request being served. */
66
64
  signal(): AbortSignal | undefined;
67
65
  }
@@ -234,9 +232,9 @@ export declare class Collection<T extends object = Record<string, unknown>, TInp
234
232
  findOne(filter?: Filter, options?: Omit<FindOptions, 'limit'>): Promise<WithMeta<T> | null>;
235
233
  /**
236
234
  * Records by ID, in the order asked for (each ID once, at its first
237
- * position); IDs that do not exist, are deleted or are hidden by employee
238
- * data rules are listed in `missing` alike. More than 100 IDs are read in
239
- * chunks of 100 (not one snapshot).
235
+ * position); IDs that do not exist or are deleted are listed in
236
+ * `missing`. More than 100 IDs are read in chunks of 100 (not one
237
+ * snapshot).
240
238
  */
241
239
  get(ids: readonly string[], options?: {
242
240
  projection?: Projection;