@livestore/common 0.4.0-dev.1 → 0.4.0-dev.10
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/ClientSessionLeaderThreadProxy.d.ts +7 -2
- package/dist/ClientSessionLeaderThreadProxy.d.ts.map +1 -1
- package/dist/ClientSessionLeaderThreadProxy.js.map +1 -1
- package/dist/adapter-types.d.ts +9 -3
- package/dist/adapter-types.d.ts.map +1 -1
- package/dist/adapter-types.js.map +1 -1
- package/dist/devtools/devtools-messages-client-session.d.ts +21 -21
- package/dist/devtools/devtools-messages-common.d.ts +7 -14
- package/dist/devtools/devtools-messages-common.d.ts.map +1 -1
- package/dist/devtools/devtools-messages-common.js +1 -6
- package/dist/devtools/devtools-messages-common.js.map +1 -1
- package/dist/devtools/devtools-messages-leader.d.ts +27 -25
- package/dist/devtools/devtools-messages-leader.d.ts.map +1 -1
- package/dist/errors.d.ts +47 -5
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +22 -3
- package/dist/errors.js.map +1 -1
- package/dist/leader-thread/LeaderSyncProcessor.d.ts +7 -3
- package/dist/leader-thread/LeaderSyncProcessor.d.ts.map +1 -1
- package/dist/leader-thread/LeaderSyncProcessor.js +122 -49
- package/dist/leader-thread/LeaderSyncProcessor.js.map +1 -1
- package/dist/leader-thread/eventlog.d.ts +4 -10
- package/dist/leader-thread/eventlog.d.ts.map +1 -1
- package/dist/leader-thread/eventlog.js +4 -6
- package/dist/leader-thread/eventlog.js.map +1 -1
- package/dist/leader-thread/leader-worker-devtools.d.ts +1 -1
- package/dist/leader-thread/leader-worker-devtools.js +6 -2
- package/dist/leader-thread/leader-worker-devtools.js.map +1 -1
- package/dist/leader-thread/make-leader-thread-layer.d.ts +1 -2
- package/dist/leader-thread/make-leader-thread-layer.d.ts.map +1 -1
- package/dist/leader-thread/make-leader-thread-layer.js +68 -19
- package/dist/leader-thread/make-leader-thread-layer.js.map +1 -1
- package/dist/leader-thread/make-leader-thread-layer.test.d.ts +2 -0
- package/dist/leader-thread/make-leader-thread-layer.test.d.ts.map +1 -0
- package/dist/leader-thread/make-leader-thread-layer.test.js +32 -0
- package/dist/leader-thread/make-leader-thread-layer.test.js.map +1 -0
- package/dist/leader-thread/materialize-event.d.ts +2 -2
- package/dist/leader-thread/materialize-event.d.ts.map +1 -1
- package/dist/leader-thread/materialize-event.js +23 -9
- package/dist/leader-thread/materialize-event.js.map +1 -1
- package/dist/leader-thread/recreate-db.d.ts +2 -3
- package/dist/leader-thread/recreate-db.d.ts.map +1 -1
- package/dist/leader-thread/recreate-db.js +1 -1
- package/dist/leader-thread/recreate-db.js.map +1 -1
- package/dist/leader-thread/shutdown-channel.d.ts +2 -2
- package/dist/leader-thread/shutdown-channel.d.ts.map +1 -1
- package/dist/leader-thread/shutdown-channel.js +2 -2
- package/dist/leader-thread/shutdown-channel.js.map +1 -1
- package/dist/leader-thread/types.d.ts +7 -5
- package/dist/leader-thread/types.d.ts.map +1 -1
- package/dist/leader-thread/types.js.map +1 -1
- package/dist/materializer-helper.d.ts +1 -1
- package/dist/materializer-helper.d.ts.map +1 -1
- package/dist/materializer-helper.js +20 -4
- package/dist/materializer-helper.js.map +1 -1
- package/dist/rematerialize-from-eventlog.d.ts +1 -1
- package/dist/rematerialize-from-eventlog.d.ts.map +1 -1
- package/dist/rematerialize-from-eventlog.js +25 -16
- package/dist/rematerialize-from-eventlog.js.map +1 -1
- package/dist/schema/EventDef.d.ts +3 -0
- package/dist/schema/EventDef.d.ts.map +1 -1
- package/dist/schema/EventDef.js.map +1 -1
- package/dist/schema/LiveStoreEvent.d.ts +1 -1
- package/dist/schema/LiveStoreEvent.d.ts.map +1 -1
- package/dist/schema/LiveStoreEvent.js +1 -2
- package/dist/schema/LiveStoreEvent.js.map +1 -1
- package/dist/schema/mod.d.ts +2 -0
- package/dist/schema/mod.d.ts.map +1 -1
- package/dist/schema/mod.js +1 -0
- package/dist/schema/mod.js.map +1 -1
- package/dist/schema/schema.d.ts +15 -0
- package/dist/schema/schema.d.ts.map +1 -1
- package/dist/schema/schema.js +26 -1
- package/dist/schema/schema.js.map +1 -1
- package/dist/schema/state/sqlite/client-document-def.d.ts +35 -5
- package/dist/schema/state/sqlite/client-document-def.d.ts.map +1 -1
- package/dist/schema/state/sqlite/client-document-def.js +95 -4
- package/dist/schema/state/sqlite/client-document-def.js.map +1 -1
- package/dist/schema/state/sqlite/client-document-def.test.js +16 -0
- package/dist/schema/state/sqlite/client-document-def.test.js.map +1 -1
- package/dist/schema/state/sqlite/column-annotations.d.ts.map +1 -1
- package/dist/schema/state/sqlite/column-annotations.js +14 -6
- package/dist/schema/state/sqlite/column-annotations.js.map +1 -1
- package/dist/schema/state/sqlite/column-def.d.ts +6 -2
- package/dist/schema/state/sqlite/column-def.d.ts.map +1 -1
- package/dist/schema/state/sqlite/column-def.js +122 -185
- package/dist/schema/state/sqlite/column-def.js.map +1 -1
- package/dist/schema/state/sqlite/column-def.test.js +116 -73
- package/dist/schema/state/sqlite/column-def.test.js.map +1 -1
- package/dist/schema/state/sqlite/db-schema/ast/sqlite.d.ts +2 -1
- package/dist/schema/state/sqlite/db-schema/ast/sqlite.d.ts.map +1 -1
- package/dist/schema/state/sqlite/db-schema/ast/sqlite.js +23 -6
- package/dist/schema/state/sqlite/db-schema/ast/sqlite.js.map +1 -1
- package/dist/schema/state/sqlite/db-schema/dsl/mod.d.ts.map +1 -1
- package/dist/schema/state/sqlite/db-schema/dsl/mod.js +2 -1
- package/dist/schema/state/sqlite/db-schema/dsl/mod.js.map +1 -1
- package/dist/schema/state/sqlite/mod.d.ts +1 -1
- package/dist/schema/state/sqlite/mod.d.ts.map +1 -1
- package/dist/schema/state/sqlite/mod.js +1 -1
- package/dist/schema/state/sqlite/mod.js.map +1 -1
- package/dist/schema/state/sqlite/query-builder/api.d.ts +5 -2
- package/dist/schema/state/sqlite/query-builder/api.d.ts.map +1 -1
- package/dist/schema/state/sqlite/query-builder/impl.d.ts.map +1 -1
- package/dist/schema/state/sqlite/query-builder/impl.js +6 -2
- package/dist/schema/state/sqlite/query-builder/impl.js.map +1 -1
- package/dist/schema/state/sqlite/query-builder/impl.test.js +137 -2
- package/dist/schema/state/sqlite/query-builder/impl.test.js.map +1 -1
- package/dist/schema/state/sqlite/system-tables.d.ts +42 -6
- package/dist/schema/state/sqlite/system-tables.d.ts.map +1 -1
- package/dist/schema/state/sqlite/system-tables.js +2 -0
- package/dist/schema/state/sqlite/system-tables.js.map +1 -1
- package/dist/schema/state/sqlite/table-def.d.ts +4 -4
- package/dist/schema/state/sqlite/table-def.d.ts.map +1 -1
- package/dist/schema/state/sqlite/table-def.js +2 -2
- package/dist/schema/state/sqlite/table-def.js.map +1 -1
- package/dist/schema/state/sqlite/table-def.test.js +51 -2
- package/dist/schema/state/sqlite/table-def.test.js.map +1 -1
- package/dist/schema/unknown-events.d.ts +47 -0
- package/dist/schema/unknown-events.d.ts.map +1 -0
- package/dist/schema/unknown-events.js +69 -0
- package/dist/schema/unknown-events.js.map +1 -0
- package/dist/sql-queries/sql-query-builder.d.ts.map +1 -1
- package/dist/sql-queries/sql-query-builder.js +2 -1
- package/dist/sql-queries/sql-query-builder.js.map +1 -1
- package/dist/sync/ClientSessionSyncProcessor.d.ts +9 -11
- package/dist/sync/ClientSessionSyncProcessor.d.ts.map +1 -1
- package/dist/sync/ClientSessionSyncProcessor.js +35 -33
- package/dist/sync/ClientSessionSyncProcessor.js.map +1 -1
- package/dist/sync/errors.d.ts +61 -0
- package/dist/sync/errors.d.ts.map +1 -0
- package/dist/sync/errors.js +36 -0
- package/dist/sync/errors.js.map +1 -0
- package/dist/sync/index.d.ts +3 -0
- package/dist/sync/index.d.ts.map +1 -1
- package/dist/sync/index.js +3 -0
- package/dist/sync/index.js.map +1 -1
- package/dist/sync/mock-sync-backend.d.ts +23 -0
- package/dist/sync/mock-sync-backend.d.ts.map +1 -0
- package/dist/sync/mock-sync-backend.js +114 -0
- package/dist/sync/mock-sync-backend.js.map +1 -0
- package/dist/sync/next/compact-events.d.ts.map +1 -1
- package/dist/sync/next/compact-events.js +4 -5
- package/dist/sync/next/compact-events.js.map +1 -1
- package/dist/sync/next/facts.d.ts.map +1 -1
- package/dist/sync/next/facts.js +1 -2
- package/dist/sync/next/facts.js.map +1 -1
- package/dist/sync/next/history-dag-common.d.ts +50 -11
- package/dist/sync/next/history-dag-common.d.ts.map +1 -1
- package/dist/sync/next/history-dag-common.js +193 -4
- package/dist/sync/next/history-dag-common.js.map +1 -1
- package/dist/sync/next/history-dag.d.ts.map +1 -1
- package/dist/sync/next/history-dag.js +3 -1
- package/dist/sync/next/history-dag.js.map +1 -1
- package/dist/sync/sync-backend-kv.d.ts +7 -0
- package/dist/sync/sync-backend-kv.d.ts.map +1 -0
- package/dist/sync/sync-backend-kv.js +18 -0
- package/dist/sync/sync-backend-kv.js.map +1 -0
- package/dist/sync/sync-backend.d.ts +105 -0
- package/dist/sync/sync-backend.d.ts.map +1 -0
- package/dist/sync/sync-backend.js +61 -0
- package/dist/sync/sync-backend.js.map +1 -0
- package/dist/sync/sync.d.ts +6 -84
- package/dist/sync/sync.d.ts.map +1 -1
- package/dist/sync/sync.js +2 -27
- package/dist/sync/sync.js.map +1 -1
- package/dist/sync/transport-chunking.d.ts +36 -0
- package/dist/sync/transport-chunking.d.ts.map +1 -0
- package/dist/sync/transport-chunking.js +56 -0
- package/dist/sync/transport-chunking.js.map +1 -0
- package/dist/sync/validate-push-payload.d.ts +1 -1
- package/dist/sync/validate-push-payload.d.ts.map +1 -1
- package/dist/sync/validate-push-payload.js +6 -6
- package/dist/sync/validate-push-payload.js.map +1 -1
- package/dist/testing/event-factory.d.ts +68 -0
- package/dist/testing/event-factory.d.ts.map +1 -0
- package/dist/testing/event-factory.js +80 -0
- package/dist/testing/event-factory.js.map +1 -0
- package/dist/testing/mod.d.ts +2 -0
- package/dist/testing/mod.d.ts.map +1 -0
- package/dist/testing/mod.js +2 -0
- package/dist/testing/mod.js.map +1 -0
- package/dist/version.d.ts +2 -2
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +2 -2
- package/dist/version.js.map +1 -1
- package/package.json +7 -8
- package/src/ClientSessionLeaderThreadProxy.ts +7 -2
- package/src/adapter-types.ts +13 -3
- package/src/devtools/devtools-messages-common.ts +1 -8
- package/src/errors.ts +33 -4
- package/src/leader-thread/LeaderSyncProcessor.ts +179 -57
- package/src/leader-thread/eventlog.ts +10 -6
- package/src/leader-thread/leader-worker-devtools.ts +6 -2
- package/src/leader-thread/make-leader-thread-layer.test.ts +44 -0
- package/src/leader-thread/make-leader-thread-layer.ts +137 -26
- package/src/leader-thread/materialize-event.ts +34 -9
- package/src/leader-thread/recreate-db.ts +11 -3
- package/src/leader-thread/shutdown-channel.ts +16 -2
- package/src/leader-thread/types.ts +7 -5
- package/src/materializer-helper.ts +22 -5
- package/src/rematerialize-from-eventlog.ts +33 -23
- package/src/schema/EventDef.ts +3 -0
- package/src/schema/LiveStoreEvent.ts +1 -2
- package/src/schema/mod.ts +2 -0
- package/src/schema/schema.ts +37 -1
- package/src/schema/state/sqlite/client-document-def.test.ts +17 -0
- package/src/schema/state/sqlite/client-document-def.ts +117 -5
- package/src/schema/state/sqlite/column-annotations.ts +16 -6
- package/src/schema/state/sqlite/column-def.test.ts +150 -93
- package/src/schema/state/sqlite/column-def.ts +128 -203
- package/src/schema/state/sqlite/db-schema/ast/sqlite.ts +26 -6
- package/src/schema/state/sqlite/db-schema/dsl/mod.ts +2 -1
- package/src/schema/state/sqlite/mod.ts +1 -0
- package/src/schema/state/sqlite/query-builder/api.ts +7 -2
- package/src/schema/state/sqlite/query-builder/impl.test.ts +187 -6
- package/src/schema/state/sqlite/query-builder/impl.ts +8 -2
- package/src/schema/state/sqlite/system-tables.ts +2 -0
- package/src/schema/state/sqlite/table-def.test.ts +64 -2
- package/src/schema/state/sqlite/table-def.ts +9 -8
- package/src/schema/unknown-events.ts +131 -0
- package/src/sql-queries/sql-query-builder.ts +2 -1
- package/src/sync/ClientSessionSyncProcessor.ts +55 -49
- package/src/sync/errors.ts +38 -0
- package/src/sync/index.ts +3 -0
- package/src/sync/mock-sync-backend.ts +184 -0
- package/src/sync/next/compact-events.ts +4 -5
- package/src/sync/next/facts.ts +1 -3
- package/src/sync/next/history-dag-common.ts +272 -21
- package/src/sync/next/history-dag.ts +3 -1
- package/src/sync/sync-backend-kv.ts +22 -0
- package/src/sync/sync-backend.ts +185 -0
- package/src/sync/sync.ts +6 -89
- package/src/sync/transport-chunking.ts +90 -0
- package/src/sync/validate-push-payload.ts +6 -7
- package/src/testing/event-factory.ts +133 -0
- package/src/testing/mod.ts +1 -0
- package/src/version.ts +2 -2
- package/dist/schema-management/migrations.test.d.ts +0 -2
- package/dist/schema-management/migrations.test.d.ts.map +0 -1
- package/dist/schema-management/migrations.test.js +0 -52
- package/dist/schema-management/migrations.test.js.map +0 -1
- package/dist/sync/next/graphology.d.ts +0 -8
- package/dist/sync/next/graphology.d.ts.map +0 -1
- package/dist/sync/next/graphology.js +0 -30
- package/dist/sync/next/graphology.js.map +0 -1
- package/dist/sync/next/graphology_.d.ts +0 -3
- package/dist/sync/next/graphology_.d.ts.map +0 -1
- package/dist/sync/next/graphology_.js +0 -3
- package/dist/sync/next/graphology_.js.map +0 -1
- package/src/sync/next/ambient.d.ts +0 -3
- package/src/sync/next/graphology.ts +0 -41
- package/src/sync/next/graphology_.ts +0 -2
@@ -0,0 +1,90 @@
|
|
1
|
+
import { Chunk, Effect, Schema } from '@livestore/utils/effect'
|
2
|
+
|
3
|
+
const textEncoder = new TextEncoder()
|
4
|
+
|
5
|
+
/**
|
6
|
+
* Configuration describing how to break a chunk into smaller payload-safe chunks.
|
7
|
+
*/
|
8
|
+
export interface ChunkingOptions<A> {
|
9
|
+
/** Maximum number of items that may appear in any emitted chunk. */
|
10
|
+
readonly maxItems: number
|
11
|
+
/** Maximum encoded byte size allowed for any emitted chunk. */
|
12
|
+
readonly maxBytes: number
|
13
|
+
/**
|
14
|
+
* Callback that produces a JSON-serialisable structure whose byte size should
|
15
|
+
* fit within {@link maxBytes}. This lets callers control framing overhead.
|
16
|
+
*/
|
17
|
+
readonly encode: (items: ReadonlyArray<A>) => unknown
|
18
|
+
/**
|
19
|
+
* Optional custom measurement function. When provided it overrides the
|
20
|
+
* default {@link JSON.stringify}-based measurement logic.
|
21
|
+
*/
|
22
|
+
readonly measure?: (items: ReadonlyArray<A>) => number
|
23
|
+
}
|
24
|
+
|
25
|
+
/**
|
26
|
+
* Derives a function that splits an input chunk into sub-chunks confined by
|
27
|
+
* both item count and encoded byte size limits. Designed for transports with
|
28
|
+
* strict frame caps (e.g. Cloudflare hibernated WebSockets).
|
29
|
+
*/
|
30
|
+
export class OversizeChunkItemError extends Schema.TaggedError<OversizeChunkItemError>()('OversizeChunkItemError', {
|
31
|
+
size: Schema.Number,
|
32
|
+
maxBytes: Schema.Number,
|
33
|
+
}) {}
|
34
|
+
|
35
|
+
export const splitChunkBySize =
|
36
|
+
<A>(options: ChunkingOptions<A>) =>
|
37
|
+
(chunk: Chunk.Chunk<A>): Effect.Effect<Chunk.Chunk<Chunk.Chunk<A>>, OversizeChunkItemError> =>
|
38
|
+
Effect.gen(function* () {
|
39
|
+
const maxItems = Math.max(1, options.maxItems)
|
40
|
+
const maxBytes = Math.max(1, options.maxBytes)
|
41
|
+
const encode = options.encode
|
42
|
+
const measure = options.measure
|
43
|
+
|
44
|
+
const computeSize = (items: ReadonlyArray<A>) => {
|
45
|
+
if (measure !== undefined) {
|
46
|
+
return measure(items)
|
47
|
+
}
|
48
|
+
|
49
|
+
const encoded = encode(items)
|
50
|
+
return textEncoder.encode(JSON.stringify(encoded)).byteLength
|
51
|
+
}
|
52
|
+
|
53
|
+
const items = Chunk.toReadonlyArray(chunk)
|
54
|
+
if (items.length === 0) {
|
55
|
+
return Chunk.fromIterable<Chunk.Chunk<A>>([])
|
56
|
+
}
|
57
|
+
|
58
|
+
const result: Array<Chunk.Chunk<A>> = []
|
59
|
+
let current: Array<A> = []
|
60
|
+
|
61
|
+
const flushCurrent = () => {
|
62
|
+
if (current.length > 0) {
|
63
|
+
result.push(Chunk.fromIterable(current))
|
64
|
+
current = []
|
65
|
+
}
|
66
|
+
}
|
67
|
+
|
68
|
+
for (const item of items) {
|
69
|
+
current.push(item)
|
70
|
+
const exceedsLimit = current.length > maxItems || computeSize(current) > maxBytes
|
71
|
+
|
72
|
+
if (exceedsLimit) {
|
73
|
+
// remove the item we just added and emit the previous chunk if it exists
|
74
|
+
const last = current.pop()!
|
75
|
+
flushCurrent()
|
76
|
+
|
77
|
+
if (last !== undefined) {
|
78
|
+
current = [last]
|
79
|
+
const singleItemTooLarge = computeSize(current) > maxBytes
|
80
|
+
if (singleItemTooLarge || current.length > maxItems) {
|
81
|
+
return yield* new OversizeChunkItemError({ size: computeSize([last]), maxBytes })
|
82
|
+
}
|
83
|
+
}
|
84
|
+
}
|
85
|
+
}
|
86
|
+
|
87
|
+
flushCurrent()
|
88
|
+
|
89
|
+
return Chunk.fromIterable(result)
|
90
|
+
})
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import { Effect } from '@livestore/utils/effect'
|
2
2
|
|
3
|
-
import
|
4
|
-
import { InvalidPushError } from './sync.ts'
|
3
|
+
import { EventSequenceNumber, type LiveStoreEvent } from '../schema/mod.ts'
|
4
|
+
import { InvalidPushError, ServerAheadError } from './sync.ts'
|
5
5
|
|
6
6
|
// TODO proper batch validation
|
7
7
|
export const validatePushPayload = (
|
@@ -11,11 +11,10 @@ export const validatePushPayload = (
|
|
11
11
|
Effect.gen(function* () {
|
12
12
|
if (batch[0]!.seqNum <= currentEventSequenceNumber) {
|
13
13
|
return yield* InvalidPushError.make({
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
},
|
14
|
+
cause: new ServerAheadError({
|
15
|
+
minimumExpectedNum: EventSequenceNumber.globalEventSequenceNumber(currentEventSequenceNumber + 1),
|
16
|
+
providedNum: EventSequenceNumber.globalEventSequenceNumber(batch[0]!.seqNum),
|
17
|
+
}),
|
19
18
|
})
|
20
19
|
}
|
21
20
|
})
|
@@ -0,0 +1,133 @@
|
|
1
|
+
/**
|
2
|
+
* Helpers for synthesizing LiveStore events in tests while keeping track of
|
3
|
+
* sequence numbers, parent pointers, and authoring client identity. Inspired
|
4
|
+
* by the effect-based schema utilities, the factory exposes a namespaced API
|
5
|
+
* where each event definition maps to a helper with `next`, `advanceTo`, and
|
6
|
+
* `setParent` functions that share a single sequence stream.
|
7
|
+
*
|
8
|
+
* @example
|
9
|
+
* ```ts
|
10
|
+
* import { EventFactory } from '@livestore/common/testing'
|
11
|
+
* import { events } from './schema'
|
12
|
+
*
|
13
|
+
* const eventFactory = EventFactory.makeFactory(events)({
|
14
|
+
* client: EventFactory.clientIdentity('test-client'),
|
15
|
+
* startSeq: 1,
|
16
|
+
* initialParent: 'root',
|
17
|
+
* })
|
18
|
+
*
|
19
|
+
* const bootstrap = eventFactory.todoCreated.next({
|
20
|
+
* id: 'todo-1',
|
21
|
+
* text: 'write tests',
|
22
|
+
* completed: false,
|
23
|
+
* })
|
24
|
+
*
|
25
|
+
* eventFactory.todoCreated.advanceTo(42)
|
26
|
+
* const branched = eventFactory.todoUpdated.next({
|
27
|
+
* id: 'todo-1',
|
28
|
+
* text: 'ship feature',
|
29
|
+
* completed: true,
|
30
|
+
* })
|
31
|
+
* ```
|
32
|
+
*/
|
33
|
+
|
34
|
+
import { Schema } from '@livestore/utils/effect'
|
35
|
+
|
36
|
+
import type { EventDef } from '../schema/EventDef.ts'
|
37
|
+
import * as EventSequenceNumber from '../schema/EventSequenceNumber.ts'
|
38
|
+
import * as LiveStoreEvent from '../schema/LiveStoreEvent.ts'
|
39
|
+
|
40
|
+
export interface ClientIdentity {
|
41
|
+
clientId: string
|
42
|
+
sessionId: string
|
43
|
+
}
|
44
|
+
|
45
|
+
export const clientIdentity = (label: string, session = `${label}-session`): ClientIdentity => ({
|
46
|
+
clientId: label,
|
47
|
+
sessionId: session,
|
48
|
+
})
|
49
|
+
|
50
|
+
export type SequenceValue = 'root' | number
|
51
|
+
|
52
|
+
type EventFactoriesArgs<TDefs extends Record<string, EventDef.Any>> = {
|
53
|
+
[K in keyof TDefs]: Parameters<TDefs[K]>[0]
|
54
|
+
}
|
55
|
+
|
56
|
+
type EventFactories<TDefs extends Record<string, EventDef.Any>, TResult> = {
|
57
|
+
[K in keyof TDefs]: {
|
58
|
+
next: (args: EventFactoriesArgs<TDefs>[K]) => TResult
|
59
|
+
advanceTo: (seq: number, parent?: SequenceValue) => void
|
60
|
+
setParent: (parent: SequenceValue) => void
|
61
|
+
current: () => { seq: number; parent: SequenceValue }
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
65
|
+
export interface EventFactoriesConfig {
|
66
|
+
client: ClientIdentity
|
67
|
+
/**
|
68
|
+
* @default 1
|
69
|
+
*/
|
70
|
+
startSeq?: number
|
71
|
+
/**
|
72
|
+
* @default 0 (root)
|
73
|
+
*/
|
74
|
+
initialParent?: SequenceValue
|
75
|
+
}
|
76
|
+
|
77
|
+
export const makeFactory =
|
78
|
+
<TDefs extends Record<string, EventDef.Any>>(eventDefs: TDefs) =>
|
79
|
+
({
|
80
|
+
client,
|
81
|
+
startSeq = 1,
|
82
|
+
initialParent = 'root',
|
83
|
+
}: EventFactoriesConfig): EventFactories<TDefs, LiveStoreEvent.AnyEncodedGlobal> => {
|
84
|
+
let nextSeq = startSeq
|
85
|
+
let parentRef: SequenceValue = initialParent
|
86
|
+
|
87
|
+
const advanceTo = (seq: number, parent: SequenceValue = 'root') => {
|
88
|
+
nextSeq = seq
|
89
|
+
parentRef = parent
|
90
|
+
}
|
91
|
+
|
92
|
+
const setParent = (parent: SequenceValue) => {
|
93
|
+
parentRef = parent
|
94
|
+
}
|
95
|
+
|
96
|
+
const current = () => ({ seq: nextSeq, parent: parentRef })
|
97
|
+
|
98
|
+
const factories: Partial<EventFactories<TDefs, LiveStoreEvent.AnyEncodedGlobal>> = {}
|
99
|
+
|
100
|
+
for (const [name, eventDef] of Object.entries(eventDefs) as [keyof TDefs, TDefs[keyof TDefs]][]) {
|
101
|
+
const next = (args: EventFactoriesArgs<TDefs>[typeof name]) => {
|
102
|
+
const decoded = eventDef(args)
|
103
|
+
const encodedArgs = Schema.encodeSync(eventDef.schema)(decoded.args)
|
104
|
+
const encoded = eventDef.encoded(encodedArgs)
|
105
|
+
|
106
|
+
const event = LiveStoreEvent.AnyEncodedGlobal.make({
|
107
|
+
name: encoded.name,
|
108
|
+
args: encoded.args,
|
109
|
+
seqNum: EventSequenceNumber.globalEventSequenceNumber(nextSeq),
|
110
|
+
parentSeqNum:
|
111
|
+
parentRef === 'root'
|
112
|
+
? EventSequenceNumber.ROOT.global
|
113
|
+
: EventSequenceNumber.globalEventSequenceNumber(parentRef),
|
114
|
+
clientId: client.clientId,
|
115
|
+
sessionId: client.sessionId,
|
116
|
+
})
|
117
|
+
|
118
|
+
parentRef = nextSeq
|
119
|
+
nextSeq = nextSeq + 1
|
120
|
+
|
121
|
+
return event
|
122
|
+
}
|
123
|
+
|
124
|
+
factories[name] = {
|
125
|
+
next,
|
126
|
+
advanceTo,
|
127
|
+
setParent,
|
128
|
+
current,
|
129
|
+
} as EventFactories<TDefs, LiveStoreEvent.AnyEncodedGlobal>[typeof name]
|
130
|
+
}
|
131
|
+
|
132
|
+
return factories as EventFactories<TDefs, LiveStoreEvent.AnyEncodedGlobal>
|
133
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
export * as EventFactory from './event-factory.ts'
|
package/src/version.ts
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
// import packageJson from '../package.json' with { type: 'json' }
|
3
3
|
// export const liveStoreVersion = packageJson.version
|
4
4
|
|
5
|
-
export const liveStoreVersion = '0.4.0-dev.
|
5
|
+
export const liveStoreVersion = '0.4.0-dev.10' as const
|
6
6
|
|
7
7
|
/**
|
8
8
|
* This version number is incremented whenever the internal storage format changes in a breaking way.
|
@@ -11,4 +11,4 @@ export const liveStoreVersion = '0.4.0-dev.1' as const
|
|
11
11
|
* While LiveStore is in beta, this might happen more frequently.
|
12
12
|
* In the future, LiveStore will provide a migration path for older database files to avoid the impression of data loss.
|
13
13
|
*/
|
14
|
-
export const liveStoreStorageFormatVersion =
|
14
|
+
export const liveStoreStorageFormatVersion = 6
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"migrations.test.d.ts","sourceRoot":"","sources":["../../src/schema-management/migrations.test.ts"],"names":[],"mappings":""}
|
@@ -1,52 +0,0 @@
|
|
1
|
-
import { Option, Schema } from '@livestore/utils/effect';
|
2
|
-
import { describe, expect, it } from 'vitest';
|
3
|
-
import { makeColumnSpec } from './migrations.js';
|
4
|
-
const createColumn = (name, type, options = {}) => ({
|
5
|
-
_tag: 'column',
|
6
|
-
name,
|
7
|
-
type: { _tag: type },
|
8
|
-
nullable: options.nullable ?? true,
|
9
|
-
primaryKey: options.primaryKey ?? false,
|
10
|
-
default: Option.none(),
|
11
|
-
schema: type === 'text' ? Schema.String : Schema.Number,
|
12
|
-
});
|
13
|
-
describe('makeColumnSpec', () => {
|
14
|
-
it('should quote column names properly for reserved keywords', () => {
|
15
|
-
const table = {
|
16
|
-
_tag: 'table',
|
17
|
-
name: 'blocks',
|
18
|
-
columns: [createColumn('order', 'integer', { nullable: false }), createColumn('group', 'text')],
|
19
|
-
indexes: [],
|
20
|
-
};
|
21
|
-
const result = makeColumnSpec(table);
|
22
|
-
expect(result).toMatchInlineSnapshot(`"'order' integer not null , 'group' text "`);
|
23
|
-
expect(result).toContain("'order'");
|
24
|
-
expect(result).toContain("'group'");
|
25
|
-
});
|
26
|
-
it('should handle basic columns with primary keys', () => {
|
27
|
-
const table = {
|
28
|
-
_tag: 'table',
|
29
|
-
name: 'users',
|
30
|
-
columns: [createColumn('id', 'text', { nullable: false, primaryKey: true }), createColumn('name', 'text')],
|
31
|
-
indexes: [],
|
32
|
-
};
|
33
|
-
const result = makeColumnSpec(table);
|
34
|
-
expect(result).toMatchInlineSnapshot(`"'id' text not null , 'name' text , PRIMARY KEY ('id')"`);
|
35
|
-
expect(result).toContain("PRIMARY KEY ('id')");
|
36
|
-
});
|
37
|
-
it('should handle multi-column primary keys', () => {
|
38
|
-
const table = {
|
39
|
-
_tag: 'table',
|
40
|
-
name: 'composite',
|
41
|
-
columns: [
|
42
|
-
createColumn('tenant_id', 'text', { nullable: false, primaryKey: true }),
|
43
|
-
createColumn('user_id', 'text', { nullable: false, primaryKey: true }),
|
44
|
-
],
|
45
|
-
indexes: [],
|
46
|
-
};
|
47
|
-
const result = makeColumnSpec(table);
|
48
|
-
expect(result).toMatchInlineSnapshot(`"'tenant_id' text not null , 'user_id' text not null , PRIMARY KEY ('tenant_id', 'user_id')"`);
|
49
|
-
expect(result).toContain("PRIMARY KEY ('tenant_id', 'user_id')");
|
50
|
-
});
|
51
|
-
});
|
52
|
-
//# sourceMappingURL=migrations.test.js.map
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"migrations.test.js","sourceRoot":"","sources":["../../src/schema-management/migrations.test.ts"],"names":[],"mappings":"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"}
|
@@ -1,8 +0,0 @@
|
|
1
|
-
import type * as graphologyTypes from 'graphology-types';
|
2
|
-
export declare const graphology: any;
|
3
|
-
export declare class IGraph<NodeAttributes extends graphologyTypes.Attributes = graphologyTypes.Attributes, EdgeAttributes extends graphologyTypes.Attributes = graphologyTypes.Attributes, GraphAttributes extends graphologyTypes.Attributes = graphologyTypes.Attributes> extends graphologyTypes.AbstractGraph<NodeAttributes, EdgeAttributes, GraphAttributes> {
|
4
|
-
constructor(options?: graphologyTypes.GraphOptions);
|
5
|
-
}
|
6
|
-
export declare const DirectedGraph: typeof IGraph;
|
7
|
-
export declare const Graph: typeof IGraph;
|
8
|
-
//# sourceMappingURL=graphology.d.ts.map
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"graphology.d.ts","sourceRoot":"","sources":["../../../src/sync/next/graphology.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,eAAe,MAAM,kBAAkB,CAAA;AAExD,eAAO,MAAM,UAAU,EAAkB,GAAG,CAAA;AAE5C,MAAM,CAAC,OAAO,OAAO,MAAM,CACzB,cAAc,SAAS,eAAe,CAAC,UAAU,GAAG,eAAe,CAAC,UAAU,EAC9E,cAAc,SAAS,eAAe,CAAC,UAAU,GAAG,eAAe,CAAC,UAAU,EAC9E,eAAe,SAAS,eAAe,CAAC,UAAU,GAAG,eAAe,CAAC,UAAU,CAC/E,SAAQ,eAAe,CAAC,aAAa,CAAC,cAAc,EAAE,cAAc,EAAE,eAAe,CAAC;gBAC1E,OAAO,CAAC,EAAE,eAAe,CAAC,YAAY;CACnD;AAED,eAAO,MAAM,aAAa,EAA8D,OAAO,MAAM,CAAA;AAErG,eAAO,MAAM,KAAK,EAA8C,OAAO,MAAM,CAAA"}
|
@@ -1,30 +0,0 @@
|
|
1
|
-
// TODO re-enable when `graphology` supports ESM `exports` and `.js` import/export syntax
|
2
|
-
// import {} from 'graphology'
|
3
|
-
import * as graphology_ from 'graphology';
|
4
|
-
export const graphology = graphology_;
|
5
|
-
export const DirectedGraph = class DirectedGraph extends graphology.DirectedGraph {
|
6
|
-
};
|
7
|
-
export const Graph = class Graph extends graphology.Graph {
|
8
|
-
};
|
9
|
-
// export const graphology = graphology_ as graphologyTypes
|
10
|
-
/*
|
11
|
-
|
12
|
-
Example usage:
|
13
|
-
|
14
|
-
const dag = new graphology.DirectedGraph({ allowSelfLoops: false })
|
15
|
-
|
16
|
-
nodes.forEach((node) => dag.addNode(node.id, { width: node.data.label.length * 100, height: 40 }))
|
17
|
-
edges.forEach((edge) => {
|
18
|
-
// TODO do this filtering earlier
|
19
|
-
if (!nodeIds.has(edge.source) || !nodeIds.has(edge.target)) return
|
20
|
-
|
21
|
-
dag.addEdge(edge.source, edge.target)
|
22
|
-
})
|
23
|
-
|
24
|
-
graphologyLayout.random.assign(dag) // needed for initial `x`, `y` values
|
25
|
-
const sensibleSettings = forceAtlas2.inferSettings(dag)
|
26
|
-
// forceAtlas2.assign(dag, { iterations: 100, settings: { adjustSizes: true, } })
|
27
|
-
forceAtlas2.assign(dag, { iterations: 100, settings: sensibleSettings })
|
28
|
-
|
29
|
-
*/
|
30
|
-
//# sourceMappingURL=graphology.js.map
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"graphology.js","sourceRoot":"","sources":["../../../src/sync/next/graphology.ts"],"names":[],"mappings":"AAAA,yFAAyF;AACzF,8BAA8B;AAC9B,OAAO,KAAK,WAAW,MAAM,YAAY,CAAA;AAGzC,MAAM,CAAC,MAAM,UAAU,GAAG,WAAkB,CAAA;AAU5C,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,aAAc,SAAQ,UAAU,CAAC,aAAa;CAAoB,CAAA;AAErG,MAAM,CAAC,MAAM,KAAK,GAAG,MAAM,KAAM,SAAQ,UAAU,CAAC,KAAK;CAAoB,CAAA;AAE7E,2DAA2D;AAE3D;;;;;;;;;;;;;;;;;;;EAmBE"}
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"graphology_.d.ts","sourceRoot":"","sources":["../../../src/sync/next/graphology_.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,gBAAgB,CAAA;AACzD,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAA"}
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"graphology_.js","sourceRoot":"","sources":["../../../src/sync/next/graphology_.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,gBAAgB,CAAA;AACzD,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAA"}
|
@@ -1,41 +0,0 @@
|
|
1
|
-
// TODO re-enable when `graphology` supports ESM `exports` and `.js` import/export syntax
|
2
|
-
// import {} from 'graphology'
|
3
|
-
import * as graphology_ from 'graphology'
|
4
|
-
import type * as graphologyTypes from 'graphology-types'
|
5
|
-
|
6
|
-
export const graphology = graphology_ as any
|
7
|
-
|
8
|
-
export declare class IGraph<
|
9
|
-
NodeAttributes extends graphologyTypes.Attributes = graphologyTypes.Attributes,
|
10
|
-
EdgeAttributes extends graphologyTypes.Attributes = graphologyTypes.Attributes,
|
11
|
-
GraphAttributes extends graphologyTypes.Attributes = graphologyTypes.Attributes,
|
12
|
-
> extends graphologyTypes.AbstractGraph<NodeAttributes, EdgeAttributes, GraphAttributes> {
|
13
|
-
constructor(options?: graphologyTypes.GraphOptions)
|
14
|
-
}
|
15
|
-
|
16
|
-
export const DirectedGraph = class DirectedGraph extends graphology.DirectedGraph {} as typeof IGraph
|
17
|
-
|
18
|
-
export const Graph = class Graph extends graphology.Graph {} as typeof IGraph
|
19
|
-
|
20
|
-
// export const graphology = graphology_ as graphologyTypes
|
21
|
-
|
22
|
-
/*
|
23
|
-
|
24
|
-
Example usage:
|
25
|
-
|
26
|
-
const dag = new graphology.DirectedGraph({ allowSelfLoops: false })
|
27
|
-
|
28
|
-
nodes.forEach((node) => dag.addNode(node.id, { width: node.data.label.length * 100, height: 40 }))
|
29
|
-
edges.forEach((edge) => {
|
30
|
-
// TODO do this filtering earlier
|
31
|
-
if (!nodeIds.has(edge.source) || !nodeIds.has(edge.target)) return
|
32
|
-
|
33
|
-
dag.addEdge(edge.source, edge.target)
|
34
|
-
})
|
35
|
-
|
36
|
-
graphologyLayout.random.assign(dag) // needed for initial `x`, `y` values
|
37
|
-
const sensibleSettings = forceAtlas2.inferSettings(dag)
|
38
|
-
// forceAtlas2.assign(dag, { iterations: 100, settings: { adjustSizes: true, } })
|
39
|
-
forceAtlas2.assign(dag, { iterations: 100, settings: sensibleSettings })
|
40
|
-
|
41
|
-
*/
|