@smoregg/sdk 0.6.2 → 1.0.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 (70) hide show
  1. package/README.md +29 -38
  2. package/dist/cjs/controller.cjs +299 -144
  3. package/dist/cjs/controller.cjs.map +1 -1
  4. package/dist/cjs/errors.cjs +36 -0
  5. package/dist/cjs/errors.cjs.map +1 -0
  6. package/dist/cjs/events.cjs +40 -19
  7. package/dist/cjs/events.cjs.map +1 -1
  8. package/dist/cjs/index.cjs +3 -8
  9. package/dist/cjs/index.cjs.map +1 -1
  10. package/dist/cjs/logger.cjs +75 -0
  11. package/dist/cjs/logger.cjs.map +1 -0
  12. package/dist/cjs/screen.cjs +302 -215
  13. package/dist/cjs/screen.cjs.map +1 -1
  14. package/dist/cjs/testing.cjs +265 -22
  15. package/dist/cjs/testing.cjs.map +1 -1
  16. package/dist/cjs/transport/DirectTransport.cjs.map +1 -1
  17. package/dist/cjs/transport/PostMessageTransport.cjs +11 -6
  18. package/dist/cjs/transport/PostMessageTransport.cjs.map +1 -1
  19. package/dist/cjs/transport/protocol.cjs +25 -5
  20. package/dist/cjs/transport/protocol.cjs.map +1 -1
  21. package/dist/esm/controller.js +292 -136
  22. package/dist/esm/controller.js.map +1 -1
  23. package/dist/esm/errors.js +34 -0
  24. package/dist/esm/errors.js.map +1 -0
  25. package/dist/esm/events.js +38 -18
  26. package/dist/esm/events.js.map +1 -1
  27. package/dist/esm/index.js +3 -4
  28. package/dist/esm/index.js.map +1 -1
  29. package/dist/esm/logger.js +73 -0
  30. package/dist/esm/logger.js.map +1 -0
  31. package/dist/esm/screen.js +290 -202
  32. package/dist/esm/screen.js.map +1 -1
  33. package/dist/esm/testing.js +265 -22
  34. package/dist/esm/testing.js.map +1 -1
  35. package/dist/esm/transport/DirectTransport.js.map +1 -1
  36. package/dist/esm/transport/PostMessageTransport.js +12 -7
  37. package/dist/esm/transport/PostMessageTransport.js.map +1 -1
  38. package/dist/esm/transport/protocol.js +23 -4
  39. package/dist/esm/transport/protocol.js.map +1 -1
  40. package/dist/types/controller.d.ts +1 -14
  41. package/dist/types/controller.d.ts.map +1 -1
  42. package/dist/types/errors.d.ts +45 -0
  43. package/dist/types/errors.d.ts.map +1 -0
  44. package/dist/types/events.d.ts +52 -12
  45. package/dist/types/events.d.ts.map +1 -1
  46. package/dist/types/index.d.ts +4 -6
  47. package/dist/types/index.d.ts.map +1 -1
  48. package/dist/types/logger.d.ts +35 -0
  49. package/dist/types/logger.d.ts.map +1 -0
  50. package/dist/types/screen.d.ts +1 -14
  51. package/dist/types/screen.d.ts.map +1 -1
  52. package/dist/types/testing.d.ts +0 -1
  53. package/dist/types/testing.d.ts.map +1 -1
  54. package/dist/types/transport/DirectTransport.d.ts +2 -1
  55. package/dist/types/transport/DirectTransport.d.ts.map +1 -1
  56. package/dist/types/transport/PostMessageTransport.d.ts +17 -2
  57. package/dist/types/transport/PostMessageTransport.d.ts.map +1 -1
  58. package/dist/types/transport/index.d.ts +2 -2
  59. package/dist/types/transport/index.d.ts.map +1 -1
  60. package/dist/types/transport/protocol.d.ts +71 -23
  61. package/dist/types/transport/protocol.d.ts.map +1 -1
  62. package/dist/types/transport/types.d.ts +24 -2
  63. package/dist/types/transport/types.d.ts.map +1 -1
  64. package/dist/types/types.d.ts +298 -215
  65. package/dist/types/types.d.ts.map +1 -1
  66. package/dist/umd/smore-sdk.umd.js +950 -349
  67. package/dist/umd/smore-sdk.umd.js.map +1 -1
  68. package/dist/umd/smore-sdk.umd.min.js +1 -1
  69. package/dist/umd/smore-sdk.umd.min.js.map +1 -1
  70. package/package.json +8 -13
