@livestore/common 0.4.0-dev.22 → 0.4.0-dev.24

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.
Files changed (314) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/ClientSessionLeaderThreadProxy.d.ts +9 -9
  3. package/dist/ClientSessionLeaderThreadProxy.d.ts.map +1 -1
  4. package/dist/WorkerTransportError.d.ts +11 -0
  5. package/dist/WorkerTransportError.d.ts.map +1 -0
  6. package/dist/WorkerTransportError.js +11 -0
  7. package/dist/WorkerTransportError.js.map +1 -0
  8. package/dist/adapter-types.d.ts +3 -3
  9. package/dist/adapter-types.d.ts.map +1 -1
  10. package/dist/adapter-types.js.map +1 -1
  11. package/dist/bounded-collections.d.ts.map +1 -1
  12. package/dist/bounded-collections.js +6 -4
  13. package/dist/bounded-collections.js.map +1 -1
  14. package/dist/debug-info.js +4 -4
  15. package/dist/debug-info.js.map +1 -1
  16. package/dist/devtools/devtools-messages-common.js +1 -1
  17. package/dist/devtools/devtools-messages-common.js.map +1 -1
  18. package/dist/devtools/mod.js +1 -1
  19. package/dist/devtools/mod.js.map +1 -1
  20. package/dist/errors.d.ts +15 -15
  21. package/dist/errors.d.ts.map +1 -1
  22. package/dist/errors.js +11 -11
  23. package/dist/errors.js.map +1 -1
  24. package/dist/index.d.ts +2 -0
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +2 -0
  27. package/dist/index.js.map +1 -1
  28. package/dist/leader-thread/LeaderSyncProcessor.d.ts +20 -6
  29. package/dist/leader-thread/LeaderSyncProcessor.d.ts.map +1 -1
  30. package/dist/leader-thread/LeaderSyncProcessor.js +287 -257
  31. package/dist/leader-thread/LeaderSyncProcessor.js.map +1 -1
  32. package/dist/leader-thread/RejectedPushError.d.ts +107 -0
  33. package/dist/leader-thread/RejectedPushError.d.ts.map +1 -0
  34. package/dist/leader-thread/RejectedPushError.js +78 -0
  35. package/dist/leader-thread/RejectedPushError.js.map +1 -0
  36. package/dist/leader-thread/connection.js +1 -1
  37. package/dist/leader-thread/connection.js.map +1 -1
  38. package/dist/leader-thread/eventlog.d.ts.map +1 -1
  39. package/dist/leader-thread/eventlog.js +12 -11
  40. package/dist/leader-thread/eventlog.js.map +1 -1
  41. package/dist/leader-thread/leader-worker-devtools.d.ts +1 -2
  42. package/dist/leader-thread/leader-worker-devtools.d.ts.map +1 -1
  43. package/dist/leader-thread/leader-worker-devtools.js +25 -14
  44. package/dist/leader-thread/leader-worker-devtools.js.map +1 -1
  45. package/dist/leader-thread/make-leader-thread-layer.d.ts +8 -3
  46. package/dist/leader-thread/make-leader-thread-layer.d.ts.map +1 -1
  47. package/dist/leader-thread/make-leader-thread-layer.js +7 -10
  48. package/dist/leader-thread/make-leader-thread-layer.js.map +1 -1
  49. package/dist/leader-thread/make-leader-thread-layer.test.js +1 -1
  50. package/dist/leader-thread/make-leader-thread-layer.test.js.map +1 -1
  51. package/dist/leader-thread/materialize-event.js +4 -4
  52. package/dist/leader-thread/materialize-event.js.map +1 -1
  53. package/dist/leader-thread/recreate-db.js +1 -1
  54. package/dist/leader-thread/recreate-db.js.map +1 -1
  55. package/dist/leader-thread/shutdown-channel.d.ts +2 -2
  56. package/dist/leader-thread/shutdown-channel.d.ts.map +1 -1
  57. package/dist/leader-thread/shutdown-channel.js +2 -2
  58. package/dist/leader-thread/shutdown-channel.js.map +1 -1
  59. package/dist/leader-thread/stream-events.d.ts.map +1 -1
  60. package/dist/leader-thread/stream-events.js +4 -3
  61. package/dist/leader-thread/stream-events.js.map +1 -1
  62. package/dist/leader-thread/types.d.ts +7 -6
  63. package/dist/leader-thread/types.d.ts.map +1 -1
  64. package/dist/leader-thread/types.js.map +1 -1
  65. package/dist/logging.js +4 -4
  66. package/dist/logging.js.map +1 -1
  67. package/dist/make-client-session.js +2 -2
  68. package/dist/make-client-session.js.map +1 -1
  69. package/dist/materializer-helper.js +6 -6
  70. package/dist/materializer-helper.js.map +1 -1
  71. package/dist/otel.d.ts +1 -1
  72. package/dist/otel.d.ts.map +1 -1
  73. package/dist/otel.js +2 -2
  74. package/dist/otel.js.map +1 -1
  75. package/dist/rematerialize-from-eventlog.d.ts +1 -1
  76. package/dist/rematerialize-from-eventlog.d.ts.map +1 -1
  77. package/dist/rematerialize-from-eventlog.js +11 -9
  78. package/dist/rematerialize-from-eventlog.js.map +1 -1
  79. package/dist/schema/EventDef/define.d.ts +2 -2
  80. package/dist/schema/EventDef/define.d.ts.map +1 -1
  81. package/dist/schema/EventDef/define.js +4 -4
  82. package/dist/schema/EventDef/define.js.map +1 -1
  83. package/dist/schema/EventDef/deprecated.js +3 -3
  84. package/dist/schema/EventDef/deprecated.js.map +1 -1
  85. package/dist/schema/EventDef/deprecated.test.js +1 -1
  86. package/dist/schema/EventDef/deprecated.test.js.map +1 -1
  87. package/dist/schema/EventSequenceNumber/client.d.ts.map +1 -1
  88. package/dist/schema/EventSequenceNumber/client.js +11 -11
  89. package/dist/schema/EventSequenceNumber/client.js.map +1 -1
  90. package/dist/schema/EventSequenceNumber.test.js +1 -1
  91. package/dist/schema/EventSequenceNumber.test.js.map +1 -1
  92. package/dist/schema/LiveStoreEvent/client.d.ts +8 -0
  93. package/dist/schema/LiveStoreEvent/client.d.ts.map +1 -1
  94. package/dist/schema/LiveStoreEvent/client.js +15 -3
  95. package/dist/schema/LiveStoreEvent/client.js.map +1 -1
  96. package/dist/schema/LiveStoreEvent/client.test.d.ts +2 -0
  97. package/dist/schema/LiveStoreEvent/client.test.d.ts.map +1 -0
  98. package/dist/schema/LiveStoreEvent/client.test.js +111 -0
  99. package/dist/schema/LiveStoreEvent/client.test.js.map +1 -0
  100. package/dist/schema/schema.d.ts.map +1 -1
  101. package/dist/schema/schema.js +7 -4
  102. package/dist/schema/schema.js.map +1 -1
  103. package/dist/schema/state/sqlite/client-document-def.d.ts.map +1 -1
  104. package/dist/schema/state/sqlite/client-document-def.js +18 -6
  105. package/dist/schema/state/sqlite/client-document-def.js.map +1 -1
  106. package/dist/schema/state/sqlite/client-document-def.test.js +1 -1
  107. package/dist/schema/state/sqlite/client-document-def.test.js.map +1 -1
  108. package/dist/schema/state/sqlite/column-annotations.d.ts.map +1 -1
  109. package/dist/schema/state/sqlite/column-annotations.js +1 -1
  110. package/dist/schema/state/sqlite/column-annotations.js.map +1 -1
  111. package/dist/schema/state/sqlite/column-annotations.test.js +1 -1
  112. package/dist/schema/state/sqlite/column-annotations.test.js.map +1 -1
  113. package/dist/schema/state/sqlite/column-def.d.ts.map +1 -1
  114. package/dist/schema/state/sqlite/column-def.js +36 -34
  115. package/dist/schema/state/sqlite/column-def.js.map +1 -1
  116. package/dist/schema/state/sqlite/column-def.test.js +7 -6
  117. package/dist/schema/state/sqlite/column-def.test.js.map +1 -1
  118. package/dist/schema/state/sqlite/column-spec.d.ts.map +1 -1
  119. package/dist/schema/state/sqlite/column-spec.js +8 -8
  120. package/dist/schema/state/sqlite/column-spec.js.map +1 -1
  121. package/dist/schema/state/sqlite/column-spec.test.js +1 -1
  122. package/dist/schema/state/sqlite/column-spec.test.js.map +1 -1
  123. package/dist/schema/state/sqlite/db-schema/ast/sqlite.js +2 -2
  124. package/dist/schema/state/sqlite/db-schema/ast/sqlite.js.map +1 -1
  125. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.d.ts +2 -2
  126. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.d.ts.map +1 -1
  127. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.js +11 -2
  128. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.js.map +1 -1
  129. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.test.js +1 -1
  130. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.test.js.map +1 -1
  131. package/dist/schema/state/sqlite/db-schema/dsl/mod.d.ts +1 -1
  132. package/dist/schema/state/sqlite/db-schema/dsl/mod.d.ts.map +1 -1
  133. package/dist/schema/state/sqlite/db-schema/dsl/mod.js +1 -1
  134. package/dist/schema/state/sqlite/db-schema/dsl/mod.js.map +1 -1
  135. package/dist/schema/state/sqlite/mod.d.ts.map +1 -1
  136. package/dist/schema/state/sqlite/mod.js +3 -5
  137. package/dist/schema/state/sqlite/mod.js.map +1 -1
  138. package/dist/schema/state/sqlite/query-builder/api.d.ts +10 -2
  139. package/dist/schema/state/sqlite/query-builder/api.d.ts.map +1 -1
  140. package/dist/schema/state/sqlite/query-builder/astToSql.js +11 -11
  141. package/dist/schema/state/sqlite/query-builder/astToSql.js.map +1 -1
  142. package/dist/schema/state/sqlite/query-builder/impl.d.ts +1 -1
  143. package/dist/schema/state/sqlite/query-builder/impl.d.ts.map +1 -1
  144. package/dist/schema/state/sqlite/query-builder/impl.js +28 -14
  145. package/dist/schema/state/sqlite/query-builder/impl.js.map +1 -1
  146. package/dist/schema/state/sqlite/query-builder/impl.test.js +3 -2
  147. package/dist/schema/state/sqlite/query-builder/impl.test.js.map +1 -1
  148. package/dist/schema/state/sqlite/schema-helpers.js +2 -2
  149. package/dist/schema/state/sqlite/schema-helpers.js.map +1 -1
  150. package/dist/schema/state/sqlite/table-def.d.ts +5 -3
  151. package/dist/schema/state/sqlite/table-def.d.ts.map +1 -1
  152. package/dist/schema/state/sqlite/table-def.js +1 -1
  153. package/dist/schema/state/sqlite/table-def.js.map +1 -1
  154. package/dist/schema/state/sqlite/table-def.test.js +57 -4
  155. package/dist/schema/state/sqlite/table-def.test.js.map +1 -1
  156. package/dist/schema/unknown-events.d.ts +1 -1
  157. package/dist/schema/unknown-events.d.ts.map +1 -1
  158. package/dist/schema/unknown-events.js +1 -1
  159. package/dist/schema/unknown-events.js.map +1 -1
  160. package/dist/schema-management/__tests__/migrations-autoincrement-quoting.test.js +1 -1
  161. package/dist/schema-management/__tests__/migrations-autoincrement-quoting.test.js.map +1 -1
  162. package/dist/schema-management/common.js +2 -2
  163. package/dist/schema-management/common.js.map +1 -1
  164. package/dist/schema-management/migrations.js +1 -1
  165. package/dist/schema-management/migrations.js.map +1 -1
  166. package/dist/sql-queries/sql-queries.js +8 -6
  167. package/dist/sql-queries/sql-queries.js.map +1 -1
  168. package/dist/sql-queries/sql-query-builder.d.ts.map +1 -1
  169. package/dist/sql-queries/sql-query-builder.js.map +1 -1
  170. package/dist/sqlite-db-helper.js +3 -3
  171. package/dist/sqlite-db-helper.js.map +1 -1
  172. package/dist/sqlite-types.d.ts +2 -2
  173. package/dist/sqlite-types.d.ts.map +1 -1
  174. package/dist/sqlite-types.js.map +1 -1
  175. package/dist/sync/ClientSessionSyncProcessor.d.ts +8 -9
  176. package/dist/sync/ClientSessionSyncProcessor.d.ts.map +1 -1
  177. package/dist/sync/ClientSessionSyncProcessor.js +95 -113
  178. package/dist/sync/ClientSessionSyncProcessor.js.map +1 -1
  179. package/dist/sync/errors.d.ts +0 -38
  180. package/dist/sync/errors.d.ts.map +1 -1
  181. package/dist/sync/errors.js +3 -20
  182. package/dist/sync/errors.js.map +1 -1
  183. package/dist/sync/mock-sync-backend.d.ts +5 -3
  184. package/dist/sync/mock-sync-backend.d.ts.map +1 -1
  185. package/dist/sync/mock-sync-backend.js +70 -68
  186. package/dist/sync/mock-sync-backend.js.map +1 -1
  187. package/dist/sync/next/compact-events.js +6 -6
  188. package/dist/sync/next/compact-events.js.map +1 -1
  189. package/dist/sync/next/facts.d.ts.map +1 -1
  190. package/dist/sync/next/facts.js +6 -6
  191. package/dist/sync/next/facts.js.map +1 -1
  192. package/dist/sync/next/history-dag-common.d.ts.map +1 -1
  193. package/dist/sync/next/history-dag-common.js +6 -6
  194. package/dist/sync/next/history-dag-common.js.map +1 -1
  195. package/dist/sync/next/history-dag.js +3 -3
  196. package/dist/sync/next/history-dag.js.map +1 -1
  197. package/dist/sync/next/rebase-events.js +1 -1
  198. package/dist/sync/next/rebase-events.js.map +1 -1
  199. package/dist/sync/next/test/compact-events.calculator.test.js +2 -2
  200. package/dist/sync/next/test/compact-events.calculator.test.js.map +1 -1
  201. package/dist/sync/next/test/compact-events.test.d.ts.map +1 -1
  202. package/dist/sync/next/test/compact-events.test.js +2 -2
  203. package/dist/sync/next/test/compact-events.test.js.map +1 -1
  204. package/dist/sync/next/test/event-fixtures.d.ts.map +1 -1
  205. package/dist/sync/next/test/event-fixtures.js +2 -2
  206. package/dist/sync/next/test/event-fixtures.js.map +1 -1
  207. package/dist/sync/sync-backend-kv.d.ts.map +1 -1
  208. package/dist/sync/sync-backend-kv.js.map +1 -1
  209. package/dist/sync/sync-backend.d.ts +3 -3
  210. package/dist/sync/sync-backend.d.ts.map +1 -1
  211. package/dist/sync/sync-backend.js +1 -1
  212. package/dist/sync/sync-backend.js.map +1 -1
  213. package/dist/sync/sync.d.ts +20 -0
  214. package/dist/sync/sync.d.ts.map +1 -1
  215. package/dist/sync/syncstate.d.ts +4 -17
  216. package/dist/sync/syncstate.d.ts.map +1 -1
  217. package/dist/sync/syncstate.js +51 -74
  218. package/dist/sync/syncstate.js.map +1 -1
  219. package/dist/sync/syncstate.test.js +148 -96
  220. package/dist/sync/syncstate.test.js.map +1 -1
  221. package/dist/sync/transport-chunking.js +3 -3
  222. package/dist/sync/transport-chunking.js.map +1 -1
  223. package/dist/sync/validate-push-payload.d.ts +2 -2
  224. package/dist/sync/validate-push-payload.d.ts.map +1 -1
  225. package/dist/sync/validate-push-payload.js +4 -6
  226. package/dist/sync/validate-push-payload.js.map +1 -1
  227. package/dist/util.js +2 -2
  228. package/dist/util.js.map +1 -1
  229. package/dist/version.d.ts.map +1 -1
  230. package/dist/version.js +2 -5
  231. package/dist/version.js.map +1 -1
  232. package/package.json +66 -12
  233. package/src/ClientSessionLeaderThreadProxy.ts +9 -9
  234. package/src/WorkerTransportError.ts +12 -0
  235. package/src/adapter-types.ts +9 -3
  236. package/src/bounded-collections.ts +6 -5
  237. package/src/debug-info.ts +4 -4
  238. package/src/devtools/devtools-messages-common.ts +1 -1
  239. package/src/devtools/mod.ts +1 -1
  240. package/src/errors.ts +18 -17
  241. package/src/index.ts +2 -0
  242. package/src/leader-thread/LeaderSyncProcessor.ts +421 -392
  243. package/src/leader-thread/RejectedPushError.ts +106 -0
  244. package/src/leader-thread/connection.ts +1 -1
  245. package/src/leader-thread/eventlog.ts +16 -14
  246. package/src/leader-thread/leader-worker-devtools.ts +96 -66
  247. package/src/leader-thread/make-leader-thread-layer.test.ts +1 -1
  248. package/src/leader-thread/make-leader-thread-layer.ts +33 -31
  249. package/src/leader-thread/materialize-event.ts +4 -4
  250. package/src/leader-thread/recreate-db.ts +1 -1
  251. package/src/leader-thread/shutdown-channel.ts +2 -6
  252. package/src/leader-thread/stream-events.ts +10 -5
  253. package/src/leader-thread/types.ts +7 -6
  254. package/src/logging.ts +4 -4
  255. package/src/make-client-session.ts +2 -2
  256. package/src/materializer-helper.ts +9 -9
  257. package/src/otel.ts +3 -2
  258. package/src/rematerialize-from-eventlog.ts +60 -60
  259. package/src/schema/EventDef/define.ts +6 -6
  260. package/src/schema/EventDef/deprecated.test.ts +2 -1
  261. package/src/schema/EventDef/deprecated.ts +3 -3
  262. package/src/schema/EventSequenceNumber/client.ts +11 -11
  263. package/src/schema/EventSequenceNumber.test.ts +2 -1
  264. package/src/schema/LiveStoreEvent/client.test.ts +129 -0
  265. package/src/schema/LiveStoreEvent/client.ts +17 -3
  266. package/src/schema/schema.ts +9 -4
  267. package/src/schema/state/sqlite/client-document-def.test.ts +2 -1
  268. package/src/schema/state/sqlite/client-document-def.ts +20 -6
  269. package/src/schema/state/sqlite/column-annotations.test.ts +2 -1
  270. package/src/schema/state/sqlite/column-annotations.ts +2 -1
  271. package/src/schema/state/sqlite/column-def.test.ts +8 -6
  272. package/src/schema/state/sqlite/column-def.ts +41 -36
  273. package/src/schema/state/sqlite/column-spec.test.ts +3 -1
  274. package/src/schema/state/sqlite/column-spec.ts +9 -8
  275. package/src/schema/state/sqlite/db-schema/ast/sqlite.ts +2 -2
  276. package/src/schema/state/sqlite/db-schema/dsl/field-defs.test.ts +2 -1
  277. package/src/schema/state/sqlite/db-schema/dsl/field-defs.ts +13 -4
  278. package/src/schema/state/sqlite/db-schema/dsl/mod.ts +3 -3
  279. package/src/schema/state/sqlite/mod.ts +4 -5
  280. package/src/schema/state/sqlite/query-builder/api.ts +12 -5
  281. package/src/schema/state/sqlite/query-builder/astToSql.ts +11 -11
  282. package/src/schema/state/sqlite/query-builder/impl.test.ts +4 -2
  283. package/src/schema/state/sqlite/query-builder/impl.ts +26 -12
  284. package/src/schema/state/sqlite/schema-helpers.ts +2 -2
  285. package/src/schema/state/sqlite/table-def.test.ts +67 -4
  286. package/src/schema/state/sqlite/table-def.ts +8 -15
  287. package/src/schema/unknown-events.ts +2 -2
  288. package/src/schema-management/__tests__/migrations-autoincrement-quoting.test.ts +3 -1
  289. package/src/schema-management/common.ts +2 -2
  290. package/src/schema-management/migrations.ts +1 -1
  291. package/src/sql-queries/sql-queries.ts +10 -6
  292. package/src/sql-queries/sql-query-builder.ts +1 -0
  293. package/src/sqlite-db-helper.ts +3 -3
  294. package/src/sqlite-types.ts +3 -2
  295. package/src/sync/ClientSessionSyncProcessor.ts +148 -152
  296. package/src/sync/errors.ts +10 -22
  297. package/src/sync/mock-sync-backend.ts +139 -97
  298. package/src/sync/next/compact-events.ts +5 -5
  299. package/src/sync/next/facts.ts +7 -6
  300. package/src/sync/next/history-dag-common.ts +9 -6
  301. package/src/sync/next/history-dag.ts +3 -3
  302. package/src/sync/next/rebase-events.ts +1 -1
  303. package/src/sync/next/test/compact-events.calculator.test.ts +3 -2
  304. package/src/sync/next/test/compact-events.test.ts +4 -3
  305. package/src/sync/next/test/event-fixtures.ts +2 -2
  306. package/src/sync/sync-backend-kv.ts +1 -0
  307. package/src/sync/sync-backend.ts +5 -4
  308. package/src/sync/sync.ts +21 -0
  309. package/src/sync/syncstate.test.ts +553 -433
  310. package/src/sync/syncstate.ts +80 -86
  311. package/src/sync/transport-chunking.ts +3 -3
  312. package/src/sync/validate-push-payload.ts +4 -6
  313. package/src/util.ts +2 -2
  314. package/src/version.ts +2 -6
