@appstrata/protocol 0.1.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 (56) hide show
  1. package/README.md +106 -0
  2. package/dist/client/index.d.ts +6 -0
  3. package/dist/client/index.d.ts.map +1 -0
  4. package/dist/client/index.js +5 -0
  5. package/dist/client/proxy.d.ts +72 -0
  6. package/dist/client/proxy.d.ts.map +1 -0
  7. package/dist/client/proxy.js +446 -0
  8. package/dist/client/rpc.d.ts +62 -0
  9. package/dist/client/rpc.d.ts.map +1 -0
  10. package/dist/client/rpc.js +138 -0
  11. package/dist/host/index.d.ts +5 -0
  12. package/dist/host/index.d.ts.map +1 -0
  13. package/dist/host/index.js +4 -0
  14. package/dist/host/message-bridge.d.ts +146 -0
  15. package/dist/host/message-bridge.d.ts.map +1 -0
  16. package/dist/host/message-bridge.js +360 -0
  17. package/dist/index.d.ts +14 -0
  18. package/dist/index.d.ts.map +1 -0
  19. package/dist/index.js +17 -0
  20. package/dist/messages.d.ts +197 -0
  21. package/dist/messages.d.ts.map +1 -0
  22. package/dist/messages.js +141 -0
  23. package/dist/transport/http/client-polling.d.ts +32 -0
  24. package/dist/transport/http/client-polling.d.ts.map +1 -0
  25. package/dist/transport/http/client-polling.js +181 -0
  26. package/dist/transport/http/client-sse.d.ts +30 -0
  27. package/dist/transport/http/client-sse.d.ts.map +1 -0
  28. package/dist/transport/http/client-sse.js +155 -0
  29. package/dist/transport/http/host-manager.d.ts +63 -0
  30. package/dist/transport/http/host-manager.d.ts.map +1 -0
  31. package/dist/transport/http/host-manager.js +74 -0
  32. package/dist/transport/http/host-polling.d.ts +65 -0
  33. package/dist/transport/http/host-polling.d.ts.map +1 -0
  34. package/dist/transport/http/host-polling.js +143 -0
  35. package/dist/transport/http/host-sse.d.ts +56 -0
  36. package/dist/transport/http/host-sse.d.ts.map +1 -0
  37. package/dist/transport/http/host-sse.js +149 -0
  38. package/dist/transport/http/index.d.ts +13 -0
  39. package/dist/transport/http/index.d.ts.map +1 -0
  40. package/dist/transport/http/index.js +12 -0
  41. package/dist/transport/http/types.d.ts +73 -0
  42. package/dist/transport/http/types.d.ts.map +1 -0
  43. package/dist/transport/http/types.js +8 -0
  44. package/dist/transport/index.d.ts +33 -0
  45. package/dist/transport/index.d.ts.map +1 -0
  46. package/dist/transport/index.js +37 -0
  47. package/dist/transport/postMessage.d.ts +70 -0
  48. package/dist/transport/postMessage.d.ts.map +1 -0
  49. package/dist/transport/postMessage.js +94 -0
  50. package/dist/transport/relay.d.ts +118 -0
  51. package/dist/transport/relay.d.ts.map +1 -0
  52. package/dist/transport/relay.js +216 -0
  53. package/dist/transport/types.d.ts +30 -0
  54. package/dist/transport/types.d.ts.map +1 -0
  55. package/dist/transport/types.js +6 -0
  56. package/package.json +60 -0