@@ -1 +1 @@
1
- {"version":3,"file":"PostMessageTransport.js","sources":["../../../src/transport/PostMessageTransport.ts"],"sourcesContent":["/**\n * PostMessageTransport - Transport over window.postMessage for iframe-hosted games.\n *\n * Used inside an iframe. Sends `smore:emit` to parent and listens for `smore:event` from parent.\n */\n\nimport type { Transport, TransportEventHandler } from './types';\nimport type { SmoreEventMessage, SmoreAckMessage } from './protocol';\nimport { isSmoreMessage } from './protocol';\n\nexport class PostMessageTransport implements Transport {\n private handlers = new Map<string, Set<TransportEventHandler>>();\n private ackCallbacks = new Map<string, (...args: any[]) => void>();\n private ackCounter = 0;\n private parentOrigin: string;\n private boundMessageHandler: (e: MessageEvent) => void;\n\n constructor(parentOrigin: string = '*') {\n this.parentOrigin = parentOrigin;\n this.boundMessageHandler = this.handleMessage.bind(this);\n window.addEventListener('message', this.boundMessageHandler);\n }\n\n emit(event: string, ...args: any[]): void {\n // Detect if last arg is a callback (ack pattern)\n let data: any = args[0];\n let ackId: string | undefined;\n\n if (args.length >= 2 && typeof args[args.length - 1] === 'function') {\n data = args.length === 2 ? args[0] : args[0];\n const callback = args[args.length - 1];\n ackId = `ack_${++this.ackCounter}`;\n this.ackCallbacks.set(ackId, callback);\n }\n\n window.parent.postMessage(\n { type: 'smore:emit', payload: { event, data, ackId } },\n this.parentOrigin,\n );\n }\n\n on(event: string, handler: TransportEventHandler): void {\n let set = this.handlers.get(event);\n if (!set) {\n set = new Set();\n this.handlers.set(event, set);\n }\n set.add(handler);\n }\n\n off(event: string, handler?: TransportEventHandler): void {\n if (!handler) {\n this.handlers.delete(event);\n return;\n }\n this.handlers.get(event)?.delete(handler);\n }\n\n destroy(): void {\n window.removeEventListener('message', this.boundMessageHandler);\n this.handlers.clear();\n this.ackCallbacks.clear();\n }\n\n private handleMessage(e: MessageEvent): void {\n // Origin validation: only accept messages from the expected parent\n if (this.parentOrigin !== '*' && e.origin !== this.parentOrigin) return;\n\n const msg = e.data;\n if (!isSmoreMessage(msg)) return;\n\n if (msg.type === 'smore:event') {\n const { event, data } = (msg as SmoreEventMessage).payload;\n const set = this.handlers.get(event);\n if (set) {\n set.forEach((handler) => handler(data));\n }\n } else if (msg.type === 'smore:ack') {\n const { ackId, data } = (msg as SmoreAckMessage).payload;\n const cb = this.ackCallbacks.get(ackId);\n if (cb) {\n this.ackCallbacks.delete(ackId);\n cb(data);\n }\n }\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"PostMessageTransport.js","sources":["../../../src/transport/PostMessageTransport.ts"],"sourcesContent":["/**\n * PostMessageTransport - Transport over window.postMessage for iframe-hosted games.\n *\n * Used inside an iframe. Sends `_bridge:emit` to parent and listens for `_bridge:event` from parent.\n */\n\nimport type { Transport, TransportEventHandler } from './types';\nimport type { BridgeEventMessage, BridgeAckMessage } from './protocol';\nimport { isBridgeMessage } from './protocol';\n\n/**\n * PostMessage-based transport for iframe-hosted games.\n *\n * Handles bi-directional communication between iframe game and parent platform using _bridge:* protocol.\n * - Outbound: `_bridge:emit` messages sent to parent\n * - Inbound: `_bridge:event` messages received from parent\n * - Acknowledgment: `_bridge:ack` pattern for request-response flows\n *\n * @example\n * ```ts\n * const transport = new PostMessageTransport('https://smore.gg');\n * transport.on('game-start', (data) => console.log('Game started', data));\n * transport.emit('player-ready', { playerIndex: 0 });\n * ```\n */\nexport class PostMessageTransport implements Transport {\n private handlers = new Map<string, Set<TransportEventHandler>>();\n private ackCallbacks = new Map<string, (...args: unknown[]) => void>();\n private ackCounter = 0;\n private parentOrigin: string;\n private boundMessageHandler: (e: MessageEvent) => void;\n\n constructor(parentOrigin: string = '*') {\n this.parentOrigin = parentOrigin;\n this.boundMessageHandler = this.handleMessage.bind(this);\n window.addEventListener('message', this.boundMessageHandler);\n }\n\n emit(event: string, ...args: unknown[]): void {\n // Detect if last arg is a callback (ack pattern)\n let data: unknown = args[0];\n let ackId: string | undefined;\n\n // Branch 1: emit('event', callback) shorthand — no data, callback only\n // Callback will be invoked when parent sends _bridge:ack with matching ackId\n if (args.length === 1 && typeof args[0] === 'function') {\n data = undefined;\n const callback = args[0] as (...cbArgs: unknown[]) => void;\n ackId = `ack_${++this.ackCounter}`;\n this.ackCallbacks.set(ackId, callback);\n }\n // Branch 2: emit('event', data, callback) — data + callback (request-response pattern)\n // Parent receives event with data and can send _bridge:ack response\n else if (args.length >= 2 && typeof args[args.length - 1] === 'function') {\n data = args[0];\n const callback = args[args.length - 1] as (...cbArgs: unknown[]) => void;\n ackId = `ack_${++this.ackCounter}`;\n this.ackCallbacks.set(ackId, callback);\n }\n\n window.parent.postMessage(\n { type: '_bridge:emit', payload: { event, data, ackId } },\n this.parentOrigin,\n );\n }\n\n on(event: string, handler: TransportEventHandler): void {\n let set = this.handlers.get(event);\n if (!set) {\n set = new Set();\n this.handlers.set(event, set);\n }\n set.add(handler);\n }\n\n off(event: string, handler?: TransportEventHandler): void {\n if (!handler) {\n this.handlers.delete(event);\n return;\n }\n this.handlers.get(event)?.delete(handler);\n }\n\n destroy(): void {\n window.removeEventListener('message', this.boundMessageHandler);\n this.handlers.clear();\n this.ackCallbacks.clear();\n }\n\n private handleMessage(e: MessageEvent): void {\n // Origin validation: only accept messages from the expected parent\n if (this.parentOrigin !== '*' && e.origin !== this.parentOrigin) return;\n\n const msg = e.data;\n if (!isBridgeMessage(msg)) return;\n\n // Branch 1: _bridge:event — state sync from bridge (server → bridge → game)\n // Parent relays socket events to iframe via this type. Game subscribes with on().\n if (msg.type === '_bridge:event') {\n const { event, data } = (msg as BridgeEventMessage).payload;\n const set = this.handlers.get(event);\n if (set) {\n set.forEach((handler) => handler(data));\n }\n }\n // Branch 2: _bridge:ack — response to emit with callback (request-response flow)\n // Fires the callback that was passed to emit('event', data, callback).\n // Edge case: In postMessage environment, callbacks cannot be truly serialized,\n // so only data types that survive JSON serialization roundtrip will work.\n else if (msg.type === '_bridge:ack') {\n const { ackId, data } = (msg as BridgeAckMessage).payload;\n const cb = this.ackCallbacks.get(ackId);\n if (cb) {\n this.ackCallbacks.delete(ackId);\n cb(data);\n }\n }\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1,7 +1,26 @@
1
- const SMORE_MSG_PREFIX = "smore:";
2
- function isSmoreMessage(data) {
3
- return data && typeof data === "object" && typeof data.type === "string" && data.type.startsWith(SMORE_MSG_PREFIX);
1
+ const BRIDGE_MSG_PREFIX = "_bridge:";
2
+ function isBridgeMessage(data) {
3
+ return data !== null && typeof data === "object" && "type" in data && typeof data.type === "string" && data.type.startsWith(BRIDGE_MSG_PREFIX);
4
+ }
5
+ function validateInitPayload(payload) {
6
+ if (!payload || typeof payload !== "object") {
7
+ throw new Error("[SDK] _bridge:init payload must be an object");
8
+ }
9
+ const p = payload;
10
+ if (typeof p.side !== "string" || !["host", "player"].includes(p.side)) {
11
+ throw new Error(`[SDK] _bridge:init payload.side must be "host" or "player", got: ${p.side}`);
12
+ }
13
+ if (typeof p.roomCode !== "string" || p.roomCode.length === 0) {
14
+ throw new Error("[SDK] _bridge:init payload.roomCode must be a non-empty string");
15
+ }
16
+ if (!Array.isArray(p.players)) {
17
+ throw new Error("[SDK] _bridge:init payload.players must be an array");
18
+ }
19
+ if (p.myIndex !== void 0 && typeof p.myIndex !== "number") {
20
+ throw new Error("[SDK] _bridge:init payload.myIndex must be a number if provided");
21
+ }
22
+ return true;
4
23
  }
5
24
 
6
- export { SMORE_MSG_PREFIX, isSmoreMessage };
25
+ export { BRIDGE_MSG_PREFIX, isBridgeMessage, validateInitPayload };
7
26
  //# sourceMappingURL=protocol.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.js","sources":["../../../src/transport/protocol.ts"],"sourcesContent":["/**\n * postMessage protocol types for iframe ↔ parent communication.\n */\n\nexport const SMORE_MSG_PREFIX = 'smore:' as const;\n\nexport interface SmoreReadyMessage {\n type: 'smore:ready';\n}\n\nexport interface SmoreInitMessage {\n type: 'smore:init';\n payload: {\n side: 'host' | 'player';\n roomCode: string;\n players: any[];\n leaderId: string | null;\n myIndex?: number;\n isLeader?: boolean;\n };\n}\n\nexport interface SmoreEmitMessage {\n type: 'smore:emit';\n payload: {\n event: string;\n data?: any;\n ackId?: string;\n };\n}\n\nexport interface SmoreEventMessage {\n type: 'smore:event';\n payload: {\n event: string;\n data?: any;\n };\n}\n\nexport interface SmoreAckMessage {\n type: 'smore:ack';\n payload: {\n ackId: string;\n data?: any;\n };\n}\n\nexport interface SmoreUpdateMessage {\n type: 'smore:update';\n payload: {\n players?: any[];\n leaderId?: string | null;\n };\n}\n\n// DEPRECATED: SmoreLoadedMessage removed - no longer used in protocol\n// Previously: interface SmoreLoadedMessage { type: 'smore:loaded' }\n\nexport type SmoreMessage =\n | SmoreReadyMessage\n | SmoreInitMessage\n | SmoreEmitMessage\n | SmoreEventMessage\n | SmoreAckMessage\n | SmoreUpdateMessage;\n\nexport function isSmoreMessage(data: any): data is SmoreMessage {\n return data && typeof data === 'object' && typeof data.type === 'string' && data.type.startsWith(SMORE_MSG_PREFIX);\n}\n"],"names":[],"mappings":"AAIO,MAAM,gBAAA,GAAmB;AA8DzB,SAAS,eAAe,IAAA,EAAiC;AAC9D,EAAA,OAAO,IAAA,IAAQ,OAAO,IAAA,KAAS,QAAA,IAAY,OAAO,IAAA,CAAK,IAAA,KAAS,QAAA,IAAY,IAAA,CAAK,IAAA,CAAK,UAAA,CAAW,gBAAgB,CAAA;AACnH;;;;"}
1
+ {"version":3,"file":"protocol.js","sources":["../../../src/transport/protocol.ts"],"sourcesContent":["/**\n * postMessage protocol types for iframe ↔ parent communication.\n *\n * Uses `_bridge:` prefix to clearly distinguish from `smore:*` socket events.\n * - `_bridge:*` = internal iframe postMessage protocol (never on socket)\n * - `smore:*` = platform service events (socket-level, e.g. smore:player-joined)\n */\n\n/**\n * Cross-reference: `CharacterAppearance` (SDK type) has an identical shape to\n * `CharacterDTO` (server type in game-project/types/src/types.ts).\n * If either type changes, the other must be updated to stay in sync.\n */\nimport type { CharacterAppearance } from '../types';\n\nexport const BRIDGE_MSG_PREFIX = '_bridge:' as const;\n\nexport interface BridgeReadyMessage {\n type: '_bridge:ready';\n}\n\n/**\n * BridgeInitMessage contains player data sent from the platform to the game iframe.\n *\n * **Field naming convention:**\n * The server uses `name` and `character` fields (matching server/Player model naming).\n * SDK code may reference fallback fields like `nickname` and `appearance` for defensive\n * compatibility with potential future field name changes, but currently the server\n * always sends `name` and `character`.\n */\nexport interface BridgeInitMessage {\n type: '_bridge:init';\n payload: {\n // 'host' = screen side, 'player' = controller side (legacy naming)\n side: 'host' | 'player';\n roomCode: string;\n players: Array<{\n playerIndex: number;\n name: string;\n connected: boolean;\n character: CharacterAppearance | null;\n }>;\n myIndex?: number;\n };\n}\n\nexport interface BridgeEmitMessage {\n type: '_bridge:emit';\n payload: {\n event: string;\n data?: unknown;\n ackId?: string;\n };\n}\n\nexport interface BridgeEventMessage {\n type: '_bridge:event';\n payload: {\n event: string;\n data?: unknown;\n };\n}\n\nexport interface BridgeAckMessage {\n type: '_bridge:ack';\n payload: {\n ackId: string;\n data?: unknown;\n };\n}\n\nexport interface BridgeUpdateMessage {\n type: '_bridge:update';\n payload: {\n players?: Array<{\n playerIndex: number;\n name: string;\n connected: boolean;\n character: CharacterAppearance | null;\n }>;\n };\n}\n\nexport type BridgeMessage =\n | BridgeReadyMessage\n | BridgeInitMessage\n | BridgeEmitMessage\n | BridgeEventMessage\n | BridgeAckMessage\n | BridgeUpdateMessage;\n\nexport function isBridgeMessage(data: unknown): data is BridgeMessage {\n return (\n data !== null &&\n typeof data === 'object' &&\n 'type' in data &&\n typeof data.type === 'string' &&\n data.type.startsWith(BRIDGE_MSG_PREFIX)\n );\n}\n\n/**\n * Validates the structure of a _bridge:init payload.\n *\n * Performs runtime validation to ensure the payload contains all required fields\n * with correct types. This provides early error detection if the parent frame\n * sends malformed initialization data.\n *\n * @param payload - The payload to validate\n * @returns true if payload is valid\n * @throws {Error} if validation fails with a descriptive error message\n *\n * @example\n * ```ts\n * try {\n * validateInitPayload(msg.payload);\n * // proceed with initialization\n * } catch (err) {\n * console.error('Invalid init payload:', err.message);\n * }\n * ```\n */\nexport function validateInitPayload(payload: unknown): payload is BridgeInitMessage['payload'] {\n if (!payload || typeof payload !== 'object') {\n throw new Error('[SDK] _bridge:init payload must be an object');\n }\n\n const p = payload as Record<string, unknown>;\n\n // Required: side\n if (typeof p.side !== 'string' || !['host', 'player'].includes(p.side)) {\n throw new Error(`[SDK] _bridge:init payload.side must be \"host\" or \"player\", got: ${p.side}`);\n }\n\n // Required: roomCode\n if (typeof p.roomCode !== 'string' || p.roomCode.length === 0) {\n throw new Error('[SDK] _bridge:init payload.roomCode must be a non-empty string');\n }\n\n // Required: players (array)\n if (!Array.isArray(p.players)) {\n throw new Error('[SDK] _bridge:init payload.players must be an array');\n }\n\n // Optional but validated if present: myIndex (controller-side only)\n if (p.myIndex !== undefined && typeof p.myIndex !== 'number') {\n throw new Error('[SDK] _bridge:init payload.myIndex must be a number if provided');\n }\n\n return true;\n}\n"],"names":[],"mappings":"AAeO,MAAM,iBAAA,GAAoB;AA4E1B,SAAS,gBAAgB,IAAA,EAAsC;AACpE,EAAA,OACE,IAAA,KAAS,IAAA,IACT,OAAO,IAAA,KAAS,YAChB,MAAA,IAAU,IAAA,IACV,OAAO,IAAA,CAAK,IAAA,KAAS,QAAA,IACrB,IAAA,CAAK,IAAA,CAAK,WAAW,iBAAiB,CAAA;AAE1C;AAuBO,SAAS,oBAAoB,OAAA,EAA2D;AAC7F,EAAA,IAAI,CAAC,OAAA,IAAW,OAAO,OAAA,KAAY,QAAA,EAAU;AAC3C,IAAA,MAAM,IAAI,MAAM,8CAA8C,CAAA;AAAA,EAChE;AAEA,EAAA,MAAM,CAAA,GAAI,OAAA;AAGV,EAAA,IAAI,OAAO,CAAA,CAAE,IAAA,KAAS,QAAA,IAAY,CAAC,CAAC,MAAA,EAAQ,QAAQ,CAAA,CAAE,QAAA,CAAS,CAAA,CAAE,IAAI,CAAA,EAAG;AACtE,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,iEAAA,EAAoE,CAAA,CAAE,IAAI,CAAA,CAAE,CAAA;AAAA,EAC9F;AAGA,EAAA,IAAI,OAAO,CAAA,CAAE,QAAA,KAAa,YAAY,CAAA,CAAE,QAAA,CAAS,WAAW,CAAA,EAAG;AAC7D,IAAA,MAAM,IAAI,MAAM,gEAAgE,CAAA;AAAA,EAClF;AAGA,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,CAAA,CAAE,OAAO,CAAA,EAAG;AAC7B,IAAA,MAAM,IAAI,MAAM,qDAAqD,CAAA;AAAA,EACvE;AAGA,EAAA,IAAI,EAAE,OAAA,KAAY,MAAA,IAAa,OAAO,CAAA,CAAE,YAAY,QAAA,EAAU;AAC5D,IAAA,MAAM,IAAI,MAAM,iEAAiE,CAAA;AAAA,EACnF;AAEA,EAAA,OAAO,IAAA;AACT;;;;"}
@@ -27,20 +27,7 @@
27
27
  * // Use controller.instance for immediate access
28
28
  * ```
29
29
  */
30
- import type { Controller, ControllerConfig, EventMap, SmoreError, SmoreErrorCode } from './types';
31
- /**
32
- * Custom error class for SDK errors.
33
- */
34
- export declare class SmoreSDKError extends Error {
35
- readonly code: SmoreErrorCode;
36
- readonly cause?: Error;
37
- readonly details?: Record<string, unknown>;
38
- constructor(code: SmoreErrorCode, message: string, options?: {
39
- cause?: Error;
40
- details?: Record<string, unknown>;
41
- });
42
- toSmoreError(): SmoreError;
43
- }
30
+ import type { Controller, ControllerConfig, EventMap } from './types';
44
31
  /**
45
32
  * Create a Controller instance for the player/phone side of your game.
46
33
  *
@@ -1 +1 @@
1
- {"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../src/controller.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EACV,UAAU,EACV,gBAAgB,EAKhB,QAAQ,EAKR,UAAU,EACV,cAAc,EACf,MAAM,SAAS,CAAC;AA2BjB;;GAEG;AACH,qBAAa,aAAc,SAAQ,KAAK;IACtC,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;IACvB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAGzC,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QACR,KAAK,CAAC,EAAE,KAAK,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACnC;IAiBH,YAAY,IAAI,UAAU;CAQ3B;AAidD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,SAAS,QAAQ,GAAG,QAAQ,EAClE,MAAM,CAAC,EAAE,gBAAgB,CAAC,OAAO,CAAC,GACjC,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,GAAG;IAAE,QAAQ,EAAE,UAAU,CAAC,OAAO,CAAC,CAAA;CAAE,CAUlE"}
1
+ {"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../src/controller.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EACV,UAAU,EACV,gBAAgB,EAIhB,QAAQ,EAIT,MAAM,SAAS,CAAC;AA8qBjB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,SAAS,QAAQ,GAAG,QAAQ,EAClE,MAAM,CAAC,EAAE,gBAAgB,CAAC,OAAO,CAAC,GACjC,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,GAAG;IAAE,QAAQ,EAAE,UAAU,CAAC,OAAO,CAAC,CAAA;CAAE,CAUlE"}
@@ -0,0 +1,45 @@
1
+ import type { SmoreError, SmoreErrorCode } from './types';
2
+ /**
3
+ * Base error class for SDK-specific errors with structured metadata.
4
+ *
5
+ * Provides error codes, optional cause chaining, and custom details for debugging.
6
+ * Use this instead of generic Error for all SDK-thrown errors.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * throw new SmoreSDKError('INVALID_EVENT', 'Event name must not contain ":"', {
11
+ * details: { event: 'foo:bar' }
12
+ * });
13
+ * ```
14
+ *
15
+ * @example With cause
16
+ * ```ts
17
+ * try {
18
+ * JSON.parse(data);
19
+ * } catch (err) {
20
+ * throw new SmoreSDKError('UNKNOWN', 'Invalid JSON payload', {
21
+ * cause: err as Error,
22
+ * details: { rawData: data }
23
+ * });
24
+ * }
25
+ * ```
26
+ */
27
+ export declare class SmoreSDKError extends Error {
28
+ readonly code: SmoreErrorCode;
29
+ /**
30
+ * The original error that caused this error.
31
+ *
32
+ * **Note:** This field intentionally shadows the native `Error.cause` (ES2022).
33
+ * Both this class field and the native property (set via `super()` options bag)
34
+ * are assigned the same value, so there is no behavioral difference.
35
+ * The explicit field provides TypeScript type narrowing to `Error` instead of `unknown`.
36
+ */
37
+ readonly cause?: Error;
38
+ readonly details?: Record<string, unknown>;
39
+ constructor(code: SmoreErrorCode, message: string, options?: {
40
+ cause?: Error;
41
+ details?: Record<string, unknown>;
42
+ });
43
+ toSmoreError(): SmoreError;
44
+ }
45
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE1D;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,qBAAa,aAAc,SAAQ,KAAK;IACtC,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B;;;;;;;OAOG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;IACvB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAGzC,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,KAAK,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE;IAehE,YAAY,IAAI,UAAU;CAQ3B"}
@@ -1,26 +1,66 @@
1
1
  /**
2
- * SDK 시스템 이벤트 상수
3
- * 모든 시스템 이벤트는 'smore:' prefix 사용
4
- * 유저 이벤트는 ':' 사용 불가
2
+ * SDK system event constants (socket level)
3
+ *
4
+ * smore:* prefix = platform service events
5
+ * User events are validated to prevent ':' usage via validateEventName()
6
+ *
7
+ * Note: iframe ↔ parent internal communication uses _bridge:* prefix (transport/protocol.ts)
8
+ */
9
+ /**
10
+ * Platform system event names (internal use only).
11
+ *
12
+ * These events are reserved by the S'MORE platform and cannot be used by game code.
13
+ * All platform events use the `smore:` prefix to avoid conflicts with user events.
14
+ *
15
+ * User-defined events are validated to prevent `:` usage via validateEventName().
16
+ *
17
+ * @internal Not part of the public SDK API. Do not import directly.
5
18
  */
6
19
  export declare const SMORE_EVENTS: {
7
- readonly READY: "smore:ready";
8
20
  readonly GAME_OVER: "smore:game-over";
9
21
  readonly RETURN_TO_LOBBY: "smore:return-to-lobby";
10
- readonly PLAYER_JOIN: "smore:player-join";
11
- readonly PLAYER_LEAVE: "smore:player-leave";
22
+ readonly PLAYER_JOINED: "smore:player-joined";
23
+ readonly PLAYER_LEFT: "smore:player-left";
24
+ readonly PLAYER_DISCONNECTED: "smore:player-disconnected";
25
+ readonly PLAYER_RECONNECTED: "smore:player-reconnected";
26
+ readonly PLAYER_CHARACTER_UPDATED: "smore:player-character-updated";
27
+ readonly RATE_LIMITED: "smore:rate-limited";
12
28
  readonly SEND_TO_PLAYER: "smore:send-to-player";
13
- readonly INIT: "smore:init";
14
- readonly UPDATE: "smore:update";
15
29
  };
16
30
  export type SmoreEvent = typeof SMORE_EVENTS[keyof typeof SMORE_EVENTS];
31
+ export declare const SYSTEM_EVENTS: ReadonlySet<string>;
32
+ export declare const EVENT_NAME_REGEX: RegExp;
33
+ export declare const EVENT_NAME_MAX_LENGTH = 128;
17
34
  /**
18
- * 유저 이벤트명 검증
19
- * ':' 포함 시 에러, '_'와 '-'는 허용
35
+ * Validate a user-defined event name.
36
+ *
37
+ * Enforces naming rules to prevent conflicts with platform system events:
38
+ * - Must start with a letter
39
+ * - Can contain letters, numbers, hyphens, underscores
40
+ * - Must end with a letter or number
41
+ * - Cannot contain `:` (reserved for platform events like `smore:*`)
42
+ * - Maximum length: 128 characters
43
+ *
44
+ * @throws {SmoreSDKError} INVALID_EVENT if validation fails
45
+ *
46
+ * @example
47
+ * ```ts
48
+ * validateEventName('player-ready'); // OK
49
+ * validateEventName('score_update'); // OK
50
+ * validateEventName('tap123'); // OK
51
+ * validateEventName('smore:internal'); // Throws: colon not allowed
52
+ * validateEventName('123start'); // Throws: must start with letter
53
+ * ```
20
54
  */
21
- export declare function validateUserEvent(event: string): void;
55
+ export declare function validateEventName(event: string): void;
22
56
  /**
23
- * 시스템 이벤트인지 확인
57
+ * Check if an event name is a system event.
58
+ *
59
+ * System events use the `smore:` prefix and are reserved for platform use.
60
+ * Prefix-based check is intentional for forward-compatibility with new system events.
61
+ *
62
+ * @param event - Event name to check
63
+ * @returns true if the event is a system event
24
64
  */
25
65
  export declare function isSystemEvent(event: string): boolean;
26
66
  //# sourceMappingURL=events.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/events.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,eAAO,MAAM,YAAY;;;;;;;;;CAgBf,CAAC;AAEX,MAAM,MAAM,UAAU,GAAG,OAAO,YAAY,CAAC,MAAM,OAAO,YAAY,CAAC,CAAC;AAExE;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAOrD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEpD"}
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/events.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH;;;;;;;;;GASG;AACH,eAAO,MAAM,YAAY;;;;;;;;;;CAmBf,CAAC;AAEX,MAAM,MAAM,UAAU,GAAG,OAAO,YAAY,CAAC,MAAM,OAAO,YAAY,CAAC,CAAC;AAExE,eAAO,MAAM,aAAa,EAAE,WAAW,CAAC,MAAM,CAE7C,CAAC;AAGF,eAAO,MAAM,gBAAgB,QAA2C,CAAC;AAEzE,eAAO,MAAM,qBAAqB,MAAM,CAAC;AAEzC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAmBrD;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEpD"}
@@ -35,13 +35,11 @@
35
35
  * controller.send('tap', { timestamp: Date.now() });
36
36
  * ```
37
37
  */
38
- export { createScreen, SmoreSDKError } from './screen';
38
+ export { createScreen } from './screen';
39
39
  export { createController } from './controller';
40
- export type { PlayerIndex, RoomCode, EventMap, EmptyEventMap, EventNames, EventData, Controller, ControllerConfig, ControllerEventHandler, ControllerListeners, ControllerInfo, CharacterAppearance, Screen, ScreenConfig, ScreenEventHandler, ScreenListeners, GameResults, SmoreError, SmoreErrorCode, LogLevel, DebugOptions, Transport, TransportEventHandler, GameMetadata, GameState, TapButtonProps, HoldButtonProps, Direction, DirectionPadProps, SwipeAreaProps, Player, SmoreScreenPlayer, SmoreHostPlayer, SmoreControllerInfo, SmorePlayerInfo, SmoreScreenConfig, SmoreHostConfig, SmoreControllerConfig, SmorePlayerConfig, SmoreScreen as SmoreScreenType, SmoreController as SmoreControllerType, InputCallback, } from './types';
41
- export { DirectTransport } from './transport/DirectTransport';
42
- export { PostMessageTransport } from './transport/PostMessageTransport';
43
- export { SMORE_EVENTS, validateUserEvent, isSystemEvent } from './events';
44
- export type { SmoreEvent } from './events';
40
+ export { SmoreSDKError } from './errors';
41
+ export { validateEventName } from './events';
42
+ export type { PlayerIndex, RoomCode, EventMap, EventNames, EventData, Controller, ControllerConfig, ControllerEventHandler, ControllerListeners, ControllerInfo, CharacterAppearance, Screen, ScreenConfig, ScreenEventHandler, ScreenListeners, GameResults, SmoreError, SmoreErrorCode, LogLevel, DebugOptions, GameMetadata, } from './types';
45
43
  export { createMockScreen, createMockController } from './testing';
46
44
  export type { MockScreen, MockController, MockOptions } from './testing';
47
45
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAMH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGhD,YAAY,EAEV,WAAW,EACX,QAAQ,EAER,QAAQ,EACR,aAAa,EACb,UAAU,EACV,SAAS,EAET,UAAU,EACV,gBAAgB,EAChB,sBAAsB,EACtB,mBAAmB,EACnB,cAAc,EACd,mBAAmB,EAEnB,MAAM,EACN,YAAY,EACZ,kBAAkB,EAClB,eAAe,EAEf,WAAW,EAEX,UAAU,EACV,cAAc,EAEd,QAAQ,EACR,YAAY,EAEZ,SAAS,EACT,qBAAqB,EAErB,YAAY,EACZ,SAAS,EAET,cAAc,EACd,eAAe,EACf,SAAS,EACT,iBAAiB,EACjB,cAAc,EAEd,MAAM,EACN,iBAAiB,EACjB,eAAe,EACf,mBAAmB,EACnB,eAAe,EACf,iBAAiB,EACjB,eAAe,EACf,qBAAqB,EACrB,iBAAiB,EACjB,WAAW,IAAI,eAAe,EAC9B,eAAe,IAAI,mBAAmB,EACtC,aAAa,GACd,MAAM,SAAS,CAAC;AAcjB,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AAGxE,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAC1E,YAAY,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAM3C,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACnE,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAMH,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAG7C,YAAY,EAEV,WAAW,EACX,QAAQ,EAER,QAAQ,EACR,UAAU,EACV,SAAS,EAET,UAAU,EACV,gBAAgB,EAChB,sBAAsB,EACtB,mBAAmB,EACnB,cAAc,EACd,mBAAmB,EAEnB,MAAM,EACN,YAAY,EACZ,kBAAkB,EAClB,eAAe,EAEf,WAAW,EAEX,UAAU,EACV,cAAc,EAEd,QAAQ,EACR,YAAY,EAEZ,YAAY,GACb,MAAM,SAAS,CAAC;AAMjB,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACnE,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC"}
@@ -0,0 +1,35 @@
1
+ import type { DebugOptions } from './types';
2
+ /**
3
+ * Internal debug logger with configurable verbosity levels.
4
+ *
5
+ * Maps SDK log levels (debug/info/warn/error) to console methods.
6
+ * Can be toggled per-instance with granular control over send/receive/lifecycle logs.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * const logger = new DebugLogger({ enabled: true, level: 'info' });
11
+ * logger.info('Game initialized');
12
+ * logger.send('player-ready', { index: 0 }); // Shows as debug
13
+ * ```
14
+ */
15
+ export declare class DebugLogger {
16
+ private enabled;
17
+ private level;
18
+ private prefix;
19
+ private logSend;
20
+ private logReceive;
21
+ private logLifecycle;
22
+ private customLogger?;
23
+ private static levelOrder;
24
+ constructor(options?: boolean | DebugOptions, defaultPrefix?: string);
25
+ private shouldLog;
26
+ private log;
27
+ debug(message: string, data?: unknown): void;
28
+ info(message: string, data?: unknown): void;
29
+ warn(message: string, data?: unknown): void;
30
+ error(message: string, data?: unknown): void;
31
+ send(event: string, data?: unknown): void;
32
+ receive(event: string, data?: unknown): void;
33
+ lifecycle(message: string, data?: unknown): void;
34
+ }
35
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAY,MAAM,SAAS,CAAC;AAEtD;;;;;;;;;;;;GAYG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,KAAK,CAAW;IACxB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,UAAU,CAAU;IAC5B,OAAO,CAAC,YAAY,CAAU;IAC9B,OAAO,CAAC,YAAY,CAAC,CAA6D;IAElF,OAAO,CAAC,MAAM,CAAC,UAAU,CAKvB;gBAEU,OAAO,CAAC,EAAE,OAAO,GAAG,YAAY,EAAE,aAAa,SAAY;IAWvE,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,GAAG;IAgBX,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI;IAI5C,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI;IAI3C,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI;IAI3C,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI;IAI5C,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI;IAOzC,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI;IAO5C,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI;CAKjD"}
@@ -28,20 +28,7 @@
28
28
  * // Use screen.instance for immediate access
29
29
  * ```
30
30
  */
31
- import type { EventMap, Screen, ScreenConfig, SmoreError, SmoreErrorCode } from './types';
32
- /**
33
- * Custom error class for SDK errors with structured error handling.
34
- */
35
- export declare class SmoreSDKError extends Error {
36
- readonly code: SmoreErrorCode;
37
- readonly cause?: Error;
38
- readonly details?: Record<string, unknown>;
39
- constructor(code: SmoreErrorCode, message: string, options?: {
40
- cause?: Error;
41
- details?: Record<string, unknown>;
42
- });
43
- toSmoreError(): SmoreError;
44
- }
31
+ import type { EventMap, Screen, ScreenConfig } from './types';
45
32
  /**
46
33
  * Create a Screen instance for the host/TV side of your game.
47
34
  *
@@ -1 +1 @@
1
- {"version":3,"file":"screen.d.ts","sourceRoot":"","sources":["../../src/screen.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,KAAK,EACV,QAAQ,EAGR,MAAM,EACN,YAAY,EAMZ,UAAU,EACV,cAAc,EAGf,MAAM,SAAS,CAAC;AAyBjB;;GAEG;AACH,qBAAa,aAAc,SAAQ,KAAK;IACtC,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;IACvB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAGzC,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,KAAK,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE;IAiBhE,YAAY,IAAI,UAAU;CAQ3B;AAmmBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,YAAY,CAAC,OAAO,SAAS,QAAQ,GAAG,QAAQ,EAC9D,MAAM,CAAC,EAAE,YAAY,CAAC,OAAO,CAAC,GAC7B,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,CAAA;CAAE,CAU1D"}
1
+ {"version":3,"file":"screen.d.ts","sourceRoot":"","sources":["../../src/screen.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,KAAK,EACV,QAAQ,EAGR,MAAM,EACN,YAAY,EAMb,MAAM,SAAS,CAAC;AAuvBjB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,YAAY,CAAC,OAAO,SAAS,QAAQ,GAAG,QAAQ,EAC9D,MAAM,CAAC,EAAE,YAAY,CAAC,OAAO,CAAC,GAC7B,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,CAAA;CAAE,CAU1D"}
@@ -43,7 +43,6 @@ export declare function createMockScreen<TEvents extends EventMap = EventMap>(op
43
43
  * ```ts
44
44
  * const controller = createMockController<MyEvents>({
45
45
  * myIndex: 0,
46
- * isLeader: true,
47
46
  * });
48
47
  *
49
48
  * // Simulate receiving from screen
@@ -1 +1 @@
1
- {"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../../src/testing.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EACV,QAAQ,EAQR,UAAU,EACV,cAAc,EACd,WAAW,EACZ,MAAM,SAAS,CAAC;AAiBjB;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,SAAS,QAAQ,GAAG,QAAQ,EAClE,OAAO,GAAE,WAAgB,GACxB,UAAU,CAAC,OAAO,CAAC,CA+NrB;AAWD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,SAAS,QAAQ,GAAG,QAAQ,EACtE,OAAO,GAAE,WAAgB,GACxB,cAAc,CAAC,OAAO,CAAC,CAiJzB;AAMD,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC"}
1
+ {"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../../src/testing.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EACV,QAAQ,EASR,UAAU,EACV,cAAc,EACd,WAAW,EACZ,MAAM,SAAS,CAAC;AAkBjB;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,SAAS,QAAQ,GAAG,QAAQ,EAClE,OAAO,GAAE,WAAgB,GACxB,UAAU,CAAC,OAAO,CAAC,CA6VrB;AAWD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,SAAS,QAAQ,GAAG,QAAQ,EACtE,OAAO,GAAE,WAAgB,GACxB,cAAc,CAAC,OAAO,CAAC,CA8RzB;AAMD,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC"}
@@ -7,8 +7,9 @@ import type { Transport, TransportEventHandler } from './types';
7
7
  export declare class DirectTransport implements Transport {
8
8
  private socket;
9
9
  constructor(socket: Socket);
10
- emit(event: string, ...args: any[]): void;
10
+ emit(event: string, ...args: unknown[]): void;
11
11
  on(event: string, handler: TransportEventHandler): void;
12
12
  off(event: string, handler?: TransportEventHandler): void;
13
+ destroy(): void;
13
14
  }
14
15
  //# sourceMappingURL=DirectTransport.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"DirectTransport.d.ts","sourceRoot":"","sources":["../../../src/transport/DirectTransport.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,KAAK,EAAE,SAAS,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAEhE,qBAAa,eAAgB,YAAW,SAAS;IACnC,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,MAAM;IAElC,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAIzC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,qBAAqB,GAAG,IAAI;IAIvD,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,IAAI;CAO1D"}
1
+ {"version":3,"file":"DirectTransport.d.ts","sourceRoot":"","sources":["../../../src/transport/DirectTransport.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,KAAK,EAAE,SAAS,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAEhE,qBAAa,eAAgB,YAAW,SAAS;IACnC,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,MAAM;IAElC,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAI7C,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,qBAAqB,GAAG,IAAI;IAIvD,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,IAAI;IAQzD,OAAO,IAAI,IAAI;CAGhB"}
@@ -1,9 +1,24 @@
1
1
  /**
2
2
  * PostMessageTransport - Transport over window.postMessage for iframe-hosted games.
3
3
  *
4
- * Used inside an iframe. Sends `smore:emit` to parent and listens for `smore:event` from parent.
4
+ * Used inside an iframe. Sends `_bridge:emit` to parent and listens for `_bridge:event` from parent.
5
5
  */
6
6
  import type { Transport, TransportEventHandler } from './types';
7
+ /**
8
+ * PostMessage-based transport for iframe-hosted games.
9
+ *
10
+ * Handles bi-directional communication between iframe game and parent platform using _bridge:* protocol.
11
+ * - Outbound: `_bridge:emit` messages sent to parent
12
+ * - Inbound: `_bridge:event` messages received from parent
13
+ * - Acknowledgment: `_bridge:ack` pattern for request-response flows
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * const transport = new PostMessageTransport('https://smore.gg');
18
+ * transport.on('game-start', (data) => console.log('Game started', data));
19
+ * transport.emit('player-ready', { playerIndex: 0 });
20
+ * ```
21
+ */
7
22
  export declare class PostMessageTransport implements Transport {
8
23
  private handlers;
9
24
  private ackCallbacks;
@@ -11,7 +26,7 @@ export declare class PostMessageTransport implements Transport {
11
26
  private parentOrigin;
12
27
  private boundMessageHandler;
13
28
  constructor(parentOrigin?: string);
14
- emit(event: string, ...args: any[]): void;
29
+ emit(event: string, ...args: unknown[]): void;
15
30
  on(event: string, handler: TransportEventHandler): void;
16
31
  off(event: string, handler?: TransportEventHandler): void;
17
32
  destroy(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"PostMessageTransport.d.ts","sourceRoot":"","sources":["../../../src/transport/PostMessageTransport.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAIhE,qBAAa,oBAAqB,YAAW,SAAS;IACpD,OAAO,CAAC,QAAQ,CAAiD;IACjE,OAAO,CAAC,YAAY,CAA+C;IACnE,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,mBAAmB,CAA4B;gBAE3C,YAAY,GAAE,MAAY;IAMtC,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAkBzC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,qBAAqB,GAAG,IAAI;IASvD,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,IAAI;IAQzD,OAAO,IAAI,IAAI;IAMf,OAAO,CAAC,aAAa;CAsBtB"}
1
+ {"version":3,"file":"PostMessageTransport.d.ts","sourceRoot":"","sources":["../../../src/transport/PostMessageTransport.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAIhE;;;;;;;;;;;;;;GAcG;AACH,qBAAa,oBAAqB,YAAW,SAAS;IACpD,OAAO,CAAC,QAAQ,CAAiD;IACjE,OAAO,CAAC,YAAY,CAAmD;IACvE,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,mBAAmB,CAA4B;gBAE3C,YAAY,GAAE,MAAY;IAMtC,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IA4B7C,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,qBAAqB,GAAG,IAAI;IASvD,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,IAAI;IAQzD,OAAO,IAAI,IAAI;IAMf,OAAO,CAAC,aAAa;CA6BtB"}
@@ -1,6 +1,6 @@
1
1
  export type { Transport, TransportEventHandler } from './types';
2
2
  export { DirectTransport } from './DirectTransport';
3
3
  export { PostMessageTransport } from './PostMessageTransport';
4
- export { isSmoreMessage } from './protocol';
5
- export type { SmoreMessage, SmoreReadyMessage, SmoreInitMessage, SmoreEmitMessage, SmoreEventMessage, SmoreAckMessage, SmoreUpdateMessage, } from './protocol';
4
+ export { isBridgeMessage } from './protocol';
5
+ export type { BridgeMessage, BridgeReadyMessage, BridgeInitMessage, BridgeEmitMessage, BridgeEventMessage, BridgeAckMessage, BridgeUpdateMessage, } from './protocol';
6
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/transport/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,SAAS,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,YAAY,EACV,YAAY,EACZ,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,kBAAkB,GACnB,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/transport/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,SAAS,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,YAAY,EACV,aAAa,EACb,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,YAAY,CAAC"}
@@ -1,50 +1,98 @@
1
1
  /**
2
2
  * postMessage protocol types for iframe ↔ parent communication.
3
+ *
4
+ * Uses `_bridge:` prefix to clearly distinguish from `smore:*` socket events.
5
+ * - `_bridge:*` = internal iframe postMessage protocol (never on socket)
6
+ * - `smore:*` = platform service events (socket-level, e.g. smore:player-joined)
3
7
  */
4
- export declare const SMORE_MSG_PREFIX: "smore:";
5
- export interface SmoreReadyMessage {
6
- type: 'smore:ready';
8
+ /**
9
+ * Cross-reference: `CharacterAppearance` (SDK type) has an identical shape to
10
+ * `CharacterDTO` (server type in game-project/types/src/types.ts).
11
+ * If either type changes, the other must be updated to stay in sync.
12
+ */
13
+ import type { CharacterAppearance } from '../types';
14
+ export declare const BRIDGE_MSG_PREFIX: "_bridge:";
15
+ export interface BridgeReadyMessage {
16
+ type: '_bridge:ready';
7
17
  }
8
- export interface SmoreInitMessage {
9
- type: 'smore:init';
18
+ /**
19
+ * BridgeInitMessage contains player data sent from the platform to the game iframe.
20
+ *
21
+ * **Field naming convention:**
22
+ * The server uses `name` and `character` fields (matching server/Player model naming).
23
+ * SDK code may reference fallback fields like `nickname` and `appearance` for defensive
24
+ * compatibility with potential future field name changes, but currently the server
25
+ * always sends `name` and `character`.
26
+ */
27
+ export interface BridgeInitMessage {
28
+ type: '_bridge:init';
10
29
  payload: {
11
30
  side: 'host' | 'player';
12
31
  roomCode: string;
13
- players: any[];
14
- leaderId: string | null;
32
+ players: Array<{
33
+ playerIndex: number;
34
+ name: string;
35
+ connected: boolean;
36
+ character: CharacterAppearance | null;
37
+ }>;
15
38
  myIndex?: number;
16
- isLeader?: boolean;
17
39
  };
18
40
  }
19
- export interface SmoreEmitMessage {
20
- type: 'smore:emit';
41
+ export interface BridgeEmitMessage {
42
+ type: '_bridge:emit';
21
43
  payload: {
22
44
  event: string;
23
- data?: any;
45
+ data?: unknown;
24
46
  ackId?: string;
25
47
  };
26
48
  }
27
- export interface SmoreEventMessage {
28
- type: 'smore:event';
49
+ export interface BridgeEventMessage {
50
+ type: '_bridge:event';
29
51
  payload: {
30
52
  event: string;
31
- data?: any;
53
+ data?: unknown;
32
54
  };
33
55
  }
34
- export interface SmoreAckMessage {
35
- type: 'smore:ack';
56
+ export interface BridgeAckMessage {
57
+ type: '_bridge:ack';
36
58
  payload: {
37
59
  ackId: string;
38
- data?: any;
60
+ data?: unknown;
39
61
  };
40
62
  }
41
- export interface SmoreUpdateMessage {
42
- type: 'smore:update';
63
+ export interface BridgeUpdateMessage {
64
+ type: '_bridge:update';
43
65
  payload: {
44
- players?: any[];
45
- leaderId?: string | null;
66
+ players?: Array<{
67
+ playerIndex: number;
68
+ name: string;
69
+ connected: boolean;
70
+ character: CharacterAppearance | null;
71
+ }>;
46
72
  };
47
73
  }
48
- export type SmoreMessage = SmoreReadyMessage | SmoreInitMessage | SmoreEmitMessage | SmoreEventMessage | SmoreAckMessage | SmoreUpdateMessage;
49
- export declare function isSmoreMessage(data: any): data is SmoreMessage;
74
+ export type BridgeMessage = BridgeReadyMessage | BridgeInitMessage | BridgeEmitMessage | BridgeEventMessage | BridgeAckMessage | BridgeUpdateMessage;
75
+ export declare function isBridgeMessage(data: unknown): data is BridgeMessage;
76
+ /**
77
+ * Validates the structure of a _bridge:init payload.
78
+ *
79
+ * Performs runtime validation to ensure the payload contains all required fields
80
+ * with correct types. This provides early error detection if the parent frame
81
+ * sends malformed initialization data.
82
+ *
83
+ * @param payload - The payload to validate
84
+ * @returns true if payload is valid
85
+ * @throws {Error} if validation fails with a descriptive error message
86
+ *
87
+ * @example
88
+ * ```ts
89
+ * try {
90
+ * validateInitPayload(msg.payload);
91
+ * // proceed with initialization
92
+ * } catch (err) {
93
+ * console.error('Invalid init payload:', err.message);
94
+ * }
95
+ * ```
96
+ */
97
+ export declare function validateInitPayload(payload: unknown): payload is BridgeInitMessage['payload'];
50
98
  //# sourceMappingURL=protocol.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../../src/transport/protocol.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,gBAAgB,EAAG,QAAiB,CAAC;AAElD,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,aAAa,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,YAAY,CAAC;IACnB,OAAO,EAAE;QACP,IAAI,EAAE,MAAM,GAAG,QAAQ,CAAC;QACxB,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,GAAG,EAAE,CAAC;QACf,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;KACpB,CAAC;CACH;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,YAAY,CAAC;IACnB,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,GAAG,CAAC;QACX,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,aAAa,CAAC;IACpB,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,GAAG,CAAC;KACZ,CAAC;CACH;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,GAAG,CAAC;KACZ,CAAC;CACH;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,cAAc,CAAC;IACrB,OAAO,EAAE;QACP,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC;QAChB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAC1B,CAAC;CACH;AAKD,MAAM,MAAM,YAAY,GACpB,iBAAiB,GACjB,gBAAgB,GAChB,gBAAgB,GAChB,iBAAiB,GACjB,eAAe,GACf,kBAAkB,CAAC;AAEvB,wBAAgB,cAAc,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI,IAAI,YAAY,CAE9D"}
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../../src/transport/protocol.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;GAIG;AACH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAEpD,eAAO,MAAM,iBAAiB,EAAG,UAAmB,CAAC;AAErD,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,eAAe,CAAC;CACvB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,cAAc,CAAC;IACrB,OAAO,EAAE;QAEP,IAAI,EAAE,MAAM,GAAG,QAAQ,CAAC;QACxB,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,KAAK,CAAC;YACb,WAAW,EAAE,MAAM,CAAC;YACpB,IAAI,EAAE,MAAM,CAAC;YACb,SAAS,EAAE,OAAO,CAAC;YACnB,SAAS,EAAE,mBAAmB,GAAG,IAAI,CAAC;SACvC,CAAC,CAAC;QACH,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,cAAc,CAAC;IACrB,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,OAAO,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,eAAe,CAAC;IACtB,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,OAAO,CAAC;KAChB,CAAC;CACH;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,aAAa,CAAC;IACpB,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,OAAO,CAAC;KAChB,CAAC;CACH;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,gBAAgB,CAAC;IACvB,OAAO,EAAE;QACP,OAAO,CAAC,EAAE,KAAK,CAAC;YACd,WAAW,EAAE,MAAM,CAAC;YACpB,IAAI,EAAE,MAAM,CAAC;YACb,SAAS,EAAE,OAAO,CAAC;YACnB,SAAS,EAAE,mBAAmB,GAAG,IAAI,CAAC;SACvC,CAAC,CAAC;KACJ,CAAC;CACH;AAED,MAAM,MAAM,aAAa,GACrB,kBAAkB,GAClB,iBAAiB,GACjB,iBAAiB,GACjB,kBAAkB,GAClB,gBAAgB,GAChB,mBAAmB,CAAC;AAExB,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,IAAI,aAAa,CAQpE;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,IAAI,iBAAiB,CAAC,SAAS,CAAC,CA4B7F"}
@@ -5,10 +5,32 @@
5
5
  * - DirectTransport: wraps a Socket.IO socket (bundled games)
6
6
  * - PostMessageTransport: wraps window.postMessage (iframe games)
7
7
  */
8
- export type TransportEventHandler = (...args: any[]) => void;
8
+ /**
9
+ * Event handler callback type for transport layer.
10
+ *
11
+ * Receives arbitrary arguments from the transport implementation.
12
+ */
13
+ export type TransportEventHandler = (...args: unknown[]) => void;
14
+ /**
15
+ * Abstract transport interface for SDK communication.
16
+ *
17
+ * Decouples SDK core from the underlying messaging protocol.
18
+ * Implementations provide concrete message passing:
19
+ * - PostMessageTransport: iframe-based games using window.postMessage
20
+ * - DirectTransport: bundled games using Socket.IO
21
+ *
22
+ * @example
23
+ * ```ts
24
+ * const transport = new PostMessageTransport('https://smore.gg');
25
+ * transport.on('event-name', (data) => console.log(data));
26
+ * transport.emit('other-event', { payload: 123 });
27
+ * ```
28
+ */
9
29
  export interface Transport {
10
- emit(event: string, ...args: any[]): void;
30
+ emit(event: string, ...args: unknown[]): void;
11
31
  on(event: string, handler: TransportEventHandler): void;
12
32
  off(event: string, handler?: TransportEventHandler): void;
33
+ /** Clean up resources (remove event listeners, clear internal state). */
34
+ destroy(): void;
13
35
  }
14
36
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/transport/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,MAAM,qBAAqB,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;AAE7D,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAC1C,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,qBAAqB,GAAG,IAAI,CAAC;IACxD,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,IAAI,CAAC;CAC3D"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/transport/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;GAIG;AACH,MAAM,MAAM,qBAAqB,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;AAEjE;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC9C,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,qBAAqB,GAAG,IAAI,CAAC;IACxD,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,IAAI,CAAC;IAC1D,yEAAyE;IACzE,OAAO,IAAI,IAAI,CAAC;CACjB"}