request-iframe 0.0.2 → 0.0.3

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 (72) hide show
  1. package/README.CN.md +269 -12
  2. package/README.md +266 -11
  3. package/library/__tests__/channel.test.ts +420 -0
  4. package/library/__tests__/debug.test.ts +588 -0
  5. package/library/__tests__/dispatcher.test.ts +481 -0
  6. package/library/__tests__/requestIframe.test.ts +2127 -99
  7. package/library/__tests__/server.test.ts +738 -0
  8. package/library/api/client.d.ts.map +1 -1
  9. package/library/api/client.js +11 -6
  10. package/library/api/server.d.ts +4 -3
  11. package/library/api/server.d.ts.map +1 -1
  12. package/library/api/server.js +25 -7
  13. package/library/constants/index.d.ts +14 -4
  14. package/library/constants/index.d.ts.map +1 -1
  15. package/library/constants/index.js +15 -7
  16. package/library/constants/messages.d.ts +35 -0
  17. package/library/constants/messages.d.ts.map +1 -1
  18. package/library/constants/messages.js +36 -1
  19. package/library/core/client-server.d.ts +101 -0
  20. package/library/core/client-server.d.ts.map +1 -0
  21. package/library/core/client-server.js +266 -0
  22. package/library/core/client.d.ts +22 -6
  23. package/library/core/client.d.ts.map +1 -1
  24. package/library/core/client.js +159 -24
  25. package/library/core/request.d.ts.map +1 -1
  26. package/library/core/response.d.ts +5 -1
  27. package/library/core/response.d.ts.map +1 -1
  28. package/library/core/response.js +85 -70
  29. package/library/core/server-client.d.ts +3 -1
  30. package/library/core/server-client.d.ts.map +1 -1
  31. package/library/core/server-client.js +19 -9
  32. package/library/core/server.d.ts +9 -1
  33. package/library/core/server.d.ts.map +1 -1
  34. package/library/core/server.js +96 -52
  35. package/library/index.d.ts +1 -1
  36. package/library/index.js +2 -2
  37. package/library/interceptors/index.d.ts.map +1 -1
  38. package/library/message/channel.d.ts +3 -1
  39. package/library/message/channel.d.ts.map +1 -1
  40. package/library/message/dispatcher.d.ts +7 -2
  41. package/library/message/dispatcher.d.ts.map +1 -1
  42. package/library/message/dispatcher.js +47 -2
  43. package/library/message/index.d.ts.map +1 -1
  44. package/library/stream/file-stream.d.ts +5 -0
  45. package/library/stream/file-stream.d.ts.map +1 -1
  46. package/library/stream/file-stream.js +41 -12
  47. package/library/stream/index.d.ts.map +1 -1
  48. package/library/stream/readable-stream.d.ts.map +1 -1
  49. package/library/stream/readable-stream.js +32 -30
  50. package/library/stream/types.d.ts +18 -0
  51. package/library/stream/types.d.ts.map +1 -1
  52. package/library/stream/writable-stream.d.ts +1 -0
  53. package/library/stream/writable-stream.d.ts.map +1 -1
  54. package/library/stream/writable-stream.js +7 -2
  55. package/library/types/index.d.ts +80 -28
  56. package/library/types/index.d.ts.map +1 -1
  57. package/library/utils/cache.d.ts +24 -0
  58. package/library/utils/cache.d.ts.map +1 -1
  59. package/library/utils/cache.js +76 -0
  60. package/library/utils/cookie.d.ts.map +1 -1
  61. package/library/utils/debug.d.ts.map +1 -1
  62. package/library/utils/debug.js +382 -20
  63. package/library/utils/index.d.ts +5 -0
  64. package/library/utils/index.d.ts.map +1 -1
  65. package/library/utils/index.js +14 -1
  66. package/library/utils/path-match.d.ts.map +1 -1
  67. package/library/utils/protocol.d.ts.map +1 -1
  68. package/package.json +3 -1
  69. package/react/library/__tests__/index.test.tsx +238 -267
  70. package/react/library/index.d.ts +4 -3
  71. package/react/library/index.d.ts.map +1 -1
  72. package/react/library/index.js +167 -158
