@emeryld/rrroutes-client 2.2.6 → 2.2.8

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 CHANGED
@@ -36,7 +36,6 @@ __export(index_exports, {
36
36
  buildRouter: () => buildRouter,
37
37
  buildSocketProvider: () => buildSocketProvider,
38
38
  createRouteClient: () => createRouteClient,
39
- createSocketedRouteHook: () => createSocketedRouteHook,
40
39
  defaultFetcher: () => defaultFetcher,
41
40
  useSocketClient: () => useSocketClient,
42
41
  useSocketConnection: () => useSocketConnection
@@ -69,19 +68,9 @@ var defaultFetcher = async (req) => {
69
68
  };
70
69
 
71
70
  // src/routesV3.client.index.ts
71
+ var import_react = require("react");
72
72
  var import_react_query = require("@tanstack/react-query");
73
73
  var import_rrroutes_contract = require("@emeryld/rrroutes-contract");
74
- function splitUseEndpointArgs(useArgs, expectsArgs) {
75
- if (useArgs.length === 0) return { args: void 0, options: void 0 };
76
- if (!expectsArgs) {
77
- return { args: void 0, options: useArgs[0] };
78
- }
79
- const [maybeArgs, maybeOptions] = useArgs;
80
- return {
81
- args: maybeArgs,
82
- options: useArgs.length > 1 ? maybeOptions : void 0
83
- };
84
- }
85
74
  var toUpper = (m) => m.toUpperCase();
86
75
  function zParse(value, schema) {
87
76
  return schema ? schema.parse(value) : value;
@@ -333,14 +322,31 @@ function createRouteClient(opts) {
333
322
  };
334
323
  if (isGet && isFeed) {
335
324
  const useEndpoint2 = (...useArgs) => {
336
- const { args, options } = splitUseEndpointArgs(useArgs, expectsArgs);
325
+ const args = useArgs[0];
337
326
  emit({ type: "useEndpoint", leaf: leafLabel, variant: "infiniteGet" });
338
327
  const tuple = toArgsTuple(args);
339
328
  const params = args?.params;
340
329
  const query = args?.query;
341
330
  const buildOptions = rqOpts ?? {};
331
+ const listenersRef = (0, import_react.useRef)(/* @__PURE__ */ new Set());
332
+ const notifyOnReceive = (0, import_react.useCallback)(
333
+ (data) => {
334
+ buildOptions?.onReceive?.(data);
335
+ listenersRef.current.forEach((listener) => listener(data));
336
+ },
337
+ []
338
+ );
339
+ const registerOnReceive = (0, import_react.useCallback)(
340
+ (listener) => {
341
+ listenersRef.current.add(listener);
342
+ return () => {
343
+ listenersRef.current.delete(listener);
344
+ };
345
+ },
346
+ []
347
+ );
342
348
  const { normalizedQuery, normalizedParams } = buildUrl(leaf, baseUrl, params, query);
343
- return (0, import_react_query.useInfiniteQuery)({
349
+ const queryResult = (0, import_react_query.useInfiniteQuery)({
344
350
  ...buildOptions,
345
351
  queryKey: getQueryKeys(...tuple),
346
352
  initialPageParam: void 0,
@@ -353,14 +359,12 @@ function createRouteClient(opts) {
353
359
  };
354
360
  return fetchEndpoint(tuple, {
355
361
  queryOverride: pageQuery,
356
- onReceive: (data) => {
357
- buildOptions?.onReceive?.(data);
358
- options?.onReceive?.(data);
359
- }
362
+ onReceive: notifyOnReceive
360
363
  });
361
364
  }
362
365
  // NOTE: TData is InfiniteData<T>, so we don't need a select here.
363
366
  }, queryClient);
367
+ return { ...queryResult, onReceive: registerOnReceive };
364
368
  };
365
369
  return {
366
370
  getQueryKeys,
@@ -372,24 +376,39 @@ function createRouteClient(opts) {
372
376
  }
373
377
  if (isGet) {
374
378
  const useEndpoint2 = (...useArgs) => {
375
- const { args, options } = splitUseEndpointArgs(useArgs, expectsArgs);
379
+ const args = useArgs[0];
376
380
  emit({ type: "useEndpoint", leaf: leafLabel, variant: "get" });
377
381
  const tuple = toArgsTuple(args);
378
382
  const params = args?.params;
379
383
  const query = args?.query;
380
384
  const buildOptions = rqOpts ?? {};
385
+ const listenersRef = (0, import_react.useRef)(/* @__PURE__ */ new Set());
386
+ const notifyOnReceive = (0, import_react.useCallback)(
387
+ (data) => {
388
+ buildOptions?.onReceive?.(data);
389
+ listenersRef.current.forEach((listener) => listener(data));
390
+ },
391
+ []
392
+ );
393
+ const registerOnReceive = (0, import_react.useCallback)(
394
+ (listener) => {
395
+ listenersRef.current.add(listener);
396
+ return () => {
397
+ listenersRef.current.delete(listener);
398
+ };
399
+ },
400
+ []
401
+ );
381
402
  buildUrl(leaf, baseUrl, params, query);
382
- return (0, import_react_query.useQuery)({
403
+ const queryResult = (0, import_react_query.useQuery)({
383
404
  ...buildOptions,
384
405
  queryKey: getQueryKeys(...tuple),
385
406
  placeholderData: import_react_query.keepPreviousData,
386
407
  queryFn: () => fetchEndpoint(tuple, {
387
- onReceive: (data) => {
388
- buildOptions?.onReceive?.(data);
389
- options?.onReceive?.(data);
390
- }
408
+ onReceive: notifyOnReceive
391
409
  })
392
410
  }, queryClient);
411
+ return { ...queryResult, onReceive: registerOnReceive };
393
412
  };
394
413
  return {
395
414
  getQueryKeys,
@@ -415,18 +434,29 @@ function createRouteClient(opts) {
415
434
  return result;
416
435
  };
417
436
  const useEndpoint = (...useArgs) => {
418
- const { args, options } = splitUseEndpointArgs(useArgs, expectsArgs);
437
+ const args = useArgs[0];
419
438
  emit({ type: "useEndpoint", leaf: leafLabel, variant: "mutation" });
420
439
  const tuple = toArgsTuple(args);
421
- return (0, import_react_query.useMutation)({
440
+ const listenersRef = (0, import_react.useRef)(/* @__PURE__ */ new Set());
441
+ const notifyListeners = (0, import_react.useCallback)((data) => {
442
+ listenersRef.current.forEach((listener) => listener(data));
443
+ }, []);
444
+ const registerOnReceive = (0, import_react.useCallback)((listener) => {
445
+ listenersRef.current.add(listener);
446
+ return () => {
447
+ listenersRef.current.delete(listener);
448
+ };
449
+ }, []);
450
+ const mutationResult = (0, import_react_query.useMutation)({
422
451
  ...mutationBuildOptions,
423
452
  mutationKey: getQueryKeys(...tuple),
424
453
  mutationFn: async (body) => {
425
454
  const result = await fetchMutation(...[...tuple, body]);
426
- options?.onReceive?.(result);
455
+ notifyListeners(result);
427
456
  return result;
428
457
  }
429
458
  }, queryClient);
459
+ return { ...mutationResult, onReceive: registerOnReceive };
430
460
  };
431
461
  return {
432
462
  getQueryKeys,
@@ -685,271 +715,6 @@ function useSocketConnection(args) {
685
715
  }, [client, event, onMessage, autoJoin, autoLeave, ...normalizedRooms]);
686
716
  }
687
717
 
688
- // src/sockets/socketedRoute/socket.client.helper.ts
689
- var import_react = require("react");
690
- function createSocketedRouteHook(args) {
691
- const { buildRoute, useClient = () => useSocketClient() } = args;
692
- return function useSocketedRoute(params) {
693
- const { routeKey, socketEvent, handlers, buildOptions, buildMeta, debug, useOptions } = params;
694
- const renderRef = (0, import_react.useRef)(0);
695
- const prevInputsRef = (0, import_react.useRef)();
696
- const debugName = buildMeta?.name;
697
- const render = ++renderRef.current;
698
- const renderChanged = [];
699
- const prevInputs = prevInputsRef.current;
700
- if (prevInputs) {
701
- if (!Object.is(prevInputs.routeKey, routeKey)) renderChanged.push("routeKey");
702
- if (!Object.is(prevInputs.socketEvent, socketEvent)) renderChanged.push("socketEvent");
703
- if (!Object.is(prevInputs.buildOptions, buildOptions)) renderChanged.push("buildOptions");
704
- if (!Object.is(prevInputs.buildMeta, buildMeta)) renderChanged.push("buildMeta");
705
- if (!Object.is(prevInputs.debug, debug)) renderChanged.push("debug");
706
- if (!Object.is(prevInputs.args, useOptions?.args)) renderChanged.push("args");
707
- if (!Object.is(prevInputs.options, useOptions?.options)) renderChanged.push("options");
708
- }
709
- prevInputsRef.current = {
710
- routeKey,
711
- socketEvent,
712
- buildOptions,
713
- buildMeta,
714
- debug,
715
- args: useOptions?.args,
716
- options: useOptions?.options
717
- };
718
- const debugRef = (0, import_react.useRef)(debug);
719
- (0, import_react.useEffect)(() => {
720
- debugRef.current = debug;
721
- }, [debug]);
722
- const emitDebug = (0, import_react.useCallback)(
723
- (event) => {
724
- const d = debugRef.current;
725
- if (!d?.logger) return;
726
- if (!d[event.type]) return;
727
- const name = event.name ?? debugName;
728
- if (d.only && name && !d.only.includes(name)) return;
729
- d.logger({ ...event, name });
730
- },
731
- [debugName]
732
- );
733
- const verboseRef = (0, import_react.useRef)(!!debug?.verbose);
734
- (0, import_react.useEffect)(() => {
735
- verboseRef.current = !!debug?.verbose;
736
- }, [debug]);
737
- const handlersRef = (0, import_react.useRef)(handlers);
738
- (0, import_react.useEffect)(() => {
739
- handlersRef.current = handlers;
740
- }, [handlers]);
741
- const endpoint = (0, import_react.useMemo)(
742
- () => buildRoute(routeKey, buildOptions, buildMeta),
743
- [buildRoute, routeKey, buildOptions, buildMeta]
744
- );
745
- (0, import_react.useEffect)(() => {
746
- emitDebug({
747
- type: "build",
748
- routeKey,
749
- socketEvent,
750
- options: verboseRef.current ? { buildOptions, buildMeta, useOptions } : void 0
751
- });
752
- }, [emitDebug, routeKey, socketEvent, buildOptions, buildMeta, useOptions]);
753
- const client = useClient();
754
- const [rooms, setRooms] = (0, import_react.useState)([]);
755
- const roomsKey = rooms.slice().sort().join("|");
756
- const roomsRef = (0, import_react.useRef)([]);
757
- roomsRef.current = rooms;
758
- const prevRoomsKeyRef = (0, import_react.useRef)(roomsKey);
759
- const prevClientRef = (0, import_react.useRef)(client);
760
- const prevRouteKeyRef = (0, import_react.useRef)(routeKey);
761
- const prevSocketEventRef = (0, import_react.useRef)(socketEvent);
762
- const prevSubscribeDepsRef = (0, import_react.useRef)({
763
- client,
764
- socketEvent,
765
- routeArgs: useOptions?.args,
766
- routeKey
767
- });
768
- (0, import_react.useEffect)(() => {
769
- emitDebug({
770
- type: "render",
771
- render,
772
- routeKey,
773
- socketEvent,
774
- changed: renderChanged,
775
- rooms: verboseRef.current ? roomsRef.current : void 0
776
- });
777
- }, [emitDebug, render, routeKey, socketEvent]);
778
- const applyRooms = (0, import_react.useCallback)(
779
- (page, source) => {
780
- const onReceiveRooms = handlersRef.current.onReceiveRooms;
781
- if (!onReceiveRooms) return;
782
- setRooms((prev) => {
783
- const next = onReceiveRooms(page, prev);
784
- const unique = Array.from(new Set(next.filter(Boolean)));
785
- if (prev.length === unique.length && prev.every((room, idx) => room === unique[idx])) {
786
- emitDebug({
787
- type: "rooms",
788
- phase: "derive",
789
- routeKey,
790
- socketEvent,
791
- rooms: unique,
792
- prev,
793
- reason: "unchanged",
794
- meta: verboseRef.current ? { page, source } : void 0,
795
- source
796
- });
797
- return prev;
798
- }
799
- emitDebug({
800
- type: "rooms",
801
- phase: "derive",
802
- routeKey,
803
- socketEvent,
804
- rooms: unique,
805
- prev,
806
- meta: verboseRef.current ? { page, source } : void 0,
807
- source
808
- });
809
- return unique;
810
- });
811
- },
812
- [emitDebug, routeKey, socketEvent]
813
- );
814
- const routeArgs = useOptions?.args;
815
- const callerOptions = useOptions?.options;
816
- const mergedOptions = (0, import_react.useMemo)(
817
- () => ({
818
- ...callerOptions ?? {},
819
- onReceive(page) {
820
- callerOptions?.onReceive?.(page);
821
- applyRooms(page, "onReceive");
822
- emitDebug({
823
- type: "onReceive",
824
- routeKey,
825
- socketEvent,
826
- page: verboseRef.current ? page : void 0,
827
- rooms: verboseRef.current ? roomsRef.current : void 0
828
- });
829
- }
830
- }),
831
- [callerOptions, applyRooms, emitDebug, routeKey, socketEvent]
832
- );
833
- const endpointArgs = routeArgs ? [routeArgs, mergedOptions] : [mergedOptions];
834
- const { data } = endpoint.useEndpoint(...endpointArgs);
835
- (0, import_react.useEffect)(() => {
836
- if (!data) return;
837
- const pages = data?.pages;
838
- if (Array.isArray(pages)) {
839
- pages.forEach((p) => applyRooms(p, "hydrate"));
840
- return;
841
- }
842
- applyRooms(data, "hydrate");
843
- }, [data, applyRooms]);
844
- (0, import_react.useEffect)(() => {
845
- const prev = prevSubscribeDepsRef.current;
846
- const changedDeps = [];
847
- if (prev.client !== client) changedDeps.push("client");
848
- if (prev.socketEvent !== socketEvent) changedDeps.push("socketEvent");
849
- if (!Object.is(prev.routeArgs, routeArgs)) changedDeps.push("args");
850
- if (prev.routeKey !== routeKey) changedDeps.push("routeKey");
851
- prevSubscribeDepsRef.current = { client, socketEvent, routeArgs, routeKey };
852
- emitDebug({
853
- type: "effect",
854
- effect: "subscribe",
855
- phase: "run",
856
- changedDeps: changedDeps.length ? changedDeps : void 0
857
- });
858
- const stop = client.on(socketEvent, (payload, meta) => {
859
- const updater = (prev2) => handlersRef.current.handleMessage(prev2, payload, meta);
860
- const setDataArgs = routeArgs ? [routeArgs] : [];
861
- endpoint.setData(updater, ...setDataArgs);
862
- emitDebug({
863
- type: "receive",
864
- routeKey,
865
- socketEvent,
866
- payload: verboseRef.current ? payload : void 0,
867
- envelope: verboseRef.current ? {
868
- eventName: meta.envelope.eventName,
869
- sentAt: meta.envelope.sentAt,
870
- sentTo: meta.envelope.sentTo,
871
- metadata: meta.envelope.metadata
872
- } : void 0
873
- });
874
- emitDebug({
875
- type: "setData",
876
- routeKey,
877
- socketEvent,
878
- args: verboseRef.current ? routeArgs : void 0
879
- });
880
- });
881
- emitDebug({ type: "subscribe", phase: "start", routeKey, socketEvent });
882
- return () => {
883
- emitDebug({ type: "subscribe", phase: "stop", routeKey, socketEvent });
884
- stop();
885
- emitDebug({ type: "effect", effect: "subscribe", phase: "cleanup" });
886
- };
887
- }, [client, socketEvent, endpoint, routeArgs, emitDebug, routeKey]);
888
- (0, import_react.useEffect)(() => {
889
- let cancelled = false;
890
- const { joinMeta, leaveMeta } = handlersRef.current;
891
- const changedDeps = [];
892
- if (prevRoomsKeyRef.current !== roomsKey) changedDeps.push("rooms");
893
- if (prevClientRef.current !== client) changedDeps.push("client");
894
- if (prevRouteKeyRef.current !== routeKey) changedDeps.push("routeKey");
895
- if (prevSocketEventRef.current !== socketEvent) changedDeps.push("socketEvent");
896
- prevRoomsKeyRef.current = roomsKey;
897
- prevClientRef.current = client;
898
- prevRouteKeyRef.current = routeKey;
899
- prevSocketEventRef.current = socketEvent;
900
- emitDebug({
901
- type: "effect",
902
- effect: "rooms",
903
- phase: "run",
904
- changedDeps: changedDeps.length ? changedDeps : void 0,
905
- rooms
906
- });
907
- (async () => {
908
- if (!rooms.length) return;
909
- emitDebug({
910
- type: "rooms",
911
- phase: "join",
912
- routeKey,
913
- socketEvent,
914
- rooms,
915
- meta: verboseRef.current ? joinMeta : void 0
916
- });
917
- try {
918
- await client.joinRooms(rooms, joinMeta);
919
- } catch {
920
- }
921
- if (cancelled) {
922
- try {
923
- await client.leaveRooms(rooms, leaveMeta);
924
- } catch {
925
- }
926
- }
927
- })();
928
- return () => {
929
- cancelled = true;
930
- if (!rooms.length) return;
931
- client.leaveRooms(rooms, leaveMeta).catch(() => {
932
- });
933
- emitDebug({
934
- type: "rooms",
935
- phase: "leave",
936
- routeKey,
937
- socketEvent,
938
- rooms,
939
- meta: verboseRef.current ? leaveMeta : void 0
940
- });
941
- emitDebug({
942
- type: "effect",
943
- effect: "rooms",
944
- phase: "cleanup",
945
- rooms
946
- });
947
- };
948
- }, [client, roomsKey, rooms, emitDebug, routeKey, socketEvent]);
949
- return { data, rooms };
950
- };
951
- }
952
-
953
718
  // src/sockets/socket.client.index.ts
954
719
  var SocketClient = class {
955
720
  constructor(events, opts) {
@@ -1573,7 +1338,6 @@ var SocketClient = class {
1573
1338
  buildRouter,
1574
1339
  buildSocketProvider,
1575
1340
  createRouteClient,
1576
- createSocketedRouteHook,
1577
1341
  defaultFetcher,
1578
1342
  useSocketClient,
1579
1343
  useSocketConnection