@adminide-stack/yantra-mobile 12.0.32-alpha.3 → 12.0.32-alpha.5

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.
Files changed (54) hide show
  1. package/lib/bridge/AuthenticatedFetch.js +77 -0
  2. package/lib/bridge/AuthenticatedFetch.js.map +1 -0
  3. package/lib/bridge/BridgeDebugger.js +65 -0
  4. package/lib/bridge/BridgeDebugger.js.map +1 -0
  5. package/lib/bridge/CancellableRequest.js +38 -0
  6. package/lib/bridge/CancellableRequest.js.map +1 -0
  7. package/lib/bridge/ChunkedMessageHandler.js +71 -0
  8. package/lib/bridge/ChunkedMessageHandler.js.map +1 -0
  9. package/lib/bridge/NativeWebViewBridge.js +256 -0
  10. package/lib/bridge/NativeWebViewBridge.js.map +1 -0
  11. package/lib/bridge/TypedBridge.js +8 -0
  12. package/lib/bridge/TypedBridge.js.map +1 -0
  13. package/lib/bridge/WebViewManager.js +57 -0
  14. package/lib/bridge/WebViewManager.js.map +1 -0
  15. package/lib/bridge/handlers/AnalyticsBridgeHandler.js +23 -0
  16. package/lib/bridge/handlers/AnalyticsBridgeHandler.js.map +1 -0
  17. package/lib/bridge/handlers/AuthBridgeHandler.js +49 -0
  18. package/lib/bridge/handlers/AuthBridgeHandler.js.map +1 -0
  19. package/lib/bridge/handlers/NavigationBridgeHandler.js +62 -0
  20. package/lib/bridge/handlers/NavigationBridgeHandler.js.map +1 -0
  21. package/lib/bridge/readAuth0Session.js +51 -0
  22. package/lib/bridge/readAuth0Session.js.map +1 -0
  23. package/lib/bridge/resolveMobileWebUrl.js +35 -0
  24. package/lib/bridge/resolveMobileWebUrl.js.map +1 -0
  25. package/lib/bridge/types.js +12 -0
  26. package/lib/bridge/types.js.map +1 -0
  27. package/lib/bridge/webBridgeBootstrap.js +185 -0
  28. package/lib/bridge/webBridgeBootstrap.js.map +1 -0
  29. package/lib/components/CustomDrawer.js +6 -2
  30. package/lib/components/CustomDrawer.js.map +1 -1
  31. package/lib/compute.js +54 -1
  32. package/lib/compute.js.map +1 -1
  33. package/lib/config/env-config.js +4 -0
  34. package/lib/config/env-config.js.map +1 -1
  35. package/lib/hooks/mintSurfaceSystemToken.js +260 -0
  36. package/lib/hooks/mintSurfaceSystemToken.js.map +1 -0
  37. package/lib/hooks/useObtainSystemToken.js +76 -0
  38. package/lib/hooks/useObtainSystemToken.js.map +1 -0
  39. package/lib/hooks/usePrerequisiteIds.js +97 -54
  40. package/lib/hooks/usePrerequisiteIds.js.map +1 -1
  41. package/lib/index.js +1 -1
  42. package/lib/index.js.map +1 -1
  43. package/lib/routes.json +55 -0
  44. package/lib/screens/Chat/index.js +41 -10
  45. package/lib/screens/Chat/index.js.map +1 -1
  46. package/lib/screens/Home/HomeScreen.js +31 -11
  47. package/lib/screens/Home/HomeScreen.js.map +1 -1
  48. package/lib/screens/WebBuilder/WebViewWithNavigation.js +20 -0
  49. package/lib/screens/WebBuilder/WebViewWithNavigation.js.map +1 -0
  50. package/lib/screens/WebBuilder/index.js +345 -0
  51. package/lib/screens/WebBuilder/index.js.map +1 -0
  52. package/lib/theme/mobileTokens.js +3 -1
  53. package/lib/theme/mobileTokens.js.map +1 -1
  54. package/package.json +11 -5
