@webview-bridge/web 1.5.1-rc.0 → 1.5.1-rc.2
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/commonjs/index.cjs +1 -485
- package/dist/module/index.mjs +1 -457
- package/dist/typescript/packages/web/src/internal/bridgeInstance.d.ts +22 -0
- package/dist/typescript/packages/web/src/internal/createPromiseProxy.d.ts +1 -0
- package/dist/typescript/packages/web/src/internal/linkBridgeStore.d.ts +2 -1
- package/dist/typescript/shared/util/src/createEvents.d.ts +2 -1
- package/dist/typescript/shared/util/src/types.d.ts +1 -0
- package/package.json +1 -1
- package/dist/typescript/packages/web/src/internal/emitter.d.ts +0 -1
package/dist/commonjs/index.cjs
CHANGED
|
@@ -1,485 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __defProps = Object.defineProperties;
|
|
4
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
-
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
6
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
-
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
8
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
-
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
10
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
11
|
-
var __spreadValues = (a, b) => {
|
|
12
|
-
for (var prop in b || (b = {}))
|
|
13
|
-
if (__hasOwnProp.call(b, prop))
|
|
14
|
-
__defNormalProp(a, prop, b[prop]);
|
|
15
|
-
if (__getOwnPropSymbols)
|
|
16
|
-
for (var prop of __getOwnPropSymbols(b)) {
|
|
17
|
-
if (__propIsEnum.call(b, prop))
|
|
18
|
-
__defNormalProp(a, prop, b[prop]);
|
|
19
|
-
}
|
|
20
|
-
return a;
|
|
21
|
-
};
|
|
22
|
-
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
23
|
-
var __export = (target, all) => {
|
|
24
|
-
for (var name in all)
|
|
25
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
26
|
-
};
|
|
27
|
-
var __copyProps = (to, from, except, desc) => {
|
|
28
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
29
|
-
for (let key of __getOwnPropNames(from))
|
|
30
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
31
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
32
|
-
}
|
|
33
|
-
return to;
|
|
34
|
-
};
|
|
35
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
36
|
-
var __async = (__this, __arguments, generator) => {
|
|
37
|
-
return new Promise((resolve, reject) => {
|
|
38
|
-
var fulfilled = (value) => {
|
|
39
|
-
try {
|
|
40
|
-
step(generator.next(value));
|
|
41
|
-
} catch (e) {
|
|
42
|
-
reject(e);
|
|
43
|
-
}
|
|
44
|
-
};
|
|
45
|
-
var rejected = (value) => {
|
|
46
|
-
try {
|
|
47
|
-
step(generator.throw(value));
|
|
48
|
-
} catch (e) {
|
|
49
|
-
reject(e);
|
|
50
|
-
}
|
|
51
|
-
};
|
|
52
|
-
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
53
|
-
step((generator = generator.apply(__this, __arguments)).next());
|
|
54
|
-
});
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
// src/index.ts
|
|
58
|
-
var src_exports = {};
|
|
59
|
-
__export(src_exports, {
|
|
60
|
-
MethodNotFoundError: () => MethodNotFoundError,
|
|
61
|
-
NativeMethodError: () => NativeMethodError,
|
|
62
|
-
linkBridge: () => linkBridge,
|
|
63
|
-
linkNativeMethod: () => linkNativeMethod,
|
|
64
|
-
registerWebMethod: () => registerWebMethod
|
|
65
|
-
});
|
|
66
|
-
module.exports = __toCommonJS(src_exports);
|
|
67
|
-
|
|
68
|
-
// src/error.ts
|
|
69
|
-
var MethodNotFoundError = class extends Error {
|
|
70
|
-
constructor(methodName) {
|
|
71
|
-
super(`Method ${methodName} is not defined`);
|
|
72
|
-
this.name = "MethodNotFoundError";
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
|
-
var NativeMethodError = class extends Error {
|
|
76
|
-
constructor(methodName) {
|
|
77
|
-
super(`An error occurred in the native bridge: ${methodName}`);
|
|
78
|
-
this.name = "NativeMethodError";
|
|
79
|
-
}
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
// ../../shared/util/src/createEvents.ts
|
|
83
|
-
var createEvents = () => ({
|
|
84
|
-
events: {},
|
|
85
|
-
emit(event, ...args) {
|
|
86
|
-
const callbacks = this.events[event] || [];
|
|
87
|
-
for (let i = 0, length = callbacks.length; i < length; i++) {
|
|
88
|
-
callbacks[i](...args);
|
|
89
|
-
}
|
|
90
|
-
},
|
|
91
|
-
on(event, cb) {
|
|
92
|
-
var _a;
|
|
93
|
-
((_a = this.events[event]) == null ? void 0 : _a.push(cb)) || (this.events[event] = [cb]);
|
|
94
|
-
return () => {
|
|
95
|
-
var _a2;
|
|
96
|
-
this.events[event] = (_a2 = this.events[event]) == null ? void 0 : _a2.filter((i) => cb !== i);
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
});
|
|
100
|
-
var createResolver = ({
|
|
101
|
-
emitter: emitter2,
|
|
102
|
-
evaluate,
|
|
103
|
-
eventId,
|
|
104
|
-
failHandler = false,
|
|
105
|
-
methodName,
|
|
106
|
-
onFallback
|
|
107
|
-
}) => {
|
|
108
|
-
return new Promise((resolve, reject) => {
|
|
109
|
-
const unbind = emitter2.on(
|
|
110
|
-
`${methodName}-${eventId}`,
|
|
111
|
-
(data, throwOccurred) => {
|
|
112
|
-
unbind();
|
|
113
|
-
if (throwOccurred) {
|
|
114
|
-
if (failHandler instanceof Error) {
|
|
115
|
-
onFallback == null ? void 0 : onFallback();
|
|
116
|
-
reject(failHandler);
|
|
117
|
-
} else {
|
|
118
|
-
resolve(void 0);
|
|
119
|
-
}
|
|
120
|
-
} else {
|
|
121
|
-
resolve(data);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
);
|
|
125
|
-
evaluate();
|
|
126
|
-
});
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
// ../../shared/util/src/createRandomId.tsx
|
|
130
|
-
var TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
131
|
-
var ID_LENGTH = 21;
|
|
132
|
-
var createRandomId = (size = ID_LENGTH) => {
|
|
133
|
-
const randomValues = Array.from(
|
|
134
|
-
{ length: size },
|
|
135
|
-
() => TABLE[Math.floor(Math.random() * TABLE.length)]
|
|
136
|
-
);
|
|
137
|
-
return randomValues.join("");
|
|
138
|
-
};
|
|
139
|
-
|
|
140
|
-
// ../../shared/util/src/equals.ts
|
|
141
|
-
var equals = (a, b) => {
|
|
142
|
-
if (a === b) {
|
|
143
|
-
return true;
|
|
144
|
-
}
|
|
145
|
-
if (a && b && typeof a === "object" && typeof b === "object") {
|
|
146
|
-
const arrA = Array.isArray(a);
|
|
147
|
-
const arrB = Array.isArray(b);
|
|
148
|
-
let i;
|
|
149
|
-
let length;
|
|
150
|
-
let key;
|
|
151
|
-
if (arrA && arrB) {
|
|
152
|
-
length = a.length;
|
|
153
|
-
if (length !== b.length) {
|
|
154
|
-
return false;
|
|
155
|
-
}
|
|
156
|
-
for (i = length; i-- !== 0; ) {
|
|
157
|
-
if (!equals(a[i], b[i])) {
|
|
158
|
-
return false;
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
return true;
|
|
162
|
-
}
|
|
163
|
-
if (arrA !== arrB) {
|
|
164
|
-
return false;
|
|
165
|
-
}
|
|
166
|
-
const keys = Object.keys(a);
|
|
167
|
-
length = keys.length;
|
|
168
|
-
if (length !== Object.keys(b).length) {
|
|
169
|
-
return false;
|
|
170
|
-
}
|
|
171
|
-
for (i = length; i-- !== 0; ) {
|
|
172
|
-
if (!Object.prototype.hasOwnProperty.call(b, keys[i])) {
|
|
173
|
-
return false;
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
for (i = length; i-- !== 0; ) {
|
|
177
|
-
key = keys[i];
|
|
178
|
-
if (!equals(a[key], b[key])) {
|
|
179
|
-
return false;
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
return true;
|
|
183
|
-
}
|
|
184
|
-
return a !== a && b !== b;
|
|
185
|
-
};
|
|
186
|
-
|
|
187
|
-
// ../../shared/util/src/noop.ts
|
|
188
|
-
var noop = () => {
|
|
189
|
-
};
|
|
190
|
-
|
|
191
|
-
// ../../shared/util/src/removeUndefinedKeys.tsx
|
|
192
|
-
var removeUndefinedKeys = (obj) => {
|
|
193
|
-
Object.keys(obj).forEach((key) => {
|
|
194
|
-
if (obj[key] === void 0) {
|
|
195
|
-
delete obj[key];
|
|
196
|
-
}
|
|
197
|
-
});
|
|
198
|
-
return obj;
|
|
199
|
-
};
|
|
200
|
-
|
|
201
|
-
// ../../shared/util/src/timeout.ts
|
|
202
|
-
var timeout = (ms, throwOnError = true) => {
|
|
203
|
-
return new Promise((resolve, reject) => {
|
|
204
|
-
setTimeout(() => {
|
|
205
|
-
if (throwOnError) {
|
|
206
|
-
reject(new Error("Timeout"));
|
|
207
|
-
} else {
|
|
208
|
-
resolve(void 0);
|
|
209
|
-
}
|
|
210
|
-
}, ms);
|
|
211
|
-
});
|
|
212
|
-
};
|
|
213
|
-
|
|
214
|
-
// src/internal/emitter.ts
|
|
215
|
-
var emitter = createEvents();
|
|
216
|
-
|
|
217
|
-
// src/internal/linkBridgeStore.ts
|
|
218
|
-
var linkBridgeStore = (initialState = {}) => {
|
|
219
|
-
var _a;
|
|
220
|
-
if (!window.ReactNativeWebView) {
|
|
221
|
-
console.warn("[WebViewBridge] Not in a WebView environment");
|
|
222
|
-
}
|
|
223
|
-
if (!window.nativeEmitter) {
|
|
224
|
-
window.nativeEmitter = emitter;
|
|
225
|
-
}
|
|
226
|
-
const getState = () => state;
|
|
227
|
-
const setState = (newState) => {
|
|
228
|
-
const _newState = __spreadValues(__spreadValues({}, state), removeUndefinedKeys(newState));
|
|
229
|
-
if (equals(state, _newState)) {
|
|
230
|
-
return;
|
|
231
|
-
}
|
|
232
|
-
const prevState = state;
|
|
233
|
-
state = _newState;
|
|
234
|
-
emitChange(state, prevState);
|
|
235
|
-
};
|
|
236
|
-
emitter.on("bridgeStateChange", (data) => {
|
|
237
|
-
setState(data);
|
|
238
|
-
});
|
|
239
|
-
document.addEventListener("visibilitychange", () => {
|
|
240
|
-
var _a2;
|
|
241
|
-
if (document.visibilityState === "visible") {
|
|
242
|
-
(_a2 = window.ReactNativeWebView) == null ? void 0 : _a2.postMessage(
|
|
243
|
-
JSON.stringify({
|
|
244
|
-
type: "getBridgeState"
|
|
245
|
-
})
|
|
246
|
-
);
|
|
247
|
-
}
|
|
248
|
-
});
|
|
249
|
-
(_a = window.ReactNativeWebView) == null ? void 0 : _a.postMessage(
|
|
250
|
-
JSON.stringify({
|
|
251
|
-
type: "getBridgeState"
|
|
252
|
-
})
|
|
253
|
-
);
|
|
254
|
-
let state = __spreadValues(__spreadValues({}, initialState), window.__bridgeInitialState__);
|
|
255
|
-
const listeners = /* @__PURE__ */ new Set();
|
|
256
|
-
const emitChange = (newState, prevState) => {
|
|
257
|
-
for (const listener of listeners) {
|
|
258
|
-
listener(newState, prevState);
|
|
259
|
-
}
|
|
260
|
-
};
|
|
261
|
-
const subscribe = (listener) => {
|
|
262
|
-
listeners.add(listener);
|
|
263
|
-
return () => listeners.delete(listener);
|
|
264
|
-
};
|
|
265
|
-
return {
|
|
266
|
-
getState,
|
|
267
|
-
subscribe
|
|
268
|
-
};
|
|
269
|
-
};
|
|
270
|
-
|
|
271
|
-
// src/linkBridge.ts
|
|
272
|
-
var createNativeMethod = ({
|
|
273
|
-
methodName,
|
|
274
|
-
throwOnError,
|
|
275
|
-
timeoutMs,
|
|
276
|
-
onFallback
|
|
277
|
-
}) => (...args) => {
|
|
278
|
-
const eventId = createRandomId();
|
|
279
|
-
return Promise.race(
|
|
280
|
-
[
|
|
281
|
-
createResolver({
|
|
282
|
-
emitter,
|
|
283
|
-
methodName,
|
|
284
|
-
eventId,
|
|
285
|
-
evaluate: () => {
|
|
286
|
-
var _a;
|
|
287
|
-
(_a = window.ReactNativeWebView) == null ? void 0 : _a.postMessage(
|
|
288
|
-
JSON.stringify({
|
|
289
|
-
type: "bridge",
|
|
290
|
-
body: {
|
|
291
|
-
method: methodName,
|
|
292
|
-
eventId,
|
|
293
|
-
args
|
|
294
|
-
}
|
|
295
|
-
})
|
|
296
|
-
);
|
|
297
|
-
},
|
|
298
|
-
onFallback: () => {
|
|
299
|
-
onFallback == null ? void 0 : onFallback(methodName, args);
|
|
300
|
-
},
|
|
301
|
-
failHandler: throwOnError && new NativeMethodError(methodName)
|
|
302
|
-
}),
|
|
303
|
-
timeoutMs > 0 && timeout(timeoutMs, throwOnError)
|
|
304
|
-
].filter(Boolean)
|
|
305
|
-
);
|
|
306
|
-
};
|
|
307
|
-
var linkBridge = (options = {
|
|
308
|
-
timeout: 2e3,
|
|
309
|
-
throwOnError: false
|
|
310
|
-
}) => {
|
|
311
|
-
var _a, _b;
|
|
312
|
-
if (typeof window === "undefined") {
|
|
313
|
-
return {
|
|
314
|
-
store: {
|
|
315
|
-
getState: () => ({}),
|
|
316
|
-
subscribe: noop
|
|
317
|
-
}
|
|
318
|
-
};
|
|
319
|
-
}
|
|
320
|
-
const {
|
|
321
|
-
timeout: timeoutMs = 2e3,
|
|
322
|
-
throwOnError = false,
|
|
323
|
-
onFallback,
|
|
324
|
-
onReady
|
|
325
|
-
} = options;
|
|
326
|
-
if (!window.ReactNativeWebView) {
|
|
327
|
-
console.warn("[WebViewBridge] Not in a WebView environment");
|
|
328
|
-
}
|
|
329
|
-
const bridgeMethods = (_a = window.__bridgeMethods__) != null ? _a : [];
|
|
330
|
-
if (!window.nativeEmitter) {
|
|
331
|
-
window.nativeEmitter = emitter;
|
|
332
|
-
}
|
|
333
|
-
const willMethodThrowOnError = (methodName) => {
|
|
334
|
-
return throwOnError === true || Array.isArray(throwOnError) && throwOnError.includes(methodName);
|
|
335
|
-
};
|
|
336
|
-
const target = bridgeMethods.reduce(
|
|
337
|
-
(acc, methodName) => {
|
|
338
|
-
return __spreadProps(__spreadValues({}, acc), {
|
|
339
|
-
[methodName]: createNativeMethod({
|
|
340
|
-
methodName,
|
|
341
|
-
timeoutMs,
|
|
342
|
-
throwOnError: willMethodThrowOnError(methodName),
|
|
343
|
-
onFallback
|
|
344
|
-
})
|
|
345
|
-
});
|
|
346
|
-
},
|
|
347
|
-
{}
|
|
348
|
-
);
|
|
349
|
-
const loose = new Proxy(target, {
|
|
350
|
-
get: (target2, methodName) => {
|
|
351
|
-
if (methodName in target2 && !["isWebViewBridgeAvailable", "isNativeMethodAvailable"].includes(
|
|
352
|
-
methodName
|
|
353
|
-
)) {
|
|
354
|
-
return target2[methodName];
|
|
355
|
-
}
|
|
356
|
-
return createNativeMethod({
|
|
357
|
-
methodName,
|
|
358
|
-
timeoutMs,
|
|
359
|
-
throwOnError: willMethodThrowOnError(methodName),
|
|
360
|
-
onFallback
|
|
361
|
-
});
|
|
362
|
-
}
|
|
363
|
-
});
|
|
364
|
-
Object.assign(target, {
|
|
365
|
-
loose,
|
|
366
|
-
store: linkBridgeStore(target),
|
|
367
|
-
isWebViewBridgeAvailable: Boolean(window.ReactNativeWebView) && bridgeMethods.length > 0,
|
|
368
|
-
isNativeMethodAvailable(methodName) {
|
|
369
|
-
return typeof methodName === "string" && Boolean(window.ReactNativeWebView) && bridgeMethods.includes(methodName);
|
|
370
|
-
},
|
|
371
|
-
addEventListener: (eventName, listener) => {
|
|
372
|
-
return emitter.on(`postMessage/${String(eventName)}`, listener);
|
|
373
|
-
}
|
|
374
|
-
});
|
|
375
|
-
const proxy = new Proxy(target, {
|
|
376
|
-
get: (target2, methodName) => {
|
|
377
|
-
var _a2;
|
|
378
|
-
if (methodName in target2) {
|
|
379
|
-
return target2[methodName];
|
|
380
|
-
}
|
|
381
|
-
(_a2 = window.ReactNativeWebView) == null ? void 0 : _a2.postMessage(
|
|
382
|
-
JSON.stringify({
|
|
383
|
-
type: "fallback",
|
|
384
|
-
body: {
|
|
385
|
-
method: methodName
|
|
386
|
-
}
|
|
387
|
-
})
|
|
388
|
-
);
|
|
389
|
-
if (willMethodThrowOnError(methodName)) {
|
|
390
|
-
return (...args) => {
|
|
391
|
-
onFallback == null ? void 0 : onFallback(methodName, args);
|
|
392
|
-
Promise.reject(new MethodNotFoundError(methodName));
|
|
393
|
-
};
|
|
394
|
-
} else {
|
|
395
|
-
console.warn(
|
|
396
|
-
`[WebViewBridge] ${methodName} is not defined, using fallback.`
|
|
397
|
-
);
|
|
398
|
-
}
|
|
399
|
-
return () => Promise.resolve();
|
|
400
|
-
}
|
|
401
|
-
});
|
|
402
|
-
for (const [eventName, ...args] of (_b = window.nativeBatchedEvents) != null ? _b : []) {
|
|
403
|
-
emitter.emit(eventName, ...args);
|
|
404
|
-
}
|
|
405
|
-
window.nativeBatchedEvents = [];
|
|
406
|
-
onReady == null ? void 0 : onReady(proxy);
|
|
407
|
-
return proxy;
|
|
408
|
-
};
|
|
409
|
-
|
|
410
|
-
// src/linkNativeMethod.ts
|
|
411
|
-
var linkNativeMethod = (options = {
|
|
412
|
-
timeout: 2e3,
|
|
413
|
-
throwOnError: false
|
|
414
|
-
}) => {
|
|
415
|
-
return linkBridge(options);
|
|
416
|
-
};
|
|
417
|
-
|
|
418
|
-
// src/registerWebMethod.ts
|
|
419
|
-
var registerWebMethod = (bridge) => {
|
|
420
|
-
if (typeof window !== "undefined" && !window.ReactNativeWebView) {
|
|
421
|
-
console.warn("[WebViewBridge] Not in a WebView environment");
|
|
422
|
-
return bridge;
|
|
423
|
-
}
|
|
424
|
-
const bridgeEntries = Object.entries(bridge);
|
|
425
|
-
const bridgeNames = Object.keys(bridge);
|
|
426
|
-
const emitter2 = createEvents();
|
|
427
|
-
window.webEmitter = emitter2;
|
|
428
|
-
for (const [funcName, func] of bridgeEntries) {
|
|
429
|
-
const $func = (eventId, args) => __async(void 0, null, function* () {
|
|
430
|
-
var _a, _b;
|
|
431
|
-
try {
|
|
432
|
-
const value = yield func(...args);
|
|
433
|
-
(_a = window.ReactNativeWebView) == null ? void 0 : _a.postMessage(
|
|
434
|
-
JSON.stringify({
|
|
435
|
-
type: "webMethodResponse",
|
|
436
|
-
body: { funcName, eventId, value }
|
|
437
|
-
})
|
|
438
|
-
);
|
|
439
|
-
} catch (e) {
|
|
440
|
-
(_b = window.ReactNativeWebView) == null ? void 0 : _b.postMessage(
|
|
441
|
-
JSON.stringify({
|
|
442
|
-
type: "webMethodError",
|
|
443
|
-
body: { funcName, eventId, error: JSON.stringify(e) }
|
|
444
|
-
})
|
|
445
|
-
);
|
|
446
|
-
}
|
|
447
|
-
});
|
|
448
|
-
emitter2.on(funcName, $func);
|
|
449
|
-
}
|
|
450
|
-
const register = () => {
|
|
451
|
-
var _a;
|
|
452
|
-
(_a = window.ReactNativeWebView) == null ? void 0 : _a.postMessage(
|
|
453
|
-
JSON.stringify({
|
|
454
|
-
type: "registerWebMethod",
|
|
455
|
-
body: { bridgeNames }
|
|
456
|
-
})
|
|
457
|
-
);
|
|
458
|
-
window.removeEventListener("DOMContentLoaded", register);
|
|
459
|
-
};
|
|
460
|
-
if (!window.ReactNativeWebView) {
|
|
461
|
-
window.addEventListener("DOMContentLoaded", register);
|
|
462
|
-
return bridge;
|
|
463
|
-
}
|
|
464
|
-
document.addEventListener("visibilitychange", () => {
|
|
465
|
-
var _a;
|
|
466
|
-
if (document.visibilityState === "visible") {
|
|
467
|
-
(_a = window.ReactNativeWebView) == null ? void 0 : _a.postMessage(
|
|
468
|
-
JSON.stringify({
|
|
469
|
-
type: "registerWebMethod",
|
|
470
|
-
body: { bridgeNames }
|
|
471
|
-
})
|
|
472
|
-
);
|
|
473
|
-
}
|
|
474
|
-
});
|
|
475
|
-
register();
|
|
476
|
-
return bridge;
|
|
477
|
-
};
|
|
478
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
479
|
-
0 && (module.exports = {
|
|
480
|
-
MethodNotFoundError,
|
|
481
|
-
NativeMethodError,
|
|
482
|
-
linkBridge,
|
|
483
|
-
linkNativeMethod,
|
|
484
|
-
registerWebMethod
|
|
485
|
-
});
|
|
1
|
+
"use strict";var w=Object.defineProperty,R=Object.defineProperties,A=Object.getOwnPropertyDescriptor,D=Object.getOwnPropertyDescriptors,K=Object.getOwnPropertyNames,b=Object.getOwnPropertySymbols;var T=Object.prototype.hasOwnProperty,J=Object.prototype.propertyIsEnumerable;var x=(t,e,r)=>e in t?w(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r,u=(t,e)=>{for(var r in e||(e={}))T.call(e,r)&&x(t,r,e[r]);if(b)for(var r of b(e))J.call(e,r)&&x(t,r,e[r]);return t},B=(t,e)=>R(t,D(e));var I=(t,e)=>{for(var r in e)w(t,r,{get:e[r],enumerable:!0})},C=(t,e,r,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of K(e))!T.call(t,n)&&n!==r&&w(t,n,{get:()=>e[n],enumerable:!(o=A(e,n))||o.enumerable});return t};var $=t=>C(w({},"__esModule",{value:!0}),t);var m=(t,e,r)=>(x(t,typeof e!="symbol"?e+"":e,r),r);var O=(t,e,r)=>new Promise((o,n)=>{var i=a=>{try{c(r.next(a))}catch(d){n(d)}},s=a=>{try{c(r.throw(a))}catch(d){n(d)}},c=a=>a.done?o(a.value):Promise.resolve(a.value).then(i,s);c((r=r.apply(t,e)).next())});var G={};I(G,{MethodNotFoundError:()=>f,NativeMethodError:()=>p,linkBridge:()=>S,linkNativeMethod:()=>H,registerWebMethod:()=>q});module.exports=$(G);var f=class extends Error{constructor(e){super(`Method ${e} is not defined`),this.name="MethodNotFoundError"}},p=class extends Error{constructor(e){super(`An error occurred in the native bridge: ${e}`),this.name="NativeMethodError"}};var y=()=>({events:{},emit(t,...e){let r=this.events[t]||[];for(let o=0,n=r.length;o<n;o++)r[o](...e)},on(t,e){var r;return(r=this.events[t])!=null&&r.push(e)||(this.events[t]=[e]),()=>{var o;this.events[t]=(o=this.events[t])==null?void 0:o.filter(n=>e!==n)}}}),P=({emitter:t,evaluate:e,eventId:r,failHandler:o=!1,methodName:n,onFallback:i})=>new Promise((s,c)=>{let a=t.on(`${n}-${r}`,(d,g)=>{a(),g?o instanceof Error?(i==null||i(),c(o)):s(void 0):s(d)});e()});var M="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";var k=(t=21)=>Array.from({length:t},()=>M[Math.floor(Math.random()*M.length)]).join("");var E=(t,e)=>{if(t===e)return!0;if(t&&e&&typeof t=="object"&&typeof e=="object"){let r=Array.isArray(t),o=Array.isArray(e),n,i,s;if(r&&o){if(i=t.length,i!==e.length)return!1;for(n=i;n--!==0;)if(!E(t[n],e[n]))return!1;return!0}if(r!==o)return!1;let c=Object.keys(t);if(i=c.length,i!==Object.keys(e).length)return!1;for(n=i;n--!==0;)if(!Object.prototype.hasOwnProperty.call(e,c[n]))return!1;for(n=i;n--!==0;)if(s=c[n],!E(t[s],e[s]))return!1;return!0}return t!==t&&e!==e};var V=()=>{};var _=t=>(Object.keys(t).forEach(e=>{t[e]===void 0&&delete t[e]}),t);var L=(t,e=!0)=>new Promise((r,o)=>{setTimeout(()=>{e?o(new Error("Timeout")):r(void 0)},t)});var N=()=>new Proxy({},{get:()=>()=>Promise.resolve()});var W=(t,e={},r={})=>{let o=()=>i,n=d=>{let g=u(u({},i),_(d));if(E(i,g))return;let l=i;i=g,c(i,l)};t.on("bridgeStateChange",d=>{n(d)});let i=u(u({},e),r),s=new Set,c=(d,g)=>{for(let l of s)l(d,g)};return{getState:o,subscribe:d=>(s.add(d),()=>s.delete(d))}};var h=class{constructor(e,r,o,n){this.options=e;this._emitter=r;this._bridgeMethods=o;this._nativeInitialState=n;m(this,"defaultTimeoutMs",2e3);m(this,"store",{});m(this,"isWebViewBridgeAvailable",!!window.ReactNativeWebView);m(this,"loose",N());this._hydrate(o,n)}isNativeMethodAvailable(e){return typeof e=="string"&&!!window.ReactNativeWebView&&this._bridgeMethods.includes(e)}addEventListener(e,r){return this._emitter.on(`postMessage/${String(e)}`,r)}_postMessage(e,r){var o;(o=window.ReactNativeWebView)==null||o.postMessage(JSON.stringify(r?{type:e,body:r}:{type:e}))}_createNativeMethod(e,r,o,n){return(...i)=>{let s=k();return Promise.race([P({emitter:this._emitter,methodName:e,eventId:s,evaluate:()=>{this._postMessage("bridge",{method:e,eventId:s,args:i})},onFallback:()=>{n==null||n(e,i)},failHandler:r&&new p(e)}),o>0&&L(o,r)].filter(Boolean))}}_willMethodThrowOnError(e){let{throwOnError:r}=this.options;return r===!0||Array.isArray(r)&&r.includes(e)}_createLoose(e){let{timeout:r=this.defaultTimeoutMs,onFallback:o}=this.options;return new Proxy(e,{get:(n,i)=>i in n&&!["isWebViewBridgeAvailable","isNativeMethodAvailable"].includes(i)?n[i]:this._createNativeMethod(i,this._willMethodThrowOnError(i),r,o)})}_hydrate(e,r={}){var s;if(this._bridgeMethods=e,this._nativeInitialState=r,e.length===0)return!1;let{timeout:o=this.defaultTimeoutMs,onFallback:n}=this.options,i=e.reduce((c,a)=>{let d=this._createNativeMethod(a,this._willMethodThrowOnError(a),o,n);return this[a]=d,B(u({},c),{[a]:d})},{});this.loose=this._createLoose(i),this.store=W(this._emitter,i,r),this.isWebViewBridgeAvailable=!!window.ReactNativeWebView&&e.length>0,document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&this._postMessage("getBridgeState")}),this._postMessage("getBridgeState");for(let[c,...a]of(s=window.nativeBatchedEvents)!=null?s:[])this._emitter.emit(c,...a);return window.nativeBatchedEvents=[],!0}};var S=(t={timeout:2e3,throwOnError:!1})=>{var a,d;if(typeof window=="undefined")return{store:{getState:()=>({}),subscribe:V}};window.ReactNativeWebView||console.warn("[WebViewBridge] Not in a WebView environment");let e=y();window.nativeEmitter||(window.nativeEmitter=e);let r=(a=window.__bridgeMethods__)!=null?a:[],o=(d=window.__bridgeInitialState__)!=null?d:{},n=new h(t,e,r,o);if(r.length===0){let g=e.on("hydrate",({bridgeMethods:l,nativeInitialState:v})=>{n._hydrate(l,v),g()})}let{onFallback:i,onReady:s}=t,c=new Proxy(n,{get:(g,l,v)=>l in g?g[l]:(v._postMessage("fallback",{method:l}),v._willMethodThrowOnError(l)?(...j)=>(i==null||i(l,j),Promise.reject(new f(l))):(console.warn(`[WebViewBridge] ${l} is not defined, using fallback.`),()=>Promise.resolve()))});return s==null||s(c),c};var H=(t={timeout:2e3,throwOnError:!1})=>S(t);var q=t=>{if(typeof window!="undefined"&&!window.ReactNativeWebView)return console.warn("[WebViewBridge] Not in a WebView environment"),t;let e=Object.entries(t),r=Object.keys(t),o=y();window.webEmitter=o;for(let[i,s]of e){let c=(a,d)=>O(void 0,null,function*(){var g,l;try{let v=yield s(...d);(g=window.ReactNativeWebView)==null||g.postMessage(JSON.stringify({type:"webMethodResponse",body:{funcName:i,eventId:a,value:v}}))}catch(v){(l=window.ReactNativeWebView)==null||l.postMessage(JSON.stringify({type:"webMethodError",body:{funcName:i,eventId:a,error:JSON.stringify(v)}}))}});o.on(i,c)}let n=()=>{var i;(i=window.ReactNativeWebView)==null||i.postMessage(JSON.stringify({type:"registerWebMethod",body:{bridgeNames:r}})),window.removeEventListener("DOMContentLoaded",n)};return window.ReactNativeWebView?(document.addEventListener("visibilitychange",()=>{var i;document.visibilityState==="visible"&&((i=window.ReactNativeWebView)==null||i.postMessage(JSON.stringify({type:"registerWebMethod",body:{bridgeNames:r}})))}),n(),t):(window.addEventListener("DOMContentLoaded",n),t)};0&&(module.exports={MethodNotFoundError,NativeMethodError,linkBridge,linkNativeMethod,registerWebMethod});
|
package/dist/module/index.mjs
CHANGED
|
@@ -1,457 +1 @@
|
|
|
1
|
-
var
|
|
2
|
-
var __defProps = Object.defineProperties;
|
|
3
|
-
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
4
|
-
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
7
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
8
|
-
var __spreadValues = (a, b) => {
|
|
9
|
-
for (var prop in b || (b = {}))
|
|
10
|
-
if (__hasOwnProp.call(b, prop))
|
|
11
|
-
__defNormalProp(a, prop, b[prop]);
|
|
12
|
-
if (__getOwnPropSymbols)
|
|
13
|
-
for (var prop of __getOwnPropSymbols(b)) {
|
|
14
|
-
if (__propIsEnum.call(b, prop))
|
|
15
|
-
__defNormalProp(a, prop, b[prop]);
|
|
16
|
-
}
|
|
17
|
-
return a;
|
|
18
|
-
};
|
|
19
|
-
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
20
|
-
var __async = (__this, __arguments, generator) => {
|
|
21
|
-
return new Promise((resolve, reject) => {
|
|
22
|
-
var fulfilled = (value) => {
|
|
23
|
-
try {
|
|
24
|
-
step(generator.next(value));
|
|
25
|
-
} catch (e) {
|
|
26
|
-
reject(e);
|
|
27
|
-
}
|
|
28
|
-
};
|
|
29
|
-
var rejected = (value) => {
|
|
30
|
-
try {
|
|
31
|
-
step(generator.throw(value));
|
|
32
|
-
} catch (e) {
|
|
33
|
-
reject(e);
|
|
34
|
-
}
|
|
35
|
-
};
|
|
36
|
-
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
37
|
-
step((generator = generator.apply(__this, __arguments)).next());
|
|
38
|
-
});
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
// src/error.ts
|
|
42
|
-
var MethodNotFoundError = class extends Error {
|
|
43
|
-
constructor(methodName) {
|
|
44
|
-
super(`Method ${methodName} is not defined`);
|
|
45
|
-
this.name = "MethodNotFoundError";
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
var NativeMethodError = class extends Error {
|
|
49
|
-
constructor(methodName) {
|
|
50
|
-
super(`An error occurred in the native bridge: ${methodName}`);
|
|
51
|
-
this.name = "NativeMethodError";
|
|
52
|
-
}
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
// ../../shared/util/src/createEvents.ts
|
|
56
|
-
var createEvents = () => ({
|
|
57
|
-
events: {},
|
|
58
|
-
emit(event, ...args) {
|
|
59
|
-
const callbacks = this.events[event] || [];
|
|
60
|
-
for (let i = 0, length = callbacks.length; i < length; i++) {
|
|
61
|
-
callbacks[i](...args);
|
|
62
|
-
}
|
|
63
|
-
},
|
|
64
|
-
on(event, cb) {
|
|
65
|
-
var _a;
|
|
66
|
-
((_a = this.events[event]) == null ? void 0 : _a.push(cb)) || (this.events[event] = [cb]);
|
|
67
|
-
return () => {
|
|
68
|
-
var _a2;
|
|
69
|
-
this.events[event] = (_a2 = this.events[event]) == null ? void 0 : _a2.filter((i) => cb !== i);
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
});
|
|
73
|
-
var createResolver = ({
|
|
74
|
-
emitter: emitter2,
|
|
75
|
-
evaluate,
|
|
76
|
-
eventId,
|
|
77
|
-
failHandler = false,
|
|
78
|
-
methodName,
|
|
79
|
-
onFallback
|
|
80
|
-
}) => {
|
|
81
|
-
return new Promise((resolve, reject) => {
|
|
82
|
-
const unbind = emitter2.on(
|
|
83
|
-
`${methodName}-${eventId}`,
|
|
84
|
-
(data, throwOccurred) => {
|
|
85
|
-
unbind();
|
|
86
|
-
if (throwOccurred) {
|
|
87
|
-
if (failHandler instanceof Error) {
|
|
88
|
-
onFallback == null ? void 0 : onFallback();
|
|
89
|
-
reject(failHandler);
|
|
90
|
-
} else {
|
|
91
|
-
resolve(void 0);
|
|
92
|
-
}
|
|
93
|
-
} else {
|
|
94
|
-
resolve(data);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
);
|
|
98
|
-
evaluate();
|
|
99
|
-
});
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
// ../../shared/util/src/createRandomId.tsx
|
|
103
|
-
var TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
104
|
-
var ID_LENGTH = 21;
|
|
105
|
-
var createRandomId = (size = ID_LENGTH) => {
|
|
106
|
-
const randomValues = Array.from(
|
|
107
|
-
{ length: size },
|
|
108
|
-
() => TABLE[Math.floor(Math.random() * TABLE.length)]
|
|
109
|
-
);
|
|
110
|
-
return randomValues.join("");
|
|
111
|
-
};
|
|
112
|
-
|
|
113
|
-
// ../../shared/util/src/equals.ts
|
|
114
|
-
var equals = (a, b) => {
|
|
115
|
-
if (a === b) {
|
|
116
|
-
return true;
|
|
117
|
-
}
|
|
118
|
-
if (a && b && typeof a === "object" && typeof b === "object") {
|
|
119
|
-
const arrA = Array.isArray(a);
|
|
120
|
-
const arrB = Array.isArray(b);
|
|
121
|
-
let i;
|
|
122
|
-
let length;
|
|
123
|
-
let key;
|
|
124
|
-
if (arrA && arrB) {
|
|
125
|
-
length = a.length;
|
|
126
|
-
if (length !== b.length) {
|
|
127
|
-
return false;
|
|
128
|
-
}
|
|
129
|
-
for (i = length; i-- !== 0; ) {
|
|
130
|
-
if (!equals(a[i], b[i])) {
|
|
131
|
-
return false;
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
return true;
|
|
135
|
-
}
|
|
136
|
-
if (arrA !== arrB) {
|
|
137
|
-
return false;
|
|
138
|
-
}
|
|
139
|
-
const keys = Object.keys(a);
|
|
140
|
-
length = keys.length;
|
|
141
|
-
if (length !== Object.keys(b).length) {
|
|
142
|
-
return false;
|
|
143
|
-
}
|
|
144
|
-
for (i = length; i-- !== 0; ) {
|
|
145
|
-
if (!Object.prototype.hasOwnProperty.call(b, keys[i])) {
|
|
146
|
-
return false;
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
for (i = length; i-- !== 0; ) {
|
|
150
|
-
key = keys[i];
|
|
151
|
-
if (!equals(a[key], b[key])) {
|
|
152
|
-
return false;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
return true;
|
|
156
|
-
}
|
|
157
|
-
return a !== a && b !== b;
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
// ../../shared/util/src/noop.ts
|
|
161
|
-
var noop = () => {
|
|
162
|
-
};
|
|
163
|
-
|
|
164
|
-
// ../../shared/util/src/removeUndefinedKeys.tsx
|
|
165
|
-
var removeUndefinedKeys = (obj) => {
|
|
166
|
-
Object.keys(obj).forEach((key) => {
|
|
167
|
-
if (obj[key] === void 0) {
|
|
168
|
-
delete obj[key];
|
|
169
|
-
}
|
|
170
|
-
});
|
|
171
|
-
return obj;
|
|
172
|
-
};
|
|
173
|
-
|
|
174
|
-
// ../../shared/util/src/timeout.ts
|
|
175
|
-
var timeout = (ms, throwOnError = true) => {
|
|
176
|
-
return new Promise((resolve, reject) => {
|
|
177
|
-
setTimeout(() => {
|
|
178
|
-
if (throwOnError) {
|
|
179
|
-
reject(new Error("Timeout"));
|
|
180
|
-
} else {
|
|
181
|
-
resolve(void 0);
|
|
182
|
-
}
|
|
183
|
-
}, ms);
|
|
184
|
-
});
|
|
185
|
-
};
|
|
186
|
-
|
|
187
|
-
// src/internal/emitter.ts
|
|
188
|
-
var emitter = createEvents();
|
|
189
|
-
|
|
190
|
-
// src/internal/linkBridgeStore.ts
|
|
191
|
-
var linkBridgeStore = (initialState = {}) => {
|
|
192
|
-
var _a;
|
|
193
|
-
if (!window.ReactNativeWebView) {
|
|
194
|
-
console.warn("[WebViewBridge] Not in a WebView environment");
|
|
195
|
-
}
|
|
196
|
-
if (!window.nativeEmitter) {
|
|
197
|
-
window.nativeEmitter = emitter;
|
|
198
|
-
}
|
|
199
|
-
const getState = () => state;
|
|
200
|
-
const setState = (newState) => {
|
|
201
|
-
const _newState = __spreadValues(__spreadValues({}, state), removeUndefinedKeys(newState));
|
|
202
|
-
if (equals(state, _newState)) {
|
|
203
|
-
return;
|
|
204
|
-
}
|
|
205
|
-
const prevState = state;
|
|
206
|
-
state = _newState;
|
|
207
|
-
emitChange(state, prevState);
|
|
208
|
-
};
|
|
209
|
-
emitter.on("bridgeStateChange", (data) => {
|
|
210
|
-
setState(data);
|
|
211
|
-
});
|
|
212
|
-
document.addEventListener("visibilitychange", () => {
|
|
213
|
-
var _a2;
|
|
214
|
-
if (document.visibilityState === "visible") {
|
|
215
|
-
(_a2 = window.ReactNativeWebView) == null ? void 0 : _a2.postMessage(
|
|
216
|
-
JSON.stringify({
|
|
217
|
-
type: "getBridgeState"
|
|
218
|
-
})
|
|
219
|
-
);
|
|
220
|
-
}
|
|
221
|
-
});
|
|
222
|
-
(_a = window.ReactNativeWebView) == null ? void 0 : _a.postMessage(
|
|
223
|
-
JSON.stringify({
|
|
224
|
-
type: "getBridgeState"
|
|
225
|
-
})
|
|
226
|
-
);
|
|
227
|
-
let state = __spreadValues(__spreadValues({}, initialState), window.__bridgeInitialState__);
|
|
228
|
-
const listeners = /* @__PURE__ */ new Set();
|
|
229
|
-
const emitChange = (newState, prevState) => {
|
|
230
|
-
for (const listener of listeners) {
|
|
231
|
-
listener(newState, prevState);
|
|
232
|
-
}
|
|
233
|
-
};
|
|
234
|
-
const subscribe = (listener) => {
|
|
235
|
-
listeners.add(listener);
|
|
236
|
-
return () => listeners.delete(listener);
|
|
237
|
-
};
|
|
238
|
-
return {
|
|
239
|
-
getState,
|
|
240
|
-
subscribe
|
|
241
|
-
};
|
|
242
|
-
};
|
|
243
|
-
|
|
244
|
-
// src/linkBridge.ts
|
|
245
|
-
var createNativeMethod = ({
|
|
246
|
-
methodName,
|
|
247
|
-
throwOnError,
|
|
248
|
-
timeoutMs,
|
|
249
|
-
onFallback
|
|
250
|
-
}) => (...args) => {
|
|
251
|
-
const eventId = createRandomId();
|
|
252
|
-
return Promise.race(
|
|
253
|
-
[
|
|
254
|
-
createResolver({
|
|
255
|
-
emitter,
|
|
256
|
-
methodName,
|
|
257
|
-
eventId,
|
|
258
|
-
evaluate: () => {
|
|
259
|
-
var _a;
|
|
260
|
-
(_a = window.ReactNativeWebView) == null ? void 0 : _a.postMessage(
|
|
261
|
-
JSON.stringify({
|
|
262
|
-
type: "bridge",
|
|
263
|
-
body: {
|
|
264
|
-
method: methodName,
|
|
265
|
-
eventId,
|
|
266
|
-
args
|
|
267
|
-
}
|
|
268
|
-
})
|
|
269
|
-
);
|
|
270
|
-
},
|
|
271
|
-
onFallback: () => {
|
|
272
|
-
onFallback == null ? void 0 : onFallback(methodName, args);
|
|
273
|
-
},
|
|
274
|
-
failHandler: throwOnError && new NativeMethodError(methodName)
|
|
275
|
-
}),
|
|
276
|
-
timeoutMs > 0 && timeout(timeoutMs, throwOnError)
|
|
277
|
-
].filter(Boolean)
|
|
278
|
-
);
|
|
279
|
-
};
|
|
280
|
-
var linkBridge = (options = {
|
|
281
|
-
timeout: 2e3,
|
|
282
|
-
throwOnError: false
|
|
283
|
-
}) => {
|
|
284
|
-
var _a, _b;
|
|
285
|
-
if (typeof window === "undefined") {
|
|
286
|
-
return {
|
|
287
|
-
store: {
|
|
288
|
-
getState: () => ({}),
|
|
289
|
-
subscribe: noop
|
|
290
|
-
}
|
|
291
|
-
};
|
|
292
|
-
}
|
|
293
|
-
const {
|
|
294
|
-
timeout: timeoutMs = 2e3,
|
|
295
|
-
throwOnError = false,
|
|
296
|
-
onFallback,
|
|
297
|
-
onReady
|
|
298
|
-
} = options;
|
|
299
|
-
if (!window.ReactNativeWebView) {
|
|
300
|
-
console.warn("[WebViewBridge] Not in a WebView environment");
|
|
301
|
-
}
|
|
302
|
-
const bridgeMethods = (_a = window.__bridgeMethods__) != null ? _a : [];
|
|
303
|
-
if (!window.nativeEmitter) {
|
|
304
|
-
window.nativeEmitter = emitter;
|
|
305
|
-
}
|
|
306
|
-
const willMethodThrowOnError = (methodName) => {
|
|
307
|
-
return throwOnError === true || Array.isArray(throwOnError) && throwOnError.includes(methodName);
|
|
308
|
-
};
|
|
309
|
-
const target = bridgeMethods.reduce(
|
|
310
|
-
(acc, methodName) => {
|
|
311
|
-
return __spreadProps(__spreadValues({}, acc), {
|
|
312
|
-
[methodName]: createNativeMethod({
|
|
313
|
-
methodName,
|
|
314
|
-
timeoutMs,
|
|
315
|
-
throwOnError: willMethodThrowOnError(methodName),
|
|
316
|
-
onFallback
|
|
317
|
-
})
|
|
318
|
-
});
|
|
319
|
-
},
|
|
320
|
-
{}
|
|
321
|
-
);
|
|
322
|
-
const loose = new Proxy(target, {
|
|
323
|
-
get: (target2, methodName) => {
|
|
324
|
-
if (methodName in target2 && !["isWebViewBridgeAvailable", "isNativeMethodAvailable"].includes(
|
|
325
|
-
methodName
|
|
326
|
-
)) {
|
|
327
|
-
return target2[methodName];
|
|
328
|
-
}
|
|
329
|
-
return createNativeMethod({
|
|
330
|
-
methodName,
|
|
331
|
-
timeoutMs,
|
|
332
|
-
throwOnError: willMethodThrowOnError(methodName),
|
|
333
|
-
onFallback
|
|
334
|
-
});
|
|
335
|
-
}
|
|
336
|
-
});
|
|
337
|
-
Object.assign(target, {
|
|
338
|
-
loose,
|
|
339
|
-
store: linkBridgeStore(target),
|
|
340
|
-
isWebViewBridgeAvailable: Boolean(window.ReactNativeWebView) && bridgeMethods.length > 0,
|
|
341
|
-
isNativeMethodAvailable(methodName) {
|
|
342
|
-
return typeof methodName === "string" && Boolean(window.ReactNativeWebView) && bridgeMethods.includes(methodName);
|
|
343
|
-
},
|
|
344
|
-
addEventListener: (eventName, listener) => {
|
|
345
|
-
return emitter.on(`postMessage/${String(eventName)}`, listener);
|
|
346
|
-
}
|
|
347
|
-
});
|
|
348
|
-
const proxy = new Proxy(target, {
|
|
349
|
-
get: (target2, methodName) => {
|
|
350
|
-
var _a2;
|
|
351
|
-
if (methodName in target2) {
|
|
352
|
-
return target2[methodName];
|
|
353
|
-
}
|
|
354
|
-
(_a2 = window.ReactNativeWebView) == null ? void 0 : _a2.postMessage(
|
|
355
|
-
JSON.stringify({
|
|
356
|
-
type: "fallback",
|
|
357
|
-
body: {
|
|
358
|
-
method: methodName
|
|
359
|
-
}
|
|
360
|
-
})
|
|
361
|
-
);
|
|
362
|
-
if (willMethodThrowOnError(methodName)) {
|
|
363
|
-
return (...args) => {
|
|
364
|
-
onFallback == null ? void 0 : onFallback(methodName, args);
|
|
365
|
-
Promise.reject(new MethodNotFoundError(methodName));
|
|
366
|
-
};
|
|
367
|
-
} else {
|
|
368
|
-
console.warn(
|
|
369
|
-
`[WebViewBridge] ${methodName} is not defined, using fallback.`
|
|
370
|
-
);
|
|
371
|
-
}
|
|
372
|
-
return () => Promise.resolve();
|
|
373
|
-
}
|
|
374
|
-
});
|
|
375
|
-
for (const [eventName, ...args] of (_b = window.nativeBatchedEvents) != null ? _b : []) {
|
|
376
|
-
emitter.emit(eventName, ...args);
|
|
377
|
-
}
|
|
378
|
-
window.nativeBatchedEvents = [];
|
|
379
|
-
onReady == null ? void 0 : onReady(proxy);
|
|
380
|
-
return proxy;
|
|
381
|
-
};
|
|
382
|
-
|
|
383
|
-
// src/linkNativeMethod.ts
|
|
384
|
-
var linkNativeMethod = (options = {
|
|
385
|
-
timeout: 2e3,
|
|
386
|
-
throwOnError: false
|
|
387
|
-
}) => {
|
|
388
|
-
return linkBridge(options);
|
|
389
|
-
};
|
|
390
|
-
|
|
391
|
-
// src/registerWebMethod.ts
|
|
392
|
-
var registerWebMethod = (bridge) => {
|
|
393
|
-
if (typeof window !== "undefined" && !window.ReactNativeWebView) {
|
|
394
|
-
console.warn("[WebViewBridge] Not in a WebView environment");
|
|
395
|
-
return bridge;
|
|
396
|
-
}
|
|
397
|
-
const bridgeEntries = Object.entries(bridge);
|
|
398
|
-
const bridgeNames = Object.keys(bridge);
|
|
399
|
-
const emitter2 = createEvents();
|
|
400
|
-
window.webEmitter = emitter2;
|
|
401
|
-
for (const [funcName, func] of bridgeEntries) {
|
|
402
|
-
const $func = (eventId, args) => __async(void 0, null, function* () {
|
|
403
|
-
var _a, _b;
|
|
404
|
-
try {
|
|
405
|
-
const value = yield func(...args);
|
|
406
|
-
(_a = window.ReactNativeWebView) == null ? void 0 : _a.postMessage(
|
|
407
|
-
JSON.stringify({
|
|
408
|
-
type: "webMethodResponse",
|
|
409
|
-
body: { funcName, eventId, value }
|
|
410
|
-
})
|
|
411
|
-
);
|
|
412
|
-
} catch (e) {
|
|
413
|
-
(_b = window.ReactNativeWebView) == null ? void 0 : _b.postMessage(
|
|
414
|
-
JSON.stringify({
|
|
415
|
-
type: "webMethodError",
|
|
416
|
-
body: { funcName, eventId, error: JSON.stringify(e) }
|
|
417
|
-
})
|
|
418
|
-
);
|
|
419
|
-
}
|
|
420
|
-
});
|
|
421
|
-
emitter2.on(funcName, $func);
|
|
422
|
-
}
|
|
423
|
-
const register = () => {
|
|
424
|
-
var _a;
|
|
425
|
-
(_a = window.ReactNativeWebView) == null ? void 0 : _a.postMessage(
|
|
426
|
-
JSON.stringify({
|
|
427
|
-
type: "registerWebMethod",
|
|
428
|
-
body: { bridgeNames }
|
|
429
|
-
})
|
|
430
|
-
);
|
|
431
|
-
window.removeEventListener("DOMContentLoaded", register);
|
|
432
|
-
};
|
|
433
|
-
if (!window.ReactNativeWebView) {
|
|
434
|
-
window.addEventListener("DOMContentLoaded", register);
|
|
435
|
-
return bridge;
|
|
436
|
-
}
|
|
437
|
-
document.addEventListener("visibilitychange", () => {
|
|
438
|
-
var _a;
|
|
439
|
-
if (document.visibilityState === "visible") {
|
|
440
|
-
(_a = window.ReactNativeWebView) == null ? void 0 : _a.postMessage(
|
|
441
|
-
JSON.stringify({
|
|
442
|
-
type: "registerWebMethod",
|
|
443
|
-
body: { bridgeNames }
|
|
444
|
-
})
|
|
445
|
-
);
|
|
446
|
-
}
|
|
447
|
-
});
|
|
448
|
-
register();
|
|
449
|
-
return bridge;
|
|
450
|
-
};
|
|
451
|
-
export {
|
|
452
|
-
MethodNotFoundError,
|
|
453
|
-
NativeMethodError,
|
|
454
|
-
linkBridge,
|
|
455
|
-
linkNativeMethod,
|
|
456
|
-
registerWebMethod
|
|
457
|
-
};
|
|
1
|
+
var W=Object.defineProperty,j=Object.defineProperties;var R=Object.getOwnPropertyDescriptors;var x=Object.getOwnPropertySymbols;var A=Object.prototype.hasOwnProperty,D=Object.prototype.propertyIsEnumerable;var h=(t,e,r)=>e in t?W(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r,u=(t,e)=>{for(var r in e||(e={}))A.call(e,r)&&h(t,r,e[r]);if(x)for(var r of x(e))D.call(e,r)&&h(t,r,e[r]);return t},S=(t,e)=>j(t,R(e));var m=(t,e,r)=>(h(t,typeof e!="symbol"?e+"":e,r),r);var b=(t,e,r)=>new Promise((o,n)=>{var i=a=>{try{c(r.next(a))}catch(d){n(d)}},s=a=>{try{c(r.throw(a))}catch(d){n(d)}},c=a=>a.done?o(a.value):Promise.resolve(a.value).then(i,s);c((r=r.apply(t,e)).next())});var f=class extends Error{constructor(e){super(`Method ${e} is not defined`),this.name="MethodNotFoundError"}},p=class extends Error{constructor(e){super(`An error occurred in the native bridge: ${e}`),this.name="NativeMethodError"}};var w=()=>({events:{},emit(t,...e){let r=this.events[t]||[];for(let o=0,n=r.length;o<n;o++)r[o](...e)},on(t,e){var r;return(r=this.events[t])!=null&&r.push(e)||(this.events[t]=[e]),()=>{var o;this.events[t]=(o=this.events[t])==null?void 0:o.filter(n=>e!==n)}}}),T=({emitter:t,evaluate:e,eventId:r,failHandler:o=!1,methodName:n,onFallback:i})=>new Promise((s,c)=>{let a=t.on(`${n}-${r}`,(d,g)=>{a(),g?o instanceof Error?(i==null||i(),c(o)):s(void 0):s(d)});e()});var B="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";var O=(t=21)=>Array.from({length:t},()=>B[Math.floor(Math.random()*B.length)]).join("");var y=(t,e)=>{if(t===e)return!0;if(t&&e&&typeof t=="object"&&typeof e=="object"){let r=Array.isArray(t),o=Array.isArray(e),n,i,s;if(r&&o){if(i=t.length,i!==e.length)return!1;for(n=i;n--!==0;)if(!y(t[n],e[n]))return!1;return!0}if(r!==o)return!1;let c=Object.keys(t);if(i=c.length,i!==Object.keys(e).length)return!1;for(n=i;n--!==0;)if(!Object.prototype.hasOwnProperty.call(e,c[n]))return!1;for(n=i;n--!==0;)if(s=c[n],!y(t[s],e[s]))return!1;return!0}return t!==t&&e!==e};var P=()=>{};var M=t=>(Object.keys(t).forEach(e=>{t[e]===void 0&&delete t[e]}),t);var k=(t,e=!0)=>new Promise((r,o)=>{setTimeout(()=>{e?o(new Error("Timeout")):r(void 0)},t)});var V=()=>new Proxy({},{get:()=>()=>Promise.resolve()});var _=(t,e={},r={})=>{let o=()=>i,n=d=>{let g=u(u({},i),M(d));if(y(i,g))return;let l=i;i=g,c(i,l)};t.on("bridgeStateChange",d=>{n(d)});let i=u(u({},e),r),s=new Set,c=(d,g)=>{for(let l of s)l(d,g)};return{getState:o,subscribe:d=>(s.add(d),()=>s.delete(d))}};var E=class{constructor(e,r,o,n){this.options=e;this._emitter=r;this._bridgeMethods=o;this._nativeInitialState=n;m(this,"defaultTimeoutMs",2e3);m(this,"store",{});m(this,"isWebViewBridgeAvailable",!!window.ReactNativeWebView);m(this,"loose",V());this._hydrate(o,n)}isNativeMethodAvailable(e){return typeof e=="string"&&!!window.ReactNativeWebView&&this._bridgeMethods.includes(e)}addEventListener(e,r){return this._emitter.on(`postMessage/${String(e)}`,r)}_postMessage(e,r){var o;(o=window.ReactNativeWebView)==null||o.postMessage(JSON.stringify(r?{type:e,body:r}:{type:e}))}_createNativeMethod(e,r,o,n){return(...i)=>{let s=O();return Promise.race([T({emitter:this._emitter,methodName:e,eventId:s,evaluate:()=>{this._postMessage("bridge",{method:e,eventId:s,args:i})},onFallback:()=>{n==null||n(e,i)},failHandler:r&&new p(e)}),o>0&&k(o,r)].filter(Boolean))}}_willMethodThrowOnError(e){let{throwOnError:r}=this.options;return r===!0||Array.isArray(r)&&r.includes(e)}_createLoose(e){let{timeout:r=this.defaultTimeoutMs,onFallback:o}=this.options;return new Proxy(e,{get:(n,i)=>i in n&&!["isWebViewBridgeAvailable","isNativeMethodAvailable"].includes(i)?n[i]:this._createNativeMethod(i,this._willMethodThrowOnError(i),r,o)})}_hydrate(e,r={}){var s;if(this._bridgeMethods=e,this._nativeInitialState=r,e.length===0)return!1;let{timeout:o=this.defaultTimeoutMs,onFallback:n}=this.options,i=e.reduce((c,a)=>{let d=this._createNativeMethod(a,this._willMethodThrowOnError(a),o,n);return this[a]=d,S(u({},c),{[a]:d})},{});this.loose=this._createLoose(i),this.store=_(this._emitter,i,r),this.isWebViewBridgeAvailable=!!window.ReactNativeWebView&&e.length>0,document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&this._postMessage("getBridgeState")}),this._postMessage("getBridgeState");for(let[c,...a]of(s=window.nativeBatchedEvents)!=null?s:[])this._emitter.emit(c,...a);return window.nativeBatchedEvents=[],!0}};var L=(t={timeout:2e3,throwOnError:!1})=>{var a,d;if(typeof window=="undefined")return{store:{getState:()=>({}),subscribe:P}};window.ReactNativeWebView||console.warn("[WebViewBridge] Not in a WebView environment");let e=w();window.nativeEmitter||(window.nativeEmitter=e);let r=(a=window.__bridgeMethods__)!=null?a:[],o=(d=window.__bridgeInitialState__)!=null?d:{},n=new E(t,e,r,o);if(r.length===0){let g=e.on("hydrate",({bridgeMethods:l,nativeInitialState:v})=>{n._hydrate(l,v),g()})}let{onFallback:i,onReady:s}=t,c=new Proxy(n,{get:(g,l,v)=>l in g?g[l]:(v._postMessage("fallback",{method:l}),v._willMethodThrowOnError(l)?(...N)=>(i==null||i(l,N),Promise.reject(new f(l))):(console.warn(`[WebViewBridge] ${l} is not defined, using fallback.`),()=>Promise.resolve()))});return s==null||s(c),c};var ye=(t={timeout:2e3,throwOnError:!1})=>L(t);var xe=t=>{if(typeof window!="undefined"&&!window.ReactNativeWebView)return console.warn("[WebViewBridge] Not in a WebView environment"),t;let e=Object.entries(t),r=Object.keys(t),o=w();window.webEmitter=o;for(let[i,s]of e){let c=(a,d)=>b(void 0,null,function*(){var g,l;try{let v=yield s(...d);(g=window.ReactNativeWebView)==null||g.postMessage(JSON.stringify({type:"webMethodResponse",body:{funcName:i,eventId:a,value:v}}))}catch(v){(l=window.ReactNativeWebView)==null||l.postMessage(JSON.stringify({type:"webMethodError",body:{funcName:i,eventId:a,error:JSON.stringify(v)}}))}});o.on(i,c)}let n=()=>{var i;(i=window.ReactNativeWebView)==null||i.postMessage(JSON.stringify({type:"registerWebMethod",body:{bridgeNames:r}})),window.removeEventListener("DOMContentLoaded",n)};return window.ReactNativeWebView?(document.addEventListener("visibilitychange",()=>{var i;document.visibilityState==="visible"&&((i=window.ReactNativeWebView)==null||i.postMessage(JSON.stringify({type:"registerWebMethod",body:{bridgeNames:r}})))}),n(),t):(window.addEventListener("DOMContentLoaded",n),t)};export{f as MethodNotFoundError,p as NativeMethodError,L as linkBridge,ye as linkNativeMethod,xe as registerWebMethod};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Bridge, BridgeStore, ExtractStore, KeyOfOrString, Parser, ParserSchema, PrimitiveObject } from "../../../../shared/util/src/types";
|
|
2
|
+
import { DefaultEmitter } from "../../../../shared/util/src";
|
|
3
|
+
import { LinkBridgeOptions } from "../linkBridge";
|
|
4
|
+
import { LinkBridge } from "../types";
|
|
5
|
+
export declare class BridgeInstance<T extends BridgeStore<T extends Bridge ? T : any>, V extends ParserSchema<any> = ParserSchema<any>> {
|
|
6
|
+
private options;
|
|
7
|
+
private _emitter;
|
|
8
|
+
private _bridgeMethods;
|
|
9
|
+
_nativeInitialState: PrimitiveObject;
|
|
10
|
+
constructor(options: LinkBridgeOptions<T, V>, _emitter: DefaultEmitter, _bridgeMethods: string[], _nativeInitialState: PrimitiveObject);
|
|
11
|
+
private defaultTimeoutMs;
|
|
12
|
+
store: Omit<T, "setState">;
|
|
13
|
+
isWebViewBridgeAvailable: boolean;
|
|
14
|
+
isNativeMethodAvailable(methodName: string): boolean;
|
|
15
|
+
addEventListener<EventName extends KeyOfOrString<V>>(eventName: EventName, listener: (args: Parser<V, EventName>) => void): () => void;
|
|
16
|
+
loose: LinkBridge<ExtractStore<T>, Omit<T, "setState">, V>;
|
|
17
|
+
private _postMessage;
|
|
18
|
+
private _createNativeMethod;
|
|
19
|
+
private _willMethodThrowOnError;
|
|
20
|
+
private _createLoose;
|
|
21
|
+
_hydrate(bridgeMethods: string[], nativeInitialState?: PrimitiveObject): boolean;
|
|
22
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const createPromiseProxy: () => {};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Bridge, BridgeStore, OnlyJSON } from "../../../../shared/util/src/types";
|
|
2
|
+
import { DefaultEmitter } from "../../../../shared/util/src";
|
|
2
3
|
export type Store<BridgeObject extends Bridge> = ({ get, set, }: {
|
|
3
4
|
get: () => BridgeObject;
|
|
4
5
|
set: (newState: Partial<OnlyJSON<BridgeObject>>) => void;
|
|
5
6
|
}) => BridgeObject;
|
|
6
|
-
export declare const linkBridgeStore: <T extends BridgeStore<T extends Bridge ? T : any>>(initialState?: Partial<T>) => Omit<T, "setState">;
|
|
7
|
+
export declare const linkBridgeStore: <T extends BridgeStore<T extends Bridge ? T : any>>(emitter: DefaultEmitter, initialState?: Partial<T>, nativeInitialState?: Partial<T>) => Omit<T, "setState">;
|
|
@@ -11,9 +11,10 @@ export interface EventEmitter<Events extends EventsMap = DefaultEvents> {
|
|
|
11
11
|
}>;
|
|
12
12
|
on<K extends keyof Events>(this: this, event: K, cb: Events[K]): () => void;
|
|
13
13
|
}
|
|
14
|
+
export type DefaultEmitter = EventEmitter<DefaultEvents>;
|
|
14
15
|
export declare const createEvents: <Events extends EventsMap = DefaultEvents>() => EventEmitter<Events>;
|
|
15
16
|
export interface CreateResolverOptions {
|
|
16
|
-
emitter:
|
|
17
|
+
emitter: DefaultEmitter;
|
|
17
18
|
evaluate: () => void;
|
|
18
19
|
eventId: string;
|
|
19
20
|
failHandler?: Error | false;
|
|
@@ -3,6 +3,7 @@ import type { AnySchema as YupTypeAny, InferType as yupInfer } from "yup";
|
|
|
3
3
|
import type { infer as zodInfer, ZodTypeAny } from "zod";
|
|
4
4
|
export type AsyncFunction = (...args: any[]) => Promise<any>;
|
|
5
5
|
export type Primitive = string | number | boolean | null | undefined;
|
|
6
|
+
export type PrimitiveObject = Record<string, Primitive>;
|
|
6
7
|
export type RawJSON = Primitive | {
|
|
7
8
|
[key: string]: RawJSON;
|
|
8
9
|
} | RawJSONArray;
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const emitter: import("../../../../shared/util/src").EventEmitter<import("../../../../shared/util/src").DefaultEvents>;
|