@platforma-sdk/model 1.52.7 → 1.53.1

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.
Files changed (37) hide show
  1. package/dist/block_migrations.cjs +145 -45
  2. package/dist/block_migrations.cjs.map +1 -1
  3. package/dist/block_migrations.d.ts +88 -26
  4. package/dist/block_migrations.d.ts.map +1 -1
  5. package/dist/block_migrations.js +142 -47
  6. package/dist/block_migrations.js.map +1 -1
  7. package/dist/block_storage.cjs +13 -6
  8. package/dist/block_storage.cjs.map +1 -1
  9. package/dist/block_storage.d.ts +16 -11
  10. package/dist/block_storage.d.ts.map +1 -1
  11. package/dist/block_storage.js +13 -7
  12. package/dist/block_storage.js.map +1 -1
  13. package/dist/block_storage_vm.cjs +15 -14
  14. package/dist/block_storage_vm.cjs.map +1 -1
  15. package/dist/block_storage_vm.d.ts +1 -1
  16. package/dist/block_storage_vm.d.ts.map +1 -1
  17. package/dist/block_storage_vm.js +16 -15
  18. package/dist/block_storage_vm.js.map +1 -1
  19. package/dist/components/PlMultiSequenceAlignment.cjs.map +1 -1
  20. package/dist/components/PlMultiSequenceAlignment.d.ts +5 -3
  21. package/dist/components/PlMultiSequenceAlignment.d.ts.map +1 -1
  22. package/dist/components/PlMultiSequenceAlignment.js.map +1 -1
  23. package/dist/index.cjs +6 -0
  24. package/dist/index.cjs.map +1 -1
  25. package/dist/index.d.ts +1 -1
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +2 -2
  28. package/dist/package.json.cjs +1 -1
  29. package/dist/package.json.js +1 -1
  30. package/package.json +7 -7
  31. package/src/block_migrations.test.ts +170 -0
  32. package/src/block_migrations.ts +207 -62
  33. package/src/block_storage.test.ts +23 -22
  34. package/src/block_storage.ts +23 -16
  35. package/src/block_storage_vm.ts +21 -19
  36. package/src/components/PlMultiSequenceAlignment.ts +12 -8
  37. package/src/index.ts +8 -1
