@remember-web/sse 0.1.0-alpha.1

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 (160) hide show
  1. package/README.md +238 -0
  2. package/dist/src/core/BaseSseClient.cjs.js +97 -0
  3. package/dist/src/core/BaseSseClient.cjs.js.map +1 -0
  4. package/dist/src/core/BaseSseClient.d.ts +33 -0
  5. package/dist/src/core/BaseSseClient.d.ts.map +1 -0
  6. package/dist/src/core/BaseSseClient.esm.js +89 -0
  7. package/dist/src/core/BaseSseClient.esm.js.map +1 -0
  8. package/dist/src/core/SseClient.cjs.js +382 -0
  9. package/dist/src/core/SseClient.cjs.js.map +1 -0
  10. package/dist/src/core/SseClient.d.ts +24 -0
  11. package/dist/src/core/SseClient.d.ts.map +1 -0
  12. package/dist/src/core/SseClient.esm.js +370 -0
  13. package/dist/src/core/SseClient.esm.js.map +1 -0
  14. package/dist/src/core/backoff.cjs.js +30 -0
  15. package/dist/src/core/backoff.cjs.js.map +1 -0
  16. package/dist/src/core/backoff.d.ts +12 -0
  17. package/dist/src/core/backoff.d.ts.map +1 -0
  18. package/dist/src/core/backoff.esm.js +28 -0
  19. package/dist/src/core/backoff.esm.js.map +1 -0
  20. package/dist/src/core/emitter.cjs.js +57 -0
  21. package/dist/src/core/emitter.cjs.js.map +1 -0
  22. package/dist/src/core/emitter.d.ts +14 -0
  23. package/dist/src/core/emitter.d.ts.map +1 -0
  24. package/dist/src/core/emitter.esm.js +51 -0
  25. package/dist/src/core/emitter.esm.js.map +1 -0
  26. package/dist/src/core/eventNames.cjs.js +64 -0
  27. package/dist/src/core/eventNames.cjs.js.map +1 -0
  28. package/dist/src/core/eventNames.d.ts +31 -0
  29. package/dist/src/core/eventNames.d.ts.map +1 -0
  30. package/dist/src/core/eventNames.esm.js +54 -0
  31. package/dist/src/core/eventNames.esm.js.map +1 -0
  32. package/dist/src/core/retryWait.cjs.js +20 -0
  33. package/dist/src/core/retryWait.cjs.js.map +1 -0
  34. package/dist/src/core/retryWait.d.ts +6 -0
  35. package/dist/src/core/retryWait.d.ts.map +1 -0
  36. package/dist/src/core/retryWait.esm.js +18 -0
  37. package/dist/src/core/retryWait.esm.js.map +1 -0
  38. package/dist/src/core/statusMachine.cjs.js +56 -0
  39. package/dist/src/core/statusMachine.cjs.js.map +1 -0
  40. package/dist/src/core/statusMachine.d.ts +9 -0
  41. package/dist/src/core/statusMachine.d.ts.map +1 -0
  42. package/dist/src/core/statusMachine.esm.js +54 -0
  43. package/dist/src/core/statusMachine.esm.js.map +1 -0
  44. package/dist/src/core/stream.cjs.js +136 -0
  45. package/dist/src/core/stream.cjs.js.map +1 -0
  46. package/dist/src/core/stream.d.ts +42 -0
  47. package/dist/src/core/stream.d.ts.map +1 -0
  48. package/dist/src/core/stream.esm.js +128 -0
  49. package/dist/src/core/stream.esm.js.map +1 -0
  50. package/dist/src/core/ticket.cjs.js +237 -0
  51. package/dist/src/core/ticket.cjs.js.map +1 -0
  52. package/dist/src/core/ticket.d.ts +31 -0
  53. package/dist/src/core/ticket.d.ts.map +1 -0
  54. package/dist/src/core/ticket.esm.js +220 -0
  55. package/dist/src/core/ticket.esm.js.map +1 -0
  56. package/dist/src/core/types.cjs.js +54 -0
  57. package/dist/src/core/types.cjs.js.map +1 -0
  58. package/dist/src/core/types.d.ts +131 -0
  59. package/dist/src/core/types.d.ts.map +1 -0
  60. package/dist/src/core/types.esm.js +50 -0
  61. package/dist/src/core/types.esm.js.map +1 -0
  62. package/dist/src/core/wire.cjs.js +29 -0
  63. package/dist/src/core/wire.cjs.js.map +1 -0
  64. package/dist/src/core/wire.d.ts +7 -0
  65. package/dist/src/core/wire.d.ts.map +1 -0
  66. package/dist/src/core/wire.esm.js +23 -0
  67. package/dist/src/core/wire.esm.js.map +1 -0
  68. package/dist/src/createSseClient.cjs.js +30 -0
  69. package/dist/src/createSseClient.cjs.js.map +1 -0
  70. package/dist/src/createSseClient.d.ts +8 -0
  71. package/dist/src/createSseClient.d.ts.map +1 -0
  72. package/dist/src/createSseClient.esm.js +28 -0
  73. package/dist/src/createSseClient.esm.js.map +1 -0
  74. package/dist/src/index.cjs.js +10 -0
  75. package/dist/src/index.cjs.js.map +1 -0
  76. package/dist/src/index.d.ts +6 -0
  77. package/dist/src/index.d.ts.map +1 -0
  78. package/dist/src/index.esm.js +3 -0
  79. package/dist/src/index.esm.js.map +1 -0
  80. package/dist/src/react/createSseContext.cjs.js +130 -0
  81. package/dist/src/react/createSseContext.cjs.js.map +1 -0
  82. package/dist/src/react/createSseContext.d.ts +32 -0
  83. package/dist/src/react/createSseContext.d.ts.map +1 -0
  84. package/dist/src/react/createSseContext.esm.js +122 -0
  85. package/dist/src/react/createSseContext.esm.js.map +1 -0
  86. package/dist/src/react/index.cjs.js +8 -0
  87. package/dist/src/react/index.cjs.js.map +1 -0
  88. package/dist/src/react/index.d.ts +3 -0
  89. package/dist/src/react/index.d.ts.map +1 -0
  90. package/dist/src/react/index.esm.js +2 -0
  91. package/dist/src/react/index.esm.js.map +1 -0
  92. package/dist/src/testing/doubles.d.ts +50 -0
  93. package/dist/src/testing/doubles.d.ts.map +1 -0
  94. package/dist/src/testing/harness.d.ts +43 -0
  95. package/dist/src/testing/harness.d.ts.map +1 -0
  96. package/dist/src/testing/index.d.ts +3 -0
  97. package/dist/src/testing/index.d.ts.map +1 -0
  98. package/dist/src/worker/WorkerSseClient.cjs.js +240 -0
  99. package/dist/src/worker/WorkerSseClient.cjs.js.map +1 -0
  100. package/dist/src/worker/WorkerSseClient.d.ts +23 -0
  101. package/dist/src/worker/WorkerSseClient.d.ts.map +1 -0
  102. package/dist/src/worker/WorkerSseClient.esm.js +228 -0
  103. package/dist/src/worker/WorkerSseClient.esm.js.map +1 -0
  104. package/dist/src/worker/hub.d.ts +19 -0
  105. package/dist/src/worker/hub.d.ts.map +1 -0
  106. package/dist/src/worker/portRegistry.d.ts +41 -0
  107. package/dist/src/worker/portRegistry.d.ts.map +1 -0
  108. package/dist/src/worker/protocol.d.ts +63 -0
  109. package/dist/src/worker/protocol.d.ts.map +1 -0
  110. package/dist/src/worker/sse.worker.d.ts +2 -0
  111. package/dist/src/worker/sse.worker.d.ts.map +1 -0
  112. package/dist/src/worker/ticketDelegate.d.ts +16 -0
  113. package/dist/src/worker/ticketDelegate.d.ts.map +1 -0
  114. package/dist/src/worker/workerConnection.d.ts +28 -0
  115. package/dist/src/worker/workerConnection.d.ts.map +1 -0
  116. package/dist/worker/sse.worker.js +1865 -0
  117. package/dist/worker/sse.worker.js.map +1 -0
  118. package/package.json +87 -0
  119. package/src/core/BaseSseClient.test.ts +142 -0
  120. package/src/core/BaseSseClient.ts +103 -0
  121. package/src/core/SseClient.connection.test.ts +863 -0
  122. package/src/core/SseClient.scenarios.test.ts +164 -0
  123. package/src/core/SseClient.test.ts +63 -0
  124. package/src/core/SseClient.ts +310 -0
  125. package/src/core/backoff.test.ts +43 -0
  126. package/src/core/backoff.ts +39 -0
  127. package/src/core/emitter.ts +56 -0
  128. package/src/core/eventNames.ts +53 -0
  129. package/src/core/retryWait.ts +18 -0
  130. package/src/core/statusMachine.ts +56 -0
  131. package/src/core/stream.ts +141 -0
  132. package/src/core/ticket.ts +146 -0
  133. package/src/core/types.ts +182 -0
  134. package/src/core/wire.ts +23 -0
  135. package/src/createSseClient.test.ts +82 -0
  136. package/src/createSseClient.ts +34 -0
  137. package/src/index.ts +21 -0
  138. package/src/react/SseProvider.test.tsx +129 -0
  139. package/src/react/createSseContext.test.ts +47 -0
  140. package/src/react/createSseContext.tsx +140 -0
  141. package/src/react/index.ts +2 -0
  142. package/src/react/useSseEvent.test.tsx +71 -0
  143. package/src/react/useSseStatus.test.tsx +40 -0
  144. package/src/testing/doubles.ts +128 -0
  145. package/src/testing/harness.ts +82 -0
  146. package/src/testing/index.ts +3 -0
  147. package/src/worker/SseClientLike.contract.test.ts +270 -0
  148. package/src/worker/WorkerSseClient.scenarios.test.ts +179 -0
  149. package/src/worker/WorkerSseClient.test.ts +377 -0
  150. package/src/worker/WorkerSseClient.ts +190 -0
  151. package/src/worker/hub.connection.test.ts +1023 -0
  152. package/src/worker/hub.test.ts +213 -0
  153. package/src/worker/hub.ts +120 -0
  154. package/src/worker/portRegistry.test.ts +59 -0
  155. package/src/worker/portRegistry.ts +86 -0
  156. package/src/worker/protocol.ts +80 -0
  157. package/src/worker/sse.worker.ts +19 -0
  158. package/src/worker/ticketDelegate.test.ts +99 -0
  159. package/src/worker/ticketDelegate.ts +80 -0
  160. package/src/worker/workerConnection.ts +134 -0
