@rocicorp/zero 0.25.10-canary.6 → 0.25.10-canary.7

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.
@@ -1,4 +1,4 @@
1
- const version = "0.25.10-canary.6";
1
+ const version = "0.25.10-canary.7";
2
2
  const packageJson = {
3
3
  version
4
4
  };
@@ -0,0 +1,2 @@
1
+ export * from '../../../zero-server/src/adapters/prisma.ts';
2
+ //# sourceMappingURL=prisma.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prisma.d.ts","sourceRoot":"","sources":["../../../../src/adapters/prisma.ts"],"names":[],"mappings":"AAAA,cAAc,6CAA6C,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { PrismaConnection, zeroPrisma } from "../../../zero-server/src/adapters/prisma.js";
2
+ export {
3
+ PrismaConnection,
4
+ zeroPrisma
5
+ };
6
+ //# sourceMappingURL=prisma.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prisma.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
@@ -1,4 +1,4 @@
1
- const version = "0.25.10-canary.6";
1
+ const version = "0.25.10-canary.7";
2
2
  export {
3
3
  version
4
4
  };
@@ -57,7 +57,7 @@ function ZeroProvider({ children, init, ...props }) {
57
57
  };
58
58
  }, [init, ...keysWithoutAuth]);
59
59
  useEffect(() => {
60
- if (!zero) return;
60
+ if (!zero || isExternalZero) return;
61
61
  const authChanged = auth !== prevAuthRef.current;
62
62
  if (authChanged) {
63
63
  prevAuthRef.current = auth;
@@ -1 +1 @@
1
- {"version":3,"file":"zero-provider.js","sources":["../../../../zero-react/src/zero-provider.tsx"],"sourcesContent":["import {\n createContext,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from 'react';\nimport {stringCompare} from '../../shared/src/string-compare.ts';\nimport {\n Zero,\n type CustomMutatorDefs,\n type DefaultContext,\n type DefaultSchema,\n type Schema,\n type ZeroOptions,\n} from './zero.ts';\n\n// oxlint-disable-next-line no-explicit-any\nexport const ZeroContext = createContext<Zero<any, any, any> | undefined>(\n undefined,\n);\n\nexport function useZero<\n S extends Schema = DefaultSchema,\n MD extends CustomMutatorDefs | undefined = undefined,\n Context = DefaultContext,\n>(): Zero<S, MD, Context> {\n const zero = useContext(ZeroContext);\n if (zero === undefined) {\n throw new Error('useZero must be used within a ZeroProvider');\n }\n return zero as Zero<S, MD, Context>;\n}\n\n/**\n * @deprecated Use {@linkcode useZero} instead, alongside default types defined with:\n *\n * ```ts\n * declare module '@rocicorp/zero' {\n * interface DefaultTypes {\n * schema: typeof schema;\n * context: Context;\n * }\n * }\n */\nexport function createUseZero<\n S extends Schema = DefaultSchema,\n MD extends CustomMutatorDefs | undefined = undefined,\n Context = DefaultContext,\n>() {\n return () => useZero<S, MD, Context>();\n}\n\nexport type ZeroProviderProps<\n S extends Schema = DefaultSchema,\n MD extends CustomMutatorDefs | undefined = undefined,\n Context = DefaultContext,\n> = (ZeroOptions<S, MD, Context> | {zero: Zero<S, MD, Context>}) & {\n init?: (zero: Zero<S, MD, Context>) => void;\n children: ReactNode;\n};\n\nconst NO_AUTH_SET = Symbol();\n\nexport function ZeroProvider<\n S extends Schema = DefaultSchema,\n MD extends CustomMutatorDefs | undefined = undefined,\n Context = DefaultContext,\n>({children, init, ...props}: ZeroProviderProps<S, MD, Context>) {\n const isExternalZero = 'zero' in props;\n\n const [zero, setZero] = useState<Zero<S, MD, Context> | undefined>(\n isExternalZero ? props.zero : undefined,\n );\n\n const auth = 'auth' in props ? props.auth : NO_AUTH_SET;\n const prevAuthRef = useRef<typeof auth>(auth);\n\n const keysWithoutAuth = useMemo(\n () =>\n Object.entries(props)\n .filter(([key]) => key !== 'auth')\n .sort(([a], [b]) => stringCompare(a, b))\n .map(([_, value]) => value),\n [props],\n );\n\n // If Zero is not passed in, we construct it, but only client-side.\n // Zero doesn't really work SSR today so this is usually the right thing.\n // When we support Zero SSR this will either become a breaking change or\n // more likely server support will be opt-in with a new prop on this\n // component.\n useEffect(() => {\n if (isExternalZero) {\n setZero(props.zero);\n return;\n }\n\n const z = new Zero(props);\n init?.(z);\n setZero(z);\n\n return () => {\n void z.close();\n setZero(undefined);\n };\n // we intentionally don't include auth in the dependency array\n // to avoid closing zero when auth changes\n }, [init, ...keysWithoutAuth]);\n\n useEffect(() => {\n if (!zero) return;\n\n const authChanged = auth !== prevAuthRef.current;\n\n if (authChanged) {\n prevAuthRef.current = auth;\n void zero.connection.connect({\n auth: auth === NO_AUTH_SET ? undefined : auth,\n });\n }\n }, [auth, zero]);\n\n return (\n zero && <ZeroContext.Provider value={zero}>{children}</ZeroContext.Provider>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AAoBO,MAAM,cAAc;AAAA,EACzB;AACF;AAEO,SAAS,UAIU;AACxB,QAAM,OAAO,WAAW,WAAW;AACnC,MAAI,SAAS,QAAW;AACtB,UAAM,IAAI,MAAM,4CAA4C;AAAA,EAC9D;AACA,SAAO;AACT;AAaO,SAAS,gBAIZ;AACF,SAAO,MAAM,QAAA;AACf;AAWA,MAAM,cAAc,OAAA;AAEb,SAAS,aAId,EAAC,UAAU,MAAM,GAAG,SAA2C;AAC/D,QAAM,iBAAiB,UAAU;AAEjC,QAAM,CAAC,MAAM,OAAO,IAAI;AAAA,IACtB,iBAAiB,MAAM,OAAO;AAAA,EAAA;AAGhC,QAAM,OAAO,UAAU,QAAQ,MAAM,OAAO;AAC5C,QAAM,cAAc,OAAoB,IAAI;AAE5C,QAAM,kBAAkB;AAAA,IACtB,MACE,OAAO,QAAQ,KAAK,EACjB,OAAO,CAAC,CAAC,GAAG,MAAM,QAAQ,MAAM,EAChC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,EACtC,IAAI,CAAC,CAAC,GAAG,KAAK,MAAM,KAAK;AAAA,IAC9B,CAAC,KAAK;AAAA,EAAA;AAQR,YAAU,MAAM;AACd,QAAI,gBAAgB;AAClB,cAAQ,MAAM,IAAI;AAClB;AAAA,IACF;AAEA,UAAM,IAAI,IAAI,KAAK,KAAK;AACxB,WAAO,CAAC;AACR,YAAQ,CAAC;AAET,WAAO,MAAM;AACX,WAAK,EAAE,MAAA;AACP,cAAQ,MAAS;AAAA,IACnB;AAAA,EAGF,GAAG,CAAC,MAAM,GAAG,eAAe,CAAC;AAE7B,YAAU,MAAM;AACd,QAAI,CAAC,KAAM;AAEX,UAAM,cAAc,SAAS,YAAY;AAEzC,QAAI,aAAa;AACf,kBAAY,UAAU;AACtB,WAAK,KAAK,WAAW,QAAQ;AAAA,QAC3B,MAAM,SAAS,cAAc,SAAY;AAAA,MAAA,CAC1C;AAAA,IACH;AAAA,EACF,GAAG,CAAC,MAAM,IAAI,CAAC;AAEf,SACE,QAAQ,oBAAC,YAAY,UAAZ,EAAqB,OAAO,MAAO,UAAS;AAEzD;"}
1
+ {"version":3,"file":"zero-provider.js","sources":["../../../../zero-react/src/zero-provider.tsx"],"sourcesContent":["import {\n createContext,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from 'react';\nimport {stringCompare} from '../../shared/src/string-compare.ts';\nimport {\n Zero,\n type CustomMutatorDefs,\n type DefaultContext,\n type DefaultSchema,\n type Schema,\n type ZeroOptions,\n} from './zero.ts';\n\n// oxlint-disable-next-line no-explicit-any\nexport const ZeroContext = createContext<Zero<any, any, any> | undefined>(\n undefined,\n);\n\nexport function useZero<\n S extends Schema = DefaultSchema,\n MD extends CustomMutatorDefs | undefined = undefined,\n Context = DefaultContext,\n>(): Zero<S, MD, Context> {\n const zero = useContext(ZeroContext);\n if (zero === undefined) {\n throw new Error('useZero must be used within a ZeroProvider');\n }\n return zero as Zero<S, MD, Context>;\n}\n\n/**\n * @deprecated Use {@linkcode useZero} instead, alongside default types defined with:\n *\n * ```ts\n * declare module '@rocicorp/zero' {\n * interface DefaultTypes {\n * schema: typeof schema;\n * context: Context;\n * }\n * }\n */\nexport function createUseZero<\n S extends Schema = DefaultSchema,\n MD extends CustomMutatorDefs | undefined = undefined,\n Context = DefaultContext,\n>() {\n return () => useZero<S, MD, Context>();\n}\n\nexport type ZeroProviderProps<\n S extends Schema = DefaultSchema,\n MD extends CustomMutatorDefs | undefined = undefined,\n Context = DefaultContext,\n> = (ZeroOptions<S, MD, Context> | {zero: Zero<S, MD, Context>}) & {\n init?: (zero: Zero<S, MD, Context>) => void;\n children: ReactNode;\n};\n\nconst NO_AUTH_SET = Symbol();\n\nexport function ZeroProvider<\n S extends Schema = DefaultSchema,\n MD extends CustomMutatorDefs | undefined = undefined,\n Context = DefaultContext,\n>({children, init, ...props}: ZeroProviderProps<S, MD, Context>) {\n const isExternalZero = 'zero' in props;\n\n const [zero, setZero] = useState<Zero<S, MD, Context> | undefined>(\n isExternalZero ? props.zero : undefined,\n );\n\n const auth = 'auth' in props ? props.auth : NO_AUTH_SET;\n const prevAuthRef = useRef<typeof auth>(auth);\n\n const keysWithoutAuth = useMemo(\n () =>\n Object.entries(props)\n .filter(([key]) => key !== 'auth')\n .sort(([a], [b]) => stringCompare(a, b))\n .map(([_, value]) => value),\n [props],\n );\n\n // If Zero is not passed in, we construct it, but only client-side.\n // Zero doesn't really work SSR today so this is usually the right thing.\n // When we support Zero SSR this will either become a breaking change or\n // more likely server support will be opt-in with a new prop on this\n // component.\n useEffect(() => {\n if (isExternalZero) {\n setZero(props.zero);\n return;\n }\n\n const z = new Zero(props);\n init?.(z);\n setZero(z);\n\n return () => {\n void z.close();\n setZero(undefined);\n };\n // we intentionally don't include auth in the dependency array\n // to avoid closing zero when auth changes\n }, [init, ...keysWithoutAuth]);\n\n useEffect(() => {\n if (!zero || isExternalZero) return;\n\n const authChanged = auth !== prevAuthRef.current;\n\n if (authChanged) {\n prevAuthRef.current = auth;\n void zero.connection.connect({\n auth: auth === NO_AUTH_SET ? undefined : auth,\n });\n }\n }, [auth, zero]);\n\n return (\n zero && <ZeroContext.Provider value={zero}>{children}</ZeroContext.Provider>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AAoBO,MAAM,cAAc;AAAA,EACzB;AACF;AAEO,SAAS,UAIU;AACxB,QAAM,OAAO,WAAW,WAAW;AACnC,MAAI,SAAS,QAAW;AACtB,UAAM,IAAI,MAAM,4CAA4C;AAAA,EAC9D;AACA,SAAO;AACT;AAaO,SAAS,gBAIZ;AACF,SAAO,MAAM,QAAA;AACf;AAWA,MAAM,cAAc,OAAA;AAEb,SAAS,aAId,EAAC,UAAU,MAAM,GAAG,SAA2C;AAC/D,QAAM,iBAAiB,UAAU;AAEjC,QAAM,CAAC,MAAM,OAAO,IAAI;AAAA,IACtB,iBAAiB,MAAM,OAAO;AAAA,EAAA;AAGhC,QAAM,OAAO,UAAU,QAAQ,MAAM,OAAO;AAC5C,QAAM,cAAc,OAAoB,IAAI;AAE5C,QAAM,kBAAkB;AAAA,IACtB,MACE,OAAO,QAAQ,KAAK,EACjB,OAAO,CAAC,CAAC,GAAG,MAAM,QAAQ,MAAM,EAChC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,EACtC,IAAI,CAAC,CAAC,GAAG,KAAK,MAAM,KAAK;AAAA,IAC9B,CAAC,KAAK;AAAA,EAAA;AAQR,YAAU,MAAM;AACd,QAAI,gBAAgB;AAClB,cAAQ,MAAM,IAAI;AAClB;AAAA,IACF;AAEA,UAAM,IAAI,IAAI,KAAK,KAAK;AACxB,WAAO,CAAC;AACR,YAAQ,CAAC;AAET,WAAO,MAAM;AACX,WAAK,EAAE,MAAA;AACP,cAAQ,MAAS;AAAA,IACnB;AAAA,EAGF,GAAG,CAAC,MAAM,GAAG,eAAe,CAAC;AAE7B,YAAU,MAAM;AACd,QAAI,CAAC,QAAQ,eAAgB;AAE7B,UAAM,cAAc,SAAS,YAAY;AAEzC,QAAI,aAAa;AACf,kBAAY,UAAU;AACtB,WAAK,KAAK,WAAW,QAAQ;AAAA,QAC3B,MAAM,SAAS,cAAc,SAAY;AAAA,MAAA,CAC1C;AAAA,IACH;AAAA,EACF,GAAG,CAAC,MAAM,IAAI,CAAC;AAEf,SACE,QAAQ,oBAAC,YAAY,UAAZ,EAAqB,OAAO,MAAO,UAAS;AAEzD;"}
@@ -35,24 +35,29 @@ export declare function toIterableRows(result: unknown): Iterable<Row>;
35
35
  * ```ts
36
36
  * import {Pool} from 'pg';
37
37
  * import {drizzle} from 'drizzle-orm/node-postgres';
38
- * import type {ServerTransaction} from '@rocicorp/zero';
38
+ * import {defineMutator, defineMutators} from '@rocicorp/zero';
39
+ * import {zeroDrizzle} from '@rocicorp/zero/server/adapters/drizzle';
40
+ * import {z} from 'zod/mini';
39
41
  *
40
42
  * const pool = new Pool({connectionString: process.env.ZERO_UPSTREAM_DB!});
41
43
  * const drizzleDb = drizzle(pool, {schema: drizzleSchema});
42
- *
43
44
  * const zql = zeroDrizzle(schema, drizzleDb);
44
45
  *
45
- * // Define the server mutator transaction type using the helper
46
- * type ServerTx = ServerTransaction<Schema, DrizzleTransaction<typeof drizzleDb>>;
47
- *
48
- * async function createUser(
49
- * tx: ServerTx,
50
- * {id, name}: {id: string; name: string},
51
- * ) {
52
- * await tx.dbTransaction.wrappedTransaction
53
- * .insert(drizzleSchema.user)
54
- * .values({id, name})
55
- * }
46
+ * export const serverMutators = defineMutators({
47
+ * user: {
48
+ * create: defineMutator(
49
+ * z.object({id: z.string(), name: z.string()}),
50
+ * async ({tx, args}) => {
51
+ * if (tx.location !== 'server') {
52
+ * throw new Error('Server-only mutator');
53
+ * }
54
+ * await tx.dbTransaction.wrappedTransaction
55
+ * .insert(drizzleSchema.user)
56
+ * .values({id: args.id, name: args.name, status: 'active'});
57
+ * },
58
+ * ),
59
+ * },
60
+ * });
56
61
  * ```
57
62
  */
58
63
  export declare function zeroDrizzle<TSchema extends Schema, TDrizzle extends DrizzleDatabase>(schema: TSchema, client: TDrizzle): ZQLDatabase<TSchema, DrizzleTransaction<TDrizzle>>;
@@ -1 +1 @@
1
- {"version":3,"file":"drizzle.d.ts","sourceRoot":"","sources":["../../../../../zero-server/src/adapters/drizzle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAM,KAAK,GAAG,EAAC,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EACV,UAAU,EACV,gBAAgB,EAChB,aAAa,EACd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAC,0BAA0B,EAAC,MAAM,uBAAuB,CAAC;AAGtE,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,mCAAmC,CAAC;AAE9D,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACb,GAAG,EACJ,MAAM,mCAAmC,CAAC;AAG3C,OAAO,EAAC,WAAW,EAAC,MAAM,oBAAoB,CAAC;AAE/C,YAAY,EAAC,WAAW,EAAC,CAAC;AAE1B,MAAM,MAAM,eAAe,CACzB,YAAY,SAAS,gBAAgB,GAAG,gBAAgB,EACxD,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAC/D,UAAU,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;AAEtC;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,CAC5B,WAAW,SAAS,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7D,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,WAAW,SAAS,UAAU,CACtE,gBAAgB,EAChB,MAAM,eAAe,CACtB,GACG,eAAe,GACf,WAAW,IACb,aAAa,CACf,gBAAgB,EAChB,OAAO,EACP,0BAA0B,CAAC,OAAO,CAAC,CACpC,CAAC;AAEF,qBAAa,iBAAiB,CAC5B,QAAQ,SAAS,eAAe,EAChC,YAAY,SACV,kBAAkB,CAAC,QAAQ,CAAC,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAC7D,YAAW,YAAY,CAAC,YAAY,CAAC;;gBAIzB,OAAO,EAAE,QAAQ;IAI7B,WAAW,CAAC,CAAC,EACX,EAAE,EAAE,CAAC,EAAE,EAAE,aAAa,CAAC,YAAY,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,GAClD,OAAO,CAAC,CAAC,CAAC;CASd;AAkCD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,CAiBrE;AAUD,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,CAuB7D;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,WAAW,CACzB,OAAO,SAAS,MAAM,EACtB,QAAQ,SAAS,eAAe,EAEhC,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,QAAQ,GACf,WAAW,CAAC,OAAO,EAAE,kBAAkB,CAAC,QAAQ,CAAC,CAAC,CAKpD"}
1
+ {"version":3,"file":"drizzle.d.ts","sourceRoot":"","sources":["../../../../../zero-server/src/adapters/drizzle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAM,KAAK,GAAG,EAAC,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EACV,UAAU,EACV,gBAAgB,EAChB,aAAa,EACd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAC,0BAA0B,EAAC,MAAM,uBAAuB,CAAC;AAGtE,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,mCAAmC,CAAC;AAE9D,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACb,GAAG,EACJ,MAAM,mCAAmC,CAAC;AAG3C,OAAO,EAAC,WAAW,EAAC,MAAM,oBAAoB,CAAC;AAE/C,YAAY,EAAC,WAAW,EAAC,CAAC;AAE1B,MAAM,MAAM,eAAe,CACzB,YAAY,SAAS,gBAAgB,GAAG,gBAAgB,EACxD,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAC/D,UAAU,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;AAEtC;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,CAC5B,WAAW,SAAS,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7D,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,WAAW,SAAS,UAAU,CACtE,gBAAgB,EAChB,MAAM,eAAe,CACtB,GACG,eAAe,GACf,WAAW,IACb,aAAa,CACf,gBAAgB,EAChB,OAAO,EACP,0BAA0B,CAAC,OAAO,CAAC,CACpC,CAAC;AAEF,qBAAa,iBAAiB,CAC5B,QAAQ,SAAS,eAAe,EAChC,YAAY,SACV,kBAAkB,CAAC,QAAQ,CAAC,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAC7D,YAAW,YAAY,CAAC,YAAY,CAAC;;gBAIzB,OAAO,EAAE,QAAQ;IAI7B,WAAW,CAAC,CAAC,EACX,EAAE,EAAE,CAAC,EAAE,EAAE,aAAa,CAAC,YAAY,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,GAClD,OAAO,CAAC,CAAC,CAAC;CASd;AAkCD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,CAiBrE;AAUD,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,CAuB7D;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAgB,WAAW,CACzB,OAAO,SAAS,MAAM,EACtB,QAAQ,SAAS,eAAe,EAEhC,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,QAAQ,GACf,WAAW,CAAC,OAAO,EAAE,kBAAkB,CAAC,QAAQ,CAAC,CAAC,CAKpD"}
@@ -1 +1 @@
1
- {"version":3,"file":"drizzle.js","sources":["../../../../../zero-server/src/adapters/drizzle.ts"],"sourcesContent":["import {sql, type SQL} from 'drizzle-orm';\nimport type {\n PgDatabase,\n PgQueryResultHKT,\n PgTransaction,\n} from 'drizzle-orm/pg-core';\nimport type {ExtractTablesWithRelations} from 'drizzle-orm/relations';\nimport type {AST} from '../../../zero-protocol/src/ast.ts';\nimport type {Format} from '../../../zero-types/src/format.ts';\nimport type {Schema} from '../../../zero-types/src/schema.ts';\nimport type {ServerSchema} from '../../../zero-types/src/server-schema.ts';\nimport type {\n DBConnection,\n DBTransaction,\n Row,\n} from '../../../zql/src/mutate/custom.ts';\nimport type {HumanReadable} from '../../../zql/src/query/query.ts';\nimport {executePostgresQuery} from '../pg-query-executor.ts';\nimport {ZQLDatabase} from '../zql-database.ts';\n\nexport type {ZQLDatabase};\n\nexport type DrizzleDatabase<\n TQueryResult extends PgQueryResultHKT = PgQueryResultHKT,\n TSchema extends Record<string, unknown> = Record<string, unknown>,\n> = PgDatabase<TQueryResult, TSchema>;\n\n/**\n * Helper type for the wrapped transaction used by drizzle-orm.\n *\n * @remarks Use with `ServerTransaction` as `ServerTransaction<Schema, DrizzleTransaction<typeof drizzleDb>>`.\n */\nexport type DrizzleTransaction<\n TDbOrSchema extends DrizzleDatabase | Record<string, unknown>,\n TSchema extends Record<string, unknown> = TDbOrSchema extends PgDatabase<\n PgQueryResultHKT,\n infer TInferredSchema\n >\n ? TInferredSchema\n : TDbOrSchema,\n> = PgTransaction<\n PgQueryResultHKT,\n TSchema,\n ExtractTablesWithRelations<TSchema>\n>;\n\nexport class DrizzleConnection<\n TDrizzle extends DrizzleDatabase,\n TTransaction extends\n DrizzleTransaction<TDrizzle> = DrizzleTransaction<TDrizzle>,\n> implements DBConnection<TTransaction>\n{\n readonly #drizzle: TDrizzle;\n\n constructor(drizzle: TDrizzle) {\n this.#drizzle = drizzle;\n }\n\n transaction<T>(\n fn: (tx: DBTransaction<TTransaction>) => Promise<T>,\n ): Promise<T> {\n return this.#drizzle.transaction(drizzleTx =>\n fn(\n new DrizzleInternalTransaction(\n drizzleTx,\n ) as DBTransaction<TTransaction>,\n ),\n );\n }\n}\n\nclass DrizzleInternalTransaction<\n TTransaction extends DrizzleTransaction<DrizzleDatabase>,\n> implements DBTransaction<TTransaction>\n{\n readonly wrappedTransaction: TTransaction;\n\n constructor(drizzleTx: TTransaction) {\n this.wrappedTransaction = drizzleTx;\n }\n\n runQuery<TReturn>(\n ast: AST,\n format: Format,\n schema: Schema,\n serverSchema: ServerSchema,\n ): Promise<HumanReadable<TReturn>> {\n return executePostgresQuery<TReturn>(\n this,\n ast,\n format,\n schema,\n serverSchema,\n );\n }\n\n async query(sql: string, params: unknown[]): Promise<Iterable<Row>> {\n const stmt = fromDollarParams(sql, params);\n const result = await this.wrappedTransaction.execute(stmt);\n return toIterableRows(result);\n }\n}\n\n/**\n * Turn `$1, $2...` placeholders into a Drizzle SQL object with bound params.\n */\nexport function fromDollarParams(text: string, params: unknown[]): SQL {\n const re = /\\$(\\d+)/g;\n const s = sql.empty();\n let last = 0;\n let m: RegExpExecArray | null;\n\n while ((m = re.exec(text)) !== null) {\n const idx = Number(m[1]) - 1;\n if (idx < 0 || idx >= params.length) {\n throw new Error(`Missing param for $${m[1]}`);\n }\n if (m.index > last) s.append(sql.raw(text.slice(last, m.index)));\n s.append(sql`${params[idx]}`); // parameterized value\n last = m.index + m[0].length;\n }\n if (last < text.length) s.append(sql.raw(text.slice(last)));\n return s;\n}\n\nfunction isIterable(value: unknown): value is Iterable<unknown> {\n return (\n // oxlint-disable-next-line eqeqeq\n value != null &&\n typeof (value as Iterable<unknown>)[Symbol.iterator] === 'function'\n );\n}\n\nexport function toIterableRows(result: unknown): Iterable<Row> {\n if (result === null || result === undefined) {\n return [] as Row[];\n }\n if (Array.isArray(result)) {\n return result as Row[];\n }\n if (isIterable(result)) {\n return result as Iterable<Row>;\n }\n if (typeof result === 'object') {\n const rows = (result as {rows?: unknown}).rows;\n if (rows === null || rows === undefined) {\n return [] as Row[];\n }\n if (Array.isArray(rows)) {\n return rows as Row[];\n }\n if (isIterable(rows)) {\n return rows as Iterable<Row>;\n }\n }\n throw new TypeError('Drizzle query result is not iterable');\n}\n\n/**\n * Wrap a `drizzle-orm` database for Zero ZQL.\n *\n * Provides ZQL querying plus access to the underlying drizzle transaction.\n * Use {@link DrizzleTransaction} to type your server mutator transaction.\n *\n * @param schema - Zero schema.\n * @param client - Drizzle database.\n *\n * @example\n * ```ts\n * import {Pool} from 'pg';\n * import {drizzle} from 'drizzle-orm/node-postgres';\n * import type {ServerTransaction} from '@rocicorp/zero';\n *\n * const pool = new Pool({connectionString: process.env.ZERO_UPSTREAM_DB!});\n * const drizzleDb = drizzle(pool, {schema: drizzleSchema});\n *\n * const zql = zeroDrizzle(schema, drizzleDb);\n *\n * // Define the server mutator transaction type using the helper\n * type ServerTx = ServerTransaction<Schema, DrizzleTransaction<typeof drizzleDb>>;\n *\n * async function createUser(\n * tx: ServerTx,\n * {id, name}: {id: string; name: string},\n * ) {\n * await tx.dbTransaction.wrappedTransaction\n * .insert(drizzleSchema.user)\n * .values({id, name})\n * }\n * ```\n */\nexport function zeroDrizzle<\n TSchema extends Schema,\n TDrizzle extends DrizzleDatabase,\n>(\n schema: TSchema,\n client: TDrizzle,\n): ZQLDatabase<TSchema, DrizzleTransaction<TDrizzle>> {\n return new ZQLDatabase(\n new DrizzleConnection<TDrizzle, DrizzleTransaction<TDrizzle>>(client),\n schema,\n );\n}\n"],"names":["sql"],"mappings":";;;AA8CO,MAAM,kBAKb;AAAA,EACW;AAAA,EAET,YAAY,SAAmB;AAC7B,SAAK,WAAW;AAAA,EAClB;AAAA,EAEA,YACE,IACY;AACZ,WAAO,KAAK,SAAS;AAAA,MAAY,CAAA,cAC/B;AAAA,QACE,IAAI;AAAA,UACF;AAAA,QAAA;AAAA,MACF;AAAA,IACF;AAAA,EAEJ;AACF;AAEA,MAAM,2BAGN;AAAA,EACW;AAAA,EAET,YAAY,WAAyB;AACnC,SAAK,qBAAqB;AAAA,EAC5B;AAAA,EAEA,SACE,KACA,QACA,QACA,cACiC;AACjC,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,EAEJ;AAAA,EAEA,MAAM,MAAMA,MAAa,QAA2C;AAClE,UAAM,OAAO,iBAAiBA,MAAK,MAAM;AACzC,UAAM,SAAS,MAAM,KAAK,mBAAmB,QAAQ,IAAI;AACzD,WAAO,eAAe,MAAM;AAAA,EAC9B;AACF;AAKO,SAAS,iBAAiB,MAAc,QAAwB;AACrE,QAAM,KAAK;AACX,QAAM,IAAI,IAAI,MAAA;AACd,MAAI,OAAO;AACX,MAAI;AAEJ,UAAQ,IAAI,GAAG,KAAK,IAAI,OAAO,MAAM;AACnC,UAAM,MAAM,OAAO,EAAE,CAAC,CAAC,IAAI;AAC3B,QAAI,MAAM,KAAK,OAAO,OAAO,QAAQ;AACnC,YAAM,IAAI,MAAM,sBAAsB,EAAE,CAAC,CAAC,EAAE;AAAA,IAC9C;AACA,QAAI,EAAE,QAAQ,KAAM,GAAE,OAAO,IAAI,IAAI,KAAK,MAAM,MAAM,EAAE,KAAK,CAAC,CAAC;AAC/D,MAAE,OAAO,MAAM,OAAO,GAAG,CAAC,EAAE;AAC5B,WAAO,EAAE,QAAQ,EAAE,CAAC,EAAE;AAAA,EACxB;AACA,MAAI,OAAO,KAAK,OAAQ,GAAE,OAAO,IAAI,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC;AAC1D,SAAO;AACT;AAEA,SAAS,WAAW,OAA4C;AAC9D;AAAA;AAAA,IAEE,SAAS,QACT,OAAQ,MAA4B,OAAO,QAAQ,MAAM;AAAA;AAE7D;AAEO,SAAS,eAAe,QAAgC;AAC7D,MAAI,WAAW,QAAQ,WAAW,QAAW;AAC3C,WAAO,CAAA;AAAA,EACT;AACA,MAAI,MAAM,QAAQ,MAAM,GAAG;AACzB,WAAO;AAAA,EACT;AACA,MAAI,WAAW,MAAM,GAAG;AACtB,WAAO;AAAA,EACT;AACA,MAAI,OAAO,WAAW,UAAU;AAC9B,UAAM,OAAQ,OAA4B;AAC1C,QAAI,SAAS,QAAQ,SAAS,QAAW;AACvC,aAAO,CAAA;AAAA,IACT;AACA,QAAI,MAAM,QAAQ,IAAI,GAAG;AACvB,aAAO;AAAA,IACT;AACA,QAAI,WAAW,IAAI,GAAG;AACpB,aAAO;AAAA,IACT;AAAA,EACF;AACA,QAAM,IAAI,UAAU,sCAAsC;AAC5D;AAmCO,SAAS,YAId,QACA,QACoD;AACpD,SAAO,IAAI;AAAA,IACT,IAAI,kBAA0D,MAAM;AAAA,IACpE;AAAA,EAAA;AAEJ;"}
1
+ {"version":3,"file":"drizzle.js","sources":["../../../../../zero-server/src/adapters/drizzle.ts"],"sourcesContent":["import {sql, type SQL} from 'drizzle-orm';\nimport type {\n PgDatabase,\n PgQueryResultHKT,\n PgTransaction,\n} from 'drizzle-orm/pg-core';\nimport type {ExtractTablesWithRelations} from 'drizzle-orm/relations';\nimport type {AST} from '../../../zero-protocol/src/ast.ts';\nimport type {Format} from '../../../zero-types/src/format.ts';\nimport type {Schema} from '../../../zero-types/src/schema.ts';\nimport type {ServerSchema} from '../../../zero-types/src/server-schema.ts';\nimport type {\n DBConnection,\n DBTransaction,\n Row,\n} from '../../../zql/src/mutate/custom.ts';\nimport type {HumanReadable} from '../../../zql/src/query/query.ts';\nimport {executePostgresQuery} from '../pg-query-executor.ts';\nimport {ZQLDatabase} from '../zql-database.ts';\n\nexport type {ZQLDatabase};\n\nexport type DrizzleDatabase<\n TQueryResult extends PgQueryResultHKT = PgQueryResultHKT,\n TSchema extends Record<string, unknown> = Record<string, unknown>,\n> = PgDatabase<TQueryResult, TSchema>;\n\n/**\n * Helper type for the wrapped transaction used by drizzle-orm.\n *\n * @remarks Use with `ServerTransaction` as `ServerTransaction<Schema, DrizzleTransaction<typeof drizzleDb>>`.\n */\nexport type DrizzleTransaction<\n TDbOrSchema extends DrizzleDatabase | Record<string, unknown>,\n TSchema extends Record<string, unknown> = TDbOrSchema extends PgDatabase<\n PgQueryResultHKT,\n infer TInferredSchema\n >\n ? TInferredSchema\n : TDbOrSchema,\n> = PgTransaction<\n PgQueryResultHKT,\n TSchema,\n ExtractTablesWithRelations<TSchema>\n>;\n\nexport class DrizzleConnection<\n TDrizzle extends DrizzleDatabase,\n TTransaction extends\n DrizzleTransaction<TDrizzle> = DrizzleTransaction<TDrizzle>,\n> implements DBConnection<TTransaction>\n{\n readonly #drizzle: TDrizzle;\n\n constructor(drizzle: TDrizzle) {\n this.#drizzle = drizzle;\n }\n\n transaction<T>(\n fn: (tx: DBTransaction<TTransaction>) => Promise<T>,\n ): Promise<T> {\n return this.#drizzle.transaction(drizzleTx =>\n fn(\n new DrizzleInternalTransaction(\n drizzleTx,\n ) as DBTransaction<TTransaction>,\n ),\n );\n }\n}\n\nclass DrizzleInternalTransaction<\n TTransaction extends DrizzleTransaction<DrizzleDatabase>,\n> implements DBTransaction<TTransaction>\n{\n readonly wrappedTransaction: TTransaction;\n\n constructor(drizzleTx: TTransaction) {\n this.wrappedTransaction = drizzleTx;\n }\n\n runQuery<TReturn>(\n ast: AST,\n format: Format,\n schema: Schema,\n serverSchema: ServerSchema,\n ): Promise<HumanReadable<TReturn>> {\n return executePostgresQuery<TReturn>(\n this,\n ast,\n format,\n schema,\n serverSchema,\n );\n }\n\n async query(sql: string, params: unknown[]): Promise<Iterable<Row>> {\n const stmt = fromDollarParams(sql, params);\n const result = await this.wrappedTransaction.execute(stmt);\n return toIterableRows(result);\n }\n}\n\n/**\n * Turn `$1, $2...` placeholders into a Drizzle SQL object with bound params.\n */\nexport function fromDollarParams(text: string, params: unknown[]): SQL {\n const re = /\\$(\\d+)/g;\n const s = sql.empty();\n let last = 0;\n let m: RegExpExecArray | null;\n\n while ((m = re.exec(text)) !== null) {\n const idx = Number(m[1]) - 1;\n if (idx < 0 || idx >= params.length) {\n throw new Error(`Missing param for $${m[1]}`);\n }\n if (m.index > last) s.append(sql.raw(text.slice(last, m.index)));\n s.append(sql`${params[idx]}`); // parameterized value\n last = m.index + m[0].length;\n }\n if (last < text.length) s.append(sql.raw(text.slice(last)));\n return s;\n}\n\nfunction isIterable(value: unknown): value is Iterable<unknown> {\n return (\n // oxlint-disable-next-line eqeqeq\n value != null &&\n typeof (value as Iterable<unknown>)[Symbol.iterator] === 'function'\n );\n}\n\nexport function toIterableRows(result: unknown): Iterable<Row> {\n if (result === null || result === undefined) {\n return [] as Row[];\n }\n if (Array.isArray(result)) {\n return result as Row[];\n }\n if (isIterable(result)) {\n return result as Iterable<Row>;\n }\n if (typeof result === 'object') {\n const rows = (result as {rows?: unknown}).rows;\n if (rows === null || rows === undefined) {\n return [] as Row[];\n }\n if (Array.isArray(rows)) {\n return rows as Row[];\n }\n if (isIterable(rows)) {\n return rows as Iterable<Row>;\n }\n }\n throw new TypeError('Drizzle query result is not iterable');\n}\n\n/**\n * Wrap a `drizzle-orm` database for Zero ZQL.\n *\n * Provides ZQL querying plus access to the underlying drizzle transaction.\n * Use {@link DrizzleTransaction} to type your server mutator transaction.\n *\n * @param schema - Zero schema.\n * @param client - Drizzle database.\n *\n * @example\n * ```ts\n * import {Pool} from 'pg';\n * import {drizzle} from 'drizzle-orm/node-postgres';\n * import {defineMutator, defineMutators} from '@rocicorp/zero';\n * import {zeroDrizzle} from '@rocicorp/zero/server/adapters/drizzle';\n * import {z} from 'zod/mini';\n *\n * const pool = new Pool({connectionString: process.env.ZERO_UPSTREAM_DB!});\n * const drizzleDb = drizzle(pool, {schema: drizzleSchema});\n * const zql = zeroDrizzle(schema, drizzleDb);\n *\n * export const serverMutators = defineMutators({\n * user: {\n * create: defineMutator(\n * z.object({id: z.string(), name: z.string()}),\n * async ({tx, args}) => {\n * if (tx.location !== 'server') {\n * throw new Error('Server-only mutator');\n * }\n * await tx.dbTransaction.wrappedTransaction\n * .insert(drizzleSchema.user)\n * .values({id: args.id, name: args.name, status: 'active'});\n * },\n * ),\n * },\n * });\n * ```\n */\nexport function zeroDrizzle<\n TSchema extends Schema,\n TDrizzle extends DrizzleDatabase,\n>(\n schema: TSchema,\n client: TDrizzle,\n): ZQLDatabase<TSchema, DrizzleTransaction<TDrizzle>> {\n return new ZQLDatabase(\n new DrizzleConnection<TDrizzle, DrizzleTransaction<TDrizzle>>(client),\n schema,\n );\n}\n"],"names":["sql"],"mappings":";;;AA8CO,MAAM,kBAKb;AAAA,EACW;AAAA,EAET,YAAY,SAAmB;AAC7B,SAAK,WAAW;AAAA,EAClB;AAAA,EAEA,YACE,IACY;AACZ,WAAO,KAAK,SAAS;AAAA,MAAY,CAAA,cAC/B;AAAA,QACE,IAAI;AAAA,UACF;AAAA,QAAA;AAAA,MACF;AAAA,IACF;AAAA,EAEJ;AACF;AAEA,MAAM,2BAGN;AAAA,EACW;AAAA,EAET,YAAY,WAAyB;AACnC,SAAK,qBAAqB;AAAA,EAC5B;AAAA,EAEA,SACE,KACA,QACA,QACA,cACiC;AACjC,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,EAEJ;AAAA,EAEA,MAAM,MAAMA,MAAa,QAA2C;AAClE,UAAM,OAAO,iBAAiBA,MAAK,MAAM;AACzC,UAAM,SAAS,MAAM,KAAK,mBAAmB,QAAQ,IAAI;AACzD,WAAO,eAAe,MAAM;AAAA,EAC9B;AACF;AAKO,SAAS,iBAAiB,MAAc,QAAwB;AACrE,QAAM,KAAK;AACX,QAAM,IAAI,IAAI,MAAA;AACd,MAAI,OAAO;AACX,MAAI;AAEJ,UAAQ,IAAI,GAAG,KAAK,IAAI,OAAO,MAAM;AACnC,UAAM,MAAM,OAAO,EAAE,CAAC,CAAC,IAAI;AAC3B,QAAI,MAAM,KAAK,OAAO,OAAO,QAAQ;AACnC,YAAM,IAAI,MAAM,sBAAsB,EAAE,CAAC,CAAC,EAAE;AAAA,IAC9C;AACA,QAAI,EAAE,QAAQ,KAAM,GAAE,OAAO,IAAI,IAAI,KAAK,MAAM,MAAM,EAAE,KAAK,CAAC,CAAC;AAC/D,MAAE,OAAO,MAAM,OAAO,GAAG,CAAC,EAAE;AAC5B,WAAO,EAAE,QAAQ,EAAE,CAAC,EAAE;AAAA,EACxB;AACA,MAAI,OAAO,KAAK,OAAQ,GAAE,OAAO,IAAI,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC;AAC1D,SAAO;AACT;AAEA,SAAS,WAAW,OAA4C;AAC9D;AAAA;AAAA,IAEE,SAAS,QACT,OAAQ,MAA4B,OAAO,QAAQ,MAAM;AAAA;AAE7D;AAEO,SAAS,eAAe,QAAgC;AAC7D,MAAI,WAAW,QAAQ,WAAW,QAAW;AAC3C,WAAO,CAAA;AAAA,EACT;AACA,MAAI,MAAM,QAAQ,MAAM,GAAG;AACzB,WAAO;AAAA,EACT;AACA,MAAI,WAAW,MAAM,GAAG;AACtB,WAAO;AAAA,EACT;AACA,MAAI,OAAO,WAAW,UAAU;AAC9B,UAAM,OAAQ,OAA4B;AAC1C,QAAI,SAAS,QAAQ,SAAS,QAAW;AACvC,aAAO,CAAA;AAAA,IACT;AACA,QAAI,MAAM,QAAQ,IAAI,GAAG;AACvB,aAAO;AAAA,IACT;AACA,QAAI,WAAW,IAAI,GAAG;AACpB,aAAO;AAAA,IACT;AAAA,EACF;AACA,QAAM,IAAI,UAAU,sCAAsC;AAC5D;AAwCO,SAAS,YAId,QACA,QACoD;AACpD,SAAO,IAAI;AAAA,IACT,IAAI,kBAA0D,MAAM;AAAA,IACpE;AAAA,EAAA;AAEJ;"}
@@ -37,23 +37,29 @@ export declare class NodePgTransactionInternal implements DBTransaction<NodePgTr
37
37
  * @example
38
38
  * ```ts
39
39
  * import {Pool} from 'pg';
40
+ * import {defineMutator, defineMutators} from '@rocicorp/zero';
41
+ * import {zeroNodePg} from '@rocicorp/zero/server/adapters/pg';
42
+ * import {z} from 'zod/mini';
40
43
  *
41
44
  * const pool = new Pool({connectionString: process.env.ZERO_UPSTREAM_DB!});
42
45
  * const zql = zeroNodePg(schema, pool);
43
46
  *
44
- * // Define the server mutator transaction type using the helper
45
- * type ServerTx = ServerTransaction<
46
- * Schema,
47
- * NodePgTransaction
48
- * >;
49
- *
50
- * async function createUser(
51
- * tx: ServerTx,
52
- * {id, name}: {id: string; name: string},
53
- * ) {
54
- * await tx.dbTransaction.wrappedTransaction
55
- * .query('SELECT * FROM "user" WHERE id = $1', [id]);
56
- * }
47
+ * export const serverMutators = defineMutators({
48
+ * user: {
49
+ * create: defineMutator(
50
+ * z.object({id: z.string(), name: z.string()}),
51
+ * async ({tx, args}) => {
52
+ * if (tx.location !== 'server') {
53
+ * throw new Error('Server-only mutator');
54
+ * }
55
+ * await tx.dbTransaction.wrappedTransaction.query(
56
+ * 'INSERT INTO "user" (id, name, status) VALUES ($1, $2, $3)',
57
+ * [args.id, args.name, 'active'],
58
+ * );
59
+ * },
60
+ * ),
61
+ * },
62
+ * });
57
63
  * ```
58
64
  */
59
65
  export declare function zeroNodePg<S extends Schema>(schema: S, pg: NodePgTransaction | string): ZQLDatabase<S, NodePgTransaction>;
@@ -1 +1 @@
1
- {"version":3,"file":"pg.d.ts","sourceRoot":"","sources":["../../../../../zero-server/src/adapters/pg.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,IAAI,CAAC;AAC/B,OAAO,EAAC,IAAI,EAAE,KAAK,UAAU,EAAC,MAAM,IAAI,CAAC;AACzC,OAAO,KAAK,EAAC,GAAG,EAAC,MAAM,mCAAmC,CAAC;AAC3D,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,mCAAmC,CAAC;AAC9D,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,mCAAmC,CAAC;AAC9D,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,0CAA0C,CAAC;AAC3E,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACb,GAAG,EACJ,MAAM,mCAAmC,CAAC;AAC3C,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,iCAAiC,CAAC;AAEnE,OAAO,EAAC,WAAW,EAAC,MAAM,oBAAoB,CAAC;AAE/C,YAAY,EAAC,WAAW,EAAC,CAAC;AAE1B;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,GAAG,IAAI,GAAG,UAAU,GAAG,MAAM,CAAC;AAE3D,qBAAa,gBAAiB,YAAW,YAAY,CAAC,iBAAiB,CAAC;;gBAG1D,IAAI,EAAE,iBAAiB;IAI7B,WAAW,CAAC,IAAI,EACpB,EAAE,EAAE,CAAC,EAAE,EAAE,aAAa,CAAC,iBAAiB,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,GAC1D,OAAO,CAAC,IAAI,CAAC;CAqBjB;AAED,qBAAa,yBACX,YAAW,aAAa,CAAC,iBAAiB,CAAC;IAE3C,QAAQ,CAAC,kBAAkB,EAAE,iBAAiB,CAAC;gBAEnC,MAAM,EAAE,iBAAiB;IAIrC,QAAQ,CAAC,OAAO,EACd,GAAG,EAAE,GAAG,EACR,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,YAAY,GACzB,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAU5B,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;CAI5D;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,MAAM,EACzC,MAAM,EAAE,CAAC,EACT,EAAE,EAAE,iBAAiB,GAAG,MAAM,qCAM/B"}
1
+ {"version":3,"file":"pg.d.ts","sourceRoot":"","sources":["../../../../../zero-server/src/adapters/pg.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,IAAI,CAAC;AAC/B,OAAO,EAAC,IAAI,EAAE,KAAK,UAAU,EAAC,MAAM,IAAI,CAAC;AACzC,OAAO,KAAK,EAAC,GAAG,EAAC,MAAM,mCAAmC,CAAC;AAC3D,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,mCAAmC,CAAC;AAC9D,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,mCAAmC,CAAC;AAC9D,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,0CAA0C,CAAC;AAC3E,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACb,GAAG,EACJ,MAAM,mCAAmC,CAAC;AAC3C,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,iCAAiC,CAAC;AAEnE,OAAO,EAAC,WAAW,EAAC,MAAM,oBAAoB,CAAC;AAE/C,YAAY,EAAC,WAAW,EAAC,CAAC;AAE1B;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,GAAG,IAAI,GAAG,UAAU,GAAG,MAAM,CAAC;AAE3D,qBAAa,gBAAiB,YAAW,YAAY,CAAC,iBAAiB,CAAC;;gBAG1D,IAAI,EAAE,iBAAiB;IAI7B,WAAW,CAAC,IAAI,EACpB,EAAE,EAAE,CAAC,EAAE,EAAE,aAAa,CAAC,iBAAiB,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,GAC1D,OAAO,CAAC,IAAI,CAAC;CAqBjB;AAED,qBAAa,yBACX,YAAW,aAAa,CAAC,iBAAiB,CAAC;IAE3C,QAAQ,CAAC,kBAAkB,EAAE,iBAAiB,CAAC;gBAEnC,MAAM,EAAE,iBAAiB;IAIrC,QAAQ,CAAC,OAAO,EACd,GAAG,EAAE,GAAG,EACR,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,YAAY,GACzB,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAU5B,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;CAI5D;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,MAAM,EACzC,MAAM,EAAE,CAAC,EACT,EAAE,EAAE,iBAAiB,GAAG,MAAM,qCAM/B"}
@@ -1 +1 @@
1
- {"version":3,"file":"pg.js","sources":["../../../../../zero-server/src/adapters/pg.ts"],"sourcesContent":["import type {Client} from 'pg';\nimport {Pool, type PoolClient} from 'pg';\nimport type {AST} from '../../../zero-protocol/src/ast.ts';\nimport type {Format} from '../../../zero-types/src/format.ts';\nimport type {Schema} from '../../../zero-types/src/schema.ts';\nimport type {ServerSchema} from '../../../zero-types/src/server-schema.ts';\nimport type {\n DBConnection,\n DBTransaction,\n Row,\n} from '../../../zql/src/mutate/custom.ts';\nimport type {HumanReadable} from '../../../zql/src/query/query.ts';\nimport {executePostgresQuery} from '../pg-query-executor.ts';\nimport {ZQLDatabase} from '../zql-database.ts';\n\nexport type {ZQLDatabase};\n\n/**\n * Helper type for the wrapped transaction used by node-postgres.\n *\n * @remarks Use with `ServerTransaction` as `ServerTransaction<Schema, NodePgTransaction>`.\n */\nexport type NodePgTransaction = Pool | PoolClient | Client;\n\nexport class NodePgConnection implements DBConnection<NodePgTransaction> {\n readonly #pool: NodePgTransaction;\n\n constructor(pool: NodePgTransaction) {\n this.#pool = pool;\n }\n\n async transaction<TRet>(\n fn: (tx: DBTransaction<NodePgTransaction>) => Promise<TRet>,\n ): Promise<TRet> {\n const client =\n this.#pool instanceof Pool ? await this.#pool.connect() : this.#pool;\n try {\n await client.query('BEGIN');\n const result = await fn(new NodePgTransactionInternal(client));\n await client.query('COMMIT');\n return result;\n } catch (error) {\n try {\n await client.query('ROLLBACK');\n } catch {\n // ignore rollback error; original error will be thrown\n }\n throw error;\n } finally {\n if (this.#pool instanceof Pool && 'release' in client) {\n client.release();\n }\n }\n }\n}\n\nexport class NodePgTransactionInternal\n implements DBTransaction<NodePgTransaction>\n{\n readonly wrappedTransaction: NodePgTransaction;\n\n constructor(client: NodePgTransaction) {\n this.wrappedTransaction = client;\n }\n\n runQuery<TReturn>(\n ast: AST,\n format: Format,\n schema: Schema,\n serverSchema: ServerSchema,\n ): Promise<HumanReadable<TReturn>> {\n return executePostgresQuery<TReturn>(\n this,\n ast,\n format,\n schema,\n serverSchema,\n );\n }\n\n async query(sql: string, params: unknown[]): Promise<Row[]> {\n const res = await this.wrappedTransaction.query(sql, params as unknown[]);\n return res.rows as Row[];\n }\n}\n\n/**\n * Wrap a `pg` Pool for Zero ZQL.\n *\n * Provides ZQL querying plus access to the underlying node-postgres client.\n * Use {@link NodePgTransaction} to type your server mutator transaction.\n *\n * @param schema - Zero schema.\n * @param pg - `pg` Pool or connection string.\n *\n * @example\n * ```ts\n * import {Pool} from 'pg';\n *\n * const pool = new Pool({connectionString: process.env.ZERO_UPSTREAM_DB!});\n * const zql = zeroNodePg(schema, pool);\n *\n * // Define the server mutator transaction type using the helper\n * type ServerTx = ServerTransaction<\n * Schema,\n * NodePgTransaction\n * >;\n *\n * async function createUser(\n * tx: ServerTx,\n * {id, name}: {id: string; name: string},\n * ) {\n * await tx.dbTransaction.wrappedTransaction\n * .query('SELECT * FROM \"user\" WHERE id = $1', [id]);\n * }\n * ```\n */\nexport function zeroNodePg<S extends Schema>(\n schema: S,\n pg: NodePgTransaction | string,\n) {\n if (typeof pg === 'string') {\n pg = new Pool({connectionString: pg});\n }\n return new ZQLDatabase(new NodePgConnection(pg), schema);\n}\n"],"names":[],"mappings":";;;AAwBO,MAAM,iBAA4D;AAAA,EAC9D;AAAA,EAET,YAAY,MAAyB;AACnC,SAAK,QAAQ;AAAA,EACf;AAAA,EAEA,MAAM,YACJ,IACe;AACf,UAAM,SACJ,KAAK,iBAAiB,OAAO,MAAM,KAAK,MAAM,YAAY,KAAK;AACjE,QAAI;AACF,YAAM,OAAO,MAAM,OAAO;AAC1B,YAAM,SAAS,MAAM,GAAG,IAAI,0BAA0B,MAAM,CAAC;AAC7D,YAAM,OAAO,MAAM,QAAQ;AAC3B,aAAO;AAAA,IACT,SAAS,OAAO;AACd,UAAI;AACF,cAAM,OAAO,MAAM,UAAU;AAAA,MAC/B,QAAQ;AAAA,MAER;AACA,YAAM;AAAA,IACR,UAAA;AACE,UAAI,KAAK,iBAAiB,QAAQ,aAAa,QAAQ;AACrD,eAAO,QAAA;AAAA,MACT;AAAA,IACF;AAAA,EACF;AACF;AAEO,MAAM,0BAEb;AAAA,EACW;AAAA,EAET,YAAY,QAA2B;AACrC,SAAK,qBAAqB;AAAA,EAC5B;AAAA,EAEA,SACE,KACA,QACA,QACA,cACiC;AACjC,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,EAEJ;AAAA,EAEA,MAAM,MAAM,KAAa,QAAmC;AAC1D,UAAM,MAAM,MAAM,KAAK,mBAAmB,MAAM,KAAK,MAAmB;AACxE,WAAO,IAAI;AAAA,EACb;AACF;AAiCO,SAAS,WACd,QACA,IACA;AACA,MAAI,OAAO,OAAO,UAAU;AAC1B,SAAK,IAAI,KAAK,EAAC,kBAAkB,IAAG;AAAA,EACtC;AACA,SAAO,IAAI,YAAY,IAAI,iBAAiB,EAAE,GAAG,MAAM;AACzD;"}
1
+ {"version":3,"file":"pg.js","sources":["../../../../../zero-server/src/adapters/pg.ts"],"sourcesContent":["import type {Client} from 'pg';\nimport {Pool, type PoolClient} from 'pg';\nimport type {AST} from '../../../zero-protocol/src/ast.ts';\nimport type {Format} from '../../../zero-types/src/format.ts';\nimport type {Schema} from '../../../zero-types/src/schema.ts';\nimport type {ServerSchema} from '../../../zero-types/src/server-schema.ts';\nimport type {\n DBConnection,\n DBTransaction,\n Row,\n} from '../../../zql/src/mutate/custom.ts';\nimport type {HumanReadable} from '../../../zql/src/query/query.ts';\nimport {executePostgresQuery} from '../pg-query-executor.ts';\nimport {ZQLDatabase} from '../zql-database.ts';\n\nexport type {ZQLDatabase};\n\n/**\n * Helper type for the wrapped transaction used by node-postgres.\n *\n * @remarks Use with `ServerTransaction` as `ServerTransaction<Schema, NodePgTransaction>`.\n */\nexport type NodePgTransaction = Pool | PoolClient | Client;\n\nexport class NodePgConnection implements DBConnection<NodePgTransaction> {\n readonly #pool: NodePgTransaction;\n\n constructor(pool: NodePgTransaction) {\n this.#pool = pool;\n }\n\n async transaction<TRet>(\n fn: (tx: DBTransaction<NodePgTransaction>) => Promise<TRet>,\n ): Promise<TRet> {\n const client =\n this.#pool instanceof Pool ? await this.#pool.connect() : this.#pool;\n try {\n await client.query('BEGIN');\n const result = await fn(new NodePgTransactionInternal(client));\n await client.query('COMMIT');\n return result;\n } catch (error) {\n try {\n await client.query('ROLLBACK');\n } catch {\n // ignore rollback error; original error will be thrown\n }\n throw error;\n } finally {\n if (this.#pool instanceof Pool && 'release' in client) {\n client.release();\n }\n }\n }\n}\n\nexport class NodePgTransactionInternal\n implements DBTransaction<NodePgTransaction>\n{\n readonly wrappedTransaction: NodePgTransaction;\n\n constructor(client: NodePgTransaction) {\n this.wrappedTransaction = client;\n }\n\n runQuery<TReturn>(\n ast: AST,\n format: Format,\n schema: Schema,\n serverSchema: ServerSchema,\n ): Promise<HumanReadable<TReturn>> {\n return executePostgresQuery<TReturn>(\n this,\n ast,\n format,\n schema,\n serverSchema,\n );\n }\n\n async query(sql: string, params: unknown[]): Promise<Row[]> {\n const res = await this.wrappedTransaction.query(sql, params as unknown[]);\n return res.rows as Row[];\n }\n}\n\n/**\n * Wrap a `pg` Pool for Zero ZQL.\n *\n * Provides ZQL querying plus access to the underlying node-postgres client.\n * Use {@link NodePgTransaction} to type your server mutator transaction.\n *\n * @param schema - Zero schema.\n * @param pg - `pg` Pool or connection string.\n *\n * @example\n * ```ts\n * import {Pool} from 'pg';\n * import {defineMutator, defineMutators} from '@rocicorp/zero';\n * import {zeroNodePg} from '@rocicorp/zero/server/adapters/pg';\n * import {z} from 'zod/mini';\n *\n * const pool = new Pool({connectionString: process.env.ZERO_UPSTREAM_DB!});\n * const zql = zeroNodePg(schema, pool);\n *\n * export const serverMutators = defineMutators({\n * user: {\n * create: defineMutator(\n * z.object({id: z.string(), name: z.string()}),\n * async ({tx, args}) => {\n * if (tx.location !== 'server') {\n * throw new Error('Server-only mutator');\n * }\n * await tx.dbTransaction.wrappedTransaction.query(\n * 'INSERT INTO \"user\" (id, name, status) VALUES ($1, $2, $3)',\n * [args.id, args.name, 'active'],\n * );\n * },\n * ),\n * },\n * });\n * ```\n */\nexport function zeroNodePg<S extends Schema>(\n schema: S,\n pg: NodePgTransaction | string,\n) {\n if (typeof pg === 'string') {\n pg = new Pool({connectionString: pg});\n }\n return new ZQLDatabase(new NodePgConnection(pg), schema);\n}\n"],"names":[],"mappings":";;;AAwBO,MAAM,iBAA4D;AAAA,EAC9D;AAAA,EAET,YAAY,MAAyB;AACnC,SAAK,QAAQ;AAAA,EACf;AAAA,EAEA,MAAM,YACJ,IACe;AACf,UAAM,SACJ,KAAK,iBAAiB,OAAO,MAAM,KAAK,MAAM,YAAY,KAAK;AACjE,QAAI;AACF,YAAM,OAAO,MAAM,OAAO;AAC1B,YAAM,SAAS,MAAM,GAAG,IAAI,0BAA0B,MAAM,CAAC;AAC7D,YAAM,OAAO,MAAM,QAAQ;AAC3B,aAAO;AAAA,IACT,SAAS,OAAO;AACd,UAAI;AACF,cAAM,OAAO,MAAM,UAAU;AAAA,MAC/B,QAAQ;AAAA,MAER;AACA,YAAM;AAAA,IACR,UAAA;AACE,UAAI,KAAK,iBAAiB,QAAQ,aAAa,QAAQ;AACrD,eAAO,QAAA;AAAA,MACT;AAAA,IACF;AAAA,EACF;AACF;AAEO,MAAM,0BAEb;AAAA,EACW;AAAA,EAET,YAAY,QAA2B;AACrC,SAAK,qBAAqB;AAAA,EAC5B;AAAA,EAEA,SACE,KACA,QACA,QACA,cACiC;AACjC,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,EAEJ;AAAA,EAEA,MAAM,MAAM,KAAa,QAAmC;AAC1D,UAAM,MAAM,MAAM,KAAK,mBAAmB,MAAM,KAAK,MAAmB;AACxE,WAAO,IAAI;AAAA,EACb;AACF;AAuCO,SAAS,WACd,QACA,IACA;AACA,MAAI,OAAO,OAAO,UAAU;AAC1B,SAAK,IAAI,KAAK,EAAC,kBAAkB,IAAG;AAAA,EACtC;AACA,SAAO,IAAI,YAAY,IAAI,iBAAiB,EAAE,GAAG,MAAM;AACzD;"}
@@ -37,23 +37,29 @@ export declare class PostgresJsTransactionInternal<T extends Record<string, unkn
37
37
  * @example
38
38
  * ```ts
39
39
  * import postgres from 'postgres';
40
+ * import {defineMutator, defineMutators} from '@rocicorp/zero';
41
+ * import {zeroPostgresJS} from '@rocicorp/zero/server/adapters/postgresjs';
42
+ * import {z} from 'zod/mini';
40
43
  *
41
44
  * const sql = postgres(process.env.ZERO_UPSTREAM_DB!);
42
45
  * const zql = zeroPostgresJS(schema, sql);
43
46
  *
44
- * // Define the server mutator transaction type using the helper
45
- * type ServerTx = ServerTransaction<
46
- * Schema,
47
- * PostgresJsTransaction
48
- * >;
49
- *
50
- * async function createUser(
51
- * tx: ServerTx,
52
- * {id, name}: {id: string; name: string},
53
- * ) {
54
- * await tx.dbTransaction.wrappedTransaction
55
- * .unsafe('INSERT INTO "user" (id, name) VALUES ($1, $2)', [id, name]);
56
- * }
47
+ * export const serverMutators = defineMutators({
48
+ * user: {
49
+ * create: defineMutator(
50
+ * z.object({id: z.string(), name: z.string()}),
51
+ * async ({tx, args}) => {
52
+ * if (tx.location !== 'server') {
53
+ * throw new Error('Server-only mutator');
54
+ * }
55
+ * await tx.dbTransaction.wrappedTransaction`
56
+ * INSERT INTO "user" (id, name, status)
57
+ * VALUES (${args.id}, ${args.name}, ${'active'})
58
+ * `;
59
+ * },
60
+ * ),
61
+ * },
62
+ * });
57
63
  * ```
58
64
  */
59
65
  export declare function zeroPostgresJS<S extends Schema, T extends Record<string, unknown> = Record<string, unknown>>(schema: S, pg: postgres.Sql<T> | string): ZQLDatabase<S, PostgresJsTransaction<T>>;
@@ -1 +1 @@
1
- {"version":3,"file":"postgresjs.d.ts","sourceRoot":"","sources":["../../../../../zero-server/src/adapters/postgresjs.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,UAAU,CAAC;AAEhC,OAAO,KAAK,EAAC,GAAG,EAAC,MAAM,mCAAmC,CAAC;AAC3D,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,mCAAmC,CAAC;AAC9D,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,mCAAmC,CAAC;AAC9D,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,0CAA0C,CAAC;AAC3E,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACb,GAAG,EACJ,MAAM,mCAAmC,CAAC;AAC3C,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,iCAAiC,CAAC;AAEnE,OAAO,EAAC,WAAW,EAAC,MAAM,oBAAoB,CAAC;AAE/C,YAAY,EAAC,WAAW,EAAC,CAAC;AAE1B;;;;;GAKG;AACH,MAAM,MAAM,qBAAqB,CAC/B,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IACzD,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;AAE/B,qBAAa,oBAAoB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CACjE,YAAW,YAAY,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;;gBAGrC,EAAE,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;IAI/B,WAAW,CAAC,IAAI,EACd,EAAE,EAAE,CAAC,EAAE,EAAE,aAAa,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,GACjE,OAAO,CAAC,IAAI,CAAC;CAKjB;AAED,qBAAa,6BAA6B,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAC1E,YAAW,aAAa,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;IAElD,QAAQ,CAAC,kBAAkB,EAAE,qBAAqB,CAAC,CAAC,CAAC,CAAC;gBAC1C,IAAI,EAAE,qBAAqB,CAAC,CAAC,CAAC;IAI1C,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAIrD,QAAQ,CAAC,OAAO,EACd,GAAG,EAAE,GAAG,EACR,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,YAAY,GACzB,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;CASnC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,cAAc,CAC5B,CAAC,SAAS,MAAM,EAChB,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC3D,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,MAAM,4CAKxC"}
1
+ {"version":3,"file":"postgresjs.d.ts","sourceRoot":"","sources":["../../../../../zero-server/src/adapters/postgresjs.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,UAAU,CAAC;AAEhC,OAAO,KAAK,EAAC,GAAG,EAAC,MAAM,mCAAmC,CAAC;AAC3D,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,mCAAmC,CAAC;AAC9D,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,mCAAmC,CAAC;AAC9D,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,0CAA0C,CAAC;AAC3E,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACb,GAAG,EACJ,MAAM,mCAAmC,CAAC;AAC3C,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,iCAAiC,CAAC;AAEnE,OAAO,EAAC,WAAW,EAAC,MAAM,oBAAoB,CAAC;AAE/C,YAAY,EAAC,WAAW,EAAC,CAAC;AAE1B;;;;;GAKG;AACH,MAAM,MAAM,qBAAqB,CAC/B,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IACzD,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;AAE/B,qBAAa,oBAAoB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CACjE,YAAW,YAAY,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;;gBAGrC,EAAE,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;IAI/B,WAAW,CAAC,IAAI,EACd,EAAE,EAAE,CAAC,EAAE,EAAE,aAAa,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,GACjE,OAAO,CAAC,IAAI,CAAC;CAKjB;AAED,qBAAa,6BAA6B,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAC1E,YAAW,aAAa,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;IAElD,QAAQ,CAAC,kBAAkB,EAAE,qBAAqB,CAAC,CAAC,CAAC,CAAC;gBAC1C,IAAI,EAAE,qBAAqB,CAAC,CAAC,CAAC;IAI1C,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAIrD,QAAQ,CAAC,OAAO,EACd,GAAG,EAAE,GAAG,EACR,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,YAAY,GACzB,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;CASnC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAgB,cAAc,CAC5B,CAAC,SAAS,MAAM,EAChB,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC3D,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,MAAM,4CAKxC"}
@@ -1 +1 @@
1
- {"version":3,"file":"postgresjs.js","sources":["../../../../../zero-server/src/adapters/postgresjs.ts"],"sourcesContent":["import postgres from 'postgres';\nimport type {JSONValue} from '../../../shared/src/json.ts';\nimport type {AST} from '../../../zero-protocol/src/ast.ts';\nimport type {Format} from '../../../zero-types/src/format.ts';\nimport type {Schema} from '../../../zero-types/src/schema.ts';\nimport type {ServerSchema} from '../../../zero-types/src/server-schema.ts';\nimport type {\n DBConnection,\n DBTransaction,\n Row,\n} from '../../../zql/src/mutate/custom.ts';\nimport type {HumanReadable} from '../../../zql/src/query/query.ts';\nimport {executePostgresQuery} from '../pg-query-executor.ts';\nimport {ZQLDatabase} from '../zql-database.ts';\n\nexport type {ZQLDatabase};\n\n/**\n * Helper type for the wrapped transaction used by postgres.js.\n *\n * @typeParam T - The row-shape context bound to the postgres.js client.\n * @remarks Use with `ServerTransaction` as `ServerTransaction<Schema, PostgresJsTransaction>`.\n */\nexport type PostgresJsTransaction<\n T extends Record<string, unknown> = Record<string, unknown>,\n> = postgres.TransactionSql<T>;\n\nexport class PostgresJSConnection<T extends Record<string, unknown>>\n implements DBConnection<PostgresJsTransaction<T>>\n{\n readonly #pg: postgres.Sql<T>;\n constructor(pg: postgres.Sql<T>) {\n this.#pg = pg;\n }\n\n transaction<TRet>(\n fn: (tx: DBTransaction<PostgresJsTransaction<T>>) => Promise<TRet>,\n ): Promise<TRet> {\n return this.#pg.begin(pgTx =>\n fn(new PostgresJsTransactionInternal(pgTx)),\n ) as Promise<TRet>;\n }\n}\n\nexport class PostgresJsTransactionInternal<T extends Record<string, unknown>>\n implements DBTransaction<PostgresJsTransaction<T>>\n{\n readonly wrappedTransaction: PostgresJsTransaction<T>;\n constructor(pgTx: PostgresJsTransaction<T>) {\n this.wrappedTransaction = pgTx;\n }\n\n query(sql: string, params: unknown[]): Promise<Row[]> {\n return this.wrappedTransaction.unsafe(sql, params as JSONValue[]);\n }\n\n runQuery<TReturn>(\n ast: AST,\n format: Format,\n schema: Schema,\n serverSchema: ServerSchema,\n ): Promise<HumanReadable<TReturn>> {\n return executePostgresQuery<TReturn>(\n this,\n ast,\n format,\n schema,\n serverSchema,\n );\n }\n}\n\n/**\n * Wrap a `postgres` client for Zero ZQL.\n *\n * Provides ZQL querying plus access to the underlying postgres.js transaction.\n * Use {@link PostgresJsTransaction} to type your server mutator transaction.\n *\n * @param schema - Zero schema.\n * @param pg - `postgres` client or connection string.\n *\n * @example\n * ```ts\n * import postgres from 'postgres';\n *\n * const sql = postgres(process.env.ZERO_UPSTREAM_DB!);\n * const zql = zeroPostgresJS(schema, sql);\n *\n * // Define the server mutator transaction type using the helper\n * type ServerTx = ServerTransaction<\n * Schema,\n * PostgresJsTransaction\n * >;\n *\n * async function createUser(\n * tx: ServerTx,\n * {id, name}: {id: string; name: string},\n * ) {\n * await tx.dbTransaction.wrappedTransaction\n * .unsafe('INSERT INTO \"user\" (id, name) VALUES ($1, $2)', [id, name]);\n * }\n * ```\n */\nexport function zeroPostgresJS<\n S extends Schema,\n T extends Record<string, unknown> = Record<string, unknown>,\n>(schema: S, pg: postgres.Sql<T> | string) {\n if (typeof pg === 'string') {\n pg = postgres(pg) as postgres.Sql<T>;\n }\n return new ZQLDatabase(new PostgresJSConnection(pg), schema);\n}\n"],"names":[],"mappings":";;;AA2BO,MAAM,qBAEb;AAAA,EACW;AAAA,EACT,YAAY,IAAqB;AAC/B,SAAK,MAAM;AAAA,EACb;AAAA,EAEA,YACE,IACe;AACf,WAAO,KAAK,IAAI;AAAA,MAAM,CAAA,SACpB,GAAG,IAAI,8BAA8B,IAAI,CAAC;AAAA,IAAA;AAAA,EAE9C;AACF;AAEO,MAAM,8BAEb;AAAA,EACW;AAAA,EACT,YAAY,MAAgC;AAC1C,SAAK,qBAAqB;AAAA,EAC5B;AAAA,EAEA,MAAM,KAAa,QAAmC;AACpD,WAAO,KAAK,mBAAmB,OAAO,KAAK,MAAqB;AAAA,EAClE;AAAA,EAEA,SACE,KACA,QACA,QACA,cACiC;AACjC,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,EAEJ;AACF;AAiCO,SAAS,eAGd,QAAW,IAA8B;AACzC,MAAI,OAAO,OAAO,UAAU;AAC1B,SAAK,SAAS,EAAE;AAAA,EAClB;AACA,SAAO,IAAI,YAAY,IAAI,qBAAqB,EAAE,GAAG,MAAM;AAC7D;"}
1
+ {"version":3,"file":"postgresjs.js","sources":["../../../../../zero-server/src/adapters/postgresjs.ts"],"sourcesContent":["import postgres from 'postgres';\nimport type {JSONValue} from '../../../shared/src/json.ts';\nimport type {AST} from '../../../zero-protocol/src/ast.ts';\nimport type {Format} from '../../../zero-types/src/format.ts';\nimport type {Schema} from '../../../zero-types/src/schema.ts';\nimport type {ServerSchema} from '../../../zero-types/src/server-schema.ts';\nimport type {\n DBConnection,\n DBTransaction,\n Row,\n} from '../../../zql/src/mutate/custom.ts';\nimport type {HumanReadable} from '../../../zql/src/query/query.ts';\nimport {executePostgresQuery} from '../pg-query-executor.ts';\nimport {ZQLDatabase} from '../zql-database.ts';\n\nexport type {ZQLDatabase};\n\n/**\n * Helper type for the wrapped transaction used by postgres.js.\n *\n * @typeParam T - The row-shape context bound to the postgres.js client.\n * @remarks Use with `ServerTransaction` as `ServerTransaction<Schema, PostgresJsTransaction>`.\n */\nexport type PostgresJsTransaction<\n T extends Record<string, unknown> = Record<string, unknown>,\n> = postgres.TransactionSql<T>;\n\nexport class PostgresJSConnection<T extends Record<string, unknown>>\n implements DBConnection<PostgresJsTransaction<T>>\n{\n readonly #pg: postgres.Sql<T>;\n constructor(pg: postgres.Sql<T>) {\n this.#pg = pg;\n }\n\n transaction<TRet>(\n fn: (tx: DBTransaction<PostgresJsTransaction<T>>) => Promise<TRet>,\n ): Promise<TRet> {\n return this.#pg.begin(pgTx =>\n fn(new PostgresJsTransactionInternal(pgTx)),\n ) as Promise<TRet>;\n }\n}\n\nexport class PostgresJsTransactionInternal<T extends Record<string, unknown>>\n implements DBTransaction<PostgresJsTransaction<T>>\n{\n readonly wrappedTransaction: PostgresJsTransaction<T>;\n constructor(pgTx: PostgresJsTransaction<T>) {\n this.wrappedTransaction = pgTx;\n }\n\n query(sql: string, params: unknown[]): Promise<Row[]> {\n return this.wrappedTransaction.unsafe(sql, params as JSONValue[]);\n }\n\n runQuery<TReturn>(\n ast: AST,\n format: Format,\n schema: Schema,\n serverSchema: ServerSchema,\n ): Promise<HumanReadable<TReturn>> {\n return executePostgresQuery<TReturn>(\n this,\n ast,\n format,\n schema,\n serverSchema,\n );\n }\n}\n\n/**\n * Wrap a `postgres` client for Zero ZQL.\n *\n * Provides ZQL querying plus access to the underlying postgres.js transaction.\n * Use {@link PostgresJsTransaction} to type your server mutator transaction.\n *\n * @param schema - Zero schema.\n * @param pg - `postgres` client or connection string.\n *\n * @example\n * ```ts\n * import postgres from 'postgres';\n * import {defineMutator, defineMutators} from '@rocicorp/zero';\n * import {zeroPostgresJS} from '@rocicorp/zero/server/adapters/postgresjs';\n * import {z} from 'zod/mini';\n *\n * const sql = postgres(process.env.ZERO_UPSTREAM_DB!);\n * const zql = zeroPostgresJS(schema, sql);\n *\n * export const serverMutators = defineMutators({\n * user: {\n * create: defineMutator(\n * z.object({id: z.string(), name: z.string()}),\n * async ({tx, args}) => {\n * if (tx.location !== 'server') {\n * throw new Error('Server-only mutator');\n * }\n * await tx.dbTransaction.wrappedTransaction`\n * INSERT INTO \"user\" (id, name, status)\n * VALUES (${args.id}, ${args.name}, ${'active'})\n * `;\n * },\n * ),\n * },\n * });\n * ```\n */\nexport function zeroPostgresJS<\n S extends Schema,\n T extends Record<string, unknown> = Record<string, unknown>,\n>(schema: S, pg: postgres.Sql<T> | string) {\n if (typeof pg === 'string') {\n pg = postgres(pg) as postgres.Sql<T>;\n }\n return new ZQLDatabase(new PostgresJSConnection(pg), schema);\n}\n"],"names":[],"mappings":";;;AA2BO,MAAM,qBAEb;AAAA,EACW;AAAA,EACT,YAAY,IAAqB;AAC/B,SAAK,MAAM;AAAA,EACb;AAAA,EAEA,YACE,IACe;AACf,WAAO,KAAK,IAAI;AAAA,MAAM,CAAA,SACpB,GAAG,IAAI,8BAA8B,IAAI,CAAC;AAAA,IAAA;AAAA,EAE9C;AACF;AAEO,MAAM,8BAEb;AAAA,EACW;AAAA,EACT,YAAY,MAAgC;AAC1C,SAAK,qBAAqB;AAAA,EAC5B;AAAA,EAEA,MAAM,KAAa,QAAmC;AACpD,WAAO,KAAK,mBAAmB,OAAO,KAAK,MAAqB;AAAA,EAClE;AAAA,EAEA,SACE,KACA,QACA,QACA,cACiC;AACjC,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,EAEJ;AACF;AAuCO,SAAS,eAGd,QAAW,IAA8B;AACzC,MAAI,OAAO,OAAO,UAAU;AAC1B,SAAK,SAAS,EAAE;AAAA,EAClB;AACA,SAAO,IAAI,YAAY,IAAI,qBAAqB,EAAE,GAAG,MAAM;AAC7D;"}
@@ -0,0 +1,66 @@
1
+ import type { Schema } from '../../../zero-types/src/schema.ts';
2
+ import type { DBConnection, DBTransaction } from '../../../zql/src/mutate/custom.ts';
3
+ import { ZQLDatabase } from '../zql-database.ts';
4
+ export type { ZQLDatabase };
5
+ export type PrismaTransactionLike = {
6
+ $queryRawUnsafe: (query: string, ...params: unknown[]) => Promise<unknown>;
7
+ };
8
+ export type PrismaClientLike<TTransaction extends PrismaTransactionLike = PrismaTransactionLike> = {
9
+ $transaction: <T>(fn: (tx: TTransaction) => Promise<T>) => Promise<T>;
10
+ };
11
+ /**
12
+ * Helper type for the wrapped transaction used by Prisma.
13
+ *
14
+ * @remarks Use with `ServerTransaction` as `ServerTransaction<Schema, PrismaTransaction<typeof prisma>>`.
15
+ */
16
+ export type PrismaTransaction<TClient extends PrismaClientLike = PrismaClientLike> = TClient extends PrismaClientLike<infer TTransaction> ? TTransaction : PrismaTransactionLike;
17
+ export declare class PrismaConnection<TClient extends PrismaClientLike> implements DBConnection<PrismaTransaction<TClient>> {
18
+ #private;
19
+ constructor(client: TClient);
20
+ transaction<T>(fn: (tx: DBTransaction<PrismaTransaction<TClient>>) => Promise<T>): Promise<T>;
21
+ }
22
+ /**
23
+ * Wrap a Prisma client for Zero ZQL.
24
+ *
25
+ * Provides ZQL querying plus access to the underlying Prisma transaction.
26
+ * Use {@link PrismaTransaction} to type your server mutator transaction.
27
+ *
28
+ * @param schema - Zero schema.
29
+ * @param client - Prisma client.
30
+ *
31
+ * @example
32
+ * ```ts
33
+ * import {PrismaPg} from '@prisma/adapter-pg';
34
+ * import {PrismaClient} from '@prisma/client';
35
+ * import {defineMutator, defineMutators} from '@rocicorp/zero';
36
+ * import {zeroPrisma} from '@rocicorp/zero/server/adapters/prisma';
37
+ * import {z} from 'zod/mini';
38
+ *
39
+ * const prisma = new PrismaClient({
40
+ * adapter: new PrismaPg({connectionString: process.env.ZERO_UPSTREAM_DB!}),
41
+ * });
42
+ * const zql = zeroPrisma(schema, prisma);
43
+ *
44
+ * export const serverMutators = defineMutators({
45
+ * user: {
46
+ * create: defineMutator(
47
+ * z.object({id: z.string(), name: z.string()}),
48
+ * async ({tx, args}) => {
49
+ * if (tx.location !== 'server') {
50
+ * throw new Error('Server-only mutator');
51
+ * }
52
+ * await tx.dbTransaction.wrappedTransaction.user.create({
53
+ * data: {
54
+ * id: args.id,
55
+ * name: args.name,
56
+ * status: 'active',
57
+ * },
58
+ * });
59
+ * },
60
+ * ),
61
+ * },
62
+ * });
63
+ * ```
64
+ */
65
+ export declare function zeroPrisma<TSchema extends Schema, TClient extends PrismaClientLike>(schema: TSchema, client: TClient): ZQLDatabase<TSchema, PrismaTransaction<TClient>>;
66
+ //# sourceMappingURL=prisma.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prisma.d.ts","sourceRoot":"","sources":["../../../../../zero-server/src/adapters/prisma.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,mCAAmC,CAAC;AAE9D,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EAEd,MAAM,mCAAmC,CAAC;AAG3C,OAAO,EAAC,WAAW,EAAC,MAAM,oBAAoB,CAAC;AAE/C,YAAY,EAAC,WAAW,EAAC,CAAC;AAE1B,MAAM,MAAM,qBAAqB,GAAG;IAClC,eAAe,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAC5E,CAAC;AAEF,MAAM,MAAM,gBAAgB,CAC1B,YAAY,SAAS,qBAAqB,GAAG,qBAAqB,IAChE;IACF,YAAY,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,YAAY,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;CACvE,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,CAC3B,OAAO,SAAS,gBAAgB,GAAG,gBAAgB,IAEnD,OAAO,SAAS,gBAAgB,CAAC,MAAM,YAAY,CAAC,GAChD,YAAY,GACZ,qBAAqB,CAAC;AAE5B,qBAAa,gBAAgB,CAAC,OAAO,SAAS,gBAAgB,CAC5D,YAAW,YAAY,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;;gBAIvC,MAAM,EAAE,OAAO;IAI3B,WAAW,CAAC,CAAC,EACX,EAAE,EAAE,CAAC,EAAE,EAAE,aAAa,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,GAChE,OAAO,CAAC,CAAC,CAAC;CASd;AAwDD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,wBAAgB,UAAU,CACxB,OAAO,SAAS,MAAM,EACtB,OAAO,SAAS,gBAAgB,EAEhC,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,OAAO,GACd,WAAW,CAAC,OAAO,EAAE,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAElD"}
@@ -0,0 +1,63 @@
1
+ import { executePostgresQuery } from "../pg-query-executor.js";
2
+ import { ZQLDatabase } from "../zql-database.js";
3
+ class PrismaConnection {
4
+ #client;
5
+ constructor(client) {
6
+ this.#client = client;
7
+ }
8
+ transaction(fn) {
9
+ return this.#client.$transaction(
10
+ (prismaTx) => fn(
11
+ new PrismaInternalTransaction(prismaTx)
12
+ )
13
+ );
14
+ }
15
+ }
16
+ class PrismaInternalTransaction {
17
+ wrappedTransaction;
18
+ constructor(prismaTx) {
19
+ this.wrappedTransaction = prismaTx;
20
+ }
21
+ runQuery(ast, format, schema, serverSchema) {
22
+ return executePostgresQuery(
23
+ this,
24
+ ast,
25
+ format,
26
+ schema,
27
+ serverSchema
28
+ );
29
+ }
30
+ async query(sql, params) {
31
+ const result = await this.wrappedTransaction.$queryRawUnsafe(
32
+ sql,
33
+ ...params
34
+ );
35
+ return toIterableRows(result);
36
+ }
37
+ }
38
+ function isIterable(value) {
39
+ return (
40
+ // oxlint-disable-next-line eqeqeq
41
+ value != null && typeof value[Symbol.iterator] === "function"
42
+ );
43
+ }
44
+ function toIterableRows(result) {
45
+ if (result === null || result === void 0) {
46
+ return [];
47
+ }
48
+ if (Array.isArray(result)) {
49
+ return result;
50
+ }
51
+ if (isIterable(result)) {
52
+ return result;
53
+ }
54
+ return [];
55
+ }
56
+ function zeroPrisma(schema, client) {
57
+ return new ZQLDatabase(new PrismaConnection(client), schema);
58
+ }
59
+ export {
60
+ PrismaConnection,
61
+ zeroPrisma
62
+ };
63
+ //# sourceMappingURL=prisma.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prisma.js","sources":["../../../../../zero-server/src/adapters/prisma.ts"],"sourcesContent":["import type {AST} from '../../../zero-protocol/src/ast.ts';\nimport type {Format} from '../../../zero-types/src/format.ts';\nimport type {Schema} from '../../../zero-types/src/schema.ts';\nimport type {ServerSchema} from '../../../zero-types/src/server-schema.ts';\nimport type {\n DBConnection,\n DBTransaction,\n Row,\n} from '../../../zql/src/mutate/custom.ts';\nimport type {HumanReadable} from '../../../zql/src/query/query.ts';\nimport {executePostgresQuery} from '../pg-query-executor.ts';\nimport {ZQLDatabase} from '../zql-database.ts';\n\nexport type {ZQLDatabase};\n\nexport type PrismaTransactionLike = {\n $queryRawUnsafe: (query: string, ...params: unknown[]) => Promise<unknown>;\n};\n\nexport type PrismaClientLike<\n TTransaction extends PrismaTransactionLike = PrismaTransactionLike,\n> = {\n $transaction: <T>(fn: (tx: TTransaction) => Promise<T>) => Promise<T>;\n};\n\n/**\n * Helper type for the wrapped transaction used by Prisma.\n *\n * @remarks Use with `ServerTransaction` as `ServerTransaction<Schema, PrismaTransaction<typeof prisma>>`.\n */\nexport type PrismaTransaction<\n TClient extends PrismaClientLike = PrismaClientLike,\n> =\n TClient extends PrismaClientLike<infer TTransaction>\n ? TTransaction\n : PrismaTransactionLike;\n\nexport class PrismaConnection<TClient extends PrismaClientLike>\n implements DBConnection<PrismaTransaction<TClient>>\n{\n readonly #client: TClient;\n\n constructor(client: TClient) {\n this.#client = client;\n }\n\n transaction<T>(\n fn: (tx: DBTransaction<PrismaTransaction<TClient>>) => Promise<T>,\n ): Promise<T> {\n return this.#client.$transaction(prismaTx =>\n fn(\n new PrismaInternalTransaction(prismaTx) as DBTransaction<\n PrismaTransaction<TClient>\n >,\n ),\n );\n }\n}\n\nclass PrismaInternalTransaction<TTransaction extends PrismaTransactionLike>\n implements DBTransaction<TTransaction>\n{\n readonly wrappedTransaction: TTransaction;\n\n constructor(prismaTx: TTransaction) {\n this.wrappedTransaction = prismaTx;\n }\n\n runQuery<TReturn>(\n ast: AST,\n format: Format,\n schema: Schema,\n serverSchema: ServerSchema,\n ): Promise<HumanReadable<TReturn>> {\n return executePostgresQuery<TReturn>(\n this,\n ast,\n format,\n schema,\n serverSchema,\n );\n }\n\n async query(sql: string, params: unknown[]): Promise<Iterable<Row>> {\n const result = await this.wrappedTransaction.$queryRawUnsafe(\n sql,\n ...params,\n );\n return toIterableRows(result);\n }\n}\n\nfunction isIterable(value: unknown): value is Iterable<unknown> {\n return (\n // oxlint-disable-next-line eqeqeq\n value != null &&\n typeof (value as Iterable<unknown>)[Symbol.iterator] === 'function'\n );\n}\n\nfunction toIterableRows(result: unknown): Iterable<Row> {\n if (result === null || result === undefined) {\n return [] as Row[];\n }\n if (Array.isArray(result)) {\n return result as Row[];\n }\n if (isIterable(result)) {\n return result as Iterable<Row>;\n }\n return [] as Row[];\n}\n\n/**\n * Wrap a Prisma client for Zero ZQL.\n *\n * Provides ZQL querying plus access to the underlying Prisma transaction.\n * Use {@link PrismaTransaction} to type your server mutator transaction.\n *\n * @param schema - Zero schema.\n * @param client - Prisma client.\n *\n * @example\n * ```ts\n * import {PrismaPg} from '@prisma/adapter-pg';\n * import {PrismaClient} from '@prisma/client';\n * import {defineMutator, defineMutators} from '@rocicorp/zero';\n * import {zeroPrisma} from '@rocicorp/zero/server/adapters/prisma';\n * import {z} from 'zod/mini';\n *\n * const prisma = new PrismaClient({\n * adapter: new PrismaPg({connectionString: process.env.ZERO_UPSTREAM_DB!}),\n * });\n * const zql = zeroPrisma(schema, prisma);\n *\n * export const serverMutators = defineMutators({\n * user: {\n * create: defineMutator(\n * z.object({id: z.string(), name: z.string()}),\n * async ({tx, args}) => {\n * if (tx.location !== 'server') {\n * throw new Error('Server-only mutator');\n * }\n * await tx.dbTransaction.wrappedTransaction.user.create({\n * data: {\n * id: args.id,\n * name: args.name,\n * status: 'active',\n * },\n * });\n * },\n * ),\n * },\n * });\n * ```\n */\nexport function zeroPrisma<\n TSchema extends Schema,\n TClient extends PrismaClientLike,\n>(\n schema: TSchema,\n client: TClient,\n): ZQLDatabase<TSchema, PrismaTransaction<TClient>> {\n return new ZQLDatabase(new PrismaConnection(client), schema);\n}\n"],"names":[],"mappings":";;AAqCO,MAAM,iBAEb;AAAA,EACW;AAAA,EAET,YAAY,QAAiB;AAC3B,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,YACE,IACY;AACZ,WAAO,KAAK,QAAQ;AAAA,MAAa,CAAA,aAC/B;AAAA,QACE,IAAI,0BAA0B,QAAQ;AAAA,MAAA;AAAA,IAGxC;AAAA,EAEJ;AACF;AAEA,MAAM,0BAEN;AAAA,EACW;AAAA,EAET,YAAY,UAAwB;AAClC,SAAK,qBAAqB;AAAA,EAC5B;AAAA,EAEA,SACE,KACA,QACA,QACA,cACiC;AACjC,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,EAEJ;AAAA,EAEA,MAAM,MAAM,KAAa,QAA2C;AAClE,UAAM,SAAS,MAAM,KAAK,mBAAmB;AAAA,MAC3C;AAAA,MACA,GAAG;AAAA,IAAA;AAEL,WAAO,eAAe,MAAM;AAAA,EAC9B;AACF;AAEA,SAAS,WAAW,OAA4C;AAC9D;AAAA;AAAA,IAEE,SAAS,QACT,OAAQ,MAA4B,OAAO,QAAQ,MAAM;AAAA;AAE7D;AAEA,SAAS,eAAe,QAAgC;AACtD,MAAI,WAAW,QAAQ,WAAW,QAAW;AAC3C,WAAO,CAAA;AAAA,EACT;AACA,MAAI,MAAM,QAAQ,MAAM,GAAG;AACzB,WAAO;AAAA,EACT;AACA,MAAI,WAAW,MAAM,GAAG;AACtB,WAAO;AAAA,EACT;AACA,SAAO,CAAA;AACT;AA6CO,SAAS,WAId,QACA,QACkD;AAClD,SAAO,IAAI,YAAY,IAAI,iBAAiB,MAAM,GAAG,MAAM;AAC7D;"}
@@ -55,7 +55,7 @@ function ZeroProvider(props) {
55
55
  let prevAuth = NO_AUTH_SET;
56
56
  createEffect(() => {
57
57
  const currentZero = zero();
58
- if (!currentZero) {
58
+ if (!currentZero || "zero" in props) {
59
59
  return;
60
60
  }
61
61
  const currentAuth = auth();
@@ -1 +1 @@
1
- {"version":3,"file":"use-zero.js","sources":["../../../../zero-solid/src/use-zero.ts"],"sourcesContent":["import {\n batch,\n createContext,\n createEffect,\n createMemo,\n onCleanup,\n splitProps,\n untrack,\n useContext,\n type Accessor,\n type JSX,\n} from 'solid-js';\nimport {\n Zero,\n type CustomMutatorDefs,\n type DefaultContext,\n type DefaultSchema,\n type Schema,\n type ZeroOptions,\n} from './zero.ts';\n\nconst ZeroContext = createContext<\n // oxlint-disable-next-line no-explicit-any\n Accessor<Zero<any, any, any>> | undefined\n>(undefined);\n\n/**\n * @deprecated Use {@linkcode ZeroProvider} instead of managing your own Zero instance.\n */\nexport function createZero<\n S extends Schema = DefaultSchema,\n MD extends CustomMutatorDefs | undefined = undefined,\n Context = DefaultContext,\n>(options: ZeroOptions<S, MD, Context>): Zero<S, MD, Context> {\n const opts = {\n ...options,\n batchViewUpdates: batch,\n };\n return new Zero(opts);\n}\n\nexport function useZero<\n S extends Schema = DefaultSchema,\n MD extends CustomMutatorDefs | undefined = undefined,\n Context = DefaultContext,\n>(): () => Zero<S, MD, Context> {\n const zero = useContext(ZeroContext);\n\n if (zero === undefined) {\n throw new Error('useZero must be used within a ZeroProvider');\n }\n return zero;\n}\n\n/**\n * @deprecated Use {@linkcode useZero} instead, alongside default types defined with:\n *\n * ```ts\n * declare module '@rocicorp/zero' {\n * interface DefaultTypes {\n * schema: typeof schema;\n * context: Context;\n * }\n * }\n */\nexport function createUseZero<\n S extends Schema = DefaultSchema,\n MD extends CustomMutatorDefs | undefined = undefined,\n Context = DefaultContext,\n>() {\n return () => useZero<S, MD, Context>();\n}\n\nconst NO_AUTH_SET = Symbol();\n\nexport function ZeroProvider<\n S extends Schema = DefaultSchema,\n MD extends CustomMutatorDefs | undefined = undefined,\n Context = DefaultContext,\n>(\n props: {\n children: JSX.Element;\n init?: (zero: Zero<S, MD, Context>) => void;\n } & (\n | {\n zero: Zero<S, MD, Context>;\n }\n | ZeroOptions<S, MD, Context>\n ),\n) {\n const zero = createMemo(() => {\n if ('zero' in props) {\n return props.zero;\n }\n\n const [, options] = splitProps(props, ['children', 'auth']);\n\n const authValue = untrack(() => props.auth);\n const createdZero = new Zero({\n ...options,\n ...(authValue !== undefined ? {auth: authValue} : {}),\n batchViewUpdates: batch,\n });\n options.init?.(createdZero);\n onCleanup(() => createdZero.close());\n return createdZero;\n });\n\n const auth = createMemo<\n typeof NO_AUTH_SET | ZeroOptions<S, MD, Context>['auth']\n >(() => ('auth' in props ? props.auth : NO_AUTH_SET));\n\n let prevAuth: typeof NO_AUTH_SET | ZeroOptions<S, MD, Context>['auth'] =\n NO_AUTH_SET;\n\n createEffect(() => {\n const currentZero = zero();\n if (!currentZero) {\n return;\n }\n\n const currentAuth = auth();\n\n if (prevAuth === NO_AUTH_SET) {\n prevAuth = currentAuth;\n return;\n }\n\n if (currentAuth !== prevAuth) {\n prevAuth = currentAuth;\n void currentZero.connection.connect({\n auth: currentAuth === NO_AUTH_SET ? undefined : currentAuth,\n });\n }\n });\n\n return ZeroContext.Provider({\n value: zero,\n get children() {\n return props.children;\n },\n });\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAqBA,MAAM,cAAc,cAGlB,MAAS;AAKJ,SAAS,WAId,SAA4D;AAC5D,QAAM,OAAO;AAAA,IACX,GAAG;AAAA,IACH,kBAAkB;AAAA,EAAA;AAEpB,SAAO,IAAI,KAAK,IAAI;AACtB;AAEO,SAAS,UAIgB;AAC9B,QAAM,OAAO,WAAW,WAAW;AAEnC,MAAI,SAAS,QAAW;AACtB,UAAM,IAAI,MAAM,4CAA4C;AAAA,EAC9D;AACA,SAAO;AACT;AAaO,SAAS,gBAIZ;AACF,SAAO,MAAM,QAAA;AACf;AAEA,MAAM,cAAc,OAAA;AAEb,SAAS,aAKd,OASA;AACA,QAAM,OAAO,WAAW,MAAM;AAC5B,QAAI,UAAU,OAAO;AACnB,aAAO,MAAM;AAAA,IACf;AAEA,UAAM,CAAA,EAAG,OAAO,IAAI,WAAW,OAAO,CAAC,YAAY,MAAM,CAAC;AAE1D,UAAM,YAAY,QAAQ,MAAM,MAAM,IAAI;AAC1C,UAAM,cAAc,IAAI,KAAK;AAAA,MAC3B,GAAG;AAAA,MACH,GAAI,cAAc,SAAY,EAAC,MAAM,UAAA,IAAa,CAAA;AAAA,MAClD,kBAAkB;AAAA,IAAA,CACnB;AACD,YAAQ,OAAO,WAAW;AAC1B,cAAU,MAAM,YAAY,OAAO;AACnC,WAAO;AAAA,EACT,CAAC;AAED,QAAM,OAAO,WAEX,MAAO,UAAU,QAAQ,MAAM,OAAO,WAAY;AAEpD,MAAI,WACF;AAEF,eAAa,MAAM;AACjB,UAAM,cAAc,KAAA;AACpB,QAAI,CAAC,aAAa;AAChB;AAAA,IACF;AAEA,UAAM,cAAc,KAAA;AAEpB,QAAI,aAAa,aAAa;AAC5B,iBAAW;AACX;AAAA,IACF;AAEA,QAAI,gBAAgB,UAAU;AAC5B,iBAAW;AACX,WAAK,YAAY,WAAW,QAAQ;AAAA,QAClC,MAAM,gBAAgB,cAAc,SAAY;AAAA,MAAA,CACjD;AAAA,IACH;AAAA,EACF,CAAC;AAED,SAAO,YAAY,SAAS;AAAA,IAC1B,OAAO;AAAA,IACP,IAAI,WAAW;AACb,aAAO,MAAM;AAAA,IACf;AAAA,EAAA,CACD;AACH;"}
1
+ {"version":3,"file":"use-zero.js","sources":["../../../../zero-solid/src/use-zero.ts"],"sourcesContent":["import {\n batch,\n createContext,\n createEffect,\n createMemo,\n onCleanup,\n splitProps,\n untrack,\n useContext,\n type Accessor,\n type JSX,\n} from 'solid-js';\nimport {\n Zero,\n type CustomMutatorDefs,\n type DefaultContext,\n type DefaultSchema,\n type Schema,\n type ZeroOptions,\n} from './zero.ts';\n\nconst ZeroContext = createContext<\n // oxlint-disable-next-line no-explicit-any\n Accessor<Zero<any, any, any>> | undefined\n>(undefined);\n\n/**\n * @deprecated Use {@linkcode ZeroProvider} instead of managing your own Zero instance.\n */\nexport function createZero<\n S extends Schema = DefaultSchema,\n MD extends CustomMutatorDefs | undefined = undefined,\n Context = DefaultContext,\n>(options: ZeroOptions<S, MD, Context>): Zero<S, MD, Context> {\n const opts = {\n ...options,\n batchViewUpdates: batch,\n };\n return new Zero(opts);\n}\n\nexport function useZero<\n S extends Schema = DefaultSchema,\n MD extends CustomMutatorDefs | undefined = undefined,\n Context = DefaultContext,\n>(): () => Zero<S, MD, Context> {\n const zero = useContext(ZeroContext);\n\n if (zero === undefined) {\n throw new Error('useZero must be used within a ZeroProvider');\n }\n return zero;\n}\n\n/**\n * @deprecated Use {@linkcode useZero} instead, alongside default types defined with:\n *\n * ```ts\n * declare module '@rocicorp/zero' {\n * interface DefaultTypes {\n * schema: typeof schema;\n * context: Context;\n * }\n * }\n */\nexport function createUseZero<\n S extends Schema = DefaultSchema,\n MD extends CustomMutatorDefs | undefined = undefined,\n Context = DefaultContext,\n>() {\n return () => useZero<S, MD, Context>();\n}\n\nconst NO_AUTH_SET = Symbol();\n\nexport function ZeroProvider<\n S extends Schema = DefaultSchema,\n MD extends CustomMutatorDefs | undefined = undefined,\n Context = DefaultContext,\n>(\n props: {\n children: JSX.Element;\n init?: (zero: Zero<S, MD, Context>) => void;\n } & (\n | {\n zero: Zero<S, MD, Context>;\n }\n | ZeroOptions<S, MD, Context>\n ),\n) {\n const zero = createMemo(() => {\n if ('zero' in props) {\n return props.zero;\n }\n\n const [, options] = splitProps(props, ['children', 'auth']);\n\n const authValue = untrack(() => props.auth);\n const createdZero = new Zero({\n ...options,\n ...(authValue !== undefined ? {auth: authValue} : {}),\n batchViewUpdates: batch,\n });\n options.init?.(createdZero);\n onCleanup(() => createdZero.close());\n return createdZero;\n });\n\n const auth = createMemo<\n typeof NO_AUTH_SET | ZeroOptions<S, MD, Context>['auth']\n >(() => ('auth' in props ? props.auth : NO_AUTH_SET));\n\n let prevAuth: typeof NO_AUTH_SET | ZeroOptions<S, MD, Context>['auth'] =\n NO_AUTH_SET;\n\n createEffect(() => {\n const currentZero = zero();\n if (!currentZero || 'zero' in props) {\n return;\n }\n\n const currentAuth = auth();\n\n if (prevAuth === NO_AUTH_SET) {\n prevAuth = currentAuth;\n return;\n }\n\n if (currentAuth !== prevAuth) {\n prevAuth = currentAuth;\n void currentZero.connection.connect({\n auth: currentAuth === NO_AUTH_SET ? undefined : currentAuth,\n });\n }\n });\n\n return ZeroContext.Provider({\n value: zero,\n get children() {\n return props.children;\n },\n });\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAqBA,MAAM,cAAc,cAGlB,MAAS;AAKJ,SAAS,WAId,SAA4D;AAC5D,QAAM,OAAO;AAAA,IACX,GAAG;AAAA,IACH,kBAAkB;AAAA,EAAA;AAEpB,SAAO,IAAI,KAAK,IAAI;AACtB;AAEO,SAAS,UAIgB;AAC9B,QAAM,OAAO,WAAW,WAAW;AAEnC,MAAI,SAAS,QAAW;AACtB,UAAM,IAAI,MAAM,4CAA4C;AAAA,EAC9D;AACA,SAAO;AACT;AAaO,SAAS,gBAIZ;AACF,SAAO,MAAM,QAAA;AACf;AAEA,MAAM,cAAc,OAAA;AAEb,SAAS,aAKd,OASA;AACA,QAAM,OAAO,WAAW,MAAM;AAC5B,QAAI,UAAU,OAAO;AACnB,aAAO,MAAM;AAAA,IACf;AAEA,UAAM,CAAA,EAAG,OAAO,IAAI,WAAW,OAAO,CAAC,YAAY,MAAM,CAAC;AAE1D,UAAM,YAAY,QAAQ,MAAM,MAAM,IAAI;AAC1C,UAAM,cAAc,IAAI,KAAK;AAAA,MAC3B,GAAG;AAAA,MACH,GAAI,cAAc,SAAY,EAAC,MAAM,UAAA,IAAa,CAAA;AAAA,MAClD,kBAAkB;AAAA,IAAA,CACnB;AACD,YAAQ,OAAO,WAAW;AAC1B,cAAU,MAAM,YAAY,OAAO;AACnC,WAAO;AAAA,EACT,CAAC;AAED,QAAM,OAAO,WAEX,MAAO,UAAU,QAAQ,MAAM,OAAO,WAAY;AAEpD,MAAI,WACF;AAEF,eAAa,MAAM;AACjB,UAAM,cAAc,KAAA;AACpB,QAAI,CAAC,eAAe,UAAU,OAAO;AACnC;AAAA,IACF;AAEA,UAAM,cAAc,KAAA;AAEpB,QAAI,aAAa,aAAa;AAC5B,iBAAW;AACX;AAAA,IACF;AAEA,QAAI,gBAAgB,UAAU;AAC5B,iBAAW;AACX,WAAK,YAAY,WAAW,QAAQ;AAAA,QAClC,MAAM,gBAAgB,cAAc,SAAY;AAAA,MAAA,CACjD;AAAA,IACH;AAAA,EACF,CAAC;AAED,SAAO,YAAY,SAAS;AAAA,IAC1B,OAAO;AAAA,IACP,IAAI,WAAW;AACb,aAAO,MAAM;AAAA,IACf;AAAA,EAAA,CACD;AACH;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rocicorp/zero",
3
- "version": "0.25.10-canary.6",
3
+ "version": "0.25.10-canary.7",
4
4
  "description": "Zero is a web framework for serverless web development.",
5
5
  "author": "Rocicorp, Inc.",
6
6
  "repository": {
@@ -155,6 +155,10 @@
155
155
  "types": "./out/zero/src/adapters/drizzle.d.ts",
156
156
  "default": "./out/zero/src/adapters/drizzle.js"
157
157
  },
158
+ "./server/adapters/prisma": {
159
+ "types": "./out/zero/src/adapters/prisma.d.ts",
160
+ "default": "./out/zero/src/adapters/prisma.js"
161
+ },
158
162
  "./server/adapters/pg": {
159
163
  "types": "./out/zero/src/adapters/pg.d.ts",
160
164
  "default": "./out/zero/src/adapters/pg.js"