|
1 | 1 | import * as React from 'react'; |
2 | | -import { RpcError, type RpcInvocationData, type PerformRpcParams } from 'livekit-client'; |
| 2 | +import { |
| 3 | + RpcError, |
| 4 | + type RpcInvocationData, |
| 5 | + type PerformRpcParams, |
| 6 | + type Serializer, |
| 7 | + isSerializer, |
| 8 | + type SerializerInput, |
| 9 | + type SerializerOutput, |
| 10 | + serializers, |
| 11 | +} from 'livekit-client'; |
3 | 12 |
|
4 | 13 | import { useEnsureSession } from '../context'; |
5 | 14 | import { isUseSessionReturn, type UseSessionReturn } from './useSession'; |
6 | 15 |
|
7 | | -// --------------------------------------------------------------------------- |
8 | | -// Serializer types + infrastructure |
9 | | -// --------------------------------------------------------------------------- |
10 | | - |
11 | | -const SerializerSymbol = Symbol.for('lk.serializer'); |
12 | | - |
13 | | -/** |
14 | | - * A bidirectional data format descriptor for RPC payloads. |
15 | | - * |
16 | | - * - `parse(raw)` decodes an incoming wire string into `Input` (used by handlers) |
17 | | - * - `serialize(val)` encodes an `Output` value to a wire string (used by handlers) |
18 | | - * |
19 | | - * For symmetric serializers (`serializers.raw`), `Input === Output === string`. |
20 | | - * For `serializers.json`, both default to `any` so each handler can annotate its own types. |
21 | | - * Use `serializers.custom` to supply your own `parse`/`serialize` pair. |
22 | | - * |
23 | | - * @beta |
24 | | - */ |
25 | | -export type Serializer<Input = any, Output = any> = { |
26 | | - symbol: typeof SerializerSymbol; |
27 | | - parse: (raw: string) => Input; |
28 | | - serialize: (val: Output) => string; |
29 | | -}; |
30 | | - |
31 | | -function isSerializer(v: unknown): v is Serializer<any, any> { |
32 | | - return ( |
33 | | - typeof v === 'object' && |
34 | | - v !== null && |
35 | | - 'symbol' in v && |
36 | | - (v as Record<string, unknown>)['symbol'] === SerializerSymbol |
37 | | - ); |
38 | | -} |
39 | | - |
40 | | -// Extract Input/Output from a Serializer type for use in handler/performRpc constraints. |
41 | | -type SerializerInput<S> = S extends Serializer<infer Input, any> ? Input : any; |
42 | | -type SerializerOutput<S> = S extends Serializer<any, infer Output> ? Output : any; |
43 | | - |
44 | | -/** @internal */ |
45 | | -function base<Input = any, Output = any>( |
46 | | - params: Omit<Serializer<Input, Output>, 'symbol'>, |
47 | | -): Serializer<Input, Output> { |
48 | | - return { ...params, symbol: SerializerSymbol }; |
49 | | -} |
50 | | - |
51 | | -/** |
52 | | - * JSON serializer — `JSON.parse` on the way in, `JSON.stringify` on the way out. |
53 | | - * Defaults to `any` so individual handlers can annotate their own payload types. |
54 | | - */ |
55 | | -function json<Input = any, Output = any>(): Serializer<Input, Output> { |
56 | | - return base({ |
57 | | - parse: (raw: string) => JSON.parse(raw) as Input, |
58 | | - serialize: (val: unknown) => JSON.stringify(val), |
59 | | - }); |
60 | | -} |
61 | | - |
62 | | -/** Raw string serializer — passes payloads through as plain strings with no encoding. */ |
63 | | -function raw() { |
64 | | - return base({ |
65 | | - parse: (raw: string) => raw, |
66 | | - serialize: (val: string) => val, |
67 | | - }); |
68 | | -} |
69 | | - |
70 | | -/** Custom serializer - allows custom defined parse and serialize functions */ |
71 | | -function custom<Input = any, Output = any>( |
72 | | - params: Omit<Serializer<Input, Output>, 'symbol'>, |
73 | | -): Serializer<Input, Output> { |
74 | | - return base(params); |
75 | | -} |
76 | | - |
77 | | -/** |
78 | | - * Serializer helpers for RPC payload encoding. |
79 | | - * |
80 | | - * @example |
81 | | - * ```ts |
82 | | - * // Inline handler — types inferred |
83 | | - * useRpc(session, "myMethod", async (payload: MyInput) => myOutput); |
84 | | - * |
85 | | - * // Override default serializer for a handler |
86 | | - * useRpc(session, "myMethod", async (payload) => payload, { serializer: serializers.raw() }); |
87 | | - * |
88 | | - * // Manual serializer instances |
89 | | - * const a = serializers.raw(); // Serializer<string, string> |
90 | | - * const b = serializer.json<{ foo: string }, { bar: string }>(); // Serializer<{ foo: string }, { bar: string }> |
91 | | - * ``` |
92 | | - * |
93 | | - * @beta |
94 | | - */ |
95 | | -export const serializers = { json, raw, custom }; |
96 | | - |
97 | 16 | // --------------------------------------------------------------------------- |
98 | 17 | // RPC types |
99 | 18 | // --------------------------------------------------------------------------- |
|
0 commit comments