@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.
@@ -1,6 +1,6 @@
1
1
  import { useCallback, useEffect, useMemo, useRef, useState, } from 'react';
2
2
  import { useTimeout } from "./useTimeout.js";
3
- export const defaultActivityStopTimeout = 1000;
3
+ export const defaultActivityStopTimeout = 1_000;
4
4
  // ------
5
5
  // Topics
6
6
  /**
@@ -70,10 +70,8 @@ export function usePublishTopic(room, topic) {
70
70
  * }
71
71
  */
72
72
  export function usePresence(room, opts = {}) {
73
- var _a, _b;
74
73
  const [state, setState] = useState(() => {
75
- var _a;
76
- return ((_a = room.core._reactor.getPresence(room.type, room.id, opts)) !== null && _a !== void 0 ? _a : {
74
+ return (room.core._reactor.getPresence(room.type, room.id, opts) ?? {
77
75
  peers: {},
78
76
  isLoading: true,
79
77
  });
@@ -83,12 +81,15 @@ export function usePresence(room, opts = {}) {
83
81
  setState(data);
84
82
  });
85
83
  return unsub;
86
- }, [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()]);
84
+ }, [room.id, opts.user, opts.peers?.join(), opts.keys?.join()]);
87
85
  const publishPresence = useCallback((data) => {
88
86
  room.core._reactor.publishPresence(room.type, room.id, data);
89
87
  }, [room.type, room.id]);
90
88
  const ret = useMemo(() => {
91
- return Object.assign(Object.assign({}, state), { publishPresence });
89
+ return {
90
+ ...state,
91
+ publishPresence,
92
+ };
92
93
  }, [state, publishPresence]);
93
94
  return ret;
94
95
  }
@@ -106,7 +107,7 @@ export function useSyncPresence(room, data, deps) {
106
107
  useEffect(() => room.core._reactor.joinRoom(room.id, data), [room.id]);
107
108
  useEffect(() => {
108
109
  return room.core._reactor.publishPresence(room.type, room.id, data);
109
- }, [room.type, room.id, deps !== null && deps !== void 0 ? deps : JSON.stringify(data)]);
110
+ }, [room.type, room.id, deps ?? JSON.stringify(data)]);
110
111
  }
111
112
  // -----------------
112
113
  // Typing Indicator
@@ -132,29 +133,27 @@ export function useTypingIndicator(room, inputName, opts = {}) {
132
133
  keys: [inputName],
133
134
  });
134
135
  const active = useMemo(() => {
135
- var _a;
136
136
  const presenceSnapshot = room._core._reactor.getPresence(room.type, room.id);
137
- return (opts === null || opts === void 0 ? void 0 : opts.writeOnly)
137
+ return opts?.writeOnly
138
138
  ? []
139
- : Object.values((_a = presenceSnapshot === null || presenceSnapshot === void 0 ? void 0 : presenceSnapshot.peers) !== null && _a !== void 0 ? _a : {}).filter((p) => p[inputName] === true);
140
- }, [opts === null || opts === void 0 ? void 0 : opts.writeOnly, observedPresence]);
139
+ : Object.values(presenceSnapshot?.peers ?? {}).filter((p) => p[inputName] === true);
140
+ }, [opts?.writeOnly, observedPresence]);
141
141
  const setActive = useCallback((isActive) => {
142
- var _a;
143
142
  room.core._reactor.publishPresence(room.type, room.id, {
144
143
  [inputName]: isActive,
145
144
  });
146
145
  if (!isActive)
147
146
  return;
148
- if ((opts === null || opts === void 0 ? void 0 : opts.timeout) === null || (opts === null || opts === void 0 ? void 0 : opts.timeout) === 0)
147
+ if (opts?.timeout === null || opts?.timeout === 0)
149
148
  return;
150
- timeout.set((_a = opts === null || opts === void 0 ? void 0 : opts.timeout) !== null && _a !== void 0 ? _a : defaultActivityStopTimeout, () => {
149
+ timeout.set(opts?.timeout ?? defaultActivityStopTimeout, () => {
151
150
  room.core._reactor.publishPresence(room.type, room.id, {
152
151
  [inputName]: null,
153
152
  });
154
153
  });
155
- }, [room.type, room.id, inputName, opts === null || opts === void 0 ? void 0 : opts.timeout, timeout]);
154
+ }, [room.type, room.id, inputName, opts?.timeout, timeout]);
156
155
  const onKeyDown = useCallback((e) => {
157
- const isEnter = (opts === null || opts === void 0 ? void 0 : opts.stopOnEnter) && e.key === 'Enter';
156
+ const isEnter = opts?.stopOnEnter && e.key === 'Enter';
158
157
  const isActive = !isEnter;
159
158
  setActive(isActive);
160
159
  }, [opts.stopOnEnter, setActive]);
