wovvmap-webview-bridge 1.0.4 → 1.0.6

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/README.md CHANGED
@@ -1,180 +1,213 @@
1
- # 📱 Native Integration Guide – wovvmap-webview-bridge
2
-
3
- This guide explains how to use the `wovvmap-webview-bridge` package **from the React Native side**. This package helps you send data to a WebView and listen for data coming from the WebView.
4
-
5
- ---
6
-
7
- ## Installation
8
-
9
- ```bash
10
- npm install wovvmap-webview-bridge
11
- # or
12
- yarn add wovvmap-webview-bridge
13
- ```
14
-
15
- ---
16
-
17
- ## 🔌 Setup WebView
18
-
19
- Import and use the `<WebViewScreen />` component provided by the package:
20
-
21
- ```tsx
22
- import React from 'react';
23
- import { View } from 'react-native';
24
- import { WebViewScreen } from 'wovvmap-webview-bridge';
25
-
26
- export default function App() {
27
- return (
28
- <View style={{ flex: 1 }}>
29
- <WebViewScreen url="http://localhost:5173/map" />
30
- </View>
31
- );
32
- }
33
- ```
34
-
35
- ---
36
-
37
- ## 📤 Send Data to WebView
38
-
39
- You can send navigation data (e.g. from, to, elevator, escalator) using `sendToWeb`:
40
-
41
- ```ts
42
- import { sendToWeb } from 'wovvmap-webview-bridge';
43
-
44
- sendToWeb({
45
- type: "setNavigationData",
46
- payload: {
47
- from: "store1",
48
- to: "store9",
49
- elevator: false,
50
- escalator: true,
51
- floor : 1
52
- },
53
- });
54
- ```
55
-
56
- ---
57
-
58
- ## 📥 Receive Events from WebView
59
-
60
- Use `registerBridgeHandler` to listen for events sent from the web:
61
-
62
- ```ts
63
- import { registerBridgeHandler } from 'wovvmap-webview-bridge';
64
-
65
- registerBridgeHandler("pathData", (points) => {
66
- console.log("📍 Received pathData:", points);
67
- });
68
-
69
- registerBridgeHandler("PathFindingResult", (result) => {
70
- console.log("🧭 Path result:", result);
71
- });
72
-
73
- registerBridgeHandler("changeFloor", (floor) => {
74
- console.log("🏢 Web requested floor change:", floor);
75
- });
76
- ```
77
-
78
- ---
79
-
80
- ## 🧠 Data Types
81
-
82
- The bridge handles these types safely:
83
-
84
- ```ts
85
- type SendToWebMessage = {
86
- type: "setNavigationData";
87
- payload: {
88
- from?: string;
89
- to?: string;
90
- elevator?: boolean;
91
- escalator?: boolean;
92
- floor?: boolean;
93
- };
94
- };
95
-
96
- type BridgeMessage =
97
- | { type: "event"; key: "floor"; value: number }
98
- | { type: "event"; key: "pathData"; value: NodePoint[] }
99
- | { type: "event"; key: "PathFindingResult"; value: PathFindingResult }
100
- | { type: "event"; key: "searchTextResult"; value: NodePoint[] }
101
- | { type: "event"; key: "shapeZoomAndSelect"; value: NodePoint | undefined }
102
- | { type: "event"; key: "searchablePoints"; value: NodePoint[] }
103
- | { type: "event"; key: "nodePoint"; value: {[key:string]: NodePointOuterFiled} }
104
- | { type: "event"; key: "nodeline"; value: {[key:string]: NodeLineOuterFiled} }
105
- | { type: "event"; key: "categoryList"; value: { [key: string]: NodePoint } }
106
- | {
107
- type: "event"; key: "floorInfo"; value: {
108
- floors: {
109
- index: number;
110
- shortName: string;
111
- fullName: string;
112
- floorNumber: number;
113
- }[],
114
- defaultFloorIndex: number
115
- }
116
- }
117
- | { type: "event"; key: "to"; value:string}
118
- | { type: "event"; key: "from"; value:string}
119
- | { type: "event"; key: "elevator"; value:"true" | "false"}
120
- | { type: "event"; key: "escalator"; value:"true" | "false"}
121
-
122
-
123
-
124
- type EventHandlerMap = {
125
- floor?: (floor: number) => void;
126
- pathData?: (val: NodePoint[]) => void;
127
- PathFindingResult?: (val: PathFindingResult) => void;
128
- searchTextResult?: (val: NodePoint[]) => void;
129
- shapeZoomAndSelect?: (val: NodePoint | undefined) => void;
130
- searchablePoints?: (val: NodePoint[]) => void;
131
- nodePoint?: (val: { [key: string]: NodePointOuterFiled }) => void;
132
- nodeline?: (val: { [key: string]: NodeLineOuterFiled }) => void;
133
- categoryList?: (val: { [key: string]: NodePoint }) => void;
134
- floorInfo?: (val: {
135
- floors: {
136
- index: number;
137
- shortName: string;
138
- fullName: string;
139
- floorNumber: number;
140
- }[];
141
- defaultFloorIndex: number;
142
- }) => void;
143
- to?: (val: string) => void;
144
- from?: (val: string) => void;
145
- elevator?: (val: "true" | "false") => void;
146
- escalator?: (val: "true" | "false") => void;
147
- };
148
-
149
- ```
150
-
151
- ---
152
-
153
- ## 💡 Tips
154
-
155
- - All bridge messages are serialized using `JSON.stringify`. Avoid non-serializable data like Maps or circular references.
156
- - WebView must have messaging enabled (already done in `<WebViewScreen />`).
157
- - You can directly access the `webviewRef` if needed.
158
-
159
- ```ts
160
- import { webviewRef } from 'wovvmap-webview-bridge';
161
- ```
162
-
163
- ---
164
-
165
- ## 📄 Summary of Exports (Native Side)
166
-
167
- ```ts
168
- import {
169
- WebViewScreen,
170
- sendToWeb,
171
- webviewRef,
172
- registerBridgeHandler,
173
- } from 'wovvmap-webview-bridge';
174
- ```
175
-
176
- ---
177
-
178
- ## 📘 Done!
179
-
180
- You're now ready to communicate seamlessly between React Native and your WebView 🎉
1
+
2
+ # React Native WebView Bridge
3
+
4
+ A tiny bridge layer to communicate between a React Native app (using `react-native-webview`) and a web page. It provides:
5
+
6
+ - A ready-to-use `<WebViewScreen />` wrapper
7
+ - A simple `sendToWeb(...)` API for posting messages to the webview
8
+ - Typed event handling for messages coming **from** the web page
9
+ - Lightweight in-app state storage (via `koshin`) to keep UI in sync with bridge events
10
+
11
+ > **Demo idea:** Your message referenced a Snack example. You can adapt this package to the same flow as in your Snack: https://snack.expo.dev/@krushnkant/react-native-webview
12
+
13
+ ---
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ # with npm
19
+ npm i react-native-webview
20
+
21
+ # or with yarn
22
+ yarn add react-native-webview
23
+
24
+ # or with pnpm
25
+ pnpm add react-native-webview
26
+ ```
27
+
28
+ ---
29
+
30
+ ## Quick Start
31
+
32
+ 1) **Render the WebView and hook the bridge handler**
33
+
34
+ ```tsx
35
+ import React from "react";
36
+ import { WebViewScreen } from "<your-package-name>";
37
+ // If you want to register custom event callbacks:
38
+ import { registerBridgeHandler } from "<your-package-name>";
39
+
40
+ export default function App() {
41
+ React.useEffect(() => {
42
+ // Optional handlers for clicks coming from the web scene
43
+ registerBridgeHandler("isSceneClick", (evt) => {
44
+ console.log("Scene clicked:", evt);
45
+ });
46
+ registerBridgeHandler("isShapClick", (evt) => {
47
+ console.log("Shape clicked:", evt.value);
48
+ });
49
+ }, []);
50
+
51
+ return <WebViewScreen url={"https://your-web-app.example.com"} />;
52
+ }
53
+ ```
54
+
55
+ Under the hood, `<WebViewScreen />` wires `onMessage` to the bridge message handler so any `postMessage(...)` coming from your web page is typed and routed correctly. fileciteturn1file6
56
+
57
+ 2) **Send commands *to* the web app**
58
+
59
+ ```ts
60
+ import {
61
+ sendActiveFloorToBridge,
62
+ sendEndPointToBridge,
63
+ sendPathFinishBtnClick,
64
+ sendPathNextBtnClick,
65
+ sendPathPreBtnClick,
66
+ sendStartPointToBridge,
67
+ } from "<your-package-name>";
68
+
69
+ // examples:
70
+ sendStartPointToBridge("node_123");
71
+ sendEndPointToBridge("node_999");
72
+ sendActiveFloorToBridge(2);
73
+ sendPathNextBtnClick();
74
+ sendPathPreBtnClick();
75
+ sendPathFinishBtnClick();
76
+ ```
77
+
78
+ These helpers call the shared `sendToWeb(...)` which posts a JSON-serialized message to the underlying `WebView` instance. fileciteturn1file1 fileciteturn1file7
79
+
80
+ 3) **Keep UI in sync with bridge state (optional)**
81
+
82
+ ```ts
83
+ import { bridgeStorage } from "<your-package-name>";
84
+
85
+ bridgeStorage.subscribe((state) => {
86
+ // state includes: isBridgeLoaded, isMapLoaded, searchablePoints, activeFloor, etc.
87
+ console.log(state);
88
+ });
89
+ ```
90
+
91
+ Internally this uses a small `koshin` store with fields like `isBridgeLoaded`, `isMapLoaded`, `searchablePoints`, `activeFloor`, `floorImages`, `stapByStapList`, and `nextPreState`. fileciteturn1file0
92
+
93
+ ---
94
+
95
+ ## What the Web Page Should Send
96
+
97
+ Your web page (inside the WebView) should `postMessage(JSON.stringify(...))` with the following **Incoming** event shapes:
98
+
99
+ ```ts
100
+ type IncomingMessage =
101
+ | { type: "event"; key: "isConnection"; value: boolean; file: string }
102
+ | { type: "event"; key: "mapLoaded"; value: boolean; file: string }
103
+ | { type: "event"; key: "_searchablePoints"; value: NodePoint[]; file: string }
104
+ | { type: "event"; key: "Category"; value: Category[]; file: string }
105
+ | { type: "event"; key: "_activeFloor"; value: number; file: string }
106
+ | { type: "event"; key: "FloorImg"; value: FloorImage[]; file: string }
107
+ | { type: "event"; key: "isSceneClick"; file: string }
108
+ | { type: "event"; key: "isShapClick"; value: NodePoint; file: string }
109
+ | { type: "event"; key: "stapByStapList"; value: StepInstruction[]; file: string }
110
+ | { type: "event"; key: "pathNextPreState"; value: NavState; file: string };
111
+ ```
112
+ The built-in handler parses the message, updates store fields, and triggers any registered callbacks for `isSceneClick` / `isShapClick`. fileciteturn1file3 fileciteturn1file2
113
+
114
+ ---
115
+
116
+ ## What the App Sends to the Web Page
117
+
118
+ Outgoing commands you can dispatch from React Native:
119
+
120
+ ```ts
121
+ type OutgoingMessage =
122
+ | { type: "applyCSS"; selector: string; style: Partial<Record<string, string | number>> }
123
+ | { type: "event"; key: "ping"; value: boolean; file: string }
124
+ | { type: "event"; key: "setEndPoint"; value: string; file: string }
125
+ | { type: "event"; key: "setStartPoint"; value: string; file: string }
126
+ | { type: "event"; key: "setActiveFloor"; value: number; file: string }
127
+ | { type: "event"; key: "pathNextBtnClick"; file: string }
128
+ | { type: "event"; key: "pathPreBtnClick"; file: string }
129
+ | { type: "event"; key: "pathFinishBtnClick"; file: string };
130
+ ```
131
+ These go through `sendToWeb(...)` which uses a shared `webviewRef` to `postMessage(...)`. fileciteturn1file7
132
+
133
+ ---
134
+
135
+ ## API Reference
136
+
137
+ ### Components
138
+
139
+ #### `<WebViewScreen />`
140
+ A thin wrapper around `react-native-webview` that plugs in the bridge message handler.
141
+
142
+ **Props**
143
+ - `url: string` the URL to load inside the WebView.
144
+
145
+ fileciteturn1file6
146
+
147
+ ### Functions
148
+
149
+ - `registerBridgeHandler(type, handler)` — Register a callback for `"isSceneClick"` or `"isShapClick"` events. fileciteturn1file3
150
+ - `sendStartPointToBridge(pointId)` — Ask web map to set the start point. fileciteturn1file1
151
+ - `sendEndPointToBridge(pointId)` — Ask web map to set the end point. fileciteturn1file1
152
+ - `sendActiveFloorToBridge(floorIndex)` — Switch active floor on the web map. fileciteturn1file1
153
+ - `sendPathNextBtnClick()` / `sendPathPreBtnClick()` / `sendPathFinishBtnClick()` — Control path stepper on the web map. fileciteturn1file1
154
+ - `bridgeStorage` — Reactive store with connection and navigation-related state. fileciteturn1file0
155
+
156
+ ### Types (partial)
157
+ - `NodePoint`, `Category`, `FloorImage`, `StepInstruction`, `NavState`, `IncomingMessage`, `OutgoingMessage` TypeScript contracts shared across the bridge. fileciteturn1file5
158
+
159
+ ---
160
+
161
+ ## Minimal Web Side (Example)
162
+
163
+ Your web app should listen for messages and respond via `window.ReactNativeWebView.postMessage(...)`:
164
+
165
+ ```js
166
+ // inside the web page
167
+ window.addEventListener("message", (e) => {
168
+ try {
169
+ const msg = JSON.parse(e.data);
170
+ if (msg.type === "event" && msg.key === "setActiveFloor") {
171
+ // do something in the web app
172
+ console.log("Active floor requested:", msg.value);
173
+ // notify RN app that web is connected
174
+ window.ReactNativeWebView?.postMessage(JSON.stringify({
175
+ type: "event",
176
+ key: "isConnection",
177
+ value: true,
178
+ file: "web-app",
179
+ }));
180
+ }
181
+ } catch {}
182
+ });
183
+ ```
184
+
185
+ ---
186
+
187
+ ## Project Structure (Library)
188
+
189
+ ```
190
+ src/
191
+ ├─ index.ts # package exports fileciteturn1file4
192
+ ├─ handlers/WebBridgeHandlers # incoming event router & registration fileciteturn1file3
193
+ ├─ webviewBridge/WebViewBridgeRef.ts # shared ref + sendToWeb fileciteturn1file7
194
+ ├─ webviewBridge/BridgeService.ts # convenience sending helpers fileciteturn1file1
195
+ ├─ webviewBridge/BridgeStorage.ts # tiny state store (koshin) fileciteturn1file0
196
+ ├─ webviewBridge/WebViewScreen.tsx # ready-to-use WebView wrapper fileciteturn1file6
197
+ ├─ types/types.ts # shared TS contracts fileciteturn1file5
198
+ ```
199
+
200
+ ---
201
+
202
+ ## Requirements
203
+
204
+ - React Native
205
+ - [`react-native-webview`](https://github.com/react-native-webview/react-native-webview)
206
+ - [`koshin`](https://www.npmjs.com/package/koshin)
207
+ - TypeScript recommended
208
+
209
+ ---
210
+
211
+ ## License
212
+
213
+ MIT © Your Name
@@ -1,38 +1,18 @@
1
1
  import type { WebViewMessageEvent } from "react-native-webview";
2
- import type { NodeLineOuterFiled, NodePointOuterFiled } from "../types/BridgeMessage";
3
- import { PathFindingResult } from "../types/PathFindingResult";
4
- import { SerializableNodePoint as NodePoint } from "../types/NodePoint";
2
+ import { NodePoint } from "../types/types";
5
3
  export type EventHandlerMap = {
6
- floor?: (floor: number) => void;
7
- pathData?: (val: NodePoint[]) => void;
8
- PathFindingResult?: (val: PathFindingResult) => void;
9
- searchTextResult?: (val: NodePoint[]) => void;
10
- shapeZoomAndSelect?: (val: NodePoint | undefined) => void;
11
- searchablePoints?: (val: NodePoint[]) => void;
12
- nodePoint?: (val: {
13
- [key: string]: NodePointOuterFiled;
4
+ isSceneClick?: (sceneClick: {
5
+ type: "event";
6
+ key: "isSceneClick";
7
+ file: string;
14
8
  }) => void;
15
- nodeline?: (val: {
16
- [key: string]: NodeLineOuterFiled;
9
+ isShapClick?: (shapClick: {
10
+ type: "event";
11
+ key: "isShapClick";
12
+ value: NodePoint;
13
+ file: string;
17
14
  }) => void;
18
- categoryList?: (val: {
19
- [key: string]: NodePoint;
20
- }) => void;
21
- floorInfo?: (val: {
22
- floors: {
23
- index: number;
24
- shortName: string;
25
- fullName: string;
26
- floorNumber: number;
27
- }[];
28
- defaultFloorIndex: number;
29
- }) => void;
30
- to?: (val: string) => void;
31
- from?: (val: string) => void;
32
- elevator?: (val: "true" | "false") => void;
33
- escalator?: (val: "true" | "false") => void;
34
15
  };
35
16
  export declare const eventHandlers: Partial<EventHandlerMap>;
36
- export declare const bridgeMessageStore: Partial<Record<keyof EventHandlerMap, any>>;
37
17
  export declare const registerBridgeHandler: <K extends keyof EventHandlerMap>(type: K, handler: EventHandlerMap[K]) => void;
38
18
  export declare const handleBridgeMessage: (event: WebViewMessageEvent) => void;
@@ -1,24 +1,33 @@
1
+ import { bridgeStorage } from "../webviewBridge/BridgeStorage";
1
2
  // ✅ 2. Global handler storage
2
3
  export var eventHandlers = {};
3
- // ✅ 3. Runtime key-value store for all event data
4
- export var bridgeMessageStore = {};
5
4
  // ✅ 4. Register handler function
6
5
  export var registerBridgeHandler = function (type, handler) {
7
6
  eventHandlers[type] = handler;
8
7
  };
9
8
  // ✅ 5. Main bridge handler
10
9
  export var handleBridgeMessage = function (event) {
10
+ var _a, _b;
11
11
  try {
12
- var data = JSON.parse(event.nativeEvent.data);
13
- if (data.type === "event") {
14
- var key = data.key;
15
- var fn = eventHandlers[key];
16
- // ✅ Store latest data in bridgeMessageStore
17
- bridgeMessageStore[key] = data.value;
18
- // ✅ Call handler if available
19
- // @ts-expect-error safe
20
- fn === null || fn === void 0 ? void 0 : fn(data.value);
21
- }
12
+ var message = JSON.parse(event.nativeEvent.data);
13
+ if (message.key === "mapLoaded")
14
+ bridgeStorage.set("isMapLoaded", message.value);
15
+ if (message.key === "isConnection")
16
+ bridgeStorage.set("isBridgeLoaded", message.value);
17
+ if (message.key === "_searchablePoints")
18
+ bridgeStorage.set("searchablePoints", message.value);
19
+ if (message.key === "_activeFloor")
20
+ bridgeStorage.set("activeFloor", message.value);
21
+ if (message.key === "FloorImg")
22
+ bridgeStorage.set("floorImages", message.value);
23
+ if (message.key === "isSceneClick")
24
+ (_a = eventHandlers[message.key]) === null || _a === void 0 ? void 0 : _a.call(eventHandlers, message);
25
+ if (message.key === "isShapClick")
26
+ (_b = eventHandlers[message.key]) === null || _b === void 0 ? void 0 : _b.call(eventHandlers, message);
27
+ if (message.key === "stapByStapList")
28
+ bridgeStorage.set("stapByStapList", message.value);
29
+ if (message.key === "pathNextPreState")
30
+ bridgeStorage.set("nextPreState", message.value);
22
31
  }
23
32
  catch (e) {
24
33
  console.error("WebView message error:", e);
package/dist/index.d.ts CHANGED
@@ -1,7 +1,4 @@
1
1
  export { WebViewScreen } from './webviewBridge/WebViewScreen';
2
- export { sendToWeb, webviewRef } from './webviewBridge/WebViewBridgeRef';
3
- export { PathFindingResult } from './types/PathFindingResult';
4
- export { NavigationInstruction, SerializablePoint2D, SerializableNodePoint } from './types/NodePoint';
5
- export { NodePointOuterFiled, Point3D, NodeLineOuterFiled, SendToWebMessage } from './types/BridgeMessage';
6
- export { bridgeMessageStore, eventHandlers, handleBridgeMessage, registerBridgeHandler } from './handlers/WebBridgeHandlers';
7
- export { EventHandlerMap } from './handlers/WebBridgeHandlers';
2
+ export { eventHandlers, registerBridgeHandler } from './handlers/WebBridgeHandlers';
3
+ export { bridgeStorage } from './webviewBridge/BridgeStorage';
4
+ export { sendActiveFloorToBridge, sendEndPointToBridge, sendPathFinishBtnClick, sendPathNextBtnClick, sendPathPreBtnClick, sendStartPointToBridge } from './webviewBridge/BridgeService';
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
1
  export { WebViewScreen } from './webviewBridge/WebViewScreen';
2
- export { sendToWeb, webviewRef } from './webviewBridge/WebViewBridgeRef';
3
- export { bridgeMessageStore, eventHandlers, handleBridgeMessage, registerBridgeHandler } from './handlers/WebBridgeHandlers';
2
+ export { eventHandlers, registerBridgeHandler } from './handlers/WebBridgeHandlers';
3
+ export { bridgeStorage } from './webviewBridge/BridgeStorage';
4
+ export { sendActiveFloorToBridge, sendEndPointToBridge, sendPathFinishBtnClick, sendPathNextBtnClick, sendPathPreBtnClick, sendStartPointToBridge } from './webviewBridge/BridgeService';
@@ -0,0 +1,178 @@
1
+ export interface LocationArea {
2
+ x: number;
3
+ y: number;
4
+ }
5
+ export interface LocationName {
6
+ text: string;
7
+ area: LocationArea;
8
+ rotate: number;
9
+ textColor: string;
10
+ textSize: string;
11
+ textStyle: string;
12
+ width: string;
13
+ height: string;
14
+ }
15
+ export interface Logo {
16
+ show: boolean;
17
+ url: string;
18
+ size: number;
19
+ x: number;
20
+ y: number;
21
+ rotate: number;
22
+ }
23
+ export interface ShapePoint {
24
+ x: number;
25
+ y: number;
26
+ }
27
+ export interface BrandId {
28
+ sit: string;
29
+ }
30
+ export interface NodePoint {
31
+ x: number;
32
+ y: number;
33
+ z: number;
34
+ targetDist: number;
35
+ previousNode: any;
36
+ close: boolean;
37
+ colleague: any[];
38
+ elementTag: string;
39
+ LocationName: LocationName;
40
+ Category: string;
41
+ type: string;
42
+ LeaseType: string;
43
+ logo: Logo;
44
+ color: string;
45
+ Description: string;
46
+ shape: ShapePoint[];
47
+ up: boolean;
48
+ down: boolean;
49
+ depth: number;
50
+ brand_Id: BrandId;
51
+ floorBash: boolean;
52
+ extra: Record<string, any>;
53
+ key: string;
54
+ myAngle: number;
55
+ NavigationInstruction: any;
56
+ distanceToNextPoint: number;
57
+ stepsToNextPoint: number;
58
+ }
59
+ export interface Category {
60
+ name: string;
61
+ Description: string;
62
+ color: string;
63
+ }
64
+ export interface FloorImage {
65
+ FloorName: string;
66
+ FloorUrl: string;
67
+ ShortName: string;
68
+ FloorNumber: number;
69
+ SubFloor?: boolean;
70
+ index: number;
71
+ }
72
+ export interface StepInstruction {
73
+ instruction: string;
74
+ distance: string;
75
+ steps?: number;
76
+ icon: "left" | "right" | "startPoint" | "endPoint" | "Take Elevator" | "Take Escalator" | "Exit Elevator" | "Exit Escalator" | null;
77
+ }
78
+ export type NavState = {
79
+ currentFloorIndex: number;
80
+ currentPointIndex: number;
81
+ totalFloors: number;
82
+ floorLengths: number[];
83
+ canPrev: boolean;
84
+ canNext: boolean;
85
+ isLastStep: boolean;
86
+ hasPath: boolean;
87
+ };
88
+ export type IncomingMessage = {
89
+ type: "event";
90
+ key: "pong";
91
+ file: string;
92
+ } | {
93
+ type: "event";
94
+ key: "isConnection";
95
+ value: boolean;
96
+ file: string;
97
+ } | {
98
+ type: "event";
99
+ key: "mapLoaded";
100
+ value: boolean;
101
+ file: string;
102
+ } | {
103
+ type: "event";
104
+ key: "_searchablePoints";
105
+ value: NodePoint[];
106
+ file: string;
107
+ } | {
108
+ type: "event";
109
+ key: "Category";
110
+ value: Category[];
111
+ file: string;
112
+ } | {
113
+ type: "event";
114
+ key: "_activeFloor";
115
+ value: number;
116
+ file: string;
117
+ } | {
118
+ type: "event";
119
+ key: "FloorImg";
120
+ value: FloorImage[];
121
+ file: string;
122
+ } | {
123
+ type: "event";
124
+ key: "isSceneClick";
125
+ file: string;
126
+ } | {
127
+ type: "event";
128
+ key: "isShapClick";
129
+ value: NodePoint;
130
+ file: string;
131
+ } | {
132
+ type: "event";
133
+ key: "stapByStapList";
134
+ value: StepInstruction[];
135
+ file: string;
136
+ } | {
137
+ type: "event";
138
+ key: "pathNextPreState";
139
+ value: NavState;
140
+ file: string;
141
+ };
142
+ export type OutgoingMessage = {
143
+ type: "applyCSS";
144
+ selector: string;
145
+ style: Partial<Record<string, string | number>>;
146
+ } | {
147
+ type: "event";
148
+ key: "ping";
149
+ value: boolean;
150
+ file: string;
151
+ } | {
152
+ type: "event";
153
+ key: "setEndPoint";
154
+ value: string;
155
+ file: string;
156
+ } | {
157
+ type: "event";
158
+ key: "setStartPoint";
159
+ value: string;
160
+ file: string;
161
+ } | {
162
+ type: "event";
163
+ key: "setActiveFloor";
164
+ value: number;
165
+ file: string;
166
+ } | {
167
+ type: "event";
168
+ key: "pathNextBtnClick";
169
+ file: string;
170
+ } | {
171
+ type: "event";
172
+ key: "pathPreBtnClick";
173
+ file: string;
174
+ } | {
175
+ type: "event";
176
+ key: "pathFinishBtnClick";
177
+ file: string;
178
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,6 @@
1
+ export declare const sendEndPointToBridge: (endPointId: string) => void;
2
+ export declare const sendStartPointToBridge: (startPointId: string) => void;
3
+ export declare const sendActiveFloorToBridge: (floorId: number) => void;
4
+ export declare const sendPathNextBtnClick: () => void;
5
+ export declare const sendPathPreBtnClick: () => void;
6
+ export declare const sendPathFinishBtnClick: () => void;
@@ -0,0 +1,19 @@
1
+ import { sendToWeb } from "./WebViewBridgeRef";
2
+ export var sendEndPointToBridge = function (endPointId) {
3
+ sendToWeb({ type: "event", key: "setEndPoint", value: endPointId, file: "BridgeService.ts" });
4
+ };
5
+ export var sendStartPointToBridge = function (startPointId) {
6
+ sendToWeb({ type: "event", key: "setStartPoint", value: startPointId, file: "BridgeService.ts" });
7
+ };
8
+ export var sendActiveFloorToBridge = function (floorId) {
9
+ sendToWeb({ type: "event", key: "setActiveFloor", value: floorId, file: "BridgeService.ts" });
10
+ };
11
+ export var sendPathNextBtnClick = function () {
12
+ sendToWeb({ type: "event", key: "pathNextBtnClick", file: "BridgeService.ts" });
13
+ };
14
+ export var sendPathPreBtnClick = function () {
15
+ sendToWeb({ type: "event", key: "pathPreBtnClick", file: "BridgeService.ts" });
16
+ };
17
+ export var sendPathFinishBtnClick = function () {
18
+ sendToWeb({ type: "event", key: "pathFinishBtnClick", file: "BridgeService.ts" });
19
+ };
@@ -0,0 +1,18 @@
1
+ import type { FloorImage, NavState, NodePoint, StepInstruction } from "../types/types";
2
+ type BridgeStorage = {
3
+ isBridgeLoaded: boolean;
4
+ isMapLoaded: boolean;
5
+ searchablePoints: NodePoint[];
6
+ activeFloor: number;
7
+ elevator: "true" | "false";
8
+ escalator: "true" | "false";
9
+ floorImages: FloorImage[];
10
+ stapByStapList: StepInstruction[];
11
+ nextPreState: NavState | null;
12
+ };
13
+ export declare let bridgeStorage: BridgeStorage & {
14
+ set<K extends keyof BridgeStorage>(key: K, value: BridgeStorage[K]): void;
15
+ onChange(callback: <K extends keyof BridgeStorage>(key: K, newValue: BridgeStorage[K], oldValue: BridgeStorage[K]) => void): () => void;
16
+ signal<K extends keyof BridgeStorage>(key: K): [BridgeStorage[K], (value: BridgeStorage[K]) => void];
17
+ };
18
+ export {};
@@ -0,0 +1,12 @@
1
+ import { createStore } from "koshin";
2
+ export var bridgeStorage = createStore({
3
+ isBridgeLoaded: false,
4
+ isMapLoaded: false,
5
+ searchablePoints: [],
6
+ activeFloor: -1,
7
+ elevator: "false",
8
+ escalator: "false",
9
+ floorImages: [],
10
+ stapByStapList: [],
11
+ nextPreState: null
12
+ });
@@ -1,4 +1,4 @@
1
1
  import type { WebView } from "react-native-webview";
2
- import type { SendToWebMessage } from "../types/BridgeMessage";
2
+ import { OutgoingMessage } from "../types/types";
3
3
  export declare const webviewRef: import("react").RefObject<WebView<{}> | null>;
4
- export declare const sendToWeb: (data: SendToWebMessage) => void;
4
+ export declare const sendToWeb: (data: OutgoingMessage) => void;
@@ -3,7 +3,9 @@ import { createRef } from "react";
3
3
  export var webviewRef = createRef();
4
4
  // Exported send function
5
5
  export var sendToWeb = function (data) {
6
+ console.log("webviweRef", webviewRef);
6
7
  if (webviewRef.current) {
8
+ console.log("enter current");
7
9
  webviewRef.current.postMessage(JSON.stringify(data));
8
10
  }
9
11
  else {
@@ -1,12 +1,15 @@
1
1
  import React from "react";
2
- import { WebView } from "react-native-webview";
3
2
  import { handleBridgeMessage } from "../handlers/WebBridgeHandlers";
4
3
  import { webviewRef } from "./WebViewBridgeRef";
4
+ import { WebView } from 'react-native-webview';
5
5
  export var WebViewScreen = function (_a) {
6
6
  var url = _a.url;
7
7
  var onMessage = function (event) {
8
8
  console.log("on message event", event);
9
9
  handleBridgeMessage(event);
10
10
  };
11
- return (React.createElement(WebView, { ref: webviewRef, source: { uri: url }, onMessage: onMessage, style: { flex: 1 } }));
11
+ return (React.createElement(WebView, { ref: webviewRef, source: { uri: url }, onMessage: onMessage, onLoadStart: function () { return console.log("WebView: load start", url); }, onLoadEnd: function () { return console.log("WebView: load end"); }, onLoadProgress: function (_a) {
12
+ var nativeEvent = _a.nativeEvent;
13
+ return console.log("WebView: progress", nativeEvent.progress);
14
+ }, onError: function (e) { return console.warn("WebView error:", e.nativeEvent); }, style: { flex: 1, width: "100%" } }));
12
15
  };
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "wovvmap-webview-bridge",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "files": [
7
- "dist"
7
+ "dist"
8
8
  ],
9
9
  "scripts": {
10
10
  "build": "tsc "
@@ -12,9 +12,11 @@
12
12
  "peerDependencies": {
13
13
  "react": "^19.1.0",
14
14
  "react-native": "^0.80.1",
15
- "react-native-webview": "^13.15.0"
15
+ "react-native-webview": "^13.15.0",
16
+ "koshin": "^1.0.5"
16
17
  },
17
18
  "devDependencies": {
18
19
  "@types/react": "^19.1.8"
19
20
  }
21
+
20
22
  }
@@ -1,102 +0,0 @@
1
- import { SerializableNodePoint as NodePoint, SerializablePoint2D as Point2D } from "./NodePoint";
2
- import { PathFindingResult } from "./PathFindingResult";
3
- export interface NodePointOuterFiled {
4
- point: NodePoint;
5
- name: string;
6
- x: number;
7
- y: number;
8
- z: number;
9
- }
10
- export interface Point3D extends Point2D {
11
- z: number;
12
- }
13
- export interface NodeLineOuterFiled {
14
- a: Point3D;
15
- b: Point3D;
16
- distance: number;
17
- pointA: NodePoint;
18
- pointB: NodePoint;
19
- }
20
- export type BridgeMessage = {
21
- type: "event";
22
- key: "floor";
23
- value: number;
24
- } | {
25
- type: "event";
26
- key: "pathData";
27
- value: NodePoint[];
28
- } | {
29
- type: "event";
30
- key: "PathFindingResult";
31
- value: PathFindingResult;
32
- } | {
33
- type: "event";
34
- key: "searchTextResult";
35
- value: NodePoint[];
36
- } | {
37
- type: "event";
38
- key: "shapeZoomAndSelect";
39
- value: NodePoint | undefined;
40
- } | {
41
- type: "event";
42
- key: "searchablePoints";
43
- value: NodePoint[];
44
- } | {
45
- type: "event";
46
- key: "nodePoint";
47
- value: {
48
- [key: string]: NodePointOuterFiled;
49
- };
50
- } | {
51
- type: "event";
52
- key: "nodeline";
53
- value: {
54
- [key: string]: NodeLineOuterFiled;
55
- };
56
- } | {
57
- type: "event";
58
- key: "categoryList";
59
- value: {
60
- [key: string]: NodePoint;
61
- };
62
- } | {
63
- type: "event";
64
- key: "floorInfo";
65
- value: {
66
- floors: {
67
- index: number;
68
- shortName: string;
69
- fullName: string;
70
- floorNumber: number;
71
- }[];
72
- defaultFloorIndex: number;
73
- };
74
- } | {
75
- type: "event";
76
- key: "to";
77
- value: string;
78
- } | {
79
- type: "event";
80
- key: "from";
81
- value: string;
82
- } | {
83
- type: "event";
84
- key: "elevator";
85
- value: "true" | "false";
86
- } | {
87
- type: "event";
88
- key: "escalator";
89
- value: "true" | "false";
90
- };
91
- export type SendToWebMessage = {
92
- type: "setNavigationData";
93
- payload: {
94
- from?: string;
95
- to?: string;
96
- elevator?: boolean;
97
- escalator?: boolean;
98
- floor?: number;
99
- };
100
- } | {
101
- type: "condtiotion";
102
- };
@@ -1,2 +0,0 @@
1
- // Shared types
2
- export {};
@@ -1,36 +0,0 @@
1
- export type NavigationInstruction = "left" | "right" | "startPoint" | "endPoint" | "Take Elevator" | "Take Escalator" | "Exit Elevator" | "Exit Escalator" | null;
2
- export type SerializablePoint2D = {
3
- x: number;
4
- y: number;
5
- };
6
- export type SerializableNodePoint = {
7
- x?: number;
8
- y?: number;
9
- z?: number;
10
- targetDist?: number;
11
- close?: boolean;
12
- elementTag?: string;
13
- type?: string;
14
- LeaseType?: string;
15
- Category?: string;
16
- color?: string;
17
- Description?: string;
18
- shape?: SerializablePoint2D[];
19
- key?: string;
20
- myAngle?: number;
21
- NavigationInstruction?: NavigationInstruction;
22
- distanceToNextPoint: number;
23
- stepsToNextPoint: number;
24
- floorBash?: boolean;
25
- brand_Id?: string | null;
26
- LocationName?: {
27
- text?: string;
28
- textColor?: string;
29
- textSize?: string;
30
- rotate?: number;
31
- };
32
- colleague?: {
33
- name: string;
34
- role?: string;
35
- }[];
36
- };
@@ -1,2 +0,0 @@
1
- // src/types/NodePoint.ts
2
- export {};
@@ -1,6 +0,0 @@
1
- import { SerializableNodePoint } from "./NodePoint";
2
- export type PathFindingResult = {
3
- path: SerializableNodePoint[];
4
- totalCost: number;
5
- floor: number;
6
- };
@@ -1,2 +0,0 @@
1
- // src/types/PathFindingResult.ts
2
- export {};