@gonvex/protocol 0.1.32 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +1 -1
  2. package/dist/index.d.ts +232 -105
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -30,7 +30,7 @@ The package includes:
30
30
  - function manifest types
31
31
  - WebSocket client and server message unions
32
32
  - live-query result, progress, patch, and revision frames
33
- - durable sync open/batch-open, snapshot, delta, reset, ready, and cursor types
33
+ - Replica Collection open/batch-open, snapshot, delta, reset, ready, and cursor types
34
34
  - browser telemetry and message trace types
35
35
 
36
36
  ## Related Packages
package/dist/index.d.ts CHANGED
@@ -1,15 +1,72 @@
1
- export type FunctionKind = "query" | "mutation" | "action" | "http" | "internalMutation" | "liveGrid" | "sync";
1
+ export type FunctionKind = "query" | "reducer" | "action";
2
+ export type ExecutionScope = "tenant" | "control";
2
3
  export type JsonValue = null | boolean | number | string | JsonValue[] | {
3
4
  [key: string]: JsonValue;
4
5
  };
6
+ /** The recursive, language-neutral value schema used by TypeScript modules. */
7
+ export type ModuleSchema = StringSchema | NumberSchema | BooleanSchema | NullSchema | AnySchema | IdSchema | LiteralSchema | ArraySchema | ObjectSchema | RecordSchema | OptionalSchema;
8
+ export type StringSchema = {
9
+ kind: "string";
10
+ format?: "email" | "uri" | "uuid" | "datetime";
11
+ minLength?: number;
12
+ maxLength?: number;
13
+ };
14
+ export type NumberSchema = {
15
+ kind: "number";
16
+ integer?: boolean;
17
+ minimum?: number;
18
+ maximum?: number;
19
+ };
20
+ export type BooleanSchema = {
21
+ kind: "boolean";
22
+ };
23
+ export type NullSchema = {
24
+ kind: "null";
25
+ };
26
+ export type AnySchema = {
27
+ kind: "any";
28
+ };
29
+ export type IdSchema = {
30
+ kind: "id";
31
+ entity: string;
32
+ };
33
+ export type LiteralSchema = {
34
+ kind: "literal";
35
+ value: JsonValue;
36
+ };
37
+ export type ArraySchema = {
38
+ kind: "array";
39
+ items: ModuleSchema;
40
+ };
41
+ export type ObjectSchema = {
42
+ kind: "object";
43
+ fields: Record<string, ModuleSchema>;
44
+ allowUnknown?: boolean;
45
+ };
46
+ export type RecordSchema = {
47
+ kind: "record";
48
+ values: ModuleSchema;
49
+ };
50
+ export type OptionalSchema = {
51
+ kind: "optional";
52
+ value: ModuleSchema;
53
+ };
5
54
  export type FunctionManifestEntry = {
6
55
  kind: FunctionKind;
7
56
  handler: string;
8
57
  file: string;
58
+ args?: ModuleSchema;
59
+ result?: ModuleSchema;
60
+ internal?: boolean;
61
+ delivery?: "oneShot" | "live" | "replica";
9
62
  dependencies?: FunctionDependencies;
10
- sync?: SyncDefinition;
63
+ replica?: ReplicaCollectionDefinition;
64
+ /** Reducer delivery policy declared by a TypeScript module. */
65
+ offline?: JsonValue;
66
+ /** Ordered atomic optimistic transaction declared by a TypeScript module. */
67
+ optimistic?: JsonValue;
11
68
  };
