@liveblocks/react
Version:
A set of React hooks and providers to use Liveblocks declaratively. Liveblocks is the all-in-one toolkit to build collaborative products like Figma, Notion, and more.
180 lines (176 loc) • 5.34 kB
JavaScript
import {
getUmbrellaStoreForClient,
useAddRoomCommentReaction,
useClient,
useClientOrNull,
useCreateRoomComment,
useCreateRoomThread,
useCreateTextMention,
useDeleteRoomComment,
useDeleteRoomThread,
useDeleteTextMention,
useEditRoomComment,
useEditRoomThreadMetadata,
useLatest,
useMarkRoomThreadAsRead,
useMarkRoomThreadAsResolved,
useMarkRoomThreadAsUnresolved,
useMentionSuggestionsCache,
useRemoveRoomCommentReaction,
useReportTextEditor,
useResolveMentionSuggestions,
useRoomAttachmentUrl,
useRoomPermissions,
useRoomThreadSubscription,
useSignal,
useSyncExternalStoreWithSelector,
useYjsProvider
} from "./chunk-JOZ4BQWH.js";
// src/lib/use-layout-effect.ts
import { useEffect, useLayoutEffect as useOriginalLayoutEffect } from "react";
var useLayoutEffect = typeof window !== "undefined" ? useOriginalLayoutEffect : useEffect;
// src/use-group.ts
import {
kInternal,
shallow
} from "@liveblocks/core";
import { useCallback, useEffect as useEffect2 } from "react";
function selectorFor_useGroup(state) {
if (state === void 0 || state?.isLoading) {
return state ?? { isLoading: true };
}
if (state.error) {
return state;
}
return {
isLoading: false,
group: state.data
};
}
function useGroup(groupId) {
const client = useClient();
const store = client[kInternal].httpClient.groupsStore;
const getGroupState = useCallback(
() => store.getItemState(groupId),
[store, groupId]
);
useEffect2(() => {
void store.enqueue(groupId);
}, [store, groupId]);
return useSyncExternalStoreWithSelector(
store.subscribe,
getGroupState,
getGroupState,
selectorFor_useGroup,
shallow
);
}
// src/use-mention-suggestions.ts
import { stableStringify } from "@liveblocks/core";
import { useEffect as useEffect3, useRef, useState } from "react";
var MENTION_SUGGESTIONS_DEBOUNCE = 500;
function normalizeMentionSuggestions(suggestions) {
return suggestions.map(
(suggestion) => typeof suggestion === "string" ? { kind: "user", id: suggestion } : suggestion
);
}
function useMentionSuggestions(roomId, search) {
const [mentionSuggestions, setMentionSuggestions] = useState();
const lastInvokedAt = useRef();
const resolveMentionSuggestions = useResolveMentionSuggestions();
const mentionSuggestionsCache = useMentionSuggestionsCache();
useEffect3(() => {
if (search === void 0 || !resolveMentionSuggestions) {
return;
}
const resolveMentionSuggestionsArgs = { text: search, roomId };
const mentionSuggestionsCacheKey = stableStringify(
resolveMentionSuggestionsArgs
);
let debounceTimeout;
let isCanceled = false;
const getMentionSuggestions = async () => {
try {
lastInvokedAt.current = performance.now();
const rawMentionSuggestions = await resolveMentionSuggestions(
resolveMentionSuggestionsArgs
);
if (!isCanceled) {
const normalizedSuggestions = normalizeMentionSuggestions(
rawMentionSuggestions
);
setMentionSuggestions(normalizedSuggestions);
mentionSuggestionsCache.set(
mentionSuggestionsCacheKey,
normalizedSuggestions
);
}
} catch (error) {
console.error(error?.message);
}
};
if (mentionSuggestionsCache.has(mentionSuggestionsCacheKey)) {
const cachedSuggestions = mentionSuggestionsCache.get(
mentionSuggestionsCacheKey
);
setMentionSuggestions(cachedSuggestions);
} else if (!lastInvokedAt.current || Math.abs(performance.now() - lastInvokedAt.current) > MENTION_SUGGESTIONS_DEBOUNCE) {
void getMentionSuggestions();
} else {
debounceTimeout = window.setTimeout(() => {
void getMentionSuggestions();
}, MENTION_SUGGESTIONS_DEBOUNCE);
}
return () => {
isCanceled = true;
window.clearTimeout(debounceTimeout);
};
}, [search, roomId, resolveMentionSuggestions, mentionSuggestionsCache]);
return mentionSuggestions;
}
// src/use-sync-source.ts
import { kInternal as kInternal2 } from "@liveblocks/core";
import { useEffect as useEffect4, useState as useState2 } from "react";
function useSyncSource() {
const client = useClient();
const createSyncSource = client[kInternal2].createSyncSource;
const [syncSource, setSyncSource] = useState2();
useEffect4(() => {
const newSyncSource = createSyncSource();
setSyncSource(newSyncSource);
return () => newSyncSource.destroy();
}, [createSyncSource]);
return syncSource;
}
export {
getUmbrellaStoreForClient,
useAddRoomCommentReaction,
useClientOrNull,
useCreateRoomComment,
useCreateRoomThread,
useCreateTextMention,
useDeleteRoomComment,
useDeleteRoomThread,
useDeleteTextMention,
useEditRoomComment,
useEditRoomThreadMetadata,
useGroup,
useLatest,
useLayoutEffect,
useMarkRoomThreadAsRead,
useMarkRoomThreadAsResolved,
useMarkRoomThreadAsUnresolved,
useMentionSuggestions,
useMentionSuggestionsCache,
useRemoveRoomCommentReaction,
useReportTextEditor,
useResolveMentionSuggestions,
useRoomAttachmentUrl,
useRoomPermissions,
useRoomThreadSubscription,
useSignal,
useSyncExternalStoreWithSelector,
useSyncSource,
useYjsProvider
};
//# sourceMappingURL=_private.js.map