@concavejs/cli 0.0.1-alpha.8 → 0.0.1-alpha.9
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/dist/assets/manifest.json +11 -11
- package/dist/assets/runtime-bun/server/index.js +261 -137
- package/dist/assets/runtime-cf/runtime.bundle.js +14216 -2636
- package/dist/assets/runtime-node/server/index.js +261 -137
- package/dist/cli.js +439 -266
- package/package.json +1 -1
|
@@ -2872,6 +2872,12 @@ function parseDocumentIdKey(key) {
|
|
|
2872
2872
|
const internalId = key.substring(colonIndex + 1);
|
|
2873
2873
|
if (!table || !internalId)
|
|
2874
2874
|
return null;
|
|
2875
|
+
if (table.startsWith("#")) {
|
|
2876
|
+
const tableNumber = Number.parseInt(table.slice(1), 10);
|
|
2877
|
+
if (Number.isInteger(tableNumber) && tableNumber > 0) {
|
|
2878
|
+
return { table, internalId, tableNumber };
|
|
2879
|
+
}
|
|
2880
|
+
}
|
|
2875
2881
|
return { table, internalId };
|
|
2876
2882
|
}
|
|
2877
2883
|
var Order;
|
|
@@ -10655,7 +10661,6 @@ class KernelContext5 {
|
|
|
10655
10661
|
}
|
|
10656
10662
|
recordTableRead(tableName) {
|
|
10657
10663
|
if (this.mutationTransaction) {
|
|
10658
|
-
this.mutationTransaction.recordTableScan(stringToHex5(tableName), []);
|
|
10659
10664
|
return;
|
|
10660
10665
|
}
|
|
10661
10666
|
this.readLog.addTableScan(tableName);
|
|
@@ -10668,8 +10673,6 @@ class KernelContext5 {
|
|
|
10668
10673
|
}
|
|
10669
10674
|
recordIndexRange(tableName, indexDescriptor, startKey, endKey) {
|
|
10670
10675
|
if (this.mutationTransaction) {
|
|
10671
|
-
const indexId = indexKeyspaceId5(tableName, indexDescriptor);
|
|
10672
|
-
this.mutationTransaction.recordIndexRangeScan(indexId, startKey, endKey, []);
|
|
10673
10676
|
return;
|
|
10674
10677
|
}
|
|
10675
10678
|
this.readLog.addIndexRange(tableName, indexDescriptor, startKey, endKey);
|
|
@@ -10821,11 +10824,12 @@ class BlobStoreGateway5 {
|
|
|
10821
10824
|
if (!latest || latest.ts > this.context.snapshotTimestamp) {
|
|
10822
10825
|
return;
|
|
10823
10826
|
}
|
|
10824
|
-
|
|
10827
|
+
const canonicalDocId = latest.value.id;
|
|
10828
|
+
await storage2.delete(canonicalDocId.internalId);
|
|
10825
10829
|
const timestamp22 = this.docStore.allocateTimestamp();
|
|
10826
|
-
const entry = { ts: timestamp22, id:
|
|
10830
|
+
const entry = { ts: timestamp22, id: canonicalDocId, value: null, prev_ts: latest.ts };
|
|
10827
10831
|
await this.docStore.applyWrites([entry], new Set, "Error");
|
|
10828
|
-
this.context.recordLocalWrite(storageId, "_storage", null,
|
|
10832
|
+
this.context.recordLocalWrite(storageId, "_storage", null, canonicalDocId);
|
|
10829
10833
|
}
|
|
10830
10834
|
requireStorage() {
|
|
10831
10835
|
if (!this.storage) {
|
|
@@ -11026,16 +11030,17 @@ class SchedulerGateway5 {
|
|
|
11026
11030
|
if (!latest) {
|
|
11027
11031
|
throw new Error(`Scheduled job with id ${id} not found.`);
|
|
11028
11032
|
}
|
|
11033
|
+
const canonicalDocId = latest.value.id;
|
|
11029
11034
|
const newValue = {
|
|
11030
11035
|
...latest.value.value,
|
|
11031
11036
|
state: state ?? { kind: "canceled" }
|
|
11032
11037
|
};
|
|
11033
|
-
const resolvedDocument = { id:
|
|
11038
|
+
const resolvedDocument = { id: canonicalDocId, value: newValue };
|
|
11034
11039
|
const timestamp22 = this.docStore.allocateTimestamp();
|
|
11035
|
-
const entry = { ts: timestamp22, id:
|
|
11040
|
+
const entry = { ts: timestamp22, id: canonicalDocId, value: resolvedDocument, prev_ts: latest.ts };
|
|
11036
11041
|
await this.docStore.applyWrites([entry], new Set, "Error");
|
|
11037
|
-
const tableName = await resolveTableName5(
|
|
11038
|
-
this.context.recordLocalWrite(id, tableName, resolvedDocument.value,
|
|
11042
|
+
const tableName = await resolveTableName5(canonicalDocId, this.context.tableRegistry);
|
|
11043
|
+
this.context.recordLocalWrite(id, tableName, resolvedDocument.value, canonicalDocId);
|
|
11039
11044
|
}
|
|
11040
11045
|
}
|
|
11041
11046
|
async function runAsServerCall5(fn, functionPath) {
|
|
@@ -11238,13 +11243,14 @@ class DatabaseSyscalls5 {
|
|
|
11238
11243
|
if (!latest) {
|
|
11239
11244
|
throw new Error(`Document with id ${id} not found.`);
|
|
11240
11245
|
}
|
|
11246
|
+
const canonicalDocId = latest.value.id;
|
|
11241
11247
|
const timestamp22 = this.docStore.allocateTimestamp();
|
|
11242
|
-
const entry = { ts: timestamp22, id:
|
|
11248
|
+
const entry = { ts: timestamp22, id: canonicalDocId, value: null, prev_ts: latest.ts };
|
|
11243
11249
|
const indexes = await this.schemaService.getAllIndexesForTable(bareTableName);
|
|
11244
|
-
const indexUpdates = generateIndexUpdates5(fullTableName,
|
|
11250
|
+
const indexUpdates = generateIndexUpdates5(fullTableName, canonicalDocId, null, latest.value.value, indexes);
|
|
11245
11251
|
const indexEntries = new Set(indexUpdates.map((update) => ({ ts: timestamp22, update })));
|
|
11246
11252
|
await this.docStore.applyWrites([entry], indexEntries, "Error");
|
|
11247
|
-
this.context.recordLocalWrite(id, fullTableName, null,
|
|
11253
|
+
this.context.recordLocalWrite(id, fullTableName, null, canonicalDocId);
|
|
11248
11254
|
return {};
|
|
11249
11255
|
}
|
|
11250
11256
|
async handleShallowMerge(args) {
|
|
@@ -11270,6 +11276,7 @@ class DatabaseSyscalls5 {
|
|
|
11270
11276
|
if (!latest) {
|
|
11271
11277
|
throw new Error(`Document with id ${id} not found.`);
|
|
11272
11278
|
}
|
|
11279
|
+
const canonicalDocId = latest.value.id;
|
|
11273
11280
|
const existingValue = latest.value.value;
|
|
11274
11281
|
const newValue = { ...existingValue };
|
|
11275
11282
|
if (typeof value === "object" && value !== null && "$undefined" in value) {
|
|
@@ -11296,14 +11303,14 @@ class DatabaseSyscalls5 {
|
|
|
11296
11303
|
}
|
|
11297
11304
|
}
|
|
11298
11305
|
await this.schemaService.validate(bareTableName, newValue);
|
|
11299
|
-
const resolvedDocument = { id:
|
|
11306
|
+
const resolvedDocument = { id: canonicalDocId, value: newValue };
|
|
11300
11307
|
const timestamp22 = this.docStore.allocateTimestamp();
|
|
11301
|
-
const entry = { ts: timestamp22, id:
|
|
11308
|
+
const entry = { ts: timestamp22, id: canonicalDocId, value: resolvedDocument, prev_ts: latest.ts };
|
|
11302
11309
|
const indexes = await this.schemaService.getAllIndexesForTable(bareTableName);
|
|
11303
|
-
const indexUpdates = generateIndexUpdates5(fullTableName,
|
|
11310
|
+
const indexUpdates = generateIndexUpdates5(fullTableName, canonicalDocId, resolvedDocument.value, existingValue, indexes);
|
|
11304
11311
|
const indexEntries = new Set(indexUpdates.map((update) => ({ ts: timestamp22, update })));
|
|
11305
11312
|
await this.docStore.applyWrites([entry], indexEntries, "Error");
|
|
11306
|
-
this.context.recordLocalWrite(id, fullTableName, resolvedDocument.value,
|
|
11313
|
+
this.context.recordLocalWrite(id, fullTableName, resolvedDocument.value, canonicalDocId);
|
|
11307
11314
|
return {};
|
|
11308
11315
|
}
|
|
11309
11316
|
async handleReplace(args) {
|
|
@@ -11325,17 +11332,18 @@ class DatabaseSyscalls5 {
|
|
|
11325
11332
|
if (!latest) {
|
|
11326
11333
|
throw new Error(`Document with id ${id} not found.`);
|
|
11327
11334
|
}
|
|
11335
|
+
const canonicalDocId = latest.value.id;
|
|
11328
11336
|
const { _id, _creationTime } = latest.value.value;
|
|
11329
11337
|
const newValue = { ...replaceValue, _id, _creationTime };
|
|
11330
11338
|
await this.schemaService.validate(bareTableName, newValue);
|
|
11331
|
-
const resolvedDocument = { id:
|
|
11339
|
+
const resolvedDocument = { id: canonicalDocId, value: newValue };
|
|
11332
11340
|
const timestamp22 = this.docStore.allocateTimestamp();
|
|
11333
|
-
const entry = { ts: timestamp22, id:
|
|
11341
|
+
const entry = { ts: timestamp22, id: canonicalDocId, value: resolvedDocument, prev_ts: latest.ts };
|
|
11334
11342
|
const indexes = await this.schemaService.getAllIndexesForTable(bareTableName);
|
|
11335
|
-
const indexUpdates = generateIndexUpdates5(fullTableName,
|
|
11343
|
+
const indexUpdates = generateIndexUpdates5(fullTableName, canonicalDocId, resolvedDocument.value, latest.value.value, indexes);
|
|
11336
11344
|
const indexEntries = new Set(indexUpdates.map((update) => ({ ts: timestamp22, update })));
|
|
11337
11345
|
await this.docStore.applyWrites([entry], indexEntries, "Error");
|
|
11338
|
-
this.context.recordLocalWrite(id, fullTableName, newValue,
|
|
11346
|
+
this.context.recordLocalWrite(id, fullTableName, newValue, canonicalDocId);
|
|
11339
11347
|
return {};
|
|
11340
11348
|
}
|
|
11341
11349
|
}
|
|
@@ -20920,7 +20928,6 @@ class KernelContext {
|
|
|
20920
20928
|
}
|
|
20921
20929
|
recordTableRead(tableName) {
|
|
20922
20930
|
if (this.mutationTransaction) {
|
|
20923
|
-
this.mutationTransaction.recordTableScan(stringToHex(tableName), []);
|
|
20924
20931
|
return;
|
|
20925
20932
|
}
|
|
20926
20933
|
this.readLog.addTableScan(tableName);
|
|
@@ -20933,8 +20940,6 @@ class KernelContext {
|
|
|
20933
20940
|
}
|
|
20934
20941
|
recordIndexRange(tableName, indexDescriptor, startKey, endKey) {
|
|
20935
20942
|
if (this.mutationTransaction) {
|
|
20936
|
-
const indexId = indexKeyspaceId(tableName, indexDescriptor);
|
|
20937
|
-
this.mutationTransaction.recordIndexRangeScan(indexId, startKey, endKey, []);
|
|
20938
20943
|
return;
|
|
20939
20944
|
}
|
|
20940
20945
|
this.readLog.addIndexRange(tableName, indexDescriptor, startKey, endKey);
|
|
@@ -21090,11 +21095,12 @@ class BlobStoreGateway {
|
|
|
21090
21095
|
if (!latest || latest.ts > this.context.snapshotTimestamp) {
|
|
21091
21096
|
return;
|
|
21092
21097
|
}
|
|
21093
|
-
|
|
21098
|
+
const canonicalDocId = latest.value.id;
|
|
21099
|
+
await storage2.delete(canonicalDocId.internalId);
|
|
21094
21100
|
const timestamp = this.docStore.allocateTimestamp();
|
|
21095
|
-
const entry = { ts: timestamp, id:
|
|
21101
|
+
const entry = { ts: timestamp, id: canonicalDocId, value: null, prev_ts: latest.ts };
|
|
21096
21102
|
await this.docStore.applyWrites([entry], new Set, "Error");
|
|
21097
|
-
this.context.recordLocalWrite(storageId, "_storage", null,
|
|
21103
|
+
this.context.recordLocalWrite(storageId, "_storage", null, canonicalDocId);
|
|
21098
21104
|
}
|
|
21099
21105
|
requireStorage() {
|
|
21100
21106
|
if (!this.storage) {
|
|
@@ -21297,16 +21303,17 @@ class SchedulerGateway {
|
|
|
21297
21303
|
if (!latest) {
|
|
21298
21304
|
throw new Error(`Scheduled job with id ${id} not found.`);
|
|
21299
21305
|
}
|
|
21306
|
+
const canonicalDocId = latest.value.id;
|
|
21300
21307
|
const newValue = {
|
|
21301
21308
|
...latest.value.value,
|
|
21302
21309
|
state: state ?? { kind: "canceled" }
|
|
21303
21310
|
};
|
|
21304
|
-
const resolvedDocument = { id:
|
|
21311
|
+
const resolvedDocument = { id: canonicalDocId, value: newValue };
|
|
21305
21312
|
const timestamp = this.docStore.allocateTimestamp();
|
|
21306
|
-
const entry = { ts: timestamp, id:
|
|
21313
|
+
const entry = { ts: timestamp, id: canonicalDocId, value: resolvedDocument, prev_ts: latest.ts };
|
|
21307
21314
|
await this.docStore.applyWrites([entry], new Set, "Error");
|
|
21308
|
-
const tableName = await resolveTableName(
|
|
21309
|
-
this.context.recordLocalWrite(id, tableName, resolvedDocument.value,
|
|
21315
|
+
const tableName = await resolveTableName(canonicalDocId, this.context.tableRegistry);
|
|
21316
|
+
this.context.recordLocalWrite(id, tableName, resolvedDocument.value, canonicalDocId);
|
|
21310
21317
|
}
|
|
21311
21318
|
}
|
|
21312
21319
|
|
|
@@ -21508,13 +21515,14 @@ class DatabaseSyscalls {
|
|
|
21508
21515
|
if (!latest) {
|
|
21509
21516
|
throw new Error(`Document with id ${id} not found.`);
|
|
21510
21517
|
}
|
|
21518
|
+
const canonicalDocId = latest.value.id;
|
|
21511
21519
|
const timestamp = this.docStore.allocateTimestamp();
|
|
21512
|
-
const entry = { ts: timestamp, id:
|
|
21520
|
+
const entry = { ts: timestamp, id: canonicalDocId, value: null, prev_ts: latest.ts };
|
|
21513
21521
|
const indexes = await this.schemaService.getAllIndexesForTable(bareTableName);
|
|
21514
|
-
const indexUpdates = generateIndexUpdates(fullTableName,
|
|
21522
|
+
const indexUpdates = generateIndexUpdates(fullTableName, canonicalDocId, null, latest.value.value, indexes);
|
|
21515
21523
|
const indexEntries = new Set(indexUpdates.map((update) => ({ ts: timestamp, update })));
|
|
21516
21524
|
await this.docStore.applyWrites([entry], indexEntries, "Error");
|
|
21517
|
-
this.context.recordLocalWrite(id, fullTableName, null,
|
|
21525
|
+
this.context.recordLocalWrite(id, fullTableName, null, canonicalDocId);
|
|
21518
21526
|
return {};
|
|
21519
21527
|
}
|
|
21520
21528
|
async handleShallowMerge(args) {
|
|
@@ -21540,6 +21548,7 @@ class DatabaseSyscalls {
|
|
|
21540
21548
|
if (!latest) {
|
|
21541
21549
|
throw new Error(`Document with id ${id} not found.`);
|
|
21542
21550
|
}
|
|
21551
|
+
const canonicalDocId = latest.value.id;
|
|
21543
21552
|
const existingValue = latest.value.value;
|
|
21544
21553
|
const newValue = { ...existingValue };
|
|
21545
21554
|
if (typeof value === "object" && value !== null && "$undefined" in value) {
|
|
@@ -21566,14 +21575,14 @@ class DatabaseSyscalls {
|
|
|
21566
21575
|
}
|
|
21567
21576
|
}
|
|
21568
21577
|
await this.schemaService.validate(bareTableName, newValue);
|
|
21569
|
-
const resolvedDocument = { id:
|
|
21578
|
+
const resolvedDocument = { id: canonicalDocId, value: newValue };
|
|
21570
21579
|
const timestamp = this.docStore.allocateTimestamp();
|
|
21571
|
-
const entry = { ts: timestamp, id:
|
|
21580
|
+
const entry = { ts: timestamp, id: canonicalDocId, value: resolvedDocument, prev_ts: latest.ts };
|
|
21572
21581
|
const indexes = await this.schemaService.getAllIndexesForTable(bareTableName);
|
|
21573
|
-
const indexUpdates = generateIndexUpdates(fullTableName,
|
|
21582
|
+
const indexUpdates = generateIndexUpdates(fullTableName, canonicalDocId, resolvedDocument.value, existingValue, indexes);
|
|
21574
21583
|
const indexEntries = new Set(indexUpdates.map((update) => ({ ts: timestamp, update })));
|
|
21575
21584
|
await this.docStore.applyWrites([entry], indexEntries, "Error");
|
|
21576
|
-
this.context.recordLocalWrite(id, fullTableName, resolvedDocument.value,
|
|
21585
|
+
this.context.recordLocalWrite(id, fullTableName, resolvedDocument.value, canonicalDocId);
|
|
21577
21586
|
return {};
|
|
21578
21587
|
}
|
|
21579
21588
|
async handleReplace(args) {
|
|
@@ -21595,17 +21604,18 @@ class DatabaseSyscalls {
|
|
|
21595
21604
|
if (!latest) {
|
|
21596
21605
|
throw new Error(`Document with id ${id} not found.`);
|
|
21597
21606
|
}
|
|
21607
|
+
const canonicalDocId = latest.value.id;
|
|
21598
21608
|
const { _id, _creationTime } = latest.value.value;
|
|
21599
21609
|
const newValue = { ...replaceValue, _id, _creationTime };
|
|
21600
21610
|
await this.schemaService.validate(bareTableName, newValue);
|
|
21601
|
-
const resolvedDocument = { id:
|
|
21611
|
+
const resolvedDocument = { id: canonicalDocId, value: newValue };
|
|
21602
21612
|
const timestamp = this.docStore.allocateTimestamp();
|
|
21603
|
-
const entry = { ts: timestamp, id:
|
|
21613
|
+
const entry = { ts: timestamp, id: canonicalDocId, value: resolvedDocument, prev_ts: latest.ts };
|
|
21604
21614
|
const indexes = await this.schemaService.getAllIndexesForTable(bareTableName);
|
|
21605
|
-
const indexUpdates = generateIndexUpdates(fullTableName,
|
|
21615
|
+
const indexUpdates = generateIndexUpdates(fullTableName, canonicalDocId, resolvedDocument.value, latest.value.value, indexes);
|
|
21606
21616
|
const indexEntries = new Set(indexUpdates.map((update) => ({ ts: timestamp, update })));
|
|
21607
21617
|
await this.docStore.applyWrites([entry], indexEntries, "Error");
|
|
21608
|
-
this.context.recordLocalWrite(id, fullTableName, newValue,
|
|
21618
|
+
this.context.recordLocalWrite(id, fullTableName, newValue, canonicalDocId);
|
|
21609
21619
|
return {};
|
|
21610
21620
|
}
|
|
21611
21621
|
}
|
|
@@ -22290,6 +22300,7 @@ class SyncProtocolHandler {
|
|
|
22290
22300
|
rateLimitWindowMs;
|
|
22291
22301
|
operationTimeoutMs;
|
|
22292
22302
|
maxActiveQueriesPerSession;
|
|
22303
|
+
lastObservedWriteTimestamp = 0n;
|
|
22293
22304
|
constructor(instanceName, udfExecutor, options) {
|
|
22294
22305
|
this.udfExecutor = udfExecutor;
|
|
22295
22306
|
this.instanceName = instanceName;
|
|
@@ -22313,6 +22324,22 @@ class SyncProtocolHandler {
|
|
|
22313
22324
|
onPing: (session) => this.sendPing(session)
|
|
22314
22325
|
});
|
|
22315
22326
|
}
|
|
22327
|
+
resolveWriteTimestamp(commitTimestamp, snapshotTimestamp) {
|
|
22328
|
+
const wallClock = BigInt(Date.now());
|
|
22329
|
+
const monotonicFloor = this.lastObservedWriteTimestamp + 1n;
|
|
22330
|
+
let resolved = wallClock;
|
|
22331
|
+
if (commitTimestamp !== undefined && commitTimestamp > resolved) {
|
|
22332
|
+
resolved = commitTimestamp;
|
|
22333
|
+
}
|
|
22334
|
+
if (snapshotTimestamp !== undefined && snapshotTimestamp > resolved) {
|
|
22335
|
+
resolved = snapshotTimestamp;
|
|
22336
|
+
}
|
|
22337
|
+
if (monotonicFloor > resolved) {
|
|
22338
|
+
resolved = monotonicFloor;
|
|
22339
|
+
}
|
|
22340
|
+
this.lastObservedWriteTimestamp = resolved;
|
|
22341
|
+
return resolved;
|
|
22342
|
+
}
|
|
22316
22343
|
createSession(sessionId, websocket) {
|
|
22317
22344
|
const session = new SyncSession(websocket);
|
|
22318
22345
|
this.sessions.set(sessionId, session);
|
|
@@ -22395,11 +22422,11 @@ class SyncProtocolHandler {
|
|
|
22395
22422
|
return assertNever(message2);
|
|
22396
22423
|
}
|
|
22397
22424
|
}
|
|
22398
|
-
async notifyWrites(writtenRanges, writtenTables, commitTimestamp) {
|
|
22425
|
+
async notifyWrites(writtenRanges, writtenTables, commitTimestamp, snapshotTimestamp) {
|
|
22399
22426
|
const ranges = writtenRanges ? writtenRanges.map(deserializeKeyRange) : convertTablesToRanges(writtenTables);
|
|
22400
22427
|
this.logRanges("/notify", ranges, { writtenTables });
|
|
22401
22428
|
if (ranges.length > 0) {
|
|
22402
|
-
const ts = commitTimestamp
|
|
22429
|
+
const ts = this.resolveWriteTimestamp(commitTimestamp, snapshotTimestamp);
|
|
22403
22430
|
this.subscriptionManager.recordWrites(ranges, ts);
|
|
22404
22431
|
await this.broadcastUpdates(ranges);
|
|
22405
22432
|
}
|
|
@@ -22497,8 +22524,8 @@ class SyncProtocolHandler {
|
|
|
22497
22524
|
if (message2.componentPath && session.auth.tokenType !== "Admin" && session.auth.tokenType !== "System") {
|
|
22498
22525
|
throw new Error("Only admin or system auth can execute component functions");
|
|
22499
22526
|
}
|
|
22500
|
-
const { result, writtenRanges, writtenTables, commitTimestamp, logLines } = await this.udfExecutor.executeMutation(message2.udfPath, message2.args[0] ?? {}, session.auth, message2.componentPath);
|
|
22501
|
-
const now = commitTimestamp
|
|
22527
|
+
const { result, writtenRanges, writtenTables, commitTimestamp, snapshotTimestamp, logLines } = await this.udfExecutor.executeMutation(message2.udfPath, message2.args[0] ?? {}, session.auth, message2.componentPath);
|
|
22528
|
+
const now = this.resolveWriteTimestamp(commitTimestamp, snapshotTimestamp);
|
|
22502
22529
|
const successResponse = {
|
|
22503
22530
|
type: "MutationResponse",
|
|
22504
22531
|
requestId: message2.requestId,
|
|
@@ -22543,8 +22570,8 @@ class SyncProtocolHandler {
|
|
|
22543
22570
|
if (message2.componentPath && session.auth.tokenType !== "Admin" && session.auth.tokenType !== "System") {
|
|
22544
22571
|
throw new Error("Only admin or system auth can mutate component functions");
|
|
22545
22572
|
}
|
|
22546
|
-
const { result, writtenRanges, writtenTables, commitTimestamp, logLines } = await this.udfExecutor.executeAction(message2.udfPath, message2.args[0] ?? {}, session.auth, message2.componentPath);
|
|
22547
|
-
const now = commitTimestamp
|
|
22573
|
+
const { result, writtenRanges, writtenTables, commitTimestamp, snapshotTimestamp, logLines } = await this.udfExecutor.executeAction(message2.udfPath, message2.args[0] ?? {}, session.auth, message2.componentPath);
|
|
22574
|
+
const now = this.resolveWriteTimestamp(commitTimestamp, snapshotTimestamp);
|
|
22548
22575
|
const successResponse = {
|
|
22549
22576
|
type: "ActionResponse",
|
|
22550
22577
|
requestId: message2.requestId,
|
|
@@ -22900,7 +22927,8 @@ function createSyncUdfExecutor(adapter) {
|
|
|
22900
22927
|
writtenRanges: result.writtenRanges,
|
|
22901
22928
|
writtenTables: writtenTablesFromRanges(result.writtenRanges),
|
|
22902
22929
|
logLines: result.logLines,
|
|
22903
|
-
commitTimestamp: result.commitTimestamp
|
|
22930
|
+
commitTimestamp: result.commitTimestamp,
|
|
22931
|
+
snapshotTimestamp: result.snapshotTimestamp
|
|
22904
22932
|
};
|
|
22905
22933
|
},
|
|
22906
22934
|
executeAction: async (path, args, auth, componentPath) => {
|
|
@@ -22918,7 +22946,8 @@ function createSyncUdfExecutor(adapter) {
|
|
|
22918
22946
|
writtenRanges: result.writtenRanges,
|
|
22919
22947
|
writtenTables: writtenTablesFromRanges(result.writtenRanges),
|
|
22920
22948
|
logLines: result.logLines,
|
|
22921
|
-
commitTimestamp: result.commitTimestamp
|
|
22949
|
+
commitTimestamp: result.commitTimestamp,
|
|
22950
|
+
snapshotTimestamp: result.snapshotTimestamp
|
|
22922
22951
|
};
|
|
22923
22952
|
}
|
|
22924
22953
|
};
|
|
@@ -26426,7 +26455,7 @@ function rangeExpressionsToIndexBounds(expressions, indexFields) {
|
|
|
26426
26455
|
}
|
|
26427
26456
|
return { start, end };
|
|
26428
26457
|
}
|
|
26429
|
-
async function executeIndexQuery(docstore, tableName, indexName, indexFields, expressions, order, limit, cursor, snapshotTimestamp) {
|
|
26458
|
+
async function executeIndexQuery(docstore, tableName, indexName, indexFields, expressions, order, limit, cursor, snapshotTimestamp, onDocumentRead) {
|
|
26430
26459
|
const tableId = stringToHex2(tableName);
|
|
26431
26460
|
const indexId = stringToHex2(`${tableName}:${indexName}`);
|
|
26432
26461
|
const indexOrder = order === "asc" ? Order.Asc : Order.Desc;
|
|
@@ -26452,6 +26481,7 @@ async function executeIndexQuery(docstore, tableName, indexName, indexFields, ex
|
|
|
26452
26481
|
try {
|
|
26453
26482
|
const generator = docstore.index_scan(indexId, tableId, readTimestamp, interval, indexOrder);
|
|
26454
26483
|
for await (const [indexKey, document] of generator) {
|
|
26484
|
+
onDocumentRead?.(document);
|
|
26455
26485
|
const doc = document.value.value;
|
|
26456
26486
|
if (skipping) {
|
|
26457
26487
|
if (resumeIndexKey) {
|
|
@@ -26881,6 +26911,9 @@ class UncommittedWrites {
|
|
|
26881
26911
|
}
|
|
26882
26912
|
}
|
|
26883
26913
|
}
|
|
26914
|
+
// ../core/dist/query/query-runtime.js
|
|
26915
|
+
init_interface();
|
|
26916
|
+
|
|
26884
26917
|
// ../core/dist/query/planner.js
|
|
26885
26918
|
init_values2();
|
|
26886
26919
|
init_interface3();
|
|
@@ -27250,13 +27283,27 @@ class QueryRuntime {
|
|
|
27250
27283
|
return paginateByCursor(sortedResults, cursor, limit);
|
|
27251
27284
|
}
|
|
27252
27285
|
async handleIndexRange(plan, cursor, limit) {
|
|
27253
|
-
|
|
27254
|
-
|
|
27286
|
+
const { start, end } = rangeExpressionsToIndexBounds(plan.expressions, plan.indexFields);
|
|
27287
|
+
const mutationTransaction = this.docStore.getTransaction();
|
|
27288
|
+
if (!mutationTransaction) {
|
|
27255
27289
|
this.context.recordIndexRange(plan.fullTableName, plan.indexDescriptor, start, end);
|
|
27256
27290
|
}
|
|
27291
|
+
const observedDocuments = mutationTransaction ? new Map : null;
|
|
27257
27292
|
let paginationResult;
|
|
27258
27293
|
try {
|
|
27259
|
-
const indexResult = await executeIndexQuery(this.docStore.getDocStore(), plan.fullTableName, plan.indexDescriptor, plan.indexFields, plan.expressions, plan.order, limit, cursor, this.context.snapshotTimestamp)
|
|
27294
|
+
const indexResult = await executeIndexQuery(this.docStore.getDocStore(), plan.fullTableName, plan.indexDescriptor, plan.indexFields, plan.expressions, plan.order, limit, cursor, this.context.snapshotTimestamp, (latestDoc) => {
|
|
27295
|
+
if (!observedDocuments) {
|
|
27296
|
+
return;
|
|
27297
|
+
}
|
|
27298
|
+
observedDocuments.set(documentIdKey(latestDoc.value.id), latestDoc);
|
|
27299
|
+
});
|
|
27300
|
+
if (mutationTransaction && observedDocuments) {
|
|
27301
|
+
const observed = Array.from(observedDocuments.values());
|
|
27302
|
+
mutationTransaction.recordIndexRangeScan(indexKeyspaceId2(plan.fullTableName, plan.indexDescriptor), start, end, observed);
|
|
27303
|
+
for (const doc of observed) {
|
|
27304
|
+
mutationTransaction.recordDocumentRead(doc.value.id, doc);
|
|
27305
|
+
}
|
|
27306
|
+
}
|
|
27260
27307
|
const uncommittedWrites = UncommittedWrites.fromContext(this.docStore.getTransaction(), this.context.getLocalWrites());
|
|
27261
27308
|
if (uncommittedWrites) {
|
|
27262
27309
|
const tableId = stringToHex2(plan.fullTableName);
|
|
@@ -27289,7 +27336,10 @@ class QueryRuntime {
|
|
|
27289
27336
|
return paginationResult;
|
|
27290
27337
|
}
|
|
27291
27338
|
async handleSearch(plan, _cursor, limit) {
|
|
27292
|
-
this.
|
|
27339
|
+
const mutationTransaction = this.docStore.getTransaction();
|
|
27340
|
+
if (!mutationTransaction) {
|
|
27341
|
+
this.context.recordTableRead(plan.fullTableName);
|
|
27342
|
+
}
|
|
27293
27343
|
const limitOperator = plan.query.operators?.find((operator) => ("limit" in operator));
|
|
27294
27344
|
const operatorLimit = limitOperator?.limit;
|
|
27295
27345
|
const combinedLimit = typeof limit === "number" && limit > 0 ? operatorLimit && operatorLimit > 0 ? Math.min(limit, operatorLimit) : limit : operatorLimit && operatorLimit > 0 ? operatorLimit : undefined;
|
|
@@ -27298,7 +27348,13 @@ class QueryRuntime {
|
|
|
27298
27348
|
throw new Error("DocStore does not support full-text search");
|
|
27299
27349
|
}
|
|
27300
27350
|
const searchResults = await rawDocStore.search(plan.indexIdHex, plan.searchTerm, plan.filterMap, { limit: combinedLimit });
|
|
27301
|
-
const
|
|
27351
|
+
const visibleResults = searchResults.filter(({ doc }) => doc.ts <= this.context.snapshotTimestamp);
|
|
27352
|
+
if (mutationTransaction) {
|
|
27353
|
+
for (const { doc } of visibleResults) {
|
|
27354
|
+
mutationTransaction.recordDocumentRead(doc.value.id, doc);
|
|
27355
|
+
}
|
|
27356
|
+
}
|
|
27357
|
+
const documents = visibleResults.map(({ doc, score }) => ({
|
|
27302
27358
|
...doc.value.value,
|
|
27303
27359
|
_score: score
|
|
27304
27360
|
}));
|
|
@@ -27485,6 +27541,7 @@ class AccessLog2 {
|
|
|
27485
27541
|
return this.ranges.getRanges().map(serializeKeyRange2);
|
|
27486
27542
|
}
|
|
27487
27543
|
}
|
|
27544
|
+
|
|
27488
27545
|
// ../core/dist/tables/memory-table-registry.js
|
|
27489
27546
|
init_interface3();
|
|
27490
27547
|
|
|
@@ -27622,7 +27679,6 @@ class KernelContext2 {
|
|
|
27622
27679
|
}
|
|
27623
27680
|
recordTableRead(tableName) {
|
|
27624
27681
|
if (this.mutationTransaction) {
|
|
27625
|
-
this.mutationTransaction.recordTableScan(stringToHex2(tableName), []);
|
|
27626
27682
|
return;
|
|
27627
27683
|
}
|
|
27628
27684
|
this.readLog.addTableScan(tableName);
|
|
@@ -27635,8 +27691,6 @@ class KernelContext2 {
|
|
|
27635
27691
|
}
|
|
27636
27692
|
recordIndexRange(tableName, indexDescriptor, startKey, endKey) {
|
|
27637
27693
|
if (this.mutationTransaction) {
|
|
27638
|
-
const indexId = indexKeyspaceId2(tableName, indexDescriptor);
|
|
27639
|
-
this.mutationTransaction.recordIndexRangeScan(indexId, startKey, endKey, []);
|
|
27640
27694
|
return;
|
|
27641
27695
|
}
|
|
27642
27696
|
this.readLog.addIndexRange(tableName, indexDescriptor, startKey, endKey);
|
|
@@ -27795,11 +27849,12 @@ class BlobStoreGateway2 {
|
|
|
27795
27849
|
if (!latest || latest.ts > this.context.snapshotTimestamp) {
|
|
27796
27850
|
return;
|
|
27797
27851
|
}
|
|
27798
|
-
|
|
27852
|
+
const canonicalDocId = latest.value.id;
|
|
27853
|
+
await storage2.delete(canonicalDocId.internalId);
|
|
27799
27854
|
const timestamp2 = this.docStore.allocateTimestamp();
|
|
27800
|
-
const entry = { ts: timestamp2, id:
|
|
27855
|
+
const entry = { ts: timestamp2, id: canonicalDocId, value: null, prev_ts: latest.ts };
|
|
27801
27856
|
await this.docStore.applyWrites([entry], new Set, "Error");
|
|
27802
|
-
this.context.recordLocalWrite(storageId, "_storage", null,
|
|
27857
|
+
this.context.recordLocalWrite(storageId, "_storage", null, canonicalDocId);
|
|
27803
27858
|
}
|
|
27804
27859
|
requireStorage() {
|
|
27805
27860
|
if (!this.storage) {
|
|
@@ -28006,16 +28061,17 @@ class SchedulerGateway2 {
|
|
|
28006
28061
|
if (!latest) {
|
|
28007
28062
|
throw new Error(`Scheduled job with id ${id} not found.`);
|
|
28008
28063
|
}
|
|
28064
|
+
const canonicalDocId = latest.value.id;
|
|
28009
28065
|
const newValue = {
|
|
28010
28066
|
...latest.value.value,
|
|
28011
28067
|
state: state ?? { kind: "canceled" }
|
|
28012
28068
|
};
|
|
28013
|
-
const resolvedDocument = { id:
|
|
28069
|
+
const resolvedDocument = { id: canonicalDocId, value: newValue };
|
|
28014
28070
|
const timestamp2 = this.docStore.allocateTimestamp();
|
|
28015
|
-
const entry = { ts: timestamp2, id:
|
|
28071
|
+
const entry = { ts: timestamp2, id: canonicalDocId, value: resolvedDocument, prev_ts: latest.ts };
|
|
28016
28072
|
await this.docStore.applyWrites([entry], new Set, "Error");
|
|
28017
|
-
const tableName = await resolveTableName2(
|
|
28018
|
-
this.context.recordLocalWrite(id, tableName, resolvedDocument.value,
|
|
28073
|
+
const tableName = await resolveTableName2(canonicalDocId, this.context.tableRegistry);
|
|
28074
|
+
this.context.recordLocalWrite(id, tableName, resolvedDocument.value, canonicalDocId);
|
|
28019
28075
|
}
|
|
28020
28076
|
}
|
|
28021
28077
|
|
|
@@ -28239,13 +28295,14 @@ class DatabaseSyscalls2 {
|
|
|
28239
28295
|
if (!latest) {
|
|
28240
28296
|
throw new Error(`Document with id ${id} not found.`);
|
|
28241
28297
|
}
|
|
28298
|
+
const canonicalDocId = latest.value.id;
|
|
28242
28299
|
const timestamp2 = this.docStore.allocateTimestamp();
|
|
28243
|
-
const entry = { ts: timestamp2, id:
|
|
28300
|
+
const entry = { ts: timestamp2, id: canonicalDocId, value: null, prev_ts: latest.ts };
|
|
28244
28301
|
const indexes = await this.schemaService.getAllIndexesForTable(bareTableName);
|
|
28245
|
-
const indexUpdates = generateIndexUpdates2(fullTableName,
|
|
28302
|
+
const indexUpdates = generateIndexUpdates2(fullTableName, canonicalDocId, null, latest.value.value, indexes);
|
|
28246
28303
|
const indexEntries = new Set(indexUpdates.map((update) => ({ ts: timestamp2, update })));
|
|
28247
28304
|
await this.docStore.applyWrites([entry], indexEntries, "Error");
|
|
28248
|
-
this.context.recordLocalWrite(id, fullTableName, null,
|
|
28305
|
+
this.context.recordLocalWrite(id, fullTableName, null, canonicalDocId);
|
|
28249
28306
|
return {};
|
|
28250
28307
|
}
|
|
28251
28308
|
async handleShallowMerge(args) {
|
|
@@ -28271,6 +28328,7 @@ class DatabaseSyscalls2 {
|
|
|
28271
28328
|
if (!latest) {
|
|
28272
28329
|
throw new Error(`Document with id ${id} not found.`);
|
|
28273
28330
|
}
|
|
28331
|
+
const canonicalDocId = latest.value.id;
|
|
28274
28332
|
const existingValue = latest.value.value;
|
|
28275
28333
|
const newValue = { ...existingValue };
|
|
28276
28334
|
if (typeof value === "object" && value !== null && "$undefined" in value) {
|
|
@@ -28297,14 +28355,14 @@ class DatabaseSyscalls2 {
|
|
|
28297
28355
|
}
|
|
28298
28356
|
}
|
|
28299
28357
|
await this.schemaService.validate(bareTableName, newValue);
|
|
28300
|
-
const resolvedDocument = { id:
|
|
28358
|
+
const resolvedDocument = { id: canonicalDocId, value: newValue };
|
|
28301
28359
|
const timestamp2 = this.docStore.allocateTimestamp();
|
|
28302
|
-
const entry = { ts: timestamp2, id:
|
|
28360
|
+
const entry = { ts: timestamp2, id: canonicalDocId, value: resolvedDocument, prev_ts: latest.ts };
|
|
28303
28361
|
const indexes = await this.schemaService.getAllIndexesForTable(bareTableName);
|
|
28304
|
-
const indexUpdates = generateIndexUpdates2(fullTableName,
|
|
28362
|
+
const indexUpdates = generateIndexUpdates2(fullTableName, canonicalDocId, resolvedDocument.value, existingValue, indexes);
|
|
28305
28363
|
const indexEntries = new Set(indexUpdates.map((update) => ({ ts: timestamp2, update })));
|
|
28306
28364
|
await this.docStore.applyWrites([entry], indexEntries, "Error");
|
|
28307
|
-
this.context.recordLocalWrite(id, fullTableName, resolvedDocument.value,
|
|
28365
|
+
this.context.recordLocalWrite(id, fullTableName, resolvedDocument.value, canonicalDocId);
|
|
28308
28366
|
return {};
|
|
28309
28367
|
}
|
|
28310
28368
|
async handleReplace(args) {
|
|
@@ -28326,17 +28384,18 @@ class DatabaseSyscalls2 {
|
|
|
28326
28384
|
if (!latest) {
|
|
28327
28385
|
throw new Error(`Document with id ${id} not found.`);
|
|
28328
28386
|
}
|
|
28387
|
+
const canonicalDocId = latest.value.id;
|
|
28329
28388
|
const { _id, _creationTime } = latest.value.value;
|
|
28330
28389
|
const newValue = { ...replaceValue, _id, _creationTime };
|
|
28331
28390
|
await this.schemaService.validate(bareTableName, newValue);
|
|
28332
|
-
const resolvedDocument = { id:
|
|
28391
|
+
const resolvedDocument = { id: canonicalDocId, value: newValue };
|
|
28333
28392
|
const timestamp2 = this.docStore.allocateTimestamp();
|
|
28334
|
-
const entry = { ts: timestamp2, id:
|
|
28393
|
+
const entry = { ts: timestamp2, id: canonicalDocId, value: resolvedDocument, prev_ts: latest.ts };
|
|
28335
28394
|
const indexes = await this.schemaService.getAllIndexesForTable(bareTableName);
|
|
28336
|
-
const indexUpdates = generateIndexUpdates2(fullTableName,
|
|
28395
|
+
const indexUpdates = generateIndexUpdates2(fullTableName, canonicalDocId, resolvedDocument.value, latest.value.value, indexes);
|
|
28337
28396
|
const indexEntries = new Set(indexUpdates.map((update) => ({ ts: timestamp2, update })));
|
|
28338
28397
|
await this.docStore.applyWrites([entry], indexEntries, "Error");
|
|
28339
|
-
this.context.recordLocalWrite(id, fullTableName, newValue,
|
|
28398
|
+
this.context.recordLocalWrite(id, fullTableName, newValue, canonicalDocId);
|
|
28340
28399
|
return {};
|
|
28341
28400
|
}
|
|
28342
28401
|
}
|
|
@@ -28731,7 +28790,7 @@ async function validateReadSetForCommit(docstore, readChecks, writtenDocKeys) {
|
|
|
28731
28790
|
await validateTableScanRead(docstore, readEntry.tableId, readEntry.documentIds, writtenDocKeys);
|
|
28732
28791
|
continue;
|
|
28733
28792
|
}
|
|
28734
|
-
await validateIndexRangeRead(docstore, readEntry.indexId, readEntry.startKey, readEntry.endKey, readEntry.documentIds, writtenDocKeys);
|
|
28793
|
+
await validateIndexRangeRead(docstore, readEntry.indexId, readEntry.startKey, readEntry.endKey, readEntry.readTimestamp, readEntry.documentIds, writtenDocKeys);
|
|
28735
28794
|
}
|
|
28736
28795
|
}
|
|
28737
28796
|
async function validateDocumentRead(docstore, key, readVersion, writtenDocKeys) {
|
|
@@ -28775,11 +28834,12 @@ async function validateTableScanRead(docstore, tableId, readDocumentIds, written
|
|
|
28775
28834
|
}
|
|
28776
28835
|
}
|
|
28777
28836
|
}
|
|
28778
|
-
async function validateIndexRangeRead(docstore, indexId, startKey, endKey, readDocumentIds, writtenDocKeys) {
|
|
28837
|
+
async function validateIndexRangeRead(docstore, indexId, startKey, endKey, readTimestamp, readDocumentIds, writtenDocKeys) {
|
|
28779
28838
|
const { table } = decodeIndexId2(indexId);
|
|
28780
28839
|
const interval = { start: startKey, end: endKey };
|
|
28840
|
+
const validationReadTimestamp = resolveValidationReadTimestamp(docstore, readTimestamp);
|
|
28781
28841
|
const currentDocIds = new Set;
|
|
28782
|
-
for await (const [, doc] of docstore.index_scan(indexId, table,
|
|
28842
|
+
for await (const [, doc] of docstore.index_scan(indexId, table, validationReadTimestamp, interval, Order.Asc)) {
|
|
28783
28843
|
currentDocIds.add(documentIdKey(doc.value.id));
|
|
28784
28844
|
}
|
|
28785
28845
|
for (const docId of currentDocIds) {
|
|
@@ -28793,6 +28853,13 @@ async function validateIndexRangeRead(docstore, indexId, startKey, endKey, readD
|
|
|
28793
28853
|
}
|
|
28794
28854
|
}
|
|
28795
28855
|
}
|
|
28856
|
+
function resolveValidationReadTimestamp(docstore, minimumTimestamp) {
|
|
28857
|
+
const maybeDocStore = docstore;
|
|
28858
|
+
const oracleTimestamp = maybeDocStore.timestampOracle?.getCurrentTimestamp?.();
|
|
28859
|
+
const wallClockTimestamp = BigInt(Date.now());
|
|
28860
|
+
const latestKnownTimestamp = oracleTimestamp !== undefined && oracleTimestamp > wallClockTimestamp ? oracleTimestamp : wallClockTimestamp;
|
|
28861
|
+
return latestKnownTimestamp > minimumTimestamp ? latestKnownTimestamp : minimumTimestamp;
|
|
28862
|
+
}
|
|
28796
28863
|
|
|
28797
28864
|
// ../core/dist/transactor/occ-transaction.js
|
|
28798
28865
|
class OccMutationTransaction {
|
|
@@ -29363,7 +29430,7 @@ function runUdfMutation(docstore, fn, auth, storage2, requestId, udfExecutor, co
|
|
|
29363
29430
|
const savepoint = parentTransaction.createSavepoint();
|
|
29364
29431
|
const existingIdGenerator = idGeneratorContext2.getStore();
|
|
29365
29432
|
const idGenerator = existingIdGenerator ?? createDeterministicIdGenerator(seed);
|
|
29366
|
-
const nestedResult = transactionContext2.run(parentTransaction, () => idGeneratorContext2.run(idGenerator, () => runUdfAndGetLogs(docstore, fn, ops, auth, "mutation", storage2, seed, parentTransaction, udfExecutor, componentPath)));
|
|
29433
|
+
const nestedResult = Promise.resolve(transactionContext2.run(parentTransaction, () => idGeneratorContext2.run(idGenerator, () => runUdfAndGetLogs(docstore, fn, ops, auth, "mutation", storage2, seed, parentTransaction, udfExecutor, componentPath))));
|
|
29367
29434
|
return nestedResult.catch((error) => {
|
|
29368
29435
|
parentTransaction.restoreSavepoint(savepoint);
|
|
29369
29436
|
throw error;
|
|
@@ -29509,10 +29576,15 @@ class InlineUdfExecutor {
|
|
|
29509
29576
|
async executeHttp(request, auth, requestId) {
|
|
29510
29577
|
const url = new URL(request.url);
|
|
29511
29578
|
const runHttpUdf = async () => {
|
|
29512
|
-
|
|
29579
|
+
let httpModule;
|
|
29580
|
+
try {
|
|
29581
|
+
httpModule = await this.loadModule("http");
|
|
29582
|
+
} catch {
|
|
29583
|
+
return new Response("Not found", { status: 404 });
|
|
29584
|
+
}
|
|
29513
29585
|
const router = httpModule?.default;
|
|
29514
29586
|
if (!router?.isRouter || typeof router.lookup !== "function") {
|
|
29515
|
-
|
|
29587
|
+
return new Response("Not found", { status: 404 });
|
|
29516
29588
|
}
|
|
29517
29589
|
const match = router.lookup(url.pathname, request.method);
|
|
29518
29590
|
if (!match) {
|
|
@@ -29947,6 +30019,9 @@ class HttpHandler {
|
|
|
29947
30019
|
if (url.pathname === "/health") {
|
|
29948
30020
|
return apply(Response.json({ status: "ok", runtime: this.runtimeName }));
|
|
29949
30021
|
}
|
|
30022
|
+
if (!isReservedApiPath(url.pathname)) {
|
|
30023
|
+
return forwardHttpRequest(request, "HTTP action");
|
|
30024
|
+
}
|
|
29950
30025
|
return apply(Response.json({ error: "Not found" }, { status: 404 }));
|
|
29951
30026
|
}
|
|
29952
30027
|
}
|
|
@@ -34103,6 +34178,12 @@ function parseDocumentIdKey2(key) {
|
|
|
34103
34178
|
const internalId = key.substring(colonIndex + 1);
|
|
34104
34179
|
if (!table || !internalId)
|
|
34105
34180
|
return null;
|
|
34181
|
+
if (table.startsWith("#")) {
|
|
34182
|
+
const tableNumber = Number.parseInt(table.slice(1), 10);
|
|
34183
|
+
if (Number.isInteger(tableNumber) && tableNumber > 0) {
|
|
34184
|
+
return { table, internalId, tableNumber };
|
|
34185
|
+
}
|
|
34186
|
+
}
|
|
34106
34187
|
return { table, internalId };
|
|
34107
34188
|
}
|
|
34108
34189
|
var Order3;
|
|
@@ -34615,7 +34696,7 @@ async function validateReadSetForCommit2(docstore, readChecks, writtenDocKeys) {
|
|
|
34615
34696
|
await validateTableScanRead2(docstore, readEntry.tableId, readEntry.documentIds, writtenDocKeys);
|
|
34616
34697
|
continue;
|
|
34617
34698
|
}
|
|
34618
|
-
await validateIndexRangeRead2(docstore, readEntry.indexId, readEntry.startKey, readEntry.endKey, readEntry.documentIds, writtenDocKeys);
|
|
34699
|
+
await validateIndexRangeRead2(docstore, readEntry.indexId, readEntry.startKey, readEntry.endKey, readEntry.readTimestamp, readEntry.documentIds, writtenDocKeys);
|
|
34619
34700
|
}
|
|
34620
34701
|
}
|
|
34621
34702
|
async function validateDocumentRead2(docstore, key, readVersion, writtenDocKeys) {
|
|
@@ -34659,11 +34740,12 @@ async function validateTableScanRead2(docstore, tableId, readDocumentIds, writte
|
|
|
34659
34740
|
}
|
|
34660
34741
|
}
|
|
34661
34742
|
}
|
|
34662
|
-
async function validateIndexRangeRead2(docstore, indexId, startKey, endKey, readDocumentIds, writtenDocKeys) {
|
|
34743
|
+
async function validateIndexRangeRead2(docstore, indexId, startKey, endKey, readTimestamp, readDocumentIds, writtenDocKeys) {
|
|
34663
34744
|
const { table } = decodeIndexId3(indexId);
|
|
34664
34745
|
const interval = { start: startKey, end: endKey };
|
|
34746
|
+
const validationReadTimestamp = resolveValidationReadTimestamp2(docstore, readTimestamp);
|
|
34665
34747
|
const currentDocIds = new Set;
|
|
34666
|
-
for await (const [, doc] of docstore.index_scan(indexId, table,
|
|
34748
|
+
for await (const [, doc] of docstore.index_scan(indexId, table, validationReadTimestamp, interval, Order3.Asc)) {
|
|
34667
34749
|
currentDocIds.add(documentIdKey2(doc.value.id));
|
|
34668
34750
|
}
|
|
34669
34751
|
for (const docId of currentDocIds) {
|
|
@@ -34677,6 +34759,13 @@ async function validateIndexRangeRead2(docstore, indexId, startKey, endKey, read
|
|
|
34677
34759
|
}
|
|
34678
34760
|
}
|
|
34679
34761
|
}
|
|
34762
|
+
function resolveValidationReadTimestamp2(docstore, minimumTimestamp) {
|
|
34763
|
+
const maybeDocStore = docstore;
|
|
34764
|
+
const oracleTimestamp = maybeDocStore.timestampOracle?.getCurrentTimestamp?.();
|
|
34765
|
+
const wallClockTimestamp = BigInt(Date.now());
|
|
34766
|
+
const latestKnownTimestamp = oracleTimestamp !== undefined && oracleTimestamp > wallClockTimestamp ? oracleTimestamp : wallClockTimestamp;
|
|
34767
|
+
return latestKnownTimestamp > minimumTimestamp ? latestKnownTimestamp : minimumTimestamp;
|
|
34768
|
+
}
|
|
34680
34769
|
|
|
34681
34770
|
class OccMutationTransaction2 {
|
|
34682
34771
|
docstore;
|
|
@@ -35281,7 +35370,6 @@ class KernelContext3 {
|
|
|
35281
35370
|
}
|
|
35282
35371
|
recordTableRead(tableName) {
|
|
35283
35372
|
if (this.mutationTransaction) {
|
|
35284
|
-
this.mutationTransaction.recordTableScan(stringToHex3(tableName), []);
|
|
35285
35373
|
return;
|
|
35286
35374
|
}
|
|
35287
35375
|
this.readLog.addTableScan(tableName);
|
|
@@ -35294,8 +35382,6 @@ class KernelContext3 {
|
|
|
35294
35382
|
}
|
|
35295
35383
|
recordIndexRange(tableName, indexDescriptor, startKey, endKey) {
|
|
35296
35384
|
if (this.mutationTransaction) {
|
|
35297
|
-
const indexId = indexKeyspaceId3(tableName, indexDescriptor);
|
|
35298
|
-
this.mutationTransaction.recordIndexRangeScan(indexId, startKey, endKey, []);
|
|
35299
35385
|
return;
|
|
35300
35386
|
}
|
|
35301
35387
|
this.readLog.addIndexRange(tableName, indexDescriptor, startKey, endKey);
|
|
@@ -35451,11 +35537,12 @@ class BlobStoreGateway3 {
|
|
|
35451
35537
|
if (!latest || latest.ts > this.context.snapshotTimestamp) {
|
|
35452
35538
|
return;
|
|
35453
35539
|
}
|
|
35454
|
-
|
|
35540
|
+
const canonicalDocId = latest.value.id;
|
|
35541
|
+
await storage2.delete(canonicalDocId.internalId);
|
|
35455
35542
|
const timestamp2 = this.docStore.allocateTimestamp();
|
|
35456
|
-
const entry = { ts: timestamp2, id:
|
|
35543
|
+
const entry = { ts: timestamp2, id: canonicalDocId, value: null, prev_ts: latest.ts };
|
|
35457
35544
|
await this.docStore.applyWrites([entry], new Set, "Error");
|
|
35458
|
-
this.context.recordLocalWrite(storageId, "_storage", null,
|
|
35545
|
+
this.context.recordLocalWrite(storageId, "_storage", null, canonicalDocId);
|
|
35459
35546
|
}
|
|
35460
35547
|
requireStorage() {
|
|
35461
35548
|
if (!this.storage) {
|
|
@@ -35658,16 +35745,17 @@ class SchedulerGateway3 {
|
|
|
35658
35745
|
if (!latest) {
|
|
35659
35746
|
throw new Error(`Scheduled job with id ${id} not found.`);
|
|
35660
35747
|
}
|
|
35748
|
+
const canonicalDocId = latest.value.id;
|
|
35661
35749
|
const newValue = {
|
|
35662
35750
|
...latest.value.value,
|
|
35663
35751
|
state: state ?? { kind: "canceled" }
|
|
35664
35752
|
};
|
|
35665
|
-
const resolvedDocument = { id:
|
|
35753
|
+
const resolvedDocument = { id: canonicalDocId, value: newValue };
|
|
35666
35754
|
const timestamp2 = this.docStore.allocateTimestamp();
|
|
35667
|
-
const entry = { ts: timestamp2, id:
|
|
35755
|
+
const entry = { ts: timestamp2, id: canonicalDocId, value: resolvedDocument, prev_ts: latest.ts };
|
|
35668
35756
|
await this.docStore.applyWrites([entry], new Set, "Error");
|
|
35669
|
-
const tableName = await resolveTableName3(
|
|
35670
|
-
this.context.recordLocalWrite(id, tableName, resolvedDocument.value,
|
|
35757
|
+
const tableName = await resolveTableName3(canonicalDocId, this.context.tableRegistry);
|
|
35758
|
+
this.context.recordLocalWrite(id, tableName, resolvedDocument.value, canonicalDocId);
|
|
35671
35759
|
}
|
|
35672
35760
|
}
|
|
35673
35761
|
init_context_storage3();
|
|
@@ -35879,13 +35967,14 @@ class DatabaseSyscalls3 {
|
|
|
35879
35967
|
if (!latest) {
|
|
35880
35968
|
throw new Error(`Document with id ${id} not found.`);
|
|
35881
35969
|
}
|
|
35970
|
+
const canonicalDocId = latest.value.id;
|
|
35882
35971
|
const timestamp2 = this.docStore.allocateTimestamp();
|
|
35883
|
-
const entry = { ts: timestamp2, id:
|
|
35972
|
+
const entry = { ts: timestamp2, id: canonicalDocId, value: null, prev_ts: latest.ts };
|
|
35884
35973
|
const indexes = await this.schemaService.getAllIndexesForTable(bareTableName);
|
|
35885
|
-
const indexUpdates = generateIndexUpdates3(fullTableName,
|
|
35974
|
+
const indexUpdates = generateIndexUpdates3(fullTableName, canonicalDocId, null, latest.value.value, indexes);
|
|
35886
35975
|
const indexEntries = new Set(indexUpdates.map((update) => ({ ts: timestamp2, update })));
|
|
35887
35976
|
await this.docStore.applyWrites([entry], indexEntries, "Error");
|
|
35888
|
-
this.context.recordLocalWrite(id, fullTableName, null,
|
|
35977
|
+
this.context.recordLocalWrite(id, fullTableName, null, canonicalDocId);
|
|
35889
35978
|
return {};
|
|
35890
35979
|
}
|
|
35891
35980
|
async handleShallowMerge(args) {
|
|
@@ -35911,6 +36000,7 @@ class DatabaseSyscalls3 {
|
|
|
35911
36000
|
if (!latest) {
|
|
35912
36001
|
throw new Error(`Document with id ${id} not found.`);
|
|
35913
36002
|
}
|
|
36003
|
+
const canonicalDocId = latest.value.id;
|
|
35914
36004
|
const existingValue = latest.value.value;
|
|
35915
36005
|
const newValue = { ...existingValue };
|
|
35916
36006
|
if (typeof value === "object" && value !== null && "$undefined" in value) {
|
|
@@ -35937,14 +36027,14 @@ class DatabaseSyscalls3 {
|
|
|
35937
36027
|
}
|
|
35938
36028
|
}
|
|
35939
36029
|
await this.schemaService.validate(bareTableName, newValue);
|
|
35940
|
-
const resolvedDocument = { id:
|
|
36030
|
+
const resolvedDocument = { id: canonicalDocId, value: newValue };
|
|
35941
36031
|
const timestamp2 = this.docStore.allocateTimestamp();
|
|
35942
|
-
const entry = { ts: timestamp2, id:
|
|
36032
|
+
const entry = { ts: timestamp2, id: canonicalDocId, value: resolvedDocument, prev_ts: latest.ts };
|
|
35943
36033
|
const indexes = await this.schemaService.getAllIndexesForTable(bareTableName);
|
|
35944
|
-
const indexUpdates = generateIndexUpdates3(fullTableName,
|
|
36034
|
+
const indexUpdates = generateIndexUpdates3(fullTableName, canonicalDocId, resolvedDocument.value, existingValue, indexes);
|
|
35945
36035
|
const indexEntries = new Set(indexUpdates.map((update) => ({ ts: timestamp2, update })));
|
|
35946
36036
|
await this.docStore.applyWrites([entry], indexEntries, "Error");
|
|
35947
|
-
this.context.recordLocalWrite(id, fullTableName, resolvedDocument.value,
|
|
36037
|
+
this.context.recordLocalWrite(id, fullTableName, resolvedDocument.value, canonicalDocId);
|
|
35948
36038
|
return {};
|
|
35949
36039
|
}
|
|
35950
36040
|
async handleReplace(args) {
|
|
@@ -35966,17 +36056,18 @@ class DatabaseSyscalls3 {
|
|
|
35966
36056
|
if (!latest) {
|
|
35967
36057
|
throw new Error(`Document with id ${id} not found.`);
|
|
35968
36058
|
}
|
|
36059
|
+
const canonicalDocId = latest.value.id;
|
|
35969
36060
|
const { _id, _creationTime } = latest.value.value;
|
|
35970
36061
|
const newValue = { ...replaceValue, _id, _creationTime };
|
|
35971
36062
|
await this.schemaService.validate(bareTableName, newValue);
|
|
35972
|
-
const resolvedDocument = { id:
|
|
36063
|
+
const resolvedDocument = { id: canonicalDocId, value: newValue };
|
|
35973
36064
|
const timestamp2 = this.docStore.allocateTimestamp();
|
|
35974
|
-
const entry = { ts: timestamp2, id:
|
|
36065
|
+
const entry = { ts: timestamp2, id: canonicalDocId, value: resolvedDocument, prev_ts: latest.ts };
|
|
35975
36066
|
const indexes = await this.schemaService.getAllIndexesForTable(bareTableName);
|
|
35976
|
-
const indexUpdates = generateIndexUpdates3(fullTableName,
|
|
36067
|
+
const indexUpdates = generateIndexUpdates3(fullTableName, canonicalDocId, resolvedDocument.value, latest.value.value, indexes);
|
|
35977
36068
|
const indexEntries = new Set(indexUpdates.map((update) => ({ ts: timestamp2, update })));
|
|
35978
36069
|
await this.docStore.applyWrites([entry], indexEntries, "Error");
|
|
35979
|
-
this.context.recordLocalWrite(id, fullTableName, newValue,
|
|
36070
|
+
this.context.recordLocalWrite(id, fullTableName, newValue, canonicalDocId);
|
|
35980
36071
|
return {};
|
|
35981
36072
|
}
|
|
35982
36073
|
}
|
|
@@ -41483,6 +41574,12 @@ function parseDocumentIdKey3(key) {
|
|
|
41483
41574
|
const internalId = key.substring(colonIndex + 1);
|
|
41484
41575
|
if (!table || !internalId)
|
|
41485
41576
|
return null;
|
|
41577
|
+
if (table.startsWith("#")) {
|
|
41578
|
+
const tableNumber = Number.parseInt(table.slice(1), 10);
|
|
41579
|
+
if (Number.isInteger(tableNumber) && tableNumber > 0) {
|
|
41580
|
+
return { table, internalId, tableNumber };
|
|
41581
|
+
}
|
|
41582
|
+
}
|
|
41486
41583
|
return { table, internalId };
|
|
41487
41584
|
}
|
|
41488
41585
|
var Order4;
|
|
@@ -41992,7 +42089,7 @@ async function validateReadSetForCommit3(docstore, readChecks, writtenDocKeys) {
|
|
|
41992
42089
|
await validateTableScanRead3(docstore, readEntry.tableId, readEntry.documentIds, writtenDocKeys);
|
|
41993
42090
|
continue;
|
|
41994
42091
|
}
|
|
41995
|
-
await validateIndexRangeRead3(docstore, readEntry.indexId, readEntry.startKey, readEntry.endKey, readEntry.documentIds, writtenDocKeys);
|
|
42092
|
+
await validateIndexRangeRead3(docstore, readEntry.indexId, readEntry.startKey, readEntry.endKey, readEntry.readTimestamp, readEntry.documentIds, writtenDocKeys);
|
|
41996
42093
|
}
|
|
41997
42094
|
}
|
|
41998
42095
|
async function validateDocumentRead3(docstore, key, readVersion, writtenDocKeys) {
|
|
@@ -42036,11 +42133,12 @@ async function validateTableScanRead3(docstore, tableId, readDocumentIds, writte
|
|
|
42036
42133
|
}
|
|
42037
42134
|
}
|
|
42038
42135
|
}
|
|
42039
|
-
async function validateIndexRangeRead3(docstore, indexId, startKey, endKey, readDocumentIds, writtenDocKeys) {
|
|
42136
|
+
async function validateIndexRangeRead3(docstore, indexId, startKey, endKey, readTimestamp, readDocumentIds, writtenDocKeys) {
|
|
42040
42137
|
const { table } = decodeIndexId4(indexId);
|
|
42041
42138
|
const interval = { start: startKey, end: endKey };
|
|
42139
|
+
const validationReadTimestamp = resolveValidationReadTimestamp3(docstore, readTimestamp);
|
|
42042
42140
|
const currentDocIds = new Set;
|
|
42043
|
-
for await (const [, doc] of docstore.index_scan(indexId, table,
|
|
42141
|
+
for await (const [, doc] of docstore.index_scan(indexId, table, validationReadTimestamp, interval, Order4.Asc)) {
|
|
42044
42142
|
currentDocIds.add(documentIdKey3(doc.value.id));
|
|
42045
42143
|
}
|
|
42046
42144
|
for (const docId of currentDocIds) {
|
|
@@ -42054,6 +42152,13 @@ async function validateIndexRangeRead3(docstore, indexId, startKey, endKey, read
|
|
|
42054
42152
|
}
|
|
42055
42153
|
}
|
|
42056
42154
|
}
|
|
42155
|
+
function resolveValidationReadTimestamp3(docstore, minimumTimestamp) {
|
|
42156
|
+
const maybeDocStore = docstore;
|
|
42157
|
+
const oracleTimestamp = maybeDocStore.timestampOracle?.getCurrentTimestamp?.();
|
|
42158
|
+
const wallClockTimestamp = BigInt(Date.now());
|
|
42159
|
+
const latestKnownTimestamp = oracleTimestamp !== undefined && oracleTimestamp > wallClockTimestamp ? oracleTimestamp : wallClockTimestamp;
|
|
42160
|
+
return latestKnownTimestamp > minimumTimestamp ? latestKnownTimestamp : minimumTimestamp;
|
|
42161
|
+
}
|
|
42057
42162
|
|
|
42058
42163
|
class OccMutationTransaction3 {
|
|
42059
42164
|
docstore;
|
|
@@ -42658,7 +42763,6 @@ class KernelContext4 {
|
|
|
42658
42763
|
}
|
|
42659
42764
|
recordTableRead(tableName) {
|
|
42660
42765
|
if (this.mutationTransaction) {
|
|
42661
|
-
this.mutationTransaction.recordTableScan(stringToHex4(tableName), []);
|
|
42662
42766
|
return;
|
|
42663
42767
|
}
|
|
42664
42768
|
this.readLog.addTableScan(tableName);
|
|
@@ -42671,8 +42775,6 @@ class KernelContext4 {
|
|
|
42671
42775
|
}
|
|
42672
42776
|
recordIndexRange(tableName, indexDescriptor, startKey, endKey) {
|
|
42673
42777
|
if (this.mutationTransaction) {
|
|
42674
|
-
const indexId = indexKeyspaceId4(tableName, indexDescriptor);
|
|
42675
|
-
this.mutationTransaction.recordIndexRangeScan(indexId, startKey, endKey, []);
|
|
42676
42778
|
return;
|
|
42677
42779
|
}
|
|
42678
42780
|
this.readLog.addIndexRange(tableName, indexDescriptor, startKey, endKey);
|
|
@@ -42828,11 +42930,12 @@ class BlobStoreGateway4 {
|
|
|
42828
42930
|
if (!latest || latest.ts > this.context.snapshotTimestamp) {
|
|
42829
42931
|
return;
|
|
42830
42932
|
}
|
|
42831
|
-
|
|
42933
|
+
const canonicalDocId = latest.value.id;
|
|
42934
|
+
await storage2.delete(canonicalDocId.internalId);
|
|
42832
42935
|
const timestamp2 = this.docStore.allocateTimestamp();
|
|
42833
|
-
const entry = { ts: timestamp2, id:
|
|
42936
|
+
const entry = { ts: timestamp2, id: canonicalDocId, value: null, prev_ts: latest.ts };
|
|
42834
42937
|
await this.docStore.applyWrites([entry], new Set, "Error");
|
|
42835
|
-
this.context.recordLocalWrite(storageId, "_storage", null,
|
|
42938
|
+
this.context.recordLocalWrite(storageId, "_storage", null, canonicalDocId);
|
|
42836
42939
|
}
|
|
42837
42940
|
requireStorage() {
|
|
42838
42941
|
if (!this.storage) {
|
|
@@ -43035,16 +43138,17 @@ class SchedulerGateway4 {
|
|
|
43035
43138
|
if (!latest) {
|
|
43036
43139
|
throw new Error(`Scheduled job with id ${id} not found.`);
|
|
43037
43140
|
}
|
|
43141
|
+
const canonicalDocId = latest.value.id;
|
|
43038
43142
|
const newValue = {
|
|
43039
43143
|
...latest.value.value,
|
|
43040
43144
|
state: state ?? { kind: "canceled" }
|
|
43041
43145
|
};
|
|
43042
|
-
const resolvedDocument = { id:
|
|
43146
|
+
const resolvedDocument = { id: canonicalDocId, value: newValue };
|
|
43043
43147
|
const timestamp2 = this.docStore.allocateTimestamp();
|
|
43044
|
-
const entry = { ts: timestamp2, id:
|
|
43148
|
+
const entry = { ts: timestamp2, id: canonicalDocId, value: resolvedDocument, prev_ts: latest.ts };
|
|
43045
43149
|
await this.docStore.applyWrites([entry], new Set, "Error");
|
|
43046
|
-
const tableName = await resolveTableName4(
|
|
43047
|
-
this.context.recordLocalWrite(id, tableName, resolvedDocument.value,
|
|
43150
|
+
const tableName = await resolveTableName4(canonicalDocId, this.context.tableRegistry);
|
|
43151
|
+
this.context.recordLocalWrite(id, tableName, resolvedDocument.value, canonicalDocId);
|
|
43048
43152
|
}
|
|
43049
43153
|
}
|
|
43050
43154
|
init_context_storage4();
|
|
@@ -43255,13 +43359,14 @@ class DatabaseSyscalls4 {
|
|
|
43255
43359
|
if (!latest) {
|
|
43256
43360
|
throw new Error(`Document with id ${id} not found.`);
|
|
43257
43361
|
}
|
|
43362
|
+
const canonicalDocId = latest.value.id;
|
|
43258
43363
|
const timestamp2 = this.docStore.allocateTimestamp();
|
|
43259
|
-
const entry = { ts: timestamp2, id:
|
|
43364
|
+
const entry = { ts: timestamp2, id: canonicalDocId, value: null, prev_ts: latest.ts };
|
|
43260
43365
|
const indexes = await this.schemaService.getAllIndexesForTable(bareTableName);
|
|
43261
|
-
const indexUpdates = generateIndexUpdates4(fullTableName,
|
|
43366
|
+
const indexUpdates = generateIndexUpdates4(fullTableName, canonicalDocId, null, latest.value.value, indexes);
|
|
43262
43367
|
const indexEntries = new Set(indexUpdates.map((update) => ({ ts: timestamp2, update })));
|
|
43263
43368
|
await this.docStore.applyWrites([entry], indexEntries, "Error");
|
|
43264
|
-
this.context.recordLocalWrite(id, fullTableName, null,
|
|
43369
|
+
this.context.recordLocalWrite(id, fullTableName, null, canonicalDocId);
|
|
43265
43370
|
return {};
|
|
43266
43371
|
}
|
|
43267
43372
|
async handleShallowMerge(args) {
|
|
@@ -43287,6 +43392,7 @@ class DatabaseSyscalls4 {
|
|
|
43287
43392
|
if (!latest) {
|
|
43288
43393
|
throw new Error(`Document with id ${id} not found.`);
|
|
43289
43394
|
}
|
|
43395
|
+
const canonicalDocId = latest.value.id;
|
|
43290
43396
|
const existingValue = latest.value.value;
|
|
43291
43397
|
const newValue = { ...existingValue };
|
|
43292
43398
|
if (typeof value === "object" && value !== null && "$undefined" in value) {
|
|
@@ -43313,14 +43419,14 @@ class DatabaseSyscalls4 {
|
|
|
43313
43419
|
}
|
|
43314
43420
|
}
|
|
43315
43421
|
await this.schemaService.validate(bareTableName, newValue);
|
|
43316
|
-
const resolvedDocument = { id:
|
|
43422
|
+
const resolvedDocument = { id: canonicalDocId, value: newValue };
|
|
43317
43423
|
const timestamp2 = this.docStore.allocateTimestamp();
|
|
43318
|
-
const entry = { ts: timestamp2, id:
|
|
43424
|
+
const entry = { ts: timestamp2, id: canonicalDocId, value: resolvedDocument, prev_ts: latest.ts };
|
|
43319
43425
|
const indexes = await this.schemaService.getAllIndexesForTable(bareTableName);
|
|
43320
|
-
const indexUpdates = generateIndexUpdates4(fullTableName,
|
|
43426
|
+
const indexUpdates = generateIndexUpdates4(fullTableName, canonicalDocId, resolvedDocument.value, existingValue, indexes);
|
|
43321
43427
|
const indexEntries = new Set(indexUpdates.map((update) => ({ ts: timestamp2, update })));
|
|
43322
43428
|
await this.docStore.applyWrites([entry], indexEntries, "Error");
|
|
43323
|
-
this.context.recordLocalWrite(id, fullTableName, resolvedDocument.value,
|
|
43429
|
+
this.context.recordLocalWrite(id, fullTableName, resolvedDocument.value, canonicalDocId);
|
|
43324
43430
|
return {};
|
|
43325
43431
|
}
|
|
43326
43432
|
async handleReplace(args) {
|
|
@@ -43342,17 +43448,18 @@ class DatabaseSyscalls4 {
|
|
|
43342
43448
|
if (!latest) {
|
|
43343
43449
|
throw new Error(`Document with id ${id} not found.`);
|
|
43344
43450
|
}
|
|
43451
|
+
const canonicalDocId = latest.value.id;
|
|
43345
43452
|
const { _id, _creationTime } = latest.value.value;
|
|
43346
43453
|
const newValue = { ...replaceValue, _id, _creationTime };
|
|
43347
43454
|
await this.schemaService.validate(bareTableName, newValue);
|
|
43348
|
-
const resolvedDocument = { id:
|
|
43455
|
+
const resolvedDocument = { id: canonicalDocId, value: newValue };
|
|
43349
43456
|
const timestamp2 = this.docStore.allocateTimestamp();
|
|
43350
|
-
const entry = { ts: timestamp2, id:
|
|
43457
|
+
const entry = { ts: timestamp2, id: canonicalDocId, value: resolvedDocument, prev_ts: latest.ts };
|
|
43351
43458
|
const indexes = await this.schemaService.getAllIndexesForTable(bareTableName);
|
|
43352
|
-
const indexUpdates = generateIndexUpdates4(fullTableName,
|
|
43459
|
+
const indexUpdates = generateIndexUpdates4(fullTableName, canonicalDocId, resolvedDocument.value, latest.value.value, indexes);
|
|
43353
43460
|
const indexEntries = new Set(indexUpdates.map((update) => ({ ts: timestamp2, update })));
|
|
43354
43461
|
await this.docStore.applyWrites([entry], indexEntries, "Error");
|
|
43355
|
-
this.context.recordLocalWrite(id, fullTableName, newValue,
|
|
43462
|
+
this.context.recordLocalWrite(id, fullTableName, newValue, canonicalDocId);
|
|
43356
43463
|
return {};
|
|
43357
43464
|
}
|
|
43358
43465
|
}
|
|
@@ -46454,6 +46561,7 @@ class SyncProtocolHandler2 {
|
|
|
46454
46561
|
rateLimitWindowMs;
|
|
46455
46562
|
operationTimeoutMs;
|
|
46456
46563
|
maxActiveQueriesPerSession;
|
|
46564
|
+
lastObservedWriteTimestamp = 0n;
|
|
46457
46565
|
constructor(instanceName, udfExecutor, options) {
|
|
46458
46566
|
this.udfExecutor = udfExecutor;
|
|
46459
46567
|
this.instanceName = instanceName;
|
|
@@ -46477,6 +46585,22 @@ class SyncProtocolHandler2 {
|
|
|
46477
46585
|
onPing: (session) => this.sendPing(session)
|
|
46478
46586
|
});
|
|
46479
46587
|
}
|
|
46588
|
+
resolveWriteTimestamp(commitTimestamp, snapshotTimestamp) {
|
|
46589
|
+
const wallClock = BigInt(Date.now());
|
|
46590
|
+
const monotonicFloor = this.lastObservedWriteTimestamp + 1n;
|
|
46591
|
+
let resolved = wallClock;
|
|
46592
|
+
if (commitTimestamp !== undefined && commitTimestamp > resolved) {
|
|
46593
|
+
resolved = commitTimestamp;
|
|
46594
|
+
}
|
|
46595
|
+
if (snapshotTimestamp !== undefined && snapshotTimestamp > resolved) {
|
|
46596
|
+
resolved = snapshotTimestamp;
|
|
46597
|
+
}
|
|
46598
|
+
if (monotonicFloor > resolved) {
|
|
46599
|
+
resolved = monotonicFloor;
|
|
46600
|
+
}
|
|
46601
|
+
this.lastObservedWriteTimestamp = resolved;
|
|
46602
|
+
return resolved;
|
|
46603
|
+
}
|
|
46480
46604
|
createSession(sessionId, websocket) {
|
|
46481
46605
|
const session = new SyncSession2(websocket);
|
|
46482
46606
|
this.sessions.set(sessionId, session);
|
|
@@ -46559,11 +46683,11 @@ class SyncProtocolHandler2 {
|
|
|
46559
46683
|
return assertNever2(message22);
|
|
46560
46684
|
}
|
|
46561
46685
|
}
|
|
46562
|
-
async notifyWrites(writtenRanges, writtenTables, commitTimestamp) {
|
|
46686
|
+
async notifyWrites(writtenRanges, writtenTables, commitTimestamp, snapshotTimestamp) {
|
|
46563
46687
|
const ranges = writtenRanges ? writtenRanges.map(deserializeKeyRange4) : convertTablesToRanges2(writtenTables);
|
|
46564
46688
|
this.logRanges("/notify", ranges, { writtenTables });
|
|
46565
46689
|
if (ranges.length > 0) {
|
|
46566
|
-
const ts = commitTimestamp
|
|
46690
|
+
const ts = this.resolveWriteTimestamp(commitTimestamp, snapshotTimestamp);
|
|
46567
46691
|
this.subscriptionManager.recordWrites(ranges, ts);
|
|
46568
46692
|
await this.broadcastUpdates(ranges);
|
|
46569
46693
|
}
|
|
@@ -46661,8 +46785,8 @@ class SyncProtocolHandler2 {
|
|
|
46661
46785
|
if (message22.componentPath && session.auth.tokenType !== "Admin" && session.auth.tokenType !== "System") {
|
|
46662
46786
|
throw new Error("Only admin or system auth can execute component functions");
|
|
46663
46787
|
}
|
|
46664
|
-
const { result, writtenRanges, writtenTables, commitTimestamp, logLines } = await this.udfExecutor.executeMutation(message22.udfPath, message22.args[0] ?? {}, session.auth, message22.componentPath);
|
|
46665
|
-
const now = commitTimestamp
|
|
46788
|
+
const { result, writtenRanges, writtenTables, commitTimestamp, snapshotTimestamp, logLines } = await this.udfExecutor.executeMutation(message22.udfPath, message22.args[0] ?? {}, session.auth, message22.componentPath);
|
|
46789
|
+
const now = this.resolveWriteTimestamp(commitTimestamp, snapshotTimestamp);
|
|
46666
46790
|
const successResponse = {
|
|
46667
46791
|
type: "MutationResponse",
|
|
46668
46792
|
requestId: message22.requestId,
|
|
@@ -46707,8 +46831,8 @@ class SyncProtocolHandler2 {
|
|
|
46707
46831
|
if (message22.componentPath && session.auth.tokenType !== "Admin" && session.auth.tokenType !== "System") {
|
|
46708
46832
|
throw new Error("Only admin or system auth can mutate component functions");
|
|
46709
46833
|
}
|
|
46710
|
-
const { result, writtenRanges, writtenTables, commitTimestamp, logLines } = await this.udfExecutor.executeAction(message22.udfPath, message22.args[0] ?? {}, session.auth, message22.componentPath);
|
|
46711
|
-
const now = commitTimestamp
|
|
46834
|
+
const { result, writtenRanges, writtenTables, commitTimestamp, snapshotTimestamp, logLines } = await this.udfExecutor.executeAction(message22.udfPath, message22.args[0] ?? {}, session.auth, message22.componentPath);
|
|
46835
|
+
const now = this.resolveWriteTimestamp(commitTimestamp, snapshotTimestamp);
|
|
46712
46836
|
const successResponse = {
|
|
46713
46837
|
type: "ActionResponse",
|
|
46714
46838
|
requestId: message22.requestId,
|