request-iframe 0.0.3 → 0.0.4

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 (53) hide show
  1. package/QUICKSTART.CN.md +35 -8
  2. package/QUICKSTART.md +35 -8
  3. package/README.CN.md +170 -24
  4. package/README.md +230 -19
  5. package/library/__tests__/coverage-branches.test.ts +356 -0
  6. package/library/__tests__/requestIframe.test.ts +1008 -58
  7. package/library/__tests__/stream.test.ts +46 -15
  8. package/library/api/client.d.ts.map +1 -1
  9. package/library/api/client.js +1 -0
  10. package/library/constants/messages.d.ts +2 -0
  11. package/library/constants/messages.d.ts.map +1 -1
  12. package/library/constants/messages.js +2 -0
  13. package/library/core/client-server.d.ts +4 -0
  14. package/library/core/client-server.d.ts.map +1 -1
  15. package/library/core/client-server.js +45 -22
  16. package/library/core/client.d.ts +31 -4
  17. package/library/core/client.d.ts.map +1 -1
  18. package/library/core/client.js +471 -284
  19. package/library/core/request.d.ts +3 -1
  20. package/library/core/request.d.ts.map +1 -1
  21. package/library/core/request.js +2 -1
  22. package/library/core/response.d.ts +26 -4
  23. package/library/core/response.d.ts.map +1 -1
  24. package/library/core/response.js +142 -81
  25. package/library/core/server.d.ts +13 -0
  26. package/library/core/server.d.ts.map +1 -1
  27. package/library/core/server.js +211 -6
  28. package/library/index.d.ts +2 -1
  29. package/library/index.d.ts.map +1 -1
  30. package/library/index.js +32 -3
  31. package/library/message/dispatcher.d.ts.map +1 -1
  32. package/library/message/dispatcher.js +4 -3
  33. package/library/stream/index.d.ts +11 -1
  34. package/library/stream/index.d.ts.map +1 -1
  35. package/library/stream/index.js +21 -3
  36. package/library/stream/types.d.ts +2 -2
  37. package/library/stream/types.d.ts.map +1 -1
  38. package/library/stream/writable-stream.d.ts +1 -1
  39. package/library/stream/writable-stream.d.ts.map +1 -1
  40. package/library/stream/writable-stream.js +8 -10
  41. package/library/types/index.d.ts +26 -4
  42. package/library/types/index.d.ts.map +1 -1
  43. package/library/utils/index.d.ts +14 -0
  44. package/library/utils/index.d.ts.map +1 -1
  45. package/library/utils/index.js +99 -1
  46. package/library/utils/path-match.d.ts +16 -0
  47. package/library/utils/path-match.d.ts.map +1 -1
  48. package/library/utils/path-match.js +65 -0
  49. package/package.json +2 -1
  50. package/react/library/__tests__/index.test.tsx +44 -22
  51. package/react/library/index.d.ts.map +1 -1
  52. package/react/library/index.js +81 -23
  53. package/react/package.json +7 -0
@@ -1,13 +1,15 @@
1
1
  /**
2
2
  * Stream functionality tests
3
3
  */
4
+ import type { MessageChannel } from '../message';
4
5
  import {
5
6
  IframeWritableStream,
6
7
  IframeReadableStream,
7
8
  IframeFileWritableStream,
8
9
  IframeFileReadableStream,
9
10
  isIframeReadableStream,
10
- isIframeFileStream,
11
+ isIframeFileReadableStream,
12
+ isIframeFileWritableStream,
11
13
  StreamMessageHandler
12
14
  } from '../stream';
13
15
 
