@emeryld/rrroutes-client 2.2.5 → 2.2.6

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
@@ -655,7 +655,50 @@ import { useCallback, useEffect as useEffect2, useMemo as useMemo2, useRef as us
655
655
  function createSocketedRouteHook(args) {
656
656
  const { buildRoute, useClient = () => useSocketClient() } = args;
657
657
  return function useSocketedRoute(params) {
658
- const { routeKey, socketEvent, handlers, buildOptions, buildMeta, useOptions } = params;
658
+ const { routeKey, socketEvent, handlers, buildOptions, buildMeta, debug, useOptions } = params;
659
+ const renderRef = useRef2(0);
660
+ const prevInputsRef = useRef2();
661
+ const debugName = buildMeta?.name;
662
+ const render = ++renderRef.current;
663
+ const renderChanged = [];
664
+ const prevInputs = prevInputsRef.current;
665
+ if (prevInputs) {
666
+ if (!Object.is(prevInputs.routeKey, routeKey)) renderChanged.push("routeKey");
667
+ if (!Object.is(prevInputs.socketEvent, socketEvent)) renderChanged.push("socketEvent");
668
+ if (!Object.is(prevInputs.buildOptions, buildOptions)) renderChanged.push("buildOptions");
669
+ if (!Object.is(prevInputs.buildMeta, buildMeta)) renderChanged.push("buildMeta");
670
+ if (!Object.is(prevInputs.debug, debug)) renderChanged.push("debug");
671
+ if (!Object.is(prevInputs.args, useOptions?.args)) renderChanged.push("args");
672
+ if (!Object.is(prevInputs.options, useOptions?.options)) renderChanged.push("options");
673
+ }
674
+ prevInputsRef.current = {
675
+ routeKey,
676
+ socketEvent,
677
+ buildOptions,
678
+ buildMeta,
679
+ debug,
680
+ args: useOptions?.args,
681
+ options: useOptions?.options
682
+ };
683
+ const debugRef = useRef2(debug);
684
+ useEffect2(() => {
685
+ debugRef.current = debug;
686
+ }, [debug]);
687
+ const emitDebug = useCallback(
688
+ (event) => {
689
+ const d = debugRef.current;
690
+ if (!d?.logger) return;
691
+ if (!d[event.type]) return;
692
+ const name = event.name ?? debugName;
693
+ if (d.only && name && !d.only.includes(name)) return;
694
+ d.logger({ ...event, name });
695
+ },
696
+ [debugName]
697
+ );
698
+ const verboseRef = useRef2(!!debug?.verbose);
699
+ useEffect2(() => {
700
+ verboseRef.current = !!debug?.verbose;
701
+ }, [debug]);
659
702
  const handlersRef = useRef2(handlers);
660
703
  useEffect2(() => {
661
704
  handlersRef.current = handlers;
@@ -664,23 +707,74 @@ function createSocketedRouteHook(args) {
664
707
  () => buildRoute(routeKey, buildOptions, buildMeta),
665
708
  [buildRoute, routeKey, buildOptions, buildMeta]
666
709
  );
710
+ useEffect2(() => {
711
+ emitDebug({
712
+ type: "build",
713
+ routeKey,
714
+ socketEvent,
715
+ options: verboseRef.current ? { buildOptions, buildMeta, useOptions } : void 0
716
+ });
717
+ }, [emitDebug, routeKey, socketEvent, buildOptions, buildMeta, useOptions]);
667
718
  const client = useClient();
668
719
  const [rooms, setRooms] = useState2([]);
669
720
  const roomsKey = rooms.slice().sort().join("|");
721
+ const roomsRef = useRef2([]);
722
+ roomsRef.current = rooms;
723
+ const prevRoomsKeyRef = useRef2(roomsKey);
724
+ const prevClientRef = useRef2(client);
725
+ const prevRouteKeyRef = useRef2(routeKey);
726
+ const prevSocketEventRef = useRef2(socketEvent);
727
+ const prevSubscribeDepsRef = useRef2({
728
+ client,
729
+ socketEvent,
730
+ routeArgs: useOptions?.args,
731
+ routeKey
732
+ });
733
+ useEffect2(() => {
734
+ emitDebug({
735
+ type: "render",
736
+ render,
737
+ routeKey,
738
+ socketEvent,
739
+ changed: renderChanged,
740
+ rooms: verboseRef.current ? roomsRef.current : void 0
741
+ });
742
+ }, [emitDebug, render, routeKey, socketEvent]);
670
743
  const applyRooms = useCallback(
671
- (page) => {
744
+ (page, source) => {
672
745
  const onReceiveRooms = handlersRef.current.onReceiveRooms;
673
746
  if (!onReceiveRooms) return;
674
747
  setRooms((prev) => {
675
748
  const next = onReceiveRooms(page, prev);
676
749
  const unique = Array.from(new Set(next.filter(Boolean)));
677
750
  if (prev.length === unique.length && prev.every((room, idx) => room === unique[idx])) {
751
+ emitDebug({
752
+ type: "rooms",
753
+ phase: "derive",
754
+ routeKey,
755
+ socketEvent,
756
+ rooms: unique,
757
+ prev,
758
+ reason: "unchanged",
759
+ meta: verboseRef.current ? { page, source } : void 0,
760
+ source
761
+ });
678
762
  return prev;
679
763
  }
764
+ emitDebug({
765
+ type: "rooms",
766
+ phase: "derive",
767
+ routeKey,
768
+ socketEvent,
769
+ rooms: unique,
770
+ prev,
771
+ meta: verboseRef.current ? { page, source } : void 0,
772
+ source
773
+ });
680
774
  return unique;
681
775
  });
682
776
  },
683
- []
777
+ [emitDebug, routeKey, socketEvent]
684
778
  );
685
779
  const routeArgs = useOptions?.args;
686
780
  const callerOptions = useOptions?.options;
@@ -689,10 +783,17 @@ function createSocketedRouteHook(args) {
689
783
  ...callerOptions ?? {},
690
784
  onReceive(page) {
691
785
  callerOptions?.onReceive?.(page);
692
- applyRooms(page);
786
+ applyRooms(page, "onReceive");
787
+ emitDebug({
788
+ type: "onReceive",
789
+ routeKey,
790
+ socketEvent,
791
+ page: verboseRef.current ? page : void 0,
792
+ rooms: verboseRef.current ? roomsRef.current : void 0
793
+ });
693
794
  }
694
795
  }),
695
- [callerOptions, applyRooms]
796
+ [callerOptions, applyRooms, emitDebug, routeKey, socketEvent]
696
797
  );
697
798
  const endpointArgs = routeArgs ? [routeArgs, mergedOptions] : [mergedOptions];
698
799
  const { data } = endpoint.useEndpoint(...endpointArgs);
@@ -700,24 +801,84 @@ function createSocketedRouteHook(args) {
700
801
  if (!data) return;
701
802
  const pages = data?.pages;
702
803
  if (Array.isArray(pages)) {
703
- pages.forEach(applyRooms);
804
+ pages.forEach((p) => applyRooms(p, "hydrate"));
704
805
  return;
705
806
  }
706
- applyRooms(data);
807
+ applyRooms(data, "hydrate");
707
808
  }, [data, applyRooms]);
708
809
  useEffect2(() => {
810
+ const prev = prevSubscribeDepsRef.current;
811
+ const changedDeps = [];
812
+ if (prev.client !== client) changedDeps.push("client");
813
+ if (prev.socketEvent !== socketEvent) changedDeps.push("socketEvent");
814
+ if (!Object.is(prev.routeArgs, routeArgs)) changedDeps.push("args");
815
+ if (prev.routeKey !== routeKey) changedDeps.push("routeKey");
816
+ prevSubscribeDepsRef.current = { client, socketEvent, routeArgs, routeKey };
817
+ emitDebug({
818
+ type: "effect",
819
+ effect: "subscribe",
820
+ phase: "run",
821
+ changedDeps: changedDeps.length ? changedDeps : void 0
822
+ });
709
823
  const stop = client.on(socketEvent, (payload, meta) => {
710
- const updater = (prev) => handlersRef.current.handleMessage(prev, payload, meta);
824
+ const updater = (prev2) => handlersRef.current.handleMessage(prev2, payload, meta);
711
825
  const setDataArgs = routeArgs ? [routeArgs] : [];
712
826
  endpoint.setData(updater, ...setDataArgs);
827
+ emitDebug({
828
+ type: "receive",
829
+ routeKey,
830
+ socketEvent,
831
+ payload: verboseRef.current ? payload : void 0,
832
+ envelope: verboseRef.current ? {
833
+ eventName: meta.envelope.eventName,
834
+ sentAt: meta.envelope.sentAt,
835
+ sentTo: meta.envelope.sentTo,
836
+ metadata: meta.envelope.metadata
837
+ } : void 0
838
+ });
839
+ emitDebug({
840
+ type: "setData",
841
+ routeKey,
842
+ socketEvent,
843
+ args: verboseRef.current ? routeArgs : void 0
844
+ });
713
845
  });
714
- return stop;
715
- }, [client, socketEvent, endpoint, routeArgs]);
846
+ emitDebug({ type: "subscribe", phase: "start", routeKey, socketEvent });
847
+ return () => {
848
+ emitDebug({ type: "subscribe", phase: "stop", routeKey, socketEvent });
849
+ stop();
850
+ emitDebug({ type: "effect", effect: "subscribe", phase: "cleanup" });
851
+ };
852
+ }, [client, socketEvent, endpoint, routeArgs, emitDebug, routeKey]);
716
853
  useEffect2(() => {
717
854
  let cancelled = false;
718
855
  const { joinMeta, leaveMeta } = handlersRef.current;
856
+ const changedDeps = [];
857
+ if (prevRoomsKeyRef.current !== roomsKey) changedDeps.push("rooms");
858
+ if (prevClientRef.current !== client) changedDeps.push("client");
859
+ if (prevRouteKeyRef.current !== routeKey) changedDeps.push("routeKey");
860
+ if (prevSocketEventRef.current !== socketEvent) changedDeps.push("socketEvent");
861
+ prevRoomsKeyRef.current = roomsKey;
862
+ prevClientRef.current = client;
863
+ prevRouteKeyRef.current = routeKey;
864
+ prevSocketEventRef.current = socketEvent;
865
+ emitDebug({
866
+ type: "effect",
867
+ effect: "rooms",
868
+ phase: "run",
869
+ changedDeps: changedDeps.length ? changedDeps : void 0,
870
+ rooms
871
+ });
719
872
  (async () => {
720
873
  if (!rooms.length) return;
874
+ emitDebug({
875
+ type: "rooms",
876
+ phase: "join",
877
+ routeKey,
878
+ socketEvent,
879
+ rooms,
880
+ meta: verboseRef.current ? joinMeta : void 0
881
+ });
721
882
  try {
722
883
  await client.joinRooms(rooms, joinMeta);
723
884
  } catch {
@@ -734,8 +895,22 @@ function createSocketedRouteHook(args) {
734
895
  if (!rooms.length) return;
735
896
  client.leaveRooms(rooms, leaveMeta).catch(() => {
736
897
  });
898
+ emitDebug({
899
+ type: "rooms",
900
+ phase: "leave",
901
+ routeKey,
902
+ socketEvent,
903
+ rooms,
904
+ meta: verboseRef.current ? leaveMeta : void 0
905
+ });
906
+ emitDebug({
907
+ type: "effect",
908
+ effect: "rooms",
909
+ phase: "cleanup",
910
+ rooms
911
+ });
737
912
  };
738
- }, [client, roomsKey, rooms]);
913
+ }, [client, roomsKey, rooms, emitDebug, routeKey, socketEvent]);
739
914
  return { data, rooms };
740
915
  };
741
916
  }