@emeryld/rrroutes-client 2.2.14 → 2.2.15
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/dist/index.cjs +232 -118
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +236 -121
- package/dist/index.mjs.map +1 -1
- package/dist/routesV3.client.index.d.ts +2 -2
- package/dist/routesV3.client.types.d.ts +44 -42
- package/dist/sockets/socket.client.index.d.ts +2 -2
- package/dist/sockets/socketedRoute/socket.client.helper.d.ts +5 -5
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -69,22 +69,20 @@ var defaultFetcher = async (req) => {
|
|
|
69
69
|
};
|
|
70
70
|
|
|
71
71
|
// src/routesV3.client.index.ts
|
|
72
|
-
var
|
|
72
|
+
var import_rrroutes_contract = require("@emeryld/rrroutes-contract");
|
|
73
73
|
var import_react_query = require("@tanstack/react-query");
|
|
74
|
+
var import_react = require("react");
|
|
74
75
|
var import_zod = require("zod");
|
|
75
|
-
var import_rrroutes_contract = require("@emeryld/rrroutes-contract");
|
|
76
76
|
var toUpper = (m) => m.toUpperCase();
|
|
77
|
-
var
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}
|
|
77
|
+
var paginationQueryShape = {
|
|
78
|
+
pagination_cursor: import_zod.z.string().optional(),
|
|
79
|
+
pagination_limit: import_zod.z.coerce.number().min(1).max(100).default(20)
|
|
80
|
+
};
|
|
81
|
+
var defaultFeedQuerySchema = import_zod.z.object(paginationQueryShape);
|
|
81
82
|
var defaultFeedOutputSchema = import_zod.z.object({
|
|
82
83
|
items: import_zod.z.array(import_zod.z.unknown()),
|
|
83
84
|
nextCursor: import_zod.z.string().optional()
|
|
84
85
|
});
|
|
85
|
-
function zParse(value, schema) {
|
|
86
|
-
return schema ? schema.parse(value) : value;
|
|
87
|
-
}
|
|
88
86
|
function toSearchString(query) {
|
|
89
87
|
if (!query) return "";
|
|
90
88
|
const params = new URLSearchParams();
|
|
@@ -183,41 +181,51 @@ function extractArgs(args) {
|
|
|
183
181
|
function toArgsTuple(args) {
|
|
184
182
|
return typeof args === "undefined" ? [] : [args];
|
|
185
183
|
}
|
|
184
|
+
function getZodShape(schema) {
|
|
185
|
+
const shapeOrGetter = schema.shape ? schema.shape : schema._def?.shape?.();
|
|
186
|
+
if (!shapeOrGetter) return {};
|
|
187
|
+
return typeof shapeOrGetter === "function" ? shapeOrGetter.call(schema) : shapeOrGetter;
|
|
188
|
+
}
|
|
186
189
|
function augmentFeedQuerySchema(schema) {
|
|
187
190
|
if (!schema) return defaultFeedQuerySchema;
|
|
188
|
-
if (schema instanceof import_zod.z.ZodObject) {
|
|
189
|
-
|
|
190
|
-
return
|
|
191
|
-
...shape ?? {},
|
|
192
|
-
cursor: defaultFeedQuerySchema.shape.cursor,
|
|
193
|
-
limit: defaultFeedQuerySchema.shape.limit
|
|
194
|
-
});
|
|
191
|
+
if (!(schema instanceof import_zod.z.ZodObject)) {
|
|
192
|
+
console.warn("Feed queries must be a ZodObject; default pagination applied.");
|
|
193
|
+
return defaultFeedQuerySchema;
|
|
195
194
|
}
|
|
196
|
-
return
|
|
195
|
+
return schema.extend(paginationQueryShape);
|
|
197
196
|
}
|
|
198
197
|
function augmentFeedOutputSchema(schema) {
|
|
199
198
|
if (!schema) return defaultFeedOutputSchema;
|
|
200
|
-
if (schema instanceof import_zod.z.
|
|
201
|
-
const shape = schema.shape ? schema.shape : schema._def?.shape?.();
|
|
202
|
-
const hasItems = Boolean(shape?.items);
|
|
203
|
-
if (hasItems) return schema.extend({ nextCursor: import_zod.z.string().optional() });
|
|
199
|
+
if (schema instanceof import_zod.z.ZodArray) {
|
|
204
200
|
return import_zod.z.object({
|
|
205
|
-
items:
|
|
201
|
+
items: schema,
|
|
206
202
|
nextCursor: import_zod.z.string().optional()
|
|
207
203
|
});
|
|
208
204
|
}
|
|
209
|
-
if (schema instanceof import_zod.z.
|
|
205
|
+
if (schema instanceof import_zod.z.ZodObject) {
|
|
206
|
+
const shape = getZodShape(schema);
|
|
207
|
+
if (shape?.items) {
|
|
208
|
+
return schema.extend({
|
|
209
|
+
nextCursor: import_zod.z.string().optional()
|
|
210
|
+
});
|
|
211
|
+
}
|
|
210
212
|
return import_zod.z.object({
|
|
211
|
-
items: schema,
|
|
213
|
+
items: import_zod.z.array(schema),
|
|
212
214
|
nextCursor: import_zod.z.string().optional()
|
|
213
215
|
});
|
|
214
216
|
}
|
|
215
|
-
return
|
|
217
|
+
return import_zod.z.object({
|
|
218
|
+
items: import_zod.z.array(schema),
|
|
219
|
+
nextCursor: import_zod.z.string().optional()
|
|
220
|
+
});
|
|
216
221
|
}
|
|
217
222
|
function buildUrl(leaf, baseUrl, params, query) {
|
|
218
|
-
const normalizedParams =
|
|
219
|
-
const normalizedQuery =
|
|
220
|
-
const path = (0, import_rrroutes_contract.compilePath)(
|
|
223
|
+
const normalizedParams = leaf.cfg.paramsSchema ? (0, import_rrroutes_contract.lowProfileParse)(leaf.cfg.paramsSchema, params) : {};
|
|
224
|
+
const normalizedQuery = leaf.cfg.querySchema ? (0, import_rrroutes_contract.lowProfileParse)(leaf.cfg.querySchema, query) : {};
|
|
225
|
+
const path = (0, import_rrroutes_contract.compilePath)(
|
|
226
|
+
leaf.path,
|
|
227
|
+
normalizedParams ?? {}
|
|
228
|
+
);
|
|
221
229
|
const url = `${baseUrl ?? ""}${path}${toSearchString(normalizedQuery)}`;
|
|
222
230
|
return { url, normalizedQuery, normalizedParams };
|
|
223
231
|
}
|
|
@@ -225,10 +233,13 @@ function createRouteClient(opts) {
|
|
|
225
233
|
const queryClient = opts.queryClient;
|
|
226
234
|
const fetcher = opts.fetcher ?? defaultFetcher;
|
|
227
235
|
const baseUrl = opts.baseUrl;
|
|
228
|
-
const cursorParam = opts.cursorParam ?? "
|
|
236
|
+
const cursorParam = opts.cursorParam ?? "pagination_cursor";
|
|
229
237
|
const getNextCursor = opts.getNextCursor ?? defaultGetNextCursor;
|
|
230
238
|
const environment = opts.environment ?? void 0;
|
|
231
|
-
const { emit: emitDebug, mode: debugMode } = createDebugEmitter(
|
|
239
|
+
const { emit: emitDebug, mode: debugMode } = createDebugEmitter(
|
|
240
|
+
opts.debug,
|
|
241
|
+
environment
|
|
242
|
+
);
|
|
232
243
|
const isVerboseDebug = debugMode === "complete";
|
|
233
244
|
const decorateDebugEvent = (event, details) => {
|
|
234
245
|
if (!isVerboseDebug || !details) return event;
|
|
@@ -242,11 +253,12 @@ function createRouteClient(opts) {
|
|
|
242
253
|
function buildInternal(leaf, rqOpts, meta) {
|
|
243
254
|
const isGet = leaf.method === "get";
|
|
244
255
|
const isFeed = !!leaf.cfg.feed;
|
|
256
|
+
const rawLeafCfg = leaf.cfg;
|
|
245
257
|
const leafCfg = isFeed ? {
|
|
246
|
-
...
|
|
247
|
-
querySchema: augmentFeedQuerySchema(
|
|
248
|
-
outputSchema: augmentFeedOutputSchema(
|
|
249
|
-
} :
|
|
258
|
+
...rawLeafCfg,
|
|
259
|
+
querySchema: augmentFeedQuerySchema(rawLeafCfg.querySchema),
|
|
260
|
+
outputSchema: augmentFeedOutputSchema(rawLeafCfg.outputSchema)
|
|
261
|
+
} : rawLeafCfg;
|
|
250
262
|
const method = toUpper(leaf.method);
|
|
251
263
|
const expectsArgs = Boolean(leafCfg.paramsSchema || leafCfg.querySchema);
|
|
252
264
|
const leafLabel = `${leaf.method.toUpperCase()} ${String(leaf.path)}`;
|
|
@@ -302,9 +314,13 @@ function createRouteClient(opts) {
|
|
|
302
314
|
const acceptsBody = Boolean(leafCfg.bodySchema);
|
|
303
315
|
const requiresBody = options?.requireBody ?? (!isGet && acceptsBody);
|
|
304
316
|
if (typeof options?.body !== "undefined") {
|
|
305
|
-
const normalizedBody =
|
|
317
|
+
const normalizedBody = leafCfg.bodySchema ? (0, import_rrroutes_contract.lowProfileParse)(leafCfg.bodySchema, options.body) : void 0;
|
|
306
318
|
const isMultipart = Array.isArray(leafCfg.bodyFiles) && leafCfg.bodyFiles.length > 0;
|
|
307
|
-
|
|
319
|
+
if (isMultipart && normalizedBody && typeof normalizedBody === "object") {
|
|
320
|
+
payload = toFormData(normalizedBody);
|
|
321
|
+
} else {
|
|
322
|
+
payload = normalizedBody;
|
|
323
|
+
}
|
|
308
324
|
} else if (requiresBody) {
|
|
309
325
|
throw new Error("Body is required when invoking a mutation fetch.");
|
|
310
326
|
}
|
|
@@ -327,7 +343,7 @@ function createRouteClient(opts) {
|
|
|
327
343
|
const out = await fetcher(
|
|
328
344
|
payload === void 0 ? { url, method } : { url, method, body: payload }
|
|
329
345
|
);
|
|
330
|
-
const parsed =
|
|
346
|
+
const parsed = leafCfg.outputSchema ? (0, import_rrroutes_contract.lowProfileParse)(leafCfg.outputSchema, out) : void 0;
|
|
331
347
|
emit(
|
|
332
348
|
decorateDebugEvent(
|
|
333
349
|
{
|
|
@@ -338,7 +354,11 @@ function createRouteClient(opts) {
|
|
|
338
354
|
leaf: leafLabel,
|
|
339
355
|
durationMs: Date.now() - startedAt
|
|
340
356
|
},
|
|
341
|
-
isVerboseDebug ? {
|
|
357
|
+
isVerboseDebug ? {
|
|
358
|
+
params: normalizedParams,
|
|
359
|
+
query: normalizedQuery,
|
|
360
|
+
output: parsed
|
|
361
|
+
} : void 0
|
|
342
362
|
)
|
|
343
363
|
);
|
|
344
364
|
options?.onReceive?.(parsed);
|
|
@@ -369,7 +389,11 @@ function createRouteClient(opts) {
|
|
|
369
389
|
const hasBodyCandidate = acceptsBody && tupleLength > maybeBodyIndex;
|
|
370
390
|
const body = hasBodyCandidate ? tupleWithBody[tupleLength - 1] : void 0;
|
|
371
391
|
const tuple = hasBodyCandidate ? tupleWithBody.slice(0, tupleLength - 1) : tupleWithBody;
|
|
372
|
-
return fetchEndpoint(tuple, {
|
|
392
|
+
return fetchEndpoint(tuple, {
|
|
393
|
+
body,
|
|
394
|
+
onReceive: buildOnReceive,
|
|
395
|
+
requireBody: false
|
|
396
|
+
});
|
|
373
397
|
};
|
|
374
398
|
if (isGet && isFeed) {
|
|
375
399
|
const useEndpoint2 = (...useArgs) => {
|
|
@@ -380,13 +404,10 @@ function createRouteClient(opts) {
|
|
|
380
404
|
const query = args?.query;
|
|
381
405
|
const buildOptions = rqOpts ?? {};
|
|
382
406
|
const listenersRef = (0, import_react.useRef)(/* @__PURE__ */ new Set());
|
|
383
|
-
const notifyOnReceive = (0, import_react.useCallback)(
|
|
384
|
-
(data)
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
},
|
|
388
|
-
[]
|
|
389
|
-
);
|
|
407
|
+
const notifyOnReceive = (0, import_react.useCallback)((data) => {
|
|
408
|
+
buildOptions?.onReceive?.(data);
|
|
409
|
+
listenersRef.current.forEach((listener) => listener(data));
|
|
410
|
+
}, []);
|
|
390
411
|
const registerOnReceive = (0, import_react.useCallback)(
|
|
391
412
|
(listener) => {
|
|
392
413
|
listenersRef.current.add(listener);
|
|
@@ -402,24 +423,27 @@ function createRouteClient(opts) {
|
|
|
402
423
|
params,
|
|
403
424
|
query
|
|
404
425
|
);
|
|
405
|
-
const queryResult = (0, import_react_query.useInfiniteQuery)(
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
426
|
+
const queryResult = (0, import_react_query.useInfiniteQuery)(
|
|
427
|
+
{
|
|
428
|
+
...buildOptions,
|
|
429
|
+
queryKey: getQueryKeys(...tuple),
|
|
430
|
+
initialPageParam: void 0,
|
|
431
|
+
getNextPageParam: (lastPage) => getNextCursor(lastPage),
|
|
432
|
+
placeholderData: import_react_query.keepPreviousData,
|
|
433
|
+
queryFn: ({ pageParam }) => {
|
|
434
|
+
const pageQuery = {
|
|
435
|
+
...normalizedQuery,
|
|
436
|
+
...pageParam ? { [cursorParam]: pageParam } : {}
|
|
437
|
+
};
|
|
438
|
+
return fetchEndpoint(tuple, {
|
|
439
|
+
queryOverride: pageQuery,
|
|
440
|
+
onReceive: notifyOnReceive
|
|
441
|
+
});
|
|
442
|
+
}
|
|
443
|
+
// NOTE: TData is InfiniteData<T>, so we don't need a select here.
|
|
444
|
+
},
|
|
445
|
+
queryClient
|
|
446
|
+
);
|
|
423
447
|
return { ...queryResult, onReceive: registerOnReceive };
|
|
424
448
|
};
|
|
425
449
|
return {
|
|
@@ -439,13 +463,10 @@ function createRouteClient(opts) {
|
|
|
439
463
|
const query = args?.query;
|
|
440
464
|
const buildOptions = rqOpts ?? {};
|
|
441
465
|
const listenersRef = (0, import_react.useRef)(/* @__PURE__ */ new Set());
|
|
442
|
-
const notifyOnReceive = (0, import_react.useCallback)(
|
|
443
|
-
(data)
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
},
|
|
447
|
-
[]
|
|
448
|
-
);
|
|
466
|
+
const notifyOnReceive = (0, import_react.useCallback)((data) => {
|
|
467
|
+
buildOptions?.onReceive?.(data);
|
|
468
|
+
listenersRef.current.forEach((listener) => listener(data));
|
|
469
|
+
}, []);
|
|
449
470
|
const registerOnReceive = (0, import_react.useCallback)(
|
|
450
471
|
(listener) => {
|
|
451
472
|
listenersRef.current.add(listener);
|
|
@@ -456,14 +477,17 @@ function createRouteClient(opts) {
|
|
|
456
477
|
[]
|
|
457
478
|
);
|
|
458
479
|
buildUrl({ ...leaf, cfg: leafCfg }, baseUrl, params, query);
|
|
459
|
-
const queryResult = (0, import_react_query.useQuery)(
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
480
|
+
const queryResult = (0, import_react_query.useQuery)(
|
|
481
|
+
{
|
|
482
|
+
...buildOptions,
|
|
483
|
+
queryKey: getQueryKeys(...tuple),
|
|
484
|
+
placeholderData: import_react_query.keepPreviousData,
|
|
485
|
+
queryFn: () => fetchEndpoint(tuple, {
|
|
486
|
+
onReceive: notifyOnReceive
|
|
487
|
+
})
|
|
488
|
+
},
|
|
489
|
+
queryClient
|
|
490
|
+
);
|
|
467
491
|
return { ...queryResult, onReceive: registerOnReceive };
|
|
468
492
|
};
|
|
469
493
|
return {
|
|
@@ -497,21 +521,29 @@ function createRouteClient(opts) {
|
|
|
497
521
|
const notifyListeners = (0, import_react.useCallback)((data) => {
|
|
498
522
|
listenersRef.current.forEach((listener) => listener(data));
|
|
499
523
|
}, []);
|
|
500
|
-
const registerOnReceive = (0, import_react.useCallback)(
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
524
|
+
const registerOnReceive = (0, import_react.useCallback)(
|
|
525
|
+
(listener) => {
|
|
526
|
+
listenersRef.current.add(listener);
|
|
527
|
+
return () => {
|
|
528
|
+
listenersRef.current.delete(listener);
|
|
529
|
+
};
|
|
530
|
+
},
|
|
531
|
+
[]
|
|
532
|
+
);
|
|
533
|
+
const mutationResult = (0, import_react_query.useMutation)(
|
|
534
|
+
{
|
|
535
|
+
...mutationBuildOptions,
|
|
536
|
+
mutationKey: getQueryKeys(...tuple),
|
|
537
|
+
mutationFn: async (body) => {
|
|
538
|
+
const result = await fetchMutation(
|
|
539
|
+
...[...tuple, body]
|
|
540
|
+
);
|
|
541
|
+
notifyListeners(result);
|
|
542
|
+
return result;
|
|
543
|
+
}
|
|
544
|
+
},
|
|
545
|
+
queryClient
|
|
546
|
+
);
|
|
515
547
|
return { ...mutationResult, onReceive: registerOnReceive };
|
|
516
548
|
};
|
|
517
549
|
return {
|
|
@@ -530,13 +562,18 @@ function createRouteClient(opts) {
|
|
|
530
562
|
}
|
|
531
563
|
function buildRouter(routeClient, routes) {
|
|
532
564
|
const buildLeaf = routeClient.build;
|
|
533
|
-
return ((key, opts, meta) => buildLeaf(
|
|
565
|
+
return ((key, opts, meta) => buildLeaf(
|
|
566
|
+
routes[key],
|
|
567
|
+
opts,
|
|
568
|
+
meta
|
|
569
|
+
));
|
|
534
570
|
}
|
|
535
571
|
function toFormData(body) {
|
|
536
572
|
const fd = new FormData();
|
|
537
573
|
for (const [k, v] of Object.entries(body ?? {})) {
|
|
538
574
|
if (v == null) continue;
|
|
539
|
-
if (Array.isArray(v))
|
|
575
|
+
if (Array.isArray(v))
|
|
576
|
+
v.forEach((item, i) => fd.append(`${k}[${i}]`, item));
|
|
540
577
|
else fd.append(k, v);
|
|
541
578
|
}
|
|
542
579
|
return fd;
|
|
@@ -799,7 +836,21 @@ function roomsFromData(data, toRooms) {
|
|
|
799
836
|
if (data == null) return { rooms: [] };
|
|
800
837
|
let state = { rooms: [] };
|
|
801
838
|
const add = (input) => {
|
|
802
|
-
|
|
839
|
+
const mergeForValue = (value) => {
|
|
840
|
+
state = mergeRoomState(state, toRooms(value));
|
|
841
|
+
};
|
|
842
|
+
if (Array.isArray(input)) {
|
|
843
|
+
input.forEach((entry) => mergeForValue(entry));
|
|
844
|
+
return;
|
|
845
|
+
}
|
|
846
|
+
if (input && typeof input === "object") {
|
|
847
|
+
const maybeItems = input.items;
|
|
848
|
+
if (Array.isArray(maybeItems)) {
|
|
849
|
+
maybeItems.forEach((entry) => mergeForValue(entry));
|
|
850
|
+
return;
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
mergeForValue(input);
|
|
803
854
|
};
|
|
804
855
|
const maybePages = data?.pages;
|
|
805
856
|
if (Array.isArray(maybePages)) {
|
|
@@ -813,22 +864,34 @@ function buildSocketedRoute(options) {
|
|
|
813
864
|
const { built, toRooms, applySocket, useSocketClient: useSocketClient2 } = options;
|
|
814
865
|
return (...useArgs) => {
|
|
815
866
|
const client = useSocketClient2();
|
|
816
|
-
const endpointResult = built.useEndpoint(
|
|
867
|
+
const endpointResult = built.useEndpoint(
|
|
868
|
+
...useArgs
|
|
869
|
+
);
|
|
817
870
|
const argsKey = (0, import_react2.useMemo)(() => JSON.stringify(useArgs[0] ?? null), [useArgs]);
|
|
818
871
|
const [roomState, setRoomState] = (0, import_react2.useState)(
|
|
819
872
|
() => roomsFromData(endpointResult.data, toRooms)
|
|
820
873
|
);
|
|
821
874
|
const roomsKey = (0, import_react2.useMemo)(() => roomState.rooms.join("|"), [roomState.rooms]);
|
|
822
|
-
const joinMetaKey = (0, import_react2.useMemo)(
|
|
823
|
-
|
|
875
|
+
const joinMetaKey = (0, import_react2.useMemo)(
|
|
876
|
+
() => JSON.stringify(roomState.joinMeta ?? null),
|
|
877
|
+
[roomState.joinMeta]
|
|
878
|
+
);
|
|
879
|
+
const leaveMetaKey = (0, import_react2.useMemo)(
|
|
880
|
+
() => JSON.stringify(roomState.leaveMeta ?? null),
|
|
881
|
+
[roomState.leaveMeta]
|
|
882
|
+
);
|
|
824
883
|
(0, import_react2.useEffect)(() => {
|
|
825
884
|
const unsubscribe = endpointResult.onReceive((data) => {
|
|
826
|
-
setRoomState(
|
|
885
|
+
setRoomState(
|
|
886
|
+
(prev) => mergeRoomState(prev, toRooms(data))
|
|
887
|
+
);
|
|
827
888
|
});
|
|
828
889
|
return unsubscribe;
|
|
829
890
|
}, [endpointResult, toRooms]);
|
|
830
891
|
(0, import_react2.useEffect)(() => {
|
|
831
|
-
setRoomState(
|
|
892
|
+
setRoomState(
|
|
893
|
+
roomsFromData(endpointResult.data, toRooms)
|
|
894
|
+
);
|
|
832
895
|
}, [endpointResult.data, toRooms]);
|
|
833
896
|
(0, import_react2.useEffect)(() => {
|
|
834
897
|
if (roomState.rooms.length === 0) return;
|
|
@@ -847,7 +910,14 @@ function buildSocketedRoute(options) {
|
|
|
847
910
|
void client.leaveRooms(roomState.rooms, leaveMeta).catch(() => {
|
|
848
911
|
});
|
|
849
912
|
};
|
|
850
|
-
}, [
|
|
913
|
+
}, [
|
|
914
|
+
client,
|
|
915
|
+
roomsKey,
|
|
916
|
+
roomState.joinMeta,
|
|
917
|
+
roomState.leaveMeta,
|
|
918
|
+
joinMetaKey,
|
|
919
|
+
leaveMetaKey
|
|
920
|
+
]);
|
|
851
921
|
(0, import_react2.useEffect)(() => {
|
|
852
922
|
const entries = Object.entries(applySocket).filter(
|
|
853
923
|
([_event, fn]) => typeof fn === "function"
|
|
@@ -856,7 +926,9 @@ function buildSocketedRoute(options) {
|
|
|
856
926
|
([ev, fn]) => client.on(ev, (payload, meta) => {
|
|
857
927
|
built.setData((prev) => {
|
|
858
928
|
const next = fn(prev, payload, meta);
|
|
859
|
-
setRoomState(
|
|
929
|
+
setRoomState(
|
|
930
|
+
roomsFromData(next, toRooms)
|
|
931
|
+
);
|
|
860
932
|
return next;
|
|
861
933
|
}, ...useArgs);
|
|
862
934
|
})
|
|
@@ -905,7 +977,11 @@ var SocketClient = class {
|
|
|
905
977
|
}
|
|
906
978
|
this.onConnect = async () => {
|
|
907
979
|
if (!this.socket) {
|
|
908
|
-
this.dbg({
|
|
980
|
+
this.dbg({
|
|
981
|
+
type: "connection",
|
|
982
|
+
phase: "connect_event",
|
|
983
|
+
err: "Socket is null"
|
|
984
|
+
});
|
|
909
985
|
throw new Error("Socket is null in onConnect handler");
|
|
910
986
|
}
|
|
911
987
|
this.dbg({
|
|
@@ -924,7 +1000,11 @@ var SocketClient = class {
|
|
|
924
1000
|
};
|
|
925
1001
|
this.onReconnect = async (attempt) => {
|
|
926
1002
|
if (!this.socket) {
|
|
927
|
-
this.dbg({
|
|
1003
|
+
this.dbg({
|
|
1004
|
+
type: "connection",
|
|
1005
|
+
phase: "reconnect_event",
|
|
1006
|
+
err: "Socket is null"
|
|
1007
|
+
});
|
|
928
1008
|
throw new Error("Socket is null in onReconnect handler");
|
|
929
1009
|
}
|
|
930
1010
|
this.dbg({
|
|
@@ -945,7 +1025,11 @@ var SocketClient = class {
|
|
|
945
1025
|
};
|
|
946
1026
|
this.onDisconnect = async (reason) => {
|
|
947
1027
|
if (!this.socket) {
|
|
948
|
-
this.dbg({
|
|
1028
|
+
this.dbg({
|
|
1029
|
+
type: "connection",
|
|
1030
|
+
phase: "disconnect_event",
|
|
1031
|
+
err: "Socket is null"
|
|
1032
|
+
});
|
|
949
1033
|
throw new Error("Socket is null in onDisconnect handler");
|
|
950
1034
|
}
|
|
951
1035
|
this.dbg({
|
|
@@ -965,7 +1049,11 @@ var SocketClient = class {
|
|
|
965
1049
|
};
|
|
966
1050
|
this.onConnectError = async (err) => {
|
|
967
1051
|
if (!this.socket) {
|
|
968
|
-
this.dbg({
|
|
1052
|
+
this.dbg({
|
|
1053
|
+
type: "connection",
|
|
1054
|
+
phase: "connect_error_event",
|
|
1055
|
+
err: "Socket is null"
|
|
1056
|
+
});
|
|
969
1057
|
throw new Error("Socket is null in onConnectError handler");
|
|
970
1058
|
}
|
|
971
1059
|
this.dbg({
|
|
@@ -983,7 +1071,11 @@ var SocketClient = class {
|
|
|
983
1071
|
};
|
|
984
1072
|
this.onPong = async (raw) => {
|
|
985
1073
|
if (!this.socket) {
|
|
986
|
-
this.dbg({
|
|
1074
|
+
this.dbg({
|
|
1075
|
+
type: "heartbeat",
|
|
1076
|
+
phase: "pong_recv",
|
|
1077
|
+
err: "Socket is null"
|
|
1078
|
+
});
|
|
987
1079
|
throw new Error("Socket is null in onPong handler");
|
|
988
1080
|
}
|
|
989
1081
|
const parsed = this.config.pongPayload.safeParse(raw);
|
|
@@ -1083,11 +1175,15 @@ var SocketClient = class {
|
|
|
1083
1175
|
}
|
|
1084
1176
|
/** internal stats snapshot */
|
|
1085
1177
|
stats() {
|
|
1086
|
-
const rooms = Array.from(this.roomCounts.entries()).map(
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1178
|
+
const rooms = Array.from(this.roomCounts.entries()).map(
|
|
1179
|
+
([room, count]) => ({ room, count })
|
|
1180
|
+
);
|
|
1181
|
+
const handlers = Array.from(this.handlerMap.entries()).map(
|
|
1182
|
+
([event, set]) => ({
|
|
1183
|
+
event,
|
|
1184
|
+
handlers: set.size
|
|
1185
|
+
})
|
|
1186
|
+
);
|
|
1091
1187
|
return {
|
|
1092
1188
|
roomsCount: rooms.length,
|
|
1093
1189
|
totalHandlers: handlers.reduce((a, b) => a + b.handlers, 0),
|
|
@@ -1159,7 +1255,10 @@ var SocketClient = class {
|
|
|
1159
1255
|
details: this.getValidationDetails(check.error)
|
|
1160
1256
|
});
|
|
1161
1257
|
if (this.environment === "development") {
|
|
1162
|
-
console.warn(
|
|
1258
|
+
console.warn(
|
|
1259
|
+
"[socket] ping schema validation failed",
|
|
1260
|
+
check.error.issues
|
|
1261
|
+
);
|
|
1163
1262
|
}
|
|
1164
1263
|
return;
|
|
1165
1264
|
}
|
|
@@ -1218,7 +1317,12 @@ var SocketClient = class {
|
|
|
1218
1317
|
}
|
|
1219
1318
|
async joinRooms(rooms, meta) {
|
|
1220
1319
|
if (!this.socket) {
|
|
1221
|
-
this.dbg({
|
|
1320
|
+
this.dbg({
|
|
1321
|
+
type: "room",
|
|
1322
|
+
phase: "join",
|
|
1323
|
+
rooms: this.toArray(rooms),
|
|
1324
|
+
err: "Socket is null"
|
|
1325
|
+
});
|
|
1222
1326
|
throw new Error("Socket is null in joinRooms method");
|
|
1223
1327
|
}
|
|
1224
1328
|
if (!await this.getSysEvent("sys:room_join")({
|
|
@@ -1271,7 +1375,12 @@ var SocketClient = class {
|
|
|
1271
1375
|
}
|
|
1272
1376
|
async leaveRooms(rooms, meta) {
|
|
1273
1377
|
if (!this.socket) {
|
|
1274
|
-
this.dbg({
|
|
1378
|
+
this.dbg({
|
|
1379
|
+
type: "room",
|
|
1380
|
+
phase: "leave",
|
|
1381
|
+
rooms: this.toArray(rooms),
|
|
1382
|
+
err: "Socket is null"
|
|
1383
|
+
});
|
|
1275
1384
|
throw new Error("Socket is null in leaveRooms method");
|
|
1276
1385
|
}
|
|
1277
1386
|
if (!await this.getSysEvent("sys:room_leave")({
|
|
@@ -1323,7 +1432,12 @@ var SocketClient = class {
|
|
|
1323
1432
|
const schema = this.events[event].message;
|
|
1324
1433
|
this.dbg({ type: "register", phase: "register", event });
|
|
1325
1434
|
if (!this.socket) {
|
|
1326
|
-
this.dbg({
|
|
1435
|
+
this.dbg({
|
|
1436
|
+
type: "register",
|
|
1437
|
+
phase: "register",
|
|
1438
|
+
event,
|
|
1439
|
+
err: "Socket is null"
|
|
1440
|
+
});
|
|
1327
1441
|
return () => {
|
|
1328
1442
|
};
|
|
1329
1443
|
}
|