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