@livestore/livestore 0.3.0-dev.28 → 0.3.0-dev.29

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 (70) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/SqliteDbWrapper.d.ts.map +1 -1
  3. package/dist/SqliteDbWrapper.js +4 -1
  4. package/dist/SqliteDbWrapper.js.map +1 -1
  5. package/dist/live-queries/base-class.d.ts +8 -12
  6. package/dist/live-queries/base-class.d.ts.map +1 -1
  7. package/dist/live-queries/base-class.js.map +1 -1
  8. package/dist/live-queries/client-document-get-query.d.ts +12 -0
  9. package/dist/live-queries/client-document-get-query.d.ts.map +1 -0
  10. package/dist/live-queries/client-document-get-query.js +18 -0
  11. package/dist/live-queries/client-document-get-query.js.map +1 -0
  12. package/dist/live-queries/computed.d.ts +4 -8
  13. package/dist/live-queries/computed.d.ts.map +1 -1
  14. package/dist/live-queries/computed.js +1 -6
  15. package/dist/live-queries/computed.js.map +1 -1
  16. package/dist/live-queries/db-query.d.ts +13 -18
  17. package/dist/live-queries/db-query.d.ts.map +1 -1
  18. package/dist/live-queries/db-query.js +34 -34
  19. package/dist/live-queries/db-query.js.map +1 -1
  20. package/dist/live-queries/db-query.test.js +32 -23
  21. package/dist/live-queries/db-query.test.js.map +1 -1
  22. package/dist/live-queries/make-ref.d.ts.map +1 -1
  23. package/dist/live-queries/make-ref.js +1 -0
  24. package/dist/live-queries/make-ref.js.map +1 -1
  25. package/dist/mod.d.ts +0 -1
  26. package/dist/mod.d.ts.map +1 -1
  27. package/dist/mod.js +0 -1
  28. package/dist/mod.js.map +1 -1
  29. package/dist/reactive.d.ts.map +1 -1
  30. package/dist/reactive.js +1 -1
  31. package/dist/reactive.js.map +1 -1
  32. package/dist/store/create-store.js +2 -2
  33. package/dist/store/create-store.js.map +1 -1
  34. package/dist/store/store-types.d.ts +5 -5
  35. package/dist/store/store-types.d.ts.map +1 -1
  36. package/dist/store/store.d.ts +27 -26
  37. package/dist/store/store.d.ts.map +1 -1
  38. package/dist/store/store.js +74 -69
  39. package/dist/store/store.js.map +1 -1
  40. package/dist/utils/stack-info.test.js +6 -6
  41. package/dist/utils/tests/fixture.d.ts +54 -207
  42. package/dist/utils/tests/fixture.d.ts.map +1 -1
  43. package/dist/utils/tests/fixture.js +20 -13
  44. package/dist/utils/tests/fixture.js.map +1 -1
  45. package/dist/utils/tests/otel.d.ts.map +1 -1
  46. package/dist/utils/tests/otel.js +8 -3
  47. package/dist/utils/tests/otel.js.map +1 -1
  48. package/package.json +7 -7
  49. package/src/SqliteDbWrapper.ts +4 -1
  50. package/src/live-queries/__snapshots__/db-query.test.ts.snap +9 -9
  51. package/src/live-queries/base-class.ts +8 -25
  52. package/src/live-queries/client-document-get-query.ts +52 -0
  53. package/src/live-queries/computed.ts +4 -18
  54. package/src/live-queries/db-query.test.ts +38 -24
  55. package/src/live-queries/db-query.ts +60 -66
  56. package/src/live-queries/make-ref.ts +2 -0
  57. package/src/mod.ts +0 -2
  58. package/src/reactive.ts +1 -1
  59. package/src/store/create-store.ts +2 -2
  60. package/src/store/store-types.ts +5 -5
  61. package/src/store/store.ts +97 -91
  62. package/src/utils/stack-info.test.ts +6 -6
  63. package/src/utils/tests/fixture.ts +21 -25
  64. package/src/utils/tests/otel.ts +10 -3
  65. package/tmp/pack.tgz +0 -0
  66. package/dist/row-query-utils.d.ts +0 -17
  67. package/dist/row-query-utils.d.ts.map +0 -1
  68. package/dist/row-query-utils.js +0 -34
  69. package/dist/row-query-utils.js.map +0 -1
  70. package/src/row-query-utils.ts +0 -76