@@ -0,0 +1,30 @@
1
+ 'use strict';
2
+
3
+ var SseClient = require('./core/SseClient.cjs.js');
4
+ var WorkerSseClient = require('./worker/WorkerSseClient.cjs.js');
5
+
6
+ /**
7
+ * @description 환경에 맞는 SseClientLike 구현을 선택합니다 — sharedWorker 팩토리를 제공하면
8
+ * 탭 간 연결 공유(WorkerSseClient), 미제공이거나 브라우저가 SharedWorker를 지원하지 않으면
9
+ * 탭별 직접 연결(SseClient)입니다. 생성 시점에는 능력 검사만 하므로 SSR·워커 스코프에서도 안전합니다.
10
+ */
11
+ var createSseClient = function createSseClient(options) {
12
+ if (options.sharedWorker !== undefined) {
13
+ if (options.eventSource !== undefined) {
14
+ var _options$logger;
15
+ (_options$logger = options.logger) === null || _options$logger === void 0 || _options$logger.warn('sse: 워커 경로에서는 eventSource 주입이 적용되지 않습니다 — 스트림은 워커 스코프에서 만들어집니다');
16
+ }
17
+ if (typeof SharedWorker !== 'undefined') {
18
+ return new WorkerSseClient.WorkerSseClient(options);
19
+ }
20
+ // document는 브라우저 메인 스레드에만 있습니다 — SSR·워커 스코프의 무의미한 경고를 함께 거릅니다
21
+ if (typeof document !== 'undefined') {
22
+ var _options$logger2;
23
+ (_options$logger2 = options.logger) === null || _options$logger2 === void 0 || _options$logger2.warn('sse: 이 브라우저는 SharedWorker를 지원하지 않습니다 — 탭별 직접 연결로 대체합니다');
24
+ }
25
+ }
26
+ return new SseClient.SseClient(options);
27
+ };
28
+
29
+ exports.createSseClient = createSseClient;
30
+ //# sourceMappingURL=createSseClient.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createSseClient.cjs.js","sources":["../../src/createSseClient.ts"],"sourcesContent":["import { SseClient } from './core/SseClient';\nimport type {\n SseClientLike,\n SseClientOptions,\n SseEventMap,\n} from './core/types';\nimport { WorkerSseClient } from './worker/WorkerSseClient';\n\n/**\n * @description 환경에 맞는 SseClientLike 구현을 선택합니다 — sharedWorker 팩토리를 제공하면\n * 탭 간 연결 공유(WorkerSseClient), 미제공이거나 브라우저가 SharedWorker를 지원하지 않으면\n * 탭별 직접 연결(SseClient)입니다. 생성 시점에는 능력 검사만 하므로 SSR·워커 스코프에서도 안전합니다.\n */\nexport const createSseClient = <M extends object = SseEventMap>(\n options: SseClientOptions\n): SseClientLike<M> => {\n if (options.sharedWorker !== undefined) {\n if (options.eventSource !== undefined) {\n options.logger?.warn(\n 'sse: 워커 경로에서는 eventSource 주입이 적용되지 않습니다 — 스트림은 워커 스코프에서 만들어집니다'\n );\n }\n if (typeof SharedWorker !== 'undefined') {\n return new WorkerSseClient<M>(options);\n }\n // document는 브라우저 메인 스레드에만 있습니다 — SSR·워커 스코프의 무의미한 경고를 함께 거릅니다\n if (typeof document !== 'undefined') {\n options.logger?.warn(\n 'sse: 이 브라우저는 SharedWorker를 지원하지 않습니다 — 탭별 직접 연결로 대체합니다'\n );\n }\n }\n return new SseClient<M>(options);\n};\n"],"names":["createSseClient","options","sharedWorker","undefined","eventSource","_options$logger","logger","warn","SharedWorker","WorkerSseClient","document","_options$logger2","SseClient"],"mappings":";;;;;AAQA;AACA;AACA;AACA;AACA;IACaA,eAAe,GAAG,SAAlBA,eAAeA,CAC1BC,OAAyB,EACJ;AACrB,EAAA,IAAIA,OAAO,CAACC,YAAY,KAAKC,SAAS,EAAE;AACtC,IAAA,IAAIF,OAAO,CAACG,WAAW,KAAKD,SAAS,EAAE;AAAA,MAAA,IAAAE,eAAA;AACrC,MAAA,CAAAA,eAAA,GAAAJ,OAAO,CAACK,MAAM,MAAA,IAAA,IAAAD,eAAA,KAAA,MAAA,IAAdA,eAAA,CAAgBE,IAAI,CAClB,gEACF,CAAC;AACH;AACA,IAAA,IAAI,OAAOC,YAAY,KAAK,WAAW,EAAE;AACvC,MAAA,OAAO,IAAIC,+BAAe,CAAIR,OAAO,CAAC;AACxC;AACA;AACA,IAAA,IAAI,OAAOS,QAAQ,KAAK,WAAW,EAAE;AAAA,MAAA,IAAAC,gBAAA;AACnC,MAAA,CAAAA,gBAAA,GAAAV,OAAO,CAACK,MAAM,MAAA,IAAA,IAAAK,gBAAA,KAAA,MAAA,IAAdA,gBAAA,CAAgBJ,IAAI,CAClB,wDACF,CAAC;AACH;AACF;AACA,EAAA,OAAO,IAAIK,mBAAS,CAAIX,OAAO,CAAC;AAClC;;;;"}
@@ -0,0 +1,8 @@
1
+ import type { SseClientLike, SseClientOptions, SseEventMap } from './core/types';
2
+ /**
3
+ * @description 환경에 맞는 SseClientLike 구현을 선택합니다 — sharedWorker 팩토리를 제공하면
4
+ * 탭 간 연결 공유(WorkerSseClient), 미제공이거나 브라우저가 SharedWorker를 지원하지 않으면
5
+ * 탭별 직접 연결(SseClient)입니다. 생성 시점에는 능력 검사만 하므로 SSR·워커 스코프에서도 안전합니다.
6
+ */
7
+ export declare const createSseClient: <M extends object = SseEventMap>(options: SseClientOptions) => SseClientLike<M>;
8
+ //# sourceMappingURL=createSseClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createSseClient.d.ts","sourceRoot":"","sources":["../../src/createSseClient.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,aAAa,EACb,gBAAgB,EAChB,WAAW,EACZ,MAAM,cAAc,CAAC;AAGtB;;;;GAIG;AACH,eAAO,MAAM,eAAe,4CACjB,gBAAgB,KACxB,cAAc,CAAC,CAkBjB,CAAC"}
@@ -0,0 +1,28 @@
1
+ import { SseClient } from './core/SseClient.esm.js';
2
+ import { WorkerSseClient } from './worker/WorkerSseClient.esm.js';
3
+
4
+ /**
5
+ * @description 환경에 맞는 SseClientLike 구현을 선택합니다 — sharedWorker 팩토리를 제공하면
6
+ * 탭 간 연결 공유(WorkerSseClient), 미제공이거나 브라우저가 SharedWorker를 지원하지 않으면
7
+ * 탭별 직접 연결(SseClient)입니다. 생성 시점에는 능력 검사만 하므로 SSR·워커 스코프에서도 안전합니다.
8
+ */
9
+ var createSseClient = function createSseClient(options) {
10
+ if (options.sharedWorker !== undefined) {
11
+ if (options.eventSource !== undefined) {
12
+ var _options$logger;
13
+ (_options$logger = options.logger) === null || _options$logger === void 0 || _options$logger.warn('sse: 워커 경로에서는 eventSource 주입이 적용되지 않습니다 — 스트림은 워커 스코프에서 만들어집니다');
14
+ }
15
+ if (typeof SharedWorker !== 'undefined') {
16
+ return new WorkerSseClient(options);
17
+ }
18
+ // document는 브라우저 메인 스레드에만 있습니다 — SSR·워커 스코프의 무의미한 경고를 함께 거릅니다
19
+ if (typeof document !== 'undefined') {
20
+ var _options$logger2;
21
+ (_options$logger2 = options.logger) === null || _options$logger2 === void 0 || _options$logger2.warn('sse: 이 브라우저는 SharedWorker를 지원하지 않습니다 — 탭별 직접 연결로 대체합니다');
22
+ }
23
+ }
24
+ return new SseClient(options);
25
+ };
26
+
27
+ export { createSseClient };
28
+ //# sourceMappingURL=createSseClient.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createSseClient.esm.js","sources":["../../src/createSseClient.ts"],"sourcesContent":["import { SseClient } from './core/SseClient';\nimport type {\n SseClientLike,\n SseClientOptions,\n SseEventMap,\n} from './core/types';\nimport { WorkerSseClient } from './worker/WorkerSseClient';\n\n/**\n * @description 환경에 맞는 SseClientLike 구현을 선택합니다 — sharedWorker 팩토리를 제공하면\n * 탭 간 연결 공유(WorkerSseClient), 미제공이거나 브라우저가 SharedWorker를 지원하지 않으면\n * 탭별 직접 연결(SseClient)입니다. 생성 시점에는 능력 검사만 하므로 SSR·워커 스코프에서도 안전합니다.\n */\nexport const createSseClient = <M extends object = SseEventMap>(\n options: SseClientOptions\n): SseClientLike<M> => {\n if (options.sharedWorker !== undefined) {\n if (options.eventSource !== undefined) {\n options.logger?.warn(\n 'sse: 워커 경로에서는 eventSource 주입이 적용되지 않습니다 — 스트림은 워커 스코프에서 만들어집니다'\n );\n }\n if (typeof SharedWorker !== 'undefined') {\n return new WorkerSseClient<M>(options);\n }\n // document는 브라우저 메인 스레드에만 있습니다 — SSR·워커 스코프의 무의미한 경고를 함께 거릅니다\n if (typeof document !== 'undefined') {\n options.logger?.warn(\n 'sse: 이 브라우저는 SharedWorker를 지원하지 않습니다 — 탭별 직접 연결로 대체합니다'\n );\n }\n }\n return new SseClient<M>(options);\n};\n"],"names":["createSseClient","options","sharedWorker","undefined","eventSource","_options$logger","logger","warn","SharedWorker","WorkerSseClient","document","_options$logger2","SseClient"],"mappings":";;;AAQA;AACA;AACA;AACA;AACA;IACaA,eAAe,GAAG,SAAlBA,eAAeA,CAC1BC,OAAyB,EACJ;AACrB,EAAA,IAAIA,OAAO,CAACC,YAAY,KAAKC,SAAS,EAAE;AACtC,IAAA,IAAIF,OAAO,CAACG,WAAW,KAAKD,SAAS,EAAE;AAAA,MAAA,IAAAE,eAAA;AACrC,MAAA,CAAAA,eAAA,GAAAJ,OAAO,CAACK,MAAM,MAAA,IAAA,IAAAD,eAAA,KAAA,MAAA,IAAdA,eAAA,CAAgBE,IAAI,CAClB,gEACF,CAAC;AACH;AACA,IAAA,IAAI,OAAOC,YAAY,KAAK,WAAW,EAAE;AACvC,MAAA,OAAO,IAAIC,eAAe,CAAIR,OAAO,CAAC;AACxC;AACA;AACA,IAAA,IAAI,OAAOS,QAAQ,KAAK,WAAW,EAAE;AAAA,MAAA,IAAAC,gBAAA;AACnC,MAAA,CAAAA,gBAAA,GAAAV,OAAO,CAACK,MAAM,MAAA,IAAA,IAAAK,gBAAA,KAAA,MAAA,IAAdA,gBAAA,CAAgBJ,IAAI,CAClB,wDACF,CAAC;AACH;AACF;AACA,EAAA,OAAO,IAAIK,SAAS,CAAIX,OAAO,CAAC;AAClC;;;;"}
@@ -0,0 +1,10 @@
1
+ 'use strict';
2
+
3
+ var createSseClient = require('./createSseClient.cjs.js');
4
+ var wire = require('./core/wire.cjs.js');
5
+
6
+
7
+
8
+ exports.createSseClient = createSseClient.createSseClient;
9
+ exports.wire = wire.wire;
10
+ //# sourceMappingURL=index.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
@@ -0,0 +1,6 @@
1
+ export { createSseClient } from './createSseClient';
2
+ export type { BackoffOptions } from './core/backoff';
3
+ export { wire } from './core/wire';
4
+ export type { WireHandlers } from './core/wire';
5
+ export type { FatalCause, FatalPayload, GoawayAction, GoawayPayload, GoawayReason, PayloadOf, SseClientLike, SseClientOptions, SseEventHandler, SseEventMap, SseEventName, SseLogger, SseStatus, Unsubscribe, } from './core/types';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACnC,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,YAAY,EACV,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,SAAS,EACT,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,WAAW,EACX,YAAY,EACZ,SAAS,EACT,SAAS,EACT,WAAW,GACZ,MAAM,cAAc,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { createSseClient } from './createSseClient.esm.js';
2
+ export { wire } from './core/wire.esm.js';
3
+ //# sourceMappingURL=index.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
@@ -0,0 +1,130 @@
1
+ 'use strict';
2
+
3
+ var _defineProperty = require('@babel/runtime/helpers/defineProperty');
4
+ var _slicedToArray = require('@babel/runtime/helpers/slicedToArray');
5
+ var _objectWithoutProperties = require('@babel/runtime/helpers/objectWithoutProperties');
6
+ var react = require('react');
7
+ var createSseClient = require('../createSseClient.cjs.js');
8
+ var jsxRuntime = require('react/jsx-runtime');
9
+
10
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
11
+
12
+ var _defineProperty__default = /*#__PURE__*/_interopDefault(_defineProperty);
13
+ var _slicedToArray__default = /*#__PURE__*/_interopDefault(_slicedToArray);
14
+ var _objectWithoutProperties__default = /*#__PURE__*/_interopDefault(_objectWithoutProperties);
15
+
16
+ var _excluded = ["enabled", "children"];
17
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
18
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), true).forEach(function (r) { _defineProperty__default.default(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
19
+ var useLatestRef = function useLatestRef(value) {
20
+ var ref = react.useRef(value);
21
+ react.useInsertionEffect(function () {
22
+ ref.current = value;
23
+ });
24
+ return ref;
25
+ };
26
+
27
+ /**
28
+ * @description 연결 옵션은 마운트 시점 값으로 고정됩니다 — 이후 prop 변경은 무시됩니다.
29
+ * 단 `getAuthToken`은 마지막 커밋된 렌더의 함수를 호출하므로 인라인 클로저를 넘겨도 안전합니다.
30
+ */
31
+
32
+ /**
33
+ * @description 앱의 이벤트 맵으로 Provider와 훅을 한 번에 생성합니다 — 호출부는 이벤트명만으로 페이로드가 추론됩니다.
34
+ * 컨텍스트를 팩토리 안에서 만들어 Provider와 훅이 타입으로 결합되며,
35
+ * 호출마다 제네릭을 명시하는 방식은 TS의 부분 타입 인자 추론 부재로 페이로드가 unknown이 되어 팩토리로 고정합니다.
36
+ * 컴포넌트 밖 모듈 스코프에서 한 번만 호출하세요 — 렌더 중 호출하면 컨텍스트가 매번 재생성됩니다.
37
+ *
38
+ * @example
39
+ * // 앱당 1회, 모듈 스코프
40
+ * export const { SseProvider, useSseEvent, useSseStatus } =
41
+ * createSseContext<AppEventMap>();
42
+ *
43
+ * // 호출부 — 이벤트명만으로 페이로드가 추론됩니다
44
+ * useSseEvent('demo.created', (event) => showToast(event.id));
45
+ */
46
+ function createSseContext() {
47
+ var SseClientContext = /*#__PURE__*/react.createContext(null);
48
+ var SseProvider = function SseProvider(_ref) {
49
+ var _ref$enabled = _ref.enabled,
50
+ enabled = _ref$enabled === void 0 ? true : _ref$enabled,
51
+ children = _ref.children,
52
+ options = _objectWithoutProperties__default.default(_ref, _excluded);
53
+ var getAuthTokenRef = useLatestRef(options.getAuthToken);
54
+ var _useState = react.useState(function () {
55
+ return createSseClient.createSseClient(_objectSpread(_objectSpread({}, options), {}, {
56
+ getAuthToken: function getAuthToken() {
57
+ return getAuthTokenRef.current();
58
+ }
59
+ }));
60
+ }),
61
+ _useState2 = _slicedToArray__default.default(_useState, 1),
62
+ client = _useState2[0];
63
+ react.useEffect(function () {
64
+ if (!enabled) {
65
+ return;
66
+ }
67
+ client.connect();
68
+ // 휴면으로 접힌 연결은 깨어난 탭의 connect만이 다시 세웁니다 — 소비처가 몰라도 복구되게 여기서 붙입니다
69
+ var detachAutoResume = client.attachAutoResume();
70
+ return function () {
71
+ detachAutoResume();
72
+ client.disconnect();
73
+ };
74
+ }, [client, enabled]);
75
+ return /*#__PURE__*/jsxRuntime.jsx(SseClientContext.Provider, {
76
+ value: client,
77
+ children: children
78
+ });
79
+ };
80
+ var useSseClient = function useSseClient() {
81
+ var client = react.useContext(SseClientContext);
82
+ if (!client) {
83
+ throw new Error('SSE 훅은 SseProvider 안에서만 호출할 수 있습니다');
84
+ }
85
+ return client;
86
+ };
87
+
88
+ /**
89
+ * @description 이벤트 구독 훅 — 마운트 동안 구독하고 언마운트에 해제하며, 핸들러는 항상 최신 렌더의 클로저를 봅니다.
90
+ * @param type 이벤트 이름. 도메인 이벤트 외 예약 4종 —
91
+ * - `fatal`(SDK의 포기 선언 — 재시도 없이 멈춤, SDK 합성) ·
92
+ * - `stalled`(재시도가 계속되는 진행형 통지, SDK 합성) ·
93
+ * - `goaway`(서버의 예고된 끊음 — `action: 'close'`만 안내 대상, 서버 발신) ·
94
+ * - `resync`(재수립 후 놓친 구간을 REST로 재조회하라는 신호, SDK 합성). 상세는 `WithLifecycle` 문서 참조.
95
+ * @param handler 이벤트 페이로드를 받는 콜백 — 발화 순간의 구독자에게만 배달되므로 수명주기 핸들러는 앱 루트에 두세요
96
+ */
97
+ var useSseEvent = function useSseEvent(type, handler) {
98
+ var client = useSseClient();
99
+ var handlerRef = useLatestRef(handler);
100
+ react.useEffect(function () {
101
+ return client.on(type, function (payload) {
102
+ return handlerRef.current(payload);
103
+ });
104
+ },
105
+ // handlerRef는 useRef 정체성이라 재구독을 유발하지 않지만, exhaustive-deps가 커스텀 훅 반환을 안정으로 볼 수 없어 명시합니다
106
+ [client, type, handlerRef]);
107
+ };
108
+ var useSseStatus = function useSseStatus() {
109
+ var client = useSseClient();
110
+ var subscribe = react.useCallback(function (onStoreChange) {
111
+ return client.onStatus(onStoreChange);
112
+ }, [client]);
113
+ return react.useSyncExternalStore(subscribe, function () {
114
+ return client.status;
115
+ },
116
+ // 서버/hydration 첫 렌더는 connect() 이전이라 항상 클라이언트 초기 상태입니다
117
+ function () {
118
+ return client.status;
119
+ });
120
+ };
121
+ return {
122
+ SseProvider: SseProvider,
123
+ useSseClient: useSseClient,
124
+ useSseEvent: useSseEvent,
125
+ useSseStatus: useSseStatus
126
+ };
127
+ }
128
+
129
+ exports.createSseContext = createSseContext;
130
+ //# sourceMappingURL=createSseContext.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createSseContext.cjs.js","sources":["../../../src/react/createSseContext.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useInsertionEffect,\n useRef,\n useState,\n useSyncExternalStore,\n} from 'react';\n\nimport type {\n PayloadOf,\n SseClientLike,\n SseClientOptions,\n SseEventHandler,\n SseEventMap,\n SseEventName,\n SseStatus,\n} from '../core/types';\nimport { createSseClient } from '../createSseClient';\n\n// useEffectEvent(React 19.2+)와 같은 목적의 latest-ref 패턴 — insertion effect는 커밋된 렌더에서만 실행되고 paint 전에 동기 반영됩니다\nconst useLatestRef = <T,>(value: T) => {\n const ref = useRef(value);\n useInsertionEffect(() => {\n ref.current = value;\n });\n return ref;\n};\n\n/**\n * @description 연결 옵션은 마운트 시점 값으로 고정됩니다 — 이후 prop 변경은 무시됩니다.\n * 단 `getAuthToken`은 마지막 커밋된 렌더의 함수를 호출하므로 인라인 클로저를 넘겨도 안전합니다.\n */\nexport interface SseProviderProps extends SseClientOptions {\n /** @description false면 연결하지 않고, 연결 중이면 해제합니다 (로그아웃 등) */\n enabled?: boolean;\n children: ReactNode;\n}\n\n/**\n * @description 앱의 이벤트 맵으로 Provider와 훅을 한 번에 생성합니다 — 호출부는 이벤트명만으로 페이로드가 추론됩니다.\n * 컨텍스트를 팩토리 안에서 만들어 Provider와 훅이 타입으로 결합되며,\n * 호출마다 제네릭을 명시하는 방식은 TS의 부분 타입 인자 추론 부재로 페이로드가 unknown이 되어 팩토리로 고정합니다.\n * 컴포넌트 밖 모듈 스코프에서 한 번만 호출하세요 — 렌더 중 호출하면 컨텍스트가 매번 재생성됩니다.\n *\n * @example\n * // 앱당 1회, 모듈 스코프\n * export const { SseProvider, useSseEvent, useSseStatus } =\n * createSseContext<AppEventMap>();\n *\n * // 호출부 — 이벤트명만으로 페이로드가 추론됩니다\n * useSseEvent('demo.created', (event) => showToast(event.id));\n */\nexport function createSseContext<M extends object = SseEventMap>() {\n const SseClientContext = createContext<SseClientLike<M> | null>(null);\n\n const SseProvider = ({\n enabled = true,\n children,\n ...options\n }: Readonly<SseProviderProps>) => {\n const getAuthTokenRef = useLatestRef(options.getAuthToken);\n\n const [client] = useState(() =>\n createSseClient<M>({\n ...options,\n getAuthToken: () => getAuthTokenRef.current(),\n })\n );\n\n useEffect(() => {\n if (!enabled) {\n return;\n }\n client.connect();\n // 휴면으로 접힌 연결은 깨어난 탭의 connect만이 다시 세웁니다 — 소비처가 몰라도 복구되게 여기서 붙입니다\n const detachAutoResume = client.attachAutoResume();\n return () => {\n detachAutoResume();\n client.disconnect();\n };\n }, [client, enabled]);\n\n return (\n <SseClientContext.Provider value={client}>\n {children}\n </SseClientContext.Provider>\n );\n };\n\n const useSseClient = (): SseClientLike<M> => {\n const client = useContext(SseClientContext);\n if (!client) {\n throw new Error('SSE 훅은 SseProvider 안에서만 호출할 수 있습니다');\n }\n return client;\n };\n\n /**\n * @description 이벤트 구독 훅 — 마운트 동안 구독하고 언마운트에 해제하며, 핸들러는 항상 최신 렌더의 클로저를 봅니다.\n * @param type 이벤트 이름. 도메인 이벤트 외 예약 4종 —\n * - `fatal`(SDK의 포기 선언 — 재시도 없이 멈춤, SDK 합성) ·\n * - `stalled`(재시도가 계속되는 진행형 통지, SDK 합성) ·\n * - `goaway`(서버의 예고된 끊음 — `action: 'close'`만 안내 대상, 서버 발신) ·\n * - `resync`(재수립 후 놓친 구간을 REST로 재조회하라는 신호, SDK 합성). 상세는 `WithLifecycle` 문서 참조.\n * @param handler 이벤트 페이로드를 받는 콜백 — 발화 순간의 구독자에게만 배달되므로 수명주기 핸들러는 앱 루트에 두세요\n */\n const useSseEvent = <K extends SseEventName<M>>(\n type: K,\n handler: SseEventHandler<PayloadOf<M, K>>\n ): void => {\n const client = useSseClient();\n const handlerRef = useLatestRef(handler);\n\n useEffect(\n () => client.on(type, (payload) => handlerRef.current(payload)),\n // handlerRef는 useRef 정체성이라 재구독을 유발하지 않지만, exhaustive-deps가 커스텀 훅 반환을 안정으로 볼 수 없어 명시합니다\n [client, type, handlerRef]\n );\n };\n\n const useSseStatus = (): SseStatus => {\n const client = useSseClient();\n const subscribe = useCallback(\n (onStoreChange: () => void) => client.onStatus(onStoreChange),\n [client]\n );\n return useSyncExternalStore(\n subscribe,\n () => client.status,\n // 서버/hydration 첫 렌더는 connect() 이전이라 항상 클라이언트 초기 상태입니다\n () => client.status\n );\n };\n\n return { SseProvider, useSseClient, useSseEvent, useSseStatus };\n}\n"],"names":["useLatestRef","value","ref","useRef","useInsertionEffect","current","createSseContext","SseClientContext","createContext","SseProvider","_ref","_ref$enabled","enabled","children","options","_objectWithoutProperties","_excluded","getAuthTokenRef","getAuthToken","_useState","useState","createSseClient","_objectSpread","_useState2","_slicedToArray","client","useEffect","connect","detachAutoResume","attachAutoResume","disconnect","_jsx","Provider","useSseClient","useContext","Error","useSseEvent","type","handler","handlerRef","on","payload","useSseStatus","subscribe","useCallback","onStoreChange","onStatus","useSyncExternalStore","status"],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { PayloadOf, SseClientLike, SseClientOptions, SseEventHandler, SseEventMap, SseEventName, SseStatus } from '../core/types';
3
+ /**
4
+ * @description 연결 옵션은 마운트 시점 값으로 고정됩니다 — 이후 prop 변경은 무시됩니다.
5
+ * 단 `getAuthToken`은 마지막 커밋된 렌더의 함수를 호출하므로 인라인 클로저를 넘겨도 안전합니다.
6
+ */
7
+ export interface SseProviderProps extends SseClientOptions {
8
+ /** @description false면 연결하지 않고, 연결 중이면 해제합니다 (로그아웃 등) */
9
+ enabled?: boolean;
10
+ children: ReactNode;
11
+ }
12
+ /**
13
+ * @description 앱의 이벤트 맵으로 Provider와 훅을 한 번에 생성합니다 — 호출부는 이벤트명만으로 페이로드가 추론됩니다.
14
+ * 컨텍스트를 팩토리 안에서 만들어 Provider와 훅이 타입으로 결합되며,
15
+ * 호출마다 제네릭을 명시하는 방식은 TS의 부분 타입 인자 추론 부재로 페이로드가 unknown이 되어 팩토리로 고정합니다.
16
+ * 컴포넌트 밖 모듈 스코프에서 한 번만 호출하세요 — 렌더 중 호출하면 컨텍스트가 매번 재생성됩니다.
17
+ *
18
+ * @example
19
+ * // 앱당 1회, 모듈 스코프
20
+ * export const { SseProvider, useSseEvent, useSseStatus } =
21
+ * createSseContext<AppEventMap>();
22
+ *
23
+ * // 호출부 — 이벤트명만으로 페이로드가 추론됩니다
24
+ * useSseEvent('demo.created', (event) => showToast(event.id));
25
+ */
26
+ export declare function createSseContext<M extends object = SseEventMap>(): {
27
+ SseProvider: ({ enabled, children, ...options }: Readonly<SseProviderProps>) => import("react/jsx-runtime").JSX.Element;
28
+ useSseClient: () => SseClientLike<M>;
29
+ useSseEvent: <K extends SseEventName<M>>(type: K, handler: SseEventHandler<PayloadOf<M, K>>) => void;
30
+ useSseStatus: () => SseStatus;
31
+ };
32
+ //# sourceMappingURL=createSseContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createSseContext.d.ts","sourceRoot":"","sources":["../../../src/react/createSseContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAYvC,OAAO,KAAK,EACV,SAAS,EACT,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,WAAW,EACX,YAAY,EACZ,SAAS,EACV,MAAM,eAAe,CAAC;AAYvB;;;GAGG;AACH,MAAM,WAAW,gBAAiB,SAAQ,gBAAgB;IACxD,yDAAyD;IACzD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,MAAM,GAAG,WAAW;qDAO1D,SAAS,gBAAgB,CAAC;wBA8BJ,cAAc,CAAC,CAAC;mDAkBjC,CAAC,WACE,gBAAgB,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,KACxC,IAAI;wBAWkB,SAAS;EAenC"}
@@ -0,0 +1,122 @@
1
+ import _defineProperty from '@babel/runtime/helpers/defineProperty';
2
+ import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
3
+ import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProperties';
4
+ import { useCallback, useSyncExternalStore, useEffect, useContext, createContext, useState, useRef, useInsertionEffect } from 'react';
5
+ import { createSseClient } from '../createSseClient.esm.js';
6
+ import { jsx } from 'react/jsx-runtime';
7
+
8
+ var _excluded = ["enabled", "children"];
9
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
10
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), true).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
11
+ var useLatestRef = function useLatestRef(value) {
12
+ var ref = useRef(value);
13
+ useInsertionEffect(function () {
14
+ ref.current = value;
15
+ });
16
+ return ref;
17
+ };
18
+
19
+ /**
20
+ * @description 연결 옵션은 마운트 시점 값으로 고정됩니다 — 이후 prop 변경은 무시됩니다.
21
+ * 단 `getAuthToken`은 마지막 커밋된 렌더의 함수를 호출하므로 인라인 클로저를 넘겨도 안전합니다.
22
+ */
23
+
24
+ /**
25
+ * @description 앱의 이벤트 맵으로 Provider와 훅을 한 번에 생성합니다 — 호출부는 이벤트명만으로 페이로드가 추론됩니다.
26
+ * 컨텍스트를 팩토리 안에서 만들어 Provider와 훅이 타입으로 결합되며,
27
+ * 호출마다 제네릭을 명시하는 방식은 TS의 부분 타입 인자 추론 부재로 페이로드가 unknown이 되어 팩토리로 고정합니다.
28
+ * 컴포넌트 밖 모듈 스코프에서 한 번만 호출하세요 — 렌더 중 호출하면 컨텍스트가 매번 재생성됩니다.
29
+ *
30
+ * @example
31
+ * // 앱당 1회, 모듈 스코프
32
+ * export const { SseProvider, useSseEvent, useSseStatus } =
33
+ * createSseContext<AppEventMap>();
34
+ *
35
+ * // 호출부 — 이벤트명만으로 페이로드가 추론됩니다
36
+ * useSseEvent('demo.created', (event) => showToast(event.id));
37
+ */
38
+ function createSseContext() {
39
+ var SseClientContext = /*#__PURE__*/createContext(null);
40
+ var SseProvider = function SseProvider(_ref) {
41
+ var _ref$enabled = _ref.enabled,
42
+ enabled = _ref$enabled === void 0 ? true : _ref$enabled,
43
+ children = _ref.children,
44
+ options = _objectWithoutProperties(_ref, _excluded);
45
+ var getAuthTokenRef = useLatestRef(options.getAuthToken);
46
+ var _useState = useState(function () {
47
+ return createSseClient(_objectSpread(_objectSpread({}, options), {}, {
48
+ getAuthToken: function getAuthToken() {
49
+ return getAuthTokenRef.current();
50
+ }
51
+ }));
52
+ }),
53
+ _useState2 = _slicedToArray(_useState, 1),
54
+ client = _useState2[0];
55
+ useEffect(function () {
56
+ if (!enabled) {
57
+ return;
58
+ }
59
+ client.connect();
60
+ // 휴면으로 접힌 연결은 깨어난 탭의 connect만이 다시 세웁니다 — 소비처가 몰라도 복구되게 여기서 붙입니다
61
+ var detachAutoResume = client.attachAutoResume();
62
+ return function () {
63
+ detachAutoResume();
64
+ client.disconnect();
65
+ };
66
+ }, [client, enabled]);
67
+ return /*#__PURE__*/jsx(SseClientContext.Provider, {
68
+ value: client,
69
+ children: children
70
+ });
71
+ };
72
+ var useSseClient = function useSseClient() {
73
+ var client = useContext(SseClientContext);
74
+ if (!client) {
75
+ throw new Error('SSE 훅은 SseProvider 안에서만 호출할 수 있습니다');
76
+ }
77
+ return client;
78
+ };
79
+
80
+ /**
81
+ * @description 이벤트 구독 훅 — 마운트 동안 구독하고 언마운트에 해제하며, 핸들러는 항상 최신 렌더의 클로저를 봅니다.
82
+ * @param type 이벤트 이름. 도메인 이벤트 외 예약 4종 —
83
+ * - `fatal`(SDK의 포기 선언 — 재시도 없이 멈춤, SDK 합성) ·
84
+ * - `stalled`(재시도가 계속되는 진행형 통지, SDK 합성) ·
85
+ * - `goaway`(서버의 예고된 끊음 — `action: 'close'`만 안내 대상, 서버 발신) ·
86
+ * - `resync`(재수립 후 놓친 구간을 REST로 재조회하라는 신호, SDK 합성). 상세는 `WithLifecycle` 문서 참조.
87
+ * @param handler 이벤트 페이로드를 받는 콜백 — 발화 순간의 구독자에게만 배달되므로 수명주기 핸들러는 앱 루트에 두세요
88
+ */
89
+ var useSseEvent = function useSseEvent(type, handler) {
90
+ var client = useSseClient();
91
+ var handlerRef = useLatestRef(handler);
92
+ useEffect(function () {
93
+ return client.on(type, function (payload) {
94
+ return handlerRef.current(payload);
95
+ });
96
+ },
97
+ // handlerRef는 useRef 정체성이라 재구독을 유발하지 않지만, exhaustive-deps가 커스텀 훅 반환을 안정으로 볼 수 없어 명시합니다
98
+ [client, type, handlerRef]);
99
+ };
100
+ var useSseStatus = function useSseStatus() {
101
+ var client = useSseClient();
102
+ var subscribe = useCallback(function (onStoreChange) {
103
+ return client.onStatus(onStoreChange);
104
+ }, [client]);
105
+ return useSyncExternalStore(subscribe, function () {
106
+ return client.status;
107
+ },
108
+ // 서버/hydration 첫 렌더는 connect() 이전이라 항상 클라이언트 초기 상태입니다
109
+ function () {
110
+ return client.status;
111
+ });
112
+ };
113
+ return {
114
+ SseProvider: SseProvider,
115
+ useSseClient: useSseClient,
116
+ useSseEvent: useSseEvent,
117
+ useSseStatus: useSseStatus
118
+ };
119
+ }
120
+
121
+ export { createSseContext };
122
+ //# sourceMappingURL=createSseContext.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createSseContext.esm.js","sources":["../../../src/react/createSseContext.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useInsertionEffect,\n useRef,\n useState,\n useSyncExternalStore,\n} from 'react';\n\nimport type {\n PayloadOf,\n SseClientLike,\n SseClientOptions,\n SseEventHandler,\n SseEventMap,\n SseEventName,\n SseStatus,\n} from '../core/types';\nimport { createSseClient } from '../createSseClient';\n\n// useEffectEvent(React 19.2+)와 같은 목적의 latest-ref 패턴 — insertion effect는 커밋된 렌더에서만 실행되고 paint 전에 동기 반영됩니다\nconst useLatestRef = <T,>(value: T) => {\n const ref = useRef(value);\n useInsertionEffect(() => {\n ref.current = value;\n });\n return ref;\n};\n\n/**\n * @description 연결 옵션은 마운트 시점 값으로 고정됩니다 — 이후 prop 변경은 무시됩니다.\n * 단 `getAuthToken`은 마지막 커밋된 렌더의 함수를 호출하므로 인라인 클로저를 넘겨도 안전합니다.\n */\nexport interface SseProviderProps extends SseClientOptions {\n /** @description false면 연결하지 않고, 연결 중이면 해제합니다 (로그아웃 등) */\n enabled?: boolean;\n children: ReactNode;\n}\n\n/**\n * @description 앱의 이벤트 맵으로 Provider와 훅을 한 번에 생성합니다 — 호출부는 이벤트명만으로 페이로드가 추론됩니다.\n * 컨텍스트를 팩토리 안에서 만들어 Provider와 훅이 타입으로 결합되며,\n * 호출마다 제네릭을 명시하는 방식은 TS의 부분 타입 인자 추론 부재로 페이로드가 unknown이 되어 팩토리로 고정합니다.\n * 컴포넌트 밖 모듈 스코프에서 한 번만 호출하세요 — 렌더 중 호출하면 컨텍스트가 매번 재생성됩니다.\n *\n * @example\n * // 앱당 1회, 모듈 스코프\n * export const { SseProvider, useSseEvent, useSseStatus } =\n * createSseContext<AppEventMap>();\n *\n * // 호출부 — 이벤트명만으로 페이로드가 추론됩니다\n * useSseEvent('demo.created', (event) => showToast(event.id));\n */\nexport function createSseContext<M extends object = SseEventMap>() {\n const SseClientContext = createContext<SseClientLike<M> | null>(null);\n\n const SseProvider = ({\n enabled = true,\n children,\n ...options\n }: Readonly<SseProviderProps>) => {\n const getAuthTokenRef = useLatestRef(options.getAuthToken);\n\n const [client] = useState(() =>\n createSseClient<M>({\n ...options,\n getAuthToken: () => getAuthTokenRef.current(),\n })\n );\n\n useEffect(() => {\n if (!enabled) {\n return;\n }\n client.connect();\n // 휴면으로 접힌 연결은 깨어난 탭의 connect만이 다시 세웁니다 — 소비처가 몰라도 복구되게 여기서 붙입니다\n const detachAutoResume = client.attachAutoResume();\n return () => {\n detachAutoResume();\n client.disconnect();\n };\n }, [client, enabled]);\n\n return (\n <SseClientContext.Provider value={client}>\n {children}\n </SseClientContext.Provider>\n );\n };\n\n const useSseClient = (): SseClientLike<M> => {\n const client = useContext(SseClientContext);\n if (!client) {\n throw new Error('SSE 훅은 SseProvider 안에서만 호출할 수 있습니다');\n }\n return client;\n };\n\n /**\n * @description 이벤트 구독 훅 — 마운트 동안 구독하고 언마운트에 해제하며, 핸들러는 항상 최신 렌더의 클로저를 봅니다.\n * @param type 이벤트 이름. 도메인 이벤트 외 예약 4종 —\n * - `fatal`(SDK의 포기 선언 — 재시도 없이 멈춤, SDK 합성) ·\n * - `stalled`(재시도가 계속되는 진행형 통지, SDK 합성) ·\n * - `goaway`(서버의 예고된 끊음 — `action: 'close'`만 안내 대상, 서버 발신) ·\n * - `resync`(재수립 후 놓친 구간을 REST로 재조회하라는 신호, SDK 합성). 상세는 `WithLifecycle` 문서 참조.\n * @param handler 이벤트 페이로드를 받는 콜백 — 발화 순간의 구독자에게만 배달되므로 수명주기 핸들러는 앱 루트에 두세요\n */\n const useSseEvent = <K extends SseEventName<M>>(\n type: K,\n handler: SseEventHandler<PayloadOf<M, K>>\n ): void => {\n const client = useSseClient();\n const handlerRef = useLatestRef(handler);\n\n useEffect(\n () => client.on(type, (payload) => handlerRef.current(payload)),\n // handlerRef는 useRef 정체성이라 재구독을 유발하지 않지만, exhaustive-deps가 커스텀 훅 반환을 안정으로 볼 수 없어 명시합니다\n [client, type, handlerRef]\n );\n };\n\n const useSseStatus = (): SseStatus => {\n const client = useSseClient();\n const subscribe = useCallback(\n (onStoreChange: () => void) => client.onStatus(onStoreChange),\n [client]\n );\n return useSyncExternalStore(\n subscribe,\n () => client.status,\n // 서버/hydration 첫 렌더는 connect() 이전이라 항상 클라이언트 초기 상태입니다\n () => client.status\n );\n };\n\n return { SseProvider, useSseClient, useSseEvent, useSseStatus };\n}\n"],"names":["useLatestRef","value","ref","useRef","useInsertionEffect","current","createSseContext","SseClientContext","createContext","SseProvider","_ref","_ref$enabled","enabled","children","options","_objectWithoutProperties","_excluded","getAuthTokenRef","getAuthToken","_useState","useState","createSseClient","_objectSpread","_useState2","_slicedToArray","client","useEffect","connect","detachAutoResume","attachAutoResume","disconnect","_jsx","Provider","useSseClient","useContext","Error","useSseEvent","type","handler","handlerRef","on","payload","useSseStatus","subscribe","useCallback","onStoreChange","onStatus","useSyncExternalStore","status"],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ 'use strict';
2
+
3
+ var createSseContext = require('./createSseContext.cjs.js');
4
+
5
+
6
+
7
+ exports.createSseContext = createSseContext.createSseContext;
8
+ //# sourceMappingURL=index.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;"}
@@ -0,0 +1,3 @@
1
+ export { createSseContext } from './createSseContext';
2
+ export type { SseProviderProps } from './createSseContext';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/react/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,YAAY,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { createSseContext } from './createSseContext.esm.js';
2
+ //# sourceMappingURL=index.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -0,0 +1,50 @@
1
+ import type { TabToWorkerMessage, WorkerToTabMessage } from '../worker/protocol';
2
+ /** @description EventSource 대역 — 생성분을 정적으로 모아 마지막 인스턴스를 집어낼 수 있게 합니다 */
3
+ export declare class FakeEventSource {
4
+ readonly url: string;
5
+ static readonly instances: FakeEventSource[];
6
+ /** @description 테스트 간 격리 — 재할당 대신 비워, 앞서 넘긴 참조가 옛 배열을 보지 않게 합니다 */
7
+ static reset(): void;
8
+ readonly listeners: Map<string, Set<(event: {
9
+ data?: string;
10
+ }) => void>>;
11
+ onerror: ((event: unknown) => void) | null;
12
+ closed: boolean;
13
+ constructor(url: string);
14
+ addEventListener(type: string, listener: (event: {
15
+ data?: string;
16
+ }) => void): void;
17
+ close(): void;
18
+ dispatch(type: string, data?: string): void;
19
+ error(): void;
20
+ }
21
+ export declare const lastSource: () => FakeEventSource;
22
+ /**
23
+ * @description 포트 대역 — 허브 쪽(HubPort)과 탭 쪽(MessagePort) 양쪽 표면을 함께 만족합니다.
24
+ * 한 포트의 양 끝을 한 객체로 보므로, 허브가 보낸 메시지는 sent에, 탭이 보낸 메시지는 posted에 쌓입니다.
25
+ */
26
+ export declare class FakePort {
27
+ /** @description 허브가 이 포트로 보낸 것 */
28
+ sent: WorkerToTabMessage[];
29
+ /** @description 탭 프록시가 이 포트로 보낸 것 */
30
+ posted: TabToWorkerMessage[];
31
+ closeCount: number;
32
+ started: boolean;
33
+ onmessage: ((event: {
34
+ data: unknown;
35
+ }) => void) | null;
36
+ get closed(): boolean;
37
+ postMessage(message: WorkerToTabMessage | TabToWorkerMessage): void;
38
+ start(): void;
39
+ close(): void;
40
+ /** @description 워커가 탭에 보낸 것처럼 프록시의 onmessage를 깨웁니다 */
41
+ deliver(message: WorkerToTabMessage): void;
42
+ }
43
+ export declare const kindsOf: <K extends "event" | "status" | "ping" | "ticket-request">(port: FakePort, kind: K) => Extract<WorkerToTabMessage, {
44
+ kind: K;
45
+ }>[];
46
+ /** @description SharedWorker 대역 — 팩토리가 넘겨받는 표면은 port 하나뿐입니다 */
47
+ export declare class FakeSharedWorker {
48
+ readonly port: FakePort;
49
+ }
50
+ //# sourceMappingURL=doubles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doubles.d.ts","sourceRoot":"","sources":["../../../src/testing/doubles.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,kBAAkB,EAClB,kBAAkB,EACnB,MAAM,oBAAoB,CAAC;AAE5B,wEAAwE;AACxE,qBAAa,eAAe;IAed,QAAQ,CAAC,GAAG,EAAE,MAAM;IAdhC,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAE,eAAe,EAAE,CAAM;IAElD,mEAAmE;IACnE,MAAM,CAAC,KAAK,IAAI,IAAI;IAIpB,QAAQ,CAAC,SAAS,0BAEJ;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,GACpC;IACJ,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC,GAAG,IAAI,CAAQ;IAClD,MAAM,UAAS;gBAEM,GAAG,EAAE,MAAM;IAIhC,gBAAgB,CACd,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,CAAC,KAAK,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,GAC3C,IAAI;IAMP,KAAK,IAAI,IAAI;IAKb,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;IAO3C,KAAK,IAAI,IAAI;CAMd;AAED,eAAO,MAAM,UAAU,QAAO,eACK,CAAC;AAEpC;;;GAGG;AACH,qBAAa,QAAQ;IACnB,kCAAkC;IAClC,IAAI,EAAE,kBAAkB,EAAE,CAAM;IAChC,qCAAqC;IACrC,MAAM,EAAE,kBAAkB,EAAE,CAAM;IAClC,UAAU,SAAK;IACf,OAAO,UAAS;IAChB,SAAS,EAAE,CAAC,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC,GAAG,IAAI,CAAQ;IAE9D,IAAI,MAAM,IAAI,OAAO,CAEpB;IAGD,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,kBAAkB,GAAG,IAAI;IAYnE,KAAK,IAAI,IAAI;IAIb,KAAK,IAAI,IAAI;IAIb,sDAAsD;IACtD,OAAO,CAAC,OAAO,EAAE,kBAAkB,GAAG,IAAI;CAG3C;AAcD,eAAO,MAAM,OAAO,mEACZ,QAAQ,QACR,CAAC,KACN,QAAQ,kBAAkB,EAAE;IAAE,IAAI,EAAE,CAAC,CAAA;CAAE,CAAC,EAIxC,CAAC;AAEJ,+DAA+D;AAC/D,qBAAa,gBAAgB;IAC3B,QAAQ,CAAC,IAAI,WAAkB;CAChC"}
@@ -0,0 +1,43 @@
1
+ import { SseClient } from '../core/SseClient';
2
+ import type { SseClientOptions } from '../core/types';
3
+ export interface TestEventMap {
4
+ 'demo.created': {
5
+ id: string;
6
+ };
7
+ }
8
+ export declare const createFetchMock: () => {
9
+ fetch: typeof fetch;
10
+ requests: {
11
+ url: string;
12
+ method?: string | undefined;
13
+ authorization?: string | undefined;
14
+ }[];
15
+ ticketRequests: () => {
16
+ url: string;
17
+ method?: string | undefined;
18
+ authorization?: string | undefined;
19
+ }[];
20
+ failTicketsWith: (status: number | null) => void;
21
+ };
22
+ export declare const createHarness: (overrides?: Partial<SseClientOptions>) => {
23
+ fetch: typeof fetch;
24
+ requests: {
25
+ url: string;
26
+ method?: string | undefined;
27
+ authorization?: string | undefined;
28
+ }[];
29
+ ticketRequests: () => {
30
+ url: string;
31
+ method?: string | undefined;
32
+ authorization?: string | undefined;
33
+ }[];
34
+ failTicketsWith: (status: number | null) => void;
35
+ client: SseClient<TestEventMap>;
36
+ };
37
+ /**
38
+ * @description 재연결 시점을 결정적으로 만드는 준비 — 정리는 vitest.setup.ts가 전역으로 합니다.
39
+ * 백오프를 기다리는 테스트 파일만 켜세요. React 테스트처럼 실제 타이머가 필요한 곳은 켜지 않습니다.
40
+ */
41
+ export declare const setupFakeTimers: () => void;
42
+ export declare const openConnection: (client: SseClient<TestEventMap>) => Promise<void>;
43
+ //# sourceMappingURL=harness.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"harness.d.ts","sourceRoot":"","sources":["../../../src/testing/harness.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEtD,MAAM,WAAW,YAAY;IAC3B,cAAc,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;CAChC;AAED,eAAO,MAAM,eAAe;;;aACH,MAAM;;;;;aAAN,MAAM;;;;8BAkCD,MAAM,GAAG,IAAI;CAI1C,CAAC;AAEF,eAAO,MAAM,aAAa,eAAgB,QAAQ,gBAAgB,CAAC;;;aAxC1C,MAAM;;;;;aAAN,MAAM;;;;8BAkCD,MAAM,GAAG,IAAI;;CAgB1C,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,eAAe,QAAO,IAMlC,CAAC;AAEF,eAAO,MAAM,cAAc,WAAkB,UAAU,YAAY,CAAC,kBAInE,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './doubles';
2
+ export * from './harness';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/testing/index.ts"],"names":[],"mappings":"AACA,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC"}