@@ -182,96 +181,101 @@ export const rooms = {
182
181
  // ------------
183
182
  // Class
184
183
  export class InstantReactRoom {
184
+ core;
185
+ /** @deprecated use `core` instead */
186
+ _core;
187
+ type;
188
+ id;
185
189
  constructor(core, type, id) {
186
- /**
187
- * @deprecated
188
- * `db.room(...).useTopicEffect` is deprecated. You can replace it with `db.rooms.useTopicEffect`.
189
- *
190
- * @example
191
- *
192
- * // Before
193
- * const room = db.room('chat', 'room-id');
194
- * room.useTopicEffect('emoji', (message, peer) => { });
195
- *
196
- * // After
197
- * const room = db.room('chat', 'room-id');
198
- * db.rooms.useTopicEffect(room, 'emoji', (message, peer) => { });
199
- */
200
- this.useTopicEffect = (topic, onEvent) => {
201
- rooms.useTopicEffect(this, topic, onEvent);
202
- };
203
- /**
204
- * @deprecated
205
- * `db.room(...).usePublishTopic` is deprecated. You can replace it with `db.rooms.usePublishTopic`.
206
- *
207
- * @example
208
- *
209
- * // Before
210
- * const room = db.room('chat', 'room-id');
211
- * const publish = room.usePublishTopic('emoji');
212
- *
213
- * // After
214
- * const room = db.room('chat', 'room-id');
215
- * const publish = db.rooms.usePublishTopic(room, 'emoji');
216
- */
217
- this.usePublishTopic = (topic) => {
218
- return rooms.usePublishTopic(this, topic);
219
- };
220
- /**
221
- * @deprecated
222
- * `db.room(...).usePresence` is deprecated. You can replace it with `db.rooms.usePresence`.
223
- *
224
- * @example
225
- *
226
- * // Before
227
- * const room = db.room('chat', 'room-id');
228
- * const { peers } = room.usePresence({ keys: ["name", "avatar"] });
229
- *
230
- * // After
231
- * const room = db.room('chat', 'room-id');
232
- * const { peers } = db.rooms.usePresence(room, { keys: ["name", "avatar"] });
233
- */
234
- this.usePresence = (opts = {}) => {
235
- return rooms.usePresence(this, opts);
236
- };
237
- /**
238
- * @deprecated
239
- * `db.room(...).useSyncPresence` is deprecated. You can replace it with `db.rooms.useSyncPresence`.
240
- *
241
- * @example
242
- *
243
- * // Before
244
- * const room = db.room('chat', 'room-id');
245
- * room.useSyncPresence(room, { nickname });
246
- *
247
- * // After
248
- * const room = db.room('chat', 'room-id');
249
- * db.rooms.useSyncPresence(room, { nickname });
250
- */
251
- this.useSyncPresence = (data, deps) => {
252
- return rooms.useSyncPresence(this, data, deps);
253
- };
254
- /**
255
- * @deprecated
256
- * `db.room(...).useTypingIndicator` is deprecated. You can replace it with `db.rooms.useTypingIndicator`.
257
- *
258
- * @example
259
- *
260
- * // Before
261
- * const room = db.room('chat', 'room-id');
262
- * const typing = room.useTypingIndiactor(room, 'chat-input');
263
- *
264
- * // After
265
- * const room = db.room('chat', 'room-id');
266
- * const typing = db.rooms.useTypingIndiactor(room, 'chat-input');
267
- */
268
- this.useTypingIndicator = (inputName, opts = {}) => {
269
- return rooms.useTypingIndicator(this, inputName, opts);
270
- };
271
190
  this.core = core;
272
191
  this._core = this.core;
273
192
  this.type = type;
274
193
  this.id = id;
275
194
  }
195
+ /**
196
+ * @deprecated
197
+ * `db.room(...).useTopicEffect` is deprecated. You can replace it with `db.rooms.useTopicEffect`.
198
+ *
199
+ * @example
200
+ *
201
+ * // Before
202
+ * const room = db.room('chat', 'room-id');
203
+ * room.useTopicEffect('emoji', (message, peer) => { });
204
+ *
205
+ * // After
206
+ * const room = db.room('chat', 'room-id');
207
+ * db.rooms.useTopicEffect(room, 'emoji', (message, peer) => { });
208
+ */
209
+ useTopicEffect = (topic, onEvent) => {
210
+ rooms.useTopicEffect(this, topic, onEvent);
211
+ };
212
+ /**
213
+ * @deprecated
214
+ * `db.room(...).usePublishTopic` is deprecated. You can replace it with `db.rooms.usePublishTopic`.
215
+ *
216
+ * @example
217
+ *
218
+ * // Before
219
+ * const room = db.room('chat', 'room-id');
220
+ * const publish = room.usePublishTopic('emoji');
221
+ *
222
+ * // After
223
+ * const room = db.room('chat', 'room-id');
224
+ * const publish = db.rooms.usePublishTopic(room, 'emoji');
225
+ */
226
+ usePublishTopic = (topic) => {
227
+ return rooms.usePublishTopic(this, topic);
228
+ };
229
+ /**
230
+ * @deprecated
231
+ * `db.room(...).usePresence` is deprecated. You can replace it with `db.rooms.usePresence`.
232
+ *
233
+ * @example
234
+ *
235
+ * // Before
236
+ * const room = db.room('chat', 'room-id');
237
+ * const { peers } = room.usePresence({ keys: ["name", "avatar"] });
238
+ *
239
+ * // After
240
+ * const room = db.room('chat', 'room-id');
241
+ * const { peers } = db.rooms.usePresence(room, { keys: ["name", "avatar"] });
242
+ */
243
+ usePresence = (opts = {}) => {
244
+ return rooms.usePresence(this, opts);
245
+ };
246
+ /**
247
+ * @deprecated
248
+ * `db.room(...).useSyncPresence` is deprecated. You can replace it with `db.rooms.useSyncPresence`.
249
+ *
250
+ * @example
251
+ *
252
+ * // Before
253
+ * const room = db.room('chat', 'room-id');
254
+ * room.useSyncPresence(room, { nickname });
255
+ *
256
+ * // After
257
+ * const room = db.room('chat', 'room-id');
258
+ * db.rooms.useSyncPresence(room, { nickname });
259
+ */
260
+ useSyncPresence = (data, deps) => {
261
+ return rooms.useSyncPresence(this, data, deps);
262
+ };
263
+ /**
264
+ * @deprecated
265
+ * `db.room(...).useTypingIndicator` is deprecated. You can replace it with `db.rooms.useTypingIndicator`.
266
+ *
267
+ * @example
268
+ *
269
+ * // Before
270
+ * const room = db.room('chat', 'room-id');
271
+ * const typing = room.useTypingIndiactor(room, 'chat-input');
272
+ *
273
+ * // After
274
+ * const room = db.room('chat', 'room-id');
275
+ * const typing = db.rooms.useTypingIndiactor(room, 'chat-input');
276
+ */
277
+ useTypingIndicator = (inputName, opts = {}) => {
278
+ return rooms.useTypingIndicator(this, inputName, opts);
279
+ };
276
280
  }
277
281
  //# sourceMappingURL=InstantReactRoom.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"InstantReactRoom.js","sourceRoot":"","sources":["../../src/InstantReactRoom.ts"],"names":[],"mappings":"AASA,OAAO,EAEL,WAAW,EACX,SAAS,EACT,OAAO,EACP,MAAM,EACN,QAAQ,GACT,MAAM,OAAO,CAAC;AAEf,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAyB7C,MAAM,CAAC,MAAM,0BAA0B,GAAG,IAAK,CAAC;AAEhD,SAAS;AACT,SAAS;AAET;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,cAAc,CAK5B,IAAiD,EACjD,KAAgB,EAChB,OAGQ;IAER,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IACnC,UAAU,CAAC,OAAO,GAAG,OAAO,CAAC;IAE7B,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAC7C,IAAI,CAAC,EAAE,EACP,KAAK,EACL,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;YACd,UAAU,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAClC,CAAC,CACF,CAAC;QAEF,OAAO,KAAK,CAAC;IACf,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC;AACvB,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,eAAe,CAK7B,IAAiD,EACjD,KAAgB;IAEhB,SAAS,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IAEjE,MAAM,YAAY,GAAG,WAAW,CAC9B,CAAC,IAAI,EAAE,EAAE;QACP,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC;YAC9B,QAAQ,EAAE,IAAI,CAAC,IAAI;YACnB,MAAM,EAAE,IAAI,CAAC,EAAE;YACf,KAAK;YACL,IAAI;SACL,CAAC,CAAC;IACL,CAAC,EACD,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,CACjB,CAAC;IAEF,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,YAAY;AACZ,WAAW;AAEX;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,WAAW,CAKzB,IAAiD,EACjD,OAA6D,EAAE;;IAE/D,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAEhC,GAAG,EAAE;;QACL,OAAO,CACL,MAAA,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,mCAAI;YAC1D,KAAK,EAAE,EAAE;YACT,SAAS,EAAE,IAAI;SAChB,CACF,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAChD,IAAI,CAAC,IAAI,EACT,IAAI,CAAC,EAAE,EACP,IAAI,EACJ,CAAC,IAAI,EAAE,EAAE;YACP,QAAQ,CAAC,IAAI,CAAC,CAAC;QACjB,CAAC,CACF,CAAC;QAEF,OAAO,KAAK,CAAC;IACf,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,EAAE,MAAA,IAAI,CAAC,KAAK,0CAAE,IAAI,EAAE,EAAE,MAAA,IAAI,CAAC,IAAI,0CAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAEhE,MAAM,eAAe,GAAG,WAAW,CACjC,CAAC,IAAI,EAAE,EAAE;QACP,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;IAC/D,CAAC,EACD,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,CACrB,CAAC;IACF,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE;QACvB,uCACK,KAAK,KACR,eAAe,IACf;IACJ,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC,CAAC;IAC7B,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,eAAe,CAI7B,IAAiD,EACjD,IAA+C,EAC/C,IAAY;IAEZ,SAAS,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IACvE,SAAS,CAAC,GAAG,EAAE;QACb,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;IACtE,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,aAAJ,IAAI,cAAJ,IAAI,GAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACzD,CAAC;AAED,oBAAoB;AACpB,mBAAmB;AAEnB;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,kBAAkB,CAIhC,IAAiD,EACjD,SAAiB,EACjB,OAA4B,EAAE;IAE9B,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAE7B,MAAM,gBAAgB,GAAG,KAAK,CAAC,WAAW,CAAC,IAAI,EAAE;QAC/C,IAAI,EAAE,CAAC,SAAS,CAA+C;KAChE,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE;;QAC1B,MAAM,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,WAAW,CACtD,IAAI,CAAC,IAAI,EACT,IAAI,CAAC,EAAE,CACR,CAAC;QAEF,OAAO,CAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,SAAS;YACpB,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAA,gBAAgB,aAAhB,gBAAgB,uBAAhB,gBAAgB,CAAE,KAAK,mCAAI,EAAE,CAAC,CAAC,MAAM,CACjD,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,IAAI,CAC7B,CAAC;IACR,CAAC,EAAE,CAAC,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,SAAS,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAExC,MAAM,SAAS,GAAG,WAAW,CAC3B,CAAC,QAAiB,EAAE,EAAE;;QACpB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE;YACrD,CAAC,SAAS,CAAC,EAAE,QAAQ;SACsB,CAAC,CAAC;QAE/C,IAAI,CAAC,QAAQ;YAAE,OAAO;QAEtB,IAAI,CAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,OAAO,MAAK,IAAI,IAAI,CAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,OAAO,MAAK,CAAC;YAAE,OAAO;QAE1D,OAAO,CAAC,GAAG,CAAC,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,OAAO,mCAAI,0BAA0B,EAAE,GAAG,EAAE;YAC5D,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE;gBACrD,CAAC,SAAS,CAAC,EAAE,IAAI;aACe,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;IACL,CAAC,EACD,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,OAAO,EAAE,OAAO,CAAC,CACxD,CAAC;IACF,MAAM,SAAS,GAAG,WAAW,CAC3B,CAAC,CAAgB,EAAE,EAAE;QACnB,MAAM,OAAO,GAAG,CAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,WAAW,KAAI,CAAC,CAAC,GAAG,KAAK,OAAO,CAAC;QACvD,MAAM,QAAQ,GAAG,CAAC,OAAO,CAAC;QAE1B,SAAS,CAAC,QAAQ,CAAC,CAAC;IACtB,CAAC,EACD,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,CAC9B,CAAC;IACF,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,EAAE;QAC9B,SAAS,CAAC,KAAK,CAAC,CAAC;IACnB,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;IAEhB,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE;QAC9B,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;IAC/B,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC;IAExB,OAAO;QACL,MAAM;QACN,SAAS;QACT,UAAU;KACX,CAAC;AACJ,CAAC;AAED,iBAAiB;AACjB,QAAQ;AAER,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,cAAc;IACd,eAAe;IACf,WAAW;IACX,eAAe;IACf,kBAAkB;CACnB,CAAC;AAEF,eAAe;AACf,QAAQ;AAER,MAAM,OAAO,gBAAgB;IAW3B,YACE,IAA0C,EAC1C,IAAc,EACd,EAAU;QAQZ;;;;;;;;;;;;;WAaG;QACH,mBAAc,GAAG,CACf,KAAgB,EAChB,OAGQ,EACF,EAAE;YACR,KAAK,CAAC,cAAc,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;QAC7C,CAAC,CAAC;QAEF;;;;;;;;;;;;;WAaG;QACH,oBAAe,GAAG,CAChB,KAAY,EAC6C,EAAE;YAC3D,OAAO,KAAK,CAAC,eAAe,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC5C,CAAC,CAAC;QAEF;;;;;;;;;;;;;WAaG;QACH,gBAAW,GAAG,CACZ,OAA6D,EAAE,EACP,EAAE;YAC1D,OAAO,KAAK,CAAC,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACvC,CAAC,CAAC;QAEF;;;;;;;;;;;;;WAaG;QACH,oBAAe,GAAG,CAChB,IAA+C,EAC/C,IAAY,EACN,EAAE;YACR,OAAO,KAAK,CAAC,eAAe,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QACjD,CAAC,CAAC;QAEF;;;;;;;;;;;;;WAaG;QACH,uBAAkB,GAAG,CACnB,SAAiB,EACjB,OAA4B,EAAE,EAC2B,EAAE;YAC3D,OAAO,KAAK,CAAC,kBAAkB,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;QACzD,CAAC,CAAC;QA9GA,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;IACf,CAAC;CA2GF","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"]}
@@ -7,11 +7,17 @@ const defaultState = {
7
7
  error: undefined,
8
8
  };
9
9
  function stateForResult(result) {
10
- return Object.assign({ isLoading: !Boolean(result), data: undefined, pageInfo: undefined, error: undefined }, (result ? result : {}));
10
+ return {
11
+ isLoading: !Boolean(result),
12
+ data: undefined,
13
+ pageInfo: undefined,
14
+ error: undefined,
15
+ ...(result ? result : {}),
16
+ };
11
17
  }
12
18
  export function useQueryInternal(_core, _query, _opts) {
13
19
  if (_query && _opts && 'ruleParams' in _opts) {
14
- _query = Object.assign({ $$ruleParams: _opts['ruleParams'] }, _query);
20
+ _query = { $$ruleParams: _opts['ruleParams'], ..._query };
15
21
  }
16
22
  const query = _query ? coerceQuery(_query) : null;
17
23
  const queryHash = weakHash(query);
@@ -36,13 +42,16 @@ export function useQueryInternal(_core, _query, _opts) {
36
42
  return unsubscribe;
37
43
  }
38
44
  const unsubscribe = _core.subscribeQuery(query, (result) => {
39
- resultCacheRef.current = Object.assign({ isLoading: !Boolean(result),
45
+ resultCacheRef.current = {
46
+ isLoading: !Boolean(result),
40
47
  // @ts-expect-error: ts thinks this will always be overwritten
41
- data: undefined,
48
+ data: undefined,
42
49
  // @ts-expect-error: ts thinks this will always be overwritten
43
- pageInfo: undefined,
50
+ pageInfo: undefined,
44
51
  // @ts-expect-error: ts thinks this will always be overwritten
45
- error: undefined }, result);
52
+ error: undefined,
53
+ ...result,
54
+ };
46
55
  cb();
47
56
  });
48
57
  return unsubscribe;
@@ -1 +1 @@
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"]}
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,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,MAAM,UAAU,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,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,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,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"]}