on-zero 0.7.10 → 0.8.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 (546) hide show
  1. package/{readme.md → README.md} +172 -231
  2. package/dist/cjs/cli.cjs +5 -2
  3. package/dist/cjs/cli.native.js +5 -2
  4. package/dist/cjs/cli.native.js.map +1 -1
  5. package/dist/cjs/combineZeroClients.cjs +2 -2
  6. package/dist/cjs/combineZeroClients.native.js +6 -6
  7. package/dist/cjs/combineZeroClients.native.js.map +1 -1
  8. package/dist/cjs/config.cjs +30 -0
  9. package/dist/cjs/config.native.js +33 -0
  10. package/dist/cjs/config.native.js.map +1 -0
  11. package/dist/cjs/createPermissions.cjs +2 -2
  12. package/dist/cjs/createPermissions.native.js +17 -27
  13. package/dist/cjs/createPermissions.native.js.map +1 -1
  14. package/dist/cjs/createUseQuery.cjs +3 -3
  15. package/dist/cjs/createUseQuery.native.js +4 -4
  16. package/dist/cjs/createUseQuery.native.js.map +1 -1
  17. package/dist/cjs/createUseQueryDirect.cjs +4 -3
  18. package/dist/cjs/createUseQueryDirect.native.js +14 -18
  19. package/dist/cjs/createUseQueryDirect.native.js.map +1 -1
  20. package/dist/cjs/createZeroClient.cjs +29 -9
  21. package/dist/cjs/createZeroClient.connection.test.cjs +11 -0
  22. package/dist/cjs/createZeroClient.connection.test.native.js +14 -7
  23. package/dist/cjs/createZeroClient.connection.test.native.js.map +1 -1
  24. package/dist/cjs/createZeroClient.native.js +58 -32
  25. package/dist/cjs/createZeroClient.native.js.map +1 -1
  26. package/dist/cjs/createZeroClient.recovery.test.cjs +90 -3
  27. package/dist/cjs/createZeroClient.recovery.test.native.js +109 -19
  28. package/dist/cjs/createZeroClient.recovery.test.native.js.map +1 -1
  29. package/dist/cjs/generate-helpers.cjs +70 -17
  30. package/dist/cjs/generate-helpers.native.js +110 -23
  31. package/dist/cjs/generate-helpers.native.js.map +1 -1
  32. package/dist/cjs/generate-layout.cjs +586 -0
  33. package/dist/cjs/generate-layout.native.js +1275 -0
  34. package/dist/cjs/generate-layout.native.js.map +1 -0
  35. package/dist/cjs/generate-lite.cjs +295 -27
  36. package/dist/cjs/generate-lite.native.js +854 -102
  37. package/dist/cjs/generate-lite.native.js.map +1 -1
  38. package/dist/cjs/generate-lite.test.cjs +433 -41
  39. package/dist/cjs/generate-lite.test.native.js +446 -41
  40. package/dist/cjs/generate-lite.test.native.js.map +1 -1
  41. package/dist/cjs/generate.cjs +172 -94
  42. package/dist/cjs/generate.native.js +324 -148
  43. package/dist/cjs/generate.native.js.map +1 -1
  44. package/dist/cjs/generate.test.cjs +362 -45
  45. package/dist/cjs/generate.test.native.js +374 -45
  46. package/dist/cjs/generate.test.native.js.map +1 -1
  47. package/dist/cjs/helpers/NullToOptional.cjs +18 -0
  48. package/dist/cjs/helpers/NullToOptional.native.js +21 -0
  49. package/dist/cjs/helpers/NullToOptional.native.js.map +1 -0
  50. package/dist/cjs/helpers/asyncContext.cjs +128 -0
  51. package/dist/cjs/helpers/asyncContext.native.js +87 -0
  52. package/dist/cjs/helpers/asyncContext.native.js.map +1 -0
  53. package/dist/cjs/helpers/batchQuery.cjs +2 -2
  54. package/dist/cjs/helpers/batchQuery.native.js +2 -2
  55. package/dist/cjs/helpers/batchQuery.native.js.map +1 -1
  56. package/dist/cjs/helpers/createMutators.cjs +7 -4
  57. package/dist/cjs/helpers/createMutators.native.js +12 -9
  58. package/dist/cjs/helpers/createMutators.native.js.map +1 -1
  59. package/dist/cjs/helpers/createMutators.test.native.js +2 -2
  60. package/dist/cjs/helpers/createMutators.test.native.js.map +1 -1
  61. package/dist/cjs/helpers/ellipsis.cjs +35 -0
  62. package/dist/cjs/helpers/ellipsis.native.js +38 -0
  63. package/dist/cjs/helpers/ellipsis.native.js.map +1 -0
  64. package/dist/cjs/helpers/emitter.cjs +99 -0
  65. package/dist/cjs/helpers/emitter.native.js +125 -0
  66. package/dist/cjs/helpers/emitter.native.js.map +1 -0
  67. package/dist/cjs/helpers/ensure.cjs +33 -0
  68. package/dist/cjs/helpers/ensure.native.js +37 -0
  69. package/dist/cjs/helpers/ensure.native.js.map +1 -0
  70. package/dist/cjs/helpers/ensureLoggedIn.cjs +2 -2
  71. package/dist/cjs/helpers/ensureLoggedIn.native.js +3 -3
  72. package/dist/cjs/helpers/ensureLoggedIn.native.js.map +1 -1
  73. package/dist/cjs/helpers/errors.cjs +40 -0
  74. package/dist/cjs/helpers/errors.native.js +152 -0
  75. package/dist/cjs/helpers/errors.native.js.map +1 -0
  76. package/dist/cjs/helpers/getCurrentComponentStack.cjs +71 -0
  77. package/dist/cjs/helpers/getCurrentComponentStack.native.js +93 -0
  78. package/dist/cjs/helpers/getCurrentComponentStack.native.js.map +1 -0
  79. package/dist/cjs/helpers/globalValue.cjs +39 -0
  80. package/dist/cjs/helpers/globalValue.native.js +42 -0
  81. package/dist/cjs/helpers/globalValue.native.js.map +1 -0
  82. package/dist/cjs/helpers/mapObject.cjs +36 -0
  83. package/dist/cjs/helpers/mapObject.native.js +39 -0
  84. package/dist/cjs/helpers/mapObject.native.js.map +1 -0
  85. package/dist/cjs/helpers/mutationLifecycle.cjs +251 -0
  86. package/dist/cjs/helpers/mutationLifecycle.native.js +392 -0
  87. package/dist/cjs/helpers/mutationLifecycle.native.js.map +1 -0
  88. package/dist/cjs/helpers/mutationLifecycle.test.cjs +174 -0
  89. package/dist/cjs/helpers/mutationLifecycle.test.native.js +182 -0
  90. package/dist/cjs/helpers/mutationLifecycle.test.native.js.map +1 -0
  91. package/dist/cjs/helpers/mutatorContext.cjs +3 -3
  92. package/dist/cjs/helpers/mutatorContext.native.js +5 -5
  93. package/dist/cjs/helpers/mutatorContext.native.js.map +1 -1
  94. package/dist/cjs/helpers/platform.cjs +31 -0
  95. package/dist/cjs/helpers/platform.native.js +33 -0
  96. package/dist/cjs/helpers/platform.native.js.map +1 -0
  97. package/dist/cjs/helpers/prettyFormatZeroQuery.cjs +2 -2
  98. package/dist/cjs/helpers/prettyFormatZeroQuery.native.js +7 -7
  99. package/dist/cjs/helpers/prettyFormatZeroQuery.native.js.map +1 -1
  100. package/dist/cjs/helpers/queryContext.cjs +2 -2
  101. package/dist/cjs/helpers/queryContext.native.js +4 -4
  102. package/dist/cjs/helpers/queryContext.native.js.map +1 -1
  103. package/dist/cjs/helpers/recoverZeroClient.cjs +14 -15
  104. package/dist/cjs/helpers/recoverZeroClient.native.js +26 -23
  105. package/dist/cjs/helpers/recoverZeroClient.native.js.map +1 -1
  106. package/dist/cjs/helpers/recoverZeroClient.test.cjs +10 -8
  107. package/dist/cjs/helpers/recoverZeroClient.test.native.js +17 -21
  108. package/dist/cjs/helpers/recoverZeroClient.test.native.js.map +1 -1
  109. package/dist/cjs/helpers/sleep.cjs +34 -0
  110. package/dist/cjs/helpers/sleep.native.js +39 -0
  111. package/dist/cjs/helpers/sleep.native.js.map +1 -0
  112. package/dist/cjs/helpers/time.cjs +47 -0
  113. package/dist/cjs/helpers/time.native.js +80 -0
  114. package/dist/cjs/helpers/time.native.js.map +1 -0
  115. package/dist/cjs/helpers/tuple.cjs +18 -0
  116. package/dist/cjs/helpers/tuple.native.js +21 -0
  117. package/dist/cjs/helpers/tuple.native.js.map +1 -0
  118. package/dist/cjs/helpers/useMutation.native.js +5 -5
  119. package/dist/cjs/helpers/useMutation.native.js.map +1 -1
  120. package/dist/cjs/helpers/useMutation.test.native.js +1 -1
  121. package/dist/cjs/helpers/useMutation.test.native.js.map +1 -1
  122. package/dist/cjs/helpers/useZeroDebug.cjs +2 -2
  123. package/dist/cjs/helpers/useZeroDebug.native.js +7 -8
  124. package/dist/cjs/helpers/useZeroDebug.native.js.map +1 -1
  125. package/dist/cjs/index.cjs +9 -1
  126. package/dist/cjs/index.native.js +8 -0
  127. package/dist/cjs/index.native.js.map +1 -1
  128. package/dist/cjs/instanceRegistry.cjs +16 -4
  129. package/dist/cjs/instanceRegistry.native.js +56 -6
  130. package/dist/cjs/instanceRegistry.native.js.map +1 -1
  131. package/dist/cjs/multi.cjs +34 -13
  132. package/dist/cjs/multi.native.js +39 -17
  133. package/dist/cjs/multi.native.js.map +1 -1
  134. package/dist/cjs/multiInstance.test.cjs +6 -2
  135. package/dist/cjs/multiInstance.test.native.js +13 -9
  136. package/dist/cjs/multiInstance.test.native.js.map +1 -1
  137. package/dist/cjs/multiInstanceNested.test.native.js +10 -10
  138. package/dist/cjs/multiInstanceNested.test.native.js.map +1 -1
  139. package/dist/cjs/multiPartition.test.cjs +85 -36
  140. package/dist/cjs/multiPartition.test.native.js +102 -39
  141. package/dist/cjs/multiPartition.test.native.js.map +1 -1
  142. package/dist/cjs/mutations.cjs +2 -2
  143. package/dist/cjs/mutations.native.js +4 -4
  144. package/dist/cjs/mutations.native.js.map +1 -1
  145. package/dist/cjs/mutations.test.native.js +3 -3
  146. package/dist/cjs/mutations.test.native.js.map +1 -1
  147. package/dist/cjs/provideZero.hydration.test.cjs +3 -3
  148. package/dist/cjs/provideZero.hydration.test.native.js +4 -4
  149. package/dist/cjs/provideZero.hydration.test.native.js.map +1 -1
  150. package/dist/cjs/run.cjs +1 -1
  151. package/dist/cjs/run.native.js +3 -3
  152. package/dist/cjs/run.native.js.map +1 -1
  153. package/dist/cjs/server.cjs +20 -16
  154. package/dist/cjs/server.native.js +50 -57
  155. package/dist/cjs/server.native.js.map +1 -1
  156. package/dist/cjs/server.test.cjs +129 -6
  157. package/dist/cjs/server.test.native.js +141 -10
  158. package/dist/cjs/server.test.native.js.map +1 -1
  159. package/dist/cjs/serverWhere.test.native.js +3 -3
  160. package/dist/cjs/serverWhere.test.native.js.map +1 -1
  161. package/dist/cjs/state.cjs +2 -2
  162. package/dist/cjs/state.native.js +10 -10
  163. package/dist/cjs/state.native.js.map +1 -1
  164. package/dist/cjs/usePermission.test.native.js +3 -3
  165. package/dist/cjs/usePermission.test.native.js.map +1 -1
  166. package/dist/cjs/useQuery.empty.test.cjs +3 -3
  167. package/dist/cjs/useQuery.empty.test.native.js +6 -6
  168. package/dist/cjs/useQuery.empty.test.native.js.map +1 -1
  169. package/dist/cjs/useQuery.ssr.test.native.js +2 -2
  170. package/dist/cjs/useQuery.ssr.test.native.js.map +1 -1
  171. package/dist/cjs/vite-plugin.cjs +7 -8
  172. package/dist/cjs/vite-plugin.native.js +11 -11
  173. package/dist/cjs/vite-plugin.native.js.map +1 -1
  174. package/dist/cjs/where.cjs +3 -3
  175. package/dist/cjs/where.native.js +4 -4
  176. package/dist/cjs/where.native.js.map +1 -1
  177. package/dist/esm/cli.mjs +6 -3
  178. package/dist/esm/cli.mjs.map +1 -1
  179. package/dist/esm/cli.native.js +6 -3
  180. package/dist/esm/cli.native.js.map +1 -1
  181. package/dist/esm/combineZeroClients.mjs +1 -1
  182. package/dist/esm/combineZeroClients.mjs.map +1 -1
  183. package/dist/esm/combineZeroClients.native.js +5 -5
  184. package/dist/esm/combineZeroClients.native.js.map +1 -1
  185. package/dist/esm/config.mjs +5 -0
  186. package/dist/esm/config.mjs.map +1 -0
  187. package/dist/esm/config.native.js +5 -0
  188. package/dist/esm/config.native.js.map +1 -0
  189. package/dist/esm/createPermissions.mjs +1 -1
  190. package/dist/esm/createPermissions.mjs.map +1 -1
  191. package/dist/esm/createPermissions.native.js +16 -26
  192. package/dist/esm/createPermissions.native.js.map +1 -1
  193. package/dist/esm/createUseQuery.mjs +2 -2
  194. package/dist/esm/createUseQuery.mjs.map +1 -1
  195. package/dist/esm/createUseQuery.native.js +3 -3
  196. package/dist/esm/createUseQuery.native.js.map +1 -1
  197. package/dist/esm/createUseQueryDirect.mjs +2 -1
  198. package/dist/esm/createUseQueryDirect.mjs.map +1 -1
  199. package/dist/esm/createUseQueryDirect.native.js +12 -16
  200. package/dist/esm/createUseQueryDirect.native.js.map +1 -1
  201. package/dist/esm/createZeroClient.connection.test.mjs +11 -0
  202. package/dist/esm/createZeroClient.connection.test.mjs.map +1 -1
  203. package/dist/esm/createZeroClient.connection.test.native.js +14 -7
  204. package/dist/esm/createZeroClient.connection.test.native.js.map +1 -1
  205. package/dist/esm/createZeroClient.mjs +25 -5
  206. package/dist/esm/createZeroClient.mjs.map +1 -1
  207. package/dist/esm/createZeroClient.native.js +54 -28
  208. package/dist/esm/createZeroClient.native.js.map +1 -1
  209. package/dist/esm/createZeroClient.recovery.test.mjs +90 -3
  210. package/dist/esm/createZeroClient.recovery.test.mjs.map +1 -1
  211. package/dist/esm/createZeroClient.recovery.test.native.js +109 -19
  212. package/dist/esm/createZeroClient.recovery.test.native.js.map +1 -1
  213. package/dist/esm/generate-helpers.mjs +70 -18
  214. package/dist/esm/generate-helpers.mjs.map +1 -1
  215. package/dist/esm/generate-helpers.native.js +110 -24
  216. package/dist/esm/generate-helpers.native.js.map +1 -1
  217. package/dist/esm/generate-layout.mjs +560 -0
  218. package/dist/esm/generate-layout.mjs.map +1 -0
  219. package/dist/esm/generate-layout.native.js +1246 -0
  220. package/dist/esm/generate-layout.native.js.map +1 -0
  221. package/dist/esm/generate-lite.mjs +296 -28
  222. package/dist/esm/generate-lite.mjs.map +1 -1
  223. package/dist/esm/generate-lite.native.js +855 -103
  224. package/dist/esm/generate-lite.native.js.map +1 -1
  225. package/dist/esm/generate-lite.test.mjs +434 -42
  226. package/dist/esm/generate-lite.test.mjs.map +1 -1
  227. package/dist/esm/generate-lite.test.native.js +447 -42
  228. package/dist/esm/generate-lite.test.native.js.map +1 -1
  229. package/dist/esm/generate.mjs +172 -96
  230. package/dist/esm/generate.mjs.map +1 -1
  231. package/dist/esm/generate.native.js +324 -150
  232. package/dist/esm/generate.native.js.map +1 -1
  233. package/dist/esm/generate.test.mjs +366 -49
  234. package/dist/esm/generate.test.mjs.map +1 -1
  235. package/dist/esm/generate.test.native.js +378 -49
  236. package/dist/esm/generate.test.native.js.map +1 -1
  237. package/dist/esm/helpers/NullToOptional.mjs +2 -0
  238. package/dist/esm/helpers/NullToOptional.mjs.map +1 -0
  239. package/dist/esm/helpers/NullToOptional.native.js +2 -0
  240. package/dist/esm/helpers/NullToOptional.native.js.map +1 -0
  241. package/dist/esm/helpers/asyncContext.mjs +102 -0
  242. package/dist/esm/helpers/asyncContext.mjs.map +1 -0
  243. package/dist/esm/helpers/asyncContext.native.js +58 -0
  244. package/dist/esm/helpers/asyncContext.native.js.map +1 -0
  245. package/dist/esm/helpers/batchQuery.mjs +1 -1
  246. package/dist/esm/helpers/batchQuery.native.js +1 -1
  247. package/dist/esm/helpers/createMutators.mjs +5 -2
  248. package/dist/esm/helpers/createMutators.mjs.map +1 -1
  249. package/dist/esm/helpers/createMutators.native.js +10 -7
  250. package/dist/esm/helpers/createMutators.native.js.map +1 -1
  251. package/dist/esm/helpers/createMutators.test.native.js +2 -2
  252. package/dist/esm/helpers/createMutators.test.native.js.map +1 -1
  253. package/dist/esm/helpers/ellipsis.mjs +10 -0
  254. package/dist/esm/helpers/ellipsis.mjs.map +1 -0
  255. package/dist/esm/helpers/ellipsis.native.js +10 -0
  256. package/dist/esm/helpers/ellipsis.native.js.map +1 -0
  257. package/dist/esm/helpers/emitter.mjs +72 -0
  258. package/dist/esm/helpers/emitter.mjs.map +1 -0
  259. package/dist/esm/helpers/emitter.native.js +95 -0
  260. package/dist/esm/helpers/emitter.native.js.map +1 -0
  261. package/dist/esm/helpers/ensure.mjs +8 -0
  262. package/dist/esm/helpers/ensure.mjs.map +1 -0
  263. package/dist/esm/helpers/ensure.native.js +9 -0
  264. package/dist/esm/helpers/ensure.native.js.map +1 -0
  265. package/dist/esm/helpers/ensureLoggedIn.mjs +1 -1
  266. package/dist/esm/helpers/ensureLoggedIn.mjs.map +1 -1
  267. package/dist/esm/helpers/ensureLoggedIn.native.js +2 -2
  268. package/dist/esm/helpers/ensureLoggedIn.native.js.map +1 -1
  269. package/dist/esm/helpers/errors.mjs +14 -0
  270. package/dist/esm/helpers/errors.mjs.map +1 -0
  271. package/dist/esm/helpers/errors.native.js +123 -0
  272. package/dist/esm/helpers/errors.native.js.map +1 -0
  273. package/dist/esm/helpers/getCurrentComponentStack.mjs +35 -0
  274. package/dist/esm/helpers/getCurrentComponentStack.mjs.map +1 -0
  275. package/dist/esm/helpers/getCurrentComponentStack.native.js +54 -0
  276. package/dist/esm/helpers/getCurrentComponentStack.native.js.map +1 -0
  277. package/dist/esm/helpers/globalValue.mjs +14 -0
  278. package/dist/esm/helpers/globalValue.mjs.map +1 -0
  279. package/dist/esm/helpers/globalValue.native.js +14 -0
  280. package/dist/esm/helpers/globalValue.native.js.map +1 -0
  281. package/dist/esm/helpers/mapObject.mjs +11 -0
  282. package/dist/esm/helpers/mapObject.mjs.map +1 -0
  283. package/dist/esm/helpers/mapObject.native.js +11 -0
  284. package/dist/esm/helpers/mapObject.native.js.map +1 -0
  285. package/dist/esm/helpers/mutationLifecycle.mjs +221 -0
  286. package/dist/esm/helpers/mutationLifecycle.mjs.map +1 -0
  287. package/dist/esm/helpers/mutationLifecycle.native.js +359 -0
  288. package/dist/esm/helpers/mutationLifecycle.native.js.map +1 -0
  289. package/dist/esm/helpers/mutationLifecycle.test.mjs +175 -0
  290. package/dist/esm/helpers/mutationLifecycle.test.mjs.map +1 -0
  291. package/dist/esm/helpers/mutationLifecycle.test.native.js +180 -0
  292. package/dist/esm/helpers/mutationLifecycle.test.native.js.map +1 -0
  293. package/dist/esm/helpers/mutatorContext.mjs +1 -1
  294. package/dist/esm/helpers/mutatorContext.native.js +4 -4
  295. package/dist/esm/helpers/mutatorContext.native.js.map +1 -1
  296. package/dist/esm/helpers/platform.mjs +5 -0
  297. package/dist/esm/helpers/platform.mjs.map +1 -0
  298. package/dist/esm/helpers/platform.native.js +4 -0
  299. package/dist/esm/helpers/platform.native.js.map +1 -0
  300. package/dist/esm/helpers/prettyFormatZeroQuery.mjs +1 -1
  301. package/dist/esm/helpers/prettyFormatZeroQuery.native.js +6 -6
  302. package/dist/esm/helpers/prettyFormatZeroQuery.native.js.map +1 -1
  303. package/dist/esm/helpers/queryContext.mjs +1 -1
  304. package/dist/esm/helpers/queryContext.native.js +3 -3
  305. package/dist/esm/helpers/queryContext.native.js.map +1 -1
  306. package/dist/esm/helpers/recoverZeroClient.mjs +14 -15
  307. package/dist/esm/helpers/recoverZeroClient.mjs.map +1 -1
  308. package/dist/esm/helpers/recoverZeroClient.native.js +26 -23
  309. package/dist/esm/helpers/recoverZeroClient.native.js.map +1 -1
  310. package/dist/esm/helpers/recoverZeroClient.test.mjs +8 -6
  311. package/dist/esm/helpers/recoverZeroClient.test.mjs.map +1 -1
  312. package/dist/esm/helpers/recoverZeroClient.test.native.js +15 -19
  313. package/dist/esm/helpers/recoverZeroClient.test.native.js.map +1 -1
  314. package/dist/esm/helpers/sleep.mjs +9 -0
  315. package/dist/esm/helpers/sleep.mjs.map +1 -0
  316. package/dist/esm/helpers/sleep.native.js +11 -0
  317. package/dist/esm/helpers/sleep.native.js.map +1 -0
  318. package/dist/esm/helpers/time.mjs +22 -0
  319. package/dist/esm/helpers/time.mjs.map +1 -0
  320. package/dist/esm/helpers/time.native.js +52 -0
  321. package/dist/esm/helpers/time.native.js.map +1 -0
  322. package/dist/esm/helpers/tuple.mjs +2 -0
  323. package/dist/esm/helpers/tuple.mjs.map +1 -0
  324. package/dist/esm/helpers/tuple.native.js +2 -0
  325. package/dist/esm/helpers/tuple.native.js.map +1 -0
  326. package/dist/esm/helpers/useMutation.native.js +5 -5
  327. package/dist/esm/helpers/useMutation.native.js.map +1 -1
  328. package/dist/esm/helpers/useMutation.test.native.js +1 -1
  329. package/dist/esm/helpers/useMutation.test.native.js.map +1 -1
  330. package/dist/esm/helpers/useZeroDebug.mjs +1 -1
  331. package/dist/esm/helpers/useZeroDebug.mjs.map +1 -1
  332. package/dist/esm/helpers/useZeroDebug.native.js +6 -7
  333. package/dist/esm/helpers/useZeroDebug.native.js.map +1 -1
  334. package/dist/esm/index.js +3 -1
  335. package/dist/esm/index.js.map +1 -1
  336. package/dist/esm/index.mjs +3 -1
  337. package/dist/esm/index.mjs.map +1 -1
  338. package/dist/esm/index.native.js +3 -1
  339. package/dist/esm/index.native.js.map +1 -1
  340. package/dist/esm/instanceRegistry.mjs +13 -2
  341. package/dist/esm/instanceRegistry.mjs.map +1 -1
  342. package/dist/esm/instanceRegistry.native.js +53 -4
  343. package/dist/esm/instanceRegistry.native.js.map +1 -1
  344. package/dist/esm/multi.mjs +33 -12
  345. package/dist/esm/multi.mjs.map +1 -1
  346. package/dist/esm/multi.native.js +38 -16
  347. package/dist/esm/multi.native.js.map +1 -1
  348. package/dist/esm/multiInstance.test.mjs +5 -1
  349. package/dist/esm/multiInstance.test.mjs.map +1 -1
  350. package/dist/esm/multiInstance.test.native.js +12 -8
  351. package/dist/esm/multiInstance.test.native.js.map +1 -1
  352. package/dist/esm/multiInstanceNested.test.native.js +10 -10
  353. package/dist/esm/multiInstanceNested.test.native.js.map +1 -1
  354. package/dist/esm/multiPartition.test.mjs +86 -37
  355. package/dist/esm/multiPartition.test.mjs.map +1 -1
  356. package/dist/esm/multiPartition.test.native.js +103 -40
  357. package/dist/esm/multiPartition.test.native.js.map +1 -1
  358. package/dist/esm/mutations.mjs +1 -1
  359. package/dist/esm/mutations.mjs.map +1 -1
  360. package/dist/esm/mutations.native.js +3 -3
  361. package/dist/esm/mutations.native.js.map +1 -1
  362. package/dist/esm/mutations.test.native.js +3 -3
  363. package/dist/esm/mutations.test.native.js.map +1 -1
  364. package/dist/esm/provideZero.hydration.test.mjs +1 -1
  365. package/dist/esm/provideZero.hydration.test.mjs.map +1 -1
  366. package/dist/esm/provideZero.hydration.test.native.js +2 -2
  367. package/dist/esm/provideZero.hydration.test.native.js.map +1 -1
  368. package/dist/esm/run.mjs +1 -1
  369. package/dist/esm/run.mjs.map +1 -1
  370. package/dist/esm/run.native.js +3 -3
  371. package/dist/esm/run.native.js.map +1 -1
  372. package/dist/esm/server.mjs +20 -15
  373. package/dist/esm/server.mjs.map +1 -1
  374. package/dist/esm/server.native.js +50 -56
  375. package/dist/esm/server.native.js.map +1 -1
  376. package/dist/esm/server.test.mjs +130 -7
  377. package/dist/esm/server.test.mjs.map +1 -1
  378. package/dist/esm/server.test.native.js +142 -11
  379. package/dist/esm/server.test.native.js.map +1 -1
  380. package/dist/esm/serverWhere.test.mjs.map +1 -1
  381. package/dist/esm/serverWhere.test.native.js +3 -3
  382. package/dist/esm/serverWhere.test.native.js.map +1 -1
  383. package/dist/esm/state.mjs +1 -1
  384. package/dist/esm/state.mjs.map +1 -1
  385. package/dist/esm/state.native.js +9 -9
  386. package/dist/esm/state.native.js.map +1 -1
  387. package/dist/esm/usePermission.test.native.js +3 -3
  388. package/dist/esm/usePermission.test.native.js.map +1 -1
  389. package/dist/esm/useQuery.empty.test.mjs +1 -1
  390. package/dist/esm/useQuery.empty.test.mjs.map +1 -1
  391. package/dist/esm/useQuery.empty.test.native.js +4 -4
  392. package/dist/esm/useQuery.empty.test.native.js.map +1 -1
  393. package/dist/esm/useQuery.ssr.test.native.js +2 -2
  394. package/dist/esm/useQuery.ssr.test.native.js.map +1 -1
  395. package/dist/esm/vite-plugin.mjs +7 -8
  396. package/dist/esm/vite-plugin.mjs.map +1 -1
  397. package/dist/esm/vite-plugin.native.js +11 -11
  398. package/dist/esm/vite-plugin.native.js.map +1 -1
  399. package/dist/esm/where.mjs +1 -1
  400. package/dist/esm/where.mjs.map +1 -1
  401. package/dist/esm/where.native.js +2 -2
  402. package/dist/esm/where.native.js.map +1 -1
  403. package/package.json +18 -6
  404. package/src/cli.ts +11 -3
  405. package/src/combineZeroClients.tsx +18 -10
  406. package/src/config.ts +72 -0
  407. package/src/createPermissions.ts +3 -4
  408. package/src/createUseQuery.tsx +8 -8
  409. package/src/createUseQueryDirect.tsx +11 -10
  410. package/src/createZeroClient.authData.test.tsx +1 -1
  411. package/src/createZeroClient.connection.test.tsx +13 -2
  412. package/src/createZeroClient.recovery.test.tsx +100 -4
  413. package/src/createZeroClient.tsx +87 -30
  414. package/src/generate-helpers.ts +108 -31
  415. package/src/generate-layout.ts +841 -0
  416. package/src/generate-lite.test.ts +421 -42
  417. package/src/generate-lite.ts +479 -43
  418. package/src/generate.test.ts +552 -90
  419. package/src/generate.ts +360 -163
  420. package/src/helpers/NullToOptional.ts +5 -0
  421. package/src/helpers/asyncContext.native.ts +90 -0
  422. package/src/helpers/asyncContext.ts +159 -0
  423. package/src/helpers/batchQuery.ts +2 -2
  424. package/src/helpers/createMutators.ts +11 -8
  425. package/src/helpers/ellipsis.ts +9 -0
  426. package/src/helpers/emitter.tsx +106 -0
  427. package/src/helpers/ensure.ts +10 -0
  428. package/src/helpers/ensureLoggedIn.ts +1 -2
  429. package/src/helpers/errors.ts +13 -0
  430. package/src/helpers/getCurrentComponentStack.ts +56 -0
  431. package/src/helpers/globalValue.ts +40 -0
  432. package/src/helpers/mapObject.ts +14 -0
  433. package/src/helpers/mutationLifecycle.test.ts +180 -0
  434. package/src/helpers/mutationLifecycle.ts +313 -0
  435. package/src/helpers/mutatorContext.ts +3 -3
  436. package/src/helpers/platform.native.ts +2 -0
  437. package/src/helpers/platform.ts +16 -0
  438. package/src/helpers/prettyFormatZeroQuery.ts +2 -2
  439. package/src/helpers/queryContext.ts +2 -2
  440. package/src/helpers/recoverZeroClient.test.ts +23 -21
  441. package/src/helpers/recoverZeroClient.ts +56 -49
  442. package/src/helpers/sleep.ts +8 -0
  443. package/src/helpers/time.ts +51 -0
  444. package/src/helpers/tuple.ts +1 -0
  445. package/src/helpers/useMutation.tsx +3 -3
  446. package/src/helpers/useZeroDebug.ts +3 -3
  447. package/src/index.ts +13 -1
  448. package/src/instanceRegistry.ts +19 -6
  449. package/src/multi.ts +75 -31
  450. package/src/multiInstance.test.tsx +31 -13
  451. package/src/multiInstanceNested.test.tsx +2 -2
  452. package/src/multiPartition.test.ts +62 -27
  453. package/src/mutations.ts +10 -10
  454. package/src/provideZero.hydration.test.tsx +1 -1
  455. package/src/resolveQuery.ts +2 -2
  456. package/src/run.ts +7 -7
  457. package/src/server.test.ts +117 -18
  458. package/src/server.ts +70 -43
  459. package/src/serverWhere.ts +2 -2
  460. package/src/state.ts +2 -2
  461. package/src/types.ts +47 -6
  462. package/src/useQuery.empty.test.tsx +3 -3
  463. package/src/useQuery.ssr.test.ts +1 -1
  464. package/src/vite-plugin.ts +12 -9
  465. package/src/where.ts +6 -7
  466. package/src/zeroRunner.ts +2 -2
  467. package/types/combineZeroClients.d.ts +11 -5
  468. package/types/combineZeroClients.d.ts.map +1 -1
  469. package/types/config.d.ts +62 -0
  470. package/types/config.d.ts.map +1 -0
  471. package/types/createPermissions.d.ts.map +1 -1
  472. package/types/createUseQuery.d.ts.map +1 -1
  473. package/types/createUseQueryDirect.d.ts +1 -1
  474. package/types/createUseQueryDirect.d.ts.map +1 -1
  475. package/types/createZeroClient.d.ts +22 -12
  476. package/types/createZeroClient.d.ts.map +1 -1
  477. package/types/createZeroClient.recovery.test.d.ts.map +1 -1
  478. package/types/generate-helpers.d.ts +17 -2
  479. package/types/generate-helpers.d.ts.map +1 -1
  480. package/types/generate-layout.d.ts +26 -0
  481. package/types/generate-layout.d.ts.map +1 -0
  482. package/types/generate-lite.d.ts +29 -1
  483. package/types/generate-lite.d.ts.map +1 -1
  484. package/types/generate.d.ts +20 -0
  485. package/types/generate.d.ts.map +1 -1
  486. package/types/helpers/NullToOptional.d.ts +6 -0
  487. package/types/helpers/NullToOptional.d.ts.map +1 -0
  488. package/types/helpers/asyncContext.d.ts +15 -0
  489. package/types/helpers/asyncContext.d.ts.map +1 -0
  490. package/types/helpers/asyncContext.native.d.ts +8 -0
  491. package/types/helpers/asyncContext.native.d.ts.map +1 -0
  492. package/types/helpers/createMutators.d.ts +2 -1
  493. package/types/helpers/createMutators.d.ts.map +1 -1
  494. package/types/helpers/ellipsis.d.ts +2 -0
  495. package/types/helpers/ellipsis.d.ts.map +1 -0
  496. package/types/helpers/emitter.d.ts +21 -0
  497. package/types/helpers/emitter.d.ts.map +1 -0
  498. package/types/helpers/ensure.d.ts +2 -0
  499. package/types/helpers/ensure.d.ts.map +1 -0
  500. package/types/helpers/ensureLoggedIn.d.ts.map +1 -1
  501. package/types/helpers/errors.d.ts +7 -0
  502. package/types/helpers/errors.d.ts.map +1 -0
  503. package/types/helpers/getCurrentComponentStack.d.ts +2 -0
  504. package/types/helpers/getCurrentComponentStack.d.ts.map +1 -0
  505. package/types/helpers/globalValue.d.ts +23 -0
  506. package/types/helpers/globalValue.d.ts.map +1 -0
  507. package/types/helpers/mapObject.d.ts +4 -0
  508. package/types/helpers/mapObject.d.ts.map +1 -0
  509. package/types/helpers/mutationLifecycle.d.ts +44 -0
  510. package/types/helpers/mutationLifecycle.d.ts.map +1 -0
  511. package/types/helpers/mutationLifecycle.test.d.ts +2 -0
  512. package/types/helpers/mutationLifecycle.test.d.ts.map +1 -0
  513. package/types/helpers/platform.d.ts +3 -0
  514. package/types/helpers/platform.d.ts.map +1 -0
  515. package/types/helpers/platform.native.d.ts +3 -0
  516. package/types/helpers/platform.native.d.ts.map +1 -0
  517. package/types/helpers/recoverZeroClient.d.ts +13 -9
  518. package/types/helpers/recoverZeroClient.d.ts.map +1 -1
  519. package/types/helpers/sleep.d.ts +2 -0
  520. package/types/helpers/sleep.d.ts.map +1 -0
  521. package/types/helpers/time.d.ts +28 -0
  522. package/types/helpers/time.d.ts.map +1 -0
  523. package/types/helpers/tuple.d.ts +2 -0
  524. package/types/helpers/tuple.d.ts.map +1 -0
  525. package/types/index.d.ts +3 -1
  526. package/types/index.d.ts.map +1 -1
  527. package/types/instanceRegistry.d.ts +1 -0
  528. package/types/instanceRegistry.d.ts.map +1 -1
  529. package/types/multi.d.ts +23 -1
  530. package/types/multi.d.ts.map +1 -1
  531. package/types/mutations.d.ts +1 -1
  532. package/types/mutations.d.ts.map +1 -1
  533. package/types/run.d.ts.map +1 -1
  534. package/types/server.d.ts +12 -8
  535. package/types/server.d.ts.map +1 -1
  536. package/types/state.d.ts +1 -1
  537. package/types/state.d.ts.map +1 -1
  538. package/types/types.d.ts +23 -1
  539. package/types/types.d.ts.map +1 -1
  540. package/types/vite-plugin.d.ts.map +1 -1
  541. package/types/where.d.ts.map +1 -1
  542. package/lint/ssr-guards.js +0 -165
  543. package/test-fixtures/server-return-types.ts +0 -58
  544. package/test-fixtures/tsconfig.json +0 -13
  545. package/tsconfig.json +0 -26
  546. package/vitest.config.ts +0 -8
