@emeryld/rrroutes-client 2.2.7 → 2.2.9
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 +143 -26
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +142 -26
- package/dist/index.mjs.map +1 -1
- package/dist/routesV3.client.types.d.ts +11 -10
- package/dist/sockets/socket.client.index.d.ts +1 -0
- package/dist/sockets/socketedRoute/socket.client.helper.d.ts +28 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -35,6 +35,7 @@ __export(index_exports, {
|
|
|
35
35
|
buildRoomPayloadSchema: () => buildRoomPayloadSchema,
|
|
36
36
|
buildRouter: () => buildRouter,
|
|
37
37
|
buildSocketProvider: () => buildSocketProvider,
|
|
38
|
+
buildSocketedRoute: () => buildSocketedRoute,
|
|
38
39
|
createRouteClient: () => createRouteClient,
|
|
39
40
|
defaultFetcher: () => defaultFetcher,
|
|
40
41
|
useSocketClient: () => useSocketClient,
|
|
@@ -68,19 +69,9 @@ var defaultFetcher = async (req) => {
|
|
|
68
69
|
};
|
|
69
70
|
|
|
70
71
|
// src/routesV3.client.index.ts
|
|
72
|
+
var import_react = require("react");
|
|
71
73
|
var import_react_query = require("@tanstack/react-query");
|
|
72
74
|
var import_rrroutes_contract = require("@emeryld/rrroutes-contract");
|
|
73
|
-
function splitUseEndpointArgs(useArgs, expectsArgs) {
|
|
74
|
-
if (useArgs.length === 0) return { args: void 0, options: void 0 };
|
|
75
|
-
if (!expectsArgs) {
|
|
76
|
-
return { args: void 0, options: useArgs[0] };
|
|
77
|
-
}
|
|
78
|
-
const [maybeArgs, maybeOptions] = useArgs;
|
|
79
|
-
return {
|
|
80
|
-
args: maybeArgs,
|
|
81
|
-
options: useArgs.length > 1 ? maybeOptions : void 0
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
75
|
var toUpper = (m) => m.toUpperCase();
|
|
85
76
|
function zParse(value, schema) {
|
|
86
77
|
return schema ? schema.parse(value) : value;
|
|
@@ -332,14 +323,31 @@ function createRouteClient(opts) {
|
|
|
332
323
|
};
|
|
333
324
|
if (isGet && isFeed) {
|
|
334
325
|
const useEndpoint2 = (...useArgs) => {
|
|
335
|
-
const
|
|
326
|
+
const args = useArgs[0];
|
|
336
327
|
emit({ type: "useEndpoint", leaf: leafLabel, variant: "infiniteGet" });
|
|
337
328
|
const tuple = toArgsTuple(args);
|
|
338
329
|
const params = args?.params;
|
|
339
330
|
const query = args?.query;
|
|
340
331
|
const buildOptions = rqOpts ?? {};
|
|
332
|
+
const listenersRef = (0, import_react.useRef)(/* @__PURE__ */ new Set());
|
|
333
|
+
const notifyOnReceive = (0, import_react.useCallback)(
|
|
334
|
+
(data) => {
|
|
335
|
+
buildOptions?.onReceive?.(data);
|
|
336
|
+
listenersRef.current.forEach((listener) => listener(data));
|
|
337
|
+
},
|
|
338
|
+
[]
|
|
339
|
+
);
|
|
340
|
+
const registerOnReceive = (0, import_react.useCallback)(
|
|
341
|
+
(listener) => {
|
|
342
|
+
listenersRef.current.add(listener);
|
|
343
|
+
return () => {
|
|
344
|
+
listenersRef.current.delete(listener);
|
|
345
|
+
};
|
|
346
|
+
},
|
|
347
|
+
[]
|
|
348
|
+
);
|
|
341
349
|
const { normalizedQuery, normalizedParams } = buildUrl(leaf, baseUrl, params, query);
|
|
342
|
-
|
|
350
|
+
const queryResult = (0, import_react_query.useInfiniteQuery)({
|
|
343
351
|
...buildOptions,
|
|
344
352
|
queryKey: getQueryKeys(...tuple),
|
|
345
353
|
initialPageParam: void 0,
|
|
@@ -352,14 +360,12 @@ function createRouteClient(opts) {
|
|
|
352
360
|
};
|
|
353
361
|
return fetchEndpoint(tuple, {
|
|
354
362
|
queryOverride: pageQuery,
|
|
355
|
-
onReceive:
|
|
356
|
-
buildOptions?.onReceive?.(data);
|
|
357
|
-
options?.onReceive?.(data);
|
|
358
|
-
}
|
|
363
|
+
onReceive: notifyOnReceive
|
|
359
364
|
});
|
|
360
365
|
}
|
|
361
366
|
// NOTE: TData is InfiniteData<T>, so we don't need a select here.
|
|
362
367
|
}, queryClient);
|
|
368
|
+
return { ...queryResult, onReceive: registerOnReceive };
|
|
363
369
|
};
|
|
364
370
|
return {
|
|
365
371
|
getQueryKeys,
|
|
@@ -371,24 +377,39 @@ function createRouteClient(opts) {
|
|
|
371
377
|
}
|
|
372
378
|
if (isGet) {
|
|
373
379
|
const useEndpoint2 = (...useArgs) => {
|
|
374
|
-
const
|
|
380
|
+
const args = useArgs[0];
|
|
375
381
|
emit({ type: "useEndpoint", leaf: leafLabel, variant: "get" });
|
|
376
382
|
const tuple = toArgsTuple(args);
|
|
377
383
|
const params = args?.params;
|
|
378
384
|
const query = args?.query;
|
|
379
385
|
const buildOptions = rqOpts ?? {};
|
|
386
|
+
const listenersRef = (0, import_react.useRef)(/* @__PURE__ */ new Set());
|
|
387
|
+
const notifyOnReceive = (0, import_react.useCallback)(
|
|
388
|
+
(data) => {
|
|
389
|
+
buildOptions?.onReceive?.(data);
|
|
390
|
+
listenersRef.current.forEach((listener) => listener(data));
|
|
391
|
+
},
|
|
392
|
+
[]
|
|
393
|
+
);
|
|
394
|
+
const registerOnReceive = (0, import_react.useCallback)(
|
|
395
|
+
(listener) => {
|
|
396
|
+
listenersRef.current.add(listener);
|
|
397
|
+
return () => {
|
|
398
|
+
listenersRef.current.delete(listener);
|
|
399
|
+
};
|
|
400
|
+
},
|
|
401
|
+
[]
|
|
402
|
+
);
|
|
380
403
|
buildUrl(leaf, baseUrl, params, query);
|
|
381
|
-
|
|
404
|
+
const queryResult = (0, import_react_query.useQuery)({
|
|
382
405
|
...buildOptions,
|
|
383
406
|
queryKey: getQueryKeys(...tuple),
|
|
384
407
|
placeholderData: import_react_query.keepPreviousData,
|
|
385
408
|
queryFn: () => fetchEndpoint(tuple, {
|
|
386
|
-
onReceive:
|
|
387
|
-
buildOptions?.onReceive?.(data);
|
|
388
|
-
options?.onReceive?.(data);
|
|
389
|
-
}
|
|
409
|
+
onReceive: notifyOnReceive
|
|
390
410
|
})
|
|
391
411
|
}, queryClient);
|
|
412
|
+
return { ...queryResult, onReceive: registerOnReceive };
|
|
392
413
|
};
|
|
393
414
|
return {
|
|
394
415
|
getQueryKeys,
|
|
@@ -414,18 +435,29 @@ function createRouteClient(opts) {
|
|
|
414
435
|
return result;
|
|
415
436
|
};
|
|
416
437
|
const useEndpoint = (...useArgs) => {
|
|
417
|
-
const
|
|
438
|
+
const args = useArgs[0];
|
|
418
439
|
emit({ type: "useEndpoint", leaf: leafLabel, variant: "mutation" });
|
|
419
440
|
const tuple = toArgsTuple(args);
|
|
420
|
-
|
|
441
|
+
const listenersRef = (0, import_react.useRef)(/* @__PURE__ */ new Set());
|
|
442
|
+
const notifyListeners = (0, import_react.useCallback)((data) => {
|
|
443
|
+
listenersRef.current.forEach((listener) => listener(data));
|
|
444
|
+
}, []);
|
|
445
|
+
const registerOnReceive = (0, import_react.useCallback)((listener) => {
|
|
446
|
+
listenersRef.current.add(listener);
|
|
447
|
+
return () => {
|
|
448
|
+
listenersRef.current.delete(listener);
|
|
449
|
+
};
|
|
450
|
+
}, []);
|
|
451
|
+
const mutationResult = (0, import_react_query.useMutation)({
|
|
421
452
|
...mutationBuildOptions,
|
|
422
453
|
mutationKey: getQueryKeys(...tuple),
|
|
423
454
|
mutationFn: async (body) => {
|
|
424
455
|
const result = await fetchMutation(...[...tuple, body]);
|
|
425
|
-
|
|
456
|
+
notifyListeners(result);
|
|
426
457
|
return result;
|
|
427
458
|
}
|
|
428
459
|
}, queryClient);
|
|
460
|
+
return { ...mutationResult, onReceive: registerOnReceive };
|
|
429
461
|
};
|
|
430
462
|
return {
|
|
431
463
|
getQueryKeys,
|
|
@@ -684,6 +716,90 @@ function useSocketConnection(args) {
|
|
|
684
716
|
}, [client, event, onMessage, autoJoin, autoLeave, ...normalizedRooms]);
|
|
685
717
|
}
|
|
686
718
|
|
|
719
|
+
// src/sockets/socketedRoute/socket.client.helper.ts
|
|
720
|
+
var import_react2 = require("react");
|
|
721
|
+
function normalizeRooms(rooms) {
|
|
722
|
+
if (rooms == null) return [];
|
|
723
|
+
const list = Array.isArray(rooms) ? rooms : [rooms];
|
|
724
|
+
const seen = /* @__PURE__ */ new Set();
|
|
725
|
+
const normalized = [];
|
|
726
|
+
for (const r of list) {
|
|
727
|
+
if (typeof r !== "string") continue;
|
|
728
|
+
if (seen.has(r)) continue;
|
|
729
|
+
seen.add(r);
|
|
730
|
+
normalized.push(r);
|
|
731
|
+
}
|
|
732
|
+
return normalized;
|
|
733
|
+
}
|
|
734
|
+
function roomsFromData(data, toRooms) {
|
|
735
|
+
if (data == null) return [];
|
|
736
|
+
const merge = /* @__PURE__ */ new Set();
|
|
737
|
+
const add = (input) => {
|
|
738
|
+
for (const r of normalizeRooms(input)) merge.add(r);
|
|
739
|
+
};
|
|
740
|
+
const maybePages = data?.pages;
|
|
741
|
+
if (Array.isArray(maybePages)) {
|
|
742
|
+
for (const page of maybePages) add(toRooms(page));
|
|
743
|
+
return Array.from(merge);
|
|
744
|
+
}
|
|
745
|
+
add(toRooms(data));
|
|
746
|
+
return Array.from(merge);
|
|
747
|
+
}
|
|
748
|
+
function buildSocketedRoute(options) {
|
|
749
|
+
const { built, event, toRooms, applyMessage, joinMeta, leaveMeta, autoJoin = true, autoLeave = true } = options;
|
|
750
|
+
return (...useArgs) => {
|
|
751
|
+
const client = useSocketClient();
|
|
752
|
+
const endpointResult = built.useEndpoint(...useArgs);
|
|
753
|
+
const argsKey = (0, import_react2.useMemo)(() => JSON.stringify(useArgs[0] ?? null), [useArgs]);
|
|
754
|
+
const [rooms, setRooms] = (0, import_react2.useState)(
|
|
755
|
+
() => roomsFromData(endpointResult.data, toRooms)
|
|
756
|
+
);
|
|
757
|
+
const roomsKey = (0, import_react2.useMemo)(() => rooms.join("|"), [rooms]);
|
|
758
|
+
(0, import_react2.useEffect)(() => {
|
|
759
|
+
const unsubscribe = endpointResult.onReceive((data) => {
|
|
760
|
+
setRooms((prev) => {
|
|
761
|
+
const next = normalizeRooms(toRooms(data));
|
|
762
|
+
if (next.length === 0) return prev;
|
|
763
|
+
const merged = new Set(prev);
|
|
764
|
+
next.forEach((r) => merged.add(r));
|
|
765
|
+
return Array.from(merged);
|
|
766
|
+
});
|
|
767
|
+
});
|
|
768
|
+
return unsubscribe;
|
|
769
|
+
}, [endpointResult, toRooms]);
|
|
770
|
+
(0, import_react2.useEffect)(() => {
|
|
771
|
+
setRooms(roomsFromData(endpointResult.data, toRooms));
|
|
772
|
+
}, [endpointResult.data, toRooms]);
|
|
773
|
+
(0, import_react2.useEffect)(() => {
|
|
774
|
+
if (!autoJoin || rooms.length === 0) return;
|
|
775
|
+
let active = true;
|
|
776
|
+
(async () => {
|
|
777
|
+
try {
|
|
778
|
+
await client.joinRooms(rooms, joinMeta);
|
|
779
|
+
} catch {
|
|
780
|
+
}
|
|
781
|
+
})();
|
|
782
|
+
return () => {
|
|
783
|
+
if (!active || !autoLeave || rooms.length === 0) return;
|
|
784
|
+
active = false;
|
|
785
|
+
void client.leaveRooms(rooms, leaveMeta).catch(() => {
|
|
786
|
+
});
|
|
787
|
+
};
|
|
788
|
+
}, [client, joinMeta, leaveMeta, autoJoin, autoLeave, roomsKey]);
|
|
789
|
+
(0, import_react2.useEffect)(() => {
|
|
790
|
+
const unsubscribe = client.on(event, (payload, meta) => {
|
|
791
|
+
built.setData((prev) => {
|
|
792
|
+
const next = applyMessage(prev, payload, meta);
|
|
793
|
+
setRooms(roomsFromData(next, toRooms));
|
|
794
|
+
return next;
|
|
795
|
+
}, ...useArgs);
|
|
796
|
+
});
|
|
797
|
+
return unsubscribe;
|
|
798
|
+
}, [client, event, applyMessage, built, argsKey]);
|
|
799
|
+
return { ...endpointResult, rooms };
|
|
800
|
+
};
|
|
801
|
+
}
|
|
802
|
+
|
|
687
803
|
// src/sockets/socket.client.index.ts
|
|
688
804
|
var SocketClient = class {
|
|
689
805
|
constructor(events, opts) {
|
|
@@ -1306,6 +1422,7 @@ var SocketClient = class {
|
|
|
1306
1422
|
buildRoomPayloadSchema,
|
|
1307
1423
|
buildRouter,
|
|
1308
1424
|
buildSocketProvider,
|
|
1425
|
+
buildSocketedRoute,
|
|
1309
1426
|
createRouteClient,
|
|
1310
1427
|
defaultFetcher,
|
|
1311
1428
|
useSocketClient,
|