linked-rolls 0.74.0 → 0.75.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.
@@ -1,5 +1,25 @@
1
- import { certainties, certaintyOf, idOf } from "./Assumption.js";
1
+ import { beliefIn, certainties, certaintyOf, idOf } from "./Assumption.js";
2
2
  import { defaultCollationTolerance } from "../collation/Collation.js";
3
+ /**
4
+ * The motivation of an edit that puts right what the version it derives
5
+ * from got wrong: a perforation put in the wrong place, struck or left
6
+ * out. Whether a change corrects an error is not read off its shape, as
7
+ * its type is, but is a reason for it, and so the editor's to give.
8
+ * The edit types held it once, and a document written then is read with
9
+ * this motivation in place of that type.
10
+ * @category Versions and stemma
11
+ */
12
+ export const correctedError = 'corrected-error';
13
+ /**
14
+ * The version's statement of what the motivation of a corrected error
15
+ * means, to stand in its `motivations`.
16
+ * @category Versions and stemma
17
+ */
18
+ export const correctedErrorMotivation = {
19
+ type: 'motivation',
20
+ id: correctedError,
21
+ note: 'Puts right an error of the version it derives from.'
22
+ };
3
23
  /**
4
24
  * The tolerance the derivation was collated at, or the default where it states none.
5
25
  * @category Collation and alignment
@@ -22,12 +42,21 @@ export const insertedBy = (version) => editsOf(version).flatMap(edit => edit.ins
22
42
  export const deletedBy = (version) => editsOf(version).flatMap(edit => edit.delete ?? []);
23
43
  /**
24
44
  * The parents the version names, in the order of `basedOn`, each with the
25
- * certainty its derivation is held with and the belief it rests on.
45
+ * certainty its derivation is held with and the belief it rests on. Given
46
+ * the edition, a derivation that belongs to a proposition set, as an
47
+ * adopted stemma's do, is read with the belief of the set, and names it
48
+ * (`propositionSet`); without it, only a belief of its own is read.
26
49
  * @category Versions and stemma
27
50
  */
28
- export const derivationsOf = (version) => (version.basedOn ?? []).map(derivation => {
29
- const belief = derivation['@annotation']?.belief;
30
- return { parent: idOf(derivation), certainty: certaintyOf(derivation), ...(belief && { belief }) };
51
+ export const derivationsOf = (version, edition = {}) => (version.basedOn ?? []).map(derivation => {
52
+ const belief = beliefIn(edition, derivation);
53
+ const set = derivation['@annotation']?.belief === undefined ? derivation['@annotation']?.id : undefined;
54
+ return {
55
+ parent: idOf(derivation),
56
+ certainty: belief?.certainty ?? 'true',
57
+ ...(belief && { belief }),
58
+ ...(set !== undefined && { propositionSet: set })
59
+ };
31
60
  });
32
61
  const rankOf = (derivation) => certainties.indexOf(certaintyOf(derivation));
33
62
  /**
@@ -2,7 +2,9 @@ import { Edit } from "../model/Edit.js";
2
2
  import { EditionOp } from "./draft.js";
3
3
  /**
4
4
  * Replaces the edits with a single one carrying all their insertions
5
- * and deletions, classified by a guess at what the exchange does.
5
+ * and deletions, classified by a guess at what the exchange does, where
6
+ * its shape says. The edit is the editor's: it belongs to no proposition
7
+ * set a program's run concluded, as one of those merged may have.
6
8
  * @category Operations
7
9
  */
8
10
  export declare const mergeEdits: (versionId: string, toMerge: readonly Edit[]) => EditionOp;
package/lib/ops/edits.js CHANGED
@@ -1,6 +1,7 @@
1
1
  /** Merging and splitting the edits of a version. */
2
2
  import { v4 } from "uuid";
3
3
  import { editsOf } from "../model/Version.js";
4
+ import { keyOf } from "../systems/TrackerBar.js";
4
5
  import { trackerBarOf } from "../systems/index.js";
5
6
  import { distance, mm, subtract } from "../model/Quantity.js";
6
7
  import { noChange, onVersion, insertion, deletion, reading } from "./draft.js";
@@ -22,9 +23,13 @@ const replacementType = (edition, inserted, deleted) => {
22
23
  return undefined;
23
24
  return lengthOf(after) < lengthOf(before) ? 'shorten' : 'prolong';
24
25
  };
26
+ /** Whether the two symbols say the same thing, as a perforation put elsewhere does. */
27
+ const sameKind = (a, b) => a.type !== 'text' && b.type !== 'text' && keyOf(a) === keyOf(b);
25
28
  /**
26
29
  * A guess at what an edit does, from the symbols it exchanges and from
27
- * the systems the version and the one it is based on are coded for.
30
+ * the systems the version and the one it is based on are coded for, or
31
+ * nothing where its shape does not say. Whether it corrects an error is
32
+ * not guessed: that is a motivation, the editor's to give.
28
33
  */
29
34
  const guessEditType = (edition, versionId, edit) => {
30
35
  const inserts = edit.insert ?? [];
@@ -56,25 +61,33 @@ const guessEditType = (edition, versionId, edit) => {
56
61
  return 'shift';
57
62
  if (inserted.length === 0 && deleted.length === 1)
58
63
  return 'remove-redundancy';
59
- if (inserts.length === 1 && deletes.length === 1)
60
- return replacementType(edition, inserts[0], deletes[0]) ?? 'correct-error';
61
- return 'correct-error';
64
+ if (inserts.length === 1 && deletes.length === 1) {
65
+ return replacementType(edition, inserts[0], deletes[0]) ?? (sameKind(inserts[0], deletes[0]) ? 'shift' : undefined);
66
+ }
67
+ return undefined;
62
68
  };
63
69
  /**
64
70
  * Replaces the edits with a single one carrying all their insertions
65
- * and deletions, classified by a guess at what the exchange does.
71
+ * and deletions, classified by a guess at what the exchange does, where
72
+ * its shape says. The edit is the editor's: it belongs to no proposition
73
+ * set a program's run concluded, as one of those merged may have.
66
74
  * @category Operations
67
75
  */
68
76
  export const mergeEdits = (versionId, toMerge) => reading(edition => {
69
77
  if (toMerge.length === 0)
70
78
  return noChange;
79
+ // The edit is the editor's grouping, whatever set of a program's the first one belonged to.
80
+ const { editType: _guessed, '@annotation': annotation, ...first } = toMerge[0];
71
81
  const merged = {
72
- ...toMerge[0],
82
+ ...first,
83
+ ...(annotation?.belief && { '@annotation': annotation }),
73
84
  id: v4(),
74
85
  insert: toMerge.flatMap(edit => edit.insert ?? []),
75
86
  delete: toMerge.flatMap(edit => edit.delete ?? [])
76
87
  };
77
- merged.editType = guessEditType(edition, versionId, merged);
88
+ const editType = guessEditType(edition, versionId, merged);
89
+ if (editType)
90
+ merged.editType = editType;
78
91
  const mergedIds = new Set(toMerge.map(edit => edit.id));
79
92
  return onVersion(versionId, version => {
80
93
  version.edits = [...editsOf(version).filter(edit => !mergedIds.has(edit.id)), merged];