@livestore/livestore 0.4.0 → 0.5.0-dev.0

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 (89) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/SqliteDbWrapper.d.ts.map +1 -1
  3. package/dist/SqliteDbWrapper.js +7 -5
  4. package/dist/SqliteDbWrapper.js.map +1 -1
  5. package/dist/SqliteDbWrapper.test.js +20 -3
  6. package/dist/SqliteDbWrapper.test.js.map +1 -1
  7. package/dist/effect/LiveStore.d.ts +15 -15
  8. package/dist/effect/LiveStore.d.ts.map +1 -1
  9. package/dist/effect/LiveStore.js +17 -17
  10. package/dist/effect/LiveStore.js.map +1 -1
  11. package/dist/effect/LiveStore.test.js +5 -6
  12. package/dist/effect/LiveStore.test.js.map +1 -1
  13. package/dist/live-queries/base-class.d.ts +19 -2
  14. package/dist/live-queries/base-class.d.ts.map +1 -1
  15. package/dist/live-queries/base-class.js +28 -2
  16. package/dist/live-queries/base-class.js.map +1 -1
  17. package/dist/live-queries/computed.d.ts.map +1 -1
  18. package/dist/live-queries/computed.js +4 -4
  19. package/dist/live-queries/computed.js.map +1 -1
  20. package/dist/live-queries/db-query.d.ts +2 -2
  21. package/dist/live-queries/db-query.d.ts.map +1 -1
  22. package/dist/live-queries/db-query.js +26 -17
  23. package/dist/live-queries/db-query.js.map +1 -1
  24. package/dist/live-queries/db-query.test.js +9 -9
  25. package/dist/live-queries/db-query.test.js.map +1 -1
  26. package/dist/live-queries/signal.d.ts.map +1 -1
  27. package/dist/live-queries/signal.js +2 -2
  28. package/dist/live-queries/signal.js.map +1 -1
  29. package/dist/live-queries/signal.test.js +2 -2
  30. package/dist/live-queries/signal.test.js.map +1 -1
  31. package/dist/reactive.d.ts +1 -1
  32. package/dist/reactive.d.ts.map +1 -1
  33. package/dist/reactive.js +20 -1
  34. package/dist/reactive.js.map +1 -1
  35. package/dist/store/StoreRegistry.d.ts +12 -12
  36. package/dist/store/StoreRegistry.d.ts.map +1 -1
  37. package/dist/store/StoreRegistry.js +24 -24
  38. package/dist/store/StoreRegistry.js.map +1 -1
  39. package/dist/store/StoreRegistry.test.js +62 -59
  40. package/dist/store/StoreRegistry.test.js.map +1 -1
  41. package/dist/store/create-store.d.ts +12 -15
  42. package/dist/store/create-store.d.ts.map +1 -1
  43. package/dist/store/create-store.js +43 -24
  44. package/dist/store/create-store.js.map +1 -1
  45. package/dist/store/devtools.d.ts +1 -2
  46. package/dist/store/devtools.d.ts.map +1 -1
  47. package/dist/store/devtools.js +3 -2
  48. package/dist/store/devtools.js.map +1 -1
  49. package/dist/store/store-eventstream.test.js +5 -5
  50. package/dist/store/store-eventstream.test.js.map +1 -1
  51. package/dist/store/store-types.d.ts +10 -28
  52. package/dist/store/store-types.d.ts.map +1 -1
  53. package/dist/store/store-types.js +2 -38
  54. package/dist/store/store-types.js.map +1 -1
  55. package/dist/store/store-types.test.js +1 -1
  56. package/dist/store/store.d.ts +2 -2
  57. package/dist/store/store.d.ts.map +1 -1
  58. package/dist/store/store.js +114 -56
  59. package/dist/store/store.js.map +1 -1
  60. package/dist/utils/dev.js +1 -1
  61. package/dist/utils/dev.js.map +1 -1
  62. package/dist/utils/stack-info.d.ts.map +1 -1
  63. package/dist/utils/stack-info.js +2 -1
  64. package/dist/utils/stack-info.js.map +1 -1
  65. package/dist/utils/tests/fixture.d.ts +26 -34
  66. package/dist/utils/tests/fixture.d.ts.map +1 -1
  67. package/package.json +14 -24
  68. package/src/SqliteDbWrapper.test.ts +25 -3
  69. package/src/SqliteDbWrapper.ts +12 -9
  70. package/src/effect/LiveStore.test.ts +16 -16
  71. package/src/effect/LiveStore.ts +79 -50
  72. package/src/live-queries/__snapshots__/db-query.test.ts.snap +273 -49
  73. package/src/live-queries/base-class.ts +38 -6
  74. package/src/live-queries/computed.ts +5 -5
  75. package/src/live-queries/db-query.test.ts +9 -9
  76. package/src/live-queries/db-query.ts +42 -30
  77. package/src/live-queries/signal.test.ts +2 -2
  78. package/src/live-queries/signal.ts +3 -3
  79. package/src/reactive.ts +45 -35
  80. package/src/store/StoreRegistry.test.ts +62 -59
  81. package/src/store/StoreRegistry.ts +49 -38
  82. package/src/store/create-store.ts +85 -51
  83. package/src/store/devtools.ts +283 -283
  84. package/src/store/store-eventstream.test.ts +16 -7
  85. package/src/store/store-types.test.ts +1 -1
  86. package/src/store/store-types.ts +10 -56
  87. package/src/store/store.ts +148 -71
  88. package/src/utils/dev.ts +1 -1
  89. package/src/utils/stack-info.ts +4 -1