@@ -0,0 +1,77 @@
1
+ var __defProp = Object.defineProperty;
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
+ class AuthenticatedFetch {
21
+ constructor(bridge) {
22
+ this.bridge = bridge;
23
+ }
24
+ async fetch(url, options = {}) {
25
+ let token = await this.getValidToken();
26
+ const response = await fetch(url, __spreadProps(__spreadValues({}, options), {
27
+ headers: __spreadProps(__spreadValues({}, options.headers), {
28
+ Authorization: `Bearer ${token}`
29
+ })
30
+ }));
31
+ if (response.status === 401) {
32
+ token = await this.refreshToken();
33
+ return fetch(url, __spreadProps(__spreadValues({}, options), {
34
+ headers: __spreadProps(__spreadValues({}, options.headers), {
35
+ Authorization: `Bearer ${token}`
36
+ })
37
+ }));
38
+ }
39
+ return response;
40
+ }
41
+ async getValidToken() {
42
+ const cached = this.getCachedToken();
43
+ if (cached && cached.expiresAt > Date.now() + 6e4) {
44
+ return cached.token;
45
+ }
46
+ return this.refreshToken();
47
+ }
48
+ async refreshToken() {
49
+ const cached = this.getCachedToken();
50
+ const result = await this.bridge.request("auth.refreshToken", {
51
+ currentToken: cached == null ? void 0 : cached.token
52
+ });
53
+ const {
54
+ token,
55
+ expiresAt
56
+ } = await Promise.resolve(result);
57
+ this.cacheToken(token, expiresAt);
58
+ return token;
59
+ }
60
+ cacheToken(token, expiresAt) {
61
+ if (typeof sessionStorage === "undefined") return;
62
+ sessionStorage.setItem("bridge_token", JSON.stringify({
63
+ token,
64
+ expiresAt
65
+ }));
66
+ }
67
+ getCachedToken() {
68
+ if (typeof sessionStorage === "undefined") return null;
69
+ const cached = sessionStorage.getItem("bridge_token");
70
+ if (!cached) return null;
71
+ try {
72
+ return JSON.parse(cached);
73
+ } catch (e) {
74
+ return null;
75
+ }
76
+ }
77
+ }export{AuthenticatedFetch};//# sourceMappingURL=AuthenticatedFetch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AuthenticatedFetch.js","sources":["../../src/bridge/AuthenticatedFetch.ts"],"sourcesContent":["import type { TypedBridge } from './TypedBridge';\n\ntype CachedToken = { token: string; expiresAt: number };\n\n/**\n * Web-side fetch helper that pulls tokens through the typed bridge.\n * Intended for use inside the WebView (or shared with account/browser).\n */\nexport class AuthenticatedFetch {\n constructor(private readonly bridge: TypedBridge) {}\n\n async fetch(url: string, options: RequestInit = {}): Promise<Response> {\n let token = await this.getValidToken();\n\n const response = await fetch(url, {\n ...options,\n headers: {\n ...options.headers,\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (response.status === 401) {\n token = await this.refreshToken();\n return fetch(url, {\n ...options,\n headers: {\n ...options.headers,\n Authorization: `Bearer ${token}`,\n },\n });\n }\n\n return response;\n }\n\n private async getValidToken(): Promise<string> {\n const cached = this.getCachedToken();\n if (cached && cached.expiresAt > Date.now() + 60_000) {\n return cached.token;\n }\n return this.refreshToken();\n }\n\n private async refreshToken(): Promise<string> {\n const cached = this.getCachedToken();\n const result = await this.bridge.request('auth.refreshToken', {\n currentToken: cached?.token,\n });\n const { token, expiresAt } = await Promise.resolve(result);\n this.cacheToken(token, expiresAt);\n return token;\n }\n\n private cacheToken(token: string, expiresAt: number): void {\n if (typeof sessionStorage === 'undefined') return;\n sessionStorage.setItem('bridge_token', JSON.stringify({ token, expiresAt }));\n }\n\n private getCachedToken(): CachedToken | null {\n if (typeof sessionStorage === 'undefined') return null;\n const cached = sessionStorage.getItem('bridge_token');\n if (!cached) return null;\n try {\n return JSON.parse(cached) as CachedToken;\n } catch {\n return null;\n }\n }\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;AAUO,MAAM,kBAAmB,CAAA;AAAA,EAC9B,YAA6B,MAAqB,EAAA;AAArB,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AAAA;AAAsB,EACnD,MAAM,KAAA,CAAM,GAAa,EAAA,OAAA,GAAuB,EAAuB,EAAA;AACrE,IAAI,IAAA,KAAA,GAAQ,MAAM,IAAA,CAAK,aAAc,EAAA;AACrC,IAAA,MAAM,QAAW,GAAA,MAAM,KAAM,CAAA,GAAA,EAAK,iCAC7B,OAD6B,CAAA,EAAA;AAAA,MAEhC,OAAA,EAAS,aACJ,CAAA,cAAA,CAAA,EAAA,EAAA,OAAA,CAAQ,OADJ,CAAA,EAAA;AAAA,QAEP,aAAA,EAAe,UAAU,KAAK,CAAA;AAAA,OAChC;AAAA,KACD,CAAA,CAAA;AACD,IAAI,IAAA,QAAA,CAAS,WAAW,GAAK,EAAA;AAC3B,MAAQ,KAAA,GAAA,MAAM,KAAK,YAAa,EAAA;AAChC,MAAO,OAAA,KAAA,CAAM,GAAK,EAAA,aAAA,CAAA,cAAA,CAAA,EAAA,EACb,OADa,CAAA,EAAA;AAAA,QAEhB,OAAA,EAAS,aACJ,CAAA,cAAA,CAAA,EAAA,EAAA,OAAA,CAAQ,OADJ,CAAA,EAAA;AAAA,UAEP,aAAA,EAAe,UAAU,KAAK,CAAA;AAAA,SAChC;AAAA,OACD,CAAA,CAAA;AAAA;AAEH,IAAO,OAAA,QAAA;AAAA;AACT,EACA,MAAc,aAAiC,GAAA;AAC7C,IAAM,MAAA,MAAA,GAAS,KAAK,cAAe,EAAA;AACnC,IAAA,IAAI,UAAU,MAAO,CAAA,SAAA,GAAY,IAAK,CAAA,GAAA,KAAQ,GAAQ,EAAA;AACpD,MAAA,OAAO,MAAO,CAAA,KAAA;AAAA;AAEhB,IAAA,OAAO,KAAK,YAAa,EAAA;AAAA;AAC3B,EACA,MAAc,YAAgC,GAAA;AAC5C,IAAM,MAAA,MAAA,GAAS,KAAK,cAAe,EAAA;AACnC,IAAA,MAAM,MAAS,GAAA,MAAM,IAAK,CAAA,MAAA,CAAO,QAAQ,mBAAqB,EAAA;AAAA,MAC5D,cAAc,MAAQ,IAAA,IAAA,GAAA,MAAA,GAAA,MAAA,CAAA;AAAA,KACvB,CAAA;AACD,IAAM,MAAA;AAAA,MACJ,KAAA;AAAA,MACA;AAAA,KACE,GAAA,MAAM,OAAQ,CAAA,OAAA,CAAQ,MAAM,CAAA;AAChC,IAAK,IAAA,CAAA,UAAA,CAAW,OAAO,SAAS,CAAA;AAChC,IAAO,OAAA,KAAA;AAAA;AACT,EACQ,UAAA,CAAW,OAAe,SAAyB,EAAA;AACzD,IAAI,IAAA,OAAO,mBAAmB,WAAa,EAAA;AAC3C,IAAe,cAAA,CAAA,OAAA,CAAQ,cAAgB,EAAA,IAAA,CAAK,SAAU,CAAA;AAAA,MACpD,KAAA;AAAA,MACA;AAAA,KACD,CAAC,CAAA;AAAA;AACJ,EACQ,cAAqC,GAAA;AAC3C,IAAI,IAAA,OAAO,cAAmB,KAAA,WAAA,EAAoB,OAAA,IAAA;AAClD,IAAM,MAAA,MAAA,GAAS,cAAe,CAAA,OAAA,CAAQ,cAAc,CAAA;AACpD,IAAI,IAAA,CAAC,QAAe,OAAA,IAAA;AACpB,IAAI,IAAA;AACF,MAAO,OAAA,IAAA,CAAK,MAAM,MAAM,CAAA;AAAA,KAClB,CAAA,OAAA,CAAA,EAAA;AACN,MAAO,OAAA,IAAA;AAAA;AACT;AAEJ"}
@@ -0,0 +1,65 @@
1
+ import {MessageType}from'./types.js';var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
+ class BridgeDebugger {
5
+ constructor() {
6
+ __publicField(this, "messageLog", []);
7
+ __publicField(this, "maxLogSize", 1e3);
8
+ __publicField(this, "pendingSentAt", /* @__PURE__ */ new Map());
9
+ }
10
+ logSent(message) {
11
+ if (message.type === MessageType.REQUEST) {
12
+ this.pendingSentAt.set(message.id, Date.now());
13
+ }
14
+ this.addToLog("sent", message);
15
+ }
16
+ logReceived(message) {
17
+ let duration;
18
+ if (message.type === MessageType.RESPONSE || message.type === MessageType.ERROR) {
19
+ const sentAt = this.pendingSentAt.get(message.id);
20
+ if (sentAt != null) {
21
+ duration = Date.now() - sentAt;
22
+ this.pendingSentAt.delete(message.id);
23
+ }
24
+ }
25
+ this.addToLog("received", message, duration);
26
+ }
27
+ addToLog(direction, message, duration) {
28
+ this.messageLog.push({
29
+ timestamp: Date.now(),
30
+ direction,
31
+ message,
32
+ duration
33
+ });
34
+ if (this.messageLog.length > this.maxLogSize) {
35
+ this.messageLog.shift();
36
+ }
37
+ }
38
+ exportLogs() {
39
+ return JSON.stringify(this.messageLog, null, 2);
40
+ }
41
+ getMetrics() {
42
+ const requests = this.messageLog.filter((log) => log.message.type === MessageType.REQUEST);
43
+ const responses = this.messageLog.filter((log) => log.message.type === MessageType.RESPONSE && log.duration != null);
44
+ const errors = this.messageLog.filter((log) => log.message.type === MessageType.ERROR);
45
+ const responseTimes = responses.map((r) => r.duration).filter((d) => d > 0);
46
+ const avgResponseTime = responseTimes.length > 0 ? responseTimes.reduce((a, b) => a + b, 0) / responseTimes.length : 0;
47
+ const slowest = responses.filter((r) => r.duration != null).sort((a, b) => {
48
+ var _a, _b;
49
+ return ((_a = b.duration) != null ? _a : 0) - ((_b = a.duration) != null ? _b : 0);
50
+ }).slice(0, 10).map((r) => ({
51
+ action: r.message.action,
52
+ duration: r.duration
53
+ }));
54
+ return {
55
+ totalMessages: this.messageLog.length,
56
+ averageResponseTime: Math.round(avgResponseTime),
57
+ slowestActions: slowest,
58
+ errorRate: requests.length > 0 ? errors.length / requests.length : 0
59
+ };
60
+ }
61
+ clear() {
62
+ this.messageLog = [];
63
+ this.pendingSentAt.clear();
64
+ }
65
+ }export{BridgeDebugger};//# sourceMappingURL=BridgeDebugger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BridgeDebugger.js","sources":["../../src/bridge/BridgeDebugger.ts"],"sourcesContent":["import { MessageType, type BridgeMessage } from './types';\n\ntype LogEntry = {\n timestamp: number;\n direction: 'sent' | 'received';\n message: BridgeMessage;\n duration?: number;\n};\n\n/**\n * Dev-oriented bridge message log + basic latency / error metrics.\n */\nexport class BridgeDebugger {\n private messageLog: LogEntry[] = [];\n\n private maxLogSize = 1000;\n\n private pendingSentAt = new Map<string, number>();\n\n logSent(message: BridgeMessage): void {\n if (message.type === MessageType.REQUEST) {\n this.pendingSentAt.set(message.id, Date.now());\n }\n this.addToLog('sent', message);\n }\n\n logReceived(message: BridgeMessage): void {\n let duration: number | undefined;\n if (message.type === MessageType.RESPONSE || message.type === MessageType.ERROR) {\n const sentAt = this.pendingSentAt.get(message.id);\n if (sentAt != null) {\n duration = Date.now() - sentAt;\n this.pendingSentAt.delete(message.id);\n }\n }\n this.addToLog('received', message, duration);\n }\n\n private addToLog(direction: 'sent' | 'received', message: BridgeMessage, duration?: number): void {\n this.messageLog.push({\n timestamp: Date.now(),\n direction,\n message,\n duration,\n });\n if (this.messageLog.length > this.maxLogSize) {\n this.messageLog.shift();\n }\n }\n\n exportLogs(): string {\n return JSON.stringify(this.messageLog, null, 2);\n }\n\n getMetrics(): {\n totalMessages: number;\n averageResponseTime: number;\n slowestActions: Array<{ action: string; duration: number }>;\n errorRate: number;\n } {\n const requests = this.messageLog.filter((log) => log.message.type === MessageType.REQUEST);\n const responses = this.messageLog.filter(\n (log) => log.message.type === MessageType.RESPONSE && log.duration != null,\n );\n const errors = this.messageLog.filter((log) => log.message.type === MessageType.ERROR);\n\n const responseTimes = responses.map((r) => r.duration!).filter((d) => d > 0);\n const avgResponseTime =\n responseTimes.length > 0 ? responseTimes.reduce((a, b) => a + b, 0) / responseTimes.length : 0;\n\n const slowest = responses\n .filter((r) => r.duration != null)\n .sort((a, b) => (b.duration ?? 0) - (a.duration ?? 0))\n .slice(0, 10)\n .map((r) => ({\n action: r.message.action,\n duration: r.duration!,\n }));\n\n return {\n totalMessages: this.messageLog.length,\n averageResponseTime: Math.round(avgResponseTime),\n slowestActions: slowest,\n errorRate: requests.length > 0 ? errors.length / requests.length : 0,\n };\n }\n\n clear(): void {\n this.messageLog = [];\n this.pendingSentAt.clear();\n }\n}\n"],"names":[],"mappings":";;;AAWO,MAAM,cAAe,CAAA;AAAA,EAArB,WAAA,GAAA;AACL,IAAA,aAAA,CAAA,IAAA,EAAQ,cAAyB,EAAC,CAAA;AAClC,IAAA,aAAA,CAAA,IAAA,EAAQ,YAAa,EAAA,GAAA,CAAA;AACrB,IAAQ,aAAA,CAAA,IAAA,EAAA,eAAA,sBAAoB,GAAoB,EAAA,CAAA;AAAA;AAAA,EAChD,QAAQ,OAA8B,EAAA;AACpC,IAAI,IAAA,OAAA,CAAQ,IAAS,KAAA,WAAA,CAAY,OAAS,EAAA;AACxC,MAAA,IAAA,CAAK,cAAc,GAAI,CAAA,OAAA,CAAQ,EAAI,EAAA,IAAA,CAAK,KAAK,CAAA;AAAA;AAE/C,IAAK,IAAA,CAAA,QAAA,CAAS,QAAQ,OAAO,CAAA;AAAA;AAC/B,EACA,YAAY,OAA8B,EAAA;AACxC,IAAI,IAAA,QAAA;AACJ,IAAA,IAAI,QAAQ,IAAS,KAAA,WAAA,CAAY,YAAY,OAAQ,CAAA,IAAA,KAAS,YAAY,KAAO,EAAA;AAC/E,MAAA,MAAM,MAAS,GAAA,IAAA,CAAK,aAAc,CAAA,GAAA,CAAI,QAAQ,EAAE,CAAA;AAChD,MAAA,IAAI,UAAU,IAAM,EAAA;AAClB,QAAW,QAAA,GAAA,IAAA,CAAK,KAAQ,GAAA,MAAA;AACxB,QAAK,IAAA,CAAA,aAAA,CAAc,MAAO,CAAA,OAAA,CAAQ,EAAE,CAAA;AAAA;AACtC;AAEF,IAAK,IAAA,CAAA,QAAA,CAAS,UAAY,EAAA,OAAA,EAAS,QAAQ,CAAA;AAAA;AAC7C,EACQ,QAAA,CAAS,SAAgC,EAAA,OAAA,EAAwB,QAAyB,EAAA;AAChG,IAAA,IAAA,CAAK,WAAW,IAAK,CAAA;AAAA,MACnB,SAAA,EAAW,KAAK,GAAI,EAAA;AAAA,MACpB,SAAA;AAAA,MACA,OAAA;AAAA,MACA;AAAA,KACD,CAAA;AACD,IAAA,IAAI,IAAK,CAAA,UAAA,CAAW,MAAS,GAAA,IAAA,CAAK,UAAY,EAAA;AAC5C,MAAA,IAAA,CAAK,WAAW,KAAM,EAAA;AAAA;AACxB;AACF,EACA,UAAqB,GAAA;AACnB,IAAA,OAAO,IAAK,CAAA,SAAA,CAAU,IAAK,CAAA,UAAA,EAAY,MAAM,CAAC,CAAA;AAAA;AAChD,EACA,UAQE,GAAA;AACA,IAAM,MAAA,QAAA,GAAW,KAAK,UAAW,CAAA,MAAA,CAAO,SAAO,GAAI,CAAA,OAAA,CAAQ,IAAS,KAAA,WAAA,CAAY,OAAO,CAAA;AACvF,IAAA,MAAM,SAAY,GAAA,IAAA,CAAK,UAAW,CAAA,MAAA,CAAO,CAAO,GAAA,KAAA,GAAA,CAAI,OAAQ,CAAA,IAAA,KAAS,WAAY,CAAA,QAAA,IAAY,GAAI,CAAA,QAAA,IAAY,IAAI,CAAA;AACjH,IAAM,MAAA,MAAA,GAAS,KAAK,UAAW,CAAA,MAAA,CAAO,SAAO,GAAI,CAAA,OAAA,CAAQ,IAAS,KAAA,WAAA,CAAY,KAAK,CAAA;AACnF,IAAM,MAAA,aAAA,GAAgB,SAAU,CAAA,GAAA,CAAI,CAAK,CAAA,KAAA,CAAA,CAAE,QAAS,CAAE,CAAA,MAAA,CAAO,CAAK,CAAA,KAAA,CAAA,GAAI,CAAC,CAAA;AACvE,IAAA,MAAM,eAAkB,GAAA,aAAA,CAAc,MAAS,GAAA,CAAA,GAAI,cAAc,MAAO,CAAA,CAAC,CAAG,EAAA,CAAA,KAAM,CAAI,GAAA,CAAA,EAAG,CAAC,CAAA,GAAI,cAAc,MAAS,GAAA,CAAA;AACrH,IAAM,MAAA,OAAA,GAAU,SAAU,CAAA,MAAA,CAAO,CAAK,CAAA,KAAA,CAAA,CAAE,QAAY,IAAA,IAAI,CAAE,CAAA,IAAA,CAAK,CAAC,CAAA,EAAG,CAAG,KAAA;AA5D1E,MAAA,IAAA,EAAA,EAAA,EAAA;AA4D8E,MAAA,OAAA,CAAA,CAAA,EAAA,GAAA,CAAA,CAAE,QAAF,KAAA,IAAA,GAAA,EAAA,GAAc,CAAM,KAAA,CAAA,EAAA,GAAA,CAAA,CAAE,aAAF,IAAc,GAAA,EAAA,GAAA,CAAA,CAAA;AAAA,KAAE,EAAE,KAAM,CAAA,CAAA,EAAG,EAAE,CAAA,CAAE,IAAI,CAAM,CAAA,MAAA;AAAA,MACrI,MAAA,EAAQ,EAAE,OAAQ,CAAA,MAAA;AAAA,MAClB,UAAU,CAAE,CAAA;AAAA,KACZ,CAAA,CAAA;AACF,IAAO,OAAA;AAAA,MACL,aAAA,EAAe,KAAK,UAAW,CAAA,MAAA;AAAA,MAC/B,mBAAA,EAAqB,IAAK,CAAA,KAAA,CAAM,eAAe,CAAA;AAAA,MAC/C,cAAgB,EAAA,OAAA;AAAA,MAChB,WAAW,QAAS,CAAA,MAAA,GAAS,IAAI,MAAO,CAAA,MAAA,GAAS,SAAS,MAAS,GAAA;AAAA,KACrE;AAAA;AACF,EACA,KAAc,GAAA;AACZ,IAAA,IAAA,CAAK,aAAa,EAAC;AACnB,IAAA,IAAA,CAAK,cAAc,KAAM,EAAA;AAAA;AAE7B"}
@@ -0,0 +1,38 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
+ class CancellableRequest {
5
+ constructor(promise, onCancel) {
6
+ this.promise = promise;
7
+ this.onCancel = onCancel;
8
+ __publicField(this, "cancelled", false);
9
+ __publicField(this, "cleanupFns", []);
10
+ }
11
+ then(onFulfilled, onRejected) {
12
+ return this.promise.then((value) => {
13
+ if (this.cancelled) {
14
+ throw new Error("Request cancelled");
15
+ }
16
+ return onFulfilled ? onFulfilled(value) : value;
17
+ }, onRejected != null ? onRejected : void 0);
18
+ }
19
+ catch(onRejected) {
20
+ return this.then(void 0, onRejected);
21
+ }
22
+ finally(onFinally) {
23
+ return this.promise.finally(onFinally != null ? onFinally : void 0);
24
+ }
25
+ cancel() {
26
+ var _a;
27
+ if (this.cancelled) return;
28
+ this.cancelled = true;
29
+ (_a = this.onCancel) == null ? void 0 : _a.call(this);
30
+ this.cleanupFns.forEach((fn) => fn());
31
+ }
32
+ get isCancelled() {
33
+ return this.cancelled;
34
+ }
35
+ addCleanup(fn) {
36
+ this.cleanupFns.push(fn);
37
+ }
38
+ }export{CancellableRequest};//# sourceMappingURL=CancellableRequest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CancellableRequest.js","sources":["../../src/bridge/CancellableRequest.ts"],"sourcesContent":["/**\n * Promise wrapper that supports explicit cancellation so late bridge\n * responses (e.g. auth refresh after timeout) do not resolve stale work.\n */\nexport class CancellableRequest<T> implements PromiseLike<T> {\n private cancelled = false;\n\n private cleanupFns: Array<() => void> = [];\n\n constructor(\n private readonly promise: Promise<T>,\n private readonly onCancel?: () => void,\n ) {}\n\n then<TResult1 = T, TResult2 = never>(\n onFulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null,\n onRejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): Promise<TResult1 | TResult2> {\n return this.promise.then((value) => {\n if (this.cancelled) {\n throw new Error('Request cancelled');\n }\n return onFulfilled ? onFulfilled(value) : (value as unknown as TResult1);\n }, onRejected ?? undefined);\n }\n\n catch<TResult = never>(\n onRejected?: ((reason: unknown) => TResult | PromiseLike<TResult>) | null,\n ): Promise<T | TResult> {\n return this.then(undefined, onRejected);\n }\n\n finally(onFinally?: (() => void) | null): Promise<T> {\n return this.promise.finally(onFinally ?? undefined);\n }\n\n cancel(): void {\n if (this.cancelled) return;\n this.cancelled = true;\n this.onCancel?.();\n this.cleanupFns.forEach((fn) => fn());\n }\n\n get isCancelled(): boolean {\n return this.cancelled;\n }\n\n addCleanup(fn: () => void): void {\n this.cleanupFns.push(fn);\n }\n}\n"],"names":[],"mappings":";;;AAIO,MAAM,kBAAgD,CAAA;AAAA,EAG3D,WAAA,CAA6B,SAAsC,QAAuB,EAAA;AAA7D,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AAAsC,IAAA,IAAA,CAAA,QAAA,GAAA,QAAA;AAFnE,IAAA,aAAA,CAAA,IAAA,EAAQ,WAAY,EAAA,KAAA,CAAA;AACpB,IAAA,aAAA,CAAA,IAAA,EAAQ,cAAgC,EAAC,CAAA;AAAA;AACkD,EAC3F,IAAA,CAAqC,aAAuE,UAA2G,EAAA;AACrN,IAAO,OAAA,IAAA,CAAK,OAAQ,CAAA,IAAA,CAAK,CAAS,KAAA,KAAA;AAChC,MAAA,IAAI,KAAK,SAAW,EAAA;AAClB,QAAM,MAAA,IAAI,MAAM,mBAAmB,CAAA;AAAA;AAErC,MAAO,OAAA,WAAA,GAAc,WAAY,CAAA,KAAK,CAAI,GAAA,KAAA;AAAA,KAC5C,EAAG,kCAAc,MAAS,CAAA;AAAA;AAC5B,EACA,MAAuB,UAAiG,EAAA;AACtH,IAAO,OAAA,IAAA,CAAK,IAAK,CAAA,MAAA,EAAW,UAAU,CAAA;AAAA;AACxC,EACA,QAAQ,SAA6C,EAAA;AACnD,IAAA,OAAO,IAAK,CAAA,OAAA,CAAQ,OAAQ,CAAA,SAAA,IAAA,IAAA,GAAA,SAAA,GAAa,MAAS,CAAA;AAAA;AACpD,EACA,MAAe,GAAA;AAtBjB,IAAA,IAAA,EAAA;AAuBI,IAAA,IAAI,KAAK,SAAW,EAAA;AACpB,IAAA,IAAA,CAAK,SAAY,GAAA,IAAA;AACjB,IAAA,CAAA,EAAA,GAAA,IAAA,CAAK,QAAL,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAA,IAAA,CAAA,IAAA,CAAA;AACA,IAAA,IAAA,CAAK,UAAW,CAAA,OAAA,CAAQ,CAAM,EAAA,KAAA,EAAA,EAAI,CAAA;AAAA;AACpC,EACA,IAAI,WAAuB,GAAA;AACzB,IAAA,OAAO,IAAK,CAAA,SAAA;AAAA;AACd,EACA,WAAW,EAAsB,EAAA;AAC/B,IAAK,IAAA,CAAA,UAAA,CAAW,KAAK,EAAE,CAAA;AAAA;AAE3B"}
@@ -0,0 +1,71 @@
1
+ import {DEFAULT_CHUNK_SIZE,MessageType}from'./types.js';var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __publicField = (obj, key, value) => __defNormalProp(obj, key + "" , value);
4
+ class ChunkedMessageHandler {
5
+ constructor() {
6
+ __publicField(this, "chunks", /* @__PURE__ */ new Map());
7
+ }
8
+ generateId() {
9
+ return `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;
10
+ }
11
+ /**
12
+ * Serialize and either send directly or as CHUNK envelopes via `send`.
13
+ */
14
+ sendChunked(message, send, chunkSize = DEFAULT_CHUNK_SIZE) {
15
+ const serialized = JSON.stringify(message);
16
+ if (serialized.length <= chunkSize) {
17
+ send(serialized);
18
+ return;
19
+ }
20
+ const parts = [];
21
+ for (let i = 0; i < serialized.length; i += chunkSize) {
22
+ parts.push(serialized.slice(i, i + chunkSize));
23
+ }
24
+ const chunkId = this.generateId();
25
+ parts.forEach((chunk, index) => {
26
+ const envelope = {
27
+ type: MessageType.CHUNK,
28
+ chunkId,
29
+ chunkIndex: index,
30
+ totalChunks: parts.length,
31
+ data: chunk
32
+ };
33
+ send(JSON.stringify(envelope));
34
+ });
35
+ }
36
+ /** Returns a complete BridgeMessage once all chunks for an id arrive. */
37
+ handleChunk(envelope) {
38
+ const {
39
+ chunkId,
40
+ chunkIndex,
41
+ totalChunks,
42
+ data
43
+ } = envelope;
44
+ if (!this.chunks.has(chunkId)) {
45
+ this.chunks.set(chunkId, {
46
+ chunks: new Array(totalChunks),
47
+ receivedCount: 0,
48
+ totalChunks
49
+ });
50
+ }
51
+ const chunkData = this.chunks.get(chunkId);
52
+ if (chunkData.chunks[chunkIndex] === void 0) {
53
+ chunkData.chunks[chunkIndex] = data;
54
+ chunkData.receivedCount += 1;
55
+ }
56
+ if (chunkData.receivedCount === chunkData.totalChunks) {
57
+ const complete = chunkData.chunks.join("");
58
+ this.chunks.delete(chunkId);
59
+ try {
60
+ return JSON.parse(complete);
61
+ } catch (error) {
62
+ console.error("[Bridge] Failed to parse chunked message:", error);
63
+ return null;
64
+ }
65
+ }
66
+ return null;
67
+ }
68
+ isChunkEnvelope(raw) {
69
+ return typeof raw === "object" && raw !== null && raw.type === MessageType.CHUNK && typeof raw.chunkId === "string";
70
+ }
71
+ }export{ChunkedMessageHandler};//# sourceMappingURL=ChunkedMessageHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChunkedMessageHandler.js","sources":["../../src/bridge/ChunkedMessageHandler.ts"],"sourcesContent":["import { MessageType, type BridgeMessage, type ChunkEnvelope, DEFAULT_CHUNK_SIZE } from './types';\n\ntype ChunkAccumulator = {\n chunks: string[];\n receivedCount: number;\n totalChunks: number;\n};\n\n/**\n * Splits / reassembles large bridge payloads so postMessage does not freeze the UI.\n */\nexport class ChunkedMessageHandler {\n private chunks = new Map<string, ChunkAccumulator>();\n\n private generateId(): string {\n return `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;\n }\n\n /**\n * Serialize and either send directly or as CHUNK envelopes via `send`.\n */\n sendChunked(message: BridgeMessage, send: (serialized: string) => void, chunkSize = DEFAULT_CHUNK_SIZE): void {\n const serialized = JSON.stringify(message);\n\n if (serialized.length <= chunkSize) {\n send(serialized);\n return;\n }\n\n const parts: string[] = [];\n for (let i = 0; i < serialized.length; i += chunkSize) {\n parts.push(serialized.slice(i, i + chunkSize));\n }\n\n const chunkId = this.generateId();\n parts.forEach((chunk, index) => {\n const envelope: ChunkEnvelope = {\n type: MessageType.CHUNK,\n chunkId,\n chunkIndex: index,\n totalChunks: parts.length,\n data: chunk,\n };\n send(JSON.stringify(envelope));\n });\n }\n\n /** Returns a complete BridgeMessage once all chunks for an id arrive. */\n handleChunk(envelope: ChunkEnvelope): BridgeMessage | null {\n const { chunkId, chunkIndex, totalChunks, data } = envelope;\n\n if (!this.chunks.has(chunkId)) {\n this.chunks.set(chunkId, {\n chunks: new Array(totalChunks),\n receivedCount: 0,\n totalChunks,\n });\n }\n\n const chunkData = this.chunks.get(chunkId)!;\n if (chunkData.chunks[chunkIndex] === undefined) {\n chunkData.chunks[chunkIndex] = data;\n chunkData.receivedCount += 1;\n }\n\n if (chunkData.receivedCount === chunkData.totalChunks) {\n const complete = chunkData.chunks.join('');\n this.chunks.delete(chunkId);\n try {\n return JSON.parse(complete) as BridgeMessage;\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error('[Bridge] Failed to parse chunked message:', error);\n return null;\n }\n }\n\n return null;\n }\n\n isChunkEnvelope(raw: unknown): raw is ChunkEnvelope {\n return (\n typeof raw === 'object' &&\n raw !== null &&\n (raw as ChunkEnvelope).type === MessageType.CHUNK &&\n typeof (raw as ChunkEnvelope).chunkId === 'string'\n );\n }\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,256 @@
1
+ import {Platform}from'react-native';import {CancellableRequest}from'./CancellableRequest.js';import {ChunkedMessageHandler}from'./ChunkedMessageHandler.js';import {BridgeDebugger}from'./BridgeDebugger.js';import {DEFAULT_BRIDGE_TIMEOUT_MS,MessageType,BRIDGE_PROTOCOL_VERSION,BRIDGE_READY_ACTION}from'./types.js';var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
+ class NativeWebViewBridge {
5
+ constructor(webViewRef) {
6
+ __publicField(this, "webViewRef");
7
+ __publicField(this, "pendingRequests", /* @__PURE__ */ new Map());
8
+ __publicField(this, "messageQueue", []);
9
+ __publicField(this, "isReady", false);
10
+ __publicField(this, "chunker", new ChunkedMessageHandler());
11
+ __publicField(this, "debugger", new BridgeDebugger());
12
+ __publicField(this, "batch", []);
13
+ __publicField(this, "batchTimeout");
14
+ __publicField(this, "batchConfig", {
15
+ batchSize: 10,
16
+ batchDelayMs: 100
17
+ });
18
+ __publicField(this, "listeners", /* @__PURE__ */ new Map());
19
+ this.webViewRef = webViewRef;
20
+ }
21
+ on(event, listener) {
22
+ if (!this.listeners.has(event)) {
23
+ this.listeners.set(event, /* @__PURE__ */ new Set());
24
+ }
25
+ this.listeners.get(event).add(listener);
26
+ return this;
27
+ }
28
+ off(event, listener) {
29
+ var _a;
30
+ (_a = this.listeners.get(event)) == null ? void 0 : _a.delete(listener);
31
+ return this;
32
+ }
33
+ emitLocal(event, payload) {
34
+ const set = this.listeners.get(event);
35
+ if (!set) return;
36
+ set.forEach((listener) => {
37
+ try {
38
+ listener(payload);
39
+ } catch (error) {
40
+ console.error(`[Bridge] listener error for ${event}:`, error);
41
+ }
42
+ });
43
+ }
44
+ removeAllListeners() {
45
+ this.listeners.clear();
46
+ }
47
+ getDebugger() {
48
+ return this.debugger;
49
+ }
50
+ request(action, payload, timeoutMs = DEFAULT_BRIDGE_TIMEOUT_MS) {
51
+ const id = this.generateId();
52
+ const message = {
53
+ id,
54
+ type: MessageType.REQUEST,
55
+ action,
56
+ payload,
57
+ timestamp: Date.now(),
58
+ version: BRIDGE_PROTOCOL_VERSION
59
+ };
60
+ let timeoutId;
61
+ const promise = new Promise((resolve, reject) => {
62
+ timeoutId = setTimeout(() => {
63
+ this.pendingRequests.delete(id);
64
+ reject(new Error(`Request ${action} timed out after ${timeoutMs}ms`));
65
+ }, timeoutMs);
66
+ this.pendingRequests.set(id, {
67
+ resolve,
68
+ reject,
69
+ timeout: timeoutId
70
+ });
71
+ this.sendMessage(message);
72
+ });
73
+ const cancellable = new CancellableRequest(promise, () => {
74
+ clearTimeout(timeoutId);
75
+ this.pendingRequests.delete(id);
76
+ this.sendEvent("request.cancelled", {
77
+ requestId: id
78
+ });
79
+ });
80
+ cancellable.addCleanup(() => clearTimeout(timeoutId));
81
+ return cancellable;
82
+ }
83
+ /** One-way event toward the WebView (batches analytics.* / metrics.*). */
84
+ sendEvent(action, payload) {
85
+ const message = {
86
+ id: this.generateId(),
87
+ type: MessageType.EVENT,
88
+ action,
89
+ payload,
90
+ timestamp: Date.now(),
91
+ version: BRIDGE_PROTOCOL_VERSION
92
+ };
93
+ if (this.shouldBatch(action)) {
94
+ this.addToBatch(message);
95
+ return;
96
+ }
97
+ this.sendMessage(message);
98
+ }
99
+ sendResponse(id, success, data, error) {
100
+ const response = {
101
+ id,
102
+ type: MessageType.RESPONSE,
103
+ action: "response",
104
+ payload: {
105
+ id,
106
+ success,
107
+ data,
108
+ error
109
+ },
110
+ timestamp: Date.now(),
111
+ version: BRIDGE_PROTOCOL_VERSION
112
+ };
113
+ this.sendMessage(response);
114
+ }
115
+ handleMessage(event) {
116
+ const rawData = event.nativeEvent.data;
117
+ const data = typeof rawData === "string" ? rawData : JSON.stringify(rawData);
118
+ try {
119
+ const parsed = JSON.parse(data);
120
+ if (this.chunker.isChunkEnvelope(parsed)) {
121
+ const complete = this.chunker.handleChunk(parsed);
122
+ if (complete) this.dispatchMessage(complete);
123
+ return;
124
+ }
125
+ this.dispatchMessage(parsed);
126
+ } catch (error) {
127
+ console.error("[Bridge] Failed to parse message:", error);
128
+ }
129
+ }
130
+ onBridgeReady() {
131
+ this.isReady = true;
132
+ while (this.messageQueue.length > 0) {
133
+ const message = this.messageQueue.shift();
134
+ if (message) this.sendMessage(message);
135
+ }
136
+ }
137
+ dispose() {
138
+ this.flushBatch();
139
+ this.pendingRequests.forEach((pending) => {
140
+ clearTimeout(pending.timeout);
141
+ pending.reject(new Error("Bridge disposed"));
142
+ });
143
+ this.pendingRequests.clear();
144
+ this.messageQueue = [];
145
+ this.isReady = false;
146
+ this.removeAllListeners();
147
+ }
148
+ dispatchMessage(message) {
149
+ this.debugger.logReceived(message);
150
+ switch (message.type) {
151
+ case MessageType.RESPONSE:
152
+ this.handleResponse(message);
153
+ break;
154
+ case MessageType.REQUEST:
155
+ this.handleRequest(message);
156
+ break;
157
+ case MessageType.EVENT:
158
+ this.handleEvent(message);
159
+ break;
160
+ case MessageType.ERROR:
161
+ this.handleError(message);
162
+ break;
163
+ }
164
+ }
165
+ handleResponse(message) {
166
+ var _a, _b, _c;
167
+ const payload = message.payload;
168
+ const responseId = (_a = payload == null ? void 0 : payload.id) != null ? _a : message.id;
169
+ const pending = this.pendingRequests.get(responseId);
170
+ if (!pending) return;
171
+ clearTimeout(pending.timeout);
172
+ this.pendingRequests.delete(responseId);
173
+ const success = (_b = payload == null ? void 0 : payload.success) != null ? _b : true;
174
+ if (success) {
175
+ pending.resolve((payload == null ? void 0 : payload.data) !== void 0 ? payload.data : message.payload);
176
+ } else {
177
+ pending.reject(new Error(((_c = payload == null ? void 0 : payload.error) == null ? void 0 : _c.message) || "Unknown error"));
178
+ }
179
+ }
180
+ handleRequest(message) {
181
+ this.emitLocal(`request:${message.action}`, message);
182
+ }
183
+ handleEvent(message) {
184
+ if (message.action === BRIDGE_READY_ACTION) {
185
+ this.onBridgeReady();
186
+ }
187
+ if (message.action === "batch" && Array.isArray(message.payload)) {
188
+ message.payload.forEach((inner) => this.dispatchMessage(inner));
189
+ return;
190
+ }
191
+ this.emitLocal(`event:${message.action}`, message.payload);
192
+ }
193
+ handleError(message) {
194
+ const pending = this.pendingRequests.get(message.id);
195
+ if (pending) {
196
+ clearTimeout(pending.timeout);
197
+ this.pendingRequests.delete(message.id);
198
+ const err = message.payload;
199
+ pending.reject(new Error((err == null ? void 0 : err.message) || "Bridge error"));
200
+ }
201
+ this.emitLocal("bridge:error", message.payload);
202
+ }
203
+ sendMessage(message) {
204
+ if (!this.isReady && message.action !== BRIDGE_READY_ACTION) {
205
+ this.messageQueue.push(message);
206
+ return;
207
+ }
208
+ this.debugger.logSent(message);
209
+ const deliver = (serialized) => {
210
+ const post = () => {
211
+ var _a;
212
+ (_a = this.webViewRef.current) == null ? void 0 : _a.postMessage(serialized);
213
+ };
214
+ if (Platform.OS === "ios") {
215
+ requestAnimationFrame(post);
216
+ } else {
217
+ post();
218
+ }
219
+ };
220
+ this.chunker.sendChunked(message, deliver);
221
+ if (__DEV__) {
222
+ console.log(`[Bridge] Sent: ${message.action}`, message);
223
+ }
224
+ }
225
+ shouldBatch(action) {
226
+ return action.startsWith("analytics.") || action.startsWith("metrics.");
227
+ }
228
+ addToBatch(message) {
229
+ this.batch.push(message);
230
+ if (this.batch.length >= this.batchConfig.batchSize) {
231
+ this.flushBatch();
232
+ } else if (!this.batchTimeout) {
233
+ this.batchTimeout = setTimeout(() => this.flushBatch(), this.batchConfig.batchDelayMs);
234
+ }
235
+ }
236
+ flushBatch() {
237
+ if (this.batchTimeout) {
238
+ clearTimeout(this.batchTimeout);
239
+ this.batchTimeout = void 0;
240
+ }
241
+ if (this.batch.length === 0) return;
242
+ const batchMessage = {
243
+ id: this.generateId(),
244
+ type: MessageType.EVENT,
245
+ action: "batch",
246
+ payload: this.batch,
247
+ timestamp: Date.now(),
248
+ version: BRIDGE_PROTOCOL_VERSION
249
+ };
250
+ this.batch = [];
251
+ this.sendMessage(batchMessage);
252
+ }
253
+ generateId() {
254
+ return `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;
255
+ }
256
+ }export{NativeWebViewBridge};//# sourceMappingURL=NativeWebViewBridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NativeWebViewBridge.js","sources":["../../src/bridge/NativeWebViewBridge.ts"],"sourcesContent":["import { Platform } from 'react-native';\nimport type { WebView, WebViewMessageEvent } from 'react-native-webview';\nimport type React from 'react';\nimport { CancellableRequest } from './CancellableRequest';\nimport { ChunkedMessageHandler } from './ChunkedMessageHandler';\nimport { BridgeDebugger } from './BridgeDebugger';\nimport {\n BRIDGE_PROTOCOL_VERSION,\n BRIDGE_READY_ACTION,\n DEFAULT_BRIDGE_TIMEOUT_MS,\n MessageType,\n type BridgeErrorPayload,\n type BridgeMessage,\n type BridgeResponse,\n} from './types';\n\ntype PendingRequest = {\n resolve: (value: unknown) => void;\n reject: (error: Error) => void;\n timeout: ReturnType<typeof setTimeout>;\n};\n\ntype BatchConfig = {\n batchSize: number;\n batchDelayMs: number;\n};\n\ntype BridgeListener = (payload: any) => void;\n\n/**\n * Native-side type-safe WebView bridge with READY queue, timeouts,\n * cancellation, chunking, analytics batching, and iOS/Android quirks.\n */\nexport class NativeWebViewBridge {\n private webViewRef: React.RefObject<WebView | null>;\n\n private pendingRequests = new Map<string, PendingRequest>();\n\n private messageQueue: BridgeMessage[] = [];\n\n private isReady = false;\n\n private readonly chunker = new ChunkedMessageHandler();\n\n private readonly debugger = new BridgeDebugger();\n\n private batch: BridgeMessage[] = [];\n\n private batchTimeout?: ReturnType<typeof setTimeout>;\n\n private readonly batchConfig: BatchConfig = { batchSize: 10, batchDelayMs: 100 };\n\n private readonly listeners = new Map<string, Set<BridgeListener>>();\n\n constructor(webViewRef: React.RefObject<WebView | null>) {\n this.webViewRef = webViewRef;\n }\n\n on(event: string, listener: BridgeListener): this {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(listener);\n return this;\n }\n\n off(event: string, listener: BridgeListener): this {\n this.listeners.get(event)?.delete(listener);\n return this;\n }\n\n private emitLocal(event: string, payload?: unknown): void {\n const set = this.listeners.get(event);\n if (!set) return;\n set.forEach((listener) => {\n try {\n listener(payload);\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error(`[Bridge] listener error for ${event}:`, error);\n }\n });\n }\n\n private removeAllListeners(): void {\n this.listeners.clear();\n }\n\n getDebugger(): BridgeDebugger {\n return this.debugger;\n }\n\n request<TRequest, TResponse>(\n action: string,\n payload: TRequest,\n timeoutMs = DEFAULT_BRIDGE_TIMEOUT_MS,\n ): CancellableRequest<TResponse> {\n const id = this.generateId();\n const message: BridgeMessage<TRequest> = {\n id,\n type: MessageType.REQUEST,\n action,\n payload,\n timestamp: Date.now(),\n version: BRIDGE_PROTOCOL_VERSION,\n };\n\n let timeoutId: ReturnType<typeof setTimeout>;\n\n const promise = new Promise<TResponse>((resolve, reject) => {\n timeoutId = setTimeout(() => {\n this.pendingRequests.delete(id);\n reject(new Error(`Request ${action} timed out after ${timeoutMs}ms`));\n }, timeoutMs);\n\n this.pendingRequests.set(id, {\n resolve: resolve as (value: unknown) => void,\n reject,\n timeout: timeoutId,\n });\n\n this.sendMessage(message);\n });\n\n const cancellable = new CancellableRequest<TResponse>(promise, () => {\n clearTimeout(timeoutId);\n this.pendingRequests.delete(id);\n this.sendEvent('request.cancelled', { requestId: id });\n });\n cancellable.addCleanup(() => clearTimeout(timeoutId));\n\n return cancellable;\n }\n\n /** One-way event toward the WebView (batches analytics.* / metrics.*). */\n sendEvent(action: string, payload?: unknown): void {\n const message: BridgeMessage = {\n id: this.generateId(),\n type: MessageType.EVENT,\n action,\n payload,\n timestamp: Date.now(),\n version: BRIDGE_PROTOCOL_VERSION,\n };\n\n if (this.shouldBatch(action)) {\n this.addToBatch(message);\n return;\n }\n\n this.sendMessage(message);\n }\n\n sendResponse(id: string, success: boolean, data?: unknown, error?: BridgeErrorPayload): void {\n const response: BridgeMessage = {\n id,\n type: MessageType.RESPONSE,\n action: 'response',\n payload: {\n id,\n success,\n data,\n error,\n } satisfies BridgeResponse,\n timestamp: Date.now(),\n version: BRIDGE_PROTOCOL_VERSION,\n };\n this.sendMessage(response);\n }\n\n handleMessage(event: WebViewMessageEvent): void {\n // Android may send string; iOS sometimes surfaces an object.\n const rawData = event.nativeEvent.data;\n const data = typeof rawData === 'string' ? rawData : JSON.stringify(rawData);\n\n try {\n const parsed: unknown = JSON.parse(data);\n\n if (this.chunker.isChunkEnvelope(parsed)) {\n const complete = this.chunker.handleChunk(parsed);\n if (complete) this.dispatchMessage(complete);\n return;\n }\n\n this.dispatchMessage(parsed as BridgeMessage);\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error('[Bridge] Failed to parse message:', error);\n }\n }\n\n onBridgeReady(): void {\n this.isReady = true;\n while (this.messageQueue.length > 0) {\n const message = this.messageQueue.shift();\n if (message) this.sendMessage(message);\n }\n }\n\n dispose(): void {\n this.flushBatch();\n this.pendingRequests.forEach((pending) => {\n clearTimeout(pending.timeout);\n pending.reject(new Error('Bridge disposed'));\n });\n this.pendingRequests.clear();\n this.messageQueue = [];\n this.isReady = false;\n this.removeAllListeners();\n }\n\n private dispatchMessage(message: BridgeMessage): void {\n this.debugger.logReceived(message);\n\n switch (message.type) {\n case MessageType.RESPONSE:\n this.handleResponse(message);\n break;\n case MessageType.REQUEST:\n this.handleRequest(message);\n break;\n case MessageType.EVENT:\n this.handleEvent(message);\n break;\n case MessageType.ERROR:\n this.handleError(message);\n break;\n default:\n break;\n }\n }\n\n private handleResponse(message: BridgeMessage): void {\n const payload = message.payload as BridgeResponse | undefined;\n const responseId = payload?.id ?? message.id;\n const pending = this.pendingRequests.get(responseId);\n if (!pending) return;\n\n clearTimeout(pending.timeout);\n this.pendingRequests.delete(responseId);\n\n const success = payload?.success ?? true;\n if (success) {\n pending.resolve(payload?.data !== undefined ? payload.data : message.payload);\n } else {\n pending.reject(new Error(payload?.error?.message || 'Unknown error'));\n }\n }\n\n private handleRequest(message: BridgeMessage): void {\n this.emitLocal(`request:${message.action}`, message);\n }\n\n private handleEvent(message: BridgeMessage): void {\n if (message.action === BRIDGE_READY_ACTION) {\n this.onBridgeReady();\n }\n if (message.action === 'batch' && Array.isArray(message.payload)) {\n (message.payload as BridgeMessage[]).forEach((inner) => this.dispatchMessage(inner));\n return;\n }\n this.emitLocal(`event:${message.action}`, message.payload);\n }\n\n private handleError(message: BridgeMessage): void {\n const pending = this.pendingRequests.get(message.id);\n if (pending) {\n clearTimeout(pending.timeout);\n this.pendingRequests.delete(message.id);\n const err = message.payload as BridgeErrorPayload | undefined;\n pending.reject(new Error(err?.message || 'Bridge error'));\n }\n this.emitLocal('bridge:error', message.payload);\n }\n\n private sendMessage(message: BridgeMessage): void {\n if (!this.isReady && message.action !== BRIDGE_READY_ACTION) {\n this.messageQueue.push(message);\n return;\n }\n\n this.debugger.logSent(message);\n\n const deliver = (serialized: string) => {\n const post = () => {\n this.webViewRef.current?.postMessage(serialized);\n };\n // iOS WebView is more reliable when postMessage is deferred one frame.\n if (Platform.OS === 'ios') {\n requestAnimationFrame(post);\n } else {\n post();\n }\n };\n\n this.chunker.sendChunked(message, deliver);\n\n if (__DEV__) {\n // eslint-disable-next-line no-console\n console.log(`[Bridge] Sent: ${message.action}`, message);\n }\n }\n\n private shouldBatch(action: string): boolean {\n return action.startsWith('analytics.') || action.startsWith('metrics.');\n }\n\n private addToBatch(message: BridgeMessage): void {\n this.batch.push(message);\n if (this.batch.length >= this.batchConfig.batchSize) {\n this.flushBatch();\n } else if (!this.batchTimeout) {\n this.batchTimeout = setTimeout(() => this.flushBatch(), this.batchConfig.batchDelayMs);\n }\n }\n\n private flushBatch(): void {\n if (this.batchTimeout) {\n clearTimeout(this.batchTimeout);\n this.batchTimeout = undefined;\n }\n if (this.batch.length === 0) return;\n\n const batchMessage: BridgeMessage = {\n id: this.generateId(),\n type: MessageType.EVENT,\n action: 'batch',\n payload: this.batch,\n timestamp: Date.now(),\n version: BRIDGE_PROTOCOL_VERSION,\n };\n this.batch = [];\n this.sendMessage(batchMessage);\n }\n\n private generateId(): string {\n return `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;\n }\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ class TypedBridge {
2
+ constructor(bridge) {
3
+ this.bridge = bridge;
4
+ }
5
+ request(action, payload, timeoutMs) {
6
+ return this.bridge.request(action, payload, timeoutMs);
7
+ }
8
+ }export{TypedBridge};//# sourceMappingURL=TypedBridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TypedBridge.js","sources":["../../src/bridge/TypedBridge.ts"],"sourcesContent":["import type { NativeWebViewBridge } from './NativeWebViewBridge';\nimport type { BridgeAPI } from './types';\n\n/** Minimal surface shared by native and web bridges for TypedBridge. */\nexport interface BridgeRequestClient {\n request<TRequest, TResponse>(action: string, payload: TRequest, timeoutMs?: number): PromiseLike<TResponse>;\n}\n\n/**\n * Compile-time checked wrapper over the raw bridge request API.\n */\nexport class TypedBridge {\n constructor(private readonly bridge: BridgeRequestClient | NativeWebViewBridge) {}\n\n request<K extends keyof BridgeAPI>(\n action: K,\n payload: BridgeAPI[K]['request'],\n timeoutMs?: number,\n ): PromiseLike<BridgeAPI[K]['response']> {\n return this.bridge.request(action, payload as never, timeoutMs);\n }\n}\n"],"names":[],"mappings":"AAWO,MAAM,WAAY,CAAA;AAAA,EACvB,YAA6B,MAAmD,EAAA;AAAnD,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AAAA;AAAoD,EACjF,OAAA,CAAmC,MAAW,EAAA,OAAA,EAAkC,SAA2D,EAAA;AACzI,IAAA,OAAO,IAAK,CAAA,MAAA,CAAO,OAAQ,CAAA,MAAA,EAAQ,SAAkB,SAAS,CAAA;AAAA;AAElE"}