@q9labsai/chalk-client 5.2.6 → 5.3.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.
- package/README.md +1 -1
- package/dist/{chunk-YIDKETOX.js → chunk-3TGVTP6Z.js} +249 -31
- package/dist/{chunk-I7Y4HR2P.js → chunk-DHUHTIU7.js} +149 -28
- package/dist/{chunk-CJVLTSIO.js → chunk-GOSWSXTH.js} +3 -1
- package/dist/{chunk-WFRTUBN6.js → chunk-O26BHHMI.js} +1 -1
- package/dist/{chunk-5YPQNMJE.js → chunk-XSB2GDRW.js} +32 -8
- package/dist/client.d.ts +2 -1
- package/dist/connection/dependencies.d.ts +2 -1
- package/dist/effect.js +4 -4
- package/dist/generated/http-api.d.ts +2 -1
- package/dist/generated/schemas.d.ts +3 -1
- package/dist/generated/sync.d.ts +45 -0
- package/dist/index.js +5 -5
- package/dist/media/client.d.ts +2 -2
- package/dist/media/index.js +1 -1
- package/dist/media/plane.d.ts +4 -2
- package/dist/media/receive-stall.d.ts +43 -0
- package/dist/media/types.d.ts +2 -0
- package/dist/public-invites/index.js +2 -2
- package/dist/server/index.cjs +1 -0
- package/dist/server/index.js +1 -0
- package/dist/server/types.d.cts +2 -0
- package/dist/server/types.d.ts +2 -0
- package/dist/space-client/same-identity.d.ts +6 -0
- package/dist/space-client/types.d.ts +6 -0
- package/dist/sync/index.js +1 -1
- package/dist/sync/v1-types.d.ts +6 -0
- package/package.json +2 -1
|
@@ -6,11 +6,11 @@ import {
|
|
|
6
6
|
describeMediaCaptureError,
|
|
7
7
|
grantedMediaFromStream,
|
|
8
8
|
markMediaFailure
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-3TGVTP6Z.js";
|
|
10
10
|
import {
|
|
11
11
|
AccessGrantError,
|
|
12
12
|
requireParsedAccessGrant
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-GOSWSXTH.js";
|
|
14
14
|
import {
|
|
15
15
|
ChatAttachmentMimeTypeSchema,
|
|
16
16
|
ChatReactionSetFrameSchema,
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
formatSyncConnectDiagnostic,
|
|
25
25
|
scheduleSyncDialDeadline,
|
|
26
26
|
syncConnectFailureCode
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-XSB2GDRW.js";
|
|
28
28
|
|
|
29
29
|
// src/access/manager.ts
|
|
30
30
|
import { Clock, Context, Data, Deferred, Effect, Layer, SynchronizedRef } from "effect";
|
|
@@ -2853,7 +2853,7 @@ var ConnectionDiagnostics = class {
|
|
|
2853
2853
|
// src/connection/lifecycle.ts
|
|
2854
2854
|
var MEDIA_RECOVERY_TIMEOUT_MS = 6e4;
|
|
2855
2855
|
var START_TIMEOUT_MS = 3e4;
|
|
2856
|
-
var LEAVE_TIMEOUT_MS =
|
|
2856
|
+
var LEAVE_TIMEOUT_MS = 4e4;
|
|
2857
2857
|
var RECOVERY_BUDGET_MS = MEDIA_RECOVERY_TIMEOUT_MS;
|
|
2858
2858
|
var MAX_RECOVERY_ATTEMPTS = 3;
|
|
2859
2859
|
var REFRESH_RETRY_MS = 5e3;
|
|
@@ -3291,6 +3291,12 @@ var makeConnectionLifecycleLayerFromServices = (options) => Layer3.effect(
|
|
|
3291
3291
|
if (model.failure) return yield* Effect2.fail(lifecycleFailure("leave_unconfirmed", false, model.failure.message));
|
|
3292
3292
|
return;
|
|
3293
3293
|
}
|
|
3294
|
+
yield* Effect2.sync(() => {
|
|
3295
|
+
for (const { track } of model.media?.getSnapshot().localTracks ?? []) {
|
|
3296
|
+
track.enabled = false;
|
|
3297
|
+
track.stop();
|
|
3298
|
+
}
|
|
3299
|
+
});
|
|
3294
3300
|
yield* transition("leaving");
|
|
3295
3301
|
const confirmed = yield* leaveIsConfirmed();
|
|
3296
3302
|
yield* stopPorts();
|
|
@@ -4877,6 +4883,20 @@ function chatError(message) {
|
|
|
4877
4883
|
return new SpaceClientError({ code: "chat.payload_invalid", recoverable: false, message });
|
|
4878
4884
|
}
|
|
4879
4885
|
|
|
4886
|
+
// src/space-client/same-identity.ts
|
|
4887
|
+
function otherDevices(participants, participantId, ownIdentityId) {
|
|
4888
|
+
const identityId = ownIdentityId ?? participants.find((item) => item.participantId === participantId)?.identityId;
|
|
4889
|
+
return identityId ? participants.filter((item) => item.participantId !== participantId && item.identityId === identityId) : [];
|
|
4890
|
+
}
|
|
4891
|
+
function otherDeviceHasMicrophone(snapshot, participants) {
|
|
4892
|
+
if (snapshot.control?.status === "ended") return false;
|
|
4893
|
+
const admitted = snapshot.control ? new Set(snapshot.control.participants.map((item) => item.participantId)) : null;
|
|
4894
|
+
const devices = new Set(
|
|
4895
|
+
otherDevices(participants, snapshot.participantId, snapshot.participantIdentityId).filter((item) => !admitted || admitted.has(item.participantId)).map((item) => item.participantId)
|
|
4896
|
+
);
|
|
4897
|
+
return snapshot.media?.items.some((item) => devices.has(item.participantId) && item.source === "microphone" && item.enabled) ?? false;
|
|
4898
|
+
}
|
|
4899
|
+
|
|
4880
4900
|
// src/space-client/media-controller.ts
|
|
4881
4901
|
import { Clock as Clock3, Context as Context6, Deferred as Deferred3, Effect as Effect5, Exit as Exit2, Layer as Layer6, Semaphore } from "effect";
|
|
4882
4902
|
|
|
@@ -5012,6 +5032,7 @@ var MediaControllerRuntime = class {
|
|
|
5012
5032
|
#unsubscribePorts = null;
|
|
5013
5033
|
#microphoneWatch = null;
|
|
5014
5034
|
#projection;
|
|
5035
|
+
#microphoneMutedByOtherDevice = false;
|
|
5015
5036
|
constructor(connection, store, selection, gates, now, fork) {
|
|
5016
5037
|
this.#connection = connection;
|
|
5017
5038
|
this.#store = store;
|
|
@@ -5037,7 +5058,10 @@ var MediaControllerRuntime = class {
|
|
|
5037
5058
|
if (intent.microphone !== void 0) this.#recordIntent("microphone", intent.microphone);
|
|
5038
5059
|
if (intent.camera !== void 0) this.#recordIntent("camera", intent.camera);
|
|
5039
5060
|
}
|
|
5040
|
-
setMicrophoneEnabled = (enabled) =>
|
|
5061
|
+
setMicrophoneEnabled = (enabled) => Effect5.sync(() => {
|
|
5062
|
+
this.#microphoneMutedByOtherDevice = false;
|
|
5063
|
+
this.#publish();
|
|
5064
|
+
}).pipe(Effect5.andThen(this.#set("microphone", enabled)));
|
|
5041
5065
|
setCameraEnabled = (enabled) => this.#set("camera", enabled);
|
|
5042
5066
|
captureCameraPreview = () => this.#cameraSource("preview").pipe(Effect5.mapError(normalizeMediaError));
|
|
5043
5067
|
setScreenShareEnabled = (enabled, options) => enabled ? this.#mediaAction(true, this.#startScreen(options)) : this.#stopScreen();
|
|
@@ -5462,19 +5486,36 @@ var MediaControllerRuntime = class {
|
|
|
5462
5486
|
}
|
|
5463
5487
|
}
|
|
5464
5488
|
startInitial(media, stream) {
|
|
5489
|
+
const waitForSync = Effect5.callback((resume) => {
|
|
5490
|
+
const sync = this.#ports?.sync;
|
|
5491
|
+
if (!sync) return resume(Effect5.void);
|
|
5492
|
+
const check = () => {
|
|
5493
|
+
if (sync.getSnapshot().connection.phase === "live" || media.getSnapshot().connection.phase === "stopped") resume(Effect5.void);
|
|
5494
|
+
};
|
|
5495
|
+
const unsubscribe = sync.subscribe(check);
|
|
5496
|
+
const unsubscribeMedia = media.subscribe(check);
|
|
5497
|
+
check();
|
|
5498
|
+
return Effect5.sync(() => {
|
|
5499
|
+
unsubscribe();
|
|
5500
|
+
unsubscribeMedia();
|
|
5501
|
+
});
|
|
5502
|
+
});
|
|
5465
5503
|
const publish = foreign2(async () => {
|
|
5466
5504
|
const revisions = { microphone: this.#sources.microphone.initialRevision, camera: this.#sources.camera.initialRevision };
|
|
5467
|
-
const tracks = stream.getTracks()
|
|
5468
|
-
|
|
5469
|
-
|
|
5470
|
-
|
|
5471
|
-
|
|
5472
|
-
|
|
5473
|
-
|
|
5474
|
-
|
|
5475
|
-
|
|
5476
|
-
|
|
5477
|
-
|
|
5505
|
+
const tracks = this.#consentedTracks(stream.getTracks());
|
|
5506
|
+
await media.start(
|
|
5507
|
+
streamFromTracks(tracks),
|
|
5508
|
+
() => Effect5.runPromise(
|
|
5509
|
+
waitForSync.pipe(
|
|
5510
|
+
Effect5.map(() => {
|
|
5511
|
+
const snapshot = this.#ports?.sync.getSnapshot();
|
|
5512
|
+
this.#microphoneMutedByOtherDevice = Boolean(snapshot && this.#hasConsent("microphone") && otherDeviceHasMicrophone(snapshot, this.#store.getSnapshot().participants.roster));
|
|
5513
|
+
if (this.#microphoneMutedByOtherDevice) this.#recordIntent("microphone", false);
|
|
5514
|
+
return streamFromTracks(this.#consentedTracks(tracks));
|
|
5515
|
+
})
|
|
5516
|
+
)
|
|
5517
|
+
)
|
|
5518
|
+
);
|
|
5478
5519
|
for (const source of ["microphone", "camera"]) {
|
|
5479
5520
|
const state = this.#sources[source];
|
|
5480
5521
|
if (state.desired.revision === revisions[source]) state.result = { revision: revisions[source], status: "confirmed" };
|
|
@@ -5482,6 +5523,18 @@ var MediaControllerRuntime = class {
|
|
|
5482
5523
|
});
|
|
5483
5524
|
return this.#serialize("microphone", this.#serialize("camera", publish));
|
|
5484
5525
|
}
|
|
5526
|
+
#consentedTracks(tracks) {
|
|
5527
|
+
return tracks.filter((track) => {
|
|
5528
|
+
const source = track.kind === "audio" ? "microphone" : "camera";
|
|
5529
|
+
const enabled = this.#hasConsent(source);
|
|
5530
|
+
track.enabled = enabled;
|
|
5531
|
+
if (!enabled) {
|
|
5532
|
+
this.#deleteTrack(source);
|
|
5533
|
+
if (source === "microphone") track.stop();
|
|
5534
|
+
}
|
|
5535
|
+
return enabled;
|
|
5536
|
+
});
|
|
5537
|
+
}
|
|
5485
5538
|
#send(ports, source, intent, enabled) {
|
|
5486
5539
|
const command = this.#mediaAction(
|
|
5487
5540
|
enabled,
|
|
@@ -5882,8 +5935,8 @@ var MediaControllerRuntime = class {
|
|
|
5882
5935
|
this.#pauseTracks(source);
|
|
5883
5936
|
if (cause === "capture_cleanup" && source !== "screen" && ports.media.pauseLocalCapture) {
|
|
5884
5937
|
state.capturePause = "pending";
|
|
5885
|
-
this.#retainPause(state, ports.media.pauseLocalCapture(source));
|
|
5886
5938
|
this.#notifyCapturePauses(ports);
|
|
5939
|
+
this.#retainPause(state, ports.media.pauseLocalCapture(source));
|
|
5887
5940
|
} else {
|
|
5888
5941
|
ports.media.setLocalSourceIntent?.(source, false, cause);
|
|
5889
5942
|
this.#retainPause(state, this.#beginLocalPause(ports, source, cause));
|
|
@@ -6101,6 +6154,7 @@ var MediaControllerRuntime = class {
|
|
|
6101
6154
|
const remote = Object.freeze((snapshot?.remoteTracks ?? []).map((track) => Object.freeze({ participantId: track.participantId, source: track.source, publicationId: track.publicationId, track: track.track })));
|
|
6102
6155
|
const media = Object.freeze({
|
|
6103
6156
|
...current.media,
|
|
6157
|
+
microphoneMutedByOtherDevice: this.#microphoneMutedByOtherDevice,
|
|
6104
6158
|
local,
|
|
6105
6159
|
remote,
|
|
6106
6160
|
screenShare: {
|
|
@@ -6491,6 +6545,12 @@ var ParticipantsControllerRuntime = class {
|
|
|
6491
6545
|
#unsubscribePorts = null;
|
|
6492
6546
|
#unsubscribe = null;
|
|
6493
6547
|
#unsubscribeMedia = null;
|
|
6548
|
+
#deviceScope = null;
|
|
6549
|
+
// Retain verified seats while the local Sync replica is recovering, and for older servers
|
|
6550
|
+
// whose negotiated hints disappear with sockets. New servers send every admitted seat.
|
|
6551
|
+
#devices = /* @__PURE__ */ new Map();
|
|
6552
|
+
#presenceCursor = null;
|
|
6553
|
+
#invalidatedDevices = /* @__PURE__ */ new Set();
|
|
6494
6554
|
constructor(connection, store, offline) {
|
|
6495
6555
|
this.#offline = offline;
|
|
6496
6556
|
this.#connection = connection;
|
|
@@ -6544,6 +6604,8 @@ var ParticipantsControllerRuntime = class {
|
|
|
6544
6604
|
return ({ sync }) => foreign3(() => sync.setDisplayName(displayName));
|
|
6545
6605
|
});
|
|
6546
6606
|
dispose() {
|
|
6607
|
+
this.#devices.clear();
|
|
6608
|
+
this.#invalidatedDevices.clear();
|
|
6547
6609
|
this.#unsubscribePorts?.();
|
|
6548
6610
|
this.#unsubscribe?.();
|
|
6549
6611
|
this.#unsubscribeMedia?.();
|
|
@@ -6563,6 +6625,10 @@ var ParticipantsControllerRuntime = class {
|
|
|
6563
6625
|
this.#unsubscribe = null;
|
|
6564
6626
|
this.#unsubscribeMedia = null;
|
|
6565
6627
|
if (!ports) {
|
|
6628
|
+
if (["idle", "leaving", "left", "failed"].includes(this.#connection.getSnapshot().state)) {
|
|
6629
|
+
this.#devices.clear();
|
|
6630
|
+
this.#invalidatedDevices.clear();
|
|
6631
|
+
}
|
|
6566
6632
|
this.#publish(null, {});
|
|
6567
6633
|
return;
|
|
6568
6634
|
}
|
|
@@ -6571,11 +6637,57 @@ var ParticipantsControllerRuntime = class {
|
|
|
6571
6637
|
this.#unsubscribeMedia = ports.media.subscribe(publish);
|
|
6572
6638
|
publish();
|
|
6573
6639
|
}
|
|
6640
|
+
#syncDeviceScope() {
|
|
6641
|
+
const subject = this.#connection.getSnapshot().subject;
|
|
6642
|
+
const scope = subject ? JSON.stringify([subject.tenantId, subject.spaceId, subject.episodeId, subject.participantId, subject.participantGeneration]) : null;
|
|
6643
|
+
if (scope !== this.#deviceScope) {
|
|
6644
|
+
this.#devices.clear();
|
|
6645
|
+
this.#invalidatedDevices.clear();
|
|
6646
|
+
}
|
|
6647
|
+
this.#deviceScope = scope;
|
|
6648
|
+
}
|
|
6649
|
+
#rememberDevices(snapshot) {
|
|
6650
|
+
this.#syncDeviceScope();
|
|
6651
|
+
const control = snapshot?.control;
|
|
6652
|
+
if (!control) return;
|
|
6653
|
+
this.#pruneDevices(control, snapshot.presence);
|
|
6654
|
+
const retained = /* @__PURE__ */ new Map();
|
|
6655
|
+
if (control.status !== "ended") {
|
|
6656
|
+
for (const participant of control.participants) {
|
|
6657
|
+
const device = this.#deviceFor(participant, snapshot.presence?.items ?? []);
|
|
6658
|
+
if (device) retained.set(participant.participantId, device);
|
|
6659
|
+
}
|
|
6660
|
+
}
|
|
6661
|
+
this.#devices = retained;
|
|
6662
|
+
}
|
|
6663
|
+
#pruneDevices(control, presence) {
|
|
6664
|
+
const cursor = presence ? JSON.stringify([presence.projectionId, presence.sequence]) : null;
|
|
6665
|
+
if (cursor !== this.#presenceCursor) this.#invalidatedDevices.clear();
|
|
6666
|
+
this.#presenceCursor = cursor;
|
|
6667
|
+
for (const [id, device] of this.#devices) {
|
|
6668
|
+
if (!control.participants.some((participant) => participant.participantId === id && participant.admissionRevision === device.admissionRevision)) this.#invalidatedDevices.add(id);
|
|
6669
|
+
}
|
|
6670
|
+
}
|
|
6671
|
+
#deviceFor(participant, presence) {
|
|
6672
|
+
const previous = this.#devices.get(participant.participantId);
|
|
6673
|
+
const known = previous && previous.admissionRevision === participant.admissionRevision ? previous : {};
|
|
6674
|
+
const hint = this.#hintFor(participant, presence) ?? {};
|
|
6675
|
+
const identityId = hint.identityId ?? known.identityId;
|
|
6676
|
+
return identityId ? { admissionRevision: participant.admissionRevision, identityId, deviceType: hint.deviceType ?? known.deviceType } : void 0;
|
|
6677
|
+
}
|
|
6678
|
+
#hintFor(participant, presence) {
|
|
6679
|
+
return presence.find((item) => {
|
|
6680
|
+
if (item.participantId !== participant.participantId) return false;
|
|
6681
|
+
if (item.admissionRevision !== void 0) return item.admissionRevision === participant.admissionRevision;
|
|
6682
|
+
return !this.#invalidatedDevices.has(participant.participantId);
|
|
6683
|
+
});
|
|
6684
|
+
}
|
|
6574
6685
|
#publish(snapshot, collaborationCapabilities, media) {
|
|
6686
|
+
this.#rememberDevices(snapshot);
|
|
6575
6687
|
if (snapshot && !controlFor(snapshot)) return;
|
|
6576
6688
|
const audioParticipants = new Set(media?.remoteTracks.filter((track) => track.source === "screen_audio" && track.track.readyState === "live").map((track) => track.participantId));
|
|
6577
6689
|
if (snapshot?.participantId && media?.localTracks.some((track) => track.source === "screen_audio" && track.enabled && track.track.readyState === "live")) audioParticipants.add(snapshot.participantId);
|
|
6578
|
-
const projected = participantsFor(snapshot, collaborationCapabilities);
|
|
6690
|
+
const projected = participantsFor(snapshot, collaborationCapabilities, this.#devices);
|
|
6579
6691
|
const participants = Object.freeze({
|
|
6580
6692
|
...projected,
|
|
6581
6693
|
roster: Object.freeze(projected.roster.map((participant) => Object.freeze({ ...participant, media: Object.freeze({ ...participant.media, screenShareHasAudio: participant.media.screenShare === "active" && audioParticipants.has(participant.participantId) }) })))
|
|
@@ -6601,10 +6713,10 @@ function invalid(message) {
|
|
|
6601
6713
|
function directed(result) {
|
|
6602
6714
|
return Object.freeze({ status: result.result, requestId: result.request_id });
|
|
6603
6715
|
}
|
|
6604
|
-
function participantsFor(snapshot, collaborationCapabilities) {
|
|
6716
|
+
function participantsFor(snapshot, collaborationCapabilities, devices) {
|
|
6605
6717
|
const control = controlFor(snapshot);
|
|
6606
|
-
if (!control) return EMPTY_PARTICIPANTS;
|
|
6607
|
-
return Object.freeze({ roster: rosterFor(control.participants, collaborationCapabilities, mediaFor(snapshot), presenceFor(snapshot)), admissionQueue: admissionQueueFor(control.admissionRequests) });
|
|
6718
|
+
if (!control || control.status === "ended") return EMPTY_PARTICIPANTS;
|
|
6719
|
+
return Object.freeze({ roster: rosterFor(control.participants, collaborationCapabilities, mediaFor(snapshot), presenceFor(snapshot), devices), admissionQueue: admissionQueueFor(control.admissionRequests) });
|
|
6608
6720
|
}
|
|
6609
6721
|
function controlFor(snapshot) {
|
|
6610
6722
|
if (!snapshot) return null;
|
|
@@ -6618,11 +6730,13 @@ function mediaFor(snapshot) {
|
|
|
6618
6730
|
function presenceFor(snapshot) {
|
|
6619
6731
|
return snapshot?.presence ?? null;
|
|
6620
6732
|
}
|
|
6621
|
-
function rosterFor(participants, collaborationCapabilities, media, presence) {
|
|
6733
|
+
function rosterFor(participants, collaborationCapabilities, media, presence, devices) {
|
|
6622
6734
|
return Object.freeze(
|
|
6623
6735
|
participants.map(
|
|
6624
6736
|
(participant) => Object.freeze({
|
|
6625
6737
|
participantId: participant.participantId,
|
|
6738
|
+
identityId: devices.get(participant.participantId)?.identityId,
|
|
6739
|
+
deviceType: devices.get(participant.participantId)?.deviceType,
|
|
6626
6740
|
displayName: participant.displayName,
|
|
6627
6741
|
role: participant.role,
|
|
6628
6742
|
eligibleRoles: Object.freeze([...participant.eligibleRoles]),
|
|
@@ -6644,13 +6758,20 @@ function admissionQueueFor(requests) {
|
|
|
6644
6758
|
function selfFor(snapshot, roster) {
|
|
6645
6759
|
const participantId = snapshot?.participantId ?? null;
|
|
6646
6760
|
const participant = roster.find((candidate) => candidate.participantId === participantId);
|
|
6647
|
-
|
|
6761
|
+
const identityId = selfIdentityFor(snapshot, participant);
|
|
6762
|
+
if (!participant) return emptySelf(participantId, identityId);
|
|
6648
6763
|
const capabilities = participant.capabilities;
|
|
6649
6764
|
const allowed = new Set(capabilities);
|
|
6650
|
-
return Object.freeze({ participantId, displayName: participant.displayName, role: participant.role, capabilities, handRaised: participant.handRaised, can: (capability) => allowed.has(capability) });
|
|
6765
|
+
return Object.freeze({ participantId, identityId, displayName: participant.displayName, role: participant.role, capabilities, handRaised: participant.handRaised, can: (capability) => allowed.has(capability) });
|
|
6766
|
+
}
|
|
6767
|
+
function selfIdentityFor(snapshot, participant) {
|
|
6768
|
+
if (!snapshot) return void 0;
|
|
6769
|
+
if (snapshot.connection.phase === "terminal") return void 0;
|
|
6770
|
+
if (snapshot.control?.status === "ended") return void 0;
|
|
6771
|
+
return snapshot.participantIdentityId ?? participant?.identityId;
|
|
6651
6772
|
}
|
|
6652
|
-
function emptySelf(participantId) {
|
|
6653
|
-
return Object.freeze({ participantId, displayName: null, role: null, capabilities: Object.freeze([]), handRaised: false, can: () => false });
|
|
6773
|
+
function emptySelf(participantId, identityId) {
|
|
6774
|
+
return Object.freeze({ participantId, identityId, displayName: null, role: null, capabilities: Object.freeze([]), handRaised: false, can: () => false });
|
|
6654
6775
|
}
|
|
6655
6776
|
function capabilitiesFor(control, collaboration) {
|
|
6656
6777
|
const capabilities = /* @__PURE__ */ new Set();
|
|
@@ -6684,10 +6805,10 @@ function sameParticipantMedia(left, right) {
|
|
|
6684
6805
|
return left.media.microphone === right.media.microphone && left.media.camera === right.media.camera && left.media.screenShare === right.media.screenShare && left.media.screenShareHasAudio === right.media.screenShareHasAudio;
|
|
6685
6806
|
}
|
|
6686
6807
|
function sameParticipantPresence(left, right) {
|
|
6687
|
-
return left.presence.state === right.presence.state && left.presence.speaking === right.presence.speaking && left.presence.activeSpeaker === right.presence.activeSpeaker;
|
|
6808
|
+
return left.identityId === right.identityId && left.deviceType === right.deviceType && left.presence.state === right.presence.state && left.presence.speaking === right.presence.speaking && left.presence.activeSpeaker === right.presence.activeSpeaker;
|
|
6688
6809
|
}
|
|
6689
6810
|
function sameSelf(left, right) {
|
|
6690
|
-
return left.participantId === right.participantId && left.displayName === right.displayName && left.role === right.role && left.handRaised === right.handRaised && sameValues(left.capabilities, right.capabilities);
|
|
6811
|
+
return left.participantId === right.participantId && left.identityId === right.identityId && left.displayName === right.displayName && left.role === right.role && left.handRaised === right.handRaised && sameValues(left.capabilities, right.capabilities);
|
|
6691
6812
|
}
|
|
6692
6813
|
function sameArray(left, right, equal) {
|
|
6693
6814
|
return left.length === right.length && left.every((value, index) => equal(value, right[index]));
|
|
@@ -84,6 +84,7 @@ var AccessGrantSchema = Schema.Struct({
|
|
|
84
84
|
});
|
|
85
85
|
var AdmitEpisodeParticipantRequestSchema = Schema.Struct({
|
|
86
86
|
admission: Schema.optional(Schema.Literals(["policy", "direct"])),
|
|
87
|
+
identity_external_id: Schema.optional(Schema.String.check(Schema.isMinLength(1), Schema.isMaxLength(256))),
|
|
87
88
|
identity_id: Schema.optional(UUIDSchema),
|
|
88
89
|
metadata: Schema.optional(Schema.Unknown),
|
|
89
90
|
name: Schema.String.check(Schema.isMinLength(1)),
|
|
@@ -1125,7 +1126,8 @@ var AddCloudflareSFUTracksQueryParamsSchema = Schema.Struct({
|
|
|
1125
1126
|
"local_signaling_failure",
|
|
1126
1127
|
"remote_signaling_failure",
|
|
1127
1128
|
"dormant_connection",
|
|
1128
|
-
"access_refresh"
|
|
1129
|
+
"access_refresh",
|
|
1130
|
+
"receive_stalled"
|
|
1129
1131
|
])
|
|
1130
1132
|
)
|
|
1131
1133
|
});
|
|
@@ -861,7 +861,8 @@ function strictEvent(value) {
|
|
|
861
861
|
}
|
|
862
862
|
function strictProjectionItem(value, stream) {
|
|
863
863
|
if (stream === "media") return exactObject(value, ["participant_id", "source", "enabled", "publication_id"]);
|
|
864
|
-
if (stream === "presence")
|
|
864
|
+
if (stream === "presence")
|
|
865
|
+
return isObject(value) && exactObject(value, [...["participant_id", "state", "speaking", "active_speaker"], ...Object.hasOwn(value, "identity_id") ? ["identity_id"] : [], ...Object.hasOwn(value, "device_type") ? ["device_type"] : [], ...Object.hasOwn(value, "admission_revision") ? ["admission_revision"] : []]);
|
|
865
866
|
return false;
|
|
866
867
|
}
|
|
867
868
|
function strictProjection(value) {
|
|
@@ -873,7 +874,13 @@ function strictWelcome(value) {
|
|
|
873
874
|
const extension = Array.isArray(value.extensions) && value.extensions.length === 1 ? value.extensions[0] : void 0;
|
|
874
875
|
const extensionValid = isObject(extension) && ["collaboration_v1", "collaboration_v2"].includes(String(extension.name)) && exactObject(extension, ["name", "capabilities", "participant_capabilities", "chat_head_sequence", "retained_floor_sequence", "read_receipts"]) && Array.isArray(extension.read_receipts);
|
|
875
876
|
if (Object.hasOwn(value, "entry_confirmation") && value.entry_confirmation !== true) return false;
|
|
876
|
-
const fields = [
|
|
877
|
+
const fields = [
|
|
878
|
+
...base,
|
|
879
|
+
...extensionValid ? ["extensions"] : [],
|
|
880
|
+
...Object.hasOwn(value, "entry_confirmation") ? ["entry_confirmation"] : [],
|
|
881
|
+
...Object.hasOwn(value, "entry_generation") ? ["entry_generation"] : [],
|
|
882
|
+
...Object.hasOwn(value, "participant_identity_id") ? ["participant_identity_id"] : []
|
|
883
|
+
];
|
|
877
884
|
if (!strictCursor(value.head)) return false;
|
|
878
885
|
if (value.mode === "snapshot") return exactObjectWithCorrelation(value, [...fields, "snapshot"]) && strictSnapshot(value.snapshot);
|
|
879
886
|
if (value.mode === "terminal") return exactObjectWithCorrelation(value, [...fields, "reason"]);
|
|
@@ -1479,6 +1486,7 @@ var WelcomeBase = {
|
|
|
1479
1486
|
protocol: Schema.Literal(1),
|
|
1480
1487
|
participant_id: UuidSchema,
|
|
1481
1488
|
participant_generation: PositiveIntegerSchema,
|
|
1489
|
+
participant_identity_id: Schema.optionalKey(UuidSchema),
|
|
1482
1490
|
recovery_id: UuidSchema,
|
|
1483
1491
|
head: ControlCursorSchema,
|
|
1484
1492
|
entry_confirmation: Schema.optionalKey(Schema.Literal(true)),
|
|
@@ -1527,9 +1535,15 @@ var CommandIdConflictAckFrameSchema = Schema.Struct({ type: Schema.Literal("ack"
|
|
|
1527
1535
|
var MediaProjectionItemSchema = Schema.Struct({ participant_id: UuidSchema, source: Schema.Union([Schema.Literal("microphone"), Schema.Literal("camera"), Schema.Literal("screen")]), enabled: Schema.Boolean, publication_id: Schema.NullOr(boundedUtf8String(256, 1)) }).check(
|
|
1528
1536
|
Schema.makeFilter((item) => !item.enabled || item.publication_id !== null ? void 0 : { path: [], issue: "enabled requires a publication_id" })
|
|
1529
1537
|
);
|
|
1530
|
-
var PresenceProjectionItemSchema = Schema.Struct({
|
|
1531
|
-
|
|
1532
|
-
)
|
|
1538
|
+
var PresenceProjectionItemSchema = Schema.Struct({
|
|
1539
|
+
participant_id: UuidSchema,
|
|
1540
|
+
state: Schema.Union([Schema.Literal("connected"), Schema.Literal("disconnected")]),
|
|
1541
|
+
speaking: Schema.Boolean,
|
|
1542
|
+
active_speaker: Schema.Boolean,
|
|
1543
|
+
identity_id: Schema.optional(UuidSchema),
|
|
1544
|
+
device_type: Schema.optional(Schema.Literals(["phone", "tablet", "computer"])),
|
|
1545
|
+
admission_revision: Schema.optional(PositiveIntegerSchema)
|
|
1546
|
+
}).check(Schema.makeFilter((item) => item.state !== "disconnected" || !item.speaking && !item.active_speaker ? void 0 : { path: [], issue: "disconnected presence cannot be speaking or active speaker" }));
|
|
1533
1547
|
var MediaProjectionSnapshotFrameSchema = Schema.Struct({
|
|
1534
1548
|
type: Schema.Literal("projection_snapshot"),
|
|
1535
1549
|
stream: Schema.Literal("media"),
|
|
@@ -3016,6 +3030,7 @@ var V1SyncClient = class {
|
|
|
3016
3030
|
#presence = null;
|
|
3017
3031
|
#participantId = null;
|
|
3018
3032
|
#participantGeneration = null;
|
|
3033
|
+
#participantIdentityId;
|
|
3019
3034
|
#entryGeneration = null;
|
|
3020
3035
|
#recovery = null;
|
|
3021
3036
|
#snapshotRecoveryRequested = false;
|
|
@@ -3136,6 +3151,7 @@ var V1SyncClient = class {
|
|
|
3136
3151
|
this.#socket?.close(1e3, "client stopped");
|
|
3137
3152
|
this.#socket = null;
|
|
3138
3153
|
this.#phase = { phase: "stopped" };
|
|
3154
|
+
this.#options.mediaPlane?.remotePublicationsChanged?.([], "unavailable");
|
|
3139
3155
|
this.#rejectEphemeral("client_stopped");
|
|
3140
3156
|
this.#collaborationState.disconnect("client_stopped");
|
|
3141
3157
|
this.#localPublications = [];
|
|
@@ -3164,6 +3180,7 @@ var V1SyncClient = class {
|
|
|
3164
3180
|
},
|
|
3165
3181
|
participantId: this.#participantId,
|
|
3166
3182
|
participantGeneration: this.#participantGeneration,
|
|
3183
|
+
participantIdentityId: this.#participantIdentityId,
|
|
3167
3184
|
control: this.#control,
|
|
3168
3185
|
optimisticControl,
|
|
3169
3186
|
media: copyProjection(this.#media),
|
|
@@ -3183,6 +3200,7 @@ var V1SyncClient = class {
|
|
|
3183
3200
|
return () => this.#mediaPauseListeners.delete(listener);
|
|
3184
3201
|
}
|
|
3185
3202
|
#notifyMediaPause(event) {
|
|
3203
|
+
if (event.name === "episode_ended") this.#options.mediaPlane?.remotePublicationsChanged?.([]);
|
|
3186
3204
|
const source = event.name === "participant_microphone_stopped" ? "microphone" : event.name === "participant_camera_stopped" ? "camera" : event.name === "participant_screen_share_stopped" ? "screen" : null;
|
|
3187
3205
|
if (source && "participant_id" in event.payload && event.payload.participant_id === this.#participantId) {
|
|
3188
3206
|
for (const listener of this.#mediaPauseListeners) listener({ source, revision: event.revision });
|
|
@@ -3444,6 +3462,7 @@ var V1SyncClient = class {
|
|
|
3444
3462
|
const control = this.#requireControl();
|
|
3445
3463
|
this.#send({ type: "delivery_ack", stream: "control", revision: control.revision, state_digest: control.stateDigest });
|
|
3446
3464
|
}
|
|
3465
|
+
if (this.#control?.status === "ended" || frame.name === "participant_left" && frame.payload.participant_id === this.#participantId) this.#participantIdentityId = void 0;
|
|
3447
3466
|
if (frame.name === "participant_left" && frame.payload.participant_id === this.#participantId) {
|
|
3448
3467
|
this.#phase = { phase: "terminal", terminalReason: frame.payload.reason === "removed" ? "participant_removed" : "participant_inactive" };
|
|
3449
3468
|
this.#socket?.close(1e3, "participant inactive");
|
|
@@ -3534,6 +3553,7 @@ var V1SyncClient = class {
|
|
|
3534
3553
|
this.#entryGeneration = frame.entry_generation ?? this.#entryGeneration;
|
|
3535
3554
|
this.#participantId = frame.participant_id;
|
|
3536
3555
|
this.#participantGeneration = frame.participant_generation;
|
|
3556
|
+
this.#participantIdentityId = frame.mode === "terminal" ? void 0 : frame.participant_identity_id;
|
|
3537
3557
|
this.#updateLocalMediaStates();
|
|
3538
3558
|
if (frame.mode === "terminal") {
|
|
3539
3559
|
await this.#commandScheduler.settleTerminalRecovery(frame);
|
|
@@ -3547,6 +3567,7 @@ var V1SyncClient = class {
|
|
|
3547
3567
|
const control = await restoreV1Snapshot(frame.snapshot);
|
|
3548
3568
|
if (!sameHead(control, frame.head)) throw new V1ReplicaError("snapshot head mismatch");
|
|
3549
3569
|
this.#control = control;
|
|
3570
|
+
if (control.status === "ended") this.#options.mediaPlane?.remotePublicationsChanged?.([]);
|
|
3550
3571
|
this.#snapshotRevision = control.revision;
|
|
3551
3572
|
this.#snapshotRecoveryRequested = false;
|
|
3552
3573
|
this.#controlHeads.clear();
|
|
@@ -3592,7 +3613,7 @@ var V1SyncClient = class {
|
|
|
3592
3613
|
previous.find((candidate) => mediaKey(candidate) === mediaKey(item)),
|
|
3593
3614
|
item
|
|
3594
3615
|
);
|
|
3595
|
-
if (!this.#mediaEnded()) this.#options.mediaPlane?.remotePublicationsChanged?.();
|
|
3616
|
+
if (!this.#mediaEnded()) this.#options.mediaPlane?.remotePublicationsChanged?.(this.#media?.items ?? []);
|
|
3596
3617
|
} else {
|
|
3597
3618
|
this.#presence = { projectionId: frame.projection_id, sequence: 0, items: frame.items.map(presenceItem) };
|
|
3598
3619
|
this.#presenceEventEvidence.clear();
|
|
@@ -3611,7 +3632,7 @@ var V1SyncClient = class {
|
|
|
3611
3632
|
rememberBoundedEvidence(this.#mediaEventEvidence, frame.sequence, frameSignature(frame), MAX_PROJECTION_EVENT_EVIDENCE);
|
|
3612
3633
|
this.#notifyRemotePublicationResumed(previous, item);
|
|
3613
3634
|
if (!this.#mediaEnded() && item.participantId !== this.#participantId && (previous?.enabled !== item.enabled || previous?.publicationId !== item.publicationId)) {
|
|
3614
|
-
this.#options.mediaPlane?.remotePublicationsChanged?.();
|
|
3635
|
+
this.#options.mediaPlane?.remotePublicationsChanged?.(this.#media?.items ?? []);
|
|
3615
3636
|
}
|
|
3616
3637
|
} else {
|
|
3617
3638
|
if (this.#acceptProjectionDuplicate(this.#presence, this.#presenceEventEvidence, frame)) return;
|
|
@@ -3694,6 +3715,7 @@ var V1SyncClient = class {
|
|
|
3694
3715
|
this.#commandScheduler.disconnect();
|
|
3695
3716
|
this.#media = null;
|
|
3696
3717
|
this.#presence = null;
|
|
3718
|
+
this.#options.mediaPlane?.remotePublicationsChanged?.([], this.#mediaEnded() ? "available" : "unavailable");
|
|
3697
3719
|
this.#rejectRequests("disconnected_before_delivery");
|
|
3698
3720
|
this.#collaborationState.disconnect("disconnected_before_delivery");
|
|
3699
3721
|
if (!this.#started || this.#phase.phase === "terminal") return;
|
|
@@ -3900,7 +3922,7 @@ function mediaItem(item) {
|
|
|
3900
3922
|
return { participantId: item.participant_id, source: item.source, enabled: item.enabled, publicationId: item.publication_id };
|
|
3901
3923
|
}
|
|
3902
3924
|
function presenceItem(item) {
|
|
3903
|
-
return { participantId: item.participant_id, state: item.state, speaking: item.speaking, activeSpeaker: item.active_speaker };
|
|
3925
|
+
return { participantId: item.participant_id, admissionRevision: item.admission_revision, identityId: item.identity_id, deviceType: item.device_type, state: item.state, speaking: item.speaking, activeSpeaker: item.active_speaker };
|
|
3904
3926
|
}
|
|
3905
3927
|
function mediaKey(item) {
|
|
3906
3928
|
return `${item.participantId}:${item.source}`;
|
|
@@ -3928,6 +3950,8 @@ function validMediaPublication(publication) {
|
|
|
3928
3950
|
}
|
|
3929
3951
|
function entryUrl(value, generation, confirmation) {
|
|
3930
3952
|
const url = new URL(value);
|
|
3953
|
+
url.searchParams.set("participant_devices", "1");
|
|
3954
|
+
url.searchParams.set("participant_device_admissions", "2");
|
|
3931
3955
|
url.searchParams.set("entry_generation", generation === null ? "new" : String(generation));
|
|
3932
3956
|
if (confirmation) url.searchParams.set("entry_confirmation", "1");
|
|
3933
3957
|
return url.toString();
|
package/dist/client.d.ts
CHANGED
|
@@ -23,7 +23,7 @@ export declare const createChalkEffectClient: (options: ChalkEffectClientOptions
|
|
|
23
23
|
readonly tenant_id: import("effect/Schema").brand<import("effect/Schema").String, "TenantId">;
|
|
24
24
|
}>>, import("effect/Schema").toCodecStringTree<import("effect/Schema").Struct<{
|
|
25
25
|
readonly allow_partial_remote_tracks: import("effect/Schema").optional<import("effect/Schema").Boolean>;
|
|
26
|
-
readonly replacement_cause: import("effect/Schema").optional<import("effect/Schema").Literals<readonly ["user_pause", "moderation_pause", "sync_recovery_loss", "discovery_absent", "capture_cleanup", "consent_revoked", "publish_failure", "enable_failure", "projection_mismatch", "forced_pause", "local_signaling_failure", "remote_signaling_failure", "dormant_connection", "access_refresh"]>>;
|
|
26
|
+
readonly replacement_cause: import("effect/Schema").optional<import("effect/Schema").Literals<readonly ["user_pause", "moderation_pause", "sync_recovery_loss", "discovery_absent", "capture_cleanup", "consent_revoked", "publish_failure", "enable_failure", "projection_mismatch", "forced_pause", "local_signaling_failure", "remote_signaling_failure", "dormant_connection", "access_refresh", "receive_stalled"]>>;
|
|
27
27
|
}>>, import("effect/Schema").toCodecJson<import("effect/Schema").Struct<{
|
|
28
28
|
readonly connection_id: import("effect/Schema").String;
|
|
29
29
|
readonly session_description: import("effect/Schema").optional<import("effect/Schema").NullOr<import("effect/Schema").Struct<{
|
|
@@ -2478,6 +2478,7 @@ export declare const createChalkEffectClient: (options: ChalkEffectClientOptions
|
|
|
2478
2478
|
readonly tenant_id: import("effect/Schema").brand<import("effect/Schema").String, "TenantId">;
|
|
2479
2479
|
}>>, never, import("effect/Schema").toCodecJson<import("effect/Schema").Struct<{
|
|
2480
2480
|
readonly admission: import("effect/Schema").optional<import("effect/Schema").Literals<readonly ["policy", "direct"]>>;
|
|
2481
|
+
readonly identity_external_id: import("effect/Schema").optional<import("effect/Schema").String>;
|
|
2481
2482
|
readonly identity_id: import("effect/Schema").optional<import("effect/Schema").brand<import("effect/Schema").String, "UUID">>;
|
|
2482
2483
|
readonly metadata: import("effect/Schema").optional<import("effect/Schema").Unknown>;
|
|
2483
2484
|
readonly name: import("effect/Schema").String;
|
|
@@ -68,7 +68,8 @@ export type ConnectionSyncClient = V1CollaborationClient & {
|
|
|
68
68
|
readonly requestStartCamera: (participantId: string) => Promise<V1DirectedRequestResult>;
|
|
69
69
|
};
|
|
70
70
|
export type ConnectionMediaClient = ClientMediaPlane & {
|
|
71
|
-
|
|
71
|
+
/** Starts receiving immediately; resolves the optional initial publication policy before sending. */
|
|
72
|
+
readonly start: (stream: MediaStream, beforePublish?: () => Promise<MediaStream>) => Promise<void>;
|
|
72
73
|
readonly stop: () => void;
|
|
73
74
|
readonly restart: (input: CloudflareSFUBootstrap | ParticipantMediaAccess) => Promise<void>;
|
|
74
75
|
readonly prepareLocalTrack: (source: "microphone" | "camera" | "screen" | "screen_audio", track: MediaStreamTrack) => void;
|
package/dist/effect.js
CHANGED
|
@@ -17,8 +17,8 @@ import {
|
|
|
17
17
|
makeSpaceClientCoreLayer,
|
|
18
18
|
makeSpaceClientCoreLayerFromServices,
|
|
19
19
|
makeSpaceStoreLayer
|
|
20
|
-
} from "./chunk-
|
|
21
|
-
import "./chunk-
|
|
20
|
+
} from "./chunk-DHUHTIU7.js";
|
|
21
|
+
import "./chunk-3TGVTP6Z.js";
|
|
22
22
|
import {
|
|
23
23
|
APIKeyListSchema,
|
|
24
24
|
APIKeyWithSecretSchema,
|
|
@@ -841,8 +841,8 @@ import {
|
|
|
841
841
|
WhiteboardStorageUnavailableErrorSchema,
|
|
842
842
|
WhiteboardStorageUnavailableErrorWireSchema,
|
|
843
843
|
createChalkEffectClient
|
|
844
|
-
} from "./chunk-
|
|
845
|
-
import "./chunk-
|
|
844
|
+
} from "./chunk-GOSWSXTH.js";
|
|
845
|
+
import "./chunk-XSB2GDRW.js";
|
|
846
846
|
|
|
847
847
|
// src/space-client/effect.ts
|
|
848
848
|
import { Context, Effect, Exit, Layer, Scope } from "effect";
|
|
@@ -7,7 +7,7 @@ declare const ChalkApi_base: HttpApi.HttpApi<"ChalkApi", HttpApiGroup.HttpApiGro
|
|
|
7
7
|
readonly tenant_id: import("effect/Schema").brand<import("effect/Schema").String, "TenantId">;
|
|
8
8
|
}>>, import("effect/Schema").toCodecStringTree<import("effect/Schema").Struct<{
|
|
9
9
|
readonly allow_partial_remote_tracks: import("effect/Schema").optional<import("effect/Schema").Boolean>;
|
|
10
|
-
readonly replacement_cause: import("effect/Schema").optional<import("effect/Schema").Literals<readonly ["user_pause", "moderation_pause", "sync_recovery_loss", "discovery_absent", "capture_cleanup", "consent_revoked", "publish_failure", "enable_failure", "projection_mismatch", "forced_pause", "local_signaling_failure", "remote_signaling_failure", "dormant_connection", "access_refresh"]>>;
|
|
10
|
+
readonly replacement_cause: import("effect/Schema").optional<import("effect/Schema").Literals<readonly ["user_pause", "moderation_pause", "sync_recovery_loss", "discovery_absent", "capture_cleanup", "consent_revoked", "publish_failure", "enable_failure", "projection_mismatch", "forced_pause", "local_signaling_failure", "remote_signaling_failure", "dormant_connection", "access_refresh", "receive_stalled"]>>;
|
|
11
11
|
}>>, import("effect/Schema").toCodecJson<import("effect/Schema").Struct<{
|
|
12
12
|
readonly connection_id: import("effect/Schema").String;
|
|
13
13
|
readonly session_description: import("effect/Schema").optional<import("effect/Schema").NullOr<import("effect/Schema").Struct<{
|
|
@@ -2434,6 +2434,7 @@ declare const ChalkApi_base: HttpApi.HttpApi<"ChalkApi", HttpApiGroup.HttpApiGro
|
|
|
2434
2434
|
readonly tenant_id: import("effect/Schema").brand<import("effect/Schema").String, "TenantId">;
|
|
2435
2435
|
}>>, never, import("effect/Schema").toCodecJson<import("effect/Schema").Struct<{
|
|
2436
2436
|
readonly admission: import("effect/Schema").optional<import("effect/Schema").Literals<readonly ["policy", "direct"]>>;
|
|
2437
|
+
readonly identity_external_id: import("effect/Schema").optional<import("effect/Schema").String>;
|
|
2437
2438
|
readonly identity_id: import("effect/Schema").optional<import("effect/Schema").brand<import("effect/Schema").String, "UUID">>;
|
|
2438
2439
|
readonly metadata: import("effect/Schema").optional<import("effect/Schema").Unknown>;
|
|
2439
2440
|
readonly name: import("effect/Schema").String;
|
|
@@ -89,6 +89,7 @@ export declare const AccessGrantSchema: Schema.Struct<{
|
|
|
89
89
|
export type AccessGrant = typeof AccessGrantSchema.Type;
|
|
90
90
|
export declare const AdmitEpisodeParticipantRequestSchema: Schema.Struct<{
|
|
91
91
|
readonly admission: Schema.optional<Schema.Literals<readonly ["policy", "direct"]>>;
|
|
92
|
+
readonly identity_external_id: Schema.optional<Schema.String>;
|
|
92
93
|
readonly identity_id: Schema.optional<Schema.brand<Schema.String, "UUID">>;
|
|
93
94
|
readonly metadata: Schema.optional<Schema.Unknown>;
|
|
94
95
|
readonly name: Schema.String;
|
|
@@ -1358,7 +1359,7 @@ export declare const AddCloudflareSFUTracksPathParamsSchema: Schema.Struct<{
|
|
|
1358
1359
|
export type AddCloudflareSFUTracksPathParams = typeof AddCloudflareSFUTracksPathParamsSchema.Type;
|
|
1359
1360
|
export declare const AddCloudflareSFUTracksQueryParamsSchema: Schema.Struct<{
|
|
1360
1361
|
readonly allow_partial_remote_tracks: Schema.optional<Schema.Boolean>;
|
|
1361
|
-
readonly replacement_cause: Schema.optional<Schema.Literals<readonly ["user_pause", "moderation_pause", "sync_recovery_loss", "discovery_absent", "capture_cleanup", "consent_revoked", "publish_failure", "enable_failure", "projection_mismatch", "forced_pause", "local_signaling_failure", "remote_signaling_failure", "dormant_connection", "access_refresh"]>>;
|
|
1362
|
+
readonly replacement_cause: Schema.optional<Schema.Literals<readonly ["user_pause", "moderation_pause", "sync_recovery_loss", "discovery_absent", "capture_cleanup", "consent_revoked", "publish_failure", "enable_failure", "projection_mismatch", "forced_pause", "local_signaling_failure", "remote_signaling_failure", "dormant_connection", "access_refresh", "receive_stalled"]>>;
|
|
1362
1363
|
}>;
|
|
1363
1364
|
export type AddCloudflareSFUTracksQueryParams = typeof AddCloudflareSFUTracksQueryParamsSchema.Type;
|
|
1364
1365
|
export declare const AddCloudflareSFUTracksRequestBodySchema: Schema.Struct<{
|
|
@@ -1426,6 +1427,7 @@ export declare const AdmitEpisodeParticipantRequestHeadersSchema: Schema.Struct<
|
|
|
1426
1427
|
export type AdmitEpisodeParticipantRequestHeaders = typeof AdmitEpisodeParticipantRequestHeadersSchema.Type;
|
|
1427
1428
|
export declare const AdmitEpisodeParticipantRequestBodySchema: Schema.Struct<{
|
|
1428
1429
|
readonly admission: Schema.optional<Schema.Literals<readonly ["policy", "direct"]>>;
|
|
1430
|
+
readonly identity_external_id: Schema.optional<Schema.String>;
|
|
1429
1431
|
readonly identity_id: Schema.optional<Schema.brand<Schema.String, "UUID">>;
|
|
1430
1432
|
readonly metadata: Schema.optional<Schema.Unknown>;
|
|
1431
1433
|
readonly name: Schema.String;
|