@q9labsai/chalk-client 5.3.0 → 5.3.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/access/grant.d.ts +2 -0
- package/dist/{chunk-DHUHTIU7.js → chunk-2CEMOTZF.js} +187 -39
- package/dist/{chunk-XSB2GDRW.js → chunk-FD7ZSDTM.js} +71 -18
- package/dist/{chunk-GOSWSXTH.js → chunk-MHJ4UPM3.js} +162 -5
- package/dist/chunk-N4IPKRS6.js +76 -0
- package/dist/{chunk-3TGVTP6Z.js → chunk-O5JB5XVX.js} +609 -25
- package/dist/{chunk-O26BHHMI.js → chunk-VAJ6XNAA.js} +1 -1
- package/dist/client.d.ts +180 -0
- package/dist/effect.js +29 -4
- package/dist/generated/http-api.d.ts +178 -0
- package/dist/generated/schemas.d.ts +287 -0
- package/dist/generated/sync.d.ts +15 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +33 -15
- package/dist/media/call-stats.d.ts +27 -0
- package/dist/media/ice-servers.d.ts +3 -0
- package/dist/media/index.d.ts +2 -0
- package/dist/media/index.js +4 -1
- package/dist/media/receive-stall.d.ts +11 -2
- package/dist/media/types.d.ts +19 -0
- package/dist/media/video-render-size.d.ts +7 -0
- package/dist/media/viewer-layer.d.ts +48 -0
- package/dist/public-invites/index.js +3 -2
- package/dist/server/index.cjs +18 -4
- package/dist/server/index.js +18 -4
- package/dist/session/index.d.ts +18 -0
- package/dist/sync/index.js +2 -1
- package/dist/sync/v1-command-scheduler.d.ts +4 -0
- package/package.json +2 -1
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
sessionBaggage
|
|
3
|
+
} from "./chunk-N4IPKRS6.js";
|
|
4
|
+
|
|
1
5
|
// src/sync/canonical.ts
|
|
2
6
|
var encoder = new TextEncoder();
|
|
3
7
|
function canonicalJson(value) {
|
|
@@ -405,11 +409,20 @@ var SyncProtocolMetadata = {
|
|
|
405
409
|
pattern: "^[a-z][a-z0-9_*\\-/]{0,255}=[\\x21-\\x2b\\x2d-\\x3c\\x3e-\\x7e]{1,256}(,[a-z][a-z0-9_*\\-/]{0,255}=[\\x21-\\x2b\\x2d-\\x3c\\x3e-\\x7e]{1,256})*$"
|
|
406
410
|
}
|
|
407
411
|
},
|
|
412
|
+
helloOnlyFields: {
|
|
413
|
+
baggage: {
|
|
414
|
+
kind: "string",
|
|
415
|
+
minBytes: 47,
|
|
416
|
+
maxBytes: 47,
|
|
417
|
+
format: "w3c-baggage-session-id",
|
|
418
|
+
pattern: "^session\\.id=[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
|
|
419
|
+
}
|
|
420
|
+
},
|
|
408
421
|
acceptedOn: {
|
|
409
422
|
hello: "client-to-server",
|
|
410
423
|
serverFrames: "server-to-client"
|
|
411
424
|
},
|
|
412
|
-
upgradeHeaders: ["x-chalk-journey-id", "traceparent", "tracestate"],
|
|
425
|
+
upgradeHeaders: ["x-chalk-journey-id", "traceparent", "tracestate", "baggage"],
|
|
413
426
|
rule: "propagate_from_first_observed_layer_to_every_downstream_frame"
|
|
414
427
|
},
|
|
415
428
|
externalIntents: [
|
|
@@ -712,7 +725,9 @@ function strictCommand(value) {
|
|
|
712
725
|
function strictCollaborationsHelloExtension(value) {
|
|
713
726
|
return exactObject(value, ["name", "chat_cursor"]) && ["collaboration_v1", "collaboration_v2"].includes(String(value.name)) && exactObject(value.chat_cursor, ["after_sequence", "retained_floor_sequence"]);
|
|
714
727
|
}
|
|
715
|
-
function strictHello(
|
|
728
|
+
function strictHello(hello) {
|
|
729
|
+
const { baggage, ...value } = hello;
|
|
730
|
+
if (baggage !== void 0 && !(typeof baggage === "string" && boundedCorrelationString(baggage, 47, 47) && /^session\.id=[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/u.test(baggage))) return false;
|
|
716
731
|
const base = exactObjectWithCorrelation(value, ["type", "protocol", "token", "streams"]);
|
|
717
732
|
const extended = exactObjectWithCorrelation(value, ["type", "protocol", "token", "streams", "extensions"]) && Array.isArray(value.extensions) && value.extensions.length === 1 && strictCollaborationsHelloExtension(value.extensions[0]);
|
|
718
733
|
if (!base && !extended || !exactObject(value.streams, ["control", "media", "presence", "requests"])) return false;
|
|
@@ -957,9 +972,10 @@ var TraceparentSchema = boundedUtf8String(55, 55).check(
|
|
|
957
972
|
var TracestateSchema = boundedUtf8String(512, 1).check(
|
|
958
973
|
Schema.makeFilter((value) => new RegExp("^[a-z][a-z0-9_*\\-/]{0,255}=[\\x21-\\x2b\\x2d-\\x3c\\x3e-\\x7e]{1,256}(,[a-z][a-z0-9_*\\-/]{0,255}=[\\x21-\\x2b\\x2d-\\x3c\\x3e-\\x7e]{1,256})*$", "u").test(value) ? void 0 : { path: [], issue: "must be a valid bounded W3C tracestate" })
|
|
959
974
|
);
|
|
975
|
+
var BaggageSchema = boundedUtf8String(47, 47).check(Schema.makeFilter((value) => /^session\.id=[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/u.test(value) ? void 0 : { path: [], issue: "must be the single W3C baggage member session.id=<lowercase UUID>" }));
|
|
960
976
|
var SyncCorrelationFieldsSchema = Schema.Struct({ journey_id: Schema.optional(JourneyIdSchema), traceparent: Schema.optional(TraceparentSchema), tracestate: Schema.optional(TracestateSchema) });
|
|
961
|
-
var
|
|
962
|
-
var
|
|
977
|
+
var ServerCorrelationFields = { journey_id: Schema.optional(JourneyIdSchema), traceparent: Schema.optional(TraceparentSchema), tracestate: Schema.optional(TracestateSchema) };
|
|
978
|
+
var HelloCorrelationFields = { ...ServerCorrelationFields, baggage: Schema.optional(BaggageSchema) };
|
|
963
979
|
var StateDigestSchema = Schema.String.check(Schema.makeFilter((value) => /^[0-9a-f]{64}$/u.test(value) ? void 0 : { path: [], issue: "must be a lowercase hexadecimal SHA-256 digest" }));
|
|
964
980
|
var UnsignedDecimalSchema = Schema.String.check(Schema.makeFilter((value) => /^(?:0|[1-9][0-9]*)$/u.test(value) ? void 0 : { path: [], issue: "must be an unsigned decimal integer" }));
|
|
965
981
|
var CommandIdSchema = boundedUtf8String(64).check(Schema.makeFilter((value) => textEncoder.encode(value).byteLength >= 16 ? void 0 : { path: [], issue: "must meet the command ID minimum byte length" }));
|
|
@@ -2528,6 +2544,11 @@ var V1CommandScheduler = class {
|
|
|
2528
2544
|
async acknowledge(frame) {
|
|
2529
2545
|
const deferred = this.#commands.get(frame.command_id);
|
|
2530
2546
|
if (!deferred) return;
|
|
2547
|
+
if (isSatisfiedByInactiveParticipant(frame, deferred.frame)) {
|
|
2548
|
+
const head = this.#options.controlHead();
|
|
2549
|
+
await this.#finishCommand(frame.command_id, { type: "ack", command_id: frame.command_id, delivery: "duplicate", outcome: "satisfied", revision: head.revision, state_digest: head.state_digest });
|
|
2550
|
+
return;
|
|
2551
|
+
}
|
|
2531
2552
|
if (frame.outcome === "rejected" || frame.outcome === "command_id_conflict") {
|
|
2532
2553
|
await this.#finishCommand(frame.command_id, frame);
|
|
2533
2554
|
return;
|
|
@@ -2566,15 +2587,12 @@ var V1CommandScheduler = class {
|
|
|
2566
2587
|
}
|
|
2567
2588
|
}
|
|
2568
2589
|
async settleTerminalRecovery(frame) {
|
|
2569
|
-
const
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
} else if (frame.reason === "participant_inactive") {
|
|
2574
|
-
satisfiedOperations.add("participant_leave");
|
|
2575
|
-
}
|
|
2590
|
+
const satisfies = (operation) => {
|
|
2591
|
+
if (frame.reason === "episode_ended") return operation === "end_episode" || operation === "participant_leave";
|
|
2592
|
+
return frame.reason === "participant_inactive" && inactiveParticipantSatisfies(operation);
|
|
2593
|
+
};
|
|
2576
2594
|
for (const [commandId, deferred] of this.#commands) {
|
|
2577
|
-
if (deferred.frame.type !== "operation" || !
|
|
2595
|
+
if (deferred.frame.type !== "operation" || !satisfies(deferred.frame.name)) continue;
|
|
2578
2596
|
await this.#finishCommand(commandId, {
|
|
2579
2597
|
type: "ack",
|
|
2580
2598
|
command_id: commandId,
|
|
@@ -2744,6 +2762,12 @@ function targetFrame(commandId, command) {
|
|
|
2744
2762
|
return { type: "command", command_id: commandId, name: command.name, payload: command.payload };
|
|
2745
2763
|
}
|
|
2746
2764
|
}
|
|
2765
|
+
function inactiveParticipantSatisfies(operation) {
|
|
2766
|
+
return operation === "participant_leave";
|
|
2767
|
+
}
|
|
2768
|
+
function isSatisfiedByInactiveParticipant(result, command) {
|
|
2769
|
+
return result.outcome === "rejected" && result.reason === "participant_inactive" && command.type === "operation" && inactiveParticipantSatisfies(command.name);
|
|
2770
|
+
}
|
|
2747
2771
|
function isTerminalLifecycleOperation(frame) {
|
|
2748
2772
|
return frame.type === "operation" && (frame.name === "participant_leave" || frame.name === "end_episode");
|
|
2749
2773
|
}
|
|
@@ -3002,6 +3026,7 @@ var MAX_REPLAY_EVENTS = SyncProtocolLimits.completeReplayMaxEvents;
|
|
|
3002
3026
|
var MAX_REPLAY_BYTES = SyncProtocolLimits.completeReplayEncodedBytes;
|
|
3003
3027
|
var MAX_PROJECTION_EVENT_EVIDENCE = 256;
|
|
3004
3028
|
var CLIENT_RESTART_CLOSE_CODE = 4e3;
|
|
3029
|
+
var legacyHelloServers = /* @__PURE__ */ new Set();
|
|
3005
3030
|
var DEFAULT_RECONNECT_DELAY_MS = 250;
|
|
3006
3031
|
var MAX_RECONNECT_DELAY_MS = 5e3;
|
|
3007
3032
|
var FAST_RECONNECT_ATTEMPTS = 8;
|
|
@@ -3052,6 +3077,8 @@ var V1SyncClient = class {
|
|
|
3052
3077
|
return { stage: this.#opened ? "hello" : "upgrade", opened: this.#opened, closeCode: null, closeReason: null, durationMs: Math.max(0, this.#clock().now() - (this.#connectStartedAt ?? this.#clock().now())), attempt: this.#connectAttemptCount };
|
|
3053
3078
|
}
|
|
3054
3079
|
#reconnectAttempt = 0;
|
|
3080
|
+
/** The socket whose hello carried baggage and has not been answered by a welcome yet. */
|
|
3081
|
+
#baggageHelloSocket = null;
|
|
3055
3082
|
#episodeEndTimer;
|
|
3056
3083
|
#heartbeatTimer;
|
|
3057
3084
|
#missedHeartbeats = 0;
|
|
@@ -3082,7 +3109,11 @@ var V1SyncClient = class {
|
|
|
3082
3109
|
isStarted: () => this.#started,
|
|
3083
3110
|
sendIfLive: (frame) => this.#sendIfLive(frame),
|
|
3084
3111
|
stateChanged: () => this.#emit(),
|
|
3085
|
-
ackHeadIsProven: (ack) => this.#ackHeadIsProven(ack)
|
|
3112
|
+
ackHeadIsProven: (ack) => this.#ackHeadIsProven(ack),
|
|
3113
|
+
controlHead: () => {
|
|
3114
|
+
const control = this.#requireControl();
|
|
3115
|
+
return { revision: control.revision, state_digest: control.stateDigest };
|
|
3116
|
+
}
|
|
3086
3117
|
});
|
|
3087
3118
|
this.#liveTargets = new V1LiveTargetCoordinator({
|
|
3088
3119
|
mediaPlane: options.mediaPlane,
|
|
@@ -3373,11 +3404,12 @@ var V1SyncClient = class {
|
|
|
3373
3404
|
this.#clock().setTimeout(() => {
|
|
3374
3405
|
if (connectionGeneration !== this.#connectionGeneration) return;
|
|
3375
3406
|
this.#inbound = this.#inbound.then(() => {
|
|
3407
|
+
const legacyHello = event.code === 1009 && this.#legacyHelloRejected(socket);
|
|
3376
3408
|
if (socket === this.#socket && event.code === 1008 && (event.reason === "" || event.reason === "invalid token" || event.reason === "policy violation" || event.reason === "entry timeout")) {
|
|
3377
3409
|
this.#phase = { phase: "terminal", terminalReason: event.reason === "entry timeout" ? "entry_timeout" : "access_rejected" };
|
|
3378
3410
|
this.#emit();
|
|
3379
3411
|
}
|
|
3380
|
-
this.#disconnected(socket);
|
|
3412
|
+
this.#disconnected(socket, legacyHello);
|
|
3381
3413
|
});
|
|
3382
3414
|
}, 0);
|
|
3383
3415
|
};
|
|
@@ -3394,10 +3426,12 @@ var V1SyncClient = class {
|
|
|
3394
3426
|
const token = await this.#options.token();
|
|
3395
3427
|
if (socket !== this.#socket) return;
|
|
3396
3428
|
this.#phase = { phase: "recovering" };
|
|
3429
|
+
const baggage = legacyHelloServers.has(this.#options.url) ? void 0 : sessionBaggage();
|
|
3397
3430
|
const hello = {
|
|
3398
3431
|
type: "hello",
|
|
3399
3432
|
protocol: 1,
|
|
3400
3433
|
...this.#options.traceparent ? { traceparent: this.#options.traceparent } : {},
|
|
3434
|
+
...baggage ? { baggage } : {},
|
|
3401
3435
|
token,
|
|
3402
3436
|
streams: {
|
|
3403
3437
|
control: { cursor: this.#control && { revision: this.#control.revision, state_schema_version: this.#control.stateSchemaVersion, state_digest: this.#control.stateDigest } },
|
|
@@ -3407,6 +3441,7 @@ var V1SyncClient = class {
|
|
|
3407
3441
|
}
|
|
3408
3442
|
};
|
|
3409
3443
|
const collaborationExtension = this.#collaborationState.helloExtension;
|
|
3444
|
+
this.#baggageHelloSocket = baggage ? socket : null;
|
|
3410
3445
|
if (!collaborationExtension) {
|
|
3411
3446
|
this.#send(hello);
|
|
3412
3447
|
} else {
|
|
@@ -3426,7 +3461,7 @@ var V1SyncClient = class {
|
|
|
3426
3461
|
} catch (error) {
|
|
3427
3462
|
if (this.#snapshotRecoveryRequested) this.#failDigestRecovery();
|
|
3428
3463
|
else if (error instanceof V1StateDigestMismatchError) this.#recoverDigestMismatch();
|
|
3429
|
-
else this.#recover("invalid_frame");
|
|
3464
|
+
else this.#recover("invalid_frame", error instanceof V1ReplicaError && error.message === "invalid_frame" && this.#legacyHelloRejected(socket));
|
|
3430
3465
|
}
|
|
3431
3466
|
}
|
|
3432
3467
|
async #handleFrame(frame) {
|
|
@@ -3548,6 +3583,7 @@ var V1SyncClient = class {
|
|
|
3548
3583
|
}
|
|
3549
3584
|
async #welcome(frame) {
|
|
3550
3585
|
if (this.#phase.phase !== "recovering" || this.#recovery) throw new V1ReplicaError("unexpected welcome");
|
|
3586
|
+
this.#baggageHelloSocket = null;
|
|
3551
3587
|
this.#collaborationState.acceptWelcome(frame);
|
|
3552
3588
|
this.#entryNegotiated = frame.entry_confirmation === true;
|
|
3553
3589
|
this.#entryGeneration = frame.entry_generation ?? this.#entryGeneration;
|
|
@@ -3704,7 +3740,7 @@ var V1SyncClient = class {
|
|
|
3704
3740
|
if (evidence.get(frame.sequence) !== frameSignature(frame)) throw new V1ReplicaError("conflicting or unprovable duplicate projection event");
|
|
3705
3741
|
return true;
|
|
3706
3742
|
}
|
|
3707
|
-
#disconnected(socket) {
|
|
3743
|
+
#disconnected(socket, retryNow = false) {
|
|
3708
3744
|
if (socket !== this.#socket) return;
|
|
3709
3745
|
this.#socket = null;
|
|
3710
3746
|
this.#clearDial();
|
|
@@ -3723,6 +3759,13 @@ var V1SyncClient = class {
|
|
|
3723
3759
|
this.#emit();
|
|
3724
3760
|
if (!this.#transportAvailable) return;
|
|
3725
3761
|
this.#clearReconnect();
|
|
3762
|
+
if (retryNow) {
|
|
3763
|
+
this.#reconnectTimer = this.#clock().setTimeout(() => {
|
|
3764
|
+
this.#reconnectTimer = void 0;
|
|
3765
|
+
this.#connect();
|
|
3766
|
+
}, 0);
|
|
3767
|
+
return;
|
|
3768
|
+
}
|
|
3726
3769
|
const configuredDelay = this.#options.reconnectDelayMs;
|
|
3727
3770
|
const exponentialAttempt = configuredDelay === void 0 ? Math.max(0, this.#reconnectAttempt - FAST_RECONNECT_ATTEMPTS + 1) : this.#reconnectAttempt;
|
|
3728
3771
|
const baseDelay = configuredDelay === 0 ? 0 : Math.min(MAX_RECONNECT_DELAY_MS, (configuredDelay ?? DEFAULT_RECONNECT_DELAY_MS) * 2 ** Math.min(exponentialAttempt, 5));
|
|
@@ -3733,11 +3776,21 @@ var V1SyncClient = class {
|
|
|
3733
3776
|
this.#connect();
|
|
3734
3777
|
}, delay);
|
|
3735
3778
|
}
|
|
3736
|
-
#recover(reason) {
|
|
3779
|
+
#recover(reason, retryNow = false) {
|
|
3737
3780
|
const socket = this.#socket;
|
|
3738
3781
|
if (!socket) return;
|
|
3739
3782
|
socket.close(CLIENT_RESTART_CLOSE_CODE, reason);
|
|
3740
|
-
this.#disconnected(socket);
|
|
3783
|
+
this.#disconnected(socket, retryNow);
|
|
3784
|
+
}
|
|
3785
|
+
/**
|
|
3786
|
+
* A Sync that predates the session ID rejects any hello with an unknown `baggage` field before welcome. The first
|
|
3787
|
+
* rejection marks that server as legacy, so the retry and every later reconnect send the hello without it.
|
|
3788
|
+
*/
|
|
3789
|
+
#legacyHelloRejected(socket) {
|
|
3790
|
+
if (this.#baggageHelloSocket !== socket) return false;
|
|
3791
|
+
this.#baggageHelloSocket = null;
|
|
3792
|
+
legacyHelloServers.add(this.#options.url);
|
|
3793
|
+
return true;
|
|
3741
3794
|
}
|
|
3742
3795
|
#recoverDigestMismatch() {
|
|
3743
3796
|
const now = this.#clock().now();
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
withRequestContext
|
|
3
|
+
} from "./chunk-N4IPKRS6.js";
|
|
4
|
+
|
|
1
5
|
// src/generated/schemas.ts
|
|
2
6
|
import { Schema, SchemaGetter } from "effect";
|
|
3
7
|
var ChalkCodePointLimits = {
|
|
@@ -92,6 +96,30 @@ var AdmitEpisodeParticipantRequestSchema = Schema.Struct({
|
|
|
92
96
|
role: Schema.String.check(Schema.isMinLength(1))
|
|
93
97
|
});
|
|
94
98
|
var AuditLogIdSchema = Schema.String.check(Schema.isMinLength(36), Schema.isMaxLength(36), Schema.isPattern(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i)).pipe(Schema.brand("AuditLogId"));
|
|
99
|
+
var CallStatsRequestSchema = Schema.Struct({
|
|
100
|
+
samples: Schema.Array(
|
|
101
|
+
Schema.Struct({
|
|
102
|
+
connection_type: Schema.Literals(["udp", "tcp", "turn", "unknown"]),
|
|
103
|
+
elapsed_ms: Schema.Number,
|
|
104
|
+
freeze_count: Schema.optional(Schema.NullOr(Schema.Number)),
|
|
105
|
+
freeze_ms: Schema.optional(Schema.NullOr(Schema.Number)),
|
|
106
|
+
local_candidate_type: Schema.optional(Schema.Literals(["host", "srflx", "prflx", "relay"])),
|
|
107
|
+
recv_bitrate_kbps: Schema.optional(Schema.NullOr(Schema.Number)),
|
|
108
|
+
recv_height: Schema.optional(Schema.NullOr(Schema.Number)),
|
|
109
|
+
recv_jitter_ms: Schema.optional(Schema.NullOr(Schema.Number)),
|
|
110
|
+
recv_loss_pct: Schema.optional(Schema.NullOr(Schema.Number)),
|
|
111
|
+
relay_protocol: Schema.optional(Schema.Literals(["udp", "tcp", "tls"])),
|
|
112
|
+
remote_candidate_type: Schema.optional(Schema.Literals(["host", "srflx", "prflx", "relay"])),
|
|
113
|
+
rtt_ms: Schema.optional(Schema.NullOr(Schema.Number)),
|
|
114
|
+
send_bitrate_kbps: Schema.optional(Schema.NullOr(Schema.Number)),
|
|
115
|
+
send_jitter_ms: Schema.optional(Schema.NullOr(Schema.Number)),
|
|
116
|
+
send_layer: Schema.optional(Schema.Literals(["h", "m", "l"])),
|
|
117
|
+
send_loss_pct: Schema.optional(Schema.NullOr(Schema.Number)),
|
|
118
|
+
window_ms: Schema.Number
|
|
119
|
+
})
|
|
120
|
+
).check(Schema.isMinLength(1), Schema.isMaxLength(30)),
|
|
121
|
+
version: Schema.Literal(1)
|
|
122
|
+
});
|
|
95
123
|
var CancelRecordingPreparationRequestSchema = Schema.Struct({
|
|
96
124
|
expected_revision: Schema.Number
|
|
97
125
|
});
|
|
@@ -136,6 +164,7 @@ var CloudflareSFUCloseTracksAPIResponseSchema = Schema.Struct({
|
|
|
136
164
|
var CloudflareSFUCloseTracksRequestSchema = Schema.Struct({
|
|
137
165
|
connection_id: Schema.String.check(Schema.isMinLength(1)),
|
|
138
166
|
force: Schema.Boolean,
|
|
167
|
+
receive_only: Schema.optional(Schema.Boolean),
|
|
139
168
|
session_description: Schema.optional(
|
|
140
169
|
Schema.NullOr(
|
|
141
170
|
Schema.Struct({
|
|
@@ -173,7 +202,7 @@ var CloudflareSFURenegotiateRequestSchema = Schema.Struct({
|
|
|
173
202
|
var CloudflareSFURenegotiateResponseSchema = Schema.Struct({
|
|
174
203
|
accepted: Schema.Boolean
|
|
175
204
|
});
|
|
176
|
-
var
|
|
205
|
+
var CloudflareSFUUpdateTracksAPIResponseSchema = Schema.Struct({
|
|
177
206
|
requiresImmediateRenegotiation: Schema.optional(Schema.Boolean),
|
|
178
207
|
sessionDescription: Schema.optional(
|
|
179
208
|
Schema.NullOr(
|
|
@@ -214,6 +243,7 @@ var CloudflareSFUTracksAPIResponseSchema = Schema.Struct({
|
|
|
214
243
|
)
|
|
215
244
|
)
|
|
216
245
|
});
|
|
246
|
+
var CloudflareSFUTracksAPIResponseSchema = CloudflareSFUUpdateTracksAPIResponseSchema;
|
|
217
247
|
var CloudflareSFUTracksRequestSchema = Schema.Struct({
|
|
218
248
|
connection_id: Schema.String.check(Schema.isMinLength(1)),
|
|
219
249
|
session_description: Schema.optional(
|
|
@@ -244,6 +274,28 @@ var CloudflareSFUTracksRequestSchema = Schema.Struct({
|
|
|
244
274
|
})
|
|
245
275
|
)
|
|
246
276
|
});
|
|
277
|
+
var CloudflareSFUUpdateTracksRequestSchema = Schema.Struct({
|
|
278
|
+
connection_id: Schema.String.check(Schema.isMinLength(1)),
|
|
279
|
+
tracks: Schema.Array(
|
|
280
|
+
Schema.Struct({
|
|
281
|
+
location: Schema.String.check(Schema.isMinLength(1)),
|
|
282
|
+
mid: Schema.optional(Schema.String.check(Schema.isMinLength(1))),
|
|
283
|
+
publication_id: Schema.optional(Schema.String.check(Schema.isMinLength(1))),
|
|
284
|
+
sessionId: Schema.optional(Schema.String.check(Schema.isMinLength(1))),
|
|
285
|
+
simulcast: Schema.optional(
|
|
286
|
+
Schema.NullOr(
|
|
287
|
+
Schema.Struct({
|
|
288
|
+
preferredRid: Schema.String.check(Schema.isMinLength(1)),
|
|
289
|
+
priorityOrdering: Schema.String.check(Schema.isMinLength(1)),
|
|
290
|
+
ridNotAvailable: Schema.String.check(Schema.isMinLength(1))
|
|
291
|
+
})
|
|
292
|
+
)
|
|
293
|
+
),
|
|
294
|
+
source: Schema.optional(Schema.String.check(Schema.isMinLength(1))),
|
|
295
|
+
trackName: Schema.String.check(Schema.isMinLength(1))
|
|
296
|
+
})
|
|
297
|
+
)
|
|
298
|
+
});
|
|
247
299
|
var ConnectionReportRequestSchema = Schema.Struct({
|
|
248
300
|
events: Schema.Array(
|
|
249
301
|
Schema.Struct({
|
|
@@ -1925,6 +1977,19 @@ var TestWebhookEndpoint429ResponseHeadersSchema = Schema.Struct({
|
|
|
1925
1977
|
"X-RateLimit-Limit": RateLimitLimitHeaderSchema,
|
|
1926
1978
|
"X-RateLimit-Remaining": RateLimitRemainingHeaderSchema
|
|
1927
1979
|
});
|
|
1980
|
+
var UpdateCloudflareSFUTracksPathParamsSchema = Schema.Struct({
|
|
1981
|
+
episode_id: EpisodeIdSchema,
|
|
1982
|
+
participant_id: ParticipantIdSchema,
|
|
1983
|
+
space_id: SpaceIdSchema,
|
|
1984
|
+
tenant_id: TenantIdSchema
|
|
1985
|
+
});
|
|
1986
|
+
var UpdateCloudflareSFUTracksRequestBodySchema = CloudflareSFUUpdateTracksRequestSchema;
|
|
1987
|
+
var UpdateCloudflareSFUTracksResponseSchema = CloudflareSFUUpdateTracksAPIResponseSchema;
|
|
1988
|
+
var UpdateCloudflareSFUTracks429ResponseHeadersSchema = Schema.Struct({
|
|
1989
|
+
"Retry-After": RetryAfterHeaderSchema,
|
|
1990
|
+
"X-RateLimit-Limit": RateLimitLimitHeaderSchema,
|
|
1991
|
+
"X-RateLimit-Remaining": RateLimitRemainingHeaderSchema
|
|
1992
|
+
});
|
|
1928
1993
|
var UpdateMembershipPathParamsSchema = Schema.Struct({
|
|
1929
1994
|
membership_id: MembershipIdSchema,
|
|
1930
1995
|
tenant_id: TenantIdSchema
|
|
@@ -1983,6 +2048,15 @@ var UpdateWebhookEndpoint429ResponseHeadersSchema = Schema.Struct({
|
|
|
1983
2048
|
"X-RateLimit-Limit": RateLimitLimitHeaderSchema,
|
|
1984
2049
|
"X-RateLimit-Remaining": RateLimitRemainingHeaderSchema
|
|
1985
2050
|
});
|
|
2051
|
+
var UploadCallStatsPathParamsSchema = Schema.Struct({
|
|
2052
|
+
tenant_id: TenantIdSchema
|
|
2053
|
+
});
|
|
2054
|
+
var UploadCallStatsRequestBodySchema = CallStatsRequestSchema;
|
|
2055
|
+
var UploadCallStats429ResponseHeadersSchema = Schema.Struct({
|
|
2056
|
+
"Retry-After": RetryAfterHeaderSchema,
|
|
2057
|
+
"X-RateLimit-Limit": RateLimitLimitHeaderSchema,
|
|
2058
|
+
"X-RateLimit-Remaining": RateLimitRemainingHeaderSchema
|
|
2059
|
+
});
|
|
1986
2060
|
var AccessForbiddenError = class extends Schema.TaggedErrorClass()("AccessForbiddenError", {
|
|
1987
2061
|
error: Schema.Struct({
|
|
1988
2062
|
code: Schema.Literal("access.forbidden"),
|
|
@@ -5110,6 +5184,22 @@ var TestWebhookEndpointErrorSchema = Schema.Union([
|
|
|
5110
5184
|
WebhookInvalidUrlErrorSchema,
|
|
5111
5185
|
WebhookUnsafeUrlErrorSchema
|
|
5112
5186
|
]);
|
|
5187
|
+
var UpdateCloudflareSFUTracksErrorSchema = Schema.Union([
|
|
5188
|
+
AccessForbiddenErrorSchema,
|
|
5189
|
+
AccessUnauthenticatedErrorSchema,
|
|
5190
|
+
EpisodeInvalidIdErrorSchema,
|
|
5191
|
+
EpisodeNotFoundErrorSchema,
|
|
5192
|
+
MediaConnectionNotFoundErrorSchema,
|
|
5193
|
+
MediaUnavailableErrorSchema,
|
|
5194
|
+
ParticipantInvalidIdErrorSchema,
|
|
5195
|
+
RequestInvalidErrorSchema,
|
|
5196
|
+
RequestPayloadTooLargeErrorSchema,
|
|
5197
|
+
RequestRateLimitedErrorSchema,
|
|
5198
|
+
ServiceInternalErrorSchema,
|
|
5199
|
+
ServiceUnavailableErrorSchema,
|
|
5200
|
+
SpaceInvalidIdErrorSchema,
|
|
5201
|
+
TenantInvalidIdErrorSchema
|
|
5202
|
+
]);
|
|
5113
5203
|
var UpdateMembershipErrorSchema = Schema.Union([
|
|
5114
5204
|
AccessForbiddenErrorSchema,
|
|
5115
5205
|
AccessUnauthenticatedErrorSchema,
|
|
@@ -5198,6 +5288,7 @@ var UpdateWebhookEndpointErrorSchema = Schema.Union([
|
|
|
5198
5288
|
WebhookInvalidUrlErrorSchema,
|
|
5199
5289
|
WebhookUnsafeUrlErrorSchema
|
|
5200
5290
|
]);
|
|
5291
|
+
var UploadCallStatsErrorSchema = Schema.Union([AccessForbiddenErrorSchema, AccessUnauthenticatedErrorSchema, RequestInvalidErrorSchema, RequestPayloadTooLargeErrorSchema, RequestRateLimitedErrorSchema, ServiceInternalErrorSchema, ServiceUnavailableErrorSchema, TenantInvalidIdErrorSchema]);
|
|
5201
5292
|
var ChalkOperationPolicies = {
|
|
5202
5293
|
addCloudflareSFUTracks: { maxBodyBytes: 1048576, rateLimit: { limit: 60, policy: "v1.authenticated.write", windowSeconds: 60 } },
|
|
5203
5294
|
admitEpisodeParticipant: { maxBodyBytes: 1048576, rateLimit: { limit: 60, policy: "v1.authenticated.write", windowSeconds: 60 } },
|
|
@@ -5259,11 +5350,13 @@ var ChalkOperationPolicies = {
|
|
|
5259
5350
|
sendProblemReport: { maxBodyBytes: 37024, rateLimit: { limit: 3, policy: "problem_reports.participant", windowSeconds: 3600 } },
|
|
5260
5351
|
setEpisodeDeadline: { maxBodyBytes: 1048576, rateLimit: { limit: 60, policy: "v1.authenticated.write", windowSeconds: 60 } },
|
|
5261
5352
|
testWebhookEndpoint: { rateLimit: { limit: 60, policy: "v1.authenticated.write", windowSeconds: 60 } },
|
|
5353
|
+
updateCloudflareSFUTracks: { maxBodyBytes: 1048576, rateLimit: { limit: 60, policy: "v1.authenticated.write", windowSeconds: 60 } },
|
|
5262
5354
|
updateMembership: { maxBodyBytes: 1048576, rateLimit: { limit: 60, policy: "v1.authenticated.write", windowSeconds: 60 } },
|
|
5263
5355
|
updateSpace: { maxBodyBytes: 1048576, rateLimit: { limit: 60, policy: "v1.authenticated.write", windowSeconds: 60 } },
|
|
5264
5356
|
updateSpacePublicInvite: { maxBodyBytes: 1048576, rateLimit: { limit: 60, policy: "v1.authenticated.write", windowSeconds: 60 } },
|
|
5265
5357
|
updateTenant: { maxBodyBytes: 1048576, rateLimit: { limit: 60, policy: "v1.authenticated.write", windowSeconds: 60 } },
|
|
5266
|
-
updateWebhookEndpoint: { maxBodyBytes: 1048576, rateLimit: { limit: 60, policy: "v1.authenticated.write", windowSeconds: 60 } }
|
|
5358
|
+
updateWebhookEndpoint: { maxBodyBytes: 1048576, rateLimit: { limit: 60, policy: "v1.authenticated.write", windowSeconds: 60 } },
|
|
5359
|
+
uploadCallStats: { maxBodyBytes: 32768, rateLimit: { limit: 30, policy: "call_stats.participant", windowSeconds: 600 } }
|
|
5267
5360
|
};
|
|
5268
5361
|
|
|
5269
5362
|
// src/generated/http-api.ts
|
|
@@ -5832,6 +5925,28 @@ var defaultGroup = HttpApiGroup.make("default").add(
|
|
|
5832
5925
|
ServiceUnavailableErrorSchema.pipe(HttpApiSchema.status(503))
|
|
5833
5926
|
]
|
|
5834
5927
|
})
|
|
5928
|
+
).add(
|
|
5929
|
+
HttpApiEndpoint.put("updateCloudflareSFUTracks", "/v1/tenants/:tenant_id/spaces/:space_id/episodes/:episode_id/participants/:participant_id/media/sfu/tracks/update", {
|
|
5930
|
+
params: UpdateCloudflareSFUTracksPathParamsSchema,
|
|
5931
|
+
payload: UpdateCloudflareSFUTracksRequestBodySchema,
|
|
5932
|
+
success: UpdateCloudflareSFUTracksResponseSchema.pipe(HttpApiSchema.status(200)),
|
|
5933
|
+
error: [
|
|
5934
|
+
EpisodeInvalidIdErrorSchema.pipe(HttpApiSchema.status(400)),
|
|
5935
|
+
ParticipantInvalidIdErrorSchema.pipe(HttpApiSchema.status(400)),
|
|
5936
|
+
RequestInvalidErrorSchema.pipe(HttpApiSchema.status(400)),
|
|
5937
|
+
SpaceInvalidIdErrorSchema.pipe(HttpApiSchema.status(400)),
|
|
5938
|
+
TenantInvalidIdErrorSchema.pipe(HttpApiSchema.status(400)),
|
|
5939
|
+
AccessUnauthenticatedErrorSchema.pipe(HttpApiSchema.status(401)),
|
|
5940
|
+
AccessForbiddenErrorSchema.pipe(HttpApiSchema.status(403)),
|
|
5941
|
+
EpisodeNotFoundErrorSchema.pipe(HttpApiSchema.status(404)),
|
|
5942
|
+
MediaConnectionNotFoundErrorSchema.pipe(HttpApiSchema.status(404)),
|
|
5943
|
+
RequestPayloadTooLargeErrorSchema.pipe(HttpApiSchema.status(413)),
|
|
5944
|
+
RequestRateLimitedErrorSchema.pipe(HttpApiSchema.status(429)),
|
|
5945
|
+
ServiceInternalErrorSchema.pipe(HttpApiSchema.status(500)),
|
|
5946
|
+
MediaUnavailableErrorSchema.pipe(HttpApiSchema.status(503)),
|
|
5947
|
+
ServiceUnavailableErrorSchema.pipe(HttpApiSchema.status(503))
|
|
5948
|
+
]
|
|
5949
|
+
})
|
|
5835
5950
|
).add(
|
|
5836
5951
|
HttpApiEndpoint.patch("updateWebhookEndpoint", "/v1/tenants/:tenant_id/webhook-endpoints/:endpoint_id", {
|
|
5837
5952
|
params: UpdateWebhookEndpointPathParamsSchema,
|
|
@@ -5867,6 +5982,22 @@ var defaultGroup = HttpApiGroup.make("default").add(
|
|
|
5867
5982
|
ServiceUnavailableErrorSchema.pipe(HttpApiSchema.status(503))
|
|
5868
5983
|
]
|
|
5869
5984
|
})
|
|
5985
|
+
).add(
|
|
5986
|
+
HttpApiEndpoint.post("uploadCallStats", "/v1/tenants/:tenant_id/call-stats", {
|
|
5987
|
+
params: UploadCallStatsPathParamsSchema,
|
|
5988
|
+
payload: UploadCallStatsRequestBodySchema,
|
|
5989
|
+
success: HttpApiSchema.Empty(204).pipe(HttpApiSchema.status(204)),
|
|
5990
|
+
error: [
|
|
5991
|
+
RequestInvalidErrorSchema.pipe(HttpApiSchema.status(400)),
|
|
5992
|
+
TenantInvalidIdErrorSchema.pipe(HttpApiSchema.status(400)),
|
|
5993
|
+
AccessUnauthenticatedErrorSchema.pipe(HttpApiSchema.status(401)),
|
|
5994
|
+
AccessForbiddenErrorSchema.pipe(HttpApiSchema.status(403)),
|
|
5995
|
+
RequestPayloadTooLargeErrorSchema.pipe(HttpApiSchema.status(413)),
|
|
5996
|
+
RequestRateLimitedErrorSchema.pipe(HttpApiSchema.status(429)),
|
|
5997
|
+
ServiceInternalErrorSchema.pipe(HttpApiSchema.status(500)),
|
|
5998
|
+
ServiceUnavailableErrorSchema.pipe(HttpApiSchema.status(503))
|
|
5999
|
+
]
|
|
6000
|
+
})
|
|
5870
6001
|
);
|
|
5871
6002
|
var episodesGroup = HttpApiGroup.make("episodes").add(
|
|
5872
6003
|
HttpApiEndpoint.post("admitEpisodeParticipant", "/v1/tenants/:tenant_id/spaces/:space_id/episodes/:episode_id/participants", {
|
|
@@ -6864,7 +6995,7 @@ var createChalkEffectClient = (options) => {
|
|
|
6864
6995
|
})
|
|
6865
6996
|
}).pipe(Effect.provide(FetchHttpClient.layer));
|
|
6866
6997
|
const configuredClient = options.credentials === void 0 ? client : client.pipe(Effect.provideService(FetchHttpClient.RequestInit, { credentials: options.credentials }));
|
|
6867
|
-
return
|
|
6998
|
+
return configuredClient.pipe(Effect.provideService(FetchHttpClient.Fetch, withRequestContext(options.fetch)));
|
|
6868
6999
|
};
|
|
6869
7000
|
function requestHeaders(options) {
|
|
6870
7001
|
return {
|
|
@@ -7015,17 +7146,31 @@ function parseMediaAccess(value) {
|
|
|
7015
7146
|
provider: value.provider,
|
|
7016
7147
|
clientPayload: {
|
|
7017
7148
|
connectionId: requireNonEmptyString(payload.connectionId),
|
|
7018
|
-
stunServer: requireNonEmptyString(payload.stunServer)
|
|
7149
|
+
stunServer: requireNonEmptyString(payload.stunServer),
|
|
7150
|
+
...payload.iceServers === void 0 || payload.iceServers === null ? {} : { iceServers: parseIceServers(payload.iceServers) }
|
|
7019
7151
|
}
|
|
7020
7152
|
};
|
|
7021
7153
|
default:
|
|
7022
7154
|
throw new AccessGrantError();
|
|
7023
7155
|
}
|
|
7024
7156
|
}
|
|
7157
|
+
function parseIceServers(value) {
|
|
7158
|
+
if (!Array.isArray(value)) throw new AccessGrantError();
|
|
7159
|
+
return value.map((entry) => {
|
|
7160
|
+
if (!isRecord(entry) || !Array.isArray(entry.urls) || entry.urls.length === 0) throw new AccessGrantError();
|
|
7161
|
+
const urls = entry.urls.map(requireNonEmptyString);
|
|
7162
|
+
if (entry.username === void 0 && entry.credential === void 0) return { urls };
|
|
7163
|
+
return { urls, username: requireNonEmptyString(entry.username), credential: requireNonEmptyString(entry.credential) };
|
|
7164
|
+
});
|
|
7165
|
+
}
|
|
7025
7166
|
function mediaClientPayload(value) {
|
|
7026
7167
|
switch (value.provider) {
|
|
7027
7168
|
case "cloudflare_sfu":
|
|
7028
|
-
return {
|
|
7169
|
+
return {
|
|
7170
|
+
connectionId: value.clientPayload.connectionId,
|
|
7171
|
+
stunServer: value.clientPayload.stunServer,
|
|
7172
|
+
...value.clientPayload.iceServers ? { iceServers: value.clientPayload.iceServers } : {}
|
|
7173
|
+
};
|
|
7029
7174
|
}
|
|
7030
7175
|
}
|
|
7031
7176
|
function requireCredential(value, audience) {
|
|
@@ -7073,6 +7218,7 @@ export {
|
|
|
7073
7218
|
AccessGrantSchema,
|
|
7074
7219
|
AdmitEpisodeParticipantRequestSchema,
|
|
7075
7220
|
AuditLogIdSchema,
|
|
7221
|
+
CallStatsRequestSchema,
|
|
7076
7222
|
CancelRecordingPreparationRequestSchema,
|
|
7077
7223
|
ChatAttachmentSchema,
|
|
7078
7224
|
ChatAttachmentDownloadSchema,
|
|
@@ -7082,8 +7228,10 @@ export {
|
|
|
7082
7228
|
CloudflareSFUPublicationsResponseSchema,
|
|
7083
7229
|
CloudflareSFURenegotiateRequestSchema,
|
|
7084
7230
|
CloudflareSFURenegotiateResponseSchema,
|
|
7231
|
+
CloudflareSFUUpdateTracksAPIResponseSchema,
|
|
7085
7232
|
CloudflareSFUTracksAPIResponseSchema,
|
|
7086
7233
|
CloudflareSFUTracksRequestSchema,
|
|
7234
|
+
CloudflareSFUUpdateTracksRequestSchema,
|
|
7087
7235
|
ConnectionReportRequestSchema,
|
|
7088
7236
|
CreateAPIKeyRequestSchema,
|
|
7089
7237
|
CreateEpisodeRequestSchema,
|
|
@@ -7429,6 +7577,10 @@ export {
|
|
|
7429
7577
|
TestWebhookEndpointRequestHeadersSchema,
|
|
7430
7578
|
TestWebhookEndpointResponseSchema,
|
|
7431
7579
|
TestWebhookEndpoint429ResponseHeadersSchema,
|
|
7580
|
+
UpdateCloudflareSFUTracksPathParamsSchema,
|
|
7581
|
+
UpdateCloudflareSFUTracksRequestBodySchema,
|
|
7582
|
+
UpdateCloudflareSFUTracksResponseSchema,
|
|
7583
|
+
UpdateCloudflareSFUTracks429ResponseHeadersSchema,
|
|
7432
7584
|
UpdateMembershipPathParamsSchema,
|
|
7433
7585
|
UpdateMembershipRequestBodySchema,
|
|
7434
7586
|
UpdateMembershipResponseSchema,
|
|
@@ -7450,6 +7602,9 @@ export {
|
|
|
7450
7602
|
UpdateWebhookEndpointRequestBodySchema,
|
|
7451
7603
|
UpdateWebhookEndpointResponseSchema,
|
|
7452
7604
|
UpdateWebhookEndpoint429ResponseHeadersSchema,
|
|
7605
|
+
UploadCallStatsPathParamsSchema,
|
|
7606
|
+
UploadCallStatsRequestBodySchema,
|
|
7607
|
+
UploadCallStats429ResponseHeadersSchema,
|
|
7453
7608
|
AccessForbiddenError,
|
|
7454
7609
|
AccessForbiddenErrorWireSchema,
|
|
7455
7610
|
AccessForbiddenErrorSchema,
|
|
@@ -7872,11 +8027,13 @@ export {
|
|
|
7872
8027
|
SendProblemReportErrorSchema,
|
|
7873
8028
|
SetEpisodeDeadlineErrorSchema,
|
|
7874
8029
|
TestWebhookEndpointErrorSchema,
|
|
8030
|
+
UpdateCloudflareSFUTracksErrorSchema,
|
|
7875
8031
|
UpdateMembershipErrorSchema,
|
|
7876
8032
|
UpdateSpaceErrorSchema,
|
|
7877
8033
|
UpdateSpacePublicInviteErrorSchema,
|
|
7878
8034
|
UpdateTenantErrorSchema,
|
|
7879
8035
|
UpdateWebhookEndpointErrorSchema,
|
|
8036
|
+
UploadCallStatsErrorSchema,
|
|
7880
8037
|
ChalkOperationPolicies,
|
|
7881
8038
|
ChalkApi,
|
|
7882
8039
|
createChalkEffectClient,
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// src/session/index.ts
|
|
2
|
+
var SESSION_ID_KEY = "session.id";
|
|
3
|
+
var STORAGE_KEY = "chalk.session.id";
|
|
4
|
+
var TAB_KEY = "chalk.session.tab";
|
|
5
|
+
var TAB_NAME_PREFIX = "chalk.tab:";
|
|
6
|
+
var SESSION_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
|
|
7
|
+
var source = browserSession;
|
|
8
|
+
var browserId;
|
|
9
|
+
function setSessionSource(next) {
|
|
10
|
+
source = next;
|
|
11
|
+
}
|
|
12
|
+
function currentSessionId() {
|
|
13
|
+
return source();
|
|
14
|
+
}
|
|
15
|
+
function newSessionId() {
|
|
16
|
+
const random = globalThis.crypto;
|
|
17
|
+
if (typeof random?.randomUUID === "function") return random.randomUUID();
|
|
18
|
+
return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, (digit) => (Number(digit) ^ random.getRandomValues(new Uint8Array(1))[0] & 15 >> Number(digit) / 4).toString(16));
|
|
19
|
+
}
|
|
20
|
+
function browserSession() {
|
|
21
|
+
if (browserId) return browserId;
|
|
22
|
+
if (typeof globalThis.document === "undefined") return void 0;
|
|
23
|
+
const tab = tabToken();
|
|
24
|
+
browserId = newSessionId();
|
|
25
|
+
try {
|
|
26
|
+
const storage = globalThis.sessionStorage;
|
|
27
|
+
browserId = storedSession(storage, tab) ?? browserId;
|
|
28
|
+
storage.setItem(STORAGE_KEY, browserId);
|
|
29
|
+
if (tab !== void 0) storage.setItem(TAB_KEY, tab);
|
|
30
|
+
} catch {
|
|
31
|
+
}
|
|
32
|
+
return browserId;
|
|
33
|
+
}
|
|
34
|
+
function storedSession(storage, tab) {
|
|
35
|
+
const stored = storage.getItem(STORAGE_KEY) ?? void 0;
|
|
36
|
+
if (!stored || !SESSION_ID.test(stored)) return void 0;
|
|
37
|
+
return tab === void 0 || storage.getItem(TAB_KEY) === tab ? stored : void 0;
|
|
38
|
+
}
|
|
39
|
+
function tabToken() {
|
|
40
|
+
const win = globalThis.window;
|
|
41
|
+
if (!win) return void 0;
|
|
42
|
+
if (win.name.startsWith(TAB_NAME_PREFIX)) return win.name;
|
|
43
|
+
if (win.name !== "") return void 0;
|
|
44
|
+
win.name = `${TAB_NAME_PREFIX}${newSessionId()}`;
|
|
45
|
+
return win.name;
|
|
46
|
+
}
|
|
47
|
+
function sessionBaggage() {
|
|
48
|
+
const sessionId = currentSessionId();
|
|
49
|
+
return sessionId ? `${SESSION_ID_KEY}=${sessionId}` : void 0;
|
|
50
|
+
}
|
|
51
|
+
function requestContextHeaders() {
|
|
52
|
+
const baggage = sessionBaggage();
|
|
53
|
+
if (!baggage) return {};
|
|
54
|
+
const trace = newSessionId().replaceAll("-", "");
|
|
55
|
+
return { baggage, traceparent: `00-${trace}-${trace.slice(16)}-01` };
|
|
56
|
+
}
|
|
57
|
+
function withRequestContext(fetchImplementation) {
|
|
58
|
+
return (input, init) => {
|
|
59
|
+
const send = fetchImplementation ?? globalThis.fetch;
|
|
60
|
+
const context = requestContextHeaders();
|
|
61
|
+
if (Object.keys(context).length === 0) return send(input, init);
|
|
62
|
+
const headers = new Headers(init?.headers ?? (input instanceof Request ? input.headers : void 0));
|
|
63
|
+
for (const [name, value] of Object.entries(context)) if (!headers.has(name)) headers.set(name, value);
|
|
64
|
+
return send(input, { ...init, headers });
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export {
|
|
69
|
+
SESSION_ID_KEY,
|
|
70
|
+
setSessionSource,
|
|
71
|
+
currentSessionId,
|
|
72
|
+
newSessionId,
|
|
73
|
+
sessionBaggage,
|
|
74
|
+
requestContextHeaders,
|
|
75
|
+
withRequestContext
|
|
76
|
+
};
|