Expressions/migrations2 (#81281)

This commit is contained in:
Peter Pisljar 2020-10-30 06:01:45 +01:00 committed by GitHub
parent 4f717708b4
commit 076bb734c7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 296 additions and 7 deletions

View file

@ -39,6 +39,8 @@ export declare class Executor<Context extends Record<string, unknown> = Record<s
| [getType(name)](./kibana-plugin-plugins-expressions-public.executor.gettype.md) | | |
| [getTypes()](./kibana-plugin-plugins-expressions-public.executor.gettypes.md) | | |
| [inject(ast, references)](./kibana-plugin-plugins-expressions-public.executor.inject.md) | | |
| [migrate(ast, version)](./kibana-plugin-plugins-expressions-public.executor.migrate.md) | | |
| [migrateToLatest(ast, version)](./kibana-plugin-plugins-expressions-public.executor.migratetolatest.md) | | |
| [registerFunction(functionDefinition)](./kibana-plugin-plugins-expressions-public.executor.registerfunction.md) | | |
| [registerType(typeDefinition)](./kibana-plugin-plugins-expressions-public.executor.registertype.md) | | |
| [run(ast, input, params)](./kibana-plugin-plugins-expressions-public.executor.run.md) | | Execute expression and return result. |

View file

@ -0,0 +1,23 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) &gt; [Executor](./kibana-plugin-plugins-expressions-public.executor.md) &gt; [migrate](./kibana-plugin-plugins-expressions-public.executor.migrate.md)
## Executor.migrate() method
<b>Signature:</b>
```typescript
migrate(ast: SerializableState, version: string): ExpressionAstExpression;
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| ast | <code>SerializableState</code> | |
| version | <code>string</code> | |
<b>Returns:</b>
`ExpressionAstExpression`

View file

@ -0,0 +1,23 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) &gt; [Executor](./kibana-plugin-plugins-expressions-public.executor.md) &gt; [migrateToLatest](./kibana-plugin-plugins-expressions-public.executor.migratetolatest.md)
## Executor.migrateToLatest() method
<b>Signature:</b>
```typescript
migrateToLatest(ast: unknown, version: string): ExpressionAstExpression;
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| ast | <code>unknown</code> | |
| version | <code>string</code> | |
<b>Returns:</b>
`ExpressionAstExpression`

View file

@ -29,6 +29,7 @@ export declare class ExpressionFunction implements PersistableState<ExpressionAs
| [help](./kibana-plugin-plugins-expressions-public.expressionfunction.help.md) | | <code>string</code> | A short help text. |
| [inject](./kibana-plugin-plugins-expressions-public.expressionfunction.inject.md) | | <code>(state: ExpressionAstFunction['arguments'], references: SavedObjectReference[]) =&gt; ExpressionAstFunction['arguments']</code> | |
| [inputTypes](./kibana-plugin-plugins-expressions-public.expressionfunction.inputtypes.md) | | <code>string[] &#124; undefined</code> | Type of inputs that this function supports. |
| [migrations](./kibana-plugin-plugins-expressions-public.expressionfunction.migrations.md) | | <code>{</code><br/><code> [key: string]: (state: SerializableState) =&gt; SerializableState;</code><br/><code> }</code> | |
| [name](./kibana-plugin-plugins-expressions-public.expressionfunction.name.md) | | <code>string</code> | Name of function |
| [telemetry](./kibana-plugin-plugins-expressions-public.expressionfunction.telemetry.md) | | <code>(state: ExpressionAstFunction['arguments'], telemetryData: Record&lt;string, any&gt;) =&gt; Record&lt;string, any&gt;</code> | |
| [type](./kibana-plugin-plugins-expressions-public.expressionfunction.type.md) | | <code>string</code> | Return type of function. This SHOULD be supplied. We use it for UI and autocomplete hinting. We may also use it for optimizations in the future. |

View file

