@emeryld/rrroutes-client 2.2.12 → 2.2.13

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/README.md CHANGED
@@ -392,21 +392,24 @@ const listRooms = client.build(registry.byKey['GET /v1/rooms'], { staleTime: 120
392
392
 
393
393
  const useSocketedRooms = buildSocketedRoute({
394
394
  built: listRooms,
395
- event: 'chat:message',
396
- toRooms: (page) => page.items.map((r) => r.id), // derive rooms from data (feeds supported)
397
- joinMeta: { source: 'rooms:list' },
398
- leaveMeta: { source: 'rooms:list' },
395
+ toRooms: (page) => ({
396
+ rooms: page.items.map((r) => r.id), // derive rooms from data (feeds supported)
397
+ joinMeta: { source: 'rooms:list' },
398
+ leaveMeta: { source: 'rooms:list' },
399
+ }),
399
400
  useSocketClient,
400
- applyMessage: (prev, payload) => {
401
- if (!prev) return prev;
402
- // Example: bump unread count in cache
403
- const apply = (items: any[]) =>
404
- items.map((room) =>
405
- room.id === payload.roomId ? { ...room, unread: (room.unread ?? 0) + 1 } : room,
406
- );
407
- return 'pages' in prev
408
- ? { ...prev, pages: prev.pages.map((p) => ({ ...p, items: apply(p.items) })) }
409
- : { ...prev, items: apply(prev.items) };
401
+ applyMessage: {
402
+ 'chat:message': (prev, payload) => {
403
+ if (!prev) return prev;
404
+ // Example: bump unread count in cache
405
+ const apply = (items: any[]) =>
406
+ items.map((room) =>
407
+ room.id === payload.roomId ? { ...room, unread: (room.unread ?? 0) + 1 } : room,
408
+ );
409
+ return 'pages' in prev
410
+ ? { ...prev, pages: prev.pages.map((p) => ({ ...p, items: apply(p.items) })) }
411
+ : { ...prev, items: apply(prev.items) };
412
+ },
410
413
  },
411
414
  });
412
415
 
package/dist/index.cjs CHANGED
@@ -786,72 +786,84 @@ function normalizeRooms(rooms) {
786
786
  }
787
787
  return normalized;
788
788
  }
789
+ function mergeRoomState(prev, toRoomsResult) {
790
+ const merged = new Set(prev.rooms);
791
+ for (const r of normalizeRooms(toRoomsResult.rooms)) merged.add(r);
792
+ return {
793
+ rooms: Array.from(merged),
794
+ joinMeta: toRoomsResult.joinMeta ?? prev.joinMeta,
795
+ leaveMeta: toRoomsResult.leaveMeta ?? prev.leaveMeta
796
+ };
797
+ }
789
798
  function roomsFromData(data, toRooms) {
790
- if (data == null) return [];
791
- const merge = /* @__PURE__ */ new Set();
799
+ if (data == null) return { rooms: [] };
800
+ let state = { rooms: [] };
792
801
  const add = (input) => {
793
- for (const r of normalizeRooms(input)) merge.add(r);
802
+ state = mergeRoomState(state, toRooms(input));
794
803
  };
795
804
  const maybePages = data?.pages;
796
805
  if (Array.isArray(maybePages)) {
797
- for (const page of maybePages) add(toRooms(page));
798
- return Array.from(merge);
806
+ for (const page of maybePages) add(page);
807
+ return state;
799
808
  }
800
- add(toRooms(data));
801
- return Array.from(merge);
809
+ add(data);
810
+ return state;
802
811
  }
803
812
  function buildSocketedRoute(options) {
804
- const { built, event, toRooms, applyMessage, joinMeta, leaveMeta, useSocketClient: useSocketClient2 } = options;
813
+ const { built, toRooms, applyMessage, useSocketClient: useSocketClient2 } = options;
805
814
  return (...useArgs) => {
806
815
  const client = useSocketClient2();
807
816
  const endpointResult = built.useEndpoint(...useArgs);
808
817
  const argsKey = (0, import_react2.useMemo)(() => JSON.stringify(useArgs[0] ?? null), [useArgs]);
809
- const [rooms, setRooms] = (0, import_react2.useState)(
818
+ const [roomState, setRoomState] = (0, import_react2.useState)(
810
819
  () => roomsFromData(endpointResult.data, toRooms)
811
820
  );
812
- const roomsKey = (0, import_react2.useMemo)(() => rooms.join("|"), [rooms]);
821
+ const roomsKey = (0, import_react2.useMemo)(() => roomState.rooms.join("|"), [roomState.rooms]);
822
+ const joinMetaKey = (0, import_react2.useMemo)(() => JSON.stringify(roomState.joinMeta ?? null), [roomState.joinMeta]);
823
+ const leaveMetaKey = (0, import_react2.useMemo)(() => JSON.stringify(roomState.leaveMeta ?? null), [roomState.leaveMeta]);
813
824
  (0, import_react2.useEffect)(() => {
814
825
  const unsubscribe = endpointResult.onReceive((data) => {
815
- setRooms((prev) => {
816
- const next = normalizeRooms(toRooms(data));
817
- if (next.length === 0) return prev;
818
- const merged = new Set(prev);
819
- next.forEach((r) => merged.add(r));
820
- return Array.from(merged);
821
- });
826
+ setRoomState((prev) => mergeRoomState(prev, toRooms(data)));
822
827
  });
823
828
  return unsubscribe;
824
829
  }, [endpointResult, toRooms]);
825
830
  (0, import_react2.useEffect)(() => {
826
- setRooms(roomsFromData(endpointResult.data, toRooms));
831
+ setRoomState(roomsFromData(endpointResult.data, toRooms));
827
832
  }, [endpointResult.data, toRooms]);
828
833
  (0, import_react2.useEffect)(() => {
829
- if (rooms.length === 0) return;
834
+ if (roomState.rooms.length === 0) return;
835
+ const { joinMeta, leaveMeta } = roomState;
836
+ if (!joinMeta || !leaveMeta) return;
830
837
  let active = true;
831
838
  (async () => {
832
839
  try {
833
- await client.joinRooms(rooms, joinMeta);
840
+ await client.joinRooms(roomState.rooms, joinMeta);
834
841
  } catch {
835
842
  }
836
843
  })();
837
844
  return () => {
838
- if (!active || rooms.length === 0) return;
845
+ if (!active || roomState.rooms.length === 0) return;
839
846
  active = false;
840
- void client.leaveRooms(rooms, leaveMeta).catch(() => {
847
+ void client.leaveRooms(roomState.rooms, leaveMeta).catch(() => {
841
848
  });
842
849
  };
843
- }, [client, joinMeta, leaveMeta, roomsKey]);
850
+ }, [client, roomsKey, roomState.joinMeta, roomState.leaveMeta, joinMetaKey, leaveMetaKey]);
844
851
  (0, import_react2.useEffect)(() => {
845
- const unsubscribe = client.on(event, (payload, meta) => {
846
- built.setData((prev) => {
847
- const next = applyMessage(prev, payload, meta);
848
- setRooms(roomsFromData(next, toRooms));
849
- return next;
850
- }, ...useArgs);
851
- });
852
- return unsubscribe;
853
- }, [client, event, applyMessage, built, argsKey]);
854
- return { ...endpointResult, rooms };
852
+ const entries = Object.entries(applyMessage).filter(
853
+ ([_event, fn]) => typeof fn === "function"
854
+ );
855
+ const unsubscribes = entries.map(
856
+ ([ev, fn]) => client.on(ev, (payload, meta) => {
857
+ built.setData((prev) => {
858
+ const next = fn(prev, payload, meta);
859
+ setRoomState(roomsFromData(next, toRooms));
860
+ return next;
861
+ }, ...useArgs);
862
+ })
863
+ );
864
+ return () => unsubscribes.forEach((u) => u?.());
865
+ }, [client, applyMessage, built, argsKey, toRooms]);
866
+ return { ...endpointResult, rooms: roomState.rooms };
855
867
  };
856
868
  }
857
869