@emeryld/rrroutes-client 2.2.4 → 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.cjs CHANGED
@@ -690,63 +690,237 @@ var import_react = require("react");
690
690
  function createSocketedRouteHook(args) {
691
691
  const { buildRoute, useClient = () => useSocketClient() } = args;
692
692
  return function useSocketedRoute(params) {
693
- const { routeKey, socketEvent, handlers, buildOptions, buildMeta, useOptions } = 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]);
694
741
  const endpoint = (0, import_react.useMemo)(
695
742
  () => buildRoute(routeKey, buildOptions, buildMeta),
696
743
  [buildRoute, routeKey, buildOptions, buildMeta]
697
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]);
698
753
  const client = useClient();
699
754
  const [rooms, setRooms] = (0, import_react.useState)([]);
700
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]);
701
778
  const applyRooms = (0, import_react.useCallback)(
702
- (page) => {
703
- if (!handlers.onReceiveRooms) return;
779
+ (page, source) => {
780
+ const onReceiveRooms = handlersRef.current.onReceiveRooms;
781
+ if (!onReceiveRooms) return;
704
782
  setRooms((prev) => {
705
- const next = handlers.onReceiveRooms(page, prev);
706
- return Array.from(new Set(next.filter(Boolean)));
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;
707
810
  });
708
811
  },
709
- [handlers]
812
+ [emitDebug, routeKey, socketEvent]
710
813
  );
711
814
  const routeArgs = useOptions?.args;
712
815
  const callerOptions = useOptions?.options;
713
- const mergedOptions = {
714
- ...callerOptions ?? {},
715
- onReceive(page) {
716
- callerOptions?.onReceive?.(page);
717
- applyRooms(page);
718
- }
719
- };
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
+ );
720
833
  const endpointArgs = routeArgs ? [routeArgs, mergedOptions] : [mergedOptions];
721
834
  const { data } = endpoint.useEndpoint(...endpointArgs);
722
835
  (0, import_react.useEffect)(() => {
723
836
  if (!data) return;
724
837
  const pages = data?.pages;
725
838
  if (Array.isArray(pages)) {
726
- pages.forEach(applyRooms);
839
+ pages.forEach((p) => applyRooms(p, "hydrate"));
727
840
  return;
728
841
  }
729
- applyRooms(data);
842
+ applyRooms(data, "hydrate");
730
843
  }, [data, applyRooms]);
731
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
+ });
732
858
  const stop = client.on(socketEvent, (payload, meta) => {
733
- const updater = (prev) => handlers.handleMessage(prev, payload, meta);
859
+ const updater = (prev2) => handlersRef.current.handleMessage(prev2, payload, meta);
734
860
  const setDataArgs = routeArgs ? [routeArgs] : [];
735
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
+ });
736
880
  });
737
- return stop;
738
- }, [client, socketEvent, endpoint, handlers]);
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]);
739
888
  (0, import_react.useEffect)(() => {
740
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
+ });
741
907
  (async () => {
742
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
+ });
743
917
  try {
744
- await client.joinRooms(rooms, handlers.joinMeta);
918
+ await client.joinRooms(rooms, joinMeta);
745
919
  } catch {
746
920
  }
747
921
  if (cancelled) {
748
922
  try {
749
- await client.leaveRooms(rooms, handlers.leaveMeta);
923
+ await client.leaveRooms(rooms, leaveMeta);
750
924
  } catch {
751
925
  }
752
926
  }
@@ -754,10 +928,24 @@ function createSocketedRouteHook(args) {
754
928
  return () => {
755
929
  cancelled = true;
756
930
  if (!rooms.length) return;
757
- client.leaveRooms(rooms, handlers.leaveMeta).catch(() => {
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
758
946
  });
759
947
  };
760
- }, [client, roomsKey, handlers.joinMeta, handlers.leaveMeta, rooms]);
948
+ }, [client, roomsKey, rooms, emitDebug, routeKey, socketEvent]);
761
949
  return { data, rooms };
762
950
  };
763
951
  }