@@ -0,0 +1,170 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import {
3
+ DataModel,
4
+ defaultRecover,
5
+ defineDataVersions,
6
+ makeDataVersioned,
7
+ } from './block_migrations';
8
+
9
+ describe('defineDataVersions', () => {
10
+ it('throws on duplicate version values', () => {
11
+ expect(() =>
12
+ defineDataVersions({
13
+ V1: 'v1',
14
+ V2: 'v1', // duplicate!
15
+ }),
16
+ ).toThrow('Duplicate version values: v1');
17
+ });
18
+
19
+ it('throws on empty version values', () => {
20
+ expect(() =>
21
+ defineDataVersions({
22
+ V1: 'v1',
23
+ V2: '', // empty!
24
+ }),
25
+ ).toThrow('Version values must be non-empty strings (empty: V2)');
26
+ });
27
+
28
+ it('allows unique version values', () => {
29
+ const versions = defineDataVersions({
30
+ V1: 'v1',
31
+ V2: 'v2',
32
+ });
33
+ expect(versions.V1).toBe('v1');
34
+ expect(versions.V2).toBe('v2');
35
+ });
36
+ });
37
+
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 } });
42
+ });
43
+ });
44
+
45
+ describe('DataModel migrations', () => {
46
+ it('resets to initial data on unknown version', () => {
47
+ const Version = {
48
+ V1: 'v1',
49
+ V2: 'v2',
50
+ } as const;
51
+
52
+ type VersionedData = {
53
+ [Version.V1]: { count: number };
54
+ [Version.V2]: { count: number; label: string };
55
+ };
56
+
57
+ const dataModel = DataModel
58
+ .from<VersionedData>(Version.V1)
59
+ .migrate(Version.V2, (v1) => ({ ...v1, label: '' }))
60
+ .create(() => ({ count: 0, label: '' }));
61
+
62
+ const result = dataModel.migrate(makeDataVersioned('legacy', { count: 42 }));
63
+ expect(result.version).toBe('v2');
64
+ expect(result.data).toStrictEqual({ count: 0, label: '' });
65
+ expect(result.warning).toBe(`Unknown version 'legacy'`);
66
+ });
67
+
68
+ it('uses recover() for unknown versions', () => {
69
+ const Version = {
70
+ V1: 'v1',
71
+ V2: 'v2',
72
+ } as const;
73
+
74
+ type VersionedData = {
75
+ [Version.V1]: { count: number };
76
+ [Version.V2]: { count: number; label: string };
77
+ };
78
+
79
+ const dataModel = DataModel
80
+ .from<VersionedData>(Version.V1)
81
+ .migrate(Version.V2, (v1) => ({ ...v1, label: '' }))
82
+ .recover((version, data) => {
83
+ if (version === 'legacy' && typeof data === 'object' && data !== null && 'count' in data) {
84
+ return { count: (data as { count: number }).count, label: 'recovered' };
85
+ }
86
+ return defaultRecover(version, data);
87
+ })
88
+ .create(() => ({ count: 0, label: '' }));
89
+
90
+ const result = dataModel.migrate(makeDataVersioned('legacy', { count: 7 }));
91
+ expect(result.version).toBe('v2');
92
+ expect(result.data).toStrictEqual({ count: 7, label: 'recovered' });
93
+ expect(result.warning).toBeUndefined();
94
+ });
95
+
96
+ it('allows recover() to delegate to defaultRecover', () => {
97
+ const Version = {
98
+ V1: 'v1',
99
+ V2: 'v2',
100
+ } as const;
101
+
102
+ type VersionedData = {
103
+ [Version.V1]: { count: number };
104
+ [Version.V2]: { count: number; label: string };
105
+ };
106
+
107
+ const dataModel = DataModel
108
+ .from<VersionedData>(Version.V1)
109
+ .migrate(Version.V2, (v1) => ({ ...v1, label: '' }))
110
+ .recover((version, data) => defaultRecover(version, data))
111
+ .create(() => ({ count: 0, label: '' }));
112
+
113
+ const result = dataModel.migrate(makeDataVersioned('legacy', { count: 7 }));
114
+ expect(result.version).toBe('v2');
115
+ expect(result.data).toStrictEqual({ count: 0, label: '' });
116
+ expect(result.warning).toBe(`Unknown version 'legacy'`);
117
+ });
118
+
119
+ it('returns initial data on migration failure', () => {
120
+ const Version = {
121
+ V1: 'v1',
122
+ V2: 'v2',
123
+ } as const;
124
+
125
+ type VersionedData = {
126
+ [Version.V1]: { numbers: number[] };
127
+ [Version.V2]: { numbers: number[]; label: string };
128
+ };
129
+
130
+ const dataModel = DataModel
131
+ .from<VersionedData>(Version.V1)
132
+ .migrate(Version.V2, (v1) => {
133
+ if (v1.numbers.includes(666)) {
134
+ throw new Error('Forbidden number');
135
+ }
136
+ return { ...v1, label: 'ok' };
137
+ })
138
+ .create(() => ({ numbers: [], label: '' }));
139
+
140
+ const result = dataModel.migrate(makeDataVersioned('v1', { numbers: [666] }));
141
+ expect(result.version).toBe('v2');
142
+ expect(result.data).toStrictEqual({ numbers: [], label: '' });
143
+ expect(result.warning).toBe(`Migration v1→v2 failed: Forbidden number`);
144
+ });
145
+ });
146
+
147
+ // Compile-time typing checks
148
+ const Version = defineDataVersions({
149
+ V1: 'v1',
150
+ V2: 'v2',
151
+ });
152
+
153
+ type VersionedData = {
154
+ [Version.V1]: { count: number };
155
+ [Version.V2]: { count: number; label: string };
156
+ };
157
+
158
+ DataModel
159
+ .from<VersionedData>(Version.V1)
160
+ .migrate(Version.V2, (v1) => ({ ...v1, label: '' }))
161
+ .create(() => ({ count: 0, label: '' }));
162
+
163
+ // @ts-expect-error invalid initial version key
164
+ DataModel.from<VersionedData>('v3');
165
+
166
+ // @ts-expect-error invalid migration target key
167
+ DataModel.from<VersionedData>(Version.V1).migrate('v3', (v1) => ({ ...v1, label: '' }));
168
+
169
+ // @ts-expect-error migration return type must match target version
170
+ DataModel.from<VersionedData>(Version.V1).migrate(Version.V2, (v1) => ({ ...v1, invalid: true }));
@@ -1,43 +1,148 @@
1
1
  import { tryRegisterCallback } from './internal';
