request-iframe 0.0.3 → 0.0.5

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 (69) hide show
  1. package/QUICKSTART.CN.md +35 -8
  2. package/QUICKSTART.md +35 -8
  3. package/README.CN.md +177 -24
  4. package/README.md +237 -19
  5. package/library/__tests__/channel.test.ts +16 -4
  6. package/library/__tests__/coverage-branches.test.ts +356 -0
  7. package/library/__tests__/debug.test.ts +22 -0
  8. package/library/__tests__/dispatcher.test.ts +8 -4
  9. package/library/__tests__/requestIframe.test.ts +1243 -87
  10. package/library/__tests__/stream.test.ts +92 -16
  11. package/library/__tests__/utils.test.ts +41 -1
  12. package/library/api/client.d.ts.map +1 -1
  13. package/library/api/client.js +1 -0
  14. package/library/constants/index.d.ts +2 -0
  15. package/library/constants/index.d.ts.map +1 -1
  16. package/library/constants/index.js +3 -1
  17. package/library/constants/messages.d.ts +3 -0
  18. package/library/constants/messages.d.ts.map +1 -1
  19. package/library/constants/messages.js +3 -0
  20. package/library/core/client-server.d.ts +4 -0
  21. package/library/core/client-server.d.ts.map +1 -1
  22. package/library/core/client-server.js +45 -22
  23. package/library/core/client.d.ts +36 -4
  24. package/library/core/client.d.ts.map +1 -1
  25. package/library/core/client.js +508 -285
  26. package/library/core/request.d.ts +3 -1
  27. package/library/core/request.d.ts.map +1 -1
  28. package/library/core/request.js +2 -1
  29. package/library/core/response.d.ts +26 -4
  30. package/library/core/response.d.ts.map +1 -1
  31. package/library/core/response.js +192 -112
  32. package/library/core/server.d.ts +13 -0
  33. package/library/core/server.d.ts.map +1 -1
  34. package/library/core/server.js +221 -6
  35. package/library/index.d.ts +2 -1
  36. package/library/index.d.ts.map +1 -1
  37. package/library/index.js +39 -3
  38. package/library/message/channel.d.ts +2 -2
  39. package/library/message/channel.d.ts.map +1 -1
  40. package/library/message/channel.js +5 -1
  41. package/library/message/dispatcher.d.ts +2 -2
  42. package/library/message/dispatcher.d.ts.map +1 -1
  43. package/library/message/dispatcher.js +6 -5
  44. package/library/stream/index.d.ts +11 -1
  45. package/library/stream/index.d.ts.map +1 -1
  46. package/library/stream/index.js +21 -3
  47. package/library/stream/types.d.ts +2 -2
  48. package/library/stream/types.d.ts.map +1 -1
  49. package/library/stream/writable-stream.d.ts +1 -1
  50. package/library/stream/writable-stream.d.ts.map +1 -1
  51. package/library/stream/writable-stream.js +87 -47
  52. package/library/types/index.d.ts +29 -5
  53. package/library/types/index.d.ts.map +1 -1
  54. package/library/utils/debug.d.ts.map +1 -1
  55. package/library/utils/debug.js +6 -2
  56. package/library/utils/error.d.ts +21 -0
  57. package/library/utils/error.d.ts.map +1 -0
  58. package/library/utils/error.js +34 -0
  59. package/library/utils/index.d.ts +21 -0
  60. package/library/utils/index.d.ts.map +1 -1
  61. package/library/utils/index.js +141 -2
  62. package/library/utils/path-match.d.ts +16 -0
  63. package/library/utils/path-match.d.ts.map +1 -1
  64. package/library/utils/path-match.js +65 -0
  65. package/package.json +2 -1
  66. package/react/library/__tests__/index.test.tsx +44 -22
  67. package/react/library/index.d.ts.map +1 -1
  68. package/react/library/index.js +81 -23
  69. package/react/package.json +7 -0
@@ -5,13 +5,15 @@ import { MessageContext } from '../message';
5
5
  */
6
6
  export declare class ServerRequestImpl implements ServerRequest {
7
7
  body: any;
8
+ stream?: ServerRequest['stream'];
8
9
  headers: Record<string, string>;
9
10
  cookies: Record<string, string>;
10
11
  path: string;
12
+ params: Record<string, string>;
11
13
  requestId: string;
12
14
  origin: string;
13
15
  source: Window;
14
16
  res: ServerResponse;
15
- constructor(data: PostMessageData, context: MessageContext, response: ServerResponse);
17
+ constructor(data: PostMessageData, context: MessageContext, response: ServerResponse, params?: Record<string, string>);
16
18
  }
