@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.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- export { A as AfterRemoteAddCallback, a as ApiFunctions, d as BatchFirstLoadResult, b as BatchPushPayload, c as BatchPushResult, B as BatchSync, C as ConflictResolutionStrategy, D as Dync, F as FirstLoadProgress, e as FirstLoadProgressCallback, f as MissingRemoteRecordDuringUpdateCallback, M as MissingRemoteRecordStrategy, g as MutationEvent, S as SyncAction, h as SyncOptions, i as SyncState, j as SyncedRecord, T as TableMap } from './index.shared-C8JTfet7.cjs';
1
+ export { A as AfterRemoteAddCallback, a as ApiFunctions, d as BatchFirstLoadResult, b as BatchPushPayload, c as BatchPushResult, B as BatchSync, C as ConflictResolutionStrategy, D as Dync, F as FirstLoadProgress, e as FirstLoadProgressCallback, f as MissingRemoteRecordDuringUpdateCallback, M as MissingRemoteRecordStrategy, g as MutationEvent, S as SyncAction, h as SyncOptions, i as SyncState, j as SyncedRecord, T as TableMap } from './index.shared-DHuT0l_t.cjs';
2
2
  export { M as MemoryAdapter, a as MemoryQueryContext, S as SQLiteAdapter, b as SqliteQueryContext, c as StorageAdapter } from './dexie-BqktVP7s.cjs';
3
3
  export { S as SQLiteDatabaseDriver, b as SQLiteQueryResult, a as SQLiteRunResult } from './types-CSbIAfu2.cjs';
4
4
  import 'dexie';
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { A as AfterRemoteAddCallback, a as ApiFunctions, d as BatchFirstLoadResult, b as BatchPushPayload, c as BatchPushResult, B as BatchSync, C as ConflictResolutionStrategy, D as Dync, F as FirstLoadProgress, e as FirstLoadProgressCallback, f as MissingRemoteRecordDuringUpdateCallback, M as MissingRemoteRecordStrategy, g as MutationEvent, S as SyncAction, h as SyncOptions, i as SyncState, j as SyncedRecord, T as TableMap } from './index.shared-DajtjVW7.js';
1
+ export { A as AfterRemoteAddCallback, a as ApiFunctions, d as BatchFirstLoadResult, b as BatchPushPayload, c as BatchPushResult, B as BatchSync, C as ConflictResolutionStrategy, D as Dync, F as FirstLoadProgress, e as FirstLoadProgressCallback, f as MissingRemoteRecordDuringUpdateCallback, M as MissingRemoteRecordStrategy, g as MutationEvent, S as SyncAction, h as SyncOptions, i as SyncState, j as SyncedRecord, T as TableMap } from './index.shared-D-fB8Odd.js';
2
2
  export { M as MemoryAdapter, a as MemoryQueryContext, S as SQLiteAdapter, b as SqliteQueryContext, c as StorageAdapter } from './dexie-DRLMKLl5.js';
3
3
  export { S as SQLiteDatabaseDriver, b as SQLiteQueryResult, a as SQLiteRunResult } from './types-CSbIAfu2.js';
4
4
  import 'dexie';
package/dist/index.js CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  SqliteQueryContext,
7
7
  SyncAction,
8
8
  createLocalId
9
- } from "./chunk-6B5N26W3.js";
9
+ } from "./chunk-NJF2KCLA.js";
10
10
  import "./chunk-SQB6E7V2.js";
