local-lite 0.0.2 → 0.0.3
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/README.md +3 -3
- package/dist/index.d.ts +1 -1
- package/dist/index.js +0 -1
- package/dist/react/index.d.ts +10 -12
- package/dist/react/index.js +52 -41
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@ Built around the **Transactional Outbox Pattern**, `local-lite` ensures instant,
|
|
|
13
13
|
* **[Configuration Reference](docs/configuration.md)** - Options for `defineSyncConfig()`, retries, and loggers
|
|
14
14
|
* **[Local SQLite Adapters](docs/adapters-local.md)** - Expo SQLite, OP-SQLite, better-sqlite3, node:sqlite, and LibSQL
|
|
15
15
|
* **[Remote Cloud Adapters](docs/adapters-remote.md)** - Supabase, Convex, Cloud Firestore, and custom adapters
|
|
16
|
-
* **[React & Expo Hooks](docs/react-hooks.md)** - `useLiveQuery()` and `
|
|
16
|
+
* **[React & Expo Hooks](docs/react-hooks.md)** - `useLiveQuery()` and `useSyncStatus()`
|
|
17
17
|
* **[Conflict Resolution](docs/conflict-resolution.md)** - LWW, Client-Wins, Server-Wins, and custom resolvers
|
|
18
18
|
|
|
19
19
|
---
|
|
@@ -147,7 +147,7 @@ export const client = await createSyncClient(syncConfig);
|
|
|
147
147
|
### 2. Use in React Native / Expo UI
|
|
148
148
|
|
|
149
149
|
```tsx
|
|
150
|
-
import { useLiveQuery,
|
|
150
|
+
import { useLiveQuery, useSyncStatus } from 'local-lite/react';
|
|
151
151
|
import { client } from './sync.config';
|
|
152
152
|
|
|
153
153
|
export function TodoScreen() {
|
|
@@ -157,7 +157,7 @@ export function TodoScreen() {
|
|
|
157
157
|
order: 'desc',
|
|
158
158
|
});
|
|
159
159
|
|
|
160
|
-
const { pendingCount } =
|
|
160
|
+
const { pendingCount, isOnline, isSyncing } = useSyncStatus(client);
|
|
161
161
|
|
|
162
162
|
const addTodo = async (title: string) => {
|
|
163
163
|
await client.insert('todos', {
|
package/dist/index.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ export * from './adapters/local/index.js';
|
|
|
12
12
|
export * from './adapters/remote/index.js';
|
|
13
13
|
export * from './adapters/network/index.js';
|
|
14
14
|
export * from './config/index.js';
|
|
15
|
-
export * from './react/index.js';
|
|
15
|
+
export type * from './react/index.js';
|
|
16
16
|
export * from './utils/uuid.js';
|
|
17
17
|
export * from './utils/sql.js';
|
|
18
18
|
export * from './utils/logger.js';
|
package/dist/index.js
CHANGED
|
@@ -28,7 +28,6 @@ __exportStar(require("./adapters/local/index.js"), exports);
|
|
|
28
28
|
__exportStar(require("./adapters/remote/index.js"), exports);
|
|
29
29
|
__exportStar(require("./adapters/network/index.js"), exports);
|
|
30
30
|
__exportStar(require("./config/index.js"), exports);
|
|
31
|
-
__exportStar(require("./react/index.js"), exports);
|
|
32
31
|
__exportStar(require("./utils/uuid.js"), exports);
|
|
33
32
|
__exportStar(require("./utils/sql.js"), exports);
|
|
34
33
|
__exportStar(require("./utils/logger.js"), exports);
|
package/dist/react/index.d.ts
CHANGED
|
@@ -24,23 +24,21 @@ export declare function useLiveQuery<T = any>(client: LocalFirstClient | null |
|
|
|
24
24
|
refetch: () => Promise<void>;
|
|
25
25
|
loading: boolean;
|
|
26
26
|
};
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
export interface UseSyncStatusResult {
|
|
28
|
+
isOnline: boolean;
|
|
29
|
+
isPushing: boolean;
|
|
30
|
+
isPulling: boolean;
|
|
31
|
+
isSyncing: boolean;
|
|
31
32
|
pendingCount: number;
|
|
32
33
|
pendingRecords: any[];
|
|
34
|
+
lastSyncedAt: number | null;
|
|
33
35
|
refresh: () => Promise<void>;
|
|
34
|
-
}
|
|
36
|
+
}
|
|
35
37
|
/**
|
|
36
|
-
*
|
|
38
|
+
* Consolidated hook that tracks real-time sync connectivity, sync worker activity
|
|
39
|
+
* (pushing/pulling/syncing), and pending items in the local SQLite outbox queue.
|
|
37
40
|
*/
|
|
38
|
-
export declare function useSyncStatus(client: LocalFirstClient | null | undefined):
|
|
39
|
-
isOnline: boolean;
|
|
40
|
-
isPushing: boolean;
|
|
41
|
-
isPulling: boolean;
|
|
42
|
-
pendingCount: number;
|
|
43
|
-
};
|
|
41
|
+
export declare function useSyncStatus(client: LocalFirstClient | null | undefined): UseSyncStatusResult;
|
|
44
42
|
/**
|
|
45
43
|
* Hook that provides real-time sync telemetry and engine performance metrics.
|
|
46
44
|
*/
|
package/dist/react/index.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.useLiveQuery = useLiveQuery;
|
|
4
|
-
exports.useOutboxStatus = useOutboxStatus;
|
|
5
4
|
exports.useSyncStatus = useSyncStatus;
|
|
6
5
|
exports.useSyncMetrics = useSyncMetrics;
|
|
7
6
|
const react_1 = require("react");
|
|
@@ -73,66 +72,78 @@ function useLiveQuery(client, tableName, queryOrOptions) {
|
|
|
73
72
|
return { data, refetch, loading };
|
|
74
73
|
}
|
|
75
74
|
/**
|
|
76
|
-
*
|
|
75
|
+
* Consolidated hook that tracks real-time sync connectivity, sync worker activity
|
|
76
|
+
* (pushing/pulling/syncing), and pending items in the local SQLite outbox queue.
|
|
77
77
|
*/
|
|
78
|
-
function
|
|
78
|
+
function useSyncStatus(client) {
|
|
79
|
+
const [isOnline, setIsOnline] = (0, react_1.useState)(true);
|
|
80
|
+
const [isPushing, setIsPushing] = (0, react_1.useState)(false);
|
|
81
|
+
const [isPulling, setIsPulling] = (0, react_1.useState)(false);
|
|
79
82
|
const [pendingCount, setPendingCount] = (0, react_1.useState)(0);
|
|
80
83
|
const [pendingRecords, setPendingRecords] = (0, react_1.useState)([]);
|
|
84
|
+
const [lastSyncedAt, setLastSyncedAt] = (0, react_1.useState)(null);
|
|
81
85
|
const refresh = (0, react_1.useCallback)(async () => {
|
|
82
86
|
if (!client || !client.db)
|
|
83
87
|
return;
|
|
84
88
|
try {
|
|
85
|
-
const records = await
|
|
86
|
-
|
|
87
|
-
|
|
89
|
+
const [metrics, records, lastSynced] = await Promise.all([
|
|
90
|
+
client.getMetrics().catch(() => null),
|
|
91
|
+
client.getOutboxRecords().catch(() => []),
|
|
92
|
+
client.getLastSyncedAt().catch(() => null),
|
|
93
|
+
]);
|
|
94
|
+
if (metrics) {
|
|
95
|
+
setIsOnline(metrics.isOnline);
|
|
96
|
+
setIsPushing(metrics.isPushing);
|
|
97
|
+
setIsPulling(metrics.isPulling);
|
|
98
|
+
}
|
|
99
|
+
if (records) {
|
|
100
|
+
setPendingRecords(records);
|
|
101
|
+
setPendingCount(records.filter((r) => r.status === 'PENDING').length);
|
|
102
|
+
}
|
|
103
|
+
if (lastSynced !== null && lastSynced !== undefined) {
|
|
104
|
+
setLastSyncedAt(lastSynced > 0 ? lastSynced : null);
|
|
105
|
+
}
|
|
88
106
|
}
|
|
89
107
|
catch {
|
|
90
|
-
// Ignored if
|
|
108
|
+
// Ignored if client is stopping or tables initializing
|
|
91
109
|
}
|
|
92
110
|
}, [client]);
|
|
93
111
|
(0, react_1.useEffect)(() => {
|
|
94
112
|
if (!client || !client.db)
|
|
95
113
|
return;
|
|
96
114
|
refresh();
|
|
97
|
-
const
|
|
115
|
+
const unsubStatus = client.events.on('sync:status', (e) => {
|
|
116
|
+
setIsOnline(e.isOnline);
|
|
117
|
+
setIsPushing(e.isPushing);
|
|
118
|
+
setIsPulling(e.isPulling);
|
|
119
|
+
setPendingCount(e.pendingCount);
|
|
120
|
+
});
|
|
121
|
+
const unsubOutbox = client.events.on('sync_outbox', () => {
|
|
98
122
|
refresh();
|
|
99
123
|
});
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
}
|
|
106
|
-
/**
|
|
107
|
-
* Hook that tracks real-time sync connectivity and sync worker activity (pushing/pulling).
|
|
108
|
-
*/
|
|
109
|
-
function useSyncStatus(client) {
|
|
110
|
-
const [status, setStatus] = (0, react_1.useState)({
|
|
111
|
-
isOnline: true,
|
|
112
|
-
isPushing: false,
|
|
113
|
-
isPulling: false,
|
|
114
|
-
pendingCount: 0,
|
|
115
|
-
});
|
|
116
|
-
(0, react_1.useEffect)(() => {
|
|
117
|
-
if (!client)
|
|
118
|
-
return;
|
|
119
|
-
// Fetch initial metrics
|
|
120
|
-
client.getMetrics().then((m) => {
|
|
121
|
-
setStatus({
|
|
122
|
-
isOnline: m.isOnline,
|
|
123
|
-
isPushing: m.isPushing,
|
|
124
|
-
isPulling: m.isPulling,
|
|
125
|
-
pendingCount: m.outboxPendingCount,
|
|
126
|
-
});
|
|
127
|
-
}).catch(() => { });
|
|
128
|
-
const unsubscribe = client.events.on('sync:status', (e) => {
|
|
129
|
-
setStatus(e);
|
|
124
|
+
const unsubPush = client.events.on('sync:push', () => {
|
|
125
|
+
refresh();
|
|
126
|
+
});
|
|
127
|
+
const unsubPull = client.events.on('sync:pull', () => {
|
|
128
|
+
refresh();
|
|
130
129
|
});
|
|
131
130
|
return () => {
|
|
132
|
-
|
|
131
|
+
unsubStatus();
|
|
132
|
+
unsubOutbox();
|
|
133
|
+
unsubPush();
|
|
134
|
+
unsubPull();
|
|
133
135
|
};
|
|
134
|
-
}, [client]);
|
|
135
|
-
return
|
|
136
|
+
}, [client, refresh]);
|
|
137
|
+
return {
|
|
138
|
+
isOnline,
|
|
139
|
+
isPushing,
|
|
140
|
+
isPulling,
|
|
141
|
+
isSyncing: isPushing || isPulling,
|
|
142
|
+
pendingCount,
|
|
143
|
+
pendingRecords,
|
|
144
|
+
lastSyncedAt,
|
|
145
|
+
refresh,
|
|
146
|
+
};
|
|
136
147
|
}
|
|
137
148
|
/**
|
|
138
149
|
* Hook that provides real-time sync telemetry and engine performance metrics.
|
package/package.json
CHANGED