@livestore/common 0.4.0-dev.18 → 0.4.0-dev.19

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 (286) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/ClientSessionLeaderThreadProxy.d.ts +10 -10
  3. package/dist/ClientSessionLeaderThreadProxy.d.ts.map +1 -1
  4. package/dist/adapter-types.d.ts +5 -5
  5. package/dist/adapter-types.d.ts.map +1 -1
  6. package/dist/devtools/devtools-messages-client-session.d.ts +28 -23
  7. package/dist/devtools/devtools-messages-client-session.d.ts.map +1 -1
  8. package/dist/devtools/devtools-messages-client-session.js +2 -2
  9. package/dist/devtools/devtools-messages-client-session.js.map +1 -1
  10. package/dist/devtools/devtools-messages-common.d.ts +6 -6
  11. package/dist/devtools/devtools-messages-leader.d.ts +33 -28
  12. package/dist/devtools/devtools-messages-leader.d.ts.map +1 -1
  13. package/dist/devtools/devtools-messages-leader.js +8 -8
  14. package/dist/devtools/devtools-messages-leader.js.map +1 -1
  15. package/dist/errors.d.ts +6 -6
  16. package/dist/errors.d.ts.map +1 -1
  17. package/dist/errors.js +7 -7
  18. package/dist/errors.js.map +1 -1
  19. package/dist/leader-thread/LeaderSyncProcessor.d.ts +2 -2
  20. package/dist/leader-thread/LeaderSyncProcessor.d.ts.map +1 -1
  21. package/dist/leader-thread/LeaderSyncProcessor.js +28 -28
  22. package/dist/leader-thread/LeaderSyncProcessor.js.map +1 -1
  23. package/dist/leader-thread/eventlog.d.ts +13 -13
  24. package/dist/leader-thread/eventlog.d.ts.map +1 -1
  25. package/dist/leader-thread/eventlog.js +12 -11
  26. package/dist/leader-thread/eventlog.js.map +1 -1
  27. package/dist/leader-thread/leader-worker-devtools.d.ts +2 -2
  28. package/dist/leader-thread/leader-worker-devtools.d.ts.map +1 -1
  29. package/dist/leader-thread/leader-worker-devtools.js +3 -3
  30. package/dist/leader-thread/leader-worker-devtools.js.map +1 -1
  31. package/dist/leader-thread/make-leader-thread-layer.d.ts +2 -2
  32. package/dist/leader-thread/make-leader-thread-layer.d.ts.map +1 -1
  33. package/dist/leader-thread/make-leader-thread-layer.js +10 -8
  34. package/dist/leader-thread/make-leader-thread-layer.js.map +1 -1
  35. package/dist/leader-thread/materialize-event.d.ts +1 -1
  36. package/dist/leader-thread/materialize-event.d.ts.map +1 -1
  37. package/dist/leader-thread/materialize-event.js +2 -2
  38. package/dist/leader-thread/materialize-event.js.map +1 -1
  39. package/dist/leader-thread/recreate-db.d.ts +2 -2
  40. package/dist/leader-thread/recreate-db.d.ts.map +1 -1
  41. package/dist/leader-thread/recreate-db.js +5 -5
  42. package/dist/leader-thread/recreate-db.js.map +1 -1
  43. package/dist/leader-thread/shutdown-channel.d.ts +2 -2
  44. package/dist/leader-thread/shutdown-channel.d.ts.map +1 -1
  45. package/dist/leader-thread/shutdown-channel.js +2 -2
  46. package/dist/leader-thread/shutdown-channel.js.map +1 -1
  47. package/dist/leader-thread/types.d.ts +15 -15
  48. package/dist/leader-thread/types.d.ts.map +1 -1
  49. package/dist/make-client-session.d.ts +2 -2
  50. package/dist/make-client-session.d.ts.map +1 -1
  51. package/dist/materializer-helper.d.ts +5 -5
  52. package/dist/materializer-helper.d.ts.map +1 -1
  53. package/dist/materializer-helper.js.map +1 -1
  54. package/dist/rematerialize-from-eventlog.d.ts +2 -2
  55. package/dist/rematerialize-from-eventlog.d.ts.map +1 -1
  56. package/dist/rematerialize-from-eventlog.js +6 -6
  57. package/dist/rematerialize-from-eventlog.js.map +1 -1
  58. package/dist/schema/EventDef/define.d.ts +147 -0
  59. package/dist/schema/EventDef/define.d.ts.map +1 -0
  60. package/dist/schema/EventDef/define.js +139 -0
  61. package/dist/schema/EventDef/define.js.map +1 -0
  62. package/dist/schema/EventDef/event-def.d.ts +106 -0
  63. package/dist/schema/EventDef/event-def.d.ts.map +1 -0
  64. package/dist/schema/EventDef/event-def.js +2 -0
  65. package/dist/schema/EventDef/event-def.js.map +1 -0
  66. package/dist/schema/EventDef/facts.d.ts +118 -0
  67. package/dist/schema/EventDef/facts.d.ts.map +1 -0
  68. package/dist/schema/EventDef/facts.js +53 -0
  69. package/dist/schema/EventDef/facts.js.map +1 -0
  70. package/dist/schema/EventDef/materializer.d.ts +155 -0
  71. package/dist/schema/EventDef/materializer.d.ts.map +1 -0
  72. package/dist/schema/EventDef/materializer.js +83 -0
  73. package/dist/schema/EventDef/materializer.js.map +1 -0
  74. package/dist/schema/EventDef/mod.d.ts +5 -0
  75. package/dist/schema/EventDef/mod.d.ts.map +1 -0
  76. package/dist/schema/EventDef/mod.js +5 -0
  77. package/dist/schema/EventDef/mod.js.map +1 -0
  78. package/dist/schema/EventSequenceNumber/client.d.ts +136 -0
  79. package/dist/schema/EventSequenceNumber/client.d.ts.map +1 -0
  80. package/dist/schema/{EventSequenceNumber.js → EventSequenceNumber/client.js} +86 -39
  81. package/dist/schema/EventSequenceNumber/client.js.map +1 -0
  82. package/dist/schema/EventSequenceNumber/global.d.ts +15 -0
  83. package/dist/schema/EventSequenceNumber/global.d.ts.map +1 -0
  84. package/dist/schema/EventSequenceNumber/global.js +14 -0
  85. package/dist/schema/EventSequenceNumber/global.js.map +1 -0
  86. package/dist/schema/EventSequenceNumber/mod.d.ts +37 -0
  87. package/dist/schema/EventSequenceNumber/mod.d.ts.map +1 -0
  88. package/dist/schema/EventSequenceNumber/mod.js +37 -0
  89. package/dist/schema/EventSequenceNumber/mod.js.map +1 -0
  90. package/dist/schema/EventSequenceNumber.test.js +41 -41
  91. package/dist/schema/EventSequenceNumber.test.js.map +1 -1
  92. package/dist/schema/{LiveStoreEvent.d.ts → LiveStoreEvent/client.d.ts} +84 -101
  93. package/dist/schema/LiveStoreEvent/client.d.ts.map +1 -0
  94. package/dist/schema/{LiveStoreEvent.js → LiveStoreEvent/client.js} +69 -52
  95. package/dist/schema/LiveStoreEvent/client.js.map +1 -0
  96. package/dist/schema/LiveStoreEvent/for-event-def.d.ts +52 -0
  97. package/dist/schema/LiveStoreEvent/for-event-def.d.ts.map +1 -0
  98. package/dist/schema/LiveStoreEvent/for-event-def.js +2 -0
  99. package/dist/schema/LiveStoreEvent/for-event-def.js.map +1 -0
  100. package/dist/schema/LiveStoreEvent/global.d.ts +36 -0
  101. package/dist/schema/LiveStoreEvent/global.d.ts.map +1 -0
  102. package/dist/schema/LiveStoreEvent/global.js +31 -0
  103. package/dist/schema/LiveStoreEvent/global.js.map +1 -0
  104. package/dist/schema/LiveStoreEvent/input.d.ts +46 -0
  105. package/dist/schema/LiveStoreEvent/input.d.ts.map +1 -0
  106. package/dist/schema/LiveStoreEvent/input.js +26 -0
  107. package/dist/schema/LiveStoreEvent/input.js.map +1 -0
  108. package/dist/schema/LiveStoreEvent/mod.d.ts +5 -0
  109. package/dist/schema/LiveStoreEvent/mod.d.ts.map +1 -0
  110. package/dist/schema/LiveStoreEvent/mod.js +5 -0
  111. package/dist/schema/LiveStoreEvent/mod.js.map +1 -0
  112. package/dist/schema/events.d.ts +1 -1
  113. package/dist/schema/events.d.ts.map +1 -1
  114. package/dist/schema/events.js +1 -1
  115. package/dist/schema/events.js.map +1 -1
  116. package/dist/schema/mod.d.ts +3 -3
  117. package/dist/schema/mod.d.ts.map +1 -1
  118. package/dist/schema/mod.js +3 -3
  119. package/dist/schema/mod.js.map +1 -1
  120. package/dist/schema/schema.d.ts +1 -1
  121. package/dist/schema/schema.d.ts.map +1 -1
  122. package/dist/schema/state/sqlite/client-document-def.d.ts +1 -1
  123. package/dist/schema/state/sqlite/client-document-def.d.ts.map +1 -1
  124. package/dist/schema/state/sqlite/client-document-def.js +2 -2
  125. package/dist/schema/state/sqlite/client-document-def.js.map +1 -1
  126. package/dist/schema/state/sqlite/client-document-def.test.js.map +1 -1
  127. package/dist/schema/state/sqlite/column-def.js +13 -0
  128. package/dist/schema/state/sqlite/column-def.js.map +1 -1
  129. package/dist/schema/state/sqlite/column-def.test.js +2 -1
  130. package/dist/schema/state/sqlite/column-def.test.js.map +1 -1
  131. package/dist/schema/state/sqlite/mod.d.ts +2 -2
  132. package/dist/schema/state/sqlite/mod.d.ts.map +1 -1
  133. package/dist/schema/state/sqlite/mod.js +1 -1
  134. package/dist/schema/state/sqlite/mod.js.map +1 -1
  135. package/dist/schema/state/sqlite/query-builder/api.d.ts +12 -8
  136. package/dist/schema/state/sqlite/query-builder/api.d.ts.map +1 -1
  137. package/dist/schema/state/sqlite/query-builder/astToSql.d.ts.map +1 -1
  138. package/dist/schema/state/sqlite/query-builder/astToSql.js +18 -11
  139. package/dist/schema/state/sqlite/query-builder/astToSql.js.map +1 -1
  140. package/dist/schema/state/sqlite/query-builder/impl.test.js +119 -90
  141. package/dist/schema/state/sqlite/query-builder/impl.test.js.map +1 -1
  142. package/dist/schema/state/sqlite/system-tables/eventlog-tables.js +5 -5
  143. package/dist/schema/state/sqlite/system-tables/eventlog-tables.js.map +1 -1
  144. package/dist/schema/state/sqlite/system-tables/state-tables.js +3 -3
  145. package/dist/schema/state/sqlite/system-tables/state-tables.js.map +1 -1
  146. package/dist/schema/unknown-events.d.ts +3 -3
  147. package/dist/schema/unknown-events.d.ts.map +1 -1
  148. package/dist/schema-management/migrations.d.ts +2 -2
  149. package/dist/schema-management/migrations.d.ts.map +1 -1
  150. package/dist/schema-management/migrations.js.map +1 -1
  151. package/dist/schema-management/validate-schema.d.ts +3 -3
  152. package/dist/schema-management/validate-schema.d.ts.map +1 -1
  153. package/dist/schema-management/validate-schema.js +2 -2
  154. package/dist/schema-management/validate-schema.js.map +1 -1
  155. package/dist/sqlite-types.d.ts +3 -3
  156. package/dist/sqlite-types.d.ts.map +1 -1
  157. package/dist/sync/ClientSessionSyncProcessor.d.ts +5 -5
  158. package/dist/sync/ClientSessionSyncProcessor.d.ts.map +1 -1
  159. package/dist/sync/ClientSessionSyncProcessor.js +12 -12
  160. package/dist/sync/ClientSessionSyncProcessor.js.map +1 -1
  161. package/dist/sync/errors.d.ts +9 -4
  162. package/dist/sync/errors.d.ts.map +1 -1
  163. package/dist/sync/errors.js +6 -6
  164. package/dist/sync/errors.js.map +1 -1
  165. package/dist/sync/mock-sync-backend.d.ts +6 -6
  166. package/dist/sync/mock-sync-backend.d.ts.map +1 -1
  167. package/dist/sync/mock-sync-backend.js +4 -4
  168. package/dist/sync/mock-sync-backend.js.map +1 -1
  169. package/dist/sync/next/compact-events.js +2 -2
  170. package/dist/sync/next/compact-events.js.map +1 -1
  171. package/dist/sync/next/facts.d.ts +5 -5
  172. package/dist/sync/next/facts.d.ts.map +1 -1
  173. package/dist/sync/next/facts.js.map +1 -1
  174. package/dist/sync/next/history-dag-common.d.ts +5 -5
  175. package/dist/sync/next/history-dag-common.d.ts.map +1 -1
  176. package/dist/sync/next/history-dag-common.js +5 -5
  177. package/dist/sync/next/history-dag-common.js.map +1 -1
  178. package/dist/sync/next/history-dag.d.ts.map +1 -1
  179. package/dist/sync/next/history-dag.js +8 -8
  180. package/dist/sync/next/history-dag.js.map +1 -1
  181. package/dist/sync/next/rebase-events.d.ts +5 -5
  182. package/dist/sync/next/rebase-events.d.ts.map +1 -1
  183. package/dist/sync/next/rebase-events.js +5 -5
  184. package/dist/sync/next/rebase-events.js.map +1 -1
  185. package/dist/sync/next/test/event-fixtures.d.ts +2 -2
  186. package/dist/sync/next/test/event-fixtures.d.ts.map +1 -1
  187. package/dist/sync/next/test/event-fixtures.js +9 -9
  188. package/dist/sync/next/test/event-fixtures.js.map +1 -1
  189. package/dist/sync/sync-backend-kv.d.ts +3 -3
  190. package/dist/sync/sync-backend-kv.d.ts.map +1 -1
  191. package/dist/sync/sync-backend-kv.js +3 -3
  192. package/dist/sync/sync-backend-kv.js.map +1 -1
  193. package/dist/sync/sync-backend.d.ts +9 -9
  194. package/dist/sync/sync-backend.d.ts.map +1 -1
  195. package/dist/sync/syncstate.d.ts +55 -42
  196. package/dist/sync/syncstate.d.ts.map +1 -1
  197. package/dist/sync/syncstate.js +42 -42
  198. package/dist/sync/syncstate.js.map +1 -1
  199. package/dist/sync/syncstate.test.js +40 -40
  200. package/dist/sync/syncstate.test.js.map +1 -1
  201. package/dist/sync/validate-push-payload.d.ts +1 -1
  202. package/dist/sync/validate-push-payload.d.ts.map +1 -1
  203. package/dist/sync/validate-push-payload.js +2 -2
  204. package/dist/sync/validate-push-payload.js.map +1 -1
  205. package/dist/testing/event-factory.d.ts +3 -3
  206. package/dist/testing/event-factory.d.ts.map +1 -1
  207. package/dist/testing/event-factory.js +5 -7
  208. package/dist/testing/event-factory.js.map +1 -1
  209. package/dist/version.d.ts +1 -1
  210. package/dist/version.js +1 -1
  211. package/package.json +4 -4
  212. package/src/ClientSessionLeaderThreadProxy.ts +10 -10
  213. package/src/adapter-types.ts +5 -5
  214. package/src/devtools/devtools-messages-client-session.ts +2 -2
  215. package/src/devtools/devtools-messages-leader.ts +8 -8
  216. package/src/errors.ts +11 -13
  217. package/src/leader-thread/LeaderSyncProcessor.ts +54 -56
  218. package/src/leader-thread/eventlog.ts +21 -26
  219. package/src/leader-thread/leader-worker-devtools.ts +3 -3
  220. package/src/leader-thread/make-leader-thread-layer.ts +12 -10
  221. package/src/leader-thread/materialize-event.ts +3 -3
  222. package/src/leader-thread/recreate-db.ts +6 -6
  223. package/src/leader-thread/shutdown-channel.ts +2 -2
  224. package/src/leader-thread/types.ts +15 -15
  225. package/src/make-client-session.ts +2 -2
  226. package/src/materializer-helper.ts +5 -5
  227. package/src/rematerialize-from-eventlog.ts +6 -6
  228. package/src/schema/EventDef/define.ts +201 -0
  229. package/src/schema/EventDef/event-def.ts +120 -0
  230. package/src/schema/EventDef/facts.ts +135 -0
  231. package/src/schema/EventDef/materializer.ts +172 -0
  232. package/src/schema/EventDef/mod.ts +4 -0
  233. package/src/schema/EventSequenceNumber/client.ts +257 -0
  234. package/src/schema/EventSequenceNumber/global.ts +19 -0
  235. package/src/schema/EventSequenceNumber/mod.ts +37 -0
  236. package/src/schema/EventSequenceNumber.test.ts +68 -50
  237. package/src/schema/LiveStoreEvent/client.ts +221 -0
  238. package/src/schema/LiveStoreEvent/for-event-def.ts +60 -0
  239. package/src/schema/LiveStoreEvent/global.ts +45 -0
  240. package/src/schema/LiveStoreEvent/input.ts +63 -0
  241. package/src/schema/LiveStoreEvent/mod.ts +4 -0
  242. package/src/schema/events.ts +1 -1
  243. package/src/schema/mod.ts +3 -3
  244. package/src/schema/schema.ts +1 -1
  245. package/src/schema/state/sqlite/client-document-def.test.ts +2 -2
  246. package/src/schema/state/sqlite/client-document-def.ts +3 -3
  247. package/src/schema/state/sqlite/column-def.test.ts +2 -1
  248. package/src/schema/state/sqlite/column-def.ts +17 -0
  249. package/src/schema/state/sqlite/mod.ts +2 -2
  250. package/src/schema/state/sqlite/query-builder/api.ts +12 -8
  251. package/src/schema/state/sqlite/query-builder/astToSql.ts +20 -11
  252. package/src/schema/state/sqlite/query-builder/impl.test.ts +122 -90
  253. package/src/schema/state/sqlite/system-tables/eventlog-tables.ts +5 -5
  254. package/src/schema/state/sqlite/system-tables/state-tables.ts +3 -3
  255. package/src/schema/unknown-events.ts +3 -3
  256. package/src/schema-management/migrations.ts +2 -2
  257. package/src/schema-management/validate-schema.ts +3 -3
  258. package/src/sqlite-types.ts +3 -3
  259. package/src/sync/ClientSessionSyncProcessor.ts +17 -17
  260. package/src/sync/errors.ts +6 -6
  261. package/src/sync/mock-sync-backend.ts +16 -16
  262. package/src/sync/next/compact-events.ts +2 -2
  263. package/src/sync/next/facts.ts +6 -6
  264. package/src/sync/next/history-dag-common.ts +8 -8
  265. package/src/sync/next/history-dag.ts +14 -10
  266. package/src/sync/next/rebase-events.ts +11 -11
  267. package/src/sync/next/test/event-fixtures.ts +11 -11
  268. package/src/sync/sync-backend-kv.ts +3 -3
  269. package/src/sync/sync-backend.ts +9 -9
  270. package/src/sync/syncstate.test.ts +46 -46
  271. package/src/sync/syncstate.ts +59 -55
  272. package/src/sync/validate-push-payload.ts +4 -4
  273. package/src/testing/event-factory.ts +10 -12
  274. package/src/version.ts +1 -1
  275. package/dist/schema/EventDef.d.ts +0 -126
  276. package/dist/schema/EventDef.d.ts.map +0 -1
  277. package/dist/schema/EventDef.js +0 -46
  278. package/dist/schema/EventDef.js.map +0 -1
  279. package/dist/schema/EventSequenceNumber.d.ts +0 -89
  280. package/dist/schema/EventSequenceNumber.d.ts.map +0 -1
  281. package/dist/schema/EventSequenceNumber.js.map +0 -1
  282. package/dist/schema/LiveStoreEvent.d.ts.map +0 -1
  283. package/dist/schema/LiveStoreEvent.js.map +0 -1
  284. package/src/schema/EventDef.ts +0 -222
  285. package/src/schema/EventSequenceNumber.ts +0 -208
  286. package/src/schema/LiveStoreEvent.ts +0 -286
