@emeryld/rrroutes-client 2.7.2 → 2.7.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/dist/index.mjs CHANGED
@@ -264,6 +264,16 @@ function buildUrl(leaf, baseUrl, params, query) {
264
264
  const url = `${baseUrl ?? ""}${path}${toSearchString(normalizedQuery)}`;
265
265
  return { url, normalizedQuery, normalizedParams };
266
266
  }
267
+ function areEndpointArgsComplete(leaf, args) {
268
+ const params = args?.params;
269
+ const query = args?.query;
270
+ try {
271
+ buildUrl(leaf, "", params, query);
272
+ return true;
273
+ } catch {
274
+ return false;
275
+ }
276
+ }
267
277
  function isBlobLike(value) {
268
278
  return typeof Blob !== "undefined" && value instanceof Blob;
269
279
  }
@@ -607,6 +617,7 @@ function buildGetLeaf(leaf, rqOpts, env) {
607
617
  const useEndpoint = (...useArgs) => {
608
618
  const args = expectsArgs ? useArgs[0] : void 0;
609
619
  const useEndpointOptions = expectsArgs ? useArgs[1] : useArgs[0];
620
+ const hasCompleteArgs = !expectsArgs || areEndpointArgsComplete(leaf, args);
610
621
  const tuple = toArgsTuple(args);
611
622
  const queryKeys = getQueryKeys(...tuple);
612
623
  emit({
@@ -621,6 +632,8 @@ function buildGetLeaf(leaf, rqOpts, env) {
621
632
  ...buildQueryOptions,
622
633
  ...runtimeQueryOptions
623
634
  };
635
+ const mergedEnabled = mergedQueryOptions.enabled;
636
+ const guardedEnabled = hasCompleteArgs && (typeof mergedEnabled === "undefined" ? true : mergedEnabled);
624
637
  const listenersRef = useRef2(/* @__PURE__ */ new Set());
625
638
  const notifyOnReceive = useCallback2((data) => {
626
639
  buildOnReceive2?.(data);
@@ -639,11 +652,17 @@ function buildGetLeaf(leaf, rqOpts, env) {
639
652
  const queryResult = useQuery2(
640
653
  {
641
654
  ...mergedQueryOptions,
655
+ enabled: guardedEnabled,
642
656
  queryKey: getQueryKeys(...tuple),
643
657
  placeholderData: mergedQueryOptions.placeholderData ?? keepPreviousData2,
644
- queryFn: () => fetchEndpoint(tuple, {
645
- onReceive: notifyOnReceive
646
- })
658
+ queryFn: () => {
659
+ if (!hasCompleteArgs) {
660
+ return Promise.resolve(void 0);
661
+ }
662
+ return fetchEndpoint(tuple, {
663
+ onReceive: notifyOnReceive
664
+ });
665
+ }
647
666
  },
648
667
  queryClient
649
668
  );
@@ -890,6 +909,7 @@ function buildInfiniteGetLeaf(leaf, rqOpts, env) {
890
909
  const useEndpoint = (...useArgs) => {
891
910
  const args = expectsArgs ? useArgs[0] : void 0;
892
911
  const useEndpointOptions = expectsArgs ? useArgs[1] : useArgs[0];
912
+ const hasCompleteArgs = !expectsArgs || areEndpointArgsComplete(leaf, args);
893
913
  const tuple = toArgsTuple(args);
894
914
  const queryKeys = getQueryKeys(...tuple);
895
915
  emit({
@@ -907,6 +927,8 @@ function buildInfiniteGetLeaf(leaf, rqOpts, env) {
907
927
  ...buildInfiniteQueryOptions,
908
928
  ...runtimeInfiniteQueryOptions
909
929
  };
930
+ const mergedEnabled = mergedInfiniteQueryOptions.enabled;
931
+ const guardedEnabled = hasCompleteArgs && (typeof mergedEnabled === "undefined" ? true : mergedEnabled);
910
932
  const listenersRef = useRef3(/* @__PURE__ */ new Set());
911
933
  const notifyOnReceive = useCallback3((data) => {
912
934
  buildOnReceive2?.(data);
@@ -922,20 +944,22 @@ function buildInfiniteGetLeaf(leaf, rqOpts, env) {
922
944
  },
923
945
  []
924
946
  );
925
- const { normalizedQuery, normalizedParams } = buildUrl(
926
- { ...leaf, cfg: leafCfg },
927
- baseUrl,
928
- params,
929
- query
930
- );
947
+ const { normalizedQuery, normalizedParams } = hasCompleteArgs ? buildUrl({ ...leaf, cfg: leafCfg }, baseUrl, params, query) : {
948
+ normalizedQuery: query ?? {},
949
+ normalizedParams: params ?? {}
950
+ };
931
951
  const queryResult = useInfiniteQuery(
932
952
  {
933
953
  ...mergedInfiniteQueryOptions,
954
+ enabled: guardedEnabled,
934
955
  placeholderData: mergedInfiniteQueryOptions.placeholderData ?? keepPreviousData3,
935
956
  initialPageParam: feedInitialPageParam,
936
957
  getNextPageParam: (lastPage) => cursorFromPage(lastPage),
937
958
  queryKey: queryKeys,
938
959
  queryFn: ({ pageParam }) => {
960
+ if (!hasCompleteArgs) {
961
+ return Promise.resolve(void 0);
962
+ }
939
963
  if (!effectiveSplitPageSize) {
940
964
  const pageQuery = {
941
965
  ...normalizedQuery,
@@ -2721,12 +2745,15 @@ function mergeRoomState(prev, toRoomsResult) {
2721
2745
  leaveMeta: toRoomsResult.leaveMeta ?? prev.leaveMeta
2722
2746
  };
2723
2747
  }
2724
- function roomsFromData(data, args, toRooms) {
2748
+ function roomsFromData(data, args, toRooms, meta) {
2725
2749
  if (data == null) return { rooms: [] };
2726
2750
  let state = { rooms: [] };
2727
2751
  const add = (input) => {
2728
2752
  const mergeForValue = (value) => {
2729
- state = mergeRoomState(state, toRooms(value, args));
2753
+ state = mergeRoomState(
2754
+ state,
2755
+ toRooms({ data: value, args, meta })
2756
+ );
2730
2757
  };
2731
2758
  if (Array.isArray(input)) {
2732
2759
  input.forEach((entry) => mergeForValue(entry));
@@ -2761,8 +2788,21 @@ function parseUseEndpointArgs(useArgs) {
2761
2788
  const endpointArgsTuple = typeof endpointArgs === "undefined" ? [] : [endpointArgs];
2762
2789
  return { endpointArgs, endpointArgsTuple };
2763
2790
  }
2791
+ function useDefaultSocketedRouteContext() {
2792
+ return void 0;
2793
+ }
2794
+ function createToRoomsMeta(appContext) {
2795
+ return { appContext };
2796
+ }
2764
2797
  function buildSocketedRoute(options) {
2765
- const { built, toRooms, applySocket, useSocketClient: useSocketClient2, debug } = options;
2798
+ const {
2799
+ built,
2800
+ toRooms,
2801
+ applySocket,
2802
+ useSocketClient: useSocketClient2,
2803
+ useContext: useRouteContext = useDefaultSocketedRouteContext,
2804
+ debug
2805
+ } = options;
2766
2806
  const { useEndpoint: useInnerEndpoint, ...rest } = built;
2767
2807
  const useEndpoint = (...useArgs) => {
2768
2808
  const client = useSocketClient2();
@@ -2770,6 +2810,11 @@ function buildSocketedRoute(options) {
2770
2810
  const endpointResult = useInnerEndpoint(
2771
2811
  ...useArgs
2772
2812
  );
2813
+ const appContext = useRouteContext();
2814
+ const toRoomsMeta = useMemo3(
2815
+ () => createToRoomsMeta(appContext),
2816
+ [appContext]
2817
+ );
2773
2818
  const { endpointArgs, endpointArgsTuple } = parseUseEndpointArgs(useArgs);
2774
2819
  const argsKey = useMemo3(
2775
2820
  () => safeJsonKey(endpointArgs ?? null),
@@ -2779,7 +2824,8 @@ function buildSocketedRoute(options) {
2779
2824
  () => roomsFromData(
2780
2825
  endpointResult.data,
2781
2826
  endpointArgs,
2782
- toRooms
2827
+ toRooms,
2828
+ toRoomsMeta
2783
2829
  )
2784
2830
  );
2785
2831
  const renderCountRef = useRef6(0);
@@ -2788,6 +2834,7 @@ function buildSocketedRoute(options) {
2788
2834
  endpointResult.data
2789
2835
  );
2790
2836
  const toRoomsRef = useRef6(toRooms);
2837
+ const toRoomsMetaRef = useRef6(toRoomsMeta);
2791
2838
  const onReceiveEffectDebugRef = useRef6(null);
2792
2839
  const deriveRoomsEffectDebugRef = useRef6(null);
2793
2840
  const joinRoomsEffectDebugRef = useRef6(null);
@@ -2795,6 +2842,7 @@ function buildSocketedRoute(options) {
2795
2842
  renderCountRef.current += 1;
2796
2843
  endpointDataRef.current = endpointResult.data;
2797
2844
  toRoomsRef.current = toRooms;
2845
+ toRoomsMetaRef.current = toRoomsMeta;
2798
2846
  const roomsKey = useMemo3(() => roomState.rooms.join("|"), [roomState.rooms]);
2799
2847
  const joinMetaKey = useMemo3(
2800
2848
  () => safeJsonKey(roomState.joinMeta ?? null),
@@ -2836,7 +2884,11 @@ function buildSocketedRoute(options) {
2836
2884
  setRoomState((prev) => {
2837
2885
  const next = mergeRoomState(
2838
2886
  prev,
2839
- toRoomsRef.current(data, endpointArgs)
2887
+ toRoomsRef.current({
2888
+ data,
2889
+ args: endpointArgs,
2890
+ meta: toRoomsMetaRef.current
2891
+ })
2840
2892
  );
2841
2893
  return roomStateEqual(prev, next) ? prev : next;
2842
2894
  });
@@ -2854,9 +2906,14 @@ function buildSocketedRoute(options) {
2854
2906
  toRoomsRef: describeObjectReference(toRooms)
2855
2907
  }
2856
2908
  });
2857
- const next = roomsFromData(endpointDataRef.current, endpointArgs, toRooms);
2909
+ const next = roomsFromData(
2910
+ endpointDataRef.current,
2911
+ endpointArgs,
2912
+ toRooms,
2913
+ toRoomsMeta
2914
+ );
2858
2915
  setRoomState((prev) => roomStateEqual(prev, next) ? prev : next);
2859
- }, [argsKey, toRooms, debug]);
2916
+ }, [argsKey, toRooms, toRoomsMeta, debug]);
2860
2917
  useEffect3(() => {
2861
2918
  trackHookTrigger2({
2862
2919
  ref: joinRoomsEffectDebugRef,
@@ -2974,7 +3031,10 @@ function buildSocketedRoute(options) {
2974
3031
  prev,
2975
3032
  payload: nextUpdate.payload,
2976
3033
  args: endpointArgs,
2977
- meta: nextUpdate.meta ?? {}
3034
+ meta: {
3035
+ ...nextUpdate.meta ?? {},
3036
+ appContext: toRoomsMetaRef.current.appContext
3037
+ }
2978
3038
  });
2979
3039
  if (next === null) return prev;
2980
3040
  if (shouldWarnSocketMutationGuard() && isSameObjectReference(prev, next) && !sameRefWarnedEvents.has(nextUpdate.event)) {
@@ -2986,7 +3046,8 @@ function buildSocketedRoute(options) {
2986
3046
  const nextRoomState = roomsFromData(
2987
3047
  next,
2988
3048
  endpointArgs,
2989
- toRooms
3049
+ toRooms,
3050
+ toRoomsMetaRef.current
2990
3051
  );
2991
3052
  setRoomState(
2992
3053
  (prevRoomState) => roomStateEqual(prevRoomState, nextRoomState) ? prevRoomState : nextRoomState