@auxilium/datalynk-client 1.3.11 → 1.3.13
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/api.d.ts +2 -0
- package/dist/api.d.ts.map +1 -1
- package/dist/index.cjs +269 -53
- package/dist/index.mjs +269 -53
- package/dist/pwa.d.ts +1 -0
- package/dist/pwa.d.ts.map +1 -1
- package/dist/slice.d.ts +4 -0
- package/dist/slice.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/api.d.ts
CHANGED
package/dist/api.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoD,QAAQ,EAAQ,MAAM,gBAAgB,CAAC;AAClG,OAAO,EAAC,eAAe,EAAuB,MAAM,MAAM,CAAC;AAC3D,OAAO,EAAC,IAAI,EAAC,MAAM,QAAQ,CAAC;AAE5B,OAAO,EAAC,GAAG,EAAC,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAC,KAAK,EAAC,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAC,IAAI,EAAC,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAC,GAAG,EAAC,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAC,OAAO,EAAE,KAAK,EAAC,MAAM,SAAS,CAAC;AACvC,OAAO,EAAC,MAAM,EAAC,MAAM,UAAU,CAAC;AAChC,OAAO,EAAC,SAAS,EAAC,MAAM,aAAa,CAAC;AAEtC,OAAO,EAAC,MAAM,EAAC,MAAM,UAAU,CAAC;AAEhC,MAAM,MAAM,UAAU,GAAG;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,GAAG,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;CACZ,CAAA;AAED;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG;IACxB,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kCAAkC;IAClC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,6BAA6B;IAC7B,QAAQ,CAAC,EAAE,GAAG,CAAC;IACf,0BAA0B;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,gCAAgC;IAChC,aAAa,CAAC,EAAE,OAAO,GAAG,KAAK,GAAG,QAAQ,CAAC;IAC3C,uBAAuB;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2DAA2D;IAC3D,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,yBAAyB;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,wDAAwD;IACxD,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IACxB,6BAA6B;IAC7B,MAAM,CAAC,EAAE;QACR,6BAA6B;QAC7B,GAAG,CAAC,EAAE,YAAY,EAAE,CAAC;QACrB,oDAAoD;QACpD,GAAG,EAAE,MAAM,CAAC;QACZ,2BAA2B;QAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,2BAA2B;QAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;KAClB,CAAA;IACD,mCAAmC;IACnC,WAAW,CAAC,EAAE;QACb,+FAA+F;QAC/F,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,uHAAuH;QACvH,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,8DAA8D;QAC9D,SAAS,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
|
package/dist/index.cjs
CHANGED
|
@@ -2363,6 +2363,16 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
2363
2363
|
else if (/linux/i.test(userAgent)) return "linux";
|
|
2364
2364
|
else return "unknown";
|
|
2365
2365
|
}
|
|
2366
|
+
get browser() {
|
|
2367
|
+
const ua = (navigator.userAgent || "").toLowerCase();
|
|
2368
|
+
if (ua.includes("edg/")) return "edge";
|
|
2369
|
+
if (ua.includes("firefox") || ua.includes("fxios")) return "firefox";
|
|
2370
|
+
if (ua.includes("opr/") || ua.includes("opera")) return "opera";
|
|
2371
|
+
if (ua.includes("samsungbrowser")) return "samsung";
|
|
2372
|
+
if ((ua.includes("crios") || ua.includes("chrome")) && !ua.includes("edg/") && !ua.includes("opr/")) return "chrome";
|
|
2373
|
+
if (ua.includes("safari") && !ua.includes("chrome") && !ua.includes("crios") && !ua.includes("edg/") && !ua.includes("opr/")) return "safari";
|
|
2374
|
+
return "unknown";
|
|
2375
|
+
}
|
|
2366
2376
|
get pwa() {
|
|
2367
2377
|
return matchMedia("(display-mode: standalone)").matches || (navigator == null ? void 0 : navigator.standalone) || document.referrer.includes("android-app://");
|
|
2368
2378
|
}
|
|
@@ -2385,6 +2395,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
2385
2395
|
}
|
|
2386
2396
|
/** Setup the PWA */
|
|
2387
2397
|
async setup(manifest = {}) {
|
|
2398
|
+
var _a;
|
|
2388
2399
|
window.addEventListener("beforeinstallprompt", (e) => {
|
|
2389
2400
|
e.preventDefault();
|
|
2390
2401
|
this.nativeInstallPrompt = e;
|
|
@@ -2400,6 +2411,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
2400
2411
|
dismissExpiry: 7,
|
|
2401
2412
|
// Days
|
|
2402
2413
|
loginLink: false,
|
|
2414
|
+
hidePWAPrompt: false,
|
|
2403
2415
|
...this.api.options.pwaSettings
|
|
2404
2416
|
};
|
|
2405
2417
|
const meta = (key, name, value) => {
|
|
@@ -2433,9 +2445,9 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
2433
2445
|
link.href = `${base}/manifest?json=${encodeURIComponent(JSON.stringify(manifestObj))}`;
|
|
2434
2446
|
document.head.append(link);
|
|
2435
2447
|
}
|
|
2436
|
-
if (!this.headless && !this.iframe && !this.pwa && this.platform != "mac") setTimeout(() => {
|
|
2437
|
-
var
|
|
2438
|
-
if (((_b = (
|
|
2448
|
+
if (!((_a = this.api.options.pwaSettings) == null ? void 0 : _a.hidePWAPrompt) && !this.headless && !this.iframe && !this.pwa && this.platform != "mac") setTimeout(() => {
|
|
2449
|
+
var _a2, _b, _c, _d;
|
|
2450
|
+
if (((_b = (_a2 = this.api.options) == null ? void 0 : _a2.pwaSettings) == null ? void 0 : _b.dismissExpiry) === 0) localStorage.removeItem(`${this.api.options.name}:pwa`);
|
|
2439
2451
|
let dismissedDate = localStorage.getItem(`${this.api.options.name}:pwa`);
|
|
2440
2452
|
if (dismissedDate) dismissedDate = JSON.parse(dismissedDate);
|
|
2441
2453
|
if (!!dismissedDate && Date.now() > dismissedDate + ((_d = (_c = this.api.options) == null ? void 0 : _c.pwaSettings) == null ? void 0 : _d.dismissExpiry) * 6e4 * 60 * 24) return;
|
|
@@ -2444,8 +2456,47 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
2444
2456
|
}
|
|
2445
2457
|
/** Prompt user to install the app */
|
|
2446
2458
|
async prompt(platform) {
|
|
2459
|
+
var _a;
|
|
2460
|
+
if ((_a = this.api.options.pwaSettings) == null ? void 0 : _a.hidePWAPrompt) return;
|
|
2447
2461
|
if (document.querySelector(".pwa-prompt")) return;
|
|
2448
|
-
const
|
|
2462
|
+
const targetPlatform = platform || this.platform;
|
|
2463
|
+
const isAndroid = targetPlatform == "android";
|
|
2464
|
+
const isIOS = targetPlatform == "ios";
|
|
2465
|
+
const browser = this.browser;
|
|
2466
|
+
const browserLabel = browser == "edge" ? "Edge" : browser == "firefox" ? "Firefox" : browser == "safari" ? "Safari" : browser == "opera" ? "Opera" : browser == "samsung" ? "Samsung Internet" : browser == "chrome" ? "Chrome" : "your browser";
|
|
2467
|
+
const stepsHtml = this.nativeInstallPrompt ? `` : `
|
|
2468
|
+
<div class="pwa-steps">
|
|
2469
|
+
${isAndroid ? `
|
|
2470
|
+
<div style="text-align:left">
|
|
2471
|
+
<strong>Android (${browserLabel})</strong>
|
|
2472
|
+
<ol>
|
|
2473
|
+
<li>Open the browser menu (⋮) or look for an <strong>Install</strong> option.</li>
|
|
2474
|
+
<li>Select <strong>Install app</strong> or <strong>Add to Home screen</strong>, then confirm.</li>
|
|
2475
|
+
</ol>
|
|
2476
|
+
${browser == "firefox" ? `<div style="font-size:0.85rem;opacity:0.85;margin-top:0.25rem;">If you do not see an install option in Firefox, use <strong>Add to Home screen</strong>.</div>` : ``}
|
|
2477
|
+
</div>
|
|
2478
|
+
` : isIOS ? `
|
|
2479
|
+
<div style="text-align:left">
|
|
2480
|
+
<strong>iPhone / iPad (Safari)</strong>
|
|
2481
|
+
<ol>
|
|
2482
|
+
<li>Tap the <strong>Share</strong> button.</li>
|
|
2483
|
+
<li>Select <strong>Add to Home Screen</strong>, then confirm.</li>
|
|
2484
|
+
</ol>
|
|
2485
|
+
${browser != "safari" ? `<div style="font-size:0.85rem;opacity:0.85;margin-top:0.25rem;">If you are using ${browserLabel} on iOS and don’t see <strong>Add to Home Screen</strong>, open this page in <strong>Safari</strong>.</div>` : ``}
|
|
2486
|
+
</div>
|
|
2487
|
+
` : `
|
|
2488
|
+
<div style="text-align:left">
|
|
2489
|
+
<strong>Desktop (${browserLabel})</strong>
|
|
2490
|
+
<ol>
|
|
2491
|
+
<li>In <strong>Chrome</strong> or <strong>Edge</strong>, look for the <strong>Install</strong> icon in the address bar (or open the browser menu).</li>
|
|
2492
|
+
<li>Select <strong>Install</strong> / <strong>Install app</strong>, then confirm.</li>
|
|
2493
|
+
</ol>
|
|
2494
|
+
${browser == "safari" ? `<div style="font-size:0.85rem;opacity:0.85;margin-top:0.25rem;">In Safari on macOS, look for <strong>Add to Dock</strong> (or a similar web app option) in the File menu, if available.</div>` : ``}
|
|
2495
|
+
${browser == "firefox" ? `<div style="font-size:0.85rem;opacity:0.85;margin-top:0.25rem;">Firefox may not offer PWA installation. You can continue using the browser, or create a shortcut to this page.</div>` : ``}
|
|
2496
|
+
</div>
|
|
2497
|
+
`}
|
|
2498
|
+
</div>
|
|
2499
|
+
`;
|
|
2449
2500
|
let style = document.querySelector("style.pwa");
|
|
2450
2501
|
if (!style) {
|
|
2451
2502
|
style = document.createElement("style");
|
|
@@ -2538,31 +2589,19 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
2538
2589
|
<button class="pwa-prompt-close">×</button>
|
|
2539
2590
|
</div>
|
|
2540
2591
|
<div class="pwa-prompt-body">
|
|
2541
|
-
|
|
2592
|
+
<div style="margin-bottom:0.5rem;">
|
|
2593
|
+
This application was built with offline capabilities. For the best experience—including reliable offline use and full-screen access—we recommend installing it on your device.
|
|
2594
|
+
</div>
|
|
2595
|
+
${this.nativeInstallPrompt ? `<div style="font-size:0.9rem;opacity:0.9;">Select <strong>Install App</strong> below to continue.</div>` : `<div style="font-size:0.9rem;opacity:0.9;">Follow the steps below for your device and browser.</div>`}
|
|
2542
2596
|
</div>
|
|
2543
2597
|
<div class="pwa-prompt-actions">
|
|
2544
|
-
${this.nativeInstallPrompt ? `<button id="installPwaBtn">Install App</button>` :
|
|
2545
|
-
<table>
|
|
2546
|
-
<tr>
|
|
2547
|
-
<td style="width:40px;text-align:center">
|
|
2548
|
-
${android ? '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="black" style="transform: scale(1.5)"><path d="M480-160q-33 0-56.5-23.5T400-240q0-33 23.5-56.5T480-320q33 0 56.5 23.5T560-240q0 33-23.5 56.5T480-160Zm0-240q-33 0-56.5-23.5T400-480q0-33 23.5-56.5T480-560q33 0 56.5 23.5T560-480q0 33-23.5 56.5T480-400Zm0-240q-33 0-56.5-23.5T400-720q0-33 23.5-56.5T480-800q33 0 56.5 23.5T560-720q0 33-23.5 56.5T480-640Z"/></svg>' : '<svg viewBox="0 0 566 670" xmlns="http://www.w3.org/2000/svg" fill="#c33031" height="40px"><path d="M255 12c4-4 10-8 16-8s12 3 16 8l94 89c3 4 6 7 8 12 2 6 0 14-5 19-7 8-20 9-28 2l-7-7-57-60 2 54v276c0 12-10 22-22 22-12 1-24-10-23-22V110l1-43-60 65c-5 5-13 8-21 6a19 19 0 0 1-16-17c-1-7 2-13 7-18l95-91z" /><path d="M43 207c16-17 40-23 63-23h83v46h-79c-12 0-25 3-33 13-8 9-10 21-10 33v260c0 13 0 27 6 38 5 12 18 18 30 19l14 1h302c14 0 28 0 40-8 11-7 16-21 16-34V276c0-11-2-24-9-33-8-10-22-13-34-13h-78v-46h75c13 0 25 1 37 4 16 4 31 13 41 27 11 17 14 37 14 57v280c0 20-3 41-15 58a71 71 0 0 1-45 27c-11 2-23 3-34 3H109c-19-1-40-4-56-15-14-9-23-23-27-38-4-12-5-25-5-38V270c1-22 6-47 22-63z" /></svg>'}
|
|
2549
|
-
</td>
|
|
2550
|
-
<td>1) ${android ? "Open the dropdown menu" : 'Tap the "Share" button'}</td>
|
|
2551
|
-
</tr>
|
|
2552
|
-
<tr>
|
|
2553
|
-
<td style="width:40px;text-align:center">
|
|
2554
|
-
${android ? '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="black" style="transform: scale(-1.5, 1.5)"><path d="M280-40q-33 0-56.5-23.5T200-120v-720q0-33 23.5-56.5T280-920h280v80H280v40h280v80H280v480h400v-80h80v200q0 33-23.5 56.5T680-40H280Zm0-120v40h400v-40H280Zm440-240L520-600l56-56 104 104v-288h80v288l104-104 56 56-200 200ZM280-800v-40 40Zm0 640v40-40Z"/></svg>' : '<svg viewBox="0 0 578 584" xmlns="http://www.w3.org/2000/svg" fill="black" height="34px"><path d="M101 35l19-1h333c12 0 23 0 35 3 17 3 34 12 44 27 13 16 16 38 16 58v329c0 19 0 39-8 57a65 65 0 0 1-37 37c-18 7-38 7-57 7H130c-21 1-44 0-63-10-14-7-25-20-30-34-6-15-8-30-8-45V121c1-21 5-44 19-61 13-16 33-23 53-25m7 46c-10 1-19 6-24 14-7 8-9 20-9 31v334c0 12 2 25 10 34 9 10 23 12 35 12h336c14 1 30-3 38-15 6-9 8-20 8-31V125c0-12-2-24-10-33-9-9-22-12-35-12H121l-13 1z" /><path d="M271 161c9-11 31-10 38 4 3 5 3 11 3 17v87h88c7 0 16 1 21 7 6 6 7 14 6 22a21 21 0 0 1-10 14c-5 4-11 5-17 5h-88v82c0 7-1 15-6 20-10 10-29 10-37-2-3-6-4-13-4-19v-81h-87c-8-1-17-3-23-9-5-6-6-15-4-22a21 21 0 0 1 11-14c6-3 13-3 19-3h84v-88c0-7 1-14 6-20z" /></svg>'}
|
|
2555
|
-
</td>
|
|
2556
|
-
<td>2) Select "Add to Home Screen"</td>
|
|
2557
|
-
</tr>
|
|
2558
|
-
</table>
|
|
2559
|
-
`}
|
|
2598
|
+
${this.nativeInstallPrompt ? `<button id="installPwaBtn">Install App</button>` : stepsHtml}
|
|
2560
2599
|
</div>
|
|
2561
2600
|
`;
|
|
2562
2601
|
const closeBtn = prompt.querySelector(".pwa-prompt-close");
|
|
2563
2602
|
closeBtn.onclick = () => {
|
|
2564
|
-
var
|
|
2565
|
-
!!((
|
|
2603
|
+
var _a2;
|
|
2604
|
+
!!((_a2 = this.api.options.pwaSettings) == null ? void 0 : _a2.dismissExpiry) ? localStorage.setItem(`${this.api.options.name}:pwa`, Date.now().toString()) : localStorage.removeItem(`${this.api.options.name}:pwa`);
|
|
2566
2605
|
prompt.remove();
|
|
2567
2606
|
};
|
|
2568
2607
|
document.body.append(prompt);
|
|
@@ -3106,6 +3145,12 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
3106
3145
|
__publicField(this, "table");
|
|
3107
3146
|
__publicField(this, "info");
|
|
3108
3147
|
__publicField(this, "loaded", false);
|
|
3148
|
+
__publicField(this, "pushing", false);
|
|
3149
|
+
// NEW: prevent concurrent pushChanges() runs
|
|
3150
|
+
__publicField(this, "pushTimer", null);
|
|
3151
|
+
// NEW: debounce pushes when connection flaps
|
|
3152
|
+
__publicField(this, "pushBackoff", 0);
|
|
3153
|
+
// NEW: backoff when internet flaps
|
|
3109
3154
|
/** Cached slice data as an observable */
|
|
3110
3155
|
__publicField(this, "cache$", new BehaviorSubject([]));
|
|
3111
3156
|
/** Unsubscribe from changes, undefined if not subscribed */
|
|
@@ -3129,10 +3174,10 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
3129
3174
|
}));
|
|
3130
3175
|
});
|
|
3131
3176
|
this.sync();
|
|
3132
|
-
this.api.online$.subscribe(async (online) => {
|
|
3177
|
+
this.api.online$.pipe(distinctUntilChanged()).subscribe(async (online) => {
|
|
3133
3178
|
if (!online) return;
|
|
3134
3179
|
if (this.api.expired) await lastValueFrom(this.api.auth.user$.pipe(skip(1), takeWhile((u) => !u || this.api.expired, true)));
|
|
3135
|
-
this.
|
|
3180
|
+
this.schedulePushChanges();
|
|
3136
3181
|
});
|
|
3137
3182
|
} else {
|
|
3138
3183
|
this.loaded = true;
|
|
@@ -3151,10 +3196,17 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
3151
3196
|
var _a;
|
|
3152
3197
|
return (_a = this.api.database) == null ? void 0 : _a.includes(this.slice.toString());
|
|
3153
3198
|
}
|
|
3199
|
+
schedulePushChanges(delay = 750) {
|
|
3200
|
+
if (this.pushTimer) clearTimeout(this.pushTimer);
|
|
3201
|
+
this.pushTimer = setTimeout(() => this.pushChanges(), delay + this.pushBackoff);
|
|
3202
|
+
}
|
|
3154
3203
|
execWrapper(call) {
|
|
3155
3204
|
const onlineExec = call.exec.bind(call);
|
|
3156
3205
|
return async () => {
|
|
3157
|
-
|
|
3206
|
+
const offlineSupported = this.offlineEnabled && typeof navigator !== "undefined";
|
|
3207
|
+
const offlineNow = offlineSupported && !(navigator == null ? void 0 : navigator.onLine);
|
|
3208
|
+
const offlineSim = async () => {
|
|
3209
|
+
var _a, _b, _c;
|
|
3158
3210
|
const where = (row, condition) => {
|
|
3159
3211
|
if (Array.isArray(condition) ? !condition.length : condition == null) return true;
|
|
3160
3212
|
if (!Array.isArray(condition)) return condition;
|
|
@@ -3174,7 +3226,8 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
3174
3226
|
await sleepWhile(() => !this.loaded);
|
|
3175
3227
|
let request = call.raw, resp = {};
|
|
3176
3228
|
if (request["$/slice/delete"]) {
|
|
3177
|
-
const
|
|
3229
|
+
const req = request["$/slice/delete"];
|
|
3230
|
+
const found = this.cache.filter((r) => (r == null ? void 0 : r._sync) != "delete").filter((r) => where(r, req["where"])).map((r) => r.id);
|
|
3178
3231
|
this.cache = this.cache.map((r) => found.includes(r.id) ? { ...r, _sync: "delete" } : r);
|
|
3179
3232
|
resp = {
|
|
3180
3233
|
affected: found.length,
|
|
@@ -3183,18 +3236,49 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
3183
3236
|
tx: null
|
|
3184
3237
|
};
|
|
3185
3238
|
} else if (request["$/slice/report"]) {
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
if (
|
|
3190
|
-
|
|
3191
|
-
|
|
3239
|
+
const req = request["$/slice/report"];
|
|
3240
|
+
resp["rows"] = deepCopy(this.cache).filter((r) => (r == null ? void 0 : r._sync) != "delete").filter((r) => r && where(r, req["where"]));
|
|
3241
|
+
const order = req["order"];
|
|
3242
|
+
if (order == null ? void 0 : order.length) {
|
|
3243
|
+
const field = (_b = (_a = order[0]) == null ? void 0 : _a[1]) == null ? void 0 : _b[1];
|
|
3244
|
+
const desc = ((_c = order[0]) == null ? void 0 : _c[0]) == "$desc";
|
|
3245
|
+
if (field) resp["rows"] = resp["rows"].toSorted(sortByProp(field, desc));
|
|
3246
|
+
}
|
|
3247
|
+
const limit = req["limit"];
|
|
3248
|
+
if (typeof limit == "number") resp["rows"] = resp["rows"].slice(0, limit);
|
|
3249
|
+
const fields = req["fields"];
|
|
3250
|
+
if (fields) {
|
|
3251
|
+
const countEntry = Object.entries(fields).find(([_, v]) => Array.isArray(v) && v[0] == "$count");
|
|
3252
|
+
if (countEntry) resp["rows"] = [{ [countEntry[0]]: resp["rows"].length }];
|
|
3253
|
+
else resp["rows"] = resp["rows"].map((r) => Object.entries(fields).reduce((acc, [k, v]) => ({
|
|
3192
3254
|
...acc,
|
|
3193
3255
|
[v]: r[k]
|
|
3194
3256
|
}), {}));
|
|
3195
3257
|
}
|
|
3258
|
+
} else if (request["$/slice/multisave"]) {
|
|
3259
|
+
const req = request["$/slice/multisave"];
|
|
3260
|
+
const incoming = makeArray(req["rows"] ?? []);
|
|
3261
|
+
const saved = incoming.map((r) => {
|
|
3262
|
+
const id = r == null ? void 0 : r.id;
|
|
3263
|
+
if (typeof id == "number" && id) return { ...r, _sync: "multisave" };
|
|
3264
|
+
return { ...r, id: --_Slice.nextId, _sync: "multisave" };
|
|
3265
|
+
});
|
|
3266
|
+
const ids = saved.map((r) => r.id);
|
|
3267
|
+
this.cache = [
|
|
3268
|
+
...this.cache.filter((c) => (c == null ? void 0 : c.id) != null && !ids.includes(c.id)),
|
|
3269
|
+
...saved
|
|
3270
|
+
].toSorted(sortByProp("id"));
|
|
3271
|
+
resp = {
|
|
3272
|
+
failed: [],
|
|
3273
|
+
granted: saved.map((r) => Object.keys(r).reduce((acc, key) => ({ ...acc, [key]: true }), {})),
|
|
3274
|
+
"ignored-fields": [],
|
|
3275
|
+
keys: ids,
|
|
3276
|
+
publish: 1,
|
|
3277
|
+
tx: null
|
|
3278
|
+
};
|
|
3196
3279
|
} else if (request["$/slice/xinsert"]) {
|
|
3197
|
-
const
|
|
3280
|
+
const req = request["$/slice/xinsert"];
|
|
3281
|
+
const rows = makeArray(req["rows"]).map((r) => ({
|
|
3198
3282
|
...r,
|
|
3199
3283
|
id: --_Slice.nextId,
|
|
3200
3284
|
_sync: "insert"
|
|
@@ -3209,19 +3293,20 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
3209
3293
|
tx: null
|
|
3210
3294
|
};
|
|
3211
3295
|
} else if (request["$/slice/xupdate"]) {
|
|
3212
|
-
const
|
|
3296
|
+
const req = request["$/slice/xupdate"];
|
|
3297
|
+
const ids = makeArray(req["rows"]).map((r) => r.id);
|
|
3213
3298
|
this.cache = [
|
|
3214
3299
|
...this.cache.filter((c) => !ids.includes(c.id)),
|
|
3215
|
-
...
|
|
3300
|
+
...makeArray(req["rows"]).map((r) => ({ ...r, _sync: "update" }))
|
|
3216
3301
|
].toSorted(sortByProp("id"));
|
|
3217
3302
|
resp = {
|
|
3218
3303
|
failed: [],
|
|
3219
|
-
granted:
|
|
3304
|
+
granted: makeArray(req["rows"]).map((r) => Object.keys(r).reduce((acc, key) => ({
|
|
3220
3305
|
...acc,
|
|
3221
3306
|
[key]: true
|
|
3222
3307
|
}), {})),
|
|
3223
3308
|
"ignored-fields": [],
|
|
3224
|
-
keys:
|
|
3309
|
+
keys: ids,
|
|
3225
3310
|
publish: 1,
|
|
3226
3311
|
tx: null
|
|
3227
3312
|
};
|
|
@@ -3229,27 +3314,158 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
3229
3314
|
if (request["$pop"])
|
|
3230
3315
|
resp = request["$pop"].split(":").reduce((acc, key) => acc[JSONAttemptParse(key)], resp);
|
|
3231
3316
|
return resp;
|
|
3232
|
-
}
|
|
3233
|
-
|
|
3317
|
+
};
|
|
3318
|
+
if (offlineNow) return offlineSim();
|
|
3319
|
+
try {
|
|
3320
|
+
return await onlineExec();
|
|
3321
|
+
} catch (e) {
|
|
3322
|
+
if (offlineSupported) return offlineSim();
|
|
3323
|
+
throw e;
|
|
3234
3324
|
}
|
|
3235
3325
|
};
|
|
3236
3326
|
}
|
|
3237
3327
|
async pushChanges() {
|
|
3238
|
-
if (this.offlineEnabled && this.api.online) {
|
|
3239
|
-
|
|
3240
|
-
|
|
3241
|
-
|
|
3242
|
-
|
|
3243
|
-
|
|
3244
|
-
|
|
3245
|
-
|
|
3246
|
-
|
|
3247
|
-
|
|
3328
|
+
if (this.offlineEnabled && this.api.online && (typeof navigator === "undefined" || (navigator == null ? void 0 : navigator.onLine))) {
|
|
3329
|
+
if (this.pushing) return;
|
|
3330
|
+
this.pushing = true;
|
|
3331
|
+
const isOnline = () => this.api.online && (typeof navigator === "undefined" || (navigator == null ? void 0 : navigator.onLine));
|
|
3332
|
+
const stripLocalFields = (obj) => {
|
|
3333
|
+
if (obj == null || typeof obj != "object") return obj;
|
|
3334
|
+
if (Array.isArray(obj)) return obj.map(stripLocalFields);
|
|
3335
|
+
const out = { ...obj };
|
|
3336
|
+
delete out._sync;
|
|
3337
|
+
delete out._syncKey;
|
|
3338
|
+
Object.entries(out).forEach(([k, v]) => out[k] = stripLocalFields(v));
|
|
3339
|
+
return out;
|
|
3340
|
+
};
|
|
3341
|
+
const swapFKs = (obj) => {
|
|
3342
|
+
let ready = true;
|
|
3343
|
+
const patched = stripLocalFields(obj);
|
|
3344
|
+
for (const [k, v] of Object.entries(patched)) {
|
|
3345
|
+
if (!/(Id|Ref)$/.test(k)) continue;
|
|
3346
|
+
if (Array.isArray(v)) {
|
|
3347
|
+
patched[k] = v.map((id) => {
|
|
3348
|
+
if (typeof id != "number") return id;
|
|
3349
|
+
if (id < 0 && _Slice.idMap[id] != null) return _Slice.idMap[id];
|
|
3350
|
+
return id;
|
|
3351
|
+
});
|
|
3352
|
+
if (patched[k].some((id) => typeof id == "number" && id < 0)) ready = false;
|
|
3353
|
+
} else if (typeof v == "number") {
|
|
3354
|
+
if (v < 0) {
|
|
3355
|
+
const mapped = _Slice.idMap[v];
|
|
3356
|
+
if (mapped == null) ready = false;
|
|
3357
|
+
else patched[k] = mapped;
|
|
3358
|
+
}
|
|
3359
|
+
}
|
|
3360
|
+
}
|
|
3361
|
+
return { ready, patched };
|
|
3362
|
+
};
|
|
3363
|
+
const remapTempId = (oldId, newId) => {
|
|
3364
|
+
this.cache = this.cache.map((r) => {
|
|
3365
|
+
if ((r == null ? void 0 : r.id) === oldId) return { ...r, id: newId, _sync: void 0 };
|
|
3366
|
+
const patched = { ...r };
|
|
3367
|
+
for (const [k, v] of Object.entries(patched)) {
|
|
3368
|
+
if (!/(Id|Ref)$/.test(k)) continue;
|
|
3369
|
+
if (Array.isArray(v)) patched[k] = v.map((id) => id === oldId ? newId : id);
|
|
3370
|
+
else if (v === oldId) patched[k] = newId;
|
|
3371
|
+
}
|
|
3372
|
+
return patched;
|
|
3373
|
+
});
|
|
3374
|
+
};
|
|
3375
|
+
const extractFirstRow = (resp) => {
|
|
3376
|
+
if (resp == null) return null;
|
|
3377
|
+
if (Array.isArray(resp)) {
|
|
3378
|
+
let r = resp;
|
|
3379
|
+
while (Array.isArray(r) && r.length) r = r[0];
|
|
3380
|
+
return r;
|
|
3381
|
+
}
|
|
3382
|
+
if (Array.isArray(resp == null ? void 0 : resp.rows)) return resp.rows[0];
|
|
3383
|
+
return resp;
|
|
3384
|
+
};
|
|
3385
|
+
const extractKey0 = (resp) => {
|
|
3386
|
+
var _a;
|
|
3387
|
+
if (resp == null) return null;
|
|
3388
|
+
if (Array.isArray(resp)) return extractKey0(resp[0]);
|
|
3389
|
+
return ((_a = resp == null ? void 0 : resp.keys) == null ? void 0 : _a[0]) ?? null;
|
|
3390
|
+
};
|
|
3391
|
+
try {
|
|
3392
|
+
await sleepWhile(() => !this.loaded);
|
|
3393
|
+
const pendingDeletes = this.cache.filter((v) => (v == null ? void 0 : v._sync) == "delete");
|
|
3394
|
+
for (const value of pendingDeletes) {
|
|
3395
|
+
if (!isOnline()) break;
|
|
3396
|
+
try {
|
|
3397
|
+
await this.delete(value.id).exec();
|
|
3398
|
+
this.cache = this.cache.filter((v) => v.id != value.id);
|
|
3399
|
+
} catch (e) {
|
|
3400
|
+
if (!isOnline()) break;
|
|
3401
|
+
}
|
|
3402
|
+
}
|
|
3403
|
+
const pendingMultisaves = this.cache.filter((v) => (v == null ? void 0 : v._sync) == "multisave");
|
|
3404
|
+
for (const value of pendingMultisaves) {
|
|
3405
|
+
if (!isOnline()) break;
|
|
3406
|
+
const localId = value.id;
|
|
3407
|
+
const raw = stripLocalFields(value);
|
|
3408
|
+
const payload = typeof localId == "number" && localId < 0 ? { ...raw, id: void 0 } : raw;
|
|
3409
|
+
const { ready, patched } = swapFKs(payload);
|
|
3410
|
+
if (!ready) continue;
|
|
3411
|
+
try {
|
|
3412
|
+
const resp = await this.save(patched).exec();
|
|
3413
|
+
const row = extractFirstRow(resp);
|
|
3414
|
+
const newId = row == null ? void 0 : row.id;
|
|
3415
|
+
if (typeof newId == "number") {
|
|
3416
|
+
if (typeof localId == "number" && localId < 0 && newId != localId) {
|
|
3417
|
+
_Slice.idMap[localId] = newId;
|
|
3418
|
+
remapTempId(localId, newId);
|
|
3419
|
+
}
|
|
3420
|
+
const cleanRow = stripLocalFields(row);
|
|
3421
|
+
this.cache = this.cache.map((r) => r.id == newId ? { ...cleanRow, id: newId, _sync: void 0 } : r);
|
|
3422
|
+
}
|
|
3423
|
+
} catch (e) {
|
|
3424
|
+
if (!isOnline()) break;
|
|
3425
|
+
}
|
|
3426
|
+
}
|
|
3427
|
+
const pendingInserts = this.cache.filter((v) => (v == null ? void 0 : v._sync) == "insert");
|
|
3428
|
+
for (const value of pendingInserts) {
|
|
3429
|
+
if (!isOnline()) break;
|
|
3430
|
+
const tempId = value.id;
|
|
3431
|
+
const { ready, patched } = swapFKs({ ...value, id: void 0 });
|
|
3432
|
+
if (!ready) continue;
|
|
3433
|
+
try {
|
|
3434
|
+
const resp = await this.insert(patched).exec();
|
|
3435
|
+
const newId = extractKey0(resp);
|
|
3436
|
+
if (typeof newId == "number") {
|
|
3437
|
+
if (typeof tempId == "number" && tempId < 0) {
|
|
3438
|
+
_Slice.idMap[tempId] = newId;
|
|
3439
|
+
remapTempId(tempId, newId);
|
|
3440
|
+
}
|
|
3441
|
+
this.cache = this.cache.map((r) => r.id == newId ? { ...r, _sync: void 0 } : r);
|
|
3442
|
+
}
|
|
3443
|
+
} catch (e) {
|
|
3444
|
+
if (!isOnline()) break;
|
|
3445
|
+
}
|
|
3446
|
+
}
|
|
3447
|
+
const pendingUpdates = this.cache.filter((v) => (v == null ? void 0 : v._sync) == "update");
|
|
3448
|
+
for (const value of pendingUpdates) {
|
|
3449
|
+
if (!isOnline()) break;
|
|
3450
|
+
const { ready, patched } = swapFKs({ ...value });
|
|
3451
|
+
if (!ready) continue;
|
|
3452
|
+
try {
|
|
3453
|
+
await this.update({
|
|
3454
|
+
...patched,
|
|
3248
3455
|
_sync: void 0
|
|
3249
3456
|
}).where("_updatedDate", "==", value.modified).exec();
|
|
3457
|
+
this.cache = this.cache.map((v) => v.id == value.id ? { ...v, _sync: void 0 } : v);
|
|
3458
|
+
} catch (e) {
|
|
3459
|
+
if (!isOnline()) break;
|
|
3250
3460
|
}
|
|
3251
|
-
}
|
|
3252
|
-
|
|
3461
|
+
}
|
|
3462
|
+
this.pushBackoff = 0;
|
|
3463
|
+
} catch (e) {
|
|
3464
|
+
this.pushBackoff = this.pushBackoff ? Math.min(15e3, this.pushBackoff * 2) : 500;
|
|
3465
|
+
this.schedulePushChanges();
|
|
3466
|
+
} finally {
|
|
3467
|
+
this.pushing = false;
|
|
3468
|
+
}
|
|
3253
3469
|
}
|
|
3254
3470
|
}
|
|
3255
3471
|
/**
|
|
@@ -3500,7 +3716,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
3500
3716
|
} });
|
|
3501
3717
|
}
|
|
3502
3718
|
}
|
|
3503
|
-
const version = "1.3.
|
|
3719
|
+
const version = "1.3.13";
|
|
3504
3720
|
class WebRtc {
|
|
3505
3721
|
constructor(api) {
|
|
3506
3722
|
__publicField(this, "ice");
|
package/dist/index.mjs
CHANGED
|
@@ -2359,6 +2359,16 @@ class PWA {
|
|
|
2359
2359
|
else if (/linux/i.test(userAgent)) return "linux";
|
|
2360
2360
|
else return "unknown";
|
|
2361
2361
|
}
|
|
2362
|
+
get browser() {
|
|
2363
|
+
const ua = (navigator.userAgent || "").toLowerCase();
|
|
2364
|
+
if (ua.includes("edg/")) return "edge";
|
|
2365
|
+
if (ua.includes("firefox") || ua.includes("fxios")) return "firefox";
|
|
2366
|
+
if (ua.includes("opr/") || ua.includes("opera")) return "opera";
|
|
2367
|
+
if (ua.includes("samsungbrowser")) return "samsung";
|
|
2368
|
+
if ((ua.includes("crios") || ua.includes("chrome")) && !ua.includes("edg/") && !ua.includes("opr/")) return "chrome";
|
|
2369
|
+
if (ua.includes("safari") && !ua.includes("chrome") && !ua.includes("crios") && !ua.includes("edg/") && !ua.includes("opr/")) return "safari";
|
|
2370
|
+
return "unknown";
|
|
2371
|
+
}
|
|
2362
2372
|
get pwa() {
|
|
2363
2373
|
return matchMedia("(display-mode: standalone)").matches || (navigator == null ? void 0 : navigator.standalone) || document.referrer.includes("android-app://");
|
|
2364
2374
|
}
|
|
@@ -2381,6 +2391,7 @@ class PWA {
|
|
|
2381
2391
|
}
|
|
2382
2392
|
/** Setup the PWA */
|
|
2383
2393
|
async setup(manifest = {}) {
|
|
2394
|
+
var _a;
|
|
2384
2395
|
window.addEventListener("beforeinstallprompt", (e) => {
|
|
2385
2396
|
e.preventDefault();
|
|
2386
2397
|
this.nativeInstallPrompt = e;
|
|
@@ -2396,6 +2407,7 @@ class PWA {
|
|
|
2396
2407
|
dismissExpiry: 7,
|
|
2397
2408
|
// Days
|
|
2398
2409
|
loginLink: false,
|
|
2410
|
+
hidePWAPrompt: false,
|
|
2399
2411
|
...this.api.options.pwaSettings
|
|
2400
2412
|
};
|
|
2401
2413
|
const meta = (key, name, value) => {
|
|
@@ -2429,9 +2441,9 @@ class PWA {
|
|
|
2429
2441
|
link.href = `${base}/manifest?json=${encodeURIComponent(JSON.stringify(manifestObj))}`;
|
|
2430
2442
|
document.head.append(link);
|
|
2431
2443
|
}
|
|
2432
|
-
if (!this.headless && !this.iframe && !this.pwa && this.platform != "mac") setTimeout(() => {
|
|
2433
|
-
var
|
|
2434
|
-
if (((_b = (
|
|
2444
|
+
if (!((_a = this.api.options.pwaSettings) == null ? void 0 : _a.hidePWAPrompt) && !this.headless && !this.iframe && !this.pwa && this.platform != "mac") setTimeout(() => {
|
|
2445
|
+
var _a2, _b, _c, _d;
|
|
2446
|
+
if (((_b = (_a2 = this.api.options) == null ? void 0 : _a2.pwaSettings) == null ? void 0 : _b.dismissExpiry) === 0) localStorage.removeItem(`${this.api.options.name}:pwa`);
|
|
2435
2447
|
let dismissedDate = localStorage.getItem(`${this.api.options.name}:pwa`);
|
|
2436
2448
|
if (dismissedDate) dismissedDate = JSON.parse(dismissedDate);
|
|
2437
2449
|
if (!!dismissedDate && Date.now() > dismissedDate + ((_d = (_c = this.api.options) == null ? void 0 : _c.pwaSettings) == null ? void 0 : _d.dismissExpiry) * 6e4 * 60 * 24) return;
|
|
@@ -2440,8 +2452,47 @@ class PWA {
|
|
|
2440
2452
|
}
|
|
2441
2453
|
/** Prompt user to install the app */
|
|
2442
2454
|
async prompt(platform) {
|
|
2455
|
+
var _a;
|
|
2456
|
+
if ((_a = this.api.options.pwaSettings) == null ? void 0 : _a.hidePWAPrompt) return;
|
|
2443
2457
|
if (document.querySelector(".pwa-prompt")) return;
|
|
2444
|
-
const
|
|
2458
|
+
const targetPlatform = platform || this.platform;
|
|
2459
|
+
const isAndroid = targetPlatform == "android";
|
|
2460
|
+
const isIOS = targetPlatform == "ios";
|
|
2461
|
+
const browser = this.browser;
|
|
2462
|
+
const browserLabel = browser == "edge" ? "Edge" : browser == "firefox" ? "Firefox" : browser == "safari" ? "Safari" : browser == "opera" ? "Opera" : browser == "samsung" ? "Samsung Internet" : browser == "chrome" ? "Chrome" : "your browser";
|
|
2463
|
+
const stepsHtml = this.nativeInstallPrompt ? `` : `
|
|
2464
|
+
<div class="pwa-steps">
|
|
2465
|
+
${isAndroid ? `
|
|
2466
|
+
<div style="text-align:left">
|
|
2467
|
+
<strong>Android (${browserLabel})</strong>
|
|
2468
|
+
<ol>
|
|
2469
|
+
<li>Open the browser menu (⋮) or look for an <strong>Install</strong> option.</li>
|
|
2470
|
+
<li>Select <strong>Install app</strong> or <strong>Add to Home screen</strong>, then confirm.</li>
|
|
2471
|
+
</ol>
|
|
2472
|
+
${browser == "firefox" ? `<div style="font-size:0.85rem;opacity:0.85;margin-top:0.25rem;">If you do not see an install option in Firefox, use <strong>Add to Home screen</strong>.</div>` : ``}
|
|
2473
|
+
</div>
|
|
2474
|
+
` : isIOS ? `
|
|
2475
|
+
<div style="text-align:left">
|
|
2476
|
+
<strong>iPhone / iPad (Safari)</strong>
|
|
2477
|
+
<ol>
|
|
2478
|
+
<li>Tap the <strong>Share</strong> button.</li>
|
|
2479
|
+
<li>Select <strong>Add to Home Screen</strong>, then confirm.</li>
|
|
2480
|
+
</ol>
|
|
2481
|
+
${browser != "safari" ? `<div style="font-size:0.85rem;opacity:0.85;margin-top:0.25rem;">If you are using ${browserLabel} on iOS and don’t see <strong>Add to Home Screen</strong>, open this page in <strong>Safari</strong>.</div>` : ``}
|
|
2482
|
+
</div>
|
|
2483
|
+
` : `
|
|
2484
|
+
<div style="text-align:left">
|
|
2485
|
+
<strong>Desktop (${browserLabel})</strong>
|
|
2486
|
+
<ol>
|
|
2487
|
+
<li>In <strong>Chrome</strong> or <strong>Edge</strong>, look for the <strong>Install</strong> icon in the address bar (or open the browser menu).</li>
|
|
2488
|
+
<li>Select <strong>Install</strong> / <strong>Install app</strong>, then confirm.</li>
|
|
2489
|
+
</ol>
|
|
2490
|
+
${browser == "safari" ? `<div style="font-size:0.85rem;opacity:0.85;margin-top:0.25rem;">In Safari on macOS, look for <strong>Add to Dock</strong> (or a similar web app option) in the File menu, if available.</div>` : ``}
|
|
2491
|
+
${browser == "firefox" ? `<div style="font-size:0.85rem;opacity:0.85;margin-top:0.25rem;">Firefox may not offer PWA installation. You can continue using the browser, or create a shortcut to this page.</div>` : ``}
|
|
2492
|
+
</div>
|
|
2493
|
+
`}
|
|
2494
|
+
</div>
|
|
2495
|
+
`;
|
|
2445
2496
|
let style = document.querySelector("style.pwa");
|
|
2446
2497
|
if (!style) {
|
|
2447
2498
|
style = document.createElement("style");
|
|
@@ -2534,31 +2585,19 @@ class PWA {
|
|
|
2534
2585
|
<button class="pwa-prompt-close">×</button>
|
|
2535
2586
|
</div>
|
|
2536
2587
|
<div class="pwa-prompt-body">
|
|
2537
|
-
|
|
2588
|
+
<div style="margin-bottom:0.5rem;">
|
|
2589
|
+
This application was built with offline capabilities. For the best experience—including reliable offline use and full-screen access—we recommend installing it on your device.
|
|
2590
|
+
</div>
|
|
2591
|
+
${this.nativeInstallPrompt ? `<div style="font-size:0.9rem;opacity:0.9;">Select <strong>Install App</strong> below to continue.</div>` : `<div style="font-size:0.9rem;opacity:0.9;">Follow the steps below for your device and browser.</div>`}
|
|
2538
2592
|
</div>
|
|
2539
2593
|
<div class="pwa-prompt-actions">
|
|
2540
|
-
${this.nativeInstallPrompt ? `<button id="installPwaBtn">Install App</button>` :
|
|
2541
|
-
<table>
|
|
2542
|
-
<tr>
|
|
2543
|
-
<td style="width:40px;text-align:center">
|
|
2544
|
-
${android ? '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="black" style="transform: scale(1.5)"><path d="M480-160q-33 0-56.5-23.5T400-240q0-33 23.5-56.5T480-320q33 0 56.5 23.5T560-240q0 33-23.5 56.5T480-160Zm0-240q-33 0-56.5-23.5T400-480q0-33 23.5-56.5T480-560q33 0 56.5 23.5T560-480q0 33-23.5 56.5T480-400Zm0-240q-33 0-56.5-23.5T400-720q0-33 23.5-56.5T480-800q33 0 56.5 23.5T560-720q0 33-23.5 56.5T480-640Z"/></svg>' : '<svg viewBox="0 0 566 670" xmlns="http://www.w3.org/2000/svg" fill="#c33031" height="40px"><path d="M255 12c4-4 10-8 16-8s12 3 16 8l94 89c3 4 6 7 8 12 2 6 0 14-5 19-7 8-20 9-28 2l-7-7-57-60 2 54v276c0 12-10 22-22 22-12 1-24-10-23-22V110l1-43-60 65c-5 5-13 8-21 6a19 19 0 0 1-16-17c-1-7 2-13 7-18l95-91z" /><path d="M43 207c16-17 40-23 63-23h83v46h-79c-12 0-25 3-33 13-8 9-10 21-10 33v260c0 13 0 27 6 38 5 12 18 18 30 19l14 1h302c14 0 28 0 40-8 11-7 16-21 16-34V276c0-11-2-24-9-33-8-10-22-13-34-13h-78v-46h75c13 0 25 1 37 4 16 4 31 13 41 27 11 17 14 37 14 57v280c0 20-3 41-15 58a71 71 0 0 1-45 27c-11 2-23 3-34 3H109c-19-1-40-4-56-15-14-9-23-23-27-38-4-12-5-25-5-38V270c1-22 6-47 22-63z" /></svg>'}
|
|
2545
|
-
</td>
|
|
2546
|
-
<td>1) ${android ? "Open the dropdown menu" : 'Tap the "Share" button'}</td>
|
|
2547
|
-
</tr>
|
|
2548
|
-
<tr>
|
|
2549
|
-
<td style="width:40px;text-align:center">
|
|
2550
|
-
${android ? '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="black" style="transform: scale(-1.5, 1.5)"><path d="M280-40q-33 0-56.5-23.5T200-120v-720q0-33 23.5-56.5T280-920h280v80H280v40h280v80H280v480h400v-80h80v200q0 33-23.5 56.5T680-40H280Zm0-120v40h400v-40H280Zm440-240L520-600l56-56 104 104v-288h80v288l104-104 56 56-200 200ZM280-800v-40 40Zm0 640v40-40Z"/></svg>' : '<svg viewBox="0 0 578 584" xmlns="http://www.w3.org/2000/svg" fill="black" height="34px"><path d="M101 35l19-1h333c12 0 23 0 35 3 17 3 34 12 44 27 13 16 16 38 16 58v329c0 19 0 39-8 57a65 65 0 0 1-37 37c-18 7-38 7-57 7H130c-21 1-44 0-63-10-14-7-25-20-30-34-6-15-8-30-8-45V121c1-21 5-44 19-61 13-16 33-23 53-25m7 46c-10 1-19 6-24 14-7 8-9 20-9 31v334c0 12 2 25 10 34 9 10 23 12 35 12h336c14 1 30-3 38-15 6-9 8-20 8-31V125c0-12-2-24-10-33-9-9-22-12-35-12H121l-13 1z" /><path d="M271 161c9-11 31-10 38 4 3 5 3 11 3 17v87h88c7 0 16 1 21 7 6 6 7 14 6 22a21 21 0 0 1-10 14c-5 4-11 5-17 5h-88v82c0 7-1 15-6 20-10 10-29 10-37-2-3-6-4-13-4-19v-81h-87c-8-1-17-3-23-9-5-6-6-15-4-22a21 21 0 0 1 11-14c6-3 13-3 19-3h84v-88c0-7 1-14 6-20z" /></svg>'}
|
|
2551
|
-
</td>
|
|
2552
|
-
<td>2) Select "Add to Home Screen"</td>
|
|
2553
|
-
</tr>
|
|
2554
|
-
</table>
|
|
2555
|
-
`}
|
|
2594
|
+
${this.nativeInstallPrompt ? `<button id="installPwaBtn">Install App</button>` : stepsHtml}
|
|
2556
2595
|
</div>
|
|
2557
2596
|
`;
|
|
2558
2597
|
const closeBtn = prompt.querySelector(".pwa-prompt-close");
|
|
2559
2598
|
closeBtn.onclick = () => {
|
|
2560
|
-
var
|
|
2561
|
-
!!((
|
|
2599
|
+
var _a2;
|
|
2600
|
+
!!((_a2 = this.api.options.pwaSettings) == null ? void 0 : _a2.dismissExpiry) ? localStorage.setItem(`${this.api.options.name}:pwa`, Date.now().toString()) : localStorage.removeItem(`${this.api.options.name}:pwa`);
|
|
2562
2601
|
prompt.remove();
|
|
2563
2602
|
};
|
|
2564
2603
|
document.body.append(prompt);
|
|
@@ -3102,6 +3141,12 @@ const _Slice = class _Slice {
|
|
|
3102
3141
|
__publicField(this, "table");
|
|
3103
3142
|
__publicField(this, "info");
|
|
3104
3143
|
__publicField(this, "loaded", false);
|
|
3144
|
+
__publicField(this, "pushing", false);
|
|
3145
|
+
// NEW: prevent concurrent pushChanges() runs
|
|
3146
|
+
__publicField(this, "pushTimer", null);
|
|
3147
|
+
// NEW: debounce pushes when connection flaps
|
|
3148
|
+
__publicField(this, "pushBackoff", 0);
|
|
3149
|
+
// NEW: backoff when internet flaps
|
|
3105
3150
|
/** Cached slice data as an observable */
|
|
3106
3151
|
__publicField(this, "cache$", new BehaviorSubject([]));
|
|
3107
3152
|
/** Unsubscribe from changes, undefined if not subscribed */
|
|
@@ -3125,10 +3170,10 @@ const _Slice = class _Slice {
|
|
|
3125
3170
|
}));
|
|
3126
3171
|
});
|
|
3127
3172
|
this.sync();
|
|
3128
|
-
this.api.online$.subscribe(async (online) => {
|
|
3173
|
+
this.api.online$.pipe(distinctUntilChanged()).subscribe(async (online) => {
|
|
3129
3174
|
if (!online) return;
|
|
3130
3175
|
if (this.api.expired) await lastValueFrom(this.api.auth.user$.pipe(skip(1), takeWhile((u) => !u || this.api.expired, true)));
|
|
3131
|
-
this.
|
|
3176
|
+
this.schedulePushChanges();
|
|
3132
3177
|
});
|
|
3133
3178
|
} else {
|
|
3134
3179
|
this.loaded = true;
|
|
@@ -3147,10 +3192,17 @@ const _Slice = class _Slice {
|
|
|
3147
3192
|
var _a;
|
|
3148
3193
|
return (_a = this.api.database) == null ? void 0 : _a.includes(this.slice.toString());
|
|
3149
3194
|
}
|
|
3195
|
+
schedulePushChanges(delay = 750) {
|
|
3196
|
+
if (this.pushTimer) clearTimeout(this.pushTimer);
|
|
3197
|
+
this.pushTimer = setTimeout(() => this.pushChanges(), delay + this.pushBackoff);
|
|
3198
|
+
}
|
|
3150
3199
|
execWrapper(call) {
|
|
3151
3200
|
const onlineExec = call.exec.bind(call);
|
|
3152
3201
|
return async () => {
|
|
3153
|
-
|
|
3202
|
+
const offlineSupported = this.offlineEnabled && typeof navigator !== "undefined";
|
|
3203
|
+
const offlineNow = offlineSupported && !(navigator == null ? void 0 : navigator.onLine);
|
|
3204
|
+
const offlineSim = async () => {
|
|
3205
|
+
var _a, _b, _c;
|
|
3154
3206
|
const where = (row, condition) => {
|
|
3155
3207
|
if (Array.isArray(condition) ? !condition.length : condition == null) return true;
|
|
3156
3208
|
if (!Array.isArray(condition)) return condition;
|
|
@@ -3170,7 +3222,8 @@ const _Slice = class _Slice {
|
|
|
3170
3222
|
await sleepWhile(() => !this.loaded);
|
|
3171
3223
|
let request = call.raw, resp = {};
|
|
3172
3224
|
if (request["$/slice/delete"]) {
|
|
3173
|
-
const
|
|
3225
|
+
const req = request["$/slice/delete"];
|
|
3226
|
+
const found = this.cache.filter((r) => (r == null ? void 0 : r._sync) != "delete").filter((r) => where(r, req["where"])).map((r) => r.id);
|
|
3174
3227
|
this.cache = this.cache.map((r) => found.includes(r.id) ? { ...r, _sync: "delete" } : r);
|
|
3175
3228
|
resp = {
|
|
3176
3229
|
affected: found.length,
|
|
@@ -3179,18 +3232,49 @@ const _Slice = class _Slice {
|
|
|
3179
3232
|
tx: null
|
|
3180
3233
|
};
|
|
3181
3234
|
} else if (request["$/slice/report"]) {
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
if (
|
|
3186
|
-
|
|
3187
|
-
|
|
3235
|
+
const req = request["$/slice/report"];
|
|
3236
|
+
resp["rows"] = deepCopy(this.cache).filter((r) => (r == null ? void 0 : r._sync) != "delete").filter((r) => r && where(r, req["where"]));
|
|
3237
|
+
const order = req["order"];
|
|
3238
|
+
if (order == null ? void 0 : order.length) {
|
|
3239
|
+
const field = (_b = (_a = order[0]) == null ? void 0 : _a[1]) == null ? void 0 : _b[1];
|
|
3240
|
+
const desc = ((_c = order[0]) == null ? void 0 : _c[0]) == "$desc";
|
|
3241
|
+
if (field) resp["rows"] = resp["rows"].toSorted(sortByProp(field, desc));
|
|
3242
|
+
}
|
|
3243
|
+
const limit = req["limit"];
|
|
3244
|
+
if (typeof limit == "number") resp["rows"] = resp["rows"].slice(0, limit);
|
|
3245
|
+
const fields = req["fields"];
|
|
3246
|
+
if (fields) {
|
|
3247
|
+
const countEntry = Object.entries(fields).find(([_, v]) => Array.isArray(v) && v[0] == "$count");
|
|
3248
|
+
if (countEntry) resp["rows"] = [{ [countEntry[0]]: resp["rows"].length }];
|
|
3249
|
+
else resp["rows"] = resp["rows"].map((r) => Object.entries(fields).reduce((acc, [k, v]) => ({
|
|
3188
3250
|
...acc,
|
|
3189
3251
|
[v]: r[k]
|
|
3190
3252
|
}), {}));
|
|
3191
3253
|
}
|
|
3254
|
+
} else if (request["$/slice/multisave"]) {
|
|
3255
|
+
const req = request["$/slice/multisave"];
|
|
3256
|
+
const incoming = makeArray(req["rows"] ?? []);
|
|
3257
|
+
const saved = incoming.map((r) => {
|
|
3258
|
+
const id = r == null ? void 0 : r.id;
|
|
3259
|
+
if (typeof id == "number" && id) return { ...r, _sync: "multisave" };
|
|
3260
|
+
return { ...r, id: --_Slice.nextId, _sync: "multisave" };
|
|
3261
|
+
});
|
|
3262
|
+
const ids = saved.map((r) => r.id);
|
|
3263
|
+
this.cache = [
|
|
3264
|
+
...this.cache.filter((c) => (c == null ? void 0 : c.id) != null && !ids.includes(c.id)),
|
|
3265
|
+
...saved
|
|
3266
|
+
].toSorted(sortByProp("id"));
|
|
3267
|
+
resp = {
|
|
3268
|
+
failed: [],
|
|
3269
|
+
granted: saved.map((r) => Object.keys(r).reduce((acc, key) => ({ ...acc, [key]: true }), {})),
|
|
3270
|
+
"ignored-fields": [],
|
|
3271
|
+
keys: ids,
|
|
3272
|
+
publish: 1,
|
|
3273
|
+
tx: null
|
|
3274
|
+
};
|
|
3192
3275
|
} else if (request["$/slice/xinsert"]) {
|
|
3193
|
-
const
|
|
3276
|
+
const req = request["$/slice/xinsert"];
|
|
3277
|
+
const rows = makeArray(req["rows"]).map((r) => ({
|
|
3194
3278
|
...r,
|
|
3195
3279
|
id: --_Slice.nextId,
|
|
3196
3280
|
_sync: "insert"
|
|
@@ -3205,19 +3289,20 @@ const _Slice = class _Slice {
|
|
|
3205
3289
|
tx: null
|
|
3206
3290
|
};
|
|
3207
3291
|
} else if (request["$/slice/xupdate"]) {
|
|
3208
|
-
const
|
|
3292
|
+
const req = request["$/slice/xupdate"];
|
|
3293
|
+
const ids = makeArray(req["rows"]).map((r) => r.id);
|
|
3209
3294
|
this.cache = [
|
|
3210
3295
|
...this.cache.filter((c) => !ids.includes(c.id)),
|
|
3211
|
-
...
|
|
3296
|
+
...makeArray(req["rows"]).map((r) => ({ ...r, _sync: "update" }))
|
|
3212
3297
|
].toSorted(sortByProp("id"));
|
|
3213
3298
|
resp = {
|
|
3214
3299
|
failed: [],
|
|
3215
|
-
granted:
|
|
3300
|
+
granted: makeArray(req["rows"]).map((r) => Object.keys(r).reduce((acc, key) => ({
|
|
3216
3301
|
...acc,
|
|
3217
3302
|
[key]: true
|
|
3218
3303
|
}), {})),
|
|
3219
3304
|
"ignored-fields": [],
|
|
3220
|
-
keys:
|
|
3305
|
+
keys: ids,
|
|
3221
3306
|
publish: 1,
|
|
3222
3307
|
tx: null
|
|
3223
3308
|
};
|
|
@@ -3225,27 +3310,158 @@ const _Slice = class _Slice {
|
|
|
3225
3310
|
if (request["$pop"])
|
|
3226
3311
|
resp = request["$pop"].split(":").reduce((acc, key) => acc[JSONAttemptParse(key)], resp);
|
|
3227
3312
|
return resp;
|
|
3228
|
-
}
|
|
3229
|
-
|
|
3313
|
+
};
|
|
3314
|
+
if (offlineNow) return offlineSim();
|
|
3315
|
+
try {
|
|
3316
|
+
return await onlineExec();
|
|
3317
|
+
} catch (e) {
|
|
3318
|
+
if (offlineSupported) return offlineSim();
|
|
3319
|
+
throw e;
|
|
3230
3320
|
}
|
|
3231
3321
|
};
|
|
3232
3322
|
}
|
|
3233
3323
|
async pushChanges() {
|
|
3234
|
-
if (this.offlineEnabled && this.api.online) {
|
|
3235
|
-
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
3239
|
-
|
|
3240
|
-
|
|
3241
|
-
|
|
3242
|
-
|
|
3243
|
-
|
|
3324
|
+
if (this.offlineEnabled && this.api.online && (typeof navigator === "undefined" || (navigator == null ? void 0 : navigator.onLine))) {
|
|
3325
|
+
if (this.pushing) return;
|
|
3326
|
+
this.pushing = true;
|
|
3327
|
+
const isOnline = () => this.api.online && (typeof navigator === "undefined" || (navigator == null ? void 0 : navigator.onLine));
|
|
3328
|
+
const stripLocalFields = (obj) => {
|
|
3329
|
+
if (obj == null || typeof obj != "object") return obj;
|
|
3330
|
+
if (Array.isArray(obj)) return obj.map(stripLocalFields);
|
|
3331
|
+
const out = { ...obj };
|
|
3332
|
+
delete out._sync;
|
|
3333
|
+
delete out._syncKey;
|
|
3334
|
+
Object.entries(out).forEach(([k, v]) => out[k] = stripLocalFields(v));
|
|
3335
|
+
return out;
|
|
3336
|
+
};
|
|
3337
|
+
const swapFKs = (obj) => {
|
|
3338
|
+
let ready = true;
|
|
3339
|
+
const patched = stripLocalFields(obj);
|
|
3340
|
+
for (const [k, v] of Object.entries(patched)) {
|
|
3341
|
+
if (!/(Id|Ref)$/.test(k)) continue;
|
|
3342
|
+
if (Array.isArray(v)) {
|
|
3343
|
+
patched[k] = v.map((id) => {
|
|
3344
|
+
if (typeof id != "number") return id;
|
|
3345
|
+
if (id < 0 && _Slice.idMap[id] != null) return _Slice.idMap[id];
|
|
3346
|
+
return id;
|
|
3347
|
+
});
|
|
3348
|
+
if (patched[k].some((id) => typeof id == "number" && id < 0)) ready = false;
|
|
3349
|
+
} else if (typeof v == "number") {
|
|
3350
|
+
if (v < 0) {
|
|
3351
|
+
const mapped = _Slice.idMap[v];
|
|
3352
|
+
if (mapped == null) ready = false;
|
|
3353
|
+
else patched[k] = mapped;
|
|
3354
|
+
}
|
|
3355
|
+
}
|
|
3356
|
+
}
|
|
3357
|
+
return { ready, patched };
|
|
3358
|
+
};
|
|
3359
|
+
const remapTempId = (oldId, newId) => {
|
|
3360
|
+
this.cache = this.cache.map((r) => {
|
|
3361
|
+
if ((r == null ? void 0 : r.id) === oldId) return { ...r, id: newId, _sync: void 0 };
|
|
3362
|
+
const patched = { ...r };
|
|
3363
|
+
for (const [k, v] of Object.entries(patched)) {
|
|
3364
|
+
if (!/(Id|Ref)$/.test(k)) continue;
|
|
3365
|
+
if (Array.isArray(v)) patched[k] = v.map((id) => id === oldId ? newId : id);
|
|
3366
|
+
else if (v === oldId) patched[k] = newId;
|
|
3367
|
+
}
|
|
3368
|
+
return patched;
|
|
3369
|
+
});
|
|
3370
|
+
};
|
|
3371
|
+
const extractFirstRow = (resp) => {
|
|
3372
|
+
if (resp == null) return null;
|
|
3373
|
+
if (Array.isArray(resp)) {
|
|
3374
|
+
let r = resp;
|
|
3375
|
+
while (Array.isArray(r) && r.length) r = r[0];
|
|
3376
|
+
return r;
|
|
3377
|
+
}
|
|
3378
|
+
if (Array.isArray(resp == null ? void 0 : resp.rows)) return resp.rows[0];
|
|
3379
|
+
return resp;
|
|
3380
|
+
};
|
|
3381
|
+
const extractKey0 = (resp) => {
|
|
3382
|
+
var _a;
|
|
3383
|
+
if (resp == null) return null;
|
|
3384
|
+
if (Array.isArray(resp)) return extractKey0(resp[0]);
|
|
3385
|
+
return ((_a = resp == null ? void 0 : resp.keys) == null ? void 0 : _a[0]) ?? null;
|
|
3386
|
+
};
|
|
3387
|
+
try {
|
|
3388
|
+
await sleepWhile(() => !this.loaded);
|
|
3389
|
+
const pendingDeletes = this.cache.filter((v) => (v == null ? void 0 : v._sync) == "delete");
|
|
3390
|
+
for (const value of pendingDeletes) {
|
|
3391
|
+
if (!isOnline()) break;
|
|
3392
|
+
try {
|
|
3393
|
+
await this.delete(value.id).exec();
|
|
3394
|
+
this.cache = this.cache.filter((v) => v.id != value.id);
|
|
3395
|
+
} catch (e) {
|
|
3396
|
+
if (!isOnline()) break;
|
|
3397
|
+
}
|
|
3398
|
+
}
|
|
3399
|
+
const pendingMultisaves = this.cache.filter((v) => (v == null ? void 0 : v._sync) == "multisave");
|
|
3400
|
+
for (const value of pendingMultisaves) {
|
|
3401
|
+
if (!isOnline()) break;
|
|
3402
|
+
const localId = value.id;
|
|
3403
|
+
const raw = stripLocalFields(value);
|
|
3404
|
+
const payload = typeof localId == "number" && localId < 0 ? { ...raw, id: void 0 } : raw;
|
|
3405
|
+
const { ready, patched } = swapFKs(payload);
|
|
3406
|
+
if (!ready) continue;
|
|
3407
|
+
try {
|
|
3408
|
+
const resp = await this.save(patched).exec();
|
|
3409
|
+
const row = extractFirstRow(resp);
|
|
3410
|
+
const newId = row == null ? void 0 : row.id;
|
|
3411
|
+
if (typeof newId == "number") {
|
|
3412
|
+
if (typeof localId == "number" && localId < 0 && newId != localId) {
|
|
3413
|
+
_Slice.idMap[localId] = newId;
|
|
3414
|
+
remapTempId(localId, newId);
|
|
3415
|
+
}
|
|
3416
|
+
const cleanRow = stripLocalFields(row);
|
|
3417
|
+
this.cache = this.cache.map((r) => r.id == newId ? { ...cleanRow, id: newId, _sync: void 0 } : r);
|
|
3418
|
+
}
|
|
3419
|
+
} catch (e) {
|
|
3420
|
+
if (!isOnline()) break;
|
|
3421
|
+
}
|
|
3422
|
+
}
|
|
3423
|
+
const pendingInserts = this.cache.filter((v) => (v == null ? void 0 : v._sync) == "insert");
|
|
3424
|
+
for (const value of pendingInserts) {
|
|
3425
|
+
if (!isOnline()) break;
|
|
3426
|
+
const tempId = value.id;
|
|
3427
|
+
const { ready, patched } = swapFKs({ ...value, id: void 0 });
|
|
3428
|
+
if (!ready) continue;
|
|
3429
|
+
try {
|
|
3430
|
+
const resp = await this.insert(patched).exec();
|
|
3431
|
+
const newId = extractKey0(resp);
|
|
3432
|
+
if (typeof newId == "number") {
|
|
3433
|
+
if (typeof tempId == "number" && tempId < 0) {
|
|
3434
|
+
_Slice.idMap[tempId] = newId;
|
|
3435
|
+
remapTempId(tempId, newId);
|
|
3436
|
+
}
|
|
3437
|
+
this.cache = this.cache.map((r) => r.id == newId ? { ...r, _sync: void 0 } : r);
|
|
3438
|
+
}
|
|
3439
|
+
} catch (e) {
|
|
3440
|
+
if (!isOnline()) break;
|
|
3441
|
+
}
|
|
3442
|
+
}
|
|
3443
|
+
const pendingUpdates = this.cache.filter((v) => (v == null ? void 0 : v._sync) == "update");
|
|
3444
|
+
for (const value of pendingUpdates) {
|
|
3445
|
+
if (!isOnline()) break;
|
|
3446
|
+
const { ready, patched } = swapFKs({ ...value });
|
|
3447
|
+
if (!ready) continue;
|
|
3448
|
+
try {
|
|
3449
|
+
await this.update({
|
|
3450
|
+
...patched,
|
|
3244
3451
|
_sync: void 0
|
|
3245
3452
|
}).where("_updatedDate", "==", value.modified).exec();
|
|
3453
|
+
this.cache = this.cache.map((v) => v.id == value.id ? { ...v, _sync: void 0 } : v);
|
|
3454
|
+
} catch (e) {
|
|
3455
|
+
if (!isOnline()) break;
|
|
3246
3456
|
}
|
|
3247
|
-
}
|
|
3248
|
-
|
|
3457
|
+
}
|
|
3458
|
+
this.pushBackoff = 0;
|
|
3459
|
+
} catch (e) {
|
|
3460
|
+
this.pushBackoff = this.pushBackoff ? Math.min(15e3, this.pushBackoff * 2) : 500;
|
|
3461
|
+
this.schedulePushChanges();
|
|
3462
|
+
} finally {
|
|
3463
|
+
this.pushing = false;
|
|
3464
|
+
}
|
|
3249
3465
|
}
|
|
3250
3466
|
}
|
|
3251
3467
|
/**
|
|
@@ -3496,7 +3712,7 @@ class Superuser {
|
|
|
3496
3712
|
} });
|
|
3497
3713
|
}
|
|
3498
3714
|
}
|
|
3499
|
-
const version = "1.3.
|
|
3715
|
+
const version = "1.3.13";
|
|
3500
3716
|
class WebRtc {
|
|
3501
3717
|
constructor(api) {
|
|
3502
3718
|
__publicField(this, "ice");
|
package/dist/pwa.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export declare class PWA {
|
|
|
7
7
|
get iframe(): boolean;
|
|
8
8
|
get mobile(): boolean;
|
|
9
9
|
get platform(): 'android' | 'ios' | 'mac' | 'windows' | 'linux' | 'unknown';
|
|
10
|
+
get browser(): 'chrome' | 'edge' | 'firefox' | 'safari' | 'opera' | 'samsung' | 'unknown';
|
|
10
11
|
get pwa(): boolean;
|
|
11
12
|
constructor(api: Api);
|
|
12
13
|
private bindInstallButton;
|
package/dist/pwa.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pwa.d.ts","sourceRoot":"","sources":["../src/pwa.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,GAAG,EAAC,MAAM,OAAO,CAAC;AAE1B,qBAAa,GAAG;
|
|
1
|
+
{"version":3,"file":"pwa.d.ts","sourceRoot":"","sources":["../src/pwa.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,GAAG,EAAC,MAAM,OAAO,CAAC;AAE1B,qBAAa,GAAG;IAmCH,OAAO,CAAC,QAAQ,CAAC,GAAG;IAlChC,4BAA4B;IACrB,mBAAmB,EAAE,GAAG,CAAQ;IAEvC,IAAI,QAAQ,IAAI,OAAO,CAAyC;IAEhE,IAAI,MAAM,IAAI,OAAO,CAAyC;IAE9D,IAAI,MAAM,IAAI,OAAO,CAAuD;IAE5E,IAAI,QAAQ,IAAI,SAAS,GAAG,KAAK,GAAG,KAAK,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAQ1E;IAED,IAAI,OAAO,IAAI,QAAQ,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,CASxF;IAED,IAAI,GAAG,IAAI,OAAO,CAEjB;gBAE4B,GAAG,EAAE,GAAG;IAErC,OAAO,CAAC,iBAAiB;IAiBzB,oBAAoB;IACd,KAAK,CAAC,QAAQ,GAAE,GAAQ;IAsE9B,qCAAqC;IAC/B,MAAM,CAAC,QAAQ,CAAC,EAAE,SAAS,GAAG,KAAK;CA8KzC"}
|
package/dist/slice.d.ts
CHANGED
|
@@ -238,6 +238,9 @@ export declare class Slice<T extends Meta = any> {
|
|
|
238
238
|
private table?;
|
|
239
239
|
private info?;
|
|
240
240
|
private loaded;
|
|
241
|
+
private pushing;
|
|
242
|
+
private pushTimer;
|
|
243
|
+
private pushBackoff;
|
|
241
244
|
/** Cached slice data as an observable */
|
|
242
245
|
cache$: BehaviorSubject<T[]>;
|
|
243
246
|
/** Unsubscribe from changes, undefined if not subscribed */
|
|
@@ -255,6 +258,7 @@ export declare class Slice<T extends Meta = any> {
|
|
|
255
258
|
* @param {Api} api Api to send the requests through
|
|
256
259
|
*/
|
|
257
260
|
constructor(slice: number | string, api: Api);
|
|
261
|
+
private schedulePushChanges;
|
|
258
262
|
private execWrapper;
|
|
259
263
|
pushChanges(): Promise<void>;
|
|
260
264
|
/**
|
package/dist/slice.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slice.d.ts","sourceRoot":"","sources":["../src/slice.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,eAAe,
|
|
1
|
+
{"version":3,"file":"slice.d.ts","sourceRoot":"","sources":["../src/slice.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@auxilium/datalynk-client",
|
|
3
3
|
"description": "Datalynk client library",
|
|
4
4
|
"repository": "https://gitlab.auxiliumgroup.com/auxilium/datalynk/datalynk-client",
|
|
5
|
-
"version": "1.3.
|
|
5
|
+
"version": "1.3.13",
|
|
6
6
|
"author": "Zak Timson <zaktimson@gmail.com>",
|
|
7
7
|
"private": false,
|
|
8
8
|
"main": "./dist/index.cjs",
|