request-iframe 0.0.6 → 0.1.1
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/README.CN.md +220 -21
- package/README.md +221 -24
- package/esm/api/client.js +80 -0
- package/esm/api/server.js +61 -0
- package/esm/constants/index.js +289 -0
- package/esm/constants/messages.js +157 -0
- package/esm/core/client-server.js +294 -0
- package/esm/core/client.js +873 -0
- package/esm/core/request.js +27 -0
- package/esm/core/response.js +459 -0
- package/esm/core/server.js +776 -0
- package/esm/index.js +21 -0
- package/esm/interceptors/index.js +122 -0
- package/esm/message/channel.js +182 -0
- package/esm/message/dispatcher.js +418 -0
- package/esm/message/index.js +2 -0
- package/esm/stream/file-stream.js +289 -0
- package/esm/stream/index.js +44 -0
- package/esm/stream/readable-stream.js +539 -0
- package/esm/stream/stream-core.js +204 -0
- package/esm/stream/types.js +1 -0
- package/esm/stream/writable-stream.js +836 -0
- package/esm/types/index.js +1 -0
- package/esm/utils/ack.js +36 -0
- package/esm/utils/cache.js +147 -0
- package/esm/utils/cookie.js +352 -0
- package/esm/utils/debug.js +521 -0
- package/esm/utils/error.js +27 -0
- package/esm/utils/index.js +180 -0
- package/esm/utils/origin.js +30 -0
- package/esm/utils/path-match.js +148 -0
- package/esm/utils/protocol.js +157 -0
- package/library/api/client.d.ts.map +1 -1
- package/library/api/client.js +13 -5
- package/library/api/server.d.ts.map +1 -1
- package/library/api/server.js +6 -1
- package/library/constants/index.d.ts +59 -4
- package/library/constants/index.d.ts.map +1 -1
- package/library/constants/index.js +67 -9
- package/library/constants/messages.d.ts +8 -1
- package/library/constants/messages.d.ts.map +1 -1
- package/library/constants/messages.js +8 -1
- package/library/core/client-server.d.ts +7 -15
- package/library/core/client-server.d.ts.map +1 -1
- package/library/core/client-server.js +56 -44
- package/library/core/client.d.ts +4 -1
- package/library/core/client.d.ts.map +1 -1
- package/library/core/client.js +74 -31
- package/library/core/response.d.ts +21 -3
- package/library/core/response.d.ts.map +1 -1
- package/library/core/response.js +55 -7
- package/library/core/server.d.ts +34 -3
- package/library/core/server.d.ts.map +1 -1
- package/library/core/server.js +191 -21
- package/library/message/channel.d.ts +6 -0
- package/library/message/channel.d.ts.map +1 -1
- package/library/message/channel.js +2 -1
- package/library/message/dispatcher.d.ts +32 -0
- package/library/message/dispatcher.d.ts.map +1 -1
- package/library/message/dispatcher.js +131 -1
- package/library/stream/file-stream.d.ts +4 -0
- package/library/stream/file-stream.d.ts.map +1 -1
- package/library/stream/file-stream.js +61 -33
- package/library/stream/index.d.ts.map +1 -1
- package/library/stream/index.js +2 -0
- package/library/stream/readable-stream.d.ts +30 -11
- package/library/stream/readable-stream.d.ts.map +1 -1
- package/library/stream/readable-stream.js +368 -73
- package/library/stream/stream-core.d.ts +65 -0
- package/library/stream/stream-core.d.ts.map +1 -0
- package/library/stream/stream-core.js +211 -0
- package/library/stream/types.d.ts +203 -3
- package/library/stream/types.d.ts.map +1 -1
- package/library/stream/writable-stream.d.ts +59 -13
- package/library/stream/writable-stream.d.ts.map +1 -1
- package/library/stream/writable-stream.js +647 -197
- package/library/types/index.d.ts +70 -4
- package/library/types/index.d.ts.map +1 -1
- package/library/utils/ack.d.ts +2 -0
- package/library/utils/ack.d.ts.map +1 -0
- package/library/utils/ack.js +44 -0
- package/library/utils/debug.js +1 -1
- package/library/utils/index.d.ts +1 -0
- package/library/utils/index.d.ts.map +1 -1
- package/library/utils/index.js +19 -2
- package/library/utils/origin.d.ts +14 -0
- package/library/utils/origin.d.ts.map +1 -0
- package/library/utils/origin.js +35 -0
- package/package.json +30 -7
- package/react/README.md +16 -0
- package/react/esm/index.js +284 -0
- package/react/library/index.d.ts +1 -1
- package/react/library/index.d.ts.map +1 -1
- package/react/library/index.js +3 -3
- package/react/package.json +24 -2
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
require("core-js/modules/es.array.filter.js");
|
|
4
4
|
require("core-js/modules/es.object.get-own-property-descriptors.js");
|
|
5
|
-
require("core-js/modules/web.dom-collections.for-each.js");
|
|
6
5
|
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
7
6
|
Object.defineProperty(exports, "__esModule", {
|
|
8
7
|
value: true
|
|
@@ -11,19 +10,19 @@ exports.IframeWritableStream = void 0;
|
|
|
11
10
|
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
12
11
|
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
13
12
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
14
|
-
require("core-js/modules/es.symbol.description.js");
|
|
15
|
-
require("core-js/modules/es.symbol.async-iterator.js");
|
|
16
13
|
require("core-js/modules/es.array.iterator.js");
|
|
17
14
|
require("core-js/modules/es.array.slice.js");
|
|
15
|
+
require("core-js/modules/es.map.js");
|
|
18
16
|
require("core-js/modules/es.promise.js");
|
|
17
|
+
require("core-js/modules/es.promise.finally.js");
|
|
19
18
|
require("core-js/modules/es.regexp.to-string.js");
|
|
19
|
+
require("core-js/modules/web.dom-collections.for-each.js");
|
|
20
20
|
require("core-js/modules/web.dom-collections.iterator.js");
|
|
21
21
|
var _utils = require("../utils");
|
|
22
22
|
var _constants = require("../constants");
|
|
23
|
+
var _streamCore = require("./stream-core");
|
|
23
24
|
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; }
|
|
24
25
|
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; }
|
|
25
|
-
function _asyncIterator(r) { var n, t, o, e = 2; for ("undefined" != typeof Symbol && (t = Symbol.asyncIterator, o = Symbol.iterator); e--;) { if (t && null != (n = r[t])) return n.call(r); if (o && null != (n = r[o])) return new AsyncFromSyncIterator(n.call(r)); t = "@@asyncIterator", o = "@@iterator"; } throw new TypeError("Object is not async iterable"); }
|
|
26
|
-
function AsyncFromSyncIterator(r) { function AsyncFromSyncIteratorContinuation(r) { if (Object(r) !== r) return Promise.reject(new TypeError(r + " is not an object.")); var n = r.done; return Promise.resolve(r.value).then(function (r) { return { value: r, done: n }; }); } return AsyncFromSyncIterator = function AsyncFromSyncIterator(r) { this.s = r, this.n = r.next; }, AsyncFromSyncIterator.prototype = { s: null, n: null, next: function next() { return AsyncFromSyncIteratorContinuation(this.n.apply(this.s, arguments)); }, return: function _return(r) { var n = this.s.return; return void 0 === n ? Promise.resolve({ value: r, done: !0 }) : AsyncFromSyncIteratorContinuation(n.apply(this.s, arguments)); }, throw: function _throw(r) { var n = this.s.return; return void 0 === n ? Promise.reject(r) : AsyncFromSyncIteratorContinuation(n.apply(this.s, arguments)); } }, new AsyncFromSyncIterator(r); }
|
|
27
26
|
/**
|
|
28
27
|
* Generate a unique stream ID
|
|
29
28
|
*/
|
|
@@ -33,25 +32,113 @@ function generateStreamId() {
|
|
|
33
32
|
|
|
34
33
|
/**
|
|
35
34
|
* IframeWritableStream - Server-side writable stream
|
|
36
|
-
*
|
|
35
|
+
*
|
|
36
|
+
* Writer/producer stream.
|
|
37
|
+
* It can be created on either side:
|
|
38
|
+
* - Server → Client: used as response stream (via `res.sendStream(stream)`)
|
|
39
|
+
* - Client → Server: used as request body stream (via `client.sendStream(path, stream)`)
|
|
37
40
|
*/
|
|
38
|
-
class IframeWritableStream {
|
|
41
|
+
class IframeWritableStream extends _streamCore.IframeStreamCore {
|
|
39
42
|
constructor(options = {}) {
|
|
40
|
-
var _options$type, _options$chunked;
|
|
41
|
-
|
|
43
|
+
var _options$type, _options$chunked, _options$mode, _options$expireTimeou;
|
|
44
|
+
var streamId = generateStreamId();
|
|
45
|
+
var streamType = (_options$type = options.type) !== null && _options$type !== void 0 ? _options$type : _constants.StreamType.DATA;
|
|
46
|
+
var chunked = (_options$chunked = options.chunked) !== null && _options$chunked !== void 0 ? _options$chunked : true;
|
|
47
|
+
super(streamId, streamType, chunked, options.metadata, false, options.mode);
|
|
42
48
|
(0, _defineProperty2.default)(this, "context", null);
|
|
43
|
-
this
|
|
44
|
-
|
|
45
|
-
|
|
49
|
+
(0, _defineProperty2.default)(this, "expireTimer", null);
|
|
50
|
+
(0, _defineProperty2.default)(this, "idleTimer", null);
|
|
51
|
+
(0, _defineProperty2.default)(this, "lastRemoteActivityAt", Date.now());
|
|
52
|
+
(0, _defineProperty2.default)(this, "heartbeatInFlight", null);
|
|
53
|
+
/** pull/ack protocol */
|
|
54
|
+
(0, _defineProperty2.default)(this, "pullCredit", 0);
|
|
55
|
+
(0, _defineProperty2.default)(this, "seq", 0);
|
|
56
|
+
(0, _defineProperty2.default)(this, "pendingBytes", 0);
|
|
57
|
+
(0, _defineProperty2.default)(this, "pendingQueue", []);
|
|
58
|
+
(0, _defineProperty2.default)(this, "pumping", false);
|
|
59
|
+
(0, _defineProperty2.default)(this, "completionPromise", null);
|
|
60
|
+
(0, _defineProperty2.default)(this, "resolveCompletion", null);
|
|
61
|
+
(0, _defineProperty2.default)(this, "rejectCompletion", null);
|
|
62
|
+
(0, _defineProperty2.default)(this, "ackWaiters", new Map());
|
|
63
|
+
(0, _defineProperty2.default)(this, "ackReceiverRegistered", false);
|
|
64
|
+
this.mode = (_options$mode = options.mode) !== null && _options$mode !== void 0 ? _options$mode : _constants.StreamMode.PULL;
|
|
46
65
|
this.iterator = options.iterator;
|
|
47
66
|
this.nextFn = options.next;
|
|
48
|
-
this.metadata = options.metadata;
|
|
49
67
|
this.autoResolve = options.autoResolve;
|
|
68
|
+
// Default to async-timeout length to avoid leaking long-lived streams
|
|
69
|
+
this.expireTimeout = (_options$expireTimeou = options.expireTimeout) !== null && _options$expireTimeou !== void 0 ? _options$expireTimeou : _constants.DefaultTimeout.ASYNC;
|
|
70
|
+
this.streamTimeout = options.streamTimeout;
|
|
71
|
+
this.maxPendingChunks = options.maxPendingChunks;
|
|
72
|
+
this.maxPendingBytes = options.maxPendingBytes;
|
|
73
|
+
}
|
|
74
|
+
enqueue(item) {
|
|
75
|
+
var max = this.maxPendingChunks;
|
|
76
|
+
if (typeof max === 'number' && max > 0 && this.pendingQueue.length >= max) {
|
|
77
|
+
throw new Error((0, _constants.formatMessage)(_constants.Messages.STREAM_PENDING_QUEUE_OVERFLOW, max));
|
|
78
|
+
}
|
|
79
|
+
var bytes = this.estimateChunkBytes(item.data);
|
|
80
|
+
var maxBytes = this.maxPendingBytes;
|
|
81
|
+
if (typeof maxBytes === 'number' && maxBytes > 0) {
|
|
82
|
+
var next = this.pendingBytes + bytes;
|
|
83
|
+
if (!Number.isFinite(next) || next > maxBytes) {
|
|
84
|
+
throw new Error((0, _constants.formatMessage)(_constants.Messages.STREAM_PENDING_BYTES_OVERFLOW, maxBytes));
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
this.pendingQueue.push(_objectSpread(_objectSpread({}, item), {}, {
|
|
88
|
+
bytes
|
|
89
|
+
}));
|
|
90
|
+
this.pendingBytes += bytes;
|
|
91
|
+
}
|
|
92
|
+
estimateChunkBytes(data) {
|
|
93
|
+
if (data === null || data === undefined) return 0;
|
|
94
|
+
if (typeof data === 'string') return this.utf8ByteLength(data);
|
|
95
|
+
try {
|
|
96
|
+
// ArrayBuffer
|
|
97
|
+
if (typeof ArrayBuffer !== 'undefined' && data instanceof ArrayBuffer) {
|
|
98
|
+
return data.byteLength;
|
|
99
|
+
}
|
|
100
|
+
// TypedArray / DataView
|
|
101
|
+
if (typeof ArrayBuffer !== 'undefined' && ArrayBuffer.isView && ArrayBuffer.isView(data)) {
|
|
102
|
+
return data.byteLength;
|
|
103
|
+
}
|
|
104
|
+
} catch (_unused) {
|
|
105
|
+
/** ignore */
|
|
106
|
+
}
|
|
107
|
+
try {
|
|
108
|
+
// Blob / File
|
|
109
|
+
if (typeof Blob !== 'undefined' && data instanceof Blob) {
|
|
110
|
+
return data.size;
|
|
111
|
+
}
|
|
112
|
+
} catch (_unused2) {
|
|
113
|
+
/** ignore */
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Strategy C: only count well-defined types; other values are not counted.
|
|
117
|
+
return 0;
|
|
118
|
+
}
|
|
119
|
+
utf8ByteLength(text) {
|
|
120
|
+
try {
|
|
121
|
+
if (typeof TextEncoder !== 'undefined') {
|
|
122
|
+
return new TextEncoder().encode(text).length;
|
|
123
|
+
}
|
|
124
|
+
} catch (_unused3) {
|
|
125
|
+
/** ignore */
|
|
126
|
+
}
|
|
127
|
+
try {
|
|
128
|
+
// eslint-disable-next-line no-undef
|
|
129
|
+
if (typeof Buffer !== 'undefined') {
|
|
130
|
+
// eslint-disable-next-line no-undef
|
|
131
|
+
return Buffer.byteLength(text, 'utf8');
|
|
132
|
+
}
|
|
133
|
+
} catch (_unused4) {
|
|
134
|
+
/** ignore */
|
|
135
|
+
}
|
|
136
|
+
return text.length;
|
|
50
137
|
}
|
|
51
138
|
|
|
52
139
|
/** Get stream state */
|
|
53
140
|
get state() {
|
|
54
|
-
return
|
|
141
|
+
return super.state;
|
|
55
142
|
}
|
|
56
143
|
|
|
57
144
|
/**
|
|
@@ -61,6 +148,125 @@ class IframeWritableStream {
|
|
|
61
148
|
_bind(context) {
|
|
62
149
|
this.context = context;
|
|
63
150
|
}
|
|
151
|
+
registerControlHandler() {
|
|
152
|
+
var _this$context;
|
|
153
|
+
if (!((_this$context = this.context) !== null && _this$context !== void 0 && _this$context.registerStreamHandler)) return;
|
|
154
|
+
this.context.registerStreamHandler(this.streamId, this.handleControlMessage.bind(this));
|
|
155
|
+
}
|
|
156
|
+
unregisterControlHandler() {
|
|
157
|
+
var _this$context2;
|
|
158
|
+
if (!((_this$context2 = this.context) !== null && _this$context2 !== void 0 && _this$context2.unregisterStreamHandler)) return;
|
|
159
|
+
this.context.unregisterStreamHandler(this.streamId);
|
|
160
|
+
}
|
|
161
|
+
handleControlMessage(data) {
|
|
162
|
+
// Update remote activity timestamp on any control message
|
|
163
|
+
this.lastRemoteActivityAt = Date.now();
|
|
164
|
+
switch (data.type) {
|
|
165
|
+
case _constants.StreamInternalMessageType.PULL:
|
|
166
|
+
{
|
|
167
|
+
var credit = typeof data.credit === 'number' && data.credit > 0 ? data.credit : 1;
|
|
168
|
+
this.pullCredit += credit;
|
|
169
|
+
this.emit(_constants.StreamEvent.PULL, {
|
|
170
|
+
credit,
|
|
171
|
+
totalCredit: this.pullCredit
|
|
172
|
+
});
|
|
173
|
+
// Try flushing buffered chunks or pumping generator
|
|
174
|
+
this.flush();
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
case _constants.StreamInternalMessageType.CANCEL:
|
|
178
|
+
this.emit(_constants.StreamEvent.CANCEL, {
|
|
179
|
+
reason: data.reason,
|
|
180
|
+
remote: true
|
|
181
|
+
});
|
|
182
|
+
this.cancel(data.reason);
|
|
183
|
+
break;
|
|
184
|
+
default:
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
clearIdleTimer() {
|
|
189
|
+
if (this.idleTimer) {
|
|
190
|
+
clearTimeout(this.idleTimer);
|
|
191
|
+
this.idleTimer = null;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
performHeartbeat() {
|
|
195
|
+
var _this = this;
|
|
196
|
+
return (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee() {
|
|
197
|
+
var _this$context3;
|
|
198
|
+
return _regenerator.default.wrap(function (_context) {
|
|
199
|
+
while (1) switch (_context.prev = _context.next) {
|
|
200
|
+
case 0:
|
|
201
|
+
if ((_this$context3 = _this.context) !== null && _this$context3 !== void 0 && _this$context3.heartbeat) {
|
|
202
|
+
_context.next = 1;
|
|
203
|
+
break;
|
|
204
|
+
}
|
|
205
|
+
return _context.abrupt("return", false);
|
|
206
|
+
case 1:
|
|
207
|
+
if (!_this.heartbeatInFlight) {
|
|
208
|
+
_this.heartbeatInFlight = Promise.resolve().then(() => _this.context.heartbeat()).catch(() => false).finally(() => {
|
|
209
|
+
_this.heartbeatInFlight = null;
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
return _context.abrupt("return", _this.heartbeatInFlight);
|
|
213
|
+
case 2:
|
|
214
|
+
case "end":
|
|
215
|
+
return _context.stop();
|
|
216
|
+
}
|
|
217
|
+
}, _callee);
|
|
218
|
+
}))();
|
|
219
|
+
}
|
|
220
|
+
startIdleTimer() {
|
|
221
|
+
var _this2 = this;
|
|
222
|
+
if (!this.streamTimeout || this.streamTimeout <= 0) return;
|
|
223
|
+
this.clearIdleTimer();
|
|
224
|
+
var timeout = this.streamTimeout;
|
|
225
|
+
this.idleTimer = setTimeout(/*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee2() {
|
|
226
|
+
var ok;
|
|
227
|
+
return _regenerator.default.wrap(function (_context2) {
|
|
228
|
+
while (1) switch (_context2.prev = _context2.next) {
|
|
229
|
+
case 0:
|
|
230
|
+
if (!(_this2._state !== _constants.StreamState.STREAMING)) {
|
|
231
|
+
_context2.next = 1;
|
|
232
|
+
break;
|
|
233
|
+
}
|
|
234
|
+
return _context2.abrupt("return");
|
|
235
|
+
case 1:
|
|
236
|
+
if (!(Date.now() - _this2.lastRemoteActivityAt < timeout)) {
|
|
237
|
+
_context2.next = 2;
|
|
238
|
+
break;
|
|
239
|
+
}
|
|
240
|
+
_this2.startIdleTimer();
|
|
241
|
+
return _context2.abrupt("return");
|
|
242
|
+
case 2:
|
|
243
|
+
_context2.next = 3;
|
|
244
|
+
return _this2.performHeartbeat();
|
|
245
|
+
case 3:
|
|
246
|
+
ok = _context2.sent;
|
|
247
|
+
if (!ok) {
|
|
248
|
+
_context2.next = 4;
|
|
249
|
+
break;
|
|
250
|
+
}
|
|
251
|
+
_this2.lastRemoteActivityAt = Date.now();
|
|
252
|
+
_this2.startIdleTimer();
|
|
253
|
+
return _context2.abrupt("return");
|
|
254
|
+
case 4:
|
|
255
|
+
try {
|
|
256
|
+
_this2.emit(_constants.StreamEvent.TIMEOUT, {
|
|
257
|
+
timeout
|
|
258
|
+
});
|
|
259
|
+
_this2.error((0, _constants.formatMessage)(_constants.Messages.STREAM_TIMEOUT, timeout));
|
|
260
|
+
} catch (_unused5) {
|
|
261
|
+
/** ignore */
|
|
262
|
+
}
|
|
263
|
+
case 5:
|
|
264
|
+
case "end":
|
|
265
|
+
return _context2.stop();
|
|
266
|
+
}
|
|
267
|
+
}, _callee2);
|
|
268
|
+
})), timeout);
|
|
269
|
+
}
|
|
64
270
|
|
|
65
271
|
/**
|
|
66
272
|
* Send message (to client when server-side stream, to server when client-side stream)
|
|
@@ -85,266 +291,459 @@ class IframeWritableStream {
|
|
|
85
291
|
var ok = this.context.channel.send(this.context.targetWindow, message, this.context.targetOrigin);
|
|
86
292
|
if (!ok) {
|
|
87
293
|
this._state = _constants.StreamState.CANCELLED;
|
|
294
|
+
this.clearExpireTimer();
|
|
88
295
|
// For most stream messages, if we cannot send, treat as a hard cancellation signal
|
|
89
296
|
// so callers can stop further processing immediately.
|
|
90
297
|
throw new Error((0, _constants.formatMessage)(_constants.Messages.STREAM_CANCELLED, 'Target window closed'));
|
|
91
298
|
}
|
|
92
299
|
return true;
|
|
93
300
|
}
|
|
301
|
+
ensureAckReceiver() {
|
|
302
|
+
if (this.ackReceiverRegistered) return;
|
|
303
|
+
if (!this.context) return;
|
|
304
|
+
var ch = this.context.channel;
|
|
305
|
+
if (typeof ch.addReceiver !== 'function' || typeof ch.removeReceiver !== 'function') return;
|
|
306
|
+
this.ackReceiver = (data, context) => {
|
|
307
|
+
if (!data || data.type !== _constants.MessageType.ACK) return;
|
|
308
|
+
var pending = this.ackWaiters.get(data.requestId);
|
|
309
|
+
if (!pending) return;
|
|
310
|
+
if (context && !context.handledBy) {
|
|
311
|
+
context.handledBy = `stream:${this.streamId}`;
|
|
312
|
+
}
|
|
313
|
+
clearTimeout(pending.timeoutId);
|
|
314
|
+
this.ackWaiters.delete(data.requestId);
|
|
315
|
+
pending.resolve(true);
|
|
316
|
+
};
|
|
317
|
+
ch.addReceiver(this.ackReceiver);
|
|
318
|
+
this.ackReceiverRegistered = true;
|
|
319
|
+
}
|
|
320
|
+
cleanupAckWaiters() {
|
|
321
|
+
this.ackWaiters.forEach(p => {
|
|
322
|
+
clearTimeout(p.timeoutId);
|
|
323
|
+
p.resolve(false);
|
|
324
|
+
});
|
|
325
|
+
this.ackWaiters.clear();
|
|
326
|
+
if (this.ackReceiverRegistered && this.ackReceiver && this.context) {
|
|
327
|
+
var ch = this.context.channel;
|
|
328
|
+
if (typeof ch.removeReceiver === 'function') {
|
|
329
|
+
try {
|
|
330
|
+
ch.removeReceiver(this.ackReceiver);
|
|
331
|
+
} catch (_unused6) {
|
|
332
|
+
/** ignore */
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
this.ackReceiverRegistered = false;
|
|
337
|
+
this.ackReceiver = undefined;
|
|
338
|
+
}
|
|
339
|
+
registerAckWaiter(requestId, timeoutMs, resolve) {
|
|
340
|
+
var timeoutId = setTimeout(() => {
|
|
341
|
+
this.ackWaiters.delete(requestId);
|
|
342
|
+
resolve(false);
|
|
343
|
+
}, timeoutMs);
|
|
344
|
+
this.ackWaiters.set(requestId, {
|
|
345
|
+
resolve,
|
|
346
|
+
timeoutId
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
clearExpireTimer() {
|
|
350
|
+
if (this.expireTimer) {
|
|
351
|
+
clearTimeout(this.expireTimer);
|
|
352
|
+
this.expireTimer = null;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
startExpireTimer() {
|
|
356
|
+
if (!this.expireTimeout || this.expireTimeout <= 0) return;
|
|
357
|
+
var expireTimeout = this.expireTimeout;
|
|
358
|
+
this.clearExpireTimer();
|
|
359
|
+
this.expireTimer = setTimeout(() => {
|
|
360
|
+
if (this._state !== _constants.StreamState.STREAMING) return;
|
|
361
|
+
try {
|
|
362
|
+
this.emit(_constants.StreamEvent.EXPIRED, {
|
|
363
|
+
timeout: expireTimeout
|
|
364
|
+
});
|
|
365
|
+
this.error((0, _constants.formatMessage)(_constants.Messages.STREAM_EXPIRED, expireTimeout));
|
|
366
|
+
} catch (_unused7) {
|
|
367
|
+
/** ignore timer-triggered send failures */
|
|
368
|
+
}
|
|
369
|
+
}, expireTimeout);
|
|
370
|
+
}
|
|
94
371
|
|
|
95
372
|
/**
|
|
96
373
|
* Start stream transfer
|
|
97
374
|
*/
|
|
98
375
|
start() {
|
|
99
|
-
var
|
|
100
|
-
return (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function
|
|
376
|
+
var _this3 = this;
|
|
377
|
+
return (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee3() {
|
|
101
378
|
var _t;
|
|
102
|
-
return _regenerator.default.wrap(function (
|
|
103
|
-
while (1) switch (
|
|
379
|
+
return _regenerator.default.wrap(function (_context3) {
|
|
380
|
+
while (1) switch (_context3.prev = _context3.next) {
|
|
104
381
|
case 0:
|
|
105
|
-
if (
|
|
106
|
-
|
|
382
|
+
if (_this3.context) {
|
|
383
|
+
_context3.next = 1;
|
|
107
384
|
break;
|
|
108
385
|
}
|
|
109
386
|
throw new Error(_constants.Messages.STREAM_NOT_BOUND);
|
|
110
387
|
case 1:
|
|
111
|
-
if (!(
|
|
112
|
-
|
|
388
|
+
if (!(_this3._state !== _constants.StreamState.PENDING)) {
|
|
389
|
+
_context3.next = 2;
|
|
113
390
|
break;
|
|
114
391
|
}
|
|
115
392
|
throw new Error(_constants.Messages.STREAM_ALREADY_STARTED);
|
|
116
393
|
case 2:
|
|
117
|
-
|
|
394
|
+
_this3.completionPromise = new Promise((resolve, reject) => {
|
|
395
|
+
_this3.resolveCompletion = resolve;
|
|
396
|
+
_this3.rejectCompletion = reject;
|
|
397
|
+
});
|
|
398
|
+
_this3._state = _constants.StreamState.STREAMING;
|
|
399
|
+
_this3.startExpireTimer();
|
|
400
|
+
_this3.startIdleTimer();
|
|
401
|
+
_this3.lastRemoteActivityAt = Date.now();
|
|
402
|
+
_this3.registerControlHandler();
|
|
118
403
|
|
|
119
404
|
// Send stream start message
|
|
120
|
-
|
|
121
|
-
type:
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
405
|
+
_this3.sendMessage(_constants.MessageType.STREAM_START, {
|
|
406
|
+
type: _this3.type,
|
|
407
|
+
mode: _this3.mode,
|
|
408
|
+
chunked: _this3.chunked,
|
|
409
|
+
metadata: _this3.metadata,
|
|
410
|
+
autoResolve: _this3.autoResolve
|
|
125
411
|
});
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
412
|
+
_this3.emit(_constants.StreamEvent.START, {
|
|
413
|
+
streamId: _this3.streamId,
|
|
414
|
+
type: _this3.type,
|
|
415
|
+
chunked: _this3.chunked,
|
|
416
|
+
mode: _this3.mode,
|
|
417
|
+
metadata: _this3.metadata
|
|
418
|
+
});
|
|
419
|
+
_context3.prev = 3;
|
|
420
|
+
if (!(_this3.mode === _constants.StreamMode.PUSH)) {
|
|
421
|
+
_context3.next = 5;
|
|
129
422
|
break;
|
|
130
423
|
}
|
|
131
|
-
|
|
132
|
-
return
|
|
424
|
+
_context3.next = 4;
|
|
425
|
+
return _this3.completionPromise;
|
|
133
426
|
case 4:
|
|
134
|
-
|
|
135
|
-
break;
|
|
427
|
+
return _context3.abrupt("return", _context3.sent);
|
|
136
428
|
case 5:
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
_context.next = 6;
|
|
142
|
-
return _this.streamFromNext();
|
|
429
|
+
// pull protocol: produce only when receiver grants credit
|
|
430
|
+
_this3.flush();
|
|
431
|
+
_context3.next = 6;
|
|
432
|
+
return _this3.completionPromise;
|
|
143
433
|
case 6:
|
|
144
|
-
|
|
145
|
-
break;
|
|
434
|
+
return _context3.abrupt("return", _context3.sent);
|
|
146
435
|
case 7:
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
break;
|
|
152
|
-
case 9:
|
|
153
|
-
_context.prev = 9;
|
|
154
|
-
_t = _context["catch"](3);
|
|
155
|
-
if (!(_this._state === _constants.StreamState.CANCELLED)) {
|
|
156
|
-
_context.next = 10;
|
|
436
|
+
_context3.prev = 7;
|
|
437
|
+
_t = _context3["catch"](3);
|
|
438
|
+
if (!(_this3._state === _constants.StreamState.CANCELLED)) {
|
|
439
|
+
_context3.next = 8;
|
|
157
440
|
break;
|
|
158
441
|
}
|
|
442
|
+
_this3.clearExpireTimer();
|
|
159
443
|
throw _t;
|
|
444
|
+
case 8:
|
|
445
|
+
_this3.error(_t.message || String(_t));
|
|
446
|
+
_context3.next = 9;
|
|
447
|
+
return _this3.completionPromise;
|
|
448
|
+
case 9:
|
|
449
|
+
return _context3.abrupt("return", _context3.sent);
|
|
160
450
|
case 10:
|
|
161
|
-
_this.error(_t.message || String(_t));
|
|
162
|
-
case 11:
|
|
163
451
|
case "end":
|
|
164
|
-
return
|
|
452
|
+
return _context3.stop();
|
|
165
453
|
}
|
|
166
|
-
},
|
|
454
|
+
}, _callee3, null, [[3, 7]]);
|
|
167
455
|
}))();
|
|
168
456
|
}
|
|
169
457
|
|
|
458
|
+
/**
|
|
459
|
+
* Push a chunk manually (mode === 'push').
|
|
460
|
+
*/
|
|
461
|
+
|
|
462
|
+
write(data, doneOrOptions = false, options) {
|
|
463
|
+
var _opts$ackTimeout;
|
|
464
|
+
if (this.mode !== _constants.StreamMode.PUSH) {
|
|
465
|
+
throw new Error(_constants.Messages.STREAM_WRITE_ONLY_IN_PUSH_MODE);
|
|
466
|
+
}
|
|
467
|
+
if (this._state === _constants.StreamState.PENDING) {
|
|
468
|
+
/**
|
|
469
|
+
* In push mode, users must call start() first so STREAM_START is sent and binding is complete.
|
|
470
|
+
*/
|
|
471
|
+
throw new Error(_constants.Messages.STREAM_NOT_BOUND);
|
|
472
|
+
}
|
|
473
|
+
if (this._state !== _constants.StreamState.STREAMING) {
|
|
474
|
+
throw new Error(_constants.Messages.STREAM_ENDED);
|
|
475
|
+
}
|
|
476
|
+
var done = typeof doneOrOptions === 'boolean' ? doneOrOptions : false;
|
|
477
|
+
var opts = typeof doneOrOptions === 'object' ? doneOrOptions : options;
|
|
478
|
+
var requireAck = (opts === null || opts === void 0 ? void 0 : opts.requireAck) === true;
|
|
479
|
+
var ackTimeout = (_opts$ackTimeout = opts === null || opts === void 0 ? void 0 : opts.ackTimeout) !== null && _opts$ackTimeout !== void 0 ? _opts$ackTimeout : _constants.DefaultTimeout.ACK;
|
|
480
|
+
if (!requireAck) {
|
|
481
|
+
// push mode now buffers and sends based on pull credit
|
|
482
|
+
this.enqueue({
|
|
483
|
+
data,
|
|
484
|
+
done
|
|
485
|
+
});
|
|
486
|
+
this.emit(_constants.StreamEvent.WRITE, {
|
|
487
|
+
data,
|
|
488
|
+
done
|
|
489
|
+
});
|
|
490
|
+
this.flush();
|
|
491
|
+
return;
|
|
492
|
+
}
|
|
493
|
+
return new Promise(resolve => {
|
|
494
|
+
var ackRequestId = (0, _utils.generateRequestId)();
|
|
495
|
+
this.enqueue({
|
|
496
|
+
data,
|
|
497
|
+
done,
|
|
498
|
+
requireAck: true,
|
|
499
|
+
ackRequestId,
|
|
500
|
+
ackTimeout,
|
|
501
|
+
resolveAck: resolve
|
|
502
|
+
});
|
|
503
|
+
this.emit(_constants.StreamEvent.WRITE, {
|
|
504
|
+
data,
|
|
505
|
+
done
|
|
506
|
+
});
|
|
507
|
+
this.flush();
|
|
508
|
+
});
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
/**
|
|
512
|
+
* End the stream (mode === 'push').
|
|
513
|
+
*/
|
|
514
|
+
end() {
|
|
515
|
+
if (this.mode !== _constants.StreamMode.PUSH) {
|
|
516
|
+
// For pull mode, end is controlled internally
|
|
517
|
+
this.endInternal();
|
|
518
|
+
return;
|
|
519
|
+
}
|
|
520
|
+
// In push mode, end means enqueue a terminal marker if nothing queued
|
|
521
|
+
if (this.mode === _constants.StreamMode.PUSH) {
|
|
522
|
+
if (this.pendingQueue.length === 0) {
|
|
523
|
+
this.enqueue({
|
|
524
|
+
data: undefined,
|
|
525
|
+
done: true
|
|
526
|
+
});
|
|
527
|
+
} else {
|
|
528
|
+
// Ensure the last queued chunk marks done
|
|
529
|
+
this.pendingQueue[this.pendingQueue.length - 1].done = true;
|
|
530
|
+
}
|
|
531
|
+
this.flush();
|
|
532
|
+
return;
|
|
533
|
+
}
|
|
534
|
+
this.endInternal();
|
|
535
|
+
}
|
|
536
|
+
|
|
170
537
|
/**
|
|
171
538
|
* Generate data from iterator
|
|
172
539
|
*/
|
|
173
|
-
|
|
174
|
-
var
|
|
175
|
-
return (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function
|
|
176
|
-
var gen,
|
|
177
|
-
return _regenerator.default.wrap(function (
|
|
178
|
-
while (1) switch (
|
|
540
|
+
pumpFromGenerator() {
|
|
541
|
+
var _this4 = this;
|
|
542
|
+
return (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee4() {
|
|
543
|
+
var gen, r, result, _t2;
|
|
544
|
+
return _regenerator.default.wrap(function (_context4) {
|
|
545
|
+
while (1) switch (_context4.prev = _context4.next) {
|
|
179
546
|
case 0:
|
|
180
|
-
if (
|
|
181
|
-
|
|
547
|
+
if (!_this4.pumping) {
|
|
548
|
+
_context4.next = 1;
|
|
182
549
|
break;
|
|
183
550
|
}
|
|
184
|
-
return
|
|
551
|
+
return _context4.abrupt("return");
|
|
185
552
|
case 1:
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
_context2.prev = 3;
|
|
191
|
-
_iterator = _asyncIterator(gen);
|
|
192
|
-
case 4:
|
|
193
|
-
_context2.next = 5;
|
|
194
|
-
return _iterator.next();
|
|
195
|
-
case 5:
|
|
196
|
-
if (!(_iteratorAbruptCompletion = !(_step = _context2.sent).done)) {
|
|
197
|
-
_context2.next = 10;
|
|
553
|
+
_this4.pumping = true;
|
|
554
|
+
_context4.prev = 2;
|
|
555
|
+
if (!_this4.iterator) {
|
|
556
|
+
_context4.next = 8;
|
|
198
557
|
break;
|
|
199
558
|
}
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
559
|
+
gen = _this4.iterator();
|
|
560
|
+
case 3:
|
|
561
|
+
if (!(_this4._state === _constants.StreamState.STREAMING)) {
|
|
562
|
+
_context4.next = 7;
|
|
203
563
|
break;
|
|
204
564
|
}
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
_context2.prev = 6;
|
|
208
|
-
_this2.sendData(chunk);
|
|
209
|
-
_context2.next = 9;
|
|
210
|
-
break;
|
|
211
|
-
case 7:
|
|
212
|
-
_context2.prev = 7;
|
|
213
|
-
_t2 = _context2["catch"](6);
|
|
214
|
-
if (!(_this2._state === _constants.StreamState.CANCELLED)) {
|
|
215
|
-
_context2.next = 8;
|
|
565
|
+
if (!(_this4.pullCredit <= 0)) {
|
|
566
|
+
_context4.next = 4;
|
|
216
567
|
break;
|
|
217
568
|
}
|
|
218
|
-
|
|
219
|
-
case
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
_context2.next = 12;
|
|
227
|
-
break;
|
|
228
|
-
case 11:
|
|
229
|
-
_context2.prev = 11;
|
|
230
|
-
_t3 = _context2["catch"](3);
|
|
231
|
-
_didIteratorError = true;
|
|
232
|
-
_iteratorError = _t3;
|
|
233
|
-
case 12:
|
|
234
|
-
_context2.prev = 12;
|
|
235
|
-
_context2.prev = 13;
|
|
236
|
-
if (!(_iteratorAbruptCompletion && _iterator.return != null)) {
|
|
237
|
-
_context2.next = 14;
|
|
238
|
-
break;
|
|
239
|
-
}
|
|
240
|
-
_context2.next = 14;
|
|
241
|
-
return _iterator.return();
|
|
242
|
-
case 14:
|
|
243
|
-
_context2.prev = 14;
|
|
244
|
-
if (!_didIteratorError) {
|
|
245
|
-
_context2.next = 15;
|
|
569
|
+
return _context4.abrupt("continue", 7);
|
|
570
|
+
case 4:
|
|
571
|
+
_context4.next = 5;
|
|
572
|
+
return gen.next();
|
|
573
|
+
case 5:
|
|
574
|
+
r = _context4.sent;
|
|
575
|
+
if (!r.done) {
|
|
576
|
+
_context4.next = 6;
|
|
246
577
|
break;
|
|
247
578
|
}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
return
|
|
251
|
-
case
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
579
|
+
// no more data: send end
|
|
580
|
+
_this4.endInternal();
|
|
581
|
+
return _context4.abrupt("continue", 7);
|
|
582
|
+
case 6:
|
|
583
|
+
_this4.enqueue({
|
|
584
|
+
data: r.value,
|
|
585
|
+
done: false
|
|
586
|
+
});
|
|
587
|
+
_this4.flush();
|
|
588
|
+
_context4.next = 3;
|
|
258
589
|
break;
|
|
259
|
-
case
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
590
|
+
case 7:
|
|
591
|
+
_context4.next = 15;
|
|
592
|
+
break;
|
|
593
|
+
case 8:
|
|
594
|
+
if (!_this4.nextFn) {
|
|
595
|
+
_context4.next = 14;
|
|
264
596
|
break;
|
|
265
597
|
}
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
_this2.error(_t4.message || String(_t4));
|
|
270
|
-
}
|
|
271
|
-
case 20:
|
|
272
|
-
case "end":
|
|
273
|
-
return _context2.stop();
|
|
274
|
-
}
|
|
275
|
-
}, _callee2, null, [[2, 18], [3, 11, 12, 17], [6, 7], [13,, 14, 16]]);
|
|
276
|
-
}))();
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
/**
|
|
280
|
-
* Generate data from next function
|
|
281
|
-
*/
|
|
282
|
-
streamFromNext() {
|
|
283
|
-
var _this3 = this;
|
|
284
|
-
return (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee3() {
|
|
285
|
-
var result, _t5;
|
|
286
|
-
return _regenerator.default.wrap(function (_context3) {
|
|
287
|
-
while (1) switch (_context3.prev = _context3.next) {
|
|
288
|
-
case 0:
|
|
289
|
-
if (_this3.nextFn) {
|
|
290
|
-
_context3.next = 1;
|
|
598
|
+
case 9:
|
|
599
|
+
if (!(_this4._state === _constants.StreamState.STREAMING)) {
|
|
600
|
+
_context4.next = 13;
|
|
291
601
|
break;
|
|
292
602
|
}
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
_context3.prev = 1;
|
|
296
|
-
case 2:
|
|
297
|
-
if (!(_this3._state === _constants.StreamState.STREAMING)) {
|
|
298
|
-
_context3.next = 5;
|
|
603
|
+
if (!(_this4.pullCredit <= 0)) {
|
|
604
|
+
_context4.next = 10;
|
|
299
605
|
break;
|
|
300
606
|
}
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
607
|
+
return _context4.abrupt("continue", 13);
|
|
608
|
+
case 10:
|
|
609
|
+
_context4.next = 11;
|
|
610
|
+
return Promise.resolve(_this4.nextFn());
|
|
611
|
+
case 11:
|
|
612
|
+
result = _context4.sent;
|
|
613
|
+
_this4.enqueue({
|
|
614
|
+
data: result.data,
|
|
615
|
+
done: result.done
|
|
616
|
+
});
|
|
617
|
+
_this4.flush();
|
|
305
618
|
if (!result.done) {
|
|
306
|
-
|
|
619
|
+
_context4.next = 12;
|
|
307
620
|
break;
|
|
308
621
|
}
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
case 4:
|
|
313
|
-
_this3.sendData(result.data);
|
|
314
|
-
_context3.next = 2;
|
|
622
|
+
return _context4.abrupt("continue", 13);
|
|
623
|
+
case 12:
|
|
624
|
+
_context4.next = 9;
|
|
315
625
|
break;
|
|
316
|
-
case
|
|
317
|
-
|
|
626
|
+
case 13:
|
|
627
|
+
_context4.next = 15;
|
|
318
628
|
break;
|
|
319
|
-
case
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
_context3.next = 7;
|
|
324
|
-
break;
|
|
629
|
+
case 14:
|
|
630
|
+
// No producer, just end when pulled
|
|
631
|
+
if (_this4.pullCredit > 0) {
|
|
632
|
+
_this4.endInternal();
|
|
325
633
|
}
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
634
|
+
case 15:
|
|
635
|
+
_context4.next = 17;
|
|
636
|
+
break;
|
|
637
|
+
case 16:
|
|
638
|
+
_context4.prev = 16;
|
|
639
|
+
_t2 = _context4["catch"](2);
|
|
640
|
+
if (_this4._state === _constants.StreamState.STREAMING) {
|
|
641
|
+
_this4.error((_t2 === null || _t2 === void 0 ? void 0 : _t2.message) || String(_t2));
|
|
330
642
|
}
|
|
331
|
-
case
|
|
643
|
+
case 17:
|
|
644
|
+
_context4.prev = 17;
|
|
645
|
+
_this4.pumping = false;
|
|
646
|
+
return _context4.finish(17);
|
|
647
|
+
case 18:
|
|
332
648
|
case "end":
|
|
333
|
-
return
|
|
649
|
+
return _context4.stop();
|
|
334
650
|
}
|
|
335
|
-
},
|
|
651
|
+
}, _callee4, null, [[2, 16, 17, 18]]);
|
|
336
652
|
}))();
|
|
337
653
|
}
|
|
338
654
|
|
|
339
655
|
/**
|
|
340
656
|
* Send data chunk
|
|
341
657
|
*/
|
|
342
|
-
sendData(data, done = false) {
|
|
343
|
-
|
|
344
|
-
|
|
658
|
+
sendData(data, done = false, options) {
|
|
659
|
+
var _this$context$serverI2, _options$requestId;
|
|
660
|
+
if (!this.context) {
|
|
661
|
+
throw new Error(_constants.Messages.STREAM_NOT_BOUND);
|
|
662
|
+
}
|
|
663
|
+
var seq = this.seq++;
|
|
664
|
+
var isClientStream = this.context.clientId !== undefined && this.context.serverId === undefined;
|
|
665
|
+
var role = isClientStream ? _constants.MessageRole.CLIENT : _constants.MessageRole.SERVER;
|
|
666
|
+
var creatorId = (_this$context$serverI2 = this.context.serverId) !== null && _this$context$serverI2 !== void 0 ? _this$context$serverI2 : this.context.clientId;
|
|
667
|
+
var message = (0, _utils.createPostMessage)(_constants.MessageType.STREAM_DATA, (_options$requestId = options === null || options === void 0 ? void 0 : options.requestId) !== null && _options$requestId !== void 0 ? _options$requestId : this.context.requestId, {
|
|
668
|
+
secretKey: this.context.secretKey,
|
|
669
|
+
requireAck: options === null || options === void 0 ? void 0 : options.requireAck,
|
|
670
|
+
/**
|
|
671
|
+
* When per-frame requireAck is enabled, include a unique identifier in ack.
|
|
672
|
+
* - seq is the stream frame sequence number.
|
|
673
|
+
*
|
|
674
|
+
* NOTE: ack is an internal reserved field (not part of public API).
|
|
675
|
+
*/
|
|
676
|
+
ack: options !== null && options !== void 0 && options.requireAck ? {
|
|
677
|
+
id: `${this.streamId}:${seq}`
|
|
678
|
+
} : undefined,
|
|
679
|
+
body: {
|
|
680
|
+
streamId: this.streamId,
|
|
681
|
+
data: this.encodeData(data),
|
|
682
|
+
done,
|
|
683
|
+
seq
|
|
684
|
+
},
|
|
685
|
+
role,
|
|
686
|
+
creatorId,
|
|
687
|
+
targetId: this.context.targetId
|
|
688
|
+
});
|
|
689
|
+
var ok = this.context.channel.send(this.context.targetWindow, message, this.context.targetOrigin);
|
|
690
|
+
if (!ok) {
|
|
691
|
+
this._state = _constants.StreamState.CANCELLED;
|
|
692
|
+
this.clearExpireTimer();
|
|
693
|
+
throw new Error((0, _constants.formatMessage)(_constants.Messages.STREAM_CANCELLED, 'Target window closed'));
|
|
694
|
+
}
|
|
695
|
+
this.emit(_constants.StreamEvent.SEND, {
|
|
696
|
+
seq,
|
|
345
697
|
done
|
|
346
698
|
});
|
|
347
699
|
}
|
|
700
|
+
flush() {
|
|
701
|
+
if (this._state !== _constants.StreamState.STREAMING) return;
|
|
702
|
+
|
|
703
|
+
// First try to pump from generator if needed
|
|
704
|
+
if (this.mode === _constants.StreamMode.PULL && this.pendingQueue.length === 0) {
|
|
705
|
+
void this.pumpFromGenerator();
|
|
706
|
+
}
|
|
707
|
+
while (this.pullCredit > 0 && this.pendingQueue.length > 0 && this._state === _constants.StreamState.STREAMING) {
|
|
708
|
+
var item = this.pendingQueue.shift();
|
|
709
|
+
this.pendingBytes -= item.bytes;
|
|
710
|
+
this.pullCredit--;
|
|
711
|
+
try {
|
|
712
|
+
if (item.requireAck && item.ackRequestId && item.resolveAck) {
|
|
713
|
+
this.ensureAckReceiver();
|
|
714
|
+
if (this.ackReceiverRegistered) {
|
|
715
|
+
var _item$ackTimeout;
|
|
716
|
+
this.registerAckWaiter(item.ackRequestId, (_item$ackTimeout = item.ackTimeout) !== null && _item$ackTimeout !== void 0 ? _item$ackTimeout : _constants.DefaultTimeout.ACK, item.resolveAck);
|
|
717
|
+
this.sendData(item.data, item.done, {
|
|
718
|
+
requestId: item.ackRequestId,
|
|
719
|
+
requireAck: true
|
|
720
|
+
});
|
|
721
|
+
} else {
|
|
722
|
+
item.resolveAck(false);
|
|
723
|
+
this.sendData(item.data, item.done);
|
|
724
|
+
}
|
|
725
|
+
} else {
|
|
726
|
+
this.sendData(item.data, item.done);
|
|
727
|
+
}
|
|
728
|
+
} catch (e) {
|
|
729
|
+
var _this$rejectCompletio;
|
|
730
|
+
// send failure treated as cancellation
|
|
731
|
+
this._state = _constants.StreamState.CANCELLED;
|
|
732
|
+
this.clearExpireTimer();
|
|
733
|
+
this.clearIdleTimer();
|
|
734
|
+
this.unregisterControlHandler();
|
|
735
|
+
this.pendingQueue.length = 0;
|
|
736
|
+
this.pendingBytes = 0;
|
|
737
|
+
this.cleanupAckWaiters();
|
|
738
|
+
(_this$rejectCompletio = this.rejectCompletion) === null || _this$rejectCompletio === void 0 || _this$rejectCompletio.call(this, e instanceof Error ? e : new Error(String(e)));
|
|
739
|
+
throw e;
|
|
740
|
+
}
|
|
741
|
+
if (item.done) {
|
|
742
|
+
this.endInternal();
|
|
743
|
+
break;
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
}
|
|
348
747
|
|
|
349
748
|
/**
|
|
350
749
|
* Encode data (subclasses can override, e.g., FileStream needs Base64 encoding)
|
|
@@ -356,38 +755,89 @@ class IframeWritableStream {
|
|
|
356
755
|
/**
|
|
357
756
|
* End stream
|
|
358
757
|
*/
|
|
359
|
-
|
|
758
|
+
endInternal() {
|
|
759
|
+
var _this$resolveCompleti;
|
|
360
760
|
if (this._state !== _constants.StreamState.STREAMING) return;
|
|
361
761
|
this._state = _constants.StreamState.ENDED;
|
|
762
|
+
this.clearExpireTimer();
|
|
763
|
+
this.clearIdleTimer();
|
|
764
|
+
this.unregisterControlHandler();
|
|
765
|
+
this.pendingQueue.length = 0;
|
|
766
|
+
this.pendingBytes = 0;
|
|
362
767
|
this.sendMessage(_constants.MessageType.STREAM_END);
|
|
768
|
+
this.emit(_constants.StreamEvent.END);
|
|
769
|
+
this.emit(_constants.StreamEvent.STATE, {
|
|
770
|
+
state: this._state
|
|
771
|
+
});
|
|
772
|
+
this.cleanupAckWaiters();
|
|
773
|
+
this.clearAllListeners();
|
|
774
|
+
(_this$resolveCompleti = this.resolveCompletion) === null || _this$resolveCompleti === void 0 || _this$resolveCompleti.call(this);
|
|
363
775
|
}
|
|
364
776
|
|
|
365
777
|
/**
|
|
366
778
|
* Send error
|
|
367
779
|
*/
|
|
368
780
|
error(message) {
|
|
781
|
+
var _this$resolveCompleti2;
|
|
369
782
|
if (this._state !== _constants.StreamState.STREAMING) return;
|
|
370
783
|
this._state = _constants.StreamState.ERROR;
|
|
784
|
+
this.clearExpireTimer();
|
|
785
|
+
this.clearIdleTimer();
|
|
786
|
+
this.unregisterControlHandler();
|
|
787
|
+
this.pendingQueue.length = 0;
|
|
788
|
+
this.pendingBytes = 0;
|
|
371
789
|
this.sendMessage(_constants.MessageType.STREAM_ERROR, {
|
|
372
790
|
error: message
|
|
373
791
|
});
|
|
792
|
+
this.emit(_constants.StreamEvent.ERROR, {
|
|
793
|
+
error: new Error(message)
|
|
794
|
+
});
|
|
795
|
+
this.emit(_constants.StreamEvent.STATE, {
|
|
796
|
+
state: this._state
|
|
797
|
+
});
|
|
798
|
+
this.cleanupAckWaiters();
|
|
799
|
+
this.clearAllListeners();
|
|
800
|
+
(_this$resolveCompleti2 = this.resolveCompletion) === null || _this$resolveCompleti2 === void 0 || _this$resolveCompleti2.call(this);
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
/**
|
|
804
|
+
* Abort stream transfer (is alias of cancel method)
|
|
805
|
+
*/
|
|
806
|
+
abort(reason) {
|
|
807
|
+
this.cancel(reason);
|
|
374
808
|
}
|
|
375
809
|
|
|
376
810
|
/**
|
|
377
811
|
* Cancel stream transfer
|
|
378
812
|
*/
|
|
379
813
|
cancel(reason) {
|
|
814
|
+
var _this$resolveCompleti3;
|
|
380
815
|
if (this._state !== _constants.StreamState.PENDING && this._state !== _constants.StreamState.STREAMING) return;
|
|
381
816
|
this._state = _constants.StreamState.CANCELLED;
|
|
817
|
+
this.clearExpireTimer();
|
|
818
|
+
this.clearIdleTimer();
|
|
819
|
+
this.unregisterControlHandler();
|
|
820
|
+
this.pendingQueue.length = 0;
|
|
821
|
+
this.pendingBytes = 0;
|
|
822
|
+
this.emit(_constants.StreamEvent.CANCEL, {
|
|
823
|
+
reason,
|
|
824
|
+
remote: false
|
|
825
|
+
});
|
|
826
|
+
this.emit(_constants.StreamEvent.STATE, {
|
|
827
|
+
state: this._state
|
|
828
|
+
});
|
|
382
829
|
if (this.context) {
|
|
383
830
|
try {
|
|
384
831
|
this.sendMessage(_constants.MessageType.STREAM_CANCEL, {
|
|
385
832
|
reason
|
|
386
833
|
});
|
|
387
|
-
} catch (
|
|
834
|
+
} catch (_unused8) {
|
|
388
835
|
// ignore send failures on cancel
|
|
389
836
|
}
|
|
390
837
|
}
|
|
838
|
+
this.cleanupAckWaiters();
|
|
839
|
+
this.clearAllListeners();
|
|
840
|
+
(_this$resolveCompleti3 = this.resolveCompletion) === null || _this$resolveCompleti3 === void 0 || _this$resolveCompleti3.call(this);
|
|
391
841
|
}
|
|
392
842
|
}
|
|
393
843
|
exports.IframeWritableStream = IframeWritableStream;
|