@@ -1,15 +1,29 @@
1
1
  import type { UnknownError } from '@livestore/common'
2
2
  import type { LiveStoreEvent, LiveStoreSchema } from '@livestore/common/schema'
3
3
  import { omitUndefineds } from '@livestore/utils'
4
- import type { Cause, OtelTracer, Scope } from '@livestore/utils/effect'
5
- import { Context, Deferred, Duration, Effect, Layer, pipe } from '@livestore/utils/effect'
4
+ import type { Schema } from '@livestore/utils/effect'
5
+ import {
6
+ type Cause,
7
+ type OtelTracer,
8
+ type Scope,
9
+ Context,
10
+ Deferred,
11
+ Duration,
12
+ Effect,
13
+ Layer,
14
+ pipe,
15
+ } from '@livestore/utils/effect'
6
16
 
7
17
  import type { LiveStoreContextProps } from '../store/create-store.ts'
8
18
  import { createStore, DeferredStoreContext, LiveStoreContextRunning } from '../store/create-store.ts'
9
19
  import type { LiveStoreContextRunning as LiveStoreContextRunningType, Queryable } from '../store/store-types.ts'
10
20
  import type { Store as StoreClass } from '../store/store.ts'
11
21
 
12
- export const makeLiveStoreContext = <TSchema extends LiveStoreSchema, TContext = {}>({
22
+ export const makeLiveStoreContext = <
23
+ TSchema extends LiveStoreSchema,
24
+ TContext = {},
25
+ TSyncPayloadSchema extends Schema.Codec<Schema.Json, Schema.Json> = typeof Schema.Json,
26
+ >({
13
27
  schema,
14
28
  storeId = 'default',
15
29
  context,
@@ -20,9 +34,9 @@ export const makeLiveStoreContext = <TSchema extends LiveStoreSchema, TContext =
20
34
  batchUpdates,
21
35
  syncPayload,
22
36
  syncPayloadSchema,
23
- }: LiveStoreContextProps<TSchema, TContext>): Effect.Effect<
24
- LiveStoreContextRunning['Type'],
25
- UnknownError | Cause.TimeoutException,
37
+ }: LiveStoreContextProps<TSchema, TContext, TSyncPayloadSchema>): Effect.Effect<
38
+ LiveStoreContextRunning['Service'],
39
+ UnknownError | Cause.TimeoutError,
26
40
  DeferredStoreContext | Scope.Scope | OtelTracer.OtelTracer
