@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,310 @@
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
+ * The three write forms and the one program each generates.
7
+ *
8
+ * What is asserted here is the DELTA — the program is only interesting for
9
+ * what it emits — so every test runs the compiled program, reads the
10
+ * `(key, op)` pairs off its emit, and sorts them by the delta's key as the
11
+ * runner's RunSorter does. Three properties are load-bearing and none is
12
+ * visible from the type: no key is emitted twice, since the delta is a dict
13
+ * with no merge; in the delta's canonical order every target's ops are one
14
+ * contiguous ascending run, since variant cases compare by NAME; and an index
15
+ * entry whose key MOVED is a delete plus an insert rather than an update,
16
+ * because `{ik, k}` is the entry's identity.
17
+ */
18
+ import { describe, it } from 'node:test';
19
+ import assert from 'node:assert/strict';
20
+ import { DateTimeType, DictType, East, IntegerType, NullType, SetType, SortedMap, SortedSet, StringType, StructType, compareFor, variant, } from '@elaraai/east';
21
+ import { DELTA_CONFLICT, editTypeOf, mutationDeltaType } from '@elaraai/e3-types';
22
+ import e3 from './index.js';
23
+ import { record } from './record.js';
24
+ import { mutation } from './mutation.js';
25
+ import { recordIndex } from './record-index.js';
26
+ import { buildMutationProgram, deltaTargets } from './record-programs.js';
27
+ const RowType = StructType({ status: StringType, due: IntegerType, title: StringType });
28
+ const PlansType = DictType(StringType, RowType);
29
+ const StatusKeyType = StructType({ status: StringType, due: IntegerType });
30
+ const CountsType = DictType(StringType, IntegerType);
31
+ const FlagsType = SetType(StringType);
32
+ const plans = new SortedMap([
33
+ ['p1', { status: 'late', due: 3n, title: 'One' }],
34
+ ['p2', { status: 'ok', due: 1n, title: 'Two' }],
35
+ ], compareFor(StringType));
36
+ const counts = new SortedMap([['a', 1n], ['b', 2n]], compareFor(StringType));
37
+ const flags = new SortedSet(['x', 'y'], compareFor(StringType));
38
+ /** A record carrying `by_status`: one entry per row, with a covering title. */
39
+ function indexedPlans() {
40
+ const rec = record('plans', PlansType, new Map());
41
+ const index = recordIndex('by_status', rec, {
42
+ key: East.function([StringType, RowType], StatusKeyType, ($, _k, v) => ({ status: v.status, due: v.due })),
43
+ value: East.function([StringType, RowType], StringType, ($, _k, v) => v.title),
44
+ });
45
+ rec.indexes[index.name] = index;
46
+ return rec;
47
+ }
48
+ /** The delta a mutation's program writes for `state` and `args`: the
49
+ * `(key, op)` pairs it emits, sorted by the delta's key as the runner sorts
50
+ * them, none emitted twice. */
51
+ function emitted(rec, mut, state, args) {
52
+ const out = [];
53
+ const run = buildMutationProgram(rec, mut).compile([]);
54
+ run(state, ...args, (key, op) => {
55
+ out.push([key, op]);
56
+ return null;
57
+ });
58
+ const delta = mutationDeltaType(deltaTargets(rec.type, Object.values(rec.indexes)));
59
+ const compare = compareFor(delta.key);
60
+ out.sort(([a], [b]) => compare(a, b));
61
+ for (let i = 1; i < out.length; i++) {
62
+ assert.notEqual(compare(out[i - 1][0], out[i][0]), 0, 'the delta is a dict with no merge: no key is emitted twice');
63
+ }
64
+ return out;
65
+ }
66
+ /** The detail of the conflict a delta opens with, or `undefined` when it opens
67
+ * with none. */
68
+ function conflictOf(out) {
69
+ const key = out[0]?.[0];
70
+ return key?.type === DELTA_CONFLICT ? key.value : undefined;
71
+ }
72
+ /** The delta's `(target, key)` / `(target, op-tag)` pairs, which is what the
73
+ * apply keys on — the payloads are asserted where they matter. */
74
+ function shape(out) {
75
+ return out.map(([key, op]) => {
76
+ const k = key;
77
+ const o = op;
78
+ return `${k.type}:${JSON.stringify(k.value, (_n, v) => (typeof v === 'bigint' ? String(v) : v))}=${o.value.type}`;
79
+ });
80
+ }
81
+ describe('the mutation delta — targets and canonical order', () => {
82
+ it('names the primary and every index, in the order their cases compare', () => {
83
+ const rec = indexedPlans();
84
+ assert.deepEqual(deltaTargets(rec.type, Object.values(rec.indexes)).map((t) => t.name), ['by_status', 'primary']);
85
+ });
86
+ it('writes every target\'s ops in one contiguous ascending run', () => {
87
+ const rec = indexedPlans();
88
+ const retitle = mutation.reduce('retitle', rec, East.function([PlansType, StringType, StringType], PlansType, ($, state, id, title) => {
89
+ const next = $.let(state.copy());
90
+ const row = $.let(next.get(id));
91
+ $(next.insertOrUpdate(id, { status: row.status, due: row.due, title }));
92
+ return next;
93
+ }));
94
+ assert.deepEqual(shape(emitted(rec, retitle, plans, ['p1', 'Renamed'])), [
95
+ 'by_status:{"ik":{"status":"late","due":"3"},"k":"p1"}=update',
96
+ 'primary:"p1"=update',
97
+ ]);
98
+ });
99
+ });
100
+ describe('the reduce form', () => {
101
+ it('turns a whole-state replace into per-key ops', () => {
102
+ const rec = record('counts', CountsType, new Map());
103
+ const reset = mutation.reduce('reset', rec, East.function([CountsType], CountsType, ($) => {
104
+ const next = $.let(new Map(), CountsType);
105
+ $(next.insert('q', 42n));
106
+ return next;
107
+ }));
108
+ assert.deepEqual(shape(emitted(rec, reset, counts, [])), ['primary:"a"=delete', 'primary:"b"=delete', 'primary:"q"=insert']);
109
+ });
110
+ it('writes a Set record\'s delta too — the ops carry no value', () => {
111
+ const rec = record('flags', FlagsType, new Set());
112
+ const raise = mutation.reduce('raise', rec, East.function([FlagsType, StringType], FlagsType, ($, state, flag) => {
113
+ const next = $.let(state.copy());
114
+ $(next.insert(flag));
115
+ return next;
116
+ }));
117
+ const out = emitted(rec, raise, flags, ['z']);
118
+ assert.deepEqual(shape(out), ['primary:"z"=insert']);
119
+ assert.equal(out[0][1].value.value, null);
120
+ });
121
+ });
122
+ describe('the edit form', () => {
123
+ it('types the capability from the record: the documented bodies, verbatim, with no casts', () => {
124
+ // Two documented record examples, written as an author would — so they
125
+ // keep compiling. `edit` is typed from `e3.mutation.editType(plans.type)`,
126
+ // so `edit.set` checks the key and the whole row; a body that leaves a
127
+ // field out does not build.
128
+ const PlanType = StructType({
129
+ title: StringType, owner: StringType, status: StringType,
130
+ due: DateTimeType, resources: SetType(StringType),
131
+ });
132
+ const plans = e3.record('plans', DictType(StringType, PlanType), new Map());
133
+ // `edit` is typed from the record: edit.set(key, row), edit.delete(key),
134
+ // edit.update(key, patch) — each checked against the record's key and row.
135
+ const reschedule = e3.mutation.edit('reschedule', plans, East.function([plans.type, StringType, DateTimeType, e3.mutation.editType(plans.type)], NullType, ($, state, id, due, edit) => {
136
+ const plan = $.let(state.get(id)); // one segment decoded, not the record
137
+ $(edit.set(id, { title: plan.title, owner: plan.owner, status: plan.status, due, resources: plan.resources }));
138
+ }));
139
+ const StatusKeyType = StructType({ status: StringType, due: DateTimeType });
140
+ const byStatus = e3.recordIndex('by_status', plans, {
141
+ key: East.function([StringType, PlanType], StatusKeyType, ($, k, v) => ({ status: v.status, due: v.due })),
142
+ value: East.function([StringType, PlanType], StringType, ($, k, v) => v.title),
143
+ });
144
+ const byResource = e3.recordIndex('by_resource', plans, {
145
+ keys: East.function([StringType, PlanType], SetType(StringType), ($, k, v) => v.resources),
146
+ });
147
+ const pkg = e3.package('planning', '1.0.0', plans, reschedule, e3.mutation.patch(plans), byStatus, byResource);
148
+ assert.deepEqual(Object.keys(pkg.records.plans.indexes).sort(), ['by_resource', 'by_status']);
149
+ // And the body does what it says: the row moves in by_status, and
150
+ // by_resource — whose entry neither moved nor carries a value — is untouched.
151
+ const row = { title: 'Pour', owner: 'ana', status: 'late', due: new Date('2026-10-01T00:00:00Z'), resources: new Set(['crane']) };
152
+ const state = new SortedMap([['p1', row]], compareFor(StringType));
153
+ assert.deepEqual(shape(emitted(pkg.records.plans, reschedule, state, ['p1', new Date('2026-11-01T00:00:00Z')])), [
154
+ 'by_status:{"ik":{"status":"late","due":"2026-10-01T00:00:00.000Z"},"k":"p1"}=delete',
155
+ 'by_status:{"ik":{"status":"late","due":"2026-11-01T00:00:00.000Z"},"k":"p1"}=insert',
156
+ 'primary:"p1"=update',
157
+ ]);
158
+ });
159
+ const EditCounts = editTypeOf(CountsType);
160
+ const rec = record('counts', CountsType, new Map());
161
+ it('resolves a set against the record: an update where it is held, an insert where it is not', () => {
162
+ const write = mutation.edit('write', rec, East.function([CountsType, EditCounts], NullType, ($, _state, edit) => {
163
+ $(edit.set('a', 10n));
164
+ $(edit.set('z', 10n));
165
+ }));
166
+ assert.deepEqual(shape(emitted(rec, write, counts, [])), ['primary:"a"=update', 'primary:"z"=insert']);
167
+ });
168
+ it('folds an update after a set into the set value', () => {
169
+ const write = mutation.edit('write', rec, East.function([CountsType, EditCounts], NullType, ($, _state, edit) => {
170
+ $(edit.set('a', 10n));
171
+ $(edit.update('a', variant('replace', { before: 10n, after: 11n })));
172
+ }));
173
+ const out = emitted(rec, write, counts, []);
174
+ assert.deepEqual(shape(out), ['primary:"a"=update']);
175
+ assert.deepEqual(out[0][1].value.value.value, { before: 1n, after: 11n }, 'one op against the state, not two');
176
+ });
177
+ it('composes an update after an update', () => {
178
+ const write = mutation.edit('write', rec, East.function([CountsType, EditCounts], NullType, ($, _state, edit) => {
179
+ $(edit.update('b', variant('replace', { before: 2n, after: 5n })));
180
+ $(edit.update('b', variant('replace', { before: 5n, after: 7n })));
181
+ }));
182
+ const out = emitted(rec, write, counts, []);
183
+ assert.deepEqual(out[0][1].value.value.value, { before: 2n, after: 7n });
184
+ });
185
+ it('writes a conflict naming the key for a delete or update of one the record does not hold', () => {
186
+ assert.equal(conflictOf(emitted(rec, mutation.edit('delete', rec, East.function([CountsType, EditCounts], NullType, ($, _s, edit) => {
187
+ $(edit.delete('zz'));
188
+ })), counts, [])), 'delete of "zz", which the record does not hold');
189
+ assert.equal(conflictOf(emitted(rec, mutation.edit('update', rec, East.function([CountsType, EditCounts], NullType, ($, _s, edit) => {
190
+ $(edit.update('zz', variant('replace', { before: 1n, after: 2n })));
191
+ })), counts, [])), 'update of "zz", which the record does not hold');
192
+ });
193
+ it('writes nothing for a key the body created and deleted again', () => {
194
+ // The record never held `zz`, so creating and removing it changed nothing:
195
+ // folded into a delete, the pair would be refused as a stale write that no
196
+ // resubmission could ever get past.
197
+ const churn = mutation.edit('churn', rec, East.function([CountsType, EditCounts], NullType, ($, _state, edit) => {
198
+ $(edit.set('zz', 10n));
199
+ $(edit.delete('zz'));
200
+ }));
201
+ assert.deepEqual(shape(emitted(rec, churn, counts, [])), []);
202
+ });
203
+ it('deletes a held key the body set before deleting it', () => {
204
+ const drop = mutation.edit('drop', rec, East.function([CountsType, EditCounts], NullType, ($, _state, edit) => {
205
+ $(edit.set('a', 10n));
206
+ $(edit.delete('a'));
207
+ }));
208
+ assert.deepEqual(shape(emitted(rec, drop, counts, [])), ['primary:"a"=delete']);
209
+ });
210
+ it('refuses, at definition time, a body that is not (state, …args, edit) => Null', () => {
211
+ const rec2 = record('counts', CountsType, new Map());
212
+ assert.throws(() => mutation.edit('no_edit', rec2, East.function([CountsType, StringType], NullType, ($) => { void $; })), /LAST parameter must be the edit capability/);
213
+ assert.throws(() => mutation.edit('returns', rec2, East.function([CountsType, EditCounts], CountsType, ($, state) => state)), /returns Null/);
214
+ const scalar = record('n', IntegerType, 0n);
215
+ assert.throws(() => mutation.edit('scalar', scalar, East.function([IntegerType], NullType, ($) => { void $; })), /needs a Dict or Set record/);
216
+ });
217
+ });
218
+ describe('the patch form', () => {
219
+ const rec = record('counts', CountsType, new Map());
220
+ const patch = mutation.patch(rec);
221
+ it('takes one argument, the state\'s patch type, and is named patch by default', () => {
222
+ assert.equal(patch.name, 'patch');
223
+ assert.equal(patch.form, 'patch');
224
+ assert.equal(patch.argTypes.length, 1);
225
+ assert.equal(patch.body, undefined, 'there is no author body to ship');
226
+ });
227
+ it('carries a patch arm through as the primary ops', () => {
228
+ const ops = new SortedMap([['c', variant('insert', 3n)]], compareFor(StringType));
229
+ assert.deepEqual(shape(emitted(rec, patch, counts, [variant('patch', ops)])), ['primary:"c"=insert']);
230
+ });
231
+ it('turns a replace arm into the ops that differ, after checking its before', () => {
232
+ const after = new SortedMap([['a', 1n], ['c', 3n]], compareFor(StringType));
233
+ assert.deepEqual(shape(emitted(rec, patch, counts, [variant('replace', { before: counts, after })])), ['primary:"b"=delete', 'primary:"c"=insert']);
234
+ assert.equal(conflictOf(emitted(rec, patch, counts, [variant('replace', {
235
+ before: new SortedMap([['a', 99n]], compareFor(StringType)),
236
+ after,
237
+ })])), 'the patch replaces a state the record no longer holds');
238
+ });
239
+ });
240
+ describe('index maintenance inside the delta', () => {
241
+ const rec = indexedPlans();
242
+ const EditPlans = editTypeOf(PlansType);
243
+ it('moves an entry as a delete plus an insert when its index key changes', () => {
244
+ const move = mutation.edit('move', rec, East.function([PlansType, EditPlans], NullType, ($, state, edit) => {
245
+ const row = $.let(state.get('p1'));
246
+ $(edit.set('p1', { status: 'ok', due: row.due, title: row.title }));
247
+ }));
248
+ assert.deepEqual(shape(emitted(rec, move, plans, [])), [
249
+ 'by_status:{"ik":{"status":"late","due":"3"},"k":"p1"}=delete',
250
+ 'by_status:{"ik":{"status":"ok","due":"3"},"k":"p1"}=insert',
251
+ 'primary:"p1"=update',
252
+ ]);
253
+ });
254
+ it('updates an entry in place when only the covering projection changes', () => {
255
+ const retitle = mutation.edit('retitle', rec, East.function([PlansType, EditPlans], NullType, ($, state, edit) => {
256
+ const row = $.let(state.get('p2'));
257
+ $(edit.set('p2', { status: row.status, due: row.due, title: 'Renamed' }));
258
+ }));
259
+ assert.deepEqual(shape(emitted(rec, retitle, plans, [])), [
260
+ 'by_status:{"ik":{"status":"ok","due":"1"},"k":"p2"}=update',
261
+ 'primary:"p2"=update',
262
+ ]);
263
+ });
264
+ it('writes a stale update as a conflict naming the key', () => {
265
+ // An indexed record applies the patch itself, to learn where the row's
266
+ // entries move. A row that no longer matches the patch is a stale write
267
+ // here exactly as it is where the engine applies an unindexed record's
268
+ // patch: a caller re-reads and resubmits a conflict, but gives up on a
269
+ // failed program.
270
+ const stale = new SortedMap([['p1', variant('update', variant('patch', {
271
+ status: variant('unchanged', null),
272
+ due: variant('unchanged', null),
273
+ title: variant('replace', { before: 'Not the title', after: 'Renamed' }),
274
+ }))]], compareFor(StringType));
275
+ assert.equal(conflictOf(emitted(rec, mutation.patch(rec), plans, [variant('patch', stale)])), 'update of "p1", whose row no longer matches the patch');
276
+ });
277
+ it('leaves the index alone when neither its key nor its projection moved', () => {
278
+ const rec2 = record('plans', PlansType, new Map());
279
+ const index = recordIndex('by_status', rec2, {
280
+ key: East.function([StringType, RowType], StatusKeyType, ($, _k, v) => ({ status: v.status, due: v.due })),
281
+ });
282
+ rec2.indexes[index.name] = index;
283
+ const retitle = mutation.edit('retitle', rec2, East.function([PlansType, editTypeOf(PlansType)], NullType, ($, state, edit) => {
284
+ const row = $.let(state.get('p2'));
285
+ $(edit.set('p2', { status: row.status, due: row.due, title: 'Renamed' }));
286
+ }));
287
+ assert.deepEqual(shape(emitted(rec2, retitle, plans, [])), ['primary:"p2"=update']);
288
+ });
289
+ it('carries a multi-valued index\'s entries one per element of the returned set', () => {
290
+ const TagRowType = StructType({ tags: SetType(StringType) });
291
+ const TaggedType = DictType(StringType, TagRowType);
292
+ const rec2 = record('tagged', TaggedType, new Map());
293
+ const index = recordIndex('by_tag', rec2, {
294
+ keys: East.function([StringType, TagRowType], SetType(StringType), ($, _k, v) => v.tags),
295
+ });
296
+ rec2.indexes[index.name] = index;
297
+ const retag = mutation.edit('retag', rec2, East.function([TaggedType, editTypeOf(TaggedType)], NullType, ($, _s, edit) => {
298
+ $(edit.set('t1', { tags: new Set(['b', 'c']) }));
299
+ }));
300
+ const state = new SortedMap([
301
+ ['t1', { tags: new Set(['a', 'b']) }],
302
+ ], compareFor(StringType));
303
+ assert.deepEqual(shape(emitted(rec2, retag, state, [])), [
304
+ 'by_tag:{"ik":"a","k":"t1"}=delete',
305
+ 'by_tag:{"ik":"c","k":"t1"}=insert',
306
+ 'primary:"t1"=update',
307
+ ]);
308
+ });
309
+ });
310
+ //# sourceMappingURL=mutation-programs.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mutation-programs.spec.js","sourceRoot":"","sources":["../../src/mutation-programs.spec.ts"],"names":[],"mappings":"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"}
@@ -6,16 +6,26 @@
6
6
  * Mutation definitions for e3 packages — the write half of the record
