@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,382 @@
1
+ 'use strict';
2
+
3
+ var _asyncToGenerator = require('@babel/runtime/helpers/asyncToGenerator');
4
+ var _classCallCheck = require('@babel/runtime/helpers/classCallCheck');
5
+ var _createClass = require('@babel/runtime/helpers/createClass');
6
+ var _possibleConstructorReturn = require('@babel/runtime/helpers/possibleConstructorReturn');
7
+ var _getPrototypeOf = require('@babel/runtime/helpers/getPrototypeOf');
8
+ var _inherits = require('@babel/runtime/helpers/inherits');
9
+ var _regeneratorRuntime = require('@babel/runtime/regenerator');
10
+ var backoff = require('./backoff.cjs.js');
11
+ var BaseSseClient = require('./BaseSseClient.cjs.js');
12
+ var eventNames = require('./eventNames.cjs.js');
13
+ var retryWait = require('./retryWait.cjs.js');
14
+ var statusMachine = require('./statusMachine.cjs.js');
15
+ var stream = require('./stream.cjs.js');
16
+ var ticket = require('./ticket.cjs.js');
17
+
18
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
19
+
20
+ var _asyncToGenerator__default = /*#__PURE__*/_interopDefault(_asyncToGenerator);
21
+ var _classCallCheck__default = /*#__PURE__*/_interopDefault(_classCallCheck);
22
+ var _createClass__default = /*#__PURE__*/_interopDefault(_createClass);
23
+ var _possibleConstructorReturn__default = /*#__PURE__*/_interopDefault(_possibleConstructorReturn);
24
+ var _getPrototypeOf__default = /*#__PURE__*/_interopDefault(_getPrototypeOf);
25
+ var _inherits__default = /*#__PURE__*/_interopDefault(_inherits);
26
+ var _regeneratorRuntime__default = /*#__PURE__*/_interopDefault(_regeneratorRuntime);
27
+
28
+ function _callSuper(t, o, e) { return o = _getPrototypeOf__default.default(o), _possibleConstructorReturn__default.default(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf__default.default(t).constructor) : o.apply(t, e)); }
29
+ function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
30
+ function _classPrivateMethodInitSpec(obj, privateSet) { _checkPrivateRedeclaration(obj, privateSet); privateSet.add(obj); }
31
+ function _classPrivateFieldInitSpec(obj, privateMap, value) { _checkPrivateRedeclaration(obj, privateMap); privateMap.set(obj, value); }
32
+ function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } }
33
+ function _classPrivateFieldGet(s, a) { return s.get(_assertClassBrand(s, a)); }
34
+ function _classPrivateFieldSet(s, a, r) { return s.set(_assertClassBrand(s, a), r), r; }
35
+ function _assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); }
36
+ // 상태 코드 → 사유 매핑이 단일 원천입니다 — 멈출 코드 판정과 사유가 같은 표에서 나와 어긋날 수 없습니다
37
+ var TICKET_FATAL_CAUSES = {
38
+ 401: 'auth',
39
+ 403: 'auth',
40
+ 429: 'rate_limit'
41
+ };
42
+ var isFatalTicketStatus = function isFatalTicketStatus(status) {
43
+ return status in TICKET_FATAL_CAUSES;
44
+ };
45
+ var HELLO_TIMEOUT_MS = 10000;
46
+
47
+ // 즉시 실패(CORS·오프라인)의 기본 백오프(full jitter) 기준 최대 15초, 보통 7~8초 안에 알립니다 — 순간 끊김에는 침묵합니다
48
+ var STALLED_AFTER_ATTEMPTS = 5;
49
+
50
+ /**
51
+ * @description 내부 확장 지점 — 워커가 티켓 발급을 탭에 위임할 때 씁니다.
52
+ * 공개 옵션(SseClientOptions)에는 노출하지 않습니다: 소비처가 티켓 발급 절차를 바꿀 이유가 없습니다.
53
+ */
54
+ var _backoff = /*#__PURE__*/new WeakMap();
55
+ var _machine = /*#__PURE__*/new WeakMap();
56
+ var _currentStream = /*#__PURE__*/new WeakMap();
57
+ var _abort = /*#__PURE__*/new WeakMap();
58
+ var _hasOpened = /*#__PURE__*/new WeakMap();
59
+ var _networkFailures = /*#__PURE__*/new WeakMap();
60
+ var _SseClient_brand = /*#__PURE__*/new WeakSet();
61
+ /** @description SSR 환경에서도 안전하게 생성할 수 있습니다 — 연결은 connect()를 호출할 때 시작됩니다 */
62
+ var SseClient = /*#__PURE__*/function (_BaseSseClient) {
63
+ function SseClient(options) {
64
+ var _internals$hasOpenedB;
65
+ var _this;
66
+ var internals = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
67
+ _classCallCheck__default.default(this, SseClient);
68
+ _this = _callSuper(this, SseClient, [options.logger]);
69
+ // 한 연결 세션을 접습니다 — 다음 connect()가 첫 연결처럼 시작하도록 재수립 판단과 백오프도 함께 되돌립니다
70
+ _classPrivateMethodInitSpec(_this, _SseClient_brand);
71
+ _classPrivateFieldInitSpec(_this, _backoff, void 0);
72
+ _classPrivateFieldInitSpec(_this, _machine, void 0);
73
+ _classPrivateFieldInitSpec(_this, _currentStream, null);
74
+ _classPrivateFieldInitSpec(_this, _abort, null);
75
+ _classPrivateFieldInitSpec(_this, _hasOpened, void 0);
76
+ _classPrivateFieldInitSpec(_this, _networkFailures, 0);
77
+ _this.options = options;
78
+ _this.internals = internals;
79
+ _classPrivateFieldSet(_hasOpened, _this, (_internals$hasOpenedB = internals.hasOpenedBefore) !== null && _internals$hasOpenedB !== void 0 ? _internals$hasOpenedB : false);
80
+ _classPrivateFieldSet(_backoff, _this, backoff.createBackoff(options.backoff));
81
+ _classPrivateFieldSet(_machine, _this, statusMachine.createStatusMachine(function (status) {
82
+ return _this.emitter.emitStatus(status);
83
+ }));
84
+ return _this;
85
+ }
86
+ _inherits__default.default(SseClient, _BaseSseClient);
87
+ return _createClass__default.default(SseClient, [{
88
+ key: "status",
89
+ get: function get() {
90
+ return _classPrivateFieldGet(_machine, this).status;
91
+ }
92
+ }, {
93
+ key: "connect",
94
+ value: function connect() {
95
+ var _this$options$eventSo,
96
+ _this2 = this;
97
+ if (((_this$options$eventSo = this.options.eventSource) !== null && _this$options$eventSo !== void 0 ? _this$options$eventSo : globalThis.EventSource) === undefined) {
98
+ // SSR 대응 - no-op
99
+ return;
100
+ }
101
+ var controller = new AbortController();
102
+ var previous = _classPrivateFieldGet(_abort, this);
103
+ // 전이 통지 중 리스너가 disconnect()해도 이 controller가 abort되도록 전이보다 먼저 교체합니다
104
+ _classPrivateFieldSet(_abort, this, controller);
105
+ if (!_classPrivateFieldGet(_machine, this).transition('connect')) {
106
+ _classPrivateFieldSet(_abort, this, previous);
107
+ if (_classPrivateFieldGet(_machine, this).status === 'fatal') {
108
+ var _this$options$logger;
109
+ (_this$options$logger = this.options.logger) === null || _this$options$logger === void 0 || _this$options$logger.warn('sse: fatal 상태에서는 connect()가 무시됩니다 — disconnect()로 정리한 뒤 다시 connect() 하세요');
110
+ }
111
+ return;
112
+ }
113
+ if (controller.signal.aborted) {
114
+ return;
115
+ }
116
+
117
+ // 루프가 예외로 죽으면 재시도가 영영 없습니다 — fatal로 떨어뜨려 회복 경로(정리 후 connect)에 맡깁니다
118
+ void _assertClassBrand(_SseClient_brand, this, _runConnection).call(this, controller.signal)["catch"](function (error) {
119
+ var _this2$options$logger;
120
+ (_this2$options$logger = _this2.options.logger) === null || _this2$options$logger === void 0 || _this2$options$logger.error('sse: 연결 루프가 예외로 중단됐습니다', error);
121
+ // 전이가 거부된 상태(reconnecting 등)에서 발화하면 "전이 후 발화" 계약이 깨집니다
122
+ if (_classPrivateFieldGet(_machine, _this2).transition('fatalFailure')) {
123
+ _this2.emitter.emit(eventNames.SDK_EVENTS.fatal, {
124
+ cause: 'unknown'
125
+ });
126
+ }
127
+ });
128
+ }
129
+ }, {
130
+ key: "disconnect",
131
+ value: function disconnect() {
132
+ var _classPrivateFieldGet2;
133
+ // abort가 연결 루프를 중단합니다 — 진행 중이던 티켓 발급·대기·스트림 전부
134
+ (_classPrivateFieldGet2 = _classPrivateFieldGet(_abort, this)) === null || _classPrivateFieldGet2 === void 0 || _classPrivateFieldGet2.abort();
135
+ _classPrivateFieldSet(_abort, this, null);
136
+ _assertClassBrand(_SseClient_brand, this, _endSession).call(this);
137
+ _classPrivateFieldGet(_machine, this).transition('disconnect');
138
+ }
139
+ }, {
140
+ key: "registerSubscription",
141
+ value:
142
+ // 열린 스트림이 없으면 조용히 넘어갑니다 — 다음 #openStream이 구독 장부를 보고 한 번에 붙입니다
143
+ function registerSubscription(type) {
144
+ _assertClassBrand(_SseClient_brand, this, _attachSourceListener).call(this, type);
145
+ }
146
+
147
+ // 티켓 발급 → 스트림 유지 → 끊김 → 대기 → 재시도. disconnect(abort)만이 루프를 종료합니다
148
+ }]);
149
+ }(BaseSseClient.BaseSseClient);
150
+ function _endSession() {
151
+ _assertClassBrand(_SseClient_brand, this, _closeStream).call(this);
152
+ _classPrivateFieldSet(_hasOpened, this, false);
153
+ _classPrivateFieldGet(_backoff, this).reset();
154
+ _classPrivateFieldSet(_networkFailures, this, 0);
155
+ }
156
+ /**
157
+ * @description hello에 닿지 못한 네트워크성(응답 status 부재) 연속 실패를 셉니다 — 임계값 도달 순간에만
158
+ * stalled를 발화해 한 구간에 한 번만 알립니다. 반드시 상태 전이 뒤에 부르세요.
159
+ * 연속은 open 도달과 서버 응답(5xx)이 끊고, 스트림 단계 실패는 status가 없어 전부 여기 해당합니다.
160
+ */
161
+ function _countNetworkFailure() {
162
+ _classPrivateFieldSet(_networkFailures, this, _classPrivateFieldGet(_networkFailures, this) + 1);
163
+ if (_classPrivateFieldGet(_networkFailures, this) === STALLED_AFTER_ATTEMPTS) {
164
+ this.emitter.emit(eventNames.SDK_EVENTS.stalled, undefined);
165
+ }
166
+ }
167
+ function _runConnection(_x) {
168
+ return _runConnection2.apply(this, arguments);
169
+ }
170
+ function _runConnection2() {
171
+ _runConnection2 = _asyncToGenerator__default.default(/*#__PURE__*/_regeneratorRuntime__default.default.mark(function _callee(signal) {
172
+ var next;
173
+ return _regeneratorRuntime__default.default.wrap(function _callee$(_context) {
174
+ while (1) switch (_context.prev = _context.next) {
175
+ case 0:
176
+ if (signal.aborted) {
177
+ _context.next = 14;
178
+ break;
179
+ }
180
+ _context.next = 3;
181
+ return _assertClassBrand(_SseClient_brand, this, _attemptConnection).call(this, signal);
182
+ case 3:
183
+ next = _context.sent;
184
+ if (!(signal.aborted || next === 'stop')) {
185
+ _context.next = 6;
186
+ break;
187
+ }
188
+ return _context.abrupt("return");
189
+ case 6:
190
+ if (!(next === 'retryWithDelay')) {
191
+ _context.next = 11;
192
+ break;
193
+ }
194
+ _context.next = 9;
195
+ return retryWait.waitForRetry(_classPrivateFieldGet(_backoff, this).nextDelayMs(), signal);
196
+ case 9:
197
+ if (!signal.aborted) {
198
+ _context.next = 11;
199
+ break;
200
+ }
201
+ return _context.abrupt("return");
202
+ case 11:
203
+ _classPrivateFieldGet(_machine, this).transition('readyToRetry');
204
+ _context.next = 0;
205
+ break;
206
+ case 14:
207
+ case "end":
208
+ return _context.stop();
209
+ }
210
+ }, _callee, this);
211
+ }));
212
+ return _runConnection2.apply(this, arguments);
213
+ }
214
+ // 스트림이 끊길 때까지 대기하고, 루프의 다음 동작('stop'·'retryWithDelay'·'retryNow')을 반환합니다
215
+ function _attemptConnection(_x2) {
216
+ return _attemptConnection2.apply(this, arguments);
217
+ }
218
+ function _attemptConnection2() {
219
+ _attemptConnection2 = _asyncToGenerator__default.default(/*#__PURE__*/_regeneratorRuntime__default.default.mark(function _callee2(signal) {
220
+ var _this$internals$issue, _this$internals$issue2, _this$internals;
221
+ var result, _result$error, status, cause, _this$options$logger2, outcome, _this$options$logger3;
222
+ return _regeneratorRuntime__default.default.wrap(function _callee2$(_context2) {
223
+ while (1) switch (_context2.prev = _context2.next) {
224
+ case 0:
225
+ _context2.next = 2;
226
+ return (_this$internals$issue = (_this$internals$issue2 = (_this$internals = this.internals).issueTicket) === null || _this$internals$issue2 === void 0 ? void 0 : _this$internals$issue2.call(_this$internals)) !== null && _this$internals$issue !== void 0 ? _this$internals$issue : ticket.issueTicketWithTimeout(this.options);
227
+ case 2:
228
+ result = _context2.sent;
229
+ if (!signal.aborted) {
230
+ _context2.next = 5;
231
+ break;
232
+ }
233
+ return _context2.abrupt("return", 'stop');
234
+ case 5:
235
+ if (result.ok) {
236
+ _context2.next = 19;
237
+ break;
238
+ }
239
+ _result$error = result.error, status = _result$error.status, cause = _result$error.cause; // 로그는 원인 예외를 쥔 ticket.ts가 남깁니다 — 여기서 또 찍으면 직결 경로에서 같은 말이 두 줄 됩니다
240
+ if (!(cause === 'auth_callback')) {
241
+ _context2.next = 11;
242
+ break;
243
+ }
244
+ _classPrivateFieldGet(_machine, this).transition('fatalFailure');
245
+ this.emitter.emit(eventNames.SDK_EVENTS.fatal, {
246
+ cause: 'auth_callback'
247
+ });
248
+ return _context2.abrupt("return", 'stop');
249
+ case 11:
250
+ if (!(status !== undefined && isFatalTicketStatus(status))) {
251
+ _context2.next = 16;
252
+ break;
253
+ }
254
+ (_this$options$logger2 = this.options.logger) === null || _this$options$logger2 === void 0 || _this$options$logger2.warn("sse: \uD2F0\uCF13 \uBC1C\uAE09\uC774 ".concat(status, "\uB85C \uAC70\uBD80\uB418\uC5B4 \uBA48\uCDA5\uB2C8\uB2E4 \u2014 disconnect()\uB85C \uC815\uB9AC\uD55C \uB4A4 \uB2E4\uC2DC connect() \uD558\uC138\uC694"));
255
+ _classPrivateFieldGet(_machine, this).transition('fatalFailure');
256
+ // 전이를 마친 뒤 알립니다 — 핸들러가 그 자리에서 disconnect()·connect() 회복을 시작할 수 있게
257
+ this.emitter.emit(eventNames.SDK_EVENTS.fatal, {
258
+ cause: TICKET_FATAL_CAUSES[status],
259
+ status: status
260
+ });
261
+ return _context2.abrupt("return", 'stop');
262
+ case 16:
263
+ _classPrivateFieldGet(_machine, this).transition('retryableFailure');
264
+ // 서버가 응답한 거부(5xx 등)는 네트워크성이 아니라 세지 않습니다 — 서버 장애에 네트워크 안내가 나가는 오안내를 막습니다
265
+ if (status === undefined) {
266
+ _assertClassBrand(_SseClient_brand, this, _countNetworkFailure).call(this);
267
+ } else {
268
+ _classPrivateFieldSet(_networkFailures, this, 0);
269
+ }
270
+ return _context2.abrupt("return", 'retryWithDelay');
271
+ case 19:
272
+ _context2.prev = 19;
273
+ _context2.next = 22;
274
+ return _assertClassBrand(_SseClient_brand, this, _openStream).call(this, result.ticket, signal);
275
+ case 22:
276
+ outcome = _context2.sent;
277
+ if (!(outcome === 'goaway-close')) {
278
+ _context2.next = 25;
279
+ break;
280
+ }
281
+ return _context2.abrupt("return", 'stop');
282
+ case 25:
283
+ return _context2.abrupt("return", outcome === 'goaway' ? 'retryNow' : 'retryWithDelay');
284
+ case 28:
285
+ _context2.prev = 28;
286
+ _context2.t0 = _context2["catch"](19);
287
+ (_this$options$logger3 = this.options.logger) === null || _this$options$logger3 === void 0 || _this$options$logger3.error('sse: EventSource 생성 실패 — baseUrl을 확인하세요', _context2.t0);
288
+ _classPrivateFieldGet(_machine, this).transition('fatalFailure');
289
+ // 생성의 동기 throw는 설정 실수입니다 — 네트워크성 실패는 onerror로 와서 reconnecting으로 갑니다
290
+ this.emitter.emit(eventNames.SDK_EVENTS.fatal, {
291
+ cause: 'config'
292
+ });
293
+ return _context2.abrupt("return", 'stop');
294
+ case 34:
295
+ case "end":
296
+ return _context2.stop();
297
+ }
298
+ }, _callee2, this, [[19, 28]]);
299
+ }));
300
+ return _attemptConnection2.apply(this, arguments);
301
+ }
302
+ // EventSource를 생성하고 스트림이 끊길 때까지 대기합니다 — 이벤트 연결은 stream.ts, 여기서는 상태 전이만 담당합니다
303
+ function _openStream(ticket, signal) {
304
+ var _this$options$eventSo2,
305
+ _this3 = this;
306
+ var EventSourceImpl = (_this$options$eventSo2 = this.options.eventSource) !== null && _this$options$eventSo2 !== void 0 ? _this$options$eventSo2 : globalThis.EventSource;
307
+ var source = new EventSourceImpl("".concat(this.options.baseUrl, "/v1/events?ticket=").concat(encodeURIComponent(ticket)));
308
+ _classPrivateFieldSet(_currentStream, this, {
309
+ source: source,
310
+ attachedEvents: new Set()
311
+ });
312
+ this.emitter.handlerTypes().forEach(function (type) {
313
+ return _assertClassBrand(_SseClient_brand, _this3, _attachSourceListener).call(_this3, type);
314
+ });
315
+
316
+ // hello 전 끊김(타임아웃 포함)만 미연결로 셉니다 — 수립 후 끊김은 다음 시도부터 다시 셉니다
317
+ var opened = false;
318
+ return stream.streamUntilClosed(source, signal, {
319
+ helloTimeoutMs: HELLO_TIMEOUT_MS,
320
+ onHello: function onHello() {
321
+ if (!_classPrivateFieldGet(_machine, _this3).transition('hello')) {
322
+ return false;
323
+ }
324
+ if (signal.aborted) {
325
+ return false;
326
+ }
327
+ opened = true;
328
+ _classPrivateFieldGet(_backoff, _this3).reset();
329
+ _classPrivateFieldSet(_networkFailures, _this3, 0);
330
+
331
+ // 갱신 전에 읽어야 이번 hello를 뺀 값입니다 — 두 번째부터가 재수립입니다
332
+ var isReestablished = _classPrivateFieldGet(_hasOpened, _this3);
333
+ _classPrivateFieldSet(_hasOpened, _this3, true);
334
+ if (isReestablished) {
335
+ _this3.emitter.emit(eventNames.SDK_EVENTS.resync, undefined);
336
+ }
337
+ return true;
338
+ },
339
+ onClosed: function onClosed(closure) {
340
+ if (closure.outcome === 'error') {
341
+ _assertClassBrand(_SseClient_brand, _this3, _closeStream).call(_this3);
342
+ _classPrivateFieldGet(_machine, _this3).transition('retryableFailure');
343
+ if (!opened) {
344
+ _assertClassBrand(_SseClient_brand, _this3, _countNetworkFailure).call(_this3);
345
+ }
346
+ return;
347
+ }
348
+
349
+ // 서버가 재연결하지 말라고 했으면 reconnecting을 거치지 않습니다 — 소비처에 헛된 재연결 중을 보이지 않게
350
+ if (closure.outcome === 'goaway-close') {
351
+ _assertClassBrand(_SseClient_brand, _this3, _endSession).call(_this3);
352
+ _classPrivateFieldGet(_machine, _this3).transition('disconnect');
353
+ } else {
354
+ _assertClassBrand(_SseClient_brand, _this3, _closeStream).call(_this3);
355
+ _classPrivateFieldGet(_machine, _this3).transition('retryableFailure');
356
+ }
357
+
358
+ // 전이를 마친 뒤 알립니다 — 핸들러가 그 자리에서 connect()·disconnect()를 부를 수 있게
359
+ _this3.emitter.emit(eventNames.SERVER_CONNECTION_EVENTS.goaway, closure.goaway);
360
+ }
361
+ });
362
+ }
363
+ function _attachSourceListener(type) {
364
+ var _this4 = this;
365
+ if (_classPrivateFieldGet(_currentStream, this) === null) {
366
+ return;
367
+ }
368
+ var _classPrivateFieldGet3 = _classPrivateFieldGet(_currentStream, this),
369
+ source = _classPrivateFieldGet3.source,
370
+ attachedEvents = _classPrivateFieldGet3.attachedEvents;
371
+ stream.attachDomainListener(source, attachedEvents, type, function (t, payload) {
372
+ return _this4.emitter.emit(t, payload);
373
+ });
374
+ }
375
+ function _closeStream() {
376
+ var _classPrivateFieldGet4;
377
+ (_classPrivateFieldGet4 = _classPrivateFieldGet(_currentStream, this)) === null || _classPrivateFieldGet4 === void 0 || _classPrivateFieldGet4.source.close();
378
+ _classPrivateFieldSet(_currentStream, this, null);
379
+ }
380
+
381
+ exports.SseClient = SseClient;
382
+ //# sourceMappingURL=SseClient.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SseClient.cjs.js","sources":["../../../src/core/SseClient.ts"],"sourcesContent":["import type { Backoff } from './backoff';\nimport { createBackoff } from './backoff';\nimport { BaseSseClient } from './BaseSseClient';\nimport { SDK_EVENTS, SERVER_CONNECTION_EVENTS } from './eventNames';\nimport { waitForRetry } from './retryWait';\nimport type { StatusMachine } from './statusMachine';\nimport { createStatusMachine } from './statusMachine';\nimport type { AttachedEvents, StreamOutcome } from './stream';\nimport { attachDomainListener, streamUntilClosed } from './stream';\nimport type { TicketResult } from './ticket';\nimport { issueTicketWithTimeout } from './ticket';\nimport type {\n FatalCause,\n FatalPayload,\n SseClientOptions,\n SseEventMap,\n SseStatus,\n} from './types';\n\n// 상태 코드 → 사유 매핑이 단일 원천입니다 — 멈출 코드 판정과 사유가 같은 표에서 나와 어긋날 수 없습니다\nconst TICKET_FATAL_CAUSES = {\n 401: 'auth',\n 403: 'auth',\n 429: 'rate_limit',\n} as const satisfies Record<number, FatalCause>;\n\ntype FatalTicketStatus = keyof typeof TICKET_FATAL_CAUSES;\n\nconst isFatalTicketStatus = (status: number): status is FatalTicketStatus =>\n status in TICKET_FATAL_CAUSES;\n\nconst HELLO_TIMEOUT_MS = 10_000;\n\n// 즉시 실패(CORS·오프라인)의 기본 백오프(full jitter) 기준 최대 15초, 보통 7~8초 안에 알립니다 — 순간 끊김에는 침묵합니다\nconst STALLED_AFTER_ATTEMPTS = 5;\n\n/**\n * @description 내부 확장 지점 — 워커가 티켓 발급을 탭에 위임할 때 씁니다.\n * 공개 옵션(SseClientOptions)에는 노출하지 않습니다: 소비처가 티켓 발급 절차를 바꿀 이유가 없습니다.\n */\nexport interface SseClientInternals {\n issueTicket?: () => Promise<TicketResult>;\n /** @description 워커가 인스턴스를 갈아끼워도 재수립 판정이 이어지게 합니다 — 첫 hello가 resync를 쏠지 가릅니다 */\n hasOpenedBefore?: boolean;\n}\n\n/** @description SSR 환경에서도 안전하게 생성할 수 있습니다 — 연결은 connect()를 호출할 때 시작됩니다 */\nexport class SseClient<\n M extends object = SseEventMap,\n> extends BaseSseClient<M> {\n readonly #backoff: Backoff;\n readonly #machine: StatusMachine;\n\n #currentStream: {\n source: EventSource;\n attachedEvents: AttachedEvents;\n } | null = null;\n\n #abort: AbortController | null = null;\n #hasOpened: boolean;\n #networkFailures = 0;\n\n constructor(\n protected readonly options: SseClientOptions,\n protected readonly internals: SseClientInternals = {}\n ) {\n super(options.logger);\n this.#hasOpened = internals.hasOpenedBefore ?? false;\n this.#backoff = createBackoff(options.backoff);\n this.#machine = createStatusMachine((status) =>\n this.emitter.emitStatus(status)\n );\n }\n\n get status(): SseStatus {\n return this.#machine.status;\n }\n\n connect(): void {\n if ((this.options.eventSource ?? globalThis.EventSource) === undefined) {\n // SSR 대응 - no-op\n return;\n }\n\n const controller = new AbortController();\n const previous = this.#abort;\n // 전이 통지 중 리스너가 disconnect()해도 이 controller가 abort되도록 전이보다 먼저 교체합니다\n this.#abort = controller;\n\n if (!this.#machine.transition('connect')) {\n this.#abort = previous;\n if (this.#machine.status === 'fatal') {\n this.options.logger?.warn(\n 'sse: fatal 상태에서는 connect()가 무시됩니다 — disconnect()로 정리한 뒤 다시 connect() 하세요'\n );\n }\n return;\n }\n if (controller.signal.aborted) {\n return;\n }\n\n // 루프가 예외로 죽으면 재시도가 영영 없습니다 — fatal로 떨어뜨려 회복 경로(정리 후 connect)에 맡깁니다\n void this.#runConnection(controller.signal).catch((error) => {\n this.options.logger?.error('sse: 연결 루프가 예외로 중단됐습니다', error);\n // 전이가 거부된 상태(reconnecting 등)에서 발화하면 \"전이 후 발화\" 계약이 깨집니다\n if (this.#machine.transition('fatalFailure')) {\n this.emitter.emit(SDK_EVENTS.fatal, {\n cause: 'unknown',\n } satisfies FatalPayload);\n }\n });\n }\n\n disconnect(): void {\n // abort가 연결 루프를 중단합니다 — 진행 중이던 티켓 발급·대기·스트림 전부\n this.#abort?.abort();\n this.#abort = null;\n this.#endSession();\n this.#machine.transition('disconnect');\n }\n\n // 한 연결 세션을 접습니다 — 다음 connect()가 첫 연결처럼 시작하도록 재수립 판단과 백오프도 함께 되돌립니다\n #endSession(): void {\n this.#closeStream();\n this.#hasOpened = false;\n this.#backoff.reset();\n this.#networkFailures = 0;\n }\n\n /**\n * @description hello에 닿지 못한 네트워크성(응답 status 부재) 연속 실패를 셉니다 — 임계값 도달 순간에만\n * stalled를 발화해 한 구간에 한 번만 알립니다. 반드시 상태 전이 뒤에 부르세요.\n * 연속은 open 도달과 서버 응답(5xx)이 끊고, 스트림 단계 실패는 status가 없어 전부 여기 해당합니다.\n */\n #countNetworkFailure(): void {\n this.#networkFailures += 1;\n if (this.#networkFailures === STALLED_AFTER_ATTEMPTS) {\n this.emitter.emit(SDK_EVENTS.stalled, undefined);\n }\n }\n\n // 열린 스트림이 없으면 조용히 넘어갑니다 — 다음 #openStream이 구독 장부를 보고 한 번에 붙입니다\n protected registerSubscription(type: string): void {\n this.#attachSourceListener(type);\n }\n\n // 티켓 발급 → 스트림 유지 → 끊김 → 대기 → 재시도. disconnect(abort)만이 루프를 종료합니다\n async #runConnection(signal: AbortSignal): Promise<void> {\n while (!signal.aborted) {\n const next = await this.#attemptConnection(signal);\n if (signal.aborted || next === 'stop') {\n return;\n }\n\n if (next === 'retryWithDelay') {\n await waitForRetry(this.#backoff.nextDelayMs(), signal);\n if (signal.aborted) {\n return;\n }\n }\n this.#machine.transition('readyToRetry');\n }\n }\n\n // 스트림이 끊길 때까지 대기하고, 루프의 다음 동작('stop'·'retryWithDelay'·'retryNow')을 반환합니다\n async #attemptConnection(\n signal: AbortSignal\n ): Promise<'stop' | 'retryWithDelay' | 'retryNow'> {\n const result = await (this.internals.issueTicket?.() ??\n issueTicketWithTimeout(this.options));\n\n if (signal.aborted) {\n return 'stop';\n }\n\n if (!result.ok) {\n const { status, cause } = result.error;\n\n // 로그는 원인 예외를 쥔 ticket.ts가 남깁니다 — 여기서 또 찍으면 직결 경로에서 같은 말이 두 줄 됩니다\n if (cause === 'auth_callback') {\n this.#machine.transition('fatalFailure');\n this.emitter.emit(SDK_EVENTS.fatal, {\n cause: 'auth_callback',\n } satisfies FatalPayload);\n return 'stop';\n }\n\n if (status !== undefined && isFatalTicketStatus(status)) {\n this.options.logger?.warn(\n `sse: 티켓 발급이 ${status}로 거부되어 멈춥니다 — disconnect()로 정리한 뒤 다시 connect() 하세요`\n );\n this.#machine.transition('fatalFailure');\n // 전이를 마친 뒤 알립니다 — 핸들러가 그 자리에서 disconnect()·connect() 회복을 시작할 수 있게\n this.emitter.emit(SDK_EVENTS.fatal, {\n cause: TICKET_FATAL_CAUSES[status],\n status,\n } satisfies FatalPayload);\n return 'stop';\n }\n\n this.#machine.transition('retryableFailure');\n // 서버가 응답한 거부(5xx 등)는 네트워크성이 아니라 세지 않습니다 — 서버 장애에 네트워크 안내가 나가는 오안내를 막습니다\n if (status === undefined) {\n this.#countNetworkFailure();\n } else {\n this.#networkFailures = 0;\n }\n return 'retryWithDelay';\n }\n\n try {\n const outcome = await this.#openStream(result.ticket, signal);\n if (outcome === 'goaway-close') {\n return 'stop';\n }\n return outcome === 'goaway' ? 'retryNow' : 'retryWithDelay';\n } catch (error) {\n this.options.logger?.error(\n 'sse: EventSource 생성 실패 — baseUrl을 확인하세요',\n error\n );\n\n this.#machine.transition('fatalFailure');\n // 생성의 동기 throw는 설정 실수입니다 — 네트워크성 실패는 onerror로 와서 reconnecting으로 갑니다\n this.emitter.emit(SDK_EVENTS.fatal, {\n cause: 'config',\n } satisfies FatalPayload);\n return 'stop';\n }\n }\n\n // EventSource를 생성하고 스트림이 끊길 때까지 대기합니다 — 이벤트 연결은 stream.ts, 여기서는 상태 전이만 담당합니다\n #openStream(ticket: string, signal: AbortSignal): Promise<StreamOutcome> {\n const EventSourceImpl = this.options.eventSource ?? globalThis.EventSource;\n const source = new EventSourceImpl(\n `${this.options.baseUrl}/v1/events?ticket=${encodeURIComponent(ticket)}`\n );\n this.#currentStream = { source, attachedEvents: new Set() };\n this.emitter\n .handlerTypes()\n .forEach((type) => this.#attachSourceListener(type));\n\n // hello 전 끊김(타임아웃 포함)만 미연결로 셉니다 — 수립 후 끊김은 다음 시도부터 다시 셉니다\n let opened = false;\n\n return streamUntilClosed(source, signal, {\n helloTimeoutMs: HELLO_TIMEOUT_MS,\n onHello: () => {\n if (!this.#machine.transition('hello')) {\n return false;\n }\n\n if (signal.aborted) {\n return false;\n }\n opened = true;\n this.#backoff.reset();\n this.#networkFailures = 0;\n\n // 갱신 전에 읽어야 이번 hello를 뺀 값입니다 — 두 번째부터가 재수립입니다\n const isReestablished = this.#hasOpened;\n this.#hasOpened = true;\n\n if (isReestablished) {\n this.emitter.emit(SDK_EVENTS.resync, undefined);\n }\n return true;\n },\n\n onClosed: (closure) => {\n if (closure.outcome === 'error') {\n this.#closeStream();\n this.#machine.transition('retryableFailure');\n if (!opened) {\n this.#countNetworkFailure();\n }\n return;\n }\n\n // 서버가 재연결하지 말라고 했으면 reconnecting을 거치지 않습니다 — 소비처에 헛된 재연결 중을 보이지 않게\n if (closure.outcome === 'goaway-close') {\n this.#endSession();\n this.#machine.transition('disconnect');\n } else {\n this.#closeStream();\n this.#machine.transition('retryableFailure');\n }\n\n // 전이를 마친 뒤 알립니다 — 핸들러가 그 자리에서 connect()·disconnect()를 부를 수 있게\n this.emitter.emit(SERVER_CONNECTION_EVENTS.goaway, closure.goaway);\n },\n });\n }\n\n #attachSourceListener(type: string): void {\n if (this.#currentStream === null) {\n return;\n }\n const { source, attachedEvents } = this.#currentStream;\n attachDomainListener(source, attachedEvents, type, (t, payload) =>\n this.emitter.emit(t, payload)\n );\n }\n\n #closeStream(): void {\n this.#currentStream?.source.close();\n this.#currentStream = null;\n }\n}\n"],"names":["TICKET_FATAL_CAUSES","isFatalTicketStatus","status","HELLO_TIMEOUT_MS","STALLED_AFTER_ATTEMPTS","_backoff","WeakMap","_machine","_currentStream","_abort","_hasOpened","_networkFailures","_SseClient_brand","WeakSet","SseClient","_BaseSseClient","options","_internals$hasOpenedB","_this","internals","arguments","length","undefined","_classCallCheck","_callSuper","logger","_classPrivateMethodInitSpec","_classPrivateFieldInitSpec","_classPrivateFieldSet","hasOpenedBefore","createBackoff","backoff","createStatusMachine","emitter","emitStatus","_inherits","_createClass","key","get","_classPrivateFieldGet","value","connect","_this$options$eventSo","_this2","eventSource","globalThis","EventSource","controller","AbortController","previous","transition","_this$options$logger","warn","signal","aborted","_assertClassBrand","_runConnection","call","error","_this2$options$logger","emit","SDK_EVENTS","fatal","cause","disconnect","_classPrivateFieldGet2","abort","_endSession","registerSubscription","type","_attachSourceListener","BaseSseClient","_closeStream","reset","_countNetworkFailure","stalled","_x","_runConnection2","apply","_asyncToGenerator","_regeneratorRuntime","mark","_callee","next","wrap","_callee$","_context","prev","_attemptConnection","sent","abrupt","waitForRetry","nextDelayMs","stop","_x2","_attemptConnection2","_callee2","_this$internals$issue","_this$internals$issue2","_this$internals","result","_result$error","_this$options$logger2","outcome","_this$options$logger3","_callee2$","_context2","issueTicket","issueTicketWithTimeout","ok","concat","_openStream","ticket","t0","_this$options$eventSo2","_this3","EventSourceImpl","source","baseUrl","encodeURIComponent","attachedEvents","Set","handlerTypes","forEach","opened","streamUntilClosed","helloTimeoutMs","onHello","isReestablished","resync","onClosed","closure","SERVER_CONNECTION_EVENTS","goaway","_this4","_classPrivateFieldGet3","attachDomainListener","t","payload","_classPrivateFieldGet4","close"],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import { BaseSseClient } from './BaseSseClient';
2
+ import type { TicketResult } from './ticket';
3
+ import type { SseClientOptions, SseEventMap, SseStatus } from './types';
4
+ /**
5
+ * @description 내부 확장 지점 — 워커가 티켓 발급을 탭에 위임할 때 씁니다.
6
+ * 공개 옵션(SseClientOptions)에는 노출하지 않습니다: 소비처가 티켓 발급 절차를 바꿀 이유가 없습니다.
7
+ */
8
+ export interface SseClientInternals {
9
+ issueTicket?: () => Promise<TicketResult>;
10
+ /** @description 워커가 인스턴스를 갈아끼워도 재수립 판정이 이어지게 합니다 — 첫 hello가 resync를 쏠지 가릅니다 */
11
+ hasOpenedBefore?: boolean;
12
+ }
13
+ /** @description SSR 환경에서도 안전하게 생성할 수 있습니다 — 연결은 connect()를 호출할 때 시작됩니다 */
14
+ export declare class SseClient<M extends object = SseEventMap> extends BaseSseClient<M> {
15
+ #private;
16
+ protected readonly options: SseClientOptions;
17
+ protected readonly internals: SseClientInternals;
18
+ constructor(options: SseClientOptions, internals?: SseClientInternals);
19
+ get status(): SseStatus;
20
+ connect(): void;
21
+ disconnect(): void;
22
+ protected registerSubscription(type: string): void;
23
+ }
24
+ //# sourceMappingURL=SseClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SseClient.d.ts","sourceRoot":"","sources":["../../../src/core/SseClient.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAOhD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE7C,OAAO,KAAK,EAGV,gBAAgB,EAChB,WAAW,EACX,SAAS,EACV,MAAM,SAAS,CAAC;AAmBjB;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,CAAC;IAC1C,+EAA+E;IAC/E,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,0EAA0E;AAC1E,qBAAa,SAAS,CACpB,CAAC,SAAS,MAAM,GAAG,WAAW,CAC9B,SAAQ,aAAa,CAAC,CAAC,CAAC;;IActB,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,gBAAgB;IAC5C,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,kBAAkB;gBAD7B,OAAO,EAAE,gBAAgB,EACzB,SAAS,GAAE,kBAAuB;IAUvD,IAAI,MAAM,IAAI,SAAS,CAEtB;IAED,OAAO,IAAI,IAAI;IAoCf,UAAU,IAAI,IAAI;IA6BlB,SAAS,CAAC,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;CAsKnD"}