@firtoz/websocket-do 10.0.0 → 13.0.0

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 (65) hide show
  1. package/README.md +68 -61
  2. package/dist/BaseSession.d.ts +41 -0
  3. package/dist/BaseSession.js +5 -0
  4. package/dist/BaseSession.js.map +1 -0
  5. package/dist/BaseWebSocketDO.d.ts +42 -0
  6. package/dist/BaseWebSocketDO.js +4 -0
  7. package/dist/BaseWebSocketDO.js.map +1 -0
  8. package/dist/StandardSchemaSession.d.ts +41 -0
  9. package/dist/StandardSchemaSession.js +8 -0
  10. package/dist/StandardSchemaSession.js.map +1 -0
  11. package/dist/StandardSchemaWebSocketClient.d.ts +45 -0
  12. package/dist/StandardSchemaWebSocketClient.js +5 -0
  13. package/dist/StandardSchemaWebSocketClient.js.map +1 -0
  14. package/dist/StandardSchemaWebSocketDO.d.ts +28 -0
  15. package/dist/StandardSchemaWebSocketDO.js +5 -0
  16. package/dist/StandardSchemaWebSocketDO.js.map +1 -0
  17. package/dist/WebsocketWrapper.d.ts +9 -0
  18. package/dist/WebsocketWrapper.js +4 -0
  19. package/dist/WebsocketWrapper.js.map +1 -0
  20. package/dist/chunk-3C77OSOD.js +54 -0
  21. package/dist/chunk-3C77OSOD.js.map +1 -0
  22. package/dist/chunk-3LWVEY3R.js +130 -0
  23. package/dist/chunk-3LWVEY3R.js.map +1 -0
  24. package/dist/chunk-53MFRNQS.js +153 -0
  25. package/dist/chunk-53MFRNQS.js.map +1 -0
  26. package/dist/chunk-CAX4POIL.js +13 -0
  27. package/dist/chunk-CAX4POIL.js.map +1 -0
  28. package/dist/chunk-KCPOB32E.js +20 -0
  29. package/dist/chunk-KCPOB32E.js.map +1 -0
  30. package/dist/chunk-NOUFNU2O.js +10 -0
  31. package/dist/chunk-NOUFNU2O.js.map +1 -0
  32. package/dist/chunk-QMGIRIHJ.js +18 -0
  33. package/dist/chunk-QMGIRIHJ.js.map +1 -0
  34. package/dist/chunk-ULGH6X42.js +23 -0
  35. package/dist/chunk-ULGH6X42.js.map +1 -0
  36. package/dist/chunk-WJIQBI6I.js +35 -0
  37. package/dist/chunk-WJIQBI6I.js.map +1 -0
  38. package/dist/chunk-XFB6C3NZ.js +134 -0
  39. package/dist/chunk-XFB6C3NZ.js.map +1 -0
  40. package/dist/index.d.ts +14 -0
  41. package/dist/index.js +11 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/parseStandardSchema.d.ts +9 -0
  44. package/dist/parseStandardSchema.js +4 -0
  45. package/dist/parseStandardSchema.js.map +1 -0
  46. package/dist/standardSchemaMsgpack.d.ts +8 -0
  47. package/dist/standardSchemaMsgpack.js +5 -0
  48. package/dist/standardSchemaMsgpack.js.map +1 -0
  49. package/dist/standardSchemaRpc.d.ts +30 -0
  50. package/dist/standardSchemaRpc.js +6 -0
  51. package/dist/standardSchemaRpc.js.map +1 -0
  52. package/dist/standardSchemaRpcReact.d.ts +27 -0
  53. package/dist/standardSchemaRpcReact.js +54 -0
  54. package/dist/standardSchemaRpcReact.js.map +1 -0
  55. package/package.json +36 -18
  56. package/src/BaseSession.ts +15 -5
  57. package/src/{ZodSession.ts → StandardSchemaSession.ts} +71 -70
  58. package/src/{ZodWebSocketClient.ts → StandardSchemaWebSocketClient.ts} +30 -50
  59. package/src/{ZodWebSocketDO.ts → StandardSchemaWebSocketDO.ts} +29 -22
  60. package/src/index.ts +15 -12
  61. package/src/parseStandardSchema.ts +17 -0
  62. package/src/standardSchemaMsgpack.ts +17 -0
  63. package/src/standardSchemaRpc.ts +83 -0
  64. package/src/standardSchemaRpcReact.ts +107 -0
  65. package/src/zodMsgpack.ts +0 -13
