@smoregg/sdk 1.2.0 → 2.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 (179) hide show
  1. package/dist/cjs/config.cjs.map +1 -1
  2. package/dist/cjs/controller.cjs +215 -145
  3. package/dist/cjs/controller.cjs.map +1 -1
  4. package/dist/cjs/screen.cjs +220 -178
  5. package/dist/cjs/screen.cjs.map +1 -1
  6. package/dist/cjs/testing.cjs +160 -151
  7. package/dist/cjs/testing.cjs.map +1 -1
  8. package/dist/esm/config.js.map +1 -1
  9. package/dist/esm/controller.js +216 -146
  10. package/dist/esm/controller.js.map +1 -1
  11. package/dist/esm/screen.js +221 -179
  12. package/dist/esm/screen.js.map +1 -1
  13. package/dist/esm/testing.js +160 -151
  14. package/dist/esm/testing.js.map +1 -1
  15. package/dist/types/config.d.ts +1 -2
  16. package/dist/types/config.d.ts.map +1 -1
  17. package/dist/types/controller.d.ts +22 -43
  18. package/dist/types/controller.d.ts.map +1 -1
  19. package/dist/types/index.d.ts +14 -14
  20. package/dist/types/index.d.ts.map +1 -1
  21. package/dist/types/screen.d.ts +26 -37
  22. package/dist/types/screen.d.ts.map +1 -1
  23. package/dist/types/testing.d.ts +16 -0
  24. package/dist/types/testing.d.ts.map +1 -1
  25. package/dist/types/types.d.ts +244 -338
  26. package/dist/types/types.d.ts.map +1 -1
  27. package/dist/umd/smore-sdk.umd.js +595 -474
  28. package/dist/umd/smore-sdk.umd.js.map +1 -1
  29. package/dist/umd/smore-sdk.umd.min.js +1 -1
  30. package/dist/umd/smore-sdk.umd.min.js.map +1 -1
  31. package/package.json +1 -1
  32. package/dist/cjs/SmoreHost.cjs +0 -306
  33. package/dist/cjs/SmoreHost.cjs.map +0 -1
  34. package/dist/cjs/SmorePlayer.cjs +0 -229
  35. package/dist/cjs/SmorePlayer.cjs.map +0 -1
  36. package/dist/cjs/components/DirectionPad.cjs +0 -68
  37. package/dist/cjs/components/DirectionPad.cjs.map +0 -1
  38. package/dist/cjs/components/DirectionPad.module.css.cjs +0 -12
  39. package/dist/cjs/components/DirectionPad.module.css.cjs.map +0 -1
  40. package/dist/cjs/components/HoldButton.cjs +0 -57
  41. package/dist/cjs/components/HoldButton.cjs.map +0 -1
  42. package/dist/cjs/components/HoldButton.module.css.cjs +0 -12
  43. package/dist/cjs/components/HoldButton.module.css.cjs.map +0 -1
  44. package/dist/cjs/components/IframeGameBridge.cjs +0 -115
  45. package/dist/cjs/components/IframeGameBridge.cjs.map +0 -1
  46. package/dist/cjs/components/SwipeArea.cjs +0 -58
  47. package/dist/cjs/components/SwipeArea.cjs.map +0 -1
  48. package/dist/cjs/components/SwipeArea.module.css.cjs +0 -12
  49. package/dist/cjs/components/SwipeArea.module.css.cjs.map +0 -1
  50. package/dist/cjs/components/TapButton.cjs +0 -58
  51. package/dist/cjs/components/TapButton.cjs.map +0 -1
  52. package/dist/cjs/components/TapButton.module.css.cjs +0 -12
  53. package/dist/cjs/components/TapButton.module.css.cjs.map +0 -1
  54. package/dist/cjs/context/RoomProvider.cjs +0 -118
  55. package/dist/cjs/context/RoomProvider.cjs.map +0 -1
  56. package/dist/cjs/hooks/useExternalGames.cjs +0 -49
  57. package/dist/cjs/hooks/useExternalGames.cjs.map +0 -1
  58. package/dist/cjs/hooks/useGameHost.cjs +0 -206
  59. package/dist/cjs/hooks/useGameHost.cjs.map +0 -1
  60. package/dist/cjs/hooks/useGamePlayer.cjs +0 -134
  61. package/dist/cjs/hooks/useGamePlayer.cjs.map +0 -1
  62. package/dist/cjs/iframe/index.cjs +0 -260
  63. package/dist/cjs/iframe/index.cjs.map +0 -1
  64. package/dist/cjs/node_modules/.pnpm/style-inject@0.3.0/node_modules/style-inject/dist/style-inject.es.cjs +0 -33
  65. package/dist/cjs/node_modules/.pnpm/style-inject@0.3.0/node_modules/style-inject/dist/style-inject.es.cjs.map +0 -1
  66. package/dist/cjs/server/index.cjs +0 -45
  67. package/dist/cjs/server/index.cjs.map +0 -1
  68. package/dist/cjs/transport/DirectTransport.cjs +0 -23
  69. package/dist/cjs/transport/DirectTransport.cjs.map +0 -1
  70. package/dist/cjs/utils/connectionMonitor.cjs +0 -77
  71. package/dist/cjs/utils/connectionMonitor.cjs.map +0 -1
  72. package/dist/cjs/utils/preloadAssets.cjs +0 -66
  73. package/dist/cjs/utils/preloadAssets.cjs.map +0 -1
  74. package/dist/cjs/utils/serverTime.cjs +0 -43
  75. package/dist/cjs/utils/serverTime.cjs.map +0 -1
  76. package/dist/esm/SmoreHost.js +0 -304
  77. package/dist/esm/SmoreHost.js.map +0 -1
  78. package/dist/esm/SmorePlayer.js +0 -227
  79. package/dist/esm/SmorePlayer.js.map +0 -1
  80. package/dist/esm/components/DirectionPad.js +0 -66
  81. package/dist/esm/components/DirectionPad.js.map +0 -1
  82. package/dist/esm/components/DirectionPad.module.css.js +0 -8
  83. package/dist/esm/components/DirectionPad.module.css.js.map +0 -1
  84. package/dist/esm/components/HoldButton.js +0 -55
  85. package/dist/esm/components/HoldButton.js.map +0 -1
  86. package/dist/esm/components/HoldButton.module.css.js +0 -8
  87. package/dist/esm/components/HoldButton.module.css.js.map +0 -1
  88. package/dist/esm/components/IframeGameBridge.js +0 -113
  89. package/dist/esm/components/IframeGameBridge.js.map +0 -1
  90. package/dist/esm/components/SwipeArea.js +0 -56
  91. package/dist/esm/components/SwipeArea.js.map +0 -1
  92. package/dist/esm/components/SwipeArea.module.css.js +0 -8
  93. package/dist/esm/components/SwipeArea.module.css.js.map +0 -1
  94. package/dist/esm/components/TapButton.js +0 -56
  95. package/dist/esm/components/TapButton.js.map +0 -1
  96. package/dist/esm/components/TapButton.module.css.js +0 -8
  97. package/dist/esm/components/TapButton.module.css.js.map +0 -1
  98. package/dist/esm/context/RoomProvider.js +0 -109
  99. package/dist/esm/context/RoomProvider.js.map +0 -1
  100. package/dist/esm/hooks/useExternalGames.js +0 -47
  101. package/dist/esm/hooks/useExternalGames.js.map +0 -1
  102. package/dist/esm/hooks/useGameHost.js +0 -204
  103. package/dist/esm/hooks/useGameHost.js.map +0 -1
  104. package/dist/esm/hooks/useGamePlayer.js +0 -132
  105. package/dist/esm/hooks/useGamePlayer.js.map +0 -1
  106. package/dist/esm/iframe/index.js +0 -257
  107. package/dist/esm/iframe/index.js.map +0 -1
  108. package/dist/esm/node_modules/.pnpm/style-inject@0.3.0/node_modules/style-inject/dist/style-inject.es.js +0 -29
  109. package/dist/esm/node_modules/.pnpm/style-inject@0.3.0/node_modules/style-inject/dist/style-inject.es.js.map +0 -1
  110. package/dist/esm/server/index.js +0 -43
  111. package/dist/esm/server/index.js.map +0 -1
  112. package/dist/esm/transport/DirectTransport.js +0 -21
  113. package/dist/esm/transport/DirectTransport.js.map +0 -1
  114. package/dist/esm/utils/connectionMonitor.js +0 -75
  115. package/dist/esm/utils/connectionMonitor.js.map +0 -1
  116. package/dist/esm/utils/preloadAssets.js +0 -63
  117. package/dist/esm/utils/preloadAssets.js.map +0 -1
  118. package/dist/esm/utils/serverTime.js +0 -41
  119. package/dist/esm/utils/serverTime.js.map +0 -1
  120. package/dist/types/SmoreHost.d.ts +0 -187
  121. package/dist/types/SmoreHost.d.ts.map +0 -1
  122. package/dist/types/SmorePlayer.d.ts +0 -146
  123. package/dist/types/SmorePlayer.d.ts.map +0 -1
  124. package/dist/types/components/DirectionPad.d.ts +0 -21
  125. package/dist/types/components/DirectionPad.d.ts.map +0 -1
  126. package/dist/types/components/HoldButton.d.ts +0 -22
  127. package/dist/types/components/HoldButton.d.ts.map +0 -1
  128. package/dist/types/components/IframeGameBridge.d.ts +0 -38
  129. package/dist/types/components/IframeGameBridge.d.ts.map +0 -1
  130. package/dist/types/components/SwipeArea.d.ts +0 -19
  131. package/dist/types/components/SwipeArea.d.ts.map +0 -1
  132. package/dist/types/components/TapButton.d.ts +0 -19
  133. package/dist/types/components/TapButton.d.ts.map +0 -1
  134. package/dist/types/components/index.d.ts +0 -6
  135. package/dist/types/components/index.d.ts.map +0 -1
  136. package/dist/types/context/RoomProvider.d.ts +0 -69
  137. package/dist/types/context/RoomProvider.d.ts.map +0 -1
  138. package/dist/types/context/index.d.ts +0 -3
  139. package/dist/types/context/index.d.ts.map +0 -1
  140. package/dist/types/dev/DevSimulator.d.ts +0 -31
  141. package/dist/types/dev/DevSimulator.d.ts.map +0 -1
  142. package/dist/types/dev/index.d.ts +0 -2
  143. package/dist/types/dev/index.d.ts.map +0 -1
  144. package/dist/types/hooks/index.d.ts +0 -7
  145. package/dist/types/hooks/index.d.ts.map +0 -1
  146. package/dist/types/hooks/useExternalGames.d.ts +0 -32
  147. package/dist/types/hooks/useExternalGames.d.ts.map +0 -1
  148. package/dist/types/hooks/useGameHost.d.ts +0 -67
  149. package/dist/types/hooks/useGameHost.d.ts.map +0 -1
  150. package/dist/types/hooks/useGamePlayer.d.ts +0 -55
  151. package/dist/types/hooks/useGamePlayer.d.ts.map +0 -1
  152. package/dist/types/iframe/IframeRoomProvider.d.ts +0 -31
  153. package/dist/types/iframe/IframeRoomProvider.d.ts.map +0 -1
  154. package/dist/types/iframe/index.d.ts +0 -18
  155. package/dist/types/iframe/index.d.ts.map +0 -1
  156. package/dist/types/iframe/vanilla-entry.d.ts +0 -7
  157. package/dist/types/iframe/vanilla-entry.d.ts.map +0 -1
  158. package/dist/types/iframe/vanilla.d.ts +0 -49
  159. package/dist/types/iframe/vanilla.d.ts.map +0 -1
  160. package/dist/types/server/createGameRelay.d.ts +0 -26
  161. package/dist/types/server/createGameRelay.d.ts.map +0 -1
  162. package/dist/types/server/index.d.ts +0 -3
  163. package/dist/types/server/index.d.ts.map +0 -1
  164. package/dist/types/utils/connectionMonitor.d.ts +0 -57
  165. package/dist/types/utils/connectionMonitor.d.ts.map +0 -1
  166. package/dist/types/utils/index.d.ts +0 -7
  167. package/dist/types/utils/index.d.ts.map +0 -1
  168. package/dist/types/utils/preloadAssets.d.ts +0 -29
  169. package/dist/types/utils/preloadAssets.d.ts.map +0 -1
  170. package/dist/types/utils/serverTime.d.ts +0 -28
  171. package/dist/types/utils/serverTime.d.ts.map +0 -1
  172. package/dist/umd/smore-sdk-iframe.umd.js +0 -266
  173. package/dist/umd/smore-sdk-iframe.umd.js.map +0 -1
  174. package/dist/umd/smore-sdk-iframe.umd.min.js +0 -2
  175. package/dist/umd/smore-sdk-iframe.umd.min.js.map +0 -1
  176. package/dist/umd/smore-sdk-vanilla.umd.js +0 -1275
  177. package/dist/umd/smore-sdk-vanilla.umd.js.map +0 -1
  178. package/dist/umd/smore-sdk-vanilla.umd.min.js +0 -2
  179. package/dist/umd/smore-sdk-vanilla.umd.min.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"IframeRoomProvider.d.ts","sourceRoot":"","sources":["../../../src/iframe/IframeRoomProvider.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAuC,MAAM,OAAO,CAAC;AAS5D,UAAU,uBAAuB;IAC/B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,uBAAuB,CAkFhE,CAAC"}
