@anfenn/dync 1.0.14 → 1.0.16

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/index.cjs CHANGED
@@ -53,6 +53,16 @@ function newLogger(base, min) {
53
53
  var SERVER_PK = "id";
54
54
  var LOCAL_PK = "_localId";
55
55
  var UPDATED_AT = "updated_at";
56
+ var ApiError = class extends Error {
57
+ isNetworkError;
58
+ cause;
59
+ constructor(message, isNetworkError2, cause) {
60
+ super(message);
61
+ this.name = "ApiError";
62
+ this.isNetworkError = isNetworkError2;
63
+ this.cause = cause;
64
+ }
65
+ };
56
66
  var SyncAction = /* @__PURE__ */ ((SyncAction2) => {
57
67
  SyncAction2["Create"] = "create";
58
68
  SyncAction2["Update"] = "update";
@@ -69,6 +79,36 @@ function createLocalId() {
69
79
  }
70
80
 
71
81
  // src/helpers.ts
82
+ function parseApiError(error) {
83
+ if (error instanceof ApiError) {
84
+ return error;
85
+ }
86
+ if (typeof error === "string") {
87
+ return new ApiError(error, false);
88
+ }
89
+ return new ApiError(error.message, isNetworkError(error), error);
90
+ }
91
+ function isNetworkError(error) {
92
+ const message = error.message?.toLowerCase() ?? "";
93
+ const name = error.name;
94
+ if (name === "TypeError" && (message.includes("failed to fetch") || message.includes("network request failed"))) {
95
+ return true;
96
+ }
97
+ const code = error.code;
98
+ if (code === "ERR_NETWORK" || code === "ECONNABORTED" || code === "ENOTFOUND" || code === "ECONNREFUSED") {
99
+ return true;
100
+ }
101
+ if (error.isAxiosError && error.response === void 0) {
102
+ return true;
103
+ }
104
+ if (name === "ApolloError" && error.networkError) {
105
+ return true;
106
+ }
107
+ if (message.includes("network error") || message.includes("networkerror")) {
108
+ return true;
109
+ }
110
+ return false;
111
+ }
72
112
  function sleep(ms, signal) {
73
113
  return new Promise((resolve) => {
74
114
  if (signal?.aborted) {
@@ -134,6 +174,7 @@ var DEFAULT_STATE = {
134
174
  var StateManager = class {
135
175
  persistedState;
136
176
  syncStatus;
177
+ apiError;
137
178
  listeners = /* @__PURE__ */ new Set();
138
179
  storageAdapter;
139
180
  hydrated = false;
@@ -174,12 +215,8 @@ var StateManager = class {
174
215
  this.persistedState = resolveNextState(this.persistedState, setterOrState);
175
216
  return this.persist();
176
217
  }
177
- /**
178
- * Set error in memory only without persisting to database.
179
- * Used when the database itself failed to open.
180
- */
181
- setErrorInMemory(error) {
182
- this.persistedState = { ...this.persistedState, error };
218
+ setApiError(error) {
219
+ this.apiError = error ? parseApiError(error) : void 0;
183
220
  this.emit();
184
221
  }
185
222
  addPendingChange(change) {
@@ -259,7 +296,7 @@ var StateManager = class {
259
296
  this.emit();
260
297
  }
261
298
  getSyncState() {
262
- return buildSyncState(this.persistedState, this.syncStatus, this.hydrated);
299
+ return buildSyncState(this.persistedState, this.syncStatus, this.hydrated, this.apiError);
263
300
  }
264
301
  subscribe(listener) {
265
302
  this.listeners.add(listener);
@@ -282,12 +319,13 @@ function resolveNextState(current, setterOrState) {
282
319
  }
283
320
  return { ...current, ...setterOrState };
284
321
  }
285
- function buildSyncState(state, status, hydrated) {
322
+ function buildSyncState(state, status, hydrated, apiError) {
286
323
  const persisted = clonePersistedState(state);
287
324
  const syncState = {
288
325
  ...persisted,
289
326
  status,
290
- hydrated
327
+ hydrated,
328
+ apiError
291
329
  };
292
330
  deleteKeyIfEmptyObject(syncState, "conflicts");
293
331
  return syncState;
@@ -1495,10 +1533,7 @@ var DyncBase = class {
1495
1533
  this.emitMutation({ type: "pull", tableName });
1496
1534
  }
1497
1535
  this.syncStatus = "idle";
1498
- await this.state.setState((syncState) => ({
1499
- ...syncState,
1500
- error: pullResult.error ?? firstPushSyncError
1501
- }));
1536
+ this.state.setApiError(pullResult.error ?? firstPushSyncError);
1502
1537
  if (this.mutationsDuringSync) {
1503
1538
  this.mutationsDuringSync = false;
1504
1539
  this.syncOnce().catch(() => {