@rocicorp/zero 0.25.0-canary.1 → 0.25.0-canary.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. package/out/{chunk-AIPM77UE.js → chunk-COKJ5W7V.js} +509 -311
  2. package/out/chunk-COKJ5W7V.js.map +7 -0
  3. package/out/{chunk-55BOUNXO.js → chunk-YWU2DZ23.js} +19 -3
  4. package/out/{chunk-55BOUNXO.js.map → chunk-YWU2DZ23.js.map} +3 -3
  5. package/out/react.js +44 -25
  6. package/out/react.js.map +2 -2
  7. package/out/shared/src/error.d.ts +4 -0
  8. package/out/shared/src/error.d.ts.map +1 -0
  9. package/out/shared/src/error.js +70 -0
  10. package/out/shared/src/error.js.map +1 -0
  11. package/out/solid.js +44 -18
  12. package/out/solid.js.map +2 -2
  13. package/out/zero/package.json +3 -2
  14. package/out/zero/src/zero-out.d.ts +3 -0
  15. package/out/zero/src/zero-out.d.ts.map +1 -0
  16. package/out/zero/src/zero-out.js +13 -0
  17. package/out/zero/src/zero-out.js.map +1 -0
  18. package/out/zero-cache/src/custom/fetch.js +3 -3
  19. package/out/zero-cache/src/custom/fetch.js.map +1 -1
  20. package/out/zero-cache/src/scripts/decommission.d.ts +50 -0
  21. package/out/zero-cache/src/scripts/decommission.d.ts.map +1 -0
  22. package/out/zero-cache/src/scripts/decommission.js +51 -0
  23. package/out/zero-cache/src/scripts/decommission.js.map +1 -0
  24. package/out/zero-cache/src/server/inspector-delegate.d.ts.map +1 -1
  25. package/out/zero-cache/src/server/inspector-delegate.js +2 -1
  26. package/out/zero-cache/src/server/inspector-delegate.js.map +1 -1
  27. package/out/zero-cache/src/services/mutagen/pusher.d.ts +17 -21
  28. package/out/zero-cache/src/services/mutagen/pusher.d.ts.map +1 -1
  29. package/out/zero-cache/src/services/mutagen/pusher.js +4 -4
  30. package/out/zero-cache/src/services/mutagen/pusher.js.map +1 -1
  31. package/out/zero-cache/src/services/view-syncer/drain-coordinator.d.ts +1 -0
  32. package/out/zero-cache/src/services/view-syncer/drain-coordinator.d.ts.map +1 -1
  33. package/out/zero-cache/src/services/view-syncer/drain-coordinator.js +5 -0
  34. package/out/zero-cache/src/services/view-syncer/drain-coordinator.js.map +1 -1
  35. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts +7 -0
  36. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
  37. package/out/zero-cache/src/services/view-syncer/view-syncer.js +24 -1
  38. package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
  39. package/out/zero-cache/src/types/streams.d.ts +1 -1
  40. package/out/zero-cache/src/types/streams.d.ts.map +1 -1
  41. package/out/zero-cache/src/types/streams.js +19 -9
  42. package/out/zero-cache/src/types/streams.js.map +1 -1
  43. package/out/zero-cache/src/types/subscription.d.ts +16 -1
  44. package/out/zero-cache/src/types/subscription.d.ts.map +1 -1
  45. package/out/zero-cache/src/types/subscription.js +41 -5
  46. package/out/zero-cache/src/types/subscription.js.map +1 -1
  47. package/out/zero-cache/src/workers/syncer.d.ts.map +1 -1
  48. package/out/zero-cache/src/workers/syncer.js +1 -3
  49. package/out/zero-cache/src/workers/syncer.js.map +1 -1
  50. package/out/zero-client/src/client/connection-manager.d.ts +21 -5
  51. package/out/zero-client/src/client/connection-manager.d.ts.map +1 -1
  52. package/out/zero-client/src/client/connection-status-enum.d.ts +2 -0
  53. package/out/zero-client/src/client/connection-status-enum.d.ts.map +1 -1
  54. package/out/zero-client/src/client/connection.d.ts +11 -3
  55. package/out/zero-client/src/client/connection.d.ts.map +1 -1
  56. package/out/zero-client/src/client/error.d.ts +33 -161
  57. package/out/zero-client/src/client/error.d.ts.map +1 -1
  58. package/out/zero-client/src/client/mutation-tracker.d.ts.map +1 -1
  59. package/out/zero-client/src/client/options.d.ts +9 -16
  60. package/out/zero-client/src/client/options.d.ts.map +1 -1
  61. package/out/zero-client/src/client/query-manager.d.ts.map +1 -1
  62. package/out/zero-client/src/client/zero-rep.d.ts +2 -0
  63. package/out/zero-client/src/client/zero-rep.d.ts.map +1 -1
  64. package/out/zero-client/src/client/zero.d.ts.map +1 -1
  65. package/out/zero-client/src/mod.d.ts +4 -1
  66. package/out/zero-client/src/mod.d.ts.map +1 -1
  67. package/out/zero-client/src/types/query-result.d.ts +23 -0
  68. package/out/zero-client/src/types/query-result.d.ts.map +1 -0
  69. package/out/zero-protocol/src/application-error.d.ts +33 -0
  70. package/out/zero-protocol/src/application-error.d.ts.map +1 -0
  71. package/out/zero-protocol/src/application-error.js +37 -0
  72. package/out/zero-protocol/src/application-error.js.map +1 -0
  73. package/out/zero-protocol/src/custom-queries.d.ts +27 -95
  74. package/out/zero-protocol/src/custom-queries.d.ts.map +1 -1
  75. package/out/zero-protocol/src/custom-queries.js +9 -24
  76. package/out/zero-protocol/src/custom-queries.js.map +1 -1
  77. package/out/zero-protocol/src/down.d.ts +7 -9
  78. package/out/zero-protocol/src/down.d.ts.map +1 -1
  79. package/out/zero-protocol/src/error.d.ts +42 -0
  80. package/out/zero-protocol/src/error.d.ts.map +1 -1
  81. package/out/zero-protocol/src/error.js +7 -0
  82. package/out/zero-protocol/src/error.js.map +1 -1
  83. package/out/zero-protocol/src/mutations-patch.d.ts +3 -0
  84. package/out/zero-protocol/src/mutations-patch.d.ts.map +1 -1
  85. package/out/zero-protocol/src/poke.d.ts +2 -0
  86. package/out/zero-protocol/src/poke.d.ts.map +1 -1
  87. package/out/zero-protocol/src/protocol-version.d.ts +1 -1
  88. package/out/zero-protocol/src/protocol-version.d.ts.map +1 -1
  89. package/out/zero-protocol/src/protocol-version.js +2 -1
  90. package/out/zero-protocol/src/protocol-version.js.map +1 -1
  91. package/out/zero-protocol/src/push.d.ts +7 -0
  92. package/out/zero-protocol/src/push.d.ts.map +1 -1
  93. package/out/zero-protocol/src/push.js +1 -0
  94. package/out/zero-protocol/src/push.js.map +1 -1
  95. package/out/zero-react/src/mod.d.ts +5 -1
  96. package/out/zero-react/src/mod.d.ts.map +1 -1
  97. package/out/zero-react/src/use-query.d.ts +1 -21
  98. package/out/zero-react/src/use-query.d.ts.map +1 -1
  99. package/out/zero-react/src/zero-provider.d.ts.map +1 -1
  100. package/out/zero-server/src/mod.d.ts +5 -4
  101. package/out/zero-server/src/mod.d.ts.map +1 -1
  102. package/out/zero-server/src/mod.js +5 -4
  103. package/out/zero-server/src/mod.js.map +1 -1
  104. package/out/zero-server/src/process-mutations.d.ts.map +1 -1
  105. package/out/zero-server/src/process-mutations.js +181 -68
  106. package/out/zero-server/src/process-mutations.js.map +1 -1
  107. package/out/zero-server/src/queries/process-queries.d.ts +4 -3
  108. package/out/zero-server/src/queries/process-queries.d.ts.map +1 -1
  109. package/out/zero-server/src/queries/process-queries.js +85 -19
  110. package/out/zero-server/src/queries/process-queries.js.map +1 -1
  111. package/out/zero-solid/src/mod.d.ts +8 -0
  112. package/out/zero-solid/src/mod.d.ts.map +1 -1
  113. package/out/zero-solid/src/solid-view.d.ts +3 -23
  114. package/out/zero-solid/src/solid-view.d.ts.map +1 -1
  115. package/out/zero-solid/src/use-query.d.ts +1 -1
  116. package/out/zero-solid/src/use-query.d.ts.map +1 -1
  117. package/out/zero-solid/src/use-zero.d.ts +1 -0
  118. package/out/zero-solid/src/use-zero.d.ts.map +1 -1
  119. package/out/zero.js +4 -2
  120. package/out/zql/src/planner/planner-builder.d.ts +2 -1
  121. package/out/zql/src/planner/planner-builder.d.ts.map +1 -1
  122. package/out/zql/src/planner/planner-builder.js +6 -6
  123. package/out/zql/src/planner/planner-builder.js.map +1 -1
  124. package/out/zql/src/planner/planner-connection.d.ts +9 -3
  125. package/out/zql/src/planner/planner-connection.d.ts.map +1 -1
  126. package/out/zql/src/planner/planner-connection.js +38 -82
  127. package/out/zql/src/planner/planner-connection.js.map +1 -1
  128. package/out/zql/src/planner/planner-debug.d.ts +37 -7
  129. package/out/zql/src/planner/planner-debug.d.ts.map +1 -1
  130. package/out/zql/src/planner/planner-debug.js +131 -80
  131. package/out/zql/src/planner/planner-debug.js.map +1 -1
  132. package/out/zql/src/planner/planner-fan-in.d.ts +5 -3
  133. package/out/zql/src/planner/planner-fan-in.d.ts.map +1 -1
  134. package/out/zql/src/planner/planner-fan-in.js +41 -23
  135. package/out/zql/src/planner/planner-fan-in.js.map +1 -1
  136. package/out/zql/src/planner/planner-fan-out.d.ts +5 -3
  137. package/out/zql/src/planner/planner-fan-out.d.ts.map +1 -1
  138. package/out/zql/src/planner/planner-fan-out.js +22 -5
  139. package/out/zql/src/planner/planner-fan-out.js.map +1 -1
  140. package/out/zql/src/planner/planner-graph.d.ts +2 -2
  141. package/out/zql/src/planner/planner-graph.d.ts.map +1 -1
  142. package/out/zql/src/planner/planner-graph.js +17 -48
  143. package/out/zql/src/planner/planner-graph.js.map +1 -1
  144. package/out/zql/src/planner/planner-join.d.ts +61 -6
  145. package/out/zql/src/planner/planner-join.d.ts.map +1 -1
  146. package/out/zql/src/planner/planner-join.js +148 -65
  147. package/out/zql/src/planner/planner-join.js.map +1 -1
  148. package/out/zql/src/planner/planner-node.d.ts +29 -2
  149. package/out/zql/src/planner/planner-node.d.ts.map +1 -1
  150. package/out/zql/src/planner/planner-source.d.ts +1 -1
  151. package/out/zql/src/planner/planner-source.d.ts.map +1 -1
  152. package/out/zql/src/planner/planner-source.js +2 -2
  153. package/out/zql/src/planner/planner-source.js.map +1 -1
  154. package/out/zql/src/planner/planner-terminus.d.ts +4 -3
  155. package/out/zql/src/planner/planner-terminus.d.ts.map +1 -1
  156. package/out/zql/src/planner/planner-terminus.js +4 -4
  157. package/out/zql/src/planner/planner-terminus.js.map +1 -1
  158. package/out/zql/src/query/error.d.ts +4 -0
  159. package/out/zql/src/query/error.d.ts.map +1 -0
  160. package/out/zql/src/query/error.js +9 -0
  161. package/out/zql/src/query/error.js.map +1 -0
  162. package/out/zql/src/query/named.d.ts.map +1 -1
  163. package/out/zql/src/query/named.js +9 -1
  164. package/out/zql/src/query/named.js.map +1 -1
  165. package/package.json +3 -2
  166. package/out/chunk-AIPM77UE.js.map +0 -7
