@lingxia/bridge 0.5.0 → 0.6.0
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/dist/bridge-runtime.es2020.js +1 -0
- package/dist/bridge-runtime.es5.js +1 -0
- package/dist/bridge.d.ts +5 -2
- package/dist/es2020/boot.js +34 -0
- package/dist/es2020/bridge.js +1597 -0
- package/dist/es2020/error.js +89 -0
- package/dist/es2020/image-proxy.js +82 -0
- package/dist/es2020/index.js +19 -0
- package/dist/es2020/invocation.js +77 -0
- package/dist/es2020/nativecomponents/coverage-monitor.js +159 -0
- package/dist/es2020/runtime-env.js +31 -0
- package/dist/es2020/types.js +16 -0
- package/dist/es2020/ui/action-sheet.js +138 -0
- package/dist/es2020/ui/index.js +10 -0
- package/dist/es2020/ui/modal.js +170 -0
- package/dist/es2020/ui/toast.js +145 -0
- package/dist/es5/boot.js +34 -0
- package/dist/es5/bridge.js +1930 -0
- package/dist/es5/error.js +35 -0
- package/dist/es5/image-proxy.js +83 -0
- package/dist/es5/index.js +19 -0
- package/dist/es5/invocation.js +103 -0
- package/dist/es5/nativecomponents/coverage-monitor.js +219 -0
- package/dist/es5/runtime-env.js +32 -0
- package/dist/es5/types.js +16 -0
- package/dist/es5/ui/action-sheet.js +82 -0
- package/dist/es5/ui/index.js +10 -0
- package/dist/es5/ui/modal.js +84 -0
- package/dist/es5/ui/toast.js +102 -0
- package/dist/index.d.ts +3 -2
- package/dist/invocation.d.ts +14 -0
- package/dist/types.d.ts +42 -15
- package/package.json +21 -9
- package/dist/runtime.es2020.js +0 -1663
- package/dist/runtime.es5.js +0 -1
|
@@ -0,0 +1,1930 @@
|
|
|
1
|
+
var __assign = (this && this.__assign) || function () {
|
|
2
|
+
__assign = Object.assign || function(t) {
|
|
3
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
+
s = arguments[i];
|
|
5
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
+
t[p] = s[p];
|
|
7
|
+
}
|
|
8
|
+
return t;
|
|
9
|
+
};
|
|
10
|
+
return __assign.apply(this, arguments);
|
|
11
|
+
};
|
|
12
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
13
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
14
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
15
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
16
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
17
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
18
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
22
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
23
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
24
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
25
|
+
function step(op) {
|
|
26
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
27
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
28
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
29
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
30
|
+
switch (op[0]) {
|
|
31
|
+
case 0: case 1: t = op; break;
|
|
32
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
33
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
34
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
35
|
+
default:
|
|
36
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
37
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
38
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
39
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
40
|
+
if (t[2]) _.ops.pop();
|
|
41
|
+
_.trys.pop(); continue;
|
|
42
|
+
}
|
|
43
|
+
op = body.call(thisArg, _);
|
|
44
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
45
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
var __values = (this && this.__values) || function(o) {
|
|
49
|
+
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
|
|
50
|
+
if (m) return m.call(o);
|
|
51
|
+
if (o && typeof o.length === "number") return {
|
|
52
|
+
next: function () {
|
|
53
|
+
if (o && i >= o.length) o = void 0;
|
|
54
|
+
return { value: o && o[i++], done: !o };
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
|
|
58
|
+
};
|
|
59
|
+
var __read = (this && this.__read) || function (o, n) {
|
|
60
|
+
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
61
|
+
if (!m) return o;
|
|
62
|
+
var i = m.call(o), r, ar = [], e;
|
|
63
|
+
try {
|
|
64
|
+
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
65
|
+
}
|
|
66
|
+
catch (error) { e = { error: error }; }
|
|
67
|
+
finally {
|
|
68
|
+
try {
|
|
69
|
+
if (r && !r.done && (m = i["return"])) m.call(i);
|
|
70
|
+
}
|
|
71
|
+
finally { if (e) throw e.error; }
|
|
72
|
+
}
|
|
73
|
+
return ar;
|
|
74
|
+
};
|
|
75
|
+
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
76
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
77
|
+
if (ar || !(i in from)) {
|
|
78
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
79
|
+
ar[i] = from[i];
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
83
|
+
};
|
|
84
|
+
import { BRIDGE_ERROR } from "./types";
|
|
85
|
+
import { toBridgeError, toNativeError } from "./invocation";
|
|
86
|
+
import { installNativeComponentCoverageMonitor } from "./nativecomponents/coverage-monitor";
|
|
87
|
+
import { BRIDGE_CONFIG, getCommunicationMethod, getPlatformOS, isAndroid, isHarmony, isIOS, isMacOS, isDesktop, } from "./runtime-env";
|
|
88
|
+
var NATIVE_HANDLER_NAME = "LingXia";
|
|
89
|
+
var GLOBAL_RECEIVER_NAME = "__LingXiaRecvMessage";
|
|
90
|
+
var DEFAULT_TIMEOUT_MS = 5000;
|
|
91
|
+
var HANDSHAKE_TIMEOUT_MS = 10000;
|
|
92
|
+
var HANDSHAKE_MAX_RETRIES = 3;
|
|
93
|
+
var LOG_PREFIX = "[LX.Bridge]";
|
|
94
|
+
var MESSAGE_PORT_TYPE = "messageport";
|
|
95
|
+
var JS_INTERFACE_TYPE = "jsinterface";
|
|
96
|
+
var OUTBOX_LIMIT = 256;
|
|
97
|
+
var APPLE_DOWNSTREAM_URL = "lx-apple://bridge/downstream";
|
|
98
|
+
var APPLE_RECONNECT_BASE_MS = 200;
|
|
99
|
+
var APPLE_RECONNECT_MAX_MS = 2000;
|
|
100
|
+
var debugFlags = { data: false, proto: false, all: false };
|
|
101
|
+
var earlyNativeMessages = [];
|
|
102
|
+
function installEarlyReceiver() {
|
|
103
|
+
if (typeof window === "undefined")
|
|
104
|
+
return;
|
|
105
|
+
if (typeof window[GLOBAL_RECEIVER_NAME] === "function")
|
|
106
|
+
return;
|
|
107
|
+
window[GLOBAL_RECEIVER_NAME] = function (message) {
|
|
108
|
+
earlyNativeMessages.push(message);
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
function activateReceiver(receiver) {
|
|
112
|
+
var e_1, _a;
|
|
113
|
+
if (typeof window === "undefined")
|
|
114
|
+
return;
|
|
115
|
+
window[GLOBAL_RECEIVER_NAME] = receiver;
|
|
116
|
+
if (earlyNativeMessages.length === 0)
|
|
117
|
+
return;
|
|
118
|
+
var queued = earlyNativeMessages.splice(0, earlyNativeMessages.length);
|
|
119
|
+
try {
|
|
120
|
+
for (var queued_1 = __values(queued), queued_1_1 = queued_1.next(); !queued_1_1.done; queued_1_1 = queued_1.next()) {
|
|
121
|
+
var message = queued_1_1.value;
|
|
122
|
+
try {
|
|
123
|
+
receiver(message);
|
|
124
|
+
}
|
|
125
|
+
catch (err) {
|
|
126
|
+
warn("Failed to replay queued native message:", err);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
131
|
+
finally {
|
|
132
|
+
try {
|
|
133
|
+
if (queued_1_1 && !queued_1_1.done && (_a = queued_1.return)) _a.call(queued_1);
|
|
134
|
+
}
|
|
135
|
+
finally { if (e_1) throw e_1.error; }
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
function isDebugEnabled(flag) {
|
|
139
|
+
return debugFlags.all || debugFlags[flag];
|
|
140
|
+
}
|
|
141
|
+
function log() {
|
|
142
|
+
var args = [];
|
|
143
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
144
|
+
args[_i] = arguments[_i];
|
|
145
|
+
}
|
|
146
|
+
console.log.apply(console, __spreadArray([LOG_PREFIX], __read(args), false));
|
|
147
|
+
}
|
|
148
|
+
function warn() {
|
|
149
|
+
var args = [];
|
|
150
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
151
|
+
args[_i] = arguments[_i];
|
|
152
|
+
}
|
|
153
|
+
console.warn.apply(console, __spreadArray([LOG_PREFIX], __read(args), false));
|
|
154
|
+
}
|
|
155
|
+
function error() {
|
|
156
|
+
var args = [];
|
|
157
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
158
|
+
args[_i] = arguments[_i];
|
|
159
|
+
}
|
|
160
|
+
console.error.apply(console, __spreadArray([LOG_PREFIX], __read(args), false));
|
|
161
|
+
}
|
|
162
|
+
function safeStringify(obj, space) {
|
|
163
|
+
var seen = new WeakSet();
|
|
164
|
+
return JSON.stringify(obj, function (_key, value) {
|
|
165
|
+
if (typeof value === "object" && value !== null) {
|
|
166
|
+
if (seen.has(value))
|
|
167
|
+
return "[Circular]";
|
|
168
|
+
seen.add(value);
|
|
169
|
+
}
|
|
170
|
+
return value;
|
|
171
|
+
}, space);
|
|
172
|
+
}
|
|
173
|
+
function stringifyForNative(obj) {
|
|
174
|
+
try {
|
|
175
|
+
return JSON.stringify(obj);
|
|
176
|
+
}
|
|
177
|
+
catch (_a) {
|
|
178
|
+
return safeStringify(obj);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
function deepCopy(data) {
|
|
182
|
+
try {
|
|
183
|
+
if (typeof structuredClone === "function")
|
|
184
|
+
return structuredClone(data);
|
|
185
|
+
return JSON.parse(JSON.stringify(data));
|
|
186
|
+
}
|
|
187
|
+
catch (_a) {
|
|
188
|
+
return {};
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
var communicationMethod = getCommunicationMethod();
|
|
192
|
+
installEarlyReceiver();
|
|
193
|
+
// Transport
|
|
194
|
+
var messagePort = null;
|
|
195
|
+
var appleDownstreamConnected = false;
|
|
196
|
+
var appleDownstreamTask = null;
|
|
197
|
+
var appleDownstreamAbortController = null;
|
|
198
|
+
var appleReconnectTimer = null;
|
|
199
|
+
var appleReconnectDelayMs = APPLE_RECONNECT_BASE_MS;
|
|
200
|
+
var portInitState = {
|
|
201
|
+
listenerInstalled: false,
|
|
202
|
+
promise: null,
|
|
203
|
+
resolve: null,
|
|
204
|
+
reject: null,
|
|
205
|
+
timer: null,
|
|
206
|
+
};
|
|
207
|
+
var portInitMessageListener = {
|
|
208
|
+
handleEvent: function (event) {
|
|
209
|
+
var _a, _b;
|
|
210
|
+
var messageEvent = event;
|
|
211
|
+
if (messageEvent.data !== "LingXia-port-init")
|
|
212
|
+
return;
|
|
213
|
+
var port = (_a = messageEvent.ports) === null || _a === void 0 ? void 0 : _a[0];
|
|
214
|
+
if (!port)
|
|
215
|
+
return;
|
|
216
|
+
LingXiaBridge._connectWebMessagePort(port);
|
|
217
|
+
(_b = portInitState.resolve) === null || _b === void 0 ? void 0 : _b.call(portInitState, port);
|
|
218
|
+
},
|
|
219
|
+
};
|
|
220
|
+
function installMessagePortInitListener() {
|
|
221
|
+
if (portInitState.listenerInstalled)
|
|
222
|
+
return;
|
|
223
|
+
portInitState.listenerInstalled = true;
|
|
224
|
+
window.addEventListener("message", portInitMessageListener);
|
|
225
|
+
}
|
|
226
|
+
function cleanupPortInit() {
|
|
227
|
+
if (portInitState.timer !== null) {
|
|
228
|
+
window.clearTimeout(portInitState.timer);
|
|
229
|
+
portInitState.timer = null;
|
|
230
|
+
}
|
|
231
|
+
portInitState.resolve = null;
|
|
232
|
+
portInitState.reject = null;
|
|
233
|
+
portInitState.promise = null;
|
|
234
|
+
}
|
|
235
|
+
function useAppleDownstreamTransport() {
|
|
236
|
+
return communicationMethod === "webkit" && (isIOS() || isMacOS());
|
|
237
|
+
}
|
|
238
|
+
function clearAppleReconnectTimer() {
|
|
239
|
+
if (appleReconnectTimer !== null) {
|
|
240
|
+
clearTimeout(appleReconnectTimer);
|
|
241
|
+
appleReconnectTimer = null;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
function closeActiveChannelsFromTransport(reason) {
|
|
245
|
+
var e_2, _a;
|
|
246
|
+
try {
|
|
247
|
+
for (var _b = __values(Array.from(activeChannels.entries())), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
248
|
+
var _d = __read(_c.value, 2), id = _d[0], channel_1 = _d[1];
|
|
249
|
+
activeChannels.delete(id);
|
|
250
|
+
channel_1._emitClose(BRIDGE_ERROR.STREAM_CLOSED, reason);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
254
|
+
finally {
|
|
255
|
+
try {
|
|
256
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
257
|
+
}
|
|
258
|
+
finally { if (e_2) throw e_2.error; }
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
function rejectAllPendingForTransport(reason) {
|
|
262
|
+
var e_3, _a, e_4, _b;
|
|
263
|
+
try {
|
|
264
|
+
for (var _c = __values(Array.from(pendingReq.keys())), _d = _c.next(); !_d.done; _d = _c.next()) {
|
|
265
|
+
var id = _d.value;
|
|
266
|
+
rejectPendingRequest(id, {
|
|
267
|
+
code: BRIDGE_ERROR.STREAM_CLOSED,
|
|
268
|
+
message: reason,
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
|
273
|
+
finally {
|
|
274
|
+
try {
|
|
275
|
+
if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
|
|
276
|
+
}
|
|
277
|
+
finally { if (e_3) throw e_3.error; }
|
|
278
|
+
}
|
|
279
|
+
try {
|
|
280
|
+
for (var _e = __values(Array.from(pendingChannels.keys())), _f = _e.next(); !_f.done; _f = _e.next()) {
|
|
281
|
+
var id = _f.value;
|
|
282
|
+
rejectPendingChannel(id, {
|
|
283
|
+
code: BRIDGE_ERROR.STREAM_CLOSED,
|
|
284
|
+
message: reason,
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
catch (e_4_1) { e_4 = { error: e_4_1 }; }
|
|
289
|
+
finally {
|
|
290
|
+
try {
|
|
291
|
+
if (_f && !_f.done && (_b = _e.return)) _b.call(_e);
|
|
292
|
+
}
|
|
293
|
+
finally { if (e_4) throw e_4.error; }
|
|
294
|
+
}
|
|
295
|
+
closeActiveChannelsFromTransport(reason);
|
|
296
|
+
}
|
|
297
|
+
function resetHandshakeState(reason, rejectPending) {
|
|
298
|
+
clearHandshakeTimer();
|
|
299
|
+
handshakeSessionId = null;
|
|
300
|
+
handshakeDone = false;
|
|
301
|
+
helloSent = false;
|
|
302
|
+
handshakeRetryCount = 0;
|
|
303
|
+
if (rejectPending)
|
|
304
|
+
rejectAllPendingForTransport(reason);
|
|
305
|
+
}
|
|
306
|
+
function processAppleDownstreamBuffer(buffer) {
|
|
307
|
+
var remaining = buffer;
|
|
308
|
+
while (true) {
|
|
309
|
+
var newlineIndex = remaining.indexOf("\n");
|
|
310
|
+
if (newlineIndex < 0)
|
|
311
|
+
break;
|
|
312
|
+
var line = remaining.slice(0, newlineIndex).trim();
|
|
313
|
+
remaining = remaining.slice(newlineIndex + 1);
|
|
314
|
+
if (!line)
|
|
315
|
+
continue;
|
|
316
|
+
try {
|
|
317
|
+
handleIncomingMessage(JSON.parse(line));
|
|
318
|
+
}
|
|
319
|
+
catch (e) {
|
|
320
|
+
warn("Apple downstream parse error:", e, line);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
return remaining;
|
|
324
|
+
}
|
|
325
|
+
function runAppleDownstream() {
|
|
326
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
327
|
+
var controller, response, e_5, reader, decoder, buffered, _a, value, done, tail;
|
|
328
|
+
return __generator(this, function (_b) {
|
|
329
|
+
switch (_b.label) {
|
|
330
|
+
case 0:
|
|
331
|
+
controller = new AbortController();
|
|
332
|
+
appleDownstreamAbortController = controller;
|
|
333
|
+
_b.label = 1;
|
|
334
|
+
case 1:
|
|
335
|
+
_b.trys.push([1, 3, , 4]);
|
|
336
|
+
return [4 /*yield*/, fetch(APPLE_DOWNSTREAM_URL, {
|
|
337
|
+
method: "GET",
|
|
338
|
+
cache: "no-store",
|
|
339
|
+
headers: { Accept: "application/x-ndjson" },
|
|
340
|
+
signal: controller.signal,
|
|
341
|
+
})];
|
|
342
|
+
case 2:
|
|
343
|
+
response = _b.sent();
|
|
344
|
+
return [3 /*break*/, 4];
|
|
345
|
+
case 3:
|
|
346
|
+
e_5 = _b.sent();
|
|
347
|
+
if (controller.signal.aborted)
|
|
348
|
+
return [2 /*return*/];
|
|
349
|
+
throw e_5;
|
|
350
|
+
case 4:
|
|
351
|
+
if (!response.ok) {
|
|
352
|
+
throw new Error("Apple downstream HTTP ".concat(response.status));
|
|
353
|
+
}
|
|
354
|
+
if (!response.body) {
|
|
355
|
+
throw new Error("Apple downstream response body unavailable");
|
|
356
|
+
}
|
|
357
|
+
appleDownstreamConnected = true;
|
|
358
|
+
appleReconnectDelayMs = APPLE_RECONNECT_BASE_MS;
|
|
359
|
+
if (isDebugEnabled("proto"))
|
|
360
|
+
log("Apple downstream connected");
|
|
361
|
+
startHandshake();
|
|
362
|
+
reader = response.body.getReader();
|
|
363
|
+
decoder = new TextDecoder();
|
|
364
|
+
buffered = "";
|
|
365
|
+
_b.label = 5;
|
|
366
|
+
case 5:
|
|
367
|
+
_b.trys.push([5, , 9, 10]);
|
|
368
|
+
_b.label = 6;
|
|
369
|
+
case 6:
|
|
370
|
+
if (!true) return [3 /*break*/, 8];
|
|
371
|
+
return [4 /*yield*/, reader.read()];
|
|
372
|
+
case 7:
|
|
373
|
+
_a = _b.sent(), value = _a.value, done = _a.done;
|
|
374
|
+
if (done)
|
|
375
|
+
return [3 /*break*/, 8];
|
|
376
|
+
buffered += decoder.decode(value, { stream: true });
|
|
377
|
+
buffered = processAppleDownstreamBuffer(buffered);
|
|
378
|
+
return [3 /*break*/, 6];
|
|
379
|
+
case 8:
|
|
380
|
+
buffered += decoder.decode();
|
|
381
|
+
tail = buffered.trim();
|
|
382
|
+
if (tail) {
|
|
383
|
+
try {
|
|
384
|
+
handleIncomingMessage(JSON.parse(tail));
|
|
385
|
+
}
|
|
386
|
+
catch (e) {
|
|
387
|
+
warn("Apple downstream trailing parse error:", e, tail);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
return [3 /*break*/, 10];
|
|
391
|
+
case 9:
|
|
392
|
+
try {
|
|
393
|
+
reader.releaseLock();
|
|
394
|
+
}
|
|
395
|
+
catch (_c) { }
|
|
396
|
+
return [7 /*endfinally*/];
|
|
397
|
+
case 10: return [2 /*return*/];
|
|
398
|
+
}
|
|
399
|
+
});
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
function scheduleAppleDownstreamReconnect(reason) {
|
|
403
|
+
if (!useAppleDownstreamTransport())
|
|
404
|
+
return;
|
|
405
|
+
clearAppleReconnectTimer();
|
|
406
|
+
var delay = appleReconnectDelayMs;
|
|
407
|
+
appleReconnectDelayMs = Math.min(appleReconnectDelayMs * 2, APPLE_RECONNECT_MAX_MS);
|
|
408
|
+
var message = "Apple downstream disconnected, retrying in ".concat(delay, "ms: ").concat(reason);
|
|
409
|
+
if (delay <= APPLE_RECONNECT_BASE_MS) {
|
|
410
|
+
log(message);
|
|
411
|
+
}
|
|
412
|
+
else {
|
|
413
|
+
warn(message);
|
|
414
|
+
}
|
|
415
|
+
appleReconnectTimer = setTimeout(function () {
|
|
416
|
+
appleReconnectTimer = null;
|
|
417
|
+
ensureAppleDownstream();
|
|
418
|
+
}, delay);
|
|
419
|
+
}
|
|
420
|
+
function ensureAppleDownstream() {
|
|
421
|
+
if (!useAppleDownstreamTransport())
|
|
422
|
+
return;
|
|
423
|
+
if (appleDownstreamTask)
|
|
424
|
+
return;
|
|
425
|
+
clearAppleReconnectTimer();
|
|
426
|
+
appleDownstreamTask = runAppleDownstream()
|
|
427
|
+
.catch(function (e) {
|
|
428
|
+
if (appleDownstreamAbortController === null || appleDownstreamAbortController === void 0 ? void 0 : appleDownstreamAbortController.signal.aborted)
|
|
429
|
+
return;
|
|
430
|
+
warn("Apple downstream failed:", e);
|
|
431
|
+
})
|
|
432
|
+
.finally(function () {
|
|
433
|
+
var _a;
|
|
434
|
+
var aborted = (_a = appleDownstreamAbortController === null || appleDownstreamAbortController === void 0 ? void 0 : appleDownstreamAbortController.signal.aborted) !== null && _a !== void 0 ? _a : false;
|
|
435
|
+
appleDownstreamTask = null;
|
|
436
|
+
appleDownstreamAbortController = null;
|
|
437
|
+
var wasConnected = appleDownstreamConnected;
|
|
438
|
+
appleDownstreamConnected = false;
|
|
439
|
+
resetHandshakeState("Apple downstream closed", wasConnected);
|
|
440
|
+
if (!aborted)
|
|
441
|
+
scheduleAppleDownstreamReconnect("stream closed");
|
|
442
|
+
});
|
|
443
|
+
}
|
|
444
|
+
function getMessagePort() {
|
|
445
|
+
var _a, _b;
|
|
446
|
+
if (messagePort)
|
|
447
|
+
return Promise.resolve(messagePort);
|
|
448
|
+
if (portInitState.promise)
|
|
449
|
+
return portInitState.promise;
|
|
450
|
+
var timeoutMs = 5000;
|
|
451
|
+
installMessagePortInitListener();
|
|
452
|
+
portInitState.promise = new Promise(function (resolve, reject) {
|
|
453
|
+
portInitState.resolve = function (port) {
|
|
454
|
+
cleanupPortInit();
|
|
455
|
+
resolve(port);
|
|
456
|
+
};
|
|
457
|
+
portInitState.reject = function (err) {
|
|
458
|
+
cleanupPortInit();
|
|
459
|
+
reject(err);
|
|
460
|
+
};
|
|
461
|
+
portInitState.timer = window.setTimeout(function () {
|
|
462
|
+
var _a;
|
|
463
|
+
(_a = portInitState.reject) === null || _a === void 0 ? void 0 : _a.call(portInitState, new Error("MessagePort init timed out after ".concat(timeoutMs, "ms")));
|
|
464
|
+
}, timeoutMs);
|
|
465
|
+
});
|
|
466
|
+
try {
|
|
467
|
+
(_a = window.LingXiaProxy) === null || _a === void 0 ? void 0 : _a.getPort("LingXiaPort");
|
|
468
|
+
}
|
|
469
|
+
catch (e) {
|
|
470
|
+
(_b = portInitState.reject) === null || _b === void 0 ? void 0 : _b.call(portInitState, e);
|
|
471
|
+
}
|
|
472
|
+
return portInitState.promise;
|
|
473
|
+
}
|
|
474
|
+
function postToNative(message) {
|
|
475
|
+
var _a, _b, _c;
|
|
476
|
+
var kind = message.kind;
|
|
477
|
+
if (kind === "req" || kind === "notify")
|
|
478
|
+
log("postToNative: ".concat(kind, " ").concat(message.method));
|
|
479
|
+
if (isDebugEnabled("proto"))
|
|
480
|
+
console.log("→", JSON.stringify(message, null, 2));
|
|
481
|
+
try {
|
|
482
|
+
if (communicationMethod === "webkit") {
|
|
483
|
+
(_b = (_a = window.webkit) === null || _a === void 0 ? void 0 : _a.messageHandlers[NATIVE_HANDLER_NAME]) === null || _b === void 0 ? void 0 : _b.postMessage(message);
|
|
484
|
+
return;
|
|
485
|
+
}
|
|
486
|
+
var messageString = stringifyForNative(message);
|
|
487
|
+
if (communicationMethod === MESSAGE_PORT_TYPE && messagePort) {
|
|
488
|
+
messagePort.postMessage(messageString);
|
|
489
|
+
return;
|
|
490
|
+
}
|
|
491
|
+
if (communicationMethod === JS_INTERFACE_TYPE &&
|
|
492
|
+
((_c = window.LingXiaProxy) === null || _c === void 0 ? void 0 : _c.postMessage)) {
|
|
493
|
+
window.LingXiaProxy.postMessage(messageString);
|
|
494
|
+
return;
|
|
495
|
+
}
|
|
496
|
+
warn("Transport not ready");
|
|
497
|
+
}
|
|
498
|
+
catch (e) {
|
|
499
|
+
error("Send error:", e);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
// Handshake state
|
|
503
|
+
var handshakeSessionId = null;
|
|
504
|
+
var handshakeDone = false;
|
|
505
|
+
var helloSent = false;
|
|
506
|
+
var handshakeRetryCount = 0;
|
|
507
|
+
var handshakeTimer = null;
|
|
508
|
+
// Host method schema — populated from handshake `Ready` message.
|
|
509
|
+
// Maps "namespace.method" → "call" | "stream".
|
|
510
|
+
var hostMethodKinds = {};
|
|
511
|
+
// Request tracking
|
|
512
|
+
var requestCounter = 0;
|
|
513
|
+
function createListenerBuckets() {
|
|
514
|
+
return {
|
|
515
|
+
data: new Set(),
|
|
516
|
+
end: new Set(),
|
|
517
|
+
error: new Set(),
|
|
518
|
+
close: new Set(),
|
|
519
|
+
};
|
|
520
|
+
}
|
|
521
|
+
function createStreamHandle(id, cancelFn) {
|
|
522
|
+
var _a;
|
|
523
|
+
var listeners = createListenerBuckets();
|
|
524
|
+
var done = false;
|
|
525
|
+
var resolveResult = function () { };
|
|
526
|
+
var rejectResult = function () { };
|
|
527
|
+
var pendingData = [];
|
|
528
|
+
var pendingReads = [];
|
|
529
|
+
var result = new Promise(function (resolve, reject) {
|
|
530
|
+
resolveResult = resolve;
|
|
531
|
+
rejectResult = reject;
|
|
532
|
+
});
|
|
533
|
+
var handle = (_a = {
|
|
534
|
+
id: id,
|
|
535
|
+
result: result,
|
|
536
|
+
on: function (event, listener) {
|
|
537
|
+
if (event === "data")
|
|
538
|
+
listeners.data.add(listener);
|
|
539
|
+
if (event === "end")
|
|
540
|
+
listeners.end.add(listener);
|
|
541
|
+
if (event === "error")
|
|
542
|
+
listeners.error.add(listener);
|
|
543
|
+
return this;
|
|
544
|
+
}
|
|
545
|
+
},
|
|
546
|
+
_a[Symbol.asyncIterator] = function () {
|
|
547
|
+
return {
|
|
548
|
+
next: function () {
|
|
549
|
+
if (pendingData.length > 0) {
|
|
550
|
+
return Promise.resolve({
|
|
551
|
+
done: false,
|
|
552
|
+
value: pendingData.shift(),
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
if (done) {
|
|
556
|
+
return result.then(function (finalValue) { return ({ done: true, value: finalValue }); }, function (err) { return Promise.reject(err); });
|
|
557
|
+
}
|
|
558
|
+
return new Promise(function (resolve, reject) {
|
|
559
|
+
pendingReads.push({ resolve: resolve, reject: reject });
|
|
560
|
+
});
|
|
561
|
+
},
|
|
562
|
+
};
|
|
563
|
+
},
|
|
564
|
+
_a.cancel = function () {
|
|
565
|
+
if (done)
|
|
566
|
+
return;
|
|
567
|
+
cancelFn();
|
|
568
|
+
},
|
|
569
|
+
_a._emitData = function (payload) {
|
|
570
|
+
var e_6, _a;
|
|
571
|
+
if (done)
|
|
572
|
+
return;
|
|
573
|
+
if (pendingReads.length > 0) {
|
|
574
|
+
pendingReads.shift().resolve({ done: false, value: payload });
|
|
575
|
+
}
|
|
576
|
+
else {
|
|
577
|
+
pendingData.push(payload);
|
|
578
|
+
}
|
|
579
|
+
try {
|
|
580
|
+
for (var _b = __values(listeners.data), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
581
|
+
var listener = _c.value;
|
|
582
|
+
try {
|
|
583
|
+
listener(payload);
|
|
584
|
+
}
|
|
585
|
+
catch (e) {
|
|
586
|
+
warn("Stream data listener failed:", e);
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
catch (e_6_1) { e_6 = { error: e_6_1 }; }
|
|
591
|
+
finally {
|
|
592
|
+
try {
|
|
593
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
594
|
+
}
|
|
595
|
+
finally { if (e_6) throw e_6.error; }
|
|
596
|
+
}
|
|
597
|
+
},
|
|
598
|
+
_a._resolve = function (resultValue) {
|
|
599
|
+
var e_7, _a;
|
|
600
|
+
if (done)
|
|
601
|
+
return;
|
|
602
|
+
done = true;
|
|
603
|
+
resolveResult(resultValue);
|
|
604
|
+
while (pendingReads.length > 0) {
|
|
605
|
+
pendingReads.shift().resolve({ done: true, value: resultValue });
|
|
606
|
+
}
|
|
607
|
+
try {
|
|
608
|
+
for (var _b = __values(listeners.end), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
609
|
+
var listener = _c.value;
|
|
610
|
+
try {
|
|
611
|
+
listener(resultValue);
|
|
612
|
+
}
|
|
613
|
+
catch (e) {
|
|
614
|
+
warn("Stream end listener failed:", e);
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
catch (e_7_1) { e_7 = { error: e_7_1 }; }
|
|
619
|
+
finally {
|
|
620
|
+
try {
|
|
621
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
622
|
+
}
|
|
623
|
+
finally { if (e_7) throw e_7.error; }
|
|
624
|
+
}
|
|
625
|
+
},
|
|
626
|
+
_a._reject = function (err) {
|
|
627
|
+
var e_8, _a;
|
|
628
|
+
if (done)
|
|
629
|
+
return;
|
|
630
|
+
done = true;
|
|
631
|
+
rejectResult(err);
|
|
632
|
+
while (pendingReads.length > 0) {
|
|
633
|
+
pendingReads.shift().reject(err);
|
|
634
|
+
}
|
|
635
|
+
try {
|
|
636
|
+
for (var _b = __values(listeners.error), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
637
|
+
var listener = _c.value;
|
|
638
|
+
try {
|
|
639
|
+
listener(err);
|
|
640
|
+
}
|
|
641
|
+
catch (e) {
|
|
642
|
+
warn("Stream error listener failed:", e);
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
catch (e_8_1) { e_8 = { error: e_8_1 }; }
|
|
647
|
+
finally {
|
|
648
|
+
try {
|
|
649
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
650
|
+
}
|
|
651
|
+
finally { if (e_8) throw e_8.error; }
|
|
652
|
+
}
|
|
653
|
+
},
|
|
654
|
+
_a);
|
|
655
|
+
return handle;
|
|
656
|
+
}
|
|
657
|
+
function createChannel(id, sendFn, closeFn) {
|
|
658
|
+
var _a;
|
|
659
|
+
var listeners = createListenerBuckets();
|
|
660
|
+
var open = false;
|
|
661
|
+
var outboundSeq = 0;
|
|
662
|
+
var closed = false;
|
|
663
|
+
var pendingData = [];
|
|
664
|
+
var pendingReads = [];
|
|
665
|
+
var channel = (_a = {
|
|
666
|
+
id: id,
|
|
667
|
+
send: function (payload) {
|
|
668
|
+
if (!open) {
|
|
669
|
+
channel._reject({
|
|
670
|
+
code: BRIDGE_ERROR.STREAM_CLOSED,
|
|
671
|
+
message: "Channel '".concat(id, "' is closed"),
|
|
672
|
+
});
|
|
673
|
+
return;
|
|
674
|
+
}
|
|
675
|
+
sendFn(payload, outboundSeq++);
|
|
676
|
+
},
|
|
677
|
+
on: function (event, listener) {
|
|
678
|
+
if (event === "data")
|
|
679
|
+
listeners.data.add(listener);
|
|
680
|
+
if (event === "close")
|
|
681
|
+
listeners.close.add(listener);
|
|
682
|
+
if (event === "error")
|
|
683
|
+
listeners.error.add(listener);
|
|
684
|
+
return this;
|
|
685
|
+
}
|
|
686
|
+
},
|
|
687
|
+
_a[Symbol.asyncIterator] = function () {
|
|
688
|
+
return {
|
|
689
|
+
next: function () {
|
|
690
|
+
if (pendingData.length > 0) {
|
|
691
|
+
return Promise.resolve({
|
|
692
|
+
done: false,
|
|
693
|
+
value: pendingData.shift(),
|
|
694
|
+
});
|
|
695
|
+
}
|
|
696
|
+
if (closed) {
|
|
697
|
+
return Promise.resolve({ done: true, value: undefined });
|
|
698
|
+
}
|
|
699
|
+
return new Promise(function (resolve, reject) {
|
|
700
|
+
pendingReads.push({ resolve: resolve, reject: reject });
|
|
701
|
+
});
|
|
702
|
+
},
|
|
703
|
+
};
|
|
704
|
+
},
|
|
705
|
+
_a.close = function (code, reason) {
|
|
706
|
+
if (!open)
|
|
707
|
+
return;
|
|
708
|
+
open = false;
|
|
709
|
+
closed = true;
|
|
710
|
+
closeFn(code, reason);
|
|
711
|
+
channel._emitClose(code, reason);
|
|
712
|
+
},
|
|
713
|
+
_a._emitData = function (payload) {
|
|
714
|
+
var e_9, _a;
|
|
715
|
+
if (!open)
|
|
716
|
+
return;
|
|
717
|
+
if (pendingReads.length > 0) {
|
|
718
|
+
pendingReads.shift().resolve({ done: false, value: payload });
|
|
719
|
+
}
|
|
720
|
+
else {
|
|
721
|
+
pendingData.push(payload);
|
|
722
|
+
}
|
|
723
|
+
try {
|
|
724
|
+
for (var _b = __values(listeners.data), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
725
|
+
var listener = _c.value;
|
|
726
|
+
try {
|
|
727
|
+
listener(payload);
|
|
728
|
+
}
|
|
729
|
+
catch (e) {
|
|
730
|
+
warn("Channel listener failed:", e);
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
catch (e_9_1) { e_9 = { error: e_9_1 }; }
|
|
735
|
+
finally {
|
|
736
|
+
try {
|
|
737
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
738
|
+
}
|
|
739
|
+
finally { if (e_9) throw e_9.error; }
|
|
740
|
+
}
|
|
741
|
+
},
|
|
742
|
+
_a._emitClose = function (code, reason) {
|
|
743
|
+
var e_10, _a;
|
|
744
|
+
closed = true;
|
|
745
|
+
while (pendingReads.length > 0) {
|
|
746
|
+
pendingReads.shift().resolve({ done: true, value: undefined });
|
|
747
|
+
}
|
|
748
|
+
try {
|
|
749
|
+
for (var _b = __values(listeners.close), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
750
|
+
var listener = _c.value;
|
|
751
|
+
try {
|
|
752
|
+
listener(code, reason);
|
|
753
|
+
}
|
|
754
|
+
catch (e) {
|
|
755
|
+
warn("Channel close listener failed:", e);
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
catch (e_10_1) { e_10 = { error: e_10_1 }; }
|
|
760
|
+
finally {
|
|
761
|
+
try {
|
|
762
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
763
|
+
}
|
|
764
|
+
finally { if (e_10) throw e_10.error; }
|
|
765
|
+
}
|
|
766
|
+
},
|
|
767
|
+
_a._reject = function (err) {
|
|
768
|
+
var e_11, _a;
|
|
769
|
+
closed = true;
|
|
770
|
+
while (pendingReads.length > 0) {
|
|
771
|
+
pendingReads.shift().reject(err);
|
|
772
|
+
}
|
|
773
|
+
try {
|
|
774
|
+
for (var _b = __values(listeners.error), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
775
|
+
var listener = _c.value;
|
|
776
|
+
try {
|
|
777
|
+
listener(err);
|
|
778
|
+
}
|
|
779
|
+
catch (e) {
|
|
780
|
+
warn("Channel error listener failed:", e);
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
catch (e_11_1) { e_11 = { error: e_11_1 }; }
|
|
785
|
+
finally {
|
|
786
|
+
try {
|
|
787
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
788
|
+
}
|
|
789
|
+
finally { if (e_11) throw e_11.error; }
|
|
790
|
+
}
|
|
791
|
+
},
|
|
792
|
+
_a._markOpen = function () {
|
|
793
|
+
open = true;
|
|
794
|
+
closed = false;
|
|
795
|
+
},
|
|
796
|
+
_a._isOpen = function () {
|
|
797
|
+
return open;
|
|
798
|
+
},
|
|
799
|
+
_a._nextSeq = function () {
|
|
800
|
+
return outboundSeq++;
|
|
801
|
+
},
|
|
802
|
+
_a);
|
|
803
|
+
return channel;
|
|
804
|
+
}
|
|
805
|
+
var pendingReq = new Map();
|
|
806
|
+
var pendingChannels = new Map();
|
|
807
|
+
var activeChannels = new Map();
|
|
808
|
+
var outbox = [];
|
|
809
|
+
// State sync
|
|
810
|
+
var stateRev = -1;
|
|
811
|
+
var pageData = {};
|
|
812
|
+
var dataSubscribers = new Set();
|
|
813
|
+
var subscriberInitStatus = new WeakMap();
|
|
814
|
+
// Logic→View method handlers (for incoming req from native side)
|
|
815
|
+
var viewMethodHandlers = new Map();
|
|
816
|
+
export function registerViewMethodHandler(method, handler) {
|
|
817
|
+
viewMethodHandlers.set(method, handler);
|
|
818
|
+
}
|
|
819
|
+
function inferCap(method) {
|
|
820
|
+
if (method.startsWith("host."))
|
|
821
|
+
return "host";
|
|
822
|
+
var i = method.indexOf(".");
|
|
823
|
+
return i > 0 ? method.slice(0, i) : "page";
|
|
824
|
+
}
|
|
825
|
+
function normalizeParams(params) {
|
|
826
|
+
if (params === null || params === undefined)
|
|
827
|
+
return undefined;
|
|
828
|
+
return params;
|
|
829
|
+
}
|
|
830
|
+
function isTransportReady() {
|
|
831
|
+
if (communicationMethod === MESSAGE_PORT_TYPE)
|
|
832
|
+
return !!messagePort;
|
|
833
|
+
if (useAppleDownstreamTransport())
|
|
834
|
+
return appleDownstreamConnected;
|
|
835
|
+
return (communicationMethod === "webkit" ||
|
|
836
|
+
communicationMethod === JS_INTERFACE_TYPE);
|
|
837
|
+
}
|
|
838
|
+
function canSendAppMessages() {
|
|
839
|
+
return isTransportReady() && handshakeDone;
|
|
840
|
+
}
|
|
841
|
+
function rejectPendingRequest(reqId, err) {
|
|
842
|
+
var _a;
|
|
843
|
+
var info = pendingReq.get(reqId);
|
|
844
|
+
if (info) {
|
|
845
|
+
pendingReq.delete(reqId);
|
|
846
|
+
if (info.timerId !== null)
|
|
847
|
+
clearTimeout(info.timerId);
|
|
848
|
+
var normalized = toBridgeError(err);
|
|
849
|
+
if (info.mode === "stream" && info.stream) {
|
|
850
|
+
info.stream._reject(normalized);
|
|
851
|
+
return;
|
|
852
|
+
}
|
|
853
|
+
(_a = info.reject) === null || _a === void 0 ? void 0 : _a.call(info, normalized);
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
function rejectPendingChannel(id, err) {
|
|
857
|
+
var pending = pendingChannels.get(id);
|
|
858
|
+
if (!pending)
|
|
859
|
+
return;
|
|
860
|
+
pendingChannels.delete(id);
|
|
861
|
+
if (pending.timerId !== null)
|
|
862
|
+
clearTimeout(pending.timerId);
|
|
863
|
+
var normalized = toBridgeError(err);
|
|
864
|
+
pending.channel._reject(normalized);
|
|
865
|
+
pending.reject(normalized);
|
|
866
|
+
}
|
|
867
|
+
function rejectPendingOperation(id, err) {
|
|
868
|
+
if (pendingReq.has(id)) {
|
|
869
|
+
rejectPendingRequest(id, err);
|
|
870
|
+
return;
|
|
871
|
+
}
|
|
872
|
+
if (pendingChannels.has(id)) {
|
|
873
|
+
rejectPendingChannel(id, err);
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
function armRequestTimer(reqId) {
|
|
877
|
+
var info = pendingReq.get(reqId);
|
|
878
|
+
if (!info)
|
|
879
|
+
return;
|
|
880
|
+
if (!Number.isFinite(info.timeoutMs) || info.timeoutMs <= 0) {
|
|
881
|
+
if (info.timerId !== null) {
|
|
882
|
+
clearTimeout(info.timerId);
|
|
883
|
+
info.timerId = null;
|
|
884
|
+
}
|
|
885
|
+
return;
|
|
886
|
+
}
|
|
887
|
+
if (info.timerId !== null)
|
|
888
|
+
clearTimeout(info.timerId);
|
|
889
|
+
info.timerId = setTimeout(function () {
|
|
890
|
+
if (!pendingReq.has(reqId))
|
|
891
|
+
return;
|
|
892
|
+
rejectPendingRequest(reqId, {
|
|
893
|
+
code: BRIDGE_ERROR.TIMEOUT,
|
|
894
|
+
message: "'".concat(info.method, "' timed out"),
|
|
895
|
+
});
|
|
896
|
+
}, info.timeoutMs);
|
|
897
|
+
}
|
|
898
|
+
function armChannelTimer(id) {
|
|
899
|
+
var pending = pendingChannels.get(id);
|
|
900
|
+
if (!pending)
|
|
901
|
+
return;
|
|
902
|
+
if (pending.timerId !== null)
|
|
903
|
+
clearTimeout(pending.timerId);
|
|
904
|
+
pending.timerId = setTimeout(function () {
|
|
905
|
+
rejectPendingChannel(id, {
|
|
906
|
+
code: BRIDGE_ERROR.TIMEOUT,
|
|
907
|
+
message: "Channel '".concat(pending.topic, "' timed out"),
|
|
908
|
+
});
|
|
909
|
+
}, DEFAULT_TIMEOUT_MS);
|
|
910
|
+
}
|
|
911
|
+
function armPendingOperationTimer(id) {
|
|
912
|
+
if (pendingReq.has(id)) {
|
|
913
|
+
armRequestTimer(id);
|
|
914
|
+
return;
|
|
915
|
+
}
|
|
916
|
+
if (pendingChannels.has(id)) {
|
|
917
|
+
armChannelTimer(id);
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
function removeOutboxByReqId(reqId) {
|
|
921
|
+
var _a;
|
|
922
|
+
for (var i = outbox.length - 1; i >= 0; i--) {
|
|
923
|
+
if (((_a = outbox[i]) === null || _a === void 0 ? void 0 : _a.reqId) === reqId) {
|
|
924
|
+
outbox.splice(i, 1);
|
|
925
|
+
return true;
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
return false;
|
|
929
|
+
}
|
|
930
|
+
function send(msg, reqId) {
|
|
931
|
+
var kind = msg.kind;
|
|
932
|
+
var isHandshake = kind === "hello" || kind === "helloAck" || kind === "ready";
|
|
933
|
+
if (!canSendAppMessages() && !isHandshake) {
|
|
934
|
+
if (outbox.length >= OUTBOX_LIMIT) {
|
|
935
|
+
error("Outbox full");
|
|
936
|
+
if (reqId) {
|
|
937
|
+
rejectPendingOperation(reqId, {
|
|
938
|
+
code: BRIDGE_ERROR.OUTBOX_FULL,
|
|
939
|
+
message: "Bridge outbox is full",
|
|
940
|
+
});
|
|
941
|
+
}
|
|
942
|
+
return;
|
|
943
|
+
}
|
|
944
|
+
outbox.push({ msg: msg, reqId: reqId });
|
|
945
|
+
return;
|
|
946
|
+
}
|
|
947
|
+
if (reqId)
|
|
948
|
+
armPendingOperationTimer(reqId);
|
|
949
|
+
postToNative(msg);
|
|
950
|
+
}
|
|
951
|
+
function flushOutbox() {
|
|
952
|
+
if (!canSendAppMessages())
|
|
953
|
+
return;
|
|
954
|
+
while (outbox.length) {
|
|
955
|
+
var item = outbox.shift();
|
|
956
|
+
if (!item)
|
|
957
|
+
continue;
|
|
958
|
+
if (item.reqId)
|
|
959
|
+
armPendingOperationTimer(item.reqId);
|
|
960
|
+
postToNative(item.msg);
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
function clearHandshakeTimer() {
|
|
964
|
+
if (handshakeTimer !== null) {
|
|
965
|
+
clearTimeout(handshakeTimer);
|
|
966
|
+
handshakeTimer = null;
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
function startHandshake() {
|
|
970
|
+
if (handshakeDone)
|
|
971
|
+
return;
|
|
972
|
+
if (!isTransportReady())
|
|
973
|
+
return;
|
|
974
|
+
clearHandshakeTimer();
|
|
975
|
+
var hello = {
|
|
976
|
+
v: 2,
|
|
977
|
+
kind: "hello",
|
|
978
|
+
nonce: BRIDGE_CONFIG.nonce || "",
|
|
979
|
+
role: "view",
|
|
980
|
+
protocolsSupported: [2],
|
|
981
|
+
};
|
|
982
|
+
helloSent = true;
|
|
983
|
+
postToNative(hello);
|
|
984
|
+
handshakeTimer = setTimeout(function () {
|
|
985
|
+
var e_12, _a;
|
|
986
|
+
if (handshakeDone)
|
|
987
|
+
return;
|
|
988
|
+
handshakeRetryCount++;
|
|
989
|
+
if (handshakeRetryCount < HANDSHAKE_MAX_RETRIES) {
|
|
990
|
+
warn("Handshake timeout (".concat(handshakeRetryCount, "/").concat(HANDSHAKE_MAX_RETRIES, "), retrying..."));
|
|
991
|
+
helloSent = false;
|
|
992
|
+
startHandshake();
|
|
993
|
+
}
|
|
994
|
+
else {
|
|
995
|
+
error("Handshake failed");
|
|
996
|
+
clearHandshakeTimer();
|
|
997
|
+
helloSent = false;
|
|
998
|
+
handshakeRetryCount = 0;
|
|
999
|
+
while (outbox.length) {
|
|
1000
|
+
var item = outbox.shift();
|
|
1001
|
+
if (item === null || item === void 0 ? void 0 : item.reqId) {
|
|
1002
|
+
rejectPendingOperation(item.reqId, {
|
|
1003
|
+
code: BRIDGE_ERROR.HANDSHAKE_FAILED,
|
|
1004
|
+
message: "Bridge handshake failed",
|
|
1005
|
+
});
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
try {
|
|
1009
|
+
for (var _b = __values(Array.from(pendingChannels.keys())), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
1010
|
+
var id = _c.value;
|
|
1011
|
+
rejectPendingChannel(id, {
|
|
1012
|
+
code: BRIDGE_ERROR.HANDSHAKE_FAILED,
|
|
1013
|
+
message: "Bridge handshake failed",
|
|
1014
|
+
});
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
catch (e_12_1) { e_12 = { error: e_12_1 }; }
|
|
1018
|
+
finally {
|
|
1019
|
+
try {
|
|
1020
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
1021
|
+
}
|
|
1022
|
+
finally { if (e_12) throw e_12.error; }
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
}, HANDSHAKE_TIMEOUT_MS);
|
|
1026
|
+
}
|
|
1027
|
+
function parseIncoming(msg) {
|
|
1028
|
+
if (!msg || typeof msg !== "object")
|
|
1029
|
+
return null;
|
|
1030
|
+
var v = msg.v;
|
|
1031
|
+
var kind = msg.kind;
|
|
1032
|
+
if (v !== 2 || typeof kind !== "string")
|
|
1033
|
+
return null;
|
|
1034
|
+
return msg;
|
|
1035
|
+
}
|
|
1036
|
+
// JSON Patch
|
|
1037
|
+
function jsonPointerUnescape(seg) {
|
|
1038
|
+
return seg.replace(/~1/g, "/").replace(/~0/g, "~");
|
|
1039
|
+
}
|
|
1040
|
+
function parseJsonPointer(path) {
|
|
1041
|
+
if (path === "")
|
|
1042
|
+
return [];
|
|
1043
|
+
if (!path.startsWith("/"))
|
|
1044
|
+
throw new Error("Invalid JSON pointer: ".concat(path));
|
|
1045
|
+
return path.split("/").slice(1).map(jsonPointerUnescape);
|
|
1046
|
+
}
|
|
1047
|
+
function getContainerAndKey(root, pointer, autoCreate) {
|
|
1048
|
+
if (autoCreate === void 0) { autoCreate = false; }
|
|
1049
|
+
var segments = parseJsonPointer(pointer);
|
|
1050
|
+
if (segments.length === 0)
|
|
1051
|
+
return { container: { $root: root }, key: "$root" };
|
|
1052
|
+
var current = root;
|
|
1053
|
+
for (var i = 0; i < segments.length - 1; i++) {
|
|
1054
|
+
var seg = segments[i];
|
|
1055
|
+
if (Array.isArray(current)) {
|
|
1056
|
+
current = current[Number(seg)];
|
|
1057
|
+
}
|
|
1058
|
+
else if (current && typeof current === "object") {
|
|
1059
|
+
var obj = current;
|
|
1060
|
+
if (autoCreate && obj[seg] === undefined) {
|
|
1061
|
+
var nextSeg = segments[i + 1];
|
|
1062
|
+
obj[seg] = nextSeg && /^\d+$/.test(nextSeg) ? [] : {};
|
|
1063
|
+
}
|
|
1064
|
+
current = obj[seg];
|
|
1065
|
+
}
|
|
1066
|
+
else {
|
|
1067
|
+
throw new Error("Invalid container at ".concat(seg));
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
return { container: current, key: segments[segments.length - 1] };
|
|
1071
|
+
}
|
|
1072
|
+
function applyJsonPatch(target, ops) {
|
|
1073
|
+
var e_13, _a, e_14, _b;
|
|
1074
|
+
try {
|
|
1075
|
+
for (var ops_1 = __values(ops), ops_1_1 = ops_1.next(); !ops_1_1.done; ops_1_1 = ops_1.next()) {
|
|
1076
|
+
var op = ops_1_1.value;
|
|
1077
|
+
var autoCreate = op.op === "add" || op.op === "replace";
|
|
1078
|
+
var _c = getContainerAndKey(target, op.path, autoCreate), container = _c.container, key = _c.key;
|
|
1079
|
+
if (key === "$root") {
|
|
1080
|
+
try {
|
|
1081
|
+
for (var _d = (e_14 = void 0, __values(Object.keys(target))), _e = _d.next(); !_e.done; _e = _d.next()) {
|
|
1082
|
+
var k = _e.value;
|
|
1083
|
+
delete target[k];
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
catch (e_14_1) { e_14 = { error: e_14_1 }; }
|
|
1087
|
+
finally {
|
|
1088
|
+
try {
|
|
1089
|
+
if (_e && !_e.done && (_b = _d.return)) _b.call(_d);
|
|
1090
|
+
}
|
|
1091
|
+
finally { if (e_14) throw e_14.error; }
|
|
1092
|
+
}
|
|
1093
|
+
if (op.op !== "remove") {
|
|
1094
|
+
var v = op.value;
|
|
1095
|
+
if (v && typeof v === "object")
|
|
1096
|
+
Object.assign(target, v);
|
|
1097
|
+
}
|
|
1098
|
+
continue;
|
|
1099
|
+
}
|
|
1100
|
+
if (Array.isArray(container)) {
|
|
1101
|
+
var idx = key === "-" ? container.length : Number(key);
|
|
1102
|
+
if (!Number.isFinite(idx) || idx < 0)
|
|
1103
|
+
throw new Error("Invalid index");
|
|
1104
|
+
if (op.op === "remove")
|
|
1105
|
+
container.splice(idx, 1);
|
|
1106
|
+
else if (op.op === "add")
|
|
1107
|
+
container.splice(idx, 0, op.value);
|
|
1108
|
+
else if (op.op === "replace")
|
|
1109
|
+
container[idx] = op.value;
|
|
1110
|
+
continue;
|
|
1111
|
+
}
|
|
1112
|
+
if (!container || typeof container !== "object")
|
|
1113
|
+
throw new Error("Invalid container");
|
|
1114
|
+
var obj = container;
|
|
1115
|
+
if (op.op === "remove")
|
|
1116
|
+
delete obj[key];
|
|
1117
|
+
else
|
|
1118
|
+
obj[key] = op.value;
|
|
1119
|
+
}
|
|
1120
|
+
}
|
|
1121
|
+
catch (e_13_1) { e_13 = { error: e_13_1 }; }
|
|
1122
|
+
finally {
|
|
1123
|
+
try {
|
|
1124
|
+
if (ops_1_1 && !ops_1_1.done && (_a = ops_1.return)) _a.call(ops_1);
|
|
1125
|
+
}
|
|
1126
|
+
finally { if (e_13) throw e_13.error; }
|
|
1127
|
+
}
|
|
1128
|
+
}
|
|
1129
|
+
function notifyStateSubscribers(initial) {
|
|
1130
|
+
dataSubscribers.forEach(function (listener) {
|
|
1131
|
+
try {
|
|
1132
|
+
if (!subscriberInitStatus.has(listener)) {
|
|
1133
|
+
subscriberInitStatus.set(listener, true);
|
|
1134
|
+
listener(deepCopy(pageData), { rev: stateRev, initial: true });
|
|
1135
|
+
return;
|
|
1136
|
+
}
|
|
1137
|
+
listener(deepCopy(pageData), { rev: stateRev, initial: initial });
|
|
1138
|
+
}
|
|
1139
|
+
catch (e) {
|
|
1140
|
+
warn("Subscriber error:", e);
|
|
1141
|
+
}
|
|
1142
|
+
});
|
|
1143
|
+
}
|
|
1144
|
+
function subscribeState(callback) {
|
|
1145
|
+
if (typeof callback !== "function")
|
|
1146
|
+
return function () { };
|
|
1147
|
+
dataSubscribers.add(callback);
|
|
1148
|
+
if (stateRev >= 0) {
|
|
1149
|
+
subscriberInitStatus.set(callback, true);
|
|
1150
|
+
try {
|
|
1151
|
+
callback(deepCopy(pageData), { rev: stateRev, initial: true });
|
|
1152
|
+
}
|
|
1153
|
+
catch (e) {
|
|
1154
|
+
error("Callback error:", e);
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1157
|
+
return function () {
|
|
1158
|
+
dataSubscribers.delete(callback);
|
|
1159
|
+
subscriberInitStatus.delete(callback);
|
|
1160
|
+
};
|
|
1161
|
+
}
|
|
1162
|
+
function requestStateRecovery(scope) {
|
|
1163
|
+
rawBridge.call("state.getSnapshot", { scope: scope }).catch(function () { });
|
|
1164
|
+
}
|
|
1165
|
+
function applySnapshotFromResult(result) {
|
|
1166
|
+
if (!result || typeof result !== "object")
|
|
1167
|
+
return false;
|
|
1168
|
+
var obj = result;
|
|
1169
|
+
if (typeof obj.rev !== "number" || !Number.isFinite(obj.rev))
|
|
1170
|
+
return false;
|
|
1171
|
+
if (!obj.state || typeof obj.state !== "object")
|
|
1172
|
+
return false;
|
|
1173
|
+
pageData = obj.state;
|
|
1174
|
+
stateRev = obj.rev;
|
|
1175
|
+
if (isDebugEnabled("data")) {
|
|
1176
|
+
console.group("[LX] snapshot(res)");
|
|
1177
|
+
console.log("rev:", stateRev, "state:", deepCopy(pageData));
|
|
1178
|
+
console.groupEnd();
|
|
1179
|
+
}
|
|
1180
|
+
notifyStateSubscribers(true);
|
|
1181
|
+
return true;
|
|
1182
|
+
}
|
|
1183
|
+
function handleIncomingMessage(msg) {
|
|
1184
|
+
var e_15, _a;
|
|
1185
|
+
var _b, _c;
|
|
1186
|
+
// Handle native component events (from Android NativeBridge.sendEventToView)
|
|
1187
|
+
if (msg && typeof msg === "object") {
|
|
1188
|
+
var obj = msg;
|
|
1189
|
+
if (obj.type === "event" && obj.name === "nativecomponent" && obj.payload) {
|
|
1190
|
+
var payload = obj.payload;
|
|
1191
|
+
var componentId = payload.id ||
|
|
1192
|
+
payload.componentId;
|
|
1193
|
+
if (typeof componentId === "string") {
|
|
1194
|
+
var handler = nativeComponentHandlers.get(componentId);
|
|
1195
|
+
if (handler) {
|
|
1196
|
+
try {
|
|
1197
|
+
handler(payload);
|
|
1198
|
+
}
|
|
1199
|
+
catch (e) {
|
|
1200
|
+
error("NC handler error:", e);
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
return;
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
var message = parseIncoming(msg);
|
|
1208
|
+
if (!message) {
|
|
1209
|
+
warn("Invalid V2 message:", msg);
|
|
1210
|
+
return;
|
|
1211
|
+
}
|
|
1212
|
+
switch (message.kind) {
|
|
1213
|
+
case "helloAck":
|
|
1214
|
+
handshakeSessionId = message.sessionId;
|
|
1215
|
+
return;
|
|
1216
|
+
case "ready":
|
|
1217
|
+
if (handshakeSessionId && message.sessionId !== handshakeSessionId) {
|
|
1218
|
+
warn("sessionId mismatch");
|
|
1219
|
+
return;
|
|
1220
|
+
}
|
|
1221
|
+
clearHandshakeTimer();
|
|
1222
|
+
handshakeDone = true;
|
|
1223
|
+
handshakeRetryCount = 0;
|
|
1224
|
+
if (message.hostMethods) {
|
|
1225
|
+
try {
|
|
1226
|
+
for (var _d = __values(Object.entries(message.hostMethods)), _e = _d.next(); !_e.done; _e = _d.next()) {
|
|
1227
|
+
var _f = __read(_e.value, 2), k = _f[0], v = _f[1];
|
|
1228
|
+
hostMethodKinds[k] = v;
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
catch (e_15_1) { e_15 = { error: e_15_1 }; }
|
|
1232
|
+
finally {
|
|
1233
|
+
try {
|
|
1234
|
+
if (_e && !_e.done && (_a = _d.return)) _a.call(_d);
|
|
1235
|
+
}
|
|
1236
|
+
finally { if (e_15) throw e_15.error; }
|
|
1237
|
+
}
|
|
1238
|
+
}
|
|
1239
|
+
if (isDebugEnabled("proto"))
|
|
1240
|
+
log("Handshake complete, hostMethods:", Object.keys(hostMethodKinds).length);
|
|
1241
|
+
flushOutbox();
|
|
1242
|
+
return;
|
|
1243
|
+
case "res": {
|
|
1244
|
+
var info = pendingReq.get(message.id);
|
|
1245
|
+
if (!info)
|
|
1246
|
+
return;
|
|
1247
|
+
pendingReq.delete(message.id);
|
|
1248
|
+
if (info.timerId !== null)
|
|
1249
|
+
clearTimeout(info.timerId);
|
|
1250
|
+
if (message.ok) {
|
|
1251
|
+
if (info.method === "state.getSnapshot") {
|
|
1252
|
+
if (!applySnapshotFromResult(message.result)) {
|
|
1253
|
+
warn("Invalid state.getSnapshot result");
|
|
1254
|
+
}
|
|
1255
|
+
}
|
|
1256
|
+
if (info.mode === "stream" && info.stream) {
|
|
1257
|
+
info.stream._resolve(message.result);
|
|
1258
|
+
return;
|
|
1259
|
+
}
|
|
1260
|
+
(_b = info.resolve) === null || _b === void 0 ? void 0 : _b.call(info, message.result);
|
|
1261
|
+
}
|
|
1262
|
+
else {
|
|
1263
|
+
var err = toBridgeError(message.error);
|
|
1264
|
+
if (info.mode === "stream" && info.stream) {
|
|
1265
|
+
info.stream._reject(err);
|
|
1266
|
+
return;
|
|
1267
|
+
}
|
|
1268
|
+
(_c = info.reject) === null || _c === void 0 ? void 0 : _c.call(info, err);
|
|
1269
|
+
}
|
|
1270
|
+
return;
|
|
1271
|
+
}
|
|
1272
|
+
case "event": {
|
|
1273
|
+
if (pendingReq.has(message.id)) {
|
|
1274
|
+
var req = pendingReq.get(message.id);
|
|
1275
|
+
if ((req === null || req === void 0 ? void 0 : req.mode) === "stream" && req.stream) {
|
|
1276
|
+
armRequestTimer(message.id);
|
|
1277
|
+
req.stream._emitData(message.payload);
|
|
1278
|
+
}
|
|
1279
|
+
else {
|
|
1280
|
+
warn("Received event for non-stream request '".concat(message.id, "'"));
|
|
1281
|
+
}
|
|
1282
|
+
return;
|
|
1283
|
+
}
|
|
1284
|
+
return;
|
|
1285
|
+
}
|
|
1286
|
+
case "state.snapshot":
|
|
1287
|
+
pageData = message.state || {};
|
|
1288
|
+
stateRev = message.rev;
|
|
1289
|
+
if (isDebugEnabled("data")) {
|
|
1290
|
+
console.group("[LX] snapshot");
|
|
1291
|
+
console.log("rev:", stateRev, "state:", deepCopy(pageData));
|
|
1292
|
+
console.groupEnd();
|
|
1293
|
+
}
|
|
1294
|
+
notifyStateSubscribers(true);
|
|
1295
|
+
return;
|
|
1296
|
+
case "state.patch":
|
|
1297
|
+
if (message.baseRev !== stateRev) {
|
|
1298
|
+
warn("baseRev mismatch", { have: stateRev, want: message.baseRev });
|
|
1299
|
+
requestStateRecovery(message.scope);
|
|
1300
|
+
return;
|
|
1301
|
+
}
|
|
1302
|
+
try {
|
|
1303
|
+
applyJsonPatch(pageData, message.ops || []);
|
|
1304
|
+
stateRev = message.rev;
|
|
1305
|
+
}
|
|
1306
|
+
catch (e) {
|
|
1307
|
+
error("Patch failed:", e);
|
|
1308
|
+
requestStateRecovery(message.scope);
|
|
1309
|
+
return;
|
|
1310
|
+
}
|
|
1311
|
+
if (isDebugEnabled("data")) {
|
|
1312
|
+
console.group("[LX] patch");
|
|
1313
|
+
console.log("rev:", stateRev, "ops:", message.ops);
|
|
1314
|
+
console.groupEnd();
|
|
1315
|
+
}
|
|
1316
|
+
notifyStateSubscribers(false);
|
|
1317
|
+
if (message.ack)
|
|
1318
|
+
send({
|
|
1319
|
+
v: 2,
|
|
1320
|
+
kind: "state.ack",
|
|
1321
|
+
scope: message.scope,
|
|
1322
|
+
rev: message.rev,
|
|
1323
|
+
});
|
|
1324
|
+
return;
|
|
1325
|
+
case "ch.ack": {
|
|
1326
|
+
var pendingChannel = pendingChannels.get(message.id);
|
|
1327
|
+
if (!pendingChannel)
|
|
1328
|
+
return;
|
|
1329
|
+
pendingChannels.delete(message.id);
|
|
1330
|
+
if (pendingChannel.timerId !== null)
|
|
1331
|
+
clearTimeout(pendingChannel.timerId);
|
|
1332
|
+
if (message.ok) {
|
|
1333
|
+
pendingChannel.channel._markOpen();
|
|
1334
|
+
activeChannels.set(message.id, pendingChannel.channel);
|
|
1335
|
+
pendingChannel.resolve(pendingChannel.channel);
|
|
1336
|
+
}
|
|
1337
|
+
else {
|
|
1338
|
+
var err = toBridgeError(message.error);
|
|
1339
|
+
pendingChannel.channel._reject(err);
|
|
1340
|
+
pendingChannel.reject(err);
|
|
1341
|
+
}
|
|
1342
|
+
return;
|
|
1343
|
+
}
|
|
1344
|
+
case "ch.data": {
|
|
1345
|
+
var channel_2 = activeChannels.get(message.id);
|
|
1346
|
+
if (!channel_2)
|
|
1347
|
+
return;
|
|
1348
|
+
channel_2._emitData(message.payload);
|
|
1349
|
+
return;
|
|
1350
|
+
}
|
|
1351
|
+
case "ch.close": {
|
|
1352
|
+
var pendingChannel = pendingChannels.get(message.id);
|
|
1353
|
+
if (pendingChannel) {
|
|
1354
|
+
pendingChannels.delete(message.id);
|
|
1355
|
+
pendingChannel.channel._emitClose(message.code, message.reason);
|
|
1356
|
+
return;
|
|
1357
|
+
}
|
|
1358
|
+
var channel_3 = activeChannels.get(message.id);
|
|
1359
|
+
if (!channel_3)
|
|
1360
|
+
return;
|
|
1361
|
+
activeChannels.delete(message.id);
|
|
1362
|
+
channel_3._emitClose(message.code, message.reason);
|
|
1363
|
+
return;
|
|
1364
|
+
}
|
|
1365
|
+
case "req": {
|
|
1366
|
+
var reqMsg_1 = message;
|
|
1367
|
+
var requiredCap = inferCap(reqMsg_1.method);
|
|
1368
|
+
if (!reqMsg_1.cap || reqMsg_1.cap !== requiredCap) {
|
|
1369
|
+
send({
|
|
1370
|
+
v: 2,
|
|
1371
|
+
kind: "res",
|
|
1372
|
+
id: reqMsg_1.id,
|
|
1373
|
+
ok: false,
|
|
1374
|
+
error: {
|
|
1375
|
+
code: BRIDGE_ERROR.CAPABILITY_DENIED,
|
|
1376
|
+
message: "Invalid cap for ".concat(reqMsg_1.method),
|
|
1377
|
+
},
|
|
1378
|
+
});
|
|
1379
|
+
return;
|
|
1380
|
+
}
|
|
1381
|
+
var handler_1 = viewMethodHandlers.get(reqMsg_1.method);
|
|
1382
|
+
if (!handler_1) {
|
|
1383
|
+
send({
|
|
1384
|
+
v: 2,
|
|
1385
|
+
kind: "res",
|
|
1386
|
+
id: reqMsg_1.id,
|
|
1387
|
+
ok: false,
|
|
1388
|
+
error: {
|
|
1389
|
+
code: BRIDGE_ERROR.METHOD_NOT_FOUND,
|
|
1390
|
+
message: "View handler not found: ".concat(reqMsg_1.method),
|
|
1391
|
+
},
|
|
1392
|
+
});
|
|
1393
|
+
return;
|
|
1394
|
+
}
|
|
1395
|
+
Promise.resolve()
|
|
1396
|
+
.then(function () { return handler_1(reqMsg_1.params); })
|
|
1397
|
+
.then(function (result) {
|
|
1398
|
+
send({ v: 2, kind: "res", id: reqMsg_1.id, ok: true, result: result });
|
|
1399
|
+
})
|
|
1400
|
+
.catch(function (err) {
|
|
1401
|
+
send({
|
|
1402
|
+
v: 2,
|
|
1403
|
+
kind: "res",
|
|
1404
|
+
id: reqMsg_1.id,
|
|
1405
|
+
ok: false,
|
|
1406
|
+
error: toBridgeError(err),
|
|
1407
|
+
});
|
|
1408
|
+
});
|
|
1409
|
+
return;
|
|
1410
|
+
}
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
// Native components
|
|
1414
|
+
var nativeComponentHandlers = new Map();
|
|
1415
|
+
var nativeComponentQueue = [];
|
|
1416
|
+
var nativeComponentReady = false;
|
|
1417
|
+
function hasNativeComponentHandler() {
|
|
1418
|
+
var _a, _b, _c;
|
|
1419
|
+
if (typeof window === "undefined")
|
|
1420
|
+
return false;
|
|
1421
|
+
return !!(((_b = (_a = window.webkit) === null || _a === void 0 ? void 0 : _a.messageHandlers) === null || _b === void 0 ? void 0 : _b.NativeComponent) ||
|
|
1422
|
+
((_c = window.NativeComponentBridge) === null || _c === void 0 ? void 0 : _c.postMessage));
|
|
1423
|
+
}
|
|
1424
|
+
function postNativeComponentMessage(message) {
|
|
1425
|
+
var _a, _b, _c;
|
|
1426
|
+
try {
|
|
1427
|
+
if ((_b = (_a = window.webkit) === null || _a === void 0 ? void 0 : _a.messageHandlers) === null || _b === void 0 ? void 0 : _b.NativeComponent) {
|
|
1428
|
+
window.webkit.messageHandlers.NativeComponent.postMessage(message);
|
|
1429
|
+
return;
|
|
1430
|
+
}
|
|
1431
|
+
if ((_c = window.NativeComponentBridge) === null || _c === void 0 ? void 0 : _c.postMessage) {
|
|
1432
|
+
window.NativeComponentBridge.postMessage(stringifyForNative(message));
|
|
1433
|
+
return;
|
|
1434
|
+
}
|
|
1435
|
+
}
|
|
1436
|
+
catch (e) {
|
|
1437
|
+
error("NativeComponent send error:", e);
|
|
1438
|
+
}
|
|
1439
|
+
}
|
|
1440
|
+
function flushNativeComponentQueue() {
|
|
1441
|
+
if (!hasNativeComponentHandler() || nativeComponentQueue.length === 0)
|
|
1442
|
+
return;
|
|
1443
|
+
nativeComponentReady = true;
|
|
1444
|
+
while (nativeComponentQueue.length) {
|
|
1445
|
+
var msg = nativeComponentQueue.shift();
|
|
1446
|
+
try {
|
|
1447
|
+
postNativeComponentMessage(msg);
|
|
1448
|
+
}
|
|
1449
|
+
catch (_a) {
|
|
1450
|
+
break;
|
|
1451
|
+
}
|
|
1452
|
+
}
|
|
1453
|
+
}
|
|
1454
|
+
function sendNativeComponentMessage(message) {
|
|
1455
|
+
try {
|
|
1456
|
+
if (!hasNativeComponentHandler()) {
|
|
1457
|
+
nativeComponentQueue.push(message);
|
|
1458
|
+
return;
|
|
1459
|
+
}
|
|
1460
|
+
if (!nativeComponentReady)
|
|
1461
|
+
flushNativeComponentQueue();
|
|
1462
|
+
postNativeComponentMessage(message);
|
|
1463
|
+
}
|
|
1464
|
+
catch (e) {
|
|
1465
|
+
error("NC send failed:", e);
|
|
1466
|
+
}
|
|
1467
|
+
}
|
|
1468
|
+
function nextMessageId(prefix) {
|
|
1469
|
+
return "".concat(prefix, "_").concat(Date.now(), "_").concat(requestCounter++);
|
|
1470
|
+
}
|
|
1471
|
+
function attachAbortSignal(id, signal, onAbort) {
|
|
1472
|
+
if (!signal)
|
|
1473
|
+
return;
|
|
1474
|
+
if (signal.aborted) {
|
|
1475
|
+
onAbort();
|
|
1476
|
+
return;
|
|
1477
|
+
}
|
|
1478
|
+
var abortListener;
|
|
1479
|
+
abortListener = {
|
|
1480
|
+
handleEvent: function () {
|
|
1481
|
+
signal.removeEventListener("abort", abortListener);
|
|
1482
|
+
onAbort();
|
|
1483
|
+
},
|
|
1484
|
+
};
|
|
1485
|
+
signal.addEventListener("abort", abortListener);
|
|
1486
|
+
}
|
|
1487
|
+
// Low-level protocol interface. Public consumers should use LingXiaBridge.invoke/stream/channel.
|
|
1488
|
+
var rawBridge = {
|
|
1489
|
+
call: function (method, params, options) {
|
|
1490
|
+
return new Promise(function (resolve, reject) {
|
|
1491
|
+
var _a;
|
|
1492
|
+
if (!method || typeof method !== "string") {
|
|
1493
|
+
reject({
|
|
1494
|
+
code: BRIDGE_ERROR.MALFORMED_MESSAGE,
|
|
1495
|
+
message: "Method name must be a non-empty string",
|
|
1496
|
+
});
|
|
1497
|
+
return;
|
|
1498
|
+
}
|
|
1499
|
+
if (!helloSent)
|
|
1500
|
+
startHandshake();
|
|
1501
|
+
var id = nextMessageId("c");
|
|
1502
|
+
var cap = (options === null || options === void 0 ? void 0 : options.cap) || inferCap(method);
|
|
1503
|
+
var timeoutMs = (_a = options === null || options === void 0 ? void 0 : options.timeoutMs) !== null && _a !== void 0 ? _a : DEFAULT_TIMEOUT_MS;
|
|
1504
|
+
pendingReq.set(id, {
|
|
1505
|
+
method: method,
|
|
1506
|
+
mode: "call",
|
|
1507
|
+
resolve: resolve,
|
|
1508
|
+
reject: function (e) { return reject(e); },
|
|
1509
|
+
timeoutMs: timeoutMs,
|
|
1510
|
+
timerId: null,
|
|
1511
|
+
});
|
|
1512
|
+
var req = {
|
|
1513
|
+
v: 2,
|
|
1514
|
+
kind: "req",
|
|
1515
|
+
id: id,
|
|
1516
|
+
method: method,
|
|
1517
|
+
params: normalizeParams(params),
|
|
1518
|
+
cap: cap,
|
|
1519
|
+
};
|
|
1520
|
+
send(req, id);
|
|
1521
|
+
attachAbortSignal(id, options === null || options === void 0 ? void 0 : options.signal, function () {
|
|
1522
|
+
var removed = removeOutboxByReqId(id);
|
|
1523
|
+
rejectPendingRequest(id, {
|
|
1524
|
+
code: BRIDGE_ERROR.CANCELED,
|
|
1525
|
+
message: "Bridge request aborted",
|
|
1526
|
+
});
|
|
1527
|
+
if (!removed && handshakeDone)
|
|
1528
|
+
send({ v: 2, kind: "cancel", id: id });
|
|
1529
|
+
});
|
|
1530
|
+
});
|
|
1531
|
+
},
|
|
1532
|
+
stream: function (method, params, options) {
|
|
1533
|
+
var _a;
|
|
1534
|
+
if (!method || typeof method !== "string") {
|
|
1535
|
+
var invalid = createStreamHandle("invalid", function () { });
|
|
1536
|
+
invalid._reject({
|
|
1537
|
+
code: BRIDGE_ERROR.MALFORMED_MESSAGE,
|
|
1538
|
+
message: "Method name must be a non-empty string",
|
|
1539
|
+
});
|
|
1540
|
+
return invalid;
|
|
1541
|
+
}
|
|
1542
|
+
if (!helloSent)
|
|
1543
|
+
startHandshake();
|
|
1544
|
+
var id = nextMessageId("c");
|
|
1545
|
+
var handle = createStreamHandle(id, function () {
|
|
1546
|
+
var removed = removeOutboxByReqId(id);
|
|
1547
|
+
if (removed) {
|
|
1548
|
+
rejectPendingRequest(id, {
|
|
1549
|
+
code: BRIDGE_ERROR.CANCELED,
|
|
1550
|
+
message: "Bridge request aborted",
|
|
1551
|
+
});
|
|
1552
|
+
return;
|
|
1553
|
+
}
|
|
1554
|
+
if (handshakeDone)
|
|
1555
|
+
send({ v: 2, kind: "cancel", id: id });
|
|
1556
|
+
});
|
|
1557
|
+
var cap = (options === null || options === void 0 ? void 0 : options.cap) || inferCap(method);
|
|
1558
|
+
var timeoutMs = (_a = options === null || options === void 0 ? void 0 : options.timeoutMs) !== null && _a !== void 0 ? _a : DEFAULT_TIMEOUT_MS;
|
|
1559
|
+
pendingReq.set(id, {
|
|
1560
|
+
method: method,
|
|
1561
|
+
mode: "stream",
|
|
1562
|
+
stream: handle,
|
|
1563
|
+
timeoutMs: timeoutMs,
|
|
1564
|
+
timerId: null,
|
|
1565
|
+
});
|
|
1566
|
+
send({
|
|
1567
|
+
v: 2,
|
|
1568
|
+
kind: "req",
|
|
1569
|
+
id: id,
|
|
1570
|
+
method: method,
|
|
1571
|
+
params: normalizeParams(params),
|
|
1572
|
+
cap: cap,
|
|
1573
|
+
}, id);
|
|
1574
|
+
attachAbortSignal(id, options === null || options === void 0 ? void 0 : options.signal, function () { return handle.cancel(); });
|
|
1575
|
+
return handle;
|
|
1576
|
+
},
|
|
1577
|
+
notify: function (method, params, options) {
|
|
1578
|
+
if (!method || typeof method !== "string")
|
|
1579
|
+
return;
|
|
1580
|
+
if (!helloSent)
|
|
1581
|
+
startHandshake();
|
|
1582
|
+
send({
|
|
1583
|
+
v: 2,
|
|
1584
|
+
kind: "notify",
|
|
1585
|
+
method: method,
|
|
1586
|
+
params: normalizeParams(params),
|
|
1587
|
+
cap: (options === null || options === void 0 ? void 0 : options.cap) || inferCap(method),
|
|
1588
|
+
});
|
|
1589
|
+
},
|
|
1590
|
+
state: {
|
|
1591
|
+
subscribe: subscribeState,
|
|
1592
|
+
},
|
|
1593
|
+
channel: {
|
|
1594
|
+
open: function (topic, params, options) {
|
|
1595
|
+
if (!topic || typeof topic !== "string") {
|
|
1596
|
+
return Promise.reject({
|
|
1597
|
+
code: BRIDGE_ERROR.MALFORMED_MESSAGE,
|
|
1598
|
+
message: "Topic name must be a non-empty string",
|
|
1599
|
+
});
|
|
1600
|
+
}
|
|
1601
|
+
if (!helloSent)
|
|
1602
|
+
startHandshake();
|
|
1603
|
+
return new Promise(function (resolve, reject) {
|
|
1604
|
+
var id = nextMessageId("ch");
|
|
1605
|
+
var channel = createChannel(id, function (payload, seq) {
|
|
1606
|
+
send({ v: 2, kind: "ch.data", id: id, seq: seq, payload: payload });
|
|
1607
|
+
}, function (code, reason) {
|
|
1608
|
+
var pending = pendingChannels.get(id);
|
|
1609
|
+
if (pending && pending.timerId !== null)
|
|
1610
|
+
clearTimeout(pending.timerId);
|
|
1611
|
+
pendingChannels.delete(id);
|
|
1612
|
+
activeChannels.delete(id);
|
|
1613
|
+
send({ v: 2, kind: "ch.close", id: id, code: code, reason: reason });
|
|
1614
|
+
});
|
|
1615
|
+
pendingChannels.set(id, {
|
|
1616
|
+
topic: topic,
|
|
1617
|
+
channel: channel,
|
|
1618
|
+
resolve: resolve,
|
|
1619
|
+
reject: reject,
|
|
1620
|
+
timerId: null,
|
|
1621
|
+
});
|
|
1622
|
+
send({
|
|
1623
|
+
v: 2,
|
|
1624
|
+
kind: "ch.open",
|
|
1625
|
+
id: id,
|
|
1626
|
+
topic: topic,
|
|
1627
|
+
params: normalizeParams(params),
|
|
1628
|
+
cap: (options === null || options === void 0 ? void 0 : options.cap) || inferCap(topic),
|
|
1629
|
+
}, id);
|
|
1630
|
+
});
|
|
1631
|
+
},
|
|
1632
|
+
},
|
|
1633
|
+
};
|
|
1634
|
+
// Public interface
|
|
1635
|
+
export var LingXiaBridge = {
|
|
1636
|
+
invoke: function (route, input, options) {
|
|
1637
|
+
return rawBridge
|
|
1638
|
+
.call(nativeRoute(route), input, nativeOptions(options))
|
|
1639
|
+
.then(function (value) { return value; })
|
|
1640
|
+
.catch(function (error) { return Promise.reject(toNativeError(error)); });
|
|
1641
|
+
},
|
|
1642
|
+
notify: function (route, input, options) {
|
|
1643
|
+
rawBridge.notify(nativeRoute(route), input, nativeOptions(options));
|
|
1644
|
+
},
|
|
1645
|
+
stream: function (route, input, options) {
|
|
1646
|
+
return wrapNativeStream(rawBridge.stream(nativeRoute(route), input, nativeOptions(options)));
|
|
1647
|
+
},
|
|
1648
|
+
channel: function (route, input, options) {
|
|
1649
|
+
return rawBridge.channel
|
|
1650
|
+
.open(nativeRoute(route), input, nativeOptions(options))
|
|
1651
|
+
.then(function (handle) { return wrapNativeChannel(handle); })
|
|
1652
|
+
.catch(function (error) { return Promise.reject(toNativeError(error)); });
|
|
1653
|
+
},
|
|
1654
|
+
raw: rawBridge,
|
|
1655
|
+
state: {
|
|
1656
|
+
subscribe: subscribeState,
|
|
1657
|
+
},
|
|
1658
|
+
_connectWebMessagePort: function (port) {
|
|
1659
|
+
if (communicationMethod !== MESSAGE_PORT_TYPE)
|
|
1660
|
+
return;
|
|
1661
|
+
if (messagePort && messagePort !== port) {
|
|
1662
|
+
try {
|
|
1663
|
+
messagePort.onmessage = null;
|
|
1664
|
+
messagePort.close();
|
|
1665
|
+
}
|
|
1666
|
+
catch (_a) { }
|
|
1667
|
+
}
|
|
1668
|
+
messagePort = port;
|
|
1669
|
+
port.onmessage = function (event) {
|
|
1670
|
+
var data = event.data;
|
|
1671
|
+
if (typeof data === "string") {
|
|
1672
|
+
try {
|
|
1673
|
+
data = JSON.parse(data);
|
|
1674
|
+
}
|
|
1675
|
+
catch (_a) {
|
|
1676
|
+
return;
|
|
1677
|
+
}
|
|
1678
|
+
}
|
|
1679
|
+
handleIncomingMessage(data);
|
|
1680
|
+
};
|
|
1681
|
+
// Some WebView MessagePort implementations (notably Android WebMessagePort)
|
|
1682
|
+
// require an explicit start() to begin dispatching onmessage events.
|
|
1683
|
+
try {
|
|
1684
|
+
port.start();
|
|
1685
|
+
}
|
|
1686
|
+
catch (_b) { }
|
|
1687
|
+
log("Port connected");
|
|
1688
|
+
startHandshake();
|
|
1689
|
+
},
|
|
1690
|
+
_receiveEvaluateMessage: function (messageString) {
|
|
1691
|
+
try {
|
|
1692
|
+
if (messageString)
|
|
1693
|
+
handleIncomingMessage(JSON.parse(messageString));
|
|
1694
|
+
}
|
|
1695
|
+
catch (e) {
|
|
1696
|
+
error("Parse error:", e);
|
|
1697
|
+
}
|
|
1698
|
+
},
|
|
1699
|
+
debug: new Proxy(debugFlags, {
|
|
1700
|
+
get: function (target, prop) {
|
|
1701
|
+
return target[prop];
|
|
1702
|
+
},
|
|
1703
|
+
set: function (target, prop, value) {
|
|
1704
|
+
if (prop in target) {
|
|
1705
|
+
target[prop] = !!value;
|
|
1706
|
+
console.log("[LX] ".concat(prop, ": ").concat(value));
|
|
1707
|
+
return true;
|
|
1708
|
+
}
|
|
1709
|
+
return false;
|
|
1710
|
+
},
|
|
1711
|
+
}),
|
|
1712
|
+
platform: {
|
|
1713
|
+
isHarmony: isHarmony,
|
|
1714
|
+
isIOS: isIOS,
|
|
1715
|
+
isAndroid: isAndroid,
|
|
1716
|
+
isMacOS: isMacOS,
|
|
1717
|
+
isDesktop: isDesktop,
|
|
1718
|
+
getOS: getPlatformOS,
|
|
1719
|
+
},
|
|
1720
|
+
dom: {
|
|
1721
|
+
measureById: function (id) {
|
|
1722
|
+
try {
|
|
1723
|
+
if (!id)
|
|
1724
|
+
return null;
|
|
1725
|
+
var el = document.getElementById(id);
|
|
1726
|
+
if (!el)
|
|
1727
|
+
return null;
|
|
1728
|
+
var r = el.getBoundingClientRect();
|
|
1729
|
+
var radius = 0;
|
|
1730
|
+
try {
|
|
1731
|
+
radius = parseFloat(getComputedStyle(el).borderRadius) || 0;
|
|
1732
|
+
}
|
|
1733
|
+
catch (_a) { }
|
|
1734
|
+
return [
|
|
1735
|
+
r.left + window.scrollX,
|
|
1736
|
+
r.top + window.scrollY,
|
|
1737
|
+
r.width,
|
|
1738
|
+
r.height,
|
|
1739
|
+
radius,
|
|
1740
|
+
];
|
|
1741
|
+
}
|
|
1742
|
+
catch (_b) {
|
|
1743
|
+
return null;
|
|
1744
|
+
}
|
|
1745
|
+
},
|
|
1746
|
+
},
|
|
1747
|
+
nativeComponents: {
|
|
1748
|
+
send: sendNativeComponentMessage,
|
|
1749
|
+
hasHandler: hasNativeComponentHandler,
|
|
1750
|
+
flush: flushNativeComponentQueue,
|
|
1751
|
+
register: function (id, handler) {
|
|
1752
|
+
if (!id || typeof handler !== "function")
|
|
1753
|
+
return function () { };
|
|
1754
|
+
nativeComponentHandlers.set(id, handler);
|
|
1755
|
+
return function () { return nativeComponentHandlers.delete(id); };
|
|
1756
|
+
},
|
|
1757
|
+
unregister: function (id) {
|
|
1758
|
+
nativeComponentHandlers.delete(id);
|
|
1759
|
+
},
|
|
1760
|
+
},
|
|
1761
|
+
isReady: function () {
|
|
1762
|
+
return handshakeDone;
|
|
1763
|
+
},
|
|
1764
|
+
};
|
|
1765
|
+
function nativeRoute(route) {
|
|
1766
|
+
return route.startsWith("host.") ? route : "host.".concat(route);
|
|
1767
|
+
}
|
|
1768
|
+
function nativeOptions(options) {
|
|
1769
|
+
return __assign(__assign({}, (options || {})), { cap: (options === null || options === void 0 ? void 0 : options.cap) || "host" });
|
|
1770
|
+
}
|
|
1771
|
+
function wrapNativeStream(handle) {
|
|
1772
|
+
var eventListeners = new Set();
|
|
1773
|
+
var errorListeners = new Set();
|
|
1774
|
+
handle.on("data", function (event) {
|
|
1775
|
+
var e_16, _a;
|
|
1776
|
+
try {
|
|
1777
|
+
for (var eventListeners_1 = __values(eventListeners), eventListeners_1_1 = eventListeners_1.next(); !eventListeners_1_1.done; eventListeners_1_1 = eventListeners_1.next()) {
|
|
1778
|
+
var listener = eventListeners_1_1.value;
|
|
1779
|
+
listener(event);
|
|
1780
|
+
}
|
|
1781
|
+
}
|
|
1782
|
+
catch (e_16_1) { e_16 = { error: e_16_1 }; }
|
|
1783
|
+
finally {
|
|
1784
|
+
try {
|
|
1785
|
+
if (eventListeners_1_1 && !eventListeners_1_1.done && (_a = eventListeners_1.return)) _a.call(eventListeners_1);
|
|
1786
|
+
}
|
|
1787
|
+
finally { if (e_16) throw e_16.error; }
|
|
1788
|
+
}
|
|
1789
|
+
});
|
|
1790
|
+
handle.on("error", function (error) {
|
|
1791
|
+
var e_17, _a;
|
|
1792
|
+
var nativeError = toNativeError(error);
|
|
1793
|
+
try {
|
|
1794
|
+
for (var errorListeners_1 = __values(errorListeners), errorListeners_1_1 = errorListeners_1.next(); !errorListeners_1_1.done; errorListeners_1_1 = errorListeners_1.next()) {
|
|
1795
|
+
var listener = errorListeners_1_1.value;
|
|
1796
|
+
listener(nativeError);
|
|
1797
|
+
}
|
|
1798
|
+
}
|
|
1799
|
+
catch (e_17_1) { e_17 = { error: e_17_1 }; }
|
|
1800
|
+
finally {
|
|
1801
|
+
try {
|
|
1802
|
+
if (errorListeners_1_1 && !errorListeners_1_1.done && (_a = errorListeners_1.return)) _a.call(errorListeners_1);
|
|
1803
|
+
}
|
|
1804
|
+
finally { if (e_17) throw e_17.error; }
|
|
1805
|
+
}
|
|
1806
|
+
});
|
|
1807
|
+
return {
|
|
1808
|
+
onEvent: function (listener) {
|
|
1809
|
+
eventListeners.add(listener);
|
|
1810
|
+
return function () {
|
|
1811
|
+
eventListeners.delete(listener);
|
|
1812
|
+
};
|
|
1813
|
+
},
|
|
1814
|
+
onError: function (listener) {
|
|
1815
|
+
errorListeners.add(listener);
|
|
1816
|
+
return function () {
|
|
1817
|
+
errorListeners.delete(listener);
|
|
1818
|
+
};
|
|
1819
|
+
},
|
|
1820
|
+
result: handle.result.catch(function (error) { return Promise.reject(toNativeError(error)); }),
|
|
1821
|
+
cancel: function () {
|
|
1822
|
+
handle.cancel();
|
|
1823
|
+
},
|
|
1824
|
+
};
|
|
1825
|
+
}
|
|
1826
|
+
function wrapNativeChannel(channel) {
|
|
1827
|
+
var messageListeners = new Set();
|
|
1828
|
+
var closeListeners = new Set();
|
|
1829
|
+
channel.on("data", function (message) {
|
|
1830
|
+
var e_18, _a;
|
|
1831
|
+
try {
|
|
1832
|
+
for (var messageListeners_1 = __values(messageListeners), messageListeners_1_1 = messageListeners_1.next(); !messageListeners_1_1.done; messageListeners_1_1 = messageListeners_1.next()) {
|
|
1833
|
+
var listener = messageListeners_1_1.value;
|
|
1834
|
+
listener(message);
|
|
1835
|
+
}
|
|
1836
|
+
}
|
|
1837
|
+
catch (e_18_1) { e_18 = { error: e_18_1 }; }
|
|
1838
|
+
finally {
|
|
1839
|
+
try {
|
|
1840
|
+
if (messageListeners_1_1 && !messageListeners_1_1.done && (_a = messageListeners_1.return)) _a.call(messageListeners_1);
|
|
1841
|
+
}
|
|
1842
|
+
finally { if (e_18) throw e_18.error; }
|
|
1843
|
+
}
|
|
1844
|
+
});
|
|
1845
|
+
channel.on("close", function (code, reason) {
|
|
1846
|
+
var e_19, _a;
|
|
1847
|
+
var event = { code: code, reason: reason };
|
|
1848
|
+
try {
|
|
1849
|
+
for (var closeListeners_1 = __values(closeListeners), closeListeners_1_1 = closeListeners_1.next(); !closeListeners_1_1.done; closeListeners_1_1 = closeListeners_1.next()) {
|
|
1850
|
+
var listener = closeListeners_1_1.value;
|
|
1851
|
+
listener(event);
|
|
1852
|
+
}
|
|
1853
|
+
}
|
|
1854
|
+
catch (e_19_1) { e_19 = { error: e_19_1 }; }
|
|
1855
|
+
finally {
|
|
1856
|
+
try {
|
|
1857
|
+
if (closeListeners_1_1 && !closeListeners_1_1.done && (_a = closeListeners_1.return)) _a.call(closeListeners_1);
|
|
1858
|
+
}
|
|
1859
|
+
finally { if (e_19) throw e_19.error; }
|
|
1860
|
+
}
|
|
1861
|
+
});
|
|
1862
|
+
return {
|
|
1863
|
+
send: function (message) {
|
|
1864
|
+
channel.send(message);
|
|
1865
|
+
},
|
|
1866
|
+
onMessage: function (listener) {
|
|
1867
|
+
messageListeners.add(listener);
|
|
1868
|
+
return function () {
|
|
1869
|
+
messageListeners.delete(listener);
|
|
1870
|
+
};
|
|
1871
|
+
},
|
|
1872
|
+
onClose: function (listener) {
|
|
1873
|
+
closeListeners.add(listener);
|
|
1874
|
+
return function () {
|
|
1875
|
+
closeListeners.delete(listener);
|
|
1876
|
+
};
|
|
1877
|
+
},
|
|
1878
|
+
close: function (code, reason) {
|
|
1879
|
+
channel.close(code, reason);
|
|
1880
|
+
},
|
|
1881
|
+
};
|
|
1882
|
+
}
|
|
1883
|
+
export function invoke(route, input, options) {
|
|
1884
|
+
return LingXiaBridge.invoke(route, input, options);
|
|
1885
|
+
}
|
|
1886
|
+
export function notify(route, input, options) {
|
|
1887
|
+
rawBridge.notify(nativeRoute(route), input, nativeOptions(options));
|
|
1888
|
+
}
|
|
1889
|
+
export function stream(route, input, options) {
|
|
1890
|
+
return wrapNativeStream(rawBridge.stream(nativeRoute(route), input, nativeOptions(options)));
|
|
1891
|
+
}
|
|
1892
|
+
export function channel(route, input, options) {
|
|
1893
|
+
return LingXiaBridge.channel(route, input, options);
|
|
1894
|
+
}
|
|
1895
|
+
export function initBridge() {
|
|
1896
|
+
if (window.__LX_BRIDGE_INIT_STATE) {
|
|
1897
|
+
log("Bridge already ".concat(window.__LX_BRIDGE_INIT_STATE, ", skipping duplicate init"));
|
|
1898
|
+
return;
|
|
1899
|
+
}
|
|
1900
|
+
window.__LX_BRIDGE_INIT_STATE = "initializing";
|
|
1901
|
+
try {
|
|
1902
|
+
log("Method: ".concat(communicationMethod));
|
|
1903
|
+
activateReceiver(LingXiaBridge._receiveEvaluateMessage);
|
|
1904
|
+
if (useAppleDownstreamTransport()) {
|
|
1905
|
+
ensureAppleDownstream();
|
|
1906
|
+
}
|
|
1907
|
+
else if (communicationMethod === MESSAGE_PORT_TYPE) {
|
|
1908
|
+
installMessagePortInitListener();
|
|
1909
|
+
getMessagePort().catch(function (e) { return warn("Port init failed:", e); });
|
|
1910
|
+
}
|
|
1911
|
+
else if (communicationMethod === "webkit" ||
|
|
1912
|
+
communicationMethod === JS_INTERFACE_TYPE) {
|
|
1913
|
+
startHandshake();
|
|
1914
|
+
}
|
|
1915
|
+
else {
|
|
1916
|
+
warn("Unknown method");
|
|
1917
|
+
}
|
|
1918
|
+
window.LingXiaBridge = LingXiaBridge;
|
|
1919
|
+
installNativeComponentCoverageMonitor({
|
|
1920
|
+
os: getPlatformOS(),
|
|
1921
|
+
send: sendNativeComponentMessage,
|
|
1922
|
+
});
|
|
1923
|
+
window.__LX_BRIDGE_INIT_STATE = "initialized";
|
|
1924
|
+
log("Init complete");
|
|
1925
|
+
}
|
|
1926
|
+
catch (e) {
|
|
1927
|
+
delete window.__LX_BRIDGE_INIT_STATE;
|
|
1928
|
+
throw e;
|
|
1929
|
+
}
|
|
1930
|
+
}
|