@gaganref/confect-test 10.3.1-fork.91 → 10.3.1-fork.93

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 (51) hide show
  1. package/dist/TestConfect.d.ts +26 -0
  2. package/dist/TestConfect.d.ts.map +1 -1
  3. package/dist/TestConfect.js +9 -1
  4. package/dist/TestConfect.js.map +1 -1
  5. package/dist/internal/Attempt.d.ts +14 -1
  6. package/dist/internal/Attempt.d.ts.map +1 -1
  7. package/dist/internal/Attempt.js +18 -1
  8. package/dist/internal/Attempt.js.map +1 -1
  9. package/dist/internal/ConvexTest.d.ts +26 -1
  10. package/dist/internal/ConvexTest.d.ts.map +1 -1
  11. package/dist/internal/ConvexTest.js +55 -27
  12. package/dist/internal/ConvexTest.js.map +1 -1
  13. package/dist/internal/Execution.d.ts +151 -1
  14. package/dist/internal/Execution.d.ts.map +1 -1
  15. package/dist/internal/Execution.js +731 -214
  16. package/dist/internal/Execution.js.map +1 -1
  17. package/dist/internal/KernelQuery.d.ts +8 -3
  18. package/dist/internal/KernelQuery.d.ts.map +1 -1
  19. package/dist/internal/KernelQuery.js +10 -3
  20. package/dist/internal/KernelQuery.js.map +1 -1
  21. package/dist/internal/KernelRefusal.d.ts +134 -0
  22. package/dist/internal/KernelRefusal.d.ts.map +1 -1
  23. package/dist/internal/KernelRefusal.js +134 -1
  24. package/dist/internal/KernelRefusal.js.map +1 -1
  25. package/dist/internal/Metering.d.ts +186 -0
  26. package/dist/internal/Metering.d.ts.map +1 -0
  27. package/dist/internal/Metering.js +401 -0
  28. package/dist/internal/Metering.js.map +1 -0
  29. package/dist/internal/Redaction.d.ts +142 -0
  30. package/dist/internal/Redaction.d.ts.map +1 -0
  31. package/dist/internal/Redaction.js +448 -0
  32. package/dist/internal/Redaction.js.map +1 -0
  33. package/dist/internal/Snapshot.d.ts +298 -0
  34. package/dist/internal/Snapshot.d.ts.map +1 -0
  35. package/dist/internal/Snapshot.js +532 -0
  36. package/dist/internal/Snapshot.js.map +1 -0
  37. package/dist/internal/Subscriptions.d.ts +13 -0
  38. package/dist/internal/Subscriptions.d.ts.map +1 -1
  39. package/dist/internal/Subscriptions.js +27 -3
  40. package/dist/internal/Subscriptions.js.map +1 -1
  41. package/package.json +3 -3
  42. package/src/TestConfect.ts +63 -4
  43. package/src/internal/Attempt.ts +24 -0
  44. package/src/internal/ConvexTest.ts +135 -38
  45. package/src/internal/Execution.ts +1141 -324
  46. package/src/internal/KernelQuery.ts +17 -6
  47. package/src/internal/KernelRefusal.ts +160 -0
  48. package/src/internal/Metering.ts +520 -0
  49. package/src/internal/Redaction.ts +730 -0
  50. package/src/internal/Snapshot.ts +945 -0
  51. package/src/internal/Subscriptions.ts +34 -4
@@ -99,17 +99,19 @@ export const validateDocument = (
99
99
  };
100
100
 
101
101
  /**
102
- * An interval a query reads, before it says where it starts and how far it got.
102
+ * An interval a query reads, before it says where it starts and how far it got,
103
+ * and the index it reads it from.
103
104
  */
104
105
  export type Interval = Omit<
105
106
  ReadSet.IntervalRead,
106
107
  "componentPath" | "after" | "through"
107
- >;
108
+ > & { readonly index: string };
108
109
 
109
110
  /**
110
111
  * What a query reads: one table of one component, as the running attempt sees
111
112
  * it. `read` records an interval in the attempt's read set and returns how to
112
- * advance it.
113
+ * advance it. `examine` charges one document the query examined, before the
114
+ * query's filters see it.
113
115
  */
114
116
  export interface TableView {
115
117
  readonly schema: KernelSchema | null;
@@ -118,6 +120,7 @@ export interface TableView {
118
120
  interval: Interval,
119
121
  after: ReadSet.Key | null,
120
122
  ) => (through: ReadSet.Key | "end") => void;
123
+ readonly examine: (table: string, doc: GenericDocument) => void;
121
124
  }
122
125
 
