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
@@ -14,8 +14,8 @@ it's what we use for our [takeout stack](https://takeout.tamagui.dev).
14
14
 
15
15
  on-zero tries to bring Rails-like structure and DRY code to Zero + React.
16
16
 
17
- it works with vanilla Zero and `zero-cache`. there is also a separate integration
18
- for Orez, our custom Rust sync engine. Orez-only setup and APIs are labeled below.
17
+ it uses vanilla Zero and `zero-cache` by default. an experimental Orez Lite path
18
+ is noted separately at the end of setup.
19
19
 
20
20
  it provides a few things:
21
21
 
@@ -27,25 +27,23 @@ it provides a few things:
27
27
 
28
28
  plus various hooks and helpers for react integration.
29
29
 
30
- mutations live in `mutations/` with their permissions. queries are just
31
- functions that use a global `zql` builder. schema is derived from drizzle.
30
+ each namespace is either one file exporting its queries and mutations, or a
31
+ folder with `queries.ts` and `mutations.ts`. queries use the global `zql`
32
+ builder. schema is derived from drizzle.
32
33
 
33
34
  ## queries
34
35
 
35
36
  write plain functions. they become synced queries automatically.
36
37
 
37
38
  ```ts
38
- // src/data/queries/notification.ts
39
+ // src/data/notification/queries.ts
39
40
  import { zql, serverWhere } from 'on-zero'
40
41
 
41
42
  const permission = serverWhere('notification', (q, auth) => {
42
43
  return q.cmp('userId', auth?.id || '')
43
44
  })
44
45
 
45
- export const latestNotifications = (props: {
46
- userId: string
47
- serverId: string
48
- }) => {
46
+ export const latestNotifications = (props: { userId: string; serverId: string }) => {
49
47
  return zql.notification
50
48
  .where(permission)
51
49
  .where('userId', props.userId)
@@ -78,10 +76,8 @@ const permission = serverWhere('channel', (q, auth) => {
78
76
  q.cmp('deleted', '!=', true),
79
77
  q.or(
80
78
  q.cmp('private', false),
81
- q.exists('role', (r) =>
82
- r.whereExists('member', (m) => m.where('id', auth?.id)),
83
- ),
84
- ),
79
+ q.exists('role', (r) => r.whereExists('member', (m) => m.where('id', auth?.id)))
80
+ )
85
81
  )
86
82
  })
87
83
  ```
@@ -103,7 +99,7 @@ mutations co-locate permissions and mutation handlers in one file. schema is
103
99
  derived from drizzle — no need to define it here.
104
100
 
105
101
  ```ts
106
- // src/data/mutations/message.ts
102
+ // src/data/message/mutations.ts
107
103
  import { ensureLoggedIn, mutations, serverWhere } from 'on-zero'
108
104
 
109
105
  const permissions = serverWhere('message', (q, auth) => {
@@ -114,7 +110,7 @@ const permissions = serverWhere('message', (q, auth) => {
114
110
  export const mutate = mutations('message', permissions, {
115
111
  async send(
116
112
  ctx,
117
- props: { id: string; content: string; channelId: string; createdAt: number },
113
+ props: { id: string; content: string; channelId: string; createdAt: number }
118
114
  ) {
119
115
  const auth = ensureLoggedIn()
120
116
 
@@ -180,7 +176,7 @@ export const permissions = serverWhere('channel', (q, auth) => {
180
176
 
181
177
  return q.or(
182
178
  q.cmp('public', true),
183
- q.exists('members', (m) => m.where('userId', auth?.id)),
179
+ q.exists('members', (m) => m.where('userId', auth?.id))
184
180
  )
185
181
  })
186
182
  ```
@@ -191,7 +187,7 @@ server-side - on the client they automatically pass.
191
187
  **for queries:** define permissions inline as a constant in query files:
192
188
 
