@q9labsai/chalk-client 5.2.4 → 5.2.5

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.
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createChalkEffectClient,
3
3
  parseAccessGrant
4
- } from "./chunk-AZONR3Q3.js";
4
+ } from "./chunk-UMAE5GCV.js";
5
5
 
6
6
  // src/public-invites/client.ts
7
7
  import { Effect } from "effect";
@@ -295,17 +295,25 @@ var ConnectionReportRequestSchema = Schema.Struct({
295
295
  "sync_socket_close",
296
296
  "sync_heartbeat_gap",
297
297
  "media_state",
298
- "media_http_error"
298
+ "media_http_error",
299
+ "media_projection_mismatch"
299
300
  ]),
301
+ granted_audio: Schema.optional(Schema.Literals(["granted", "not_granted", "unknown"])),
302
+ granted_video: Schema.optional(Schema.Literals(["granted", "not_granted", "unknown"])),
300
303
  heartbeat_gap_ms: Schema.optional(Schema.NullOr(Schema.Number)),
301
304
  http_status: Schema.optional(Schema.NullOr(Schema.Number)),
305
+ media_error_kind: Schema.optional(Schema.Literals(["NotAllowedError", "NotReadableError", "NotFoundError", "OverconstrainedError", "AbortError", "SecurityError", "InvalidStateError", "OperationError", "NotSupportedError", "CloudflareSFUError", "network", "timeout", "unknown"])),
306
+ media_error_step: Schema.optional(Schema.Literals(["local_capture", "peer_connection", "access_refresh", "sfu_tracks", "sfu_close_tracks", "sfu_renegotiate", "sfu_publications"])),
302
307
  outcome: Schema.optional(Schema.Literals(["started", "succeeded", "failed", "cancelled"])),
303
308
  phase: Schema.optional(Schema.Literals(["idle", "connecting", "live", "recovering", "failed", "stopped", "new", "connected", "disconnected", "closed"])),
309
+ projection_state: Schema.optional(Schema.Literals(["on", "off"])),
310
+ publication_state: Schema.optional(Schema.Literals(["on", "off"])),
311
+ source: Schema.optional(Schema.Literals(["microphone", "camera"])),
304
312
  state: Schema.optional(Schema.Literals(["idle", "joining", "live", "reconnecting", "leaving", "left", "failed"])),
305
313
  step: Schema.optional(Schema.Literals(["join", "acquire_initial_media", "access_initialize", "create_media_client", "create_sync_client", "start_media", "start_sync", "wait_for_sync_live", "confirm_entered"]))
306
314
  })
307
315
  ).check(Schema.isMinLength(1), Schema.isMaxLength(64)),
308
- trigger: Schema.Literals(["join_failed", "connection_lost", "recovery_exhausted"]),
316
+ trigger: Schema.Literals(["join_failed", "connection_lost", "recovery_exhausted", "media_projection_mismatch"]),
309
317
  version: Schema.Literal(1)
310
318
  });
