@liveblocks/react 1.2.0-internal6 → 1.2.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.
package/dist/index.js CHANGED
@@ -1,4 +1,12 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }// src/ClientSideSuspense.tsx
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }// src/index.ts
2
+ var _core = require('@liveblocks/core');
3
+
4
+ // src/version.ts
5
+ var PKG_NAME = "@liveblocks/react";
6
+ var PKG_VERSION = "1.2.0";
7
+ var PKG_FORMAT = "cjs";
8
+
9
+ // src/ClientSideSuspense.tsx
2
10
  var _react = require('react'); var React = _interopRequireWildcard(_react); var React2 = _interopRequireWildcard(_react);
3
11
  function ClientSideSuspense(props) {
4
12
  const [mounted, setMounted] = React.useState(false);
@@ -14,7 +22,7 @@ var _client = require('@liveblocks/client');
14
22
 
15
23
 
16
24
 
17
- var _core = require('@liveblocks/core');
25
+
18
26
 
19
27
  var _withselectorjs = require('use-sync-external-store/shim/with-selector.js');
20
28
 
@@ -79,7 +87,7 @@ function makeMutationContext(room) {
79
87
  },
80
88
  get others() {
81
89
  const others = room.getOthers();
82
- if (!room.isSelfAware()) {
90
+ if (room.getSelf() === null) {
83
91
  throw new Error(errmsg);
84
92
  }
85
93
  return others;
@@ -164,7 +172,7 @@ function createRoomContext(client) {
164
172
  }
165
173
  function useMyPresence() {
166
174
  const room = useRoom();
167
- const subscribe = room.events.me.subscribe;
175
+ const subscribe = room.events.myPresence.subscribe;
168
176
  const getSnapshot = room.getPresence;
169
177
  const presence = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
170
178
  const setPresence = room.updatePresence;
@@ -285,17 +293,7 @@ function createRoomContext(client) {
285
293
  }
286
294
  function useSelf(maybeSelector, isEqual) {
287
295
  const room = useRoom();
288
- const subscribe = React2.useCallback(
289
- (onChange) => {
290
- const unsub1 = room.events.me.subscribe(onChange);
291
- const unsub2 = room.events.connection.subscribe(onChange);
292
- return () => {
293
- unsub1();
294
- unsub2();
295
- };
296
- },
297
- [room]
298
- );
296
+ const subscribe = room.events.self.subscribe;
299
297
  const getSnapshot = room.getSelf;
300
298
  const selector = _nullishCoalesce(maybeSelector, () => ( identity));
301
299
  const wrappedSelector = React2.useCallback(
@@ -437,12 +435,12 @@ function createRoomContext(client) {
437
435
  }
438
436
  function useSuspendUntilPresenceLoaded() {
439
437
  const room = useRoom();
440
- if (room.isSelfAware()) {
438
+ if (room.getSelf() !== null) {
441
439
  return;
442
440
  }
443
441
  ensureNotServerSide();
444
442
  throw new Promise((res) => {
445
- room.events.connection.subscribeOnce(() => res());
443
+ room.events.status.subscribeOnce(() => res());
446
444
  });
447
445
  }
448
446
  function useMutation(callback, deps) {
@@ -567,6 +565,7 @@ function createRoomContext(client) {
567
565
 
568
566
  // src/index.ts
569
567
 
568
+ _core.detectDupes.call(void 0, PKG_NAME, PKG_VERSION, PKG_FORMAT);
570
569
 
571
570
 
572
571
 
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/ClientSideSuspense.tsx","../src/factory.tsx","../src/hooks.ts","../src/index.ts"],"names":["React","other","rootOrNull","shallow"],"mappings":"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","sourcesContent":["import type { ReactElement, ReactNode } from \"react\";\nimport * as React from \"react\";\n\ntype Props = {\n fallback: NonNullable<ReactNode> | null;\n children: () => ReactNode | undefined;\n};\n\n/**\n * Almost like a normal <Suspense> component, except that for server-side\n * renders, the fallback will be used.\n *\n * The child props will have to be provided in a function, i.e. change:\n *\n * <Suspense fallback={<Loading />}>\n * <MyRealComponent a={1} />\n * </Suspense>\n *\n * To:\n *\n * <ClientSideSuspense fallback={<Loading />}>\n * {() => <MyRealComponent a={1} />}\n * </ClientSideSuspense>\n *\n */\nexport function ClientSideSuspense(props: Props): ReactElement {\n const [mounted, setMounted] = React.useState(false);\n\n React.useEffect(() => {\n // Effects are never executed on the server side. The point of this is to\n // delay the flipping of this boolean until after hydration has happened.\n setMounted(true);\n }, []);\n\n return (\n <React.Suspense fallback={props.fallback}>\n {mounted ? props.children() : props.fallback}\n </React.Suspense>\n );\n}\n","import type {\n BaseUserMeta,\n BroadcastOptions,\n Client,\n History,\n Json,\n JsonObject,\n LiveObject,\n LostConnectionEvent,\n LsonObject,\n Others,\n Room,\n Status,\n User,\n} from \"@liveblocks/client\";\nimport { shallow } from \"@liveblocks/client\";\nimport type { ToImmutable } from \"@liveblocks/core\";\nimport {\n asArrayWithLegacyMethods,\n deprecateIf,\n errorIf,\n} from \"@liveblocks/core\";\nimport * as React from \"react\";\nimport { useSyncExternalStoreWithSelector } from \"use-sync-external-store/shim/with-selector.js\";\n\nimport { useInitial, useRerender } from \"./hooks\";\nimport type {\n MutationContext,\n OmitFirstArg,\n RoomContextBundle,\n RoomProviderProps,\n} from \"./types\";\n\nconst noop = () => {};\nconst identity: <T>(x: T) => T = (x) => x;\n\nconst missing_unstable_batchedUpdates = (\n reactVersion: number,\n roomId: string\n) =>\n `We noticed you’re using React ${reactVersion}. Please pass unstable_batchedUpdates at the RoomProvider level until you’re ready to upgrade to React 18:\n\n import { unstable_batchedUpdates } from \"react-dom\"; // or \"react-native\"\n\n <RoomProvider id=${JSON.stringify(\n roomId\n )} ... unstable_batchedUpdates={unstable_batchedUpdates}>\n ...\n </RoomProvider>\n\nWhy? Please see https://liveblocks.io/docs/guides/troubleshooting#stale-props-zombie-child for more information`;\n\nconst superfluous_unstable_batchedUpdates =\n \"You don’t need to pass unstable_batchedUpdates to RoomProvider anymore, since you’re on React 18+ already.\";\n\nfunction useSyncExternalStore<Snapshot>(\n s: (onStoreChange: () => void) => () => void,\n gs: () => Snapshot,\n gss: undefined | null | (() => Snapshot)\n): Snapshot {\n return useSyncExternalStoreWithSelector(s, gs, gss, identity);\n}\n\nconst EMPTY_OTHERS =\n // NOTE: asArrayWithLegacyMethods() wrapping should no longer be necessary in 0.19\n asArrayWithLegacyMethods([]);\n\nfunction getEmptyOthers() {\n return EMPTY_OTHERS;\n}\n\nfunction makeMutationContext<\n TPresence extends JsonObject,\n TStorage extends LsonObject,\n TUserMeta extends BaseUserMeta,\n TRoomEvent extends Json,\n>(\n room: Room<TPresence, TStorage, TUserMeta, TRoomEvent>\n): MutationContext<TPresence, TStorage, TUserMeta> {\n const errmsg =\n \"This mutation cannot be used until connected to the Liveblocks room\";\n\n return {\n get storage() {\n const mutableRoot = room.getStorageSnapshot();\n if (mutableRoot === null) {\n throw new Error(errmsg);\n }\n return mutableRoot;\n },\n\n get self() {\n const self = room.getSelf();\n // NOTE: We could use room.isSelfAware() here to keep the check\n // consistent with `others`, but we also want to refine the `null` case\n // away here.\n if (self === null) {\n throw new Error(errmsg);\n }\n return self;\n },\n\n get others() {\n const others = room.getOthers();\n if (!room.isSelfAware()) {\n throw new Error(errmsg);\n }\n return others;\n },\n\n setMyPresence: room.updatePresence,\n };\n}\n\nexport function createRoomContext<\n TPresence extends JsonObject,\n TStorage extends LsonObject = LsonObject,\n TUserMeta extends BaseUserMeta = BaseUserMeta,\n TRoomEvent extends Json = never,\n>(\n client: Client\n): RoomContextBundle<TPresence, TStorage, TUserMeta, TRoomEvent> {\n const RoomContext = React.createContext<Room<\n TPresence,\n TStorage,\n TUserMeta,\n TRoomEvent\n > | null>(null);\n\n function RoomProvider(props: RoomProviderProps<TPresence, TStorage>) {\n const {\n id: roomId,\n initialPresence,\n initialStorage,\n unstable_batchedUpdates,\n shouldInitiallyConnect,\n } = props;\n\n if (process.env.NODE_ENV !== \"production\") {\n if (!roomId) {\n throw new Error(\n \"RoomProvider id property is required. For more information: https://liveblocks.io/docs/errors/liveblocks-react/RoomProvider-id-property-is-required\"\n );\n }\n\n if (typeof roomId !== \"string\") {\n throw new Error(\"RoomProvider id property should be a string.\");\n }\n\n const majorReactVersion = parseInt(React.version) || 1;\n const oldReactVersion = majorReactVersion < 18;\n errorIf(\n oldReactVersion && props.unstable_batchedUpdates === undefined,\n missing_unstable_batchedUpdates(majorReactVersion, roomId)\n );\n deprecateIf(\n !oldReactVersion && props.unstable_batchedUpdates !== undefined,\n superfluous_unstable_batchedUpdates\n );\n }\n\n // Note: We'll hold on to the initial value given here, and ignore any\n // changes to this argument in subsequent renders\n const frozen = useInitial({\n initialPresence,\n initialStorage,\n unstable_batchedUpdates,\n shouldInitiallyConnect:\n shouldInitiallyConnect === undefined\n ? typeof window !== \"undefined\"\n : shouldInitiallyConnect,\n });\n\n const [room, setRoom] = React.useState<\n Room<TPresence, TStorage, TUserMeta, TRoomEvent>\n >(() =>\n client.enter(roomId, {\n initialPresence: frozen.initialPresence,\n initialStorage: frozen.initialStorage,\n shouldInitiallyConnect: frozen.shouldInitiallyConnect,\n unstable_batchedUpdates: frozen.unstable_batchedUpdates,\n })\n );\n\n React.useEffect(() => {\n setRoom(\n client.enter(roomId, {\n initialPresence: frozen.initialPresence,\n initialStorage: frozen.initialStorage,\n shouldInitiallyConnect: frozen.shouldInitiallyConnect,\n unstable_batchedUpdates: frozen.unstable_batchedUpdates,\n })\n );\n\n return () => {\n client.leave(roomId);\n };\n }, [roomId, frozen]);\n\n return (\n <RoomContext.Provider value={room}>{props.children}</RoomContext.Provider>\n );\n }\n\n function connectionIdSelector(\n others: Others<TPresence, TUserMeta>\n ): number[] {\n return others.map((user) => user.connectionId);\n }\n\n function useRoom(): Room<TPresence, TStorage, TUserMeta, TRoomEvent> {\n const room = React.useContext(RoomContext);\n if (room === null) {\n throw new Error(\"RoomProvider is missing from the react tree\");\n }\n return room;\n }\n\n function useStatus(): Status {\n const room = useRoom();\n const subscribe = room.events.status.subscribe;\n const getSnapshot = room.getStatus;\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n }\n\n function useMyPresence(): [\n TPresence,\n (patch: Partial<TPresence>, options?: { addToHistory: boolean }) => void,\n ] {\n const room = useRoom();\n const subscribe = room.events.me.subscribe;\n const getSnapshot = room.getPresence;\n const presence = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n const setPresence = room.updatePresence;\n return [presence, setPresence];\n }\n\n function useUpdateMyPresence(): (\n patch: Partial<TPresence>,\n options?: { addToHistory: boolean }\n ) => void {\n return useRoom().updatePresence;\n }\n\n function useOthers(): Others<TPresence, TUserMeta>;\n function useOthers<T>(\n selector: (others: Others<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T;\n function useOthers<T>(\n selector?: (others: Others<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T | Others<TPresence, TUserMeta> {\n const room = useRoom();\n const subscribe = room.events.others.subscribe;\n const getSnapshot = room.getOthers;\n const getServerSnapshot = getEmptyOthers;\n return useSyncExternalStoreWithSelector(\n subscribe,\n getSnapshot,\n getServerSnapshot,\n selector ?? (identity as (others: Others<TPresence, TUserMeta>) => T),\n isEqual\n );\n }\n\n function useOthersConnectionIds(): readonly number[] {\n return useOthers(connectionIdSelector, shallow);\n }\n\n function useOthersMapped<T>(\n itemSelector: (other: User<TPresence, TUserMeta>) => T,\n itemIsEqual?: (prev: T, curr: T) => boolean\n ): ReadonlyArray<readonly [connectionId: number, data: T]> {\n const wrappedSelector = React.useCallback(\n (others: Others<TPresence, TUserMeta>) =>\n others.map(\n (other) => [other.connectionId, itemSelector(other)] as const\n ),\n [itemSelector]\n );\n\n const wrappedIsEqual = React.useCallback(\n (\n a: ReadonlyArray<readonly [connectionId: number, data: T]>,\n b: ReadonlyArray<readonly [connectionId: number, data: T]>\n ): boolean => {\n const eq = itemIsEqual ?? Object.is;\n return (\n a.length === b.length &&\n a.every((atuple, index) => {\n const btuple = b[index];\n return atuple[0] === btuple[0] && eq(atuple[1], btuple[1]);\n })\n );\n },\n [itemIsEqual]\n );\n\n return useOthers(wrappedSelector, wrappedIsEqual);\n }\n\n const NOT_FOUND = Symbol();\n\n type NotFound = typeof NOT_FOUND;\n\n function useOther<T>(\n connectionId: number,\n selector: (other: User<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T {\n const wrappedSelector = React.useCallback(\n (others: Others<TPresence, TUserMeta>) => {\n // TODO: Make this O(1) instead of O(n)?\n const other = others.find(\n (other) => other.connectionId === connectionId\n );\n return other !== undefined ? selector(other) : NOT_FOUND;\n },\n [connectionId, selector]\n );\n\n const wrappedIsEqual = React.useCallback(\n (prev: T | NotFound, curr: T | NotFound): boolean => {\n if (prev === NOT_FOUND || curr === NOT_FOUND) {\n return prev === curr;\n }\n\n const eq = isEqual ?? Object.is;\n return eq(prev, curr);\n },\n [isEqual]\n );\n\n const other = useOthers(wrappedSelector, wrappedIsEqual);\n if (other === NOT_FOUND) {\n throw new Error(\n `No such other user with connection id ${connectionId} exists`\n );\n }\n\n return other;\n }\n\n function useBroadcastEvent(): (\n event: TRoomEvent,\n options?: BroadcastOptions\n ) => void {\n const room = useRoom();\n\n return React.useCallback(\n (\n event: TRoomEvent,\n options: BroadcastOptions = { shouldQueueEventIfNotReady: false }\n ) => {\n room.broadcastEvent(event, options);\n },\n [room]\n );\n }\n\n function useLostConnectionListener(\n callback: (event: LostConnectionEvent) => void\n ): void {\n const room = useRoom();\n const savedCallback = React.useRef(callback);\n\n React.useEffect(() => {\n savedCallback.current = callback;\n });\n\n React.useEffect(\n () =>\n room.events.lostConnection.subscribe((event: LostConnectionEvent) =>\n savedCallback.current(event)\n ),\n [room]\n );\n }\n\n function useErrorListener(callback: (err: Error) => void): void {\n const room = useRoom();\n const savedCallback = React.useRef(callback);\n\n React.useEffect(() => {\n savedCallback.current = callback;\n });\n\n React.useEffect(\n () => room.events.error.subscribe((e: Error) => savedCallback.current(e)),\n [room]\n );\n }\n\n function useEventListener(\n callback: (eventData: { connectionId: number; event: TRoomEvent }) => void\n ): void {\n const room = useRoom();\n const savedCallback = React.useRef(callback);\n\n React.useEffect(() => {\n savedCallback.current = callback;\n });\n\n React.useEffect(() => {\n const listener = (eventData: {\n connectionId: number;\n event: TRoomEvent;\n }) => {\n savedCallback.current(eventData);\n };\n\n return room.events.customEvent.subscribe(listener);\n }, [room]);\n }\n\n function useSelf(): User<TPresence, TUserMeta> | null;\n function useSelf<T>(\n selector: (me: User<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T | null, curr: T | null) => boolean\n ): T | null;\n function useSelf<T>(\n maybeSelector?: (me: User<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T | null, curr: T | null) => boolean\n ): T | User<TPresence, TUserMeta> | null {\n type Snapshot = User<TPresence, TUserMeta> | null;\n type Selection = T | null;\n\n const room = useRoom();\n\n const subscribe = React.useCallback(\n (onChange: () => void) => {\n const unsub1 = room.events.me.subscribe(onChange);\n const unsub2 = room.events.connection.subscribe(onChange);\n return () => {\n unsub1();\n unsub2();\n };\n },\n [room]\n );\n\n const getSnapshot: () => Snapshot = room.getSelf;\n\n const selector =\n maybeSelector ?? (identity as (me: User<TPresence, TUserMeta>) => T);\n\n const wrappedSelector = React.useCallback(\n (me: Snapshot): Selection => (me !== null ? selector(me) : null),\n [selector]\n );\n\n const getServerSnapshot = React.useCallback((): Snapshot => null, []);\n\n return useSyncExternalStoreWithSelector(\n subscribe,\n getSnapshot,\n getServerSnapshot,\n wrappedSelector,\n isEqual\n );\n }\n\n function useMutableStorageRoot(): LiveObject<TStorage> | null {\n type Snapshot = LiveObject<TStorage> | null;\n const room = useRoom();\n const subscribe = room.events.storageDidLoad.subscribeOnce;\n const getSnapshot = room.getStorageSnapshot;\n const getServerSnapshot = React.useCallback((): Snapshot => null, []);\n return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n }\n\n // NOTE: This API exists for backward compatible reasons\n function useStorageRoot(): [root: LiveObject<TStorage> | null] {\n return [useMutableStorageRoot()];\n }\n\n function useHistory(): History {\n return useRoom().history;\n }\n\n function useUndo(): () => void {\n return useHistory().undo;\n }\n\n function useRedo(): () => void {\n return useHistory().redo;\n }\n\n function useCanUndo(): boolean {\n const room = useRoom();\n const subscribe = room.events.history.subscribe;\n const canUndo = room.history.canUndo;\n return useSyncExternalStore(subscribe, canUndo, canUndo);\n }\n\n function useCanRedo(): boolean {\n const room = useRoom();\n const subscribe = room.events.history.subscribe;\n const canRedo = room.history.canRedo;\n return useSyncExternalStore(subscribe, canRedo, canRedo);\n }\n\n function useBatch<T>(): (callback: () => T) => T {\n return useRoom().batch;\n }\n\n function useLegacyKey<TKey extends Extract<keyof TStorage, string>>(\n key: TKey\n ): TStorage[TKey] | null {\n const room = useRoom();\n const root = useMutableStorageRoot();\n const rerender = useRerender();\n\n React.useEffect(() => {\n if (root === null) {\n return;\n }\n\n let liveValue = root.get(key);\n\n function onRootChange() {\n const newCrdt = root!.get(key);\n if (newCrdt !== liveValue) {\n unsubscribeCrdt();\n liveValue = newCrdt;\n unsubscribeCrdt = room.subscribe(\n liveValue as any /* AbstractCrdt */, // TODO: This is hiding a bug! If `liveValue` happens to be the string `\"event\"` this actually subscribes an event handler!\n rerender\n );\n rerender();\n }\n }\n\n let unsubscribeCrdt = room.subscribe(\n liveValue as any /* AbstractCrdt */, // TODO: This is hiding a bug! If `liveValue` happens to be the string `\"event\"` this actually subscribes an event handler!\n rerender\n );\n const unsubscribeRoot = room.subscribe(\n root as any /* AbstractCrdt */, // TODO: This is hiding a bug! If `liveValue` happens to be the string `\"event\"` this actually subscribes an event handler!\n onRootChange\n );\n\n rerender();\n\n return () => {\n unsubscribeRoot();\n unsubscribeCrdt();\n };\n }, [root, room, key, rerender]);\n\n if (root === null) {\n return null;\n } else {\n return root.get(key);\n }\n }\n\n function useStorage<T>(\n selector: (root: ToImmutable<TStorage>) => T,\n isEqual?: (prev: T | null, curr: T | null) => boolean\n ): T | null {\n type Snapshot = ToImmutable<TStorage> | null;\n type Selection = T | null;\n\n const room = useRoom();\n const rootOrNull = useMutableStorageRoot();\n\n const wrappedSelector = React.useCallback(\n (rootOrNull: Snapshot): Selection =>\n rootOrNull !== null ? selector(rootOrNull) : null,\n [selector]\n );\n\n const subscribe = React.useCallback(\n (onStoreChange: () => void) =>\n rootOrNull !== null\n ? room.subscribe(rootOrNull, onStoreChange, { isDeep: true })\n : noop,\n [room, rootOrNull]\n );\n\n const getSnapshot = React.useCallback((): Snapshot => {\n if (rootOrNull === null) {\n return null;\n } else {\n const root = rootOrNull;\n const imm = root.toImmutable();\n return imm;\n }\n }, [rootOrNull]);\n\n const getServerSnapshot = React.useCallback((): Snapshot => null, []);\n\n return useSyncExternalStoreWithSelector(\n subscribe,\n getSnapshot,\n getServerSnapshot,\n wrappedSelector,\n isEqual\n );\n }\n\n function ensureNotServerSide(): void {\n // Error early if suspense is used in a server-side context\n if (typeof window === \"undefined\") {\n throw new Error(\n \"You cannot use the Suspense version of this hook on the server side. Make sure to only call them on the client side.\\nFor tips, see https://liveblocks.io/docs/api-reference/liveblocks-react#suspense-avoid-ssr\"\n );\n }\n }\n\n function useSuspendUntilStorageLoaded(): void {\n const room = useRoom();\n if (room.getStorageSnapshot() !== null) {\n return;\n }\n\n ensureNotServerSide();\n\n // Throw a _promise_. Suspense will suspend the component tree until this\n // promise resolves (aka until storage has loaded). After that, it will\n // render this component tree again.\n throw new Promise<void>((res) => {\n room.events.storageDidLoad.subscribeOnce(() => res());\n });\n }\n\n function useSuspendUntilPresenceLoaded(): void {\n const room = useRoom();\n if (room.isSelfAware()) {\n return;\n }\n\n ensureNotServerSide();\n\n // Throw a _promise_. Suspense will suspend the component tree until this\n // promise resolves (aka until storage has loaded). After that, it will\n // render this component tree again.\n throw new Promise<void>((res) => {\n room.events.connection.subscribeOnce(() => res());\n });\n }\n\n function useMutation<\n F extends (\n context: MutationContext<TPresence, TStorage, TUserMeta>,\n ...args: any[]\n ) => any,\n >(callback: F, deps: readonly unknown[]): OmitFirstArg<F> {\n const room = useRoom();\n return React.useMemo(\n () => {\n return ((...args) =>\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n room.batch(() =>\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n callback(\n makeMutationContext(room),\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n ...args\n )\n )) as OmitFirstArg<F>;\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [room, ...deps]\n );\n }\n\n function useStorageSuspense<T>(\n selector: (root: ToImmutable<TStorage>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T {\n useSuspendUntilStorageLoaded();\n return useStorage(\n selector,\n isEqual as (prev: T | null, curr: T | null) => boolean\n ) as T;\n }\n\n function useSelfSuspense(): User<TPresence, TUserMeta>;\n function useSelfSuspense<T>(\n selector: (me: User<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T;\n function useSelfSuspense<T>(\n selector?: (me: User<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T | User<TPresence, TUserMeta> {\n useSuspendUntilPresenceLoaded();\n return useSelf(\n selector as (me: User<TPresence, TUserMeta>) => T,\n isEqual as (prev: T | null, curr: T | null) => boolean\n ) as T | User<TPresence, TUserMeta>;\n }\n\n function useOthersSuspense<T>(\n selector?: (others: Others<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T | Others<TPresence, TUserMeta> {\n useSuspendUntilPresenceLoaded();\n return useOthers(\n selector as (others: Others<TPresence, TUserMeta>) => T,\n isEqual as (prev: T, curr: T) => boolean\n ) as T | Others<TPresence, TUserMeta>;\n }\n\n function useOthersConnectionIdsSuspense(): readonly number[] {\n useSuspendUntilPresenceLoaded();\n return useOthersConnectionIds();\n }\n\n function useOthersMappedSuspense<T>(\n itemSelector: (other: User<TPresence, TUserMeta>) => T,\n itemIsEqual?: (prev: T, curr: T) => boolean\n ): ReadonlyArray<readonly [connectionId: number, data: T]> {\n useSuspendUntilPresenceLoaded();\n return useOthersMapped(itemSelector, itemIsEqual);\n }\n\n function useOtherSuspense<T>(\n connectionId: number,\n selector: (other: User<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T {\n useSuspendUntilPresenceLoaded();\n return useOther(connectionId, selector, isEqual);\n }\n\n function useLegacyKeySuspense<TKey extends Extract<keyof TStorage, string>>(\n key: TKey\n ): TStorage[TKey] {\n useSuspendUntilStorageLoaded();\n return useLegacyKey(key) as TStorage[TKey];\n }\n\n return {\n RoomContext,\n RoomProvider,\n\n useRoom,\n useStatus,\n\n useBatch,\n useBroadcastEvent,\n useLostConnectionListener,\n useErrorListener,\n useEventListener,\n\n useHistory,\n useUndo,\n useRedo,\n useCanRedo,\n useCanUndo,\n\n // These are just aliases. The passed-in key will define their return values.\n useList: useLegacyKey,\n useMap: useLegacyKey,\n useObject: useLegacyKey,\n\n useStorageRoot,\n useStorage,\n\n useSelf,\n useMyPresence,\n useUpdateMyPresence,\n useOthers,\n useOthersMapped,\n useOthersConnectionIds,\n useOther,\n\n useMutation,\n\n suspense: {\n RoomContext,\n RoomProvider,\n\n useRoom,\n useStatus,\n\n useBatch,\n useBroadcastEvent,\n useLostConnectionListener,\n useErrorListener,\n useEventListener,\n\n useHistory,\n useUndo,\n useRedo,\n useCanRedo,\n useCanUndo,\n\n // Legacy hooks\n useList: useLegacyKeySuspense,\n useMap: useLegacyKeySuspense,\n useObject: useLegacyKeySuspense,\n\n useStorageRoot,\n useStorage: useStorageSuspense,\n\n useSelf: useSelfSuspense,\n useMyPresence,\n useUpdateMyPresence,\n useOthers: useOthersSuspense,\n useOthersMapped: useOthersMappedSuspense,\n useOthersConnectionIds: useOthersConnectionIdsSuspense,\n useOther: useOtherSuspense,\n\n useMutation,\n },\n };\n}\n","import { useReducer, useRef } from \"react\";\n\n/**\n * Trigger a re-render programmatically, without changing the component's\n * state.\n *\n * Usage:\n *\n * const rerender = useRerender();\n * return (\n * <button onClick={rerender}>\n * {Math.random()}\n * </button>\n * )\n *\n */\nexport function useRerender(): () => void {\n const [, update] = useReducer(\n // This implementation works by incrementing a hidden counter value that is\n // never consumed. Simply incrementing the counter changes the component's\n // state and, thus, trigger a re-render.\n (x: number): number => x + 1,\n 0\n );\n return update;\n}\n\n/**\n * \"Freezes\" a given value, so that it will return the same value/instance on\n * each subsequent render. This can be used to freeze \"initial\" values for\n * custom hooks, much like how `useState(initialState)` or\n * `useRef(initialValue)` works.\n */\nexport function useInitial<T>(value: T): T {\n return useRef(value).current;\n}\n","export { ClientSideSuspense } from \"./ClientSideSuspense\";\nexport { createRoomContext } from \"./factory\";\nexport type { MutationContext } from \"./types\";\n\n// Re-exports from @liveblocks/client, for convenience\nexport type { Json, JsonObject } from \"@liveblocks/client\";\nexport { shallow } from \"@liveblocks/client\";\n"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/version.ts","../src/ClientSideSuspense.tsx","../src/factory.tsx","../src/hooks.ts"],"names":["React","other","rootOrNull","shallow"],"mappings":"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","sourcesContent":["import { detectDupes } from \"@liveblocks/core\";\n\nimport { PKG_FORMAT, PKG_NAME, PKG_VERSION } from \"./version\";\n\ndetectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);\n\nexport { ClientSideSuspense } from \"./ClientSideSuspense\";\nexport { createRoomContext } from \"./factory\";\nexport type { MutationContext } from \"./types\";\n\n// Re-exports from @liveblocks/client, for convenience\nexport type { Json, JsonObject } from \"@liveblocks/client\";\nexport { shallow } from \"@liveblocks/client\";\n","declare const __VERSION__: string;\ndeclare const TSUP_FORMAT: string;\n\nexport const PKG_NAME = \"@liveblocks/react\";\nexport const PKG_VERSION = typeof __VERSION__ === \"string\" && __VERSION__;\nexport const PKG_FORMAT = typeof TSUP_FORMAT === \"string\" && TSUP_FORMAT;\n","import type { ReactElement, ReactNode } from \"react\";\nimport * as React from \"react\";\n\ntype Props = {\n fallback: NonNullable<ReactNode> | null;\n children: () => ReactNode | undefined;\n};\n\n/**\n * Almost like a normal <Suspense> component, except that for server-side\n * renders, the fallback will be used.\n *\n * The child props will have to be provided in a function, i.e. change:\n *\n * <Suspense fallback={<Loading />}>\n * <MyRealComponent a={1} />\n * </Suspense>\n *\n * To:\n *\n * <ClientSideSuspense fallback={<Loading />}>\n * {() => <MyRealComponent a={1} />}\n * </ClientSideSuspense>\n *\n */\nexport function ClientSideSuspense(props: Props): ReactElement {\n const [mounted, setMounted] = React.useState(false);\n\n React.useEffect(() => {\n // Effects are never executed on the server side. The point of this is to\n // delay the flipping of this boolean until after hydration has happened.\n setMounted(true);\n }, []);\n\n return (\n <React.Suspense fallback={props.fallback}>\n {mounted ? props.children() : props.fallback}\n </React.Suspense>\n );\n}\n","import type {\n BaseUserMeta,\n BroadcastOptions,\n Client,\n History,\n Json,\n JsonObject,\n LiveObject,\n LostConnectionEvent,\n LsonObject,\n Others,\n Room,\n Status,\n User,\n} from \"@liveblocks/client\";\nimport { shallow } from \"@liveblocks/client\";\nimport type { ToImmutable } from \"@liveblocks/core\";\nimport {\n asArrayWithLegacyMethods,\n deprecateIf,\n errorIf,\n} from \"@liveblocks/core\";\nimport * as React from \"react\";\nimport { useSyncExternalStoreWithSelector } from \"use-sync-external-store/shim/with-selector.js\";\n\nimport { useInitial, useRerender } from \"./hooks\";\nimport type {\n MutationContext,\n OmitFirstArg,\n RoomContextBundle,\n RoomProviderProps,\n} from \"./types\";\n\nconst noop = () => {};\nconst identity: <T>(x: T) => T = (x) => x;\n\nconst missing_unstable_batchedUpdates = (\n reactVersion: number,\n roomId: string\n) =>\n `We noticed you’re using React ${reactVersion}. Please pass unstable_batchedUpdates at the RoomProvider level until you’re ready to upgrade to React 18:\n\n import { unstable_batchedUpdates } from \"react-dom\"; // or \"react-native\"\n\n <RoomProvider id=${JSON.stringify(\n roomId\n )} ... unstable_batchedUpdates={unstable_batchedUpdates}>\n ...\n </RoomProvider>\n\nWhy? Please see https://liveblocks.io/docs/guides/troubleshooting#stale-props-zombie-child for more information`;\n\nconst superfluous_unstable_batchedUpdates =\n \"You don’t need to pass unstable_batchedUpdates to RoomProvider anymore, since you’re on React 18+ already.\";\n\nfunction useSyncExternalStore<Snapshot>(\n s: (onStoreChange: () => void) => () => void,\n gs: () => Snapshot,\n gss: undefined | null | (() => Snapshot)\n): Snapshot {\n return useSyncExternalStoreWithSelector(s, gs, gss, identity);\n}\n\nconst EMPTY_OTHERS =\n // NOTE: asArrayWithLegacyMethods() wrapping should no longer be necessary in 0.19\n asArrayWithLegacyMethods([]);\n\nfunction getEmptyOthers() {\n return EMPTY_OTHERS;\n}\n\nfunction makeMutationContext<\n TPresence extends JsonObject,\n TStorage extends LsonObject,\n TUserMeta extends BaseUserMeta,\n TRoomEvent extends Json,\n>(\n room: Room<TPresence, TStorage, TUserMeta, TRoomEvent>\n): MutationContext<TPresence, TStorage, TUserMeta> {\n const errmsg =\n \"This mutation cannot be used until connected to the Liveblocks room\";\n\n return {\n get storage() {\n const mutableRoot = room.getStorageSnapshot();\n if (mutableRoot === null) {\n throw new Error(errmsg);\n }\n return mutableRoot;\n },\n\n get self() {\n const self = room.getSelf();\n if (self === null) {\n throw new Error(errmsg);\n }\n return self;\n },\n\n get others() {\n const others = room.getOthers();\n if (room.getSelf() === null) {\n throw new Error(errmsg);\n }\n return others;\n },\n\n setMyPresence: room.updatePresence,\n };\n}\n\nexport function createRoomContext<\n TPresence extends JsonObject,\n TStorage extends LsonObject = LsonObject,\n TUserMeta extends BaseUserMeta = BaseUserMeta,\n TRoomEvent extends Json = never,\n>(\n client: Client\n): RoomContextBundle<TPresence, TStorage, TUserMeta, TRoomEvent> {\n const RoomContext = React.createContext<Room<\n TPresence,\n TStorage,\n TUserMeta,\n TRoomEvent\n > | null>(null);\n\n function RoomProvider(props: RoomProviderProps<TPresence, TStorage>) {\n const {\n id: roomId,\n initialPresence,\n initialStorage,\n unstable_batchedUpdates,\n shouldInitiallyConnect,\n } = props;\n\n if (process.env.NODE_ENV !== \"production\") {\n if (!roomId) {\n throw new Error(\n \"RoomProvider id property is required. For more information: https://liveblocks.io/docs/errors/liveblocks-react/RoomProvider-id-property-is-required\"\n );\n }\n\n if (typeof roomId !== \"string\") {\n throw new Error(\"RoomProvider id property should be a string.\");\n }\n\n const majorReactVersion = parseInt(React.version) || 1;\n const oldReactVersion = majorReactVersion < 18;\n errorIf(\n oldReactVersion && props.unstable_batchedUpdates === undefined,\n missing_unstable_batchedUpdates(majorReactVersion, roomId)\n );\n deprecateIf(\n !oldReactVersion && props.unstable_batchedUpdates !== undefined,\n superfluous_unstable_batchedUpdates\n );\n }\n\n // Note: We'll hold on to the initial value given here, and ignore any\n // changes to this argument in subsequent renders\n const frozen = useInitial({\n initialPresence,\n initialStorage,\n unstable_batchedUpdates,\n shouldInitiallyConnect:\n shouldInitiallyConnect === undefined\n ? typeof window !== \"undefined\"\n : shouldInitiallyConnect,\n });\n\n const [room, setRoom] = React.useState<\n Room<TPresence, TStorage, TUserMeta, TRoomEvent>\n >(() =>\n client.enter(roomId, {\n initialPresence: frozen.initialPresence,\n initialStorage: frozen.initialStorage,\n shouldInitiallyConnect: frozen.shouldInitiallyConnect,\n unstable_batchedUpdates: frozen.unstable_batchedUpdates,\n })\n );\n\n React.useEffect(() => {\n setRoom(\n client.enter(roomId, {\n initialPresence: frozen.initialPresence,\n initialStorage: frozen.initialStorage,\n shouldInitiallyConnect: frozen.shouldInitiallyConnect,\n unstable_batchedUpdates: frozen.unstable_batchedUpdates,\n })\n );\n\n return () => {\n client.leave(roomId);\n };\n }, [roomId, frozen]);\n\n return (\n <RoomContext.Provider value={room}>{props.children}</RoomContext.Provider>\n );\n }\n\n function connectionIdSelector(\n others: Others<TPresence, TUserMeta>\n ): number[] {\n return others.map((user) => user.connectionId);\n }\n\n function useRoom(): Room<TPresence, TStorage, TUserMeta, TRoomEvent> {\n const room = React.useContext(RoomContext);\n if (room === null) {\n throw new Error(\"RoomProvider is missing from the react tree\");\n }\n return room;\n }\n\n function useStatus(): Status {\n const room = useRoom();\n const subscribe = room.events.status.subscribe;\n const getSnapshot = room.getStatus;\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n }\n\n function useMyPresence(): [\n TPresence,\n (patch: Partial<TPresence>, options?: { addToHistory: boolean }) => void,\n ] {\n const room = useRoom();\n const subscribe = room.events.myPresence.subscribe;\n const getSnapshot = room.getPresence;\n const presence = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n const setPresence = room.updatePresence;\n return [presence, setPresence];\n }\n\n function useUpdateMyPresence(): (\n patch: Partial<TPresence>,\n options?: { addToHistory: boolean }\n ) => void {\n return useRoom().updatePresence;\n }\n\n function useOthers(): Others<TPresence, TUserMeta>;\n function useOthers<T>(\n selector: (others: Others<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T;\n function useOthers<T>(\n selector?: (others: Others<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T | Others<TPresence, TUserMeta> {\n const room = useRoom();\n const subscribe = room.events.others.subscribe;\n const getSnapshot = room.getOthers;\n const getServerSnapshot = getEmptyOthers;\n return useSyncExternalStoreWithSelector(\n subscribe,\n getSnapshot,\n getServerSnapshot,\n selector ?? (identity as (others: Others<TPresence, TUserMeta>) => T),\n isEqual\n );\n }\n\n function useOthersConnectionIds(): readonly number[] {\n return useOthers(connectionIdSelector, shallow);\n }\n\n function useOthersMapped<T>(\n itemSelector: (other: User<TPresence, TUserMeta>) => T,\n itemIsEqual?: (prev: T, curr: T) => boolean\n ): ReadonlyArray<readonly [connectionId: number, data: T]> {\n const wrappedSelector = React.useCallback(\n (others: Others<TPresence, TUserMeta>) =>\n others.map(\n (other) => [other.connectionId, itemSelector(other)] as const\n ),\n [itemSelector]\n );\n\n const wrappedIsEqual = React.useCallback(\n (\n a: ReadonlyArray<readonly [connectionId: number, data: T]>,\n b: ReadonlyArray<readonly [connectionId: number, data: T]>\n ): boolean => {\n const eq = itemIsEqual ?? Object.is;\n return (\n a.length === b.length &&\n a.every((atuple, index) => {\n const btuple = b[index];\n return atuple[0] === btuple[0] && eq(atuple[1], btuple[1]);\n })\n );\n },\n [itemIsEqual]\n );\n\n return useOthers(wrappedSelector, wrappedIsEqual);\n }\n\n const NOT_FOUND = Symbol();\n\n type NotFound = typeof NOT_FOUND;\n\n function useOther<T>(\n connectionId: number,\n selector: (other: User<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T {\n const wrappedSelector = React.useCallback(\n (others: Others<TPresence, TUserMeta>) => {\n // TODO: Make this O(1) instead of O(n)?\n const other = others.find(\n (other) => other.connectionId === connectionId\n );\n return other !== undefined ? selector(other) : NOT_FOUND;\n },\n [connectionId, selector]\n );\n\n const wrappedIsEqual = React.useCallback(\n (prev: T | NotFound, curr: T | NotFound): boolean => {\n if (prev === NOT_FOUND || curr === NOT_FOUND) {\n return prev === curr;\n }\n\n const eq = isEqual ?? Object.is;\n return eq(prev, curr);\n },\n [isEqual]\n );\n\n const other = useOthers(wrappedSelector, wrappedIsEqual);\n if (other === NOT_FOUND) {\n throw new Error(\n `No such other user with connection id ${connectionId} exists`\n );\n }\n\n return other;\n }\n\n function useBroadcastEvent(): (\n event: TRoomEvent,\n options?: BroadcastOptions\n ) => void {\n const room = useRoom();\n\n return React.useCallback(\n (\n event: TRoomEvent,\n options: BroadcastOptions = { shouldQueueEventIfNotReady: false }\n ) => {\n room.broadcastEvent(event, options);\n },\n [room]\n );\n }\n\n function useLostConnectionListener(\n callback: (event: LostConnectionEvent) => void\n ): void {\n const room = useRoom();\n const savedCallback = React.useRef(callback);\n\n React.useEffect(() => {\n savedCallback.current = callback;\n });\n\n React.useEffect(\n () =>\n room.events.lostConnection.subscribe((event: LostConnectionEvent) =>\n savedCallback.current(event)\n ),\n [room]\n );\n }\n\n function useErrorListener(callback: (err: Error) => void): void {\n const room = useRoom();\n const savedCallback = React.useRef(callback);\n\n React.useEffect(() => {\n savedCallback.current = callback;\n });\n\n React.useEffect(\n () => room.events.error.subscribe((e: Error) => savedCallback.current(e)),\n [room]\n );\n }\n\n function useEventListener(\n callback: (eventData: { connectionId: number; event: TRoomEvent }) => void\n ): void {\n const room = useRoom();\n const savedCallback = React.useRef(callback);\n\n React.useEffect(() => {\n savedCallback.current = callback;\n });\n\n React.useEffect(() => {\n const listener = (eventData: {\n connectionId: number;\n event: TRoomEvent;\n }) => {\n savedCallback.current(eventData);\n };\n\n return room.events.customEvent.subscribe(listener);\n }, [room]);\n }\n\n function useSelf(): User<TPresence, TUserMeta> | null;\n function useSelf<T>(\n selector: (me: User<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T | null, curr: T | null) => boolean\n ): T | null;\n function useSelf<T>(\n maybeSelector?: (me: User<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T | null, curr: T | null) => boolean\n ): T | User<TPresence, TUserMeta> | null {\n type Snapshot = User<TPresence, TUserMeta> | null;\n type Selection = T | null;\n\n const room = useRoom();\n const subscribe = room.events.self.subscribe;\n const getSnapshot: () => Snapshot = room.getSelf;\n\n const selector =\n maybeSelector ?? (identity as (me: User<TPresence, TUserMeta>) => T);\n const wrappedSelector = React.useCallback(\n (me: Snapshot): Selection => (me !== null ? selector(me) : null),\n [selector]\n );\n\n const getServerSnapshot = React.useCallback((): Snapshot => null, []);\n\n return useSyncExternalStoreWithSelector(\n subscribe,\n getSnapshot,\n getServerSnapshot,\n wrappedSelector,\n isEqual\n );\n }\n\n function useMutableStorageRoot(): LiveObject<TStorage> | null {\n type Snapshot = LiveObject<TStorage> | null;\n const room = useRoom();\n const subscribe = room.events.storageDidLoad.subscribeOnce;\n const getSnapshot = room.getStorageSnapshot;\n const getServerSnapshot = React.useCallback((): Snapshot => null, []);\n return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n }\n\n // NOTE: This API exists for backward compatible reasons\n function useStorageRoot(): [root: LiveObject<TStorage> | null] {\n return [useMutableStorageRoot()];\n }\n\n function useHistory(): History {\n return useRoom().history;\n }\n\n function useUndo(): () => void {\n return useHistory().undo;\n }\n\n function useRedo(): () => void {\n return useHistory().redo;\n }\n\n function useCanUndo(): boolean {\n const room = useRoom();\n const subscribe = room.events.history.subscribe;\n const canUndo = room.history.canUndo;\n return useSyncExternalStore(subscribe, canUndo, canUndo);\n }\n\n function useCanRedo(): boolean {\n const room = useRoom();\n const subscribe = room.events.history.subscribe;\n const canRedo = room.history.canRedo;\n return useSyncExternalStore(subscribe, canRedo, canRedo);\n }\n\n function useBatch<T>(): (callback: () => T) => T {\n return useRoom().batch;\n }\n\n function useLegacyKey<TKey extends Extract<keyof TStorage, string>>(\n key: TKey\n ): TStorage[TKey] | null {\n const room = useRoom();\n const root = useMutableStorageRoot();\n const rerender = useRerender();\n\n React.useEffect(() => {\n if (root === null) {\n return;\n }\n\n let liveValue = root.get(key);\n\n function onRootChange() {\n const newCrdt = root!.get(key);\n if (newCrdt !== liveValue) {\n unsubscribeCrdt();\n liveValue = newCrdt;\n unsubscribeCrdt = room.subscribe(\n liveValue as any /* AbstractCrdt */, // TODO: This is hiding a bug! If `liveValue` happens to be the string `\"event\"` this actually subscribes an event handler!\n rerender\n );\n rerender();\n }\n }\n\n let unsubscribeCrdt = room.subscribe(\n liveValue as any /* AbstractCrdt */, // TODO: This is hiding a bug! If `liveValue` happens to be the string `\"event\"` this actually subscribes an event handler!\n rerender\n );\n const unsubscribeRoot = room.subscribe(\n root as any /* AbstractCrdt */, // TODO: This is hiding a bug! If `liveValue` happens to be the string `\"event\"` this actually subscribes an event handler!\n onRootChange\n );\n\n rerender();\n\n return () => {\n unsubscribeRoot();\n unsubscribeCrdt();\n };\n }, [root, room, key, rerender]);\n\n if (root === null) {\n return null;\n } else {\n return root.get(key);\n }\n }\n\n function useStorage<T>(\n selector: (root: ToImmutable<TStorage>) => T,\n isEqual?: (prev: T | null, curr: T | null) => boolean\n ): T | null {\n type Snapshot = ToImmutable<TStorage> | null;\n type Selection = T | null;\n\n const room = useRoom();\n const rootOrNull = useMutableStorageRoot();\n\n const wrappedSelector = React.useCallback(\n (rootOrNull: Snapshot): Selection =>\n rootOrNull !== null ? selector(rootOrNull) : null,\n [selector]\n );\n\n const subscribe = React.useCallback(\n (onStoreChange: () => void) =>\n rootOrNull !== null\n ? room.subscribe(rootOrNull, onStoreChange, { isDeep: true })\n : noop,\n [room, rootOrNull]\n );\n\n const getSnapshot = React.useCallback((): Snapshot => {\n if (rootOrNull === null) {\n return null;\n } else {\n const root = rootOrNull;\n const imm = root.toImmutable();\n return imm;\n }\n }, [rootOrNull]);\n\n const getServerSnapshot = React.useCallback((): Snapshot => null, []);\n\n return useSyncExternalStoreWithSelector(\n subscribe,\n getSnapshot,\n getServerSnapshot,\n wrappedSelector,\n isEqual\n );\n }\n\n function ensureNotServerSide(): void {\n // Error early if suspense is used in a server-side context\n if (typeof window === \"undefined\") {\n throw new Error(\n \"You cannot use the Suspense version of this hook on the server side. Make sure to only call them on the client side.\\nFor tips, see https://liveblocks.io/docs/api-reference/liveblocks-react#suspense-avoid-ssr\"\n );\n }\n }\n\n function useSuspendUntilStorageLoaded(): void {\n const room = useRoom();\n if (room.getStorageSnapshot() !== null) {\n return;\n }\n\n ensureNotServerSide();\n\n // Throw a _promise_. Suspense will suspend the component tree until this\n // promise resolves (aka until storage has loaded). After that, it will\n // render this component tree again.\n throw new Promise<void>((res) => {\n room.events.storageDidLoad.subscribeOnce(() => res());\n });\n }\n\n function useSuspendUntilPresenceLoaded(): void {\n const room = useRoom();\n if (room.getSelf() !== null) {\n return;\n }\n\n ensureNotServerSide();\n\n // Throw a _promise_. Suspense will suspend the component tree until this\n // promise resolves (aka until storage has loaded). After that, it will\n // render this component tree again.\n throw new Promise<void>((res) => {\n room.events.status.subscribeOnce(() => res());\n });\n }\n\n function useMutation<\n F extends (\n context: MutationContext<TPresence, TStorage, TUserMeta>,\n ...args: any[]\n ) => any,\n >(callback: F, deps: readonly unknown[]): OmitFirstArg<F> {\n const room = useRoom();\n return React.useMemo(\n () => {\n return ((...args) =>\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n room.batch(() =>\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n callback(\n makeMutationContext(room),\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n ...args\n )\n )) as OmitFirstArg<F>;\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [room, ...deps]\n );\n }\n\n function useStorageSuspense<T>(\n selector: (root: ToImmutable<TStorage>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T {\n useSuspendUntilStorageLoaded();\n return useStorage(\n selector,\n isEqual as (prev: T | null, curr: T | null) => boolean\n ) as T;\n }\n\n function useSelfSuspense(): User<TPresence, TUserMeta>;\n function useSelfSuspense<T>(\n selector: (me: User<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T;\n function useSelfSuspense<T>(\n selector?: (me: User<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T | User<TPresence, TUserMeta> {\n useSuspendUntilPresenceLoaded();\n return useSelf(\n selector as (me: User<TPresence, TUserMeta>) => T,\n isEqual as (prev: T | null, curr: T | null) => boolean\n ) as T | User<TPresence, TUserMeta>;\n }\n\n function useOthersSuspense<T>(\n selector?: (others: Others<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T | Others<TPresence, TUserMeta> {\n useSuspendUntilPresenceLoaded();\n return useOthers(\n selector as (others: Others<TPresence, TUserMeta>) => T,\n isEqual as (prev: T, curr: T) => boolean\n ) as T | Others<TPresence, TUserMeta>;\n }\n\n function useOthersConnectionIdsSuspense(): readonly number[] {\n useSuspendUntilPresenceLoaded();\n return useOthersConnectionIds();\n }\n\n function useOthersMappedSuspense<T>(\n itemSelector: (other: User<TPresence, TUserMeta>) => T,\n itemIsEqual?: (prev: T, curr: T) => boolean\n ): ReadonlyArray<readonly [connectionId: number, data: T]> {\n useSuspendUntilPresenceLoaded();\n return useOthersMapped(itemSelector, itemIsEqual);\n }\n\n function useOtherSuspense<T>(\n connectionId: number,\n selector: (other: User<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T {\n useSuspendUntilPresenceLoaded();\n return useOther(connectionId, selector, isEqual);\n }\n\n function useLegacyKeySuspense<TKey extends Extract<keyof TStorage, string>>(\n key: TKey\n ): TStorage[TKey] {\n useSuspendUntilStorageLoaded();\n return useLegacyKey(key) as TStorage[TKey];\n }\n\n return {\n RoomContext,\n RoomProvider,\n\n useRoom,\n useStatus,\n\n useBatch,\n useBroadcastEvent,\n useLostConnectionListener,\n useErrorListener,\n useEventListener,\n\n useHistory,\n useUndo,\n useRedo,\n useCanRedo,\n useCanUndo,\n\n // These are just aliases. The passed-in key will define their return values.\n useList: useLegacyKey,\n useMap: useLegacyKey,\n useObject: useLegacyKey,\n\n useStorageRoot,\n useStorage,\n\n useSelf,\n useMyPresence,\n useUpdateMyPresence,\n useOthers,\n useOthersMapped,\n useOthersConnectionIds,\n useOther,\n\n useMutation,\n\n suspense: {\n RoomContext,\n RoomProvider,\n\n useRoom,\n useStatus,\n\n useBatch,\n useBroadcastEvent,\n useLostConnectionListener,\n useErrorListener,\n useEventListener,\n\n useHistory,\n useUndo,\n useRedo,\n useCanRedo,\n useCanUndo,\n\n // Legacy hooks\n useList: useLegacyKeySuspense,\n useMap: useLegacyKeySuspense,\n useObject: useLegacyKeySuspense,\n\n useStorageRoot,\n useStorage: useStorageSuspense,\n\n useSelf: useSelfSuspense,\n useMyPresence,\n useUpdateMyPresence,\n useOthers: useOthersSuspense,\n useOthersMapped: useOthersMappedSuspense,\n useOthersConnectionIds: useOthersConnectionIdsSuspense,\n useOther: useOtherSuspense,\n\n useMutation,\n },\n };\n}\n","import { useReducer, useRef } from \"react\";\n\n/**\n * Trigger a re-render programmatically, without changing the component's\n * state.\n *\n * Usage:\n *\n * const rerender = useRerender();\n * return (\n * <button onClick={rerender}>\n * {Math.random()}\n * </button>\n * )\n *\n */\nexport function useRerender(): () => void {\n const [, update] = useReducer(\n // This implementation works by incrementing a hidden counter value that is\n // never consumed. Simply incrementing the counter changes the component's\n // state and, thus, trigger a re-render.\n (x: number): number => x + 1,\n 0\n );\n return update;\n}\n\n/**\n * \"Freezes\" a given value, so that it will return the same value/instance on\n * each subsequent render. This can be used to freeze \"initial\" values for\n * custom hooks, much like how `useState(initialState)` or\n * `useRef(initialValue)` works.\n */\nexport function useInitial<T>(value: T): T {\n return useRef(value).current;\n}\n"]}
package/dist/index.mjs CHANGED
@@ -1,3 +1,11 @@
1
+ // src/index.ts
2
+ import { detectDupes } from "@liveblocks/core";
3
+
4
+ // src/version.ts
5
+ var PKG_NAME = "@liveblocks/react";
6
+ var PKG_VERSION = "1.2.0";
7
+ var PKG_FORMAT = "esm";
8
+
1
9
  // src/ClientSideSuspense.tsx
2
10
  import * as React from "react";
3
11
  function ClientSideSuspense(props) {
@@ -79,7 +87,7 @@ function makeMutationContext(room) {
79
87
  },
80
88
  get others() {
81
89
  const others = room.getOthers();
82
- if (!room.isSelfAware()) {
90
+ if (room.getSelf() === null) {
83
91
  throw new Error(errmsg);
84
92
  }
85
93
  return others;
@@ -164,7 +172,7 @@ function createRoomContext(client) {
164
172
  }
165
173
  function useMyPresence() {
166
174
  const room = useRoom();
167
- const subscribe = room.events.me.subscribe;
175
+ const subscribe = room.events.myPresence.subscribe;
168
176
  const getSnapshot = room.getPresence;
169
177
  const presence = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
170
178
  const setPresence = room.updatePresence;
@@ -285,17 +293,7 @@ function createRoomContext(client) {
285
293
  }
286
294
  function useSelf(maybeSelector, isEqual) {
287
295
  const room = useRoom();
288
- const subscribe = React2.useCallback(
289
- (onChange) => {
290
- const unsub1 = room.events.me.subscribe(onChange);
291
- const unsub2 = room.events.connection.subscribe(onChange);
292
- return () => {
293
- unsub1();
294
- unsub2();
295
- };
296
- },
297
- [room]
298
- );
296
+ const subscribe = room.events.self.subscribe;
299
297
  const getSnapshot = room.getSelf;
300
298
  const selector = maybeSelector ?? identity;
301
299
  const wrappedSelector = React2.useCallback(
@@ -437,12 +435,12 @@ function createRoomContext(client) {
437
435
  }
438
436
  function useSuspendUntilPresenceLoaded() {
439
437
  const room = useRoom();
440
- if (room.isSelfAware()) {
438
+ if (room.getSelf() !== null) {
441
439
  return;
442
440
  }
443
441
  ensureNotServerSide();
444
442
  throw new Promise((res) => {
445
- room.events.connection.subscribeOnce(() => res());
443
+ room.events.status.subscribeOnce(() => res());
446
444
  });
447
445
  }
448
446
  function useMutation(callback, deps) {
@@ -567,6 +565,7 @@ function createRoomContext(client) {
567
565
 
568
566
  // src/index.ts
569
567
  import { shallow as shallow2 } from "@liveblocks/client";
568
+ detectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);
570
569
  export {
571
570
  ClientSideSuspense,
572
571
  createRoomContext,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/ClientSideSuspense.tsx","../src/factory.tsx","../src/hooks.ts","../src/index.ts"],"sourcesContent":["import type { ReactElement, ReactNode } from \"react\";\nimport * as React from \"react\";\n\ntype Props = {\n fallback: NonNullable<ReactNode> | null;\n children: () => ReactNode | undefined;\n};\n\n/**\n * Almost like a normal <Suspense> component, except that for server-side\n * renders, the fallback will be used.\n *\n * The child props will have to be provided in a function, i.e. change:\n *\n * <Suspense fallback={<Loading />}>\n * <MyRealComponent a={1} />\n * </Suspense>\n *\n * To:\n *\n * <ClientSideSuspense fallback={<Loading />}>\n * {() => <MyRealComponent a={1} />}\n * </ClientSideSuspense>\n *\n */\nexport function ClientSideSuspense(props: Props): ReactElement {\n const [mounted, setMounted] = React.useState(false);\n\n React.useEffect(() => {\n // Effects are never executed on the server side. The point of this is to\n // delay the flipping of this boolean until after hydration has happened.\n setMounted(true);\n }, []);\n\n return (\n <React.Suspense fallback={props.fallback}>\n {mounted ? props.children() : props.fallback}\n </React.Suspense>\n );\n}\n","import type {\n BaseUserMeta,\n BroadcastOptions,\n Client,\n History,\n Json,\n JsonObject,\n LiveObject,\n LostConnectionEvent,\n LsonObject,\n Others,\n Room,\n Status,\n User,\n} from \"@liveblocks/client\";\nimport { shallow } from \"@liveblocks/client\";\nimport type { ToImmutable } from \"@liveblocks/core\";\nimport {\n asArrayWithLegacyMethods,\n deprecateIf,\n errorIf,\n} from \"@liveblocks/core\";\nimport * as React from \"react\";\nimport { useSyncExternalStoreWithSelector } from \"use-sync-external-store/shim/with-selector.js\";\n\nimport { useInitial, useRerender } from \"./hooks\";\nimport type {\n MutationContext,\n OmitFirstArg,\n RoomContextBundle,\n RoomProviderProps,\n} from \"./types\";\n\nconst noop = () => {};\nconst identity: <T>(x: T) => T = (x) => x;\n\nconst missing_unstable_batchedUpdates = (\n reactVersion: number,\n roomId: string\n) =>\n `We noticed you’re using React ${reactVersion}. Please pass unstable_batchedUpdates at the RoomProvider level until you’re ready to upgrade to React 18:\n\n import { unstable_batchedUpdates } from \"react-dom\"; // or \"react-native\"\n\n <RoomProvider id=${JSON.stringify(\n roomId\n )} ... unstable_batchedUpdates={unstable_batchedUpdates}>\n ...\n </RoomProvider>\n\nWhy? Please see https://liveblocks.io/docs/guides/troubleshooting#stale-props-zombie-child for more information`;\n\nconst superfluous_unstable_batchedUpdates =\n \"You don’t need to pass unstable_batchedUpdates to RoomProvider anymore, since you’re on React 18+ already.\";\n\nfunction useSyncExternalStore<Snapshot>(\n s: (onStoreChange: () => void) => () => void,\n gs: () => Snapshot,\n gss: undefined | null | (() => Snapshot)\n): Snapshot {\n return useSyncExternalStoreWithSelector(s, gs, gss, identity);\n}\n\nconst EMPTY_OTHERS =\n // NOTE: asArrayWithLegacyMethods() wrapping should no longer be necessary in 0.19\n asArrayWithLegacyMethods([]);\n\nfunction getEmptyOthers() {\n return EMPTY_OTHERS;\n}\n\nfunction makeMutationContext<\n TPresence extends JsonObject,\n TStorage extends LsonObject,\n TUserMeta extends BaseUserMeta,\n TRoomEvent extends Json,\n>(\n room: Room<TPresence, TStorage, TUserMeta, TRoomEvent>\n): MutationContext<TPresence, TStorage, TUserMeta> {\n const errmsg =\n \"This mutation cannot be used until connected to the Liveblocks room\";\n\n return {\n get storage() {\n const mutableRoot = room.getStorageSnapshot();\n if (mutableRoot === null) {\n throw new Error(errmsg);\n }\n return mutableRoot;\n },\n\n get self() {\n const self = room.getSelf();\n // NOTE: We could use room.isSelfAware() here to keep the check\n // consistent with `others`, but we also want to refine the `null` case\n // away here.\n if (self === null) {\n throw new Error(errmsg);\n }\n return self;\n },\n\n get others() {\n const others = room.getOthers();\n if (!room.isSelfAware()) {\n throw new Error(errmsg);\n }\n return others;\n },\n\n setMyPresence: room.updatePresence,\n };\n}\n\nexport function createRoomContext<\n TPresence extends JsonObject,\n TStorage extends LsonObject = LsonObject,\n TUserMeta extends BaseUserMeta = BaseUserMeta,\n TRoomEvent extends Json = never,\n>(\n client: Client\n): RoomContextBundle<TPresence, TStorage, TUserMeta, TRoomEvent> {\n const RoomContext = React.createContext<Room<\n TPresence,\n TStorage,\n TUserMeta,\n TRoomEvent\n > | null>(null);\n\n function RoomProvider(props: RoomProviderProps<TPresence, TStorage>) {\n const {\n id: roomId,\n initialPresence,\n initialStorage,\n unstable_batchedUpdates,\n shouldInitiallyConnect,\n } = props;\n\n if (process.env.NODE_ENV !== \"production\") {\n if (!roomId) {\n throw new Error(\n \"RoomProvider id property is required. For more information: https://liveblocks.io/docs/errors/liveblocks-react/RoomProvider-id-property-is-required\"\n );\n }\n\n if (typeof roomId !== \"string\") {\n throw new Error(\"RoomProvider id property should be a string.\");\n }\n\n const majorReactVersion = parseInt(React.version) || 1;\n const oldReactVersion = majorReactVersion < 18;\n errorIf(\n oldReactVersion && props.unstable_batchedUpdates === undefined,\n missing_unstable_batchedUpdates(majorReactVersion, roomId)\n );\n deprecateIf(\n !oldReactVersion && props.unstable_batchedUpdates !== undefined,\n superfluous_unstable_batchedUpdates\n );\n }\n\n // Note: We'll hold on to the initial value given here, and ignore any\n // changes to this argument in subsequent renders\n const frozen = useInitial({\n initialPresence,\n initialStorage,\n unstable_batchedUpdates,\n shouldInitiallyConnect:\n shouldInitiallyConnect === undefined\n ? typeof window !== \"undefined\"\n : shouldInitiallyConnect,\n });\n\n const [room, setRoom] = React.useState<\n Room<TPresence, TStorage, TUserMeta, TRoomEvent>\n >(() =>\n client.enter(roomId, {\n initialPresence: frozen.initialPresence,\n initialStorage: frozen.initialStorage,\n shouldInitiallyConnect: frozen.shouldInitiallyConnect,\n unstable_batchedUpdates: frozen.unstable_batchedUpdates,\n })\n );\n\n React.useEffect(() => {\n setRoom(\n client.enter(roomId, {\n initialPresence: frozen.initialPresence,\n initialStorage: frozen.initialStorage,\n shouldInitiallyConnect: frozen.shouldInitiallyConnect,\n unstable_batchedUpdates: frozen.unstable_batchedUpdates,\n })\n );\n\n return () => {\n client.leave(roomId);\n };\n }, [roomId, frozen]);\n\n return (\n <RoomContext.Provider value={room}>{props.children}</RoomContext.Provider>\n );\n }\n\n function connectionIdSelector(\n others: Others<TPresence, TUserMeta>\n ): number[] {\n return others.map((user) => user.connectionId);\n }\n\n function useRoom(): Room<TPresence, TStorage, TUserMeta, TRoomEvent> {\n const room = React.useContext(RoomContext);\n if (room === null) {\n throw new Error(\"RoomProvider is missing from the react tree\");\n }\n return room;\n }\n\n function useStatus(): Status {\n const room = useRoom();\n const subscribe = room.events.status.subscribe;\n const getSnapshot = room.getStatus;\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n }\n\n function useMyPresence(): [\n TPresence,\n (patch: Partial<TPresence>, options?: { addToHistory: boolean }) => void,\n ] {\n const room = useRoom();\n const subscribe = room.events.me.subscribe;\n const getSnapshot = room.getPresence;\n const presence = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n const setPresence = room.updatePresence;\n return [presence, setPresence];\n }\n\n function useUpdateMyPresence(): (\n patch: Partial<TPresence>,\n options?: { addToHistory: boolean }\n ) => void {\n return useRoom().updatePresence;\n }\n\n function useOthers(): Others<TPresence, TUserMeta>;\n function useOthers<T>(\n selector: (others: Others<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T;\n function useOthers<T>(\n selector?: (others: Others<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T | Others<TPresence, TUserMeta> {\n const room = useRoom();\n const subscribe = room.events.others.subscribe;\n const getSnapshot = room.getOthers;\n const getServerSnapshot = getEmptyOthers;\n return useSyncExternalStoreWithSelector(\n subscribe,\n getSnapshot,\n getServerSnapshot,\n selector ?? (identity as (others: Others<TPresence, TUserMeta>) => T),\n isEqual\n );\n }\n\n function useOthersConnectionIds(): readonly number[] {\n return useOthers(connectionIdSelector, shallow);\n }\n\n function useOthersMapped<T>(\n itemSelector: (other: User<TPresence, TUserMeta>) => T,\n itemIsEqual?: (prev: T, curr: T) => boolean\n ): ReadonlyArray<readonly [connectionId: number, data: T]> {\n const wrappedSelector = React.useCallback(\n (others: Others<TPresence, TUserMeta>) =>\n others.map(\n (other) => [other.connectionId, itemSelector(other)] as const\n ),\n [itemSelector]\n );\n\n const wrappedIsEqual = React.useCallback(\n (\n a: ReadonlyArray<readonly [connectionId: number, data: T]>,\n b: ReadonlyArray<readonly [connectionId: number, data: T]>\n ): boolean => {\n const eq = itemIsEqual ?? Object.is;\n return (\n a.length === b.length &&\n a.every((atuple, index) => {\n const btuple = b[index];\n return atuple[0] === btuple[0] && eq(atuple[1], btuple[1]);\n })\n );\n },\n [itemIsEqual]\n );\n\n return useOthers(wrappedSelector, wrappedIsEqual);\n }\n\n const NOT_FOUND = Symbol();\n\n type NotFound = typeof NOT_FOUND;\n\n function useOther<T>(\n connectionId: number,\n selector: (other: User<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T {\n const wrappedSelector = React.useCallback(\n (others: Others<TPresence, TUserMeta>) => {\n // TODO: Make this O(1) instead of O(n)?\n const other = others.find(\n (other) => other.connectionId === connectionId\n );\n return other !== undefined ? selector(other) : NOT_FOUND;\n },\n [connectionId, selector]\n );\n\n const wrappedIsEqual = React.useCallback(\n (prev: T | NotFound, curr: T | NotFound): boolean => {\n if (prev === NOT_FOUND || curr === NOT_FOUND) {\n return prev === curr;\n }\n\n const eq = isEqual ?? Object.is;\n return eq(prev, curr);\n },\n [isEqual]\n );\n\n const other = useOthers(wrappedSelector, wrappedIsEqual);\n if (other === NOT_FOUND) {\n throw new Error(\n `No such other user with connection id ${connectionId} exists`\n );\n }\n\n return other;\n }\n\n function useBroadcastEvent(): (\n event: TRoomEvent,\n options?: BroadcastOptions\n ) => void {\n const room = useRoom();\n\n return React.useCallback(\n (\n event: TRoomEvent,\n options: BroadcastOptions = { shouldQueueEventIfNotReady: false }\n ) => {\n room.broadcastEvent(event, options);\n },\n [room]\n );\n }\n\n function useLostConnectionListener(\n callback: (event: LostConnectionEvent) => void\n ): void {\n const room = useRoom();\n const savedCallback = React.useRef(callback);\n\n React.useEffect(() => {\n savedCallback.current = callback;\n });\n\n React.useEffect(\n () =>\n room.events.lostConnection.subscribe((event: LostConnectionEvent) =>\n savedCallback.current(event)\n ),\n [room]\n );\n }\n\n function useErrorListener(callback: (err: Error) => void): void {\n const room = useRoom();\n const savedCallback = React.useRef(callback);\n\n React.useEffect(() => {\n savedCallback.current = callback;\n });\n\n React.useEffect(\n () => room.events.error.subscribe((e: Error) => savedCallback.current(e)),\n [room]\n );\n }\n\n function useEventListener(\n callback: (eventData: { connectionId: number; event: TRoomEvent }) => void\n ): void {\n const room = useRoom();\n const savedCallback = React.useRef(callback);\n\n React.useEffect(() => {\n savedCallback.current = callback;\n });\n\n React.useEffect(() => {\n const listener = (eventData: {\n connectionId: number;\n event: TRoomEvent;\n }) => {\n savedCallback.current(eventData);\n };\n\n return room.events.customEvent.subscribe(listener);\n }, [room]);\n }\n\n function useSelf(): User<TPresence, TUserMeta> | null;\n function useSelf<T>(\n selector: (me: User<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T | null, curr: T | null) => boolean\n ): T | null;\n function useSelf<T>(\n maybeSelector?: (me: User<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T | null, curr: T | null) => boolean\n ): T | User<TPresence, TUserMeta> | null {\n type Snapshot = User<TPresence, TUserMeta> | null;\n type Selection = T | null;\n\n const room = useRoom();\n\n const subscribe = React.useCallback(\n (onChange: () => void) => {\n const unsub1 = room.events.me.subscribe(onChange);\n const unsub2 = room.events.connection.subscribe(onChange);\n return () => {\n unsub1();\n unsub2();\n };\n },\n [room]\n );\n\n const getSnapshot: () => Snapshot = room.getSelf;\n\n const selector =\n maybeSelector ?? (identity as (me: User<TPresence, TUserMeta>) => T);\n\n const wrappedSelector = React.useCallback(\n (me: Snapshot): Selection => (me !== null ? selector(me) : null),\n [selector]\n );\n\n const getServerSnapshot = React.useCallback((): Snapshot => null, []);\n\n return useSyncExternalStoreWithSelector(\n subscribe,\n getSnapshot,\n getServerSnapshot,\n wrappedSelector,\n isEqual\n );\n }\n\n function useMutableStorageRoot(): LiveObject<TStorage> | null {\n type Snapshot = LiveObject<TStorage> | null;\n const room = useRoom();\n const subscribe = room.events.storageDidLoad.subscribeOnce;\n const getSnapshot = room.getStorageSnapshot;\n const getServerSnapshot = React.useCallback((): Snapshot => null, []);\n return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n }\n\n // NOTE: This API exists for backward compatible reasons\n function useStorageRoot(): [root: LiveObject<TStorage> | null] {\n return [useMutableStorageRoot()];\n }\n\n function useHistory(): History {\n return useRoom().history;\n }\n\n function useUndo(): () => void {\n return useHistory().undo;\n }\n\n function useRedo(): () => void {\n return useHistory().redo;\n }\n\n function useCanUndo(): boolean {\n const room = useRoom();\n const subscribe = room.events.history.subscribe;\n const canUndo = room.history.canUndo;\n return useSyncExternalStore(subscribe, canUndo, canUndo);\n }\n\n function useCanRedo(): boolean {\n const room = useRoom();\n const subscribe = room.events.history.subscribe;\n const canRedo = room.history.canRedo;\n return useSyncExternalStore(subscribe, canRedo, canRedo);\n }\n\n function useBatch<T>(): (callback: () => T) => T {\n return useRoom().batch;\n }\n\n function useLegacyKey<TKey extends Extract<keyof TStorage, string>>(\n key: TKey\n ): TStorage[TKey] | null {\n const room = useRoom();\n const root = useMutableStorageRoot();\n const rerender = useRerender();\n\n React.useEffect(() => {\n if (root === null) {\n return;\n }\n\n let liveValue = root.get(key);\n\n function onRootChange() {\n const newCrdt = root!.get(key);\n if (newCrdt !== liveValue) {\n unsubscribeCrdt();\n liveValue = newCrdt;\n unsubscribeCrdt = room.subscribe(\n liveValue as any /* AbstractCrdt */, // TODO: This is hiding a bug! If `liveValue` happens to be the string `\"event\"` this actually subscribes an event handler!\n rerender\n );\n rerender();\n }\n }\n\n let unsubscribeCrdt = room.subscribe(\n liveValue as any /* AbstractCrdt */, // TODO: This is hiding a bug! If `liveValue` happens to be the string `\"event\"` this actually subscribes an event handler!\n rerender\n );\n const unsubscribeRoot = room.subscribe(\n root as any /* AbstractCrdt */, // TODO: This is hiding a bug! If `liveValue` happens to be the string `\"event\"` this actually subscribes an event handler!\n onRootChange\n );\n\n rerender();\n\n return () => {\n unsubscribeRoot();\n unsubscribeCrdt();\n };\n }, [root, room, key, rerender]);\n\n if (root === null) {\n return null;\n } else {\n return root.get(key);\n }\n }\n\n function useStorage<T>(\n selector: (root: ToImmutable<TStorage>) => T,\n isEqual?: (prev: T | null, curr: T | null) => boolean\n ): T | null {\n type Snapshot = ToImmutable<TStorage> | null;\n type Selection = T | null;\n\n const room = useRoom();\n const rootOrNull = useMutableStorageRoot();\n\n const wrappedSelector = React.useCallback(\n (rootOrNull: Snapshot): Selection =>\n rootOrNull !== null ? selector(rootOrNull) : null,\n [selector]\n );\n\n const subscribe = React.useCallback(\n (onStoreChange: () => void) =>\n rootOrNull !== null\n ? room.subscribe(rootOrNull, onStoreChange, { isDeep: true })\n : noop,\n [room, rootOrNull]\n );\n\n const getSnapshot = React.useCallback((): Snapshot => {\n if (rootOrNull === null) {\n return null;\n } else {\n const root = rootOrNull;\n const imm = root.toImmutable();\n return imm;\n }\n }, [rootOrNull]);\n\n const getServerSnapshot = React.useCallback((): Snapshot => null, []);\n\n return useSyncExternalStoreWithSelector(\n subscribe,\n getSnapshot,\n getServerSnapshot,\n wrappedSelector,\n isEqual\n );\n }\n\n function ensureNotServerSide(): void {\n // Error early if suspense is used in a server-side context\n if (typeof window === \"undefined\") {\n throw new Error(\n \"You cannot use the Suspense version of this hook on the server side. Make sure to only call them on the client side.\\nFor tips, see https://liveblocks.io/docs/api-reference/liveblocks-react#suspense-avoid-ssr\"\n );\n }\n }\n\n function useSuspendUntilStorageLoaded(): void {\n const room = useRoom();\n if (room.getStorageSnapshot() !== null) {\n return;\n }\n\n ensureNotServerSide();\n\n // Throw a _promise_. Suspense will suspend the component tree until this\n // promise resolves (aka until storage has loaded). After that, it will\n // render this component tree again.\n throw new Promise<void>((res) => {\n room.events.storageDidLoad.subscribeOnce(() => res());\n });\n }\n\n function useSuspendUntilPresenceLoaded(): void {\n const room = useRoom();\n if (room.isSelfAware()) {\n return;\n }\n\n ensureNotServerSide();\n\n // Throw a _promise_. Suspense will suspend the component tree until this\n // promise resolves (aka until storage has loaded). After that, it will\n // render this component tree again.\n throw new Promise<void>((res) => {\n room.events.connection.subscribeOnce(() => res());\n });\n }\n\n function useMutation<\n F extends (\n context: MutationContext<TPresence, TStorage, TUserMeta>,\n ...args: any[]\n ) => any,\n >(callback: F, deps: readonly unknown[]): OmitFirstArg<F> {\n const room = useRoom();\n return React.useMemo(\n () => {\n return ((...args) =>\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n room.batch(() =>\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n callback(\n makeMutationContext(room),\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n ...args\n )\n )) as OmitFirstArg<F>;\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [room, ...deps]\n );\n }\n\n function useStorageSuspense<T>(\n selector: (root: ToImmutable<TStorage>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T {\n useSuspendUntilStorageLoaded();\n return useStorage(\n selector,\n isEqual as (prev: T | null, curr: T | null) => boolean\n ) as T;\n }\n\n function useSelfSuspense(): User<TPresence, TUserMeta>;\n function useSelfSuspense<T>(\n selector: (me: User<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T;\n function useSelfSuspense<T>(\n selector?: (me: User<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T | User<TPresence, TUserMeta> {\n useSuspendUntilPresenceLoaded();\n return useSelf(\n selector as (me: User<TPresence, TUserMeta>) => T,\n isEqual as (prev: T | null, curr: T | null) => boolean\n ) as T | User<TPresence, TUserMeta>;\n }\n\n function useOthersSuspense<T>(\n selector?: (others: Others<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T | Others<TPresence, TUserMeta> {\n useSuspendUntilPresenceLoaded();\n return useOthers(\n selector as (others: Others<TPresence, TUserMeta>) => T,\n isEqual as (prev: T, curr: T) => boolean\n ) as T | Others<TPresence, TUserMeta>;\n }\n\n function useOthersConnectionIdsSuspense(): readonly number[] {\n useSuspendUntilPresenceLoaded();\n return useOthersConnectionIds();\n }\n\n function useOthersMappedSuspense<T>(\n itemSelector: (other: User<TPresence, TUserMeta>) => T,\n itemIsEqual?: (prev: T, curr: T) => boolean\n ): ReadonlyArray<readonly [connectionId: number, data: T]> {\n useSuspendUntilPresenceLoaded();\n return useOthersMapped(itemSelector, itemIsEqual);\n }\n\n function useOtherSuspense<T>(\n connectionId: number,\n selector: (other: User<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T {\n useSuspendUntilPresenceLoaded();\n return useOther(connectionId, selector, isEqual);\n }\n\n function useLegacyKeySuspense<TKey extends Extract<keyof TStorage, string>>(\n key: TKey\n ): TStorage[TKey] {\n useSuspendUntilStorageLoaded();\n return useLegacyKey(key) as TStorage[TKey];\n }\n\n return {\n RoomContext,\n RoomProvider,\n\n useRoom,\n useStatus,\n\n useBatch,\n useBroadcastEvent,\n useLostConnectionListener,\n useErrorListener,\n useEventListener,\n\n useHistory,\n useUndo,\n useRedo,\n useCanRedo,\n useCanUndo,\n\n // These are just aliases. The passed-in key will define their return values.\n useList: useLegacyKey,\n useMap: useLegacyKey,\n useObject: useLegacyKey,\n\n useStorageRoot,\n useStorage,\n\n useSelf,\n useMyPresence,\n useUpdateMyPresence,\n useOthers,\n useOthersMapped,\n useOthersConnectionIds,\n useOther,\n\n useMutation,\n\n suspense: {\n RoomContext,\n RoomProvider,\n\n useRoom,\n useStatus,\n\n useBatch,\n useBroadcastEvent,\n useLostConnectionListener,\n useErrorListener,\n useEventListener,\n\n useHistory,\n useUndo,\n useRedo,\n useCanRedo,\n useCanUndo,\n\n // Legacy hooks\n useList: useLegacyKeySuspense,\n useMap: useLegacyKeySuspense,\n useObject: useLegacyKeySuspense,\n\n useStorageRoot,\n useStorage: useStorageSuspense,\n\n useSelf: useSelfSuspense,\n useMyPresence,\n useUpdateMyPresence,\n useOthers: useOthersSuspense,\n useOthersMapped: useOthersMappedSuspense,\n useOthersConnectionIds: useOthersConnectionIdsSuspense,\n useOther: useOtherSuspense,\n\n useMutation,\n },\n };\n}\n","import { useReducer, useRef } from \"react\";\n\n/**\n * Trigger a re-render programmatically, without changing the component's\n * state.\n *\n * Usage:\n *\n * const rerender = useRerender();\n * return (\n * <button onClick={rerender}>\n * {Math.random()}\n * </button>\n * )\n *\n */\nexport function useRerender(): () => void {\n const [, update] = useReducer(\n // This implementation works by incrementing a hidden counter value that is\n // never consumed. Simply incrementing the counter changes the component's\n // state and, thus, trigger a re-render.\n (x: number): number => x + 1,\n 0\n );\n return update;\n}\n\n/**\n * \"Freezes\" a given value, so that it will return the same value/instance on\n * each subsequent render. This can be used to freeze \"initial\" values for\n * custom hooks, much like how `useState(initialState)` or\n * `useRef(initialValue)` works.\n */\nexport function useInitial<T>(value: T): T {\n return useRef(value).current;\n}\n","export { ClientSideSuspense } from \"./ClientSideSuspense\";\nexport { createRoomContext } from \"./factory\";\nexport type { MutationContext } from \"./types\";\n\n// Re-exports from @liveblocks/client, for convenience\nexport type { Json, JsonObject } from \"@liveblocks/client\";\nexport { shallow } from \"@liveblocks/client\";\n"],"mappings":"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","names":["React","other","rootOrNull","shallow"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/version.ts","../src/ClientSideSuspense.tsx","../src/factory.tsx","../src/hooks.ts"],"sourcesContent":["import { detectDupes } from \"@liveblocks/core\";\n\nimport { PKG_FORMAT, PKG_NAME, PKG_VERSION } from \"./version\";\n\ndetectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);\n\nexport { ClientSideSuspense } from \"./ClientSideSuspense\";\nexport { createRoomContext } from \"./factory\";\nexport type { MutationContext } from \"./types\";\n\n// Re-exports from @liveblocks/client, for convenience\nexport type { Json, JsonObject } from \"@liveblocks/client\";\nexport { shallow } from \"@liveblocks/client\";\n","declare const __VERSION__: string;\ndeclare const TSUP_FORMAT: string;\n\nexport const PKG_NAME = \"@liveblocks/react\";\nexport const PKG_VERSION = typeof __VERSION__ === \"string\" && __VERSION__;\nexport const PKG_FORMAT = typeof TSUP_FORMAT === \"string\" && TSUP_FORMAT;\n","import type { ReactElement, ReactNode } from \"react\";\nimport * as React from \"react\";\n\ntype Props = {\n fallback: NonNullable<ReactNode> | null;\n children: () => ReactNode | undefined;\n};\n\n/**\n * Almost like a normal <Suspense> component, except that for server-side\n * renders, the fallback will be used.\n *\n * The child props will have to be provided in a function, i.e. change:\n *\n * <Suspense fallback={<Loading />}>\n * <MyRealComponent a={1} />\n * </Suspense>\n *\n * To:\n *\n * <ClientSideSuspense fallback={<Loading />}>\n * {() => <MyRealComponent a={1} />}\n * </ClientSideSuspense>\n *\n */\nexport function ClientSideSuspense(props: Props): ReactElement {\n const [mounted, setMounted] = React.useState(false);\n\n React.useEffect(() => {\n // Effects are never executed on the server side. The point of this is to\n // delay the flipping of this boolean until after hydration has happened.\n setMounted(true);\n }, []);\n\n return (\n <React.Suspense fallback={props.fallback}>\n {mounted ? props.children() : props.fallback}\n </React.Suspense>\n );\n}\n","import type {\n BaseUserMeta,\n BroadcastOptions,\n Client,\n History,\n Json,\n JsonObject,\n LiveObject,\n LostConnectionEvent,\n LsonObject,\n Others,\n Room,\n Status,\n User,\n} from \"@liveblocks/client\";\nimport { shallow } from \"@liveblocks/client\";\nimport type { ToImmutable } from \"@liveblocks/core\";\nimport {\n asArrayWithLegacyMethods,\n deprecateIf,\n errorIf,\n} from \"@liveblocks/core\";\nimport * as React from \"react\";\nimport { useSyncExternalStoreWithSelector } from \"use-sync-external-store/shim/with-selector.js\";\n\nimport { useInitial, useRerender } from \"./hooks\";\nimport type {\n MutationContext,\n OmitFirstArg,\n RoomContextBundle,\n RoomProviderProps,\n} from \"./types\";\n\nconst noop = () => {};\nconst identity: <T>(x: T) => T = (x) => x;\n\nconst missing_unstable_batchedUpdates = (\n reactVersion: number,\n roomId: string\n) =>\n `We noticed you’re using React ${reactVersion}. Please pass unstable_batchedUpdates at the RoomProvider level until you’re ready to upgrade to React 18:\n\n import { unstable_batchedUpdates } from \"react-dom\"; // or \"react-native\"\n\n <RoomProvider id=${JSON.stringify(\n roomId\n )} ... unstable_batchedUpdates={unstable_batchedUpdates}>\n ...\n </RoomProvider>\n\nWhy? Please see https://liveblocks.io/docs/guides/troubleshooting#stale-props-zombie-child for more information`;\n\nconst superfluous_unstable_batchedUpdates =\n \"You don’t need to pass unstable_batchedUpdates to RoomProvider anymore, since you’re on React 18+ already.\";\n\nfunction useSyncExternalStore<Snapshot>(\n s: (onStoreChange: () => void) => () => void,\n gs: () => Snapshot,\n gss: undefined | null | (() => Snapshot)\n): Snapshot {\n return useSyncExternalStoreWithSelector(s, gs, gss, identity);\n}\n\nconst EMPTY_OTHERS =\n // NOTE: asArrayWithLegacyMethods() wrapping should no longer be necessary in 0.19\n asArrayWithLegacyMethods([]);\n\nfunction getEmptyOthers() {\n return EMPTY_OTHERS;\n}\n\nfunction makeMutationContext<\n TPresence extends JsonObject,\n TStorage extends LsonObject,\n TUserMeta extends BaseUserMeta,\n TRoomEvent extends Json,\n>(\n room: Room<TPresence, TStorage, TUserMeta, TRoomEvent>\n): MutationContext<TPresence, TStorage, TUserMeta> {\n const errmsg =\n \"This mutation cannot be used until connected to the Liveblocks room\";\n\n return {\n get storage() {\n const mutableRoot = room.getStorageSnapshot();\n if (mutableRoot === null) {\n throw new Error(errmsg);\n }\n return mutableRoot;\n },\n\n get self() {\n const self = room.getSelf();\n if (self === null) {\n throw new Error(errmsg);\n }\n return self;\n },\n\n get others() {\n const others = room.getOthers();\n if (room.getSelf() === null) {\n throw new Error(errmsg);\n }\n return others;\n },\n\n setMyPresence: room.updatePresence,\n };\n}\n\nexport function createRoomContext<\n TPresence extends JsonObject,\n TStorage extends LsonObject = LsonObject,\n TUserMeta extends BaseUserMeta = BaseUserMeta,\n TRoomEvent extends Json = never,\n>(\n client: Client\n): RoomContextBundle<TPresence, TStorage, TUserMeta, TRoomEvent> {\n const RoomContext = React.createContext<Room<\n TPresence,\n TStorage,\n TUserMeta,\n TRoomEvent\n > | null>(null);\n\n function RoomProvider(props: RoomProviderProps<TPresence, TStorage>) {\n const {\n id: roomId,\n initialPresence,\n initialStorage,\n unstable_batchedUpdates,\n shouldInitiallyConnect,\n } = props;\n\n if (process.env.NODE_ENV !== \"production\") {\n if (!roomId) {\n throw new Error(\n \"RoomProvider id property is required. For more information: https://liveblocks.io/docs/errors/liveblocks-react/RoomProvider-id-property-is-required\"\n );\n }\n\n if (typeof roomId !== \"string\") {\n throw new Error(\"RoomProvider id property should be a string.\");\n }\n\n const majorReactVersion = parseInt(React.version) || 1;\n const oldReactVersion = majorReactVersion < 18;\n errorIf(\n oldReactVersion && props.unstable_batchedUpdates === undefined,\n missing_unstable_batchedUpdates(majorReactVersion, roomId)\n );\n deprecateIf(\n !oldReactVersion && props.unstable_batchedUpdates !== undefined,\n superfluous_unstable_batchedUpdates\n );\n }\n\n // Note: We'll hold on to the initial value given here, and ignore any\n // changes to this argument in subsequent renders\n const frozen = useInitial({\n initialPresence,\n initialStorage,\n unstable_batchedUpdates,\n shouldInitiallyConnect:\n shouldInitiallyConnect === undefined\n ? typeof window !== \"undefined\"\n : shouldInitiallyConnect,\n });\n\n const [room, setRoom] = React.useState<\n Room<TPresence, TStorage, TUserMeta, TRoomEvent>\n >(() =>\n client.enter(roomId, {\n initialPresence: frozen.initialPresence,\n initialStorage: frozen.initialStorage,\n shouldInitiallyConnect: frozen.shouldInitiallyConnect,\n unstable_batchedUpdates: frozen.unstable_batchedUpdates,\n })\n );\n\n React.useEffect(() => {\n setRoom(\n client.enter(roomId, {\n initialPresence: frozen.initialPresence,\n initialStorage: frozen.initialStorage,\n shouldInitiallyConnect: frozen.shouldInitiallyConnect,\n unstable_batchedUpdates: frozen.unstable_batchedUpdates,\n })\n );\n\n return () => {\n client.leave(roomId);\n };\n }, [roomId, frozen]);\n\n return (\n <RoomContext.Provider value={room}>{props.children}</RoomContext.Provider>\n );\n }\n\n function connectionIdSelector(\n others: Others<TPresence, TUserMeta>\n ): number[] {\n return others.map((user) => user.connectionId);\n }\n\n function useRoom(): Room<TPresence, TStorage, TUserMeta, TRoomEvent> {\n const room = React.useContext(RoomContext);\n if (room === null) {\n throw new Error(\"RoomProvider is missing from the react tree\");\n }\n return room;\n }\n\n function useStatus(): Status {\n const room = useRoom();\n const subscribe = room.events.status.subscribe;\n const getSnapshot = room.getStatus;\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n }\n\n function useMyPresence(): [\n TPresence,\n (patch: Partial<TPresence>, options?: { addToHistory: boolean }) => void,\n ] {\n const room = useRoom();\n const subscribe = room.events.myPresence.subscribe;\n const getSnapshot = room.getPresence;\n const presence = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n const setPresence = room.updatePresence;\n return [presence, setPresence];\n }\n\n function useUpdateMyPresence(): (\n patch: Partial<TPresence>,\n options?: { addToHistory: boolean }\n ) => void {\n return useRoom().updatePresence;\n }\n\n function useOthers(): Others<TPresence, TUserMeta>;\n function useOthers<T>(\n selector: (others: Others<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T;\n function useOthers<T>(\n selector?: (others: Others<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T | Others<TPresence, TUserMeta> {\n const room = useRoom();\n const subscribe = room.events.others.subscribe;\n const getSnapshot = room.getOthers;\n const getServerSnapshot = getEmptyOthers;\n return useSyncExternalStoreWithSelector(\n subscribe,\n getSnapshot,\n getServerSnapshot,\n selector ?? (identity as (others: Others<TPresence, TUserMeta>) => T),\n isEqual\n );\n }\n\n function useOthersConnectionIds(): readonly number[] {\n return useOthers(connectionIdSelector, shallow);\n }\n\n function useOthersMapped<T>(\n itemSelector: (other: User<TPresence, TUserMeta>) => T,\n itemIsEqual?: (prev: T, curr: T) => boolean\n ): ReadonlyArray<readonly [connectionId: number, data: T]> {\n const wrappedSelector = React.useCallback(\n (others: Others<TPresence, TUserMeta>) =>\n others.map(\n (other) => [other.connectionId, itemSelector(other)] as const\n ),\n [itemSelector]\n );\n\n const wrappedIsEqual = React.useCallback(\n (\n a: ReadonlyArray<readonly [connectionId: number, data: T]>,\n b: ReadonlyArray<readonly [connectionId: number, data: T]>\n ): boolean => {\n const eq = itemIsEqual ?? Object.is;\n return (\n a.length === b.length &&\n a.every((atuple, index) => {\n const btuple = b[index];\n return atuple[0] === btuple[0] && eq(atuple[1], btuple[1]);\n })\n );\n },\n [itemIsEqual]\n );\n\n return useOthers(wrappedSelector, wrappedIsEqual);\n }\n\n const NOT_FOUND = Symbol();\n\n type NotFound = typeof NOT_FOUND;\n\n function useOther<T>(\n connectionId: number,\n selector: (other: User<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T {\n const wrappedSelector = React.useCallback(\n (others: Others<TPresence, TUserMeta>) => {\n // TODO: Make this O(1) instead of O(n)?\n const other = others.find(\n (other) => other.connectionId === connectionId\n );\n return other !== undefined ? selector(other) : NOT_FOUND;\n },\n [connectionId, selector]\n );\n\n const wrappedIsEqual = React.useCallback(\n (prev: T | NotFound, curr: T | NotFound): boolean => {\n if (prev === NOT_FOUND || curr === NOT_FOUND) {\n return prev === curr;\n }\n\n const eq = isEqual ?? Object.is;\n return eq(prev, curr);\n },\n [isEqual]\n );\n\n const other = useOthers(wrappedSelector, wrappedIsEqual);\n if (other === NOT_FOUND) {\n throw new Error(\n `No such other user with connection id ${connectionId} exists`\n );\n }\n\n return other;\n }\n\n function useBroadcastEvent(): (\n event: TRoomEvent,\n options?: BroadcastOptions\n ) => void {\n const room = useRoom();\n\n return React.useCallback(\n (\n event: TRoomEvent,\n options: BroadcastOptions = { shouldQueueEventIfNotReady: false }\n ) => {\n room.broadcastEvent(event, options);\n },\n [room]\n );\n }\n\n function useLostConnectionListener(\n callback: (event: LostConnectionEvent) => void\n ): void {\n const room = useRoom();\n const savedCallback = React.useRef(callback);\n\n React.useEffect(() => {\n savedCallback.current = callback;\n });\n\n React.useEffect(\n () =>\n room.events.lostConnection.subscribe((event: LostConnectionEvent) =>\n savedCallback.current(event)\n ),\n [room]\n );\n }\n\n function useErrorListener(callback: (err: Error) => void): void {\n const room = useRoom();\n const savedCallback = React.useRef(callback);\n\n React.useEffect(() => {\n savedCallback.current = callback;\n });\n\n React.useEffect(\n () => room.events.error.subscribe((e: Error) => savedCallback.current(e)),\n [room]\n );\n }\n\n function useEventListener(\n callback: (eventData: { connectionId: number; event: TRoomEvent }) => void\n ): void {\n const room = useRoom();\n const savedCallback = React.useRef(callback);\n\n React.useEffect(() => {\n savedCallback.current = callback;\n });\n\n React.useEffect(() => {\n const listener = (eventData: {\n connectionId: number;\n event: TRoomEvent;\n }) => {\n savedCallback.current(eventData);\n };\n\n return room.events.customEvent.subscribe(listener);\n }, [room]);\n }\n\n function useSelf(): User<TPresence, TUserMeta> | null;\n function useSelf<T>(\n selector: (me: User<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T | null, curr: T | null) => boolean\n ): T | null;\n function useSelf<T>(\n maybeSelector?: (me: User<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T | null, curr: T | null) => boolean\n ): T | User<TPresence, TUserMeta> | null {\n type Snapshot = User<TPresence, TUserMeta> | null;\n type Selection = T | null;\n\n const room = useRoom();\n const subscribe = room.events.self.subscribe;\n const getSnapshot: () => Snapshot = room.getSelf;\n\n const selector =\n maybeSelector ?? (identity as (me: User<TPresence, TUserMeta>) => T);\n const wrappedSelector = React.useCallback(\n (me: Snapshot): Selection => (me !== null ? selector(me) : null),\n [selector]\n );\n\n const getServerSnapshot = React.useCallback((): Snapshot => null, []);\n\n return useSyncExternalStoreWithSelector(\n subscribe,\n getSnapshot,\n getServerSnapshot,\n wrappedSelector,\n isEqual\n );\n }\n\n function useMutableStorageRoot(): LiveObject<TStorage> | null {\n type Snapshot = LiveObject<TStorage> | null;\n const room = useRoom();\n const subscribe = room.events.storageDidLoad.subscribeOnce;\n const getSnapshot = room.getStorageSnapshot;\n const getServerSnapshot = React.useCallback((): Snapshot => null, []);\n return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n }\n\n // NOTE: This API exists for backward compatible reasons\n function useStorageRoot(): [root: LiveObject<TStorage> | null] {\n return [useMutableStorageRoot()];\n }\n\n function useHistory(): History {\n return useRoom().history;\n }\n\n function useUndo(): () => void {\n return useHistory().undo;\n }\n\n function useRedo(): () => void {\n return useHistory().redo;\n }\n\n function useCanUndo(): boolean {\n const room = useRoom();\n const subscribe = room.events.history.subscribe;\n const canUndo = room.history.canUndo;\n return useSyncExternalStore(subscribe, canUndo, canUndo);\n }\n\n function useCanRedo(): boolean {\n const room = useRoom();\n const subscribe = room.events.history.subscribe;\n const canRedo = room.history.canRedo;\n return useSyncExternalStore(subscribe, canRedo, canRedo);\n }\n\n function useBatch<T>(): (callback: () => T) => T {\n return useRoom().batch;\n }\n\n function useLegacyKey<TKey extends Extract<keyof TStorage, string>>(\n key: TKey\n ): TStorage[TKey] | null {\n const room = useRoom();\n const root = useMutableStorageRoot();\n const rerender = useRerender();\n\n React.useEffect(() => {\n if (root === null) {\n return;\n }\n\n let liveValue = root.get(key);\n\n function onRootChange() {\n const newCrdt = root!.get(key);\n if (newCrdt !== liveValue) {\n unsubscribeCrdt();\n liveValue = newCrdt;\n unsubscribeCrdt = room.subscribe(\n liveValue as any /* AbstractCrdt */, // TODO: This is hiding a bug! If `liveValue` happens to be the string `\"event\"` this actually subscribes an event handler!\n rerender\n );\n rerender();\n }\n }\n\n let unsubscribeCrdt = room.subscribe(\n liveValue as any /* AbstractCrdt */, // TODO: This is hiding a bug! If `liveValue` happens to be the string `\"event\"` this actually subscribes an event handler!\n rerender\n );\n const unsubscribeRoot = room.subscribe(\n root as any /* AbstractCrdt */, // TODO: This is hiding a bug! If `liveValue` happens to be the string `\"event\"` this actually subscribes an event handler!\n onRootChange\n );\n\n rerender();\n\n return () => {\n unsubscribeRoot();\n unsubscribeCrdt();\n };\n }, [root, room, key, rerender]);\n\n if (root === null) {\n return null;\n } else {\n return root.get(key);\n }\n }\n\n function useStorage<T>(\n selector: (root: ToImmutable<TStorage>) => T,\n isEqual?: (prev: T | null, curr: T | null) => boolean\n ): T | null {\n type Snapshot = ToImmutable<TStorage> | null;\n type Selection = T | null;\n\n const room = useRoom();\n const rootOrNull = useMutableStorageRoot();\n\n const wrappedSelector = React.useCallback(\n (rootOrNull: Snapshot): Selection =>\n rootOrNull !== null ? selector(rootOrNull) : null,\n [selector]\n );\n\n const subscribe = React.useCallback(\n (onStoreChange: () => void) =>\n rootOrNull !== null\n ? room.subscribe(rootOrNull, onStoreChange, { isDeep: true })\n : noop,\n [room, rootOrNull]\n );\n\n const getSnapshot = React.useCallback((): Snapshot => {\n if (rootOrNull === null) {\n return null;\n } else {\n const root = rootOrNull;\n const imm = root.toImmutable();\n return imm;\n }\n }, [rootOrNull]);\n\n const getServerSnapshot = React.useCallback((): Snapshot => null, []);\n\n return useSyncExternalStoreWithSelector(\n subscribe,\n getSnapshot,\n getServerSnapshot,\n wrappedSelector,\n isEqual\n );\n }\n\n function ensureNotServerSide(): void {\n // Error early if suspense is used in a server-side context\n if (typeof window === \"undefined\") {\n throw new Error(\n \"You cannot use the Suspense version of this hook on the server side. Make sure to only call them on the client side.\\nFor tips, see https://liveblocks.io/docs/api-reference/liveblocks-react#suspense-avoid-ssr\"\n );\n }\n }\n\n function useSuspendUntilStorageLoaded(): void {\n const room = useRoom();\n if (room.getStorageSnapshot() !== null) {\n return;\n }\n\n ensureNotServerSide();\n\n // Throw a _promise_. Suspense will suspend the component tree until this\n // promise resolves (aka until storage has loaded). After that, it will\n // render this component tree again.\n throw new Promise<void>((res) => {\n room.events.storageDidLoad.subscribeOnce(() => res());\n });\n }\n\n function useSuspendUntilPresenceLoaded(): void {\n const room = useRoom();\n if (room.getSelf() !== null) {\n return;\n }\n\n ensureNotServerSide();\n\n // Throw a _promise_. Suspense will suspend the component tree until this\n // promise resolves (aka until storage has loaded). After that, it will\n // render this component tree again.\n throw new Promise<void>((res) => {\n room.events.status.subscribeOnce(() => res());\n });\n }\n\n function useMutation<\n F extends (\n context: MutationContext<TPresence, TStorage, TUserMeta>,\n ...args: any[]\n ) => any,\n >(callback: F, deps: readonly unknown[]): OmitFirstArg<F> {\n const room = useRoom();\n return React.useMemo(\n () => {\n return ((...args) =>\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n room.batch(() =>\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n callback(\n makeMutationContext(room),\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n ...args\n )\n )) as OmitFirstArg<F>;\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [room, ...deps]\n );\n }\n\n function useStorageSuspense<T>(\n selector: (root: ToImmutable<TStorage>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T {\n useSuspendUntilStorageLoaded();\n return useStorage(\n selector,\n isEqual as (prev: T | null, curr: T | null) => boolean\n ) as T;\n }\n\n function useSelfSuspense(): User<TPresence, TUserMeta>;\n function useSelfSuspense<T>(\n selector: (me: User<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T;\n function useSelfSuspense<T>(\n selector?: (me: User<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T | User<TPresence, TUserMeta> {\n useSuspendUntilPresenceLoaded();\n return useSelf(\n selector as (me: User<TPresence, TUserMeta>) => T,\n isEqual as (prev: T | null, curr: T | null) => boolean\n ) as T | User<TPresence, TUserMeta>;\n }\n\n function useOthersSuspense<T>(\n selector?: (others: Others<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T | Others<TPresence, TUserMeta> {\n useSuspendUntilPresenceLoaded();\n return useOthers(\n selector as (others: Others<TPresence, TUserMeta>) => T,\n isEqual as (prev: T, curr: T) => boolean\n ) as T | Others<TPresence, TUserMeta>;\n }\n\n function useOthersConnectionIdsSuspense(): readonly number[] {\n useSuspendUntilPresenceLoaded();\n return useOthersConnectionIds();\n }\n\n function useOthersMappedSuspense<T>(\n itemSelector: (other: User<TPresence, TUserMeta>) => T,\n itemIsEqual?: (prev: T, curr: T) => boolean\n ): ReadonlyArray<readonly [connectionId: number, data: T]> {\n useSuspendUntilPresenceLoaded();\n return useOthersMapped(itemSelector, itemIsEqual);\n }\n\n function useOtherSuspense<T>(\n connectionId: number,\n selector: (other: User<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T {\n useSuspendUntilPresenceLoaded();\n return useOther(connectionId, selector, isEqual);\n }\n\n function useLegacyKeySuspense<TKey extends Extract<keyof TStorage, string>>(\n key: TKey\n ): TStorage[TKey] {\n useSuspendUntilStorageLoaded();\n return useLegacyKey(key) as TStorage[TKey];\n }\n\n return {\n RoomContext,\n RoomProvider,\n\n useRoom,\n useStatus,\n\n useBatch,\n useBroadcastEvent,\n useLostConnectionListener,\n useErrorListener,\n useEventListener,\n\n useHistory,\n useUndo,\n useRedo,\n useCanRedo,\n useCanUndo,\n\n // These are just aliases. The passed-in key will define their return values.\n useList: useLegacyKey,\n useMap: useLegacyKey,\n useObject: useLegacyKey,\n\n useStorageRoot,\n useStorage,\n\n useSelf,\n useMyPresence,\n useUpdateMyPresence,\n useOthers,\n useOthersMapped,\n useOthersConnectionIds,\n useOther,\n\n useMutation,\n\n suspense: {\n RoomContext,\n RoomProvider,\n\n useRoom,\n useStatus,\n\n useBatch,\n useBroadcastEvent,\n useLostConnectionListener,\n useErrorListener,\n useEventListener,\n\n useHistory,\n useUndo,\n useRedo,\n useCanRedo,\n useCanUndo,\n\n // Legacy hooks\n useList: useLegacyKeySuspense,\n useMap: useLegacyKeySuspense,\n useObject: useLegacyKeySuspense,\n\n useStorageRoot,\n useStorage: useStorageSuspense,\n\n useSelf: useSelfSuspense,\n useMyPresence,\n useUpdateMyPresence,\n useOthers: useOthersSuspense,\n useOthersMapped: useOthersMappedSuspense,\n useOthersConnectionIds: useOthersConnectionIdsSuspense,\n useOther: useOtherSuspense,\n\n useMutation,\n },\n };\n}\n","import { useReducer, useRef } from \"react\";\n\n/**\n * Trigger a re-render programmatically, without changing the component's\n * state.\n *\n * Usage:\n *\n * const rerender = useRerender();\n * return (\n * <button onClick={rerender}>\n * {Math.random()}\n * </button>\n * )\n *\n */\nexport function useRerender(): () => void {\n const [, update] = useReducer(\n // This implementation works by incrementing a hidden counter value that is\n // never consumed. Simply incrementing the counter changes the component's\n // state and, thus, trigger a re-render.\n (x: number): number => x + 1,\n 0\n );\n return update;\n}\n\n/**\n * \"Freezes\" a given value, so that it will return the same value/instance on\n * each subsequent render. This can be used to freeze \"initial\" values for\n * custom hooks, much like how `useState(initialState)` or\n * `useRef(initialValue)` works.\n */\nexport function useInitial<T>(value: T): T {\n return useRef(value).current;\n}\n"],"mappings":"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","names":["React","other","rootOrNull","shallow"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@liveblocks/react",
3
- "version": "1.2.0-internal6",
3
+ "version": "1.2.0",
4
4
  "description": "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.",
5
5
  "license": "Apache-2.0",
6
6
  "main": "./dist/index.js",
@@ -34,8 +34,8 @@
34
34
  "test:watch": "jest --silent --verbose --color=always --watch"
35
35
  },
36
36
  "dependencies": {
37
- "@liveblocks/client": "1.2.0-internal6",
38
- "@liveblocks/core": "1.2.0-internal6",
37
+ "@liveblocks/client": "1.2.0",
38
+ "@liveblocks/core": "1.2.0",
39
39
  "use-sync-external-store": "^1.2.0"
40
40
  },
41
41
  "peerDependencies": {