7
7
  * machinery (CQRS; `e3.function` is the read half).
8
8
  *
9
- * A mutation is a pure East reducer `(State, ...Args) => State` that runs
10
- * server-side, where the record's data is, in a compare-and-swap retry loop.
11
- * Purity is what makes retry-on-conflict safe: the loop can re-run the reducer
12
- * against fresher state with no observable side effects.
9
+ * There are three write forms and they all commit the same thing: a mutation
10
+ * delta, the primary's and every index's changes addressed by key, which the
11
+ * engine applies segment by segment. They differ in how the author says what
12
+ * changed — a reducer over the whole state, a body writing through an `edit`
13
+ * capability, or a patch sent by whoever made the edit — and so in what a
14
+ * write costs.
15
+ *
16
+ * All three are pure East: purity is what makes retry-on-conflict safe, since
17
+ * the compare-and-swap loop can re-run against fresher state with no
18
+ * observable side effects. They are `e3.mutation.reduce`, `e3.mutation.edit`
19
+ * and `e3.mutation.patch`, beside `e3.mutation.editType`, the type of the
20
+ * `edit` capability.
13
21
  */
14
- import type { CallableFunctionExpr, EastType, FunctionExpr } from '@elaraai/east';
22
+ import type { CallableFunctionExpr, EastType, FunctionExpr, PatchTypeOf } from '@elaraai/east';
23
+ import { NullType } from '@elaraai/east';
24
+ import { editTypeOf } from '@elaraai/e3-types';
15
25
  import type { MutationDef, RecordDef } from './types.js';
