request-iframe 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (223) hide show
  1. package/QUICKSTART.CN.md +4 -2
  2. package/QUICKSTART.md +4 -2
  3. package/README.CN.md +302 -54
  4. package/README.md +281 -36
  5. package/cdn/request-iframe-react.umd.js +3354 -0
  6. package/cdn/request-iframe-react.umd.js.map +1 -0
  7. package/cdn/request-iframe-react.umd.min.js +2 -0
  8. package/cdn/request-iframe-react.umd.min.js.map +1 -0
  9. package/cdn/request-iframe.umd.js +19735 -0
  10. package/cdn/request-iframe.umd.js.map +1 -0
  11. package/cdn/request-iframe.umd.min.js +4 -0
  12. package/cdn/request-iframe.umd.min.js.map +1 -0
  13. package/esm/api/client.js +31 -22
  14. package/esm/api/endpoint.js +229 -0
  15. package/esm/api/server.js +19 -9
  16. package/esm/constants/debug.js +17 -0
  17. package/esm/constants/index.js +115 -66
  18. package/esm/constants/log.js +11 -0
  19. package/esm/constants/messages.js +6 -1
  20. package/esm/constants/warn-once.js +15 -0
  21. package/esm/endpoint/facade.js +390 -0
  22. package/esm/endpoint/heartbeat/heartbeat.js +60 -0
  23. package/esm/endpoint/heartbeat/ping.js +20 -0
  24. package/esm/endpoint/index.js +13 -0
  25. package/esm/endpoint/infra/hub.js +316 -0
  26. package/esm/endpoint/infra/inbox.js +232 -0
  27. package/esm/endpoint/infra/outbox.js +408 -0
  28. package/esm/endpoint/stream/dispatcher.js +58 -0
  29. package/esm/endpoint/stream/errors.js +27 -0
  30. package/esm/endpoint/stream/factory.js +76 -0
  31. package/esm/endpoint/stream/file-auto-resolve.js +34 -0
  32. package/esm/endpoint/stream/file-writable.js +105 -0
  33. package/esm/endpoint/stream/handler.js +26 -0
  34. package/esm/{core → impl}/client.js +243 -320
  35. package/esm/{core → impl}/response.js +120 -154
  36. package/esm/impl/server.js +568 -0
  37. package/esm/index.js +13 -6
  38. package/esm/message/ack.js +27 -0
  39. package/esm/message/channel-cache.js +108 -0
  40. package/esm/message/channel.js +92 -5
  41. package/esm/message/dispatcher.js +149 -98
  42. package/esm/stream/error.js +22 -0
  43. package/esm/stream/index.js +3 -1
  44. package/esm/stream/readable-stream.js +101 -26
  45. package/esm/stream/stream-core.js +121 -3
  46. package/esm/stream/writable-stream.js +368 -43
  47. package/esm/utils/ack.js +36 -0
  48. package/esm/utils/blob.js +16 -0
  49. package/esm/utils/cache.js +25 -76
  50. package/esm/utils/content-type.js +81 -0
  51. package/esm/utils/debug.js +157 -180
  52. package/esm/utils/hooks.js +130 -0
  53. package/esm/utils/id.js +14 -0
  54. package/esm/utils/iframe.js +20 -0
  55. package/esm/utils/index.js +12 -162
  56. package/esm/utils/is.js +3 -0
  57. package/esm/utils/logger.js +55 -0
  58. package/esm/utils/origin.js +3 -1
  59. package/esm/utils/promise.js +3 -0
  60. package/esm/utils/window.js +31 -0
  61. package/library/api/client.d.ts.map +1 -1
  62. package/library/api/client.js +32 -23
  63. package/library/api/endpoint.d.ts +23 -0
  64. package/library/api/endpoint.d.ts.map +1 -0
  65. package/library/api/endpoint.js +235 -0
  66. package/library/api/server.d.ts +4 -1
  67. package/library/api/server.d.ts.map +1 -1
  68. package/library/api/server.js +19 -9
  69. package/library/constants/debug.d.ts +18 -0
  70. package/library/constants/debug.d.ts.map +1 -0
  71. package/library/constants/debug.js +23 -0
  72. package/library/constants/index.d.ts +58 -7
  73. package/library/constants/index.d.ts.map +1 -1
  74. package/library/constants/index.js +143 -67
  75. package/library/constants/log.d.ts +12 -0
  76. package/library/constants/log.d.ts.map +1 -0
  77. package/library/constants/log.js +17 -0
  78. package/library/constants/messages.d.ts +6 -1
  79. package/library/constants/messages.d.ts.map +1 -1
  80. package/library/constants/messages.js +6 -1
  81. package/library/constants/warn-once.d.ts +12 -0
  82. package/library/constants/warn-once.d.ts.map +1 -0
  83. package/library/constants/warn-once.js +22 -0
  84. package/library/endpoint/facade.d.ts +238 -0
  85. package/library/endpoint/facade.d.ts.map +1 -0
  86. package/library/endpoint/facade.js +398 -0
  87. package/library/endpoint/heartbeat/heartbeat.d.ts +34 -0
  88. package/library/endpoint/heartbeat/heartbeat.d.ts.map +1 -0
  89. package/library/endpoint/heartbeat/heartbeat.js +67 -0
  90. package/library/endpoint/heartbeat/ping.d.ts +18 -0
  91. package/library/endpoint/heartbeat/ping.d.ts.map +1 -0
  92. package/library/endpoint/heartbeat/ping.js +26 -0
  93. package/library/endpoint/index.d.ts +16 -0
  94. package/library/endpoint/index.d.ts.map +1 -0
  95. package/library/endpoint/index.js +114 -0
  96. package/library/endpoint/infra/hub.d.ts +170 -0
  97. package/library/endpoint/infra/hub.d.ts.map +1 -0
  98. package/library/endpoint/infra/hub.js +323 -0
  99. package/library/endpoint/infra/inbox.d.ts +73 -0
  100. package/library/endpoint/infra/inbox.d.ts.map +1 -0
  101. package/library/endpoint/infra/inbox.js +239 -0
  102. package/library/endpoint/infra/outbox.d.ts +149 -0
  103. package/library/endpoint/infra/outbox.d.ts.map +1 -0
  104. package/library/endpoint/infra/outbox.js +415 -0
  105. package/library/endpoint/stream/dispatcher.d.ts +33 -0
  106. package/library/endpoint/stream/dispatcher.d.ts.map +1 -0
  107. package/library/endpoint/stream/dispatcher.js +66 -0
  108. package/library/endpoint/stream/errors.d.ts +20 -0
  109. package/library/endpoint/stream/errors.d.ts.map +1 -0
  110. package/library/endpoint/stream/errors.js +32 -0
  111. package/library/endpoint/stream/factory.d.ts +44 -0
  112. package/library/endpoint/stream/factory.d.ts.map +1 -0
  113. package/library/endpoint/stream/factory.js +82 -0
  114. package/library/endpoint/stream/file-auto-resolve.d.ts +26 -0
  115. package/library/endpoint/stream/file-auto-resolve.d.ts.map +1 -0
  116. package/library/endpoint/stream/file-auto-resolve.js +41 -0
  117. package/library/endpoint/stream/file-writable.d.ts +33 -0
  118. package/library/endpoint/stream/file-writable.d.ts.map +1 -0
  119. package/library/endpoint/stream/file-writable.js +115 -0
  120. package/library/endpoint/stream/handler.d.ts +20 -0
  121. package/library/endpoint/stream/handler.d.ts.map +1 -0
  122. package/library/endpoint/stream/handler.js +32 -0
  123. package/library/{core → impl}/client.d.ts +16 -13
  124. package/library/impl/client.d.ts.map +1 -0
  125. package/library/{core → impl}/client.js +254 -333
  126. package/library/{core → impl}/request.d.ts.map +1 -1
  127. package/library/{core → impl}/response.d.ts +7 -12
  128. package/library/impl/response.d.ts.map +1 -0
  129. package/library/{core → impl}/response.js +120 -154
  130. package/library/{core → impl}/server.d.ts +26 -55
  131. package/library/impl/server.d.ts.map +1 -0
  132. package/library/impl/server.js +575 -0
  133. package/library/index.d.ts +13 -6
  134. package/library/index.d.ts.map +1 -1
  135. package/library/index.js +16 -16
  136. package/library/message/ack.d.ts +15 -0
  137. package/library/message/ack.d.ts.map +1 -0
  138. package/library/message/ack.js +33 -0
  139. package/library/message/channel-cache.d.ts +26 -0
  140. package/library/message/channel-cache.d.ts.map +1 -0
  141. package/library/message/channel-cache.js +115 -0
  142. package/library/message/channel.d.ts +53 -6
  143. package/library/message/channel.d.ts.map +1 -1
  144. package/library/message/channel.js +96 -9
  145. package/library/message/dispatcher.d.ts +17 -0
  146. package/library/message/dispatcher.d.ts.map +1 -1
  147. package/library/message/dispatcher.js +149 -98
  148. package/library/stream/error.d.ts +24 -0
  149. package/library/stream/error.d.ts.map +1 -0
  150. package/library/stream/error.js +29 -0
  151. package/library/stream/index.d.ts +4 -1
  152. package/library/stream/index.d.ts.map +1 -1
  153. package/library/stream/index.js +7 -4
  154. package/library/stream/readable-stream.d.ts.map +1 -1
  155. package/library/stream/readable-stream.js +102 -27
  156. package/library/stream/stream-core.d.ts +22 -1
  157. package/library/stream/stream-core.d.ts.map +1 -1
  158. package/library/stream/stream-core.js +120 -2
  159. package/library/stream/types.d.ts +115 -2
  160. package/library/stream/types.d.ts.map +1 -1
  161. package/library/stream/writable-stream.d.ts +20 -2
  162. package/library/stream/writable-stream.d.ts.map +1 -1
  163. package/library/stream/writable-stream.js +366 -41
  164. package/library/types/index.d.ts +17 -22
  165. package/library/types/index.d.ts.map +1 -1
  166. package/library/utils/ack.d.ts +2 -0
  167. package/library/utils/ack.d.ts.map +1 -0
  168. package/library/utils/ack.js +44 -0
  169. package/library/utils/blob.d.ts +3 -0
  170. package/library/utils/blob.d.ts.map +1 -0
  171. package/library/utils/blob.js +22 -0
  172. package/library/utils/cache.d.ts +10 -20
  173. package/library/utils/cache.d.ts.map +1 -1
  174. package/library/utils/cache.js +25 -79
  175. package/library/utils/content-type.d.ts +13 -0
  176. package/library/utils/content-type.d.ts.map +1 -0
  177. package/library/utils/content-type.js +87 -0
  178. package/library/utils/debug.d.ts.map +1 -1
  179. package/library/utils/debug.js +156 -178
  180. package/library/utils/hooks.d.ts +30 -0
  181. package/library/utils/hooks.d.ts.map +1 -0
  182. package/library/utils/hooks.js +139 -0
  183. package/library/utils/id.d.ts +9 -0
  184. package/library/utils/id.d.ts.map +1 -0
  185. package/library/utils/id.js +21 -0
  186. package/library/utils/iframe.d.ts +5 -0
  187. package/library/utils/iframe.d.ts.map +1 -0
  188. package/library/utils/iframe.js +25 -0
  189. package/library/utils/index.d.ts +7 -34
  190. package/library/utils/index.d.ts.map +1 -1
  191. package/library/utils/index.js +58 -193
  192. package/library/utils/is.d.ts +2 -0
  193. package/library/utils/is.d.ts.map +1 -0
  194. package/library/utils/is.js +9 -0
  195. package/library/utils/logger.d.ts +13 -0
  196. package/library/utils/logger.d.ts.map +1 -0
  197. package/library/utils/logger.js +63 -0
  198. package/library/utils/origin.d.ts.map +1 -1
  199. package/library/utils/origin.js +2 -1
  200. package/library/utils/promise.d.ts +2 -0
  201. package/library/utils/promise.d.ts.map +1 -0
  202. package/library/utils/promise.js +9 -0
  203. package/library/utils/window.d.ts +2 -0
  204. package/library/utils/window.d.ts.map +1 -0
  205. package/library/utils/window.js +38 -0
  206. package/package.json +49 -2
  207. package/react/package.json +2 -1
  208. package/esm/core/client-server.js +0 -329
  209. package/esm/core/server.js +0 -767
  210. package/esm/utils/ack-meta.js +0 -53
  211. package/library/core/client-server.d.ts +0 -106
  212. package/library/core/client-server.d.ts.map +0 -1
  213. package/library/core/client-server.js +0 -336
  214. package/library/core/client.d.ts.map +0 -1
  215. package/library/core/response.d.ts.map +0 -1
  216. package/library/core/server.d.ts.map +0 -1
  217. package/library/core/server.js +0 -772
  218. package/library/utils/ack-meta.d.ts +0 -2
  219. package/library/utils/ack-meta.d.ts.map +0 -1
  220. package/library/utils/ack-meta.js +0 -59
  221. /package/esm/{core → impl}/request.js +0 -0
  222. /package/library/{core → impl}/request.d.ts +0 -0
  223. /package/library/{core → impl}/request.js +0 -0