@@ -18,7 +18,7 @@ import {
18
18
  type MaterializerHashMismatchError,
19
19
  type SqliteDb,
20
20
  type SqliteError,
21
- UnexpectedError,
21
+ UnknownError,
22
22
  } from '../adapter-types.ts'
23
23
  import type { MigrationsReport } from '../defs.ts'
24
24
  import type * as Devtools from '../devtools/mod.ts'
@@ -82,7 +82,7 @@ export const makeLeaderThreadLayer = ({
82
82
  shutdownChannel,
83
83
  params,
84
84
  testing,
85
- }: MakeLeaderThreadLayerParams): Layer.Layer<LeaderThreadCtx, UnexpectedError, Scope.Scope | HttpClient.HttpClient> =>
85
+ }: MakeLeaderThreadLayerParams): Layer.Layer<LeaderThreadCtx, UnknownError, Scope.Scope | HttpClient.HttpClient> =>
86
86
  Effect.gen(function* () {
87
87
  const syncPayloadDecoded =
88
88
  syncPayloadEncoded === undefined ? undefined : yield* Schema.decodeUnknown(syncPayloadSchema)(syncPayloadEncoded)
@@ -192,7 +192,7 @@ export const makeLeaderThreadLayer = ({
192
192
  dbState,
193
193
  dbEventlog,
194
194
  makeSqliteDb,
195
- eventSchema: LiveStoreEvent.makeEventDefSchema(schema),
195
+ eventSchema: LiveStoreEvent.Client.makeSchema(schema),
196
196
  shutdownStateSubRef: yield* SubscriptionRef.make<ShutdownState>('running'),
197
197
  shutdownChannel,
198
198
  syncBackend,
@@ -220,7 +220,7 @@ export const makeLeaderThreadLayer = ({
220
220
  }).pipe(
221
221
  Effect.withSpan('@livestore/common:leader-thread:boot'),
222
222
  Effect.withSpanScoped('@livestore/common:leader-thread'),
223
- UnexpectedError.mapToUnexpectedError,
223
+ UnknownError.mapToUnknownError,
224
224
  Effect.tapCauseLogPretty,
225
225
  Layer.unwrapScoped,
226
226
  )
@@ -257,10 +257,12 @@ const getInitialSyncState = ({
257
257
  dbEventlogMissing: boolean
258
258
  }) => {
259
259
  const initialBackendHead = dbEventlogMissing
260
- ? EventSequenceNumber.ROOT.global
260
+ ? EventSequenceNumber.Client.ROOT.global
261
261
  : Eventlog.getBackendHeadFromDb(dbEventlog)
262
262
 
263
- const initialLocalHead = dbEventlogMissing ? EventSequenceNumber.ROOT : Eventlog.getClientHeadFromDb(dbEventlog)
263
+ const initialLocalHead = dbEventlogMissing
264
+ ? EventSequenceNumber.Client.ROOT
265
+ : Eventlog.getClientHeadFromDb(dbEventlog)
264
266
 
265
267
  if (initialBackendHead > initialLocalHead.global) {
266
268
  return shouldNeverHappen(
@@ -272,8 +274,8 @@ const getInitialSyncState = ({
272
274
  localHead: initialLocalHead,
273
275
  upstreamHead: {
274
276
  global: initialBackendHead,
275
- client: EventSequenceNumber.clientDefault,
276
- rebaseGeneration: EventSequenceNumber.rebaseGenerationDefault,
277
+ client: EventSequenceNumber.Client.DEFAULT,
278
+ rebaseGeneration: EventSequenceNumber.Client.REBASE_GENERATION_DEFAULT,
277
279
  },
278
280
  pending: dbEventlogMissing
279
281
  ? []
@@ -282,7 +284,7 @@ const getInitialSyncState = ({
282
284
  dbState,
283
285
  since: {
284
286
  global: initialBackendHead,
285
- client: EventSequenceNumber.clientDefault,
287
+ client: EventSequenceNumber.Client.DEFAULT,
286
288
  rebaseGeneration: initialLocalHead.rebaseGeneration,
287
289
  },
288
290
  }),
@@ -350,7 +352,7 @@ const bootLeaderThread = ({
350
352
  devtoolsOptions: DevtoolsOptions
351
353
  }): Effect.Effect<
352
354
  LeaderThreadCtx['Type']['initialState'],
353
- UnexpectedError | SqliteError | IsOfflineError | InvalidPullError | MaterializerHashMismatchError,
355
+ UnknownError | SqliteError | IsOfflineError | InvalidPullError | MaterializerHashMismatchError,
354
356
  LeaderThreadCtx | Scope.Scope | HttpClient.HttpClient
355
357
  > =>
356
358
  Effect.gen(function* () {
@@ -155,7 +155,7 @@ export const makeMaterializeEvent = ({
155
155
  attributes: {
156
156
  eventName: eventEncoded.name,
157
157
  eventNum: eventEncoded.seqNum,
158
- 'span.label': `${EventSequenceNumber.toString(eventEncoded.seqNum)} ${eventEncoded.name}`,
158
+ 'span.label': `${EventSequenceNumber.Client.toString(eventEncoded.seqNum)} ${eventEncoded.name}`,
159
159
  },
160
160
  }),
161
161
  // Effect.logDuration('@livestore/common:leader-thread:materializeEvent'),
@@ -169,7 +169,7 @@ export const rollback = ({
169
169
  }: {
170
170
  dbState: SqliteDb
171
171
  dbEventlog: SqliteDb
172
- eventNumsToRollback: EventSequenceNumber.EventSequenceNumber[]
172
+ eventNumsToRollback: EventSequenceNumber.Client.Composite[]
173
173
  }) =>
174
174
  Effect.gen(function* () {
175
175
  const rollbackEvents = dbState
@@ -185,7 +185,7 @@ export const rollback = ({
185
185
  changeset: _.changeset,
186
186
  debug: _.debug,
187
187
  }))
188
- .toSorted((a, b) => EventSequenceNumber.compare(a.seqNum, b.seqNum))
188
+ .toSorted((a, b) => EventSequenceNumber.Client.compare(a.seqNum, b.seqNum))
189
189
 
190
190
  // Apply changesets in reverse order
191
191
  for (let i = rollbackEvents.length - 1; i >= 0; i--) {
@@ -10,7 +10,7 @@ import {
10
10
  rematerializeFromEventlog,
11
11
  type SqliteDb,
12
12
  type SqliteError,
13
- UnexpectedError,
13
+ UnknownError,
14
14
  } from '../index.ts'
15
15
  import type { LiveStoreSchema } from '../schema/mod.ts'
16
16
  import { configureConnection } from './connection.ts'
@@ -28,7 +28,7 @@ export const recreateDb = ({
28
28
  schema: LiveStoreSchema
29
29
  bootStatusQueue: Queue.Queue<BootStatus>
30
30
  materializeEvent: MaterializeEvent
31
- }): Effect.Effect<{ migrationsReport: MigrationsReport }, UnexpectedError | MaterializeError | SqliteError> =>
31
+ }): Effect.Effect<{ migrationsReport: MigrationsReport }, UnknownError | MaterializeError | SqliteError> =>
32
32
  Effect.gen(function* () {
33
33
  const migrationOptions = schema.state.sqlite.migrations
34
34
  let migrationsReport: MigrationsReport
@@ -48,7 +48,7 @@ export const recreateDb = ({
48
48
 
49
49
  const initDb = (hooks: Partial<MigrationHooks> | undefined) =>
50
50
  Effect.gen(function* () {
51
- yield* Effect.tryAll(() => hooks?.init?.(tmpDb)).pipe(UnexpectedError.mapToUnexpectedError)
51
+ yield* Effect.tryAll(() => hooks?.init?.(tmpDb)).pipe(UnknownError.mapToUnknownError)
52
52
 
53
53
  const migrationsReport = yield* migrateDb({
54
54
  db: tmpDb,
@@ -57,7 +57,7 @@ export const recreateDb = ({
57
57
  Queue.offer(bootStatusQueue, { stage: 'migrating', progress: { done, total } }),
58
58
  })
59
59
 
60
- yield* Effect.tryAll(() => hooks?.pre?.(tmpDb)).pipe(UnexpectedError.mapToUnexpectedError)
60
+ yield* Effect.tryAll(() => hooks?.pre?.(tmpDb)).pipe(UnknownError.mapToUnknownError)
61
61
 
62
62
  return { migrationsReport, tmpDb }
63
63
  })
@@ -78,7 +78,7 @@ export const recreateDb = ({
78
78
  Queue.offer(bootStatusQueue, { stage: 'rehydrating', progress: { done, total } }),
79
79
  })
80
80
 
81
- yield* Effect.tryAll(() => hooks?.post?.(initResult.tmpDb)).pipe(UnexpectedError.mapToUnexpectedError)
81
+ yield* Effect.tryAll(() => hooks?.post?.(initResult.tmpDb)).pipe(UnknownError.mapToUnknownError)
82
82
 
83
83
  break
84
84
  }
@@ -88,7 +88,7 @@ export const recreateDb = ({
88
88
  migrationsReport = { migrations: [] }
89
89
 
90
90
  const newDbData = yield* Effect.tryAll(() => migrationOptions.migrate(oldDbData)).pipe(
91
- UnexpectedError.mapToUnexpectedError,
91
+ UnknownError.mapToUnknownError,
92
92
  )
93
93
 
94
94
  tmpDb.import(newDbData)
@@ -7,12 +7,12 @@ import {
7
7
  InvalidPushError,
8
8
  IsOfflineError,
9
9
  MaterializeError,
10
- UnexpectedError,
10
+ UnknownError,
11
11
  } from '../index.ts'
12
12
 
13
13
  export class All extends Schema.Union(
14
14
  IntentionalShutdownCause,
15
- UnexpectedError,
15
+ UnknownError,
16
16
  IsOfflineError,
17
17
  InvalidPushError,
18
18
  InvalidPullError,
@@ -22,7 +22,7 @@ import type {
22
22
  PersistenceInfo,
23
23
  SqliteDb,
24
24
  SyncBackend,
25
- UnexpectedError,
25
+ UnknownError,
26
26
  } from '../index.ts'
27
27
  import type { EventSequenceNumber, LiveStoreEvent, LiveStoreSchema } from '../schema/mod.ts'
28
28
  import type * as SyncState from '../sync/syncstate.ts'
@@ -43,7 +43,7 @@ export const InitialSyncOptions = Schema.Union(InitialSyncOptionsSkip, InitialSy
43
43
  export type InitialSyncOptions = typeof InitialSyncOptions.Type
44
44
 
45
45
  export type InitialSyncInfo = Option.Option<{
46
- eventSequenceNumber: EventSequenceNumber.GlobalEventSequenceNumber
46
+ eventSequenceNumber: EventSequenceNumber.Global.Type
47
47
  metadata: Option.Option<Schema.JsonValue>
48
48
  }>
49
49
 
@@ -66,7 +66,7 @@ export type DevtoolsOptions =
66
66
  persistenceInfo: PersistenceInfoPair
67
67
  mode: 'proxy' | 'direct'
68
68
  },
69
- UnexpectedError,
69
+ UnknownError,
70
70
  Scope.Scope | HttpClient.HttpClient | LeaderThreadCtx
71
71
  >
72
72
  }
@@ -96,13 +96,13 @@ export class LeaderThreadCtx extends Context.Tag('LeaderThreadCtx')<
96
96
  // TODO we should find a more elegant way to handle cases which need this ref for their implementation
97
97
  shutdownStateSubRef: SubscriptionRef.SubscriptionRef<ShutdownState>
98
98
  shutdownChannel: ShutdownChannel
99
- eventSchema: LiveStoreEvent.ForEventDefRecord<any>
99
+ eventSchema: LiveStoreEvent.ForEventDef.ForRecord<any>
100
100
  devtools: DevtoolsContext
101
101
  syncBackend: SyncBackend.SyncBackend | undefined
102
102
  syncProcessor: LeaderSyncProcessor
103
103
  materializeEvent: MaterializeEvent
104
104
  initialState: {
105
- leaderHead: EventSequenceNumber.EventSequenceNumber
105
+ leaderHead: EventSequenceNumber.Client.Composite
106
106
  migrationsReport: MigrationsReport
107
107
  }
108
108
  /**
@@ -116,7 +116,7 @@ export class LeaderThreadCtx extends Context.Tag('LeaderThreadCtx')<
116
116
  >() {}
117
117
 
118
118
  export type MaterializeEvent = (
119
- eventEncoded: LiveStoreEvent.EncodedWithMeta,
119
+ eventEncoded: LiveStoreEvent.Client.EncodedWithMeta,
120
120
  options?: {
121
121
  /** Needed for rematerializeFromEventlog */
122
122
  skipEventlog?: boolean
@@ -137,17 +137,17 @@ export type InitialBlockingSyncContext = {
137
137
  export interface LeaderSyncProcessor {
138
138
  /** Used by client sessions to subscribe to upstream sync state changes */
139
139
  pull: (args: {
140
- cursor: EventSequenceNumber.EventSequenceNumber
141
- }) => Stream.Stream<{ payload: typeof SyncState.PayloadUpstream.Type }, UnexpectedError>
140
+ cursor: EventSequenceNumber.Client.Composite
141
+ }) => Stream.Stream<{ payload: typeof SyncState.PayloadUpstream.Type }, UnknownError>
142
142
  /** The `pullQueue` API can be used instead of `pull` when more convenient */
143
143
  pullQueue: (args: {
144
- cursor: EventSequenceNumber.EventSequenceNumber
145
- }) => Effect.Effect<Queue.Queue<{ payload: typeof SyncState.PayloadUpstream.Type }>, UnexpectedError, Scope.Scope>
144
+ cursor: EventSequenceNumber.Client.Composite
145
+ }) => Effect.Effect<Queue.Queue<{ payload: typeof SyncState.PayloadUpstream.Type }>, UnknownError, Scope.Scope>
146
146
 
147
147
  /** Used by client sessions to push events to the leader thread */
148
148
  push: (
149
149
  /** `batch` needs to follow the same rules as `batch` in `SyncBackend.push` */
150
- batch: ReadonlyArray<LiveStoreEvent.EncodedWithMeta>,
150
+ batch: ReadonlyArray<LiveStoreEvent.Client.EncodedWithMeta>,
151
151
  options?: {
152
152
  /**
153
153
  * If true, the effect will only finish when the local push has been processed (i.e. succeeded or was rejected).
@@ -160,14 +160,14 @@ export interface LeaderSyncProcessor {
160
160
 
161
161
  /** Currently only used by devtools which don't provide their own event numbers */
162
162
  pushPartial: (args: {
163
- event: LiveStoreEvent.PartialAnyEncoded
163
+ event: LiveStoreEvent.Input.Encoded
164
164
  clientId: string
165
165
  sessionId: string
166
- }) => Effect.Effect<void, UnexpectedError>
166
+ }) => Effect.Effect<void, UnknownError>
167
167
 
168
168
  boot: Effect.Effect<
169
- { initialLeaderHead: EventSequenceNumber.EventSequenceNumber },
170
- UnexpectedError,
169
+ { initialLeaderHead: EventSequenceNumber.Client.Composite },
170
+ UnknownError,
171
171
  LeaderThreadCtx | Scope.Scope | HttpClient.HttpClient
172
172
  >
173
173
  syncState: Subscribable.Subscribable<SyncState.SyncState>
@@ -8,7 +8,7 @@ import type {
8
8
  ClientSessionLeaderThreadProxy,
9
9
  LockStatus,
10
10
  SqliteDb,
11
- UnexpectedError,
11
+ UnknownError,
12
12
  } from './adapter-types.ts'
13
13
  import * as Devtools from './devtools/mod.ts'
14
14
  import { liveStoreVersion } from './version.ts'
@@ -44,7 +44,7 @@ export const makeClientSession = <R>({
44
44
  connectWebmeshNode: (args: {
45
45
  webmeshNode: Webmesh.MeshNode
46
46
  sessionInfo: Devtools.SessionInfo.SessionInfo
47
- }) => Effect.Effect<void, UnexpectedError, Scope.Scope | R>
47
+ }) => Effect.Effect<void, UnknownError, Scope.Scope | R>
48
48
  webmeshMode: 'direct' | 'proxy'
49
49
  registerBeforeUnload: (onBeforeUnload: () => void) => () => void
50
50
  /** Browser origin of the client session; used for origin-scoped DevTools mesh channels */
@@ -3,8 +3,8 @@ import { Hash, Option, Schema } from '@livestore/utils/effect'
3
3
 
4
4
  import type { SqliteDb } from './adapter-types.ts'
5
5
  import { SessionIdSymbol } from './adapter-types.ts'
6
- import type { EventDef, Materializer, MaterializerContextQuery, MaterializerResult } from './schema/EventDef.ts'
7
- import type * as LiveStoreEvent from './schema/LiveStoreEvent.ts'
6
+ import type { EventDef, Materializer, MaterializerContextQuery, MaterializerResult } from './schema/EventDef/mod.ts'
7
+ import type * as LiveStoreEvent from './schema/LiveStoreEvent/mod.ts'
8
8
  import type { LiveStoreSchema } from './schema/schema.ts'
9
9
  import type { QueryBuilder } from './schema/state/sqlite/query-builder/api.ts'
10
10
  import { isQueryBuilder } from './schema/state/sqlite/query-builder/api.ts'
@@ -24,8 +24,8 @@ export const getExecStatementsFromMaterializer = ({
24
24
  dbState: SqliteDb
25
25
  /** Both encoded and decoded events are supported to reduce the number of times we need to decode/encode */
26
26
  event:
27
- | { decoded: LiveStoreEvent.AnyDecoded; encoded: undefined }
28
- | { decoded: undefined; encoded: LiveStoreEvent.AnyEncoded }
27
+ | { decoded: LiveStoreEvent.Client.Decoded; encoded: undefined }
28
+ | { decoded: undefined; encoded: LiveStoreEvent.Client.Encoded }
29
29
  }): ReadonlyArray<{
30
30
  statementSql: string
31
31
  bindValues: PreparedBindValues
@@ -85,7 +85,7 @@ export const getExecStatementsFromMaterializer = ({
85
85
 
86
86
  export const makeMaterializerHash =
87
87
  ({ schema, dbState }: { schema: LiveStoreSchema; dbState: SqliteDb }) =>
88
- (event: LiveStoreEvent.AnyEncoded): Option.Option<number> => {
88
+ (event: LiveStoreEvent.Client.Encoded): Option.Option<number> => {
89
89
  if (isDevEnv()) {
90
90
  // Hashing is only needed during dev-mode diagnostics. Skip work entirely for
91
91
  // unknown events (no definition/materializer) so we do not introduce noisy
@@ -1,7 +1,7 @@
1
1
  import { memoizeByRef } from '@livestore/utils'
2
2
  import { Chunk, Effect, Option, Schema, Stream } from '@livestore/utils/effect'
3
3
 
4
- import { type SqliteDb, UnexpectedError } from './adapter-types.ts'
4
+ import { type SqliteDb, UnknownError } from './adapter-types.ts'
5
5
  import type { MaterializeEvent } from './leader-thread/mod.ts'
6
6
  import type { EventDef, LiveStoreSchema } from './schema/mod.ts'
7
7
  import { EventSequenceNumber, LiveStoreEvent, resolveEventDef, SystemTables } from './schema/mod.ts'
@@ -32,7 +32,7 @@ export const rematerializeFromEventlog = ({
32
32
  const processEvent = (row: SystemTables.EventlogMetaRow) =>
33
33
  Effect.gen(function* () {
34
34
  const args = JSON.parse(row.argsJson)
35
- const eventEncoded = LiveStoreEvent.EncodedWithMeta.make({
35
+ const eventEncoded = LiveStoreEvent.Client.EncodedWithMeta.make({
36
36
  name: row.name,
37
37
  args,
38
38
  seqNum: {
@@ -52,7 +52,7 @@ export const rematerializeFromEventlog = ({
52
52
  const resolution = yield* resolveEventDef(schema, {
53
53
  operation: '@livestore/common:rematerializeFromEventlog:processEvent',
54
54
  event: eventEncoded,
55
- }).pipe(UnexpectedError.mapToUnexpectedError)
55
+ }).pipe(UnknownError.mapToUnknownError)
56
56
 
57
57
  if (resolution._tag === 'unknown') {
58
58
  // Old snapshots can contain newer events. Skip until the runtime has
@@ -71,7 +71,7 @@ export const rematerializeFromEventlog = ({
71
71
  // Checking whether the schema has changed in an incompatible way
72
72
  yield* Schema.decodeUnknown(eventDef.schema)(args).pipe(
73
73
  Effect.mapError((cause) =>
74
- UnexpectedError.make({
74
+ UnknownError.make({
75
75
  cause,
76
76
  note: `\
77
77
  There was an error during rematerializing from the eventlog while decoding
@@ -106,9 +106,9 @@ LIMIT ${CHUNK_SIZE}
106
106
  const lastId = Chunk.isChunk(item)
107
107
  ? Chunk.last(item).pipe(
108
108
  Option.map((_) => ({ global: _.seqNumGlobal, client: _.seqNumClient })),
109
- Option.getOrElse(() => EventSequenceNumber.ROOT),
109
+ Option.getOrElse(() => EventSequenceNumber.Client.ROOT),
110
110
  )
111
- : EventSequenceNumber.ROOT
111
+ : EventSequenceNumber.Client.ROOT
112
112
  const nextItem = Chunk.fromIterable(
113
113
  stmt.select<SystemTables.EventlogMetaRow>({
114
114
  $seqNumGlobal: lastId?.global,
@@ -0,0 +1,201 @@
1
+ /**
2
+ * Event Definition Functions
3
+ *
4
+ * This module provides functions for creating event definitions in LiveStore.
5
+ * Events are the core unit of state change - all mutations to the database
6
+ * happen through events that are committed to the eventlog.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * import { Events } from '@livestore/livestore'
11
+ * import { Schema } from 'effect'
12
+ *
13
+ * // Define events for your application
14
+ * export const events = {
15
+ * // Synced events are sent to the sync backend
16
+ * todoCreated: Events.synced({
17
+ * name: 'v1.TodoCreated',
18
+ * schema: Schema.Struct({ id: Schema.String, text: Schema.String }),
19
+ * }),
20
+ *
21
+ * // Client-only events stay local (useful for UI state)
22
+ * uiStateSet: Events.clientOnly({
23
+ * name: 'UiStateSet',
24
+ * schema: Schema.Struct({ selectedId: Schema.NullOr(Schema.String) }),
25
+ * }),
26
+ * }
27
+ * ```
28
+ * @module
29
+ */
30
+
31
+ import { shouldNeverHappen } from '@livestore/utils'
32
+ import { Schema } from '@livestore/utils/effect'
33
+
34
+ import type { EventDef } from './event-def.ts'
35
+ import type { EventDefFactInput, EventDefFacts } from './facts.ts'
36
+
37
+ /** Options for defining an event. */
38
+ export type DefineEventOptions<TTo, TDerived extends boolean = false> = {
39
+ /**
40
+ * Callback defining fact constraints for this event.
41
+ * @experimental This feature is not fully implemented yet.
42
+ */
43
+ facts?: (
44
+ args: TTo,
45
+ currentFacts: EventDefFacts,
46
+ ) => {
47
+ modify?: {
48
+ /** Facts to set (create or update). */
49
+ set?: Iterable<EventDefFactInput>
50
+ /** Facts to unset (remove). */
51
+ unset?: Iterable<EventDefFactInput>
52
+ }
53
+ /**
54
+ * Facts that must exist for this event to be valid.
55
+ * Used for history constraints and compaction rules.
56
+ */
57
+ require?: Iterable<EventDefFactInput>
58
+ }
59
+
60
+ /**
61
+ * When true, the event is only synced within the same client's sessions
62
+ * but never sent to the sync backend. Useful for UI state.
63
+ * @default false
64
+ */
65
+ clientOnly?: boolean
66
+
67
+ /**
68
+ * When true, marks this as a derived event that cannot have materializers.
69
+ * @default false
70
+ */
71
+ derived?: TDerived
72
+ }
73
+
74
+ /**
75
+ * Creates an event definition with full control over all options.
76
+ *
77
+ * This is the low-level function for creating events. For most cases,
78
+ * prefer using `synced()` or `clientOnly()` which provide simpler APIs.
79
+ *
80
+ * @example
81
+ * ```ts
82
+ * const customEvent = defineEvent({
83
+ * name: 'v1.CustomEvent',
84
+ * schema: Schema.Struct({ data: Schema.String }),
85
+ * clientOnly: false,
86
+ * derived: false,
87
+ * })
88
+ * ```
89
+ */
90
+ export const defineEvent = <TName extends string, TType, TEncoded = TType, TDerived extends boolean = false>(
91
+ args: {
92
+ name: TName
93
+ schema: Schema.Schema<TType, TEncoded>
94
+ } & DefineEventOptions<TType, TDerived>,
95
+ ): EventDef<TName, TType, TEncoded, TDerived> => {
96
+ const { name, schema, ...options } = args
97
+
98
+ const makePartialEvent = (args: TType) => {
99
+ const res = Schema.validateEither(schema)(args)
100
+ if (res._tag === 'Left') {
101
+ shouldNeverHappen(`Invalid event args for event '${name}':`, res.left.message, '\n')
102
+ }
103
+ return { name: name, args }
104
+ }
105
+
106
+ Object.defineProperty(makePartialEvent, 'name', { value: name })
107
+ Object.defineProperty(makePartialEvent, 'schema', { value: schema })
108
+ Object.defineProperty(makePartialEvent, 'encoded', {
109
+ value: (args: TEncoded) => ({ name: name, args }),
110
+ })
111
+
112
+ Object.defineProperty(makePartialEvent, 'options', {
113
+ value: {
114
+ clientOnly: options?.clientOnly ?? false,
115
+ facts: options?.facts
116
+ ? (args, currentFacts) => {
117
+ const res = options.facts!(args, currentFacts)
118
+ return {
119
+ modify: {
120
+ set: res.modify?.set ? new Set(res.modify.set) : new Set(),
121
+ unset: res.modify?.unset ? new Set(res.modify.unset) : new Set(),
122
+ },
123
+ require: res.require ? new Set(res.require) : new Set(),
124
+ }
125
+ }
126
+ : undefined,
127
+ derived: options?.derived ?? false,
128
+ } satisfies EventDef.Any['options'],
129
+ })
130
+
131
+ return makePartialEvent as EventDef<TName, TType, TEncoded, TDerived>
132
+ }
133
+
134
+ /**
135
+ * Creates a synced event definition.
136
+ *
137
+ * Synced events are sent to the sync backend and distributed to all connected
138
+ * clients. Use this for collaborative data that should be shared across users
139
+ * and devices.
140
+ *
141
+ * Event names should be versioned (e.g., `v1.TodoCreated`) to support
142
+ * schema evolution over time.
143
+ *
144
+ * @example
145
+ * ```ts
146
+ * import { Events } from '@livestore/livestore'
147
+ * import { Schema } from 'effect'
148
+ *
149
+ * const todoCreated = Events.synced({
150
+ * name: 'v1.TodoCreated',
151
+ * schema: Schema.Struct({
152
+ * id: Schema.String,
153
+ * text: Schema.String,
154
+ * completed: Schema.Boolean,
155
+ * }),
156
+ * })
157
+ *
158
+ * // Commit the event
159
+ * store.commit(todoCreated({ id: 'abc', text: 'Buy milk', completed: false }))
160
+ * ```
161
+ */
162
+ export const synced = <TName extends string, TType, TEncoded = TType>(
163
+ args: {
164
+ name: TName
165
+ schema: Schema.Schema<TType, TEncoded>
166
+ } & Omit<DefineEventOptions<TType, false>, 'derived' | 'clientOnly'>,
167
+ ): EventDef<TName, TType, TEncoded> => defineEvent({ ...args, clientOnly: false })
168
+
169
+ /**
170
+ * Creates a client-only event definition.
171
+ *
172
+ * Client-only events are synced within the same client's sessions (e.g., across
173
+ * browser tabs) but are never sent to the sync backend. Use this for local UI
174
+ * state like selected items, filter settings, or draft content.
175
+ *
176
+ * Note: Client-only events still require materializers and are stored in the
177
+ * local eventlog, they just don't participate in server-side sync.
178
+ *
179
+ * @example
180
+ * ```ts
181
+ * import { Events } from '@livestore/livestore'
182
+ * import { Schema } from 'effect'
183
+ *
184
+ * const uiStateSet = Events.clientOnly({
185
+ * name: 'UiStateSet',
186
+ * schema: Schema.Struct({
187
+ * selectedTodoId: Schema.NullOr(Schema.String),
188
+ * filterMode: Schema.Literal('all', 'active', 'completed'),
189
+ * }),
190
+ * })
191
+ *
192
+ * // Update local UI state
193
+ * store.commit(uiStateSet({ selectedTodoId: 'abc', filterMode: 'active' }))
194
+ * ```
195
+ */
196
+ export const clientOnly = <TName extends string, TType, TEncoded = TType>(
197
+ args: {
198
+ name: TName
199
+ schema: Schema.Schema<TType, TEncoded>
200
+ } & Omit<DefineEventOptions<TType, false>, 'derived' | 'clientOnly'>,
201
+ ): EventDef<TName, TType, TEncoded> => defineEvent({ ...args, clientOnly: true })
@@ -0,0 +1,120 @@
1
+ import type { Schema } from '@livestore/utils/effect'
2
+
3
+ import type { FactsCallback } from './facts.ts'
4
+
5
+ /**
6
+ * Core type representing an event definition in LiveStore.
7
+ *
8
+ * An EventDef defines the structure and behavior of an event type, including:
9
+ * - A unique name identifying the event type (conventionally versioned, e.g., `v1.TodoCreated`)
10
+ * - A schema for validating and encoding/decoding event arguments
11
+ * - Options controlling sync behavior and constraints
12
+ *
13
+ * EventDefs are callable - invoking them creates a partial event object suitable for `store.commit()`.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * import { Events } from '@livestore/livestore'
18
+ * import { Schema } from 'effect'
19
+ *
20
+ * const todoCreated = Events.synced({
21
+ * name: 'v1.TodoCreated',
22
+ * schema: Schema.Struct({
23
+ * id: Schema.String,
24
+ * text: Schema.String,
25
+ * }),
26
+ * })
27
+ *
28
+ * // Use the EventDef as a constructor
29
+ * store.commit(todoCreated({ id: 'abc', text: 'Buy milk' }))
30
+ * ```
31
+ */
32
+ export type EventDef<TName extends string, TType, TEncoded = TType, TDerived extends boolean = false> = {
33
+ /** Unique identifier for this event type. Conventionally versioned (e.g., `v1.TodoCreated`). */
34
+ name: TName
35
+
36
+ /** Effect Schema used for validating and encoding/decoding event arguments. */
37
+ schema: Schema.Schema<TType, TEncoded>
38
+
39
+ options: {
40
+ /**
41
+ * When true, the event is only synced within the same client's sessions (e.g., across tabs)
42
+ * but never sent to the sync backend. Useful for UI state like selected items or filters.
43
+ */
44
+ clientOnly: boolean
45
+
46
+ /**
47
+ * Callback defining fact constraints for this event.
48
+ * @experimental This feature is not fully implemented yet.
49
+ */
50
+ facts: FactsCallback<TType> | undefined
51
+
52
+ /** Whether this is a derived event. Derived events cannot have materializers. */
53
+ derived: TDerived
54
+ }
55
+
56
+ /**
57
+ * Callable signature - creates a partial event with decoded arguments.
58
+ * The returned object can be passed directly to `store.commit()`.
59
+ */
60
+ (
61
+ args: TType,
62
+ ): {
63
+ name: TName
64
+ args: TType
65
+ }
66
+
67
+ /**
68
+ * Creates a partial event with pre-encoded arguments.
69
+ * Useful when working with already-serialized data.
70
+ */
71
+ encoded: (args: TEncoded) => {
72
+ name: TName
73
+ args: TEncoded
74
+ }
75
+
76
+ /** Type helper for accessing the event's shape with name and decoded args. */
77
+ readonly Event: {
78
+ name: TName
79
+ args: TType
80
+ }
81
+ }
82
+
83
+ export namespace EventDef {
84
+ /**
85
+ * Wildcard type matching any EventDef regardless of type parameters.
86
+ * Used as a type constraint in generic functions and collections.
87
+ */
88
+ export type Any = EventDef<string, any, any, boolean>
89
+
90
+ /**
91
+ * EventDef without the callable function signature.
92
+ * Used in contexts where only the metadata (name, schema, options) is needed,
93
+ * such as materializer definitions.
94
+ */
95
+ export type AnyWithoutFn = Pick<Any, 'name' | 'schema' | 'options'>
96
+ }
97
+
98
+ /**
99
+ * Container holding a Map of event definitions keyed by name.
100
+ * Used internally by LiveStoreSchema.
101
+ */
102
+ export type EventDefMap = {
103
+ map: Map<string, EventDef.Any>
104
+ }
105
+
106
+ /**
107
+ * Plain object record of event definitions keyed by name.
108
+ * This is the typical shape when defining events in user code.
109
+ *
110
+ * @example
111
+ * ```ts
112
+ * const events = {
113
+ * todoCreated: Events.synced({ name: 'v1.TodoCreated', schema: ... }),
114
+ * todoDeleted: Events.synced({ name: 'v1.TodoDeleted', schema: ... }),
115
+ * } satisfies EventDefRecord
116
+ * ```
117
+ */
118
+ export type EventDefRecord = {
119
+ [name: string]: EventDef.Any
120
+ }