27
41
  > =>
28
42
  pipe(
@@ -35,9 +49,9 @@ export const makeLiveStoreContext = <TSchema extends LiveStoreSchema, TContext =
35
49
  ...omitUndefineds({ context, boot, disableDevtools, onBootStatus, syncPayload, syncPayloadSchema }),
36
50
  })
37
51
 
38
- return { stage: 'running', store } as any as LiveStoreContextRunning['Type']
52
+ return LiveStoreContextRunning.of({ stage: 'running', store } as any as LiveStoreContextRunning['Service'])
39
53
  }),
40
- Effect.tapErrorCause((cause) => Effect.flatMap(DeferredStoreContext, (def) => Deferred.failCause(def, cause))),
54
+ Effect.tapCause((cause) => Effect.flatMap(DeferredStoreContext, (def) => Deferred.failCause(def, cause))),
41
55
  Effect.tap((storeCtx) => Effect.flatMap(DeferredStoreContext, (def) => Deferred.succeed(def, storeCtx))),
42
56
  // This can take quite a while.
43
57
  // TODO make this configurable
@@ -58,10 +72,14 @@ export const makeLiveStoreContext = <TSchema extends LiveStoreSchema, TContext =
58
72
  * const layer = MainStore.layer({ adapter, ... })
59
73
  * ```
60
74
  */
61
- export const LiveStoreContextLayer = <TSchema extends LiveStoreSchema, TContext = {}>(
62
- props: LiveStoreContextProps<TSchema, TContext>,
63
- ): Layer.Layer<LiveStoreContextRunning, UnknownError | Cause.TimeoutException, OtelTracer.OtelTracer> =>
64
- Layer.scoped(LiveStoreContextRunning, makeLiveStoreContext(props)).pipe(
75
+ export const LiveStoreContextLayer = <
76
+ TSchema extends LiveStoreSchema,
77
+ TContext = {},
78
+ TSyncPayloadSchema extends Schema.Codec<Schema.Json, Schema.Json> = typeof Schema.Json,
79
+ >(
80
+ props: LiveStoreContextProps<TSchema, TContext, TSyncPayloadSchema>,
81
+ ): Layer.Layer<LiveStoreContextRunning, UnknownError | Cause.TimeoutError, OtelTracer.OtelTracer> =>
82
+ Layer.effect(LiveStoreContextRunning, makeLiveStoreContext(props)).pipe(
65
83
  Layer.withSpan('LiveStore'),
66
84
  Layer.provide(LiveStoreContextDeferred),
67
85
  )
@@ -71,7 +89,7 @@ export const LiveStoreContextLayer = <TSchema extends LiveStoreSchema, TContext
71
89
  */
72
90
  export const LiveStoreContextDeferred = Layer.effect(
73
91
  DeferredStoreContext,
74
- Deferred.make<LiveStoreContextRunning['Type'], UnknownError>(),
92
+ Deferred.make<LiveStoreContextRunning['Service'], UnknownError>(),
75
93
  )
76
94
 
77
95
  // =============================================================================
@@ -99,10 +117,11 @@ export interface DeferredContextId<TStoreId extends string> {
99
117
  }
100
118
 
101
119
  /** Props for creating a store layer (schema and storeId are already provided) */
102
- export type StoreLayerProps<TSchema extends LiveStoreSchema, TContext = {}> = Omit<
103
- LiveStoreContextProps<TSchema, TContext>,
104
- 'storeId' | 'schema'
105
- >
120
+ export type StoreLayerProps<
121
+ TSchema extends LiveStoreSchema,
122
+ TContext = {},
123
+ TSyncPayloadSchema extends Schema.Codec<Schema.Json, Schema.Json> = typeof Schema.Json,
124
+ > = Omit<LiveStoreContextProps<TSchema, TContext, TSyncPayloadSchema>, 'storeId' | 'schema'>
106
125
 
107
126
  /**
108
127
  * Type for a Store.Tag class. This is the return type of `Store.Tag(schema, storeId)`.
@@ -117,16 +136,18 @@ export type StoreLayerProps<TSchema extends LiveStoreSchema, TContext = {}> = Om
117
136
  * Uses `interface` (not `type`) to allow the self-referential identifier without
118
137
  * triggering TS2456 (circular type alias).
119
138
  */
120
- export interface StoreTagClass<TSchema extends LiveStoreSchema, TStoreId extends string>
121
- extends Context.Tag<StoreTagClass<TSchema, TStoreId>, LiveStoreContextRunningType<TSchema>> {
139
+ export interface StoreTagClass<TSchema extends LiveStoreSchema, TStoreId extends string> extends Context.Key<
140
+ StoreTagClass<TSchema, TStoreId>,
141
+ LiveStoreContextRunningType<TSchema>
142
+ > {
122
143
  /** Constructor signature (makes the type extendable as a class) */
123
- new (): Context.Tag<StoreTagClass<TSchema, TStoreId>, LiveStoreContextRunningType<TSchema>>
144
+ new (): Context.Key<StoreTagClass<TSchema, TStoreId>, LiveStoreContextRunningType<TSchema>>
124
145
 
125
- /** Tag identity type (from Context.Tag) */
146
+ /** Key identity type (from Context.Key) */
126
147
  readonly Id: StoreTagClass<TSchema, TStoreId>
127
148
 
128
- /** Service type (from Context.Tag) */
129
- readonly Type: LiveStoreContextRunningType<TSchema>
149
+ /** Service type (from Context.Key) */
150
+ readonly Service: LiveStoreContextRunningType<TSchema>
130
151
 
131
152
  /** The LiveStore schema for this store */
132
153
  readonly schema: TSchema
@@ -135,12 +156,12 @@ export interface StoreTagClass<TSchema extends LiveStoreSchema, TStoreId extends
135
156
  readonly storeId: TStoreId
136
157
 
137
158
  /** Creates a layer that initializes the store */
138
- layer<TContext>(
139
- props: StoreLayerProps<TSchema, TContext>,
140
- ): Layer.Layer<StoreTagClass<TSchema, TStoreId>, UnknownError | Cause.TimeoutException, OtelTracer.OtelTracer>
159
+ layer<TContext, TSyncPayloadSchema extends Schema.Codec<Schema.Json, Schema.Json> = typeof Schema.Json>(
160
+ props: StoreLayerProps<TSchema, TContext, TSyncPayloadSchema>,
161
+ ): Layer.Layer<StoreTagClass<TSchema, TStoreId>, UnknownError | Cause.TimeoutError, OtelTracer.OtelTracer>
141
162
 
142
163
  /** Deferred store tag for async initialization patterns */
143
- readonly Deferred: Context.Tag<
164
+ readonly Deferred: Context.Key<
144
165
  DeferredContextId<TStoreId>,
145
166
  Deferred.Deferred<LiveStoreContextRunningType<TSchema>, UnknownError>
146
167
  >
@@ -168,7 +189,7 @@ export interface StoreTagClass<TSchema extends LiveStoreSchema, TStoreId extends
168
189
  /**
169
190
  * Create a typed store context class for use with Effect.
170
191
  *
171
- * Returns a class that extends `Context.Tag`, making it directly yieldable in Effect code.
192
+ * Returns a class that extends `Context.Service`, making it directly yieldable in Effect code.
172
193
  * The class includes static methods for creating layers and accessors for common operations.
173
194
  *
174
195
  * @param schema - The LiveStore schema (used for type inference and runtime)
@@ -224,17 +245,19 @@ const makeStoreTag = <TSchema extends LiveStoreSchema, TStoreId extends string>(
224
245
  type DeferredType = Deferred.Deferred<RunningType, UnknownError>
225
246
 
226
247
  // Create the deferred tag and layers upfront
227
- const _DeferredTag = Context.GenericTag<DeferredContextId<TStoreId>, DeferredType>(
248
+ const _DeferredTag = Context.Service<DeferredContextId<TStoreId>, DeferredType>(
228
249
  `@livestore/store-deferred/${storeId}`,
229
250
  )
230
251
 
231
252
  const _DeferredLayer = Layer.effect(_DeferredTag, Deferred.make<RunningType, UnknownError>())
232
253
 
233
- class Tag extends Context.Tag(`@livestore/store/${storeId}`)<Tag, RunningType>() {
254
+ class Tag extends Context.Service<Tag, RunningType>()(`@livestore/store/${storeId}`) {
234
255
  static readonly schema: TSchema = schema
235
256
  static readonly storeId: TStoreId = storeId
236
257
 
237
- static layer<TContext = {}>(props: StoreLayerProps<TSchema, TContext>) {
258
+ static layer<TContext = {}, TSyncPayloadSchema extends Schema.Codec<Schema.Json, Schema.Json> = typeof Schema.Json>(
259
+ props: StoreLayerProps<TSchema, TContext, TSyncPayloadSchema>,
260
+ ) {
238
261
  return pipe(
239
262
  Effect.gen(function* () {
240
263
  const store = yield* createStore({
@@ -259,11 +282,11 @@ const makeStoreTag = <TSchema extends LiveStoreSchema, TStoreId extends string>(
259
282
  optDeferred._tag === 'Some' ? Deferred.succeed(optDeferred.value, ctx) : Effect.void,
260
283
  )
261
284
 
262
- return ctx
285
+ return Tag.of(ctx)
263
286
  }),
264
287
  Effect.timeout(Duration.minutes(5)),
265
288
  Effect.withSpan(`@livestore/effect:Store.Tag:${storeId}`),
266
- Layer.scoped(Tag),
289
+ Layer.effect(Tag),
267
290
  Layer.withSpan(`LiveStore:${storeId}`),
268
291
  Layer.provide(_DeferredLayer),
269
292
  )
@@ -275,10 +298,10 @@ const makeStoreTag = <TSchema extends LiveStoreSchema, TStoreId extends string>(
275
298
  static readonly fromDeferred = pipe(
276
299
  Effect.gen(function* () {
277
300
  const deferred = yield* _DeferredTag
278
- const ctx = yield* deferred
279
- return Layer.succeed(Tag, ctx)
301
+ const ctx = yield* Deferred.await(deferred)
302
+ return Layer.succeed(Tag, Tag.of(ctx))
280
303
  }),
281
- Layer.unwrapScoped,
304
+ Layer.unwrap,
282
305
  )
283
306
 
284
307
  static query<TResult>(query: Queryable<TResult>) {
@@ -291,7 +314,7 @@ const makeStoreTag = <TSchema extends LiveStoreSchema, TStoreId extends string>(
291
314
  })
292
315
  }
293
316
 
294
- static use<A, E, R>(f: (ctx: RunningType) => Effect.Effect<A, E, R>) {
317
+ static override use<A, E, R>(f: (ctx: RunningType) => Effect.Effect<A, E, R>) {
295
318
  return Effect.flatMap(Tag, f)
296
319
  }
297
320
  }
@@ -338,14 +361,17 @@ export const Store = {
338
361
  */
339
362
  export interface StoreContext<TSchema extends LiveStoreSchema, TStoreId extends string> {
340
363
  readonly storeId: TStoreId
341
- readonly Tag: Context.Tag<StoreContextId<TSchema, TStoreId>, LiveStoreContextRunningType<TSchema>>
342
- readonly DeferredTag: Context.Tag<
364
+ readonly Tag: Context.Key<StoreContextId<TSchema, TStoreId>, LiveStoreContextRunningType<TSchema>>
365
+ readonly DeferredTag: Context.Key<
343
366
  DeferredContextId<TStoreId>,
344
367
  Deferred.Deferred<LiveStoreContextRunningType<TSchema>, UnknownError>
345
368
  >
346
- readonly Layer: <TContext = {}>(
347
- props: Omit<LiveStoreContextProps<TSchema, TContext>, 'storeId'>,
348
- ) => Layer.Layer<StoreContextId<TSchema, TStoreId>, UnknownError | Cause.TimeoutException, OtelTracer.OtelTracer>
369
+ readonly Layer: <
370
+ TContext = {},
371
+ TSyncPayloadSchema extends Schema.Codec<Schema.Json, Schema.Json> = typeof Schema.Json,
372
+ >(
373
+ props: Omit<LiveStoreContextProps<TSchema, TContext, TSyncPayloadSchema>, 'storeId'>,
374
+ ) => Layer.Layer<StoreContextId<TSchema, TStoreId>, UnknownError | Cause.TimeoutError, OtelTracer.OtelTracer>
349
375
  readonly DeferredLayer: Layer.Layer<DeferredContextId<TStoreId>>
350
376
  readonly fromDeferred: Layer.Layer<StoreContextId<TSchema, TStoreId>, UnknownError, DeferredContextId<TStoreId>>
351
377
  }
@@ -368,17 +394,20 @@ export const makeStoreContext =
368
394
  type RunningType = LiveStoreContextRunningType<TSchema>
369
395
  type DeferredType = Deferred.Deferred<RunningType, UnknownError>
370
396
 
371
- const Tag = Context.GenericTag<StoreContextId<TSchema, TStoreId>, RunningType>(`@livestore/store/${storeId}`)
397
+ const Tag = Context.Service<StoreContextId<TSchema, TStoreId>, RunningType>(`@livestore/store/${storeId}`)
372
398
 
373
- const DeferredTag = Context.GenericTag<DeferredContextId<TStoreId>, DeferredType>(
399
+ const DeferredTag = Context.Service<DeferredContextId<TStoreId>, DeferredType>(
374
400
  `@livestore/store-deferred/${storeId}`,
375
401
  )
376
402
 
377
403
  const DeferredLayer = Layer.effect(DeferredTag, Deferred.make<RunningType, UnknownError>())
378
404
 
379
- const makeLayer = <TContext = {}>(
380
- props: Omit<LiveStoreContextProps<TSchema, TContext>, 'storeId'>,
381
- ): Layer.Layer<StoreContextId<TSchema, TStoreId>, UnknownError | Cause.TimeoutException, OtelTracer.OtelTracer> =>
405
+ const makeLayer = <
406
+ TContext = {},
407
+ TSyncPayloadSchema extends Schema.Codec<Schema.Json, Schema.Json> = typeof Schema.Json,
408
+ >(
409
+ props: Omit<LiveStoreContextProps<TSchema, TContext, TSyncPayloadSchema>, 'storeId'>,
410
+ ): Layer.Layer<StoreContextId<TSchema, TStoreId>, UnknownError | Cause.TimeoutError, OtelTracer.OtelTracer> =>
382
411
  pipe(
383
412
  Effect.gen(function* () {
384
413
  const store = yield* createStore({
@@ -407,7 +436,7 @@ export const makeStoreContext =
407
436
  }),
408
437
  Effect.timeout(Duration.minutes(5)),
409
438
  Effect.withSpan(`@livestore/effect:makeStoreContext:${storeId}`),
410
- Layer.scoped(Tag),
439
+ Layer.effect(Tag),
411
440
  Layer.withSpan(`LiveStore:${storeId}`),
412
441
  Layer.provide(DeferredLayer),
413
442
  )
@@ -419,10 +448,10 @@ export const makeStoreContext =
419
448
  > = pipe(
420
449
  Effect.gen(function* () {
421
450
  const deferred = yield* DeferredTag
422
- const ctx = yield* deferred
451
+ const ctx = yield* Deferred.await(deferred)
423
452
  return Layer.succeed(Tag, ctx)
424
453
  }),
425
- Layer.unwrapScoped,
454
+ Layer.unwrap,
426
455
  )
427
456
 
428
457
  return {