@instantdb/react-common 0.22.99-experimental.add-user-perm-rules.20792844601.1 → 0.22.99-experimental.add-user-perm-rules.20792984656.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.
@@ -8,7 +8,7 @@ exports.useSyncPresence = useSyncPresence;
8
8
  exports.useTypingIndicator = useTypingIndicator;
9
9
  const react_1 = require("react");
10
10
  const useTimeout_ts_1 = require("./useTimeout.js");
11
- exports.defaultActivityStopTimeout = 1000;
11
+ exports.defaultActivityStopTimeout = 1_000;
12
12
  // ------
13
13
  // Topics
14
14
  /**
@@ -78,10 +78,8 @@ function usePublishTopic(room, topic) {
78
78
  * }
79
79
  */
80
80
  function usePresence(room, opts = {}) {
81
- var _a, _b;
82
81
  const [state, setState] = (0, react_1.useState)(() => {
83
- var _a;
84
- return ((_a = room.core._reactor.getPresence(room.type, room.id, opts)) !== null && _a !== void 0 ? _a : {
82
+ return (room.core._reactor.getPresence(room.type, room.id, opts) ?? {
85
83
  peers: {},
86
84
  isLoading: true,
87
85
  });
@@ -91,12 +89,15 @@ function usePresence(room, opts = {}) {
91
89
  setState(data);
92
90
  });
93
91
  return unsub;
94
- }, [room.id, opts.user, (_a = opts.peers) === null || _a === void 0 ? void 0 : _a.join(), (_b = opts.keys) === null || _b === void 0 ? void 0 : _b.join()]);
92
+ }, [room.id, opts.user, opts.peers?.join(), opts.keys?.join()]);
95
93
  const publishPresence = (0, react_1.useCallback)((data) => {
96
94
  room.core._reactor.publishPresence(room.type, room.id, data);
97
95
  }, [room.type, room.id]);
98
96
  const ret = (0, react_1.useMemo)(() => {
99
- return Object.assign(Object.assign({}, state), { publishPresence });
97
+ return {
98
+ ...state,
99
+ publishPresence,
100
+ };
100
101
  }, [state, publishPresence]);
101
102
  return ret;
102
103
  }
@@ -114,7 +115,7 @@ function useSyncPresence(room, data, deps) {
114
115
  (0, react_1.useEffect)(() => room.core._reactor.joinRoom(room.id, data), [room.id]);
115
116
  (0, react_1.useEffect)(() => {
116
117
  return room.core._reactor.publishPresence(room.type, room.id, data);
117
- }, [room.type, room.id, deps !== null && deps !== void 0 ? deps : JSON.stringify(data)]);
118
+ }, [room.type, room.id, deps ?? JSON.stringify(data)]);
118
119
  }
119
120
  // -----------------
120
121
  // Typing Indicator
@@ -140,29 +141,27 @@ function useTypingIndicator(room, inputName, opts = {}) {
140
141
  keys: [inputName],
141
142
  });
142
143
  const active = (0, react_1.useMemo)(() => {
143
- var _a;
144
144
  const presenceSnapshot = room._core._reactor.getPresence(room.type, room.id);
145
- return (opts === null || opts === void 0 ? void 0 : opts.writeOnly)
145
+ return opts?.writeOnly
146
146
  ? []
147
- : Object.values((_a = presenceSnapshot === null || presenceSnapshot === void 0 ? void 0 : presenceSnapshot.peers) !== null && _a !== void 0 ? _a : {}).filter((p) => p[inputName] === true);
148
- }, [opts === null || opts === void 0 ? void 0 : opts.writeOnly, observedPresence]);
147
+ : Object.values(presenceSnapshot?.peers ?? {}).filter((p) => p[inputName] === true);
148
+ }, [opts?.writeOnly, observedPresence]);
149
149
  const setActive = (0, react_1.useCallback)((isActive) => {
150
- var _a;
151
150
  room.core._reactor.publishPresence(room.type, room.id, {
152
151
  [inputName]: isActive,
153
152
  });
154
153
  if (!isActive)
155
154
  return;
156
- if ((opts === null || opts === void 0 ? void 0 : opts.timeout) === null || (opts === null || opts === void 0 ? void 0 : opts.timeout) === 0)
155
+ if (opts?.timeout === null || opts?.timeout === 0)
157
156
  return;
158
- timeout.set((_a = opts === null || opts === void 0 ? void 0 : opts.timeout) !== null && _a !== void 0 ? _a : exports.defaultActivityStopTimeout, () => {
157
+ timeout.set(opts?.timeout ?? exports.defaultActivityStopTimeout, () => {
159
158
  room.core._reactor.publishPresence(room.type, room.id, {
160
159
  [inputName]: null,
161
160
  });
162
161
  });
163
- }, [room.type, room.id, inputName, opts === null || opts === void 0 ? void 0 : opts.timeout, timeout]);
162
+ }, [room.type, room.id, inputName, opts?.timeout, timeout]);
164
163
  const onKeyDown = (0, react_1.useCallback)((e) => {
165
- const isEnter = (opts === null || opts === void 0 ? void 0 : opts.stopOnEnter) && e.key === 'Enter';
164
+ const isEnter = opts?.stopOnEnter && e.key === 'Enter';
166
165
  const isActive = !isEnter;
167
166
  setActive(isActive);
168
167
  }, [opts.stopOnEnter, setActive]);
