@q9labsai/chalk-client 5.2.3 → 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.
Files changed (37) hide show
  1. package/README.md +1 -1
  2. package/dist/access/grant.d.ts +2 -1
  3. package/dist/access/manager.d.ts +1 -0
  4. package/dist/{chunk-IMMT22US.js → chunk-5YPQNMJE.js} +11 -0
  5. package/dist/{chunk-4ZUN55Z2.js → chunk-BUNSEDXL.js} +840 -185
  6. package/dist/{chunk-DWKTGBHR.js → chunk-FD25AMLG.js} +322 -206
  7. package/dist/{chunk-6LNRDKJF.js → chunk-LKNT6XFD.js} +1 -1
  8. package/dist/{chunk-GA3JDPFI.js → chunk-UMAE5GCV.js} +205 -5
  9. package/dist/client.d.ts +131 -0
  10. package/dist/connection/dependencies.d.ts +10 -1
  11. package/dist/connection/diagnostics.d.ts +4 -0
  12. package/dist/connection/episode-status.d.ts +7 -0
  13. package/dist/connection/index.d.ts +2 -0
  14. package/dist/connection/lifecycle.d.ts +2 -0
  15. package/dist/connection/report.d.ts +21 -0
  16. package/dist/effect.js +30 -4
  17. package/dist/generated/http-api.d.ts +129 -0
  18. package/dist/generated/schemas.d.ts +219 -0
  19. package/dist/index.js +5 -5
  20. package/dist/media/client.d.ts +1 -1
  21. package/dist/media/failure-diagnostics.d.ts +10 -0
  22. package/dist/media/index.js +1 -1
  23. package/dist/media/plane.d.ts +1 -0
  24. package/dist/media/types.d.ts +5 -1
  25. package/dist/public-invites/index.js +2 -2
  26. package/dist/server/access-refresh.d.cts +1 -1
  27. package/dist/server/access-refresh.d.ts +1 -1
  28. package/dist/server/index.cjs +15 -5
  29. package/dist/server/index.js +15 -5
  30. package/dist/server/types.d.cts +2 -1
  31. package/dist/server/types.d.ts +2 -1
  32. package/dist/space-client/media-projection-monitor.d.ts +26 -0
  33. package/dist/space-client/types.d.ts +4 -0
  34. package/dist/sync/index.js +1 -1
  35. package/dist/sync/v1-types.d.ts +3 -0
  36. package/dist/transport-diagnostics.d.ts +3 -0
  37. package/package.json +2 -2
package/README.md CHANGED
@@ -311,7 +311,7 @@ SpaceClient negotiates `collaboration_v2` for the 24-emoji set and per-message r
311
311
 
312
312
  `await client.media.setScreenShareEnabled(true, { surface: "browser", audio: true })` requests tab audio. The browser picker remains authoritative: selecting a window or declining audio still shares video normally. Audio is published separately as `screen_audio`; it starts, stops, and is revoked with the share, never with the microphone. `media.screenShare.hasAudio` reports local live audio; `participants.roster[].media.screenShareHasAudio` reports the remote publication. `media.remote` contains the received track.
313
313
 
