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
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { ZeroEvent } from '../types'
|
|
3
|
-
import type { UpdateNeededReason } from '@rocicorp/zero'
|
|
1
|
+
import type { ZeroEventsEmitter, ZeroRecoveryReasonKey } from '../types'
|
|
4
2
|
import type { Context, LogLevel, LogSink } from '@rocicorp/logger'
|
|
3
|
+
import type { UpdateNeededReason } from '@rocicorp/zero'
|
|
5
4
|
|
|
6
5
|
// per-reason guard window: the SAME reason re-failing right after its reload is
|
|
7
6
|
// surfaced as fatal instead of reload-storming on something the reload can't fix.
|
|
@@ -24,22 +23,21 @@ const STORE_CLOSED = 'Store is closed'
|
|
|
24
23
|
const STORE_CLOSED_REPEAT_MIN_MS = 2_000
|
|
25
24
|
const STORE_CLOSED_REPEAT_MAX_MS = 60_000
|
|
26
25
|
|
|
27
|
-
export type ZeroRecoveryLogReason =
|
|
28
|
-
| 'indexeddb-not-found'
|
|
29
|
-
| 'sqlite-statement-finalized'
|
|
30
|
-
| 'store-closed-repeat'
|
|
31
|
-
| 'mutation-desync'
|
|
32
|
-
| 'connection-cookie-invalid'
|
|
33
|
-
| 'client-not-found'
|
|
34
|
-
| 'connection-userid-mismatch'
|
|
35
|
-
|
|
36
26
|
export type ZeroRecoveryLogClassification = {
|
|
37
|
-
|
|
38
|
-
|
|
27
|
+
reasonKey: Exclude<
|
|
28
|
+
ZeroRecoveryReasonKey,
|
|
29
|
+
| 'NewClientGroup'
|
|
30
|
+
| 'VersionNotSupported'
|
|
31
|
+
| 'SchemaVersionNotSupported'
|
|
32
|
+
| 'client-state-not-found'
|
|
33
|
+
| 'server-ack-timeout'
|
|
34
|
+
>
|
|
39
35
|
message: string
|
|
40
36
|
dropLocalState: boolean
|
|
41
37
|
}
|
|
42
38
|
|
|
39
|
+
export type ZeroLogPattern = string | RegExp
|
|
40
|
+
|
|
43
41
|
// a minimal synchronous key/value store the cross-reload guard persists into.
|
|
44
42
|
// web defaults to sessionStorage; native (Hermes) has none, so a consumer can
|
|
45
43
|
// inject an MMKV/sqlite-backed store to get cross-reload loop protection — the
|
|
@@ -54,7 +52,7 @@ export type RecoveryGuardStorage = {
|
|
|
54
52
|
// expo-updates reload) while still driving the SAME deletes-then-reload work.
|
|
55
53
|
export type ScheduleReloadContext = {
|
|
56
54
|
reason: string
|
|
57
|
-
reasonKey:
|
|
55
|
+
reasonKey: ZeroRecoveryReasonKey
|
|
58
56
|
dropLocalState: boolean
|
|
59
57
|
// deletes every affected instance's local store, awaits beforeReload, then
|
|
60
58
|
// reloads. idempotent — safe to call once the consumer decides to proceed.
|
|
@@ -67,7 +65,7 @@ export type ZeroRecoveryDeps = {
|
|
|
67
65
|
// EVERY underlying store; the latch below keeps it to one reload.
|
|
68
66
|
deleteLocalState: () => Promise<unknown>
|
|
69
67
|
// recovery lifecycle for consumers (preview postMessage, toast, …).
|
|
70
|
-
zeroEvents:
|
|
68
|
+
zeroEvents: ZeroEventsEmitter
|
|
71
69
|
// awaited before the reload — e.g. wait for the dev origin to come back so the
|
|
72
70
|
// reload doesn't land on a restarting server. optional.
|
|
73
71
|
beforeReload?: () => Promise<void>
|
|
@@ -78,9 +76,11 @@ export type ZeroRecoveryDeps = {
|
|
|
78
76
|
// cross-reload guard backing store (defaults to sessionStorage on web). inject
|
|
79
77
|
// a native KV so Hermes gets real cross-reload loop protection.
|
|
80
78
|
guardStorage?: RecoveryGuardStorage
|
|
81
|
-
//
|
|
82
|
-
|
|
83
|
-
|
|
79
|
+
// classified transport/app messages that are expected and must not recover.
|
|
80
|
+
benignLogPatterns?: readonly ZeroLogPattern[]
|
|
81
|
+
// internal lifecycle fence. recovery invalidates queued and in-flight work
|
|
82
|
+
// before the consumer can defer the reload.
|
|
83
|
+
onRecovery?: (reasonKey: ZeroRecoveryReasonKey) => void
|
|
84
84
|
// injectable for tests; defaults to a real page reload.
|
|
85
85
|
reload?: () => void
|
|
86
86
|
}
|
|
@@ -117,8 +117,8 @@ function defaultGuardStorage(): RecoveryGuardStorage | undefined {
|
|
|
117
117
|
// survives the reload, so a reason that reloaded then immediately re-fires is
|
|
118
118
|
// caught as a genuine fatal instead of reload-storming across loads.
|
|
119
119
|
function recoveryGuardOpen(
|
|
120
|
-
reasonKey:
|
|
121
|
-
guardStorage: RecoveryGuardStorage | undefined
|
|
120
|
+
reasonKey: ZeroRecoveryReasonKey,
|
|
121
|
+
guardStorage: RecoveryGuardStorage | undefined
|
|
122
122
|
): boolean {
|
|
123
123
|
const key = `on-zero-recover-${reasonKey}`
|
|
124
124
|
const now = Date.now()
|
|
@@ -207,11 +207,12 @@ function performReload(deps: ZeroRecoveryDeps): Promise<void> {
|
|
|
207
207
|
|
|
208
208
|
function recover(
|
|
209
209
|
deps: ZeroRecoveryDeps,
|
|
210
|
-
reasonKey:
|
|
210
|
+
reasonKey: ZeroRecoveryReasonKey,
|
|
211
211
|
message: string,
|
|
212
|
-
dropLocalState: boolean
|
|
212
|
+
dropLocalState: boolean
|
|
213
213
|
): void {
|
|
214
214
|
if (typeof window === 'undefined') return
|
|
215
|
+
deps.onRecovery?.(reasonKey)
|
|
215
216
|
// each affected instance drops its OWN stale store, even when a reload is
|
|
216
217
|
// already queued — otherwise a sibling's store survives the reload and
|
|
217
218
|
// fatal-loops on the next boot. the single scheduled reload awaits these.
|
|
@@ -222,13 +223,13 @@ function recover(
|
|
|
222
223
|
if (reloadScheduled) return
|
|
223
224
|
if (!recoveryGuardOpen(reasonKey, deps.guardStorage)) {
|
|
224
225
|
console.error(`[on-zero] ${message} — already recovered once, not reloading`)
|
|
225
|
-
deps.zeroEvents.emit({ type: 'fatal', reason: message })
|
|
226
|
+
deps.zeroEvents.emit({ type: 'fatal', reasonKey, reason: message })
|
|
226
227
|
return
|
|
227
228
|
}
|
|
228
229
|
reloadScheduled = true
|
|
229
230
|
armReloadLatchTimeout()
|
|
230
231
|
console.warn(`[on-zero] ${message} — recovering`)
|
|
231
|
-
deps.zeroEvents.emit({ type: 'recovering', reason: message })
|
|
232
|
+
deps.zeroEvents.emit({ type: 'recovering', reasonKey, reason: message })
|
|
232
233
|
|
|
233
234
|
const runReload = () => performReload(deps)
|
|
234
235
|
if (deps.scheduleReload) {
|
|
@@ -261,7 +262,7 @@ export function makeZeroRecovery(deps: ZeroRecoveryDeps) {
|
|
|
261
262
|
deps,
|
|
262
263
|
reason.type,
|
|
263
264
|
`update needed (${reason.message || reason.type})`,
|
|
264
|
-
dropLocalState
|
|
265
|
+
dropLocalState
|
|
265
266
|
)
|
|
266
267
|
},
|
|
267
268
|
onClientStateNotFound() {
|
|
@@ -269,6 +270,18 @@ export function makeZeroRecovery(deps: ZeroRecoveryDeps) {
|
|
|
269
270
|
// drop it and reload into a fresh client.
|
|
270
271
|
recover(deps, 'client-state-not-found', 'client state not found', true)
|
|
271
272
|
},
|
|
273
|
+
onServerAckTimeout(input: {
|
|
274
|
+
label: string
|
|
275
|
+
timeoutMs: number
|
|
276
|
+
consecutiveTimeouts: number
|
|
277
|
+
}) {
|
|
278
|
+
recover(
|
|
279
|
+
deps,
|
|
280
|
+
'server-ack-timeout',
|
|
281
|
+
`${input.label} server acknowledgement timed out ${input.consecutiveTimeouts} consecutive times (${input.timeoutMs}ms each)`,
|
|
282
|
+
true
|
|
283
|
+
)
|
|
284
|
+
},
|
|
272
285
|
}
|
|
273
286
|
}
|
|
274
287
|
|
|
@@ -311,16 +324,14 @@ function isBenignStoreClosedLog(text: string): boolean {
|
|
|
311
324
|
// the mutation/connection desync class: the local client group is out of sync
|
|
312
325
|
// with the server's last-mutation-id / cookie / client record, so the store is
|
|
313
326
|
// unusable and must be dropped + recovered. these surface only through the error
|
|
314
|
-
// log, never the structured onClientStateNotFound callback.
|
|
315
|
-
//
|
|
316
|
-
//
|
|
317
|
-
// handling.
|
|
327
|
+
// log, never the structured onClientStateNotFound callback. server acknowledgement
|
|
328
|
+
// timeouts enter through the mutation lifecycle instead of string classification;
|
|
329
|
+
// expected transport startup messages are declared through benignLogPatterns.
|
|
318
330
|
function classifyMutationDesync(
|
|
319
|
-
text: string
|
|
320
|
-
):
|
|
331
|
+
text: string
|
|
332
|
+
): Pick<ZeroRecoveryLogClassification, 'reasonKey' | 'message'> | undefined {
|
|
321
333
|
if (text.includes('sent mutation ID') && text.includes('but expected')) {
|
|
322
334
|
return {
|
|
323
|
-
reason: 'mutation-desync',
|
|
324
335
|
reasonKey: 'mutation-desync',
|
|
325
336
|
message: 'mutation id desync',
|
|
326
337
|
}
|
|
@@ -330,42 +341,36 @@ function classifyMutationDesync(
|
|
|
330
341
|
text.includes('Server reported an out-of-order mutation')
|
|
331
342
|
) {
|
|
332
343
|
return {
|
|
333
|
-
reason: 'mutation-desync',
|
|
334
344
|
reasonKey: 'mutation-desync',
|
|
335
345
|
message: 'out-of-order mutation',
|
|
336
346
|
}
|
|
337
347
|
}
|
|
338
348
|
if (text.includes('already processed')) {
|
|
339
349
|
return {
|
|
340
|
-
reason: 'mutation-desync',
|
|
341
350
|
reasonKey: 'mutation-desync',
|
|
342
351
|
message: 'mutation already processed',
|
|
343
352
|
}
|
|
344
353
|
}
|
|
345
354
|
if (text.includes('InvalidConnectionRequestLastMutationID')) {
|
|
346
355
|
return {
|
|
347
|
-
reason: 'mutation-desync',
|
|
348
356
|
reasonKey: 'mutation-desync',
|
|
349
357
|
message: 'invalid connection last mutation id',
|
|
350
358
|
}
|
|
351
359
|
}
|
|
352
360
|
if (text.includes('InvalidConnectionRequestBaseCookie')) {
|
|
353
361
|
return {
|
|
354
|
-
reason: 'connection-cookie-invalid',
|
|
355
362
|
reasonKey: 'connection-cookie-invalid',
|
|
356
363
|
message: 'invalid connection base cookie',
|
|
357
364
|
}
|
|
358
365
|
}
|
|
359
366
|
if (text.includes('ClientNotFound') || text.includes('Client not found')) {
|
|
360
367
|
return {
|
|
361
|
-
reason: 'client-not-found',
|
|
362
368
|
reasonKey: 'client-not-found',
|
|
363
369
|
message: 'client not found',
|
|
364
370
|
}
|
|
365
371
|
}
|
|
366
372
|
if (text.includes('connection userID mismatch')) {
|
|
367
373
|
return {
|
|
368
|
-
reason: 'connection-userid-mismatch',
|
|
369
374
|
reasonKey: 'connection-userid-mismatch',
|
|
370
375
|
message: 'connection user id mismatch',
|
|
371
376
|
}
|
|
@@ -376,21 +381,19 @@ function classifyMutationDesync(
|
|
|
376
381
|
export function classifyZeroRecoveryLog(
|
|
377
382
|
level: LogLevel | string,
|
|
378
383
|
args: readonly unknown[],
|
|
379
|
-
nowMs = Date.now()
|
|
384
|
+
nowMs = Date.now()
|
|
380
385
|
): ZeroRecoveryLogClassification | undefined {
|
|
381
386
|
if (level !== 'error') return undefined
|
|
382
387
|
const text = args.map(logArgText).join(' ')
|
|
383
388
|
if (text.includes(LOCAL_STORE_LOST)) {
|
|
384
389
|
return {
|
|
385
|
-
|
|
386
|
-
reasonKey: 'local-store',
|
|
390
|
+
reasonKey: 'indexeddb-not-found',
|
|
387
391
|
message: 'local store lost',
|
|
388
392
|
dropLocalState: true,
|
|
389
393
|
}
|
|
390
394
|
}
|
|
391
395
|
if (text.includes(SQLITE_ERROR_NAME) && text.includes(SQLITE_STATEMENT_FINALIZED)) {
|
|
392
396
|
return {
|
|
393
|
-
reason: 'sqlite-statement-finalized',
|
|
394
397
|
reasonKey: 'sqlite-statement-finalized',
|
|
395
398
|
message: 'sqlite statement finalized',
|
|
396
399
|
dropLocalState: true,
|
|
@@ -409,7 +412,6 @@ export function classifyZeroRecoveryLog(
|
|
|
409
412
|
nowMs - prevMs <= STORE_CLOSED_REPEAT_MAX_MS
|
|
410
413
|
) {
|
|
411
414
|
return {
|
|
412
|
-
reason: 'store-closed-repeat',
|
|
413
415
|
reasonKey: 'store-closed-repeat',
|
|
414
416
|
message: 'local store closed repeatedly',
|
|
415
417
|
dropLocalState: true,
|
|
@@ -426,7 +428,7 @@ export function classifyZeroRecoveryLog(
|
|
|
426
428
|
// consumer that owns log-based recovery isn't double-fired.
|
|
427
429
|
export function composeRecoveryLogSink(
|
|
428
430
|
deps: ZeroRecoveryDeps,
|
|
429
|
-
consumerLogSink?: LogSink
|
|
431
|
+
consumerLogSink?: LogSink
|
|
430
432
|
): LogSink {
|
|
431
433
|
const consumerFlush = consumerLogSink?.flush
|
|
432
434
|
return {
|
|
@@ -435,10 +437,9 @@ export function composeRecoveryLogSink(
|
|
|
435
437
|
else logToConsole(level, context, ...args)
|
|
436
438
|
const recovery = classifyZeroRecoveryLog(level, args)
|
|
437
439
|
if (!recovery) return
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
}
|
|
440
|
+
const text = args.map(logArgText).join(' ')
|
|
441
|
+
if (deps.benignLogPatterns?.some((pattern) => matchesLogPattern(text, pattern)))
|
|
442
|
+
return
|
|
442
443
|
recover(deps, recovery.reasonKey, recovery.message, recovery.dropLocalState)
|
|
443
444
|
},
|
|
444
445
|
// call through the consumer sink so a class-based sink keeps its `this`,
|
|
@@ -447,6 +448,12 @@ export function composeRecoveryLogSink(
|
|
|
447
448
|
}
|
|
448
449
|
}
|
|
449
450
|
|
|
451
|
+
function matchesLogPattern(message: string, pattern: ZeroLogPattern): boolean {
|
|
452
|
+
if (typeof pattern === 'string') return message.includes(pattern)
|
|
453
|
+
pattern.lastIndex = 0
|
|
454
|
+
return pattern.test(message)
|
|
455
|
+
}
|
|
456
|
+
|
|
450
457
|
// generic Zero stale-poke / stale-cookie signatures: the client's view is behind
|
|
451
458
|
// the server's snapshot cookie, which a plain reconnect resolves — this is not a
|
|
452
459
|
// fatal store-loss, so ConnectionMonitor reconnects instead of recovering.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
interface MsFunction {
|
|
2
|
+
(n: number): number
|
|
3
|
+
seconds: (n: number) => number
|
|
4
|
+
minutes: (n: number) => number
|
|
5
|
+
hours: (n: number) => number
|
|
6
|
+
days: (n: number) => number
|
|
7
|
+
weeks: (n: number) => number
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
interface SecondFunction {
|
|
11
|
+
(n: number): number
|
|
12
|
+
minutes: (n: number) => number
|
|
13
|
+
hours: (n: number) => number
|
|
14
|
+
days: (n: number) => number
|
|
15
|
+
weeks: (n: number) => number
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface MinuteFunction {
|
|
19
|
+
(n: number): number
|
|
20
|
+
hours: (n: number) => number
|
|
21
|
+
days: (n: number) => number
|
|
22
|
+
weeks: (n: number) => number
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const ms = ((n: number) => n) as MsFunction
|
|
26
|
+
ms.seconds = (n: number) => n * 1000
|
|
27
|
+
ms.minutes = (n: number) => ms.seconds(n * 60)
|
|
28
|
+
ms.hours = (n: number) => ms.minutes(n * 60)
|
|
29
|
+
ms.days = (n: number) => ms.hours(n * 24)
|
|
30
|
+
ms.weeks = (n: number) => ms.days(n * 7)
|
|
31
|
+
|
|
32
|
+
const second = ((n: number) => n) as SecondFunction
|
|
33
|
+
second.minutes = (n: number) => n * 60
|
|
34
|
+
second.hours = (n: number) => second.minutes(n * 60)
|
|
35
|
+
second.days = (n: number) => second.hours(n * 24)
|
|
36
|
+
second.weeks = (n: number) => second.days(n * 7)
|
|
37
|
+
|
|
38
|
+
const minute = ((n: number) => n * 60) as MinuteFunction
|
|
39
|
+
minute.hours = (n: number) => minute(n * 60)
|
|
40
|
+
minute.days = (n: number) => minute.hours(n * 24)
|
|
41
|
+
minute.weeks = (n: number) => minute.days(n * 7)
|
|
42
|
+
|
|
43
|
+
export const time: {
|
|
44
|
+
ms: MsFunction
|
|
45
|
+
second: SecondFunction
|
|
46
|
+
minute: MinuteFunction
|
|
47
|
+
} = {
|
|
48
|
+
ms,
|
|
49
|
+
second,
|
|
50
|
+
minute,
|
|
51
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type TupleToUnion<T extends any[]> = T[number]
|
|
@@ -53,7 +53,7 @@ function emitMutationError(error: MutationError): void {
|
|
|
53
53
|
|
|
54
54
|
function toMutationError(
|
|
55
55
|
scope: 'client' | 'server',
|
|
56
|
-
details: unknown
|
|
56
|
+
details: unknown
|
|
57
57
|
): MutationError | null {
|
|
58
58
|
if (!details || typeof details !== 'object') return null
|
|
59
59
|
const d = details as {
|
|
@@ -90,7 +90,7 @@ function rejectionToError(scope: 'client' | 'server', e: unknown): MutationError
|
|
|
90
90
|
*/
|
|
91
91
|
export function observeMutation(
|
|
92
92
|
result: MutatorResultLike,
|
|
93
|
-
onError?: (error: MutationError) => void
|
|
93
|
+
onError?: (error: MutationError) => void
|
|
94
94
|
): Promise<void> {
|
|
95
95
|
let reportedGlobal = false
|
|
96
96
|
const report = (err: MutationError | null) => {
|
|
@@ -128,7 +128,7 @@ export function observeMutation(
|
|
|
128
128
|
* transaction, not N calls — that keeps it atomic and a single state.
|
|
129
129
|
*/
|
|
130
130
|
export function useMutation<Fn extends (...args: any[]) => MutatorResultLike>(
|
|
131
|
-
mutator: Fn
|
|
131
|
+
mutator: Fn
|
|
132
132
|
): [Fn, MutationState] {
|
|
133
133
|
const [pending, setPending] = useState(false)
|
|
134
134
|
const [error, setError] = useState<MutationError | null>(null)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { getCurrentComponentStack } from '@take-out/helpers'
|
|
2
1
|
import { useEffect, useId } from 'react'
|
|
3
2
|
|
|
3
|
+
import { getCurrentComponentStack } from './getCurrentComponentStack'
|
|
4
4
|
import { prettyFormatZeroQuery } from './prettyFormatZeroQuery'
|
|
5
5
|
|
|
6
6
|
import type { Query } from '@rocicorp/zero'
|
|
@@ -42,7 +42,7 @@ export const useZeroDebug = (query: Query<any, any, any>, options: any, results:
|
|
|
42
42
|
if (shouldLog) {
|
|
43
43
|
if (COLLAPSED) {
|
|
44
44
|
console.groupCollapsed(
|
|
45
|
-
`${isPermissionQuery ? `👮♂️` : `✨`}${prettyFormatZeroQuery(query, 'minimal')}
|
|
45
|
+
`${isPermissionQuery ? `👮♂️` : `✨`}${prettyFormatZeroQuery(query, 'minimal')}`
|
|
46
46
|
)
|
|
47
47
|
console.info(id, prettyFormatZeroQuery(query, 'full'))
|
|
48
48
|
console.info('cached result', results)
|
|
@@ -80,7 +80,7 @@ export const useZeroDebug = (query: Query<any, any, any>, options: any, results:
|
|
|
80
80
|
table,
|
|
81
81
|
changeCount: history.changeCount,
|
|
82
82
|
recentAsts: history.asts,
|
|
83
|
-
}
|
|
83
|
+
}
|
|
84
84
|
)
|
|
85
85
|
}
|
|
86
86
|
}
|
package/src/index.ts
CHANGED
|
@@ -24,6 +24,7 @@ export * from './mutations'
|
|
|
24
24
|
export * from './where'
|
|
25
25
|
export * from './serverWhere'
|
|
26
26
|
export * from './zql'
|
|
27
|
+
export { defineConfig, type DataConfig, type DataInstanceConfig } from './config'
|
|
27
28
|
export { defineQuery, defineQueries } from '@rocicorp/zero'
|
|
28
29
|
|
|
29
30
|
// drizzle-zero re-exports moved to 'on-zero/drizzle' to avoid pulling
|
|
@@ -48,8 +49,19 @@ export {
|
|
|
48
49
|
composeRecoveryLogSink,
|
|
49
50
|
isRecoverableZeroStalePokeMessage,
|
|
50
51
|
type ZeroRecoveryLogClassification,
|
|
51
|
-
type ZeroRecoveryLogReason,
|
|
52
52
|
type ZeroRecoveryDeps,
|
|
53
53
|
type ScheduleReloadContext,
|
|
54
54
|
type RecoveryGuardStorage,
|
|
55
|
+
type ZeroLogPattern,
|
|
55
56
|
} from './helpers/recoverZeroClient'
|
|
57
|
+
|
|
58
|
+
export {
|
|
59
|
+
isStaleGenerationError,
|
|
60
|
+
mutationErrorMessage,
|
|
61
|
+
MutationResultError,
|
|
62
|
+
MutationTimeoutError,
|
|
63
|
+
StaleGenerationError,
|
|
64
|
+
type BackgroundMutationOptions,
|
|
65
|
+
type MutationLike,
|
|
66
|
+
type MutationPhase,
|
|
67
|
+
} from './helpers/mutationLifecycle'
|
package/src/instanceRegistry.ts
CHANGED
|
@@ -7,8 +7,9 @@
|
|
|
7
7
|
// stored via globalValue so dual-loaded module copies (cjs/esm) share one map,
|
|
8
8
|
// matching the package's other cross-module registries.
|
|
9
9
|
|
|
10
|
-
import { globalValue } from '
|
|
10
|
+
import { globalValue } from './helpers/globalValue'
|
|
11
11
|
import { getQueryName } from './queryRegistry'
|
|
12
|
+
|
|
12
13
|
import type { ZeroRunner } from './zeroRunner'
|
|
13
14
|
import type { AnyQueryRegistry } from '@rocicorp/zero'
|
|
14
15
|
|
|
@@ -23,15 +24,27 @@ export type ZeroClientInstance = {
|
|
|
23
24
|
const getInstancesByNamespace = () =>
|
|
24
25
|
globalValue<Map<string, ZeroClientInstance>>(
|
|
25
26
|
'on-zero:instances-by-namespace',
|
|
26
|
-
() => new Map()
|
|
27
|
+
() => new Map()
|
|
27
28
|
)
|
|
28
29
|
|
|
29
30
|
const getInstancesByQueryName = () =>
|
|
30
31
|
globalValue<Map<string, ZeroClientInstance>>(
|
|
31
32
|
'on-zero:instances-by-query-name',
|
|
32
|
-
() => new Map()
|
|
33
|
+
() => new Map()
|
|
33
34
|
)
|
|
34
35
|
|
|
36
|
+
export function releaseClientInstances(names: readonly string[]): void {
|
|
37
|
+
const releasing = new Set(names)
|
|
38
|
+
const instancesByNamespace = getInstancesByNamespace()
|
|
39
|
+
const instancesByQueryName = getInstancesByQueryName()
|
|
40
|
+
for (const [namespace, owner] of instancesByNamespace) {
|
|
41
|
+
if (releasing.has(owner.name)) instancesByNamespace.delete(namespace)
|
|
42
|
+
}
|
|
43
|
+
for (const [queryName, owner] of instancesByQueryName) {
|
|
44
|
+
if (releasing.has(owner.name)) instancesByQueryName.delete(queryName)
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
35
48
|
export function registerClientInstance({
|
|
36
49
|
name,
|
|
37
50
|
namespaces,
|
|
@@ -65,7 +78,7 @@ export function registerClientInstance({
|
|
|
65
78
|
if (existing) {
|
|
66
79
|
throw new Error(
|
|
67
80
|
`[on-zero] namespace '${namespace}' is already claimed by zero client instance '${existing.name}' ` +
|
|
68
|
-
`(while creating instance '${name}'). Each query/mutator namespace must belong to exactly one createZeroClient instance
|
|
81
|
+
`(while creating instance '${name}'). Each query/mutator namespace must belong to exactly one createZeroClient instance.`
|
|
69
82
|
)
|
|
70
83
|
}
|
|
71
84
|
instancesByNamespace.set(namespace, instance)
|
|
@@ -76,7 +89,7 @@ export function registerClientInstance({
|
|
|
76
89
|
if (existing) {
|
|
77
90
|
throw new Error(
|
|
78
91
|
`[on-zero] query '${queryName}' is already claimed by zero client instance '${existing.name}' ` +
|
|
79
|
-
`(while creating instance '${name}'). Each query function must belong to exactly one createZeroClient instance
|
|
92
|
+
`(while creating instance '${name}'). Each query function must belong to exactly one createZeroClient instance.`
|
|
80
93
|
)
|
|
81
94
|
}
|
|
82
95
|
instancesByQueryName.set(queryName, instance)
|
|
@@ -86,7 +99,7 @@ export function registerClientInstance({
|
|
|
86
99
|
}
|
|
87
100
|
|
|
88
101
|
export function getInstanceForNamespace(
|
|
89
|
-
namespace: string
|
|
102
|
+
namespace: string
|
|
90
103
|
): ZeroClientInstance | undefined {
|
|
91
104
|
return getInstancesByNamespace().get(namespace)
|
|
92
105
|
}
|
package/src/multi.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import { combineZeroClients } from './combineZeroClients'
|
|
2
|
+
import { createUseQueryDirect } from './createUseQueryDirect'
|
|
1
3
|
import {
|
|
2
4
|
createZeroClientInternal,
|
|
3
5
|
type DirectQueryAdapter,
|
|
4
6
|
type CreateZeroClientOptions,
|
|
5
7
|
} from './createZeroClient'
|
|
6
|
-
import {
|
|
8
|
+
import { releaseClientInstances } from './instanceRegistry'
|
|
7
9
|
|
|
8
10
|
import type { GenericModels } from './types'
|
|
9
11
|
import type { Schema as ZeroSchema } from '@rocicorp/zero'
|
|
@@ -14,7 +16,7 @@ export function createZeroClientWithDirectQueries<
|
|
|
14
16
|
Schema extends ZeroSchema,
|
|
15
17
|
Models extends GenericModels,
|
|
16
18
|
>(
|
|
17
|
-
options: CreateZeroClientOptions<Schema, Models
|
|
19
|
+
options: CreateZeroClientOptions<Schema, Models>
|
|
18
20
|
): ReturnType<typeof createZeroClientInternal<Schema, Models>> {
|
|
19
21
|
const createDirectUseQuery: DirectQueryAdapter<Schema> = createUseQueryDirect
|
|
20
22
|
return createZeroClientInternal<Schema, Models>({
|
|
@@ -23,35 +25,77 @@ export function createZeroClientWithDirectQueries<
|
|
|
23
25
|
})
|
|
24
26
|
}
|
|
25
27
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
28
|
+
export type ZeroInstanceManifestEntry<
|
|
29
|
+
Schema extends ZeroSchema = ZeroSchema,
|
|
30
|
+
Models extends GenericModels = GenericModels,
|
|
31
|
+
> = {
|
|
32
|
+
schema: Schema
|
|
33
|
+
queries: CreateZeroClientOptions<Schema, Models>['groupedQueries']
|
|
34
|
+
models: Models
|
|
35
|
+
tables: readonly string[]
|
|
36
|
+
syncTables: readonly string[]
|
|
37
|
+
supportTables: readonly string[]
|
|
38
|
+
scope: string | null
|
|
39
|
+
defaultVisibility: ((value: string) => { column: string; value: string }) | null
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
type ClientFor<Entry> =
|
|
43
|
+
Entry extends ZeroInstanceManifestEntry<infer Schema, infer Models>
|
|
44
|
+
? ReturnType<typeof createZeroClientInternal<Schema, Models>>
|
|
45
|
+
: never
|
|
46
|
+
|
|
47
|
+
type ClientMap<Instances extends Record<string, ZeroInstanceManifestEntry>> = {
|
|
48
|
+
[Name in keyof Instances]: ClientFor<Instances[Name]>
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
type ClientUnion<Instances extends Record<string, ZeroInstanceManifestEntry>> =
|
|
52
|
+
ClientMap<Instances>[keyof Instances]
|
|
53
|
+
|
|
54
|
+
export function createZeroClients<
|
|
55
|
+
const Instances extends Record<string, ZeroInstanceManifestEntry>,
|
|
56
|
+
>(instances: Instances) {
|
|
57
|
+
const names = Object.keys(instances)
|
|
58
|
+
if (names.length === 0) {
|
|
59
|
+
throw new Error('[on-zero] createZeroClients requires at least one instance')
|
|
60
|
+
}
|
|
61
|
+
if (names.includes('default')) {
|
|
62
|
+
names.splice(names.indexOf('default'), 1)
|
|
63
|
+
names.unshift('default')
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const innerName = names[names.length - 1]!
|
|
67
|
+
const clients: Record<string, ReturnType<typeof createZeroClientInternal>> = {}
|
|
68
|
+
|
|
69
|
+
// release the complete old partition atomically before any new instance
|
|
70
|
+
// claims namespaces that may have moved during hot reload.
|
|
71
|
+
releaseClientInstances(names)
|
|
72
|
+
for (const name of [...names].reverse()) {
|
|
73
|
+
const instance = instances[name]!
|
|
74
|
+
const options = {
|
|
75
|
+
schema: instance.schema,
|
|
76
|
+
models: instance.models,
|
|
77
|
+
groupedQueries: instance.queries,
|
|
78
|
+
instanceName: name,
|
|
55
79
|
}
|
|
80
|
+
clients[name] =
|
|
81
|
+
name === innerName
|
|
82
|
+
? createZeroClientInternal(options)
|
|
83
|
+
: createZeroClientWithDirectQueries(options)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const typedClients = clients as ClientMap<Instances>
|
|
87
|
+
// names is checked non-empty above. retain the union of the concrete client
|
|
88
|
+
// types so combineZeroClients can intersect every instance surface.
|
|
89
|
+
const orderedClients = names.map(
|
|
90
|
+
(name) => typedClients[name as keyof Instances]
|
|
91
|
+
) as unknown as [ClientUnion<Instances>, ...ClientUnion<Instances>[]]
|
|
92
|
+
const providers = Object.fromEntries(
|
|
93
|
+
names.map((name) => [name, clients[name]!.ProvideZero])
|
|
94
|
+
) as { [Name in keyof Instances]: ClientMap<Instances>[Name]['ProvideZero'] }
|
|
95
|
+
|
|
96
|
+
return {
|
|
97
|
+
clients: typedClients,
|
|
98
|
+
providers,
|
|
99
|
+
combined: combineZeroClients(...orderedClients),
|
|
56
100
|
}
|
|
57
101
|
}
|