@sqlite-sync/core 0.9.3 → 0.10.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.
@@ -1,5 +1,6 @@
1
- import { a as ensureSingletonExecution, f as tryCatchAsync, i as createTypedEventTarget, o as generateId, t as TypedBroadcastChannel, u as quoteId } from "./utils-Dr5JwcTP.js";
2
- import { d as CRDT_EVENT_NO_OP_PAYLOAD, f as isNoOpCrdtEventPayload, u as createStoredValue } from "./system-schema-CkglcfTS.js";
1
+ import { c as generateId, f as quoteId, n as isNoOpCrdtEventPayload, o as createTypedEventTarget, r as TypedBroadcastChannel, s as ensureSingletonExecution, t as CRDT_EVENT_NO_OP_PAYLOAD } from "./crdt-table-schema-2w_AIpsV.js";
2
+ import { c as serializeHLC, n as CrdtEventValidationError, r as validateNewCrdtEvent, s as deserializeHLC } from "./crdt-sync-remote-source-Dtvyrk0R.js";
3
+ import { u as createStoredValue } from "./system-schema-C2JZDv6L.js";
3
4
  import { DummyDriver, Kysely, SqliteAdapter, SqliteIntrospector, SqliteQueryCompiler, sql } from "kysely";
4
5
  import initXxhash from "xxhash-wasm";
5
6
  import sqlite3InitModule from "@sqlite.org/sqlite-wasm";
@@ -132,81 +133,6 @@ const xxhash = {
132
133
  h64
133
134
  };
134
135
  //#endregion
135
- //#region src/hlc.ts
136
- const MAX_COUNTER = 36 ** 5 - 1;
137
- const DEFAULT_MAX_DRIFT_MS = 216e5;
138
- var HLCCounter = class {
139
- timestamp;
140
- counter;
141
- nodeId;
142
- getTimestamp;
143
- maxDrift;
144
- constructor(nodeId, getTimestamp, maxDrift = DEFAULT_MAX_DRIFT_MS) {
145
- this.timestamp = getTimestamp();
146
- this.counter = 0;
147
- this.nodeId = nodeId;
148
- this.getTimestamp = getTimestamp;
149
- this.maxDrift = maxDrift;
150
- }
151
- getCurrentHLC() {
152
- return {
153
- timestamp: this.timestamp,
154
- counter: this.counter,
155
- nodeId: this.nodeId
156
- };
157
- }
158
- getNextHLC() {
159
- const now = this.getTimestamp();
160
- if (now > this.timestamp) {
161
- this.timestamp = now;
162
- this.counter = 0;
163
- return this.getCurrentHLC();
164
- }
165
- this.counter++;
166
- if (this.counter > MAX_COUNTER) throw new Error(`HLC counter overflow: exceeded max value ${MAX_COUNTER}`);
167
- return this.getCurrentHLC();
168
- }
169
- mergeHLC(hlc) {
170
- const now = this.getTimestamp();
171
- if (hlc.timestamp - now > this.maxDrift) {
172
- console.warn(`HLC: ignoring far-future timestamp (remote=${hlc.timestamp}, local=${now}, drift=${hlc.timestamp - now}ms)`);
173
- return;
174
- }
175
- if (this.timestamp === hlc.timestamp) this.counter = Math.max(this.counter, hlc.counter) + 1;
176
- else if (this.timestamp > hlc.timestamp) this.counter++;
177
- else {
178
- this.timestamp = hlc.timestamp;
179
- this.counter = hlc.counter + 1;
180
- }
181
- if (this.counter > MAX_COUNTER) throw new Error(`HLC counter overflow: exceeded max value ${MAX_COUNTER}`);
182
- }
183
- };
184
- function serializeHLC(hlc) {
185
- return `${hlc.timestamp.toString().padStart(15, "0")}:${hlc.counter.toString(36).padStart(5, "0")}:${hlc.nodeId}`;
186
- }
187
- function deserializeHLC(serialized) {
188
- const parts = serialized.split(":");
189
- if (parts.length < 3) throw new Error(`Invalid HLC format: expected at least 3 colon-separated segments, got ${parts.length}`);
190
- const timestamp = parseInt(parts[0], 10);
191
- const counter = parseInt(parts[1], 36);
192
- if (Number.isNaN(timestamp) || Number.isNaN(counter)) throw new Error(`Invalid HLC values: timestamp=${parts[0]}, counter=${parts[1]}`);
193
- return {
194
- timestamp,
195
- counter,
196
- nodeId: parts.slice(2).join(":")
197
- };
198
- }
199
- function compareHLC(one, two) {
200
- if (one.timestamp === two.timestamp) {
201
- if (one.counter === two.counter) {
202
- if (one.nodeId === two.nodeId) return 0;
203
- return one.nodeId < two.nodeId ? -1 : 1;
204
- }
205
- return one.counter - two.counter;
206
- }
207
- return one.timestamp - two.timestamp;
208
- }
209
- //#endregion
210
136
  //#region src/introspection.ts
