@livestore/common 0.0.56-dev.2 → 0.0.56
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 +19 -11
- package/dist/adapter-types.d.ts.map +1 -1
- package/dist/adapter-types.js +9 -3
- package/dist/adapter-types.js.map +1 -1
- package/dist/devtools/devtools-messages.d.ts +29 -18
- package/dist/devtools/devtools-messages.d.ts.map +1 -1
- package/dist/devtools/devtools-messages.js +7 -2
- package/dist/devtools/devtools-messages.js.map +1 -1
- package/dist/rehydrate-from-mutationlog.d.ts +2 -2
- package/dist/rehydrate-from-mutationlog.d.ts.map +1 -1
- package/dist/rehydrate-from-mutationlog.js +11 -28
- package/dist/rehydrate-from-mutationlog.js.map +1 -1
- package/dist/schema/index.d.ts +3 -3
- 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 -1
- package/dist/schema-management/common.d.ts.map +1 -1
- package/dist/schema-management/common.js +4 -1
- package/dist/schema-management/common.js.map +1 -1
- package/dist/schema-management/migrations.d.ts.map +1 -1
- package/dist/schema-management/migrations.js +2 -5
- package/dist/schema-management/migrations.js.map +1 -1
- package/package.json +3 -3
- package/src/adapter-types.ts +21 -12
- package/src/devtools/devtools-messages.ts +7 -2
- package/src/rehydrate-from-mutationlog.ts +18 -34
- package/src/schema/index.ts +4 -4
- package/src/schema-management/common.ts +5 -1
- package/src/schema-management/migrations.ts +3 -8
package/src/adapter-types.ts
CHANGED
|
@@ -6,7 +6,7 @@ import type { LiveStoreSchema, MutationEvent } from './schema/index.js'
|
|
|
6
6
|
import type { PreparedBindValues } from './util.js'
|
|
7
7
|
|
|
8
8
|
export interface PreparedStatement {
|
|
9
|
-
execute(bindValues: PreparedBindValues | undefined):
|
|
9
|
+
execute(bindValues: PreparedBindValues | undefined, options?: { onRowsChanged?: (rowsChanged: number) => void }): void
|
|
10
10
|
select<T>(bindValues: PreparedBindValues | undefined): ReadonlyArray<T>
|
|
11
11
|
finalize(): void
|
|
12
12
|
}
|
|
@@ -21,7 +21,12 @@ export type StoreAdapter = {
|
|
|
21
21
|
export type SynchronousDatabase = {
|
|
22
22
|
_tag: 'SynchronousDatabase'
|
|
23
23
|
prepare(queryStr: string): PreparedStatement
|
|
24
|
-
execute(
|
|
24
|
+
execute(
|
|
25
|
+
queryStr: string,
|
|
26
|
+
bindValues?: PreparedBindValues | undefined,
|
|
27
|
+
options?: { onRowsChanged?: (rowsChanged: number) => void },
|
|
28
|
+
): void
|
|
29
|
+
select<T>(queryStr: string, bindValues?: PreparedBindValues | undefined): ReadonlyArray<T>
|
|
25
30
|
export(): Uint8Array
|
|
26
31
|
}
|
|
27
32
|
|
|
@@ -62,18 +67,11 @@ export type Coordinator = {
|
|
|
62
67
|
syncMutations: Stream.Stream<MutationEvent.AnyEncoded, UnexpectedError>
|
|
63
68
|
execute(queryStr: string, bindValues: PreparedBindValues | undefined): Effect.Effect<void, UnexpectedError>
|
|
64
69
|
mutate(mutationEventEncoded: MutationEvent.Any, options: { persisted: boolean }): Effect.Effect<void, UnexpectedError>
|
|
65
|
-
dangerouslyReset(mode: ResetMode): Effect.Effect<void, UnexpectedError>
|
|
66
70
|
export: Effect.Effect<Uint8Array | undefined, UnexpectedError>
|
|
67
|
-
/**
|
|
68
|
-
* This is different from `export` since in `getInitialSnapshot` is usually the place for migrations etc to happen
|
|
69
|
-
*/
|
|
70
|
-
getInitialSnapshot: Effect.Effect<Uint8Array, UnexpectedError>
|
|
71
71
|
getMutationLogData: Effect.Effect<Uint8Array, UnexpectedError>
|
|
72
72
|
networkStatus: SubscriptionRef.SubscriptionRef<NetworkStatus>
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
export type GetRowsChangedCount = () => number
|
|
76
|
-
|
|
77
75
|
export type LockStatus = 'has-lock' | 'no-lock'
|
|
78
76
|
|
|
79
77
|
export type BootDb = {
|
|
@@ -102,11 +100,22 @@ export class UnexpectedError extends Schema.TaggedError<UnexpectedError>()('Live
|
|
|
102
100
|
)
|
|
103
101
|
}
|
|
104
102
|
|
|
103
|
+
export class IntentionalShutdownCause extends Schema.TaggedError<IntentionalShutdownCause>()(
|
|
104
|
+
'LiveStore.IntentionalShutdownCause',
|
|
105
|
+
{
|
|
106
|
+
reason: Schema.Literal('devtools-reset', 'devtools-import'),
|
|
107
|
+
},
|
|
108
|
+
) {}
|
|
109
|
+
|
|
105
110
|
export class SqliteError extends Schema.TaggedError<SqliteError>()('LiveStore.SqliteError', {
|
|
106
|
-
|
|
107
|
-
|
|
111
|
+
query: Schema.optional(
|
|
112
|
+
Schema.Struct({
|
|
113
|
+
sql: Schema.String,
|
|
114
|
+
bindValues: Schema.Union(Schema.Record({ key: Schema.String, value: Schema.Any }), Schema.Array(Schema.Any)),
|
|
115
|
+
}),
|
|
116
|
+
),
|
|
108
117
|
/** The SQLite result code */
|
|
109
|
-
code: Schema.Number,
|
|
118
|
+
code: Schema.optional(Schema.Number),
|
|
110
119
|
/** The original SQLite3 error */
|
|
111
120
|
cause: Schema.Defect,
|
|
112
121
|
}) {}
|
|
@@ -124,9 +124,14 @@ export class ResetAllDataRes extends LSDReqResMessage('LSD.ResetAllDataRes', {})
|
|
|
124
124
|
|
|
125
125
|
export class DatabaseFileInfoReq extends LSDReqResMessage('LSD.DatabaseFileInfoReq', {}) {}
|
|
126
126
|
|
|
127
|
+
export class DatabaseFileInfo extends Schema.Struct({
|
|
128
|
+
fileSize: Schema.Number,
|
|
129
|
+
persistenceInfo: Schema.Struct({ fileName: Schema.String }, { key: Schema.String, value: Schema.Any }),
|
|
130
|
+
}) {}
|
|
131
|
+
|
|
127
132
|
export class DatabaseFileInfoRes extends LSDReqResMessage('LSD.DatabaseFileInfoRes', {
|
|
128
|
-
|
|
129
|
-
|
|
133
|
+
db: DatabaseFileInfo,
|
|
134
|
+
mutationLog: DatabaseFileInfo,
|
|
130
135
|
}) {}
|
|
131
136
|
|
|
132
137
|
export class MessagePortForStoreReq extends LSDReqResMessage('LSD.MessagePortForStoreReq', {}) {}
|
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
import { memoizeByRef, shouldNeverHappen } from '@livestore/utils'
|
|
2
2
|
import { Chunk, Effect, Option, Schema, Stream } from '@livestore/utils/effect'
|
|
3
3
|
|
|
4
|
-
import {
|
|
5
|
-
type MigrationOptionsFromMutationLog,
|
|
6
|
-
SqliteError,
|
|
7
|
-
type SynchronousDatabase,
|
|
8
|
-
UnexpectedError,
|
|
9
|
-
} from './adapter-types.js'
|
|
4
|
+
import { type MigrationOptionsFromMutationLog, type SynchronousDatabase, UnexpectedError } from './adapter-types.js'
|
|
10
5
|
import { getExecArgsFromMutation } from './mutation.js'
|
|
11
6
|
import type { LiveStoreSchema, MutationDef, MutationLogMetaRow } from './schema/index.js'
|
|
12
7
|
import { MUTATION_LOG_META_TABLE } from './schema/index.js'
|
|
@@ -27,9 +22,9 @@ export const rehydrateFromMutationLog = ({
|
|
|
27
22
|
onProgress: (_: { done: number; total: number }) => Effect.Effect<void>
|
|
28
23
|
}) =>
|
|
29
24
|
Effect.gen(function* () {
|
|
30
|
-
const mutationsCount = logDb
|
|
31
|
-
|
|
32
|
-
|
|
25
|
+
const mutationsCount = logDb.select<{ count: number }>(
|
|
26
|
+
`SELECT COUNT(*) AS count FROM ${MUTATION_LOG_META_TABLE}`,
|
|
27
|
+
)[0]!.count
|
|
33
28
|
|
|
34
29
|
const hashMutation = memoizeByRef((mutation: MutationDef.Any) => Schema.hash(mutation.schema))
|
|
35
30
|
|
|
@@ -63,36 +58,25 @@ This likely means the schema has changed in an incompatible way.
|
|
|
63
58
|
mutation: row.mutation,
|
|
64
59
|
args: argsDecoded,
|
|
65
60
|
}
|
|
66
|
-
// const argsEncoded = JSON.parse(row.args_json)
|
|
67
|
-
// const mutationSqlRes =
|
|
68
|
-
// typeof mutation.sql === 'string'
|
|
69
|
-
// ? mutation.sql
|
|
70
|
-
// : mutation.sql(Schema.decodeUnknownSync(mutation.schema)(argsEncoded))
|
|
71
|
-
// const mutationSql = typeof mutationSqlRes === 'string' ? mutationSqlRes : mutationSqlRes.sql
|
|
72
|
-
// const bindValues = typeof mutationSqlRes === 'string' ? argsEncoded : mutationSqlRes.bindValues
|
|
73
61
|
|
|
74
62
|
const execArgsArr = getExecArgsFromMutation({ mutationDef, mutationEventDecoded })
|
|
75
63
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
const getRowsChanged = db.execute(statementSql, bindValues)
|
|
80
|
-
if (
|
|
81
|
-
import.meta.env.DEV &&
|
|
82
|
-
getRowsChanged() === 0 &&
|
|
83
|
-
migrationOptions.logging?.excludeAffectedRows?.(statementSql) !== true
|
|
84
|
-
) {
|
|
64
|
+
const makeExecuteOptions = (statementSql: string, bindValues: any) => ({
|
|
65
|
+
onRowsChanged: (rowsChanged: number) => {
|
|
66
|
+
if (rowsChanged === 0 && migrationOptions.logging?.excludeAffectedRows?.(statementSql) !== true) {
|
|
85
67
|
console.warn(`Mutation "${mutationDef.name}" did not affect any rows:`, statementSql, bindValues)
|
|
86
68
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
69
|
+
},
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
for (const { statementSql, bindValues } of execArgsArr) {
|
|
73
|
+
// TODO cache prepared statements for mutations
|
|
74
|
+
db.execute(
|
|
75
|
+
statementSql,
|
|
76
|
+
bindValues,
|
|
77
|
+
import.meta.env.DEV ? makeExecuteOptions(statementSql, bindValues) : undefined,
|
|
78
|
+
)
|
|
79
|
+
// console.log(`Re-executed mutation ${mutationSql}`, bindValues)
|
|
96
80
|
}
|
|
97
81
|
}).pipe(Effect.withSpan(`@livestore/common:rehydrateFromMutationLog:processMutation`))
|
|
98
82
|
|
package/src/schema/index.ts
CHANGED
|
@@ -39,6 +39,9 @@ export type LiveStoreSchema<
|
|
|
39
39
|
|
|
40
40
|
migrationOptions: MigrationOptions
|
|
41
41
|
|
|
42
|
+
/**
|
|
43
|
+
* @default 'default'
|
|
44
|
+
*/
|
|
42
45
|
key: string
|
|
43
46
|
}
|
|
44
47
|
|
|
@@ -47,9 +50,6 @@ export type InputSchema = {
|
|
|
47
50
|
readonly mutations?: ReadonlyArray<MutationDef.Any> | Record<string, MutationDef.Any>
|
|
48
51
|
/**
|
|
49
52
|
* Can be used to isolate multiple LiveStore apps running in the same origin
|
|
50
|
-
*
|
|
51
|
-
* Make sure you also use this key in the `storage` options (e.g. directory, prefix etc) to make sure
|
|
52
|
-
* different instances of LiveStore aren't overlapping on the storage level.
|
|
53
53
|
*/
|
|
54
54
|
readonly key?: string
|
|
55
55
|
}
|
|
@@ -118,7 +118,7 @@ export const makeSchema = <TInputSchema extends InputSchema>(
|
|
|
118
118
|
mutations,
|
|
119
119
|
migrationOptions: inputSchema.migrations ?? { strategy: 'hard-reset' },
|
|
120
120
|
hash,
|
|
121
|
-
key: inputSchema.key ?? '',
|
|
121
|
+
key: inputSchema.key ?? 'default',
|
|
122
122
|
} satisfies LiveStoreSchema
|
|
123
123
|
}
|
|
124
124
|
|
|
@@ -16,6 +16,8 @@ export const dbExecute = (db: SynchronousDatabase, queryStr: string, bindValues?
|
|
|
16
16
|
const preparedBindValues = bindValues ? prepareBindValues(bindValues, queryStr) : undefined
|
|
17
17
|
|
|
18
18
|
stmt.execute(preparedBindValues)
|
|
19
|
+
|
|
20
|
+
stmt.finalize()
|
|
19
21
|
}
|
|
20
22
|
|
|
21
23
|
export const dbSelect = <T>(db: SynchronousDatabase, queryStr: string, bindValues?: ParamsObject) => {
|
|
@@ -25,7 +27,9 @@ export const dbSelect = <T>(db: SynchronousDatabase, queryStr: string, bindValue
|
|
|
25
27
|
// cachedStmts.set(queryStr, stmt)
|
|
26
28
|
// }
|
|
27
29
|
|
|
28
|
-
|
|
30
|
+
const res = stmt.select<T>(bindValues ? prepareBindValues(bindValues, queryStr) : undefined)
|
|
31
|
+
stmt.finalize()
|
|
32
|
+
return res
|
|
29
33
|
}
|
|
30
34
|
|
|
31
35
|
export interface SchemaManager {
|
|
@@ -28,14 +28,9 @@ export const makeSchemaManager = (db: SynchronousDatabase): Effect.Effect<Schema
|
|
|
28
28
|
})
|
|
29
29
|
|
|
30
30
|
return {
|
|
31
|
-
getMutationDefInfos: () =>
|
|
32
|
-
|
|
33
|
-
db,
|
|
34
|
-
sql`SELECT * FROM ${SCHEMA_MUTATIONS_META_TABLE}`,
|
|
35
|
-
)
|
|
31
|
+
getMutationDefInfos: () =>
|
|
32
|
+
dbSelect<SchemaMutationsMetaRow>(db, sql`SELECT * FROM ${SCHEMA_MUTATIONS_META_TABLE}`),
|
|
36
33
|
|
|
37
|
-
return schemaMutationsMetaRows
|
|
38
|
-
},
|
|
39
34
|
setMutationDefInfo: (info) => {
|
|
40
35
|
dbExecute(
|
|
41
36
|
db,
|
|
@@ -128,7 +123,7 @@ export const migrateTable = ({
|
|
|
128
123
|
skipMetaTable?: boolean
|
|
129
124
|
}) =>
|
|
130
125
|
Effect.gen(function* () {
|
|
131
|
-
console.log(`Migrating table '${tableAst.name}'...`)
|
|
126
|
+
// console.log(`Migrating table '${tableAst.name}'...`)
|
|
132
127
|
const tableName = tableAst.name
|
|
133
128
|
const columnSpec = makeColumnSpec(tableAst)
|
|
134
129
|
|