@@ -0,0 +1,266 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.RequestIframeClientServer = void 0;
8
+ require("core-js/modules/es.array.iterator.js");
9
+ require("core-js/modules/es.map.js");
10
+ require("core-js/modules/es.string.starts-with.js");
11
+ require("core-js/modules/web.dom-collections.for-each.js");
12
+ require("core-js/modules/web.dom-collections.iterator.js");
13
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
14
+ var _message = require("../message");
15
+ var _cache = require("../utils/cache");
16
+ var _utils = require("../utils");
17
+ var _constants = require("../constants");
18
+ /**
19
+ * Stream message handler callback
20
+ */
21
+
22
+ /**
23
+ * Pending acknowledgment response
24
+ */
25
+
26
+ /**
27
+ * Pending request awaiting response
28
+ */
29
+
30
+ /**
31
+ * ClientServer configuration options
32
+ */
33
+
34
+ /**
35
+ * RequestIframeClientServer - Client-side message server
36
+ * Only handles responses, not requests
37
+ * Uses shared MessageDispatcher (backed by MessageChannel) to listen for and send messages
38
+ */
39
+ class RequestIframeClientServer {
40
+ constructor(options, instanceId) {
41
+ var _options$ackTimeout, _options$versionValid;
42
+ /** Pending responses awaiting client acknowledgment */
43
+ (0, _defineProperty2.default)(this, "pendingAcks", new Map());
44
+ /** Pending requests awaiting response */
45
+ (0, _defineProperty2.default)(this, "pendingRequests", new Map());
46
+ /** List of unregister handler functions */
47
+ (0, _defineProperty2.default)(this, "unregisterFns", []);
48
+ /** Whether opened */
49
+ (0, _defineProperty2.default)(this, "_isOpen", false);
50
+ this.ackTimeout = (_options$ackTimeout = options === null || options === void 0 ? void 0 : options.ackTimeout) !== null && _options$ackTimeout !== void 0 ? _options$ackTimeout : _constants.DefaultTimeout.ACK;
51
+ this.versionValidator = (_options$versionValid = options === null || options === void 0 ? void 0 : options.versionValidator) !== null && _options$versionValid !== void 0 ? _options$versionValid : _utils.isCompatibleVersion;
52
+
53
+ // Get or create shared channel and create dispatcher
54
+ var channel = (0, _cache.getOrCreateMessageChannel)(options === null || options === void 0 ? void 0 : options.secretKey);
55
+ this.dispatcher = new _message.MessageDispatcher(channel, _constants.MessageRole.CLIENT, instanceId);
56
+
57
+ // Auto-open by default (unless explicitly set to false)
58
+ if ((options === null || options === void 0 ? void 0 : options.autoOpen) !== false) {
59
+ this.open();
60
+ }
61
+ }
62
+
63
+ /**
64
+ * Open message handling (register message handlers)
65
+ */
66
+ open() {
67
+ if (this._isOpen) return;
68
+ this._isOpen = true;
69
+ this.registerHandlers();
70
+ }
71
+
72
+ /**
73
+ * Close message handling (unregister message handlers, but don't release channel)
74
+ */
75
+ close() {
76
+ if (!this._isOpen) return;
77
+ this._isOpen = false;
78
+
79
+ // Unregister all handlers
80
+ this.unregisterFns.forEach(fn => fn());
81
+ this.unregisterFns.length = 0;
82
+ }
83
+
84
+ /**
85
+ * Whether opened
86
+ */
87
+ get isOpen() {
88
+ return this._isOpen;
89
+ }
90
+
91
+ /**
92
+ * Register message handlers
93
+ */
94
+ registerHandlers() {
95
+ var handlerOptions = {
96
+ versionValidator: this.versionValidator,
97
+ onVersionError: this.handleVersionError.bind(this)
98
+ };
99
+
100
+ // Handle ACK messages
101
+ this.unregisterFns.push(this.dispatcher.registerHandler(_constants.MessageType.ACK, (data, context) => this.handleClientResponse(data, context), handlerOptions));
102
+
103
+ // Handle ASYNC messages
104
+ this.unregisterFns.push(this.dispatcher.registerHandler(_constants.MessageType.ASYNC, (data, context) => this.handleClientResponse(data, context), handlerOptions));
105
+
106
+ // Handle RESPONSE messages
107
+ this.unregisterFns.push(this.dispatcher.registerHandler(_constants.MessageType.RESPONSE, (data, context) => this.handleClientResponse(data, context), handlerOptions));
108
+
109
+ // Handle ERROR messages
110
+ this.unregisterFns.push(this.dispatcher.registerHandler(_constants.MessageType.ERROR, (data, context) => this.handleClientResponse(data, context), handlerOptions));
111
+
112
+ // Handle RECEIVED messages
113
+ this.unregisterFns.push(this.dispatcher.registerHandler(_constants.MessageType.RECEIVED, data => this.handleReceived(data), handlerOptions));
114
+
115
+ // Handle PONG messages
116
+ this.unregisterFns.push(this.dispatcher.registerHandler(_constants.MessageType.PONG, (data, context) => this.handlePong(data, context), handlerOptions));
117
+
118
+ // Handle stream_start messages (route to handleClientResponse so it reaches send callback)
119
+ // Note: stream_start is handled in send callback, not through streamCallback
120
+ this.unregisterFns.push(this.dispatcher.registerHandler(_constants.MessageType.STREAM_START, (data, context) => {
121
+ // Route to handleClientResponse so it reaches send callback
122
+ this.handleClientResponse(data, context);
123
+ // Don't call streamCallback here - stream_start is handled in send callback
124
+ }, handlerOptions));
125
+
126
+ // Handle other stream messages (stream_data, stream_end, etc.)
127
+ this.unregisterFns.push(this.dispatcher.registerHandler(type => type.startsWith('stream_') && type !== _constants.MessageType.STREAM_START, (data, context) => {
128
+ var _this$streamCallback;
129
+ return (_this$streamCallback = this.streamCallback) === null || _this$streamCallback === void 0 ? void 0 : _this$streamCallback.call(this, data, context);
130
+ }, handlerOptions));
131
+ }
132
+
133
+ /**
134
+ * Handle protocol version error
135
+ */
136
+ handleVersionError(data, context, version) {
137
+ // For response messages, we need to notify the waiting request
138
+ var pending = this.pendingRequests.get(data.requestId);
139
+ if (pending) {
140
+ this.pendingRequests.delete(data.requestId);
141
+ pending.reject(new Error((0, _constants.formatMessage)(_constants.Messages.PROTOCOL_VERSION_TOO_LOW, version, _constants.ProtocolVersion.MIN_SUPPORTED)));
142
+ }
143
+ }
144
+
145
+ /**
146
+ * Handle client response
147
+ */
148
+ handleClientResponse(data, context) {
149
+ var pending = this.pendingRequests.get(data.requestId);
150
+ if (pending) {
151
+ // Validate origin
152
+ if (pending.origin && pending.origin !== '*' && context.origin !== pending.origin) {
153
+ return;
154
+ }
155
+ // ack, async, and stream_start don't delete pending (stream_start needs to keep pending for stream_data/stream_end)
156
+ if (data.type === _constants.MessageType.ACK || data.type === _constants.MessageType.ASYNC || data.type === _constants.MessageType.STREAM_START) {
157
+ pending.resolve(data);
158
+ return;
159
+ }
160
+ // response and error delete pending
161
+ this.pendingRequests.delete(data.requestId);
162
+ pending.resolve(data);
163
+ }
164
+ }
165
+
166
+ /**
167
+ * Handle received acknowledgment
168
+ */
169
+ handleReceived(data) {
170
+ var pending = this.pendingAcks.get(data.requestId);
171
+ if (pending) {
172
+ clearTimeout(pending.timeoutId);
173
+ this.pendingAcks.delete(data.requestId);
174
+ pending.resolve(true);
175
+ }
176
+ }
177
+
178
+ /**
179
+ * Handle pong
180
+ */
181
+ handlePong(data, context) {
182
+ var pending = this.pendingRequests.get(data.requestId);
183
+ if (pending) {
184
+ if (pending.origin && pending.origin !== '*' && context.origin !== pending.origin) {
185
+ return;
186
+ }
187
+ this.pendingRequests.delete(data.requestId);
188
+ pending.resolve(data);
189
+ }
190
+ }
191
+
192
+ /**
193
+ * Set stream message handler callback
194
+ */
195
+ setStreamCallback(callback) {
196
+ this.streamCallback = callback;
197
+ }
198
+
199
+ /** Get secretKey */
200
+ get secretKey() {
201
+ return this.dispatcher.secretKey;
202
+ }
203
+
204
+ /** Get the underlying MessageDispatcher */
205
+ get messageDispatcher() {
206
+ return this.dispatcher;
207
+ }
208
+
209
+ /**
210
+ * Register pending acknowledgment response
211
+ */
212
+ _registerPendingAck(requestId, resolve, reject) {
213
+ var timeoutId = setTimeout(() => {
214
+ this.pendingAcks.delete(requestId);
215
+ resolve(false);
216
+ }, this.ackTimeout);
217
+ this.pendingAcks.set(requestId, {
218
+ resolve,
219
+ reject,
220
+ timeoutId
221
+ });
222
+ }
223
+
224
+ /**
225
+ * Register pending request awaiting response
226
+ */
227
+ _registerPendingRequest(requestId, resolve, reject, origin) {
228
+ this.pendingRequests.set(requestId, {
229
+ resolve,
230
+ reject,
231
+ origin
232
+ });
233
+ }
234
+
235
+ /**
236
+ * Cancel pending response
237
+ */
238
+ _unregisterPendingRequest(requestId) {
239
+ this.pendingRequests.delete(requestId);
240
+ }
241
+
242
+ /**
243
+ * Send ping message
244
+ */
245
+ sendPing(targetWindow, targetOrigin, requestId) {
246
+ this.dispatcher.sendMessage(targetWindow, targetOrigin, _constants.MessageType.PING, requestId);
247
+ }
248
+
249
+ /**
250
+ * Destroy (close and release channel reference)
251
+ */
252
+ destroy() {
253
+ // Close first
254
+ this.close();
255
+
256
+ // Clear pending
257
+ this.pendingRequests.clear();
258
+ this.pendingAcks.forEach(pending => clearTimeout(pending.timeoutId));
259
+ this.pendingAcks.clear();
260
+
261
+ // Destroy dispatcher and release channel reference
262
+ this.dispatcher.destroy();
263
+ (0, _cache.releaseMessageChannel)(this.dispatcher.getChannel());
264
+ }
265
+ }
266
+ exports.RequestIframeClientServer = RequestIframeClientServer;
@@ -1,17 +1,20 @@
1
- import { RequestOptions, Response, RequestIframeClient, RequestDefaults } from '../types';
1
+ import { RequestOptions, Response, RequestIframeClient, RequestDefaults, HeadersConfig } from '../types';
2
2
  import { RequestInterceptorManager, ResponseInterceptorManager } from '../interceptors';
