@sqlite-sync/core 0.6.0 → 0.7.0

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.
@@ -171,6 +171,8 @@ function introspectDb(_db) {
171
171
  isNullable: !col.notnull,
172
172
  isAutoIncrementing: col.name === autoIncrementCol,
173
173
  hasDefaultValue: col.dflt_value != null,
174
+ defaultValueSql: col.dflt_value == null ? null : String(col.dflt_value),
175
+ isPrimaryKey: col.pk > 0,
174
176
  comment: void 0
175
177
  }))
176
178
  }
@@ -892,6 +894,276 @@ function applyMemoryDbSchema(db) {
892
894
  );
893
895
  }
894
896
 
897
+ // src/schema/validate-crdt-event.ts
898
+ var CrdtEventValidationError = class extends Error {
899
+ constructor(errors) {
900
+ super(`Invalid CRDT events: ${errors.join("; ")}`);
901
+ this.errors = errors;
902
+ this.name = "CrdtEventValidationError";
903
+ }
904
+ };
905
+ var crdtEventTypes = ["item-created", "item-updated", "item-deleted"];
906
+ function validateNewCrdtEvent(schema, input) {
907
+ const errors = [];
908
+ if (!isRecord(input)) {
909
+ return { success: false, errors: ["Event must be an object"] };
910
+ }
911
+ const type = input.type;
912
+ const dataset = input.dataset;
913
+ const itemId = input.item_id;
914
+ let payload = input.payload;
915
+ let payloadParseFailed = false;
916
+ if (typeof payload === "string") {
917
+ try {
918
+ payload = JSON.parse(payload);
919
+ } catch {
920
+ payloadParseFailed = true;
921
+ errors.push(`Event payload is not valid JSON`);
922
+ }
923
+ }
924
+ if (!isCrdtEventType(type)) {
925
+ errors.push(`Invalid event type "${String(type)}"`);
926
+ }
927
+ if (typeof dataset !== "string") {
928
+ errors.push(`Event dataset must be a string`);
929
+ }
930
+ if (typeof itemId !== "string") {
931
+ errors.push(`Event item_id must be a string`);
932
+ }
933
+ if (!payloadParseFailed && !isRecord(payload)) {
934
+ errors.push(`Event payload must be an object`);
935
+ }
936
+ const datasetMatch = typeof dataset === "string" ? findTableForDataset(schema, dataset) : null;
937
+ if (typeof dataset === "string" && !datasetMatch) {
938
+ errors.push(`Unknown dataset "${dataset}"`);
939
+ }
940
+ if (isCrdtEventType(type) && datasetMatch && isRecord(payload)) {
941
+ switch (type) {
942
+ case "item-created": {
943
+ const result = datasetMatch.table.validatePayload(payload, { event: "item-created" });
944
+ if (!result.success) {
945
+ errors.push(...result.errors.map((error) => `payload: ${error}`));
946
+ }
947
+ if (typeof itemId === "string" && "id" in payload && payload.id !== itemId) {
948
+ errors.push(`payload: Column "id" must match item_id "${itemId}"`);
949
+ }
950
+ break;
951
+ }
952
+ case "item-updated": {
953
+ const result = datasetMatch.table.validatePayload(payload, { event: "item-updated" });
954
+ if (!result.success) {
955
+ errors.push(...result.errors.map((error) => `payload: ${error}`));
956
+ }
957
+ break;
958
+ }
959
+ case "item-deleted":
960
+ if (Object.keys(payload).length > 0) {
961
+ errors.push(`payload: item-deleted events must have an empty payload`);
962
+ }
963
+ break;
964
+ }
965
+ }
966
+ if (errors.length > 0) {
967
+ return { success: false, errors };
968
+ }
969
+ return {
970
+ success: true,
971
+ event: {
972
+ type,
973
+ dataset: datasetMatch?.baseTableName ?? dataset,
974
+ item_id: itemId,
975
+ payload
976
+ }
977
+ };
978
+ }
979
+ function findTableForDataset(schema, dataset) {
980
+ const config = schema.tablesConfig.find(
981
+ (tableConfig) => tableConfig.baseTableName === dataset || tableConfig.crdtTableName === dataset
982
+ );
983
+ if (config) {
984
+ const table2 = schema.tables[config.crdtTableName];
985
+ return table2 ? { table: table2, baseTableName: config.baseTableName } : null;
986
+ }
987
+ const table = schema.tables[dataset];
988
+ return table ? { table, baseTableName: dataset } : null;
989
+ }
990
+ function isRecord(value) {
991
+ return typeof value === "object" && value !== null && !Array.isArray(value);
992
+ }
993
+ function isCrdtEventType(value) {
994
+ return typeof value === "string" && crdtEventTypes.includes(value);
995
+ }
996
+
997
+ // src/schema/verify-sync-schema.ts
998
+ import sqlite3InitModule from "@sqlite.org/sqlite-wasm";
999
+ var acceptedDataTypes = {
1000
+ text: ["TEXT"],
1001
+ integer: ["INTEGER", "INT"],
1002
+ real: ["REAL", "DOUBLE", "FLOAT"],
1003
+ boolean: ["BOOLEAN", "INTEGER", "INT"],
1004
+ enum: ["TEXT"]
1005
+ };
1006
+ var sqliteModule = null;
1007
+ async function verifySyncSchema(schema) {
1008
+ if (!sqliteModule) {
1009
+ sqliteModule = await sqlite3InitModule();
1010
+ }
1011
+ const sqlite3 = sqliteModule;
1012
+ const db = new SQLiteDbWrapper({
1013
+ db: () => new sqlite3.oo1.DB({ filename: ":memory:" }),
1014
+ logger: () => {
1015
+ },
1016
+ loggerPrefix: "schema-verify",
1017
+ sqlite3
1018
+ });
1019
+ try {
1020
+ const migrator = createMigrator({
1021
+ migrations: schema.migrations,
1022
+ schemaVersion: createStoredValue({ initialValue: -1 })
1023
+ });
1024
+ try {
1025
+ migrator.migrateDbToLatest({
1026
+ startTransaction: (callback) => {
1027
+ db.executeTransaction(
1028
+ (tx) => callback({ execute: (sql4, parameters, meta) => tx.execute({ sql: sql4, parameters }, meta) })
1029
+ );
1030
+ }
1031
+ });
1032
+ } catch (error) {
1033
+ return [
1034
+ {
1035
+ table: "(migrations)",
1036
+ message: `migration replay failed on an empty database: ${error instanceof Error ? error.message : String(error)}`
1037
+ }
1038
+ ];
1039
+ }
1040
+ const introspection = introspectDb(db);
1041
+ const issues = [];
1042
+ for (const { crdtTableName, baseTableName } of schema.tablesConfig) {
1043
+ const declared = schema.tables[crdtTableName];
1044
+ if (!declared) continue;
1045
+ verifyTable(db, baseTableName, declared.columns, introspection[baseTableName], issues);
1046
+ }
1047
+ return issues;
1048
+ } finally {
1049
+ db.close();
1050
+ }
1051
+ }
1052
+ function formatSchemaVerificationIssues(issues) {
1053
+ const lines = issues.map(
1054
+ (issue) => ` - table "${issue.table}"${issue.column ? ` column "${issue.column}"` : ""}: ${issue.message}`
1055
+ );
1056
+ return `sync schema verification failed (${issues.length} issue${issues.length === 1 ? "" : "s"}):
1057
+ ${lines.join("\n")}`;
1058
+ }
1059
+ function verifyTable(db, table, declaredColumns, actual, issues) {
1060
+ if (!actual) {
1061
+ issues.push({
1062
+ table,
1063
+ message: "declared in the schema but missing after migrations \u2014 add a createTable step in a new version"
1064
+ });
1065
+ return;
1066
+ }
1067
+ if (actual.isView) {
1068
+ issues.push({ table, message: "expected a base table, but migrations created a view with this name" });
1069
+ return;
1070
+ }
1071
+ const actualColumns = new Map(actual.columns.map((column) => [column.name, column]));
1072
+ for (const [name, meta] of Object.entries(declaredColumns)) {
1073
+ const column = actualColumns.get(name);
1074
+ if (!column) {
1075
+ issues.push({
1076
+ table,
1077
+ column: name,
1078
+ message: "declared in the schema but missing after migrations \u2014 add an addColumn step in a new version"
1079
+ });
1080
+ continue;
1081
+ }
1082
+ const accepted = acceptedDataTypes[meta.kind];
1083
+ if (!accepted.includes(column.dataType.toUpperCase())) {
1084
+ issues.push({
1085
+ table,
1086
+ column: name,
1087
+ message: `type mismatch \u2014 schema declares ${meta.kind} (${accepted.join("/")}), migrated column is ${column.dataType.toUpperCase()}`
1088
+ });
1089
+ }
1090
+ if (column.isNullable !== meta.nullable) {
1091
+ issues.push({
1092
+ table,
1093
+ column: name,
1094
+ message: meta.nullable ? "schema declares the column nullable, but the migrated column is NOT NULL" : "schema declares the column NOT NULL, but the migrated column is nullable"
1095
+ });
1096
+ }
1097
+ if (name === "id" && !column.isPrimaryKey) {
1098
+ issues.push({ table, column: name, message: "the id column must be the PRIMARY KEY" });
1099
+ }
1100
+ verifyDefault(db, table, name, meta, column.defaultValueSql, issues);
1101
+ }
1102
+ for (const column of actual.columns) {
1103
+ if (!(column.name in declaredColumns)) {
1104
+ issues.push({
1105
+ table,
1106
+ column: column.name,
1107
+ message: "created by migrations but not declared in the schema \u2014 sync event payloads include every column, so declare it (or drop it in a new version)"
1108
+ });
1109
+ }
1110
+ }
1111
+ }
1112
+ function verifyDefault(db, table, column, meta, defaultValueSql, issues) {
1113
+ if (meta.hasDefault && meta.defaultValue !== null && defaultValueSql === null) {
1114
+ issues.push({
1115
+ table,
1116
+ column,
1117
+ message: `schema declares default ${formatExpected(meta)}, but the migrated column has no default`
1118
+ });
1119
+ return;
1120
+ }
1121
+ if (!meta.hasDefault && defaultValueSql !== null) {
1122
+ issues.push({
1123
+ table,
1124
+ column,
1125
+ message: `migrated column has default ${defaultValueSql}, but the schema declares none`
1126
+ });
1127
+ return;
1128
+ }
1129
+ if (!meta.hasDefault || defaultValueSql === null) {
1130
+ return;
1131
+ }
1132
+ let actual;
1133
+ try {
1134
+ actual = db.execute({
1135
+ sql: `SELECT (${defaultValueSql}) AS value`,
1136
+ parameters: []
1137
+ }).rows[0]?.value;
1138
+ } catch {
1139
+ actual = void 0;
1140
+ }
1141
+ if (actual !== expectedDefaultValue(meta)) {
1142
+ issues.push({
1143
+ table,
1144
+ column,
1145
+ message: `default mismatch \u2014 schema declares ${formatExpected(meta)}, migrated column default is ${defaultValueSql}`
1146
+ });
1147
+ }
1148
+ }
1149
+ function expectedDefaultValue(meta) {
1150
+ if (meta.defaultValue === null) return null;
1151
+ switch (meta.kind) {
1152
+ case "boolean":
1153
+ return meta.defaultValue ? 1 : 0;
1154
+ case "integer":
1155
+ case "real":
1156
+ return Number(meta.defaultValue);
1157
+ case "text":
1158
+ case "enum":
1159
+ return String(meta.defaultValue);
1160
+ }
1161
+ }
1162
+ function formatExpected(meta) {
1163
+ const expected = expectedDefaultValue(meta);
1164
+ return typeof expected === "string" ? `'${expected}'` : String(expected);
1165
+ }
1166
+
895
1167
  // src/sqlite-crdt/apply-crdt-event.ts