@@ -1,18 +0,0 @@
1
- /**
2
- * @smoregg/sdk/iframe - Entry point for external iframe-hosted games.
3
- *
4
- * For Vanilla JS games:
5
- * ```ts
6
- * import { createHostBridge, createPlayerBridge } from '@smoregg/sdk/iframe';
7
- * ```
8
- *
9
- * For class-based API (recommended):
10
- * ```ts
11
- * import { SmoreHost, SmorePlayer } from '@smoregg/sdk';
12
- * ```
13
- */
14
- export { createHostBridge, createPlayerBridge } from './vanilla';
15
- export type { HostBridgeOptions, HostBridge, PlayerBridgeOptions, PlayerBridge } from './vanilla';
16
- export type { Transport } from '../transport/types';
17
- export type { Player } from '@smoregg/shared';
18
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/iframe/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AACjE,YAAY,EAAE,iBAAiB,EAAE,UAAU,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAGlG,YAAY,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,YAAY,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC"}
@@ -1,7 +0,0 @@
1
- /**
2
- * Vanilla JS entry point for UMD bundle.
3
- * No React dependency - only plain JS bridge functions.
4
- */
5
- export { createHostBridge, createPlayerBridge } from './vanilla';
6
- export type { HostBridgeOptions, HostBridge, PlayerBridgeOptions, PlayerBridge } from './vanilla';
7
- //# sourceMappingURL=vanilla-entry.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"vanilla-entry.d.ts","sourceRoot":"","sources":["../../../src/iframe/vanilla-entry.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AACjE,YAAY,EAAE,iBAAiB,EAAE,UAAU,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC"}
@@ -1,49 +0,0 @@
1
- /**
2
- * Vanilla JS bridge API for iframe-hosted games.
3
- * No React - pure JavaScript with PostMessage transport.
4
- */
5
- export interface HostBridgeOptions {
6
- parentOrigin?: string;
7
- gameId: string;
8
- listeners?: Record<string, (data: any) => void>;
9
- onPlayerJoin?: (playerIndex: number) => void;
10
- onPlayerLeave?: (playerIndex: number) => void;
11
- onReady?: (room: {
12
- roomCode: string;
13
- players: any[];
14
- leaderId: string | null;
15
- }) => void;
16
- /** Called when any device's custom state changes (AirConsole pattern) */
17
- onCustomStateChange?: (playerIndex: number, state: Record<string, any>) => void;
18
- }
19
- export interface HostBridge {
20
- broadcast: (event: string, data?: any) => void;
21
- sendToPlayer: (playerIndex: number, event: string, data?: any) => void;
22
- emitGameOver: (results: any) => void;
23
- setLoaded: () => void;
24
- /** Set custom device state (AirConsole pattern) - merges with existing state */
25
- setCustomState: (state: Record<string, any>) => void;
26
- destroy: () => void;
27
- }
28
- export interface PlayerBridgeOptions {
29
- parentOrigin?: string;
30
- gameId: string;
31
- listeners?: Record<string, (data: any) => void>;
32
- onReady?: (room: {
33
- roomCode: string;
34
- isLeader: boolean;
35
- myIndex: number;
36
- }) => void;
37
- /** Called when any device's custom state changes (AirConsole pattern) */
38
- onCustomStateChange?: (playerIndex: number, state: Record<string, any>) => void;
39
- }
40
- export interface PlayerBridge {
41
- emit: (event: string, data?: any) => void;
42
- onEvent: (event: string, handler: (data: any) => void) => () => void;
43
- /** Set custom device state (AirConsole pattern) - merges with existing state */
44
- setCustomState: (state: Record<string, any>) => void;
45
- destroy: () => void;
46
- }
47
- export declare function createHostBridge(options: HostBridgeOptions): HostBridge;
48
- export declare function createPlayerBridge(options: PlayerBridgeOptions): PlayerBridge;
49
- //# sourceMappingURL=vanilla.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"vanilla.d.ts","sourceRoot":"","sources":["../../../src/iframe/vanilla.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA0BH,MAAM,WAAW,iBAAiB;IAChC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,CAAC,CAAC;IAChD,YAAY,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,aAAa,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,GAAG,EAAE,CAAC;QAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,KAAK,IAAI,CAAC;IACxF,yEAAyE;IACzE,mBAAmB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,IAAI,CAAC;CACjF;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;IAC/C,YAAY,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;IACvE,YAAY,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,CAAC;IACrC,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,gFAAgF;IAChF,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,IAAI,CAAC;IACrD,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IAClC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,CAAC,CAAC;IAChD,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACnF,yEAAyE;IACzE,mBAAmB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,IAAI,CAAC;CACjF;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;IAC1C,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,KAAK,MAAM,IAAI,CAAC;IACrE,gFAAgF;IAChF,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,IAAI,CAAC;IACrD,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,iBAAiB,GAAG,UAAU,CAwHvE;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,mBAAmB,GAAG,YAAY,CAmG7E"}
@@ -1,26 +0,0 @@
1
- import type { Server, Socket } from 'socket.io';
2
- export interface RelayEvent {
3
- from: string;
4
- toHost?: string;
5
- withAck?: boolean;
6
- }
7
- export interface BroadcastEvent {
8
- from: string;
9
- toPlayers?: string;
10
- }
11
- export interface TargetedEvent {
12
- from: string;
13
- toPlayer?: string;
14
- }
15
- export interface CreateGameRelayConfig {
16
- gameId: string;
17
- playerToHost?: RelayEvent[];
18
- hostBroadcast?: BroadcastEvent[];
19
- hostToPlayer?: TargetedEvent[];
20
- }
21
- export type GameRelaySetup = (io: Server, socket: Socket & {
22
- sessionId?: string;
23
- roomCode?: string;
24
- }, getRoomHostSocketId: (roomCode: string) => string | null, getPlayerSocketId?: (sessionId: string) => string | null) => void;
25
- export declare function createGameRelay(config: CreateGameRelayConfig): GameRelaySetup;
26
- //# sourceMappingURL=createGameRelay.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"createGameRelay.d.ts","sourceRoot":"","sources":["../../../src/server/createGameRelay.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAEhD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,UAAU,EAAE,CAAC;IAC5B,aAAa,CAAC,EAAE,cAAc,EAAE,CAAC;IACjC,YAAY,CAAC,EAAE,aAAa,EAAE,CAAC;CAChC;AAED,MAAM,MAAM,cAAc,GAAG,CAC3B,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,EAC1D,mBAAmB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,EACxD,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,KACrD,IAAI,CAAC;AAEV,wBAAgB,eAAe,CAAC,MAAM,EAAE,qBAAqB,GAAG,cAAc,CA6C7E"}
@@ -1,3 +0,0 @@
1
- export { createGameRelay } from './createGameRelay';
2
- export type { CreateGameRelayConfig, GameRelaySetup, RelayEvent, BroadcastEvent, TargetedEvent, } from './createGameRelay';
3
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,YAAY,EACV,qBAAqB,EACrB,cAAc,EACd,UAAU,EACV,cAAc,EACd,aAAa,GACd,MAAM,mBAAmB,CAAC"}
@@ -1,57 +0,0 @@
1
- /**
2
- * Connection monitor for detecting unstable connections.
3
- * AirConsole pattern: onPause/onResume for connection issues.
4
- *
5
- * @example
6
- * ```typescript
7
- * const monitor = createConnectionMonitor(socket, {
8
- * onPause: () => {
9
- * pauseGame();
10
- * muteAudio();
11
- * },
12
- * onResume: () => {
13
- * resumeGame();
14
- * unmuteAudio();
15
- * },
16
- * onCountdown: (secondsLeft) => {
17
- * showCountdown(secondsLeft);
18
- * },
19
- * });
20
- *
21
- * // Later
22
- * monitor.destroy();
23
- * ```
24
- */
25
- import type { Socket } from 'socket.io-client';
26
- export interface ConnectionMonitorOptions {
27
- /** Called when connection becomes unstable or disconnects */
28
- onPause: () => void;
29
- /** Called after connection restores and countdown completes */
30
- onResume: () => void;
31
- /** Latency threshold to trigger pause (ms), default 2000 */
32
- latencyThreshold?: number;
33
- /** Resume countdown duration (ms), default 3000 */
34
- resumeCountdown?: number;
35
- /** Called during resume countdown with seconds remaining */
36
- onCountdown?: (secondsLeft: number) => void;
37
- }
38
- export interface ConnectionMonitor {
39
- /** Clean up listeners and intervals */
40
- destroy: () => void;
41
- /** Check if currently paused */
42
- isPaused: () => boolean;
43
- /** Get current latency (ms) */
44
- getLatency: () => number;
45
- }
46
- /**
47
- * Creates a connection monitor that detects network issues and triggers pause/resume.
48
- *
49
- * Monitors both:
50
- * - Socket.IO disconnect/reconnect events
51
- * - High latency via periodic ping
52
- *
53
- * When connection is lost or latency exceeds threshold, calls onPause().
54
- * When connection restores, starts countdown and calls onResume() after delay.
55
- */
56
- export declare function createConnectionMonitor(socket: Socket, options: ConnectionMonitorOptions): ConnectionMonitor;
57
- //# sourceMappingURL=connectionMonitor.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"connectionMonitor.d.ts","sourceRoot":"","sources":["../../../src/utils/connectionMonitor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE/C,MAAM,WAAW,wBAAwB;IACvC,6DAA6D;IAC7D,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,+DAA+D;IAC/D,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,4DAA4D;IAC5D,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mDAAmD;IACnD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,4DAA4D;IAC5D,WAAW,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7C;AAED,MAAM,WAAW,iBAAiB;IAChC,uCAAuC;IACvC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,gCAAgC;IAChC,QAAQ,EAAE,MAAM,OAAO,CAAC;IACxB,+BAA+B;IAC/B,UAAU,EAAE,MAAM,MAAM,CAAC;CAC1B;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,wBAAwB,GAChC,iBAAiB,CA2GnB"}
@@ -1,7 +0,0 @@
1
- export { preloadAssets, preloadImage } from './preloadAssets';
2
- export type { PreloadProgress, PreloadOptions } from './preloadAssets';
3
- export { createTimeSync } from './serverTime';
4
- export type { TimeSync } from './serverTime';
5
- export { createConnectionMonitor } from './connectionMonitor';
6
- export type { ConnectionMonitorOptions, ConnectionMonitor } from './connectionMonitor';
7
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC9D,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEvE,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,YAAY,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAE7C,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,YAAY,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC"}
@@ -1,29 +0,0 @@
1
- /**
2
- * Preload assets (images, audio, etc.) before game starts.
3
- * AirConsole best practice: load all resources before onReady.
4
- *
5
- * @example
6
- * ```typescript
7
- * await preloadAssets([
8
- * '/sprites/player.png',
9
- * '/audio/background.mp3',
10
- * ]);
11
- * bridge.setLoaded(); // Signal ready after preload
12
- * ```
13
- */
14
- export interface PreloadProgress {
15
- loaded: number;
16
- total: number;
17
- percent: number;
18
- currentUrl: string;
19
- }
20
- export interface PreloadOptions {
21
- onProgress?: (progress: PreloadProgress) => void;
22
- timeout?: number;
23
- }
24
- export declare function preloadAssets(urls: string[], options?: PreloadOptions): Promise<void>;
25
- /**
26
- * Preload a single image and return the Image element.
27
- */
28
- export declare function preloadImage(url: string): Promise<HTMLImageElement>;
29
- //# sourceMappingURL=preloadAssets.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"preloadAssets.d.ts","sourceRoot":"","sources":["../../../src/utils/preloadAssets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,eAAe,KAAK,IAAI,CAAC;IACjD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,CA2Df;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAOnE"}
@@ -1,28 +0,0 @@
1
- /**
2
- * Server time synchronization utility.
3
- * AirConsole pattern: getServerTime() for synchronized clocks.
4
- *
5
- * Used for quiz games (who pressed first), action games (latency compensation).
6
- *
7
- * @example
8
- * ```typescript
9
- * const timeSync = createTimeSync(socket);
10
- * await timeSync.sync(); // Initial sync
11
- *
12
- * const serverNow = timeSync.getServerTime();
13
- * socket.emit('answer', { timestamp: serverNow });
14
- * ```
15
- */
16
- import type { Socket } from 'socket.io-client';
17
- export interface TimeSync {
18
- /** Synchronize with server (call once at start) */
19
- sync: () => Promise<void>;
20
- /** Get current server time (after sync) */
21
- getServerTime: () => number;
22
- /** Get latency to server in ms */
23
- getLatency: () => number;
24
- /** Check if synchronized */
25
- isSynced: () => boolean;
26
- }
27
- export declare function createTimeSync(socket: Socket): TimeSync;
28
- //# sourceMappingURL=serverTime.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"serverTime.d.ts","sourceRoot":"","sources":["../../../src/utils/serverTime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE/C,MAAM,WAAW,QAAQ;IACvB,mDAAmD;IACnD,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,2CAA2C;IAC3C,aAAa,EAAE,MAAM,MAAM,CAAC;IAC5B,kCAAkC;IAClC,UAAU,EAAE,MAAM,MAAM,CAAC;IACzB,4BAA4B;IAC5B,QAAQ,EAAE,MAAM,OAAO,CAAC;CACzB;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAgDvD"}
@@ -1,266 +0,0 @@
1
- (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
3
- typeof define === 'function' && define.amd ? define(['exports'], factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.SmoreSDKIframe = {}));
5
- })(this, (function (exports) { 'use strict';
6
-
7
- const SMORE_MSG_PREFIX = "smore:";
8
- function isSmoreMessage(data) {
9
- return data && typeof data === "object" && typeof data.type === "string" && data.type.startsWith(SMORE_MSG_PREFIX);
10
- }
11
-
12
- class PostMessageTransport {
13
- handlers = /* @__PURE__ */ new Map();
14
- ackCallbacks = /* @__PURE__ */ new Map();
15
- ackCounter = 0;
16
- parentOrigin;
17
- boundMessageHandler;
18
- constructor(parentOrigin = "*") {
19
- this.parentOrigin = parentOrigin;
20
- this.boundMessageHandler = this.handleMessage.bind(this);
21
- window.addEventListener("message", this.boundMessageHandler);
22
- }
23
- emit(event, ...args) {
24
- let data = args[0];
25
- let ackId;
26
- if (args.length >= 2 && typeof args[args.length - 1] === "function") {
27
- data = args.length === 2 ? args[0] : args[0];
28
- const callback = args[args.length - 1];
29
- ackId = `ack_${++this.ackCounter}`;
30
- this.ackCallbacks.set(ackId, callback);
31
- }
32
- window.parent.postMessage(
33
- { type: "smore:emit", payload: { event, data, ackId } },
34
- this.parentOrigin
35
- );
36
- }
37
- on(event, handler) {
38
- let set = this.handlers.get(event);
39
- if (!set) {
40
- set = /* @__PURE__ */ new Set();
41
- this.handlers.set(event, set);
42
- }
43
- set.add(handler);
44
- }
45
- off(event, handler) {
46
- if (!handler) {
47
- this.handlers.delete(event);
48
- return;
49
- }
50
- this.handlers.get(event)?.delete(handler);
51
- }
52
- destroy() {
53
- window.removeEventListener("message", this.boundMessageHandler);
54
- this.handlers.clear();
55
- this.ackCallbacks.clear();
56
- }
57
- handleMessage(e) {
58
- if (this.parentOrigin !== "*" && e.origin !== this.parentOrigin) return;
59
- const msg = e.data;
60
- if (!isSmoreMessage(msg)) return;
61
- if (msg.type === "smore:event") {
62
- const { event, data } = msg.payload;
63
- const set = this.handlers.get(event);
64
- if (set) {
65
- set.forEach((handler) => handler(data));
66
- }
67
- } else if (msg.type === "smore:ack") {
68
- const { ackId, data } = msg.payload;
69
- const cb = this.ackCallbacks.get(ackId);
70
- if (cb) {
71
- this.ackCallbacks.delete(ackId);
72
- cb(data);
73
- }
74
- }
75
- }
76
- }
77
-
78
- const EVENT_NAME_REGEX = /^[a-zA-Z]([a-zA-Z_-]*[a-zA-Z])?$/;
79
- function validateEventName(event) {
80
- if (!EVENT_NAME_REGEX.test(event)) {
81
- console.error(
82
- `[SDK] Invalid event name "${event}". Event names must:
83
- - Only contain letters (a-z, A-Z), hyphens (-), and underscores (_)
84
- - Start and end with a letter (no leading/trailing - or _)`
85
- );
86
- return false;
87
- }
88
- return true;
89
- }
90
- function createHostBridge(options) {
91
- const { parentOrigin = "*", gameId, listeners, onPlayerJoin, onPlayerLeave, onReady, onCustomStateChange } = options;
92
- let transport = null;
93
- window.parent.postMessage({ type: "smore:ready" }, parentOrigin);
94
- const messageHandler = (e) => {
95
- if (parentOrigin !== "*" && e.origin !== parentOrigin) return;
96
- const msg = e.data;
97
- if (!isSmoreMessage(msg)) return;
98
- if (msg.type === "smore:init") {
99
- const { side, roomCode, players, leaderId } = msg.payload;
100
- if (side !== "host") {
101
- console.error("[HostBridge] Received init for wrong side:", side);
102
- return;
103
- }
104
- transport = new PostMessageTransport(parentOrigin);
105
- if (listeners) {
106
- Object.keys(listeners).forEach((event) => {
107
- validateEventName(event);
108
- const handler = listeners[event];
109
- transport.on(event, handler);
110
- });
111
- }
112
- if (onPlayerJoin) {
113
- transport.on("player:joined", (payload) => {
114
- const playerIndex = payload.player?.playerIndex ?? payload.playerIndex;
115
- if (playerIndex !== void 0) {
116
- onPlayerJoin(playerIndex);
117
- }
118
- });
119
- }
120
- if (onPlayerLeave) {
121
- transport.on("player:left", (payload) => {
122
- const playerIndex = payload.player?.playerIndex ?? payload.playerIndex;
123
- if (playerIndex !== void 0) {
124
- onPlayerLeave(playerIndex);
125
- }
126
- });
127
- }
128
- if (onCustomStateChange) {
129
- transport.on("smore:custom-state-change", (data) => {
130
- if (data.playerIndex !== void 0) {
131
- onCustomStateChange(data.playerIndex, data.state);
132
- }
133
- });
134
- }
135
- if (onReady) {
136
- onReady({ roomCode, players, leaderId });
137
- }
138
- }
139
- };
140
- window.addEventListener("message", messageHandler);
141
- return {
142
- broadcast: (event, data) => {
143
- if (!transport) {
144
- console.warn("[HostBridge] Cannot broadcast before init");
145
- return;
146
- }
147
- validateEventName(event);
148
- transport.emit(event, data);
149
- },
150
- sendToPlayer: (playerIndex, event, data) => {
151
- if (!transport) {
152
- console.warn("[HostBridge] Cannot sendToPlayer before init");
153
- return;
154
- }
155
- transport.emit(event, { targetPlayerIndex: playerIndex, ...data });
156
- },
157
- emitGameOver: (results) => {
158
- if (!transport) {
159
- console.warn("[HostBridge] Cannot emitGameOver before init");
160
- return;
161
- }
162
- transport.emit("game-over", results);
163
- },
164
- setLoaded: () => {
165
- window.parent.postMessage({ type: "smore:loaded" }, parentOrigin);
166
- },
167
- setCustomState: (state) => {
168
- if (!transport) {
169
- console.warn("[HostBridge] Cannot setCustomState before init");
170
- return;
171
- }
172
- window.parent.postMessage(
173
- { type: "smore:emit", payload: { event: "smore:custom-state-change", data: { state } } },
174
- parentOrigin
175
- );
176
- },
177
- destroy: () => {
178
- window.removeEventListener("message", messageHandler);
179
- transport?.destroy();
180
- transport = null;
181
- }
182
- };
183
- }
184
- function createPlayerBridge(options) {
185
- const { parentOrigin = "*", gameId, listeners, onReady, onCustomStateChange } = options;
186
- let transport = null;
187
- window.parent.postMessage({ type: "smore:ready" }, parentOrigin);
188
- const messageHandler = (e) => {
189
- if (parentOrigin !== "*" && e.origin !== parentOrigin) return;
190
- const msg = e.data;
191
- if (!isSmoreMessage(msg)) return;
192
- if (msg.type === "smore:init") {
193
- const { side, roomCode, myIndex, isLeader } = msg.payload;
194
- if (side !== "player") {
195
- console.error("[PlayerBridge] Received init for wrong side:", side);
196
- return;
197
- }
198
- if (myIndex === void 0) {
199
- console.error("[PlayerBridge] Missing myIndex in init payload");
200
- return;
201
- }
202
- transport = new PostMessageTransport(parentOrigin);
203
- if (listeners) {
204
- Object.keys(listeners).forEach((event) => {
205
- validateEventName(event);
206
- const handler = listeners[event];
207
- transport.on(event, handler);
208
- });
209
- }
210
- if (onCustomStateChange) {
211
- transport.on("smore:custom-state-change", (data) => {
212
- if (data.playerIndex !== void 0) {
213
- onCustomStateChange(data.playerIndex, data.state);
214
- }
215
- });
216
- }
217
- if (onReady) {
218
- onReady({ roomCode, isLeader: !!isLeader, myIndex });
219
- }
220
- }
221
- };
222
- window.addEventListener("message", messageHandler);
223
- return {
224
- emit: (event, data) => {
225
- if (!transport) {
226
- console.warn("[PlayerBridge] Cannot emit before init");
227
- return;
228
- }
229
- validateEventName(event);
230
- transport.emit(event, data);
231
- },
232
- onEvent: (event, handler) => {
233
- if (!transport) {
234
- console.warn("[PlayerBridge] Cannot onEvent before init");
235
- return () => {
236
- };
237
- }
238
- validateEventName(event);
239
- transport.on(event, handler);
240
- return () => {
241
- transport?.off(event, handler);
242
- };
243
- },
244
- setCustomState: (state) => {
245
- if (!transport) {
246
- console.warn("[PlayerBridge] Cannot setCustomState before init");
247
- return;
248
- }
249
- window.parent.postMessage(
250
- { type: "smore:emit", payload: { event: "smore:custom-state-change", data: { state } } },
251
- parentOrigin
252
- );
253
- },
254
- destroy: () => {
255
- window.removeEventListener("message", messageHandler);
256
- transport?.destroy();
257
- transport = null;
258
- }
259
- };
260
- }
261
-
262
- exports.createHostBridge = createHostBridge;
263
- exports.createPlayerBridge = createPlayerBridge;
264
-
265
- }));
266
- //# sourceMappingURL=smore-sdk-iframe.umd.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"smore-sdk-iframe.umd.js","sources":["../../src/transport/protocol.ts","../../src/transport/PostMessageTransport.ts","../../src/iframe/vanilla.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\nexport interface SmoreLoadedMessage {\n type: 'smore:loaded';\n}\n\nexport type SmoreMessage =\n | SmoreReadyMessage\n | SmoreInitMessage\n | SmoreEmitMessage\n | SmoreEventMessage\n | SmoreAckMessage\n | SmoreUpdateMessage\n | SmoreLoadedMessage;\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","/**\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","/**\n * Vanilla JS bridge API for iframe-hosted games.\n * No React - pure JavaScript with PostMessage transport.\n */\n\nimport { PostMessageTransport } from '../transport/PostMessageTransport';\nimport { isSmoreMessage, type SmoreInitMessage } from '../transport/protocol';\n\n/**\n * Validates event name format.\n * Rules:\n * - Only English letters (a-z, A-Z), hyphens (-), and underscores (_) allowed\n * - Must start and end with a letter (no leading/trailing - or _)\n * - Colons are reserved for system prefix\n */\nconst EVENT_NAME_REGEX = /^[a-zA-Z]([a-zA-Z_-]*[a-zA-Z])?$/;\n\nfunction validateEventName(event: string): boolean {\n if (!EVENT_NAME_REGEX.test(event)) {\n console.error(\n `[SDK] Invalid event name \"${event}\". Event names must:\\n` +\n ` - Only contain letters (a-z, A-Z), hyphens (-), and underscores (_)\\n` +\n ` - Start and end with a letter (no leading/trailing - or _)`\n );\n return false;\n }\n return true;\n}\n\nexport interface HostBridgeOptions {\n parentOrigin?: string;\n gameId: string;\n listeners?: Record<string, (data: any) => void>;\n onPlayerJoin?: (playerIndex: number) => void;\n onPlayerLeave?: (playerIndex: number) => void;\n onReady?: (room: { roomCode: string; players: any[]; leaderId: string | null }) => void;\n /** Called when any device's custom state changes (AirConsole pattern) */\n onCustomStateChange?: (playerIndex: number, state: Record<string, any>) => void;\n}\n\nexport interface HostBridge {\n broadcast: (event: string, data?: any) => void;\n sendToPlayer: (playerIndex: number, event: string, data?: any) => void;\n emitGameOver: (results: any) => void;\n setLoaded: () => void;\n /** Set custom device state (AirConsole pattern) - merges with existing state */\n setCustomState: (state: Record<string, any>) => void;\n destroy: () => void;\n}\n\nexport interface PlayerBridgeOptions {\n parentOrigin?: string;\n gameId: string;\n listeners?: Record<string, (data: any) => void>;\n onReady?: (room: { roomCode: string; isLeader: boolean; myIndex: number }) => void;\n /** Called when any device's custom state changes (AirConsole pattern) */\n onCustomStateChange?: (playerIndex: number, state: Record<string, any>) => void;\n}\n\nexport interface PlayerBridge {\n emit: (event: string, data?: any) => void;\n onEvent: (event: string, handler: (data: any) => void) => () => void;\n /** Set custom device state (AirConsole pattern) - merges with existing state */\n setCustomState: (state: Record<string, any>) => void;\n destroy: () => void;\n}\n\nexport function createHostBridge(options: HostBridgeOptions): HostBridge {\n const { parentOrigin = '*', gameId, listeners, onPlayerJoin, onPlayerLeave, onReady, onCustomStateChange } = options;\n\n let transport: PostMessageTransport | null = null;\n let isInitialized = false;\n\n // Immediately signal ready to parent\n window.parent.postMessage({ type: 'smore:ready' }, parentOrigin);\n\n const messageHandler = (e: MessageEvent) => {\n if (parentOrigin !== '*' && e.origin !== parentOrigin) return;\n const msg = e.data;\n if (!isSmoreMessage(msg)) return;\n\n if (msg.type === 'smore:init') {\n const { side, roomCode, players, leaderId } = (msg as SmoreInitMessage).payload;\n\n if (side !== 'host') {\n console.error('[HostBridge] Received init for wrong side:', side);\n return;\n }\n\n // Create transport and wire up event handlers\n transport = new PostMessageTransport(parentOrigin);\n\n // Handle input events\n if (listeners) {\n Object.keys(listeners).forEach((event) => {\n validateEventName(event);\n const handler = listeners[event];\n transport!.on(event, handler);\n });\n }\n\n // Handle player join/leave events\n if (onPlayerJoin) {\n transport.on('player:joined', (payload: any) => {\n const playerIndex = payload.player?.playerIndex ?? payload.playerIndex;\n if (playerIndex !== undefined) {\n onPlayerJoin(playerIndex);\n }\n });\n }\n if (onPlayerLeave) {\n transport.on('player:left', (payload: any) => {\n const playerIndex = payload.player?.playerIndex ?? payload.playerIndex;\n if (playerIndex !== undefined) {\n onPlayerLeave(playerIndex);\n }\n });\n }\n\n // Handle custom device state changes (AirConsole pattern)\n if (onCustomStateChange) {\n transport.on('smore:custom-state-change', (data: { playerIndex?: number; state: Record<string, any> }) => {\n if (data.playerIndex !== undefined) {\n onCustomStateChange(data.playerIndex, data.state);\n }\n });\n }\n\n isInitialized = true;\n\n // Call onReady callback\n if (onReady) {\n onReady({ roomCode, players, leaderId });\n }\n }\n };\n\n window.addEventListener('message', messageHandler);\n\n return {\n broadcast: (event: string, data?: any) => {\n if (!transport) {\n console.warn('[HostBridge] Cannot broadcast before init');\n return;\n }\n validateEventName(event);\n transport.emit(event, data);\n },\n\n sendToPlayer: (playerIndex: number, event: string, data?: any) => {\n if (!transport) {\n console.warn('[HostBridge] Cannot sendToPlayer before init');\n return;\n }\n transport.emit(event, { targetPlayerIndex: playerIndex, ...data });\n },\n\n emitGameOver: (results: any) => {\n if (!transport) {\n console.warn('[HostBridge] Cannot emitGameOver before init');\n return;\n }\n transport.emit('game-over', results);\n },\n\n setLoaded: () => {\n window.parent.postMessage({ type: 'smore:loaded' }, parentOrigin);\n },\n\n setCustomState: (state: Record<string, any>) => {\n if (!transport) {\n console.warn('[HostBridge] Cannot setCustomState before init');\n return;\n }\n window.parent.postMessage(\n { type: 'smore:emit', payload: { event: 'smore:custom-state-change', data: { state } } },\n parentOrigin\n );\n },\n\n destroy: () => {\n window.removeEventListener('message', messageHandler);\n transport?.destroy();\n transport = null;\n isInitialized = false;\n },\n };\n}\n\nexport function createPlayerBridge(options: PlayerBridgeOptions): PlayerBridge {\n const { parentOrigin = '*', gameId, listeners, onReady, onCustomStateChange } = options;\n\n let transport: PostMessageTransport | null = null;\n let isInitialized = false;\n\n // Immediately signal ready to parent\n window.parent.postMessage({ type: 'smore:ready' }, parentOrigin);\n\n const messageHandler = (e: MessageEvent) => {\n if (parentOrigin !== '*' && e.origin !== parentOrigin) return;\n const msg = e.data;\n if (!isSmoreMessage(msg)) return;\n\n if (msg.type === 'smore:init') {\n const { side, roomCode, myIndex, isLeader } = (msg as SmoreInitMessage).payload;\n\n if (side !== 'player') {\n console.error('[PlayerBridge] Received init for wrong side:', side);\n return;\n }\n\n if (myIndex === undefined) {\n console.error('[PlayerBridge] Missing myIndex in init payload');\n return;\n }\n\n // Create transport and wire up listeners\n transport = new PostMessageTransport(parentOrigin);\n\n // Wire up game-specific event listeners\n if (listeners) {\n Object.keys(listeners).forEach((event) => {\n validateEventName(event);\n const handler = listeners[event];\n transport!.on(event, handler);\n });\n }\n\n // Handle custom device state changes (AirConsole pattern)\n if (onCustomStateChange) {\n transport!.on('smore:custom-state-change', (data: { playerIndex?: number; state: Record<string, any> }) => {\n if (data.playerIndex !== undefined) {\n onCustomStateChange(data.playerIndex, data.state);\n }\n });\n }\n\n isInitialized = true;\n\n // Call onReady callback\n if (onReady) {\n onReady({ roomCode, isLeader: !!isLeader, myIndex });\n }\n }\n };\n\n window.addEventListener('message', messageHandler);\n\n return {\n emit: (event: string, data?: any) => {\n if (!transport) {\n console.warn('[PlayerBridge] Cannot emit before init');\n return;\n }\n validateEventName(event);\n transport.emit(event, data);\n },\n\n onEvent: (event: string, handler: (data: any) => void) => {\n if (!transport) {\n console.warn('[PlayerBridge] Cannot onEvent before init');\n return () => {};\n }\n validateEventName(event);\n transport.on(event, handler);\n return () => {\n transport?.off(event, handler);\n };\n },\n\n setCustomState: (state: Record<string, any>) => {\n if (!transport) {\n console.warn('[PlayerBridge] Cannot setCustomState before init');\n return;\n }\n window.parent.postMessage(\n { type: 'smore:emit', payload: { event: 'smore:custom-state-change', data: { state } } },\n parentOrigin\n );\n },\n\n destroy: () => {\n window.removeEventListener('message', messageHandler);\n transport?.destroy();\n transport = null;\n isInitialized = false;\n },\n };\n}\n"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).SmoreSDKIframe={})}(this,function(e){"use strict";function t(e){return e&&"object"==typeof e&&"string"==typeof e.type&&e.type.startsWith("smore:")}class n{handlers=new Map;ackCallbacks=new Map;ackCounter=0;parentOrigin;boundMessageHandler;constructor(e="*"){this.parentOrigin=e,this.boundMessageHandler=this.handleMessage.bind(this),window.addEventListener("message",this.boundMessageHandler)}emit(e,...t){let n,o=t[0];if(t.length>=2&&"function"==typeof t[t.length-1]){t.length,o=t[0];const e=t[t.length-1];n="ack_"+ ++this.ackCounter,this.ackCallbacks.set(n,e)}window.parent.postMessage({type:"smore:emit",payload:{event:e,data:o,ackId:n}},this.parentOrigin)}on(e,t){let n=this.handlers.get(e);n||(n=new Set,this.handlers.set(e,n)),n.add(t)}off(e,t){t?this.handlers.get(e)?.delete(t):this.handlers.delete(e)}destroy(){window.removeEventListener("message",this.boundMessageHandler),this.handlers.clear(),this.ackCallbacks.clear()}handleMessage(e){if("*"!==this.parentOrigin&&e.origin!==this.parentOrigin)return;const n=e.data;if(t(n))if("smore:event"===n.type){const{event:e,data:t}=n.payload,o=this.handlers.get(e);o&&o.forEach(e=>e(t))}else if("smore:ack"===n.type){const{ackId:e,data:t}=n.payload,o=this.ackCallbacks.get(e);o&&(this.ackCallbacks.delete(e),o(t))}}}const o=/^[a-zA-Z]([a-zA-Z_-]*[a-zA-Z])?$/;function a(e){return!!o.test(e)||(console.error(`[SDK] Invalid event name "${e}". Event names must:\n - Only contain letters (a-z, A-Z), hyphens (-), and underscores (_)\n - Start and end with a letter (no leading/trailing - or _)`),!1)}e.createHostBridge=function(e){const{parentOrigin:o="*",gameId:s,listeners:r,onPlayerJoin:i,onPlayerLeave:d,onReady:l,onCustomStateChange:c}=e;let y=null;window.parent.postMessage({type:"smore:ready"},o);const p=e=>{if("*"!==o&&e.origin!==o)return;const s=e.data;if(t(s)&&"smore:init"===s.type){const{side:e,roomCode:t,players:p,leaderId:g}=s.payload;if("host"!==e)return void console.error("[HostBridge] Received init for wrong side:",e);y=new n(o),r&&Object.keys(r).forEach(e=>{a(e);const t=r[e];y.on(e,t)}),i&&y.on("player:joined",e=>{const t=e.player?.playerIndex??e.playerIndex;void 0!==t&&i(t)}),d&&y.on("player:left",e=>{const t=e.player?.playerIndex??e.playerIndex;void 0!==t&&d(t)}),c&&y.on("smore:custom-state-change",e=>{void 0!==e.playerIndex&&c(e.playerIndex,e.state)}),l&&l({roomCode:t,players:p,leaderId:g})}};return window.addEventListener("message",p),{broadcast:(e,t)=>{y?(a(e),y.emit(e,t)):console.warn("[HostBridge] Cannot broadcast before init")},sendToPlayer:(e,t,n)=>{y?y.emit(t,{targetPlayerIndex:e,...n}):console.warn("[HostBridge] Cannot sendToPlayer before init")},emitGameOver:e=>{y?y.emit("game-over",e):console.warn("[HostBridge] Cannot emitGameOver before init")},setLoaded:()=>{window.parent.postMessage({type:"smore:loaded"},o)},setCustomState:e=>{y?window.parent.postMessage({type:"smore:emit",payload:{event:"smore:custom-state-change",data:{state:e}}},o):console.warn("[HostBridge] Cannot setCustomState before init")},destroy:()=>{window.removeEventListener("message",p),y?.destroy(),y=null}}},e.createPlayerBridge=function(e){const{parentOrigin:o="*",gameId:s,listeners:r,onReady:i,onCustomStateChange:d}=e;let l=null;window.parent.postMessage({type:"smore:ready"},o);const c=e=>{if("*"!==o&&e.origin!==o)return;const s=e.data;if(t(s)&&"smore:init"===s.type){const{side:e,roomCode:t,myIndex:c,isLeader:y}=s.payload;if("player"!==e)return void console.error("[PlayerBridge] Received init for wrong side:",e);if(void 0===c)return void console.error("[PlayerBridge] Missing myIndex in init payload");l=new n(o),r&&Object.keys(r).forEach(e=>{a(e);const t=r[e];l.on(e,t)}),d&&l.on("smore:custom-state-change",e=>{void 0!==e.playerIndex&&d(e.playerIndex,e.state)}),i&&i({roomCode:t,isLeader:!!y,myIndex:c})}};return window.addEventListener("message",c),{emit:(e,t)=>{l?(a(e),l.emit(e,t)):console.warn("[PlayerBridge] Cannot emit before init")},onEvent:(e,t)=>l?(a(e),l.on(e,t),()=>{l?.off(e,t)}):(console.warn("[PlayerBridge] Cannot onEvent before init"),()=>{}),setCustomState:e=>{l?window.parent.postMessage({type:"smore:emit",payload:{event:"smore:custom-state-change",data:{state:e}}},o):console.warn("[PlayerBridge] Cannot setCustomState before init")},destroy:()=>{window.removeEventListener("message",c),l?.destroy(),l=null}}}});
2
- //# sourceMappingURL=smore-sdk-iframe.umd.min.js.map