@voltro/react-native 0.85.0 → 0.87.0

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.
@@ -0,0 +1,47 @@
1
+ //#region src/backgroundSync.ts
2
+ var e = {
3
+ status: "idle",
4
+ isForeground: !0,
5
+ lastSyncAt: void 0,
6
+ lastAttemptAt: void 0,
7
+ lastError: void 0,
8
+ successCount: 0,
9
+ failureCount: 0
10
+ }, t = (t, n) => {
11
+ switch (n.type) {
12
+ case "foreground": return t.isForeground ? t : {
13
+ ...t,
14
+ isForeground: !0
15
+ };
16
+ case "background": return t.isForeground ? {
17
+ ...t,
18
+ isForeground: !1
19
+ } : t;
20
+ case "syncStarted": return t.status === "syncing" ? t : {
21
+ ...t,
22
+ status: "syncing",
23
+ lastAttemptAt: n.at,
24
+ lastError: void 0
25
+ };
26
+ case "syncSucceeded": return {
27
+ ...t,
28
+ status: "success",
29
+ lastSyncAt: n.at,
30
+ lastError: void 0,
31
+ successCount: t.successCount + 1,
32
+ failureCount: 0
33
+ };
34
+ case "syncFailed": return {
35
+ ...t,
36
+ status: "error",
37
+ lastError: n.error,
38
+ failureCount: t.failureCount + 1
39
+ };
40
+ case "reset": return {
41
+ ...e,
42
+ isForeground: t.isForeground
43
+ };
44
+ }
45
+ }, n = (e, t, n, r = !1) => !(!n.enabled || e.status === "syncing" || !r && !e.isForeground || !r && n.intervalMs > 0 && e.lastAttemptAt !== void 0 && t - e.lastAttemptAt < n.intervalMs);
46
+ //#endregion
47
+ export { t as backgroundSyncReducer, e as initialBackgroundSyncState, n as shouldSync };
@@ -0,0 +1,31 @@
1
+ //#region src/backgroundSyncTask.ts
2
+ var e = "voltro-background-sync", t = (e) => {
3
+ let t = e.name ?? "voltro-background-sync", n = e.backgroundFetch.BackgroundFetchResult, r = async () => {
4
+ try {
5
+ let t = await e.run() ?? "no-data";
6
+ return e.onOutcome?.(t), t;
7
+ } catch (t) {
8
+ return e.onOutcome?.("failed", t), "failed";
9
+ }
10
+ }, i = (e) => e === "new-data" ? n.NewData : e === "no-data" ? n.NoData : n.Failed;
11
+ return e.taskManager.defineTask(t, async ({ error: t }) => t ? (e.onOutcome?.("failed", t), n.Failed) : i(await r())), {
12
+ name: t,
13
+ register: async () => {
14
+ e.taskManager.isTaskRegisteredAsync && await e.taskManager.isTaskRegisteredAsync(t) || await e.backgroundFetch.registerTaskAsync(t, {
15
+ minimumInterval: e.minimumIntervalSeconds ?? 900,
16
+ stopOnTerminate: !(e.survivesTermination ?? !0),
17
+ startOnBoot: e.startOnBoot ?? !0
18
+ });
19
+ },
20
+ unregister: () => e.backgroundFetch.unregisterTaskAsync(t),
21
+ availability: async () => {
22
+ let t = e.backgroundFetch;
23
+ if (!t.getStatusAsync || !t.BackgroundFetchStatus) return "unknown";
24
+ let n = await t.getStatusAsync();
25
+ return n === t.BackgroundFetchStatus.Available ? "available" : n === t.BackgroundFetchStatus.Denied ? "denied" : n === t.BackgroundFetchStatus.Restricted ? "restricted" : "unknown";
26
+ },
27
+ runNow: r
28
+ };
29
+ };
30
+ //#endregion
31
+ export { e as DEFAULT_BACKGROUND_SYNC_TASK, t as defineBackgroundSyncTask };
@@ -0,0 +1,51 @@
1
+ import { browserOnlineSource as e, browserOnlineSource as t } from "@voltro/client";
2
+ import { useCallback as n, useEffect as r, useRef as i, useState as a } from "react";
3
+ //#region src/connection.tsx
4
+ var o = {
5
+ localFirst: !0,
6
+ optimistic: !0,
7
+ syncOnForeground: !0,
8
+ syncIntervalMs: 3e5,
9
+ showSyncStatus: !0,
10
+ retryBackoffMs: [
11
+ 1e3,
12
+ 5e3,
13
+ 15e3,
14
+ 6e4
15
+ ]
16
+ }, s = (e, t) => e ? t > 0 ? "degraded" : "connected" : "offline", c = (e) => {
17
+ let t = (e) => typeof e.isInternetReachable == "boolean" ? e.isInternetReachable : e.isConnected === !0, n = !0;
18
+ return {
19
+ read: () => n,
20
+ subscribe: (r) => {
21
+ let i = e.addEventListener((e) => {
22
+ n = t(e), r(n);
23
+ });
24
+ return e.fetch?.().then((e) => {
25
+ n = t(e), r(n);
26
+ }).catch(() => {}), i;
27
+ }
28
+ };
29
+ }, l = (t) => {
30
+ let o = t?.onlineSource ?? e, [c, l] = a(() => o.read()), [u, d] = a(0), [f, p] = a(void 0), m = i(!0);
31
+ r(() => (m.current = !0, () => {
32
+ m.current = !1;
33
+ }), []), r(() => o.subscribe((e) => {
34
+ l(e), e && d(0);
35
+ }), [o]);
36
+ let h = n(() => {
37
+ m.current && (d((e) => e + 1), p(Date.now()));
38
+ }, []), g = n(() => {
39
+ m.current && d(0);
40
+ }, []);
41
+ return {
42
+ status: s(c, u),
43
+ online: c,
44
+ failureCount: u,
45
+ lastFailureAt: f,
46
+ reportFailure: h,
47
+ reportSuccess: g
48
+ };
49
+ };
50
+ //#endregion
51
+ export { t as browserOnlineSource, s as deriveConnectionStatus, c as netInfoOnlineSource, o as offlineFirstDefaults, l as useMobileConnectionStatus };
@@ -0,0 +1 @@
1
+ export { deepLinkHref, defineDeepLink, dispatchDeepLink, matchDeepLink, matchFirstDeepLink, runDeepLink } from "@voltro/client";
@@ -3,7 +3,7 @@ var e = [
3
3
  "ios",
4
4
  "android",
5
5
  "web"
6
- ], t = (t) => typeof t == "string" && e.includes(t), n = "_voltro_devices", r = "en", i = "UTC", a = () => {
6
+ ], t = (t) => typeof t == "string" && e.includes(t), n = "_voltro_push_devices", r = "en", i = "UTC", a = () => {
7
7
  if (typeof navigator < "u" && typeof navigator.language == "string") return navigator.language;
8
8
  }, o = () => {
9
9
  try {
@@ -25,4 +25,4 @@ var e = [
25
25
  };
26
26
  }, c = (e, t, n) => e(s(t, n));
27
27
  //#endregion
28
- export { s as a, c as i, e as n, t as r, n as t };
28
+ export { n as DEVICES_TABLE, e as DEVICE_PLATFORMS, t as isDevicePlatform, c as registerDevice, s as resolveDeviceRegistration };
package/dist/index.d.ts CHANGED
@@ -253,7 +253,7 @@ export declare const DEVICE_PLATFORMS: ReadonlyArray<DevicePlatform>;
253
253
  export declare type DevicePlatform = 'ios' | 'android' | 'web';
254
254
 
255
255
  /**
256
- * The normalised row, ready to upsert into `_voltro_devices`. `locale` and
256
+ * The normalised row, ready to upsert into `_voltro_push_devices`. `locale` and
257
257
  * `timezone` are resolved (never `undefined`); `registeredAt` is the moment we
258
258
  * built this. `userId` / `tenantId` are NOT here on purpose — they are the
259
259
  * server's to stamp from the authenticated request, never trusted from the
@@ -297,7 +297,7 @@ export declare interface DeviceRegistrationInput {
297
297
  }
298
298
 
299
299
  /** The framework table name devices are stored in — shared with `./schema`. */
300
- export declare const DEVICES_TABLE = "_voltro_devices";
300
+ export declare const DEVICES_TABLE = "_voltro_push_devices";
301
301
 
302
302
  /**
303
303
  * The transport that actually persists a device. The app supplies it — usually
@@ -415,6 +415,7 @@ export declare interface MobileApiBinding {
415
415
  /** `ws(s)://host:port/ws`. On a device this is NOT localhost — see
416
416
  * {@link resolveDevWsUrl}. */
417
417
  readonly wsUrl: string;
418
+ readonly roleEndpoints?: unknown;
418
419
  readonly headers?: ResolvableHeaders | undefined;
419
420
  readonly recovery?: MountedApi['recovery'];
420
421
  /** Durable local mirror of this api's subscriptions, resolved per
@@ -532,7 +533,7 @@ export { OnlineSource }
532
533
  * )
533
534
  * ```
534
535
  *
535
- * Idempotent by construction: the `_voltro_devices` unique key is
536
+ * Idempotent by construction: the `_voltro_push_devices` unique key is
536
537
  * `(platform, token)`, so calling this again with the same token updates the
537
538
  * existing row (locale/timezone/lastSeen) instead of inserting a duplicate. A
538
539
  * ROTATED token is a new registration; reaping the stale one is the sender
@@ -617,8 +618,10 @@ export declare interface SqliteDatabaseLike {
617
618
  *
618
619
  * `reconnect()` on the returned handle forces a fresh socket for every api —
619
620
  * call it after a sign-in or a tenant switch so the connection re-resolves who
620
- * it is. The supervisor blanks caches across that swap on purpose: the next
621
- * subject may be entitled to less than the previous one.
621
+ * it is. Its promise resolves once every api runs on the rebuilt socket; await
622
+ * it before calling as the new subject. The supervisor blanks caches across
623
+ * that swap on purpose: the next subject may be entitled to less than the
624
+ * previous one.
622
625
  */
623
626
  export declare const startMobileApis: (options: StartMobileApisOptions) => SupervisorHandle;
624
627
 
package/dist/index.js CHANGED
@@ -1,419 +1,11 @@
1
- import { a as e, i as t, n, r, t as i } from "./devices-BjXAU-8I.js";
2
- import { browserOnlineSource as a, browserOnlineSource as o, buildApiRuntime as s, deepLinkHref as c, defineDeepLink as l, definePlatform as u, dispatchDeepLink as d, matchDeepLink as f, matchFirstDeepLink as p, recoveryCoordinatorFor as m, runDeepLink as h, startApiSupervisor as g } from "@voltro/client";
3
- import { useCallback as _, useEffect as v, useReducer as y, useRef as b, useState as x } from "react";
4
- //#region src/backgroundSync.ts
5
- var S = {
6
- status: "idle",
7
- isForeground: !0,
8
- lastSyncAt: void 0,
9
- lastAttemptAt: void 0,
10
- lastError: void 0,
11
- successCount: 0,
12
- failureCount: 0
13
- }, C = (e, t) => {
14
- switch (t.type) {
15
- case "foreground": return e.isForeground ? e : {
16
- ...e,
17
- isForeground: !0
18
- };
19
- case "background": return e.isForeground ? {
20
- ...e,
21
- isForeground: !1
22
- } : e;
23
- case "syncStarted": return e.status === "syncing" ? e : {
24
- ...e,
25
- status: "syncing",
26
- lastAttemptAt: t.at,
27
- lastError: void 0
28
- };
29
- case "syncSucceeded": return {
30
- ...e,
31
- status: "success",
32
- lastSyncAt: t.at,
33
- lastError: void 0,
34
- successCount: e.successCount + 1,
35
- failureCount: 0
36
- };
37
- case "syncFailed": return {
38
- ...e,
39
- status: "error",
40
- lastError: t.error,
41
- failureCount: e.failureCount + 1
42
- };
43
- case "reset": return {
44
- ...S,
45
- isForeground: e.isForeground
46
- };
47
- }
48
- }, w = (e, t, n, r = !1) => !(!n.enabled || e.status === "syncing" || !r && !e.isForeground || !r && n.intervalMs > 0 && e.lastAttemptAt !== void 0 && t - e.lastAttemptAt < n.intervalMs), T = (e, t) => {
49
- if (typeof document > "u" || typeof window > "u") return () => {};
50
- let n = () => {
51
- document.visibilityState === "visible" ? e() : t();
52
- };
53
- return document.addEventListener("visibilitychange", n), window.addEventListener("focus", e), () => {
54
- document.removeEventListener("visibilitychange", n), window.removeEventListener("focus", e);
55
- };
56
- }, E = 3e5, D = (e, t = {}) => {
57
- let n = t.intervalMs ?? E, r = t.syncOnForeground ?? !0, i = t.enabled ?? !0, a = t.now ?? Date.now, o = t.subscribeForeground ?? T, [s, c] = y(C, S), l = b(e);
58
- l.current = e;
59
- let u = b(s);
60
- u.current = s;
61
- let d = b(!0), f = _((e) => {
62
- w(u.current, a(), {
63
- intervalMs: n,
64
- enabled: i
65
- }, e) && (c({
66
- type: "syncStarted",
67
- at: a()
68
- }), Promise.resolve().then(() => l.current()).then(() => {
69
- d.current && c({
70
- type: "syncSucceeded",
71
- at: a()
72
- });
73
- }).catch((e) => {
74
- d.current && c({
75
- type: "syncFailed",
76
- at: a(),
77
- error: e instanceof Error ? e.message : String(e)
78
- });
79
- }));
80
- }, [
81
- i,
82
- n,
83
- a
84
- ]);
85
- v(() => (d.current = !0, () => {
86
- d.current = !1;
87
- }), []), v(() => o(() => {
88
- c({ type: "foreground" }), r && f(!0);
89
- }, () => c({ type: "background" })), [
90
- o,
91
- r,
92
- f
93
- ]), v(() => {
94
- if (!i || n <= 0) return;
95
- let e = setInterval(() => f(!1), n);
96
- return () => clearInterval(e);
97
- }, [
98
- i,
99
- n,
100
- f
101
- ]);
102
- let p = _(() => f(!0), [f]);
103
- return {
104
- ...s,
105
- sync: p
106
- };
107
- }, O = {
108
- localFirst: !0,
109
- optimistic: !0,
110
- syncOnForeground: !0,
111
- syncIntervalMs: 3e5,
112
- showSyncStatus: !0,
113
- retryBackoffMs: [
114
- 1e3,
115
- 5e3,
116
- 15e3,
117
- 6e4
118
- ]
119
- }, k = (e, t) => e ? t > 0 ? "degraded" : "connected" : "offline", A = (e) => {
120
- let t = (e) => typeof e.isInternetReachable == "boolean" ? e.isInternetReachable : e.isConnected === !0, n = !0;
121
- return {
122
- read: () => n,
123
- subscribe: (r) => {
124
- let i = e.addEventListener((e) => {
125
- n = t(e), r(n);
126
- });
127
- return e.fetch?.().then((e) => {
128
- n = t(e), r(n);
129
- }).catch(() => {}), i;
130
- }
131
- };
132
- }, j = (e) => {
133
- let t = e?.onlineSource ?? o, [n, r] = x(() => t.read()), [i, a] = x(0), [s, c] = x(void 0), l = b(!0);
134
- v(() => (l.current = !0, () => {
135
- l.current = !1;
136
- }), []), v(() => t.subscribe((e) => {
137
- r(e), e && a(0);
138
- }), [t]);
139
- let u = _(() => {
140
- l.current && (a((e) => e + 1), c(Date.now()));
141
- }, []), d = _(() => {
142
- l.current && a(0);
143
- }, []);
144
- return {
145
- status: k(n, i),
146
- online: n,
147
- failureCount: i,
148
- lastFailureAt: s,
149
- reportFailure: u,
150
- reportSuccess: d
151
- };
152
- }, M = (e) => {
153
- let { storage: t, keys: n } = e, r = e.onError ?? ((e, t) => {
154
- console.warn(`[voltro] persisting '${e}' failed`, t);
155
- }), i = /* @__PURE__ */ new Map(), a = !1, o = null, s = /* @__PURE__ */ new Map(), c = null, l = async () => {
156
- for (; s.size > 0;) {
157
- let [e, n] = s.entries().next().value;
158
- s.delete(e);
159
- try {
160
- n === null ? await t.removeItem(e) : await t.setItem(e, n);
161
- } catch (t) {
162
- r(e, t);
163
- }
164
- }
165
- }, u = () => {
166
- c === null && (c = Promise.resolve().then(l).finally(() => {
167
- c = null;
168
- }));
169
- }, d = async (e) => {
170
- if (e.length === 0) return;
171
- if (t.multiGet) {
172
- let n = await t.multiGet(e);
173
- for (let [e, t] of n) t === null ? i.delete(e) : i.set(e, t);
174
- return;
175
- }
176
- let n = await Promise.all(e.map((e) => t.getItem(e)));
177
- e.forEach((e, t) => {
178
- let r = n[t];
179
- r == null ? i.delete(e) : i.set(e, r);
180
- });
181
- }, f = () => {
182
- if (o !== null) return o;
183
- let e = (async () => {
184
- let e;
185
- if (n !== void 0) e = n;
186
- else if (t.getAllKeys) e = await t.getAllKeys();
187
- else throw Error("createAsyncStoragePersistence: the storage has no getAllKeys(), so the keys to hydrate cannot be discovered. Pass an explicit `keys: [...]` listing the persisted stores' keys.");
188
- await d(e), a = !0;
189
- })();
190
- return o = e, e.finally(() => {
191
- o = null;
192
- });
193
- }, p = {
194
- getItem: (e) => i.get(e) ?? null,
195
- setItem: (e, t) => {
196
- i.set(e, t), s.set(e, t), u();
197
- },
198
- removeItem: (e) => {
199
- i.delete(e), s.set(e, null), u();
200
- }
201
- };
202
- return {
203
- hydrate: f,
204
- hydrated: () => a,
205
- provider: () => p,
206
- flush: async () => {
207
- for (; c !== null || s.size > 0;) await (c ?? Promise.resolve()), c === null && s.size > 0 && u();
208
- },
209
- keys: () => [...i.keys()]
210
- };
211
- }, N = (e, t) => {
212
- let n = typeof t == "object" && !Array.isArray(t) ? void 0 : t, r = globalThis.WebSocket;
213
- if (r === void 0) throw Error("startMobileApis: no global WebSocket. React Native provides one; if you are running these bindings somewhere else, pass `webSocketConstructor`.");
214
- return n === void 0 ? new r(e) : new r(e, n);
215
- }, P = (e, t, n) => (r, i) => {
216
- let a = e(r, i);
217
- return a.addEventListener("open", () => t()), a.addEventListener("close", () => n("close")), a.addEventListener("error", () => n("error")), a;
218
- }, F = (e) => {
219
- let t = e.webSocketConstructor ?? N;
220
- return g({
221
- apis: e.apis.map((e) => ({
222
- name: e.name,
223
- group: e.group,
224
- descriptors: e.descriptors,
225
- wsUrl: e.wsUrl,
226
- ...e.headers === void 0 ? {} : { headers: e.headers },
227
- ...e.recovery === void 0 ? {} : { recovery: e.recovery },
228
- ...e.mirror === void 0 ? {} : { mirror: e.mirror }
229
- })),
230
- ...e.retryDelayMs === void 0 ? {} : { retryDelayMs: e.retryDelayMs },
231
- onChange: e.onChange,
232
- buildClient: async (e, n, r, i, a, o) => await s({
233
- name: e.name,
234
- generation: n,
235
- wsUrl: e.wsUrl,
236
- group: e.group,
237
- ...e.headers === void 0 ? {} : { headers: e.headers },
238
- ...e.mirror === void 0 ? {} : { mirror: e.mirror },
239
- descriptors: e.descriptors,
240
- ...a === void 0 ? {} : { errorBus: a },
241
- ...o === void 0 ? {} : { recovery: o },
242
- webSocketConstructor: P(t, r, i)
243
- })
244
- });
245
- }, I = (e, t, n = "/ws") => {
246
- let r = (e ?? "").split(":")[0];
247
- return r === void 0 || r === "" || r === "localhost" || r === "127.0.0.1" ? `ws://localhost:${t}${n}` : `ws://${r}:${t}${n}`;
248
- }, L = (e, t) => {
249
- let n = /* @__PURE__ */ new Map();
250
- for (let r of e) {
251
- let e = t.get(r.name);
252
- e !== void 0 && n.set(r.name, {
253
- runtime: e.runtime,
254
- cache: e.cache,
255
- client: e.client,
256
- descriptors: r.descriptors,
257
- inspectBaseUrl: r.wsUrl.replace(/^ws/, "http").replace(/\/ws$/, ""),
258
- errorBus: e.errorBus,
259
- recovery: e.recovery ?? m(e.errorBus, r.name, r.recovery)
260
- });
261
- }
262
- return n;
263
- }, R = (e) => e === "ios" ? "ios" : e === "android" ? "android" : e === "web" ? "web" : "unknown", z = (e) => e === "active" ? "active" : e === "background" ? "background" : "inactive", B = (e) => e === "granted" ? "granted" : e === "denied" ? "denied" : "prompt", V = (e) => ({
264
- kind: "keychain",
265
- get: (t) => e.getItemAsync(t),
266
- set: (t, n) => e.setItemAsync(t, n),
267
- delete: (t) => e.deleteItemAsync(t)
268
- }), H = (e) => ({
269
- read: () => z(e.currentState),
270
- subscribe: (t) => {
271
- let n = e.addEventListener("change", (e) => t(z(e)));
272
- return () => n.remove();
273
- }
274
- }), U = (e) => ({
275
- initialUrl: () => e.getInitialURL(),
276
- subscribe: (t) => {
277
- let n = e.addEventListener("url", ({ url: e }) => t(e));
278
- return () => n.remove();
279
- }
280
- }), W = (e, t) => ({
281
- permission: async () => B((await e.getPermissionsAsync()).status),
282
- requestPermission: async () => B((await e.requestPermissionsAsync()).status),
283
- ...e.getExpoPushTokenAsync === void 0 ? {} : { pushToken: async () => (await e.getExpoPushTokenAsync(t === void 0 ? void 0 : { projectId: t })).data },
284
- ...e.scheduleNotificationAsync === void 0 ? {} : { show: async (t) => {
285
- await e.scheduleNotificationAsync({
286
- content: {
287
- title: t.title,
288
- ...t.body === void 0 ? {} : { body: t.body },
289
- ...t.data === void 0 ? {} : { data: { ...t.data } }
290
- },
291
- trigger: null
292
- });
293
- } }
294
- }), G = (e) => ({
295
- check: async () => {
296
- let t = await e.checkForUpdateAsync();
297
- return t.isAvailable ? { version: t.manifest?.id ?? "available" } : null;
298
- },
299
- apply: async () => {
300
- await e.fetchUpdateAsync(), await e.reloadAsync();
301
- }
302
- }), K = (e) => ({
303
- available: async () => await e.hasHardwareAsync() && await e.isEnrolledAsync(),
304
- authenticate: async (t) => (await e.authenticateAsync({ promptMessage: t })).success
305
- }), q = async (e) => {
306
- let t = M({
307
- storage: e.storage,
308
- ...e.persistedKeys === void 0 ? {} : { keys: e.persistedKeys }
309
- });
310
- return await t.hydrate(), {
311
- adapter: u({
312
- platform: {
313
- kind: R(e.os),
314
- shell: "expo",
315
- installed: !0,
316
- ...e.appVersion === void 0 ? {} : { appVersion: e.appVersion },
317
- ...e.updates?.updateId ? { buildId: e.updates.updateId } : {}
318
- },
319
- webSocket: e.webSocket ?? N,
320
- storage: t.provider,
321
- secureStorage: V(e.secureStore),
322
- online: A(e.netInfo),
323
- lifecycle: H(e.appState),
324
- links: U(e.linking),
325
- ...e.notifications === void 0 ? {} : { notifications: W(e.notifications, e.expoProjectId) },
326
- ...e.updates === void 0 ? {} : { updates: G(e.updates) },
327
- ...e.localAuthentication === void 0 ? {} : { biometrics: K(e.localAuthentication) },
328
- clock: { now: () => Date.now() },
329
- ...e.extensions === void 0 ? {} : { extensions: e.extensions },
330
- ...e.capabilities === void 0 ? {} : { capabilities: e.capabilities }
331
- }),
332
- persistence: t
333
- };
334
- }, J = "\nCREATE TABLE IF NOT EXISTS voltro_crdt (key TEXT PRIMARY KEY NOT NULL, state BLOB NOT NULL);\nCREATE TABLE IF NOT EXISTS voltro_queue (id INTEGER PRIMARY KEY CHECK (id = 1), json TEXT NOT NULL);\nCREATE TABLE IF NOT EXISTS voltro_pins (key TEXT PRIMARY KEY NOT NULL);\nCREATE TABLE IF NOT EXISTS voltro_kv (key TEXT PRIMARY KEY NOT NULL, json TEXT NOT NULL);\n", Y = (e, t) => `${e}\u0001${t}`, X = (e) => {
335
- if (e instanceof Uint8Array) return new Uint8Array(e);
336
- if (ArrayBuffer.isView(e)) return new Uint8Array(e.buffer, e.byteOffset, e.byteLength).slice();
337
- if (e instanceof ArrayBuffer) return new Uint8Array(e.slice(0));
338
- throw Error("expo-sqlite persistence: CRDT state column is not a BLOB");
339
- }, Z = (e) => `${e.replace(/[\\%_]/g, (e) => `\\${e}`)}%`, Q = async (e) => {
340
- let t = async () => {
341
- await e.execAsync(J);
342
- };
343
- return await t(), {
344
- persistence: {
345
- kind: "expo-sqlite",
346
- loadCrdtState: async (t, n) => {
347
- let r = await e.getFirstAsync("SELECT state FROM voltro_crdt WHERE key = ?", [Y(t, n)]);
348
- return r === null ? void 0 : X(r.state);
349
- },
350
- saveCrdtState: async (t, n, r) => {
351
- await e.runAsync("INSERT OR REPLACE INTO voltro_crdt (key, state) VALUES (?, ?)", [Y(t, n), new Uint8Array(r)]);
352
- },
353
- loadQueue: async () => {
354
- let t = await e.getFirstAsync("SELECT json FROM voltro_queue WHERE id = 1");
355
- if (t === null) return [];
356
- try {
357
- return JSON.parse(t.json);
358
- } catch {
359
- return [];
360
- }
361
- },
362
- saveQueue: async (t) => {
363
- await e.runAsync("INSERT OR REPLACE INTO voltro_queue (id, json) VALUES (1, ?)", [JSON.stringify(t)]);
364
- },
365
- pin: async (t, n) => {
366
- await e.runAsync("INSERT OR IGNORE INTO voltro_pins (key) VALUES (?)", [Y(t, n)]);
367
- },
368
- isPinned: async (t, n) => await e.getFirstAsync("SELECT key FROM voltro_pins WHERE key = ?", [Y(t, n)]) !== null
369
- },
370
- kv: {
371
- kind: "expo-sqlite",
372
- get: async (t) => {
373
- let n = await e.getFirstAsync("SELECT json FROM voltro_kv WHERE key = ?", [t]);
374
- if (n !== null) try {
375
- return JSON.parse(n.json);
376
- } catch {
377
- return;
378
- }
379
- },
380
- put: async (t, n) => {
381
- await e.runAsync("INSERT OR REPLACE INTO voltro_kv (key, json) VALUES (?, ?)", [t, JSON.stringify(n)]);
382
- },
383
- del: async (t) => {
384
- await e.runAsync("DELETE FROM voltro_kv WHERE key = ?", [t]);
385
- },
386
- keysWithPrefix: async (t) => (await e.getAllAsync("SELECT key FROM voltro_kv WHERE key LIKE ? ESCAPE '\\'", [Z(t)])).map((e) => e.key)
387
- },
388
- migrate: t
389
- };
390
- }, $ = "voltro-background-sync", ee = (e) => {
391
- let t = e.name ?? "voltro-background-sync", n = e.backgroundFetch.BackgroundFetchResult, r = async () => {
392
- try {
393
- let t = await e.run() ?? "no-data";
394
- return e.onOutcome?.(t), t;
395
- } catch (t) {
396
- return e.onOutcome?.("failed", t), "failed";
397
- }
398
- }, i = (e) => e === "new-data" ? n.NewData : e === "no-data" ? n.NoData : n.Failed;
399
- return e.taskManager.defineTask(t, async ({ error: t }) => t ? (e.onOutcome?.("failed", t), n.Failed) : i(await r())), {
400
- name: t,
401
- register: async () => {
402
- e.taskManager.isTaskRegisteredAsync && await e.taskManager.isTaskRegisteredAsync(t) || await e.backgroundFetch.registerTaskAsync(t, {
403
- minimumInterval: e.minimumIntervalSeconds ?? 900,
404
- stopOnTerminate: !(e.survivesTermination ?? !0),
405
- startOnBoot: e.startOnBoot ?? !0
406
- });
407
- },
408
- unregister: () => e.backgroundFetch.unregisterTaskAsync(t),
409
- availability: async () => {
410
- let t = e.backgroundFetch;
411
- if (!t.getStatusAsync || !t.BackgroundFetchStatus) return "unknown";
412
- let n = await t.getStatusAsync();
413
- return n === t.BackgroundFetchStatus.Available ? "available" : n === t.BackgroundFetchStatus.Denied ? "denied" : n === t.BackgroundFetchStatus.Restricted ? "restricted" : "unknown";
414
- },
415
- runNow: r
416
- };
417
- };
418
- //#endregion
419
- export { $ as DEFAULT_BACKGROUND_SYNC_TASK, i as DEVICES_TABLE, n as DEVICE_PLATFORMS, H as appStateLifecycle, C as backgroundSyncReducer, a as browserOnlineSource, M as createAsyncStoragePersistence, q as createExpoPlatform, Q as createExpoSqliteLocalFirst, c as deepLinkHref, N as defaultWebSocketConstructor, ee as defineBackgroundSyncTask, l as defineDeepLink, k as deriveConnectionStatus, d as dispatchDeepLink, K as expoBiometrics, W as expoNotifications, V as expoSecureTokenStore, G as expoUpdates, S as initialBackgroundSyncState, r as isDevicePlatform, U as linkingDeepLinks, f as matchDeepLink, p as matchFirstDeepLink, A as netInfoOnlineSource, O as offlineFirstDefaults, t as registerDevice, I as resolveDevWsUrl, e as resolveDeviceRegistration, h as runDeepLink, w as shouldSync, F as startMobileApis, L as toApiHandles, D as useBackgroundSync, j as useMobileConnectionStatus, P as wireSocket };
1
+ import { DEVICES_TABLE as e, DEVICE_PLATFORMS as t, isDevicePlatform as n, registerDevice as r, resolveDeviceRegistration as i } from "./devices.js";
2
+ import { deepLinkHref as a, defineDeepLink as o, dispatchDeepLink as s, matchDeepLink as c, matchFirstDeepLink as l, runDeepLink as u } from "./deepLink.js";
3
+ import { backgroundSyncReducer as d, initialBackgroundSyncState as f, shouldSync as p } from "./backgroundSync.js";
4
+ import { useBackgroundSync as m } from "./useBackgroundSync.js";
5
+ import { browserOnlineSource as h, deriveConnectionStatus as g, netInfoOnlineSource as _, offlineFirstDefaults as v, useMobileConnectionStatus as y } from "./connection.js";
6
+ import { createAsyncStoragePersistence as b } from "./persistence.js";
7
+ import { defaultWebSocketConstructor as x, resolveDevWsUrl as S, startMobileApis as C, toApiHandles as w, wireSocket as T } from "./mobileRuntime.js";
8
+ import { appStateLifecycle as E, createExpoPlatform as D, expoBiometrics as O, expoNotifications as k, expoSecureTokenStore as A, expoUpdates as j, linkingDeepLinks as M } from "./platform.js";
9
+ import { createExpoSqliteLocalFirst as N } from "./sqlite.js";
10
+ import { DEFAULT_BACKGROUND_SYNC_TASK as P, defineBackgroundSyncTask as F } from "./backgroundSyncTask.js";
11
+ export { P as DEFAULT_BACKGROUND_SYNC_TASK, e as DEVICES_TABLE, t as DEVICE_PLATFORMS, E as appStateLifecycle, d as backgroundSyncReducer, h as browserOnlineSource, b as createAsyncStoragePersistence, D as createExpoPlatform, N as createExpoSqliteLocalFirst, a as deepLinkHref, x as defaultWebSocketConstructor, F as defineBackgroundSyncTask, o as defineDeepLink, g as deriveConnectionStatus, s as dispatchDeepLink, O as expoBiometrics, k as expoNotifications, A as expoSecureTokenStore, j as expoUpdates, f as initialBackgroundSyncState, n as isDevicePlatform, M as linkingDeepLinks, c as matchDeepLink, l as matchFirstDeepLink, _ as netInfoOnlineSource, v as offlineFirstDefaults, r as registerDevice, S as resolveDevWsUrl, i as resolveDeviceRegistration, u as runDeepLink, p as shouldSync, C as startMobileApis, w as toApiHandles, m as useBackgroundSync, y as useMobileConnectionStatus, T as wireSocket };