@@ -95,7 +95,7 @@ async function mount(extraProps: Record<string, unknown> = {}, userID = 'conn')
95
95
  {...extraProps}
96
96
  >
97
97
  <span>ok</span>
98
- </client.ProvideZero>,
98
+ </client.ProvideZero>
99
99
  )
100
100
  await Promise.resolve()
101
101
  })
@@ -119,7 +119,7 @@ test('waitForZero resolves when the provider publishes its active instance', asy
119
119
  userID="readiness"
120
120
  >
121
121
  <span>ok</span>
122
- </readinessClient.ProvideZero>,
122
+ </readinessClient.ProvideZero>
123
123
  )
124
124
  await Promise.resolve()
125
125
  })
@@ -138,6 +138,10 @@ test('installs the supplied client transport for the provider server', async ()
138
138
 
139
139
  test('refreshAuth reconnects in place on needs-auth, once per transition', async () => {
140
140
  const refreshAuth = vi.fn(async () => 'fresh-token')
141
+ const events: Array<{ type: string; reasonKey?: string }> = []
142
+ const off = client.zeroEvents.listen((event) => {
143
+ if (event) events.push(event)
144
+ })
141
145
  const instance = await mount({ refreshAuth }, 'conn-auth')
142
146
 
143
147
  await act(async () => {
@@ -150,6 +154,12 @@ test('refreshAuth reconnects in place on needs-auth, once per transition', async
150
154
  await Promise.resolve()
151
155
  })
152
156
  expect(instance.connection.connect).toHaveBeenCalledWith({ auth: 'fresh-token' })
157
+ expect(events).toContainEqual({
158
+ type: 'error',
159
+ reasonKey: 'connection-needs-auth',
160
+ message: 'token expired',
161
+ })
162
+ off()
153
163
  })
154
164
 
155
165
  test('stale-poke error reconnects instead of surfacing a fatal error', async () => {
@@ -219,6 +229,7 @@ test('fatal error state stays terminal and reports the reason', async () => {
219
229
  expect(instance.connection.connect).not.toHaveBeenCalled()
220
230
  expect(events).toContainEqual({
221
231
  type: 'error',
232
+ reasonKey: 'connection-error',
222
233
  message: 'Got open event but connect start time is undefined',
223
234
  })
224
235
  off()
@@ -23,7 +23,7 @@ const fakeZero = vi.hoisted(() => {
23
23
  complete: Promise.resolve(),
24
24
  }))
25
25
 
26
- constructor() {
26
+ constructor(readonly options: Record<string, any>) {
27
27
  instances.push(this)
28
28
  }
29
29
  }
@@ -41,6 +41,7 @@ vi.mock('@rocicorp/zero', async (importOriginal) => {
41
41
  })
42
42
 
43
43
  import { createZeroClient } from './createZeroClient'
44
+ import { resetRecoveryStateForTests } from './helpers/recoverZeroClient'
44
45
 
45
46
  declare global {
46
47
  // eslint-disable-next-line no-var
@@ -62,6 +63,8 @@ let container: HTMLDivElement
62
63
  let root: Root | null
63
64
 
64
65
  beforeEach(() => {
66
+ window.sessionStorage.clear()
67
+ resetRecoveryStateForTests()
65
68
  fakeZero.instances.length = 0
66
69
  container = document.createElement('div')
67
70
  root = null
@@ -77,7 +80,7 @@ async function mount() {
77
80
  root?.render(
78
81
  <client.ProvideZero cacheURL="http://127.0.0.1:7777/zero" userID="agentbus">
79
82
  <span>ok</span>
80
- </client.ProvideZero>,
83
+ </client.ProvideZero>
81
84
  )
82
85
  await Promise.resolve()
83
86
  })
@@ -111,7 +114,7 @@ test('remint drops local state and reconstructs a fresh instance in place', asyn
111
114
  root?.render(
112
115
  <client.ProvideZero cacheURL="http://127.0.0.1:7777/zero" userID="remint-test">
113
116
  <span>ok</span>
114
- </client.ProvideZero>,
117
+ </client.ProvideZero>
115
118
  )
116
119
  await Promise.resolve()
117
120
  })
@@ -156,7 +159,7 @@ test('remint with no provider mounted returns false without burning the guard bu
156
159
  userID="remint-unmounted"
157
160
  >
158
161
  <span>ok</span>
159
- </isolated.ProvideZero>,
162
+ </isolated.ProvideZero>
160
163
  )
161
164
  await Promise.resolve()
162
165
  })
@@ -170,3 +173,96 @@ test('remint with no provider mounted returns false without burning the guard bu
170
173
  })
171
174
  expect(result).toBe(true)
172
175
  })
176
+
177
+ test('two consecutive server acknowledgement timeouts enter normal recovery', async () => {
178
+ vi.useFakeTimers()
179
+ try {
180
+ const isolated = createZeroClient({
181
+ schema,
182
+ models: {},
183
+ groupedQueries: {},
184
+ instanceName: 'ack-timeout-recovery-test',
185
+ })
186
+ let scheduled:
187
+ | {
188
+ reasonKey: string
189
+ performReload: () => Promise<void>
190
+ }
191
+ | undefined
192
+
193
+ root = createRoot(container)
194
+ await act(async () => {
195
+ root?.render(
196
+ <isolated.ProvideZero
197
+ cacheURL="http://127.0.0.1:7777/zero"
198
+ userID="ack-timeout"
199
+ scheduleReload={(context) => {
200
+ scheduled = context
201
+ }}
202
+ >
203
+ <span>ok</span>
204
+ </isolated.ProvideZero>
205
+ )
206
+ await Promise.resolve()
207
+ })
208
+
209
+ const timeout = async (label: string) => {
210
+ const result = isolated.awaitMutationServer(
211
+ { client: Promise.resolve({}), server: new Promise(() => {}) },
212
+ label,
213
+ 10
214
+ )
215
+ const timedOut = expect(result).rejects.toMatchObject({
216
+ name: 'MutationTimeoutError',
217
+ phase: 'server',
218
+ })
219
+ await act(async () => {
220
+ await vi.advanceTimersByTimeAsync(10)
221
+ })
222
+ await timedOut
223
+ }
224
+
225
+ await timeout('first write')
226
+ expect(scheduled).toBeUndefined()
227
+ await timeout('second write')
228
+ expect(scheduled).toMatchObject({ reasonKey: 'server-ack-timeout' })
229
+ } finally {
230
+ vi.useRealTimers()
231
+ }
232
+ })
233
+
234
+ test('transport and app benign log patterns suppress classified recovery', async () => {
235
+ const isolated = createZeroClient({
236
+ schema,
237
+ models: {},
238
+ groupedQueries: {},
239
+ instanceName: 'transport-log-classification-test',
240
+ })
241
+ const scheduleReload = vi.fn()
242
+ const install = vi.fn()
243
+ root = createRoot(container)
244
+ await act(async () => {
245
+ root?.render(
246
+ <isolated.ProvideZero
247
+ cacheURL="http://127.0.0.1:7777/zero"
248
+ userID="transport-log"
249
+ transport={{
250
+ install,
251
+ logClassifications: { benign: ['ClientNotFound'] },
252
+ }}
253
+ benignLogPatterns={[/sent mutation ID .* but expected/]}
254
+ scheduleReload={scheduleReload}
255
+ >
256
+ <span>ok</span>
257
+ </isolated.ProvideZero>
258
+ )
259
+ await Promise.resolve()
260
+ })
261
+
262
+ const instance = fakeZero.instances.at(-1)!
263
+ instance.options.logSink.log('error', undefined, 'ClientNotFound: cold boot')
264
+ instance.options.logSink.log('error', undefined, 'sent mutation ID 5 but expected 4')
265
+ await Promise.resolve()
266
+ expect(install).toHaveBeenCalledOnce()
267
+ expect(scheduleReload).not.toHaveBeenCalled()
268
+ })
@@ -10,7 +10,6 @@ import {
10
10
  ZeroContext,
11
11
  ZeroProvider,
12
12
  } from '@rocicorp/zero/react'
13
- import { createEmitter, IS_SERVER_RUNTIME, type Emitter } from '@take-out/helpers'
14
13
  import {
15
14
  createContext,
16
15
  memo,
@@ -23,6 +22,7 @@ import {
23
22
  type Context,
24
23
  type ReactNode,
25
24
  } from 'react'
25
+
26
26
  import { createPermissions } from './createPermissions'
27
27
  import {
28
28
  createUseQuery,
@@ -30,13 +30,17 @@ import {
30
30
  type UseQueryHook,
31
31
  } from './createUseQuery'
32
32
  import { createMutators } from './helpers/createMutators'
33
+ import { createEmitter, type Emitter } from './helpers/emitter'
33
34
  import { getAuth } from './helpers/getAuth'
35
+ import { createMutationLifecycle } from './helpers/mutationLifecycle'
36
+ import { IS_SERVER_RUNTIME } from './helpers/platform'
34
37
  import {
35
38
  composeRecoveryLogSink,
36
39
  isRecoverableZeroStalePokeMessage,
37
40
  makeZeroRecovery,
38
41
  type RecoveryGuardStorage,
39
42
  type ScheduleReloadContext,
43
+ type ZeroLogPattern,
40
44
  type ZeroRecoveryDeps,
41
45
  } from './helpers/recoverZeroClient'
42
46
  import { registerClientInstance } from './instanceRegistry'
@@ -48,7 +52,14 @@ import { getEnvironment, setAuthData, setEnvironment, setSchema } from './state'
48
52
  import { getRawWhere, setEvaluatingPermission } from './where'
49
53
  import { setRunner, type ZeroRunner } from './zeroRunner'
50
54
  import { zql } from './zql'
51
- import type { AuthData, GenericModels, GetZeroMutators, ZeroEvent } from './types'
55
+
56
+ import type {
57
+ AuthData,
58
+ GenericModels,
59
+ GetZeroMutators,
60
+ ZeroEvent,
61
+ ZeroEventsEmitter,
62
+ } from './types'
52
63
  import type {
53
64
  AnyQueryRegistry,
54
65
  Query,
@@ -70,6 +81,9 @@ export type PermissionStrategy = 'optimistic' | 'optimistic-deny' | 'optimistic-
70
81
 
71
82
  export type ZeroProviderTransport = {
72
83
  install(serverURL: string): unknown
84
+ logClassifications?: {
85
+ benign?: readonly ZeroLogPattern[]
86
+ }
73
87
  }
74
88
 
75
89
  export type WaitForZeroOptions = {
@@ -84,6 +98,9 @@ export type CreateZeroClientOptions<
84
98
  models: Models
85
99
  groupedQueries: GroupedQueries
86
100
  permissionStrategy?: PermissionStrategy
101
+ // repeated server acknowledgement timeouts are a desync signal. one timeout
102
+ // remains a normal slow-server failure; recovery begins at this threshold.
103
+ serverAckTimeoutRecoveryThreshold?: number
87
104
  // names this client instance so multiple instances can coexist on one page.
88
105
  // each query/mutator namespace is claimed by exactly one instance, and the
89
106
  // ambient run() + the combineZeroClients facade dispatch by that claim.
@@ -119,7 +136,7 @@ function createUnavailableDirectUseQuery<
119
136
  >(): UseQueryHook<Schema> {
120
137
  function useQueryDirect(): never {
121
138
  throw new Error(
122
- `[on-zero] direct queries are optional. Import createZeroClientWithDirectQueries from 'on-zero/multi' for clients used outside the innermost ZeroProvider.`,
139
+ `[on-zero] direct queries are optional. Import createZeroClientWithDirectQueries from 'on-zero/multi' for clients used outside the innermost ZeroProvider.`
123
140
  )
124
141
  }
125
142
 
@@ -127,7 +144,7 @@ function createUnavailableDirectUseQuery<
127
144
  }
128
145
 
129
146
  export function createZeroClient<Schema extends ZeroSchema, Models extends GenericModels>(
130
- options: CreateZeroClientOptions<Schema, Models>,
147
+ options: CreateZeroClientOptions<Schema, Models>
131
148
  ) {
132
149
  return createZeroClientInternal(options)
133
150
  }
@@ -141,6 +158,7 @@ export function createZeroClientInternal<
141
158
  groupedQueries,
142
159
  permissionStrategy = 'optimistic',
143
160
  instanceName = 'default',
161
+ serverAckTimeoutRecoveryThreshold = 2,
144
162
  createDirectUseQuery,
145
163
  }: CreateZeroClientOptions<Schema, Models> & {
146
164
  createDirectUseQuery?: DirectQueryAdapter<Schema>
@@ -175,7 +193,7 @@ export function createZeroClientInternal<
175
193
  registerQuery(fn, `${namespace}.${name}`)
176
194
  // wrap each plain function in defineQuery
177
195
  wrappedNamespaces[namespace][name] = defineQuery(({ args }: { args: any }) =>
178
- fn(args),
196
+ fn(args)
179
197
  )
180
198
  }
181
199
  }
@@ -210,7 +228,7 @@ export function createZeroClientInternal<
210
228
  eb,
211
229
  rawPerm || ((e: any) => e.and()),
212
230
  args.objOrId,
213
- table,
231
+ table
214
232
  )
215
233
  } finally {
216
234
  setEvaluatingPermission(false)
@@ -234,7 +252,7 @@ export function createZeroClientInternal<
234
252
  eb,
235
253
  perm || ((e: any) => e.and()),
236
254
  args.objOrId,
237
- table,
255
+ table
238
256
  )
239
257
  })