2
- import { createBlockStorage } from './block_storage';
2
+ import { createBlockStorage, DATA_MODEL_DEFAULT_VERSION } from './block_storage';
3
3
 
4
- export type MigrationFn<From, To> = (prev: Readonly<From>) => To;
4
+ export type DataVersionKey = string;
5
+ export type DataVersionMap = Record<string, unknown>;
6
+ export type DataMigrateFn<From, To> = (prev: Readonly<From>) => To;
7
+ export type DataCreateFn<T> = () => T;
8
+ export type DataRecoverFn<T> = (version: DataVersionKey, data: unknown) => T;
9
+
10
+ /**
11
+ * Helper to define version keys with literal type inference and runtime validation.
12
+ * - Validates that all version values are unique
13
+ * - Eliminates need for `as const` assertion
14
+ *
15
+ * @throws Error if duplicate version values are found
16
+ *
17
+ * @example
18
+ * const Version = defineDataVersions({
19
+ * Initial: 'v1',
20
+ * AddedLabels: 'v2',
21
+ * });
22
+ *
23
+ * type VersionedData = {
24
+ * [Version.Initial]: DataV1;
25
+ * [Version.AddedLabels]: DataV2;
26
+ * };
27
+ */
28
+ export function defineDataVersions<const T extends Record<string, string>>(versions: T): T {
29
+ const values = Object.values(versions);
30
+ const emptyKeys = Object.keys(versions).filter((key) => versions[key] === '');
31
+ if (emptyKeys.length > 0) {
32
+ throw new Error(`Version values must be non-empty strings (empty: ${emptyKeys.join(', ')})`);
33
+ }
34
+ const unique = new Set(values);
35
+ if (unique.size !== values.length) {
36
+ const duplicates = values.filter((v, i) => values.indexOf(v) !== i);
37
+ throw new Error(`Duplicate version values: ${[...new Set(duplicates)].join(', ')}`);
38
+ }
39
+ return versions;
40
+ }
5
41
 
6
42
  /** Versioned data wrapper for persistence */
