@livestore/common 0.3.0-dev.27 → 0.3.0-dev.29
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/__tests__/fixture.d.ts +83 -221
- package/dist/__tests__/fixture.d.ts.map +1 -1
- package/dist/__tests__/fixture.js +33 -11
- package/dist/__tests__/fixture.js.map +1 -1
- package/dist/adapter-types.d.ts +22 -15
- package/dist/adapter-types.d.ts.map +1 -1
- package/dist/adapter-types.js +15 -2
- package/dist/adapter-types.js.map +1 -1
- package/dist/bounded-collections.d.ts +1 -1
- package/dist/bounded-collections.d.ts.map +1 -1
- package/dist/debug-info.d.ts.map +1 -1
- package/dist/debug-info.js +1 -0
- package/dist/debug-info.js.map +1 -1
- package/dist/devtools/devtools-messages-client-session.d.ts +21 -21
- package/dist/devtools/devtools-messages-common.d.ts +6 -6
- package/dist/devtools/devtools-messages-leader.d.ts +45 -45
- package/dist/devtools/devtools-messages-leader.d.ts.map +1 -1
- package/dist/devtools/devtools-messages-leader.js +11 -11
- package/dist/devtools/devtools-messages-leader.js.map +1 -1
- package/dist/index.d.ts +2 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -5
- package/dist/index.js.map +1 -1
- package/dist/leader-thread/LeaderSyncProcessor.d.ts +25 -12
- package/dist/leader-thread/LeaderSyncProcessor.d.ts.map +1 -1
- package/dist/leader-thread/LeaderSyncProcessor.js +125 -89
- package/dist/leader-thread/LeaderSyncProcessor.js.map +1 -1
- package/dist/leader-thread/{apply-mutation.d.ts → apply-event.d.ts} +7 -7
- package/dist/leader-thread/apply-event.d.ts.map +1 -0
- package/dist/leader-thread/apply-event.js +103 -0
- package/dist/leader-thread/apply-event.js.map +1 -0
- package/dist/leader-thread/eventlog.d.ts +27 -0
- package/dist/leader-thread/eventlog.d.ts.map +1 -0
- package/dist/leader-thread/eventlog.js +123 -0
- package/dist/leader-thread/eventlog.js.map +1 -0
- package/dist/leader-thread/leader-worker-devtools.js +18 -18
- package/dist/leader-thread/leader-worker-devtools.js.map +1 -1
- package/dist/leader-thread/make-leader-thread-layer.d.ts +16 -4
- package/dist/leader-thread/make-leader-thread-layer.d.ts.map +1 -1
- package/dist/leader-thread/make-leader-thread-layer.js +23 -16
- package/dist/leader-thread/make-leader-thread-layer.js.map +1 -1
- package/dist/leader-thread/mod.d.ts +1 -1
- package/dist/leader-thread/mod.d.ts.map +1 -1
- package/dist/leader-thread/mod.js +1 -1
- package/dist/leader-thread/mod.js.map +1 -1
- package/dist/leader-thread/recreate-db.d.ts.map +1 -1
- package/dist/leader-thread/recreate-db.js +6 -8
- package/dist/leader-thread/recreate-db.js.map +1 -1
- package/dist/leader-thread/types.d.ts +11 -11
- package/dist/leader-thread/types.d.ts.map +1 -1
- package/dist/materializer-helper.d.ts +23 -0
- package/dist/materializer-helper.d.ts.map +1 -0
- package/dist/materializer-helper.js +70 -0
- package/dist/materializer-helper.js.map +1 -0
- package/dist/query-builder/api.d.ts +58 -53
- package/dist/query-builder/api.d.ts.map +1 -1
- package/dist/query-builder/api.js +3 -5
- package/dist/query-builder/api.js.map +1 -1
- package/dist/query-builder/astToSql.d.ts.map +1 -1
- package/dist/query-builder/astToSql.js +59 -37
- package/dist/query-builder/astToSql.js.map +1 -1
- package/dist/query-builder/impl.d.ts +2 -3
- package/dist/query-builder/impl.d.ts.map +1 -1
- package/dist/query-builder/impl.js +48 -46
- package/dist/query-builder/impl.js.map +1 -1
- package/dist/query-builder/impl.test.d.ts +86 -1
- package/dist/query-builder/impl.test.d.ts.map +1 -1
- package/dist/query-builder/impl.test.js +244 -36
- package/dist/query-builder/impl.test.js.map +1 -1
- package/dist/rehydrate-from-eventlog.d.ts +14 -0
- package/dist/rehydrate-from-eventlog.d.ts.map +1 -0
- package/dist/{rehydrate-from-mutationlog.js → rehydrate-from-eventlog.js} +25 -26
- package/dist/rehydrate-from-eventlog.js.map +1 -0
- package/dist/schema/EventDef.d.ts +136 -0
- package/dist/schema/EventDef.d.ts.map +1 -0
- package/dist/schema/EventDef.js +58 -0
- package/dist/schema/EventDef.js.map +1 -0
- package/dist/schema/EventId.d.ts +2 -2
- package/dist/schema/EventId.d.ts.map +1 -1
- package/dist/schema/EventId.js +8 -2
- package/dist/schema/EventId.js.map +1 -1
- package/dist/schema/{MutationEvent.d.ts → LiveStoreEvent.d.ts} +56 -56
- package/dist/schema/LiveStoreEvent.d.ts.map +1 -0
- package/dist/schema/{MutationEvent.js → LiveStoreEvent.js} +25 -25
- package/dist/schema/LiveStoreEvent.js.map +1 -0
- package/dist/schema/client-document-def.d.ts +223 -0
- package/dist/schema/client-document-def.d.ts.map +1 -0
- package/dist/schema/client-document-def.js +170 -0
- package/dist/schema/client-document-def.js.map +1 -0
- package/dist/schema/client-document-def.test.d.ts +2 -0
- package/dist/schema/client-document-def.test.d.ts.map +1 -0
- package/dist/schema/client-document-def.test.js +201 -0
- package/dist/schema/client-document-def.test.js.map +1 -0
- package/dist/schema/db-schema/dsl/mod.d.ts.map +1 -1
- package/dist/schema/events.d.ts +2 -0
- package/dist/schema/events.d.ts.map +1 -0
- package/dist/schema/events.js +2 -0
- package/dist/schema/events.js.map +1 -0
- package/dist/schema/mod.d.ts +4 -3
- package/dist/schema/mod.d.ts.map +1 -1
- package/dist/schema/mod.js +4 -3
- package/dist/schema/mod.js.map +1 -1
- package/dist/schema/schema.d.ts +27 -23
- package/dist/schema/schema.d.ts.map +1 -1
- package/dist/schema/schema.js +45 -43
- package/dist/schema/schema.js.map +1 -1
- package/dist/schema/sqlite-state.d.ts +12 -0
- package/dist/schema/sqlite-state.d.ts.map +1 -0
- package/dist/schema/sqlite-state.js +36 -0
- package/dist/schema/sqlite-state.js.map +1 -0
- package/dist/schema/system-tables.d.ts +67 -98
- package/dist/schema/system-tables.d.ts.map +1 -1
- package/dist/schema/system-tables.js +62 -48
- package/dist/schema/system-tables.js.map +1 -1
- package/dist/schema/table-def.d.ts +26 -96
- package/dist/schema/table-def.d.ts.map +1 -1
- package/dist/schema/table-def.js +16 -64
- package/dist/schema/table-def.js.map +1 -1
- package/dist/schema/view.d.ts +3 -0
- package/dist/schema/view.d.ts.map +1 -0
- package/dist/schema/view.js +3 -0
- package/dist/schema/view.js.map +1 -0
- package/dist/schema-management/common.d.ts +4 -4
- package/dist/schema-management/common.d.ts.map +1 -1
- package/dist/schema-management/migrations.d.ts.map +1 -1
- package/dist/schema-management/migrations.js +6 -6
- package/dist/schema-management/migrations.js.map +1 -1
- package/dist/schema-management/validate-mutation-defs.d.ts +3 -3
- package/dist/schema-management/validate-mutation-defs.d.ts.map +1 -1
- package/dist/schema-management/validate-mutation-defs.js +17 -17
- package/dist/schema-management/validate-mutation-defs.js.map +1 -1
- package/dist/sync/ClientSessionSyncProcessor.d.ts +7 -7
- package/dist/sync/ClientSessionSyncProcessor.d.ts.map +1 -1
- package/dist/sync/ClientSessionSyncProcessor.js +31 -30
- package/dist/sync/ClientSessionSyncProcessor.js.map +1 -1
- package/dist/sync/next/facts.d.ts +19 -19
- package/dist/sync/next/facts.d.ts.map +1 -1
- package/dist/sync/next/facts.js +2 -2
- package/dist/sync/next/facts.js.map +1 -1
- package/dist/sync/next/history-dag-common.d.ts +3 -3
- package/dist/sync/next/history-dag-common.d.ts.map +1 -1
- package/dist/sync/next/history-dag-common.js +1 -1
- package/dist/sync/next/history-dag-common.js.map +1 -1
- package/dist/sync/next/history-dag.js +1 -1
- package/dist/sync/next/history-dag.js.map +1 -1
- package/dist/sync/next/rebase-events.d.ts +7 -7
- package/dist/sync/next/rebase-events.d.ts.map +1 -1
- package/dist/sync/next/rebase-events.js +5 -5
- package/dist/sync/next/rebase-events.js.map +1 -1
- package/dist/sync/next/test/compact-events.calculator.test.js +38 -33
- package/dist/sync/next/test/compact-events.calculator.test.js.map +1 -1
- package/dist/sync/next/test/compact-events.test.js +71 -71
- package/dist/sync/next/test/compact-events.test.js.map +1 -1
- package/dist/sync/next/test/{mutation-fixtures.d.ts → event-fixtures.d.ts} +29 -29
- package/dist/sync/next/test/event-fixtures.d.ts.map +1 -0
- package/dist/sync/next/test/{mutation-fixtures.js → event-fixtures.js} +60 -25
- package/dist/sync/next/test/event-fixtures.js.map +1 -0
- package/dist/sync/next/test/mod.d.ts +1 -1
- package/dist/sync/next/test/mod.d.ts.map +1 -1
- package/dist/sync/next/test/mod.js +1 -1
- package/dist/sync/next/test/mod.js.map +1 -1
- package/dist/sync/sync.d.ts +3 -3
- package/dist/sync/sync.d.ts.map +1 -1
- package/dist/sync/syncstate.d.ts +32 -32
- package/dist/sync/syncstate.d.ts.map +1 -1
- package/dist/sync/syncstate.js +31 -25
- package/dist/sync/syncstate.js.map +1 -1
- package/dist/sync/syncstate.test.js +165 -175
- package/dist/sync/syncstate.test.js.map +1 -1
- package/dist/sync/validate-push-payload.d.ts +2 -2
- package/dist/sync/validate-push-payload.d.ts.map +1 -1
- package/dist/sync/validate-push-payload.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +3 -3
- package/src/__tests__/fixture.ts +36 -15
- package/src/adapter-types.ts +23 -16
- package/src/debug-info.ts +1 -0
- package/src/devtools/devtools-messages-leader.ts +13 -13
- package/src/index.ts +2 -5
- package/src/leader-thread/LeaderSyncProcessor.ts +183 -122
- package/src/leader-thread/{apply-mutation.ts → apply-event.ts} +50 -74
- package/src/leader-thread/eventlog.ts +199 -0
- package/src/leader-thread/leader-worker-devtools.ts +18 -18
- package/src/leader-thread/make-leader-thread-layer.ts +51 -29
- package/src/leader-thread/mod.ts +1 -1
- package/src/leader-thread/recreate-db.ts +6 -9
- package/src/leader-thread/types.ts +12 -12
- package/src/materializer-helper.ts +110 -0
- package/src/query-builder/api.ts +79 -105
- package/src/query-builder/astToSql.ts +68 -39
- package/src/query-builder/impl.test.ts +264 -42
- package/src/query-builder/impl.ts +72 -56
- package/src/{rehydrate-from-mutationlog.ts → rehydrate-from-eventlog.ts} +33 -40
- package/src/schema/EventDef.ts +216 -0
- package/src/schema/EventId.ts +11 -3
- package/src/schema/{MutationEvent.ts → LiveStoreEvent.ts} +68 -69
- package/src/schema/client-document-def.test.ts +239 -0
- package/src/schema/client-document-def.ts +444 -0
- package/src/schema/db-schema/dsl/mod.ts +0 -1
- package/src/schema/events.ts +1 -0
- package/src/schema/mod.ts +4 -3
- package/src/schema/schema.ts +79 -69
- package/src/schema/sqlite-state.ts +62 -0
- package/src/schema/system-tables.ts +42 -53
- package/src/schema/table-def.ts +53 -209
- package/src/schema/view.ts +2 -0
- package/src/schema-management/common.ts +4 -4
- package/src/schema-management/migrations.ts +8 -9
- package/src/schema-management/validate-mutation-defs.ts +22 -24
- package/src/sync/ClientSessionSyncProcessor.ts +37 -36
- package/src/sync/next/facts.ts +31 -32
- package/src/sync/next/history-dag-common.ts +4 -4
- package/src/sync/next/history-dag.ts +1 -1
- package/src/sync/next/rebase-events.ts +13 -13
- package/src/sync/next/test/compact-events.calculator.test.ts +45 -45
- package/src/sync/next/test/compact-events.test.ts +73 -73
- package/src/sync/next/test/event-fixtures.ts +219 -0
- package/src/sync/next/test/mod.ts +1 -1
- package/src/sync/sync.ts +3 -3
- package/src/sync/syncstate.test.ts +168 -179
- package/src/sync/syncstate.ts +48 -38
- package/src/sync/validate-push-payload.ts +2 -2
- package/src/version.ts +1 -1
- package/tmp/pack.tgz +0 -0
- package/tsconfig.json +1 -0
- package/dist/derived-mutations.d.ts +0 -109
- package/dist/derived-mutations.d.ts.map +0 -1
- package/dist/derived-mutations.js +0 -54
- package/dist/derived-mutations.js.map +0 -1
- package/dist/derived-mutations.test.d.ts +0 -2
- package/dist/derived-mutations.test.d.ts.map +0 -1
- package/dist/derived-mutations.test.js +0 -93
- package/dist/derived-mutations.test.js.map +0 -1
- package/dist/init-singleton-tables.d.ts +0 -4
- package/dist/init-singleton-tables.d.ts.map +0 -1
- package/dist/init-singleton-tables.js +0 -16
- package/dist/init-singleton-tables.js.map +0 -1
- package/dist/leader-thread/apply-mutation.d.ts.map +0 -1
- package/dist/leader-thread/apply-mutation.js +0 -122
- package/dist/leader-thread/apply-mutation.js.map +0 -1
- package/dist/leader-thread/mutationlog.d.ts +0 -27
- package/dist/leader-thread/mutationlog.d.ts.map +0 -1
- package/dist/leader-thread/mutationlog.js +0 -124
- package/dist/leader-thread/mutationlog.js.map +0 -1
- package/dist/leader-thread/pull-queue-set.d.ts +0 -7
- package/dist/leader-thread/pull-queue-set.d.ts.map +0 -1
- package/dist/leader-thread/pull-queue-set.js +0 -38
- package/dist/leader-thread/pull-queue-set.js.map +0 -1
- package/dist/mutation.d.ts +0 -20
- package/dist/mutation.d.ts.map +0 -1
- package/dist/mutation.js +0 -68
- package/dist/mutation.js.map +0 -1
- package/dist/query-info.d.ts +0 -41
- package/dist/query-info.d.ts.map +0 -1
- package/dist/query-info.js +0 -7
- package/dist/query-info.js.map +0 -1
- package/dist/rehydrate-from-mutationlog.d.ts +0 -15
- package/dist/rehydrate-from-mutationlog.d.ts.map +0 -1
- package/dist/rehydrate-from-mutationlog.js.map +0 -1
- package/dist/schema/MutationEvent.d.ts.map +0 -1
- package/dist/schema/MutationEvent.js.map +0 -1
- package/dist/schema/mutations.d.ts +0 -115
- package/dist/schema/mutations.d.ts.map +0 -1
- package/dist/schema/mutations.js +0 -42
- package/dist/schema/mutations.js.map +0 -1
- package/dist/sync/next/test/mutation-fixtures.d.ts.map +0 -1
- package/dist/sync/next/test/mutation-fixtures.js.map +0 -1
- package/src/derived-mutations.test.ts +0 -101
- package/src/derived-mutations.ts +0 -170
- package/src/init-singleton-tables.ts +0 -24
- package/src/leader-thread/mutationlog.ts +0 -202
- package/src/mutation.ts +0 -108
- package/src/query-info.ts +0 -83
- package/src/schema/mutations.ts +0 -193
- package/src/sync/next/test/mutation-fixtures.ts +0 -228
package/src/schema/table-def.ts
CHANGED
@@ -1,12 +1,8 @@
|
|
1
|
-
import type
|
2
|
-
import {
|
3
|
-
import type { Types } from '@livestore/utils/effect'
|
4
|
-
import { ReadonlyRecord, Schema } from '@livestore/utils/effect'
|
1
|
+
import { type Nullable } from '@livestore/utils'
|
2
|
+
import type { Schema, Types } from '@livestore/utils/effect'
|
5
3
|
|
6
|
-
import type { DerivedMutationHelperFns } from '../derived-mutations.js'
|
7
|
-
import { makeDerivedMutationDefsForTable } from '../derived-mutations.js'
|
8
4
|
import type { QueryBuilder } from '../query-builder/mod.js'
|
9
|
-
import { makeQueryBuilder } from '../query-builder/mod.js'
|
5
|
+
import { makeQueryBuilder, QueryBuilderAstSymbol, QueryBuilderTypeId } from '../query-builder/mod.js'
|
10
6
|
import { SqliteDsl } from './db-schema/mod.js'
|
11
7
|
|
12
8
|
export const { blob, boolean, column, datetime, integer, isColumnDefinition, json, real, text } = SqliteDsl
|
@@ -16,6 +12,10 @@ export type StateType = 'singleton' | 'dynamic'
|
|
16
12
|
export type DefaultSqliteTableDef = SqliteDsl.TableDefinition<string, SqliteDsl.Columns>
|
17
13
|
export type DefaultSqliteTableDefConstrained = SqliteDsl.TableDefinition<string, SqliteDsl.ConstraintColumns>
|
18
14
|
|
15
|
+
// TODO use to hide table def internals
|
16
|
+
export const TableDefInternalsSymbol = Symbol('TableDefInternals')
|
17
|
+
export type TableDefInternalsSymbol = typeof TableDefInternalsSymbol
|
18
|
+
|
19
19
|
export type TableDefBase<
|
20
20
|
TSqliteDef extends DefaultSqliteTableDef = DefaultSqliteTableDefConstrained,
|
21
21
|
TOptions extends TableOptions = TableOptions,
|
@@ -23,7 +23,7 @@ export type TableDefBase<
|
|
23
23
|
sqliteDef: TSqliteDef
|
24
24
|
options: TOptions
|
25
25
|
// Derived from `sqliteDef`, so only exposed for convenience
|
26
|
-
|
26
|
+
rowSchema: SqliteDsl.StructSchemaForColumns<TSqliteDef['columns']>
|
27
27
|
insertSchema: SqliteDsl.InsertStructSchemaForColumns<TSqliteDef['columns']>
|
28
28
|
}
|
29
29
|
|
@@ -46,249 +46,74 @@ export type TableDef<
|
|
46
46
|
sqliteDef: TSqliteDef
|
47
47
|
options: TOptions
|
48
48
|
// Derived from `sqliteDef`, so only exposed for convenience
|
49
|
-
|
49
|
+
rowSchema: TSchema
|
50
50
|
insertSchema: SqliteDsl.InsertStructSchemaForColumns<TSqliteDef['columns']>
|
51
|
-
query: QueryBuilder<ReadonlyArray<Schema.Schema.Type<TSchema>>, TableDefBase<TSqliteDef & {}, TOptions>>
|
51
|
+
// query: QueryBuilder<ReadonlyArray<Schema.Schema.Type<TSchema>>, TableDefBase<TSqliteDef & {}, TOptions>>
|
52
52
|
readonly Type: Schema.Schema.Type<TSchema>
|
53
53
|
readonly Encoded: Schema.Schema.Encoded<TSchema>
|
54
|
-
} &
|
55
|
-
? DerivedMutationHelperFns<TSqliteDef['columns'], TOptions>
|
56
|
-
: {})
|
54
|
+
} & QueryBuilder<ReadonlyArray<Schema.Schema.Type<TSchema>>, TableDefBase<TSqliteDef & {}, TOptions>>
|
57
55
|
|
58
56
|
export type TableOptionsInput = Partial<{
|
59
57
|
indexes: SqliteDsl.Index[]
|
60
|
-
disableAutomaticIdColumn: boolean
|
61
|
-
isSingleton: boolean
|
62
|
-
deriveMutations:
|
63
|
-
| boolean
|
64
|
-
| {
|
65
|
-
clientOnly?: boolean
|
66
|
-
}
|
67
58
|
}>
|
68
59
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
: TColumns extends SqliteDsl.ColumnDefinition<any, any>
|
73
|
-
? { value: TColumns }
|
74
|
-
: never
|
75
|
-
|
76
|
-
type ValidateTableOptionsInput<
|
77
|
-
TColumns extends SqliteDsl.Columns | SqliteDsl.ColumnDefinition<any, any>,
|
78
|
-
TOptionsInput extends TableOptionsInput,
|
79
|
-
TPassthroughIfValid,
|
80
|
-
> =
|
81
|
-
SqliteDsl.FromColumns.RequiresInsertValues<ToColumns<TColumns>> extends true
|
82
|
-
? TOptionsInput['isSingleton'] extends true
|
83
|
-
? 'Error: To use `isSingleton: true` with this table, each column must have a default value or be nullable'
|
84
|
-
: TPassthroughIfValid
|
85
|
-
: TPassthroughIfValid
|
60
|
+
export namespace TableDef {
|
61
|
+
export type Any = TableDef<any, any>
|
62
|
+
}
|
86
63
|
|
87
64
|
export type TableOptions = {
|
88
|
-
/**
|
89
|
-
* Setting this to true will have the following consequences:
|
90
|
-
* - An `id` column will be added with `primaryKey: true` and `"singleton"` as default value and only allowed value
|
91
|
-
* - LiveStore will automatically create the singleton row when booting up
|
92
|
-
* - LiveStore will fail if there is already a column defined with `primaryKey: true`
|
93
|
-
*
|
94
|
-
* @default false
|
95
|
-
*/
|
96
|
-
readonly isSingleton: boolean
|
97
|
-
|
98
|
-
readonly disableAutomaticIdColumn: boolean
|
99
|
-
|
100
|
-
/**
|
101
|
-
* Setting this to true will automatically derive insert, update and delete mutations for this table. Example:
|
102
|
-
*
|
103
|
-
* ```ts
|
104
|
-
* const todos = table('todos', { ... }, { deriveMutations: true })
|
105
|
-
* todos.insert({ id: '1', text: 'Hello' })
|
106
|
-
* ```
|
107
|
-
*
|
108
|
-
* This is also a prerequisite for using the `useRow`, `useAtom` and `rowQuery` APIs.
|
109
|
-
*
|
110
|
-
* Important: When using this option, make sure you're following the "Rules of mutations" for the table schema.
|
111
|
-
*/
|
112
|
-
readonly deriveMutations:
|
113
|
-
| { enabled: false }
|
114
|
-
| {
|
115
|
-
enabled: true
|
116
|
-
/**
|
117
|
-
* When set to true, the mutations won't be synced over the network
|
118
|
-
*/
|
119
|
-
clientOnly: boolean
|
120
|
-
}
|
121
|
-
|
122
65
|
/** Derived based on whether the table definition has one or more columns (besides the `id` column) */
|
123
|
-
readonly
|
124
|
-
|
125
|
-
/**
|
126
|
-
* Derived based on whether the table definition has one or more columns (besides the `id` column) that require
|
127
|
-
* insert values (i.e. are not nullable and don't have a default value)
|
128
|
-
*
|
129
|
-
* `isSingleton` tables always imply `requiresInsertValues: false`
|
130
|
-
*/
|
131
|
-
readonly requiredInsertColumnNames: string
|
66
|
+
readonly isClientDocumentTable: boolean
|
132
67
|
}
|
133
68
|
|
134
69
|
export const table = <
|
135
70
|
TName extends string,
|
136
71
|
TColumns extends SqliteDsl.Columns | SqliteDsl.ColumnDefinition<any, any>,
|
137
|
-
TOptionsInput extends TableOptionsInput = TableOptionsInput,
|
72
|
+
const TOptionsInput extends TableOptionsInput = TableOptionsInput,
|
138
73
|
>(
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
TableDef<
|
146
|
-
SqliteTableDefForInput<TName, TColumns, WithDefaults<TOptionsInput, TColumns>>,
|
147
|
-
WithDefaults<TOptionsInput, TColumns>
|
148
|
-
>
|
149
|
-
> => {
|
74
|
+
args: {
|
75
|
+
name: TName
|
76
|
+
columns: TColumns
|
77
|
+
} & Partial<TOptionsInput>,
|
78
|
+
): TableDef<SqliteTableDefForInput<TName, TColumns>, WithDefaults<TColumns>> => {
|
79
|
+
const { name, columns: columnOrColumns, ...options } = args
|
150
80
|
const tablePath = name
|
151
81
|
|
152
82
|
const options_: TableOptions = {
|
153
|
-
|
154
|
-
disableAutomaticIdColumn: options?.disableAutomaticIdColumn ?? false,
|
155
|
-
deriveMutations:
|
156
|
-
options?.deriveMutations === true
|
157
|
-
? { enabled: true as const, clientOnly: false }
|
158
|
-
: options?.deriveMutations === false
|
159
|
-
? { enabled: false as const }
|
160
|
-
: options?.deriveMutations === undefined
|
161
|
-
? { enabled: false as const }
|
162
|
-
: { enabled: true as const, clientOnly: options.deriveMutations.clientOnly ?? false },
|
163
|
-
isSingleColumn: SqliteDsl.isColumnDefinition(columnOrColumns) === true,
|
164
|
-
requiredInsertColumnNames: 'type-level-only',
|
83
|
+
isClientDocumentTable: false,
|
165
84
|
}
|
166
85
|
|
167
86
|
const columns = (
|
168
87
|
SqliteDsl.isColumnDefinition(columnOrColumns) ? { value: columnOrColumns } : columnOrColumns
|
169
88
|
) as SqliteDsl.Columns
|
170
89
|
|
171
|
-
if (options_.disableAutomaticIdColumn === true) {
|
172
|
-
if (columns.id === undefined && options_.isSingleton === true) {
|
173
|
-
shouldNeverHappen(
|
174
|
-
`Cannot create table ${name} with "isSingleton: true" because there is no column with name "id" and "disableAutomaticIdColumn: true" is set`,
|
175
|
-
)
|
176
|
-
}
|
177
|
-
} else if (columns.id === undefined && ReadonlyRecord.some(columns, (_) => _.primaryKey === true) === false) {
|
178
|
-
if (options_.isSingleton) {
|
179
|
-
columns.id = SqliteDsl.text({ schema: Schema.Literal('singleton'), primaryKey: true, default: 'singleton' })
|
180
|
-
} else {
|
181
|
-
columns.id = SqliteDsl.text({ primaryKey: true })
|
182
|
-
}
|
183
|
-
}
|
184
|
-
|
185
90
|
const sqliteDef = SqliteDsl.table(tablePath, columns, options?.indexes ?? [])
|
186
91
|
|
187
|
-
|
188
|
-
if (options_.isSingleton) {
|
189
|
-
for (const column of sqliteDef.ast.columns) {
|
190
|
-
if (column.nullable === false && column.default._tag === 'None') {
|
191
|
-
shouldNeverHappen(
|
192
|
-
`When creating a singleton table, each column must be either nullable or have a default value. Column '${column.name}' is neither.`,
|
193
|
-
)
|
194
|
-
}
|
195
|
-
}
|
196
|
-
}
|
197
|
-
|
198
|
-
const isSingleColumn = SqliteDsl.isColumnDefinition(columnOrColumns) === true
|
199
|
-
|
200
|
-
const schema = SqliteDsl.structSchemaForTable(sqliteDef)
|
92
|
+
const rowSchema = SqliteDsl.structSchemaForTable(sqliteDef)
|
201
93
|
const insertSchema = SqliteDsl.insertStructSchemaForTable(sqliteDef)
|
202
94
|
const tableDef = {
|
203
95
|
sqliteDef,
|
204
96
|
options: options_,
|
205
|
-
|
97
|
+
rowSchema,
|
206
98
|
insertSchema,
|
207
99
|
} satisfies TableDefBase
|
208
100
|
|
209
101
|
const query = makeQueryBuilder(tableDef)
|
210
|
-
//
|
102
|
+
// tableDef.query = query
|
211
103
|
|
212
104
|
// NOTE we're currently patching the existing tableDef object
|
213
105
|
// as it's being used as part of the query builder API
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
if (tableHasDerivedMutations(tableDef)) {
|
218
|
-
const derivedMutationDefs = makeDerivedMutationDefsForTable(tableDef)
|
219
|
-
|
220
|
-
tableDef.insert = (valuesOrValue: any) => {
|
221
|
-
if (isSingleColumn && options_.isSingleton) {
|
222
|
-
return derivedMutationDefs.insert({ id: 'singleton', value: { value: valuesOrValue } })
|
223
|
-
} else {
|
224
|
-
return derivedMutationDefs.insert(valuesOrValue as any)
|
225
|
-
}
|
226
|
-
}
|
227
|
-
|
228
|
-
tableDef.update = (argsOrValues: any) => {
|
229
|
-
if (isSingleColumn && options_.isSingleton) {
|
230
|
-
return derivedMutationDefs.update({ where: { id: 'singleton' }, values: { value: argsOrValues } as any })
|
231
|
-
} else {
|
232
|
-
return derivedMutationDefs.update(argsOrValues as any)
|
233
|
-
}
|
234
|
-
}
|
235
|
-
|
236
|
-
tableDef.delete = (args: any) => derivedMutationDefs.delete(args)
|
106
|
+
for (const key of Object.keys(query)) {
|
107
|
+
// @ts-expect-error TODO properly implement this
|
108
|
+
tableDef[key] = query[key]
|
237
109
|
}
|
238
110
|
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
tableDef: TTableDef,
|
244
|
-
): tableDef is TTableDef & {
|
245
|
-
options: { deriveMutations: { enabled: true; clientOnly: boolean } }
|
246
|
-
} & DerivedMutationHelperFns<TTableDef['sqliteDef']['columns'], TTableDef['options']> =>
|
247
|
-
tableDef.options.deriveMutations.enabled === true
|
248
|
-
|
249
|
-
export const tableIsSingleton = <TTableDef extends TableDefBase>(
|
250
|
-
tableDef: TTableDef,
|
251
|
-
): tableDef is TTableDef & { options: { isSingleton: true } } => tableDef.options.isSingleton === true
|
252
|
-
|
253
|
-
export type PrettifyFlat<T> = T extends infer U ? { [K in keyof U]: U[K] } : never
|
111
|
+
// @ts-expect-error TODO properly type this
|
112
|
+
tableDef[QueryBuilderAstSymbol] = query[QueryBuilderAstSymbol]
|
113
|
+
// @ts-expect-error TODO properly type this
|
114
|
+
tableDef[QueryBuilderTypeId] = query[QueryBuilderTypeId]
|
254
115
|
|
255
|
-
|
256
|
-
TName extends string,
|
257
|
-
TColumns extends SqliteDsl.Columns | SqliteDsl.ColumnDefinition<any, any>,
|
258
|
-
TOptions extends TableOptions,
|
259
|
-
> = SqliteDsl.TableDefinition<TName, PrettifyFlat<WithId<ToColumns<TColumns>, TOptions>>>
|
260
|
-
|
261
|
-
type WithId<TColumns extends SqliteDsl.Columns, TOptions extends TableOptions> = TColumns &
|
262
|
-
('id' extends keyof TColumns
|
263
|
-
? {}
|
264
|
-
: TOptions['disableAutomaticIdColumn'] extends true
|
265
|
-
? {}
|
266
|
-
: TOptions['isSingleton'] extends true
|
267
|
-
? {
|
268
|
-
id: SqliteDsl.ColumnDefinition<'singleton', 'singleton'>
|
269
|
-
}
|
270
|
-
: {
|
271
|
-
id: SqliteDsl.ColumnDefinition<string, string>
|
272
|
-
})
|
273
|
-
|
274
|
-
type WithDefaults<
|
275
|
-
TOptionsInput extends TableOptionsInput,
|
276
|
-
TColumns extends SqliteDsl.Columns | SqliteDsl.ColumnDefinition<any, any>,
|
277
|
-
> = {
|
278
|
-
isSingleton: TOptionsInput['isSingleton'] extends true ? true : false
|
279
|
-
disableAutomaticIdColumn: TOptionsInput['disableAutomaticIdColumn'] extends true ? true : false
|
280
|
-
deriveMutations: TOptionsInput['deriveMutations'] extends true
|
281
|
-
? { enabled: true; clientOnly: false }
|
282
|
-
: TOptionsInput['deriveMutations'] extends false
|
283
|
-
? { enabled: false }
|
284
|
-
: TOptionsInput['deriveMutations'] extends { clientOnly: boolean }
|
285
|
-
? {
|
286
|
-
enabled: true
|
287
|
-
clientOnly: TOptionsInput['deriveMutations']['clientOnly'] extends true ? true : false
|
288
|
-
}
|
289
|
-
: never
|
290
|
-
isSingleColumn: SqliteDsl.IsSingleColumn<TColumns>
|
291
|
-
requiredInsertColumnNames: SqliteDsl.FromColumns.RequiredInsertColumnNames<ToColumns<TColumns>>
|
116
|
+
return tableDef as any
|
292
117
|
}
|
293
118
|
|
294
119
|
export namespace FromTable {
|
@@ -351,3 +176,22 @@ export namespace FromColumns {
|
|
351
176
|
|
352
177
|
export type InsertRowDecoded<TColumns extends SqliteDsl.Columns> = SqliteDsl.FromColumns.InsertRowDecoded<TColumns>
|
353
178
|
}
|
179
|
+
|
180
|
+
type SqliteTableDefForInput<
|
181
|
+
TName extends string,
|
182
|
+
TColumns extends SqliteDsl.Columns | SqliteDsl.ColumnDefinition<any, any>,
|
183
|
+
> = SqliteDsl.TableDefinition<TName, PrettifyFlat<ToColumns<TColumns>>>
|
184
|
+
|
185
|
+
type WithDefaults<TColumns extends SqliteDsl.Columns | SqliteDsl.ColumnDefinition<any, any>> = {
|
186
|
+
isClientDocumentTable: false
|
187
|
+
requiredInsertColumnNames: SqliteDsl.FromColumns.RequiredInsertColumnNames<ToColumns<TColumns>>
|
188
|
+
}
|
189
|
+
|
190
|
+
export type PrettifyFlat<T> = T extends infer U ? { [K in keyof U]: U[K] } : never
|
191
|
+
|
192
|
+
type ToColumns<TColumns extends SqliteDsl.Columns | SqliteDsl.ColumnDefinition<any, any>> =
|
193
|
+
TColumns extends SqliteDsl.Columns
|
194
|
+
? TColumns
|
195
|
+
: TColumns extends SqliteDsl.ColumnDefinition<any, any>
|
196
|
+
? { value: TColumns }
|
197
|
+
: never
|
@@ -33,12 +33,12 @@ export const dbSelect = <T>(db: SqliteDb, queryStr: string, bindValues?: ParamsO
|
|
33
33
|
}
|
34
34
|
|
35
35
|
export interface SchemaManager {
|
36
|
-
|
36
|
+
getEventDefInfos: () => ReadonlyArray<EventDefInfo>
|
37
37
|
|
38
|
-
|
38
|
+
setEventDefInfo: (eventDefInfo: EventDefInfo) => void
|
39
39
|
}
|
40
40
|
|
41
|
-
export type
|
42
|
-
|
41
|
+
export type EventDefInfo = {
|
42
|
+
eventName: string
|
43
43
|
schemaHash: number
|
44
44
|
}
|
@@ -4,12 +4,12 @@ import { Effect, Schema as EffectSchema } from '@livestore/utils/effect'
|
|
4
4
|
import type { MigrationsReport, MigrationsReportEntry, SqliteDb, UnexpectedError } from '../adapter-types.js'
|
5
5
|
import { SqliteAst, SqliteDsl } from '../schema/db-schema/mod.js'
|
6
6
|
import type { LiveStoreSchema } from '../schema/mod.js'
|
7
|
-
import type {
|
7
|
+
import type { SchemaEventDefsMetaRow, SchemaMetaRow } from '../schema/system-tables.js'
|
8
8
|
import {
|
9
|
+
SCHEMA_EVENT_DEFS_META_TABLE,
|
9
10
|
SCHEMA_META_TABLE,
|
10
|
-
|
11
|
+
schemaEventDefsMetaTable,
|
11
12
|
schemaMetaTable,
|
12
|
-
schemaMutationsMetaTable,
|
13
13
|
systemTables,
|
14
14
|
} from '../schema/system-tables.js'
|
15
15
|
import { sql } from '../util.js'
|
@@ -23,20 +23,19 @@ export const makeSchemaManager = (db: SqliteDb): Effect.Effect<SchemaManager> =>
|
|
23
23
|
Effect.gen(function* () {
|
24
24
|
yield* migrateTable({
|
25
25
|
db,
|
26
|
-
tableAst:
|
26
|
+
tableAst: schemaEventDefsMetaTable.sqliteDef.ast,
|
27
27
|
behaviour: 'create-if-not-exists',
|
28
28
|
})
|
29
29
|
|
30
30
|
return {
|
31
|
-
|
32
|
-
dbSelect<SchemaMutationsMetaRow>(db, sql`SELECT * FROM ${SCHEMA_MUTATIONS_META_TABLE}`),
|
31
|
+
getEventDefInfos: () => dbSelect<SchemaEventDefsMetaRow>(db, sql`SELECT * FROM ${SCHEMA_EVENT_DEFS_META_TABLE}`),
|
33
32
|
|
34
|
-
|
33
|
+
setEventDefInfo: (info) => {
|
35
34
|
dbExecute(
|
36
35
|
db,
|
37
|
-
sql`INSERT OR REPLACE INTO ${
|
36
|
+
sql`INSERT OR REPLACE INTO ${SCHEMA_EVENT_DEFS_META_TABLE} (eventName, schemaHash, updatedAt) VALUES ($eventName, $schemaHash, $updatedAt)`,
|
38
37
|
{
|
39
|
-
|
38
|
+
eventName: info.eventName,
|
40
39
|
schemaHash: info.schemaHash,
|
41
40
|
updatedAt: new Date().toISOString(),
|
42
41
|
},
|
@@ -1,63 +1,61 @@
|
|
1
1
|
import { Effect, Schema } from '@livestore/utils/effect'
|
2
2
|
|
3
3
|
import { UnexpectedError } from '../adapter-types.js'
|
4
|
+
import type { EventDef } from '../schema/EventDef.js'
|
4
5
|
import type { LiveStoreSchema } from '../schema/mod.js'
|
5
|
-
import type {
|
6
|
-
import type { MutationDefInfo, SchemaManager } from './common.js'
|
6
|
+
import type { EventDefInfo, SchemaManager } from './common.js'
|
7
7
|
|
8
8
|
export const validateSchema = (schema: LiveStoreSchema, schemaManager: SchemaManager) =>
|
9
9
|
Effect.gen(function* () {
|
10
10
|
// Validate mutation definitions
|
11
|
-
const
|
11
|
+
const registeredEventDefInfos = schemaManager.getEventDefInfos()
|
12
12
|
|
13
|
-
const
|
14
|
-
(
|
13
|
+
const missingEventDefs = registeredEventDefInfos.filter(
|
14
|
+
(registeredEventDefInfo) => !schema.eventsDefsMap.has(registeredEventDefInfo.eventName),
|
15
15
|
)
|
16
16
|
|
17
|
-
if (
|
17
|
+
if (missingEventDefs.length > 0) {
|
18
18
|
yield* new UnexpectedError({
|
19
|
-
cause: `Missing mutation definitions: ${
|
19
|
+
cause: `Missing mutation definitions: ${missingEventDefs.map((info) => info.eventName).join(', ')}`,
|
20
20
|
})
|
21
21
|
}
|
22
22
|
|
23
|
-
for (const [,
|
24
|
-
const
|
25
|
-
(info) => info.mutationName === mutationDef.name,
|
26
|
-
)
|
23
|
+
for (const [, eventDef] of schema.eventsDefsMap) {
|
24
|
+
const registeredEventDefInfo = registeredEventDefInfos.find((info) => info.eventName === eventDef.name)
|
27
25
|
|
28
|
-
|
26
|
+
validateEventDef(eventDef, schemaManager, registeredEventDefInfo)
|
29
27
|
}
|
30
28
|
|
31
29
|
// Validate table schemas
|
32
30
|
})
|
33
31
|
|
34
|
-
export const
|
35
|
-
|
32
|
+
export const validateEventDef = (
|
33
|
+
eventDef: EventDef.AnyWithoutFn,
|
36
34
|
schemaManager: SchemaManager,
|
37
|
-
|
35
|
+
registeredEventDefInfo: EventDefInfo | undefined,
|
38
36
|
) => {
|
39
|
-
const schemaHash = Schema.hash(
|
37
|
+
const schemaHash = Schema.hash(eventDef.schema)
|
40
38
|
|
41
|
-
if (
|
42
|
-
schemaManager.
|
39
|
+
if (registeredEventDefInfo === undefined) {
|
40
|
+
schemaManager.setEventDefInfo({
|
43
41
|
schemaHash,
|
44
|
-
|
42
|
+
eventName: eventDef.name,
|
45
43
|
})
|
46
44
|
|
47
45
|
return
|
48
46
|
}
|
49
47
|
|
50
|
-
if (schemaHash ===
|
48
|
+
if (schemaHash === registeredEventDefInfo.schemaHash) return
|
51
49
|
|
52
50
|
// TODO bring back some form of schema compatibility check (see https://github.com/livestorejs/livestore/issues/69)
|
53
|
-
// const newSchemaIsCompatibleWithOldSchema = Schema.isSubType(jsonSchemaDefFromMgmtStore,
|
51
|
+
// const newSchemaIsCompatibleWithOldSchema = Schema.isSubType(jsonSchemaDefFromMgmtStore, eventDef.schema)
|
54
52
|
|
55
53
|
// if (!newSchemaIsCompatibleWithOldSchema) {
|
56
|
-
// shouldNeverHappen(`Schema for mutation ${
|
54
|
+
// shouldNeverHappen(`Schema for mutation ${eventDef.name} has changed in an incompatible way`)
|
57
55
|
// }
|
58
56
|
|
59
|
-
schemaManager.
|
57
|
+
schemaManager.setEventDefInfo({
|
60
58
|
schemaHash,
|
61
|
-
|
59
|
+
eventName: eventDef.name,
|
62
60
|
})
|
63
61
|
}
|