@livestore/react 0.0.0-snapshot-2ef046b02334f52613d31dbe06af53487685edc0 → 0.0.0-snapshot-2c861249e50661661613204300b1fc0d902c2e46

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 (63) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/LiveStoreContext.d.ts +10 -6
  3. package/dist/LiveStoreContext.d.ts.map +1 -1
  4. package/dist/LiveStoreContext.js +0 -14
  5. package/dist/LiveStoreContext.js.map +1 -1
  6. package/dist/LiveStoreProvider.d.ts +2 -2
  7. package/dist/LiveStoreProvider.d.ts.map +1 -1
  8. package/dist/LiveStoreProvider.js +5 -1
  9. package/dist/LiveStoreProvider.js.map +1 -1
  10. package/dist/LiveStoreProvider.test.js +6 -5
  11. package/dist/LiveStoreProvider.test.js.map +1 -1
  12. package/dist/__tests__/fixture.d.ts +115 -546
  13. package/dist/__tests__/fixture.d.ts.map +1 -1
  14. package/dist/__tests__/fixture.js +64 -22
  15. package/dist/__tests__/fixture.js.map +1 -1
  16. package/dist/mod.d.ts +4 -4
  17. package/dist/mod.d.ts.map +1 -1
  18. package/dist/mod.js +4 -4
  19. package/dist/mod.js.map +1 -1
  20. package/dist/useClientDocument.d.ts +61 -0
  21. package/dist/useClientDocument.d.ts.map +1 -0
  22. package/dist/useClientDocument.js +73 -0
  23. package/dist/useClientDocument.js.map +1 -0
  24. package/dist/useClientDocument.test.d.ts +2 -0
  25. package/dist/useClientDocument.test.d.ts.map +1 -0
  26. package/dist/{useRow.test.js → useClientDocument.test.js} +38 -43
  27. package/dist/useClientDocument.test.js.map +1 -0
  28. package/dist/useQuery.d.ts +1 -3
  29. package/dist/useQuery.d.ts.map +1 -1
  30. package/dist/useQuery.js +6 -3
  31. package/dist/useQuery.js.map +1 -1
  32. package/dist/useQuery.test.js +16 -17
  33. package/dist/useQuery.test.js.map +1 -1
  34. package/dist/useStore.d.ts +9 -0
  35. package/dist/useStore.d.ts.map +1 -0
  36. package/dist/useStore.js +28 -0
  37. package/dist/useStore.js.map +1 -0
  38. package/package.json +5 -5
  39. package/src/LiveStoreContext.ts +10 -19
  40. package/src/LiveStoreProvider.test.tsx +6 -5
  41. package/src/LiveStoreProvider.tsx +7 -4
  42. package/src/__snapshots__/{useRow.test.tsx.snap → useClientDocument.test.tsx.snap} +50 -30
  43. package/src/__snapshots__/useQuery.test.tsx.snap +8 -8
  44. package/src/__tests__/fixture.tsx +69 -39
  45. package/src/mod.ts +5 -5
  46. package/src/{useRow.test.tsx → useClientDocument.test.tsx} +43 -49
  47. package/src/useClientDocument.ts +149 -0
  48. package/src/useQuery.test.tsx +18 -19
  49. package/src/useQuery.ts +9 -8
  50. package/src/useStore.ts +36 -0
  51. package/dist/useAtom.d.ts +0 -8
  52. package/dist/useAtom.d.ts.map +0 -1
  53. package/dist/useAtom.js +0 -42
  54. package/dist/useAtom.js.map +0 -1
  55. package/dist/useRow.d.ts +0 -64
  56. package/dist/useRow.d.ts.map +0 -1
  57. package/dist/useRow.js +0 -108
  58. package/dist/useRow.js.map +0 -1
  59. package/dist/useRow.test.d.ts +0 -2
  60. package/dist/useRow.test.d.ts.map +0 -1
  61. package/dist/useRow.test.js.map +0 -1
  62. package/src/useAtom.ts +0 -66
  63. package/src/useRow.ts +0 -210
