@livon/client 0.27.0-rc.3 → 0.28.0-rc.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/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 LIVON contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,8 +1,145 @@
1
+ <!-- Generated from website/docs/packages/*.md. Do not edit directly. -->
2
+
1
3
  # @livon/client
2
4
 
3
- Package docs (GitHub Pages):
4
- - https://live-input-vector-output-node.github.io/livon-ts/docs/packages/client
5
5
 
6
- License:
7
- - MIT
8
- - Root license text: `../../LIZENZ.md`
6
+ [![npm](https://img.shields.io/npm/v/%40livon%2Fclient)](https://www.npmjs.com/package/@livon/client)
7
+ [![dependencies](https://img.shields.io/librariesio/release/npm/%40livon%2Fclient?label=dependencies)](https://libraries.io/npm/%40livon%2Fclient)
8
+ [![code quality](https://img.shields.io/github/actions/workflow/status/live-input-vector-output-node/livon-ts/code-quality.yml?branch=main&label=code%20quality)](https://github.com/live-input-vector-output-node/livon-ts/actions/workflows/code-quality.yml)
9
+ [![package size](https://img.shields.io/npm/unpacked-size/%40livon%2Fclient?label=package%20size)](https://www.npmjs.com/package/@livon/client)
10
+ [![license](https://img.shields.io/github/license/live-input-vector-output-node/livon-ts)](https://github.com/live-input-vector-output-node/livon-ts)
11
+
12
+ ## Purpose
13
+
14
+ [@livon/client](https://livon.tech/docs/packages/client) provides deterministic client interface execution and generated-client foundations.
15
+
16
+ ## Best for
17
+
18
+ Use this package when frontend apps consume generated LIVON APIs and typed subscription handlers.
19
+
20
+ Exports include:
21
+
22
+ - `createClient`
23
+ - `createClientModule`
24
+ - `clientModule`
25
+
26
+ ## Generator sync policy
27
+
28
+ Generated client surfaces and hover docs are built from the client generator.
29
+ When generator output changes, docs must be updated in sync.
30
+
31
+ - Rule source: `packages/client/PROMPT.md`
32
+ - JSDoc reference: [SchemaDoc & Generated JSDoc](https://livon.tech/docs/core/schema-doc-and-generated-jsdoc)
33
+
34
+ Current generated typing behavior to keep in sync:
35
+
36
+ - `and(...)` schema nodes are emitted as TypeScript intersections (`Left & Right`).
37
+ - If schema composition passes an explicit `name`, that name is used as the generated type name.
38
+
39
+ ### Central TypeScript surface template
40
+
41
+ Generated interface and signature syntax is centralized in:
42
+
43
+ - `packages/client/src/typeScriptSurfaceTemplate.ts`
44
+
45
+ Use this file when TypeScript surface style should change globally (for example interface member syntax, callable signatures, or method/property signature formatting).
46
+ This avoids editing many render call sites in `packages/client/src/generate.ts`.
47
+
48
+ ## Install
49
+
50
+ ```sh
51
+ pnpm add @livon/client
52
+ ```
53
+
54
+ ## Runtime wiring (generated API path)
55
+
56
+ ```ts
57
+ import {runtime} from '@livon/runtime';
58
+ import {clientWsTransport} from '@livon/client-ws-transport';
59
+ import {api} from './generated/api';
60
+
61
+ runtime(
62
+ clientWsTransport({url: 'ws://127.0.0.1:3002/ws'}),
63
+ api,
64
+ );
65
+ ```
66
+
67
+ ### Parameters in this example
68
+
69
+ `clientWsTransport({...})`:
70
+
71
+ - `url` (`string`): websocket endpoint used by client transport.
72
+
73
+ `runtime(transport, api)`:
74
+
75
+ - `transport` (`RuntimeModule`): client transport module.
76
+ - `api` (`RuntimeModule`): generated client module built from server schema.
77
+
78
+ ## Subscription handling pattern
79
+
80
+ ```ts
81
+ api({
82
+ onMessage: (payload, ctx) => {
83
+ payload.text;
84
+ ctx.state.get('lastMessage');
85
+ },
86
+ });
87
+
88
+ api.onMessage.off();
89
+ ```
90
+
91
+ ### Parameters in this example
92
+
93
+ `api({...})`:
94
+
95
+ - `onMessage` (`(payload, ctx) => void`): typed subscription callback.
96
+ - `payload` (in callback): generated payload type from server schema.
97
+ - `ctx` (in callback): runtime context for state/emit/room access.
98
+
99
+ `api.onMessage.off()`:
100
+
101
+ - no parameters; disables one subscription callback stream.
102
+
103
+ ## Room-scoped handlers
104
+
105
+ ```ts
106
+ api.room('global')({
107
+ onMessage: (payload) => {
108
+ payload.text;
109
+ },
110
+ });
111
+ ```
112
+
113
+ ### Parameters in this example
114
+
115
+ `api.room(roomId)`:
116
+
117
+ - `roomId` (`string`): room selector for scoped schema handling.
118
+
119
+ `api.room(... )({...})`:
120
+
121
+ - `onMessage` (`(payload) => void`): room-scoped subscription callback.
122
+
123
+ ## Low-level client module
124
+
125
+ ```ts
126
+ import {createClientModule} from '@livon/client';
127
+ import {runtime} from '@livon/runtime';
128
+
129
+ const module = createClientModule({ast});
130
+ runtime(transport, module);
131
+ ```
132
+
133
+ ### Parameters in this example
134
+
135
+ `createClientModule({...})`:
136
+
137
+ - `ast` (`AstNode`): schema AST used to build executable client interface module.
138
+
139
+ ## Related pages
140
+
141
+ - [@livon/runtime](https://livon.tech/docs/packages/runtime)
142
+ - [@livon/client-ws-transport](https://livon.tech/docs/packages/client-ws-transport)
143
+ - [@livon/schema](https://livon.tech/docs/packages/schema)
144
+ - [SchemaDoc & Generated JSDoc](https://livon.tech/docs/core/schema-doc-and-generated-jsdoc)
145
+ - [Schema APIs](https://livon.tech/docs/schema)
@@ -0,0 +1 @@
1
+ No third-party notices are required for this package at this time.
package/dist/client.cjs CHANGED
@@ -1 +1,360 @@
1
- "use strict";const __rslib_import_meta_url__="u"<typeof document?new(require("url".replace("",""))).URL("file:"+__filename).href:document.currentScript&&document.currentScript.src||new URL("main.js",document.baseURI).href;var __webpack_require__={};__webpack_require__.d=(e,t)=>{for(var r in t)__webpack_require__.o(t,r)&&!__webpack_require__.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},__webpack_require__.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),__webpack_require__.r=e=>{"u">typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var __webpack_exports__={};__webpack_require__.r(__webpack_exports__),__webpack_require__.d(__webpack_exports__,{clientModule:()=>clientModule,createClient:()=>createClient,createClientModule:()=>createClientModule});const DEFAULT_REQUEST_KEY="livon.client.request",setClientRequest=({client:e,registry:t,requestKey:r})=>{"object"==typeof e&&null!==e&&"setRequest"in e&&"function"==typeof e.setRequest&&e.setRequest((e,n)=>{let a=t.state.get(r);if(!a)throw Error("Client request handler is not available.");return a(e,n)})},buildClientEventEnvelope=e=>"payload"in e?{...e,payload:e.payload}:{...e,error:e.error},clientModule=(e,t={})=>({name:t.name??"client-module",register:r=>{setClientRequest({client:e,registry:r,requestKey:t.requestKey??DEFAULT_REQUEST_KEY}),r.onReceive((t,r,n)=>(e.emitEvent(buildClientEventEnvelope(t)),n()))}}),isRecord=e=>"object"==typeof e&&null!==e&&!Array.isArray(e),isArray=e=>Array.isArray(e),capitalize=e=>0===e.length?e:e.slice(0,1).toUpperCase()+e.slice(1),camelCaseName=e=>e?e.replace(/[^a-zA-Z0-9]+(.)/g,(e,t)=>String(t).toUpperCase()).replace(/^./,e=>e.toLowerCase()):e,fieldMethodName=(e,t)=>`$${camelCaseName(e)}${capitalize(t)}`,fieldEventName=(e,t)=>`$${e}.${t}`,walkAst=(e,t)=>{t(e),e.children?.forEach(e=>walkAst(e,t))},collectOperations=e=>{let t=[];return walkAst(e,e=>{if("operation"!==e.type||!e.name)return;let r=e.children?.[0],n=e.children?.[1];t.push({name:e.name,input:r,output:n,event:e.name})}),t},collectFieldOperations=e=>{let t=new Map;return walkAst(e,e=>{if("field"!==e.type)return;let r=e.constraints,n="string"==typeof r?.owner?r.owner:void 0,a="string"==typeof r?.field?r.field:void 0;if(!n||!a)return;let i=e.children??[],l=i[0],o=3===i.length?i[1]:void 0,s=3===i.length?i[2]:i[1];if(!l)return;let c={owner:n,field:a,input:o,output:s,event:fieldEventName(n,a)};t.has(n)||t.set(n,new Map),t.get(n).set(a,c)}),t},hydrateByNode=({value:e,node:t,registry:r,request:n})=>{if(!t)return e;if("array"===t.type&&Array.isArray(e)){let a=t.children?.[0];return e.forEach((t,i)=>{e[i]=hydrateByNode({value:t,node:a,registry:r,request:n})}),e}if("tuple"===t.type&&Array.isArray(e)){let a=t.children??[];return e.forEach((t,i)=>{e[i]=hydrateByNode({value:t,node:a[i],registry:r,request:n})}),e}if("object"===t.type&&isRecord(e)){let a=t.name;return a&&r.has(a)&&attachFieldOperations({target:e,typeName:a,registry:r,request:n}),(t.children??[]).forEach(t=>{if("field"!==t.type||!t.name)return;let a=t.children?.[0];a&&(e[t.name]=hydrateByNode({value:e[t.name],node:a,registry:r,request:n}))}),e}return"field"===t.type?hydrateByNode({value:e,node:t.children?.[0],registry:r,request:n}):e},attachFieldOperations=({target:e,typeName:t,registry:r,request:n})=>{let a=r.get(t);!a||Object.isExtensible(e)&&a.forEach((t,a)=>{a in e||Object.defineProperty(e,a,{enumerable:!1,configurable:!0,value:async a=>hydrateByNode({value:await n(t.event,{dependsOn:e,input:a}),node:t.output,registry:r,request:n})})})},normalizeFieldPayload=e=>{if(isRecord(e)&&"dependsOn"in e){let t=e.dependsOn,r="input"in e?e.input:void 0;return void 0===r?{dependsOn:t}:{dependsOn:t,input:r}}return{dependsOn:e}},createClientCore=({ast:e})=>{let t,r=collectOperations(e),n=collectFieldOperations(e),a={};a.setRequest=e=>{t=e};let i=new Map,l=new Map,o=new Map,s=new Map;return r.forEach(e=>{a[e.name]=async r=>{if(!t)throw Error("Client request handler is not available.");return hydrateByNode({value:await t(e.event,r),node:e.output,registry:n,request:t})}}),n.forEach((e,r)=>{e.forEach((e,i)=>{let l=fieldMethodName(r,i);l in a||(a[l]=async(r,a)=>{let i=normalizeFieldPayload(r);if(!t)throw Error("Client request handler is not available.");return hydrateByNode({value:await t(e.event,{dependsOn:i.dependsOn,input:a??i.input}),node:e.output,registry:n,request:t})})})}),Object.assign(a,{__register:(e,t)=>{let r=Object.entries(e).filter(([,e])=>"function"==typeof e);if(0===r.length)return;if(!t)return void r.forEach(([e,t])=>{i.set(e,t),l.set(e,!0)});let n=o.get(t)??new Map,a=s.get(t)??new Map;r.forEach(([e,t])=>{n.set(e,t),a.set(e,!0)}),o.set(t,n),s.set(t,a)},__toggle:(e,t,r)=>(({enabled:e,event:t,roomId:r})=>{if(!r)return void l.set(t,e);let n=s.get(r)??new Map;n.set(t,e),s.set(r,n)})({event:e,enabled:t,roomId:r}),emitEvent:e=>{let t={eventId:e.id,event:e.event,status:e.status,metadata:e.metadata,context:e.context,room:"string"==typeof e.metadata?.room?String(e.metadata.room):void 0},r=t.room;if(r){let n=s.get(r),a=o.get(r),i=a?.get(e.event),l=n?.get(e.event)??!0;i&&l&&i(e.payload,t)}let n=i.get(e.event),a=l.get(e.event)??!0;n&&a&&n(e.payload,t)}})},createClient=e=>{let t=createClientCore({ast:e.ast});return Object.assign({name:e.name??"client",register:r=>{setClientRequest({client:t,registry:r,requestKey:e.requestKey??DEFAULT_REQUEST_KEY}),r.onReceive((e,r,n)=>(t.emitEvent(buildClientEventEnvelope(e)),n()))}},t)},createClientModule=e=>createClient(e);for(var __rspack_i in exports.clientModule=__webpack_exports__.clientModule,exports.createClient=__webpack_exports__.createClient,exports.createClientModule=__webpack_exports__.createClientModule,__webpack_exports__)-1===["clientModule","createClient","createClientModule"].indexOf(__rspack_i)&&(exports[__rspack_i]=__webpack_exports__[__rspack_i]);Object.defineProperty(exports,"__esModule",{value:!0});
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.d = (exports1, definition)=>{
5
+ for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
6
+ enumerable: true,
7
+ get: definition[key]
8
+ });
9
+ };
10
+ })();
11
+ (()=>{
12
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
13
+ })();
14
+ (()=>{
15
+ __webpack_require__.r = (exports1)=>{
16
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
17
+ value: 'Module'
18
+ });
19
+ Object.defineProperty(exports1, '__esModule', {
20
+ value: true
21
+ });
22
+ };
23
+ })();
24
+ var __webpack_exports__ = {};
25
+ __webpack_require__.r(__webpack_exports__);
26
+ __webpack_require__.d(__webpack_exports__, {
27
+ clientModule: ()=>clientModule,
28
+ createClient: ()=>createClient,
29
+ createClientModule: ()=>createClientModule
30
+ });
31
+ const DEFAULT_REQUEST_KEY = 'livon.client.request';
32
+ const setClientRequest = ({ client, registry, requestKey })=>{
33
+ if ('object' != typeof client || null === client || !('setRequest' in client)) return;
34
+ const candidate = client;
35
+ if ('function' != typeof candidate.setRequest) return;
36
+ candidate.setRequest((event, payload)=>{
37
+ const request = registry.state.get(requestKey);
38
+ if (!request) throw new Error('Client request handler is not available.');
39
+ return request(event, payload);
40
+ });
41
+ };
42
+ const buildClientEventEnvelope = (envelope)=>{
43
+ if ('payload' in envelope) return {
44
+ ...envelope,
45
+ payload: envelope.payload
46
+ };
47
+ return {
48
+ ...envelope,
49
+ error: envelope.error
50
+ };
51
+ };
52
+ const clientModule = (client, options = {})=>{
53
+ const register = (registry)=>{
54
+ const requestKey = options.requestKey ?? DEFAULT_REQUEST_KEY;
55
+ setClientRequest({
56
+ client,
57
+ registry,
58
+ requestKey
59
+ });
60
+ registry.onReceive((envelope, _ctx, next)=>{
61
+ client.emitEvent(buildClientEventEnvelope(envelope));
62
+ return next();
63
+ });
64
+ };
65
+ return {
66
+ name: options.name ?? 'client-module',
67
+ register
68
+ };
69
+ };
70
+ const isRecord = (value)=>'object' == typeof value && null !== value && !Array.isArray(value);
71
+ const isArray = (value)=>Array.isArray(value);
72
+ const capitalize = (value)=>0 === value.length ? value : value.slice(0, 1).toUpperCase() + value.slice(1);
73
+ const camelCaseName = (value)=>{
74
+ if (!value) return value;
75
+ return value.replace(/[^a-zA-Z0-9]+(.)/g, (_, group)=>String(group).toUpperCase()).replace(/^./, (char)=>char.toLowerCase());
76
+ };
77
+ const fieldMethodName = (owner, field)=>`$${camelCaseName(owner)}${capitalize(field)}`;
78
+ const fieldEventName = (owner, field)=>`$${owner}.${field}`;
79
+ const walkAst = (node, visit)=>{
80
+ visit(node);
81
+ node.children?.forEach((child)=>walkAst(child, visit));
82
+ };
83
+ const collectOperations = (root)=>{
84
+ const operations = [];
85
+ walkAst(root, (node)=>{
86
+ if ('operation' !== node.type || !node.name) return;
87
+ const input = node.children?.[0];
88
+ const output = node.children?.[1];
89
+ operations.push({
90
+ name: node.name,
91
+ input,
92
+ output,
93
+ event: node.name
94
+ });
95
+ });
96
+ return operations;
97
+ };
98
+ const collectFieldOperations = (root)=>{
99
+ const registry = new Map();
100
+ walkAst(root, (node)=>{
101
+ if ('field' !== node.type) return;
102
+ const constraints = node.constraints;
103
+ const owner = 'string' == typeof constraints?.owner ? constraints.owner : void 0;
104
+ const field = 'string' == typeof constraints?.field ? constraints.field : void 0;
105
+ if (!owner || !field) return;
106
+ const children = node.children ?? [];
107
+ const dependsOn = children[0];
108
+ const input = 3 === children.length ? children[1] : void 0;
109
+ const output = 3 === children.length ? children[2] : children[1];
110
+ if (!dependsOn) return;
111
+ const spec = {
112
+ owner,
113
+ field,
114
+ input,
115
+ output,
116
+ event: fieldEventName(owner, field)
117
+ };
118
+ if (!registry.has(owner)) registry.set(owner, new Map());
119
+ registry.get(owner).set(field, spec);
120
+ });
121
+ return registry;
122
+ };
123
+ const hydrateByNode = ({ value, node, registry, request })=>{
124
+ if (!node) return value;
125
+ if ('array' === node.type && isArray(value)) {
126
+ const child = node.children?.[0];
127
+ value.forEach((item, index)=>{
128
+ value[index] = hydrateByNode({
129
+ value: item,
130
+ node: child,
131
+ registry,
132
+ request
133
+ });
134
+ });
135
+ return value;
136
+ }
137
+ if ('tuple' === node.type && isArray(value)) {
138
+ const children = node.children ?? [];
139
+ value.forEach((item, index)=>{
140
+ value[index] = hydrateByNode({
141
+ value: item,
142
+ node: children[index],
143
+ registry,
144
+ request
145
+ });
146
+ });
147
+ return value;
148
+ }
149
+ if ('and' === node.type) return (node.children ?? []).reduce((current, child)=>hydrateByNode({
150
+ value: current,
151
+ node: child,
152
+ registry,
153
+ request
154
+ }), value);
155
+ if ('object' === node.type && isRecord(value)) {
156
+ const typeName = node.name;
157
+ if (typeName && registry.has(typeName)) attachFieldOperations({
158
+ target: value,
159
+ typeName,
160
+ registry,
161
+ request
162
+ });
163
+ const fields = node.children ?? [];
164
+ fields.forEach((fieldNode)=>{
165
+ if ('field' !== fieldNode.type || !fieldNode.name) return;
166
+ const child = fieldNode.children?.[0];
167
+ if (!child) return;
168
+ value[fieldNode.name] = hydrateByNode({
169
+ value: value[fieldNode.name],
170
+ node: child,
171
+ registry,
172
+ request
173
+ });
174
+ });
175
+ return value;
176
+ }
177
+ if ('field' === node.type) {
178
+ const child = node.children?.[0];
179
+ return hydrateByNode({
180
+ value,
181
+ node: child,
182
+ registry,
183
+ request
184
+ });
185
+ }
186
+ return value;
187
+ };
188
+ const attachFieldOperations = ({ target, typeName, registry, request })=>{
189
+ const operations = registry.get(typeName);
190
+ if (!operations) return;
191
+ if (!Object.isExtensible(target)) return;
192
+ operations.forEach((spec, fieldName)=>{
193
+ if (fieldName in target) return;
194
+ Object.defineProperty(target, fieldName, {
195
+ enumerable: false,
196
+ configurable: true,
197
+ value: async (input)=>{
198
+ const payload = {
199
+ dependsOn: target,
200
+ input
201
+ };
202
+ const result = await request(spec.event, payload);
203
+ return hydrateByNode({
204
+ value: result,
205
+ node: spec.output,
206
+ registry,
207
+ request
208
+ });
209
+ }
210
+ });
211
+ });
212
+ };
213
+ const normalizeFieldPayload = (payload)=>{
214
+ if (isRecord(payload) && 'dependsOn' in payload) {
215
+ const dependsOn = payload.dependsOn;
216
+ const input = 'input' in payload ? payload.input : void 0;
217
+ if (void 0 === input) return {
218
+ dependsOn
219
+ };
220
+ return {
221
+ dependsOn,
222
+ input
223
+ };
224
+ }
225
+ return {
226
+ dependsOn: payload
227
+ };
228
+ };
229
+ const createClientCore = ({ ast })=>{
230
+ const operations = collectOperations(ast);
231
+ const fieldRegistry = collectFieldOperations(ast);
232
+ let request;
233
+ const client = {};
234
+ client.setRequest = (next)=>{
235
+ request = next;
236
+ };
237
+ const globalHandlers = new Map();
238
+ const globalEnabled = new Map();
239
+ const roomHandlers = new Map();
240
+ const roomEnabled = new Map();
241
+ const registerHandlers = (handlers, roomId)=>{
242
+ const entries = Object.entries(handlers).filter(([, handler])=>'function' == typeof handler);
243
+ if (0 === entries.length) return;
244
+ if (!roomId) return void entries.forEach(([event, handler])=>{
245
+ globalHandlers.set(event, handler);
246
+ globalEnabled.set(event, true);
247
+ });
248
+ const roomMap = roomHandlers.get(roomId) ?? new Map();
249
+ const enabledMap = roomEnabled.get(roomId) ?? new Map();
250
+ entries.forEach(([event, handler])=>{
251
+ roomMap.set(event, handler);
252
+ enabledMap.set(event, true);
253
+ });
254
+ roomHandlers.set(roomId, roomMap);
255
+ roomEnabled.set(roomId, enabledMap);
256
+ };
257
+ const toggleHandler = ({ enabled, event, roomId })=>{
258
+ if (!roomId) return void globalEnabled.set(event, enabled);
259
+ const enabledMap = roomEnabled.get(roomId) ?? new Map();
260
+ enabledMap.set(event, enabled);
261
+ roomEnabled.set(roomId, enabledMap);
262
+ };
263
+ const dispatch = (envelope)=>{
264
+ const ctx = {
265
+ eventId: envelope.id,
266
+ event: envelope.event,
267
+ status: envelope.status,
268
+ metadata: envelope.metadata,
269
+ context: envelope.context,
270
+ room: 'string' == typeof envelope.metadata?.room ? String(envelope.metadata.room) : void 0
271
+ };
272
+ const roomId = ctx.room;
273
+ if (roomId) {
274
+ const enabledMap = roomEnabled.get(roomId);
275
+ const roomMap = roomHandlers.get(roomId);
276
+ const handler = roomMap?.get(envelope.event);
277
+ const isEnabled = enabledMap?.get(envelope.event) ?? true;
278
+ if (handler && isEnabled) handler(envelope.payload, ctx);
279
+ }
280
+ const handler = globalHandlers.get(envelope.event);
281
+ const isEnabled = globalEnabled.get(envelope.event) ?? true;
282
+ if (handler && isEnabled) handler(envelope.payload, ctx);
283
+ };
284
+ operations.forEach((op)=>{
285
+ client[op.name] = async (input)=>{
286
+ if (!request) throw new Error('Client request handler is not available.');
287
+ const result = await request(op.event, input);
288
+ return hydrateByNode({
289
+ value: result,
290
+ node: op.output,
291
+ registry: fieldRegistry,
292
+ request
293
+ });
294
+ };
295
+ });
296
+ fieldRegistry.forEach((fields, owner)=>{
297
+ fields.forEach((spec, field)=>{
298
+ const method = fieldMethodName(owner, field);
299
+ if (method in client) return;
300
+ client[method] = async (payload, input)=>{
301
+ const normalized = normalizeFieldPayload(payload);
302
+ if (!request) throw new Error('Client request handler is not available.');
303
+ const result = await request(spec.event, {
304
+ dependsOn: normalized.dependsOn,
305
+ input: input ?? normalized.input
306
+ });
307
+ return hydrateByNode({
308
+ value: result,
309
+ node: spec.output,
310
+ registry: fieldRegistry,
311
+ request
312
+ });
313
+ };
314
+ });
315
+ });
316
+ return Object.assign(client, {
317
+ __register: registerHandlers,
318
+ __toggle: (event, enabled, roomId)=>toggleHandler({
319
+ event,
320
+ enabled,
321
+ roomId
322
+ }),
323
+ emitEvent: dispatch
324
+ });
325
+ };
326
+ const createClient = (input)=>{
327
+ const client = createClientCore({
328
+ ast: input.ast
329
+ });
330
+ const register = (registry)=>{
331
+ const requestKey = input.requestKey ?? DEFAULT_REQUEST_KEY;
332
+ setClientRequest({
333
+ client,
334
+ registry,
335
+ requestKey
336
+ });
337
+ registry.onReceive((envelope, _ctx, next)=>{
338
+ client.emitEvent(buildClientEventEnvelope(envelope));
339
+ return next();
340
+ });
341
+ };
342
+ const moduleBase = {
343
+ name: input.name ?? 'client',
344
+ register
345
+ };
346
+ const moduleWithClient = Object.assign(moduleBase, client);
347
+ return moduleWithClient;
348
+ };
349
+ const createClientModule = (input)=>createClient(input);
350
+ exports.clientModule = __webpack_exports__.clientModule;
351
+ exports.createClient = __webpack_exports__.createClient;
352
+ exports.createClientModule = __webpack_exports__.createClientModule;
353
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
354
+ "clientModule",
355
+ "createClient",
356
+ "createClientModule"
357
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
358
+ Object.defineProperty(exports, '__esModule', {
359
+ value: true
360
+ });
package/dist/client.d.ts CHANGED
@@ -64,7 +64,7 @@ export interface ClientModuleOptions {
64
64
  * @remarks
65
65
  * Parameter and return types are defined in the TypeScript signature.
66
66
  *
67
- * @see https://live-input-vector-output-node.github.io/livon-ts/docs/packages/client
67
+ * @see https://livon.tech/docs/packages/client
68
68
  *
69
69
  * @example
70
70
  * const result = clientModule(undefined as never);
@@ -76,7 +76,7 @@ export declare const clientModule: (client: ClientEventEmitter, options?: Client
76
76
  * @remarks
77
77
  * Parameter and return types are defined in the TypeScript signature.
78
78
  *
79
- * @see https://live-input-vector-output-node.github.io/livon-ts/docs/packages/client
79
+ * @see https://livon.tech/docs/packages/client
80
80
  *
81
81
  * @example
82
82
  * const result = createClient(undefined as never);
@@ -92,7 +92,7 @@ export declare const createClient: (input: ClientModuleInput) => ClientModule &
92
92
  * @remarks
93
93
  * Parameter and return types are defined in the TypeScript signature.
94
94
  *
95
- * @see https://live-input-vector-output-node.github.io/livon-ts/docs/packages/client
95
+ * @see https://livon.tech/docs/packages/client
96
96
  *
97
97
  * @example
98
98
  * const result = createClientModule(undefined as never);