@@ -5,7 +5,7 @@ import {
5
5
  defaultFormat,
6
6
  newQuery,
7
7
  newQuerySymbol
8
- } from "./chunk-AIPM77UE.js";
8
+ } from "./chunk-COKJ5W7V.js";
9
9
  import {
10
10
  mapCondition,
11
11
  toStaticParam
@@ -273,6 +273,17 @@ function escapeLike(val) {
273
273
  return val.replace(/[%_]/g, "\\$&");
274
274
  }
275
275
 
276
+ // ../zql/src/query/error.ts
277
+ var QueryParseError = class extends Error {
278
+ constructor(opts) {
279
+ super(
280
+ opts?.cause instanceof Error ? `Failed to parse arguments for query: ${opts.cause.message}` : `Failed to parse arguments for query`,
281
+ opts
282
+ );
283
+ this.name = "QueryParseError";
284
+ }
285
+ };
286
+
276
287
  // ../zql/src/query/named.ts
277
288
  function normalizeParser(parser) {
278
289
  if (parser) {
@@ -311,7 +322,12 @@ function withValidation(fn) {
311
322
  }
312
323
  const ret = (context, ...args) => {
313
324
  const f = fn;
314
- const parsed = f.parse(args);
325
+ let parsed;
326
+ try {
327
+ parsed = f.parse(args);
328
+ } catch (error) {
329
+ throw new QueryParseError({ cause: error });
330
+ }
315
331
  return f.takesContext ? f(context, ...parsed) : f(...parsed);
316
332
  };
317
333
  ret.queryName = fn.queryName;
@@ -353,4 +369,4 @@ export {
353
369
  withValidation,
354
370
  createBuilder
355
371
  };
356
- //# sourceMappingURL=chunk-55BOUNXO.js.map
372
+ //# sourceMappingURL=chunk-YWU2DZ23.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../zero-schema/src/builder/relationship-builder.ts", "../../zql/src/query/static-query.ts", "../../zero-schema/src/permissions.ts", "../../zql/src/query/escape-like.ts", "../../zql/src/query/named.ts"],
4
- "sourcesContent": ["/* oxlint-disable @typescript-eslint/no-explicit-any */\nimport type {Relationship, TableSchema} from '../table-schema.ts';\nimport type {TableBuilderWithColumns} from './table-builder.ts';\n\ntype ConnectArg<TSourceField, TDestField, TDest extends TableSchema> = {\n readonly sourceField: TSourceField;\n readonly destField: TDestField;\n readonly destSchema: TableBuilderWithColumns<TDest>;\n};\n\ntype ManyConnection<TSourceField, TDestField, TDest extends TableSchema> = {\n readonly sourceField: TSourceField;\n readonly destField: TDestField;\n readonly destSchema: TDest['name'];\n readonly cardinality: 'many';\n};\n\ntype OneConnection<TSourceField, TDestField, TDest extends TableSchema> = {\n readonly sourceField: TSourceField;\n readonly destField: TDestField;\n readonly destSchema: TDest['name'];\n readonly cardinality: 'one';\n};\n\ntype Prev = [-1, 0, 1, 2, 3, 4, 5, 6];\n\nexport type PreviousSchema<\n TSource extends TableSchema,\n K extends number,\n TDests extends TableSchema[],\n> = K extends 0 ? TSource : TDests[Prev[K]];\n\nexport type Relationships = {\n name: string; // table name\n relationships: Record<string, Relationship>; // relationships for that table\n};\n\n// Overloaded types for better inference\ntype ManyConnector<TSource extends TableSchema> = {\n // Single direct relationship\n <TDest extends TableSchema>(\n arg: ConnectArg<\n readonly (keyof TSource['columns'] & string)[],\n readonly (keyof TDest['columns'] & string)[],\n TDest\n >,\n ): [\n ManyConnection<\n readonly (keyof TSource['columns'] & string)[],\n readonly (keyof TDest['columns'] & string)[],\n TDest\n >,\n ];\n\n // Junction relationship (two hops)\n <TJunction extends TableSchema, TDest extends TableSchema>(\n firstHop: ConnectArg<\n readonly (keyof TSource['columns'] & string)[],\n readonly (keyof TJunction['columns'] & string)[],\n TJunction\n >,\n secondHop: ConnectArg<\n readonly (keyof TJunction['columns'] & string)[],\n readonly (keyof TDest['columns'] & string)[],\n TDest\n >,\n ): [\n ManyConnection<\n readonly (keyof TSource['columns'] & string)[],\n readonly (keyof TJunction['columns'] & string)[],\n TJunction\n >,\n ManyConnection<\n readonly (keyof TJunction['columns'] & string)[],\n readonly (keyof TDest['columns'] & string)[],\n TDest\n >,\n ];\n};\n\ntype OneConnector<TSource extends TableSchema> = {\n // Single direct relationship\n <TDest extends TableSchema>(\n arg: ConnectArg<\n readonly (keyof TSource['columns'] & string)[],\n readonly (keyof TDest['columns'] & string)[],\n TDest\n >,\n ): [\n OneConnection<\n readonly (keyof TSource['columns'] & string)[],\n readonly (keyof TDest['columns'] & string)[],\n TDest\n >,\n ];\n\n // Two-hop relationship (e.g., invoice_line -> invoice -> customer)\n <TIntermediate extends TableSchema, TDest extends TableSchema>(\n firstHop: ConnectArg<\n readonly (keyof TSource['columns'] & string)[],\n readonly (keyof TIntermediate['columns'] & string)[],\n TIntermediate\n >,\n secondHop: ConnectArg<\n readonly (keyof TIntermediate['columns'] & string)[],\n readonly (keyof TDest['columns'] & string)[],\n TDest\n >,\n ): [\n OneConnection<\n readonly (keyof TSource['columns'] & string)[],\n readonly (keyof TIntermediate['columns'] & string)[],\n TIntermediate\n >,\n OneConnection<\n readonly (keyof TIntermediate['columns'] & string)[],\n readonly (keyof TDest['columns'] & string)[],\n TDest\n >,\n ];\n};\n\nexport function relationships<\n TSource extends TableSchema,\n TRelationships extends Record<string, Relationship>,\n>(\n table: TableBuilderWithColumns<TSource>,\n cb: (connects: {\n many: ManyConnector<TSource>;\n one: OneConnector<TSource>;\n }) => TRelationships,\n): {name: TSource['name']; relationships: TRelationships} {\n const relationships = cb({many, one} as any);\n\n return {\n name: table.schema.name,\n relationships,\n };\n}\n\nfunction many(\n ...args: readonly ConnectArg<any, any, TableSchema>[]\n): ManyConnection<any, any, any>[] {\n return args.map(arg => ({\n sourceField: arg.sourceField,\n destField: arg.destField,\n destSchema: arg.destSchema.schema.name,\n cardinality: 'many',\n }));\n}\n\nfunction one(\n ...args: readonly ConnectArg<any, any, TableSchema>[]\n): OneConnection<any, any, any>[] {\n return args.map(arg => ({\n sourceField: arg.sourceField,\n destField: arg.destField,\n destSchema: arg.destSchema.schema.name,\n cardinality: 'one',\n }));\n}\n", "import type {AST, System} from '../../../zero-protocol/src/ast.ts';\nimport type {Schema} from '../../../zero-types/src/schema.ts';\nimport {defaultFormat} from '../ivm/default-format.ts';\nimport type {Format} from '../ivm/view.ts';\nimport {ExpressionBuilder} from './expression.ts';\nimport type {CustomQueryID} from './named.ts';\nimport type {QueryDelegate} from './query-delegate.ts';\nimport {AbstractQuery, newQuerySymbol} from './query-impl.ts';\nimport type {HumanReadable, PullRow, Query} from './query.ts';\nimport type {TypedView} from './typed-view.ts';\n\nexport function staticQuery<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n>(schema: TSchema, tableName: TTable): Query<TSchema, TTable> {\n return new StaticQuery<TSchema, TTable>(\n schema,\n tableName,\n {table: tableName},\n defaultFormat,\n );\n}\n\n/**\n * A query that cannot be run.\n * Only serves to generate ASTs.\n */\nexport class StaticQuery<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n TReturn = PullRow<TTable, TSchema>,\n> extends AbstractQuery<TSchema, TTable, TReturn> {\n constructor(\n schema: TSchema,\n tableName: TTable,\n ast: AST,\n format: Format,\n system: System = 'permissions',\n customQueryID?: CustomQueryID,\n currentJunction?: string,\n ) {\n super(\n undefined,\n schema,\n tableName,\n ast,\n format,\n system,\n customQueryID,\n currentJunction,\n );\n }\n\n expressionBuilder() {\n return new ExpressionBuilder(this._exists);\n }\n\n protected [newQuerySymbol]<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n TReturn,\n >(\n _delegate: QueryDelegate | undefined,\n schema: TSchema,\n tableName: TTable,\n ast: AST,\n format: Format,\n customQueryID: CustomQueryID | undefined,\n currentJunction: string | undefined,\n ): StaticQuery<TSchema, TTable, TReturn> {\n return new StaticQuery(\n schema,\n tableName,\n ast,\n format,\n 'permissions',\n customQueryID,\n currentJunction,\n );\n }\n\n get ast() {\n return this._completeAst();\n }\n\n materialize(): TypedView<HumanReadable<TReturn>> {\n throw new Error('StaticQuery cannot be materialized');\n }\n\n run(): Promise<HumanReadable<TReturn>> {\n return Promise.reject(new Error('StaticQuery cannot be run'));\n }\n\n preload(): {\n cleanup: () => void;\n complete: Promise<void>;\n } {\n throw new Error('StaticQuery cannot be preloaded');\n }\n}\n", "import {assert} from '../../shared/src/asserts.ts';\nimport {\n mapCondition,\n toStaticParam,\n type Condition,\n type Parameter,\n} from '../../zero-protocol/src/ast.ts';\nimport {defaultFormat} from '../../zero-types/src/format.ts';\nimport type {ExpressionBuilder} from '../../zql/src/query/expression.ts';\nimport type {Query} from '../../zql/src/query/query.ts';\nimport {StaticQuery} from '../../zql/src/query/static-query.ts';\nimport type {Schema} from './builder/schema-builder.ts';\nimport type {\n AssetPermissions as CompiledAssetPermissions,\n PermissionsConfig as CompiledPermissionsConfig,\n} from './compiled-permissions.ts';\nimport {clientToServer, NameMapper} from './name-mapper.ts';\n\nexport const ANYONE_CAN = [\n (_: unknown, eb: ExpressionBuilder<Schema, never>) => eb.and(),\n];\n\n/**\n * @deprecated Use {@link ANYONE_CAN} instead.\n */\nexport const ANYONE_CAN_DO_ANYTHING = {\n row: {\n select: ANYONE_CAN,\n insert: ANYONE_CAN,\n update: {\n preMutation: ANYONE_CAN,\n postMutation: ANYONE_CAN,\n },\n delete: ANYONE_CAN,\n },\n};\n\nexport const NOBODY_CAN = [];\n\nexport type Anchor = 'authData' | 'preMutationRow';\n\nexport type Queries<TSchema extends Schema> = {\n [K in keyof TSchema['tables']]: Query<Schema, K & string>;\n};\n\nexport type PermissionRule<\n TAuthDataShape,\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n> = (\n authData: TAuthDataShape,\n eb: ExpressionBuilder<TSchema, TTable>,\n) => Condition;\n\nexport type AssetPermissions<\n TAuthDataShape,\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n> = {\n // Why an array of rules?: https://github.com/rocicorp/mono/pull/3184/files#r1869680716\n select?: PermissionRule<TAuthDataShape, TSchema, TTable>[] | undefined;\n /**\n * @deprecated Use Mutators instead.\n * @see {@link https://zero.rocicorp.dev/docs/writing-data}\n */\n insert?: PermissionRule<TAuthDataShape, TSchema, TTable>[] | undefined;\n /**\n * @deprecated Use Mutators instead.\n * @see {@link https://zero.rocicorp.dev/docs/writing-data}\n */\n update?:\n | {\n preMutation?: PermissionRule<TAuthDataShape, TSchema, TTable>[];\n postMutation?: PermissionRule<TAuthDataShape, TSchema, TTable>[];\n }\n | undefined;\n /**\n * @deprecated Use Mutators instead.\n * @see {@link https://zero.rocicorp.dev/docs/writing-data}\n */\n delete?: PermissionRule<TAuthDataShape, TSchema, TTable>[] | undefined;\n};\n\nexport type PermissionsConfig<TAuthDataShape, TSchema extends Schema> = {\n [K in keyof TSchema['tables']]?: {\n row?: AssetPermissions<TAuthDataShape, TSchema, K & string> | undefined;\n cell?:\n | {\n [C in keyof TSchema['tables'][K]['columns']]?: Omit<\n AssetPermissions<TAuthDataShape, TSchema, K & string>,\n 'cell'\n >;\n }\n | undefined;\n };\n};\n\nexport async function definePermissions<TAuthDataShape, TSchema extends Schema>(\n schema: TSchema,\n definer: () =>\n | Promise<PermissionsConfig<TAuthDataShape, TSchema>>\n | PermissionsConfig<TAuthDataShape, TSchema>,\n): Promise<CompiledPermissionsConfig | undefined> {\n const expressionBuilders = {} as Record<\n string,\n ExpressionBuilder<Schema, string>\n >;\n for (const name of Object.keys(schema.tables)) {\n expressionBuilders[name] = new StaticQuery(\n schema,\n name,\n {table: name},\n defaultFormat,\n ).expressionBuilder();\n }\n\n const config = await definer();\n return compilePermissions(schema, config, expressionBuilders);\n}\n\nfunction compilePermissions<TAuthDataShape, TSchema extends Schema>(\n schema: TSchema,\n authz: PermissionsConfig<TAuthDataShape, TSchema> | undefined,\n expressionBuilders: Record<string, ExpressionBuilder<Schema, string>>,\n): CompiledPermissionsConfig | undefined {\n if (!authz) {\n return undefined;\n }\n const nameMapper = clientToServer(schema.tables);\n const ret: CompiledPermissionsConfig = {tables: {}};\n for (const [tableName, tableConfig] of Object.entries(authz)) {\n const serverName = schema.tables[tableName].serverName ?? tableName;\n ret.tables[serverName] = {\n row: compileRowConfig(\n nameMapper,\n tableName,\n tableConfig.row,\n expressionBuilders[tableName],\n ),\n cell: compileCellConfig(\n nameMapper,\n tableName,\n tableConfig.cell,\n expressionBuilders[tableName],\n ),\n };\n }\n\n return ret;\n}\n\nfunction compileRowConfig<\n TAuthDataShape,\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n>(\n clientToServer: NameMapper,\n tableName: TTable,\n rowRules: AssetPermissions<TAuthDataShape, TSchema, TTable> | undefined,\n expressionBuilder: ExpressionBuilder<TSchema, TTable>,\n): CompiledAssetPermissions | undefined {\n if (!rowRules) {\n return undefined;\n }\n return {\n select: compileRules(\n clientToServer,\n tableName,\n rowRules.select,\n expressionBuilder,\n ),\n insert: compileRules(\n clientToServer,\n tableName,\n rowRules.insert,\n expressionBuilder,\n ),\n update: {\n preMutation: compileRules(\n clientToServer,\n tableName,\n rowRules.update?.preMutation,\n expressionBuilder,\n ),\n postMutation: compileRules(\n clientToServer,\n tableName,\n rowRules.update?.postMutation,\n expressionBuilder,\n ),\n },\n delete: compileRules(\n clientToServer,\n tableName,\n rowRules.delete,\n expressionBuilder,\n ),\n };\n}\n\n/**\n * What is this \"allow\" and why are permissions policies an array of rules?\n *\n * Please read: https://github.com/rocicorp/mono/pull/3184/files#r1869680716\n */\nfunction compileRules<\n TAuthDataShape,\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n>(\n clientToServer: NameMapper,\n tableName: TTable,\n rules: PermissionRule<TAuthDataShape, TSchema, TTable>[] | undefined,\n expressionBuilder: ExpressionBuilder<TSchema, TTable>,\n): ['allow', Condition][] | undefined {\n if (!rules) {\n return undefined;\n }\n\n return rules.map(rule => {\n const cond = rule(authDataRef as TAuthDataShape, expressionBuilder);\n return ['allow', mapCondition(cond, tableName, clientToServer)] as const;\n });\n}\n\nfunction compileCellConfig<\n TAuthDataShape,\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n>(\n clientToServer: NameMapper,\n tableName: TTable,\n cellRules:\n | Record<string, AssetPermissions<TAuthDataShape, TSchema, TTable>>\n | undefined,\n expressionBuilder: ExpressionBuilder<TSchema, TTable>,\n): Record<string, CompiledAssetPermissions> | undefined {\n if (!cellRules) {\n return undefined;\n }\n const ret: Record<string, CompiledAssetPermissions> = {};\n for (const [columnName, rules] of Object.entries(cellRules)) {\n ret[columnName] = {\n select: compileRules(\n clientToServer,\n tableName,\n rules.select,\n expressionBuilder,\n ),\n insert: compileRules(\n clientToServer,\n tableName,\n rules.insert,\n expressionBuilder,\n ),\n update: {\n preMutation: compileRules(\n clientToServer,\n tableName,\n rules.update?.preMutation,\n expressionBuilder,\n ),\n postMutation: compileRules(\n clientToServer,\n tableName,\n rules.update?.postMutation,\n expressionBuilder,\n ),\n },\n delete: compileRules(\n clientToServer,\n tableName,\n rules.delete,\n expressionBuilder,\n ),\n };\n }\n return ret;\n}\n\nclass CallTracker {\n readonly #anchor: Anchor;\n readonly #path: string[];\n constructor(anchor: Anchor, path: string[]) {\n this.#anchor = anchor;\n this.#path = path;\n }\n\n get(target: {[toStaticParam]: () => Parameter}, prop: string | symbol) {\n if (prop === toStaticParam) {\n return target[toStaticParam];\n }\n assert(typeof prop === 'string');\n const path = [...this.#path, prop];\n return new Proxy(\n {\n [toStaticParam]: () => staticParam(this.#anchor, path),\n },\n new CallTracker(this.#anchor, path),\n );\n }\n}\n\nfunction baseTracker(anchor: Anchor) {\n return new Proxy(\n {\n [toStaticParam]: () => {\n throw new Error('no JWT field specified');\n },\n },\n new CallTracker(anchor, []),\n );\n}\n\nexport const authDataRef = baseTracker('authData');\nexport const preMutationRowRef = baseTracker('preMutationRow');\nexport function staticParam(\n anchorClass: 'authData' | 'preMutationRow',\n field: string | string[],\n): Parameter {\n return {\n type: 'static',\n anchor: anchorClass,\n // for backwards compatibility\n field: field.length === 1 ? field[0] : field,\n };\n}\n", "export function escapeLike(val: string) {\n return val.replace(/[%_]/g, '\\\\$&');\n}\n", "/* oxlint-disable @typescript-eslint/no-explicit-any */\nimport type {ReadonlyJSONValue} from '../../../shared/src/json.ts';\nimport type {Schema} from '../../../zero-types/src/schema.ts';\nimport type {SchemaQuery} from '../mutate/custom.ts';\nimport {newQuery} from './query-impl.ts';\nimport type {Query} from './query.ts';\n\nexport type QueryFn<\n TContext,\n TTakesContext extends boolean,\n TArg extends ReadonlyJSONValue[],\n TReturnQuery extends Query<any, any, any>,\n> = TTakesContext extends false\n ? {(...args: TArg): TReturnQuery}\n : {(context: TContext, ...args: TArg): TReturnQuery};\n\nexport type SyncedQuery<\n TName extends string,\n TContext,\n TTakesContext extends boolean,\n TArg extends ReadonlyJSONValue[],\n TReturnQuery extends Query<any, any, any>,\n> = QueryFn<TContext, TTakesContext, TArg, TReturnQuery> & {\n queryName: TName;\n parse: ParseFn<TArg> | undefined;\n takesContext: TTakesContext;\n};\n\nfunction normalizeParser<T extends ReadonlyJSONValue[]>(\n parser: ParseFn<T> | HasParseFn<T> | undefined,\n): ParseFn<T> | undefined {\n if (parser) {\n if ('parse' in parser) {\n return parser.parse.bind(parser);\n }\n return parser;\n }\n return undefined;\n}\n\nexport function syncedQuery<\n TName extends string,\n TArg extends ReadonlyJSONValue[],\n TReturnQuery extends Query<any, any, any>,\n>(\n name: TName,\n parser: ParseFn<TArg> | HasParseFn<TArg> | undefined,\n fn: QueryFn<unknown, false, TArg, TReturnQuery>,\n): SyncedQuery<TName, unknown, false, TArg, TReturnQuery> {\n const impl = syncedQueryImpl(name, fn, false);\n const ret: any = (...args: TArg) => impl(undefined, args);\n ret.queryName = name;\n ret.parse = normalizeParser(parser);\n ret.takesContext = false;\n return ret;\n}\n\nexport function syncedQueryWithContext<\n TName extends string,\n TContext,\n TArg extends ReadonlyJSONValue[],\n TReturnQuery extends Query<any, any, any>,\n>(\n name: TName,\n parser: ParseFn<TArg> | HasParseFn<TArg> | undefined,\n fn: QueryFn<TContext, true, TArg, TReturnQuery>,\n): SyncedQuery<TName, TContext, true, TArg, TReturnQuery> {\n const impl = syncedQueryImpl(name, fn, true);\n const ret: any = (context: TContext, ...args: TArg) => impl(context, args);\n ret.queryName = name;\n ret.parse = normalizeParser(parser);\n ret.takesContext = true;\n return ret;\n}\n\nfunction syncedQueryImpl<\n TName extends string,\n TContext,\n TArg extends ReadonlyJSONValue[],\n TReturnQuery extends Query<any, any, any>,\n>(name: TName, fn: any, takesContext: boolean) {\n return (context: TContext, args: TArg) => {\n const q = takesContext ? fn(context, ...args) : fn(...args);\n return q.nameAndArgs(name, args) as TReturnQuery;\n };\n}\n\nexport function withValidation<T extends SyncedQuery<any, any, any, any, any>>(\n fn: T,\n): T extends SyncedQuery<infer N, infer C, any, any, infer R>\n ? SyncedQuery<N, C, true, ReadonlyJSONValue[], R>\n : never {\n if (!fn.parse) {\n throw new Error('ret does not have a parse function defined');\n }\n const ret: any = (context: unknown, ...args: unknown[]) => {\n const f = fn as any;\n const parsed = f.parse(args);\n return f.takesContext ? f(context, ...parsed) : f(...parsed);\n };\n ret.queryName = fn.queryName;\n ret.parse = fn.parse;\n ret.takesContext = true;\n\n return ret;\n}\n\nexport type ParseFn<T extends ReadonlyJSONValue[]> = (args: unknown[]) => T;\n\nexport type HasParseFn<T extends ReadonlyJSONValue[]> = {\n parse: ParseFn<T>;\n};\n\nexport type Parser<T extends ReadonlyJSONValue[]> = ParseFn<T> | HasParseFn<T>;\n\nexport type CustomQueryID = {\n name: string;\n args: ReadonlyArray<ReadonlyJSONValue>;\n};\n\n/**\n * Returns a set of query builders for the given schema.\n */\nexport function createBuilder<S extends Schema>(s: S): SchemaQuery<S> {\n return makeQueryBuilders(s) as SchemaQuery<S>;\n}\n\n/**\n * This produces the query builders for a given schema.\n * For use in Zero on the server to process custom queries.\n */\nfunction makeQueryBuilders<S extends Schema>(schema: S): SchemaQuery<S> {\n return new Proxy(\n {},\n {\n get: (\n target: Record<\n string,\n Omit<Query<S, string, any>, 'materialize' | 'preload'>\n >,\n prop: string,\n ) => {\n if (prop in target) {\n return target[prop];\n }\n\n if (!(prop in schema.tables)) {\n throw new Error(`Table ${prop} does not exist in schema`);\n }\n\n const q = newQuery(undefined, schema, prop);\n target[prop] = q;\n return q;\n },\n },\n ) as SchemaQuery<S>;\n}\n"],
5
- "mappings": "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",
3
+ "sources": ["../../zero-schema/src/builder/relationship-builder.ts", "../../zql/src/query/static-query.ts", "../../zero-schema/src/permissions.ts", "../../zql/src/query/escape-like.ts", "../../zql/src/query/error.ts", "../../zql/src/query/named.ts"],
4
+ "sourcesContent": ["/* oxlint-disable @typescript-eslint/no-explicit-any */\nimport type {Relationship, TableSchema} from '../table-schema.ts';\nimport type {TableBuilderWithColumns} from './table-builder.ts';\n\ntype ConnectArg<TSourceField, TDestField, TDest extends TableSchema> = {\n readonly sourceField: TSourceField;\n readonly destField: TDestField;\n readonly destSchema: TableBuilderWithColumns<TDest>;\n};\n\ntype ManyConnection<TSourceField, TDestField, TDest extends TableSchema> = {\n readonly sourceField: TSourceField;\n readonly destField: TDestField;\n readonly destSchema: TDest['name'];\n readonly cardinality: 'many';\n};\n\ntype OneConnection<TSourceField, TDestField, TDest extends TableSchema> = {\n readonly sourceField: TSourceField;\n readonly destField: TDestField;\n readonly destSchema: TDest['name'];\n readonly cardinality: 'one';\n};\n\ntype Prev = [-1, 0, 1, 2, 3, 4, 5, 6];\n\nexport type PreviousSchema<\n TSource extends TableSchema,\n K extends number,\n TDests extends TableSchema[],\n> = K extends 0 ? TSource : TDests[Prev[K]];\n\nexport type Relationships = {\n name: string; // table name\n relationships: Record<string, Relationship>; // relationships for that table\n};\n\n// Overloaded types for better inference\ntype ManyConnector<TSource extends TableSchema> = {\n // Single direct relationship\n <TDest extends TableSchema>(\n arg: ConnectArg<\n readonly (keyof TSource['columns'] & string)[],\n readonly (keyof TDest['columns'] & string)[],\n TDest\n >,\n ): [\n ManyConnection<\n readonly (keyof TSource['columns'] & string)[],\n readonly (keyof TDest['columns'] & string)[],\n TDest\n >,\n ];\n\n // Junction relationship (two hops)\n <TJunction extends TableSchema, TDest extends TableSchema>(\n firstHop: ConnectArg<\n readonly (keyof TSource['columns'] & string)[],\n readonly (keyof TJunction['columns'] & string)[],\n TJunction\n >,\n secondHop: ConnectArg<\n readonly (keyof TJunction['columns'] & string)[],\n readonly (keyof TDest['columns'] & string)[],\n TDest\n >,\n ): [\n ManyConnection<\n readonly (keyof TSource['columns'] & string)[],\n readonly (keyof TJunction['columns'] & string)[],\n TJunction\n >,\n ManyConnection<\n readonly (keyof TJunction['columns'] & string)[],\n readonly (keyof TDest['columns'] & string)[],\n TDest\n >,\n ];\n};\n\ntype OneConnector<TSource extends TableSchema> = {\n // Single direct relationship\n <TDest extends TableSchema>(\n arg: ConnectArg<\n readonly (keyof TSource['columns'] & string)[],\n readonly (keyof TDest['columns'] & string)[],\n TDest\n >,\n ): [\n OneConnection<\n readonly (keyof TSource['columns'] & string)[],\n readonly (keyof TDest['columns'] & string)[],\n TDest\n >,\n ];\n\n // Two-hop relationship (e.g., invoice_line -> invoice -> customer)\n <TIntermediate extends TableSchema, TDest extends TableSchema>(\n firstHop: ConnectArg<\n readonly (keyof TSource['columns'] & string)[],\n readonly (keyof TIntermediate['columns'] & string)[],\n TIntermediate\n >,\n secondHop: ConnectArg<\n readonly (keyof TIntermediate['columns'] & string)[],\n readonly (keyof TDest['columns'] & string)[],\n TDest\n >,\n ): [\n OneConnection<\n readonly (keyof TSource['columns'] & string)[],\n readonly (keyof TIntermediate['columns'] & string)[],\n TIntermediate\n >,\n OneConnection<\n readonly (keyof TIntermediate['columns'] & string)[],\n readonly (keyof TDest['columns'] & string)[],\n TDest\n >,\n ];\n};\n\nexport function relationships<\n TSource extends TableSchema,\n TRelationships extends Record<string, Relationship>,\n>(\n table: TableBuilderWithColumns<TSource>,\n cb: (connects: {\n many: ManyConnector<TSource>;\n one: OneConnector<TSource>;\n }) => TRelationships,\n): {name: TSource['name']; relationships: TRelationships} {\n const relationships = cb({many, one} as any);\n\n return {\n name: table.schema.name,\n relationships,\n };\n}\n\nfunction many(\n ...args: readonly ConnectArg<any, any, TableSchema>[]\n): ManyConnection<any, any, any>[] {\n return args.map(arg => ({\n sourceField: arg.sourceField,\n destField: arg.destField,\n destSchema: arg.destSchema.schema.name,\n cardinality: 'many',\n }));\n}\n\nfunction one(\n ...args: readonly ConnectArg<any, any, TableSchema>[]\n): OneConnection<any, any, any>[] {\n return args.map(arg => ({\n sourceField: arg.sourceField,\n destField: arg.destField,\n destSchema: arg.destSchema.schema.name,\n cardinality: 'one',\n }));\n}\n", "import type {AST, System} from '../../../zero-protocol/src/ast.ts';\nimport type {Schema} from '../../../zero-types/src/schema.ts';\nimport {defaultFormat} from '../ivm/default-format.ts';\nimport type {Format} from '../ivm/view.ts';\nimport {ExpressionBuilder} from './expression.ts';\nimport type {CustomQueryID} from './named.ts';\nimport type {QueryDelegate} from './query-delegate.ts';\nimport {AbstractQuery, newQuerySymbol} from './query-impl.ts';\nimport type {HumanReadable, PullRow, Query} from './query.ts';\nimport type {TypedView} from './typed-view.ts';\n\nexport function staticQuery<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n>(schema: TSchema, tableName: TTable): Query<TSchema, TTable> {\n return new StaticQuery<TSchema, TTable>(\n schema,\n tableName,\n {table: tableName},\n defaultFormat,\n );\n}\n\n/**\n * A query that cannot be run.\n * Only serves to generate ASTs.\n */\nexport class StaticQuery<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n TReturn = PullRow<TTable, TSchema>,\n> extends AbstractQuery<TSchema, TTable, TReturn> {\n constructor(\n schema: TSchema,\n tableName: TTable,\n ast: AST,\n format: Format,\n system: System = 'permissions',\n customQueryID?: CustomQueryID,\n currentJunction?: string,\n ) {\n super(\n undefined,\n schema,\n tableName,\n ast,\n format,\n system,\n customQueryID,\n currentJunction,\n );\n }\n\n expressionBuilder() {\n return new ExpressionBuilder(this._exists);\n }\n\n protected [newQuerySymbol]<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n TReturn,\n >(\n _delegate: QueryDelegate | undefined,\n schema: TSchema,\n tableName: TTable,\n ast: AST,\n format: Format,\n customQueryID: CustomQueryID | undefined,\n currentJunction: string | undefined,\n ): StaticQuery<TSchema, TTable, TReturn> {\n return new StaticQuery(\n schema,\n tableName,\n ast,\n format,\n 'permissions',\n customQueryID,\n currentJunction,\n );\n }\n\n get ast() {\n return this._completeAst();\n }\n\n materialize(): TypedView<HumanReadable<TReturn>> {\n throw new Error('StaticQuery cannot be materialized');\n }\n\n run(): Promise<HumanReadable<TReturn>> {\n return Promise.reject(new Error('StaticQuery cannot be run'));\n }\n\n preload(): {\n cleanup: () => void;\n complete: Promise<void>;\n } {\n throw new Error('StaticQuery cannot be preloaded');\n }\n}\n", "import {assert} from '../../shared/src/asserts.ts';\nimport {\n mapCondition,\n toStaticParam,\n type Condition,\n type Parameter,\n} from '../../zero-protocol/src/ast.ts';\nimport {defaultFormat} from '../../zero-types/src/format.ts';\nimport type {ExpressionBuilder} from '../../zql/src/query/expression.ts';\nimport type {Query} from '../../zql/src/query/query.ts';\nimport {StaticQuery} from '../../zql/src/query/static-query.ts';\nimport type {Schema} from './builder/schema-builder.ts';\nimport type {\n AssetPermissions as CompiledAssetPermissions,\n PermissionsConfig as CompiledPermissionsConfig,\n} from './compiled-permissions.ts';\nimport {clientToServer, NameMapper} from './name-mapper.ts';\n\nexport const ANYONE_CAN = [\n (_: unknown, eb: ExpressionBuilder<Schema, never>) => eb.and(),\n];\n\n/**\n * @deprecated Use {@link ANYONE_CAN} instead.\n */\nexport const ANYONE_CAN_DO_ANYTHING = {\n row: {\n select: ANYONE_CAN,\n insert: ANYONE_CAN,\n update: {\n preMutation: ANYONE_CAN,\n postMutation: ANYONE_CAN,\n },\n delete: ANYONE_CAN,\n },\n};\n\nexport const NOBODY_CAN = [];\n\nexport type Anchor = 'authData' | 'preMutationRow';\n\nexport type Queries<TSchema extends Schema> = {\n [K in keyof TSchema['tables']]: Query<Schema, K & string>;\n};\n\nexport type PermissionRule<\n TAuthDataShape,\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n> = (\n authData: TAuthDataShape,\n eb: ExpressionBuilder<TSchema, TTable>,\n) => Condition;\n\nexport type AssetPermissions<\n TAuthDataShape,\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n> = {\n // Why an array of rules?: https://github.com/rocicorp/mono/pull/3184/files#r1869680716\n select?: PermissionRule<TAuthDataShape, TSchema, TTable>[] | undefined;\n /**\n * @deprecated Use Mutators instead.\n * @see {@link https://zero.rocicorp.dev/docs/writing-data}\n */\n insert?: PermissionRule<TAuthDataShape, TSchema, TTable>[] | undefined;\n /**\n * @deprecated Use Mutators instead.\n * @see {@link https://zero.rocicorp.dev/docs/writing-data}\n */\n update?:\n | {\n preMutation?: PermissionRule<TAuthDataShape, TSchema, TTable>[];\n postMutation?: PermissionRule<TAuthDataShape, TSchema, TTable>[];\n }\n | undefined;\n /**\n * @deprecated Use Mutators instead.\n * @see {@link https://zero.rocicorp.dev/docs/writing-data}\n */\n delete?: PermissionRule<TAuthDataShape, TSchema, TTable>[] | undefined;\n};\n\nexport type PermissionsConfig<TAuthDataShape, TSchema extends Schema> = {\n [K in keyof TSchema['tables']]?: {\n row?: AssetPermissions<TAuthDataShape, TSchema, K & string> | undefined;\n cell?:\n | {\n [C in keyof TSchema['tables'][K]['columns']]?: Omit<\n AssetPermissions<TAuthDataShape, TSchema, K & string>,\n 'cell'\n >;\n }\n | undefined;\n };\n};\n\nexport async function definePermissions<TAuthDataShape, TSchema extends Schema>(\n schema: TSchema,\n definer: () =>\n | Promise<PermissionsConfig<TAuthDataShape, TSchema>>\n | PermissionsConfig<TAuthDataShape, TSchema>,\n): Promise<CompiledPermissionsConfig | undefined> {\n const expressionBuilders = {} as Record<\n string,\n ExpressionBuilder<Schema, string>\n >;\n for (const name of Object.keys(schema.tables)) {\n expressionBuilders[name] = new StaticQuery(\n schema,\n name,\n {table: name},\n defaultFormat,\n ).expressionBuilder();\n }\n\n const config = await definer();\n return compilePermissions(schema, config, expressionBuilders);\n}\n\nfunction compilePermissions<TAuthDataShape, TSchema extends Schema>(\n schema: TSchema,\n authz: PermissionsConfig<TAuthDataShape, TSchema> | undefined,\n expressionBuilders: Record<string, ExpressionBuilder<Schema, string>>,\n): CompiledPermissionsConfig | undefined {\n if (!authz) {\n return undefined;\n }\n const nameMapper = clientToServer(schema.tables);\n const ret: CompiledPermissionsConfig = {tables: {}};\n for (const [tableName, tableConfig] of Object.entries(authz)) {\n const serverName = schema.tables[tableName].serverName ?? tableName;\n ret.tables[serverName] = {\n row: compileRowConfig(\n nameMapper,\n tableName,\n tableConfig.row,\n expressionBuilders[tableName],\n ),\n cell: compileCellConfig(\n nameMapper,\n tableName,\n tableConfig.cell,\n expressionBuilders[tableName],\n ),\n };\n }\n\n return ret;\n}\n\nfunction compileRowConfig<\n TAuthDataShape,\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n>(\n clientToServer: NameMapper,\n tableName: TTable,\n rowRules: AssetPermissions<TAuthDataShape, TSchema, TTable> | undefined,\n expressionBuilder: ExpressionBuilder<TSchema, TTable>,\n): CompiledAssetPermissions | undefined {\n if (!rowRules) {\n return undefined;\n }\n return {\n select: compileRules(\n clientToServer,\n tableName,\n rowRules.select,\n expressionBuilder,\n ),\n insert: compileRules(\n clientToServer,\n tableName,\n rowRules.insert,\n expressionBuilder,\n ),\n update: {\n preMutation: compileRules(\n clientToServer,\n tableName,\n rowRules.update?.preMutation,\n expressionBuilder,\n ),\n postMutation: compileRules(\n clientToServer,\n tableName,\n rowRules.update?.postMutation,\n expressionBuilder,\n ),\n },\n delete: compileRules(\n clientToServer,\n tableName,\n rowRules.delete,\n expressionBuilder,\n ),\n };\n}\n\n/**\n * What is this \"allow\" and why are permissions policies an array of rules?\n *\n * Please read: https://github.com/rocicorp/mono/pull/3184/files#r1869680716\n */\nfunction compileRules<\n TAuthDataShape,\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n>(\n clientToServer: NameMapper,\n tableName: TTable,\n rules: PermissionRule<TAuthDataShape, TSchema, TTable>[] | undefined,\n expressionBuilder: ExpressionBuilder<TSchema, TTable>,\n): ['allow', Condition][] | undefined {\n if (!rules) {\n return undefined;\n }\n\n return rules.map(rule => {\n const cond = rule(authDataRef as TAuthDataShape, expressionBuilder);\n return ['allow', mapCondition(cond, tableName, clientToServer)] as const;\n });\n}\n\nfunction compileCellConfig<\n TAuthDataShape,\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n>(\n clientToServer: NameMapper,\n tableName: TTable,\n cellRules:\n | Record<string, AssetPermissions<TAuthDataShape, TSchema, TTable>>\n | undefined,\n expressionBuilder: ExpressionBuilder<TSchema, TTable>,\n): Record<string, CompiledAssetPermissions> | undefined {\n if (!cellRules) {\n return undefined;\n }\n const ret: Record<string, CompiledAssetPermissions> = {};\n for (const [columnName, rules] of Object.entries(cellRules)) {\n ret[columnName] = {\n select: compileRules(\n clientToServer,\n tableName,\n rules.select,\n expressionBuilder,\n ),\n insert: compileRules(\n clientToServer,\n tableName,\n rules.insert,\n expressionBuilder,\n ),\n update: {\n preMutation: compileRules(\n clientToServer,\n tableName,\n rules.update?.preMutation,\n expressionBuilder,\n ),\n postMutation: compileRules(\n clientToServer,\n tableName,\n rules.update?.postMutation,\n expressionBuilder,\n ),\n },\n delete: compileRules(\n clientToServer,\n tableName,\n rules.delete,\n expressionBuilder,\n ),\n };\n }\n return ret;\n}\n\nclass CallTracker {\n readonly #anchor: Anchor;\n readonly #path: string[];\n constructor(anchor: Anchor, path: string[]) {\n this.#anchor = anchor;\n this.#path = path;\n }\n\n get(target: {[toStaticParam]: () => Parameter}, prop: string | symbol) {\n if (prop === toStaticParam) {\n return target[toStaticParam];\n }\n assert(typeof prop === 'string');\n const path = [...this.#path, prop];\n return new Proxy(\n {\n [toStaticParam]: () => staticParam(this.#anchor, path),\n },\n new CallTracker(this.#anchor, path),\n );\n }\n}\n\nfunction baseTracker(anchor: Anchor) {\n return new Proxy(\n {\n [toStaticParam]: () => {\n throw new Error('no JWT field specified');\n },\n },\n new CallTracker(anchor, []),\n );\n}\n\nexport const authDataRef = baseTracker('authData');\nexport const preMutationRowRef = baseTracker('preMutationRow');\nexport function staticParam(\n anchorClass: 'authData' | 'preMutationRow',\n field: string | string[],\n): Parameter {\n return {\n type: 'static',\n anchor: anchorClass,\n // for backwards compatibility\n field: field.length === 1 ? field[0] : field,\n };\n}\n", "export function escapeLike(val: string) {\n return val.replace(/[%_]/g, '\\\\$&');\n}\n", "export class QueryParseError extends Error {\n constructor(opts: ErrorOptions) {\n super(\n opts?.cause instanceof Error\n ? `Failed to parse arguments for query: ${opts.cause.message}`\n : `Failed to parse arguments for query`,\n opts,\n );\n this.name = 'QueryParseError';\n }\n}\n", "/* oxlint-disable @typescript-eslint/no-explicit-any */\nimport type {ReadonlyJSONValue} from '../../../shared/src/json.ts';\nimport type {Schema} from '../../../zero-types/src/schema.ts';\nimport type {SchemaQuery} from '../mutate/custom.ts';\nimport {QueryParseError} from './error.ts';\nimport {newQuery} from './query-impl.ts';\nimport type {Query} from './query.ts';\n\nexport type QueryFn<\n TContext,\n TTakesContext extends boolean,\n TArg extends ReadonlyJSONValue[],\n TReturnQuery extends Query<any, any, any>,\n> = TTakesContext extends false\n ? {(...args: TArg): TReturnQuery}\n : {(context: TContext, ...args: TArg): TReturnQuery};\n\nexport type SyncedQuery<\n TName extends string,\n TContext,\n TTakesContext extends boolean,\n TArg extends ReadonlyJSONValue[],\n TReturnQuery extends Query<any, any, any>,\n> = QueryFn<TContext, TTakesContext, TArg, TReturnQuery> & {\n queryName: TName;\n parse: ParseFn<TArg> | undefined;\n takesContext: TTakesContext;\n};\n\nfunction normalizeParser<T extends ReadonlyJSONValue[]>(\n parser: ParseFn<T> | HasParseFn<T> | undefined,\n): ParseFn<T> | undefined {\n if (parser) {\n if ('parse' in parser) {\n return parser.parse.bind(parser);\n }\n return parser;\n }\n return undefined;\n}\n\nexport function syncedQuery<\n TName extends string,\n TArg extends ReadonlyJSONValue[],\n TReturnQuery extends Query<any, any, any>,\n>(\n name: TName,\n parser: ParseFn<TArg> | HasParseFn<TArg> | undefined,\n fn: QueryFn<unknown, false, TArg, TReturnQuery>,\n): SyncedQuery<TName, unknown, false, TArg, TReturnQuery> {\n const impl = syncedQueryImpl(name, fn, false);\n const ret: any = (...args: TArg) => impl(undefined, args);\n ret.queryName = name;\n ret.parse = normalizeParser(parser);\n ret.takesContext = false;\n return ret;\n}\n\nexport function syncedQueryWithContext<\n TName extends string,\n TContext,\n TArg extends ReadonlyJSONValue[],\n TReturnQuery extends Query<any, any, any>,\n>(\n name: TName,\n parser: ParseFn<TArg> | HasParseFn<TArg> | undefined,\n fn: QueryFn<TContext, true, TArg, TReturnQuery>,\n): SyncedQuery<TName, TContext, true, TArg, TReturnQuery> {\n const impl = syncedQueryImpl(name, fn, true);\n const ret: any = (context: TContext, ...args: TArg) => impl(context, args);\n ret.queryName = name;\n ret.parse = normalizeParser(parser);\n ret.takesContext = true;\n return ret;\n}\n\nfunction syncedQueryImpl<\n TName extends string,\n TContext,\n TArg extends ReadonlyJSONValue[],\n TReturnQuery extends Query<any, any, any>,\n>(name: TName, fn: any, takesContext: boolean) {\n return (context: TContext, args: TArg) => {\n const q = takesContext ? fn(context, ...args) : fn(...args);\n return q.nameAndArgs(name, args) as TReturnQuery;\n };\n}\n\nexport function withValidation<T extends SyncedQuery<any, any, any, any, any>>(\n fn: T,\n): T extends SyncedQuery<infer N, infer C, any, any, infer R>\n ? SyncedQuery<N, C, true, ReadonlyJSONValue[], R>\n : never {\n if (!fn.parse) {\n throw new Error('ret does not have a parse function defined');\n }\n const ret: any = (context: unknown, ...args: unknown[]) => {\n const f = fn as any;\n\n // oxlint-disable-next-line no-explicit-any\n let parsed: any;\n try {\n parsed = f.parse(args);\n } catch (error) {\n throw new QueryParseError({cause: error});\n }\n\n return f.takesContext ? f(context, ...parsed) : f(...parsed);\n };\n ret.queryName = fn.queryName;\n ret.parse = fn.parse;\n ret.takesContext = true;\n\n return ret;\n}\n\nexport type ParseFn<T extends ReadonlyJSONValue[]> = (args: unknown[]) => T;\n\nexport type HasParseFn<T extends ReadonlyJSONValue[]> = {\n parse: ParseFn<T>;\n};\n\nexport type Parser<T extends ReadonlyJSONValue[]> = ParseFn<T> | HasParseFn<T>;\n\nexport type CustomQueryID = {\n name: string;\n args: ReadonlyArray<ReadonlyJSONValue>;\n};\n\n/**\n * Returns a set of query builders for the given schema.\n */\nexport function createBuilder<S extends Schema>(s: S): SchemaQuery<S> {\n return makeQueryBuilders(s) as SchemaQuery<S>;\n}\n\n/**\n * This produces the query builders for a given schema.\n * For use in Zero on the server to process custom queries.\n */\nfunction makeQueryBuilders<S extends Schema>(schema: S): SchemaQuery<S> {\n return new Proxy(\n {},\n {\n get: (\n target: Record<\n string,\n Omit<Query<S, string, any>, 'materialize' | 'preload'>\n >,\n prop: string,\n ) => {\n if (prop in target) {\n return target[prop];\n }\n\n if (!(prop in schema.tables)) {\n throw new Error(`Table ${prop} does not exist in schema`);\n }\n\n const q = newQuery(undefined, schema, prop);\n target[prop] = q;\n return q;\n },\n },\n ) as SchemaQuery<S>;\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["table", "relationships", "clientToServer"]
7
7
  }
package/out/react.js CHANGED
@@ -2,8 +2,9 @@ import {
2
2
  MarkIcon
3
3
  } from "./chunk-VZOYWIRW.js";
4
4
  import {
5
- Zero
6
- } from "./chunk-AIPM77UE.js";
5
+ Zero,
6
+ connection_status_enum_exports
7
+ } from "./chunk-COKJ5W7V.js";
7
8
  import "./chunk-ASRS2LFV.js";
8
9
  import {
9
10
  DEFAULT_TTL_MS
@@ -105,6 +106,8 @@ import {
105
106
  createContext,
106
107
  useContext,
107
108
  useEffect,
109
+ useMemo,
110
+ useRef,
108
111
  useState as useState2
109
112
  } from "react";
110
113
  import { jsx as jsx2 } from "react/jsx-runtime";
@@ -119,12 +122,20 @@ function useZero() {
119
122
  function createUseZero() {
120
123
  return () => useZero();
121
124
  }
125
+ var NO_AUTH_SET = Symbol("NO_AUTH_SET");
122
126
  function ZeroProvider({ children, init, ...props }) {
127
+ const isExternalZero = "zero" in props;
123
128
  const [zero, setZero] = useState2(
124
- "zero" in props ? props.zero : void 0
129
+ isExternalZero ? props.zero : void 0
130
+ );
131
+ const auth = "auth" in props ? props.auth : NO_AUTH_SET;
132
+ const prevAuthRef = useRef(auth);
133
+ const keysWithoutAuth = useMemo(
134
+ () => Object.entries(props).filter(([key]) => key !== "auth").sort(([a], [b]) => a.localeCompare(b)).map(([_, value]) => value),
135
+ [props]
125
136
  );
126
137
  useEffect(() => {
127
- if ("zero" in props) {
138
+ if (isExternalZero) {
128
139
  setZero(props.zero);
129
140
  return;
130
141
  }
@@ -135,7 +146,17 @@ function ZeroProvider({ children, init, ...props }) {
135
146
  void z.close();
136
147
  setZero(void 0);
137
148
  };
138
- }, [init, ...Object.values(props)]);
149
+ }, [init, ...keysWithoutAuth]);
150
+ useEffect(() => {
151
+ if (!zero) return;
152
+ const authChanged = auth !== prevAuthRef.current;
153
+ if (authChanged) {
154
+ prevAuthRef.current = auth;
155
+ void zero.connection.connect({
156
+ auth: auth === NO_AUTH_SET ? void 0 : auth
157
+ });
158
+ }
159
+ }, [auth, zero]);
139
160
  return zero && /* @__PURE__ */ jsx2(ZeroContext.Provider, { value: zero, children });
140
161
  }
141
162
 
@@ -213,14 +234,14 @@ var emptySnapshotErrorUnknown = [emptyArray, resultTypeError];
213
234
  function getDefaultSnapshot(singular) {
214
235
  return singular ? emptySnapshotSingularUnknown : emptySnapshotPluralUnknown;
215
236
  }
216
- function getSnapshot(singular, data, resultType, refetchFn, error) {
237
+ function getSnapshot(singular, data, resultType, retryFn, error) {
217
238
  if (singular && data === void 0) {
218
239
  switch (resultType) {
219
240
  case "error":
220
241
  if (error) {
221
242
  return [
222
243
  void 0,
223
- makeError(refetchFn, error)
244
+ makeError(retryFn, error)
224
245
  ];
225
246
  }
226
247
  return emptySnapshotSingularErrorUnknown;
@@ -236,7 +257,7 @@ function getSnapshot(singular, data, resultType, refetchFn, error) {
236
257
  if (error) {
237
258
  return [
238
259
  emptyArray,
239
- makeError(refetchFn, error)
260
+ makeError(retryFn, error)
240
261
  ];
241
262
  }
242
263
  return emptySnapshotErrorUnknown;
@@ -249,15 +270,15 @@ function getSnapshot(singular, data, resultType, refetchFn, error) {
249
270
  switch (resultType) {
250
271
  case "error":
251
272
  if (error) {
252
- return [data, makeError(refetchFn, error)];
273
+ return [data, makeError(retryFn, error)];
253
274
  }
254
275
  return [
255
276
  data,
256
- makeError(refetchFn, {
277
+ makeError(retryFn, {
257
278
  error: "app",
258
279
  id: "unknown",
259
280
  name: "unknown",
260
- details: "An unknown error occurred"
281
+ message: "An unknown error occurred"
261
282
  })
262
283
  ];
263
284
  case "complete":
@@ -266,19 +287,16 @@ function getSnapshot(singular, data, resultType, refetchFn, error) {
266
287
  return [data, resultTypeUnknown];
267
288
  }
268
289
  }
269
- function makeError(refetch, error) {
290
+ function makeError(retry, error) {
291
+ const message = error.message ?? "An unknown error occurred";
270
292
  return {
271
293
  type: "error",
272
- refetch,
273
- error: error.error === "app" || error.error === "zero" ? {
274
- type: "app",
275
- queryName: error.name,
276
- details: error.details
277
- } : {
278
- type: "http",
279
- queryName: error.name,
280
- status: error.status,
281
- details: error.details
294
+ retry,
295
+ refetch: retry,
296
+ error: {
297
+ type: error.error,
298
+ message,
299
+ ...error.details ? { details: error.details } : {}
282
300
  }
283
301
  };
284
302
  }
@@ -350,7 +368,7 @@ var ViewWrapper = class {
350
368
  this.#format.singular,
351
369
  data,
352
370
  resultType,
353
- this.#refetch,
371
+ this.#retry,
354
372
  error
355
373
  );
356
374
  if (resultType === "complete" || resultType === "error") {
@@ -368,10 +386,10 @@ var ViewWrapper = class {
368
386
  }
369
387
  };
370
388
  /**
371
- * Called by the user to force a refetch of the query
389
+ * Called by the user to force a retry of the query
372
390
  * in the case the query errored.
373
391
  */
374
- #refetch = () => {
392
+ #retry = () => {
375
393
  this.#view?.destroy();
376
394
  this.#view = void 0;
377
395
  this.#materializeIfNeeded();
@@ -448,6 +466,7 @@ function useZeroOnline() {
448
466
  );
449
467
  }
450
468
  export {
469
+ connection_status_enum_exports as ConnectionStatus,
451
470
  ZeroInspector,
452
471
  ZeroProvider,
453
472
  createUseZero,
package/out/react.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../zero-react/src/components/zero-inspector.tsx", "../../zero-react/src/use-query.tsx", "../../shared/src/deep-clone.ts", "../../zero-react/src/zero-provider.tsx", "../../zero-react/src/use-zero-connection-state.tsx", "../../zero-react/src/use-zero-online.tsx"],
4
- "sourcesContent": ["import {lazy, Suspense, useState} from 'react';\nimport type {CustomMutatorDefs} from '../../../zero-client/src/client/custom.ts';\nimport type {Zero} from '../../../zero-client/src/client/zero.ts';\nimport type {Schema} from '../../../zero-schema/src/builder/schema-builder.ts';\nimport {MarkIcon} from './mark-icon.tsx';\n\nconst Inspector = lazy(() => import('./inspector.tsx'));\n\nexport function ZeroInspector<\n S extends Schema,\n MD extends CustomMutatorDefs | undefined = undefined,\n>({zero}: {zero: Zero<S, MD>}): JSX.Element {\n const [show, setShow] = useState(false);\n return show ? (\n <Suspense fallback={<div>Loading Inspector...</div>}>\n <Inspector\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n zero={zero as any}\n onClose={() => setShow(false)}\n />\n </Suspense>\n ) : (\n <button\n onClick={() => setShow(!show)}\n style={{\n position: 'fixed',\n bottom: 0,\n right: 0,\n zIndex: 1000,\n padding: '5px',\n color: 'white',\n backgroundColor: '#333',\n borderTopLeftRadius: '8px',\n opacity: 0.95,\n }}\n >\n <MarkIcon\n style={{\n width: '20px',\n height: '20px',\n fill: 'currentColor',\n }}\n />\n </button>\n );\n}\n", "import {resolver} from '@rocicorp/resolver';\nimport React, {useSyncExternalStore} from 'react';\nimport {deepClone} from '../../shared/src/deep-clone.ts';\nimport type {Immutable} from '../../shared/src/immutable.ts';\nimport type {ReadonlyJSONValue} from '../../shared/src/json.ts';\nimport {Zero} from '../../zero-client/src/client/zero.ts';\nimport type {ErroredQuery} from '../../zero-protocol/src/custom-queries.ts';\nimport type {Schema} from '../../zero-schema/src/builder/schema-builder.ts';\nimport type {Format} from '../../zql/src/ivm/view.ts';\nimport {AbstractQuery} from '../../zql/src/query/query-impl.ts';\nimport {type HumanReadable, type Query} from '../../zql/src/query/query.ts';\nimport {DEFAULT_TTL_MS, type TTL} from '../../zql/src/query/ttl.ts';\nimport type {ResultType, TypedView} from '../../zql/src/query/typed-view.ts';\nimport {useZero} from './zero-provider.tsx';\n\nexport type QueryResultDetails = Readonly<\n | {\n type: 'complete';\n }\n | {\n type: 'unknown';\n }\n | QueryErrorDetails\n>;\n\ntype QueryErrorDetails = {\n type: 'error';\n refetch: () => void;\n error:\n | {\n type: 'app';\n queryName: string;\n details: ReadonlyJSONValue;\n }\n | {\n type: 'http';\n queryName: string;\n status: number;\n details: ReadonlyJSONValue;\n };\n};\n\nexport type QueryResult<TReturn> = readonly [\n HumanReadable<TReturn>,\n QueryResultDetails,\n];\n\nexport type UseQueryOptions = {\n enabled?: boolean | undefined;\n /**\n * Time to live (TTL) in seconds. Controls how long query results are cached\n * after the query is removed. During this time, Zero continues to sync the query.\n * Default is 'never'.\n */\n ttl?: TTL | undefined;\n};\n\nexport type UseSuspenseQueryOptions = UseQueryOptions & {\n /**\n * Whether to suspend until:\n * - 'partial': the query has partial results (partial array or defined\n * value for singular results) which may be of result type 'unknown',\n * or the query result type is 'complete' (in which case results may be\n * empty). This is useful for suspending until there are partial\n * optimistic local results, or the query has completed loading from the\n * server.\n * - 'complete': the query result type is 'complete'.\n *\n * Default is 'partial'.\n */\n suspendUntil?: 'complete' | 'partial';\n};\n\nconst reactUse = (React as {use?: (p: Promise<unknown>) => void}).use;\nconst suspend: (p: Promise<unknown>) => void = reactUse\n ? reactUse\n : p => {\n throw p;\n };\n\nexport function useQuery<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n TReturn,\n>(\n query: Query<TSchema, TTable, TReturn>,\n options?: UseQueryOptions | boolean,\n): QueryResult<TReturn> {\n let enabled = true;\n let ttl: TTL = DEFAULT_TTL_MS;\n if (typeof options === 'boolean') {\n enabled = options;\n } else if (options) {\n ({enabled = true, ttl = DEFAULT_TTL_MS} = options);\n }\n\n const view = viewStore.getView(\n useZero(),\n query as AbstractQuery<TSchema, TTable, TReturn>,\n enabled,\n ttl,\n );\n // https://react.dev/reference/react/useSyncExternalStore\n return useSyncExternalStore(\n view.subscribeReactInternals,\n view.getSnapshot,\n view.getSnapshot,\n );\n}\n\nexport function useSuspenseQuery<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n TReturn,\n>(\n query: Query<TSchema, TTable, TReturn>,\n options?: UseSuspenseQueryOptions | boolean,\n): QueryResult<TReturn> {\n let enabled = true;\n let ttl: TTL = DEFAULT_TTL_MS;\n let suspendUntil: 'complete' | 'partial' = 'partial';\n if (typeof options === 'boolean') {\n enabled = options;\n } else if (options) {\n ({\n enabled = true,\n ttl = DEFAULT_TTL_MS,\n suspendUntil = 'complete',\n } = options);\n }\n\n const view = viewStore.getView(\n useZero(),\n query as AbstractQuery<TSchema, TTable, TReturn>,\n enabled,\n ttl,\n );\n // https://react.dev/reference/react/useSyncExternalStore\n const snapshot = useSyncExternalStore(\n view.subscribeReactInternals,\n view.getSnapshot,\n view.getSnapshot,\n );\n\n if (enabled) {\n if (suspendUntil === 'complete' && !view.complete) {\n suspend(view.waitForComplete());\n }\n\n if (suspendUntil === 'partial' && !view.nonEmpty) {\n suspend(view.waitForNonEmpty());\n }\n }\n\n return snapshot;\n}\n\nconst emptyArray: unknown[] = [];\nconst disabledSubscriber = () => () => {};\n\nconst resultTypeUnknown = {type: 'unknown'} as const;\nconst resultTypeComplete = {type: 'complete'} as const;\nconst resultTypeError = {type: 'error'} as const;\n\nconst emptySnapshotSingularUnknown = [undefined, resultTypeUnknown] as const;\nconst emptySnapshotSingularComplete = [undefined, resultTypeComplete] as const;\nconst emptySnapshotSingularErrorUnknown = [undefined, resultTypeError] as const;\nconst emptySnapshotPluralUnknown = [emptyArray, resultTypeUnknown] as const;\nconst emptySnapshotPluralComplete = [emptyArray, resultTypeComplete] as const;\nconst emptySnapshotErrorUnknown = [emptyArray, resultTypeError] as const;\n\nfunction getDefaultSnapshot<TReturn>(singular: boolean): QueryResult<TReturn> {\n return (\n singular ? emptySnapshotSingularUnknown : emptySnapshotPluralUnknown\n ) as QueryResult<TReturn>;\n}\n\n/**\n * Returns a new snapshot or one of the empty predefined ones. Returning the\n * predefined ones is important to prevent unnecessary re-renders in React.\n */\nfunction getSnapshot<TReturn>(\n singular: boolean,\n data: HumanReadable<TReturn>,\n resultType: ResultType,\n refetchFn: () => void,\n error?: ErroredQuery,\n): QueryResult<TReturn> {\n if (singular && data === undefined) {\n switch (resultType) {\n case 'error':\n if (error) {\n return [\n undefined,\n makeError(refetchFn, error),\n ] as unknown as QueryResult<TReturn>;\n }\n return emptySnapshotSingularErrorUnknown as unknown as QueryResult<TReturn>;\n case 'complete':\n return emptySnapshotSingularComplete as unknown as QueryResult<TReturn>;\n case 'unknown':\n return emptySnapshotSingularUnknown as unknown as QueryResult<TReturn>;\n }\n }\n\n if (!singular && (data as unknown[]).length === 0) {\n switch (resultType) {\n case 'error':\n if (error) {\n return [\n emptyArray,\n makeError(refetchFn, error),\n ] as unknown as QueryResult<TReturn>;\n }\n return emptySnapshotErrorUnknown as unknown as QueryResult<TReturn>;\n case 'complete':\n return emptySnapshotPluralComplete as unknown as QueryResult<TReturn>;\n case 'unknown':\n return emptySnapshotPluralUnknown as unknown as QueryResult<TReturn>;\n }\n }\n\n switch (resultType) {\n case 'error':\n if (error) {\n return [data, makeError(refetchFn, error)];\n }\n return [\n data,\n makeError(refetchFn, {\n error: 'app',\n id: 'unknown',\n name: 'unknown',\n details: 'An unknown error occurred',\n }),\n ];\n case 'complete':\n return [data, resultTypeComplete];\n case 'unknown':\n return [data, resultTypeUnknown];\n }\n}\n\nfunction makeError(\n refetch: () => void,\n error: ErroredQuery,\n): QueryErrorDetails {\n return {\n type: 'error',\n refetch,\n error:\n error.error === 'app' || error.error === 'zero'\n ? {\n type: 'app',\n queryName: error.name,\n details: error.details,\n }\n : {\n type: 'http',\n queryName: error.name,\n status: error.status,\n details: error.details,\n },\n };\n}\n\ndeclare const TESTING: boolean;\n\n// oxlint-disable-next-line @typescript-eslint/no-explicit-any\ntype ViewWrapperAny = ViewWrapper<any, any, any>;\n\nconst allViews = new WeakMap<ViewStore, Map<string, ViewWrapperAny>>();\n\nexport function getAllViewsSizeForTesting(store: ViewStore): number {\n if (TESTING) {\n return allViews.get(store)?.size ?? 0;\n }\n return 0;\n}\n\n/**\n * A global store of all active views.\n *\n * React subscribes and unsubscribes to these views\n * via `useSyncExternalStore`.\n *\n * Managing views through `useEffect` or `useLayoutEffect` causes\n * inconsistencies because effects run after render.\n *\n * For example, if useQuery used use*Effect in the component below:\n * ```ts\n * function Foo({issueID}) {\n * const issue = useQuery(z.query.issue.where('id', issueID).one());\n * if (issue?.id !== undefined && issue.id !== issueID) {\n * console.log('MISMATCH!', issue.id, issueID);\n * }\n * }\n * ```\n *\n * `MISMATCH` will be printed whenever the `issueID` prop changes.\n *\n * This is because the component will render once with\n * the old state returned from `useQuery`. Then the effect inside\n * `useQuery` will run. The component will render again with the new\n * state. This inconsistent transition can cause unexpected results.\n *\n * Emulating `useEffect` via `useState` and `if` causes resource leaks.\n * That is:\n *\n * ```ts\n * function useQuery(q) {\n * const [oldHash, setOldHash] = useState();\n * if (hash(q) !== oldHash) {\n * // make new view\n * }\n *\n * useEffect(() => {\n * return () => view.destroy();\n * }, []);\n * }\n * ```\n *\n * I'm not sure why but in strict mode the cleanup function\n * fails to be called for the first instance of the view and only\n * cleans up later instances.\n *\n * Swapping `useState` to `useRef` has similar problems.\n */\nexport class ViewStore {\n #views = new Map<string, ViewWrapperAny>();\n\n constructor() {\n if (TESTING) {\n allViews.set(this, this.#views);\n }\n }\n\n getView<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n TReturn,\n >(\n zero: Zero<TSchema>,\n query: Query<TSchema, TTable, TReturn>,\n enabled: boolean,\n ttl: TTL,\n ): {\n getSnapshot: () => QueryResult<TReturn>;\n subscribeReactInternals: (internals: () => void) => () => void;\n updateTTL: (ttl: TTL) => void;\n waitForComplete: () => Promise<void>;\n waitForNonEmpty: () => Promise<void>;\n complete: boolean;\n nonEmpty: boolean;\n } {\n const {format} = query;\n if (!enabled) {\n return {\n getSnapshot: () => getDefaultSnapshot(format.singular),\n subscribeReactInternals: disabledSubscriber,\n updateTTL: () => {},\n waitForComplete: () => Promise.resolve(),\n waitForNonEmpty: () => Promise.resolve(),\n complete: false,\n nonEmpty: false,\n };\n }\n\n const hash = query.hash() + zero.clientID;\n let existing = this.#views.get(hash);\n if (!existing) {\n existing = new ViewWrapper(zero, query, format, ttl, view => {\n const currentView = this.#views.get(hash);\n if (currentView && currentView !== view) {\n // we replaced the view with a new one already.\n return;\n }\n this.#views.delete(hash);\n });\n this.#views.set(hash, existing);\n } else {\n existing.updateTTL(ttl);\n }\n return existing as ViewWrapper<TSchema, TTable, TReturn>;\n }\n}\n\nconst viewStore = new ViewStore();\n\n/**\n * This wraps and ref counts a view.\n *\n * The only signal we have from React as to whether or not it is\n * done with a view is when it calls `unsubscribe`.\n *\n * In non-strict-mode we can clean up the view as soon\n * as the listener count goes to 0.\n *\n * In strict-mode, the listener count will go to 0 then a\n * new listener for the same view is immediately added back.\n *\n * This is why the `onMaterialized` and `onDematerialized` callbacks exist --\n * they allow a view which React is still referencing to be added\n * back into the store when React re-subscribes to it.\n *\n * This wrapper also exists to deal with the various\n * `useSyncExternalStore` caveats that cause excessive\n * re-renders and materializations.\n *\n * See: https://react.dev/reference/react/useSyncExternalStore#caveats\n * Especially:\n * 1. The store snapshot returned by getSnapshot must be immutable. If the underlying store has mutable data, return a new immutable snapshot if the data has changed. Otherwise, return a cached last snapshot.\n * 2. If a different subscribe function is passed during a re-render, React will re-subscribe to the store using the newly passed subscribe function. You can prevent this by declaring subscribe outside the component.\n */\nclass ViewWrapper<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n TReturn,\n> {\n #zero: Zero<TSchema>;\n #view: TypedView<HumanReadable<TReturn>> | undefined;\n readonly #onDematerialized;\n readonly #query: Query<TSchema, TTable, TReturn>;\n readonly #format: Format;\n #snapshot: QueryResult<TReturn>;\n #reactInternals: Set<() => void>;\n #ttl: TTL;\n #complete = false;\n #completeResolver = resolver<void>();\n #nonEmpty = false;\n #nonEmptyResolver = resolver<void>();\n\n constructor(\n zero: Zero<TSchema>,\n query: Query<TSchema, TTable, TReturn>,\n format: Format,\n ttl: TTL,\n onDematerialized: (view: ViewWrapper<TSchema, TTable, TReturn>) => void,\n ) {\n this.#zero = zero;\n this.#query = query;\n this.#format = format;\n this.#ttl = ttl;\n this.#onDematerialized = onDematerialized;\n this.#snapshot = getDefaultSnapshot(format.singular);\n this.#reactInternals = new Set();\n this.#materializeIfNeeded();\n }\n\n #onData = (\n snap: Immutable<HumanReadable<TReturn>>,\n resultType: ResultType,\n error?: ErroredQuery,\n ) => {\n const data =\n snap === undefined\n ? snap\n : (deepClone(snap as ReadonlyJSONValue) as HumanReadable<TReturn>);\n this.#snapshot = getSnapshot(\n this.#format.singular,\n data,\n resultType,\n this.#refetch,\n error,\n );\n if (resultType === 'complete' || resultType === 'error') {\n this.#complete = true;\n this.#completeResolver.resolve();\n this.#nonEmpty = true;\n this.#nonEmptyResolver.resolve();\n }\n\n if (\n this.#format.singular\n ? this.#snapshot[0] !== undefined\n : (this.#snapshot[0] as unknown[]).length !== 0\n ) {\n this.#nonEmpty = true;\n this.#nonEmptyResolver.resolve();\n }\n\n for (const internals of this.#reactInternals) {\n internals();\n }\n };\n\n /**\n * Called by the user to force a refetch of the query\n * in the case the query errored.\n */\n #refetch = () => {\n this.#view?.destroy();\n this.#view = undefined;\n this.#materializeIfNeeded();\n };\n\n #materializeIfNeeded = () => {\n if (this.#view) {\n return;\n }\n\n this.#view = this.#zero.materialize(this.#query, {ttl: this.#ttl});\n this.#view.addListener(this.#onData);\n };\n\n getSnapshot = () => this.#snapshot;\n\n subscribeReactInternals = (internals: () => void): (() => void) => {\n this.#reactInternals.add(internals);\n this.#materializeIfNeeded();\n return () => {\n this.#reactInternals.delete(internals);\n\n // only schedule a cleanup task if we have no listeners left\n if (this.#reactInternals.size === 0) {\n setTimeout(() => {\n // We already destroyed the view\n if (this.#view === undefined) {\n return;\n }\n\n // Someone re-registered a listener on this view before the timeout elapsed.\n // This happens often in strict-mode which forces a component\n // to mount, unmount, remount.\n if (this.#reactInternals.size > 0) {\n return;\n }\n\n this.#view.destroy();\n this.#view = undefined;\n this.#complete = false;\n this.#completeResolver = resolver();\n this.#nonEmpty = false;\n this.#nonEmptyResolver = resolver();\n this.#onDematerialized(this);\n }, 10);\n }\n };\n };\n\n updateTTL(ttl: TTL): void {\n this.#ttl = ttl;\n this.#view?.updateTTL(ttl);\n }\n\n get complete() {\n return this.#complete;\n }\n\n waitForComplete(): Promise<void> {\n return this.#completeResolver.promise;\n }\n\n get nonEmpty() {\n return this.#nonEmpty;\n }\n\n waitForNonEmpty(): Promise<void> {\n return this.#nonEmptyResolver.promise;\n }\n}\n", "import {hasOwn} from './has-own.ts';\nimport type {JSONValue, ReadonlyJSONValue} from './json.ts';\n\nexport function deepClone(value: ReadonlyJSONValue): JSONValue {\n const seen: Array<ReadonlyJSONValue> = [];\n return internalDeepClone(value, seen);\n}\n\nexport function internalDeepClone(\n value: ReadonlyJSONValue,\n seen: Array<ReadonlyJSONValue>,\n): JSONValue {\n switch (typeof value) {\n case 'boolean':\n case 'number':\n case 'string':\n case 'undefined':\n return value;\n case 'object': {\n if (value === null) {\n return null;\n }\n if (seen.includes(value)) {\n throw new Error('Cyclic object');\n }\n seen.push(value);\n if (Array.isArray(value)) {\n const rv = value.map(v => internalDeepClone(v, seen));\n seen.pop();\n return rv;\n }\n\n const obj: JSONValue = {};\n\n for (const k in value) {\n if (hasOwn(value, k)) {\n const v = (value as Record<string, ReadonlyJSONValue>)[k];\n if (v !== undefined) {\n obj[k] = internalDeepClone(v, seen);\n }\n }\n }\n seen.pop();\n return obj;\n }\n\n default:\n throw new Error(`Invalid type: ${typeof value}`);\n }\n}\n", "import {\n createContext,\n useContext,\n useEffect,\n useState,\n type ReactNode,\n} from 'react';\nimport type {CustomMutatorDefs} from '../../zero-client/src/client/custom.ts';\nimport type {ZeroOptions} from '../../zero-client/src/client/options.ts';\nimport {Zero} from '../../zero-client/src/client/zero.ts';\nimport type {Schema} from '../../zero-schema/src/builder/schema-builder.ts';\n\nconst ZeroContext = createContext<unknown | undefined>(undefined);\n\nexport function useZero<\n S extends Schema,\n MD extends CustomMutatorDefs | undefined = undefined,\n>(): Zero<S, MD> {\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>;\n}\n\nexport function createUseZero<\n S extends Schema,\n MD extends CustomMutatorDefs | undefined = undefined,\n>() {\n return () => useZero<S, MD>();\n}\n\nexport type ZeroProviderProps<\n S extends Schema,\n MD extends CustomMutatorDefs | undefined = undefined,\n> = (ZeroOptions<S, MD> | {zero: Zero<S, MD>}) & {\n init?: (zero: Zero<S, MD>) => void;\n children: ReactNode;\n};\n\nexport function ZeroProvider<\n S extends Schema,\n MD extends CustomMutatorDefs | undefined = undefined,\n>({children, init, ...props}: ZeroProviderProps<S, MD>) {\n const [zero, setZero] = useState<Zero<S, MD> | undefined>(\n 'zero' in props ? props.zero : undefined,\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 ('zero' in props) {\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 }, [init, ...Object.values(props)]);\n\n return (\n zero && <ZeroContext.Provider value={zero}>{children}</ZeroContext.Provider>\n );\n}\n", "import {useSyncExternalStore} from 'react';\nimport type {ConnectionState} from '../../zero-client/src/client/connection-manager.ts';\nimport {useZero} from './zero-provider.tsx';\n\n/**\n * Hook to subscribe to the connection status of the Zero instance.\n *\n * @returns The connection status of the Zero instance.\n * @see {@link ConnectionState} for more details on the connection state.\n */\nexport function useZeroConnectionState(): ConnectionState {\n const zero = useZero();\n return useSyncExternalStore(\n zero.connection.state.subscribe,\n () => zero.connection.state.current,\n () => zero.connection.state.current,\n );\n}\n", "import {useSyncExternalStore} from 'react';\nimport {useZero} from './zero-provider.tsx';\n\n/**\n * Hook to subscribe to the online status of the Zero instance.\n *\n * This is useful when you want to update state based on the online status.\n *\n * @returns The online status of the Zero instance.\n *\n * @deprecated Use {@linkcode useZeroConnectionState} instead, which provides more detailed connection state.\n */\nexport function useZeroOnline(): boolean {\n const zero = useZero();\n return useSyncExternalStore(\n zero.onOnline,\n () => zero.online,\n () => zero.online,\n );\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {lazy, Suspense, useState} from 'react';\nimport type {CustomMutatorDefs} from '../../../zero-client/src/client/custom.ts';\nimport type {Zero} from '../../../zero-client/src/client/zero.ts';\nimport type {Schema} from '../../../zero-schema/src/builder/schema-builder.ts';\nimport {MarkIcon} from './mark-icon.tsx';\n\nconst Inspector = lazy(() => import('./inspector.tsx'));\n\nexport function ZeroInspector<\n S extends Schema,\n MD extends CustomMutatorDefs | undefined = undefined,\n>({zero}: {zero: Zero<S, MD>}): JSX.Element {\n const [show, setShow] = useState(false);\n return show ? (\n <Suspense fallback={<div>Loading Inspector...</div>}>\n <Inspector\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n zero={zero as any}\n onClose={() => setShow(false)}\n />\n </Suspense>\n ) : (\n <button\n onClick={() => setShow(!show)}\n style={{\n position: 'fixed',\n bottom: 0,\n right: 0,\n zIndex: 1000,\n padding: '5px',\n color: 'white',\n backgroundColor: '#333',\n borderTopLeftRadius: '8px',\n opacity: 0.95,\n }}\n >\n <MarkIcon\n style={{\n width: '20px',\n height: '20px',\n fill: 'currentColor',\n }}\n />\n </button>\n );\n}\n", "import {resolver} from '@rocicorp/resolver';\nimport React, {useSyncExternalStore} from 'react';\nimport {deepClone} from '../../shared/src/deep-clone.ts';\nimport type {Immutable} from '../../shared/src/immutable.ts';\nimport type {ReadonlyJSONValue} from '../../shared/src/json.ts';\nimport {Zero} from '../../zero-client/src/client/zero.ts';\nimport type {ErroredQuery} from '../../zero-protocol/src/custom-queries.ts';\nimport type {Schema} from '../../zero-schema/src/builder/schema-builder.ts';\nimport type {Format} from '../../zql/src/ivm/view.ts';\nimport {AbstractQuery} from '../../zql/src/query/query-impl.ts';\nimport {type HumanReadable, type Query} from '../../zql/src/query/query.ts';\nimport {DEFAULT_TTL_MS, type TTL} from '../../zql/src/query/ttl.ts';\nimport type {ResultType, TypedView} from '../../zql/src/query/typed-view.ts';\nimport {useZero} from './zero-provider.tsx';\nimport type {\n QueryErrorDetails,\n QueryResultDetails,\n} from '../../zero-client/src/types/query-result.ts';\n\nexport type QueryResult<TReturn> = readonly [\n HumanReadable<TReturn>,\n QueryResultDetails,\n];\n\nexport type UseQueryOptions = {\n enabled?: boolean | undefined;\n /**\n * Time to live (TTL) in seconds. Controls how long query results are cached\n * after the query is removed. During this time, Zero continues to sync the query.\n * Default is 'never'.\n */\n ttl?: TTL | undefined;\n};\n\nexport type UseSuspenseQueryOptions = UseQueryOptions & {\n /**\n * Whether to suspend until:\n * - 'partial': the query has partial results (partial array or defined\n * value for singular results) which may be of result type 'unknown',\n * or the query result type is 'complete' (in which case results may be\n * empty). This is useful for suspending until there are partial\n * optimistic local results, or the query has completed loading from the\n * server.\n * - 'complete': the query result type is 'complete'.\n *\n * Default is 'partial'.\n */\n suspendUntil?: 'complete' | 'partial';\n};\n\nconst reactUse = (React as {use?: (p: Promise<unknown>) => void}).use;\nconst suspend: (p: Promise<unknown>) => void = reactUse\n ? reactUse\n : p => {\n throw p;\n };\n\nexport function useQuery<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n TReturn,\n>(\n query: Query<TSchema, TTable, TReturn>,\n options?: UseQueryOptions | boolean,\n): QueryResult<TReturn> {\n let enabled = true;\n let ttl: TTL = DEFAULT_TTL_MS;\n if (typeof options === 'boolean') {\n enabled = options;\n } else if (options) {\n ({enabled = true, ttl = DEFAULT_TTL_MS} = options);\n }\n\n const view = viewStore.getView(\n useZero(),\n query as AbstractQuery<TSchema, TTable, TReturn>,\n enabled,\n ttl,\n );\n // https://react.dev/reference/react/useSyncExternalStore\n return useSyncExternalStore(\n view.subscribeReactInternals,\n view.getSnapshot,\n view.getSnapshot,\n );\n}\n\nexport function useSuspenseQuery<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n TReturn,\n>(\n query: Query<TSchema, TTable, TReturn>,\n options?: UseSuspenseQueryOptions | boolean,\n): QueryResult<TReturn> {\n let enabled = true;\n let ttl: TTL = DEFAULT_TTL_MS;\n let suspendUntil: 'complete' | 'partial' = 'partial';\n if (typeof options === 'boolean') {\n enabled = options;\n } else if (options) {\n ({\n enabled = true,\n ttl = DEFAULT_TTL_MS,\n suspendUntil = 'complete',\n } = options);\n }\n\n const view = viewStore.getView(\n useZero(),\n query as AbstractQuery<TSchema, TTable, TReturn>,\n enabled,\n ttl,\n );\n // https://react.dev/reference/react/useSyncExternalStore\n const snapshot = useSyncExternalStore(\n view.subscribeReactInternals,\n view.getSnapshot,\n view.getSnapshot,\n );\n\n if (enabled) {\n if (suspendUntil === 'complete' && !view.complete) {\n suspend(view.waitForComplete());\n }\n\n if (suspendUntil === 'partial' && !view.nonEmpty) {\n suspend(view.waitForNonEmpty());\n }\n }\n\n return snapshot;\n}\n\nconst emptyArray: unknown[] = [];\nconst disabledSubscriber = () => () => {};\n\nconst resultTypeUnknown = {type: 'unknown'} as const;\nconst resultTypeComplete = {type: 'complete'} as const;\nconst resultTypeError = {type: 'error'} as const;\n\nconst emptySnapshotSingularUnknown = [undefined, resultTypeUnknown] as const;\nconst emptySnapshotSingularComplete = [undefined, resultTypeComplete] as const;\nconst emptySnapshotSingularErrorUnknown = [undefined, resultTypeError] as const;\nconst emptySnapshotPluralUnknown = [emptyArray, resultTypeUnknown] as const;\nconst emptySnapshotPluralComplete = [emptyArray, resultTypeComplete] as const;\nconst emptySnapshotErrorUnknown = [emptyArray, resultTypeError] as const;\n\nfunction getDefaultSnapshot<TReturn>(singular: boolean): QueryResult<TReturn> {\n return (\n singular ? emptySnapshotSingularUnknown : emptySnapshotPluralUnknown\n ) as QueryResult<TReturn>;\n}\n\n/**\n * Returns a new snapshot or one of the empty predefined ones. Returning the\n * predefined ones is important to prevent unnecessary re-renders in React.\n */\nfunction getSnapshot<TReturn>(\n singular: boolean,\n data: HumanReadable<TReturn>,\n resultType: ResultType,\n retryFn: () => void,\n error?: ErroredQuery,\n): QueryResult<TReturn> {\n if (singular && data === undefined) {\n switch (resultType) {\n case 'error':\n if (error) {\n return [\n undefined,\n makeError(retryFn, error),\n ] as unknown as QueryResult<TReturn>;\n }\n return emptySnapshotSingularErrorUnknown as unknown as QueryResult<TReturn>;\n case 'complete':\n return emptySnapshotSingularComplete as unknown as QueryResult<TReturn>;\n case 'unknown':\n return emptySnapshotSingularUnknown as unknown as QueryResult<TReturn>;\n }\n }\n\n if (!singular && (data as unknown[]).length === 0) {\n switch (resultType) {\n case 'error':\n if (error) {\n return [\n emptyArray,\n makeError(retryFn, error),\n ] as unknown as QueryResult<TReturn>;\n }\n return emptySnapshotErrorUnknown as unknown as QueryResult<TReturn>;\n case 'complete':\n return emptySnapshotPluralComplete as unknown as QueryResult<TReturn>;\n case 'unknown':\n return emptySnapshotPluralUnknown as unknown as QueryResult<TReturn>;\n }\n }\n\n switch (resultType) {\n case 'error':\n if (error) {\n return [data, makeError(retryFn, error)];\n }\n return [\n data,\n makeError(retryFn, {\n error: 'app',\n id: 'unknown',\n name: 'unknown',\n message: 'An unknown error occurred',\n }),\n ];\n case 'complete':\n return [data, resultTypeComplete];\n case 'unknown':\n return [data, resultTypeUnknown];\n }\n}\n\nfunction makeError(retry: () => void, error: ErroredQuery): QueryErrorDetails {\n const message = error.message ?? 'An unknown error occurred';\n return {\n type: 'error',\n retry,\n refetch: retry,\n error: {\n type: error.error,\n message,\n ...(error.details ? {details: error.details} : {}),\n },\n };\n}\n\ndeclare const TESTING: boolean;\n\n// oxlint-disable-next-line @typescript-eslint/no-explicit-any\ntype ViewWrapperAny = ViewWrapper<any, any, any>;\n\nconst allViews = new WeakMap<ViewStore, Map<string, ViewWrapperAny>>();\n\nexport function getAllViewsSizeForTesting(store: ViewStore): number {\n if (TESTING) {\n return allViews.get(store)?.size ?? 0;\n }\n return 0;\n}\n\n/**\n * A global store of all active views.\n *\n * React subscribes and unsubscribes to these views\n * via `useSyncExternalStore`.\n *\n * Managing views through `useEffect` or `useLayoutEffect` causes\n * inconsistencies because effects run after render.\n *\n * For example, if useQuery used use*Effect in the component below:\n * ```ts\n * function Foo({issueID}) {\n * const issue = useQuery(z.query.issue.where('id', issueID).one());\n * if (issue?.id !== undefined && issue.id !== issueID) {\n * console.log('MISMATCH!', issue.id, issueID);\n * }\n * }\n * ```\n *\n * `MISMATCH` will be printed whenever the `issueID` prop changes.\n *\n * This is because the component will render once with\n * the old state returned from `useQuery`. Then the effect inside\n * `useQuery` will run. The component will render again with the new\n * state. This inconsistent transition can cause unexpected results.\n *\n * Emulating `useEffect` via `useState` and `if` causes resource leaks.\n * That is:\n *\n * ```ts\n * function useQuery(q) {\n * const [oldHash, setOldHash] = useState();\n * if (hash(q) !== oldHash) {\n * // make new view\n * }\n *\n * useEffect(() => {\n * return () => view.destroy();\n * }, []);\n * }\n * ```\n *\n * I'm not sure why but in strict mode the cleanup function\n * fails to be called for the first instance of the view and only\n * cleans up later instances.\n *\n * Swapping `useState` to `useRef` has similar problems.\n */\nexport class ViewStore {\n #views = new Map<string, ViewWrapperAny>();\n\n constructor() {\n if (TESTING) {\n allViews.set(this, this.#views);\n }\n }\n\n getView<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n TReturn,\n >(\n zero: Zero<TSchema>,\n query: Query<TSchema, TTable, TReturn>,\n enabled: boolean,\n ttl: TTL,\n ): {\n getSnapshot: () => QueryResult<TReturn>;\n subscribeReactInternals: (internals: () => void) => () => void;\n updateTTL: (ttl: TTL) => void;\n waitForComplete: () => Promise<void>;\n waitForNonEmpty: () => Promise<void>;\n complete: boolean;\n nonEmpty: boolean;\n } {\n const {format} = query;\n if (!enabled) {\n return {\n getSnapshot: () => getDefaultSnapshot(format.singular),\n subscribeReactInternals: disabledSubscriber,\n updateTTL: () => {},\n waitForComplete: () => Promise.resolve(),\n waitForNonEmpty: () => Promise.resolve(),\n complete: false,\n nonEmpty: false,\n };\n }\n\n const hash = query.hash() + zero.clientID;\n let existing = this.#views.get(hash);\n if (!existing) {\n existing = new ViewWrapper(zero, query, format, ttl, view => {\n const currentView = this.#views.get(hash);\n if (currentView && currentView !== view) {\n // we replaced the view with a new one already.\n return;\n }\n this.#views.delete(hash);\n });\n this.#views.set(hash, existing);\n } else {\n existing.updateTTL(ttl);\n }\n return existing as ViewWrapper<TSchema, TTable, TReturn>;\n }\n}\n\nconst viewStore = new ViewStore();\n\n/**\n * This wraps and ref counts a view.\n *\n * The only signal we have from React as to whether or not it is\n * done with a view is when it calls `unsubscribe`.\n *\n * In non-strict-mode we can clean up the view as soon\n * as the listener count goes to 0.\n *\n * In strict-mode, the listener count will go to 0 then a\n * new listener for the same view is immediately added back.\n *\n * This is why the `onMaterialized` and `onDematerialized` callbacks exist --\n * they allow a view which React is still referencing to be added\n * back into the store when React re-subscribes to it.\n *\n * This wrapper also exists to deal with the various\n * `useSyncExternalStore` caveats that cause excessive\n * re-renders and materializations.\n *\n * See: https://react.dev/reference/react/useSyncExternalStore#caveats\n * Especially:\n * 1. The store snapshot returned by getSnapshot must be immutable. If the underlying store has mutable data, return a new immutable snapshot if the data has changed. Otherwise, return a cached last snapshot.\n * 2. If a different subscribe function is passed during a re-render, React will re-subscribe to the store using the newly passed subscribe function. You can prevent this by declaring subscribe outside the component.\n */\nclass ViewWrapper<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n TReturn,\n> {\n #zero: Zero<TSchema>;\n #view: TypedView<HumanReadable<TReturn>> | undefined;\n readonly #onDematerialized;\n readonly #query: Query<TSchema, TTable, TReturn>;\n readonly #format: Format;\n #snapshot: QueryResult<TReturn>;\n #reactInternals: Set<() => void>;\n #ttl: TTL;\n #complete = false;\n #completeResolver = resolver<void>();\n #nonEmpty = false;\n #nonEmptyResolver = resolver<void>();\n\n constructor(\n zero: Zero<TSchema>,\n query: Query<TSchema, TTable, TReturn>,\n format: Format,\n ttl: TTL,\n onDematerialized: (view: ViewWrapper<TSchema, TTable, TReturn>) => void,\n ) {\n this.#zero = zero;\n this.#query = query;\n this.#format = format;\n this.#ttl = ttl;\n this.#onDematerialized = onDematerialized;\n this.#snapshot = getDefaultSnapshot(format.singular);\n this.#reactInternals = new Set();\n this.#materializeIfNeeded();\n }\n\n #onData = (\n snap: Immutable<HumanReadable<TReturn>>,\n resultType: ResultType,\n error?: ErroredQuery,\n ) => {\n const data =\n snap === undefined\n ? snap\n : (deepClone(snap as ReadonlyJSONValue) as HumanReadable<TReturn>);\n this.#snapshot = getSnapshot(\n this.#format.singular,\n data,\n resultType,\n this.#retry,\n error,\n );\n if (resultType === 'complete' || resultType === 'error') {\n this.#complete = true;\n this.#completeResolver.resolve();\n this.#nonEmpty = true;\n this.#nonEmptyResolver.resolve();\n }\n\n if (\n this.#format.singular\n ? this.#snapshot[0] !== undefined\n : (this.#snapshot[0] as unknown[]).length !== 0\n ) {\n this.#nonEmpty = true;\n this.#nonEmptyResolver.resolve();\n }\n\n for (const internals of this.#reactInternals) {\n internals();\n }\n };\n\n /**\n * Called by the user to force a retry of the query\n * in the case the query errored.\n */\n #retry = () => {\n this.#view?.destroy();\n this.#view = undefined;\n this.#materializeIfNeeded();\n };\n\n #materializeIfNeeded = () => {\n if (this.#view) {\n return;\n }\n\n this.#view = this.#zero.materialize(this.#query, {ttl: this.#ttl});\n this.#view.addListener(this.#onData);\n };\n\n getSnapshot = () => this.#snapshot;\n\n subscribeReactInternals = (internals: () => void): (() => void) => {\n this.#reactInternals.add(internals);\n this.#materializeIfNeeded();\n return () => {\n this.#reactInternals.delete(internals);\n\n // only schedule a cleanup task if we have no listeners left\n if (this.#reactInternals.size === 0) {\n setTimeout(() => {\n // We already destroyed the view\n if (this.#view === undefined) {\n return;\n }\n\n // Someone re-registered a listener on this view before the timeout elapsed.\n // This happens often in strict-mode which forces a component\n // to mount, unmount, remount.\n if (this.#reactInternals.size > 0) {\n return;\n }\n\n this.#view.destroy();\n this.#view = undefined;\n this.#complete = false;\n this.#completeResolver = resolver();\n this.#nonEmpty = false;\n this.#nonEmptyResolver = resolver();\n this.#onDematerialized(this);\n }, 10);\n }\n };\n };\n\n updateTTL(ttl: TTL): void {\n this.#ttl = ttl;\n this.#view?.updateTTL(ttl);\n }\n\n get complete() {\n return this.#complete;\n }\n\n waitForComplete(): Promise<void> {\n return this.#completeResolver.promise;\n }\n\n get nonEmpty() {\n return this.#nonEmpty;\n }\n\n waitForNonEmpty(): Promise<void> {\n return this.#nonEmptyResolver.promise;\n }\n}\n", "import {hasOwn} from './has-own.ts';\nimport type {JSONValue, ReadonlyJSONValue} from './json.ts';\n\nexport function deepClone(value: ReadonlyJSONValue): JSONValue {\n const seen: Array<ReadonlyJSONValue> = [];\n return internalDeepClone(value, seen);\n}\n\nexport function internalDeepClone(\n value: ReadonlyJSONValue,\n seen: Array<ReadonlyJSONValue>,\n): JSONValue {\n switch (typeof value) {\n case 'boolean':\n case 'number':\n case 'string':\n case 'undefined':\n return value;\n case 'object': {\n if (value === null) {\n return null;\n }\n if (seen.includes(value)) {\n throw new Error('Cyclic object');\n }\n seen.push(value);\n if (Array.isArray(value)) {\n const rv = value.map(v => internalDeepClone(v, seen));\n seen.pop();\n return rv;\n }\n\n const obj: JSONValue = {};\n\n for (const k in value) {\n if (hasOwn(value, k)) {\n const v = (value as Record<string, ReadonlyJSONValue>)[k];\n if (v !== undefined) {\n obj[k] = internalDeepClone(v, seen);\n }\n }\n }\n seen.pop();\n return obj;\n }\n\n default:\n throw new Error(`Invalid type: ${typeof value}`);\n }\n}\n", "import {\n createContext,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from 'react';\nimport type {CustomMutatorDefs} from '../../zero-client/src/client/custom.ts';\nimport type {ZeroOptions} from '../../zero-client/src/client/options.ts';\nimport {Zero} from '../../zero-client/src/client/zero.ts';\nimport type {Schema} from '../../zero-schema/src/builder/schema-builder.ts';\n\nconst ZeroContext = createContext<unknown | undefined>(undefined);\n\nexport function useZero<\n S extends Schema,\n MD extends CustomMutatorDefs | undefined = undefined,\n>(): Zero<S, MD> {\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>;\n}\n\nexport function createUseZero<\n S extends Schema,\n MD extends CustomMutatorDefs | undefined = undefined,\n>() {\n return () => useZero<S, MD>();\n}\n\nexport type ZeroProviderProps<\n S extends Schema,\n MD extends CustomMutatorDefs | undefined = undefined,\n> = (ZeroOptions<S, MD> | {zero: Zero<S, MD>}) & {\n init?: (zero: Zero<S, MD>) => void;\n children: ReactNode;\n};\n\nconst NO_AUTH_SET = Symbol('NO_AUTH_SET');\n\nexport function ZeroProvider<\n S extends Schema,\n MD extends CustomMutatorDefs | undefined = undefined,\n>({children, init, ...props}: ZeroProviderProps<S, MD>) {\n const isExternalZero = 'zero' in props;\n\n const [zero, setZero] = useState<Zero<S, MD> | 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]) => a.localeCompare(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", "import {useSyncExternalStore} from 'react';\nimport type {ConnectionState} from '../../zero-client/src/client/connection-manager.ts';\nimport {useZero} from './zero-provider.tsx';\n\n/**\n * Hook to subscribe to the connection status of the Zero instance.\n *\n * @returns The connection status of the Zero instance.\n * @see {@link ConnectionState} for more details on the connection state.\n */\nexport function useZeroConnectionState(): ConnectionState {\n const zero = useZero();\n return useSyncExternalStore(\n zero.connection.state.subscribe,\n () => zero.connection.state.current,\n () => zero.connection.state.current,\n );\n}\n", "import {useSyncExternalStore} from 'react';\nimport {useZero} from './zero-provider.tsx';\n\n/**\n * Hook to subscribe to the online status of the Zero instance.\n *\n * This is useful when you want to update state based on the online status.\n *\n * @returns The online status of the Zero instance.\n *\n * @deprecated Use {@linkcode useZeroConnectionState} instead, which provides more detailed connection state.\n */\nexport function useZeroOnline(): boolean {\n const zero = useZero();\n return useSyncExternalStore(\n zero.onOnline,\n () => zero.online,\n () => zero.online,\n );\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["useState", "jsx", "useState", "useSyncExternalStore", "useSyncExternalStore", "useSyncExternalStore", "useSyncExternalStore"]
7
7
  }
@@ -0,0 +1,4 @@
1
+ import type { ReadonlyJSONValue } from './json.ts';
2
+ export declare function getErrorMessage(error: unknown): string;
3
+ export declare function getErrorDetails(error: unknown): ReadonlyJSONValue | undefined;
4
+ //# sourceMappingURL=error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../../../shared/src/error.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,WAAW,CAAC;AAEjD,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEtD;AAkDD,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,iBAAiB,GAAG,SAAS,CA0B7E"}
@@ -0,0 +1,70 @@
1
+ import { jsonSchema } from "./json-schema.js";
2
+ export function getErrorMessage(error) {
3
+ return getErrorMessageInternal(error, new Set());
4
+ }
5
+ function getErrorMessageInternal(error, seen) {
6
+ if (typeof error === 'string') {
7
+ return error;
8
+ }
9
+ if (typeof error === 'object' && error !== null) {
10
+ if (seen.has(error)) {
11
+ return 'Circular error reference detected while extracting the error message.';
12
+ }
13
+ seen.add(error);
14
+ }
15
+ if (error instanceof Error) {
16
+ if (error.message) {
17
+ return error.message;
18
+ }
19
+ if ('cause' in error) {
20
+ const cause = error.cause;
21
+ if (cause !== undefined) {
22
+ const causeMessage = getErrorMessageInternal(cause, seen);
23
+ if (causeMessage) {
24
+ return causeMessage;
25
+ }
26
+ }
27
+ }
28
+ }
29
+ if (typeof error === 'object' &&
30
+ error !== null &&
31
+ 'message' in error &&
32
+ typeof error.message === 'string') {
33
+ const message = error.message;
34
+ if (message) {
35
+ return message;
36
+ }
37
+ }
38
+ try {
39
+ const json = jsonSchema.parse(error);
40
+ return `Parsed message: ${JSON.stringify(json)}`;
41
+ }
42
+ catch (_e) { }
43
+ return `Unknown error of type ${typeof error} was thrown and the message could not be determined. See cause for details.`;
44
+ }
45
+ export function getErrorDetails(error) {
46
+ if (error instanceof Error) {
47
+ if ('details' in error) {
48
+ try {
49
+ return jsonSchema.parse(error?.details);
50
+ }
51
+ catch (_e) { }
52
+ }
53
+ if (error.name && error.name !== 'Error') {
54
+ return { name: error.name };
55
+ }
56
+ return undefined;
57
+ }
58
+ if (typeof error === 'object' && error !== null && 'details' in error) {
59
+ try {
60
+ return jsonSchema.parse(error?.details);
61
+ }
62
+ catch (_e) { }
63
+ }
64
+ try {
65
+ return jsonSchema.parse(error);
66
+ }
67
+ catch (_e) { }
68
+ return undefined;
69
+ }
70
+ //# sourceMappingURL=error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error.js","sourceRoot":"","sources":["../../../../shared/src/error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAG5C,MAAM,UAAU,eAAe,CAAC,KAAc;IAC5C,OAAO,uBAAuB,CAAC,KAAK,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;AACnD,CAAC;AAED,SAAS,uBAAuB,CAAC,KAAc,EAAE,IAAkB;IACjE,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QAChD,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YACpB,OAAO,uEAAuE,CAAC;QACjF,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QAC3B,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YAClB,OAAO,KAAK,CAAC,OAAO,CAAC;QACvB,CAAC;QAED,IAAI,OAAO,IAAI,KAAK,EAAE,CAAC;YACrB,MAAM,KAAK,GAAI,KAA2B,CAAC,KAAK,CAAC;YACjD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACxB,MAAM,YAAY,GAAG,uBAAuB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;gBAC1D,IAAI,YAAY,EAAE,CAAC;oBACjB,OAAO,YAAY,CAAC;gBACtB,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,IACE,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,SAAS,IAAI,KAAK;QAClB,OAAQ,KAA4B,CAAC,OAAO,KAAK,QAAQ,EACzD,CAAC;QACD,MAAM,OAAO,GAAI,KAA2B,CAAC,OAAO,CAAC;QACrD,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,OAAO,CAAC;QACjB,CAAC;IACH,CAAC;IAED,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACrC,OAAO,mBAAmB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;IACnD,CAAC;IAAC,OAAO,EAAE,EAAE,CAAC,CAAA,CAAC;IAEf,OAAO,yBAAyB,OAAO,KAAK,6EAA6E,CAAC;AAC5H,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAc;IAC5C,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QAC3B,IAAI,SAAS,IAAI,KAAK,EAAE,CAAC;YACvB,IAAI,CAAC;gBACH,OAAO,UAAU,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YAC1C,CAAC;YAAC,OAAO,EAAE,EAAE,CAAC,CAAA,CAAC;QACjB,CAAC;QAED,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YACzC,OAAO,EAAC,IAAI,EAAE,KAAK,CAAC,IAAI,EAAC,CAAC;QAC5B,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,SAAS,IAAI,KAAK,EAAE,CAAC;QACtE,IAAI,CAAC;YACH,OAAO,UAAU,CAAC,KAAK,CAAE,KAAsC,EAAE,OAAO,CAAC,CAAC;QAC5E,CAAC;QAAC,OAAO,EAAE,EAAE,CAAC,CAAA,CAAC;IACjB,CAAC;IAED,IAAI,CAAC;QACH,OAAO,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC;IAAC,OAAO,EAAE,EAAE,CAAC,CAAA,CAAC;IAEf,OAAO,SAAS,CAAC;AACnB,CAAC"}