@korajs/store 1.0.0-beta.1 → 1.0.0-beta.2
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/adapters/indexeddb.cjs +39 -5
- package/dist/adapters/indexeddb.cjs.map +1 -1
- package/dist/adapters/indexeddb.js +13 -6
- package/dist/adapters/indexeddb.js.map +1 -1
- package/dist/adapters/sqlite-wasm-worker.cjs +25 -3
- package/dist/adapters/sqlite-wasm-worker.cjs.map +1 -1
- package/dist/adapters/sqlite-wasm-worker.js +25 -3
- package/dist/adapters/sqlite-wasm-worker.js.map +1 -1
- package/dist/adapters/sqlite-wasm.cjs +29 -0
- package/dist/adapters/sqlite-wasm.cjs.map +1 -1
- package/dist/adapters/sqlite-wasm.d.cts +16 -1
- package/dist/adapters/sqlite-wasm.d.ts +16 -1
- package/dist/adapters/sqlite-wasm.js +1 -1
- package/dist/{backup-ZV4Y424B.js → backup-IQE4QC7Q.js} +2 -2
- package/dist/{chunk-ZLWAYQEQ.js → chunk-2VRPF25R.js} +31 -27
- package/dist/chunk-2VRPF25R.js.map +1 -0
- package/dist/{chunk-X57MWW35.js → chunk-OCOGQRHW.js} +12 -9
- package/dist/chunk-OCOGQRHW.js.map +1 -0
- package/dist/{chunk-RBPVEAVM.js → chunk-QUJGXSZ6.js} +30 -1
- package/dist/chunk-QUJGXSZ6.js.map +1 -0
- package/dist/{chunk-FFYA7J5H.js → chunk-RCTG3IJG.js} +3 -2
- package/dist/chunk-RCTG3IJG.js.map +1 -0
- package/dist/{export-audit-AJ7RORNK.js → export-audit-MT2LTMIN.js} +2 -2
- package/dist/index.cjs +155 -141
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +48 -40
- package/dist/index.js.map +1 -1
- package/dist/internal.cjs +45 -40
- package/dist/internal.cjs.map +1 -1
- package/dist/internal.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-FFYA7J5H.js.map +0 -1
- package/dist/chunk-RBPVEAVM.js.map +0 -1
- package/dist/chunk-X57MWW35.js.map +0 -1
- package/dist/chunk-ZLWAYQEQ.js.map +0 -1
- /package/dist/{backup-ZV4Y424B.js.map → backup-IQE4QC7Q.js.map} +0 -0
- /package/dist/{export-audit-AJ7RORNK.js.map → export-audit-MT2LTMIN.js.map} +0 -0
package/dist/index.cjs
CHANGED
|
@@ -528,7 +528,7 @@ async function restoreBackup(adapter, schema, data, options) {
|
|
|
528
528
|
schema_version: op.schemaVersion
|
|
529
529
|
};
|
|
530
530
|
await tx.execute(
|
|
531
|
-
`INSERT OR IGNORE INTO _kora_ops_${collection} (id, node_id, type, record_id, data, previous_data, timestamp, sequence_number, causal_deps, schema_version) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
531
|
+
`INSERT OR IGNORE INTO ${(0, import_core6.quoteIdent)(`_kora_ops_${collection}`)} (id, node_id, type, record_id, data, previous_data, timestamp, sequence_number, causal_deps, schema_version) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
532
532
|
[
|
|
533
533
|
opRow.id,
|
|
534
534
|
opRow.node_id,
|
|
@@ -547,8 +547,8 @@ async function restoreBackup(adapter, schema, data, options) {
|
|
|
547
547
|
} else {
|
|
548
548
|
await adapter.transaction(async (tx) => {
|
|
549
549
|
for (const collection of Object.keys(schema.collections)) {
|
|
550
|
-
await tx.execute(`DELETE FROM _kora_ops_${collection}`);
|
|
551
|
-
await tx.execute(`DELETE FROM ${collection}`);
|
|
550
|
+
await tx.execute(`DELETE FROM ${(0, import_core6.quoteIdent)(`_kora_ops_${collection}`)}`);
|
|
551
|
+
await tx.execute(`DELETE FROM ${(0, import_core6.quoteIdent)(collection)}`);
|
|
552
552
|
}
|
|
553
553
|
await tx.execute("DELETE FROM _kora_version_vector");
|
|
554
554
|
await tx.execute("DELETE FROM _kora_meta");
|
|
@@ -568,7 +568,7 @@ async function restoreBackup(adapter, schema, data, options) {
|
|
|
568
568
|
for (const op of operations) {
|
|
569
569
|
const collection = op.collection;
|
|
570
570
|
await tx.execute(
|
|
571
|
-
`INSERT INTO _kora_ops_${collection} (id, node_id, type, record_id, data, previous_data, timestamp, sequence_number, causal_deps, schema_version) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
571
|
+
`INSERT INTO ${(0, import_core6.quoteIdent)(`_kora_ops_${collection}`)} (id, node_id, type, record_id, data, previous_data, timestamp, sequence_number, causal_deps, schema_version) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
572
572
|
[
|
|
573
573
|
op.id,
|
|
574
574
|
op.nodeId,
|
|
@@ -600,6 +600,7 @@ async function restoreBackup(adapter, schema, data, options) {
|
|
|
600
600
|
for (const record of records) {
|
|
601
601
|
const keys = Object.keys(record);
|
|
602
602
|
const placeholders = keys.map(() => "?").join(", ");
|
|
603
|
+
const quotedKeys = keys.map((k) => (0, import_core6.quoteIdent)(k)).join(", ");
|
|
603
604
|
const values = keys.map((k) => {
|
|
604
605
|
const v = record[k];
|
|
605
606
|
if (typeof v === "boolean") return v ? 1 : 0;
|
|
@@ -607,7 +608,7 @@ async function restoreBackup(adapter, schema, data, options) {
|
|
|
607
608
|
return v;
|
|
608
609
|
});
|
|
609
610
|
await tx.execute(
|
|
610
|
-
`INSERT OR REPLACE INTO ${col} (${
|
|
611
|
+
`INSERT OR REPLACE INTO ${(0, import_core6.quoteIdent)(col)} (${quotedKeys}) VALUES (${placeholders})`,
|
|
611
612
|
values
|
|
612
613
|
);
|
|
613
614
|
}
|
|
@@ -640,7 +641,7 @@ async function readAllOperations(adapter, schema) {
|
|
|
640
641
|
const allOps = [];
|
|
641
642
|
for (const collectionName of Object.keys(schema.collections)) {
|
|
642
643
|
const rows = await adapter.query(
|
|
643
|
-
`SELECT * FROM _kora_ops_${collectionName} ORDER BY sequence_number ASC`
|
|
644
|
+
`SELECT * FROM ${(0, import_core6.quoteIdent)(`_kora_ops_${collectionName}`)} ORDER BY sequence_number ASC`
|
|
644
645
|
);
|
|
645
646
|
for (const row of rows) {
|
|
646
647
|
allOps.push(deserializeOperationWithCollection(row, collectionName));
|
|
@@ -649,7 +650,9 @@ async function readAllOperations(adapter, schema) {
|
|
|
649
650
|
return allOps;
|
|
650
651
|
}
|
|
651
652
|
async function readCollectionRecords(adapter, collection) {
|
|
652
|
-
return adapter.query(
|
|
653
|
+
return adapter.query(
|
|
654
|
+
`SELECT * FROM ${(0, import_core6.quoteIdent)(collection)} WHERE _deleted = 0`
|
|
655
|
+
);
|
|
653
656
|
}
|
|
654
657
|
async function computeSha256(data) {
|
|
655
658
|
const hashBuffer = await crypto.subtle.digest("SHA-256", data);
|
|
@@ -717,7 +720,7 @@ __export(audit_trace_store_exports, {
|
|
|
717
720
|
});
|
|
718
721
|
function persistedAuditTraceFromEvent(event) {
|
|
719
722
|
return {
|
|
720
|
-
id: (0,
|
|
723
|
+
id: (0, import_core21.generateUUIDv7)(),
|
|
721
724
|
recordedAt: Date.now(),
|
|
722
725
|
eventType: event.type,
|
|
723
726
|
constraint: event.type === "constraint:violated" ? event.constraint : void 0,
|
|
@@ -783,11 +786,11 @@ function auditTraceIndexFields(trace) {
|
|
|
783
786
|
recordId: trace.operationA.recordId
|
|
784
787
|
};
|
|
785
788
|
}
|
|
786
|
-
var
|
|
789
|
+
var import_core21;
|
|
787
790
|
var init_audit_trace_store = __esm({
|
|
788
791
|
"src/audit/audit-trace-store.ts"() {
|
|
789
792
|
"use strict";
|
|
790
|
-
|
|
793
|
+
import_core21 = require("@korajs/core");
|
|
791
794
|
init_audit_json();
|
|
792
795
|
}
|
|
793
796
|
});
|
|
@@ -859,7 +862,7 @@ async function readAllOperations2(adapter, schema, collectionFilter) {
|
|
|
859
862
|
const allOps = [];
|
|
860
863
|
for (const collectionName of collections) {
|
|
861
864
|
const rows = await adapter.query(
|
|
862
|
-
`SELECT * FROM _kora_ops_${collectionName} ORDER BY sequence_number ASC`
|
|
865
|
+
`SELECT * FROM ${(0, import_core22.quoteIdent)(`_kora_ops_${collectionName}`)} ORDER BY sequence_number ASC`
|
|
863
866
|
);
|
|
864
867
|
for (const row of rows) {
|
|
865
868
|
allOps.push(deserializeOperationWithCollection(row, collectionName));
|
|
@@ -970,9 +973,11 @@ function parseNdjsonSection(content) {
|
|
|
970
973
|
}
|
|
971
974
|
return text.split("\n").map((line) => deserializeAuditJson(line));
|
|
972
975
|
}
|
|
976
|
+
var import_core22;
|
|
973
977
|
var init_export_audit = __esm({
|
|
974
978
|
"src/audit/export-audit.ts"() {
|
|
975
979
|
"use strict";
|
|
980
|
+
import_core22 = require("@korajs/core");
|
|
976
981
|
init_serializer();
|
|
977
982
|
init_audit_json();
|
|
978
983
|
init_audit_trace_store();
|
|
@@ -1147,7 +1152,7 @@ async function compactOperationLog(adapter, schema, strategy, serverVector) {
|
|
|
1147
1152
|
const collectionNames = Object.keys(schema.collections);
|
|
1148
1153
|
await adapter.transaction(async (tx) => {
|
|
1149
1154
|
for (const collectionName of collectionNames) {
|
|
1150
|
-
const table = `_kora_ops_${collectionName}
|
|
1155
|
+
const table = (0, import_core2.quoteIdent)(`_kora_ops_${collectionName}`);
|
|
1151
1156
|
for (const [nodeId, maxSeq] of watermark) {
|
|
1152
1157
|
if (maxSeq <= 0) continue;
|
|
1153
1158
|
const countSql = buildCountSql(table, ageCutoffSerialized !== null);
|
|
@@ -1256,11 +1261,14 @@ async function saveDeltaCursor(adapter, cursor) {
|
|
|
1256
1261
|
}
|
|
1257
1262
|
|
|
1258
1263
|
// src/store/store.ts
|
|
1259
|
-
var
|
|
1264
|
+
var import_core23 = require("@korajs/core");
|
|
1260
1265
|
init_backup();
|
|
1261
1266
|
|
|
1267
|
+
// src/collection/collection.ts
|
|
1268
|
+
var import_core13 = require("@korajs/core");
|
|
1269
|
+
|
|
1262
1270
|
// src/mutations/execute-delete.ts
|
|
1263
|
-
var
|
|
1271
|
+
var import_core9 = require("@korajs/core");
|
|
1264
1272
|
|
|
1265
1273
|
// src/lww/row-version.ts
|
|
1266
1274
|
var import_core7 = require("@korajs/core");
|
|
@@ -1286,9 +1294,10 @@ function lwwVersionWhereClause(remoteVersion) {
|
|
|
1286
1294
|
}
|
|
1287
1295
|
|
|
1288
1296
|
// src/query/sql-builder.ts
|
|
1297
|
+
var import_core8 = require("@korajs/core");
|
|
1289
1298
|
function buildSelectQuery(descriptor, fields) {
|
|
1290
1299
|
const params = [];
|
|
1291
|
-
const parts = [`SELECT * FROM ${descriptor.collection}`];
|
|
1300
|
+
const parts = [`SELECT * FROM ${(0, import_core8.quoteIdent)(descriptor.collection)}`];
|
|
1292
1301
|
const whereClause = buildWhereClauseParts(descriptor.where, fields, params);
|
|
1293
1302
|
const deletedFilter = "_deleted = 0";
|
|
1294
1303
|
if (whereClause) {
|
|
@@ -1299,7 +1308,7 @@ function buildSelectQuery(descriptor, fields) {
|
|
|
1299
1308
|
if (descriptor.orderBy.length > 0) {
|
|
1300
1309
|
const orderParts = descriptor.orderBy.map((o) => {
|
|
1301
1310
|
validateFieldName(o.field, fields);
|
|
1302
|
-
return `${o.field} ${o.direction.toUpperCase()}`;
|
|
1311
|
+
return `${(0, import_core8.quoteIdent)(o.field)} ${o.direction.toUpperCase()}`;
|
|
1303
1312
|
});
|
|
1304
1313
|
parts.push(`ORDER BY ${orderParts.join(", ")}`);
|
|
1305
1314
|
}
|
|
@@ -1313,7 +1322,7 @@ function buildSelectQuery(descriptor, fields) {
|
|
|
1313
1322
|
}
|
|
1314
1323
|
function buildCountQuery(descriptor, fields) {
|
|
1315
1324
|
const params = [];
|
|
1316
|
-
const parts = [`SELECT COUNT(*) as count FROM ${descriptor.collection}`];
|
|
1325
|
+
const parts = [`SELECT COUNT(*) as count FROM ${(0, import_core8.quoteIdent)(descriptor.collection)}`];
|
|
1317
1326
|
const whereClause = buildWhereClauseParts(descriptor.where, fields, params);
|
|
1318
1327
|
const deletedFilter = "_deleted = 0";
|
|
1319
1328
|
if (whereClause) {
|
|
@@ -1327,17 +1336,18 @@ function buildInsertQuery(collection, record) {
|
|
|
1327
1336
|
const columns = Object.keys(record);
|
|
1328
1337
|
const placeholders = columns.map(() => "?");
|
|
1329
1338
|
const params = Object.values(record);
|
|
1330
|
-
const
|
|
1339
|
+
const quotedColumns = columns.map((col) => (0, import_core8.quoteIdent)(col));
|
|
1340
|
+
const sql = `INSERT INTO ${(0, import_core8.quoteIdent)(collection)} (${quotedColumns.join(", ")}) VALUES (${placeholders.join(", ")})`;
|
|
1331
1341
|
return { sql, params };
|
|
1332
1342
|
}
|
|
1333
1343
|
function buildUpdateQuery(collection, id, changes) {
|
|
1334
|
-
const setClauses = Object.keys(changes).map((col) => `${col} = ?`);
|
|
1344
|
+
const setClauses = Object.keys(changes).map((col) => `${(0, import_core8.quoteIdent)(col)} = ?`);
|
|
1335
1345
|
const params = [...Object.values(changes), id];
|
|
1336
|
-
const sql = `UPDATE ${collection} SET ${setClauses.join(", ")} WHERE id = ?`;
|
|
1346
|
+
const sql = `UPDATE ${(0, import_core8.quoteIdent)(collection)} SET ${setClauses.join(", ")} WHERE id = ?`;
|
|
1337
1347
|
return { sql, params };
|
|
1338
1348
|
}
|
|
1339
1349
|
function buildFieldFastForwardUpdateQuery(collection, id, fieldChanges, remoteVersion, wallTime, options) {
|
|
1340
|
-
const fieldClauses = Object.keys(fieldChanges).map((col) => `${col} = ?`);
|
|
1350
|
+
const fieldClauses = Object.keys(fieldChanges).map((col) => `${(0, import_core8.quoteIdent)(col)} = ?`);
|
|
1341
1351
|
const setClauses = [
|
|
1342
1352
|
...fieldClauses,
|
|
1343
1353
|
"_version = CASE WHEN _version >= ? THEN _version ELSE ? END",
|
|
@@ -1355,25 +1365,25 @@ function buildFieldFastForwardUpdateQuery(collection, id, fieldChanges, remoteVe
|
|
|
1355
1365
|
params.push(options.maxCreatedAt, options.maxCreatedAt);
|
|
1356
1366
|
}
|
|
1357
1367
|
params.push(id);
|
|
1358
|
-
const sql = `UPDATE ${collection} SET ${setClauses.join(", ")} WHERE id = ?`;
|
|
1368
|
+
const sql = `UPDATE ${(0, import_core8.quoteIdent)(collection)} SET ${setClauses.join(", ")} WHERE id = ?`;
|
|
1359
1369
|
return { sql, params };
|
|
1360
1370
|
}
|
|
1361
1371
|
function buildSoftDeleteQuery(collection, id, updatedAt, version) {
|
|
1362
1372
|
if (version !== void 0) {
|
|
1363
1373
|
return {
|
|
1364
|
-
sql: `UPDATE ${collection} SET _deleted = 1, _updated_at = ?, _version = ? WHERE id = ?`,
|
|
1374
|
+
sql: `UPDATE ${(0, import_core8.quoteIdent)(collection)} SET _deleted = 1, _updated_at = ?, _version = ? WHERE id = ?`,
|
|
1365
1375
|
params: [updatedAt, version, id]
|
|
1366
1376
|
};
|
|
1367
1377
|
}
|
|
1368
1378
|
return {
|
|
1369
|
-
sql: `UPDATE ${collection} SET _deleted = 1, _updated_at = ? WHERE id = ?`,
|
|
1379
|
+
sql: `UPDATE ${(0, import_core8.quoteIdent)(collection)} SET _deleted = 1, _updated_at = ? WHERE id = ?`,
|
|
1370
1380
|
params: [updatedAt, id]
|
|
1371
1381
|
};
|
|
1372
1382
|
}
|
|
1373
1383
|
function buildLwwSoftDeleteQuery(collection, id, updatedAt, version) {
|
|
1374
1384
|
const lww = lwwVersionWhereClause(version);
|
|
1375
1385
|
return {
|
|
1376
|
-
sql: `UPDATE ${collection} SET _deleted = 1, _updated_at = ?, _version = ? WHERE id = ? AND ${lww.sql}`,
|
|
1386
|
+
sql: `UPDATE ${(0, import_core8.quoteIdent)(collection)} SET _deleted = 1, _updated_at = ?, _version = ? WHERE id = ? AND ${lww.sql}`,
|
|
1377
1387
|
params: [updatedAt, version, id, ...lww.params]
|
|
1378
1388
|
};
|
|
1379
1389
|
}
|
|
@@ -1404,31 +1414,32 @@ function buildWhereClauseParts(where, fields, params) {
|
|
|
1404
1414
|
}
|
|
1405
1415
|
function buildOperatorCondition(fieldName, operator, value, descriptor, params) {
|
|
1406
1416
|
const sqlValue = descriptor?.kind === "boolean" && typeof value === "boolean" ? value ? 1 : 0 : value;
|
|
1417
|
+
const column = (0, import_core8.quoteIdent)(fieldName);
|
|
1407
1418
|
switch (operator) {
|
|
1408
1419
|
case "$eq":
|
|
1409
1420
|
if (sqlValue === null) {
|
|
1410
|
-
return `${
|
|
1421
|
+
return `${column} IS NULL`;
|
|
1411
1422
|
}
|
|
1412
1423
|
params.push(sqlValue);
|
|
1413
|
-
return `${
|
|
1424
|
+
return `${column} = ?`;
|
|
1414
1425
|
case "$ne":
|
|
1415
1426
|
if (sqlValue === null) {
|
|
1416
|
-
return `${
|
|
1427
|
+
return `${column} IS NOT NULL`;
|
|
1417
1428
|
}
|
|
1418
1429
|
params.push(sqlValue);
|
|
1419
|
-
return `${
|
|
1430
|
+
return `${column} != ?`;
|
|
1420
1431
|
case "$gt":
|
|
1421
1432
|
params.push(sqlValue);
|
|
1422
|
-
return `${
|
|
1433
|
+
return `${column} > ?`;
|
|
1423
1434
|
case "$gte":
|
|
1424
1435
|
params.push(sqlValue);
|
|
1425
|
-
return `${
|
|
1436
|
+
return `${column} >= ?`;
|
|
1426
1437
|
case "$lt":
|
|
1427
1438
|
params.push(sqlValue);
|
|
1428
|
-
return `${
|
|
1439
|
+
return `${column} < ?`;
|
|
1429
1440
|
case "$lte":
|
|
1430
1441
|
params.push(sqlValue);
|
|
1431
|
-
return `${
|
|
1442
|
+
return `${column} <= ?`;
|
|
1432
1443
|
case "$in": {
|
|
1433
1444
|
if (!Array.isArray(sqlValue)) {
|
|
1434
1445
|
throw new QueryError(`$in operator requires an array value for field "${fieldName}"`, {
|
|
@@ -1442,7 +1453,7 @@ function buildOperatorCondition(fieldName, operator, value, descriptor, params)
|
|
|
1442
1453
|
descriptor?.kind === "boolean" && typeof item === "boolean" ? item ? 1 : 0 : item
|
|
1443
1454
|
);
|
|
1444
1455
|
}
|
|
1445
|
-
return `${
|
|
1456
|
+
return `${column} IN (${placeholders.join(", ")})`;
|
|
1446
1457
|
}
|
|
1447
1458
|
default:
|
|
1448
1459
|
throw new QueryError(`Unknown operator "${operator}"`, { operator });
|
|
@@ -1522,7 +1533,7 @@ function resolveCausalDeps(ctx) {
|
|
|
1522
1533
|
// src/mutations/execute-delete.ts
|
|
1523
1534
|
async function executeDelete(ctx, id, options) {
|
|
1524
1535
|
const currentRows = await ctx.adapter.query(
|
|
1525
|
-
`SELECT * FROM ${ctx.collection} WHERE id = ? AND _deleted = 0`,
|
|
1536
|
+
`SELECT * FROM ${(0, import_core9.quoteIdent)(ctx.collection)} WHERE id = ? AND _deleted = 0`,
|
|
1526
1537
|
[id]
|
|
1527
1538
|
);
|
|
1528
1539
|
if (!currentRows[0]) {
|
|
@@ -1534,7 +1545,7 @@ async function executeDelete(ctx, id, options) {
|
|
|
1534
1545
|
await ctx.adapter.transaction(async (tx) => {
|
|
1535
1546
|
if (!operation) {
|
|
1536
1547
|
const sequenceNumber = await allocateNextSequenceInTransaction(tx, ctx.nodeId);
|
|
1537
|
-
operation = await (0,
|
|
1548
|
+
operation = await (0, import_core9.createOperation)(
|
|
1538
1549
|
{
|
|
1539
1550
|
nodeId: ctx.nodeId,
|
|
1540
1551
|
type: "delete",
|
|
@@ -1581,7 +1592,7 @@ async function executeDelete(ctx, id, options) {
|
|
|
1581
1592
|
}
|
|
1582
1593
|
|
|
1583
1594
|
// src/mutations/execute-insert.ts
|
|
1584
|
-
var
|
|
1595
|
+
var import_core10 = require("@korajs/core");
|
|
1585
1596
|
|
|
1586
1597
|
// src/lww/field-versions.ts
|
|
1587
1598
|
function parseFieldVersions(raw) {
|
|
@@ -1638,14 +1649,14 @@ function resolvePerFieldLww(current, incomingFields, incomingVersion, rowVersion
|
|
|
1638
1649
|
init_op_data_encoding();
|
|
1639
1650
|
init_serializer();
|
|
1640
1651
|
async function executeInsert(ctx, data) {
|
|
1641
|
-
const validated = (0,
|
|
1642
|
-
const recordId = (0,
|
|
1652
|
+
const validated = (0, import_core10.validateRecord)(ctx.collection, ctx.definition, data, "insert");
|
|
1653
|
+
const recordId = (0, import_core10.generateUUIDv7)();
|
|
1643
1654
|
for (const [fieldName, descriptor] of Object.entries(ctx.definition.fields)) {
|
|
1644
1655
|
if (descriptor.auto && descriptor.kind === "timestamp") {
|
|
1645
1656
|
validated[fieldName] = Date.now();
|
|
1646
1657
|
}
|
|
1647
1658
|
}
|
|
1648
|
-
const writeData = await (0,
|
|
1659
|
+
const writeData = await (0, import_core10.transformSecretFieldsForWrite)(
|
|
1649
1660
|
validated,
|
|
1650
1661
|
ctx.definition,
|
|
1651
1662
|
ctx.secretKeyProvider
|
|
@@ -1655,7 +1666,7 @@ async function executeInsert(ctx, data) {
|
|
|
1655
1666
|
let record;
|
|
1656
1667
|
await ctx.adapter.transaction(async (tx) => {
|
|
1657
1668
|
const sequenceNumber = await allocateNextSequenceInTransaction(tx, ctx.nodeId);
|
|
1658
|
-
operation = await (0,
|
|
1669
|
+
operation = await (0, import_core10.createOperation)(
|
|
1659
1670
|
{
|
|
1660
1671
|
nodeId: ctx.nodeId,
|
|
1661
1672
|
type: "insert",
|
|
@@ -1705,13 +1716,13 @@ async function executeInsert(ctx, data) {
|
|
|
1705
1716
|
}
|
|
1706
1717
|
|
|
1707
1718
|
// src/mutations/execute-update.ts
|
|
1708
|
-
var
|
|
1719
|
+
var import_core12 = require("@korajs/core");
|
|
1709
1720
|
init_op_data_encoding();
|
|
1710
1721
|
init_serializer();
|
|
1711
1722
|
|
|
1712
1723
|
// src/state-machine/state-validator.ts
|
|
1713
|
-
var
|
|
1714
|
-
var InvalidStateTransitionError = class extends
|
|
1724
|
+
var import_core11 = require("@korajs/core");
|
|
1725
|
+
var InvalidStateTransitionError = class extends import_core11.KoraError {
|
|
1715
1726
|
constructor(collection, recordId, field, fromState, toState, allowedStates) {
|
|
1716
1727
|
super(
|
|
1717
1728
|
`Invalid state transition in collection "${collection}": cannot transition field "${field}" from "${fromState}" to "${toState}". Allowed transitions from "${fromState}": ${allowedStates.length > 0 ? allowedStates.join(", ") : "(none -- terminal state)"}`,
|
|
@@ -1745,7 +1756,7 @@ function validateStateTransition(collectionName, recordId, stateMachine, current
|
|
|
1745
1756
|
collection: collectionName,
|
|
1746
1757
|
transitions: stateMachine.transitions
|
|
1747
1758
|
};
|
|
1748
|
-
const transitionResult = (0,
|
|
1759
|
+
const transitionResult = (0, import_core11.validateTransition)(constraint, currentState, newState);
|
|
1749
1760
|
if (transitionResult.valid) {
|
|
1750
1761
|
return { valid: true, allowedStates: transitionResult.allowedTargets };
|
|
1751
1762
|
}
|
|
@@ -1794,14 +1805,14 @@ function validateUpdateStateMachine(collectionName, recordId, collectionDef, cur
|
|
|
1794
1805
|
// src/mutations/execute-update.ts
|
|
1795
1806
|
async function executeUpdate(ctx, id, data) {
|
|
1796
1807
|
const currentRows = await ctx.adapter.query(
|
|
1797
|
-
`SELECT * FROM ${ctx.collection} WHERE id = ? AND _deleted = 0`,
|
|
1808
|
+
`SELECT * FROM ${(0, import_core12.quoteIdent)(ctx.collection)} WHERE id = ? AND _deleted = 0`,
|
|
1798
1809
|
[id]
|
|
1799
1810
|
);
|
|
1800
1811
|
const currentRow = currentRows[0];
|
|
1801
1812
|
if (!currentRow) {
|
|
1802
1813
|
throw new RecordNotFoundError(ctx.collection, id);
|
|
1803
1814
|
}
|
|
1804
|
-
let validated = (0,
|
|
1815
|
+
let validated = (0, import_core12.validateRecord)(ctx.collection, ctx.definition, data, "update");
|
|
1805
1816
|
const currentRecord = deserializeRecord(currentRow, ctx.definition.fields);
|
|
1806
1817
|
validated = validateUpdateStateMachine(
|
|
1807
1818
|
ctx.collection,
|
|
@@ -1819,14 +1830,14 @@ async function executeUpdate(ctx, id, data) {
|
|
|
1819
1830
|
for (const key of Object.keys(validated)) {
|
|
1820
1831
|
const value = validated[key];
|
|
1821
1832
|
previousData[key] = currentRecord[key];
|
|
1822
|
-
if ((0,
|
|
1823
|
-
resolvedData[key] = (0,
|
|
1824
|
-
atomicOps[key] = (0,
|
|
1833
|
+
if ((0, import_core12.isAtomicOp)(value)) {
|
|
1834
|
+
resolvedData[key] = (0, import_core12.resolveAtomicOp)(currentRecord[key], value);
|
|
1835
|
+
atomicOps[key] = (0, import_core12.toAtomicOp)(value);
|
|
1825
1836
|
} else {
|
|
1826
1837
|
resolvedData[key] = value;
|
|
1827
1838
|
}
|
|
1828
1839
|
}
|
|
1829
|
-
const writeData = await (0,
|
|
1840
|
+
const writeData = await (0, import_core12.transformSecretFieldsForWrite)(
|
|
1830
1841
|
resolvedData,
|
|
1831
1842
|
ctx.definition,
|
|
1832
1843
|
ctx.secretKeyProvider
|
|
@@ -1836,7 +1847,7 @@ async function executeUpdate(ctx, id, data) {
|
|
|
1836
1847
|
let operation;
|
|
1837
1848
|
await ctx.adapter.transaction(async (tx) => {
|
|
1838
1849
|
const sequenceNumber = await allocateNextSequenceInTransaction(tx, ctx.nodeId);
|
|
1839
|
-
operation = await (0,
|
|
1850
|
+
operation = await (0, import_core12.createOperation)(
|
|
1840
1851
|
{
|
|
1841
1852
|
nodeId: ctx.nodeId,
|
|
1842
1853
|
type: "update",
|
|
@@ -1876,7 +1887,7 @@ async function executeUpdate(ctx, id, data) {
|
|
|
1876
1887
|
});
|
|
1877
1888
|
ctx.onMutation(ctx.collection, operation);
|
|
1878
1889
|
const rows = await ctx.adapter.query(
|
|
1879
|
-
`SELECT * FROM ${ctx.collection} WHERE id = ? AND _deleted = 0`,
|
|
1890
|
+
`SELECT * FROM ${(0, import_core12.quoteIdent)(ctx.collection)} WHERE id = ? AND _deleted = 0`,
|
|
1880
1891
|
[id]
|
|
1881
1892
|
);
|
|
1882
1893
|
const row = rows[0];
|
|
@@ -1939,7 +1950,7 @@ var Collection = class {
|
|
|
1939
1950
|
}
|
|
1940
1951
|
async findById(id) {
|
|
1941
1952
|
const rows = await this.adapter.query(
|
|
1942
|
-
`SELECT * FROM ${this.name} WHERE id = ? AND _deleted = 0`,
|
|
1953
|
+
`SELECT * FROM ${(0, import_core13.quoteIdent)(this.name)} WHERE id = ? AND _deleted = 0`,
|
|
1943
1954
|
[id]
|
|
1944
1955
|
);
|
|
1945
1956
|
const row = rows[0];
|
|
@@ -1972,6 +1983,7 @@ var Collection = class {
|
|
|
1972
1983
|
};
|
|
1973
1984
|
|
|
1974
1985
|
// src/query/query-builder.ts
|
|
1986
|
+
var import_core14 = require("@korajs/core");
|
|
1975
1987
|
init_serializer();
|
|
1976
1988
|
|
|
1977
1989
|
// src/query/pluralize.ts
|
|
@@ -2203,7 +2215,7 @@ var QueryBuilder = class _QueryBuilder {
|
|
|
2203
2215
|
const relatedDef = this.schema?.collections[relatedCollection];
|
|
2204
2216
|
if (!relatedDef) return;
|
|
2205
2217
|
const placeholders = uniqueFks.map(() => "?").join(", ");
|
|
2206
|
-
const sql = `SELECT * FROM ${relatedCollection} WHERE id IN (${placeholders}) AND _deleted = 0`;
|
|
2218
|
+
const sql = `SELECT * FROM ${(0, import_core14.quoteIdent)(relatedCollection)} WHERE id IN (${placeholders}) AND _deleted = 0`;
|
|
2207
2219
|
const rows = await this.adapter.query(sql, uniqueFks);
|
|
2208
2220
|
const relatedRecords = rows.map((row) => deserializeRecord(row, relatedDef.fields));
|
|
2209
2221
|
const lookup = /* @__PURE__ */ new Map();
|
|
@@ -2226,7 +2238,7 @@ var QueryBuilder = class _QueryBuilder {
|
|
|
2226
2238
|
if (!relatedDef) return;
|
|
2227
2239
|
const fkField = relation.field;
|
|
2228
2240
|
const placeholders = primaryIds.map(() => "?").join(", ");
|
|
2229
|
-
const sql = `SELECT * FROM ${relatedCollection} WHERE ${fkField} IN (${placeholders}) AND _deleted = 0`;
|
|
2241
|
+
const sql = `SELECT * FROM ${(0, import_core14.quoteIdent)(relatedCollection)} WHERE ${(0, import_core14.quoteIdent)(fkField)} IN (${placeholders}) AND _deleted = 0`;
|
|
2230
2242
|
const rows = await this.adapter.query(sql, primaryIds);
|
|
2231
2243
|
const relatedRecords = rows.map((row) => deserializeRecord(row, relatedDef.fields));
|
|
2232
2244
|
const grouped = /* @__PURE__ */ new Map();
|
|
@@ -2268,7 +2280,7 @@ var QueryError2 = class extends Error {
|
|
|
2268
2280
|
};
|
|
2269
2281
|
|
|
2270
2282
|
// src/relations/relation-enforcer.ts
|
|
2271
|
-
var
|
|
2283
|
+
var import_core15 = require("@korajs/core");
|
|
2272
2284
|
init_serializer();
|
|
2273
2285
|
|
|
2274
2286
|
// src/relations/relation-lookup.ts
|
|
@@ -2293,7 +2305,7 @@ function getIncomingRelations(lookup, collection) {
|
|
|
2293
2305
|
}
|
|
2294
2306
|
|
|
2295
2307
|
// src/relations/relation-enforcer.ts
|
|
2296
|
-
var ReferentialIntegrityError = class extends
|
|
2308
|
+
var ReferentialIntegrityError = class extends import_core15.KoraError {
|
|
2297
2309
|
constructor(collection, recordId, referencingCollection, relationName, referencingCount) {
|
|
2298
2310
|
super(
|
|
2299
2311
|
`Cannot delete record "${recordId}" from "${collection}": ${referencingCount} record(s) in "${referencingCollection}" reference it via relation "${relationName}" with onDelete: 'restrict'. Delete or reassign the referencing records first.`,
|
|
@@ -2372,7 +2384,7 @@ var RelationEnforcer = class {
|
|
|
2372
2384
|
async enforceCascade(incoming, deletedRecordId, tx, causalDeps) {
|
|
2373
2385
|
const { sourceCollection, foreignKeyField } = incoming;
|
|
2374
2386
|
const referencingRows = await tx.query(
|
|
2375
|
-
`SELECT id FROM ${sourceCollection} WHERE ${foreignKeyField} = ? AND _deleted = 0`,
|
|
2387
|
+
`SELECT id FROM ${(0, import_core15.quoteIdent)(sourceCollection)} WHERE ${(0, import_core15.quoteIdent)(foreignKeyField)} = ? AND _deleted = 0`,
|
|
2376
2388
|
[deletedRecordId]
|
|
2377
2389
|
);
|
|
2378
2390
|
if (referencingRows.length === 0) {
|
|
@@ -2382,7 +2394,7 @@ var RelationEnforcer = class {
|
|
|
2382
2394
|
for (const row of referencingRows) {
|
|
2383
2395
|
const now = Date.now();
|
|
2384
2396
|
const sequenceNumber = await allocateNextSequenceInTransaction(tx, this.nodeId);
|
|
2385
|
-
const operation = await (0,
|
|
2397
|
+
const operation = await (0, import_core15.createOperation)(
|
|
2386
2398
|
{
|
|
2387
2399
|
nodeId: this.nodeId,
|
|
2388
2400
|
type: "delete",
|
|
@@ -2419,7 +2431,7 @@ var RelationEnforcer = class {
|
|
|
2419
2431
|
return [];
|
|
2420
2432
|
}
|
|
2421
2433
|
const referencingRows = await tx.query(
|
|
2422
|
-
`SELECT id FROM ${sourceCollection} WHERE ${foreignKeyField} = ? AND _deleted = 0`,
|
|
2434
|
+
`SELECT id FROM ${(0, import_core15.quoteIdent)(sourceCollection)} WHERE ${(0, import_core15.quoteIdent)(foreignKeyField)} = ? AND _deleted = 0`,
|
|
2423
2435
|
[deletedRecordId]
|
|
2424
2436
|
);
|
|
2425
2437
|
if (referencingRows.length === 0) {
|
|
@@ -2431,7 +2443,7 @@ var RelationEnforcer = class {
|
|
|
2431
2443
|
const sequenceNumber = await allocateNextSequenceInTransaction(tx, this.nodeId);
|
|
2432
2444
|
const updateData = { [foreignKeyField]: null };
|
|
2433
2445
|
const previousData = { [foreignKeyField]: deletedRecordId };
|
|
2434
|
-
const operation = await (0,
|
|
2446
|
+
const operation = await (0, import_core15.createOperation)(
|
|
2435
2447
|
{
|
|
2436
2448
|
nodeId: this.nodeId,
|
|
2437
2449
|
type: "update",
|
|
@@ -2467,7 +2479,7 @@ var RelationEnforcer = class {
|
|
|
2467
2479
|
async enforceRestrict(incoming, deletedRecordId, tx) {
|
|
2468
2480
|
const { sourceCollection, foreignKeyField, relationName } = incoming;
|
|
2469
2481
|
const countRows = await tx.query(
|
|
2470
|
-
`SELECT COUNT(*) as cnt FROM ${sourceCollection} WHERE ${foreignKeyField} = ? AND _deleted = 0`,
|
|
2482
|
+
`SELECT COUNT(*) as cnt FROM ${(0, import_core15.quoteIdent)(sourceCollection)} WHERE ${(0, import_core15.quoteIdent)(foreignKeyField)} = ? AND _deleted = 0`,
|
|
2471
2483
|
[deletedRecordId]
|
|
2472
2484
|
);
|
|
2473
2485
|
const count = countRows[0]?.cnt ?? 0;
|
|
@@ -2492,7 +2504,7 @@ var RelationEnforcer = class {
|
|
|
2492
2504
|
};
|
|
2493
2505
|
|
|
2494
2506
|
// src/replay/replay-to.ts
|
|
2495
|
-
var
|
|
2507
|
+
var import_core16 = require("@korajs/core");
|
|
2496
2508
|
var import_internal = require("@korajs/core/internal");
|
|
2497
2509
|
init_op_data_encoding();
|
|
2498
2510
|
function collectCausalClosure(allOps, targetOperationId) {
|
|
@@ -2502,7 +2514,7 @@ function collectCausalClosure(allOps, targetOperationId) {
|
|
|
2502
2514
|
}
|
|
2503
2515
|
const target = opMap.get(targetOperationId);
|
|
2504
2516
|
if (!target) {
|
|
2505
|
-
throw new
|
|
2517
|
+
throw new import_core16.OperationError(
|
|
2506
2518
|
`Operation "${targetOperationId}" not found in the local operation log`,
|
|
2507
2519
|
{
|
|
2508
2520
|
operationId: targetOperationId
|
|
@@ -2534,7 +2546,7 @@ function buildReplaySnapshot(schema, allOps, targetOperationId) {
|
|
|
2534
2546
|
const operationsApplied = collectCausalClosure(allOps, targetOperationId);
|
|
2535
2547
|
const targetOperation = operationsApplied.find((op) => op.id === targetOperationId);
|
|
2536
2548
|
if (!targetOperation) {
|
|
2537
|
-
throw new
|
|
2549
|
+
throw new import_core16.OperationError(`Operation "${targetOperationId}" not found after causal sort`, {
|
|
2538
2550
|
operationId: targetOperationId
|
|
2539
2551
|
});
|
|
2540
2552
|
}
|
|
@@ -2660,7 +2672,7 @@ function toCollectionRecord(record, definition) {
|
|
|
2660
2672
|
}
|
|
2661
2673
|
|
|
2662
2674
|
// src/sequences/sequence-manager.ts
|
|
2663
|
-
var
|
|
2675
|
+
var import_core17 = require("@korajs/core");
|
|
2664
2676
|
var SequenceManager = class {
|
|
2665
2677
|
adapter;
|
|
2666
2678
|
nodeId;
|
|
@@ -2678,7 +2690,7 @@ var SequenceManager = class {
|
|
|
2678
2690
|
async next(name, config) {
|
|
2679
2691
|
const scope = config?.scope ?? "";
|
|
2680
2692
|
const startAt = config?.startAt ?? 1;
|
|
2681
|
-
const format = config?.format ?? (0,
|
|
2693
|
+
const format = config?.format ?? (0, import_core17.defaultSequenceFormat)(name);
|
|
2682
2694
|
let counter = 0;
|
|
2683
2695
|
await this.adapter.transaction(async (tx) => {
|
|
2684
2696
|
const rows = await tx.query(
|
|
@@ -2700,7 +2712,7 @@ var SequenceManager = class {
|
|
|
2700
2712
|
);
|
|
2701
2713
|
}
|
|
2702
2714
|
});
|
|
2703
|
-
return (0,
|
|
2715
|
+
return (0, import_core17.formatSequenceValue)(format, counter, this.nodeId);
|
|
2704
2716
|
}
|
|
2705
2717
|
/**
|
|
2706
2718
|
* Get the current counter value without incrementing.
|
|
@@ -3159,10 +3171,10 @@ var SubscriptionManager = class {
|
|
|
3159
3171
|
};
|
|
3160
3172
|
|
|
3161
3173
|
// src/sync/rebase-unsynced-operations.ts
|
|
3162
|
-
var
|
|
3174
|
+
var import_core18 = require("@korajs/core");
|
|
3163
3175
|
var import_internal2 = require("@korajs/core/internal");
|
|
3164
3176
|
init_serializer();
|
|
3165
|
-
var LOGICAL_COUNTER_LIMIT =
|
|
3177
|
+
var LOGICAL_COUNTER_LIMIT = import_core18.MAX_LOGICAL + 1;
|
|
3166
3178
|
function emptyResult() {
|
|
3167
3179
|
return { operations: [], idMapping: {}, rebasedCount: 0, newMaxTimestamp: null };
|
|
3168
3180
|
}
|
|
@@ -3174,7 +3186,9 @@ async function rebaseUnsyncedOperationsInLog(adapter, schema, unsyncedOpIds, cor
|
|
|
3174
3186
|
const rebased = [];
|
|
3175
3187
|
let maxOtherSerializedTs = null;
|
|
3176
3188
|
for (const collectionName of Object.keys(schema.collections)) {
|
|
3177
|
-
const rows = await adapter.query(
|
|
3189
|
+
const rows = await adapter.query(
|
|
3190
|
+
`SELECT * FROM ${(0, import_core18.quoteIdent)(`_kora_ops_${collectionName}`)}`
|
|
3191
|
+
);
|
|
3178
3192
|
for (const row of rows) {
|
|
3179
3193
|
if (rebaseIds.has(row.id)) {
|
|
3180
3194
|
rebased.push(deserializeOperationWithCollection(row, collectionName));
|
|
@@ -3186,9 +3200,9 @@ async function rebaseUnsyncedOperationsInLog(adapter, schema, unsyncedOpIds, cor
|
|
|
3186
3200
|
if (rebased.length === 0) {
|
|
3187
3201
|
return emptyResult();
|
|
3188
3202
|
}
|
|
3189
|
-
const maxOtherWallTime = maxOtherSerializedTs === null ? Number.NEGATIVE_INFINITY :
|
|
3203
|
+
const maxOtherWallTime = maxOtherSerializedTs === null ? Number.NEGATIVE_INFINITY : import_core18.HybridLogicalClock.deserialize(maxOtherSerializedTs).wallTime;
|
|
3190
3204
|
const baseWallTime = Math.max(correctedNowMs, maxOtherWallTime + 1);
|
|
3191
|
-
rebased.sort((a, b) =>
|
|
3205
|
+
rebased.sort((a, b) => import_core18.HybridLogicalClock.compare(a.timestamp, b.timestamp));
|
|
3192
3206
|
const newTimestamps = rebased.map((op, i) => ({
|
|
3193
3207
|
// Spill into wallTime past the 5-digit logical serialization limit so the
|
|
3194
3208
|
// serialized order stays correct even for enormous offline queues.
|
|
@@ -3216,7 +3230,7 @@ async function rebaseUnsyncedOperationsInLog(adapter, schema, unsyncedOpIds, cor
|
|
|
3216
3230
|
schemaVersion: op.schemaVersion,
|
|
3217
3231
|
...op.atomicOps !== void 0 ? { atomicOps: op.atomicOps } : {}
|
|
3218
3232
|
};
|
|
3219
|
-
const newId = await (0, import_internal2.computeOperationId)(input,
|
|
3233
|
+
const newId = await (0, import_internal2.computeOperationId)(input, import_core18.HybridLogicalClock.serialize(ts));
|
|
3220
3234
|
idMapping[op.id] = newId;
|
|
3221
3235
|
newIds.push(newId);
|
|
3222
3236
|
}
|
|
@@ -3243,7 +3257,7 @@ async function rebaseUnsyncedOperationsInLog(adapter, schema, unsyncedOpIds, cor
|
|
|
3243
3257
|
continue;
|
|
3244
3258
|
}
|
|
3245
3259
|
const opsTable = `_kora_ops_${oldOp.collection}`;
|
|
3246
|
-
await tx.execute(`DELETE FROM ${opsTable} WHERE id = ?`, [oldOp.id]);
|
|
3260
|
+
await tx.execute(`DELETE FROM ${(0, import_core18.quoteIdent)(opsTable)} WHERE id = ?`, [oldOp.id]);
|
|
3247
3261
|
const opInsert = buildInsertQuery(
|
|
3248
3262
|
opsTable,
|
|
3249
3263
|
serializeOperation(newOp)
|
|
@@ -3252,11 +3266,11 @@ async function rebaseUnsyncedOperationsInLog(adapter, schema, unsyncedOpIds, cor
|
|
|
3252
3266
|
const oldVersion = serializeRowVersion(oldOp.timestamp);
|
|
3253
3267
|
const newVersion = serializeRowVersion(newOp.timestamp);
|
|
3254
3268
|
await tx.execute(
|
|
3255
|
-
`UPDATE ${oldOp.collection} SET _version = ?, _updated_at = ? WHERE id = ? AND _version = ?`,
|
|
3269
|
+
`UPDATE ${(0, import_core18.quoteIdent)(oldOp.collection)} SET _version = ?, _updated_at = ? WHERE id = ? AND _version = ?`,
|
|
3256
3270
|
[newVersion, newOp.timestamp.wallTime, oldOp.recordId, oldVersion]
|
|
3257
3271
|
);
|
|
3258
3272
|
const rows = await tx.query(
|
|
3259
|
-
`SELECT _field_versions FROM ${oldOp.collection} WHERE id = ?`,
|
|
3273
|
+
`SELECT _field_versions FROM ${(0, import_core18.quoteIdent)(oldOp.collection)} WHERE id = ?`,
|
|
3260
3274
|
[oldOp.recordId]
|
|
3261
3275
|
);
|
|
3262
3276
|
const fieldVersions = parseFieldVersions(rows[0]?._field_versions);
|
|
@@ -3268,14 +3282,14 @@ async function rebaseUnsyncedOperationsInLog(adapter, schema, unsyncedOpIds, cor
|
|
|
3268
3282
|
}
|
|
3269
3283
|
}
|
|
3270
3284
|
if (changed) {
|
|
3271
|
-
await tx.execute(
|
|
3272
|
-
|
|
3273
|
-
oldOp.recordId
|
|
3274
|
-
|
|
3285
|
+
await tx.execute(
|
|
3286
|
+
`UPDATE ${(0, import_core18.quoteIdent)(oldOp.collection)} SET _field_versions = ? WHERE id = ?`,
|
|
3287
|
+
[serializeFieldVersions(fieldVersions), oldOp.recordId]
|
|
3288
|
+
);
|
|
3275
3289
|
}
|
|
3276
3290
|
if (oldOp.type === "insert") {
|
|
3277
3291
|
await tx.execute(
|
|
3278
|
-
`UPDATE ${oldOp.collection} SET _created_at = ? WHERE id = ? AND _created_at = ?`,
|
|
3292
|
+
`UPDATE ${(0, import_core18.quoteIdent)(oldOp.collection)} SET _created_at = ? WHERE id = ? AND _created_at = ?`,
|
|
3279
3293
|
[newOp.timestamp.wallTime, oldOp.recordId, oldOp.timestamp.wallTime]
|
|
3280
3294
|
);
|
|
3281
3295
|
}
|
|
@@ -3291,7 +3305,7 @@ async function rebaseUnsyncedOperationsInLog(adapter, schema, unsyncedOpIds, cor
|
|
|
3291
3305
|
}
|
|
3292
3306
|
|
|
3293
3307
|
// src/transaction/transaction-context.ts
|
|
3294
|
-
var
|
|
3308
|
+
var import_core19 = require("@korajs/core");
|
|
3295
3309
|
init_op_data_encoding();
|
|
3296
3310
|
init_serializer();
|
|
3297
3311
|
var TransactionContext = class {
|
|
@@ -3303,7 +3317,7 @@ var TransactionContext = class {
|
|
|
3303
3317
|
config;
|
|
3304
3318
|
constructor(config) {
|
|
3305
3319
|
this.config = config;
|
|
3306
|
-
this.transactionId = (0,
|
|
3320
|
+
this.transactionId = (0, import_core19.generateUUIDv7)();
|
|
3307
3321
|
}
|
|
3308
3322
|
/**
|
|
3309
3323
|
* Set a human-readable mutation name for this transaction.
|
|
@@ -3418,8 +3432,8 @@ var TransactionContext = class {
|
|
|
3418
3432
|
}
|
|
3419
3433
|
async insert(collectionName, definition, data) {
|
|
3420
3434
|
this.ensureActive();
|
|
3421
|
-
const validated = (0,
|
|
3422
|
-
const recordId = (0,
|
|
3435
|
+
const validated = (0, import_core19.validateRecord)(collectionName, definition, data, "insert");
|
|
3436
|
+
const recordId = (0, import_core19.generateUUIDv7)();
|
|
3423
3437
|
const now = Date.now();
|
|
3424
3438
|
for (const [fieldName, descriptor] of Object.entries(definition.fields)) {
|
|
3425
3439
|
if (descriptor.auto && descriptor.kind === "timestamp") {
|
|
@@ -3428,7 +3442,7 @@ var TransactionContext = class {
|
|
|
3428
3442
|
}
|
|
3429
3443
|
const sequenceNumber = await this.config.sequenceAllocator.allocate();
|
|
3430
3444
|
const causalDeps = this.config.causalTracker?.nextCausalDeps(collectionName, true) ?? [];
|
|
3431
|
-
const operation = await (0,
|
|
3445
|
+
const operation = await (0, import_core19.createOperation)(
|
|
3432
3446
|
{
|
|
3433
3447
|
nodeId: this.config.nodeId,
|
|
3434
3448
|
type: "insert",
|
|
@@ -3483,7 +3497,7 @@ var TransactionContext = class {
|
|
|
3483
3497
|
if (!currentRecord) {
|
|
3484
3498
|
throw new RecordNotFoundError(collectionName, id);
|
|
3485
3499
|
}
|
|
3486
|
-
const validated = (0,
|
|
3500
|
+
const validated = (0, import_core19.validateRecord)(collectionName, definition, data, "update");
|
|
3487
3501
|
const now = Date.now();
|
|
3488
3502
|
const previousData = {};
|
|
3489
3503
|
const resolvedData = {};
|
|
@@ -3491,9 +3505,9 @@ var TransactionContext = class {
|
|
|
3491
3505
|
for (const key of Object.keys(validated)) {
|
|
3492
3506
|
const value = validated[key];
|
|
3493
3507
|
previousData[key] = currentRecord[key];
|
|
3494
|
-
if ((0,
|
|
3495
|
-
resolvedData[key] = (0,
|
|
3496
|
-
atomicOps[key] = (0,
|
|
3508
|
+
if ((0, import_core19.isAtomicOp)(value)) {
|
|
3509
|
+
resolvedData[key] = (0, import_core19.resolveAtomicOp)(currentRecord[key], value);
|
|
3510
|
+
atomicOps[key] = (0, import_core19.toAtomicOp)(value);
|
|
3497
3511
|
} else {
|
|
3498
3512
|
resolvedData[key] = value;
|
|
3499
3513
|
}
|
|
@@ -3501,7 +3515,7 @@ var TransactionContext = class {
|
|
|
3501
3515
|
const hasAtomicOps = Object.keys(atomicOps).length > 0;
|
|
3502
3516
|
const sequenceNumber = await this.config.sequenceAllocator.allocate();
|
|
3503
3517
|
const causalDeps = this.config.causalTracker?.nextCausalDeps(collectionName, true) ?? [];
|
|
3504
|
-
const operation = await (0,
|
|
3518
|
+
const operation = await (0, import_core19.createOperation)(
|
|
3505
3519
|
{
|
|
3506
3520
|
nodeId: this.config.nodeId,
|
|
3507
3521
|
type: "update",
|
|
@@ -3556,7 +3570,7 @@ var TransactionContext = class {
|
|
|
3556
3570
|
const now = Date.now();
|
|
3557
3571
|
const sequenceNumber = await this.config.sequenceAllocator.allocate();
|
|
3558
3572
|
const causalDeps = this.config.causalTracker?.nextCausalDeps(collectionName, true) ?? [];
|
|
3559
|
-
const operation = await (0,
|
|
3573
|
+
const operation = await (0, import_core19.createOperation)(
|
|
3560
3574
|
{
|
|
3561
3575
|
nodeId: this.config.nodeId,
|
|
3562
3576
|
type: "delete",
|
|
@@ -3606,7 +3620,7 @@ var TransactionContext = class {
|
|
|
3606
3620
|
}
|
|
3607
3621
|
}
|
|
3608
3622
|
const rows = await this.config.adapter.query(
|
|
3609
|
-
`SELECT * FROM ${collectionName} WHERE id = ? AND _deleted = 0`,
|
|
3623
|
+
`SELECT * FROM ${(0, import_core19.quoteIdent)(collectionName)} WHERE id = ? AND _deleted = 0`,
|
|
3610
3624
|
[id]
|
|
3611
3625
|
);
|
|
3612
3626
|
let record = rows[0] ? deserializeRecord(rows[0], definition.fields) : null;
|
|
@@ -3661,7 +3675,7 @@ var TransactionSequenceAllocator = class {
|
|
|
3661
3675
|
};
|
|
3662
3676
|
|
|
3663
3677
|
// src/store/tab-node-id.ts
|
|
3664
|
-
var
|
|
3678
|
+
var import_core20 = require("@korajs/core");
|
|
3665
3679
|
function perTabStorageKey(dbName) {
|
|
3666
3680
|
return `kora-tab-node-${dbName}`;
|
|
3667
3681
|
}
|
|
@@ -3682,7 +3696,7 @@ function resolvePerTabNodeId(dbName) {
|
|
|
3682
3696
|
if (existing) {
|
|
3683
3697
|
return existing;
|
|
3684
3698
|
}
|
|
3685
|
-
const nodeId = (0,
|
|
3699
|
+
const nodeId = (0, import_core20.generateUUIDv7)();
|
|
3686
3700
|
savePerTabNodeId(dbName, nodeId);
|
|
3687
3701
|
return nodeId;
|
|
3688
3702
|
}
|
|
@@ -3692,7 +3706,7 @@ var Store = class {
|
|
|
3692
3706
|
opened = false;
|
|
3693
3707
|
nodeId = "";
|
|
3694
3708
|
sequenceNumber = 0;
|
|
3695
|
-
versionVector = (0,
|
|
3709
|
+
versionVector = (0, import_core23.createVersionVector)();
|
|
3696
3710
|
clock = null;
|
|
3697
3711
|
collections = /* @__PURE__ */ new Map();
|
|
3698
3712
|
subscriptionManager;
|
|
@@ -3728,8 +3742,8 @@ var Store = class {
|
|
|
3728
3742
|
await this.adapter.open(this.schema);
|
|
3729
3743
|
await this.runMigrationsIfNeeded();
|
|
3730
3744
|
this.nodeId = await this.loadOrGenerateNodeId();
|
|
3731
|
-
this.clock = new
|
|
3732
|
-
this.causalTracker = new
|
|
3745
|
+
this.clock = new import_core23.HybridLogicalClock(this.nodeId);
|
|
3746
|
+
this.causalTracker = new import_core23.CausalTracker();
|
|
3733
3747
|
this.sequenceManager = new SequenceManager(this.adapter, this.nodeId);
|
|
3734
3748
|
this.sequenceNumber = await this.loadSequenceNumber();
|
|
3735
3749
|
this.versionVector = await this.loadVersionVector();
|
|
@@ -3841,7 +3855,7 @@ var Store = class {
|
|
|
3841
3855
|
return "skipped";
|
|
3842
3856
|
}
|
|
3843
3857
|
const existing = await this.adapter.query(
|
|
3844
|
-
`SELECT id FROM _kora_ops_${collection} WHERE id = ?`,
|
|
3858
|
+
`SELECT id FROM ${(0, import_core23.quoteIdent)(`_kora_ops_${collection}`)} WHERE id = ?`,
|
|
3845
3859
|
[op.id]
|
|
3846
3860
|
);
|
|
3847
3861
|
if (existing.length > 0) {
|
|
@@ -3946,7 +3960,7 @@ var Store = class {
|
|
|
3946
3960
|
const serializedChanges = serializeRecord(materializeSource, definition.fields);
|
|
3947
3961
|
const changedFields = Object.keys(serializedChanges);
|
|
3948
3962
|
const currentRows = await tx.query(
|
|
3949
|
-
`SELECT _version, _field_versions FROM ${collection} WHERE id = ?`,
|
|
3963
|
+
`SELECT _version, _field_versions FROM ${(0, import_core23.quoteIdent)(collection)} WHERE id = ?`,
|
|
3950
3964
|
[op.recordId]
|
|
3951
3965
|
);
|
|
3952
3966
|
const currentRow = currentRows[0];
|
|
@@ -4042,20 +4056,20 @@ var Store = class {
|
|
|
4042
4056
|
*/
|
|
4043
4057
|
async foldOrphanedOperations(tx, collection, definition, recordId) {
|
|
4044
4058
|
const orphanRows = await tx.query(
|
|
4045
|
-
`SELECT * FROM _kora_ops_${collection} WHERE record_id = ? AND type IN ('update', 'delete')`,
|
|
4059
|
+
`SELECT * FROM ${(0, import_core23.quoteIdent)(`_kora_ops_${collection}`)} WHERE record_id = ? AND type IN ('update', 'delete')`,
|
|
4046
4060
|
[recordId]
|
|
4047
4061
|
);
|
|
4048
4062
|
if (orphanRows.length === 0) {
|
|
4049
4063
|
return;
|
|
4050
4064
|
}
|
|
4051
|
-
const orphans = orphanRows.map((r) => deserializeOperationWithCollection(r, collection)).sort((a, b) =>
|
|
4065
|
+
const orphans = orphanRows.map((r) => deserializeOperationWithCollection(r, collection)).sort((a, b) => import_core23.HybridLogicalClock.compare(a.timestamp, b.timestamp));
|
|
4052
4066
|
for (const orphan of orphans) {
|
|
4053
4067
|
const orphanVersion = serializeRowVersion(orphan.timestamp);
|
|
4054
4068
|
const orphanWall = orphan.timestamp.wallTime;
|
|
4055
4069
|
if (orphan.type === "update" && orphan.data) {
|
|
4056
4070
|
const orphanChanges = serializeRecord(orphan.data, definition.fields);
|
|
4057
4071
|
const rows = await tx.query(
|
|
4058
|
-
`SELECT _version, _field_versions FROM ${collection} WHERE id = ?`,
|
|
4072
|
+
`SELECT _version, _field_versions FROM ${(0, import_core23.quoteIdent)(collection)} WHERE id = ?`,
|
|
4059
4073
|
[recordId]
|
|
4060
4074
|
);
|
|
4061
4075
|
const current = rows[0];
|
|
@@ -4105,7 +4119,7 @@ var Store = class {
|
|
|
4105
4119
|
const allOps = [];
|
|
4106
4120
|
for (const collectionName of Object.keys(this.schema.collections)) {
|
|
4107
4121
|
const rows = await this.adapter.query(
|
|
4108
|
-
`SELECT * FROM _kora_ops_${collectionName} WHERE node_id = ? AND sequence_number >= ? AND sequence_number <= ? ORDER BY sequence_number ASC`,
|
|
4122
|
+
`SELECT * FROM ${(0, import_core23.quoteIdent)(`_kora_ops_${collectionName}`)} WHERE node_id = ? AND sequence_number >= ? AND sequence_number <= ? ORDER BY sequence_number ASC`,
|
|
4109
4123
|
[nodeId, fromSeq, toSeq]
|
|
4110
4124
|
);
|
|
4111
4125
|
for (const row of rows) {
|
|
@@ -4124,7 +4138,7 @@ var Store = class {
|
|
|
4124
4138
|
const allOps = [];
|
|
4125
4139
|
for (const collectionName of Object.keys(this.schema.collections)) {
|
|
4126
4140
|
const rows = await this.adapter.query(
|
|
4127
|
-
`SELECT * FROM _kora_ops_${collectionName} ORDER BY sequence_number ASC`
|
|
4141
|
+
`SELECT * FROM ${(0, import_core23.quoteIdent)(`_kora_ops_${collectionName}`)} ORDER BY sequence_number ASC`
|
|
4128
4142
|
);
|
|
4129
4143
|
for (const row of rows) {
|
|
4130
4144
|
allOps.push(deserializeOperationWithCollection(row, collectionName));
|
|
@@ -4234,7 +4248,7 @@ var Store = class {
|
|
|
4234
4248
|
return null;
|
|
4235
4249
|
}
|
|
4236
4250
|
const rows = await this.adapter.query(
|
|
4237
|
-
`SELECT * FROM ${collection} WHERE id = ?`,
|
|
4251
|
+
`SELECT * FROM ${(0, import_core23.quoteIdent)(collection)} WHERE id = ?`,
|
|
4238
4252
|
[recordId]
|
|
4239
4253
|
);
|
|
4240
4254
|
const row = rows[0];
|
|
@@ -4259,7 +4273,7 @@ var Store = class {
|
|
|
4259
4273
|
return null;
|
|
4260
4274
|
}
|
|
4261
4275
|
const rows = await this.adapter.query(
|
|
4262
|
-
`SELECT _version, _field_versions FROM ${collection} WHERE id = ?`,
|
|
4276
|
+
`SELECT _version, _field_versions FROM ${(0, import_core23.quoteIdent)(collection)} WHERE id = ?`,
|
|
4263
4277
|
[recordId]
|
|
4264
4278
|
);
|
|
4265
4279
|
const row = rows[0];
|
|
@@ -4351,7 +4365,7 @@ var Store = class {
|
|
|
4351
4365
|
async compact(strategy) {
|
|
4352
4366
|
this.ensureOpen();
|
|
4353
4367
|
if (strategy.mode === "never") {
|
|
4354
|
-
return compactOperationLog(this.adapter, this.schema, strategy, (0,
|
|
4368
|
+
return compactOperationLog(this.adapter, this.schema, strategy, (0, import_core23.createVersionVector)());
|
|
4355
4369
|
}
|
|
4356
4370
|
const serverVector = strategy.serverVector ?? await loadLastAckedServerVector(this.adapter);
|
|
4357
4371
|
return compactOperationLog(this.adapter, this.schema, strategy, serverVector);
|
|
@@ -4365,7 +4379,7 @@ var Store = class {
|
|
|
4365
4379
|
async getLatestLocalOperationForRecord(collection, recordId) {
|
|
4366
4380
|
this.ensureOpen();
|
|
4367
4381
|
const rows = await this.adapter.query(
|
|
4368
|
-
`SELECT * FROM _kora_ops_${collection} WHERE node_id = ? AND record_id = ? ORDER BY sequence_number DESC LIMIT 1`,
|
|
4382
|
+
`SELECT * FROM ${(0, import_core23.quoteIdent)(`_kora_ops_${collection}`)} WHERE node_id = ? AND record_id = ? ORDER BY sequence_number DESC LIMIT 1`,
|
|
4369
4383
|
[this.nodeId, recordId]
|
|
4370
4384
|
);
|
|
4371
4385
|
const row = rows[0];
|
|
@@ -4380,13 +4394,13 @@ var Store = class {
|
|
|
4380
4394
|
async getLatestOperationForRecord(collection, recordId) {
|
|
4381
4395
|
this.ensureOpen();
|
|
4382
4396
|
const rows = await this.adapter.query(
|
|
4383
|
-
`SELECT * FROM _kora_ops_${collection} WHERE record_id = ?`,
|
|
4397
|
+
`SELECT * FROM ${(0, import_core23.quoteIdent)(`_kora_ops_${collection}`)} WHERE record_id = ?`,
|
|
4384
4398
|
[recordId]
|
|
4385
4399
|
);
|
|
4386
4400
|
let latest = null;
|
|
4387
4401
|
for (const row of rows) {
|
|
4388
4402
|
const op = deserializeOperationWithCollection(row, collection);
|
|
4389
|
-
if (!latest ||
|
|
4403
|
+
if (!latest || import_core23.HybridLogicalClock.compare(op.timestamp, latest.timestamp) > 0) {
|
|
4390
4404
|
latest = op;
|
|
4391
4405
|
}
|
|
4392
4406
|
}
|
|
@@ -4529,7 +4543,7 @@ var Store = class {
|
|
|
4529
4543
|
for (let v = storedVersion + 1; v <= targetVersion; v++) {
|
|
4530
4544
|
const migration = migrations[v];
|
|
4531
4545
|
if (!migration) continue;
|
|
4532
|
-
const sqlStatements = (0,
|
|
4546
|
+
const sqlStatements = (0, import_core23.migrationStepsToSQL)(migration.steps);
|
|
4533
4547
|
for (const sql of sqlStatements) {
|
|
4534
4548
|
try {
|
|
4535
4549
|
await this.adapter.execute(sql);
|
|
@@ -4567,14 +4581,14 @@ var Store = class {
|
|
|
4567
4581
|
*/
|
|
4568
4582
|
async runBackfill(collection, transform) {
|
|
4569
4583
|
const rows = await this.adapter.query(
|
|
4570
|
-
`SELECT * FROM ${collection} WHERE _deleted = 0`
|
|
4584
|
+
`SELECT * FROM ${(0, import_core23.quoteIdent)(collection)} WHERE _deleted = 0`
|
|
4571
4585
|
);
|
|
4572
4586
|
await this.adapter.transaction(async (tx) => {
|
|
4573
4587
|
for (const row of rows) {
|
|
4574
4588
|
const updates = transform(row);
|
|
4575
4589
|
const fields = Object.keys(updates);
|
|
4576
4590
|
if (fields.length === 0) continue;
|
|
4577
|
-
const setClauses = fields.map((f) => `${f} = ?`).join(", ");
|
|
4591
|
+
const setClauses = fields.map((f) => `${(0, import_core23.quoteIdent)(f)} = ?`).join(", ");
|
|
4578
4592
|
const values = fields.map((f) => {
|
|
4579
4593
|
const val = updates[f];
|
|
4580
4594
|
if (typeof val === "boolean") return val ? 1 : 0;
|
|
@@ -4584,7 +4598,7 @@ var Store = class {
|
|
|
4584
4598
|
return val;
|
|
4585
4599
|
});
|
|
4586
4600
|
values.push(row.id);
|
|
4587
|
-
await tx.execute(`UPDATE ${collection} SET ${setClauses} WHERE id = ?`, values);
|
|
4601
|
+
await tx.execute(`UPDATE ${(0, import_core23.quoteIdent)(collection)} SET ${setClauses} WHERE id = ?`, values);
|
|
4588
4602
|
}
|
|
4589
4603
|
});
|
|
4590
4604
|
}
|
|
@@ -4607,7 +4621,7 @@ var Store = class {
|
|
|
4607
4621
|
if (rows[0]) {
|
|
4608
4622
|
return rows[0].value;
|
|
4609
4623
|
}
|
|
4610
|
-
const newNodeId = (0,
|
|
4624
|
+
const newNodeId = (0, import_core23.generateUUIDv7)();
|
|
4611
4625
|
await this.adapter.execute("INSERT INTO _kora_meta (key, value) VALUES ('node_id', ?)", [
|
|
4612
4626
|
newNodeId
|
|
4613
4627
|
]);
|
|
@@ -4624,7 +4638,7 @@ var Store = class {
|
|
|
4624
4638
|
const rows = await this.adapter.query(
|
|
4625
4639
|
"SELECT node_id, sequence_number FROM _kora_version_vector"
|
|
4626
4640
|
);
|
|
4627
|
-
const vector = (0,
|
|
4641
|
+
const vector = (0, import_core23.createVersionVector)();
|
|
4628
4642
|
for (const row of rows) {
|
|
4629
4643
|
vector.set(row.node_id, row.sequence_number);
|
|
4630
4644
|
}
|
|
@@ -4698,12 +4712,12 @@ var QueryStore = class {
|
|
|
4698
4712
|
};
|
|
4699
4713
|
|
|
4700
4714
|
// src/reactivity/assert-query-ready.ts
|
|
4701
|
-
var
|
|
4715
|
+
var import_core24 = require("@korajs/core");
|
|
4702
4716
|
var LEGACY_PENDING_COLLECTION = "__pending__";
|
|
4703
4717
|
function assertQueryReady(query) {
|
|
4704
4718
|
const descriptor = query.getDescriptor();
|
|
4705
4719
|
if (descriptor.collection === LEGACY_PENDING_COLLECTION) {
|
|
4706
|
-
throw new
|
|
4720
|
+
throw new import_core24.AppNotReadyError(
|
|
4707
4721
|
"Cannot use useQuery() before app.ready. Await app.ready or wrap your UI in <KoraProvider app={app}>."
|
|
4708
4722
|
);
|
|
4709
4723
|
}
|
|
@@ -5126,7 +5140,7 @@ init_audit_json();
|
|
|
5126
5140
|
init_export_audit();
|
|
5127
5141
|
|
|
5128
5142
|
// src/blob/content-addressed-blob-store.ts
|
|
5129
|
-
var
|
|
5143
|
+
var import_core25 = require("@korajs/core");
|
|
5130
5144
|
var BlobIntegrityError = class extends Error {
|
|
5131
5145
|
constructor(expectedHash, actualHash) {
|
|
5132
5146
|
super(`Blob integrity check failed: content under hash ${expectedHash} hashes to ${actualHash}`);
|
|
@@ -5140,7 +5154,7 @@ var BlobIntegrityError = class extends Error {
|
|
|
5140
5154
|
var MemoryBlobStore = class {
|
|
5141
5155
|
blobs = /* @__PURE__ */ new Map();
|
|
5142
5156
|
async put(bytes, metadata = {}) {
|
|
5143
|
-
const ref = await (0,
|
|
5157
|
+
const ref = await (0, import_core25.createBlobRef)(bytes, metadata);
|
|
5144
5158
|
if (!this.blobs.has(ref.hash)) {
|
|
5145
5159
|
const stored = new Uint8Array(bytes.byteLength);
|
|
5146
5160
|
stored.set(bytes);
|
|
@@ -5153,7 +5167,7 @@ var MemoryBlobStore = class {
|
|
|
5153
5167
|
if (stored === void 0) {
|
|
5154
5168
|
return null;
|
|
5155
5169
|
}
|
|
5156
|
-
const actualHash = await (0,
|
|
5170
|
+
const actualHash = await (0, import_core25.hashBlob)(stored);
|
|
5157
5171
|
if (actualHash !== hash) {
|
|
5158
5172
|
throw new BlobIntegrityError(hash, actualHash);
|
|
5159
5173
|
}
|
|
@@ -5176,7 +5190,7 @@ var MemoryBlobStore = class {
|
|
|
5176
5190
|
};
|
|
5177
5191
|
|
|
5178
5192
|
// src/blob/opfs-blob-store.ts
|
|
5179
|
-
var
|
|
5193
|
+
var import_core26 = require("@korajs/core");
|
|
5180
5194
|
var OpfsBlobStore = class {
|
|
5181
5195
|
constructor(dir) {
|
|
5182
5196
|
this.dir = dir;
|
|
@@ -5186,7 +5200,7 @@ var OpfsBlobStore = class {
|
|
|
5186
5200
|
return hash.slice(0, 2);
|
|
5187
5201
|
}
|
|
5188
5202
|
async put(bytes, metadata = {}) {
|
|
5189
|
-
const ref = await (0,
|
|
5203
|
+
const ref = await (0, import_core26.createBlobRef)(bytes, metadata);
|
|
5190
5204
|
const shard = this.shardFor(ref.hash);
|
|
5191
5205
|
if (await this.dir.has(shard, ref.hash)) {
|
|
5192
5206
|
return ref;
|
|
@@ -5201,7 +5215,7 @@ var OpfsBlobStore = class {
|
|
|
5201
5215
|
if (bytes === null) {
|
|
5202
5216
|
return null;
|
|
5203
5217
|
}
|
|
5204
|
-
const actual = await (0,
|
|
5218
|
+
const actual = await (0, import_core26.hashBlob)(bytes);
|
|
5205
5219
|
if (actual !== hash) {
|
|
5206
5220
|
throw new BlobIntegrityError(hash, actual);
|
|
5207
5221
|
}
|
|
@@ -5347,7 +5361,7 @@ async function createOpfsBlobStore(rootDirName = "kora-blobs") {
|
|
|
5347
5361
|
}
|
|
5348
5362
|
|
|
5349
5363
|
// src/blob/blob-chunking.ts
|
|
5350
|
-
var
|
|
5364
|
+
var import_core27 = require("@korajs/core");
|
|
5351
5365
|
var DEFAULT_CHUNK_SIZE = 256 * 1024;
|
|
5352
5366
|
async function chunkBlob(bytes, chunkSize = DEFAULT_CHUNK_SIZE, metadata = {}) {
|
|
5353
5367
|
if (chunkSize <= 0) {
|
|
@@ -5359,13 +5373,13 @@ async function chunkBlob(bytes, chunkSize = DEFAULT_CHUNK_SIZE, metadata = {}) {
|
|
|
5359
5373
|
const end = Math.min(offset + chunkSize, bytes.byteLength);
|
|
5360
5374
|
const chunk = new Uint8Array(end - offset);
|
|
5361
5375
|
chunk.set(bytes.subarray(offset, end));
|
|
5362
|
-
const hash = await (0,
|
|
5376
|
+
const hash = await (0, import_core27.hashBlob)(chunk);
|
|
5363
5377
|
chunkHashes.push(hash);
|
|
5364
5378
|
if (!chunks.has(hash)) {
|
|
5365
5379
|
chunks.set(hash, chunk);
|
|
5366
5380
|
}
|
|
5367
5381
|
}
|
|
5368
|
-
const blobHash = await (0,
|
|
5382
|
+
const blobHash = await (0, import_core27.hashBlob)(bytes);
|
|
5369
5383
|
const manifest = {
|
|
5370
5384
|
blobHash,
|
|
5371
5385
|
size: bytes.byteLength,
|
|
@@ -5397,7 +5411,7 @@ async function reassembleBlob(manifest, chunkStore) {
|
|
|
5397
5411
|
out.set(part, offset);
|
|
5398
5412
|
offset += part.byteLength;
|
|
5399
5413
|
}
|
|
5400
|
-
const actual = await (0,
|
|
5414
|
+
const actual = await (0, import_core27.hashBlob)(out);
|
|
5401
5415
|
if (actual !== manifest.blobHash) {
|
|
5402
5416
|
throw new BlobIntegrityError(manifest.blobHash, actual);
|
|
5403
5417
|
}
|
|
@@ -5405,7 +5419,7 @@ async function reassembleBlob(manifest, chunkStore) {
|
|
|
5405
5419
|
}
|
|
5406
5420
|
|
|
5407
5421
|
// src/blob/blob-transfer.ts
|
|
5408
|
-
var
|
|
5422
|
+
var import_core28 = require("@korajs/core");
|
|
5409
5423
|
async function receiveBlob(manifest, provider, stores) {
|
|
5410
5424
|
let chunksFetched = 0;
|
|
5411
5425
|
let chunksSkipped = 0;
|
|
@@ -5423,7 +5437,7 @@ async function receiveBlob(manifest, provider, stores) {
|
|
|
5423
5437
|
if (bytes === null) {
|
|
5424
5438
|
throw new Error(`Blob transfer failed: provider could not supply chunk ${hash}`);
|
|
5425
5439
|
}
|
|
5426
|
-
const actual = await (0,
|
|
5440
|
+
const actual = await (0, import_core28.hashBlob)(bytes);
|
|
5427
5441
|
if (actual !== hash) {
|
|
5428
5442
|
throw new BlobIntegrityError(hash, actual);
|
|
5429
5443
|
}
|
|
@@ -5452,7 +5466,7 @@ async function prepareBlobForSend(bytes, chunkStore, options = {}) {
|
|
|
5452
5466
|
}
|
|
5453
5467
|
|
|
5454
5468
|
// src/blob/blob-manifest-transfer.ts
|
|
5455
|
-
var
|
|
5469
|
+
var import_core29 = require("@korajs/core");
|
|
5456
5470
|
function serializeBlobManifest(manifest) {
|
|
5457
5471
|
const canonical = {
|
|
5458
5472
|
blobHash: manifest.blobHash,
|
|
@@ -5517,7 +5531,7 @@ async function fetchBlobManifest(provider, manifestHash) {
|
|
|
5517
5531
|
if (bytes === null) {
|
|
5518
5532
|
throw new Error(`Blob manifest ${manifestHash} could not be fetched from the provider`);
|
|
5519
5533
|
}
|
|
5520
|
-
const actual = await (0,
|
|
5534
|
+
const actual = await (0, import_core29.hashBlob)(bytes);
|
|
5521
5535
|
if (actual !== manifestHash) {
|
|
5522
5536
|
throw new BlobIntegrityError(manifestHash, actual);
|
|
5523
5537
|
}
|
|
@@ -5533,12 +5547,12 @@ async function resolveBlobManifest(provider, ref) {
|
|
|
5533
5547
|
}
|
|
5534
5548
|
|
|
5535
5549
|
// src/blob/server-blob-callbacks.ts
|
|
5536
|
-
var
|
|
5550
|
+
var import_core30 = require("@korajs/core");
|
|
5537
5551
|
function toServerBlobCallbacks(store) {
|
|
5538
5552
|
return {
|
|
5539
5553
|
resolveBlobChunk: (hash) => store.get(hash),
|
|
5540
5554
|
async persistBlobChunk(hash, bytes) {
|
|
5541
|
-
const actual = await (0,
|
|
5555
|
+
const actual = await (0, import_core30.hashBlob)(bytes);
|
|
5542
5556
|
if (actual !== hash) {
|
|
5543
5557
|
return;
|
|
5544
5558
|
}
|
|
@@ -5552,11 +5566,11 @@ function createMemoryServerBlobStore() {
|
|
|
5552
5566
|
}
|
|
5553
5567
|
|
|
5554
5568
|
// src/blob/blob-gc.ts
|
|
5555
|
-
var
|
|
5569
|
+
var import_core31 = require("@korajs/core");
|
|
5556
5570
|
function extractBlobRefs(record) {
|
|
5557
5571
|
const refs = [];
|
|
5558
5572
|
for (const value of Object.values(record)) {
|
|
5559
|
-
if ((0,
|
|
5573
|
+
if ((0, import_core31.isBlobRef)(value)) {
|
|
5560
5574
|
refs.push(value);
|
|
5561
5575
|
}
|
|
5562
5576
|
}
|
|
@@ -5601,7 +5615,7 @@ async function collectBlobGarbage(store, liveRefs, options = {}) {
|
|
|
5601
5615
|
}
|
|
5602
5616
|
|
|
5603
5617
|
// src/blob/blob-chunk-transport.ts
|
|
5604
|
-
var
|
|
5618
|
+
var import_core32 = require("@korajs/core");
|
|
5605
5619
|
function createRemoteChunkProvider(port, options = {}) {
|
|
5606
5620
|
const timeoutMs = options.timeoutMs ?? 3e4;
|
|
5607
5621
|
const pending = /* @__PURE__ */ new Map();
|
|
@@ -5620,7 +5634,7 @@ function createRemoteChunkProvider(port, options = {}) {
|
|
|
5620
5634
|
return {
|
|
5621
5635
|
pendingCount: () => pending.size,
|
|
5622
5636
|
getChunk(hash) {
|
|
5623
|
-
const requestId = (0,
|
|
5637
|
+
const requestId = (0, import_core32.generateUUIDv7)();
|
|
5624
5638
|
return new Promise((resolve, reject) => {
|
|
5625
5639
|
const timer = setTimeout(() => {
|
|
5626
5640
|
pending.delete(requestId);
|