@platforma-sdk/model 1.58.3 → 1.58.9
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/_virtual/_rolldown/runtime.cjs +43 -0
- package/dist/_virtual/_rolldown/runtime.js +18 -0
- package/dist/annotations/converter.cjs +15 -20
- package/dist/annotations/converter.cjs.map +1 -1
- package/dist/annotations/converter.d.ts +6 -2
- package/dist/annotations/converter.js +14 -18
- package/dist/annotations/converter.js.map +1 -1
- package/dist/annotations/index.cjs +1 -0
- package/dist/annotations/index.d.ts +2 -3
- package/dist/annotations/index.js +1 -0
- package/dist/annotations/types.d.ts +21 -16
- package/dist/bconfig/index.cjs +2 -0
- package/dist/bconfig/index.d.ts +5 -6
- package/dist/bconfig/index.js +2 -0
- package/dist/bconfig/lambdas.d.ts +52 -52
- package/dist/bconfig/normalization.cjs +13 -18
- package/dist/bconfig/normalization.cjs.map +1 -1
- package/dist/bconfig/normalization.d.ts +10 -6
- package/dist/bconfig/normalization.js +12 -16
- package/dist/bconfig/normalization.js.map +1 -1
- package/dist/bconfig/types.cjs +4 -3
- package/dist/bconfig/types.cjs.map +1 -1
- package/dist/bconfig/types.d.ts +10 -5
- package/dist/bconfig/types.js +4 -2
- package/dist/bconfig/types.js.map +1 -1
- package/dist/bconfig/util.d.ts +7 -4
- package/dist/bconfig/v3.d.ts +10 -6
- package/dist/block_api_v1.d.ts +62 -58
- package/dist/block_api_v2.d.ts +51 -47
- package/dist/block_api_v3.d.ts +33 -29
- package/dist/block_migrations.cjs +481 -413
- package/dist/block_migrations.cjs.map +1 -1
- package/dist/block_migrations.d.ts +258 -204
- package/dist/block_migrations.js +482 -408
- package/dist/block_migrations.js.map +1 -1
- package/dist/block_model.cjs +312 -343
- package/dist/block_model.cjs.map +1 -1
- package/dist/block_model.d.ts +143 -147
- package/dist/block_model.js +312 -341
- package/dist/block_model.js.map +1 -1
- package/dist/block_model_legacy.cjs +231 -255
- package/dist/block_model_legacy.cjs.map +1 -1
- package/dist/block_model_legacy.d.ts +108 -106
- package/dist/block_model_legacy.js +231 -253
- package/dist/block_model_legacy.js.map +1 -1
- package/dist/block_state_patch.d.ts +10 -10
- package/dist/block_state_util.cjs +15 -19
- package/dist/block_state_util.cjs.map +1 -1
- package/dist/block_state_util.d.ts +14 -13
- package/dist/block_state_util.js +15 -18
- package/dist/block_state_util.js.map +1 -1
- package/dist/block_storage.cjs +233 -238
- package/dist/block_storage.cjs.map +1 -1
- package/dist/block_storage.d.ts +62 -78
- package/dist/block_storage.js +234 -237
- package/dist/block_storage.js.map +1 -1
- package/dist/block_storage_callbacks.cjs +156 -195
- package/dist/block_storage_callbacks.cjs.map +1 -1
- package/dist/block_storage_callbacks.js +156 -192
- package/dist/block_storage_callbacks.js.map +1 -1
- package/dist/block_storage_facade.cjs +29 -85
- package/dist/block_storage_facade.cjs.map +1 -1
- package/dist/block_storage_facade.d.ts +83 -126
- package/dist/block_storage_facade.js +29 -83
- package/dist/block_storage_facade.js.map +1 -1
- package/dist/components/PFrameForGraphs.cjs +26 -24
- package/dist/components/PFrameForGraphs.cjs.map +1 -1
- package/dist/components/PFrameForGraphs.d.ts +12 -7
- package/dist/components/PFrameForGraphs.js +25 -22
- package/dist/components/PFrameForGraphs.js.map +1 -1
- package/dist/components/PlAnnotations/filter.d.ts +62 -79
- package/dist/components/PlAnnotations/filters_ui.cjs +135 -171
- package/dist/components/PlAnnotations/filters_ui.cjs.map +1 -1
- package/dist/components/PlAnnotations/filters_ui.d.ts +48 -46
- package/dist/components/PlAnnotations/filters_ui.js +135 -170
- package/dist/components/PlAnnotations/filters_ui.js.map +1 -1
- package/dist/components/PlAnnotations/index.d.ts +2 -3
- package/dist/components/PlDataTable/index.cjs +2 -0
- package/dist/components/PlDataTable/index.d.ts +3 -5
- package/dist/components/PlDataTable/index.js +2 -0
- package/dist/components/PlDataTable/labels.cjs +59 -81
- package/dist/components/PlDataTable/labels.cjs.map +1 -1
- package/dist/components/PlDataTable/labels.js +58 -79
- package/dist/components/PlDataTable/labels.js.map +1 -1
- package/dist/components/PlDataTable/state-migration.cjs +186 -144
- package/dist/components/PlDataTable/state-migration.cjs.map +1 -1
- package/dist/components/PlDataTable/state-migration.d.ts +85 -82
- package/dist/components/PlDataTable/state-migration.js +185 -142
- package/dist/components/PlDataTable/state-migration.js.map +1 -1
- package/dist/components/PlDataTable/table.cjs +172 -194
- package/dist/components/PlDataTable/table.cjs.map +1 -1
- package/dist/components/PlDataTable/table.d.ts +16 -12
- package/dist/components/PlDataTable/table.js +171 -192
- package/dist/components/PlDataTable/table.js.map +1 -1
- package/dist/components/PlDataTable/v4.d.ts +84 -119
- package/dist/components/PlDataTable/v5.d.ts +80 -103
- package/dist/components/PlMultiSequenceAlignment.cjs +27 -29
- package/dist/components/PlMultiSequenceAlignment.cjs.map +1 -1
- package/dist/components/PlMultiSequenceAlignment.d.ts +36 -27
- package/dist/components/PlMultiSequenceAlignment.js +26 -27
- package/dist/components/PlMultiSequenceAlignment.js.map +1 -1
- package/dist/components/PlSelectionModel.cjs +7 -6
- package/dist/components/PlSelectionModel.cjs.map +1 -1
- package/dist/components/PlSelectionModel.d.ts +10 -8
- package/dist/components/PlSelectionModel.js +7 -5
- package/dist/components/PlSelectionModel.js.map +1 -1
- package/dist/components/index.cjs +8 -0
- package/dist/components/index.d.ts +11 -6
- package/dist/components/index.js +8 -0
- package/dist/config/actions.cjs +138 -171
- package/dist/config/actions.cjs.map +1 -1
- package/dist/config/actions.d.ts +47 -47
- package/dist/config/actions.js +146 -178
- package/dist/config/actions.js.map +1 -1
- package/dist/config/actions_kinds.d.ts +114 -121
- package/dist/config/index.cjs +1 -0
- package/dist/config/index.d.ts +6 -7
- package/dist/config/index.js +1 -0
- package/dist/config/model.d.ts +131 -127
- package/dist/config/model_meta.d.ts +4 -1
- package/dist/config/type_engine.d.ts +22 -21
- package/dist/config/type_util.d.ts +12 -10
- package/dist/env_value.cjs +5 -6
- package/dist/env_value.cjs.map +1 -1
- package/dist/env_value.d.ts +4 -1
- package/dist/env_value.js +5 -5
- package/dist/env_value.js.map +1 -1
- package/dist/filters/converters/filterToQuery.cjs +273 -239
- package/dist/filters/converters/filterToQuery.cjs.map +1 -1
- package/dist/filters/converters/filterToQuery.d.ts +6 -2
- package/dist/filters/converters/filterToQuery.js +272 -237
- package/dist/filters/converters/filterToQuery.js.map +1 -1
- package/dist/filters/converters/filterUiToExpressionImpl.cjs +56 -85
- package/dist/filters/converters/filterUiToExpressionImpl.cjs.map +1 -1
- package/dist/filters/converters/filterUiToExpressionImpl.d.ts +8 -4
- package/dist/filters/converters/filterUiToExpressionImpl.js +55 -83
- package/dist/filters/converters/filterUiToExpressionImpl.js.map +1 -1
- package/dist/filters/converters/index.cjs +2 -0
- package/dist/filters/converters/index.d.ts +2 -3
- package/dist/filters/converters/index.js +2 -0
- package/dist/filters/distill.cjs +59 -50
- package/dist/filters/distill.cjs.map +1 -1
- package/dist/filters/distill.d.ts +6 -3
- package/dist/filters/distill.js +58 -48
- package/dist/filters/distill.js.map +1 -1
- package/dist/filters/index.cjs +4 -0
- package/dist/filters/index.d.ts +5 -4
- package/dist/filters/index.js +4 -0
- package/dist/filters/traverse.cjs +31 -40
- package/dist/filters/traverse.cjs.map +1 -1
- package/dist/filters/traverse.js +31 -39
- package/dist/filters/traverse.js.map +1 -1
- package/dist/filters/types.d.ts +10 -7
- package/dist/index.cjs +193 -187
- package/dist/index.d.ts +61 -28
- package/dist/index.js +49 -41
- package/dist/internal.cjs +48 -62
- package/dist/internal.cjs.map +1 -1
- package/dist/internal.js +49 -60
- package/dist/internal.js.map +1 -1
- package/dist/package.cjs +12 -0
- package/dist/package.cjs.map +1 -0
- package/dist/package.js +6 -0
- package/dist/package.js.map +1 -0
- package/dist/pframe.cjs +32 -37
- package/dist/pframe.cjs.map +1 -1
- package/dist/pframe.d.ts +14 -10
- package/dist/pframe.js +32 -35
- package/dist/pframe.js.map +1 -1
- package/dist/pframe_utils/axes.cjs +81 -114
- package/dist/pframe_utils/axes.cjs.map +1 -1
- package/dist/pframe_utils/axes.d.ts +10 -13
- package/dist/pframe_utils/axes.js +80 -112
- package/dist/pframe_utils/axes.js.map +1 -1
- package/dist/pframe_utils/columns.cjs +61 -81
- package/dist/pframe_utils/columns.cjs.map +1 -1
- package/dist/pframe_utils/columns.d.ts +15 -6
- package/dist/pframe_utils/columns.js +60 -79
- package/dist/pframe_utils/columns.js.map +1 -1
- package/dist/pframe_utils/index.cjs +232 -253
- package/dist/pframe_utils/index.cjs.map +1 -1
- package/dist/pframe_utils/index.d.ts +39 -35
- package/dist/pframe_utils/index.js +231 -251
- package/dist/pframe_utils/index.js.map +1 -1
- package/dist/platforma.d.ts +48 -46
- package/dist/plugin_handle.cjs +6 -14
- package/dist/plugin_handle.cjs.map +1 -1
- package/dist/plugin_handle.d.ts +20 -25
- package/dist/plugin_handle.js +6 -13
- package/dist/plugin_handle.js.map +1 -1
- package/dist/plugin_model.cjs +364 -163
- package/dist/plugin_model.cjs.map +1 -1
- package/dist/plugin_model.d.ts +280 -129
- package/dist/plugin_model.js +362 -163
- package/dist/plugin_model.js.map +1 -1
- package/dist/raw_globals.cjs +10 -22
- package/dist/raw_globals.cjs.map +1 -1
- package/dist/raw_globals.d.ts +8 -5
- package/dist/raw_globals.js +10 -20
- package/dist/raw_globals.js.map +1 -1
- package/dist/ref_util.cjs +14 -13
- package/dist/ref_util.cjs.map +1 -1
- package/dist/ref_util.d.ts +18 -12
- package/dist/ref_util.js +14 -11
- package/dist/ref_util.js.map +1 -1
- package/dist/render/accessor.cjs +213 -226
- package/dist/render/accessor.cjs.map +1 -1
- package/dist/render/accessor.d.ts +115 -120
- package/dist/render/accessor.js +212 -224
- package/dist/render/accessor.js.map +1 -1
- package/dist/render/api.cjs +478 -580
- package/dist/render/api.cjs.map +1 -1
- package/dist/render/api.d.ts +207 -209
- package/dist/render/api.js +476 -578
- package/dist/render/api.js.map +1 -1
- package/dist/render/future.cjs +28 -32
- package/dist/render/future.cjs.map +1 -1
- package/dist/render/future.d.ts +15 -11
- package/dist/render/future.js +28 -30
- package/dist/render/future.js.map +1 -1
- package/dist/render/index.cjs +8 -0
- package/dist/render/index.d.ts +10 -8
- package/dist/render/index.js +8 -0
- package/dist/render/internal.cjs +33 -29
- package/dist/render/internal.cjs.map +1 -1
- package/dist/render/internal.d.ts +78 -72
- package/dist/render/internal.js +29 -26
- package/dist/render/internal.js.map +1 -1
- package/dist/render/traversal_ops.d.ts +42 -43
- package/dist/render/util/axis_filtering.cjs +63 -86
- package/dist/render/util/axis_filtering.cjs.map +1 -1
- package/dist/render/util/axis_filtering.d.ts +10 -7
- package/dist/render/util/axis_filtering.js +63 -85
- package/dist/render/util/axis_filtering.js.map +1 -1
- package/dist/render/util/column_collection.cjs +266 -321
- package/dist/render/util/column_collection.cjs.map +1 -1
- package/dist/render/util/column_collection.d.ts +47 -47
- package/dist/render/util/column_collection.js +264 -319
- package/dist/render/util/column_collection.js.map +1 -1
- package/dist/render/util/index.cjs +4 -0
- package/dist/render/util/index.d.ts +4 -5
- package/dist/render/util/index.js +4 -0
- package/dist/render/util/label.cjs +129 -163
- package/dist/render/util/label.cjs.map +1 -1
- package/dist/render/util/label.d.ts +45 -46
- package/dist/render/util/label.js +128 -161
- package/dist/render/util/label.js.map +1 -1
- package/dist/render/util/pcolumn_data.cjs +315 -375
- package/dist/render/util/pcolumn_data.cjs.map +1 -1
- package/dist/render/util/pcolumn_data.d.ts +33 -32
- package/dist/render/util/pcolumn_data.js +314 -373
- package/dist/render/util/pcolumn_data.js.map +1 -1
- package/dist/render/util/pframe_upgraders.cjs +37 -42
- package/dist/render/util/pframe_upgraders.cjs.map +1 -1
- package/dist/render/util/pframe_upgraders.js +37 -41
- package/dist/render/util/pframe_upgraders.js.map +1 -1
- package/dist/render/util/split_selectors.d.ts +13 -9
- package/dist/version.cjs +6 -8
- package/dist/version.cjs.map +1 -1
- package/dist/version.d.ts +7 -4
- package/dist/version.js +5 -5
- package/dist/version.js.map +1 -1
- package/package.json +9 -3
- package/src/block_migrations.test.ts +184 -14
- package/src/block_migrations.ts +185 -30
- package/src/block_model.ts +111 -66
- package/src/block_storage.test.ts +147 -3
- package/src/block_storage.ts +43 -8
- package/src/block_storage_callbacks.ts +9 -4
- package/src/env_value.ts +0 -2
- package/src/filters/distill.ts +17 -6
- package/src/index.ts +12 -11
- package/src/internal.ts +0 -1
- package/src/platforma.ts +4 -4
- package/src/plugin_handle.ts +1 -1
- package/src/plugin_model.test.ts +217 -21
- package/src/plugin_model.ts +450 -55
- package/src/raw_globals.ts +0 -1
- package/dist/annotations/converter.d.ts.map +0 -1
- package/dist/annotations/index.d.ts.map +0 -1
- package/dist/annotations/types.d.ts.map +0 -1
- package/dist/bconfig/index.d.ts.map +0 -1
- package/dist/bconfig/lambdas.d.ts.map +0 -1
- package/dist/bconfig/normalization.d.ts.map +0 -1
- package/dist/bconfig/types.d.ts.map +0 -1
- package/dist/bconfig/util.d.ts.map +0 -1
- package/dist/bconfig/v3.d.ts.map +0 -1
- package/dist/block_api_v1.d.ts.map +0 -1
- package/dist/block_api_v2.d.ts.map +0 -1
- package/dist/block_api_v3.d.ts.map +0 -1
- package/dist/block_migrations.d.ts.map +0 -1
- package/dist/block_model.d.ts.map +0 -1
- package/dist/block_model_legacy.d.ts.map +0 -1
- package/dist/block_state_patch.d.ts.map +0 -1
- package/dist/block_state_util.d.ts.map +0 -1
- package/dist/block_storage.d.ts.map +0 -1
- package/dist/block_storage_callbacks.d.ts +0 -115
- package/dist/block_storage_callbacks.d.ts.map +0 -1
- package/dist/block_storage_facade.d.ts.map +0 -1
- package/dist/components/PFrameForGraphs.d.ts.map +0 -1
- package/dist/components/PlAnnotations/filter.d.ts.map +0 -1
- package/dist/components/PlAnnotations/filters_ui.d.ts.map +0 -1
- package/dist/components/PlAnnotations/index.d.ts.map +0 -1
- package/dist/components/PlAnnotations/types.d.ts +0 -3
- package/dist/components/PlAnnotations/types.d.ts.map +0 -1
- package/dist/components/PlDataTable/index.d.ts.map +0 -1
- package/dist/components/PlDataTable/labels.d.ts +0 -7
- package/dist/components/PlDataTable/labels.d.ts.map +0 -1
- package/dist/components/PlDataTable/state-migration.d.ts.map +0 -1
- package/dist/components/PlDataTable/table.d.ts.map +0 -1
- package/dist/components/PlDataTable/v4.d.ts.map +0 -1
- package/dist/components/PlDataTable/v5.d.ts.map +0 -1
- package/dist/components/PlMultiSequenceAlignment.d.ts.map +0 -1
- package/dist/components/PlSelectionModel.d.ts.map +0 -1
- package/dist/components/index.d.ts.map +0 -1
- package/dist/config/actions.d.ts.map +0 -1
- package/dist/config/actions_kinds.d.ts.map +0 -1
- package/dist/config/index.d.ts.map +0 -1
- package/dist/config/model.d.ts.map +0 -1
- package/dist/config/model_meta.d.ts.map +0 -1
- package/dist/config/type_engine.d.ts.map +0 -1
- package/dist/config/type_util.d.ts.map +0 -1
- package/dist/env_value.d.ts.map +0 -1
- package/dist/filters/converters/filterToQuery.d.ts.map +0 -1
- package/dist/filters/converters/filterUiToExpressionImpl.d.ts.map +0 -1
- package/dist/filters/converters/index.d.ts.map +0 -1
- package/dist/filters/distill.d.ts.map +0 -1
- package/dist/filters/index.d.ts.map +0 -1
- package/dist/filters/traverse.d.ts +0 -27
- package/dist/filters/traverse.d.ts.map +0 -1
- package/dist/filters/types.d.ts.map +0 -1
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/internal.d.ts +0 -36
- package/dist/internal.d.ts.map +0 -1
- package/dist/package.json.cjs +0 -6
- package/dist/package.json.cjs.map +0 -1
- package/dist/package.json.js +0 -4
- package/dist/package.json.js.map +0 -1
- package/dist/pframe.d.ts.map +0 -1
- package/dist/pframe_utils/axes.d.ts.map +0 -1
- package/dist/pframe_utils/columns.d.ts.map +0 -1
- package/dist/pframe_utils/index.d.ts.map +0 -1
- package/dist/pframe_utils/querySpec.d.ts +0 -2
- package/dist/pframe_utils/querySpec.d.ts.map +0 -1
- package/dist/platforma.d.ts.map +0 -1
- package/dist/plugin_handle.d.ts.map +0 -1
- package/dist/plugin_model.d.ts.map +0 -1
- package/dist/raw_globals.d.ts.map +0 -1
- package/dist/ref_util.d.ts.map +0 -1
- package/dist/render/accessor.d.ts.map +0 -1
- package/dist/render/api.d.ts.map +0 -1
- package/dist/render/future.d.ts.map +0 -1
- package/dist/render/index.d.ts.map +0 -1
- package/dist/render/internal.d.ts.map +0 -1
- package/dist/render/traversal_ops.d.ts.map +0 -1
- package/dist/render/util/axis_filtering.d.ts.map +0 -1
- package/dist/render/util/column_collection.d.ts.map +0 -1
- package/dist/render/util/index.d.ts.map +0 -1
- package/dist/render/util/label.d.ts.map +0 -1
- package/dist/render/util/pcolumn_data.d.ts.map +0 -1
- package/dist/render/util/pframe_upgraders.d.ts +0 -3
- package/dist/render/util/pframe_upgraders.d.ts.map +0 -1
- package/dist/render/util/split_selectors.d.ts.map +0 -1
- package/dist/version.d.ts.map +0 -1
package/dist/block_migrations.js
CHANGED
|
@@ -1,426 +1,500 @@
|
|
|
1
|
-
import { DATA_MODEL_LEGACY_VERSION } from
|
|
1
|
+
import { DATA_MODEL_LEGACY_VERSION } from "./block_storage.js";
|
|
2
2
|
|
|
3
|
+
//#region src/block_migrations.ts
|
|
3
4
|
/** Create a DataVersioned wrapper with correct shape */
|
|
4
|
-
function
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
name = "DataMigrationError";
|
|
10
|
-
constructor(message) {
|
|
11
|
-
super(message);
|
|
12
|
-
}
|
|
5
|
+
function makeVersionedData(version, data) {
|
|
6
|
+
return {
|
|
7
|
+
version,
|
|
8
|
+
data
|
|
9
|
+
};
|
|
13
10
|
}
|
|
14
11
|
/** Thrown by recover() to signal unrecoverable data. */
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
12
|
+
var DataUnrecoverableError = class extends Error {
|
|
13
|
+
name = "DataUnrecoverableError";
|
|
14
|
+
constructor(dataVersion) {
|
|
15
|
+
super(`Unknown version '${dataVersion}'`);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
21
18
|
function isDataUnrecoverableError(error) {
|
|
22
|
-
|
|
19
|
+
return error instanceof Error && error.name === "DataUnrecoverableError";
|
|
23
20
|
}
|
|
24
21
|
/**
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
22
|
+
* Default recover function for unknown versions.
|
|
23
|
+
* Use as fallback at the end of custom recover functions.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* .recover((version, data) => {
|
|
27
|
+
* if (version === 'legacy') {
|
|
28
|
+
* return transformLegacyData(data);
|
|
29
|
+
* }
|
|
30
|
+
* return defaultRecover(version, data);
|
|
31
|
+
* })
|
|
32
|
+
*/
|
|
36
33
|
const defaultRecover = (version, _data) => {
|
|
37
|
-
|
|
34
|
+
throw new DataUnrecoverableError(version);
|
|
38
35
|
};
|
|
39
36
|
/** Symbol for internal builder creation method */
|
|
40
37
|
const FROM_BUILDER = Symbol("fromBuilder");
|
|
41
38
|
/**
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
39
|
+
* Abstract base for both migration chain types.
|
|
40
|
+
* Holds shared state, buildStep() helper, and init().
|
|
41
|
+
* migrate() cannot be shared due to a TypeScript limitation: when the base class
|
|
42
|
+
* migrate() return type is abstract, subclasses cannot narrow it without losing type safety.
|
|
43
|
+
* Each subclass therefore owns its migrate() with the correct concrete return type.
|
|
44
|
+
*
|
|
45
|
+
* @internal
|
|
46
|
+
*/
|
|
47
|
+
var MigrationChainBase = class {
|
|
48
|
+
versionChain;
|
|
49
|
+
migrationSteps;
|
|
50
|
+
transferSteps;
|
|
51
|
+
constructor(state) {
|
|
52
|
+
this.versionChain = state.versionChain;
|
|
53
|
+
this.migrationSteps = state.steps;
|
|
54
|
+
this.transferSteps = state.transferSteps ?? [];
|
|
55
|
+
}
|
|
56
|
+
/** Appends a migration step and returns the new versionChain and steps arrays. */
|
|
57
|
+
buildStep(nextVersion, fn) {
|
|
58
|
+
if (this.versionChain.includes(nextVersion)) throw new Error(`Duplicate version '${nextVersion}' in migration chain`);
|
|
59
|
+
const step = {
|
|
60
|
+
fromVersion: this.versionChain[this.versionChain.length - 1],
|
|
61
|
+
toVersion: nextVersion,
|
|
62
|
+
migrate: fn
|
|
63
|
+
};
|
|
64
|
+
return {
|
|
65
|
+
versionChain: [...this.versionChain, nextVersion],
|
|
66
|
+
steps: [...this.migrationSteps, step]
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/** Validates uniqueness and records a TransferStep. */
|
|
70
|
+
buildTransfer(target, extract) {
|
|
71
|
+
if (this.transferSteps.some((t) => t.pluginId === target.id)) throw new Error(`Duplicate transfer for plugin '${target.id}'`);
|
|
72
|
+
const entry = {
|
|
73
|
+
pluginId: target.id,
|
|
74
|
+
beforeStepIndex: this.migrationSteps.length,
|
|
75
|
+
extract,
|
|
76
|
+
targetVersion: target.transferVersion
|
|
77
|
+
};
|
|
78
|
+
return { transferSteps: [...this.transferSteps, entry] };
|
|
79
|
+
}
|
|
80
|
+
/** Returns recover-specific fields for DataModel construction. Overridden by WithRecover. */
|
|
81
|
+
recoverState() {
|
|
82
|
+
return {};
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Finalize the DataModel with initial data factory.
|
|
86
|
+
*
|
|
87
|
+
* @param initialData - Factory function returning the initial state
|
|
88
|
+
* @returns Finalized DataModel instance
|
|
89
|
+
*/
|
|
90
|
+
init(initialData) {
|
|
91
|
+
return DataModel[FROM_BUILDER]({
|
|
92
|
+
versionChain: this.versionChain,
|
|
93
|
+
steps: this.migrationSteps,
|
|
94
|
+
transferSteps: this.transferSteps,
|
|
95
|
+
initialDataFn: initialData,
|
|
96
|
+
...this.recoverState()
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
};
|
|
92
100
|
/**
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
}
|
|
101
|
+
* Migration chain after recover() or upgradeLegacy() has been called.
|
|
102
|
+
* Further migrate() and transfer() calls are allowed; recover() and upgradeLegacy() are not
|
|
103
|
+
* (enforced by type — no such methods on this class).
|
|
104
|
+
*
|
|
105
|
+
* @typeParam Current - Data type at the current point in the chain
|
|
106
|
+
* @typeParam Transfers - Accumulated transfer types keyed by plugin ID
|
|
107
|
+
* @internal
|
|
108
|
+
*/
|
|
109
|
+
var DataModelMigrationChainWithRecover = class DataModelMigrationChainWithRecover extends MigrationChainBase {
|
|
110
|
+
recoverFn;
|
|
111
|
+
recoverFromIndex;
|
|
112
|
+
/** @internal */
|
|
113
|
+
constructor(state) {
|
|
114
|
+
super(state);
|
|
115
|
+
this.recoverFn = state.recoverFn;
|
|
116
|
+
this.recoverFromIndex = state.recoverFromIndex;
|
|
117
|
+
}
|
|
118
|
+
recoverState() {
|
|
119
|
+
return {
|
|
120
|
+
recoverFn: this.recoverFn,
|
|
121
|
+
recoverFromIndex: this.recoverFromIndex
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Add a migration step. Same semantics as on the base chain.
|
|
126
|
+
* recover() and upgradeLegacy() are not available — one has already been called.
|
|
127
|
+
*/
|
|
128
|
+
migrate(nextVersion, fn) {
|
|
129
|
+
const { versionChain, steps } = this.buildStep(nextVersion, fn);
|
|
130
|
+
return new DataModelMigrationChainWithRecover({
|
|
131
|
+
versionChain,
|
|
132
|
+
steps,
|
|
133
|
+
transferSteps: this.transferSteps,
|
|
134
|
+
recoverFn: this.recoverFn,
|
|
135
|
+
recoverFromIndex: this.recoverFromIndex
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Extract data at the current chain position for seeding a new plugin.
|
|
140
|
+
* The extract function's return type must match the plugin's transfer data type.
|
|
141
|
+
* Duplicate plugin IDs are rejected at both type and runtime level.
|
|
142
|
+
*/
|
|
143
|
+
transfer(target, extract) {
|
|
144
|
+
const { transferSteps } = this.buildTransfer(target, extract);
|
|
145
|
+
return new DataModelMigrationChainWithRecover({
|
|
146
|
+
versionChain: this.versionChain,
|
|
147
|
+
steps: this.migrationSteps,
|
|
148
|
+
transferSteps,
|
|
149
|
+
recoverFn: this.recoverFn,
|
|
150
|
+
recoverFromIndex: this.recoverFromIndex
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
};
|
|
129
154
|
/**
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
155
|
+
* Migration chain builder.
|
|
156
|
+
* Each migrate() call advances the current data type. recover() can be called once
|
|
157
|
+
* at any point — it removes itself from the returned chain so it cannot be called again.
|
|
158
|
+
* Duplicate version keys throw at runtime.
|
|
159
|
+
*
|
|
160
|
+
* @typeParam Current - Data type at the current point in the migration chain
|
|
161
|
+
* @typeParam Transfers - Accumulated transfer types keyed by plugin ID
|
|
162
|
+
* @internal
|
|
163
|
+
*/
|
|
164
|
+
var DataModelMigrationChain = class DataModelMigrationChain extends MigrationChainBase {
|
|
165
|
+
/** @internal */
|
|
166
|
+
constructor({ versionChain, steps = [], transferSteps = [] }) {
|
|
167
|
+
super({
|
|
168
|
+
versionChain,
|
|
169
|
+
steps,
|
|
170
|
+
transferSteps
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Add a migration step transforming data from the current version to the next.
|
|
175
|
+
*
|
|
176
|
+
* @typeParam Next - Data type of the next version
|
|
177
|
+
* @param nextVersion - Version key to migrate to (must be unique in the chain)
|
|
178
|
+
* @param fn - Migration function
|
|
179
|
+
* @returns Builder with the next version as current
|
|
180
|
+
*
|
|
181
|
+
* @example
|
|
182
|
+
* .migrate<BlockDataV2>("v2", (v1) => ({ ...v1, labels: [] }))
|
|
183
|
+
*/
|
|
184
|
+
migrate(nextVersion, fn) {
|
|
185
|
+
const { versionChain, steps } = this.buildStep(nextVersion, fn);
|
|
186
|
+
return new DataModelMigrationChain({
|
|
187
|
+
versionChain,
|
|
188
|
+
steps,
|
|
189
|
+
transferSteps: this.transferSteps
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Extract data at the current chain position for seeding a new plugin.
|
|
194
|
+
* The extract function's return type must match the plugin's transfer data type.
|
|
195
|
+
* Duplicate plugin IDs are rejected at both type and runtime level.
|
|
196
|
+
*
|
|
197
|
+
* Calling .transfer() on DataModelInitialChain returns DataModelMigrationChain,
|
|
198
|
+
* which removes .upgradeLegacy() from the chain (preventing a problematic combination).
|
|
199
|
+
*
|
|
200
|
+
* @example
|
|
201
|
+
* .from<V1>("v1")
|
|
202
|
+
* .transfer(tablePlugin, (v1) => ({ state: v1.tableState }))
|
|
203
|
+
* .migrate<V2>("v2", ({ tableState: _, ...rest }) => rest)
|
|
204
|
+
*/
|
|
205
|
+
transfer(target, extract) {
|
|
206
|
+
const { transferSteps } = this.buildTransfer(target, extract);
|
|
207
|
+
return new DataModelMigrationChain({
|
|
208
|
+
versionChain: this.versionChain,
|
|
209
|
+
steps: this.migrationSteps,
|
|
210
|
+
transferSteps
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Set a recovery handler for unknown or legacy versions.
|
|
215
|
+
*
|
|
216
|
+
* The recover function is called when data has a version not in the migration chain.
|
|
217
|
+
* It must return data of the type at this point in the chain (Current). Any migrate()
|
|
218
|
+
* steps added after recover() will then run on the recovered data.
|
|
219
|
+
*
|
|
220
|
+
* Can only be called once — the returned chain has no recover() method.
|
|
221
|
+
*
|
|
222
|
+
* @param fn - Recovery function returning Current (the type at this chain position)
|
|
223
|
+
* @returns Builder with migrate() and init() but without recover()
|
|
224
|
+
*
|
|
225
|
+
* @example
|
|
226
|
+
* // Recover between migrations — recovered data goes through v3 migration
|
|
227
|
+
* new DataModelBuilder<V1>("v1")
|
|
228
|
+
* .migrate<V2>("v2", (v1) => ({ ...v1, label: "" }))
|
|
229
|
+
* .recover((version, data) => {
|
|
230
|
+
* if (version === 'legacy') return transformLegacy(data); // returns V2
|
|
231
|
+
* return defaultRecover(version, data);
|
|
232
|
+
* })
|
|
233
|
+
* .migrate<V3>("v3", (v2) => ({ ...v2, description: "" }))
|
|
234
|
+
* .init(() => ({ count: 0, label: "", description: "" }));
|
|
235
|
+
*/
|
|
236
|
+
recover(fn) {
|
|
237
|
+
return new DataModelMigrationChainWithRecover({
|
|
238
|
+
versionChain: this.versionChain,
|
|
239
|
+
steps: this.migrationSteps,
|
|
240
|
+
transferSteps: this.transferSteps,
|
|
241
|
+
recoverFn: fn,
|
|
242
|
+
recoverFromIndex: this.migrationSteps.length
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
};
|
|
190
246
|
/**
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
}
|
|
247
|
+
* Initial migration chain returned by `.from()`.
|
|
248
|
+
* Extends DataModelMigrationChain with `upgradeLegacy()` — available only before
|
|
249
|
+
* any `.migrate()` calls, since legacy data always arrives at the initial version.
|
|
250
|
+
*
|
|
251
|
+
* @typeParam Current - Data type at the initial version
|
|
252
|
+
* @typeParam Transfers - Accumulated transfer types keyed by plugin ID
|
|
253
|
+
* @internal
|
|
254
|
+
*/
|
|
255
|
+
var DataModelInitialChain = class extends DataModelMigrationChain {
|
|
256
|
+
/**
|
|
257
|
+
* Handle legacy V1 model state ({ args, uiState }) when upgrading a block from
|
|
258
|
+
* BlockModel V1 to BlockModelV3.
|
|
259
|
+
*
|
|
260
|
+
* When a V1 block is upgraded, its stored state `{ args, uiState }` is normalized
|
|
261
|
+
* to the internal default version. This method inserts a migration step from that
|
|
262
|
+
* internal version to the version specified in `.from()`, using the provided typed
|
|
263
|
+
* callback to transform the legacy shape. Non-legacy data passes through unchanged.
|
|
264
|
+
*
|
|
265
|
+
* Must be called right after `.from()` — not available after `.migrate()` calls.
|
|
266
|
+
* Any `.migrate()` steps added after `upgradeLegacy()` will run on the transformed result.
|
|
267
|
+
*
|
|
268
|
+
* Can only be called once — the returned chain has no upgradeLegacy() method.
|
|
269
|
+
* Mutually exclusive with recover().
|
|
270
|
+
*
|
|
271
|
+
* @typeParam Args - Type of the legacy block args
|
|
272
|
+
* @typeParam UiState - Type of the legacy block uiState
|
|
273
|
+
* @param fn - Typed transform from { args, uiState } to Current
|
|
274
|
+
* @returns Builder with migrate() and init() but without recover() or upgradeLegacy()
|
|
275
|
+
*
|
|
276
|
+
* @example
|
|
277
|
+
* type OldArgs = { inputFile: string; threshold: number };
|
|
278
|
+
* type OldUiState = { selectedTab: string };
|
|
279
|
+
* type BlockData = { inputFile: string; threshold: number; selectedTab: string };
|
|
280
|
+
*
|
|
281
|
+
* const dataModel = new DataModelBuilder()
|
|
282
|
+
* .from<BlockData>("v1")
|
|
283
|
+
* .upgradeLegacy<OldArgs, OldUiState>(({ args, uiState }) => ({
|
|
284
|
+
* inputFile: args.inputFile,
|
|
285
|
+
* threshold: args.threshold,
|
|
286
|
+
* selectedTab: uiState.selectedTab,
|
|
287
|
+
* }))
|
|
288
|
+
* .init(() => ({ inputFile: '', threshold: 0, selectedTab: 'main' }));
|
|
289
|
+
*/
|
|
290
|
+
upgradeLegacy(fn) {
|
|
291
|
+
const wrappedFn = (data) => {
|
|
292
|
+
if (data !== null && typeof data === "object" && "args" in data) return fn(data);
|
|
293
|
+
return data;
|
|
294
|
+
};
|
|
295
|
+
const step = {
|
|
296
|
+
fromVersion: DATA_MODEL_LEGACY_VERSION,
|
|
297
|
+
toVersion: this.versionChain[0],
|
|
298
|
+
migrate: wrappedFn
|
|
299
|
+
};
|
|
300
|
+
return new DataModelMigrationChainWithRecover({
|
|
301
|
+
versionChain: [DATA_MODEL_LEGACY_VERSION, ...this.versionChain],
|
|
302
|
+
steps: [step, ...this.migrationSteps],
|
|
303
|
+
transferSteps: this.transferSteps.map((t) => ({
|
|
304
|
+
...t,
|
|
305
|
+
beforeStepIndex: t.beforeStepIndex + 1
|
|
306
|
+
}))
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
};
|
|
254
310
|
/**
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
}
|
|
311
|
+
* Builder entry point for creating DataModel with type-safe migrations.
|
|
312
|
+
*
|
|
313
|
+
* @example
|
|
314
|
+
* // Simple (no migrations):
|
|
315
|
+
* const dataModel = new DataModelBuilder()
|
|
316
|
+
* .from<BlockData>("v1")
|
|
317
|
+
* .init(() => ({ numbers: [] }));
|
|
318
|
+
*
|
|
319
|
+
* @example
|
|
320
|
+
* // With migrations:
|
|
321
|
+
* const dataModel = new DataModelBuilder()
|
|
322
|
+
* .from<BlockDataV1>("v1")
|
|
323
|
+
* .migrate<BlockDataV2>("v2", (v1) => ({ ...v1, labels: [] }))
|
|
324
|
+
* .migrate<BlockDataV3>("v3", (v2) => ({ ...v2, description: '' }))
|
|
325
|
+
* .init(() => ({ numbers: [], labels: [], description: '' }));
|
|
326
|
+
*
|
|
327
|
+
* @example
|
|
328
|
+
* // With recover() between migrations — recovered data goes through remaining migrations:
|
|
329
|
+
* const dataModelChain = new DataModelBuilder()
|
|
330
|
+
* .from<BlockDataV1>("v1")
|
|
331
|
+
* .migrate<BlockDataV2>("v2", (v1) => ({ ...v1, labels: [] }));
|
|
332
|
+
*
|
|
333
|
+
* // recover() placed before the v3 migration: recovered data goes through v3
|
|
334
|
+
* const dataModel = dataModelChain
|
|
335
|
+
* .recover((version, data) => {
|
|
336
|
+
* if (version === 'legacy' && isLegacyData(data)) return transformLegacy(data); // returns V2
|
|
337
|
+
* return defaultRecover(version, data);
|
|
338
|
+
* })
|
|
339
|
+
* .migrate<BlockDataV3>("v3", (v2) => ({ ...v2, description: '' }))
|
|
340
|
+
* .init(() => ({ numbers: [], labels: [], description: '' }));
|
|
341
|
+
*
|
|
342
|
+
* @example
|
|
343
|
+
* // With upgradeLegacy() — typed upgrade from BlockModel V1 state:
|
|
344
|
+
* type OldArgs = { inputFile: string };
|
|
345
|
+
* type OldUiState = { selectedTab: string };
|
|
346
|
+
* type BlockData = { inputFile: string; selectedTab: string };
|
|
347
|
+
*
|
|
348
|
+
* const dataModel = new DataModelBuilder()
|
|
349
|
+
* .from<BlockData>("v1")
|
|
350
|
+
* .upgradeLegacy<OldArgs, OldUiState>(({ args, uiState }) => ({
|
|
351
|
+
* inputFile: args.inputFile,
|
|
352
|
+
* selectedTab: uiState.selectedTab,
|
|
353
|
+
* }))
|
|
354
|
+
* .init(() => ({ inputFile: '', selectedTab: 'main' }));
|
|
355
|
+
*/
|
|
356
|
+
var DataModelBuilder = class {
|
|
357
|
+
/**
|
|
358
|
+
* Start the migration chain with the given initial data type and version key.
|
|
359
|
+
*
|
|
360
|
+
* @typeParam T - Data type for the initial version
|
|
361
|
+
* @param initialVersion - Version key string (e.g. "v1")
|
|
362
|
+
* @returns Migration chain builder
|
|
363
|
+
*/
|
|
364
|
+
from(initialVersion) {
|
|
365
|
+
return new DataModelInitialChain({ versionChain: [initialVersion] });
|
|
366
|
+
}
|
|
367
|
+
};
|
|
312
368
|
/**
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
class DataModel {
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
369
|
+
* DataModel defines the block's data structure, initial values, and migrations.
|
|
370
|
+
* Used by BlockModelV3 to manage data state.
|
|
371
|
+
*
|
|
372
|
+
* Use `new DataModelBuilder()` to create a DataModel.
|
|
373
|
+
*
|
|
374
|
+
* @example
|
|
375
|
+
* // With recover() between migrations:
|
|
376
|
+
* // Recovered data (V2) goes through the v2→v3 migration automatically.
|
|
377
|
+
* const dataModel = new DataModelBuilder()
|
|
378
|
+
* .from<V1>("v1")
|
|
379
|
+
* .migrate<V2>("v2", (v1) => ({ ...v1, label: "" }))
|
|
380
|
+
* .recover((version, data) => {
|
|
381
|
+
* if (version === "legacy") return transformLegacy(data); // returns V2
|
|
382
|
+
* return defaultRecover(version, data);
|
|
383
|
+
* })
|
|
384
|
+
* .migrate<V3>("v3", (v2) => ({ ...v2, description: "" }))
|
|
385
|
+
* .init(() => ({ count: 0, label: "", description: "" }));
|
|
386
|
+
*/
|
|
387
|
+
var DataModel = class DataModel {
|
|
388
|
+
/** Latest version key — O(1) access for the common "already current" check. */
|
|
389
|
+
latestVersion;
|
|
390
|
+
/** Maps each known version key to the index of the first step to run from it. O(1) lookup. */
|
|
391
|
+
stepsByFromVersion;
|
|
392
|
+
steps;
|
|
393
|
+
transferSteps;
|
|
394
|
+
initialDataFn;
|
|
395
|
+
recoverFn;
|
|
396
|
+
recoverFromIndex;
|
|
397
|
+
constructor({ versionChain, steps, transferSteps = [], initialDataFn, recoverFn = defaultRecover, recoverFromIndex }) {
|
|
398
|
+
if (versionChain.length === 0) throw new Error("DataModel requires at least one version key");
|
|
399
|
+
this.latestVersion = versionChain[versionChain.length - 1];
|
|
400
|
+
this.stepsByFromVersion = new Map(versionChain.map((v, i) => [v, i]));
|
|
401
|
+
this.steps = steps;
|
|
402
|
+
this.transferSteps = transferSteps;
|
|
403
|
+
this.initialDataFn = initialDataFn;
|
|
404
|
+
this.recoverFn = recoverFn;
|
|
405
|
+
this.recoverFromIndex = recoverFromIndex ?? steps.length;
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* Internal method for creating DataModel from builder.
|
|
409
|
+
* Uses Symbol key to prevent external access.
|
|
410
|
+
* @internal
|
|
411
|
+
*/
|
|
412
|
+
static [FROM_BUILDER](state) {
|
|
413
|
+
return new DataModel(state);
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* The latest (current) version key in the migration chain.
|
|
417
|
+
*/
|
|
418
|
+
get version() {
|
|
419
|
+
return this.latestVersion;
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* Get a fresh copy of the initial data.
|
|
423
|
+
*/
|
|
424
|
+
initialData() {
|
|
425
|
+
return this.initialDataFn();
|
|
426
|
+
}
|
|
427
|
+
/**
|
|
428
|
+
* Get initial data wrapped with current version.
|
|
429
|
+
* Used when creating new blocks or resetting to defaults.
|
|
430
|
+
*/
|
|
431
|
+
getDefaultData() {
|
|
432
|
+
return makeVersionedData(this.latestVersion, this.initialDataFn());
|
|
433
|
+
}
|
|
434
|
+
recoverFrom(data, version) {
|
|
435
|
+
let currentData = this.recoverFn(version, data);
|
|
436
|
+
for (let i = this.recoverFromIndex; i < this.steps.length; i++) currentData = this.steps[i].migrate(currentData);
|
|
437
|
+
return {
|
|
438
|
+
version: this.latestVersion,
|
|
439
|
+
data: currentData
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
/**
|
|
443
|
+
* Migrate versioned data from any version to the latest.
|
|
444
|
+
* Collects transfer extractions at their designated chain positions.
|
|
445
|
+
*
|
|
446
|
+
* - If version is in chain, applies needed migrations (O(1) lookup)
|
|
447
|
+
* - If version is unknown, attempts recovery; falls back to initial data
|
|
448
|
+
* - If a migration step fails, throws so the caller can preserve original data
|
|
449
|
+
*
|
|
450
|
+
* Transfers only fire during normal step-by-step migration:
|
|
451
|
+
* - Recovery path: returns empty transfers
|
|
452
|
+
* - Fast-path (already at latest): returns empty transfers
|
|
453
|
+
*
|
|
454
|
+
* @param versioned - Data with version tag
|
|
455
|
+
* @returns Migrated data at the latest version with transfer record
|
|
456
|
+
* @throws If a migration step from a known version fails
|
|
457
|
+
*/
|
|
458
|
+
migrate(versioned) {
|
|
459
|
+
const { version: fromVersion, data } = versioned;
|
|
460
|
+
if (fromVersion === this.latestVersion) return {
|
|
461
|
+
version: this.latestVersion,
|
|
462
|
+
data,
|
|
463
|
+
transfers: {}
|
|
464
|
+
};
|
|
465
|
+
const startIndex = this.stepsByFromVersion.get(fromVersion);
|
|
466
|
+
if (startIndex === void 0) try {
|
|
467
|
+
return {
|
|
468
|
+
...this.recoverFrom(data, fromVersion),
|
|
469
|
+
transfers: {}
|
|
470
|
+
};
|
|
471
|
+
} catch {
|
|
472
|
+
return {
|
|
473
|
+
...this.getDefaultData(),
|
|
474
|
+
transfers: {}
|
|
475
|
+
};
|
|
476
|
+
}
|
|
477
|
+
let currentData = data;
|
|
478
|
+
const transfers = {};
|
|
479
|
+
for (let i = startIndex; i < this.steps.length; i++) {
|
|
480
|
+
for (const t of this.transferSteps) if (t.beforeStepIndex === i) transfers[t.pluginId] = {
|
|
481
|
+
version: t.targetVersion,
|
|
482
|
+
data: t.extract(currentData)
|
|
483
|
+
};
|
|
484
|
+
currentData = this.steps[i].migrate(currentData);
|
|
485
|
+
}
|
|
486
|
+
for (const t of this.transferSteps) if (t.beforeStepIndex >= this.steps.length && t.beforeStepIndex >= startIndex) transfers[t.pluginId] = {
|
|
487
|
+
version: t.targetVersion,
|
|
488
|
+
data: t.extract(currentData)
|
|
489
|
+
};
|
|
490
|
+
return {
|
|
491
|
+
version: this.latestVersion,
|
|
492
|
+
data: currentData,
|
|
493
|
+
transfers
|
|
494
|
+
};
|
|
495
|
+
}
|
|
496
|
+
};
|
|
424
497
|
|
|
425
|
-
|
|
426
|
-
|
|
498
|
+
//#endregion
|
|
499
|
+
export { DataModel, DataModelBuilder, isDataUnrecoverableError };
|
|
500
|
+
//# sourceMappingURL=block_migrations.js.map
|