240
258
  .one()
@@ -261,7 +279,7 @@ export function createZeroClientInternal<
261
279
  namespaces: Object.keys(models),
262
280
  customQueries,
263
281
  queryNames: Object.entries(groupedQueries).flatMap(([namespace, queries]) =>
264
- Object.keys(queries).map((name) => `${namespace}.${name}`),
282
+ Object.keys(queries).map((name) => `${namespace}.${name}`)
265
283
  ),
266
284
  })
267
285
 
@@ -277,7 +295,7 @@ export function createZeroClientInternal<
277
295
  if (latestZeroInstance) return Promise.resolve(latestZeroInstance)
278
296
  if (signal?.aborted) {
279
297
  return Promise.reject(
280
- signal.reason ?? new Error('Waiting for the Zero instance was aborted'),
298
+ signal.reason ?? new Error('Waiting for the Zero instance was aborted')
281
299
  )
282
300
  }
283
301
 
@@ -305,7 +323,7 @@ export function createZeroClientInternal<
305
323
  const resolve = () => {
306
324
  if (latestZeroInstance === null) {
307
325
  throw new Error(
308
- `Zero instance not initialized. Ensure ZeroProvider is mounted before accessing 'zero'.`,
326
+ `Zero instance not initialized. Ensure ZeroProvider is mounted before accessing 'zero'.`
309
327
  )
310
328
  }
311
329
  let target: any = (latestZeroInstance as any).mutate
@@ -330,7 +348,7 @@ export function createZeroClientInternal<
330
348
  if (latestZeroInstance === null) {
331
349
  if (key === 'mutate') return lazyMutatePath([])
332
350
  throw new Error(
333
- `Zero instance not initialized. Ensure ZeroProvider is mounted before accessing 'zero'.`,
351
+ `Zero instance not initialized. Ensure ZeroProvider is mounted before accessing 'zero'.`
334
352
  )
335
353
  }
336
354
  if (key === 'delete') {
@@ -346,7 +364,25 @@ export function createZeroClientInternal<
346
364
  // unchanged for single-instance back-compat.
347
365
  const emitterScope = instanceName === 'default' ? '' : `:${instanceName}`
348
366
 
349
- const zeroEvents = createEmitter<ZeroEvent | null>(`zero${emitterScope}`, null)
367
+ const zeroEvents: ZeroEventsEmitter = createEmitter<ZeroEvent | null>(
368
+ `zero${emitterScope}`,
369
+ null
370
+ )
371
+
372
+ let recoverFromAckTimeout: (input: {
373
+ label: string
374
+ timeoutMs: number
375
+ consecutiveTimeouts: number
376
+ }) => void = () => {}
377
+ const ackTimeoutRecoveryThreshold =
378
+ Number.isFinite(serverAckTimeoutRecoveryThreshold) &&
379
+ serverAckTimeoutRecoveryThreshold >= 2
380
+ ? Math.floor(serverAckTimeoutRecoveryThreshold)
381
+ : 2
382
+ const mutationLifecycle = createMutationLifecycle({
383
+ ackTimeoutRecoveryThreshold,
384
+ recoverFromAckTimeout: (input) => recoverFromAckTimeout(input),
385
+ })
350
386
 
351
387
  const zeroInstanceVersion = createDirectUseQuery
352
388
  ? createEmitter<number>(`zero-instance-version${emitterScope}`, 0)
@@ -381,14 +417,14 @@ export function createZeroClientInternal<
381
417
  table: TableName | (string & {}),
382
418
  objOrId: string | Partial<Row<any>> | undefined,
383
419
  enabled?: boolean,
384
- debug?: boolean,
420
+ debug?: boolean
385
421
  ) => boolean | null
386
422
  }
