@livestore/common 0.0.58-dev.9 → 0.1.0-dev.2
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/adapter-types.d.ts +21 -12
- package/dist/adapter-types.d.ts.map +1 -1
- package/dist/adapter-types.js +10 -0
- package/dist/adapter-types.js.map +1 -1
- package/dist/bounded-collections.js.map +1 -1
- package/dist/derived-mutations.d.ts +1 -1
- package/dist/derived-mutations.d.ts.map +1 -1
- package/dist/derived-mutations.js +4 -2
- package/dist/derived-mutations.js.map +1 -1
- package/dist/devtools/devtools-messages.d.ts +1 -1
- package/dist/devtools/devtools-messages.js +1 -1
- package/dist/devtools/devtools-messages.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/mutation.d.ts +1 -0
- package/dist/mutation.d.ts.map +1 -1
- package/dist/mutation.js +23 -0
- package/dist/mutation.js.map +1 -1
- package/dist/query-info.d.ts +4 -3
- package/dist/query-info.d.ts.map +1 -1
- package/dist/query-info.js.map +1 -1
- package/dist/schema/index.d.ts +2 -2
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +1 -1
- package/dist/schema/index.js.map +1 -1
- package/dist/schema/mutations.d.ts +1 -0
- package/dist/schema/mutations.d.ts.map +1 -1
- package/dist/schema/mutations.js +1 -0
- package/dist/schema/mutations.js.map +1 -1
- package/dist/schema/schema-helpers.js +1 -1
- package/dist/schema/schema-helpers.js.map +1 -1
- package/dist/schema/system-tables.d.ts +1 -10
- package/dist/schema/system-tables.d.ts.map +1 -1
- package/dist/schema/system-tables.js +2 -4
- package/dist/schema/system-tables.js.map +1 -1
- package/dist/schema/table-def.d.ts +3 -3
- package/dist/schema/table-def.d.ts.map +1 -1
- package/dist/schema/table-def.js +1 -1
- package/dist/schema/table-def.js.map +1 -1
- package/dist/schema-management/migrations.d.ts +1 -1
- package/dist/schema-management/migrations.d.ts.map +1 -1
- package/dist/schema-management/migrations.js +1 -1
- package/dist/schema-management/migrations.js.map +1 -1
- package/dist/sql-queries/sql-queries.d.ts +10 -3
- package/dist/sql-queries/sql-queries.d.ts.map +1 -1
- package/dist/sql-queries/sql-queries.js +8 -7
- package/dist/sql-queries/sql-queries.js.map +1 -1
- package/dist/sql-queries/sql-query-builder.d.ts +1 -1
- package/dist/sql-queries/sql-query-builder.d.ts.map +1 -1
- package/dist/sql-queries/types.d.ts +1 -1
- package/dist/sql-queries/types.d.ts.map +1 -1
- package/dist/sync/next/facts.d.ts.map +1 -1
- package/dist/sync/next/facts.js +2 -1
- package/dist/sync/next/facts.js.map +1 -1
- package/dist/sync/next-mutation-event-id-pair.d.ts +14 -0
- package/dist/sync/next-mutation-event-id-pair.d.ts.map +1 -0
- package/dist/sync/next-mutation-event-id-pair.js +13 -0
- package/dist/sync/next-mutation-event-id-pair.js.map +1 -0
- package/dist/version.d.ts +8 -0
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +8 -0
- package/dist/version.js.map +1 -1
- package/package.json +3 -3
- package/src/adapter-types.ts +20 -12
- package/src/bounded-collections.ts +1 -1
- package/src/derived-mutations.ts +5 -5
- package/src/devtools/devtools-messages.ts +1 -1
- package/src/index.ts +1 -0
- package/src/mutation.ts +23 -0
- package/src/query-info.ts +4 -3
- package/src/schema/index.ts +4 -3
- package/src/schema/mutations.ts +4 -0
- package/src/schema/schema-helpers.ts +1 -1
- package/src/schema/system-tables.ts +2 -4
- package/src/schema/table-def.ts +3 -3
- package/src/schema-management/migrations.ts +1 -1
- package/src/sql-queries/sql-queries.ts +21 -10
- package/src/sql-queries/sql-query-builder.ts +1 -1
- package/src/sql-queries/types.ts +1 -1
- package/src/sync/next/facts.ts +2 -1
- package/src/sync/next-mutation-event-id-pair.ts +20 -0
- package/src/version.ts +9 -0
- package/tsconfig.json +1 -1
- package/dist/sync/next/mutation-fixtures.d.ts +0 -73
- package/dist/sync/next/mutation-fixtures.d.ts.map +0 -1
- package/dist/sync/next/mutation-fixtures.js +0 -160
- package/dist/sync/next/mutation-fixtures.js.map +0 -1
package/src/adapter-types.ts
CHANGED
@@ -12,7 +12,7 @@ export interface PreparedStatement {
|
|
12
12
|
sql: string
|
13
13
|
}
|
14
14
|
|
15
|
-
export type
|
15
|
+
export type ClientSession = {
|
16
16
|
/** SQLite database with synchronous API running in the same thread (usually in-memory) */
|
17
17
|
syncDb: SynchronousDatabase
|
18
18
|
/** The coordinator is responsible for persisting the database, syncing etc */
|
@@ -62,8 +62,10 @@ export type BootStatus = typeof BootStatus.Type
|
|
62
62
|
export type Coordinator = {
|
63
63
|
devtools: {
|
64
64
|
enabled: boolean
|
65
|
+
// TODO incorporate sessionId and rethink appHostId
|
65
66
|
appHostId: string
|
66
67
|
}
|
68
|
+
sessionId: string
|
67
69
|
// TODO is exposing the lock status really needed (or only relevant for web adapter?)
|
68
70
|
lockStatus: SubscriptionRef.SubscriptionRef<LockStatus>
|
69
71
|
syncMutations: Stream.Stream<MutationEvent.Any, UnexpectedError>
|
@@ -73,7 +75,7 @@ export type Coordinator = {
|
|
73
75
|
options: { persisted: boolean },
|
74
76
|
): Effect.Effect<void, UnexpectedError>
|
75
77
|
/** Can be called synchronously */
|
76
|
-
|
78
|
+
nextMutationEventIdPair: (opts: { localOnly: boolean }) => Effect.Effect<EventIdPair, UnexpectedError>
|
77
79
|
/** Used to initially get the current mutation event id to use as `parentId` for the next mutation event */
|
78
80
|
getCurrentMutationEventId: Effect.Effect<EventId, UnexpectedError>
|
79
81
|
export: Effect.Effect<Uint8Array | undefined, UnexpectedError>
|
@@ -81,6 +83,18 @@ export type Coordinator = {
|
|
81
83
|
networkStatus: SubscriptionRef.SubscriptionRef<NetworkStatus>
|
82
84
|
}
|
83
85
|
|
86
|
+
/**
|
87
|
+
* Can be used in queries to refer to the current session id.
|
88
|
+
* Will be replaced with the actual session id at runtime
|
89
|
+
*
|
90
|
+
* Example:
|
91
|
+
* ```ts
|
92
|
+
* const query$ = rowQuery(tables.app, SessionIdSymbol)
|
93
|
+
* ```
|
94
|
+
*/
|
95
|
+
export const SessionIdSymbol = Symbol.for('@livestore/session-id')
|
96
|
+
export type SessionIdSymbol = typeof SessionIdSymbol
|
97
|
+
|
84
98
|
export type LockStatus = 'has-lock' | 'no-lock'
|
85
99
|
|
86
100
|
/**
|
@@ -96,15 +110,9 @@ export const EventId = Schema.Struct({
|
|
96
110
|
local: Schema.Number,
|
97
111
|
}).annotations({ title: 'LiveStore.EventId' })
|
98
112
|
|
99
|
-
export
|
113
|
+
export type EventIdPair = { id: EventId; parentId: EventId }
|
100
114
|
|
101
|
-
export
|
102
|
-
_tag: 'BootDb'
|
103
|
-
execute(queryStr: string, bindValues?: PreparedBindValues): void
|
104
|
-
mutate: <const TMutationArg extends ReadonlyArray<MutationEvent.PartialAny>>(...list: TMutationArg) => void
|
105
|
-
select<T>(queryStr: string, bindValues?: PreparedBindValues): ReadonlyArray<T>
|
106
|
-
txn(callback: () => void): void
|
107
|
-
}
|
115
|
+
export const ROOT_ID = { global: -1, local: 0 } satisfies EventId
|
108
116
|
|
109
117
|
export class UnexpectedError extends Schema.TaggedError<UnexpectedError>()('LiveStore.UnexpectedError', {
|
110
118
|
cause: Schema.Defect,
|
@@ -190,11 +198,11 @@ export type ConnectDevtoolsToStore = (
|
|
190
198
|
storeDevtoolsChannel: StoreDevtoolsChannel,
|
191
199
|
) => Effect.Effect<void, UnexpectedError, Scope.Scope>
|
192
200
|
|
193
|
-
export type
|
201
|
+
export type Adapter = (opts: {
|
194
202
|
schema: LiveStoreSchema
|
195
203
|
storeId: string
|
196
204
|
devtoolsEnabled: boolean
|
197
205
|
bootStatusQueue: Queue.Queue<BootStatus>
|
198
206
|
shutdown: (cause: Cause.Cause<any>) => Effect.Effect<void>
|
199
207
|
connectDevtoolsToStore: ConnectDevtoolsToStore
|
200
|
-
}) => Effect.Effect<
|
208
|
+
}) => Effect.Effect<ClientSession, UnexpectedError, Scope.Scope>
|
@@ -16,7 +16,7 @@ export class BoundMap<K, V> {
|
|
16
16
|
this.#map.set(key, value)
|
17
17
|
// console.log(this.#map.size, this.#sizeLimit);
|
18
18
|
if (this.#map.size > this.#sizeLimit) {
|
19
|
-
const firstKey = this.#map.keys().next().value
|
19
|
+
const firstKey = this.#map.keys().next().value as K
|
20
20
|
const deletedValue = this.#map.get(firstKey)!
|
21
21
|
this.#map.delete(firstKey)
|
22
22
|
if (this.onEvict) {
|
package/src/derived-mutations.ts
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
+
import type { SqliteDsl } from '@livestore/db-schema'
|
1
2
|
import type { GetValForKey } from '@livestore/utils'
|
2
3
|
import { ReadonlyRecord, Schema } from '@livestore/utils/effect'
|
3
|
-
import type { SqliteDsl } from 'effect-db-schema'
|
4
4
|
|
5
5
|
import type { MutationEvent } from './schema/mutations.js'
|
6
6
|
import { defineMutation } from './schema/mutations.js'
|
@@ -38,9 +38,9 @@ export const deriveCreateMutationDef = <
|
|
38
38
|
(col) => col.nullable === false && col.default._tag === 'None',
|
39
39
|
)
|
40
40
|
|
41
|
-
const insertSchema = Schema.Struct(ReadonlyRecord.map(requiredColumns, (col) => col.schema))
|
42
|
-
Schema.extend(Schema.partial(Schema.Struct(ReadonlyRecord.map(optionalFields, (col) => col.schema))))
|
43
|
-
|
41
|
+
const insertSchema = Schema.Struct(ReadonlyRecord.map(requiredColumns, (col) => col.schema))
|
42
|
+
.pipe(Schema.extend(Schema.partial(Schema.Struct(ReadonlyRecord.map(optionalFields, (col) => col.schema)))))
|
43
|
+
.annotations({ title: `${tableName}:Insert` })
|
44
44
|
|
45
45
|
return defineMutation(
|
46
46
|
`_Derived_Create_${tableName}`,
|
@@ -76,7 +76,7 @@ export const deriveUpdateMutationDef = <
|
|
76
76
|
Schema.Struct({
|
77
77
|
where: Schema.partial(table.schema),
|
78
78
|
values: Schema.partial(table.schema),
|
79
|
-
}),
|
79
|
+
}).annotations({ title: `${tableName}:Update` }),
|
80
80
|
({ where, values }) => {
|
81
81
|
const [sql, bindValues] = updateRows({
|
82
82
|
tableName: table.sqliteDef.name,
|
@@ -101,7 +101,7 @@ export class LiveQueriesSubscribe extends LSDReqResMessage('LSD.LiveQueriesSubsc
|
|
101
101
|
export class LiveQueriesUnsubscribe extends LSDReqResMessage('LSD.LiveQueriesUnsubscribe', {}) {}
|
102
102
|
|
103
103
|
export class SerializedLiveQuery extends Schema.Struct({
|
104
|
-
_tag: Schema.Literal('
|
104
|
+
_tag: Schema.Literal('computed', 'sql', 'graphql'),
|
105
105
|
id: Schema.Number,
|
106
106
|
label: Schema.String,
|
107
107
|
runs: Schema.Number,
|
package/src/index.ts
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
export * from './schema/system-tables.js'
|
2
2
|
export * from './util.js'
|
3
3
|
export * from './adapter-types.js'
|
4
|
+
export * from './sync/next-mutation-event-id-pair.js'
|
4
5
|
export * from './schema-management/migrations.js'
|
5
6
|
export * from './mutation.js'
|
6
7
|
export * from './init-singleton-tables.js'
|
package/src/mutation.ts
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
import { memoizeByRef, shouldNeverHappen } from '@livestore/utils'
|
2
2
|
import { Schema } from '@livestore/utils/effect'
|
3
3
|
|
4
|
+
import { SessionIdSymbol } from './adapter-types.js'
|
4
5
|
import type { LiveStoreSchema } from './schema/index.js'
|
5
6
|
import type { MutationDef, MutationEvent } from './schema/mutations.js'
|
6
7
|
import type { PreparedBindValues } from './util.js'
|
@@ -67,3 +68,25 @@ export const makeShouldExcludeMutationFromLog = memoizeByRef((schema: LiveStoreS
|
|
67
68
|
return execArgsArr.some((_) => _.statementSql.includes('__livestore'))
|
68
69
|
}
|
69
70
|
})
|
71
|
+
|
72
|
+
// NOTE we should explore whether there is a more elegant solution
|
73
|
+
// e.g. by leveraging the schema to replace the sessionIdSymbol
|
74
|
+
export const replaceSessionIdSymbol = (bindValues: Record<string, unknown>, sessionId: string) => {
|
75
|
+
deepReplaceValue(bindValues, SessionIdSymbol, sessionId)
|
76
|
+
}
|
77
|
+
|
78
|
+
const deepReplaceValue = <S, R>(input: any, searchValue: S, replaceValue: R): void => {
|
79
|
+
if (Array.isArray(input)) {
|
80
|
+
for (const i in input) {
|
81
|
+
deepReplaceValue(input[i], searchValue, replaceValue)
|
82
|
+
}
|
83
|
+
} else if (typeof input === 'object' && input !== null) {
|
84
|
+
for (const key in input) {
|
85
|
+
if (input[key] === searchValue) {
|
86
|
+
input[key] = replaceValue
|
87
|
+
} else {
|
88
|
+
deepReplaceValue(input[key], searchValue, replaceValue)
|
89
|
+
}
|
90
|
+
}
|
91
|
+
}
|
92
|
+
}
|
package/src/query-info.ts
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
import type { Schema } from '@livestore/utils/effect'
|
2
2
|
|
3
|
+
import type { SessionIdSymbol } from './adapter-types.js'
|
3
4
|
import type { DbSchema } from './schema/index.js'
|
4
5
|
|
5
6
|
/**
|
@@ -21,7 +22,7 @@ export type QueryInfoNone = {
|
|
21
22
|
export type QueryInfoRow<TTableDef extends DbSchema.TableDef> = {
|
22
23
|
_tag: 'Row'
|
23
24
|
table: TTableDef
|
24
|
-
id: string
|
25
|
+
id: string | SessionIdSymbol
|
25
26
|
}
|
26
27
|
|
27
28
|
export type QueryInfoCol<
|
@@ -30,14 +31,14 @@ export type QueryInfoCol<
|
|
30
31
|
> = {
|
31
32
|
_tag: 'Col'
|
32
33
|
table: TTableDef
|
33
|
-
id: string
|
34
|
+
id: string | SessionIdSymbol
|
34
35
|
column: TColName
|
35
36
|
}
|
36
37
|
|
37
38
|
export type QueryInfoColJsonValue<TTableDef extends DbSchema.TableDef, TColName extends GetJsonColumn<TTableDef>> = {
|
38
39
|
_tag: 'ColJsonValue'
|
39
40
|
table: TTableDef
|
40
|
-
id: string
|
41
|
+
id: string | SessionIdSymbol
|
41
42
|
column: TColName
|
42
43
|
/**
|
43
44
|
* example: `$.tabs[3].items[2]` (`$` referring to the column value)
|
package/src/schema/index.ts
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
+
import type { SqliteDsl } from '@livestore/db-schema'
|
2
|
+
import { SqliteAst } from '@livestore/db-schema'
|
1
3
|
import { isReadonlyArray, shouldNeverHappen } from '@livestore/utils'
|
2
|
-
import type { SqliteDsl } from 'effect-db-schema'
|
3
|
-
import { SqliteAst } from 'effect-db-schema'
|
4
4
|
|
5
5
|
import type { MigrationOptions } from '../adapter-types.js'
|
6
6
|
import { makeDerivedMutationDefsForTable } from '../derived-mutations.js'
|
@@ -46,6 +46,7 @@ export type InputSchema = {
|
|
46
46
|
/**
|
47
47
|
* Can be used to isolate multiple LiveStore apps running in the same origin
|
48
48
|
*/
|
49
|
+
// TODO remove this in favour of storeId
|
49
50
|
readonly key?: string
|
50
51
|
}
|
51
52
|
|
@@ -116,7 +117,7 @@ export const makeSchema = <TInputSchema extends InputSchema>(
|
|
116
117
|
} satisfies LiveStoreSchema
|
117
118
|
}
|
118
119
|
|
119
|
-
namespace FromInputSchema {
|
120
|
+
export namespace FromInputSchema {
|
120
121
|
export type DeriveSchema<TInputSchema extends InputSchema> = LiveStoreSchema<
|
121
122
|
DbSchemaFromInputSchemaTables<TInputSchema['tables']>,
|
122
123
|
MutationDefRecordFromInputSchemaMutations<TInputSchema['mutations']>
|
package/src/schema/mutations.ts
CHANGED
@@ -231,6 +231,10 @@ export namespace MutationEvent {
|
|
231
231
|
}[keyof TSchema['_MutationDefMapType']]
|
232
232
|
}
|
233
233
|
|
234
|
+
export const isPartialMutationEvent = (
|
235
|
+
mutationEvent: MutationEvent.Any | MutationEvent.PartialAny,
|
236
|
+
): mutationEvent is MutationEvent.PartialAny => 'id' in mutationEvent === false && 'parentId' in mutationEvent === false
|
237
|
+
|
234
238
|
export type MutationEventSchema<TMutationsDefRecord extends MutationDefRecord> = Schema.Schema<
|
235
239
|
{
|
236
240
|
[K in keyof TMutationsDefRecord]: {
|
@@ -1,6 +1,6 @@
|
|
1
|
+
import { SqliteDsl } from '@livestore/db-schema'
|
1
2
|
import { shouldNeverHappen } from '@livestore/utils'
|
2
3
|
import { pipe, ReadonlyRecord, Schema } from '@livestore/utils/effect'
|
3
|
-
import { SqliteDsl } from 'effect-db-schema'
|
4
4
|
|
5
5
|
import type { TableDef } from './table-def.js'
|
6
6
|
|
@@ -1,5 +1,5 @@
|
|
1
|
+
import { type SqliteAst as __SqliteAst, SqliteDsl } from '@livestore/db-schema'
|
1
2
|
import { Schema } from '@livestore/utils/effect'
|
2
|
-
import { type SqliteAst as __SqliteAst, SqliteDsl } from 'effect-db-schema'
|
3
3
|
|
4
4
|
import type { FromTable } from './table-def.js'
|
5
5
|
import { table } from './table-def.js'
|
@@ -73,14 +73,12 @@ export const mutationLogMetaTable = table(
|
|
73
73
|
mutation: SqliteDsl.text({}),
|
74
74
|
argsJson: SqliteDsl.text({ schema: Schema.parseJson(Schema.Any) }),
|
75
75
|
schemaHash: SqliteDsl.integer({}),
|
76
|
-
/** Local only, used for ordered queries to avoid recursive id traversal */
|
77
|
-
orderKey: SqliteDsl.integer({}),
|
78
76
|
/** ISO date format */
|
79
77
|
createdAt: SqliteDsl.text({}),
|
80
78
|
syncStatus: SqliteDsl.text({ schema: SyncStatus }),
|
81
79
|
syncMetadataJson: SqliteDsl.text({ schema: Schema.parseJson(Schema.Option(Schema.JsonValue)) }),
|
82
80
|
},
|
83
|
-
{ disableAutomaticIdColumn: true, indexes: [
|
81
|
+
{ disableAutomaticIdColumn: true, indexes: [] },
|
84
82
|
)
|
85
83
|
|
86
84
|
export type MutationLogMetaRow = FromTable.RowDecoded<typeof mutationLogMetaTable>
|
package/src/schema/table-def.ts
CHANGED
@@ -1,14 +1,14 @@
|
|
1
|
+
import type { Nullable, PrettifyFlat } from '@livestore/db-schema'
|
2
|
+
import { SqliteDsl } from '@livestore/db-schema'
|
1
3
|
import { shouldNeverHappen } from '@livestore/utils'
|
2
4
|
import { ReadonlyRecord, Schema } from '@livestore/utils/effect'
|
3
|
-
import type { Nullable, PrettifyFlat } from 'effect-db-schema'
|
4
|
-
import { SqliteDsl } from 'effect-db-schema'
|
5
5
|
|
6
6
|
import type { DerivedMutationHelperFns } from '../derived-mutations.js'
|
7
7
|
import { makeDerivedMutationDefsForTable } from '../derived-mutations.js'
|
8
8
|
|
9
9
|
export const { blob, boolean, column, datetime, integer, isColumnDefinition, json, real, text } = SqliteDsl
|
10
10
|
|
11
|
-
export { type SqliteDsl } from '
|
11
|
+
export { type SqliteDsl } from '@livestore/db-schema'
|
12
12
|
|
13
13
|
export type StateType = 'singleton' | 'dynamic'
|
14
14
|
|
@@ -1,6 +1,6 @@
|
|
1
|
+
import { SqliteAst, SqliteDsl } from '@livestore/db-schema'
|
1
2
|
import { memoizeByStringifyArgs } from '@livestore/utils'
|
2
3
|
import { Effect, Schema as EffectSchema } from '@livestore/utils/effect'
|
3
|
-
import { SqliteAst, SqliteDsl } from 'effect-db-schema'
|
4
4
|
|
5
5
|
import type { SynchronousDatabase } from '../adapter-types.js'
|
6
6
|
import type { LiveStoreSchema } from '../schema/index.js'
|
@@ -1,6 +1,6 @@
|
|
1
|
+
import type { SqliteDsl } from '@livestore/db-schema'
|
1
2
|
import { shouldNeverHappen } from '@livestore/utils'
|
2
3
|
import { pipe, ReadonlyArray, Schema, TreeFormatter } from '@livestore/utils/effect'
|
3
|
-
import type { SqliteDsl } from 'effect-db-schema'
|
4
4
|
|
5
5
|
import { sql } from '../util.js'
|
6
6
|
import { objectEntries } from './misc.js'
|
@@ -58,15 +58,26 @@ export const insertRow = <TColumns extends SqliteDsl.Columns>({
|
|
58
58
|
values: ClientTypes.DecodedValuesForColumns<TColumns>
|
59
59
|
options?: { orReplace: boolean }
|
60
60
|
}): [string, BindValues] => {
|
61
|
-
const
|
62
|
-
|
63
|
-
|
61
|
+
const stmt = insertRowPrepared({ tableName, columns, options })
|
62
|
+
|
63
|
+
return [stmt, makeBindValues({ columns, values })]
|
64
|
+
}
|
65
|
+
|
66
|
+
export const insertRowPrepared = <TColumns extends SqliteDsl.Columns>({
|
67
|
+
tableName,
|
68
|
+
columns,
|
69
|
+
options = { orReplace: false },
|
70
|
+
}: {
|
71
|
+
tableName: string
|
72
|
+
columns: TColumns
|
73
|
+
options?: { orReplace: boolean }
|
74
|
+
}): string => {
|
75
|
+
const keysStr = Object.keys(columns).join(', ')
|
76
|
+
const valuesStr = Object.keys(columns)
|
77
|
+
.map((key) => `$${key}`)
|
64
78
|
.join(', ')
|
65
79
|
|
66
|
-
return
|
67
|
-
sql`INSERT ${options.orReplace ? 'OR REPLACE ' : ''}INTO ${tableName} (${keysStr}) VALUES (${valuesStr})`,
|
68
|
-
makeBindValues({ columns, values }),
|
69
|
-
]
|
80
|
+
return sql`INSERT ${options.orReplace ? 'OR REPLACE ' : ''}INTO ${tableName} (${keysStr}) VALUES (${valuesStr})`
|
70
81
|
}
|
71
82
|
|
72
83
|
export const insertRows = <TColumns extends SqliteDsl.Columns>({
|
@@ -243,14 +254,14 @@ export const createTable = ({
|
|
243
254
|
return sql`CREATE TABLE ${tableName} (${columnDefStrs.join(', ')});`
|
244
255
|
}
|
245
256
|
|
246
|
-
export const makeBindValues = <TColumns extends SqliteDsl.Columns, TKeys extends
|
257
|
+
export const makeBindValues = <TColumns extends SqliteDsl.Columns, TKeys extends keyof TColumns>({
|
247
258
|
columns,
|
248
259
|
values,
|
249
260
|
variablePrefix = '',
|
250
261
|
skipNil,
|
251
262
|
}: {
|
252
263
|
columns: TColumns
|
253
|
-
values: Record<TKeys, any
|
264
|
+
values: Partial<Record<TKeys, any>>
|
254
265
|
variablePrefix?: string
|
255
266
|
/** So far only used to prepare `where` statements */
|
256
267
|
skipNil?: boolean
|
package/src/sql-queries/types.ts
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
+
import type { Prettify, SqliteDsl } from '@livestore/db-schema'
|
1
2
|
import type { Schema } from '@livestore/utils/effect'
|
2
|
-
import type { Prettify, SqliteDsl } from 'effect-db-schema'
|
3
3
|
|
4
4
|
export type DecodedValuesForTableAll<TSchema extends SqliteDsl.DbSchema, TTableName extends keyof TSchema> = {
|
5
5
|
[K in keyof GetColumns<TSchema, TTableName>]: Schema.Schema.Type<GetColumn<TSchema, TTableName, K>['schema']>
|
package/src/sync/next/facts.ts
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import {
|
1
|
+
import { notYetImplemented } from '@livestore/utils'
|
2
2
|
|
3
3
|
import type { EventId } from '../../adapter-types.js'
|
4
4
|
import type {
|
@@ -8,6 +8,7 @@ import type {
|
|
8
8
|
MutationEventFactsGroup,
|
9
9
|
MutationEventFactsSnapshot,
|
10
10
|
} from '../../schema/mutations.js'
|
11
|
+
import { graphologyDag } from './graphology_.js'
|
11
12
|
import { EMPTY_FACT_VALUE, type HistoryDag, type HistoryDagNode } from './history-dag.js'
|
12
13
|
|
13
14
|
export const factsSnapshotForEvents = (events: HistoryDagNode[], endEventId: EventId): MutationEventFactsSnapshot => {
|
@@ -0,0 +1,20 @@
|
|
1
|
+
import { Effect } from '@livestore/utils/effect'
|
2
|
+
|
3
|
+
import type { EventId } from '../adapter-types.js'
|
4
|
+
|
5
|
+
export const makeNextMutationEventIdPair =
|
6
|
+
(currentMutationEventIdRef: { current: EventId }) => (opts: { localOnly: boolean }) =>
|
7
|
+
Effect.gen(function* () {
|
8
|
+
// NOTE we always point to `local: 0` for non-localOnly mutations
|
9
|
+
const parentId = opts.localOnly
|
10
|
+
? currentMutationEventIdRef.current
|
11
|
+
: { global: currentMutationEventIdRef.current.global, local: 0 }
|
12
|
+
|
13
|
+
const id = opts.localOnly
|
14
|
+
? { global: parentId.global, local: parentId.local + 1 }
|
15
|
+
: { global: parentId.global + 1, local: 0 }
|
16
|
+
|
17
|
+
currentMutationEventIdRef.current = id
|
18
|
+
|
19
|
+
return { id, parentId }
|
20
|
+
})
|
package/src/version.ts
CHANGED
@@ -1,3 +1,12 @@
|
|
1
1
|
import packageJson from '../package.json' with { type: 'json' }
|
2
2
|
|
3
3
|
export const liveStoreVersion = packageJson.version
|
4
|
+
|
5
|
+
/**
|
6
|
+
* This version number is incremented whenever the internal storage format changes in a breaking way.
|
7
|
+
* Whenever this version changes, LiveStore will start with fresh database files. Old database files are not deleted.
|
8
|
+
*
|
9
|
+
* While LiveStore is in alpha, this might happen more frequently.
|
10
|
+
* In the future, LiveStore will provide a migration path for older database files to avoid the impression of data loss.
|
11
|
+
*/
|
12
|
+
export const liveStoreStorageFormatVersion = 2
|
package/tsconfig.json
CHANGED
@@ -1,73 +0,0 @@
|
|
1
|
-
import type { MutationDef } from '@livestore/common/schema';
|
2
|
-
import type { EventNode } from './history-dag.js';
|
3
|
-
/** Used for conflict detection and event history compaction */
|
4
|
-
export declare const facts: {
|
5
|
-
todoExists: (id: string) => string;
|
6
|
-
todoIsWriteable: (id: string, writeable: boolean) => [string, boolean];
|
7
|
-
todoCompleted: (id: string, completed: boolean) => [string, boolean];
|
8
|
-
todoTextUpdated: (id: string) => string;
|
9
|
-
inputValue: (id: string) => string;
|
10
|
-
};
|
11
|
-
export declare const mutations: {
|
12
|
-
createTodo: MutationDef<"createTodo", {
|
13
|
-
readonly id: string;
|
14
|
-
readonly text: string;
|
15
|
-
}, {
|
16
|
-
readonly id: string;
|
17
|
-
readonly text: string;
|
18
|
-
}>;
|
19
|
-
upsertTodo: MutationDef<"upsertTodo", {
|
20
|
-
readonly id: string;
|
21
|
-
readonly text?: string | undefined;
|
22
|
-
}, {
|
23
|
-
readonly id: string;
|
24
|
-
readonly text?: string | undefined;
|
25
|
-
}>;
|
26
|
-
completeTodo: MutationDef<"completeTodo", {
|
27
|
-
readonly id: string;
|
28
|
-
}, {
|
29
|
-
readonly id: string;
|
30
|
-
}>;
|
31
|
-
uncompleteTodo: MutationDef<"uncompleteTodo", {
|
32
|
-
readonly id: string;
|
33
|
-
}, {
|
34
|
-
readonly id: string;
|
35
|
-
}>;
|
36
|
-
completeTodos: MutationDef<"completeTodos", {
|
37
|
-
readonly ids: readonly string[];
|
38
|
-
}, {
|
39
|
-
readonly ids: readonly string[];
|
40
|
-
}>;
|
41
|
-
toggleTodo: MutationDef<"toggleTodo", {
|
42
|
-
readonly id: string;
|
43
|
-
}, {
|
44
|
-
readonly id: string;
|
45
|
-
}>;
|
46
|
-
setReadonlyTodo: MutationDef<"setReadonlyTodo", {
|
47
|
-
readonly id: string;
|
48
|
-
readonly readonly: boolean;
|
49
|
-
}, {
|
50
|
-
readonly id: string;
|
51
|
-
readonly readonly: boolean;
|
52
|
-
}>;
|
53
|
-
setTextTodo: MutationDef<"setTextTodo", {
|
54
|
-
readonly id: string;
|
55
|
-
readonly text: string;
|
56
|
-
}, {
|
57
|
-
readonly id: string;
|
58
|
-
readonly text: string;
|
59
|
-
}>;
|
60
|
-
setInputValue: MutationDef<"setInputValue", {
|
61
|
-
readonly id: string;
|
62
|
-
readonly text: string;
|
63
|
-
}, {
|
64
|
-
readonly id: string;
|
65
|
-
readonly text: string;
|
66
|
-
}>;
|
67
|
-
};
|
68
|
-
export type PartialEvent = {
|
69
|
-
mutation: string;
|
70
|
-
args: any;
|
71
|
-
};
|
72
|
-
export declare const toEventNodes: (partialEvents: PartialEvent[], mutationDefs: Record<string, MutationDef.Any>) => EventNode[];
|
73
|
-
//# sourceMappingURL=mutation-fixtures.d.ts.map
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"mutation-fixtures.d.ts","sourceRoot":"","sources":["../../../src/sync/next/mutation-fixtures.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAK3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAGjD,+DAA+D;AAC/D,eAAO,MAAM,KAAK;qBACC,MAAM;0BACD,MAAM,aAAa,OAAO;wBAC5B,MAAM,aAAa,OAAO;0BACxB,MAAM;qBACX,MAAM;CACvB,CAAA;AAEF,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+GrB,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,GAAG,CAAA;CAAE,CAAA;AAE1D,eAAO,MAAM,YAAY,kBACR,YAAY,EAAE,gBACf,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,CAAC,KAC5C,SAAS,EAkFX,CAAA"}
|