311
319
  var CreateAPIKeyRequestSchema = Schema.Struct({
@@ -475,6 +483,7 @@ var IntegrationActionIdSchema = Schema.String.check(Schema.isMinLength(1)).pipe(
475
483
  var IntegrationServiceIdSchema = Schema.String.check(Schema.isMinLength(1)).pipe(Schema.brand("IntegrationServiceId"));
476
484
  var IssueAccessGrantRequestSchema = Schema.Struct({
477
485
  current_media_token: Schema.optional(Schema.String.check(Schema.isMinLength(1))),
486
+ expected_media_connection_id: Schema.optional(Schema.NullOr(Schema.String.check(Schema.isMinLength(1)))),
478
487
  participant_generation: Schema.Number,
479
488
  replace_media_connection: Schema.Boolean
480
489
  });
@@ -493,6 +502,9 @@ var MembershipListSchema = Schema.Struct({
493
502
  memberships: Schema.Array(MembershipSchema),
494
503
  pagination: PaginationSchema
495
504
  });
505
+ var ParticipantEpisodeStatusSchema = Schema.Struct({
506
+ status: Schema.Literals(["active", "ending", "ended"])
507
+ });
496
508
  var ParticipantJoinCancellationSchema = Schema.Struct({
497
509
  cancelled: Schema.Boolean
498
510
  });
@@ -1383,6 +1395,18 @@ var GetEpisodeAttendance429ResponseHeadersSchema = Schema.Struct({
1383
1395
  "X-RateLimit-Limit": RateLimitLimitHeaderSchema,
1384
1396
  "X-RateLimit-Remaining": RateLimitRemainingHeaderSchema
1385
1397
  });
1398
+ var GetParticipantEpisodeStatusPathParamsSchema = Schema.Struct({
1399
+ episode_id: EpisodeIdSchema,
1400
+ participant_id: ParticipantIdSchema,
1401
+ space_id: SpaceIdSchema,
1402
+ tenant_id: TenantIdSchema
1403
+ });
1404
+ var GetParticipantEpisodeStatusResponseSchema = ParticipantEpisodeStatusSchema;
1405
+ var GetParticipantEpisodeStatus429ResponseHeadersSchema = Schema.Struct({
1406
+ "Retry-After": RetryAfterHeaderSchema,
1407
+ "X-RateLimit-Limit": RateLimitLimitHeaderSchema,
1408
+ "X-RateLimit-Remaining": RateLimitRemainingHeaderSchema
1409
+ });
1386
1410
  var GetProblemReportAvailabilityPathParamsSchema = Schema.Struct({
1387
1411
  tenant_id: TenantIdSchema
1388
1412
  });
@@ -2889,6 +2913,25 @@ var ParticipantInvalidIdErrorSchema = ParticipantInvalidIdErrorWireSchema.pipe(
2889
2913
  encode: SchemaGetter.transform((error) => ({ error: error.error }))
2890
2914
  })
2891
2915
  );
2916
+ var ParticipantMediaReplacementPendingError = class extends Schema.TaggedErrorClass()("ParticipantMediaReplacementPendingError", {
2917
+ error: Schema.Struct({
2918
+ code: Schema.Literal("participant.media_replacement_pending"),
2919
+ message: Schema.String
2920
+ })
2921
+ }) {
2922
+ };
2923
+ var ParticipantMediaReplacementPendingErrorWireSchema = Schema.Struct({
2924
+ error: Schema.Struct({
2925
+ code: Schema.Literal("participant.media_replacement_pending"),
2926
+ message: Schema.String
2927
+ })
2928
+ });
2929
+ var ParticipantMediaReplacementPendingErrorSchema = ParticipantMediaReplacementPendingErrorWireSchema.pipe(
2930
+ Schema.decodeTo(ParticipantMediaReplacementPendingError, {
2931
+ decode: SchemaGetter.transform((wire) => ({ _tag: "ParticipantMediaReplacementPendingError", ...wire })),
2932
+ encode: SchemaGetter.transform((error) => ({ error: error.error }))
2933
+ })
2934
+ );
2892
2935
  var ParticipantNotActiveError = class extends Schema.TaggedErrorClass()("ParticipantNotActiveError", {
2893
2936
  error: Schema.Struct({
2894
2937
  code: Schema.Literal("participant.not_active"),
@@ -4490,6 +4533,18 @@ var GetEpisodeErrorSchema = Schema.Union([
4490
4533
  SpaceNotFoundErrorSchema,
4491
4534
  TenantInvalidIdErrorSchema
4492
4535
  ]);
4536
+ var GetParticipantEpisodeStatusErrorSchema = Schema.Union([
4537
+ AccessForbiddenErrorSchema,
4538
+ AccessUnauthenticatedErrorSchema,
4539
+ EpisodeInvalidIdErrorSchema,
4540
+ EpisodeNotFoundErrorSchema,
4541
+ ParticipantInvalidIdErrorSchema,
4542
+ RequestRateLimitedErrorSchema,
4543
+ ServiceInternalErrorSchema,
4544
+ ServiceUnavailableErrorSchema,
4545
+ SpaceInvalidIdErrorSchema,
4546
+ TenantInvalidIdErrorSchema
4547
+ ]);
4493
4548
  var GetProblemReportAvailabilityErrorSchema = TenantInvalidIdErrorSchema;
4494
4549
  var GetRecordingErrorSchema = Schema.Union([AccessForbiddenErrorSchema, AccessUnauthenticatedErrorSchema, RecordingInvalidIdErrorSchema, RecordingNotFoundErrorSchema, ServiceInternalErrorSchema, ServiceUnavailableErrorSchema, TenantInvalidIdErrorSchema]);
4495
4550
  var GetSpaceErrorSchema = Schema.Union([AccessForbiddenErrorSchema, AccessUnauthenticatedErrorSchema, ServiceInternalErrorSchema, ServiceUnavailableErrorSchema, SpaceInvalidIdErrorSchema, SpaceNotFoundErrorSchema, TenantInvalidIdErrorSchema]);
@@ -4621,6 +4676,7 @@ var IssueAccessGrantErrorSchema = Schema.Union([
4621
4676
  ParticipantConnectionSupersededErrorSchema,
4622
4677
  ParticipantGenerationMismatchErrorSchema,
4623
4678
  ParticipantInvalidIdErrorSchema,
4679
+ ParticipantMediaReplacementPendingErrorSchema,
4624
4680
  ParticipantNotFoundErrorSchema,
4625
4681
  RequestInvalidErrorSchema,
4626
4682
  RequestPayloadTooLargeErrorSchema,
@@ -5148,6 +5204,7 @@ var ChalkOperationPolicies = {
5148
5204
  findTenantByExternalID: { rateLimit: { limit: 300, policy: "v1.authenticated.read", windowSeconds: 60 } },
5149
5205
  getEpisode: { rateLimit: { limit: 300, policy: "v1.authenticated.read", windowSeconds: 60 } },
5150
5206
  getEpisodeAttendance: { rateLimit: { limit: 300, policy: "v1.authenticated.read", windowSeconds: 60 } },
5207
+ getParticipantEpisodeStatus: { rateLimit: { limit: 300, policy: "v1.authenticated.read", windowSeconds: 60 } },
5151
5208
  getSpacePublicInvite: { rateLimit: { limit: 300, policy: "v1.authenticated.read", windowSeconds: 60 } },
5152
5209
  getSpacePublicInviteArrival: { rateLimit: { limit: 300, policy: "v1.authenticated.read", windowSeconds: 60 } },
5153
5210
  getTenant: { rateLimit: { limit: 300, policy: "v1.authenticated.read", windowSeconds: 60 } },
@@ -5475,6 +5532,7 @@ var defaultGroup = HttpApiGroup.make("default").add(
5475
5532
  ParticipantNotFoundErrorSchema.pipe(HttpApiSchema.status(404)),
5476
5533
  ParticipantConnectionSupersededErrorSchema.pipe(HttpApiSchema.status(409)),
5477
5534
  ParticipantGenerationMismatchErrorSchema.pipe(HttpApiSchema.status(409)),
5535
+ ParticipantMediaReplacementPendingErrorSchema.pipe(HttpApiSchema.status(409)),
5478
5536
  RequestPayloadTooLargeErrorSchema.pipe(HttpApiSchema.status(413)),
5479
5537
  RequestRateLimitedErrorSchema.pipe(HttpApiSchema.status(429)),
5480
5538
  ServiceInternalErrorSchema.pipe(HttpApiSchema.status(500)),
@@ -5911,6 +5969,23 @@ var episodesGroup = HttpApiGroup.make("episodes").add(
5911
5969
  ServiceUnavailableErrorSchema.pipe(HttpApiSchema.status(503))
5912
5970
  ]
5913
5971
  })
5972
+ ).add(
5973
+ HttpApiEndpoint.get("getParticipantEpisodeStatus", "/v1/tenants/:tenant_id/spaces/:space_id/episodes/:episode_id/participants/:participant_id/episode-status", {
5974
+ params: GetParticipantEpisodeStatusPathParamsSchema,
5975
+ success: GetParticipantEpisodeStatusResponseSchema.pipe(HttpApiSchema.status(200)),
5976
+ error: [
5977
+ EpisodeInvalidIdErrorSchema.pipe(HttpApiSchema.status(400)),
5978
+ ParticipantInvalidIdErrorSchema.pipe(HttpApiSchema.status(400)),
5979
+ SpaceInvalidIdErrorSchema.pipe(HttpApiSchema.status(400)),
5980
+ TenantInvalidIdErrorSchema.pipe(HttpApiSchema.status(400)),
5981
+ AccessUnauthenticatedErrorSchema.pipe(HttpApiSchema.status(401)),
5982
+ AccessForbiddenErrorSchema.pipe(HttpApiSchema.status(403)),
5983
+ EpisodeNotFoundErrorSchema.pipe(HttpApiSchema.status(404)),
5984
+ RequestRateLimitedErrorSchema.pipe(HttpApiSchema.status(429)),
5985
+ ServiceInternalErrorSchema.pipe(HttpApiSchema.status(500)),
5986
+ ServiceUnavailableErrorSchema.pipe(HttpApiSchema.status(503))
5987
+ ]
5988
+ })
5914
5989
  ).add(
5915
5990
  HttpApiEndpoint.post("issueEpisodeParticipantSyncToken", "/v1/tenants/:tenant_id/spaces/:space_id/episodes/:episode_id/participants/:participant_id/sync-token", {
5916
5991
  params: IssueEpisodeParticipantSyncTokenPathParamsSchema,
@@ -6797,11 +6872,13 @@ function decodeBase64Url(value) {
6797
6872
  // src/access/grant.ts
6798
6873
  var accessGrantBrand = /* @__PURE__ */ Symbol("AccessGrant");
6799
6874
  var AccessGrantError = class extends TypeError {
6800
- code = "access.invalid";
6801
- constructor(message = "Access grant is invalid") {
6875
+ constructor(message = "Access grant is invalid", reason) {
6802
6876
  super(message);
6877
+ this.reason = reason;
6803
6878
  this.name = "AccessGrantError";
6804
6879
  }
6880
+ reason;
6881
+ code = "access.invalid";
6805
6882
  };
6806
6883
  var AccessUnavailableError = class extends Error {
6807
6884
  code = "access.unavailable";
@@ -6810,12 +6887,21 @@ var AccessUnavailableError = class extends Error {
6810
6887
  this.name = "AccessUnavailableError";
6811
6888
  }
6812
6889
  };
6813
- function requireSuccessfulResponse(response) {
6890
+ async function requireSuccessfulResponse(response) {
6814
6891
  if (response.ok) return;
6815
6892
  const status = response.status;
6816
6893
  if (status === 408 || status === 425 || status === 429 || status >= 500) throw new AccessUnavailableError(status);
6894
+ if (status === 409) {
6895
+ const body = await response.json().catch(() => null);
6896
+ const code = conflictResponseCode(body);
6897
+ if (code === "participant.media_replacement_pending") throw new AccessUnavailableError(status);
6898
+ if (code === "participant.connection_superseded") throw new AccessGrantError(void 0, "connection_superseded");
6899
+ }
6817
6900
  throw new AccessGrantError(`Access grant request failed with HTTP ${status}`);
6818
6901
  }
6902
+ function conflictResponseCode(body) {
6903
+ return typeof body === "object" && body !== null && "error" in body && typeof body.error === "object" && body.error !== null && "code" in body.error ? body.error.code : void 0;
6904
+ }
6819
6905
  function parseParsedAccessGrant(value) {
6820
6906
  if (!isRecord(value)) throw new AccessGrantError();
6821
6907
  const subject = parseSubject(value.subject);
@@ -6852,7 +6938,7 @@ function accessGrantFromParsed(value) {
6852
6938
  }
6853
6939
  async function requireParsedAccessGrant(value) {
6854
6940
  if (typeof Response !== "undefined" && value instanceof Response) {
6855
- requireSuccessfulResponse(value);
6941
+ await requireSuccessfulResponse(value);
6856
6942
  try {
6857
6943
  return parseParsedAccessGrant(await value.json());
6858
6944
  } catch (error) {
@@ -6864,7 +6950,7 @@ async function requireParsedAccessGrant(value) {
6864
6950
  }
6865
6951
  async function requireAccessGrant(value) {
6866
6952
  if (typeof Response !== "undefined" && value instanceof Response) {
6867
- requireSuccessfulResponse(value);
6953
+ await requireSuccessfulResponse(value);
6868
6954
  try {
6869
6955
  return parseAccessGrant(await value.json());
6870
6956
  } catch (error) {
@@ -7007,6 +7093,7 @@ export {
7007
7093
  MembershipIdSchema,
7008
7094
  MembershipSchema,
7009
7095
  MembershipListSchema,
7096
+ ParticipantEpisodeStatusSchema,
7010
7097
  ParticipantJoinCancellationSchema,
7011
7098
  ParticipantLifecycleSchema,
7012
7099
  ParticipantRemovalSchema,
@@ -7163,6 +7250,9 @@ export {
7163
7250
  GetEpisodeAttendancePathParamsSchema,
7164
7251
  GetEpisodeAttendanceResponseSchema,
7165
7252
  GetEpisodeAttendance429ResponseHeadersSchema,
7253
+ GetParticipantEpisodeStatusPathParamsSchema,
7254
+ GetParticipantEpisodeStatusResponseSchema,
7255
+ GetParticipantEpisodeStatus429ResponseHeadersSchema,
7166
7256
  GetProblemReportAvailabilityPathParamsSchema,
7167
7257
  GetProblemReportAvailabilityResponseSchema,
7168
7258
  GetRecordingPathParamsSchema,
@@ -7490,6 +7580,9 @@ export {
7490
7580
  ParticipantInvalidIdError,
7491
7581
  ParticipantInvalidIdErrorWireSchema,
7492
7582
  ParticipantInvalidIdErrorSchema,
7583
+ ParticipantMediaReplacementPendingError,
7584
+ ParticipantMediaReplacementPendingErrorWireSchema,
7585
+ ParticipantMediaReplacementPendingErrorSchema,
7493
7586
  ParticipantNotActiveError,
7494
7587
  ParticipantNotActiveErrorWireSchema,
7495
7588
  ParticipantNotActiveErrorSchema,
@@ -7711,6 +7804,7 @@ export {
7711
7804
  GetChatAttachmentDownloadErrorSchema,
7712
7805
  GetEpisodeAttendanceErrorSchema,
7713
7806
  GetEpisodeErrorSchema,
7807
+ GetParticipantEpisodeStatusErrorSchema,
7714
7808
  GetProblemReportAvailabilityErrorSchema,
7715
7809
  GetRecordingErrorSchema,
7716
7810
  GetSpaceErrorSchema,
package/dist/client.d.ts CHANGED
@@ -1065,6 +1065,7 @@ export declare const createChalkEffectClient: (options: ChalkEffectClientOptions
1065
1065
  readonly tenant_id: import("effect/Schema").brand<import("effect/Schema").String, "TenantId">;
1066
1066
  }>>, never, import("effect/Schema").toCodecJson<import("effect/Schema").Struct<{
1067
1067
  readonly current_media_token: import("effect/Schema").optional<import("effect/Schema").String>;
1068
+ readonly expected_media_connection_id: import("effect/Schema").optional<import("effect/Schema").NullOr<import("effect/Schema").String>>;
1068
1069
  readonly participant_generation: import("effect/Schema").Number;
1069
1070
  readonly replace_media_connection: import("effect/Schema").Boolean;
1070
1071
  }>>, never, import("effect/Schema").toCodecJson<import("effect/Schema").Struct<{
@@ -1186,6 +1187,11 @@ export declare const createChalkEffectClient: (options: ChalkEffectClientOptions
1186
1187
  readonly code: import("effect/Schema").Literal<"participant.invalid_id">;
1187
1188
  readonly message: import("effect/Schema").String;
1188
1189
  }>;
1190
+ }>, never, never> | import("effect/Schema").decodeTo<typeof import("./effect").ParticipantMediaReplacementPendingError, import("effect/Schema").Struct<{
1191
+ readonly error: import("effect/Schema").Struct<{
1192
+ readonly code: import("effect/Schema").Literal<"participant.media_replacement_pending">;
1193
+ readonly message: import("effect/Schema").String;
1194
+ }>;
1189
1195
  }>, never, never> | import("effect/Schema").decodeTo<typeof import("./effect").ParticipantNotFoundError, import("effect/Schema").Struct<{
1190
1196
  readonly error: import("effect/Schema").Struct<{
1191
1197
  readonly code: import("effect/Schema").Literal<"participant.not_found">;
@@ -1770,15 +1776,22 @@ export declare const createChalkEffectClient: (options: ChalkEffectClientOptions
1770
1776
  readonly code: import("effect/Schema").optional<import("effect/Schema").Literals<readonly ["invalid_state", "invalid_access", "access_unavailable", "permission_denied", "device_not_found", "device_busy", "device_constraint_invalid", "media_capture_failed", "sync_start_failed", "state_digest_recovery_failed", "sync_hello_timeout", "media_start_failed", "join_cleanup_unconfirmed", "sync_recovery_exhausted", "media_recovery_exhausted", "command_rejected", "leave_unconfirmed", "episode_ended", "unsupported_environment", "internal_error", "collaboration_unavailable", "chat_cursor_reset_required", "rate_limited", "invalid_payload"]>>;
1771
1777
  readonly duration_ms: import("effect/Schema").optional<import("effect/Schema").NullOr<import("effect/Schema").Number>>;
1772
1778
  readonly elapsed_ms: import("effect/Schema").Number;
1773
- readonly event: import("effect/Schema").Literals<readonly ["space_join_span", "state_changed", "connection_failed", "sync_connect_failed", "sync_dial_timeout", "access_refreshed", "access_refresh_failed", "recovery_attempt", "recovery_succeeded", "recovery_exhausted", "cleanup_completed", "cleanup_unconfirmed", "sync_socket_open", "sync_socket_close", "sync_heartbeat_gap", "media_state", "media_http_error"]>;
1779
+ readonly event: import("effect/Schema").Literals<readonly ["space_join_span", "state_changed", "connection_failed", "sync_connect_failed", "sync_dial_timeout", "access_refreshed", "access_refresh_failed", "recovery_attempt", "recovery_succeeded", "recovery_exhausted", "cleanup_completed", "cleanup_unconfirmed", "sync_socket_open", "sync_socket_close", "sync_heartbeat_gap", "media_state", "media_http_error", "media_projection_mismatch"]>;
1780
+ readonly granted_audio: import("effect/Schema").optional<import("effect/Schema").Literals<readonly ["granted", "not_granted", "unknown"]>>;
1781
+ readonly granted_video: import("effect/Schema").optional<import("effect/Schema").Literals<readonly ["granted", "not_granted", "unknown"]>>;
1774
1782
  readonly heartbeat_gap_ms: import("effect/Schema").optional<import("effect/Schema").NullOr<import("effect/Schema").Number>>;
1775
1783
  readonly http_status: import("effect/Schema").optional<import("effect/Schema").NullOr<import("effect/Schema").Number>>;
1784
+ readonly media_error_kind: import("effect/Schema").optional<import("effect/Schema").Literals<readonly ["NotAllowedError", "NotReadableError", "NotFoundError", "OverconstrainedError", "AbortError", "SecurityError", "InvalidStateError", "OperationError", "NotSupportedError", "CloudflareSFUError", "network", "timeout", "unknown"]>>;
1785
+ readonly media_error_step: import("effect/Schema").optional<import("effect/Schema").Literals<readonly ["local_capture", "peer_connection", "access_refresh", "sfu_tracks", "sfu_close_tracks", "sfu_renegotiate", "sfu_publications"]>>;
1776
1786
  readonly outcome: import("effect/Schema").optional<import("effect/Schema").Literals<readonly ["started", "succeeded", "failed", "cancelled"]>>;
1777
1787
  readonly phase: import("effect/Schema").optional<import("effect/Schema").Literals<readonly ["idle", "connecting", "live", "recovering", "failed", "stopped", "new", "connected", "disconnected", "closed"]>>;
1788
+ readonly projection_state: import("effect/Schema").optional<import("effect/Schema").Literals<readonly ["on", "off"]>>;
1789
+ readonly publication_state: import("effect/Schema").optional<import("effect/Schema").Literals<readonly ["on", "off"]>>;
1790
+ readonly source: import("effect/Schema").optional<import("effect/Schema").Literals<readonly ["microphone", "camera"]>>;
1778
1791
  readonly state: import("effect/Schema").optional<import("effect/Schema").Literals<readonly ["idle", "joining", "live", "reconnecting", "leaving", "left", "failed"]>>;
1779
1792
  readonly step: import("effect/Schema").optional<import("effect/Schema").Literals<readonly ["join", "acquire_initial_media", "access_initialize", "create_media_client", "create_sync_client", "start_media", "start_sync", "wait_for_sync_live", "confirm_entered"]>>;
1780
1793
  }>>;
1781
- readonly trigger: import("effect/Schema").Literals<readonly ["join_failed", "connection_lost", "recovery_exhausted"]>;
1794
+ readonly trigger: import("effect/Schema").Literals<readonly ["join_failed", "connection_lost", "recovery_exhausted", "media_projection_mismatch"]>;
1782
1795
  readonly version: import("effect/Schema").Literal<1>;
1783
1796
  }>>, never, import("effect/Schema").toCodecJson<import("effect/Schema").Void>, import("effect/Schema").toCodecJson<import("effect/Schema").decodeTo<typeof import("./effect").AccessForbiddenError, import("effect/Schema").Struct<{
1784
1797
  readonly error: import("effect/Schema").Struct<{
@@ -2980,6 +2993,64 @@ export declare const createChalkEffectClient: (options: ChalkEffectClientOptions
2980
2993
  readonly message: import("effect/Schema").String;
2981
2994
  }>;
2982
2995
  }>, never, never>>, never, never>, never, never>;
2996
+ readonly getParticipantEpisodeStatus: HttpApiClient.Client.Method<import("effect/unstable/httpapi/HttpApiEndpoint").HttpApiEndpoint<"getParticipantEpisodeStatus", "GET", "/v1/tenants/:tenant_id/spaces/:space_id/episodes/:episode_id/participants/:participant_id/episode-status", import("effect/Schema").toCodecStringTree<import("effect/Schema").Struct<{
2997
+ readonly episode_id: import("effect/Schema").brand<import("effect/Schema").String, "EpisodeId">;
2998
+ readonly participant_id: import("effect/Schema").brand<import("effect/Schema").String, "ParticipantId">;
2999
+ readonly space_id: import("effect/Schema").brand<import("effect/Schema").String, "SpaceId">;
3000
+ readonly tenant_id: import("effect/Schema").brand<import("effect/Schema").String, "TenantId">;
3001
+ }>>, never, never, never, import("effect/Schema").toCodecJson<import("effect/Schema").Struct<{
3002
+ readonly status: import("effect/Schema").Literals<readonly ["active", "ending", "ended"]>;
3003
+ }>>, import("effect/Schema").toCodecJson<import("effect/Schema").decodeTo<typeof import("./effect").AccessForbiddenError, import("effect/Schema").Struct<{
3004
+ readonly error: import("effect/Schema").Struct<{
3005
+ readonly code: import("effect/Schema").Literal<"access.forbidden">;
3006
+ readonly message: import("effect/Schema").String;
3007
+ }>;
3008
+ }>, never, never> | import("effect/Schema").decodeTo<typeof import("./effect").AccessUnauthenticatedError, import("effect/Schema").Struct<{
3009
+ readonly error: import("effect/Schema").Struct<{
3010
+ readonly code: import("effect/Schema").Literal<"access.unauthenticated">;
3011
+ readonly message: import("effect/Schema").String;
3012
+ }>;
3013
+ }>, never, never> | import("effect/Schema").decodeTo<typeof import("./effect").EpisodeInvalidIdError, import("effect/Schema").Struct<{
3014
+ readonly error: import("effect/Schema").Struct<{
3015
+ readonly code: import("effect/Schema").Literal<"episode.invalid_id">;
3016
+ readonly message: import("effect/Schema").String;
3017
+ }>;
3018
+ }>, never, never> | import("effect/Schema").decodeTo<typeof import("./effect").EpisodeNotFoundError, import("effect/Schema").Struct<{
3019
+ readonly error: import("effect/Schema").Struct<{
3020
+ readonly code: import("effect/Schema").Literal<"episode.not_found">;
3021
+ readonly message: import("effect/Schema").String;
3022
+ }>;
3023
+ }>, never, never> | import("effect/Schema").decodeTo<typeof import("./effect").ParticipantInvalidIdError, import("effect/Schema").Struct<{
3024
+ readonly error: import("effect/Schema").Struct<{
3025
+ readonly code: import("effect/Schema").Literal<"participant.invalid_id">;
3026
+ readonly message: import("effect/Schema").String;
3027
+ }>;
3028
+ }>, never, never> | import("effect/Schema").decodeTo<typeof import("./effect").RequestRateLimitedError, import("effect/Schema").Struct<{
3029
+ readonly error: import("effect/Schema").Struct<{
3030
+ readonly code: import("effect/Schema").Literal<"request.rate_limited">;
3031
+ readonly message: import("effect/Schema").String;
3032
+ }>;
3033
+ }>, never, never> | import("effect/Schema").decodeTo<typeof import("./effect").ServiceInternalError, import("effect/Schema").Struct<{
3034
+ readonly error: import("effect/Schema").Struct<{
3035
+ readonly code: import("effect/Schema").Literal<"service.internal_error">;
3036
+ readonly message: import("effect/Schema").String;
3037
+ }>;
3038
+ }>, never, never> | import("effect/Schema").decodeTo<typeof import("./effect").ServiceUnavailableError, import("effect/Schema").Struct<{
3039
+ readonly error: import("effect/Schema").Struct<{
3040
+ readonly code: import("effect/Schema").Literal<"service.unavailable">;
3041
+ readonly message: import("effect/Schema").String;
3042
+ }>;
3043
+ }>, never, never> | import("effect/Schema").decodeTo<typeof import("./effect").SpaceInvalidIdError, import("effect/Schema").Struct<{
3044
+ readonly error: import("effect/Schema").Struct<{
3045
+ readonly code: import("effect/Schema").Literal<"space.invalid_id">;
3046
+ readonly message: import("effect/Schema").String;
3047
+ }>;
3048
+ }>, never, never> | import("effect/Schema").decodeTo<typeof import("./effect").TenantInvalidIdError, import("effect/Schema").Struct<{
3049
+ readonly error: import("effect/Schema").Struct<{
3050
+ readonly code: import("effect/Schema").Literal<"tenant.invalid_id">;
3051
+ readonly message: import("effect/Schema").String;
3052
+ }>;
3053
+ }>, never, never>>, never, never>, never, never>;
2983
3054
  readonly issueEpisodeParticipantSyncToken: HttpApiClient.Client.Method<import("effect/unstable/httpapi/HttpApiEndpoint").HttpApiEndpoint<"issueEpisodeParticipantSyncToken", "POST", "/v1/tenants/:tenant_id/spaces/:space_id/episodes/:episode_id/participants/:participant_id/sync-token", import("effect/Schema").toCodecStringTree<import("effect/Schema").Struct<{
2984
3055
  readonly episode_id: import("effect/Schema").brand<import("effect/Schema").String, "EpisodeId">;
2985
3056
  readonly participant_id: import("effect/Schema").brand<import("effect/Schema").String, "ParticipantId">;
@@ -1,3 +1,4 @@
1
+ import type { ParticipantEpisodeStatus } from "../generated/schemas";
1
2
  import type { ConnectionReporter, ConnectionReportTransportEvent } from "./report";
2
3
  import type { ClientMediaPlane, CloudflareSFUBootstrap, ConnectionMediaSnapshot } from "../media";
3
4
  import type { ChalkChatFileTransport } from "../chat-files";
@@ -13,6 +14,7 @@ export type ConnectionAccessRequest = {
13
14
  readonly signal?: AbortSignal;
14
15
  readonly currentMediaToken?: ParticipantMediaCredential;
15
16
  readonly expectedParticipantGeneration?: number;
17
+ readonly expectedMediaConnectionId?: string;
16
18
  };
17
19
  export type ConnectionAccessProvider = (request?: ConnectionAccessRequest) => ParsedAccessGrant | Promise<ParsedAccessGrant>;
18
20
  export type ConnectionClock = {
@@ -82,7 +84,7 @@ export type ConnectionMediaFactoryInput = {
82
84
  readonly replaceMediaConnection?: () => Promise<ParticipantMediaAccess>;
83
85
  readonly traceparent?: string;
84
86
  readonly onTransportDiagnostic?: (event: ConnectionReportTransportEvent) => void;
85
- readonly onFailure: (error: unknown) => void;
87
+ readonly onFailure: (error: unknown, mediaConnectionId?: string) => void;
86
88
  readonly onScreenEnded: () => void;
87
89
  };
88
90
  export type ConnectionSyncFactoryInput = {
@@ -103,6 +105,7 @@ export type ConnectionChatFileFactoryInput = {
103
105
  export type ConnectionDependencies = {
104
106
  readonly clock: ConnectionClock;
105
107
  readonly createConnectionReporter?: (access: () => ParsedAccessGrant | null) => ConnectionReporter | undefined;
108
+ readonly getEpisodeStatus?: (access: ParsedAccessGrant, signal: AbortSignal) => Promise<ParticipantEpisodeStatus["status"]>;
106
109
  readonly cancelPendingAdmission?: (access: ParsedAccessGrant, signal: AbortSignal) => Promise<boolean>;
107
110
  readonly mediaDevices: ConnectionMediaDevices;
108
111
  readonly createMediaClient: (input: ConnectionMediaFactoryInput) => ConnectionMediaClient;
@@ -18,8 +18,10 @@ export type ConnectionJoinTraceEnd = {
18
18
  readonly epoch: number;
19
19
  readonly outcome: Exclude<ConnectionJoinTraceOutcome, "started">;
20
20
  readonly code?: ConnectionErrorCode;
21
+ readonly media?: import("../media/failure-diagnostics").MediaFailureDiagnostic & import("../media/failure-diagnostics").GrantedMedia;
21
22
  };
22
23
  export type ConnectionDiagnostic = {
24
+ readonly media?: import("../media/failure-diagnostics").MediaFailureDiagnostic & import("../media/failure-diagnostics").GrantedMedia;
23
25
  readonly timestamp: number;
24
26
  readonly event: ConnectionDiagnosticEventName;
25
27
  readonly state: ConnectionState;
@@ -54,6 +56,8 @@ export declare class ConnectionDiagnostics {
54
56
  readonly code: "sync_recovery_exhausted" | "media_recovery_exhausted";
55
57
  readonly attempts: number;
56
58
  readonly transport: import("../sync/connect-diagnostics").SyncRecoveryDiagnostic | null;
59
+ readonly media?: ConnectionDiagnostic["media"];
60
+ readonly grantedMedia: import("../media/failure-diagnostics").GrantedMedia;
57
61
  }): void;
58
62
  snapshot(): readonly ConnectionDiagnostic[];
59
63
  startSpan(input: {
@@ -0,0 +1,7 @@
1
+ export declare class EpisodeStatusError extends Error {
2
+ readonly status: number;
3
+ readonly retryAfterMs: number;
4
+ constructor(status: number, retryAfterMs?: number);
5
+ }
6
+ export declare function episodeStatusRetryDelay(attempt: number, error: unknown): number;
7
+ export declare function retryAfterMilliseconds(value: string | null, now: number): number;
@@ -34,7 +34,9 @@ export type ConnectionOptions = {
34
34
  readonly initialCameraEnabled?: boolean;
35
35
  readonly accessRefreshWindowMs?: number;
36
36
  readonly recovery?: {
37
+ /** Sync attempt cap. Recoverable media failures retry until budgetMs expires. */
37
38
  readonly maxAttempts?: number;
39
+ /** Foreground recovery budget for either transport; defaults to 60 seconds. */
38
40
  readonly budgetMs?: number;
39
41
  readonly backoffMs?: readonly number[];
40
42
  };
@@ -39,6 +39,7 @@ export type ConnectionLifecycleCapability = {
39
39
  }>) => Effect.Effect<void, ConnectionLifecycleFailure>;
40
40
  readonly getSyncToken: () => Effect.Effect<string, ConnectionLifecycleFailure>;
41
41
  readonly confirmEpisodeEnded: Effect.Effect<void>;
42
+ readonly runEpisodeEnd: <A, E>(operation: Effect.Effect<A, E>) => Effect.Effect<A, E>;
42
43
  readonly join: () => Effect.Effect<void, ConnectionLifecycleFailure>;
43
44
  readonly leave: () => Effect.Effect<void, ConnectionLifecycleFailure>;
44
45
  readonly runCommand: <A, E>(operation: (ports: ConnectionPorts) => Effect.Effect<A, E>) => Effect.Effect<A, ConnectionLifecycleFailure | E>;
@@ -47,6 +48,7 @@ export type ConnectionLifecycleCapability = {
47
48
  readonly scheduleUnsafe: (callback: () => void, milliseconds: number) => unknown;
48
49
  readonly cancelScheduleUnsafe: (handle: unknown) => void;
49
50
  readonly createId: () => string;
51
+ readonly recordTransportDiagnostic: (event: import("./report").ConnectionReportTransportEvent) => void;
50
52
  };
51
53
  declare const ConnectionLifecycleService_base: Context.ServiceClass<ConnectionLifecycleService, "@chalk/client/ConnectionLifecycle", ConnectionLifecycleCapability>;
52
54
  export declare class ConnectionLifecycleService extends ConnectionLifecycleService_base {
package/dist/effect.js CHANGED
@@ -17,8 +17,8 @@ import {
17
17
  makeSpaceClientCoreLayer,
18
18
  makeSpaceClientCoreLayerFromServices,
19
19
  makeSpaceStoreLayer
20
- } from "./chunk-LDPC2JZB.js";
21
- import "./chunk-3ASKGMD3.js";
20
+ } from "./chunk-BUNSEDXL.js";
21
+ import "./chunk-FD25AMLG.js";
22
22
  import {
23
23
  APIKeyListSchema,
24
24
  APIKeyWithSecretSchema,
@@ -261,6 +261,10 @@ import {
261
261
  GetEpisodeErrorSchema,
262
262
  GetEpisodePathParamsSchema,
263
263
  GetEpisodeResponseSchema,
264
+ GetParticipantEpisodeStatus429ResponseHeadersSchema,
265
+ GetParticipantEpisodeStatusErrorSchema,
266
+ GetParticipantEpisodeStatusPathParamsSchema,
267
+ GetParticipantEpisodeStatusResponseSchema,
264
268
  GetProblemReportAvailabilityErrorSchema,
265
269
  GetProblemReportAvailabilityPathParamsSchema,
266
270
  GetProblemReportAvailabilityResponseSchema,
@@ -451,6 +455,7 @@ import {
451
455
  ParticipantConnectionSupersededError,
452
456
  ParticipantConnectionSupersededErrorSchema,
453
457
  ParticipantConnectionSupersededErrorWireSchema,
458
+ ParticipantEpisodeStatusSchema,
454
459
  ParticipantGenerationMismatchError,
455
460
  ParticipantGenerationMismatchErrorSchema,
456
461
  ParticipantGenerationMismatchErrorWireSchema,
@@ -460,6 +465,9 @@ import {
460
465
  ParticipantInvalidIdErrorWireSchema,
461
466
  ParticipantJoinCancellationSchema,
462
467
  ParticipantLifecycleSchema,
468
+ ParticipantMediaReplacementPendingError,
469
+ ParticipantMediaReplacementPendingErrorSchema,
470
+ ParticipantMediaReplacementPendingErrorWireSchema,
463
471
  ParticipantNotActiveError,
464
472
  ParticipantNotActiveErrorSchema,
465
473
  ParticipantNotActiveErrorWireSchema,
@@ -833,7 +841,7 @@ import {
833
841
  WhiteboardStorageUnavailableErrorSchema,
834
842
  WhiteboardStorageUnavailableErrorWireSchema,
835
843
  createChalkEffectClient
836
- } from "./chunk-AZONR3Q3.js";
844
+ } from "./chunk-UMAE5GCV.js";
837
845
  import "./chunk-5YPQNMJE.js";
838
846
 
839
847
  // src/space-client/effect.ts
@@ -1117,6 +1125,10 @@ export {
1117
1125
  GetEpisodeErrorSchema,
1118
1126
  GetEpisodePathParamsSchema,
1119
1127
  GetEpisodeResponseSchema,
1128
+ GetParticipantEpisodeStatus429ResponseHeadersSchema,
1129
+ GetParticipantEpisodeStatusErrorSchema,
1130
+ GetParticipantEpisodeStatusPathParamsSchema,
1131
+ GetParticipantEpisodeStatusResponseSchema,
1120
1132
  GetProblemReportAvailabilityErrorSchema,
1121
1133
  GetProblemReportAvailabilityPathParamsSchema,
1122
1134
  GetProblemReportAvailabilityResponseSchema,
@@ -1307,6 +1319,7 @@ export {
1307
1319
  ParticipantConnectionSupersededError,
1308
1320
  ParticipantConnectionSupersededErrorSchema,
1309
1321
  ParticipantConnectionSupersededErrorWireSchema,
1322
+ ParticipantEpisodeStatusSchema,
1310
1323
  ParticipantGenerationMismatchError,
1311
1324
  ParticipantGenerationMismatchErrorSchema,
1312
1325
  ParticipantGenerationMismatchErrorWireSchema,
@@ -1316,6 +1329,9 @@ export {
1316
1329
  ParticipantInvalidIdErrorWireSchema,
1317
1330
  ParticipantJoinCancellationSchema,
1318
1331
  ParticipantLifecycleSchema,
1332
+ ParticipantMediaReplacementPendingError,
1333
+ ParticipantMediaReplacementPendingErrorSchema,
1334
+ ParticipantMediaReplacementPendingErrorWireSchema,
1319
1335
  ParticipantNotActiveError,
1320
1336
  ParticipantNotActiveErrorSchema,
1321
1337
  ParticipantNotActiveErrorWireSchema,