17
19
  //# sourceMappingURL=request.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/core/request.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EAAE,cAAc,EAAE,eAAe,EAC/C,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5C;;GAEG;AACH,qBAAa,iBAAkB,YAAW,aAAa;IAC9C,IAAI,EAAE,GAAG,CAAC;IACV,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,cAAc,CAAC;gBAGzB,IAAI,EAAE,eAAe,EACrB,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,cAAc;CAiB3B"}
1
+ {"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/core/request.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EAAE,cAAc,EAAE,eAAe,EAC/C,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5C;;GAEG;AACH,qBAAa,iBAAkB,YAAW,aAAa;IAC9C,IAAI,EAAE,GAAG,CAAC;IACV,MAAM,CAAC,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;IACjC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,cAAc,CAAC;gBAGzB,IAAI,EAAE,eAAe,EACrB,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,cAAc,EACxB,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM;CAkBtC"}
@@ -11,7 +11,7 @@ require("core-js/modules/es.object.entries.js");
11
11
  * ServerRequest implementation
12
12
  */
13
13
  class ServerRequestImpl {
14
- constructor(data, context, response) {
14
+ constructor(data, context, response, params = {}) {
15
15
  this.body = data.body;
16
16
  // headers may contain array values (e.g., Set-Cookie), simplified to string here
17
17
  this.headers = {};
@@ -25,6 +25,7 @@ class ServerRequestImpl {
25
25
  }
26
26
  this.cookies = data.cookies || {};
27
27
  this.path = data.path || '';
28
+ this.params = params;
28
29
  this.requestId = data.requestId;
29
30
  this.origin = context.origin;
30
31
  this.source = context.source;
@@ -16,18 +16,31 @@ export declare class ServerResponseImpl implements ServerResponse {
16
16
  private readonly secretKey?;
17
17
  private readonly targetWindow;
18
18
  private readonly targetOrigin;
19
- private readonly channel?;
19
+ private readonly channel;
20
20
  /** Target client ID (usually the creatorId of the original request) */
21
21
  private readonly targetId?;
22
22
  /** Server instance ID (for creatorId in responses) */
23
23
  private readonly serverId?;
24
24
  private onAckCallback?;
25
25
  _sent: boolean;
26
- constructor(requestId: string, path: string, secretKey: string | undefined, targetWindow: Window, targetOrigin: string, channel?: MessageChannel, serverId?: string, targetId?: string);
26
+ constructor(requestId: string, path: string, secretKey: string | undefined, targetWindow: Window, targetOrigin: string, channel: MessageChannel, serverId?: string, targetId?: string);
27
27
  /**
28
- * Send message via channel or direct postMessage
28
+ * Send message via channel
29
29
  */
30
30
  private sendMessage;
31
+ /**
32
+ * Check if header exists (case-insensitive)
33
+ */
34
+ private hasHeader;
35
+ /**
36
+ * Detect data type and return appropriate Content-Type
37
+ * Returns null if Content-Type should not be auto-set
38
+ */
39
+ private detectContentType;
40
+ /**
41
+ * Auto set Content-Type based on data type (only if user not set)
42
+ */
43
+ private ensureContentTypeIfNeeded;
31
44
  /**
32
45
  * Set callback waiting for client acknowledgment
33
46
  */
@@ -36,6 +49,16 @@ export declare class ServerResponseImpl implements ServerResponse {
36
49
  * Trigger client acknowledgment callback
37
50
  */
38
51
  _triggerAck(received: boolean): void;
52
+ /**
53
+ * Internal method: send raw data (used by send after type detection)
54
+ */
55
+ private _sendRaw;
56
+ /**
57
+ * Universal send method - automatically detects data type and calls appropriate method
58
+ * - If data is IframeWritableStream, calls sendStream
59
+ * - If data is File/Blob, calls sendFile
60
+ * - Otherwise, sends as regular data with auto-detected Content-Type
61
+ */
39
62
  send(data: any, options?: SendOptions): Promise<boolean>;
40
63
  json(data: any, options?: SendOptions): Promise<boolean>;
41
64
  sendFile(content: string | Blob | File, options?: SendFileOptions): Promise<boolean>;
@@ -49,7 +72,6 @@ export declare class ServerResponseImpl implements ServerResponse {
49
72
  set(name: string, value: string | number | string[]): ServerResponse;
50
73
  cookie(name: string, value: string, options?: CookieOptions): ServerResponse;
51
74
  clearCookie(name: string, options?: CookieOptions): ServerResponse;
52
- private blobToBase64;
53
75
  }
54
76
  export {};
55
77
  //# sourceMappingURL=response.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../../src/core/response.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAGvF,OAAO,EAAE,oBAAoB,EAA4B,MAAM,WAAW,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAI5C;;GAEG;AACH,KAAK,WAAW,GAAG,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;AAE/C;;GAEG;AACH,qBAAa,kBAAmB,YAAW,cAAc;IAChD,UAAU,EAAE,MAAM,CAAiB;IACnC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAM;IACvD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAiB;IAC1C,uEAAuE;IACvE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAS;IACnC,sDAAsD;IACtD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAS;IACnC,OAAO,CAAC,aAAa,CAAC,CAAc;IAC7B,KAAK,UAAS;gBAGnB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE,cAAc,EACxB,QAAQ,CAAC,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,MAAM;IAYnB;;OAEG;IACH,OAAO,CAAC,WAAW;IAQnB;;OAEG;IACI,iBAAiB,CAAC,QAAQ,EAAE,WAAW,GAAG,IAAI;IAIrD;;OAEG;IACI,WAAW,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI;IAOpC,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;IA8CxD,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;IAKlD,QAAQ,CACnB,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,EAC7B,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,OAAO,CAAC;IAoDnB;;;OAGG;IACU,UAAU,CAAC,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB7D,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc;IAKpC,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI;IAwBhE,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,cAAc;IAMpE,MAAM,CACX,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,aAAa,GACtB,cAAc;IA4BV,WAAW,CAChB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,aAAa,GACtB,cAAc;YAkBH,YAAY;CAa3B"}
1
+ {"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../../src/core/response.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAGvF,OAAO,EAAE,oBAAoB,EAAoD,MAAM,WAAW,CAAC;AACnG,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAI5C;;GAEG;AACH,KAAK,WAAW,GAAG,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;AAE/C;;GAEG;AACH,qBAAa,kBAAmB,YAAW,cAAc;IAChD,UAAU,EAAE,MAAM,CAAiB;IACnC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAM;IACvD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiB;IACzC,uEAAuE;IACvE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAS;IACnC,sDAAsD;IACtD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAS;IACnC,OAAO,CAAC,aAAa,CAAC,CAAc;IAC7B,KAAK,UAAS;gBAGnB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,cAAc,EACvB,QAAQ,CAAC,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,MAAM;IAYnB;;OAEG;IACH,OAAO,CAAC,WAAW;IAKnB;;OAEG;IACH,OAAO,CAAC,SAAS;IAKjB;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAIzB;;OAEG;IACH,OAAO,CAAC,yBAAyB;IAQjC;;OAEG;IACI,iBAAiB,CAAC,QAAQ,EAAE,WAAW,GAAG,IAAI;IAIrD;;OAEG;IACI,WAAW,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI;IAO3C;;OAEG;IACH,OAAO,CAAC,QAAQ;IA+DhB;;;;;OAKG;IACU,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;IAiC9D,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;IAIlD,QAAQ,CACnB,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,EAC7B,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,OAAO,CAAC;IAoDnB;;;OAGG;IACU,UAAU,CAAC,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC;IAqB7D,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc;IAKpC,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI;IAwBhE,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,cAAc;IAMpE,MAAM,CACX,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,aAAa,GACtB,cAAc;IA4BV,WAAW,CAChB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,aAAa,GACtB,cAAc;CAkBlB"}
@@ -1,21 +1,24 @@
1
1
  "use strict";
2
2
 
3
+ require("core-js/modules/es.array.filter.js");
4
+ require("core-js/modules/es.object.get-own-property-descriptors.js");
5
+ require("core-js/modules/web.dom-collections.for-each.js");
3
6
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
7
  Object.defineProperty(exports, "__esModule", {
5
8
  value: true
6
9
  });
7
10
  exports.ServerResponseImpl = void 0;
8
11
  var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
9
- require("core-js/modules/es.array.includes.js");
10
12
  require("core-js/modules/es.array.iterator.js");
11
13
  require("core-js/modules/es.promise.js");
12
- require("core-js/modules/es.string.includes.js");
13
14
  require("core-js/modules/web.dom-collections.iterator.js");
14
15
  var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
15
16
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
16
17
  var _utils = require("../utils");
17
18
  var _constants = require("../constants");
18
19
  var _stream = require("../stream");
20
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
21
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
19
22
  /**
20
23
  * Callback waiting for client acknowledgment
21
24
  */
@@ -39,13 +42,40 @@ class ServerResponseImpl {
39
42
  }
40
43
 
41
44
  /**
42
- * Send message via channel or direct postMessage
45
+ * Send message via channel
43
46
  */
44
47
  sendMessage(message) {
45
- if (this.channel) {
46
- this.channel.send(this.targetWindow, message, this.targetOrigin);
47
- } else {
48
- this.targetWindow.postMessage(message, this.targetOrigin);
48
+ // Window check is handled in MessageDispatcher (via channel.send -> dispatcher.send)
49
+ this.channel.send(this.targetWindow, message, this.targetOrigin);
50
+ }
51
+
52
+ /**
53
+ * Check if header exists (case-insensitive)
54
+ */
55
+ hasHeader(name) {
56
+ var lower = name.toLowerCase();
57
+ return Object.keys(this.headers).some(k => k.toLowerCase() === lower);
58
+ }
59
+
60
+ /**
61
+ * Detect data type and return appropriate Content-Type
62
+ * Returns null if Content-Type should not be auto-set
63
+ */
64
+ detectContentType(data) {
65
+ return (0, _utils.detectContentType)(data, {
66
+ checkStream: true,
67
+ isIframeWritableStream: _stream.isIframeWritableStream
68
+ });
69
+ }
70
+
71
+ /**
72
+ * Auto set Content-Type based on data type (only if user not set)
73
+ */
74
+ ensureContentTypeIfNeeded(data) {
75
+ if (this.hasHeader(_constants.HttpHeader.CONTENT_TYPE)) return;
76
+ var contentType = this.detectContentType(data);
77
+ if (contentType) {
78
+ this.setHeader(_constants.HttpHeader.CONTENT_TYPE, contentType);
49
79
  }
50
80
  }
51
81
 
@@ -65,98 +95,169 @@ class ServerResponseImpl {
65
95
  this.onAckCallback = undefined;
66
96
  }
67
97
  }
68
- send(data, options) {
98
+
99
+ /**
100
+ * Internal method: send raw data (used by send after type detection)
101
+ */
102
+ _sendRaw(data, options) {
69
103
  var _options$requireAck;
70
104
  if (this._sent) return Promise.resolve(false);
71
105
  this._sent = true;
72
106
  var requireAck = (_options$requireAck = options === null || options === void 0 ? void 0 : options.requireAck) !== null && _options$requireAck !== void 0 ? _options$requireAck : false;
107
+ try {
108
+ // If acknowledgment not required, send directly and return true
109
+ if (!requireAck) {
110
+ this.sendMessage((0, _utils.createPostMessage)(_constants.MessageType.RESPONSE, this.requestId, {
111
+ path: this.path,
112
+ secretKey: this.secretKey,
113
+ data,
114
+ status: this.statusCode,
115
+ statusText: (0, _constants.getStatusText)(this.statusCode),
116
+ headers: this.headers,
117
+ requireAck: false,
118
+ role: _constants.MessageRole.SERVER,
119
+ creatorId: this.serverId,
120
+ targetId: this.targetId
121
+ }));
122
+ return Promise.resolve(true);
123
+ }
73
124
 
74
- // If acknowledgment not required, send directly and return true
75
- if (!requireAck) {
76
- this.sendMessage((0, _utils.createPostMessage)(_constants.MessageType.RESPONSE, this.requestId, {
77
- path: this.path,
78
- secretKey: this.secretKey,
79
- data,
80
- status: this.statusCode,
81
- statusText: (0, _constants.getStatusText)(this.statusCode),
82
- headers: this.headers,
83
- requireAck: false,
84
- role: _constants.MessageRole.SERVER,
85
- creatorId: this.serverId,
86
- targetId: this.targetId
87
- }));
88
- return Promise.resolve(true);
125
+ // Acknowledgment required, wait for client response
126
+ return new Promise((resolve, reject) => {
127
+ try {
128
+ this._setOnAckCallback(resolve);
129
+ this.sendMessage((0, _utils.createPostMessage)(_constants.MessageType.RESPONSE, this.requestId, {
130
+ path: this.path,
131
+ secretKey: this.secretKey,
132
+ data,
133
+ status: this.statusCode,
134
+ statusText: (0, _constants.getStatusText)(this.statusCode),
135
+ headers: this.headers,
136
+ requireAck: true,
137
+ role: _constants.MessageRole.SERVER,
138
+ creatorId: this.serverId,
139
+ targetId: this.targetId
140
+ }));
141
+ } catch (error) {
142
+ // If window is closed, reject immediately
143
+ if ((error === null || error === void 0 ? void 0 : error.code) === _constants.ErrorCode.TARGET_WINDOW_CLOSED) {
144
+ reject(error);
145
+ } else {
146
+ throw error;
147
+ }
148
+ }
149
+ });
150
+ } catch (error) {
151
+ // If window is closed, return rejected promise
152
+ if ((error === null || error === void 0 ? void 0 : error.code) === _constants.ErrorCode.TARGET_WINDOW_CLOSED) {
153
+ return Promise.reject(error);
154
+ }
155
+ throw error;
89
156
  }
157
+ }
90
158
 
91
- // Acknowledgment required, wait for client response
92
- return new Promise(resolve => {
93
- this._setOnAckCallback(resolve);
94
- this.sendMessage((0, _utils.createPostMessage)(_constants.MessageType.RESPONSE, this.requestId, {
95
- path: this.path,
96
- secretKey: this.secretKey,
97
- data,
98
- status: this.statusCode,
99
- statusText: (0, _constants.getStatusText)(this.statusCode),
100
- headers: this.headers,
101
- requireAck: true,
102
- role: _constants.MessageRole.SERVER,
103
- creatorId: this.serverId,
104
- targetId: this.targetId
105
- }));
106
- });
159
+ /**
160
+ * Universal send method - automatically detects data type and calls appropriate method
161
+ * - If data is IframeWritableStream, calls sendStream
162
+ * - If data is File/Blob, calls sendFile
163
+ * - Otherwise, sends as regular data with auto-detected Content-Type
164
+ */
165
+ send(data, options) {
166
+ var _this = this;
167
+ return (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee() {
168
+ var fileOptions;
169
+ return _regenerator.default.wrap(function (_context) {
170
+ while (1) switch (_context.prev = _context.next) {
171
+ case 0:
172
+ if (!_this._sent) {
173
+ _context.next = 1;
174
+ break;
175
+ }
176
+ return _context.abrupt("return", Promise.resolve(false));
177
+ case 1:
178
+ if (!(0, _stream.isIframeWritableStream)(data)) {
179
+ _context.next = 3;
180
+ break;
181
+ }
182
+ _context.next = 2;
183
+ return _this.sendStream(data);
184
+ case 2:
185
+ return _context.abrupt("return", true);
186
+ case 3:
187
+ if (!(typeof File !== 'undefined' && data instanceof File || typeof Blob !== 'undefined' && data instanceof Blob)) {
188
+ _context.next = 4;
189
+ break;
190
+ }
191
+ // Extract options for sendFile
192
+ fileOptions = _objectSpread({
193
+ requireAck: options === null || options === void 0 ? void 0 : options.requireAck
194
+ }, typeof File !== 'undefined' && data instanceof File ? {
195
+ mimeType: data.type,
196
+ fileName: data.name
197
+ } : {});
198
+ return _context.abrupt("return", _this.sendFile(data, fileOptions));
199
+ case 4:
200
+ // For other types, auto-detect and set Content-Type, then send
201
+ _this.ensureContentTypeIfNeeded(data);
202
+ return _context.abrupt("return", _this._sendRaw(data, options));
203
+ case 5:
204
+ case "end":
205
+ return _context.stop();
206
+ }
207
+ }, _callee);
208
+ }))();
107
209
  }
108
210
  json(data, options) {
109
- this.setHeader(_constants.HttpHeader.CONTENT_TYPE, 'application/json');
110
211
  return this.send(data, options);
111
212
  }
112
213
  sendFile(content, options) {
113
- var _this = this;
114
- return (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee2() {
214
+ var _this2 = this;
215
+ return (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee3() {
115
216
  var mimeType, fileName, fileContent, stream;
116
- return _regenerator.default.wrap(function (_context2) {
117
- while (1) switch (_context2.prev = _context2.next) {
217
+ return _regenerator.default.wrap(function (_context3) {
218
+ while (1) switch (_context3.prev = _context3.next) {
118
219
  case 0:
119
- if (!_this._sent) {
120
- _context2.next = 1;
220
+ if (!_this2._sent) {
221
+ _context3.next = 1;
121
222
  break;
122
223
  }
123
- return _context2.abrupt("return", false);
224
+ return _context3.abrupt("return", false);
124
225
  case 1:
125
226
  mimeType = (options === null || options === void 0 ? void 0 : options.mimeType) || 'application/octet-stream';
126
227
  fileName = options === null || options === void 0 ? void 0 : options.fileName;
127
228
  if (!(typeof content === 'string')) {
128
- _context2.next = 2;
229
+ _context3.next = 2;
129
230
  break;
130
231
  }
131
232
  // If it's a plain string, convert to base64
132
233
  fileContent = btoa(unescape(encodeURIComponent(content)));
133
- _context2.next = 6;
234
+ _context3.next = 6;
134
235
  break;
135
236
  case 2:
136
237
  if (!(content instanceof File)) {
137
- _context2.next = 4;
238
+ _context3.next = 4;
138
239
  break;
139
240
  }
140
241
  mimeType = content.type || mimeType;
141
242
  fileName = fileName || content.name;
142
- _context2.next = 3;
143
- return _this.blobToBase64(content);
243
+ _context3.next = 3;
244
+ return (0, _utils.blobToBase64)(content);
144
245
  case 3:
145
- fileContent = _context2.sent;
146
- _context2.next = 6;
246
+ fileContent = _context3.sent;
247
+ _context3.next = 6;
147
248
  break;
148
249
  case 4:
149
- _context2.next = 5;
150
- return _this.blobToBase64(content);
250
+ _context3.next = 5;
251
+ return (0, _utils.blobToBase64)(content);
151
252
  case 5:
152
- fileContent = _context2.sent;
253
+ fileContent = _context3.sent;
153
254
  case 6:
154
255
  // Set file-related headers
155
- _this.setHeader(_constants.HttpHeader.CONTENT_TYPE, mimeType);
256
+ _this2.setHeader(_constants.HttpHeader.CONTENT_TYPE, mimeType);
156
257
  if (fileName) {
157
- _this.setHeader(_constants.HttpHeader.CONTENT_DISPOSITION, `attachment; filename="${fileName}"`);
258
+ _this2.setHeader(_constants.HttpHeader.CONTENT_DISPOSITION, `attachment; filename="${fileName}"`);
158
259
  } else {
159
- _this.setHeader(_constants.HttpHeader.CONTENT_DISPOSITION, 'attachment');
260
+ _this2.setHeader(_constants.HttpHeader.CONTENT_DISPOSITION, 'attachment');
160
261
  }
161
262
 
162
263
  // Create file stream with autoResolve enabled
@@ -168,19 +269,19 @@ class ServerResponseImpl {
168
269
  autoResolve: true,
169
270
  // Client will automatically resolve to fileData
170
271
  next: function () {
171
- var _next = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee() {
172
- return _regenerator.default.wrap(function (_context) {
173
- while (1) switch (_context.prev = _context.next) {
272
+ var _next = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee2() {
273
+ return _regenerator.default.wrap(function (_context2) {
274
+ while (1) switch (_context2.prev = _context2.next) {
174
275
  case 0:
175
- return _context.abrupt("return", {
276
+ return _context2.abrupt("return", {
176
277
  data: fileContent,
177
278
  done: true
178
279
  });
179
280
  case 1:
180
281
  case "end":
181
- return _context.stop();
282
+ return _context2.stop();
182
283
  }
183
- }, _callee);
284
+ }, _callee2);
184
285
  }));
185
286
  function next() {
186
287
  return _next.apply(this, arguments);
@@ -188,15 +289,15 @@ class ServerResponseImpl {
188
289
  return next;
189
290
  }()
190
291
  }); // Send stream (this will handle the requireAck logic internally and set _sent)
191
- _context2.next = 7;
192
- return _this.sendStream(stream);
292
+ _context3.next = 7;
293
+ return _this2.sendStream(stream);
193
294
  case 7:
194
- return _context2.abrupt("return", true);
295
+ return _context3.abrupt("return", true);
195
296
  case 8:
196
297
  case "end":
197
- return _context2.stop();
298
+ return _context3.stop();
198
299
  }
199
- }, _callee2);
300
+ }, _callee3);
200
301
  }))();
201
302
  }
202
303
 
@@ -205,38 +306,40 @@ class ServerResponseImpl {
205
306
  * Bind stream to current request context and start stream transmission
206
307
  */
207
308
  sendStream(stream) {
208
- var _this2 = this;
209
- return (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee3() {
210
- return _regenerator.default.wrap(function (_context3) {
211
- while (1) switch (_context3.prev = _context3.next) {
309
+ var _this3 = this;
310
+ return (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee4() {
311
+ return _regenerator.default.wrap(function (_context4) {
312
+ while (1) switch (_context4.prev = _context4.next) {
212
313
  case 0:
213
- if (!_this2._sent) {
214
- _context3.next = 1;
314
+ if (!_this3._sent) {
315
+ _context4.next = 1;
215
316
  break;
216
317
  }
217
- return _context3.abrupt("return");
318
+ return _context4.abrupt("return");
218
319
  case 1:
219
- _this2._sent = true;
320
+ _this3._sent = true;
321
+
322
+ // Window check is handled in MessageDispatcher when stream sends messages
220
323
 
221
324
  // Bind stream to request context
222
325
  stream._bind({
223
- requestId: _this2.requestId,
224
- targetWindow: _this2.targetWindow,
225
- targetOrigin: _this2.targetOrigin,
226
- secretKey: _this2.secretKey,
227
- channel: _this2.channel,
228
- serverId: _this2.serverId,
229
- targetId: _this2.targetId
326
+ requestId: _this3.requestId,
327
+ targetWindow: _this3.targetWindow,
328
+ targetOrigin: _this3.targetOrigin,
329
+ secretKey: _this3.secretKey,
330
+ channel: _this3.channel,
331
+ serverId: _this3.serverId,
332
+ targetId: _this3.targetId
230
333
  });
231
334
 
232
335
  // Start stream transmission
233
- _context3.next = 2;
336
+ _context4.next = 2;
234
337
  return stream.start();
235
338
  case 2:
236
339
  case "end":
237
- return _context3.stop();
340
+ return _context4.stop();
238
341
  }
239
- }, _callee3);
342
+ }, _callee4);
240
343
  }))();
241
344
  }
242
345
  status(code) {
@@ -311,28 +414,5 @@ class ServerResponseImpl {
311
414
  }
312
415
  return this;
313
416
  }
314
- blobToBase64(blob) {
315
- return (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee4() {
316
- return _regenerator.default.wrap(function (_context4) {
317
- while (1) switch (_context4.prev = _context4.next) {
318
- case 0:
319
- return _context4.abrupt("return", new Promise((resolve, reject) => {
320
- var reader = new FileReader();
321
- reader.onloadend = () => {
322
- var result = reader.result;
323
- // Remove data URL prefix (e.g., "data:image/png;base64,")
324
- var base64 = result.includes(',') ? result.split(',')[1] : result;
325
- resolve(base64);
326
- };
327
- reader.onerror = reject;
328
- reader.readAsDataURL(blob);
329
- }));
330
- case 1:
331
- case "end":
332
- return _context4.stop();
333
- }
334
- }, _callee4);
335
- }))();
336
- }
337
417
  }
338
418
  exports.ServerResponseImpl = ServerResponseImpl;
@@ -29,6 +29,10 @@ export declare class RequestIframeServerImpl implements RequestIframeServer {
29
29
  private readonly middlewares;
30
30
  /** Responses waiting for client acknowledgment */
31
31
  private readonly pendingAcks;
32
+ /** Pending requests waiting for client stream_start (streamId present) */
33
+ private readonly pendingStreamRequests;
34
+ /** Stream message handlers (streamId -> handler) for client→server streams */
35
+ private readonly streamHandlers;
32
36
  /** List of functions to unregister handlers */
33
37
  private readonly unregisterFns;
34
38
  /** Whether it is open */
@@ -50,6 +54,9 @@ export declare class RequestIframeServerImpl implements RequestIframeServer {
50
54
  * Register message handlers
51
55
  */
52
56
  private registerHandlers;
57
+ /** Handle stream_start from client (stream request with streamId) */
58
+ private handleStreamStart;
59
+ private dispatchStreamMessage;
53
60
  /**
54
61
  * Handle protocol version error
55
62
  */
@@ -68,6 +75,12 @@ export declare class RequestIframeServerImpl implements RequestIframeServer {
68
75
  get messageDispatcher(): MessageDispatcher;
69
76
  private handleRequestError;
70
77
  private handleRequestResult;
78
+ /**
79
+ * Find matching handler and extract path parameters
80
+ * @param requestPath The actual request path
81
+ * @returns Handler function and extracted parameters, or null if not found
82
+ */
83
+ private findHandler;
71
84
  /**
72
85
  * Handle request
73
86
  */
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/core/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,aAAa,EACb,mBAAmB,EACnB,UAAU,EACV,WAAW,EACZ,MAAM,UAAU,CAAC;AAKlB,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAkB,MAAM,YAAY,CAAC;AAiCjF;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,mCAAmC;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kGAAkG;IAClG,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,2BAA2B;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gFAAgF;IAChF,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;GAGG;AACH,qBAAa,uBAAwB,YAAW,mBAAmB;IACjE,yBAAyB;IACzB,SAAgB,EAAE,EAAE,MAAM,CAAC;IAE3B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAoB;IAC/C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAmB;IACpD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAoC;IAC7D,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAwB;IAEpD,kDAAkD;IAClD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAiC;IAE7D,+CAA+C;IAC/C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAyB;IAEvD,yBAAyB;IACzB,OAAO,CAAC,OAAO,CAAS;gBAEL,OAAO,CAAC,EAAE,aAAa;IAgB1C;;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;IAkCxB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAqB1B;;OAEG;IACH,OAAO,CAAC,UAAU;IAUlB;;OAEG;IACH,OAAO,CAAC,cAAc;IAStB,oBAAoB;IACpB,IAAW,SAAS,IAAI,MAAM,GAAG,SAAS,CAEzC;IAED,2CAA2C;IAC3C,IAAW,iBAAiB,IAAI,iBAAiB,CAEhD;IAED,OAAO,CAAC,kBAAkB;IAmC1B,OAAO,CAAC,mBAAmB;IA4B3B;;OAEG;IACH,OAAO,CAAC,aAAa;IAoHrB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAanB,GAAG,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI;IACjC,GAAG,CAAC,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,GAAG,IAAI;IAepD,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,MAAM,IAAI;IAU3D,OAAO,CAAC,cAAc;IA4Cf,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI;IAYlC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC;IAUjE;;OAEG;IACI,OAAO,IAAI,IAAI;CAgBvB"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/core/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,aAAa,EACb,mBAAmB,EACnB,UAAU,EACV,WAAW,EACZ,MAAM,UAAU,CAAC;AAKlB,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAkB,MAAM,YAAY,CAAC;AAiDjF;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,mCAAmC;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kGAAkG;IAClG,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,2BAA2B;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gFAAgF;IAChF,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;GAGG;AACH,qBAAa,uBAAwB,YAAW,mBAAmB;IACjE,yBAAyB;IACzB,SAAgB,EAAE,EAAE,MAAM,CAAC;IAE3B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAoB;IAC/C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAmB;IACpD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAoC;IAC7D,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAwB;IAEpD,kDAAkD;IAClD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAiC;IAE7D,0EAA0E;IAC1E,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAA2C;IAEjF,8EAA8E;IAC9E,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAwD;IAEvF,+CAA+C;IAC/C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAyB;IAEvD,yBAAyB;IACzB,OAAO,CAAC,OAAO,CAAS;gBAEL,OAAO,CAAC,EAAE,aAAa;IAgB1C;;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;IAkDxB,qEAAqE;IACrE,OAAO,CAAC,iBAAiB;IAkHzB,OAAO,CAAC,qBAAqB;IAU7B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAsB1B;;OAEG;IACH,OAAO,CAAC,UAAU;IAYlB;;OAEG;IACH,OAAO,CAAC,cAAc;IAStB,oBAAoB;IACpB,IAAW,SAAS,IAAI,MAAM,GAAG,SAAS,CAEzC;IAED,2CAA2C;IAC3C,IAAW,iBAAiB,IAAI,iBAAiB,CAEhD;IAED,OAAO,CAAC,kBAAkB;IAoC1B,OAAO,CAAC,mBAAmB;IA4B3B;;;;OAIG;IACH,OAAO,CAAC,WAAW;IAuBnB;;OAEG;IACH,OAAO,CAAC,aAAa;IA2IrB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAanB,GAAG,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI;IACjC,GAAG,CAAC,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,GAAG,IAAI;IAepD,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,MAAM,IAAI;IAU3D,OAAO,CAAC,cAAc;IA4Cf,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI;IAYlC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC;IAUjE;;OAEG;IACI,OAAO,IAAI,IAAI;CAgBvB"}