16
26
  import { type FunctionRunner } from './runner.js';
17
27
  /**
18
- * Defines a mutation that writes a record.
28
+ * Defines a mutation that writes a record by reducing its whole state.
19
29
  *
20
30
  * The reducer is an ordinary East function whose first parameter is the
21
31
  * current state and whose return is the new state — both the record's type,
@@ -29,10 +39,16 @@ import { type FunctionRunner } from './runner.js';
29
39
  * from a `.copy()` (or build it fresh) rather than mutating in place, which
30
40
  * raises the uniform copy-first runtime error.
31
41
  *
42
+ * The reducer sees the whole state, so its cost in the runner is the record's
43
+ * size however little it changes; only its write, for a Dict or Set record, is
44
+ * proportional to what it touched — any other record's state is written whole.
45
+ * {@link edit} is the form whose body reads only the entries it touches, and
46
+ * whose commit rewrites only the segments they live in.
47
+ *
32
48
  * @typeParam Name - Mutation name (literal type)
33
49
  * @typeParam T - The owning record's state type
34
50
  * @typeParam Args - The EXTRA positional parameter types (after the state)
35
- * @param name - Mutation name (unique within the record)
51
+ * @param name - Mutation name: an identifier, unique within the record
36
52
  * @param rec - The record this mutation writes
37
53
  * @param fn - The reducer `(state, ...args) => state`
38
54
  * @param config - Optional runner selection (known runtimes only, like e3.function)
@@ -42,7 +58,7 @@ import { type FunctionRunner } from './runner.js';
42
58
  * ```ts
43
59
  * const orders = e3.record('orders', OrdersType, new Map());
44
60
  *
45
- * const placeOrder = e3.mutation('place_order', orders,
61
+ * const placeOrder = e3.mutation.reduce('place_order', orders,
46
62
  * East.function([OrdersType, OrderType], OrdersType, ($, state, order) => {
47
63
  * $.if(state.has(order.id), $ => $.error(East.str`duplicate order ${order.id}`));
48
64
  * const next = $.let(state.copy());
@@ -53,7 +69,99 @@ import { type FunctionRunner } from './runner.js';
53
69
  * const pkg = e3.package('planning', '1.0.0', orders, placeOrder);
54
70
  * ```
55
71
  */