@@ -15,12 +17,17 @@ describe('Stream', () => {
15
17
  describe('IframeWritableStream', () => {
16
18
  let mockTargetWindow: Window;
17
19
  let mockPostMessage: jest.Mock;
20
+ /** Mock channel: only send() is used by WritableStream */
21
+ let mockChannel: MessageChannel;
18
22
 
19
23
  beforeEach(() => {
20
24
  mockPostMessage = jest.fn();
21
25
  mockTargetWindow = {
22
26
  postMessage: mockPostMessage
23
27
  } as any;
28
+ mockChannel = {
29
+ send: (target: Window, message: any, origin: string) => target.postMessage(message, origin)
30
+ } as unknown as MessageChannel;
24
31
  });
25
32
 
26
33
  it('should create stream with default options', () => {
@@ -69,7 +76,8 @@ describe('Stream', () => {
69
76
  requestId: 'req-123',
70
77
  targetWindow: mockTargetWindow,
71
78
  targetOrigin: 'https://example.com',
72
- secretKey: 'test'
79
+ secretKey: 'test',
80
+ channel: mockChannel
73
81
  });
74
82
 
75
83
  await stream.start();
@@ -98,7 +106,8 @@ describe('Stream', () => {
98
106
  requestId: 'req-123',
99
107
  targetWindow: mockTargetWindow,
100
108
  targetOrigin: 'https://example.com',
101
- secretKey: 'test'
109
+ secretKey: 'test',
110
+ channel: mockChannel
102
111
  });
103
112
 
104
113
  await stream.start();
@@ -115,7 +124,8 @@ describe('Stream', () => {
115
124
  requestId: 'req-123',
116
125
  targetWindow: mockTargetWindow,
117
126
  targetOrigin: 'https://example.com',
118
- secretKey: 'test'
127
+ secretKey: 'test',
128
+ channel: mockChannel
119
129
  });
120
130
 
121
131
  await stream.start();
@@ -136,7 +146,8 @@ describe('Stream', () => {
136
146
  requestId: 'req-123',
137
147
  targetWindow: mockTargetWindow,
138
148
  targetOrigin: 'https://example.com',
139
- secretKey: 'test'
149
+ secretKey: 'test',
150
+ channel: mockChannel
140
151
  });
141
152
 
142
153
  await stream.start();
@@ -159,7 +170,8 @@ describe('Stream', () => {
159
170
  requestId: 'req-123',
160
171
  targetWindow: mockTargetWindow,
161
172
  targetOrigin: 'https://example.com',
162
- secretKey: 'test'
173
+ secretKey: 'test',
174
+ channel: mockChannel
163
175
  });
164
176
 
165
177
  await stream.start();
@@ -174,7 +186,8 @@ describe('Stream', () => {
174
186
  requestId: 'req-123',
175
187
  targetWindow: mockTargetWindow,
176
188
  targetOrigin: 'https://example.com',
177
- secretKey: 'test'
189
+ secretKey: 'test',
190
+ channel: mockChannel
178
191
  });
179
192
 
180
193
  stream.cancel('User cancelled');
@@ -192,7 +205,8 @@ describe('Stream', () => {
192
205
  requestId: 'req-123',
193
206
  targetWindow: mockTargetWindow,
194
207
  targetOrigin: 'https://example.com',
195
- secretKey: 'test'
208
+ secretKey: 'test',
209
+ channel: mockChannel
196
210
  });
197
211
 
198
212
  // Manually set state to ended (simulating already ended)
@@ -237,7 +251,8 @@ describe('Stream', () => {
237
251
  requestId: 'req-123',
238
252
  targetWindow: mockTargetWindow,
239
253
  targetOrigin: 'https://example.com',
240
- secretKey: 'test'
254
+ secretKey: 'test',
255
+ channel: mockChannel
241
256
  });
242
257
 
243
258
  stream.cancel('User cancelled');
@@ -261,7 +276,8 @@ describe('Stream', () => {
261
276
  requestId: 'req-123',
262
277
  targetWindow: mockTargetWindow,
263
278
  targetOrigin: 'https://example.com',
264
- secretKey: 'test'
279
+ secretKey: 'test',
280
+ channel: mockChannel
265
281
  });
266
282
 
267
283
  await stream.start();
@@ -284,7 +300,8 @@ describe('Stream', () => {
284
300
  requestId: 'req-123',
285
301
  targetWindow: mockTargetWindow,
286
302
  targetOrigin: 'https://example.com',
287
- secretKey: 'test'
303
+ secretKey: 'test',
304
+ channel: mockChannel
288
305
  });
289
306
 
290
307
  const startPromise = stream.start();
@@ -637,14 +654,28 @@ describe('Stream', () => {
637
654
  expect(isIframeReadableStream('string')).toBe(false);
638
655
  });
639
656
 
640
- it('isIframeFileStream should return true for IframeFileReadableStream', () => {
657
+ it('isIframeFileReadableStream should return true for IframeFileReadableStream', () => {
641
658
  const stream = new IframeFileReadableStream('id', 'reqId', mockHandler);
642
- expect(isIframeFileStream(stream)).toBe(true);
659
+ expect(isIframeFileReadableStream(stream)).toBe(true);
643
660
  });
644
661
 
645
- it('isIframeFileStream should return false for regular IframeReadableStream', () => {
662
+ it('isIframeFileReadableStream should return false for regular IframeReadableStream', () => {
646
663
  const stream = new IframeReadableStream('id', 'reqId', mockHandler);
647
- expect(isIframeFileStream(stream)).toBe(false);
664
+ expect(isIframeFileReadableStream(stream)).toBe(false);
665
+ });
666
+
667
+ it('isIframeFileWritableStream should return true for IframeFileWritableStream', () => {
668
+ const stream = new IframeFileWritableStream({
669
+ filename: 'test.txt',
670
+ mimeType: 'text/plain',
671
+ next: async () => ({ data: btoa('test'), done: true })
672
+ });
673
+ expect(isIframeFileWritableStream(stream)).toBe(true);
674
+ });
675
+
676
+ it('isIframeFileWritableStream should return false for regular IframeWritableStream', () => {
677
+ const stream = new IframeWritableStream();
678
+ expect(isIframeFileWritableStream(stream)).toBe(false);
648
679
  });
649
680
  });
650
681
  });
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,mBAAmB,EAAE,0BAA0B,EAAE,MAAM,UAAU,CAAC;AAO1F;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,iBAAiB,GAAG,MAAM,EAClC,OAAO,CAAC,EAAE,0BAA0B,GACnC,mBAAmB,CA+CrB;AAED;;;GAGG;AACH,wBAAgB,6BAA6B,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAKtE"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,mBAAmB,EAAE,0BAA0B,EAAE,MAAM,UAAU,CAAC;AAO1F;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,iBAAiB,GAAG,MAAM,EAClC,OAAO,CAAC,EAAE,0BAA0B,GACnC,mBAAmB,CAgDrB;AAED;;;GAGG;AACH,wBAAgB,6BAA6B,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAKtE"}
@@ -55,6 +55,7 @@ function requestIframeClient(target, options) {
55
55
  ackTimeout: options === null || options === void 0 ? void 0 : options.ackTimeout,
56
56
  timeout: options === null || options === void 0 ? void 0 : options.timeout,
57
57
  asyncTimeout: options === null || options === void 0 ? void 0 : options.asyncTimeout,
58
+ returnData: options === null || options === void 0 ? void 0 : options.returnData,
58
59
  headers: options === null || options === void 0 ? void 0 : options.headers
59
60
  }, instanceId);
60
61
 
@@ -33,6 +33,8 @@ declare const defaultMessages: {
33
33
  readonly ERROR: "Error";
34
34
  /** Client errors */
35
35
  readonly IFRAME_NOT_READY: "iframe.contentWindow is not available";
36
+ /** ClientServer warnings */
37
+ readonly CLIENT_SERVER_IGNORED_MESSAGE_WHEN_CLOSED: "Ignored message because client server is closed/destroyed (type: {0}, requestId: {1})";
36
38
  /** Stream related messages */
37
39
  readonly STREAM_NOT_BOUND: "Stream is not bound to a request context";
38
40
  readonly STREAM_ALREADY_STARTED: "Stream has already started";
@@ -1 +1 @@
1
- {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/constants/messages.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;GAEG;AACH,QAAA,MAAM,eAAe;IACnB,8BAA8B;;;;IAK9B,4BAA4B;;;;;IAM5B,qBAAqB;;;;IAKrB,8BAA8B;;;;;;IAO9B,oBAAoB;;IAGpB,8BAA8B;;;;;;;IAQ9B,8BAA8B;;;;;;;;;;;;;;;;;IAkB9B,8BAA8B;;;;;;;;;;;;;;;;;;CAkBtB,CAAC;AAEX;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,OAAO,eAAe,CAAC;AAOtD;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAIxD,CAAC;AAEH;;;GAGG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,GAAG,IAAI,CAE/E;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,IAAI,CAEpC;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,GAAG,MAAM,CAKpF;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAElE"}
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/constants/messages.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;GAEG;AACH,QAAA,MAAM,eAAe;IACnB,8BAA8B;;;;IAK9B,4BAA4B;;;;;IAM5B,qBAAqB;;;;IAKrB,8BAA8B;;;;;;IAO9B,oBAAoB;;IAGpB,4BAA4B;;IAI5B,8BAA8B;;;;;;;IAQ9B,8BAA8B;;;;;;;;;;;;;;;;;IAkB9B,8BAA8B;;;;;;;;;;;;;;;;;;CAkBtB,CAAC;AAEX;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,OAAO,eAAe,CAAC;AAOtD;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAIxD,CAAC;AAEH;;;GAGG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,GAAG,IAAI,CAE/E;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,IAAI,CAEpC;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,GAAG,MAAM,CAKpF;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAElE"}
@@ -53,6 +53,8 @@ var defaultMessages = {
53
53
  ERROR: 'Error',
54
54
  /** Client errors */
55
55
  IFRAME_NOT_READY: 'iframe.contentWindow is not available',
56
+ /** ClientServer warnings */
57
+ CLIENT_SERVER_IGNORED_MESSAGE_WHEN_CLOSED: 'Ignored message because client server is closed/destroyed (type: {0}, requestId: {1})',
56
58
  /** Stream related messages */
57
59
  STREAM_NOT_BOUND: 'Stream is not bound to a request context',
58
60
  STREAM_ALREADY_STARTED: 'Stream has already started',
@@ -30,6 +30,10 @@ export declare class RequestIframeClientServer {
30
30
  private readonly pendingAcks;
31
31
  /** Pending requests awaiting response */
32
32
  private readonly pendingRequests;
33
+ /**
34
+ * Avoid spamming logs for the same requestId when closed/destroyed
35
+ */
36
+ private readonly warnedMissingPendingWhenClosed;
33
37
  /** Stream message callback */
34
38
  private streamCallback?;
35
39
  /** List of unregister handler functions */
@@ -1 +1 @@
1
- {"version":3,"file":"client-server.d.ts","sourceRoot":"","sources":["../../src/core/client-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAKjF;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG,CAAC,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,cAAc,KAAK,IAAI,CAAC;AAoB7F;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,4BAA4B;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kBAAkB;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iFAAiF;IACjF,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,sFAAsF;IACtF,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;GAIG;AACH,qBAAa,yBAAyB;IACpC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAoB;IAC/C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAmB;IAEpD,uDAAuD;IACvD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAiC;IAE7D,yCAAyC;IACzC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAqC;IAErE,8BAA8B;IAC9B,OAAO,CAAC,cAAc,CAAC,CAAwB;IAE/C,2CAA2C;IAC3C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAyB;IAEvD,qBAAqB;IACrB,OAAO,CAAC,OAAO,CAAS;gBAEL,OAAO,CAAC,EAAE,mBAAmB,EAAE,UAAU,CAAC,EAAE,MAAM;IAcrE;;OAEG;IACI,IAAI,IAAI,IAAI;IAMnB;;OAEG;IACI,KAAK,IAAI,IAAI;IASpB;;OAEG;IACH,IAAW,MAAM,IAAI,OAAO,CAE3B;IAED;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAoFxB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAW1B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAkB5B;;OAEG;IACH,OAAO,CAAC,cAAc;IAStB;;OAEG;IACH,OAAO,CAAC,UAAU;IAWlB;;OAEG;IACI,iBAAiB,CAAC,QAAQ,EAAE,qBAAqB,GAAG,IAAI;IAI/D,oBAAoB;IACpB,IAAW,SAAS,IAAI,MAAM,GAAG,SAAS,CAEzC;IAED,2CAA2C;IAC3C,IAAW,iBAAiB,IAAI,iBAAiB,CAEhD;IAED;;OAEG;IACI,mBAAmB,CACxB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,EACpC,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAC7B,IAAI;IASP;;OAEG;IACI,uBAAuB,CAC5B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,IAAI,EACxC,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,EAC9B,MAAM,CAAC,EAAE,MAAM,GACd,IAAI;IAIP;;OAEG;IACI,yBAAyB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAIzD;;OAEG;IACI,QAAQ,CAAC,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAIpF;;OAEG;IACI,OAAO,IAAI,IAAI;CAavB"}
1
+ {"version":3,"file":"client-server.d.ts","sourceRoot":"","sources":["../../src/core/client-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAKjF;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG,CAAC,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,cAAc,KAAK,IAAI,CAAC;AAoB7F;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,4BAA4B;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kBAAkB;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iFAAiF;IACjF,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,sFAAsF;IACtF,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;GAIG;AACH,qBAAa,yBAAyB;IACpC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAoB;IAC/C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAmB;IAEpD,uDAAuD;IACvD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAiC;IAE7D,yCAAyC;IACzC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAqC;IAErE;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,8BAA8B,CAAqB;IAEpE,8BAA8B;IAC9B,OAAO,CAAC,cAAc,CAAC,CAAwB;IAE/C,2CAA2C;IAC3C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAyB;IAEvD,qBAAqB;IACrB,OAAO,CAAC,OAAO,CAAS;gBAEL,OAAO,CAAC,EAAE,mBAAmB,EAAE,UAAU,CAAC,EAAE,MAAM;IAcrE;;OAEG;IACI,IAAI,IAAI,IAAI;IAMnB;;OAEG;IACI,KAAK,IAAI,IAAI;IASpB;;OAEG;IACH,IAAW,MAAM,IAAI,OAAO,CAE3B;IAED;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAmFxB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAW1B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAoC5B;;OAEG;IACH,OAAO,CAAC,cAAc;IAStB;;OAEG;IACH,OAAO,CAAC,UAAU;IAWlB;;OAEG;IACI,iBAAiB,CAAC,QAAQ,EAAE,qBAAqB,GAAG,IAAI;IAI/D,oBAAoB;IACpB,IAAW,SAAS,IAAI,MAAM,GAAG,SAAS,CAEzC;IAED,2CAA2C;IAC3C,IAAW,iBAAiB,IAAI,iBAAiB,CAEhD;IAED;;OAEG;IACI,mBAAmB,CACxB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,EACpC,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAC7B,IAAI;IASP;;OAEG;IACI,uBAAuB,CAC5B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,IAAI,EACxC,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,EAC9B,MAAM,CAAC,EAAE,MAAM,GACd,IAAI;IAIP;;OAEG;IACI,yBAAyB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAIzD;;OAEG;IACI,QAAQ,CAAC,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAIpF;;OAEG;IACI,OAAO,IAAI,IAAI;CAcvB"}
@@ -7,6 +7,7 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports.RequestIframeClientServer = void 0;
8
8
  require("core-js/modules/es.array.iterator.js");
9
9
  require("core-js/modules/es.map.js");
10
+ require("core-js/modules/es.set.js");
10
11
  require("core-js/modules/es.string.starts-with.js");
11
12
  require("core-js/modules/web.dom-collections.for-each.js");
12
13
  require("core-js/modules/web.dom-collections.iterator.js");
@@ -43,6 +44,10 @@ class RequestIframeClientServer {
43
44
  (0, _defineProperty2.default)(this, "pendingAcks", new Map());
44
45
  /** Pending requests awaiting response */
45
46
  (0, _defineProperty2.default)(this, "pendingRequests", new Map());
47
+ /**
48
+ * Avoid spamming logs for the same requestId when closed/destroyed
49
+ */
50
+ (0, _defineProperty2.default)(this, "warnedMissingPendingWhenClosed", new Set());
46
51
  /** List of unregister handler functions */
47
52
  (0, _defineProperty2.default)(this, "unregisterFns", []);
48
53
  /** Whether opened */
@@ -97,31 +102,30 @@ class RequestIframeClientServer {
97
102
  onVersionError: this.handleVersionError.bind(this)
98
103
  };
99
104
 
105
+ // Bind handleClientResponse to ensure correct 'this' context
106
+ var boundHandleClientResponse = this.handleClientResponse.bind(this);
107
+
100
108
  // Handle ACK messages
101
- this.unregisterFns.push(this.dispatcher.registerHandler(_constants.MessageType.ACK, (data, context) => this.handleClientResponse(data, context), handlerOptions));
109
+ this.unregisterFns.push(this.dispatcher.registerHandler(_constants.MessageType.ACK, boundHandleClientResponse, handlerOptions));
102
110
 
103
111
  // Handle ASYNC messages
104
- this.unregisterFns.push(this.dispatcher.registerHandler(_constants.MessageType.ASYNC, (data, context) => this.handleClientResponse(data, context), handlerOptions));
112
+ this.unregisterFns.push(this.dispatcher.registerHandler(_constants.MessageType.ASYNC, boundHandleClientResponse, handlerOptions));
105
113
 
106
114
  // Handle RESPONSE messages
107
- this.unregisterFns.push(this.dispatcher.registerHandler(_constants.MessageType.RESPONSE, (data, context) => this.handleClientResponse(data, context), handlerOptions));
115
+ this.unregisterFns.push(this.dispatcher.registerHandler(_constants.MessageType.RESPONSE, boundHandleClientResponse, handlerOptions));
108
116
 
109
117
  // Handle ERROR messages
110
- this.unregisterFns.push(this.dispatcher.registerHandler(_constants.MessageType.ERROR, (data, context) => this.handleClientResponse(data, context), handlerOptions));
118
+ this.unregisterFns.push(this.dispatcher.registerHandler(_constants.MessageType.ERROR, boundHandleClientResponse, handlerOptions));
111
119
 
112
120
  // Handle RECEIVED messages
113
- this.unregisterFns.push(this.dispatcher.registerHandler(_constants.MessageType.RECEIVED, data => this.handleReceived(data), handlerOptions));
121
+ this.unregisterFns.push(this.dispatcher.registerHandler(_constants.MessageType.RECEIVED, this.handleReceived.bind(this), handlerOptions));
114
122
 
115
123
  // Handle PONG messages
116
- this.unregisterFns.push(this.dispatcher.registerHandler(_constants.MessageType.PONG, (data, context) => this.handlePong(data, context), handlerOptions));
124
+ this.unregisterFns.push(this.dispatcher.registerHandler(_constants.MessageType.PONG, this.handlePong.bind(this), handlerOptions));
117
125
 
118
126
  // Handle stream_start messages (route to handleClientResponse so it reaches send callback)
119
127
  // 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));
128
+ this.unregisterFns.push(this.dispatcher.registerHandler(_constants.MessageType.STREAM_START, boundHandleClientResponse, handlerOptions));
125
129
 
126
130
  // Handle other stream messages (stream_data, stream_end, etc.)
127
131
  this.unregisterFns.push(this.dispatcher.registerHandler(type => type.startsWith('stream_') && type !== _constants.MessageType.STREAM_START, (data, context) => {
@@ -147,20 +151,38 @@ class RequestIframeClientServer {
147
151
  */
148
152
  handleClientResponse(data, context) {
149
153
  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;
154
+ if (!pending) {
155
+ /**
156
+ * Pending request not found - ignore by default.
157
+ *
158
+ * If client server is already closed/destroyed, emit a warning to help debugging:
159
+ * this usually means the client was recreated/unmounted before the response arrived.
160
+ */
161
+ if (!this._isOpen) {
162
+ var key = data.requestId;
163
+ if (!this.warnedMissingPendingWhenClosed.has(key)) {
164
+ this.warnedMissingPendingWhenClosed.add(key);
165
+ // eslint-disable-next-line no-console
166
+ console.warn((0, _constants.formatMessage)(_constants.Messages.CLIENT_SERVER_IGNORED_MESSAGE_WHEN_CLOSED, data.type, data.requestId));
167
+ }
159
168
  }
160
- // response and error delete pending
161
- this.pendingRequests.delete(data.requestId);
169
+ return;
170
+ }
171
+
172
+ // Validate origin
173
+ if (pending.origin && pending.origin !== '*' && context.origin !== pending.origin) {
174
+ return;
175
+ }
176
+
177
+ // ack, async, and stream_start don't delete pending (stream_start needs to keep pending for stream_data/stream_end)
178
+ if (data.type === _constants.MessageType.ACK || data.type === _constants.MessageType.ASYNC || data.type === _constants.MessageType.STREAM_START) {
162
179
  pending.resolve(data);
180
+ return;
163
181
  }
182
+
183
+ // response and error delete pending
184
+ this.pendingRequests.delete(data.requestId);
185
+ pending.resolve(data);
164
186
  }
165
187
 
166
188
  /**
@@ -257,6 +279,7 @@ class RequestIframeClientServer {
257
279
  this.pendingRequests.clear();
258
280
  this.pendingAcks.forEach(pending => clearTimeout(pending.timeoutId));
259
281
  this.pendingAcks.clear();
282
+ this.warnedMissingPendingWhenClosed.clear();
260
283
 
261
284
  // Destroy dispatcher and release channel reference
262
285
  this.dispatcher.destroy();
@@ -1,7 +1,7 @@
1
1
  import { RequestOptions, Response, RequestIframeClient, RequestDefaults, HeadersConfig } from '../types';
2
2
  import { RequestInterceptorManager, ResponseInterceptorManager } from '../interceptors';
3
3
  import { RequestIframeClientServer } from './client-server';
4
- import { StreamMessageHandler, StreamMessageData } from '../stream';
4
+ import { IframeWritableStream, StreamMessageHandler, StreamMessageData } from '../stream';
5
5
  /**
6
6
  * Client configuration options
7
7
  */
@@ -19,7 +19,7 @@ export declare class RequestIframeClientImpl implements RequestIframeClient, Str
19
19
  request: RequestInterceptorManager;
20
20
  response: ResponseInterceptorManager;
21
21
  };
22
- private readonly targetWindow;
22
+ readonly targetWindow: Window;
23
23
  private readonly targetOrigin;
24
24
  private readonly server;
25
25
  private readonly secretKey?;
@@ -27,6 +27,8 @@ export declare class RequestIframeClientImpl implements RequestIframeClient, Str
27
27
  private readonly defaultAckTimeout;
28
28
  private readonly defaultTimeout;
29
29
  private readonly defaultAsyncTimeout;
30
+ /** Default returnData configuration */
31
+ private readonly defaultReturnData;
30
32
  /** Initial headers configuration */
31
33
  private readonly initialHeaders?;
32
34
  /**
@@ -64,17 +66,42 @@ export declare class RequestIframeClientImpl implements RequestIframeClient, Str
64
66
  * Resolve header value (handle function type headers)
65
67
  */
66
68
  private resolveHeaderValue;
69
+ /**
70
+ * Detect Content-Type for request body
71
+ */
72
+ private detectContentTypeForBody;
73
+ /**
74
+ * Check if header exists (case-insensitive)
75
+ */
76
+ private hasHeader;
67
77
  /**
68
78
  * Merge and resolve headers (initial headers + request headers)
69
79
  * Request headers take precedence over initial headers
80
+ * Also auto-detects and sets Content-Type if not already set
70
81
  */
71
82
  private mergeHeaders;
72
83
  /**
73
84
  * Check if server is reachable
74
85
  */
75
86
  isConnect(): Promise<boolean>;
76
- send<T = any>(path: string, body?: Record<string, any>, options?: RequestOptions): Promise<Response<T>>;
77
- private prefixPath;
87
+ send<T = any>(path: string, body?: any, options?: RequestOptions): Promise<Response<T> | T>;
88
+ /**
89
+ * Send file as request body (stream only; server receives stream or auto-resolved File/Blob via autoResolve).
90
+ */
91
+ sendFile<T = any>(path: string, content: string | Blob | File, options?: RequestOptions & {
92
+ mimeType?: string;
93
+ fileName?: string;
94
+ autoResolve?: boolean;
95
+ }): Promise<Response<T> | T>;
96
+ /**
97
+ * Send stream as request body (server receives readable stream).
98
+ * Sends REQUEST with streamId and stream: true, then starts the writable stream.
99
+ */
100
+ sendStream<T = any>(path: string, stream: IframeWritableStream, options?: RequestOptions): Promise<Response<T> | T>;
101
+ /**
102
+ * Internal: send REQUEST and wait for response (used by send, sendFile, sendStream).
103
+ */
104
+ private _sendRequest;
78
105
  /**
79
106
  * Get internal server instance (for debugging)
80
107
  */
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/core/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/core/client.ts"],"names":[],"mappings":"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"}