@livestore/livestore 0.3.0-dev.23 → 0.3.0-dev.25

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.
@@ -1,6 +1,7 @@
1
1
  import type { ClientSession, IntentionalShutdownCause, StoreInterrupted, UnexpectedError } from '@livestore/common'
2
2
  import type { EventId, LiveStoreSchema, MutationEvent } from '@livestore/common/schema'
3
- import type { Deferred, MutableHashMap, Runtime, Scope } from '@livestore/utils/effect'
3
+ import type { Effect, MutableHashMap, Runtime, Scope } from '@livestore/utils/effect'
4
+ import { Deferred } from '@livestore/utils/effect'
4
5
  import type * as otel from '@opentelemetry/api'
5
6
 
6
7
  import type { DebugRefreshReasonBase } from '../reactive.js'
@@ -19,6 +20,10 @@ export type LiveStoreContext =
19
20
  }
20
21
 
21
22
  export type ShutdownDeferred = Deferred.Deferred<void, UnexpectedError | IntentionalShutdownCause | StoreInterrupted>
23
+ export const makeShutdownDeferred: Effect.Effect<ShutdownDeferred> = Deferred.make<
24
+ void,
25
+ UnexpectedError | IntentionalShutdownCause | StoreInterrupted
26
+ >()
22
27
 
23
28
  export type LiveStoreContextRunning = {
24
29
  stage: 'running'
@@ -51,7 +56,7 @@ export type StoreOptions<TSchema extends LiveStoreSchema = LiveStoreSchema, TCon
51
56
  export type RefreshReason =
52
57
  | DebugRefreshReasonBase
53
58
  | {
54
- _tag: 'mutate'
59
+ _tag: 'commit'
55
60
  /** The mutations that were applied */
56
61
  mutations: ReadonlyArray<MutationEvent.AnyDecoded | MutationEvent.PartialAnyDecoded>
57
62
 
@@ -412,6 +412,7 @@ export class Store<TSchema extends LiveStoreSchema = LiveStoreSchema, TContext =
412
412
  otelContext: options?.otelContext,
413
413
  queriedTables: new Set([query[QueryBuilderAstSymbol].tableDef.sqliteDef.name]),
414
414
  })
415
+
415
416
  return Schema.decodeSync(schema)(rawRes)
416
417
  } else if (query._tag === 'def') {
417
418
  const query$ = query.make(this.reactivityGraph.context!)
@@ -440,8 +441,59 @@ export class Store<TSchema extends LiveStoreSchema = LiveStoreSchema, TContext =
440
441
  ref.deref()
441
442
  }
442
443
 