314
- The sharer keeps local playback (`suppressLocalAudioPlayback: false`). Display audio disables echo cancellation, noise suppression and automatic gain control to preserve music; microphone capture and its processing are unchanged. System audio is excluded to avoid sending the call back to itself. Headphones avoid acoustic doubling through the microphone; local playback cannot be preserved while guaranteeing that loudspeakers never leak into it. Chrome documents [local playback control](https://developer.chrome.com/blog/screen-sharing-improvements-in-chrome-109) and [system-audio feedback](https://developer.chrome.com/docs/web-platform/screen-sharing-controls). [Meet documents the same “Also share tab audio” picker control](https://support.google.com/meet/answer/9308856?hl=en). No public X documentation establishing its echo default was found.
314
+ The sharer keeps local playback (`suppressLocalAudioPlayback: false`). Display audio disables echo cancellation, noise suppression and automatic gain control to preserve music; microphone capture and its processing are unchanged. System audio is excluded to avoid sending the call back to itself. Headphones avoid acoustic doubling through the microphone; local playback cannot be preserved while guaranteeing that loudspeakers never leak into it. Chrome documents [local playback control](https://developer.chrome.com/blog/screen-sharing-improvements-in-chrome-109) and [system-audio feedback](https://developer.chrome.com/docs/web-platform/screen-sharing-controls). [Meet documents the same “Also share tab audio” picker control](https://support.google.com/meet/answer/9308856?hl=en).
315
315
 
316
316
  Shared tab audio is excluded from recordings until the recording format supports it. React Native display capture behavior is unchanged.
317
317
 
@@ -39,8 +39,9 @@ export type AccessGrant = {
39
39
  };
40
40
  export type AccessGrantProvider = () => ParsedAccessGrant | Promise<ParsedAccessGrant>;
41
41
  export declare class AccessGrantError extends TypeError {
42
+ readonly reason?: "connection_superseded" | undefined;
42
43
  readonly code: "access.invalid";
43
- constructor(message?: string);
44
+ constructor(message?: string, reason?: "connection_superseded" | undefined);
44
45
  }
45
46
  export declare function parseParsedAccessGrant(value: unknown): ParsedAccessGrant;
46
47
  export declare function parseAccessGrant(value: unknown): AccessGrant;
@@ -23,6 +23,7 @@ export type ConnectionAccessEffectService = {
23
23
  readonly subscribeAutomaticMediaReplacement: (listener: AutomaticMediaReplacementListener) => Effect.Effect<() => void>;
24
24
  readonly requiresRefresh: Effect.Effect<boolean>;
25
25
  readonly millisecondsUntilRefresh: Effect.Effect<number | null>;
26
+ readonly holdMediaBinding: (binding: string) => Effect.Effect<Effect.Effect<void>>;
26
27
  readonly clear: Effect.Effect<void>;
27
28
  };
28
29
  declare const ConnectionAccessService_base: Context.ServiceClass<ConnectionAccessService, "@chalk/client/ConnectionAccess", ConnectionAccessEffectService>;
@@ -3303,6 +3303,7 @@ var V1SyncClient = class {
3303
3303
  this.#phase = { phase: "connecting" };
3304
3304
  this.#connectAttemptCount += 1;
3305
3305
  this.#connectStartedAt = this.#clock().now();
3306
+ const socketStartedAt = this.#connectStartedAt;
3306
3307
  this.#opened = false;
3307
3308
  if (this.#connectFailure?.opened) this.#connectFailure = void 0;
3308
3309
  this.#emit();
@@ -3331,6 +3332,7 @@ var V1SyncClient = class {
3331
3332
  if (socket !== this.#socket) return;
3332
3333
  this.#clearDial();
3333
3334
  this.#opened = true;
3335
+ this.#diagnostic({ event: "sync_socket_open", attempt: this.#connectAttemptCount, duration_ms: this.#clock().now() - socketStartedAt });
3334
3336
  this.#connectFailure = void 0;
3335
3337
  void this.#authenticate(socket);
3336
3338
  };
@@ -3338,6 +3340,7 @@ var V1SyncClient = class {
3338
3340
  this.#inbound = this.#inbound.then(() => this.#receive(socket, event.data));
3339
3341
  };
3340
3342
  socket.onclose = (event) => {
3343
+ this.#diagnostic({ event: "sync_socket_close", close_code: event.code, duration_ms: this.#clock().now() - socketStartedAt, ...this.#lastHeartbeatReplyAt === null ? {} : { heartbeat_gap_ms: this.#now() - this.#lastHeartbeatReplyAt } });
3341
3344
  if (this.#started) {
3342
3345
  this.#socketCloses.push({ code: event.code, wasClean: event.wasClean ?? null });
3343
3346
  if (this.#socketCloses.length > 50) {
@@ -3376,6 +3379,7 @@ var V1SyncClient = class {
3376
3379
  const hello = {
3377
3380
  type: "hello",
3378
3381
  protocol: 1,
3382
+ ...this.#options.traceparent ? { traceparent: this.#options.traceparent } : {},
3379
3383
  token,
3380
3384
  streams: {
3381
3385
  control: { cursor: this.#control && { revision: this.#control.revision, state_schema_version: this.#control.stateSchemaVersion, state_digest: this.#control.stateDigest } },
@@ -3829,12 +3833,19 @@ var V1SyncClient = class {
3829
3833
  #updateLocalMediaStates() {
3830
3834
  this.#liveTargets.updateFromPublications(this.#localPublications);
3831
3835
  }
3836
+ #diagnostic(event) {
3837
+ try {
3838
+ this.#options.onDiagnostic?.(event);
3839
+ } catch {
3840
+ }
3841
+ }
3832
3842
  #startHeartbeat() {
3833
3843
  this.#clearHeartbeat();
3834
3844
  this.#heartbeatTimer = this.#clock().setTimeout(() => {
3835
3845
  this.#heartbeatTimer = void 0;
3836
3846
  if (this.#phase.phase !== "live") return;
3837
3847
  this.#missedHeartbeats += 1;
3848
+ if (this.#missedHeartbeats > 1) this.#diagnostic({ event: "sync_heartbeat_gap", duration_ms: this.#missedHeartbeats * 2e4, ...this.#lastHeartbeatReplyAt === null ? {} : { heartbeat_gap_ms: this.#now() - this.#lastHeartbeatReplyAt } });
3838
3849
  if (this.#missedHeartbeats > 2) {
3839
3850
  this.#socket?.close(CLIENT_RESTART_CLOSE_CODE, "heartbeat timeout");
3840
3851
  return;