@may-db/react 0.1.0

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.
@@ -0,0 +1,12 @@
1
+ import type { Room } from "@may-db/core";
2
+ export interface AllowedRoomInfo {
3
+ roomId: string;
4
+ title: string;
5
+ }
6
+ export declare function useAllowedRooms(room: Room): {
7
+ allowedRooms: AllowedRoomInfo[];
8
+ loading: boolean;
9
+ error: Error | null;
10
+ refresh: () => Promise<void>;
11
+ };
12
+ //# sourceMappingURL=useAllowedRooms.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useAllowedRooms.d.ts","sourceRoot":"","sources":["../../src/hooks/useAllowedRooms.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI;;;;;EA+BzC"}
@@ -0,0 +1,29 @@
1
+ import { useState, useEffect, useCallback } from "react";
2
+ export function useAllowedRooms(room) {
3
+ const [allowedRooms, setAllowedRooms] = useState([]);
4
+ const [loading, setLoading] = useState(true);
5
+ const [error, setError] = useState(null);
6
+ const refresh = useCallback(async () => {
7
+ setLoading(true);
8
+ setError(null);
9
+ try {
10
+ const ids = await room.getAllowedRoomIds();
11
+ const rooms = await Promise.all(ids.map(async (roomId) => ({
12
+ roomId,
13
+ title: await room.getRoomName(roomId),
14
+ })));
15
+ setAllowedRooms(rooms);
16
+ }
17
+ catch (err) {
18
+ setError(err instanceof Error ? err : new Error("Failed to fetch allowed rooms"));
19
+ }
20
+ finally {
21
+ setLoading(false);
22
+ }
23
+ }, [room]);
24
+ useEffect(() => {
25
+ refresh();
26
+ }, [refresh]);
27
+ return { allowedRooms, loading, error, refresh };
28
+ }
29
+ //# sourceMappingURL=useAllowedRooms.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useAllowedRooms.js","sourceRoot":"","sources":["../../src/hooks/useAllowedRooms.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAQzD,MAAM,UAAU,eAAe,CAAC,IAAU;IACxC,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAoB,EAAE,CAAC,CAAC;IACxE,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC7C,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAe,IAAI,CAAC,CAAC;IAEvD,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QACrC,UAAU,CAAC,IAAI,CAAC,CAAC;QACjB,QAAQ,CAAC,IAAI,CAAC,CAAC;QACf,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAC3C,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,GAAG,CAC7B,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;gBACzB,MAAM;gBACN,KAAK,EAAE,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC;aACtC,CAAC,CAAC,CACJ,CAAC;YACF,eAAe,CAAC,KAAK,CAAC,CAAC;QACzB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,QAAQ,CACN,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,+BAA+B,CAAC,CACxE,CAAC;QACJ,CAAC;gBAAS,CAAC;YACT,UAAU,CAAC,KAAK,CAAC,CAAC;QACpB,CAAC;IACH,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IAEX,SAAS,CAAC,GAAG,EAAE;QACb,OAAO,EAAE,CAAC;IACZ,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAEd,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AACnD,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { Client, type RoomConfig } from "@may-db/core";
2
+ type AuthState = "loading" | "unauthenticated" | "authenticated";
3
+ export declare function useAuth(config: RoomConfig): {
4
+ state: AuthState;
5
+ client: Client | null;
6
+ error: string | null;
7
+ logout: () => Promise<void>;
8
+ };
9
+ export {};
10
+ //# sourceMappingURL=useAuth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useAuth.d.ts","sourceRoot":"","sources":["../../src/hooks/useAuth.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAA0B,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/E,KAAK,SAAS,GAAG,SAAS,GAAG,iBAAiB,GAAG,eAAe,CAAC;AAEjE,wBAAgB,OAAO,CAAC,MAAM,EAAE,UAAU;;;;;EA2CzC"}
@@ -0,0 +1,43 @@
1
+ import { useState, useEffect, useCallback } from "react";
2
+ import { Client, completeLogin, getAuth } from "@may-db/core";
3
+ export function useAuth(config) {
4
+ const [state, setState] = useState("loading");
5
+ const [client, setClient] = useState(null);
6
+ const [error, setError] = useState(null);
7
+ useEffect(() => {
8
+ async function init() {
9
+ try {
10
+ const callbackAuth = await completeLogin();
11
+ if (callbackAuth) {
12
+ setClient(new Client(callbackAuth, config));
13
+ setState("authenticated");
14
+ return;
15
+ }
16
+ const storedAuth = getAuth();
17
+ if (storedAuth) {
18
+ try {
19
+ setClient(new Client(storedAuth, config));
20
+ setState("authenticated");
21
+ return;
22
+ }
23
+ catch {
24
+ // Stored auth invalid, continue to login
25
+ }
26
+ }
27
+ setState("unauthenticated");
28
+ }
29
+ catch (err) {
30
+ setError(err instanceof Error ? err.message : "Initialization failed");
31
+ setState("unauthenticated");
32
+ }
33
+ }
34
+ init();
35
+ }, [config]);
36
+ const logout = useCallback(async () => {
37
+ await client?.logout();
38
+ setClient(null);
39
+ setState("unauthenticated");
40
+ }, [client]);
41
+ return { state, client, error, logout };
42
+ }
43
+ //# sourceMappingURL=useAuth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useAuth.js","sourceRoot":"","sources":["../../src/hooks/useAuth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AACzD,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,OAAO,EAAmB,MAAM,cAAc,CAAC;AAI/E,MAAM,UAAU,OAAO,CAAC,MAAkB;IACxC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAY,SAAS,CAAC,CAAC;IACzD,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAC1D,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAExD,SAAS,CAAC,GAAG,EAAE;QACb,KAAK,UAAU,IAAI;YACjB,IAAI,CAAC;gBACH,MAAM,YAAY,GAAG,MAAM,aAAa,EAAE,CAAC;gBAC3C,IAAI,YAAY,EAAE,CAAC;oBACjB,SAAS,CAAC,IAAI,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC;oBAC5C,QAAQ,CAAC,eAAe,CAAC,CAAC;oBAC1B,OAAO;gBACT,CAAC;gBAED,MAAM,UAAU,GAAG,OAAO,EAAE,CAAC;gBAC7B,IAAI,UAAU,EAAE,CAAC;oBACf,IAAI,CAAC;wBACH,SAAS,CAAC,IAAI,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;wBAC1C,QAAQ,CAAC,eAAe,CAAC,CAAC;wBAC1B,OAAO;oBACT,CAAC;oBAAC,MAAM,CAAC;wBACP,yCAAyC;oBAC3C,CAAC;gBACH,CAAC;gBAED,QAAQ,CAAC,iBAAiB,CAAC,CAAC;YAC9B,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,QAAQ,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC;gBACvE,QAAQ,CAAC,iBAAiB,CAAC,CAAC;YAC9B,CAAC;QACH,CAAC;QAED,IAAI,EAAE,CAAC;IACT,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAEb,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QACpC,MAAM,MAAM,EAAE,MAAM,EAAE,CAAC;QACvB,SAAS,CAAC,IAAI,CAAC,CAAC;QAChB,QAAQ,CAAC,iBAAiB,CAAC,CAAC;IAC9B,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAEb,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AAC1C,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { MayDb } from "@may-db/core";
2
+ type AuthStatus = "loading" | "unauthenticated" | "authenticated";
3
+ export declare function useMayDb(namespace: string): {
4
+ status: AuthStatus;
5
+ db: MayDb | null;
6
+ error: string | null;
7
+ logout: () => Promise<void>;
8
+ };
9
+ export {};
10
+ //# sourceMappingURL=useMayDb.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useMayDb.d.ts","sourceRoot":"","sources":["../../src/hooks/useMayDb.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAA0B,MAAM,cAAc,CAAC;AAE7D,KAAK,UAAU,GAAG,SAAS,GAAG,iBAAiB,GAAG,eAAe,CAAC;AAElE,wBAAgB,QAAQ,CAAC,SAAS,EAAE,MAAM;;;;;EAgCzC"}
@@ -0,0 +1,32 @@
1
+ import { useState, useEffect, useCallback } from "react";
2
+ import { MayDb, completeLogin, getAuth } from "@may-db/core";
3
+ export function useMayDb(namespace) {
4
+ const [status, setStatus] = useState("loading");
5
+ const [db, setDb] = useState(null);
6
+ const [error, setError] = useState(null);
7
+ useEffect(() => {
8
+ async function init() {
9
+ try {
10
+ const auth = (await completeLogin()) ?? getAuth();
11
+ if (!auth) {
12
+ setStatus("unauthenticated");
13
+ return;
14
+ }
15
+ setDb(new MayDb(auth, namespace));
16
+ setStatus("authenticated");
17
+ }
18
+ catch (err) {
19
+ setError(err instanceof Error ? err.message : "Initialization failed");
20
+ setStatus("unauthenticated");
21
+ }
22
+ }
23
+ init();
24
+ }, [namespace]);
25
+ const logout = useCallback(async () => {
26
+ await db?.logout();
27
+ setDb(null);
28
+ setStatus("unauthenticated");
29
+ }, [db]);
30
+ return { status, db, error, logout };
31
+ }
32
+ //# sourceMappingURL=useMayDb.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useMayDb.js","sourceRoot":"","sources":["../../src/hooks/useMayDb.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AACzD,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAI7D,MAAM,UAAU,QAAQ,CAAC,SAAiB;IACxC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAa,SAAS,CAAC,CAAC;IAC5D,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,GAAG,QAAQ,CAAe,IAAI,CAAC,CAAC;IACjD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAExD,SAAS,CAAC,GAAG,EAAE;QACb,KAAK,UAAU,IAAI;YACjB,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,CAAC,MAAM,aAAa,EAAE,CAAC,IAAI,OAAO,EAAE,CAAC;gBAClD,IAAI,CAAC,IAAI,EAAE,CAAC;oBACV,SAAS,CAAC,iBAAiB,CAAC,CAAC;oBAC7B,OAAO;gBACT,CAAC;gBAED,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC;gBAClC,SAAS,CAAC,eAAe,CAAC,CAAC;YAC7B,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,QAAQ,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC;gBACvE,SAAS,CAAC,iBAAiB,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC;QAED,IAAI,EAAE,CAAC;IACT,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;IAEhB,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QACpC,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC;QACnB,KAAK,CAAC,IAAI,CAAC,CAAC;QACZ,SAAS,CAAC,iBAAiB,CAAC,CAAC;IAC/B,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAET,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AACvC,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { type RemotePresence, type Room } from "@may-db/core";
2
+ /**
3
+ * Hook for managing presence via Matrix to-device messages.
4
+ * Broadcasts local focus changes to room members and receives their presence updates.
5
+ */
6
+ export declare function usePresence({ room }: {
7
+ room: Room;
8
+ }): {
9
+ remotePresences: RemotePresence[];
10
+ setLocalFocus: (focus: string | null) => void;
11
+ };
12
+ export type UsePresenceOptions = Parameters<typeof usePresence>[0];
13
+ //# sourceMappingURL=usePresence.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePresence.d.ts","sourceRoot":"","sources":["../../src/hooks/usePresence.ts"],"names":[],"mappings":"AACA,OAAO,EAML,KAAK,cAAc,EACnB,KAAK,IAAI,EACV,MAAM,cAAc,CAAC;AAItB;;;GAGG;AACH,wBAAgB,WAAW,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,IAAI,CAAA;CAAE;;2BAsCxC,MAAM,GAAG,IAAI;EAkDxB;AAED,MAAM,MAAM,kBAAkB,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC"}
@@ -0,0 +1,78 @@
1
+ import { useState, useEffect, useCallback, useMemo, useRef } from "react";
2
+ import { applyPresenceUpdates, filterRelevantPresenceEvents, getUserColor, PRESENCE_EVENT, } from "@may-db/core";
3
+ const SYNC_POLL_INTERVAL_MS = 2500;
4
+ /**
5
+ * Hook for managing presence via Matrix to-device messages.
6
+ * Broadcasts local focus changes to room members and receives their presence updates.
7
+ */
8
+ export function usePresence({ room }) {
9
+ const roomId = room.roomId;
10
+ const localUserId = room.userId;
11
+ const localUserName = room.userDisplayName || localUserId;
12
+ const localColor = useMemo(() => getUserColor(localUserId), [localUserId]);
13
+ const [remotePresences, setRemotePresences] = useState([]);
14
+ // Track sync token for incremental sync
15
+ const syncTokenRef = useRef(null);
16
+ // Track current local focus to avoid duplicate sends
17
+ const localFocusRef = useRef(null);
18
+ const sendPresence = useCallback(async (focus) => {
19
+ const presence = {
20
+ roomId,
21
+ focus,
22
+ timestamp: Date.now(),
23
+ user: {
24
+ id: localUserId,
25
+ name: localUserName,
26
+ color: localColor,
27
+ },
28
+ };
29
+ try {
30
+ await room.sendToDevice(PRESENCE_EVENT, presence);
31
+ }
32
+ catch (err) {
33
+ console.error("Failed to send presence:", err);
34
+ }
35
+ }, [room, roomId, localUserId, localUserName, localColor]);
36
+ const setLocalFocus = useCallback((focus) => {
37
+ if (localFocusRef.current === focus)
38
+ return;
39
+ localFocusRef.current = focus;
40
+ sendPresence(focus);
41
+ }, [sendPresence]);
42
+ useEffect(() => {
43
+ let stopped = false;
44
+ const poll = async () => {
45
+ try {
46
+ const { events, nextBatch } = await room.pollToDeviceEvents(syncTokenRef.current);
47
+ syncTokenRef.current = nextBatch;
48
+ const updates = filterRelevantPresenceEvents(events, {
49
+ roomId,
50
+ localUserId,
51
+ });
52
+ if (updates.length > 0) {
53
+ setRemotePresences((prev) => applyPresenceUpdates(prev, updates));
54
+ }
55
+ }
56
+ catch (err) {
57
+ console.error("Presence poll error:", err);
58
+ }
59
+ };
60
+ poll();
61
+ const interval = setInterval(() => {
62
+ if (!stopped)
63
+ poll();
64
+ }, SYNC_POLL_INTERVAL_MS);
65
+ return () => {
66
+ stopped = true;
67
+ clearInterval(interval);
68
+ };
69
+ }, [room, roomId, localUserId]);
70
+ // Send null presence when unmounting (leaving room)
71
+ useEffect(() => {
72
+ return () => {
73
+ sendPresence(null);
74
+ };
75
+ }, [sendPresence]);
76
+ return { remotePresences, setLocalFocus };
77
+ }
78
+ //# sourceMappingURL=usePresence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePresence.js","sourceRoot":"","sources":["../../src/hooks/usePresence.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { Room, RoomStatus, RoomMetadata } from "@may-db/core";
2
+ export declare function useRoom(room: Room): {
3
+ room: Room;
4
+ status: RoomStatus;
5
+ isConnected: boolean;
6
+ canWrite: boolean;
7
+ metadata: RoomMetadata | null;
8
+ error: Error | null;
9
+ };
10
+ //# sourceMappingURL=useRoom.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useRoom.d.ts","sourceRoot":"","sources":["../../src/hooks/useRoom.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEnE,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI;;;;;;;EAqCjC"}
@@ -0,0 +1,37 @@
1
+ import { useState, useEffect } from "react";
2
+ export function useRoom(room) {
3
+ const [status, setStatus] = useState(room.status);
4
+ const [canWrite, setCanWrite] = useState(room.canWrite);
5
+ const [metadata, setMetadata] = useState(room.metadata);
6
+ const [error, setError] = useState(null);
7
+ useEffect(() => {
8
+ const unsubscribe = room.subscribe({
9
+ onStatusChange: setStatus,
10
+ onCanWriteChange: setCanWrite,
11
+ onMetadataChange: setMetadata,
12
+ });
13
+ return unsubscribe;
14
+ }, [room]);
15
+ // Auto-connect effect (no cleanup - rooms are cached and stay connected)
16
+ useEffect(() => {
17
+ if (room.isConnected)
18
+ return;
19
+ (async () => {
20
+ try {
21
+ await room.connect();
22
+ }
23
+ catch (err) {
24
+ setError(err instanceof Error ? err : new Error("Failed to connect"));
25
+ }
26
+ })();
27
+ }, [room]);
28
+ return {
29
+ room,
30
+ status,
31
+ isConnected: status === "connected",
32
+ canWrite,
33
+ metadata,
34
+ error,
35
+ };
36
+ }
37
+ //# sourceMappingURL=useRoom.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useRoom.js","sourceRoot":"","sources":["../../src/hooks/useRoom.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAG5C,MAAM,UAAU,OAAO,CAAC,IAAU;IAChC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAa,IAAI,CAAC,MAAM,CAAC,CAAC;IAC9D,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACxD,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAsB,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC7E,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAe,IAAI,CAAC,CAAC;IAEvD,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC;YACjC,cAAc,EAAE,SAAS;YACzB,gBAAgB,EAAE,WAAW;YAC7B,gBAAgB,EAAE,WAAW;SAC9B,CAAC,CAAC;QAEH,OAAO,WAAW,CAAC;IACrB,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IAEX,yEAAyE;IACzE,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,IAAI,CAAC,WAAW;YAAE,OAAO;QAE7B,CAAC,KAAK,IAAI,EAAE;YACV,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;YACvB,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,QAAQ,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC,CAAC;YACxE,CAAC;QACH,CAAC,CAAC,EAAE,CAAC;IACP,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IAEX,OAAO;QACL,IAAI;QACJ,MAAM;QACN,WAAW,EAAE,MAAM,KAAK,WAAW;QACnC,QAAQ;QACR,QAAQ;QACR,KAAK;KACN,CAAC;AACJ,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { Room } from "@may-db/core";
2
+ export interface RoomDelegateInfo {
3
+ roomId: string;
4
+ title: string;
5
+ }
6
+ export declare function useRoomDelegates(room: Room): {
7
+ roomDelegates: RoomDelegateInfo[];
8
+ loading: boolean;
9
+ error: Error | null;
10
+ refresh: () => Promise<void>;
11
+ };
12
+ //# sourceMappingURL=useRoomDelegates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useRoomDelegates.d.ts","sourceRoot":"","sources":["../../src/hooks/useRoomDelegates.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI;;;;;EA+B1C"}
@@ -0,0 +1,29 @@
1
+ import { useState, useEffect, useCallback } from "react";
2
+ export function useRoomDelegates(room) {
3
+ const [roomDelegates, setRoomDelegates] = useState([]);
4
+ const [loading, setLoading] = useState(true);
5
+ const [error, setError] = useState(null);
6
+ const refresh = useCallback(async () => {
7
+ setLoading(true);
8
+ setError(null);
9
+ try {
10
+ const ids = await room.getDelegateRoomIds();
11
+ const rooms = await Promise.all(ids.map(async (roomId) => ({
12
+ roomId,
13
+ title: await room.getRoomName(roomId),
14
+ })));
15
+ setRoomDelegates(rooms);
16
+ }
17
+ catch (err) {
18
+ setError(err instanceof Error ? err : new Error("Failed to fetch room delegates"));
19
+ }
20
+ finally {
21
+ setLoading(false);
22
+ }
23
+ }, [room]);
24
+ useEffect(() => {
25
+ refresh();
26
+ }, [refresh]);
27
+ return { roomDelegates, loading, error, refresh };
28
+ }
29
+ //# sourceMappingURL=useRoomDelegates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useRoomDelegates.js","sourceRoot":"","sources":["../../src/hooks/useRoomDelegates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAQzD,MAAM,UAAU,gBAAgB,CAAC,IAAU;IACzC,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAqB,EAAE,CAAC,CAAC;IAC3E,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC7C,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAe,IAAI,CAAC,CAAC;IAEvD,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QACrC,UAAU,CAAC,IAAI,CAAC,CAAC;QACjB,QAAQ,CAAC,IAAI,CAAC,CAAC;QACf,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC5C,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,GAAG,CAC7B,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;gBACzB,MAAM;gBACN,KAAK,EAAE,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC;aACtC,CAAC,CAAC,CACJ,CAAC;YACF,gBAAgB,CAAC,KAAK,CAAC,CAAC;QAC1B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,QAAQ,CACN,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,gCAAgC,CAAC,CACzE,CAAC;QACJ,CAAC;gBAAS,CAAC;YACT,UAAU,CAAC,KAAK,CAAC,CAAC;QACpB,CAAC;IACH,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IAEX,SAAS,CAAC,GAAG,EAAE;QACb,OAAO,EAAE,CAAC;IACZ,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAEd,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AACpD,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { Room, RoomMember, AccessLevel } from "@may-db/core";
2
+ export declare function useRoomMembers(room: Room): {
3
+ members: RoomMember[];
4
+ loading: boolean;
5
+ error: Error | null;
6
+ refresh: () => Promise<void>;
7
+ invite: (userId: string, access: AccessLevel) => Promise<void>;
8
+ setAccess: (userId: string, access: AccessLevel) => Promise<void>;
9
+ kick: (userId: string) => Promise<void>;
10
+ };
11
+ //# sourceMappingURL=useRoomMembers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useRoomMembers.d.ts","sourceRoot":"","sources":["../../src/hooks/useRoomMembers.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAElE,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI;;;;;qBAyBtB,MAAM,UAAU,WAAW;wBAQ3B,MAAM,UAAU,WAAW;mBAQ3B,MAAM;EAQxB"}
@@ -0,0 +1,37 @@
1
+ import { useState, useEffect, useCallback } from "react";
2
+ export function useRoomMembers(room) {
3
+ const [members, setMembers] = useState([]);
4
+ const [loading, setLoading] = useState(true);
5
+ const [error, setError] = useState(null);
6
+ const refresh = useCallback(async () => {
7
+ setLoading(true);
8
+ setError(null);
9
+ try {
10
+ const memberList = await room.getMembers();
11
+ setMembers(memberList);
12
+ }
13
+ catch (err) {
14
+ setError(err instanceof Error ? err : new Error("Failed to load members"));
15
+ }
16
+ finally {
17
+ setLoading(false);
18
+ }
19
+ }, [room]);
20
+ useEffect(() => {
21
+ refresh();
22
+ }, [refresh]);
23
+ const invite = useCallback(async (userId, access) => {
24
+ await room.invite(userId, access);
25
+ await refresh();
26
+ }, [room, refresh]);
27
+ const setAccess = useCallback(async (userId, access) => {
28
+ await room.setAccess(userId, access);
29
+ await refresh();
30
+ }, [room, refresh]);
31
+ const kick = useCallback(async (userId) => {
32
+ await room.kick(userId);
33
+ await refresh();
34
+ }, [room, refresh]);
35
+ return { members, loading, error, refresh, invite, setAccess, kick };
36
+ }
37
+ //# sourceMappingURL=useRoomMembers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useRoomMembers.js","sourceRoot":"","sources":["../../src/hooks/useRoomMembers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAGzD,MAAM,UAAU,cAAc,CAAC,IAAU;IACvC,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAe,EAAE,CAAC,CAAC;IACzD,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC7C,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAe,IAAI,CAAC,CAAC;IAEvD,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QACrC,UAAU,CAAC,IAAI,CAAC,CAAC;QACjB,QAAQ,CAAC,IAAI,CAAC,CAAC;QACf,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;YAC3C,UAAU,CAAC,UAAU,CAAC,CAAC;QACzB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,QAAQ,CACN,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,wBAAwB,CAAC,CACjE,CAAC;QACJ,CAAC;gBAAS,CAAC;YACT,UAAU,CAAC,KAAK,CAAC,CAAC;QACpB,CAAC;IACH,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IAEX,SAAS,CAAC,GAAG,EAAE;QACb,OAAO,EAAE,CAAC;IACZ,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAEd,MAAM,MAAM,GAAG,WAAW,CACxB,KAAK,EAAE,MAAc,EAAE,MAAmB,EAAE,EAAE;QAC5C,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAClC,MAAM,OAAO,EAAE,CAAC;IAClB,CAAC,EACD,CAAC,IAAI,EAAE,OAAO,CAAC,CAChB,CAAC;IAEF,MAAM,SAAS,GAAG,WAAW,CAC3B,KAAK,EAAE,MAAc,EAAE,MAAmB,EAAE,EAAE;QAC5C,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACrC,MAAM,OAAO,EAAE,CAAC;IAClB,CAAC,EACD,CAAC,IAAI,EAAE,OAAO,CAAC,CAChB,CAAC;IAEF,MAAM,IAAI,GAAG,WAAW,CACtB,KAAK,EAAE,MAAc,EAAE,EAAE;QACvB,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACxB,MAAM,OAAO,EAAE,CAAC;IAClB,CAAC,EACD,CAAC,IAAI,EAAE,OAAO,CAAC,CAChB,CAAC;IAEF,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;AACvE,CAAC"}
@@ -0,0 +1,7 @@
1
+ export { useMayDb } from "./hooks/useMayDb";
2
+ export { useRoomDelegates, type RoomDelegateInfo } from "./hooks/useRoomDelegates";
3
+ export { usePresence, type UsePresenceOptions } from "./hooks/usePresence";
4
+ export { useRoom } from "./hooks/useRoom";
5
+ export { useRoomMembers } from "./hooks/useRoomMembers";
6
+ export { PRESENCE_EVENT, type PresenceContent, type RemotePresence, } from "@may-db/core";
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,KAAK,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACnF,OAAO,EAAE,WAAW,EAAE,KAAK,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC3E,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EACL,cAAc,EACd,KAAK,eAAe,EACpB,KAAK,cAAc,GACpB,MAAM,cAAc,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ export { useMayDb } from "./hooks/useMayDb";
2
+ export { useRoomDelegates } from "./hooks/useRoomDelegates";
3
+ export { usePresence } from "./hooks/usePresence";
4
+ export { useRoom } from "./hooks/useRoom";
5
+ export { useRoomMembers } from "./hooks/useRoomMembers";
6
+ export { PRESENCE_EVENT, } from "@may-db/core";
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAyB,MAAM,0BAA0B,CAAC;AACnF,OAAO,EAAE,WAAW,EAA2B,MAAM,qBAAqB,CAAC;AAC3E,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EACL,cAAc,GAGf,MAAM,cAAc,CAAC"}
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "@may-db/react",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "dependencies": {
18
+ "@may-db/core": "0.1.0"
19
+ },
20
+ "peerDependencies": {
21
+ "react": "^18.0.0 || ^19.0.0"
22
+ },
23
+ "devDependencies": {
24
+ "@types/react": "^18.3.18",
25
+ "eslint": "^9.39.1",
26
+ "react": "^18.3.1",
27
+ "typescript": "~5.9.3"
28
+ },
29
+ "scripts": {
30
+ "build": "tsc -p tsconfig.json",
31
+ "lint": "eslint src"
32
+ }
33
+ }