387
423
  return function usePermission(
388
424
  table: TableName | (string & {}),
389
425
  objOrId: string | Partial<Row<any>> | undefined,
390
426
  enabled = typeof objOrId !== 'undefined',
391
- debug = false,
427
+ debug = false
392
428
  ): boolean | null {
393
429
  const disableMode = useContext(DisabledContext)
394
430
  const lastRef = useRef<boolean | null>(null)
@@ -403,7 +439,7 @@ export function createZeroClientInternal<
403
439
  const [data, status] = useQueryImpl(
404
440
  checkFn as any,
405
441
  { objOrId: objOrId as any, _uid },
406
- { enabled: Boolean(!disableMode && enabled && objOrId && checkFn) },
442
+ { enabled: Boolean(!disableMode && enabled && objOrId && checkFn) }
407
443
  )
408
444
 
409
445
  if (debug) {
@@ -478,6 +514,7 @@ export function createZeroClientInternal<
478
514
  function invalidateZeroInstance(instanceToInvalidate: ZeroInstance | null): void {
479
515
  if (!instanceToInvalidate) return
480
516
 
517
+ mutationLifecycle.fence()
481
518
  if (clearZeroInstanceReferences(instanceToInvalidate)) {
482
519
  zeroInstanceVersion?.emit(zeroInstanceVersion.value + 1)
483
520
  }
@@ -489,8 +526,9 @@ export function createZeroClientInternal<
489
526
  }
490
527
 
491
528
  async function deleteZeroInstance(
492
- instanceToDelete: ZeroInstance | null,
529
+ instanceToDelete: ZeroInstance | null
493
530
  ): Promise<unknown> {
531
+ mutationLifecycle.fence()
494
532
  try {
495
533
  return await instanceToDelete?.delete()
496
534
  } finally {
@@ -588,9 +626,9 @@ export function createZeroClientInternal<
588
626
  // cross-reload loop-guard backing store; defaults to sessionStorage on web.
589
627
  // inject a native KV so Hermes gets real cross-reload protection.
590
628
  guardStorage?: RecoveryGuardStorage
591
- // return true for a classified recovery log the app wants treated as benign
592
- // (its own cold-boot timeout, say) so it does NOT trigger recovery.
593
- benignLogFilter?: (message: string) => boolean
629
+ // expected recovery signatures supplied as data. transport patterns and app
630
+ // patterns are combined; neither replaces the built-in classification.
631
+ benignLogPatterns?: readonly ZeroLogPattern[]
594
632
  // called when the connection needs auth; return a fresh token to reconnect
595
633
  // in place. lets an expired token auto-recover without a reload.
596
634
  refreshAuth?: () => Promise<string | undefined>
@@ -633,7 +671,7 @@ export function createZeroClientInternal<
633
671
  beforeReload,
634
672
  scheduleReload,
635
673
  guardStorage,
636
- benignLogFilter,
674
+ benignLogPatterns,
637
675
  refreshAuth,
638
676
  connectionDataset,
639
677
  disable,
@@ -696,11 +734,14 @@ export function createZeroClientInternal<
696
734
  Object.entries({ kvStore: 'mem', ...props })
697
735
  .filter(
698
736
  ([key, value]) =>
699
- key !== 'auth' && typeof value !== 'function' && value !== undefined,
737
+ key !== 'auth' && typeof value !== 'function' && value !== undefined
700
738
  )
701
739
  .sort(([a], [b]) => (a < b ? -1 : 1)),
702
740
  hasAuth,
703
741
  transport,
742
+ benignLogPatterns?.map((pattern) =>
743
+ typeof pattern === 'string' ? pattern : `/${pattern.source}/${pattern.flags}`
744
+ ),
704
745
  remintGeneration,
705
746
  ])
706
747
 
@@ -717,6 +758,7 @@ export function createZeroClientInternal<
717
758
  // until the commit-safe rotation effect below closes or reuses it.
718
759
  useLayoutEffect(() => {
719
760
  if (latestZeroInstance && (disable || cachedZero?.key !== instanceKey)) {
761
+ mutationLifecycle.fence()
720
762
  unpublishZeroInstance(latestZeroInstance)
721
763
  }
722
764
  }, [disable, instanceKey])
@@ -754,6 +796,7 @@ export function createZeroClientInternal<
754
796
  // the replacement's SetZeroInstance effect publishes one version
755
797
  // change; clearing the old references here must not emit a second.
756
798
  clearZeroInstanceReferences(cached.instance)
799
+ mutationLifecycle.fence()
757
800
  cached.instance.close()
758
801
  }
759
802
  // recovery closures reach the instance through this ref so they always
@@ -766,9 +809,14 @@ export function createZeroClientInternal<
766
809
  beforeReload,
767
810
  scheduleReload,
768
811
  guardStorage,
769
- benignLogFilter,
812
+ benignLogPatterns: [
813
+ ...(transport?.logClassifications?.benign ?? []),
814
+ ...(benignLogPatterns ?? []),
815
+ ],
816
+ onRecovery: () => mutationLifecycle.fence(),
770
817
  }