package/src/useRow.ts DELETED
@@ -1,210 +0,0 @@
1
- import type { QueryInfo, RowQuery } from '@livestore/common'
2
- import { SessionIdSymbol } from '@livestore/common'
3
- import type { SqliteDsl } from '@livestore/common/schema'
4
- import { DbSchema } from '@livestore/common/schema'
5
- import type { LiveQuery, LiveQueryDef, Store } from '@livestore/livestore'
6
- import { queryDb } from '@livestore/livestore'
7
- import { shouldNeverHappen } from '@livestore/utils'
8
- import { ReadonlyRecord } from '@livestore/utils/effect'
9
- import React from 'react'
10
-
11
- import { useStore } from './LiveStoreContext.js'
12
- import { useQueryRef } from './useQuery.js'
13
-
14
- export type UseRowResult<TTableDef extends DbSchema.TableDefBase> = [
15
- row: RowQuery.Result<TTableDef>,
16
- setRow: StateSetters<TTableDef>,
17
- query$: LiveQuery<RowQuery.Result<TTableDef>, QueryInfo>,
18
- ]
19
-
20
- /**
21
- * Similar to `React.useState` but returns a tuple of `[row, setRow, query$]` for a given table where ...
22
- *
23
- * - `row` is the current value of the row (fully decoded according to the table schema)
24
- * - `setRow` is a function that can be used to update the row (values will be encoded according to the table schema)
25
- * - `query$` is a `LiveQuery` that e.g. can be used to subscribe to changes to the row
26
- *
27
- * `useRow` only works with for tables with client-only derived mutations,
28
- * i.e. requires the following table options to be set:
29
- * ```ts
30
- * const myTable = DbSchema.table('myTable', {
31
- * // fields ...
32
- * }, { deriveMutations: { clientOnly: true } })
33
- * ```
34
- *
35
- * If the table is a singleton table, `useRow` can be called without an `id` argument. Otherwise, the `id` argument is required.
36
- */
37
- export const useRow: {
38
- // isSingleton: true
39
- <
40
- TTableDef extends DbSchema.TableDef<
41
- DbSchema.DefaultSqliteTableDef,
42
- DbSchema.TableOptions & { isSingleton: true; deriveMutations: { enabled: true; clientOnly: true } }
43
- >,
44
- >(
45
- table: TTableDef,
46
- options?: { store?: Store },
47
- ): UseRowResult<TTableDef>
48
-
49
- // isSingleton: false with requiredInsertColumnNames: 'id'
50
- <
51
- TTableDef extends DbSchema.TableDef<
52
- DbSchema.DefaultSqliteTableDef,
53
- DbSchema.TableOptions & {
54
- isSingleton: false
55
- requiredInsertColumnNames: 'id'
56
- deriveMutations: { enabled: true; clientOnly: true }
57
- }
58
- >,
59
- >(
60
- table: TTableDef,
61
- // TODO adjust so it works with arbitrary primary keys or unique constraints
62
- id: string | SessionIdSymbol | number,
63
- options?: Partial<RowQuery.RequiredColumnsOptions<TTableDef>> & { store?: Store },
64
- ): UseRowResult<TTableDef>
65
-
66
- // isSingleton: false
67
- <
68
- TTableDef extends DbSchema.TableDef<
69
- DbSchema.DefaultSqliteTableDef,
70
- DbSchema.TableOptions & { isSingleton: false; deriveMutations: { enabled: true; clientOnly: true } }
71
- >,
72
- >(
73
- table: TTableDef,
74
- // TODO adjust so it works with arbitrary primary keys or unique constraints
75
- id: string | SessionIdSymbol | number,
76
- options: RowQuery.RequiredColumnsOptions<TTableDef> & { store?: Store },
77
- ): UseRowResult<TTableDef>
78
- } = <
79
- TTableDef extends DbSchema.TableDef<
80
- DbSchema.DefaultSqliteTableDefConstrained,
81
- DbSchema.TableOptions & { deriveMutations: { enabled: true; clientOnly: true } }
82
- >,
83
- >(
84
- table: TTableDef,
85
- idOrOptions?: string | SessionIdSymbol | number | { store?: Store },
86
- options_?: Partial<RowQuery.RequiredColumnsOptions<TTableDef>> & { store?: Store },
87
- ): UseRowResult<TTableDef> => {
88
- const sqliteTableDef = table.sqliteDef
89
- const id =
90
- typeof idOrOptions === 'string' || idOrOptions === SessionIdSymbol || typeof idOrOptions === 'number'
91
- ? idOrOptions
92
- : undefined
93
- const options: (Partial<RowQuery.RequiredColumnsOptions<TTableDef>> & { store?: Store }) | undefined =
94
- typeof idOrOptions === 'string' || idOrOptions === SessionIdSymbol || typeof idOrOptions === 'number'
95
- ? options_
96
- : idOrOptions
97
- const { insertValues } = options ?? {}
98
-
99
- type TComponentState = SqliteDsl.FromColumns.RowDecoded<TTableDef['sqliteDef']['columns']>
100
-
101
- React.useMemo(() => validateTableOptions(table), [table])
102
-
103
- const tableName = table.sqliteDef.name
104
-
105
- const { store } = useStore({ store: options?.store })
106
-
107
- if (
108
- store.schema.tables.has(table.sqliteDef.name) === false &&
109
- table.sqliteDef.name.startsWith('__livestore') === false
110
- ) {
111
- shouldNeverHappen(`Table "${table.sqliteDef.name}" not found in schema`)
112
- }
113
-
114
- // console.debug('useRow', tableName, id)
115
-
116
- const idVal = id === SessionIdSymbol ? 'session' : id
117
- const rowQuery = table.query.row as any
118
-
119
- type QueryDef = LiveQueryDef<RowQuery.Result<TTableDef>, QueryInfo.Row>
120
- const queryDef: QueryDef = React.useMemo(
121
- () =>
122
- DbSchema.tableIsSingleton(table)
123
- ? queryDb(rowQuery(), {})
124
- : queryDb(rowQuery(id!, { insertValues: insertValues! }), { deps: idVal! }),
125
- [id, insertValues, rowQuery, table, idVal],
126
- )
127
-
128
- const queryRef = useQueryRef(queryDef, {
129
- otelSpanName: `LiveStore:useRow:${tableName}${idVal === undefined ? '' : `:${idVal}`}`,
130
- store: options?.store,
131
- })
132
-
133
- const setState = React.useMemo<StateSetters<TTableDef>>(() => {
134
- if (table.options.isSingleColumn) {
135
- return (newValueOrFn: RowQuery.Result<TTableDef>) => {
136
- const newValue = typeof newValueOrFn === 'function' ? newValueOrFn(queryRef.valueRef.current) : newValueOrFn
137
- if (queryRef.valueRef.current === newValue) return
138
-
139
- // NOTE we need to account for the short-hand syntax for single-column+singleton tables
140
- if (table.options.isSingleton) {
141
- store.commit(table.update(newValue))
142
- } else {
143
- store.commit(table.update({ where: { id }, values: { value: newValue } }))
144
- }
145
- // store.commit(updateMutationForQueryInfo(query$.queryInfo!, { value: newValue }))
146
- }
147
- } else {
148
- const setState = // TODO: do we have a better type for the values that can go in SQLite?
149
- ReadonlyRecord.map(sqliteTableDef.columns, (column, columnName) => (newValueOrFn: any) => {
150
- const newValue =
151
- // @ts-expect-error TODO fix typing
152
- typeof newValueOrFn === 'function' ? newValueOrFn(queryRef.valueRef.current[columnName]) : newValueOrFn
153
-
154
- // Don't update the state if it's the same as the value already seen in the component
155
- // @ts-expect-error TODO fix typing
156
- if (queryRef.valueRef.current[columnName] === newValue) return
157
-
158
- store.commit(table.update({ where: { id: id ?? 'singleton' }, values: { [columnName]: newValue } }))
159
- // store.commit(updateMutationForQueryInfo(query$.queryInfo!, { [columnName]: newValue }))
160
- })
161
-
162
- setState.setMany = (columnValuesOrFn: Partial<TComponentState>) => {
163
- const columnValues =
164
- // @ts-expect-error TODO fix typing
165
- typeof columnValuesOrFn === 'function' ? columnValuesOrFn(queryRef.valueRef.current) : columnValuesOrFn
166
-
167
- // TODO use hashing instead
168
- // Don't update the state if it's the same as the value already seen in the component
169
- if (
170
- // @ts-expect-error TODO fix typing
171
- Object.entries(columnValues).every(([columnName, value]) => queryRef.valueRef.current[columnName] === value)
172
- ) {
173
- return
174
- }
175
-
176
- store.commit(table.update({ where: { id: id ?? 'singleton' }, values: columnValues }))
177
- // store.commit(updateMutationForQueryInfo(query$.queryInfo!, columnValues))
178
- }
179
-
180
- return setState as any
181
- }
182
- }, [id, queryRef.valueRef, sqliteTableDef.columns, store, table])
183
-
184
- return [queryRef.valueRef.current, setState, queryRef.queryRcRef.value]
185
- }
186
-
187
- export type Dispatch<A> = (action: A) => void
188
- export type SetStateAction<S> = S | ((previousValue: S) => S)
189
-
190
- export type StateSetters<TTableDef extends DbSchema.TableDefBase> = TTableDef['options']['isSingleColumn'] extends true
191
- ? Dispatch<SetStateAction<RowQuery.Result<TTableDef>>>
192
- : {
193
- [K in keyof RowQuery.Result<TTableDef>]: Dispatch<SetStateAction<RowQuery.Result<TTableDef>[K]>>
194
- } & {
195
- setMany: Dispatch<SetStateAction<Partial<RowQuery.Result<TTableDef>>>>
196
- }
197
-
198
- const validateTableOptions = (table: DbSchema.TableDef<any, any>) => {
199
- if (table.options.deriveMutations.clientOnly === false) {
200
- return shouldNeverHappen(
201
- `useRow called on table "${table.sqliteDef.name}" which does not have 'deriveMutations: { clientOnly: true }' set`,
202
- )
203
- }
204
-
205
- if (table.options.deriveMutations.enabled === false) {
206
- return shouldNeverHappen(
207
- `useRow called on table "${table.sqliteDef.name}" which does not have 'deriveMutations: { clientOnly: true }' set`,
208
- )
209
- }
210
- }