@@ -0,0 +1,316 @@
1
+ import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
2
+ import "core-js/modules/es.array.iterator.js";
3
+ import "core-js/modules/es.array.map.js";
4
+ import "core-js/modules/es.map.js";
5
+ import "core-js/modules/es.set.js";
6
+ import "core-js/modules/web.dom-collections.for-each.js";
7
+ import "core-js/modules/web.dom-collections.iterator.js";
8
+ import { MessageDispatcher } from '../../message';
9
+ import { isCompatibleVersion } from '../../utils/protocol';
10
+ import { OriginConstant, Messages } from '../../constants';
11
+ import { getOrCreateMessageChannel, releaseMessageChannel } from '../../message/channel-cache';
12
+ import { RequestIframeEndpointOutbox } from './outbox';
13
+ import { SyncHook } from '../../utils/hooks';
14
+
15
+ /**
16
+ * Pending manager for maps and timers.
17
+ *
18
+ * - Track all pending maps created by hub
19
+ * - Track all timeouts created by hub
20
+ * - Provide a unified cleanup when destroying
21
+ */
22
+ class RequestIframePendingManager {
23
+ constructor() {
24
+ _defineProperty(this, "maps", new Map());
25
+ _defineProperty(this, "timeouts", new Set());
26
+ }
27
+ /**
28
+ * Get or create a named pending map that will be auto-cleared on destroy.
29
+ */
30
+ map(name) {
31
+ var existing = this.maps.get(name);
32
+ if (existing) return existing;
33
+ var m = new Map();
34
+ this.maps.set(name, m);
35
+ return m;
36
+ }
37
+ get(name, key) {
38
+ return this.map(name).get(key);
39
+ }
40
+ set(name, key, value) {
41
+ this.map(name).set(key, value);
42
+ }
43
+ has(name, key) {
44
+ return this.map(name).has(key);
45
+ }
46
+ delete(name, key) {
47
+ return this.map(name).delete(key);
48
+ }
49
+
50
+ /**
51
+ * Create a timeout that will be auto-cleared on destroy.
52
+ */
53
+ setTimeout(fn, ms) {
54
+ var id = setTimeout(() => {
55
+ this.timeouts.delete(id);
56
+ fn();
57
+ }, ms);
58
+ this.timeouts.add(id);
59
+ return id;
60
+ }
61
+
62
+ /**
63
+ * Clear a tracked timeout.
64
+ */
65
+ clearTimeout(id) {
66
+ clearTimeout(id);
67
+ this.timeouts.delete(id);
68
+ }
69
+
70
+ /**
71
+ * Clear all tracked pending maps and timeouts.
72
+ */
73
+ clearAll() {
74
+ this.timeouts.forEach(id => clearTimeout(id));
75
+ this.timeouts.clear();
76
+ this.maps.forEach(m => m.clear());
77
+ }
78
+ }
79
+
80
+ /**
81
+ * Generic counter/limiter utilities (built on hub.pending maps).
82
+ *
83
+ * This is intended as a shared infrastructure for both client/server:
84
+ * - server can limit max concurrent in-flight requests per client
85
+ * - client can limit max concurrent streams / in-flight sends in future
86
+ */
87
+ class RequestIframeLimiter {
88
+ constructor(pending) {
89
+ this.pending = pending;
90
+ }
91
+ get(bucket, key) {
92
+ var _this$pending$get;
93
+ return (_this$pending$get = this.pending.get(bucket, key)) !== null && _this$pending$get !== void 0 ? _this$pending$get : 0;
94
+ }
95
+
96
+ /**
97
+ * Try acquire one permit for the given key.
98
+ * Returns true if acquired, false if limit reached.
99
+ */
100
+ tryAcquire(bucket, key, limit) {
101
+ if (!Number.isFinite(limit)) {
102
+ /** Treat Infinity as always allowed but still count for symmetry */
103
+ var next = this.get(bucket, key) + 1;
104
+ this.pending.set(bucket, key, next);
105
+ return true;
106
+ }
107
+ var current = this.get(bucket, key);
108
+ if (current >= limit) return false;
109
+ this.pending.set(bucket, key, current + 1);
110
+ return true;
111
+ }
112
+
113
+ /**
114
+ * Release one permit for the given key.
115
+ */
116
+ release(bucket, key) {
117
+ var current = this.get(bucket, key);
118
+ var next = current - 1;
119
+ if (next <= 0) {
120
+ this.pending.delete(bucket, key);
121
+ return;
122
+ }
123
+ this.pending.set(bucket, key, next);
124
+ }
125
+ }
126
+
127
+ /**
128
+ * Shared options for endpoint hub.
129
+ */
130
+
131
+ /**
132
+ * RequestIframeEndpointHub
133
+ *
134
+ * Endpoint "hub" responsible for:
135
+ * - MessageDispatcher lifecycle
136
+ * - handler registration/unregistration
137
+ * - pending + timeout management
138
+ * - limiter counters
139
+ */
140
+ export class RequestIframeEndpointHub {
141
+ constructor(role, instanceId, options) {
142
+ var _options$versionValid;
143
+ _defineProperty(this, "hooks", {
144
+ beforeOpen: new SyncHook(),
145
+ afterOpen: new SyncHook(),
146
+ beforeClose: new SyncHook(),
147
+ afterClose: new SyncHook(),
148
+ beforeDestroy: new SyncHook(),
149
+ afterDestroy: new SyncHook(),
150
+ registerHandler: new SyncHook(),
151
+ unregisterHandler: new SyncHook()
152
+ });
153
+ _defineProperty(this, "pending", new RequestIframePendingManager());
154
+ _defineProperty(this, "limiter", new RequestIframeLimiter(this.pending));
155
+ _defineProperty(this, "unregisterFns", []);
156
+ _defineProperty(this, "warnOnceKeys", new Set());
157
+ /** Whether it is open */
158
+ _defineProperty(this, "_isOpen", false);
159
+ this.instanceId = instanceId;
160
+ this.versionValidator = (_options$versionValid = options === null || options === void 0 ? void 0 : options.versionValidator) !== null && _options$versionValid !== void 0 ? _options$versionValid : isCompatibleVersion;
161
+
162
+ /** Get or create shared channel and create dispatcher */
163
+ var channel = getOrCreateMessageChannel(options === null || options === void 0 ? void 0 : options.secretKey);
164
+ this.messageDispatcher = new MessageDispatcher(channel, role, instanceId);
165
+ this.messageDispatcher.setAutoAckLimits({
166
+ maxMetaLength: options === null || options === void 0 ? void 0 : options.autoAckMaxMetaLength,
167
+ maxIdLength: options === null || options === void 0 ? void 0 : options.autoAckMaxIdLength
168
+ });
169
+ }
170
+
171
+ /**
172
+ * Set registerHandlers callback.
173
+ *
174
+ * This is used by composition-based implementations to define handler bindings.
175
+ */
176
+ setRegisterHandlers(fn) {
177
+ this.registerHandlersFn = fn;
178
+ }
179
+
180
+ /**
181
+ * Register a dispatcher handler and track its unregister function.
182
+ */
183
+ registerHandler(matcher, handler, options) {
184
+ this.hooks.registerHandler.call(matcher);
185
+ var unreg = this.messageDispatcher.registerHandler(matcher, handler, options);
186
+ this.unregisterFns.push(unreg);
187
+ return unreg;
188
+ }
189
+
190
+ /**
191
+ * Create common handler options object.
192
+ */
193
+ createHandlerOptions(onVersionError) {
194
+ return {
195
+ versionValidator: this.versionValidator,
196
+ onVersionError
197
+ };
198
+ }
199
+
200
+ /**
201
+ * Warn once per key.
202
+ */
203
+ warnOnce(key, fn) {
204
+ if (this.warnOnceKeys.has(key)) return;
205
+ this.warnOnceKeys.add(key);
206
+ fn();
207
+ }
208
+
209
+ /**
210
+ * Set stream callback (used by client-side stream routing).
211
+ */
212
+ setStreamCallback(callback) {
213
+ this.streamCallback = callback;
214
+ }
215
+
216
+ /**
217
+ * Get stream callback (used by handler registration side).
218
+ */
219
+ getStreamCallback() {
220
+ return this.streamCallback;
221
+ }
222
+
223
+ /**
224
+ * Validate origin safely (originValidator wins over origin string).
225
+ */
226
+ isOriginAllowedBy(contextOrigin, data, context, origin, originValidator) {
227
+ if (originValidator) {
228
+ try {
229
+ return originValidator(contextOrigin, data, context);
230
+ } catch (_unused) {
231
+ return false;
232
+ }
233
+ }
234
+ if (!origin || origin === OriginConstant.ANY) return true;
235
+ return contextOrigin === origin;
236
+ }
237
+
238
+ /**
239
+ * Set a fixed peer (fallback target) for cases where MessageEvent.source is missing.
240
+ *
241
+ * This is useful for "response endpoint" style usage where the peer is already known
242
+ * (e.g. a client bound to an iframe window).
243
+ */
244
+ setFallbackTarget(targetWindow, targetOrigin) {
245
+ this.messageDispatcher.setFallbackTarget(targetWindow, targetOrigin);
246
+ }
247
+
248
+ /**
249
+ * Create a peer-bound outbox using this hub's dispatcher.
250
+ */
251
+ createOutbox(targetWindow, targetOrigin, defaultTargetId) {
252
+ return new RequestIframeEndpointOutbox(this.messageDispatcher, targetWindow, targetOrigin, defaultTargetId);
253
+ }
254
+
255
+ /**
256
+ * Open message processing (register message handlers)
257
+ */
258
+ open() {
259
+ if (this._isOpen) return;
260
+ this.hooks.beforeOpen.call();
261
+ this._isOpen = true;
262
+ if (!this.registerHandlersFn) {
263
+ throw new Error(Messages.HUB_REGISTER_HANDLERS_NOT_SET);
264
+ }
265
+ this.registerHandlersFn();
266
+ this.hooks.afterOpen.call();
267
+ }
268
+
269
+ /**
270
+ * Close message processing (unregister message handlers, but don't release channel)
271
+ */
272
+ close() {
273
+ if (!this._isOpen) return;
274
+ this.hooks.beforeClose.call();
275
+ this._isOpen = false;
276
+
277
+ /** Unregister all handlers */
278
+ this.unregisterFns.forEach(fn => fn());
279
+ this.unregisterFns.length = 0;
280
+ this.hooks.unregisterHandler.call();
281
+ this.hooks.afterClose.call();
282
+ }
283
+
284
+ /**
285
+ * Whether it is open
286
+ */
287
+ get isOpen() {
288
+ return this._isOpen;
289
+ }
290
+
291
+ /**
292
+ * Get secretKey
293
+ */
294
+ get secretKey() {
295
+ return this.messageDispatcher.secretKey;
296
+ }
297
+
298
+ /**
299
+ * Destroy (close and release channel reference)
300
+ */
301
+ destroy() {
302
+ this.hooks.beforeDestroy.call();
303
+ /** Close first */
304
+ this.close();
305
+
306
+ /** Clear all pending maps and timeouts */
307
+ this.pending.clearAll();
308
+ this.warnOnceKeys.clear();
309
+ this.streamCallback = undefined;
310
+
311
+ /** Destroy dispatcher and release channel reference */
312
+ this.messageDispatcher.destroy();
313
+ releaseMessageChannel(this.messageDispatcher.getChannel());
314
+ this.hooks.afterDestroy.call();
315
+ }
316
+ }
@@ -0,0 +1,232 @@
1
+ import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
2
+ import "core-js/modules/es.array.slice.js";
3
+ import "core-js/modules/es.promise.js";
4
+ import "core-js/modules/es.regexp.to-string.js";
5
+ import { MessageType, ProtocolVersion, Messages, formatMessage, MessageRole, WarnOnceKey, buildWarnOnceKey } from '../../constants';
6
+ import { createPingResponder } from '../heartbeat/ping';
7
+ import { SyncHook } from '../../utils/hooks';
8
+ import { requestIframeLog } from '../../utils/logger';
9
+
10
+ /**
11
+ * Pending request awaiting response
12
+ */
13
+
14
+ /**
15
+ * RequestIframeEndpointInbox
16
+ *
17
+ * The endpoint "inbox" is responsible for handling inbound framework messages and
18
+ * driving pending request resolution by requestId.
19
+ *
20
+ * - Registers dispatcher handlers for ACK/ASYNC/RESPONSE/ERROR/STREAM_START + PING/PONG
21
+ * - Manages pending requests via hub.pending
22
+ */
23
+ export class RequestIframeEndpointInbox {
24
+ constructor(hub, versionValidator) {
25
+ _defineProperty(this, "hooks", {
26
+ inbound: new SyncHook(),
27
+ pendingRegistered: new SyncHook(),
28
+ pendingUnregistered: new SyncHook(),
29
+ pendingResolved: new SyncHook(),
30
+ missingPending: new SyncHook()
31
+ });
32
+ this.hub = hub;
33
+ this.versionValidator = versionValidator !== null && versionValidator !== void 0 ? versionValidator : hub.versionValidator;
34
+ }
35
+
36
+ /**
37
+ * Register message handlers on hub.
38
+ */
39
+ registerHandlers() {
40
+ var handlerOptions = this.hub.createHandlerOptions(this.handleVersionError.bind(this));
41
+ handlerOptions.versionValidator = this.versionValidator;
42
+ var boundHandleClientResponse = this.handleClientResponse.bind(this);
43
+ this.hub.registerHandler(MessageType.ACK, boundHandleClientResponse, handlerOptions);
44
+ this.hub.registerHandler(MessageType.ASYNC, boundHandleClientResponse, handlerOptions);
45
+ this.hub.registerHandler(MessageType.RESPONSE, boundHandleClientResponse, handlerOptions);
46
+ this.hub.registerHandler(MessageType.ERROR, boundHandleClientResponse, handlerOptions);
47
+ this.hub.registerHandler(MessageType.PONG, this.handlePong.bind(this), handlerOptions);
48
+ this.hub.registerHandler(MessageType.PING, this.handlePing.bind(this), handlerOptions);
49
+ this.hub.registerHandler(MessageType.STREAM_START, boundHandleClientResponse, handlerOptions);
50
+ }
51
+
52
+ /**
53
+ * Client-side "isConnect" ping helper.
54
+ *
55
+ * - Sends PING(requireAck=true)
56
+ * - Resolves true when ACK or PONG arrives, false on timeout
57
+ */
58
+ pingIsConnect(params) {
59
+ var requestId = `ping_${Date.now()}_${Math.random().toString(36).slice(2)}`;
60
+ return new Promise(resolve => {
61
+ var timeoutId = this.hub.pending.setTimeout(() => {
62
+ this.hub.pending.delete(RequestIframeEndpointInbox.PENDING_IS_CONNECT, requestId);
63
+ resolve(false);
64
+ }, params.timeoutMs);
65
+ this.hub.pending.set(RequestIframeEndpointInbox.PENDING_IS_CONNECT, requestId, {
66
+ resolve,
67
+ timeoutId,
68
+ targetOrigin: params.targetOrigin,
69
+ originValidator: params.originValidator,
70
+ onPeerId: params.onPeerId
71
+ });
72
+ params.peer.sendMessage(MessageType.PING, requestId, {
73
+ requireAck: true,
74
+ targetId: params.targetId
75
+ });
76
+ });
77
+ }
78
+
79
+ /**
80
+ * Register pending request awaiting response
81
+ */
82
+ registerPendingRequest(requestId, resolve, reject, origin, originValidator) {
83
+ this.hub.pending.set(RequestIframeEndpointInbox.PENDING_REQUESTS, requestId, {
84
+ resolve,
85
+ reject,
86
+ origin,
87
+ originValidator
88
+ });
89
+ this.hooks.pendingRegistered.call(requestId, {
90
+ origin
91
+ });
92
+ }
93
+
94
+ /**
95
+ * Cancel pending response
96
+ */
97
+ unregisterPendingRequest(requestId) {
98
+ this.hub.pending.delete(RequestIframeEndpointInbox.PENDING_REQUESTS, requestId);
99
+ this.hooks.pendingUnregistered.call(requestId);
100
+ }
101
+ handlePing(data, context) {
102
+ var _this$hub$instanceId;
103
+ this.hooks.inbound.call(data, context);
104
+ var responder = createPingResponder({
105
+ hub: this.hub,
106
+ handledBy: (_this$hub$instanceId = this.hub.instanceId) !== null && _this$hub$instanceId !== void 0 ? _this$hub$instanceId : MessageRole.CLIENT,
107
+ includeTargetId: true
108
+ });
109
+ responder(data, context);
110
+ }
111
+
112
+ /**
113
+ * Handle protocol version error
114
+ */
115
+ handleVersionError(data, context, version) {
116
+ void context;
117
+ var pending = this.hub.pending.get(RequestIframeEndpointInbox.PENDING_REQUESTS, data.requestId);
118
+ if (pending) {
119
+ this.hub.pending.delete(RequestIframeEndpointInbox.PENDING_REQUESTS, data.requestId);
120
+ pending.reject(new Error(formatMessage(Messages.PROTOCOL_VERSION_TOO_LOW, version, ProtocolVersion.MIN_SUPPORTED)));
121
+ }
122
+ }
123
+
124
+ /**
125
+ * Handle client response
126
+ */
127
+ handleClientResponse(data, context) {
128
+ var _this$hub$instanceId4;
129
+ this.hooks.inbound.call(data, context);
130
+
131
+ /**
132
+ * isConnect waiter:
133
+ * - ACK is sent by the peer when it accepted the PING (auto-ack workflow)
134
+ * - We treat either ACK or PONG as a successful connectivity signal
135
+ */
136
+ if (data.type === MessageType.ACK) {
137
+ var pendingIsConnect = this.hub.pending.get(RequestIframeEndpointInbox.PENDING_IS_CONNECT, data.requestId);
138
+ if (pendingIsConnect) {
139
+ var _this$hub$instanceId3, _pendingIsConnect$onP;
140
+ // Must match the pending target origin (and originValidator if configured)
141
+ if (!this.hub.isOriginAllowedBy(context.origin, data, context, pendingIsConnect.targetOrigin, pendingIsConnect.originValidator)) {
142
+ var _this$hub$instanceId2;
143
+ // Mark handled (and auto-ack if requireAck) but ignore the signal
144
+ context.markAcceptedBy((_this$hub$instanceId2 = this.hub.instanceId) !== null && _this$hub$instanceId2 !== void 0 ? _this$hub$instanceId2 : MessageRole.CLIENT);
145
+ return;
146
+ }
147
+ context.markAcceptedBy((_this$hub$instanceId3 = this.hub.instanceId) !== null && _this$hub$instanceId3 !== void 0 ? _this$hub$instanceId3 : MessageRole.CLIENT);
148
+ this.hub.pending.clearTimeout(pendingIsConnect.timeoutId);
149
+ this.hub.pending.delete(RequestIframeEndpointInbox.PENDING_IS_CONNECT, data.requestId);
150
+ (_pendingIsConnect$onP = pendingIsConnect.onPeerId) === null || _pendingIsConnect$onP === void 0 || _pendingIsConnect$onP.call(pendingIsConnect, data.creatorId);
151
+ pendingIsConnect.resolve(true);
152
+ return;
153
+ }
154
+ }
155
+ var pending = this.hub.pending.get(RequestIframeEndpointInbox.PENDING_REQUESTS, data.requestId);
156
+ if (!pending) {
157
+ /**
158
+ * Pending request not found - ignore by default.
159
+ *
160
+ * If endpoint is already closed/destroyed, emit a warning to help debugging:
161
+ * this usually means the client was recreated/unmounted before the response arrived.
162
+ */
163
+ if (!this.hub.isOpen) {
164
+ this.hooks.missingPending.call(data, context);
165
+ this.hub.warnOnce(buildWarnOnceKey(WarnOnceKey.INBOX_MISSING_PENDING_WHEN_CLOSED, data.requestId), () => {
166
+ requestIframeLog('warn', formatMessage(Messages.CLIENT_SERVER_IGNORED_MESSAGE_WHEN_CLOSED, data.type, data.requestId));
167
+ });
168
+ }
169
+ return;
170
+ }
171
+
172
+ /** Validate origin */
173
+ if (!this.hub.isOriginAllowedBy(context.origin, data, context, pending.origin, pending.originValidator)) {
174
+ return;
175
+ }
176
+
177
+ /**
178
+ * Mark as handled so:
179
+ * - other client instances sharing the same channel won't also process it
180
+ * - MessageDispatcher can run its generalized requireAck auto-ack logic
181
+ */
182
+ context.markAcceptedBy((_this$hub$instanceId4 = this.hub.instanceId) !== null && _this$hub$instanceId4 !== void 0 ? _this$hub$instanceId4 : MessageRole.CLIENT);
183
+
184
+ /** ack, async, and stream_start don't delete pending (stream_start needs to keep pending for stream_data/stream_end) */
185
+ if (data.type === MessageType.ACK || data.type === MessageType.ASYNC || data.type === MessageType.STREAM_START) {
186
+ this.hooks.pendingResolved.call(data.requestId, data);
187
+ pending.resolve(data);
188
+ return;
189
+ }
190
+
191
+ /** response and error delete pending */
192
+ this.hub.pending.delete(RequestIframeEndpointInbox.PENDING_REQUESTS, data.requestId);
193
+ this.hooks.pendingResolved.call(data.requestId, data);
194
+ pending.resolve(data);
195
+ }
196
+
197
+ /**
198
+ * Handle PONG:
199
+ * - If it matches an existing pending request, resolve it.
200
+ * - Otherwise, ignore (facade may still use PONG for isConnect waiter).
201
+ */
202
+ handlePong(data, context) {
203
+ var _this$hub$instanceId7;
204
+ this.hooks.inbound.call(data, context);
205
+ var pendingIsConnect = this.hub.pending.get(RequestIframeEndpointInbox.PENDING_IS_CONNECT, data.requestId);
206
+ if (pendingIsConnect) {
207
+ var _this$hub$instanceId6, _pendingIsConnect$onP2;
208
+ if (!this.hub.isOriginAllowedBy(context.origin, data, context, pendingIsConnect.targetOrigin, pendingIsConnect.originValidator)) {
209
+ var _this$hub$instanceId5;
210
+ context.markAcceptedBy((_this$hub$instanceId5 = this.hub.instanceId) !== null && _this$hub$instanceId5 !== void 0 ? _this$hub$instanceId5 : MessageRole.CLIENT);
211
+ return;
212
+ }
213
+ context.markAcceptedBy((_this$hub$instanceId6 = this.hub.instanceId) !== null && _this$hub$instanceId6 !== void 0 ? _this$hub$instanceId6 : MessageRole.CLIENT);
214
+ this.hub.pending.clearTimeout(pendingIsConnect.timeoutId);
215
+ this.hub.pending.delete(RequestIframeEndpointInbox.PENDING_IS_CONNECT, data.requestId);
216
+ (_pendingIsConnect$onP2 = pendingIsConnect.onPeerId) === null || _pendingIsConnect$onP2 === void 0 || _pendingIsConnect$onP2.call(pendingIsConnect, data.creatorId);
217
+ pendingIsConnect.resolve(true);
218
+ return;
219
+ }
220
+ var pending = this.hub.pending.get(RequestIframeEndpointInbox.PENDING_REQUESTS, data.requestId);
221
+ if (!pending) return;
222
+ if (!this.hub.isOriginAllowedBy(context.origin, data, context, pending.origin, pending.originValidator)) {
223
+ return;
224
+ }
225
+ context.markAcceptedBy((_this$hub$instanceId7 = this.hub.instanceId) !== null && _this$hub$instanceId7 !== void 0 ? _this$hub$instanceId7 : MessageRole.CLIENT);
226
+ this.hub.pending.delete(RequestIframeEndpointInbox.PENDING_REQUESTS, data.requestId);
227
+ this.hooks.pendingResolved.call(data.requestId, data);
228
+ pending.resolve(data);
229
+ }
230
+ }
231
+ _defineProperty(RequestIframeEndpointInbox, "PENDING_REQUESTS", 'inbox:pendingRequests');
232
+ _defineProperty(RequestIframeEndpointInbox, "PENDING_IS_CONNECT", 'inbox:pendingIsConnect');