linked-rolls 0.74.0 → 0.76.0
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 +62 -26
- package/lib/collation/Collation.d.ts +12 -42
- package/lib/collation/Collation.js +15 -48
- package/lib/filiation/adoption.d.ts +23 -4
- package/lib/filiation/adoption.js +81 -23
- package/lib/filiation/edits.d.ts +35 -19
- package/lib/filiation/edits.js +68 -34
- package/lib/filiation/index.d.ts +2 -1
- package/lib/filiation/index.js +2 -1
- package/lib/filiation/record.d.ts +49 -0
- package/lib/filiation/record.js +49 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/io/asJsonLd.js +5 -1
- package/lib/io/importJsonLd.js +42 -4
- package/lib/io/migrate.d.ts +7 -0
- package/lib/io/migrate.js +196 -2
- package/lib/model/Agent.d.ts +3 -1
- package/lib/model/Assumption.d.ts +8 -1
- package/lib/model/Assumption.js +2 -1
- package/lib/model/Edit.d.ts +76 -17
- package/lib/model/Edit.js +52 -3
- package/lib/model/Edition.d.ts +32 -3
- package/lib/model/RollCopy.js +1 -1
- package/lib/model/Version.d.ts +3 -13
- package/lib/model/Version.js +7 -2
- package/lib/ops/collation.d.ts +8 -4
- package/lib/ops/collation.js +40 -23
- package/lib/ops/copies.js +1 -2
- package/lib/ops/draft.d.ts +1 -9
- package/lib/ops/draft.js +0 -12
- package/lib/ops/edits.d.ts +20 -3
- package/lib/ops/edits.js +36 -15
- package/lib/ops/index.d.ts +1 -1
- package/lib/ops/index.js +1 -1
- package/lib/ops/versions.d.ts +3 -2
- package/lib/ops/versions.js +4 -5
- package/lib/schema.json +60 -64
- package/lib/software.d.ts +12 -0
- package/lib/software.js +10 -0
- package/lib/spec/context.json +8 -5
- package/package.json +1 -1
package/lib/ops/collation.js
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import { v4 } from "uuid";
|
|
2
2
|
import { getAt, pathIn } from "../lookup/paths.js";
|
|
3
|
-
import { collationsOf, defaultCollationTolerance, isCollationsOwn
|
|
3
|
+
import { collationsOf, defaultCollationTolerance, isCollationsOwn } from "../collation/Collation.js";
|
|
4
|
+
import { motivationProposedFor, technicalChange } from "../model/Edit.js";
|
|
4
5
|
import { collationToleranceOf, derivesFrom, editsOf, insertedBy, principalDerivationOf } from "../model/Version.js";
|
|
5
6
|
import { substitutionsBetween } from "../collation/substitution.js";
|
|
6
7
|
import { trackerBarOf } from "../systems/index.js";
|
|
7
8
|
import { assignReference, idOf } from "../model/Assumption.js";
|
|
8
|
-
import { noChange, onVersion, insertion, deletion,
|
|
9
|
+
import { noChange, onVersion, insertion, deletion, dropInsertions, reading } from "./draft.js";
|
|
9
10
|
import { hypothesesBeside } from "./versions.js";
|
|
11
|
+
import { shapeOf } from "./edits.js";
|
|
12
|
+
import { predecessorOf } from "../analysis/stemma.js";
|
|
10
13
|
import { placeOf, snapshotOf } from "../analysis/text.js";
|
|
11
14
|
import { copyOfFeature, versionIn } from "../lookup/lookup.js";
|
|
15
|
+
import { motivationOfChanges, proposedMotivations } from "../filiation/edits.js";
|
|
12
16
|
/** The carriers of each collated symbol pass to its counterpart. */
|
|
13
17
|
const handOverCarriers = (edition, draft, collations) => collations.forEach(({ symbol, counterpart }) => {
|
|
14
18
|
const path = pathIn(edition, counterpart.id);
|
|
@@ -43,15 +47,18 @@ const byExchange = (edits) => new Map(edits.map(edit => [exchangeKey((edit.inser
|
|
|
43
47
|
* tolerance it was collated at and becomes the principal one; the
|
|
44
48
|
* hypotheses the child stated beside its former one stay.
|
|
45
49
|
*
|
|
46
|
-
* The edits the child already stated are rewritten only as far as
|
|
47
|
-
*
|
|
50
|
+
* The edits the child already stated are rewritten only as far as they
|
|
51
|
+
* are the program's (`isCollationsOwn`). An editor's reading of the
|
|
48
52
|
* difference between the two texts stays, and the symbols it speaks for
|
|
49
53
|
* are left out of the collation, so that connecting the two again
|
|
50
54
|
* neither doubles them nor silently drops what somebody established by
|
|
51
55
|
* hand. An equivalence is the collation's own, since it is drawn from
|
|
52
56
|
* the two systems' vocabularies rather than read off the paper, but one
|
|
53
57
|
* drawn again over the very same symbols is kept as it stands, with its
|
|
54
|
-
* identifier and whatever was written on it.
|
|
58
|
+
* identifier and whatever was written on it. An insertion or deletion
|
|
59
|
+
* drawn anew has the motivation its shape calls for
|
|
60
|
+
* (`motivationProposedFor`): the generic musical one, or the technical
|
|
61
|
+
* one, which an equivalence drawn anew always has.
|
|
55
62
|
*
|
|
56
63
|
* The child's own text is what it shows less what the parent hands
|
|
57
64
|
* down, so that connecting two versions already connected collates the
|
|
@@ -101,31 +108,36 @@ export const connectVersions = (childId, parentId, tolerance = defaultCollationT
|
|
|
101
108
|
return alreadyStated.get(exchangeKey(inserted, deleted)) ?? {
|
|
102
109
|
type: 'edit',
|
|
103
110
|
id: v4(),
|
|
104
|
-
|
|
105
|
-
motivation: unchecked,
|
|
111
|
+
motivation: technicalChange,
|
|
106
112
|
insert: [...by],
|
|
107
113
|
delete: deleted
|
|
108
114
|
};
|
|
109
115
|
};
|
|
110
|
-
const
|
|
111
|
-
...
|
|
112
|
-
...substituted.map(equivalence),
|
|
113
|
-
...own.filter(symbol => !collated.has(symbol.id) && !paired.has(symbol.id)).map(insertion).map(asUnchecked),
|
|
116
|
+
const bare = [
|
|
117
|
+
...own.filter(symbol => !collated.has(symbol.id) && !paired.has(symbol.id)).map(insertion),
|
|
114
118
|
...inherited
|
|
115
119
|
.filter(symbol => !matched.has(symbol.id) && !paired.has(symbol.id))
|
|
116
|
-
.map(symbol =>
|
|
120
|
+
.map(symbol => deletion(symbol.id))
|
|
117
121
|
];
|
|
122
|
+
const drawn = [...established, ...substituted.map(equivalence), ...bare];
|
|
118
123
|
// Read off the child as it stands, since once its edits are written a
|
|
119
124
|
// reading of it would copy them all.
|
|
120
|
-
const motivations = declaring(child?.motivations ?? [], edits);
|
|
121
125
|
const basedOn = [
|
|
122
126
|
{ ...assignReference(parentId), collationTolerance: tolerance },
|
|
123
127
|
...(child ? hypothesesBeside(child, parentId) : [])
|
|
124
128
|
];
|
|
129
|
+
// What kind of change an insertion or a deletion is depends on what it stands among.
|
|
130
|
+
const connected = { ...edition, versions: edition.versions.map(version => version.id === childId ? { ...version, edits: drawn, basedOn } : version) };
|
|
131
|
+
const motivations = proposedMotivations(connected, childId);
|
|
132
|
+
const anew = new Set(bare.map(edit => edit.id));
|
|
133
|
+
const edits = drawn.map(edit => {
|
|
134
|
+
if (!anew.has(edit.id))
|
|
135
|
+
return edit;
|
|
136
|
+
return { ...edit, motivation: motivationOfChanges(motivations, [...(edit.insert ?? []).map(symbol => symbol.id), ...(edit.delete ?? [])]) };
|
|
137
|
+
});
|
|
125
138
|
return onVersion(childId, (version, draft) => {
|
|
126
139
|
handOverCarriers(edition, draft, collations);
|
|
127
140
|
version.edits = edits;
|
|
128
|
-
version.motivations = motivations;
|
|
129
141
|
version.basedOn = basedOn;
|
|
130
142
|
});
|
|
131
143
|
});
|
|
@@ -184,7 +196,8 @@ const sharedWith = (edition, symbol, copies) => {
|
|
|
184
196
|
* Takes the named copies' reading of a symbol back out of the symbol it
|
|
185
197
|
* was collated into: their carriers pass to a new symbol of the
|
|
186
198
|
* version's own, the remaining copies keep the symbol they had, and the
|
|
187
|
-
* version states the exchange
|
|
199
|
+
* version states the exchange, with the motivation its shape calls for
|
|
200
|
+
* (`motivationProposedFor`) where the version derives from another.
|
|
188
201
|
*
|
|
189
202
|
* This is the inverse of the hand-over a collation makes, and it is
|
|
190
203
|
* what lets a derivation be collated a second time. A collated symbol
|
|
@@ -217,14 +230,18 @@ export const separateReadings = (versionId, copies, symbolIds) => reading(editio
|
|
|
217
230
|
return noChange;
|
|
218
231
|
const inserted = new Set(insertedBy(version).map(symbol => symbol.id));
|
|
219
232
|
const stated = editsOf(version);
|
|
220
|
-
const
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
233
|
+
const derived = predecessorOf(edition, versionId) !== undefined;
|
|
234
|
+
const separations = shared.map(({ symbol, mine }) => {
|
|
235
|
+
const separation = {
|
|
236
|
+
type: 'edit',
|
|
237
|
+
id: v4(),
|
|
238
|
+
insert: [readingOf(symbol, [...mine])],
|
|
239
|
+
// A symbol the version inserts itself stays where it is, minus
|
|
240
|
+
// the carriers that leave it. Only one it inherits is exchanged.
|
|
241
|
+
...(inserted.has(symbol.id) ? {} : { delete: [symbol.id] })
|
|
242
|
+
};
|
|
243
|
+
return derived ? { ...separation, motivation: motivationProposedFor(shapeOf(edition, versionId, separation)) } : separation;
|
|
244
|
+
});
|
|
228
245
|
return onVersion(versionId, (version, draft) => {
|
|
229
246
|
shared.forEach(({ symbol, theirs }) => {
|
|
230
247
|
const path = pathIn(edition, symbol.id);
|
package/lib/ops/copies.js
CHANGED
|
@@ -21,8 +21,7 @@ export const createVersion = (copy) => draft => {
|
|
|
21
21
|
draft.versions.push({
|
|
22
22
|
id: v4(),
|
|
23
23
|
system: systemOf(bar),
|
|
24
|
-
edits: asSymbols(featuresOf(copy), bar).map(insertion)
|
|
25
|
-
motivations: []
|
|
24
|
+
edits: asSymbols(featuresOf(copy), bar).map(insertion)
|
|
26
25
|
});
|
|
27
26
|
};
|
|
28
27
|
/**
|
package/lib/ops/draft.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { Draft } from "immer";
|
|
|
3
3
|
import { Edition } from "../model/Edition.js";
|
|
4
4
|
import { AnySymbol } from "../model/Symbol.js";
|
|
5
5
|
import { Edit } from "../model/Edit.js";
|
|
6
|
-
import {
|
|
6
|
+
import { Version } from "../model/Version.js";
|
|
7
7
|
import { RollCopy } from "../model/RollCopy.js";
|
|
8
8
|
import { Belief, ReferenceAssumption } from "../model/Assumption.js";
|
|
9
9
|
import { FeatureOrPatch } from "../model/Feature.js";
|
|
@@ -42,14 +42,6 @@ export declare const droppedIds: (before: readonly WithId[], after: readonly Wit
|
|
|
42
42
|
export type Ids = ReadonlySet<string>;
|
|
43
43
|
export declare const insertion: (symbol: AnySymbol) => Edit;
|
|
44
44
|
export declare const deletion: (symbolId: string) => Edit;
|
|
45
|
-
/** The edit as a collation leaves it: made by rule, and not yet read by anybody. */
|
|
46
|
-
export declare const asUnchecked: (edit: Edit) => Edit;
|
|
47
|
-
/**
|
|
48
|
-
* The motivations with the unchecked one declared, where any edit
|
|
49
|
-
* names it and the version does not state it yet. An edit naming a
|
|
50
|
-
* motivation the version leaves undeclared points at nothing.
|
|
51
|
-
*/
|
|
52
|
-
export declare const declaring: (motivations: Motivation[], edits: readonly Edit[]) => Motivation[];
|
|
53
45
|
export declare const insertedIn: (versions: readonly Version[]) => AnySymbol[];
|
|
54
46
|
/** The edits with the change applied, less those it emptied; the very same array where it changed none. */
|
|
55
47
|
export declare const edited: (edits: Edit[], change: (edit: Edit) => Edit) => Edit[];
|
package/lib/ops/draft.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/** What the operations are built from: the type of an operation, how one finds what it writes to on the draft, and the edits it writes. */
|
|
2
2
|
import { isDraft } from "immer";
|
|
3
3
|
import { v4 } from "uuid";
|
|
4
|
-
import { unchecked, uncheckedMotivation } from "../collation/Collation.js";
|
|
5
4
|
import { insertedBy } from "../model/Version.js";
|
|
6
5
|
import { featuresOf } from "../model/RollCopy.js";
|
|
7
6
|
import { assignReference } from "../model/Assumption.js";
|
|
@@ -45,17 +44,6 @@ export const droppedIds = (before, after) => {
|
|
|
45
44
|
};
|
|
46
45
|
export const insertion = (symbol) => ({ type: 'edit', id: v4(), insert: [symbol] });
|
|
47
46
|
export const deletion = (symbolId) => ({ type: 'edit', id: v4(), delete: [symbolId] });
|
|
48
|
-
/** The edit as a collation leaves it: made by rule, and not yet read by anybody. */
|
|
49
|
-
export const asUnchecked = (edit) => ({ ...edit, motivation: unchecked });
|
|
50
|
-
/**
|
|
51
|
-
* The motivations with the unchecked one declared, where any edit
|
|
52
|
-
* names it and the version does not state it yet. An edit naming a
|
|
53
|
-
* motivation the version leaves undeclared points at nothing.
|
|
54
|
-
*/
|
|
55
|
-
export const declaring = (motivations, edits) => edits.some(edit => edit.motivation === unchecked)
|
|
56
|
-
&& !motivations.some(motivation => motivation.id === unchecked)
|
|
57
|
-
? [...motivations, uncheckedMotivation]
|
|
58
|
-
: motivations;
|
|
59
47
|
const isEmpty = (edit) => !edit.insert?.length && !edit.delete?.length;
|
|
60
48
|
export const insertedIn = (versions) => versions.flatMap(insertedBy);
|
|
61
49
|
/** The edits with the change applied, less those it emptied; the very same array where it changed none. */
|
package/lib/ops/edits.d.ts
CHANGED
|
@@ -1,13 +1,30 @@
|
|
|
1
|
-
import { Edit } from "../model/Edit.js";
|
|
1
|
+
import { Edit, EditShape } from "../model/Edit.js";
|
|
2
2
|
import { EditionOp } from "./draft.js";
|
|
3
|
+
import { Edition } from "../model/Edition.js";
|
|
4
|
+
/**
|
|
5
|
+
* A guess at the shape of an edit, from the symbols it exchanges and
|
|
6
|
+
* from the systems the version and the one it is based on are coded
|
|
7
|
+
* for, or nothing where it takes no shape the guess knows. It looks at
|
|
8
|
+
* the edit alone: a single expression deleted is taken for a redundancy
|
|
9
|
+
* removed, which `proposeEdits` checks against the text.
|
|
10
|
+
* @category Lookups
|
|
11
|
+
*/
|
|
12
|
+
export declare const shapeOf: (edition: Edition, versionId: string, edit: Readonly<Edit>) => EditShape | undefined;
|
|
3
13
|
/**
|
|
4
14
|
* Replaces the edits with a single one carrying all their insertions
|
|
5
|
-
* and deletions
|
|
15
|
+
* and deletions. It keeps the first motivation of the editor's that any
|
|
16
|
+
* of them states, and where none does, it has the one its shape calls
|
|
17
|
+
* for (`motivationProposedFor`), so that a merge says it is a musical
|
|
18
|
+
* or a technical change, unless the version derives from none. A
|
|
19
|
+
* grouping that says no more is the program's by rule
|
|
20
|
+
* (`isCollationsOwn`), until the editor says why it was made.
|
|
6
21
|
* @category Operations
|
|
7
22
|
*/
|
|
8
23
|
export declare const mergeEdits: (versionId: string, toMerge: readonly Edit[]) => EditionOp;
|
|
9
24
|
/**
|
|
10
|
-
* Replaces the edit with one edit per inserted and one per deleted
|
|
25
|
+
* Replaces the edit with one edit per inserted and one per deleted
|
|
26
|
+
* symbol. Each part keeps the motivation of the edit, since splitting
|
|
27
|
+
* an edit does not change why it was made.
|
|
11
28
|
* @category Operations
|
|
12
29
|
*/
|
|
13
30
|
export declare const splitEdit: (versionId: string, toSplit: Edit) => EditionOp;
|
package/lib/ops/edits.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/** Merging and splitting the edits of a version. */
|
|
2
2
|
import { v4 } from "uuid";
|
|
3
|
+
import { motivationProposedFor, musicalChange, technicalChange } from "../model/Edit.js";
|
|
3
4
|
import { editsOf } from "../model/Version.js";
|
|
5
|
+
import { keyOf } from "../systems/TrackerBar.js";
|
|
4
6
|
import { trackerBarOf } from "../systems/index.js";
|
|
5
7
|
import { distance, mm, subtract } from "../model/Quantity.js";
|
|
6
8
|
import { noChange, onVersion, insertion, deletion, reading } from "./draft.js";
|
|
@@ -15,18 +17,24 @@ const lengthOf = (span) => subtract(span.to, span.from);
|
|
|
15
17
|
/** How far apart two onsets may lie for the one symbol to count as a replacement of the other. */
|
|
16
18
|
const REPLACEMENT_TOLERANCE = mm(5);
|
|
17
19
|
/** Shorten or prolong, where the inserted symbol starts about where the deleted one did. */
|
|
18
|
-
const
|
|
20
|
+
const replacementShape = (edition, inserted, deleted) => {
|
|
19
21
|
const after = placeOf(edition, inserted);
|
|
20
22
|
const before = placeOf(edition, deleted);
|
|
21
23
|
if (!after || !before || distance(after.from, before.from) >= REPLACEMENT_TOLERANCE)
|
|
22
24
|
return undefined;
|
|
23
25
|
return lengthOf(after) < lengthOf(before) ? 'shorten' : 'prolong';
|
|
24
26
|
};
|
|
27
|
+
/** Whether the two symbols say the same thing, as a perforation put elsewhere does. */
|
|
28
|
+
const sameKind = (a, b) => a.type !== 'text' && b.type !== 'text' && keyOf(a) === keyOf(b);
|
|
25
29
|
/**
|
|
26
|
-
* A guess at
|
|
27
|
-
* the systems the version and the one it is based on are coded
|
|
30
|
+
* A guess at the shape of an edit, from the symbols it exchanges and
|
|
31
|
+
* from the systems the version and the one it is based on are coded
|
|
32
|
+
* for, or nothing where it takes no shape the guess knows. It looks at
|
|
33
|
+
* the edit alone: a single expression deleted is taken for a redundancy
|
|
34
|
+
* removed, which `proposeEdits` checks against the text.
|
|
35
|
+
* @category Lookups
|
|
28
36
|
*/
|
|
29
|
-
const
|
|
37
|
+
export const shapeOf = (edition, versionId, edit) => {
|
|
30
38
|
const inserts = edit.insert ?? [];
|
|
31
39
|
const deletes = symbolsIn(edition, edit.delete ?? []);
|
|
32
40
|
const inserted = expressionTypesOf(inserts);
|
|
@@ -40,8 +48,7 @@ const guessEditType = (edition, versionId, edit) => {
|
|
|
40
48
|
* SforzandoForte says the same thing in the other system's words, and
|
|
41
49
|
* a red command the green bar cannot read struck, or a green hold put
|
|
42
50
|
* in where the red had no word for it, belongs to the same act. That
|
|
43
|
-
* is a recoding.
|
|
44
|
-
* made a mistake. Only an insertion spelling the bar's own accent
|
|
51
|
+
* is a recoding. Only an insertion spelling the bar's own accent
|
|
45
52
|
* reads more narrowly, as the accent it spells.
|
|
46
53
|
*/
|
|
47
54
|
const transferred = bar && parentBar && bar.id !== parentBar.id;
|
|
@@ -56,38 +63,52 @@ const guessEditType = (edition, versionId, edit) => {
|
|
|
56
63
|
return 'shift';
|
|
57
64
|
if (inserted.length === 0 && deleted.length === 1)
|
|
58
65
|
return 'remove-redundancy';
|
|
59
|
-
if (inserts.length === 1 && deletes.length === 1)
|
|
60
|
-
return
|
|
61
|
-
|
|
66
|
+
if (inserts.length === 1 && deletes.length === 1) {
|
|
67
|
+
return replacementShape(edition, inserts[0], deletes[0]) ?? (sameKind(inserts[0], deletes[0]) ? 'shift' : undefined);
|
|
68
|
+
}
|
|
69
|
+
return undefined;
|
|
62
70
|
};
|
|
63
71
|
/**
|
|
64
72
|
* Replaces the edits with a single one carrying all their insertions
|
|
65
|
-
* and deletions
|
|
73
|
+
* and deletions. It keeps the first motivation of the editor's that any
|
|
74
|
+
* of them states, and where none does, it has the one its shape calls
|
|
75
|
+
* for (`motivationProposedFor`), so that a merge says it is a musical
|
|
76
|
+
* or a technical change, unless the version derives from none. A
|
|
77
|
+
* grouping that says no more is the program's by rule
|
|
78
|
+
* (`isCollationsOwn`), until the editor says why it was made.
|
|
66
79
|
* @category Operations
|
|
67
80
|
*/
|
|
68
81
|
export const mergeEdits = (versionId, toMerge) => reading(edition => {
|
|
69
82
|
if (toMerge.length === 0)
|
|
70
83
|
return noChange;
|
|
84
|
+
const { motivation: _first, ...first } = toMerge[0];
|
|
71
85
|
const merged = {
|
|
72
|
-
...
|
|
86
|
+
...first,
|
|
73
87
|
id: v4(),
|
|
74
88
|
insert: toMerge.flatMap(edit => edit.insert ?? []),
|
|
75
89
|
delete: toMerge.flatMap(edit => edit.delete ?? [])
|
|
76
90
|
};
|
|
77
|
-
|
|
91
|
+
const editors = toMerge.find(edit => edit.motivation !== undefined && edit.motivation !== musicalChange && edit.motivation !== technicalChange);
|
|
92
|
+
if (editors)
|
|
93
|
+
merged.motivation = editors.motivation;
|
|
94
|
+
else if (predecessorOf(edition, versionId))
|
|
95
|
+
merged.motivation = motivationProposedFor(shapeOf(edition, versionId, merged));
|
|
78
96
|
const mergedIds = new Set(toMerge.map(edit => edit.id));
|
|
79
97
|
return onVersion(versionId, version => {
|
|
80
98
|
version.edits = [...editsOf(version).filter(edit => !mergedIds.has(edit.id)), merged];
|
|
81
99
|
});
|
|
82
100
|
});
|
|
83
101
|
/**
|
|
84
|
-
* Replaces the edit with one edit per inserted and one per deleted
|
|
102
|
+
* Replaces the edit with one edit per inserted and one per deleted
|
|
103
|
+
* symbol. Each part keeps the motivation of the edit, since splitting
|
|
104
|
+
* an edit does not change why it was made.
|
|
85
105
|
* @category Operations
|
|
86
106
|
*/
|
|
87
107
|
export const splitEdit = (versionId, toSplit) => {
|
|
108
|
+
const kept = toSplit.motivation === undefined ? {} : { motivation: toSplit.motivation };
|
|
88
109
|
const parts = [
|
|
89
|
-
...(toSplit.insert ?? []).map(insertion),
|
|
90
|
-
...(toSplit.delete ?? []).map(deletion)
|
|
110
|
+
...(toSplit.insert ?? []).map(symbol => ({ ...insertion(symbol), ...kept })),
|
|
111
|
+
...(toSplit.delete ?? []).map(id => ({ ...deletion(id), ...kept }))
|
|
91
112
|
];
|
|
92
113
|
return onVersion(versionId, version => {
|
|
93
114
|
version.edits = [...editsOf(version).filter(edit => edit.id !== toSplit.id), ...parts];
|
package/lib/ops/index.d.ts
CHANGED
|
@@ -8,6 +8,6 @@ export { createVersion, addCopy, alignmentFor, alignCopy, alignCopies, chooseRef
|
|
|
8
8
|
export { stateFeatureCondition, addFeature, addBorneFeature, removeFeatures, mergeObstacle, mergeObstacleIn, mergeFeatures, type FeatureAct, type MergeObstacle } from "./features.js";
|
|
9
9
|
export { detachVersion, removeVersion, removeSymbols, deriveVersion, stateDerivation, clearDerivation } from "./versions.js";
|
|
10
10
|
export { connectVersions, collateSymbols, separateReadings } from "./collation.js";
|
|
11
|
-
export { mergeEdits, splitEdit } from "./edits.js";
|
|
11
|
+
export { mergeEdits, splitEdit, shapeOf } from "./edits.js";
|
|
12
12
|
export { placeCommand, unplaceCommand, pairCommands, unpairCommand } from "./commands.js";
|
|
13
13
|
export { createBelief, clearBelief, setCertainty, addReason, removeReason } from "./beliefs.js";
|
package/lib/ops/index.js
CHANGED
|
@@ -8,6 +8,6 @@ export { createVersion, addCopy, alignmentFor, alignCopy, alignCopies, chooseRef
|
|
|
8
8
|
export { stateFeatureCondition, addFeature, addBorneFeature, removeFeatures, mergeObstacle, mergeObstacleIn, mergeFeatures } from "./features.js";
|
|
9
9
|
export { detachVersion, removeVersion, removeSymbols, deriveVersion, stateDerivation, clearDerivation } from "./versions.js";
|
|
10
10
|
export { connectVersions, collateSymbols, separateReadings } from "./collation.js";
|
|
11
|
-
export { mergeEdits, splitEdit } from "./edits.js";
|
|
11
|
+
export { mergeEdits, splitEdit, shapeOf } from "./edits.js";
|
|
12
12
|
export { placeCommand, unplaceCommand, pairCommands, unpairCommand } from "./commands.js";
|
|
13
13
|
export { createBelief, clearBelief, setCertainty, addReason, removeReason } from "./beliefs.js";
|
package/lib/ops/versions.d.ts
CHANGED
|
@@ -5,8 +5,9 @@ import { EditionOp } from "./draft.js";
|
|
|
5
5
|
export declare const hypothesesBeside: (version: Readonly<Version>, parentId: string) => Derivation[];
|
|
6
6
|
/**
|
|
7
7
|
* Makes the version stand on its own: what it inherited becomes its
|
|
8
|
-
* own insertions, and its derivations go, the hypotheses among them
|
|
9
|
-
*
|
|
8
|
+
* own insertions, and its derivations go, the hypotheses among them.
|
|
9
|
+
* Its edits now state its text rather than a change, and say nothing of
|
|
10
|
+
* why they were made.
|
|
10
11
|
* @category Operations
|
|
11
12
|
*/
|
|
12
13
|
export declare const detachVersion: (versionId: string) => EditionOp;
|
package/lib/ops/versions.js
CHANGED
|
@@ -28,8 +28,9 @@ const dropDerivations = (version, matches) => {
|
|
|
28
28
|
};
|
|
29
29
|
/**
|
|
30
30
|
* Makes the version stand on its own: what it inherited becomes its
|
|
31
|
-
* own insertions, and its derivations go, the hypotheses among them
|
|
32
|
-
*
|
|
31
|
+
* own insertions, and its derivations go, the hypotheses among them.
|
|
32
|
+
* Its edits now state its text rather than a change, and say nothing of
|
|
33
|
+
* why they were made.
|
|
33
34
|
* @category Operations
|
|
34
35
|
*/
|
|
35
36
|
export const detachVersion = (versionId) => reading(edition => {
|
|
@@ -37,7 +38,6 @@ export const detachVersion = (versionId) => reading(edition => {
|
|
|
37
38
|
return onVersion(versionId, version => {
|
|
38
39
|
version.edits = edits;
|
|
39
40
|
delete version.basedOn;
|
|
40
|
-
version.motivations = [];
|
|
41
41
|
});
|
|
42
42
|
});
|
|
43
43
|
/**
|
|
@@ -76,8 +76,7 @@ export const deriveVersion = (versionId, editIds) => onVersion(versionId, (versi
|
|
|
76
76
|
id: v4(),
|
|
77
77
|
system: stateOf(version).system,
|
|
78
78
|
basedOn: [assignReference(versionId)],
|
|
79
|
-
edits: moved
|
|
80
|
-
motivations: []
|
|
79
|
+
edits: moved
|
|
81
80
|
});
|
|
82
81
|
});
|
|
83
82
|
/**
|