@@ -1,4 +1,5 @@
1
1
  import { Schema } from '@livestore/utils/effect'
2
+
2
3
  import { type SqliteAst, SqliteDsl } from './db-schema/mod.ts'
3
4
 
4
5
  /**
@@ -12,13 +13,13 @@ import { type SqliteAst, SqliteDsl } from './db-schema/mod.ts'
12
13
  export const makeColumnSpec = (tableAst: SqliteAst.Table) => {
13
14
  const pkColumns = tableAst.columns.filter((_) => _.primaryKey)
14
15
  const hasSinglePk = pkColumns.length === 1
15
- const pkColumn = hasSinglePk ? pkColumns[0] : undefined
16
+ const pkColumn = hasSinglePk === true ? pkColumns[0] : undefined
16
17
 
17
18
  // Build column definitions, handling the special SQLite rule that AUTOINCREMENT
18
19
  // is only valid on a single column declared as INTEGER PRIMARY KEY (column-level).
19
20
  const columnDefStrs = tableAst.columns.map((column) =>
20
21
  toSqliteColumnSpec(column, {
21
- inlinePrimaryKey: hasSinglePk && column === pkColumn && column.primaryKey === true,
22
+ inlinePrimaryKey: hasSinglePk && column === pkColumn && column.primaryKey,
22
23
  }),
23
24
  )
24
25
 
@@ -36,24 +37,24 @@ const toSqliteColumnSpec = (column: SqliteAst.Column, opts: { inlinePrimaryKey:
36
37
  const columnTypeStr = column.type._tag
37
38
  // When PRIMARY KEY is declared inline, NOT NULL is implied and should not be emitted,
38
39
  // and AUTOINCREMENT must immediately follow PRIMARY KEY within the same constraint.
39
- const nullableStr = opts.inlinePrimaryKey ? '' : column.nullable === false ? 'not null' : ''
40
+ const nullableStr = opts.inlinePrimaryKey === true ? '' : column.nullable === false ? 'not null' : ''
40
41
 
41
42
  // Only include AUTOINCREMENT when it's valid: single-column INTEGER PRIMARY KEY
42
- const includeAutoIncrement = opts.inlinePrimaryKey && column.type._tag === 'integer' && column.autoIncrement === true
43
+ const includeAutoIncrement = opts.inlinePrimaryKey === true && column.type._tag === 'integer' && column.autoIncrement === true
43
44
 
44
- const pkStr = opts.inlinePrimaryKey ? 'primary key' : ''
45
- const autoIncrementStr = includeAutoIncrement ? 'autoincrement' : ''
45
+ const pkStr = opts.inlinePrimaryKey === true ? 'primary key' : ''
46
+ const autoIncrementStr = includeAutoIncrement === true ? 'autoincrement' : ''
46
47
 
47
48
  const defaultValueStr = (() => {
48
49
  if (column.default._tag === 'None') return ''
49
50
 
50
51
  const defaultValue = column.default.value
51
- if (SqliteDsl.isDefaultThunk(defaultValue)) return ''
52
+ if (SqliteDsl.isDefaultThunk(defaultValue) === true) return ''
52
53
 
53
54
  const resolvedDefault = SqliteDsl.resolveColumnDefault(defaultValue)
54
55
 
55
56
  if (resolvedDefault === null) return 'default null'
56
- if (SqliteDsl.isSqlDefaultValue(resolvedDefault)) return `default ${resolvedDefault.sql}`
57
+ if (SqliteDsl.isSqlDefaultValue(resolvedDefault) === true) return `default ${resolvedDefault.sql}`
57
58
 
58
59
  const encodeValue = Schema.encodeSync(column.schema)
59
60
  const encodedDefaultValue = encodeValue(resolvedDefault)
@@ -124,7 +124,7 @@ const trimInfoForHasing = (obj: Table | Column | Index | ForeignKey | DbSchema):
124
124
 
125
125
  // NEW: Include schema hash for JSON columns
126
126
  // This ensures that changes to the JSON schema are detected
127
- if (isJsonColumn(obj) && obj.schema) {
127
+ if (isJsonColumn(obj) === true && obj.schema !== undefined) {
128
128
  // Use Effect's Schema.hash for consistent hashing
129
129
  baseInfo.jsonSchemaHash = Schema.hash(obj.schema)
130
130
  }
@@ -155,7 +155,7 @@ const trimInfoForHasing = (obj: Table | Column | Index | ForeignKey | DbSchema):
155
155
  }
156
156
  }
157
157
  default: {
158
- throw new Error(`Unreachable: ${obj}`)
158
+ throw new Error(`Unreachable: ${String(obj)}`)
159
159
  }
160
160
  }
161
161
  }
@@ -1,6 +1,7 @@
1
- import { Schema } from '@livestore/utils/effect'
2
1
  import { describe, expect, test } from 'vitest'
3
2
 
3
+ import { Schema } from '@livestore/utils/effect'
4
+
4
5
  import * as F from './field-defs.ts'
5
6
 
6
7
  describe.concurrent('FieldDefs', () => {
@@ -6,6 +6,7 @@ export type SqlDefaultValue = {
6
6
  }
7
7
 
8
8
  export const isSqlDefaultValue = (value: unknown): value is SqlDefaultValue => {
9
+ // oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- type guard property access after structural check
9
10
  return typeof value === 'object' && value !== null && 'sql' in value && typeof (value as any).sql === 'string'
10
11
  }
11
12
 
@@ -16,14 +17,14 @@ export const isDefaultThunk = (value: unknown): value is ColumnDefaultThunk<unkn
16
17
  export type ColumnDefaultValue<T> = T | null | ColumnDefaultThunk<T | null> | SqlDefaultValue
17
18
 
18
19
  export const resolveColumnDefault = <T>(value: ColumnDefaultValue<T>): T | null | SqlDefaultValue =>
19
- isDefaultThunk(value) ? (value as ColumnDefaultThunk<T | null>)() : value
20
+ isDefaultThunk(value) === true ? value() : value
20
21
 
21
- export type ColumnDefinition<TEncoded, TDecoded> = {
22
+ export type ColumnDefinition<TEncoded, TDecoded, TNullable extends boolean = boolean> = {
22
23
  readonly columnType: FieldColumnType
23
24
  readonly schema: Schema.Schema<TDecoded, TEncoded>
24
25
  readonly default: Option.Option<ColumnDefaultValue<TDecoded>>
25
26
  /** @default false */
