@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
|
@@ -24,6 +24,12 @@ function parseDocumentIdKey(key) {
|
|
|
24
24
|
const internalId = key.substring(colonIndex + 1);
|
|
25
25
|
if (!table || !internalId)
|
|
26
26
|
return null;
|
|
27
|
+
if (table.startsWith("#")) {
|
|
28
|
+
const tableNumber = Number.parseInt(table.slice(1), 10);
|
|
29
|
+
if (Number.isInteger(tableNumber) && tableNumber > 0) {
|
|
30
|
+
return { table, internalId, tableNumber };
|
|
31
|
+
}
|
|
32
|
+
}
|
|
27
33
|
return { table, internalId };
|
|
28
34
|
}
|
|
29
35
|
var Order;
|
|
@@ -9103,7 +9109,6 @@ class KernelContext {
|
|
|
9103
9109
|
}
|
|
9104
9110
|
recordTableRead(tableName) {
|
|
9105
9111
|
if (this.mutationTransaction) {
|
|
9106
|
-
this.mutationTransaction.recordTableScan(stringToHex(tableName), []);
|
|
9107
9112
|
return;
|
|
9108
9113
|
}
|
|
9109
9114
|
this.readLog.addTableScan(tableName);
|
|
@@ -9116,8 +9121,6 @@ class KernelContext {
|
|
|
9116
9121
|
}
|
|
9117
9122
|
recordIndexRange(tableName, indexDescriptor, startKey, endKey) {
|
|
9118
9123
|
if (this.mutationTransaction) {
|
|
9119
|
-
const indexId = indexKeyspaceId(tableName, indexDescriptor);
|
|
9120
|
-
this.mutationTransaction.recordIndexRangeScan(indexId, startKey, endKey, []);
|
|
9121
9124
|
return;
|
|
9122
9125
|
}
|
|
9123
9126
|
this.readLog.addIndexRange(tableName, indexDescriptor, startKey, endKey);
|
|
@@ -9273,11 +9276,12 @@ class BlobStoreGateway {
|
|
|
9273
9276
|
if (!latest || latest.ts > this.context.snapshotTimestamp) {
|
|
9274
9277
|
return;
|
|
9275
9278
|
}
|
|
9276
|
-
|
|
9279
|
+
const canonicalDocId = latest.value.id;
|
|
9280
|
+
await storage2.delete(canonicalDocId.internalId);
|
|
9277
9281
|
const timestamp2 = this.docStore.allocateTimestamp();
|
|
9278
|
-
const entry = { ts: timestamp2, id:
|
|
9282
|
+
const entry = { ts: timestamp2, id: canonicalDocId, value: null, prev_ts: latest.ts };
|
|
9279
9283
|
await this.docStore.applyWrites([entry], new Set, "Error");
|
|
9280
|
-
this.context.recordLocalWrite(storageId, "_storage", null,
|
|
9284
|
+
this.context.recordLocalWrite(storageId, "_storage", null, canonicalDocId);
|
|
9281
9285
|
}
|
|
9282
9286
|
requireStorage() {
|
|
9283
9287
|
if (!this.storage) {
|
|
@@ -9480,16 +9484,17 @@ class SchedulerGateway {
|
|
|
9480
9484
|
if (!latest) {
|
|
9481
9485
|
throw new Error(`Scheduled job with id ${id} not found.`);
|
|
9482
9486
|
}
|
|
9487
|
+
const canonicalDocId = latest.value.id;
|
|
9483
9488
|
const newValue = {
|
|
9484
9489
|
...latest.value.value,
|
|
9485
9490
|
state: state ?? { kind: "canceled" }
|
|
9486
9491
|
};
|
|
9487
|
-
const resolvedDocument = { id:
|
|
9492
|
+
const resolvedDocument = { id: canonicalDocId, value: newValue };
|
|
9488
9493
|
const timestamp2 = this.docStore.allocateTimestamp();
|
|
9489
|
-
const entry = { ts: timestamp2, id:
|
|
9494
|
+
const entry = { ts: timestamp2, id: canonicalDocId, value: resolvedDocument, prev_ts: latest.ts };
|
|
9490
9495
|
await this.docStore.applyWrites([entry], new Set, "Error");
|
|
9491
|
-
const tableName = await resolveTableName(
|
|
9492
|
-
this.context.recordLocalWrite(id, tableName, resolvedDocument.value,
|
|
9496
|
+
const tableName = await resolveTableName(canonicalDocId, this.context.tableRegistry);
|
|
9497
|
+
this.context.recordLocalWrite(id, tableName, resolvedDocument.value, canonicalDocId);
|
|
9493
9498
|
}
|
|
9494
9499
|
}
|
|
9495
9500
|
init_context_storage();
|
|
@@ -9701,13 +9706,14 @@ class DatabaseSyscalls {
|
|
|
9701
9706
|
if (!latest) {
|
|
9702
9707
|
throw new Error(`Document with id ${id} not found.`);
|
|
9703
9708
|
}
|
|
9709
|
+
const canonicalDocId = latest.value.id;
|
|
9704
9710
|
const timestamp2 = this.docStore.allocateTimestamp();
|
|
9705
|
-
const entry = { ts: timestamp2, id:
|
|
9711
|
+
const entry = { ts: timestamp2, id: canonicalDocId, value: null, prev_ts: latest.ts };
|
|
9706
9712
|
const indexes = await this.schemaService.getAllIndexesForTable(bareTableName);
|
|
9707
|
-
const indexUpdates = generateIndexUpdates(fullTableName,
|
|
9713
|
+
const indexUpdates = generateIndexUpdates(fullTableName, canonicalDocId, null, latest.value.value, indexes);
|
|
9708
9714
|
const indexEntries = new Set(indexUpdates.map((update) => ({ ts: timestamp2, update })));
|
|
9709
9715
|
await this.docStore.applyWrites([entry], indexEntries, "Error");
|
|
9710
|
-
this.context.recordLocalWrite(id, fullTableName, null,
|
|
9716
|
+
this.context.recordLocalWrite(id, fullTableName, null, canonicalDocId);
|
|
9711
9717
|
return {};
|
|
9712
9718
|
}
|
|
9713
9719
|
async handleShallowMerge(args) {
|
|
@@ -9733,6 +9739,7 @@ class DatabaseSyscalls {
|
|
|
9733
9739
|
if (!latest) {
|
|
9734
9740
|
throw new Error(`Document with id ${id} not found.`);
|
|
9735
9741
|
}
|
|
9742
|
+
const canonicalDocId = latest.value.id;
|
|
9736
9743
|
const existingValue = latest.value.value;
|
|
9737
9744
|
const newValue = { ...existingValue };
|
|
9738
9745
|
if (typeof value === "object" && value !== null && "$undefined" in value) {
|
|
@@ -9759,14 +9766,14 @@ class DatabaseSyscalls {
|
|
|
9759
9766
|
}
|
|
9760
9767
|
}
|
|
9761
9768
|
await this.schemaService.validate(bareTableName, newValue);
|
|
9762
|
-
const resolvedDocument = { id:
|
|
9769
|
+
const resolvedDocument = { id: canonicalDocId, value: newValue };
|
|
9763
9770
|
const timestamp2 = this.docStore.allocateTimestamp();
|
|
9764
|
-
const entry = { ts: timestamp2, id:
|
|
9771
|
+
const entry = { ts: timestamp2, id: canonicalDocId, value: resolvedDocument, prev_ts: latest.ts };
|
|
9765
9772
|
const indexes = await this.schemaService.getAllIndexesForTable(bareTableName);
|
|
9766
|
-
const indexUpdates = generateIndexUpdates(fullTableName,
|
|
9773
|
+
const indexUpdates = generateIndexUpdates(fullTableName, canonicalDocId, resolvedDocument.value, existingValue, indexes);
|
|
9767
9774
|
const indexEntries = new Set(indexUpdates.map((update) => ({ ts: timestamp2, update })));
|
|
9768
9775
|
await this.docStore.applyWrites([entry], indexEntries, "Error");
|
|
9769
|
-
this.context.recordLocalWrite(id, fullTableName, resolvedDocument.value,
|
|
9776
|
+
this.context.recordLocalWrite(id, fullTableName, resolvedDocument.value, canonicalDocId);
|
|
9770
9777
|
return {};
|
|
9771
9778
|
}
|
|
9772
9779
|
async handleReplace(args) {
|
|
@@ -9788,17 +9795,18 @@ class DatabaseSyscalls {
|
|
|
9788
9795
|
if (!latest) {
|
|
9789
9796
|
throw new Error(`Document with id ${id} not found.`);
|
|
9790
9797
|
}
|
|
9798
|
+
const canonicalDocId = latest.value.id;
|
|
9791
9799
|
const { _id, _creationTime } = latest.value.value;
|
|
9792
9800
|
const newValue = { ...replaceValue, _id, _creationTime };
|
|
9793
9801
|
await this.schemaService.validate(bareTableName, newValue);
|
|
9794
|
-
const resolvedDocument = { id:
|
|
9802
|
+
const resolvedDocument = { id: canonicalDocId, value: newValue };
|
|
9795
9803
|
const timestamp2 = this.docStore.allocateTimestamp();
|
|
9796
|
-
const entry = { ts: timestamp2, id:
|
|
9804
|
+
const entry = { ts: timestamp2, id: canonicalDocId, value: resolvedDocument, prev_ts: latest.ts };
|
|
9797
9805
|
const indexes = await this.schemaService.getAllIndexesForTable(bareTableName);
|
|
9798
|
-
const indexUpdates = generateIndexUpdates(fullTableName,
|
|
9806
|
+
const indexUpdates = generateIndexUpdates(fullTableName, canonicalDocId, resolvedDocument.value, latest.value.value, indexes);
|
|
9799
9807
|
const indexEntries = new Set(indexUpdates.map((update) => ({ ts: timestamp2, update })));
|
|
9800
9808
|
await this.docStore.applyWrites([entry], indexEntries, "Error");
|
|
9801
|
-
this.context.recordLocalWrite(id, fullTableName, newValue,
|
|
9809
|
+
this.context.recordLocalWrite(id, fullTableName, newValue, canonicalDocId);
|
|
9802
9810
|
return {};
|
|
9803
9811
|
}
|
|
9804
9812
|
}
|
|
@@ -18124,7 +18132,6 @@ class KernelContext2 {
|
|
|
18124
18132
|
}
|
|
18125
18133
|
recordTableRead(tableName) {
|
|
18126
18134
|
if (this.mutationTransaction) {
|
|
18127
|
-
this.mutationTransaction.recordTableScan(stringToHex2(tableName), []);
|
|
18128
18135
|
return;
|
|
18129
18136
|
}
|
|
18130
18137
|
this.readLog.addTableScan(tableName);
|
|
@@ -18137,8 +18144,6 @@ class KernelContext2 {
|
|
|
18137
18144
|
}
|
|
18138
18145
|
recordIndexRange(tableName, indexDescriptor, startKey, endKey) {
|
|
18139
18146
|
if (this.mutationTransaction) {
|
|
18140
|
-
const indexId = indexKeyspaceId2(tableName, indexDescriptor);
|
|
18141
|
-
this.mutationTransaction.recordIndexRangeScan(indexId, startKey, endKey, []);
|
|
18142
18147
|
return;
|
|
18143
18148
|
}
|
|
18144
18149
|
this.readLog.addIndexRange(tableName, indexDescriptor, startKey, endKey);
|
|
@@ -18294,11 +18299,12 @@ class BlobStoreGateway2 {
|
|
|
18294
18299
|
if (!latest || latest.ts > this.context.snapshotTimestamp) {
|
|
18295
18300
|
return;
|
|
18296
18301
|
}
|
|
18297
|
-
|
|
18302
|
+
const canonicalDocId = latest.value.id;
|
|
18303
|
+
await storage2.delete(canonicalDocId.internalId);
|
|
18298
18304
|
const timestamp = this.docStore.allocateTimestamp();
|
|
18299
|
-
const entry = { ts: timestamp, id:
|
|
18305
|
+
const entry = { ts: timestamp, id: canonicalDocId, value: null, prev_ts: latest.ts };
|
|
18300
18306
|
await this.docStore.applyWrites([entry], new Set, "Error");
|
|
18301
|
-
this.context.recordLocalWrite(storageId, "_storage", null,
|
|
18307
|
+
this.context.recordLocalWrite(storageId, "_storage", null, canonicalDocId);
|
|
18302
18308
|
}
|
|
18303
18309
|
requireStorage() {
|
|
18304
18310
|
if (!this.storage) {
|
|
@@ -18501,16 +18507,17 @@ class SchedulerGateway2 {
|
|
|
18501
18507
|
if (!latest) {
|
|
18502
18508
|
throw new Error(`Scheduled job with id ${id} not found.`);
|
|
18503
18509
|
}
|
|
18510
|
+
const canonicalDocId = latest.value.id;
|
|
18504
18511
|
const newValue = {
|
|
18505
18512
|
...latest.value.value,
|
|
18506
18513
|
state: state ?? { kind: "canceled" }
|
|
18507
18514
|
};
|
|
18508
|
-
const resolvedDocument = { id:
|
|
18515
|
+
const resolvedDocument = { id: canonicalDocId, value: newValue };
|
|
18509
18516
|
const timestamp = this.docStore.allocateTimestamp();
|
|
18510
|
-
const entry = { ts: timestamp, id:
|
|
18517
|
+
const entry = { ts: timestamp, id: canonicalDocId, value: resolvedDocument, prev_ts: latest.ts };
|
|
18511
18518
|
await this.docStore.applyWrites([entry], new Set, "Error");
|
|
18512
|
-
const tableName = await resolveTableName2(
|
|
18513
|
-
this.context.recordLocalWrite(id, tableName, resolvedDocument.value,
|
|
18519
|
+
const tableName = await resolveTableName2(canonicalDocId, this.context.tableRegistry);
|
|
18520
|
+
this.context.recordLocalWrite(id, tableName, resolvedDocument.value, canonicalDocId);
|
|
18514
18521
|
}
|
|
18515
18522
|
}
|
|
18516
18523
|
|
|
@@ -18712,13 +18719,14 @@ class DatabaseSyscalls2 {
|
|
|
18712
18719
|
if (!latest) {
|
|
18713
18720
|
throw new Error(`Document with id ${id} not found.`);
|
|
18714
18721
|
}
|
|
18722
|
+
const canonicalDocId = latest.value.id;
|
|
18715
18723
|
const timestamp = this.docStore.allocateTimestamp();
|
|
18716
|
-
const entry = { ts: timestamp, id:
|
|
18724
|
+
const entry = { ts: timestamp, id: canonicalDocId, value: null, prev_ts: latest.ts };
|
|
18717
18725
|
const indexes = await this.schemaService.getAllIndexesForTable(bareTableName);
|
|
18718
|
-
const indexUpdates = generateIndexUpdates2(fullTableName,
|
|
18726
|
+
const indexUpdates = generateIndexUpdates2(fullTableName, canonicalDocId, null, latest.value.value, indexes);
|
|
18719
18727
|
const indexEntries = new Set(indexUpdates.map((update) => ({ ts: timestamp, update })));
|
|
18720
18728
|
await this.docStore.applyWrites([entry], indexEntries, "Error");
|
|
18721
|
-
this.context.recordLocalWrite(id, fullTableName, null,
|
|
18729
|
+
this.context.recordLocalWrite(id, fullTableName, null, canonicalDocId);
|
|
18722
18730
|
return {};
|
|
18723
18731
|
}
|
|
18724
18732
|
async handleShallowMerge(args) {
|
|
@@ -18744,6 +18752,7 @@ class DatabaseSyscalls2 {
|
|
|
18744
18752
|
if (!latest) {
|
|
18745
18753
|
throw new Error(`Document with id ${id} not found.`);
|
|
18746
18754
|
}
|
|
18755
|
+
const canonicalDocId = latest.value.id;
|
|
18747
18756
|
const existingValue = latest.value.value;
|
|
18748
18757
|
const newValue = { ...existingValue };
|
|
18749
18758
|
if (typeof value === "object" && value !== null && "$undefined" in value) {
|
|
@@ -18770,14 +18779,14 @@ class DatabaseSyscalls2 {
|
|
|
18770
18779
|
}
|
|
18771
18780
|
}
|
|
18772
18781
|
await this.schemaService.validate(bareTableName, newValue);
|
|
18773
|
-
const resolvedDocument = { id:
|
|
18782
|
+
const resolvedDocument = { id: canonicalDocId, value: newValue };
|
|
18774
18783
|
const timestamp = this.docStore.allocateTimestamp();
|
|
18775
|
-
const entry = { ts: timestamp, id:
|
|
18784
|
+
const entry = { ts: timestamp, id: canonicalDocId, value: resolvedDocument, prev_ts: latest.ts };
|
|
18776
18785
|
const indexes = await this.schemaService.getAllIndexesForTable(bareTableName);
|
|
18777
|
-
const indexUpdates = generateIndexUpdates2(fullTableName,
|
|
18786
|
+
const indexUpdates = generateIndexUpdates2(fullTableName, canonicalDocId, resolvedDocument.value, existingValue, indexes);
|
|
18778
18787
|
const indexEntries = new Set(indexUpdates.map((update) => ({ ts: timestamp, update })));
|
|
18779
18788
|
await this.docStore.applyWrites([entry], indexEntries, "Error");
|
|
18780
|
-
this.context.recordLocalWrite(id, fullTableName, resolvedDocument.value,
|
|
18789
|
+
this.context.recordLocalWrite(id, fullTableName, resolvedDocument.value, canonicalDocId);
|
|
18781
18790
|
return {};
|
|
18782
18791
|
}
|
|
18783
18792
|
async handleReplace(args) {
|
|
@@ -18799,17 +18808,18 @@ class DatabaseSyscalls2 {
|
|
|
18799
18808
|
if (!latest) {
|
|
18800
18809
|
throw new Error(`Document with id ${id} not found.`);
|
|
18801
18810
|
}
|
|
18811
|
+
const canonicalDocId = latest.value.id;
|
|
18802
18812
|
const { _id, _creationTime } = latest.value.value;
|
|
18803
18813
|
const newValue = { ...replaceValue, _id, _creationTime };
|
|
18804
18814
|
await this.schemaService.validate(bareTableName, newValue);
|
|
18805
|
-
const resolvedDocument = { id:
|
|
18815
|
+
const resolvedDocument = { id: canonicalDocId, value: newValue };
|
|
18806
18816
|
const timestamp = this.docStore.allocateTimestamp();
|
|
18807
|
-
const entry = { ts: timestamp, id:
|
|
18817
|
+
const entry = { ts: timestamp, id: canonicalDocId, value: resolvedDocument, prev_ts: latest.ts };
|
|
18808
18818
|
const indexes = await this.schemaService.getAllIndexesForTable(bareTableName);
|
|
18809
|
-
const indexUpdates = generateIndexUpdates2(fullTableName,
|
|
18819
|
+
const indexUpdates = generateIndexUpdates2(fullTableName, canonicalDocId, resolvedDocument.value, latest.value.value, indexes);
|
|
18810
18820
|
const indexEntries = new Set(indexUpdates.map((update) => ({ ts: timestamp, update })));
|
|
18811
18821
|
await this.docStore.applyWrites([entry], indexEntries, "Error");
|
|
18812
|
-
this.context.recordLocalWrite(id, fullTableName, newValue,
|
|
18822
|
+
this.context.recordLocalWrite(id, fullTableName, newValue, canonicalDocId);
|
|
18813
18823
|
return {};
|
|
18814
18824
|
}
|
|
18815
18825
|
}
|
|
@@ -19494,6 +19504,7 @@ class SyncProtocolHandler {
|
|
|
19494
19504
|
rateLimitWindowMs;
|
|
19495
19505
|
operationTimeoutMs;
|
|
19496
19506
|
maxActiveQueriesPerSession;
|
|
19507
|
+
lastObservedWriteTimestamp = 0n;
|
|
19497
19508
|
constructor(instanceName, udfExecutor, options) {
|
|
19498
19509
|
this.udfExecutor = udfExecutor;
|
|
19499
19510
|
this.instanceName = instanceName;
|
|
@@ -19517,6 +19528,22 @@ class SyncProtocolHandler {
|
|
|
19517
19528
|
onPing: (session) => this.sendPing(session)
|
|
19518
19529
|
});
|
|
19519
19530
|
}
|
|
19531
|
+
resolveWriteTimestamp(commitTimestamp, snapshotTimestamp) {
|
|
19532
|
+
const wallClock = BigInt(Date.now());
|
|
19533
|
+
const monotonicFloor = this.lastObservedWriteTimestamp + 1n;
|
|
19534
|
+
let resolved = wallClock;
|
|
19535
|
+
if (commitTimestamp !== undefined && commitTimestamp > resolved) {
|
|
19536
|
+
resolved = commitTimestamp;
|
|
19537
|
+
}
|
|
19538
|
+
if (snapshotTimestamp !== undefined && snapshotTimestamp > resolved) {
|
|
19539
|
+
resolved = snapshotTimestamp;
|
|
19540
|
+
}
|
|
19541
|
+
if (monotonicFloor > resolved) {
|
|
19542
|
+
resolved = monotonicFloor;
|
|
19543
|
+
}
|
|
19544
|
+
this.lastObservedWriteTimestamp = resolved;
|
|
19545
|
+
return resolved;
|
|
19546
|
+
}
|
|
19520
19547
|
createSession(sessionId, websocket) {
|
|
19521
19548
|
const session = new SyncSession(websocket);
|
|
19522
19549
|
this.sessions.set(sessionId, session);
|
|
@@ -19599,11 +19626,11 @@ class SyncProtocolHandler {
|
|
|
19599
19626
|
return assertNever(message2);
|
|
19600
19627
|
}
|
|
19601
19628
|
}
|
|
19602
|
-
async notifyWrites(writtenRanges, writtenTables, commitTimestamp) {
|
|
19629
|
+
async notifyWrites(writtenRanges, writtenTables, commitTimestamp, snapshotTimestamp) {
|
|
19603
19630
|
const ranges = writtenRanges ? writtenRanges.map(deserializeKeyRange2) : convertTablesToRanges(writtenTables);
|
|
19604
19631
|
this.logRanges("/notify", ranges, { writtenTables });
|
|
19605
19632
|
if (ranges.length > 0) {
|
|
19606
|
-
const ts = commitTimestamp
|
|
19633
|
+
const ts = this.resolveWriteTimestamp(commitTimestamp, snapshotTimestamp);
|
|
19607
19634
|
this.subscriptionManager.recordWrites(ranges, ts);
|
|
19608
19635
|
await this.broadcastUpdates(ranges);
|
|
19609
19636
|
}
|
|
@@ -19701,8 +19728,8 @@ class SyncProtocolHandler {
|
|
|
19701
19728
|
if (message2.componentPath && session.auth.tokenType !== "Admin" && session.auth.tokenType !== "System") {
|
|
19702
19729
|
throw new Error("Only admin or system auth can execute component functions");
|
|
19703
19730
|
}
|
|
19704
|
-
const { result, writtenRanges, writtenTables, commitTimestamp, logLines } = await this.udfExecutor.executeMutation(message2.udfPath, message2.args[0] ?? {}, session.auth, message2.componentPath);
|
|
19705
|
-
const now = commitTimestamp
|
|
19731
|
+
const { result, writtenRanges, writtenTables, commitTimestamp, snapshotTimestamp, logLines } = await this.udfExecutor.executeMutation(message2.udfPath, message2.args[0] ?? {}, session.auth, message2.componentPath);
|
|
19732
|
+
const now = this.resolveWriteTimestamp(commitTimestamp, snapshotTimestamp);
|
|
19706
19733
|
const successResponse = {
|
|
19707
19734
|
type: "MutationResponse",
|
|
19708
19735
|
requestId: message2.requestId,
|
|
@@ -19747,8 +19774,8 @@ class SyncProtocolHandler {
|
|
|
19747
19774
|
if (message2.componentPath && session.auth.tokenType !== "Admin" && session.auth.tokenType !== "System") {
|
|
19748
19775
|
throw new Error("Only admin or system auth can mutate component functions");
|
|
19749
19776
|
}
|
|
19750
|
-
const { result, writtenRanges, writtenTables, commitTimestamp, logLines } = await this.udfExecutor.executeAction(message2.udfPath, message2.args[0] ?? {}, session.auth, message2.componentPath);
|
|
19751
|
-
const now = commitTimestamp
|
|
19777
|
+
const { result, writtenRanges, writtenTables, commitTimestamp, snapshotTimestamp, logLines } = await this.udfExecutor.executeAction(message2.udfPath, message2.args[0] ?? {}, session.auth, message2.componentPath);
|
|
19778
|
+
const now = this.resolveWriteTimestamp(commitTimestamp, snapshotTimestamp);
|
|
19752
19779
|
const successResponse = {
|
|
19753
19780
|
type: "ActionResponse",
|
|
19754
19781
|
requestId: message2.requestId,
|
|
@@ -20104,7 +20131,8 @@ function createSyncUdfExecutor(adapter) {
|
|
|
20104
20131
|
writtenRanges: result.writtenRanges,
|
|
20105
20132
|
writtenTables: writtenTablesFromRanges(result.writtenRanges),
|
|
20106
20133
|
logLines: result.logLines,
|
|
20107
|
-
commitTimestamp: result.commitTimestamp
|
|
20134
|
+
commitTimestamp: result.commitTimestamp,
|
|
20135
|
+
snapshotTimestamp: result.snapshotTimestamp
|
|
20108
20136
|
};
|
|
20109
20137
|
},
|
|
20110
20138
|
executeAction: async (path, args, auth, componentPath) => {
|
|
@@ -20122,7 +20150,8 @@ function createSyncUdfExecutor(adapter) {
|
|
|
20122
20150
|
writtenRanges: result.writtenRanges,
|
|
20123
20151
|
writtenTables: writtenTablesFromRanges(result.writtenRanges),
|
|
20124
20152
|
logLines: result.logLines,
|
|
20125
|
-
commitTimestamp: result.commitTimestamp
|
|
20153
|
+
commitTimestamp: result.commitTimestamp,
|
|
20154
|
+
snapshotTimestamp: result.snapshotTimestamp
|
|
20126
20155
|
};
|
|
20127
20156
|
}
|
|
20128
20157
|
};
|
|
@@ -23636,7 +23665,7 @@ function rangeExpressionsToIndexBounds(expressions, indexFields) {
|
|
|
23636
23665
|
}
|
|
23637
23666
|
return { start, end };
|
|
23638
23667
|
}
|
|
23639
|
-
async function executeIndexQuery(docstore, tableName, indexName, indexFields, expressions, order, limit, cursor, snapshotTimestamp) {
|
|
23668
|
+
async function executeIndexQuery(docstore, tableName, indexName, indexFields, expressions, order, limit, cursor, snapshotTimestamp, onDocumentRead) {
|
|
23640
23669
|
const tableId = stringToHex3(tableName);
|
|
23641
23670
|
const indexId = stringToHex3(`${tableName}:${indexName}`);
|
|
23642
23671
|
const indexOrder = order === "asc" ? Order.Asc : Order.Desc;
|
|
@@ -23662,6 +23691,7 @@ async function executeIndexQuery(docstore, tableName, indexName, indexFields, ex
|
|
|
23662
23691
|
try {
|
|
23663
23692
|
const generator = docstore.index_scan(indexId, tableId, readTimestamp, interval, indexOrder);
|
|
23664
23693
|
for await (const [indexKey, document] of generator) {
|
|
23694
|
+
onDocumentRead?.(document);
|
|
23665
23695
|
const doc = document.value.value;
|
|
23666
23696
|
if (skipping) {
|
|
23667
23697
|
if (resumeIndexKey) {
|
|
@@ -24091,6 +24121,9 @@ class UncommittedWrites {
|
|
|
24091
24121
|
}
|
|
24092
24122
|
}
|
|
24093
24123
|
}
|
|
24124
|
+
// ../core/dist/query/query-runtime.js
|
|
24125
|
+
init_interface();
|
|
24126
|
+
|
|
24094
24127
|
// ../core/dist/query/planner.js
|
|
24095
24128
|
init_values3();
|
|
24096
24129
|
init_interface4();
|
|
@@ -24460,13 +24493,27 @@ class QueryRuntime {
|
|
|
24460
24493
|
return paginateByCursor(sortedResults, cursor, limit);
|
|
24461
24494
|
}
|
|
24462
24495
|
async handleIndexRange(plan, cursor, limit) {
|
|
24463
|
-
|
|
24464
|
-
|
|
24496
|
+
const { start, end } = rangeExpressionsToIndexBounds(plan.expressions, plan.indexFields);
|
|
24497
|
+
const mutationTransaction = this.docStore.getTransaction();
|
|
24498
|
+
if (!mutationTransaction) {
|
|
24465
24499
|
this.context.recordIndexRange(plan.fullTableName, plan.indexDescriptor, start, end);
|
|
24466
24500
|
}
|
|
24501
|
+
const observedDocuments = mutationTransaction ? new Map : null;
|
|
24467
24502
|
let paginationResult;
|
|
24468
24503
|
try {
|
|
24469
|
-
const indexResult = await executeIndexQuery(this.docStore.getDocStore(), plan.fullTableName, plan.indexDescriptor, plan.indexFields, plan.expressions, plan.order, limit, cursor, this.context.snapshotTimestamp)
|
|
24504
|
+
const indexResult = await executeIndexQuery(this.docStore.getDocStore(), plan.fullTableName, plan.indexDescriptor, plan.indexFields, plan.expressions, plan.order, limit, cursor, this.context.snapshotTimestamp, (latestDoc) => {
|
|
24505
|
+
if (!observedDocuments) {
|
|
24506
|
+
return;
|
|
24507
|
+
}
|
|
24508
|
+
observedDocuments.set(documentIdKey(latestDoc.value.id), latestDoc);
|
|
24509
|
+
});
|
|
24510
|
+
if (mutationTransaction && observedDocuments) {
|
|
24511
|
+
const observed = Array.from(observedDocuments.values());
|
|
24512
|
+
mutationTransaction.recordIndexRangeScan(indexKeyspaceId3(plan.fullTableName, plan.indexDescriptor), start, end, observed);
|
|
24513
|
+
for (const doc of observed) {
|
|
24514
|
+
mutationTransaction.recordDocumentRead(doc.value.id, doc);
|
|
24515
|
+
}
|
|
24516
|
+
}
|
|
24470
24517
|
const uncommittedWrites = UncommittedWrites.fromContext(this.docStore.getTransaction(), this.context.getLocalWrites());
|
|
24471
24518
|
if (uncommittedWrites) {
|
|
24472
24519
|
const tableId = stringToHex3(plan.fullTableName);
|
|
@@ -24499,7 +24546,10 @@ class QueryRuntime {
|
|
|
24499
24546
|
return paginationResult;
|
|
24500
24547
|
}
|
|
24501
24548
|
async handleSearch(plan, _cursor, limit) {
|
|
24502
|
-
this.
|
|
24549
|
+
const mutationTransaction = this.docStore.getTransaction();
|
|
24550
|
+
if (!mutationTransaction) {
|
|
24551
|
+
this.context.recordTableRead(plan.fullTableName);
|
|
24552
|
+
}
|
|
24503
24553
|
const limitOperator = plan.query.operators?.find((operator) => ("limit" in operator));
|
|
24504
24554
|
const operatorLimit = limitOperator?.limit;
|
|
24505
24555
|
const combinedLimit = typeof limit === "number" && limit > 0 ? operatorLimit && operatorLimit > 0 ? Math.min(limit, operatorLimit) : limit : operatorLimit && operatorLimit > 0 ? operatorLimit : undefined;
|
|
@@ -24508,7 +24558,13 @@ class QueryRuntime {
|
|
|
24508
24558
|
throw new Error("DocStore does not support full-text search");
|
|
24509
24559
|
}
|
|
24510
24560
|
const searchResults = await rawDocStore.search(plan.indexIdHex, plan.searchTerm, plan.filterMap, { limit: combinedLimit });
|
|
24511
|
-
const
|
|
24561
|
+
const visibleResults = searchResults.filter(({ doc }) => doc.ts <= this.context.snapshotTimestamp);
|
|
24562
|
+
if (mutationTransaction) {
|
|
24563
|
+
for (const { doc } of visibleResults) {
|
|
24564
|
+
mutationTransaction.recordDocumentRead(doc.value.id, doc);
|
|
24565
|
+
}
|
|
24566
|
+
}
|
|
24567
|
+
const documents = visibleResults.map(({ doc, score }) => ({
|
|
24512
24568
|
...doc.value.value,
|
|
24513
24569
|
_score: score
|
|
24514
24570
|
}));
|
|
@@ -24695,6 +24751,7 @@ class AccessLog3 {
|
|
|
24695
24751
|
return this.ranges.getRanges().map(serializeKeyRange3);
|
|
24696
24752
|
}
|
|
24697
24753
|
}
|
|
24754
|
+
|
|
24698
24755
|
// ../core/dist/tables/memory-table-registry.js
|
|
24699
24756
|
init_interface4();
|
|
24700
24757
|
|
|
@@ -24832,7 +24889,6 @@ class KernelContext3 {
|
|
|
24832
24889
|
}
|
|
24833
24890
|
recordTableRead(tableName) {
|
|
24834
24891
|
if (this.mutationTransaction) {
|
|
24835
|
-
this.mutationTransaction.recordTableScan(stringToHex3(tableName), []);
|
|
24836
24892
|
return;
|
|
24837
24893
|
}
|
|
24838
24894
|
this.readLog.addTableScan(tableName);
|
|
@@ -24845,8 +24901,6 @@ class KernelContext3 {
|
|
|
24845
24901
|
}
|
|
24846
24902
|
recordIndexRange(tableName, indexDescriptor, startKey, endKey) {
|
|
24847
24903
|
if (this.mutationTransaction) {
|
|
24848
|
-
const indexId = indexKeyspaceId3(tableName, indexDescriptor);
|
|
24849
|
-
this.mutationTransaction.recordIndexRangeScan(indexId, startKey, endKey, []);
|
|
24850
24904
|
return;
|
|
24851
24905
|
}
|
|
24852
24906
|
this.readLog.addIndexRange(tableName, indexDescriptor, startKey, endKey);
|
|
@@ -25005,11 +25059,12 @@ class BlobStoreGateway3 {
|
|
|
25005
25059
|
if (!latest || latest.ts > this.context.snapshotTimestamp) {
|
|
25006
25060
|
return;
|
|
25007
25061
|
}
|
|
25008
|
-
|
|
25062
|
+
const canonicalDocId = latest.value.id;
|
|
25063
|
+
await storage2.delete(canonicalDocId.internalId);
|
|
25009
25064
|
const timestamp2 = this.docStore.allocateTimestamp();
|
|
25010
|
-
const entry = { ts: timestamp2, id:
|
|
25065
|
+
const entry = { ts: timestamp2, id: canonicalDocId, value: null, prev_ts: latest.ts };
|
|
25011
25066
|
await this.docStore.applyWrites([entry], new Set, "Error");
|
|
25012
|
-
this.context.recordLocalWrite(storageId, "_storage", null,
|
|
25067
|
+
this.context.recordLocalWrite(storageId, "_storage", null, canonicalDocId);
|
|
25013
25068
|
}
|
|
25014
25069
|
requireStorage() {
|
|
25015
25070
|
if (!this.storage) {
|
|
@@ -25216,16 +25271,17 @@ class SchedulerGateway3 {
|
|
|
25216
25271
|
if (!latest) {
|
|
25217
25272
|
throw new Error(`Scheduled job with id ${id} not found.`);
|
|
25218
25273
|
}
|
|
25274
|
+
const canonicalDocId = latest.value.id;
|
|
25219
25275
|
const newValue = {
|
|
25220
25276
|
...latest.value.value,
|
|
25221
25277
|
state: state ?? { kind: "canceled" }
|
|
25222
25278
|
};
|
|
25223
|
-
const resolvedDocument = { id:
|
|
25279
|
+
const resolvedDocument = { id: canonicalDocId, value: newValue };
|
|
25224
25280
|
const timestamp2 = this.docStore.allocateTimestamp();
|
|
25225
|
-
const entry = { ts: timestamp2, id:
|
|
25281
|
+
const entry = { ts: timestamp2, id: canonicalDocId, value: resolvedDocument, prev_ts: latest.ts };
|
|
25226
25282
|
await this.docStore.applyWrites([entry], new Set, "Error");
|
|
25227
|
-
const tableName = await resolveTableName3(
|
|
25228
|
-
this.context.recordLocalWrite(id, tableName, resolvedDocument.value,
|
|
25283
|
+
const tableName = await resolveTableName3(canonicalDocId, this.context.tableRegistry);
|
|
25284
|
+
this.context.recordLocalWrite(id, tableName, resolvedDocument.value, canonicalDocId);
|
|
25229
25285
|
}
|
|
25230
25286
|
}
|
|
25231
25287
|
|
|
@@ -25449,13 +25505,14 @@ class DatabaseSyscalls3 {
|
|
|
25449
25505
|
if (!latest) {
|
|
25450
25506
|
throw new Error(`Document with id ${id} not found.`);
|
|
25451
25507
|
}
|
|
25508
|
+
const canonicalDocId = latest.value.id;
|
|
25452
25509
|
const timestamp2 = this.docStore.allocateTimestamp();
|
|
25453
|
-
const entry = { ts: timestamp2, id:
|
|
25510
|
+
const entry = { ts: timestamp2, id: canonicalDocId, value: null, prev_ts: latest.ts };
|
|
25454
25511
|
const indexes = await this.schemaService.getAllIndexesForTable(bareTableName);
|
|
25455
|
-
const indexUpdates = generateIndexUpdates3(fullTableName,
|
|
25512
|
+
const indexUpdates = generateIndexUpdates3(fullTableName, canonicalDocId, null, latest.value.value, indexes);
|
|
25456
25513
|
const indexEntries = new Set(indexUpdates.map((update) => ({ ts: timestamp2, update })));
|
|
25457
25514
|
await this.docStore.applyWrites([entry], indexEntries, "Error");
|
|
25458
|
-
this.context.recordLocalWrite(id, fullTableName, null,
|
|
25515
|
+
this.context.recordLocalWrite(id, fullTableName, null, canonicalDocId);
|
|
25459
25516
|
return {};
|
|
25460
25517
|
}
|
|
25461
25518
|
async handleShallowMerge(args) {
|
|
@@ -25481,6 +25538,7 @@ class DatabaseSyscalls3 {
|
|
|
25481
25538
|
if (!latest) {
|
|
25482
25539
|
throw new Error(`Document with id ${id} not found.`);
|
|
25483
25540
|
}
|
|
25541
|
+
const canonicalDocId = latest.value.id;
|
|
25484
25542
|
const existingValue = latest.value.value;
|
|
25485
25543
|
const newValue = { ...existingValue };
|
|
25486
25544
|
if (typeof value === "object" && value !== null && "$undefined" in value) {
|
|
@@ -25507,14 +25565,14 @@ class DatabaseSyscalls3 {
|
|
|
25507
25565
|
}
|
|
25508
25566
|
}
|
|
25509
25567
|
await this.schemaService.validate(bareTableName, newValue);
|
|
25510
|
-
const resolvedDocument = { id:
|
|
25568
|
+
const resolvedDocument = { id: canonicalDocId, value: newValue };
|
|
25511
25569
|
const timestamp2 = this.docStore.allocateTimestamp();
|
|
25512
|
-
const entry = { ts: timestamp2, id:
|
|
25570
|
+
const entry = { ts: timestamp2, id: canonicalDocId, value: resolvedDocument, prev_ts: latest.ts };
|
|
25513
25571
|
const indexes = await this.schemaService.getAllIndexesForTable(bareTableName);
|
|
25514
|
-
const indexUpdates = generateIndexUpdates3(fullTableName,
|
|
25572
|
+
const indexUpdates = generateIndexUpdates3(fullTableName, canonicalDocId, resolvedDocument.value, existingValue, indexes);
|
|
25515
25573
|
const indexEntries = new Set(indexUpdates.map((update) => ({ ts: timestamp2, update })));
|
|
25516
25574
|
await this.docStore.applyWrites([entry], indexEntries, "Error");
|
|
25517
|
-
this.context.recordLocalWrite(id, fullTableName, resolvedDocument.value,
|
|
25575
|
+
this.context.recordLocalWrite(id, fullTableName, resolvedDocument.value, canonicalDocId);
|
|
25518
25576
|
return {};
|
|
25519
25577
|
}
|
|
25520
25578
|
async handleReplace(args) {
|
|
@@ -25536,17 +25594,18 @@ class DatabaseSyscalls3 {
|
|
|
25536
25594
|
if (!latest) {
|
|
25537
25595
|
throw new Error(`Document with id ${id} not found.`);
|
|
25538
25596
|
}
|
|
25597
|
+
const canonicalDocId = latest.value.id;
|
|
25539
25598
|
const { _id, _creationTime } = latest.value.value;
|
|
25540
25599
|
const newValue = { ...replaceValue, _id, _creationTime };
|
|
25541
25600
|
await this.schemaService.validate(bareTableName, newValue);
|
|
25542
|
-
const resolvedDocument = { id:
|
|
25601
|
+
const resolvedDocument = { id: canonicalDocId, value: newValue };
|
|
25543
25602
|
const timestamp2 = this.docStore.allocateTimestamp();
|
|
25544
|
-
const entry = { ts: timestamp2, id:
|
|
25603
|
+
const entry = { ts: timestamp2, id: canonicalDocId, value: resolvedDocument, prev_ts: latest.ts };
|
|
25545
25604
|
const indexes = await this.schemaService.getAllIndexesForTable(bareTableName);
|
|
25546
|
-
const indexUpdates = generateIndexUpdates3(fullTableName,
|
|
25605
|
+
const indexUpdates = generateIndexUpdates3(fullTableName, canonicalDocId, resolvedDocument.value, latest.value.value, indexes);
|
|
25547
25606
|
const indexEntries = new Set(indexUpdates.map((update) => ({ ts: timestamp2, update })));
|
|
25548
25607
|
await this.docStore.applyWrites([entry], indexEntries, "Error");
|
|
25549
|
-
this.context.recordLocalWrite(id, fullTableName, newValue,
|
|
25608
|
+
this.context.recordLocalWrite(id, fullTableName, newValue, canonicalDocId);
|
|
25550
25609
|
return {};
|
|
25551
25610
|
}
|
|
25552
25611
|
}
|
|
@@ -25941,7 +26000,7 @@ async function validateReadSetForCommit(docstore, readChecks, writtenDocKeys) {
|
|
|
25941
26000
|
await validateTableScanRead(docstore, readEntry.tableId, readEntry.documentIds, writtenDocKeys);
|
|
25942
26001
|
continue;
|
|
25943
26002
|
}
|
|
25944
|
-
await validateIndexRangeRead(docstore, readEntry.indexId, readEntry.startKey, readEntry.endKey, readEntry.documentIds, writtenDocKeys);
|
|
26003
|
+
await validateIndexRangeRead(docstore, readEntry.indexId, readEntry.startKey, readEntry.endKey, readEntry.readTimestamp, readEntry.documentIds, writtenDocKeys);
|
|
25945
26004
|
}
|
|
25946
26005
|
}
|
|
25947
26006
|
async function validateDocumentRead(docstore, key, readVersion, writtenDocKeys) {
|
|
@@ -25985,11 +26044,12 @@ async function validateTableScanRead(docstore, tableId, readDocumentIds, written
|
|
|
25985
26044
|
}
|
|
25986
26045
|
}
|
|
25987
26046
|
}
|
|
25988
|
-
async function validateIndexRangeRead(docstore, indexId, startKey, endKey, readDocumentIds, writtenDocKeys) {
|
|
26047
|
+
async function validateIndexRangeRead(docstore, indexId, startKey, endKey, readTimestamp, readDocumentIds, writtenDocKeys) {
|
|
25989
26048
|
const { table } = decodeIndexId3(indexId);
|
|
25990
26049
|
const interval = { start: startKey, end: endKey };
|
|
26050
|
+
const validationReadTimestamp = resolveValidationReadTimestamp(docstore, readTimestamp);
|
|
25991
26051
|
const currentDocIds = new Set;
|
|
25992
|
-
for await (const [, doc] of docstore.index_scan(indexId, table,
|
|
26052
|
+
for await (const [, doc] of docstore.index_scan(indexId, table, validationReadTimestamp, interval, Order.Asc)) {
|
|
25993
26053
|
currentDocIds.add(documentIdKey(doc.value.id));
|
|
25994
26054
|
}
|
|
25995
26055
|
for (const docId of currentDocIds) {
|
|
@@ -26003,6 +26063,13 @@ async function validateIndexRangeRead(docstore, indexId, startKey, endKey, readD
|
|
|
26003
26063
|
}
|
|
26004
26064
|
}
|
|
26005
26065
|
}
|
|
26066
|
+
function resolveValidationReadTimestamp(docstore, minimumTimestamp) {
|
|
26067
|
+
const maybeDocStore = docstore;
|
|
26068
|
+
const oracleTimestamp = maybeDocStore.timestampOracle?.getCurrentTimestamp?.();
|
|
26069
|
+
const wallClockTimestamp = BigInt(Date.now());
|
|
26070
|
+
const latestKnownTimestamp = oracleTimestamp !== undefined && oracleTimestamp > wallClockTimestamp ? oracleTimestamp : wallClockTimestamp;
|
|
26071
|
+
return latestKnownTimestamp > minimumTimestamp ? latestKnownTimestamp : minimumTimestamp;
|
|
26072
|
+
}
|
|
26006
26073
|
|
|
26007
26074
|
// ../core/dist/transactor/occ-transaction.js
|
|
26008
26075
|
class OccMutationTransaction {
|
|
@@ -26573,7 +26640,7 @@ function runUdfMutation(docstore, fn, auth, storage2, requestId, udfExecutor, co
|
|
|
26573
26640
|
const savepoint = parentTransaction.createSavepoint();
|
|
26574
26641
|
const existingIdGenerator = idGeneratorContext3.getStore();
|
|
26575
26642
|
const idGenerator = existingIdGenerator ?? createDeterministicIdGenerator(seed);
|
|
26576
|
-
const nestedResult = transactionContext3.run(parentTransaction, () => idGeneratorContext3.run(idGenerator, () => runUdfAndGetLogs(docstore, fn, ops, auth, "mutation", storage2, seed, parentTransaction, udfExecutor, componentPath)));
|
|
26643
|
+
const nestedResult = Promise.resolve(transactionContext3.run(parentTransaction, () => idGeneratorContext3.run(idGenerator, () => runUdfAndGetLogs(docstore, fn, ops, auth, "mutation", storage2, seed, parentTransaction, udfExecutor, componentPath))));
|
|
26577
26644
|
return nestedResult.catch((error) => {
|
|
26578
26645
|
parentTransaction.restoreSavepoint(savepoint);
|
|
26579
26646
|
throw error;
|
|
@@ -26719,10 +26786,15 @@ class InlineUdfExecutor {
|
|
|
26719
26786
|
async executeHttp(request, auth, requestId) {
|
|
26720
26787
|
const url = new URL(request.url);
|
|
26721
26788
|
const runHttpUdf = async () => {
|
|
26722
|
-
|
|
26789
|
+
let httpModule;
|
|
26790
|
+
try {
|
|
26791
|
+
httpModule = await this.loadModule("http");
|
|
26792
|
+
} catch {
|
|
26793
|
+
return new Response("Not found", { status: 404 });
|
|
26794
|
+
}
|
|
26723
26795
|
const router = httpModule?.default;
|
|
26724
26796
|
if (!router?.isRouter || typeof router.lookup !== "function") {
|
|
26725
|
-
|
|
26797
|
+
return new Response("Not found", { status: 404 });
|
|
26726
26798
|
}
|
|
26727
26799
|
const match = router.lookup(url.pathname, request.method);
|
|
26728
26800
|
if (!match) {
|
|
@@ -27157,6 +27229,9 @@ class HttpHandler {
|
|
|
27157
27229
|
if (url.pathname === "/health") {
|
|
27158
27230
|
return apply(Response.json({ status: "ok", runtime: this.runtimeName }));
|
|
27159
27231
|
}
|
|
27232
|
+
if (!isReservedApiPath(url.pathname)) {
|
|
27233
|
+
return forwardHttpRequest(request, "HTTP action");
|
|
27234
|
+
}
|
|
27160
27235
|
return apply(Response.json({ error: "Not found" }, { status: 404 }));
|
|
27161
27236
|
}
|
|
27162
27237
|
}
|
|
@@ -31330,6 +31405,12 @@ function parseDocumentIdKey2(key) {
|
|
|
31330
31405
|
const internalId = key.substring(colonIndex + 1);
|
|
31331
31406
|
if (!table || !internalId)
|
|
31332
31407
|
return null;
|
|
31408
|
+
if (table.startsWith("#")) {
|
|
31409
|
+
const tableNumber = Number.parseInt(table.slice(1), 10);
|
|
31410
|
+
if (Number.isInteger(tableNumber) && tableNumber > 0) {
|
|
31411
|
+
return { table, internalId, tableNumber };
|
|
31412
|
+
}
|
|
31413
|
+
}
|
|
31333
31414
|
return { table, internalId };
|
|
31334
31415
|
}
|
|
31335
31416
|
var Order4;
|
|
@@ -31842,7 +31923,7 @@ async function validateReadSetForCommit2(docstore, readChecks, writtenDocKeys) {
|
|
|
31842
31923
|
await validateTableScanRead2(docstore, readEntry.tableId, readEntry.documentIds, writtenDocKeys);
|
|
31843
31924
|
continue;
|
|
31844
31925
|
}
|
|
31845
|
-
await validateIndexRangeRead2(docstore, readEntry.indexId, readEntry.startKey, readEntry.endKey, readEntry.documentIds, writtenDocKeys);
|
|
31926
|
+
await validateIndexRangeRead2(docstore, readEntry.indexId, readEntry.startKey, readEntry.endKey, readEntry.readTimestamp, readEntry.documentIds, writtenDocKeys);
|
|
31846
31927
|
}
|
|
31847
31928
|
}
|
|
31848
31929
|
async function validateDocumentRead2(docstore, key, readVersion, writtenDocKeys) {
|
|
@@ -31886,11 +31967,12 @@ async function validateTableScanRead2(docstore, tableId, readDocumentIds, writte
|
|
|
31886
31967
|
}
|
|
31887
31968
|
}
|
|
31888
31969
|
}
|
|
31889
|
-
async function validateIndexRangeRead2(docstore, indexId, startKey, endKey, readDocumentIds, writtenDocKeys) {
|
|
31970
|
+
async function validateIndexRangeRead2(docstore, indexId, startKey, endKey, readTimestamp, readDocumentIds, writtenDocKeys) {
|
|
31890
31971
|
const { table } = decodeIndexId4(indexId);
|
|
31891
31972
|
const interval = { start: startKey, end: endKey };
|
|
31973
|
+
const validationReadTimestamp = resolveValidationReadTimestamp2(docstore, readTimestamp);
|
|
31892
31974
|
const currentDocIds = new Set;
|
|
31893
|
-
for await (const [, doc] of docstore.index_scan(indexId, table,
|
|
31975
|
+
for await (const [, doc] of docstore.index_scan(indexId, table, validationReadTimestamp, interval, Order4.Asc)) {
|
|
31894
31976
|
currentDocIds.add(documentIdKey3(doc.value.id));
|
|
31895
31977
|
}
|
|
31896
31978
|
for (const docId of currentDocIds) {
|
|
@@ -31904,6 +31986,13 @@ async function validateIndexRangeRead2(docstore, indexId, startKey, endKey, read
|
|
|
31904
31986
|
}
|
|
31905
31987
|
}
|
|
31906
31988
|
}
|
|
31989
|
+
function resolveValidationReadTimestamp2(docstore, minimumTimestamp) {
|
|
31990
|
+
const maybeDocStore = docstore;
|
|
31991
|
+
const oracleTimestamp = maybeDocStore.timestampOracle?.getCurrentTimestamp?.();
|
|
31992
|
+
const wallClockTimestamp = BigInt(Date.now());
|
|
31993
|
+
const latestKnownTimestamp = oracleTimestamp !== undefined && oracleTimestamp > wallClockTimestamp ? oracleTimestamp : wallClockTimestamp;
|
|
31994
|
+
return latestKnownTimestamp > minimumTimestamp ? latestKnownTimestamp : minimumTimestamp;
|
|
31995
|
+
}
|
|
31907
31996
|
|
|
31908
31997
|
class OccMutationTransaction2 {
|
|
31909
31998
|
docstore;
|
|
@@ -32508,7 +32597,6 @@ class KernelContext4 {
|
|
|
32508
32597
|
}
|
|
32509
32598
|
recordTableRead(tableName) {
|
|
32510
32599
|
if (this.mutationTransaction) {
|
|
32511
|
-
this.mutationTransaction.recordTableScan(stringToHex4(tableName), []);
|
|
32512
32600
|
return;
|
|
32513
32601
|
}
|
|
32514
32602
|
this.readLog.addTableScan(tableName);
|
|
@@ -32521,8 +32609,6 @@ class KernelContext4 {
|
|
|
32521
32609
|
}
|
|
32522
32610
|
recordIndexRange(tableName, indexDescriptor, startKey, endKey) {
|
|
32523
32611
|
if (this.mutationTransaction) {
|
|
32524
|
-
const indexId = indexKeyspaceId4(tableName, indexDescriptor);
|
|
32525
|
-
this.mutationTransaction.recordIndexRangeScan(indexId, startKey, endKey, []);
|
|
32526
32612
|
return;
|
|
32527
32613
|
}
|
|
32528
32614
|
this.readLog.addIndexRange(tableName, indexDescriptor, startKey, endKey);
|
|
@@ -32678,11 +32764,12 @@ class BlobStoreGateway4 {
|
|
|
32678
32764
|
if (!latest || latest.ts > this.context.snapshotTimestamp) {
|
|
32679
32765
|
return;
|
|
32680
32766
|
}
|
|
32681
|
-
|
|
32767
|
+
const canonicalDocId = latest.value.id;
|
|
32768
|
+
await storage2.delete(canonicalDocId.internalId);
|
|
32682
32769
|
const timestamp2 = this.docStore.allocateTimestamp();
|
|
32683
|
-
const entry = { ts: timestamp2, id:
|
|
32770
|
+
const entry = { ts: timestamp2, id: canonicalDocId, value: null, prev_ts: latest.ts };
|
|
32684
32771
|
await this.docStore.applyWrites([entry], new Set, "Error");
|
|
32685
|
-
this.context.recordLocalWrite(storageId, "_storage", null,
|
|
32772
|
+
this.context.recordLocalWrite(storageId, "_storage", null, canonicalDocId);
|
|
32686
32773
|
}
|
|
32687
32774
|
requireStorage() {
|
|
32688
32775
|
if (!this.storage) {
|
|
@@ -32885,16 +32972,17 @@ class SchedulerGateway4 {
|
|
|
32885
32972
|
if (!latest) {
|
|
32886
32973
|
throw new Error(`Scheduled job with id ${id} not found.`);
|
|
32887
32974
|
}
|
|
32975
|
+
const canonicalDocId = latest.value.id;
|
|
32888
32976
|
const newValue = {
|
|
32889
32977
|
...latest.value.value,
|
|
32890
32978
|
state: state ?? { kind: "canceled" }
|
|
32891
32979
|
};
|
|
32892
|
-
const resolvedDocument = { id:
|
|
32980
|
+
const resolvedDocument = { id: canonicalDocId, value: newValue };
|
|
32893
32981
|
const timestamp2 = this.docStore.allocateTimestamp();
|
|
32894
|
-
const entry = { ts: timestamp2, id:
|
|
32982
|
+
const entry = { ts: timestamp2, id: canonicalDocId, value: resolvedDocument, prev_ts: latest.ts };
|
|
32895
32983
|
await this.docStore.applyWrites([entry], new Set, "Error");
|
|
32896
|
-
const tableName = await resolveTableName4(
|
|
32897
|
-
this.context.recordLocalWrite(id, tableName, resolvedDocument.value,
|
|
32984
|
+
const tableName = await resolveTableName4(canonicalDocId, this.context.tableRegistry);
|
|
32985
|
+
this.context.recordLocalWrite(id, tableName, resolvedDocument.value, canonicalDocId);
|
|
32898
32986
|
}
|
|
32899
32987
|
}
|
|
32900
32988
|
init_context_storage4();
|
|
@@ -33106,13 +33194,14 @@ class DatabaseSyscalls4 {
|
|
|
33106
33194
|
if (!latest) {
|
|
33107
33195
|
throw new Error(`Document with id ${id} not found.`);
|
|
33108
33196
|
}
|
|
33197
|
+
const canonicalDocId = latest.value.id;
|
|
33109
33198
|
const timestamp2 = this.docStore.allocateTimestamp();
|
|
33110
|
-
const entry = { ts: timestamp2, id:
|
|
33199
|
+
const entry = { ts: timestamp2, id: canonicalDocId, value: null, prev_ts: latest.ts };
|
|
33111
33200
|
const indexes = await this.schemaService.getAllIndexesForTable(bareTableName);
|
|
33112
|
-
const indexUpdates = generateIndexUpdates4(fullTableName,
|
|
33201
|
+
const indexUpdates = generateIndexUpdates4(fullTableName, canonicalDocId, null, latest.value.value, indexes);
|
|
33113
33202
|
const indexEntries = new Set(indexUpdates.map((update) => ({ ts: timestamp2, update })));
|
|
33114
33203
|
await this.docStore.applyWrites([entry], indexEntries, "Error");
|
|
33115
|
-
this.context.recordLocalWrite(id, fullTableName, null,
|
|
33204
|
+
this.context.recordLocalWrite(id, fullTableName, null, canonicalDocId);
|
|
33116
33205
|
return {};
|
|
33117
33206
|
}
|
|
33118
33207
|
async handleShallowMerge(args) {
|
|
@@ -33138,6 +33227,7 @@ class DatabaseSyscalls4 {
|
|
|
33138
33227
|
if (!latest) {
|
|
33139
33228
|
throw new Error(`Document with id ${id} not found.`);
|
|
33140
33229
|
}
|
|
33230
|
+
const canonicalDocId = latest.value.id;
|
|
33141
33231
|
const existingValue = latest.value.value;
|
|
33142
33232
|
const newValue = { ...existingValue };
|
|
33143
33233
|
if (typeof value === "object" && value !== null && "$undefined" in value) {
|
|
@@ -33164,14 +33254,14 @@ class DatabaseSyscalls4 {
|
|
|
33164
33254
|
}
|
|
33165
33255
|
}
|
|
33166
33256
|
await this.schemaService.validate(bareTableName, newValue);
|
|
33167
|
-
const resolvedDocument = { id:
|
|
33257
|
+
const resolvedDocument = { id: canonicalDocId, value: newValue };
|
|
33168
33258
|
const timestamp2 = this.docStore.allocateTimestamp();
|
|
33169
|
-
const entry = { ts: timestamp2, id:
|
|
33259
|
+
const entry = { ts: timestamp2, id: canonicalDocId, value: resolvedDocument, prev_ts: latest.ts };
|
|
33170
33260
|
const indexes = await this.schemaService.getAllIndexesForTable(bareTableName);
|
|
33171
|
-
const indexUpdates = generateIndexUpdates4(fullTableName,
|
|
33261
|
+
const indexUpdates = generateIndexUpdates4(fullTableName, canonicalDocId, resolvedDocument.value, existingValue, indexes);
|
|
33172
33262
|
const indexEntries = new Set(indexUpdates.map((update) => ({ ts: timestamp2, update })));
|
|
33173
33263
|
await this.docStore.applyWrites([entry], indexEntries, "Error");
|
|
33174
|
-
this.context.recordLocalWrite(id, fullTableName, resolvedDocument.value,
|
|
33264
|
+
this.context.recordLocalWrite(id, fullTableName, resolvedDocument.value, canonicalDocId);
|
|
33175
33265
|
return {};
|
|
33176
33266
|
}
|
|
33177
33267
|
async handleReplace(args) {
|
|
@@ -33193,17 +33283,18 @@ class DatabaseSyscalls4 {
|
|
|
33193
33283
|
if (!latest) {
|
|
33194
33284
|
throw new Error(`Document with id ${id} not found.`);
|
|
33195
33285
|
}
|
|
33286
|
+
const canonicalDocId = latest.value.id;
|
|
33196
33287
|
const { _id, _creationTime } = latest.value.value;
|
|
33197
33288
|
const newValue = { ...replaceValue, _id, _creationTime };
|
|
33198
33289
|
await this.schemaService.validate(bareTableName, newValue);
|
|
33199
|
-
const resolvedDocument = { id:
|
|
33290
|
+
const resolvedDocument = { id: canonicalDocId, value: newValue };
|
|
33200
33291
|
const timestamp2 = this.docStore.allocateTimestamp();
|
|
33201
|
-
const entry = { ts: timestamp2, id:
|
|
33292
|
+
const entry = { ts: timestamp2, id: canonicalDocId, value: resolvedDocument, prev_ts: latest.ts };
|
|
33202
33293
|
const indexes = await this.schemaService.getAllIndexesForTable(bareTableName);
|
|
33203
|
-
const indexUpdates = generateIndexUpdates4(fullTableName,
|
|
33294
|
+
const indexUpdates = generateIndexUpdates4(fullTableName, canonicalDocId, resolvedDocument.value, latest.value.value, indexes);
|
|
33204
33295
|
const indexEntries = new Set(indexUpdates.map((update) => ({ ts: timestamp2, update })));
|
|
33205
33296
|
await this.docStore.applyWrites([entry], indexEntries, "Error");
|
|
33206
|
-
this.context.recordLocalWrite(id, fullTableName, newValue,
|
|
33297
|
+
this.context.recordLocalWrite(id, fullTableName, newValue, canonicalDocId);
|
|
33207
33298
|
return {};
|
|
33208
33299
|
}
|
|
33209
33300
|
}
|
|
@@ -38710,6 +38801,12 @@ function parseDocumentIdKey3(key) {
|
|
|
38710
38801
|
const internalId = key.substring(colonIndex + 1);
|
|
38711
38802
|
if (!table || !internalId)
|
|
38712
38803
|
return null;
|
|
38804
|
+
if (table.startsWith("#")) {
|
|
38805
|
+
const tableNumber = Number.parseInt(table.slice(1), 10);
|
|
38806
|
+
if (Number.isInteger(tableNumber) && tableNumber > 0) {
|
|
38807
|
+
return { table, internalId, tableNumber };
|
|
38808
|
+
}
|
|
38809
|
+
}
|
|
38713
38810
|
return { table, internalId };
|
|
38714
38811
|
}
|
|
38715
38812
|
var Order5;
|
|
@@ -39219,7 +39316,7 @@ async function validateReadSetForCommit3(docstore, readChecks, writtenDocKeys) {
|
|
|
39219
39316
|
await validateTableScanRead3(docstore, readEntry.tableId, readEntry.documentIds, writtenDocKeys);
|
|
39220
39317
|
continue;
|
|
39221
39318
|
}
|
|
39222
|
-
await validateIndexRangeRead3(docstore, readEntry.indexId, readEntry.startKey, readEntry.endKey, readEntry.documentIds, writtenDocKeys);
|
|
39319
|
+
await validateIndexRangeRead3(docstore, readEntry.indexId, readEntry.startKey, readEntry.endKey, readEntry.readTimestamp, readEntry.documentIds, writtenDocKeys);
|
|
39223
39320
|
}
|
|
39224
39321
|
}
|
|
39225
39322
|
async function validateDocumentRead3(docstore, key, readVersion, writtenDocKeys) {
|
|
@@ -39263,11 +39360,12 @@ async function validateTableScanRead3(docstore, tableId, readDocumentIds, writte
|
|
|
39263
39360
|
}
|
|
39264
39361
|
}
|
|
39265
39362
|
}
|
|
39266
|
-
async function validateIndexRangeRead3(docstore, indexId, startKey, endKey, readDocumentIds, writtenDocKeys) {
|
|
39363
|
+
async function validateIndexRangeRead3(docstore, indexId, startKey, endKey, readTimestamp, readDocumentIds, writtenDocKeys) {
|
|
39267
39364
|
const { table } = decodeIndexId5(indexId);
|
|
39268
39365
|
const interval = { start: startKey, end: endKey };
|
|
39366
|
+
const validationReadTimestamp = resolveValidationReadTimestamp3(docstore, readTimestamp);
|
|
39269
39367
|
const currentDocIds = new Set;
|
|
39270
|
-
for await (const [, doc] of docstore.index_scan(indexId, table,
|
|
39368
|
+
for await (const [, doc] of docstore.index_scan(indexId, table, validationReadTimestamp, interval, Order5.Asc)) {
|
|
39271
39369
|
currentDocIds.add(documentIdKey4(doc.value.id));
|
|
39272
39370
|
}
|
|
39273
39371
|
for (const docId of currentDocIds) {
|
|
@@ -39281,6 +39379,13 @@ async function validateIndexRangeRead3(docstore, indexId, startKey, endKey, read
|
|
|
39281
39379
|
}
|
|
39282
39380
|
}
|
|
39283
39381
|
}
|
|
39382
|
+
function resolveValidationReadTimestamp3(docstore, minimumTimestamp) {
|
|
39383
|
+
const maybeDocStore = docstore;
|
|
39384
|
+
const oracleTimestamp = maybeDocStore.timestampOracle?.getCurrentTimestamp?.();
|
|
39385
|
+
const wallClockTimestamp = BigInt(Date.now());
|
|
39386
|
+
const latestKnownTimestamp = oracleTimestamp !== undefined && oracleTimestamp > wallClockTimestamp ? oracleTimestamp : wallClockTimestamp;
|
|
39387
|
+
return latestKnownTimestamp > minimumTimestamp ? latestKnownTimestamp : minimumTimestamp;
|
|
39388
|
+
}
|
|
39284
39389
|
|
|
39285
39390
|
class OccMutationTransaction3 {
|
|
39286
39391
|
docstore;
|
|
@@ -39885,7 +39990,6 @@ class KernelContext5 {
|
|
|
39885
39990
|
}
|
|
39886
39991
|
recordTableRead(tableName) {
|
|
39887
39992
|
if (this.mutationTransaction) {
|
|
39888
|
-
this.mutationTransaction.recordTableScan(stringToHex5(tableName), []);
|
|
39889
39993
|
return;
|
|
39890
39994
|
}
|
|
39891
39995
|
this.readLog.addTableScan(tableName);
|
|
@@ -39898,8 +40002,6 @@ class KernelContext5 {
|
|
|
39898
40002
|
}
|
|
39899
40003
|
recordIndexRange(tableName, indexDescriptor, startKey, endKey) {
|
|
39900
40004
|
if (this.mutationTransaction) {
|
|
39901
|
-
const indexId = indexKeyspaceId5(tableName, indexDescriptor);
|
|
39902
|
-
this.mutationTransaction.recordIndexRangeScan(indexId, startKey, endKey, []);
|
|
39903
40005
|
return;
|
|
39904
40006
|
}
|
|
39905
40007
|
this.readLog.addIndexRange(tableName, indexDescriptor, startKey, endKey);
|
|
@@ -40055,11 +40157,12 @@ class BlobStoreGateway5 {
|
|
|
40055
40157
|
if (!latest || latest.ts > this.context.snapshotTimestamp) {
|
|
40056
40158
|
return;
|
|
40057
40159
|
}
|
|
40058
|
-
|
|
40160
|
+
const canonicalDocId = latest.value.id;
|
|
40161
|
+
await storage2.delete(canonicalDocId.internalId);
|
|
40059
40162
|
const timestamp2 = this.docStore.allocateTimestamp();
|
|
40060
|
-
const entry = { ts: timestamp2, id:
|
|
40163
|
+
const entry = { ts: timestamp2, id: canonicalDocId, value: null, prev_ts: latest.ts };
|
|
40061
40164
|
await this.docStore.applyWrites([entry], new Set, "Error");
|
|
40062
|
-
this.context.recordLocalWrite(storageId, "_storage", null,
|
|
40165
|
+
this.context.recordLocalWrite(storageId, "_storage", null, canonicalDocId);
|
|
40063
40166
|
}
|
|
40064
40167
|
requireStorage() {
|
|
40065
40168
|
if (!this.storage) {
|
|
@@ -40262,16 +40365,17 @@ class SchedulerGateway5 {
|
|
|
40262
40365
|
if (!latest) {
|
|
40263
40366
|
throw new Error(`Scheduled job with id ${id} not found.`);
|
|
40264
40367
|
}
|
|
40368
|
+
const canonicalDocId = latest.value.id;
|
|
40265
40369
|
const newValue = {
|
|
40266
40370
|
...latest.value.value,
|
|
40267
40371
|
state: state ?? { kind: "canceled" }
|
|
40268
40372
|
};
|
|
40269
|
-
const resolvedDocument = { id:
|
|
40373
|
+
const resolvedDocument = { id: canonicalDocId, value: newValue };
|
|
40270
40374
|
const timestamp2 = this.docStore.allocateTimestamp();
|
|
40271
|
-
const entry = { ts: timestamp2, id:
|
|
40375
|
+
const entry = { ts: timestamp2, id: canonicalDocId, value: resolvedDocument, prev_ts: latest.ts };
|
|
40272
40376
|
await this.docStore.applyWrites([entry], new Set, "Error");
|
|
40273
|
-
const tableName = await resolveTableName5(
|
|
40274
|
-
this.context.recordLocalWrite(id, tableName, resolvedDocument.value,
|
|
40377
|
+
const tableName = await resolveTableName5(canonicalDocId, this.context.tableRegistry);
|
|
40378
|
+
this.context.recordLocalWrite(id, tableName, resolvedDocument.value, canonicalDocId);
|
|
40275
40379
|
}
|
|
40276
40380
|
}
|
|
40277
40381
|
init_context_storage5();
|
|
@@ -40482,13 +40586,14 @@ class DatabaseSyscalls5 {
|
|
|
40482
40586
|
if (!latest) {
|
|
40483
40587
|
throw new Error(`Document with id ${id} not found.`);
|
|
40484
40588
|
}
|
|
40589
|
+
const canonicalDocId = latest.value.id;
|
|
40485
40590
|
const timestamp2 = this.docStore.allocateTimestamp();
|
|
40486
|
-
const entry = { ts: timestamp2, id:
|
|
40591
|
+
const entry = { ts: timestamp2, id: canonicalDocId, value: null, prev_ts: latest.ts };
|
|
40487
40592
|
const indexes = await this.schemaService.getAllIndexesForTable(bareTableName);
|
|
40488
|
-
const indexUpdates = generateIndexUpdates5(fullTableName,
|
|
40593
|
+
const indexUpdates = generateIndexUpdates5(fullTableName, canonicalDocId, null, latest.value.value, indexes);
|
|
40489
40594
|
const indexEntries = new Set(indexUpdates.map((update) => ({ ts: timestamp2, update })));
|
|
40490
40595
|
await this.docStore.applyWrites([entry], indexEntries, "Error");
|
|
40491
|
-
this.context.recordLocalWrite(id, fullTableName, null,
|
|
40596
|
+
this.context.recordLocalWrite(id, fullTableName, null, canonicalDocId);
|
|
40492
40597
|
return {};
|
|
40493
40598
|
}
|
|
40494
40599
|
async handleShallowMerge(args) {
|
|
@@ -40514,6 +40619,7 @@ class DatabaseSyscalls5 {
|
|
|
40514
40619
|
if (!latest) {
|
|
40515
40620
|
throw new Error(`Document with id ${id} not found.`);
|
|
40516
40621
|
}
|
|
40622
|
+
const canonicalDocId = latest.value.id;
|
|
40517
40623
|
const existingValue = latest.value.value;
|
|
40518
40624
|
const newValue = { ...existingValue };
|
|
40519
40625
|
if (typeof value === "object" && value !== null && "$undefined" in value) {
|
|
@@ -40540,14 +40646,14 @@ class DatabaseSyscalls5 {
|
|
|
40540
40646
|
}
|
|
40541
40647
|
}
|
|
40542
40648
|
await this.schemaService.validate(bareTableName, newValue);
|
|
40543
|
-
const resolvedDocument = { id:
|
|
40649
|
+
const resolvedDocument = { id: canonicalDocId, value: newValue };
|
|
40544
40650
|
const timestamp2 = this.docStore.allocateTimestamp();
|
|
40545
|
-
const entry = { ts: timestamp2, id:
|
|
40651
|
+
const entry = { ts: timestamp2, id: canonicalDocId, value: resolvedDocument, prev_ts: latest.ts };
|
|
40546
40652
|
const indexes = await this.schemaService.getAllIndexesForTable(bareTableName);
|
|
40547
|
-
const indexUpdates = generateIndexUpdates5(fullTableName,
|
|
40653
|
+
const indexUpdates = generateIndexUpdates5(fullTableName, canonicalDocId, resolvedDocument.value, existingValue, indexes);
|
|
40548
40654
|
const indexEntries = new Set(indexUpdates.map((update) => ({ ts: timestamp2, update })));
|
|
40549
40655
|
await this.docStore.applyWrites([entry], indexEntries, "Error");
|
|
40550
|
-
this.context.recordLocalWrite(id, fullTableName, resolvedDocument.value,
|
|
40656
|
+
this.context.recordLocalWrite(id, fullTableName, resolvedDocument.value, canonicalDocId);
|
|
40551
40657
|
return {};
|
|
40552
40658
|
}
|
|
40553
40659
|
async handleReplace(args) {
|
|
@@ -40569,17 +40675,18 @@ class DatabaseSyscalls5 {
|
|
|
40569
40675
|
if (!latest) {
|
|
40570
40676
|
throw new Error(`Document with id ${id} not found.`);
|
|
40571
40677
|
}
|
|
40678
|
+
const canonicalDocId = latest.value.id;
|
|
40572
40679
|
const { _id, _creationTime } = latest.value.value;
|
|
40573
40680
|
const newValue = { ...replaceValue, _id, _creationTime };
|
|
40574
40681
|
await this.schemaService.validate(bareTableName, newValue);
|
|
40575
|
-
const resolvedDocument = { id:
|
|
40682
|
+
const resolvedDocument = { id: canonicalDocId, value: newValue };
|
|
40576
40683
|
const timestamp2 = this.docStore.allocateTimestamp();
|
|
40577
|
-
const entry = { ts: timestamp2, id:
|
|
40684
|
+
const entry = { ts: timestamp2, id: canonicalDocId, value: resolvedDocument, prev_ts: latest.ts };
|
|
40578
40685
|
const indexes = await this.schemaService.getAllIndexesForTable(bareTableName);
|
|
40579
|
-
const indexUpdates = generateIndexUpdates5(fullTableName,
|
|
40686
|
+
const indexUpdates = generateIndexUpdates5(fullTableName, canonicalDocId, resolvedDocument.value, latest.value.value, indexes);
|
|
40580
40687
|
const indexEntries = new Set(indexUpdates.map((update) => ({ ts: timestamp2, update })));
|
|
40581
40688
|
await this.docStore.applyWrites([entry], indexEntries, "Error");
|
|
40582
|
-
this.context.recordLocalWrite(id, fullTableName, newValue,
|
|
40689
|
+
this.context.recordLocalWrite(id, fullTableName, newValue, canonicalDocId);
|
|
40583
40690
|
return {};
|
|
40584
40691
|
}
|
|
40585
40692
|
}
|
|
@@ -43681,6 +43788,7 @@ class SyncProtocolHandler2 {
|
|
|
43681
43788
|
rateLimitWindowMs;
|
|
43682
43789
|
operationTimeoutMs;
|
|
43683
43790
|
maxActiveQueriesPerSession;
|
|
43791
|
+
lastObservedWriteTimestamp = 0n;
|
|
43684
43792
|
constructor(instanceName, udfExecutor, options) {
|
|
43685
43793
|
this.udfExecutor = udfExecutor;
|
|
43686
43794
|
this.instanceName = instanceName;
|
|
@@ -43704,6 +43812,22 @@ class SyncProtocolHandler2 {
|
|
|
43704
43812
|
onPing: (session) => this.sendPing(session)
|
|
43705
43813
|
});
|
|
43706
43814
|
}
|
|
43815
|
+
resolveWriteTimestamp(commitTimestamp, snapshotTimestamp) {
|
|
43816
|
+
const wallClock = BigInt(Date.now());
|
|
43817
|
+
const monotonicFloor = this.lastObservedWriteTimestamp + 1n;
|
|
43818
|
+
let resolved = wallClock;
|
|
43819
|
+
if (commitTimestamp !== undefined && commitTimestamp > resolved) {
|
|
43820
|
+
resolved = commitTimestamp;
|
|
43821
|
+
}
|
|
43822
|
+
if (snapshotTimestamp !== undefined && snapshotTimestamp > resolved) {
|
|
43823
|
+
resolved = snapshotTimestamp;
|
|
43824
|
+
}
|
|
43825
|
+
if (monotonicFloor > resolved) {
|
|
43826
|
+
resolved = monotonicFloor;
|
|
43827
|
+
}
|
|
43828
|
+
this.lastObservedWriteTimestamp = resolved;
|
|
43829
|
+
return resolved;
|
|
43830
|
+
}
|
|
43707
43831
|
createSession(sessionId, websocket) {
|
|
43708
43832
|
const session = new SyncSession2(websocket);
|
|
43709
43833
|
this.sessions.set(sessionId, session);
|
|
@@ -43786,11 +43910,11 @@ class SyncProtocolHandler2 {
|
|
|
43786
43910
|
return assertNever2(message22);
|
|
43787
43911
|
}
|
|
43788
43912
|
}
|
|
43789
|
-
async notifyWrites(writtenRanges, writtenTables, commitTimestamp) {
|
|
43913
|
+
async notifyWrites(writtenRanges, writtenTables, commitTimestamp, snapshotTimestamp) {
|
|
43790
43914
|
const ranges = writtenRanges ? writtenRanges.map(deserializeKeyRange5) : convertTablesToRanges2(writtenTables);
|
|
43791
43915
|
this.logRanges("/notify", ranges, { writtenTables });
|
|
43792
43916
|
if (ranges.length > 0) {
|
|
43793
|
-
const ts = commitTimestamp
|
|
43917
|
+
const ts = this.resolveWriteTimestamp(commitTimestamp, snapshotTimestamp);
|
|
43794
43918
|
this.subscriptionManager.recordWrites(ranges, ts);
|
|
43795
43919
|
await this.broadcastUpdates(ranges);
|
|
43796
43920
|
}
|
|
@@ -43888,8 +44012,8 @@ class SyncProtocolHandler2 {
|
|
|
43888
44012
|
if (message22.componentPath && session.auth.tokenType !== "Admin" && session.auth.tokenType !== "System") {
|
|
43889
44013
|
throw new Error("Only admin or system auth can execute component functions");
|
|
43890
44014
|
}
|
|
43891
|
-
const { result, writtenRanges, writtenTables, commitTimestamp, logLines } = await this.udfExecutor.executeMutation(message22.udfPath, message22.args[0] ?? {}, session.auth, message22.componentPath);
|
|
43892
|
-
const now = commitTimestamp
|
|
44015
|
+
const { result, writtenRanges, writtenTables, commitTimestamp, snapshotTimestamp, logLines } = await this.udfExecutor.executeMutation(message22.udfPath, message22.args[0] ?? {}, session.auth, message22.componentPath);
|
|
44016
|
+
const now = this.resolveWriteTimestamp(commitTimestamp, snapshotTimestamp);
|
|
43893
44017
|
const successResponse = {
|
|
43894
44018
|
type: "MutationResponse",
|
|
43895
44019
|
requestId: message22.requestId,
|
|
@@ -43934,8 +44058,8 @@ class SyncProtocolHandler2 {
|
|
|
43934
44058
|
if (message22.componentPath && session.auth.tokenType !== "Admin" && session.auth.tokenType !== "System") {
|
|
43935
44059
|
throw new Error("Only admin or system auth can mutate component functions");
|
|
43936
44060
|
}
|
|
43937
|
-
const { result, writtenRanges, writtenTables, commitTimestamp, logLines } = await this.udfExecutor.executeAction(message22.udfPath, message22.args[0] ?? {}, session.auth, message22.componentPath);
|
|
43938
|
-
const now = commitTimestamp
|
|
44061
|
+
const { result, writtenRanges, writtenTables, commitTimestamp, snapshotTimestamp, logLines } = await this.udfExecutor.executeAction(message22.udfPath, message22.args[0] ?? {}, session.auth, message22.componentPath);
|
|
44062
|
+
const now = this.resolveWriteTimestamp(commitTimestamp, snapshotTimestamp);
|
|
43939
44063
|
const successResponse = {
|
|
43940
44064
|
type: "ActionResponse",
|
|
43941
44065
|
requestId: message22.requestId,
|