doover-js 0.5.3 → 0.6.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.
Files changed (156) hide show
  1. package/README.md +146 -0
  2. package/dist/apis/_args.d.ts +16 -0
  3. package/dist/apis/_args.js +26 -0
  4. package/dist/apis/agents-api.d.ts +4 -1
  5. package/dist/apis/agents-api.js +139 -1
  6. package/dist/apis/aggregates-api.d.ts +23 -3
  7. package/dist/apis/aggregates-api.js +33 -4
  8. package/dist/apis/alarms-api.d.ts +30 -0
  9. package/dist/apis/alarms-api.js +51 -6
  10. package/dist/apis/channels-api.d.ts +40 -3
  11. package/dist/apis/channels-api.js +50 -5
  12. package/dist/apis/connections-api.d.ts +21 -5
  13. package/dist/apis/connections-api.js +26 -10
  14. package/dist/apis/messages-api.d.ts +54 -9
  15. package/dist/apis/messages-api.js +94 -12
  16. package/dist/apis/notifications-api.d.ts +52 -0
  17. package/dist/apis/notifications-api.js +99 -13
  18. package/dist/apis/permissions-api.d.ts +8 -0
  19. package/dist/apis/permissions-api.js +11 -2
  20. package/dist/apis/processors-api.d.ts +35 -0
  21. package/dist/apis/processors-api.js +64 -8
  22. package/dist/apis/users-api.d.ts +8 -0
  23. package/dist/apis/users-api.js +13 -0
  24. package/dist/client/capabilities.d.ts +10 -0
  25. package/dist/client/capabilities.js +43 -0
  26. package/dist/client/data-client.d.ts +104 -0
  27. package/dist/client/data-client.js +2 -0
  28. package/dist/client/doover-client.d.ts +31 -31
  29. package/dist/client/doover-client.js +58 -37
  30. package/dist/client/errors.d.ts +23 -0
  31. package/dist/client/errors.js +50 -0
  32. package/dist/client/local-agent-client.d.ts +65 -0
  33. package/dist/client/local-agent-client.js +222 -0
  34. package/dist/client/multiplex-client.d.ts +151 -0
  35. package/dist/client/multiplex-client.js +744 -0
  36. package/dist/client/multiplex-gateway.d.ts +49 -0
  37. package/dist/client/multiplex-gateway.js +114 -0
  38. package/dist/client/multiplex-merge.d.ts +12 -0
  39. package/dist/client/multiplex-merge.js +42 -0
  40. package/dist/client/provenance.d.ts +60 -0
  41. package/dist/client/provenance.js +113 -0
  42. package/dist/client/stats.d.ts +24 -0
  43. package/dist/client/stats.js +62 -0
  44. package/dist/client/status-tracker.d.ts +24 -0
  45. package/dist/client/status-tracker.js +90 -0
  46. package/dist/gateway/gateway-client.d.ts +23 -1
  47. package/dist/gateway/gateway-client.js +75 -6
  48. package/dist/http/rest-client.d.ts +5 -0
  49. package/dist/index.d.ts +15 -0
  50. package/dist/index.js +22 -7
  51. package/dist/react/context.d.ts +9 -5
  52. package/dist/react/context.js +6 -2
  53. package/dist/react/index.d.ts +3 -0
  54. package/dist/react/index.js +3 -1
  55. package/dist/react/useChannelAggregate.d.ts +8 -1
  56. package/dist/react/useChannelAggregate.js +24 -6
  57. package/dist/react/useChannelMessage.d.ts +8 -1
  58. package/dist/react/useChannelMessage.js +17 -6
  59. package/dist/react/useChannelMessages.d.ts +8 -1
  60. package/dist/react/useChannelMessages.js +21 -7
  61. package/dist/react/useChannelSubscription.d.ts +6 -0
  62. package/dist/react/useChannelSubscription.js +8 -18
  63. package/dist/react/useClientStatus.d.ts +10 -0
  64. package/dist/react/useClientStatus.js +22 -0
  65. package/dist/react/useConnectionState.d.ts +5 -0
  66. package/dist/react/useConnectionState.js +5 -0
  67. package/dist/react/useMultiAgentAggregates.d.ts +8 -1
  68. package/dist/react/useMultiAgentAggregates.js +25 -21
  69. package/dist/react/useMultiAgentChannelMessages.d.ts +8 -1
  70. package/dist/react/useMultiAgentChannelMessages.js +23 -18
  71. package/dist/react/useSendMessage.d.ts +8 -1
  72. package/dist/react/useSendMessage.js +15 -2
  73. package/dist/react/useSendRpc.js +4 -1
  74. package/dist/react/useUpdateAggregate.d.ts +6 -0
  75. package/dist/react/useUpdateAggregate.js +20 -4
  76. package/dist/react/useUpdateMessage.d.ts +5 -0
  77. package/dist/react/useUpdateMessage.js +11 -2
  78. package/dist/rpc/errors.d.ts +10 -0
  79. package/dist/rpc/errors.js +23 -0
  80. package/dist/rpc/rpc-dispatcher.d.ts +28 -0
  81. package/dist/rpc/rpc-dispatcher.js +129 -0
  82. package/dist/test/api-args.test.d.ts +1 -0
  83. package/dist/test/api-args.test.js +48 -0
  84. package/dist/test/api-overloads.test.d.ts +9 -0
  85. package/dist/test/api-overloads.test.js +276 -0
  86. package/dist/test/capabilities.test.d.ts +1 -0
  87. package/dist/test/capabilities.test.js +27 -0
  88. package/dist/test/data-client-errors.test.d.ts +1 -0
  89. package/dist/test/data-client-errors.test.js +24 -0
  90. package/dist/test/data-client-shape.test.d.ts +1 -0
  91. package/dist/test/data-client-shape.test.js +28 -0
  92. package/dist/test/doover-client-dataclient.test.d.ts +1 -0
  93. package/dist/test/doover-client-dataclient.test.js +58 -0
  94. package/dist/test/doover-client-provenance.test.d.ts +1 -0
  95. package/dist/test/doover-client-provenance.test.js +32 -0
  96. package/dist/test/exports.test.d.ts +1 -0
  97. package/dist/test/exports.test.js +76 -0
  98. package/dist/test/gateway-provenance.test.d.ts +1 -0
  99. package/dist/test/gateway-provenance.test.js +29 -0
  100. package/dist/test/gateway-subscriptions.test.d.ts +1 -0
  101. package/dist/test/gateway-subscriptions.test.js +95 -0
  102. package/dist/test/local-agent-client.test.d.ts +1 -0
  103. package/dist/test/local-agent-client.test.js +202 -0
  104. package/dist/test/multiplex-capabilities.test.d.ts +1 -0
  105. package/dist/test/multiplex-capabilities.test.js +37 -0
  106. package/dist/test/multiplex-conflicts.test.d.ts +1 -0
  107. package/dist/test/multiplex-conflicts.test.js +35 -0
  108. package/dist/test/multiplex-gateway.test.d.ts +1 -0
  109. package/dist/test/multiplex-gateway.test.js +103 -0
  110. package/dist/test/multiplex-merge.test.d.ts +1 -0
  111. package/dist/test/multiplex-merge.test.js +19 -0
  112. package/dist/test/multiplex-noncore.test.d.ts +1 -0
  113. package/dist/test/multiplex-noncore.test.js +82 -0
  114. package/dist/test/multiplex-passthrough.test.d.ts +1 -0
  115. package/dist/test/multiplex-passthrough.test.js +35 -0
  116. package/dist/test/multiplex-reads.test.d.ts +1 -0
  117. package/dist/test/multiplex-reads.test.js +87 -0
  118. package/dist/test/multiplex-registry.test.d.ts +1 -0
  119. package/dist/test/multiplex-registry.test.js +81 -0
  120. package/dist/test/multiplex-routing.test.d.ts +1 -0
  121. package/dist/test/multiplex-routing.test.js +45 -0
  122. package/dist/test/multiplex-status.test.d.ts +1 -0
  123. package/dist/test/multiplex-status.test.js +63 -0
  124. package/dist/test/multiplex-writes.test.d.ts +1 -0
  125. package/dist/test/multiplex-writes.test.js +93 -0
  126. package/dist/test/provenance-regression.test.d.ts +1 -0
  127. package/dist/test/provenance-regression.test.js +45 -0
  128. package/dist/test/provenance-stamper.test.d.ts +1 -0
  129. package/dist/test/provenance-stamper.test.js +41 -0
  130. package/dist/test/provenance-type.test.d.ts +1 -0
  131. package/dist/test/provenance-type.test.js +15 -0
  132. package/dist/test/react-client-status.test.d.ts +1 -0
  133. package/dist/test/react-client-status.test.js +35 -0
  134. package/dist/test/react-dataclient.test.d.ts +1 -0
  135. package/dist/test/react-dataclient.test.js +28 -0
  136. package/dist/test/react-exports.test.d.ts +1 -0
  137. package/dist/test/react-exports.test.js +45 -0
  138. package/dist/test/react-sources-option.test.d.ts +1 -0
  139. package/dist/test/react-sources-option.test.js +41 -0
  140. package/dist/test/react.test.js +2 -2
  141. package/dist/test/rpc-dispatcher.test.d.ts +1 -0
  142. package/dist/test/rpc-dispatcher.test.js +190 -0
  143. package/dist/test/stats-rpc.test.d.ts +1 -0
  144. package/dist/test/stats-rpc.test.js +69 -0
  145. package/dist/test/status-tracker.test.d.ts +1 -0
  146. package/dist/test/status-tracker.test.js +85 -0
  147. package/dist/test/users-api.test.d.ts +1 -0
  148. package/dist/test/users-api.test.js +19 -0
  149. package/dist/types/common.d.ts +18 -1
  150. package/dist/types/openapi.d.ts +1 -0
  151. package/dist/types/provenance.d.ts +45 -0
  152. package/dist/types/provenance.js +2 -0
  153. package/dist/types/viewer.d.ts +3 -0
  154. package/dist/viewer/doover-data-provider.d.ts +30 -34
  155. package/dist/viewer/doover-data-provider.js +82 -316
  156. package/package.json +1 -1
