@livestore/common 0.3.0-dev.2 → 0.3.0-dev.22
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/__tests__/fixture.d.ts +21 -21
- package/dist/adapter-types.d.ts +97 -53
- package/dist/adapter-types.d.ts.map +1 -1
- package/dist/adapter-types.js +17 -0
- package/dist/adapter-types.js.map +1 -1
- package/dist/bounded-collections.d.ts +1 -1
- package/dist/bounded-collections.d.ts.map +1 -1
- package/dist/debug-info.d.ts +1 -1
- package/dist/debug-info.d.ts.map +1 -1
- package/dist/derived-mutations.d.ts +5 -5
- package/dist/derived-mutations.d.ts.map +1 -1
- package/dist/derived-mutations.js +3 -3
- package/dist/derived-mutations.js.map +1 -1
- package/dist/derived-mutations.test.js.map +1 -1
- package/dist/devtools/devtools-messages-client-session.d.ts +389 -0
- package/dist/devtools/devtools-messages-client-session.d.ts.map +1 -0
- package/dist/devtools/devtools-messages-client-session.js +96 -0
- package/dist/devtools/devtools-messages-client-session.js.map +1 -0
- package/dist/devtools/devtools-messages-common.d.ts +61 -0
- package/dist/devtools/devtools-messages-common.d.ts.map +1 -0
- package/dist/devtools/devtools-messages-common.js +54 -0
- package/dist/devtools/devtools-messages-common.js.map +1 -0
- package/dist/devtools/devtools-messages-leader.d.ts +393 -0
- package/dist/devtools/devtools-messages-leader.d.ts.map +1 -0
- package/dist/devtools/devtools-messages-leader.js +148 -0
- package/dist/devtools/devtools-messages-leader.js.map +1 -0
- package/dist/devtools/devtools-messages.d.ts +3 -592
- package/dist/devtools/devtools-messages.d.ts.map +1 -1
- package/dist/devtools/devtools-messages.js +3 -171
- package/dist/devtools/devtools-messages.js.map +1 -1
- package/dist/devtools/devtools-sessioninfo.d.ts +28 -0
- package/dist/devtools/devtools-sessioninfo.d.ts.map +1 -0
- package/dist/devtools/devtools-sessioninfo.js +34 -0
- package/dist/devtools/devtools-sessioninfo.js.map +1 -0
- package/dist/devtools/mod.d.ts +39 -0
- package/dist/devtools/mod.d.ts.map +1 -0
- package/dist/devtools/mod.js +27 -0
- package/dist/devtools/mod.js.map +1 -0
- package/dist/index.d.ts +2 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/init-singleton-tables.d.ts +2 -2
- package/dist/init-singleton-tables.d.ts.map +1 -1
- package/dist/init-singleton-tables.js.map +1 -1
- package/dist/leader-thread/LeaderSyncProcessor.d.ts +39 -0
- package/dist/leader-thread/LeaderSyncProcessor.d.ts.map +1 -0
- package/dist/leader-thread/LeaderSyncProcessor.js +527 -0
- package/dist/leader-thread/LeaderSyncProcessor.js.map +1 -0
- package/dist/leader-thread/apply-mutation.d.ts +5 -2
- package/dist/leader-thread/apply-mutation.d.ts.map +1 -1
- package/dist/leader-thread/apply-mutation.js +55 -35
- package/dist/leader-thread/apply-mutation.js.map +1 -1
- package/dist/leader-thread/connection.d.ts +34 -6
- package/dist/leader-thread/connection.d.ts.map +1 -1
- package/dist/leader-thread/connection.js +22 -7
- package/dist/leader-thread/connection.js.map +1 -1
- package/dist/leader-thread/leader-worker-devtools.d.ts +1 -1
- package/dist/leader-thread/leader-worker-devtools.d.ts.map +1 -1
- package/dist/leader-thread/leader-worker-devtools.js +147 -124
- package/dist/leader-thread/leader-worker-devtools.js.map +1 -1
- package/dist/leader-thread/make-leader-thread-layer.d.ts +12 -11
- package/dist/leader-thread/make-leader-thread-layer.d.ts.map +1 -1
- package/dist/leader-thread/make-leader-thread-layer.js +55 -18
- package/dist/leader-thread/make-leader-thread-layer.js.map +1 -1
- package/dist/leader-thread/mutationlog.d.ts +6 -19
- package/dist/leader-thread/mutationlog.d.ts.map +1 -1
- package/dist/leader-thread/mutationlog.js +12 -9
- package/dist/leader-thread/mutationlog.js.map +1 -1
- package/dist/leader-thread/pull-queue-set.d.ts +3 -3
- package/dist/leader-thread/pull-queue-set.d.ts.map +1 -1
- package/dist/leader-thread/pull-queue-set.js +9 -0
- package/dist/leader-thread/pull-queue-set.js.map +1 -1
- package/dist/leader-thread/recreate-db.d.ts +4 -2
- package/dist/leader-thread/recreate-db.d.ts.map +1 -1
- package/dist/leader-thread/recreate-db.js +32 -21
- package/dist/leader-thread/recreate-db.js.map +1 -1
- package/dist/leader-thread/shutdown-channel.d.ts +2 -5
- package/dist/leader-thread/shutdown-channel.d.ts.map +1 -1
- package/dist/leader-thread/shutdown-channel.js +2 -4
- package/dist/leader-thread/shutdown-channel.js.map +1 -1
- package/dist/leader-thread/types.d.ts +58 -26
- package/dist/leader-thread/types.d.ts.map +1 -1
- package/dist/leader-thread/types.js +1 -3
- package/dist/leader-thread/types.js.map +1 -1
- package/dist/mutation.d.ts +9 -2
- package/dist/mutation.d.ts.map +1 -1
- package/dist/mutation.js +5 -5
- package/dist/mutation.js.map +1 -1
- package/dist/otel.d.ts +2 -0
- package/dist/otel.d.ts.map +1 -1
- package/dist/otel.js +5 -0
- package/dist/otel.js.map +1 -1
- package/dist/query-builder/api.d.ts +3 -3
- package/dist/query-builder/api.d.ts.map +1 -1
- package/dist/query-builder/impl.d.ts +4 -4
- package/dist/query-builder/impl.d.ts.map +1 -1
- package/dist/query-builder/impl.js.map +1 -1
- package/dist/query-builder/impl.test.js +16 -1
- package/dist/query-builder/impl.test.js.map +1 -1
- package/dist/query-info.d.ts +3 -3
- package/dist/query-info.d.ts.map +1 -1
- package/dist/rehydrate-from-mutationlog.d.ts +5 -5
- package/dist/rehydrate-from-mutationlog.d.ts.map +1 -1
- package/dist/rehydrate-from-mutationlog.js +23 -27
- package/dist/rehydrate-from-mutationlog.js.map +1 -1
- package/dist/schema/EventId.d.ts +27 -16
- package/dist/schema/EventId.d.ts.map +1 -1
- package/dist/schema/EventId.js +36 -11
- package/dist/schema/EventId.js.map +1 -1
- package/dist/schema/EventId.test.d.ts +2 -0
- package/dist/schema/EventId.test.d.ts.map +1 -0
- package/dist/schema/EventId.test.js +11 -0
- package/dist/schema/EventId.test.js.map +1 -0
- package/dist/schema/MutationEvent.d.ts +76 -82
- package/dist/schema/MutationEvent.d.ts.map +1 -1
- package/dist/schema/MutationEvent.js +53 -20
- package/dist/schema/MutationEvent.js.map +1 -1
- package/dist/schema/db-schema/ast/sqlite.d.ts +69 -0
- package/dist/schema/db-schema/ast/sqlite.d.ts.map +1 -0
- package/dist/schema/db-schema/ast/sqlite.js +71 -0
- package/dist/schema/db-schema/ast/sqlite.js.map +1 -0
- package/dist/schema/db-schema/ast/validate.d.ts +3 -0
- package/dist/schema/db-schema/ast/validate.d.ts.map +1 -0
- package/dist/schema/db-schema/ast/validate.js +12 -0
- package/dist/schema/db-schema/ast/validate.js.map +1 -0
- package/dist/schema/db-schema/dsl/field-defs.d.ts +90 -0
- package/dist/schema/db-schema/dsl/field-defs.d.ts.map +1 -0
- package/dist/schema/db-schema/dsl/field-defs.js +87 -0
- package/dist/schema/db-schema/dsl/field-defs.js.map +1 -0
- package/dist/schema/db-schema/dsl/field-defs.test.d.ts +2 -0
- package/dist/schema/db-schema/dsl/field-defs.test.d.ts.map +1 -0
- package/dist/schema/db-schema/dsl/field-defs.test.js +29 -0
- package/dist/schema/db-schema/dsl/field-defs.test.js.map +1 -0
- package/dist/schema/db-schema/dsl/mod.d.ts +88 -0
- package/dist/schema/db-schema/dsl/mod.d.ts.map +1 -0
- package/dist/schema/db-schema/dsl/mod.js +35 -0
- package/dist/schema/db-schema/dsl/mod.js.map +1 -0
- package/dist/schema/db-schema/hash.d.ts +2 -0
- package/dist/schema/db-schema/hash.d.ts.map +1 -0
- package/dist/schema/db-schema/hash.js +14 -0
- package/dist/schema/db-schema/hash.js.map +1 -0
- package/dist/schema/db-schema/mod.d.ts +3 -0
- package/dist/schema/db-schema/mod.d.ts.map +1 -0
- package/dist/schema/db-schema/mod.js +3 -0
- package/dist/schema/db-schema/mod.js.map +1 -0
- package/dist/schema/mod.d.ts +1 -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/mutations.d.ts +8 -9
- package/dist/schema/mutations.d.ts.map +1 -1
- package/dist/schema/mutations.js +2 -2
- package/dist/schema/mutations.js.map +1 -1
- package/dist/schema/schema-helpers.d.ts.map +1 -1
- package/dist/schema/schema-helpers.js +1 -1
- package/dist/schema/schema-helpers.js.map +1 -1
- package/dist/schema/schema.d.ts +5 -2
- package/dist/schema/schema.d.ts.map +1 -1
- package/dist/schema/schema.js +20 -9
- package/dist/schema/schema.js.map +1 -1
- package/dist/schema/system-tables.d.ts +65 -47
- package/dist/schema/system-tables.d.ts.map +1 -1
- package/dist/schema/system-tables.js +24 -13
- package/dist/schema/system-tables.js.map +1 -1
- package/dist/schema/table-def.d.ts +18 -24
- package/dist/schema/table-def.d.ts.map +1 -1
- package/dist/schema/table-def.js +3 -4
- package/dist/schema/table-def.js.map +1 -1
- package/dist/schema-management/common.d.ts +3 -3
- package/dist/schema-management/common.d.ts.map +1 -1
- package/dist/schema-management/common.js.map +1 -1
- package/dist/schema-management/migrations.d.ts +6 -6
- package/dist/schema-management/migrations.d.ts.map +1 -1
- package/dist/schema-management/migrations.js +13 -8
- package/dist/schema-management/migrations.js.map +1 -1
- package/dist/schema-management/validate-mutation-defs.d.ts.map +1 -1
- package/dist/schema-management/validate-mutation-defs.js +2 -2
- package/dist/schema-management/validate-mutation-defs.js.map +1 -1
- package/dist/sql-queries/misc.d.ts.map +1 -1
- package/dist/sql-queries/sql-queries.d.ts +1 -1
- package/dist/sql-queries/sql-queries.d.ts.map +1 -1
- package/dist/sql-queries/sql-queries.js.map +1 -1
- package/dist/sql-queries/sql-query-builder.d.ts +1 -1
- package/dist/sql-queries/sql-query-builder.d.ts.map +1 -1
- package/dist/sql-queries/sql-query-builder.js.map +1 -1
- package/dist/sql-queries/types.d.ts +2 -1
- package/dist/sql-queries/types.d.ts.map +1 -1
- package/dist/sql-queries/types.js.map +1 -1
- package/dist/sync/{client-session-sync-processor.d.ts → ClientSessionSyncProcessor.d.ts} +25 -14
- package/dist/sync/ClientSessionSyncProcessor.d.ts.map +1 -0
- package/dist/sync/ClientSessionSyncProcessor.js +199 -0
- package/dist/sync/ClientSessionSyncProcessor.js.map +1 -0
- 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/compact-events.d.ts.map +1 -1
- package/dist/sync/next/facts.d.ts.map +1 -1
- package/dist/sync/next/facts.js +1 -1
- package/dist/sync/next/facts.js.map +1 -1
- package/dist/sync/next/history-dag-common.d.ts +3 -4
- package/dist/sync/next/history-dag-common.d.ts.map +1 -1
- package/dist/sync/next/history-dag-common.js +3 -1
- 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 +1 -1
- package/dist/sync/next/history-dag.js.map +1 -1
- package/dist/sync/next/rebase-events.d.ts +6 -4
- package/dist/sync/next/rebase-events.d.ts.map +1 -1
- package/dist/sync/next/rebase-events.js +6 -3
- package/dist/sync/next/rebase-events.js.map +1 -1
- package/dist/sync/next/test/compact-events.calculator.test.js +12 -12
- package/dist/sync/next/test/compact-events.calculator.test.js.map +1 -1
- package/dist/sync/next/test/compact-events.test.js +43 -43
- package/dist/sync/next/test/compact-events.test.js.map +1 -1
- package/dist/sync/next/test/mutation-fixtures.d.ts +4 -4
- package/dist/sync/next/test/mutation-fixtures.d.ts.map +1 -1
- package/dist/sync/next/test/mutation-fixtures.js +12 -16
- package/dist/sync/next/test/mutation-fixtures.js.map +1 -1
- package/dist/sync/sync.d.ts +31 -16
- package/dist/sync/sync.d.ts.map +1 -1
- package/dist/sync/sync.js +7 -3
- package/dist/sync/sync.js.map +1 -1
- package/dist/sync/syncstate.d.ts +177 -44
- package/dist/sync/syncstate.d.ts.map +1 -1
- package/dist/sync/syncstate.js +188 -56
- package/dist/sync/syncstate.js.map +1 -1
- package/dist/sync/syncstate.test.js +162 -92
- package/dist/sync/syncstate.test.js.map +1 -1
- package/dist/sync/validate-push-payload.d.ts +2 -2
- package/dist/sync/validate-push-payload.d.ts.map +1 -1
- package/dist/sync/validate-push-payload.js +2 -2
- package/dist/sync/validate-push-payload.js.map +1 -1
- package/dist/util.d.ts +2 -2
- package/dist/util.d.ts.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 -6
- package/src/adapter-types.ts +80 -56
- package/src/derived-mutations.test.ts +1 -1
- package/src/derived-mutations.ts +13 -9
- package/src/devtools/devtools-messages-client-session.ts +141 -0
- package/src/devtools/devtools-messages-common.ts +106 -0
- package/src/devtools/devtools-messages-leader.ts +192 -0
- package/src/devtools/devtools-messages.ts +3 -243
- package/src/devtools/devtools-sessioninfo.ts +99 -0
- package/src/devtools/mod.ts +36 -0
- package/src/index.ts +2 -8
- package/src/init-singleton-tables.ts +2 -2
- package/src/leader-thread/LeaderSyncProcessor.ts +833 -0
- package/src/leader-thread/apply-mutation.ts +87 -43
- package/src/leader-thread/connection.ts +54 -9
- package/src/leader-thread/leader-worker-devtools.ts +199 -174
- package/src/leader-thread/make-leader-thread-layer.ts +89 -35
- package/src/leader-thread/mutationlog.ts +20 -14
- package/src/leader-thread/pull-queue-set.ts +10 -1
- package/src/leader-thread/recreate-db.ts +38 -25
- package/src/leader-thread/shutdown-channel.ts +2 -4
- package/src/leader-thread/types.ts +68 -34
- package/src/mutation.ts +17 -7
- package/src/otel.ts +8 -0
- package/src/query-builder/api.ts +4 -4
- package/src/query-builder/impl.test.ts +22 -1
- package/src/query-builder/impl.ts +2 -2
- package/src/query-info.ts +3 -3
- package/src/rehydrate-from-mutationlog.ts +28 -34
- package/src/schema/EventId.test.ts +12 -0
- package/src/schema/EventId.ts +49 -15
- package/src/schema/MutationEvent.ts +78 -31
- package/src/schema/db-schema/ast/sqlite.ts +142 -0
- package/src/schema/db-schema/ast/validate.ts +13 -0
- package/src/schema/db-schema/dsl/__snapshots__/field-defs.test.ts.snap +206 -0
- package/src/schema/db-schema/dsl/field-defs.test.ts +35 -0
- package/src/schema/db-schema/dsl/field-defs.ts +242 -0
- package/src/schema/db-schema/dsl/mod.ts +195 -0
- package/src/schema/db-schema/hash.ts +14 -0
- package/src/schema/db-schema/mod.ts +2 -0
- package/src/schema/mod.ts +1 -0
- package/src/schema/mutations.ts +10 -20
- package/src/schema/schema-helpers.ts +1 -1
- package/src/schema/schema.ts +22 -10
- package/src/schema/system-tables.ts +24 -13
- package/src/schema/table-def.ts +17 -17
- package/src/schema-management/common.ts +3 -3
- package/src/schema-management/migrations.ts +19 -15
- package/src/schema-management/validate-mutation-defs.ts +2 -2
- package/src/sql-queries/sql-queries.ts +1 -1
- package/src/sql-queries/sql-query-builder.ts +1 -2
- package/src/sql-queries/types.ts +3 -1
- package/src/sync/ClientSessionSyncProcessor.ts +313 -0
- package/src/sync/index.ts +1 -1
- package/src/sync/next/facts.ts +1 -1
- package/src/sync/next/history-dag-common.ts +5 -1
- package/src/sync/next/history-dag.ts +1 -1
- package/src/sync/next/rebase-events.ts +13 -7
- package/src/sync/next/test/compact-events.calculator.test.ts +12 -12
- package/src/sync/next/test/compact-events.test.ts +43 -43
- package/src/sync/next/test/mutation-fixtures.ts +16 -19
- package/src/sync/sync.ts +26 -10
- package/src/sync/syncstate.test.ts +178 -98
- package/src/sync/syncstate.ts +170 -83
- package/src/sync/validate-push-payload.ts +7 -4
- package/src/version.ts +1 -1
- package/tmp/pack.tgz +0 -0
- package/tsconfig.json +1 -1
- package/dist/devtools/devtools-bridge.d.ts +0 -12
- package/dist/devtools/devtools-bridge.d.ts.map +0 -1
- package/dist/devtools/devtools-bridge.js +0 -2
- package/dist/devtools/devtools-bridge.js.map +0 -1
- package/dist/devtools/index.d.ts +0 -42
- package/dist/devtools/index.d.ts.map +0 -1
- package/dist/devtools/index.js +0 -48
- package/dist/devtools/index.js.map +0 -1
- package/dist/leader-thread/leader-sync-processor.d.ts +0 -47
- package/dist/leader-thread/leader-sync-processor.d.ts.map +0 -1
- package/dist/leader-thread/leader-sync-processor.js +0 -422
- package/dist/leader-thread/leader-sync-processor.js.map +0 -1
- package/dist/sync/client-session-sync-processor.d.ts.map +0 -1
- package/dist/sync/client-session-sync-processor.js +0 -131
- package/dist/sync/client-session-sync-processor.js.map +0 -1
- package/src/devtools/devtools-bridge.ts +0 -13
- package/src/devtools/index.ts +0 -48
- package/src/leader-thread/leader-sync-processor.ts +0 -666
- package/src/sync/client-session-sync-processor.ts +0 -207
package/src/mutation.ts
CHANGED
@@ -8,10 +8,19 @@ import { prepareBindValues } from './util.js'
|
|
8
8
|
|
9
9
|
export const getExecArgsFromMutation = ({
|
10
10
|
mutationDef,
|
11
|
-
|
11
|
+
mutationEvent,
|
12
12
|
}: {
|
13
13
|
mutationDef: MutationDef.Any
|
14
|
-
|
14
|
+
/** Both encoded and decoded mutation events are supported to reduce the number of times we need to decode/encode */
|
15
|
+
mutationEvent:
|
16
|
+
| {
|
17
|
+
decoded: MutationEvent.AnyDecoded | MutationEvent.PartialAnyDecoded
|
18
|
+
encoded: undefined
|
19
|
+
}
|
20
|
+
| {
|
21
|
+
decoded: undefined
|
22
|
+
encoded: MutationEvent.AnyEncoded | MutationEvent.PartialAnyEncoded
|
23
|
+
}
|
15
24
|
}): ReadonlyArray<{
|
16
25
|
statementSql: string
|
17
26
|
bindValues: PreparedBindValues
|
@@ -23,7 +32,9 @@ export const getExecArgsFromMutation = ({
|
|
23
32
|
|
24
33
|
switch (typeof mutationDef.sql) {
|
25
34
|
case 'function': {
|
26
|
-
const
|
35
|
+
const mutationArgsDecoded =
|
36
|
+
mutationEvent.decoded?.args ?? Schema.decodeUnknownSync(mutationDef.schema)(mutationEvent.encoded!.args)
|
37
|
+
const res = mutationDef.sql(mutationArgsDecoded)
|
27
38
|
statementRes = Array.isArray(res) ? res : [res]
|
28
39
|
break
|
29
40
|
}
|
@@ -40,10 +51,9 @@ export const getExecArgsFromMutation = ({
|
|
40
51
|
return statementRes.map((statementRes) => {
|
41
52
|
const statementSql = typeof statementRes === 'string' ? statementRes : statementRes.sql
|
42
53
|
|
43
|
-
const
|
44
|
-
|
45
|
-
|
46
|
-
: statementRes.bindValues
|
54
|
+
const mutationArgsEncoded =
|
55
|
+
mutationEvent.encoded?.args ?? Schema.encodeUnknownSync(mutationDef.schema)(mutationEvent.decoded!.args)
|
56
|
+
const bindValues = typeof statementRes === 'string' ? mutationArgsEncoded : statementRes.bindValues
|
47
57
|
|
48
58
|
const writeTables = typeof statementRes === 'string' ? undefined : statementRes.writeTables
|
49
59
|
|
package/src/otel.ts
CHANGED
@@ -18,3 +18,11 @@ export const provideOtel =
|
|
18
18
|
Effect.provide(TracingLive),
|
19
19
|
)
|
20
20
|
}
|
21
|
+
|
22
|
+
export const getDurationMsFromSpan = (span: otel.Span): number => {
|
23
|
+
const durationHr: [seconds: number, nanos: number] = (span as any)._duration
|
24
|
+
return durationHr[0] * 1000 + durationHr[1] / 1_000_000
|
25
|
+
}
|
26
|
+
|
27
|
+
export const getStartTimeHighResFromSpan = (span: otel.Span): DOMHighResTimeStamp =>
|
28
|
+
(span as any)._performanceStartTime as DOMHighResTimeStamp
|
package/src/query-builder/api.ts
CHANGED
@@ -3,8 +3,8 @@ import { type Option, Predicate, type Schema } from '@livestore/utils/effect'
|
|
3
3
|
|
4
4
|
import type { SessionIdSymbol } from '../adapter-types.js'
|
5
5
|
import type { QueryInfo } from '../query-info.js'
|
6
|
+
import type { SqliteDsl } from '../schema/db-schema/mod.js'
|
6
7
|
import type { DbSchema } from '../schema/mod.js'
|
7
|
-
import type { SqliteDsl } from '../schema/table-def.js'
|
8
8
|
import type { SqlValue } from '../util.js'
|
9
9
|
|
10
10
|
export type QueryBuilderAst = QueryBuilderAst.SelectQuery | QueryBuilderAst.CountQuery | QueryBuilderAst.RowQuery
|
@@ -35,7 +35,7 @@ export namespace QueryBuilderAst {
|
|
35
35
|
export type RowQuery = {
|
36
36
|
readonly _tag: 'RowQuery'
|
37
37
|
readonly tableDef: DbSchema.TableDefBase
|
38
|
-
readonly id: string | SessionIdSymbol
|
38
|
+
readonly id: string | SessionIdSymbol | number
|
39
39
|
readonly insertValues: Record<string, unknown>
|
40
40
|
}
|
41
41
|
|
@@ -252,10 +252,10 @@ export namespace QueryBuilder {
|
|
252
252
|
? (_: 'Error: Need to enable deriveMutations to use row()') => any
|
253
253
|
: TTableDef['options']['requiredInsertColumnNames'] extends never
|
254
254
|
? (
|
255
|
-
id: string | SessionIdSymbol,
|
255
|
+
id: string | SessionIdSymbol | number,
|
256
256
|
) => QueryBuilder<RowQuery.Result<TTableDef>, TTableDef, QueryBuilder.ApiFeature, QueryInfo.Row>
|
257
257
|
: <TOptions extends RowQuery.RequiredColumnsOptions<TTableDef>>(
|
258
|
-
id: string | SessionIdSymbol,
|
258
|
+
id: string | SessionIdSymbol | number,
|
259
259
|
opts: TOptions,
|
260
260
|
) => QueryBuilder<RowQuery.Result<TTableDef>, TTableDef, QueryBuilder.ApiFeature, QueryInfo.Row>
|
261
261
|
}
|
@@ -18,13 +18,23 @@ const todos = DbSchema.table(
|
|
18
18
|
{ deriveMutations: true },
|
19
19
|
)
|
20
20
|
|
21
|
+
const todosWithIntId = DbSchema.table(
|
22
|
+
'todos_with_int_id',
|
23
|
+
{
|
24
|
+
id: DbSchema.integer({ primaryKey: true }),
|
25
|
+
text: DbSchema.text({ default: '', nullable: false }),
|
26
|
+
status: DbSchema.text({ schema: Schema.Literal('active', 'completed') }),
|
27
|
+
},
|
28
|
+
{ deriveMutations: true },
|
29
|
+
)
|
30
|
+
|
21
31
|
const comments = DbSchema.table('comments', {
|
22
32
|
id: DbSchema.text({ primaryKey: true }),
|
23
33
|
text: DbSchema.text({ default: '', nullable: false }),
|
24
34
|
todoId: DbSchema.text({}),
|
25
35
|
})
|
26
36
|
|
27
|
-
const db = { todos: todos.query, comments: comments.query }
|
37
|
+
const db = { todos: todos.query, todosWithIntId: todosWithIntId.query, comments: comments.query }
|
28
38
|
|
29
39
|
describe('query builder', () => {
|
30
40
|
describe('result schema', () => {
|
@@ -204,6 +214,17 @@ describe('query builder', () => {
|
|
204
214
|
}
|
205
215
|
`)
|
206
216
|
})
|
217
|
+
|
218
|
+
it('should handle row queries with numbers', () => {
|
219
|
+
expect(db.todosWithIntId.row(123, { insertValues: { status: 'active' } }).asSql()).toMatchInlineSnapshot(`
|
220
|
+
{
|
221
|
+
"bindValues": [
|
222
|
+
123,
|
223
|
+
],
|
224
|
+
"query": "SELECT * FROM 'todos_with_int_id' WHERE id = ?",
|
225
|
+
}
|
226
|
+
`)
|
227
|
+
})
|
207
228
|
})
|
208
229
|
})
|
209
230
|
|
@@ -128,12 +128,12 @@ export const makeQueryBuilder = <TResult, TTableDef extends DbSchema.TableDefBas
|
|
128
128
|
// eslint-disable-next-line prefer-rest-params
|
129
129
|
const params = [...arguments]
|
130
130
|
|
131
|
-
let id: string
|
131
|
+
let id: string | number
|
132
132
|
|
133
133
|
if (tableDef.options.isSingleton) {
|
134
134
|
id = tableDef.sqliteDef.columns.id!.default.pipe(Option.getOrThrow)
|
135
135
|
} else {
|
136
|
-
id = params[0] as string
|
136
|
+
id = params[0] as string | number
|
137
137
|
if (id === undefined) {
|
138
138
|
invalidQueryBuilder(`Id missing for row query on non-singleton table ${tableDef.sqliteDef.name}`)
|
139
139
|
}
|
package/src/query-info.ts
CHANGED
@@ -24,20 +24,20 @@ export namespace QueryInfo {
|
|
24
24
|
export type Row = {
|
25
25
|
_tag: 'Row'
|
26
26
|
table: DbSchema.TableDefBase
|
27
|
-
id: string | SessionIdSymbol
|
27
|
+
id: string | SessionIdSymbol | number
|
28
28
|
}
|
29
29
|
|
30
30
|
export type Col = {
|
31
31
|
_tag: 'Col'
|
32
32
|
table: DbSchema.TableDefBase
|
33
|
-
id: string | SessionIdSymbol
|
33
|
+
id: string | SessionIdSymbol | number
|
34
34
|
column: string
|
35
35
|
}
|
36
36
|
|
37
37
|
export type ColJsonValue = {
|
38
38
|
_tag: 'ColJsonValue'
|
39
39
|
table: DbSchema.TableDefBase
|
40
|
-
id: string | SessionIdSymbol
|
40
|
+
id: string | SessionIdSymbol | number
|
41
41
|
column: string
|
42
42
|
/**
|
43
43
|
* example: `$.tabs[3].items[2]` (`$` referring to the column value)
|
@@ -1,22 +1,23 @@
|
|
1
|
-
import {
|
1
|
+
import { memoizeByRef } from '@livestore/utils'
|
2
2
|
import { Chunk, Effect, Option, Schema, Stream } from '@livestore/utils/effect'
|
3
3
|
|
4
|
-
import { type MigrationOptionsFromMutationLog, type
|
5
|
-
import {
|
4
|
+
import { type MigrationOptionsFromMutationLog, type SqliteDb, UnexpectedError } from './adapter-types.js'
|
5
|
+
import { makeApplyMutation } from './leader-thread/apply-mutation.js'
|
6
6
|
import type { LiveStoreSchema, MutationDef, MutationEvent, MutationLogMetaRow } from './schema/mod.js'
|
7
|
-
import { EventId, MUTATION_LOG_META_TABLE } from './schema/mod.js'
|
7
|
+
import { EventId, getMutationDef, MUTATION_LOG_META_TABLE } from './schema/mod.js'
|
8
8
|
import type { PreparedBindValues } from './util.js'
|
9
9
|
import { sql } from './util.js'
|
10
10
|
|
11
11
|
export const rehydrateFromMutationLog = ({
|
12
12
|
logDb,
|
13
|
-
db
|
13
|
+
// TODO re-use this db when bringing back the boot in-memory db implementation
|
14
|
+
// db,
|
14
15
|
schema,
|
15
16
|
migrationOptions,
|
16
17
|
onProgress,
|
17
18
|
}: {
|
18
|
-
logDb:
|
19
|
-
db:
|
19
|
+
logDb: SqliteDb
|
20
|
+
db: SqliteDb
|
20
21
|
schema: LiveStoreSchema
|
21
22
|
migrationOptions: MigrationOptionsFromMutationLog
|
22
23
|
onProgress: (_: { done: number; total: number }) => Effect.Effect<void>
|
@@ -28,9 +29,11 @@ export const rehydrateFromMutationLog = ({
|
|
28
29
|
|
29
30
|
const hashMutation = memoizeByRef((mutation: MutationDef.Any) => Schema.hash(mutation.schema))
|
30
31
|
|
32
|
+
const applyMutation = yield* makeApplyMutation
|
33
|
+
|
31
34
|
const processMutation = (row: MutationLogMetaRow) =>
|
32
35
|
Effect.gen(function* () {
|
33
|
-
const mutationDef = schema
|
36
|
+
const mutationDef = getMutationDef(schema, row.mutation)
|
34
37
|
|
35
38
|
if (migrationOptions.excludeMutations?.has(row.mutation) === true) return
|
36
39
|
|
@@ -40,7 +43,10 @@ export const rehydrateFromMutationLog = ({
|
|
40
43
|
)
|
41
44
|
}
|
42
45
|
|
43
|
-
const
|
46
|
+
const args = JSON.parse(row.argsJson)
|
47
|
+
|
48
|
+
// Checking whether the schema has changed in an incompatible way
|
49
|
+
yield* Schema.decodeUnknown(mutationDef.schema)(args).pipe(
|
44
50
|
Effect.mapError((cause) =>
|
45
51
|
UnexpectedError.make({
|
46
52
|
cause,
|
@@ -53,36 +59,24 @@ This likely means the schema has changed in an incompatible way.
|
|
53
59
|
),
|
54
60
|
)
|
55
61
|
|
56
|
-
const
|
57
|
-
id: { global: row.idGlobal,
|
58
|
-
parentId: { global: row.parentIdGlobal,
|
62
|
+
const mutationEventEncoded = {
|
63
|
+
id: { global: row.idGlobal, client: row.idClient },
|
64
|
+
parentId: { global: row.parentIdGlobal, client: row.parentIdClient },
|
59
65
|
mutation: row.mutation,
|
60
|
-
args
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
onRowsChanged: (rowsChanged: number) => {
|
67
|
-
if (rowsChanged === 0 && migrationOptions.logging?.excludeAffectedRows?.(statementSql) !== true) {
|
68
|
-
console.warn(`Mutation "${mutationDef.name}" did not affect any rows:`, statementSql, bindValues)
|
69
|
-
}
|
70
|
-
},
|
71
|
-
})
|
72
|
-
|
73
|
-
for (const { statementSql, bindValues } of execArgsArr) {
|
74
|
-
// TODO cache prepared statements for mutations
|
75
|
-
db.execute(statementSql, bindValues, isDevEnv() ? makeExecuteOptions(statementSql, bindValues) : undefined)
|
76
|
-
// console.log(`Re-executed mutation ${mutationSql}`, bindValues)
|
77
|
-
}
|
66
|
+
args,
|
67
|
+
clientId: row.clientId,
|
68
|
+
sessionId: row.sessionId ?? undefined,
|
69
|
+
} satisfies MutationEvent.AnyEncoded
|
70
|
+
|
71
|
+
yield* applyMutation(mutationEventEncoded, { skipMutationLog: true })
|
78
72
|
}).pipe(Effect.withSpan(`@livestore/common:rehydrateFromMutationLog:processMutation`))
|
79
73
|
|
80
74
|
const CHUNK_SIZE = 100
|
81
75
|
|
82
76
|
const stmt = logDb.prepare(sql`\
|
83
77
|
SELECT * FROM ${MUTATION_LOG_META_TABLE}
|
84
|
-
WHERE idGlobal > $idGlobal OR (idGlobal = $idGlobal AND
|
85
|
-
ORDER BY idGlobal ASC,
|
78
|
+
WHERE idGlobal > $idGlobal OR (idGlobal = $idGlobal AND idClient > $idClient)
|
79
|
+
ORDER BY idGlobal ASC, idClient ASC
|
86
80
|
LIMIT ${CHUNK_SIZE}
|
87
81
|
`)
|
88
82
|
|
@@ -96,14 +90,14 @@ LIMIT ${CHUNK_SIZE}
|
|
96
90
|
|
97
91
|
const lastId = Chunk.isChunk(item)
|
98
92
|
? Chunk.last(item).pipe(
|
99
|
-
Option.map((_) => ({ global: _.idGlobal,
|
93
|
+
Option.map((_) => ({ global: _.idGlobal, client: _.idClient })),
|
100
94
|
Option.getOrElse(() => EventId.ROOT),
|
101
95
|
)
|
102
96
|
: EventId.ROOT
|
103
97
|
const nextItem = Chunk.fromIterable(
|
104
98
|
stmt.select<MutationLogMetaRow>({
|
105
99
|
$idGlobal: lastId?.global,
|
106
|
-
$
|
100
|
+
$idClient: lastId?.client,
|
107
101
|
} as any as PreparedBindValues),
|
108
102
|
)
|
109
103
|
const prevItem = Chunk.isChunk(item) ? item : Chunk.empty()
|
@@ -0,0 +1,12 @@
|
|
1
|
+
import { Vitest } from '@livestore/utils/node-vitest'
|
2
|
+
import { expect } from 'vitest'
|
3
|
+
|
4
|
+
import { EventId } from './mod.js'
|
5
|
+
|
6
|
+
Vitest.describe('EventId', () => {
|
7
|
+
Vitest.test('nextPair', () => {
|
8
|
+
const e_0_0 = EventId.make({ global: 0, client: 0 })
|
9
|
+
expect(EventId.nextPair(e_0_0, false).id).toStrictEqual({ global: 1, client: 0 })
|
10
|
+
expect(EventId.nextPair(e_0_0, true).id).toStrictEqual({ global: 0, client: 1 })
|
11
|
+
})
|
12
|
+
})
|
package/src/schema/EventId.ts
CHANGED
@@ -1,16 +1,26 @@
|
|
1
|
-
import { Schema } from '@livestore/utils/effect'
|
1
|
+
import { Brand, Schema } from '@livestore/utils/effect'
|
2
|
+
|
3
|
+
export type ClientEventId = Brand.Branded<number, 'ClientEventId'>
|
4
|
+
export const localEventId = Brand.nominal<ClientEventId>()
|
5
|
+
export const ClientEventId = Schema.fromBrand(localEventId)(Schema.Int)
|
6
|
+
|
7
|
+
export type GlobalEventId = Brand.Branded<number, 'GlobalEventId'>
|
8
|
+
export const globalEventId = Brand.nominal<GlobalEventId>()
|
9
|
+
export const GlobalEventId = Schema.fromBrand(globalEventId)(Schema.Int)
|
10
|
+
|
11
|
+
export const clientDefault = 0 as any as ClientEventId
|
2
12
|
|
3
13
|
/**
|
4
14
|
* LiveStore event id value consisting of a globally unique event sequence number
|
5
|
-
* and a
|
15
|
+
* and a client sequence number.
|
6
16
|
*
|
7
|
-
* The
|
17
|
+
* The client sequence number is only used for clientOnly mutations and starts from 0 for each global sequence number.
|
8
18
|
*/
|
9
|
-
export type EventId = { global:
|
19
|
+
export type EventId = { global: GlobalEventId; client: ClientEventId }
|
10
20
|
|
11
21
|
export const EventId = Schema.Struct({
|
12
|
-
global:
|
13
|
-
|
22
|
+
global: GlobalEventId,
|
23
|
+
client: ClientEventId,
|
14
24
|
}).annotations({ title: 'LiveStore.EventId' })
|
15
25
|
|
16
26
|
/**
|
@@ -20,27 +30,51 @@ export const compare = (a: EventId, b: EventId) => {
|
|
20
30
|
if (a.global !== b.global) {
|
21
31
|
return a.global - b.global
|
22
32
|
}
|
23
|
-
return a.
|
33
|
+
return a.client - b.client
|
24
34
|
}
|
25
35
|
|
26
|
-
|
36
|
+
/**
|
37
|
+
* Convert an event id to a string representation.
|
38
|
+
*/
|
39
|
+
export const toString = (id: EventId) => `(${id.global},${id.client})`
|
40
|
+
|
41
|
+
/**
|
42
|
+
* Convert a string representation of an event id to an event id.
|
43
|
+
*/
|
44
|
+
export const fromString = (str: string): EventId => {
|
45
|
+
const [global, client] = str.slice(1, -1).split(',').map(Number)
|
46
|
+
if (global === undefined || client === undefined) {
|
47
|
+
throw new Error('Invalid event id string')
|
48
|
+
}
|
49
|
+
return { global, client } as EventId
|
50
|
+
}
|
51
|
+
|
52
|
+
export const isEqual = (a: EventId, b: EventId) => a.global === b.global && a.client === b.client
|
27
53
|
|
28
54
|
export type EventIdPair = { id: EventId; parentId: EventId }
|
29
55
|
|
30
|
-
export const ROOT = { global: -1,
|
56
|
+
export const ROOT = { global: -1 as any as GlobalEventId, client: clientDefault } satisfies EventId
|
31
57
|
|
32
58
|
export const isGreaterThan = (a: EventId, b: EventId) => {
|
33
|
-
return a.global > b.global || (a.global === b.global && a.
|
59
|
+
return a.global > b.global || (a.global === b.global && a.client > b.client)
|
60
|
+
}
|
61
|
+
|
62
|
+
export const isGreaterThanOrEqual = (a: EventId, b: EventId) => {
|
63
|
+
return a.global > b.global || (a.global === b.global && a.client >= b.client)
|
64
|
+
}
|
65
|
+
|
66
|
+
export const make = (id: EventId | typeof EventId.Encoded): EventId => {
|
67
|
+
return Schema.is(EventId)(id) ? id : Schema.decodeSync(EventId)(id)
|
34
68
|
}
|
35
69
|
|
36
|
-
export const nextPair = (id: EventId, isLocal: boolean) => {
|
70
|
+
export const nextPair = (id: EventId, isLocal: boolean): EventIdPair => {
|
37
71
|
if (isLocal) {
|
38
|
-
return { id: { global: id.global,
|
72
|
+
return { id: { global: id.global, client: (id.client + 1) as any as ClientEventId }, parentId: id }
|
39
73
|
}
|
40
74
|
|
41
75
|
return {
|
42
|
-
id: { global: id.global + 1,
|
43
|
-
// NOTE we always point to `
|
44
|
-
parentId: { global: id.global,
|
76
|
+
id: { global: (id.global + 1) as any as GlobalEventId, client: clientDefault },
|
77
|
+
// NOTE we always point to `client: 0` for non-clientOnly mutations
|
78
|
+
parentId: { global: id.global, client: clientDefault },
|
45
79
|
}
|
46
80
|
}
|
@@ -1,5 +1,4 @@
|
|
1
1
|
import { memoizeByRef } from '@livestore/utils'
|
2
|
-
import type { Deferred } from '@livestore/utils/effect'
|
3
2
|
import { Schema } from '@livestore/utils/effect'
|
4
3
|
|
5
4
|
import * as EventId from './EventId.js'
|
@@ -11,7 +10,7 @@ export type MutationEventPartial<TMutationsDef extends MutationDef.Any> = {
|
|
11
10
|
args: Schema.Schema.Type<TMutationsDef['schema']>
|
12
11
|
}
|
13
12
|
|
14
|
-
export type
|
13
|
+
export type PartialEncoded<TMutationsDef extends MutationDef.Any> = {
|
15
14
|
mutation: TMutationsDef['name']
|
16
15
|
args: Schema.Schema.Encoded<TMutationsDef['schema']>
|
17
16
|
}
|
@@ -21,6 +20,8 @@ export type MutationEvent<TMutationsDef extends MutationDef.Any> = {
|
|
21
20
|
args: Schema.Schema.Type<TMutationsDef['schema']>
|
22
21
|
id: EventId.EventId
|
23
22
|
parentId: EventId.EventId
|
23
|
+
clientId: string
|
24
|
+
sessionId: string | undefined
|
24
25
|
}
|
25
26
|
|
26
27
|
export type MutationEventEncoded<TMutationsDef extends MutationDef.Any> = {
|
@@ -28,13 +29,46 @@ export type MutationEventEncoded<TMutationsDef extends MutationDef.Any> = {
|
|
28
29
|
args: Schema.Schema.Encoded<TMutationsDef['schema']>
|
29
30
|
id: EventId.EventId
|
30
31
|
parentId: EventId.EventId
|
32
|
+
clientId: string
|
33
|
+
sessionId: string | undefined
|
31
34
|
}
|
32
35
|
|
33
|
-
export type
|
36
|
+
export type AnyDecoded = MutationEvent<MutationDef.Any>
|
37
|
+
export const AnyDecoded = Schema.Struct({
|
38
|
+
mutation: Schema.String,
|
39
|
+
args: Schema.Any,
|
40
|
+
id: EventId.EventId,
|
41
|
+
parentId: EventId.EventId,
|
42
|
+
clientId: Schema.String,
|
43
|
+
sessionId: Schema.UndefinedOr(Schema.String),
|
44
|
+
}).annotations({ title: 'MutationEvent.AnyDecoded' })
|
45
|
+
|
34
46
|
export type AnyEncoded = MutationEventEncoded<MutationDef.Any>
|
47
|
+
export const AnyEncoded = Schema.Struct({
|
48
|
+
mutation: Schema.String,
|
49
|
+
args: Schema.Any,
|
50
|
+
id: EventId.EventId,
|
51
|
+
parentId: EventId.EventId,
|
52
|
+
clientId: Schema.String,
|
53
|
+
sessionId: Schema.UndefinedOr(Schema.String),
|
54
|
+
}).annotations({ title: 'MutationEvent.AnyEncoded' })
|
55
|
+
|
56
|
+
export const AnyEncodedGlobal = Schema.Struct({
|
57
|
+
mutation: Schema.String,
|
58
|
+
args: Schema.Any,
|
59
|
+
id: EventId.GlobalEventId,
|
60
|
+
parentId: EventId.GlobalEventId,
|
61
|
+
clientId: Schema.String,
|
62
|
+
}).annotations({ title: 'MutationEvent.AnyEncodedGlobal' })
|
63
|
+
export type AnyEncodedGlobal = typeof AnyEncodedGlobal.Type
|
35
64
|
|
36
|
-
export type
|
37
|
-
export type PartialAnyEncoded =
|
65
|
+
export type PartialAnyDecoded = MutationEventPartial<MutationDef.Any>
|
66
|
+
export type PartialAnyEncoded = PartialEncoded<MutationDef.Any>
|
67
|
+
|
68
|
+
export const PartialAnyEncoded = Schema.Struct({
|
69
|
+
mutation: Schema.String,
|
70
|
+
args: Schema.Any,
|
71
|
+
})
|
38
72
|
|
39
73
|
export type PartialForSchema<TSchema extends LiveStoreSchema> = {
|
40
74
|
[K in keyof TSchema['_MutationDefMapType']]: MutationEventPartial<TSchema['_MutationDefMapType'][K]>
|
@@ -44,8 +78,9 @@ export type ForSchema<TSchema extends LiveStoreSchema> = {
|
|
44
78
|
[K in keyof TSchema['_MutationDefMapType']]: MutationEvent<TSchema['_MutationDefMapType'][K]>
|
45
79
|
}[keyof TSchema['_MutationDefMapType']]
|
46
80
|
|
47
|
-
export const isPartialMutationEvent = (
|
48
|
-
|
81
|
+
export const isPartialMutationEvent = (
|
82
|
+
mutationEvent: AnyDecoded | PartialAnyDecoded,
|
83
|
+
): mutationEvent is PartialAnyDecoded => 'id' in mutationEvent === false && 'parentId' in mutationEvent === false
|
49
84
|
|
50
85
|
export type ForMutationDefRecord<TMutationsDefRecord extends MutationDefRecord> = Schema.Schema<
|
51
86
|
{
|
@@ -54,6 +89,8 @@ export type ForMutationDefRecord<TMutationsDefRecord extends MutationDefRecord>
|
|
54
89
|
args: Schema.Schema.Type<TMutationsDefRecord[K]['schema']>
|
55
90
|
id: EventId.EventId
|
56
91
|
parentId: EventId.EventId
|
92
|
+
clientId: string
|
93
|
+
sessionId: string | undefined
|
57
94
|
}
|
58
95
|
}[keyof TMutationsDefRecord],
|
59
96
|
{
|
@@ -62,6 +99,8 @@ export type ForMutationDefRecord<TMutationsDefRecord extends MutationDefRecord>
|
|
62
99
|
args: Schema.Schema.Encoded<TMutationsDefRecord[K]['schema']>
|
63
100
|
id: EventId.EventId
|
64
101
|
parentId: EventId.EventId
|
102
|
+
clientId: string
|
103
|
+
sessionId: string | undefined
|
65
104
|
}
|
66
105
|
}[keyof TMutationsDefRecord]
|
67
106
|
>
|
@@ -85,12 +124,14 @@ export const makeMutationEventSchema = <TSchema extends LiveStoreSchema>(
|
|
85
124
|
schema: TSchema,
|
86
125
|
): ForMutationDefRecord<TSchema['_MutationDefMapType']> =>
|
87
126
|
Schema.Union(
|
88
|
-
...[...schema.mutations.values()].map((def) =>
|
127
|
+
...[...schema.mutations.map.values()].map((def) =>
|
89
128
|
Schema.Struct({
|
90
129
|
mutation: Schema.Literal(def.name),
|
91
130
|
args: def.schema,
|
92
131
|
id: EventId.EventId,
|
93
132
|
parentId: EventId.EventId,
|
133
|
+
clientId: Schema.String,
|
134
|
+
sessionId: Schema.UndefinedOr(Schema.String),
|
94
135
|
}),
|
95
136
|
),
|
96
137
|
).annotations({ title: 'MutationEvent' }) as any
|
@@ -99,48 +140,38 @@ export const makeMutationEventPartialSchema = <TSchema extends LiveStoreSchema>(
|
|
99
140
|
schema: TSchema,
|
100
141
|
): MutationEventPartialSchema<TSchema['_MutationDefMapType']> =>
|
101
142
|
Schema.Union(
|
102
|
-
...[...schema.mutations.values()].map((def) =>
|
143
|
+
...[...schema.mutations.map.values()].map((def) =>
|
103
144
|
Schema.Struct({
|
104
145
|
mutation: Schema.Literal(def.name),
|
105
146
|
args: def.schema,
|
106
147
|
}),
|
107
148
|
),
|
108
|
-
).annotations({ title: '
|
149
|
+
).annotations({ title: 'MutationEventPartial' }) as any
|
109
150
|
|
110
151
|
export const makeMutationEventSchemaMemo = memoizeByRef(makeMutationEventSchema)
|
111
152
|
|
112
|
-
|
113
|
-
mutation: Schema.String,
|
114
|
-
args: Schema.Any,
|
115
|
-
id: EventId.EventId,
|
116
|
-
parentId: EventId.EventId,
|
117
|
-
}).annotations({ title: 'MutationEvent.Any' })
|
118
|
-
|
119
|
-
export const DecodedAny = Schema.typeSchema(Any).annotations({
|
120
|
-
title: 'MutationEvent.DecodedAny',
|
121
|
-
})
|
122
|
-
|
123
|
-
export const EncodedAny = Schema.encodedSchema(Any).annotations({
|
124
|
-
title: 'MutationEvent.EncodedAny',
|
125
|
-
})
|
126
|
-
|
127
|
-
/** Equivalent to EncodedAny but with a meta field and some convenience methods */
|
153
|
+
/** Equivalent to AnyEncoded but with a meta field and some convenience methods */
|
128
154
|
export class EncodedWithMeta extends Schema.Class<EncodedWithMeta>('MutationEvent.EncodedWithMeta')({
|
129
155
|
mutation: Schema.String,
|
130
156
|
args: Schema.Any,
|
131
157
|
id: EventId.EventId,
|
132
158
|
parentId: EventId.EventId,
|
159
|
+
clientId: Schema.String,
|
160
|
+
sessionId: Schema.UndefinedOr(Schema.String),
|
161
|
+
// TODO get rid of `meta` again by cleaning up the usage implementations
|
133
162
|
meta: Schema.optionalWith(
|
134
|
-
Schema.Any as Schema.Schema<{
|
163
|
+
Schema.Any as Schema.Schema<{
|
164
|
+
sessionChangeset?: Uint8Array
|
165
|
+
}>,
|
135
166
|
{ default: () => ({}) },
|
136
167
|
),
|
137
168
|
}) {
|
138
169
|
toJSON = (): any => {
|
139
170
|
// Only used for logging/debugging
|
140
171
|
// - More readable way to print the id + parentId
|
141
|
-
// - not including `meta`
|
172
|
+
// - not including `meta`, `clientId`, `sessionId`
|
142
173
|
return {
|
143
|
-
id: `(${this.id.global},${this.id.
|
174
|
+
id: `(${this.id.global},${this.id.client}) → (${this.parentId.global},${this.parentId.client})`,
|
144
175
|
mutation: this.mutation,
|
145
176
|
args: this.args,
|
146
177
|
}
|
@@ -149,13 +180,29 @@ export class EncodedWithMeta extends Schema.Class<EncodedWithMeta>('MutationEven
|
|
149
180
|
rebase = (parentId: EventId.EventId, isLocal: boolean) =>
|
150
181
|
new EncodedWithMeta({
|
151
182
|
...this,
|
152
|
-
...EventId.nextPair(
|
183
|
+
...EventId.nextPair(parentId, isLocal),
|
153
184
|
})
|
185
|
+
|
186
|
+
static fromGlobal = (mutationEvent: AnyEncodedGlobal) =>
|
187
|
+
new EncodedWithMeta({
|
188
|
+
...mutationEvent,
|
189
|
+
id: { global: mutationEvent.id, client: EventId.clientDefault },
|
190
|
+
parentId: { global: mutationEvent.parentId, client: EventId.clientDefault },
|
191
|
+
sessionId: undefined,
|
192
|
+
})
|
193
|
+
|
194
|
+
toGlobal = (): AnyEncodedGlobal => ({
|
195
|
+
...this,
|
196
|
+
id: this.id.global,
|
197
|
+
parentId: this.parentId.global,
|
198
|
+
})
|
154
199
|
}
|
155
200
|
|
156
201
|
export const isEqualEncoded = (a: AnyEncoded, b: AnyEncoded) =>
|
157
202
|
a.id.global === b.id.global &&
|
158
|
-
a.id.
|
203
|
+
a.id.client === b.id.client &&
|
159
204
|
a.mutation === b.mutation &&
|
205
|
+
a.clientId === b.clientId &&
|
206
|
+
// a.sessionId === b.sessionId &&
|
160
207
|
// TODO use schema equality here
|
161
208
|
JSON.stringify(a.args) === JSON.stringify(b.args)
|