@livestore/livestore 0.3.0-dev.34 → 0.3.0-dev.37
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/base-class.d.ts +9 -9
- package/dist/live-queries/base-class.d.ts.map +1 -1
- package/dist/live-queries/base-class.js +5 -5
- package/dist/live-queries/base-class.js.map +1 -1
- package/dist/live-queries/mod.d.ts +1 -1
- package/dist/live-queries/mod.d.ts.map +1 -1
- package/dist/live-queries/mod.js +1 -1
- package/dist/live-queries/mod.js.map +1 -1
- package/dist/live-queries/signal.d.ts +20 -0
- package/dist/live-queries/signal.d.ts.map +1 -0
- package/dist/live-queries/signal.js +33 -0
- package/dist/live-queries/signal.js.map +1 -0
- package/dist/live-queries/signal.test.d.ts +2 -0
- package/dist/live-queries/signal.test.d.ts.map +1 -0
- package/dist/live-queries/signal.test.js +17 -0
- package/dist/live-queries/signal.test.js.map +1 -0
- package/dist/mod.d.ts +1 -1
- package/dist/mod.d.ts.map +1 -1
- package/dist/mod.js +1 -1
- package/dist/mod.js.map +1 -1
- package/dist/store/store.d.ts +9 -5
- package/dist/store/store.d.ts.map +1 -1
- package/dist/store/store.js +27 -23
- package/dist/store/store.js.map +1 -1
- package/package.json +5 -5
- package/src/live-queries/base-class.ts +14 -14
- package/src/live-queries/mod.ts +1 -1
- package/src/live-queries/signal.test.ts +25 -0
- package/src/live-queries/{make-ref.ts → signal.ts} +7 -9
- package/src/mod.ts +1 -1
- package/src/store/store.ts +30 -29
@@ -0,0 +1,25 @@
|
|
1
|
+
import { Effect } from '@livestore/utils/effect'
|
2
|
+
import { Vitest } from '@livestore/utils-dev/node-vitest'
|
3
|
+
import { expect } from 'vitest'
|
4
|
+
|
5
|
+
import { makeTodoMvc } from '../utils/tests/fixture.js'
|
6
|
+
import { computed } from './computed.js'
|
7
|
+
import { signal } from './signal.js'
|
8
|
+
|
9
|
+
Vitest.describe('signal', () => {
|
10
|
+
Vitest.scopedLive('should be able to create a signal', () =>
|
11
|
+
Effect.gen(function* () {
|
12
|
+
const num$ = signal(0, { label: 'num$' })
|
13
|
+
|
14
|
+
const duplicated$ = computed((get) => get(num$) * 2, { label: 'duplicated$' })
|
15
|
+
|
16
|
+
const store = yield* makeTodoMvc({})
|
17
|
+
|
18
|
+
expect(store.query(duplicated$)).toBe(0)
|
19
|
+
|
20
|
+
store.setSignal(num$, 1)
|
21
|
+
|
22
|
+
expect(store.query(duplicated$)).toBe(2)
|
23
|
+
}),
|
24
|
+
)
|
25
|
+
})
|
@@ -2,27 +2,25 @@ import { nanoid } from '@livestore/utils/nanoid'
|
|
2
2
|
|
3
3
|
import type * as RG from '../reactive.js'
|
4
4
|
import type { RefreshReason } from '../store/store-types.js'
|
5
|
-
import type {
|
5
|
+
import type { ISignal, ReactivityGraph, ReactivityGraphContext, SignalDef } from './base-class.js'
|
6
6
|
import { withRCMap } from './base-class.js'
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
export const makeRef = <T>(
|
8
|
+
export const signal = <T>(
|
11
9
|
defaultValue: T,
|
12
10
|
options?: {
|
13
11
|
label?: string
|
14
12
|
},
|
15
|
-
):
|
13
|
+
): SignalDef<T> => {
|
16
14
|
const id = nanoid()
|
17
15
|
return {
|
18
|
-
_tag: '
|
16
|
+
_tag: 'signal-def',
|
19
17
|
defaultValue,
|
20
|
-
make: withRCMap(id, (ctx) => new
|
18
|
+
make: withRCMap(id, (ctx) => new Signal(defaultValue, ctx.reactivityGraph.deref()!, options)),
|
21
19
|
}
|
22
20
|
}
|
23
21
|
|
24
|
-
export class
|
25
|
-
_tag = '
|
22
|
+
export class Signal<T> implements ISignal<T> {
|
23
|
+
_tag = 'signal' as const
|
26
24
|
readonly ref: RG.Ref<T, ReactivityGraphContext, RefreshReason>
|
27
25
|
|
28
26
|
constructor(
|
package/src/mod.ts
CHANGED
@@ -13,7 +13,7 @@ export {
|
|
13
13
|
|
14
14
|
export { SqliteDbWrapper, emptyDebugInfo } from './SqliteDbWrapper.js'
|
15
15
|
|
16
|
-
export { queryDb, computed,
|
16
|
+
export { queryDb, computed, signal, type LiveQuery, type LiveQueryDef } from './live-queries/mod.js'
|
17
17
|
|
18
18
|
export * from '@livestore/common/schema'
|
19
19
|
export {
|
package/src/store/store.ts
CHANGED
@@ -28,11 +28,11 @@ import { nanoid } from '@livestore/utils/nanoid'
|
|
28
28
|
import * as otel from '@opentelemetry/api'
|
29
29
|
|
30
30
|
import type {
|
31
|
-
ILiveQueryRefDef,
|
32
31
|
LiveQuery,
|
33
32
|
LiveQueryDef,
|
34
33
|
ReactivityGraph,
|
35
34
|
ReactivityGraphContext,
|
35
|
+
SignalDef,
|
36
36
|
} from '../live-queries/base-class.js'
|
37
37
|
import { makeReactivityGraph } from '../live-queries/base-class.js'
|
38
38
|
import { makeExecBeforeFirstRun } from '../live-queries/client-document-get-query.js'
|
@@ -108,10 +108,12 @@ export class Store<TSchema extends LiveStoreSchema = LiveStoreSchema, TContext =
|
|
108
108
|
clientSession,
|
109
109
|
runtime: effectContext.runtime,
|
110
110
|
materializeEvent: (eventDecoded, { otelContext, withChangeset }) => {
|
111
|
-
const eventDef = getEventDef(schema, eventDecoded.name)
|
111
|
+
const { eventDef, materializer } = getEventDef(schema, eventDecoded.name)
|
112
112
|
|
113
113
|
const execArgsArr = getExecArgsFromEvent({
|
114
114
|
eventDef,
|
115
|
+
materializer,
|
116
|
+
db: this.sqliteDbWrapper,
|
115
117
|
event: { decoded: eventDecoded, encoded: undefined },
|
116
118
|
})
|
117
119
|
|
@@ -203,7 +205,13 @@ export class Store<TSchema extends LiveStoreSchema = LiveStoreSchema, TContext =
|
|
203
205
|
.map((_) => [_.label!.slice('tableRef:'.length), _] as const),
|
204
206
|
)
|
205
207
|
for (const tableName of allTableNames) {
|
206
|
-
this.tableRefs[tableName] =
|
208
|
+
this.tableRefs[tableName] =
|
209
|
+
existingTableRefs.get(tableName) ??
|
210
|
+
this.reactivityGraph.makeRef(null, {
|
211
|
+
equal: () => false,
|
212
|
+
label: `tableRef:${tableName}`,
|
213
|
+
meta: { liveStoreRefType: 'table' },
|
214
|
+
})
|
207
215
|
}
|
208
216
|
|
209
217
|
this.boot = Effect.gen(this, function* () {
|
@@ -402,23 +410,18 @@ export class Store<TSchema extends LiveStoreSchema = LiveStoreSchema, TContext =
|
|
402
410
|
}
|
403
411
|
}
|
404
412
|
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
setRef = <T>(refDef: ILiveQueryRefDef<T>, value: T): void => {
|
419
|
-
const ref = refDef.make(this.reactivityGraph.context!)
|
420
|
-
ref.value.set(value)
|
421
|
-
ref.deref()
|
413
|
+
setSignal = <T>(signalDef: SignalDef<T>, value: T): void => {
|
414
|
+
const signalRef = signalDef.make(this.reactivityGraph.context!)
|
415
|
+
signalRef.value.set(value)
|
416
|
+
|
417
|
+
// The current implementation of signals i.e. the separation into `signal-def` and `signal`
|
418
|
+
// can lead to a situation where a reffed signal is immediately de-reffed when calling `store.setSignal`,
|
419
|
+
// in case there is nothing else holding a reference to the signal which leads to the set value being "lost".
|
420
|
+
// To avoid this, we don't deref the signal here if this set call is the only reference to the signal.
|
421
|
+
// Hopefully this won't lead to any issues in the future. 🤞
|
422
|
+
if (signalRef.rc > 1) {
|
423
|
+
signalRef.deref()
|
424
|
+
}
|
422
425
|
}
|
423
426
|
|
424
427
|
// #region commit
|
@@ -593,12 +596,13 @@ export class Store<TSchema extends LiveStoreSchema = LiveStoreSchema, TContext =
|
|
593
596
|
)
|
594
597
|
}
|
595
598
|
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
599
|
+
/**
|
600
|
+
* Shuts down the store and closes the client session.
|
601
|
+
*
|
602
|
+
* This is called automatically when the store was created using the React or Effect API.
|
603
|
+
*/
|
604
|
+
shutdown = (cause?: Cause.Cause<UnexpectedError>) =>
|
605
|
+
this.clientSession.shutdown(cause ?? Cause.fail(IntentionalShutdownCause.make({ reason: 'manual' })))
|
602
606
|
|
603
607
|
/**
|
604
608
|
* Helper methods useful during development
|
@@ -638,9 +642,6 @@ export class Store<TSchema extends LiveStoreSchema = LiveStoreSchema, TContext =
|
|
638
642
|
}).pipe(this.runEffectFork)
|
639
643
|
},
|
640
644
|
|
641
|
-
shutdown: (cause?: Cause.Cause<UnexpectedError>) =>
|
642
|
-
this.clientSession.shutdown(cause ?? Cause.fail(IntentionalShutdownCause.make({ reason: 'manual' }))),
|
643
|
-
|
644
645
|
version: liveStoreVersion,
|
645
646
|
}
|
646
647
|
|