26
- readonly nullable: boolean
27
+ readonly nullable: TNullable
27
28
  /** @default false */
28
29
  readonly primaryKey: boolean
29
30
  /** @default false */
@@ -40,6 +41,7 @@ export const isColumnDefinition = (value: unknown): value is ColumnDefinition.An
40
41
  typeof value === 'object' &&
41
42
  value !== null &&
42
43
  'columnType' in value &&
44
+ // oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- type guard narrowing; columnType checked to be in valid set
43
45
  validColumnTypes.includes(value.columnType as any)
44
46
  )
45
47
  }
@@ -105,6 +107,7 @@ const makeColDef =
105
107
  const schema = nullable === true ? Schema.NullOr(schemaWithoutNull) : schemaWithoutNull
106
108
  const default_ = def?.default === undefined || def.default === NoDefault ? Option.none() : Option.some(def.default)
107
109
 
110
+ // oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- column factory return type uses complex conditional generics; consumer type safety enforced by ColDefFn signature
108
111
  return {
109
112
  columnType,
110
113
  schema,
@@ -200,10 +203,12 @@ type MakeSpecializedColDefFn = {
200
203
 
201
204
  const makeSpecializedColDef: MakeSpecializedColDefFn = (columnType, opts) => (def?: ColumnDefinitionInput) => {
202
205
  const nullable = def?.nullable ?? false
206
+ // oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- schema type variance; custom schema compatibility checked at call site
203
207
  const schemaWithoutNull = opts._tag === 'baseSchemaFn' ? opts.baseSchemaFn(def?.schema as any) : opts.baseSchema
204
208
  const schema = nullable === true ? Schema.NullOr(schemaWithoutNull) : schemaWithoutNull
205
209
  const default_ = def?.default === undefined || def.default === NoDefault ? Option.none() : Option.some(def.default)
206
210
 
211
+ // oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- specialized column factory return type uses complex conditional generics; consumer type safety enforced by SpecializedColDefFn signature
207
212
  return {
208
213
  columnType,
209
214
  schema,
@@ -236,7 +241,7 @@ export const boolean: SpecializedColDefFn<'integer', false, boolean> = makeSpeci
236
241
  _tag: 'baseSchema',
237
242
  baseSchema: Schema.transform(Schema.Number, Schema.Boolean, {
238
243
  decode: (_) => _ === 1,
239
- encode: (_) => (_ ? 1 : 0),
244
+ encode: (_) => (_ === true ? 1 : 0),
240
245
  }),
241
246
  })
242
247
 
@@ -259,15 +264,19 @@ export const defaultSchemaForColumnType = <TColumnType extends FieldColumnType>(
259
264
 
260
265
  switch (columnType) {
261
266
  case 'text': {
267
+ // oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- switch-based type narrowing for column type to schema mapping; each case is correct for its branch
262
268
  return Schema.String as any as Schema.Schema<T>
263
269
  }
264
270
  case 'integer': {
271
+ // oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- switch-based type narrowing for column type to schema mapping; each case is correct for its branch
265
272
  return Schema.Number as any as Schema.Schema<T>
266
273
  }
267
274
  case 'real': {
275
+ // oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- switch-based type narrowing for column type to schema mapping; each case is correct for its branch
268
276
  return Schema.Number as any as Schema.Schema<T>
269
277
  }
270
278
  case 'blob': {
279
+ // oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- switch-based type narrowing for column type to schema mapping; each case is correct for its branch
271
280
  return Schema.Uint8ArrayFromSelf as any as Schema.Schema<T>
272
281
  }
273
282
  default: {
@@ -31,7 +31,7 @@ export type DbSchemaFromInputSchema<TSchemaInput extends DbSchemaInput> =
31
31
  export const makeDbSchema = <TDbSchemaInput extends DbSchemaInput>(
32
32
  schema: TDbSchemaInput,
33
33
  ): DbSchemaFromInputSchema<TDbSchemaInput> => {
34
- return Array.isArray(schema) ? Object.fromEntries(schema.map((_) => [_.name, _])) : (schema as any)
34
+ return Array.isArray(schema) === true ? Object.fromEntries(schema.map((_) => [_.name, _])) : (schema as any)
35
35
  }
36
36
 
37
37
  export const table = <TTableName extends string, TColumns extends Columns, TIndexes extends Index[]>(
@@ -76,6 +76,7 @@ export const insertStructSchemaForTable = <TTableDefinition extends TableDefinit
76
76
  Object.fromEntries(
77
77
  tableDef.ast.columns.map((column) => [
78
78
  column.name,
79
+
79
80
  column.nullable === true || column.default._tag === 'Some' ? Schema.optional(column.schema) : column.schema,
80
81
  ]),
81
82
  ),
@@ -195,8 +196,7 @@ export namespace FromColumns {
195
196
  }
196
197
 
197
198
  export type NullableColumnNames<TColumns extends Columns> = keyof {
198
- // TODO double check why there is a `true` in the type
199
- [K in keyof TColumns as TColumns[K] extends ColumnDefinition<any, true> ? K : never]: {}
199
+ [K in keyof TColumns as TColumns[K]['nullable'] extends true ? K : never]: {}
200
200
  }
201
201
 
202
202
  export type RequiredInsertColumns<TColumns extends Columns> = {
@@ -22,16 +22,15 @@ export * from './column-spec.ts'
22
22
  export * from './table-def.ts'
23
23
 
24
24
  export const makeState = <TStateInput extends InputState>(inputSchema: TStateInput): InternalState => {
25
- const inputTables: ReadonlyArray<TableDef> = Array.isArray(inputSchema.tables)
26
- ? inputSchema.tables
27
- : Object.values(inputSchema.tables)
25
+ const inputTables: ReadonlyArray<TableDef> =
26
+ Array.isArray(inputSchema.tables) === true ? inputSchema.tables : Object.values(inputSchema.tables)
28
27
 
29
28
  const tables = new Map<string, TableDef.Any>()
30
29
 
31
30
  for (const tableDef of inputTables) {
32
31
  const sqliteDef = tableDef.sqliteDef
33
32
  // TODO validate tables (e.g. index names are unique)
34
- if (tables.has(sqliteDef.ast.name)) {
33
+ if (tables.has(sqliteDef.ast.name) === true) {
35
34
  shouldNeverHappen(`Duplicate table name: ${sqliteDef.ast.name}. Please use unique names for tables.`)
36
35
  }
37
36
  tables.set(sqliteDef.ast.name, tableDef)
@@ -48,7 +47,7 @@ export const makeState = <TStateInput extends InputState>(inputSchema: TStateInp
48
47
  }
49
48
 
50
49
  for (const tableDef of inputTables) {
51
- if (tableIsClientDocumentTable(tableDef)) {
50
+ if (tableIsClientDocumentTable(tableDef) === true) {
52
51
  materializers.set(
53
52
  tableDef[ClientDocumentTableDefSymbol].derived.setEventDef.name,
54
53
  tableDef[ClientDocumentTableDefSymbol].derived.setMaterializer,
@@ -230,9 +230,8 @@ export namespace QueryBuilder {
230
230
  /** Select multiple columns */
231
231
  <TColumns extends keyof TTableDef['sqliteDef']['columns'] & string>(
232
232
  ...columns: TColumns[]
233
- // TODO also support arbitrary SQL selects
234
- // params: QueryBuilderSelectParams,
235
- ): QueryBuilder<
233
+ )// params: QueryBuilderSelectParams, // TODO also support arbitrary SQL selects
234
+ : QueryBuilder<
236
235
  ReadonlyArray<{
237
236
  readonly [K in TColumns]: TTableDef['sqliteDef']['columns'][K]['schema']['Type']
238
237
  }>,
@@ -358,12 +357,20 @@ export namespace QueryBuilder {
358
357
  >
359
358
 
360
359
  /**
361
- * Insert a new row into the table
360
+ * Insert a new row into the table.
361
+ *
362
+ * @remarks
363
+ *
364
+ * Follows SQL semantics: nullable columns and columns with defaults are omittable.
365
+ * `NullOr(S)` and `optional(NullOr(S))` both produce nullable columns, so both are omittable.
366
+ *
367
+ * @example
362
368
  *
363
- * Example:
364
369
  * ```ts
365
370
  * db.todos.insert({ id: '123', text: 'Buy milk', status: 'active' })
366
371
  * ```
372
+ *
373
+ * @param values - The row values to insert.
367
374
  */
368
375
  readonly insert: (
369
376
  values: TTableDef['insertSchema']['Type'],
@@ -11,11 +11,11 @@ import type { QueryBuilderAst } from './api.ts'
11
11
  * Returns the element schema, or undefined if not a JSON array transformation.
12
12
  */
13
13
  const extractArrayElementFromTransformation = (ast: SchemaAST.AST): Schema.Schema.Any | undefined => {
14
- if (!SchemaAST.isTransformation(ast)) return undefined
14
+ if (SchemaAST.isTransformation(ast) === false) return undefined
15
15
 
16
16
  const toAst = ast.to
17
17
  // Check if the "to" side is a TupleType (Effect's internal representation of Array)
18
- if (!SchemaAST.isTupleType(toAst)) return undefined
18
+ if (SchemaAST.isTupleType(toAst) === false) return undefined
19
19
 
20
20
  // For Schema.Array, rest contains { type: AST } elements - get the first one's type
21
21
  const restElement = toAst.rest[0]
@@ -34,13 +34,13 @@ const getJsonArrayElementSchema = (colSchema: Schema.Schema.Any): Schema.Schema.
34
34
 
35
35
  // Case 1: Direct transformation (non-nullable JSON array)
36
36
  // Schema.parseJson(Schema.Array(ElementSchema)) creates a Transformation AST
37
- if (SchemaAST.isTransformation(ast)) {
37
+ if (SchemaAST.isTransformation(ast) === true) {
38
38
  return extractArrayElementFromTransformation(ast)
39
39
  }
40
40
 
41
41
  // Case 2: Nullable JSON array - Schema.NullOr wraps the parseJson in a Union
42
42
  // Structure: Union([Transformation (JSON array), Literal (null)])
43
- if (SchemaAST.isUnion(ast)) {
43
+ if (SchemaAST.isUnion(ast) === true) {
44
44
  for (const member of ast.types) {
45
45
  const result = extractArrayElementFromTransformation(member)
46
46
  if (result !== undefined) return result
@@ -63,7 +63,7 @@ const encodeJsonArrayElementValue = (elementSchema: Schema.Schema.Any, value: un
63
63
  return JSON.stringify(encoded)
64
64
  }
65
65
  if (typeof encoded === 'boolean') {
66
- return encoded ? 1 : 0
66
+ return encoded === true ? 1 : 0
67
67
  }
68
68
 
69
69
  return encoded
@@ -118,9 +118,9 @@ const formatWhereClause = (
118
118
  // Handle array values for IN/NOT IN operators
119
119
  const isArray = op === 'IN' || op === 'NOT IN'
120
120
 
121
- if (isArray) {
121
+ if (isArray === true) {
122
122
  // Verify value is an array
123
- if (!Array.isArray(value)) {
123
+ if (Array.isArray(value) === false) {
124
124
  return shouldNeverHappen(`Expected array value for ${op} operator but got`, value)
125
125
  }
126
126
 
@@ -145,7 +145,7 @@ const formatWhereClause = (
145
145
  }
146
146
 
147
147
  const formatReturningClause = (returning?: string[]): string => {
148
- if (!returning || returning.length === 0) return ''
148
+ if (returning == null || returning.length === 0) return ''
149
149
  return ` RETURNING ${returning.map(quoteIdentifier).join(', ')}`
150
150
  }
151
151
 
@@ -169,7 +169,7 @@ export const astToSql = (ast: QueryBuilderAst): { query: string; bindValues: Sql
169
169
  let conflictClause = '' // Store the ON CONFLICT clause separately
170
170
 
171
171
  // Handle ON CONFLICT clause
172
- if (ast.onConflict) {
172
+ if (ast.onConflict !== undefined) {
173
173
  // Handle REPLACE specifically as it changes the INSERT verb
174
174
  if (ast.onConflict.action._tag === 'replace') {
175
175
  insertVerb = 'INSERT OR REPLACE'
@@ -249,7 +249,7 @@ export const astToSql = (ast: QueryBuilderAst): { query: string; bindValues: Sql
249
249
  .join(', ')}`
250
250
 
251
251
  const whereClause = formatWhereClause(ast.where, ast.tableDef, bindValues)
252
- if (whereClause) query += ` ${whereClause}`
252
+ if (whereClause !== undefined) query += ` ${whereClause}`
253
253
 
254
254
  query += formatReturningClause(ast.returning)
255
255
  return { query, bindValues, usedTables }
@@ -260,7 +260,7 @@ export const astToSql = (ast: QueryBuilderAst): { query: string; bindValues: Sql
260
260
  let query = `DELETE FROM '${ast.tableDef.sqliteDef.name}'`
261
261
 
262
262
  const whereClause = formatWhereClause(ast.where, ast.tableDef, bindValues)
263
- if (whereClause) query += ` ${whereClause}`
263
+ if (whereClause !== undefined) query += ` ${whereClause}`
264
264
 
265
265
  query += formatReturningClause(ast.returning)
266
266
  return { query, bindValues, usedTables }
@@ -1,6 +1,8 @@
1
- import { Schema } from '@livestore/utils/effect'
2
1
  import { describe, expect, it } from 'vitest'
3
2
 
3
+ import { Schema } from '@livestore/utils/effect'
4
+ import { objectToString } from '@livestore/utils'
5
+
4
6
  import { State } from '../../../mod.ts'
5
7
  import type { QueryBuilder } from './api.ts'
6
8
  import { getResultSchema } from './impl.ts'
@@ -101,7 +103,7 @@ const db = { todos, todosWithIntId, comments, issue, selections, UiState, UiStat
101
103
  const dump = (qb: QueryBuilder<any, any, any>) => ({
102
104
  bindValues: qb.asSql().bindValues,
103
105
  query: qb.asSql().query,
104
- schema: getResultSchema(qb).toString(),
106
+ schema: objectToString(getResultSchema(qb)),
105
107
  })
106
108
 
107
109
  describe('query builder', () => {
@@ -9,7 +9,7 @@ import { astToSql } from './astToSql.ts'
9
9
  export const makeQueryBuilder = <TResult, TTableDef extends TableDefBase>(
10
10
  tableDef: TTableDef,
11
11
  ast: QueryBuilderAst = emptyAst(tableDef),
12
- ): QueryBuilder<TResult, TTableDef, never> => {
12
+ ): QueryBuilder<TResult, TTableDef> => {
13
13
  const api = {
14
14
  select() {
15
15
  assertSelectQueryBuilderAst(ast)
@@ -18,6 +18,7 @@ export const makeQueryBuilder = <TResult, TTableDef extends TableDefBase>(
18
18
 
19
19
  // Pluck if there's only one column selected
20
20
  if (params.length === 1) {
21
+ // oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- arguments-based overload dispatch requires manual narrowing
21
22
  const [col] = params as any as [string]
22
23
  return makeQueryBuilder(tableDef, {
23
24
  ...ast,
@@ -26,8 +27,10 @@ export const makeQueryBuilder = <TResult, TTableDef extends TableDefBase>(
26
27
  })
27
28
  }
28
29
 
30
+ // oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- arguments-based overload dispatch requires manual narrowing
29
31
  const columns = params as unknown as ReadonlyArray<string>
30
32
 
33
+ // oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- query builder return type depends on AST state; consumer type safety enforced by api.ts
31
34
  return makeQueryBuilder(tableDef, {
32
35
  ...ast,
33
36
  resultSchemaSingle:
@@ -44,7 +47,8 @@ export const makeQueryBuilder = <TResult, TTableDef extends TableDefBase>(
44
47
  const newOps = Object.entries(params)
45
48
  .filter(([, value]) => value !== undefined)
46
49
  .map<QueryBuilderAst.Where>(([col, value]) =>
47
- Predicate.hasProperty(value, 'op') && Predicate.hasProperty(value, 'value')
50
+ Predicate.hasProperty(value, 'op') === true && Predicate.hasProperty(value, 'value') === true
51
+ // oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- where clause construction; shape validated at runtime
48
52
  ? ({ col, op: value.op, value: value.value } as any)
49
53
  : { col, op: '=', value },
50
54
  )
@@ -54,6 +58,7 @@ export const makeQueryBuilder = <TResult, TTableDef extends TableDefBase>(
54
58
  case 'SelectQuery':
55
59
  case 'UpdateQuery':
56
60
  case 'DeleteQuery': {
61
+ // oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- query builder return type depends on AST state; consumer type safety enforced by api.ts
57
62
  return makeQueryBuilder(tableDef, {
58
63
  ...ast,
59
64
  where: [...ast.where, ...newOps],
@@ -74,6 +79,7 @@ export const makeQueryBuilder = <TResult, TTableDef extends TableDefBase>(
74
79
  case 'SelectQuery':
75
80
  case 'UpdateQuery':
76
81
  case 'DeleteQuery': {
82
+ // oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- query builder return type depends on AST state; consumer type safety enforced by api.ts
77
83
  return makeQueryBuilder(tableDef, {
78
84
  ...ast,
79
85
  where: [...ast.where, { col, op, value }],
@@ -91,6 +97,7 @@ export const makeQueryBuilder = <TResult, TTableDef extends TableDefBase>(
91
97
  if (arguments.length === 0 || arguments.length > 2) return invalidQueryBuilder()
92
98
 
93
99
  if (arguments.length === 1) {
100
+ // oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- arguments-based overload dispatch requires manual narrowing
94
101
  const params = arguments[0] as QueryBuilder.OrderByParams<TTableDef>
95
102
  return makeQueryBuilder(tableDef, {
96
103
  ...ast,
@@ -98,8 +105,10 @@ export const makeQueryBuilder = <TResult, TTableDef extends TableDefBase>(
98
105
  })
99
106
  }
100
107
 
108
+ // oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- arguments-based overload dispatch requires manual narrowing
101
109
  const [col, direction] = arguments as any as [keyof TTableDef['sqliteDef']['columns'] & string, 'asc' | 'desc']
102
110
 
111
+ // oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- query builder return type depends on AST state; consumer type safety enforced by api.ts
103
112
  return makeQueryBuilder(tableDef, {
104
113
  ...ast,
105
114
  orderBy: [...ast.orderBy, { col, direction }],
@@ -116,7 +125,7 @@ export const makeQueryBuilder = <TResult, TTableDef extends TableDefBase>(
116
125
  return makeQueryBuilder(tableDef, { ...ast, offset: Option.some(offset) })
117
126
  },
118
127
  count: () => {
119
- if (isRowQuery(ast) || ast._tag === 'InsertQuery' || ast._tag === 'UpdateQuery' || ast._tag === 'DeleteQuery')
128
+ if (isRowQuery(ast) === true || ast._tag === 'InsertQuery' || ast._tag === 'UpdateQuery' || ast._tag === 'DeleteQuery')
120
129
  return invalidQueryBuilder()
121
130
 
122
131
  return makeQueryBuilder(tableDef, {
@@ -171,6 +180,7 @@ export const makeQueryBuilder = <TResult, TTableDef extends TableDefBase>(
171
180
  insert: (values) => {
172
181
  const filteredValues = Object.fromEntries(Object.entries(values).filter(([, value]) => value !== undefined))
173
182
 
183
+ // oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- query builder return type depends on AST state; consumer type safety enforced by api.ts
174
184
  return makeQueryBuilder(tableDef, {
175
185
  _tag: 'InsertQuery',
176
186
  tableDef,
@@ -185,7 +195,7 @@ export const makeQueryBuilder = <TResult, TTableDef extends TableDefBase>(
185
195
  action: 'ignore' | 'replace' | 'update',
186
196
  updateValues?: Record<string, unknown>,
187
197
  ) => {
188
- const targets = Array.isArray(targetOrTargets) ? targetOrTargets : [targetOrTargets]
198
+ const targets = Array.isArray(targetOrTargets) === true ? targetOrTargets : [targetOrTargets]
189
199
 
190
200
  assertInsertQueryBuilderAst(ast)
191
201
 
@@ -199,6 +209,7 @@ export const makeQueryBuilder = <TResult, TTableDef extends TableDefBase>(
199
209
  Match.exhaustive,
200
210
  )
201
211
 
212
+ // oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- query builder return type depends on AST state; consumer type safety enforced by api.ts
202
213
  return makeQueryBuilder(tableDef, {
203
214
  ...ast,
204
215
  onConflict,
@@ -208,6 +219,7 @@ export const makeQueryBuilder = <TResult, TTableDef extends TableDefBase>(
208
219
  returning: (...columns) => {
209
220
  assertWriteQueryBuilderAst(ast)
210
221
 
222
+ // oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- query builder return type depends on AST state; consumer type safety enforced by api.ts
211
223
  return makeQueryBuilder(tableDef, {
212
224
  ...ast,
213
225
  returning: columns,
@@ -221,6 +233,7 @@ export const makeQueryBuilder = <TResult, TTableDef extends TableDefBase>(
221
233
  // Preserve where clauses if coming from a SelectQuery
222
234
  const whereClause = ast._tag === 'SelectQuery' ? ast.where : []
223
235
 
236
+ // oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- query builder return type depends on AST state; consumer type safety enforced by api.ts
224
237
  return makeQueryBuilder(tableDef, {
225
238
  _tag: 'UpdateQuery',
226
239
  tableDef,
@@ -235,6 +248,7 @@ export const makeQueryBuilder = <TResult, TTableDef extends TableDefBase>(
235
248
  // Preserve where clauses if coming from a SelectQuery
236
249
  const whereClause = ast._tag === 'SelectQuery' ? ast.where : []
237
250
 
251
+ // oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- query builder return type depends on AST state; consumer type safety enforced by api.ts
238
252
  return makeQueryBuilder(tableDef, {
239
253
  _tag: 'DeleteQuery',
240
254
  tableDef,
@@ -248,6 +262,7 @@ export const makeQueryBuilder = <TResult, TTableDef extends TableDefBase>(
248
262
  return {
249
263
  [QueryBuilderTypeId]: QueryBuilderTypeId,
250
264
  [QueryBuilderAstSymbol]: ast,
265
+ // oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- phantom type field for generic inference only
251
266
  ResultType: 'only-for-type-inference' as TResult,
252
267
  asSql: () => astToSql(ast),
253
268
  toString: () => {
@@ -277,19 +292,19 @@ const emptyAst = (tableDef: TableDefBase): QueryBuilderAst.SelectQuery => ({
277
292
 
278
293
  // Helper functions
279
294
 
280
- function assertSelectQueryBuilderAst(ast: QueryBuilderAst): asserts ast is QueryBuilderAst.SelectQuery {
295
+ const assertSelectQueryBuilderAst: (ast: QueryBuilderAst) => asserts ast is QueryBuilderAst.SelectQuery = (ast) => {
281
296
  if (ast._tag !== 'SelectQuery') {
282
297
  return shouldNeverHappen(`Expected SelectQuery but got ${ast._tag}`)
283
298
  }
284
299
  }
285
300
 
286
- function assertInsertQueryBuilderAst(ast: QueryBuilderAst): asserts ast is QueryBuilderAst.InsertQuery {
301
+ const assertInsertQueryBuilderAst: (ast: QueryBuilderAst) => asserts ast is QueryBuilderAst.InsertQuery = (ast) => {
287
302
  if (ast._tag !== 'InsertQuery') {
288
303
  return shouldNeverHappen(`Expected InsertQuery but got ${ast._tag}`)
289
304
  }
290
305
  }
291
306
 
292
- function assertWriteQueryBuilderAst(ast: QueryBuilderAst): asserts ast is QueryBuilderAst.WriteQuery {
307
+ const assertWriteQueryBuilderAst: (ast: QueryBuilderAst) => asserts ast is QueryBuilderAst.WriteQuery = (ast) => {
293
308
  if (ast._tag !== 'InsertQuery' && ast._tag !== 'UpdateQuery' && ast._tag !== 'DeleteQuery') {
294
309
  return shouldNeverHappen(`Expected WriteQuery but got ${ast._tag}`)
295
310
  }
@@ -298,7 +313,7 @@ function assertWriteQueryBuilderAst(ast: QueryBuilderAst): asserts ast is QueryB
298
313
  const isRowQuery = (ast: QueryBuilderAst): ast is QueryBuilderAst.RowQuery => ast._tag === 'RowQuery'
299
314
 
300
315
  export const invalidQueryBuilder = (msg?: string) => {
301
- return shouldNeverHappen(`Invalid query builder${msg ? `: ${msg}` : ''}`)
316
+ return shouldNeverHappen(`Invalid query builder${msg !== undefined ? `: ${msg}` : ''}`)
302
317
  }
303
318
 
304
319
  export const getResultSchema = (qb: QueryBuilder<any, any, any>): Schema.Schema<any> => {
@@ -328,7 +343,7 @@ export const getResultSchema = (qb: QueryBuilder<any, any, any>): Schema.Schema<
328
343
  case 'UpdateQuery':
329
344
  case 'DeleteQuery': {
330
345
  // For write operations with RETURNING clause, we need to return the appropriate schema
331
- if (queryAst.returning && queryAst.returning.length > 0) {
346
+ if (queryAst.returning !== undefined && queryAst.returning.length > 0) {
332
347
  // Create a schema for the returned columns
333
348
  return queryAst.tableDef.rowSchema.pipe(Schema.pick(...queryAst.returning), Schema.Array)
334
349
  }
@@ -344,8 +359,7 @@ export const getResultSchema = (qb: QueryBuilder<any, any, any>): Schema.Schema<
344
359
  Schema.headOrElse(),
345
360
  )
346
361
  }
347
- default: {
348
- casesHandled(queryAst)
349
- }
362
+ default:
363
+ return casesHandled(queryAst)
350
364
  }
351
365
  }
@@ -13,7 +13,7 @@ export const getDefaultValuesEncoded = <TTableDef extends TableDefBase>(
13
13
  ReadonlyRecord.filter((col, key) => {
14
14
  if (fallbackValues?.[key] !== undefined) return true
15
15
  if (key === 'id') return false
16
- return col!.default._tag === 'None' || SqliteDsl.isSqlDefaultValue(col!.default.value) === false
16
+ return col!.default._tag === 'None' || !SqliteDsl.isSqlDefaultValue(col!.default.value)
17
17
  }),
18
18
  ReadonlyRecord.map((column, columnName) => {
19
19
  if (fallbackValues?.[columnName] !== undefined) return fallbackValues[columnName]
@@ -39,7 +39,7 @@ export const getDefaultValuesDecoded = <TTableDef extends TableDefBase>(
39
39
  ReadonlyRecord.filter((col, key) => {
40
40
  if (fallbackValues?.[key] !== undefined) return true
41
41
  if (key === 'id') return false
42
- return col!.default._tag === 'None' || SqliteDsl.isSqlDefaultValue(col!.default.value) === false
42
+ return col!.default._tag === 'None' || !SqliteDsl.isSqlDefaultValue(col!.default.value)
43
43
  }),
44
44
  ReadonlyRecord.map((column, columnName) => {
45
45
  if (fallbackValues?.[columnName] !== undefined) return fallbackValues[columnName]