3
- import { RequestIframeClientServer } from './server-client';
3
+ import { RequestIframeClientServer } from './client-server';
4
4
  import { StreamMessageHandler, StreamMessageData } from '../stream';
5
5
  /**
6
6
  * Client configuration options
7
7
  */
8
8
  export interface ClientOptions extends RequestDefaults {
9
9
  secretKey?: string;
10
+ headers?: HeadersConfig;
10
11
  }
11
12
  /**
12
13
  * RequestIframeClient implementation (only responsible for initiating requests, reuses server's listener)
13
14
  */
14
15
  export declare class RequestIframeClientImpl implements RequestIframeClient, StreamMessageHandler {
16
+ /** Unique instance ID */
17
+ readonly id: string;
15
18
  interceptors: {
16
19
  request: RequestInterceptorManager;
17
20
  response: ResponseInterceptorManager;
@@ -24,6 +27,8 @@ export declare class RequestIframeClientImpl implements RequestIframeClient, Str
24
27
  private readonly defaultAckTimeout;
25
28
  private readonly defaultTimeout;
26
29
  private readonly defaultAsyncTimeout;
30
+ /** Initial headers configuration */
31
+ private readonly initialHeaders?;
27
32
  /**
28
33
  * Internal cookies storage
29
34
  * - Automatically includes cookies matching the path when sending requests
@@ -36,7 +41,12 @@ export declare class RequestIframeClientImpl implements RequestIframeClient, Str
36
41
  * value: stream message handler function
37
42
  */
38
43
  private readonly streamHandlers;
39
- constructor(targetWindow: Window, targetOrigin: string, server: RequestIframeClientServer, options?: ClientOptions);
44
+ /**
45
+ * Target server ID (remembered from responses)
46
+ * When a response is received, we remember the server's creatorId as the targetId for future requests
47
+ */
48
+ private _targetServerId?;
49
+ constructor(targetWindow: Window, targetOrigin: string, server: RequestIframeClientServer, options?: ClientOptions, instanceId?: string);
40
50
  /**
41
51
  * Register stream message handler (StreamMessageHandler interface implementation)
42
52
  */
@@ -45,14 +55,20 @@ export declare class RequestIframeClientImpl implements RequestIframeClient, Str
45
55
  * Unregister stream message handler (StreamMessageHandler interface implementation)
46
56
  */
47
57
  unregisterStreamHandler(streamId: string): void;
48
- /**
49
- * Send message (StreamMessageHandler interface implementation)
50
- */
51
58
  postMessage(message: any): void;
52
59
  /**
53
60
  * Dispatch stream message to corresponding handler
54
61
  */
55
62
  private dispatchStreamMessage;
63
+ /**
64
+ * Resolve header value (handle function type headers)
65
+ */
66
+ private resolveHeaderValue;
67
+ /**
68
+ * Merge and resolve headers (initial headers + request headers)
69
+ * Request headers take precedence over initial headers
70
+ */
71
+ private mergeHeaders;
56
72
  /**
57
73
  * Check if server is reachable
58
74
  */
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["client.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,cAAc,EACd,QAAQ,EAGR,mBAAmB,EACnB,eAAe,EAChB,MAAM,UAAU,CAAC;AAKlB,OAAO,EACL,yBAAyB,EACzB,0BAA0B,EAG3B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAY5D,OAAO,EAGL,oBAAoB,EACpB,iBAAiB,EAClB,MAAM,WAAW,CAAC;AAEnB;;GAEG;AACH,MAAM,WAAW,aAAc,SAAQ,eAAe;IACpD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,qBAAa,uBAAwB,YAAW,mBAAmB,EAAE,oBAAoB;IAChF,YAAY;;;MAGjB;IAEF,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA4B;IACnD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAS;IAEpC,oCAAoC;IACpC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAS;IAE7C;;;;OAIG;IACH,OAAO,CAAC,YAAY,CAAkC;IAEtD;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAwD;gBAGrF,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,yBAAyB,EACjC,OAAO,CAAC,EAAE,aAAa;IAkBzB;;OAEG;IACI,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,IAAI,GAAG,IAAI;IAIhG;;OAEG;IACI,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAItD;;OAEG;IACI,WAAW,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI;IAItC;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAY7B;;OAEG;IACI,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;IA+CvB,IAAI,CAAC,CAAC,GAAG,GAAG,EACvB,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC1B,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAmQvB,OAAO,CAAC,UAAU;IAIlB;;OAEG;IACI,SAAS,IAAI,yBAAyB;IAI7C;;OAEG;IACH,IAAW,MAAM,IAAI,OAAO,CAE3B;IAED;;OAEG;IACI,IAAI,IAAI,IAAI;IAInB;;OAEG;IACI,KAAK,IAAI,IAAI;IAIpB;;OAEG;IACI,OAAO,IAAI,IAAI;IAetB;;;OAGG;IACI,UAAU,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAOxD;;;;OAIG;IACI,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAIjE;;;;;OAKG;IACI,SAAS,CACd,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,IAAI,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAC3D,IAAI;IAgBP;;;;OAIG;IACI,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;IAItD;;OAEG;IACI,YAAY,IAAI,IAAI;CAG5B"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/core/client.ts"],"names":[],"mappings":"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"}
@@ -6,7 +6,6 @@ require("core-js/modules/es.array.from.js");
6
6
  require("core-js/modules/es.array.slice.js");
7
7
  require("core-js/modules/es.object.get-own-property-descriptors.js");
8
8
  require("core-js/modules/es.regexp.to-string.js");
9
- require("core-js/modules/web.dom-collections.for-each.js");
10
9
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
11
10
  Object.defineProperty(exports, "__esModule", {
12
11
  value: true
@@ -15,12 +14,16 @@ exports.RequestIframeClientImpl = void 0;
15
14
  var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
16
15
  require("core-js/modules/es.array.iterator.js");
17
16
  require("core-js/modules/es.map.js");
17
+ require("core-js/modules/es.object.entries.js");
18
18
  require("core-js/modules/es.promise.js");
19
19
  require("core-js/modules/es.regexp.exec.js");
20
+ require("core-js/modules/es.string.match.js");
20
21
  require("core-js/modules/es.string.replace.js");
21
22
  require("core-js/modules/es.string.starts-with.js");
23
+ require("core-js/modules/web.dom-collections.for-each.js");
22
24
  require("core-js/modules/web.dom-collections.iterator.js");
23
25
  var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
26
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
24
27
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
25
28
  var _utils = require("../utils");
26
29
  var _interceptors = require("../interceptors");
@@ -39,8 +42,14 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
39
42
  * RequestIframeClient implementation (only responsible for initiating requests, reuses server's listener)
40
43
  */
41
44
  class RequestIframeClientImpl {
42
- constructor(targetWindow, targetOrigin, server, options) {
45
+ /**
46
+ * Target server ID (remembered from responses)
47
+ * When a response is received, we remember the server's creatorId as the targetId for future requests
48
+ */
49
+
50
+ constructor(targetWindow, targetOrigin, server, options, instanceId) {
43
51
  var _options$ackTimeout, _options$timeout, _options$asyncTimeout;
52
+ /** Unique instance ID */
44
53
  (0, _defineProperty2.default)(this, "interceptors", {
45
54
  request: new _interceptors.RequestInterceptorManager(),
46
55
  response: new _interceptors.ResponseInterceptorManager()
@@ -57,6 +66,7 @@ class RequestIframeClientImpl {
57
66
  * value: stream message handler function
58
67
  */
59
68
  (0, _defineProperty2.default)(this, "streamHandlers", new Map());
69
+ this.id = instanceId || (0, _utils.generateInstanceId)();
60
70
  this.targetWindow = targetWindow;
61
71
  this.targetOrigin = targetOrigin;
62
72
  this.server = server;
@@ -67,6 +77,9 @@ class RequestIframeClientImpl {
67
77
  this.defaultTimeout = (_options$timeout = options === null || options === void 0 ? void 0 : options.timeout) !== null && _options$timeout !== void 0 ? _options$timeout : _constants.DefaultTimeout.REQUEST;
68
78
  this.defaultAsyncTimeout = (_options$asyncTimeout = options === null || options === void 0 ? void 0 : options.asyncTimeout) !== null && _options$asyncTimeout !== void 0 ? _options$asyncTimeout : _constants.DefaultTimeout.ASYNC;
69
79
 
80
+ // Save initial headers configuration
81
+ this.initialHeaders = options === null || options === void 0 ? void 0 : options.headers;
82
+
70
83
  // Register stream message processing callback
71
84
  this.server.setStreamCallback(data => {
72
85
  this.dispatchStreamMessage(data);
@@ -87,8 +100,8 @@ class RequestIframeClientImpl {
87
100
  this.streamHandlers.delete(streamId);
88
101
  }
89
102
 
90
- /**
91
- * Send message (StreamMessageHandler interface implementation)
103
+ /*
104
+ Send message (StreamMessageHandler interface implementation)
92
105
  */
93
106
  postMessage(message) {
94
107
  this.server.messageDispatcher.send(this.targetWindow, message, this.targetOrigin);
@@ -110,6 +123,45 @@ class RequestIframeClientImpl {
110
123
  }
111
124
  }
112
125
 
126
+ /**
127
+ * Resolve header value (handle function type headers)
128
+ */
129
+ resolveHeaderValue(value, config) {
130
+ if (typeof value === 'function') {
131
+ return value(config);
132
+ }
133
+ return value;
134
+ }
135
+
136
+ /**
137
+ * Merge and resolve headers (initial headers + request headers)
138
+ * Request headers take precedence over initial headers
139
+ */
140
+ mergeHeaders(config) {
141
+ var resolvedHeaders = {};
142
+
143
+ // First, resolve initial headers
144
+ if (this.initialHeaders) {
145
+ for (var _i = 0, _Object$entries = Object.entries(this.initialHeaders); _i < _Object$entries.length; _i++) {
146
+ var _Object$entries$_i = (0, _slicedToArray2.default)(_Object$entries[_i], 2),
147
+ key = _Object$entries$_i[0],
148
+ value = _Object$entries$_i[1];
149
+ resolvedHeaders[key] = this.resolveHeaderValue(value, config);
150
+ }
151
+ }
152
+
153
+ // Then, merge request headers (request headers take precedence)
154
+ if (config.headers) {
155
+ for (var _i2 = 0, _Object$entries2 = Object.entries(config.headers); _i2 < _Object$entries2.length; _i2++) {
156
+ var _Object$entries2$_i = (0, _slicedToArray2.default)(_Object$entries2[_i2], 2),
157
+ _key = _Object$entries2$_i[0],
158
+ _value = _Object$entries2$_i[1];
159
+ resolvedHeaders[_key] = this.resolveHeaderValue(_value, config);
160
+ }
161
+ }
162
+ return resolvedHeaders;
163
+ }
164
+
113
165
  /**
114
166
  * Check if server is reachable
115
167
  */
@@ -149,7 +201,7 @@ class RequestIframeClientImpl {
149
201
  send(path, body, options) {
150
202
  var _this = this;
151
203
  return (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee() {
152
- var config, processedConfig, processedPath, processedBody, processedHeaders, processedCookies, _processedConfig$ackT, ackTimeout, _processedConfig$time, timeout, _processedConfig$asyn, asyncTimeout, _processedConfig$requ, requestId;
204
+ var config, processedConfig, mergedHeaders, processedPath, processedBody, processedCookies, userTargetId, _processedConfig$ackT, ackTimeout, _processedConfig$time, timeout, _processedConfig$asyn, asyncTimeout, _processedConfig$requ, requestId, targetId;
153
205
  return _regenerator.default.wrap(function (_context) {
154
206
  while (1) switch (_context.prev = _context.next) {
155
207
  case 0:
@@ -161,7 +213,10 @@ class RequestIframeClientImpl {
161
213
  return (0, _interceptors.runRequestInterceptors)(_this.interceptors.request, config);
162
214
  case 1:
163
215
  processedConfig = _context.sent;
164
- processedPath = processedConfig.path, processedBody = processedConfig.body, processedHeaders = processedConfig.headers, processedCookies = processedConfig.cookies, _processedConfig$ackT = processedConfig.ackTimeout, ackTimeout = _processedConfig$ackT === void 0 ? _this.defaultAckTimeout : _processedConfig$ackT, _processedConfig$time = processedConfig.timeout, timeout = _processedConfig$time === void 0 ? _this.defaultTimeout : _processedConfig$time, _processedConfig$asyn = processedConfig.asyncTimeout, asyncTimeout = _processedConfig$asyn === void 0 ? _this.defaultAsyncTimeout : _processedConfig$asyn, _processedConfig$requ = processedConfig.requestId, requestId = _processedConfig$requ === void 0 ? (0, _utils.generateRequestId)() : _processedConfig$requ;
216
+ // Merge and resolve headers (initial headers + request headers)
217
+ mergedHeaders = _this.mergeHeaders(processedConfig);
218
+ processedPath = processedConfig.path, processedBody = processedConfig.body, processedCookies = processedConfig.cookies, userTargetId = processedConfig.targetId, _processedConfig$ackT = processedConfig.ackTimeout, ackTimeout = _processedConfig$ackT === void 0 ? _this.defaultAckTimeout : _processedConfig$ackT, _processedConfig$time = processedConfig.timeout, timeout = _processedConfig$time === void 0 ? _this.defaultTimeout : _processedConfig$time, _processedConfig$asyn = processedConfig.asyncTimeout, asyncTimeout = _processedConfig$asyn === void 0 ? _this.defaultAsyncTimeout : _processedConfig$asyn, _processedConfig$requ = processedConfig.requestId, requestId = _processedConfig$requ === void 0 ? (0, _utils.generateRequestId)() : _processedConfig$requ; // Use user-specified targetId, or remembered target server ID, or undefined
219
+ targetId = userTargetId || _this._targetServerId;
165
220
  return _context.abrupt("return", new Promise((resolve, reject) => {
166
221
  var prefixedPath = _this.prefixPath(processedPath);
167
222
  var done = false;
@@ -174,7 +229,23 @@ class RequestIframeClientImpl {
174
229
  if (done) return;
175
230
  done = true;
176
231
  cleanup();
177
- reject(error);
232
+ // Run response interceptors to allow error logging
233
+ Promise.reject(error).catch(err => {
234
+ // Run through response interceptors' rejected callbacks
235
+ var promise = Promise.reject(err);
236
+ _this.interceptors.response.forEach(interceptor => {
237
+ promise = promise.catch(e => {
238
+ if (interceptor.rejected) {
239
+ return interceptor.rejected(e);
240
+ }
241
+ return Promise.reject(e);
242
+ });
243
+ });
244
+ return promise;
245
+ }).catch(() => {
246
+ // After interceptors, reject with original error
247
+ reject(error);
248
+ });
178
249
  };
179
250
  var setAckTimeout = () => {
180
251
  if (timeoutId) clearTimeout(timeoutId);
@@ -216,6 +287,10 @@ class RequestIframeClientImpl {
216
287
 
217
288
  // Received ACK: server has received request
218
289
  if (data.type === _constants.MessageType.ACK) {
290
+ // Remember server's creatorId as target server ID for future requests
291
+ if (data.creatorId && !_this._targetServerId) {
292
+ _this._targetServerId = data.creatorId;
293
+ }
219
294
  // Switch to request timeout
220
295
  setRequestTimeout();
221
296
  return;
@@ -223,6 +298,10 @@ class RequestIframeClientImpl {
223
298
 
224
299
  // Received ASYNC notification: this is an async task
225
300
  if (data.type === _constants.MessageType.ASYNC) {
301
+ // Remember server's creatorId as target server ID for future requests
302
+ if (data.creatorId && !_this._targetServerId) {
303
+ _this._targetServerId = data.creatorId;
304
+ }
226
305
  // Switch to async timeout
227
306
  setAsyncTimeout();
228
307
  return;
@@ -230,7 +309,7 @@ class RequestIframeClientImpl {
230
309
 
231
310
  // Received stream start message
232
311
  if (data.type === _constants.MessageType.STREAM_START) {
233
- var _streamBody$chunked;
312
+ var _streamBody$chunked, _streamBody$autoResol;
234
313
  done = true;
235
314
  cleanup();
236
315
  var streamBody = data.body;
@@ -238,24 +317,68 @@ class RequestIframeClientImpl {
238
317
  var streamType = streamBody.type || _constants.StreamType.DATA;
239
318
  var streamChunked = (_streamBody$chunked = streamBody.chunked) !== null && _streamBody$chunked !== void 0 ? _streamBody$chunked : true;
240
319
  var streamMetadata = streamBody.metadata;
320
+ var autoResolve = (_streamBody$autoResol = streamBody.autoResolve) !== null && _streamBody$autoResol !== void 0 ? _streamBody$autoResol : false;
241
321
 
242
322
  // Create corresponding readable stream based on stream type
243
- var readableStream;
244
323
  if (streamType === _constants.StreamType.FILE) {
245
- readableStream = new _stream.IframeFileReadableStream(streamId, requestId, _this, {
324
+ var _readableStream = new _stream.IframeFileReadableStream(streamId, requestId, _this, {
246
325
  chunked: streamChunked,
247
326
  metadata: streamMetadata,
248
327
  filename: streamMetadata === null || streamMetadata === void 0 ? void 0 : streamMetadata.filename,
249
328
  mimeType: streamMetadata === null || streamMetadata === void 0 ? void 0 : streamMetadata.mimeType,
250
329
  size: streamMetadata === null || streamMetadata === void 0 ? void 0 : streamMetadata.size
251
330
  });
252
- } else {
253
- readableStream = new _stream.IframeReadableStream(streamId, requestId, _this, {
254
- type: streamType,
255
- chunked: streamChunked,
256
- metadata: streamMetadata
257
- });
331
+
332
+ // If autoResolve is enabled, automatically read and convert to File/Blob
333
+ if (autoResolve) {
334
+ var _data$headers;
335
+ // Extract fileName from headers if available
336
+ var contentDisposition = (_data$headers = data.headers) === null || _data$headers === void 0 ? void 0 : _data$headers[_constants.HttpHeader.CONTENT_DISPOSITION];
337
+ var fileName;
338
+ if (contentDisposition) {
339
+ var disposition = typeof contentDisposition === 'string' ? contentDisposition : contentDisposition[0];
340
+ var filenameMatch = disposition.match(/filename="?([^"]+)"?/i);
341
+ if (filenameMatch) {
342
+ fileName = filenameMatch[1];
343
+ }
344
+ }
345
+ // Fallback to stream metadata if not found in headers
346
+ fileName = fileName || (streamMetadata === null || streamMetadata === void 0 ? void 0 : streamMetadata.filename) || _readableStream.filename;
347
+
348
+ // Use stream's readAsFile or readAsBlob method
349
+ var fileDataPromise = fileName ? _readableStream.readAsFile(fileName) : _readableStream.readAsBlob();
350
+ fileDataPromise.then(fileData => {
351
+ var resp = {
352
+ data: fileData,
353
+ status: data.status || _constants.HttpStatus.OK,
354
+ statusText: data.statusText || _constants.HttpStatusText[_constants.HttpStatus.OK],
355
+ requestId,
356
+ headers: data.headers
357
+ };
358
+ return (0, _interceptors.runResponseInterceptors)(_this.interceptors.response, resp);
359
+ }).then(resolve).catch(reject);
360
+ return;
361
+ }
362
+
363
+ // Non-autoResolve: return file stream directly
364
+ var _resp = {
365
+ data: undefined,
366
+ status: data.status || _constants.HttpStatus.OK,
367
+ statusText: data.statusText || _constants.HttpStatusText[_constants.HttpStatus.OK],
368
+ requestId,
369
+ headers: data.headers,
370
+ stream: _readableStream
371
+ };
372
+ (0, _interceptors.runResponseInterceptors)(_this.interceptors.response, _resp).then(resolve).catch(reject);
373
+ return;
258
374
  }
375
+
376
+ // Non-file stream: create regular readable stream
377
+ var readableStream = new _stream.IframeReadableStream(streamId, requestId, _this, {
378
+ type: streamType,
379
+ chunked: streamChunked,
380
+ metadata: streamMetadata
381
+ });
259
382
  var resp = {
260
383
  data: undefined,
261
384
  status: data.status || _constants.HttpStatus.OK,
@@ -279,10 +402,16 @@ class RequestIframeClientImpl {
279
402
  done = true;
280
403
  cleanup();
281
404
 
405
+ // Remember server's creatorId as target server ID for future requests
406
+ if (data.creatorId && !_this._targetServerId) {
407
+ _this._targetServerId = data.creatorId;
408
+ }
409
+
282
410
  // If server requires acknowledgment, send received message
283
411
  if (data.requireAck) {
284
412
  _this.server.messageDispatcher.sendMessage(_this.targetWindow, _this.targetOrigin, _constants.MessageType.RECEIVED, requestId, {
285
- path: prefixedPath
413
+ path: prefixedPath,
414
+ targetId: data.creatorId
286
415
  });
287
416
  }
288
417
 
@@ -303,25 +432,30 @@ class RequestIframeClientImpl {
303
432
  _iterator.f();
304
433
  }
305
434
  }
306
- var _resp = {
435
+ var _resp2 = {
307
436
  data: data.data,
308
437
  status: data.status || _constants.HttpStatus.OK,
309
438
  statusText: data.statusText || _constants.HttpStatusText[_constants.HttpStatus.OK],
310
439
  requestId,
311
- headers: data.headers,
312
- fileData: data.fileData
440
+ headers: data.headers
313
441
  };
314
- (0, _interceptors.runResponseInterceptors)(_this.interceptors.response, _resp).then(resolve).catch(reject);
442
+ (0, _interceptors.runResponseInterceptors)(_this.interceptors.response, _resp2).then(resolve).catch(reject);
315
443
  return;
316
444
  }
317
445
 
318
446
  // Received error
319
447
  if (data.type === _constants.MessageType.ERROR) {
320
448
  var _data$error, _data$error2;
449
+ // Remember server's creatorId as target server ID for future requests
450
+ if (data.creatorId && !_this._targetServerId) {
451
+ _this._targetServerId = data.creatorId;
452
+ }
453
+
321
454
  // If server requires acknowledgment, send received message
322
455
  if (data.requireAck) {
323
456
  _this.server.messageDispatcher.sendMessage(_this.targetWindow, _this.targetOrigin, _constants.MessageType.RECEIVED, requestId, {
324
- path: prefixedPath
457
+ path: prefixedPath,
458
+ targetId: data.creatorId
325
459
  });
326
460
  }
327
461
  var err = {
@@ -357,8 +491,9 @@ class RequestIframeClientImpl {
357
491
  _this.server.messageDispatcher.sendMessage(_this.targetWindow, _this.targetOrigin, _constants.MessageType.REQUEST, requestId, {
358
492
  path: prefixedPath,
359
493
  body: processedBody,
360
- headers: processedHeaders,
361
- cookies: mergedCookies
494
+ headers: mergedHeaders,
495
+ cookies: mergedCookies,
496
+ targetId
362
497
  });
363
498
  }));
364
499
  case 2: