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.
- package/{readme.md → README.md} +172 -231
- package/dist/cjs/cli.cjs +5 -2
- package/dist/cjs/cli.native.js +5 -2
- package/dist/cjs/cli.native.js.map +1 -1
- package/dist/cjs/combineZeroClients.cjs +2 -2
- package/dist/cjs/combineZeroClients.native.js +6 -6
- package/dist/cjs/combineZeroClients.native.js.map +1 -1
- package/dist/cjs/config.cjs +30 -0
- package/dist/cjs/config.native.js +33 -0
- package/dist/cjs/config.native.js.map +1 -0
- package/dist/cjs/createPermissions.cjs +2 -2
- package/dist/cjs/createPermissions.native.js +17 -27
- package/dist/cjs/createPermissions.native.js.map +1 -1
- package/dist/cjs/createUseQuery.cjs +3 -3
- package/dist/cjs/createUseQuery.native.js +4 -4
- package/dist/cjs/createUseQuery.native.js.map +1 -1
- package/dist/cjs/createUseQueryDirect.cjs +4 -3
- package/dist/cjs/createUseQueryDirect.native.js +14 -18
- package/dist/cjs/createUseQueryDirect.native.js.map +1 -1
- package/dist/cjs/createZeroClient.cjs +29 -9
- package/dist/cjs/createZeroClient.connection.test.cjs +11 -0
- package/dist/cjs/createZeroClient.connection.test.native.js +14 -7
- package/dist/cjs/createZeroClient.connection.test.native.js.map +1 -1
- package/dist/cjs/createZeroClient.native.js +58 -32
- package/dist/cjs/createZeroClient.native.js.map +1 -1
- package/dist/cjs/createZeroClient.recovery.test.cjs +90 -3
- package/dist/cjs/createZeroClient.recovery.test.native.js +109 -19
- package/dist/cjs/createZeroClient.recovery.test.native.js.map +1 -1
- package/dist/cjs/generate-helpers.cjs +70 -17
- package/dist/cjs/generate-helpers.native.js +110 -23
- package/dist/cjs/generate-helpers.native.js.map +1 -1
- package/dist/cjs/generate-layout.cjs +586 -0
- package/dist/cjs/generate-layout.native.js +1275 -0
- package/dist/cjs/generate-layout.native.js.map +1 -0
- package/dist/cjs/generate-lite.cjs +295 -27
- package/dist/cjs/generate-lite.native.js +854 -102
- package/dist/cjs/generate-lite.native.js.map +1 -1
- package/dist/cjs/generate-lite.test.cjs +433 -41
- package/dist/cjs/generate-lite.test.native.js +446 -41
- package/dist/cjs/generate-lite.test.native.js.map +1 -1
- package/dist/cjs/generate.cjs +172 -94
- package/dist/cjs/generate.native.js +324 -148
- package/dist/cjs/generate.native.js.map +1 -1
- package/dist/cjs/generate.test.cjs +362 -45
- package/dist/cjs/generate.test.native.js +374 -45
- package/dist/cjs/generate.test.native.js.map +1 -1
- package/dist/cjs/helpers/NullToOptional.cjs +18 -0
- package/dist/cjs/helpers/NullToOptional.native.js +21 -0
- package/dist/cjs/helpers/NullToOptional.native.js.map +1 -0
- package/dist/cjs/helpers/asyncContext.cjs +128 -0
- package/dist/cjs/helpers/asyncContext.native.js +87 -0
- package/dist/cjs/helpers/asyncContext.native.js.map +1 -0
- package/dist/cjs/helpers/batchQuery.cjs +2 -2
- package/dist/cjs/helpers/batchQuery.native.js +2 -2
- package/dist/cjs/helpers/batchQuery.native.js.map +1 -1
- package/dist/cjs/helpers/createMutators.cjs +7 -4
- package/dist/cjs/helpers/createMutators.native.js +12 -9
- package/dist/cjs/helpers/createMutators.native.js.map +1 -1
- package/dist/cjs/helpers/createMutators.test.native.js +2 -2
- package/dist/cjs/helpers/createMutators.test.native.js.map +1 -1
- package/dist/cjs/helpers/ellipsis.cjs +35 -0
- package/dist/cjs/helpers/ellipsis.native.js +38 -0
- package/dist/cjs/helpers/ellipsis.native.js.map +1 -0
- package/dist/cjs/helpers/emitter.cjs +99 -0
- package/dist/cjs/helpers/emitter.native.js +125 -0
- package/dist/cjs/helpers/emitter.native.js.map +1 -0
- package/dist/cjs/helpers/ensure.cjs +33 -0
- package/dist/cjs/helpers/ensure.native.js +37 -0
- package/dist/cjs/helpers/ensure.native.js.map +1 -0
- package/dist/cjs/helpers/ensureLoggedIn.cjs +2 -2
- package/dist/cjs/helpers/ensureLoggedIn.native.js +3 -3
- package/dist/cjs/helpers/ensureLoggedIn.native.js.map +1 -1
- package/dist/cjs/helpers/errors.cjs +40 -0
- package/dist/cjs/helpers/errors.native.js +152 -0
- package/dist/cjs/helpers/errors.native.js.map +1 -0
- package/dist/cjs/helpers/getCurrentComponentStack.cjs +71 -0
- package/dist/cjs/helpers/getCurrentComponentStack.native.js +93 -0
- package/dist/cjs/helpers/getCurrentComponentStack.native.js.map +1 -0
- package/dist/cjs/helpers/globalValue.cjs +39 -0
- package/dist/cjs/helpers/globalValue.native.js +42 -0
- package/dist/cjs/helpers/globalValue.native.js.map +1 -0
- package/dist/cjs/helpers/mapObject.cjs +36 -0
- package/dist/cjs/helpers/mapObject.native.js +39 -0
- package/dist/cjs/helpers/mapObject.native.js.map +1 -0
- package/dist/cjs/helpers/mutationLifecycle.cjs +251 -0
- package/dist/cjs/helpers/mutationLifecycle.native.js +392 -0
- package/dist/cjs/helpers/mutationLifecycle.native.js.map +1 -0
- package/dist/cjs/helpers/mutationLifecycle.test.cjs +174 -0
- package/dist/cjs/helpers/mutationLifecycle.test.native.js +182 -0
- package/dist/cjs/helpers/mutationLifecycle.test.native.js.map +1 -0
- package/dist/cjs/helpers/mutatorContext.cjs +3 -3
- package/dist/cjs/helpers/mutatorContext.native.js +5 -5
- package/dist/cjs/helpers/mutatorContext.native.js.map +1 -1
- package/dist/cjs/helpers/platform.cjs +31 -0
- package/dist/cjs/helpers/platform.native.js +33 -0
- package/dist/cjs/helpers/platform.native.js.map +1 -0
- package/dist/cjs/helpers/prettyFormatZeroQuery.cjs +2 -2
- package/dist/cjs/helpers/prettyFormatZeroQuery.native.js +7 -7
- package/dist/cjs/helpers/prettyFormatZeroQuery.native.js.map +1 -1
- package/dist/cjs/helpers/queryContext.cjs +2 -2
- package/dist/cjs/helpers/queryContext.native.js +4 -4
- package/dist/cjs/helpers/queryContext.native.js.map +1 -1
- package/dist/cjs/helpers/recoverZeroClient.cjs +14 -15
- package/dist/cjs/helpers/recoverZeroClient.native.js +26 -23
- package/dist/cjs/helpers/recoverZeroClient.native.js.map +1 -1
- package/dist/cjs/helpers/recoverZeroClient.test.cjs +10 -8
- package/dist/cjs/helpers/recoverZeroClient.test.native.js +17 -21
- package/dist/cjs/helpers/recoverZeroClient.test.native.js.map +1 -1
- package/dist/cjs/helpers/sleep.cjs +34 -0
- package/dist/cjs/helpers/sleep.native.js +39 -0
- package/dist/cjs/helpers/sleep.native.js.map +1 -0
- package/dist/cjs/helpers/time.cjs +47 -0
- package/dist/cjs/helpers/time.native.js +80 -0
- package/dist/cjs/helpers/time.native.js.map +1 -0
- package/dist/cjs/helpers/tuple.cjs +18 -0
- package/dist/cjs/helpers/tuple.native.js +21 -0
- package/dist/cjs/helpers/tuple.native.js.map +1 -0
- package/dist/cjs/helpers/useMutation.native.js +5 -5
- package/dist/cjs/helpers/useMutation.native.js.map +1 -1
- package/dist/cjs/helpers/useMutation.test.native.js +1 -1
- package/dist/cjs/helpers/useMutation.test.native.js.map +1 -1
- package/dist/cjs/helpers/useZeroDebug.cjs +2 -2
- package/dist/cjs/helpers/useZeroDebug.native.js +7 -8
- package/dist/cjs/helpers/useZeroDebug.native.js.map +1 -1
- package/dist/cjs/index.cjs +9 -1
- package/dist/cjs/index.native.js +8 -0
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/cjs/instanceRegistry.cjs +16 -4
- package/dist/cjs/instanceRegistry.native.js +56 -6
- package/dist/cjs/instanceRegistry.native.js.map +1 -1
- package/dist/cjs/multi.cjs +34 -13
- package/dist/cjs/multi.native.js +39 -17
- package/dist/cjs/multi.native.js.map +1 -1
- package/dist/cjs/multiInstance.test.cjs +6 -2
- package/dist/cjs/multiInstance.test.native.js +13 -9
- package/dist/cjs/multiInstance.test.native.js.map +1 -1
- package/dist/cjs/multiInstanceNested.test.native.js +10 -10
- package/dist/cjs/multiInstanceNested.test.native.js.map +1 -1
- package/dist/cjs/multiPartition.test.cjs +85 -36
- package/dist/cjs/multiPartition.test.native.js +102 -39
- package/dist/cjs/multiPartition.test.native.js.map +1 -1
- package/dist/cjs/mutations.cjs +2 -2
- package/dist/cjs/mutations.native.js +4 -4
- package/dist/cjs/mutations.native.js.map +1 -1
- package/dist/cjs/mutations.test.native.js +3 -3
- package/dist/cjs/mutations.test.native.js.map +1 -1
- package/dist/cjs/provideZero.hydration.test.cjs +3 -3
- package/dist/cjs/provideZero.hydration.test.native.js +4 -4
- package/dist/cjs/provideZero.hydration.test.native.js.map +1 -1
- package/dist/cjs/run.cjs +1 -1
- package/dist/cjs/run.native.js +3 -3
- package/dist/cjs/run.native.js.map +1 -1
- package/dist/cjs/server.cjs +20 -16
- package/dist/cjs/server.native.js +50 -57
- package/dist/cjs/server.native.js.map +1 -1
- package/dist/cjs/server.test.cjs +129 -6
- package/dist/cjs/server.test.native.js +141 -10
- package/dist/cjs/server.test.native.js.map +1 -1
- package/dist/cjs/serverWhere.test.native.js +3 -3
- package/dist/cjs/serverWhere.test.native.js.map +1 -1
- package/dist/cjs/state.cjs +2 -2
- package/dist/cjs/state.native.js +10 -10
- package/dist/cjs/state.native.js.map +1 -1
- package/dist/cjs/usePermission.test.native.js +3 -3
- package/dist/cjs/usePermission.test.native.js.map +1 -1
- package/dist/cjs/useQuery.empty.test.cjs +3 -3
- package/dist/cjs/useQuery.empty.test.native.js +6 -6
- package/dist/cjs/useQuery.empty.test.native.js.map +1 -1
- package/dist/cjs/useQuery.ssr.test.native.js +2 -2
- package/dist/cjs/useQuery.ssr.test.native.js.map +1 -1
- package/dist/cjs/vite-plugin.cjs +7 -8
- package/dist/cjs/vite-plugin.native.js +11 -11
- package/dist/cjs/vite-plugin.native.js.map +1 -1
- package/dist/cjs/where.cjs +3 -3
- package/dist/cjs/where.native.js +4 -4
- package/dist/cjs/where.native.js.map +1 -1
- package/dist/esm/cli.mjs +6 -3
- package/dist/esm/cli.mjs.map +1 -1
- package/dist/esm/cli.native.js +6 -3
- package/dist/esm/cli.native.js.map +1 -1
- package/dist/esm/combineZeroClients.mjs +1 -1
- package/dist/esm/combineZeroClients.mjs.map +1 -1
- package/dist/esm/combineZeroClients.native.js +5 -5
- package/dist/esm/combineZeroClients.native.js.map +1 -1
- package/dist/esm/config.mjs +5 -0
- package/dist/esm/config.mjs.map +1 -0
- package/dist/esm/config.native.js +5 -0
- package/dist/esm/config.native.js.map +1 -0
- package/dist/esm/createPermissions.mjs +1 -1
- package/dist/esm/createPermissions.mjs.map +1 -1
- package/dist/esm/createPermissions.native.js +16 -26
- package/dist/esm/createPermissions.native.js.map +1 -1
- package/dist/esm/createUseQuery.mjs +2 -2
- package/dist/esm/createUseQuery.mjs.map +1 -1
- package/dist/esm/createUseQuery.native.js +3 -3
- package/dist/esm/createUseQuery.native.js.map +1 -1
- package/dist/esm/createUseQueryDirect.mjs +2 -1
- package/dist/esm/createUseQueryDirect.mjs.map +1 -1
- package/dist/esm/createUseQueryDirect.native.js +12 -16
- package/dist/esm/createUseQueryDirect.native.js.map +1 -1
- package/dist/esm/createZeroClient.connection.test.mjs +11 -0
- package/dist/esm/createZeroClient.connection.test.mjs.map +1 -1
- package/dist/esm/createZeroClient.connection.test.native.js +14 -7
- package/dist/esm/createZeroClient.connection.test.native.js.map +1 -1
- package/dist/esm/createZeroClient.mjs +25 -5
- package/dist/esm/createZeroClient.mjs.map +1 -1
- package/dist/esm/createZeroClient.native.js +54 -28
- package/dist/esm/createZeroClient.native.js.map +1 -1
- package/dist/esm/createZeroClient.recovery.test.mjs +90 -3
- package/dist/esm/createZeroClient.recovery.test.mjs.map +1 -1
- package/dist/esm/createZeroClient.recovery.test.native.js +109 -19
- package/dist/esm/createZeroClient.recovery.test.native.js.map +1 -1
- package/dist/esm/generate-helpers.mjs +70 -18
- package/dist/esm/generate-helpers.mjs.map +1 -1
- package/dist/esm/generate-helpers.native.js +110 -24
- package/dist/esm/generate-helpers.native.js.map +1 -1
- package/dist/esm/generate-layout.mjs +560 -0
- package/dist/esm/generate-layout.mjs.map +1 -0
- package/dist/esm/generate-layout.native.js +1246 -0
- package/dist/esm/generate-layout.native.js.map +1 -0
- package/dist/esm/generate-lite.mjs +296 -28
- package/dist/esm/generate-lite.mjs.map +1 -1
- package/dist/esm/generate-lite.native.js +855 -103
- package/dist/esm/generate-lite.native.js.map +1 -1
- package/dist/esm/generate-lite.test.mjs +434 -42
- package/dist/esm/generate-lite.test.mjs.map +1 -1
- package/dist/esm/generate-lite.test.native.js +447 -42
- package/dist/esm/generate-lite.test.native.js.map +1 -1
- package/dist/esm/generate.mjs +172 -96
- package/dist/esm/generate.mjs.map +1 -1
- package/dist/esm/generate.native.js +324 -150
- package/dist/esm/generate.native.js.map +1 -1
- package/dist/esm/generate.test.mjs +366 -49
- package/dist/esm/generate.test.mjs.map +1 -1
- package/dist/esm/generate.test.native.js +378 -49
- package/dist/esm/generate.test.native.js.map +1 -1
- package/dist/esm/helpers/NullToOptional.mjs +2 -0
- package/dist/esm/helpers/NullToOptional.mjs.map +1 -0
- package/dist/esm/helpers/NullToOptional.native.js +2 -0
- package/dist/esm/helpers/NullToOptional.native.js.map +1 -0
- package/dist/esm/helpers/asyncContext.mjs +102 -0
- package/dist/esm/helpers/asyncContext.mjs.map +1 -0
- package/dist/esm/helpers/asyncContext.native.js +58 -0
- package/dist/esm/helpers/asyncContext.native.js.map +1 -0
- package/dist/esm/helpers/batchQuery.mjs +1 -1
- package/dist/esm/helpers/batchQuery.native.js +1 -1
- package/dist/esm/helpers/createMutators.mjs +5 -2
- package/dist/esm/helpers/createMutators.mjs.map +1 -1
- package/dist/esm/helpers/createMutators.native.js +10 -7
- package/dist/esm/helpers/createMutators.native.js.map +1 -1
- package/dist/esm/helpers/createMutators.test.native.js +2 -2
- package/dist/esm/helpers/createMutators.test.native.js.map +1 -1
- package/dist/esm/helpers/ellipsis.mjs +10 -0
- package/dist/esm/helpers/ellipsis.mjs.map +1 -0
- package/dist/esm/helpers/ellipsis.native.js +10 -0
- package/dist/esm/helpers/ellipsis.native.js.map +1 -0
- package/dist/esm/helpers/emitter.mjs +72 -0
- package/dist/esm/helpers/emitter.mjs.map +1 -0
- package/dist/esm/helpers/emitter.native.js +95 -0
- package/dist/esm/helpers/emitter.native.js.map +1 -0
- package/dist/esm/helpers/ensure.mjs +8 -0
- package/dist/esm/helpers/ensure.mjs.map +1 -0
- package/dist/esm/helpers/ensure.native.js +9 -0
- package/dist/esm/helpers/ensure.native.js.map +1 -0
- package/dist/esm/helpers/ensureLoggedIn.mjs +1 -1
- package/dist/esm/helpers/ensureLoggedIn.mjs.map +1 -1
- package/dist/esm/helpers/ensureLoggedIn.native.js +2 -2
- package/dist/esm/helpers/ensureLoggedIn.native.js.map +1 -1
- package/dist/esm/helpers/errors.mjs +14 -0
- package/dist/esm/helpers/errors.mjs.map +1 -0
- package/dist/esm/helpers/errors.native.js +123 -0
- package/dist/esm/helpers/errors.native.js.map +1 -0
- package/dist/esm/helpers/getCurrentComponentStack.mjs +35 -0
- package/dist/esm/helpers/getCurrentComponentStack.mjs.map +1 -0
- package/dist/esm/helpers/getCurrentComponentStack.native.js +54 -0
- package/dist/esm/helpers/getCurrentComponentStack.native.js.map +1 -0
- package/dist/esm/helpers/globalValue.mjs +14 -0
- package/dist/esm/helpers/globalValue.mjs.map +1 -0
- package/dist/esm/helpers/globalValue.native.js +14 -0
- package/dist/esm/helpers/globalValue.native.js.map +1 -0
- package/dist/esm/helpers/mapObject.mjs +11 -0
- package/dist/esm/helpers/mapObject.mjs.map +1 -0
- package/dist/esm/helpers/mapObject.native.js +11 -0
- package/dist/esm/helpers/mapObject.native.js.map +1 -0
- package/dist/esm/helpers/mutationLifecycle.mjs +221 -0
- package/dist/esm/helpers/mutationLifecycle.mjs.map +1 -0
- package/dist/esm/helpers/mutationLifecycle.native.js +359 -0
- package/dist/esm/helpers/mutationLifecycle.native.js.map +1 -0
- package/dist/esm/helpers/mutationLifecycle.test.mjs +175 -0
- package/dist/esm/helpers/mutationLifecycle.test.mjs.map +1 -0
- package/dist/esm/helpers/mutationLifecycle.test.native.js +180 -0
- package/dist/esm/helpers/mutationLifecycle.test.native.js.map +1 -0
- package/dist/esm/helpers/mutatorContext.mjs +1 -1
- package/dist/esm/helpers/mutatorContext.native.js +4 -4
- package/dist/esm/helpers/mutatorContext.native.js.map +1 -1
- package/dist/esm/helpers/platform.mjs +5 -0
- package/dist/esm/helpers/platform.mjs.map +1 -0
- package/dist/esm/helpers/platform.native.js +4 -0
- package/dist/esm/helpers/platform.native.js.map +1 -0
- package/dist/esm/helpers/prettyFormatZeroQuery.mjs +1 -1
- package/dist/esm/helpers/prettyFormatZeroQuery.native.js +6 -6
- package/dist/esm/helpers/prettyFormatZeroQuery.native.js.map +1 -1
- package/dist/esm/helpers/queryContext.mjs +1 -1
- package/dist/esm/helpers/queryContext.native.js +3 -3
- package/dist/esm/helpers/queryContext.native.js.map +1 -1
- package/dist/esm/helpers/recoverZeroClient.mjs +14 -15
- package/dist/esm/helpers/recoverZeroClient.mjs.map +1 -1
- package/dist/esm/helpers/recoverZeroClient.native.js +26 -23
- package/dist/esm/helpers/recoverZeroClient.native.js.map +1 -1
- package/dist/esm/helpers/recoverZeroClient.test.mjs +8 -6
- package/dist/esm/helpers/recoverZeroClient.test.mjs.map +1 -1
- package/dist/esm/helpers/recoverZeroClient.test.native.js +15 -19
- package/dist/esm/helpers/recoverZeroClient.test.native.js.map +1 -1
- package/dist/esm/helpers/sleep.mjs +9 -0
- package/dist/esm/helpers/sleep.mjs.map +1 -0
- package/dist/esm/helpers/sleep.native.js +11 -0
- package/dist/esm/helpers/sleep.native.js.map +1 -0
- package/dist/esm/helpers/time.mjs +22 -0
- package/dist/esm/helpers/time.mjs.map +1 -0
- package/dist/esm/helpers/time.native.js +52 -0
- package/dist/esm/helpers/time.native.js.map +1 -0
- package/dist/esm/helpers/tuple.mjs +2 -0
- package/dist/esm/helpers/tuple.mjs.map +1 -0
- package/dist/esm/helpers/tuple.native.js +2 -0
- package/dist/esm/helpers/tuple.native.js.map +1 -0
- package/dist/esm/helpers/useMutation.native.js +5 -5
- package/dist/esm/helpers/useMutation.native.js.map +1 -1
- package/dist/esm/helpers/useMutation.test.native.js +1 -1
- package/dist/esm/helpers/useMutation.test.native.js.map +1 -1
- package/dist/esm/helpers/useZeroDebug.mjs +1 -1
- package/dist/esm/helpers/useZeroDebug.mjs.map +1 -1
- package/dist/esm/helpers/useZeroDebug.native.js +6 -7
- package/dist/esm/helpers/useZeroDebug.native.js.map +1 -1
- package/dist/esm/index.js +3 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/index.mjs +3 -1
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/index.native.js +3 -1
- package/dist/esm/index.native.js.map +1 -1
- package/dist/esm/instanceRegistry.mjs +13 -2
- package/dist/esm/instanceRegistry.mjs.map +1 -1
- package/dist/esm/instanceRegistry.native.js +53 -4
- package/dist/esm/instanceRegistry.native.js.map +1 -1
- package/dist/esm/multi.mjs +33 -12
- package/dist/esm/multi.mjs.map +1 -1
- package/dist/esm/multi.native.js +38 -16
- package/dist/esm/multi.native.js.map +1 -1
- package/dist/esm/multiInstance.test.mjs +5 -1
- package/dist/esm/multiInstance.test.mjs.map +1 -1
- package/dist/esm/multiInstance.test.native.js +12 -8
- package/dist/esm/multiInstance.test.native.js.map +1 -1
- package/dist/esm/multiInstanceNested.test.native.js +10 -10
- package/dist/esm/multiInstanceNested.test.native.js.map +1 -1
- package/dist/esm/multiPartition.test.mjs +86 -37
- package/dist/esm/multiPartition.test.mjs.map +1 -1
- package/dist/esm/multiPartition.test.native.js +103 -40
- package/dist/esm/multiPartition.test.native.js.map +1 -1
- package/dist/esm/mutations.mjs +1 -1
- package/dist/esm/mutations.mjs.map +1 -1
- package/dist/esm/mutations.native.js +3 -3
- package/dist/esm/mutations.native.js.map +1 -1
- package/dist/esm/mutations.test.native.js +3 -3
- package/dist/esm/mutations.test.native.js.map +1 -1
- package/dist/esm/provideZero.hydration.test.mjs +1 -1
- package/dist/esm/provideZero.hydration.test.mjs.map +1 -1
- package/dist/esm/provideZero.hydration.test.native.js +2 -2
- package/dist/esm/provideZero.hydration.test.native.js.map +1 -1
- package/dist/esm/run.mjs +1 -1
- package/dist/esm/run.mjs.map +1 -1
- package/dist/esm/run.native.js +3 -3
- package/dist/esm/run.native.js.map +1 -1
- package/dist/esm/server.mjs +20 -15
- package/dist/esm/server.mjs.map +1 -1
- package/dist/esm/server.native.js +50 -56
- package/dist/esm/server.native.js.map +1 -1
- package/dist/esm/server.test.mjs +130 -7
- package/dist/esm/server.test.mjs.map +1 -1
- package/dist/esm/server.test.native.js +142 -11
- package/dist/esm/server.test.native.js.map +1 -1
- package/dist/esm/serverWhere.test.mjs.map +1 -1
- package/dist/esm/serverWhere.test.native.js +3 -3
- package/dist/esm/serverWhere.test.native.js.map +1 -1
- package/dist/esm/state.mjs +1 -1
- package/dist/esm/state.mjs.map +1 -1
- package/dist/esm/state.native.js +9 -9
- package/dist/esm/state.native.js.map +1 -1
- package/dist/esm/usePermission.test.native.js +3 -3
- package/dist/esm/usePermission.test.native.js.map +1 -1
- package/dist/esm/useQuery.empty.test.mjs +1 -1
- package/dist/esm/useQuery.empty.test.mjs.map +1 -1
- package/dist/esm/useQuery.empty.test.native.js +4 -4
- package/dist/esm/useQuery.empty.test.native.js.map +1 -1
- package/dist/esm/useQuery.ssr.test.native.js +2 -2
- package/dist/esm/useQuery.ssr.test.native.js.map +1 -1
- package/dist/esm/vite-plugin.mjs +7 -8
- package/dist/esm/vite-plugin.mjs.map +1 -1
- package/dist/esm/vite-plugin.native.js +11 -11
- package/dist/esm/vite-plugin.native.js.map +1 -1
- package/dist/esm/where.mjs +1 -1
- package/dist/esm/where.mjs.map +1 -1
- package/dist/esm/where.native.js +2 -2
- package/dist/esm/where.native.js.map +1 -1
- package/package.json +18 -6
- package/src/cli.ts +11 -3
- package/src/combineZeroClients.tsx +18 -10
- package/src/config.ts +72 -0
- package/src/createPermissions.ts +3 -4
- package/src/createUseQuery.tsx +8 -8
- package/src/createUseQueryDirect.tsx +11 -10
- package/src/createZeroClient.authData.test.tsx +1 -1
- package/src/createZeroClient.connection.test.tsx +13 -2
- package/src/createZeroClient.recovery.test.tsx +100 -4
- package/src/createZeroClient.tsx +87 -30
- package/src/generate-helpers.ts +108 -31
- package/src/generate-layout.ts +841 -0
- package/src/generate-lite.test.ts +421 -42
- package/src/generate-lite.ts +479 -43
- package/src/generate.test.ts +552 -90
- package/src/generate.ts +360 -163
- package/src/helpers/NullToOptional.ts +5 -0
- package/src/helpers/asyncContext.native.ts +90 -0
- package/src/helpers/asyncContext.ts +159 -0
- package/src/helpers/batchQuery.ts +2 -2
- package/src/helpers/createMutators.ts +11 -8
- package/src/helpers/ellipsis.ts +9 -0
- package/src/helpers/emitter.tsx +106 -0
- package/src/helpers/ensure.ts +10 -0
- package/src/helpers/ensureLoggedIn.ts +1 -2
- package/src/helpers/errors.ts +13 -0
- package/src/helpers/getCurrentComponentStack.ts +56 -0
- package/src/helpers/globalValue.ts +40 -0
- package/src/helpers/mapObject.ts +14 -0
- package/src/helpers/mutationLifecycle.test.ts +180 -0
- package/src/helpers/mutationLifecycle.ts +313 -0
- package/src/helpers/mutatorContext.ts +3 -3
- package/src/helpers/platform.native.ts +2 -0
- package/src/helpers/platform.ts +16 -0
- package/src/helpers/prettyFormatZeroQuery.ts +2 -2
- package/src/helpers/queryContext.ts +2 -2
- package/src/helpers/recoverZeroClient.test.ts +23 -21
- package/src/helpers/recoverZeroClient.ts +56 -49
- package/src/helpers/sleep.ts +8 -0
- package/src/helpers/time.ts +51 -0
- package/src/helpers/tuple.ts +1 -0
- package/src/helpers/useMutation.tsx +3 -3
- package/src/helpers/useZeroDebug.ts +3 -3
- package/src/index.ts +13 -1
- package/src/instanceRegistry.ts +19 -6
- package/src/multi.ts +75 -31
- package/src/multiInstance.test.tsx +31 -13
- package/src/multiInstanceNested.test.tsx +2 -2
- package/src/multiPartition.test.ts +62 -27
- package/src/mutations.ts +10 -10
- package/src/provideZero.hydration.test.tsx +1 -1
- package/src/resolveQuery.ts +2 -2
- package/src/run.ts +7 -7
- package/src/server.test.ts +117 -18
- package/src/server.ts +70 -43
- package/src/serverWhere.ts +2 -2
- package/src/state.ts +2 -2
- package/src/types.ts +47 -6
- package/src/useQuery.empty.test.tsx +3 -3
- package/src/useQuery.ssr.test.ts +1 -1
- package/src/vite-plugin.ts +12 -9
- package/src/where.ts +6 -7
- package/src/zeroRunner.ts +2 -2
- package/types/combineZeroClients.d.ts +11 -5
- package/types/combineZeroClients.d.ts.map +1 -1
- package/types/config.d.ts +62 -0
- package/types/config.d.ts.map +1 -0
- package/types/createPermissions.d.ts.map +1 -1
- package/types/createUseQuery.d.ts.map +1 -1
- package/types/createUseQueryDirect.d.ts +1 -1
- package/types/createUseQueryDirect.d.ts.map +1 -1
- package/types/createZeroClient.d.ts +22 -12
- package/types/createZeroClient.d.ts.map +1 -1
- package/types/createZeroClient.recovery.test.d.ts.map +1 -1
- package/types/generate-helpers.d.ts +17 -2
- package/types/generate-helpers.d.ts.map +1 -1
- package/types/generate-layout.d.ts +26 -0
- package/types/generate-layout.d.ts.map +1 -0
- package/types/generate-lite.d.ts +29 -1
- package/types/generate-lite.d.ts.map +1 -1
- package/types/generate.d.ts +20 -0
- package/types/generate.d.ts.map +1 -1
- package/types/helpers/NullToOptional.d.ts +6 -0
- package/types/helpers/NullToOptional.d.ts.map +1 -0
- package/types/helpers/asyncContext.d.ts +15 -0
- package/types/helpers/asyncContext.d.ts.map +1 -0
- package/types/helpers/asyncContext.native.d.ts +8 -0
- package/types/helpers/asyncContext.native.d.ts.map +1 -0
- package/types/helpers/createMutators.d.ts +2 -1
- package/types/helpers/createMutators.d.ts.map +1 -1
- package/types/helpers/ellipsis.d.ts +2 -0
- package/types/helpers/ellipsis.d.ts.map +1 -0
- package/types/helpers/emitter.d.ts +21 -0
- package/types/helpers/emitter.d.ts.map +1 -0
- package/types/helpers/ensure.d.ts +2 -0
- package/types/helpers/ensure.d.ts.map +1 -0
- package/types/helpers/ensureLoggedIn.d.ts.map +1 -1
- package/types/helpers/errors.d.ts +7 -0
- package/types/helpers/errors.d.ts.map +1 -0
- package/types/helpers/getCurrentComponentStack.d.ts +2 -0
- package/types/helpers/getCurrentComponentStack.d.ts.map +1 -0
- package/types/helpers/globalValue.d.ts +23 -0
- package/types/helpers/globalValue.d.ts.map +1 -0
- package/types/helpers/mapObject.d.ts +4 -0
- package/types/helpers/mapObject.d.ts.map +1 -0
- package/types/helpers/mutationLifecycle.d.ts +44 -0
- package/types/helpers/mutationLifecycle.d.ts.map +1 -0
- package/types/helpers/mutationLifecycle.test.d.ts +2 -0
- package/types/helpers/mutationLifecycle.test.d.ts.map +1 -0
- package/types/helpers/platform.d.ts +3 -0
- package/types/helpers/platform.d.ts.map +1 -0
- package/types/helpers/platform.native.d.ts +3 -0
- package/types/helpers/platform.native.d.ts.map +1 -0
- package/types/helpers/recoverZeroClient.d.ts +13 -9
- package/types/helpers/recoverZeroClient.d.ts.map +1 -1
- package/types/helpers/sleep.d.ts +2 -0
- package/types/helpers/sleep.d.ts.map +1 -0
- package/types/helpers/time.d.ts +28 -0
- package/types/helpers/time.d.ts.map +1 -0
- package/types/helpers/tuple.d.ts +2 -0
- package/types/helpers/tuple.d.ts.map +1 -0
- package/types/index.d.ts +3 -1
- package/types/index.d.ts.map +1 -1
- package/types/instanceRegistry.d.ts +1 -0
- package/types/instanceRegistry.d.ts.map +1 -1
- package/types/multi.d.ts +23 -1
- package/types/multi.d.ts.map +1 -1
- package/types/mutations.d.ts +1 -1
- package/types/mutations.d.ts.map +1 -1
- package/types/run.d.ts.map +1 -1
- package/types/server.d.ts +12 -8
- package/types/server.d.ts.map +1 -1
- package/types/state.d.ts +1 -1
- package/types/state.d.ts.map +1 -1
- package/types/types.d.ts +23 -1
- package/types/types.d.ts.map +1 -1
- package/types/vite-plugin.d.ts.map +1 -1
- package/types/where.d.ts.map +1 -1
- package/lint/ssr-guards.js +0 -165
- package/test-fixtures/server-return-types.ts +0 -58
- package/test-fixtures/tsconfig.json +0 -13
- package/tsconfig.json +0 -26
- package/vitest.config.ts +0 -8
package/{readme.md → README.md}
RENAMED
|
@@ -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
|
|
18
|
-
|
|
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
|
-
|
|
31
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
243
|
-
|
|
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
|
|
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
|
|
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.
|
|
424
|
-
2.
|
|
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 {
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
545
|
-
|
|
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
|
-
|
|
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
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
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
|
-
|
|
594
|
-
|
|
595
|
-
|
|
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
|
-
|
|
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
|
-
|
|
547
|
+
```sh
|
|
548
|
+
on-zero generate ./src/data/on-zero.config.ts
|
|
549
|
+
```
|
|
602
550
|
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
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 {
|
|
611
|
-
import {
|
|
556
|
+
import { createZeroClients } from 'on-zero/multi'
|
|
557
|
+
import { instances } from '~/data/generated/instances'
|
|
612
558
|
|
|
613
|
-
const
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
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
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
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
|
-
</
|
|
642
|
-
</
|
|
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
|
-
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
909
|
-
|
|
910
|
-
`
|
|
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
|
-
- **`
|
|
940
|
-
|
|
941
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
```
|