@elaraai/e3 1.0.79 → 1.0.80
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/README.md +11 -2
- package/dist/src/browser.d.ts +5 -4
- package/dist/src/browser.d.ts.map +1 -1
- package/dist/src/browser.js +3 -2
- package/dist/src/browser.js.map +1 -1
- package/dist/src/dataset-file.d.ts +17 -19
- package/dist/src/dataset-file.d.ts.map +1 -1
- package/dist/src/dataset-file.js +26 -45
- package/dist/src/dataset-file.js.map +1 -1
- package/dist/src/export.d.ts +2 -3
- package/dist/src/export.d.ts.map +1 -1
- package/dist/src/export.js +150 -80
- package/dist/src/export.js.map +1 -1
- package/dist/src/export.spec.js +177 -57
- package/dist/src/export.spec.js.map +1 -1
- package/dist/src/function.spec.js +29 -58
- package/dist/src/function.spec.js.map +1 -1
- package/dist/src/functions-link.spec.js +19 -17
- package/dist/src/functions-link.spec.js.map +1 -1
- package/dist/src/index.d.ts +56 -8
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +11 -4
- package/dist/src/index.js.map +1 -1
- package/dist/src/input.d.ts +8 -5
- package/dist/src/input.d.ts.map +1 -1
- package/dist/src/input.js +8 -5
- package/dist/src/input.js.map +1 -1
- package/dist/src/migration.d.ts +172 -0
- package/dist/src/migration.d.ts.map +1 -0
- package/dist/src/migration.js +108 -0
- package/dist/src/migration.js.map +1 -0
- package/dist/src/migration.spec.d.ts +6 -0
- package/dist/src/migration.spec.d.ts.map +1 -0
- package/dist/src/migration.spec.js +197 -0
- package/dist/src/migration.spec.js.map +1 -0
- package/dist/src/mutation-programs.spec.d.ts +6 -0
- package/dist/src/mutation-programs.spec.d.ts.map +1 -0
- package/dist/src/mutation-programs.spec.js +310 -0
- package/dist/src/mutation-programs.spec.js.map +1 -0
- package/dist/src/mutation.d.ts +117 -9
- package/dist/src/mutation.d.ts.map +1 -1
- package/dist/src/mutation.js +104 -46
- package/dist/src/mutation.js.map +1 -1
- package/dist/src/open-beast-link.spec.js +10 -8
- package/dist/src/open-beast-link.spec.js.map +1 -1
- package/dist/src/output.d.ts +117 -0
- package/dist/src/output.d.ts.map +1 -0
- package/dist/src/output.js +119 -0
- package/dist/src/output.js.map +1 -0
- package/dist/src/package.d.ts +7 -5
- package/dist/src/package.d.ts.map +1 -1
- package/dist/src/package.js +98 -8
- package/dist/src/package.js.map +1 -1
- package/dist/src/package.spec.d.ts +6 -0
- package/dist/src/package.spec.d.ts.map +1 -0
- package/dist/src/package.spec.js +16 -0
- package/dist/src/package.spec.js.map +1 -0
- package/dist/src/record-guards.d.ts +41 -0
- package/dist/src/record-guards.d.ts.map +1 -0
- package/dist/src/record-guards.js +44 -0
- package/dist/src/record-guards.js.map +1 -0
- package/dist/src/record-index.d.ts +129 -0
- package/dist/src/record-index.d.ts.map +1 -0
- package/dist/src/record-index.js +144 -0
- package/dist/src/record-index.js.map +1 -0
- package/dist/src/record-index.spec.d.ts +6 -0
- package/dist/src/record-index.spec.d.ts.map +1 -0
- package/dist/src/record-index.spec.js +160 -0
- package/dist/src/record-index.spec.js.map +1 -0
- package/dist/src/record-programs.d.ts +128 -0
- package/dist/src/record-programs.d.ts.map +1 -0
- package/dist/src/record-programs.js +480 -0
- package/dist/src/record-programs.js.map +1 -0
- package/dist/src/record.d.ts.map +1 -1
- package/dist/src/record.js +2 -0
- package/dist/src/record.js.map +1 -1
- package/dist/src/record.spec.js +71 -13
- package/dist/src/record.spec.js.map +1 -1
- package/dist/src/runner.d.ts +6 -9
- package/dist/src/runner.d.ts.map +1 -1
- package/dist/src/runner.js +9 -25
- package/dist/src/runner.js.map +1 -1
- package/dist/src/runner.spec.js +16 -34
- package/dist/src/runner.spec.js.map +1 -1
- package/dist/src/sha256.d.ts +4 -3
- package/dist/src/sha256.d.ts.map +1 -1
- package/dist/src/sha256.js +20 -17
- package/dist/src/sha256.js.map +1 -1
- package/dist/src/sha256.spec.js +10 -0
- package/dist/src/sha256.spec.js.map +1 -1
- package/dist/src/task.d.ts +116 -251
- package/dist/src/task.d.ts.map +1 -1
- package/dist/src/task.js +169 -435
- package/dist/src/task.js.map +1 -1
- package/dist/src/task.spec.js +174 -489
- package/dist/src/task.spec.js.map +1 -1
- package/dist/src/types.d.ts +215 -23
- package/dist/src/types.d.ts.map +1 -1
- package/package.json +4 -4
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Migration definitions for e3 records: the steps a deploy runs over a
|
|
7
|
+
* workspace's state when a package changes a record's type, or its values.
|
|
8
|
+
*
|
|
9
|
+
* A record's migrations are one chain. Each step names the one before it with
|
|
10
|
+
* `after`, and `e3.package` folds the chain onto its record in order. A deploy
|
|
11
|
+
* runs the steps a workspace has not applied and records each by its name, so
|
|
12
|
+
* a step keeps its identity when its code moves or its package is re-exported.
|
|
13
|
+
*
|
|
14
|
+
* The three forms differ in what the author's function sees, and so in what a
|
|
15
|
+
* step costs: `e3.migration.value` the whole state, `e3.migration.rows` one
|
|
16
|
+
* row at a time, and `e3.migration.rekey` one row at a time under a new key.
|
|
17
|
+
* Each function is pure East for the reason a mutation's is: a step runs again
|
|
18
|
+
* in every workspace that has not applied it, a piece at a time, and must
|
|
19
|
+
* migrate every one the same way.
|
|
20
|
+
*/
|
|
21
|
+
import type { CallableFunctionExpr, EastType, FunctionExpr, StructType } from '@elaraai/east';
|
|
22
|
+
import { ArrayType, DictType, SetType } from '@elaraai/east';
|
|
23
|
+
import type { MigrationDef, RecordDef } from './types.js';
|
|
24
|
+
import { type FunctionRunner } from './runner.js';
|
|
25
|
+
/**
|
|
26
|
+
* What a migration's declaration may add to its function.
|
|
27
|
+
*/
|
|
28
|
+
export type MigrationConfig = {
|
|
29
|
+
/** The step before this one, a migration of the same record. The chain's
|
|
30
|
+
* first step has none. */
|
|
31
|
+
readonly after?: MigrationDef;
|
|
32
|
+
/** Runner selection (known runtimes only, like e3.function). */
|
|
33
|
+
readonly runner?: FunctionRunner;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Defines a migration of a record's whole state, from its old type to its new.
|
|
37
|
+
*
|
|
38
|
+
* The function is `(Old) => New`, for a record of any type. It runs as one
|
|
39
|
+
* unit whose runner opens the state lazily, so a step that reads little of a
|
|
40
|
+
* large record costs little, and one that rebuilds it costs the record.
|
|
41
|
+
* {@link rows} and {@link rekey} migrate a collection a piece at a time.
|
|
42
|
+
*
|
|
43
|
+
* The function must be pure, synchronous East, as a mutation's reducer is: a
|
|
44
|
+
* step runs again in every workspace that has not applied it. Its types are
|
|
45
|
+
* read off its signature, and its chain is checked where it is declared: the
|
|
46
|
+
* step it names as `after` must be a migration of the same record that leaves
|
|
47
|
+
* the record as this step's `Old`. `e3.package` checks that the record's last
|
|
48
|
+
* step leaves it as its declared type.
|
|
49
|
+
*
|
|
50
|
+
* @typeParam Name - Migration name (literal type)
|
|
51
|
+
* @typeParam T - The record's declared state type
|
|
52
|
+
* @typeParam From - The record's type before the step
|
|
53
|
+
* @typeParam To - The record's type after it
|
|
54
|
+
* @param name - Migration name: an identifier, unique on the record, by which
|
|
55
|
+
* a workspace records that it has applied the step
|
|
56
|
+
* @param rec - The record this migration changes
|
|
57
|
+
* @param fn - `(Old) => New`
|
|
58
|
+
* @param config - The step before this one, and the runner
|
|
59
|
+
* @returns A MigrationDef to pass to `e3.package`
|
|
60
|
+
* @throws {Error} When the name is not an identifier, the function is async,
|
|
61
|
+
* calls a platform function or takes other than the one state, or `after`
|
|
62
|
+
* is another record's step or leaves the record as another type than `Old`.
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```ts
|
|
66
|
+
* const RosterV1Type = DictType(StringType, StructType({ name: StringType }));
|
|
67
|
+
* const RosterV2Type = DictType(StringType, StructType({ name: StringType, shift: StringType }));
|
|
68
|
+
* const roster = e3.record('roster', RosterV2Type, new Map());
|
|
69
|
+
*
|
|
70
|
+
* // Every row gains a shift, from the whole state.
|
|
71
|
+
* const addShift = e3.migration.value('add_shift', roster,
|
|
72
|
+
* East.function([RosterV1Type], RosterV2Type, ($, old) =>
|
|
73
|
+
* old.map(($, row) => ({ name: row.name, shift: 'day' }))));
|
|
74
|
+
*
|
|
75
|
+
* const pkg = e3.package('planning', '2.0.0', roster, addShift);
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
78
|
+
declare function value<Name extends string, T extends EastType, From extends EastType, To extends EastType>(name: Name, rec: RecordDef<T>, fn: FunctionExpr<[From], To> | CallableFunctionExpr<[From], To>, config?: MigrationConfig): MigrationDef<Name, T, From, To>;
|
|
79
|
+
/**
|
|
80
|
+
* Defines a migration of a collection record's rows, one at a time: a Dict's
|
|
81
|
+
* rows with its keys unchanged, or an Array's elements in order.
|
|
82
|
+
*
|
|
83
|
+
* The function is `(K, V1) => V2` for a Dict, whose key it may read, or
|
|
84
|
+
* `(T1) => T2` for an Array; its parameters say which. The step runs as a task
|
|
85
|
+
* split over the stored state, so a record of any size migrates a piece at a
|
|
86
|
+
* time, in parallel, each piece cached, and none holds more than its piece.
|
|
87
|
+
*
|
|
88
|
+
* The purity rules and chain checks of {@link value} apply unchanged.
|
|
89
|
+
*
|
|
90
|
+
* @typeParam Name - Migration name (literal type)
|
|
91
|
+
* @typeParam T - The record's declared state type
|
|
92
|
+
* @param name - Migration name: an identifier, unique on the record
|
|
93
|
+
* @param rec - The record this migration changes
|
|
94
|
+
* @param fn - `(T1) => T2` over an Array's elements, or `(K, V1) => V2` over a
|
|
95
|
+
* Dict's rows
|
|
96
|
+
* @param config - The step before this one, and the runner
|
|
97
|
+
* @returns A MigrationDef to pass to `e3.package`
|
|
98
|
+
* @throws {Error} When the name is not an identifier, the function is async,
|
|
99
|
+
* calls a platform function or takes other than one or two parameters, or
|
|
100
|
+
* `after` is another record's step or leaves the record as another type.
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* ```ts
|
|
104
|
+
* const RowV1Type = StructType({ title: StringType });
|
|
105
|
+
* const RowV2Type = StructType({ title: StringType, owner: StringType });
|
|
106
|
+
* const plans = e3.record('plans', DictType(StringType, RowV2Type), new Map());
|
|
107
|
+
*
|
|
108
|
+
* // Each row gains an owner; the keys are unchanged.
|
|
109
|
+
* const addOwner = e3.migration.rows('add_owner', plans,
|
|
110
|
+
* East.function([StringType, RowV1Type], RowV2Type,
|
|
111
|
+
* ($, id, row) => ({ title: row.title, owner: 'unassigned' })));
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
114
|
+
declare function rows<Name extends string, T extends EastType, E1 extends EastType, E2 extends EastType>(name: Name, rec: RecordDef<T>, fn: FunctionExpr<[E1], E2> | CallableFunctionExpr<[E1], E2>, config?: MigrationConfig): MigrationDef<Name, T, ArrayType<E1>, ArrayType<E2>>;
|
|
115
|
+
declare function rows<Name extends string, T extends EastType, K extends EastType, V1 extends EastType, V2 extends EastType>(name: Name, rec: RecordDef<T>, fn: FunctionExpr<[K, V1], V2> | CallableFunctionExpr<[K, V1], V2>, config?: MigrationConfig): MigrationDef<Name, T, DictType<K, V1>, DictType<K, V2>>;
|
|
116
|
+
/**
|
|
117
|
+
* Defines a migration that re-keys a collection record: a Dict's entries under
|
|
118
|
+
* new keys, or a Set's elements.
|
|
119
|
+
*
|
|
120
|
+
* The function is `(K1, V1) => { key: K2, value: V2 }` for a Dict, or
|
|
121
|
+
* `(T1) => T2` for a Set; its parameters say which. It is the task {@link rows}
|
|
122
|
+
* runs, over each piece of the stored state, and the pieces' outputs are merged
|
|
123
|
+
* by key. Two rows of a Dict landing on one key fail the deploy, naming it,
|
|
124
|
+
* since their values may differ and neither can be chosen; two elements of a
|
|
125
|
+
* Set landing on one are one element, as in any Set, and nothing is lost.
|
|
126
|
+
*
|
|
127
|
+
* The purity rules and chain checks of {@link value} apply unchanged.
|
|
128
|
+
*
|
|
129
|
+
* @typeParam Name - Migration name (literal type)
|
|
130
|
+
* @typeParam T - The record's declared state type
|
|
131
|
+
* @param name - Migration name: an identifier, unique on the record
|
|
132
|
+
* @param rec - The record this migration changes
|
|
133
|
+
* @param fn - `(T1) => T2` over a Set's elements, or
|
|
134
|
+
* `(K1, V1) => { key: K2, value: V2 }` over a Dict's entries
|
|
135
|
+
* @param config - The step before this one, and the runner
|
|
136
|
+
* @returns A MigrationDef to pass to `e3.package`
|
|
137
|
+
* @throws {Error} When the name is not an identifier, the function is async,
|
|
138
|
+
* calls a platform function, takes other than one or two parameters, or over
|
|
139
|
+
* a Dict returns other than `{ key, value }`, when the new key is not a type
|
|
140
|
+
* a key may be, or when `after` is another record's step or leaves the record
|
|
141
|
+
* as another type.
|
|
142
|
+
*
|
|
143
|
+
* @example
|
|
144
|
+
* ```ts
|
|
145
|
+
* const PlanType = StructType({ site: StringType, title: StringType });
|
|
146
|
+
* const plans = e3.record('plans', DictType(StringType, PlanType), new Map());
|
|
147
|
+
*
|
|
148
|
+
* // Plans were keyed by a number; they are keyed by site and title.
|
|
149
|
+
* const bySite = e3.migration.rekey('by_site', plans,
|
|
150
|
+
* East.function([IntegerType, PlanType], StructType({ key: StringType, value: PlanType }),
|
|
151
|
+
* ($, id, plan) => ({ key: East.str`${plan.site}/${plan.title}`, value: plan })));
|
|
152
|
+
* ```
|
|
153
|
+
*/
|
|
154
|
+
declare function rekey<Name extends string, T extends EastType, E1 extends EastType, E2 extends EastType>(name: Name, rec: RecordDef<T>, fn: FunctionExpr<[E1], E2> | CallableFunctionExpr<[E1], E2>, config?: MigrationConfig): MigrationDef<Name, T, SetType<E1>, SetType<E2>>;
|
|
155
|
+
declare function rekey<Name extends string, T extends EastType, K1 extends EastType, V1 extends EastType, K2 extends EastType, V2 extends EastType>(name: Name, rec: RecordDef<T>, fn: FunctionExpr<[K1, V1], StructType<{
|
|
156
|
+
key: K2;
|
|
157
|
+
value: V2;
|
|
158
|
+
}>> | CallableFunctionExpr<[K1, V1], StructType<{
|
|
159
|
+
key: K2;
|
|
160
|
+
value: V2;
|
|
161
|
+
}>>, config?: MigrationConfig): MigrationDef<Name, T, DictType<K1, V1>, DictType<K2, V2>>;
|
|
162
|
+
/**
|
|
163
|
+
* The migration forms of a record: {@link value}, {@link rows} and
|
|
164
|
+
* {@link rekey}.
|
|
165
|
+
*/
|
|
166
|
+
export declare const migration: {
|
|
167
|
+
value: typeof value;
|
|
168
|
+
rows: typeof rows;
|
|
169
|
+
rekey: typeof rekey;
|
|
170
|
+
};
|
|
171
|
+
export {};
|
|
172
|
+
//# sourceMappingURL=migration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration.d.ts","sourceRoot":"","sources":["../../src/migration.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
import { ArrayType, DictType, Expr, SetType, printType } from '@elaraai/east';
|
|
6
|
+
import { checkPure, sameEastType } from './record-guards.js';
|
|
7
|
+
import { DEFAULT_RUNNER, runnerToVariant } from './runner.js';
|
|
8
|
+
/** A migration's name is an identifier, as an index's is: a workspace records
|
|
9
|
+
* the steps it has applied by their names. */
|
|
10
|
+
const IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
11
|
+
/**
|
|
12
|
+
* Checks a step and declares it, with the record's types before and after it
|
|
13
|
+
* as its function's signature gives them.
|
|
14
|
+
*
|
|
15
|
+
* @throws {Error} When the name is not an identifier, the runner is not a known
|
|
16
|
+
* runtime, the function is async or calls a platform function, its signature
|
|
17
|
+
* is not the form's, or `after` is another record's step or leaves the record
|
|
18
|
+
* as another type than this step takes.
|
|
19
|
+
*/
|
|
20
|
+
function declare(form, name, rec, fn, config, recordTypes) {
|
|
21
|
+
const surface = `e3.migration.${form}`;
|
|
22
|
+
if (!IDENTIFIER.test(name)) {
|
|
23
|
+
throw new Error(`${surface} requires a name that is an identifier, got '${name}' — a workspace records ` +
|
|
24
|
+
`the steps it has applied by their names.`);
|
|
25
|
+
}
|
|
26
|
+
const subject = `${surface} '${name}'`;
|
|
27
|
+
const runner = config?.runner ?? DEFAULT_RUNNER;
|
|
28
|
+
// Validate eagerly so a bad runner fails at definition time, not export time.
|
|
29
|
+
runnerToVariant(runner);
|
|
30
|
+
checkPure(`${subject} function`, fn, {
|
|
31
|
+
async: 'an async function implies platform IO, and a migration runs again in every workspace that has not applied it.',
|
|
32
|
+
platform: 'a migration runs again in every workspace that has not applied it, a piece at a time, so a platform call makes the migrated record depend on where and when it ran.',
|
|
33
|
+
});
|
|
34
|
+
const { inputs, output } = Expr.type(fn);
|
|
35
|
+
let types;
|
|
36
|
+
try {
|
|
37
|
+
types = recordTypes(inputs, output);
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
throw new Error(`${subject}: ${err instanceof Error ? err.message : String(err)}`);
|
|
41
|
+
}
|
|
42
|
+
const after = config?.after;
|
|
43
|
+
if (after !== undefined) {
|
|
44
|
+
if (after.record.name !== rec.name) {
|
|
45
|
+
throw new Error(`${subject} follows '${after.name}', a migration of record '${after.record.name}' — a step ` +
|
|
46
|
+
`follows a migration of its own record, '${rec.name}'.`);
|
|
47
|
+
}
|
|
48
|
+
if (!sameEastType(after.to, types.from)) {
|
|
49
|
+
throw new Error(`${subject} takes the record as ${printType(types.from)}, but '${after.name}', the step ` +
|
|
50
|
+
`before it, leaves it as ${printType(after.to)}.`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
kind: 'migration',
|
|
55
|
+
name,
|
|
56
|
+
record: rec,
|
|
57
|
+
form,
|
|
58
|
+
from: types.from,
|
|
59
|
+
to: types.to,
|
|
60
|
+
// Keep the full EastIR bundle (IR + source map) so export.ts can encode
|
|
61
|
+
// with encodeEastIR and preserve source locations.
|
|
62
|
+
body: fn.toIR(),
|
|
63
|
+
fn,
|
|
64
|
+
...(after !== undefined && { after }),
|
|
65
|
+
runner,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function value(name, rec, fn, config) {
|
|
69
|
+
return declare('value', name, rec, fn, config, (inputs, output) => {
|
|
70
|
+
if (inputs.length !== 1) {
|
|
71
|
+
throw new Error(`a value step's function takes the record's state alone, but takes ${inputs.length} parameters.`);
|
|
72
|
+
}
|
|
73
|
+
return { from: inputs[0], to: output };
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
function rows(name, rec, fn, config) {
|
|
77
|
+
return declare('rows', name, rec, fn, config, (inputs, output) => {
|
|
78
|
+
if (inputs.length === 1)
|
|
79
|
+
return { from: ArrayType(inputs[0]), to: ArrayType(output) };
|
|
80
|
+
if (inputs.length === 2)
|
|
81
|
+
return { from: DictType(inputs[0], inputs[1]), to: DictType(inputs[0], output) };
|
|
82
|
+
throw new Error(`a rows step's function takes a Dict's row, (key, value), or an Array's element, but takes ` +
|
|
83
|
+
`${inputs.length} parameters.`);
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
function rekey(name, rec, fn, config) {
|
|
87
|
+
return declare('rekey', name, rec, fn, config, (inputs, output) => {
|
|
88
|
+
if (inputs.length === 1)
|
|
89
|
+
return { from: SetType(inputs[0]), to: SetType(output) };
|
|
90
|
+
if (inputs.length === 2) {
|
|
91
|
+
const entry = output;
|
|
92
|
+
const fields = entry.type === 'Struct' ? Object.keys(entry.fields) : [];
|
|
93
|
+
if (fields.length !== 2 || !fields.includes('key') || !fields.includes('value')) {
|
|
94
|
+
throw new Error(`a rekey step's function returns a Dict's entry under its new key, { key, value }, but ` +
|
|
95
|
+
`returns ${printType(output)}.`);
|
|
96
|
+
}
|
|
97
|
+
return { from: DictType(inputs[0], inputs[1]), to: DictType(entry.fields.key, entry.fields.value) };
|
|
98
|
+
}
|
|
99
|
+
throw new Error(`a rekey step's function takes a Dict's entry, (key, value), or a Set's element, but takes ` +
|
|
100
|
+
`${inputs.length} parameters.`);
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* The migration forms of a record: {@link value}, {@link rows} and
|
|
105
|
+
* {@link rekey}.
|
|
106
|
+
*/
|
|
107
|
+
export const migration = { value, rows, rekey };
|
|
108
|
+
//# sourceMappingURL=migration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration.js","sourceRoot":"","sources":["../../src/migration.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration.spec.d.ts","sourceRoot":"","sources":["../../src/migration.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* `e3.migration` — the three forms, the chain a package folds them into, and
|
|
7
|
+
* the program a `rows` or `rekey` step runs.
|
|
8
|
+
*
|
|
9
|
+
* Every guard is a definition-time error: a chain that cannot migrate a
|
|
10
|
+
* workspace is refused at the developer's desk, not by a deploy halfway
|
|
11
|
+
* through one. The programs are asserted by running them: each emits one entry
|
|
12
|
+
* per row as it reads the row, for the runner's output to sort, under the key
|
|
13
|
+
* the step gives it.
|
|
14
|
+
*/
|
|
15
|
+
import { describe, it } from 'node:test';
|
|
16
|
+
import assert from 'node:assert/strict';
|
|
17
|
+
import { ArrayType, DictType, East, IntegerType, SetType, SortedMap, SortedSet, StringType, StructType, compareFor, printType, } from '@elaraai/east';
|
|
18
|
+
import e3 from './index.js';
|
|
19
|
+
import { record } from './record.js';
|
|
20
|
+
import { migration } from './migration.js';
|
|
21
|
+
import { migrationProgram } from './record-programs.js';
|
|
22
|
+
import { package_ } from './package.js';
|
|
23
|
+
const RowV1Type = StructType({ title: StringType });
|
|
24
|
+
const RowV2Type = StructType({ title: StringType, owner: StringType });
|
|
25
|
+
const PlansV1Type = DictType(StringType, RowV1Type);
|
|
26
|
+
const PlansV2Type = DictType(StringType, RowV2Type);
|
|
27
|
+
const plans = () => record('plans', PlansV2Type, new Map());
|
|
28
|
+
/** A chain of one step of each form, in order: a repair that keeps the type,
|
|
29
|
+
* a new field on every row, and the rows keyed by title. */
|
|
30
|
+
function chain(rec = plans()) {
|
|
31
|
+
const normalize = migration.value('normalize', rec, East.function([PlansV1Type], PlansV1Type, ($, old) => old));
|
|
32
|
+
const addOwner = migration.rows('add_owner', rec, East.function([StringType, RowV1Type], RowV2Type, ($, _id, row) => ({ title: row.title, owner: 'unassigned' })), { after: normalize });
|
|
33
|
+
const byTitle = migration.rekey('by_title', rec, East.function([StringType, RowV2Type], StructType({ key: StringType, value: RowV2Type }), ($, _id, row) => ({ key: row.title, value: row })), { after: addOwner });
|
|
34
|
+
return { rec, normalize, addOwner, byTitle };
|
|
35
|
+
}
|
|
36
|
+
/** What a step's program emits for `piece`, one argument list per call. */
|
|
37
|
+
function emitted(def, piece) {
|
|
38
|
+
const out = [];
|
|
39
|
+
const run = migrationProgram(def).compile([]);
|
|
40
|
+
run(piece, (...args) => {
|
|
41
|
+
out.push(args);
|
|
42
|
+
return null;
|
|
43
|
+
});
|
|
44
|
+
return out;
|
|
45
|
+
}
|
|
46
|
+
const sameType = (a, b) => assert.equal(printType(a), printType(b));
|
|
47
|
+
describe('e3.migration — the declaration', () => {
|
|
48
|
+
// The typed bindings are half of each test: they compile only when the step
|
|
49
|
+
// carries the exact record types its function gives.
|
|
50
|
+
it('reads the record\'s types before and after the step off each form\'s function', () => {
|
|
51
|
+
const rec = plans();
|
|
52
|
+
const whole = migration.value('whole', rec, East.function([PlansV1Type], PlansV2Type, ($, old) => old.map(($, row) => ({ title: row.title, owner: 'unassigned' }))));
|
|
53
|
+
sameType(whole.from, PlansV1Type);
|
|
54
|
+
sameType(whole.to, PlansV2Type);
|
|
55
|
+
assert.equal(whole.form, 'value');
|
|
56
|
+
const dictRows = migration.rows('dict_rows', rec, East.function([StringType, RowV1Type], RowV2Type, ($, _id, row) => ({ title: row.title, owner: 'unassigned' })));
|
|
57
|
+
sameType(dictRows.from, PlansV1Type);
|
|
58
|
+
sameType(dictRows.to, PlansV2Type);
|
|
59
|
+
const arrayRows = migration.rows('array_rows', rec, East.function([IntegerType], StringType, ($, n) => East.print(n)));
|
|
60
|
+
sameType(arrayRows.from, ArrayType(IntegerType));
|
|
61
|
+
sameType(arrayRows.to, ArrayType(StringType));
|
|
62
|
+
const dictKeys = migration.rekey('dict_keys', rec, East.function([IntegerType, RowV2Type], StructType({ key: StringType, value: RowV2Type }), ($, _id, row) => ({ key: row.title, value: row })));
|
|
63
|
+
sameType(dictKeys.from, DictType(IntegerType, RowV2Type));
|
|
64
|
+
sameType(dictKeys.to, PlansV2Type);
|
|
65
|
+
const setKeys = migration.rekey('set_keys', rec, East.function([StringType], IntegerType, ($, s) => s.length()));
|
|
66
|
+
sameType(setKeys.from, SetType(StringType));
|
|
67
|
+
sameType(setKeys.to, SetType(IntegerType));
|
|
68
|
+
});
|
|
69
|
+
it('declares the documented examples as they are written', () => {
|
|
70
|
+
const RosterV1Type = DictType(StringType, StructType({ name: StringType }));
|
|
71
|
+
const RosterV2Type = DictType(StringType, StructType({ name: StringType, shift: StringType }));
|
|
72
|
+
const roster = e3.record('roster', RosterV2Type, new Map());
|
|
73
|
+
// Every row gains a shift, from the whole state.
|
|
74
|
+
const addShift = e3.migration.value('add_shift', roster, East.function([RosterV1Type], RosterV2Type, ($, old) => old.map(($, row) => ({ name: row.name, shift: 'day' }))));
|
|
75
|
+
const pkg = e3.package('planning', '2.0.0', roster, addShift);
|
|
76
|
+
assert.deepEqual(pkg.records.roster.migrations.map((step) => step.name), ['add_shift']);
|
|
77
|
+
const RowV1Type = StructType({ title: StringType });
|
|
78
|
+
const RowV2Type = StructType({ title: StringType, owner: StringType });
|
|
79
|
+
const owned = e3.record('plans', DictType(StringType, RowV2Type), new Map());
|
|
80
|
+
// Each row gains an owner; the keys are unchanged.
|
|
81
|
+
const addOwner = e3.migration.rows('add_owner', owned, East.function([StringType, RowV1Type], RowV2Type, ($, id, row) => ({ title: row.title, owner: 'unassigned' })));
|
|
82
|
+
assert.equal(e3.package('planning', '2.0.0', owned, addOwner).records.plans.migrations.length, 1);
|
|
83
|
+
const PlanType = StructType({ site: StringType, title: StringType });
|
|
84
|
+
const sited = e3.record('plans', DictType(StringType, PlanType), new Map());
|
|
85
|
+
// Plans were keyed by a number; they are keyed by site and title.
|
|
86
|
+
const bySite = e3.migration.rekey('by_site', sited, East.function([IntegerType, PlanType], StructType({ key: StringType, value: PlanType }), ($, id, plan) => ({ key: East.str `${plan.site}/${plan.title}`, value: plan })));
|
|
87
|
+
assert.equal(e3.package('planning', '2.0.0', sited, bySite).records.plans.migrations.length, 1);
|
|
88
|
+
});
|
|
89
|
+
describe('refuses, at definition time', () => {
|
|
90
|
+
const identity = East.function([PlansV2Type], PlansV2Type, ($, old) => old);
|
|
91
|
+
it('a name that is not an identifier', () => {
|
|
92
|
+
assert.throws(() => migration.value('add shift', plans(), identity), /e3.migration.value requires a name that is an identifier, got 'add shift'/);
|
|
93
|
+
assert.throws(() => migration.value('', plans(), identity), /requires a name that is an identifier/);
|
|
94
|
+
});
|
|
95
|
+
it('an async function, and one that reaches a platform function', () => {
|
|
96
|
+
assert.throws(
|
|
97
|
+
// Only a dynamic or cast caller reaches this; the typed surface refuses
|
|
98
|
+
// an async function.
|
|
99
|
+
() => migration.value('async', plans(), East.asyncFunction([PlansV2Type], PlansV2Type, ($, old) => old)), /e3.migration.value 'async' function must be a synchronous East function/);
|
|
100
|
+
assert.throws(() => migration.rows('clock', plans(), East.function([StringType, RowV1Type], IntegerType, ($, _id, _row) => East.platform('time_now', [], IntegerType)())), /e3.migration.rows 'clock' function must not call platform functions \(found 'time_now'\)/);
|
|
101
|
+
});
|
|
102
|
+
it('a function that is not its form\'s', () => {
|
|
103
|
+
assert.throws(() => migration.value('two', plans(), East.function([StringType, RowV1Type], RowV2Type, ($, _id, row) => ({ title: row.title, owner: '' }))), /e3.migration.value 'two': a value step's function takes the record's state alone, but takes 2 parameters/);
|
|
104
|
+
assert.throws(() => migration.rows('three', plans(), East.function([StringType, RowV1Type, IntegerType], RowV2Type, ($, _id, row) => ({ title: row.title, owner: '' }))), /e3.migration.rows 'three': a rows step's function takes a Dict's row, \(key, value\), or an Array's element, but takes 3 parameters/);
|
|
105
|
+
assert.throws(() => migration.rekey('flat', plans(), East.function([StringType, RowV2Type], StringType, ($, id) => id)), new RegExp(`e3.migration.rekey 'flat': a rekey step's function returns a Dict's entry under its new key, \\{ key, value \\}, but returns ${literal(printType(StringType))}`));
|
|
106
|
+
// A key must be a type a key may be, and East says why.
|
|
107
|
+
assert.throws(() => migration.rekey('listed', plans(), East.function([StringType], ArrayType(StringType), ($, s) => [s])), /e3.migration.rekey 'listed': Set key type must be an immutable type/);
|
|
108
|
+
});
|
|
109
|
+
it('a step after another record\'s, or after one that leaves the record as another type', () => {
|
|
110
|
+
const other = record('other', PlansV2Type, new Map());
|
|
111
|
+
const elsewhere = migration.value('elsewhere', other, identity);
|
|
112
|
+
assert.throws(() => migration.value('here', plans(), identity, { after: elsewhere }), /e3.migration.value 'here' follows 'elsewhere', a migration of record 'other' — a step follows a migration of its own record, 'plans'/);
|
|
113
|
+
const { rec, normalize } = chain();
|
|
114
|
+
assert.throws(() => migration.value('mismatch', rec, identity, { after: normalize }), new RegExp(`e3.migration.value 'mismatch' takes the record as ${literal(printType(PlansV2Type))}, but 'normalize', the step before it, leaves it as ${literal(printType(PlansV1Type))}`));
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
describe('e3.migration — the chain a package folds', () => {
|
|
119
|
+
it('takes a step\'s predecessors from its after, in the order they run', () => {
|
|
120
|
+
const { rec, normalize, addOwner, byTitle } = chain();
|
|
121
|
+
// Passing the last step passes the chain, and the order is the chain's
|
|
122
|
+
// whatever order the steps are passed in.
|
|
123
|
+
for (const pkg of [package_('planning', '3.0.0', byTitle), package_('planning', '3.0.0', byTitle, rec, normalize, addOwner)]) {
|
|
124
|
+
assert.deepEqual(pkg.records.plans.migrations.map((step) => step.name), ['normalize', 'add_owner', 'by_title']);
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
it('keeps a record\'s chain when its package is imported into another', () => {
|
|
128
|
+
const { byTitle } = chain();
|
|
129
|
+
const outer = package_('outer', '1.0.0', package_('inner', '1.0.0', byTitle));
|
|
130
|
+
assert.deepEqual(outer.records.plans.migrations.map((step) => step.name), ['normalize', 'add_owner', 'by_title']);
|
|
131
|
+
});
|
|
132
|
+
it('refuses two firsts, two steps after one, and a chain that does not end at the declared type', () => {
|
|
133
|
+
const rec = plans();
|
|
134
|
+
const toV2 = East.function([StringType, RowV1Type], RowV2Type, ($, _id, row) => ({ title: row.title, owner: '' }));
|
|
135
|
+
const first = migration.rows('first', rec, toV2);
|
|
136
|
+
const second = migration.rows('second', rec, toV2);
|
|
137
|
+
assert.throws(() => package_('planning', '3.0.0', first, second), /e3.package 'planning': record 'plans' has 2 migrations with no 'after' \('first', 'second'\) — its migrations are one chain/);
|
|
138
|
+
const keep = East.function([PlansV2Type], PlansV2Type, ($, old) => old);
|
|
139
|
+
const left = migration.value('left', rec, keep, { after: first });
|
|
140
|
+
const right = migration.value('right', rec, keep, { after: first });
|
|
141
|
+
assert.throws(() => package_('planning', '3.0.0', left, right), /record 'plans' has two migrations after 'first', 'left' and 'right' — its migrations are one chain/);
|
|
142
|
+
const short = migration.value('short', rec, East.function([PlansV2Type], PlansV1Type, ($, old) => old.map(($, row) => ({ title: row.title }))));
|
|
143
|
+
assert.throws(() => package_('planning', '3.0.0', short), new RegExp(`record 'plans' is declared as ${literal(printType(PlansV2Type))}, but its last migration, 'short', leaves it as ${literal(printType(PlansV1Type))}`));
|
|
144
|
+
});
|
|
145
|
+
it('refuses two different migrations of one name, and takes one passed twice once', () => {
|
|
146
|
+
const rec = plans();
|
|
147
|
+
const toV2 = East.function([StringType, RowV1Type], RowV2Type, ($, _id, row) => ({ title: row.title, owner: '' }));
|
|
148
|
+
const once = migration.rows('add_owner', rec, toV2);
|
|
149
|
+
const again = migration.rows('add_owner', rec, toV2);
|
|
150
|
+
assert.throws(() => package_('planning', '3.0.0', once, again), /record 'plans' declares two migrations named 'add_owner'/);
|
|
151
|
+
assert.deepEqual(package_('planning', '3.0.0', once, once).records.plans.migrations.map((step) => step.name), ['add_owner']);
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
describe('e3.migration — the program a step runs', () => {
|
|
155
|
+
const byKey = compareFor(StringType);
|
|
156
|
+
it('emits each Dict row under its own key, as the function rewrites it', () => {
|
|
157
|
+
const { addOwner } = chain();
|
|
158
|
+
const piece = new SortedMap([['p1', { title: 'One' }], ['p2', { title: 'Two' }]], byKey);
|
|
159
|
+
assert.deepEqual(emitted(addOwner, piece), [
|
|
160
|
+
['p1', { title: 'One', owner: 'unassigned' }],
|
|
161
|
+
['p2', { title: 'Two', owner: 'unassigned' }],
|
|
162
|
+
]);
|
|
163
|
+
});
|
|
164
|
+
it('emits an Array\'s elements in order', () => {
|
|
165
|
+
const step = migration.rows('printed', plans(), East.function([IntegerType], StringType, ($, n) => East.print(n)));
|
|
166
|
+
assert.deepEqual(emitted(step, [3n, 1n, 2n]), [['3'], ['1'], ['2']]);
|
|
167
|
+
});
|
|
168
|
+
it('emits each Dict row under the key the function gives it, in the order read', () => {
|
|
169
|
+
const { byTitle } = chain();
|
|
170
|
+
const piece = new SortedMap([
|
|
171
|
+
['p1', { title: 'Zed', owner: 'ana' }],
|
|
172
|
+
['p2', { title: 'Alpha', owner: 'bo' }],
|
|
173
|
+
], byKey);
|
|
174
|
+
// Out of key order: the runner's dict output sorts what it is given, and
|
|
175
|
+
// refuses a key given twice.
|
|
176
|
+
assert.deepEqual(emitted(byTitle, piece), [
|
|
177
|
+
['Zed', { title: 'Zed', owner: 'ana' }],
|
|
178
|
+
['Alpha', { title: 'Alpha', owner: 'bo' }],
|
|
179
|
+
]);
|
|
180
|
+
});
|
|
181
|
+
it('emits each Set element as the function maps it, two landing on one among them', () => {
|
|
182
|
+
const step = migration.rekey('lower', plans(), East.function([StringType], StringType, ($, s) => s.lowerCase()));
|
|
183
|
+
const piece = new SortedSet(['Ann', 'ann', 'Bo'], byKey);
|
|
184
|
+
// The runner's set output unions what it is given, so the two that land on
|
|
185
|
+
// `ann` are one element.
|
|
186
|
+
assert.deepEqual(emitted(step, piece), [['ann'], ['bo'], ['ann']]);
|
|
187
|
+
});
|
|
188
|
+
it('is none for a value step, whose own function runs', () => {
|
|
189
|
+
const { normalize } = chain();
|
|
190
|
+
assert.throws(() => migrationProgram(normalize), /e3.migration.value 'normalize' runs its own function, and has no program/);
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
/** A type's printed form, escaped for a regular expression. */
|
|
194
|
+
function literal(text) {
|
|
195
|
+
return text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
196
|
+
}
|
|
197
|
+
//# sourceMappingURL=migration.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration.spec.js","sourceRoot":"","sources":["../../src/migration.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mutation-programs.spec.d.ts","sourceRoot":"","sources":["../../src/mutation-programs.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|