771
818
  const recovery = makeZeroRecovery(recoveryDeps)
819
+ recoverFromAckTimeout = recovery.onServerAckTimeout
772
820
  const createdInstance = new ZeroClient<Schema, ZeroMutators>({
773
821
  kvStore: 'mem',
774
822
  ...options,
@@ -860,6 +908,7 @@ export function createZeroClientInternal<
860
908
  // runner before descendant effects perform imperative work.
861
909
  if (zeroInstance !== latestZeroInstance) {
862
910
  latestZeroInstance = zeroInstance
911
+ mutationLifecycle.activate()
863
912
  const runner: ZeroRunner = (query, options) =>
864
913
  zeroInstance.run(query as any, options)
865
914
  // the instance-keyed runner is what run() dispatches owned namespaces
@@ -889,7 +938,7 @@ export function createZeroClientInternal<
889
938
  exposeDataset,
890
939
  datasetCacheUrl,
891
940
  }: {
892
- zeroEvents: ReturnType<typeof createEmitter<ZeroEvent | null>>
941
+ zeroEvents: ZeroEventsEmitter
893
942
  refreshAuth?: () => Promise<string | undefined>
894
943
  exposeDataset?: boolean
895
944
  datasetCacheUrl?: string
@@ -947,13 +996,18 @@ export function createZeroClientInternal<
947
996
  if (name !== prevState.current) {
948
997
  prevState.current = name
949
998
  if (name === 'error' || name === 'needs-auth') {
950
- zeroEvents.emit({ type: 'error', message: reason || name })
999
+ zeroEvents.emit({
1000
+ type: 'error',
1001
+ reasonKey:
1002
+ name === 'needs-auth' ? 'connection-needs-auth' : 'connection-error',
1003
+ message: reason || name,
1004
+ })
951
1005
  }
952
1006
  }
953
1007
  }, [state, zeroEvents, zeroInstance, refreshAuth, exposeDataset, datasetCacheUrl])
954
1008
 
955
1009
  return null
956
- },
1010
+ }
957
1011
  )