11
11
  export {
12
12
  Dync,
@@ -9,6 +9,11 @@ interface Logger {
9
9
  error: (...args: any[]) => void;
10
10
  }
11
11
 
12
+ declare class ApiError extends Error {
13
+ readonly isNetworkError: boolean;
14
+ readonly cause?: Error;
15
+ constructor(message: string, isNetworkError: boolean, cause?: Error);
16
+ }
12
17
  interface SyncedRecord {
13
18
  _localId: string;
14
19
  id?: any;
@@ -114,13 +119,13 @@ interface PersistedSyncState {
114
119
  firstLoadDone: boolean;
115
120
  pendingChanges: PendingChange[];
116
121
  lastPulled: Record<string, string>;
117
- error?: Error;
118
122
  conflicts?: Record<string, Conflict>;
119
123
  }
120
124
  type SyncStatus = 'disabled' | 'disabling' | 'idle' | 'syncing' | 'error';
121
125
  interface SyncState extends PersistedSyncState {
122
126
  status: SyncStatus;
123
127
  hydrated: boolean;
128
+ apiError?: ApiError;
124
129
  }
125
130
  declare enum SyncAction {
126
131
  Create = "create",
@@ -9,6 +9,11 @@ interface Logger {
9
9
  error: (...args: any[]) => void;
10
10
  }
11
11
 
12
+ declare class ApiError extends Error {
13
+ readonly isNetworkError: boolean;
14
+ readonly cause?: Error;
15
+ constructor(message: string, isNetworkError: boolean, cause?: Error);
16
+ }
12
17
  interface SyncedRecord {
13
18
  _localId: string;
14
19
  id?: any;
@@ -114,13 +119,13 @@ interface PersistedSyncState {
114
119
  firstLoadDone: boolean;
115
120
  pendingChanges: PendingChange[];
116
121
  lastPulled: Record<string, string>;
117
- error?: Error;
118
122
  conflicts?: Record<string, Conflict>;
119
123
  }
120
124
  type SyncStatus = 'disabled' | 'disabling' | 'idle' | 'syncing' | 'error';
121
125
  interface SyncState extends PersistedSyncState {
122
126
  status: SyncStatus;
123
127
  hydrated: boolean;
128
+ apiError?: ApiError;
124
129
  }
125
130
  declare enum SyncAction {
126
131
  Create = "create",
@@ -50,6 +50,16 @@ function newLogger(base, min) {
50
50
  var SERVER_PK = "id";
51
51
  var LOCAL_PK = "_localId";
52
52
  var UPDATED_AT = "updated_at";
53
+ var ApiError = class extends Error {
54
+ isNetworkError;
55
+ cause;
56
+ constructor(message, isNetworkError2, cause) {
57
+ super(message);
58
+ this.name = "ApiError";
59
+ this.isNetworkError = isNetworkError2;
60
+ this.cause = cause;
61
+ }
62
+ };
53
63
 
54
64
  // src/createLocalId.ts
55
65
  function createLocalId() {
@@ -60,6 +70,36 @@ function createLocalId() {
60
70
  }
61
71
 
62
72
  // src/helpers.ts
73
+ function parseApiError(error) {
74
+ if (error instanceof ApiError) {
75
+ return error;
76
+ }
77
+ if (typeof error === "string") {
78
+ return new ApiError(error, false);
79
+ }
80
+ return new ApiError(error.message, isNetworkError(error), error);
81
+ }
82
+ function isNetworkError(error) {
83
+ const message = error.message?.toLowerCase() ?? "";
84
+ const name = error.name;
85
+ if (name === "TypeError" && (message.includes("failed to fetch") || message.includes("network request failed"))) {
86
+ return true;
87
+ }
88
+ const code = error.code;
89
+ if (code === "ERR_NETWORK" || code === "ECONNABORTED" || code === "ENOTFOUND" || code === "ECONNREFUSED") {
90
+ return true;
91
+ }
92
+ if (error.isAxiosError && error.response === void 0) {
93
+ return true;
94
+ }
95
+ if (name === "ApolloError" && error.networkError) {
96
+ return true;
97
+ }
98
+ if (message.includes("network error") || message.includes("networkerror")) {
99
+ return true;
100
+ }
101
+ return false;
102
+ }
63
103
  function sleep(ms, signal) {
64
104
  return new Promise((resolve) => {
65
105
  if (signal?.aborted) {
@@ -125,6 +165,7 @@ var DEFAULT_STATE = {
125
165
  var StateManager = class {
126
166
  persistedState;
127
167
  syncStatus;
168
+ apiError;
128
169
  listeners = /* @__PURE__ */ new Set();
129
170
  storageAdapter;
130
171
  hydrated = false;
@@ -165,12 +206,8 @@ var StateManager = class {
165
206
  this.persistedState = resolveNextState(this.persistedState, setterOrState);
166
207
  return this.persist();
167
208
  }
168
- /**
169
- * Set error in memory only without persisting to database.
170
- * Used when the database itself failed to open.
171
- */
172
- setErrorInMemory(error) {
173
- this.persistedState = { ...this.persistedState, error };
209
+ setApiError(error) {
210
+ this.apiError = error ? parseApiError(error) : void 0;
174
211
  this.emit();
175
212
  }
176
213
  addPendingChange(change) {
@@ -250,7 +287,7 @@ var StateManager = class {
250
287
  this.emit();
251
288
  }
252
289
  getSyncState() {
253
- return buildSyncState(this.persistedState, this.syncStatus, this.hydrated);
290
+ return buildSyncState(this.persistedState, this.syncStatus, this.hydrated, this.apiError);
254
291
  }
255
292
  subscribe(listener) {
256
293
  this.listeners.add(listener);
@@ -273,12 +310,13 @@ function resolveNextState(current, setterOrState) {
273
310
  }
274
311
  return { ...current, ...setterOrState };
275
312
  }
276
- function buildSyncState(state, status, hydrated) {
313
+ function buildSyncState(state, status, hydrated, apiError) {
277
314
  const persisted = clonePersistedState(state);
278
315
  const syncState = {
279
316
  ...persisted,
280
317
  status,
281
- hydrated
318
+ hydrated,
319
+ apiError
282
320
  };
283
321
  deleteKeyIfEmptyObject(syncState, "conflicts");
284
322
  return syncState;
@@ -1486,10 +1524,7 @@ var DyncBase = class {
1486
1524
  this.emitMutation({ type: "pull", tableName });
1487
1525
  }
1488
1526
  this.syncStatus = "idle";
1489
- await this.state.setState((syncState) => ({
1490
- ...syncState,
1491
- error: pullResult.error ?? firstPushSyncError
1492
- }));
1527
+ this.state.setApiError(pullResult.error ?? firstPushSyncError);
1493
1528
  if (this.mutationsDuringSync) {
1494
1529
  this.mutationsDuringSync = false;
1495
1530
  this.syncOnce().catch(() => {