211
137
  function tablesQuery(qb) {
212
138
  return qb.selectFrom("sqlite_master").where("type", "in", ["table", "view"]).where("name", "not like", "sqlite_%").select([
@@ -775,93 +701,6 @@ WHERE "dataset" = ?
775
701
  };
776
702
  }
777
703
  //#endregion
778
- //#region src/schema/validate-crdt-event.ts
779
- var CrdtEventValidationError = class extends Error {
780
- errors;
781
- constructor(errors) {
782
- super(`Invalid CRDT events: ${errors.join("; ")}`);
783
- this.errors = errors;
784
- this.name = "CrdtEventValidationError";
785
- }
786
- };
787
- const crdtEventTypes = [
788
- "item-created",
789
- "item-updated",
790
- "item-deleted"
791
- ];
792
- function validateNewCrdtEvent(schema, input) {
793
- const errors = [];
794
- if (!isRecord(input)) return {
795
- success: false,
796
- errors: ["Event must be an object"]
797
- };
798
- const type = input.type;
799
- const dataset = input.dataset;
800
- const itemId = input.item_id;
801
- let payload = input.payload;
802
- let payloadParseFailed = false;
803
- if (typeof payload === "string") try {
804
- payload = JSON.parse(payload);
805
- } catch {
806
- payloadParseFailed = true;
807
- errors.push(`Event payload is not valid JSON`);
808
- }
809
- if (!isCrdtEventType(type)) errors.push(`Invalid event type "${String(type)}"`);
810
- if (typeof dataset !== "string") errors.push(`Event dataset must be a string`);
811
- if (typeof itemId !== "string") errors.push(`Event item_id must be a string`);
812
- if (!payloadParseFailed && !isRecord(payload)) errors.push(`Event payload must be an object`);
813
- const datasetMatch = typeof dataset === "string" ? findTableForDataset(schema, dataset) : null;
814
- if (typeof dataset === "string" && !datasetMatch) errors.push(`Unknown dataset "${dataset}"`);
815
- if (isCrdtEventType(type) && datasetMatch && isRecord(payload)) switch (type) {
816
- case "item-created": {
817
- const result = datasetMatch.table.validatePayload(payload, { event: "item-created" });
818
- if (!result.success) errors.push(...result.errors.map((error) => `payload: ${error}`));
819
- if (typeof itemId === "string" && "id" in payload && payload.id !== itemId) errors.push(`payload: Column "id" must match item_id "${itemId}"`);
820
- break;
821
- }
822
- case "item-updated": {
823
- const result = datasetMatch.table.validatePayload(payload, { event: "item-updated" });
824
- if (!result.success) errors.push(...result.errors.map((error) => `payload: ${error}`));
825
- break;
826
- }
827
- case "item-deleted": if (Object.keys(payload).length > 0) errors.push(`payload: item-deleted events must have an empty payload`);
828
- }
829
- if (errors.length > 0) return {
830
- success: false,
831
- errors
832
- };
833
- return {
834
- success: true,
835
- event: {
836
- type,
837
- dataset: datasetMatch?.baseTableName ?? dataset,
838
- item_id: itemId,
839
- payload
840
- }
841
- };
842
- }
843
- function findTableForDataset(schema, dataset) {
844
- const config = schema.tablesConfig.find((tableConfig) => tableConfig.baseTableName === dataset || tableConfig.crdtTableName === dataset);
845
- if (config) {
846
- const table = schema.tables[config.crdtTableName];
847
- return table ? {
848
- table,
849
- baseTableName: config.baseTableName
850
- } : null;
851
- }
852
- const table = schema.tables[dataset];
853
- return table ? {
854
- table,
855
- baseTableName: dataset
856
- } : null;
857
- }
858
- function isRecord(value) {
859
- return typeof value === "object" && value !== null && !Array.isArray(value);
860
- }
861
- function isCrdtEventType(value) {
862
- return typeof value === "string" && crdtEventTypes.includes(value);
863
- }
864
- //#endregion
865
704
  //#region src/schema/verify-sync-schema.ts
866
705
  const acceptedDataTypes = {
867
706
  text: ["TEXT"],
@@ -1098,6 +937,7 @@ function createCrdtApplyFunction({ getCrdtUpdateLog, insertItem, insertCrdtUpdat
1098
937
  const applyItemUpdated = ({ event, meta }) => {
1099
938
  if (!meta) throw new Error(`Item ${event.item_id} in dataset ${event.dataset} not found`);
1100
939
  const eventPayload = event.type === "item-deleted" ? { tombstone: 1 } : JSON.parse(event.payload);
940
+ if (event.type === "item-created") eventPayload.tombstone = 0;
1101
941
  const updatePayload = {};
1102
942
  let hasUpdates = false;
1103
943
  for (const [key, value] of Object.entries(eventPayload)) {
@@ -1178,6 +1018,17 @@ function createCrdtStorage(storage) {
1178
1018
  const crdtEventsTable = storage.dbConfig.eventsTable.fullIdentifier;
1179
1019
  const quotedEventsTable = quoteId(storage.dbConfig.eventsTable.fullIdentifier);
1180
1020
  const noOpPayloadSqlLiteral = `'${CRDT_EVENT_NO_OP_PAYLOAD}'`;
1021
+ const [persistedClock] = db.executePreparedRaw({
1022
+ key: "get-persisted-hlc",
1023
+ sql: `select max("timestamp") as "timestamp" from (
1024
+ select max("timestamp") as "timestamp" from ${quotedEventsTable} where "status" = 'applied'
1025
+ union all
1026
+ select max(fields.value) as "timestamp"
1027
+ from ${quoteId(storage.dbConfig.updateLogTable.fullIdentifier)} as updates, json_each(updates.payload) as fields
1028
+ )`,
1029
+ meta: { loggerLevel: "system" }
1030
+ });
1031
+ if (persistedClock?.timestamp) storage.hlc.restoreHLC(deserializeHLC(persistedClock.timestamp));
1181
1032
  const getInitialSequentialSyncId = () => {
1182
1033
  const [firstPendingEvent] = db.executePrepared("get-first-pending-event", { status: "pending" }, (db, params) => db.selectFrom(crdtEventsTable).select("sync_id").where("status", "=", params("status")).orderBy("sync_id", "asc").limit(sql.lit(1)), { loggerLevel: "system" });
1183
1034
  return firstPendingEvent ? firstPendingEvent.sync_id - 1 : localSyncId;
@@ -1273,7 +1124,13 @@ function createCrdtStorage(storage) {
1273
1124
  };
1274
1125
  };
1275
1126
  const enqueueLocalEvents = (events, sourceNodeId) => {
1276
- return enqueueEvents("local", sourceNodeId, events);
1127
+ const known = getFirstAcceptedSyncIdsByTimestamp(db, events);
1128
+ const newEvents = events.filter((event) => {
1129
+ if (known.has(event.timestamp)) return false;
1130
+ known.set(event.timestamp, 0);
1131
+ return true;
1132
+ });
1133
+ return enqueueEvents("local", sourceNodeId, newEvents);
1277
1134
  };
1278
1135
  const enqueueOwnEvents = (events) => {
1279
1136
  return enqueueEvents("own", storage.nodeId, events);
@@ -1359,7 +1216,19 @@ function createCrdtStorage(storage) {
1359
1216
  sync_id: syncId,
1360
1217
  status: "pending"
1361
1218
  };
1362
- tx.executePreparedRaw({
1219
+ const [newerEvent] = tx.executePreparedRaw({
1220
+ key: "get-crdt-row-event-newer-than-snapshot",
1221
+ sql: `select "sync_id" from ${quotedEventsTable}
1222
+ where "dataset" = ? and "item_id" = ? and "timestamp" > ? and "payload" <> ${noOpPayloadSqlLiteral}
1223
+ limit 1`,
1224
+ params: [
1225
+ event.dataset,
1226
+ event.item_id,
1227
+ event.timestamp
1228
+ ],
1229
+ meta: { loggerLevel: "system" }
1230
+ });
1231
+ if (!newerEvent) tx.executePreparedRaw({
1363
1232
  key: "replace-crdt-row-history-with-no-ops",
1364
1233
  sql: `update ${quotedEventsTable}
1365
1234
  set "payload" = ?
@@ -1486,7 +1355,7 @@ where "dataset" = ? and "item_id" = ? and "payload" <> ${noOpPayloadSqlLiteral}`
1486
1355
  persistEventHlcAccumulator();
1487
1356
  };
1488
1357
  const getFirstAcceptedSyncIdsByTimestamp = (tx, events) => {
1489
- const timestamps = Array.from(new Set(events.filter((event) => event.origin !== "own-applied").map((event) => event.timestamp)));
1358
+ const timestamps = Array.from(new Set(events.map((event) => event.timestamp)));
1490
1359
  if (timestamps.length === 0) return /* @__PURE__ */ new Map();
1491
1360
  const rows = timestamps.length === 1 ? tx.executePreparedRaw({
1492
1361
  key: "get-first-accepted-sync-id-by-timestamp",
@@ -1602,7 +1471,7 @@ where "dataset" = ? and "item_id" = ? and "payload" <> ${noOpPayloadSqlLiteral}`
1602
1471
  const failedRemoteSyncIds = [];
1603
1472
  const appliedEventsToNotify = [];
1604
1473
  db.executeTransaction((tx) => {
1605
- const firstAcceptedSyncIdByTimestamp = getFirstAcceptedSyncIdsByTimestamp(tx, events);
1474
+ const firstAcceptedSyncIdByTimestamp = getFirstAcceptedSyncIdsByTimestamp(tx, events.filter((event) => event.origin !== "own-applied"));
1606
1475
  const statusOnlyEvents = [];
1607
1476
  for (const event of events) {
1608
1477
  processPersistedEvent(tx, event, firstAcceptedSyncIdByTimestamp, statusOnlyEvents);
@@ -1656,265 +1525,6 @@ const createCrdtSyncProducer = ({ storage, broadcastEvents }) => {
1656
1525
  });
1657
1526
  };
1658
1527
  //#endregion
1659
- //#region src/sqlite-crdt/retry-remote-operation.ts
1660
- const REMOTE_RETRY_OPTIONS = {
1661
- maxAttempts: 3,
1662
- backoffBaseMs: 100,
1663
- backoffExponent: 1.5,
1664
- backoffJitterMs: 150,
1665
- timeoutMs: 1e4
1666
- };
1667
- var RetryTimeoutError = class extends Error {
1668
- previous;
1669
- constructor(message, previous) {
1670
- super(message);
1671
- this.previous = previous;
1672
- this.name = "TimeoutError";
1673
- }
1674
- };
1675
- const applyJitter = (delayMs, maxJitterMs) => {
1676
- const jitter = Math.random() * maxJitterMs * (Math.random() > .5 ? 1 : -1);
1677
- return Math.max(0, delayMs + jitter);
1678
- };
1679
- const delay = (delayMs) => new Promise((resolve) => setTimeout(resolve, delayMs));
1680
- const withTimeout = async (operation, timeoutMs, previousError) => {
1681
- let timeoutId;
1682
- try {
1683
- return await Promise.race([operation(), new Promise((_, reject) => {
1684
- timeoutId = setTimeout(() => reject(new RetryTimeoutError("Remote operation timed out", previousError)), timeoutMs);
1685
- })]);
1686
- } finally {
1687
- if (timeoutId) clearTimeout(timeoutId);
1688
- }
1689
- };
1690
- const retryRemoteOperation = async (operation, options) => {
1691
- let lastError;
1692
- for (let attempt = 1; attempt <= options.maxAttempts; attempt++) try {
1693
- return await withTimeout(operation, options.timeoutMs, lastError);
1694
- } catch (error) {
1695
- lastError = error;
1696
- if (attempt >= options.maxAttempts) throw error;
1697
- const backoffDelay = applyJitter(options.backoffBaseMs * options.backoffExponent ** (attempt - 1), options.backoffJitterMs);
1698
- if (backoffDelay > 0) await delay(backoffDelay);
1699
- }
1700
- throw lastError;
1701
- };
1702
- //#endregion
1703
- //#region src/sqlite-crdt/crdt-sync-remote-source.ts
1704
- var SchemaVersionMismatchError = class extends Error {
1705
- remoteSchemaVersion;
1706
- localSchemaVersion;
1707
- constructor(remoteSchemaVersion, localSchemaVersion) {
1708
- super(`Schema version mismatch: remote ${remoteSchemaVersion} != local ${localSchemaVersion}`);
1709
- this.remoteSchemaVersion = remoteSchemaVersion;
1710
- this.localSchemaVersion = localSchemaVersion;
1711
- this.name = "SchemaVersionMismatchError";
1712
- }
1713
- };
1714
- const createCrdtSyncRemoteSource = ({ bufferSize, storage, migrator, pullSyncId, pushSyncId, nodeId, remoteFactory }) => {
1715
- const eventTarget = createTypedEventTarget();
1716
- let remoteState = {
1717
- type: "offline",
1718
- reason: "NOT_INITIALIZED",
1719
- deSynced: false,
1720
- schemaVersionMismatched: false
1721
- };
1722
- const patchRemoteState = (state) => {
1723
- remoteState = {
1724
- ...remoteState,
1725
- ...state
1726
- };
1727
- eventTarget.dispatchEvent("state-changed", remoteState.type);
1728
- };
1729
- const initRemote = ensureSingletonExecution(async () => {
1730
- if (remoteState.type !== "offline") throw new Error("Remote source is not offline");
1731
- if (!remoteFactory) {
1732
- console.warn("Remote source factory not provided. Going offline.");
1733
- patchRemoteState({
1734
- type: "offline",
1735
- reason: "NOT_INITIALIZED"
1736
- });
1737
- return;
1738
- }
1739
- patchRemoteState({ type: "pending" });
1740
- const factoryResult = await tryCatchAsync(async () => {
1741
- return await remoteFactory?.({ onEventsAvailable: ({ newSyncId, remoteEventHlcSum }) => {
1742
- pullEvents({
1743
- remoteSyncId: newSyncId,
1744
- remoteEventHlcSum,
1745
- includeSelf: false
1746
- });
1747
- } });
1748
- });
1749
- if (!factoryResult.success) {
1750
- patchRemoteState({
1751
- type: "offline",
1752
- reason: "INITIALIZATION_FAILED"
1753
- });
1754
- console.warn("Failed to create remote source", factoryResult.error);
1755
- return;
1756
- }
1757
- patchRemoteState({
1758
- type: "online",
1759
- source: factoryResult.data,
1760
- deSynced: false,
1761
- schemaVersionMismatched: false
1762
- });
1763
- }, { queueReExecution: false });
1764
- const syncWithRemote = ensureSingletonExecution(async () => {
1765
- if (remoteState.type !== "online") return;
1766
- await pullEvents();
1767
- await startPushingEvents();
1768
- }, { queueReExecution: false });
1769
- const goOffline = ensureSingletonExecution(async (reason) => {
1770
- if (remoteState.type !== "online") return;
1771
- const source = remoteState.source;
1772
- patchRemoteState({ type: "pending" });
1773
- const disconnectResult = await tryCatchAsync(async () => {
1774
- return await source.disconnect?.();
1775
- });
1776
- if (!disconnectResult.success) console.warn("Error while disconnecting from remote source", disconnectResult.error);
1777
- patchRemoteState({
1778
- type: "offline",
1779
- reason
1780
- });
1781
- }, { queueReExecution: false });
1782
- const goOnline = async () => {
1783
- if (remoteState.type !== "online") await initRemote();
1784
- if (remoteState.type === "online") await syncWithRemote();
1785
- };
1786
- let requestedPullSyncId = null;
1787
- let pullPromise = null;
1788
- const pullEvents = (request) => {
1789
- if (remoteState.type !== "online") return Promise.resolve();
1790
- const remoteSyncId = request?.remoteSyncId;
1791
- if (remoteSyncId !== void 0 && remoteSyncId <= pullSyncId.current) {
1792
- checkRemoteConsistency(remoteSyncId, request?.remoteEventHlcSum ?? null);
1793
- return Promise.resolve();
1794
- }
1795
- if (pullPromise) {
1796
- if (remoteSyncId !== void 0 && (!requestedPullSyncId || requestedPullSyncId < remoteSyncId)) requestedPullSyncId = remoteSyncId;
1797
- return pullPromise;
1798
- }
1799
- pullPromise = pullAllEvents({
1800
- afterSyncId: pullSyncId.current,
1801
- excludeNodeId: request?.includeSelf ? void 0 : nodeId
1802
- }).catch((error) => {
1803
- console.error("Error pulling events. Going offline.", error);
1804
- goOffline("REMOTE_PULL_ERROR");
1805
- }).finally(() => {
1806
- pullPromise = null;
1807
- const nextTarget = requestedPullSyncId;
1808
- requestedPullSyncId = null;
1809
- if (nextTarget && nextTarget > pullSyncId.current) pullEvents({ remoteSyncId: nextTarget });
1810
- });
1811
- return pullPromise;
1812
- };
1813
- const pullAllEvents = async (opts) => {
1814
- let hasMore = true;
1815
- let afterSyncId = opts.afterSyncId;
1816
- while (hasMore) {
1817
- if (remoteState.type !== "online") return;
1818
- const source = remoteState.source;
1819
- const response = await retryRemoteOperation(() => source.pullEvents({
1820
- ...opts,
1821
- afterSyncId
1822
- }), REMOTE_RETRY_OPTIONS);
1823
- hasMore = response.hasMore;
1824
- afterSyncId = response.nextSyncId;
1825
- if (response.events) storage.enqueueRemoteEvents(response.events.map((x) => {
1826
- if (x.schema_version > migrator.currentSchemaVersion) {
1827
- eventTarget.dispatchEvent("remote-schema-version-mismatch", {
1828
- remoteSchemaVersion: x.schema_version,
1829
- localSchemaVersion: migrator.currentSchemaVersion
1830
- });
1831
- if (remoteState.type === "online" && !remoteState.schemaVersionMismatched) patchRemoteState({ schemaVersionMismatched: true });
1832
- throw new SchemaVersionMismatchError(x.schema_version, migrator.currentSchemaVersion);
1833
- }
1834
- return x;
1835
- }));
1836
- if (response.nextSyncId <= pullSyncId.current) break;
1837
- if (response.nextSyncId > pullSyncId.current) pullSyncId.current = response.nextSyncId;
1838
- }
1839
- };
1840
- const checkRemoteConsistency = (remoteSyncId, remoteEventHlcSum) => {
1841
- if (remoteEventHlcSum === null) return;
1842
- if (remoteSyncId !== pullSyncId.current) return;
1843
- if (!storage.checkIsQuiescent(pushSyncId.current)) return;
1844
- const localEventHlcSum = storage.getEventHlcAccumulator();
1845
- if (localEventHlcSum === null) return;
1846
- if (localEventHlcSum === remoteEventHlcSum) return;
1847
- eventTarget.dispatchEvent("de-sync-detected", { reason: "CHECKSUM_MISMATCH" });
1848
- console.warn(`[sqlite-sync] De-sync detected at syncId ${remoteSyncId}: local HLC checksum ${localEventHlcSum} != remote ${remoteEventHlcSum}. Local and remote have diverged despite being caught up.`);
1849
- if (remoteState.type === "online" && !remoteState.deSynced) patchRemoteState({ deSynced: true });
1850
- };
1851
- const startPushingEvents = ensureSingletonExecution(async () => {
1852
- while (true) {
1853
- const eventsBatch = storage.getEventsBatch({
1854
- status: "applied",
1855
- afterSyncId: pushSyncId.current,
1856
- excludeOrigin: "remote",
1857
- limit: bufferSize
1858
- });
1859
- if (eventsBatch.events.length === 0) break;
1860
- if (remoteState.type !== "online") break;
1861
- const source = remoteState.source;
1862
- let response;
1863
- try {
1864
- response = await retryRemoteOperation(() => source.pushEvents({
1865
- nodeId,
1866
- events: eventsBatch.events.map((event) => ({
1867
- schema_version: event.schema_version,
1868
- timestamp: event.timestamp,
1869
- type: event.type,
1870
- dataset: event.dataset,
1871
- item_id: event.item_id,
1872
- payload: event.payload
1873
- }))
1874
- }), REMOTE_RETRY_OPTIONS);
1875
- } catch (error) {
1876
- console.error("Error pushing events. Going offline.", error);
1877
- goOffline("REMOTE_PUSH_ERROR");
1878
- return;
1879
- }
1880
- if (!response.ok) {
1881
- console.error("Remote rejected pushed events. Going offline.");
1882
- goOffline("REMOTE_PUSH_ERROR");
1883
- return;
1884
- }
1885
- pushSyncId.current = eventsBatch.nextSyncId;
1886
- if (response.beforeSyncId !== void 0 && response.afterSyncId !== void 0 && response.beforeSyncId <= pullSyncId.current && response.afterSyncId > pullSyncId.current) pullSyncId.current = response.afterSyncId;
1887
- if (!eventsBatch.hasMore) break;
1888
- }
1889
- });
1890
- const eventsAppliedSubscription = storage.addEventListener("events-applied", () => {
1891
- startPushingEvents();
1892
- });
1893
- const remoteEventApplyFailedSubscription = storage.addEventListener("remote-event-apply-failed", () => {
1894
- eventTarget.dispatchEvent("de-sync-detected", { reason: "ERROR_APPLYING_REMOTE_EVENT" });
1895
- if (remoteState.type === "online" && !remoteState.deSynced) patchRemoteState({ deSynced: true });
1896
- });
1897
- const getState = () => ({
1898
- remoteState: remoteState.type,
1899
- deSynced: remoteState.deSynced,
1900
- schemaVersionMismatched: remoteState.schemaVersionMismatched
1901
- });
1902
- const dispose = async () => {
1903
- await goOffline("DISCONNECTED");
1904
- eventsAppliedSubscription.unsubscribe();
1905
- remoteEventApplyFailedSubscription.unsubscribe();
1906
- };
1907
- return {
1908
- goOnline,
1909
- goOffline,
1910
- syncWithRemote,
1911
- getState,
1912
- dispose,
1913
- addEventListener: eventTarget.addEventListener,
1914
- removeEventListener: eventTarget.removeEventListener
1915
- };
1916
- };
1917
- //#endregion
1918
1528
  //#region src/worker-db/worker-common.ts
1919
1529
  const syncDbWorkerLockName = "sync-db-worker-lock";
1920
1530
  const syncDbClientLockName = "sync-db-client-lock";
@@ -2023,6 +1633,6 @@ function createReloadRequestHandler({ resetState, broadcast, generateEpoch = gen
2023
1633
  };
2024
1634
  }
2025
1635
  //#endregion
2026
- export { serializeHLC as A, createMigrator as C, HLCCounter as D, introspectDb as E, createExportData as M, createImportData as N, compareHLC as O, dummyKysely as P, createMigrations as S, startPerformanceLogger as T, createSQLiteCrdtApplyFunction as _, createBroadcastChannels as a, CrdtEventValidationError as b, isWorkerNotificationMessage as c, syncDbClientLockName as d, syncDbWorkerLockName as f, createCrdtApplyFunction as g, createCrdtStorage as h, createResetStateStore as i, xxhash as j, deserializeHLC as k, isWorkerRequestMessage as l, createCrdtSyncProducer as m, createIdbResetStore as n, isWorkerErrorResponseMessage as o, createCrdtSyncRemoteSource as p, createReloadRequestHandler as r, isWorkerInitMessage as s, RESET_REQUEST_TTL_MS as t, isWorkerResponseMessage as u, formatSchemaVerificationIssues as v, SQLiteDbWrapper as w, validateNewCrdtEvent as x, verifySyncSchema as y };
1636
+ export { introspectDb as C, dummyKysely as D, createImportData as E, startPerformanceLogger as S, createExportData as T, formatSchemaVerificationIssues as _, createBroadcastChannels as a, createMigrator as b, isWorkerNotificationMessage as c, syncDbClientLockName as d, syncDbWorkerLockName as f, createSQLiteCrdtApplyFunction as g, createCrdtApplyFunction as h, createResetStateStore as i, isWorkerRequestMessage as l, createCrdtStorage as m, createIdbResetStore as n, isWorkerErrorResponseMessage as o, createCrdtSyncProducer as p, createReloadRequestHandler as r, isWorkerInitMessage as s, RESET_REQUEST_TTL_MS as t, isWorkerResponseMessage as u, verifySyncSchema as v, xxhash as w, SQLiteDbWrapper as x, createMigrations as y };
2027
1637
 
2028
- //# sourceMappingURL=reset-state-4Hn95CKG.js.map
1638
+ //# sourceMappingURL=reset-state-BVWEcT_z.js.map