From 6d604146375e88806f58aa3c15541d2a56c0999f Mon Sep 17 00:00:00 2001 From: stopachka Date: Thu, 16 Jan 2025 09:57:52 -0800 Subject: [PATCH] roar roar keep rolling roar roar roar roar sm --- .../react/src/InstantReactAbstractDatabase.ts | 23 ++- client/packages/react/src/InstantReactRoom.ts | 165 +++++++++++++----- .../src/typescript_tests_experimental_v2.tsx | 39 ++++- ...script_tests_experimental_v2_no_schema.tsx | 33 +++- ...ypescript_tests_normal_as_experimental.tsx | 28 ++- client/www/pages/docs/presence-and-topics.md | 32 ++-- .../www/pages/examples/4-custom-cursors.tsx | 2 +- client/www/pages/examples/5-reactions.tsx | 34 ++-- .../www/pages/examples/6-typing-indicator.tsx | 9 +- client/www/pages/examples/7-avatar-stack.tsx | 2 +- .../www/pages/examples/8-merge-tile-game.tsx | 11 +- client/www/pages/index.tsx | 2 +- 12 files changed, 279 insertions(+), 101 deletions(-) diff --git a/client/packages/react/src/InstantReactAbstractDatabase.ts b/client/packages/react/src/InstantReactAbstractDatabase.ts index f8b9ccdc7..7894020f4 100644 --- a/client/packages/react/src/InstantReactAbstractDatabase.ts +++ b/client/packages/react/src/InstantReactAbstractDatabase.ts @@ -31,7 +31,7 @@ import { } from "react"; import { useQueryInternal } from "./useQuery"; import { useTimeout } from "./useTimeout"; -import { InstantReactRoom } from "./InstantReactRoom"; +import { InstantReactRoom, rooms } from "./InstantReactRoom"; const defaultAuthState = { isLoading: true, @@ -82,12 +82,8 @@ export default abstract class InstantReactAbstractDatabase< * @see https://instantdb.com/docs/presence-and-topics * * @example - * const { - * useTopicEffect, - * usePublishTopic, - * useSyncPresence, - * useTypingIndicator, - * } = db.room(roomType, roomId); + * const room = db.room('chat', roomId); + * const { peers } = db.rooms.usePresence(room); */ room( type: RoomType = "_defaultRoomType" as RoomType, @@ -96,6 +92,19 @@ export default abstract class InstantReactAbstractDatabase< return new InstantReactRoom(this._core, type, id); } + /** + * Hooks for working with rooms + * + * @see https://instantdb.com/docs/presence-and-topics + * + * @example + * const room = db.room('chat', roomId); + * const { peers } = db.rooms.usePresence(room); + * const publish = db.rooms.usePublishTopic(room, 'emoji'); + * // ... + */ + rooms = rooms + /** * Use this to write data! You can create, update, delete, and link objects * diff --git a/client/packages/react/src/InstantReactRoom.ts b/client/packages/react/src/InstantReactRoom.ts index 9b55daa54..6ae1a4438 100644 --- a/client/packages/react/src/InstantReactRoom.ts +++ b/client/packages/react/src/InstantReactRoom.ts @@ -45,7 +45,20 @@ export const defaultActivityStopTimeout = 1_000; // ------ // Topics -function useTopicEffect< +/** + * Listen for broadcasted events given a room and topic. + * + * @see https://instantdb.com/docs/presence-and-topics + * @example + * function App({ roomId }) { + * const room = db.room('chats', roomId); + * db.rooms.useTopicEffect(room, 'emoji', (message, peer) => { + * console.log(peer.name, 'sent', message); + * }); + * // ... + * } + */ +export function useTopicEffect< RoomSchema extends RoomSchemaShape, RoomType extends keyof RoomSchema, TopicType extends keyof RoomSchema[RoomType]["topics"], @@ -70,7 +83,22 @@ function useTopicEffect< }, [room.id, topic]); } -function usePublishTopic< +/** + * Broadcast an event to a room. + * + * @see https://instantdb.com/docs/presence-and-topics + * @example + * function App({ roomId }) { + * const room = db.room('chat', roomId); + * const publishTopic = db.rooms.usePublishTopic(room, "emoji"); + * + * return ( + * + * ); + * } + * + */ +export function usePublishTopic< RoomSchema extends RoomSchemaShape, RoomType extends keyof RoomSchema, TopicType extends keyof RoomSchema[RoomType]["topics"], @@ -98,7 +126,21 @@ function usePublishTopic< // --------- // Presence -function usePresence< +/** + * Listen for peer's presence data in a room, and publish the current user's presence. + * + * @see https://instantdb.com/docs/presence-and-topics + * @example + * function App({ roomId }) { + * const { + * peers, + * publishPresence + * } = db.room(roomType, roomId).usePresence({ keys: ["name", "avatar"] }); + * + * // ... + * } + */ +export function usePresence< RoomSchema extends RoomSchemaShape, RoomType extends keyof RoomSchema, Keys extends keyof RoomSchema[RoomType]["presence"], @@ -138,7 +180,17 @@ function usePresence< }; } -function useSyncPresence< +/** + * Publishes presence data to a room + * + * @see https://instantdb.com/docs/presence-and-topics + * @example + * function App({ roomId, nickname }) { + * const room = db.room('chat', roomId); + * db.rooms.useSyncPresence(room, { nickname }); + * } + */ +export function useSyncPresence< RoomSchema extends RoomSchemaShape, RoomType extends keyof RoomSchema, >( @@ -155,7 +207,23 @@ function useSyncPresence< // ----------------- // Typing Indicator -function useTypingIndicator< +/** + * Manage typing indicator state + * + * @see https://instantdb.com/docs/presence-and-topics + * @example + * function App({ roomId }) { + * const room = db.room('chat', roomId); + * const { + * active, + * setActive, + * inputProps, + * } = db.rooms.useTypingIndicator(room, "chat-input"); + * + * return ; + * } + */ +export function useTypingIndicator< RoomSchema extends RoomSchemaShape, RoomType extends keyof RoomSchema, >( @@ -220,7 +288,7 @@ function useTypingIndicator< // -------------- // Hooks -const rooms = { +export const rooms = { useTopicEffect, usePublishTopic, usePresence, @@ -247,17 +315,18 @@ export class InstantReactRoom< } /** - * Listen for broadcasted events given a room and topic. + * @deprecated + * `db.room(...).useTopicEffect` is deprecated. You can replace it with `db.rooms.useTopicEffect`. * - * @see https://instantdb.com/docs/presence-and-topics * @example - * function App({ roomId }) { - * db.room(roomType, roomId).useTopicEffect("chat", (message, peer) => { - * console.log("New message", message, 'from', peer.name); - * }); * - * // ... - * } + * // Before + * const room = db.room('chat', 'room-id'); + * room.useTopicEffect('emoji', (message, peer) => { }); + * + * // After + * const room = db.room('chat', 'room-id'); + * db.rooms.useTopicEffect(room, 'emoji', (message, peer) => { }); */ useTopicEffect = ( topic: TopicType, @@ -270,18 +339,18 @@ export class InstantReactRoom< }; /** - * Broadcast an event to a room. + * @deprecated + * `db.room(...).usePublishTopic` is deprecated. You can replace it with `db.rooms.usePublishTopic`. * - * @see https://instantdb.com/docs/presence-and-topics * @example - * function App({ roomId }) { - * const publishTopic = db.room(roomType, roomId).usePublishTopic("clicks"); * - * return ( - * - * ); - * } + * // Before + * const room = db.room('chat', 'room-id'); + * const publish = room.usePublishTopic('emoji'); * + * // After + * const room = db.room('chat', 'room-id'); + * const publish = db.rooms.usePublishTopic(room, 'emoji'); */ usePublishTopic = ( topic: Topic, @@ -290,18 +359,18 @@ export class InstantReactRoom< }; /** - * Listen for peer's presence data in a room, and publish the current user's presence. + * @deprecated + * `db.room(...).usePresence` is deprecated. You can replace it with `db.rooms.usePresence`. * - * @see https://instantdb.com/docs/presence-and-topics * @example - * function App({ roomId }) { - * const { - * peers, - * publishPresence - * } = db.room(roomType, roomId).usePresence({ keys: ["name", "avatar"] }); * - * // ... - * } + * // Before + * const room = db.room('chat', 'room-id'); + * const { peers } = room.usePresence({ keys: ["name", "avatar"] }); + * + * // After + * const room = db.room('chat', 'room-id'); + * const { peers } = db.rooms.usePresence(room, { keys: ["name", "avatar"] }); */ usePresence = ( opts: PresenceOpts = {}, @@ -310,15 +379,18 @@ export class InstantReactRoom< }; /** - * Publishes presence data to a room + * @deprecated + * `db.room(...).useSyncPresence` is deprecated. You can replace it with `db.rooms.useSyncPresence`. * - * @see https://instantdb.com/docs/presence-and-topics * @example - * function App({ roomId }) { - * db.room(roomType, roomId).useSyncPresence({ name, avatar, color }); * - * // ... - * } + * // Before + * const room = db.room('chat', 'room-id'); + * room.useSyncPresence(room, { nickname }); + * + * // After + * const room = db.room('chat', 'room-id'); + * db.rooms.useSyncPresence(room, { nickname }); */ useSyncPresence = ( data: Partial, @@ -328,19 +400,18 @@ export class InstantReactRoom< }; /** - * Manage typing indicator state + * @deprecated + * `db.room(...).useTypingIndicator` is deprecated. You can replace it with `db.rooms.useTypingIndicator`. * - * @see https://instantdb.com/docs/presence-and-topics * @example - * function App({ roomId }) { - * const { - * active, - * setActive, - * inputProps, - * } = db.room(roomType, roomId).useTypingIndicator("chat-input", opts); * - * return ; - * } + * // Before + * const room = db.room('chat', 'room-id'); + * const typing = room.useTypingIndiactor(room, 'chat-input'); + * + * // After + * const room = db.room('chat', 'room-id'); + * const typing = db.rooms.useTypingIndiactor(room, 'chat-input'); */ useTypingIndicator = ( inputName: string, diff --git a/client/sandbox/strong-init-vite/src/typescript_tests_experimental_v2.tsx b/client/sandbox/strong-init-vite/src/typescript_tests_experimental_v2.tsx index 1838238a6..b22ad2967 100644 --- a/client/sandbox/strong-init-vite/src/typescript_tests_experimental_v2.tsx +++ b/client/sandbox/strong-init-vite/src/typescript_tests_experimental_v2.tsx @@ -64,6 +64,27 @@ function ReactNormalApp() { const _reactPublishEmoji = reactRoom.usePublishTopic("emoji"); const _reactPresenceUser = reactPresence.user!; const _reactPresencePeers = reactPresence.peers!; + _reactPresenceUser.name; + _reactPresencePeers[0].name; + + const reactPresenceNew = reactDB.rooms.usePresence(reactRoom, { keys: ["name"] }); + const _reactPublishEmojiNew = reactDB.rooms.usePublishTopic(reactRoom, "emoji"); + const _reactPresenceUserNew = reactPresenceNew.user!; + const _reactPresencePeersNew = reactPresenceNew.peers!; + _reactPresenceUserNew.name; + _reactPresencePeersNew[0].name; + + // More room tsts + reactDB.rooms.useTopicEffect(reactRoom, "emoji", (emoji) => { + emoji.directionAngle; + }); + const publish = reactDB.rooms.usePublishTopic(reactRoom, "emoji"); + publish({ name: "confetti", rotationAngle: 1, directionAngle: 0 }) + + reactDB.rooms.useSyncPresence(reactRoom, { name: 'foo', avatarURI: 'bar' }); + const typing = reactDB.rooms.useTypingIndicator(reactRoom, 'chatInput'); + typing; + // queries const { isLoading, error, data } = reactDB.useQuery({ messages: { creator: {} }, @@ -86,7 +107,10 @@ function ReactNormalApp() { // to silence ts warnings _reactPublishEmoji; _reactPresenceUser; - _reactPresencePeers; + _reactPresencePeersNew; + _reactPublishEmojiNew; + _reactPresenceUserNew; + _reactPresencePeersNew; } // ---- @@ -104,6 +128,16 @@ function ReactNativeNormalApp() { const _reactPublishEmoji = reactRoom.usePublishTopic("emoji"); const _reactPresenceUser = reactPresence.user!; const _reactPresencePeers = reactPresence.peers!; + _reactPresenceUser.name; + _reactPresencePeers[0].name; + + const reactPresenceNew = reactNativeDB.rooms.usePresence(reactRoom, { keys: ["name"] }); + const _reactPublishEmojiNew = reactNativeDB.rooms.usePublishTopic(reactRoom, "emoji"); + const _reactPresenceUserNew = reactPresenceNew.user!; + const _reactPresencePeersNew = reactPresenceNew.peers!; + _reactPresenceUserNew.name; + _reactPresencePeersNew[0].name; + // queries const { isLoading, error, data } = reactNativeDB.useQuery({ messages: { creator: {} }, @@ -119,6 +153,9 @@ function ReactNativeNormalApp() { _reactPublishEmoji; _reactPresenceUser; _reactPresencePeers; + _reactPublishEmojiNew; + _reactPresenceUserNew; + _reactPresencePeersNew; } // ---- diff --git a/client/sandbox/strong-init-vite/src/typescript_tests_experimental_v2_no_schema.tsx b/client/sandbox/strong-init-vite/src/typescript_tests_experimental_v2_no_schema.tsx index 530cee5e6..07b33f9b3 100644 --- a/client/sandbox/strong-init-vite/src/typescript_tests_experimental_v2_no_schema.tsx +++ b/client/sandbox/strong-init-vite/src/typescript_tests_experimental_v2_no_schema.tsx @@ -53,10 +53,22 @@ const reactDB = react_init({ function ReactNormalApp() { // rooms const reactRoom = reactDB.room("chat"); + const reactPresence = reactRoom.usePresence({ keys: ["name"] }); - const _reactPublishEmoji = reactRoom.usePublishTopic("emoji"); const _reactPresenceUser = reactPresence.user!; const _reactPresencePeers = reactPresence.peers!; + _reactPresenceUser.name; + _reactPresencePeers[0].name; + + const reactPresenceNew = reactDB.rooms.usePresence(reactRoom, {keys: ["name"]}); + const _reactPresenceUserNew = reactPresenceNew.user!; + const _reactPresencePeersNew = reactPresenceNew.peers!; + _reactPresenceUserNew.name; + _reactPresencePeersNew[0].name; + + const _reactPublishEmoji = reactRoom.usePublishTopic("emoji"); + const _reactPublishEmojiNew = reactDB.rooms.usePublishTopic(reactRoom, "emoji"); + // queries const { isLoading, error, data } = reactDB.useQuery({ posts: { comments: {} }, @@ -80,6 +92,9 @@ function ReactNormalApp() { _reactPublishEmoji; _reactPresenceUser; _reactPresencePeers; + _reactPublishEmojiNew; + _reactPresenceUserNew; + _reactPresencePeersNew; } // ---- @@ -93,9 +108,20 @@ function ReactNativeNormalApp() { // rooms const reactRoom = reactNativeDB.room("chat"); const reactPresence = reactRoom.usePresence({ keys: ["name"] }); - const _reactPublishEmoji = reactRoom.usePublishTopic("emoji"); const _reactPresenceUser = reactPresence.user!; const _reactPresencePeers = reactPresence.peers!; + _reactPresenceUser.name; + _reactPresencePeers[0].name; + + const reactPresenceNew = reactNativeDB.rooms.usePresence(reactRoom, { keys: ["name"] }); + const _reactPresenceUserNew = reactPresenceNew.user!; + const _reactPresencePeersNew = reactPresenceNew.peers!; + _reactPresenceUserNew.name; + _reactPresencePeersNew[0].name; + + const _reactPublishEmoji = reactNativeDB.rooms.usePublishTopic(reactRoom, "emoji"); + const _reactPublishEmojiNew = reactRoom.usePublishTopic("emoji"); + // queries const { isLoading, error, data } = reactNativeDB.useQuery({ posts: { comments: {} }, @@ -112,6 +138,9 @@ function ReactNativeNormalApp() { _reactPublishEmoji; _reactPresenceUser; _reactPresencePeers; + _reactPublishEmojiNew; + _reactPresenceUserNew; + _reactPresencePeersNew; } // ---- diff --git a/client/sandbox/strong-init-vite/src/typescript_tests_normal_as_experimental.tsx b/client/sandbox/strong-init-vite/src/typescript_tests_normal_as_experimental.tsx index 6e6c6ab50..e93973565 100644 --- a/client/sandbox/strong-init-vite/src/typescript_tests_normal_as_experimental.tsx +++ b/client/sandbox/strong-init-vite/src/typescript_tests_normal_as_experimental.tsx @@ -88,6 +88,16 @@ function ReactNormalApp() { const _reactPublishEmoji = reactRoom.usePublishTopic("emoji"); const _reactPresenceUser = reactPresence.user!; const _reactPresencePeers = reactPresence.peers!; + _reactPresenceUser.name; + _reactPresencePeers[0].name; + + const reactPresenceNew = reactDB.rooms.usePresence(reactRoom, { keys: ["name"] }); + const _reactPublishEmojiNew = reactDB.rooms.usePublishTopic(reactRoom, "emoji"); + const _reactPresenceUserNew = reactPresenceNew.user!; + const _reactPresencePeersNew = reactPresenceNew.peers!; + _reactPresenceUserNew.name; + _reactPresencePeersNew[0].name; + // queries const { isLoading, error, data } = reactDB.useQuery({ messages: {} }); if (isLoading || error) { @@ -105,7 +115,10 @@ function ReactNormalApp() { // to silence ts warnings _reactPublishEmoji; _reactPresenceUser; - _reactPresencePeers; + _reactPresencePeersNew; + _reactPublishEmojiNew; + _reactPresenceUserNew; + _reactPresencePeersNew; messages; } @@ -123,6 +136,16 @@ function ReactNativeNormalApp() { const _reactPublishEmoji = reactRoom.usePublishTopic("emoji"); const _reactPresenceUser = reactPresence.user!; const _reactPresencePeers = reactPresence.peers!; + _reactPresenceUser.name; + _reactPresencePeers[0].name; + + const reactPresenceNew = reactNativeDB.rooms.usePresence(reactRoom, { keys: ["name"] }); + const _reactPublishEmojiNew = reactNativeDB.rooms.usePublishTopic(reactRoom, "emoji"); + const _reactPresenceUserNew = reactPresenceNew.user!; + const _reactPresencePeersNew = reactPresenceNew.peers!; + _reactPresenceUserNew.name; + _reactPresencePeersNew[0].name; + // queries const { isLoading, error, data } = reactNativeDB.useQuery({ messages: {}, @@ -136,6 +159,9 @@ function ReactNativeNormalApp() { _reactPublishEmoji; _reactPresenceUser; _reactPresencePeers; + _reactPublishEmojiNew; + _reactPresenceUserNew; + _reactPresencePeersNew; messages; } diff --git a/client/www/pages/docs/presence-and-topics.md b/client/www/pages/docs/presence-and-topics.md index 044e3a738..43bba3da1 100644 --- a/client/www/pages/docs/presence-and-topics.md +++ b/client/www/pages/docs/presence-and-topics.md @@ -71,7 +71,7 @@ const APP_ID = '__APP_ID__'; const db = init({ appId: APP_ID, schema }); const roomId = 'hacker-chat-room-id'; -// The `room` chat is typed automatically from schema! +// The `chat` room is typed automatically from schema! const room = db.room('chat', roomId); ``` @@ -128,14 +128,14 @@ import { init } from '@instantdb/react'; const APP_ID = "__APP_ID__"; const db = init({ appId: APP_ID }); -const room = db.room('chat', 'main'); +const room = db.room('chat', 'hacker-chat-room-id'); const randomId = Math.random().toString(36).slice(2, 6); const user = { name: `User#${randomId}`, }; function App() { - const { user: myPresence, peers, publishPresence } = room.usePresence(); + const { user: myPresence, peers, publishPresence } = db.rooms.usePresence(room); // Publish your presence to the room useEffect(() => { @@ -173,7 +173,7 @@ const room = db.room('chat', 'hacker-chat-room-id'); // We only return the `status` value for each peer // We will _only_ trigger an update when a user's `status` value changes -const { user, peers, publishPresence } = room.usePresence({ +const { user, peers, publishPresence } = db.rooms.usePresence(room, { keys: ['status'], }); ``` @@ -182,9 +182,9 @@ You may also specify an array of `peers` and a `user` flag to further constrain ```typescript // Will not trigger re-renders on presence changes -const room = db.room('chat', 'chatRoomId'); +const room = db.room('chat', 'hacker-chat-room-id'); -const { publishPresence } = room.usePresence({ +const { publishPresence } = db.rooms.usePresence(room, { peers: [], user: false, }); @@ -223,11 +223,11 @@ const room = db.room('main'); export default function InstantTopics() { // Use publishEmoji to broadcast to peers listening to `emoji` events. - const publishEmoji = room.usePublishTopic('emoji'); + const publishEmoji = db.rooms.usePublishTopic(room, 'emoji'); // Use useTopicEffect to listen for `emoji` events from peers // and animate their emojis on the screen. - room.useTopicEffect('emoji', ({ name, directionAngle, rotationAngle }) => { + db.rooms.useTopicEffect(room, 'emoji', ({ name, directionAngle, rotationAngle }) => { if (!emoji[name]) return; animateEmoji( @@ -401,12 +401,12 @@ You can render multiple cursor spaces. For instance, imagine you're building a s `useTypingIndicator` is a small utility useful for building inputs for chat-style apps. You can use this hook to show things like " is typing..." in your chat app. ```javascript {% showCopy=true %} -"use client"; +'use client'; -import { init } from "@instantdb/react"; +import { init } from '@instantdb/react'; // Instant app -const APP_ID = "__APP_ID__"; +const APP_ID = '__APP_ID__'; const db = init({ appId: APP_ID }); @@ -415,23 +415,23 @@ const user = { name: `User#${randomId}`, }; -const room = db.room("chat", "main"); +const room = db.room('chat', 'hacker-chat-room-id'); export default function InstantTypingIndicator() { // 1. Publish your presence in the room. - room.useSyncPresence(user); + db.rooms.useSyncPresence(room, user); // 2. Use the typing indicator hook - const typing = room.useTypingIndicator("chat"); + const typing = db.rooms.useTypingIndicator(room, 'chat'); const onKeyDown = (e) => { // 3. Render typing indicator typing.inputProps.onKeyDown(e); // 4. Optionally run your own onKeyDown logic - if (e.key === "Enter" && !e.shiftKey) { + if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); - console.log("Message sent:", e.target.value); + console.log('Message sent:', e.target.value); } }; diff --git a/client/www/pages/examples/4-custom-cursors.tsx b/client/www/pages/examples/4-custom-cursors.tsx index 66922843f..9914fe4b6 100644 --- a/client/www/pages/examples/4-custom-cursors.tsx +++ b/client/www/pages/examples/4-custom-cursors.tsx @@ -22,7 +22,7 @@ function CustomCursor({ color, name }: { color?: string; name: string }) { } export default function InstantCursors() { - room.useSyncPresence({ + db.rooms.useSyncPresence(room, { name: userId, }); diff --git a/client/www/pages/examples/5-reactions.tsx b/client/www/pages/examples/5-reactions.tsx index 0d221616b..5800af42f 100644 --- a/client/www/pages/examples/5-reactions.tsx +++ b/client/www/pages/examples/5-reactions.tsx @@ -7,20 +7,24 @@ const db = init({ appId: __getAppId(), }); -const { usePublishTopic, useTopicEffect } = db.room('topics-example', '123'); +const room = db.room('topics-example', '123'); export default function InstantTopics() { - const publishEmoji = usePublishTopic('emoji'); - - useTopicEffect('emoji', ({ name, directionAngle, rotationAngle }) => { - const emojiName = name as EmojiName; - if (!emoji[emojiName]) return; - - animateEmoji( - { emoji: emoji[emojiName], directionAngle, rotationAngle }, - elRefsRef.current[name].current - ); - }); + const publishEmoji = db.rooms.usePublishTopic(room, 'emoji'); + + db.rooms.useTopicEffect( + room, + 'emoji', + ({ name, directionAngle, rotationAngle }) => { + const emojiName = name as EmojiName; + if (!emoji[emojiName]) return; + + animateEmoji( + { emoji: emoji[emojiName], directionAngle, rotationAngle }, + elRefsRef.current[name].current, + ); + }, + ); const elRefsRef = useRef<{ [k: string]: RefObject; @@ -45,7 +49,7 @@ export default function InstantTopics() { rotationAngle: params.rotationAngle, directionAngle: params.directionAngle, }, - elRefsRef.current[name].current + elRefsRef.current[name].current, ); publishEmoji(params); @@ -72,7 +76,7 @@ const emoji = { const emojiNames = Object.keys(emoji) as EmojiName[]; const refsInit = Object.fromEntries( - emojiNames.map((name) => [name, createRef()]) + emojiNames.map((name) => [name, createRef()]), ); const containerClassNames = @@ -83,7 +87,7 @@ const emojiButtonClassNames = function animateEmoji( config: { emoji: string; directionAngle: number; rotationAngle: number }, - target: HTMLDivElement | null + target: HTMLDivElement | null, ) { if (!target) return; diff --git a/client/www/pages/examples/6-typing-indicator.tsx b/client/www/pages/examples/6-typing-indicator.tsx index e051f3a15..e5e3edf63 100644 --- a/client/www/pages/examples/6-typing-indicator.tsx +++ b/client/www/pages/examples/6-typing-indicator.tsx @@ -25,11 +25,14 @@ const user = { const room = db.room('typing-indicator-example', '1234'); export default function InstantTypingIndicator() { - room.useSyncPresence(user); + db.rooms.useSyncPresence(room, user); - const presence = room.usePresence(); + const presence = db.rooms.usePresence(room); - const { active, inputProps } = room.useTypingIndicator('chat'); + const { active, inputProps } = db.rooms.useTypingIndicator( + room, + 'chat-input', + ); const peers = Object.values(presence.peers).filter((p) => p.id); const activeMap = Object.fromEntries( diff --git a/client/www/pages/examples/7-avatar-stack.tsx b/client/www/pages/examples/7-avatar-stack.tsx index 8ad11adf9..675405f8c 100644 --- a/client/www/pages/examples/7-avatar-stack.tsx +++ b/client/www/pages/examples/7-avatar-stack.tsx @@ -24,7 +24,7 @@ export default function InstantAvatarStack() { user: true, }); - room.useSyncPresence({ + db.rooms.useSyncPresence(room, { name: userId, color: randomDarkColor, }); diff --git a/client/www/pages/examples/8-merge-tile-game.tsx b/client/www/pages/examples/8-merge-tile-game.tsx index 658a4710c..f4b2fd202 100644 --- a/client/www/pages/examples/8-merge-tile-game.tsx +++ b/client/www/pages/examples/8-merge-tile-game.tsx @@ -14,19 +14,18 @@ const db = init({ appId: __getAppId(), }); -const { useQuery, transact } = db; const room = db.room('main'); export default function App() { const [hoveredSquare, setHoveredSquare] = useState(null as string | null); const [myColor, setMyColor] = useState(null as string | null); - const { isLoading, error, data } = useQuery({ boards: {} }); + const { isLoading, error, data } = db.useQuery({ boards: {} }); const { user: myPresence, peers, publishPresence, isLoading: isPresenceLoading, - } = room.usePresence(); + } = db.rooms.usePresence(room); const boardState = data?.boards.find((b) => b.id === boardId)?.state; @@ -36,7 +35,7 @@ export default function App() { // If the board doesn't exist, create it if (!boardState) { - transact([ + db.transact([ db.tx.boards[boardId].update({ state: makeEmptyBoard(), }), @@ -99,7 +98,7 @@ export default function App() { onMouseEnter={() => setHoveredSquare(`${r}-${c}`)} onMouseLeave={() => setHoveredSquare(null)} onClick={() => { - transact([ + db.transact([ db.tx.boards[boardId].merge({ state: { [`${r}-${c}`]: myColor, @@ -115,7 +114,7 @@ export default function App() {