linked-rolls 0.28.0 → 0.30.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/lib/RollCopy.d.ts CHANGED
@@ -274,8 +274,10 @@ export interface RollCopy extends WithType<'RollCopy'>, WithId {
274
274
  */
275
275
  conditions: RollConditionAssignment[];
276
276
  /**
277
- * A short siglum to identify the copy, e.g. "W1" or "S2". A copy
278
- * without one is named by its keeper.
277
+ * A short siglum to identify the copy, e.g. "St1" or "Wi1": letters
278
+ * for the collection the copy was read in, and a number counting the
279
+ * copies of the roll held there. A copy without one is named by its
280
+ * keeper.
279
281
  * @see reo:siglum
280
282
  */
281
283
  siglum?: string;
package/lib/Version.d.ts CHANGED
@@ -4,22 +4,6 @@ import { ActorAssignment, Belief, Certainty, DateAssignment, ReferenceAssumption
4
4
  import { CollationTolerance } from "./Collation";
5
5
  import { AnySymbol } from "./Symbol";
6
6
  import { WithId, WithNote, WithType } from "./utils";
7
- export declare const versionTypes: readonly [
8
- /**
9
- * The roll is in a state where it is (possibly) used as
10
- * the master roll for several new reproductions.
11
- */
12
- 'edition',
13
- /**
14
- * A version that exists only on one specific copy of a roll.
15
- */
16
- 'unicum'];
17
- /**
18
- * The type of a version. An 'edition' version may serve as the
19
- * master for several roll copies; a 'unicum' version exists only
20
- * on one specific copy.
21
- */
22
- export type VersionType = typeof versionTypes[number];
23
7
  /**
24
8
  * A motivation provides a reason or rationale for an editorial change.
25
9
  * Motivations are defined at the version level and referenced by edits.
@@ -82,7 +66,11 @@ export interface VersionCreation {
82
66
  */
83
67
  export interface Version extends WithId, WithType<'Version'> {
84
68
  /**
85
- * A short siglum to identify the version, e.g. "A", "B1", "B2_rev", etc.
69
+ * A short siglum to identify the version, e.g. "A" or "B2". A siglum
70
+ * is given once and not changed: its letter names the line the version
71
+ * was first recognised in, its number counts the versions admitted to
72
+ * that line. Where later work places the version elsewhere in the
73
+ * stemma, `basedOn` changes and the siglum stays.
86
74
  * @see reo:siglum
87
75
  */
88
76
  siglum: string;
@@ -96,13 +84,6 @@ export interface Version extends WithId, WithType<'Version'> {
96
84
  * @see crm:P2 has type
97
85
  */
98
86
  system: Concept;
99
- /**
100
- * Whether the version served as a master for reproductions
101
- * or exists on one copy only. Left out where that is not known,
102
- * as for a version only a secondary witness hints at.
103
- * @see crm:P2 has type
104
- */
105
- versionType?: VersionType;
106
87
  /**
107
88
  * The versions this one is held to derive from, each under the
108
89
  * belief it rests on. The text is read against the principal one
package/lib/Version.js CHANGED
@@ -1,16 +1,5 @@
1
1
  import { certainties, certaintyOf, idOf } from "./Assumption";
2
2
  import { defaultCollationTolerance } from "./Collation";
3
- export const versionTypes = [
4
- /**
5
- * The roll is in a state where it is (possibly) used as
6
- * the master roll for several new reproductions.
7
- */
8
- 'edition',
9
- /**
10
- * A version that exists only on one specific copy of a roll.
11
- */
12
- 'unicum'
13
- ];
14
3
  /** The tolerance the derivation was collated at, or the default where it states none. */
15
4
  export const collationToleranceOf = (derivation) => derivation.collationTolerance ?? defaultCollationTolerance;
16
5
  /** The edits the version states, none where it leaves its text unstated. */
package/lib/editionOps.js CHANGED
@@ -83,7 +83,6 @@ export const createVersion = (siglum, copy) => draft => {
83
83
  id: v4(),
84
84
  siglum,
85
85
  system: systemOf(bar),
86
- versionType: 'edition',
87
86
  edits: asSymbols(copy.features, bar).map(insertion),
88
87
  motivations: []
89
88
  });
@@ -638,6 +637,19 @@ export const removeVersion = (view, versionId) => {
638
637
  };
639
638
  /** Takes the symbols out of the version's own insertions, and the edits that had nothing else. */
640
639
  export const removeSymbols = (versionId, symbolIds) => onVersion(versionId, version => dropInsertions(version, new Set(symbolIds)));
640
+ /**
641
+ * The siglum for a version derived from this one: the line the siglum
642
+ * names, and the next number free in it. A number already given stays
643
+ * given, whatever the stemma does later.
644
+ */
645
+ const nextInLine = (versions, siglum) => {
646
+ const [line] = siglum.match(/^\D*/) ?? [siglum];
647
+ const numbers = versions.flatMap(other => {
648
+ const match = other.siglum.match(/^(\D*)(\d*)$/);
649
+ return match && match[1] === line ? [Number(match[2] || 1)] : [];
650
+ });
651
+ return `${line}${Math.max(1, ...numbers) + 1}`;
652
+ };
641
653
  /** Moves the edits into a new version based on this one. */
642
654
  export const deriveVersion = (versionId, editIds) => onVersion(versionId, (version, draft) => {
643
655
  const chosen = new Set(editIds);
@@ -647,9 +659,8 @@ export const deriveVersion = (versionId, editIds) => onVersion(versionId, (versi
647
659
  draft.versions.push({
648
660
  type: 'Version',
649
661
  id: v4(),
650
- siglum: `${version.siglum}_derived`,
662
+ siglum: nextInLine(draft.versions, version.siglum),
651
663
  system: stateOf(version).system,
652
- versionType: 'unicum',
653
664
  basedOn: [assignReference(versionId)],
654
665
  edits: moved,
655
666
  motivations: []
package/lib/migrate.js CHANGED
@@ -3,8 +3,7 @@ import { rollConditions } from "./RollCopy";
3
3
  import { systemIdIn, systemOf, translationBetween } from "./TrackerBar";
4
4
  import { trackerBars } from "./systems";
5
5
  import { welteT100 } from "./systems/welteT100/bar";
6
- import { versionTypes } from "./Version";
7
- const versionTypeValues = new Set(versionTypes);
6
+ const retiredVersionTypes = new Set(['edition', 'unicum']);
8
7
  const conditionTypeValues = new Set([...rollConditions, ...Object.values(conditions).flat()]);
9
8
  const renamedKeys = {
10
9
  productionEvent: 'production',
@@ -17,14 +16,21 @@ const withRenamedKeys = (node) => Object.keys(node).some(key => Object.hasOwn(re
17
16
  ? Object.fromEntries(Object.entries(node).map(([key, value]) => [renamedKeys[key] ?? key, value]))
18
17
  : node;
19
18
  const withTypology = (node) => {
20
- if (versionTypeValues.has(node['@type'])) {
21
- return { ...node, '@type': 'Version', versionType: node['@type'] };
19
+ if (retiredVersionTypes.has(node['@type'])) {
20
+ return { ...node, '@type': 'Version' };
22
21
  }
23
22
  if (conditionTypeValues.has(node['@type'])) {
24
23
  return { ...node, '@type': 'ConditionState', conditionType: node['@type'] };
25
24
  }
26
25
  return node;
27
26
  };
27
+ /** A version once stated whether it served as a master or stood on one copy. */
28
+ const withoutVersionType = (node) => {
29
+ if (!Object.hasOwn(node, 'versionType'))
30
+ return node;
31
+ const { versionType: _retired, ...rest } = node;
32
+ return rest;
33
+ };
28
34
  const withReferences = (node) => referenceKeys.reduce((result, key) => {
29
35
  const reference = result[key];
30
36
  if (reference && typeof reference === 'object' && '@value' in reference) {
@@ -88,7 +94,7 @@ const withoutEmptyKeeper = (node) => {
88
94
  const { keeper: _unnamed, ...rest } = node;
89
95
  return rest;
90
96
  };
91
- const migrateNode = (node) => [withRenamedKeys, withTypology, withReferences, withKeeper, withoutEmptyKeeper, withProductionNodes, withScale,
97
+ const migrateNode = (node) => [withRenamedKeys, withTypology, withoutVersionType, withReferences, withKeeper, withoutEmptyKeeper, withProductionNodes, withScale,
92
98
  withDerivationList, withReadingKind]
93
99
  .reduce((result, step) => step(result), node);
94
100
  /** The items each walked, or the very same list where the walk changed none. */
@@ -24,7 +24,7 @@ export interface Reservation<T extends string = ReservationType> {
24
24
  * the measurement leaves open, then who holds it.
25
25
  */
26
26
  export declare const reservationsAbout: (copy: RollCopy) => Reservation[];
27
- export declare const versionReservationTypes: readonly ['text-not-stated', 'type-not-stated', 'witnessed-by-statement-only'];
27
+ export declare const versionReservationTypes: readonly ['text-not-stated', 'witnessed-by-statement-only'];
28
28
  export type VersionReservationType = typeof versionReservationTypes[number];
29
29
  /** What the edition cannot vouch for in a version, in the order the checks are listed. */
30
30
  export declare const reservationsAboutVersion: (view: EditionView, version: Readonly<Version>) => Reservation<VersionReservationType>[];
@@ -102,17 +102,12 @@ const checks = [
102
102
  export const reservationsAbout = (copy) => checks.flatMap(check => check(copy) ?? []);
103
103
  export const versionReservationTypes = [
104
104
  'text-not-stated',
105
- 'type-not-stated',
106
105
  'witnessed-by-statement-only'
107
106
  ];
108
107
  const textStated = (_view, version) => version.edits ? undefined : {
109
108
  type: 'text-not-stated',
110
109
  note: 'The version does not state its edits, so it reads as the version it derives from.'
111
110
  };
112
- const typeStated = (_view, version) => version.versionType ? undefined : {
113
- type: 'type-not-stated',
114
- note: 'The version does not say whether it served as a master for several copies or exists on one only.'
115
- };
116
111
  const witnessedByFeatures = (view, version) => {
117
112
  const witnesses = witnessesOf(view, version.id);
118
113
  return witnesses.length > 0 && witnesses.every(({ by }) => by === 'statement') ? {
@@ -120,6 +115,6 @@ const witnessedByFeatures = (view, version) => {
120
115
  note: 'No copy\'s features carry what the version inserts; only copies that state they carry it bear witness to it.'
121
116
  } : undefined;
122
117
  };
123
- const versionChecks = [textStated, typeStated, witnessedByFeatures];
118
+ const versionChecks = [textStated, witnessedByFeatures];
124
119
  /** What the edition cannot vouch for in a version, in the order the checks are listed. */
125
120
  export const reservationsAboutVersion = (view, version) => versionChecks.flatMap(check => check(view, version) ?? []);
package/lib/schema.json CHANGED
@@ -2271,7 +2271,7 @@
2271
2271
  "ontology": "crm:P138i has representation"
2272
2272
  },
2273
2273
  "siglum": {
2274
- "description": "A short siglum to identify the copy, e.g. \"W1\" or \"S2\". A copy without one is named by its keeper.",
2274
+ "description": "A short siglum to identify the copy, e.g. \"St1\" or \"Wi1\": letters for the collection the copy was read in, and a number counting the copies of the roll held there. A copy without one is named by its keeper.",
2275
2275
  "type": "string",
2276
2276
  "ontology": "reo:siglum"
2277
2277
  },
@@ -2446,7 +2446,7 @@
2446
2446
  "type": "array"
2447
2447
  },
2448
2448
  "siglum": {
2449
- "description": "A short siglum to identify the version, e.g. \"A\", \"B1\", \"B2_rev\", etc.",
2449
+ "description": "A short siglum to identify the version, e.g. \"A\" or \"B2\". A siglum is given once and not changed: its letter names the line the version was first recognised in, its number counts the versions admitted to that line. Where later work places the version elsewhere in the stemma, `basedOn` changes and the siglum stays.",
2450
2450
  "type": "string",
2451
2451
  "ontology": "reo:siglum"
2452
2452
  },
@@ -2455,11 +2455,6 @@
2455
2455
  "description": "The reproducing system this version is coded for. One roll was often issued for several of them, and a version is a reading in one system's words: its expression types are that system's vocabulary and its notes sit on that bar's positions. A system the type vocabulary knows carries the IRI of its concept as `id`, from which the export takes the system's own context.",
2456
2456
  "ontology": "crm:P2 has type"
2457
2457
  },
2458
- "versionType": {
2459
- "$ref": "#/definitions/VersionType",
2460
- "description": "Whether the version served as a master for reproductions or exists on one copy only. Left out where that is not known, as for a version only a secondary witness hints at.",
2461
- "ontology": "crm:P2 has type"
2462
- },
2463
2458
  "@id": {
2464
2459
  "description": "A unique identifier for this object.",
2465
2460
  "type": "string"
@@ -2503,14 +2498,6 @@
2503
2498
  "type": "object",
2504
2499
  "ontology": "lrmoo:F28 Expression Creation"
2505
2500
  },
2506
- "VersionType": {
2507
- "description": "The type of a version. An 'edition' version may serve as the master for several roll copies; a 'unicum' version exists only on one specific copy.",
2508
- "enum": [
2509
- "edition",
2510
- "unicum"
2511
- ],
2512
- "type": "string"
2513
- },
2514
2501
  "VerticalSpan": {
2515
2502
  "description": "Describes the vertical extent of a feature on the roll, measured in track numbers. Track numbers correspond to positions on the tracker bar.",
2516
2503
  "properties": {
@@ -249,11 +249,6 @@
249
249
  "@context": { "@vocab": "https://w3id.org/reo/type/" }
250
250
  },
251
251
  "siglum": "reo:siglum",
252
- "versionType": {
253
- "@id": "crm:P2_has_type",
254
- "@type": "@vocab",
255
- "@context": { "@vocab": "https://w3id.org/reo/type/" }
256
- },
257
252
  "basedOn": "lrmoo:R76_is_derivative_of",
258
253
  "edits": "reo:involvedEdit",
259
254
  "motivations": "@included",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "linked-rolls",
3
- "version": "0.28.0",
3
+ "version": "0.30.0",
4
4
  "description": "Digital editions of piano rolls: import, collation, editorial assumptions, JSON-LD export, and emulation through a reproducing system",
5
5
  "license": "MIT",
6
6
  "repository": {