12
- export type SyncDefinition = {
69
+ export type ReplicaCollectionDefinition = {
13
70
  table: string;
14
71
  key: string;
15
72
  columns: string[];
@@ -23,30 +80,68 @@ export type SyncDefinition = {
23
80
  maxBytes?: number;
24
81
  retentionMs?: number;
25
82
  };
26
- export type SyncCursor = {
83
+ export type ReplicaCursor = {
27
84
  epoch: string;
28
85
  revision: number;
29
86
  };
87
+ export type ReplicaChange = {
88
+ entity: string;
89
+ id: string;
90
+ operation: "insert" | "update" | "delete";
91
+ oldValue?: JsonValue;
92
+ newValue?: JsonValue;
93
+ changedColumns?: string[];
94
+ };
30
95
  export type FunctionDependencies = {
31
- reads?: Array<{
32
- table: string;
33
- columns?: string[];
34
- filters?: string[];
35
- ordersBy?: string[];
36
- windowed?: boolean;
37
- predicate?: string;
38
- }>;
39
- writes?: Array<{
40
- table: string;
41
- columns?: string[];
42
- }>;
43
- readsEphemeral?: boolean;
44
- writesEphemeral?: boolean;
45
96
  shareByPermissions?: boolean;
46
- shareByVisibility?: string;
97
+ liveQueryPlan?: LiveQueryPlan;
98
+ nonOptimisticReason?: string;
47
99
  shareResultFrom?: string;
48
100
  shareResultField?: string;
49
101
  };
102
+ export type LiveQueryPlan = {
103
+ table: string;
104
+ key: string;
105
+ columns?: string[];
106
+ resultPath?: string[];
107
+ where?: LiveExpression;
108
+ search?: {
109
+ argument: string;
110
+ columns: string[];
111
+ };
112
+ filters?: {
113
+ argument: string;
114
+ allowedColumns: string[];
115
+ allowedOperators: FilterOperator[];
116
+ };
117
+ sort?: {
118
+ columnArgument: string;
119
+ directionArgument: string;
120
+ defaultColumn: string;
121
+ defaultDirection: "asc" | "desc";
122
+ allowedColumns: string[];
123
+ };
124
+ window?: {
125
+ offsetArgument: string;
126
+ limitArgument: string;
127
+ defaultLimit: number;
128
+ maxLimit: number;
129
+ count?: "exact";
130
+ };
131
+ serverOnly?: boolean;
132
+ };
133
+ export type FilterOperator = "contains" | "notContains" | "equals" | "notEquals" | "startsWith" | "endsWith" | "empty" | "notEmpty" | "oneOf" | "lessThan" | "lessThanOrEqual" | "greaterThan" | "greaterThanOrEqual" | "inRange";
134
+ export type LiveExpression = {
135
+ operator: "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "in" | "contains" | "containsInsensitive" | "range" | "and" | "or" | "not" | "server";
136
+ column?: string;
137
+ value?: LiveValue;
138
+ valueTo?: LiveValue;
139
+ children?: LiveExpression[];
140
+ };
141
+ export type LiveValue = {
142
+ argument?: string;
143
+ literal?: JsonValue;
144
+ };
50
145
  export type SubscriptionRevision = {
51
146
  epoch: string;
52
147
  sequence: number;
@@ -54,8 +149,8 @@ export type SubscriptionRevision = {
54
149
  export type MessageTrace = {
55
150
  clientSentAtMs?: number;
56
151
  serverReceivedAtMs?: number;
57
- serverMutationStartedAtMs?: number;
58
- serverMutationCommittedAtMs?: number;
152
+ serverReducerStartedAtMs?: number;
153
+ serverReducerCommittedAtMs?: number;
59
154
  serverCompletedAtMs?: number;
60
155
  serverBroadcastScheduledAtMs?: number;
61
156
  serverChangeCommittedAtMs?: number;
@@ -81,73 +176,69 @@ export type BrowserTelemetryInfo = {
81
176
  connectionType?: string;
82
177
  effectiveConnectionType?: string;
83
178
  };
84
- export type QueryCacheDirective = {
179
+ export type ReplicaDirective = {
85
180
  protocolVersion: 1;
86
181
  scope: string;
87
- /**
88
- * Visibility-only scope (project/tenant/user/permissions, no code epoch)
89
- * under which sync collections are persisted and resumed. Unlike `scope`,
90
- * it survives deploys; resume safety comes from the server's authoritative
91
- * reconcile. Absent on runtimes that predate deploy-stable sync scopes.
92
- */
93
- syncScope?: string;
182
+ /** Visibility-only scope for persistent, authoritatively reconciled rows. */
183
+ visibilityScope: string;
94
184
  epoch: string;
95
- maxAgeMs: number;
96
185
  };
97
186
  export type ServerCapabilities = {
98
187
  /** WebSocket protocol generation implemented by this runtime. */
99
188
  protocolVersion?: number;
100
189
  /** Exact runtime build identifier, normally the deployed Git commit SHA. */
101
190
  runtimeVersion?: string;
102
- syncBatch?: 1;
103
- /** sync.ready frames always carry a collection integrity digest. */
104
- syncIntegrity?: 1;
191
+ replicaBatch?: 1;
192
+ /** replica.ready frames always carry a collection integrity digest. */
193
+ replicaIntegrity?: 1;
105
194
  /** Server accepts `query.subscribeMany` batched subscription frames. */
106
195
  queryBatch?: 1;
107
196
  /** Server emits several independent query updates in one WebSocket frame. */
108
197
  queryResultBatch?: 1;
109
- /** Server accepts `mutation.callMany` batched offline-queue flushes. */
110
- mutationBatch?: 1;
111
- /** Server emits connection-level sync revision watermarks. */
112
- syncWatermark?: 1;
198
+ /** Server accepts `reducer.callMany` batched command-outbox flushes. */
199
+ reducerBatch?: 1;
200
+ /** Server emits connection-level replica revision watermarks. */
201
+ replicaWatermark?: 1;
113
202
  };
114
203
  export type QuerySubscribeRequest = {
115
204
  id: string;
116
205
  path: string;
117
206
  args: JsonValue;
118
- cacheRevision?: string;
207
+ scope?: ExecutionScope;
208
+ windowRevision?: string;
119
209
  };
120
- export type MutationCallRequest = {
210
+ export type ReducerCallRequest = {
121
211
  id: string;
122
212
  path: string;
123
213
  args: JsonValue;
214
+ scope?: ExecutionScope;
124
215
  trace?: MessageTrace;
125
- /** Stable key for a replayable write; see the `mutation.call` message. */
216
+ /** Stable key for a replayable command; see the `reducer.call` message. */
126
217
  idempotencyKey?: string;
127
218
  };
128
- export type SyncOpenRequest = {
219
+ export type ReplicaOpenRequest = {
129
220
  id: string;
130
221
  path: string;
131
222
  args: JsonValue;
132
- cursor?: SyncCursor;
223
+ cursor?: ReplicaCursor;
133
224
  keys?: string[];
134
225
  hashes?: Record<string, string>;
135
226
  digest?: string;
136
227
  fullIntegrity?: boolean;
137
228
  };
138
- export type SyncReady = {
229
+ export type ReplicaReady = {
139
230
  id: string;
140
231
  path?: string;
141
- cursor: SyncCursor;
232
+ cursor: ReplicaCursor;
142
233
  mode?: "eager" | "progressive";
143
- digest?: string;
234
+ digest: string;
144
235
  truncated?: boolean;
145
236
  };
146
237
  export type ClientCapabilities = {
147
- /** Client accepts coalesced `sync.readyMany` server frames. */
148
- syncReadyMany?: 1;
149
- /** Client accepts connection-level `sync.watermark` server frames. */
150
- syncWatermark?: 1;
238
+ /** Client accepts coalesced `replica.readyMany` server frames. */
239
+ replicaReadyMany?: 1;
240
+ /** Client accepts connection-level `replica.watermark` server frames. */
241
+ replicaWatermark?: 1;
151
242
  /** Client accepts keyed patches for object results with a `page` row array. */
152
243
  queryPagePatch?: 1;
153
244
  /** Client atomically applies keyed patches to named arrays in object results. */
@@ -179,63 +270,86 @@ export type ClientMessage = {
179
270
  token?: string;
180
271
  project?: string;
181
272
  tenant?: string;
273
+ controlOnly?: boolean;
182
274
  device?: BrowserTelemetryInfo;
183
275
  capabilities?: ClientCapabilities;
276
+ } | {
277
+ type: "query.call";
278
+ id: string;
279
+ path: string;
280
+ args: JsonValue;
281
+ scope?: ExecutionScope;
184
282
  } | {
185
283
  type: "query.subscribe";
186
284
  id: string;
187
285
  path: string;
188
286
  args: JsonValue;
189
- cacheRevision?: string;
287
+ scope?: ExecutionScope;
288
+ windowRevision?: string;
190
289
  } | {
191
290
  type: "query.unsubscribe";
192
291
  id: string;
193
292
  } | {
194
- type: "sync.open";
293
+ type: "replica.open";
195
294
  id: string;
196
295
  path: string;
197
296
  args: JsonValue;
198
- cursor?: SyncCursor;
297
+ cursor?: ReplicaCursor;
199
298
  keys?: string[];
200
299
  hashes?: Record<string, string>;
201
300
  digest?: string;
202
301
  fullIntegrity?: boolean;
203
302
  } | {
204
- type: "sync.openMany";
205
- opens: SyncOpenRequest[];
303
+ type: "replica.openMany";
304
+ opens: ReplicaOpenRequest[];
206
305
  } | {
207
306
  type: "query.subscribeMany";
208
307
  subscribes: QuerySubscribeRequest[];
209
308
  } | {
210
- type: "sync.close";
309
+ type: "replica.close";
211
310
  id: string;
212
311
  } | {
213
- type: "mutation.call";
312
+ type: "reducer.call";
214
313
  id: string;
215
314
  path: string;
216
315
  args: JsonValue;
316
+ scope?: ExecutionScope;
217
317
  trace?: MessageTrace;
218
318
  /**
219
- * Stable key for a replayable write from the client outbox. The runtime
220
- * executes the mutation once per key and serves the stored result to
319
+ * Stable key for a replayable command from the client outbox. The runtime
320
+ * executes the reducer once per key and serves the stored result to
221
321
  * every duplicate delivery.
222
322
  */
223
323
  idempotencyKey?: string;
224
324
  } | {
225
- type: "mutation.callMany";
226
- calls: MutationCallRequest[];
325
+ type: "reducer.callMany";
326
+ calls: ReducerCallRequest[];
227
327
  } | {
228
328
  type: "action.call";
229
329
  id: string;
230
330
  path: string;
231
331
  args: JsonValue;
332
+ scope?: ExecutionScope;
333
+ idempotencyKey?: string;
232
334
  trace?: MessageTrace;
335
+ } | {
336
+ type: "error.register";
337
+ id: string;
338
+ release?: string;
339
+ environment?: string;
340
+ } | {
341
+ type: "error.envelope";
342
+ id: string;
343
+ events: JsonValue[];
344
+ } | {
345
+ type: "error.heartbeat";
346
+ id: string;
233
347
  } | {
234
348
  type: "telemetry.event";
235
349
  id: string;
236
- kind: "query" | "mutation" | "action";
350
+ kind: "query" | "reducer" | "action";
237
351
  path: string;
238
- reason?: "initial" | "invalidate" | "recover";
352
+ reason?: "initial" | "change" | "recover";
239
353
  outcome: "ok" | "error";
240
354
  error?: string;
241
355
  clientSentAtMs?: number;
@@ -253,10 +367,10 @@ export type ServerMessage = {
253
367
  ids: string[];
254
368
  path?: string;
255
369
  result?: JsonValue;
256
- reason?: "initial" | "invalidate" | "recover";
370
+ reason?: "initial" | "change" | "recover";
257
371
  trace?: MessageTrace;
258
- cacheScope?: string;
259
- cacheRevision?: string;
372
+ replicaScope?: string;
373
+ windowRevision?: string;
260
374
  subscriptionRevision?: SubscriptionRevision;
261
375
  baseRevision?: SubscriptionRevision;
262
376
  throughRevision?: SubscriptionRevision;
@@ -267,16 +381,18 @@ export type ServerMessage = {
267
381
  prepend?: string[];
268
382
  append?: string[];
269
383
  collections?: Record<string, KeyedCollectionPatch>;
270
- mutationIds?: string[];
384
+ originCommandIds?: string[];
385
+ } | {
386
+ type: "replica.transaction";
387
+ cursor: ReplicaCursor;
388
+ originCommandId?: string;
389
+ changes: ReplicaChange[];
271
390
  } | {
272
391
  type: "session.ready";
273
392
  project?: string;
274
393
  tenant?: string;
275
- queryCache?: QueryCacheDirective;
394
+ replica?: ReplicaDirective;
276
395
  capabilities?: ServerCapabilities;
277
- } | {
278
- type: "session.scope";
279
- queryCache?: QueryCacheDirective;
280
396
  } | {
281
397
  type: "auth.result";
282
398
  id: string;
@@ -285,30 +401,40 @@ export type ServerMessage = {
285
401
  type: "auth.error";
286
402
  id: string;
287
403
  error: string;
404
+ } | {
405
+ type: "error.ack";
406
+ id: string;
407
+ accepted?: number;
408
+ fingerprints?: string[];
409
+ error?: string;
410
+ } | {
411
+ type: "support.command";
412
+ id: string;
413
+ result: JsonValue;
288
414
  } | {
289
415
  type: "query.result";
290
416
  id: string;
291
417
  path?: string;
292
418
  result: JsonValue;
293
- reason?: "initial" | "invalidate" | "recover";
419
+ reason?: "initial" | "change" | "recover";
294
420
  trace?: MessageTrace;
295
- cacheScope?: string;
296
- cacheRevision?: string;
421
+ replicaScope?: string;
422
+ windowRevision?: string;
297
423
  subscriptionRevision?: SubscriptionRevision;
298
- mutationIds?: string[];
424
+ originCommandIds?: string[];
299
425
  } | {
300
426
  type: "query.progress";
301
427
  id: string;
302
428
  path?: string;
303
- reason?: "initial" | "invalidate" | "recover";
429
+ reason?: "initial" | "change" | "recover";
304
430
  throughRevision: SubscriptionRevision;
305
431
  trace?: MessageTrace;
306
- mutationIds?: string[];
432
+ originCommandIds?: string[];
307
433
  } | {
308
434
  type: "query.patch";
309
435
  id: string;
310
436
  path?: string;
311
- reason?: "initial" | "invalidate" | "recover";
437
+ reason?: "initial" | "change" | "recover";
312
438
  baseRevision: SubscriptionRevision;
313
439
  subscriptionRevision: SubscriptionRevision;
314
440
  inserted?: JsonValue[];
@@ -317,15 +443,15 @@ export type ServerMessage = {
317
443
  order?: string[];
318
444
  prepend?: string[];
319
445
  append?: string[];
320
- cacheScope?: string;
321
- cacheRevision?: string;
446
+ replicaScope?: string;
447
+ windowRevision?: string;
322
448
  trace?: MessageTrace;
323
- mutationIds?: string[];
449
+ originCommandIds?: string[];
324
450
  } | {
325
451
  type: "query.pagePatch";
326
452
  id: string;
327
453
  path?: string;
328
- reason?: "initial" | "invalidate" | "recover";
454
+ reason?: "initial" | "change" | "recover";
329
455
  baseRevision: SubscriptionRevision;
330
456
  subscriptionRevision: SubscriptionRevision;
331
457
  result?: JsonValue;
@@ -335,28 +461,28 @@ export type ServerMessage = {
335
461
  order?: string[];
336
462
  prepend?: string[];
337
463
  append?: string[];
338
- cacheScope?: string;
339
- cacheRevision?: string;
464
+ replicaScope?: string;
465
+ windowRevision?: string;
340
466
  trace?: MessageTrace;
341
- mutationIds?: string[];
467
+ originCommandIds?: string[];
342
468
  } | {
343
469
  type: "query.objectPatch";
344
470
  id: string;
345
471
  path?: string;
346
- reason?: "initial" | "invalidate" | "recover";
472
+ reason?: "initial" | "change" | "recover";
347
473
  baseRevision: SubscriptionRevision;
348
474
  subscriptionRevision: SubscriptionRevision;
349
475
  collections: Record<string, KeyedCollectionPatch>;
350
- cacheScope?: string;
351
- cacheRevision?: string;
476
+ replicaScope?: string;
477
+ windowRevision?: string;
352
478
  trace?: MessageTrace;
353
- mutationIds?: string[];
479
+ originCommandIds?: string[];
354
480
  } | {
355
- type: "sync.snapshot";
481
+ type: "replica.snapshot";
356
482
  id: string;
357
483
  path?: string;
358
484
  result: JsonValue[];
359
- cursor: SyncCursor;
485
+ cursor: ReplicaCursor;
360
486
  key: string;
361
487
  orderBy?: string;
362
488
  orderDirection?: "asc" | "desc";
@@ -365,40 +491,39 @@ export type ServerMessage = {
365
491
  maxBytes?: number;
366
492
  hashes?: Record<string, string>;
367
493
  } | {
368
- type: "sync.delta";
494
+ type: "replica.delta";
369
495
  id: string;
370
496
  path?: string;
371
- cursor: SyncCursor;
497
+ cursor: ReplicaCursor;
372
498
  upserts?: JsonValue[];
373
499
  deleted?: string[];
374
- mutationIds?: string[];
500
+ originCommandIds?: string[];
375
501
  hashes?: Record<string, string>;
376
502
  digest?: string;
377
503
  } | ({
378
- type: "sync.ready";
379
- digest?: string;
380
- } & SyncReady) | {
381
- type: "sync.readyMany";
382
- ready: SyncReady[];
504
+ type: "replica.ready";
505
+ } & ReplicaReady) | {
506
+ type: "replica.readyMany";
507
+ ready: ReplicaReady[];
383
508
  } | {
384
- type: "sync.watermark";
509
+ type: "replica.watermark";
385
510
  revision: number;
386
511
  } | {
387
- type: "sync.needHashes";
512
+ type: "replica.needHashes";
388
513
  id: string;
389
514
  path?: string;
390
515
  } | {
391
- type: "sync.syncing";
516
+ type: "replica.syncing";
392
517
  id: string;
393
518
  path?: string;
394
519
  reason: "disconnected" | "reconciling" | "listener-reconnecting" | "integrity-reconciling";
395
520
  } | {
396
- type: "sync.reset";
521
+ type: "replica.reset";
397
522
  id: string;
398
523
  path?: string;
399
524
  reason: "cursor-expired" | "definition-changed" | "visibility-changed" | "integrity-mismatch" | "integrity-missing" | "recover";
400
525
  } | {
401
- type: "sync.error";
526
+ type: "replica.error";
402
527
  id: string;
403
528
  path?: string;
404
529
  error: string;
@@ -408,13 +533,15 @@ export type ServerMessage = {
408
533
  path?: string;
409
534
  error: string;
410
535
  } | {
411
- type: "mutation.result";
536
+ type: "reducer.result";
412
537
  id: string;
413
538
  path?: string;
414
539
  result: JsonValue;
540
+ originCommandId: string;
541
+ committedRevision?: number;
415
542
  trace?: MessageTrace;
416
543
  } | {
417
- type: "mutation.error";
544
+ type: "reducer.error";
418
545
  id: string;
419
546
  path?: string;
420
547
  error: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gonvex/protocol",
3
- "version": "0.1.32",
3
+ "version": "0.3.1",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public"