193
189
  ```ts
194
- // src/data/queries/channel.ts
190
+ // src/data/channel/queries.ts
195
191
  const permission = serverWhere('channel', (q, auth) => {
196
192
  return q.cmp('userId', auth?.id || '')
197
193
  })
@@ -204,7 +200,7 @@ export const myChannels = () => {
204
200
  **for mutations:** define permissions in mutation files for CRUD operations:
205
201
 
206
202
  ```ts
207
- // src/data/mutations/message.ts
203
+ // src/data/message/mutations.ts
208
204
  const permissions = serverWhere('message', (q, auth) => {
209
205
  return q.cmp('authorId', auth?.id || '')
210
206
  })
@@ -239,8 +235,9 @@ type RelatedToServer = 'role' | 'channel' | 'message'
239
235
  export const hasServerAdminPermission = serverWhere<RelatedToServer>((_, auth) =>
240
236
  _.exists('server', (q) =>
241
237
  q.whereExists('role', (r) =>
242
- r.where('canAdmin', true)
243
- .whereExists('member', (m) => m.where('id', auth?.id || ''))
238
+ r
239
+ .where('canAdmin', true)
240
+ .whereExists('member', (m) => m.where('id', auth?.id || ''))
244
241
  )
245
242
  )
246
243
  )
@@ -289,9 +286,7 @@ use in queries:
289
286
  import { hasChannelReadPermission } from '../where/channel'
290
287
 
291
288
  export const channelMessages = (props: { channelId: string }) => {
292
- return zql.message
293
- .where(hasChannelReadPermission)
294
- .where('channelId', props.channelId)
289
+ return zql.message.where(hasChannelReadPermission).where('channelId', props.channelId)
295
290
  }
296
291
  ```
297
292
 
@@ -311,7 +306,7 @@ export default {
311
306
  plugins: [
312
307
  onZeroPlugin(),
313
308
  // ... other plugins
314
- ]
309
+ ],
315
310
  }
316
311
  ```
317
312
 
@@ -356,8 +351,7 @@ generates all files needed to connect your mutations and queries:
356
351
 
357
352
  **options:**
358
353
 
359
- - `dir` - base directory containing `mutations/` and `queries/` folders
360
- (default: `src/data`)
354
+ - `dir` - base directory containing namespace files/folders (default: `src/data`)
361
355
  - `--watch` - watch for changes and regenerate automatically
362
356
  - `--after` - command to run after generation completes
363
357
  - `--force` - ignore cached inputs and regenerate all outputs
@@ -398,7 +392,7 @@ export type ChannelUpdate = Partial<Channel> & Pick<Channel, 'id'>
398
392
  ```ts
399
393
  import * as v from 'valibot'
400
394
  import { syncedQuery } from '@rocicorp/zero'
401
- import * as messageQueries from '../queries/message'
395
+ import * as messageQueries from '../message/queries'
402
396
 
403
397
  export const latestMessages = syncedQuery(
404
398
  'latestMessages',
@@ -408,11 +402,11 @@ export const latestMessages = syncedQuery(
408
402
  channelId: v.string(),
409
403
  limit: v.optional(v.number()),
410
404
  }),
411
- ]),
405
+ ])
412
406
  ),
413
407
  (arg) => {
414
408
  return messageQueries.latestMessages(arg)
415
- },
409
+ }
416
410
  )
417
411
  ```
418
412
 
