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.
- package/QUICKSTART.CN.md +35 -8
- package/QUICKSTART.md +35 -8
- package/README.CN.md +177 -24
- package/README.md +237 -19
- package/library/__tests__/channel.test.ts +16 -4
- package/library/__tests__/coverage-branches.test.ts +356 -0
- package/library/__tests__/debug.test.ts +22 -0
- package/library/__tests__/dispatcher.test.ts +8 -4
- package/library/__tests__/requestIframe.test.ts +1243 -87
- package/library/__tests__/stream.test.ts +92 -16
- package/library/__tests__/utils.test.ts +41 -1
- package/library/api/client.d.ts.map +1 -1
- package/library/api/client.js +1 -0
- package/library/constants/index.d.ts +2 -0
- package/library/constants/index.d.ts.map +1 -1
- package/library/constants/index.js +3 -1
- package/library/constants/messages.d.ts +3 -0
- package/library/constants/messages.d.ts.map +1 -1
- package/library/constants/messages.js +3 -0
- package/library/core/client-server.d.ts +4 -0
- package/library/core/client-server.d.ts.map +1 -1
- package/library/core/client-server.js +45 -22
- package/library/core/client.d.ts +36 -4
- package/library/core/client.d.ts.map +1 -1
- package/library/core/client.js +508 -285
- package/library/core/request.d.ts +3 -1
- package/library/core/request.d.ts.map +1 -1
- package/library/core/request.js +2 -1
- package/library/core/response.d.ts +26 -4
- package/library/core/response.d.ts.map +1 -1
- package/library/core/response.js +192 -112
- package/library/core/server.d.ts +13 -0
- package/library/core/server.d.ts.map +1 -1
- package/library/core/server.js +221 -6
- package/library/index.d.ts +2 -1
- package/library/index.d.ts.map +1 -1
- package/library/index.js +39 -3
- package/library/message/channel.d.ts +2 -2
- package/library/message/channel.d.ts.map +1 -1
- package/library/message/channel.js +5 -1
- package/library/message/dispatcher.d.ts +2 -2
- package/library/message/dispatcher.d.ts.map +1 -1
- package/library/message/dispatcher.js +6 -5
- package/library/stream/index.d.ts +11 -1
- package/library/stream/index.d.ts.map +1 -1
- package/library/stream/index.js +21 -3
- package/library/stream/types.d.ts +2 -2
- package/library/stream/types.d.ts.map +1 -1
- package/library/stream/writable-stream.d.ts +1 -1
- package/library/stream/writable-stream.d.ts.map +1 -1
- package/library/stream/writable-stream.js +87 -47
- package/library/types/index.d.ts +29 -5
- package/library/types/index.d.ts.map +1 -1
- package/library/utils/debug.d.ts.map +1 -1
- package/library/utils/debug.js +6 -2
- package/library/utils/error.d.ts +21 -0
- package/library/utils/error.d.ts.map +1 -0
- package/library/utils/error.js +34 -0
- package/library/utils/index.d.ts +21 -0
- package/library/utils/index.d.ts.map +1 -1
- package/library/utils/index.js +141 -2
- package/library/utils/path-match.d.ts +16 -0
- package/library/utils/path-match.d.ts.map +1 -1
- package/library/utils/path-match.js +65 -0
- package/package.json +2 -1
- package/react/library/__tests__/index.test.tsx +44 -22
- package/react/library/index.d.ts.map +1 -1
- package/react/library/index.js +81 -23
- 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;
|
|
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"}
|
package/library/core/request.js
CHANGED
|
@@ -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
|
|
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
|
|
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,
|
|
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"}
|
package/library/core/response.js
CHANGED
|
@@ -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
|
|
45
|
+
* Send message via channel
|
|
43
46
|
*/
|
|
44
47
|
sendMessage(message) {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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
|
-
|
|
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
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
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
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
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
|
|
114
|
-
return (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function
|
|
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 (
|
|
117
|
-
while (1) switch (
|
|
217
|
+
return _regenerator.default.wrap(function (_context3) {
|
|
218
|
+
while (1) switch (_context3.prev = _context3.next) {
|
|
118
219
|
case 0:
|
|
119
|
-
if (!
|
|
120
|
-
|
|
220
|
+
if (!_this2._sent) {
|
|
221
|
+
_context3.next = 1;
|
|
121
222
|
break;
|
|
122
223
|
}
|
|
123
|
-
return
|
|
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
|
-
|
|
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
|
-
|
|
234
|
+
_context3.next = 6;
|
|
134
235
|
break;
|
|
135
236
|
case 2:
|
|
136
237
|
if (!(content instanceof File)) {
|
|
137
|
-
|
|
238
|
+
_context3.next = 4;
|
|
138
239
|
break;
|
|
139
240
|
}
|
|
140
241
|
mimeType = content.type || mimeType;
|
|
141
242
|
fileName = fileName || content.name;
|
|
142
|
-
|
|
143
|
-
return
|
|
243
|
+
_context3.next = 3;
|
|
244
|
+
return (0, _utils.blobToBase64)(content);
|
|
144
245
|
case 3:
|
|
145
|
-
fileContent =
|
|
146
|
-
|
|
246
|
+
fileContent = _context3.sent;
|
|
247
|
+
_context3.next = 6;
|
|
147
248
|
break;
|
|
148
249
|
case 4:
|
|
149
|
-
|
|
150
|
-
return
|
|
250
|
+
_context3.next = 5;
|
|
251
|
+
return (0, _utils.blobToBase64)(content);
|
|
151
252
|
case 5:
|
|
152
|
-
fileContent =
|
|
253
|
+
fileContent = _context3.sent;
|
|
153
254
|
case 6:
|
|
154
255
|
// Set file-related headers
|
|
155
|
-
|
|
256
|
+
_this2.setHeader(_constants.HttpHeader.CONTENT_TYPE, mimeType);
|
|
156
257
|
if (fileName) {
|
|
157
|
-
|
|
258
|
+
_this2.setHeader(_constants.HttpHeader.CONTENT_DISPOSITION, `attachment; filename="${fileName}"`);
|
|
158
259
|
} else {
|
|
159
|
-
|
|
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
|
|
172
|
-
return _regenerator.default.wrap(function (
|
|
173
|
-
while (1) switch (
|
|
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
|
|
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
|
|
282
|
+
return _context2.stop();
|
|
182
283
|
}
|
|
183
|
-
},
|
|
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
|
-
|
|
192
|
-
return
|
|
292
|
+
_context3.next = 7;
|
|
293
|
+
return _this2.sendStream(stream);
|
|
193
294
|
case 7:
|
|
194
|
-
return
|
|
295
|
+
return _context3.abrupt("return", true);
|
|
195
296
|
case 8:
|
|
196
297
|
case "end":
|
|
197
|
-
return
|
|
298
|
+
return _context3.stop();
|
|
198
299
|
}
|
|
199
|
-
},
|
|
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
|
|
209
|
-
return (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function
|
|
210
|
-
return _regenerator.default.wrap(function (
|
|
211
|
-
while (1) switch (
|
|
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 (!
|
|
214
|
-
|
|
314
|
+
if (!_this3._sent) {
|
|
315
|
+
_context4.next = 1;
|
|
215
316
|
break;
|
|
216
317
|
}
|
|
217
|
-
return
|
|
318
|
+
return _context4.abrupt("return");
|
|
218
319
|
case 1:
|
|
219
|
-
|
|
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:
|
|
224
|
-
targetWindow:
|
|
225
|
-
targetOrigin:
|
|
226
|
-
secretKey:
|
|
227
|
-
channel:
|
|
228
|
-
serverId:
|
|
229
|
-
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
|
-
|
|
336
|
+
_context4.next = 2;
|
|
234
337
|
return stream.start();
|
|
235
338
|
case 2:
|
|
236
339
|
case "end":
|
|
237
|
-
return
|
|
340
|
+
return _context4.stop();
|
|
238
341
|
}
|
|
239
|
-
},
|
|
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;
|
package/library/core/server.d.ts
CHANGED
|
@@ -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;
|
|
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"}
|