@tensorix/metahub 0.4.1 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/cli.js +6151 -15068
  2. package/dist/cli.js.map +26 -77
  3. package/dist/core/audit.d.ts +97 -0
  4. package/dist/core/audit.d.ts.map +1 -0
  5. package/dist/core/crdt.d.ts +13 -1
  6. package/dist/core/crdt.d.ts.map +1 -1
  7. package/dist/core/databases.d.ts.map +1 -1
  8. package/dist/core/documents.d.ts +6 -0
  9. package/dist/core/documents.d.ts.map +1 -1
  10. package/dist/core/grants-core.d.ts.map +1 -1
  11. package/dist/core/history.d.ts +31 -0
  12. package/dist/core/history.d.ts.map +1 -1
  13. package/dist/core/indexing.d.ts +1 -1
  14. package/dist/core/integrity.d.ts +1 -1
  15. package/dist/core/integrity.d.ts.map +1 -1
  16. package/dist/core/properties.d.ts +1 -1
  17. package/dist/core/properties.d.ts.map +1 -1
  18. package/dist/core/records.d.ts +5 -0
  19. package/dist/core/records.d.ts.map +1 -1
  20. package/dist/core/relation-cells.d.ts +23 -0
  21. package/dist/core/relation-cells.d.ts.map +1 -0
  22. package/dist/core/resolve.d.ts +4 -0
  23. package/dist/core/resolve.d.ts.map +1 -1
  24. package/dist/core/sync/files.d.ts.map +1 -1
  25. package/dist/core/sync/server.d.ts.map +1 -1
  26. package/dist/core/sync/share-serve.d.ts.map +1 -1
  27. package/dist/db-worker.js +96 -98
  28. package/dist/edge-worker.js +135 -87
  29. package/dist/index.js +11712 -20459
  30. package/dist/index.js.map +18 -71
  31. package/dist/metahub-sdk.js +7 -7
  32. package/dist/mh-runtime.js +1 -1
  33. package/dist/sw.js +7 -7
  34. package/dist/webui/server/assets.d.ts +3 -1
  35. package/dist/webui/server/assets.d.ts.map +1 -1
  36. package/dist/webui/server/changes-route.d.ts +7 -0
  37. package/dist/webui/server/changes-route.d.ts.map +1 -0
  38. package/dist/webui/server/routes.d.ts.map +1 -1
  39. package/dist/webui-fmt-clang.js +1 -1
  40. package/dist/webui-fmt-gofmt.js +1 -1
  41. package/dist/webui-fmt-lua.js +2 -2
  42. package/dist/webui-fmt-ruff.js +2 -2
  43. package/dist/webui-fmt-sh.js +8 -8
  44. package/dist/webui-fmt-taplo.js +2 -2
  45. package/dist/webui-fmt.js +346 -346
  46. package/dist/webui.js +182 -178
  47. package/package.json +1 -1
@@ -279,9 +279,9 @@ function lcs(a, b) {
279
279
  const m = a.length;
280
280
  const n = b.length;
281
281
  const dp = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0));
282
- for (let i2 = m - 1;i2 >= 0; i2--)
283
- for (let j2 = n - 1;j2 >= 0; j2--)
284
- dp[i2][j2] = a[i2] === b[j2] ? dp[i2 + 1][j2 + 1] + 1 : Math.max(dp[i2 + 1][j2], dp[i2][j2 + 1]);
282
+ for (let i = m - 1;i >= 0; i--)
283
+ for (let j = n - 1;j >= 0; j--)
284
+ dp[i][j] = a[i] === b[j] ? dp[i + 1][j + 1] + 1 : Math.max(dp[i + 1][j], dp[i][j + 1]);
285
285
  const pairs = [];
286
286
  let i = 0;
287
287
  let j = 0;