@@ -0,0 +1,360 @@
1
+ /**
2
+ * MessageBridge - Host-side message protocol bridge.
3
+ *
4
+ * Bridges communication between the player and app via the message protocol.
5
+ * Handles the HELLO/READY/READY_ACK handshake and subsequent RPC/event communication.
6
+ *
7
+ * Key responsibilities:
8
+ * - Listen for HELLO messages from apps
9
+ * - Send READY messages with AppContext
10
+ * - Retry READY until READY_ACK received (if HELLO not received)
11
+ * - Handle REQUEST messages and send RESPONSE
12
+ * - Fire lifecycle EVENT messages
13
+ */
14
+ import { createLogger, setHandlingLogRpc } from "@appstrata/core";
15
+ const logger = createLogger("MessageBridge");
16
+ import { isHelloMessage, isReadyAckMessage, isRequestMessage, appContextToWire, generateRequestId, } from "../messages.js";
17
+ /**
18
+ * MessageBridge - Host-side protocol bridge.
19
+ *
20
+ * **Single-session:** one `MessageBridge` instance covers one App page load.
21
+ * Once the handshake completes (`receivedReadyAck = true`), the bridge enters
22
+ * the ACTIVE state and does not reset. When the App reloads, the old bridge
23
+ * must be destroyed and a new one created.
24
+ *
25
+ * Bridges the player to apps via the message protocol.
26
+ *
27
+ * Usage:
28
+ * ```typescript
29
+ * const bridge = new MessageBridge({
30
+ * transport: createPostMessageTransport({ targetWindow: iframe.contentWindow!, targetOrigin: "*" }),
31
+ * player: myPlayer,
32
+ * getContext: async () => buildAppContext(),
33
+ * });
34
+ *
35
+ * // Start the handshake (sends READY)
36
+ * bridge.start();
37
+ *
38
+ * // Send lifecycle events
39
+ * bridge.fireShow();
40
+ * bridge.fireStart();
41
+ * ```
42
+ */
43
+ export class MessageBridge {
44
+ constructor(config) {
45
+ this.receivedHello = false;
46
+ this.receivedReadyAck = false;
47
+ this.retryCount = 0;
48
+ this.started = false;
49
+ this.pendingEvents = [];
50
+ this.config = {
51
+ retryInterval: 1000,
52
+ maxRetries: 10,
53
+ ...config,
54
+ };
55
+ this.transport = config.transport;
56
+ // Install message listener
57
+ this.unsubscribeFromTransport = this.transport.onMessage((msg) => {
58
+ if (isHelloMessage(msg)) {
59
+ this.handleHello(msg);
60
+ }
61
+ else if (isReadyAckMessage(msg)) {
62
+ this.handleReadyAck(msg);
63
+ }
64
+ else if (isRequestMessage(msg)) {
65
+ this.handleRequest(msg);
66
+ }
67
+ });
68
+ }
69
+ /**
70
+ * Start the bridge (send initial READY message).
71
+ */
72
+ start() {
73
+ if (this.started) {
74
+ return;
75
+ }
76
+ this.started = true;
77
+ // avoid sending proactive READY if we've already received HELLO
78
+ // because we will already have sent READY in response to HELLO
79
+ if (!this.receivedHello) {
80
+ this.sendReady('proactive', true);
81
+ }
82
+ }
83
+ /**
84
+ * Handle HELLO message from app.
85
+ */
86
+ handleHello(message) {
87
+ logger.debug(`↓ HELLO received (requestId=${message.requestId}, timestamp=${message.timestamp})`);
88
+ this.receivedHello = true;
89
+ this.helloRequestId = message.requestId;
90
+ // Stop retrying if we were
91
+ this.cancelNextRetry();
92
+ // If the proactive READY was already acknowledged, the handshake is done.
93
+ // A late HELLO (arrived after READY_ACK) may trigger a second READY.
94
+ // TBD: whether the spec should allow this or not.
95
+ // if (this.receivedReadyAck) {
96
+ // logger.debug("Ignoring late HELLO — handshake already completed via proactive READY");
97
+ // return;
98
+ // }
99
+ // Send READY in response (will include requestId from HELLO)
100
+ this.sendReady('response to HELLO');
101
+ }
102
+ /**
103
+ * Handle READY_ACK message from app.
104
+ */
105
+ handleReadyAck(message) {
106
+ logger.debug(`↓ READY_ACK received (requestId=${message.requestId}, timestamp=${message.timestamp})`);
107
+ this.receivedReadyAck = true;
108
+ // Stop retrying
109
+ this.cancelNextRetry();
110
+ // Flush any events that were queued before handshake completed
111
+ this.flushPendingEvents();
112
+ }
113
+ /**
114
+ * Flush pending events that were queued before READY_ACK.
115
+ */
116
+ flushPendingEvents() {
117
+ for (const event of this.pendingEvents) {
118
+ this.transport.send(event);
119
+ logger.debug(`Flushed queued event: ${event.name}`);
120
+ }
121
+ this.pendingEvents = [];
122
+ }
123
+ /**
124
+ * Handle REQUEST message from app.
125
+ */
126
+ async handleRequest(message) {
127
+ // Spec §2.2: Hosts SHOULD ignore REQUESTs from an App that has not completed the handshake
128
+ if (!this.receivedReadyAck) {
129
+ logger.debug("Ignoring REQUEST before READY_ACK:", message.op);
130
+ return;
131
+ }
132
+ // Notification = no requestId => no RESPONSE (spec §4.4)
133
+ const isNotification = !message.requestId;
134
+ const isLogOp = message.op === "log";
135
+ if (isLogOp)
136
+ setHandlingLogRpc(true);
137
+ try {
138
+ logger.debug(`↓ REQUEST received: ${message.op} (requestId=${message.requestId ?? "(notification)"}, timestamp=${message.timestamp})`);
139
+ const result = await this.handlePlayerRequest(message.op, message.payload);
140
+ if (isNotification)
141
+ return;
142
+ const response = {
143
+ protocol: "appstrata-protocol",
144
+ version: "1.0",
145
+ type: "RESPONSE",
146
+ timestamp: Date.now(),
147
+ requestId: message.requestId,
148
+ op: message.op,
149
+ ok: true,
150
+ result,
151
+ };
152
+ this.transport.send(response);
153
+ }
154
+ catch (error) {
155
+ if (isNotification)
156
+ return;
157
+ const response = {
158
+ protocol: "appstrata-protocol",
159
+ version: "1.0",
160
+ type: "RESPONSE",
161
+ timestamp: Date.now(),
162
+ requestId: message.requestId,
163
+ op: message.op,
164
+ ok: false,
165
+ error: {
166
+ code: "INTERNAL_ERROR",
167
+ message: error instanceof Error ? error.message : String(error),
168
+ details: error,
169
+ },
170
+ };
171
+ this.transport.send(response);
172
+ }
173
+ finally {
174
+ if (isLogOp)
175
+ setHandlingLogRpc(false);
176
+ }
177
+ }
178
+ /**
179
+ * Handle request by routing to player API.
180
+ */
181
+ async handlePlayerRequest(op, payload) {
182
+ const player = this.config.player;
183
+ const handlers = {
184
+ // Core operations
185
+ "notifyComplete": () => player.notifyComplete(),
186
+ "notifyEstimatedEnd": () => player.notifyEstimatedEnd(payload),
187
+ "notifyNoContent": () => player.notifyNoContent(payload),
188
+ // Storage operations
189
+ "storage.get": async () => {
190
+ this.requireCapability(player.storage, "Storage");
191
+ return { value: await player.storage.get(payload.key) };
192
+ },
193
+ "storage.set": async () => {
194
+ this.requireCapability(player.storage, "Storage");
195
+ await player.storage.set(payload.key, payload.value);
196
+ },
197
+ "storage.remove": async () => {
198
+ this.requireCapability(player.storage, "Storage");
199
+ await player.storage.remove(payload.key);
200
+ },
201
+ "storage.list": async () => {
202
+ this.requireCapability(player.storage, "Storage");
203
+ return { keys: await player.storage.list() };
204
+ },
205
+ "storage.clear": async () => {
206
+ this.requireCapability(player.storage, "Storage");
207
+ await player.storage.clear();
208
+ },
209
+ // Proxy operations
210
+ "proxy.fetch": async () => {
211
+ this.requireCapability(player.proxy, "Proxy");
212
+ const response = await player.proxy.fetch(payload);
213
+ // Convert ProxyResponse to ProxyResponseWire for serialization
214
+ const wireResponse = {
215
+ ok: response.ok,
216
+ status: response.status,
217
+ statusText: response.statusText,
218
+ headers: response.headers,
219
+ body: await response.text(),
220
+ cached: response.cached,
221
+ stale: response.stale,
222
+ cachedAt: response.cachedAt,
223
+ };
224
+ return wireResponse;
225
+ },
226
+ // Fire-and-forget: don't await so the _handlingLogRpc flag
227
+ // (cycle guard) is cleared before any async work in player.log().
228
+ "log": () => {
229
+ if (player.log) {
230
+ void player.log(payload.level, payload.message, payload.data);
231
+ }
232
+ },
233
+ };
234
+ const handler = handlers[op];
235
+ if (!handler) {
236
+ throw new Error(`Unknown operation: ${op}`);
237
+ }
238
+ return await handler();
239
+ }
240
+ /**
241
+ * Helper to check capability availability.
242
+ */
243
+ requireCapability(capability, name) {
244
+ if (!capability) {
245
+ throw new Error(`${name} capability not available`);
246
+ }
247
+ }
248
+ /**
249
+ * Send latest AppContext as READY message to app.
250
+ *
251
+ * Awaits the AppContext to be available.
252
+ * If proactive is true, and HELLO arrives by the time the context is available,
253
+ * no READY is sent.
254
+ *
255
+ * @param reason - The phase at which the READY message is being sent. Only used for logging.
256
+ */
257
+ async sendReady(reason, proactive = false) {
258
+ const context = await this.config.getContext();
259
+ const contextWire = appContextToWire(context);
260
+ if (proactive && this.receivedHello) {
261
+ // HELLO arrived while we were waiting for the context
262
+ return;
263
+ }
264
+ const ready = {
265
+ protocol: "appstrata-protocol",
266
+ version: "1.0",
267
+ type: "READY",
268
+ timestamp: Date.now(),
269
+ context: contextWire,
270
+ requestId: this.helloRequestId ?? generateRequestId(),
271
+ };
272
+ logger.debug(`↑ Sending READY (${reason}) (requestId=${ready.requestId}, timestamp=${ready.timestamp})`);
273
+ this.transport.send(ready);
274
+ if (!this.receivedHello && !this.receivedReadyAck) {
275
+ this.scheduleNextRetry();
276
+ }
277
+ }
278
+ /**
279
+ * Schedule next retry for READY messages.
280
+ */
281
+ scheduleNextRetry() {
282
+ // Just an defensive check to avoid setting up overlapping retries and going over the max retries
283
+ if (this.retryTimer || this.retryCount >= this.config.maxRetries) {
284
+ return;
285
+ }
286
+ this.retryTimer = setTimeout(() => {
287
+ // Clear timer before calling sendReady() so that it can schedule the next retry
288
+ this.retryTimer = undefined;
289
+ this.retryCount++;
290
+ logger.debug(`Retrying READY (${this.retryCount}/${this.config.maxRetries})`);
291
+ if (this.retryCount < this.config.maxRetries) {
292
+ this.sendReady('retry');
293
+ }
294
+ else {
295
+ logger.debug("Max retries reached, giving up");
296
+ }
297
+ }, this.config.retryInterval);
298
+ }
299
+ /**
300
+ * Cancel the next retry for READY messages.
301
+ */
302
+ cancelNextRetry() {
303
+ if (this.retryTimer) {
304
+ clearTimeout(this.retryTimer);
305
+ this.retryTimer = undefined;
306
+ }
307
+ }
308
+ /**
309
+ * Send an EVENT message through the transport.
310
+ * If the handshake is not yet complete (READY_ACK not received), the event
311
+ * is queued and will be flushed when READY_ACK arrives.
312
+ */
313
+ sendEventMessage(name, payload) {
314
+ const message = {
315
+ protocol: "appstrata-protocol",
316
+ version: "1.0",
317
+ type: "EVENT",
318
+ timestamp: Date.now(),
319
+ name,
320
+ payload,
321
+ };
322
+ if (!this.receivedReadyAck) {
323
+ this.pendingEvents.push(message);
324
+ logger.debug(`Event queued (awaiting READY_ACK): ${name}`);
325
+ return;
326
+ }
327
+ this.transport.send(message);
328
+ logger.debug(`Event fired: ${name}`);
329
+ }
330
+ fireShow() {
331
+ this.sendEventMessage("show");
332
+ }
333
+ fireStart() {
334
+ this.sendEventMessage("start");
335
+ }
336
+ fireHide() {
337
+ this.sendEventMessage("hide");
338
+ }
339
+ fireStop() {
340
+ this.sendEventMessage("stop");
341
+ }
342
+ fireContextChange(context) {
343
+ this.sendEventMessage("contextChange", appContextToWire(context));
344
+ }
345
+ /**
346
+ * Cleanup.
347
+ *
348
+ * Unsubscribes from the transport but does NOT close it.
349
+ * The transport lifecycle is owned by whoever created it
350
+ * (e.g., the session manager), not by the bridge.
351
+ */
352
+ destroy() {
353
+ this.cancelNextRetry();
354
+ if (this.unsubscribeFromTransport) {
355
+ this.unsubscribeFromTransport();
356
+ this.unsubscribeFromTransport = undefined;
357
+ }
358
+ this.pendingEvents = [];
359
+ }
360
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * AppStrata Protocol Package
3
+ *
4
+ * The messaging protocol implementation for AppStrata Digital Signage SDK.
5
+ * Contains message definitions, transport implementations, client (app-side) ProxyPlayer,
6
+ * and host (player-side) MessageBridge.
7
+ *
8
+ * @packageDocumentation
9
+ */
10
+ export * from "./messages.js";
11
+ export * from "./transport/index.js";
12
+ export * from "./client/index.js";
13
+ export * from "./host/index.js";
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,cAAc,eAAe,CAAC;AAG9B,cAAc,sBAAsB,CAAC;AAGrC,cAAc,mBAAmB,CAAC;AAGlC,cAAc,iBAAiB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,17 @@
1
+ /**
2
+ * AppStrata Protocol Package
3
+ *
4
+ * The messaging protocol implementation for AppStrata Digital Signage SDK.
5
+ * Contains message definitions, transport implementations, client (app-side) ProxyPlayer,
6
+ * and host (player-side) MessageBridge.
7
+ *
8
+ * @packageDocumentation
9
+ */
10
+ // Messages
11
+ export * from "./messages.js";
12
+ // Transport
13
+ export * from "./transport/index.js";
14
+ // Client (app-side)
15
+ export * from "./client/index.js";
16
+ // Host (player-side)
17
+ export * from "./host/index.js";
@@ -0,0 +1,197 @@
1
+ /**
2
+ * Protocol message types from the AppStrata specification.
3
+ *
4
+ * Defines all message types used in the HELLO/READY/READY_ACK handshake
5
+ * and subsequent RPC and event communication.
6
+ */
7
+ import type { AppContext, Resource } from "@appstrata/core";
8
+ /**
9
+ * Protocol message - base structure for all messages.
10
+ * All protocol messages must include these fields.
11
+ */
12
+ export interface ProtocolMessage {
13
+ /** Protocol identifier - must be "appstrata-protocol" */
14
+ protocol: "appstrata-protocol";
15
+ /** Protocol version - must be "1.0" */
16
+ version: "1.0";
17
+ /** Message type */
18
+ type: string;
19
+ /** Unix epoch milliseconds (Date.now()) at message construction time */
20
+ timestamp: number;
21
+ /** Allow additional properties */
22
+ [key: string]: unknown;
23
+ }
24
+ /**
25
+ * HELLO message (App → Host).
26
+ *
27
+ * Sent by app to announce readiness and establish session.
28
+ * App SHOULD send HELLO once per session after installing listeners.
29
+ */
30
+ export interface HelloMessage extends ProtocolMessage {
31
+ type: "HELLO";
32
+ /** Request ID for handshake correlation (MUST be unique per HELLO) */
33
+ requestId: string;
34
+ }
35
+ /**
36
+ * AppContext in wire format.
37
+ *
38
+ * This is the wire protocol representation where capabilities are an array.
39
+ * The SDK converts this to AppContext with hasCapability() method.
40
+ */
41
+ export interface AppContextWire {
42
+ instanceId?: string;
43
+ duration?: number;
44
+ config: Record<string, unknown>;
45
+ resources: Resource[];
46
+ mode: "signage" | "preview" | "development";
47
+ environment: string;
48
+ viewportWidth: number;
49
+ viewportHeight: number;
50
+ device: {
51
+ id: string;
52
+ name?: string;
53
+ type?: string;
54
+ version?: string;
55
+ platformName?: string;
56
+ location?: [number, number];
57
+ locale: string;
58
+ timezone: string;
59
+ touchscreen?: boolean;
60
+ };
61
+ capabilities?: string[];
62
+ }
63
+ /**
64
+ * READY message (Host → App).
65
+ *
66
+ * Delivers complete AppContext to the app.
67
+ * Host MUST deliver READY at least once per session.
68
+ */
69
+ export interface ReadyMessage extends ProtocolMessage {
70
+ type: "READY";
71
+ /** Complete app context */
72
+ context: AppContextWire;
73
+ /** Echoed from HELLO requestId if responding to HELLO; otherwise a fresh UUID generated by the Host. */
74
+ requestId: string;
75
+ }
76
+ /**
77
+ * READY_ACK message (App → Host).
78
+ *
79
+ * App acknowledges receipt of READY.
80
+ * App MUST always send READY_ACK upon receiving READY.
81
+ */
82
+ export interface ReadyAckMessage extends ProtocolMessage {
83
+ type: "READY_ACK";
84
+ /** Echoed from the READY message's requestId */
85
+ requestId: string;
86
+ }
87
+ /**
88
+ * REQUEST message (App → Host).
89
+ *
90
+ * Used for capability operations (storage, proxy, etc.).
91
+ * NOT used for retrieving context (context is delivered via READY).
92
+ *
93
+ * When `requestId` is present, the Host MUST reply with a RESPONSE.
94
+ * When `requestId` is absent, the message is a **notification** (fire-and-forget)
95
+ * and the Host MUST NOT reply.
96
+ */
97
+ export interface RequestMessage extends ProtocolMessage {
98
+ type: "REQUEST";
99
+ /** Unique request identifier. Absent for notifications (fire-and-forget). */
100
+ requestId?: string;
101
+ /** Operation name (e.g., "storage.get", "proxy.fetch") */
102
+ op: string;
103
+ /** Operation payload (operation-specific) */
104
+ payload?: unknown;
105
+ }
106
+ /**
107
+ * RESPONSE message (Host → App).
108
+ *
109
+ * Response to a REQUEST message.
110
+ */
111
+ export interface ResponseMessage extends ProtocolMessage {
112
+ type: "RESPONSE";
113
+ /** Request ID from the original REQUEST */
114
+ requestId: string;
115
+ /** Operation name echoed from the original REQUEST */
116
+ op: string;
117
+ /** Whether the operation succeeded */
118
+ ok: boolean;
119
+ /** Result data (if ok is true) */
120
+ result?: unknown;
121
+ /** Error information (if ok is false) */
122
+ error?: {
123
+ /** Error code */
124
+ code: string;
125
+ /** Human-readable error message */
126
+ message?: string;
127
+ /** Additional error details */
128
+ details?: unknown;
129
+ };
130
+ }
131
+ /**
132
+ * EVENT message (Host → App).
133
+ *
134
+ * Used for lifecycle events and context changes.
135
+ */
136
+ export interface EventMessage extends ProtocolMessage {
137
+ type: "EVENT";
138
+ /** Event name */
139
+ name: string;
140
+ /** Event payload (event-specific) */
141
+ payload?: unknown;
142
+ }
143
+ /**
144
+ * Type guard to check if data is a valid protocol message.
145
+ *
146
+ * Validates the base structure: protocol identifier, version, and type.
147
+ */
148
+ export declare function isProtocolMessage(data: unknown): data is ProtocolMessage;
149
+ /**
150
+ * Type guard for HELLO message.
151
+ */
152
+ export declare function isHelloMessage(msg: ProtocolMessage): msg is HelloMessage;
153
+ /**
154
+ * Type guard for READY message.
155
+ */
156
+ export declare function isReadyMessage(msg: ProtocolMessage): msg is ReadyMessage;
157
+ /**
158
+ * Type guard for READY_ACK message.
159
+ */
160
+ export declare function isReadyAckMessage(msg: ProtocolMessage): msg is ReadyAckMessage;
161
+ /**
162
+ * Type guard for REQUEST message.
163
+ */
164
+ export declare function isRequestMessage(msg: ProtocolMessage): msg is RequestMessage;
165
+ /**
166
+ * Type guard for RESPONSE message.
167
+ */
168
+ export declare function isResponseMessage(msg: ProtocolMessage): msg is ResponseMessage;
169
+ /**
170
+ * Type guard for EVENT message.
171
+ */
172
+ export declare function isEventMessage(msg: ProtocolMessage): msg is EventMessage;
173
+ /**
174
+ * Generate a unique request ID (UUID v4).
175
+ *
176
+ * @returns Unique request identifier
177
+ */
178
+ export declare function generateRequestId(): string;
179
+ /**
180
+ * Convert wire format context to AppContext.
181
+ *
182
+ * Adds the hasCapability() method to the context.
183
+ *
184
+ * @param wireContext - Context from wire protocol
185
+ * @returns AppContext with hasCapability method
186
+ */
187
+ export declare function wireContextToAppContext(wireContext: AppContextWire): AppContext;
188
+ /**
189
+ * Convert AppContext to wire format.
190
+ *
191
+ * Extracts capabilities array from hasCapability method.
192
+ *
193
+ * @param context - AppContext with hasCapability method
194
+ * @returns Wire format context with capabilities array
195
+ */
196
+ export declare function appContextToWire(context: AppContext): AppContextWire;
197
+ //# sourceMappingURL=messages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"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"}