@@ -190,97 +189,102 @@ exports.rooms = {
190
189
  // ------------
191
190
  // Class
192
191
  class InstantReactRoom {
192
+ core;
193
+ /** @deprecated use `core` instead */
194
+ _core;
195
+ type;
196
+ id;
193
197
  constructor(core, type, id) {
194
- /**
195
- * @deprecated
196
- * `db.room(...).useTopicEffect` is deprecated. You can replace it with `db.rooms.useTopicEffect`.
197
- *
198
- * @example
199
- *
200
- * // Before
201
- * const room = db.room('chat', 'room-id');
202
- * room.useTopicEffect('emoji', (message, peer) => { });
203
- *
204
- * // After
205
- * const room = db.room('chat', 'room-id');
206
- * db.rooms.useTopicEffect(room, 'emoji', (message, peer) => { });
207
- */
208
- this.useTopicEffect = (topic, onEvent) => {
209
- exports.rooms.useTopicEffect(this, topic, onEvent);
210
- };
211
- /**
212
- * @deprecated
213
- * `db.room(...).usePublishTopic` is deprecated. You can replace it with `db.rooms.usePublishTopic`.
214
- *
215
- * @example
216
- *
217
- * // Before
218
- * const room = db.room('chat', 'room-id');
219
- * const publish = room.usePublishTopic('emoji');
220
- *
221
- * // After
222
- * const room = db.room('chat', 'room-id');
223
- * const publish = db.rooms.usePublishTopic(room, 'emoji');
224
- */
225
- this.usePublishTopic = (topic) => {
226
- return exports.rooms.usePublishTopic(this, topic);
227
- };
228
- /**
229
- * @deprecated
230
- * `db.room(...).usePresence` is deprecated. You can replace it with `db.rooms.usePresence`.
231
- *
232
- * @example
233
- *
234
- * // Before
235
- * const room = db.room('chat', 'room-id');
236
- * const { peers } = room.usePresence({ keys: ["name", "avatar"] });
237
- *
238
- * // After
239
- * const room = db.room('chat', 'room-id');
240
- * const { peers } = db.rooms.usePresence(room, { keys: ["name", "avatar"] });
241
- */
242
- this.usePresence = (opts = {}) => {
243
- return exports.rooms.usePresence(this, opts);
244
- };
245
- /**
246
- * @deprecated
247
- * `db.room(...).useSyncPresence` is deprecated. You can replace it with `db.rooms.useSyncPresence`.
248
- *
249
- * @example
250
- *
251
- * // Before
252
- * const room = db.room('chat', 'room-id');
253
- * room.useSyncPresence(room, { nickname });
254
- *
255
- * // After
256
- * const room = db.room('chat', 'room-id');
257
- * db.rooms.useSyncPresence(room, { nickname });
258
- */
259
- this.useSyncPresence = (data, deps) => {
260
- return exports.rooms.useSyncPresence(this, data, deps);
261
- };
262
- /**
263
- * @deprecated
264
- * `db.room(...).useTypingIndicator` is deprecated. You can replace it with `db.rooms.useTypingIndicator`.
265
- *
266
- * @example
267
- *
268
- * // Before
269
- * const room = db.room('chat', 'room-id');
270
- * const typing = room.useTypingIndiactor(room, 'chat-input');
271
- *
272
- * // After
273
- * const room = db.room('chat', 'room-id');
274
- * const typing = db.rooms.useTypingIndiactor(room, 'chat-input');
275
- */
276
- this.useTypingIndicator = (inputName, opts = {}) => {
277
- return exports.rooms.useTypingIndicator(this, inputName, opts);
278
- };
279
198
  this.core = core;
280
199
  this._core = this.core;
281
200
  this.type = type;
282
201
  this.id = id;
283
202
  }
203
+ /**
204
+ * @deprecated
205
+ * `db.room(...).useTopicEffect` is deprecated. You can replace it with `db.rooms.useTopicEffect`.
206
+ *
207
+ * @example
208
+ *
209
+ * // Before
210
+ * const room = db.room('chat', 'room-id');
211
+ * room.useTopicEffect('emoji', (message, peer) => { });
212
+ *
213
+ * // After
214
+ * const room = db.room('chat', 'room-id');
215
+ * db.rooms.useTopicEffect(room, 'emoji', (message, peer) => { });
216
+ */
217
+ useTopicEffect = (topic, onEvent) => {
218
+ exports.rooms.useTopicEffect(this, topic, onEvent);
219
+ };
220
+ /**
221
+ * @deprecated
222
+ * `db.room(...).usePublishTopic` is deprecated. You can replace it with `db.rooms.usePublishTopic`.
223
+ *
224
+ * @example
225
+ *
226
+ * // Before
227
+ * const room = db.room('chat', 'room-id');
228
+ * const publish = room.usePublishTopic('emoji');
229
+ *
230
+ * // After
231
+ * const room = db.room('chat', 'room-id');
232
+ * const publish = db.rooms.usePublishTopic(room, 'emoji');
233
+ */
234
+ usePublishTopic = (topic) => {
235
+ return exports.rooms.usePublishTopic(this, topic);
236
+ };
237
+ /**
238
+ * @deprecated
239
+ * `db.room(...).usePresence` is deprecated. You can replace it with `db.rooms.usePresence`.
240
+ *
241
+ * @example
242
+ *
243
+ * // Before
244
+ * const room = db.room('chat', 'room-id');
245
+ * const { peers } = room.usePresence({ keys: ["name", "avatar"] });
246
+ *
247
+ * // After
248
+ * const room = db.room('chat', 'room-id');
249
+ * const { peers } = db.rooms.usePresence(room, { keys: ["name", "avatar"] });
250
+ */
251
+ usePresence = (opts = {}) => {
252
+ return exports.rooms.usePresence(this, opts);
253
+ };
254
+ /**
255
+ * @deprecated
256
+ * `db.room(...).useSyncPresence` is deprecated. You can replace it with `db.rooms.useSyncPresence`.
257
+ *
258
+ * @example
259
+ *
260
+ * // Before
261
+ * const room = db.room('chat', 'room-id');
262
+ * room.useSyncPresence(room, { nickname });
263
+ *
264
+ * // After
265
+ * const room = db.room('chat', 'room-id');
266
+ * db.rooms.useSyncPresence(room, { nickname });
267
+ */
268
+ useSyncPresence = (data, deps) => {
269
+ return exports.rooms.useSyncPresence(this, data, deps);
270
+ };
271
+ /**
272
+ * @deprecated
273
+ * `db.room(...).useTypingIndicator` is deprecated. You can replace it with `db.rooms.useTypingIndicator`.
274
+ *
275
+ * @example
276
+ *
277
+ * // Before
278
+ * const room = db.room('chat', 'room-id');
279
+ * const typing = room.useTypingIndiactor(room, 'chat-input');
280
+ *
281
+ * // After
282
+ * const room = db.room('chat', 'room-id');
283
+ * const typing = db.rooms.useTypingIndiactor(room, 'chat-input');
284
+ */
285
+ useTypingIndicator = (inputName, opts = {}) => {
286
+ return exports.rooms.useTypingIndicator(this, inputName, opts);
287
+ };
284
288
  }
285
289
  exports.InstantReactRoom = InstantReactRoom;
286
290
  //# sourceMappingURL=InstantReactRoom.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"InstantReactRoom.js","sourceRoot":"","sources":["../../src/InstantReactRoom.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n // types\n type PresenceOpts,\n type PresenceResponse,\n type RoomSchemaShape,\n InstantCoreDatabase,\n InstantSchemaDef,\n} from '@instantdb/core';\n\nimport {\n KeyboardEvent,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\n\nimport { useTimeout } from './useTimeout.ts';\n\nexport type PresenceHandle<\n PresenceShape,\n Keys extends keyof PresenceShape,\n> = PresenceResponse<PresenceShape, Keys> & {\n publishPresence: (data: Partial<PresenceShape>) => void;\n};\n\nexport type TypingIndicatorOpts = {\n timeout?: number | null;\n stopOnEnter?: boolean;\n // Perf opt - `active` will always be an empty array\n writeOnly?: boolean;\n};\n\nexport type TypingIndicatorHandle<PresenceShape> = {\n active: PresenceShape[];\n setActive(active: boolean): void;\n inputProps: {\n onKeyDown: (e: KeyboardEvent) => void;\n onBlur: () => void;\n };\n};\n\nexport const defaultActivityStopTimeout = 1_000;\n\n// ------\n// Topics\n\n/**\n * Listen for broadcasted events given a room and topic.\n *\n * @see https://instantdb.com/docs/presence-and-topics\n * @example\n * function App({ roomId }) {\n * const room = db.room('chats', roomId);\n * db.rooms.useTopicEffect(room, 'emoji', (message, peer) => {\n * console.log(peer.name, 'sent', message);\n * });\n * // ...\n * }\n */\nexport function useTopicEffect<\n RoomSchema extends RoomSchemaShape,\n RoomType extends keyof RoomSchema,\n TopicType extends keyof RoomSchema[RoomType]['topics'],\n>(\n room: InstantReactRoom<any, RoomSchema, RoomType>,\n topic: TopicType,\n onEvent: (\n event: RoomSchema[RoomType]['topics'][TopicType],\n peer: RoomSchema[RoomType]['presence'],\n ) => any,\n): void {\n const onEventRef = useRef(onEvent);\n onEventRef.current = onEvent;\n\n useEffect(() => {\n const unsub = room.core._reactor.subscribeTopic(\n room.id,\n topic,\n (event, peer) => {\n onEventRef.current(event, peer);\n },\n );\n\n return unsub;\n }, [room.id, topic]);\n}\n\n/**\n * Broadcast an event to a room.\n *\n * @see https://instantdb.com/docs/presence-and-topics\n * @example\n * function App({ roomId }) {\n * const room = db.room('chat', roomId);\n * const publishTopic = db.rooms.usePublishTopic(room, \"emoji\");\n *\n * return (\n * <button onClick={() => publishTopic({ emoji: \"🔥\" })}>Send emoji</button>\n * );\n * }\n *\n */\nexport function usePublishTopic<\n RoomSchema extends RoomSchemaShape,\n RoomType extends keyof RoomSchema,\n TopicType extends keyof RoomSchema[RoomType]['topics'],\n>(\n room: InstantReactRoom<any, RoomSchema, RoomType>,\n topic: TopicType,\n): (data: RoomSchema[RoomType]['topics'][TopicType]) => void {\n useEffect(() => room.core._reactor.joinRoom(room.id), [room.id]);\n\n const publishTopic = useCallback(\n (data) => {\n room.core._reactor.publishTopic({\n roomType: room.type,\n roomId: room.id,\n topic,\n data,\n });\n },\n [room.id, topic],\n );\n\n return publishTopic;\n}\n\n// ---------\n// Presence\n\n/**\n * Listen for peer's presence data in a room, and publish the current user's presence.\n *\n * @see https://instantdb.com/docs/presence-and-topics\n * @example\n * function App({ roomId }) {\n * const {\n * peers,\n * publishPresence\n * } = db.room(roomType, roomId).usePresence({ keys: [\"name\", \"avatar\"] });\n *\n * // ...\n * }\n */\nexport function usePresence<\n RoomSchema extends RoomSchemaShape,\n RoomType extends keyof RoomSchema,\n Keys extends keyof RoomSchema[RoomType]['presence'],\n>(\n room: InstantReactRoom<any, RoomSchema, RoomType>,\n opts: PresenceOpts<RoomSchema[RoomType]['presence'], Keys> = {},\n): PresenceHandle<RoomSchema[RoomType]['presence'], Keys> {\n const [state, setState] = useState<\n PresenceResponse<RoomSchema[RoomType]['presence'], Keys>\n >(() => {\n return (\n room.core._reactor.getPresence(room.type, room.id, opts) ?? {\n peers: {},\n isLoading: true,\n }\n );\n });\n\n useEffect(() => {\n const unsub = room.core._reactor.subscribePresence(\n room.type,\n room.id,\n opts,\n (data) => {\n setState(data);\n },\n );\n\n return unsub;\n }, [room.id, opts.user, opts.peers?.join(), opts.keys?.join()]);\n\n const publishPresence = useCallback(\n (data) => {\n room.core._reactor.publishPresence(room.type, room.id, data);\n },\n [room.type, room.id],\n );\n const ret = useMemo(() => {\n return {\n ...state,\n publishPresence,\n };\n }, [state, publishPresence]);\n return ret;\n}\n\n/**\n * Publishes presence data to a room\n *\n * @see https://instantdb.com/docs/presence-and-topics\n * @example\n * function App({ roomId, nickname }) {\n * const room = db.room('chat', roomId);\n * db.rooms.useSyncPresence(room, { nickname });\n * }\n */\nexport function useSyncPresence<\n RoomSchema extends RoomSchemaShape,\n RoomType extends keyof RoomSchema,\n>(\n room: InstantReactRoom<any, RoomSchema, RoomType>,\n data: Partial<RoomSchema[RoomType]['presence']>,\n deps?: any[],\n): void {\n useEffect(() => room.core._reactor.joinRoom(room.id, data), [room.id]);\n useEffect(() => {\n return room.core._reactor.publishPresence(room.type, room.id, data);\n }, [room.type, room.id, deps ?? JSON.stringify(data)]);\n}\n\n// -----------------\n// Typing Indicator\n\n/**\n * Manage typing indicator state\n *\n * @see https://instantdb.com/docs/presence-and-topics\n * @example\n * function App({ roomId }) {\n * const room = db.room('chat', roomId);\n * const {\n * active,\n * setActive,\n * inputProps,\n * } = db.rooms.useTypingIndicator(room, \"chat-input\");\n *\n * return <input {...inputProps} />;\n * }\n */\nexport function useTypingIndicator<\n RoomSchema extends RoomSchemaShape,\n RoomType extends keyof RoomSchema,\n>(\n room: InstantReactRoom<any, RoomSchema, RoomType>,\n inputName: string,\n opts: TypingIndicatorOpts = {},\n): TypingIndicatorHandle<RoomSchema[RoomType]['presence']> {\n const timeout = useTimeout();\n\n const observedPresence = rooms.usePresence(room, {\n keys: [inputName] as (keyof RoomSchema[RoomType]['presence'])[],\n });\n\n const active = useMemo(() => {\n const presenceSnapshot = room._core._reactor.getPresence(\n room.type,\n room.id,\n );\n\n return opts?.writeOnly\n ? []\n : Object.values(presenceSnapshot?.peers ?? {}).filter(\n (p) => p[inputName] === true,\n );\n }, [opts?.writeOnly, observedPresence]);\n\n const setActive = useCallback(\n (isActive: boolean) => {\n room.core._reactor.publishPresence(room.type, room.id, {\n [inputName]: isActive,\n } as unknown as Partial<RoomSchema[RoomType]>);\n\n if (!isActive) return;\n\n if (opts?.timeout === null || opts?.timeout === 0) return;\n\n timeout.set(opts?.timeout ?? defaultActivityStopTimeout, () => {\n room.core._reactor.publishPresence(room.type, room.id, {\n [inputName]: null,\n } as Partial<RoomSchema[RoomType]>);\n });\n },\n [room.type, room.id, inputName, opts?.timeout, timeout],\n );\n const onKeyDown = useCallback(\n (e: KeyboardEvent) => {\n const isEnter = opts?.stopOnEnter && e.key === 'Enter';\n const isActive = !isEnter;\n\n setActive(isActive);\n },\n [opts.stopOnEnter, setActive],\n );\n const onBlur = useCallback(() => {\n setActive(false);\n }, [setActive]);\n\n const inputProps = useMemo(() => {\n return { onKeyDown, onBlur };\n }, [onKeyDown, onBlur]);\n\n return {\n active,\n setActive,\n inputProps,\n };\n}\n\n// --------------\n// Hooks\n\nexport const rooms = {\n useTopicEffect,\n usePublishTopic,\n usePresence,\n useSyncPresence,\n useTypingIndicator,\n};\n\n// ------------\n// Class\n\nexport class InstantReactRoom<\n Schema extends InstantSchemaDef<any, any, any>,\n RoomSchema extends RoomSchemaShape,\n RoomType extends keyof RoomSchema,\n> {\n core: InstantCoreDatabase<Schema, boolean>;\n /** @deprecated use `core` instead */\n _core: InstantCoreDatabase<Schema, boolean>;\n type: RoomType;\n id: string;\n\n constructor(\n core: InstantCoreDatabase<Schema, boolean>,\n type: RoomType,\n id: string,\n ) {\n this.core = core;\n this._core = this.core;\n this.type = type;\n this.id = id;\n }\n\n /**\n * @deprecated\n * `db.room(...).useTopicEffect` is deprecated. You can replace it with `db.rooms.useTopicEffect`.\n *\n * @example\n *\n * // Before\n * const room = db.room('chat', 'room-id');\n * room.useTopicEffect('emoji', (message, peer) => { });\n *\n * // After\n * const room = db.room('chat', 'room-id');\n * db.rooms.useTopicEffect(room, 'emoji', (message, peer) => { });\n */\n useTopicEffect = <TopicType extends keyof RoomSchema[RoomType]['topics']>(\n topic: TopicType,\n onEvent: (\n event: RoomSchema[RoomType]['topics'][TopicType],\n peer: RoomSchema[RoomType]['presence'],\n ) => any,\n ): void => {\n rooms.useTopicEffect(this, topic, onEvent);\n };\n\n /**\n * @deprecated\n * `db.room(...).usePublishTopic` is deprecated. You can replace it with `db.rooms.usePublishTopic`.\n *\n * @example\n *\n * // Before\n * const room = db.room('chat', 'room-id');\n * const publish = room.usePublishTopic('emoji');\n *\n * // After\n * const room = db.room('chat', 'room-id');\n * const publish = db.rooms.usePublishTopic(room, 'emoji');\n */\n usePublishTopic = <Topic extends keyof RoomSchema[RoomType]['topics']>(\n topic: Topic,\n ): ((data: RoomSchema[RoomType]['topics'][Topic]) => void) => {\n return rooms.usePublishTopic(this, topic);\n };\n\n /**\n * @deprecated\n * `db.room(...).usePresence` is deprecated. You can replace it with `db.rooms.usePresence`.\n *\n * @example\n *\n * // Before\n * const room = db.room('chat', 'room-id');\n * const { peers } = room.usePresence({ keys: [\"name\", \"avatar\"] });\n *\n * // After\n * const room = db.room('chat', 'room-id');\n * const { peers } = db.rooms.usePresence(room, { keys: [\"name\", \"avatar\"] });\n */\n usePresence = <Keys extends keyof RoomSchema[RoomType]['presence']>(\n opts: PresenceOpts<RoomSchema[RoomType]['presence'], Keys> = {},\n ): PresenceHandle<RoomSchema[RoomType]['presence'], Keys> => {\n return rooms.usePresence(this, opts);\n };\n\n /**\n * @deprecated\n * `db.room(...).useSyncPresence` is deprecated. You can replace it with `db.rooms.useSyncPresence`.\n *\n * @example\n *\n * // Before\n * const room = db.room('chat', 'room-id');\n * room.useSyncPresence(room, { nickname });\n *\n * // After\n * const room = db.room('chat', 'room-id');\n * db.rooms.useSyncPresence(room, { nickname });\n */\n useSyncPresence = (\n data: Partial<RoomSchema[RoomType]['presence']>,\n deps?: any[],\n ): void => {\n return rooms.useSyncPresence(this, data, deps);\n };\n\n /**\n * @deprecated\n * `db.room(...).useTypingIndicator` is deprecated. You can replace it with `db.rooms.useTypingIndicator`.\n *\n * @example\n *\n * // Before\n * const room = db.room('chat', 'room-id');\n * const typing = room.useTypingIndiactor(room, 'chat-input');\n *\n * // After\n * const room = db.room('chat', 'room-id');\n * const typing = db.rooms.useTypingIndiactor(room, 'chat-input');\n */\n useTypingIndicator = (\n inputName: string,\n opts: TypingIndicatorOpts = {},\n ): TypingIndicatorHandle<RoomSchema[RoomType]['presence']> => {\n return rooms.useTypingIndicator(this, inputName, opts);\n };\n}\n"]}
1
+ {"version":3,"file":"InstantReactRoom.js","sourceRoot":"","sources":["../../src/InstantReactRoom.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n // types\n type PresenceOpts,\n type PresenceResponse,\n type RoomSchemaShape,\n InstantCoreDatabase,\n InstantSchemaDef,\n} from '@instantdb/core';\n\nimport {\n KeyboardEvent,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\n\nimport { useTimeout } from './useTimeout.ts';\n\nexport type PresenceHandle<\n PresenceShape,\n Keys extends keyof PresenceShape,\n> = PresenceResponse<PresenceShape, Keys> & {\n publishPresence: (data: Partial<PresenceShape>) => void;\n};\n\nexport type TypingIndicatorOpts = {\n timeout?: number | null;\n stopOnEnter?: boolean;\n // Perf opt - `active` will always be an empty array\n writeOnly?: boolean;\n};\n\nexport type TypingIndicatorHandle<PresenceShape> = {\n active: PresenceShape[];\n setActive(active: boolean): void;\n inputProps: {\n onKeyDown: (e: KeyboardEvent) => void;\n onBlur: () => void;\n };\n};\n\nexport const defaultActivityStopTimeout = 1_000;\n\n// ------\n// Topics\n\n/**\n * Listen for broadcasted events given a room and topic.\n *\n * @see https://instantdb.com/docs/presence-and-topics\n * @example\n * function App({ roomId }) {\n * const room = db.room('chats', roomId);\n * db.rooms.useTopicEffect(room, 'emoji', (message, peer) => {\n * console.log(peer.name, 'sent', message);\n * });\n * // ...\n * }\n */\nexport function useTopicEffect<\n RoomSchema extends RoomSchemaShape,\n RoomType extends keyof RoomSchema,\n TopicType extends keyof RoomSchema[RoomType]['topics'],\n>(\n room: InstantReactRoom<any, RoomSchema, RoomType>,\n topic: TopicType,\n onEvent: (\n event: RoomSchema[RoomType]['topics'][TopicType],\n peer: RoomSchema[RoomType]['presence'],\n ) => any,\n): void {\n const onEventRef = useRef(onEvent);\n onEventRef.current = onEvent;\n\n useEffect(() => {\n const unsub = room.core._reactor.subscribeTopic(\n room.id,\n topic,\n (event, peer) => {\n onEventRef.current(event, peer);\n },\n );\n\n return unsub;\n }, [room.id, topic]);\n}\n\n/**\n * Broadcast an event to a room.\n *\n * @see https://instantdb.com/docs/presence-and-topics\n * @example\n * function App({ roomId }) {\n * const room = db.room('chat', roomId);\n * const publishTopic = db.rooms.usePublishTopic(room, \"emoji\");\n *\n * return (\n * <button onClick={() => publishTopic({ emoji: \"🔥\" })}>Send emoji</button>\n * );\n * }\n *\n */\nexport function usePublishTopic<\n RoomSchema extends RoomSchemaShape,\n RoomType extends keyof RoomSchema,\n TopicType extends keyof RoomSchema[RoomType]['topics'],\n>(\n room: InstantReactRoom<any, RoomSchema, RoomType>,\n topic: TopicType,\n): (data: RoomSchema[RoomType]['topics'][TopicType]) => void {\n useEffect(() => room.core._reactor.joinRoom(room.id), [room.id]);\n\n const publishTopic = useCallback(\n (data) => {\n room.core._reactor.publishTopic({\n roomType: room.type,\n roomId: room.id,\n topic,\n data,\n });\n },\n [room.id, topic],\n );\n\n return publishTopic;\n}\n\n// ---------\n// Presence\n\n/**\n * Listen for peer's presence data in a room, and publish the current user's presence.\n *\n * @see https://instantdb.com/docs/presence-and-topics\n * @example\n * function App({ roomId }) {\n * const {\n * peers,\n * publishPresence\n * } = db.room(roomType, roomId).usePresence({ keys: [\"name\", \"avatar\"] });\n *\n * // ...\n * }\n */\nexport function usePresence<\n RoomSchema extends RoomSchemaShape,\n RoomType extends keyof RoomSchema,\n Keys extends keyof RoomSchema[RoomType]['presence'],\n>(\n room: InstantReactRoom<any, RoomSchema, RoomType>,\n opts: PresenceOpts<RoomSchema[RoomType]['presence'], Keys> = {},\n): PresenceHandle<RoomSchema[RoomType]['presence'], Keys> {\n const [state, setState] = useState<\n PresenceResponse<RoomSchema[RoomType]['presence'], Keys>\n >(() => {\n return (\n room.core._reactor.getPresence(room.type, room.id, opts) ?? {\n peers: {},\n isLoading: true,\n }\n );\n });\n\n useEffect(() => {\n const unsub = room.core._reactor.subscribePresence(\n room.type,\n room.id,\n opts,\n (data) => {\n setState(data);\n },\n );\n\n return unsub;\n }, [room.id, opts.user, opts.peers?.join(), opts.keys?.join()]);\n\n const publishPresence = useCallback(\n (data) => {\n room.core._reactor.publishPresence(room.type, room.id, data);\n },\n [room.type, room.id],\n );\n const ret = useMemo(() => {\n return {\n ...state,\n publishPresence,\n };\n }, [state, publishPresence]);\n return ret;\n}\n\n/**\n * Publishes presence data to a room\n *\n * @see https://instantdb.com/docs/presence-and-topics\n * @example\n * function App({ roomId, nickname }) {\n * const room = db.room('chat', roomId);\n * db.rooms.useSyncPresence(room, { nickname });\n * }\n */\nexport function useSyncPresence<\n RoomSchema extends RoomSchemaShape,\n RoomType extends keyof RoomSchema,\n>(\n room: InstantReactRoom<any, RoomSchema, RoomType>,\n data: Partial<RoomSchema[RoomType]['presence']>,\n deps?: any[],\n): void {\n useEffect(() => room.core._reactor.joinRoom(room.id, data), [room.id]);\n useEffect(() => {\n return room.core._reactor.publishPresence(room.type, room.id, data);\n }, [room.type, room.id, deps ?? JSON.stringify(data)]);\n}\n\n// -----------------\n// Typing Indicator\n\n/**\n * Manage typing indicator state\n *\n * @see https://instantdb.com/docs/presence-and-topics\n * @example\n * function App({ roomId }) {\n * const room = db.room('chat', roomId);\n * const {\n * active,\n * setActive,\n * inputProps,\n * } = db.rooms.useTypingIndicator(room, \"chat-input\");\n *\n * return <input {...inputProps} />;\n * }\n */\nexport function useTypingIndicator<\n RoomSchema extends RoomSchemaShape,\n RoomType extends keyof RoomSchema,\n>(\n room: InstantReactRoom<any, RoomSchema, RoomType>,\n inputName: string,\n opts: TypingIndicatorOpts = {},\n): TypingIndicatorHandle<RoomSchema[RoomType]['presence']> {\n const timeout = useTimeout();\n\n const observedPresence = rooms.usePresence(room, {\n keys: [inputName] as (keyof RoomSchema[RoomType]['presence'])[],\n });\n\n const active = useMemo(() => {\n const presenceSnapshot = room._core._reactor.getPresence(\n room.type,\n room.id,\n );\n\n return opts?.writeOnly\n ? []\n : Object.values(presenceSnapshot?.peers ?? {}).filter(\n (p) => p[inputName] === true,\n );\n }, [opts?.writeOnly, observedPresence]);\n\n const setActive = useCallback(\n (isActive: boolean) => {\n room.core._reactor.publishPresence(room.type, room.id, {\n [inputName]: isActive,\n } as unknown as Partial<RoomSchema[RoomType]>);\n\n if (!isActive) return;\n\n if (opts?.timeout === null || opts?.timeout === 0) return;\n\n timeout.set(opts?.timeout ?? defaultActivityStopTimeout, () => {\n room.core._reactor.publishPresence(room.type, room.id, {\n [inputName]: null,\n } as Partial<RoomSchema[RoomType]>);\n });\n },\n [room.type, room.id, inputName, opts?.timeout, timeout],\n );\n const onKeyDown = useCallback(\n (e: KeyboardEvent) => {\n const isEnter = opts?.stopOnEnter && e.key === 'Enter';\n const isActive = !isEnter;\n\n setActive(isActive);\n },\n [opts.stopOnEnter, setActive],\n );\n const onBlur = useCallback(() => {\n setActive(false);\n }, [setActive]);\n\n const inputProps = useMemo(() => {\n return { onKeyDown, onBlur };\n }, [onKeyDown, onBlur]);\n\n return {\n active,\n setActive,\n inputProps,\n };\n}\n\n// --------------\n// Hooks\n\nexport const rooms = {\n useTopicEffect,\n usePublishTopic,\n usePresence,\n useSyncPresence,\n useTypingIndicator,\n};\n\n// ------------\n// Class\n\nexport class InstantReactRoom<\n Schema extends InstantSchemaDef<any, any, any>,\n RoomSchema extends RoomSchemaShape,\n RoomType extends keyof RoomSchema,\n> {\n core: InstantCoreDatabase<Schema, boolean>;\n /** @deprecated use `core` instead */\n _core: InstantCoreDatabase<Schema, boolean>;\n type: RoomType;\n id: string;\n\n constructor(\n core: InstantCoreDatabase<Schema, boolean>,\n type: RoomType,\n id: string,\n ) {\n this.core = core;\n this._core = this.core;\n this.type = type;\n this.id = id;\n }\n\n /**\n * @deprecated\n * `db.room(...).useTopicEffect` is deprecated. You can replace it with `db.rooms.useTopicEffect`.\n *\n * @example\n *\n * // Before\n * const room = db.room('chat', 'room-id');\n * room.useTopicEffect('emoji', (message, peer) => { });\n *\n * // After\n * const room = db.room('chat', 'room-id');\n * db.rooms.useTopicEffect(room, 'emoji', (message, peer) => { });\n */\n useTopicEffect = <TopicType extends keyof RoomSchema[RoomType]['topics']>(\n topic: TopicType,\n onEvent: (\n event: RoomSchema[RoomType]['topics'][TopicType],\n peer: RoomSchema[RoomType]['presence'],\n ) => any,\n ): void => {\n rooms.useTopicEffect(this, topic, onEvent);\n };\n\n /**\n * @deprecated\n * `db.room(...).usePublishTopic` is deprecated. You can replace it with `db.rooms.usePublishTopic`.\n *\n * @example\n *\n * // Before\n * const room = db.room('chat', 'room-id');\n * const publish = room.usePublishTopic('emoji');\n *\n * // After\n * const room = db.room('chat', 'room-id');\n * const publish = db.rooms.usePublishTopic(room, 'emoji');\n */\n usePublishTopic = <Topic extends keyof RoomSchema[RoomType]['topics']>(\n topic: Topic,\n ): ((data: RoomSchema[RoomType]['topics'][Topic]) => void) => {\n return rooms.usePublishTopic(this, topic);\n };\n\n /**\n * @deprecated\n * `db.room(...).usePresence` is deprecated. You can replace it with `db.rooms.usePresence`.\n *\n * @example\n *\n * // Before\n * const room = db.room('chat', 'room-id');\n * const { peers } = room.usePresence({ keys: [\"name\", \"avatar\"] });\n *\n * // After\n * const room = db.room('chat', 'room-id');\n * const { peers } = db.rooms.usePresence(room, { keys: [\"name\", \"avatar\"] });\n */\n usePresence = <Keys extends keyof RoomSchema[RoomType]['presence']>(\n opts: PresenceOpts<RoomSchema[RoomType]['presence'], Keys> = {},\n ): PresenceHandle<RoomSchema[RoomType]['presence'], Keys> => {\n return rooms.usePresence(this, opts);\n };\n\n /**\n * @deprecated\n * `db.room(...).useSyncPresence` is deprecated. You can replace it with `db.rooms.useSyncPresence`.\n *\n * @example\n *\n * // Before\n * const room = db.room('chat', 'room-id');\n * room.useSyncPresence(room, { nickname });\n *\n * // After\n * const room = db.room('chat', 'room-id');\n * db.rooms.useSyncPresence(room, { nickname });\n */\n useSyncPresence = (\n data: Partial<RoomSchema[RoomType]['presence']>,\n deps?: any[],\n ): void => {\n return rooms.useSyncPresence(this, data, deps);\n };\n\n /**\n * @deprecated\n * `db.room(...).useTypingIndicator` is deprecated. You can replace it with `db.rooms.useTypingIndicator`.\n *\n * @example\n *\n * // Before\n * const room = db.room('chat', 'room-id');\n * const typing = room.useTypingIndiactor(room, 'chat-input');\n *\n * // After\n * const room = db.room('chat', 'room-id');\n * const typing = db.rooms.useTypingIndiactor(room, 'chat-input');\n */\n useTypingIndicator = (\n inputName: string,\n opts: TypingIndicatorOpts = {},\n ): TypingIndicatorHandle<RoomSchema[RoomType]['presence']> => {\n return rooms.useTypingIndicator(this, inputName, opts);\n };\n}\n"]}
@@ -10,11 +10,17 @@ const defaultState = {
10
10
  error: undefined,
11
11
  };
12
12
  function stateForResult(result) {
13
- return Object.assign({ isLoading: !Boolean(result), data: undefined, pageInfo: undefined, error: undefined }, (result ? result : {}));
13
+ return {
14
+ isLoading: !Boolean(result),
15
+ data: undefined,
16
+ pageInfo: undefined,
17
+ error: undefined,
18
+ ...(result ? result : {}),
19
+ };
14
20
  }
15
21
  function useQueryInternal(_core, _query, _opts) {
16
22
  if (_query && _opts && 'ruleParams' in _opts) {
17
- _query = Object.assign({ $$ruleParams: _opts['ruleParams'] }, _query);
23
+ _query = { $$ruleParams: _opts['ruleParams'], ..._query };
18
24
  }
19
25
  const query = _query ? (0, core_1.coerceQuery)(_query) : null;
20
26
  const queryHash = (0, core_1.weakHash)(query);
@@ -39,13 +45,16 @@ function useQueryInternal(_core, _query, _opts) {
39
45
  return unsubscribe;
40
46
  }
41
47
  const unsubscribe = _core.subscribeQuery(query, (result) => {
42
- resultCacheRef.current = Object.assign({ isLoading: !Boolean(result),
48
+ resultCacheRef.current = {
49
+ isLoading: !Boolean(result),
43
50
  // @ts-expect-error: ts thinks this will always be overwritten
44
- data: undefined,
51
+ data: undefined,
45
52
  // @ts-expect-error: ts thinks this will always be overwritten
46
- pageInfo: undefined,
53
+ pageInfo: undefined,
47
54
  // @ts-expect-error: ts thinks this will always be overwritten
48
- error: undefined }, result);
55
+ error: undefined,
56
+ ...result,
57
+ };
49
58
  cb();
50
59
  });
51
60
  return unsubscribe;
@@ -1 +1 @@
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"]}
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,OAAO;QACL,SAAS,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC;QAC3B,IAAI,EAAE,SAAS;QACf,QAAQ,EAAE,SAAS;QACnB,KAAK,EAAE,SAAS;QAChB,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;KAC1B,CAAC;AACJ,CAAC;AAED,SAAgB,gBAAgB,CAK9B,KAA4C,EAC5C,MAAgB,EAChB,KAAsB;IAKtB,IAAI,MAAM,IAAI,KAAK,IAAI,YAAY,IAAI,KAAK,EAAE,CAAC;QAC7C,MAAM,GAAG,EAAE,YAAY,EAAE,KAAK,CAAC,YAAY,CAAC,EAAE,GAAG,MAAM,EAAE,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,GAAG;gBACvB,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;gBAChB,GAAG,MAAM;aACV,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"]}