@livestore/livestore 0.0.54-dev.2 → 0.0.54-dev.21
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/MainDatabaseWrapper.d.ts +6 -5
- package/dist/MainDatabaseWrapper.d.ts.map +1 -1
- package/dist/MainDatabaseWrapper.js +3 -3
- package/dist/MainDatabaseWrapper.js.map +1 -1
- package/dist/QueryCache.d.ts +1 -1
- package/dist/QueryCache.d.ts.map +1 -1
- package/dist/QueryCache.js.map +1 -1
- package/dist/__tests__/react/fixture.d.ts +3 -3
- package/dist/__tests__/react/fixture.d.ts.map +1 -1
- package/dist/__tests__/react/fixture.js +10 -8
- package/dist/__tests__/react/fixture.js.map +1 -1
- package/dist/effect/LiveStore.d.ts +2 -3
- package/dist/effect/LiveStore.d.ts.map +1 -1
- package/dist/effect/LiveStore.js +4 -2
- package/dist/effect/LiveStore.js.map +1 -1
- package/dist/global-state.d.ts +1 -1
- package/dist/global-state.d.ts.map +1 -1
- package/dist/global-state.js +2 -2
- package/dist/global-state.js.map +1 -1
- package/dist/index.d.ts +3 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -4
- package/dist/index.js.map +1 -1
- package/dist/react/LiveStoreProvider.d.ts +3 -4
- package/dist/react/LiveStoreProvider.d.ts.map +1 -1
- package/dist/react/LiveStoreProvider.js +8 -13
- package/dist/react/LiveStoreProvider.js.map +1 -1
- package/dist/react/useRow.d.ts +2 -2
- package/dist/react/useRow.d.ts.map +1 -1
- package/dist/react/useRow.js +3 -3
- package/dist/react/useRow.js.map +1 -1
- package/dist/react/useRow.test.js +21 -21
- package/dist/react/useRow.test.js.map +1 -1
- package/dist/react/useTemporaryQuery.js +1 -1
- package/dist/react/useTemporaryQuery.js.map +1 -1
- package/dist/reactiveQueries/base-class.d.ts +6 -6
- package/dist/reactiveQueries/base-class.d.ts.map +1 -1
- package/dist/reactiveQueries/base-class.js +3 -3
- package/dist/reactiveQueries/base-class.js.map +1 -1
- package/dist/reactiveQueries/graphql.d.ts +8 -8
- package/dist/reactiveQueries/graphql.d.ts.map +1 -1
- package/dist/reactiveQueries/graphql.js +10 -10
- package/dist/reactiveQueries/graphql.js.map +1 -1
- package/dist/reactiveQueries/js.d.ts +6 -6
- package/dist/reactiveQueries/js.d.ts.map +1 -1
- package/dist/reactiveQueries/js.js +8 -8
- package/dist/reactiveQueries/js.js.map +1 -1
- package/dist/reactiveQueries/sql.d.ts +9 -10
- package/dist/reactiveQueries/sql.d.ts.map +1 -1
- package/dist/reactiveQueries/sql.js +12 -12
- package/dist/reactiveQueries/sql.js.map +1 -1
- package/dist/row-query.d.ts +2 -2
- package/dist/row-query.d.ts.map +1 -1
- package/dist/row-query.js +2 -2
- package/dist/row-query.js.map +1 -1
- package/dist/store.d.ts +18 -18
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +48 -53
- package/dist/store.js.map +1 -1
- package/package.json +5 -12
- package/src/MainDatabaseWrapper.ts +14 -8
- package/src/QueryCache.ts +1 -2
- package/src/__tests__/react/fixture.tsx +11 -9
- package/src/effect/LiveStore.ts +6 -5
- package/src/global-state.ts +2 -2
- package/src/index.ts +17 -4
- package/src/react/LiveStoreProvider.tsx +10 -18
- package/src/react/useRow.test.tsx +21 -21
- package/src/react/useRow.ts +5 -5
- package/src/react/useTemporaryQuery.ts +2 -2
- package/src/reactiveQueries/base-class.ts +9 -9
- package/src/reactiveQueries/graphql.ts +19 -15
- package/src/reactiveQueries/js.ts +12 -12
- package/src/reactiveQueries/sql.ts +19 -21
- package/src/row-query.ts +6 -6
- package/src/store.ts +85 -74
- package/dist/utils/bounded-collections.d.ts +0 -34
- package/dist/utils/bounded-collections.d.ts.map +0 -1
- package/dist/utils/bounded-collections.js +0 -91
- package/dist/utils/bounded-collections.js.map +0 -1
- package/dist/utils/util.d.ts +0 -14
- package/dist/utils/util.d.ts.map +0 -1
- package/dist/utils/util.js +0 -19
- package/dist/utils/util.js.map +0 -1
- package/src/utils/util.ts +0 -31
package/src/store.ts
CHANGED
|
@@ -1,22 +1,27 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
1
|
+
import type {
|
|
2
|
+
BootDb,
|
|
3
|
+
ParamsObject,
|
|
4
|
+
PreparedBindValues,
|
|
5
|
+
ResetMode,
|
|
6
|
+
StoreAdapter,
|
|
7
|
+
StoreAdapterFactory,
|
|
8
|
+
} from '@livestore/common'
|
|
9
|
+
import { Devtools, getExecArgsFromMutation, prepareBindValues } from '@livestore/common'
|
|
3
10
|
import { version as liveStoreVersion } from '@livestore/common/package.json'
|
|
4
|
-
import type { LiveStoreSchema, MutationEvent
|
|
5
|
-
import {
|
|
6
|
-
import { assertNever, isPromise, makeNoopTracer,
|
|
11
|
+
import type { LiveStoreSchema, MutationEvent } from '@livestore/common/schema'
|
|
12
|
+
import { makeMutationEventSchemaMemo } from '@livestore/common/schema'
|
|
13
|
+
import { assertNever, isPromise, makeNoopTracer, shouldNeverHappen } from '@livestore/utils'
|
|
7
14
|
import { Effect, Schema, Stream } from '@livestore/utils/effect'
|
|
8
15
|
import * as otel from '@opentelemetry/api'
|
|
9
16
|
import type { GraphQLSchema } from 'graphql'
|
|
10
17
|
|
|
11
|
-
import {
|
|
18
|
+
import { globalReactivityGraph } from './global-state.js'
|
|
12
19
|
import { MainDatabaseWrapper } from './MainDatabaseWrapper.js'
|
|
13
20
|
import type { StackInfo } from './react/utils/stack-info.js'
|
|
14
|
-
import type { DebugRefreshReasonBase,
|
|
15
|
-
import type {
|
|
21
|
+
import type { DebugRefreshReasonBase, Ref } from './reactive.js'
|
|
22
|
+
import type { LiveQuery, QueryContext, ReactivityGraph } from './reactiveQueries/base-class.js'
|
|
16
23
|
import { downloadBlob } from './utils/dev.js'
|
|
17
24
|
import { getDurationMsFromSpan } from './utils/otel.js'
|
|
18
|
-
import type { ParamsObject } from './utils/util.js'
|
|
19
|
-
import { prepareBindValues } from './utils/util.js'
|
|
20
25
|
|
|
21
26
|
export type BaseGraphQLContext = {
|
|
22
27
|
queriedTables: Set<string>
|
|
@@ -29,17 +34,21 @@ export type GraphQLOptions<TContext> = {
|
|
|
29
34
|
makeContext: (db: MainDatabaseWrapper, tracer: otel.Tracer) => TContext
|
|
30
35
|
}
|
|
31
36
|
|
|
37
|
+
export type OtelOptions = {
|
|
38
|
+
tracer: otel.Tracer
|
|
39
|
+
rootSpanContext: otel.Context
|
|
40
|
+
}
|
|
41
|
+
|
|
32
42
|
export type StoreOptions<
|
|
33
43
|
TGraphQLContext extends BaseGraphQLContext,
|
|
34
44
|
TSchema extends LiveStoreSchema = LiveStoreSchema,
|
|
35
45
|
> = {
|
|
36
46
|
adapter: StoreAdapter
|
|
37
47
|
schema: TSchema
|
|
48
|
+
// TODO remove graphql-related stuff from store and move to GraphQL query directly
|
|
38
49
|
graphQLOptions?: GraphQLOptions<TGraphQLContext>
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
dbGraph: DbGraph
|
|
42
|
-
mutationEventSchema: MutationEventSchema<any>
|
|
50
|
+
otelOptions: OtelOptions
|
|
51
|
+
reactivityGraph: ReactivityGraph
|
|
43
52
|
disableDevtools?: boolean
|
|
44
53
|
}
|
|
45
54
|
|
|
@@ -95,11 +104,8 @@ export class Store<
|
|
|
95
104
|
TSchema extends LiveStoreSchema = LiveStoreSchema,
|
|
96
105
|
> {
|
|
97
106
|
id = uniqueStoreId()
|
|
98
|
-
|
|
107
|
+
reactivityGraph: ReactivityGraph
|
|
99
108
|
mainDbWrapper: MainDatabaseWrapper
|
|
100
|
-
// TODO refactor
|
|
101
|
-
// _proxyDb: InMemoryDatabase
|
|
102
|
-
// TODO
|
|
103
109
|
adapter: StoreAdapter
|
|
104
110
|
schema: LiveStoreSchema
|
|
105
111
|
graphQLSchema?: GraphQLSchema
|
|
@@ -109,7 +115,7 @@ export class Store<
|
|
|
109
115
|
* Note we're using `Ref<null>` here as we don't care about the value but only about *that* something has changed.
|
|
110
116
|
* This only works in combination with `equal: () => false` which will always trigger a refresh.
|
|
111
117
|
*/
|
|
112
|
-
tableRefs: { [key: string]: Ref<null,
|
|
118
|
+
tableRefs: { [key: string]: Ref<null, QueryContext, RefreshReason> }
|
|
113
119
|
|
|
114
120
|
// TODO remove this temporary solution and find a better way to avoid re-processing the same mutation
|
|
115
121
|
__processedMutationIds = new Set<string>()
|
|
@@ -124,32 +130,33 @@ export class Store<
|
|
|
124
130
|
adapter,
|
|
125
131
|
schema,
|
|
126
132
|
graphQLOptions,
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
otelRootSpanContext,
|
|
130
|
-
mutationEventSchema,
|
|
133
|
+
reactivityGraph,
|
|
134
|
+
otelOptions,
|
|
131
135
|
disableDevtools,
|
|
132
136
|
}: StoreOptions<TGraphQLContext, TSchema>) {
|
|
133
|
-
this.mainDbWrapper = new MainDatabaseWrapper({
|
|
137
|
+
this.mainDbWrapper = new MainDatabaseWrapper({ otel: otelOptions, db: adapter.mainDb })
|
|
134
138
|
this.adapter = adapter
|
|
135
139
|
this.schema = schema
|
|
136
140
|
|
|
137
141
|
// TODO refactor
|
|
138
|
-
this.__mutationEventSchema =
|
|
139
|
-
// this.mutationEventSchema = makeMutationEventSchema(Object.fromEntries(schema.mutations.entries()) as any)
|
|
142
|
+
this.__mutationEventSchema = makeMutationEventSchemaMemo(schema)
|
|
140
143
|
|
|
141
144
|
// TODO generalize the `tableRefs` concept to allow finer-grained refs
|
|
142
145
|
this.tableRefs = {}
|
|
143
146
|
this.activeQueries = new ReferenceCountedSet()
|
|
144
147
|
|
|
145
|
-
const mutationsSpan =
|
|
148
|
+
const mutationsSpan = otelOptions.tracer.startSpan('LiveStore:mutations', {}, otelOptions.rootSpanContext)
|
|
146
149
|
const otelMuationsSpanContext = otel.trace.setSpan(otel.context.active(), mutationsSpan)
|
|
147
150
|
|
|
148
|
-
const queriesSpan =
|
|
151
|
+
const queriesSpan = otelOptions.tracer.startSpan('LiveStore:queries', {}, otelOptions.rootSpanContext)
|
|
149
152
|
const otelQueriesSpanContext = otel.trace.setSpan(otel.context.active(), queriesSpan)
|
|
150
153
|
|
|
151
|
-
this.
|
|
152
|
-
this.
|
|
154
|
+
this.reactivityGraph = reactivityGraph
|
|
155
|
+
this.reactivityGraph.context = {
|
|
156
|
+
store: this as any,
|
|
157
|
+
otelTracer: otelOptions.tracer,
|
|
158
|
+
rootOtelContext: otelQueriesSpanContext,
|
|
159
|
+
}
|
|
153
160
|
|
|
154
161
|
this.adapter.coordinator.syncMutations.pipe(
|
|
155
162
|
Stream.tapSync((mutationEventDecoded) => {
|
|
@@ -165,7 +172,7 @@ export class Store<
|
|
|
165
172
|
}
|
|
166
173
|
|
|
167
174
|
this.otel = {
|
|
168
|
-
tracer:
|
|
175
|
+
tracer: otelOptions.tracer,
|
|
169
176
|
mutationsSpanContext: otelMuationsSpanContext,
|
|
170
177
|
queriesSpanContext: otelQueriesSpanContext,
|
|
171
178
|
}
|
|
@@ -177,7 +184,7 @@ export class Store<
|
|
|
177
184
|
// ...Array.from(dynamicallyRegisteredTables.values()).map((_) => _.sqliteDef.name),
|
|
178
185
|
)
|
|
179
186
|
const existingTableRefs = new Map(
|
|
180
|
-
Array.from(this.
|
|
187
|
+
Array.from(this.reactivityGraph.atoms.values())
|
|
181
188
|
.filter((_): _ is Ref<any, any, any> => _._tag === 'ref' && _.label?.startsWith('tableRef:') === true)
|
|
182
189
|
.map((_) => [_.label!.slice('tableRef:'.length), _] as const),
|
|
183
190
|
)
|
|
@@ -196,7 +203,7 @@ export class Store<
|
|
|
196
203
|
parentSpan: otel.Span,
|
|
197
204
|
): Store<TGraphQLContext, TSchema> => {
|
|
198
205
|
const ctx = otel.trace.setSpan(otel.context.active(), parentSpan)
|
|
199
|
-
return storeOptions.
|
|
206
|
+
return storeOptions.otelOptions.tracer.startActiveSpan('LiveStore:store-constructor', {}, ctx, (span) => {
|
|
200
207
|
try {
|
|
201
208
|
return new Store(storeOptions)
|
|
202
209
|
} finally {
|
|
@@ -224,7 +231,7 @@ export class Store<
|
|
|
224
231
|
const otelContext = otel.trace.setSpan(otel.context.active(), span)
|
|
225
232
|
|
|
226
233
|
const label = `subscribe:${options?.label}`
|
|
227
|
-
const effect = this.
|
|
234
|
+
const effect = this.reactivityGraph.makeEffect((get) => onNewValue(get(query$.results$)), { label })
|
|
228
235
|
|
|
229
236
|
this.activeQueries.add(query$ as LiveQuery<TResult>)
|
|
230
237
|
|
|
@@ -236,7 +243,7 @@ export class Store<
|
|
|
236
243
|
const unsubscribe = () => {
|
|
237
244
|
// console.log('store unsub', query$.label)
|
|
238
245
|
try {
|
|
239
|
-
this.
|
|
246
|
+
this.reactivityGraph.destroyNode(effect)
|
|
240
247
|
this.activeQueries.remove(query$ as LiveQuery<TResult>)
|
|
241
248
|
onUnsubsubscribe?.()
|
|
242
249
|
} finally {
|
|
@@ -256,7 +263,7 @@ export class Store<
|
|
|
256
263
|
destroy = async () => {
|
|
257
264
|
for (const tableRef of Object.values(this.tableRefs)) {
|
|
258
265
|
for (const superComp of tableRef.super) {
|
|
259
|
-
this.
|
|
266
|
+
this.reactivityGraph.removeEdge(superComp, tableRef)
|
|
260
267
|
}
|
|
261
268
|
}
|
|
262
269
|
|
|
@@ -374,7 +381,7 @@ export class Store<
|
|
|
374
381
|
},
|
|
375
382
|
)
|
|
376
383
|
|
|
377
|
-
const tablesToUpdate = [] as [Ref<null,
|
|
384
|
+
const tablesToUpdate = [] as [Ref<null, QueryContext, RefreshReason>, null][]
|
|
378
385
|
for (const tableName of writeTables) {
|
|
379
386
|
const tableRef = this.tableRefs[tableName]
|
|
380
387
|
assertNever(tableRef !== undefined, `No table ref found for ${tableName}`)
|
|
@@ -388,7 +395,7 @@ export class Store<
|
|
|
388
395
|
}
|
|
389
396
|
|
|
390
397
|
// Update all table refs together in a batch, to only trigger one reactive update
|
|
391
|
-
this.
|
|
398
|
+
this.reactivityGraph.setRefs(tablesToUpdate, { debugRefreshReason, otelContext, skipRefresh })
|
|
392
399
|
} catch (e: any) {
|
|
393
400
|
span.setStatus({ code: otel.SpanStatusCode.ERROR, message: e.toString() })
|
|
394
401
|
} finally {
|
|
@@ -412,7 +419,7 @@ export class Store<
|
|
|
412
419
|
this.otel.mutationsSpanContext,
|
|
413
420
|
(span) => {
|
|
414
421
|
const otelContext = otel.trace.setSpan(otel.context.active(), span)
|
|
415
|
-
this.
|
|
422
|
+
this.reactivityGraph.runDeferredEffects({ otelContext })
|
|
416
423
|
span.end()
|
|
417
424
|
},
|
|
418
425
|
)
|
|
@@ -480,7 +487,7 @@ export class Store<
|
|
|
480
487
|
|
|
481
488
|
if (coordinatorMode !== 'skip-coordinator') {
|
|
482
489
|
// Asynchronously apply mutation to a persistent storage (we're not awaiting this promise here)
|
|
483
|
-
void this.adapter.coordinator.mutate(mutationEventEncoded, {
|
|
490
|
+
void this.adapter.coordinator.mutate(mutationEventEncoded as MutationEvent.AnyEncoded, {
|
|
484
491
|
span,
|
|
485
492
|
persisted: coordinatorMode !== 'skip-persist',
|
|
486
493
|
})
|
|
@@ -518,7 +525,7 @@ export class Store<
|
|
|
518
525
|
}
|
|
519
526
|
|
|
520
527
|
makeTableRef = (tableName: string) =>
|
|
521
|
-
this.
|
|
528
|
+
this.reactivityGraph.makeRef(null, {
|
|
522
529
|
equal: () => false,
|
|
523
530
|
label: `tableRef:${tableName}`,
|
|
524
531
|
meta: { liveStoreRefType: 'table' },
|
|
@@ -527,14 +534,16 @@ export class Store<
|
|
|
527
534
|
private bootDevtools = () => {
|
|
528
535
|
const devtoolsChannel = Devtools.makeBroadcastChannels()
|
|
529
536
|
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
537
|
+
type Unsub = () => void
|
|
538
|
+
type RequestId = string
|
|
539
|
+
|
|
540
|
+
const reactivityGraphSubcriptions = new Map<RequestId, Unsub>()
|
|
541
|
+
const liveQueriesSubscriptions = new Map<RequestId, Unsub>()
|
|
533
542
|
devtoolsChannel.toAppHost.addEventListener('message', async (event) => {
|
|
534
543
|
const decoded = Schema.decodeUnknownOption(Devtools.MessageToAppHost)(event.data)
|
|
535
544
|
if (
|
|
536
545
|
decoded._tag === 'None' ||
|
|
537
|
-
decoded.value._tag === 'LSD.
|
|
546
|
+
decoded.value._tag === 'LSD.DevtoolsReady' ||
|
|
538
547
|
decoded.value._tag === 'LSD.DevtoolsConnected' ||
|
|
539
548
|
decoded.value.channelId !== this.adapter.coordinator.devtools.channelId
|
|
540
549
|
) {
|
|
@@ -547,12 +556,12 @@ export class Store<
|
|
|
547
556
|
devtoolsChannel.fromAppHost.postMessage(Schema.encodeSync(Devtools.MessageFromAppHost)(message))
|
|
548
557
|
|
|
549
558
|
switch (decoded.value._tag) {
|
|
550
|
-
case 'LSD.
|
|
559
|
+
case 'LSD.ReactivityGraphSubscribe': {
|
|
551
560
|
const includeResults = decoded.value.includeResults
|
|
552
561
|
const send = () =>
|
|
553
562
|
sendToDevtools(
|
|
554
|
-
Devtools.
|
|
555
|
-
|
|
563
|
+
Devtools.ReactivityGraphRes.make({
|
|
564
|
+
reactivityGraph: this.reactivityGraph.getSnapshot({ includeResults }),
|
|
556
565
|
requestId,
|
|
557
566
|
liveStoreVersion,
|
|
558
567
|
}),
|
|
@@ -560,9 +569,10 @@ export class Store<
|
|
|
560
569
|
|
|
561
570
|
send()
|
|
562
571
|
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
572
|
+
reactivityGraphSubcriptions.set(
|
|
573
|
+
requestId,
|
|
574
|
+
this.reactivityGraph.subscribeToRefresh(() => send()),
|
|
575
|
+
)
|
|
566
576
|
|
|
567
577
|
break
|
|
568
578
|
}
|
|
@@ -583,9 +593,8 @@ export class Store<
|
|
|
583
593
|
sendToDevtools(Devtools.DebugInfoRerunQueryRes.make({ requestId, liveStoreVersion }))
|
|
584
594
|
break
|
|
585
595
|
}
|
|
586
|
-
case 'LSD.
|
|
587
|
-
|
|
588
|
-
signalsSubcriptionRef.current = undefined
|
|
596
|
+
case 'LSD.ReactivityGraphUnsubscribe': {
|
|
597
|
+
reactivityGraphSubcriptions.get(requestId)!()
|
|
589
598
|
break
|
|
590
599
|
}
|
|
591
600
|
case 'LSD.LiveQueriesSubscribe': {
|
|
@@ -608,15 +617,15 @@ export class Store<
|
|
|
608
617
|
|
|
609
618
|
send()
|
|
610
619
|
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
620
|
+
liveQueriesSubscriptions.set(
|
|
621
|
+
requestId,
|
|
622
|
+
this.reactivityGraph.subscribeToRefresh(() => send()),
|
|
623
|
+
)
|
|
614
624
|
|
|
615
625
|
break
|
|
616
626
|
}
|
|
617
627
|
case 'LSD.LiveQueriesUnsubscribe': {
|
|
618
|
-
|
|
619
|
-
liveQueriesSubscriptionRef.current = undefined
|
|
628
|
+
liveQueriesSubscriptions.get(requestId)!()
|
|
620
629
|
break
|
|
621
630
|
}
|
|
622
631
|
case 'LSD.ResetAllDataReq': {
|
|
@@ -651,24 +660,24 @@ export const createStore = async <
|
|
|
651
660
|
>({
|
|
652
661
|
schema,
|
|
653
662
|
graphQLOptions,
|
|
654
|
-
|
|
655
|
-
otelRootSpanContext = otel.context.active(),
|
|
663
|
+
otelOptions,
|
|
656
664
|
adapter: adapterFactory,
|
|
657
665
|
boot,
|
|
658
|
-
|
|
666
|
+
reactivityGraph = globalReactivityGraph,
|
|
659
667
|
batchUpdates,
|
|
660
668
|
disableDevtools,
|
|
661
669
|
}: {
|
|
662
670
|
schema: TSchema
|
|
663
|
-
graphQLOptions?: GraphQLOptions<TGraphQLContext>
|
|
664
|
-
otelTracer?: otel.Tracer
|
|
665
|
-
otelRootSpanContext?: otel.Context
|
|
666
671
|
adapter: StoreAdapterFactory
|
|
672
|
+
reactivityGraph?: ReactivityGraph
|
|
673
|
+
graphQLOptions?: GraphQLOptions<TGraphQLContext>
|
|
674
|
+
otelOptions?: Partial<OtelOptions>
|
|
667
675
|
boot?: (db: BootDb, parentSpan: otel.Span) => unknown | Promise<unknown>
|
|
668
|
-
dbGraph?: DbGraph
|
|
669
676
|
batchUpdates?: (run: () => void) => void
|
|
670
677
|
disableDevtools?: boolean
|
|
671
678
|
}): Promise<Store<TGraphQLContext, TSchema>> => {
|
|
679
|
+
const otelTracer = otelOptions?.tracer ?? makeNoopTracer()
|
|
680
|
+
const otelRootSpanContext = otelOptions?.rootSpanContext ?? otel.context.active()
|
|
672
681
|
return otelTracer.startActiveSpan('createStore', {}, otelRootSpanContext, async (span) => {
|
|
673
682
|
try {
|
|
674
683
|
performance.mark('livestore:db-creating')
|
|
@@ -680,10 +689,10 @@ export const createStore = async <
|
|
|
680
689
|
performance.measure('livestore:db-create', 'livestore:db-creating', 'livestore:db-created')
|
|
681
690
|
|
|
682
691
|
if (batchUpdates !== undefined) {
|
|
683
|
-
|
|
692
|
+
reactivityGraph.effectsWrapper = batchUpdates
|
|
684
693
|
}
|
|
685
694
|
|
|
686
|
-
const mutationEventSchema =
|
|
695
|
+
const mutationEventSchema = makeMutationEventSchemaMemo(schema)
|
|
687
696
|
|
|
688
697
|
// TODO consider moving booting into the storage backend
|
|
689
698
|
if (boot !== undefined) {
|
|
@@ -716,7 +725,11 @@ export const createStore = async <
|
|
|
716
725
|
}
|
|
717
726
|
|
|
718
727
|
const mutationEventEncoded = Schema.encodeUnknownSync(mutationEventSchema)(mutationEventDecoded)
|
|
719
|
-
|
|
728
|
+
|
|
729
|
+
void adapter.coordinator.mutate(mutationEventEncoded as MutationEvent.AnyEncoded, {
|
|
730
|
+
span,
|
|
731
|
+
persisted: true,
|
|
732
|
+
})
|
|
720
733
|
}
|
|
721
734
|
},
|
|
722
735
|
select: (queryStr, bindValues) => {
|
|
@@ -759,13 +772,11 @@ export const createStore = async <
|
|
|
759
772
|
// await applySchema(db, schema)
|
|
760
773
|
return Store.createStore<TGraphQLContext, TSchema>(
|
|
761
774
|
{
|
|
762
|
-
adapter
|
|
775
|
+
adapter,
|
|
763
776
|
schema,
|
|
764
777
|
graphQLOptions,
|
|
765
|
-
otelTracer,
|
|
766
|
-
|
|
767
|
-
dbGraph,
|
|
768
|
-
mutationEventSchema,
|
|
778
|
+
otelOptions: { tracer: otelTracer, rootSpanContext: otelRootSpanContext },
|
|
779
|
+
reactivityGraph,
|
|
769
780
|
disableDevtools,
|
|
770
781
|
},
|
|
771
782
|
span,
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Creates a map that has a fixed number of entries.
|
|
3
|
-
* Once hitting the bound, earliest insertions are removed
|
|
4
|
-
*/
|
|
5
|
-
export default class BoundMap<K, V> {
|
|
6
|
-
#private;
|
|
7
|
-
constructor(sizeLimit: number);
|
|
8
|
-
onEvict: ((key: K, value: V) => void) | undefined;
|
|
9
|
-
set: (key: K, value: V) => void;
|
|
10
|
-
get: (key: K) => V | undefined;
|
|
11
|
-
delete: (key: K) => void;
|
|
12
|
-
keys: () => IterableIterator<K>;
|
|
13
|
-
}
|
|
14
|
-
export declare class BoundSet<V> {
|
|
15
|
-
#private;
|
|
16
|
-
constructor(sizeLimit: number);
|
|
17
|
-
onEvict: ((key: V) => void) | undefined;
|
|
18
|
-
add: (v: V) => void;
|
|
19
|
-
[Symbol.iterator]: () => IterableIterator<V>;
|
|
20
|
-
}
|
|
21
|
-
export declare class BoundArray<V> {
|
|
22
|
-
#private;
|
|
23
|
-
constructor(sizeLimit: number);
|
|
24
|
-
onEvict: ((key: V) => void) | undefined;
|
|
25
|
-
push: (v: V) => void;
|
|
26
|
-
get: (index: number) => V | undefined;
|
|
27
|
-
delete: (index: number) => void;
|
|
28
|
-
get length(): number;
|
|
29
|
-
[Symbol.iterator]: () => IterableIterator<V>;
|
|
30
|
-
map: <T>(fn: (v: V) => T) => T[];
|
|
31
|
-
clear: () => void;
|
|
32
|
-
sort: (fn?: (a: V, b: V) => number) => V[];
|
|
33
|
-
}
|
|
34
|
-
//# sourceMappingURL=bounded-collections.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"bounded-collections.d.ts","sourceRoot":"","sources":["../../src/utils/bounded-collections.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,OAAO,OAAO,QAAQ,CAAC,CAAC,EAAE,CAAC;;gBAIpB,SAAS,EAAE,MAAM;IAI7B,OAAO,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;IAEjD,GAAG,QAAS,CAAC,SAAS,CAAC,UAWtB;IAED,GAAG,QAAS,CAAC,KAAG,CAAC,GAAG,SAAS,CAE5B;IAED,MAAM,QAAS,CAAC,UAEf;IAED,IAAI,4BAEH;CACF;AAED,qBAAa,QAAQ,CAAC,CAAC;;gBAGT,SAAS,EAAE,MAAM;IAW7B,OAAO,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;IAEvC,GAAG,MAAO,CAAC,UAET;IAEF,CAAC,MAAM,CAAC,QAAQ,CAAC,4BAEhB;CACF;AAED,qBAAa,UAAU,CAAC,CAAC;;gBAIX,SAAS,EAAE,MAAM;IAI7B,OAAO,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;IAEvC,IAAI,MAAO,CAAC,UAQX;IAED,GAAG,UAAW,MAAM,KAAG,CAAC,GAAG,SAAS,CAEnC;IAED,MAAM,UAAW,MAAM,UAEtB;IAED,IAAI,MAAM,WAET;IAED,CAAC,MAAM,CAAC,QAAQ,CAAC,4BAEhB;IAED,GAAG,UAAW,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAG,CAAC,EAAE,CAE9B;IAED,KAAK,aAEJ;IAED,IAAI,QAAS,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,MAAM,SAElC;CACF"}
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Creates a map that has a fixed number of entries.
|
|
3
|
-
* Once hitting the bound, earliest insertions are removed
|
|
4
|
-
*/
|
|
5
|
-
export default class BoundMap {
|
|
6
|
-
#map = new Map();
|
|
7
|
-
#sizeLimit;
|
|
8
|
-
constructor(sizeLimit) {
|
|
9
|
-
this.#sizeLimit = sizeLimit;
|
|
10
|
-
}
|
|
11
|
-
onEvict;
|
|
12
|
-
set = (key, value) => {
|
|
13
|
-
this.#map.set(key, value);
|
|
14
|
-
// console.log(this.#map.size, this.#sizeLimit);
|
|
15
|
-
if (this.#map.size > this.#sizeLimit) {
|
|
16
|
-
const firstKey = this.#map.keys().next().value;
|
|
17
|
-
const deletedValue = this.#map.get(firstKey);
|
|
18
|
-
this.#map.delete(firstKey);
|
|
19
|
-
if (this.onEvict) {
|
|
20
|
-
this.onEvict(firstKey, deletedValue);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
};
|
|
24
|
-
get = (key) => {
|
|
25
|
-
return this.#map.get(key);
|
|
26
|
-
};
|
|
27
|
-
delete = (key) => {
|
|
28
|
-
this.#map.delete(key);
|
|
29
|
-
};
|
|
30
|
-
keys = () => {
|
|
31
|
-
return this.#map.keys();
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
export class BoundSet {
|
|
35
|
-
#map;
|
|
36
|
-
constructor(sizeLimit) {
|
|
37
|
-
this.#map = new BoundMap(sizeLimit);
|
|
38
|
-
this.#map.onEvict = this.#onEvict;
|
|
39
|
-
}
|
|
40
|
-
#onEvict = (v) => {
|
|
41
|
-
if (this.onEvict) {
|
|
42
|
-
this.onEvict(v);
|
|
43
|
-
}
|
|
44
|
-
};
|
|
45
|
-
onEvict;
|
|
46
|
-
add = (v) => {
|
|
47
|
-
this.#map.set(v, v);
|
|
48
|
-
};
|
|
49
|
-
[Symbol.iterator] = () => {
|
|
50
|
-
return this.#map.keys();
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
export class BoundArray {
|
|
54
|
-
#array = [];
|
|
55
|
-
#sizeLimit;
|
|
56
|
-
constructor(sizeLimit) {
|
|
57
|
-
this.#sizeLimit = sizeLimit;
|
|
58
|
-
}
|
|
59
|
-
onEvict;
|
|
60
|
-
push = (v) => {
|
|
61
|
-
this.#array.push(v);
|
|
62
|
-
if (this.#array.length > this.#sizeLimit) {
|
|
63
|
-
const first = this.#array.shift();
|
|
64
|
-
if (first && this.onEvict) {
|
|
65
|
-
this.onEvict(first);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
};
|
|
69
|
-
get = (index) => {
|
|
70
|
-
return this.#array[index];
|
|
71
|
-
};
|
|
72
|
-
delete = (index) => {
|
|
73
|
-
this.#array.splice(index, 1);
|
|
74
|
-
};
|
|
75
|
-
get length() {
|
|
76
|
-
return this.#array.length;
|
|
77
|
-
}
|
|
78
|
-
[Symbol.iterator] = () => {
|
|
79
|
-
return this.#array[Symbol.iterator]();
|
|
80
|
-
};
|
|
81
|
-
map = (fn) => {
|
|
82
|
-
return this.#array.map(fn);
|
|
83
|
-
};
|
|
84
|
-
clear = () => {
|
|
85
|
-
this.#array = [];
|
|
86
|
-
};
|
|
87
|
-
sort = (fn) => {
|
|
88
|
-
return this.#array.sort(fn);
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
//# sourceMappingURL=bounded-collections.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"bounded-collections.js","sourceRoot":"","sources":["../../src/utils/bounded-collections.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/util.d.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/// <reference lib="es2022" />
|
|
2
|
-
import type { Brand } from '@livestore/utils/effect';
|
|
3
|
-
export type ParamsObject = Record<string, SqlValue>;
|
|
4
|
-
export type SqlValue = string | number | Uint8Array | null;
|
|
5
|
-
export type Bindable = ReadonlyArray<SqlValue> | ParamsObject;
|
|
6
|
-
export type PreparedBindValues = Brand.Branded<Bindable, 'PreparedBindValues'>;
|
|
7
|
-
/** Prepare bind values to send to SQLite
|
|
8
|
-
/* Add $ to the beginning of keys; which we use as our interpolation syntax
|
|
9
|
-
/* We also strip out any params that aren't used in the statement,
|
|
10
|
-
/* because rusqlite doesn't allow unused named params
|
|
11
|
-
/* TODO: Search for unused params via proper parsing, not string search
|
|
12
|
-
**/
|
|
13
|
-
export declare const prepareBindValues: (values: Bindable, statement: string) => PreparedBindValues;
|
|
14
|
-
//# sourceMappingURL=util.d.ts.map
|
package/dist/utils/util.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../src/utils/util.ts"],"names":[],"mappings":";AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAA;AAEpD,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;AACnD,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU,GAAG,IAAI,CAAA;AAE1D,MAAM,MAAM,QAAQ,GAAG,aAAa,CAAC,QAAQ,CAAC,GAAG,YAAY,CAAA;AAI7D,MAAM,MAAM,kBAAkB,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,oBAAoB,CAAC,CAAA;AAE9E;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,WAAY,QAAQ,aAAa,MAAM,KAAG,kBAWvE,CAAA"}
|
package/dist/utils/util.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
/// <reference lib="es2022" />
|
|
2
|
-
/** Prepare bind values to send to SQLite
|
|
3
|
-
/* Add $ to the beginning of keys; which we use as our interpolation syntax
|
|
4
|
-
/* We also strip out any params that aren't used in the statement,
|
|
5
|
-
/* because rusqlite doesn't allow unused named params
|
|
6
|
-
/* TODO: Search for unused params via proper parsing, not string search
|
|
7
|
-
**/
|
|
8
|
-
export const prepareBindValues = (values, statement) => {
|
|
9
|
-
if (Array.isArray(values))
|
|
10
|
-
return values;
|
|
11
|
-
const result = {};
|
|
12
|
-
for (const [key, value] of Object.entries(values)) {
|
|
13
|
-
if (statement.includes(key)) {
|
|
14
|
-
result[`$${key}`] = value;
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
return result;
|
|
18
|
-
};
|
|
19
|
-
//# sourceMappingURL=util.js.map
|
package/dist/utils/util.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/utils/util.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAa9B;;;;;GAKG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,MAAgB,EAAE,SAAiB,EAAsB,EAAE;IAC3F,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QAAE,OAAO,MAAmC,CAAA;IAErE,MAAM,MAAM,GAAiB,EAAE,CAAA;IAC/B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,IAAI,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAC5B,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC,GAAG,KAAK,CAAA;QAC3B,CAAC;IACH,CAAC;IAED,OAAO,MAA4B,CAAA;AACrC,CAAC,CAAA"}
|
package/src/utils/util.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
/// <reference lib="es2022" />
|
|
2
|
-
|
|
3
|
-
import type { Brand } from '@livestore/utils/effect'
|
|
4
|
-
|
|
5
|
-
export type ParamsObject = Record<string, SqlValue>
|
|
6
|
-
export type SqlValue = string | number | Uint8Array | null
|
|
7
|
-
|
|
8
|
-
export type Bindable = ReadonlyArray<SqlValue> | ParamsObject
|
|
9
|
-
|
|
10
|
-
type XXX_TODO_REMOVE_REDUDANCY = 1
|
|
11
|
-
|
|
12
|
-
export type PreparedBindValues = Brand.Branded<Bindable, 'PreparedBindValues'>
|
|
13
|
-
|
|
14
|
-
/** Prepare bind values to send to SQLite
|
|
15
|
-
/* Add $ to the beginning of keys; which we use as our interpolation syntax
|
|
16
|
-
/* We also strip out any params that aren't used in the statement,
|
|
17
|
-
/* because rusqlite doesn't allow unused named params
|
|
18
|
-
/* TODO: Search for unused params via proper parsing, not string search
|
|
19
|
-
**/
|
|
20
|
-
export const prepareBindValues = (values: Bindable, statement: string): PreparedBindValues => {
|
|
21
|
-
if (Array.isArray(values)) return values as any as PreparedBindValues
|
|
22
|
-
|
|
23
|
-
const result: ParamsObject = {}
|
|
24
|
-
for (const [key, value] of Object.entries(values)) {
|
|
25
|
-
if (statement.includes(key)) {
|
|
26
|
-
result[`$${key}`] = value
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
return result as PreparedBindValues
|
|
31
|
-
}
|