@instantdb/react-common 0.22.96-experimental.add-posthog-frontend.20386914944.1 → 0.22.96-experimental.add-posthog-frontend.20387039167.1

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.
@@ -142,6 +142,7 @@ export default abstract class InstantReactAbstractDatabase<Schema extends Instan
142
142
  *
143
143
  */
144
144
  useAuth: () => AuthState;
145
+ protected _useAuth(): AuthState;
145
146
  /**
146
147
  * Subscribe to the currently logged in user.
147
148
  * If the user is not logged in, this hook with throw an Error.
@@ -1 +1 @@
1
- {"version":3,"file":"InstantReactAbstractDatabase.d.ts","sourceRoot":"","sources":["../../src/InstantReactAbstractDatabase.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"InstantReactAbstractDatabase.d.ts","sourceRoot":"","sources":["../../src/InstantReactAbstractDatabase.tsx"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ 'use client';
1
2
  "use strict";
2
3
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
4
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
@@ -149,23 +150,7 @@ class InstantReactAbstractDatabase {
149
150
  *
150
151
  */
151
152
  this.useAuth = () => {
152
- // We use a ref to store the result of the query.
153
- // This is becuase `useSyncExternalStore` uses `Object.is`
154
- // to compare the previous and next state.
155
- // If we don't use a ref, the state will always be considered different, so
156
- // the component will always re-render.
157
- const resultCacheRef = (0, react_1.useRef)(this.core._reactor._currentUserCached);
158
- // Similar to `resultCacheRef`, `useSyncExternalStore` will unsubscribe
159
- // if `subscribe` changes, so we use `useCallback` to memoize the function.
160
- const subscribe = (0, react_1.useCallback)((cb) => {
161
- const unsubscribe = this.core.subscribeAuth((auth) => {
162
- resultCacheRef.current = Object.assign({ isLoading: false }, auth);
163
- cb();
164
- });
165
- return unsubscribe;
166
- }, []);
167
- const state = (0, react_1.useSyncExternalStore)(subscribe, () => resultCacheRef.current, () => defaultAuthState);
168
- return state;
153
+ return this._useAuth();
169
154
  };