7
- export type Versioned<T> = {
8
- version: number;
43
+ export type DataVersioned<T> = {
44
+ version: DataVersionKey;
9
45
  data: T;
10
46
  };
11
47
 
12
- /** Result of upgrade operation, may include warning if migration failed */
13
- export type UpgradeResult<T> = Versioned<T> & {
48
+ /** Create a DataVersioned wrapper with correct shape */
49
+ export function makeDataVersioned<T>(version: DataVersionKey, data: T): DataVersioned<T> {
50
+ return { version, data };
51
+ }
52
+
53
+ /** Result of migration operation, may include warning if migration failed */
54
+ export type DataMigrationResult<T> = DataVersioned<T> & {
14
55
  warning?: string;
15
56
  };
16
57
 
58
+ /** Thrown by recover() to signal unrecoverable data. */
59
+ export class DataUnrecoverableError extends Error {
60
+ name = 'DataUnrecoverableError';
61
+ constructor(dataVersion: DataVersionKey) {
62
+ super(`Unknown version '${dataVersion}'`);
63
+ }
64
+ }
65
+
66
+ export function isDataUnrecoverableError(error: unknown): error is DataUnrecoverableError {
67
+ return error instanceof Error && error.name === 'DataUnrecoverableError';
68
+ }
69
+
70
+ type MigrationStep = {
71
+ fromVersion: DataVersionKey;
72
+ toVersion: DataVersionKey;
73
+ migrate: (data: unknown) => unknown;
74
+ };
75
+
76
+ /** Default recover function for unknown versions */
77
+ export const defaultRecover: DataRecoverFn<never> = (version, _data) => {
78
+ throw new DataUnrecoverableError(version);
79
+ };
80
+
17
81
  /** Internal builder for chaining migrations */
18
- class DataModelBuilder<State> {
19
- private readonly migrationSteps: Array<(x: unknown) => unknown>;
82
+ class DataModelBuilder<
83
+ VersionedData extends DataVersionMap,
84
+ CurrentVersion extends keyof VersionedData & string,
85
+ > {
86
+ private readonly versionChain: DataVersionKey[];
87
+ private readonly migrationSteps: MigrationStep[];
88
+ private readonly recoverFn?: DataRecoverFn<VersionedData[CurrentVersion]>;
20
89
 
21
- private constructor(steps: Array<(x: unknown) => unknown> = []) {
90
+ private constructor(
91
+ versionChain: DataVersionKey[],
92
+ steps: MigrationStep[] = [],
93
+ recoverFn?: DataRecoverFn<VersionedData[CurrentVersion]>,
94
+ ) {
95
+ this.versionChain = versionChain;
22
96
  this.migrationSteps = steps;
97
+ this.recoverFn = recoverFn;
23
98
  }
24
99
 
25
- /** Start a migration chain from an initial type */
26
- static from<T = unknown>(): DataModelBuilder<T> {
27
- return new DataModelBuilder<T>();
100
+ /** Start a migration chain from an initial version */
101
+ static from<
102
+ VersionedData extends DataVersionMap,
103
+ InitialVersion extends keyof VersionedData & string = keyof VersionedData & string,
104
+ >(initialVersion: InitialVersion): DataModelBuilder<VersionedData, InitialVersion> {
105
+ return new DataModelBuilder<VersionedData, InitialVersion>([initialVersion]);
28
106
  }
29
107
 
30
- /** Add a migration step */
31
- migrate<Next>(fn: MigrationFn<State, Next>): DataModelBuilder<Next> {
32
- return new DataModelBuilder<Next>([...this.migrationSteps, fn as any]);
108
+ /** Add a migration step to the target version */
109
+ migrate<NextVersion extends keyof VersionedData & string>(
110
+ nextVersion: NextVersion,
111
+ fn: DataMigrateFn<VersionedData[CurrentVersion], VersionedData[NextVersion]>,
112
+ ): DataModelBuilder<VersionedData, NextVersion> {
113
+ if (this.versionChain.includes(nextVersion)) {
114
+ throw new Error(`Duplicate version '${nextVersion}' in migration chain`);
115
+ }
116
+ const fromVersion = this.versionChain[this.versionChain.length - 1];
117
+ const step: MigrationStep = { fromVersion, toVersion: nextVersion, migrate: fn as (data: unknown) => unknown };
118
+ return new DataModelBuilder<VersionedData, NextVersion>(
119
+ [...this.versionChain, nextVersion],
120
+ [...this.migrationSteps, step],
121
+ );
122
+ }
123
+
124
+ /** Set recovery handler for unknown or unsupported versions */
125
+ recover(
126
+ fn: DataRecoverFn<VersionedData[CurrentVersion]>,
127
+ ): DataModelBuilder<VersionedData, CurrentVersion> {
128
+ return new DataModelBuilder<VersionedData, CurrentVersion>(
129
+ [...this.versionChain],
130
+ [...this.migrationSteps],
131
+ fn,
132
+ );
33
133
  }
34
134
 
35
135
  /** Finalize with initial data, creating the DataModel */
36
- create<S>(
37
- initialData: () => S,
38
- ..._: [State] extends [S] ? [] : [never]
136
+ create<S extends VersionedData[CurrentVersion]>(
137
+ initialData: DataCreateFn<S>,
138
+ ..._: [VersionedData[CurrentVersion]] extends [S] ? [] : [never]
39
139
  ): DataModel<S> {
40
- return DataModel._fromBuilder<S>(this.migrationSteps, initialData);
140
+ return DataModel._fromBuilder<S>(
141
+ this.versionChain,
142
+ this.migrationSteps,
143
+ initialData,
144
+ this.recoverFn as DataRecoverFn<S> | undefined,
145
+ );
41
146
  }
42
147
  }
43
148
 
@@ -53,45 +158,79 @@ class DataModelBuilder<State> {
53
158
  * }));
54
159
  *
55
160
  * // Data model with migrations
161
+ * const Version = defineDataVersions({
162
+ * V1: 'v1',
163
+ * V2: 'v2',
164
+ * V3: 'v3',
165
+ * });
166
+ *
167
+ * type VersionedData = {
168
+ * [Version.V1]: { numbers: number[] };
169
+ * [Version.V2]: { numbers: number[]; labels: string[] };
170
+ * [Version.V3]: { numbers: number[]; labels: string[]; description: string };
171
+ * };
172
+ *
56
173
  * const dataModel = DataModel
57
- * .from<V1>()
58
- * .migrate((data) => ({ ...data, labels: [] })) // v1 → v2
59
- * .migrate((data) => ({ ...data, description: '' })) // v2 → v3
60
- * .create<BlockData>(() => ({ numbers: [], labels: [], description: '' }));
174
+ * .from<VersionedData>(Version.V1)
175
+ * .migrate(Version.V2, (data) => ({ ...data, labels: [] }))
176
+ * .migrate(Version.V3, (data) => ({ ...data, description: '' }))
177
+ * .recover((version, data) => {
178
+ * if (version === 'legacy' && typeof data === 'object' && data !== null && 'numbers' in data) {
179
+ * return { numbers: (data as { numbers: number[] }).numbers, labels: [], description: '' };
180
+ * }
181
+ * return defaultRecover(version, data);
182
+ * })
183
+ * .create(() => ({ numbers: [], labels: [], description: '' }));
61
184
  */
62
185
  export class DataModel<State> {
63
- private readonly steps: Array<(x: unknown) => unknown>;
64
- private readonly _initialData: () => State;
186
+ private readonly versionChain: DataVersionKey[];
187
+ private readonly steps: MigrationStep[];
188
+ private readonly initialDataFn: () => State;
189
+ private readonly recoverFn: DataRecoverFn<State>;
65
190
 
66
- private constructor(steps: Array<(x: unknown) => unknown>, initialData: () => State) {
191
+ private constructor(
192
+ versionChain: DataVersionKey[],
193
+ steps: MigrationStep[],
194
+ initialData: () => State,
195
+ recover: DataRecoverFn<State> = defaultRecover as DataRecoverFn<State>,
196
+ ) {
197
+ if (versionChain.length === 0) {
198
+ throw new Error('DataModel requires at least one version key');
199
+ }
200
+ this.versionChain = versionChain;
67
201
  this.steps = steps;
68
- this._initialData = initialData;
202
+ this.initialDataFn = initialData;
203
+ this.recoverFn = recover;
69
204
  }
70
205
 
71
206
  /** Start a migration chain from an initial type */
72
- static from<S>(): DataModelBuilder<S> {
73
- return DataModelBuilder.from<S>();
207
+ static from<
208
+ VersionedData extends DataVersionMap,
209
+ InitialVersion extends keyof VersionedData & string = keyof VersionedData & string,
210
+ >(initialVersion: InitialVersion): DataModelBuilder<VersionedData, InitialVersion> {
211
+ return DataModelBuilder.from<VersionedData, InitialVersion>(initialVersion);
74
212
  }
75
213
 
76
214
  /** Create a data model with just initial data (no migrations) */
77
- static create<S>(initialData: () => S): DataModel<S> {
78
- return new DataModel<S>([], initialData);
215
+ static create<S>(initialData: () => S, version: DataVersionKey = DATA_MODEL_DEFAULT_VERSION): DataModel<S> {
216
+ return new DataModel<S>([version], [], initialData);
79
217
  }
80
218
 
81
219
  /** Create from builder (internal use) */
82
220
  static _fromBuilder<S>(
83
- steps: Array<(x: unknown) => unknown>,
221
+ versionChain: DataVersionKey[],
222
+ steps: MigrationStep[],
84
223
  initialData: () => S,
224
+ recover?: DataRecoverFn<S>,
85
225
  ): DataModel<S> {
86
- return new DataModel<S>(steps, initialData);
226
+ return new DataModel<S>(versionChain, steps, initialData, recover);
87
227
  }
88
228
 
89
229
  /**
90
- * Latest version number.
91
- * Version 1 = initial state, each migration adds 1.
230
+ * Latest version key.
92
231
  */
93
- get version(): number {
94
- return this.steps.length + 1;
232
+ get version(): DataVersionKey {
233
+ return this.versionChain[this.versionChain.length - 1];
95
234
  }
96
235
 
97
236
  /** Number of migration steps */
@@ -101,50 +240,56 @@ export class DataModel<State> {
101
240
 
102
241
  /** Get initial data */
103
242
  initialData(): State {
104
- return this._initialData();
243
+ return this.initialDataFn();
105
244
  }
106
245
 
107
246
  /** Get default data wrapped with current version */
108
- getDefaultData(): Versioned<State> {
109
- return { version: this.version, data: this._initialData() };
247
+ getDefaultData(): DataVersioned<State> {
248
+ return makeDataVersioned(this.version, this.initialDataFn());
249
+ }
250
+
251
+ private recoverFrom(data: unknown, version: DataVersionKey): DataMigrationResult<State> {
252
+ try {
253
+ return { version: this.version, data: this.recoverFn(version, data) };
254
+ } catch (error) {
255
+ if (isDataUnrecoverableError(error)) {
256
+ return { ...this.getDefaultData(), warning: error.message };
257
+ }
258
+ const errorMessage = error instanceof Error ? error.message : String(error);
259
+ return {
260
+ ...this.getDefaultData(),
261
+ warning: `Recover failed for version '${version}': ${errorMessage}`,
262
+ };
263
+ }
110
264
  }
111
265
 
112
266
  /**
113
- * Upgrade versioned data from any version to the latest.
267
+ * Migrate versioned data from any version to the latest.
114
268
  * Applies only the migrations needed (skips already-applied ones).
115
269
  * If a migration fails, returns default data with a warning.
116
270
  */
117
- upgrade(versioned: Versioned<unknown>): UpgradeResult<State> {
271
+ migrate(versioned: DataVersioned<unknown>): DataMigrationResult<State> {
118
272
  const { version: fromVersion, data } = versioned;
119
273
 
120
- if (fromVersion > this.version) {
121
- throw new Error(
122
- `Cannot downgrade from version ${fromVersion} to ${this.version}`,
123
- );
124
- }
125
-
126
274
  if (fromVersion === this.version) {
127
275
  return { version: this.version, data: data as State };
128
276
  }
129
277
 
130
- // Apply migrations starting from (fromVersion - 1) index
131
- // Version 1 -> no migrations applied yet -> start at index 0
132
- // Version 2 -> migration[0] already applied -> start at index 1
133
- const startIndex = fromVersion - 1;
134
- const migrationsToApply = this.steps.slice(startIndex);
278
+ const startIndex = this.versionChain.indexOf(fromVersion);
279
+ if (startIndex < 0) {
280
+ return this.recoverFrom(data, fromVersion);
281
+ }
135
282
 
136
283
  let currentData: unknown = data;
137
- for (let i = 0; i < migrationsToApply.length; i++) {
138
- const stepIndex = startIndex + i;
139
- const fromVer = stepIndex + 1;
140
- const toVer = stepIndex + 2;
284
+ for (let i = startIndex; i < this.steps.length; i++) {
285
+ const step = this.steps[i];
141
286
  try {
142
- currentData = migrationsToApply[i](currentData);
287
+ currentData = step.migrate(currentData);
143
288
  } catch (error) {
144
289
  const errorMessage = error instanceof Error ? error.message : String(error);
145
290
  return {
146
291
  ...this.getDefaultData(),
147
- warning: `Migration v${fromVer}→v${toVer} failed: ${errorMessage}`,
292
+ warning: `Migration ${step.fromVersion}→${step.toVersion} failed: ${errorMessage}`,
148
293
  };
149
294
  }
150
295
  }
@@ -158,12 +303,12 @@ export class DataModel<State> {
158
303
  *
159
304
  * All callbacks are prefixed with `__pl_` to indicate internal SDK use:
160
305
  * - `__pl_data_initial`: returns initial data for new blocks
161
- * - `__pl_data_upgrade`: upgrades versioned data from any version to latest
306
+ * - `__pl_data_migrate`: migrates versioned data from any version to latest
162
307
  * - `__pl_storage_initial`: returns initial BlockStorage as JSON string
163
308
  */
164
309
  registerCallbacks(): void {
165
- tryRegisterCallback('__pl_data_initial', () => this._initialData());
166
- tryRegisterCallback('__pl_data_upgrade', (versioned: Versioned<unknown>) => this.upgrade(versioned));
310
+ tryRegisterCallback('__pl_data_initial', () => this.initialDataFn());
311
+ tryRegisterCallback('__pl_data_migrate', (versioned: DataVersioned<unknown>) => this.migrate(versioned));
167
312
  tryRegisterCallback('__pl_storage_initial', () => {
168
313
  const { version, data } = this.getDefaultData();
169
314
  const storage = createBlockStorage(data, version);