@xenide-io/suite-client 0.6.0 → 0.6.1
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/index.d.mts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +74 -34
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +74 -34
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -9508,6 +9508,7 @@ function createApiClient(config) {
|
|
|
9508
9508
|
let refreshToken = null;
|
|
9509
9509
|
let activeWorkspaceId = null;
|
|
9510
9510
|
const etagBodies = /* @__PURE__ */ new Map();
|
|
9511
|
+
const pendingGets = /* @__PURE__ */ new Map();
|
|
9511
9512
|
let authFailureHandler = null;
|
|
9512
9513
|
let authFailureFired = false;
|
|
9513
9514
|
let refreshPromise = null;
|
|
@@ -9634,6 +9635,7 @@ function createApiClient(config) {
|
|
|
9634
9635
|
refreshToken = null;
|
|
9635
9636
|
activeWorkspaceId = null;
|
|
9636
9637
|
etagBodies.clear();
|
|
9638
|
+
pendingGets.clear();
|
|
9637
9639
|
if (typeof window !== "undefined") {
|
|
9638
9640
|
window.localStorage.removeItem(ACCESS_KEY);
|
|
9639
9641
|
window.localStorage.removeItem(REFRESH_KEY);
|
|
@@ -9702,6 +9704,30 @@ function createApiClient(config) {
|
|
|
9702
9704
|
}
|
|
9703
9705
|
}
|
|
9704
9706
|
async function apiFetch(path, init = {}) {
|
|
9707
|
+
if ((init.method ?? "GET").toUpperCase() !== "GET") {
|
|
9708
|
+
pendingGets.clear();
|
|
9709
|
+
try {
|
|
9710
|
+
return await apiFetchInternal(path, init);
|
|
9711
|
+
} finally {
|
|
9712
|
+
pendingGets.clear();
|
|
9713
|
+
}
|
|
9714
|
+
}
|
|
9715
|
+
if (Object.keys(init).length > 0) return apiFetchInternal(path, init);
|
|
9716
|
+
const key = JSON.stringify([
|
|
9717
|
+
getAccessToken(),
|
|
9718
|
+
getActiveWorkspaceId(),
|
|
9719
|
+
path
|
|
9720
|
+
]);
|
|
9721
|
+
let pending = pendingGets.get(key);
|
|
9722
|
+
if (!pending) {
|
|
9723
|
+
pending = apiFetchInternal(path, init).finally(() => {
|
|
9724
|
+
if (pendingGets.get(key) === pending) pendingGets.delete(key);
|
|
9725
|
+
});
|
|
9726
|
+
pendingGets.set(key, pending);
|
|
9727
|
+
}
|
|
9728
|
+
return (await pending).clone();
|
|
9729
|
+
}
|
|
9730
|
+
async function apiFetchInternal(path, init = {}) {
|
|
9705
9731
|
const { skipAuth, ...requestInit } = init;
|
|
9706
9732
|
const token = getAccessToken();
|
|
9707
9733
|
const headers = {
|
|
@@ -10436,40 +10462,49 @@ function createCrossAppSync(config) {
|
|
|
10436
10462
|
const subscribers = [];
|
|
10437
10463
|
let pollInterval = null;
|
|
10438
10464
|
let pollListeners = 0;
|
|
10465
|
+
let inFlight = false;
|
|
10466
|
+
let primed = false;
|
|
10467
|
+
let scope;
|
|
10468
|
+
let lastRequestedScope;
|
|
10469
|
+
let lastRequestedAt;
|
|
10439
10470
|
async function fetchCheckpoint() {
|
|
10471
|
+
if (inFlight || document.visibilityState !== "visible") return null;
|
|
10472
|
+
const requestScope = config.getScope?.();
|
|
10473
|
+
if (requestScope === lastRequestedScope && lastRequestedAt !== void 0 && Date.now() - lastRequestedAt < pollMs)
|
|
10474
|
+
return null;
|
|
10475
|
+
inFlight = true;
|
|
10476
|
+
lastRequestedScope = requestScope;
|
|
10477
|
+
lastRequestedAt = Date.now();
|
|
10440
10478
|
try {
|
|
10441
10479
|
const res = await config.api.get(config.checkpointPath);
|
|
10442
10480
|
if (!res.ok) return null;
|
|
10443
|
-
|
|
10481
|
+
const data = await res.json();
|
|
10482
|
+
if (requestScope !== config.getScope?.()) return null;
|
|
10483
|
+
if (scope !== requestScope) {
|
|
10484
|
+
primed = false;
|
|
10485
|
+
scope = requestScope;
|
|
10486
|
+
}
|
|
10487
|
+
return data;
|
|
10444
10488
|
} catch {
|
|
10445
10489
|
return null;
|
|
10446
|
-
}
|
|
10447
|
-
|
|
10448
|
-
function notify(topic) {
|
|
10449
|
-
for (const sub of subscribers) {
|
|
10450
|
-
if (!sub.topic || sub.topic === topic) {
|
|
10451
|
-
if (lastKnown[topic] > sub.lastSync) {
|
|
10452
|
-
sub.lastSync = lastKnown[topic];
|
|
10453
|
-
sub.callback();
|
|
10454
|
-
}
|
|
10455
|
-
}
|
|
10490
|
+
} finally {
|
|
10491
|
+
inFlight = false;
|
|
10456
10492
|
}
|
|
10457
10493
|
}
|
|
10458
10494
|
function checkAndNotify(data) {
|
|
10459
|
-
const
|
|
10460
|
-
|
|
10461
|
-
|
|
10462
|
-
|
|
10463
|
-
|
|
10464
|
-
|
|
10465
|
-
|
|
10466
|
-
|
|
10467
|
-
|
|
10468
|
-
|
|
10469
|
-
|
|
10470
|
-
|
|
10471
|
-
|
|
10472
|
-
notify("integration");
|
|
10495
|
+
const next = {
|
|
10496
|
+
tasks: data.tasks_synced_at || 0,
|
|
10497
|
+
time: data.time_synced_at || 0,
|
|
10498
|
+
integration: data.integration_synced_at || 0
|
|
10499
|
+
};
|
|
10500
|
+
const changed = ["tasks", "time", "integration"].filter(
|
|
10501
|
+
(topic) => primed && next[topic] > lastKnown[topic]
|
|
10502
|
+
);
|
|
10503
|
+
Object.assign(lastKnown, next);
|
|
10504
|
+
primed = true;
|
|
10505
|
+
for (const sub of subscribers) {
|
|
10506
|
+
if (changed.some((topic) => !sub.topic || sub.topic === topic))
|
|
10507
|
+
sub.callback();
|
|
10473
10508
|
}
|
|
10474
10509
|
}
|
|
10475
10510
|
function startPolling() {
|
|
@@ -10496,8 +10531,7 @@ function createCrossAppSync(config) {
|
|
|
10496
10531
|
};
|
|
10497
10532
|
const sub = {
|
|
10498
10533
|
topic,
|
|
10499
|
-
callback: onSync
|
|
10500
|
-
lastSync: lastKnown[topic || "tasks"]
|
|
10534
|
+
callback: onSync
|
|
10501
10535
|
};
|
|
10502
10536
|
subscribers.push(sub);
|
|
10503
10537
|
pollListeners += 1;
|
|
@@ -10602,17 +10636,22 @@ function useSuiteRevisions(options) {
|
|
|
10602
10636
|
let seen = {};
|
|
10603
10637
|
let ready = switching;
|
|
10604
10638
|
let timer;
|
|
10639
|
+
let inFlight = false;
|
|
10640
|
+
let disposed = false;
|
|
10605
10641
|
const tick = async () => {
|
|
10606
|
-
|
|
10642
|
+
if (inFlight || disposed) return;
|
|
10643
|
+
inFlight = true;
|
|
10607
10644
|
try {
|
|
10608
|
-
data = await loadRef.current();
|
|
10645
|
+
const data = await loadRef.current();
|
|
10646
|
+
if (disposed) return;
|
|
10647
|
+
const step = nextRevisionTick(seen, ready, data);
|
|
10648
|
+
seen = step.seen;
|
|
10649
|
+
ready = step.ready;
|
|
10650
|
+
for (const topic of step.changed) onTopicRef.current(topic);
|
|
10609
10651
|
} catch {
|
|
10610
|
-
|
|
10652
|
+
} finally {
|
|
10653
|
+
inFlight = false;
|
|
10611
10654
|
}
|
|
10612
|
-
const step = nextRevisionTick(seen, ready, data);
|
|
10613
|
-
seen = step.seen;
|
|
10614
|
-
ready = step.ready;
|
|
10615
|
-
for (const topic of step.changed) onTopicRef.current(topic);
|
|
10616
10655
|
};
|
|
10617
10656
|
const stop = () => {
|
|
10618
10657
|
if (timer !== void 0) window.clearInterval(timer);
|
|
@@ -10630,6 +10669,7 @@ function useSuiteRevisions(options) {
|
|
|
10630
10669
|
if (document.visibilityState === "visible") start();
|
|
10631
10670
|
document.addEventListener("visibilitychange", onVisibility);
|
|
10632
10671
|
return () => {
|
|
10672
|
+
disposed = true;
|
|
10633
10673
|
stop();
|
|
10634
10674
|
document.removeEventListener("visibilitychange", onVisibility);
|
|
10635
10675
|
};
|