@@ -420,8 +414,8 @@ export const latestMessages = syncedQuery(
420
414
 
421
415
  the generator:
422
416
 
423
- 1. scans `mutations/` for files with `export const mutate`
424
- 2. scans `queries/` for exported arrow functions
417
+ 1. discovers namespace files and folders, plus explicit multi-instance config
418
+ 2. derives each instance's related-table closure, mutation support tables, and scope
425
419
  3. parses TypeScript AST to extract parameter types
426
420
  4. converts types to valibot schemas
427
421
  5. wraps query functions in `syncedQuery()` with validators
@@ -430,7 +424,7 @@ the generator:
430
424
  7. generates `syncedMutations.ts` with valibot validators for mutation args
431
425
 
432
426
  when using drizzle-zero integration, `schema.ts` is generated from your drizzle
433
- schema using `generateDrizzleSchemaFile()` — it produces `table()` +
427
+ schema using `generateDrizzleSchemaFile()` — it produces `table()` +
434
428
  `relationships()` + `createSchema()` calls with full type inference.
435
429
 
436
430
  exports named `permission` are automatically skipped during query generation.
@@ -444,27 +438,37 @@ eliminates duplicate column definitions — drizzle is the single source of trut
444
438
  ```ts
445
439
  // generate-schema.ts (run at build/dev time)
446
440
  import { drizzleZeroConfig } from 'drizzle-zero'
447
- import { generateDrizzleSchemaFile } from 'on-zero'
448
- import * as drizzleSchema from './database/schema'
449
- import { relations } from './database/relations'
450
-
451
- const dzSchema = drizzleZeroConfig(
452
- { ...drizzleSchema, relations },
453
- {
454
- tables: {
455
- user: true,
456
- post: true,
457
- comment: true,
458
- },
459
- suppressDefaultsWarning: true,
460
- },
441
+ import {
442
+ deriveDataMembership,
443
+ generateDrizzleSchemaFile,
444
+ generateDrizzleSchemaInputFile,
445
+ } from 'on-zero/generate'
446
+ import * as drizzleSchema from './data/generated/drizzleSchema'
447
+
448
+ const { allTables } = await deriveDataMembership({ dir: 'src/data' })
449
+ writeFileSync(
450
+ 'src/data/generated/drizzleSchema.ts',
451
+ await generateDrizzleSchemaInputFile({
452
+ dir: 'src/data',
453
+ schemaImportPath: '../../database/schema',
454
+ })
461
455
  )
456
+ const dzSchema = drizzleZeroConfig(drizzleSchema, {
457
+ tables: Object.fromEntries(allTables.map((table) => [table, true])),
458
+ suppressDefaultsWarning: true,
459
+ })
462
460
 
463
461
  // generates a typed schema.ts with createSchema() + relationships()
464
462
  const output = generateDrizzleSchemaFile(dzSchema)
465
463
  writeFileSync('src/data/generated/schema.ts', output)
466
464
  ```
467
465
 
466
+ `allTables` includes synced tables plus fileless tables reached through static
467
+ `tx.mutate.<table>` and `tx.query.<table>` accesses in mutation modules and their
468
+ local helpers. these support tables type server pushes but do not become client
469
+ query namespaces or part of `syncTables`. the generated drizzle input filters out
470
+ relations whose source or target is outside `allTables`.
471
+
468
472
  the generated file uses zero's `table()` builder and `relationships()` function,
469
473
  giving full type inference for zql queries including nested `.related()` calls.
470
474
 
@@ -479,8 +483,7 @@ global schema type — no need to import table builders.
479
483
 
480
484
  ## setup
481
485
 
482
- there are two server paths. use vanilla Zero unless you have deliberately chosen
483
- the custom Orez engine. the client factory is shared by both paths:
486
+ the supported setup uses vanilla Zero and `zero-cache`:
484
487
 
485
488
  ```tsx
486
489
  import { createZeroClient } from 'on-zero'
@@ -514,132 +517,59 @@ transport. mount the shared client without a `transport` prop:
514
517
 
515
518
  configure `zero-cache`, `ZERO_QUERY_URL`, and `ZERO_MUTATE_URL` using the
516
519
  standard [Zero installation guide](https://zero.rocicorp.dev/docs/install).
517
- the executor bindings and client transport in the next section are not part of
518
- the vanilla Zero path.
519
-
520
- ### Orez custom Rust engine
521
-
522
- Orez is a separate server implementation. it uses the same client factory, but
523
- passes its own client transport to the provider:
524
-
525
- ```tsx
526
- import { createZeroClientTransport } from 'orez/client'
527
520
 
528
- const orezTransport = createZeroClientTransport({
529
- pullIntervalMs: 15_000,
530
- queryForward: true,
531
- })
532
-
533
- <ProvideZero
534
- cacheURL={syncOrigin}
535
- transport={orezTransport}
536
- userID={user.id}
537
- auth={sessionToken}
538
- authData={{ id: user.id, email: user.email, role: user.role }}
539
- >
540
- <App />
541
- </ProvideZero>
542
- ```
521
+ ### multiple client instances
543
522
 
544
- the following example wires the engine-agnostic on-zero server bindings to
545
- Orez:
523
+ one page can run several zero clients (e.g. a global control-plane instance
524
+ plus a per-project instance with its own storage key and sync url). add one
525
+ `on-zero.config.ts` at the data root. every instance is explicit; its `dir`
526
+ defaults to the instance key and otherwise resolves relative to the config file.
546
527
 
547
528
  ```ts
548
- import { createZeroServerBindings } from 'on-zero/server'
549
- import {
550
- createPostgreSQLApplicationDatabase,
551
- createSyncExecutor,
552
- handleSyncExecutorPushRequest,
553
- } from 'orez/sync-executor'
554
- import { syncedQueries } from '~/data/generated/syncedQueries'
555
- import { mutationValidators } from '~/data/generated/syncedMutations'
556
-
557
- export const zeroBindings = createZeroServerBindings({
558
- schema,
559
- models,
560
- queries: syncedQueries,
561
- mutations: mutationValidators,
562
- createServerActions: () => ({
563
- sendEmail: async (to, subject, body) => { ... }
564
- })
565
- })
529
+ // src/data/on-zero.config.ts
530
+ import { defineConfig } from 'on-zero'
566
531
 
567
- export const zeroExecutor = createSyncExecutor({
568
- schema,
569
- mutators: zeroBindings.mutators,
570
- database: createPostgreSQLApplicationDatabase(pool, {
571
- schema,
572
- internalSchema: 'zero_0',
573
- }),
574
- effects: {
575
- runBackground: (promise) => host.waitUntil(promise),
576
- report: (error) => console.error(error),
532
+ export default defineConfig({
533
+ instances: {
534
+ default: { dir: '.', supportTables: ['accountRepo', 'usageLedger'] },
535
+ project: { dir: './project-data', scope: 'projectId' },
577
536
  },
578
537
  })
579
-
580
- export const zeroServer = zeroBindings.server(zeroExecutor)
581
-
582
- app.post('/api/zero/push', async (request) => {
583
- const claims = await getClaimsFromRequest(request)
584
- return handleSyncExecutorPushRequest({ executor: zeroExecutor, request, claims })
585
- })
586
-
587
- app.post('/api/zero/pull', async (request) => {
588
- const authData = await getAuthFromRequest(request)
589
- return Response.json(await zeroBindings.transformQueryRequest({ authData, request }))
590
- })
591
538
  ```
592
539
 
593
- Orez owns transactions, CRUD SQL, the client ledger, replay, and effect
594
- scheduling. on-zero supplies the structural executor seam, mutator registry,
595
- auth/query helpers, and typed direct-call facade.
540
+ single-instance applications omit the config and keep namespaces directly in
541
+ the data root. multi-instance applications may keep those root namespaces by
542
+ declaring an instance with `dir: '.'`; nested instance directories remain
543
+ independently owned. `instance.ts` and `defineInstance` were removed.
596
544
 
597
- `createZeroServerBindings` is not Orez-specific. it can attach to any server
598
- implementation of the `ZeroServerExecutor` interface; Orez is the concrete
599
- executor used in this example.
545
+ generation auto-discovers the config. the cli also accepts its explicit path:
600
546
 
601
- ### multiple client instances
547
+ ```sh
548
+ on-zero generate ./src/data/on-zero.config.ts
549
+ ```
602
550
 
603
- one page can run several zero clients (e.g. a global control-plane instance
604
- plus a per-project instance with its own storage key and sync url). give each
605
- a unique `instanceName` and split queries/models so every namespace belongs to
606
- exactly one instance — duplicate claims throw at create time. then combine
607
- them into one consumer surface:
551
+ generation derives each instance's queries, models, support tables, and
552
+ sync-table closure and rejects missing or multiply claimed directories,
553
+ duplicate namespaces, missing scope columns, and cross-instance reach.
608
554
 
609
555
  ```tsx
610
- import { createZeroClient } from 'on-zero'
611
- import { combineZeroClients, createZeroClientWithDirectQueries } from 'on-zero/multi'
556
+ import { createZeroClients } from 'on-zero/multi'
557
+ import { instances } from '~/data/generated/instances'
612
558
 
613
- const control = createZeroClientWithDirectQueries({
614
- schema,
615
- models: controlModels,
616
- groupedQueries: controlQueries,
617
- instanceName: 'control',
618
- })
619
- const project = createZeroClient({
620
- schema,
621
- models: projectModels,
622
- groupedQueries: projectQueries,
623
- instanceName: 'project',
624
- })
559
+ const clients = createZeroClients(instances)
560
+ const control = clients.clients.control
561
+ const project = clients.clients.project
562
+ const ProvideControlZero = clients.providers.control
563
+ const ProvideProjectZero = clients.providers.project
625
564
 
626
565
  // useQuery/run/preload/getQuery dispatch by the query fn's namespace,
627
- // zero.mutate.<namespace> dispatches by model namespace; anything unclaimed
628
- // (and non-mutate zero access like userID) goes to the first client
629
- export const { useQuery, zero, run, preload, getQuery, zeroEvents } =
630
- combineZeroClients(control, project)
631
-
632
- // render every instance's provider. NESTING ORDER IS A CONTRACT: the LAST
633
- // client passed to combineZeroClients (or the `inner` option) must be the
634
- // INNERMOST provider — zero-react's useQuery resolves the nearest provider's
635
- // instance from context, so only the inner instance rides that path. all
636
- // other instances must opt into the context-free direct adapter through
637
- // createZeroClientWithDirectQueries.
638
- ;<control.ProvideZero cacheURL={controlUrl} userID={user.id}>
639
- <project.ProvideZero cacheURL={projectUrl} userID={`${user.id}:${projectId}`}>
566
+ // zero.mutate.<namespace> dispatches by model namespace
567
+ export const { useQuery, zero, run, preload, getQuery, zeroEvents } = clients.combined
568
+ ;<ProvideControlZero cacheURL={controlUrl} userID={user.id}>
569
+ <ProvideProjectZero cacheURL={projectUrl} userID={`${user.id}:${projectId}`}>
640
570
  <App />
641
- </project.ProvideZero>
642
- </control.ProvideZero>
571
+ </ProvideProjectZero>
572
+ </ProvideControlZero>
643
573
  ```
644
574
 
645
575
  constraints:
@@ -647,8 +577,7 @@ constraints:
647
577
  - each instance needs its own client-group identity (separate `userID` /
648
578
  storage key / cache url) — never swap the backing namespace under a live
649
579
  instance.
650
- - most apps should use plain `createZeroClient`; the `on-zero/multi` entrypoint
651
- is only for this nested-provider edge case.
580
+ - single-instance apps can keep using plain `createZeroClient`.
652
581
  - give the INNER slot to the instance owning the bulk of the subscriptions —
653
582
  inner queries use zero-react's native context path. outer instances use the
654
583
  direct adapter on their own mounted zero, so keep those instances on bounded,
@@ -656,35 +585,11 @@ constraints:
656
585
  - a mutator may only read/write tables owned by its own instance. its
657
586
  transaction runs on that instance alone; cross-instance writes are not
658
587
  detectable at registration and will silently miss the other store.
659
- - multiple clients do not mix server paths: keep using either the vanilla Zero
660
- backend or the Orez backend selected above.
661
588
  - omitting `instanceName` keeps the exact single-instance behavior.
662
589
 
663
- **guarding the partition against drift.** a generated namespace that ends up in
664
- NEITHER instance's split silently un-registers its queries (a `useQuery` then
665
- throws "query not registered" at runtime, error-boundarying a whole screen). run
666
- `assertZeroInstancePartition` at module eval over each split so the drift is a
667
- boot throw instead — it also catches a namespace listed in more than one
668
- partition:
669
-
670
- ```ts
671
- import { assertZeroInstancePartition } from 'on-zero/multi'
672
-
673
- assertZeroInstancePartition('query namespace', groupedQueries, {
674
- control: controlQueries,
675
- project: projectQueries,
676
- })
677
- assertZeroInstancePartition('model namespace', models, {
678
- control: controlModels,
679
- project: projectModels,
680
- })
681
- ```
682
-
683
590
  ### server validation hooks
684
591
 
685
- the validation hooks belong to the engine-agnostic on-zero server bindings. add
686
- custom validation for all queries and mutations before attaching the bindings
687
- to your server executor:
592
+ add custom validation for all queries and mutations:
688
593
 
689
594
  ```ts
690
595
  export const zeroBindings = createZeroServerBindings({
@@ -720,8 +625,7 @@ export const zeroBindings = createZeroServerBindings({
720
625
  ### mutation arg validation
721
626
 
722
627
  on-zero can auto-generate valibot validators for all mutation arguments. the
723
- validators belong to the server bindings rather than a particular executor.
724
- the generator uses the TypeScript type checker to deeply resolve param types -
628
+ generator uses the TypeScript type checker to deeply resolve param types -
725
629
  including imported types, aliases, and cross-file references - then converts them
726
630
  to valibot schemas.
727
631
 
@@ -783,6 +687,11 @@ declare module 'on-zero' {
783
687
  }
784
688
  ```
785
689
 
690
+ ### Orez Lite (experimental)
691
+
692
+ Orez Lite is our custom Rust engine and a separate alternative to vanilla Zero.
693
+ it is still pre-alpha, so its setup is intentionally not documented here yet.
694
+
786
695
  ## mutation context
787
696
 
788
697
  every mutation receives `MutatorContext` as first argument:
@@ -796,6 +705,7 @@ type MutatorContext = {
796
705
  server?: {
797
706
  actions: ServerActions // async server functions
798
707
  enqueueTask(task: AsyncTask, opts?: { barrier?: boolean }): void
708
+ enqueueAction(action: AsyncAction, opts?: { barrier?: boolean }): void
799
709
  }
800
710
  }
801
711
  ```
@@ -827,6 +737,64 @@ response by default. Pass `{ barrier: true }` only when the client's next writes
827
737
  depend on the effect, such as provisioning a namespace before the client writes
828
738
  through a new Zero instance.
829
739
 
740
+ ### typed async actions
741
+
742
+ for effects that may need to cross a worker or service-binding boundary, augment
743
+ `Config.asyncAction` with a discriminated union and configure one executor on the
744
+ server bindings:
745
+
746
+ ```ts
747
+ type AppAction =
748
+ | { type: 'project.provisionNamespace'; projectId: string; userId: string }
749
+ | { type: 'project.invalidateAccess'; projectId: string }
750
+
751
+ declare module 'on-zero' {
752
+ interface Config {
753
+ asyncAction: AppAction
754
+ }
755
+ }
756
+
757
+ const zeroBindings = createZeroServerBindings({
758
+ schema,
759
+ models,
760
+ createServerActions,
761
+ actions: {
762
+ execute: executeAppAction,
763
+ // when this runtime cannot execute app effects locally, inject a remote
764
+ // dispatcher. it becomes the only route; a failure never runs locally too.
765
+ dispatchRemote,
766
+ },
767
+ })
768
+ ```
769
+
770
+ mutators call `ctx.server?.enqueueAction(action, { barrier })`. on-zero schedules
771
+ it through the same post-commit task mechanism as `enqueueTask`, preserving the
772
+ barrier and auth scope without a global dispatcher.
773
+
774
+ ### awaiting and queueing mutations
775
+
776
+ each `createZeroClient` result owns settlement helpers and one serial background
777
+ queue:
778
+
779
+ ```ts
780
+ await client.awaitMutationClient(client.zero.mutate.note.update(note), 'save note')
781
+ await client.awaitMutationServer(client.zero.mutate.note.insert(note), 'create note')
782
+
783
+ void client.enqueueBackgroundMutation(
784
+ 'stream note',
785
+ () => client.zero.mutate.note.update(note),
786
+ { coalesceKey: `note:${note.id}` }
787
+ )
788
+ ```
789
+
790
+ the queue settles the client commit by default; use `settle: 'server'` only when
791
+ later work requires the authoritative server row. same-key work that has not
792
+ started is superseded by the newest write. recovery and instance replacement
793
+ fence queued and in-flight work internally. direct settlement rejects with
794
+ `StaleGenerationError`; the best-effort background queue drops that condition
795
+ quietly. `MutationTimeoutError`, `MutationResultError`, and
796
+ `mutationErrorMessage()` expose typed failure details.
797
+
830
798
  ## getAuth
831
799
 
832
800
  `getAuth()` returns the current user's auth data. works inside both queries and
@@ -854,33 +822,6 @@ import { ensureAuth } from 'on-zero'
854
822
  const auth = ensureAuth() // AuthData (throws if not authenticated)
855
823
  ```
856
824
 
857
- ## custom client transport lifecycle
858
-
859
- vanilla Zero uses Zero's built-in WebSocket transport and does not pass a
860
- `transport` prop. Orez uses this extension point for its custom transport.
861
-
862
- pass the transport plugin to the provider so transport installation and Zero
863
- instance creation share one owner. on-zero only calls its `install(serverURL)`
864
- method:
865
-
866
- ```tsx
867
- <client.ProvideZero
868
- cacheURL={syncOrigin}
869
- transport={transport}
870
- >
871
- {children}
872
- </client.ProvideZero>
873
- ```
874
-
875
- The provider installs the plugin before constructing Zero, including after an
876
- instance rotation. The plugin owns its own idempotence and conflict behavior.
877
-
878
- Imperative consumers can call `client.waitForZero()` to await the provider's
879
- active instance without polling the throwing `client.zero` facade. Pass an
880
- `AbortSignal` when the wait belongs to a component effect.
881
-
882
- Transport-specific lifecycle events and logging belong to the selected plugin.
883
-
884
825
  ## recovery
885
826
 
886
827
  on-zero self-heals a client whose local sync state is lost or rejected. this is
@@ -905,9 +846,9 @@ drops the affected instance's local store and reloads the page ONCE. this covers
905
846
  `…LastMutationID`, `ClientNotFound`, `connection userID mismatch`. these
906
847
  surface only through the error log, so the log sink recovers on them too.
907
848
 
908
- genuinely app-infra signatures (your own synthesized ack-timeout marker, a
909
- cold-boot connect timeout) are NOT in this list keep those app-side and use
910
- `benignLogFilter` to stop them from tripping recovery.
849
+ two consecutive server acknowledgement timeouts also recover by default. one
850
+ timeout remains a normal slow-server failure. configure the threshold with
851
+ `serverAckTimeoutRecoveryThreshold` on `createZeroClient`.
911
852
 
912
853
  ### the hooks (all optional props on `ProvideZero`)
913
854
 
@@ -936,9 +877,10 @@ cold-boot connect timeout) are NOT in this list — keep those app-side and use
936
877
  (e.g. wait for the dev origin to come back so the reload doesn't hit a
937
878
  restarting server). composes with `scheduleReload`.
938
879
 
939
- - **`benignLogFilter?: (message) => boolean`** return `true` for a classified
940
- recovery log you want treated as benign so it does NOT recover (your app's
941
- cold-boot timeout, say). only affects recovery; the log still reaches the sink.
880
+ - **`benignLogPatterns?: readonly (string | RegExp)[]`**: classified recovery
881
+ logs matching one of these patterns remain benign. a client transport can
882
+ provide its own patterns through `transport.logClassifications.benign`; app and
883
+ transport patterns are combined. the log still reaches the sink.
942
884
 
943
885
  - **`refreshAuth?: () => Promise<string | undefined>`** — called when the
944
886
  connection enters `needs-auth` (an expired token). return a fresh token and
@@ -953,6 +895,11 @@ cold-boot connect timeout) are NOT in this list — keep those app-side and use
953
895
  `zeroReason`, `zeroCacheUrl`) for e2e/diagnostics. enable on ONE instance so
954
896
  multiple instances don't clobber the dataset.
955
897
 
898
+ `zeroEvents` always carries a typed `reasonKey`. recovery events use
899
+ `ZeroRecoveryReasonKey`; connection errors use `connection-error` or
900
+ `connection-needs-auth`, so consumers can switch on stable keys instead of
901
+ matching message strings.
902
+
956
903
  ### guard + latch semantics
957
904
 
958
905
  - a **per-reason guard** (60s window) means the SAME reason re-failing right
@@ -991,15 +938,11 @@ instead of surfacing a fatal error, deduped per reason. no configuration.
991
938
 
992
939
  **server-only mutations:**
993
940
 
994
- server-only mutations are available whenever the on-zero server bindings are
995
- attached to an executor. they are not specific to Orez:
996
-
997
941
  ```ts
998
942
  await zeroServer.mutate.user.insert(user)
999
943
 
1000
944
  // with explicit auth (optional - authData auto-resolves from context)
1001
945
  await zeroServer.mutate.user.insert(user, { authData: { id: userId, email } })
1002
-
1003
946
  ```
1004
947
 
1005
948
  the second argument is an options object:
@@ -1018,7 +961,7 @@ run a query once without subscribing. works on both client and server:
1018
961
 
1019
962
  ```ts
1020
963
  import { run } from 'on-zero'
1021
- import { userById } from '~/data/queries/user'
964
+ import { userById } from '~/data/user/queries'
1022
965
 
1023
966
  // with params - defaults to cache only on client
1024
967
  const user = await run(userById, { id: userId })
@@ -1045,7 +988,7 @@ use `getQuery` when you need the raw zero query object rather than subscribing v
1045
988
 
1046
989
  ```ts
1047
990
  import { getQuery } from '~/zero/client'
1048
- import { postById } from '~/data/queries/post'
991
+ import { postById } from '~/data/post/queries'
1049
992
 
1050
993
  // returns the zero query object — same as what useQuery resolves internally
1051
994
  const query = getQuery(postById, { postId: '123' })
@@ -1062,7 +1005,7 @@ preload query results into cache without subscribing:
1062
1005
 
1063
1006
  ```ts
1064
1007
  import { preload } from '~/zero/client'
1065
- import { userNotifications } from '~/data/queries/notification'
1008
+ import { userNotifications } from '~/data/notification/queries'
1066
1009
 
1067
1010
  // preload after login
1068
1011
  const { complete, cleanup } = preload(userNotifications, { userId, limit: 100 })
@@ -1076,13 +1019,11 @@ useful for prefetching data before navigation to avoid loading states.
1076
1019
 
1077
1020
  **server-only queries:**
1078
1021
 
1079
- like server-only mutations, these use the attached server executor and are not
1080
- specific to Orez. for ad-hoc queries that don't use query functions:
1022
+ for ad-hoc queries that don't use query functions:
1081
1023
 
1082
1024
  ```ts
1083
- const user = await zeroServer.query(
1084
- { userID: userId },
1085
- (q) => q.user.where('id', userId).one(),
1025
+ const user = await zeroServer.query({ userID: userId }, (q) =>
1026
+ q.user.where('id', userId).one()
1086
1027
  )
1087
1028
  ```
1088
1029
 
@@ -1131,6 +1072,6 @@ await batchQuery(
1131
1072
  await processMessage(msg)
1132
1073
  }
1133
1074
  },
1134
- { chunk: 100, pause: 50 },
1075
+ { chunk: 100, pause: 50 }
1135
1076
  )
1136
1077
  ```