443
- // #region mutate
444
- mutate: {
444
+ // #region commit
445
+ /**
446
+ * Commit a list of mutations to the store which will immediately update the local database
447
+ * and sync the mutations across other clients (similar to a `git commit`).
448
+ *
449
+ * @example
450
+ * ```ts
451
+ * store.commit(mutations.todoCreated({ id: nanoid(), text: 'Make coffee' }))
452
+ * ```
453
+ *
454
+ * You can call `commit` with multiple mutations to apply them in a single database transaction.
455
+ *
456
+ * @example
457
+ * ```ts
458
+ * const todoId = nanoid()
459
+ * store.commit(
460
+ * mutations.todoCreated({ id: todoId, text: 'Make coffee' }),
461
+ * mutations.todoCompleted({ id: todoId }))
462
+ * ```
463
+ *
464
+ * For more advanced transaction scenarios, you can pass a synchronous function to `commit` which will receive a callback
465
+ * to which you can pass multiple mutations to be committed in the same database transaction.
466
+ * Under the hood this will simply collect all mutations and apply them in a single database transaction.
467
+ *
468
+ * @example
469
+ * ```ts
470
+ * store.commit((commit) => {
471
+ * const todoId = nanoid()
472
+ * if (Math.random() > 0.5) {
473
+ * commit(mutations.todoCreated({ id: todoId, text: 'Make coffee' }))
474
+ * } else {
475
+ * commit(mutations.todoCompleted({ id: todoId }))
476
+ * }
477
+ * })
478
+ * ```
479
+ *
480
+ * When committing a large batch of mutations, you can also skip the database refresh to improve performance
481
+ * and call `store.manualRefresh()` after all mutations have been committed.
482
+ *
483
+ * @example
484
+ * ```ts
485
+ * const todos = [
486
+ * { id: nanoid(), text: 'Make coffee' },
487
+ * { id: nanoid(), text: 'Buy groceries' },
488
+ * // ... 1000 more todos
489
+ * ]
490
+ * for (const todo of todos) {
491
+ * store.commit({ skipRefresh: true }, mutations.todoCreated({ id: todo.id, text: todo.text }))
492
+ * }
493
+ * store.manualRefresh()
494
+ * ```
495
+ */
496
+ commit: {
445
497
  <const TMutationArg extends ReadonlyArray<MutationEvent.PartialForSchema<TSchema>>>(...list: TMutationArg): void
446
498
  (
447
499
  txn: <const TMutationArg extends ReadonlyArray<MutationEvent.PartialForSchema<TSchema>>>(
@@ -470,21 +522,21 @@ export class Store<TSchema extends LiveStoreSchema = LiveStoreSchema, TContext =
470
522
  const skipRefresh = options?.skipRefresh ?? false
471
523
 
472
524
  const mutationsSpan = otel.trace.getSpan(this.otel.mutationsSpanContext)!
473
- mutationsSpan.addEvent('mutate')
525
+ mutationsSpan.addEvent('commit')
474
526
 
475
- // console.group('LiveStore.mutate', { skipRefresh, wasSyncMessage, label })
527
+ // console.group('LiveStore.commit', { skipRefresh, wasSyncMessage, label })
476
528
  // mutationsEvents.forEach((_) => console.debug(_.mutation, _.id, _.args))
477
529
  // console.groupEnd()
478
530
 
479
531
  let durationMs: number
480
532
 
481
533
  return this.otel.tracer.startActiveSpan(
482
- 'LiveStore:mutate',
534
+ 'LiveStore:commit',
483
535
  {
484
536
  attributes: {
485
537
  'livestore.mutationEventsCount': mutationsEvents.length,
486
538
  'livestore.mutationEventTags': mutationsEvents.map((_) => _.mutation),
487
- 'livestore.mutateLabel': options?.label,
539
+ 'livestore.commitLabel': options?.label,
488
540
  },
489
541
  links: options?.spanLinks,
490
542
  },
@@ -520,7 +572,7 @@ export class Store<TSchema extends LiveStoreSchema = LiveStoreSchema, TContext =
520
572
  }
521
573
 
522
574
  const debugRefreshReason = {
523
- _tag: 'mutate' as const,
575
+ _tag: 'commit' as const,
524
576
  mutations: mutationsEvents,
525
577
  writeTables: Array.from(writeTables),
526
578
  }
@@ -541,7 +593,7 @@ export class Store<TSchema extends LiveStoreSchema = LiveStoreSchema, TContext =
541
593
  },
542
594
  )
543
595
  }
544
- // #endregion mutate
596
+ // #endregion commit
545
597
 
546
598
  /**
547
599
  * This can be used in combination with `skipRefresh` when applying mutations.
@@ -643,7 +695,7 @@ export class Store<TSchema extends LiveStoreSchema = LiveStoreSchema, TContext =
643
695
  options = firstMutationOrTxnFnOrOptions
644
696
  mutationsEvents = restMutations
645
697
  } else if (firstMutationOrTxnFnOrOptions === undefined) {
646
- // When `mutate` is called with no arguments (which sometimes happens when dynamically filtering mutations)
698
+ // When `commit` is called with no arguments (which sometimes happens when dynamically filtering mutations)
647
699
  mutationsEvents = []
648
700
  } else {
649
701
  mutationsEvents = [firstMutationOrTxnFnOrOptions, ...restMutations]
package/tmp/pack.tgz CHANGED
Binary file