on-zero 0.0.1
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/LICENSE +21 -0
- package/cli.cjs +3 -0
- package/dist/cjs/cli.cjs +405 -0
- package/dist/cjs/cli.js +397 -0
- package/dist/cjs/cli.js.map +6 -0
- package/dist/cjs/cli.native.js +505 -0
- package/dist/cjs/cli.native.js.map +1 -0
- package/dist/cjs/constants.cjs +28 -0
- package/dist/cjs/constants.js +22 -0
- package/dist/cjs/constants.js.map +6 -0
- package/dist/cjs/constants.native.js +31 -0
- package/dist/cjs/constants.native.js.map +1 -0
- package/dist/cjs/createPermissions.cjs +82 -0
- package/dist/cjs/createPermissions.js +77 -0
- package/dist/cjs/createPermissions.js.map +6 -0
- package/dist/cjs/createPermissions.native.js +107 -0
- package/dist/cjs/createPermissions.native.js.map +1 -0
- package/dist/cjs/createUseQuery.cjs +59 -0
- package/dist/cjs/createUseQuery.js +34 -0
- package/dist/cjs/createUseQuery.js.map +6 -0
- package/dist/cjs/createUseQuery.native.js +70 -0
- package/dist/cjs/createUseQuery.native.js.map +1 -0
- package/dist/cjs/createZeroClient.cjs +162 -0
- package/dist/cjs/createZeroClient.js +126 -0
- package/dist/cjs/createZeroClient.js.map +6 -0
- package/dist/cjs/createZeroClient.native.js +214 -0
- package/dist/cjs/createZeroClient.native.js.map +1 -0
- package/dist/cjs/createZeroServer.cjs +148 -0
- package/dist/cjs/createZeroServer.js +126 -0
- package/dist/cjs/createZeroServer.js.map +6 -0
- package/dist/cjs/createZeroServer.native.js +170 -0
- package/dist/cjs/createZeroServer.native.js.map +1 -0
- package/dist/cjs/helpers/batchQuery.cjs +49 -0
- package/dist/cjs/helpers/batchQuery.js +38 -0
- package/dist/cjs/helpers/batchQuery.js.map +6 -0
- package/dist/cjs/helpers/batchQuery.native.js +49 -0
- package/dist/cjs/helpers/batchQuery.native.js.map +1 -0
- package/dist/cjs/helpers/createMutators.cjs +90 -0
- package/dist/cjs/helpers/createMutators.js +85 -0
- package/dist/cjs/helpers/createMutators.js.map +6 -0
- package/dist/cjs/helpers/createMutators.native.js +132 -0
- package/dist/cjs/helpers/createMutators.native.js.map +1 -0
- package/dist/cjs/helpers/didRunPermissionCheck.cjs +30 -0
- package/dist/cjs/helpers/didRunPermissionCheck.js +26 -0
- package/dist/cjs/helpers/didRunPermissionCheck.js.map +6 -0
- package/dist/cjs/helpers/didRunPermissionCheck.native.js +39 -0
- package/dist/cjs/helpers/didRunPermissionCheck.native.js.map +1 -0
- package/dist/cjs/helpers/ensureLoggedIn.cjs +33 -0
- package/dist/cjs/helpers/ensureLoggedIn.js +25 -0
- package/dist/cjs/helpers/ensureLoggedIn.js.map +6 -0
- package/dist/cjs/helpers/ensureLoggedIn.native.js +36 -0
- package/dist/cjs/helpers/ensureLoggedIn.native.js.map +1 -0
- package/dist/cjs/helpers/getQueryOrMutatorAuthData.cjs +30 -0
- package/dist/cjs/helpers/getQueryOrMutatorAuthData.js +24 -0
- package/dist/cjs/helpers/getQueryOrMutatorAuthData.js.map +6 -0
- package/dist/cjs/helpers/getQueryOrMutatorAuthData.native.js +33 -0
- package/dist/cjs/helpers/getQueryOrMutatorAuthData.native.js.map +1 -0
- package/dist/cjs/helpers/mutatorContext.cjs +40 -0
- package/dist/cjs/helpers/mutatorContext.js +36 -0
- package/dist/cjs/helpers/mutatorContext.js.map +6 -0
- package/dist/cjs/helpers/mutatorContext.native.js +43 -0
- package/dist/cjs/helpers/mutatorContext.native.js.map +1 -0
- package/dist/cjs/helpers/prettyFormatZeroQuery.cjs +107 -0
- package/dist/cjs/helpers/prettyFormatZeroQuery.js +92 -0
- package/dist/cjs/helpers/prettyFormatZeroQuery.js.map +6 -0
- package/dist/cjs/helpers/prettyFormatZeroQuery.native.js +119 -0
- package/dist/cjs/helpers/prettyFormatZeroQuery.native.js.map +1 -0
- package/dist/cjs/helpers/useZeroDebug.cjs +68 -0
- package/dist/cjs/helpers/useZeroDebug.js +49 -0
- package/dist/cjs/helpers/useZeroDebug.js.map +6 -0
- package/dist/cjs/helpers/useZeroDebug.native.js +81 -0
- package/dist/cjs/helpers/useZeroDebug.native.js.map +1 -0
- package/dist/cjs/index.cjs +42 -0
- package/dist/cjs/index.js +35 -0
- package/dist/cjs/index.js.map +6 -0
- package/dist/cjs/index.native.js +45 -0
- package/dist/cjs/index.native.js.map +1 -0
- package/dist/cjs/mutations.cjs +51 -0
- package/dist/cjs/mutations.js +44 -0
- package/dist/cjs/mutations.js.map +6 -0
- package/dist/cjs/mutations.native.js +56 -0
- package/dist/cjs/mutations.native.js.map +1 -0
- package/dist/cjs/queryRegistry.cjs +33 -0
- package/dist/cjs/queryRegistry.js +28 -0
- package/dist/cjs/queryRegistry.js.map +6 -0
- package/dist/cjs/queryRegistry.native.js +36 -0
- package/dist/cjs/queryRegistry.native.js.map +1 -0
- package/dist/cjs/resolveQuery.cjs +41 -0
- package/dist/cjs/resolveQuery.js +40 -0
- package/dist/cjs/resolveQuery.js.map +6 -0
- package/dist/cjs/resolveQuery.native.js +46 -0
- package/dist/cjs/resolveQuery.native.js.map +1 -0
- package/dist/cjs/run.cjs +48 -0
- package/dist/cjs/run.js +37 -0
- package/dist/cjs/run.js.map +6 -0
- package/dist/cjs/run.native.js +52 -0
- package/dist/cjs/run.native.js.map +1 -0
- package/dist/cjs/server.cjs +18 -0
- package/dist/cjs/server.js +15 -0
- package/dist/cjs/server.js.map +6 -0
- package/dist/cjs/server.native.js +21 -0
- package/dist/cjs/server.native.js.map +1 -0
- package/dist/cjs/serverWhere.cjs +29 -0
- package/dist/cjs/serverWhere.js +24 -0
- package/dist/cjs/serverWhere.js.map +6 -0
- package/dist/cjs/serverWhere.native.js +32 -0
- package/dist/cjs/serverWhere.native.js.map +1 -0
- package/dist/cjs/state.cjs +49 -0
- package/dist/cjs/state.js +37 -0
- package/dist/cjs/state.js.map +6 -0
- package/dist/cjs/state.native.js +54 -0
- package/dist/cjs/state.native.js.map +1 -0
- package/dist/cjs/types.cjs +16 -0
- package/dist/cjs/types.js +14 -0
- package/dist/cjs/types.js.map +6 -0
- package/dist/cjs/types.native.js +19 -0
- package/dist/cjs/types.native.js.map +1 -0
- package/dist/cjs/where.cjs +41 -0
- package/dist/cjs/where.js +35 -0
- package/dist/cjs/where.js.map +6 -0
- package/dist/cjs/where.native.js +46 -0
- package/dist/cjs/where.native.js.map +1 -0
- package/dist/cjs/zeroRunner.cjs +34 -0
- package/dist/cjs/zeroRunner.js +32 -0
- package/dist/cjs/zeroRunner.js.map +6 -0
- package/dist/cjs/zeroRunner.native.js +37 -0
- package/dist/cjs/zeroRunner.native.js.map +1 -0
- package/dist/cjs/zql.cjs +31 -0
- package/dist/cjs/zql.js +26 -0
- package/dist/cjs/zql.js.map +6 -0
- package/dist/cjs/zql.native.js +35 -0
- package/dist/cjs/zql.native.js.map +1 -0
- package/dist/esm/cli.js +383 -0
- package/dist/esm/cli.js.map +6 -0
- package/dist/esm/cli.mjs +384 -0
- package/dist/esm/cli.mjs.map +1 -0
- package/dist/esm/cli.native.js +481 -0
- package/dist/esm/cli.native.js.map +1 -0
- package/dist/esm/constants.js +6 -0
- package/dist/esm/constants.js.map +6 -0
- package/dist/esm/constants.mjs +4 -0
- package/dist/esm/constants.mjs.map +1 -0
- package/dist/esm/constants.native.js +4 -0
- package/dist/esm/constants.native.js.map +1 -0
- package/dist/esm/createPermissions.js +66 -0
- package/dist/esm/createPermissions.js.map +6 -0
- package/dist/esm/createPermissions.mjs +59 -0
- package/dist/esm/createPermissions.mjs.map +1 -0
- package/dist/esm/createPermissions.native.js +81 -0
- package/dist/esm/createPermissions.native.js.map +1 -0
- package/dist/esm/createUseQuery.js +21 -0
- package/dist/esm/createUseQuery.js.map +6 -0
- package/dist/esm/createUseQuery.mjs +36 -0
- package/dist/esm/createUseQuery.mjs.map +1 -0
- package/dist/esm/createUseQuery.native.js +44 -0
- package/dist/esm/createUseQuery.native.js.map +1 -0
- package/dist/esm/createZeroClient.js +135 -0
- package/dist/esm/createZeroClient.js.map +6 -0
- package/dist/esm/createZeroClient.mjs +139 -0
- package/dist/esm/createZeroClient.mjs.map +1 -0
- package/dist/esm/createZeroClient.native.js +188 -0
- package/dist/esm/createZeroClient.native.js.map +1 -0
- package/dist/esm/createZeroServer.js +121 -0
- package/dist/esm/createZeroServer.js.map +6 -0
- package/dist/esm/createZeroServer.mjs +125 -0
- package/dist/esm/createZeroServer.mjs.map +1 -0
- package/dist/esm/createZeroServer.native.js +144 -0
- package/dist/esm/createZeroServer.native.js.map +1 -0
- package/dist/esm/helpers/batchQuery.js +22 -0
- package/dist/esm/helpers/batchQuery.js.map +6 -0
- package/dist/esm/helpers/batchQuery.mjs +26 -0
- package/dist/esm/helpers/batchQuery.mjs.map +1 -0
- package/dist/esm/helpers/batchQuery.native.js +23 -0
- package/dist/esm/helpers/batchQuery.native.js.map +1 -0
- package/dist/esm/helpers/createMutators.js +71 -0
- package/dist/esm/helpers/createMutators.js.map +6 -0
- package/dist/esm/helpers/createMutators.mjs +67 -0
- package/dist/esm/helpers/createMutators.mjs.map +1 -0
- package/dist/esm/helpers/createMutators.native.js +106 -0
- package/dist/esm/helpers/createMutators.native.js.map +1 -0
- package/dist/esm/helpers/didRunPermissionCheck.js +10 -0
- package/dist/esm/helpers/didRunPermissionCheck.js.map +6 -0
- package/dist/esm/helpers/didRunPermissionCheck.mjs +6 -0
- package/dist/esm/helpers/didRunPermissionCheck.mjs.map +1 -0
- package/dist/esm/helpers/didRunPermissionCheck.native.js +12 -0
- package/dist/esm/helpers/didRunPermissionCheck.native.js.map +1 -0
- package/dist/esm/helpers/ensureLoggedIn.js +10 -0
- package/dist/esm/helpers/ensureLoggedIn.js.map +6 -0
- package/dist/esm/helpers/ensureLoggedIn.mjs +10 -0
- package/dist/esm/helpers/ensureLoggedIn.mjs.map +1 -0
- package/dist/esm/helpers/ensureLoggedIn.native.js +10 -0
- package/dist/esm/helpers/ensureLoggedIn.native.js.map +1 -0
- package/dist/esm/helpers/getQueryOrMutatorAuthData.js +9 -0
- package/dist/esm/helpers/getQueryOrMutatorAuthData.js.map +6 -0
- package/dist/esm/helpers/getQueryOrMutatorAuthData.mjs +7 -0
- package/dist/esm/helpers/getQueryOrMutatorAuthData.mjs.map +1 -0
- package/dist/esm/helpers/getQueryOrMutatorAuthData.native.js +7 -0
- package/dist/esm/helpers/getQueryOrMutatorAuthData.native.js.map +1 -0
- package/dist/esm/helpers/mutatorContext.js +20 -0
- package/dist/esm/helpers/mutatorContext.js.map +6 -0
- package/dist/esm/helpers/mutatorContext.mjs +15 -0
- package/dist/esm/helpers/mutatorContext.mjs.map +1 -0
- package/dist/esm/helpers/mutatorContext.native.js +15 -0
- package/dist/esm/helpers/mutatorContext.native.js.map +1 -0
- package/dist/esm/helpers/prettyFormatZeroQuery.js +76 -0
- package/dist/esm/helpers/prettyFormatZeroQuery.js.map +6 -0
- package/dist/esm/helpers/prettyFormatZeroQuery.mjs +84 -0
- package/dist/esm/helpers/prettyFormatZeroQuery.mjs.map +1 -0
- package/dist/esm/helpers/prettyFormatZeroQuery.native.js +93 -0
- package/dist/esm/helpers/prettyFormatZeroQuery.native.js.map +1 -0
- package/dist/esm/helpers/useZeroDebug.js +35 -0
- package/dist/esm/helpers/useZeroDebug.js.map +6 -0
- package/dist/esm/helpers/useZeroDebug.mjs +45 -0
- package/dist/esm/helpers/useZeroDebug.mjs.map +1 -0
- package/dist/esm/helpers/useZeroDebug.native.js +55 -0
- package/dist/esm/helpers/useZeroDebug.native.js.map +1 -0
- package/dist/esm/index.js +20 -0
- package/dist/esm/index.js.map +6 -0
- package/dist/esm/index.mjs +17 -0
- package/dist/esm/index.mjs.map +1 -0
- package/dist/esm/index.native.js +17 -0
- package/dist/esm/index.native.js.map +1 -0
- package/dist/esm/mutations.js +28 -0
- package/dist/esm/mutations.js.map +6 -0
- package/dist/esm/mutations.mjs +28 -0
- package/dist/esm/mutations.mjs.map +1 -0
- package/dist/esm/mutations.native.js +30 -0
- package/dist/esm/mutations.native.js.map +1 -0
- package/dist/esm/queryRegistry.js +12 -0
- package/dist/esm/queryRegistry.js.map +6 -0
- package/dist/esm/queryRegistry.mjs +9 -0
- package/dist/esm/queryRegistry.mjs.map +1 -0
- package/dist/esm/queryRegistry.native.js +9 -0
- package/dist/esm/queryRegistry.native.js.map +1 -0
- package/dist/esm/resolveQuery.js +24 -0
- package/dist/esm/resolveQuery.js.map +6 -0
- package/dist/esm/resolveQuery.mjs +18 -0
- package/dist/esm/resolveQuery.mjs.map +1 -0
- package/dist/esm/resolveQuery.native.js +20 -0
- package/dist/esm/resolveQuery.native.js.map +1 -0
- package/dist/esm/run.js +22 -0
- package/dist/esm/run.js.map +6 -0
- package/dist/esm/run.mjs +24 -0
- package/dist/esm/run.mjs.map +1 -0
- package/dist/esm/run.native.js +25 -0
- package/dist/esm/run.native.js.map +1 -0
- package/dist/esm/server.js +2 -0
- package/dist/esm/server.js.map +6 -0
- package/dist/esm/server.mjs +2 -0
- package/dist/esm/server.mjs.map +1 -0
- package/dist/esm/server.native.js +2 -0
- package/dist/esm/server.native.js.map +1 -0
- package/dist/esm/serverWhere.js +8 -0
- package/dist/esm/serverWhere.js.map +6 -0
- package/dist/esm/serverWhere.mjs +6 -0
- package/dist/esm/serverWhere.mjs.map +1 -0
- package/dist/esm/serverWhere.native.js +6 -0
- package/dist/esm/serverWhere.native.js.map +1 -0
- package/dist/esm/state.js +21 -0
- package/dist/esm/state.js.map +6 -0
- package/dist/esm/state.mjs +22 -0
- package/dist/esm/state.mjs.map +1 -0
- package/dist/esm/state.native.js +24 -0
- package/dist/esm/state.native.js.map +1 -0
- package/dist/esm/types.js +1 -0
- package/dist/esm/types.js.map +6 -0
- package/dist/esm/types.mjs +2 -0
- package/dist/esm/types.mjs.map +1 -0
- package/dist/esm/types.native.js +2 -0
- package/dist/esm/types.native.js.map +1 -0
- package/dist/esm/where.js +20 -0
- package/dist/esm/where.js.map +6 -0
- package/dist/esm/where.mjs +17 -0
- package/dist/esm/where.mjs.map +1 -0
- package/dist/esm/where.native.js +19 -0
- package/dist/esm/where.native.js.map +1 -0
- package/dist/esm/zeroRunner.js +16 -0
- package/dist/esm/zeroRunner.js.map +6 -0
- package/dist/esm/zeroRunner.mjs +10 -0
- package/dist/esm/zeroRunner.mjs.map +1 -0
- package/dist/esm/zeroRunner.native.js +10 -0
- package/dist/esm/zeroRunner.native.js.map +1 -0
- package/dist/esm/zql.js +10 -0
- package/dist/esm/zql.js.map +6 -0
- package/dist/esm/zql.mjs +8 -0
- package/dist/esm/zql.mjs.map +1 -0
- package/dist/esm/zql.native.js +9 -0
- package/dist/esm/zql.native.js.map +1 -0
- package/package.json +98 -0
- package/readme.md +594 -0
- package/src/cli.ts +626 -0
- package/src/constants.native.ts +3 -0
- package/src/constants.ts +3 -0
- package/src/createPermissions.ts +131 -0
- package/src/createUseQuery.tsx +82 -0
- package/src/createZeroClient.tsx +301 -0
- package/src/createZeroServer.ts +226 -0
- package/src/helpers/batchQuery.ts +46 -0
- package/src/helpers/createMutators.ts +138 -0
- package/src/helpers/didRunPermissionCheck.ts +16 -0
- package/src/helpers/ensureLoggedIn.ts +11 -0
- package/src/helpers/getQueryOrMutatorAuthData.ts +12 -0
- package/src/helpers/mutatorContext.ts +25 -0
- package/src/helpers/prettyFormatZeroQuery.ts +167 -0
- package/src/helpers/useZeroDebug.ts +102 -0
- package/src/index.ts +18 -0
- package/src/mutations.ts +133 -0
- package/src/queryRegistry.ts +12 -0
- package/src/resolveQuery.ts +44 -0
- package/src/run.ts +62 -0
- package/src/server.ts +1 -0
- package/src/serverWhere.ts +21 -0
- package/src/state.ts +32 -0
- package/src/types.ts +136 -0
- package/src/where.ts +58 -0
- package/src/zeroRunner.ts +28 -0
- package/src/zql.ts +10 -0
- package/types/cli.d.ts +3 -0
- package/types/cli.d.ts.map +1 -0
- package/types/constants.d.ts +3 -0
- package/types/constants.d.ts.map +1 -0
- package/types/constants.native.d.ts +3 -0
- package/types/constants.native.d.ts.map +1 -0
- package/types/createPermissions.d.ts +10 -0
- package/types/createPermissions.d.ts.map +1 -0
- package/types/createUseQuery.d.ts +20 -0
- package/types/createUseQuery.d.ts.map +1 -0
- package/types/createZeroClient.d.ts +35 -0
- package/types/createZeroClient.d.ts.map +1 -0
- package/types/createZeroServer.d.ts +146 -0
- package/types/createZeroServer.d.ts.map +1 -0
- package/types/helpers/batchQuery.d.ts +7 -0
- package/types/helpers/batchQuery.d.ts.map +1 -0
- package/types/helpers/createMutators.d.ts +10 -0
- package/types/helpers/createMutators.d.ts.map +1 -0
- package/types/helpers/didRunPermissionCheck.d.ts +4 -0
- package/types/helpers/didRunPermissionCheck.d.ts.map +1 -0
- package/types/helpers/ensureLoggedIn.d.ts +3 -0
- package/types/helpers/ensureLoggedIn.d.ts.map +1 -0
- package/types/helpers/getQueryOrMutatorAuthData.d.ts +3 -0
- package/types/helpers/getQueryOrMutatorAuthData.d.ts.map +1 -0
- package/types/helpers/mutatorContext.d.ts +5 -0
- package/types/helpers/mutatorContext.d.ts.map +1 -0
- package/types/helpers/prettyFormatZeroQuery.d.ts +3 -0
- package/types/helpers/prettyFormatZeroQuery.d.ts.map +1 -0
- package/types/helpers/useZeroDebug.d.ts +3 -0
- package/types/helpers/useZeroDebug.d.ts.map +1 -0
- package/types/index.d.ts +17 -0
- package/types/index.d.ts.map +1 -0
- package/types/mutations.d.ts +20 -0
- package/types/mutations.d.ts.map +1 -0
- package/types/queryRegistry.d.ts +3 -0
- package/types/queryRegistry.d.ts.map +1 -0
- package/types/resolveQuery.d.ts +11 -0
- package/types/resolveQuery.d.ts.map +1 -0
- package/types/run.d.ts +7 -0
- package/types/run.d.ts.map +1 -0
- package/types/server.d.ts +2 -0
- package/types/server.d.ts.map +1 -0
- package/types/serverWhere.d.ts +5 -0
- package/types/serverWhere.d.ts.map +1 -0
- package/types/state.d.ts +8 -0
- package/types/state.d.ts.map +1 -0
- package/types/types.d.ts +78 -0
- package/types/types.d.ts.map +1 -0
- package/types/where.d.ts +6 -0
- package/types/where.d.ts.map +1 -0
- package/types/zeroRunner.d.ts +6 -0
- package/types/zeroRunner.d.ts.map +1 -0
- package/types/zql.d.ts +3 -0
- package/types/zql.d.ts.map +1 -0
package/package.json
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "on-zero",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "A typed layer over @rocicorp/zero with queries, mutations, and permissions",
|
|
5
|
+
"sideEffects": false,
|
|
6
|
+
"source": "src/index.ts",
|
|
7
|
+
"main": "dist/cjs",
|
|
8
|
+
"module": "dist/esm",
|
|
9
|
+
"type": "module",
|
|
10
|
+
"types": "./types/index.d.ts",
|
|
11
|
+
"bin": {
|
|
12
|
+
"on-zero": "./cli.cjs"
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"src",
|
|
16
|
+
"types",
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"publishConfig": {
|
|
20
|
+
"access": "public"
|
|
21
|
+
},
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "git+https://github.com/onejs/on-zero.git"
|
|
25
|
+
},
|
|
26
|
+
"homepage": "https://github.com/onejs/on-zero#readme",
|
|
27
|
+
"bugs": {
|
|
28
|
+
"url": "https://github.com/onejs/on-zero/issues"
|
|
29
|
+
},
|
|
30
|
+
"keywords": [
|
|
31
|
+
"zero",
|
|
32
|
+
"rocicorp",
|
|
33
|
+
"sync",
|
|
34
|
+
"mutations",
|
|
35
|
+
"permissions",
|
|
36
|
+
"react"
|
|
37
|
+
],
|
|
38
|
+
"author": "Nate Wienert",
|
|
39
|
+
"license": "MIT",
|
|
40
|
+
"scripts": {
|
|
41
|
+
"build": "tamagui-build",
|
|
42
|
+
"watch": "tamagui-build --watch",
|
|
43
|
+
"typecheck": "tsc --noEmit",
|
|
44
|
+
"clean": "tamagui-build clean",
|
|
45
|
+
"clean:build": "tamagui-build clean:build",
|
|
46
|
+
"prepublishOnly": "bun run build",
|
|
47
|
+
"release": "bun ./scripts/release.ts"
|
|
48
|
+
},
|
|
49
|
+
"exports": {
|
|
50
|
+
"./package.json": "./package.json",
|
|
51
|
+
".": {
|
|
52
|
+
"react-native": {
|
|
53
|
+
"import": "./dist/esm/index.native.js",
|
|
54
|
+
"require": "./dist/cjs/index.native.js"
|
|
55
|
+
},
|
|
56
|
+
"types": "./types/index.d.ts",
|
|
57
|
+
"import": "./dist/esm/index.mjs",
|
|
58
|
+
"require": "./dist/cjs/index.cjs",
|
|
59
|
+
"default": "./dist/esm/index.mjs"
|
|
60
|
+
},
|
|
61
|
+
"./server": {
|
|
62
|
+
"types": "./types/server.d.ts",
|
|
63
|
+
"import": "./dist/esm/server.mjs",
|
|
64
|
+
"require": "./dist/cjs/server.cjs"
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
"dependencies": {
|
|
68
|
+
"@take-out/helpers": "^0.0.61",
|
|
69
|
+
"@sinclair/typebox": "^0.34.41",
|
|
70
|
+
"@sinclair/typebox-codegen": "^0.11.1",
|
|
71
|
+
"chokidar": "^4.0.3",
|
|
72
|
+
"citty": "^0.1.6"
|
|
73
|
+
},
|
|
74
|
+
"peerDependencies": {
|
|
75
|
+
"pg": ">=8.0.0",
|
|
76
|
+
"@rocicorp/zero": ">=0.17",
|
|
77
|
+
"react": "*",
|
|
78
|
+
"react-native": "*"
|
|
79
|
+
},
|
|
80
|
+
"peerDependenciesMeta": {
|
|
81
|
+
"react-native": {
|
|
82
|
+
"optional": true
|
|
83
|
+
},
|
|
84
|
+
"pg": {
|
|
85
|
+
"optional": true
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
"devDependencies": {
|
|
89
|
+
"@tamagui/build": "^2.0.0-rc.0",
|
|
90
|
+
"@types/node": "25.2.0",
|
|
91
|
+
"@types/pg": "^8.11.10",
|
|
92
|
+
"@types/react": "^19.0.0",
|
|
93
|
+
"react": "^19.0.0",
|
|
94
|
+
"react-native": "*",
|
|
95
|
+
"typescript": "^5.9.3",
|
|
96
|
+
"valibot": "^1.1.0"
|
|
97
|
+
}
|
|
98
|
+
}
|
package/readme.md
ADDED
|
@@ -0,0 +1,594 @@
|
|
|
1
|
+
# on-zero
|
|
2
|
+
|
|
3
|
+
<picture>
|
|
4
|
+
<source media="(prefers-color-scheme: dark)" srcset="./on-zero-dark.svg">
|
|
5
|
+
<source media="(prefers-color-scheme: light)" srcset="./on-zero.svg">
|
|
6
|
+
<img src="./on-zero.svg" width="120" alt="on-zero">
|
|
7
|
+
</picture>
|
|
8
|
+
|
|
9
|
+
makes [zero](https://zero.rocicorp.dev) really simple to use
|
|
10
|
+
|
|
11
|
+
## what it does
|
|
12
|
+
|
|
13
|
+
on-zero tries to bring Rails-like structure and DRY code to Zero + React.
|
|
14
|
+
|
|
15
|
+
it provides a few things:
|
|
16
|
+
|
|
17
|
+
- **generation** - cli with watch and generate commands
|
|
18
|
+
- **queries** - convert plain TS query functions into validated synced queries
|
|
19
|
+
- **mutations** - simply create CRUD queries with permissions
|
|
20
|
+
- **models** - standardized co-locating schema/permissions/mutations
|
|
21
|
+
- **permissions** - `serverWhere` for simple query-based permissions
|
|
22
|
+
|
|
23
|
+
plus various hooks and helpers for react integration.
|
|
24
|
+
|
|
25
|
+
models live alongside their permissions and mutations. queries are just
|
|
26
|
+
functions that use a global `zql` builder.
|
|
27
|
+
|
|
28
|
+
## queries
|
|
29
|
+
|
|
30
|
+
write plain functions. they become synced queries automatically.
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
// src/data/queries/notification.ts
|
|
34
|
+
import { zql, serverWhere } from 'on-zero'
|
|
35
|
+
|
|
36
|
+
const permission = serverWhere('notification', (q, auth) => {
|
|
37
|
+
return q.cmp('userId', auth?.id || '')
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
export const latestNotifications = (props: {
|
|
41
|
+
userId: string
|
|
42
|
+
serverId: string
|
|
43
|
+
}) => {
|
|
44
|
+
return zql.notification
|
|
45
|
+
.where(permission)
|
|
46
|
+
.where('userId', props.userId)
|
|
47
|
+
.where('serverId', props.serverId)
|
|
48
|
+
.orderBy('createdAt', 'desc')
|
|
49
|
+
.limit(20)
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
zql is just the normal Zero query builder based on your typed schema.
|
|
54
|
+
|
|
55
|
+
use them:
|
|
56
|
+
|
|
57
|
+
```tsx
|
|
58
|
+
const [data, state] = useQuery(latestNotifications, { userId, serverId })
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
the function name becomes the query name. `useQuery` detects plain functions,
|
|
62
|
+
creates a cached `SyncedQuery` per function, and calls it with your params.
|
|
63
|
+
|
|
64
|
+
### query permissions
|
|
65
|
+
|
|
66
|
+
define permissions inline using `serverWhere()`:
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
const permission = serverWhere('channel', (q, auth) => {
|
|
70
|
+
if (auth?.role === 'admin') return true
|
|
71
|
+
|
|
72
|
+
return q.and(
|
|
73
|
+
q.cmp('deleted', '!=', true),
|
|
74
|
+
q.or(
|
|
75
|
+
q.cmp('private', false),
|
|
76
|
+
q.exists('role', (r) =>
|
|
77
|
+
r.whereExists('member', (m) => m.where('id', auth?.id)),
|
|
78
|
+
),
|
|
79
|
+
),
|
|
80
|
+
)
|
|
81
|
+
})
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
then use in queries:
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
export const channelById = (props: { channelId: string }) => {
|
|
88
|
+
return zql.channel.where(permission).where('id', props.channelId).one()
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
permissions execute server-side only. on the client they automatically pass. the
|
|
93
|
+
`serverWhere()` helper automatically accesses auth data from `queryContext()` or
|
|
94
|
+
`mutatorContext()` so you don't need to pass it manually.
|
|
95
|
+
|
|
96
|
+
## models
|
|
97
|
+
|
|
98
|
+
models co-locate schema, permissions, and mutations in one file:
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
// src/data/models/message.ts
|
|
102
|
+
import { number, string, table } from '@rocicorp/zero'
|
|
103
|
+
import { mutations, serverWhere } from 'on-zero'
|
|
104
|
+
|
|
105
|
+
export const schema = table('message')
|
|
106
|
+
.columns({
|
|
107
|
+
id: string(),
|
|
108
|
+
content: string(),
|
|
109
|
+
authorId: string(),
|
|
110
|
+
channelId: string(),
|
|
111
|
+
createdAt: number(),
|
|
112
|
+
})
|
|
113
|
+
.primaryKey('id')
|
|
114
|
+
|
|
115
|
+
export const permissions = serverWhere('message', (q, auth) => {
|
|
116
|
+
return q.cmp('authorId', auth?.id || '')
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
// CRUD mutations with permissions by passing schema + permissions:
|
|
120
|
+
export const mutate = mutations(schema, permissions, {
|
|
121
|
+
async send(ctx, props: { content: string; channelId: string }) {
|
|
122
|
+
await ctx.can(permissions, props)
|
|
123
|
+
|
|
124
|
+
await ctx.tx.mutate.message.insert({
|
|
125
|
+
id: randomId(),
|
|
126
|
+
content: props.content,
|
|
127
|
+
channelId: props.channelId,
|
|
128
|
+
authorId: ctx.authData!.id,
|
|
129
|
+
createdAt: Date.now(),
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
if (ctx.server) {
|
|
133
|
+
ctx.server.asyncTasks.push(async () => {
|
|
134
|
+
await ctx.server.actions.sendNotification(props)
|
|
135
|
+
})
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
})
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
call mutations from react:
|
|
142
|
+
|
|
143
|
+
```tsx
|
|
144
|
+
await zero.mutate.message.send({ content: 'hello', channelId: 'ch-1' })
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
the second argument (`permissions`) enables auto-generated crud that checks
|
|
148
|
+
permissions:
|
|
149
|
+
|
|
150
|
+
```tsx
|
|
151
|
+
zero.mutate.message.insert(message)
|
|
152
|
+
zero.mutate.message.update(message)
|
|
153
|
+
zero.mutate.message.delete(message)
|
|
154
|
+
zero.mutate.message.upsert(message)
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## permissions
|
|
158
|
+
|
|
159
|
+
on-zero's permissions system is optional - you can implement your own
|
|
160
|
+
permission logic however you like. `serverWhere()` is a light helper for
|
|
161
|
+
RLS-style permissions that automatically integrate with queries and mutations.
|
|
162
|
+
|
|
163
|
+
permissions use the `serverWhere()` helper to create Zero `ExpressionBuilder`
|
|
164
|
+
conditions:
|
|
165
|
+
|
|
166
|
+
```ts
|
|
167
|
+
export const permissions = serverWhere('channel', (q, auth) => {
|
|
168
|
+
if (auth?.role === 'admin') return true
|
|
169
|
+
|
|
170
|
+
return q.or(
|
|
171
|
+
q.cmp('public', true),
|
|
172
|
+
q.exists('members', (m) => m.where('userId', auth?.id)),
|
|
173
|
+
)
|
|
174
|
+
})
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
the `serverWhere()` helper automatically gets auth data from `queryContext()` or
|
|
178
|
+
`mutatorContext()`, so you don't manually pass it. permissions only execute
|
|
179
|
+
server-side - on the client they automatically pass.
|
|
180
|
+
|
|
181
|
+
**for queries:** define permissions inline as a constant in query files:
|
|
182
|
+
|
|
183
|
+
```ts
|
|
184
|
+
// src/data/queries/channel.ts
|
|
185
|
+
const permission = serverWhere('channel', (q, auth) => {
|
|
186
|
+
return q.cmp('userId', auth?.id || '')
|
|
187
|
+
})
|
|
188
|
+
|
|
189
|
+
export const myChannels = () => {
|
|
190
|
+
return zql.channel.where(permission)
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
**for mutations:** define permissions in model files for CRUD operations:
|
|
195
|
+
|
|
196
|
+
```ts
|
|
197
|
+
// src/data/models/message.ts
|
|
198
|
+
export const permissions = serverWhere('message', (q, auth) => {
|
|
199
|
+
return q.cmp('authorId', auth?.id || '')
|
|
200
|
+
})
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
CRUD mutations automatically apply them, but for custom mutations use `can()`:
|
|
204
|
+
|
|
205
|
+
```ts
|
|
206
|
+
await ctx.can(permissions, messageId)
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
check permissions in React with `usePermission()`:
|
|
210
|
+
|
|
211
|
+
```tsx
|
|
212
|
+
const canEdit = usePermission('message', messageId)
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### composable query partials
|
|
216
|
+
|
|
217
|
+
for complex or reusable query logic, create partials in a `where/` directory.
|
|
218
|
+
use `serverWhere` without a table name to create partials that work across
|
|
219
|
+
multiple tables:
|
|
220
|
+
|
|
221
|
+
```ts
|
|
222
|
+
// src/data/where/server.ts
|
|
223
|
+
import { serverWhere } from 'on-zero'
|
|
224
|
+
|
|
225
|
+
type RelatedToServer = 'role' | 'channel' | 'message'
|
|
226
|
+
|
|
227
|
+
export const hasServerAdminPermission = serverWhere<RelatedToServer>((_, auth) =>
|
|
228
|
+
_.exists('server', (q) =>
|
|
229
|
+
q.whereExists('role', (r) =>
|
|
230
|
+
r.where('canAdmin', true)
|
|
231
|
+
.whereExists('member', (m) => m.where('id', auth?.id || ''))
|
|
232
|
+
)
|
|
233
|
+
)
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
export const hasServerReadPermission = serverWhere<RelatedToServer>((_, auth) =>
|
|
237
|
+
_.exists('server', (q) =>
|
|
238
|
+
q.where((_) =>
|
|
239
|
+
_.or(
|
|
240
|
+
_.cmp('private', false),
|
|
241
|
+
_.exists('member', (m) => m.where('id', auth?.id || ''))
|
|
242
|
+
)
|
|
243
|
+
)
|
|
244
|
+
)
|
|
245
|
+
)
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
then compose them in other permissions:
|
|
249
|
+
|
|
250
|
+
```ts
|
|
251
|
+
// src/data/where/channel.ts
|
|
252
|
+
import { serverWhere } from 'on-zero'
|
|
253
|
+
import { hasServerAdminPermission, hasServerReadPermission } from './server'
|
|
254
|
+
|
|
255
|
+
type RelatedToChannel = 'message' | 'pin' | 'channelTopic'
|
|
256
|
+
|
|
257
|
+
const hasChannelRole = serverWhere<RelatedToChannel>((_, auth) =>
|
|
258
|
+
_.exists('channel', (q) =>
|
|
259
|
+
q.whereExists('role', (r) =>
|
|
260
|
+
r.whereExists('member', (m) => m.where('id', auth?.id || ''))
|
|
261
|
+
)
|
|
262
|
+
)
|
|
263
|
+
)
|
|
264
|
+
|
|
265
|
+
export const hasChannelReadPermission = serverWhere<RelatedToChannel>((_, auth) => {
|
|
266
|
+
const isServerMember = hasServerReadPermission(_, auth)
|
|
267
|
+
const isChannelMember = hasChannelRole(_, auth)
|
|
268
|
+
const isAdmin = hasServerAdminPermission(_, auth)
|
|
269
|
+
|
|
270
|
+
return _.or(isServerMember, isChannelMember, isAdmin)
|
|
271
|
+
})
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
use in queries:
|
|
275
|
+
|
|
276
|
+
```ts
|
|
277
|
+
import { hasChannelReadPermission } from '../where/channel'
|
|
278
|
+
|
|
279
|
+
export const channelMessages = (props: { channelId: string }) => {
|
|
280
|
+
return zql.message
|
|
281
|
+
.where(hasChannelReadPermission)
|
|
282
|
+
.where('channelId', props.channelId)
|
|
283
|
+
}
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
## generation
|
|
287
|
+
|
|
288
|
+
`on-zero` has a CLI that auto-generates glue files that wire up your models,
|
|
289
|
+
queries, and types.
|
|
290
|
+
|
|
291
|
+
### cli commands
|
|
292
|
+
|
|
293
|
+
**`on-zero generate [dir]`**
|
|
294
|
+
|
|
295
|
+
generates all files needed to connect your models and queries:
|
|
296
|
+
|
|
297
|
+
- `models.ts` - aggregates all model files into a single import
|
|
298
|
+
- `types.ts` - generates TypeScript types from table schemas
|
|
299
|
+
- `tables.ts` - exports table schemas (separate to avoid circular types)
|
|
300
|
+
- `syncedQueries.ts` - generates synced query definitions with valibot
|
|
301
|
+
validators
|
|
302
|
+
|
|
303
|
+
**options:**
|
|
304
|
+
|
|
305
|
+
- `dir` - base directory containing `models/` and `queries/` folders (default:
|
|
306
|
+
`src/data`)
|
|
307
|
+
- `--watch` - watch for changes and regenerate automatically
|
|
308
|
+
- `--after` - command to run after generation completes
|
|
309
|
+
|
|
310
|
+
**examples:**
|
|
311
|
+
|
|
312
|
+
```bash
|
|
313
|
+
# generate once
|
|
314
|
+
bun on-zero generate
|
|
315
|
+
|
|
316
|
+
# generate and watch
|
|
317
|
+
bun on-zero generate --watch
|
|
318
|
+
|
|
319
|
+
# custom directory
|
|
320
|
+
bun on-zero generate ./app/data
|
|
321
|
+
|
|
322
|
+
# run linter after generation
|
|
323
|
+
bun on-zero generate --after "bun lint:fix"
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
**`on-zero generate-queries <dir>`**
|
|
327
|
+
|
|
328
|
+
generates query validators from TypeScript query functions. this is included in
|
|
329
|
+
`generate` but can be run standalone.
|
|
330
|
+
|
|
331
|
+
- parses exported arrow functions from `.ts` files in the queries directory
|
|
332
|
+
- extracts parameter types using TypeScript compiler API
|
|
333
|
+
- generates valibot schemas using typebox-codegen
|
|
334
|
+
|
|
335
|
+
**example:**
|
|
336
|
+
|
|
337
|
+
```bash
|
|
338
|
+
bun on-zero generate-queries src/data/queries
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
### what gets generated
|
|
342
|
+
|
|
343
|
+
**models.ts:**
|
|
344
|
+
|
|
345
|
+
```ts
|
|
346
|
+
import * as channel from '~/data/models/channel'
|
|
347
|
+
import * as message from '~/data/models/message'
|
|
348
|
+
|
|
349
|
+
export const models = {
|
|
350
|
+
channel,
|
|
351
|
+
message,
|
|
352
|
+
}
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
**types.ts:**
|
|
356
|
+
|
|
357
|
+
```ts
|
|
358
|
+
import type { TableInsertRow, TableUpdateRow } from 'on-zero'
|
|
359
|
+
import type * as schema from './tables'
|
|
360
|
+
|
|
361
|
+
export type Channel = TableInsertRow<typeof schema.channel>
|
|
362
|
+
export type ChannelUpdate = TableUpdateRow<typeof schema.channel>
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
**tables.ts:**
|
|
366
|
+
|
|
367
|
+
```ts
|
|
368
|
+
export { schema as channel } from '~/data/models/channel'
|
|
369
|
+
export { schema as message } from '~/data/models/message'
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
**syncedQueries.ts:**
|
|
373
|
+
|
|
374
|
+
```ts
|
|
375
|
+
import * as v from 'valibot'
|
|
376
|
+
import { syncedQuery } from '@rocicorp/zero'
|
|
377
|
+
import * as messageQueries from '../queries/message'
|
|
378
|
+
|
|
379
|
+
export const latestMessages = syncedQuery(
|
|
380
|
+
'latestMessages',
|
|
381
|
+
v.parser(
|
|
382
|
+
v.tuple([
|
|
383
|
+
v.object({
|
|
384
|
+
channelId: v.string(),
|
|
385
|
+
limit: v.optional(v.number()),
|
|
386
|
+
}),
|
|
387
|
+
]),
|
|
388
|
+
),
|
|
389
|
+
(arg) => {
|
|
390
|
+
return messageQueries.latestMessages(arg)
|
|
391
|
+
},
|
|
392
|
+
)
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
### how it works
|
|
396
|
+
|
|
397
|
+
the generator:
|
|
398
|
+
|
|
399
|
+
1. scans `models/` for files with `export const schema = table(...)`
|
|
400
|
+
2. scans `queries/` for exported arrow functions
|
|
401
|
+
3. parses TypeScript AST to extract parameter types
|
|
402
|
+
4. converts types to valibot schemas using typebox-codegen
|
|
403
|
+
5. wraps query functions in `syncedQuery()` with validators
|
|
404
|
+
6. handles special cases (void params, user → userPublic mapping)
|
|
405
|
+
7. groups query imports by source file
|
|
406
|
+
|
|
407
|
+
queries with no parameters get wrapped in `v.parser(v.tuple([]))` while queries
|
|
408
|
+
with params get validators like `v.parser(v.tuple([v.object({ ... })]))`.
|
|
409
|
+
|
|
410
|
+
exports named `permission` are automatically skipped during query generation.
|
|
411
|
+
|
|
412
|
+
## setup
|
|
413
|
+
|
|
414
|
+
client:
|
|
415
|
+
|
|
416
|
+
```tsx
|
|
417
|
+
import { createZeroClient } from 'on-zero'
|
|
418
|
+
import { schema } from '~/data/schema'
|
|
419
|
+
import { models } from '~/data/generated/models'
|
|
420
|
+
import * as groupedQueries from '~/data/generated/groupedQueries'
|
|
421
|
+
|
|
422
|
+
export const { ProvideZero, useQuery, zero, usePermission } = createZeroClient({
|
|
423
|
+
schema,
|
|
424
|
+
models,
|
|
425
|
+
groupedQueries,
|
|
426
|
+
})
|
|
427
|
+
|
|
428
|
+
// in your app root
|
|
429
|
+
<ProvideZero
|
|
430
|
+
server="http://localhost:4848"
|
|
431
|
+
userID={user.id}
|
|
432
|
+
auth={jwtToken}
|
|
433
|
+
authData={{ id: user.id, email: user.email, role: user.role }}
|
|
434
|
+
>
|
|
435
|
+
<App />
|
|
436
|
+
</ProvideZero>
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
server:
|
|
440
|
+
|
|
441
|
+
```ts
|
|
442
|
+
import { createZeroServer } from 'on-zero/server'
|
|
443
|
+
import { syncedQueries } from '~/data/generated/syncedQueries'
|
|
444
|
+
|
|
445
|
+
export const zeroServer = createZeroServer({
|
|
446
|
+
schema,
|
|
447
|
+
models,
|
|
448
|
+
database: process.env.DATABASE_URL,
|
|
449
|
+
queries: syncedQueries, // required for synced queries / pull endpoint
|
|
450
|
+
createServerActions: () => ({
|
|
451
|
+
sendEmail: async (to, subject, body) => { ... }
|
|
452
|
+
})
|
|
453
|
+
})
|
|
454
|
+
|
|
455
|
+
// push endpoint for mutations
|
|
456
|
+
app.post('/api/zero/push', async (req) => {
|
|
457
|
+
const authData = await getAuthFromRequest(req)
|
|
458
|
+
const { response } = await zeroServer.handleMutationRequest({
|
|
459
|
+
authData,
|
|
460
|
+
request: req
|
|
461
|
+
})
|
|
462
|
+
return response
|
|
463
|
+
})
|
|
464
|
+
|
|
465
|
+
// pull endpoint for synced queries
|
|
466
|
+
app.post('/api/zero/pull', async (req) => {
|
|
467
|
+
const authData = await getAuthFromRequest(req)
|
|
468
|
+
const { response } = await zeroServer.handleQueryRequest({
|
|
469
|
+
authData,
|
|
470
|
+
request: req
|
|
471
|
+
})
|
|
472
|
+
return response
|
|
473
|
+
})
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
type augmentation:
|
|
477
|
+
|
|
478
|
+
```ts
|
|
479
|
+
// src/zero/types.ts
|
|
480
|
+
import type { schema } from '~/data/schema'
|
|
481
|
+
import type { AuthData } from './auth'
|
|
482
|
+
|
|
483
|
+
declare module 'on-zero' {
|
|
484
|
+
interface Config {
|
|
485
|
+
schema: typeof schema
|
|
486
|
+
authData: AuthData
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
## mutation context
|
|
492
|
+
|
|
493
|
+
every mutation receives `MutatorContext` as first argument:
|
|
494
|
+
|
|
495
|
+
```ts
|
|
496
|
+
type MutatorContext = {
|
|
497
|
+
tx: Transaction // database transaction
|
|
498
|
+
authData: AuthData | null // current user
|
|
499
|
+
environment: 'server' | 'client' // where executing
|
|
500
|
+
can: (where, obj) => Promise<void> // permission checker
|
|
501
|
+
server?: {
|
|
502
|
+
actions: ServerActions // async server functions
|
|
503
|
+
asyncTasks: AsyncAction[] // run after transaction
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
use it:
|
|
509
|
+
|
|
510
|
+
```ts
|
|
511
|
+
export const mutate = mutations(schema, permissions, {
|
|
512
|
+
async archive(ctx, { messageId }) {
|
|
513
|
+
await ctx.can(permissions, messageId)
|
|
514
|
+
await ctx.tx.mutate.message.update({ id: messageId, archived: true })
|
|
515
|
+
|
|
516
|
+
ctx.server?.asyncTasks.push(async () => {
|
|
517
|
+
await ctx.server.actions.indexForSearch(messageId)
|
|
518
|
+
})
|
|
519
|
+
},
|
|
520
|
+
})
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
## patterns
|
|
524
|
+
|
|
525
|
+
**server-only mutations:**
|
|
526
|
+
|
|
527
|
+
```ts
|
|
528
|
+
await zeroServer.mutate(async (tx, mutators) => {
|
|
529
|
+
await mutators.user.insert(tx, user)
|
|
530
|
+
})
|
|
531
|
+
```
|
|
532
|
+
|
|
533
|
+
**one-off queries with `run()`:**
|
|
534
|
+
|
|
535
|
+
run a query once without subscribing. works on both client and server:
|
|
536
|
+
|
|
537
|
+
```ts
|
|
538
|
+
import { run } from 'on-zero'
|
|
539
|
+
import { userById } from '~/data/queries/user'
|
|
540
|
+
|
|
541
|
+
// with params
|
|
542
|
+
const user = await run(userById, { id: userId })
|
|
543
|
+
|
|
544
|
+
// without params
|
|
545
|
+
const allUsers = await run(allUsers)
|
|
546
|
+
|
|
547
|
+
// with options (client only)
|
|
548
|
+
const cached = await run(userById, { id: userId }, { type: 'unknown' })
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
on client, uses `zero.run()` under the hood. on server, uses transaction-based
|
|
552
|
+
execution. same query functions work in both environments.
|
|
553
|
+
|
|
554
|
+
**preloading data (client only):**
|
|
555
|
+
|
|
556
|
+
preload query results into cache without subscribing:
|
|
557
|
+
|
|
558
|
+
```ts
|
|
559
|
+
import { preload } from '~/zero/client'
|
|
560
|
+
import { userNotifications } from '~/data/queries/notification'
|
|
561
|
+
|
|
562
|
+
// preload after login
|
|
563
|
+
const { complete, cleanup } = preload(userNotifications, { userId, limit: 100 })
|
|
564
|
+
await complete
|
|
565
|
+
|
|
566
|
+
// cleanup if needed
|
|
567
|
+
cleanup()
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
useful for prefetching data before navigation to avoid loading states.
|
|
571
|
+
|
|
572
|
+
**server-only queries:**
|
|
573
|
+
|
|
574
|
+
for ad-hoc queries that don't use query functions:
|
|
575
|
+
|
|
576
|
+
```ts
|
|
577
|
+
const user = await zeroServer.query((q) => q.user.where('id', userId).one())
|
|
578
|
+
```
|
|
579
|
+
|
|
580
|
+
**batch processing:**
|
|
581
|
+
|
|
582
|
+
```ts
|
|
583
|
+
import { batchQuery } from 'on-zero'
|
|
584
|
+
|
|
585
|
+
await batchQuery(
|
|
586
|
+
zql.message.where('processed', false),
|
|
587
|
+
async (messages) => {
|
|
588
|
+
for (const msg of messages) {
|
|
589
|
+
await processMessage(msg)
|
|
590
|
+
}
|
|
591
|
+
},
|
|
592
|
+
{ chunk: 100, pause: 50 },
|
|
593
|
+
)
|
|
594
|
+
```
|