@instantdb/react-common 0.22.15-experimental.react-common.18536829600.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.
Files changed (65) hide show
  1. package/.tshy/build.json +8 -0
  2. package/.tshy/commonjs.json +16 -0
  3. package/.tshy/esm.json +15 -0
  4. package/README.md +53 -0
  5. package/dist/commonjs/InstantReactAbstractDatabase.d.ts +241 -0
  6. package/dist/commonjs/InstantReactAbstractDatabase.d.ts.map +1 -0
  7. package/dist/commonjs/InstantReactAbstractDatabase.js +323 -0
  8. package/dist/commonjs/InstantReactAbstractDatabase.js.map +1 -0
  9. package/dist/commonjs/InstantReactRoom.d.ts +183 -0
  10. package/dist/commonjs/InstantReactRoom.d.ts.map +1 -0
  11. package/dist/commonjs/InstantReactRoom.js +284 -0
  12. package/dist/commonjs/InstantReactRoom.js.map +1 -0
  13. package/dist/commonjs/index.d.ts +4 -0
  14. package/dist/commonjs/index.d.ts.map +1 -0
  15. package/dist/commonjs/index.js +9 -0
  16. package/dist/commonjs/index.js.map +1 -0
  17. package/dist/commonjs/package.json +3 -0
  18. package/dist/commonjs/useQuery.d.ts +6 -0
  19. package/dist/commonjs/useQuery.d.ts.map +1 -0
  20. package/dist/commonjs/useQuery.js +48 -0
  21. package/dist/commonjs/useQuery.js.map +1 -0
  22. package/dist/commonjs/useTimeout.d.ts +5 -0
  23. package/dist/commonjs/useTimeout.d.ts.map +1 -0
  24. package/dist/commonjs/useTimeout.js +19 -0
  25. package/dist/commonjs/useTimeout.js.map +1 -0
  26. package/dist/commonjs/version.d.ts +3 -0
  27. package/dist/commonjs/version.d.ts.map +1 -0
  28. package/dist/commonjs/version.js +5 -0
  29. package/dist/commonjs/version.js.map +1 -0
  30. package/dist/esm/InstantReactAbstractDatabase.d.ts +241 -0
  31. package/dist/esm/InstantReactAbstractDatabase.d.ts.map +1 -0
  32. package/dist/esm/InstantReactAbstractDatabase.js +320 -0
  33. package/dist/esm/InstantReactAbstractDatabase.js.map +1 -0
  34. package/dist/esm/InstantReactRoom.d.ts +183 -0
  35. package/dist/esm/InstantReactRoom.d.ts.map +1 -0
  36. package/dist/esm/InstantReactRoom.js +275 -0
  37. package/dist/esm/InstantReactRoom.js.map +1 -0
  38. package/dist/esm/index.d.ts +4 -0
  39. package/dist/esm/index.d.ts.map +1 -0
  40. package/dist/esm/index.js +3 -0
  41. package/dist/esm/index.js.map +1 -0
  42. package/dist/esm/package.json +3 -0
  43. package/dist/esm/useQuery.d.ts +6 -0
  44. package/dist/esm/useQuery.d.ts.map +1 -0
  45. package/dist/esm/useQuery.js +45 -0
  46. package/dist/esm/useQuery.js.map +1 -0
  47. package/dist/esm/useTimeout.d.ts +5 -0
  48. package/dist/esm/useTimeout.d.ts.map +1 -0
  49. package/dist/esm/useTimeout.js +16 -0
  50. package/dist/esm/useTimeout.js.map +1 -0
  51. package/dist/esm/version.d.ts +3 -0
  52. package/dist/esm/version.d.ts.map +1 -0
  53. package/dist/esm/version.js +3 -0
  54. package/dist/esm/version.js.map +1 -0
  55. package/dist/standalone/index.js +5993 -0
  56. package/dist/standalone/index.umd.cjs +36 -0
  57. package/package.json +68 -0
  58. package/src/InstantReactAbstractDatabase.tsx +421 -0
  59. package/src/InstantReactRoom.ts +443 -0
  60. package/src/index.ts +4 -0
  61. package/src/useQuery.ts +99 -0
  62. package/src/useTimeout.ts +20 -0
  63. package/src/version.ts +3 -0
  64. package/tsconfig.json +11 -0
  65. package/vite.config.ts +35 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useQuery.js","sourceRoot":"","sources":["../../src/useQuery.ts"],"names":[],"mappings":";;AA8BA,4CAoEC;AAlGD,0CAUyB;AACzB,iCAAkE;AAElE,MAAM,YAAY,GAAG;IACnB,SAAS,EAAE,IAAI;IACf,IAAI,EAAE,SAAS;IACf,QAAQ,EAAE,SAAS;IACnB,KAAK,EAAE,SAAS;CACjB,CAAC;AAEF,SAAS,cAAc,CAAC,MAAW;IACjC,uBACE,SAAS,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,EAC3B,IAAI,EAAE,SAAS,EACf,QAAQ,EAAE,SAAS,EACnB,KAAK,EAAE,SAAS,IACb,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EACzB;AACJ,CAAC;AAED,SAAgB,gBAAgB,CAK9B,KAA4C,EAC5C,MAAgB,EAChB,KAAsB;IAKtB,IAAI,MAAM,IAAI,KAAK,IAAI,YAAY,IAAI,KAAK,EAAE,CAAC;QAC7C,MAAM,mBAAK,YAAY,EAAE,KAAK,CAAC,YAAY,CAAC,IAAK,MAAM,CAAE,CAAC;IAC5D,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,IAAA,kBAAW,EAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAClD,MAAM,SAAS,GAAG,IAAA,eAAQ,EAAC,KAAK,CAAC,CAAC;IAElC,iDAAiD;IACjD,0DAA0D;IAC1D,0CAA0C;IAC1C,2EAA2E;IAC3E,uCAAuC;IACvC,MAAM,cAAc,GAAG,IAAA,cAAM,EAC3B,cAAc,CAAC,KAAK,CAAC,QAAQ,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,CACxD,CAAC;IAEF,uEAAuE;IACvE,2EAA2E;IAC3E,MAAM,SAAS,GAAG,IAAA,mBAAW,EAC3B,CAAC,EAAE,EAAE,EAAE;QACL,oEAAoE;QACpE,cAAc,CAAC,OAAO,GAAG,cAAc,CACrC,KAAK,CAAC,QAAQ,CAAC,iBAAiB,CAAC,KAAK,CAAC,CACxC,CAAC;QAEF,mCAAmC;QACnC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,WAAW,GAAG,GAAG,EAAE,GAAE,CAAC,CAAC;YAC7B,OAAO,WAAW,CAAC;QACrB,CAAC;QAED,MAAM,WAAW,GAAG,KAAK,CAAC,cAAc,CAAc,KAAK,EAAE,CAAC,MAAM,EAAE,EAAE;YACtE,cAAc,CAAC,OAAO,mBACpB,SAAS,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,EAC3B,IAAI,EAAE,SAAS,EACf,QAAQ,EAAE,SAAS,EACnB,KAAK,EAAE,SAAS,IACb,MAAM,CACV,CAAC;YAEF,EAAE,EAAE,CAAC;QACP,CAAC,CAAC,CAAC;QAEH,OAAO,WAAW,CAAC;IACrB,CAAC;IACD,sDAAsD;IACtD,CAAC,SAAS,CAAC,CACZ,CAAC;IAEF,MAAM,KAAK,GAAG,IAAA,4BAAoB,EAGhC,SAAS,EACT,GAAG,EAAE,CAAC,cAAc,CAAC,OAAO,EAC5B,GAAG,EAAE,CAAC,YAAY,CACnB,CAAC;IACF,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AAC1B,CAAC","sourcesContent":["import {\n weakHash,\n coerceQuery,\n type InstaQLParams,\n type InstaQLOptions,\n type InstantGraph,\n InstantCoreDatabase,\n InstaQLLifecycleState,\n InstantSchemaDef,\n ValidQuery,\n} from '@instantdb/core';\nimport { useCallback, useRef, useSyncExternalStore } from 'react';\n\nconst defaultState = {\n isLoading: true,\n data: undefined,\n pageInfo: undefined,\n error: undefined,\n};\n\nfunction stateForResult(result: any) {\n return {\n isLoading: !Boolean(result),\n data: undefined,\n pageInfo: undefined,\n error: undefined,\n ...(result ? result : {}),\n };\n}\n\nexport function useQueryInternal<\n Q extends ValidQuery<Q, Schema>,\n Schema extends InstantSchemaDef<any, any, any>,\n UseDates extends boolean,\n>(\n _core: InstantCoreDatabase<Schema, UseDates>,\n _query: null | Q,\n _opts?: InstaQLOptions,\n): {\n state: InstaQLLifecycleState<Schema, Q, UseDates>;\n query: any;\n} {\n if (_query && _opts && 'ruleParams' in _opts) {\n _query = { $$ruleParams: _opts['ruleParams'], ..._query };\n }\n const query = _query ? coerceQuery(_query) : null;\n const queryHash = weakHash(query);\n\n // We use a ref to store the result of the query.\n // This is becuase `useSyncExternalStore` uses `Object.is`\n // to compare the previous and next state.\n // If we don't use a ref, the state will always be considered different, so\n // the component will always re-render.\n const resultCacheRef = useRef<InstaQLLifecycleState<Schema, Q, UseDates>>(\n stateForResult(_core._reactor.getPreviousResult(query)),\n );\n\n // Similar to `resultCacheRef`, `useSyncExternalStore` will unsubscribe\n // if `subscribe` changes, so we use `useCallback` to memoize the function.\n const subscribe = useCallback(\n (cb) => {\n // Update the ref when the query changes to avoid showing stale data\n resultCacheRef.current = stateForResult(\n _core._reactor.getPreviousResult(query),\n );\n\n // Don't subscribe if query is null\n if (!query) {\n const unsubscribe = () => {};\n return unsubscribe;\n }\n\n const unsubscribe = _core.subscribeQuery<Q, UseDates>(query, (result) => {\n resultCacheRef.current = {\n isLoading: !Boolean(result),\n data: undefined,\n pageInfo: undefined,\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"]}
@@ -0,0 +1,5 @@
1
+ export declare function useTimeout(): {
2
+ set: (delay: number, fn: () => void) => void;
3
+ clear: () => void;
4
+ };
5
+ //# sourceMappingURL=useTimeout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTimeout.d.ts","sourceRoot":"","sources":["../../src/useTimeout.ts"],"names":[],"mappings":"AAEA,wBAAgB,UAAU;iBAOJ,MAAM,MAAM,MAAM,IAAI;;EAU3C"}
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useTimeout = useTimeout;
4
+ const react_1 = require("react");
5
+ function useTimeout() {
6
+ const timeoutRef = (0, react_1.useRef)(null);
7
+ (0, react_1.useEffect)(() => {
8
+ clear();
9
+ }, []);
10
+ function set(delay, fn) {
11
+ clearTimeout(timeoutRef.current);
12
+ timeoutRef.current = setTimeout(fn, delay);
13
+ }
14
+ function clear() {
15
+ clearTimeout(timeoutRef.current);
16
+ }
17
+ return { set, clear };
18
+ }
19
+ //# sourceMappingURL=useTimeout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTimeout.js","sourceRoot":"","sources":["../../src/useTimeout.ts"],"names":[],"mappings":";;AAEA,gCAiBC;AAnBD,iCAA0C;AAE1C,SAAgB,UAAU;IACxB,MAAM,UAAU,GAAG,IAAA,cAAM,EAAC,IAAI,CAAC,CAAC;IAEhC,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,KAAK,EAAE,CAAC;IACV,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,SAAS,GAAG,CAAC,KAAa,EAAE,EAAc;QACxC,YAAY,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QACjC,UAAU,CAAC,OAAO,GAAG,UAAU,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;IAC7C,CAAC;IAED,SAAS,KAAK;QACZ,YAAY,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC;IAED,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;AACxB,CAAC","sourcesContent":["import { useEffect, useRef } from 'react';\n\nexport function useTimeout() {\n const timeoutRef = useRef(null);\n\n useEffect(() => {\n clear();\n }, []);\n\n function set(delay: number, fn: () => void) {\n clearTimeout(timeoutRef.current);\n timeoutRef.current = setTimeout(fn, delay);\n }\n\n function clear() {\n clearTimeout(timeoutRef.current);\n }\n\n return { set, clear };\n}\n"]}
@@ -0,0 +1,3 @@
1
+ import { version } from '@instantdb/version';
2
+ export default version;
3
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C,eAAe,OAAO,CAAC"}
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const version_1 = require("@instantdb/version");
4
+ exports.default = version_1.version;
5
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":";;AAAA,gDAA6C;AAE7C,kBAAe,iBAAO,CAAC","sourcesContent":["import { version } from '@instantdb/version';\n\nexport default version;\n"]}
@@ -0,0 +1,241 @@
1
+ import { Auth, Storage, type AuthState, type User, type ConnectionStatus, type TransactionChunk, type RoomSchemaShape, type InstaQLOptions, type InstantConfig, type PageInfoResponse, InstantCoreDatabase, InstaQLLifecycleState, InstaQLResponse, RoomsOf, InstantSchemaDef, IInstantDatabase, ValidQuery } from '@instantdb/core';
2
+ import { ReactNode } from 'react';
3
+ import { InstantReactRoom } from './InstantReactRoom.ts';
4
+ export default abstract class InstantReactAbstractDatabase<Schema extends InstantSchemaDef<any, any, any>, Config extends InstantConfig<Schema, boolean> = InstantConfig<Schema, false>, Rooms extends RoomSchemaShape = RoomsOf<Schema>> implements IInstantDatabase<Schema> {
5
+ tx: import("@instantdb/core").TxChunk<Schema>;
6
+ auth: Auth;
7
+ storage: Storage;
8
+ core: InstantCoreDatabase<Schema, Config['useDateObjects']>;
9
+ /** @deprecated use `core` instead */
10
+ _core: InstantCoreDatabase<Schema, Config['useDateObjects']>;
11
+ static Storage?: any;
12
+ static NetworkListener?: any;
13
+ static EventSourceImpl?: any;
14
+ constructor(config: Config, versions?: {
15
+ [key: string]: string;
16
+ });
17
+ /**
18
+ * Returns a unique ID for a given `name`. It's stored in local storage,
19
+ * so you will get the same ID across sessions.
20
+ *
21
+ * This is useful for generating IDs that could identify a local device or user.
22
+ *
23
+ * @example
24
+ * const deviceId = await db.getLocalId('device');
25
+ */
26
+ getLocalId: (name: string) => Promise<string>;
27
+ /**
28
+ * A hook that returns a unique ID for a given `name`. localIds are
29
+ * stored in local storage, so you will get the same ID across sessions.
30
+ *
31
+ * Initially returns `null`, and then loads the localId.
32
+ *
33
+ * @example
34
+ * const deviceId = db.useLocalId('device');
35
+ * if (!deviceId) return null; // loading
36
+ * console.log('Device ID:', deviceId)
37
+ */
38
+ useLocalId: (name: string) => string | null;
39
+ /**
40
+ * Obtain a handle to a room, which allows you to listen to topics and presence data
41
+ *
42
+ * If you don't provide a `type` or `id`, Instant will default to `_defaultRoomType` and `_defaultRoomId`
43
+ * as the room type and id, respectively.
44
+ *
45
+ * @see https://instantdb.com/docs/presence-and-topics
46
+ *
47
+ * @example
48
+ * const room = db.room('chat', roomId);
49
+ * const { peers } = db.rooms.usePresence(room);
50
+ */
51
+ room<RoomType extends keyof Rooms>(type?: RoomType, id?: string): InstantReactRoom<Schema, Rooms, RoomType>;
52
+ /**
53
+ * Hooks for working with rooms
54
+ *
55
+ * @see https://instantdb.com/docs/presence-and-topics
56
+ *
57
+ * @example
58
+ * const room = db.room('chat', roomId);
59
+ * const { peers } = db.rooms.usePresence(room);
60
+ * const publish = db.rooms.usePublishTopic(room, 'emoji');
61
+ * // ...
62
+ */
63
+ rooms: {
64
+ useTopicEffect: typeof import("./InstantReactRoom.ts").useTopicEffect;
65
+ usePublishTopic: typeof import("./InstantReactRoom.ts").usePublishTopic;
66
+ usePresence: typeof import("./InstantReactRoom.ts").usePresence;
67
+ useSyncPresence: typeof import("./InstantReactRoom.ts").useSyncPresence;
68
+ useTypingIndicator: typeof import("./InstantReactRoom.ts").useTypingIndicator;
69
+ };
70
+ /**
71
+ * Use this to write data! You can create, update, delete, and link objects
72
+ *
73
+ * @see https://instantdb.com/docs/instaml
74
+ *
75
+ * @example
76
+ * // Create a new object in the `goals` namespace
77
+ * const goalId = id();
78
+ * db.transact(db.tx.goals[goalId].update({title: "Get fit"}))
79
+ *
80
+ * // Update the title
81
+ * db.transact(db.tx.goals[goalId].update({title: "Get super fit"}))
82
+ *
83
+ * // Delete it
84
+ * db.transact(db.tx.goals[goalId].delete())
85
+ *
86
+ * // Or create an association:
87
+ * todoId = id();
88
+ * db.transact([
89
+ * db.tx.todos[todoId].update({ title: 'Go on a run' }),
90
+ * db.tx.goals[goalId].link({todos: todoId}),
91
+ * ])
92
+ */
93
+ transact: (chunks: TransactionChunk<any, any> | TransactionChunk<any, any>[]) => Promise<import("@instantdb/core").TransactionResult>;
94
+ /**
95
+ * Use this to query your data!
96
+ *
97
+ * @see https://instantdb.com/docs/instaql
98
+ *
99
+ * @example
100
+ * // listen to all goals
101
+ * const { isLoading, error, data } = db.useQuery({ goals: {} });
102
+ *
103
+ * // goals where the title is "Get Fit"
104
+ * const { isLoading, error, data } = db.useQuery({
105
+ * goals: { $: { where: { title: 'Get Fit' } } },
106
+ * });
107
+ *
108
+ * // all goals, _alongside_ their todos
109
+ * const { isLoading, error, data } = db.useQuery({
110
+ * goals: { todos: {} },
111
+ * });
112
+ *
113
+ * // skip if `user` is not logged in
114
+ * const { isLoading, error, data } = db.useQuery(
115
+ * auth.user ? { goals: {} } : null,
116
+ * );
117
+ */
118
+ useQuery: <Q extends ValidQuery<Q, Schema>>(query: null | Q, opts?: InstaQLOptions) => InstaQLLifecycleState<Schema, Q, NonNullable<Config["useDateObjects"]>>;
119
+ /**
120
+ * Listen for the logged in state. This is useful
121
+ * for deciding when to show a login screen.
122
+ *
123
+ * Check out the docs for an example `Login` component too!
124
+ *
125
+ * @see https://instantdb.com/docs/auth
126
+ * @example
127
+ * function App() {
128
+ * const { isLoading, user, error } = db.useAuth()
129
+ * if (isLoading) {
130
+ * return <div>Loading...</div>
131
+ * }
132
+ * if (error) {
133
+ * return <div>Uh oh! {error.message}</div>
134
+ * }
135
+ * if (user) {
136
+ * return <Main user={user} />
137
+ * }
138
+ * return <Login />
139
+ * }
140
+ *
141
+ */
142
+ useAuth: () => AuthState;
143
+ /**
144
+ * Subscribe to the currently logged in user.
145
+ * If the user is not logged in, this hook with throw an Error.
146
+ * You will want to protect any calls of this hook with a
147
+ * <db.SignedIn> component, or your own logic based on db.useAuth()
148
+ *
149
+ * @see https://instantdb.com/docs/auth
150
+ * @throws Error indicating user not signed in
151
+ * @example
152
+ * function UserDisplay() {
153
+ * const user = db.useUser()
154
+ * return <div>Logged in as: {user.email}</div>
155
+ * }
156
+ *
157
+ * <db.SignedIn>
158
+ * <UserDisplay />
159
+ * </db.SignedIn>
160
+ *
161
+ */
162
+ useUser: () => User;
163
+ /**
164
+ * One time query for the logged in state. This is useful
165
+ * for scenarios where you want to know the current auth
166
+ * state without subscribing to changes.
167
+ *
168
+ * @see https://instantdb.com/docs/auth
169
+ * @example
170
+ * const user = await db.getAuth();
171
+ * console.log('logged in as', user.email)
172
+ */
173
+ getAuth(): Promise<User | null>;
174
+ /**
175
+ * Listen for connection status changes to Instant. Use this for things like
176
+ * showing connection state to users
177
+ *
178
+ * @see https://www.instantdb.com/docs/patterns#connection-status
179
+ * @example
180
+ * function App() {
181
+ * const status = db.useConnectionStatus()
182
+ * const connectionState =
183
+ * status === 'connecting' || status === 'opened'
184
+ * ? 'authenticating'
185
+ * : status === 'authenticated'
186
+ * ? 'connected'
187
+ * : status === 'closed'
188
+ * ? 'closed'
189
+ * : status === 'errored'
190
+ * ? 'errored'
191
+ * : 'unexpected state';
192
+ *
193
+ * return <div>Connection state: {connectionState}</div>
194
+ * }
195
+ */
196
+ useConnectionStatus: () => ConnectionStatus;
197
+ /**
198
+ * Use this for one-off queries.
199
+ * Returns local data if available, otherwise fetches from the server.
200
+ * Because we want to avoid stale data, this method will throw an error
201
+ * if the user is offline or there is no active connection to the server.
202
+ *
203
+ * @see https://instantdb.com/docs/instaql
204
+ *
205
+ * @example
206
+ *
207
+ * const resp = await db.queryOnce({ goals: {} });
208
+ * console.log(resp.data.goals)
209
+ */
210
+ queryOnce: <Q extends ValidQuery<Q, Schema>>(query: Q, opts?: InstaQLOptions) => Promise<{
211
+ data: InstaQLResponse<Schema, Q, Config["useDateObjects"]>;
212
+ pageInfo: PageInfoResponse<Q>;
213
+ }>;
214
+ /**
215
+ * Only render children if the user is signed in.
216
+ * @see https://instantdb.com/docs/auth
217
+ *
218
+ * @example
219
+ * <db.SignedIn>
220
+ * <MyComponent />
221
+ * </db.SignedIn>
222
+ *
223
+ */
224
+ SignedIn: React.FC<{
225
+ children: ReactNode;
226
+ }>;
227
+ /**
228
+ * Only render children if the user is signed out.
229
+ * @see https://instantdb.com/docs/auth
230
+ *
231
+ * @example
232
+ * <db.SignedOut>
233
+ * <MyComponent />
234
+ * </db.SignedOut>
235
+ *
236
+ */
237
+ SignedOut: React.FC<{
238
+ children: ReactNode;
239
+ }>;
240
+ }
241
+ //# sourceMappingURL=InstantReactAbstractDatabase.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InstantReactAbstractDatabase.d.ts","sourceRoot":"","sources":["../../src/InstantReactAbstractDatabase.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,320 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
11
+ import { txInit, init as core_init, InstantError, } from '@instantdb/core';
12
+ import { useCallback, useEffect, useRef, useState, useSyncExternalStore, } from 'react';
13
+ import { useQueryInternal } from "./useQuery.js";
14
+ import { InstantReactRoom, rooms } from "./InstantReactRoom.js";
15
+ const defaultAuthState = {
16
+ isLoading: true,
17
+ user: undefined,
18
+ error: undefined,
19
+ };
20
+ export default class InstantReactAbstractDatabase {
21
+ constructor(config, versions) {
22
+ this.tx = txInit();
23
+ /**
24
+ * Returns a unique ID for a given `name`. It's stored in local storage,
25
+ * so you will get the same ID across sessions.
26
+ *
27
+ * This is useful for generating IDs that could identify a local device or user.
28
+ *
29
+ * @example
30
+ * const deviceId = await db.getLocalId('device');
31
+ */
32
+ this.getLocalId = (name) => {
33
+ return this.core.getLocalId(name);
34
+ };
35
+ /**
36
+ * A hook that returns a unique ID for a given `name`. localIds are
37
+ * stored in local storage, so you will get the same ID across sessions.
38
+ *
39
+ * Initially returns `null`, and then loads the localId.
40
+ *
41
+ * @example
42
+ * const deviceId = db.useLocalId('device');
43
+ * if (!deviceId) return null; // loading
44
+ * console.log('Device ID:', deviceId)
45
+ */
46
+ this.useLocalId = (name) => {
47
+ const [localId, setLocalId] = useState(null);
48
+ useEffect(() => {
49
+ let mounted = true;
50
+ const f = () => __awaiter(this, void 0, void 0, function* () {
51
+ const id = yield this.getLocalId(name);
52
+ if (!mounted)
53
+ return;
54
+ setLocalId(id);
55
+ });
56
+ f();
57
+ return;
58
+ }, [name]);
59
+ return localId;
60
+ };
61
+ /**
62
+ * Hooks for working with rooms
63
+ *
64
+ * @see https://instantdb.com/docs/presence-and-topics
65
+ *
66
+ * @example
67
+ * const room = db.room('chat', roomId);
68
+ * const { peers } = db.rooms.usePresence(room);
69
+ * const publish = db.rooms.usePublishTopic(room, 'emoji');
70
+ * // ...
71
+ */
72
+ this.rooms = rooms;
73
+ /**
74
+ * Use this to write data! You can create, update, delete, and link objects
75
+ *
76
+ * @see https://instantdb.com/docs/instaml
77
+ *
78
+ * @example
79
+ * // Create a new object in the `goals` namespace
80
+ * const goalId = id();
81
+ * db.transact(db.tx.goals[goalId].update({title: "Get fit"}))
82
+ *
83
+ * // Update the title
84
+ * db.transact(db.tx.goals[goalId].update({title: "Get super fit"}))
85
+ *
86
+ * // Delete it
87
+ * db.transact(db.tx.goals[goalId].delete())
88
+ *
89
+ * // Or create an association:
90
+ * todoId = id();
91
+ * db.transact([
92
+ * db.tx.todos[todoId].update({ title: 'Go on a run' }),
93
+ * db.tx.goals[goalId].link({todos: todoId}),
94
+ * ])
95
+ */
96
+ this.transact = (chunks) => {
97
+ return this.core.transact(chunks);
98
+ };
99
+ /**
100
+ * Use this to query your data!
101
+ *
102
+ * @see https://instantdb.com/docs/instaql
103
+ *
104
+ * @example
105
+ * // listen to all goals
106
+ * const { isLoading, error, data } = db.useQuery({ goals: {} });
107
+ *
108
+ * // goals where the title is "Get Fit"
109
+ * const { isLoading, error, data } = db.useQuery({
110
+ * goals: { $: { where: { title: 'Get Fit' } } },
111
+ * });
112
+ *
113
+ * // all goals, _alongside_ their todos
114
+ * const { isLoading, error, data } = db.useQuery({
115
+ * goals: { todos: {} },
116
+ * });
117
+ *
118
+ * // skip if `user` is not logged in
119
+ * const { isLoading, error, data } = db.useQuery(
120
+ * auth.user ? { goals: {} } : null,
121
+ * );
122
+ */
123
+ this.useQuery = (query, opts) => {
124
+ return useQueryInternal(this.core, query, opts).state;
125
+ };
126
+ /**
127
+ * Listen for the logged in state. This is useful
128
+ * for deciding when to show a login screen.
129
+ *
130
+ * Check out the docs for an example `Login` component too!
131
+ *
132
+ * @see https://instantdb.com/docs/auth
133
+ * @example
134
+ * function App() {
135
+ * const { isLoading, user, error } = db.useAuth()
136
+ * if (isLoading) {
137
+ * return <div>Loading...</div>
138
+ * }
139
+ * if (error) {
140
+ * return <div>Uh oh! {error.message}</div>
141
+ * }
142
+ * if (user) {
143
+ * return <Main user={user} />
144
+ * }
145
+ * return <Login />
146
+ * }
147
+ *
148
+ */
149
+ this.useAuth = () => {
150
+ // We use a ref to store the result of the query.
151
+ // This is becuase `useSyncExternalStore` uses `Object.is`
152
+ // to compare the previous and next state.
153
+ // If we don't use a ref, the state will always be considered different, so
154
+ // the component will always re-render.
155
+ const resultCacheRef = useRef(this.core._reactor._currentUserCached);
156
+ // Similar to `resultCacheRef`, `useSyncExternalStore` will unsubscribe
157
+ // if `subscribe` changes, so we use `useCallback` to memoize the function.
158
+ const subscribe = useCallback((cb) => {
159
+ const unsubscribe = this.core.subscribeAuth((auth) => {
160
+ resultCacheRef.current = Object.assign({ isLoading: false }, auth);
161
+ cb();
162
+ });
163
+ return unsubscribe;
164
+ }, []);
165
+ const state = useSyncExternalStore(subscribe, () => resultCacheRef.current, () => defaultAuthState);
166
+ return state;
167
+ };
168
+ /**
169
+ * Subscribe to the currently logged in user.
170
+ * If the user is not logged in, this hook with throw an Error.
171
+ * You will want to protect any calls of this hook with a
172
+ * <db.SignedIn> component, or your own logic based on db.useAuth()
173
+ *
174
+ * @see https://instantdb.com/docs/auth
175
+ * @throws Error indicating user not signed in
176
+ * @example
177
+ * function UserDisplay() {
178
+ * const user = db.useUser()
179
+ * return <div>Logged in as: {user.email}</div>
180
+ * }
181
+ *
182
+ * <db.SignedIn>
183
+ * <UserDisplay />
184
+ * </db.SignedIn>
185
+ *
186
+ */
187
+ this.useUser = () => {
188
+ const { user } = this.useAuth();
189
+ if (!user) {
190
+ throw new InstantError('useUser must be used within an auth-protected route');
191
+ }
192
+ return user;
193
+ };
194
+ /**
195
+ * Listen for connection status changes to Instant. Use this for things like
196
+ * showing connection state to users
197
+ *
198
+ * @see https://www.instantdb.com/docs/patterns#connection-status
199
+ * @example
200
+ * function App() {
201
+ * const status = db.useConnectionStatus()
202
+ * const connectionState =
203
+ * status === 'connecting' || status === 'opened'
204
+ * ? 'authenticating'
205
+ * : status === 'authenticated'
206
+ * ? 'connected'
207
+ * : status === 'closed'
208
+ * ? 'closed'
209
+ * : status === 'errored'
210
+ * ? 'errored'
211
+ * : 'unexpected state';
212
+ *
213
+ * return <div>Connection state: {connectionState}</div>
214
+ * }
215
+ */
216
+ this.useConnectionStatus = () => {
217
+ const statusRef = useRef(this.core._reactor.status);
218
+ const subscribe = useCallback((cb) => {
219
+ const unsubscribe = this.core.subscribeConnectionStatus((newStatus) => {
220
+ if (newStatus !== statusRef.current) {
221
+ statusRef.current = newStatus;
222
+ cb();
223
+ }
224
+ });
225
+ return unsubscribe;
226
+ }, []);
227
+ const status = useSyncExternalStore(subscribe, () => statusRef.current,
228
+ // For SSR, always return 'connecting' as the initial state
229
+ () => 'connecting');
230
+ return status;
231
+ };
232
+ /**
233
+ * Use this for one-off queries.
234
+ * Returns local data if available, otherwise fetches from the server.
235
+ * Because we want to avoid stale data, this method will throw an error
236
+ * if the user is offline or there is no active connection to the server.
237
+ *
238
+ * @see https://instantdb.com/docs/instaql
239
+ *
240
+ * @example
241
+ *
242
+ * const resp = await db.queryOnce({ goals: {} });
243
+ * console.log(resp.data.goals)
244
+ */
245
+ this.queryOnce = (query, opts) => {
246
+ return this.core.queryOnce(query, opts);
247
+ };
248
+ /**
249
+ * Only render children if the user is signed in.
250
+ * @see https://instantdb.com/docs/auth
251
+ *
252
+ * @example
253
+ * <db.SignedIn>
254
+ * <MyComponent />
255
+ * </db.SignedIn>
256
+ *
257
+ */
258
+ this.SignedIn = ({ children }) => {
259
+ const auth = this.useAuth();
260
+ if (auth.isLoading || auth.error || !auth.user)
261
+ return null;
262
+ return _jsx(_Fragment, { children: children });
263
+ };
264
+ /**
265
+ * Only render children if the user is signed out.
266
+ * @see https://instantdb.com/docs/auth
267
+ *
268
+ * @example
269
+ * <db.SignedOut>
270
+ * <MyComponent />
271
+ * </db.SignedOut>
272
+ *
273
+ */
274
+ this.SignedOut = ({ children }) => {
275
+ const auth = this.useAuth();
276
+ if (auth.isLoading || auth.error || auth.user)
277
+ return null;
278
+ return _jsx(_Fragment, { children: children });
279
+ };
280
+ this.core = core_init(config,
281
+ // @ts-expect-error because TS can't resolve subclass statics
282
+ this.constructor.Storage,
283
+ // @ts-expect-error because TS can't resolve subclass statics
284
+ this.constructor.NetworkListener, versions,
285
+ // @ts-expect-error because TS can't resolve subclass statics
286
+ this.constructor.EventSourceImpl);
287
+ this._core = this.core;
288
+ this.auth = this.core.auth;
289
+ this.storage = this.core.storage;
290
+ }
291
+ /**
292
+ * Obtain a handle to a room, which allows you to listen to topics and presence data
293
+ *
294
+ * If you don't provide a `type` or `id`, Instant will default to `_defaultRoomType` and `_defaultRoomId`
295
+ * as the room type and id, respectively.
296
+ *
297
+ * @see https://instantdb.com/docs/presence-and-topics
298
+ *
299
+ * @example
300
+ * const room = db.room('chat', roomId);
301
+ * const { peers } = db.rooms.usePresence(room);
302
+ */
303
+ room(type = '_defaultRoomType', id = '_defaultRoomId') {
304
+ return new InstantReactRoom(this.core, type, id);
305
+ }
306
+ /**
307
+ * One time query for the logged in state. This is useful
308
+ * for scenarios where you want to know the current auth
309
+ * state without subscribing to changes.
310
+ *
311
+ * @see https://instantdb.com/docs/auth
312
+ * @example
313
+ * const user = await db.getAuth();
314
+ * console.log('logged in as', user.email)
315
+ */
316
+ getAuth() {
317
+ return this.core.getAuth();
318
+ }
319
+ }
320
+ //# sourceMappingURL=InstantReactAbstractDatabase.js.map