170
155
  /**
171
156
  * Subscribe to the currently logged in user.
@@ -305,6 +290,25 @@ class InstantReactAbstractDatabase {
305
290
  room(type = '_defaultRoomType', id = '_defaultRoomId') {
306
291
  return new InstantReactRoom_ts_1.InstantReactRoom(this.core, type, id);
307
292
  }
293
+ _useAuth() {
294
+ // We use a ref to store the result of the query.
295
+ // This is becuase `useSyncExternalStore` uses `Object.is`
296
+ // to compare the previous and next state.
297
+ // If we don't use a ref, the state will always be considered different, so
298
+ // the component will always re-render.
299
+ const resultCacheRef = (0, react_1.useRef)(this.core._reactor._currentUserCached);
300
+ // Similar to `resultCacheRef`, `useSyncExternalStore` will unsubscribe
301
+ // if `subscribe` changes, so we use `useCallback` to memoize the function.
302
+ const subscribe = (0, react_1.useCallback)((cb) => {
303
+ const unsubscribe = this.core.subscribeAuth((auth) => {
304
+ resultCacheRef.current = Object.assign({ isLoading: false }, auth);
305
+ cb();
306
+ });
307
+ return unsubscribe;
308
+ }, []);
309
+ const state = (0, react_1.useSyncExternalStore)(subscribe, () => resultCacheRef.current, () => defaultAuthState);
310
+ return state;
311
+ }
308
312
  /**
309
313
  * One time query for the logged in state. This is useful
310
314
  * for scenarios where you want to know the current auth
@@ -1 +1 @@
1
- {"version":3,"file":"InstantReactAbstractDatabase.js","sourceRoot":"","sources":["../../src/InstantReactAbstractDatabase.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n // types\n Auth,\n Storage,\n txInit,\n type AuthState,\n type User,\n type ConnectionStatus,\n type TransactionChunk,\n type RoomSchemaShape,\n type InstaQLParams,\n type InstaQLOptions,\n type InstantConfig,\n type PageInfoResponse,\n InstantCoreDatabase,\n init as core_init,\n InstaQLLifecycleState,\n InstaQLResponse,\n RoomsOf,\n InstantSchemaDef,\n IInstantDatabase,\n InstantError,\n ValidQuery,\n} from '@instantdb/core';\nimport {\n ReactNode,\n useCallback,\n useEffect,\n useRef,\n useState,\n useSyncExternalStore,\n} from 'react';\nimport { useQueryInternal } from './useQuery.ts';\nimport { InstantReactRoom, rooms } from './InstantReactRoom.ts';\n\nconst defaultAuthState = {\n isLoading: true,\n user: undefined,\n error: undefined,\n};\n\nexport default abstract class InstantReactAbstractDatabase<\n // need to pull this schema out to another generic for query params, not sure why\n Schema extends InstantSchemaDef<any, any, any>,\n UseDates extends boolean = false,\n Config extends InstantConfig<Schema, boolean> = InstantConfig<\n Schema,\n UseDates\n >,\n Rooms extends RoomSchemaShape = RoomsOf<Schema>,\n> implements IInstantDatabase<Schema>\n{\n public tx = txInit<Schema>();\n\n public auth: Auth;\n public storage: Storage;\n public core: InstantCoreDatabase<Schema, UseDates>;\n\n /** @deprecated use `core` instead */\n public _core: InstantCoreDatabase<Schema, UseDates>;\n\n static Storage?: any;\n static NetworkListener?: any;\n static EventSourceImpl?: any;\n\n constructor(\n config: Omit<InstantConfig<Schema, UseDates>, 'useDateObjects'> & {\n useDateObjects?: UseDates;\n },\n versions?: { [key: string]: string },\n ) {\n this.core = core_init<Schema, UseDates>(\n config,\n // @ts-expect-error because TS can't resolve subclass statics\n this.constructor.Storage,\n // @ts-expect-error because TS can't resolve subclass statics\n this.constructor.NetworkListener,\n versions,\n // @ts-expect-error because TS can't resolve subclass statics\n this.constructor.EventSourceImpl,\n );\n this._core = this.core;\n this.auth = this.core.auth;\n this.storage = this.core.storage;\n }\n\n /**\n * Returns a unique ID for a given `name`. It's stored in local storage,\n * so you will get the same ID across sessions.\n *\n * This is useful for generating IDs that could identify a local device or user.\n *\n * @example\n * const deviceId = await db.getLocalId('device');\n */\n getLocalId = (name: string): Promise<string> => {\n return this.core.getLocalId(name);\n };\n\n /**\n * A hook that returns a unique ID for a given `name`. localIds are\n * stored in local storage, so you will get the same ID across sessions.\n *\n * Initially returns `null`, and then loads the localId.\n *\n * @example\n * const deviceId = db.useLocalId('device');\n * if (!deviceId) return null; // loading\n * console.log('Device ID:', deviceId)\n */\n useLocalId = (name: string): string | null => {\n const [localId, setLocalId] = useState<string | null>(null);\n\n useEffect(() => {\n let mounted = true;\n const f = async () => {\n const id = await this.getLocalId(name);\n if (!mounted) return;\n setLocalId(id);\n };\n f();\n return;\n }, [name]);\n\n return localId;\n };\n\n /**\n * Obtain a handle to a room, which allows you to listen to topics and presence data\n *\n * If you don't provide a `type` or `id`, Instant will default to `_defaultRoomType` and `_defaultRoomId`\n * as the room type and id, respectively.\n *\n * @see https://instantdb.com/docs/presence-and-topics\n *\n * @example\n * const room = db.room('chat', roomId);\n * const { peers } = db.rooms.usePresence(room);\n */\n room<RoomType extends keyof Rooms>(\n type: RoomType = '_defaultRoomType' as RoomType,\n id: string = '_defaultRoomId',\n ) {\n return new InstantReactRoom<Schema, Rooms, RoomType>(this.core, type, id);\n }\n\n /**\n * Hooks for working with rooms\n *\n * @see https://instantdb.com/docs/presence-and-topics\n *\n * @example\n * const room = db.room('chat', roomId);\n * const { peers } = db.rooms.usePresence(room);\n * const publish = db.rooms.usePublishTopic(room, 'emoji');\n * // ...\n */\n rooms = rooms;\n\n /**\n * Use this to write data! You can create, update, delete, and link objects\n *\n * @see https://instantdb.com/docs/instaml\n *\n * @example\n * // Create a new object in the `goals` namespace\n * const goalId = id();\n * db.transact(db.tx.goals[goalId].update({title: \"Get fit\"}))\n *\n * // Update the title\n * db.transact(db.tx.goals[goalId].update({title: \"Get super fit\"}))\n *\n * // Delete it\n * db.transact(db.tx.goals[goalId].delete())\n *\n * // Or create an association:\n * todoId = id();\n * db.transact([\n * db.tx.todos[todoId].update({ title: 'Go on a run' }),\n * db.tx.goals[goalId].link({todos: todoId}),\n * ])\n */\n transact = (\n chunks: TransactionChunk<any, any> | TransactionChunk<any, any>[],\n ) => {\n return this.core.transact(chunks);\n };\n\n /**\n * Use this to query your data!\n *\n * @see https://instantdb.com/docs/instaql\n *\n * @example\n * // listen to all goals\n * const { isLoading, error, data } = db.useQuery({ goals: {} });\n *\n * // goals where the title is \"Get Fit\"\n * const { isLoading, error, data } = db.useQuery({\n * goals: { $: { where: { title: 'Get Fit' } } },\n * });\n *\n * // all goals, _alongside_ their todos\n * const { isLoading, error, data } = db.useQuery({\n * goals: { todos: {} },\n * });\n *\n * // skip if `user` is not logged in\n * const { isLoading, error, data } = db.useQuery(\n * auth.user ? { goals: {} } : null,\n * );\n */\n useQuery = <Q extends ValidQuery<Q, Schema>>(\n query: null | Q,\n opts?: InstaQLOptions,\n ): InstaQLLifecycleState<Schema, Q, UseDates> => {\n return useQueryInternal<Q, Schema, UseDates>(this.core, query, opts).state;\n };\n\n /**\n * Listen for the logged in state. This is useful\n * for deciding when to show a login screen.\n *\n * Check out the docs for an example `Login` component too!\n *\n * @see https://instantdb.com/docs/auth\n * @example\n * function App() {\n * const { isLoading, user, error } = db.useAuth()\n * if (isLoading) {\n * return <div>Loading...</div>\n * }\n * if (error) {\n * return <div>Uh oh! {error.message}</div>\n * }\n * if (user) {\n * return <Main user={user} />\n * }\n * return <Login />\n * }\n *\n */\n useAuth = (): AuthState => {\n // We use a ref to store the result of the query.\n // This is becuase `useSyncExternalStore` uses `Object.is`\n // to compare the previous and next state.\n // If we don't use a ref, the state will always be considered different, so\n // the component will always re-render.\n const resultCacheRef = useRef<AuthState>(\n this.core._reactor._currentUserCached,\n );\n\n // Similar to `resultCacheRef`, `useSyncExternalStore` will unsubscribe\n // if `subscribe` changes, so we use `useCallback` to memoize the function.\n const subscribe = useCallback((cb: Function) => {\n const unsubscribe = this.core.subscribeAuth((auth) => {\n resultCacheRef.current = { isLoading: false, ...auth };\n cb();\n });\n\n return unsubscribe;\n }, []);\n\n const state = useSyncExternalStore<AuthState>(\n subscribe,\n () => resultCacheRef.current,\n () => defaultAuthState,\n );\n return state;\n };\n\n /**\n * Subscribe to the currently logged in user.\n * If the user is not logged in, this hook with throw an Error.\n * You will want to protect any calls of this hook with a\n * <db.SignedIn> component, or your own logic based on db.useAuth()\n *\n * @see https://instantdb.com/docs/auth\n * @throws Error indicating user not signed in\n * @example\n * function UserDisplay() {\n * const user = db.useUser()\n * return <div>Logged in as: {user.email}</div>\n * }\n *\n * <db.SignedIn>\n * <UserDisplay />\n * </db.SignedIn>\n *\n */\n useUser = (): User => {\n const { user } = this.useAuth();\n if (!user) {\n throw new InstantError(\n 'useUser must be used within an auth-protected route',\n );\n }\n return user;\n };\n\n /**\n * One time query for the logged in state. This is useful\n * for scenarios where you want to know the current auth\n * state without subscribing to changes.\n *\n * @see https://instantdb.com/docs/auth\n * @example\n * const user = await db.getAuth();\n * console.log('logged in as', user.email)\n */\n getAuth(): Promise<User | null> {\n return this.core.getAuth();\n }\n\n /**\n * Listen for connection status changes to Instant. Use this for things like\n * showing connection state to users\n *\n * @see https://www.instantdb.com/docs/patterns#connection-status\n * @example\n * function App() {\n * const status = db.useConnectionStatus()\n * const connectionState =\n * status === 'connecting' || status === 'opened'\n * ? 'authenticating'\n * : status === 'authenticated'\n * ? 'connected'\n * : status === 'closed'\n * ? 'closed'\n * : status === 'errored'\n * ? 'errored'\n * : 'unexpected state';\n *\n * return <div>Connection state: {connectionState}</div>\n * }\n */\n useConnectionStatus = (): ConnectionStatus => {\n const statusRef = useRef<ConnectionStatus>(\n this.core._reactor.status as ConnectionStatus,\n );\n\n const subscribe = useCallback((cb: Function) => {\n const unsubscribe = this.core.subscribeConnectionStatus((newStatus) => {\n if (newStatus !== statusRef.current) {\n statusRef.current = newStatus;\n cb();\n }\n });\n\n return unsubscribe;\n }, []);\n\n const status = useSyncExternalStore<ConnectionStatus>(\n subscribe,\n () => statusRef.current,\n // For SSR, always return 'connecting' as the initial state\n () => 'connecting',\n );\n\n return status;\n };\n\n /**\n * Use this for one-off queries.\n * Returns local data if available, otherwise fetches from the server.\n * Because we want to avoid stale data, this method will throw an error\n * if the user is offline or there is no active connection to the server.\n *\n * @see https://instantdb.com/docs/instaql\n *\n * @example\n *\n * const resp = await db.queryOnce({ goals: {} });\n * console.log(resp.data.goals)\n */\n queryOnce = <Q extends ValidQuery<Q, Schema>>(\n query: Q,\n opts?: InstaQLOptions,\n ): Promise<{\n data: InstaQLResponse<Schema, Q, UseDates>;\n pageInfo: PageInfoResponse<Q>;\n }> => {\n return this.core.queryOnce(query, opts);\n };\n\n /**\n * Only render children if the user is signed in.\n * @see https://instantdb.com/docs/auth\n *\n * @example\n * <db.SignedIn>\n * <MyComponent />\n * </db.SignedIn>\n *\n */\n SignedIn: React.FC<{\n children: ReactNode;\n }> = ({ children }) => {\n const auth = this.useAuth();\n if (auth.isLoading || auth.error || !auth.user) return null;\n\n return <>{children}</>;\n };\n\n /**\n * Only render children if the user is signed out.\n * @see https://instantdb.com/docs/auth\n *\n * @example\n * <db.SignedOut>\n * <MyComponent />\n * </db.SignedOut>\n *\n */\n SignedOut: React.FC<{\n children: ReactNode;\n }> = ({ children }) => {\n const auth = this.useAuth();\n if (auth.isLoading || auth.error || auth.user) return null;\n return <>{children}</>;\n };\n}\n"]}
1
+ {"version":3,"file":"InstantReactAbstractDatabase.js","sourceRoot":"","sources":["../../src/InstantReactAbstractDatabase.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\nimport {\n // types\n Auth,\n Storage,\n txInit,\n type AuthState,\n type User,\n type ConnectionStatus,\n type TransactionChunk,\n type RoomSchemaShape,\n type InstaQLOptions,\n type InstantConfig,\n type PageInfoResponse,\n InstantCoreDatabase,\n init as core_init,\n InstaQLLifecycleState,\n InstaQLResponse,\n RoomsOf,\n InstantSchemaDef,\n IInstantDatabase,\n InstantError,\n ValidQuery,\n} from '@instantdb/core';\nimport {\n ReactNode,\n useCallback,\n useEffect,\n useRef,\n useState,\n useSyncExternalStore,\n} from 'react';\nimport { useQueryInternal } from './useQuery.ts';\nimport { InstantReactRoom, rooms } from './InstantReactRoom.ts';\n\nconst defaultAuthState = {\n isLoading: true,\n user: undefined,\n error: undefined,\n};\n\nexport default abstract class InstantReactAbstractDatabase<\n // need to pull this schema out to another generic for query params, not sure why\n Schema extends InstantSchemaDef<any, any, any>,\n UseDates extends boolean = false,\n Config extends InstantConfig<Schema, boolean> = InstantConfig<\n Schema,\n UseDates\n >,\n Rooms extends RoomSchemaShape = RoomsOf<Schema>,\n> implements IInstantDatabase<Schema>\n{\n public tx = txInit<Schema>();\n\n public auth: Auth;\n public storage: Storage;\n public core: InstantCoreDatabase<Schema, UseDates>;\n\n /** @deprecated use `core` instead */\n public _core: InstantCoreDatabase<Schema, UseDates>;\n\n static Storage?: any;\n static NetworkListener?: any;\n static EventSourceImpl?: any;\n\n constructor(\n config: Omit<InstantConfig<Schema, UseDates>, 'useDateObjects'> & {\n useDateObjects?: UseDates;\n },\n versions?: { [key: string]: string },\n ) {\n this.core = core_init<Schema, UseDates>(\n config,\n // @ts-expect-error because TS can't resolve subclass statics\n this.constructor.Storage,\n // @ts-expect-error because TS can't resolve subclass statics\n this.constructor.NetworkListener,\n versions,\n // @ts-expect-error because TS can't resolve subclass statics\n this.constructor.EventSourceImpl,\n );\n this._core = this.core;\n this.auth = this.core.auth;\n this.storage = this.core.storage;\n }\n\n /**\n * Returns a unique ID for a given `name`. It's stored in local storage,\n * so you will get the same ID across sessions.\n *\n * This is useful for generating IDs that could identify a local device or user.\n *\n * @example\n * const deviceId = await db.getLocalId('device');\n */\n getLocalId = (name: string): Promise<string> => {\n return this.core.getLocalId(name);\n };\n\n /**\n * A hook that returns a unique ID for a given `name`. localIds are\n * stored in local storage, so you will get the same ID across sessions.\n *\n * Initially returns `null`, and then loads the localId.\n *\n * @example\n * const deviceId = db.useLocalId('device');\n * if (!deviceId) return null; // loading\n * console.log('Device ID:', deviceId)\n */\n useLocalId = (name: string): string | null => {\n const [localId, setLocalId] = useState<string | null>(null);\n\n useEffect(() => {\n let mounted = true;\n const f = async () => {\n const id = await this.getLocalId(name);\n if (!mounted) return;\n setLocalId(id);\n };\n f();\n return;\n }, [name]);\n\n return localId;\n };\n\n /**\n * Obtain a handle to a room, which allows you to listen to topics and presence data\n *\n * If you don't provide a `type` or `id`, Instant will default to `_defaultRoomType` and `_defaultRoomId`\n * as the room type and id, respectively.\n *\n * @see https://instantdb.com/docs/presence-and-topics\n *\n * @example\n * const room = db.room('chat', roomId);\n * const { peers } = db.rooms.usePresence(room);\n */\n room<RoomType extends keyof Rooms>(\n type: RoomType = '_defaultRoomType' as RoomType,\n id: string = '_defaultRoomId',\n ) {\n return new InstantReactRoom<Schema, Rooms, RoomType>(this.core, type, id);\n }\n\n /**\n * Hooks for working with rooms\n *\n * @see https://instantdb.com/docs/presence-and-topics\n *\n * @example\n * const room = db.room('chat', roomId);\n * const { peers } = db.rooms.usePresence(room);\n * const publish = db.rooms.usePublishTopic(room, 'emoji');\n * // ...\n */\n rooms = rooms;\n\n /**\n * Use this to write data! You can create, update, delete, and link objects\n *\n * @see https://instantdb.com/docs/instaml\n *\n * @example\n * // Create a new object in the `goals` namespace\n * const goalId = id();\n * db.transact(db.tx.goals[goalId].update({title: \"Get fit\"}))\n *\n * // Update the title\n * db.transact(db.tx.goals[goalId].update({title: \"Get super fit\"}))\n *\n * // Delete it\n * db.transact(db.tx.goals[goalId].delete())\n *\n * // Or create an association:\n * todoId = id();\n * db.transact([\n * db.tx.todos[todoId].update({ title: 'Go on a run' }),\n * db.tx.goals[goalId].link({todos: todoId}),\n * ])\n */\n transact = (\n chunks: TransactionChunk<any, any> | TransactionChunk<any, any>[],\n ) => {\n return this.core.transact(chunks);\n };\n\n /**\n * Use this to query your data!\n *\n * @see https://instantdb.com/docs/instaql\n *\n * @example\n * // listen to all goals\n * const { isLoading, error, data } = db.useQuery({ goals: {} });\n *\n * // goals where the title is \"Get Fit\"\n * const { isLoading, error, data } = db.useQuery({\n * goals: { $: { where: { title: 'Get Fit' } } },\n * });\n *\n * // all goals, _alongside_ their todos\n * const { isLoading, error, data } = db.useQuery({\n * goals: { todos: {} },\n * });\n *\n * // skip if `user` is not logged in\n * const { isLoading, error, data } = db.useQuery(\n * auth.user ? { goals: {} } : null,\n * );\n */\n useQuery = <Q extends ValidQuery<Q, Schema>>(\n query: null | Q,\n opts?: InstaQLOptions,\n ): InstaQLLifecycleState<Schema, Q, UseDates> => {\n return useQueryInternal<Q, Schema, UseDates>(this.core, query, opts).state;\n };\n\n /**\n * Listen for the logged in state. This is useful\n * for deciding when to show a login screen.\n *\n * Check out the docs for an example `Login` component too!\n *\n * @see https://instantdb.com/docs/auth\n * @example\n * function App() {\n * const { isLoading, user, error } = db.useAuth()\n * if (isLoading) {\n * return <div>Loading...</div>\n * }\n * if (error) {\n * return <div>Uh oh! {error.message}</div>\n * }\n * if (user) {\n * return <Main user={user} />\n * }\n * return <Login />\n * }\n *\n */\n useAuth = (): AuthState => {\n return this._useAuth();\n };\n\n protected _useAuth(): AuthState {\n // We use a ref to store the result of the query.\n // This is becuase `useSyncExternalStore` uses `Object.is`\n // to compare the previous and next state.\n // If we don't use a ref, the state will always be considered different, so\n // the component will always re-render.\n const resultCacheRef = useRef<AuthState>(\n this.core._reactor._currentUserCached,\n );\n\n // Similar to `resultCacheRef`, `useSyncExternalStore` will unsubscribe\n // if `subscribe` changes, so we use `useCallback` to memoize the function.\n const subscribe = useCallback((cb: Function) => {\n const unsubscribe = this.core.subscribeAuth((auth) => {\n resultCacheRef.current = { isLoading: false, ...auth };\n cb();\n });\n\n return unsubscribe;\n }, []);\n\n const state = useSyncExternalStore<AuthState>(\n subscribe,\n () => resultCacheRef.current,\n () => defaultAuthState,\n );\n return state;\n }\n\n /**\n * Subscribe to the currently logged in user.\n * If the user is not logged in, this hook with throw an Error.\n * You will want to protect any calls of this hook with a\n * <db.SignedIn> component, or your own logic based on db.useAuth()\n *\n * @see https://instantdb.com/docs/auth\n * @throws Error indicating user not signed in\n * @example\n * function UserDisplay() {\n * const user = db.useUser()\n * return <div>Logged in as: {user.email}</div>\n * }\n *\n * <db.SignedIn>\n * <UserDisplay />\n * </db.SignedIn>\n *\n */\n useUser = (): User => {\n const { user } = this.useAuth();\n if (!user) {\n throw new InstantError(\n 'useUser must be used within an auth-protected route',\n );\n }\n return user;\n };\n\n /**\n * One time query for the logged in state. This is useful\n * for scenarios where you want to know the current auth\n * state without subscribing to changes.\n *\n * @see https://instantdb.com/docs/auth\n * @example\n * const user = await db.getAuth();\n * console.log('logged in as', user.email)\n */\n getAuth(): Promise<User | null> {\n return this.core.getAuth();\n }\n\n /**\n * Listen for connection status changes to Instant. Use this for things like\n * showing connection state to users\n *\n * @see https://www.instantdb.com/docs/patterns#connection-status\n * @example\n * function App() {\n * const status = db.useConnectionStatus()\n * const connectionState =\n * status === 'connecting' || status === 'opened'\n * ? 'authenticating'\n * : status === 'authenticated'\n * ? 'connected'\n * : status === 'closed'\n * ? 'closed'\n * : status === 'errored'\n * ? 'errored'\n * : 'unexpected state';\n *\n * return <div>Connection state: {connectionState}</div>\n * }\n */\n useConnectionStatus = (): ConnectionStatus => {\n const statusRef = useRef<ConnectionStatus>(\n this.core._reactor.status as ConnectionStatus,\n );\n\n const subscribe = useCallback((cb: Function) => {\n const unsubscribe = this.core.subscribeConnectionStatus((newStatus) => {\n if (newStatus !== statusRef.current) {\n statusRef.current = newStatus;\n cb();\n }\n });\n\n return unsubscribe;\n }, []);\n\n const status = useSyncExternalStore<ConnectionStatus>(\n subscribe,\n () => statusRef.current,\n // For SSR, always return 'connecting' as the initial state\n () => 'connecting',\n );\n\n return status;\n };\n\n /**\n * Use this for one-off queries.\n * Returns local data if available, otherwise fetches from the server.\n * Because we want to avoid stale data, this method will throw an error\n * if the user is offline or there is no active connection to the server.\n *\n * @see https://instantdb.com/docs/instaql\n *\n * @example\n *\n * const resp = await db.queryOnce({ goals: {} });\n * console.log(resp.data.goals)\n */\n queryOnce = <Q extends ValidQuery<Q, Schema>>(\n query: Q,\n opts?: InstaQLOptions,\n ): Promise<{\n data: InstaQLResponse<Schema, Q, UseDates>;\n pageInfo: PageInfoResponse<Q>;\n }> => {\n return this.core.queryOnce(query, opts);\n };\n\n /**\n * Only render children if the user is signed in.\n * @see https://instantdb.com/docs/auth\n *\n * @example\n * <db.SignedIn>\n * <MyComponent />\n * </db.SignedIn>\n *\n */\n SignedIn: React.FC<{\n children: ReactNode;\n }> = ({ children }) => {\n const auth = this.useAuth();\n if (auth.isLoading || auth.error || !auth.user) return null;\n\n return <>{children}</>;\n };\n\n /**\n * Only render children if the user is signed out.\n * @see https://instantdb.com/docs/auth\n *\n * @example\n * <db.SignedOut>\n * <MyComponent />\n * </db.SignedOut>\n *\n */\n SignedOut: React.FC<{\n children: ReactNode;\n }> = ({ children }) => {\n const auth = this.useAuth();\n if (auth.isLoading || auth.error || auth.user) return null;\n return <>{children}</>;\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"useQuery.d.ts","sourceRoot":"","sources":["../../src/useQuery.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,cAAc,EAEnB,mBAAmB,EACnB,qBAAqB,EACrB,gBAAgB,EAChB,UAAU,EACX,MAAM,iBAAiB,CAAC;AAoBzB,wBAAgB,gBAAgB,CAC9B,CAAC,SAAS,UAAU,CAAC,CAAC,EAAE,MAAM,CAAC,EAC/B,MAAM,SAAS,gBAAgB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAC9C,QAAQ,SAAS,OAAO,EAExB,KAAK,EAAE,mBAAmB,CAAC,MAAM,EAAE,QAAQ,CAAC,EAC5C,MAAM,EAAE,IAAI,GAAG,CAAC,EAChB,KAAK,CAAC,EAAE,cAAc,GACrB;IACD,KAAK,EAAE,qBAAqB,CAAC,MAAM,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;IAClD,KAAK,EAAE,GAAG,CAAC;CACZ,CA4DA"}
1
+ {"version":3,"file":"useQuery.d.ts","sourceRoot":"","sources":["../../src/useQuery.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,cAAc,EACnB,mBAAmB,EACnB,qBAAqB,EACrB,gBAAgB,EAChB,UAAU,EACX,MAAM,iBAAiB,CAAC;AAoBzB,wBAAgB,gBAAgB,CAC9B,CAAC,SAAS,UAAU,CAAC,CAAC,EAAE,MAAM,CAAC,EAC/B,MAAM,SAAS,gBAAgB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAC9C,QAAQ,SAAS,OAAO,EAExB,KAAK,EAAE,mBAAmB,CAAC,MAAM,EAAE,QAAQ,CAAC,EAC5C,MAAM,EAAE,IAAI,GAAG,CAAC,EAChB,KAAK,CAAC,EAAE,cAAc,GACrB;IACD,KAAK,EAAE,qBAAqB,CAAC,MAAM,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;IAClD,KAAK,EAAE,GAAG,CAAC;CACZ,CAgEA"}
@@ -29,6 +29,10 @@ function useQueryInternal(_core, _query, _opts) {
29
29
  const subscribe = (0, react_1.useCallback)((cb) => {
30
30
  // Update the ref when the query changes to avoid showing stale data
31
31
  resultCacheRef.current = stateForResult(_core._reactor.getPreviousResult(query));
32
+ // before the subscribeQuery is connected and calls it's own callback,
33
+ // we might have data in the store via SSR, we need to notify useSyncExternalStore that
34
+ // the data has changed.
35
+ cb();
32
36
  // Don't subscribe if query is null
33
37
  if (!query) {
34
38
  const unsubscribe = () => { };
@@ -1 +1 @@
1
- {"version":3,"file":"useQuery.js","sourceRoot":"","sources":["../../src/useQuery.ts"],"names":[],"mappings":";;AA8BA,4CAuEC;AArGD,0CAUyB;AACzB,iCAAkE;AAElE,MAAM,YAAY,GAAG;IACnB,SAAS,EAAE,IAAI;IACf,IAAI,EAAE,SAAS;IACf,QAAQ,EAAE,SAAS;IACnB,KAAK,EAAE,SAAS;CACR,CAAC;AAEX,SAAS,cAAc,CAAC,MAAW;IACjC,uBACE,SAAS,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,EAC3B,IAAI,EAAE,SAAS,EACf,QAAQ,EAAE,SAAS,EACnB,KAAK,EAAE,SAAS,IACb,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EACzB;AACJ,CAAC;AAED,SAAgB,gBAAgB,CAK9B,KAA4C,EAC5C,MAAgB,EAChB,KAAsB;IAKtB,IAAI,MAAM,IAAI,KAAK,IAAI,YAAY,IAAI,KAAK,EAAE,CAAC;QAC7C,MAAM,mBAAK,YAAY,EAAE,KAAK,CAAC,YAAY,CAAC,IAAK,MAAM,CAAE,CAAC;IAC5D,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,IAAA,kBAAW,EAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAClD,MAAM,SAAS,GAAG,IAAA,eAAQ,EAAC,KAAK,CAAC,CAAC;IAElC,iDAAiD;IACjD,0DAA0D;IAC1D,0CAA0C;IAC1C,2EAA2E;IAC3E,uCAAuC;IACvC,MAAM,cAAc,GAAG,IAAA,cAAM,EAC3B,cAAc,CAAC,KAAK,CAAC,QAAQ,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,CACxD,CAAC;IAEF,uEAAuE;IACvE,2EAA2E;IAC3E,MAAM,SAAS,GAAG,IAAA,mBAAW,EAC3B,CAAC,EAAE,EAAE,EAAE;QACL,oEAAoE;QACpE,cAAc,CAAC,OAAO,GAAG,cAAc,CACrC,KAAK,CAAC,QAAQ,CAAC,iBAAiB,CAAC,KAAK,CAAC,CACxC,CAAC;QAEF,mCAAmC;QACnC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,WAAW,GAAG,GAAG,EAAE,GAAE,CAAC,CAAC;YAC7B,OAAO,WAAW,CAAC;QACrB,CAAC;QAED,MAAM,WAAW,GAAG,KAAK,CAAC,cAAc,CAAc,KAAK,EAAE,CAAC,MAAM,EAAE,EAAE;YACtE,cAAc,CAAC,OAAO,mBACpB,SAAS,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC;gBAC3B,8DAA8D;gBAC9D,IAAI,EAAE,SAAS;gBACf,8DAA8D;gBAC9D,QAAQ,EAAE,SAAS;gBACnB,8DAA8D;gBAC9D,KAAK,EAAE,SAAS,IACb,MAAM,CACV,CAAC;YAEF,EAAE,EAAE,CAAC;QACP,CAAC,CAAC,CAAC;QAEH,OAAO,WAAW,CAAC;IACrB,CAAC;IACD,sDAAsD;IACtD,CAAC,SAAS,CAAC,CACZ,CAAC;IAEF,MAAM,KAAK,GAAG,IAAA,4BAAoB,EAGhC,SAAS,EACT,GAAG,EAAE,CAAC,cAAc,CAAC,OAAO,EAC5B,GAAG,EAAE,CAAC,YAAY,CACnB,CAAC;IACF,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AAC1B,CAAC","sourcesContent":["import {\n weakHash,\n coerceQuery,\n type InstaQLParams,\n type InstaQLOptions,\n type InstantGraph,\n InstantCoreDatabase,\n InstaQLLifecycleState,\n InstantSchemaDef,\n ValidQuery,\n} from '@instantdb/core';\nimport { useCallback, useRef, useSyncExternalStore } from 'react';\n\nconst defaultState = {\n isLoading: true,\n data: undefined,\n pageInfo: undefined,\n error: undefined,\n} as const;\n\nfunction stateForResult(result: any) {\n return {\n isLoading: !Boolean(result),\n data: undefined,\n pageInfo: undefined,\n error: undefined,\n ...(result ? result : {}),\n };\n}\n\nexport function useQueryInternal<\n Q extends ValidQuery<Q, Schema>,\n Schema extends InstantSchemaDef<any, any, any>,\n UseDates extends boolean,\n>(\n _core: InstantCoreDatabase<Schema, UseDates>,\n _query: null | Q,\n _opts?: InstaQLOptions,\n): {\n state: InstaQLLifecycleState<Schema, Q, UseDates>;\n query: any;\n} {\n if (_query && _opts && 'ruleParams' in _opts) {\n _query = { $$ruleParams: _opts['ruleParams'], ..._query };\n }\n const query = _query ? coerceQuery(_query) : null;\n const queryHash = weakHash(query);\n\n // We use a ref to store the result of the query.\n // This is becuase `useSyncExternalStore` uses `Object.is`\n // to compare the previous and next state.\n // If we don't use a ref, the state will always be considered different, so\n // the component will always re-render.\n const resultCacheRef = useRef<InstaQLLifecycleState<Schema, Q, UseDates>>(\n stateForResult(_core._reactor.getPreviousResult(query)),\n );\n\n // Similar to `resultCacheRef`, `useSyncExternalStore` will unsubscribe\n // if `subscribe` changes, so we use `useCallback` to memoize the function.\n const subscribe = useCallback(\n (cb) => {\n // Update the ref when the query changes to avoid showing stale data\n resultCacheRef.current = stateForResult(\n _core._reactor.getPreviousResult(query),\n );\n\n // Don't subscribe if query is null\n if (!query) {\n const unsubscribe = () => {};\n return unsubscribe;\n }\n\n const unsubscribe = _core.subscribeQuery<Q, UseDates>(query, (result) => {\n resultCacheRef.current = {\n isLoading: !Boolean(result),\n // @ts-expect-error: ts thinks this will always be overwritten\n data: undefined,\n // @ts-expect-error: ts thinks this will always be overwritten\n pageInfo: undefined,\n // @ts-expect-error: ts thinks this will always be overwritten\n error: undefined,\n ...result,\n };\n\n cb();\n });\n\n return unsubscribe;\n },\n // Build a new subscribe function if the query changes\n [queryHash],\n );\n\n const state = useSyncExternalStore<\n InstaQLLifecycleState<Schema, Q, UseDates>\n >(\n subscribe,\n () => resultCacheRef.current,\n () => defaultState,\n );\n return { state, query };\n}\n"]}
1
+ {"version":3,"file":"useQuery.js","sourceRoot":"","sources":["../../src/useQuery.ts"],"names":[],"mappings":";;AA4BA,4CA2EC;AAvGD,0CAQyB;AACzB,iCAAkE;AAElE,MAAM,YAAY,GAAG;IACnB,SAAS,EAAE,IAAI;IACf,IAAI,EAAE,SAAS;IACf,QAAQ,EAAE,SAAS;IACnB,KAAK,EAAE,SAAS;CACR,CAAC;AAEX,SAAS,cAAc,CAAC,MAAW;IACjC,uBACE,SAAS,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,EAC3B,IAAI,EAAE,SAAS,EACf,QAAQ,EAAE,SAAS,EACnB,KAAK,EAAE,SAAS,IACb,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EACzB;AACJ,CAAC;AAED,SAAgB,gBAAgB,CAK9B,KAA4C,EAC5C,MAAgB,EAChB,KAAsB;IAKtB,IAAI,MAAM,IAAI,KAAK,IAAI,YAAY,IAAI,KAAK,EAAE,CAAC;QAC7C,MAAM,mBAAK,YAAY,EAAE,KAAK,CAAC,YAAY,CAAC,IAAK,MAAM,CAAE,CAAC;IAC5D,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,IAAA,kBAAW,EAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAClD,MAAM,SAAS,GAAG,IAAA,eAAQ,EAAC,KAAK,CAAC,CAAC;IAElC,iDAAiD;IACjD,0DAA0D;IAC1D,0CAA0C;IAC1C,2EAA2E;IAC3E,uCAAuC;IACvC,MAAM,cAAc,GAAG,IAAA,cAAM,EAC3B,cAAc,CAAC,KAAK,CAAC,QAAQ,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,CACxD,CAAC;IAEF,uEAAuE;IACvE,2EAA2E;IAC3E,MAAM,SAAS,GAAG,IAAA,mBAAW,EAC3B,CAAC,EAAE,EAAE,EAAE;QACL,oEAAoE;QACpE,cAAc,CAAC,OAAO,GAAG,cAAc,CACrC,KAAK,CAAC,QAAQ,CAAC,iBAAiB,CAAC,KAAK,CAAC,CACxC,CAAC;QACF,sEAAsE;QACtE,uFAAuF;QACvF,wBAAwB;QACxB,EAAE,EAAE,CAAC;QAEL,mCAAmC;QACnC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,WAAW,GAAG,GAAG,EAAE,GAAE,CAAC,CAAC;YAC7B,OAAO,WAAW,CAAC;QACrB,CAAC;QAED,MAAM,WAAW,GAAG,KAAK,CAAC,cAAc,CAAc,KAAK,EAAE,CAAC,MAAM,EAAE,EAAE;YACtE,cAAc,CAAC,OAAO,mBACpB,SAAS,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC;gBAC3B,8DAA8D;gBAC9D,IAAI,EAAE,SAAS;gBACf,8DAA8D;gBAC9D,QAAQ,EAAE,SAAS;gBACnB,8DAA8D;gBAC9D,KAAK,EAAE,SAAS,IACb,MAAM,CACV,CAAC;YAEF,EAAE,EAAE,CAAC;QACP,CAAC,CAAC,CAAC;QAEH,OAAO,WAAW,CAAC;IACrB,CAAC;IACD,sDAAsD;IACtD,CAAC,SAAS,CAAC,CACZ,CAAC;IAEF,MAAM,KAAK,GAAG,IAAA,4BAAoB,EAGhC,SAAS,EACT,GAAG,EAAE,CAAC,cAAc,CAAC,OAAO,EAC5B,GAAG,EAAE,CAAC,YAAY,CACnB,CAAC;IACF,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AAC1B,CAAC","sourcesContent":["import {\n weakHash,\n coerceQuery,\n type InstaQLOptions,\n InstantCoreDatabase,\n InstaQLLifecycleState,\n InstantSchemaDef,\n ValidQuery,\n} from '@instantdb/core';\nimport { useCallback, useRef, useSyncExternalStore } from 'react';\n\nconst defaultState = {\n isLoading: true,\n data: undefined,\n pageInfo: undefined,\n error: undefined,\n} as const;\n\nfunction stateForResult(result: any) {\n return {\n isLoading: !Boolean(result),\n data: undefined,\n pageInfo: undefined,\n error: undefined,\n ...(result ? result : {}),\n };\n}\n\nexport function useQueryInternal<\n Q extends ValidQuery<Q, Schema>,\n Schema extends InstantSchemaDef<any, any, any>,\n UseDates extends boolean,\n>(\n _core: InstantCoreDatabase<Schema, UseDates>,\n _query: null | Q,\n _opts?: InstaQLOptions,\n): {\n state: InstaQLLifecycleState<Schema, Q, UseDates>;\n query: any;\n} {\n if (_query && _opts && 'ruleParams' in _opts) {\n _query = { $$ruleParams: _opts['ruleParams'], ..._query };\n }\n const query = _query ? coerceQuery(_query) : null;\n const queryHash = weakHash(query);\n\n // We use a ref to store the result of the query.\n // This is becuase `useSyncExternalStore` uses `Object.is`\n // to compare the previous and next state.\n // If we don't use a ref, the state will always be considered different, so\n // the component will always re-render.\n const resultCacheRef = useRef<InstaQLLifecycleState<Schema, Q, UseDates>>(\n stateForResult(_core._reactor.getPreviousResult(query)),\n );\n\n // Similar to `resultCacheRef`, `useSyncExternalStore` will unsubscribe\n // if `subscribe` changes, so we use `useCallback` to memoize the function.\n const subscribe = useCallback(\n (cb) => {\n // Update the ref when the query changes to avoid showing stale data\n resultCacheRef.current = stateForResult(\n _core._reactor.getPreviousResult(query),\n );\n // before the subscribeQuery is connected and calls it's own callback,\n // we might have data in the store via SSR, we need to notify useSyncExternalStore that\n // the data has changed.\n cb();\n\n // Don't subscribe if query is null\n if (!query) {\n const unsubscribe = () => {};\n return unsubscribe;\n }\n\n const unsubscribe = _core.subscribeQuery<Q, UseDates>(query, (result) => {\n resultCacheRef.current = {\n isLoading: !Boolean(result),\n // @ts-expect-error: ts thinks this will always be overwritten\n data: undefined,\n // @ts-expect-error: ts thinks this will always be overwritten\n pageInfo: undefined,\n // @ts-expect-error: ts thinks this will always be overwritten\n error: undefined,\n ...result,\n };\n\n cb();\n });\n\n return unsubscribe;\n },\n // Build a new subscribe function if the query changes\n [queryHash],\n );\n\n const state = useSyncExternalStore<\n InstaQLLifecycleState<Schema, Q, UseDates>\n >(\n subscribe,\n () => resultCacheRef.current,\n () => defaultState,\n );\n return { state, query };\n}\n"]}
@@ -142,6 +142,7 @@ export default abstract class InstantReactAbstractDatabase<Schema extends Instan
142
142
  *
143
143
  */
144
144
  useAuth: () => AuthState;
145
+ protected _useAuth(): AuthState;
145
146
  /**
146
147
  * Subscribe to the currently logged in user.
147
148
  * If the user is not logged in, this hook with throw an Error.
@@ -1 +1 @@
1
- {"version":3,"file":"InstantReactAbstractDatabase.d.ts","sourceRoot":"","sources":["../../src/InstantReactAbstractDatabase.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"InstantReactAbstractDatabase.d.ts","sourceRoot":"","sources":["../../src/InstantReactAbstractDatabase.tsx"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ 'use client';
1
2
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
3
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
4
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -147,23 +148,7 @@ export default class InstantReactAbstractDatabase {
147
148
  *
148
149
  */
149
150
  this.useAuth = () => {
150
- // We use a ref to store the result of the query.
151
- // This is becuase `useSyncExternalStore` uses `Object.is`
152
- // to compare the previous and next state.
153
- // If we don't use a ref, the state will always be considered different, so
154
- // the component will always re-render.
155
- const resultCacheRef = useRef(this.core._reactor._currentUserCached);
156
- // Similar to `resultCacheRef`, `useSyncExternalStore` will unsubscribe
157
- // if `subscribe` changes, so we use `useCallback` to memoize the function.
158
- const subscribe = useCallback((cb) => {
159
- const unsubscribe = this.core.subscribeAuth((auth) => {
160
- resultCacheRef.current = Object.assign({ isLoading: false }, auth);
161
- cb();
162
- });
163
- return unsubscribe;
164
- }, []);
165
- const state = useSyncExternalStore(subscribe, () => resultCacheRef.current, () => defaultAuthState);
166
- return state;
151
+ return this._useAuth();
167
152
  };
168
153
  /**
169
154
  * Subscribe to the currently logged in user.
@@ -303,6 +288,25 @@ export default class InstantReactAbstractDatabase {
303
288
  room(type = '_defaultRoomType', id = '_defaultRoomId') {
304
289
  return new InstantReactRoom(this.core, type, id);
305
290
  }
291
+ _useAuth() {
292
+ // We use a ref to store the result of the query.
293
+ // This is becuase `useSyncExternalStore` uses `Object.is`
294
+ // to compare the previous and next state.
295
+ // If we don't use a ref, the state will always be considered different, so
296
+ // the component will always re-render.
297
+ const resultCacheRef = useRef(this.core._reactor._currentUserCached);
298
+ // Similar to `resultCacheRef`, `useSyncExternalStore` will unsubscribe
299
+ // if `subscribe` changes, so we use `useCallback` to memoize the function.
300
+ const subscribe = useCallback((cb) => {
301
+ const unsubscribe = this.core.subscribeAuth((auth) => {
302
+ resultCacheRef.current = Object.assign({ isLoading: false }, auth);
303
+ cb();
304
+ });
305
+ return unsubscribe;
306
+ }, []);
307
+ const state = useSyncExternalStore(subscribe, () => resultCacheRef.current, () => defaultAuthState);
308
+ return state;
309
+ }
306
310
  /**
307
311
  * One time query for the logged in state. This is useful
308
312
  * for scenarios where you want to know the current auth
@@ -1 +1 @@
1
- {"version":3,"file":"InstantReactAbstractDatabase.js","sourceRoot":"","sources":["../../src/InstantReactAbstractDatabase.tsx"],"names":[],"mappings":";;;;;;;;;;AAAA,OAAO,EAIL,MAAM,EAWN,IAAI,IAAI,SAAS,EAMjB,YAAY,GAEb,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAEL,WAAW,EACX,SAAS,EACT,MAAM,EACN,QAAQ,EACR,oBAAoB,GACrB,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAEhE,MAAM,gBAAgB,GAAG;IACvB,SAAS,EAAE,IAAI;IACf,IAAI,EAAE,SAAS;IACf,KAAK,EAAE,SAAS;CACjB,CAAC;AAEF,MAAM,CAAC,OAAO,OAAgB,4BAA4B;IAwBxD,YACE,MAEC,EACD,QAAoC;QAjB/B,OAAE,GAAG,MAAM,EAAU,CAAC;QAkC7B;;;;;;;;WAQG;QACH,eAAU,GAAG,CAAC,IAAY,EAAmB,EAAE;YAC7C,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACpC,CAAC,CAAC;QAEF;;;;;;;;;;WAUG;QACH,eAAU,GAAG,CAAC,IAAY,EAAiB,EAAE;YAC3C,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;YAE5D,SAAS,CAAC,GAAG,EAAE;gBACb,IAAI,OAAO,GAAG,IAAI,CAAC;gBACnB,MAAM,CAAC,GAAG,GAAS,EAAE;oBACnB,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;oBACvC,IAAI,CAAC,OAAO;wBAAE,OAAO;oBACrB,UAAU,CAAC,EAAE,CAAC,CAAC;gBACjB,CAAC,CAAA,CAAC;gBACF,CAAC,EAAE,CAAC;gBACJ,OAAO;YACT,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;YAEX,OAAO,OAAO,CAAC;QACjB,CAAC,CAAC;QAqBF;;;;;;;;;;WAUG;QACH,UAAK,GAAG,KAAK,CAAC;QAEd;;;;;;;;;;;;;;;;;;;;;;WAsBG;QACH,aAAQ,GAAG,CACT,MAAiE,EACjE,EAAE;YACF,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACpC,CAAC,CAAC;QAEF;;;;;;;;;;;;;;;;;;;;;;;WAuBG;QACH,aAAQ,GAAG,CACT,KAAe,EACf,IAAqB,EACuB,EAAE;YAC9C,OAAO,gBAAgB,CAAsB,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC;QAC7E,CAAC,CAAC;QAEF;;;;;;;;;;;;;;;;;;;;;;WAsBG;QACH,YAAO,GAAG,GAAc,EAAE;YACxB,iDAAiD;YACjD,0DAA0D;YAC1D,0CAA0C;YAC1C,2EAA2E;YAC3E,uCAAuC;YACvC,MAAM,cAAc,GAAG,MAAM,CAC3B,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CACtC,CAAC;YAEF,uEAAuE;YACvE,2EAA2E;YAC3E,MAAM,SAAS,GAAG,WAAW,CAAC,CAAC,EAAY,EAAE,EAAE;gBAC7C,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,IAAI,EAAE,EAAE;oBACnD,cAAc,CAAC,OAAO,mBAAK,SAAS,EAAE,KAAK,IAAK,IAAI,CAAE,CAAC;oBACvD,EAAE,EAAE,CAAC;gBACP,CAAC,CAAC,CAAC;gBAEH,OAAO,WAAW,CAAC;YACrB,CAAC,EAAE,EAAE,CAAC,CAAC;YAEP,MAAM,KAAK,GAAG,oBAAoB,CAChC,SAAS,EACT,GAAG,EAAE,CAAC,cAAc,CAAC,OAAO,EAC5B,GAAG,EAAE,CAAC,gBAAgB,CACvB,CAAC;YACF,OAAO,KAAK,CAAC;QACf,CAAC,CAAC;QAEF;;;;;;;;;;;;;;;;;;WAkBG;QACH,YAAO,GAAG,GAAS,EAAE;YACnB,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;YAChC,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,MAAM,IAAI,YAAY,CACpB,qDAAqD,CACtD,CAAC;YACJ,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;QAgBF;;;;;;;;;;;;;;;;;;;;;WAqBG;QACH,wBAAmB,GAAG,GAAqB,EAAE;YAC3C,MAAM,SAAS,GAAG,MAAM,CACtB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAA0B,CAC9C,CAAC;YAEF,MAAM,SAAS,GAAG,WAAW,CAAC,CAAC,EAAY,EAAE,EAAE;gBAC7C,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC,SAAS,EAAE,EAAE;oBACpE,IAAI,SAAS,KAAK,SAAS,CAAC,OAAO,EAAE,CAAC;wBACpC,SAAS,CAAC,OAAO,GAAG,SAAS,CAAC;wBAC9B,EAAE,EAAE,CAAC;oBACP,CAAC;gBACH,CAAC,CAAC,CAAC;gBAEH,OAAO,WAAW,CAAC;YACrB,CAAC,EAAE,EAAE,CAAC,CAAC;YAEP,MAAM,MAAM,GAAG,oBAAoB,CACjC,SAAS,EACT,GAAG,EAAE,CAAC,SAAS,CAAC,OAAO;YACvB,2DAA2D;YAC3D,GAAG,EAAE,CAAC,YAAY,CACnB,CAAC;YAEF,OAAO,MAAM,CAAC;QAChB,CAAC,CAAC;QAEF;;;;;;;;;;;;WAYG;QACH,cAAS,GAAG,CACV,KAAQ,EACR,IAAqB,EAIpB,EAAE;YACH,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAC1C,CAAC,CAAC;QAEF;;;;;;;;;WASG;QACH,aAAQ,GAEH,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE;YACpB,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;YAC5B,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,IAAI;gBAAE,OAAO,IAAI,CAAC;YAE5D,OAAO,4BAAG,QAAQ,GAAI,CAAC;QACzB,CAAC,CAAC;QAEF;;;;;;;;;WASG;QACH,cAAS,GAEJ,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE;YACpB,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;YAC5B,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,IAAI;gBAAE,OAAO,IAAI,CAAC;YAC3D,OAAO,4BAAG,QAAQ,GAAI,CAAC;QACzB,CAAC,CAAC;QA7VA,IAAI,CAAC,IAAI,GAAG,SAAS,CACnB,MAAM;QACN,6DAA6D;QAC7D,IAAI,CAAC,WAAW,CAAC,OAAO;QACxB,6DAA6D;QAC7D,IAAI,CAAC,WAAW,CAAC,eAAe,EAChC,QAAQ;QACR,6DAA6D;QAC7D,IAAI,CAAC,WAAW,CAAC,eAAe,CACjC,CAAC;QACF,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;QAC3B,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;IACnC,CAAC;IA2CD;;;;;;;;;;;OAWG;IACH,IAAI,CACF,OAAiB,kBAA8B,EAC/C,KAAa,gBAAgB;QAE7B,OAAO,IAAI,gBAAgB,CAA0B,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;IAC5E,CAAC;IA4JD;;;;;;;;;OASG;IACH,OAAO;QACL,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;IAC7B,CAAC;CA6GF","sourcesContent":["import {\n // types\n Auth,\n Storage,\n txInit,\n type AuthState,\n type User,\n type ConnectionStatus,\n type TransactionChunk,\n type RoomSchemaShape,\n type InstaQLParams,\n type InstaQLOptions,\n type InstantConfig,\n type PageInfoResponse,\n InstantCoreDatabase,\n init as core_init,\n InstaQLLifecycleState,\n InstaQLResponse,\n RoomsOf,\n InstantSchemaDef,\n IInstantDatabase,\n InstantError,\n ValidQuery,\n} from '@instantdb/core';\nimport {\n ReactNode,\n useCallback,\n useEffect,\n useRef,\n useState,\n useSyncExternalStore,\n} from 'react';\nimport { useQueryInternal } from './useQuery.ts';\nimport { InstantReactRoom, rooms } from './InstantReactRoom.ts';\n\nconst defaultAuthState = {\n isLoading: true,\n user: undefined,\n error: undefined,\n};\n\nexport default abstract class InstantReactAbstractDatabase<\n // need to pull this schema out to another generic for query params, not sure why\n Schema extends InstantSchemaDef<any, any, any>,\n UseDates extends boolean = false,\n Config extends InstantConfig<Schema, boolean> = InstantConfig<\n Schema,\n UseDates\n >,\n Rooms extends RoomSchemaShape = RoomsOf<Schema>,\n> implements IInstantDatabase<Schema>\n{\n public tx = txInit<Schema>();\n\n public auth: Auth;\n public storage: Storage;\n public core: InstantCoreDatabase<Schema, UseDates>;\n\n /** @deprecated use `core` instead */\n public _core: InstantCoreDatabase<Schema, UseDates>;\n\n static Storage?: any;\n static NetworkListener?: any;\n static EventSourceImpl?: any;\n\n constructor(\n config: Omit<InstantConfig<Schema, UseDates>, 'useDateObjects'> & {\n useDateObjects?: UseDates;\n },\n versions?: { [key: string]: string },\n ) {\n this.core = core_init<Schema, UseDates>(\n config,\n // @ts-expect-error because TS can't resolve subclass statics\n this.constructor.Storage,\n // @ts-expect-error because TS can't resolve subclass statics\n this.constructor.NetworkListener,\n versions,\n // @ts-expect-error because TS can't resolve subclass statics\n this.constructor.EventSourceImpl,\n );\n this._core = this.core;\n this.auth = this.core.auth;\n this.storage = this.core.storage;\n }\n\n /**\n * Returns a unique ID for a given `name`. It's stored in local storage,\n * so you will get the same ID across sessions.\n *\n * This is useful for generating IDs that could identify a local device or user.\n *\n * @example\n * const deviceId = await db.getLocalId('device');\n */\n getLocalId = (name: string): Promise<string> => {\n return this.core.getLocalId(name);\n };\n\n /**\n * A hook that returns a unique ID for a given `name`. localIds are\n * stored in local storage, so you will get the same ID across sessions.\n *\n * Initially returns `null`, and then loads the localId.\n *\n * @example\n * const deviceId = db.useLocalId('device');\n * if (!deviceId) return null; // loading\n * console.log('Device ID:', deviceId)\n */\n useLocalId = (name: string): string | null => {\n const [localId, setLocalId] = useState<string | null>(null);\n\n useEffect(() => {\n let mounted = true;\n const f = async () => {\n const id = await this.getLocalId(name);\n if (!mounted) return;\n setLocalId(id);\n };\n f();\n return;\n }, [name]);\n\n return localId;\n };\n\n /**\n * Obtain a handle to a room, which allows you to listen to topics and presence data\n *\n * If you don't provide a `type` or `id`, Instant will default to `_defaultRoomType` and `_defaultRoomId`\n * as the room type and id, respectively.\n *\n * @see https://instantdb.com/docs/presence-and-topics\n *\n * @example\n * const room = db.room('chat', roomId);\n * const { peers } = db.rooms.usePresence(room);\n */\n room<RoomType extends keyof Rooms>(\n type: RoomType = '_defaultRoomType' as RoomType,\n id: string = '_defaultRoomId',\n ) {\n return new InstantReactRoom<Schema, Rooms, RoomType>(this.core, type, id);\n }\n\n /**\n * Hooks for working with rooms\n *\n * @see https://instantdb.com/docs/presence-and-topics\n *\n * @example\n * const room = db.room('chat', roomId);\n * const { peers } = db.rooms.usePresence(room);\n * const publish = db.rooms.usePublishTopic(room, 'emoji');\n * // ...\n */\n rooms = rooms;\n\n /**\n * Use this to write data! You can create, update, delete, and link objects\n *\n * @see https://instantdb.com/docs/instaml\n *\n * @example\n * // Create a new object in the `goals` namespace\n * const goalId = id();\n * db.transact(db.tx.goals[goalId].update({title: \"Get fit\"}))\n *\n * // Update the title\n * db.transact(db.tx.goals[goalId].update({title: \"Get super fit\"}))\n *\n * // Delete it\n * db.transact(db.tx.goals[goalId].delete())\n *\n * // Or create an association:\n * todoId = id();\n * db.transact([\n * db.tx.todos[todoId].update({ title: 'Go on a run' }),\n * db.tx.goals[goalId].link({todos: todoId}),\n * ])\n */\n transact = (\n chunks: TransactionChunk<any, any> | TransactionChunk<any, any>[],\n ) => {\n return this.core.transact(chunks);\n };\n\n /**\n * Use this to query your data!\n *\n * @see https://instantdb.com/docs/instaql\n *\n * @example\n * // listen to all goals\n * const { isLoading, error, data } = db.useQuery({ goals: {} });\n *\n * // goals where the title is \"Get Fit\"\n * const { isLoading, error, data } = db.useQuery({\n * goals: { $: { where: { title: 'Get Fit' } } },\n * });\n *\n * // all goals, _alongside_ their todos\n * const { isLoading, error, data } = db.useQuery({\n * goals: { todos: {} },\n * });\n *\n * // skip if `user` is not logged in\n * const { isLoading, error, data } = db.useQuery(\n * auth.user ? { goals: {} } : null,\n * );\n */\n useQuery = <Q extends ValidQuery<Q, Schema>>(\n query: null | Q,\n opts?: InstaQLOptions,\n ): InstaQLLifecycleState<Schema, Q, UseDates> => {\n return useQueryInternal<Q, Schema, UseDates>(this.core, query, opts).state;\n };\n\n /**\n * Listen for the logged in state. This is useful\n * for deciding when to show a login screen.\n *\n * Check out the docs for an example `Login` component too!\n *\n * @see https://instantdb.com/docs/auth\n * @example\n * function App() {\n * const { isLoading, user, error } = db.useAuth()\n * if (isLoading) {\n * return <div>Loading...</div>\n * }\n * if (error) {\n * return <div>Uh oh! {error.message}</div>\n * }\n * if (user) {\n * return <Main user={user} />\n * }\n * return <Login />\n * }\n *\n */\n useAuth = (): AuthState => {\n // We use a ref to store the result of the query.\n // This is becuase `useSyncExternalStore` uses `Object.is`\n // to compare the previous and next state.\n // If we don't use a ref, the state will always be considered different, so\n // the component will always re-render.\n const resultCacheRef = useRef<AuthState>(\n this.core._reactor._currentUserCached,\n );\n\n // Similar to `resultCacheRef`, `useSyncExternalStore` will unsubscribe\n // if `subscribe` changes, so we use `useCallback` to memoize the function.\n const subscribe = useCallback((cb: Function) => {\n const unsubscribe = this.core.subscribeAuth((auth) => {\n resultCacheRef.current = { isLoading: false, ...auth };\n cb();\n });\n\n return unsubscribe;\n }, []);\n\n const state = useSyncExternalStore<AuthState>(\n subscribe,\n () => resultCacheRef.current,\n () => defaultAuthState,\n );\n return state;\n };\n\n /**\n * Subscribe to the currently logged in user.\n * If the user is not logged in, this hook with throw an Error.\n * You will want to protect any calls of this hook with a\n * <db.SignedIn> component, or your own logic based on db.useAuth()\n *\n * @see https://instantdb.com/docs/auth\n * @throws Error indicating user not signed in\n * @example\n * function UserDisplay() {\n * const user = db.useUser()\n * return <div>Logged in as: {user.email}</div>\n * }\n *\n * <db.SignedIn>\n * <UserDisplay />\n * </db.SignedIn>\n *\n */\n useUser = (): User => {\n const { user } = this.useAuth();\n if (!user) {\n throw new InstantError(\n 'useUser must be used within an auth-protected route',\n );\n }\n return user;\n };\n\n /**\n * One time query for the logged in state. This is useful\n * for scenarios where you want to know the current auth\n * state without subscribing to changes.\n *\n * @see https://instantdb.com/docs/auth\n * @example\n * const user = await db.getAuth();\n * console.log('logged in as', user.email)\n */\n getAuth(): Promise<User | null> {\n return this.core.getAuth();\n }\n\n /**\n * Listen for connection status changes to Instant. Use this for things like\n * showing connection state to users\n *\n * @see https://www.instantdb.com/docs/patterns#connection-status\n * @example\n * function App() {\n * const status = db.useConnectionStatus()\n * const connectionState =\n * status === 'connecting' || status === 'opened'\n * ? 'authenticating'\n * : status === 'authenticated'\n * ? 'connected'\n * : status === 'closed'\n * ? 'closed'\n * : status === 'errored'\n * ? 'errored'\n * : 'unexpected state';\n *\n * return <div>Connection state: {connectionState}</div>\n * }\n */\n useConnectionStatus = (): ConnectionStatus => {\n const statusRef = useRef<ConnectionStatus>(\n this.core._reactor.status as ConnectionStatus,\n );\n\n const subscribe = useCallback((cb: Function) => {\n const unsubscribe = this.core.subscribeConnectionStatus((newStatus) => {\n if (newStatus !== statusRef.current) {\n statusRef.current = newStatus;\n cb();\n }\n });\n\n return unsubscribe;\n }, []);\n\n const status = useSyncExternalStore<ConnectionStatus>(\n subscribe,\n () => statusRef.current,\n // For SSR, always return 'connecting' as the initial state\n () => 'connecting',\n );\n\n return status;\n };\n\n /**\n * Use this for one-off queries.\n * Returns local data if available, otherwise fetches from the server.\n * Because we want to avoid stale data, this method will throw an error\n * if the user is offline or there is no active connection to the server.\n *\n * @see https://instantdb.com/docs/instaql\n *\n * @example\n *\n * const resp = await db.queryOnce({ goals: {} });\n * console.log(resp.data.goals)\n */\n queryOnce = <Q extends ValidQuery<Q, Schema>>(\n query: Q,\n opts?: InstaQLOptions,\n ): Promise<{\n data: InstaQLResponse<Schema, Q, UseDates>;\n pageInfo: PageInfoResponse<Q>;\n }> => {\n return this.core.queryOnce(query, opts);\n };\n\n /**\n * Only render children if the user is signed in.\n * @see https://instantdb.com/docs/auth\n *\n * @example\n * <db.SignedIn>\n * <MyComponent />\n * </db.SignedIn>\n *\n */\n SignedIn: React.FC<{\n children: ReactNode;\n }> = ({ children }) => {\n const auth = this.useAuth();\n if (auth.isLoading || auth.error || !auth.user) return null;\n\n return <>{children}</>;\n };\n\n /**\n * Only render children if the user is signed out.\n * @see https://instantdb.com/docs/auth\n *\n * @example\n * <db.SignedOut>\n * <MyComponent />\n * </db.SignedOut>\n *\n */\n SignedOut: React.FC<{\n children: ReactNode;\n }> = ({ children }) => {\n const auth = this.useAuth();\n if (auth.isLoading || auth.error || auth.user) return null;\n return <>{children}</>;\n };\n}\n"]}
1
+ {"version":3,"file":"InstantReactAbstractDatabase.js","sourceRoot":"","sources":["../../src/InstantReactAbstractDatabase.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\nimport {\n // types\n Auth,\n Storage,\n txInit,\n type AuthState,\n type User,\n type ConnectionStatus,\n type TransactionChunk,\n type RoomSchemaShape,\n type InstaQLOptions,\n type InstantConfig,\n type PageInfoResponse,\n InstantCoreDatabase,\n init as core_init,\n InstaQLLifecycleState,\n InstaQLResponse,\n RoomsOf,\n InstantSchemaDef,\n IInstantDatabase,\n InstantError,\n ValidQuery,\n} from '@instantdb/core';\nimport {\n ReactNode,\n useCallback,\n useEffect,\n useRef,\n useState,\n useSyncExternalStore,\n} from 'react';\nimport { useQueryInternal } from './useQuery.ts';\nimport { InstantReactRoom, rooms } from './InstantReactRoom.ts';\n\nconst defaultAuthState = {\n isLoading: true,\n user: undefined,\n error: undefined,\n};\n\nexport default abstract class InstantReactAbstractDatabase<\n // need to pull this schema out to another generic for query params, not sure why\n Schema extends InstantSchemaDef<any, any, any>,\n UseDates extends boolean = false,\n Config extends InstantConfig<Schema, boolean> = InstantConfig<\n Schema,\n UseDates\n >,\n Rooms extends RoomSchemaShape = RoomsOf<Schema>,\n> implements IInstantDatabase<Schema>\n{\n public tx = txInit<Schema>();\n\n public auth: Auth;\n public storage: Storage;\n public core: InstantCoreDatabase<Schema, UseDates>;\n\n /** @deprecated use `core` instead */\n public _core: InstantCoreDatabase<Schema, UseDates>;\n\n static Storage?: any;\n static NetworkListener?: any;\n static EventSourceImpl?: any;\n\n constructor(\n config: Omit<InstantConfig<Schema, UseDates>, 'useDateObjects'> & {\n useDateObjects?: UseDates;\n },\n versions?: { [key: string]: string },\n ) {\n this.core = core_init<Schema, UseDates>(\n config,\n // @ts-expect-error because TS can't resolve subclass statics\n this.constructor.Storage,\n // @ts-expect-error because TS can't resolve subclass statics\n this.constructor.NetworkListener,\n versions,\n // @ts-expect-error because TS can't resolve subclass statics\n this.constructor.EventSourceImpl,\n );\n this._core = this.core;\n this.auth = this.core.auth;\n this.storage = this.core.storage;\n }\n\n /**\n * Returns a unique ID for a given `name`. It's stored in local storage,\n * so you will get the same ID across sessions.\n *\n * This is useful for generating IDs that could identify a local device or user.\n *\n * @example\n * const deviceId = await db.getLocalId('device');\n */\n getLocalId = (name: string): Promise<string> => {\n return this.core.getLocalId(name);\n };\n\n /**\n * A hook that returns a unique ID for a given `name`. localIds are\n * stored in local storage, so you will get the same ID across sessions.\n *\n * Initially returns `null`, and then loads the localId.\n *\n * @example\n * const deviceId = db.useLocalId('device');\n * if (!deviceId) return null; // loading\n * console.log('Device ID:', deviceId)\n */\n useLocalId = (name: string): string | null => {\n const [localId, setLocalId] = useState<string | null>(null);\n\n useEffect(() => {\n let mounted = true;\n const f = async () => {\n const id = await this.getLocalId(name);\n if (!mounted) return;\n setLocalId(id);\n };\n f();\n return;\n }, [name]);\n\n return localId;\n };\n\n /**\n * Obtain a handle to a room, which allows you to listen to topics and presence data\n *\n * If you don't provide a `type` or `id`, Instant will default to `_defaultRoomType` and `_defaultRoomId`\n * as the room type and id, respectively.\n *\n * @see https://instantdb.com/docs/presence-and-topics\n *\n * @example\n * const room = db.room('chat', roomId);\n * const { peers } = db.rooms.usePresence(room);\n */\n room<RoomType extends keyof Rooms>(\n type: RoomType = '_defaultRoomType' as RoomType,\n id: string = '_defaultRoomId',\n ) {\n return new InstantReactRoom<Schema, Rooms, RoomType>(this.core, type, id);\n }\n\n /**\n * Hooks for working with rooms\n *\n * @see https://instantdb.com/docs/presence-and-topics\n *\n * @example\n * const room = db.room('chat', roomId);\n * const { peers } = db.rooms.usePresence(room);\n * const publish = db.rooms.usePublishTopic(room, 'emoji');\n * // ...\n */\n rooms = rooms;\n\n /**\n * Use this to write data! You can create, update, delete, and link objects\n *\n * @see https://instantdb.com/docs/instaml\n *\n * @example\n * // Create a new object in the `goals` namespace\n * const goalId = id();\n * db.transact(db.tx.goals[goalId].update({title: \"Get fit\"}))\n *\n * // Update the title\n * db.transact(db.tx.goals[goalId].update({title: \"Get super fit\"}))\n *\n * // Delete it\n * db.transact(db.tx.goals[goalId].delete())\n *\n * // Or create an association:\n * todoId = id();\n * db.transact([\n * db.tx.todos[todoId].update({ title: 'Go on a run' }),\n * db.tx.goals[goalId].link({todos: todoId}),\n * ])\n */\n transact = (\n chunks: TransactionChunk<any, any> | TransactionChunk<any, any>[],\n ) => {\n return this.core.transact(chunks);\n };\n\n /**\n * Use this to query your data!\n *\n * @see https://instantdb.com/docs/instaql\n *\n * @example\n * // listen to all goals\n * const { isLoading, error, data } = db.useQuery({ goals: {} });\n *\n * // goals where the title is \"Get Fit\"\n * const { isLoading, error, data } = db.useQuery({\n * goals: { $: { where: { title: 'Get Fit' } } },\n * });\n *\n * // all goals, _alongside_ their todos\n * const { isLoading, error, data } = db.useQuery({\n * goals: { todos: {} },\n * });\n *\n * // skip if `user` is not logged in\n * const { isLoading, error, data } = db.useQuery(\n * auth.user ? { goals: {} } : null,\n * );\n */\n useQuery = <Q extends ValidQuery<Q, Schema>>(\n query: null | Q,\n opts?: InstaQLOptions,\n ): InstaQLLifecycleState<Schema, Q, UseDates> => {\n return useQueryInternal<Q, Schema, UseDates>(this.core, query, opts).state;\n };\n\n /**\n * Listen for the logged in state. This is useful\n * for deciding when to show a login screen.\n *\n * Check out the docs for an example `Login` component too!\n *\n * @see https://instantdb.com/docs/auth\n * @example\n * function App() {\n * const { isLoading, user, error } = db.useAuth()\n * if (isLoading) {\n * return <div>Loading...</div>\n * }\n * if (error) {\n * return <div>Uh oh! {error.message}</div>\n * }\n * if (user) {\n * return <Main user={user} />\n * }\n * return <Login />\n * }\n *\n */\n useAuth = (): AuthState => {\n return this._useAuth();\n };\n\n protected _useAuth(): AuthState {\n // We use a ref to store the result of the query.\n // This is becuase `useSyncExternalStore` uses `Object.is`\n // to compare the previous and next state.\n // If we don't use a ref, the state will always be considered different, so\n // the component will always re-render.\n const resultCacheRef = useRef<AuthState>(\n this.core._reactor._currentUserCached,\n );\n\n // Similar to `resultCacheRef`, `useSyncExternalStore` will unsubscribe\n // if `subscribe` changes, so we use `useCallback` to memoize the function.\n const subscribe = useCallback((cb: Function) => {\n const unsubscribe = this.core.subscribeAuth((auth) => {\n resultCacheRef.current = { isLoading: false, ...auth };\n cb();\n });\n\n return unsubscribe;\n }, []);\n\n const state = useSyncExternalStore<AuthState>(\n subscribe,\n () => resultCacheRef.current,\n () => defaultAuthState,\n );\n return state;\n }\n\n /**\n * Subscribe to the currently logged in user.\n * If the user is not logged in, this hook with throw an Error.\n * You will want to protect any calls of this hook with a\n * <db.SignedIn> component, or your own logic based on db.useAuth()\n *\n * @see https://instantdb.com/docs/auth\n * @throws Error indicating user not signed in\n * @example\n * function UserDisplay() {\n * const user = db.useUser()\n * return <div>Logged in as: {user.email}</div>\n * }\n *\n * <db.SignedIn>\n * <UserDisplay />\n * </db.SignedIn>\n *\n */\n useUser = (): User => {\n const { user } = this.useAuth();\n if (!user) {\n throw new InstantError(\n 'useUser must be used within an auth-protected route',\n );\n }\n return user;\n };\n\n /**\n * One time query for the logged in state. This is useful\n * for scenarios where you want to know the current auth\n * state without subscribing to changes.\n *\n * @see https://instantdb.com/docs/auth\n * @example\n * const user = await db.getAuth();\n * console.log('logged in as', user.email)\n */\n getAuth(): Promise<User | null> {\n return this.core.getAuth();\n }\n\n /**\n * Listen for connection status changes to Instant. Use this for things like\n * showing connection state to users\n *\n * @see https://www.instantdb.com/docs/patterns#connection-status\n * @example\n * function App() {\n * const status = db.useConnectionStatus()\n * const connectionState =\n * status === 'connecting' || status === 'opened'\n * ? 'authenticating'\n * : status === 'authenticated'\n * ? 'connected'\n * : status === 'closed'\n * ? 'closed'\n * : status === 'errored'\n * ? 'errored'\n * : 'unexpected state';\n *\n * return <div>Connection state: {connectionState}</div>\n * }\n */\n useConnectionStatus = (): ConnectionStatus => {\n const statusRef = useRef<ConnectionStatus>(\n this.core._reactor.status as ConnectionStatus,\n );\n\n const subscribe = useCallback((cb: Function) => {\n const unsubscribe = this.core.subscribeConnectionStatus((newStatus) => {\n if (newStatus !== statusRef.current) {\n statusRef.current = newStatus;\n cb();\n }\n });\n\n return unsubscribe;\n }, []);\n\n const status = useSyncExternalStore<ConnectionStatus>(\n subscribe,\n () => statusRef.current,\n // For SSR, always return 'connecting' as the initial state\n () => 'connecting',\n );\n\n return status;\n };\n\n /**\n * Use this for one-off queries.\n * Returns local data if available, otherwise fetches from the server.\n * Because we want to avoid stale data, this method will throw an error\n * if the user is offline or there is no active connection to the server.\n *\n * @see https://instantdb.com/docs/instaql\n *\n * @example\n *\n * const resp = await db.queryOnce({ goals: {} });\n * console.log(resp.data.goals)\n */\n queryOnce = <Q extends ValidQuery<Q, Schema>>(\n query: Q,\n opts?: InstaQLOptions,\n ): Promise<{\n data: InstaQLResponse<Schema, Q, UseDates>;\n pageInfo: PageInfoResponse<Q>;\n }> => {\n return this.core.queryOnce(query, opts);\n };\n\n /**\n * Only render children if the user is signed in.\n * @see https://instantdb.com/docs/auth\n *\n * @example\n * <db.SignedIn>\n * <MyComponent />\n * </db.SignedIn>\n *\n */\n SignedIn: React.FC<{\n children: ReactNode;\n }> = ({ children }) => {\n const auth = this.useAuth();\n if (auth.isLoading || auth.error || !auth.user) return null;\n\n return <>{children}</>;\n };\n\n /**\n * Only render children if the user is signed out.\n * @see https://instantdb.com/docs/auth\n *\n * @example\n * <db.SignedOut>\n * <MyComponent />\n * </db.SignedOut>\n *\n */\n SignedOut: React.FC<{\n children: ReactNode;\n }> = ({ children }) => {\n const auth = this.useAuth();\n if (auth.isLoading || auth.error || auth.user) return null;\n return <>{children}</>;\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"useQuery.d.ts","sourceRoot":"","sources":["../../src/useQuery.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,cAAc,EAEnB,mBAAmB,EACnB,qBAAqB,EACrB,gBAAgB,EAChB,UAAU,EACX,MAAM,iBAAiB,CAAC;AAoBzB,wBAAgB,gBAAgB,CAC9B,CAAC,SAAS,UAAU,CAAC,CAAC,EAAE,MAAM,CAAC,EAC/B,MAAM,SAAS,gBAAgB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAC9C,QAAQ,SAAS,OAAO,EAExB,KAAK,EAAE,mBAAmB,CAAC,MAAM,EAAE,QAAQ,CAAC,EAC5C,MAAM,EAAE,IAAI,GAAG,CAAC,EAChB,KAAK,CAAC,EAAE,cAAc,GACrB;IACD,KAAK,EAAE,qBAAqB,CAAC,MAAM,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;IAClD,KAAK,EAAE,GAAG,CAAC;CACZ,CA4DA"}
1
+ {"version":3,"file":"useQuery.d.ts","sourceRoot":"","sources":["../../src/useQuery.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,cAAc,EACnB,mBAAmB,EACnB,qBAAqB,EACrB,gBAAgB,EAChB,UAAU,EACX,MAAM,iBAAiB,CAAC;AAoBzB,wBAAgB,gBAAgB,CAC9B,CAAC,SAAS,UAAU,CAAC,CAAC,EAAE,MAAM,CAAC,EAC/B,MAAM,SAAS,gBAAgB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAC9C,QAAQ,SAAS,OAAO,EAExB,KAAK,EAAE,mBAAmB,CAAC,MAAM,EAAE,QAAQ,CAAC,EAC5C,MAAM,EAAE,IAAI,GAAG,CAAC,EAChB,KAAK,CAAC,EAAE,cAAc,GACrB;IACD,KAAK,EAAE,qBAAqB,CAAC,MAAM,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;IAClD,KAAK,EAAE,GAAG,CAAC;CACZ,CAgEA"}
@@ -26,6 +26,10 @@ export function useQueryInternal(_core, _query, _opts) {
26
26
  const subscribe = useCallback((cb) => {
27
27
  // Update the ref when the query changes to avoid showing stale data
28
28
  resultCacheRef.current = stateForResult(_core._reactor.getPreviousResult(query));
29
+ // before the subscribeQuery is connected and calls it's own callback,
30
+ // we might have data in the store via SSR, we need to notify useSyncExternalStore that
31
+ // the data has changed.
32
+ cb();
29
33
  // Don't subscribe if query is null
30
34
  if (!query) {
31
35
  const unsubscribe = () => { };
@@ -1 +1 @@
1
- {"version":3,"file":"useQuery.js","sourceRoot":"","sources":["../../src/useQuery.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EACR,WAAW,GAQZ,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAElE,MAAM,YAAY,GAAG;IACnB,SAAS,EAAE,IAAI;IACf,IAAI,EAAE,SAAS;IACf,QAAQ,EAAE,SAAS;IACnB,KAAK,EAAE,SAAS;CACR,CAAC;AAEX,SAAS,cAAc,CAAC,MAAW;IACjC,uBACE,SAAS,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,EAC3B,IAAI,EAAE,SAAS,EACf,QAAQ,EAAE,SAAS,EACnB,KAAK,EAAE,SAAS,IACb,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EACzB;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAK9B,KAA4C,EAC5C,MAAgB,EAChB,KAAsB;IAKtB,IAAI,MAAM,IAAI,KAAK,IAAI,YAAY,IAAI,KAAK,EAAE,CAAC;QAC7C,MAAM,mBAAK,YAAY,EAAE,KAAK,CAAC,YAAY,CAAC,IAAK,MAAM,CAAE,CAAC;IAC5D,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAClD,MAAM,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAElC,iDAAiD;IACjD,0DAA0D;IAC1D,0CAA0C;IAC1C,2EAA2E;IAC3E,uCAAuC;IACvC,MAAM,cAAc,GAAG,MAAM,CAC3B,cAAc,CAAC,KAAK,CAAC,QAAQ,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,CACxD,CAAC;IAEF,uEAAuE;IACvE,2EAA2E;IAC3E,MAAM,SAAS,GAAG,WAAW,CAC3B,CAAC,EAAE,EAAE,EAAE;QACL,oEAAoE;QACpE,cAAc,CAAC,OAAO,GAAG,cAAc,CACrC,KAAK,CAAC,QAAQ,CAAC,iBAAiB,CAAC,KAAK,CAAC,CACxC,CAAC;QAEF,mCAAmC;QACnC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,WAAW,GAAG,GAAG,EAAE,GAAE,CAAC,CAAC;YAC7B,OAAO,WAAW,CAAC;QACrB,CAAC;QAED,MAAM,WAAW,GAAG,KAAK,CAAC,cAAc,CAAc,KAAK,EAAE,CAAC,MAAM,EAAE,EAAE;YACtE,cAAc,CAAC,OAAO,mBACpB,SAAS,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC;gBAC3B,8DAA8D;gBAC9D,IAAI,EAAE,SAAS;gBACf,8DAA8D;gBAC9D,QAAQ,EAAE,SAAS;gBACnB,8DAA8D;gBAC9D,KAAK,EAAE,SAAS,IACb,MAAM,CACV,CAAC;YAEF,EAAE,EAAE,CAAC;QACP,CAAC,CAAC,CAAC;QAEH,OAAO,WAAW,CAAC;IACrB,CAAC;IACD,sDAAsD;IACtD,CAAC,SAAS,CAAC,CACZ,CAAC;IAEF,MAAM,KAAK,GAAG,oBAAoB,CAGhC,SAAS,EACT,GAAG,EAAE,CAAC,cAAc,CAAC,OAAO,EAC5B,GAAG,EAAE,CAAC,YAAY,CACnB,CAAC;IACF,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AAC1B,CAAC","sourcesContent":["import {\n weakHash,\n coerceQuery,\n type InstaQLParams,\n type InstaQLOptions,\n type InstantGraph,\n InstantCoreDatabase,\n InstaQLLifecycleState,\n InstantSchemaDef,\n ValidQuery,\n} from '@instantdb/core';\nimport { useCallback, useRef, useSyncExternalStore } from 'react';\n\nconst defaultState = {\n isLoading: true,\n data: undefined,\n pageInfo: undefined,\n error: undefined,\n} as const;\n\nfunction stateForResult(result: any) {\n return {\n isLoading: !Boolean(result),\n data: undefined,\n pageInfo: undefined,\n error: undefined,\n ...(result ? result : {}),\n };\n}\n\nexport function useQueryInternal<\n Q extends ValidQuery<Q, Schema>,\n Schema extends InstantSchemaDef<any, any, any>,\n UseDates extends boolean,\n>(\n _core: InstantCoreDatabase<Schema, UseDates>,\n _query: null | Q,\n _opts?: InstaQLOptions,\n): {\n state: InstaQLLifecycleState<Schema, Q, UseDates>;\n query: any;\n} {\n if (_query && _opts && 'ruleParams' in _opts) {\n _query = { $$ruleParams: _opts['ruleParams'], ..._query };\n }\n const query = _query ? coerceQuery(_query) : null;\n const queryHash = weakHash(query);\n\n // We use a ref to store the result of the query.\n // This is becuase `useSyncExternalStore` uses `Object.is`\n // to compare the previous and next state.\n // If we don't use a ref, the state will always be considered different, so\n // the component will always re-render.\n const resultCacheRef = useRef<InstaQLLifecycleState<Schema, Q, UseDates>>(\n stateForResult(_core._reactor.getPreviousResult(query)),\n );\n\n // Similar to `resultCacheRef`, `useSyncExternalStore` will unsubscribe\n // if `subscribe` changes, so we use `useCallback` to memoize the function.\n const subscribe = useCallback(\n (cb) => {\n // Update the ref when the query changes to avoid showing stale data\n resultCacheRef.current = stateForResult(\n _core._reactor.getPreviousResult(query),\n );\n\n // Don't subscribe if query is null\n if (!query) {\n const unsubscribe = () => {};\n return unsubscribe;\n }\n\n const unsubscribe = _core.subscribeQuery<Q, UseDates>(query, (result) => {\n resultCacheRef.current = {\n isLoading: !Boolean(result),\n // @ts-expect-error: ts thinks this will always be overwritten\n data: undefined,\n // @ts-expect-error: ts thinks this will always be overwritten\n pageInfo: undefined,\n // @ts-expect-error: ts thinks this will always be overwritten\n error: undefined,\n ...result,\n };\n\n cb();\n });\n\n return unsubscribe;\n },\n // Build a new subscribe function if the query changes\n [queryHash],\n );\n\n const state = useSyncExternalStore<\n InstaQLLifecycleState<Schema, Q, UseDates>\n >(\n subscribe,\n () => resultCacheRef.current,\n () => defaultState,\n );\n return { state, query };\n}\n"]}
1
+ {"version":3,"file":"useQuery.js","sourceRoot":"","sources":["../../src/useQuery.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EACR,WAAW,GAMZ,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAElE,MAAM,YAAY,GAAG;IACnB,SAAS,EAAE,IAAI;IACf,IAAI,EAAE,SAAS;IACf,QAAQ,EAAE,SAAS;IACnB,KAAK,EAAE,SAAS;CACR,CAAC;AAEX,SAAS,cAAc,CAAC,MAAW;IACjC,uBACE,SAAS,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,EAC3B,IAAI,EAAE,SAAS,EACf,QAAQ,EAAE,SAAS,EACnB,KAAK,EAAE,SAAS,IACb,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EACzB;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAK9B,KAA4C,EAC5C,MAAgB,EAChB,KAAsB;IAKtB,IAAI,MAAM,IAAI,KAAK,IAAI,YAAY,IAAI,KAAK,EAAE,CAAC;QAC7C,MAAM,mBAAK,YAAY,EAAE,KAAK,CAAC,YAAY,CAAC,IAAK,MAAM,CAAE,CAAC;IAC5D,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAClD,MAAM,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAElC,iDAAiD;IACjD,0DAA0D;IAC1D,0CAA0C;IAC1C,2EAA2E;IAC3E,uCAAuC;IACvC,MAAM,cAAc,GAAG,MAAM,CAC3B,cAAc,CAAC,KAAK,CAAC,QAAQ,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,CACxD,CAAC;IAEF,uEAAuE;IACvE,2EAA2E;IAC3E,MAAM,SAAS,GAAG,WAAW,CAC3B,CAAC,EAAE,EAAE,EAAE;QACL,oEAAoE;QACpE,cAAc,CAAC,OAAO,GAAG,cAAc,CACrC,KAAK,CAAC,QAAQ,CAAC,iBAAiB,CAAC,KAAK,CAAC,CACxC,CAAC;QACF,sEAAsE;QACtE,uFAAuF;QACvF,wBAAwB;QACxB,EAAE,EAAE,CAAC;QAEL,mCAAmC;QACnC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,WAAW,GAAG,GAAG,EAAE,GAAE,CAAC,CAAC;YAC7B,OAAO,WAAW,CAAC;QACrB,CAAC;QAED,MAAM,WAAW,GAAG,KAAK,CAAC,cAAc,CAAc,KAAK,EAAE,CAAC,MAAM,EAAE,EAAE;YACtE,cAAc,CAAC,OAAO,mBACpB,SAAS,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC;gBAC3B,8DAA8D;gBAC9D,IAAI,EAAE,SAAS;gBACf,8DAA8D;gBAC9D,QAAQ,EAAE,SAAS;gBACnB,8DAA8D;gBAC9D,KAAK,EAAE,SAAS,IACb,MAAM,CACV,CAAC;YAEF,EAAE,EAAE,CAAC;QACP,CAAC,CAAC,CAAC;QAEH,OAAO,WAAW,CAAC;IACrB,CAAC;IACD,sDAAsD;IACtD,CAAC,SAAS,CAAC,CACZ,CAAC;IAEF,MAAM,KAAK,GAAG,oBAAoB,CAGhC,SAAS,EACT,GAAG,EAAE,CAAC,cAAc,CAAC,OAAO,EAC5B,GAAG,EAAE,CAAC,YAAY,CACnB,CAAC;IACF,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AAC1B,CAAC","sourcesContent":["import {\n weakHash,\n coerceQuery,\n type InstaQLOptions,\n InstantCoreDatabase,\n InstaQLLifecycleState,\n InstantSchemaDef,\n ValidQuery,\n} from '@instantdb/core';\nimport { useCallback, useRef, useSyncExternalStore } from 'react';\n\nconst defaultState = {\n isLoading: true,\n data: undefined,\n pageInfo: undefined,\n error: undefined,\n} as const;\n\nfunction stateForResult(result: any) {\n return {\n isLoading: !Boolean(result),\n data: undefined,\n pageInfo: undefined,\n error: undefined,\n ...(result ? result : {}),\n };\n}\n\nexport function useQueryInternal<\n Q extends ValidQuery<Q, Schema>,\n Schema extends InstantSchemaDef<any, any, any>,\n UseDates extends boolean,\n>(\n _core: InstantCoreDatabase<Schema, UseDates>,\n _query: null | Q,\n _opts?: InstaQLOptions,\n): {\n state: InstaQLLifecycleState<Schema, Q, UseDates>;\n query: any;\n} {\n if (_query && _opts && 'ruleParams' in _opts) {\n _query = { $$ruleParams: _opts['ruleParams'], ..._query };\n }\n const query = _query ? coerceQuery(_query) : null;\n const queryHash = weakHash(query);\n\n // We use a ref to store the result of the query.\n // This is becuase `useSyncExternalStore` uses `Object.is`\n // to compare the previous and next state.\n // If we don't use a ref, the state will always be considered different, so\n // the component will always re-render.\n const resultCacheRef = useRef<InstaQLLifecycleState<Schema, Q, UseDates>>(\n stateForResult(_core._reactor.getPreviousResult(query)),\n );\n\n // Similar to `resultCacheRef`, `useSyncExternalStore` will unsubscribe\n // if `subscribe` changes, so we use `useCallback` to memoize the function.\n const subscribe = useCallback(\n (cb) => {\n // Update the ref when the query changes to avoid showing stale data\n resultCacheRef.current = stateForResult(\n _core._reactor.getPreviousResult(query),\n );\n // before the subscribeQuery is connected and calls it's own callback,\n // we might have data in the store via SSR, we need to notify useSyncExternalStore that\n // the data has changed.\n cb();\n\n // Don't subscribe if query is null\n if (!query) {\n const unsubscribe = () => {};\n return unsubscribe;\n }\n\n const unsubscribe = _core.subscribeQuery<Q, UseDates>(query, (result) => {\n resultCacheRef.current = {\n isLoading: !Boolean(result),\n // @ts-expect-error: ts thinks this will always be overwritten\n data: undefined,\n // @ts-expect-error: ts thinks this will always be overwritten\n pageInfo: undefined,\n // @ts-expect-error: ts thinks this will always be overwritten\n error: undefined,\n ...result,\n };\n\n cb();\n });\n\n return unsubscribe;\n },\n // Build a new subscribe function if the query changes\n [queryHash],\n );\n\n const state = useSyncExternalStore<\n InstaQLLifecycleState<Schema, Q, UseDates>\n >(\n subscribe,\n () => resultCacheRef.current,\n () => defaultState,\n );\n return { state, query };\n}\n"]}