@@ -9,7 +9,7 @@ import type {
9
9
  import {
10
10
  Devtools,
11
11
  getDurationMsFromSpan,
12
- getExecArgsFromMutation,
12
+ getExecArgsFromEvent,
13
13
  getResultSchema,
14
14
  IntentionalShutdownCause,
15
15
  isQueryBuilder,
@@ -21,16 +21,16 @@ import {
21
21
  } from '@livestore/common'
22
22
  import type { LiveStoreSchema } from '@livestore/common/schema'
23
23
  import {
24
- getMutationDef,
24
+ getEventDef,
25
25
  LEADER_MERGE_COUNTER_TABLE,
26
- MutationEvent,
26
+ LiveStoreEvent,
27
+ SCHEMA_EVENT_DEFS_META_TABLE,
27
28
  SCHEMA_META_TABLE,
28
- SCHEMA_MUTATIONS_META_TABLE,
29
29
  SESSION_CHANGESET_META_TABLE,
30
30
  } from '@livestore/common/schema'
31
31
  import { assertNever, isDevEnv } from '@livestore/utils'
32
32
  import type { Scope } from '@livestore/utils/effect'
33
- import { Cause, Effect, Inspectable, OtelTracer, Predicate, Runtime, Schema, Stream } from '@livestore/utils/effect'
33
+ import { Cause, Effect, Inspectable, OtelTracer, Runtime, Schema, Stream } from '@livestore/utils/effect'
34
34
  import { nanoid } from '@livestore/utils/nanoid'
35
35
  import * as otel from '@opentelemetry/api'
36
36
 
@@ -42,13 +42,13 @@ import type {
42
42
  ReactivityGraphContext,
43
43
  } from '../live-queries/base-class.js'
44
44
  import { makeReactivityGraph } from '../live-queries/base-class.js'
45
+ import { makeExecBeforeFirstRun } from '../live-queries/client-document-get-query.js'
45
46
  import type { Ref } from '../reactive.js'
46
- import { makeExecBeforeFirstRun } from '../row-query-utils.js'
47
47
  import { SqliteDbWrapper } from '../SqliteDbWrapper.js'
48
48
  import { ReferenceCountedSet } from '../utils/data-structures.js'
49
49
  import { downloadBlob, exposeDebugUtils } from '../utils/dev.js'
50
50
  import type { StackInfo } from '../utils/stack-info.js'
51
- import type { RefreshReason, StoreMutateOptions, StoreOptions, StoreOtel, Unsubscribe } from './store-types.js'
51
+ import type { RefreshReason, StoreCommitOptions, StoreOptions, StoreOtel, Unsubscribe } from './store-types.js'
52
52
 
53
53
  if (isDevEnv()) {
54
54
  exposeDebugUtils()
@@ -76,8 +76,8 @@ export class Store<TSchema extends LiveStoreSchema = LiveStoreSchema, TContext =
76
76
  /** RC-based set to see which queries are currently subscribed to */
77
77
  activeQueries: ReferenceCountedSet<LiveQuery<any>>
78
78
 
79
- // NOTE this is currently exposed for the Devtools databrowser to emit mutation events
80
- readonly __mutationEventSchema
79
+ // NOTE this is currently exposed for the Devtools databrowser to commit events
80
+ readonly __eventSchema
81
81
  readonly syncProcessor: ClientSessionSyncProcessor
82
82
 
83
83
  readonly boot: Effect.Effect<void, UnexpectedError, Scope.Scope>
@@ -114,12 +114,12 @@ export class Store<TSchema extends LiveStoreSchema = LiveStoreSchema, TContext =
114
114
  schema,
115
115
  clientSession,
116
116
  runtime: effectContext.runtime,
117
- applyMutation: (mutationEventDecoded, { otelContext, withChangeset }) => {
118
- const mutationDef = getMutationDef(schema, mutationEventDecoded.mutation)
117
+ applyEvent: (eventDecoded, { otelContext, withChangeset }) => {
118
+ const eventDef = getEventDef(schema, eventDecoded.name)
119
119
 
120
- const execArgsArr = getExecArgsFromMutation({
121
- mutationDef,
122
- mutationEvent: { decoded: mutationEventDecoded, encoded: undefined },
120
+ const execArgsArr = getExecArgsFromEvent({
121
+ eventDef,
122
+ event: { decoded: eventDecoded, encoded: undefined },
123
123
  })
124
124
 
125
125
  const writeTablesForEvent = new Set<string>()
@@ -168,14 +168,14 @@ export class Store<TSchema extends LiveStoreSchema = LiveStoreSchema, TContext =
168
168
  confirmUnsavedChanges,
169
169
  })
170
170
 
171
- this.__mutationEventSchema = MutationEvent.makeMutationEventSchemaMemo(schema)
171
+ this.__eventSchema = LiveStoreEvent.makeEventDefSchemaMemo(schema)
172
172
 
173
173
  // TODO generalize the `tableRefs` concept to allow finer-grained refs
174
174
  this.tableRefs = {}
175
175
  this.activeQueries = new ReferenceCountedSet()
176
176
 
177
- const mutationsSpan = otelOptions.tracer.startSpan('LiveStore:mutations', {}, otelOptions.rootSpanContext)
178
- const otelMuationsSpanContext = otel.trace.setSpan(otel.context.active(), mutationsSpan)
177
+ const commitsSpan = otelOptions.tracer.startSpan('LiveStore:commits', {}, otelOptions.rootSpanContext)
178
+ const otelMuationsSpanContext = otel.trace.setSpan(otel.context.active(), commitsSpan)
179
179
 
180
180
  const queriesSpan = otelOptions.tracer.startSpan('LiveStore:queries', {}, otelOptions.rootSpanContext)
181
181
  const otelQueriesSpanContext = otel.trace.setSpan(otel.context.active(), queriesSpan)
@@ -192,20 +192,20 @@ export class Store<TSchema extends LiveStoreSchema = LiveStoreSchema, TContext =
192
192
 
193
193
  this.otel = {
194
194
  tracer: otelOptions.tracer,
195
- mutationsSpanContext: otelMuationsSpanContext,
195
+ commitsSpanContext: otelMuationsSpanContext,
196
196
  queriesSpanContext: otelQueriesSpanContext,
197
197
  }
198
198
 
199
199
  // Need a set here since `schema.tables` might contain duplicates and some componentStateTables
200
200
  const allTableNames = new Set(
201
- // NOTE we're excluding the LiveStore schema and mutations tables as they are not user-facing
201
+ // NOTE we're excluding the LiveStore schema and events tables as they are not user-facing
202
202
  // unless LiveStore is running in the devtools
203
203
  __runningInDevtools
204
204
  ? this.schema.tables.keys()
205
205
  : Array.from(this.schema.tables.keys()).filter(
206
206
  (_) =>
207
207
  _ !== SCHEMA_META_TABLE &&
208
- _ !== SCHEMA_MUTATIONS_META_TABLE &&
208
+ _ !== SCHEMA_EVENT_DEFS_META_TABLE &&
209
209
  _ !== SESSION_CHANGESET_META_TABLE &&
210
210
  _ !== LEADER_MERGE_COUNTER_TABLE,
211
211
  ),
@@ -231,7 +231,7 @@ export class Store<TSchema extends LiveStoreSchema = LiveStoreSchema, TContext =
231
231
 
232
232
  // End the otel spans
233
233
  syncSpan.end()
234
- mutationsSpan.end()
234
+ commitsSpan.end()
235
235
  queriesSpan.end()
236
236
  }),
237
237
  )
@@ -259,11 +259,11 @@ export class Store<TSchema extends LiveStoreSchema = LiveStoreSchema, TContext =
259
259
  * ```
260
260
  */
261
261
  subscribe = <TResult>(
262
- query: LiveQueryDef<TResult, any> | LiveQuery<TResult, any>,
262
+ query: LiveQueryDef<TResult> | LiveQuery<TResult>,
263
263
  options: {
264
264
  /** Called when the query result has changed */
265
265
  onUpdate: (value: TResult) => void
266
- onSubscribe?: (query$: LiveQuery<TResult, any>) => void
266
+ onSubscribe?: (query$: LiveQuery<TResult>) => void
267
267
  /** Gets called after the query subscription has been removed */
268
268
  onUnsubsubscribe?: () => void
269
269
  label?: string
@@ -337,7 +337,7 @@ export class Store<TSchema extends LiveStoreSchema = LiveStoreSchema, TContext =
337
337
  )
338
338
 
339
339
  subscribeStream = <TResult>(
340
- query$: LiveQueryDef<TResult, any>,
340
+ query$: LiveQueryDef<TResult>,
341
341
  options?: { label?: string; skipInitialRun?: boolean } | undefined,
342
342
  ): Stream.Stream<TResult> =>
343
343
  Stream.asyncPush<TResult>((emit) =>
@@ -377,8 +377,8 @@ export class Store<TSchema extends LiveStoreSchema = LiveStoreSchema, TContext =
377
377
  query = <TResult>(
378
378
  query:
379
379
  | QueryBuilder<TResult, any, any>
380
- | LiveQuery<TResult, any>
381
- | LiveQueryDef<TResult, any>
380
+ | LiveQuery<TResult>
381
+ | LiveQueryDef<TResult>
382
382
  | { query: string; bindValues: ParamsObject },
383
383
  options?: { otelContext?: otel.Context; debugRefreshReason?: RefreshReason },
384
384
  ): TResult => {
@@ -392,7 +392,7 @@ export class Store<TSchema extends LiveStoreSchema = LiveStoreSchema, TContext =
392
392
  makeExecBeforeFirstRun({
393
393
  table: ast.tableDef,
394
394
  id: ast.id,
395
- insertValues: ast.insertValues,
395
+ explicitDefaultValues: ast.explicitDefaultValues,
396
396
  otelContext: options?.otelContext,
397
397
  })(this.reactivityGraph.context!)
398
398
  }
@@ -415,6 +415,8 @@ export class Store<TSchema extends LiveStoreSchema = LiveStoreSchema, TContext =
415
415
  }
416
416
  }
417
417
 
418
+ atom = (): TODO => {}
419
+
418
420
  // makeLive: {
419
421
  // <T>(def: LiveQueryDef<T, any>): LiveQuery<T, any>
420
422
  // <T>(def: ILiveQueryRefDef<T>): ILiveQueryRef<T>
@@ -434,42 +436,42 @@ export class Store<TSchema extends LiveStoreSchema = LiveStoreSchema, TContext =
434
436
 
435
437
  // #region commit
436
438
  /**
437
- * Commit a list of mutations to the store which will immediately update the local database
438
- * and sync the mutations across other clients (similar to a `git commit`).
439
+ * Commit a list of events to the store which will immediately update the local database
440
+ * and sync the events across other clients (similar to a `git commit`).
439
441
  *
440
442
  * @example
441
443
  * ```ts
442
- * store.commit(mutations.todoCreated({ id: nanoid(), text: 'Make coffee' }))
444
+ * store.commit(events.todoCreated({ id: nanoid(), text: 'Make coffee' }))
443
445
  * ```
444
446
  *
445
- * You can call `commit` with multiple mutations to apply them in a single database transaction.
447
+ * You can call `commit` with multiple events to apply them in a single database transaction.
446
448
  *
447
449
  * @example
448
450
  * ```ts
449
451
  * const todoId = nanoid()
450
452
  * store.commit(
451
- * mutations.todoCreated({ id: todoId, text: 'Make coffee' }),
452
- * mutations.todoCompleted({ id: todoId }))
453
+ * events.todoCreated({ id: todoId, text: 'Make coffee' }),
454
+ * events.todoCompleted({ id: todoId }))
453
455
  * ```
454
456
  *
455
457
  * For more advanced transaction scenarios, you can pass a synchronous function to `commit` which will receive a callback
456
- * to which you can pass multiple mutations to be committed in the same database transaction.
457
- * Under the hood this will simply collect all mutations and apply them in a single database transaction.
458
+ * to which you can pass multiple events to be committed in the same database transaction.
459
+ * Under the hood this will simply collect all events and apply them in a single database transaction.
458
460
  *
459
461
  * @example
460
462
  * ```ts
461
463
  * store.commit((commit) => {
462
464
  * const todoId = nanoid()
463
465
  * if (Math.random() > 0.5) {
464
- * commit(mutations.todoCreated({ id: todoId, text: 'Make coffee' }))
466
+ * commit(events.todoCreated({ id: todoId, text: 'Make coffee' }))
465
467
  * } else {
466
- * commit(mutations.todoCompleted({ id: todoId }))
468
+ * commit(events.todoCompleted({ id: todoId }))
467
469
  * }
468
470
  * })
469
471
  * ```
470
472
  *
471
- * When committing a large batch of mutations, you can also skip the database refresh to improve performance
472
- * and call `store.manualRefresh()` after all mutations have been committed.
473
+ * When committing a large batch of events, you can also skip the database refresh to improve performance
474
+ * and call `store.manualRefresh()` after all events have been committed.
473
475
  *
474
476
  * @example
475
477
  * ```ts
@@ -479,44 +481,44 @@ export class Store<TSchema extends LiveStoreSchema = LiveStoreSchema, TContext =
479
481
  * // ... 1000 more todos
480
482
  * ]
481
483
  * for (const todo of todos) {
482
- * store.commit({ skipRefresh: true }, mutations.todoCreated({ id: todo.id, text: todo.text }))
484
+ * store.commit({ skipRefresh: true }, events.todoCreated({ id: todo.id, text: todo.text }))
483
485
  * }
484
486
  * store.manualRefresh()
485
487
  * ```
486
488
  */
487
489
  commit: {
488
- <const TMutationArg extends ReadonlyArray<MutationEvent.PartialForSchema<TSchema>>>(...list: TMutationArg): void
490
+ <const TCommitArg extends ReadonlyArray<LiveStoreEvent.PartialForSchema<TSchema>>>(...list: TCommitArg): void
489
491
  (
490
- txn: <const TMutationArg extends ReadonlyArray<MutationEvent.PartialForSchema<TSchema>>>(
491
- ...list: TMutationArg
492
+ txn: <const TCommitArg extends ReadonlyArray<LiveStoreEvent.PartialForSchema<TSchema>>>(
493
+ ...list: TCommitArg
492
494
  ) => void,
493
495
  ): void
494
- <const TMutationArg extends ReadonlyArray<MutationEvent.PartialForSchema<TSchema>>>(
495
- options: StoreMutateOptions,
496
- ...list: TMutationArg
496
+ <const TCommitArg extends ReadonlyArray<LiveStoreEvent.PartialForSchema<TSchema>>>(
497
+ options: StoreCommitOptions,
498
+ ...list: TCommitArg
497
499
  ): void
498
500
  (
499
- options: StoreMutateOptions,
500
- txn: <const TMutationArg extends ReadonlyArray<MutationEvent.PartialForSchema<TSchema>>>(
501
- ...list: TMutationArg
501
+ options: StoreCommitOptions,
502
+ txn: <const TCommitArg extends ReadonlyArray<LiveStoreEvent.PartialForSchema<TSchema>>>(
503
+ ...list: TCommitArg
502
504
  ) => void,
503
505
  ): void
504
- } = (firstMutationOrTxnFnOrOptions: any, ...restMutations: any[]) => {
505
- const { mutationsEvents, options } = this.getMutateArgs(firstMutationOrTxnFnOrOptions, restMutations)
506
+ } = (firstEventOrTxnFnOrOptions: any, ...restEvents: any[]) => {
507
+ const { events, options } = this.getCommitArgs(firstEventOrTxnFnOrOptions, restEvents)
506
508
 
507
- for (const mutationEvent of mutationsEvents) {
508
- replaceSessionIdSymbol(mutationEvent.args, this.clientSession.sessionId)
509
+ for (const event of events) {
510
+ replaceSessionIdSymbol(event.args, this.clientSession.sessionId)
509
511
  }
510
512
 
511
- if (mutationsEvents.length === 0) return
513
+ if (events.length === 0) return
512
514
 
513
515
  const skipRefresh = options?.skipRefresh ?? false
514
516
 
515
- const mutationsSpan = otel.trace.getSpan(this.otel.mutationsSpanContext)!
516
- mutationsSpan.addEvent('commit')
517
+ const commitsSpan = otel.trace.getSpan(this.otel.commitsSpanContext)!
518
+ commitsSpan.addEvent('commit')
517
519
 
518
520
  // console.group('LiveStore.commit', { skipRefresh, wasSyncMessage, label })
519
- // mutationsEvents.forEach((_) => console.debug(_.mutation, _.id, _.args))
521
+ // events.forEach((_) => console.debug(_.name, _.id, _.args))
520
522
  // console.groupEnd()
521
523
 
522
524
  let durationMs: number
@@ -525,26 +527,26 @@ export class Store<TSchema extends LiveStoreSchema = LiveStoreSchema, TContext =
525
527
  'LiveStore:commit',
526
528
  {
527
529
  attributes: {
528
- 'livestore.mutationEventsCount': mutationsEvents.length,
529
- 'livestore.mutationEventTags': mutationsEvents.map((_) => _.mutation),
530
+ 'livestore.eventsCount': events.length,
531
+ 'livestore.eventTags': events.map((_) => _.name),
530
532
  'livestore.commitLabel': options?.label,
531
533
  },
532
534
  links: options?.spanLinks,
533
535
  },
534
- options?.otelContext ?? this.otel.mutationsSpanContext,
536
+ options?.otelContext ?? this.otel.commitsSpanContext,
535
537
  (span) => {
536
538
  const otelContext = otel.trace.setSpan(otel.context.active(), span)
537
539
 
538
540
  try {
539
541
  const { writeTables } = (() => {
540
542
  try {
541
- const applyMutations = () => this.syncProcessor.push(mutationsEvents, { otelContext })
543
+ const applyEvents = () => this.syncProcessor.push(events, { otelContext })
542
544
 
543
- if (mutationsEvents.length > 1) {
545
+ if (events.length > 1) {
544
546
  // TODO: what to do about leader transaction here?
545
- return this.sqliteDbWrapper.txn(applyMutations)
547
+ return this.sqliteDbWrapper.txn(applyEvents)
546
548
  } else {
547
- return applyMutations()
549
+ return applyEvents()
548
550
  }
549
551
  } catch (e: any) {
550
552
  console.error(e)
@@ -564,7 +566,7 @@ export class Store<TSchema extends LiveStoreSchema = LiveStoreSchema, TContext =
564
566
 
565
567
  const debugRefreshReason = {
566
568
  _tag: 'commit' as const,
567
- mutations: mutationsEvents,
569
+ events,
568
570
  writeTables: Array.from(writeTables),
569
571
  }
570
572
 
@@ -587,7 +589,7 @@ export class Store<TSchema extends LiveStoreSchema = LiveStoreSchema, TContext =
587
589
  // #endregion commit
588
590
 
589
591
  /**
590
- * This can be used in combination with `skipRefresh` when applying mutations.
592
+ * This can be used in combination with `skipRefresh` when committing events.
591
593
  * We might need a better solution for this. Let's see.
592
594
  */
593
595
  manualRefresh = (options?: { label?: string }) => {
@@ -595,7 +597,7 @@ export class Store<TSchema extends LiveStoreSchema = LiveStoreSchema, TContext =
595
597
  this.otel.tracer.startActiveSpan(
596
598
  'LiveStore:manualRefresh',
597
599
  { attributes: { 'livestore.manualRefreshLabel': label } },
598
- this.otel.mutationsSpanContext,
600
+ this.otel.commitsSpanContext,
599
601
  (span) => {
600
602
  const otelContext = otel.trace.setSpan(otel.context.active(), span)
601
603
  this.reactivityGraph.runDeferredEffects({ otelContext })
@@ -624,10 +626,10 @@ export class Store<TSchema extends LiveStoreSchema = LiveStoreSchema, TContext =
624
626
  }).pipe(this.runEffectFork)
625
627
  },
626
628
 
627
- downloadMutationLogDb: () => {
629
+ downloadEventlogDb: () => {
628
630
  Effect.gen(this, function* () {
629
- const data = yield* this.clientSession.leaderThread.getMutationLogData
630
- downloadBlob(data, `livestore-mutationlog-${Date.now()}.db`)
631
+ const data = yield* this.clientSession.leaderThread.getEventlogData
632
+ downloadBlob(data, `livestore-eventlog-${Date.now()}.db`)
631
633
  }).pipe(this.runEffectFork)
632
634
  },
633
635
 
@@ -668,36 +670,40 @@ export class Store<TSchema extends LiveStoreSchema = LiveStoreSchema, TContext =
668
670
  Runtime.runFork(this.effectContext.runtime),
669
671
  )
670
672
 
671
- private getMutateArgs = (
672
- firstMutationOrTxnFnOrOptions: any,
673
- restMutations: any[],
673
+ private getCommitArgs = (
674
+ firstEventOrTxnFnOrOptions: any,
675
+ restEvents: any[],
674
676
  ): {
675
- mutationsEvents: (MutationEvent.ForSchema<TSchema> | MutationEvent.PartialForSchema<TSchema>)[]
676
- options: StoreMutateOptions | undefined
677
+ events: LiveStoreEvent.PartialForSchema<TSchema>[]
678
+ options: StoreCommitOptions | undefined
677
679
  } => {
678
- let mutationsEvents: (MutationEvent.ForSchema<TSchema> | MutationEvent.PartialForSchema<TSchema>)[]
679
- let options: StoreMutateOptions | undefined
680
+ let events: LiveStoreEvent.PartialForSchema<TSchema>[]
681
+ let options: StoreCommitOptions | undefined
680
682
 
681
- if (typeof firstMutationOrTxnFnOrOptions === 'function') {
683
+ if (typeof firstEventOrTxnFnOrOptions === 'function') {
682
684
  // TODO ensure that function is synchronous and isn't called in a async way (also write tests for this)
683
- mutationsEvents = firstMutationOrTxnFnOrOptions((arg: any) => mutationsEvents.push(arg))
685
+ events = firstEventOrTxnFnOrOptions((arg: any) => events.push(arg))
684
686
  } else if (
685
- firstMutationOrTxnFnOrOptions?.label !== undefined ||
686
- firstMutationOrTxnFnOrOptions?.skipRefresh !== undefined ||
687
- firstMutationOrTxnFnOrOptions?.otelContext !== undefined ||
688
- firstMutationOrTxnFnOrOptions?.spanLinks !== undefined
687
+ firstEventOrTxnFnOrOptions?.label !== undefined ||
688
+ firstEventOrTxnFnOrOptions?.skipRefresh !== undefined ||
689
+ firstEventOrTxnFnOrOptions?.otelContext !== undefined ||
690
+ firstEventOrTxnFnOrOptions?.spanLinks !== undefined
689
691
  ) {
690
- options = firstMutationOrTxnFnOrOptions
691
- mutationsEvents = restMutations
692
- } else if (firstMutationOrTxnFnOrOptions === undefined) {
693
- // When `commit` is called with no arguments (which sometimes happens when dynamically filtering mutations)
694
- mutationsEvents = []
692
+ options = firstEventOrTxnFnOrOptions
693
+ events = restEvents
694
+ } else if (firstEventOrTxnFnOrOptions === undefined) {
695
+ // When `commit` is called with no arguments (which sometimes happens when dynamically filtering events)
696
+ events = []
695
697
  } else {
696
- mutationsEvents = [firstMutationOrTxnFnOrOptions, ...restMutations]
698
+ events = [firstEventOrTxnFnOrOptions, ...restEvents]
697
699
  }
698
700
 
699
- mutationsEvents = mutationsEvents.filter((_) => Predicate.hasProperty(_, 'id') === false)
701
+ // for (const event of events) {
702
+ // if (event.args.id === SessionIdSymbol) {
703
+ // event.args.id = this.clientSession.sessionId
704
+ // }
705
+ // }
700
706
 
701
- return { mutationsEvents, options }
707
+ return { events, options }
702
708
  }
703
709
  }
@@ -86,7 +86,7 @@ Error:
86
86
  at Object.useMemo (/Users/schickling/Code/overtone/node_modules/.pnpm/react-dom@19.0.0_react@19.0.0/node_modules/react-dom/cjs/react-dom-client.development.js:22757:18)
87
87
  at Object.process.env.NODE_ENV.exports.useMemo (/Users/schickling/Code/overtone/node_modules/.pnpm/react@19.0.0/node_modules/react/cjs/react.development.js:1488:34)
88
88
  at Module.useQueryRef (/Users/schickling/Code/overtone/submodules/livestore/packages/@livestore/react/src/useQuery.ts:54:27)
89
- at Module.useRow (/Users/schickling/Code/overtone/submodules/livestore/packages/@livestore/react/src/useRow.ts:111:20)
89
+ at Module.useClientDocument (/Users/schickling/Code/overtone/submodules/livestore/packages/@livestore/react/src/useClientDocument.ts:111:20)
90
90
  at TestComponent (/Users/schickling/Code/overtone/node_modules/.pnpm/@testing-library+react@16.1.0_@testing-library+dom@10.4.0_@types+react-dom@19.0.3_@types+reac_2jaiibiag2sxou3wtzbuqx3r5a/node_modules/@testing-library/react/dist/pure.js:309:27)
91
91
  at Object.react-stack-bottom-frame (/Users/schickling/Code/overtone/node_modules/.pnpm/react-dom@19.0.0_react@19.0.0/node_modules/react-dom/cjs/react-dom-client.development.js:22428:20)
92
92
  at renderWithHooks (/Users/schickling/Code/overtone/node_modules/.pnpm/react-dom@19.0.0_react@19.0.0/node_modules/react-dom/cjs/react-dom-client.development.js:5757:22)
@@ -101,8 +101,8 @@ Error:
101
101
  "name": "TestComponent",
102
102
  },
103
103
  {
104
- "filePath": "/Users/schickling/Code/overtone/submodules/livestore/packages/@livestore/react/src/useRow.ts:111:20",
105
- "name": "useRow",
104
+ "filePath": "/Users/schickling/Code/overtone/submodules/livestore/packages/@livestore/react/src/useClientDocument.ts:111:20",
105
+ "name": "useClientDocument",
106
106
  },
107
107
  ],
108
108
  }
@@ -117,7 +117,7 @@ Error:
117
117
  at Object.useMemo (/Users/schickling/Code/overtone/node_modules/.pnpm/react-dom@19.0.0_react@19.0.0/node_modules/react-dom/cjs/react-dom-client.development.js:22757:18)
118
118
  at Object.process.env.NODE_ENV.exports.useMemo (/Users/schickling/Code/overtone/node_modules/.pnpm/react@19.0.0/node_modules/react/cjs/react.development.js:1488:34)
119
119
  at Module.useQueryRef (/Users/schickling/Code/overtone/submodules/livestore/packages/@livestore/react/src/useQuery.ts:54:27)
120
- at Module.useRow (/Users/schickling/Code/overtone/submodules/livestore/packages/@livestore/react/src/useRow.ts:111:20)
120
+ at Module.useClientDocument (/Users/schickling/Code/overtone/submodules/livestore/packages/@livestore/react/src/useClientDocument.ts:111:20)
121
121
  at Object.react-stack-bottom-frame (/Users/schickling/Code/overtone/node_modules/.pnpm/react-dom@19.0.0_react@19.0.0/node_modules/react-dom/cjs/react-dom-client.development.js:22428:20)
122
122
  at renderWithHooks (/Users/schickling/Code/overtone/node_modules/.pnpm/react-dom@19.0.0_react@19.0.0/node_modules/react-dom/cjs/react-dom-client.development.js:5757:22)
123
123
  `
@@ -127,8 +127,8 @@ Error:
127
127
  {
128
128
  "frames": [
129
129
  {
130
- "filePath": "/Users/schickling/Code/overtone/submodules/livestore/packages/@livestore/react/src/useRow.ts:111:20",
131
- "name": "useRow",
130
+ "filePath": "/Users/schickling/Code/overtone/submodules/livestore/packages/@livestore/react/src/useClientDocument.ts:111:20",
131
+ "name": "useClientDocument",
132
132
  },
133
133
  ],
134
134
  }
@@ -1,9 +1,7 @@
1
1
  import { makeInMemoryAdapter } from '@livestore/adapter-web'
2
2
  import { provideOtel } from '@livestore/common'
3
- import type { FromInputSchema } from '@livestore/common/schema'
4
- import type { Store } from '@livestore/livestore'
5
- import { createStore, DbSchema, makeSchema } from '@livestore/livestore'
6
- import { Effect } from '@livestore/utils/effect'
3
+ import { createStore, makeSchema, State } from '@livestore/livestore'
4
+ import { Effect, Schema } from '@livestore/utils/effect'
7
5
  import type * as otel from '@opentelemetry/api'
8
6
 
9
7
  export type Todo = {
@@ -19,30 +17,28 @@ export type AppState = {
19
17
  filter: Filter
20
18
  }
21
19
 
22
- export const todos = DbSchema.table(
23
- 'todos',
24
- {
25
- id: DbSchema.text({ primaryKey: true }),
26
- text: DbSchema.text({ default: '', nullable: false }),
27
- completed: DbSchema.boolean({ default: false, nullable: false }),
20
+ export const todos = State.SQLite.table({
21
+ name: 'todos',
22
+ columns: {
23
+ id: State.SQLite.text({ primaryKey: true }),
24
+ text: State.SQLite.text({ default: '', nullable: false }),
25
+ completed: State.SQLite.boolean({ default: false, nullable: false }),
28
26
  },
29
- { deriveMutations: true, isSingleton: false },
30
- )
31
-
32
- export const app = DbSchema.table(
33
- 'app',
34
- {
35
- id: DbSchema.text({ primaryKey: true, default: 'static' }),
36
- newTodoText: DbSchema.text({ default: '', nullable: true }),
37
- filter: DbSchema.text({ default: 'all', nullable: false }),
38
- },
39
- { isSingleton: true },
40
- )
27
+ })
28
+
29
+ export const app = State.SQLite.clientDocument({
30
+ name: 'app',
31
+ schema: Schema.Struct({
32
+ newTodoText: Schema.String,
33
+ filter: Schema.String,
34
+ }),
35
+ default: { value: { newTodoText: '', filter: 'all' } },
36
+ })
41
37
 
42
38
  export const tables = { todos, app }
43
- export const schema = makeSchema({ tables })
44
39
 
45
- export interface FixtureSchema extends FromInputSchema.DeriveSchema<{ tables: typeof tables }> {}
40
+ export const state = State.SQLite.makeState({ tables, materializers: {} })
41
+ export const schema = makeSchema({ state, events: {} })
46
42
 
47
43
  export const makeTodoMvc = ({
48
44
  otelTracer,
@@ -52,7 +48,7 @@ export const makeTodoMvc = ({
52
48
  otelContext?: otel.Context
53
49
  } = {}) =>
54
50
  Effect.gen(function* () {
55
- const store: Store<FixtureSchema> = yield* createStore({
51
+ const store = yield* createStore({
56
52
  schema,
57
53
  storeId: 'default',
58
54
  adapter: makeInMemoryAdapter(),
@@ -13,14 +13,21 @@ export const getSimplifiedRootSpan = (
13
13
  const mapAttributesfn = mapAttributes ?? identity
14
14
 
15
15
  spansMap.forEach((nestedSpan) => {
16
- const parentSpan = nestedSpan.span.parentSpanId ? spansMap.get(nestedSpan.span.parentSpanId) : undefined
16
+ const parentId = nestedSpan.span.parentSpanContext?.spanId
17
+ const parentSpan = parentId ? spansMap.get(parentId) : undefined
17
18
  if (parentSpan) {
18
19
  parentSpan.children.push(nestedSpan)
19
20
  }
20
21
  })
21
22
 
22
23
  type NestedSpan = { span: ReadableSpan; children: NestedSpan[] }
23
- const rootSpan = spansMap.get(spans.find((_) => _.name === 'createStore')!.spanContext().spanId)!
24
+ const createStoreSpanData = spans.find((_) => _.name === 'createStore')
25
+ if (createStoreSpanData === undefined) {
26
+ throw new Error(
27
+ "Could not find the root span named 'createStore'. Available spans: " + spans.map((s) => s.name).join(', '),
28
+ )
29
+ }
30
+ const rootSpan = spansMap.get(createStoreSpanData.spanContext().spanId)!
24
31
 
25
32
  const simplifySpanRec = (span: NestedSpan): SimplifiedNestedSpan =>
26
33
  omitEmpty({
@@ -88,7 +95,7 @@ export const toTraceFile = (spans: ReadableSpan[]) => {
88
95
  spans: spans.map((span) => ({
89
96
  traceId: span.spanContext().traceId,
90
97
  spanId: span.spanContext().spanId,
91
- ...(span.parentSpanId ? { parentSpanId: span.parentSpanId } : {}),
98
+ ...(span.parentSpanContext?.spanId ? { parentSpanId: span.parentSpanContext.spanId } : {}),
92
99
  // traceState: span.spanContext().traceState ?? '',
93
100
  name: span.name,
94
101
  kind: 'SPAN_KIND_INTERNAL',
package/tmp/pack.tgz CHANGED
Binary file
@@ -1,17 +0,0 @@
1
- import type { QueryInfo } from '@livestore/common';
2
- import { SessionIdSymbol } from '@livestore/common';
3
- import { DbSchema } from '@livestore/common/schema';
4
- import type * as otel from '@opentelemetry/api';
5
- import type { GetResult, LiveQueryDef, ReactivityGraphContext } from './live-queries/base-class.js';
6
- export declare const rowQueryLabel: (table: DbSchema.TableDefBase, id: string | SessionIdSymbol | number | undefined) => string;
7
- export declare const deriveColQuery: {
8
- <TQueryDef extends LiveQueryDef<any, QueryInfo.None>, TCol extends keyof GetResult<TQueryDef> & string>(queryDef: TQueryDef, colName: TCol): LiveQueryDef<GetResult<TQueryDef>[TCol], QueryInfo.None>;
9
- <TQueryDef extends LiveQueryDef<any, QueryInfo.Row>, TCol extends keyof GetResult<TQueryDef> & string>(queryDef: TQueryDef, colName: TCol): LiveQueryDef<GetResult<TQueryDef>[TCol], QueryInfo.Col>;
10
- };
11
- export declare const makeExecBeforeFirstRun: ({ id, insertValues, table, otelContext: otelContext_, }: {
12
- id?: string | SessionIdSymbol | number;
13
- insertValues?: any;
14
- table: DbSchema.TableDefBase;
15
- otelContext: otel.Context | undefined;
16
- }) => ({ store }: ReactivityGraphContext) => undefined;
17
- //# sourceMappingURL=row-query-utils.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"row-query-utils.d.ts","sourceRoot":"","sources":["../src/row-query-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAsB,SAAS,EAAE,MAAM,mBAAmB,CAAA;AACtE,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AAEnD,OAAO,KAAK,KAAK,IAAI,MAAM,oBAAoB,CAAA;AAE/C,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAA;AAGnG,eAAO,MAAM,aAAa,GAAI,OAAO,QAAQ,CAAC,YAAY,EAAE,IAAI,MAAM,GAAG,eAAe,GAAG,MAAM,GAAG,SAAS,WACH,CAAA;AAE1G,eAAO,MAAM,cAAc,EAAE;IAC3B,CAAC,SAAS,SAAS,YAAY,CAAC,GAAG,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,IAAI,SAAS,MAAM,SAAS,CAAC,SAAS,CAAC,GAAG,MAAM,EACpG,QAAQ,EAAE,SAAS,EACnB,OAAO,EAAE,IAAI,GACZ,YAAY,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,IAAI,CAAC,CAAA;IAC3D,CAAC,SAAS,SAAS,YAAY,CAAC,GAAG,EAAE,SAAS,CAAC,GAAG,CAAC,EAAE,IAAI,SAAS,MAAM,SAAS,CAAC,SAAS,CAAC,GAAG,MAAM,EACnG,QAAQ,EAAE,SAAS,EACnB,OAAO,EAAE,IAAI,GACZ,YAAY,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,GAAG,CAAC,CAAA;CAc3D,CAAA;AAED,eAAO,MAAM,sBAAsB,GAChC,yDAKE;IACD,EAAE,CAAC,EAAE,MAAM,GAAG,eAAe,GAAG,MAAM,CAAA;IACtC,YAAY,CAAC,EAAE,GAAG,CAAA;IAClB,KAAK,EAAE,QAAQ,CAAC,YAAY,CAAA;IAC5B,WAAW,EAAE,IAAI,CAAC,OAAO,GAAG,SAAS,CAAA;CACtC,MACA,WAAW,sBAAsB,cA2BjC,CAAA"}
@@ -1,34 +0,0 @@
1
- import { SessionIdSymbol } from '@livestore/common';
2
- import { DbSchema } from '@livestore/common/schema';
3
- import { shouldNeverHappen } from '@livestore/utils';
4
- import { computed } from './live-queries/computed.js';
5
- export const rowQueryLabel = (table, id) => `row:${table.sqliteDef.name}${id === undefined ? '' : id === SessionIdSymbol ? `:sessionId` : `:${id}`}`;
6
- export const deriveColQuery = (queryDef, colName) => {
7
- return computed((get) => get(queryDef)[colName], {
8
- label: `deriveColQuery:${queryDef.label}:${colName}`,
9
- queryInfo: queryDef.queryInfo._tag === 'Row'
10
- ? { _tag: 'Col', table: queryDef.queryInfo.table, column: colName, id: queryDef.queryInfo.id }
11
- : undefined,
12
- deps: [
13
- queryDef.queryInfo.table.sqliteDef.name,
14
- queryDef.queryInfo.id === SessionIdSymbol ? 'sessionId' : queryDef.queryInfo.id,
15
- queryDef.queryInfo._tag === 'Col' ? queryDef.queryInfo.column : undefined,
16
- ],
17
- });
18
- };
19
- export const makeExecBeforeFirstRun = ({ id, insertValues, table, otelContext: otelContext_, }) => ({ store }) => {
20
- const otelContext = otelContext_ ?? store.otel.queriesSpanContext;
21
- if (table.options.isSingleton === false) {
22
- const idVal = id === SessionIdSymbol ? store.sessionId : id;
23
- const rowExists = store.sqliteDbWrapper.select(`SELECT 1 FROM '${table.sqliteDef.name}' WHERE id = ?`, [idVal], { otelContext }).length === 1;
24
- if (rowExists)
25
- return;
26
- if (DbSchema.tableHasDerivedMutations(table) === false) {
27
- return shouldNeverHappen(`Cannot insert row for table "${table.sqliteDef.name}" which does not have 'deriveMutations: true' set`);
28
- }
29
- // It's important that we only commit and don't refresh here, as this function might be called during a render
30
- // and otherwise we might end up in a "reactive loop"
31
- store.commit({ otelContext, skipRefresh: true, label: `rowQuery:${table.sqliteDef.name}:${idVal}` }, table.insert({ id, ...insertValues }));
32
- }
33
- };
34
- //# sourceMappingURL=row-query-utils.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"row-query-utils.js","sourceRoot":"","sources":["../src/row-query-utils.ts"],"names":[],"mappings":"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"}