@webview-bridge/web 1.5.1-rc.0 → 1.5.1-rc.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.
@@ -33,6 +33,10 @@ var __copyProps = (to, from, except, desc) => {
33
33
  return to;
34
34
  };
35
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
+ };
36
40
  var __async = (__this, __arguments, generator) => {
37
41
  return new Promise((resolve, reject) => {
38
42
  var fulfilled = (value) => {
@@ -98,7 +102,7 @@ var createEvents = () => ({
98
102
  }
99
103
  });
100
104
  var createResolver = ({
101
- emitter: emitter2,
105
+ emitter,
102
106
  evaluate,
103
107
  eventId,
104
108
  failHandler = false,
@@ -106,7 +110,7 @@ var createResolver = ({
106
110
  onFallback
107
111
  }) => {
108
112
  return new Promise((resolve, reject) => {
109
- const unbind = emitter2.on(
113
+ const unbind = emitter.on(
110
114
  `${methodName}-${eventId}`,
111
115
  (data, throwOccurred) => {
112
116
  unbind();
@@ -211,18 +215,8 @@ var timeout = (ms, throwOnError = true) => {
211
215
  });
212
216
  };
213
217
 
214
- // src/internal/emitter.ts
215
- var emitter = createEvents();
216
-
217
218
  // 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
- }
219
+ var linkBridgeStore = (emitter, initialState = {}, nativeInitialState = {}) => {
226
220
  const getState = () => state;
227
221
  const setState = (newState) => {
228
222
  const _newState = __spreadValues(__spreadValues({}, state), removeUndefinedKeys(newState));
@@ -236,22 +230,7 @@ var linkBridgeStore = (initialState = {}) => {
236
230
  emitter.on("bridgeStateChange", (data) => {
237
231
  setState(data);
238
232
  });
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__);
233
+ let state = __spreadValues(__spreadValues({}, initialState), nativeInitialState);
255
234
  const listeners = /* @__PURE__ */ new Set();
256
235
  const emitChange = (newState, prevState) => {
257
236
  for (const listener of listeners) {
@@ -268,47 +247,160 @@ var linkBridgeStore = (initialState = {}) => {
268
247
  };
269
248
  };
270
249
 
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: {
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", {
291
284
  method: methodName,
292
285
  eventId,
293
286
  args
294
- }
295
- })
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.`
296
380
  );
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
- );
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
+ }
306
396
  };
397
+
398
+ // src/linkBridge.ts
307
399
  var linkBridge = (options = {
308
400
  timeout: 2e3,
309
401
  throwOnError: false
310
402
  }) => {
311
- var _a, _b;
403
+ var _a;
312
404
  if (typeof window === "undefined") {
313
405
  return {
314
406
  store: {
@@ -317,94 +409,23 @@ var linkBridge = (options = {
317
409
  }
318
410
  };
319
411
  }
320
- const {
321
- timeout: timeoutMs = 2e3,
322
- throwOnError = false,
323
- onFallback,
324
- onReady
325
- } = options;
326
412
  if (!window.ReactNativeWebView) {
327
413
  console.warn("[WebViewBridge] Not in a WebView environment");
328
414
  }
329
- const bridgeMethods = (_a = window.__bridgeMethods__) != null ? _a : [];
415
+ const emitter = createEvents();
330
416
  if (!window.nativeEmitter) {
331
417
  window.nativeEmitter = emitter;
332
418
  }
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);
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
+ });
404
426
  }
405
- window.nativeBatchedEvents = [];
406
- onReady == null ? void 0 : onReady(proxy);
407
- return proxy;
427
+ instance.hydrate(bridgeMethods);
428
+ return instance.proxy;
408
429
  };
409
430
 
410
431
  // src/linkNativeMethod.ts
@@ -423,8 +444,8 @@ var registerWebMethod = (bridge) => {
423
444
  }
424
445
  const bridgeEntries = Object.entries(bridge);
425
446
  const bridgeNames = Object.keys(bridge);
426
- const emitter2 = createEvents();
427
- window.webEmitter = emitter2;
447
+ const emitter = createEvents();
448
+ window.webEmitter = emitter;
428
449
  for (const [funcName, func] of bridgeEntries) {
429
450
  const $func = (eventId, args) => __async(void 0, null, function* () {
430
451
  var _a, _b;
@@ -445,7 +466,7 @@ var registerWebMethod = (bridge) => {
445
466
  );
446
467
  }
447
468
  });
448
- emitter2.on(funcName, $func);
469
+ emitter.on(funcName, $func);
449
470
  }
450
471
  const register = () => {
451
472
  var _a;
@@ -17,6 +17,10 @@ var __spreadValues = (a, b) => {
17
17
  return a;
18
18
  };
19
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
+ };
20
24
  var __async = (__this, __arguments, generator) => {
21
25
  return new Promise((resolve, reject) => {
22
26
  var fulfilled = (value) => {
@@ -71,7 +75,7 @@ var createEvents = () => ({
71
75
  }
72
76
  });
73
77
  var createResolver = ({
74
- emitter: emitter2,
78
+ emitter,
75
79
  evaluate,
76
80
  eventId,
77
81
  failHandler = false,
@@ -79,7 +83,7 @@ var createResolver = ({
79
83
  onFallback
80
84
  }) => {
81
85
  return new Promise((resolve, reject) => {
82
- const unbind = emitter2.on(
86
+ const unbind = emitter.on(
83
87
  `${methodName}-${eventId}`,
84
88
  (data, throwOccurred) => {
85
89
  unbind();
@@ -184,18 +188,8 @@ var timeout = (ms, throwOnError = true) => {
184
188
  });
185
189
  };
186
190
 
187
- // src/internal/emitter.ts
188
- var emitter = createEvents();
189
-
190
191
  // 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
- }
192
+ var linkBridgeStore = (emitter, initialState = {}, nativeInitialState = {}) => {
199
193
  const getState = () => state;
200
194
  const setState = (newState) => {
201
195
  const _newState = __spreadValues(__spreadValues({}, state), removeUndefinedKeys(newState));
@@ -209,22 +203,7 @@ var linkBridgeStore = (initialState = {}) => {
209
203
  emitter.on("bridgeStateChange", (data) => {
210
204
  setState(data);
211
205
  });
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__);
206
+ let state = __spreadValues(__spreadValues({}, initialState), nativeInitialState);
228
207
  const listeners = /* @__PURE__ */ new Set();
229
208
  const emitChange = (newState, prevState) => {
230
209
  for (const listener of listeners) {
@@ -241,47 +220,160 @@ var linkBridgeStore = (initialState = {}) => {
241
220
  };
242
221
  };
243
222
 
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: {
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", {
264
257
  method: methodName,
265
258
  eventId,
266
259
  args
267
- }
268
- })
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.`
269
353
  );
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
- );
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
+ }
279
369
  };
370
+
371
+ // src/linkBridge.ts
280
372
  var linkBridge = (options = {
281
373
  timeout: 2e3,
282
374
  throwOnError: false
283
375
  }) => {
284
- var _a, _b;
376
+ var _a;
285
377
  if (typeof window === "undefined") {
286
378
  return {
287
379
  store: {
@@ -290,94 +382,23 @@ var linkBridge = (options = {
290
382
  }
291
383
  };
292
384
  }
293
- const {
294
- timeout: timeoutMs = 2e3,
295
- throwOnError = false,
296
- onFallback,
297
- onReady
298
- } = options;
299
385
  if (!window.ReactNativeWebView) {
300
386
  console.warn("[WebViewBridge] Not in a WebView environment");
301
387
  }
302
- const bridgeMethods = (_a = window.__bridgeMethods__) != null ? _a : [];
388
+ const emitter = createEvents();
303
389
  if (!window.nativeEmitter) {
304
390
  window.nativeEmitter = emitter;
305
391
  }
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);
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
+ });
377
399
  }
378
- window.nativeBatchedEvents = [];
379
- onReady == null ? void 0 : onReady(proxy);
380
- return proxy;
400
+ instance.hydrate(bridgeMethods);
401
+ return instance.proxy;
381
402
  };
382
403
 
383
404
  // src/linkNativeMethod.ts
@@ -396,8 +417,8 @@ var registerWebMethod = (bridge) => {
396
417
  }
397
418
  const bridgeEntries = Object.entries(bridge);
398
419
  const bridgeNames = Object.keys(bridge);
399
- const emitter2 = createEvents();
400
- window.webEmitter = emitter2;
420
+ const emitter = createEvents();
421
+ window.webEmitter = emitter;
401
422
  for (const [funcName, func] of bridgeEntries) {
402
423
  const $func = (eventId, args) => __async(void 0, null, function* () {
403
424
  var _a, _b;
@@ -418,7 +439,7 @@ var registerWebMethod = (bridge) => {
418
439
  );
419
440
  }
420
441
  });
421
- emitter2.on(funcName, $func);
442
+ emitter.on(funcName, $func);
422
443
  }
423
444
  const register = () => {
424
445
  var _a;
@@ -0,0 +1,18 @@
1
+ import type { Bridge, BridgeStore, ExcludePrimitive, ExtractStore, ParserSchema } 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
+ emitter: DefaultEmitter;
7
+ bridgeMethods: string[];
8
+ private options;
9
+ private defaultTimeoutMs;
10
+ private $proxy;
11
+ constructor(emitter: DefaultEmitter, bridgeMethods: string[], options: LinkBridgeOptions<T, V>);
12
+ private postMessage;
13
+ private createNativeMethod;
14
+ private willMethodThrowOnError;
15
+ private createLoose;
16
+ hydrate(bridgeMethods: string[], nativeInitialState?: Partial<T>): LinkBridge<ExtractStore<T>, Omit<T, "setState">, V>;
17
+ get proxy(): LinkBridge<ExcludePrimitive<ExtractStore<T>>, Omit<T, "setState">, V>;
18
+ }
@@ -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: EventEmitter<DefaultEvents>;
17
+ emitter: DefaultEmitter;
17
18
  evaluate: () => void;
18
19
  eventId: string;
19
20
  failHandler?: Error | false;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@webview-bridge/web",
3
3
  "type": "module",
4
- "version": "1.5.1-rc.0",
4
+ "version": "1.5.1-rc.1",
5
5
  "description": "Fully Type-Safe Integration for React Native WebView and Web",
6
6
  "publishConfig": {
7
7
  "access": "public"