@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,51 @@
1
+ import _toConsumableArray from '@babel/runtime/helpers/toConsumableArray';
2
+
3
+ /**
4
+ * @description SseClient·WorkerSseClient가 공유하는 구독·발행 코어.
5
+ * 리스너 예외를 격리합니다 — 하나가 던져도 나머지 리스너와 호출자의 정리 로직이 중단되지 않게.
6
+ */
7
+ var createEmitter = function createEmitter(logger) {
8
+ var handlers = new Map();
9
+ var statusListeners = new Set();
10
+ var safeCall = function safeCall(listener, value) {
11
+ try {
12
+ listener(value);
13
+ } catch (error) {
14
+ logger === null || logger === void 0 || logger.warn('sse: 리스너 예외를 격리했습니다', error);
15
+ }
16
+ };
17
+ return {
18
+ on: function on(type, handler) {
19
+ var _handlers$get;
20
+ var set = (_handlers$get = handlers.get(type)) !== null && _handlers$get !== void 0 ? _handlers$get : new Set();
21
+ set.add(handler);
22
+ handlers.set(type, set);
23
+ return function () {
24
+ set["delete"](handler);
25
+ };
26
+ },
27
+ onStatus: function onStatus(listener) {
28
+ statusListeners.add(listener);
29
+ return function () {
30
+ statusListeners["delete"](listener);
31
+ };
32
+ },
33
+ emit: function emit(type, payload) {
34
+ var _handlers$get2;
35
+ (_handlers$get2 = handlers.get(type)) === null || _handlers$get2 === void 0 || _handlers$get2.forEach(function (handler) {
36
+ return safeCall(handler, payload);
37
+ });
38
+ },
39
+ emitStatus: function emitStatus(status) {
40
+ statusListeners.forEach(function (listener) {
41
+ return safeCall(listener, status);
42
+ });
43
+ },
44
+ handlerTypes: function handlerTypes() {
45
+ return _toConsumableArray(handlers.keys());
46
+ }
47
+ };
48
+ };
49
+
50
+ export { createEmitter };
51
+ //# sourceMappingURL=emitter.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emitter.esm.js","sources":["../../../src/core/emitter.ts"],"sourcesContent":["import type {\n SseEventHandler,\n SseLogger,\n SseStatus,\n Unsubscribe,\n} from './types';\n\n/**\n * @description SseClient·WorkerSseClient가 공유하는 구독·발행 코어.\n * 리스너 예외를 격리합니다 — 하나가 던져도 나머지 리스너와 호출자의 정리 로직이 중단되지 않게.\n */\nexport const createEmitter = (logger?: SseLogger) => {\n const handlers = new Map<string, Set<SseEventHandler<unknown>>>();\n const statusListeners = new Set<(status: SseStatus) => void>();\n\n const safeCall = <T>(listener: (value: T) => void, value: T): void => {\n try {\n listener(value);\n } catch (error) {\n logger?.warn('sse: 리스너 예외를 격리했습니다', error);\n }\n };\n\n return {\n on: (type: string, handler: SseEventHandler<unknown>): Unsubscribe => {\n const set = handlers.get(type) ?? new Set();\n\n set.add(handler);\n handlers.set(type, set);\n\n return () => {\n set.delete(handler);\n };\n },\n\n onStatus: (listener: (status: SseStatus) => void): Unsubscribe => {\n statusListeners.add(listener);\n\n return () => {\n statusListeners.delete(listener);\n };\n },\n\n emit: (type: string, payload: unknown): void => {\n handlers.get(type)?.forEach((handler) => safeCall(handler, payload));\n },\n\n emitStatus: (status: SseStatus): void => {\n statusListeners.forEach((listener) => safeCall(listener, status));\n },\n\n handlerTypes: (): string[] => [...handlers.keys()],\n };\n};\n\nexport type Emitter = ReturnType<typeof createEmitter>;\n"],"names":["createEmitter","logger","handlers","Map","statusListeners","Set","safeCall","listener","value","error","warn","on","type","handler","_handlers$get","set","get","add","onStatus","emit","payload","_handlers$get2","forEach","emitStatus","status","handlerTypes","_toConsumableArray","keys"],"mappings":";;AAOA;AACA;AACA;AACA;IACaA,aAAa,GAAG,SAAhBA,aAAaA,CAAIC,MAAkB,EAAK;AACnD,EAAA,IAAMC,QAAQ,GAAG,IAAIC,GAAG,EAAyC;AACjE,EAAA,IAAMC,eAAe,GAAG,IAAIC,GAAG,EAA+B;EAE9D,IAAMC,QAAQ,GAAG,SAAXA,QAAQA,CAAOC,QAA4B,EAAEC,KAAQ,EAAW;IACpE,IAAI;MACFD,QAAQ,CAACC,KAAK,CAAC;KAChB,CAAC,OAAOC,KAAK,EAAE;MACdR,MAAM,KAAA,IAAA,IAANA,MAAM,KAAA,MAAA,IAANA,MAAM,CAAES,IAAI,CAAC,qBAAqB,EAAED,KAAK,CAAC;AAC5C;GACD;EAED,OAAO;AACLE,IAAAA,EAAE,EAAE,SAAAA,EAAAA,CAACC,IAAY,EAAEC,OAAiC,EAAkB;AAAA,MAAA,IAAAC,aAAA;AACpE,MAAA,IAAMC,GAAG,GAAA,CAAAD,aAAA,GAAGZ,QAAQ,CAACc,GAAG,CAACJ,IAAI,CAAC,MAAA,IAAA,IAAAE,aAAA,KAAA,MAAA,GAAAA,aAAA,GAAI,IAAIT,GAAG,EAAE;AAE3CU,MAAAA,GAAG,CAACE,GAAG,CAACJ,OAAO,CAAC;AAChBX,MAAAA,QAAQ,CAACa,GAAG,CAACH,IAAI,EAAEG,GAAG,CAAC;AAEvB,MAAA,OAAO,YAAM;QACXA,GAAG,CAAA,QAAA,CAAO,CAACF,OAAO,CAAC;OACpB;KACF;AAEDK,IAAAA,QAAQ,EAAE,SAAAA,QAAAA,CAACX,QAAqC,EAAkB;AAChEH,MAAAA,eAAe,CAACa,GAAG,CAACV,QAAQ,CAAC;AAE7B,MAAA,OAAO,YAAM;QACXH,eAAe,CAAA,QAAA,CAAO,CAACG,QAAQ,CAAC;OACjC;KACF;AAEDY,IAAAA,IAAI,EAAE,SAAAA,IAAAA,CAACP,IAAY,EAAEQ,OAAgB,EAAW;AAAA,MAAA,IAAAC,cAAA;AAC9C,MAAA,CAAAA,cAAA,GAAAnB,QAAQ,CAACc,GAAG,CAACJ,IAAI,CAAC,MAAA,IAAA,IAAAS,cAAA,eAAlBA,cAAA,CAAoBC,OAAO,CAAC,UAACT,OAAO,EAAA;AAAA,QAAA,OAAKP,QAAQ,CAACO,OAAO,EAAEO,OAAO,CAAC;OAAA,CAAC;KACrE;AAEDG,IAAAA,UAAU,EAAE,SAAAA,UAAAA,CAACC,MAAiB,EAAW;AACvCpB,MAAAA,eAAe,CAACkB,OAAO,CAAC,UAACf,QAAQ,EAAA;AAAA,QAAA,OAAKD,QAAQ,CAACC,QAAQ,EAAEiB,MAAM,CAAC;OAAA,CAAC;KAClE;IAEDC,YAAY,EAAE,SAAAA,YAAAA,GAAA;AAAA,MAAA,OAAAC,kBAAA,CAAoBxB,QAAQ,CAACyB,IAAI,EAAE,CAAA;AAAA;GAClD;AACH;;;;"}
@@ -0,0 +1,64 @@
1
+ 'use strict';
2
+
3
+ var _toConsumableArray = require('@babel/runtime/helpers/toConsumableArray');
4
+
5
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
6
+
7
+ var _toConsumableArray__default = /*#__PURE__*/_interopDefault(_toConsumableArray);
8
+
9
+ // 서버가 /v1/events 스트림으로 보내는 연결 수명주기 이벤트 — 도메인 이벤트와 달리 SDK가 소비합니다
10
+ var SERVER_CONNECTION_EVENTS = {
11
+ hello: 'hello',
12
+ goaway: 'goaway'
13
+ };
14
+
15
+ /**
16
+ * @description SDK가 스스로 발화하는 이벤트 — 재수립(resync)·멈춘 사유(fatal)·미연결 지속(stalled)을 SDK가 알아채 알립니다
17
+ */
18
+ var SDK_EVENTS = {
19
+ resync: 'resync',
20
+ fatal: 'fatal',
21
+ stalled: 'stalled'
22
+ };
23
+
24
+ /**
25
+ * @description 소비처로 배달하는 이름들 — 출처(서버·SDK)와 무관하게 "소비처가 보는가"만 봅니다.
26
+ * 워커는 구독 장부와 별개로 이 목록을 중계해야 합니다: 장부만 보고 붙이면 소비처에 영영 도달하지 않습니다.
27
+ * SDK 이벤트는 배달이 곧 존재 이유라 전부 파생합니다 — 나열하면 이름을 늘릴 때 빠뜨릴 자리가 생깁니다.
28
+ * 서버 연결 이벤트는 SDK가 소비하는 게 기본이라 배달할 것만 골라 넣습니다:
29
+ * goaway는 SDK가 action으로 재연결을 판단하고, 소비처는 reason으로 안내를 정합니다.
30
+ */
31
+ var FORWARDED_EVENTS = [].concat(_toConsumableArray__default.default(Object.values(SDK_EVENTS)), [SERVER_CONNECTION_EVENTS.goaway]);
32
+
33
+ // 멤버십 검사는 Set 파생으로 — Object.hasOwn(Safari 15.4+)이 배포 하한을 만들지 않게 합니다
34
+ var SERVER_CONNECTION_EVENT_NAMES = new Set(Object.values(SERVER_CONNECTION_EVENTS));
35
+ var FORWARDED_EVENT_NAMES = new Set(FORWARDED_EVENTS);
36
+ var isServerConnectionEvent = function isServerConnectionEvent(type) {
37
+ return SERVER_CONNECTION_EVENT_NAMES.has(type);
38
+ };
39
+ var isForwardedEvent = function isForwardedEvent(type) {
40
+ return FORWARDED_EVENT_NAMES.has(type);
41
+ };
42
+
43
+ /**
44
+ * @description 서버 스트림에 구독을 걸 이름인지 판정합니다 — 연결 이벤트와 중계 목록은 SDK가 소유합니다.
45
+ * 목록에서 판정을 파생해야 이름을 추가할 때 구독 제외가 따라옵니다: 빠지면 워커가 같은 이벤트를 두 번 배달합니다.
46
+ */
47
+ var isSubscribableEvent = function isSubscribableEvent(type) {
48
+ return !isServerConnectionEvent(type) && !isForwardedEvent(type);
49
+ };
50
+
51
+ /**
52
+ * @description 구독해도 배달되지 않는 이름인지 판정합니다 — 조용한 무배달 구독을 경고로 알리는 데 씁니다.
53
+ * 중계 목록에 있으면 SDK가 소비하더라도 소비처에 배달되므로 경고 대상이 아닙니다.
54
+ */
55
+ var isUndeliverableEvent = function isUndeliverableEvent(type) {
56
+ return isServerConnectionEvent(type) && !isForwardedEvent(type);
57
+ };
58
+
59
+ exports.FORWARDED_EVENTS = FORWARDED_EVENTS;
60
+ exports.SDK_EVENTS = SDK_EVENTS;
61
+ exports.SERVER_CONNECTION_EVENTS = SERVER_CONNECTION_EVENTS;
62
+ exports.isSubscribableEvent = isSubscribableEvent;
63
+ exports.isUndeliverableEvent = isUndeliverableEvent;
64
+ //# sourceMappingURL=eventNames.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eventNames.cjs.js","sources":["../../../src/core/eventNames.ts"],"sourcesContent":["// 서버가 /v1/events 스트림으로 보내는 연결 수명주기 이벤트 — 도메인 이벤트와 달리 SDK가 소비합니다\nexport const SERVER_CONNECTION_EVENTS = {\n hello: 'hello',\n goaway: 'goaway',\n} as const;\n\n/**\n * @description SDK가 스스로 발화하는 이벤트 — 재수립(resync)·멈춘 사유(fatal)·미연결 지속(stalled)을 SDK가 알아채 알립니다\n */\nexport const SDK_EVENTS = {\n resync: 'resync',\n fatal: 'fatal',\n stalled: 'stalled',\n} as const;\n\n/**\n * @description 소비처로 배달하는 이름들 — 출처(서버·SDK)와 무관하게 \"소비처가 보는가\"만 봅니다.\n * 워커는 구독 장부와 별개로 이 목록을 중계해야 합니다: 장부만 보고 붙이면 소비처에 영영 도달하지 않습니다.\n * SDK 이벤트는 배달이 곧 존재 이유라 전부 파생합니다 — 나열하면 이름을 늘릴 때 빠뜨릴 자리가 생깁니다.\n * 서버 연결 이벤트는 SDK가 소비하는 게 기본이라 배달할 것만 골라 넣습니다:\n * goaway는 SDK가 action으로 재연결을 판단하고, 소비처는 reason으로 안내를 정합니다.\n */\nexport const FORWARDED_EVENTS = [\n ...Object.values(SDK_EVENTS),\n SERVER_CONNECTION_EVENTS.goaway,\n] as const;\n\n// 멤버십 검사는 Set 파생으로 — Object.hasOwn(Safari 15.4+)이 배포 하한을 만들지 않게 합니다\nconst SERVER_CONNECTION_EVENT_NAMES: ReadonlySet<string> = new Set(\n Object.values(SERVER_CONNECTION_EVENTS)\n);\n\nconst FORWARDED_EVENT_NAMES: ReadonlySet<string> = new Set(FORWARDED_EVENTS);\n\nconst isServerConnectionEvent = (type: string): boolean =>\n SERVER_CONNECTION_EVENT_NAMES.has(type);\n\nconst isForwardedEvent = (type: string): boolean =>\n FORWARDED_EVENT_NAMES.has(type);\n\n/**\n * @description 서버 스트림에 구독을 걸 이름인지 판정합니다 — 연결 이벤트와 중계 목록은 SDK가 소유합니다.\n * 목록에서 판정을 파생해야 이름을 추가할 때 구독 제외가 따라옵니다: 빠지면 워커가 같은 이벤트를 두 번 배달합니다.\n */\nexport const isSubscribableEvent = (type: string): boolean =>\n !isServerConnectionEvent(type) && !isForwardedEvent(type);\n\n/**\n * @description 구독해도 배달되지 않는 이름인지 판정합니다 — 조용한 무배달 구독을 경고로 알리는 데 씁니다.\n * 중계 목록에 있으면 SDK가 소비하더라도 소비처에 배달되므로 경고 대상이 아닙니다.\n */\nexport const isUndeliverableEvent = (type: string): boolean =>\n isServerConnectionEvent(type) && !isForwardedEvent(type);\n"],"names":["SERVER_CONNECTION_EVENTS","hello","goaway","SDK_EVENTS","resync","fatal","stalled","FORWARDED_EVENTS","concat","_toConsumableArray","Object","values","SERVER_CONNECTION_EVENT_NAMES","Set","FORWARDED_EVENT_NAMES","isServerConnectionEvent","type","has","isForwardedEvent","isSubscribableEvent","isUndeliverableEvent"],"mappings":";;;;;;;;AAAA;AACO,IAAMA,wBAAwB,GAAG;AACtCC,EAAAA,KAAK,EAAE,OAAO;AACdC,EAAAA,MAAM,EAAE;AACV;;AAEA;AACA;AACA;AACO,IAAMC,UAAU,GAAG;AACxBC,EAAAA,MAAM,EAAE,QAAQ;AAChBC,EAAAA,KAAK,EAAE,OAAO;AACdC,EAAAA,OAAO,EAAE;AACX;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;IACaC,gBAAgB,GAAA,EAAA,CAAAC,MAAA,CAAAC,mCAAA,CACxBC,MAAM,CAACC,MAAM,CAACR,UAAU,CAAC,IAC5BH,wBAAwB,CAACE,MAAM,CAAA;;AAGjC;AACA,IAAMU,6BAAkD,GAAG,IAAIC,GAAG,CAChEH,MAAM,CAACC,MAAM,CAACX,wBAAwB,CACxC,CAAC;AAED,IAAMc,qBAA0C,GAAG,IAAID,GAAG,CAACN,gBAAgB,CAAC;AAE5E,IAAMQ,uBAAuB,GAAG,SAA1BA,uBAAuBA,CAAIC,IAAY,EAAA;AAAA,EAAA,OAC3CJ,6BAA6B,CAACK,GAAG,CAACD,IAAI,CAAC;AAAA,CAAA;AAEzC,IAAME,gBAAgB,GAAG,SAAnBA,gBAAgBA,CAAIF,IAAY,EAAA;AAAA,EAAA,OACpCF,qBAAqB,CAACG,GAAG,CAACD,IAAI,CAAC;AAAA,CAAA;;AAEjC;AACA;AACA;AACA;IACaG,mBAAmB,GAAG,SAAtBA,mBAAmBA,CAAIH,IAAY,EAAA;EAAA,OAC9C,CAACD,uBAAuB,CAACC,IAAI,CAAC,IAAI,CAACE,gBAAgB,CAACF,IAAI,CAAC;AAAA;;AAE3D;AACA;AACA;AACA;IACaI,oBAAoB,GAAG,SAAvBA,oBAAoBA,CAAIJ,IAAY,EAAA;EAAA,OAC/CD,uBAAuB,CAACC,IAAI,CAAC,IAAI,CAACE,gBAAgB,CAACF,IAAI,CAAC;AAAA;;;;;;;;"}
@@ -0,0 +1,31 @@
1
+ export declare const SERVER_CONNECTION_EVENTS: {
2
+ readonly hello: "hello";
3
+ readonly goaway: "goaway";
4
+ };
5
+ /**
6
+ * @description SDK가 스스로 발화하는 이벤트 — 재수립(resync)·멈춘 사유(fatal)·미연결 지속(stalled)을 SDK가 알아채 알립니다
7
+ */
8
+ export declare const SDK_EVENTS: {
9
+ readonly resync: "resync";
10
+ readonly fatal: "fatal";
11
+ readonly stalled: "stalled";
12
+ };
13
+ /**
14
+ * @description 소비처로 배달하는 이름들 — 출처(서버·SDK)와 무관하게 "소비처가 보는가"만 봅니다.
15
+ * 워커는 구독 장부와 별개로 이 목록을 중계해야 합니다: 장부만 보고 붙이면 소비처에 영영 도달하지 않습니다.
16
+ * SDK 이벤트는 배달이 곧 존재 이유라 전부 파생합니다 — 나열하면 이름을 늘릴 때 빠뜨릴 자리가 생깁니다.
17
+ * 서버 연결 이벤트는 SDK가 소비하는 게 기본이라 배달할 것만 골라 넣습니다:
18
+ * goaway는 SDK가 action으로 재연결을 판단하고, 소비처는 reason으로 안내를 정합니다.
19
+ */
20
+ export declare const FORWARDED_EVENTS: readonly [...("resync" | "fatal" | "stalled")[], "goaway"];
21
+ /**
22
+ * @description 서버 스트림에 구독을 걸 이름인지 판정합니다 — 연결 이벤트와 중계 목록은 SDK가 소유합니다.
23
+ * 목록에서 판정을 파생해야 이름을 추가할 때 구독 제외가 따라옵니다: 빠지면 워커가 같은 이벤트를 두 번 배달합니다.
24
+ */
25
+ export declare const isSubscribableEvent: (type: string) => boolean;
26
+ /**
27
+ * @description 구독해도 배달되지 않는 이름인지 판정합니다 — 조용한 무배달 구독을 경고로 알리는 데 씁니다.
28
+ * 중계 목록에 있으면 SDK가 소비하더라도 소비처에 배달되므로 경고 대상이 아닙니다.
29
+ */
30
+ export declare const isUndeliverableEvent: (type: string) => boolean;
31
+ //# sourceMappingURL=eventNames.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eventNames.d.ts","sourceRoot":"","sources":["../../../src/core/eventNames.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,wBAAwB;;;CAG3B,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,UAAU;;;;CAIb,CAAC;AAEX;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,4DAGnB,CAAC;AAeX;;;GAGG;AACH,eAAO,MAAM,mBAAmB,SAAU,MAAM,KAAG,OACQ,CAAC;AAE5D;;;GAGG;AACH,eAAO,MAAM,oBAAoB,SAAU,MAAM,KAAG,OACM,CAAC"}
@@ -0,0 +1,54 @@
1
+ import _toConsumableArray from '@babel/runtime/helpers/toConsumableArray';
2
+
3
+ // 서버가 /v1/events 스트림으로 보내는 연결 수명주기 이벤트 — 도메인 이벤트와 달리 SDK가 소비합니다
4
+ var SERVER_CONNECTION_EVENTS = {
5
+ hello: 'hello',
6
+ goaway: 'goaway'
7
+ };
8
+
9
+ /**
10
+ * @description SDK가 스스로 발화하는 이벤트 — 재수립(resync)·멈춘 사유(fatal)·미연결 지속(stalled)을 SDK가 알아채 알립니다
11
+ */
12
+ var SDK_EVENTS = {
13
+ resync: 'resync',
14
+ fatal: 'fatal',
15
+ stalled: 'stalled'
16
+ };
17
+
18
+ /**
19
+ * @description 소비처로 배달하는 이름들 — 출처(서버·SDK)와 무관하게 "소비처가 보는가"만 봅니다.
20
+ * 워커는 구독 장부와 별개로 이 목록을 중계해야 합니다: 장부만 보고 붙이면 소비처에 영영 도달하지 않습니다.
21
+ * SDK 이벤트는 배달이 곧 존재 이유라 전부 파생합니다 — 나열하면 이름을 늘릴 때 빠뜨릴 자리가 생깁니다.
22
+ * 서버 연결 이벤트는 SDK가 소비하는 게 기본이라 배달할 것만 골라 넣습니다:
23
+ * goaway는 SDK가 action으로 재연결을 판단하고, 소비처는 reason으로 안내를 정합니다.
24
+ */
25
+ var FORWARDED_EVENTS = [].concat(_toConsumableArray(Object.values(SDK_EVENTS)), [SERVER_CONNECTION_EVENTS.goaway]);
26
+
27
+ // 멤버십 검사는 Set 파생으로 — Object.hasOwn(Safari 15.4+)이 배포 하한을 만들지 않게 합니다
28
+ var SERVER_CONNECTION_EVENT_NAMES = new Set(Object.values(SERVER_CONNECTION_EVENTS));
29
+ var FORWARDED_EVENT_NAMES = new Set(FORWARDED_EVENTS);
30
+ var isServerConnectionEvent = function isServerConnectionEvent(type) {
31
+ return SERVER_CONNECTION_EVENT_NAMES.has(type);
32
+ };
33
+ var isForwardedEvent = function isForwardedEvent(type) {
34
+ return FORWARDED_EVENT_NAMES.has(type);
35
+ };
36
+
37
+ /**
38
+ * @description 서버 스트림에 구독을 걸 이름인지 판정합니다 — 연결 이벤트와 중계 목록은 SDK가 소유합니다.
39
+ * 목록에서 판정을 파생해야 이름을 추가할 때 구독 제외가 따라옵니다: 빠지면 워커가 같은 이벤트를 두 번 배달합니다.
40
+ */
41
+ var isSubscribableEvent = function isSubscribableEvent(type) {
42
+ return !isServerConnectionEvent(type) && !isForwardedEvent(type);
43
+ };
44
+
45
+ /**
46
+ * @description 구독해도 배달되지 않는 이름인지 판정합니다 — 조용한 무배달 구독을 경고로 알리는 데 씁니다.
47
+ * 중계 목록에 있으면 SDK가 소비하더라도 소비처에 배달되므로 경고 대상이 아닙니다.
48
+ */
49
+ var isUndeliverableEvent = function isUndeliverableEvent(type) {
50
+ return isServerConnectionEvent(type) && !isForwardedEvent(type);
51
+ };
52
+
53
+ export { FORWARDED_EVENTS, SDK_EVENTS, SERVER_CONNECTION_EVENTS, isSubscribableEvent, isUndeliverableEvent };
54
+ //# sourceMappingURL=eventNames.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eventNames.esm.js","sources":["../../../src/core/eventNames.ts"],"sourcesContent":["// 서버가 /v1/events 스트림으로 보내는 연결 수명주기 이벤트 — 도메인 이벤트와 달리 SDK가 소비합니다\nexport const SERVER_CONNECTION_EVENTS = {\n hello: 'hello',\n goaway: 'goaway',\n} as const;\n\n/**\n * @description SDK가 스스로 발화하는 이벤트 — 재수립(resync)·멈춘 사유(fatal)·미연결 지속(stalled)을 SDK가 알아채 알립니다\n */\nexport const SDK_EVENTS = {\n resync: 'resync',\n fatal: 'fatal',\n stalled: 'stalled',\n} as const;\n\n/**\n * @description 소비처로 배달하는 이름들 — 출처(서버·SDK)와 무관하게 \"소비처가 보는가\"만 봅니다.\n * 워커는 구독 장부와 별개로 이 목록을 중계해야 합니다: 장부만 보고 붙이면 소비처에 영영 도달하지 않습니다.\n * SDK 이벤트는 배달이 곧 존재 이유라 전부 파생합니다 — 나열하면 이름을 늘릴 때 빠뜨릴 자리가 생깁니다.\n * 서버 연결 이벤트는 SDK가 소비하는 게 기본이라 배달할 것만 골라 넣습니다:\n * goaway는 SDK가 action으로 재연결을 판단하고, 소비처는 reason으로 안내를 정합니다.\n */\nexport const FORWARDED_EVENTS = [\n ...Object.values(SDK_EVENTS),\n SERVER_CONNECTION_EVENTS.goaway,\n] as const;\n\n// 멤버십 검사는 Set 파생으로 — Object.hasOwn(Safari 15.4+)이 배포 하한을 만들지 않게 합니다\nconst SERVER_CONNECTION_EVENT_NAMES: ReadonlySet<string> = new Set(\n Object.values(SERVER_CONNECTION_EVENTS)\n);\n\nconst FORWARDED_EVENT_NAMES: ReadonlySet<string> = new Set(FORWARDED_EVENTS);\n\nconst isServerConnectionEvent = (type: string): boolean =>\n SERVER_CONNECTION_EVENT_NAMES.has(type);\n\nconst isForwardedEvent = (type: string): boolean =>\n FORWARDED_EVENT_NAMES.has(type);\n\n/**\n * @description 서버 스트림에 구독을 걸 이름인지 판정합니다 — 연결 이벤트와 중계 목록은 SDK가 소유합니다.\n * 목록에서 판정을 파생해야 이름을 추가할 때 구독 제외가 따라옵니다: 빠지면 워커가 같은 이벤트를 두 번 배달합니다.\n */\nexport const isSubscribableEvent = (type: string): boolean =>\n !isServerConnectionEvent(type) && !isForwardedEvent(type);\n\n/**\n * @description 구독해도 배달되지 않는 이름인지 판정합니다 — 조용한 무배달 구독을 경고로 알리는 데 씁니다.\n * 중계 목록에 있으면 SDK가 소비하더라도 소비처에 배달되므로 경고 대상이 아닙니다.\n */\nexport const isUndeliverableEvent = (type: string): boolean =>\n isServerConnectionEvent(type) && !isForwardedEvent(type);\n"],"names":["SERVER_CONNECTION_EVENTS","hello","goaway","SDK_EVENTS","resync","fatal","stalled","FORWARDED_EVENTS","concat","_toConsumableArray","Object","values","SERVER_CONNECTION_EVENT_NAMES","Set","FORWARDED_EVENT_NAMES","isServerConnectionEvent","type","has","isForwardedEvent","isSubscribableEvent","isUndeliverableEvent"],"mappings":";;AAAA;AACO,IAAMA,wBAAwB,GAAG;AACtCC,EAAAA,KAAK,EAAE,OAAO;AACdC,EAAAA,MAAM,EAAE;AACV;;AAEA;AACA;AACA;AACO,IAAMC,UAAU,GAAG;AACxBC,EAAAA,MAAM,EAAE,QAAQ;AAChBC,EAAAA,KAAK,EAAE,OAAO;AACdC,EAAAA,OAAO,EAAE;AACX;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;IACaC,gBAAgB,GAAA,EAAA,CAAAC,MAAA,CAAAC,kBAAA,CACxBC,MAAM,CAACC,MAAM,CAACR,UAAU,CAAC,IAC5BH,wBAAwB,CAACE,MAAM,CAAA;;AAGjC;AACA,IAAMU,6BAAkD,GAAG,IAAIC,GAAG,CAChEH,MAAM,CAACC,MAAM,CAACX,wBAAwB,CACxC,CAAC;AAED,IAAMc,qBAA0C,GAAG,IAAID,GAAG,CAACN,gBAAgB,CAAC;AAE5E,IAAMQ,uBAAuB,GAAG,SAA1BA,uBAAuBA,CAAIC,IAAY,EAAA;AAAA,EAAA,OAC3CJ,6BAA6B,CAACK,GAAG,CAACD,IAAI,CAAC;AAAA,CAAA;AAEzC,IAAME,gBAAgB,GAAG,SAAnBA,gBAAgBA,CAAIF,IAAY,EAAA;AAAA,EAAA,OACpCF,qBAAqB,CAACG,GAAG,CAACD,IAAI,CAAC;AAAA,CAAA;;AAEjC;AACA;AACA;AACA;IACaG,mBAAmB,GAAG,SAAtBA,mBAAmBA,CAAIH,IAAY,EAAA;EAAA,OAC9C,CAACD,uBAAuB,CAACC,IAAI,CAAC,IAAI,CAACE,gBAAgB,CAACF,IAAI,CAAC;AAAA;;AAE3D;AACA;AACA;AACA;IACaI,oBAAoB,GAAG,SAAvBA,oBAAoBA,CAAIJ,IAAY,EAAA;EAAA,OAC/CD,uBAAuB,CAACC,IAAI,CAAC,IAAI,CAACE,gBAAgB,CAACF,IAAI,CAAC;AAAA;;;;"}
@@ -0,0 +1,20 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * @description 재시도 대기 Promise — 타이머 만료·abort 중 먼저 발생하는 쪽에서 resolve됩니다.
5
+ * 어느 경로로 풀리든 타이머와 abort 리스너를 함께 정리합니다.
6
+ */
7
+ var waitForRetry = function waitForRetry(delayMs, signal) {
8
+ return new Promise(function (resolve) {
9
+ var finish = function finish() {
10
+ clearTimeout(timer);
11
+ signal.removeEventListener('abort', finish);
12
+ resolve();
13
+ };
14
+ var timer = setTimeout(finish, delayMs);
15
+ signal.addEventListener('abort', finish);
16
+ });
17
+ };
18
+
19
+ exports.waitForRetry = waitForRetry;
20
+ //# sourceMappingURL=retryWait.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retryWait.cjs.js","sources":["../../../src/core/retryWait.ts"],"sourcesContent":["/**\n * @description 재시도 대기 Promise — 타이머 만료·abort 중 먼저 발생하는 쪽에서 resolve됩니다.\n * 어느 경로로 풀리든 타이머와 abort 리스너를 함께 정리합니다.\n */\nexport const waitForRetry = (\n delayMs: number,\n signal: AbortSignal\n): Promise<void> =>\n new Promise((resolve) => {\n const finish = () => {\n clearTimeout(timer);\n signal.removeEventListener('abort', finish);\n resolve();\n };\n\n const timer = setTimeout(finish, delayMs);\n signal.addEventListener('abort', finish);\n });\n"],"names":["waitForRetry","delayMs","signal","Promise","resolve","finish","clearTimeout","timer","removeEventListener","setTimeout","addEventListener"],"mappings":";;AAAA;AACA;AACA;AACA;AACO,IAAMA,YAAY,GAAG,SAAfA,YAAYA,CACvBC,OAAe,EACfC,MAAmB,EAAA;AAAA,EAAA,OAEnB,IAAIC,OAAO,CAAC,UAACC,OAAO,EAAK;AACvB,IAAA,IAAMC,MAAM,GAAG,SAATA,MAAMA,GAAS;MACnBC,YAAY,CAACC,KAAK,CAAC;AACnBL,MAAAA,MAAM,CAACM,mBAAmB,CAAC,OAAO,EAAEH,MAAM,CAAC;AAC3CD,MAAAA,OAAO,EAAE;KACV;AAED,IAAA,IAAMG,KAAK,GAAGE,UAAU,CAACJ,MAAM,EAAEJ,OAAO,CAAC;AACzCC,IAAAA,MAAM,CAACQ,gBAAgB,CAAC,OAAO,EAAEL,MAAM,CAAC;AAC1C,GAAC,CAAC;AAAA;;;;"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @description 재시도 대기 Promise — 타이머 만료·abort 중 먼저 발생하는 쪽에서 resolve됩니다.
3
+ * 어느 경로로 풀리든 타이머와 abort 리스너를 함께 정리합니다.
4
+ */
5
+ export declare const waitForRetry: (delayMs: number, signal: AbortSignal) => Promise<void>;
6
+ //# sourceMappingURL=retryWait.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retryWait.d.ts","sourceRoot":"","sources":["../../../src/core/retryWait.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,YAAY,YACd,MAAM,UACP,WAAW,KAClB,QAAQ,IAAI,CAUX,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @description 재시도 대기 Promise — 타이머 만료·abort 중 먼저 발생하는 쪽에서 resolve됩니다.
3
+ * 어느 경로로 풀리든 타이머와 abort 리스너를 함께 정리합니다.
4
+ */
5
+ var waitForRetry = function waitForRetry(delayMs, signal) {
6
+ return new Promise(function (resolve) {
7
+ var finish = function finish() {
8
+ clearTimeout(timer);
9
+ signal.removeEventListener('abort', finish);
10
+ resolve();
11
+ };
12
+ var timer = setTimeout(finish, delayMs);
13
+ signal.addEventListener('abort', finish);
14
+ });
15
+ };
16
+
17
+ export { waitForRetry };
18
+ //# sourceMappingURL=retryWait.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retryWait.esm.js","sources":["../../../src/core/retryWait.ts"],"sourcesContent":["/**\n * @description 재시도 대기 Promise — 타이머 만료·abort 중 먼저 발생하는 쪽에서 resolve됩니다.\n * 어느 경로로 풀리든 타이머와 abort 리스너를 함께 정리합니다.\n */\nexport const waitForRetry = (\n delayMs: number,\n signal: AbortSignal\n): Promise<void> =>\n new Promise((resolve) => {\n const finish = () => {\n clearTimeout(timer);\n signal.removeEventListener('abort', finish);\n resolve();\n };\n\n const timer = setTimeout(finish, delayMs);\n signal.addEventListener('abort', finish);\n });\n"],"names":["waitForRetry","delayMs","signal","Promise","resolve","finish","clearTimeout","timer","removeEventListener","setTimeout","addEventListener"],"mappings":"AAAA;AACA;AACA;AACA;AACO,IAAMA,YAAY,GAAG,SAAfA,YAAYA,CACvBC,OAAe,EACfC,MAAmB,EAAA;AAAA,EAAA,OAEnB,IAAIC,OAAO,CAAC,UAACC,OAAO,EAAK;AACvB,IAAA,IAAMC,MAAM,GAAG,SAATA,MAAMA,GAAS;MACnBC,YAAY,CAACC,KAAK,CAAC;AACnBL,MAAAA,MAAM,CAACM,mBAAmB,CAAC,OAAO,EAAEH,MAAM,CAAC;AAC3CD,MAAAA,OAAO,EAAE;KACV;AAED,IAAA,IAAMG,KAAK,GAAGE,UAAU,CAACJ,MAAM,EAAEJ,OAAO,CAAC;AACzCC,IAAAA,MAAM,CAACQ,gBAAgB,CAAC,OAAO,EAAEL,MAAM,CAAC;AAC1C,GAAC,CAAC;AAAA;;;;"}
@@ -0,0 +1,56 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * @description 상태 전이 규칙을 명시합니다
5
+ */
6
+ var TRANSITIONS = {
7
+ idle: {
8
+ connect: 'connecting',
9
+ disconnect: 'closed'
10
+ },
11
+ connecting: {
12
+ hello: 'open',
13
+ retryableFailure: 'reconnecting',
14
+ fatalFailure: 'fatal',
15
+ disconnect: 'closed'
16
+ },
17
+ open: {
18
+ retryableFailure: 'reconnecting',
19
+ fatalFailure: 'fatal',
20
+ disconnect: 'closed'
21
+ },
22
+ reconnecting: {
23
+ readyToRetry: 'connecting',
24
+ disconnect: 'closed'
25
+ },
26
+ // closed 후 재연결을 열어둔 이유: React StrictMode 재마운트가 같은 인스턴스로 connect→disconnect→connect를 수행합니다
27
+ closed: {
28
+ connect: 'connecting'
29
+ },
30
+ fatal: {
31
+ disconnect: 'closed'
32
+ }
33
+ };
34
+
35
+ /** @description 연결 상태머신 — 표에 선언된 전이만 수행하고, 전이가 일어날 때 onChange를 호출합니다 */
36
+ var createStatusMachine = function createStatusMachine(onChange) {
37
+ var status = 'idle';
38
+ return {
39
+ get status() {
40
+ return status;
41
+ },
42
+ transition: function transition(event) {
43
+ var transitions = TRANSITIONS[status];
44
+ var next = transitions[event];
45
+ if (next === undefined) {
46
+ return false;
47
+ }
48
+ status = next;
49
+ onChange(next);
50
+ return true;
51
+ }
52
+ };
53
+ };
54
+
55
+ exports.createStatusMachine = createStatusMachine;
56
+ //# sourceMappingURL=statusMachine.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"statusMachine.cjs.js","sources":["../../../src/core/statusMachine.ts"],"sourcesContent":["import type { SseStatus } from './types';\n\nexport type TransitionEvent =\n | 'connect'\n | 'hello'\n | 'retryableFailure'\n | 'fatalFailure'\n | 'readyToRetry'\n | 'disconnect';\n\n/**\n * @description 상태 전이 규칙을 명시합니다\n */\nconst TRANSITIONS = {\n idle: { connect: 'connecting', disconnect: 'closed' },\n connecting: {\n hello: 'open',\n retryableFailure: 'reconnecting',\n fatalFailure: 'fatal',\n disconnect: 'closed',\n },\n open: {\n retryableFailure: 'reconnecting',\n fatalFailure: 'fatal',\n disconnect: 'closed',\n },\n reconnecting: { readyToRetry: 'connecting', disconnect: 'closed' },\n // closed 후 재연결을 열어둔 이유: React StrictMode 재마운트가 같은 인스턴스로 connect→disconnect→connect를 수행합니다\n closed: { connect: 'connecting' },\n fatal: { disconnect: 'closed' },\n} satisfies Record<SseStatus, Partial<Record<TransitionEvent, SseStatus>>>;\n\n/** @description 연결 상태머신 — 표에 선언된 전이만 수행하고, 전이가 일어날 때 onChange를 호출합니다 */\nexport const createStatusMachine = (onChange: (status: SseStatus) => void) => {\n let status: SseStatus = 'idle';\n\n return {\n get status(): SseStatus {\n return status;\n },\n transition: (event: TransitionEvent): boolean => {\n const transitions: Partial<Record<TransitionEvent, SseStatus>> =\n TRANSITIONS[status];\n const next = transitions[event];\n if (next === undefined) {\n return false;\n }\n\n status = next;\n onChange(next);\n return true;\n },\n };\n};\n\nexport type StatusMachine = ReturnType<typeof createStatusMachine>;\n"],"names":["TRANSITIONS","idle","connect","disconnect","connecting","hello","retryableFailure","fatalFailure","open","reconnecting","readyToRetry","closed","fatal","createStatusMachine","onChange","status","transition","event","transitions","next","undefined"],"mappings":";;AAUA;AACA;AACA;AACA,IAAMA,WAAW,GAAG;AAClBC,EAAAA,IAAI,EAAE;AAAEC,IAAAA,OAAO,EAAE,YAAY;AAAEC,IAAAA,UAAU,EAAE;GAAU;AACrDC,EAAAA,UAAU,EAAE;AACVC,IAAAA,KAAK,EAAE,MAAM;AACbC,IAAAA,gBAAgB,EAAE,cAAc;AAChCC,IAAAA,YAAY,EAAE,OAAO;AACrBJ,IAAAA,UAAU,EAAE;GACb;AACDK,EAAAA,IAAI,EAAE;AACJF,IAAAA,gBAAgB,EAAE,cAAc;AAChCC,IAAAA,YAAY,EAAE,OAAO;AACrBJ,IAAAA,UAAU,EAAE;GACb;AACDM,EAAAA,YAAY,EAAE;AAAEC,IAAAA,YAAY,EAAE,YAAY;AAAEP,IAAAA,UAAU,EAAE;GAAU;AAClE;AACAQ,EAAAA,MAAM,EAAE;AAAET,IAAAA,OAAO,EAAE;GAAc;AACjCU,EAAAA,KAAK,EAAE;AAAET,IAAAA,UAAU,EAAE;AAAS;AAChC,CAA0E;;AAE1E;IACaU,mBAAmB,GAAG,SAAtBA,mBAAmBA,CAAIC,QAAqC,EAAK;EAC5E,IAAIC,MAAiB,GAAG,MAAM;EAE9B,OAAO;IACL,IAAIA,MAAMA,GAAc;AACtB,MAAA,OAAOA,MAAM;KACd;AACDC,IAAAA,UAAU,EAAE,SAAAA,UAAAA,CAACC,KAAsB,EAAc;AAC/C,MAAA,IAAMC,WAAwD,GAC5DlB,WAAW,CAACe,MAAM,CAAC;AACrB,MAAA,IAAMI,IAAI,GAAGD,WAAW,CAACD,KAAK,CAAC;MAC/B,IAAIE,IAAI,KAAKC,SAAS,EAAE;AACtB,QAAA,OAAO,KAAK;AACd;AAEAL,MAAAA,MAAM,GAAGI,IAAI;MACbL,QAAQ,CAACK,IAAI,CAAC;AACd,MAAA,OAAO,IAAI;AACb;GACD;AACH;;;;"}
@@ -0,0 +1,9 @@
1
+ import type { SseStatus } from './types';
2
+ export type TransitionEvent = 'connect' | 'hello' | 'retryableFailure' | 'fatalFailure' | 'readyToRetry' | 'disconnect';
3
+ /** @description 연결 상태머신 — 표에 선언된 전이만 수행하고, 전이가 일어날 때 onChange를 호출합니다 */
4
+ export declare const createStatusMachine: (onChange: (status: SseStatus) => void) => {
5
+ readonly status: "idle" | "connecting" | "open" | "reconnecting" | "closed" | "fatal";
6
+ transition: (event: TransitionEvent) => boolean;
7
+ };
8
+ export type StatusMachine = ReturnType<typeof createStatusMachine>;
9
+ //# sourceMappingURL=statusMachine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"statusMachine.d.ts","sourceRoot":"","sources":["../../../src/core/statusMachine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzC,MAAM,MAAM,eAAe,GACvB,SAAS,GACT,OAAO,GACP,kBAAkB,GAClB,cAAc,GACd,cAAc,GACd,YAAY,CAAC;AAwBjB,wEAAwE;AACxE,eAAO,MAAM,mBAAmB,aAAc,CAAC,MAAM,EAAE,SAAS,KAAK,IAAI;;wBAOjD,eAAe,KAAG,OAAO;CAahD,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * @description 상태 전이 규칙을 명시합니다
3
+ */
4
+ var TRANSITIONS = {
5
+ idle: {
6
+ connect: 'connecting',
7
+ disconnect: 'closed'
8
+ },
9
+ connecting: {
10
+ hello: 'open',
11
+ retryableFailure: 'reconnecting',
12
+ fatalFailure: 'fatal',
13
+ disconnect: 'closed'
14
+ },
15
+ open: {
16
+ retryableFailure: 'reconnecting',
17
+ fatalFailure: 'fatal',
18
+ disconnect: 'closed'
19
+ },
20
+ reconnecting: {
21
+ readyToRetry: 'connecting',
22
+ disconnect: 'closed'
23
+ },
24
+ // closed 후 재연결을 열어둔 이유: React StrictMode 재마운트가 같은 인스턴스로 connect→disconnect→connect를 수행합니다
25
+ closed: {
26
+ connect: 'connecting'
27
+ },
28
+ fatal: {
29
+ disconnect: 'closed'
30
+ }
31
+ };
32
+
33
+ /** @description 연결 상태머신 — 표에 선언된 전이만 수행하고, 전이가 일어날 때 onChange를 호출합니다 */
34
+ var createStatusMachine = function createStatusMachine(onChange) {
35
+ var status = 'idle';
36
+ return {
37
+ get status() {
38
+ return status;
39
+ },
40
+ transition: function transition(event) {
41
+ var transitions = TRANSITIONS[status];
42
+ var next = transitions[event];
43
+ if (next === undefined) {
44
+ return false;
45
+ }
46
+ status = next;
47
+ onChange(next);
48
+ return true;
49
+ }
50
+ };
51
+ };
52
+
53
+ export { createStatusMachine };
54
+ //# sourceMappingURL=statusMachine.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"statusMachine.esm.js","sources":["../../../src/core/statusMachine.ts"],"sourcesContent":["import type { SseStatus } from './types';\n\nexport type TransitionEvent =\n | 'connect'\n | 'hello'\n | 'retryableFailure'\n | 'fatalFailure'\n | 'readyToRetry'\n | 'disconnect';\n\n/**\n * @description 상태 전이 규칙을 명시합니다\n */\nconst TRANSITIONS = {\n idle: { connect: 'connecting', disconnect: 'closed' },\n connecting: {\n hello: 'open',\n retryableFailure: 'reconnecting',\n fatalFailure: 'fatal',\n disconnect: 'closed',\n },\n open: {\n retryableFailure: 'reconnecting',\n fatalFailure: 'fatal',\n disconnect: 'closed',\n },\n reconnecting: { readyToRetry: 'connecting', disconnect: 'closed' },\n // closed 후 재연결을 열어둔 이유: React StrictMode 재마운트가 같은 인스턴스로 connect→disconnect→connect를 수행합니다\n closed: { connect: 'connecting' },\n fatal: { disconnect: 'closed' },\n} satisfies Record<SseStatus, Partial<Record<TransitionEvent, SseStatus>>>;\n\n/** @description 연결 상태머신 — 표에 선언된 전이만 수행하고, 전이가 일어날 때 onChange를 호출합니다 */\nexport const createStatusMachine = (onChange: (status: SseStatus) => void) => {\n let status: SseStatus = 'idle';\n\n return {\n get status(): SseStatus {\n return status;\n },\n transition: (event: TransitionEvent): boolean => {\n const transitions: Partial<Record<TransitionEvent, SseStatus>> =\n TRANSITIONS[status];\n const next = transitions[event];\n if (next === undefined) {\n return false;\n }\n\n status = next;\n onChange(next);\n return true;\n },\n };\n};\n\nexport type StatusMachine = ReturnType<typeof createStatusMachine>;\n"],"names":["TRANSITIONS","idle","connect","disconnect","connecting","hello","retryableFailure","fatalFailure","open","reconnecting","readyToRetry","closed","fatal","createStatusMachine","onChange","status","transition","event","transitions","next","undefined"],"mappings":"AAUA;AACA;AACA;AACA,IAAMA,WAAW,GAAG;AAClBC,EAAAA,IAAI,EAAE;AAAEC,IAAAA,OAAO,EAAE,YAAY;AAAEC,IAAAA,UAAU,EAAE;GAAU;AACrDC,EAAAA,UAAU,EAAE;AACVC,IAAAA,KAAK,EAAE,MAAM;AACbC,IAAAA,gBAAgB,EAAE,cAAc;AAChCC,IAAAA,YAAY,EAAE,OAAO;AACrBJ,IAAAA,UAAU,EAAE;GACb;AACDK,EAAAA,IAAI,EAAE;AACJF,IAAAA,gBAAgB,EAAE,cAAc;AAChCC,IAAAA,YAAY,EAAE,OAAO;AACrBJ,IAAAA,UAAU,EAAE;GACb;AACDM,EAAAA,YAAY,EAAE;AAAEC,IAAAA,YAAY,EAAE,YAAY;AAAEP,IAAAA,UAAU,EAAE;GAAU;AAClE;AACAQ,EAAAA,MAAM,EAAE;AAAET,IAAAA,OAAO,EAAE;GAAc;AACjCU,EAAAA,KAAK,EAAE;AAAET,IAAAA,UAAU,EAAE;AAAS;AAChC,CAA0E;;AAE1E;IACaU,mBAAmB,GAAG,SAAtBA,mBAAmBA,CAAIC,QAAqC,EAAK;EAC5E,IAAIC,MAAiB,GAAG,MAAM;EAE9B,OAAO;IACL,IAAIA,MAAMA,GAAc;AACtB,MAAA,OAAOA,MAAM;KACd;AACDC,IAAAA,UAAU,EAAE,SAAAA,UAAAA,CAACC,KAAsB,EAAc;AAC/C,MAAA,IAAMC,WAAwD,GAC5DlB,WAAW,CAACe,MAAM,CAAC;AACrB,MAAA,IAAMI,IAAI,GAAGD,WAAW,CAACD,KAAK,CAAC;MAC/B,IAAIE,IAAI,KAAKC,SAAS,EAAE;AACtB,QAAA,OAAO,KAAK;AACd;AAEAL,MAAAA,MAAM,GAAGI,IAAI;MACbL,QAAQ,CAACK,IAAI,CAAC;AACd,MAAA,OAAO,IAAI;AACb;GACD;AACH;;;;"}
@@ -0,0 +1,136 @@
1
+ 'use strict';
2
+
3
+ var _defineProperty = require('@babel/runtime/helpers/defineProperty');
4
+ var _typeof = require('@babel/runtime/helpers/typeof');
5
+ var eventNames = require('./eventNames.cjs.js');
6
+ var types = require('./types.cjs.js');
7
+
8
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
9
+
10
+ var _defineProperty__default = /*#__PURE__*/_interopDefault(_defineProperty);
11
+ var _typeof__default = /*#__PURE__*/_interopDefault(_typeof);
12
+
13
+ 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; }
14
+ 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; }
15
+
16
+ /**
17
+ * @description 스트림이 끊긴 이유.
18
+ * goaway는 서버가 예고하고 닫는 정상 종료라 백오프 없이 즉시 재수립하고,
19
+ * goaway-close는 서버가 재연결하지 말라고 한 것이라 루프를 끝냅니다.
20
+ */
21
+
22
+ /**
23
+ * @description 끊김의 전말 — goaway 계열에만 페이로드가 붙습니다.
24
+ * 유니온으로 묶어 "outcome이 goaway일 때만 payload가 있다"를 타입이 강제하게 합니다.
25
+ */
26
+
27
+ /**
28
+ * @description 한 EventSource에 리스너를 이미 건 이벤트 이름들 — 중복 부착을 막는 장부입니다.
29
+ * 소스가 바뀌면 리스너도 함께 사라지므로, 이 장부는 소스와 수명을 같이해야 합니다.
30
+ */
31
+
32
+ var parsePayload = function parsePayload(event) {
33
+ if (typeof event.data !== 'string' || event.data === '') {
34
+ return undefined;
35
+ }
36
+ try {
37
+ return JSON.parse(event.data);
38
+ } catch (_unused) {
39
+ return event.data;
40
+ }
41
+ };
42
+
43
+ // 구버전 서버·잘린 프레임에서는 필드가 없거나 미지 값이 옵니다 — 아는 값만 남기고 나머지는 버립니다
44
+ var toGoawayPayload = function toGoawayPayload(parsed) {
45
+ if (_typeof__default.default(parsed) !== 'object' || parsed === null) {
46
+ return {};
47
+ }
48
+ var _ref = parsed,
49
+ reason = _ref.reason,
50
+ action = _ref.action;
51
+ return _objectSpread(_objectSpread({}, types.isGoawayReason(reason) && {
52
+ reason: reason
53
+ }), types.isGoawayAction(action) && {
54
+ action: action
55
+ });
56
+ };
57
+
58
+ /**
59
+ * @description 도메인 이벤트 리스너를 소스에 1회 부착합니다 — SDK 예약 이벤트는 소비처로 흘리지 않습니다
60
+ */
61
+ var attachDomainListener = function attachDomainListener(source, attachedEvents, type, deliver) {
62
+ if (attachedEvents.has(type)) {
63
+ return;
64
+ }
65
+ if (!eventNames.isSubscribableEvent(type)) {
66
+ return;
67
+ }
68
+ attachedEvents.add(type);
69
+ source.addEventListener(type, function (event) {
70
+ deliver(type, parsePayload(event));
71
+ });
72
+ };
73
+ /**
74
+ * @description 콜백 세계(EventSource 이벤트·타이머·abort)를 Promise 하나로 바꾸는 경계 어댑터.
75
+ * 아래 결말 4개 중 먼저 발생하는 것으로 정확히 한 번 끝나고, hello는 결말이 아니라 수립 신호입니다.
76
+ */
77
+ var streamUntilClosed = function streamUntilClosed(source, signal, hooks) {
78
+ return new Promise(function (resolve) {
79
+ var settled = false;
80
+ var settle = function settle(closure, options) {
81
+ if (settled) {
82
+ return;
83
+ }
84
+ settled = true;
85
+ clearTimeout(helloTimer);
86
+ signal.removeEventListener('abort', onAbort);
87
+ if (options.notifyClosed) {
88
+ hooks.onClosed(closure);
89
+ }
90
+ resolve(closure.outcome);
91
+ };
92
+ var helloTimer = setTimeout(function () {
93
+ return settle({
94
+ outcome: 'error'
95
+ }, {
96
+ notifyClosed: true
97
+ });
98
+ }, hooks.helloTimeoutMs);
99
+ source.addEventListener(eventNames.SERVER_CONNECTION_EVENTS.goaway, function (event) {
100
+ var goaway = toGoawayPayload(parsePayload(event));
101
+ settle({
102
+ outcome: goaway.action === 'close' ? 'goaway-close' : 'goaway',
103
+ goaway: goaway
104
+ }, {
105
+ notifyClosed: true
106
+ });
107
+ });
108
+ source.onerror = function () {
109
+ return settle({
110
+ outcome: 'error'
111
+ }, {
112
+ notifyClosed: true
113
+ });
114
+ };
115
+ var onAbort = function onAbort() {
116
+ return settle({
117
+ outcome: 'error'
118
+ }, {
119
+ notifyClosed: false
120
+ });
121
+ };
122
+ signal.addEventListener('abort', onAbort);
123
+ source.addEventListener(eventNames.SERVER_CONNECTION_EVENTS.hello, function () {
124
+ if (settled) {
125
+ return;
126
+ }
127
+ if (hooks.onHello()) {
128
+ clearTimeout(helloTimer);
129
+ }
130
+ });
131
+ });
132
+ };
133
+
134
+ exports.attachDomainListener = attachDomainListener;
135
+ exports.streamUntilClosed = streamUntilClosed;
136
+ //# sourceMappingURL=stream.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream.cjs.js","sources":["../../../src/core/stream.ts"],"sourcesContent":["import { isSubscribableEvent, SERVER_CONNECTION_EVENTS } from './eventNames';\nimport type { GoawayPayload } from './types';\nimport { isGoawayAction, isGoawayReason } from './types';\n\n/**\n * @description 스트림이 끊긴 이유.\n * goaway는 서버가 예고하고 닫는 정상 종료라 백오프 없이 즉시 재수립하고,\n * goaway-close는 서버가 재연결하지 말라고 한 것이라 루프를 끝냅니다.\n */\nexport type StreamOutcome = 'error' | 'goaway' | 'goaway-close';\n\n/**\n * @description 끊김의 전말 — goaway 계열에만 페이로드가 붙습니다.\n * 유니온으로 묶어 \"outcome이 goaway일 때만 payload가 있다\"를 타입이 강제하게 합니다.\n */\nexport type StreamClosure =\n | { outcome: 'error' }\n | { outcome: 'goaway' | 'goaway-close'; goaway: GoawayPayload };\n\n/**\n * @description 한 EventSource에 리스너를 이미 건 이벤트 이름들 — 중복 부착을 막는 장부입니다.\n * 소스가 바뀌면 리스너도 함께 사라지므로, 이 장부는 소스와 수명을 같이해야 합니다.\n */\nexport type AttachedEvents = Set<string>;\n\nconst parsePayload = (event: { data?: unknown }): unknown => {\n if (typeof event.data !== 'string' || event.data === '') {\n return undefined;\n }\n try {\n return JSON.parse(event.data);\n } catch {\n return event.data;\n }\n};\n\n// 구버전 서버·잘린 프레임에서는 필드가 없거나 미지 값이 옵니다 — 아는 값만 남기고 나머지는 버립니다\nconst toGoawayPayload = (parsed: unknown): GoawayPayload => {\n if (typeof parsed !== 'object' || parsed === null) {\n return {};\n }\n\n const { reason, action } = parsed as { reason?: unknown; action?: unknown };\n\n return {\n ...(isGoawayReason(reason) && { reason }),\n ...(isGoawayAction(action) && { action }),\n };\n};\n\n/**\n * @description 도메인 이벤트 리스너를 소스에 1회 부착합니다 — SDK 예약 이벤트는 소비처로 흘리지 않습니다\n */\nexport const attachDomainListener = (\n source: EventSource,\n attachedEvents: AttachedEvents,\n type: string,\n deliver: (type: string, payload: unknown) => void\n): void => {\n if (attachedEvents.has(type)) {\n return;\n }\n if (!isSubscribableEvent(type)) {\n return;\n }\n\n attachedEvents.add(type);\n source.addEventListener(type, (event) => {\n deliver(type, parsePayload(event));\n });\n};\n\nexport interface StreamHooks {\n helloTimeoutMs: number;\n /** @description hello 프레임 수신 — 수립으로 인정하면 true를 반환해 타임아웃을 해제시킵니다 */\n onHello: () => boolean;\n /**\n * @description 끊김 확정 — resolve 전에 동기로 호출됩니다 (정리·상태 전이는 호출자 몫).\n * goaway면 페이로드가 함께 옵니다: 소비처가 reason으로 안내를 정하도록 그대로 넘깁니다.\n */\n onClosed: (closure: StreamClosure) => void;\n}\n\n/**\n * @description 콜백 세계(EventSource 이벤트·타이머·abort)를 Promise 하나로 바꾸는 경계 어댑터.\n * 아래 결말 4개 중 먼저 발생하는 것으로 정확히 한 번 끝나고, hello는 결말이 아니라 수립 신호입니다.\n */\nexport const streamUntilClosed = (\n source: EventSource,\n signal: AbortSignal,\n hooks: StreamHooks\n): Promise<StreamOutcome> =>\n new Promise((resolve) => {\n let settled = false;\n\n const settle = (\n closure: StreamClosure,\n options: { notifyClosed: boolean }\n ) => {\n if (settled) {\n return;\n }\n settled = true;\n clearTimeout(helloTimer);\n signal.removeEventListener('abort', onAbort);\n if (options.notifyClosed) {\n hooks.onClosed(closure);\n }\n resolve(closure.outcome);\n };\n\n const helloTimer = setTimeout(\n () => settle({ outcome: 'error' }, { notifyClosed: true }),\n hooks.helloTimeoutMs\n );\n\n source.addEventListener(SERVER_CONNECTION_EVENTS.goaway, (event) => {\n const goaway = toGoawayPayload(parsePayload(event));\n settle(\n {\n outcome: goaway.action === 'close' ? 'goaway-close' : 'goaway',\n goaway,\n },\n { notifyClosed: true }\n );\n });\n\n source.onerror = () => settle({ outcome: 'error' }, { notifyClosed: true });\n\n const onAbort = () => settle({ outcome: 'error' }, { notifyClosed: false });\n signal.addEventListener('abort', onAbort);\n\n source.addEventListener(SERVER_CONNECTION_EVENTS.hello, () => {\n if (settled) {\n return;\n }\n if (hooks.onHello()) {\n clearTimeout(helloTimer);\n }\n });\n });\n"],"names":["parsePayload","event","data","undefined","JSON","parse","_unused","toGoawayPayload","parsed","_typeof","_ref","reason","action","_objectSpread","isGoawayReason","isGoawayAction","attachDomainListener","source","attachedEvents","type","deliver","has","isSubscribableEvent","add","addEventListener","streamUntilClosed","signal","hooks","Promise","resolve","settled","settle","closure","options","clearTimeout","helloTimer","removeEventListener","onAbort","notifyClosed","onClosed","outcome","setTimeout","helloTimeoutMs","SERVER_CONNECTION_EVENTS","goaway","onerror","hello","onHello"],"mappings":"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"}