@rocicorp/zero 0.22.2025071100 → 0.22.2025071900
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/out/{chunk-ZVMEFHVU.js → chunk-A6LHZQIK.js} +26 -7
- package/out/{chunk-ZVMEFHVU.js.map → chunk-A6LHZQIK.js.map} +2 -2
- package/out/{chunk-ZRSXCDPE.js → chunk-IQCMHXK7.js} +167 -37
- package/out/chunk-IQCMHXK7.js.map +7 -0
- package/out/{chunk-INLOZBST.js → chunk-P5M53J4D.js} +2 -3
- package/out/{chunk-INLOZBST.js.map → chunk-P5M53J4D.js.map} +2 -2
- package/out/{inspector-HDOYOVMS.js → inspector-TFZBDN6K.js} +2 -2
- package/out/react.js +2 -2
- package/out/replicache/src/kv/idb-store.d.ts.map +1 -1
- package/out/shared/src/options.d.ts +4 -1
- package/out/shared/src/options.d.ts.map +1 -1
- package/out/shared/src/options.js +1 -1
- package/out/shared/src/options.js.map +1 -1
- package/out/solid.js +7 -3
- package/out/solid.js.map +1 -1
- package/out/zero/package.json +161 -0
- package/out/zero-cache/src/config/normalize.d.ts +1 -0
- package/out/zero-cache/src/config/normalize.d.ts.map +1 -1
- package/out/zero-cache/src/config/normalize.js +10 -1
- package/out/zero-cache/src/config/normalize.js.map +1 -1
- package/out/zero-cache/src/config/zero-config.d.ts +44 -6
- package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
- package/out/zero-cache/src/config/zero-config.js +48 -54
- package/out/zero-cache/src/config/zero-config.js.map +1 -1
- package/out/zero-cache/src/custom/fetch.d.ts +14 -1
- package/out/zero-cache/src/custom/fetch.d.ts.map +1 -1
- package/out/zero-cache/src/custom/fetch.js +56 -1
- package/out/zero-cache/src/custom/fetch.js.map +1 -1
- package/out/zero-cache/src/custom-queries/transform-query.d.ts +1 -1
- package/out/zero-cache/src/custom-queries/transform-query.d.ts.map +1 -1
- package/out/zero-cache/src/custom-queries/transform-query.js +2 -1
- package/out/zero-cache/src/custom-queries/transform-query.js.map +1 -1
- package/out/zero-cache/src/observability/histograms.d.ts.map +1 -1
- package/out/zero-cache/src/observability/histograms.js +8 -14
- package/out/zero-cache/src/observability/histograms.js.map +1 -1
- package/out/zero-cache/src/server/anonymous-otel-start.d.ts +9 -0
- package/out/zero-cache/src/server/anonymous-otel-start.d.ts.map +1 -0
- package/out/zero-cache/src/server/anonymous-otel-start.js +289 -0
- package/out/zero-cache/src/server/anonymous-otel-start.js.map +1 -0
- package/out/zero-cache/src/server/main.d.ts.map +1 -1
- package/out/zero-cache/src/server/main.js +1 -5
- package/out/zero-cache/src/server/main.js.map +1 -1
- package/out/zero-cache/src/server/otel-start.js +1 -1
- package/out/zero-cache/src/server/otel-start.js.map +1 -1
- package/out/zero-cache/src/server/runner/zero-dispatcher.d.ts.map +1 -1
- package/out/zero-cache/src/server/runner/zero-dispatcher.js +2 -2
- package/out/zero-cache/src/server/runner/zero-dispatcher.js.map +1 -1
- package/out/zero-cache/src/server/syncer.d.ts.map +1 -1
- package/out/zero-cache/src/server/syncer.js +6 -3
- package/out/zero-cache/src/server/syncer.js.map +1 -1
- package/out/zero-cache/src/server/worker-dispatcher.js +3 -3
- package/out/zero-cache/src/server/worker-dispatcher.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/change-source.d.ts +0 -7
- package/out/zero-cache/src/services/change-source/pg/change-source.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/change-source.js +43 -32
- package/out/zero-cache/src/services/change-source/pg/change-source.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/initial-sync.js +24 -12
- package/out/zero-cache/src/services/change-source/pg/initial-sync.js.map +1 -1
- package/out/zero-cache/src/services/mutagen/mutagen.d.ts.map +1 -1
- package/out/zero-cache/src/services/mutagen/mutagen.js +4 -0
- package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
- package/out/zero-cache/src/services/mutagen/pusher.d.ts +4 -4
- package/out/zero-cache/src/services/mutagen/pusher.d.ts.map +1 -1
- package/out/zero-cache/src/services/mutagen/pusher.js +8 -5
- package/out/zero-cache/src/services/mutagen/pusher.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts +11 -8
- package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr-store.js +14 -13
- package/out/zero-cache/src/services/view-syncer/cvr-store.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr.d.ts +9 -16
- package/out/zero-cache/src/services/view-syncer/cvr.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr.js +25 -28
- package/out/zero-cache/src/services/view-syncer/cvr.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/row-record-cache.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/row-record-cache.js +3 -0
- package/out/zero-cache/src/services/view-syncer/row-record-cache.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/schema/cvr.d.ts +3 -2
- package/out/zero-cache/src/services/view-syncer/schema/cvr.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/schema/cvr.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/schema/types.d.ts +11 -11
- package/out/zero-cache/src/services/view-syncer/schema/types.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/schema/types.js +3 -2
- package/out/zero-cache/src/services/view-syncer/schema/types.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/ttl-clock.d.ts +10 -0
- package/out/zero-cache/src/services/view-syncer/ttl-clock.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/ttl-clock.js +9 -0
- package/out/zero-cache/src/services/view-syncer/ttl-clock.js.map +1 -0
- package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts +14 -13
- package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/view-syncer.js +92 -124
- package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
- package/out/zero-cache/src/types/processes.d.ts +6 -6
- package/out/zero-cache/src/types/processes.d.ts.map +1 -1
- package/out/zero-cache/src/types/processes.js +2 -2
- package/out/zero-cache/src/types/processes.js.map +1 -1
- package/out/zero-cache/src/types/websocket-handoff.d.ts +2 -2
- package/out/zero-cache/src/types/websocket-handoff.d.ts.map +1 -1
- package/out/zero-cache/src/types/websocket-handoff.js +4 -4
- package/out/zero-cache/src/types/websocket-handoff.js.map +1 -1
- package/out/zero-cache/src/workers/connection.d.ts +1 -1
- package/out/zero-cache/src/workers/connection.d.ts.map +1 -1
- package/out/zero-cache/src/workers/connection.js +2 -0
- package/out/zero-cache/src/workers/connection.js.map +1 -1
- package/out/zero-cache/src/workers/syncer-ws-message-handler.js +1 -1
- package/out/zero-cache/src/workers/syncer-ws-message-handler.js.map +1 -1
- package/out/zero-cache/src/workers/syncer.d.ts.map +1 -1
- package/out/zero-cache/src/workers/syncer.js +3 -1
- package/out/zero-cache/src/workers/syncer.js.map +1 -1
- package/out/zero-client/src/client/active-clients-manager.d.ts.map +1 -1
- package/out/zero-client/src/client/mutation-tracker.d.ts +38 -5
- package/out/zero-client/src/client/mutation-tracker.d.ts.map +1 -1
- package/out/zero-client/src/client/options.d.ts +9 -4
- package/out/zero-client/src/client/options.d.ts.map +1 -1
- package/out/zero-client/src/client/query-manager.d.ts.map +1 -1
- package/out/zero-client/src/client/zero.d.ts +2 -2
- package/out/zero-client/src/client/zero.d.ts.map +1 -1
- package/out/zero-client/src/mod.d.ts +1 -1
- package/out/zero-client/src/mod.d.ts.map +1 -1
- package/out/zero-protocol/src/connect.d.ts +24 -2
- package/out/zero-protocol/src/connect.d.ts.map +1 -1
- package/out/zero-protocol/src/connect.js +26 -5
- package/out/zero-protocol/src/connect.js.map +1 -1
- package/out/zero-protocol/src/protocol-version.d.ts +1 -1
- package/out/zero-protocol/src/protocol-version.d.ts.map +1 -1
- package/out/zero-protocol/src/protocol-version.js +2 -1
- package/out/zero-protocol/src/protocol-version.js.map +1 -1
- package/out/zero-protocol/src/up.d.ts +5 -0
- package/out/zero-protocol/src/up.d.ts.map +1 -1
- package/out/zero-server/src/queries/process-queries.d.ts +1 -1
- package/out/zero-server/src/queries/process-queries.d.ts.map +1 -1
- package/out/zero-server/src/queries/process-queries.js +1 -1
- package/out/zero-server/src/queries/process-queries.js.map +1 -1
- package/out/zero-solid/src/mod.d.ts +2 -2
- package/out/zero-solid/src/mod.d.ts.map +1 -1
- package/out/zero.js +9 -7
- package/out/zql/src/query/named.d.ts +11 -11
- package/out/zql/src/query/named.d.ts.map +1 -1
- package/out/zql/src/query/named.js +20 -2
- package/out/zql/src/query/named.js.map +1 -1
- package/out/zql/src/query/query-impl.js +1 -1
- package/out/zql/src/query/query-impl.js.map +1 -1
- package/out/zql/src/query/query.d.ts +12 -3
- package/out/zql/src/query/query.d.ts.map +1 -1
- package/out/zql/src/query/query.js.map +1 -1
- package/package.json +2 -2
- package/out/chunk-ZRSXCDPE.js.map +0 -7
- /package/out/{inspector-HDOYOVMS.js.map → inspector-TFZBDN6K.js.map} +0 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
-
clientToServer
|
|
3
|
-
|
|
2
|
+
clientToServer,
|
|
3
|
+
mapEntries
|
|
4
|
+
} from "./chunk-IQCMHXK7.js";
|
|
4
5
|
import {
|
|
5
6
|
AbstractQuery,
|
|
6
7
|
ExpressionBuilder,
|
|
@@ -15,7 +16,7 @@ import {
|
|
|
15
16
|
staticParam,
|
|
16
17
|
toStaticParam,
|
|
17
18
|
valita_exports
|
|
18
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-P5M53J4D.js";
|
|
19
20
|
|
|
20
21
|
// ../zero-protocol/src/custom-queries.ts
|
|
21
22
|
var transformRequestBodySchema = valita_exports.array(
|
|
@@ -300,12 +301,29 @@ function escapeLike(val) {
|
|
|
300
301
|
}
|
|
301
302
|
|
|
302
303
|
// ../zql/src/query/named.ts
|
|
303
|
-
function
|
|
304
|
+
function createBuilder(s) {
|
|
304
305
|
return makeQueryBuilders(s);
|
|
305
306
|
}
|
|
306
307
|
function namedQuery(name, fn) {
|
|
307
308
|
return (...args) => fn(...args).nameAndArgs(name, args);
|
|
308
309
|
}
|
|
310
|
+
function contextualizedNamedQuery(name, fn) {
|
|
311
|
+
const ret = (context, ...args) => fn(context, ...args).nameAndArgs(name, args);
|
|
312
|
+
ret.contextualized = true;
|
|
313
|
+
return ret;
|
|
314
|
+
}
|
|
315
|
+
function named(queries) {
|
|
316
|
+
return mapEntries(queries, (name, query) => [
|
|
317
|
+
name,
|
|
318
|
+
namedQuery(name, query)
|
|
319
|
+
]);
|
|
320
|
+
}
|
|
321
|
+
function namedWithContext(queries) {
|
|
322
|
+
return mapEntries(queries, (name, query) => [
|
|
323
|
+
name,
|
|
324
|
+
contextualizedNamedQuery(name, query)
|
|
325
|
+
]);
|
|
326
|
+
}
|
|
309
327
|
function makeQueryBuilders(schema) {
|
|
310
328
|
return new Proxy(
|
|
311
329
|
{},
|
|
@@ -334,7 +352,8 @@ export {
|
|
|
334
352
|
NOBODY_CAN,
|
|
335
353
|
definePermissions,
|
|
336
354
|
escapeLike,
|
|
337
|
-
|
|
338
|
-
|
|
355
|
+
createBuilder,
|
|
356
|
+
named,
|
|
357
|
+
namedWithContext
|
|
339
358
|
};
|
|
340
|
-
//# sourceMappingURL=chunk-
|
|
359
|
+
//# sourceMappingURL=chunk-A6LHZQIK.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../zero-protocol/src/custom-queries.ts", "../../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": ["import {jsonSchema} from '../../shared/src/json-schema.ts';\nimport * as v from '../../shared/src/valita.ts';\nimport {astSchema} from './ast.ts';\n\nexport const transformRequestBodySchema = v.array(\n v.object({\n id: v.string(),\n name: v.string(),\n args: v.readonly(v.array(jsonSchema)),\n }),\n);\nexport type TransformRequestBody = v.Infer<typeof transformRequestBodySchema>;\n\nexport const transformedQuerySchema = v.object({\n id: v.string(),\n name: v.string(),\n ast: astSchema,\n});\n\nexport const erroredQuerySchema = v.object({\n error: v.literal('app'),\n id: v.string(),\n name: v.string(),\n details: jsonSchema,\n});\nexport type ErroredQuery = v.Infer<typeof erroredQuerySchema>;\n\nexport const transformResponseBodySchema = v.array(\n v.union(transformedQuerySchema, erroredQuerySchema),\n);\nexport type TransformResponseBody = v.Infer<typeof transformResponseBodySchema>;\n\nexport const transformRequestMessageSchema = v.tuple([\n v.literal('transform'),\n transformRequestBodySchema,\n]);\nexport type TransformRequestMessage = v.Infer<\n typeof transformRequestMessageSchema\n>;\n\nexport const transformResponseMessageSchema = v.tuple([\n v.literal('transformed'),\n transformResponseBodySchema,\n]);\nexport type TransformResponseMessage = v.Infer<\n typeof transformResponseMessageSchema\n>;\n", "/* eslint-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\nexport function relationships<\n TSource extends TableSchema,\n TRelationships extends Record<string, Relationship>,\n>(\n table: TableBuilderWithColumns<TSource>,\n cb: (connects: {\n many: <\n TDests extends TableSchema[],\n TSourceFields extends {\n [K in keyof TDests]: (keyof PreviousSchema<\n TSource,\n K & number,\n TDests\n >['columns'] &\n string)[];\n },\n TDestFields extends {\n [K in keyof TDests]: (keyof TDests[K]['columns'] & string)[];\n },\n >(\n ...args: {\n [K in keyof TDests]: ConnectArg<\n TSourceFields[K],\n TDestFields[K],\n TDests[K]\n >;\n }\n ) => {\n [K in keyof TDests]: ManyConnection<\n TSourceFields[K],\n TDestFields[K],\n TDests[K]\n >;\n };\n one: <\n TDests extends TableSchema[],\n TSourceFields extends {\n [K in keyof TDests]: (keyof PreviousSchema<\n TSource,\n K & number,\n TDests\n >['columns'] &\n string)[];\n },\n TDestFields extends {\n [K in keyof TDests]: (keyof TDests[K]['columns'] & string)[];\n },\n >(\n ...args: {\n [K in keyof TDests]: ConnectArg<\n TSourceFields[K],\n TDestFields[K],\n TDests[K]\n >;\n }\n ) => {\n [K in keyof TDests]: OneConnection<\n TSourceFields[K],\n TDestFields[K],\n TDests[K]\n >;\n };\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-schema/src/builder/schema-builder.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, defaultFormat, 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 | undefined,\n currentJunction?: string | undefined,\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 type {ExpressionBuilder} from '../../zql/src/query/expression.ts';\nimport {defaultFormat, staticParam} from '../../zql/src/query/query-impl.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];\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};\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 insert?: PermissionRule<TAuthDataShape, TSchema, TTable>[] | undefined;\n update?:\n | {\n preMutation?: PermissionRule<TAuthDataShape, TSchema, TTable>[];\n postMutation?: PermissionRule<TAuthDataShape, TSchema, TTable>[];\n }\n | undefined;\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');\n", "export function escapeLike(val: string) {\n return val.replace(/[%_]/g, '\\\\$&');\n}\n", "/* eslint-disable @typescript-eslint/no-explicit-any */\nimport type {ReadonlyJSONValue} from '../../../shared/src/json.ts';\nimport type {Schema} from '../../../zero-schema/src/builder/schema-builder.ts';\nimport type {SchemaQuery} from '../mutate/custom.ts';\nimport {newQuery} from './query-impl.ts';\nimport type {Query} from './query.ts';\n\nexport type NamedQuery<\n TArg extends\n ReadonlyArray<ReadonlyJSONValue> = ReadonlyArray<ReadonlyJSONValue>,\n TReturnQuery extends Query<any, any, any> = Query<any, any, any>,\n> = (...args: TArg) => TReturnQuery;\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 querify<S extends Schema>(s: S): SchemaQuery<S> {\n return makeQueryBuilders(s) as SchemaQuery<S>;\n}\n\n/**\n * Tags a query with a name and arguments.\n * Named queries are run on both the client and server.\n * The server will receive the name and arguments for a named query and can\n * either run the same query the client did or a completely different one.\n *\n * The main use case here is to apply permissions to the requested query or\n * to expand the scope of the query to include additional data. E.g., for preloading.\n */\nexport function namedQuery<\n TArg extends ReadonlyArray<ReadonlyJSONValue>,\n TReturnQuery extends Query<any, any, any>,\n>(\n name: string,\n fn: NamedQuery<TArg, TReturnQuery>,\n): NamedQuery<TArg, TReturnQuery> {\n return ((...args: TArg) => fn(...args).nameAndArgs(name, args)) as NamedQuery<\n TArg,\n TReturnQuery\n >;\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": "
|
|
4
|
+
"sourcesContent": ["import {jsonSchema} from '../../shared/src/json-schema.ts';\nimport * as v from '../../shared/src/valita.ts';\nimport {astSchema} from './ast.ts';\n\nexport const transformRequestBodySchema = v.array(\n v.object({\n id: v.string(),\n name: v.string(),\n args: v.readonly(v.array(jsonSchema)),\n }),\n);\nexport type TransformRequestBody = v.Infer<typeof transformRequestBodySchema>;\n\nexport const transformedQuerySchema = v.object({\n id: v.string(),\n name: v.string(),\n ast: astSchema,\n});\n\nexport const erroredQuerySchema = v.object({\n error: v.literal('app'),\n id: v.string(),\n name: v.string(),\n details: jsonSchema,\n});\nexport type ErroredQuery = v.Infer<typeof erroredQuerySchema>;\n\nexport const transformResponseBodySchema = v.array(\n v.union(transformedQuerySchema, erroredQuerySchema),\n);\nexport type TransformResponseBody = v.Infer<typeof transformResponseBodySchema>;\n\nexport const transformRequestMessageSchema = v.tuple([\n v.literal('transform'),\n transformRequestBodySchema,\n]);\nexport type TransformRequestMessage = v.Infer<\n typeof transformRequestMessageSchema\n>;\n\nexport const transformResponseMessageSchema = v.tuple([\n v.literal('transformed'),\n transformResponseBodySchema,\n]);\nexport type TransformResponseMessage = v.Infer<\n typeof transformResponseMessageSchema\n>;\n", "/* eslint-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\nexport function relationships<\n TSource extends TableSchema,\n TRelationships extends Record<string, Relationship>,\n>(\n table: TableBuilderWithColumns<TSource>,\n cb: (connects: {\n many: <\n TDests extends TableSchema[],\n TSourceFields extends {\n [K in keyof TDests]: (keyof PreviousSchema<\n TSource,\n K & number,\n TDests\n >['columns'] &\n string)[];\n },\n TDestFields extends {\n [K in keyof TDests]: (keyof TDests[K]['columns'] & string)[];\n },\n >(\n ...args: {\n [K in keyof TDests]: ConnectArg<\n TSourceFields[K],\n TDestFields[K],\n TDests[K]\n >;\n }\n ) => {\n [K in keyof TDests]: ManyConnection<\n TSourceFields[K],\n TDestFields[K],\n TDests[K]\n >;\n };\n one: <\n TDests extends TableSchema[],\n TSourceFields extends {\n [K in keyof TDests]: (keyof PreviousSchema<\n TSource,\n K & number,\n TDests\n >['columns'] &\n string)[];\n },\n TDestFields extends {\n [K in keyof TDests]: (keyof TDests[K]['columns'] & string)[];\n },\n >(\n ...args: {\n [K in keyof TDests]: ConnectArg<\n TSourceFields[K],\n TDestFields[K],\n TDests[K]\n >;\n }\n ) => {\n [K in keyof TDests]: OneConnection<\n TSourceFields[K],\n TDestFields[K],\n TDests[K]\n >;\n };\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-schema/src/builder/schema-builder.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, defaultFormat, 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 | undefined,\n currentJunction?: string | undefined,\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 type {ExpressionBuilder} from '../../zql/src/query/expression.ts';\nimport {defaultFormat, staticParam} from '../../zql/src/query/query-impl.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];\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};\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 insert?: PermissionRule<TAuthDataShape, TSchema, TTable>[] | undefined;\n update?:\n | {\n preMutation?: PermissionRule<TAuthDataShape, TSchema, TTable>[];\n postMutation?: PermissionRule<TAuthDataShape, TSchema, TTable>[];\n }\n | undefined;\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');\n", "export function escapeLike(val: string) {\n return val.replace(/[%_]/g, '\\\\$&');\n}\n", "/* eslint-disable @typescript-eslint/no-explicit-any */\nimport type {ReadonlyJSONValue} from '../../../shared/src/json.ts';\nimport {mapEntries} from '../../../shared/src/objects.ts';\nimport type {Schema} from '../../../zero-schema/src/builder/schema-builder.ts';\nimport type {SchemaQuery} from '../mutate/custom.ts';\nimport {newQuery} from './query-impl.ts';\nimport type {Query} from './query.ts';\n\nexport type NamedQuery<\n TArg extends\n ReadonlyArray<ReadonlyJSONValue> = ReadonlyArray<ReadonlyJSONValue>,\n TReturnQuery extends Query<any, any, any> = Query<any, any, any>,\n> = (...args: TArg) => TReturnQuery;\n\nexport type ContextualizedNamedQuery<\n TContext,\n TArg extends\n ReadonlyArray<ReadonlyJSONValue> = ReadonlyArray<ReadonlyJSONValue>,\n TReturnQuery extends Query<any, any, any> = Query<any, any, any>,\n> = {\n (context: TContext, ...args: TArg): TReturnQuery;\n contextualized?: boolean;\n};\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 * Tags a query with a name and arguments.\n * Named queries are run on both the client and server.\n * The server will receive the name and arguments for a named query and can\n * either run the same query the client did or a completely different one.\n *\n * The main use case here is to apply permissions to the requested query or\n * to expand the scope of the query to include additional data. E.g., for preloading.\n */\nfunction namedQuery(\n name: string,\n fn: NamedQuery<ReadonlyArray<ReadonlyJSONValue>, Query<any, any, any>>,\n): NamedQuery<ReadonlyArray<ReadonlyJSONValue>, Query<any, any, any>> {\n return ((...args: ReadonlyArray<ReadonlyJSONValue>) =>\n fn(...args).nameAndArgs(name, args)) as NamedQuery<\n ReadonlyArray<ReadonlyJSONValue>,\n Query<any, any, any>\n >;\n}\n\nfunction contextualizedNamedQuery<TContext>(\n name: string,\n fn: ContextualizedNamedQuery<\n TContext,\n ReadonlyArray<ReadonlyJSONValue>,\n Query<any, any, any>\n >,\n): ContextualizedNamedQuery<\n TContext,\n ReadonlyArray<ReadonlyJSONValue>,\n Query<any, any, any>\n> {\n const ret = ((context: TContext, ...args: ReadonlyArray<ReadonlyJSONValue>) =>\n fn(context, ...args).nameAndArgs(name, args)) as ContextualizedNamedQuery<\n TContext,\n ReadonlyArray<ReadonlyJSONValue>,\n Query<any, any, any>\n >;\n ret.contextualized = true;\n\n return ret;\n}\n\nexport function named<\n TQueries extends {\n [K in keyof TQueries]: TQueries[K] extends NamedQuery<\n infer TArgs,\n Query<any, any, any>\n >\n ? TArgs extends ReadonlyArray<ReadonlyJSONValue>\n ? NamedQuery<TArgs, Query<any, any, any>>\n : never\n : never;\n },\n>(queries: TQueries): TQueries {\n return mapEntries(queries, (name, query) => [\n name,\n namedQuery(name, query as any),\n ]) as TQueries;\n}\n\nexport function namedWithContext<\n TContext,\n TQueries extends {\n [K in keyof TQueries]: TQueries[K] extends ContextualizedNamedQuery<\n TContext,\n infer TArgs,\n Query<any, any, any>\n >\n ? TArgs extends ReadonlyArray<ReadonlyJSONValue>\n ? ContextualizedNamedQuery<TContext, TArgs, Query<any, any, any>>\n : never\n : never;\n },\n>(queries: TQueries): TQueries {\n return mapEntries(queries, (name, query) => [\n name,\n contextualizedNamedQuery(name, query as any),\n ]) as TQueries;\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
|
}
|
|
@@ -98,7 +98,6 @@ import {
|
|
|
98
98
|
normalizeAST,
|
|
99
99
|
once,
|
|
100
100
|
parse,
|
|
101
|
-
parseTTL,
|
|
102
101
|
primaryKeySchema,
|
|
103
102
|
primaryKeyValueRecordSchema,
|
|
104
103
|
readFromDefaultHead,
|
|
@@ -127,7 +126,7 @@ import {
|
|
|
127
126
|
withWrite,
|
|
128
127
|
withWriteNoImplicitCommit,
|
|
129
128
|
wrapIterable
|
|
130
|
-
} from "./chunk-
|
|
129
|
+
} from "./chunk-P5M53J4D.js";
|
|
131
130
|
import {
|
|
132
131
|
__export
|
|
133
132
|
} from "./chunk-424PT5DM.js";
|
|
@@ -405,7 +404,11 @@ var IDBStore = class {
|
|
|
405
404
|
assertNotNull(tx);
|
|
406
405
|
tx.abort();
|
|
407
406
|
this.#idbDeleted = true;
|
|
408
|
-
reject(
|
|
407
|
+
reject(
|
|
408
|
+
new IDBNotFoundError(
|
|
409
|
+
`Expected IndexedDB not found: ${name}. This likely means that the user deleted IndexedDB instances while the app was running. This is non-fatal. The app will continue running in memory until reload.`
|
|
410
|
+
)
|
|
411
|
+
);
|
|
409
412
|
};
|
|
410
413
|
req.onsuccess = () => resolve(req.result);
|
|
411
414
|
req.onerror = () => reject(req.error);
|
|
@@ -426,7 +429,7 @@ var IDBStore = class {
|
|
|
426
429
|
this.#idbDeleted = true;
|
|
427
430
|
mustGetBrowserGlobal("indexedDB").deleteDatabase(db.name);
|
|
428
431
|
throw new IDBNotFoundError(
|
|
429
|
-
`
|
|
432
|
+
`Expected IndexedDB ${db.name} missing object store. Deleting db. This is non-fatal, the app will continue working in memory until it is reloaded.`
|
|
430
433
|
);
|
|
431
434
|
}
|
|
432
435
|
}
|
|
@@ -5891,14 +5894,29 @@ var connectedMessageSchema = valita_exports.tuple([
|
|
|
5891
5894
|
valita_exports.literal("connected"),
|
|
5892
5895
|
connectedBodySchema
|
|
5893
5896
|
]);
|
|
5894
|
-
var
|
|
5897
|
+
var userQueryMutateParamsSchema = valita_exports.object({
|
|
5898
|
+
/**
|
|
5899
|
+
* A client driven URL to send queries or mutations to.
|
|
5900
|
+
* This URL must match one of the URLs set in the zero config.
|
|
5901
|
+
*
|
|
5902
|
+
* E.g., Given the following environment variable:
|
|
5903
|
+
* ZERO_QUERY_URL=[https://*.example.com/query]
|
|
5904
|
+
*
|
|
5905
|
+
* Then this URL could be:
|
|
5906
|
+
* https://myapp.example.com/query
|
|
5907
|
+
*/
|
|
5908
|
+
url: valita_exports.string().optional(),
|
|
5909
|
+
// The query string to use for query or mutation calls.
|
|
5895
5910
|
queryParams: valita_exports.record(valita_exports.string()).optional()
|
|
5896
5911
|
});
|
|
5897
5912
|
var initConnectionBodySchema = valita_exports.object({
|
|
5898
5913
|
desiredQueriesPatch: upQueriesPatchSchema,
|
|
5899
5914
|
clientSchema: clientSchemaSchema.optional(),
|
|
5900
5915
|
deleted: deleteClientsBodySchema.optional(),
|
|
5901
|
-
|
|
5916
|
+
// parameters to configure the mutate endpoint
|
|
5917
|
+
userPushParams: userQueryMutateParamsSchema.optional(),
|
|
5918
|
+
// parameters to configure the query endpoint
|
|
5919
|
+
userQueryParams: userQueryMutateParamsSchema.optional(),
|
|
5902
5920
|
/**
|
|
5903
5921
|
* `activeClients` is an optional array of client IDs that are currently active
|
|
5904
5922
|
* in the client group. This is used to inform the server about the clients
|
|
@@ -5916,7 +5934,8 @@ function encodeSecProtocols(initConnectionMessage, authToken) {
|
|
|
5916
5934
|
initConnectionMessage,
|
|
5917
5935
|
authToken
|
|
5918
5936
|
};
|
|
5919
|
-
|
|
5937
|
+
const bytes = new TextEncoder().encode(JSON.stringify(protocols));
|
|
5938
|
+
return encodeURIComponent(btoa(String.fromCharCode(...bytes)));
|
|
5920
5939
|
}
|
|
5921
5940
|
|
|
5922
5941
|
// ../zero-protocol/src/error.ts
|
|
@@ -6246,7 +6265,7 @@ var downstreamSchema = valita_exports.union(
|
|
|
6246
6265
|
);
|
|
6247
6266
|
|
|
6248
6267
|
// ../zero-protocol/src/protocol-version.ts
|
|
6249
|
-
var PROTOCOL_VERSION =
|
|
6268
|
+
var PROTOCOL_VERSION = 22;
|
|
6250
6269
|
var MIN_SERVER_SUPPORTED_SYNC_PROTOCOL = 18;
|
|
6251
6270
|
assert(MIN_SERVER_SUPPORTED_SYNC_PROTOCOL < PROTOCOL_VERSION);
|
|
6252
6271
|
|
|
@@ -6395,7 +6414,7 @@ var ActiveClientsManager = class _ActiveClientsManager {
|
|
|
6395
6414
|
*/
|
|
6396
6415
|
static async create(clientGroupID, clientID, signal) {
|
|
6397
6416
|
const instance = new _ActiveClientsManager(clientGroupID, clientID, signal);
|
|
6398
|
-
await instance.#init(
|
|
6417
|
+
await instance.#init(signal);
|
|
6399
6418
|
return instance;
|
|
6400
6419
|
}
|
|
6401
6420
|
constructor(clientGroupID, clientID, signal) {
|
|
@@ -6404,7 +6423,8 @@ var ActiveClientsManager = class _ActiveClientsManager {
|
|
|
6404
6423
|
this.#lockManager = getClientLockManager(signal);
|
|
6405
6424
|
this.#activeClients.add(clientID);
|
|
6406
6425
|
}
|
|
6407
|
-
async #init(
|
|
6426
|
+
async #init(signal) {
|
|
6427
|
+
const { clientGroupID, clientID } = this;
|
|
6408
6428
|
const name = toLockName(clientGroupID, clientID);
|
|
6409
6429
|
const channel = new bc(toBroadcastChannelName(clientGroupID));
|
|
6410
6430
|
channel.addEventListener(
|
|
@@ -8537,7 +8557,7 @@ function makeMessage(message, context, logLevel) {
|
|
|
8537
8557
|
}
|
|
8538
8558
|
|
|
8539
8559
|
// ../zero-client/src/client/version.ts
|
|
8540
|
-
var version2 = "0.22.
|
|
8560
|
+
var version2 = "0.22.2025071900";
|
|
8541
8561
|
|
|
8542
8562
|
// ../zero-client/src/client/log-options.ts
|
|
8543
8563
|
var LevelFilterLogSink = class {
|
|
@@ -8833,9 +8853,7 @@ var State = class {
|
|
|
8833
8853
|
|
|
8834
8854
|
// ../zero-client/src/client/mutation-tracker.ts
|
|
8835
8855
|
import { resolver as resolver8 } from "@rocicorp/resolver";
|
|
8836
|
-
var
|
|
8837
|
-
"zeroPusher",
|
|
8838
|
-
"http",
|
|
8856
|
+
var completeFailureTypes = [
|
|
8839
8857
|
// These should never actually be received as they cause the websocket
|
|
8840
8858
|
// connection to be closed.
|
|
8841
8859
|
"unsupportedPushVersion",
|
|
@@ -8848,14 +8866,20 @@ function nextEphemeralID() {
|
|
|
8848
8866
|
var MutationTracker = class {
|
|
8849
8867
|
#outstandingMutations;
|
|
8850
8868
|
#ephemeralIDsByMutationID;
|
|
8851
|
-
#
|
|
8869
|
+
#allMutationsAppliedListeners;
|
|
8852
8870
|
#lc;
|
|
8871
|
+
#limboMutations;
|
|
8853
8872
|
#clientID;
|
|
8873
|
+
#largestOutstandingMutationID;
|
|
8874
|
+
#currentMutationID;
|
|
8854
8875
|
constructor(lc) {
|
|
8855
8876
|
this.#lc = lc.withContext("MutationTracker");
|
|
8856
8877
|
this.#outstandingMutations = /* @__PURE__ */ new Map();
|
|
8857
8878
|
this.#ephemeralIDsByMutationID = /* @__PURE__ */ new Map();
|
|
8858
|
-
this.#
|
|
8879
|
+
this.#allMutationsAppliedListeners = /* @__PURE__ */ new Set();
|
|
8880
|
+
this.#limboMutations = /* @__PURE__ */ new Set();
|
|
8881
|
+
this.#largestOutstandingMutationID = 0;
|
|
8882
|
+
this.#currentMutationID = 0;
|
|
8859
8883
|
}
|
|
8860
8884
|
set clientID(clientID) {
|
|
8861
8885
|
this.#clientID = clientID;
|
|
@@ -8873,6 +8897,10 @@ var MutationTracker = class {
|
|
|
8873
8897
|
if (entry) {
|
|
8874
8898
|
entry.mutationID = mutationID;
|
|
8875
8899
|
this.#ephemeralIDsByMutationID.set(mutationID, id);
|
|
8900
|
+
this.#largestOutstandingMutationID = Math.max(
|
|
8901
|
+
this.#largestOutstandingMutationID,
|
|
8902
|
+
mutationID
|
|
8903
|
+
);
|
|
8876
8904
|
}
|
|
8877
8905
|
}
|
|
8878
8906
|
/**
|
|
@@ -8904,7 +8932,7 @@ var MutationTracker = class {
|
|
|
8904
8932
|
* to those mutations have been lost.
|
|
8905
8933
|
*
|
|
8906
8934
|
* An example case: the API server responds while the connection
|
|
8907
|
-
* is down. Those responses are
|
|
8935
|
+
* is down. Those responses are lost.
|
|
8908
8936
|
*
|
|
8909
8937
|
* Mutations whose LMID is > the lastMutationID are not resolved
|
|
8910
8938
|
* since they will be retried by the client, giving us another chance
|
|
@@ -8913,9 +8941,6 @@ var MutationTracker = class {
|
|
|
8913
8941
|
* The only way to ensure that all API server responses are
|
|
8914
8942
|
* received would be to have the API server write them
|
|
8915
8943
|
* to the DB while writing the LMID.
|
|
8916
|
-
*
|
|
8917
|
-
* This would have the downside of not being able to provide responses to a
|
|
8918
|
-
* mutation with data gathered after the transaction.
|
|
8919
8944
|
*/
|
|
8920
8945
|
onConnected(lastMutationID) {
|
|
8921
8946
|
for (const [id, entry] of this.#outstandingMutations) {
|
|
@@ -8928,12 +8953,78 @@ var MutationTracker = class {
|
|
|
8928
8953
|
break;
|
|
8929
8954
|
}
|
|
8930
8955
|
}
|
|
8956
|
+
for (const [id, entry] of this.#outstandingMutations) {
|
|
8957
|
+
if (entry.mutationID && entry.mutationID > lastMutationID) {
|
|
8958
|
+
this.#limboMutations.add(id);
|
|
8959
|
+
}
|
|
8960
|
+
}
|
|
8961
|
+
this.lmidAdvanced(lastMutationID);
|
|
8962
|
+
}
|
|
8963
|
+
/**
|
|
8964
|
+
* lmid advance will:
|
|
8965
|
+
* 1. notify "allMutationsApplied" listeners if the lastMutationID
|
|
8966
|
+
* is greater than or equal to the largest outstanding mutation ID.
|
|
8967
|
+
* 2. resolve all limbo mutations whose mutation ID is less than or equal to
|
|
8968
|
+
* the lastMutationID.
|
|
8969
|
+
*
|
|
8970
|
+
* We only resolve "limbo mutations" since we want to give the mutation
|
|
8971
|
+
* responses a chance to be received. `poke` and `pushResponse` are non transactional
|
|
8972
|
+
* so they race.
|
|
8973
|
+
*
|
|
8974
|
+
* E.g., a `push` may call the api server which:
|
|
8975
|
+
* writes to PG, replicates to zero-cache, then pokes the lmid down before the
|
|
8976
|
+
* push response is sent.
|
|
8977
|
+
*
|
|
8978
|
+
* The only fix for this would be to have mutation responses be written to the database
|
|
8979
|
+
* and sent down through the poke protocol.
|
|
8980
|
+
*
|
|
8981
|
+
* The artifact the user sees is that promise resolutions for mutations is not transactional
|
|
8982
|
+
* with the update to synced data.
|
|
8983
|
+
*
|
|
8984
|
+
* It was a mistake to not just write the mutation responses to the database
|
|
8985
|
+
* in the first place as this route ends up being more complicated
|
|
8986
|
+
* and less reliable.
|
|
8987
|
+
*/
|
|
8988
|
+
lmidAdvanced(lastMutationID) {
|
|
8989
|
+
assert(
|
|
8990
|
+
lastMutationID >= this.#currentMutationID,
|
|
8991
|
+
"lmid must be greater than or equal to current lmid"
|
|
8992
|
+
);
|
|
8993
|
+
if (lastMutationID === this.#currentMutationID) {
|
|
8994
|
+
return;
|
|
8995
|
+
}
|
|
8996
|
+
try {
|
|
8997
|
+
this.#currentMutationID = lastMutationID;
|
|
8998
|
+
this.#resolveLimboMutations(lastMutationID);
|
|
8999
|
+
} finally {
|
|
9000
|
+
if (lastMutationID >= this.#largestOutstandingMutationID) {
|
|
9001
|
+
this.#notifyAllMutationsAppliedListeners();
|
|
9002
|
+
}
|
|
9003
|
+
}
|
|
8931
9004
|
}
|
|
8932
9005
|
get size() {
|
|
8933
9006
|
return this.#outstandingMutations.size;
|
|
8934
9007
|
}
|
|
9008
|
+
/**
|
|
9009
|
+
* Push errors fall into two categories:
|
|
9010
|
+
* - Those where we know the mutations were not applied
|
|
9011
|
+
* - Those where we do not know the state of the mutations.
|
|
9012
|
+
*
|
|
9013
|
+
* The first category includes errors like "unsupportedPushVersion"
|
|
9014
|
+
* and "unsupportedSchemaVersion". The mutations were never applied in those cases.
|
|
9015
|
+
*
|
|
9016
|
+
* The second category includes errors like "http" errors. E.g., a 500 on the user's
|
|
9017
|
+
* API server or a network error.
|
|
9018
|
+
*
|
|
9019
|
+
* The mutations may have been applied by the API server but we never
|
|
9020
|
+
* received the response.
|
|
9021
|
+
*
|
|
9022
|
+
* In this latter case, we must mark the mutations as being in limbo.
|
|
9023
|
+
* This allows us to resolve them when we receive the next
|
|
9024
|
+
* lmid bump if their lmids are lesser.
|
|
9025
|
+
*/
|
|
8935
9026
|
#processPushError(error) {
|
|
8936
|
-
if (
|
|
9027
|
+
if (completeFailureTypes.includes(error.error)) {
|
|
8937
9028
|
return;
|
|
8938
9029
|
}
|
|
8939
9030
|
const mids = error.mutationIDs;
|
|
@@ -8941,7 +9032,30 @@ var MutationTracker = class {
|
|
|
8941
9032
|
return;
|
|
8942
9033
|
}
|
|
8943
9034
|
for (const mid of mids) {
|
|
8944
|
-
this.#
|
|
9035
|
+
const ephemeralID = this.#ephemeralIDsByMutationID.get(mid.id);
|
|
9036
|
+
if (ephemeralID) {
|
|
9037
|
+
if (mid.id <= this.#currentMutationID) {
|
|
9038
|
+
const entry = this.#outstandingMutations.get(ephemeralID);
|
|
9039
|
+
if (entry) {
|
|
9040
|
+
this.#settleMutation(ephemeralID, entry, "resolve", emptyObject);
|
|
9041
|
+
}
|
|
9042
|
+
continue;
|
|
9043
|
+
}
|
|
9044
|
+
this.#limboMutations.add(ephemeralID);
|
|
9045
|
+
}
|
|
9046
|
+
}
|
|
9047
|
+
}
|
|
9048
|
+
#resolveLimboMutations(lastMutationID) {
|
|
9049
|
+
for (const id of this.#limboMutations) {
|
|
9050
|
+
const entry = this.#outstandingMutations.get(id);
|
|
9051
|
+
if (!entry || !entry.mutationID) {
|
|
9052
|
+
this.#limboMutations.delete(id);
|
|
9053
|
+
continue;
|
|
9054
|
+
}
|
|
9055
|
+
if (entry.mutationID <= lastMutationID) {
|
|
9056
|
+
this.#limboMutations.delete(id);
|
|
9057
|
+
this.#settleMutation(id, entry, "resolve", emptyObject);
|
|
9058
|
+
}
|
|
8945
9059
|
}
|
|
8946
9060
|
}
|
|
8947
9061
|
#processPushOk(ok) {
|
|
@@ -8994,19 +9108,27 @@ var MutationTracker = class {
|
|
|
8994
9108
|
entry.resolver.reject(result);
|
|
8995
9109
|
break;
|
|
8996
9110
|
}
|
|
8997
|
-
|
|
9111
|
+
this.#outstandingMutations.delete(ephemeralID);
|
|
8998
9112
|
if (entry.mutationID) {
|
|
8999
9113
|
this.#ephemeralIDsByMutationID.delete(entry.mutationID);
|
|
9000
9114
|
}
|
|
9001
|
-
|
|
9002
|
-
this.#notifyAllMutationsConfirmedListeners();
|
|
9003
|
-
}
|
|
9115
|
+
this.#limboMutations.delete(ephemeralID);
|
|
9004
9116
|
}
|
|
9005
|
-
|
|
9006
|
-
|
|
9117
|
+
/**
|
|
9118
|
+
* Be notified when all mutations have been included in the server snapshot.
|
|
9119
|
+
*
|
|
9120
|
+
* The query manager will not de-register queries from the server until there
|
|
9121
|
+
* are no pending mutations.
|
|
9122
|
+
*
|
|
9123
|
+
* The reason is that a mutation may need to be rebased. We do not want
|
|
9124
|
+
* data that was available the first time it was run to not be available
|
|
9125
|
+
* on a rebase.
|
|
9126
|
+
*/
|
|
9127
|
+
onAllMutationsApplied(listener) {
|
|
9128
|
+
this.#allMutationsAppliedListeners.add(listener);
|
|
9007
9129
|
}
|
|
9008
|
-
#
|
|
9009
|
-
for (const listener of this.#
|
|
9130
|
+
#notifyAllMutationsAppliedListeners() {
|
|
9131
|
+
for (const listener of this.#allMutationsAppliedListeners) {
|
|
9010
9132
|
listener();
|
|
9011
9133
|
}
|
|
9012
9134
|
}
|
|
@@ -9039,7 +9161,7 @@ var QueryManager = class {
|
|
|
9039
9161
|
this.#send = send2;
|
|
9040
9162
|
this.#mutationTracker = mutationTracker;
|
|
9041
9163
|
this.#queryChangeThrottleMs = queryChangeThrottleMs;
|
|
9042
|
-
this.#mutationTracker.
|
|
9164
|
+
this.#mutationTracker.onAllMutationsApplied(() => {
|
|
9043
9165
|
if (this.#pendingRemovals.length === 0) {
|
|
9044
9166
|
return;
|
|
9045
9167
|
}
|
|
@@ -9112,6 +9234,8 @@ var QueryManager = class {
|
|
|
9112
9234
|
ast: normalized,
|
|
9113
9235
|
name,
|
|
9114
9236
|
args,
|
|
9237
|
+
// We get TTL out of the DagStore so it is possible that the TTL was written
|
|
9238
|
+
// with a too high TTL.
|
|
9115
9239
|
ttl: clampTTL(ttl)
|
|
9116
9240
|
// no lc here since no need to log here
|
|
9117
9241
|
});
|
|
@@ -9224,6 +9348,7 @@ var QueryManager = class {
|
|
|
9224
9348
|
this.#updateEntry(entry, astHash, ttl);
|
|
9225
9349
|
}
|
|
9226
9350
|
#updateEntry(entry, hash, ttl) {
|
|
9351
|
+
ttl = clampTTL(ttl, this.#lc);
|
|
9227
9352
|
if (compareTTL(ttl, entry.ttl) > 0) {
|
|
9228
9353
|
entry.ttl = ttl;
|
|
9229
9354
|
this.#queueQueryChange({
|
|
@@ -9232,7 +9357,7 @@ var QueryManager = class {
|
|
|
9232
9357
|
ast: entry.normalized,
|
|
9233
9358
|
name: entry.name,
|
|
9234
9359
|
args: entry.args,
|
|
9235
|
-
ttl
|
|
9360
|
+
ttl
|
|
9236
9361
|
});
|
|
9237
9362
|
}
|
|
9238
9363
|
}
|
|
@@ -10556,7 +10681,8 @@ var Zero = class _Zero {
|
|
|
10556
10681
|
// The clientSchema only needs to be sent for the very first request.
|
|
10557
10682
|
// Henceforth it is stored with the CVR and verified automatically.
|
|
10558
10683
|
...this.#connectCookie === null ? { clientSchema } : {},
|
|
10559
|
-
userPushParams: this.#options.push
|
|
10684
|
+
userPushParams: this.#options.mutate ?? this.#options.push,
|
|
10685
|
+
userQueryParams: this.#options.query
|
|
10560
10686
|
}
|
|
10561
10687
|
]);
|
|
10562
10688
|
this.#deletedClients = void 0;
|
|
@@ -10631,7 +10757,8 @@ var Zero = class _Zero {
|
|
|
10631
10757
|
wsid,
|
|
10632
10758
|
this.#options.logLevel === "debug",
|
|
10633
10759
|
lc,
|
|
10634
|
-
this.#options.push,
|
|
10760
|
+
this.#options.mutate ?? this.#options.push,
|
|
10761
|
+
this.#options.query,
|
|
10635
10762
|
this.#options.maxHeaderLength,
|
|
10636
10763
|
additionalConnectParams,
|
|
10637
10764
|
await this.#activeClientsManager
|
|
@@ -10735,6 +10862,7 @@ var Zero = class _Zero {
|
|
|
10735
10862
|
#handlePokeEnd(_lc, pokeMessage) {
|
|
10736
10863
|
this.#abortPingTimeout();
|
|
10737
10864
|
this.#pokeHandler.handlePokeEnd(pokeMessage[1]);
|
|
10865
|
+
this.#mutationTracker.lmidAdvanced(this.#lastMutationIDReceived);
|
|
10738
10866
|
}
|
|
10739
10867
|
#onPokeError() {
|
|
10740
10868
|
const lc = this.#lc;
|
|
@@ -11103,7 +11231,7 @@ var Zero = class _Zero {
|
|
|
11103
11231
|
*/
|
|
11104
11232
|
async inspect() {
|
|
11105
11233
|
BUNDLE_SIZE: {
|
|
11106
|
-
const m = await import("./inspector-
|
|
11234
|
+
const m = await import("./inspector-TFZBDN6K.js");
|
|
11107
11235
|
return m.newInspector(this.#rep, this.#schema, async () => {
|
|
11108
11236
|
await this.#connectResolver.promise;
|
|
11109
11237
|
return this.#socket;
|
|
@@ -11111,7 +11239,7 @@ var Zero = class _Zero {
|
|
|
11111
11239
|
}
|
|
11112
11240
|
}
|
|
11113
11241
|
};
|
|
11114
|
-
async function createSocket(rep, queryManager, deleteClientsManager, socketOrigin, baseCookie, clientID, clientGroupID, clientSchema, userID, auth, lmid, wsid, debugPerf, lc, userPushParams, maxHeaderLength = 1024 * 8, additionalConnectParams, activeClientsManager) {
|
|
11242
|
+
async function createSocket(rep, queryManager, deleteClientsManager, socketOrigin, baseCookie, clientID, clientGroupID, clientSchema, userID, auth, lmid, wsid, debugPerf, lc, userPushParams, userQueryParams, maxHeaderLength = 1024 * 8, additionalConnectParams, activeClientsManager) {
|
|
11115
11243
|
const url = new URL(
|
|
11116
11244
|
appendPath(socketOrigin, `/sync/v${PROTOCOL_VERSION}/connect`)
|
|
11117
11245
|
);
|
|
@@ -11151,6 +11279,7 @@ async function createSocket(rep, queryManager, deleteClientsManager, socketOrigi
|
|
|
11151
11279
|
// Henceforth it is stored with the CVR and verified automatically.
|
|
11152
11280
|
...baseCookie === null ? { clientSchema } : {},
|
|
11153
11281
|
userPushParams,
|
|
11282
|
+
userQueryParams,
|
|
11154
11283
|
activeClients: [...activeClients]
|
|
11155
11284
|
}
|
|
11156
11285
|
],
|
|
@@ -11230,6 +11359,7 @@ export {
|
|
|
11230
11359
|
dropDatabase,
|
|
11231
11360
|
dropAllDatabases,
|
|
11232
11361
|
error_kind_enum_exports,
|
|
11362
|
+
mapEntries,
|
|
11233
11363
|
table,
|
|
11234
11364
|
string3 as string,
|
|
11235
11365
|
number2 as number,
|
|
@@ -11241,4 +11371,4 @@ export {
|
|
|
11241
11371
|
update_needed_reason_type_enum_exports,
|
|
11242
11372
|
Zero
|
|
11243
11373
|
};
|
|
11244
|
-
//# sourceMappingURL=chunk-
|
|
11374
|
+
//# sourceMappingURL=chunk-IQCMHXK7.js.map
|