@@ -0,0 +1,83 @@
1
+ import {
2
+ type StandardSchemaWebSocketClientOptions,
3
+ StandardSchemaWebSocketClient,
4
+ } from "./StandardSchemaWebSocketClient";
5
+
6
+ export type StandardSchemaWebSocketRpcSessionConstructorOptions<
7
+ TClientMsg,
8
+ TServerMsg,
9
+ TPending extends { reject: (error: Error) => void },
10
+ > = Omit<
11
+ StandardSchemaWebSocketClientOptions<TClientMsg, TServerMsg>,
12
+ "onMessage"
13
+ > & {
14
+ onMessage: (
15
+ message: TServerMsg,
16
+ session: StandardSchemaWebSocketRpcSession<
17
+ TClientMsg,
18
+ TServerMsg,
19
+ TPending
20
+ >,
21
+ ) => void;
22
+ };
23
+
24
+ /**
25
+ * WebSocket client session with a pending map for request/response RPC and a
26
+ * monotonic id helper. Wire formats stay in your Standard Schema schemas; you dispatch
27
+ * {@link TServerMsg} in `onMessage` (typically with `switch` + `exhaustiveGuard`)
28
+ * and resolve/reject entries in {@link pending}.
29
+ */
30
+ export class StandardSchemaWebSocketRpcSession<
31
+ TClientMsg,
32
+ TServerMsg,
33
+ TPending extends { reject: (error: Error) => void },
34
+ > {
35
+ readonly pending = new Map<string, TPending>();
36
+ readonly client: StandardSchemaWebSocketClient<TClientMsg, TServerMsg>;
37
+ private idSeq = 0;
38
+
39
+ constructor(
40
+ options: StandardSchemaWebSocketRpcSessionConstructorOptions<
41
+ TClientMsg,
42
+ TServerMsg,
43
+ TPending
44
+ >,
45
+ ) {
46
+ const { onMessage, ...clientOptions } = options;
47
+ this.client = new StandardSchemaWebSocketClient({
48
+ ...clientOptions,
49
+ onMessage: (message) => {
50
+ onMessage(message, this);
51
+ },
52
+ });
53
+ }
54
+
55
+ nextId(prefix: string): string {
56
+ return `${prefix}-${++this.idSeq}`;
57
+ }
58
+
59
+ rejectAllPending(reason: Error): void {
60
+ for (const [, pending] of this.pending) {
61
+ pending.reject(reason);
62
+ }
63
+ this.pending.clear();
64
+ }
65
+
66
+ close(code?: number, reason?: string): void {
67
+ this.client.close(code, reason);
68
+ }
69
+ }
70
+
71
+ export function createStandardSchemaWebSocketRpcSession<
72
+ TClientMsg,
73
+ TServerMsg,
74
+ TPending extends { reject: (error: Error) => void },
75
+ >(
76
+ options: StandardSchemaWebSocketRpcSessionConstructorOptions<
77
+ TClientMsg,
78
+ TServerMsg,
79
+ TPending
80
+ >,
81
+ ): StandardSchemaWebSocketRpcSession<TClientMsg, TServerMsg, TPending> {
82
+ return new StandardSchemaWebSocketRpcSession(options);
83
+ }
@@ -0,0 +1,107 @@
1
+ import type { DependencyList, RefObject } from "react";
2
+ import { useEffect, useRef, useState } from "react";
3
+ import {
4
+ type StandardSchemaWebSocketRpcSession,
5
+ type StandardSchemaWebSocketRpcSessionConstructorOptions,
6
+ createStandardSchemaWebSocketRpcSession,
7
+ } from "./standardSchemaRpc";
8
+
9
+ /** Options for {@link useStandardSchemaWebSocketRpc} (same as constructor options for {@link StandardSchemaWebSocketRpcSession}). */
10
+ export type UseStandardSchemaWebSocketRpcOptions<
11
+ TClientMsg,
12
+ TServerMsg,
13
+ TPending extends { reject: (error: Error) => void },
14
+ > = StandardSchemaWebSocketRpcSessionConstructorOptions<
15
+ TClientMsg,
16
+ TServerMsg,
17
+ TPending
18
+ >;
19
+
20
+ /**
21
+ * Connects a {@link StandardSchemaWebSocketRpcSession} in an effect: rejects all pending
22
+ * RPCs and closes the socket on cleanup or when `deps` change.
23
+ *
24
+ * Callback refs keep the latest `onMessage` / `onOpen` / `onClose` without
25
+ * listing them in `deps`, so inline handlers do not reconnect every render.
26
+ *
27
+ * Pass `deps` as the second argument; keep it aligned with values used to
28
+ * build `url` / `webSocket`.
29
+ */
30
+ export function useStandardSchemaWebSocketRpc<
31
+ TClientMsg,
32
+ TServerMsg,
33
+ TPending extends { reject: (error: Error) => void },
34
+ >(
35
+ options: UseStandardSchemaWebSocketRpcOptions<
36
+ TClientMsg,
37
+ TServerMsg,
38
+ TPending
39
+ >,
40
+ deps: DependencyList,
41
+ ): {
42
+ ready: boolean;
43
+ sessionRef: RefObject<StandardSchemaWebSocketRpcSession<
44
+ TClientMsg,
45
+ TServerMsg,
46
+ TPending
47
+ > | null>;
48
+ } {
49
+ const { onMessage, onOpen, onClose, ...clientOptions } = options;
50
+
51
+ const onMessageRef = useRef(onMessage);
52
+ onMessageRef.current = onMessage;
53
+ const onOpenRef = useRef(onOpen);
54
+ onOpenRef.current = onOpen;
55
+ const onCloseRef = useRef(onClose);
56
+ onCloseRef.current = onClose;
57
+
58
+ const [ready, setReady] = useState(false);
59
+ const sessionRef = useRef<StandardSchemaWebSocketRpcSession<
60
+ TClientMsg,
61
+ TServerMsg,
62
+ TPending
63
+ > | null>(null);
64
+
65
+ useEffect(() => {
66
+ let cancelled = false;
67
+ setReady(false);
68
+
69
+ const session = createStandardSchemaWebSocketRpcSession<
70
+ TClientMsg,
71
+ TServerMsg,
72
+ TPending
73
+ >({
74
+ ...clientOptions,
75
+ onMessage: (msg, s) => {
76
+ onMessageRef.current(msg, s);
77
+ },
78
+ onOpen: (event) => {
79
+ if (!cancelled) {
80
+ setReady(true);
81
+ }
82
+ onOpenRef.current?.(event);
83
+ },
84
+ onClose: (event) => {
85
+ if (!cancelled) {
86
+ setReady(false);
87
+ }
88
+ onCloseRef.current?.(event);
89
+ },
90
+ });
91
+
92
+ sessionRef.current = session;
93
+ if (session.client.socket.readyState === WebSocket.OPEN) {
94
+ setReady(true);
95
+ }
96
+
97
+ return () => {
98
+ cancelled = true;
99
+ sessionRef.current = null;
100
+ session.rejectAllPending(new Error("WebSocket closed"));
101
+ session.close();
102
+ };
103
+ // biome-ignore lint/correctness/useExhaustiveDependencies: deps is the explicit contract
104
+ }, deps);
105
+
106
+ return { ready, sessionRef };
107
+ }
package/src/zodMsgpack.ts DELETED
@@ -1,13 +0,0 @@
1
- import { pack, unpack } from "msgpackr";
2
- import type { ZodType } from "zod";
3
-
4
- export const zodMsgpack = <T>(schema: ZodType<T>) => ({
5
- encode(value: T): Uint8Array {
6
- const validated = schema.parse(value);
7
- const packed = pack(validated);
8
- return new Uint8Array(packed);
9
- },
10
- decode(bytes: Uint8Array): T {
11
- return schema.parse(unpack(bytes));
12
- },
13
- });