123
126
  interface ResolvedSource {
@@ -138,9 +141,12 @@ const resolveSource = (
138
141
  let order: "asc" | "desc";
139
142
  let table: string;
140
143
  let range: ReadonlyArray<SerializedRangeExpression> = [];
144
+ let index: string;
141
145
  switch (source.type) {
142
146
  case "FullTableScan": {
143
147
  table = source.tableName;
148
+ // The binary scans a whole table through its creation-time index.
149
+ index = "by_creation_time";
144
150
  docs = [...view.scan(source.tableName)];
145
151
  order = source.order ?? "asc";
146
152
  fieldPathsToSortBy = ["_creationTime"];
@@ -152,6 +158,7 @@ const resolveSource = (
152
158
  string,
153
159
  ];
154
160
  table = tableName;
161
+ index = indexName;
155
162
  range = source.range;
156
163
  order = source.order ?? "asc";
157
164
  let fields: Array<string>;
@@ -160,18 +167,18 @@ const resolveSource = (
160
167
  } else if (indexName === "by_id") {
161
168
  fields = ["_id"];
162
169
  } else {
163
- const index = view.schema?.tables
170
+ const declared = view.schema?.tables
164
171
  .get(tableName)
165
172
  ?.indexes.find(
166
173
  ({ indexDescriptor }) => indexDescriptor === indexName,
167
174
  );
168
- if (index === undefined) {
175
+ if (declared === undefined) {
169
176
  throw new Error(
170
177
  `Cannot use index "${indexName}" for table "${tableName}" because ` +
171
178
  `it is not declared in the schema.`,
172
179
  );
173
180
  }
174
- fields = index.fields.concat(["_creationTime", "_id"]);
181
+ fields = declared.fields.concat(["_creationTime", "_id"]);
175
182
  }
176
183
  fieldPathsToSortBy = fields;
177
184
  validateIndexRangeExpression(source, fields);
@@ -216,6 +223,7 @@ const resolveSource = (
216
223
  order,
217
224
  interval: {
218
225
  kind: "interval",
226
+ index,
219
227
  table,
220
228
  fields: fieldPathsToSortBy.includes("_id")
221
229
  ? fieldPathsToSortBy
@@ -241,6 +249,7 @@ export const stream = (
241
249
  let returned = 0;
242
250
  for (const doc of sortedDocs) {
243
251
  if (limit !== null && returned >= limit) return;
252
+ view.examine(interval.table, doc);
244
253
  examined(ReadSet.keyOf(interval.fields, doc as StoredDocument));
245
254
  if (filterFn(doc)) {
246
255
  returned++;
@@ -352,6 +361,7 @@ export const paginate = (
352
361
  reachedEnd = false;
353
362
  examined(endCursorKeys);
354
363
  if (cmp === 0) {
364
+ view.examine(interval.table, doc);
355
365
  rowsRead += 1;
356
366
  bytesRead += getDocumentSize(doc);
357
367
  readDocCursors.push(encodeCursor(doc, cursorFields));
@@ -361,6 +371,7 @@ export const paginate = (
361
371
  break;
362
372
  }
363
373
  }
374
+ view.examine(interval.table, doc);
364
375
  rowsRead += 1;
365
376
  bytesRead += getDocumentSize(doc);
366
377
  readDocCursors.push(encodeCursor(doc, cursorFields));
@@ -110,3 +110,163 @@ export const rowPending = (operation: string, row: number) =>
110
110
  row,
111
111
  message: `The test kernel supplies ${operation} in build-order row ${row}.`,
112
112
  });
113
+
114
+ /**
115
+ * Snapshot bytes are not a kernel snapshot this kernel reads: an unknown
116
+ * header, a body that is not the snapshot's JSON, or a value that does not
117
+ * decode.
118
+ */
119
+ export class SnapshotMalformed extends Schema.TaggedError<SnapshotMalformed>()(
120
+ "SnapshotMalformed",
121
+ { reason: Schema.String, message: Schema.String },
122
+ ) {}
123
+
124
+ /**
125
+ * A snapshot's body does not hash to the digest its header names, so its bytes
126
+ * changed after export.
127
+ */
128
+ export class SnapshotDigestMismatch extends Schema.TaggedError<SnapshotDigestMismatch>()(
129
+ "SnapshotDigestMismatch",
130
+ { expected: Schema.String, actual: Schema.String, message: Schema.String },
131
+ ) {}
132
+
133
+ /**
134
+ * A snapshot's components are not the components registered on the world
135
+ * restoring it.
136
+ */
137
+ export class SnapshotComponentMismatch extends Schema.TaggedError<SnapshotComponentMismatch>()(
138
+ "SnapshotComponentMismatch",
139
+ {
140
+ snapshot: Schema.Array(Schema.String),
141
+ registered: Schema.Array(Schema.String),
142
+ message: Schema.String,
143
+ },
144
+ ) {}
145
+
146
+ /**
147
+ * A job's test world is named by no world, or by more than one, so the job
148
+ * could not run under the world that scheduled it.
149
+ */
150
+ export class SnapshotWorldUnresolved extends Schema.TaggedError<SnapshotWorldUnresolved>()(
151
+ "SnapshotWorldUnresolved",
152
+ {
153
+ name: Schema.String,
154
+ reason: Schema.Literals(["missing", "ambiguous"]),
155
+ message: Schema.String,
156
+ },
157
+ ) {}
158
+
159
+ /**
160
+ * A world holds work a snapshot does not carry: attempts held for `apply`, or,
161
+ * when it restores, commits of its own.
162
+ */
163
+ export class SnapshotWorldBusy extends Schema.TaggedError<SnapshotWorldBusy>()(
164
+ "SnapshotWorldBusy",
165
+ {
166
+ version: Schema.Int,
167
+ held: Schema.Array(Schema.String),
168
+ message: Schema.String,
169
+ },
170
+ ) {}
171
+
172
+ /**
173
+ * A snapshot marks a secret the restore was not given, so the raw value its
174
+ * replay needs is not in memory.
175
+ */
176
+ export class SnapshotSecretMissing extends Schema.TaggedError<SnapshotSecretMissing>()(
177
+ "SnapshotSecretMissing",
178
+ { ref: Schema.String, message: Schema.String },
179
+ ) {}
180
+
181
+ /**
182
+ * A world is running work a snapshot taken or restored now would split: calls
183
+ * from the test, scheduler walks, or function executions, nested and detached
184
+ * ones included.
185
+ */
186
+ export class SnapshotWorldRunning extends Schema.TaggedError<SnapshotWorldRunning>()(
187
+ "SnapshotWorldRunning",
188
+ {
189
+ registry: Schema.Literals(["running", "walks", "functions"]),
190
+ count: Schema.Int,
191
+ message: Schema.String,
192
+ },
193
+ ) {}
194
+
195
+ /**
196
+ * A world has subscribers, whose identity versions a restore would rewind.
197
+ * Subscriptions are live client state, so a restore needs a world with none.
198
+ */
199
+ export class SnapshotSubscribed extends Schema.TaggedError<SnapshotSubscribed>()(
200
+ "SnapshotSubscribed",
201
+ { subscribers: Schema.Int, message: Schema.String },
202
+ ) {}
203
+
204
+ /**
205
+ * A snapshot's identity counters stand at or behind an identity its state
206
+ * already holds, so the next allocation would reuse one.
207
+ */
208
+ export class SnapshotAllocatorBehind extends Schema.TaggedError<SnapshotAllocatorBehind>()(
209
+ "SnapshotAllocatorBehind",
210
+ {
211
+ allocator: Schema.Literals([
212
+ "nextDocumentId",
213
+ "lastCreationTime",
214
+ "nextAttemptId",
215
+ "identityEpoch",
216
+ ]),
217
+ value: Schema.Finite,
218
+ required: Schema.Finite,
219
+ message: Schema.String,
220
+ },
221
+ ) {}
222
+
223
+ /**
224
+ * A snapshot's rows are not what its write log publishes: a row filed under
225
+ * another table or an unregistered component, a version the log does not give
226
+ * it, or a log change whose before value is not the row it replaced.
227
+ */
228
+ export class SnapshotRowInconsistent extends Schema.TaggedError<SnapshotRowInconsistent>()(
229
+ "SnapshotRowInconsistent",
230
+ {
231
+ componentPath: Schema.String,
232
+ id: Schema.String,
233
+ reason: Schema.Literals([
234
+ "id",
235
+ "component",
236
+ "log",
237
+ "row",
238
+ "systemFields",
239
+ "duplicate",
240
+ ]),
241
+ message: Schema.String,
242
+ },
243
+ ) {}
244
+
245
+ /**
246
+ * A snapshot's commit timestamps do not strictly increase through its write
247
+ * log, or its latest commit timestamp is not the log's last.
248
+ */
249
+ export class SnapshotTimestampInconsistent extends Schema.TaggedError<SnapshotTimestampInconsistent>()(
250
+ "SnapshotTimestampInconsistent",
251
+ { version: Schema.Int, commitTs: Schema.String, message: Schema.String },
252
+ ) {}
253
+
254
+ /**
255
+ * A snapshot's jobs and job rows disagree: a job with no row, a row with no
256
+ * job, a job left running, or a target no registered component exports.
257
+ */
258
+ export class SnapshotJobInconsistent extends Schema.TaggedError<SnapshotJobInconsistent>()(
259
+ "SnapshotJobInconsistent",
260
+ {
261
+ id: Schema.String,
262
+ reason: Schema.Literals([
263
+ "row",
264
+ "untargeted",
265
+ "inProgress",
266
+ "component",
267
+ "function",
268
+ "duplicate",
269
+ ]),
270
+ message: Schema.String,
271
+ },
272
+ ) {}