@livestore/livestore 0.0.25 → 0.0.27
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.
- package/dist/.tsbuildinfo +1 -1
- package/dist/QueryCache.d.ts +1 -1
- package/dist/QueryCache.d.ts.map +1 -1
- package/dist/QueryCache.js +50 -60
- package/dist/QueryCache.js.map +1 -1
- package/dist/__tests__/react/fixture.d.ts +21 -6
- package/dist/__tests__/react/fixture.d.ts.map +1 -1
- package/dist/__tests__/react/fixture.js +13 -14
- package/dist/__tests__/react/fixture.js.map +1 -1
- package/dist/__tests__/react/useQuery.test.js +5 -5
- package/dist/__tests__/react/useQuery.test.js.map +1 -1
- package/dist/__tests__/react/useRow.test.d.ts +2 -0
- package/dist/__tests__/react/useRow.test.d.ts.map +1 -0
- package/dist/__tests__/react/{useComponentState.test.js → useRow.test.js} +21 -26
- package/dist/__tests__/react/useRow.test.js.map +1 -0
- package/dist/__tests__/react/utils/stack-info.test.js +32 -0
- package/dist/__tests__/react/utils/stack-info.test.js.map +1 -1
- package/dist/__tests__/reactiveQueries/sql.test.js +4 -4
- package/dist/__tests__/reactiveQueries/sql.test.js.map +1 -1
- package/dist/effect/LiveStore.d.ts +3 -3
- package/dist/effect/LiveStore.d.ts.map +1 -1
- package/dist/effect/LiveStore.js +1 -1
- package/dist/effect/LiveStore.js.map +1 -1
- package/dist/global-state.d.ts +19 -0
- package/dist/global-state.d.ts.map +1 -0
- package/dist/global-state.js +20 -0
- package/dist/global-state.js.map +1 -0
- package/dist/inMemoryDatabase.d.ts +3 -3
- package/dist/inMemoryDatabase.d.ts.map +1 -1
- package/dist/inMemoryDatabase.js +13 -7
- package/dist/inMemoryDatabase.js.map +1 -1
- package/dist/index.d.ts +5 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -5
- package/dist/index.js.map +1 -1
- package/dist/migrations.d.ts +4 -4
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +34 -28
- package/dist/migrations.js.map +1 -1
- package/dist/react/LiveStoreContext.js.map +1 -1
- package/dist/react/LiveStoreProvider.d.ts +2 -2
- package/dist/react/LiveStoreProvider.d.ts.map +1 -1
- package/dist/react/LiveStoreProvider.js.map +1 -1
- package/dist/react/index.d.ts +1 -2
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +1 -1
- package/dist/react/index.js.map +1 -1
- package/dist/react/useQuery.d.ts +3 -0
- package/dist/react/useQuery.d.ts.map +1 -1
- package/dist/react/useQuery.js +5 -4
- package/dist/react/useQuery.js.map +1 -1
- package/dist/react/useRow.d.ts +33 -0
- package/dist/react/useRow.d.ts.map +1 -0
- package/dist/react/useRow.js +136 -0
- package/dist/react/useRow.js.map +1 -0
- package/dist/react/useTemporaryQuery.d.ts +2 -0
- package/dist/react/useTemporaryQuery.d.ts.map +1 -1
- package/dist/react/useTemporaryQuery.js +28 -11
- package/dist/react/useTemporaryQuery.js.map +1 -1
- package/dist/react/utils/stack-info.d.ts.map +1 -1
- package/dist/react/utils/stack-info.js +3 -2
- package/dist/react/utils/stack-info.js.map +1 -1
- package/dist/react/utils/useStateRefWithReactiveInput.js.map +1 -1
- package/dist/reactive.d.ts +1 -1
- package/dist/reactive.d.ts.map +1 -1
- package/dist/reactive.js +47 -44
- package/dist/reactive.js.map +1 -1
- package/dist/reactiveQueries/base-class.d.ts +6 -2
- package/dist/reactiveQueries/base-class.d.ts.map +1 -1
- package/dist/reactiveQueries/base-class.js +10 -12
- package/dist/reactiveQueries/base-class.js.map +1 -1
- package/dist/reactiveQueries/graphql.d.ts +2 -2
- package/dist/reactiveQueries/graphql.d.ts.map +1 -1
- package/dist/reactiveQueries/graphql.js +56 -50
- package/dist/reactiveQueries/graphql.js.map +1 -1
- package/dist/reactiveQueries/js.d.ts +1 -2
- package/dist/reactiveQueries/js.d.ts.map +1 -1
- package/dist/reactiveQueries/js.js +25 -15
- package/dist/reactiveQueries/js.js.map +1 -1
- package/dist/reactiveQueries/sql.d.ts +3 -3
- package/dist/reactiveQueries/sql.d.ts.map +1 -1
- package/dist/reactiveQueries/sql.js +39 -34
- package/dist/reactiveQueries/sql.js.map +1 -1
- package/dist/row-query.d.ts +21 -0
- package/dist/row-query.d.ts.map +1 -0
- package/dist/row-query.js +77 -0
- package/dist/row-query.js.map +1 -0
- package/dist/schema/action.d.ts +30 -0
- package/dist/schema/action.d.ts.map +1 -0
- package/dist/schema/action.js +3 -0
- package/dist/schema/action.js.map +1 -0
- package/dist/schema/index.d.ts +28 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/index.js +26 -0
- package/dist/schema/index.js.map +1 -0
- package/dist/schema/system-tables.d.ts +24 -0
- package/dist/schema/system-tables.d.ts.map +1 -0
- package/dist/schema/system-tables.js +11 -0
- package/dist/schema/system-tables.js.map +1 -0
- package/dist/schema/table-def.d.ts +161 -0
- package/dist/schema/table-def.d.ts.map +1 -0
- package/dist/schema/table-def.js +53 -0
- package/dist/schema/table-def.js.map +1 -0
- package/dist/storage/in-memory/index.d.ts +1 -1
- package/dist/storage/in-memory/index.d.ts.map +1 -1
- package/dist/storage/in-memory/index.js +6 -7
- package/dist/storage/in-memory/index.js.map +1 -1
- package/dist/storage/index.d.ts +1 -1
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/tauri/index.d.ts +1 -1
- package/dist/storage/tauri/index.d.ts.map +1 -1
- package/dist/storage/tauri/index.js +25 -23
- package/dist/storage/tauri/index.js.map +1 -1
- package/dist/storage/utils/idb.js +3 -1
- package/dist/storage/utils/idb.js.map +1 -1
- package/dist/storage/web-worker/index.d.ts +1 -1
- package/dist/storage/web-worker/index.d.ts.map +1 -1
- package/dist/storage/web-worker/index.js +38 -34
- package/dist/storage/web-worker/index.js.map +1 -1
- package/dist/storage/web-worker/worker.d.ts +1 -1
- package/dist/storage/web-worker/worker.d.ts.map +1 -1
- package/dist/storage/web-worker/worker.js +1 -1
- package/dist/storage/web-worker/worker.js.map +1 -1
- package/dist/store.d.ts +9 -10
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +282 -265
- package/dist/store.js.map +1 -1
- package/dist/utils/bounded-collections.d.ts.map +1 -0
- package/dist/utils/bounded-collections.js +90 -0
- package/dist/utils/bounded-collections.js.map +1 -0
- package/dist/utils/otel.d.ts.map +1 -0
- package/dist/{otel.js → utils/otel.js} +1 -1
- package/dist/utils/otel.js.map +1 -0
- package/dist/utils/util.d.ts.map +1 -0
- package/dist/utils/util.js.map +1 -0
- package/package.json +12 -12
- package/src/QueryCache.ts +2 -2
- package/src/__tests__/react/fixture.tsx +15 -15
- package/src/__tests__/react/useQuery.test.tsx +5 -5
- package/src/__tests__/react/{useComponentState.test.tsx → useRow.test.tsx} +27 -28
- package/src/__tests__/react/utils/stack-info.test.ts +34 -0
- package/src/__tests__/reactiveQueries/sql.test.ts +4 -4
- package/src/effect/LiveStore.ts +6 -6
- package/src/global-state.ts +26 -0
- package/src/inMemoryDatabase.ts +6 -4
- package/src/index.ts +18 -17
- package/src/migrations.ts +41 -35
- package/src/react/LiveStoreProvider.tsx +2 -2
- package/src/react/index.ts +7 -9
- package/src/react/useQuery.ts +10 -4
- package/src/react/useRow.ts +221 -0
- package/src/react/useTemporaryQuery.ts +43 -11
- package/src/react/utils/stack-info.ts +4 -2
- package/src/reactive.ts +1 -1
- package/src/reactiveQueries/base-class.ts +8 -2
- package/src/reactiveQueries/graphql.ts +4 -3
- package/src/reactiveQueries/js.ts +3 -4
- package/src/reactiveQueries/sql.ts +6 -6
- package/src/row-query.ts +142 -0
- package/src/schema/action.ts +41 -0
- package/src/schema/index.ts +63 -0
- package/src/schema/system-tables.ts +21 -0
- package/src/schema/table-def.ts +199 -0
- package/src/storage/in-memory/index.ts +1 -1
- package/src/storage/index.ts +2 -1
- package/src/storage/tauri/index.ts +2 -2
- package/src/storage/web-worker/index.ts +1 -1
- package/src/storage/web-worker/worker.ts +2 -2
- package/src/store.ts +39 -27
- package/dist/__tests__/react/useComponentState.test.d.ts +0 -2
- package/dist/__tests__/react/useComponentState.test.d.ts.map +0 -1
- package/dist/__tests__/react/useComponentState.test.js.map +0 -1
- package/dist/bounded-collections.d.ts.map +0 -1
- package/dist/bounded-collections.js +0 -103
- package/dist/bounded-collections.js.map +0 -1
- package/dist/componentKey.d.ts +0 -20
- package/dist/componentKey.d.ts.map +0 -1
- package/dist/componentKey.js +0 -3
- package/dist/componentKey.js.map +0 -1
- package/dist/otel.d.ts.map +0 -1
- package/dist/otel.js.map +0 -1
- package/dist/react/useComponentState.d.ts +0 -50
- package/dist/react/useComponentState.d.ts.map +0 -1
- package/dist/react/useComponentState.js +0 -226
- package/dist/react/useComponentState.js.map +0 -1
- package/dist/reactiveQueries/graph.d.ts +0 -10
- package/dist/reactiveQueries/graph.d.ts.map +0 -1
- package/dist/reactiveQueries/graph.js +0 -6
- package/dist/reactiveQueries/graph.js.map +0 -1
- package/dist/schema.d.ts +0 -81
- package/dist/schema.d.ts.map +0 -1
- package/dist/schema.js +0 -46
- package/dist/schema.js.map +0 -1
- package/dist/util.d.ts.map +0 -1
- package/dist/util.js.map +0 -1
- package/src/componentKey.ts +0 -9
- package/src/react/useComponentState.ts +0 -385
- package/src/reactiveQueries/graph.ts +0 -15
- package/src/schema.ts +0 -143
- /package/dist/{bounded-collections.d.ts → utils/bounded-collections.d.ts} +0 -0
- /package/dist/{otel.d.ts → utils/otel.d.ts} +0 -0
- /package/dist/{util.d.ts → utils/util.d.ts} +0 -0
- /package/dist/{util.js → utils/util.js} +0 -0
- /package/src/{bounded-collections.ts → utils/bounded-collections.ts} +0 -0
- /package/src/{otel.ts → utils/otel.ts} +0 -0
- /package/src/{util.ts → utils/util.ts} +0 -0
package/src/store.ts
CHANGED
|
@@ -5,24 +5,21 @@ import type { GraphQLSchema } from 'graphql'
|
|
|
5
5
|
import type * as Sqlite from 'sqlite-esm'
|
|
6
6
|
import { v4 as uuid } from 'uuid'
|
|
7
7
|
|
|
8
|
-
import type { ComponentKey } from './componentKey.js'
|
|
9
|
-
import { tableNameForComponentKey } from './componentKey.js'
|
|
10
8
|
import type { LiveStoreEvent } from './events.js'
|
|
9
|
+
import { dbGraph, dynamicallyRegisteredTables } from './global-state.js'
|
|
11
10
|
import { InMemoryDatabase } from './inMemoryDatabase.js'
|
|
12
11
|
import { migrateDb } from './migrations.js'
|
|
13
|
-
import { getDurationMsFromSpan } from './otel.js'
|
|
14
12
|
import type { StackInfo } from './react/utils/stack-info.js'
|
|
15
13
|
import type { DebugRefreshReasonBase, ReactiveGraph, Ref } from './reactive.js'
|
|
16
|
-
import type { ILiveStoreQuery } from './reactiveQueries/base-class.js'
|
|
17
|
-
import { type DbContext, dbGraph } from './reactiveQueries/graph.js'
|
|
14
|
+
import type { DbContext, ILiveStoreQuery } from './reactiveQueries/base-class.js'
|
|
18
15
|
import type { LiveStoreGraphQLQuery } from './reactiveQueries/graphql.js'
|
|
19
16
|
import type { LiveStoreJSQuery } from './reactiveQueries/js.js'
|
|
20
17
|
import type { LiveStoreSQLQuery } from './reactiveQueries/sql.js'
|
|
21
|
-
import type { ActionDefinition, GetActionArgs,
|
|
22
|
-
import { componentStateTables } from './schema.js'
|
|
18
|
+
import type { ActionDefinition, GetActionArgs, LiveStoreSchema, SQLWriteStatement } from './schema/index.js'
|
|
23
19
|
import type { Storage, StorageInit } from './storage/index.js'
|
|
24
|
-
import
|
|
25
|
-
import {
|
|
20
|
+
import { getDurationMsFromSpan } from './utils/otel.js'
|
|
21
|
+
import type { ParamsObject } from './utils/util.js'
|
|
22
|
+
import { isPromise, prepareBindValues, sql } from './utils/util.js'
|
|
26
23
|
|
|
27
24
|
export type LiveStoreQuery<TResult extends Record<string, any> = any> =
|
|
28
25
|
| LiveStoreSQLQuery<TResult>
|
|
@@ -52,7 +49,7 @@ export type StoreOptions<TGraphQLContext extends BaseGraphQLContext> = {
|
|
|
52
49
|
db: InMemoryDatabase
|
|
53
50
|
/** A `Proxy`d version of `db` except that it also mirrors `execute` calls to the storage */
|
|
54
51
|
dbProxy: InMemoryDatabase
|
|
55
|
-
schema:
|
|
52
|
+
schema: LiveStoreSchema
|
|
56
53
|
storage?: Storage
|
|
57
54
|
graphQLOptions?: GraphQLOptions<TGraphQLContext>
|
|
58
55
|
otelTracer: otel.Tracer
|
|
@@ -69,7 +66,7 @@ export type RefreshReason =
|
|
|
69
66
|
event: Omit<LiveStoreEvent, 'id'>
|
|
70
67
|
|
|
71
68
|
/** The tables that were written to by the event */
|
|
72
|
-
writeTables: string
|
|
69
|
+
writeTables: ReadonlyArray<string>
|
|
73
70
|
}
|
|
74
71
|
| {
|
|
75
72
|
_tag: 'applyEvents'
|
|
@@ -79,7 +76,7 @@ export type RefreshReason =
|
|
|
79
76
|
events: Omit<LiveStoreEvent, 'id'>[]
|
|
80
77
|
|
|
81
78
|
/** The tables that were written to by the event */
|
|
82
|
-
writeTables: string
|
|
79
|
+
writeTables: ReadonlyArray<string>
|
|
83
80
|
}
|
|
84
81
|
| {
|
|
85
82
|
_tag: 'react'
|
|
@@ -107,7 +104,7 @@ export class Store<TGraphQLContext extends BaseGraphQLContext = BaseGraphQLConte
|
|
|
107
104
|
inMemoryDB: InMemoryDatabase
|
|
108
105
|
// TODO refactor
|
|
109
106
|
_proxyDb: InMemoryDatabase
|
|
110
|
-
schema:
|
|
107
|
+
schema: LiveStoreSchema
|
|
111
108
|
graphQLSchema?: GraphQLSchema
|
|
112
109
|
graphQLContext?: TGraphQLContext
|
|
113
110
|
otel: StoreOtel
|
|
@@ -154,10 +151,11 @@ export class Store<TGraphQLContext extends BaseGraphQLContext = BaseGraphQLConte
|
|
|
154
151
|
queriesSpanContext: otelQueriesSpanContext,
|
|
155
152
|
}
|
|
156
153
|
|
|
154
|
+
// Need a set here since `schema.tables` might contain duplicates and some componentStateTables
|
|
157
155
|
const allTableNames = new Set([
|
|
158
|
-
...
|
|
159
|
-
|
|
160
|
-
...
|
|
156
|
+
...this.schema.tables.keys(),
|
|
157
|
+
// TODO activate dynamic tables
|
|
158
|
+
...Array.from(dynamicallyRegisteredTables.values()).map((_) => _.schema.name),
|
|
161
159
|
])
|
|
162
160
|
for (const tableName of allTableNames) {
|
|
163
161
|
this.tableRefs[tableName] = this.graph.makeRef(null, {
|
|
@@ -199,7 +197,7 @@ export class Store<TGraphQLContext extends BaseGraphQLContext = BaseGraphQLConte
|
|
|
199
197
|
): (() => void) =>
|
|
200
198
|
this.otel.tracer.startActiveSpan(
|
|
201
199
|
`LiveStore.subscribe`,
|
|
202
|
-
{ attributes: { label: options?.label } },
|
|
200
|
+
{ attributes: { label: options?.label, queryLabel: query.label } },
|
|
203
201
|
options?.otelContext ?? this.otel.queriesSpanContext,
|
|
204
202
|
(span) => {
|
|
205
203
|
const otelContext = otel.trace.setSpan(otel.context.active(), span)
|
|
@@ -417,7 +415,7 @@ export class Store<TGraphQLContext extends BaseGraphQLContext = BaseGraphQLConte
|
|
|
417
415
|
eventType: string,
|
|
418
416
|
args: any = {},
|
|
419
417
|
otelContext: otel.Context,
|
|
420
|
-
): { writeTables: string
|
|
418
|
+
): { writeTables: ReadonlyArray<string>; durationMs: number } => {
|
|
421
419
|
return this.otel.tracer.startActiveSpan(
|
|
422
420
|
'LiveStore:applyEventWithoutRefresh',
|
|
423
421
|
{
|
|
@@ -434,21 +432,30 @@ export class Store<TGraphQLContext extends BaseGraphQLContext = BaseGraphQLConte
|
|
|
434
432
|
...this.schema.actions,
|
|
435
433
|
|
|
436
434
|
// Special LiveStore:defined actions
|
|
437
|
-
|
|
438
|
-
statement: ({
|
|
439
|
-
|
|
435
|
+
'livestore.UpdateComponentState': {
|
|
436
|
+
statement: ({
|
|
437
|
+
id,
|
|
438
|
+
columnNames,
|
|
439
|
+
tableName,
|
|
440
|
+
}: {
|
|
441
|
+
id?: string
|
|
442
|
+
columnNames: ReadonlyArray<string>
|
|
443
|
+
tableName: string
|
|
444
|
+
}) => {
|
|
445
|
+
const whereClause = id === undefined ? '' : `where id = '${id}'`
|
|
440
446
|
const updateClause = columnNames.map((columnName) => `${columnName} = $${columnName}`).join(', ')
|
|
441
|
-
const stmt = sql`update ${
|
|
447
|
+
const stmt = sql`update ${tableName} set ${updateClause} ${whereClause}`
|
|
442
448
|
|
|
443
449
|
return {
|
|
444
450
|
sql: stmt,
|
|
445
|
-
writeTables: [
|
|
451
|
+
writeTables: [tableName],
|
|
446
452
|
}
|
|
447
453
|
},
|
|
454
|
+
prepareBindValues: ({ bindValues }) => bindValues ?? {},
|
|
448
455
|
},
|
|
449
456
|
|
|
450
|
-
RawSql: {
|
|
451
|
-
statement: ({ sql, writeTables }: { sql: string; writeTables: string
|
|
457
|
+
'livestore.RawSql': {
|
|
458
|
+
statement: ({ sql, writeTables }: { sql: string; writeTables: ReadonlyArray<string> }) => ({
|
|
452
459
|
sql,
|
|
453
460
|
writeTables,
|
|
454
461
|
argsAlreadyBound: false,
|
|
@@ -500,7 +507,12 @@ export class Store<TGraphQLContext extends BaseGraphQLContext = BaseGraphQLConte
|
|
|
500
507
|
* This should only be used for framework-internal purposes;
|
|
501
508
|
* all app writes should go through applyEvent.
|
|
502
509
|
*/
|
|
503
|
-
execute = (
|
|
510
|
+
execute = (
|
|
511
|
+
query: string,
|
|
512
|
+
params: ParamsObject = {},
|
|
513
|
+
writeTables?: ReadonlyArray<string>,
|
|
514
|
+
otelContext?: otel.Context,
|
|
515
|
+
) => {
|
|
504
516
|
this.inMemoryDB.execute(query, prepareBindValues(params, query), writeTables, { otelContext })
|
|
505
517
|
|
|
506
518
|
if (this.storage !== undefined) {
|
|
@@ -520,7 +532,7 @@ export const createStore = async <TGraphQLContext extends BaseGraphQLContext>({
|
|
|
520
532
|
boot,
|
|
521
533
|
sqlite3,
|
|
522
534
|
}: {
|
|
523
|
-
schema:
|
|
535
|
+
schema: LiveStoreSchema
|
|
524
536
|
loadStorage: () => StorageInit | Promise<StorageInit>
|
|
525
537
|
graphQLOptions?: GraphQLOptions<TGraphQLContext>
|
|
526
538
|
otelTracer?: otel.Tracer
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useComponentState.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/react/useComponentState.test.tsx"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useComponentState.test.js","sourceRoot":"","sources":["../../../src/__tests__/react/useComponentState.test.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"bounded-collections.d.ts","sourceRoot":"","sources":["../src/bounded-collections.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,OAAO,OAAO,QAAQ,CAAC,CAAC,EAAE,CAAC;;gBAIpB,SAAS,EAAE,MAAM;IAI7B,OAAO,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;IAEvC,GAAG,QAAS,CAAC,SAAS,CAAC,UAUtB;IAED,GAAG,QAAS,CAAC,KAAG,CAAC,GAAG,SAAS,CAE5B;IAED,MAAM,QAAS,CAAC,UAEf;IAED,IAAI,4BAEH;CACF;AAED,qBAAa,QAAQ,CAAC,CAAC;;gBAGT,SAAS,EAAE,MAAM;IAW7B,OAAO,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;IAEvC,GAAG,MAAO,CAAC,UAET;IAEF,CAAC,MAAM,CAAC,QAAQ,CAAC,4BAEhB;CACF;AAED,qBAAa,UAAU,CAAC,CAAC;;gBAIX,SAAS,EAAE,MAAM;IAI7B,OAAO,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;IAEvC,IAAI,MAAO,CAAC,UAQX;IAED,GAAG,UAAW,MAAM,KAAG,CAAC,GAAG,SAAS,CAEnC;IAED,MAAM,UAAW,MAAM,UAEtB;IAED,IAAI,MAAM,WAET;IAED,CAAC,MAAM,CAAC,QAAQ,CAAC,4BAEhB;IAED,GAAG,cAAe,CAAC,eAElB;IAED,KAAK,aAEJ;IAED,IAAI,aAAa,CAAC,KAAK,CAAC,KAAK,MAAM,sBAElC;CACF"}
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
2
|
-
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
3
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
4
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
5
|
-
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
6
|
-
};
|
|
7
|
-
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
8
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
9
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
|
-
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
|
-
};
|
|
12
|
-
var _BoundMap_map, _BoundMap_sizeLimit, _BoundSet_map, _BoundSet_onEvict, _a, _BoundArray_array, _BoundArray_sizeLimit, _b;
|
|
13
|
-
/**
|
|
14
|
-
* Creates a map that has a fixed number of entries.
|
|
15
|
-
* Once hitting the bound, earliest insertions are removed
|
|
16
|
-
*/
|
|
17
|
-
class BoundMap {
|
|
18
|
-
constructor(sizeLimit) {
|
|
19
|
-
_BoundMap_map.set(this, new Map());
|
|
20
|
-
_BoundMap_sizeLimit.set(this, void 0);
|
|
21
|
-
this.set = (key, value) => {
|
|
22
|
-
__classPrivateFieldGet(this, _BoundMap_map, "f").set(key, value);
|
|
23
|
-
// console.log(this.#map.size, this.#sizeLimit);
|
|
24
|
-
if (__classPrivateFieldGet(this, _BoundMap_map, "f").size > __classPrivateFieldGet(this, _BoundMap_sizeLimit, "f")) {
|
|
25
|
-
const firstKey = __classPrivateFieldGet(this, _BoundMap_map, "f").keys().next().value;
|
|
26
|
-
__classPrivateFieldGet(this, _BoundMap_map, "f").delete(firstKey);
|
|
27
|
-
if (this.onEvict) {
|
|
28
|
-
this.onEvict(firstKey);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
};
|
|
32
|
-
this.get = (key) => {
|
|
33
|
-
return __classPrivateFieldGet(this, _BoundMap_map, "f").get(key);
|
|
34
|
-
};
|
|
35
|
-
this.delete = (key) => {
|
|
36
|
-
__classPrivateFieldGet(this, _BoundMap_map, "f").delete(key);
|
|
37
|
-
};
|
|
38
|
-
this.keys = () => {
|
|
39
|
-
return __classPrivateFieldGet(this, _BoundMap_map, "f").keys();
|
|
40
|
-
};
|
|
41
|
-
__classPrivateFieldSet(this, _BoundMap_sizeLimit, sizeLimit, "f");
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
_BoundMap_map = new WeakMap(), _BoundMap_sizeLimit = new WeakMap();
|
|
45
|
-
export default BoundMap;
|
|
46
|
-
export class BoundSet {
|
|
47
|
-
constructor(sizeLimit) {
|
|
48
|
-
_BoundSet_map.set(this, void 0);
|
|
49
|
-
_BoundSet_onEvict.set(this, (v) => {
|
|
50
|
-
if (this.onEvict) {
|
|
51
|
-
this.onEvict(v);
|
|
52
|
-
}
|
|
53
|
-
});
|
|
54
|
-
this.add = (v) => {
|
|
55
|
-
__classPrivateFieldGet(this, _BoundSet_map, "f").set(v, v);
|
|
56
|
-
};
|
|
57
|
-
this[_a] = () => {
|
|
58
|
-
return __classPrivateFieldGet(this, _BoundSet_map, "f").keys();
|
|
59
|
-
};
|
|
60
|
-
__classPrivateFieldSet(this, _BoundSet_map, new BoundMap(sizeLimit), "f");
|
|
61
|
-
__classPrivateFieldGet(this, _BoundSet_map, "f").onEvict = __classPrivateFieldGet(this, _BoundSet_onEvict, "f");
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
_BoundSet_map = new WeakMap(), _BoundSet_onEvict = new WeakMap(), _a = Symbol.iterator;
|
|
65
|
-
export class BoundArray {
|
|
66
|
-
constructor(sizeLimit) {
|
|
67
|
-
_BoundArray_array.set(this, []);
|
|
68
|
-
_BoundArray_sizeLimit.set(this, void 0);
|
|
69
|
-
this.push = (v) => {
|
|
70
|
-
__classPrivateFieldGet(this, _BoundArray_array, "f").push(v);
|
|
71
|
-
if (__classPrivateFieldGet(this, _BoundArray_array, "f").length > __classPrivateFieldGet(this, _BoundArray_sizeLimit, "f")) {
|
|
72
|
-
const first = __classPrivateFieldGet(this, _BoundArray_array, "f").shift();
|
|
73
|
-
if (first && this.onEvict) {
|
|
74
|
-
this.onEvict(first);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
};
|
|
78
|
-
this.get = (index) => {
|
|
79
|
-
return __classPrivateFieldGet(this, _BoundArray_array, "f")[index];
|
|
80
|
-
};
|
|
81
|
-
this.delete = (index) => {
|
|
82
|
-
__classPrivateFieldGet(this, _BoundArray_array, "f").splice(index, 1);
|
|
83
|
-
};
|
|
84
|
-
this[_b] = () => {
|
|
85
|
-
return __classPrivateFieldGet(this, _BoundArray_array, "f")[Symbol.iterator]();
|
|
86
|
-
};
|
|
87
|
-
this.map = (fn) => {
|
|
88
|
-
return __classPrivateFieldGet(this, _BoundArray_array, "f").map(fn);
|
|
89
|
-
};
|
|
90
|
-
this.clear = () => {
|
|
91
|
-
__classPrivateFieldSet(this, _BoundArray_array, [], "f");
|
|
92
|
-
};
|
|
93
|
-
this.sort = (fn) => {
|
|
94
|
-
return __classPrivateFieldGet(this, _BoundArray_array, "f").sort(fn);
|
|
95
|
-
};
|
|
96
|
-
__classPrivateFieldSet(this, _BoundArray_sizeLimit, sizeLimit, "f");
|
|
97
|
-
}
|
|
98
|
-
get length() {
|
|
99
|
-
return __classPrivateFieldGet(this, _BoundArray_array, "f").length;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
_BoundArray_array = new WeakMap(), _BoundArray_sizeLimit = new WeakMap(), _b = Symbol.iterator;
|
|
103
|
-
//# sourceMappingURL=bounded-collections.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"bounded-collections.js","sourceRoot":"","sources":["../src/bounded-collections.ts"],"names":[],"mappings":"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"}
|
package/dist/componentKey.d.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
type SingletonKey = {
|
|
2
|
-
_tag: 'singleton';
|
|
3
|
-
componentName: string;
|
|
4
|
-
id: 'singleton';
|
|
5
|
-
};
|
|
6
|
-
type EphemeralKey = {
|
|
7
|
-
_tag: 'ephemeral';
|
|
8
|
-
componentName: string;
|
|
9
|
-
id: string;
|
|
10
|
-
};
|
|
11
|
-
type CustomKey = {
|
|
12
|
-
_tag: 'custom';
|
|
13
|
-
componentName: string;
|
|
14
|
-
id: string;
|
|
15
|
-
};
|
|
16
|
-
export type ComponentKey = SingletonKey | EphemeralKey | CustomKey;
|
|
17
|
-
export declare const labelForKey: (key: ComponentKey) => string;
|
|
18
|
-
export declare const tableNameForComponentKey: (componentKey: ComponentKey) => string;
|
|
19
|
-
export {};
|
|
20
|
-
//# sourceMappingURL=componentKey.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"componentKey.d.ts","sourceRoot":"","sources":["../src/componentKey.ts"],"names":[],"mappings":"AAAA,KAAK,YAAY,GAAG;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,WAAW,CAAA;CAAE,CAAA;AACjF,KAAK,YAAY,GAAG;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAA;AAC5E,KAAK,SAAS,GAAG;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAA;AAEtE,MAAM,MAAM,YAAY,GAAG,YAAY,GAAG,YAAY,GAAG,SAAS,CAAA;AAElE,eAAO,MAAM,WAAW,QAAS,YAAY,KAAG,MAA0C,CAAA;AAE1F,eAAO,MAAM,wBAAwB,iBAAkB,YAAY,WAAgD,CAAA"}
|
package/dist/componentKey.js
DELETED
package/dist/componentKey.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"componentKey.js","sourceRoot":"","sources":["../src/componentKey.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,GAAiB,EAAU,EAAE,CAAC,GAAG,GAAG,CAAC,aAAa,IAAI,GAAG,CAAC,EAAE,EAAE,CAAA;AAE1F,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,YAA0B,EAAE,EAAE,CAAC,eAAe,YAAY,CAAC,aAAa,EAAE,CAAA"}
|
package/dist/otel.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"otel.d.ts","sourceRoot":"","sources":["../src/otel.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,IAAI,MAAM,oBAAoB,CAAA;AAE/C,eAAO,MAAM,qBAAqB,SAAU,KAAK,IAAI,KAAG,MAGvD,CAAA;AAED,eAAO,MAAM,2BAA2B,SAAU,KAAK,IAAI,KAAG,mBACF,CAAA"}
|
package/dist/otel.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"otel.js","sourceRoot":"","sources":["../src/otel.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,IAAe,EAAU,EAAE;IAC/D,MAAM,UAAU,GAAsC,IAAY,CAAC,SAAS,CAAA;IAC5E,OAAO,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,OAAS,CAAA;AACzD,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,IAAe,EAAuB,EAAE,CACjF,IAAY,CAAC,qBAA4C,CAAA"}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import type { LiteralUnion } from '@livestore/utils';
|
|
2
|
-
import { SqliteDsl } from 'effect-db-schema';
|
|
3
|
-
import type { DependencyList } from 'react';
|
|
4
|
-
import React from 'react';
|
|
5
|
-
import type { ComponentKey } from '../componentKey.js';
|
|
6
|
-
import type { LiveStoreJSQuery } from '../reactiveQueries/js.js';
|
|
7
|
-
import type { LiveStoreQuery } from '../store.js';
|
|
8
|
-
export interface QueryDefinitions {
|
|
9
|
-
[queryName: string]: LiveStoreQuery;
|
|
10
|
-
}
|
|
11
|
-
export type UseComponentStateProps<TStateColumns extends ComponentColumns> = {
|
|
12
|
-
schema: SqliteDsl.TableDefinition<string, TStateColumns>;
|
|
13
|
-
componentKey: ComponentKeyConfig;
|
|
14
|
-
reactDeps?: React.DependencyList;
|
|
15
|
-
};
|
|
16
|
-
export type ComponentKeyConfig = {
|
|
17
|
-
/**
|
|
18
|
-
* Name of the Component
|
|
19
|
-
*
|
|
20
|
-
* TODO we should eventually derive this info automatically from the component (TBD how though...)
|
|
21
|
-
*/
|
|
22
|
-
name: string;
|
|
23
|
-
id: LiteralUnion<'singleton' | '__ephemeral__', string>;
|
|
24
|
-
};
|
|
25
|
-
export interface ComponentColumns extends SqliteDsl.Columns {
|
|
26
|
-
id: SqliteDsl.ColumnDefinition<SqliteDsl.FieldType.FieldTypeText<string, string>, false>;
|
|
27
|
-
}
|
|
28
|
-
type UseLiveStoreJsonState<TState> = <TResult>(jsonStringKey: keyof TState, parse?: (_: unknown) => TResult) => [value: TResult, setValue: (newVal: TResult | ((prevVal: TResult) => TResult)) => void];
|
|
29
|
-
export type GetStateType<TTableDef extends SqliteDsl.TableDefinition<any, any>> = SqliteDsl.FromColumns.RowDecoded<TTableDef['columns']>;
|
|
30
|
-
export type GetStateTypeEncoded<TTableDef extends SqliteDsl.TableDefinition<any, any>> = SqliteDsl.FromColumns.RowEncoded<TTableDef['columns']>;
|
|
31
|
-
/**
|
|
32
|
-
* Create reactive queries within a component.
|
|
33
|
-
* @param config.queries A function that returns a map of named reactive queries.
|
|
34
|
-
* @param config.componentKey A function that returns a unique key for this component.
|
|
35
|
-
* @param config.reactDeps A list of React-level dependencies that will refresh the queries.
|
|
36
|
-
*/
|
|
37
|
-
export declare const useComponentState: <TStateColumns extends ComponentColumns>({ schema: stateSchema_, componentKey: componentKeyConfig, reactDeps, }: UseComponentStateProps<TStateColumns>) => {
|
|
38
|
-
state$: LiveStoreJSQuery<import("effect-db-schema").PrettifyFlat<import("effect-db-schema").Nullable<Pick<SqliteDsl.FromColumns.RowDecodedAll<TStateColumns>, keyof { [K in keyof TStateColumns as TStateColumns[K] extends SqliteDsl.ColumnDefinition<any, true> ? K : never]: {}; }>> & Omit<SqliteDsl.FromColumns.RowDecodedAll<TStateColumns>, keyof { [K in keyof TStateColumns as TStateColumns[K] extends SqliteDsl.ColumnDefinition<any, true> ? K : never]: {}; }>>>;
|
|
39
|
-
state: import("effect-db-schema").PrettifyFlat<import("effect-db-schema").Nullable<Pick<SqliteDsl.FromColumns.RowDecodedAll<TStateColumns>, keyof { [K in keyof TStateColumns as TStateColumns[K] extends SqliteDsl.ColumnDefinition<any, true> ? K : never]: {}; }>> & Omit<SqliteDsl.FromColumns.RowDecodedAll<TStateColumns>, keyof { [K in keyof TStateColumns as TStateColumns[K] extends SqliteDsl.ColumnDefinition<any, true> ? K : never]: {}; }>>;
|
|
40
|
-
setState: Setters<import("effect-db-schema").PrettifyFlat<import("effect-db-schema").Nullable<Pick<SqliteDsl.FromColumns.RowDecodedAll<TStateColumns>, keyof { [K in keyof TStateColumns as TStateColumns[K] extends SqliteDsl.ColumnDefinition<any, true> ? K : never]: {}; }>> & Omit<SqliteDsl.FromColumns.RowDecodedAll<TStateColumns>, keyof { [K in keyof TStateColumns as TStateColumns[K] extends SqliteDsl.ColumnDefinition<any, true> ? K : never]: {}; }>>>;
|
|
41
|
-
useLiveStoreJsonState: UseLiveStoreJsonState<import("effect-db-schema").PrettifyFlat<import("effect-db-schema").Nullable<Pick<SqliteDsl.FromColumns.RowDecodedAll<TStateColumns>, keyof { [K in keyof TStateColumns as TStateColumns[K] extends SqliteDsl.ColumnDefinition<any, true> ? K : never]: {}; }>> & Omit<SqliteDsl.FromColumns.RowDecodedAll<TStateColumns>, keyof { [K in keyof TStateColumns as TStateColumns[K] extends SqliteDsl.ColumnDefinition<any, true> ? K : never]: {}; }>>>;
|
|
42
|
-
};
|
|
43
|
-
export type Setters<TComponentState> = {
|
|
44
|
-
[k in keyof TComponentState]: (newValue: TComponentState[k]) => void;
|
|
45
|
-
} & {
|
|
46
|
-
setMany: (newValues: Partial<TComponentState>) => void;
|
|
47
|
-
};
|
|
48
|
-
export declare const useComponentKey: ({ name, id }: ComponentKeyConfig, deps?: DependencyList) => ComponentKey;
|
|
49
|
-
export {};
|
|
50
|
-
//# sourceMappingURL=useComponentState.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useComponentState.d.ts","sourceRoot":"","sources":["../../src/react/useComponentState.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAIpD,OAAO,EAAa,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAEvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAA;AAC3C,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAGtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAGhE,OAAO,KAAK,EAAsB,cAAc,EAAS,MAAM,aAAa,CAAA;AAM5E,MAAM,WAAW,gBAAgB;IAC/B,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,CAAA;CACpC;AAED,MAAM,MAAM,sBAAsB,CAAC,aAAa,SAAS,gBAAgB,IAAI;IAC3E,MAAM,EAAE,SAAS,CAAC,eAAe,CAAC,MAAM,EAAE,aAAa,CAAC,CAAA;IACxD,YAAY,EAAE,kBAAkB,CAAA;IAChC,SAAS,CAAC,EAAE,KAAK,CAAC,cAAc,CAAA;CACjC,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B;;;;OAIG;IACH,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,EAAE,YAAY,CAAC,WAAW,GAAG,eAAe,EAAE,MAAM,CAAC,CAAA;CACxD,CAAA;AAGD,MAAM,WAAW,gBAAiB,SAAQ,SAAS,CAAC,OAAO;IACzD,EAAE,EAAE,SAAS,CAAC,gBAAgB,CAAC,SAAS,CAAC,SAAS,CAAC,aAAa,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,KAAK,CAAC,CAAA;CACzF;AAeD,KAAK,qBAAqB,CAAC,MAAM,IAAI,CAAC,OAAO,EAC3C,aAAa,EAAE,MAAM,MAAM,EAC3B,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,OAAO,KAC5B,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,MAAM,EAAE,OAAO,GAAG,CAAC,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,KAAK,IAAI,CAAC,CAAA;AAE5F,MAAM,MAAM,YAAY,CAAC,SAAS,SAAS,SAAS,CAAC,eAAe,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,SAAS,CAAC,WAAW,CAAC,UAAU,CAChH,SAAS,CAAC,SAAS,CAAC,CACrB,CAAA;AAED,MAAM,MAAM,mBAAmB,CAAC,SAAS,SAAS,SAAS,CAAC,eAAe,CAAC,GAAG,EAAE,GAAG,CAAC,IACnF,SAAS,CAAC,WAAW,CAAC,UAAU,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAA;AAExD;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB;;;;;CAkP7B,CAAA;AAED,MAAM,MAAM,OAAO,CAAC,eAAe,IAAI;KACpC,CAAC,IAAI,MAAM,eAAe,GAAG,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC,CAAC,KAAK,IAAI;CACrE,GAAG;IACF,OAAO,EAAE,CAAC,SAAS,EAAE,OAAO,CAAC,eAAe,CAAC,KAAK,IAAI,CAAA;CACvD,CAAA;AAED,eAAO,MAAM,eAAe,iBAAkB,kBAAkB,wCAcvC,CAAA"}
|
|
@@ -1,226 +0,0 @@
|
|
|
1
|
-
import { omit, shouldNeverHappen } from '@livestore/utils';
|
|
2
|
-
import { Schema } from '@livestore/utils/effect';
|
|
3
|
-
import * as otel from '@opentelemetry/api';
|
|
4
|
-
import { SqliteAst, SqliteDsl } from 'effect-db-schema';
|
|
5
|
-
import { isEqual, mapValues } from 'lodash-es';
|
|
6
|
-
import React from 'react';
|
|
7
|
-
import { v4 as uuid } from 'uuid';
|
|
8
|
-
import { labelForKey, tableNameForComponentKey } from '../componentKey.js';
|
|
9
|
-
import { migrateTable } from '../migrations.js';
|
|
10
|
-
import { LiveStoreSQLQuery } from '../reactiveQueries/sql.js';
|
|
11
|
-
import { SCHEMA_META_TABLE } from '../schema.js';
|
|
12
|
-
import { sql } from '../util.js';
|
|
13
|
-
import { useStore } from './LiveStoreContext.js';
|
|
14
|
-
import { extractStackInfoFromStackTrace, originalStackLimit } from './utils/stack-info.js';
|
|
15
|
-
import { useStateRefWithReactiveInput } from './utils/useStateRefWithReactiveInput.js';
|
|
16
|
-
// type ComponentState = {
|
|
17
|
-
// /** Equivalent to `componentKey.key` */
|
|
18
|
-
// id: string
|
|
19
|
-
// [key: string]: string | number | boolean | null
|
|
20
|
-
// }
|
|
21
|
-
/**
|
|
22
|
-
* This is needed because the `React.useMemo` call below, can sometimes be called multiple times 🤷,
|
|
23
|
-
* so we need to "cache" the fact that we've already started a span for this component.
|
|
24
|
-
* The map entry is being removed again in the `React.useEffect` call below.
|
|
25
|
-
*/
|
|
26
|
-
const spanAlreadyStartedCache = new Map();
|
|
27
|
-
/**
|
|
28
|
-
* Create reactive queries within a component.
|
|
29
|
-
* @param config.queries A function that returns a map of named reactive queries.
|
|
30
|
-
* @param config.componentKey A function that returns a unique key for this component.
|
|
31
|
-
* @param config.reactDeps A list of React-level dependencies that will refresh the queries.
|
|
32
|
-
*/
|
|
33
|
-
export const useComponentState = ({ schema: stateSchema_, componentKey: componentKeyConfig, reactDeps = [], }) => {
|
|
34
|
-
// TODO validate schema to make sure each column has a default value
|
|
35
|
-
// TODO we should clean up the state schema handling to remove this special handling for the `id` column
|
|
36
|
-
const stateSchema = React.useMemo(() => ({ ...stateSchema_, columns: omit(stateSchema_.columns, 'id') }), [stateSchema_]);
|
|
37
|
-
const componentKey = useComponentKey(componentKeyConfig, reactDeps);
|
|
38
|
-
const { store } = useStore();
|
|
39
|
-
const componentKeyLabel = React.useMemo(() => labelForKey(componentKey), [componentKey]);
|
|
40
|
-
const stackInfo = React.useMemo(() => {
|
|
41
|
-
Error.stackTraceLimit = 10;
|
|
42
|
-
// eslint-disable-next-line unicorn/error-message
|
|
43
|
-
const stack = new Error().stack;
|
|
44
|
-
Error.stackTraceLimit = originalStackLimit;
|
|
45
|
-
return extractStackInfoFromStackTrace(stack);
|
|
46
|
-
}, []);
|
|
47
|
-
// The following `React.useMemo` and `React.useEffect` calls are used to start and end a span for the lifetime of this component.
|
|
48
|
-
const { span, otelContext } = React.useMemo(() => {
|
|
49
|
-
const existingSpan = spanAlreadyStartedCache.get(componentKeyLabel);
|
|
50
|
-
if (existingSpan !== undefined)
|
|
51
|
-
return existingSpan;
|
|
52
|
-
const span = store.otel.tracer.startSpan(`LiveStore:useComponentState:${componentKeyLabel}`, { attributes: { stackInfo: JSON.stringify(stackInfo) } }, store.otel.queriesSpanContext);
|
|
53
|
-
const otelContext = otel.trace.setSpan(otel.context.active(), span);
|
|
54
|
-
spanAlreadyStartedCache.set(componentKeyLabel, { span, otelContext });
|
|
55
|
-
return { span, otelContext };
|
|
56
|
-
}, [componentKeyLabel, stackInfo, store.otel.queriesSpanContext, store.otel.tracer]);
|
|
57
|
-
React.useEffect(() => () => {
|
|
58
|
-
spanAlreadyStartedCache.delete(componentKeyLabel);
|
|
59
|
-
span.end();
|
|
60
|
-
}, [componentKeyLabel, span]);
|
|
61
|
-
const defaultComponentState = React.useMemo(() => {
|
|
62
|
-
const defaultState = mapValues(stateSchema.columns, (c) => c.default);
|
|
63
|
-
// @ts-expect-error TODO fix typing
|
|
64
|
-
defaultState.id = componentKeyConfig.id;
|
|
65
|
-
return defaultState;
|
|
66
|
-
}, [componentKeyConfig.id, stateSchema]);
|
|
67
|
-
const componentStateEffectSchema = React.useMemo(() => SqliteDsl.structSchemaForTable(stateSchema), [stateSchema]);
|
|
68
|
-
// create state query
|
|
69
|
-
const state$ = React.useMemo(() => {
|
|
70
|
-
const componentTableName = tableNameForComponentKey(componentKey);
|
|
71
|
-
const whereClause = componentKey._tag === 'singleton' ? '' : `where id = '${componentKey.id}'`;
|
|
72
|
-
// TODO find a better solution for this
|
|
73
|
-
if (store.tableRefs[componentTableName] === undefined) {
|
|
74
|
-
const schemaHash = SqliteAst.hash(stateSchema.ast);
|
|
75
|
-
const res = store.inMemoryDB.select(sql `SELECT schemaHash FROM ${SCHEMA_META_TABLE} WHERE tableName = '${componentTableName}'`);
|
|
76
|
-
if (res.length === 0 || res[0].schemaHash !== schemaHash) {
|
|
77
|
-
migrateTable({ db: store._proxyDb, tableDef: stateSchema.ast, otelContext, schemaHash });
|
|
78
|
-
}
|
|
79
|
-
store.tableRefs[componentTableName] = store.graph.makeRef(null, {
|
|
80
|
-
equal: () => false,
|
|
81
|
-
label: componentTableName,
|
|
82
|
-
meta: { liveStoreRefType: 'table' },
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
return (new LiveStoreSQLQuery({
|
|
86
|
-
label: `localState:query:${componentKeyLabel}`,
|
|
87
|
-
genQueryString: () => sql `select * from ${componentTableName} ${whereClause} limit 1`,
|
|
88
|
-
queriedTables: new Set([componentTableName]),
|
|
89
|
-
})
|
|
90
|
-
// TODO consider to instead of just returning the default value, to write the default component state to the DB
|
|
91
|
-
.pipe((results) => results.length === 1
|
|
92
|
-
? Schema.parseSync(componentStateEffectSchema)(results[0])
|
|
93
|
-
: defaultComponentState));
|
|
94
|
-
}, [
|
|
95
|
-
componentKey,
|
|
96
|
-
componentKeyLabel,
|
|
97
|
-
componentStateEffectSchema,
|
|
98
|
-
defaultComponentState,
|
|
99
|
-
otelContext,
|
|
100
|
-
stateSchema,
|
|
101
|
-
store,
|
|
102
|
-
]);
|
|
103
|
-
// Step 1:
|
|
104
|
-
// Synchronously create state and queries for initial render pass.
|
|
105
|
-
const initialComponentState = React.useMemo(() => state$.run(otelContext, { _tag: 'react', api: 'useComponentState', label: state$.label, stackInfo }), [otelContext, stackInfo, state$]);
|
|
106
|
-
// Now that we've computed the initial state synchronously,
|
|
107
|
-
// we can set up our useState calls w/ a default value populated...
|
|
108
|
-
const [componentStateRef, setComponentState_] = useStateRefWithReactiveInput(initialComponentState);
|
|
109
|
-
const setState = // TODO: do we have a better type for the values that can go in SQLite?
|
|
110
|
-
mapValues(stateSchema.columns, (column, columnName) => (value) => {
|
|
111
|
-
// Don't update the state if it's the same as the value already seen in the component
|
|
112
|
-
// @ts-expect-error TODO fix typing
|
|
113
|
-
if (componentStateRef.current[columnName] === value)
|
|
114
|
-
return;
|
|
115
|
-
const encodedValue = Schema.encodeSync(column.type.codec)(value);
|
|
116
|
-
if (['componentKey', 'columnNames'].includes(columnName)) {
|
|
117
|
-
shouldNeverHappen(`Can't use reserved column name ${columnName}`);
|
|
118
|
-
}
|
|
119
|
-
return store.applyEvent('updateComponentState', {
|
|
120
|
-
componentKey,
|
|
121
|
-
columnNames: [columnName],
|
|
122
|
-
[columnName]: encodedValue,
|
|
123
|
-
});
|
|
124
|
-
});
|
|
125
|
-
setState.setMany = (columnValues) => {
|
|
126
|
-
// TODO use hashing instead
|
|
127
|
-
// Don't update the state if it's the same as the value already seen in the component
|
|
128
|
-
// @ts-expect-error TODO fix typing
|
|
129
|
-
if (Object.entries(columnValues).every(([columnName, value]) => componentStateRef.current[columnName] === value)) {
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
const columnNames = Object.keys(columnValues);
|
|
133
|
-
return store.applyEvent('updateComponentState', { componentKey, columnNames, ...columnValues });
|
|
134
|
-
};
|
|
135
|
-
// OK, now all the synchronous work is done;
|
|
136
|
-
// time to set up our long-running queries in an effect
|
|
137
|
-
React.useEffect(() => {
|
|
138
|
-
return store.otel.tracer.startActiveSpan('LiveStore:useComponentState:long-running', { attributes: {} }, otelContext, (span) => {
|
|
139
|
-
const unsubs = [];
|
|
140
|
-
const otelContext = otel.trace.setSpan(otel.context.active(), span);
|
|
141
|
-
insertRowForComponentInstance({ store, componentKey, stateSchema, otelContext });
|
|
142
|
-
state$.activeSubscriptions.add(stackInfo);
|
|
143
|
-
unsubs.push(store.subscribe(state$, (results) => {
|
|
144
|
-
if (isEqual(results, componentStateRef.current) === false) {
|
|
145
|
-
setComponentState_(results);
|
|
146
|
-
}
|
|
147
|
-
}, undefined, { label: `useComponentState:localState:subscribe:${state$.label}`, otelContext }), () => state$.activeSubscriptions.delete(stackInfo));
|
|
148
|
-
return () => {
|
|
149
|
-
for (const unsub of unsubs) {
|
|
150
|
-
unsub();
|
|
151
|
-
}
|
|
152
|
-
span.end();
|
|
153
|
-
};
|
|
154
|
-
});
|
|
155
|
-
}, [
|
|
156
|
-
store,
|
|
157
|
-
stackInfo,
|
|
158
|
-
stateSchema,
|
|
159
|
-
defaultComponentState,
|
|
160
|
-
otelContext,
|
|
161
|
-
componentStateRef,
|
|
162
|
-
state$,
|
|
163
|
-
setComponentState_,
|
|
164
|
-
componentKey,
|
|
165
|
-
]);
|
|
166
|
-
React.useEffect(() => () => state$.destroy(), [state$]);
|
|
167
|
-
const state = componentStateRef.current;
|
|
168
|
-
const useLiveStoreJsonState = (jsonStringKey, parse = (_) => _) => {
|
|
169
|
-
const value = React.useMemo(() => {
|
|
170
|
-
return parse(JSON.parse(state[jsonStringKey]));
|
|
171
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
172
|
-
}, [state[jsonStringKey], parse]);
|
|
173
|
-
const setValue = React.useCallback((newValOrFn) => {
|
|
174
|
-
const newVal = typeof newValOrFn === 'function'
|
|
175
|
-
? // NOTE we're using the ref instead of the value because we want to be sure
|
|
176
|
-
// we're using the latest value when the setter is called
|
|
177
|
-
newValOrFn(parse(JSON.parse(componentStateRef.current[jsonStringKey])))
|
|
178
|
-
: newValOrFn;
|
|
179
|
-
setState[jsonStringKey](JSON.stringify(newVal));
|
|
180
|
-
}, [parse, jsonStringKey]);
|
|
181
|
-
return [value, setValue];
|
|
182
|
-
};
|
|
183
|
-
return {
|
|
184
|
-
state$,
|
|
185
|
-
state,
|
|
186
|
-
setState,
|
|
187
|
-
useLiveStoreJsonState,
|
|
188
|
-
};
|
|
189
|
-
};
|
|
190
|
-
export const useComponentKey = ({ name, id }, deps = []) => React.useMemo(() => {
|
|
191
|
-
switch (id) {
|
|
192
|
-
case 'singleton': {
|
|
193
|
-
return { _tag: 'singleton', componentName: name, id: 'singleton' };
|
|
194
|
-
}
|
|
195
|
-
case '__ephemeral__': {
|
|
196
|
-
return { _tag: 'ephemeral', componentName: name, id: uuid() };
|
|
197
|
-
}
|
|
198
|
-
default: {
|
|
199
|
-
return { _tag: 'custom', componentName: name, id };
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
203
|
-
}, [...deps, id, name]);
|
|
204
|
-
/**
|
|
205
|
-
* Create a row storing the state for a component instance, if none exists yet.
|
|
206
|
-
* Initialized with default values, and keyed on the component key.
|
|
207
|
-
*/
|
|
208
|
-
const insertRowForComponentInstance = ({ store, componentKey, stateSchema, otelContext, }) => {
|
|
209
|
-
const columnNames = ['id', ...Object.keys(stateSchema.columns)];
|
|
210
|
-
const columnValues = columnNames.map((name) => `$${name}`).join(', ');
|
|
211
|
-
const tableName = tableNameForComponentKey(componentKey);
|
|
212
|
-
const insertQuery = sql `insert into ${tableName} (${columnNames.join(', ')}) select ${columnValues} where not exists(select 1 from ${tableName} where id = '${componentKey.id}')`;
|
|
213
|
-
void store.execute(insertQuery, {
|
|
214
|
-
...mapValues(stateSchema.columns, (column) => prepareValueForSql(column.default ?? null)),
|
|
215
|
-
id: componentKey.id,
|
|
216
|
-
}, [tableName], otelContext);
|
|
217
|
-
};
|
|
218
|
-
const prepareValueForSql = (value) => {
|
|
219
|
-
if (typeof value === 'string' || typeof value === 'number' || value === null) {
|
|
220
|
-
return value;
|
|
221
|
-
}
|
|
222
|
-
else {
|
|
223
|
-
return value ? 1 : 0;
|
|
224
|
-
}
|
|
225
|
-
};
|
|
226
|
-
//# sourceMappingURL=useComponentState.js.map
|