958
1012
 
959
1013
  // preload data for a query into cache without materializing
@@ -961,16 +1015,16 @@ export function createZeroClientInternal<
961
1015
  function preload<TArg, TTable extends keyof Schema['tables'] & string, TReturn>(
962
1016
  fn: PlainQueryFn<TArg, Query<TTable, Schema, TReturn>>,
963
1017
  params: TArg,
964
- options?: PreloadOptions,
1018
+ options?: PreloadOptions
965
1019
  ): { cleanup: () => void; complete: Promise<void> }
966
1020
  function preload<TTable extends keyof Schema['tables'] & string, TReturn>(
967
1021
  fn: PlainQueryFn<void, Query<TTable, Schema, TReturn>>,
968
- options?: PreloadOptions,
1022
+ options?: PreloadOptions
969
1023
  ): { cleanup: () => void; complete: Promise<void> }
970
1024
  function preload(
971
1025
  fnArg: any,
972
1026
  paramsOrOptions?: any,
973
- optionsArg?: PreloadOptions,
1027
+ optionsArg?: PreloadOptions
974
1028
  ): { cleanup: () => void; complete: Promise<void> } {
975
1029
  const hasParams =
976
1030
  optionsArg !== undefined || (paramsOrOptions && !('ttl' in paramsOrOptions))
@@ -983,10 +1037,10 @@ export function createZeroClientInternal<
983
1037
 
984
1038
  function getQuery<TArg, TTable extends keyof Schema['tables'] & string, TReturn>(
985
1039
  fn: PlainQueryFn<TArg, Query<TTable, Schema, TReturn>>,
986
- params: TArg,
1040
+ params: TArg
987
1041
  ): ReturnType<typeof resolveQuery<Schema>>
988
1042
  function getQuery<TTable extends keyof Schema['tables'] & string, TReturn>(
989
- fn: PlainQueryFn<void, Query<TTable, Schema, TReturn>>,
1043
+ fn: PlainQueryFn<void, Query<TTable, Schema, TReturn>>
990
1044
  ): ReturnType<typeof resolveQuery<Schema>>
991
1045
  function getQuery(fn: any, params?: any) {
992
1046
  return resolveQuery({ customQueries, fn, params })
@@ -1019,5 +1073,8 @@ export function createZeroClientInternal<
1019
1073
  getQuery,
1020
1074
  waitForZero,
1021
1075
  remint,
1076
+ enqueueBackgroundMutation: mutationLifecycle.enqueueBackgroundMutation,
1077
+ awaitMutationClient: mutationLifecycle.awaitMutationClient,
1078
+ awaitMutationServer: mutationLifecycle.awaitMutationServer,
1022
1079
  }
1023
1080
  }