forked from LedgerHQ/ledger-live-common
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDataModel.ts
64 lines (57 loc) · 1.43 KB
/
DataModel.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/**
* Interface for the end user.
* @memberof DataModel
*/
export type DataModel<R, M> = {
// R: Raw , M: Model
// import a given version of rawData back into model
decode(rawModel: { data: R; version: number }): M;
// export data into a serializable object (can be saved to a JSON file)
encode(model: M): {
data: R;
version: number;
};
// current version of the model
version: number;
};
/**
* this is to be implemented to create a DataModel
* @memberof DataModel
*/
export type DataSchema<R, M> = {
// write extra logic to transform raw data into your model
decode(raw: R): M;
// reverse version of wrap, that will transform it back to a serializable object
encode(data: M): R;
// A map of migrations functions that are unrolled when an old version is imported
migrations: Array<(arg0: any) => R | any>;
};
/**
* @memberof DataModel
*/
export function createDataModel<R, M>(
schema: DataSchema<R, M>
): DataModel<R, M> {
const { migrations, encode, decode } = schema;
const version = migrations.length;
function decodeModel(raw) {
let { data } = raw;
for (let i = raw.version; i < version; i++) {
data = migrations[i](data);
}
data = decode(data);
return data;
}
function encodeModel(model) {
const data = encode(model);
return {
data,
version,
};
}
return Object.freeze({
version,
decode: decodeModel,
encode: encodeModel,
});
}