request-iframe 0.0.2 → 0.0.4
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/QUICKSTART.CN.md +35 -8
- package/QUICKSTART.md +35 -8
- package/README.CN.md +439 -36
- package/README.md +496 -30
- package/library/__tests__/channel.test.ts +420 -0
- package/library/__tests__/coverage-branches.test.ts +356 -0
- package/library/__tests__/debug.test.ts +588 -0
- package/library/__tests__/dispatcher.test.ts +481 -0
- package/library/__tests__/requestIframe.test.ts +3163 -185
- package/library/__tests__/server.test.ts +738 -0
- package/library/__tests__/stream.test.ts +46 -15
- package/library/api/client.d.ts.map +1 -1
- package/library/api/client.js +12 -6
- package/library/api/server.d.ts +4 -3
- package/library/api/server.d.ts.map +1 -1
- package/library/api/server.js +25 -7
- package/library/constants/index.d.ts +14 -4
- package/library/constants/index.d.ts.map +1 -1
- package/library/constants/index.js +15 -7
- package/library/constants/messages.d.ts +37 -0
- package/library/constants/messages.d.ts.map +1 -1
- package/library/constants/messages.js +38 -1
- package/library/core/client-server.d.ts +105 -0
- package/library/core/client-server.d.ts.map +1 -0
- package/library/core/client-server.js +289 -0
- package/library/core/client.d.ts +53 -10
- package/library/core/client.d.ts.map +1 -1
- package/library/core/client.js +529 -207
- package/library/core/request.d.ts +3 -1
- package/library/core/request.d.ts.map +1 -1
- package/library/core/request.js +2 -1
- package/library/core/response.d.ts +30 -4
- package/library/core/response.d.ts.map +1 -1
- package/library/core/response.js +176 -100
- package/library/core/server-client.d.ts +3 -1
- package/library/core/server-client.d.ts.map +1 -1
- package/library/core/server-client.js +19 -9
- package/library/core/server.d.ts +22 -1
- package/library/core/server.d.ts.map +1 -1
- package/library/core/server.js +304 -55
- package/library/index.d.ts +3 -2
- package/library/index.d.ts.map +1 -1
- package/library/index.js +34 -5
- package/library/interceptors/index.d.ts.map +1 -1
- package/library/message/channel.d.ts +3 -1
- package/library/message/channel.d.ts.map +1 -1
- package/library/message/dispatcher.d.ts +7 -2
- package/library/message/dispatcher.d.ts.map +1 -1
- package/library/message/dispatcher.js +48 -2
- package/library/message/index.d.ts.map +1 -1
- package/library/stream/file-stream.d.ts +5 -0
- package/library/stream/file-stream.d.ts.map +1 -1
- package/library/stream/file-stream.js +41 -12
- package/library/stream/index.d.ts +11 -1
- package/library/stream/index.d.ts.map +1 -1
- package/library/stream/index.js +21 -3
- package/library/stream/readable-stream.d.ts.map +1 -1
- package/library/stream/readable-stream.js +32 -30
- package/library/stream/types.d.ts +20 -2
- package/library/stream/types.d.ts.map +1 -1
- package/library/stream/writable-stream.d.ts +2 -1
- package/library/stream/writable-stream.d.ts.map +1 -1
- package/library/stream/writable-stream.js +13 -10
- package/library/types/index.d.ts +106 -32
- package/library/types/index.d.ts.map +1 -1
- package/library/utils/cache.d.ts +24 -0
- package/library/utils/cache.d.ts.map +1 -1
- package/library/utils/cache.js +76 -0
- package/library/utils/cookie.d.ts.map +1 -1
- package/library/utils/debug.d.ts.map +1 -1
- package/library/utils/debug.js +382 -20
- package/library/utils/index.d.ts +19 -0
- package/library/utils/index.d.ts.map +1 -1
- package/library/utils/index.js +113 -2
- package/library/utils/path-match.d.ts +16 -0
- package/library/utils/path-match.d.ts.map +1 -1
- package/library/utils/path-match.js +65 -0
- package/library/utils/protocol.d.ts.map +1 -1
- package/package.json +4 -1
- package/react/library/__tests__/index.test.tsx +274 -281
- package/react/library/index.d.ts +4 -3
- package/react/library/index.d.ts.map +1 -1
- package/react/library/index.js +225 -158
- package/react/package.json +7 -0
package/react/library/index.d.ts
CHANGED
|
@@ -52,9 +52,10 @@ export declare function useClient(targetFnOrRef: (() => HTMLIFrameElement | Wind
|
|
|
52
52
|
* const server = useServer({ secretKey: 'my-app' });
|
|
53
53
|
*
|
|
54
54
|
* useEffect(() => {
|
|
55
|
-
* server.on('/api/data', (req, res) => {
|
|
55
|
+
* const off = server.on('/api/data', (req, res) => {
|
|
56
56
|
* res.send({ data: 'Hello' });
|
|
57
57
|
* });
|
|
58
|
+
* return off;
|
|
58
59
|
* }, [server]);
|
|
59
60
|
*
|
|
60
61
|
* return <div>Server Component</div>;
|
|
@@ -85,7 +86,7 @@ export declare function useServer(options?: RequestIframeServerOptions, deps?: r
|
|
|
85
86
|
* };
|
|
86
87
|
* ```
|
|
87
88
|
*/
|
|
88
|
-
export declare function useServerHandler(server: RequestIframeServer | null, path: string, handler: ServerHandler, deps
|
|
89
|
+
export declare function useServerHandler(server: RequestIframeServer | null, path: string, handler: ServerHandler, deps: readonly unknown[]): void;
|
|
89
90
|
/**
|
|
90
91
|
* React hook for registering server handlers map
|
|
91
92
|
*
|
|
@@ -113,5 +114,5 @@ export declare function useServerHandler(server: RequestIframeServer | null, pat
|
|
|
113
114
|
* };
|
|
114
115
|
* ```
|
|
115
116
|
*/
|
|
116
|
-
export declare function useServerHandlerMap(server: RequestIframeServer | null, map: Record<string, ServerHandler>, deps
|
|
117
|
+
export declare function useServerHandlerMap(server: RequestIframeServer | null, map: Record<string, ServerHandler>, deps: readonly unknown[]): void;
|
|
117
118
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAC1F,OAAO,EAGL,KAAK,mBAAmB,EACxB,KAAK,0BAA0B,EAC/B,KAAK,mBAAmB,EACxB,KAAK,0BAA0B,EAC/B,KAAK,aAAa,EACnB,MAAM,OAAO,CAAC;AAEf;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAgB,SAAS,CACvB,aAAa,EAAE,CAAC,MAAM,iBAAiB,GAAG,MAAM,GAAG,IAAI,CAAC,GAAG,SAAS,CAAC,iBAAiB,GAAG,MAAM,GAAG,IAAI,CAAC,EACvG,OAAO,CAAC,EAAE,0BAA0B,EACpC,IAAI,CAAC,EAAE,SAAS,OAAO,EAAE,GACxB,mBAAmB,GAAG,IAAI,CA2E5B;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,SAAS,CACvB,OAAO,CAAC,EAAE,0BAA0B,EACpC,IAAI,CAAC,EAAE,SAAS,OAAO,EAAE,GACxB,mBAAmB,GAAG,IAAI,CA2C5B;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,mBAAmB,GAAG,IAAI,EAClC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,aAAa,EACtB,IAAI,EAAE,SAAS,OAAO,EAAE,GACvB,IAAI,CAmBN;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,mBAAmB,GAAG,IAAI,EAClC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,EAClC,IAAI,EAAE,SAAS,OAAO,EAAE,GACvB,IAAI,CA2BN"}
|
package/react/library/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
3
4
|
Object.defineProperty(exports, "__esModule", {
|
|
4
5
|
value: true
|
|
5
6
|
});
|
|
@@ -9,215 +10,281 @@ exports.useServerHandler = useServerHandler;
|
|
|
9
10
|
exports.useServerHandlerMap = useServerHandlerMap;
|
|
10
11
|
require("core-js/modules/es.array.iterator.js");
|
|
11
12
|
require("core-js/modules/es.array.map.js");
|
|
13
|
+
require("core-js/modules/es.array.reduce.js");
|
|
14
|
+
require("core-js/modules/es.array.sort.js");
|
|
12
15
|
require("core-js/modules/web.dom-collections.iterator.js");
|
|
16
|
+
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
13
17
|
var _react = require("react");
|
|
14
18
|
var _ = require("../..");
|
|
15
|
-
/**
|
|
16
|
-
* React hook for using request-iframe client
|
|
17
|
-
*
|
|
18
|
-
* @param targetFnOrRef - function that returns iframe element or Window object, or a React ref object
|
|
19
|
-
* @param options - client options
|
|
20
|
-
* @param deps - dependency array (optional, for re-creating client when dependencies change)
|
|
21
|
-
* @returns client instance
|
|
22
|
-
*
|
|
23
|
-
* @example
|
|
24
|
-
* ```tsx
|
|
25
|
-
* // Using function
|
|
26
|
-
* const MyComponent = () => {
|
|
27
|
-
* const iframeRef = useRef<HTMLIFrameElement>(null);
|
|
28
|
-
* const client = useClient(() => iframeRef.current, { secretKey: 'my-app' });
|
|
29
|
-
*
|
|
30
|
-
* const handleClick = async () => {
|
|
31
|
-
* if (client) {
|
|
32
|
-
* const response = await client.send('/api/data', { id: 1 });
|
|
33
|
-
* console.log(response.data);
|
|
34
|
-
* }
|
|
35
|
-
* };
|
|
36
|
-
*
|
|
37
|
-
* return (
|
|
38
|
-
* <div>
|
|
39
|
-
* <iframe ref={iframeRef} src="/iframe.html" />
|
|
40
|
-
* <button onClick={handleClick}>Send Request</button>
|
|
41
|
-
* </div>
|
|
42
|
-
* );
|
|
43
|
-
* };
|
|
44
|
-
*
|
|
45
|
-
* // Using ref directly
|
|
46
|
-
* const MyComponent2 = () => {
|
|
47
|
-
* const iframeRef = useRef<HTMLIFrameElement>(null);
|
|
48
|
-
* const client = useClient(iframeRef, { secretKey: 'my-app' });
|
|
49
|
-
* // ...
|
|
50
|
-
* };
|
|
51
|
-
* ```
|
|
19
|
+
/**
|
|
20
|
+
* React hook for using request-iframe client
|
|
21
|
+
*
|
|
22
|
+
* @param targetFnOrRef - function that returns iframe element or Window object, or a React ref object
|
|
23
|
+
* @param options - client options
|
|
24
|
+
* @param deps - dependency array (optional, for re-creating client when dependencies change)
|
|
25
|
+
* @returns client instance
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```tsx
|
|
29
|
+
* // Using function
|
|
30
|
+
* const MyComponent = () => {
|
|
31
|
+
* const iframeRef = useRef<HTMLIFrameElement>(null);
|
|
32
|
+
* const client = useClient(() => iframeRef.current, { secretKey: 'my-app' });
|
|
33
|
+
*
|
|
34
|
+
* const handleClick = async () => {
|
|
35
|
+
* if (client) {
|
|
36
|
+
* const response = await client.send('/api/data', { id: 1 });
|
|
37
|
+
* console.log(response.data);
|
|
38
|
+
* }
|
|
39
|
+
* };
|
|
40
|
+
*
|
|
41
|
+
* return (
|
|
42
|
+
* <div>
|
|
43
|
+
* <iframe ref={iframeRef} src="/iframe.html" />
|
|
44
|
+
* <button onClick={handleClick}>Send Request</button>
|
|
45
|
+
* </div>
|
|
46
|
+
* );
|
|
47
|
+
* };
|
|
48
|
+
*
|
|
49
|
+
* // Using ref directly
|
|
50
|
+
* const MyComponent2 = () => {
|
|
51
|
+
* const iframeRef = useRef<HTMLIFrameElement>(null);
|
|
52
|
+
* const client = useClient(iframeRef, { secretKey: 'my-app' });
|
|
53
|
+
* // ...
|
|
54
|
+
* };
|
|
55
|
+
* ```
|
|
52
56
|
*/
|
|
53
57
|
function useClient(targetFnOrRef, options, deps) {
|
|
54
58
|
var clientRef = (0, _react.useRef)(null);
|
|
55
|
-
var
|
|
59
|
+
var _useState = (0, _react.useState)(null),
|
|
60
|
+
_useState2 = (0, _slicedToArray2.default)(_useState, 2),
|
|
61
|
+
client = _useState2[0],
|
|
62
|
+
setClient = _useState2[1];
|
|
63
|
+
var lastTargetRef = (0, _react.useRef)(null);
|
|
56
64
|
var targetFnOrRefRef = (0, _react.useRef)(targetFnOrRef);
|
|
65
|
+
var optionsRef = (0, _react.useRef)(options);
|
|
57
66
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
// Get current target
|
|
65
|
-
var target = typeof targetFnOrRefRef.current === 'function' ? targetFnOrRefRef.current() : targetFnOrRefRef.current.current;
|
|
67
|
+
/** Keep latest inputs without re-creating effect deps */
|
|
68
|
+
targetFnOrRefRef.current = targetFnOrRef;
|
|
69
|
+
optionsRef.current = options;
|
|
70
|
+
var getTarget = (0, _react.useCallback)(() => {
|
|
71
|
+
return typeof targetFnOrRefRef.current === 'function' ? targetFnOrRefRef.current() : targetFnOrRefRef.current.current;
|
|
72
|
+
}, []);
|
|
66
73
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// Destroy previous client if exists
|
|
74
|
+
/**
|
|
75
|
+
* Snapshot the current target during render (pure read).
|
|
76
|
+
* We use this value as an effect dependency so the effect only runs when
|
|
77
|
+
* the target actually changes (avoids StrictMode update-depth loops).
|
|
78
|
+
*/
|
|
79
|
+
var target = getTarget();
|
|
80
|
+
var destroy = (0, _react.useCallback)(() => {
|
|
77
81
|
if (clientRef.current) {
|
|
78
82
|
clientRef.current.destroy();
|
|
79
83
|
clientRef.current = null;
|
|
80
84
|
}
|
|
85
|
+
lastTargetRef.current = null;
|
|
86
|
+
}, []);
|
|
81
87
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
88
|
+
/**
|
|
89
|
+
* Create/destroy client in effect to be compatible with React 18 StrictMode
|
|
90
|
+
* and concurrent rendering (avoid render-phase side effects).
|
|
91
|
+
*/
|
|
92
|
+
(0, _react.useEffect)(() => {
|
|
93
|
+
/** If target unchanged, keep current client */
|
|
94
|
+
if (target === lastTargetRef.current) return;
|
|
85
95
|
|
|
86
|
-
|
|
96
|
+
/** Target changed: destroy old client and maybe create a new one */
|
|
97
|
+
if (clientRef.current) {
|
|
98
|
+
clientRef.current.destroy();
|
|
99
|
+
clientRef.current = null;
|
|
100
|
+
}
|
|
101
|
+
lastTargetRef.current = target;
|
|
102
|
+
if (!target) {
|
|
103
|
+
setClient(null);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
var newClient = (0, _.requestIframeClient)(target, optionsRef.current);
|
|
107
|
+
clientRef.current = newClient;
|
|
108
|
+
setClient(newClient);
|
|
87
109
|
return () => {
|
|
88
|
-
if
|
|
89
|
-
|
|
110
|
+
/** Cleanup only if it's still the current client */
|
|
111
|
+
if (clientRef.current === newClient) {
|
|
112
|
+
newClient.destroy();
|
|
90
113
|
clientRef.current = null;
|
|
114
|
+
lastTargetRef.current = null;
|
|
91
115
|
}
|
|
92
116
|
};
|
|
93
|
-
}, deps
|
|
94
|
-
|
|
117
|
+
}, deps ? [...deps, target] : [target]);
|
|
118
|
+
|
|
119
|
+
// Cleanup on unmount
|
|
120
|
+
(0, _react.useEffect)(() => {
|
|
121
|
+
return () => {
|
|
122
|
+
destroy();
|
|
123
|
+
};
|
|
124
|
+
}, []);
|
|
125
|
+
return client;
|
|
95
126
|
}
|
|
96
127
|
|
|
97
|
-
/**
|
|
98
|
-
* React hook for using request-iframe server
|
|
99
|
-
*
|
|
100
|
-
* @param options - server options
|
|
101
|
-
* @param deps - dependency array (optional, for re-creating server when dependencies change)
|
|
102
|
-
* @returns server instance
|
|
103
|
-
*
|
|
104
|
-
* @example
|
|
105
|
-
* ```tsx
|
|
106
|
-
* const MyComponent = () => {
|
|
107
|
-
* const server = useServer({ secretKey: 'my-app' });
|
|
108
|
-
*
|
|
109
|
-
* useEffect(() => {
|
|
110
|
-
* server.on('/api/data', (req, res) => {
|
|
111
|
-
* res.send({ data: 'Hello' });
|
|
112
|
-
* });
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
*
|
|
128
|
+
/**
|
|
129
|
+
* React hook for using request-iframe server
|
|
130
|
+
*
|
|
131
|
+
* @param options - server options
|
|
132
|
+
* @param deps - dependency array (optional, for re-creating server when dependencies change)
|
|
133
|
+
* @returns server instance
|
|
134
|
+
*
|
|
135
|
+
* @example
|
|
136
|
+
* ```tsx
|
|
137
|
+
* const MyComponent = () => {
|
|
138
|
+
* const server = useServer({ secretKey: 'my-app' });
|
|
139
|
+
*
|
|
140
|
+
* useEffect(() => {
|
|
141
|
+
* const off = server.on('/api/data', (req, res) => {
|
|
142
|
+
* res.send({ data: 'Hello' });
|
|
143
|
+
* });
|
|
144
|
+
* return off;
|
|
145
|
+
* }, [server]);
|
|
146
|
+
*
|
|
147
|
+
* return <div>Server Component</div>;
|
|
148
|
+
* };
|
|
149
|
+
* ```
|
|
118
150
|
*/
|
|
119
151
|
function useServer(options, deps) {
|
|
120
152
|
var serverRef = (0, _react.useRef)(null);
|
|
153
|
+
var _useState3 = (0, _react.useState)(null),
|
|
154
|
+
_useState4 = (0, _slicedToArray2.default)(_useState3, 2),
|
|
155
|
+
server = _useState4[0],
|
|
156
|
+
setServer = _useState4[1];
|
|
121
157
|
var optionsRef = (0, _react.useRef)(options);
|
|
158
|
+
optionsRef.current = options;
|
|
159
|
+
var destroy = (0, _react.useCallback)(() => {
|
|
160
|
+
if (serverRef.current) {
|
|
161
|
+
serverRef.current.destroy();
|
|
162
|
+
serverRef.current = null;
|
|
163
|
+
}
|
|
164
|
+
}, []);
|
|
122
165
|
|
|
123
|
-
|
|
166
|
+
/**
|
|
167
|
+
* Create/destroy server in effect to be compatible with React 18 StrictMode
|
|
168
|
+
* and concurrent rendering (avoid render-phase side effects).
|
|
169
|
+
*/
|
|
124
170
|
(0, _react.useEffect)(() => {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
var
|
|
130
|
-
serverRef.current =
|
|
131
|
-
|
|
132
|
-
// Cleanup: destroy server on unmount
|
|
171
|
+
if (serverRef.current) {
|
|
172
|
+
serverRef.current.destroy();
|
|
173
|
+
serverRef.current = null;
|
|
174
|
+
}
|
|
175
|
+
var newServer = (0, _.requestIframeServer)(optionsRef.current);
|
|
176
|
+
serverRef.current = newServer;
|
|
177
|
+
setServer(newServer);
|
|
133
178
|
return () => {
|
|
134
|
-
if (serverRef.current) {
|
|
135
|
-
|
|
179
|
+
if (serverRef.current === newServer) {
|
|
180
|
+
newServer.destroy();
|
|
136
181
|
serverRef.current = null;
|
|
137
182
|
}
|
|
138
183
|
};
|
|
139
|
-
}, deps !==
|
|
184
|
+
}, deps !== null && deps !== void 0 ? deps : []);
|
|
140
185
|
|
|
141
|
-
|
|
186
|
+
// Cleanup on unmount
|
|
187
|
+
(0, _react.useEffect)(() => {
|
|
188
|
+
return () => {
|
|
189
|
+
destroy();
|
|
190
|
+
};
|
|
191
|
+
}, []);
|
|
192
|
+
return server;
|
|
142
193
|
}
|
|
143
194
|
|
|
144
|
-
/**
|
|
145
|
-
* React hook for registering server handlers
|
|
146
|
-
*
|
|
147
|
-
* @param server - server instance (from useServer)
|
|
148
|
-
* @param path - route path
|
|
149
|
-
* @param handler - handler function
|
|
150
|
-
* @param deps - dependency array (optional, for re-registering when dependencies change)
|
|
151
|
-
*
|
|
152
|
-
* @example
|
|
153
|
-
* ```tsx
|
|
154
|
-
* const MyComponent = () => {
|
|
155
|
-
* const server = useServer();
|
|
156
|
-
* const [userId, setUserId] = useState(1);
|
|
157
|
-
*
|
|
158
|
-
* // Register handler that depends on userId
|
|
159
|
-
* useServerHandler(server, '/api/user', (req, res) => {
|
|
160
|
-
* res.send({ userId, data: 'Hello' });
|
|
161
|
-
* }, [userId]);
|
|
162
|
-
*
|
|
163
|
-
* return <div>Server Component</div>;
|
|
164
|
-
* };
|
|
165
|
-
* ```
|
|
195
|
+
/**
|
|
196
|
+
* React hook for registering server handlers
|
|
197
|
+
*
|
|
198
|
+
* @param server - server instance (from useServer)
|
|
199
|
+
* @param path - route path
|
|
200
|
+
* @param handler - handler function
|
|
201
|
+
* @param deps - dependency array (optional, for re-registering when dependencies change)
|
|
202
|
+
*
|
|
203
|
+
* @example
|
|
204
|
+
* ```tsx
|
|
205
|
+
* const MyComponent = () => {
|
|
206
|
+
* const server = useServer();
|
|
207
|
+
* const [userId, setUserId] = useState(1);
|
|
208
|
+
*
|
|
209
|
+
* // Register handler that depends on userId
|
|
210
|
+
* useServerHandler(server, '/api/user', (req, res) => {
|
|
211
|
+
* res.send({ userId, data: 'Hello' });
|
|
212
|
+
* }, [userId]);
|
|
213
|
+
*
|
|
214
|
+
* return <div>Server Component</div>;
|
|
215
|
+
* };
|
|
216
|
+
* ```
|
|
166
217
|
*/
|
|
167
218
|
function useServerHandler(server, path, handler, deps) {
|
|
219
|
+
var handlerRef = (0, _react.useRef)(handler);
|
|
220
|
+
handlerRef.current = handler;
|
|
221
|
+
var handlerWrapper = (0, _react.useCallback)((req, res) => {
|
|
222
|
+
var _handlerRef$current;
|
|
223
|
+
return (_handlerRef$current = handlerRef.current) === null || _handlerRef$current === void 0 ? void 0 : _handlerRef$current.call(handlerRef, req, res);
|
|
224
|
+
}, []);
|
|
168
225
|
(0, _react.useEffect)(() => {
|
|
169
226
|
if (!server) {
|
|
170
227
|
return;
|
|
171
228
|
}
|
|
172
229
|
|
|
173
|
-
// Register handler
|
|
174
|
-
var
|
|
230
|
+
// Register handler with stable wrapper
|
|
231
|
+
var off = server.on(path, handlerWrapper);
|
|
175
232
|
|
|
176
233
|
// Cleanup: unregister handler on unmount or when deps change
|
|
177
|
-
return
|
|
178
|
-
|
|
179
|
-
};
|
|
180
|
-
}, [server, path, handler, ...(deps || [])]);
|
|
234
|
+
return off;
|
|
235
|
+
}, [server, path, handlerWrapper, ...(deps || [])]);
|
|
181
236
|
}
|
|
182
237
|
|
|
183
|
-
/**
|
|
184
|
-
* React hook for registering server handlers map
|
|
185
|
-
*
|
|
186
|
-
* @param server - server instance (from useServer)
|
|
187
|
-
* @param map - map of route paths and handler functions
|
|
188
|
-
* @param deps - dependency array (optional, for re-registering when dependencies change)
|
|
189
|
-
*
|
|
190
|
-
* @example
|
|
191
|
-
* ```tsx
|
|
192
|
-
* const MyComponent = () => {
|
|
193
|
-
* const server = useServer();
|
|
194
|
-
* const [userId, setUserId] = useState(1);
|
|
195
|
-
*
|
|
196
|
-
* // Register handlers using map
|
|
197
|
-
* useServerHandlerMap(server, {
|
|
198
|
-
* '/api/user': (req, res) => {
|
|
199
|
-
* res.send({ userId, data: 'Hello' });
|
|
200
|
-
* },
|
|
201
|
-
* '/api/user2': (req, res) => {
|
|
202
|
-
* res.send({ userId, data: 'Hello' });
|
|
203
|
-
* }
|
|
204
|
-
* }, [userId]);
|
|
205
|
-
*
|
|
206
|
-
* return <div>Server Component</div>;
|
|
207
|
-
* };
|
|
208
|
-
* ```
|
|
238
|
+
/**
|
|
239
|
+
* React hook for registering server handlers map
|
|
240
|
+
*
|
|
241
|
+
* @param server - server instance (from useServer)
|
|
242
|
+
* @param map - map of route paths and handler functions
|
|
243
|
+
* @param deps - dependency array (optional, for re-registering when dependencies change)
|
|
244
|
+
*
|
|
245
|
+
* @example
|
|
246
|
+
* ```tsx
|
|
247
|
+
* const MyComponent = () => {
|
|
248
|
+
* const server = useServer();
|
|
249
|
+
* const [userId, setUserId] = useState(1);
|
|
250
|
+
*
|
|
251
|
+
* // Register handlers using map
|
|
252
|
+
* useServerHandlerMap(server, {
|
|
253
|
+
* '/api/user': (req, res) => {
|
|
254
|
+
* res.send({ userId, data: 'Hello' });
|
|
255
|
+
* },
|
|
256
|
+
* '/api/user2': (req, res) => {
|
|
257
|
+
* res.send({ userId, data: 'Hello' });
|
|
258
|
+
* }
|
|
259
|
+
* }, [userId]);
|
|
260
|
+
*
|
|
261
|
+
* return <div>Server Component</div>;
|
|
262
|
+
* };
|
|
263
|
+
* ```
|
|
209
264
|
*/
|
|
210
265
|
function useServerHandlerMap(server, map, deps) {
|
|
266
|
+
var mapRef = (0, _react.useRef)(map);
|
|
267
|
+
mapRef.current = map;
|
|
268
|
+
var keys = (0, _react.useMemo)(() => {
|
|
269
|
+
return Object.keys(map).sort();
|
|
270
|
+
}, [map]);
|
|
271
|
+
var mapWrapper = (0, _react.useMemo)(() => {
|
|
272
|
+
return keys.reduce((acc, key) => {
|
|
273
|
+
acc[key] = function (req, res) {
|
|
274
|
+
var _mapRef$current;
|
|
275
|
+
return (_mapRef$current = mapRef.current) === null || _mapRef$current === void 0 || (_mapRef$current = _mapRef$current[key]) === null || _mapRef$current === void 0 ? void 0 : _mapRef$current.call(this, req, res);
|
|
276
|
+
};
|
|
277
|
+
return acc;
|
|
278
|
+
}, {});
|
|
279
|
+
}, [keys]);
|
|
211
280
|
(0, _react.useEffect)(() => {
|
|
212
281
|
if (!server) {
|
|
213
282
|
return;
|
|
214
283
|
}
|
|
215
|
-
// Register handlers using map
|
|
216
|
-
server.map(
|
|
284
|
+
// Register handlers using map with stable wrappers
|
|
285
|
+
var off = server.map(mapWrapper);
|
|
217
286
|
|
|
218
287
|
// Cleanup: unregister all handlers on unmount or when deps change
|
|
219
|
-
return
|
|
220
|
-
|
|
221
|
-
};
|
|
222
|
-
}, [server, map, ...(deps || [])]);
|
|
288
|
+
return off;
|
|
289
|
+
}, [server, mapWrapper, ...(deps || [])]);
|
|
223
290
|
}
|