@fuzionx/core 0.1.39 → 0.1.41

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/lib/router.js CHANGED
@@ -1,55 +1,55 @@
1
- /**
2
- * Router — fuzionx-bridge의 registerRoute/buildRoutes를 래핑하는 라우트 매니저.
3
- * Express 스타일 path를 Rust 라우터 형식({param})으로 변환.
4
- */
5
- export class Router {
6
- constructor(bridge) {
7
- this._bridge = bridge;
8
- this._routes = []; // { method, path, handlers }
9
- this._handlerMap = {}; // handlerId → handlers[]
10
- this._nextId = 1;
11
- this._built = false;
12
- }
13
-
14
- /**
15
- * 라우트 추가
16
- * @param {string} method - HTTP 메서드
17
- * @param {string} routePath - Express 스타일 경로 (예: /api/users/:id)
18
- * @param {Function[]} handlers - 핸들러 배열
19
- */
20
- add(method, routePath, handlers) {
21
- if (this._built) {
22
- throw new Error('라우트는 listen() 호출 전에 등록해야 합니다');
23
- }
24
-
25
- // Express :param → Rust {param} 변환
26
- const rustPath = routePath.replace(/:([a-zA-Z_][a-zA-Z0-9_]*)/g, '{$1}');
27
- const handlerId = this._nextId++;
28
-
29
- this._routes.push({ method, path: rustPath, handlerId, handlers });
30
- this._handlerMap[handlerId] = handlers;
31
-
32
- return handlerId;
33
- }
34
-
35
- /** 모든 등록된 라우트를 fuzionx-bridge에 등록하고 빌드 */
36
- build() {
37
- if (this._built) return;
38
-
39
- for (const route of this._routes) {
40
- this._bridge.registerRoute(route.method, route.path, route.handlerId);
41
- }
42
- this._bridge.buildRoutes();
43
- this._built = true;
44
- }
45
-
46
- /**
47
- * handlerId로 핸들러 배열 조회
48
- * @param {number} handlerId
49
- * @returns {Function[]|null}
50
- */
51
- getHandler(handlerId) {
52
- if (handlerId < 0) return null;
53
- return this._handlerMap[handlerId] || null;
54
- }
55
- }
1
+ /**
2
+ * Router — fuzionx-bridge의 registerRoute/buildRoutes를 래핑하는 라우트 매니저.
3
+ * Express 스타일 path를 Rust 라우터 형식({param})으로 변환.
4
+ */
5
+ export class Router {
6
+ constructor(bridge) {
7
+ this._bridge = bridge;
8
+ this._routes = []; // { method, path, handlers }
9
+ this._handlerMap = {}; // handlerId → handlers[]
10
+ this._nextId = 1;
11
+ this._built = false;
12
+ }
13
+
14
+ /**
15
+ * 라우트 추가
16
+ * @param {string} method - HTTP 메서드
17
+ * @param {string} routePath - Express 스타일 경로 (예: /api/users/:id)
18
+ * @param {Function[]} handlers - 핸들러 배열
19
+ */
20
+ add(method, routePath, handlers) {
21
+ if (this._built) {
22
+ throw new Error('라우트는 listen() 호출 전에 등록해야 합니다');
23
+ }
24
+
25
+ // Express :param → Rust {param} 변환
26
+ const rustPath = routePath.replace(/:([a-zA-Z_][a-zA-Z0-9_]*)/g, '{$1}');
27
+ const handlerId = this._nextId++;
28
+
29
+ this._routes.push({ method, path: rustPath, handlerId, handlers });
30
+ this._handlerMap[handlerId] = handlers;
31
+
32
+ return handlerId;
33
+ }
34
+
35
+ /** 모든 등록된 라우트를 fuzionx-bridge에 등록하고 빌드 */
36
+ build() {
37
+ if (this._built) return;
38
+
39
+ for (const route of this._routes) {
40
+ this._bridge.registerRoute(route.method, route.path, route.handlerId);
41
+ }
42
+ this._bridge.buildRoutes();
43
+ this._built = true;
44
+ }
45
+
46
+ /**
47
+ * handlerId로 핸들러 배열 조회
48
+ * @param {number} handlerId
49
+ * @returns {Function[]|null}
50
+ */
51
+ getHandler(handlerId) {
52
+ if (handlerId < 0) return null;
53
+ return this._handlerMap[handlerId] || null;
54
+ }
55
+ }
package/lib/session.js CHANGED
@@ -1,18 +1,18 @@
1
- /**
2
- * Session — fuzionx-bridge 세션 N-API를 래핑하는 헬퍼.
3
- * context.js에서 req.session으로 사용됨.
4
- */
5
-
6
- export function createSession(bridge) {
7
- return {
8
- /** 세션 데이터 조회 (전체) */
9
- get: (sessionId) => bridge.sessionGet(sessionId),
10
- /** 세션 데이터 저장 (data: HashMap, ttl: optional) */
11
- set: (sessionId, data, ttlSecs) => bridge.sessionSet(sessionId, data, ttlSecs),
12
- destroy: (sessionId) => bridge.sessionDestroy(sessionId),
13
- renew: (sessionId, ttlSecs) => bridge.sessionRenew(sessionId, ttlSecs),
14
- exists: (sessionId) => bridge.sessionExists(sessionId),
15
- load: (sessionId) => bridge.sessionLoad(sessionId),
16
- cleanup: () => bridge.sessionCleanup(),
17
- };
18
- }
1
+ /**
2
+ * Session — fuzionx-bridge 세션 N-API를 래핑하는 헬퍼.
3
+ * context.js에서 req.session으로 사용됨.
4
+ */
5
+
6
+ export function createSession(bridge) {
7
+ return {
8
+ /** 세션 데이터 조회 (전체) */
9
+ get: (sessionId) => bridge.sessionGet(sessionId),
10
+ /** 세션 데이터 저장 (data: HashMap, ttl: optional) */
11
+ set: (sessionId, data, ttlSecs) => bridge.sessionSet(sessionId, data, ttlSecs),
12
+ destroy: (sessionId) => bridge.sessionDestroy(sessionId),
13
+ renew: (sessionId, ttlSecs) => bridge.sessionRenew(sessionId, ttlSecs),
14
+ exists: (sessionId) => bridge.sessionExists(sessionId),
15
+ load: (sessionId) => bridge.sessionLoad(sessionId),
16
+ cleanup: () => bridge.sessionCleanup(),
17
+ };
18
+ }
package/lib/ws.js CHANGED
@@ -1,210 +1,210 @@
1
- /**
2
- * WebSocket — 네임스페이스 기반 WS 매니저.
3
- *
4
- * 사용법:
5
- * app.ws('/chat').on('connect', (socket) => { ... });
6
- * app.ws('/chat').on('message', (socket, data) => { ... });
7
- * app.ws('/chat').on('disconnect', (socket) => { ... });
8
- *
9
- * // 기본 네임스페이스 ("/")
10
- * app.ws.on('message', (socket, data) => { ... });
11
- */
12
-
13
- /**
14
- * 개별 WebSocket 연결을 나타내는 래퍼.
15
- */
16
- class FuzionXSocket {
17
- constructor(sessionId, bridge, namespace) {
18
- this._bridge = bridge;
19
- this._namespace = namespace || null;
20
- this.sessionId = sessionId;
21
- }
22
-
23
- /** 이 소켓에 메시지 전송 */
24
- send(data) {
25
- const msg = typeof data === 'string' ? data : JSON.stringify(data);
26
- this._bridge.wsSendTo(this.sessionId, msg, this._namespace);
27
- }
28
-
29
- /** 전체 연결에 브로드캐스트 (네임스페이스 범위) */
30
- broadcast(data) {
31
- const msg = typeof data === 'string' ? data : JSON.stringify(data);
32
- this._bridge.wsBroadcast(msg, this._namespace);
33
- }
34
-
35
- /** 자신을 제외하고 브로드캐스트 (네임스페이스 범위) */
36
- broadcastExcluding(data) {
37
- const msg = typeof data === 'string' ? data : JSON.stringify(data);
38
- this._bridge.wsBroadcastExcluding(msg, this.sessionId, this._namespace);
39
- }
40
-
41
- /** 여러 세션에 전송 (네임스페이스 범위) */
42
- sendToMany(sessionIds, data) {
43
- const msg = typeof data === 'string' ? data : JSON.stringify(data);
44
- this._bridge.wsSendToMany(sessionIds, msg, this._namespace);
45
- }
46
-
47
- /** 메타데이터 매칭 세션에 전송 (네임스페이스 범위) */
48
- sendToMatch(key, value, data) {
49
- const msg = typeof data === 'string' ? data : JSON.stringify(data);
50
- this._bridge.wsSendToMetadataMatch(key, value, msg, this._namespace);
51
- }
52
-
53
- /** 메타데이터 설정 */
54
- setMetadata(key, value) {
55
- this._bridge.wsSetMetadata(this.sessionId, key, value);
56
- }
57
-
58
- /** 메타데이터 조회 */
59
- getMetadata(key) {
60
- return this._bridge.wsGetMetadata(this.sessionId, key);
61
- }
62
-
63
- /** 임의 세션의 메타데이터 조회 (로컬 + 원격 자동 폴백) */
64
- getMetadataFor(sessionId, key) {
65
- return this._bridge.wsGetMetadata(sessionId, key) || null;
66
- }
67
-
68
- /** 네임스페이스별 접속자 수 */
69
- get onlineCount() {
70
- return this._namespace
71
- ? this._bridge.wsGetOnlineCountNs(this._namespace)
72
- : this._bridge.wsGetOnlineCount();
73
- }
74
-
75
- /** 네임스페이스별 세션 ID 목록 */
76
- get sessionIds() {
77
- return this._namespace
78
- ? this._bridge.wsGetSessionIdsNs(this._namespace)
79
- : this._bridge.wsGetSessionIds();
80
- }
81
-
82
- /** 연결 끊기 */
83
- disconnect() {
84
- this._bridge.wsDisconnect(this.sessionId);
85
- }
86
-
87
- /** JSON 직렬화 */
88
- toJSON() {
89
- return { sessionId: this.sessionId };
90
- }
91
- }
92
-
93
- /**
94
- * 네임스페이스별 핸들러 레지스트리.
95
- */
96
- class WsNamespace {
97
- constructor(path) {
98
- this.path = path;
99
- this._handlers = { connect: null, message: null, disconnect: null };
100
- }
101
-
102
- /**
103
- * 이벤트 핸들러 등록.
104
- * @param {'connect'|'message'|'disconnect'} event
105
- * @param {Function} handler
106
- * @returns {WsNamespace} 체이닝 지원
107
- */
108
- on(event, handler) {
109
- if (!['connect', 'message', 'disconnect'].includes(event)) {
110
- throw new Error(`Unknown WS event: ${event}`);
111
- }
112
- this._handlers[event] = handler;
113
- return this;
114
- }
115
- }
116
-
117
- export function createWs(bridge) {
118
- /** @type {Map<string, WsNamespace>} */
119
- const namespaces = new Map();
120
- let _initialized = false;
121
-
122
- /**
123
- * 내부: TSFN 콜백을 bridge에 한 번만 등록.
124
- * 모든 네임스페이스의 이벤트가 여기로 들어옴 → path로 dispatch.
125
- */
126
- function ensureInitialized() {
127
- if (_initialized) return;
128
- _initialized = true;
129
-
130
- // connect 이벤트 디스패쳐
131
- bridge.wsOnConnect((namespace, sessionId) => {
132
- const ns = namespaces.get(namespace);
133
- if (ns && ns._handlers.connect) {
134
- ns._handlers.connect(new FuzionXSocket(sessionId, bridge, namespace));
135
- }
136
- });
137
-
138
- // message 이벤트 디스패쳐
139
- bridge.wsOnMessage((namespace, sessionId, message) => {
140
- const ns = namespaces.get(namespace);
141
- if (ns && ns._handlers.message) {
142
- ns._handlers.message(new FuzionXSocket(sessionId, bridge, namespace), message);
143
- }
144
- });
145
-
146
- // disconnect 이벤트 디스패쳐
147
- bridge.wsOnDisconnect((namespace, sessionId) => {
148
- const ns = namespaces.get(namespace);
149
- if (ns && ns._handlers.disconnect) {
150
- ns._handlers.disconnect(new FuzionXSocket(sessionId, bridge, namespace));
151
- }
152
- });
153
- }
154
-
155
- /**
156
- * 네임스페이스를 가져오거나 생성.
157
- * @param {string} path
158
- * @returns {WsNamespace}
159
- */
160
- function getOrCreateNs(path) {
161
- ensureInitialized();
162
- if (!namespaces.has(path)) {
163
- namespaces.set(path, new WsNamespace(path));
164
- }
165
- return namespaces.get(path);
166
- }
167
-
168
- // Proxy: ws('/chat') → 네임스페이스, ws.on() → 기본 "/" 네임스페이스
169
- const wsProxy = new Proxy(function wsFunc(path) {
170
- return getOrCreateNs(path);
171
- }, {
172
- get(target, prop) {
173
- // ws.on('event', handler) → 기본 "/" 네임스페이스
174
- if (prop === 'on') {
175
- const defaultNs = getOrCreateNs('/');
176
- return defaultNs.on.bind(defaultNs);
177
- }
178
-
179
- // ws.broadcast, ws.sendTo 등 글로벌 유틸
180
- switch (prop) {
181
- case 'broadcast':
182
- return (data) => bridge.wsBroadcast(typeof data === 'string' ? data : JSON.stringify(data));
183
- case 'broadcastExcluding':
184
- return (data, excludeSessionId) => bridge.wsBroadcastExcluding(typeof data === 'string' ? data : JSON.stringify(data), excludeSessionId);
185
- case 'broadcastLocal':
186
- return (data) => bridge.wsBroadcastLocal(typeof data === 'string' ? data : JSON.stringify(data));
187
- case 'broadcastExcludingLocal':
188
- return (data, excludeSessionId) => bridge.wsBroadcastExcludingLocal(typeof data === 'string' ? data : JSON.stringify(data), excludeSessionId);
189
- case 'sendTo':
190
- return (sessionId, data) => bridge.wsSendTo(sessionId, typeof data === 'string' ? data : JSON.stringify(data));
191
- case 'sendToMany':
192
- return (sessionIds, data) => bridge.wsSendToMany(sessionIds, typeof data === 'string' ? data : JSON.stringify(data));
193
- case 'onlineCount':
194
- return bridge.wsGetOnlineCount();
195
- case 'sessionIds':
196
- return bridge.wsGetSessionIds();
197
- case 'removeInactive':
198
- return (seconds) => bridge.wsRemoveInactive(seconds);
199
- case 'disconnect':
200
- return (sessionId) => bridge.wsDisconnect(sessionId);
201
- case 'namespaces':
202
- return namespaces;
203
- default:
204
- return Reflect.get(target, prop);
205
- }
206
- },
207
- });
208
-
209
- return wsProxy;
210
- }
1
+ /**
2
+ * WebSocket — 네임스페이스 기반 WS 매니저.
3
+ *
4
+ * 사용법:
5
+ * app.ws('/chat').on('connect', (socket) => { ... });
6
+ * app.ws('/chat').on('message', (socket, data) => { ... });
7
+ * app.ws('/chat').on('disconnect', (socket) => { ... });
8
+ *
9
+ * // 기본 네임스페이스 ("/")
10
+ * app.ws.on('message', (socket, data) => { ... });
11
+ */
12
+
13
+ /**
14
+ * 개별 WebSocket 연결을 나타내는 래퍼.
15
+ */
16
+ class FuzionXSocket {
17
+ constructor(sessionId, bridge, namespace) {
18
+ this._bridge = bridge;
19
+ this._namespace = namespace || null;
20
+ this.sessionId = sessionId;
21
+ }
22
+
23
+ /** 이 소켓에 메시지 전송 */
24
+ send(data) {
25
+ const msg = typeof data === 'string' ? data : JSON.stringify(data);
26
+ this._bridge.wsSendTo(this.sessionId, msg, this._namespace);
27
+ }
28
+
29
+ /** 전체 연결에 브로드캐스트 (네임스페이스 범위) */
30
+ broadcast(data) {
31
+ const msg = typeof data === 'string' ? data : JSON.stringify(data);
32
+ this._bridge.wsBroadcast(msg, this._namespace);
33
+ }
34
+
35
+ /** 자신을 제외하고 브로드캐스트 (네임스페이스 범위) */
36
+ broadcastExcluding(data) {
37
+ const msg = typeof data === 'string' ? data : JSON.stringify(data);
38
+ this._bridge.wsBroadcastExcluding(msg, this.sessionId, this._namespace);
39
+ }
40
+
41
+ /** 여러 세션에 전송 (네임스페이스 범위) */
42
+ sendToMany(sessionIds, data) {
43
+ const msg = typeof data === 'string' ? data : JSON.stringify(data);
44
+ this._bridge.wsSendToMany(sessionIds, msg, this._namespace);
45
+ }
46
+
47
+ /** 메타데이터 매칭 세션에 전송 (네임스페이스 범위) */
48
+ sendToMatch(key, value, data) {
49
+ const msg = typeof data === 'string' ? data : JSON.stringify(data);
50
+ this._bridge.wsSendToMetadataMatch(key, value, msg, this._namespace);
51
+ }
52
+
53
+ /** 메타데이터 설정 */
54
+ setMetadata(key, value) {
55
+ this._bridge.wsSetMetadata(this.sessionId, key, value);
56
+ }
57
+
58
+ /** 메타데이터 조회 */
59
+ getMetadata(key) {
60
+ return this._bridge.wsGetMetadata(this.sessionId, key);
61
+ }
62
+
63
+ /** 임의 세션의 메타데이터 조회 (로컬 + 원격 자동 폴백) */
64
+ getMetadataFor(sessionId, key) {
65
+ return this._bridge.wsGetMetadata(sessionId, key) || null;
66
+ }
67
+
68
+ /** 네임스페이스별 접속자 수 */
69
+ get onlineCount() {
70
+ return this._namespace
71
+ ? this._bridge.wsGetOnlineCountNs(this._namespace)
72
+ : this._bridge.wsGetOnlineCount();
73
+ }
74
+
75
+ /** 네임스페이스별 세션 ID 목록 */
76
+ get sessionIds() {
77
+ return this._namespace
78
+ ? this._bridge.wsGetSessionIdsNs(this._namespace)
79
+ : this._bridge.wsGetSessionIds();
80
+ }
81
+
82
+ /** 연결 끊기 */
83
+ disconnect() {
84
+ this._bridge.wsDisconnect(this.sessionId);
85
+ }
86
+
87
+ /** JSON 직렬화 */
88
+ toJSON() {
89
+ return { sessionId: this.sessionId };
90
+ }
91
+ }
92
+
93
+ /**
94
+ * 네임스페이스별 핸들러 레지스트리.
95
+ */
96
+ class WsNamespace {
97
+ constructor(path) {
98
+ this.path = path;
99
+ this._handlers = { connect: null, message: null, disconnect: null };
100
+ }
101
+
102
+ /**
103
+ * 이벤트 핸들러 등록.
104
+ * @param {'connect'|'message'|'disconnect'} event
105
+ * @param {Function} handler
106
+ * @returns {WsNamespace} 체이닝 지원
107
+ */
108
+ on(event, handler) {
109
+ if (!['connect', 'message', 'disconnect'].includes(event)) {
110
+ throw new Error(`Unknown WS event: ${event}`);
111
+ }
112
+ this._handlers[event] = handler;
113
+ return this;
114
+ }
115
+ }
116
+
117
+ export function createWs(bridge) {
118
+ /** @type {Map<string, WsNamespace>} */
119
+ const namespaces = new Map();
120
+ let _initialized = false;
121
+
122
+ /**
123
+ * 내부: TSFN 콜백을 bridge에 한 번만 등록.
124
+ * 모든 네임스페이스의 이벤트가 여기로 들어옴 → path로 dispatch.
125
+ */
126
+ function ensureInitialized() {
127
+ if (_initialized) return;
128
+ _initialized = true;
129
+
130
+ // connect 이벤트 디스패쳐
131
+ bridge.wsOnConnect((namespace, sessionId) => {
132
+ const ns = namespaces.get(namespace);
133
+ if (ns && ns._handlers.connect) {
134
+ ns._handlers.connect(new FuzionXSocket(sessionId, bridge, namespace));
135
+ }
136
+ });
137
+
138
+ // message 이벤트 디스패쳐
139
+ bridge.wsOnMessage((namespace, sessionId, message) => {
140
+ const ns = namespaces.get(namespace);
141
+ if (ns && ns._handlers.message) {
142
+ ns._handlers.message(new FuzionXSocket(sessionId, bridge, namespace), message);
143
+ }
144
+ });
145
+
146
+ // disconnect 이벤트 디스패쳐
147
+ bridge.wsOnDisconnect((namespace, sessionId) => {
148
+ const ns = namespaces.get(namespace);
149
+ if (ns && ns._handlers.disconnect) {
150
+ ns._handlers.disconnect(new FuzionXSocket(sessionId, bridge, namespace));
151
+ }
152
+ });
153
+ }
154
+
155
+ /**
156
+ * 네임스페이스를 가져오거나 생성.
157
+ * @param {string} path
158
+ * @returns {WsNamespace}
159
+ */
160
+ function getOrCreateNs(path) {
161
+ ensureInitialized();
162
+ if (!namespaces.has(path)) {
163
+ namespaces.set(path, new WsNamespace(path));
164
+ }
165
+ return namespaces.get(path);
166
+ }
167
+
168
+ // Proxy: ws('/chat') → 네임스페이스, ws.on() → 기본 "/" 네임스페이스
169
+ const wsProxy = new Proxy(function wsFunc(path) {
170
+ return getOrCreateNs(path);
171
+ }, {
172
+ get(target, prop) {
173
+ // ws.on('event', handler) → 기본 "/" 네임스페이스
174
+ if (prop === 'on') {
175
+ const defaultNs = getOrCreateNs('/');
176
+ return defaultNs.on.bind(defaultNs);
177
+ }
178
+
179
+ // ws.broadcast, ws.sendTo 등 글로벌 유틸
180
+ switch (prop) {
181
+ case 'broadcast':
182
+ return (data) => bridge.wsBroadcast(typeof data === 'string' ? data : JSON.stringify(data));
183
+ case 'broadcastExcluding':
184
+ return (data, excludeSessionId) => bridge.wsBroadcastExcluding(typeof data === 'string' ? data : JSON.stringify(data), excludeSessionId);
185
+ case 'broadcastLocal':
186
+ return (data) => bridge.wsBroadcastLocal(typeof data === 'string' ? data : JSON.stringify(data));
187
+ case 'broadcastExcludingLocal':
188
+ return (data, excludeSessionId) => bridge.wsBroadcastExcludingLocal(typeof data === 'string' ? data : JSON.stringify(data), excludeSessionId);
189
+ case 'sendTo':
190
+ return (sessionId, data) => bridge.wsSendTo(sessionId, typeof data === 'string' ? data : JSON.stringify(data));
191
+ case 'sendToMany':
192
+ return (sessionIds, data) => bridge.wsSendToMany(sessionIds, typeof data === 'string' ? data : JSON.stringify(data));
193
+ case 'onlineCount':
194
+ return bridge.wsGetOnlineCount();
195
+ case 'sessionIds':
196
+ return bridge.wsGetSessionIds();
197
+ case 'removeInactive':
198
+ return (seconds) => bridge.wsRemoveInactive(seconds);
199
+ case 'disconnect':
200
+ return (sessionId) => bridge.wsDisconnect(sessionId);
201
+ case 'namespaces':
202
+ return namespaces;
203
+ default:
204
+ return Reflect.get(target, prop);
205
+ }
206
+ },
207
+ });
208
+
209
+ return wsProxy;
210
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fuzionx/core",
3
- "version": "0.1.39",
3
+ "version": "0.1.41",
4
4
  "type": "module",
5
5
  "description": "Express-style Node.js framework powered by FuzionX native bridge — 167K RPS single process",
6
6
  "main": "index.js",
@@ -8,7 +8,16 @@
8
8
  "exports": {
9
9
  ".": "./index.js"
10
10
  },
11
- "keywords": ["framework", "http", "server", "rust", "native", "high-performance", "fuzionx", "napi"],
11
+ "keywords": [
12
+ "framework",
13
+ "http",
14
+ "server",
15
+ "rust",
16
+ "native",
17
+ "high-performance",
18
+ "fuzionx",
19
+ "napi"
20
+ ],
12
21
  "license": "MIT",
13
22
  "engines": {
14
23
  "node": ">=18.0.0"
@@ -18,7 +27,7 @@
18
27
  "url": "https://github.com/saytohenry/fuzionx"
19
28
  },
20
29
  "dependencies": {
21
- "@fuzionx/bridge": "^0.1.39"
30
+ "@fuzionx/bridge": "^0.1.41"
22
31
  },
23
32
  "files": [
24
33
  "index.js",