@@ -327,6 +327,7 @@ function intentSubmissionExpired(submittedAt, now = Date.now()) {
327
327
  var CHANGE_COLS = ["hlc", "node_id", "dataset", "row_id", "col", "value", "txn"];
328
328
  var CHANGE_SELECT = CHANGE_COLS.join(", ");
329
329
  var currentTxn = null;
330
+ var currentActor = null;
330
331
  var currentNodeOverride = null;
331
332
  function withNodeId(node, fn) {
332
333
  const prev = currentNodeOverride;
@@ -340,7 +341,7 @@ function withNodeId(node, fn) {
340
341
  function withChangeGroup(label, fn) {
341
342
  if (currentTxn !== null)
342
343
  return fn();
343
- currentTxn = (label ? label + ":" : "") + randomSuffix(8);
344
+ currentTxn = (currentActor ? currentActor + "/" : "") + (label ? label + ":" : "") + randomSuffix(8);
344
345
  try {
345
346
  return fn();
346
347
  } finally {
@@ -462,8 +463,8 @@ function materialize(db, dataset, rowId, col, valueJson) {
462
463
  if (dataset === "records") {
463
464
  if (RECORD_META.has(col)) {
464
465
  ensureRow(db, "records", rowId);
465
- const v2 = decodeMaterializeValue("records", col, valueJson);
466
- db.query(`UPDATE records SET "${col}" = ? WHERE id = ?`).run(encodeScalar(v2), rowId);
466
+ const v = decodeMaterializeValue("records", col, valueJson);
467
+ db.query(`UPDATE records SET "${col}" = ? WHERE id = ?`).run(encodeScalar(v), rowId);
467
468
  } else {
468
469
  ensureRow(db, "records", rowId);
469
470
  if (valueJson === null) {
@@ -565,7 +566,7 @@ function ensurePropIndex(db, databaseId, propId) {
565
566
  function maybeAutoIndex(db, databaseId, prop) {
566
567
  if (hasIndex(db, databaseId, prop.id))
567
568
  return;
568
- if (prop.type !== "relation") {
569
+ if (prop.type !== "relation" && prop.type !== "doc") {
569
570
  const row = db.query("SELECT COUNT(*) AS c FROM records WHERE database_id = ? AND __deleted = 0").get(databaseId);
570
571
  if (row.c < AUTO_INDEX_ROW_THRESHOLD)
571
572
  return;
@@ -582,6 +583,7 @@ var PROP_TYPES = new Set([
582
583
  "multi_select",
583
584
  "date",
584
585
  "relation",
586
+ "doc",
585
587
  "url"
586
588
  ]);
587
589
  var PROPERTY_COLS = ["id", "database_id", "name", "type", "config", "position"];
@@ -601,7 +603,7 @@ function nextPosition(db, databaseId) {
601
603
  const row = db.query("SELECT MAX(position) AS m FROM properties WHERE database_id = ? AND __deleted = 0").get(databaseId);
602
604
  return (row.m ?? 0) + 1;
603
605
  }
604
- var addProperty = grouped(function addProperty2(db, databaseId, opts) {
606
+ var addProperty = grouped(function addProperty(db, databaseId, opts) {
605
607
  if (!getDatabase(db, databaseId))
606
608
  throw new MhError("not_found", `no such database: ${databaseId}`);
607
609
  if (!PROP_TYPES.has(opts.type))
@@ -614,7 +616,7 @@ var addProperty = grouped(function addProperty2(db, databaseId, opts) {
614
616
  emit(db, "properties", id, "type", opts.type);
615
617
  emit(db, "properties", id, "config", config);
616
618
  emit(db, "properties", id, "position", opts.position ?? nextPosition(db, databaseId));
617
- if (opts.type === "relation" || opts.indexed === true)
619
+ if (opts.type === "relation" || opts.type === "doc" || opts.indexed === true)
618
620
  ensurePropIndex(db, databaseId, id);
619
621
  return getProperty(db, id);
620
622
  });
@@ -631,7 +633,7 @@ function listProperties(db, databaseId) {
631
633
  config: r.config ? JSON.parse(r.config) : null
632
634
  }));
633
635
  }
634
- var updateProperty = grouped(function updateProperty2(db, id, fields) {
636
+ var updateProperty = grouped(function updateProperty(db, id, fields) {
635
637
  const cur = getProperty(db, id);
636
638
  if (!cur)
637
639
  throw new MhError("not_found", `no such property: ${id}`);
@@ -675,7 +677,7 @@ function getSelectProperty(db, id) {
675
677
  throw new MhError("invalid_input", `${prop.type} property has no options`);
676
678
  return { prop, options: prop.config?.options ?? [] };
677
679
  }
678
- var renameSelectOption = grouped(function renameSelectOption2(db, id, from, to) {
680
+ var renameSelectOption = grouped(function renameSelectOption(db, id, from, to) {
679
681
  const { prop, options } = getSelectProperty(db, id);
680
682
  to = to.trim();
681
683
  if (!to)
@@ -708,7 +710,7 @@ var renameSelectOption = grouped(function renameSelectOption2(db, id, from, to)
708
710
  }
709
711
  return { property: getProperty(db, id), renamed };
710
712
  });
711
- var removeSelectOption = grouped(function removeSelectOption2(db, id, name) {
713
+ var removeSelectOption = grouped(function removeSelectOption(db, id, name) {
712
714
  const { prop, options } = getSelectProperty(db, id);
713
715
  if (!options.includes(name))
714
716
  throw new MhError("not_found", `no such option: ${name}`);
@@ -736,7 +738,7 @@ var removeSelectOption = grouped(function removeSelectOption2(db, id, name) {
736
738
  }
737
739
  return { property: getProperty(db, id), cleared };
738
740
  });
739
- var removeProperty = grouped(function removeProperty2(db, id) {
741
+ var removeProperty = grouped(function removeProperty(db, id) {
740
742
  const prop = getProperty(db, id);
741
743
  if (!prop)
742
744
  return false;
@@ -886,6 +888,20 @@ function resolveRelation(db, prop, value) {
886
888
  }
887
889
  throw new MhError("ambiguous", `${prop.name}: ambiguous relation "${value}" (${cands.length} matches); use a full id`);
888
890
  }
891
+ function resolveDoc(db, prop, value) {
892
+ const cands = resolveCandidates(db, value, { kind: "doc" });
893
+ const exact = cands.find((c) => c.id === value);
894
+ if (exact)
895
+ return exact.id;
896
+ if (cands.length === 1)
897
+ return cands[0].id;
898
+ if (cands.length === 0) {
899
+ if (idKind(value) === "doc")
900
+ return value;
901
+ throw new MhError("not_found", `${prop.name}: no such document: ${value}`);
902
+ }
903
+ throw new MhError("ambiguous", `${prop.name}: ambiguous document "${value}" (${cands.length} matches); use a full id`);
904
+ }
889
905
  function coerce(db, prop, value) {
890
906
  switch (prop.type) {
891
907
  case "text":
@@ -934,6 +950,10 @@ function coerce(db, prop, value) {
934
950
  const arr = value === null ? [] : Array.isArray(value) ? value : [value];
935
951
  return arr.map((v) => resolveRelation(db, prop, String(v)));
936
952
  }
953
+ case "doc": {
954
+ const arr = value === null ? [] : Array.isArray(value) ? value : [value];
955
+ return arr.map((v) => resolveDoc(db, prop, String(v)));
956
+ }
937
957
  }
938
958
  }
939
959
  function propsByName(props) {
@@ -1021,7 +1041,7 @@ function rebalanceRecordOrderKeys(db, databaseId) {
1021
1041
  emit(db, "records", row.id, "order_key", keys[i]);
1022
1042
  });
1023
1043
  }
1024
- var backfillRecordOrderKeys = grouped(function backfillRecordOrderKeys2(db, databaseId) {
1044
+ var backfillRecordOrderKeys = grouped(function backfillRecordOrderKeys(db, databaseId) {
1025
1045
  const emitChange = canEmitOrderKeys(db);
1026
1046
  const dbRows = databaseId ? [{ database_id: databaseId }] : db.query(`SELECT DISTINCT database_id FROM records
1027
1047
  WHERE database_id IS NOT NULL AND __deleted = 0 AND order_key IS NULL`).all();
@@ -1036,7 +1056,7 @@ var backfillRecordOrderKeys = grouped(function backfillRecordOrderKeys2(db, data
1036
1056
  missing.forEach((row, i) => writeRecordOrderKey(db, row.id, keys[i], emitChange));
1037
1057
  }
1038
1058
  });
1039
- var createRecordPrepared = grouped(function createRecordPrepared2(db, database, cells) {
1059
+ var createRecordPrepared = grouped(function createRecordPrepared(db, database, cells) {
1040
1060
  const id = deriveTitle(cells, slugify(database.name, "rec"));
1041
1061
  const orderKey = keyBetween(lastRecordOrderKey(db, database.id), null);
1042
1062
  const first = emit(db, "records", id, "database_id", database.id);
@@ -1046,7 +1066,7 @@ var createRecordPrepared = grouped(function createRecordPrepared2(db, database,
1046
1066
  emit(db, "records", id, prop.id, value);
1047
1067
  return getRecord(db, id);
1048
1068
  });
1049
- var createRecord = grouped(function createRecord2(db, databaseId, data) {
1069
+ var createRecord = grouped(function createRecord(db, databaseId, data) {
1050
1070
  const database = getDatabase(db, databaseId);
1051
1071
  if (!database)
1052
1072
  throw new MhError("not_found", `no such database: ${databaseId}`);
@@ -1078,7 +1098,7 @@ function listRecords(db, databaseId, opts = {}) {
1078
1098
  key = key.slice(1);
1079
1099
  }
1080
1100
  if (key !== "created" && key !== "created_hlc") {
1081
- let p = props.find((p2) => p2.id === key);
1101
+ let p = props.find((p) => p.id === key);
1082
1102
  if (!p) {
1083
1103
  const matches = props.filter((q) => q.name.toLowerCase() === key.toLowerCase());
1084
1104
  if (matches.length > 1)
@@ -1116,7 +1136,7 @@ function listRecords(db, databaseId, opts = {}) {
1116
1136
  }
1117
1137
  return rows;
1118
1138
  }
1119
- var moveRecord = grouped(function moveRecord2(db, id, targetId, where) {
1139
+ var moveRecord = grouped(function moveRecord(db, id, targetId, where) {
1120
1140
  if (where !== "before" && where !== "after")
1121
1141
  throw new MhError("invalid_input", `unknown move position: ${where}`);
1122
1142
  const src = db.query("SELECT id, database_id FROM records WHERE id = ? AND __deleted = 0").get(id);
@@ -1146,21 +1166,26 @@ var moveRecord = grouped(function moveRecord2(db, id, targetId, where) {
1146
1166
  emit(db, "records", id, "order_key", keyBetween(left, right));
1147
1167
  return getRecord(db, id);
1148
1168
  });
1149
- var updateRecordPrepared = grouped(function updateRecordPrepared2(db, id, cells) {
1150
- const rec = db.query("SELECT id, database_id FROM records WHERE id = ? AND __deleted = 0").get(id);
1169
+ var updateRecordPrepared = grouped(function updateRecordPrepared(db, id, cells) {
1170
+ const rec = db.query("SELECT id, database_id, data FROM records WHERE id = ? AND __deleted = 0").get(id);
1151
1171
  if (!rec)
1152
1172
  throw new MhError("not_found", `no such record: ${id}`);
1153
- for (const { prop, value } of cells)
1154
- emit(db, "records", id, prop.id, value);
1173
+ const cur = JSON.parse(rec.data || "{}");
1174
+ for (const { prop, value } of cells) {
1175
+ const exists = Object.hasOwn(cur, prop.id);
1176
+ const same = value === undefined ? !exists : exists && JSON.stringify(value) === JSON.stringify(cur[prop.id]);
1177
+ if (!same)
1178
+ emit(db, "records", id, prop.id, value);
1179
+ }
1155
1180
  return getRecord(db, id);
1156
1181
  });
1157
- var updateRecord = grouped(function updateRecord2(db, id, data) {
1182
+ var updateRecord = grouped(function updateRecord(db, id, data) {
1158
1183
  const rec = db.query("SELECT id, database_id FROM records WHERE id = ? AND __deleted = 0").get(id);
1159
1184
  if (!rec)
1160
1185
  throw new MhError("not_found", `no such record: ${id}`);
1161
1186
  return updateRecordPrepared(db, id, prepareRecordCells(db, rec.database_id, data));
1162
1187
  });
1163
- var deleteRecord = grouped(function deleteRecord2(db, id) {
1188
+ var deleteRecord = grouped(function deleteRecord(db, id) {
1164
1189
  const rec = db.query("SELECT id FROM records WHERE id = ? AND __deleted = 0").get(id);
1165
1190
  if (!rec)
1166
1191
  return false;
@@ -1176,7 +1201,7 @@ function rowOut(r) {
1176
1201
  return null;
1177
1202
  return { ...r, meta: r.meta === null ? null : JSON.parse(r.meta) };
1178
1203
  }
1179
- var createDatabase = grouped(function createDatabase2(db, opts) {
1204
+ var createDatabase = grouped(function createDatabase(db, opts) {
1180
1205
  const id = newId("db", opts.name);
1181
1206
  const first = emit(db, "databases", id, "name", opts.name);
1182
1207
  emit(db, "databases", id, "created_hlc", first.hlc);
@@ -1184,7 +1209,7 @@ var createDatabase = grouped(function createDatabase2(db, opts) {
1184
1209
  emit(db, "databases", id, "icon", opts.icon);
1185
1210
  return getDatabase(db, id);
1186
1211
  });
1187
- var updateDatabase = grouped(function updateDatabase2(db, id, fields) {
1212
+ var updateDatabase = grouped(function updateDatabase(db, id, fields) {
1188
1213
  if (!getDatabase(db, id))
1189
1214
  throw new MhError("not_found", `no such database: ${id}`);
1190
1215
  if (fields.name !== undefined)
@@ -1198,7 +1223,7 @@ var updateDatabase = grouped(function updateDatabase2(db, id, fields) {
1198
1223
  }
1199
1224
  return getDatabase(db, id);
1200
1225
  });
1201
- var duplicateDatabase = grouped(function duplicateDatabase2(db, id, opts = {}) {
1226
+ var duplicateDatabase = grouped(function duplicateDatabase(db, id, opts = {}) {
1202
1227
  const src = getDatabase(db, id);
1203
1228
  if (!src)
1204
1229
  throw new MhError("not_found", `no such database: ${id}`);
@@ -1212,26 +1237,45 @@ var duplicateDatabase = grouped(function duplicateDatabase2(db, id, opts = {}) {
1212
1237
  emit(db, "databases", dup.id, "meta", meta);
1213
1238
  }
1214
1239
  const propIdMap = new Map;
1240
+ const selfRelNew = new Set;
1215
1241
  for (const p of listProperties(db, id)) {
1216
- const config = p.config?.database === id ? { ...p.config, database: dup.id } : p.config ?? undefined;
1242
+ const self = p.type === "relation" && p.config?.database === id;
1243
+ const config = self ? { ...p.config, database: dup.id } : p.config ?? undefined;
1217
1244
  const np = addProperty(db, dup.id, { name: p.name, type: p.type, config, position: p.position });
1218
1245
  propIdMap.set(p.id, np.id);
1246
+ if (self)
1247
+ selfRelNew.add(np.id);
1219
1248
  }
1220
- for (const r of listRecords(db, id)) {
1249
+ const srcRecords = listRecords(db, id);
1250
+ const recIdMap = new Map;
1251
+ for (const r of srcRecords) {
1221
1252
  const data = {};
1222
1253
  for (const [pid, v] of Object.entries(r.cells)) {
1223
1254
  const nid = propIdMap.get(pid);
1224
- if (nid)
1225
- data[nid] = v;
1255
+ if (!nid)
1256
+ continue;
1257
+ if (selfRelNew.has(nid) && Array.isArray(v) && v.length > 0)
1258
+ continue;
1259
+ data[nid] = v;
1260
+ }
1261
+ recIdMap.set(r.id, createRecord(db, dup.id, data).id);
1262
+ }
1263
+ for (const r of srcRecords) {
1264
+ const patch = {};
1265
+ for (const [pid, v] of Object.entries(r.cells)) {
1266
+ const nid = propIdMap.get(pid);
1267
+ if (nid && selfRelNew.has(nid) && Array.isArray(v) && v.length > 0)
1268
+ patch[nid] = v.map((x) => recIdMap.get(String(x)) ?? x);
1226
1269
  }
1227
- createRecord(db, dup.id, data);
1270
+ if (Object.keys(patch).length)
1271
+ updateRecord(db, recIdMap.get(r.id), patch);
1228
1272
  }
1229
1273
  return getDatabase(db, dup.id);
1230
1274
  });
1231
1275
  function getDatabase(db, id) {
1232
1276
  return rowOut(db.query(`SELECT ${DATABASE_SELECT} FROM databases WHERE id = ? AND __deleted = 0`).get(id));
1233
1277
  }
1234
- var deleteDatabase = grouped(function deleteDatabase2(db, id) {
1278
+ var deleteDatabase = grouped(function deleteDatabase(db, id) {
1235
1279
  if (!getDatabase(db, id))
1236
1280
  return false;
1237
1281
  emit(db, "databases", id, "__deleted", 1);
@@ -1363,29 +1407,33 @@ function liveRowCount(db, databaseId) {
1363
1407
  }
1364
1408
  function assertRelationAllowed(set, principalKind, prop) {
1365
1409
  if (principalKind === "public")
1366
- throw new MhError("invalid_input", `${prop.name}: relation properties are not writable anonymously`);
1410
+ throw new MhError("invalid_input", `${prop.name}: ${prop.type} properties are not writable anonymously`);
1411
+ if (prop.type === "doc")
1412
+ throw new MhError("invalid_input", `${prop.name}: doc properties are not writable via shares (grants cannot scope documents)`);
1367
1413
  const target = prop.config?.database;
1368
1414
  if (!target || !grantFor(set, target))
1369
1415
  throw new MhError("invalid_input", `${prop.name}: relation target database is not in this share's grants`);
1370
1416
  }
1417
+ function isLiveRefValue(prop, value) {
1418
+ return (prop.type === "relation" || prop.type === "doc") && value != null && !(Array.isArray(value) && value.length === 0);
1419
+ }
1371
1420
  function assertGuestPayload(db, set, principal, database, values, opts = {}) {
1372
1421
  const limits = opts.limits ?? GUEST_LIMITS;
1373
1422
  const entries = Object.entries(values);
1374
1423
  if (entries.length > limits.maxCells)
1375
1424
  throw new MhError("invalid_input", `too many cells (max ${limits.maxCells})`);
1376
1425
  const props = listProperties(db, database.id);
1377
- const resolved = resolveData(props, values).map(({ prop, value }) => ({
1378
- prop,
1379
- value: coerce(db, prop, value)
1380
- }));
1426
+ const resolved = resolveData(props, values).map(({ prop, value }) => {
1427
+ if (isLiveRefValue(prop, value))
1428
+ assertRelationAllowed(set, principal.kind, prop);
1429
+ return { prop, value: coerce(db, prop, value) };
1430
+ });
1381
1431
  let total = 0;
1382
1432
  for (const { prop, value } of resolved) {
1383
1433
  const size = utf8Len(JSON.stringify(value ?? null));
1384
1434
  if (size > limits.maxValueBytes)
1385
1435
  throw new MhError("invalid_input", `${prop.name}: value too large (max ${limits.maxValueBytes} bytes)`);
1386
1436
  total += size;
1387
- if (prop.type === "relation" && value != null && !(Array.isArray(value) && value.length === 0))
1388
- assertRelationAllowed(set, principal.kind, prop);
1389
1437
  }
1390
1438
  if (total > limits.maxBodyBytes)
1391
1439
  throw new MhError("invalid_input", `payload too large (max ${limits.maxBodyBytes} bytes)`);
@@ -1551,14 +1599,14 @@ function prepareIntent(db, policy, principal, intent, clock) {
1551
1599
  if (intent.action === "createRecord") {
1552
1600
  if (!intent.table || typeof intent.table !== "string")
1553
1601
  throw new MhError("invalid_input", "createRecord intent needs a table");
1554
- const database2 = authorizeDbRef(db, policy.grants, intent.table, "create");
1555
- const cells2 = assertGuestPayload(db, policy.grants, principal, database2, intent.payload, { limits: policy.limits });
1602
+ const database = authorizeDbRef(db, policy.grants, intent.table, "create");
1603
+ const cells = assertGuestPayload(db, policy.grants, principal, database, intent.payload, { limits: policy.limits });
1556
1604
  return {
1557
1605
  action: intent.action,
1558
- database: database2,
1559
- cells: cells2,
1606
+ database,
1607
+ cells,
1560
1608
  targetLive: true,
1561
- fingerprint: fingerprintIntent(intent.action, database2.id, clock === "submitted" ? intent.recordId ?? null : null, cells2)
1609
+ fingerprint: fingerprintIntent(intent.action, database.id, clock === "submitted" ? intent.recordId ?? null : null, cells)
1562
1610
  };
1563
1611
  }
1564
1612
  if (intent.action !== "updateRecord")
@@ -1704,10 +1752,10 @@ function isRecordRow(value) {
1704
1752
  return typeof row.id === "string" && typeof row.database_id === "string" && !!row.values && typeof row.values === "object" && !Array.isArray(row.values) && !!row.cells && typeof row.cells === "object" && !Array.isArray(row.cells);
1705
1753
  }
1706
1754
  function clampMillis(submittedAt, now) {
1707
- const safeNow2 = Math.max(0, Math.trunc(Number.isFinite(now) ? now : Date.now()));
1708
- const ceil = safeNow2 + HLC_SKEW_MS;
1755
+ const safeNow = Math.max(0, Math.trunc(Number.isFinite(now) ? now : Date.now()));
1756
+ const ceil = safeNow + HLC_SKEW_MS;
1709
1757
  if (!Number.isFinite(submittedAt))
1710
- return safeNow2;
1758
+ return safeNow;
1711
1759
  return Math.max(0, Math.min(Math.trunc(submittedAt), ceil));
1712
1760
  }
1713
1761
  function seedCounter(db, node, millis) {
@@ -1747,12 +1795,12 @@ function stableStringify(value) {
1747
1795
 
1748
1796
  // src/core/sync/anti-abuse.ts
1749
1797
  function timingSafeEq(a, b) {
1750
- const ab2 = new TextEncoder().encode(a);
1798
+ const ab = new TextEncoder().encode(a);
1751
1799
  const bb = new TextEncoder().encode(b);
1752
- let diff = ab2.length ^ bb.length;
1753
- const n = Math.max(ab2.length, bb.length);
1800
+ let diff = ab.length ^ bb.length;
1801
+ const n = Math.max(ab.length, bb.length);
1754
1802
  for (let i = 0;i < n; i++)
1755
- diff |= (ab2[i] ?? 0) ^ (bb[i] ?? 0);
1803
+ diff |= (ab[i] ?? 0) ^ (bb[i] ?? 0);
1756
1804
  return diff === 0;
1757
1805
  }
1758
1806
  var siteverify = async (secret, token, ip) => {
@@ -2033,7 +2081,7 @@ function assertVisibility(v) {
2033
2081
  if (v !== "public" && v !== "private")
2034
2082
  throw new MhError("invalid_input", `visibility must be "public" or "private", got ${JSON.stringify(v)}`);
2035
2083
  }
2036
- var createSite = grouped(function createSite2(db, opts) {
2084
+ var createSite = grouped(function createSite(db, opts) {
2037
2085
  const name = normalizeSiteName(opts.name);
2038
2086
  if (getSiteByName(db, name))
2039
2087
  throw new MhError("conflict", `site name already exists: ${name}`);
@@ -2048,7 +2096,7 @@ var createSite = grouped(function createSite2(db, opts) {
2048
2096
  emit(db, "sites", id, "visibility", opts.visibility);
2049
2097
  return getSite(db, id);
2050
2098
  });
2051
- var updateSite = grouped(function updateSite2(db, id, opts) {
2099
+ var updateSite = grouped(function updateSite(db, id, opts) {
2052
2100
  if (!getSite(db, id))
2053
2101
  throw new MhError("not_found", `no such site: ${id}`);
2054
2102
  if (opts.visibility !== undefined)
@@ -2068,14 +2116,14 @@ var updateSite = grouped(function updateSite2(db, id, opts) {
2068
2116
  emit(db, "sites", id, "spa", opts.spa ? 1 : 0);
2069
2117
  return getSite(db, id);
2070
2118
  });
2071
- var setSitePublicGrants = grouped(function setSitePublicGrants2(db, siteId, grants) {
2119
+ var setSitePublicGrants = grouped(function setSitePublicGrants(db, siteId, grants) {
2072
2120
  if (!getSite(db, siteId))
2073
2121
  throw new MhError("not_found", `no such site: ${siteId}`);
2074
2122
  const value = grants == null ? null : serializeGrantSet(validateGrantSetInput(grants));
2075
2123
  emit(db, "sites", siteId, "public_grants", value);
2076
2124
  return getSite(db, siteId);
2077
2125
  });
2078
- var deleteSite = grouped(function deleteSite2(db, id) {
2126
+ var deleteSite = grouped(function deleteSite(db, id) {
2079
2127
  if (!getSite(db, id))
2080
2128
  return false;
2081
2129
  const files = db.query("SELECT id FROM site_files WHERE site_id = ? AND __deleted = 0").all(id);
@@ -2088,7 +2136,7 @@ function fileIdFor(db, siteId, path) {
2088
2136
  const row = db.query("SELECT id FROM site_files WHERE site_id = ? AND path = ? ORDER BY created_hlc LIMIT 1").get(siteId, path);
2089
2137
  return row?.id ?? null;
2090
2138
  }
2091
- var deleteFile = grouped(function deleteFile2(db, siteId, path) {
2139
+ var deleteFile = grouped(function deleteFile(db, siteId, path) {
2092
2140
  const id = fileIdFor(db, siteId, normalizeSitePath(path));
2093
2141
  if (!id)
2094
2142
  return false;
@@ -2552,7 +2600,7 @@ function documentVersion(db, id) {
2552
2600
  OR (dataset = 'doc_blocks' AND row_id IN (SELECT id FROM doc_blocks WHERE doc_id = ?))`).get(id, id);
2553
2601
  return row.h ?? "";
2554
2602
  }
2555
- var createDocument = grouped(function createDocument2(db, opts) {
2603
+ var createDocument = grouped(function createDocument(db, opts) {
2556
2604
  const id = newId("doc", opts.title);
2557
2605
  const first = emit(db, "documents", id, "title", opts.title);
2558
2606
  emit(db, "documents", id, "created_hlc", first.hlc);
@@ -2616,7 +2664,7 @@ function backfillSiblings(db, parentId) {
2616
2664
  db.query("UPDATE documents SET order_key = ? WHERE id = ?").run(keys[i], row.id);
2617
2665
  });
2618
2666
  }
2619
- var backfillDocumentOrderKeys = grouped(function backfillDocumentOrderKeys2(db) {
2667
+ var backfillDocumentOrderKeys = grouped(function backfillDocumentOrderKeys(db) {
2620
2668
  const parents = db.query("SELECT DISTINCT parent_id FROM documents WHERE __deleted = 0 AND order_key IS NULL").all();
2621
2669
  for (const p of parents)
2622
2670
  backfillSiblings(db, p.parent_id);
@@ -2652,7 +2700,7 @@ function placeInSiblings(db, id, parentId, anchor) {
2652
2700
  }
2653
2701
  emit(db, "documents", id, "order_key", key);
2654
2702
  }
2655
- var moveDocument = grouped(function moveDocument2(db, id, targetId, where) {
2703
+ var moveDocument = grouped(function moveDocument(db, id, targetId, where) {
2656
2704
  const src = getDocument(db, id);
2657
2705
  if (!src)
2658
2706
  throw new MhError("not_found", `no such document: ${id}`);
@@ -2667,7 +2715,7 @@ var moveDocument = grouped(function moveDocument2(db, id, targetId, where) {
2667
2715
  placeInSiblings(db, id, target.parent_id, { targetId, where });
2668
2716
  return getDocument(db, id);
2669
2717
  });
2670
- var duplicateDocument = grouped(function duplicateDocument2(db, id, opts = {}) {
2718
+ var duplicateDocument = grouped(function duplicateDocument(db, id, opts = {}) {
2671
2719
  const src = getDocument(db, id);
2672
2720
  if (!src)
2673
2721
  throw new MhError("not_found", `no such document: ${id}`);
@@ -2685,7 +2733,7 @@ var duplicateDocument = grouped(function duplicateDocument2(db, id, opts = {}) {
2685
2733
  moveDocument(db, dup.id, src.id, "after");
2686
2734
  return getDocument(db, dup.id);
2687
2735
  });
2688
- var updateDocument = grouped(function updateDocument2(db, id, fields, opts = {}) {
2736
+ var updateDocument = grouped(function updateDocument(db, id, fields, opts = {}) {
2689
2737
  const doc = getDocument(db, id);
2690
2738
  if (!doc)
2691
2739
  throw new MhError("not_found", `no such document: ${id}`);
@@ -2706,7 +2754,7 @@ var updateDocument = grouped(function updateDocument2(db, id, fields, opts = {})
2706
2754
  }
2707
2755
  return getDocument(db, id);
2708
2756
  });
2709
- var editDocument = grouped(function editDocument2(db, id, opts) {
2757
+ var editDocument = grouped(function editDocument(db, id, opts) {
2710
2758
  if (!getDocument(db, id))
2711
2759
  throw new MhError("not_found", `no such document: ${id}`);
2712
2760
  if (opts.ifMatch !== undefined && documentVersion(db, id) !== opts.ifMatch)
@@ -2744,7 +2792,7 @@ var editDocument = grouped(function editDocument2(db, id, opts) {
2744
2792
  reconcileBody(db, id, newBody);
2745
2793
  return { id, changed: newBody !== body, replaced: opts.replaceAll ? count : 1, version: documentVersion(db, id) };
2746
2794
  });
2747
- var editDocumentBatch = grouped(function editDocumentBatch2(db, id, opts) {
2795
+ var editDocumentBatch = grouped(function editDocumentBatch(db, id, opts) {
2748
2796
  if (!getDocument(db, id))
2749
2797
  throw new MhError("not_found", `no such document: ${id}`);
2750
2798
  if (opts.edits.length === 0)
@@ -2771,7 +2819,7 @@ var editDocumentBatch = grouped(function editDocumentBatch2(db, id, opts) {
2771
2819
  reconcileBody(db, id, body);
2772
2820
  return { id, changed: body !== orig, replaced: total, version: documentVersion(db, id) };
2773
2821
  });
2774
- var appendDocument = grouped(function appendDocument2(db, id, body) {
2822
+ var appendDocument = grouped(function appendDocument(db, id, body) {
2775
2823
  if (!getDocument(db, id))
2776
2824
  throw new MhError("not_found", `no such document: ${id}`);
2777
2825
  ensureBlocks(db, id);
@@ -2783,7 +2831,7 @@ var appendDocument = grouped(function appendDocument2(db, id, body) {
2783
2831
  }
2784
2832
  return { id, changed: next.length > 0, replaced: next.length, version: documentVersion(db, id) };
2785
2833
  });
2786
- var prependDocument = grouped(function prependDocument2(db, id, body) {
2834
+ var prependDocument = grouped(function prependDocument(db, id, body) {
2787
2835
  if (!getDocument(db, id))
2788
2836
  throw new MhError("not_found", `no such document: ${id}`);
2789
2837
  ensureBlocks(db, id);
@@ -2795,7 +2843,7 @@ var prependDocument = grouped(function prependDocument2(db, id, body) {
2795
2843
  }
2796
2844
  return { id, changed: next.length > 0, replaced: next.length, version: documentVersion(db, id) };
2797
2845
  });
2798
- var deleteDocument = grouped(function deleteDocument2(db, id) {
2846
+ var deleteDocument = grouped(function deleteDocument(db, id) {
2799
2847
  if (!getDocument(db, id))
2800
2848
  return false;
2801
2849
  emit(db, "documents", id, "__deleted", 1);
@@ -3495,7 +3543,7 @@ function createRoomFetch(deps) {
3495
3543
  if (!body || typeof body.guestBase !== "string" || body.guestBase === "")
3496
3544
  return json({ error: "provision needs a guestBase", code: "invalid_input" }, 400);
3497
3545
  const str = (v) => typeof v === "string" && v !== "" ? v : null;
3498
- const cfg3 = initRoomDb(db, {
3546
+ const cfg = initRoomDb(db, {
3499
3547
  slug: typeof body.slug === "string" && body.slug !== "" ? body.slug : pathSlug,
3500
3548
  guestBase: body.guestBase,
3501
3549
  grants: str(body.grants) ?? "",
@@ -3503,11 +3551,11 @@ function createRoomFetch(deps) {
3503
3551
  pwSalt: str(body.pwSalt),
3504
3552
  expiresAt: typeof body.expiresAt === "number" ? body.expiresAt : null
3505
3553
  });
3506
- await deps.setAlarm?.(cfg3.expiresAt ?? null);
3507
- return json({ slug: cfg3.slug, room_node: cfg3.roomNode, provisioned: true });
3554
+ await deps.setAlarm?.(cfg.expiresAt ?? null);
3555
+ return json({ slug: cfg.slug, room_node: cfg.roomNode, provisioned: true });
3508
3556
  }
3509
- const cfg2 = tryConfig(db);
3510
- if (!cfg2)
3557
+ const cfg = tryConfig(db);
3558
+ if (!cfg)
3511
3559
  return json({ error: "room is not provisioned", code: "not_found" }, 404);
3512
3560
  if (sub === "owner/sync") {
3513
3561
  const body = await req.json().catch(() => null);
@@ -3515,7 +3563,7 @@ function createRoomFetch(deps) {
3515
3563
  return json({ error: "malformed sync request", code: "invalid_input" }, 400);
3516
3564
  await hlcHeadroom(db, deps);
3517
3565
  try {
3518
- const resp = handleOwnerSync(db, body, cfg2);
3566
+ const resp = handleOwnerSync(db, body, cfg);
3519
3567
  if (resp.share_state === "active" && body.changes.length > 0)
3520
3568
  deps.poke?.(maxSeq(db));
3521
3569
  return json(resp);
@@ -3614,10 +3662,10 @@ function serveRoomFile(db, cfg, path) {
3614
3662
  if (row.encoding === "utf8")
3615
3663
  return new Response(row.content ?? "", { status, headers });
3616
3664
  if (row.encoding === "base64") {
3617
- const bytes2 = base64ToBytes(row.content ?? "");
3618
- const body2 = new Uint8Array(bytes2.byteLength);
3619
- body2.set(bytes2);
3620
- return new Response(body2.buffer, { status, headers });
3665
+ const bytes = base64ToBytes(row.content ?? "");
3666
+ const body = new Uint8Array(bytes.byteLength);
3667
+ body.set(bytes);
3668
+ return new Response(body.buffer, { status, headers });
3621
3669
  }
3622
3670
  const bytes = row.content ? roomBlobBytes(db, row.content) : null;
3623
3671
  if (!bytes)
@@ -4018,21 +4066,21 @@ var edge_worker_default = {
4018
4066
  if (slug === null)
4019
4067
  return new Response("bad request", { status: 400 });
4020
4068
  const id = env.ROOM.idFromName(slug);
4021
- const res2 = await env.ROOM.get(id).fetch(req);
4022
- return cors ? corsResponse(res2) : res2;
4069
+ const res = await env.ROOM.get(id).fetch(req);
4070
+ return cors ? corsResponse(res) : res;
4023
4071
  }
4024
4072
  const res = await createInboxFetch({ sql: d1Sql(env.DB), ownerToken: env.OWNER_TOKEN })(req);
4025
4073
  return cors ? corsResponse(res) : res;
4026
4074
  }
4027
4075
  };
4028
4076
  export {
4029
- edge_worker_default as default,
4030
- createInboxFetch,
4031
- MhRoom,
4032
- EDGE_WORKER_VERSION,
4033
- EDGE_WORKER_MARKER,
4034
- EDGE_SCHEMA_SQL,
4035
- DROP_ENVELOPE_LIMIT_BYTES,
4077
+ DROP_DEFAULT_MAX_BYTES,
4036
4078
  DROP_DEFAULT_MAX_ENVELOPES,
4037
- DROP_DEFAULT_MAX_BYTES
4079
+ DROP_ENVELOPE_LIMIT_BYTES,
4080
+ EDGE_SCHEMA_SQL,
4081
+ EDGE_WORKER_MARKER,
4082
+ EDGE_WORKER_VERSION,
4083
+ MhRoom,
4084
+ createInboxFetch,
4085
+ edge_worker_default as default
4038
4086
  };