@platforma-sdk/model 1.53.10 → 1.53.13
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/annotations/converter.cjs +11 -11
- package/dist/annotations/converter.cjs.map +1 -1
- package/dist/annotations/converter.d.ts +1 -1
- package/dist/annotations/converter.d.ts.map +1 -1
- package/dist/annotations/converter.js +11 -11
- package/dist/annotations/converter.js.map +1 -1
- package/dist/annotations/index.d.ts +2 -2
- package/dist/annotations/types.d.ts +4 -4
- package/dist/bconfig/index.d.ts +5 -5
- package/dist/bconfig/lambdas.d.ts +7 -7
- package/dist/bconfig/lambdas.d.ts.map +1 -1
- package/dist/bconfig/normalization.cjs.map +1 -1
- package/dist/bconfig/normalization.d.ts +3 -3
- package/dist/bconfig/normalization.js.map +1 -1
- package/dist/bconfig/types.cjs.map +1 -1
- package/dist/bconfig/types.d.ts +2 -2
- package/dist/bconfig/types.d.ts.map +1 -1
- package/dist/bconfig/types.js.map +1 -1
- package/dist/bconfig/util.d.ts +4 -4
- package/dist/bconfig/v3.d.ts +3 -3
- package/dist/block_api_v1.d.ts +2 -2
- package/dist/block_api_v1.d.ts.map +1 -1
- package/dist/block_api_v2.d.ts +2 -2
- package/dist/block_api_v2.d.ts.map +1 -1
- package/dist/block_api_v3.d.ts +3 -3
- package/dist/block_migrations.cjs +10 -10
- package/dist/block_migrations.cjs.map +1 -1
- package/dist/block_migrations.d.ts.map +1 -1
- package/dist/block_migrations.js +10 -10
- package/dist/block_migrations.js.map +1 -1
- package/dist/block_model.cjs +11 -11
- package/dist/block_model.cjs.map +1 -1
- package/dist/block_model.d.ts +8 -8
- package/dist/block_model.d.ts.map +1 -1
- package/dist/block_model.js +11 -11
- package/dist/block_model.js.map +1 -1
- package/dist/block_state_patch.d.ts +2 -2
- package/dist/block_state_util.cjs +1 -1
- package/dist/block_state_util.cjs.map +1 -1
- package/dist/block_state_util.d.ts +3 -3
- package/dist/block_state_util.js +1 -1
- package/dist/block_state_util.js.map +1 -1
- package/dist/block_storage.cjs +10 -10
- package/dist/block_storage.cjs.map +1 -1
- package/dist/block_storage.d.ts +2 -2
- package/dist/block_storage.d.ts.map +1 -1
- package/dist/block_storage.js +10 -10
- package/dist/block_storage.js.map +1 -1
- package/dist/block_storage_vm.cjs +22 -22
- package/dist/block_storage_vm.cjs.map +1 -1
- package/dist/block_storage_vm.d.ts +1 -1
- package/dist/block_storage_vm.d.ts.map +1 -1
- package/dist/block_storage_vm.js +22 -22
- package/dist/block_storage_vm.js.map +1 -1
- package/dist/builder.cjs +32 -23
- package/dist/builder.cjs.map +1 -1
- package/dist/builder.d.ts +7 -7
- package/dist/builder.d.ts.map +1 -1
- package/dist/builder.js +32 -23
- package/dist/builder.js.map +1 -1
- package/dist/components/PFrameForGraphs.cjs +7 -6
- package/dist/components/PFrameForGraphs.cjs.map +1 -1
- package/dist/components/PFrameForGraphs.d.ts +4 -4
- package/dist/components/PFrameForGraphs.d.ts.map +1 -1
- package/dist/components/PFrameForGraphs.js +7 -6
- package/dist/components/PFrameForGraphs.js.map +1 -1
- package/dist/components/PlAnnotations/filter.d.ts +14 -14
- package/dist/components/PlAnnotations/filter.d.ts.map +1 -1
- package/dist/components/PlAnnotations/filters_ui.cjs +46 -46
- package/dist/components/PlAnnotations/filters_ui.cjs.map +1 -1
- package/dist/components/PlAnnotations/filters_ui.d.ts +10 -34
- package/dist/components/PlAnnotations/filters_ui.d.ts.map +1 -1
- package/dist/components/PlAnnotations/filters_ui.js +46 -46
- package/dist/components/PlAnnotations/filters_ui.js.map +1 -1
- package/dist/components/PlAnnotations/index.d.ts +2 -2
- package/dist/components/PlAnnotations/types.d.ts +2 -2
- package/dist/components/PlDataTable.cjs +19 -20
- package/dist/components/PlDataTable.cjs.map +1 -1
- package/dist/components/PlDataTable.d.ts +27 -27
- package/dist/components/PlDataTable.d.ts.map +1 -1
- package/dist/components/PlDataTable.js +19 -20
- package/dist/components/PlDataTable.js.map +1 -1
- package/dist/components/PlMultiSequenceAlignment.cjs +2 -2
- package/dist/components/PlMultiSequenceAlignment.cjs.map +1 -1
- package/dist/components/PlMultiSequenceAlignment.d.ts +6 -6
- package/dist/components/PlMultiSequenceAlignment.d.ts.map +1 -1
- package/dist/components/PlMultiSequenceAlignment.js +2 -2
- package/dist/components/PlMultiSequenceAlignment.js.map +1 -1
- package/dist/components/PlSelectionModel.cjs.map +1 -1
- package/dist/components/PlSelectionModel.d.ts +1 -1
- package/dist/components/PlSelectionModel.js.map +1 -1
- package/dist/components/index.d.ts +5 -5
- package/dist/config/actions.cjs +39 -39
- package/dist/config/actions.cjs.map +1 -1
- package/dist/config/actions.d.ts +9 -9
- package/dist/config/actions.d.ts.map +1 -1
- package/dist/config/actions.js +39 -39
- package/dist/config/actions.js.map +1 -1
- package/dist/config/actions_kinds.d.ts +30 -30
- package/dist/config/actions_kinds.d.ts.map +1 -1
- package/dist/config/index.d.ts +6 -6
- package/dist/config/model.d.ts +28 -28
- package/dist/config/model_meta.d.ts +1 -1
- package/dist/config/type_engine.d.ts +3 -3
- package/dist/config/type_util.d.ts +2 -2
- package/dist/env_value.cjs +1 -1
- package/dist/env_value.cjs.map +1 -1
- package/dist/env_value.js +1 -1
- package/dist/env_value.js.map +1 -1
- package/dist/filters/converter.cjs +36 -32
- package/dist/filters/converter.cjs.map +1 -1
- package/dist/filters/converter.d.ts +2 -2
- package/dist/filters/converter.d.ts.map +1 -1
- package/dist/filters/converter.js +36 -32
- package/dist/filters/converter.js.map +1 -1
- package/dist/filters/index.d.ts +2 -2
- package/dist/filters/types.d.ts +33 -33
- package/dist/filters/types.d.ts.map +1 -1
- package/dist/index.d.ts +24 -24
- package/dist/internal.cjs +7 -7
- package/dist/internal.cjs.map +1 -1
- package/dist/internal.d.ts +4 -4
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +7 -7
- package/dist/internal.js.map +1 -1
- package/dist/package.json.cjs +1 -1
- package/dist/package.json.js +1 -1
- package/dist/pframe.cjs +1 -1
- package/dist/pframe.cjs.map +1 -1
- package/dist/pframe.d.ts +1 -1
- package/dist/pframe.js +1 -1
- package/dist/pframe.js.map +1 -1
- package/dist/pframe_utils/columns.cjs +23 -15
- package/dist/pframe_utils/columns.cjs.map +1 -1
- package/dist/pframe_utils/columns.d.ts +3 -3
- package/dist/pframe_utils/columns.d.ts.map +1 -1
- package/dist/pframe_utils/columns.js +23 -15
- package/dist/pframe_utils/columns.js.map +1 -1
- package/dist/pframe_utils/index.cjs +25 -25
- package/dist/pframe_utils/index.cjs.map +1 -1
- package/dist/pframe_utils/index.d.ts +3 -3
- package/dist/pframe_utils/index.d.ts.map +1 -1
- package/dist/pframe_utils/index.js +25 -25
- package/dist/pframe_utils/index.js.map +1 -1
- package/dist/platforma.d.ts +7 -7
- package/dist/platforma.d.ts.map +1 -1
- package/dist/raw_globals.cjs +4 -1
- package/dist/raw_globals.cjs.map +1 -1
- package/dist/raw_globals.d.ts +2 -2
- package/dist/raw_globals.d.ts.map +1 -1
- package/dist/raw_globals.js +4 -1
- package/dist/raw_globals.js.map +1 -1
- package/dist/ref_util.cjs +4 -4
- package/dist/ref_util.cjs.map +1 -1
- package/dist/ref_util.d.ts +1 -1
- package/dist/ref_util.js +4 -4
- package/dist/ref_util.js.map +1 -1
- package/dist/render/accessor.cjs +24 -24
- package/dist/render/accessor.cjs.map +1 -1
- package/dist/render/accessor.d.ts +10 -10
- package/dist/render/accessor.d.ts.map +1 -1
- package/dist/render/accessor.js +24 -24
- package/dist/render/accessor.js.map +1 -1
- package/dist/render/api.cjs +23 -23
- package/dist/render/api.cjs.map +1 -1
- package/dist/render/api.d.ts +11 -11
- package/dist/render/api.d.ts.map +1 -1
- package/dist/render/api.js +23 -23
- package/dist/render/api.js.map +1 -1
- package/dist/render/future.cjs.map +1 -1
- package/dist/render/future.d.ts +1 -1
- package/dist/render/future.js.map +1 -1
- package/dist/render/index.d.ts +6 -6
- package/dist/render/internal.cjs +4 -4
- package/dist/render/internal.cjs.map +1 -1
- package/dist/render/internal.d.ts +7 -7
- package/dist/render/internal.d.ts.map +1 -1
- package/dist/render/internal.js +4 -4
- package/dist/render/internal.js.map +1 -1
- package/dist/render/traversal_ops.d.ts +1 -1
- package/dist/render/util/axis_filtering.cjs +48 -44
- package/dist/render/util/axis_filtering.cjs.map +1 -1
- package/dist/render/util/axis_filtering.d.ts +2 -2
- package/dist/render/util/axis_filtering.js +48 -44
- package/dist/render/util/axis_filtering.js.map +1 -1
- package/dist/render/util/column_collection.cjs +42 -35
- package/dist/render/util/column_collection.cjs.map +1 -1
- package/dist/render/util/column_collection.d.ts +4 -4
- package/dist/render/util/column_collection.d.ts.map +1 -1
- package/dist/render/util/column_collection.js +42 -35
- package/dist/render/util/column_collection.js.map +1 -1
- package/dist/render/util/index.d.ts +4 -4
- package/dist/render/util/label.cjs +15 -21
- package/dist/render/util/label.cjs.map +1 -1
- package/dist/render/util/label.d.ts +2 -2
- package/dist/render/util/label.d.ts.map +1 -1
- package/dist/render/util/label.js +15 -21
- package/dist/render/util/label.js.map +1 -1
- package/dist/render/util/pcolumn_data.cjs +56 -54
- package/dist/render/util/pcolumn_data.cjs.map +1 -1
- package/dist/render/util/pcolumn_data.d.ts +5 -5
- package/dist/render/util/pcolumn_data.d.ts.map +1 -1
- package/dist/render/util/pcolumn_data.js +56 -54
- package/dist/render/util/pcolumn_data.js.map +1 -1
- package/dist/render/util/pframe_upgraders.cjs +6 -6
- package/dist/render/util/pframe_upgraders.cjs.map +1 -1
- package/dist/render/util/pframe_upgraders.d.ts +1 -1
- package/dist/render/util/pframe_upgraders.d.ts.map +1 -1
- package/dist/render/util/pframe_upgraders.js +6 -6
- package/dist/render/util/pframe_upgraders.js.map +1 -1
- package/dist/render/util/split_selectors.d.ts +1 -1
- package/dist/render/util/split_selectors.d.ts.map +1 -1
- package/dist/sdk_info.cjs.map +1 -1
- package/dist/sdk_info.js.map +1 -1
- package/dist/version.cjs.map +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +23 -21
- package/src/annotations/converter.test.ts +98 -101
- package/src/annotations/converter.ts +21 -17
- package/src/annotations/index.ts +2 -2
- package/src/annotations/types.ts +4 -4
- package/src/bconfig/index.ts +5 -5
- package/src/bconfig/lambdas.ts +10 -12
- package/src/bconfig/normalization.ts +5 -5
- package/src/bconfig/types.ts +3 -5
- package/src/bconfig/util.ts +3 -3
- package/src/bconfig/v3.ts +3 -3
- package/src/block_api_v1.ts +7 -3
- package/src/block_api_v2.ts +7 -3
- package/src/block_api_v3.ts +3 -3
- package/src/block_migrations.test.ts +66 -67
- package/src/block_migrations.ts +16 -16
- package/src/block_model.ts +76 -140
- package/src/block_state_patch.ts +2 -2
- package/src/block_state_util.ts +4 -4
- package/src/block_storage.test.ts +106 -99
- package/src/block_storage.ts +22 -25
- package/src/block_storage_vm.ts +41 -35
- package/src/builder.ts +107 -95
- package/src/components/PFrameForGraphs.test.ts +261 -255
- package/src/components/PFrameForGraphs.ts +35 -22
- package/src/components/PlAnnotations/filter.ts +21 -15
- package/src/components/PlAnnotations/filters_ui.test.ts +230 -73
- package/src/components/PlAnnotations/filters_ui.ts +138 -105
- package/src/components/PlAnnotations/index.ts +2 -2
- package/src/components/PlAnnotations/types.ts +2 -2
- package/src/components/PlDataTable.ts +177 -164
- package/src/components/PlMultiSequenceAlignment.ts +11 -18
- package/src/components/PlSelectionModel.ts +1 -1
- package/src/components/index.ts +5 -5
- package/src/config/actions.ts +64 -59
- package/src/config/actions_kinds.ts +38 -34
- package/src/config/index.ts +6 -6
- package/src/config/model.ts +28 -28
- package/src/config/model_meta.ts +1 -1
- package/src/config/type_engine.ts +3 -3
- package/src/config/type_util.ts +2 -2
- package/src/env_value.ts +2 -2
- package/src/filters/converter.test.ts +185 -144
- package/src/filters/converter.ts +47 -35
- package/src/filters/index.ts +2 -2
- package/src/filters/types.ts +44 -39
- package/src/global.d.ts +1 -1
- package/src/index.ts +24 -24
- package/src/internal.ts +27 -17
- package/src/pframe.ts +3 -3
- package/src/pframe_utils/columns.ts +81 -31
- package/src/pframe_utils/index.ts +65 -43
- package/src/platforma.ts +44 -21
- package/src/raw_globals.ts +13 -7
- package/src/ref_util.ts +6 -6
- package/src/render/accessor.ts +43 -44
- package/src/render/api.ts +102 -78
- package/src/render/future.ts +2 -2
- package/src/render/index.ts +6 -6
- package/src/render/internal.ts +11 -12
- package/src/render/traversal_ops.ts +1 -1
- package/src/render/util/axis_filtering.ts +67 -52
- package/src/render/util/column_collection.ts +171 -91
- package/src/render/util/index.ts +4 -4
- package/src/render/util/label.test.ts +139 -139
- package/src/render/util/label.ts +42 -33
- package/src/render/util/pcolumn_data.ts +111 -75
- package/src/render/util/pframe_upgraders.ts +24 -13
- package/src/render/util/split_selectors.ts +6 -1
- package/src/sdk_info.ts +1 -1
- package/src/typing.test.ts +56 -56
- package/src/version.ts +1 -1
package/src/block_api_v2.ts
CHANGED
|
@@ -6,8 +6,8 @@ import type {
|
|
|
6
6
|
ValueWithUTagAndAuthor,
|
|
7
7
|
AuthorMarker,
|
|
8
8
|
ResultOrError,
|
|
9
|
-
} from
|
|
10
|
-
import type { Operation } from
|
|
9
|
+
} from "@milaboratories/pl-model-common";
|
|
10
|
+
import type { Operation } from "fast-json-patch";
|
|
11
11
|
|
|
12
12
|
/** Defines methods to read and write current block data. */
|
|
13
13
|
export interface BlockApiV2<
|
|
@@ -55,7 +55,11 @@ export interface BlockApiV2<
|
|
|
55
55
|
* function under the hood may delay actual persistence of the supplied
|
|
56
56
|
* values.
|
|
57
57
|
* */
|
|
58
|
-
setBlockArgsAndUiState(
|
|
58
|
+
setBlockArgsAndUiState(
|
|
59
|
+
args: Args,
|
|
60
|
+
state: UiState,
|
|
61
|
+
author?: AuthorMarker,
|
|
62
|
+
): Promise<ResultOrError<void>>;
|
|
59
63
|
|
|
60
64
|
/**
|
|
61
65
|
* Sets block navigation state.
|
package/src/block_api_v3.ts
CHANGED
|
@@ -6,9 +6,9 @@ import type {
|
|
|
6
6
|
AuthorMarker,
|
|
7
7
|
ResultOrError,
|
|
8
8
|
BlockStateV3,
|
|
9
|
-
} from
|
|
10
|
-
import type { Operation } from
|
|
11
|
-
import type { MutateStoragePayload } from
|
|
9
|
+
} from "@milaboratories/pl-model-common";
|
|
10
|
+
import type { Operation } from "fast-json-patch";
|
|
11
|
+
import type { MutateStoragePayload } from "./block_storage";
|
|
12
12
|
|
|
13
13
|
/** Defines methods to read and write current block data. */
|
|
14
14
|
export interface BlockApiV3<
|
|
@@ -1,53 +1,52 @@
|
|
|
1
|
-
import { describe, expect, it } from
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
2
|
import {
|
|
3
|
-
DataModel,
|
|
4
3
|
DataModelBuilder,
|
|
5
4
|
defaultRecover,
|
|
6
5
|
defineDataVersions,
|
|
7
6
|
makeDataVersioned,
|
|
8
|
-
} from
|
|
7
|
+
} from "./block_migrations";
|
|
9
8
|
|
|
10
|
-
describe(
|
|
11
|
-
it(
|
|
9
|
+
describe("defineDataVersions", () => {
|
|
10
|
+
it("throws on duplicate version values", () => {
|
|
12
11
|
expect(() =>
|
|
13
12
|
defineDataVersions({
|
|
14
|
-
V1:
|
|
15
|
-
V2:
|
|
13
|
+
V1: "v1",
|
|
14
|
+
V2: "v1", // duplicate!
|
|
16
15
|
}),
|
|
17
|
-
).toThrow(
|
|
16
|
+
).toThrow("Duplicate version values: v1");
|
|
18
17
|
});
|
|
19
18
|
|
|
20
|
-
it(
|
|
19
|
+
it("throws on empty version values", () => {
|
|
21
20
|
expect(() =>
|
|
22
21
|
defineDataVersions({
|
|
23
|
-
V1:
|
|
24
|
-
V2:
|
|
22
|
+
V1: "v1",
|
|
23
|
+
V2: "", // empty!
|
|
25
24
|
}),
|
|
26
|
-
).toThrow(
|
|
25
|
+
).toThrow("Version values must be non-empty strings (empty: V2)");
|
|
27
26
|
});
|
|
28
27
|
|
|
29
|
-
it(
|
|
28
|
+
it("allows unique version values", () => {
|
|
30
29
|
const versions = defineDataVersions({
|
|
31
|
-
V1:
|
|
32
|
-
V2:
|
|
30
|
+
V1: "v1",
|
|
31
|
+
V2: "v2",
|
|
33
32
|
});
|
|
34
|
-
expect(versions.V1).toBe(
|
|
35
|
-
expect(versions.V2).toBe(
|
|
33
|
+
expect(versions.V1).toBe("v1");
|
|
34
|
+
expect(versions.V2).toBe("v2");
|
|
36
35
|
});
|
|
37
36
|
});
|
|
38
37
|
|
|
39
|
-
describe(
|
|
40
|
-
it(
|
|
41
|
-
const versioned = makeDataVersioned(
|
|
42
|
-
expect(versioned).toStrictEqual({ version:
|
|
38
|
+
describe("makeDataVersioned", () => {
|
|
39
|
+
it("creates correct DataVersioned shape", () => {
|
|
40
|
+
const versioned = makeDataVersioned("v1", { count: 42 });
|
|
41
|
+
expect(versioned).toStrictEqual({ version: "v1", data: { count: 42 } });
|
|
43
42
|
});
|
|
44
43
|
});
|
|
45
44
|
|
|
46
|
-
describe(
|
|
47
|
-
it(
|
|
45
|
+
describe("DataModel migrations", () => {
|
|
46
|
+
it("resets to initial data on unknown version", () => {
|
|
48
47
|
const Version = defineDataVersions({
|
|
49
|
-
V1:
|
|
50
|
-
V2:
|
|
48
|
+
V1: "v1",
|
|
49
|
+
V2: "v2",
|
|
51
50
|
});
|
|
52
51
|
|
|
53
52
|
type VersionedData = {
|
|
@@ -57,19 +56,19 @@ describe('DataModel migrations', () => {
|
|
|
57
56
|
|
|
58
57
|
const dataModel = new DataModelBuilder<VersionedData>()
|
|
59
58
|
.from(Version.V1)
|
|
60
|
-
.migrate(Version.V2, (v1) => ({ ...v1, label:
|
|
61
|
-
.init(() => ({ count: 0, label:
|
|
59
|
+
.migrate(Version.V2, (v1) => ({ ...v1, label: "" }))
|
|
60
|
+
.init(() => ({ count: 0, label: "" }));
|
|
62
61
|
|
|
63
|
-
const result = dataModel.migrate(makeDataVersioned(
|
|
64
|
-
expect(result.version).toBe(
|
|
65
|
-
expect(result.data).toStrictEqual({ count: 0, label:
|
|
62
|
+
const result = dataModel.migrate(makeDataVersioned("legacy", { count: 42 }));
|
|
63
|
+
expect(result.version).toBe("v2");
|
|
64
|
+
expect(result.data).toStrictEqual({ count: 0, label: "" });
|
|
66
65
|
expect(result.warning).toBe(`Unknown version 'legacy'`);
|
|
67
66
|
});
|
|
68
67
|
|
|
69
|
-
it(
|
|
68
|
+
it("uses recover() for unknown versions", () => {
|
|
70
69
|
const Version = defineDataVersions({
|
|
71
|
-
V1:
|
|
72
|
-
V2:
|
|
70
|
+
V1: "v1",
|
|
71
|
+
V2: "v2",
|
|
73
72
|
});
|
|
74
73
|
|
|
75
74
|
type VersionedData = {
|
|
@@ -79,25 +78,25 @@ describe('DataModel migrations', () => {
|
|
|
79
78
|
|
|
80
79
|
const dataModel = new DataModelBuilder<VersionedData>()
|
|
81
80
|
.from(Version.V1)
|
|
82
|
-
.migrate(Version.V2, (v1) => ({ ...v1, label:
|
|
81
|
+
.migrate(Version.V2, (v1) => ({ ...v1, label: "" }))
|
|
83
82
|
.recover((version, data) => {
|
|
84
|
-
if (version ===
|
|
85
|
-
return { count: (data as { count: number }).count, label:
|
|
83
|
+
if (version === "legacy" && typeof data === "object" && data !== null && "count" in data) {
|
|
84
|
+
return { count: (data as { count: number }).count, label: "recovered" };
|
|
86
85
|
}
|
|
87
86
|
return defaultRecover(version, data);
|
|
88
87
|
})
|
|
89
|
-
.init(() => ({ count: 0, label:
|
|
88
|
+
.init(() => ({ count: 0, label: "" }));
|
|
90
89
|
|
|
91
|
-
const result = dataModel.migrate(makeDataVersioned(
|
|
92
|
-
expect(result.version).toBe(
|
|
93
|
-
expect(result.data).toStrictEqual({ count: 7, label:
|
|
90
|
+
const result = dataModel.migrate(makeDataVersioned("legacy", { count: 7 }));
|
|
91
|
+
expect(result.version).toBe("v2");
|
|
92
|
+
expect(result.data).toStrictEqual({ count: 7, label: "recovered" });
|
|
94
93
|
expect(result.warning).toBeUndefined();
|
|
95
94
|
});
|
|
96
95
|
|
|
97
|
-
it(
|
|
96
|
+
it("allows recover() to delegate to defaultRecover", () => {
|
|
98
97
|
const Version = defineDataVersions({
|
|
99
|
-
V1:
|
|
100
|
-
V2:
|
|
98
|
+
V1: "v1",
|
|
99
|
+
V2: "v2",
|
|
101
100
|
});
|
|
102
101
|
|
|
103
102
|
type VersionedData = {
|
|
@@ -107,20 +106,20 @@ describe('DataModel migrations', () => {
|
|
|
107
106
|
|
|
108
107
|
const dataModel = new DataModelBuilder<VersionedData>()
|
|
109
108
|
.from(Version.V1)
|
|
110
|
-
.migrate(Version.V2, (v1) => ({ ...v1, label:
|
|
109
|
+
.migrate(Version.V2, (v1) => ({ ...v1, label: "" }))
|
|
111
110
|
.recover((version, data) => defaultRecover(version, data))
|
|
112
|
-
.init(() => ({ count: 0, label:
|
|
111
|
+
.init(() => ({ count: 0, label: "" }));
|
|
113
112
|
|
|
114
|
-
const result = dataModel.migrate(makeDataVersioned(
|
|
115
|
-
expect(result.version).toBe(
|
|
116
|
-
expect(result.data).toStrictEqual({ count: 0, label:
|
|
113
|
+
const result = dataModel.migrate(makeDataVersioned("legacy", { count: 7 }));
|
|
114
|
+
expect(result.version).toBe("v2");
|
|
115
|
+
expect(result.data).toStrictEqual({ count: 0, label: "" });
|
|
117
116
|
expect(result.warning).toBe(`Unknown version 'legacy'`);
|
|
118
117
|
});
|
|
119
118
|
|
|
120
|
-
it(
|
|
119
|
+
it("returns initial data on migration failure", () => {
|
|
121
120
|
const Version = defineDataVersions({
|
|
122
|
-
V1:
|
|
123
|
-
V2:
|
|
121
|
+
V1: "v1",
|
|
122
|
+
V2: "v2",
|
|
124
123
|
});
|
|
125
124
|
|
|
126
125
|
type VersionedData = {
|
|
@@ -132,23 +131,23 @@ describe('DataModel migrations', () => {
|
|
|
132
131
|
.from(Version.V1)
|
|
133
132
|
.migrate(Version.V2, (v1) => {
|
|
134
133
|
if (v1.numbers.includes(666)) {
|
|
135
|
-
throw new Error(
|
|
134
|
+
throw new Error("Forbidden number");
|
|
136
135
|
}
|
|
137
|
-
return { ...v1, label:
|
|
136
|
+
return { ...v1, label: "ok" };
|
|
138
137
|
})
|
|
139
|
-
.init(() => ({ numbers: [], label:
|
|
138
|
+
.init(() => ({ numbers: [], label: "" }));
|
|
140
139
|
|
|
141
|
-
const result = dataModel.migrate(makeDataVersioned(
|
|
142
|
-
expect(result.version).toBe(
|
|
143
|
-
expect(result.data).toStrictEqual({ numbers: [], label:
|
|
140
|
+
const result = dataModel.migrate(makeDataVersioned("v1", { numbers: [666] }));
|
|
141
|
+
expect(result.version).toBe("v2");
|
|
142
|
+
expect(result.data).toStrictEqual({ numbers: [], label: "" });
|
|
144
143
|
expect(result.warning).toBe(`Migration v1→v2 failed: Forbidden number`);
|
|
145
144
|
});
|
|
146
145
|
});
|
|
147
146
|
|
|
148
147
|
function _compileTimeTypeChecks() {
|
|
149
148
|
const Version = defineDataVersions({
|
|
150
|
-
V1:
|
|
151
|
-
V2:
|
|
149
|
+
V1: "v1",
|
|
150
|
+
V2: "v2",
|
|
152
151
|
});
|
|
153
152
|
|
|
154
153
|
type VersionedData = {
|
|
@@ -159,24 +158,24 @@ function _compileTimeTypeChecks() {
|
|
|
159
158
|
// Valid: complete migration chain
|
|
160
159
|
new DataModelBuilder<VersionedData>()
|
|
161
160
|
.from(Version.V1)
|
|
162
|
-
.migrate(Version.V2, (v1) => ({ ...v1, label:
|
|
163
|
-
.init(() => ({ count: 0, label:
|
|
161
|
+
.migrate(Version.V2, (v1) => ({ ...v1, label: "" }))
|
|
162
|
+
.init(() => ({ count: 0, label: "" }));
|
|
164
163
|
|
|
165
164
|
// Valid: with recover()
|
|
166
165
|
new DataModelBuilder<VersionedData>()
|
|
167
166
|
.from(Version.V1)
|
|
168
|
-
.migrate(Version.V2, (v1) => ({ ...v1, label:
|
|
167
|
+
.migrate(Version.V2, (v1) => ({ ...v1, label: "" }))
|
|
169
168
|
.recover((version, data) => defaultRecover(version, data))
|
|
170
|
-
.init(() => ({ count: 0, label:
|
|
169
|
+
.init(() => ({ count: 0, label: "" }));
|
|
171
170
|
|
|
172
171
|
new DataModelBuilder<VersionedData>()
|
|
173
172
|
// @ts-expect-error invalid initial version key
|
|
174
|
-
.from(
|
|
173
|
+
.from("v3");
|
|
175
174
|
|
|
176
175
|
new DataModelBuilder<VersionedData>()
|
|
177
176
|
.from(Version.V1)
|
|
178
177
|
// @ts-expect-error invalid migration target key
|
|
179
|
-
.migrate(
|
|
178
|
+
.migrate("v3", (v1) => ({ ...v1, label: "" }));
|
|
180
179
|
|
|
181
180
|
new DataModelBuilder<VersionedData>()
|
|
182
181
|
.from(Version.V1)
|
|
@@ -193,7 +192,7 @@ function _compileTimeTypeChecks() {
|
|
|
193
192
|
|
|
194
193
|
new DataModelBuilder<VersionedData>()
|
|
195
194
|
.from(Version.V1)
|
|
196
|
-
.migrate(Version.V2, (v1) => ({ ...v1, label:
|
|
195
|
+
.migrate(Version.V2, (v1) => ({ ...v1, label: "" }))
|
|
197
196
|
.recover((version, data) => defaultRecover(version, data))
|
|
198
197
|
// @ts-expect-error recover() returns builder without recover() method - cannot call twice (only init() available)
|
|
199
198
|
.recover((version, data) => defaultRecover(version, data));
|
|
@@ -202,5 +201,5 @@ function _compileTimeTypeChecks() {
|
|
|
202
201
|
.from(Version.V1)
|
|
203
202
|
.recover((version, data) => defaultRecover(version, data))
|
|
204
203
|
// @ts-expect-error recover() returns builder without migrate() method (only init() available)
|
|
205
|
-
.migrate(Version.V2, (v1) => ({ ...v1, label:
|
|
204
|
+
.migrate(Version.V2, (v1) => ({ ...v1, label: "" }));
|
|
206
205
|
}
|
package/src/block_migrations.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { tryRegisterCallback } from
|
|
2
|
-
import { createBlockStorage } from
|
|
1
|
+
import { tryRegisterCallback } from "./internal";
|
|
2
|
+
import { createBlockStorage } from "./block_storage";
|
|
3
3
|
|
|
4
4
|
export type DataVersionKey = string;
|
|
5
5
|
export type DataVersionMap = Record<string, unknown>;
|
|
@@ -29,14 +29,14 @@ export type DataRecoverFn<T> = (version: DataVersionKey, data: unknown) => T;
|
|
|
29
29
|
export function defineDataVersions<const T extends Record<string, string>>(versions: T): T {
|
|
30
30
|
const values = Object.values(versions) as (string & keyof T)[];
|
|
31
31
|
const keys = Object.keys(versions) as (keyof T)[];
|
|
32
|
-
const emptyKeys = keys.filter((key) => versions[key] ===
|
|
32
|
+
const emptyKeys = keys.filter((key) => versions[key] === "");
|
|
33
33
|
if (emptyKeys.length > 0) {
|
|
34
|
-
throw new Error(`Version values must be non-empty strings (empty: ${emptyKeys.join(
|
|
34
|
+
throw new Error(`Version values must be non-empty strings (empty: ${emptyKeys.join(", ")})`);
|
|
35
35
|
}
|
|
36
36
|
const unique = new Set(values);
|
|
37
37
|
if (unique.size !== values.length) {
|
|
38
38
|
const duplicates = values.filter((v, i) => values.indexOf(v) !== i);
|
|
39
|
-
throw new Error(`Duplicate version values: ${[...new Set(duplicates)].join(
|
|
39
|
+
throw new Error(`Duplicate version values: ${[...new Set(duplicates)].join(", ")}`);
|
|
40
40
|
}
|
|
41
41
|
return versions;
|
|
42
42
|
}
|
|
@@ -59,14 +59,14 @@ export type DataMigrationResult<T> = DataVersioned<T> & {
|
|
|
59
59
|
|
|
60
60
|
/** Thrown by recover() to signal unrecoverable data. */
|
|
61
61
|
export class DataUnrecoverableError extends Error {
|
|
62
|
-
name =
|
|
62
|
+
name = "DataUnrecoverableError";
|
|
63
63
|
constructor(dataVersion: DataVersionKey) {
|
|
64
64
|
super(`Unknown version '${dataVersion}'`);
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
export function isDataUnrecoverableError(error: unknown): error is DataUnrecoverableError {
|
|
69
|
-
return error instanceof Error && error.name ===
|
|
69
|
+
return error instanceof Error && error.name === "DataUnrecoverableError";
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
type MigrationStep = {
|
|
@@ -92,7 +92,7 @@ export const defaultRecover: DataRecoverFn<never> = (version, _data) => {
|
|
|
92
92
|
};
|
|
93
93
|
|
|
94
94
|
/** Symbol for internal builder creation method */
|
|
95
|
-
const FROM_BUILDER = Symbol(
|
|
95
|
+
const FROM_BUILDER = Symbol("fromBuilder");
|
|
96
96
|
|
|
97
97
|
/** Internal state passed from builder to DataModel */
|
|
98
98
|
type BuilderState<S> = {
|
|
@@ -338,10 +338,10 @@ export class DataModelBuilder<VersionedData extends DataVersionMap> {
|
|
|
338
338
|
from<InitialVersion extends keyof VersionedData & string>(
|
|
339
339
|
initialVersion: InitialVersion,
|
|
340
340
|
): DataModelMigrationChain<
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
341
|
+
VersionedData,
|
|
342
|
+
InitialVersion,
|
|
343
|
+
Exclude<keyof VersionedData & string, InitialVersion>
|
|
344
|
+
> {
|
|
345
345
|
return new DataModelMigrationChain<
|
|
346
346
|
VersionedData,
|
|
347
347
|
InitialVersion,
|
|
@@ -409,7 +409,7 @@ export class DataModel<State> {
|
|
|
409
409
|
recoverFn?: DataRecoverFn<State>;
|
|
410
410
|
}) {
|
|
411
411
|
if (versionChain.length === 0) {
|
|
412
|
-
throw new Error(
|
|
412
|
+
throw new Error("DataModel requires at least one version key");
|
|
413
413
|
}
|
|
414
414
|
this.versionChain = versionChain;
|
|
415
415
|
this.steps = steps;
|
|
@@ -517,11 +517,11 @@ export class DataModel<State> {
|
|
|
517
517
|
* @internal
|
|
518
518
|
*/
|
|
519
519
|
registerCallbacks(): void {
|
|
520
|
-
tryRegisterCallback(
|
|
521
|
-
tryRegisterCallback(
|
|
520
|
+
tryRegisterCallback("__pl_data_initial", () => this.initialDataFn());
|
|
521
|
+
tryRegisterCallback("__pl_data_upgrade", (versioned: DataVersioned<unknown>) =>
|
|
522
522
|
this.migrate(versioned),
|
|
523
523
|
);
|
|
524
|
-
tryRegisterCallback(
|
|
524
|
+
tryRegisterCallback("__pl_storage_initial", () => {
|
|
525
525
|
const { version, data } = this.getDefaultData();
|
|
526
526
|
const storage = createBlockStorage(data, version);
|
|
527
527
|
return JSON.stringify(storage);
|