@q9labsai/chalk-client 4.1.5 → 4.1.8
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/access/grant.d.ts +8 -0
- package/dist/access/grant.d.ts.map +1 -1
- package/dist/{chunk-PBCGWE2V.js → chunk-C4BIONCP.js} +442 -7
- package/dist/chunk-DFLTEYWX.js +144 -0
- package/dist/chunk-JPNE4K2L.js +8911 -0
- package/dist/{chunk-DI7C5UEM.js → chunk-V6P6EHYO.js} +87 -175
- package/dist/client.d.ts +951 -59
- package/dist/client.d.ts.map +1 -1
- package/dist/connection/dependencies.d.ts +4 -4
- package/dist/connection/dependencies.d.ts.map +1 -1
- package/dist/connection/lifecycle.d.ts.map +1 -1
- package/dist/connection/production.d.ts.map +1 -1
- package/dist/connection/snapshot.d.ts +2 -2
- package/dist/connection/snapshot.d.ts.map +1 -1
- package/dist/effect.js +1012 -7052
- package/dist/generated/http-api.d.ts +941 -62
- package/dist/generated/http-api.d.ts.map +1 -1
- package/dist/generated/schemas.d.ts +1353 -31
- package/dist/generated/schemas.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -2
- package/dist/media/client.d.ts.map +1 -1
- package/dist/media/index.d.ts +2 -1
- package/dist/media/index.d.ts.map +1 -1
- package/dist/media/index.js +5 -1
- package/dist/media/observers.d.ts +3 -0
- package/dist/media/observers.d.ts.map +1 -0
- package/dist/media/plane.d.ts +25 -0
- package/dist/media/plane.d.ts.map +1 -1
- package/dist/media/rtk.d.ts +101 -0
- package/dist/media/rtk.d.ts.map +1 -0
- package/dist/media/target.d.ts +10 -0
- package/dist/media/target.d.ts.map +1 -0
- package/dist/public-invites/client.d.ts +4 -0
- package/dist/public-invites/client.d.ts.map +1 -0
- package/dist/public-invites/index.d.ts +5 -0
- package/dist/public-invites/index.d.ts.map +1 -0
- package/dist/public-invites/index.js +18 -0
- package/dist/public-invites/types.d.ts +67 -0
- package/dist/public-invites/types.d.ts.map +1 -0
- package/dist/server/{chunk-A6YMG5FM.js → chunk-C4XITY5U.js} +1 -1
- package/dist/server/client.d.ts.map +1 -1
- package/dist/server/index.cjs +72 -19
- package/dist/server/index.d.cts +1 -1
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +72 -19
- package/dist/server/server-only.js +1 -1
- package/dist/server/transport.d.cts +1 -1
- package/dist/server/transport.d.ts +1 -1
- package/dist/server/transport.d.ts.map +1 -1
- package/dist/server/types.d.cts +40 -0
- package/dist/server/types.d.ts +40 -0
- package/dist/server/types.d.ts.map +1 -1
- package/dist/whiteboard/types.d.ts +1 -1
- package/dist/whiteboard/types.d.ts.map +1 -1
- package/dist/whiteboard/v1-client.d.ts +1 -1
- package/dist/whiteboard/v1-client.d.ts.map +1 -1
- package/package.json +20 -2
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
|
+
CloudflareRTKClient,
|
|
2
3
|
CloudflareSFUClient,
|
|
3
4
|
createCloudflareSFUHTTPTransport
|
|
4
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-C4BIONCP.js";
|
|
6
|
+
import {
|
|
7
|
+
AccessGrantError,
|
|
8
|
+
requireParsedAccessGrant,
|
|
9
|
+
validEpisodeDiagnosticCredential
|
|
10
|
+
} from "./chunk-JPNE4K2L.js";
|
|
5
11
|
import {
|
|
6
12
|
createBrowserSyncLifecycle,
|
|
7
13
|
createBrowserWebSocketFactory,
|
|
@@ -81,7 +87,15 @@ function validateRefresh(previous, next, replaceMediaConnection) {
|
|
|
81
87
|
if (left.tenantId !== right.tenantId || left.spaceId !== right.spaceId || left.episodeId !== right.episodeId || left.participantId !== right.participantId || left.participantGeneration !== right.participantGeneration) {
|
|
82
88
|
throw new TypeError("Access grant refresh changed its subject");
|
|
83
89
|
}
|
|
84
|
-
if (!replaceMediaConnection && previous.media.
|
|
90
|
+
if (!replaceMediaConnection && (previous.media.provider !== next.media.provider || mediaBinding(previous) !== mediaBinding(next))) throw new TypeError("Access grant refresh unexpectedly replaced its media connection");
|
|
91
|
+
}
|
|
92
|
+
function mediaBinding(access) {
|
|
93
|
+
switch (access.media.provider) {
|
|
94
|
+
case "cloudflare_sfu":
|
|
95
|
+
return access.media.clientPayload.connectionId;
|
|
96
|
+
case "cloudflare_rtk":
|
|
97
|
+
return access.media.clientPayload.providerSubject;
|
|
98
|
+
}
|
|
85
99
|
}
|
|
86
100
|
function expiresAt(value) {
|
|
87
101
|
const timestamp = Date.parse(value);
|
|
@@ -873,6 +887,7 @@ var ChalkWhiteboardV1Client = class {
|
|
|
873
887
|
#listeners = /* @__PURE__ */ new Set();
|
|
874
888
|
#operations = /* @__PURE__ */ new Map();
|
|
875
889
|
#reservedOperationIds = /* @__PURE__ */ new Set();
|
|
890
|
+
#pendingStoreWrites = /* @__PURE__ */ new Set();
|
|
876
891
|
#operationRetryTimers = /* @__PURE__ */ new Map();
|
|
877
892
|
#snapshots = /* @__PURE__ */ new Map();
|
|
878
893
|
#updateAssembler = new WhiteboardV1UpdateAssembler();
|
|
@@ -894,6 +909,7 @@ var ChalkWhiteboardV1Client = class {
|
|
|
894
909
|
#latestSnapshot = null;
|
|
895
910
|
#initialSnapshot = null;
|
|
896
911
|
#startPromise = null;
|
|
912
|
+
#stopPromise = null;
|
|
897
913
|
#reconnectTimer;
|
|
898
914
|
#heartbeatTimer;
|
|
899
915
|
#missedHeartbeats = 0;
|
|
@@ -912,6 +928,7 @@ var ChalkWhiteboardV1Client = class {
|
|
|
912
928
|
this.#revision = options.cursor?.revision ?? null;
|
|
913
929
|
}
|
|
914
930
|
startSceneSubscription() {
|
|
931
|
+
if (this.#stopPromise) return this.#stopPromise.then(() => this.startSceneSubscription());
|
|
915
932
|
if (this.#started && this.#startPromise) return this.#startPromise;
|
|
916
933
|
this.#started = true;
|
|
917
934
|
this.#useLegacyHello = false;
|
|
@@ -925,6 +942,18 @@ var ChalkWhiteboardV1Client = class {
|
|
|
925
942
|
return this.#startPromise;
|
|
926
943
|
}
|
|
927
944
|
stopSceneSubscription() {
|
|
945
|
+
if (this.#stopPromise) return this.#stopPromise;
|
|
946
|
+
if (this.#phase === "stopped" && !this.#started) return Promise.resolve();
|
|
947
|
+
this.#stopPromise = Promise.resolve().then(async () => {
|
|
948
|
+
while (this.#pendingStoreWrites.size > 0) {
|
|
949
|
+
await Promise.allSettled([...this.#pendingStoreWrites]);
|
|
950
|
+
}
|
|
951
|
+
this.#stopNow();
|
|
952
|
+
this.#stopPromise = null;
|
|
953
|
+
});
|
|
954
|
+
return this.#stopPromise;
|
|
955
|
+
}
|
|
956
|
+
#stopNow() {
|
|
928
957
|
this.#started = false;
|
|
929
958
|
this.#startupGeneration += 1;
|
|
930
959
|
this.#unsubscribeLifecycle?.();
|
|
@@ -1270,11 +1299,19 @@ var ChalkWhiteboardV1Client = class {
|
|
|
1270
1299
|
throw error(failure("submit_update", "unavailable", true, "Whiteboard operation byte capacity is full."));
|
|
1271
1300
|
}
|
|
1272
1301
|
this.#reservedOperationIds.add(frame.operation_id);
|
|
1302
|
+
let storeWrite;
|
|
1303
|
+
try {
|
|
1304
|
+
storeWrite = this.#store.put(pending);
|
|
1305
|
+
} catch (cause) {
|
|
1306
|
+
throw error(failure(operationName(frame), "unavailable", true, "Unable to persist the whiteboard operation."), cause);
|
|
1307
|
+
}
|
|
1308
|
+
this.#pendingStoreWrites.add(storeWrite);
|
|
1273
1309
|
try {
|
|
1274
|
-
await
|
|
1310
|
+
await storeWrite;
|
|
1275
1311
|
} catch (cause) {
|
|
1276
1312
|
throw error(failure(operationName(frame), "unavailable", true, "Unable to persist the whiteboard operation."), cause);
|
|
1277
1313
|
} finally {
|
|
1314
|
+
this.#pendingStoreWrites.delete(storeWrite);
|
|
1278
1315
|
this.#reservedOperationIds.delete(frame.operation_id);
|
|
1279
1316
|
}
|
|
1280
1317
|
let deferred;
|
|
@@ -1669,8 +1706,18 @@ function createChatFileTransport(apiBaseURL, input) {
|
|
|
1669
1706
|
});
|
|
1670
1707
|
}
|
|
1671
1708
|
function createMediaClient(apiBaseURL, input) {
|
|
1709
|
+
if (input.access.media.provider === "cloudflare_rtk") {
|
|
1710
|
+
return createRTKConnectionMediaClient(
|
|
1711
|
+
new CloudflareRTKClient({
|
|
1712
|
+
authToken: input.access.media.clientPayload.token,
|
|
1713
|
+
participantId: input.access.subject.participantId,
|
|
1714
|
+
onError: input.onFailure,
|
|
1715
|
+
onScreenEnded: input.onScreenEnded
|
|
1716
|
+
})
|
|
1717
|
+
);
|
|
1718
|
+
}
|
|
1672
1719
|
const { subject } = input.access;
|
|
1673
|
-
|
|
1720
|
+
const client = new CloudflareSFUClient({
|
|
1674
1721
|
bootstrap: input.access.media.clientPayload,
|
|
1675
1722
|
participantId: subject.participantId,
|
|
1676
1723
|
transport: createCloudflareSFUHTTPTransport({
|
|
@@ -1684,6 +1731,36 @@ function createMediaClient(apiBaseURL, input) {
|
|
|
1684
1731
|
onError: input.onFailure,
|
|
1685
1732
|
onScreenEnded: input.onScreenEnded
|
|
1686
1733
|
});
|
|
1734
|
+
return createSFUConnectionMediaClient(client);
|
|
1735
|
+
}
|
|
1736
|
+
function createRTKConnectionMediaClient(client) {
|
|
1737
|
+
return bindConnectionMediaClient(client, (input) => {
|
|
1738
|
+
if (!("provider" in input) || input.provider !== "cloudflare_rtk") throw new TypeError("The RealtimeKit adapter requires a Cloudflare RealtimeKit access grant");
|
|
1739
|
+
return client.restart(input);
|
|
1740
|
+
});
|
|
1741
|
+
}
|
|
1742
|
+
function createSFUConnectionMediaClient(client) {
|
|
1743
|
+
return bindConnectionMediaClient(client, (input) => {
|
|
1744
|
+
if ("provider" in input) {
|
|
1745
|
+
if (input.provider !== "cloudflare_sfu") throw new TypeError("The Cloudflare SFU adapter requires a Cloudflare SFU access grant");
|
|
1746
|
+
return client.restart(input.clientPayload);
|
|
1747
|
+
}
|
|
1748
|
+
return client.restart(input);
|
|
1749
|
+
});
|
|
1750
|
+
}
|
|
1751
|
+
function bindConnectionMediaClient(client, restart) {
|
|
1752
|
+
return {
|
|
1753
|
+
setLocalPublicationTarget: client.setLocalPublicationTarget.bind(client),
|
|
1754
|
+
observeLocalPublications: client.observeLocalPublications.bind(client),
|
|
1755
|
+
observeRemotePublications: client.observeRemotePublications.bind(client),
|
|
1756
|
+
start: client.start.bind(client),
|
|
1757
|
+
stop: client.stop.bind(client),
|
|
1758
|
+
restart,
|
|
1759
|
+
prepareLocalTrack: client.prepareLocalTrack.bind(client),
|
|
1760
|
+
clearPreparedLocalTrack: client.clearPreparedLocalTrack.bind(client),
|
|
1761
|
+
getSnapshot: client.getSnapshot.bind(client),
|
|
1762
|
+
subscribe: client.subscribe.bind(client)
|
|
1763
|
+
};
|
|
1687
1764
|
}
|
|
1688
1765
|
function createSyncClient(syncURL, input) {
|
|
1689
1766
|
return createV1SyncClient({
|
|
@@ -1725,172 +1802,6 @@ function whiteboardURL(syncURL) {
|
|
|
1725
1802
|
// src/connection/lifecycle.ts
|
|
1726
1803
|
import { Clock as Clock2, Context as Context3, Data as Data2, Deferred, Duration, Effect as Effect2, Exit, Fiber, Layer as Layer3, Queue, Scope, SubscriptionRef } from "effect";
|
|
1727
1804
|
|
|
1728
|
-
// src/access/base64-url.ts
|
|
1729
|
-
function decodeBase64Url(value) {
|
|
1730
|
-
const base64 = value.replaceAll("-", "+").replaceAll("_", "/").padEnd(Math.ceil(value.length / 4) * 4, "=");
|
|
1731
|
-
const bytes = Uint8Array.from(globalThis.atob(base64), (character) => character.charCodeAt(0));
|
|
1732
|
-
return new TextDecoder().decode(bytes);
|
|
1733
|
-
}
|
|
1734
|
-
|
|
1735
|
-
// src/access/episode-diagnostic-credential.ts
|
|
1736
|
-
var INTAKE_PATH = "/_internal/episode-diagnostic-events";
|
|
1737
|
-
var RFC3339_ZONED = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.\d+)?(Z|[+-]\d{2}:\d{2})$/;
|
|
1738
|
-
function parseEpisodeDiagnosticCredential(value) {
|
|
1739
|
-
if (!isRecord3(value)) return null;
|
|
1740
|
-
const token = value.token;
|
|
1741
|
-
const expiresAt2 = value.expires_at;
|
|
1742
|
-
const generation = value.generation;
|
|
1743
|
-
const intakePath = value.intake_path;
|
|
1744
|
-
if (typeof token !== "string" || !validDiagnosticCredential(token)) return null;
|
|
1745
|
-
if (!isRFC3339Zoned(expiresAt2)) return null;
|
|
1746
|
-
if (!Number.isSafeInteger(generation) || generation < 1) return null;
|
|
1747
|
-
if (intakePath !== INTAKE_PATH) return null;
|
|
1748
|
-
return Object.freeze({ token, expiresAt: expiresAt2, generation, intakePath });
|
|
1749
|
-
}
|
|
1750
|
-
function validEpisodeDiagnosticCredential(credential, now) {
|
|
1751
|
-
return credential.intakePath === INTAKE_PATH && Number.isSafeInteger(credential.generation) && credential.generation > 0 && isRFC3339Zoned(credential.expiresAt) && Date.parse(credential.expiresAt) > now && validDiagnosticCredential(credential.token);
|
|
1752
|
-
}
|
|
1753
|
-
function validDiagnosticCredential(token) {
|
|
1754
|
-
const segments = token.split(".");
|
|
1755
|
-
if (segments.length !== 3) return false;
|
|
1756
|
-
try {
|
|
1757
|
-
const payload = JSON.parse(decodeBase64Url(segments[1] ?? ""));
|
|
1758
|
-
return isRecord3(payload) && payload.aud === "chalk-diagnostics";
|
|
1759
|
-
} catch {
|
|
1760
|
-
return false;
|
|
1761
|
-
}
|
|
1762
|
-
}
|
|
1763
|
-
function isRFC3339Zoned(value) {
|
|
1764
|
-
if (typeof value !== "string") return false;
|
|
1765
|
-
const match = RFC3339_ZONED.exec(value);
|
|
1766
|
-
if (!match) return false;
|
|
1767
|
-
return validTimestampFields(match) && Number.isFinite(Date.parse(value));
|
|
1768
|
-
}
|
|
1769
|
-
function validTimestampFields(match) {
|
|
1770
|
-
const year = Number(match[1]);
|
|
1771
|
-
const month = Number(match[2]);
|
|
1772
|
-
const day = Number(match[3]);
|
|
1773
|
-
const hour = Number(match[4]);
|
|
1774
|
-
const minute = Number(match[5]);
|
|
1775
|
-
const second = Number(match[6]);
|
|
1776
|
-
const zone = match[7] ?? "";
|
|
1777
|
-
return validCalendarDate(year, month, day) && validClockTime(hour, minute, second) && validZoneOffset(zone);
|
|
1778
|
-
}
|
|
1779
|
-
function inRange(value, min, max) {
|
|
1780
|
-
return value >= min && value <= max;
|
|
1781
|
-
}
|
|
1782
|
-
function validCalendarDate(year, month, day) {
|
|
1783
|
-
return inRange(month, 1, 12) && inRange(day, 1, daysInMonth(year, month));
|
|
1784
|
-
}
|
|
1785
|
-
function validClockTime(hour, minute, second) {
|
|
1786
|
-
return inRange(hour, 0, 23) && inRange(minute, 0, 59) && inRange(second, 0, 59);
|
|
1787
|
-
}
|
|
1788
|
-
function validZoneOffset(zone) {
|
|
1789
|
-
if (zone === "Z") return true;
|
|
1790
|
-
return inRange(Number(zone.slice(1, 3)), 0, 23) && inRange(Number(zone.slice(4, 6)), 0, 59);
|
|
1791
|
-
}
|
|
1792
|
-
function daysInMonth(year, month) {
|
|
1793
|
-
if (month === 2) return isLeapYear(year) ? 29 : 28;
|
|
1794
|
-
return [4, 6, 9, 11].includes(month) ? 30 : 31;
|
|
1795
|
-
}
|
|
1796
|
-
function isLeapYear(year) {
|
|
1797
|
-
return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
|
|
1798
|
-
}
|
|
1799
|
-
function isRecord3(value) {
|
|
1800
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1801
|
-
}
|
|
1802
|
-
|
|
1803
|
-
// src/access/grant.ts
|
|
1804
|
-
var AccessGrantError = class extends TypeError {
|
|
1805
|
-
code = "access.invalid";
|
|
1806
|
-
constructor(message = "Access grant is invalid") {
|
|
1807
|
-
super(message);
|
|
1808
|
-
this.name = "AccessGrantError";
|
|
1809
|
-
}
|
|
1810
|
-
};
|
|
1811
|
-
function parseParsedAccessGrant(value) {
|
|
1812
|
-
if (!isRecord4(value)) throw new AccessGrantError();
|
|
1813
|
-
const subject = parseSubject(value.subject);
|
|
1814
|
-
const diagnostics = parseEpisodeDiagnosticCredential(value.diagnostics);
|
|
1815
|
-
return {
|
|
1816
|
-
subject,
|
|
1817
|
-
sync: parseSyncAccess(value.sync),
|
|
1818
|
-
media: parseMediaAccess(value.media),
|
|
1819
|
-
diagnostics: diagnostics?.generation === subject.participantGeneration ? diagnostics : null
|
|
1820
|
-
};
|
|
1821
|
-
}
|
|
1822
|
-
async function requireParsedAccessGrant(value) {
|
|
1823
|
-
if (typeof Response !== "undefined" && value instanceof Response) {
|
|
1824
|
-
if (!value.ok) throw new AccessGrantError(`Access grant request failed with HTTP ${value.status}`);
|
|
1825
|
-
try {
|
|
1826
|
-
return parseParsedAccessGrant(await value.json());
|
|
1827
|
-
} catch (error2) {
|
|
1828
|
-
if (error2 instanceof AccessGrantError) throw error2;
|
|
1829
|
-
throw new AccessGrantError();
|
|
1830
|
-
}
|
|
1831
|
-
}
|
|
1832
|
-
return parseParsedAccessGrant(value);
|
|
1833
|
-
}
|
|
1834
|
-
function parseSubject(value) {
|
|
1835
|
-
if (!isRecord4(value)) throw new AccessGrantError();
|
|
1836
|
-
return {
|
|
1837
|
-
tenantId: requireNonEmptyString(value.tenant_id),
|
|
1838
|
-
spaceId: requireNonEmptyString(value.space_id),
|
|
1839
|
-
episodeId: requireNonEmptyString(value.episode_id),
|
|
1840
|
-
participantId: requireNonEmptyString(value.participant_id),
|
|
1841
|
-
participantGeneration: requirePositiveInteger(value.participant_generation)
|
|
1842
|
-
};
|
|
1843
|
-
}
|
|
1844
|
-
function requirePositiveInteger(value) {
|
|
1845
|
-
if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 1) throw new AccessGrantError();
|
|
1846
|
-
return value;
|
|
1847
|
-
}
|
|
1848
|
-
function parseSyncAccess(value) {
|
|
1849
|
-
if (!isRecord4(value)) throw new AccessGrantError();
|
|
1850
|
-
return {
|
|
1851
|
-
token: requireCredential(value.token, "chalk-sync"),
|
|
1852
|
-
expiresAt: requireDateTime(value.expires_at ?? value.expiresAt)
|
|
1853
|
-
};
|
|
1854
|
-
}
|
|
1855
|
-
function parseMediaAccess(value) {
|
|
1856
|
-
if (!isRecord4(value) || value.provider !== "cloudflare_sfu" || !isRecord4(value.client_payload ?? value.clientPayload)) throw new AccessGrantError();
|
|
1857
|
-
const payload = value.client_payload ?? value.clientPayload;
|
|
1858
|
-
return {
|
|
1859
|
-
token: requireCredential(value.token, "chalk-media"),
|
|
1860
|
-
expiresAt: requireDateTime(value.expires_at ?? value.expiresAt),
|
|
1861
|
-
provider: value.provider,
|
|
1862
|
-
clientPayload: {
|
|
1863
|
-
connectionId: requireNonEmptyString(payload.connectionId),
|
|
1864
|
-
stunServer: requireNonEmptyString(payload.stunServer)
|
|
1865
|
-
}
|
|
1866
|
-
};
|
|
1867
|
-
}
|
|
1868
|
-
function requireCredential(value, audience) {
|
|
1869
|
-
const token = requireNonEmptyString(value);
|
|
1870
|
-
const segments = token.split(".");
|
|
1871
|
-
if (segments.length !== 3) throw new AccessGrantError();
|
|
1872
|
-
let payload;
|
|
1873
|
-
try {
|
|
1874
|
-
payload = JSON.parse(decodeBase64Url(segments[1] ?? ""));
|
|
1875
|
-
} catch {
|
|
1876
|
-
throw new AccessGrantError();
|
|
1877
|
-
}
|
|
1878
|
-
if (!isRecord4(payload) || payload.aud !== audience) throw new AccessGrantError();
|
|
1879
|
-
return token;
|
|
1880
|
-
}
|
|
1881
|
-
function requireDateTime(value) {
|
|
1882
|
-
const dateTime = requireNonEmptyString(value);
|
|
1883
|
-
if (!Number.isFinite(Date.parse(dateTime))) throw new AccessGrantError();
|
|
1884
|
-
return dateTime;
|
|
1885
|
-
}
|
|
1886
|
-
function requireNonEmptyString(value) {
|
|
1887
|
-
if (typeof value !== "string" || value.trim().length === 0) throw new AccessGrantError();
|
|
1888
|
-
return value;
|
|
1889
|
-
}
|
|
1890
|
-
function isRecord4(value) {
|
|
1891
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1892
|
-
}
|
|
1893
|
-
|
|
1894
1805
|
// src/connection/diagnostics.ts
|
|
1895
1806
|
var ConnectionDiagnostics = class {
|
|
1896
1807
|
#limit;
|
|
@@ -2346,7 +2257,8 @@ var makeConnectionLifecycleLayerFromServices = (options) => Layer3.effect(
|
|
|
2346
2257
|
const sync = model.sync;
|
|
2347
2258
|
if (!media || !sync) return yield* Effect2.fail(lifecycleFailure("invalid_state", false, "Media recovery requires active ports"));
|
|
2348
2259
|
const grant = yield* access.refresh("media_recovery", true).pipe(Effect2.mapError(accessFailure));
|
|
2349
|
-
|
|
2260
|
+
const restartInput = grant.media.provider === "cloudflare_sfu" ? grant.media.clientPayload : grant.media;
|
|
2261
|
+
yield* foreign6(() => media.restart(restartInput));
|
|
2350
2262
|
model.mediaSnapshot = media.getSnapshot();
|
|
2351
2263
|
yield* waitForSyncLive(sync, boundedInteger(options.recovery?.budgetMs, RECOVERY_BUDGET_MS, 1, 6e4));
|
|
2352
2264
|
});
|
|
@@ -4757,7 +4669,7 @@ function stripTrailingUrlSlash(value) {
|
|
|
4757
4669
|
return value.endsWith("/") ? value.slice(0, -1) : value;
|
|
4758
4670
|
}
|
|
4759
4671
|
function intakeResponse(value) {
|
|
4760
|
-
if (!
|
|
4672
|
+
if (!isRecord3(value) || typeof value.diagnosticReference !== "string" || !Number.isSafeInteger(value.committedCursor)) return null;
|
|
4761
4673
|
if (!Array.isArray(value.accepted) || !Array.isArray(value.duplicates) || !Array.isArray(value.conflicts)) return null;
|
|
4762
4674
|
return { accepted: value.accepted, duplicates: value.duplicates, conflicts: value.conflicts };
|
|
4763
4675
|
}
|
|
@@ -4768,14 +4680,14 @@ function completeDelivery(delivery, expected) {
|
|
|
4768
4680
|
function intakeIds(items, expected, cursorRequired) {
|
|
4769
4681
|
const ids = [];
|
|
4770
4682
|
for (const item of items) {
|
|
4771
|
-
if (!
|
|
4683
|
+
if (!isRecord3(item) || typeof item.eventId !== "string" || !expected.has(item.eventId)) return null;
|
|
4772
4684
|
if (cursorRequired && !Number.isSafeInteger(item.cursor)) return null;
|
|
4773
4685
|
if (!cursorRequired && item.code !== "fingerprint_mismatch") return null;
|
|
4774
4686
|
ids.push(item.eventId);
|
|
4775
4687
|
}
|
|
4776
4688
|
return ids;
|
|
4777
4689
|
}
|
|
4778
|
-
function
|
|
4690
|
+
function isRecord3(value) {
|
|
4779
4691
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4780
4692
|
}
|
|
4781
4693
|
|
|
@@ -4863,7 +4775,7 @@ var makeSpaceClientCoreLayer = (options, platform = {}) => {
|
|
|
4863
4775
|
now: baseDependencies.clock.now,
|
|
4864
4776
|
setTimeout: baseDependencies.clock.setTimeout,
|
|
4865
4777
|
clearTimeout: baseDependencies.clock.clearTimeout,
|
|
4866
|
-
release: { id: "chalk-client@4.1.
|
|
4778
|
+
release: { id: "chalk-client@4.1.8" }
|
|
4867
4779
|
});
|
|
4868
4780
|
const diagnosticSyncClients = /* @__PURE__ */ new Set();
|
|
4869
4781
|
const dependencies = {
|