@livestore/common 0.0.0-snapshot-f5ece014485b5ab43795c218f7ba7cfa32c81707 → 0.0.0-snapshot-057a9e3a18ca69a310d4eb8cf35a34e94fa1841e
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 +35 -0
- package/dist/ClientSessionLeaderThreadProxy.d.ts.map +1 -0
- package/dist/ClientSessionLeaderThreadProxy.js +6 -0
- package/dist/ClientSessionLeaderThreadProxy.js.map +1 -0
- package/dist/adapter-types.d.ts +10 -161
- package/dist/adapter-types.d.ts.map +1 -1
- package/dist/adapter-types.js +5 -49
- package/dist/adapter-types.js.map +1 -1
- package/dist/defs.d.ts +20 -0
- package/dist/defs.d.ts.map +1 -0
- package/dist/defs.js +12 -0
- package/dist/defs.js.map +1 -0
- package/dist/devtools/devtools-messages-client-session.d.ts +23 -21
- package/dist/devtools/devtools-messages-client-session.d.ts.map +1 -1
- package/dist/devtools/devtools-messages-common.d.ts +6 -6
- package/dist/devtools/devtools-messages-common.d.ts.map +1 -1
- package/dist/devtools/devtools-messages-leader.d.ts +26 -24
- package/dist/devtools/devtools-messages-leader.d.ts.map +1 -1
- package/dist/devtools/devtools-messages.d.ts +1 -1
- package/dist/devtools/devtools-messages.d.ts.map +1 -1
- package/dist/devtools/devtools-messages.js +1 -1
- package/dist/devtools/devtools-messages.js.map +1 -1
- package/dist/errors.d.ts +50 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +36 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +11 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -11
- package/dist/index.js.map +1 -1
- package/dist/leader-thread/LeaderSyncProcessor.d.ts +6 -7
- package/dist/leader-thread/LeaderSyncProcessor.d.ts.map +1 -1
- package/dist/leader-thread/LeaderSyncProcessor.js +112 -122
- package/dist/leader-thread/LeaderSyncProcessor.js.map +1 -1
- package/dist/leader-thread/eventlog.d.ts +17 -6
- package/dist/leader-thread/eventlog.d.ts.map +1 -1
- package/dist/leader-thread/eventlog.js +33 -18
- package/dist/leader-thread/eventlog.js.map +1 -1
- package/dist/leader-thread/leader-worker-devtools.d.ts.map +1 -1
- package/dist/leader-thread/leader-worker-devtools.js +1 -2
- package/dist/leader-thread/leader-worker-devtools.js.map +1 -1
- package/dist/leader-thread/make-leader-thread-layer.d.ts.map +1 -1
- package/dist/leader-thread/make-leader-thread-layer.js +37 -7
- package/dist/leader-thread/make-leader-thread-layer.js.map +1 -1
- package/dist/leader-thread/materialize-event.d.ts.map +1 -1
- package/dist/leader-thread/materialize-event.js +7 -1
- package/dist/leader-thread/materialize-event.js.map +1 -1
- package/dist/leader-thread/mod.d.ts +4 -3
- package/dist/leader-thread/mod.d.ts.map +1 -1
- package/dist/leader-thread/mod.js +4 -3
- package/dist/leader-thread/mod.js.map +1 -1
- package/dist/leader-thread/recreate-db.d.ts +13 -6
- package/dist/leader-thread/recreate-db.d.ts.map +1 -1
- package/dist/leader-thread/recreate-db.js +1 -3
- package/dist/leader-thread/recreate-db.js.map +1 -1
- package/dist/leader-thread/types.d.ts +5 -7
- package/dist/leader-thread/types.d.ts.map +1 -1
- package/dist/make-client-session.d.ts +1 -1
- package/dist/make-client-session.d.ts.map +1 -1
- package/dist/make-client-session.js +1 -1
- package/dist/make-client-session.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 +10 -2
- package/dist/rematerialize-from-eventlog.js.map +1 -1
- package/dist/schema/EventDef.d.ts +2 -2
- package/dist/schema/EventDef.d.ts.map +1 -1
- package/dist/schema/EventDef.js +2 -2
- package/dist/schema/EventDef.js.map +1 -1
- package/dist/schema/EventSequenceNumber.d.ts +20 -2
- package/dist/schema/EventSequenceNumber.d.ts.map +1 -1
- package/dist/schema/EventSequenceNumber.js +71 -19
- package/dist/schema/EventSequenceNumber.js.map +1 -1
- package/dist/schema/EventSequenceNumber.test.js +88 -3
- package/dist/schema/EventSequenceNumber.test.js.map +1 -1
- package/dist/schema/LiveStoreEvent.d.ts +23 -9
- package/dist/schema/LiveStoreEvent.d.ts.map +1 -1
- package/dist/schema/LiveStoreEvent.js +12 -4
- package/dist/schema/LiveStoreEvent.js.map +1 -1
- package/dist/schema/events.d.ts +1 -1
- package/dist/schema/events.d.ts.map +1 -1
- package/dist/schema/events.js +1 -1
- package/dist/schema/events.js.map +1 -1
- package/dist/schema/mod.d.ts +6 -6
- package/dist/schema/mod.d.ts.map +1 -1
- package/dist/schema/mod.js +6 -6
- package/dist/schema/mod.js.map +1 -1
- package/dist/schema/state/sqlite/client-document-def.d.ts.map +1 -1
- package/dist/schema/state/sqlite/client-document-def.js.map +1 -1
- package/dist/schema/state/sqlite/client-document-def.test.js +3 -5
- package/dist/schema/state/sqlite/client-document-def.test.js.map +1 -1
- package/dist/schema/state/sqlite/db-schema/dsl/field-defs.js +2 -2
- package/dist/schema/state/sqlite/db-schema/dsl/field-defs.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.map +1 -1
- package/dist/schema/state/sqlite/db-schema/hash.d.ts.map +1 -1
- package/dist/schema/state/sqlite/db-schema/hash.js +3 -2
- package/dist/schema/state/sqlite/db-schema/hash.js.map +1 -1
- package/dist/schema/state/sqlite/db-schema/mod.d.ts +1 -1
- package/dist/schema/state/sqlite/db-schema/mod.d.ts.map +1 -1
- package/dist/schema/state/sqlite/db-schema/mod.js +1 -1
- package/dist/schema/state/sqlite/db-schema/mod.js.map +1 -1
- package/dist/schema/state/sqlite/mod.d.ts +3 -3
- package/dist/schema/state/sqlite/mod.d.ts.map +1 -1
- package/dist/schema/state/sqlite/mod.js +2 -2
- package/dist/schema/state/sqlite/mod.js.map +1 -1
- package/dist/schema/state/sqlite/query-builder/api.d.ts +35 -8
- package/dist/schema/state/sqlite/query-builder/api.d.ts.map +1 -1
- package/dist/schema/state/sqlite/query-builder/api.js.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 +18 -23
- package/dist/schema/state/sqlite/query-builder/impl.js.map +1 -1
- package/dist/schema/state/sqlite/query-builder/impl.test.d.ts +1 -81
- package/dist/schema/state/sqlite/query-builder/impl.test.d.ts.map +1 -1
- package/dist/schema/state/sqlite/query-builder/impl.test.js +34 -20
- package/dist/schema/state/sqlite/query-builder/impl.test.js.map +1 -1
- package/dist/schema/state/sqlite/system-tables.d.ts +67 -62
- package/dist/schema/state/sqlite/system-tables.d.ts.map +1 -1
- package/dist/schema/state/sqlite/system-tables.js +8 -17
- package/dist/schema/state/sqlite/system-tables.js.map +1 -1
- package/dist/schema/state/sqlite/table-def.d.ts +1 -1
- package/dist/schema/state/sqlite/table-def.d.ts.map +1 -1
- package/dist/schema-management/migrations.d.ts +3 -1
- package/dist/schema-management/migrations.d.ts.map +1 -1
- package/dist/schema-management/migrations.js.map +1 -1
- package/dist/sql-queries/sql-queries.d.ts.map +1 -1
- package/dist/sql-queries/sql-queries.js +2 -0
- package/dist/sql-queries/sql-queries.js.map +1 -1
- package/dist/sqlite-types.d.ts +72 -0
- package/dist/sqlite-types.d.ts.map +1 -0
- package/dist/sqlite-types.js +5 -0
- package/dist/sqlite-types.js.map +1 -0
- package/dist/sync/ClientSessionSyncProcessor.d.ts +7 -4
- package/dist/sync/ClientSessionSyncProcessor.d.ts.map +1 -1
- package/dist/sync/ClientSessionSyncProcessor.js +17 -16
- package/dist/sync/ClientSessionSyncProcessor.js.map +1 -1
- package/dist/sync/index.d.ts +1 -1
- package/dist/sync/index.d.ts.map +1 -1
- package/dist/sync/index.js +1 -1
- package/dist/sync/index.js.map +1 -1
- package/dist/sync/next/graphology.d.ts.map +1 -1
- package/dist/sync/next/graphology.js +0 -6
- package/dist/sync/next/graphology.js.map +1 -1
- package/dist/sync/next/graphology_.d.ts +1 -1
- package/dist/sync/next/graphology_.d.ts.map +1 -1
- package/dist/sync/next/graphology_.js +1 -1
- package/dist/sync/next/graphology_.js.map +1 -1
- package/dist/sync/next/mod.d.ts +3 -3
- package/dist/sync/next/mod.d.ts.map +1 -1
- package/dist/sync/next/mod.js +3 -3
- package/dist/sync/next/mod.js.map +1 -1
- package/dist/sync/next/rebase-events.d.ts.map +1 -1
- package/dist/sync/next/rebase-events.js +1 -0
- package/dist/sync/next/rebase-events.js.map +1 -1
- package/dist/sync/next/test/compact-events.test.js +1 -1
- package/dist/sync/next/test/compact-events.test.js.map +1 -1
- package/dist/sync/next/test/event-fixtures.d.ts.map +1 -1
- package/dist/sync/next/test/event-fixtures.js +12 -3
- package/dist/sync/next/test/event-fixtures.js.map +1 -1
- package/dist/sync/sync.d.ts +2 -0
- package/dist/sync/sync.d.ts.map +1 -1
- package/dist/sync/sync.js +3 -0
- package/dist/sync/sync.js.map +1 -1
- package/dist/sync/syncstate.d.ts +13 -4
- package/dist/sync/syncstate.d.ts.map +1 -1
- package/dist/sync/syncstate.js +23 -10
- package/dist/sync/syncstate.js.map +1 -1
- package/dist/sync/syncstate.test.js +17 -18
- package/dist/sync/syncstate.test.js.map +1 -1
- package/dist/util.d.ts.map +1 -1
- package/dist/util.js +0 -1
- package/dist/util.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +6 -5
- package/src/ClientSessionLeaderThreadProxy.ts +40 -0
- package/src/adapter-types.ts +19 -165
- package/src/defs.ts +17 -0
- package/src/devtools/devtools-messages.ts +1 -1
- package/src/errors.ts +49 -0
- package/src/index.ts +11 -11
- package/src/leader-thread/LeaderSyncProcessor.ts +141 -180
- package/src/leader-thread/eventlog.ts +79 -57
- package/src/leader-thread/leader-worker-devtools.ts +1 -2
- package/src/leader-thread/make-leader-thread-layer.ts +52 -8
- package/src/leader-thread/materialize-event.ts +8 -1
- package/src/leader-thread/mod.ts +4 -3
- package/src/leader-thread/recreate-db.ts +99 -91
- package/src/leader-thread/types.ts +6 -11
- package/src/make-client-session.ts +2 -3
- package/src/rematerialize-from-eventlog.ts +10 -2
- package/src/schema/EventDef.ts +5 -3
- package/src/schema/EventSequenceNumber.test.ts +120 -3
- package/src/schema/EventSequenceNumber.ts +95 -23
- package/src/schema/LiveStoreEvent.ts +20 -4
- package/src/schema/events.ts +1 -1
- package/src/schema/mod.ts +6 -6
- package/src/schema/state/sqlite/client-document-def.test.ts +7 -5
- package/src/schema/state/sqlite/client-document-def.ts +36 -24
- package/src/schema/state/sqlite/db-schema/dsl/field-defs.ts +2 -2
- package/src/schema/state/sqlite/db-schema/dsl/mod.ts +16 -10
- package/src/schema/state/sqlite/db-schema/hash.ts +3 -4
- package/src/schema/state/sqlite/db-schema/mod.ts +1 -1
- package/src/schema/state/sqlite/mod.ts +6 -6
- package/src/schema/state/sqlite/query-builder/api.ts +38 -8
- package/src/schema/state/sqlite/query-builder/impl.test.ts +60 -20
- package/src/schema/state/sqlite/query-builder/impl.ts +19 -24
- package/src/schema/state/sqlite/system-tables.ts +9 -22
- package/src/schema/state/sqlite/table-def.ts +1 -1
- package/src/schema-management/migrations.ts +3 -1
- package/src/sql-queries/sql-queries.ts +2 -0
- package/src/sqlite-types.ts +76 -0
- package/src/sync/ClientSessionSyncProcessor.ts +29 -23
- package/src/sync/index.ts +1 -1
- package/src/sync/next/graphology.ts +3 -11
- package/src/sync/next/graphology_.ts +1 -1
- package/src/sync/next/mod.ts +3 -3
- package/src/sync/next/rebase-events.ts +2 -1
- package/src/sync/next/test/compact-events.test.ts +1 -1
- package/src/sync/next/test/event-fixtures.ts +12 -3
- package/src/sync/sync.ts +3 -0
- package/src/sync/syncstate.test.ts +17 -18
- package/src/sync/syncstate.ts +31 -10
- package/src/util.ts +0 -1
- package/src/version.ts +1 -1
package/src/schema/EventDef.ts
CHANGED
|
@@ -28,7 +28,9 @@ export type EventDef<TName extends string, TType, TEncoded = TType, TDerived ext
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
/** Helper function to construct a partial event */
|
|
31
|
-
(
|
|
31
|
+
(
|
|
32
|
+
args: TType,
|
|
33
|
+
): {
|
|
32
34
|
name: TName
|
|
33
35
|
args: TType
|
|
34
36
|
}
|
|
@@ -194,14 +196,14 @@ export type Materializer<TEventDef extends EventDef.AnyWithoutFn = EventDef.AnyW
|
|
|
194
196
|
) => SingleOrReadonlyArray<MaterializerResult>
|
|
195
197
|
|
|
196
198
|
export const defineMaterializer = <TEventDef extends EventDef.AnyWithoutFn>(
|
|
197
|
-
|
|
199
|
+
_eventDef: TEventDef,
|
|
198
200
|
materializer: Materializer<TEventDef>,
|
|
199
201
|
): Materializer<TEventDef> => {
|
|
200
202
|
return materializer
|
|
201
203
|
}
|
|
202
204
|
|
|
203
205
|
export const materializers = <TInputRecord extends Record<string, EventDef.AnyWithoutFn>>(
|
|
204
|
-
|
|
206
|
+
_eventDefRecord: TInputRecord,
|
|
205
207
|
handlers: {
|
|
206
208
|
[TEventName in TInputRecord[keyof TInputRecord]['name'] as Extract<
|
|
207
209
|
TInputRecord[keyof TInputRecord],
|
|
@@ -4,9 +4,126 @@ import { expect } from 'vitest'
|
|
|
4
4
|
import { EventSequenceNumber } from './mod.js'
|
|
5
5
|
|
|
6
6
|
Vitest.describe('EventSequenceNumber', () => {
|
|
7
|
-
Vitest.test('nextPair', () => {
|
|
7
|
+
Vitest.test('nextPair (no rebase)', () => {
|
|
8
8
|
const e_0_0 = EventSequenceNumber.make({ global: 0, client: 0 })
|
|
9
|
-
expect(EventSequenceNumber.nextPair(e_0_0, false).seqNum).toStrictEqual({
|
|
10
|
-
|
|
9
|
+
expect(EventSequenceNumber.nextPair({ seqNum: e_0_0, isClient: false }).seqNum).toStrictEqual({
|
|
10
|
+
global: 1,
|
|
11
|
+
client: 0,
|
|
12
|
+
rebaseGeneration: 0,
|
|
13
|
+
})
|
|
14
|
+
expect(EventSequenceNumber.nextPair({ seqNum: e_0_0, isClient: true }).seqNum).toStrictEqual({
|
|
15
|
+
global: 0,
|
|
16
|
+
client: 1,
|
|
17
|
+
rebaseGeneration: 0,
|
|
18
|
+
})
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
Vitest.test('nextPair (rebase)', () => {
|
|
22
|
+
const e_0_0 = EventSequenceNumber.make({ global: 0, client: 0 })
|
|
23
|
+
expect(EventSequenceNumber.nextPair({ seqNum: e_0_0, isClient: false, rebaseGeneration: 1 }).seqNum).toStrictEqual({
|
|
24
|
+
global: 1,
|
|
25
|
+
client: 0,
|
|
26
|
+
rebaseGeneration: 1,
|
|
27
|
+
})
|
|
28
|
+
expect(EventSequenceNumber.nextPair({ seqNum: e_0_0, isClient: true, rebaseGeneration: 1 }).seqNum).toStrictEqual({
|
|
29
|
+
global: 0,
|
|
30
|
+
client: 1,
|
|
31
|
+
rebaseGeneration: 1,
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
const e_0_0_g1 = EventSequenceNumber.make({ global: 0, client: 0, rebaseGeneration: 2 })
|
|
35
|
+
expect(EventSequenceNumber.nextPair({ seqNum: e_0_0_g1, isClient: false }).seqNum).toStrictEqual({
|
|
36
|
+
global: 1,
|
|
37
|
+
client: 0,
|
|
38
|
+
rebaseGeneration: 2,
|
|
39
|
+
})
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
Vitest.test('toString', () => {
|
|
43
|
+
expect(EventSequenceNumber.toString(EventSequenceNumber.make({ global: 0, client: 0 }))).toBe('e0')
|
|
44
|
+
expect(EventSequenceNumber.toString(EventSequenceNumber.make({ global: 0, client: 0, rebaseGeneration: 1 }))).toBe(
|
|
45
|
+
'e0r1',
|
|
46
|
+
)
|
|
47
|
+
expect(EventSequenceNumber.toString(EventSequenceNumber.make({ global: 0, client: 1 }))).toBe('e0+1')
|
|
48
|
+
expect(EventSequenceNumber.toString(EventSequenceNumber.make({ global: 0, client: 1, rebaseGeneration: 1 }))).toBe(
|
|
49
|
+
'e0+1r1',
|
|
50
|
+
)
|
|
51
|
+
expect(EventSequenceNumber.toString(EventSequenceNumber.make({ global: 5, client: 3, rebaseGeneration: 2 }))).toBe(
|
|
52
|
+
'e5+3r2',
|
|
53
|
+
)
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
Vitest.test('fromString', () => {
|
|
57
|
+
// Basic cases
|
|
58
|
+
expect(EventSequenceNumber.fromString('e0')).toStrictEqual(EventSequenceNumber.make({ global: 0, client: 0 }))
|
|
59
|
+
expect(EventSequenceNumber.fromString('e0r1')).toStrictEqual(
|
|
60
|
+
EventSequenceNumber.make({ global: 0, client: 0, rebaseGeneration: 1 }),
|
|
61
|
+
)
|
|
62
|
+
expect(EventSequenceNumber.fromString('e0+1')).toStrictEqual(EventSequenceNumber.make({ global: 0, client: 1 }))
|
|
63
|
+
expect(EventSequenceNumber.fromString('e0+1r1')).toStrictEqual(
|
|
64
|
+
EventSequenceNumber.make({ global: 0, client: 1, rebaseGeneration: 1 }),
|
|
65
|
+
)
|
|
66
|
+
expect(EventSequenceNumber.fromString('e5+3r2')).toStrictEqual(
|
|
67
|
+
EventSequenceNumber.make({ global: 5, client: 3, rebaseGeneration: 2 }),
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
// Error cases
|
|
71
|
+
expect(() => EventSequenceNumber.fromString('0')).toThrow(
|
|
72
|
+
'Invalid event sequence number string: must start with "e"',
|
|
73
|
+
)
|
|
74
|
+
expect(() => EventSequenceNumber.fromString('eabc')).toThrow(
|
|
75
|
+
'Invalid event sequence number string: invalid number format',
|
|
76
|
+
)
|
|
77
|
+
expect(() => EventSequenceNumber.fromString('e0+abc')).toThrow(
|
|
78
|
+
'Invalid event sequence number string: invalid number format',
|
|
79
|
+
)
|
|
80
|
+
expect(() => EventSequenceNumber.fromString('e0rabc')).toThrow(
|
|
81
|
+
'Invalid event sequence number string: invalid number format',
|
|
82
|
+
)
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
Vitest.test('toString/fromString roundtrip', () => {
|
|
86
|
+
const testCases = [
|
|
87
|
+
{ global: 0, client: 0, rebaseGeneration: 0 },
|
|
88
|
+
{ global: 0, client: 0, rebaseGeneration: 1 },
|
|
89
|
+
{ global: 0, client: 1, rebaseGeneration: 0 },
|
|
90
|
+
{ global: 0, client: 1, rebaseGeneration: 1 },
|
|
91
|
+
{ global: 5, client: 3, rebaseGeneration: 2 },
|
|
92
|
+
{ global: 100, client: 50, rebaseGeneration: 10 },
|
|
93
|
+
]
|
|
94
|
+
|
|
95
|
+
for (const testCase of testCases) {
|
|
96
|
+
const original = EventSequenceNumber.make(testCase)
|
|
97
|
+
const str = EventSequenceNumber.toString(original)
|
|
98
|
+
const parsed = EventSequenceNumber.fromString(str)
|
|
99
|
+
expect(parsed).toStrictEqual(original)
|
|
100
|
+
}
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
Vitest.test('compare', () => {
|
|
104
|
+
const e_0_0_r0 = EventSequenceNumber.make({ global: 0, client: 0, rebaseGeneration: 0 })
|
|
105
|
+
const e_0_0_r1 = EventSequenceNumber.make({ global: 0, client: 0, rebaseGeneration: 1 })
|
|
106
|
+
const e_0_1_r0 = EventSequenceNumber.make({ global: 0, client: 1, rebaseGeneration: 0 })
|
|
107
|
+
const e_0_1_r1 = EventSequenceNumber.make({ global: 0, client: 1, rebaseGeneration: 1 })
|
|
108
|
+
const e_1_0_r0 = EventSequenceNumber.make({ global: 1, client: 0, rebaseGeneration: 0 })
|
|
109
|
+
const e_1_1_r0 = EventSequenceNumber.make({ global: 1, client: 1, rebaseGeneration: 0 })
|
|
110
|
+
|
|
111
|
+
// Global comparison (strongest level)
|
|
112
|
+
expect(EventSequenceNumber.compare(e_0_0_r0, e_1_0_r0)).toBeLessThan(0)
|
|
113
|
+
expect(EventSequenceNumber.compare(e_1_0_r0, e_0_0_r0)).toBeGreaterThan(0)
|
|
114
|
+
expect(EventSequenceNumber.compare(e_0_1_r1, e_1_0_r0)).toBeLessThan(0) // global overrides client and rebase
|
|
115
|
+
|
|
116
|
+
// Client comparison (second level)
|
|
117
|
+
expect(EventSequenceNumber.compare(e_0_0_r0, e_0_1_r0)).toBeLessThan(0)
|
|
118
|
+
expect(EventSequenceNumber.compare(e_0_1_r0, e_0_0_r0)).toBeGreaterThan(0)
|
|
119
|
+
expect(EventSequenceNumber.compare(e_0_0_r1, e_0_1_r0)).toBeLessThan(0) // client overrides rebase
|
|
120
|
+
|
|
121
|
+
// Rebase generation comparison (weakest level)
|
|
122
|
+
expect(EventSequenceNumber.compare(e_0_0_r0, e_0_0_r1)).toBeLessThan(0)
|
|
123
|
+
expect(EventSequenceNumber.compare(e_0_0_r1, e_0_0_r0)).toBeGreaterThan(0)
|
|
124
|
+
|
|
125
|
+
// Equal comparison
|
|
126
|
+
expect(EventSequenceNumber.compare(e_0_0_r0, e_0_0_r0)).toBe(0)
|
|
127
|
+
expect(EventSequenceNumber.compare(e_1_1_r0, e_1_1_r0)).toBe(0)
|
|
11
128
|
})
|
|
12
129
|
})
|
|
@@ -10,6 +10,8 @@ export const GlobalEventSequenceNumber = Schema.fromBrand(globalEventSequenceNum
|
|
|
10
10
|
|
|
11
11
|
export const clientDefault = 0 as any as ClientEventSequenceNumber
|
|
12
12
|
|
|
13
|
+
export const rebaseGenerationDefault = 0
|
|
14
|
+
|
|
13
15
|
/**
|
|
14
16
|
* LiveStore event sequence number value consisting of a globally unique event sequence number
|
|
15
17
|
* and a client sequence number.
|
|
@@ -20,16 +22,17 @@ export type EventSequenceNumber = {
|
|
|
20
22
|
global: GlobalEventSequenceNumber
|
|
21
23
|
client: ClientEventSequenceNumber
|
|
22
24
|
/**
|
|
23
|
-
*
|
|
25
|
+
* Generation integer that is incremented whenever the client rebased.
|
|
26
|
+
* Starts from and resets to 0 for each global sequence number.
|
|
24
27
|
*/
|
|
25
|
-
|
|
28
|
+
rebaseGeneration: number
|
|
26
29
|
}
|
|
27
30
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
// export const GlobalEventSequenceNumber = Schema.Struct({})
|
|
31
|
+
export type EventSequenceNumberInput =
|
|
32
|
+
| EventSequenceNumber
|
|
33
|
+
| (Omit<typeof EventSequenceNumber.Encoded, 'rebaseGeneration'> & { rebaseGeneration?: number })
|
|
32
34
|
|
|
35
|
+
// TODO adjust name to `ClientEventSequenceNumber`
|
|
33
36
|
/**
|
|
34
37
|
* NOTE: Client mutation events with a non-0 client id, won't be synced to the sync backend.
|
|
35
38
|
*/
|
|
@@ -40,36 +43,83 @@ export const EventSequenceNumber = Schema.Struct({
|
|
|
40
43
|
|
|
41
44
|
// TODO also provide a way to see "confirmation level" of event (e.g. confirmed by leader/sync backend)
|
|
42
45
|
|
|
43
|
-
// TODO: actually add this field
|
|
44
46
|
// Client only
|
|
45
|
-
|
|
46
|
-
}).annotations({
|
|
47
|
+
rebaseGeneration: Schema.Int,
|
|
48
|
+
}).annotations({
|
|
49
|
+
title: 'LiveStore.EventSequenceNumber',
|
|
50
|
+
pretty: () => (seqNum) => toString(seqNum),
|
|
51
|
+
})
|
|
47
52
|
|
|
48
53
|
/**
|
|
49
54
|
* Compare two event sequence numbers i.e. checks if the first event sequence number is less than the second.
|
|
55
|
+
* Comparison hierarchy: global > client > rebaseGeneration
|
|
50
56
|
*/
|
|
51
57
|
export const compare = (a: EventSequenceNumber, b: EventSequenceNumber) => {
|
|
52
58
|
if (a.global !== b.global) {
|
|
53
59
|
return a.global - b.global
|
|
54
60
|
}
|
|
55
|
-
|
|
61
|
+
if (a.client !== b.client) {
|
|
62
|
+
return a.client - b.client
|
|
63
|
+
}
|
|
64
|
+
return a.rebaseGeneration - b.rebaseGeneration
|
|
56
65
|
}
|
|
57
66
|
|
|
58
67
|
/**
|
|
59
68
|
* Convert an event sequence number to a string representation.
|
|
60
69
|
*/
|
|
61
|
-
export const toString = (seqNum: EventSequenceNumber) =>
|
|
62
|
-
seqNum.
|
|
70
|
+
export const toString = (seqNum: EventSequenceNumber) => {
|
|
71
|
+
const rebaseGenerationStr = seqNum.rebaseGeneration > 0 ? `r${seqNum.rebaseGeneration}` : ''
|
|
72
|
+
return seqNum.client === 0
|
|
73
|
+
? `e${seqNum.global}${rebaseGenerationStr}`
|
|
74
|
+
: `e${seqNum.global}+${seqNum.client}${rebaseGenerationStr}`
|
|
75
|
+
}
|
|
63
76
|
|
|
64
77
|
/**
|
|
65
78
|
* Convert a string representation of an event sequence number to an event sequence number.
|
|
79
|
+
* Parses strings in the format: e{global}[+{client}][r{rebaseGeneration}]
|
|
80
|
+
* Examples: "e0", "e0r1", "e0+1", "e0+1r1"
|
|
66
81
|
*/
|
|
67
82
|
export const fromString = (str: string): EventSequenceNumber => {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
83
|
+
if (!str.startsWith('e')) {
|
|
84
|
+
throw new Error('Invalid event sequence number string: must start with "e"')
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Remove the 'e' prefix
|
|
88
|
+
const remaining = str.slice(1)
|
|
89
|
+
|
|
90
|
+
// Parse rebase generation if present
|
|
91
|
+
let rebaseGeneration = rebaseGenerationDefault
|
|
92
|
+
let withoutRebase = remaining
|
|
93
|
+
const rebaseMatch = remaining.match(/r(\d+)$/)
|
|
94
|
+
if (rebaseMatch !== null) {
|
|
95
|
+
rebaseGeneration = Number.parseInt(rebaseMatch[1]!, 10)
|
|
96
|
+
withoutRebase = remaining.slice(0, -rebaseMatch[0].length)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Parse global and client parts
|
|
100
|
+
const parts = withoutRebase.split('+')
|
|
101
|
+
|
|
102
|
+
// Validate that parts contain only digits (and possibly empty for client)
|
|
103
|
+
if (parts[0] === '' || !/^\d+$/.test(parts[0]!)) {
|
|
104
|
+
throw new Error('Invalid event sequence number string: invalid number format')
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (parts.length > 1 && parts[1] !== undefined && (parts[1] === '' || !/^\d+$/.test(parts[1]))) {
|
|
108
|
+
throw new Error('Invalid event sequence number string: invalid number format')
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const global = Number.parseInt(parts[0]!, 10)
|
|
112
|
+
const client = parts.length > 1 && parts[1] !== undefined ? Number.parseInt(parts[1], 10) : 0
|
|
113
|
+
|
|
114
|
+
if (Number.isNaN(global) || Number.isNaN(client) || Number.isNaN(rebaseGeneration)) {
|
|
115
|
+
throw new TypeError('Invalid event sequence number string: invalid number format')
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return {
|
|
119
|
+
global: global as any as GlobalEventSequenceNumber,
|
|
120
|
+
client: client as any as ClientEventSequenceNumber,
|
|
121
|
+
rebaseGeneration,
|
|
71
122
|
}
|
|
72
|
-
return { global, client } as EventSequenceNumber
|
|
73
123
|
}
|
|
74
124
|
|
|
75
125
|
export const isEqual = (a: EventSequenceNumber, b: EventSequenceNumber) =>
|
|
@@ -80,6 +130,7 @@ export type EventSequenceNumberPair = { seqNum: EventSequenceNumber; parentSeqNu
|
|
|
80
130
|
export const ROOT = {
|
|
81
131
|
global: 0 as any as GlobalEventSequenceNumber,
|
|
82
132
|
client: clientDefault,
|
|
133
|
+
rebaseGeneration: rebaseGenerationDefault,
|
|
83
134
|
} satisfies EventSequenceNumber
|
|
84
135
|
|
|
85
136
|
export const isGreaterThan = (a: EventSequenceNumber, b: EventSequenceNumber) => {
|
|
@@ -101,21 +152,42 @@ export const diff = (a: EventSequenceNumber, b: EventSequenceNumber) => {
|
|
|
101
152
|
}
|
|
102
153
|
}
|
|
103
154
|
|
|
104
|
-
export const make = (seqNum:
|
|
105
|
-
return Schema.is(EventSequenceNumber)(seqNum)
|
|
155
|
+
export const make = (seqNum: EventSequenceNumberInput): EventSequenceNumber => {
|
|
156
|
+
return Schema.is(EventSequenceNumber)(seqNum)
|
|
157
|
+
? seqNum
|
|
158
|
+
: Schema.decodeSync(EventSequenceNumber)({
|
|
159
|
+
...seqNum,
|
|
160
|
+
rebaseGeneration: seqNum.rebaseGeneration ?? rebaseGenerationDefault,
|
|
161
|
+
})
|
|
106
162
|
}
|
|
107
163
|
|
|
108
|
-
export const nextPair = (
|
|
109
|
-
|
|
164
|
+
export const nextPair = ({
|
|
165
|
+
seqNum,
|
|
166
|
+
isClient,
|
|
167
|
+
rebaseGeneration,
|
|
168
|
+
}: {
|
|
169
|
+
seqNum: EventSequenceNumber
|
|
170
|
+
isClient: boolean
|
|
171
|
+
rebaseGeneration?: number
|
|
172
|
+
}): EventSequenceNumberPair => {
|
|
173
|
+
if (isClient) {
|
|
110
174
|
return {
|
|
111
|
-
seqNum: {
|
|
175
|
+
seqNum: {
|
|
176
|
+
global: seqNum.global,
|
|
177
|
+
client: (seqNum.client + 1) as any as ClientEventSequenceNumber,
|
|
178
|
+
rebaseGeneration: rebaseGeneration ?? seqNum.rebaseGeneration,
|
|
179
|
+
},
|
|
112
180
|
parentSeqNum: seqNum,
|
|
113
181
|
}
|
|
114
182
|
}
|
|
115
183
|
|
|
116
184
|
return {
|
|
117
|
-
seqNum: {
|
|
185
|
+
seqNum: {
|
|
186
|
+
global: (seqNum.global + 1) as any as GlobalEventSequenceNumber,
|
|
187
|
+
client: clientDefault,
|
|
188
|
+
rebaseGeneration: rebaseGeneration ?? seqNum.rebaseGeneration,
|
|
189
|
+
},
|
|
118
190
|
// NOTE we always point to `client: 0` for non-clientOnly events
|
|
119
|
-
parentSeqNum: { global: seqNum.global, client: clientDefault },
|
|
191
|
+
parentSeqNum: { global: seqNum.global, client: clientDefault, rebaseGeneration: seqNum.rebaseGeneration },
|
|
120
192
|
}
|
|
121
193
|
}
|
|
@@ -221,10 +221,18 @@ export class EncodedWithMeta extends Schema.Class<EncodedWithMeta>('LiveStoreEve
|
|
|
221
221
|
* +---- global number
|
|
222
222
|
* Client num is ommitted for global events
|
|
223
223
|
*/
|
|
224
|
-
rebase = (
|
|
224
|
+
rebase = ({
|
|
225
|
+
parentSeqNum,
|
|
226
|
+
isClient,
|
|
227
|
+
rebaseGeneration,
|
|
228
|
+
}: {
|
|
229
|
+
parentSeqNum: EventSequenceNumber.EventSequenceNumber
|
|
230
|
+
isClient: boolean
|
|
231
|
+
rebaseGeneration: number
|
|
232
|
+
}) =>
|
|
225
233
|
new EncodedWithMeta({
|
|
226
234
|
...this,
|
|
227
|
-
...EventSequenceNumber.nextPair(parentSeqNum, isClient),
|
|
235
|
+
...EventSequenceNumber.nextPair({ seqNum: parentSeqNum, isClient, rebaseGeneration }),
|
|
228
236
|
})
|
|
229
237
|
|
|
230
238
|
static fromGlobal = (
|
|
@@ -237,8 +245,16 @@ export class EncodedWithMeta extends Schema.Class<EncodedWithMeta>('LiveStoreEve
|
|
|
237
245
|
) =>
|
|
238
246
|
new EncodedWithMeta({
|
|
239
247
|
...event,
|
|
240
|
-
seqNum: {
|
|
241
|
-
|
|
248
|
+
seqNum: {
|
|
249
|
+
global: event.seqNum,
|
|
250
|
+
client: EventSequenceNumber.clientDefault,
|
|
251
|
+
rebaseGeneration: EventSequenceNumber.rebaseGenerationDefault,
|
|
252
|
+
},
|
|
253
|
+
parentSeqNum: {
|
|
254
|
+
global: event.parentSeqNum,
|
|
255
|
+
client: EventSequenceNumber.clientDefault,
|
|
256
|
+
rebaseGeneration: EventSequenceNumber.rebaseGenerationDefault,
|
|
257
|
+
},
|
|
242
258
|
meta: {
|
|
243
259
|
sessionChangeset: { _tag: 'unset' as const },
|
|
244
260
|
syncMetadata: meta.syncMetadata,
|
package/src/schema/events.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { defineEvent, synced
|
|
1
|
+
export { clientOnly, defineEvent, synced } from './EventDef.js'
|
package/src/schema/mod.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
export * as SystemTables from './state/sqlite/system-tables.js'
|
|
2
|
-
export { SqliteAst, SqliteDsl } from './state/sqlite/db-schema/mod.js'
|
|
3
1
|
export * from './EventDef.js'
|
|
4
|
-
export * from './state/sqlite/schema-helpers.js'
|
|
5
|
-
export * from './schema.js'
|
|
6
|
-
export * as State from './state/mod.js'
|
|
7
|
-
export * as LiveStoreEvent from './LiveStoreEvent.js'
|
|
8
2
|
export * as EventSequenceNumber from './EventSequenceNumber.js'
|
|
9
3
|
export * as Events from './events.js'
|
|
4
|
+
export * as LiveStoreEvent from './LiveStoreEvent.js'
|
|
5
|
+
export * from './schema.js'
|
|
6
|
+
export * as State from './state/mod.js'
|
|
7
|
+
export { SqliteAst, SqliteDsl } from './state/sqlite/db-schema/mod.js'
|
|
8
|
+
export * from './state/sqlite/schema-helpers.js'
|
|
9
|
+
export * as SystemTables from './state/sqlite/system-tables.js'
|
|
@@ -3,7 +3,7 @@ import { describe, expect, test } from 'vitest'
|
|
|
3
3
|
|
|
4
4
|
import { tables } from '../../../__tests__/fixture.js'
|
|
5
5
|
import type * as LiveStoreEvent from '../../LiveStoreEvent.js'
|
|
6
|
-
import {
|
|
6
|
+
import { ClientDocumentTableDefSymbol, clientDocument } from './client-document-def.js'
|
|
7
7
|
|
|
8
8
|
describe('client document table', () => {
|
|
9
9
|
test('set event', () => {
|
|
@@ -70,8 +70,9 @@ describe('client document table', () => {
|
|
|
70
70
|
})
|
|
71
71
|
|
|
72
72
|
test('struct value (partial set=true)', () => {
|
|
73
|
-
expect(
|
|
74
|
-
.
|
|
73
|
+
expect(
|
|
74
|
+
forSchema(Schema.Struct({ a: Schema.String }), { a: 'hello' }, 'id1', { partialSet: true }),
|
|
75
|
+
).toMatchInlineSnapshot(`
|
|
75
76
|
{
|
|
76
77
|
"bindValues": [
|
|
77
78
|
"id1",
|
|
@@ -92,8 +93,9 @@ describe('client document table', () => {
|
|
|
92
93
|
})
|
|
93
94
|
|
|
94
95
|
test('struct value (partial set=false)', () => {
|
|
95
|
-
expect(
|
|
96
|
-
.
|
|
96
|
+
expect(
|
|
97
|
+
forSchema(Schema.Struct({ a: Schema.String }), { a: 'hello' }, 'id1', { partialSet: false }),
|
|
98
|
+
).toMatchInlineSnapshot(`
|
|
97
99
|
{
|
|
98
100
|
"bindValues": [
|
|
99
101
|
"id1",
|
|
@@ -386,37 +386,49 @@ export namespace ClientDocumentTableDef {
|
|
|
386
386
|
}
|
|
387
387
|
}
|
|
388
388
|
|
|
389
|
-
export type GetOptions<TTableDef extends TraitAny> =
|
|
390
|
-
|
|
389
|
+
export type GetOptions<TTableDef extends TraitAny> = TTableDef extends ClientDocumentTableDef.Trait<
|
|
390
|
+
any,
|
|
391
|
+
any,
|
|
392
|
+
any,
|
|
393
|
+
infer TOptions
|
|
394
|
+
>
|
|
395
|
+
? TOptions
|
|
396
|
+
: never
|
|
391
397
|
|
|
392
398
|
export type TraitAny = Trait<any, any, any, any>
|
|
393
399
|
|
|
394
|
-
export type DefaultIdType<TTableDef extends TraitAny> =
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
400
|
+
export type DefaultIdType<TTableDef extends TraitAny> = TTableDef extends ClientDocumentTableDef.Trait<
|
|
401
|
+
any,
|
|
402
|
+
any,
|
|
403
|
+
any,
|
|
404
|
+
infer TOptions
|
|
405
|
+
>
|
|
406
|
+
? TOptions['default']['id'] extends SessionIdSymbol | string
|
|
407
|
+
? TOptions['default']['id']
|
|
399
408
|
: never
|
|
409
|
+
: never
|
|
400
410
|
|
|
401
|
-
export type SetEventDefLike<
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
411
|
+
export type SetEventDefLike<
|
|
412
|
+
TName extends string,
|
|
413
|
+
TType,
|
|
414
|
+
TOptions extends ClientDocumentTableOptions<TType>,
|
|
415
|
+
> = (TOptions['default']['id'] extends undefined // Helper to create partial event
|
|
416
|
+
? (
|
|
417
|
+
args: TOptions['partialSet'] extends false ? TType : Partial<TType>,
|
|
418
|
+
id: string | SessionIdSymbol,
|
|
419
|
+
) => { name: `${TName}Set`; args: { id: string; value: TType } }
|
|
420
|
+
: (
|
|
421
|
+
args: TOptions['partialSet'] extends false ? TType : Partial<TType>,
|
|
422
|
+
id?: string | SessionIdSymbol,
|
|
423
|
+
) => { name: `${TName}Set`; args: { id: string; value: TType } }) & {
|
|
424
|
+
readonly name: `${TName}Set`
|
|
425
|
+
readonly schema: Schema.Schema<any>
|
|
426
|
+
readonly Event: {
|
|
412
427
|
readonly name: `${TName}Set`
|
|
413
|
-
readonly
|
|
414
|
-
readonly Event: {
|
|
415
|
-
readonly name: `${TName}Set`
|
|
416
|
-
readonly args: { id: string; value: TType }
|
|
417
|
-
}
|
|
418
|
-
readonly options: { derived: true; clientOnly: true; facts: undefined }
|
|
428
|
+
readonly args: { id: string; value: TType }
|
|
419
429
|
}
|
|
430
|
+
readonly options: { derived: true; clientOnly: true; facts: undefined }
|
|
431
|
+
}
|
|
420
432
|
|
|
421
433
|
export type SetEventDef<TName extends string, TType, TOptions extends ClientDocumentTableOptions<TType>> = EventDef<
|
|
422
434
|
TName,
|
|
@@ -17,7 +17,7 @@ export const isColumnDefinition = (value: unknown): value is ColumnDefinition<an
|
|
|
17
17
|
typeof value === 'object' &&
|
|
18
18
|
value !== null &&
|
|
19
19
|
'columnType' in value &&
|
|
20
|
-
validColumnTypes.includes(value
|
|
20
|
+
validColumnTypes.includes(value.columnType as any)
|
|
21
21
|
)
|
|
22
22
|
}
|
|
23
23
|
|
|
@@ -36,7 +36,7 @@ export type SqlDefaultValue = {
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
export const isSqlDefaultValue = (value: unknown): value is SqlDefaultValue => {
|
|
39
|
-
return typeof value === 'object' && value !== null && 'sql' in value && typeof value
|
|
39
|
+
return typeof value === 'object' && value !== null && 'sql' in value && typeof value.sql === 'string'
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
export type ColDefFn<TColumnType extends FieldColumnType> = {
|
|
@@ -19,12 +19,13 @@ export type DbSchemaInput = Record<string, TableDefinition<any, any>> | Readonly
|
|
|
19
19
|
* - array: we use the table name of each array item (= table definition) as the object key
|
|
20
20
|
* - object: we discard the keys of the input object and use the table name of each object value (= table definition) as the new object key
|
|
21
21
|
*/
|
|
22
|
-
export type DbSchemaFromInputSchema<TSchemaInput extends DbSchemaInput> =
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
22
|
+
export type DbSchemaFromInputSchema<TSchemaInput extends DbSchemaInput> = TSchemaInput extends ReadonlyArray<
|
|
23
|
+
TableDefinition<any, any>
|
|
24
|
+
>
|
|
25
|
+
? { [K in TSchemaInput[number] as K['name']]: K }
|
|
26
|
+
: TSchemaInput extends Record<string, TableDefinition<any, any>>
|
|
27
|
+
? { [K in keyof TSchemaInput as TSchemaInput[K]['name']]: TSchemaInput[K] }
|
|
28
|
+
: never
|
|
28
29
|
|
|
29
30
|
// TODO ensure via runtime check (possibly even via type-level check) that all index names are unique
|
|
30
31
|
export const makeDbSchema = <TDbSchemaInput extends DbSchemaInput>(
|
|
@@ -113,8 +114,12 @@ export type TableDefinition<TName extends string, TColumns extends Columns> = {
|
|
|
113
114
|
|
|
114
115
|
export type Columns = Record<string, ColumnDefinition<any, any>>
|
|
115
116
|
|
|
116
|
-
export type IsSingleColumn<TColumns extends Columns | ColumnDefinition<any, any>> =
|
|
117
|
-
|
|
117
|
+
export type IsSingleColumn<TColumns extends Columns | ColumnDefinition<any, any>> = TColumns extends ColumnDefinition<
|
|
118
|
+
any,
|
|
119
|
+
any
|
|
120
|
+
>
|
|
121
|
+
? true
|
|
122
|
+
: false
|
|
118
123
|
|
|
119
124
|
/**
|
|
120
125
|
* NOTE this is only needed to avoid a TS limitation where `StructSchemaForColumns` in the default case
|
|
@@ -207,8 +212,9 @@ export namespace FromColumns {
|
|
|
207
212
|
|
|
208
213
|
export type RequiredInsertColumnNames<TColumns extends Columns> = keyof RequiredInsertColumns<TColumns>
|
|
209
214
|
|
|
210
|
-
export type RequiresInsertValues<TColumns extends Columns> =
|
|
211
|
-
|
|
215
|
+
export type RequiresInsertValues<TColumns extends Columns> = RequiredInsertColumnNames<TColumns> extends never
|
|
216
|
+
? false
|
|
217
|
+
: true
|
|
212
218
|
|
|
213
219
|
export type InsertRowDecoded<TColumns extends Columns> = Types.Simplify<
|
|
214
220
|
Pick<RowDecodedAll<TColumns>, RequiredInsertColumnNames<TColumns>> &
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
// Based on https://stackoverflow.com/a/7616484
|
|
2
2
|
export const hashCode = (str: string) => {
|
|
3
|
-
let hash = 0
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
let hash = 0
|
|
4
|
+
let i: number
|
|
5
|
+
let chr: number
|
|
6
6
|
if (str.length === 0) return hash
|
|
7
7
|
for (i = 0; i < str.length; i++) {
|
|
8
|
-
// eslint-disable-next-line unicorn/prefer-code-point
|
|
9
8
|
chr = str.charCodeAt(i)
|
|
10
9
|
hash = (hash << 5) - hash + chr
|
|
11
10
|
hash = Math.trunc(hash) // Convert to 32bit integer
|
|
@@ -6,17 +6,17 @@ import type { InternalState } from '../../schema.js'
|
|
|
6
6
|
import { ClientDocumentTableDefSymbol, tableIsClientDocumentTable } from './client-document-def.js'
|
|
7
7
|
import { SqliteAst } from './db-schema/mod.js'
|
|
8
8
|
import { stateSystemTables } from './system-tables.js'
|
|
9
|
-
import {
|
|
9
|
+
import type { TableDef, TableDefBase } from './table-def.js'
|
|
10
10
|
|
|
11
|
-
export * from '
|
|
11
|
+
export * from '../../EventDef.js'
|
|
12
12
|
export {
|
|
13
|
-
ClientDocumentTableDefSymbol,
|
|
14
|
-
tableIsClientDocumentTable,
|
|
15
|
-
clientDocument,
|
|
16
13
|
type ClientDocumentTableDef,
|
|
14
|
+
ClientDocumentTableDefSymbol,
|
|
17
15
|
type ClientDocumentTableOptions,
|
|
16
|
+
clientDocument,
|
|
17
|
+
tableIsClientDocumentTable,
|
|
18
18
|
} from './client-document-def.js'
|
|
19
|
-
export * from '
|
|
19
|
+
export * from './table-def.js'
|
|
20
20
|
|
|
21
21
|
export const makeState = <TStateInput extends InputState>(inputSchema: TStateInput): InternalState => {
|
|
22
22
|
const inputTables: ReadonlyArray<TableDef> = Array.isArray(inputSchema.tables)
|