@anfenn/dync 1.0.15 → 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.
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Dync
3
- } from "../chunk-I4L3W4PX.js";
3
+ } from "../chunk-NJF2KCLA.js";
4
4
  import "../chunk-SQB6E7V2.js";
5
5
 
6
6
  // src/react/useDync.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anfenn/dync",
3
- "version": "1.0.15",
3
+ "version": "1.0.16",
4
4
  "private": false,
5
5
  "description": "Write once, run IndexedDB & SQLite with sync anywhere - React, React Native, Expo, Capacitor, Electron & Node.js",
6
6
  "keywords": [
@@ -1,15 +1,5 @@
1
- import { deleteKeyIfEmptyObject, omitFields } from '../helpers';
2
- import {
3
- LOCAL_PK,
4
- UPDATED_AT,
5
- SyncAction,
6
- ApiError,
7
- parseApiError,
8
- type PendingChange,
9
- type PersistedSyncState,
10
- type SyncState,
11
- type SyncStatus,
12
- } from '../types';
1
+ import { deleteKeyIfEmptyObject, omitFields, parseApiError } from '../helpers';
2
+ import { LOCAL_PK, UPDATED_AT, SyncAction, ApiError, type PendingChange, type PersistedSyncState, type SyncState, type SyncStatus } from '../types';
13
3
  import type { StorageAdapter } from '../storage/types';
14
4
 
15
5
  const LOCAL_ONLY_SYNC_FIELDS = [LOCAL_PK, UPDATED_AT];
package/src/helpers.ts CHANGED
@@ -1,8 +1,57 @@
1
- import { SyncAction } from './types';
1
+ import { ApiError, SyncAction } from './types';
2
2
  import { createLocalId } from './createLocalId';
3
3
 
4
4
  export { createLocalId };
5
5
 
6
+ export function parseApiError(error: any): ApiError {
7
+ if (error instanceof ApiError) {
8
+ return error;
9
+ }
10
+
11
+ if (typeof error === 'string') {
12
+ return new ApiError(error, false);
13
+ }
14
+
15
+ return new ApiError(error.message, isNetworkError(error), error);
16
+ }
17
+
18
+ /**
19
+ * Detects if an error is a network-level failure from common HTTP libraries.
20
+ * Supports: fetch, axios, Apollo GraphQL, and generic network errors.
21
+ */
22
+ function isNetworkError(error: any): boolean {
23
+ const message = error.message?.toLowerCase() ?? '';
24
+ const name = error.name;
25
+
26
+ // fetch: throws TypeError on network failure
27
+ if (name === 'TypeError' && (message.includes('failed to fetch') || message.includes('network request failed'))) {
28
+ return true;
29
+ }
30
+
31
+ // axios: sets error.code for network issues
32
+ const code = error.code;
33
+ if (code === 'ERR_NETWORK' || code === 'ECONNABORTED' || code === 'ENOTFOUND' || code === 'ECONNREFUSED') {
34
+ return true;
35
+ }
36
+
37
+ // axios: no response means request never reached server
38
+ if (error.isAxiosError && error.response === undefined) {
39
+ return true;
40
+ }
41
+
42
+ // Apollo GraphQL: network error wrapper
43
+ if (name === 'ApolloError' && error.networkError) {
44
+ return true;
45
+ }
46
+
47
+ // Generic network error messages
48
+ if (message.includes('network error') || message.includes('networkerror')) {
49
+ return true;
50
+ }
51
+
52
+ return false;
53
+ }
54
+
6
55
  export function sleep(ms: number, signal?: AbortSignal): Promise<void> {
7
56
  return new Promise((resolve) => {
8
57
  if (signal?.aborted) {
package/src/types.ts CHANGED
@@ -17,57 +17,6 @@ export class ApiError extends Error {
17
17
  }
18
18
  }
19
19
 
20
- /**
21
- * Detects if an error is a network-level failure from common HTTP libraries.
22
- * Supports: fetch, axios, Apollo GraphQL, and generic network errors.
23
- */
24
- function isNetworkError(error: Error): boolean {
25
- const message = error.message.toLowerCase();
26
- const name = error.name;
27
-
28
- // fetch: throws TypeError on network failure
29
- if (name === 'TypeError' && (message.includes('failed to fetch') || message.includes('network request failed'))) {
30
- return true;
31
- }
32
-
33
- // axios: sets error.code for network issues
34
- const code = (error as any).code;
35
- if (code === 'ERR_NETWORK' || code === 'ECONNABORTED' || code === 'ENOTFOUND' || code === 'ECONNREFUSED') {
36
- return true;
37
- }
38
-
39
- // axios: no response means request never reached server
40
- if ((error as any).isAxiosError && (error as any).response === undefined) {
41
- return true;
42
- }
43
-
44
- // Apollo GraphQL: network error wrapper
45
- if (name === 'ApolloError' && (error as any).networkError) {
46
- return true;
47
- }
48
-
49
- // Generic network error messages
50
- if (message.includes('network error') || message.includes('networkerror')) {
51
- return true;
52
- }
53
-
54
- return false;
55
- }
56
-
57
- export function parseApiError(error: unknown): ApiError {
58
- if (error instanceof ApiError) {
59
- return error;
60
- }
61
-
62
- if (error instanceof Error) {
63
- return new ApiError(error.message, isNetworkError(error), error);
64
- }
65
-
66
- // Non-Error thrown (string, object, etc.)
67
- const message = String(error);
68
- return new ApiError(message, false);
69
- }
70
-
71
20
  export interface SyncedRecord {
72
21
  _localId: string;
73
22
  id?: any;