@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.
Files changed (99) hide show
  1. package/README.md +11 -2
  2. package/dist/src/browser.d.ts +5 -4
  3. package/dist/src/browser.d.ts.map +1 -1
  4. package/dist/src/browser.js +3 -2
  5. package/dist/src/browser.js.map +1 -1
  6. package/dist/src/dataset-file.d.ts +17 -19
  7. package/dist/src/dataset-file.d.ts.map +1 -1
  8. package/dist/src/dataset-file.js +26 -45
  9. package/dist/src/dataset-file.js.map +1 -1
  10. package/dist/src/export.d.ts +2 -3
  11. package/dist/src/export.d.ts.map +1 -1
  12. package/dist/src/export.js +150 -80
  13. package/dist/src/export.js.map +1 -1
  14. package/dist/src/export.spec.js +177 -57
  15. package/dist/src/export.spec.js.map +1 -1
  16. package/dist/src/function.spec.js +29 -58
  17. package/dist/src/function.spec.js.map +1 -1
  18. package/dist/src/functions-link.spec.js +19 -17
  19. package/dist/src/functions-link.spec.js.map +1 -1
  20. package/dist/src/index.d.ts +56 -8
  21. package/dist/src/index.d.ts.map +1 -1
  22. package/dist/src/index.js +11 -4
  23. package/dist/src/index.js.map +1 -1
  24. package/dist/src/input.d.ts +8 -5
  25. package/dist/src/input.d.ts.map +1 -1
  26. package/dist/src/input.js +8 -5
  27. package/dist/src/input.js.map +1 -1
  28. package/dist/src/migration.d.ts +172 -0
  29. package/dist/src/migration.d.ts.map +1 -0
  30. package/dist/src/migration.js +108 -0
  31. package/dist/src/migration.js.map +1 -0
  32. package/dist/src/migration.spec.d.ts +6 -0
  33. package/dist/src/migration.spec.d.ts.map +1 -0
  34. package/dist/src/migration.spec.js +197 -0
  35. package/dist/src/migration.spec.js.map +1 -0
  36. package/dist/src/mutation-programs.spec.d.ts +6 -0
  37. package/dist/src/mutation-programs.spec.d.ts.map +1 -0
  38. package/dist/src/mutation-programs.spec.js +310 -0
  39. package/dist/src/mutation-programs.spec.js.map +1 -0
  40. package/dist/src/mutation.d.ts +117 -9
  41. package/dist/src/mutation.d.ts.map +1 -1
  42. package/dist/src/mutation.js +104 -46
  43. package/dist/src/mutation.js.map +1 -1
  44. package/dist/src/open-beast-link.spec.js +10 -8
  45. package/dist/src/open-beast-link.spec.js.map +1 -1
  46. package/dist/src/output.d.ts +117 -0
  47. package/dist/src/output.d.ts.map +1 -0
  48. package/dist/src/output.js +119 -0
  49. package/dist/src/output.js.map +1 -0
  50. package/dist/src/package.d.ts +7 -5
  51. package/dist/src/package.d.ts.map +1 -1
  52. package/dist/src/package.js +98 -8
  53. package/dist/src/package.js.map +1 -1
  54. package/dist/src/package.spec.d.ts +6 -0
  55. package/dist/src/package.spec.d.ts.map +1 -0
  56. package/dist/src/package.spec.js +16 -0
  57. package/dist/src/package.spec.js.map +1 -0
  58. package/dist/src/record-guards.d.ts +41 -0
  59. package/dist/src/record-guards.d.ts.map +1 -0
  60. package/dist/src/record-guards.js +44 -0
  61. package/dist/src/record-guards.js.map +1 -0
  62. package/dist/src/record-index.d.ts +129 -0
  63. package/dist/src/record-index.d.ts.map +1 -0
  64. package/dist/src/record-index.js +144 -0
  65. package/dist/src/record-index.js.map +1 -0
  66. package/dist/src/record-index.spec.d.ts +6 -0
  67. package/dist/src/record-index.spec.d.ts.map +1 -0
  68. package/dist/src/record-index.spec.js +160 -0
  69. package/dist/src/record-index.spec.js.map +1 -0
  70. package/dist/src/record-programs.d.ts +128 -0
  71. package/dist/src/record-programs.d.ts.map +1 -0
  72. package/dist/src/record-programs.js +480 -0
  73. package/dist/src/record-programs.js.map +1 -0
  74. package/dist/src/record.d.ts.map +1 -1
  75. package/dist/src/record.js +2 -0
  76. package/dist/src/record.js.map +1 -1
  77. package/dist/src/record.spec.js +71 -13
  78. package/dist/src/record.spec.js.map +1 -1
  79. package/dist/src/runner.d.ts +6 -9
  80. package/dist/src/runner.d.ts.map +1 -1
  81. package/dist/src/runner.js +9 -25
  82. package/dist/src/runner.js.map +1 -1
  83. package/dist/src/runner.spec.js +16 -34
  84. package/dist/src/runner.spec.js.map +1 -1
  85. package/dist/src/sha256.d.ts +4 -3
  86. package/dist/src/sha256.d.ts.map +1 -1
  87. package/dist/src/sha256.js +20 -17
  88. package/dist/src/sha256.js.map +1 -1
  89. package/dist/src/sha256.spec.js +10 -0
  90. package/dist/src/sha256.spec.js.map +1 -1
  91. package/dist/src/task.d.ts +116 -251
  92. package/dist/src/task.d.ts.map +1 -1
  93. package/dist/src/task.js +169 -435
  94. package/dist/src/task.js.map +1 -1
  95. package/dist/src/task.spec.js +174 -489
  96. package/dist/src/task.spec.js.map +1 -1
  97. package/dist/src/types.d.ts +215 -23
  98. package/dist/src/types.d.ts.map +1 -1
  99. 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,6 @@
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
+ export {};
6
+ //# sourceMappingURL=migration.spec.d.ts.map
@@ -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":"AAAA;;;GAGG;AAEH;;;;;;;;;GASG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EACL,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAC7F,UAAU,EAAE,SAAS,GACtB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAGxC,MAAM,SAAS,GAAG,UAAU,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC;AACpD,MAAM,SAAS,GAAG,UAAU,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC;AACvE,MAAM,WAAW,GAAG,QAAQ,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;AACpD,MAAM,WAAW,GAAG,QAAQ,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;AAEpD,MAAM,KAAK,GAAG,GAA2D,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;AAEpH;6DAC6D;AAC7D,SAAS,KAAK,CAAC,GAAG,GAAG,KAAK,EAAE;IAC1B,MAAM,SAAS,GAAG,SAAS,CAAC,KAAK,CAAC,WAAW,EAAE,GAAG,EAChD,IAAI,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9D,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,EAC9C,IAAI,CAAC,QAAQ,CAAC,CAAC,UAAU,EAAE,SAAS,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,CAAC,EAC/G,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IACxB,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,CAAC,UAAU,EAAE,GAAG,EAC7C,IAAI,CAAC,QAAQ,CAAC,CAAC,UAAU,EAAE,SAAS,CAAC,EAAE,UAAU,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,EACtF,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,EACpD,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;IACvB,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;AAC/C,CAAC;AAED,2EAA2E;AAC3E,SAAS,OAAO,CAAC,GAAiB,EAAE,KAAc;IAChD,MAAM,GAAG,GAAgB,EAAE,CAAC;IAC5B,MAAM,GAAG,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,EAAE,CAAoE,CAAC;IACjH,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,IAAe,EAAE,EAAE;QAChC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACf,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;IACH,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,QAAQ,GAAG,CAAC,CAAW,EAAE,CAAW,EAAQ,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;AAE9F,QAAQ,CAAC,gCAAgC,EAAE,GAAG,EAAE;IAC9C,4EAA4E;IAC5E,qDAAqD;IAErD,EAAE,CAAC,+EAA+E,EAAE,GAAG,EAAE;QACvF,MAAM,GAAG,GAAG,KAAK,EAAE,CAAC;QACpB,MAAM,KAAK,GACT,SAAS,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,EAAE,WAAW,EACpE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACnF,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAClC,QAAQ,CAAC,KAAK,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC;QAChC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAElC,MAAM,QAAQ,GACZ,SAAS,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,UAAU,EAAE,SAAS,CAAC,EAAE,SAAS,EAC/E,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC;QACnE,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QACrC,QAAQ,CAAC,QAAQ,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC;QAEnC,MAAM,SAAS,GACb,SAAS,CAAC,IAAI,CAAC,YAAY,EAAE,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACvG,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC;QACjD,QAAQ,CAAC,SAAS,CAAC,EAAE,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC;QAE9C,MAAM,QAAQ,GACZ,SAAS,CAAC,KAAK,CAAC,WAAW,EAAE,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,SAAS,CAAC,EAAE,UAAU,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,EACzH,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;QACxD,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC,CAAC;QAC1D,QAAQ,CAAC,QAAQ,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC;QAEnC,MAAM,OAAO,GACX,SAAS,CAAC,KAAK,CAAC,UAAU,EAAE,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QACnG,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;QAC5C,QAAQ,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;QAC9D,MAAM,YAAY,GAAG,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC;QAC5E,MAAM,YAAY,GAAG,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC;QAC/F,MAAM,MAAM,GAAG,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,YAAY,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;QAE5D,iDAAiD;QACjD,MAAM,QAAQ,GAAG,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,WAAW,EAAE,MAAM,EACrD,IAAI,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CACrD,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAE9D,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;QAC9D,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,MAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;QAEzF,MAAM,SAAS,GAAG,UAAU,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC;QACpD,MAAM,SAAS,GAAG,UAAU,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC;QACvE,MAAM,KAAK,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,UAAU,EAAE,SAAS,CAAC,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;QAE7E,mDAAmD;QACnD,MAAM,QAAQ,GAAG,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,EACnD,IAAI,CAAC,QAAQ,CAAC,CAAC,UAAU,EAAE,SAAS,CAAC,EAAE,SAAS,EAC9C,CAAC,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC;QAClE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,OAAO,CAAC,KAAM,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAEnG,MAAM,QAAQ,GAAG,UAAU,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC;QACrE,MAAM,KAAK,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;QAE5E,kEAAkE;QAClE,MAAM,MAAM,GAAG,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,EAChD,IAAI,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,QAAQ,CAAC,EAAE,UAAU,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,EACrF,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,CAAA,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACpF,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,KAAM,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACnG,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,6BAA6B,EAAE,GAAG,EAAE;QAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;QAE5E,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;YAC1C,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,EAAE,EAAE,QAAQ,CAAC,EACjE,2EAA2E,CAAC,CAAC;YAC/E,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,QAAQ,CAAC,EAAE,uCAAuC,CAAC,CAAC;QACvG,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6DAA6D,EAAE,GAAG,EAAE;YACrE,MAAM,CAAC,MAAM;YACX,wEAAwE;YACxE,qBAAqB;YACrB,GAAG,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC,WAAW,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,CAAU,CAAC,EACjH,yEAAyE,CAC1E,CAAC;YACF,MAAM,CAAC,MAAM,CACX,GAAG,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,UAAU,EAAE,SAAS,CAAC,EAAE,WAAW,EACvF,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,EAAE,EAAE,WAAW,CAAC,EAAE,CAAC,CAAC,EAClE,0FAA0F,CAC3F,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;YAC5C,MAAM,CAAC,MAAM,CACX,GAAG,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,UAAU,EAAE,SAAS,CAAC,EAAE,SAAS,EACpF,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAU,CAAC,EAC/D,0GAA0G,CAC3G,CAAC;YACF,MAAM,CAAC,MAAM,CACX,GAAG,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,UAAU,EAAE,SAAS,EAAE,WAAW,CAAC,EAAE,SAAS,EAClG,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAU,CAAC,EAC/D,qIAAqI,CACtI,CAAC;YACF,MAAM,CAAC,MAAM,CACX,GAAG,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,UAAU,EAAE,SAAS,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAU,CAAC,EAClH,IAAI,MAAM,CAAC,gIAAgI,OAAO,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,CAC7K,CAAC;YACF,wDAAwD;YACxD,MAAM,CAAC,MAAM,CACX,GAAG,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,EAAE,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAC3G,qEAAqE,CACtE,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qFAAqF,EAAE,GAAG,EAAE;YAC7F,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;YACtD,MAAM,SAAS,GAAG,SAAS,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;YAChE,MAAM,CAAC,MAAM,CACX,GAAG,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,EACtE,sIAAsI,CACvI,CAAC;YACF,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,CAAC;YACnC,MAAM,CAAC,MAAM,CACX,GAAG,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,UAAU,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,EACtE,IAAI,MAAM,CAAC,qDAAqD,OAAO,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,uDAAuD,OAAO,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CACzL,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,0CAA0C,EAAE,GAAG,EAAE;IACxD,EAAE,CAAC,oEAAoE,EAAE,GAAG,EAAE;QAC5E,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,KAAK,EAAE,CAAC;QACtD,uEAAuE;QACvE,0CAA0C;QAC1C,KAAK,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC;YAC7H,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,KAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,WAAW,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC;QACnH,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mEAAmE,EAAE,GAAG,EAAE;QAC3E,MAAM,EAAE,OAAO,EAAE,GAAG,KAAK,EAAE,CAAC;QAC5B,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;QAC9E,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,KAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,WAAW,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC;IACrH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6FAA6F,EAAE,GAAG,EAAE;QACrG,MAAM,GAAG,GAAG,KAAK,EAAE,CAAC;QACpB,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,UAAU,EAAE,SAAS,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QACnH,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QACjD,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QACnD,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,EAC9D,6HAA6H,CAAC,CAAC;QAEjI,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;QACxE,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;QAClE,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;QACpE,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,EAC5D,oGAAoG,CAAC,CAAC;QAExG,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,EAAE,WAAW,EAClF,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5D,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,OAAO,EAAE,KAAK,CAAC,EACtD,IAAI,MAAM,CAAC,iCAAiC,OAAO,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,mDAAmD,OAAO,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACtK,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+EAA+E,EAAE,GAAG,EAAE;QACvF,MAAM,GAAG,GAAG,KAAK,EAAE,CAAC;QACpB,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,UAAU,EAAE,SAAS,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QACnH,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QACpD,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QACrD,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,EAAE,0DAA0D,CAAC,CAAC;QAC5H,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,KAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;IAChI,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,wCAAwC,EAAE,GAAG,EAAE;IACtD,MAAM,KAAK,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;IAErC,EAAE,CAAC,oEAAoE,EAAE,GAAG,EAAE;QAC5E,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,IAAI,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;QACzF,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE;YACzC,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC;YAC7C,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC;SAC9C,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACnH,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACvE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4EAA4E,EAAE,GAAG,EAAE;QACpF,MAAM,EAAE,OAAO,EAAE,GAAG,KAAK,EAAE,CAAC;QAC5B,MAAM,KAAK,GAAG,IAAI,SAAS,CAAC;YAC1B,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;YACtC,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;SACxC,EAAE,KAAK,CAAC,CAAC;QACV,yEAAyE;QACzE,6BAA6B;QAC7B,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE;YACxC,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;YACvC,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;SAC3C,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+EAA+E,EAAE,GAAG,EAAE;QACvF,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;QACjH,MAAM,KAAK,GAAG,IAAI,SAAS,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;QACzD,2EAA2E;QAC3E,yBAAyB;QACzB,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;QAC3D,MAAM,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,CAAC;QAC9B,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,gBAAgB,CAAC,SAAS,CAAC,EAAE,0EAA0E,CAAC,CAAC;IAC/H,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,+DAA+D;AAC/D,SAAS,OAAO,CAAC,IAAY;IAC3B,OAAO,IAAI,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AACrD,CAAC"}
@@ -0,0 +1,6 @@
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
+ export {};
6
+ //# sourceMappingURL=mutation-programs.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mutation-programs.spec.d.ts","sourceRoot":"","sources":["../../src/mutation-programs.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG"}