@@ -2,7 +2,16 @@ import type { DooverAuth } from "../auth/doover-auth";
2
2
  import type { DooverStatsCollector } from "../client/stats";
3
3
  import type { DooverClientConfig } from "../http/rest-client";
4
4
  import type { GatewayListenerMap, WebSocketSession } from "./types";
5
- import type { ChannelRef, JSONValue } from "../types/common";
5
+ import type { Aggregate, ChannelRef, JSONValue, MessageStructure } from "../types/common";
6
+ export type GatewayProvenanceHook = <T>(value: T, ctx: {
7
+ event: string;
8
+ sessionId?: string;
9
+ }) => any;
10
+ export interface ChannelHandlers {
11
+ onMessage?: (msg: MessageStructure) => void;
12
+ onMessageUpdate?: (msg: MessageStructure, requestData?: JSONValue) => void;
13
+ onAggregate?: (agg: Aggregate) => void;
14
+ }
6
15
  export declare class GatewayClient {
7
16
  private readonly config;
8
17
  private socket;
@@ -15,11 +24,18 @@ export declare class GatewayClient {
15
24
  private opening;
16
25
  private listeners;
17
26
  private subscriptions;
27
+ private channelRegistry;
18
28
  private readonly auth;
19
29
  private stats;
30
+ private provenanceHook;
20
31
  constructor(config: DooverClientConfig, auth?: DooverAuth);
21
32
  /** Attach a stats collector. Call with `null` to detach. */
22
33
  setStats(stats: DooverStatsCollector | null): void;
34
+ /** Optional hook that stamps `__source` provenance onto emitted gateway
35
+ * payloads. `DooverClient` / `LocalAgentClient` set this; standalone
36
+ * `GatewayClient` users leave it null and get raw payloads. */
37
+ setProvenanceHook(hook: GatewayProvenanceHook | null): void;
38
+ private stamp;
23
39
  connect(): Promise<void>;
24
40
  private openSocket;
25
41
  disconnect(code?: number, reason?: string): void;
@@ -29,6 +45,12 @@ export declare class GatewayClient {
29
45
  diff_only?: boolean;
30
46
  }): void;
31
47
  unsubscribe(channel: ChannelRef): void;
48
+ /**
49
+ * Attach channel-scoped handlers. Returns an idempotent unsubscribe fn.
50
+ * The first handler for a channel triggers a wire-level subscribe; the
51
+ * last detach triggers a wire-level unsubscribe.
52
+ */
53
+ subscribeToChannel(channel: ChannelRef, handlers: ChannelHandlers): () => void;
32
54
  syncChannel(channel: ChannelRef): void;
33
55
  sendOneShotMessage(channel: ChannelRef, data: JSONValue): void;
34
56
  getSession(): WebSocketSession | null;
@@ -32,7 +32,9 @@ class GatewayClient {
32
32
  close: new Set(),
33
33
  };
34
34
  this.subscriptions = new Map();
35
+ this.channelRegistry = new Map();
35
36
  this.stats = null;
37
+ this.provenanceHook = null;
36
38
  this.handleVisibilityChange = () => {
37
39
  if (typeof document === "undefined")
38
40
  return;
@@ -50,6 +52,20 @@ class GatewayClient {
50
52
  setStats(stats) {
51
53
  this.stats = stats;
52
54
  }
55
+ /** Optional hook that stamps `__source` provenance onto emitted gateway
56
+ * payloads. `DooverClient` / `LocalAgentClient` set this; standalone
57
+ * `GatewayClient` users leave it null and get raw payloads. */
58
+ setProvenanceHook(hook) {
59
+ this.provenanceHook = hook;
60
+ }
61
+ stamp(value, event) {
62
+ if (!this.provenanceHook)
63
+ return value;
64
+ return this.provenanceHook(value, {
65
+ event,
66
+ ...(this.session?.session_id ? { sessionId: this.session.session_id } : {}),
67
+ });
68
+ }
53
69
  async connect() {
54
70
  this.explicitlyDisconnected = false;
55
71
  if (this.socket && this.socket.readyState <= WebSocket.OPEN) {
@@ -151,6 +167,59 @@ class GatewayClient {
151
167
  },
152
168
  });
153
169
  }
170
+ /**
171
+ * Attach channel-scoped handlers. Returns an idempotent unsubscribe fn.
172
+ * The first handler for a channel triggers a wire-level subscribe; the
173
+ * last detach triggers a wire-level unsubscribe.
174
+ */
175
+ subscribeToChannel(channel, handlers) {
176
+ const key = this.channelKey(channel);
177
+ let entry = this.channelRegistry.get(key);
178
+ if (!entry) {
179
+ entry = { handlers: new Set(), cleanup: [] };
180
+ this.channelRegistry.set(key, entry);
181
+ const matches = (c) => c.agent_id === channel.agent_id && c.name === channel.name;
182
+ const onMsgCreate = (msg) => {
183
+ if (!matches(msg.channel))
184
+ return;
185
+ entry.handlers.forEach((h) => h.onMessage?.(msg));
186
+ };
187
+ const onMsgUpdate = (msg, requestData) => {
188
+ if (!matches(msg.channel))
189
+ return;
190
+ entry.handlers.forEach((h) => h.onMessageUpdate?.(msg, requestData));
191
+ };
192
+ const onAggregate = (event) => {
193
+ if (!matches(event.channel))
194
+ return;
195
+ entry.handlers.forEach((h) => h.onAggregate?.(event.aggregate));
196
+ };
197
+ const onChannelSync = (event) => {
198
+ if (!matches(event.channel))
199
+ return;
200
+ entry.handlers.forEach((h) => h.onAggregate?.(event.aggregate));
201
+ };
202
+ this.on("messageCreate", onMsgCreate);
203
+ this.on("messageUpdate", onMsgUpdate);
204
+ this.on("aggregateUpdate", onAggregate);
205
+ this.on("channelSync", onChannelSync);
206
+ entry.cleanup.push(() => this.off("messageCreate", onMsgCreate), () => this.off("messageUpdate", onMsgUpdate), () => this.off("aggregateUpdate", onAggregate), () => this.off("channelSync", onChannelSync));
207
+ this.subscribe(channel);
208
+ }
209
+ entry.handlers.add(handlers);
210
+ let detached = false;
211
+ return () => {
212
+ if (detached)
213
+ return;
214
+ detached = true;
215
+ entry.handlers.delete(handlers);
216
+ if (entry.handlers.size === 0) {
217
+ entry.cleanup.forEach((fn) => fn());
218
+ this.channelRegistry.delete(key);
219
+ this.unsubscribe(channel);
220
+ }
221
+ };
222
+ }
154
223
  syncChannel(channel) {
155
224
  if (!this.isConnected()) {
156
225
  void this.connect();
@@ -237,22 +306,22 @@ class GatewayClient {
237
306
  this.resubscribeAll();
238
307
  break;
239
308
  case "ChannelSync":
240
- this.emit("channelSync", message.d);
309
+ this.emit("channelSync", this.stamp(message.d, "channelSync"));
241
310
  break;
242
311
  case "MessageCreate":
243
- this.emit("messageCreate", (0, snowflake_1.addTimestampToMessage)(message.d));
312
+ this.emit("messageCreate", this.stamp((0, snowflake_1.addTimestampToMessage)(message.d), "messageCreate"));
244
313
  break;
245
314
  case "MessageUpdate":
246
- this.emit("messageUpdate", (0, snowflake_1.addTimestampToMessage)(message.d.message), message.d.request_data);
315
+ this.emit("messageUpdate", this.stamp((0, snowflake_1.addTimestampToMessage)(message.d.message), "messageUpdate"), message.d.request_data);
247
316
  break;
248
317
  case "AggregateUpdate":
249
- this.emit("aggregateUpdate", message.d);
318
+ this.emit("aggregateUpdate", this.stamp(message.d, "aggregateUpdate"));
250
319
  break;
251
320
  case "AlarmTrigger":
252
- this.emit("alarmTrigger", message.d);
321
+ this.emit("alarmTrigger", this.stamp(message.d, "alarmTrigger"));
253
322
  break;
254
323
  case "OneShotMessage":
255
- this.emit("oneShotMessage", message.d);
324
+ this.emit("oneShotMessage", this.stamp(message.d, "oneShotMessage"));
256
325
  break;
257
326
  case "ChannelSubscription":
258
327
  this.emit("channelSubscription", message.d);
@@ -20,6 +20,11 @@ export interface DooverClientConfig extends AuthConfig {
20
20
  * in browsers and automatically skipped in non-browser environments.
21
21
  */
22
22
  disableBrowserLifecycleHooks?: boolean;
23
+ /** Stable id for this client as a data source. Defaults to "cloud". Used in
24
+ * `__source` provenance and `DataClientStatus.clientId`. */
25
+ sourceId?: string;
26
+ /** Optional human label for this source (UI/debug). */
27
+ sourceLabel?: string;
23
28
  }
24
29
  export interface RequestOptions {
25
30
  baseUrl?: string;
package/dist/index.d.ts CHANGED
@@ -1,4 +1,8 @@
1
1
  export { DooverClient } from "./client/doover-client";
2
+ export { LocalAgentClient } from "./client/local-agent-client";
3
+ export type { LocalAgentClientConfig } from "./client/local-agent-client";
4
+ export { MultiplexClient } from "./client/multiplex-client";
5
+ export type { MultiplexClientOptions, SourceDescriptor, RegisteredSource, MultiplexConflict, } from "./client/multiplex-client";
2
6
  export { getDooverClient, peekDooverClient, resetDooverClient, } from "./client/singleton";
3
7
  export { DooverStatsCollector } from "./client/stats";
4
8
  export type { DooverStatsSnapshot, RestStatsSnapshot, GatewayStatsSnapshot, } from "./client/stats";
@@ -12,6 +16,17 @@ export { NotificationsApi } from "./apis/notifications-api";
12
16
  export { PermissionsApi } from "./apis/permissions-api";
13
17
  export { ProcessorsApi } from "./apis/processors-api";
14
18
  export { TurnApi } from "./apis/turn-api";
19
+ export { UsersApi } from "./apis/users-api";
20
+ export { RpcDispatcher } from "./rpc/rpc-dispatcher";
21
+ export type { SendRpcOptions } from "./rpc/rpc-dispatcher";
22
+ export { DooverRpcError } from "./rpc/errors";
23
+ export type { ChannelHandlers } from "./gateway/gateway-client";
24
+ export type { RpcStatsSnapshot } from "./client/stats";
25
+ export { ALL_CAPABILITIES } from "./client/capabilities";
26
+ export type { Capability } from "./client/capabilities";
27
+ export { UnsupportedCapabilityError, AmbiguousWriteError } from "./client/errors";
28
+ export type { DataClient, AgentScope, DataClientStatus, DataClientConnectionState, AgentsApiLike, AggregatesApiLike, AlarmsApiLike, ChannelsApiLike, ConnectionsApiLike, MessagesApiLike, NotificationsApiLike, PermissionsApiLike, ProcessorsApiLike, TurnApiLike, UsersApiLike, GatewayClientLike, RpcDispatcherLike, } from "./client/data-client";
29
+ export type { SourceProvenance, SourceProvenanceViaRest, SourceProvenanceViaGateway, } from "./types/provenance";
15
30
  export { DooverAuth } from "./auth/doover-auth";
16
31
  export { CookieAuth } from "./auth/cookie-auth";
17
32
  export { DooverTokenAuth } from "./auth/doover-token-auth";
package/dist/index.js CHANGED
@@ -1,8 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.generateSnowflakeIdAtTime = exports.extractSnowflakeId = exports.addTimestampToMessage = exports.getIdentifierFromPath = exports.DooverDataProvider = exports.DooverValidationError = exports.DooverGatewayError = exports.DooverApiError = exports.RestClient = exports.GatewayClient = exports.buildAuth = exports.DooverAuthError = exports.AuthProfile = exports.DooverTokenAuth = exports.CookieAuth = exports.DooverAuth = exports.TurnApi = exports.ProcessorsApi = exports.PermissionsApi = exports.NotificationsApi = exports.MessagesApi = exports.ConnectionsApi = exports.ChannelsApi = exports.AlarmsApi = exports.AggregatesApi = exports.AgentsApi = exports.DooverStatsCollector = exports.resetDooverClient = exports.peekDooverClient = exports.getDooverClient = exports.DooverClient = void 0;
3
+ exports.generateSnowflakeIdAtTime = exports.extractSnowflakeId = exports.addTimestampToMessage = exports.getIdentifierFromPath = exports.DooverDataProvider = exports.DooverValidationError = exports.DooverGatewayError = exports.DooverApiError = exports.RestClient = exports.GatewayClient = exports.buildAuth = exports.DooverAuthError = exports.AuthProfile = exports.DooverTokenAuth = exports.CookieAuth = exports.DooverAuth = exports.AmbiguousWriteError = exports.UnsupportedCapabilityError = exports.ALL_CAPABILITIES = exports.DooverRpcError = exports.RpcDispatcher = exports.UsersApi = exports.TurnApi = exports.ProcessorsApi = exports.PermissionsApi = exports.NotificationsApi = exports.MessagesApi = exports.ConnectionsApi = exports.ChannelsApi = exports.AlarmsApi = exports.AggregatesApi = exports.AgentsApi = exports.DooverStatsCollector = exports.resetDooverClient = exports.peekDooverClient = exports.getDooverClient = exports.MultiplexClient = exports.LocalAgentClient = exports.DooverClient = void 0;
4
4
  var doover_client_1 = require("./client/doover-client");
5
5
  Object.defineProperty(exports, "DooverClient", { enumerable: true, get: function () { return doover_client_1.DooverClient; } });
6
+ var local_agent_client_1 = require("./client/local-agent-client");
7
+ Object.defineProperty(exports, "LocalAgentClient", { enumerable: true, get: function () { return local_agent_client_1.LocalAgentClient; } });
8
+ var multiplex_client_1 = require("./client/multiplex-client");
9
+ Object.defineProperty(exports, "MultiplexClient", { enumerable: true, get: function () { return multiplex_client_1.MultiplexClient; } });
6
10
  var singleton_1 = require("./client/singleton");
7
11
  Object.defineProperty(exports, "getDooverClient", { enumerable: true, get: function () { return singleton_1.getDooverClient; } });
8
12
  Object.defineProperty(exports, "peekDooverClient", { enumerable: true, get: function () { return singleton_1.peekDooverClient; } });
@@ -29,6 +33,17 @@ var processors_api_1 = require("./apis/processors-api");
29
33
  Object.defineProperty(exports, "ProcessorsApi", { enumerable: true, get: function () { return processors_api_1.ProcessorsApi; } });
30
34
  var turn_api_1 = require("./apis/turn-api");
31
35
  Object.defineProperty(exports, "TurnApi", { enumerable: true, get: function () { return turn_api_1.TurnApi; } });
36
+ var users_api_1 = require("./apis/users-api");
37
+ Object.defineProperty(exports, "UsersApi", { enumerable: true, get: function () { return users_api_1.UsersApi; } });
38
+ var rpc_dispatcher_1 = require("./rpc/rpc-dispatcher");
39
+ Object.defineProperty(exports, "RpcDispatcher", { enumerable: true, get: function () { return rpc_dispatcher_1.RpcDispatcher; } });
40
+ var errors_1 = require("./rpc/errors");
41
+ Object.defineProperty(exports, "DooverRpcError", { enumerable: true, get: function () { return errors_1.DooverRpcError; } });
42
+ var capabilities_1 = require("./client/capabilities");
43
+ Object.defineProperty(exports, "ALL_CAPABILITIES", { enumerable: true, get: function () { return capabilities_1.ALL_CAPABILITIES; } });
44
+ var errors_2 = require("./client/errors");
45
+ Object.defineProperty(exports, "UnsupportedCapabilityError", { enumerable: true, get: function () { return errors_2.UnsupportedCapabilityError; } });
46
+ Object.defineProperty(exports, "AmbiguousWriteError", { enumerable: true, get: function () { return errors_2.AmbiguousWriteError; } });
32
47
  var doover_auth_1 = require("./auth/doover-auth");
33
48
  Object.defineProperty(exports, "DooverAuth", { enumerable: true, get: function () { return doover_auth_1.DooverAuth; } });
34
49
  var cookie_auth_1 = require("./auth/cookie-auth");
@@ -37,18 +52,18 @@ var doover_token_auth_1 = require("./auth/doover-token-auth");
37
52
  Object.defineProperty(exports, "DooverTokenAuth", { enumerable: true, get: function () { return doover_token_auth_1.DooverTokenAuth; } });
38
53
  var auth_profile_1 = require("./auth/auth-profile");
39
54
  Object.defineProperty(exports, "AuthProfile", { enumerable: true, get: function () { return auth_profile_1.AuthProfile; } });
40
- var errors_1 = require("./auth/errors");
41
- Object.defineProperty(exports, "DooverAuthError", { enumerable: true, get: function () { return errors_1.DooverAuthError; } });
55
+ var errors_3 = require("./auth/errors");
56
+ Object.defineProperty(exports, "DooverAuthError", { enumerable: true, get: function () { return errors_3.DooverAuthError; } });
42
57
  var build_auth_1 = require("./auth/build-auth");
43
58
  Object.defineProperty(exports, "buildAuth", { enumerable: true, get: function () { return build_auth_1.buildAuth; } });
44
59
  var gateway_client_1 = require("./gateway/gateway-client");
45
60
  Object.defineProperty(exports, "GatewayClient", { enumerable: true, get: function () { return gateway_client_1.GatewayClient; } });
46
61
  var rest_client_1 = require("./http/rest-client");
47
62
  Object.defineProperty(exports, "RestClient", { enumerable: true, get: function () { return rest_client_1.RestClient; } });
48
- var errors_2 = require("./http/errors");
49
- Object.defineProperty(exports, "DooverApiError", { enumerable: true, get: function () { return errors_2.DooverApiError; } });
50
- Object.defineProperty(exports, "DooverGatewayError", { enumerable: true, get: function () { return errors_2.DooverGatewayError; } });
51
- Object.defineProperty(exports, "DooverValidationError", { enumerable: true, get: function () { return errors_2.DooverValidationError; } });
63
+ var errors_4 = require("./http/errors");
64
+ Object.defineProperty(exports, "DooverApiError", { enumerable: true, get: function () { return errors_4.DooverApiError; } });
65
+ Object.defineProperty(exports, "DooverGatewayError", { enumerable: true, get: function () { return errors_4.DooverGatewayError; } });
66
+ Object.defineProperty(exports, "DooverValidationError", { enumerable: true, get: function () { return errors_4.DooverValidationError; } });
52
67
  var doover_data_provider_1 = require("./viewer/doover-data-provider");
53
68
  Object.defineProperty(exports, "DooverDataProvider", { enumerable: true, get: function () { return doover_data_provider_1.DooverDataProvider; } });
54
69
  var path_parsing_1 = require("./viewer/path-parsing");
@@ -1,19 +1,23 @@
1
1
  import { type ReactNode } from "react";
2
- import { DooverClient } from "../client/doover-client";
2
+ import type { DataClient } from "../client/data-client";
3
3
  export interface DooverProviderProps {
4
- client: DooverClient;
4
+ client: DataClient;
5
5
  children: ReactNode;
6
6
  }
7
7
  /**
8
- * Wraps a React subtree with a `DooverClient` instance so downstream hooks
8
+ * Wraps a React subtree with a `DataClient` instance so downstream hooks
9
9
  * (`useDooverClient`, `useChannelAggregate`, etc.) can read it from context.
10
10
  *
11
11
  * Pair with a `@tanstack/react-query` `<QueryClientProvider>` in the same tree —
12
12
  * the hooks call `useQueryClient()` internally and will throw without one.
13
+ *
14
+ * Accepts any `DataClient` implementation — `DooverClient` (single cloud source),
15
+ * `LocalAgentClient` (single local device), or `MultiplexClient` (fan-out across
16
+ * multiple sources).
13
17
  */
14
18
  export declare function DooverProvider({ client, children }: DooverProviderProps): import("react/jsx-runtime").JSX.Element;
15
19
  /**
16
- * Read the `DooverClient` from context. Throws if called outside a
20
+ * Read the `DataClient` from context. Throws if called outside a
17
21
  * `<DooverProvider>`.
18
22
  */
19
- export declare function useDooverClient(): DooverClient;
23
+ export declare function useDooverClient(): DataClient;
@@ -6,17 +6,21 @@ const jsx_runtime_1 = require("react/jsx-runtime");
6
6
  const react_1 = require("react");
7
7
  const DooverClientContext = (0, react_1.createContext)(null);
8
8
  /**
9
- * Wraps a React subtree with a `DooverClient` instance so downstream hooks
9
+ * Wraps a React subtree with a `DataClient` instance so downstream hooks
10
10
  * (`useDooverClient`, `useChannelAggregate`, etc.) can read it from context.
11
11
  *
12
12
  * Pair with a `@tanstack/react-query` `<QueryClientProvider>` in the same tree —
13
13
  * the hooks call `useQueryClient()` internally and will throw without one.
14
+ *
15
+ * Accepts any `DataClient` implementation — `DooverClient` (single cloud source),
16
+ * `LocalAgentClient` (single local device), or `MultiplexClient` (fan-out across
17
+ * multiple sources).
14
18
  */
15
19
  function DooverProvider({ client, children }) {
16
20
  return ((0, jsx_runtime_1.jsx)(DooverClientContext.Provider, { value: client, children: children }));
17
21
  }
18
22
  /**
19
- * Read the `DooverClient` from context. Throws if called outside a
23
+ * Read the `DataClient` from context. Throws if called outside a
20
24
  * `<DooverProvider>`.
21
25
  */
22
26
  function useDooverClient() {
@@ -1,5 +1,7 @@
1
1
  export { DooverProvider, useDooverClient } from "./context";
2
2
  export type { DooverProviderProps } from "./context";
3
+ export type { DataClientStatus, DataClientConnectionState, AgentScope } from "../client/data-client";
4
+ export { useClientStatus } from "./useClientStatus";
3
5
  export { useConnectionState } from "./useConnectionState";
4
6
  export type { ConnectionState, ConnectionStatus } from "./useConnectionState";
5
7
  export { useAgentConnections, agentConnectionsQueryKey, } from "./useAgentConnections";
@@ -9,6 +11,7 @@ export { useChannelAggregate, channelAggregateQueryKey, } from "./useChannelAggr
9
11
  export type { UseChannelAggregateOptions, UseChannelAggregateResult, } from "./useChannelAggregate";
10
12
  export { useAgentChannel } from "./useAgentChannel";
11
13
  export { useSendMessage } from "./useSendMessage";
14
+ export type { UseSendMessageOptions } from "./useSendMessage";
12
15
  export { useUpdateAggregate } from "./useUpdateAggregate";
13
16
  export type { UseUpdateAggregateOptions } from "./useUpdateAggregate";
14
17
  export { useUpdateMessage } from "./useUpdateMessage";
@@ -1,9 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.resetSharedQueryClient = exports.getSharedQueryClient = exports.useTurnCredentials = exports.useDeviceMap = exports.multiAgentChannelMessagesQueryKey = exports.useMultiAgentChannelMessages = exports.multiAgentAggregatesQueryKey = exports.useMultiAgentAggregates = exports.useSendRpc = exports.invocationLogsQueryKey = exports.useInvocationLogs = exports.channelMessageQueryKey = exports.useChannelMessage = exports.channelMessagesQueryKey = exports.useChannelMessages = exports.useUpdateMessage = exports.useUpdateAggregate = exports.useSendMessage = exports.useAgentChannel = exports.channelAggregateQueryKey = exports.useChannelAggregate = exports.useChannelSubscription = exports.agentConnectionsQueryKey = exports.useAgentConnections = exports.useConnectionState = exports.useDooverClient = exports.DooverProvider = void 0;
3
+ exports.resetSharedQueryClient = exports.getSharedQueryClient = exports.useTurnCredentials = exports.useDeviceMap = exports.multiAgentChannelMessagesQueryKey = exports.useMultiAgentChannelMessages = exports.multiAgentAggregatesQueryKey = exports.useMultiAgentAggregates = exports.useSendRpc = exports.invocationLogsQueryKey = exports.useInvocationLogs = exports.channelMessageQueryKey = exports.useChannelMessage = exports.channelMessagesQueryKey = exports.useChannelMessages = exports.useUpdateMessage = exports.useUpdateAggregate = exports.useSendMessage = exports.useAgentChannel = exports.channelAggregateQueryKey = exports.useChannelAggregate = exports.useChannelSubscription = exports.agentConnectionsQueryKey = exports.useAgentConnections = exports.useConnectionState = exports.useClientStatus = exports.useDooverClient = exports.DooverProvider = void 0;
4
4
  var context_1 = require("./context");
5
5
  Object.defineProperty(exports, "DooverProvider", { enumerable: true, get: function () { return context_1.DooverProvider; } });
6
6
  Object.defineProperty(exports, "useDooverClient", { enumerable: true, get: function () { return context_1.useDooverClient; } });
7
+ var useClientStatus_1 = require("./useClientStatus");
8
+ Object.defineProperty(exports, "useClientStatus", { enumerable: true, get: function () { return useClientStatus_1.useClientStatus; } });
7
9
  var useConnectionState_1 = require("./useConnectionState");
8
10
  Object.defineProperty(exports, "useConnectionState", { enumerable: true, get: function () { return useConnectionState_1.useConnectionState; } });
9
11
  var useAgentConnections_1 = require("./useAgentConnections");
@@ -1,7 +1,7 @@
1
1
  import { type UseQueryResult } from "@tanstack/react-query";
2
2
  import type { Aggregate } from "../types/common";
3
3
  import type { ChannelIdentifier } from "../types/viewer";
4
- export declare function channelAggregateQueryKey(agentId: string | undefined, channelName: string | undefined): readonly ["doover", "agent", string | undefined, "channel", string | undefined];
4
+ export declare function channelAggregateQueryKey(agentId: string | undefined, channelName: string | undefined, sources?: string[]): readonly ["doover", "agent", string | undefined, "channel", string | undefined, "src", string];
5
5
  /**
6
6
  * Shape returned by `useChannelAggregate`. Shadows the react-query
7
7
  * `data` field with the unwrapped aggregate payload (`TData`) so the
@@ -39,6 +39,13 @@ export interface UseChannelAggregateOptions {
39
39
  * `AggregateUpdate` events.
40
40
  */
41
41
  fetchInitial?: boolean;
42
+ /**
43
+ * Restrict to these source ids on a `MultiplexClient`. Ignored for a plain
44
+ * `DooverClient` or `LocalAgentClient`. When set, the query key is
45
+ * source-dimensioned so data from different source subsets is cached
46
+ * independently.
47
+ */
48
+ sources?: string[];
42
49
  }
43
50
  /**
44
51
  * Fetch a channel's aggregate and keep it live via the gateway. Incoming
@@ -7,8 +7,9 @@ const react_query_1 = require("@tanstack/react-query");
7
7
  const errors_1 = require("../http/errors");
8
8
  const context_1 = require("./context");
9
9
  const useChannelSubscription_1 = require("./useChannelSubscription");
10
- function channelAggregateQueryKey(agentId, channelName) {
11
- return ["doover", "agent", agentId, "channel", channelName];
10
+ function channelAggregateQueryKey(agentId, channelName, sources) {
11
+ const sourceDim = sources && sources.length ? [...sources].sort().join(",") : "*";
12
+ return ["doover", "agent", agentId, "channel", channelName, "src", sourceDim];
12
13
  }
13
14
  /**
14
15
  * Fetch a channel's aggregate and keep it live via the gateway. Incoming
@@ -25,20 +26,37 @@ function useChannelAggregate(identifier, options) {
25
26
  const client = (0, context_1.useDooverClient)();
26
27
  const queryClient = (0, react_query_1.useQueryClient)();
27
28
  const { agentId, channelName } = identifier;
28
- const key = channelAggregateQueryKey(agentId, channelName);
29
+ const sources = options?.sources;
30
+ const key = channelAggregateQueryKey(agentId, channelName, sources);
29
31
  const fetchInitial = options?.fetchInitial ?? true;
30
32
  const onAggregate = (0, react_1.useCallback)((aggregate) => {
31
33
  queryClient.setQueryData(key, aggregate);
32
34
  },
33
- // The key array is structurally stable per (agentId, channelName).
35
+ // The key array is structurally stable per (agentId, channelName, sourceDim).
34
36
  // eslint-disable-next-line react-hooks/exhaustive-deps
35
- [queryClient, agentId, channelName]);
37
+ [queryClient, agentId, channelName, sources?.join(",")]);
36
38
  (0, useChannelSubscription_1.useChannelSubscription)(identifier, { onAggregate });
37
39
  const query = (0, react_query_1.useQuery)({
38
40
  queryKey: key,
39
41
  enabled: fetchInitial && !!agentId && !!channelName,
40
42
  staleTime: Infinity,
41
- queryFn: () => client.viewer.getAggregate(identifier),
43
+ queryFn: async () => {
44
+ if (!agentId || !channelName)
45
+ return undefined;
46
+ const id = { agentId, channelName };
47
+ // Pass `{ sources }` as a trailing bag only when set. The TypeScript
48
+ // overloads don't declare it, so we cast through `never` — the runtime
49
+ // implementation reads it via `...args: unknown[]`.
50
+ const sourcesArg = sources ? { sources } : undefined;
51
+ const channel = sourcesArg
52
+ ? await client.channels.getChannel(id, sourcesArg)
53
+ : await client.channels.getChannel(id);
54
+ if (channel.aggregate)
55
+ return channel.aggregate;
56
+ return (sourcesArg
57
+ ? await client.aggregates.getAggregate(id, sourcesArg)
58
+ : await client.aggregates.getAggregate(id));
59
+ },
42
60
  // A 404 means the aggregate doesn't exist — retrying won't change that,
43
61
  // and the caller needs the error promptly to render an empty/"not
44
62
  // installed" state. Fall back to the react-query default (3 retries) for
@@ -1,10 +1,17 @@
1
1
  import { type UseQueryResult } from "@tanstack/react-query";
2
2
  import type { JSONValue, MessageAttachment, MessageStructure } from "../types/common";
3
3
  import type { ChannelIdentifier } from "../types/viewer";
4
- export declare function channelMessageQueryKey(agentId: string | undefined, channelName: string | undefined, messageId: string | undefined): readonly ["doover", "agent", string | undefined, "channel", string | undefined, "message", string | undefined];
4
+ export declare function channelMessageQueryKey(agentId: string | undefined, channelName: string | undefined, messageId: string | undefined, sources?: string[]): readonly ["doover", "agent", string | undefined, "channel", string | undefined, "message", string | undefined, "src", string];
5
5
  export interface UseChannelMessageOptions {
6
6
  /** If false, skip subscribing for live message-update events. Defaults true. */
7
7
  liveUpdates?: boolean;
8
+ /**
9
+ * Restrict to these source ids on a `MultiplexClient`. Ignored for a plain
10
+ * `DooverClient` or `LocalAgentClient`. When set, the query key is
11
+ * source-dimensioned so data from different source subsets is cached
12
+ * independently.
13
+ */
14
+ sources?: string[];
8
15
  }
9
16
  /**
10
17
  * Shape returned by `useChannelMessage`. Mirrors `UseChannelAggregateResult`:
@@ -6,7 +6,8 @@ const react_1 = require("react");
6
6
  const react_query_1 = require("@tanstack/react-query");
7
7
  const context_1 = require("./context");
8
8
  const useChannelSubscription_1 = require("./useChannelSubscription");
9
- function channelMessageQueryKey(agentId, channelName, messageId) {
9
+ function channelMessageQueryKey(agentId, channelName, messageId, sources) {
10
+ const sourceDim = sources && sources.length ? [...sources].sort().join(",") : "*";
10
11
  return [
11
12
  "doover",
12
13
  "agent",
@@ -15,6 +16,8 @@ function channelMessageQueryKey(agentId, channelName, messageId) {
15
16
  channelName,
16
17
  "message",
17
18
  messageId,
19
+ "src",
20
+ sourceDim,
18
21
  ];
19
22
  }
20
23
  /**
@@ -35,15 +38,16 @@ function useChannelMessage(identifier, messageId, options) {
35
38
  const queryClient = (0, react_query_1.useQueryClient)();
36
39
  const { agentId, channelName } = identifier;
37
40
  const liveUpdates = options?.liveUpdates ?? true;
38
- const key = channelMessageQueryKey(agentId, channelName, messageId);
41
+ const sources = options?.sources;
42
+ const key = channelMessageQueryKey(agentId, channelName, messageId, sources);
39
43
  const onMessageUpdate = (0, react_1.useCallback)((message) => {
40
44
  if (message.id !== messageId)
41
45
  return;
42
46
  queryClient.setQueryData(key, message);
43
47
  },
44
- // The key array is structurally stable per (agentId, channelName, messageId).
48
+ // The key array is structurally stable per (agentId, channelName, messageId, sourceDim).
45
49
  // eslint-disable-next-line react-hooks/exhaustive-deps
46
- [queryClient, agentId, channelName, messageId]);
50
+ [queryClient, agentId, channelName, messageId, sources?.join(",")]);
47
51
  // Cover the case where the caller has the id before the create event has
48
52
  // landed on this client — patch the cache when it shows up.
49
53
  const onMessage = (0, react_1.useCallback)((message) => {
@@ -52,13 +56,20 @@ function useChannelMessage(identifier, messageId, options) {
52
56
  queryClient.setQueryData(key, message);
53
57
  },
54
58
  // eslint-disable-next-line react-hooks/exhaustive-deps
55
- [queryClient, agentId, channelName, messageId]);
59
+ [queryClient, agentId, channelName, messageId, sources?.join(",")]);
56
60
  (0, useChannelSubscription_1.useChannelSubscription)(liveUpdates && messageId ? identifier : undefined, { onMessage, onMessageUpdate });
57
61
  const query = (0, react_query_1.useQuery)({
58
62
  queryKey: key,
59
63
  enabled: !!agentId && !!channelName && !!messageId,
60
64
  staleTime: Infinity,
61
- queryFn: () => client.messages.getMessage(agentId, channelName, messageId),
65
+ queryFn: () => {
66
+ // Pass `{ sources }` as a trailing bag only when set — cast through
67
+ // `never` since the TypeScript overloads don't declare it.
68
+ const sourcesArg = sources ? { sources } : undefined;
69
+ return (sourcesArg
70
+ ? client.messages.getMessage(agentId, channelName, messageId, sourcesArg)
71
+ : client.messages.getMessage(agentId, channelName, messageId));
72
+ },
62
73
  });
63
74
  const message = query.data;
64
75
  const { data: _ignored, ...rest } = query;
@@ -1,7 +1,7 @@
1
1
  import { type InfiniteData, type UseInfiniteQueryResult } from "@tanstack/react-query";
2
2
  import type { MessageStructure } from "../types/common";
3
3
  import type { ChannelIdentifier } from "../types/viewer";
4
- export declare function channelMessagesQueryKey(agentId: string | undefined, channelName: string | undefined, fields?: readonly string[]): readonly ["doover", "agent", string | undefined, "channel", string | undefined, "messages"] | readonly ["doover", "agent", string | undefined, "channel", string | undefined, "messages", {
4
+ export declare function channelMessagesQueryKey(agentId: string | undefined, channelName: string | undefined, fields?: readonly string[], sources?: string[]): readonly ["doover", "agent", string | undefined, "channel", string | undefined, "messages", "src", string] | readonly ["doover", "agent", string | undefined, "channel", string | undefined, "messages", "src", string, {
5
5
  readonly fields: string[];
6
6
  }];
7
7
  export interface UseChannelMessagesOptions {
@@ -35,6 +35,13 @@ export interface UseChannelMessagesOptions {
35
35
  * bound this will walk the channel back to its first message.
36
36
  */
37
37
  autoPaginate?: boolean;
38
+ /**
39
+ * Restrict to these source ids on a `MultiplexClient`. Ignored for a plain
40
+ * `DooverClient` or `LocalAgentClient`. When set, the query key is
41
+ * source-dimensioned so data from different source subsets is cached
42
+ * independently.
43
+ */
44
+ sources?: string[];
38
45
  }
39
46
  type Page<TData> = MessageStructure<TData>[];
40
47
  export interface UseChannelMessagesResult<TData> extends Omit<UseInfiniteQueryResult<InfiniteData<Page<TData>>>, "data"> {
@@ -6,8 +6,11 @@ const react_1 = require("react");
6
6
  const react_query_1 = require("@tanstack/react-query");
7
7
  const context_1 = require("./context");
8
8
  const useChannelSubscription_1 = require("./useChannelSubscription");
9
- function channelMessagesQueryKey(agentId, channelName, fields) {
10
- const key = ["doover", "agent", agentId, "channel", channelName, "messages"];
9
+ function channelMessagesQueryKey(agentId, channelName, fields, sources) {
10
+ // Source-dimension the key (multiplex source subsets cache independently);
11
+ // "*" means "all/unspecified" for a plain DooverClient/LocalAgentClient.
12
+ const sourceDim = sources && sources.length ? [...sources].sort().join(",") : "*";
13
+ const key = ["doover", "agent", agentId, "channel", channelName, "messages", "src", sourceDim];
11
14
  if (!fields || fields.length === 0)
12
15
  return key;
13
16
  // A `field_name`-filtered request returns a different message stream than
@@ -33,7 +36,8 @@ function useChannelMessages(identifier, options) {
33
36
  const initialBefore = options?.initialBefore;
34
37
  const after = options?.after;
35
38
  const autoPaginate = options?.autoPaginate ?? false;
36
- const key = channelMessagesQueryKey(agentId, channelName, fields);
39
+ const sources = options?.sources;
40
+ const key = channelMessagesQueryKey(agentId, channelName, fields, sources);
37
41
  const onMessage = (0, react_1.useCallback)((message) => {
38
42
  // This cache entry is scoped to `fields`; the gateway delivers every
39
43
  // message on the channel, so drop live pushes whose payload doesn't
@@ -59,7 +63,7 @@ function useChannelMessages(identifier, options) {
59
63
  });
60
64
  },
61
65
  // eslint-disable-next-line react-hooks/exhaustive-deps
62
- [queryClient, agentId, channelName, fields?.join(",")]);
66
+ [queryClient, agentId, channelName, fields?.join(","), sources?.join(",")]);
63
67
  (0, useChannelSubscription_1.useChannelSubscription)(liveUpdates ? identifier : undefined, { onMessage });
64
68
  const query = (0, react_query_1.useInfiniteQuery)({
65
69
  queryKey: key,
@@ -68,13 +72,23 @@ function useChannelMessages(identifier, options) {
68
72
  initialPageParam: initialBefore,
69
73
  getNextPageParam: (lastPage) => lastPage && lastPage.length > 0 ? lastPage[0]?.id : undefined,
70
74
  queryFn: async ({ pageParam }) => {
71
- const page = await client.viewer.getMessages(identifier, {
75
+ if (!agentId || !channelName)
76
+ return [];
77
+ const id = { agentId, channelName };
78
+ const params = {
72
79
  ...(typeof pageParam === "string" ? { before: pageParam } : {}),
73
80
  ...(limit !== undefined ? { limit } : {}),
74
81
  ...(fields && fields.length > 0 ? { field_name: fields } : {}),
75
82
  ...(after !== undefined ? { after } : {}),
76
- });
77
- return (page ?? []);
83
+ order: "asc",
84
+ };
85
+ // Pass `{ sources }` as a trailing bag only when set — cast through
86
+ // `never` since the TypeScript overloads don't declare it.
87
+ const sourcesArg = sources ? { sources } : undefined;
88
+ const page = sourcesArg
89
+ ? await client.messages.listMessages(id, params, sourcesArg)
90
+ : await client.messages.listMessages(id, params);
91
+ return page;
78
92
  },
79
93
  });
80
94
  (0, react_1.useEffect)(() => {
@@ -9,6 +9,12 @@ export interface ChannelSubscriptionHandlers {
9
9
  */
10
10
  onMessageUpdate?: (message: MessageStructure, request_data?: JSONValue) => void;
11
11
  onAggregate?: (aggregate: Aggregate) => void;
12
+ /**
13
+ * Reserved for future use. The composite gateway already routes by
14
+ * `channel.agent_id`, so this option is a no-op in v1. Pass it for
15
+ * forward-compatibility; it has no effect on the subscription.
16
+ */
17
+ sources?: string[];
12
18
  }
13
19
  /**
14
20
  * Attach live-update handlers to a channel for the lifetime of the host