local-lite 0.0.5 → 0.0.7
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/adapters/local/better-sqlite3.d.ts +5 -1
- package/dist/adapters/local/better-sqlite3.js +35 -14
- package/dist/adapters/local/expo-sqlite.d.ts +11 -2
- package/dist/adapters/local/expo-sqlite.js +37 -20
- package/dist/adapters/local/index.d.ts +2 -0
- package/dist/adapters/local/libsql.d.ts +1 -0
- package/dist/adapters/local/libsql.js +1 -0
- package/dist/adapters/local/node-sqlite.d.ts +5 -1
- package/dist/adapters/local/node-sqlite.js +30 -12
- package/dist/adapters/local/op-sqlite.d.ts +1 -0
- package/dist/adapters/local/op-sqlite.js +1 -0
- package/dist/adapters/local/sql-js.d.ts +1 -0
- package/dist/adapters/local/sql-js.js +1 -0
- package/dist/adapters/remote/firestore.js +39 -32
- package/dist/adapters/remote/supabase.d.ts +5 -0
- package/dist/adapters/remote/supabase.js +192 -85
- package/dist/core/client.d.ts +1 -9
- package/dist/core/client.js +123 -105
- package/dist/core/outbox-store.d.ts +5 -0
- package/dist/core/outbox-store.js +29 -4
- package/dist/core/query-builder.d.ts +1 -0
- package/dist/core/query-builder.js +140 -71
- package/dist/core/query.js +28 -32
- package/dist/core/schema-manager.d.ts +4 -15
- package/dist/core/schema-manager.js +45 -135
- package/dist/core/sync-worker.js +7 -2
- package/dist/react/index.js +123 -57
- package/dist/react/status.d.ts +5 -0
- package/dist/react/status.js +20 -12
- package/dist/utils/uuid.d.ts +1 -1
- package/dist/utils/uuid.js +7 -16
- package/package.json +5 -4
package/dist/react/index.js
CHANGED
|
@@ -33,14 +33,14 @@ function areRowsEqual(a, b) {
|
|
|
33
33
|
if (aObj.id !== undefined && bObj.id !== undefined && aObj.id !== bObj.id) {
|
|
34
34
|
return false;
|
|
35
35
|
}
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
const aTs = aObj.updated_at ?? aObj.updatedAt;
|
|
37
|
+
const bTs = bObj.updated_at ?? bObj.updatedAt;
|
|
38
38
|
if (aObj.id !== undefined &&
|
|
39
39
|
bObj.id !== undefined &&
|
|
40
40
|
aObj.id === bObj.id &&
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
return
|
|
41
|
+
aTs !== undefined &&
|
|
42
|
+
bTs !== undefined) {
|
|
43
|
+
return aTs === bTs;
|
|
44
44
|
}
|
|
45
45
|
const aKeys = Object.keys(aObj);
|
|
46
46
|
const bKeys = Object.keys(bObj);
|
|
@@ -80,9 +80,83 @@ function areRowArraysEqual(a, b) {
|
|
|
80
80
|
}
|
|
81
81
|
return true;
|
|
82
82
|
}
|
|
83
|
-
|
|
84
|
-
|
|
83
|
+
const MAX_QUERY_CACHE_SIZE = 100;
|
|
84
|
+
class LRUQueryCache {
|
|
85
|
+
map = new Map();
|
|
86
|
+
get(key) {
|
|
87
|
+
const val = this.map.get(key);
|
|
88
|
+
if (val !== undefined) {
|
|
89
|
+
this.map.delete(key);
|
|
90
|
+
this.map.set(key, val);
|
|
91
|
+
}
|
|
92
|
+
return val;
|
|
93
|
+
}
|
|
94
|
+
set(key, val) {
|
|
95
|
+
if (this.map.has(key)) {
|
|
96
|
+
this.map.delete(key);
|
|
97
|
+
}
|
|
98
|
+
else if (this.map.size >= MAX_QUERY_CACHE_SIZE) {
|
|
99
|
+
const oldestKey = this.map.keys().next().value;
|
|
100
|
+
if (oldestKey !== undefined) {
|
|
101
|
+
this.map.delete(oldestKey);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
this.map.set(key, val);
|
|
105
|
+
}
|
|
106
|
+
has(key) {
|
|
107
|
+
return this.map.has(key);
|
|
108
|
+
}
|
|
109
|
+
delete(key) {
|
|
110
|
+
return this.map.delete(key);
|
|
111
|
+
}
|
|
112
|
+
clear() {
|
|
113
|
+
this.map.clear();
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
// In-memory query result cache capped with LRU eviction to prevent memory leaks
|
|
117
|
+
const queryCache = new LRUQueryCache();
|
|
85
118
|
const inFlightQueries = new Map();
|
|
119
|
+
const tableVersions = new WeakMap();
|
|
120
|
+
const clientIds = new WeakMap();
|
|
121
|
+
let nextClientId = 1;
|
|
122
|
+
function getClientScope(client) {
|
|
123
|
+
if (!client)
|
|
124
|
+
return 'no-client';
|
|
125
|
+
let id = clientIds.get(client);
|
|
126
|
+
if (!id) {
|
|
127
|
+
id = nextClientId++;
|
|
128
|
+
clientIds.set(client, id);
|
|
129
|
+
}
|
|
130
|
+
return 'client-' + id;
|
|
131
|
+
}
|
|
132
|
+
function getScopedCacheKey(client, key) {
|
|
133
|
+
return getClientScope(client) + ':' + key;
|
|
134
|
+
}
|
|
135
|
+
function getTableVersion(client, tableName) {
|
|
136
|
+
if (!client)
|
|
137
|
+
return 0;
|
|
138
|
+
return tableVersions.get(client)?.get(tableName) || 0;
|
|
139
|
+
}
|
|
140
|
+
function advanceTableVersion(client, tableName) {
|
|
141
|
+
if (!client)
|
|
142
|
+
return 0;
|
|
143
|
+
let versions = tableVersions.get(client);
|
|
144
|
+
if (!versions) {
|
|
145
|
+
versions = new Map();
|
|
146
|
+
tableVersions.set(client, versions);
|
|
147
|
+
}
|
|
148
|
+
const nextVersion = getTableVersion(client, tableName) + 1;
|
|
149
|
+
versions.set(tableName, nextVersion);
|
|
150
|
+
return nextVersion;
|
|
151
|
+
}
|
|
152
|
+
async function fetchDeduped(key, fn) {
|
|
153
|
+
let inFlight = inFlightQueries.get(key);
|
|
154
|
+
if (!inFlight) {
|
|
155
|
+
inFlight = fn().finally(() => inFlightQueries.delete(key));
|
|
156
|
+
inFlightQueries.set(key, inFlight);
|
|
157
|
+
}
|
|
158
|
+
return inFlight;
|
|
159
|
+
}
|
|
86
160
|
/**
|
|
87
161
|
* Clears the in-memory live query cache.
|
|
88
162
|
*/
|
|
@@ -114,7 +188,7 @@ function useLiveQuery(client, tableName, queryOrOptions) {
|
|
|
114
188
|
: typeof queryOrOptions === 'function'
|
|
115
189
|
? 'custom'
|
|
116
190
|
: 'all';
|
|
117
|
-
const cacheKey = `${tableName}:${queryKey}
|
|
191
|
+
const cacheKey = getScopedCacheKey(client, `${tableName}:${queryKey}`);
|
|
118
192
|
// Read-through cache: return instant cached rows on mount (0ms latency, zero flicker)
|
|
119
193
|
const [data, setData] = (0, react_1.useState)(() => queryCache.get(cacheKey) || []);
|
|
120
194
|
const [loading, setLoading] = (0, react_1.useState)(() => !queryCache.has(cacheKey));
|
|
@@ -123,28 +197,18 @@ function useLiveQuery(client, tableName, queryOrOptions) {
|
|
|
123
197
|
const refetch = (0, react_1.useCallback)(async () => {
|
|
124
198
|
if (!client || !client.db)
|
|
125
199
|
return;
|
|
200
|
+
const versionAtStart = getTableVersion(client, tableName);
|
|
126
201
|
try {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
}
|
|
138
|
-
else {
|
|
139
|
-
return await client.findMany(tableName);
|
|
140
|
-
}
|
|
141
|
-
})();
|
|
142
|
-
inFlightQueries.set(cacheKey, inFlight);
|
|
143
|
-
inFlight.finally(() => {
|
|
144
|
-
inFlightQueries.delete(cacheKey);
|
|
145
|
-
});
|
|
146
|
-
}
|
|
147
|
-
const res = (await inFlight) || [];
|
|
202
|
+
const res = await fetchDeduped(cacheKey + ':v' + versionAtStart, async () => {
|
|
203
|
+
const param = queryParamRef.current;
|
|
204
|
+
if (typeof param === 'function')
|
|
205
|
+
return (await param(client)) || [];
|
|
206
|
+
if (typeof param === 'object' && param !== null)
|
|
207
|
+
return await client.findMany(tableName, param);
|
|
208
|
+
return await client.findMany(tableName);
|
|
209
|
+
});
|
|
210
|
+
if (versionAtStart !== getTableVersion(client, tableName))
|
|
211
|
+
return;
|
|
148
212
|
queryCache.set(cacheKey, res);
|
|
149
213
|
setData((prev) => (areRowArraysEqual(prev, res) ? prev : res));
|
|
150
214
|
}
|
|
@@ -168,6 +232,7 @@ function useLiveQuery(client, tableName, queryOrOptions) {
|
|
|
168
232
|
return;
|
|
169
233
|
refetch();
|
|
170
234
|
const unsubscribe = client.events.on(tableName, () => {
|
|
235
|
+
advanceTableVersion(client, tableName);
|
|
171
236
|
scheduleRefetch();
|
|
172
237
|
});
|
|
173
238
|
return () => {
|
|
@@ -269,10 +334,11 @@ function useLiveQueries(client, queries) {
|
|
|
269
334
|
return JSON.stringify(queries, (_, val) => (typeof val === 'function' ? 'fn' : val));
|
|
270
335
|
}, [queries]);
|
|
271
336
|
const items = (0, react_1.useMemo)(() => normalizeMultiQueries(queries), [signature]);
|
|
337
|
+
const clientScope = getClientScope(client);
|
|
272
338
|
const [data, setData] = (0, react_1.useState)(() => {
|
|
273
339
|
const initial = {};
|
|
274
340
|
for (const item of items) {
|
|
275
|
-
const cached = queryCache.get(item.cacheKey);
|
|
341
|
+
const cached = queryCache.get(clientScope + ':' + item.cacheKey);
|
|
276
342
|
initial[item.key] = cached ? cached : [];
|
|
277
343
|
}
|
|
278
344
|
return initial;
|
|
@@ -281,7 +347,7 @@ function useLiveQueries(client, queries) {
|
|
|
281
347
|
if (items.length === 0)
|
|
282
348
|
return false;
|
|
283
349
|
for (const item of items) {
|
|
284
|
-
if (!queryCache.has(item.cacheKey))
|
|
350
|
+
if (!queryCache.has(clientScope + ':' + item.cacheKey))
|
|
285
351
|
return true;
|
|
286
352
|
}
|
|
287
353
|
return false;
|
|
@@ -291,27 +357,19 @@ function useLiveQueries(client, queries) {
|
|
|
291
357
|
return;
|
|
292
358
|
try {
|
|
293
359
|
const results = await Promise.all(items.map(async (item) => {
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
360
|
+
try {
|
|
361
|
+
const versionAtStart = getTableVersion(client, item.table);
|
|
362
|
+
const scopedCacheKey = clientScope + ':' + item.cacheKey;
|
|
363
|
+
const rows = await fetchDeduped(scopedCacheKey + ':v' + versionAtStart, async () => {
|
|
364
|
+
if (item.fn)
|
|
298
365
|
return (await item.fn(client)) || [];
|
|
299
|
-
|
|
300
|
-
else if (item.options) {
|
|
366
|
+
if (item.options)
|
|
301
367
|
return await client.findMany(item.table, item.options);
|
|
302
|
-
|
|
303
|
-
else {
|
|
304
|
-
return await client.findMany(item.table);
|
|
305
|
-
}
|
|
306
|
-
})();
|
|
307
|
-
inFlightQueries.set(item.cacheKey, inFlight);
|
|
308
|
-
inFlight.finally(() => {
|
|
309
|
-
inFlightQueries.delete(item.cacheKey);
|
|
368
|
+
return await client.findMany(item.table);
|
|
310
369
|
});
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
queryCache.set(item.cacheKey, rows);
|
|
370
|
+
if (versionAtStart !== getTableVersion(client, item.table))
|
|
371
|
+
return null;
|
|
372
|
+
queryCache.set(scopedCacheKey, rows);
|
|
315
373
|
return { key: item.key, rows };
|
|
316
374
|
}
|
|
317
375
|
catch (err) {
|
|
@@ -327,6 +385,8 @@ function useLiveQueries(client, queries) {
|
|
|
327
385
|
let changed = false;
|
|
328
386
|
const next = { ...prev };
|
|
329
387
|
for (const res of results) {
|
|
388
|
+
if (!res)
|
|
389
|
+
continue;
|
|
330
390
|
if (!areRowArraysEqual(prev[res.key], res.rows)) {
|
|
331
391
|
next[res.key] = res.rows;
|
|
332
392
|
changed = true;
|
|
@@ -346,6 +406,7 @@ function useLiveQueries(client, queries) {
|
|
|
346
406
|
refetch();
|
|
347
407
|
const tables = Array.from(new Set(items.map((i) => i.table).filter(Boolean)));
|
|
348
408
|
const unsubs = tables.map((tbl) => client.events.on(tbl, () => {
|
|
409
|
+
advanceTableVersion(client, tbl);
|
|
349
410
|
scheduleRefetch();
|
|
350
411
|
}));
|
|
351
412
|
return () => {
|
|
@@ -361,7 +422,7 @@ function useLiveQueries(client, queries) {
|
|
|
361
422
|
* Automatically re-renders only when this specific row or table changes.
|
|
362
423
|
*/
|
|
363
424
|
function useLiveRow(client, tableName, rowId, options) {
|
|
364
|
-
const cacheKey = `${tableName}:row:${rowId || 'null'}:${Boolean(options?.includeDeleted)}
|
|
425
|
+
const cacheKey = getScopedCacheKey(client, `${tableName}:row:${rowId || 'null'}:${Boolean(options?.includeDeleted)}`);
|
|
365
426
|
const [data, setData] = (0, react_1.useState)(() => {
|
|
366
427
|
if (!rowId)
|
|
367
428
|
return null;
|
|
@@ -376,13 +437,13 @@ function useLiveRow(client, tableName, rowId, options) {
|
|
|
376
437
|
return;
|
|
377
438
|
}
|
|
378
439
|
try {
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
440
|
+
const versionAtStart = getTableVersion(client, tableName);
|
|
441
|
+
const res = await fetchDeduped(cacheKey + ':v' + versionAtStart, async () => {
|
|
442
|
+
const r = await client.findById(tableName, rowId, options);
|
|
443
|
+
return r ? [r] : [];
|
|
444
|
+
});
|
|
445
|
+
if (versionAtStart !== getTableVersion(client, tableName))
|
|
446
|
+
return;
|
|
386
447
|
const row = res.length > 0 ? res[0] : null;
|
|
387
448
|
if (row) {
|
|
388
449
|
queryCache.set(cacheKey, [row]);
|
|
@@ -411,6 +472,7 @@ function useLiveRow(client, tableName, rowId, options) {
|
|
|
411
472
|
return;
|
|
412
473
|
refetch();
|
|
413
474
|
const unsubscribe = client.events.on(tableName, (event) => {
|
|
475
|
+
advanceTableVersion(client, tableName);
|
|
414
476
|
// Precise row-level invalidation: only refetch if event affects this rowId or is a bulk event
|
|
415
477
|
if (!event || !event.rowId || event.rowId === rowId || event.rowId === 'batch') {
|
|
416
478
|
scheduleRefetch();
|
|
@@ -442,6 +504,7 @@ function useLiveInfiniteQuery(client, tableName, options = {}) {
|
|
|
442
504
|
return;
|
|
443
505
|
if (isNextPage)
|
|
444
506
|
setIsFetchingNextPage(true);
|
|
507
|
+
const versionAtStart = getTableVersion(client, tableName);
|
|
445
508
|
try {
|
|
446
509
|
const currentOpts = optionsRef.current;
|
|
447
510
|
const fetchLimit = pages * pageSize + 1; // +1 to check for hasNextPage
|
|
@@ -450,6 +513,8 @@ function useLiveInfiniteQuery(client, tableName, options = {}) {
|
|
|
450
513
|
limit: fetchLimit,
|
|
451
514
|
offset: currentOpts.offset || 0,
|
|
452
515
|
});
|
|
516
|
+
if (versionAtStart !== getTableVersion(client, tableName))
|
|
517
|
+
return;
|
|
453
518
|
if (rows.length > pages * pageSize) {
|
|
454
519
|
setHasNextPage(true);
|
|
455
520
|
setData(rows.slice(0, pages * pageSize));
|
|
@@ -491,6 +556,7 @@ function useLiveInfiniteQuery(client, tableName, options = {}) {
|
|
|
491
556
|
return;
|
|
492
557
|
loadData(1, false);
|
|
493
558
|
const unsubscribe = client.events.on(tableName, () => {
|
|
559
|
+
advanceTableVersion(client, tableName);
|
|
494
560
|
scheduleRefetch();
|
|
495
561
|
});
|
|
496
562
|
return () => {
|
package/dist/react/status.d.ts
CHANGED
|
@@ -13,6 +13,11 @@ export interface UseSyncStatusResult {
|
|
|
13
13
|
/**
|
|
14
14
|
* Consolidated hook that tracks real-time sync connectivity, sync worker activity
|
|
15
15
|
* (pushing/pulling/syncing), and pending items in the local SQLite outbox queue.
|
|
16
|
+
*
|
|
17
|
+
* Performance notes:
|
|
18
|
+
* - sync:status events update isOnline/isPushing/isPulling/pendingCount in-place (no DB query).
|
|
19
|
+
* - The 50-record outbox fetch (pendingRecords) only runs on mount and on explicit refresh().
|
|
20
|
+
* - sync:push / sync:pull only trigger a lightweight pendingCount update via sync:status.
|
|
16
21
|
*/
|
|
17
22
|
export declare function useSyncStatus(client: LocalFirstClient | null | undefined): UseSyncStatusResult;
|
|
18
23
|
/**
|
package/dist/react/status.js
CHANGED
|
@@ -7,6 +7,11 @@ const runner_js_1 = require("./runner.js");
|
|
|
7
7
|
/**
|
|
8
8
|
* Consolidated hook that tracks real-time sync connectivity, sync worker activity
|
|
9
9
|
* (pushing/pulling/syncing), and pending items in the local SQLite outbox queue.
|
|
10
|
+
*
|
|
11
|
+
* Performance notes:
|
|
12
|
+
* - sync:status events update isOnline/isPushing/isPulling/pendingCount in-place (no DB query).
|
|
13
|
+
* - The 50-record outbox fetch (pendingRecords) only runs on mount and on explicit refresh().
|
|
14
|
+
* - sync:push / sync:pull only trigger a lightweight pendingCount update via sync:status.
|
|
10
15
|
*/
|
|
11
16
|
function useSyncStatus(client) {
|
|
12
17
|
const [isOnline, setIsOnline] = (0, react_1.useState)(true);
|
|
@@ -44,33 +49,36 @@ function useSyncStatus(client) {
|
|
|
44
49
|
// Ignored if client is stopping or tables initializing
|
|
45
50
|
}
|
|
46
51
|
}, [client]);
|
|
47
|
-
const scheduleRefresh = (0, runner_js_1.useCoalescedRunner)(refresh);
|
|
48
52
|
(0, react_1.useEffect)(() => {
|
|
49
53
|
if (!client || !client.db)
|
|
50
54
|
return;
|
|
55
|
+
// Initial full fetch on mount
|
|
51
56
|
refresh();
|
|
57
|
+
// sync:status fires after every push/pull cycle — update scalar fields directly,
|
|
58
|
+
// no DB round-trip needed. pendingCount comes from the event payload.
|
|
52
59
|
const unsubStatus = client.events.on('sync:status', (e) => {
|
|
53
60
|
setIsOnline(e.isOnline);
|
|
54
61
|
setIsPushing(e.isPushing);
|
|
55
62
|
setIsPulling(e.isPulling);
|
|
56
63
|
setPendingCount(e.pendingCount);
|
|
57
64
|
});
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
65
|
+
// Only refresh lastSyncedAt after a completed pull (lightweight meta query only)
|
|
66
|
+
const unsubPull = client.events.on('sync:pull', async (e) => {
|
|
67
|
+
if (e?.success) {
|
|
68
|
+
try {
|
|
69
|
+
const ts = await client.getLastSyncedAt().catch(() => null);
|
|
70
|
+
if (ts !== null && ts !== undefined) {
|
|
71
|
+
setLastSyncedAt(ts > 0 ? ts : null);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
catch { /* ignored */ }
|
|
75
|
+
}
|
|
66
76
|
});
|
|
67
77
|
return () => {
|
|
68
78
|
unsubStatus();
|
|
69
|
-
unsubOutbox();
|
|
70
|
-
unsubPush();
|
|
71
79
|
unsubPull();
|
|
72
80
|
};
|
|
73
|
-
}, [client, refresh
|
|
81
|
+
}, [client, refresh]);
|
|
74
82
|
return {
|
|
75
83
|
isOnline,
|
|
76
84
|
isPushing,
|
package/dist/utils/uuid.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { v4 as uuidv4 } from 'uuid';
|
|
2
2
|
/**
|
|
3
3
|
* Generates an RFC4122 v4 compliant UUID.
|
|
4
|
-
* Uses native crypto.randomUUID() when
|
|
4
|
+
* Uses native crypto.randomUUID() when available (detected once at import), with uuid.v4 fallback.
|
|
5
5
|
*/
|
|
6
6
|
export declare function generateUUID(): string;
|
|
7
7
|
export { uuidv4 };
|
package/dist/utils/uuid.js
CHANGED
|
@@ -4,24 +4,15 @@ exports.uuidv4 = void 0;
|
|
|
4
4
|
exports.generateUUID = generateUUID;
|
|
5
5
|
const uuid_1 = require("uuid");
|
|
6
6
|
Object.defineProperty(exports, "uuidv4", { enumerable: true, get: function () { return uuid_1.v4; } });
|
|
7
|
+
// Detect once at module load — avoids 3 typeof checks per UUID call
|
|
8
|
+
const nativeRandomUUID = typeof globalThis !== 'undefined' &&
|
|
9
|
+
typeof globalThis.crypto?.randomUUID === 'function'
|
|
10
|
+
? () => globalThis.crypto.randomUUID()
|
|
11
|
+
: null;
|
|
7
12
|
/**
|
|
8
13
|
* Generates an RFC4122 v4 compliant UUID.
|
|
9
|
-
* Uses native crypto.randomUUID() when
|
|
14
|
+
* Uses native crypto.randomUUID() when available (detected once at import), with uuid.v4 fallback.
|
|
10
15
|
*/
|
|
11
16
|
function generateUUID() {
|
|
12
|
-
|
|
13
|
-
if (typeof globalThis !== 'undefined' &&
|
|
14
|
-
globalThis.crypto &&
|
|
15
|
-
typeof globalThis.crypto.randomUUID === 'function') {
|
|
16
|
-
return globalThis.crypto.randomUUID();
|
|
17
|
-
}
|
|
18
|
-
return (0, uuid_1.v4)();
|
|
19
|
-
}
|
|
20
|
-
catch {
|
|
21
|
-
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
|
|
22
|
-
const r = (Math.random() * 16) | 0;
|
|
23
|
-
const v = c === 'x' ? r : (r & 0x3) | 0x8;
|
|
24
|
-
return v.toString(16);
|
|
25
|
-
});
|
|
26
|
-
}
|
|
17
|
+
return nativeRandomUUID ? nativeRandomUUID() : (0, uuid_1.v4)();
|
|
27
18
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "local-lite",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.7",
|
|
4
4
|
"description": "Never let a lost connection break a promise. Local-first sync that faithfully keeps data safe until you're back online.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -129,8 +129,9 @@
|
|
|
129
129
|
}
|
|
130
130
|
},
|
|
131
131
|
"devDependencies": {
|
|
132
|
-
"@supabase/supabase-js": "^2.118.0",
|
|
133
|
-
"@types/
|
|
132
|
+
"@supabase/supabase-js": "^2.118.0",
|
|
133
|
+
"@types/node": "^26.6.5",
|
|
134
|
+
"@types/react": "^19.3.0",
|
|
134
135
|
"@types/uuid": "^11.0.0",
|
|
135
136
|
"expo-sqlite": "^58.0.13",
|
|
136
137
|
"react": "^19.3.1",
|
|
@@ -140,4 +141,4 @@
|
|
|
140
141
|
"dependencies": {
|
|
141
142
|
"uuid": "^14.0.3"
|
|
142
143
|
}
|
|
143
|
-
}
|
|
144
|
+
}
|