@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) &gt; [ExpressionFunction](./kibana-plugin-plugins-expressions-public.expressionfunction.md) &gt; [migrations](./kibana-plugin-plugins-expressions-public.expressionfunction.migrations.md)
## ExpressionFunction.migrations property
<b>Signature:</b>
```typescript
migrations: {
[key: string]: (state: SerializableState) => SerializableState;
};
```

View file

@ -39,6 +39,8 @@ export declare class ExpressionsService implements PersistableState<ExpressionAs
| [getType](./kibana-plugin-plugins-expressions-public.expressionsservice.gettype.md) | | <code>ExpressionsServiceStart['getType']</code> | |
| [getTypes](./kibana-plugin-plugins-expressions-public.expressionsservice.gettypes.md) | | <code>() =&gt; ReturnType&lt;Executor['getTypes']&gt;</code> | Returns POJO map of all registered expression types, where keys are names of the types and values are <code>ExpressionType</code> instances. |
| [inject](./kibana-plugin-plugins-expressions-public.expressionsservice.inject.md) | | <code>(state: ExpressionAstExpression, references: SavedObjectReference[]) =&gt; ExpressionAstExpression</code> | Injects saved object references into expression AST |
| [migrate](./kibana-plugin-plugins-expressions-public.expressionsservice.migrate.md) | | <code>(state: SerializableState, version: string) =&gt; ExpressionAstExpression</code> | Injects saved object references into expression AST |
| [migrateToLatest](./kibana-plugin-plugins-expressions-public.expressionsservice.migratetolatest.md) | | <code>(state: unknown, version: string) =&gt; ExpressionAstExpression</code> | Injects saved object references into expression AST |
| [registerFunction](./kibana-plugin-plugins-expressions-public.expressionsservice.registerfunction.md) | | <code>(functionDefinition: AnyExpressionFunctionDefinition &#124; (() =&gt; AnyExpressionFunctionDefinition)) =&gt; void</code> | Register an expression function, which will be possible to execute as part of the expression pipeline.<!-- -->Below we register a function which simply sleeps for given number of milliseconds to delay the execution and outputs its input as-is.
```ts
expressions.registerFunction({

View file

@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) &gt; [ExpressionsService](./kibana-plugin-plugins-expressions-public.expressionsservice.md) &gt; [migrate](./kibana-plugin-plugins-expressions-public.expressionsservice.migrate.md)
## ExpressionsService.migrate property
Injects saved object references into expression AST
<b>Signature:</b>
```typescript
readonly migrate: (state: SerializableState, version: string) => ExpressionAstExpression;
```

View file

@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) &gt; [ExpressionsService](./kibana-plugin-plugins-expressions-public.expressionsservice.md) &gt; [migrateToLatest](./kibana-plugin-plugins-expressions-public.expressionsservice.migratetolatest.md)
## ExpressionsService.migrateToLatest property
Injects saved object references into expression AST
<b>Signature:</b>
```typescript
readonly migrateToLatest: (state: unknown, version: string) => ExpressionAstExpression;
```

View file

@ -39,6 +39,8 @@ export declare class Executor<Context extends Record<string, unknown> = Record<s
| [getType(name)](./kibana-plugin-plugins-expressions-server.executor.gettype.md) | | |
| [getTypes()](./kibana-plugin-plugins-expressions-server.executor.gettypes.md) | | |
| [inject(ast, references)](./kibana-plugin-plugins-expressions-server.executor.inject.md) | | |
| [migrate(ast, version)](./kibana-plugin-plugins-expressions-server.executor.migrate.md) | | |
| [migrateToLatest(ast, version)](./kibana-plugin-plugins-expressions-server.executor.migratetolatest.md) | | |
| [registerFunction(functionDefinition)](./kibana-plugin-plugins-expressions-server.executor.registerfunction.md) | | |
| [registerType(typeDefinition)](./kibana-plugin-plugins-expressions-server.executor.registertype.md) | | |
| [run(ast, input, params)](./kibana-plugin-plugins-expressions-server.executor.run.md) | | Execute expression and return result. |

View file

@ -0,0 +1,23 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) &gt; [Executor](./kibana-plugin-plugins-expressions-server.executor.md) &gt; [migrate](./kibana-plugin-plugins-expressions-server.executor.migrate.md)
## Executor.migrate() method
<b>Signature:</b>
```typescript
migrate(ast: SerializableState, version: string): ExpressionAstExpression;
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| ast | <code>SerializableState</code> | |
| version | <code>string</code> | |
<b>Returns:</b>
`ExpressionAstExpression`

View file

@ -0,0 +1,23 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) &gt; [Executor](./kibana-plugin-plugins-expressions-server.executor.md) &gt; [migrateToLatest](./kibana-plugin-plugins-expressions-server.executor.migratetolatest.md)
## Executor.migrateToLatest() method
<b>Signature:</b>
```typescript
migrateToLatest(ast: unknown, version: string): ExpressionAstExpression;
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| ast | <code>unknown</code> | |
| version | <code>string</code> | |
<b>Returns:</b>
`ExpressionAstExpression`

View file

@ -29,6 +29,7 @@ export declare class ExpressionFunction implements PersistableState<ExpressionAs
| [help](./kibana-plugin-plugins-expressions-server.expressionfunction.help.md) | | <code>string</code> | A short help text. |
| [inject](./kibana-plugin-plugins-expressions-server.expressionfunction.inject.md) | | <code>(state: ExpressionAstFunction['arguments'], references: SavedObjectReference[]) =&gt; ExpressionAstFunction['arguments']</code> | |
| [inputTypes](./kibana-plugin-plugins-expressions-server.expressionfunction.inputtypes.md) | | <code>string[] &#124; undefined</code> | Type of inputs that this function supports. |
| [migrations](./kibana-plugin-plugins-expressions-server.expressionfunction.migrations.md) | | <code>{</code><br/><code> [key: string]: (state: SerializableState) =&gt; SerializableState;</code><br/><code> }</code> | |
| [name](./kibana-plugin-plugins-expressions-server.expressionfunction.name.md) | | <code>string</code> | Name of function |
| [telemetry](./kibana-plugin-plugins-expressions-server.expressionfunction.telemetry.md) | | <code>(state: ExpressionAstFunction['arguments'], telemetryData: Record&lt;string, any&gt;) =&gt; Record&lt;string, any&gt;</code> | |
| [type](./kibana-plugin-plugins-expressions-server.expressionfunction.type.md) | | <code>string</code> | Return type of function. This SHOULD be supplied. We use it for UI and autocomplete hinting. We may also use it for optimizations in the future. |

View file

@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) &gt; [ExpressionFunction](./kibana-plugin-plugins-expressions-server.expressionfunction.md) &gt; [migrations](./kibana-plugin-plugins-expressions-server.expressionfunction.migrations.md)
## ExpressionFunction.migrations property
<b>Signature:</b>
```typescript
migrations: {
[key: string]: (state: SerializableState) => SerializableState;
};
```

View file

@ -22,6 +22,7 @@ import * as expressionTypes from '../expression_types';
import * as expressionFunctions from '../expression_functions';
import { Execution } from '../execution';
import { ExpressionAstFunction, parseExpression } from '../ast';
import { MigrateFunction } from '../../../kibana_utils/common/persistable_state';
describe('Executor', () => {
test('can instantiate', () => {
@ -158,6 +159,7 @@ describe('Executor', () => {
const injectFn = jest.fn().mockImplementation((args, references) => args);
const extractFn = jest.fn().mockReturnValue({ args: {}, references: [] });
const migrateFn = jest.fn().mockImplementation((args) => args);
const fooFn = {
name: 'foo',
@ -174,6 +176,14 @@ describe('Executor', () => {
inject: (state: ExpressionAstFunction['arguments']) => {
return injectFn(state);
},
migrations: {
'7.10.0': (((state: ExpressionAstFunction, version: string): ExpressionAstFunction => {
return migrateFn(state, version);
}) as any) as MigrateFunction,
'7.10.1': (((state: ExpressionAstFunction, version: string): ExpressionAstFunction => {
return migrateFn(state, version);
}) as any) as MigrateFunction,
},
fn: jest.fn(),
};
executor.registerFunction(fooFn);
@ -194,5 +204,26 @@ describe('Executor', () => {
expect(extractFn).toBeCalledTimes(5);
});
});
describe('.migrate', () => {
test('calls migrate function for every expression function in expression', () => {
executor.migrate(
parseExpression('foo bar="baz" | foo bar={foo bar="baz" | foo bar={foo bar="baz"}}'),
'7.10.0'
);
expect(migrateFn).toBeCalledTimes(5);
});
});
describe('.migrateToLatest', () => {
test('calls extract function for every expression function in expression', () => {
migrateFn.mockClear();
executor.migrateToLatest(
parseExpression('foo bar="baz" | foo bar={foo bar="baz" | foo bar={foo bar="baz"}}'),
'7.10.0'
);
expect(migrateFn).toBeCalledTimes(10);
});
});
});
});

View file

@ -32,7 +32,7 @@ import { typeSpecs } from '../expression_types/specs';
import { functionSpecs } from '../expression_functions/specs';
import { getByAlias } from '../util';
import { SavedObjectReference } from '../../../../core/types';
import { PersistableState } from '../../../kibana_utils/common';
import { PersistableState, SerializableState } from '../../../kibana_utils/common';
import { ExpressionExecutionParams } from '../service';
export interface ExpressionExecOptions {
@ -88,6 +88,20 @@ export class FunctionsRegistry implements IRegistry<ExpressionFunction> {
}
}
const semverGte = (semver1: string, semver2: string) => {
const regex = /^([0-9]+)\.([0-9]+)\.([0-9]+)$/;
const matches1 = regex.exec(semver1) as RegExpMatchArray;
const matches2 = regex.exec(semver2) as RegExpMatchArray;
const [, major1, minor1, patch1] = matches1;
const [, major2, minor2, patch2] = matches2;
return (
major1 > major2 ||
(major1 === major2 && (minor1 > minor2 || (minor1 === minor2 && patch1 >= patch2)))
);
};
export class Executor<Context extends Record<string, unknown> = Record<string, unknown>>
implements PersistableState<ExpressionAstExpression> {
static createWithDefaults<Ctx extends Record<string, unknown> = Record<string, unknown>>(
@ -249,6 +263,27 @@ export class Executor<Context extends Record<string, unknown> = Record<string, u
return telemetryData;
}
public migrate(ast: SerializableState, version: string) {
return this.walkAst(cloneDeep(ast) as ExpressionAstExpression, (fn, link) => {
if (!fn.migrations[version]) return link;
const updatedAst = fn.migrations[version](link) as ExpressionAstFunction;
link.arguments = updatedAst.arguments;
link.type = updatedAst.type;
});
}
public migrateToLatest(ast: unknown, version: string) {
return this.walkAst(cloneDeep(ast) as ExpressionAstExpression, (fn, link) => {
for (const key of Object.keys(fn.migrations)) {
if (semverGte(key, version)) {
const updatedAst = fn.migrations[key](link) as ExpressionAstFunction;
link.arguments = updatedAst.arguments;
link.type = updatedAst.type;
}
}
});
}
public fork(): Executor<Context> {
const initialState = this.state.get();
const fork = new Executor<Context>(initialState);

View file

@ -24,7 +24,7 @@ import { ExpressionValue } from '../expression_types/types';
import { ExecutionContext } from '../execution';
import { ExpressionAstFunction } from '../ast';
import { SavedObjectReference } from '../../../../core/types';
import { PersistableState } from '../../../kibana_utils/common';
import { PersistableState, SerializableState } from '../../../kibana_utils/common';
export class ExpressionFunction implements PersistableState<ExpressionAstFunction['arguments']> {
/**
@ -76,6 +76,9 @@ export class ExpressionFunction implements PersistableState<ExpressionAstFunctio
state: ExpressionAstFunction['arguments'],
references: SavedObjectReference[]
) => ExpressionAstFunction['arguments'];
migrations: {
[key: string]: (state: SerializableState) => SerializableState;
};
constructor(functionDefinition: AnyExpressionFunctionDefinition) {
const {
@ -91,6 +94,7 @@ export class ExpressionFunction implements PersistableState<ExpressionAstFunctio
telemetry,
inject,
extract,
migrations,
} = functionDefinition;
this.name = name;
@ -104,6 +108,7 @@ export class ExpressionFunction implements PersistableState<ExpressionAstFunctio
this.telemetry = telemetry || ((s, c) => c);
this.inject = inject || identity;
this.extract = extract || ((s) => ({ state: s, references: [] }));
this.migrations = migrations || {};
for (const [key, arg] of Object.entries(args || {})) {
this.args[key] = new ExpressionFunctionParameter(key, arg);

View file

@ -24,7 +24,7 @@ import { ExecutionContract } from '../execution/execution_contract';
import { AnyExpressionTypeDefinition } from '../expression_types';
import { AnyExpressionFunctionDefinition } from '../expression_functions';
import { SavedObjectReference } from '../../../../core/types';
import { PersistableState } from '../../../kibana_utils/common';
import { PersistableState, SerializableState } from '../../../kibana_utils/common';
import { Adapters } from '../../../inspector/common/adapters';
import { ExecutionContextSearch } from '../execution';
@ -303,6 +303,26 @@ export class ExpressionsService implements PersistableState<ExpressionAstExpress
return this.executor.inject(state, references);
};
/**
* Runs the migration (if it exists) for specified version. This will run a single migration step (ie from 7.10.0 to 7.10.1)
* @param state expression AST to update
* @param version defines which migration version to run
* @returns new migrated expression AST
*/
public readonly migrate = (state: SerializableState, version: string) => {
return this.executor.migrate(state, version);
};
/**
* Migrates expression to the latest version
* @param state expression AST to update
* @param version the version of kibana in which expression was created
* @returns migrated expression AST
*/
public readonly migrateToLatest = (state: unknown, version: string) => {
return this.executor.migrateToLatest(state, version);
};
/**
* Returns Kibana Platform *setup* life-cycle contract. Useful to return the
* same contract on server-side and browser-side.

View file

@ -222,6 +222,12 @@ export class Executor<Context extends Record<string, unknown> = Record<string, u
//
// (undocumented)
inject(ast: ExpressionAstExpression, references: SavedObjectReference[]): ExpressionAstExpression;
// Warning: (ae-forgotten-export) The symbol "SerializableState" needs to be exported by the entry point index.d.ts
//
// (undocumented)
migrate(ast: SerializableState, version: string): ExpressionAstExpression;
// (undocumented)
migrateToLatest(ast: unknown, version: string): ExpressionAstExpression;
// (undocumented)
registerFunction(functionDefinition: AnyExpressionFunctionDefinition | (() => AnyExpressionFunctionDefinition)): void;
// (undocumented)
@ -342,6 +348,10 @@ export class ExpressionFunction implements PersistableState<ExpressionAstFunctio
// (undocumented)
inject: (state: ExpressionAstFunction['arguments'], references: SavedObjectReference[]) => ExpressionAstFunction['arguments'];
inputTypes: string[] | undefined;
// (undocumented)
migrations: {
[key: string]: (state: SerializableState) => SerializableState;
};
name: string;
// (undocumented)
telemetry: (state: ExpressionAstFunction['arguments'], telemetryData: Record<string, any>) => Record<string, any>;
@ -586,6 +596,8 @@ export class ExpressionsService implements PersistableState<ExpressionAstExpress
readonly getType: ExpressionsServiceStart['getType'];
readonly getTypes: () => ReturnType<Executor['getTypes']>;
readonly inject: (state: ExpressionAstExpression, references: SavedObjectReference[]) => ExpressionAstExpression;
readonly migrate: (state: SerializableState, version: string) => ExpressionAstExpression;
readonly migrateToLatest: (state: unknown, version: string) => ExpressionAstExpression;
readonly registerFunction: (functionDefinition: AnyExpressionFunctionDefinition | (() => AnyExpressionFunctionDefinition)) => void;
// (undocumented)
readonly registerRenderer: (definition: AnyExpressionRenderDefinition | (() => AnyExpressionRenderDefinition)) => void;
@ -1149,7 +1161,6 @@ export type UnmappedTypeStrings = 'date' | 'filter';
//
// src/plugins/expressions/common/ast/types.ts:40:3 - (ae-forgotten-export) The symbol "ExpressionAstFunctionDebug" needs to be exported by the entry point index.d.ts
// src/plugins/expressions/common/expression_types/specs/error.ts:31:5 - (ae-forgotten-export) The symbol "ErrorLike" needs to be exported by the entry point index.d.ts
// src/plugins/expressions/common/expression_types/specs/error.ts:32:5 - (ae-forgotten-export) The symbol "SerializableState" needs to be exported by the entry point index.d.ts
// (No @packageDocumentation comment for this package)

View file

@ -204,6 +204,12 @@ export class Executor<Context extends Record<string, unknown> = Record<string, u
//
// (undocumented)
inject(ast: ExpressionAstExpression, references: SavedObjectReference[]): ExpressionAstExpression;
// Warning: (ae-forgotten-export) The symbol "SerializableState" needs to be exported by the entry point index.d.ts
//
// (undocumented)
migrate(ast: SerializableState, version: string): ExpressionAstExpression;
// (undocumented)
migrateToLatest(ast: unknown, version: string): ExpressionAstExpression;
// (undocumented)
registerFunction(functionDefinition: AnyExpressionFunctionDefinition | (() => AnyExpressionFunctionDefinition)): void;
// (undocumented)
@ -314,6 +320,10 @@ export class ExpressionFunction implements PersistableState<ExpressionAstFunctio
// (undocumented)
inject: (state: ExpressionAstFunction['arguments'], references: SavedObjectReference[]) => ExpressionAstFunction['arguments'];
inputTypes: string[] | undefined;
// (undocumented)
migrations: {
[key: string]: (state: SerializableState) => SerializableState;
};
name: string;
// (undocumented)
telemetry: (state: ExpressionAstFunction['arguments'], telemetryData: Record<string, any>) => Record<string, any>;
@ -939,7 +949,6 @@ export type UnmappedTypeStrings = 'date' | 'filter';
//
// src/plugins/expressions/common/ast/types.ts:40:3 - (ae-forgotten-export) The symbol "ExpressionAstFunctionDebug" needs to be exported by the entry point index.d.ts
// src/plugins/expressions/common/expression_types/specs/error.ts:31:5 - (ae-forgotten-export) The symbol "ErrorLike" needs to be exported by the entry point index.d.ts
// src/plugins/expressions/common/expression_types/specs/error.ts:32:5 - (ae-forgotten-export) The symbol "SerializableState" needs to be exported by the entry point index.d.ts
// (No @packageDocumentation comment for this package)

View file

@ -27,6 +27,11 @@ export type SerializableState = {
[key: string]: Serializable;
};
export type MigrateFunction<
FromVersion extends SerializableState = SerializableState,
ToVersion extends SerializableState = SerializableState
> = (state: FromVersion) => ToVersion;
export interface PersistableState<P extends SerializableState = SerializableState> {
/**
* function to extract telemetry information
@ -47,8 +52,29 @@ export interface PersistableState<P extends SerializableState = SerializableStat
* @param state
*/
extract: (state: P) => { state: P; references: SavedObjectReference[] };
/**
* migrateToLatest function receives state of older version and should migrate to the latest version
* @param state
* @param version
*/
migrateToLatest?: (state: SerializableState, version: string) => P;
/**
* migrate function runs the specified migration
* @param state
* @param version
*/
migrate?: (state: SerializableState, version: string) => SerializableState;
}
export type PersistableStateDefinition<P extends SerializableState = SerializableState> = Partial<
PersistableState<P>
>;
Omit<PersistableState<P>, 'migrate'>
> & {
/**
* list of all migrations per semver
*/
migrations?: {
[key: string]: MigrateFunction;
};
};