@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.cjs CHANGED
@@ -690,7 +690,50 @@ 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]);
694
737
  const handlersRef = (0, import_react.useRef)(handlers);
695
738
  (0, import_react.useEffect)(() => {
696
739
  handlersRef.current = handlers;
@@ -699,23 +742,74 @@ function createSocketedRouteHook(args) {
699
742
  () => buildRoute(routeKey, buildOptions, buildMeta),
700
743
  [buildRoute, routeKey, buildOptions, buildMeta]
701
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]);
702
753
  const client = useClient();
703
754
  const [rooms, setRooms] = (0, import_react.useState)([]);
704
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]);
705
778
  const applyRooms = (0, import_react.useCallback)(
706
- (page) => {
779
+ (page, source) => {
707
780
  const onReceiveRooms = handlersRef.current.onReceiveRooms;
708
781
  if (!onReceiveRooms) return;
709
782
  setRooms((prev) => {
710
783
  const next = onReceiveRooms(page, prev);
711
784
  const unique = Array.from(new Set(next.filter(Boolean)));
712
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
+ });
713
797
  return prev;
714
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
+ });
715
809
  return unique;
716
810
  });
717
811
  },
718
- []
812
+ [emitDebug, routeKey, socketEvent]
719
813
  );
720
814
  const routeArgs = useOptions?.args;
721
815
  const callerOptions = useOptions?.options;
@@ -724,10 +818,17 @@ function createSocketedRouteHook(args) {
724
818
  ...callerOptions ?? {},
725
819
  onReceive(page) {
726
820
  callerOptions?.onReceive?.(page);
727
- applyRooms(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
+ });
728
829
  }
729
830
  }),
730
- [callerOptions, applyRooms]
831
+ [callerOptions, applyRooms, emitDebug, routeKey, socketEvent]
731
832
  );
732
833
  const endpointArgs = routeArgs ? [routeArgs, mergedOptions] : [mergedOptions];
733
834
  const { data } = endpoint.useEndpoint(...endpointArgs);
@@ -735,24 +836,84 @@ function createSocketedRouteHook(args) {
735
836
  if (!data) return;
736
837
  const pages = data?.pages;
737
838
  if (Array.isArray(pages)) {
738
- pages.forEach(applyRooms);
839
+ pages.forEach((p) => applyRooms(p, "hydrate"));
739
840
  return;
740
841
  }
741
- applyRooms(data);
842
+ applyRooms(data, "hydrate");
742
843
  }, [data, applyRooms]);
743
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
+ });
744
858
  const stop = client.on(socketEvent, (payload, meta) => {
745
- const updater = (prev) => handlersRef.current.handleMessage(prev, payload, meta);
859
+ const updater = (prev2) => handlersRef.current.handleMessage(prev2, payload, meta);
746
860
  const setDataArgs = routeArgs ? [routeArgs] : [];
747
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
+ });
748
880
  });
749
- return stop;
750
- }, [client, socketEvent, endpoint, routeArgs]);
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]);
751
888
  (0, import_react.useEffect)(() => {
752
889
  let cancelled = false;
753
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
+ });
754
907
  (async () => {
755
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
+ });
756
917
  try {
757
918
  await client.joinRooms(rooms, joinMeta);
758
919
  } catch {
@@ -769,8 +930,22 @@ function createSocketedRouteHook(args) {
769
930
  if (!rooms.length) return;
770
931
  client.leaveRooms(rooms, leaveMeta).catch(() => {
771
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
+ });
772
947
  };
773
- }, [client, roomsKey, rooms]);
948
+ }, [client, roomsKey, rooms, emitDebug, routeKey, socketEvent]);
774
949
  return { data, rooms };
775
950
  };
776
951
  }