@livestore/common 0.4.0-dev.16 → 0.4.0-dev.18
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/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 +24 -24
- package/dist/leader-thread/leader-worker-devtools.js +22 -38
- package/dist/leader-thread/leader-worker-devtools.js.map +1 -1
- package/dist/schema/state/sqlite/column-annotations.test.js +1 -1
- package/dist/schema/state/sqlite/column-annotations.test.js.map +1 -1
- package/dist/schema/state/sqlite/column-def.js +48 -29
- package/dist/schema/state/sqlite/column-def.js.map +1 -1
- package/dist/schema/state/sqlite/column-def.test.js +15 -5
- package/dist/schema/state/sqlite/column-def.test.js.map +1 -1
- package/dist/schema/state/sqlite/query-builder/impl.d.ts.map +1 -1
- package/dist/schema/state/sqlite/query-builder/impl.js +0 -1
- package/dist/schema/state/sqlite/query-builder/impl.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +4 -4
- package/src/leader-thread/leader-worker-devtools.ts +42 -50
- package/src/schema/state/sqlite/column-annotations.test.ts +1 -1
- package/src/schema/state/sqlite/column-def.test.ts +21 -5
- package/src/schema/state/sqlite/column-def.ts +58 -32
- package/src/schema/state/sqlite/query-builder/impl.ts +0 -1
- package/src/version.ts +1 -1
|
@@ -273,11 +273,27 @@ describe('getColumnDefForSchema', () => {
|
|
|
273
273
|
INACTIVE: 'inactive',
|
|
274
274
|
})
|
|
275
275
|
|
|
276
|
-
const StatusUnion = Schema.
|
|
276
|
+
const StatusUnion = Schema.Literal('pending', 'active', 'inactive')
|
|
277
277
|
|
|
278
278
|
expect(State.SQLite.getColumnDefForSchema(StatusEnum).columnType).toBe('text')
|
|
279
279
|
expect(State.SQLite.getColumnDefForSchema(StatusUnion).columnType).toBe('text')
|
|
280
280
|
})
|
|
281
|
+
|
|
282
|
+
it('should handle unions of numeric literals as integer column', () => {
|
|
283
|
+
const IntervalSchema = Schema.Literal(1, 5, 15, 30)
|
|
284
|
+
|
|
285
|
+
const columnDef = State.SQLite.getColumnDefForSchema(IntervalSchema)
|
|
286
|
+
|
|
287
|
+
expect(columnDef.columnType).toBe('integer')
|
|
288
|
+
})
|
|
289
|
+
|
|
290
|
+
it('should handle unions of non-integer numeric literals as real column', () => {
|
|
291
|
+
const PercentSchema = Schema.Literal(0.1, 0.2, 0.25)
|
|
292
|
+
|
|
293
|
+
const columnDef = State.SQLite.getColumnDefForSchema(PercentSchema)
|
|
294
|
+
|
|
295
|
+
expect(columnDef.columnType).toBe('real')
|
|
296
|
+
})
|
|
281
297
|
})
|
|
282
298
|
|
|
283
299
|
describe('binary data', () => {
|
|
@@ -552,7 +568,7 @@ describe('getColumnDefForSchema', () => {
|
|
|
552
568
|
|
|
553
569
|
it('should work with column type annotation', () => {
|
|
554
570
|
const UserSchema = Schema.Struct({
|
|
555
|
-
id: Schema.Number.pipe(withColumnType('integer')
|
|
571
|
+
id: Schema.Number.pipe(withColumnType('integer'), withPrimaryKey),
|
|
556
572
|
name: Schema.String,
|
|
557
573
|
})
|
|
558
574
|
|
|
@@ -584,7 +600,7 @@ describe('getColumnDefForSchema', () => {
|
|
|
584
600
|
describe('withAutoIncrement', () => {
|
|
585
601
|
it('should add autoIncrement annotation to schema', () => {
|
|
586
602
|
const UserSchema = Schema.Struct({
|
|
587
|
-
id: Schema.Int.pipe(withPrimaryKey
|
|
603
|
+
id: Schema.Int.pipe(withPrimaryKey, withAutoIncrement),
|
|
588
604
|
name: Schema.String,
|
|
589
605
|
})
|
|
590
606
|
const userTable = State.SQLite.table({
|
|
@@ -704,7 +720,7 @@ describe('getColumnDefForSchema', () => {
|
|
|
704
720
|
|
|
705
721
|
describe('combined annotations', () => {
|
|
706
722
|
it('should work with multiple annotations', () => {
|
|
707
|
-
const schema = Schema.Uint8ArrayFromBase64.pipe(withColumnType('blob')
|
|
723
|
+
const schema = Schema.Uint8ArrayFromBase64.pipe(withColumnType('blob'), withPrimaryKey)
|
|
708
724
|
|
|
709
725
|
const UserSchema = Schema.Struct({
|
|
710
726
|
id: schema,
|
|
@@ -722,7 +738,7 @@ describe('getColumnDefForSchema', () => {
|
|
|
722
738
|
|
|
723
739
|
it('should combine all annotations', () => {
|
|
724
740
|
const UserSchema = Schema.Struct({
|
|
725
|
-
id: Schema.Int.pipe(withPrimaryKey
|
|
741
|
+
id: Schema.Int.pipe(withPrimaryKey, withAutoIncrement),
|
|
726
742
|
email: Schema.String.pipe(withUnique),
|
|
727
743
|
status: Schema.String.pipe(withDefault('active')),
|
|
728
744
|
metadata: Schema.Unknown.pipe(withColumnType('text')),
|
|
@@ -179,33 +179,12 @@ const getColumnForSchema = (schema: Schema.Schema.AnyNoContext, nullable = false
|
|
|
179
179
|
return SqliteDsl.real({ schema: coreSchema, nullable })
|
|
180
180
|
}
|
|
181
181
|
|
|
182
|
-
|
|
183
|
-
if (
|
|
184
|
-
const value = coreAst.literal
|
|
185
|
-
if (typeof value === 'boolean') return SqliteDsl.boolean({ nullable })
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
if (isLiteralUnionOf(coreAst, (value): value is string => typeof value === 'string')) {
|
|
189
|
-
return SqliteDsl.text({ schema: coreSchema, nullable })
|
|
190
|
-
}
|
|
182
|
+
const literalColumn = getLiteralColumnDefinition(encodedAst, coreSchema, nullable, coreAst)
|
|
183
|
+
if (literalColumn) return literalColumn
|
|
191
184
|
|
|
192
|
-
//
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
if (typeof value === 'string') return SqliteDsl.text({ schema: coreSchema, nullable })
|
|
196
|
-
if (typeof value === 'number') {
|
|
197
|
-
// Check if the original schema is Int
|
|
198
|
-
const id = SchemaAST.getIdentifierAnnotation(coreAst).pipe(Option.getOrElse(() => ''))
|
|
199
|
-
if (id === 'Int') {
|
|
200
|
-
return SqliteDsl.integer({ schema: coreSchema, nullable })
|
|
201
|
-
}
|
|
202
|
-
return SqliteDsl.real({ schema: coreSchema, nullable })
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
if (isLiteralUnionOf(encodedAst, (value): value is string => typeof value === 'string')) {
|
|
207
|
-
return SqliteDsl.text({ schema: coreSchema, nullable })
|
|
208
|
-
}
|
|
185
|
+
// Fallback to checking the original AST in case the encoded schema differs
|
|
186
|
+
const coreLiteralColumn = getLiteralColumnDefinition(coreAst, coreSchema, nullable, coreAst)
|
|
187
|
+
if (coreLiteralColumn) return coreLiteralColumn
|
|
209
188
|
|
|
210
189
|
// Everything else needs JSON encoding
|
|
211
190
|
return SqliteDsl.json({ schema: coreSchema, nullable })
|
|
@@ -230,10 +209,57 @@ const stripNullable = (ast: SchemaAST.AST): SchemaAST.AST => {
|
|
|
230
209
|
return SchemaAST.Union.make(coreTypes, ast.annotations)
|
|
231
210
|
}
|
|
232
211
|
|
|
233
|
-
const
|
|
212
|
+
const getLiteralColumnDefinition = (
|
|
234
213
|
ast: SchemaAST.AST,
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
SchemaAST.
|
|
238
|
-
|
|
239
|
-
|
|
214
|
+
schema: Schema.Schema.AnyNoContext,
|
|
215
|
+
nullable: boolean,
|
|
216
|
+
sourceAst: SchemaAST.AST,
|
|
217
|
+
): SqliteDsl.ColumnDefinition.Any | null => {
|
|
218
|
+
const literalValues = extractLiteralValues(ast)
|
|
219
|
+
if (!literalValues) return null
|
|
220
|
+
|
|
221
|
+
const literalType = getLiteralValueType(literalValues)
|
|
222
|
+
switch (literalType) {
|
|
223
|
+
case 'string':
|
|
224
|
+
return SqliteDsl.text({ schema, nullable })
|
|
225
|
+
case 'number': {
|
|
226
|
+
const id = SchemaAST.getIdentifierAnnotation(sourceAst).pipe(Option.getOrElse(() => ''))
|
|
227
|
+
if (id === 'Int' || id === 'DateFromNumber') {
|
|
228
|
+
return SqliteDsl.integer({ schema, nullable })
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
const useIntegerColumn =
|
|
232
|
+
literalValues.length > 1 && literalValues.every((value) => typeof value === 'number' && Number.isInteger(value))
|
|
233
|
+
|
|
234
|
+
return useIntegerColumn ? SqliteDsl.integer({ schema, nullable }) : SqliteDsl.real({ schema, nullable })
|
|
235
|
+
}
|
|
236
|
+
case 'boolean':
|
|
237
|
+
return SqliteDsl.boolean({ nullable })
|
|
238
|
+
case 'bigint':
|
|
239
|
+
return SqliteDsl.integer({ schema, nullable })
|
|
240
|
+
default:
|
|
241
|
+
return null
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
const extractLiteralValues = (ast: SchemaAST.AST): ReadonlyArray<SchemaAST.LiteralValue> | null => {
|
|
246
|
+
if (SchemaAST.isLiteral(ast)) return [ast.literal]
|
|
247
|
+
|
|
248
|
+
if (SchemaAST.isUnion(ast) && ast.types.length > 0 && ast.types.every((type) => SchemaAST.isLiteral(type))) {
|
|
249
|
+
return ast.types.map((type) => (type as SchemaAST.Literal).literal)
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
return null
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
const getLiteralValueType = (
|
|
256
|
+
literals: ReadonlyArray<SchemaAST.LiteralValue>,
|
|
257
|
+
): 'string' | 'number' | 'boolean' | 'bigint' | null => {
|
|
258
|
+
const literalTypes = new Set(literals.map((value) => (value === null ? 'null' : typeof value)))
|
|
259
|
+
if (literalTypes.size !== 1) return null
|
|
260
|
+
|
|
261
|
+
const [literalType] = literalTypes
|
|
262
|
+
return literalType === 'string' || literalType === 'number' || literalType === 'boolean' || literalType === 'bigint'
|
|
263
|
+
? literalType
|
|
264
|
+
: null
|
|
265
|
+
}
|
|
@@ -35,7 +35,6 @@ export const makeQueryBuilder = <TResult, TTableDef extends TableDefBase>(
|
|
|
35
35
|
select: { columns },
|
|
36
36
|
}) as any
|
|
37
37
|
},
|
|
38
|
-
// biome-ignore lint/complexity/useArrowFunction: prefer function over arrow function for this case
|
|
39
38
|
where: function () {
|
|
40
39
|
if (ast._tag === 'InsertQuery') return invalidQueryBuilder('Cannot use where with insert')
|
|
41
40
|
if (ast._tag === 'RowQuery') return invalidQueryBuilder('Cannot use where with row')
|
package/src/version.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// import packageJson from '../package.json' with { type: 'json' }
|
|
3
3
|
// export const liveStoreVersion = packageJson.version
|
|
4
4
|
|
|
5
|
-
export const liveStoreVersion = '0.4.0-dev.
|
|
5
|
+
export const liveStoreVersion = '0.4.0-dev.18' as const
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* CRITICAL: Increment this version whenever you modify client-side EVENTLOG table schemas.
|