896
1168
  var createSQLiteCrdtApplyFunction = ({
897
1169
  db,
@@ -1084,6 +1356,16 @@ function createCrdtStorage(storage) {
1084
1356
  let localSyncId = storage.initialLocalSyncId;
1085
1357
  const db = storage.db;
1086
1358
  const crdtEventsTable = storage.dbConfig.eventsTable.fullIdentifier;
1359
+ const getInitialSequentialSyncId = () => {
1360
+ const [firstPendingEvent] = db.executePrepared(
1361
+ "get-first-pending-event",
1362
+ { status: "pending" },
1363
+ (db2, params) => db2.selectFrom(crdtEventsTable).select("sync_id").where("status", "=", params("status")).orderBy("sync_id", "asc").limit(sql3.lit(1)),
1364
+ { loggerLevel: "system" }
1365
+ );
1366
+ return firstPendingEvent ? firstPendingEvent.sync_id - 1 : localSyncId;
1367
+ };
1368
+ let sequentialSyncId = getInitialSequentialSyncId();
1087
1369
  const eventTarget = createTypedEventTarget();
1088
1370
  const persistEvent = (tx, event) => {
1089
1371
  tx.executePrepared(
@@ -1138,38 +1420,77 @@ function createCrdtStorage(storage) {
1138
1420
  };
1139
1421
  const notifyEventApplied = (event) => {
1140
1422
  if (event.status === "applied") {
1141
- storage.onEventApplied?.(event);
1423
+ queueMicrotask(() => {
1424
+ storage.onEventApplied?.(event);
1425
+ });
1426
+ }
1427
+ };
1428
+ const applyOwnEvents = (events) => {
1429
+ const schema = storage.schema;
1430
+ if (!schema) {
1431
+ throw new Error("applyOwnEvents requires a sync schema; none was provided to createCrdtStorage");
1432
+ }
1433
+ const validatedEvents = [];
1434
+ const errors = [];
1435
+ for (const [index, event] of events.entries()) {
1436
+ const result = validateNewCrdtEvent(schema, {
1437
+ type: event.type,
1438
+ dataset: event.dataset,
1439
+ item_id: event.item_id,
1440
+ payload: event.payload
1441
+ });
1442
+ if (!result.success) {
1443
+ errors.push(...result.errors.map((error) => `[${index}] ${error}`));
1444
+ continue;
1445
+ }
1446
+ validatedEvents.push(result.event);
1142
1447
  }
1448
+ if (errors.length > 0) {
1449
+ throw new CrdtEventValidationError(errors);
1450
+ }
1451
+ db.executeTransaction((tx) => {
1452
+ for (const event of validatedEvents) {
1453
+ const persistedEvent = {
1454
+ schema_version: storage.migrator.currentSchemaVersion,
1455
+ timestamp: serializeHLC(storage.hlc.getNextHLC()),
1456
+ type: event.type,
1457
+ dataset: event.dataset,
1458
+ item_id: event.item_id,
1459
+ origin: "own-applied",
1460
+ source_node_id: storage.nodeId,
1461
+ payload: JSON.stringify(event.payload),
1462
+ sync_id: ++localSyncId,
1463
+ status: "pending"
1464
+ };
1465
+ persistEvent(tx, persistedEvent);
1466
+ applyCrdtEvent(persistedEvent);
1467
+ }
1468
+ });
1469
+ void processEnqueuedEvents();
1143
1470
  };
1144
- const applyOwnEvent = (event, { wrapInTransaction } = {}) => {
1471
+ const applyOwnEventFromTransaction = (tx, event) => {
1145
1472
  const persistedEvent = {
1146
1473
  schema_version: storage.migrator.currentSchemaVersion,
1147
1474
  timestamp: serializeHLC(storage.hlc.getNextHLC()),
1148
1475
  type: event.type,
1149
1476
  dataset: event.dataset,
1150
1477
  item_id: event.item_id,
1151
- origin: "own",
1478
+ origin: "own-applied",
1152
1479
  source_node_id: storage.nodeId,
1153
1480
  payload: event.payload,
1154
1481
  sync_id: ++localSyncId,
1155
1482
  status: "pending"
1156
1483
  };
1157
- if (wrapInTransaction) {
1158
- db.executeTransaction((tx) => {
1159
- persistEvent(tx, persistedEvent);
1160
- processPersistedEvent(tx, persistedEvent);
1161
- persistEventHlcAccumulator();
1162
- });
1163
- } else {
1164
- persistEvent(db, persistedEvent);
1165
- processPersistedEvent(db, persistedEvent);
1166
- persistEventHlcAccumulator();
1167
- }
1484
+ persistEvent(tx, persistedEvent);
1485
+ applyCrdtEvent(persistedEvent);
1168
1486
  };
1169
- const dispatchEventsApplied = (syncId = localSyncId) => {
1487
+ const dispatchEventsApplied = (previousSequentialSyncId) => {
1488
+ if (sequentialSyncId <= previousSequentialSyncId) {
1489
+ return;
1490
+ }
1170
1491
  eventTarget.dispatchEvent("events-applied", {
1171
- syncId,
1172
- eventHlcSum: eventHlcAccumulator?.current ?? null
1492
+ syncId: sequentialSyncId,
1493
+ eventHlcSum: sequentialSyncId === localSyncId ? eventHlcAccumulator?.current ?? null : null
1173
1494
  });
1174
1495
  };
1175
1496
  const hasPendingEvents = () => {
@@ -1188,7 +1509,8 @@ function createCrdtStorage(storage) {
1188
1509
  status: options.status ?? null,
1189
1510
  afterSyncId: options.afterSyncId ?? null,
1190
1511
  excludeOrigin: options.excludeOrigin ?? null,
1191
- excludeNodeId: options.excludeNodeId ?? null
1512
+ excludeNodeId: options.excludeNodeId ?? null,
1513
+ maxSyncId: options.status === "applied" ? sequentialSyncId : localSyncId
1192
1514
  };
1193
1515
  const filterKeys = [
1194
1516
  queryParams.excludeNodeId ? "nodeid" : "no-nodeid",
@@ -1197,17 +1519,22 @@ function createCrdtStorage(storage) {
1197
1519
  const events = db.executePrepared(
1198
1520
  `get-events-batch-${filterKeys.join("-")}`,
1199
1521
  queryParams,
1200
- (db2, params) => db2.selectFrom(crdtEventsTable).where("sync_id", ">", params("afterSyncId")).where("status", "=", params("status")).$if(!!queryParams.excludeNodeId, (qb) => qb.where("source_node_id", "!=", params("excludeNodeId"))).$if(!!queryParams.excludeOrigin, (qb) => qb.where("origin", "!=", params("excludeOrigin"))).selectAll().limit(params("limit")).orderBy("sync_id", "asc"),
1522
+ (db2, params) => db2.selectFrom(crdtEventsTable).where("sync_id", ">", params("afterSyncId")).where("sync_id", "<=", params("maxSyncId")).where("status", "=", params("status")).$if(!!queryParams.excludeNodeId, (qb) => qb.where("source_node_id", "!=", params("excludeNodeId"))).$if(!!queryParams.excludeOrigin, (qb) => qb.where("origin", "!=", params("excludeOrigin"))).selectAll().limit(params("limit")).orderBy("sync_id", "asc"),
1201
1523
  { loggerLevel: "system" }
1202
1524
  );
1203
1525
  const hasMore = events.length > limit;
1204
1526
  if (hasMore) {
1205
1527
  events.pop();
1206
1528
  }
1529
+ const lastReturnedSyncId = events[events.length - 1]?.sync_id ?? options.afterSyncId ?? 0;
1530
+ let nextSyncId = lastReturnedSyncId;
1531
+ if (!hasMore && options.status === "applied") {
1532
+ nextSyncId = Math.max(lastReturnedSyncId, queryParams.maxSyncId);
1533
+ }
1207
1534
  return {
1208
1535
  events,
1209
1536
  hasMore,
1210
- nextSyncId: events[events.length - 1]?.sync_id ?? options.afterSyncId ?? 0
1537
+ nextSyncId
1211
1538
  };
1212
1539
  };
1213
1540
  const checkIsQuiescent = (pushedSyncId) => {
@@ -1278,6 +1605,10 @@ function createCrdtStorage(storage) {
1278
1605
  throw new Error(`Event ${event.sync_id} is not pending`);
1279
1606
  }
1280
1607
  try {
1608
+ if (event.origin === "own-applied") {
1609
+ event.status = "applied";
1610
+ return event;
1611
+ }
1281
1612
  if (hasAcceptedEventWithTimestamp(tx, event)) {
1282
1613
  event.status = "deduped";
1283
1614
  return event;
@@ -1288,7 +1619,6 @@ function createCrdtStorage(storage) {
1288
1619
  if (isNoOpCrdtEventPayload(event.payload)) {
1289
1620
  applyCrdtEvent(event);
1290
1621
  event.status = "applied";
1291
- eventHlcAccumulator?.add(event.timestamp);
1292
1622
  return event;
1293
1623
  }
1294
1624
  const migratedEvent = storage.migrator.migrateEvent(event, storage.migrator.latestSchemaVersion);
@@ -1297,7 +1627,6 @@ function createCrdtStorage(storage) {
1297
1627
  event.payload = CRDT_EVENT_NO_OP_PAYLOAD;
1298
1628
  applyCrdtEvent(event);
1299
1629
  event.status = "applied";
1300
- eventHlcAccumulator?.add(event.timestamp);
1301
1630
  return event;
1302
1631
  }
1303
1632
  event.schema_version = migratedEvent.schema_version;
@@ -1307,7 +1636,6 @@ function createCrdtStorage(storage) {
1307
1636
  event.payload = migratedEvent.payload;
1308
1637
  applyCrdtEvent(event);
1309
1638
  event.status = "applied";
1310
- eventHlcAccumulator?.add(event.timestamp);
1311
1639
  } catch (error) {
1312
1640
  console.error("Error applying enqueued CRDT event", error);
1313
1641
  event.status = "failed";
@@ -1345,26 +1673,28 @@ function createCrdtStorage(storage) {
1345
1673
  if (hasMore) {
1346
1674
  events.pop();
1347
1675
  }
1676
+ const previousSequentialSyncId = sequentialSyncId;
1348
1677
  if (events.length === 0) {
1678
+ sequentialSyncId = localSyncId;
1679
+ dispatchEventsApplied(previousSequentialSyncId);
1349
1680
  break;
1350
1681
  }
1351
- let appliedSyncId = null;
1352
1682
  const failedRemoteSyncIds = [];
1353
1683
  db.executeTransaction((tx) => {
1354
1684
  for (const event of events) {
1355
1685
  processPersistedEvent(tx, event);
1356
- notifyEventApplied(event);
1357
1686
  if (event.status === "applied") {
1358
- appliedSyncId = event.sync_id;
1359
- } else if (event.status === "failed" && event.origin === "remote") {
1687
+ eventHlcAccumulator?.add(event.timestamp);
1688
+ }
1689
+ notifyEventApplied(event);
1690
+ if (event.status === "failed" && event.origin === "remote") {
1360
1691
  failedRemoteSyncIds.push(event.sync_id);
1361
1692
  }
1362
1693
  }
1363
1694
  persistEventHlcAccumulator();
1364
1695
  });
1365
- if (appliedSyncId !== null) {
1366
- dispatchEventsApplied(appliedSyncId);
1367
- }
1696
+ sequentialSyncId = hasMore ? events[events.length - 1]?.sync_id ?? sequentialSyncId : localSyncId;
1697
+ dispatchEventsApplied(previousSequentialSyncId);
1368
1698
  for (const syncId of failedRemoteSyncIds) {
1369
1699
  eventTarget.dispatchEvent("remote-event-apply-failed", { syncId });
1370
1700
  }
@@ -1377,12 +1707,15 @@ function createCrdtStorage(storage) {
1377
1707
  enqueueLocalEvents,
1378
1708
  enqueueOwnEvents,
1379
1709
  enqueueRemoteEvents,
1380
- applyOwnEvent,
1381
- dispatchEventsApplied,
1710
+ applyOwnEvents,
1382
1711
  checkIsQuiescent,
1383
1712
  getEventHlcAccumulator: () => eventHlcAccumulator?.current ?? null,
1384
1713
  addEventListener: eventTarget.addEventListener,
1385
- removeEventListener: eventTarget.removeEventListener
1714
+ removeEventListener: eventTarget.removeEventListener,
1715
+ internal: {
1716
+ applyOwnEventFromTransaction,
1717
+ processEnqueuedEvents
1718
+ }
1386
1719
  };
1387
1720
  }
1388
1721
 
@@ -1850,6 +2183,10 @@ export {
1850
2183
  runSystemMigrations,
1851
2184
  applyWorkerDbSchema,
1852
2185
  applyMemoryDbSchema,
2186
+ CrdtEventValidationError,
2187
+ validateNewCrdtEvent,
2188
+ verifySyncSchema,
2189
+ formatSchemaVerificationIssues,
1853
2190
  createSQLiteCrdtApplyFunction,
1854
2191
  createCrdtApplyFunction,
1855
2192
  createCrdtStorage,
@@ -1868,4 +2205,4 @@ export {
1868
2205
  createResetStateStore,
1869
2206
  createReloadRequestHandler
1870
2207
  };
1871
- //# sourceMappingURL=chunk-3L4QG3BZ.js.map
2208
+ //# sourceMappingURL=chunk-LBYL5L4O.js.map