56
- export declare function mutation<Name extends string, T extends EastType, Args extends EastType[]>(name: Name, rec: RecordDef<T>, fn: FunctionExpr<[T, ...Args], T> | CallableFunctionExpr<[T, ...Args], T>, config?: {
72
+ declare function reduce<Name extends string, T extends EastType, Args extends EastType[]>(name: Name, rec: RecordDef<T>, fn: FunctionExpr<[T, ...Args], T> | CallableFunctionExpr<[T, ...Args], T>, config?: {
57
73
  runner?: FunctionRunner;
58
74
  }): MutationDef<Name, T, Args>;
75
+ /**
76
+ * Defines a mutation that writes a record through an `edit` capability — the
77
+ * lazy write.
78
+ *
79
+ * The body is `(state, ...args, edit) => Null`. It reads the state it is given
80
+ * — lazily, so a body that looks at ten entries of a two-million-entry record
81
+ * decodes the segments those ten live in and nothing else — and writes through
82
+ * `edit.set(key, value)`, `edit.delete(key)` and `edit.update(key, patch)`. It
83
+ * never returns a state, so its commit rewrites only the segments the entries
84
+ * it touched live in. The state reaches its runner as the record's manifest,
85
+ * the segments linked, so nothing on the way reads the record whole either.
86
+ *
87
+ * Repeated edits of one key fold: `set` after anything is that `set`; `update`
88
+ * after `set` applies to the set value; `update` after `update` composes;
89
+ * `delete` after anything is `delete`. A `set` of the value the record already
90
+ * holds is no change. A `delete` or `update` of a key the record does not hold
91
+ * is a conflict naming the key, exactly as applying such a patch would be.
92
+ *
93
+ * The purity rules of {@link reduce} apply unchanged.
94
+ *
95
+ * @typeParam Name - Mutation name (literal type)
96
+ * @typeParam T - The owning record's state type (a Dict)
97
+ * @typeParam Args - The EXTRA positional parameter types (between the state and the edit)
98
+ * @typeParam E - The edit capability's struct type, `e3.mutation.editType(T)`
99
+ * @param name - Mutation name: an identifier, unique within the record
100
+ * @param rec - The record this mutation writes
101
+ * @param fn - The body `(state, ...args, edit) => null`
102
+ * @param config - Optional runner selection (known runtimes only)
103
+ * @returns A MutationDef to pass to `e3.package`
104
+ *
105
+ * @example
106
+ * ```ts
107
+ * const PlanType = StructType({ title: StringType, owner: StringType, due: DateTimeType });
108
+ * const plans = e3.record('plans', DictType(StringType, PlanType), new Map());
109
+ *
110
+ * // The edit capability is the body's LAST parameter; its type comes from
111
+ * // the record, so `edit.set` checks the key and the row.
112
+ * const reschedule = e3.mutation.edit('reschedule', plans,
113
+ * East.function([plans.type, StringType, DateTimeType, e3.mutation.editType(plans.type)], NullType,
114
+ * ($, state, id, due, edit) => {
115
+ * const plan = $.let(state.get(id));
116
+ * $(edit.set(id, { title: plan.title, owner: plan.owner, due }));
117
+ * }));
118
+ * ```
119
+ */
120
+ declare function edit<Name extends string, T extends EastType, Args extends EastType[], E extends EastType>(name: Name, rec: RecordDef<T>, fn: FunctionExpr<[T, ...Args, E], NullType> | CallableFunctionExpr<[T, ...Args, E], NullType>, config?: {
121
+ runner?: FunctionRunner;
122
+ }): MutationDef<Name, T, Args>;
123
+ /**
124
+ * Defines the mutation that applies a patch a client computed — one door for
125
+ * interactive edits.
126
+ *
127
+ * There is no body: the argument IS the change, a `PatchType(State)` sent by
128
+ * whoever made the edit — so it is what a view's save should call, and what an
129
+ * integration sending diffs should call.
130
+ *
131
+ * On a record with no secondary index a patch of per-key changes IS the delta
132
+ * and no program runs at all, which makes it the only write whose cost is
133
+ * independent of the record's size: the touched keys are known before anything
134
+ * runs. Any other patch, such as one replacing the whole state, runs a program
135
+ * that checks it against the state, and on a record with indexes one run
136
+ * computes the index entries the change moves, since that is user East and
137
+ * only a runner evaluates it. That run reads the rows the patch touches, and a
138
+ * replace reads them all.
139
+ *
140
+ * @typeParam Name - Mutation name (literal type)
141
+ * @typeParam T - The owning record's state type (a Dict or a Set)
142
+ * @param rec - The record this mutation writes
143
+ * @param name - Mutation name: an identifier; defaults to `patch`
144
+ * @param config - Optional runner selection (known runtimes only)
145
+ * @returns A MutationDef to pass to `e3.package`
146
+ *
147
+ * @example
148
+ * ```ts
149
+ * const plans = e3.record('plans', DictType(StringType, PlanType), new Map());
150
+ * const pkg = e3.package('planning', '1.0.0', plans, e3.mutation.patch(plans));
151
+ * ```
152
+ */
153
+ declare function patch<T extends EastType, Name extends string = 'patch'>(rec: RecordDef<T>, name?: Name, config?: {
154
+ runner?: FunctionRunner;
155
+ }): MutationDef<Name, T, [PatchTypeOf<T>]>;
156
+ /**
157
+ * The write forms of a record: {@link reduce}, {@link edit} and {@link patch},
158
+ * and `editType`, the type of the capability an `edit` body writes through.
159
+ */
160
+ export declare const mutation: {
161
+ reduce: typeof reduce;
162
+ edit: typeof edit;
163
+ patch: typeof patch;
164
+ editType: typeof editTypeOf;
165
+ };
166
+ export {};
59
167
  //# sourceMappingURL=mutation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mutation.d.ts","sourceRoot":"","sources":["../../src/mutation.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAEV,oBAAoB,EACpB,QAAQ,EACR,YAAY,EACb,MAAM,eAAe,CAAC;AAEvB,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACzD,OAAO,EAAmC,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAQnF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,wBAAgB,QAAQ,CAAC,IAAI,SAAS,MAAM,EAAE,CAAC,SAAS,QAAQ,EAAE,IAAI,SAAS,QAAQ,EAAE,EACvF,IAAI,EAAE,IAAI,EACV,GAAG,EAAE,SAAS,CAAC,CAAC,CAAC,EACjB,EAAE,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,GAAG,oBAAoB,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,EACzE,MAAM,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,cAAc,CAAA;CAAE,GACnC,WAAW,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC"}
1
+ {"version":3,"file":"mutation.d.ts","sourceRoot":"","sources":["../../src/mutation.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAEV,oBAAoB,EACpB,QAAQ,EACR,YAAY,EACZ,WAAW,EACZ,MAAM,eAAe,CAAC;AACvB,OAAO,EAAQ,QAAQ,EAAwB,MAAM,eAAe,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAGzD,OAAO,EAAmC,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAoDnF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,iBAAS,MAAM,CAAC,IAAI,SAAS,MAAM,EAAE,CAAC,SAAS,QAAQ,EAAE,IAAI,SAAS,QAAQ,EAAE,EAC9E,IAAI,EAAE,IAAI,EACV,GAAG,EAAE,SAAS,CAAC,CAAC,CAAC,EACjB,EAAE,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,GAAG,oBAAoB,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,EACzE,MAAM,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,cAAc,CAAA;CAAE,GACnC,WAAW,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;AAuC9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,iBAAS,IAAI,CAAC,IAAI,SAAS,MAAM,EAAE,CAAC,SAAS,QAAQ,EAAE,IAAI,SAAS,QAAQ,EAAE,EAAE,CAAC,SAAS,QAAQ,EAChG,IAAI,EAAE,IAAI,EACV,GAAG,EAAE,SAAS,CAAC,CAAC,CAAC,EACjB,EAAE,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC,EAAE,QAAQ,CAAC,GAAG,oBAAoB,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC,EAAE,QAAQ,CAAC,EAC7F,MAAM,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,cAAc,CAAA;CAAE,GACnC,WAAW,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;AA0C9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,iBAAS,KAAK,CAAC,CAAC,SAAS,QAAQ,EAAE,IAAI,SAAS,MAAM,GAAG,OAAO,EAC9D,GAAG,EAAE,SAAS,CAAC,CAAC,CAAC,EACjB,IAAI,CAAC,EAAE,IAAI,EACX,MAAM,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,cAAc,CAAA;CAAE,GACnC,WAAW,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAqB1C;;;GAGG;AACH,eAAO,MAAM,QAAQ;;;;;CAAgD,CAAC"}