@livestore/livestore 0.0.29 → 0.0.31
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__/mutations.test.d.ts +2 -0
- package/dist/__tests__/mutations.test.d.ts.map +1 -0
- package/dist/__tests__/mutations.test.js +40 -0
- package/dist/__tests__/mutations.test.js.map +1 -0
- package/dist/__tests__/react/fixture.d.ts +50 -8
- package/dist/__tests__/react/fixture.d.ts.map +1 -1
- package/dist/inMemoryDatabase.d.ts.map +1 -1
- package/dist/inMemoryDatabase.js +4 -0
- package/dist/inMemoryDatabase.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/migrations.js +3 -3
- package/dist/migrations.js.map +1 -1
- package/dist/mutations.d.ts +31 -0
- package/dist/mutations.d.ts.map +1 -0
- package/dist/mutations.js +38 -0
- package/dist/mutations.js.map +1 -0
- package/dist/react/useRow.js +3 -3
- package/dist/react/useRow.js.map +1 -1
- package/dist/row-query.d.ts +3 -0
- package/dist/row-query.d.ts.map +1 -1
- package/dist/row-query.js +13 -11
- package/dist/row-query.js.map +1 -1
- package/dist/schema/system-tables.d.ts +42 -6
- package/dist/schema/system-tables.d.ts.map +1 -1
- package/dist/schema/table-def.d.ts +12 -98
- package/dist/schema/table-def.d.ts.map +1 -1
- package/dist/schema/table-def.js +3 -3
- package/dist/schema/table-def.js.map +1 -1
- package/package.json +4 -3
- package/src/__tests__/mutations.test.ts +43 -0
- package/src/inMemoryDatabase.ts +3 -0
- package/src/index.ts +2 -0
- package/src/migrations.ts +3 -3
- package/src/mutations.ts +74 -0
- package/src/react/useRow.ts +3 -3
- package/src/row-query.ts +19 -11
- package/src/schema/table-def.ts +16 -23
- package/tsconfig.json +1 -1
|
@@ -1,95 +1,7 @@
|
|
|
1
1
|
import { Schema } from '@livestore/utils/effect';
|
|
2
2
|
import type { Nullable, PrettifyFlat } from 'effect-db-schema';
|
|
3
3
|
import { SqliteDsl } from 'effect-db-schema';
|
|
4
|
-
export declare const blob: <
|
|
5
|
-
default?: Uint8Array | null | undefined;
|
|
6
|
-
primaryKey?: boolean | undefined;
|
|
7
|
-
nullable?: TNullable | undefined;
|
|
8
|
-
type: SqliteDsl.FieldType.FieldTypeBlob<Uint8Array>;
|
|
9
|
-
}, blobWithSchema: <TDecoded, TNullable extends boolean = false>({ schema, ...def }: {
|
|
10
|
-
schema: Schema.Schema<Uint8Array, TDecoded>;
|
|
11
|
-
} & Omit<SqliteDsl.ColumnDefinition<SqliteDsl.FieldType.FieldTypeBlob<TDecoded>, TNullable>, "type">) => {
|
|
12
|
-
default?: TDecoded | null | undefined;
|
|
13
|
-
primaryKey?: boolean | undefined;
|
|
14
|
-
nullable?: TNullable | undefined;
|
|
15
|
-
type: SqliteDsl.FieldType.FieldTypeBlob<TDecoded>;
|
|
16
|
-
}, boolean: <const TDef extends {
|
|
17
|
-
readonly default?: boolean | null | undefined;
|
|
18
|
-
readonly primaryKey?: boolean | undefined;
|
|
19
|
-
readonly nullable?: boolean | undefined;
|
|
20
|
-
}>(def?: TDef | undefined) => SqliteDsl.ColumnDefinition<SqliteDsl.FieldType.FieldTypeBoolean, TDef["nullable"] extends boolean ? TDef["nullable"] : false>, column: <TType extends SqliteDsl.FieldType.FieldColumnType, TEncoded, TDecoded, TNullable extends boolean>(_: SqliteDsl.ColumnDefinition<SqliteDsl.FieldType.FieldType<TType, TEncoded, TDecoded>, TNullable>) => SqliteDsl.ColumnDefinition<SqliteDsl.FieldType.FieldType<TType, TEncoded, TDecoded>, TNullable>, datetime: <const TDef extends {
|
|
21
|
-
readonly default?: {
|
|
22
|
-
toString: {};
|
|
23
|
-
toDateString: {};
|
|
24
|
-
toTimeString: {};
|
|
25
|
-
toLocaleString: {};
|
|
26
|
-
toLocaleDateString: {};
|
|
27
|
-
toLocaleTimeString: {};
|
|
28
|
-
valueOf: {};
|
|
29
|
-
getTime: {};
|
|
30
|
-
getFullYear: {};
|
|
31
|
-
getUTCFullYear: {};
|
|
32
|
-
getMonth: {};
|
|
33
|
-
getUTCMonth: {};
|
|
34
|
-
getDate: {};
|
|
35
|
-
getUTCDate: {};
|
|
36
|
-
getDay: {};
|
|
37
|
-
getUTCDay: {};
|
|
38
|
-
getHours: {};
|
|
39
|
-
getUTCHours: {};
|
|
40
|
-
getMinutes: {};
|
|
41
|
-
getUTCMinutes: {};
|
|
42
|
-
getSeconds: {};
|
|
43
|
-
getUTCSeconds: {};
|
|
44
|
-
getMilliseconds: {};
|
|
45
|
-
getUTCMilliseconds: {};
|
|
46
|
-
getTimezoneOffset: {};
|
|
47
|
-
setTime: {};
|
|
48
|
-
setMilliseconds: {};
|
|
49
|
-
setUTCMilliseconds: {};
|
|
50
|
-
setSeconds: {};
|
|
51
|
-
setUTCSeconds: {};
|
|
52
|
-
setMinutes: {};
|
|
53
|
-
setUTCMinutes: {};
|
|
54
|
-
setHours: {};
|
|
55
|
-
setUTCHours: {};
|
|
56
|
-
setDate: {};
|
|
57
|
-
setUTCDate: {};
|
|
58
|
-
setMonth: {};
|
|
59
|
-
setUTCMonth: {};
|
|
60
|
-
setFullYear: {};
|
|
61
|
-
setUTCFullYear: {};
|
|
62
|
-
toUTCString: {};
|
|
63
|
-
toISOString: {};
|
|
64
|
-
toJSON: {};
|
|
65
|
-
getVarDate: {};
|
|
66
|
-
[Symbol.toPrimitive]: {};
|
|
67
|
-
} | null | undefined;
|
|
68
|
-
readonly primaryKey?: boolean | undefined;
|
|
69
|
-
readonly nullable?: boolean | undefined;
|
|
70
|
-
}>(def?: TDef | undefined) => SqliteDsl.ColumnDefinition<SqliteDsl.FieldType.FieldTypeDateTime, TDef["nullable"] extends boolean ? TDef["nullable"] : false>, integer: <const TDef extends {
|
|
71
|
-
readonly default?: number | null | undefined;
|
|
72
|
-
readonly primaryKey?: boolean | undefined;
|
|
73
|
-
readonly nullable?: boolean | undefined;
|
|
74
|
-
}>(def?: TDef | undefined) => SqliteDsl.ColumnDefinition<SqliteDsl.FieldType.FieldTypeInteger<number, number>, TDef["nullable"] extends boolean ? TDef["nullable"] : false>, isColumnDefinition: (value: unknown) => value is SqliteDsl.ColumnDefinition<any, any>, json: <TEncoded, TDecoded, const TDef extends {
|
|
75
|
-
readonly default?: import("effect-db-schema").Prettify<TDecoded> | null | undefined;
|
|
76
|
-
readonly primaryKey?: boolean | undefined;
|
|
77
|
-
readonly nullable?: boolean | undefined;
|
|
78
|
-
}>({ schema, ...def }: TDef & {
|
|
79
|
-
schema: Schema.Schema<TEncoded, TDecoded>;
|
|
80
|
-
}) => SqliteDsl.ColumnDefinition<SqliteDsl.FieldType.FieldTypeJson<TDecoded>, TDef["nullable"] extends boolean ? TDef["nullable"] : false>, real: <const TDef extends {
|
|
81
|
-
readonly default?: number | null | undefined;
|
|
82
|
-
readonly primaryKey?: boolean | undefined;
|
|
83
|
-
readonly nullable?: boolean | undefined;
|
|
84
|
-
}>(def?: TDef | undefined) => SqliteDsl.ColumnDefinition<SqliteDsl.FieldType.FieldTypeReal<number, number>, TDef["nullable"] extends boolean ? TDef["nullable"] : false>, text: <const TDef extends {
|
|
85
|
-
readonly default?: string | null | undefined;
|
|
86
|
-
readonly primaryKey?: boolean | undefined;
|
|
87
|
-
readonly nullable?: boolean | undefined;
|
|
88
|
-
}>(def?: TDef | undefined) => SqliteDsl.ColumnDefinition<SqliteDsl.FieldType.FieldTypeText<string, string>, TDef["nullable"] extends boolean ? TDef["nullable"] : false>, textWithSchema: <TEncoded extends string, TDecoded, const TDef extends {
|
|
89
|
-
readonly default?: import("effect-db-schema").Prettify<TDecoded> | null | undefined;
|
|
90
|
-
readonly primaryKey?: boolean | undefined;
|
|
91
|
-
readonly nullable?: boolean | undefined;
|
|
92
|
-
}>(schema: Schema.Schema<TEncoded, TDecoded>, def?: TDef | undefined) => SqliteDsl.ColumnDefinition<SqliteDsl.FieldType.FieldTypeText<TEncoded, TDecoded>, TDef["nullable"] extends boolean ? TDef["nullable"] : false>;
|
|
4
|
+
export declare const blob: SqliteDsl.ColDefFn<"blob">, boolean: SqliteDsl.SpecializedColDefFn<"integer", false, boolean>, column: <TColumnType extends SqliteDsl.FieldColumnType>(columnType: TColumnType) => SqliteDsl.ColDefFn<TColumnType>, datetime: SqliteDsl.SpecializedColDefFn<"text", false, Date>, integer: SqliteDsl.ColDefFn<"integer">, isColumnDefinition: (value: unknown) => value is SqliteDsl.ColumnDefinition<any, any>, json: SqliteDsl.SpecializedColDefFn<"text", true, unknown>, real: SqliteDsl.ColDefFn<"real">, text: SqliteDsl.ColDefFn<"text">;
|
|
93
5
|
export { type SqliteDsl as __SqliteDsl } from 'effect-db-schema';
|
|
94
6
|
export type StateType = 'singleton' | 'dynamic';
|
|
95
7
|
export type DefaultSqliteTableDef = SqliteDsl.TableDefinition<string, SqliteDsl.Columns>;
|
|
@@ -114,7 +26,7 @@ export type TableOptions = {
|
|
|
114
26
|
dynamicRegistration: boolean;
|
|
115
27
|
disableAutomaticIdColumn: boolean;
|
|
116
28
|
};
|
|
117
|
-
export declare const table: <TName extends string, TColumns extends SqliteDsl.
|
|
29
|
+
export declare const table: <TName extends string, TColumns extends SqliteDsl.ColumnDefinition<any, any> | SqliteDsl.Columns, const TOptionsInput extends Partial<TableOptions & {
|
|
118
30
|
indexes: SqliteDsl.Index[];
|
|
119
31
|
}> = Partial<TableOptions & {
|
|
120
32
|
indexes: SqliteDsl.Index[];
|
|
@@ -122,9 +34,9 @@ export declare const table: <TName extends string, TColumns extends SqliteDsl.Co
|
|
|
122
34
|
value: TColumns;
|
|
123
35
|
}, WithDefaults<TOptionsInput>>>>, TColumns extends SqliteDsl.ColumnDefinition<any, any> ? true : false, WithDefaults<TOptionsInput>>;
|
|
124
36
|
type WithId<TColumns extends SqliteDsl.Columns, TOptions extends TableOptions> = TColumns & (TOptions['disableAutomaticIdColumn'] extends true ? {} : TOptions['isSingleton'] extends true ? {
|
|
125
|
-
id: SqliteDsl.ColumnDefinition<
|
|
37
|
+
id: SqliteDsl.ColumnDefinition<'singleton', 'singleton'>;
|
|
126
38
|
} : {
|
|
127
|
-
id: SqliteDsl.ColumnDefinition<
|
|
39
|
+
id: SqliteDsl.ColumnDefinition<string, string>;
|
|
128
40
|
});
|
|
129
41
|
type WithDefaults<TOptionsInput extends TableOptionsInput> = {
|
|
130
42
|
isSingleton: TOptionsInput['isSingleton'] extends true ? true : false;
|
|
@@ -135,27 +47,29 @@ export declare namespace FromTable {
|
|
|
135
47
|
type RowDecoded<TTableDef extends TableDef> = PrettifyFlat<Nullable<Pick<RowDecodedAll<TTableDef>, NullableColumnNames<TTableDef>>> & Omit<RowDecodedAll<TTableDef>, NullableColumnNames<TTableDef>>>;
|
|
136
48
|
type NullableColumnNames<TTableDef extends TableDef> = FromColumns.NullableColumnNames<TTableDef['schema']['columns']>;
|
|
137
49
|
type Columns<TTableDef extends TableDef> = {
|
|
138
|
-
[K in keyof TTableDef['schema']['columns']]: TTableDef['schema']['columns'][K]['
|
|
50
|
+
[K in keyof TTableDef['schema']['columns']]: TTableDef['schema']['columns'][K]['columnType'];
|
|
139
51
|
};
|
|
140
52
|
type RowEncodeNonNullable<TTableDef extends TableDef> = {
|
|
141
|
-
[K in keyof TTableDef['schema']['columns']]: Schema.Schema.From<TTableDef['schema']['columns'][K]['
|
|
53
|
+
[K in keyof TTableDef['schema']['columns']]: Schema.Schema.From<TTableDef['schema']['columns'][K]['schema']>;
|
|
142
54
|
};
|
|
143
55
|
type RowEncoded<TTableDef extends TableDef> = PrettifyFlat<Nullable<Pick<RowEncodeNonNullable<TTableDef>, NullableColumnNames<TTableDef>>> & Omit<RowEncodeNonNullable<TTableDef>, NullableColumnNames<TTableDef>>>;
|
|
144
56
|
type RowDecodedAll<TTableDef extends TableDef> = {
|
|
145
|
-
[K in keyof TTableDef['schema']['columns']]: Schema.Schema.To<TTableDef['schema']['columns'][K]['
|
|
57
|
+
[K in keyof TTableDef['schema']['columns']]: Schema.Schema.To<TTableDef['schema']['columns'][K]['schema']>;
|
|
146
58
|
};
|
|
147
59
|
}
|
|
148
60
|
export declare namespace FromColumns {
|
|
149
61
|
type RowDecoded<TColumns extends SqliteDsl.Columns> = PrettifyFlat<Nullable<Pick<RowDecodedAll<TColumns>, NullableColumnNames<TColumns>>> & Omit<RowDecodedAll<TColumns>, NullableColumnNames<TColumns>>>;
|
|
150
62
|
type RowDecodedAll<TColumns extends SqliteDsl.Columns> = {
|
|
151
|
-
[K in keyof TColumns]: Schema.Schema.To<TColumns[K]['
|
|
63
|
+
[K in keyof TColumns]: Schema.Schema.To<TColumns[K]['schema']>;
|
|
152
64
|
};
|
|
153
65
|
type RowEncoded<TColumns extends SqliteDsl.Columns> = PrettifyFlat<Nullable<Pick<RowEncodeNonNullable<TColumns>, NullableColumnNames<TColumns>>> & Omit<RowEncodeNonNullable<TColumns>, NullableColumnNames<TColumns>>>;
|
|
154
66
|
type RowEncodeNonNullable<TColumns extends SqliteDsl.Columns> = {
|
|
155
|
-
[K in keyof TColumns]: Schema.Schema.From<TColumns[K]['
|
|
67
|
+
[K in keyof TColumns]: Schema.Schema.From<TColumns[K]['schema']>;
|
|
156
68
|
};
|
|
157
69
|
type NullableColumnNames<TColumns extends SqliteDsl.Columns> = keyof {
|
|
158
|
-
[K in keyof TColumns as TColumns[K] extends
|
|
70
|
+
[K in keyof TColumns as TColumns[K]['default'] extends true ? K : never]: {};
|
|
159
71
|
};
|
|
72
|
+
type RequiredInsertColumnNames<TColumns extends SqliteDsl.Columns> = SqliteDsl.FromColumns.RequiredInsertColumnNames<TColumns>;
|
|
73
|
+
type InsertRowDecoded<TColumns extends SqliteDsl.Columns> = SqliteDsl.FromColumns.InsertRowDecoded<TColumns>;
|
|
160
74
|
}
|
|
161
75
|
//# sourceMappingURL=table-def.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"table-def.d.ts","sourceRoot":"","sources":["../../src/schema/table-def.ts"],"names":[],"mappings":"AACA,OAAO,EAAkB,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAChE,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC9D,OAAO,EAAa,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAEvD,eAAO,
|
|
1
|
+
{"version":3,"file":"table-def.d.ts","sourceRoot":"","sources":["../../src/schema/table-def.ts"],"names":[],"mappings":"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"}
|
package/dist/schema/table-def.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { shouldNeverHappen } from '@livestore/utils';
|
|
2
2
|
import { ReadonlyRecord, Schema } from '@livestore/utils/effect';
|
|
3
3
|
import { SqliteAst, SqliteDsl } from 'effect-db-schema';
|
|
4
|
-
export const { blob,
|
|
4
|
+
export const { blob, boolean, column, datetime, integer, isColumnDefinition, json, real, text } = SqliteDsl;
|
|
5
5
|
import { dynamicallyRegisteredTables } from '../global-state.js';
|
|
6
6
|
export const table = (name, columnOrColumns,
|
|
7
7
|
// type?: TStateType,
|
|
@@ -20,7 +20,7 @@ options) => {
|
|
|
20
20
|
}
|
|
21
21
|
else if (columns.id === undefined && ReadonlyRecord.some(columns, (_) => _.primaryKey === true) === false) {
|
|
22
22
|
if (options_.isSingleton) {
|
|
23
|
-
columns.id = SqliteDsl.
|
|
23
|
+
columns.id = SqliteDsl.text({ schema: Schema.literal('singleton'), primaryKey: true, default: 'singleton' });
|
|
24
24
|
}
|
|
25
25
|
else {
|
|
26
26
|
columns.id = SqliteDsl.text({ primaryKey: true });
|
|
@@ -29,7 +29,7 @@ options) => {
|
|
|
29
29
|
const schema = SqliteDsl.table(tablePath, columns, options?.indexes ?? []);
|
|
30
30
|
if (options_.isSingleton) {
|
|
31
31
|
for (const column of schema.ast.columns) {
|
|
32
|
-
if (column.nullable === false && column.default ===
|
|
32
|
+
if (column.nullable === false && column.default._tag === 'None') {
|
|
33
33
|
shouldNeverHappen(`When creating a singleton table, each column must be either nullable or have a default value. Column '${column.name}' is neither.`);
|
|
34
34
|
}
|
|
35
35
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"table-def.js","sourceRoot":"","sources":["../../src/schema/table-def.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAEhE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAEvD,MAAM,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"table-def.js","sourceRoot":"","sources":["../../src/schema/table-def.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@livestore/livestore",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.31",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -53,8 +53,9 @@
|
|
|
53
53
|
"lodash-es": "^4.17.21",
|
|
54
54
|
"sqlite-esm": "3.42.0-build6",
|
|
55
55
|
"uuid": "^9.0.1",
|
|
56
|
-
"@livestore/utils": "0.0.
|
|
57
|
-
"
|
|
56
|
+
"@livestore/utils": "0.0.31",
|
|
57
|
+
"@livestore/sql-queries": "0.0.31",
|
|
58
|
+
"effect-db-schema": "0.0.31"
|
|
58
59
|
},
|
|
59
60
|
"devDependencies": {
|
|
60
61
|
"@opentelemetry/sdk-trace-base": "1.19.0",
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { describe, expect, test } from 'vitest'
|
|
2
|
+
|
|
3
|
+
import { makeMutations } from '../mutations.js'
|
|
4
|
+
import { schema } from './react/fixture.js'
|
|
5
|
+
|
|
6
|
+
describe('mutations', () => {
|
|
7
|
+
const mutations = makeMutations(schema)
|
|
8
|
+
|
|
9
|
+
test('basic', () => {
|
|
10
|
+
expect(mutations.todos.insert({ id: 't1', completed: true, text: 'Task 1' })).toMatchInlineSnapshot(`
|
|
11
|
+
{
|
|
12
|
+
"args": {
|
|
13
|
+
"bindValues": {
|
|
14
|
+
"completed": 1,
|
|
15
|
+
"id": "t1",
|
|
16
|
+
"text": "Task 1",
|
|
17
|
+
},
|
|
18
|
+
"sql": "INSERT INTO todos (id, completed, text) VALUES ($id, $completed, $text)",
|
|
19
|
+
"writeTables": Set {
|
|
20
|
+
"todos",
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
"eventType": "livestore.RawSql",
|
|
24
|
+
}
|
|
25
|
+
`)
|
|
26
|
+
|
|
27
|
+
expect(mutations.todos.update({ where: { id: 't1' }, values: { text: 'Task 1 - fixed' } })).toMatchInlineSnapshot(`
|
|
28
|
+
{
|
|
29
|
+
"args": {
|
|
30
|
+
"bindValues": {
|
|
31
|
+
"update_text": "Task 1 - fixed",
|
|
32
|
+
"where_id": "t1",
|
|
33
|
+
},
|
|
34
|
+
"sql": "UPDATE todos SET text = $update_text WHERE id = $where_id",
|
|
35
|
+
"writeTables": Set {
|
|
36
|
+
"todos",
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
"eventType": "livestore.RawSql",
|
|
40
|
+
}
|
|
41
|
+
`)
|
|
42
|
+
})
|
|
43
|
+
})
|
package/src/inMemoryDatabase.ts
CHANGED
|
@@ -125,6 +125,9 @@ export class InMemoryDatabase {
|
|
|
125
125
|
while (stmt.step()) {
|
|
126
126
|
tablesUsed.add(stmt.get(0))
|
|
127
127
|
}
|
|
128
|
+
} catch (e) {
|
|
129
|
+
console.error('Error getting tables used', e, 'for query', query)
|
|
130
|
+
return new Set<string>()
|
|
128
131
|
} finally {
|
|
129
132
|
stmt.reset()
|
|
130
133
|
}
|
package/src/index.ts
CHANGED
|
@@ -17,6 +17,8 @@ export { dbGraph } from './global-state.js'
|
|
|
17
17
|
|
|
18
18
|
export { type RowResult, type RowResultEncoded, type RowQueryArgs, rowQuery } from './row-query.js'
|
|
19
19
|
|
|
20
|
+
export * from './mutations.js'
|
|
21
|
+
|
|
20
22
|
export { defineAction, defineActions, makeSchema, DbSchema } from './schema/index.js'
|
|
21
23
|
|
|
22
24
|
export type {
|
package/src/migrations.ts
CHANGED
|
@@ -119,10 +119,10 @@ const toSqliteColumnSpec = (column: SqliteAst.Column) => {
|
|
|
119
119
|
const columnTypeStr = column.type._tag
|
|
120
120
|
const nullableStr = column.nullable === false ? 'not null' : ''
|
|
121
121
|
const defaultValueStr = (() => {
|
|
122
|
-
if (column.default ===
|
|
122
|
+
if (column.default._tag === 'None') return ''
|
|
123
123
|
|
|
124
|
-
const encodeValue = EffectSchema.encodeSync(column.
|
|
125
|
-
const encodedDefaultValue = encodeValue(column.default
|
|
124
|
+
const encodeValue = EffectSchema.encodeSync(column.schema)
|
|
125
|
+
const encodedDefaultValue = encodeValue(column.default.value)
|
|
126
126
|
|
|
127
127
|
return columnTypeStr === 'text' ? `default '${encodedDefaultValue}'` : `default ${encodedDefaultValue}`
|
|
128
128
|
})()
|
package/src/mutations.ts
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import * as SqlQueries from '@livestore/sql-queries'
|
|
2
|
+
import type { SqliteDsl } from 'effect-db-schema'
|
|
3
|
+
|
|
4
|
+
import type { RowInsert, RowResult } from './row-query.js'
|
|
5
|
+
import type { LiveStoreSchema } from './schema/index.js'
|
|
6
|
+
import type { TableDef } from './schema/table-def.js'
|
|
7
|
+
|
|
8
|
+
export const makeMutations = <TDbSchema extends SqliteDsl.DbSchema>(
|
|
9
|
+
schema: LiveStoreSchema<TDbSchema>,
|
|
10
|
+
): Mutations<TDbSchema> => {
|
|
11
|
+
return Object.fromEntries(Array.from(schema.tables.values()).map(mutationsForTable)) as any
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const mutationsForTable = <TTableDef extends TableDef>(tableDef: TTableDef): [string, Mutation<TTableDef>] => {
|
|
15
|
+
const table = tableDef.schema
|
|
16
|
+
const writeTables = new Set([table.name])
|
|
17
|
+
const api = {
|
|
18
|
+
insert: (values) => {
|
|
19
|
+
const [sql, bindValues] = SqlQueries.insertRow({
|
|
20
|
+
tableName: table.name,
|
|
21
|
+
columns: table.columns,
|
|
22
|
+
options: { orReplace: false },
|
|
23
|
+
values: values as any,
|
|
24
|
+
})
|
|
25
|
+
return { eventType: 'livestore.RawSql', args: { sql, bindValues, writeTables } }
|
|
26
|
+
},
|
|
27
|
+
update: ({ where, values }) => {
|
|
28
|
+
const [sql, bindValues] = SqlQueries.updateRows({
|
|
29
|
+
tableName: table.name,
|
|
30
|
+
columns: table.columns,
|
|
31
|
+
where: where,
|
|
32
|
+
updateValues: values,
|
|
33
|
+
})
|
|
34
|
+
return { eventType: 'livestore.RawSql', args: { sql, bindValues, writeTables } }
|
|
35
|
+
},
|
|
36
|
+
delete: ({ where }) => {
|
|
37
|
+
const [sql, bindValues] = SqlQueries.deleteRows({
|
|
38
|
+
tableName: table.name,
|
|
39
|
+
columns: table.columns,
|
|
40
|
+
where: where,
|
|
41
|
+
})
|
|
42
|
+
return { eventType: 'livestore.RawSql', args: { sql, bindValues, writeTables } }
|
|
43
|
+
},
|
|
44
|
+
} satisfies Mutation<TTableDef>
|
|
45
|
+
|
|
46
|
+
return [tableDef.schema.name, api]
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export type MutationEvent = {
|
|
50
|
+
eventType: 'livestore.RawSql'
|
|
51
|
+
args: { sql: string; bindValues: SqlQueries.BindValues; writeTables: Set<string> }
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export type UpdateMutation<TTableDef extends TableDef> = (args: {
|
|
55
|
+
// TODO also allow `id` if present in `TTableDef`
|
|
56
|
+
where: Partial<RowResult<TTableDef>>
|
|
57
|
+
values: Partial<RowResult<TTableDef>>
|
|
58
|
+
}) => MutationEvent
|
|
59
|
+
|
|
60
|
+
export type InsertMutation<TTableDef extends TableDef> = (values: RowInsert<TTableDef>) => MutationEvent
|
|
61
|
+
|
|
62
|
+
export type DeleteMutation<TTableDef extends TableDef> = (args: {
|
|
63
|
+
where: Partial<RowResult<TTableDef>>
|
|
64
|
+
}) => MutationEvent
|
|
65
|
+
|
|
66
|
+
export type Mutation<TTableDef extends TableDef> = {
|
|
67
|
+
insert: InsertMutation<TTableDef>
|
|
68
|
+
update: UpdateMutation<TTableDef>
|
|
69
|
+
delete: DeleteMutation<TTableDef>
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export type Mutations<TDbSchema extends SqliteDsl.DbSchema> = {
|
|
73
|
+
[TTableName in keyof TDbSchema]: Mutation<TableDef<TDbSchema[TTableName]>>
|
|
74
|
+
}
|
package/src/react/useRow.ts
CHANGED
|
@@ -104,7 +104,7 @@ export const useRow: {
|
|
|
104
104
|
const newValue = typeof newValueOrFn === 'function' ? newValueOrFn(query$Ref.current) : newValueOrFn
|
|
105
105
|
if (query$Ref.current === newValue) return
|
|
106
106
|
|
|
107
|
-
const encodedValue = Schema.encodeSync(sqliteTableDef.columns['value']!.
|
|
107
|
+
const encodedValue = Schema.encodeSync(sqliteTableDef.columns['value']!.schema)(newValue)
|
|
108
108
|
|
|
109
109
|
store.applyEvent('livestore.UpdateComponentState', {
|
|
110
110
|
tableName: sqliteTableDef.name,
|
|
@@ -124,7 +124,7 @@ export const useRow: {
|
|
|
124
124
|
// @ts-expect-error TODO fix typing
|
|
125
125
|
if (query$Ref.current[columnName] === newValue) return
|
|
126
126
|
|
|
127
|
-
const encodedValue = Schema.encodeSync(column.
|
|
127
|
+
const encodedValue = Schema.encodeSync(column.schema)(newValue)
|
|
128
128
|
|
|
129
129
|
store.applyEvent('livestore.UpdateComponentState', {
|
|
130
130
|
tableName: sqliteTableDef.name,
|
|
@@ -150,7 +150,7 @@ export const useRow: {
|
|
|
150
150
|
|
|
151
151
|
const columnNames = Object.keys(columnValues)
|
|
152
152
|
const bindValues = mapValues(columnValues, (value, columnName) =>
|
|
153
|
-
Schema.encodeSync(sqliteTableDef.columns[columnName]!.
|
|
153
|
+
Schema.encodeSync(sqliteTableDef.columns[columnName]!.schema)(value),
|
|
154
154
|
)
|
|
155
155
|
|
|
156
156
|
store.applyEvent('livestore.UpdateComponentState', {
|
package/src/row-query.ts
CHANGED
|
@@ -18,6 +18,7 @@ export type RowQueryArgs<TTableDef extends TableDef> = TTableDef['options']['isS
|
|
|
18
18
|
store: Store
|
|
19
19
|
otelContext?: otel.Context
|
|
20
20
|
defaultValues: Partial<RowResult<TTableDef>>
|
|
21
|
+
skipInsertDefaultRow?: boolean
|
|
21
22
|
}
|
|
22
23
|
: {
|
|
23
24
|
table: TTableDef
|
|
@@ -25,13 +26,14 @@ export type RowQueryArgs<TTableDef extends TableDef> = TTableDef['options']['isS
|
|
|
25
26
|
otelContext?: otel.Context
|
|
26
27
|
id: string
|
|
27
28
|
defaultValues: Partial<RowResult<TTableDef>>
|
|
29
|
+
skipInsertDefaultRow?: boolean
|
|
28
30
|
}
|
|
29
31
|
|
|
30
32
|
// TODO also allow other where clauses and multiple rows
|
|
31
33
|
export const rowQuery = <TTableDef extends TableDef>(
|
|
32
34
|
args: RowQueryArgs<TTableDef>,
|
|
33
35
|
): LiveStoreJSQuery<RowResult<TTableDef>> => {
|
|
34
|
-
const { table, store, defaultValues } = args
|
|
36
|
+
const { table, store, defaultValues, skipInsertDefaultRow } = args
|
|
35
37
|
const otelContext = args.otelContext ?? store.otel.queriesSpanContext
|
|
36
38
|
const id: string | undefined = (args as any).id
|
|
37
39
|
|
|
@@ -69,14 +71,16 @@ export const rowQuery = <TTableDef extends TableDef>(
|
|
|
69
71
|
})
|
|
70
72
|
}
|
|
71
73
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
74
|
+
if (skipInsertDefaultRow !== true) {
|
|
75
|
+
// TODO find a way to only do this if necessary
|
|
76
|
+
insertRowWithDefaultValuesOrIgnore({
|
|
77
|
+
db: store._proxyDb,
|
|
78
|
+
id: id ?? 'singleton',
|
|
79
|
+
stateSchema,
|
|
80
|
+
otelContext,
|
|
81
|
+
defaultValues,
|
|
82
|
+
})
|
|
83
|
+
}
|
|
80
84
|
|
|
81
85
|
const whereClause = id === undefined ? '' : `where id = '${id}'`
|
|
82
86
|
const queryStr = sql`select * from ${componentTableName} ${whereClause} limit 1`
|
|
@@ -110,6 +114,10 @@ export type RowResultEncoded<TTableDef extends TableDef> = TTableDef['isSingleCo
|
|
|
110
114
|
? GetValForKey<SqliteDsl.FromColumns.RowEncoded<TTableDef['schema']['columns']>, 'value'>
|
|
111
115
|
: SqliteDsl.FromColumns.RowEncoded<TTableDef['schema']['columns']>
|
|
112
116
|
|
|
117
|
+
export type RowInsert<TTableDef extends TableDef> = TTableDef['isSingleColumn'] extends true
|
|
118
|
+
? GetValForKey<SqliteDsl.FromColumns.InsertRowDecoded<TTableDef['schema']['columns']>, 'value'>
|
|
119
|
+
: SqliteDsl.FromColumns.InsertRowDecoded<TTableDef['schema']['columns']>
|
|
120
|
+
|
|
113
121
|
const insertRowWithDefaultValuesOrIgnore = ({
|
|
114
122
|
db,
|
|
115
123
|
id,
|
|
@@ -135,11 +143,11 @@ const insertRowWithDefaultValuesOrIgnore = ({
|
|
|
135
143
|
stateSchema.columns,
|
|
136
144
|
ReadonlyRecord.filter((_, key) => key !== 'id'),
|
|
137
145
|
ReadonlyRecord.map((column, columnName) =>
|
|
138
|
-
column.default ===
|
|
146
|
+
column.default._tag === 'None'
|
|
139
147
|
? column.nullable === true
|
|
140
148
|
? null
|
|
141
149
|
: shouldNeverHappen(`Column ${columnName} has no default value and is not nullable`)
|
|
142
|
-
: Schema.encodeSync(column.
|
|
150
|
+
: Schema.encodeSync(column.schema)(column.default.value),
|
|
143
151
|
),
|
|
144
152
|
ReadonlyRecord.map((val, columnName) => explicitDefaultValues?.[columnName] ?? val),
|
|
145
153
|
)
|
package/src/schema/table-def.ts
CHANGED
|
@@ -3,19 +3,7 @@ import { ReadonlyRecord, Schema } from '@livestore/utils/effect'
|
|
|
3
3
|
import type { Nullable, PrettifyFlat } from 'effect-db-schema'
|
|
4
4
|
import { SqliteAst, SqliteDsl } from 'effect-db-schema'
|
|
5
5
|
|
|
6
|
-
export const {
|
|
7
|
-
blob,
|
|
8
|
-
blobWithSchema,
|
|
9
|
-
boolean,
|
|
10
|
-
column,
|
|
11
|
-
datetime,
|
|
12
|
-
integer,
|
|
13
|
-
isColumnDefinition,
|
|
14
|
-
json,
|
|
15
|
-
real,
|
|
16
|
-
text,
|
|
17
|
-
textWithSchema,
|
|
18
|
-
} = SqliteDsl
|
|
6
|
+
export const { blob, boolean, column, datetime, integer, isColumnDefinition, json, real, text } = SqliteDsl
|
|
19
7
|
|
|
20
8
|
export { type SqliteDsl as __SqliteDsl } from 'effect-db-schema'
|
|
21
9
|
|
|
@@ -91,7 +79,7 @@ export const table = <
|
|
|
91
79
|
}
|
|
92
80
|
} else if (columns.id === undefined && ReadonlyRecord.some(columns, (_) => _.primaryKey === true) === false) {
|
|
93
81
|
if (options_.isSingleton) {
|
|
94
|
-
columns.id = SqliteDsl.
|
|
82
|
+
columns.id = SqliteDsl.text({ schema: Schema.literal('singleton'), primaryKey: true, default: 'singleton' })
|
|
95
83
|
} else {
|
|
96
84
|
columns.id = SqliteDsl.text({ primaryKey: true })
|
|
97
85
|
}
|
|
@@ -101,7 +89,7 @@ export const table = <
|
|
|
101
89
|
|
|
102
90
|
if (options_.isSingleton) {
|
|
103
91
|
for (const column of schema.ast.columns) {
|
|
104
|
-
if (column.nullable === false && column.default ===
|
|
92
|
+
if (column.nullable === false && column.default._tag === 'None') {
|
|
105
93
|
shouldNeverHappen(
|
|
106
94
|
`When creating a singleton table, each column must be either nullable or have a default value. Column '${column.name}' is neither.`,
|
|
107
95
|
)
|
|
@@ -130,10 +118,10 @@ type WithId<TColumns extends SqliteDsl.Columns, TOptions extends TableOptions> =
|
|
|
130
118
|
? {}
|
|
131
119
|
: TOptions['isSingleton'] extends true
|
|
132
120
|
? {
|
|
133
|
-
id: SqliteDsl.ColumnDefinition<
|
|
121
|
+
id: SqliteDsl.ColumnDefinition<'singleton', 'singleton'>
|
|
134
122
|
}
|
|
135
123
|
: {
|
|
136
|
-
id: SqliteDsl.ColumnDefinition<
|
|
124
|
+
id: SqliteDsl.ColumnDefinition<string, string>
|
|
137
125
|
})
|
|
138
126
|
|
|
139
127
|
type WithDefaults<TOptionsInput extends TableOptionsInput> = {
|
|
@@ -154,11 +142,11 @@ export namespace FromTable {
|
|
|
154
142
|
>
|
|
155
143
|
|
|
156
144
|
export type Columns<TTableDef extends TableDef> = {
|
|
157
|
-
[K in keyof TTableDef['schema']['columns']]: TTableDef['schema']['columns'][K]['
|
|
145
|
+
[K in keyof TTableDef['schema']['columns']]: TTableDef['schema']['columns'][K]['columnType']
|
|
158
146
|
}
|
|
159
147
|
|
|
160
148
|
export type RowEncodeNonNullable<TTableDef extends TableDef> = {
|
|
161
|
-
[K in keyof TTableDef['schema']['columns']]: Schema.Schema.From<TTableDef['schema']['columns'][K]['
|
|
149
|
+
[K in keyof TTableDef['schema']['columns']]: Schema.Schema.From<TTableDef['schema']['columns'][K]['schema']>
|
|
162
150
|
}
|
|
163
151
|
|
|
164
152
|
export type RowEncoded<TTableDef extends TableDef> = PrettifyFlat<
|
|
@@ -167,7 +155,7 @@ export namespace FromTable {
|
|
|
167
155
|
>
|
|
168
156
|
|
|
169
157
|
export type RowDecodedAll<TTableDef extends TableDef> = {
|
|
170
|
-
[K in keyof TTableDef['schema']['columns']]: Schema.Schema.To<TTableDef['schema']['columns'][K]['
|
|
158
|
+
[K in keyof TTableDef['schema']['columns']]: Schema.Schema.To<TTableDef['schema']['columns'][K]['schema']>
|
|
171
159
|
}
|
|
172
160
|
}
|
|
173
161
|
|
|
@@ -179,7 +167,7 @@ export namespace FromColumns {
|
|
|
179
167
|
>
|
|
180
168
|
|
|
181
169
|
export type RowDecodedAll<TColumns extends SqliteDsl.Columns> = {
|
|
182
|
-
[K in keyof TColumns]: Schema.Schema.To<TColumns[K]['
|
|
170
|
+
[K in keyof TColumns]: Schema.Schema.To<TColumns[K]['schema']>
|
|
183
171
|
}
|
|
184
172
|
|
|
185
173
|
export type RowEncoded<TColumns extends SqliteDsl.Columns> = PrettifyFlat<
|
|
@@ -188,10 +176,15 @@ export namespace FromColumns {
|
|
|
188
176
|
>
|
|
189
177
|
|
|
190
178
|
export type RowEncodeNonNullable<TColumns extends SqliteDsl.Columns> = {
|
|
191
|
-
[K in keyof TColumns]: Schema.Schema.From<TColumns[K]['
|
|
179
|
+
[K in keyof TColumns]: Schema.Schema.From<TColumns[K]['schema']>
|
|
192
180
|
}
|
|
193
181
|
|
|
194
182
|
export type NullableColumnNames<TColumns extends SqliteDsl.Columns> = keyof {
|
|
195
|
-
[K in keyof TColumns as TColumns[K] extends
|
|
183
|
+
[K in keyof TColumns as TColumns[K]['default'] extends true ? K : never]: {}
|
|
196
184
|
}
|
|
185
|
+
|
|
186
|
+
export type RequiredInsertColumnNames<TColumns extends SqliteDsl.Columns> =
|
|
187
|
+
SqliteDsl.FromColumns.RequiredInsertColumnNames<TColumns>
|
|
188
|
+
|
|
189
|
+
export type InsertRowDecoded<TColumns extends SqliteDsl.Columns> = SqliteDsl.FromColumns.InsertRowDecoded<TColumns>
|
|
197
190
|
}
|
package/tsconfig.json
CHANGED