@livestore/livestore 0.3.0-dev.22 → 0.3.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.
- package/dist/.tsbuildinfo +1 -1
- package/dist/live-queries/db-query.test.js +3 -3
- package/dist/mod.d.ts +2 -1
- package/dist/mod.d.ts.map +1 -1
- package/dist/mod.js +3 -0
- package/dist/mod.js.map +1 -1
- package/dist/reactive.d.ts +1 -1
- package/dist/row-query-utils.js +2 -2
- package/dist/store/create-store.d.ts +8 -1
- package/dist/store/create-store.d.ts.map +1 -1
- package/dist/store/create-store.js +2 -1
- package/dist/store/create-store.js.map +1 -1
- package/dist/store/store-types.d.ts +4 -2
- package/dist/store/store-types.d.ts.map +1 -1
- package/dist/store/store-types.js +2 -1
- package/dist/store/store-types.js.map +1 -1
- package/dist/store/store.d.ts +52 -1
- package/dist/store/store.d.ts.map +1 -1
- package/dist/store/store.js +60 -9
- package/dist/store/store.js.map +1 -1
- package/package.json +4 -4
- package/src/live-queries/__snapshots__/db-query.test.ts.snap +3 -3
- package/src/live-queries/db-query.test.ts +3 -3
- package/src/mod.ts +8 -1
- package/src/reactive.ts +1 -1
- package/src/row-query-utils.ts +2 -2
- package/src/store/create-store.ts +9 -1
- package/src/store/store-types.ts +7 -2
- package/src/store/store.ts +61 -9
- package/tmp/pack.tgz +0 -0
package/src/row-query-utils.ts
CHANGED
|
@@ -66,9 +66,9 @@ export const makeExecBeforeFirstRun =
|
|
|
66
66
|
)
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
// It's important that we only
|
|
69
|
+
// It's important that we only commit and don't refresh here, as this function might be called during a render
|
|
70
70
|
// and otherwise we might end up in a "reactive loop"
|
|
71
|
-
store.
|
|
71
|
+
store.commit(
|
|
72
72
|
{ otelContext, skipRefresh: true, label: `rowQuery:${table.sqliteDef.name}:${idVal}` },
|
|
73
73
|
table.insert({ id, ...insertValues }),
|
|
74
74
|
)
|
|
@@ -9,7 +9,7 @@ import type {
|
|
|
9
9
|
import { provideOtel, UnexpectedError } from '@livestore/common'
|
|
10
10
|
import type { EventId, LiveStoreSchema, MutationEvent } from '@livestore/common/schema'
|
|
11
11
|
import { LS_DEV } from '@livestore/utils'
|
|
12
|
-
import type { Cause } from '@livestore/utils/effect'
|
|
12
|
+
import type { Cause, Schema } from '@livestore/utils/effect'
|
|
13
13
|
import {
|
|
14
14
|
Context,
|
|
15
15
|
Deferred,
|
|
@@ -102,6 +102,12 @@ export interface CreateStoreOptions<TSchema extends LiveStoreSchema, TContext =
|
|
|
102
102
|
* @default true
|
|
103
103
|
*/
|
|
104
104
|
confirmUnsavedChanges?: boolean
|
|
105
|
+
/**
|
|
106
|
+
* Payload that will be passed to the sync backend when connecting
|
|
107
|
+
*
|
|
108
|
+
* @default undefined
|
|
109
|
+
*/
|
|
110
|
+
syncPayload?: Schema.JsonValue
|
|
105
111
|
params?: {
|
|
106
112
|
leaderPushBatchSize?: number
|
|
107
113
|
}
|
|
@@ -155,6 +161,7 @@ export const createStore = <TSchema extends LiveStoreSchema = LiveStoreSchema, T
|
|
|
155
161
|
params,
|
|
156
162
|
debug,
|
|
157
163
|
confirmUnsavedChanges = true,
|
|
164
|
+
syncPayload,
|
|
158
165
|
}: CreateStoreOptions<TSchema, TContext>): Effect.Effect<
|
|
159
166
|
Store<TSchema, TContext>,
|
|
160
167
|
UnexpectedError,
|
|
@@ -227,6 +234,7 @@ export const createStore = <TSchema extends LiveStoreSchema = LiveStoreSchema, T
|
|
|
227
234
|
shutdown,
|
|
228
235
|
connectDevtoolsToStore: connectDevtoolsToStore_,
|
|
229
236
|
debugInstanceId,
|
|
237
|
+
syncPayload,
|
|
230
238
|
}).pipe(Effect.withPerformanceMeasure('livestore:makeAdapter'), Effect.withSpan('createStore:makeAdapter'))
|
|
231
239
|
|
|
232
240
|
if (LS_DEV && clientSession.leaderThread.initialState.migrationsReport.migrations.length > 0) {
|
package/src/store/store-types.ts
CHANGED
|
@@ -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 {
|
|
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: '
|
|
59
|
+
_tag: 'commit'
|
|
55
60
|
/** The mutations that were applied */
|
|
56
61
|
mutations: ReadonlyArray<MutationEvent.AnyDecoded | MutationEvent.PartialAnyDecoded>
|
|
57
62
|
|
package/src/store/store.ts
CHANGED
|
@@ -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
|
|
444
|
-
|
|
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('
|
|
525
|
+
mutationsSpan.addEvent('commit')
|
|
474
526
|
|
|
475
|
-
// console.group('LiveStore.
|
|
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:
|
|
534
|
+
'LiveStore:commit',
|
|
483
535
|
{
|
|
484
536
|
attributes: {
|
|
485
537
|
'livestore.mutationEventsCount': mutationsEvents.length,
|
|
486
538
|
'livestore.mutationEventTags': mutationsEvents.map((_) => _.mutation),
|
|
487
|
-
'livestore.
|
|
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: '
|
|
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
|
|
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 `
|
|
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
|