linked-rolls 0.55.0 → 0.57.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 +12 -6
- package/lib/ConditionState.d.ts +1 -2
- package/lib/EditionView.d.ts +22 -8
- package/lib/EditionView.js +66 -23
- package/lib/Emulation.js +2 -2
- package/lib/Feature.d.ts +17 -16
- package/lib/Feature.js +6 -4
- package/lib/RollCopy.d.ts +4 -4
- package/lib/Version.d.ts +1 -1
- package/lib/asJsonLd.js +17 -48
- package/lib/constraints.js +1 -1
- package/lib/editionOps.js +11 -13
- package/lib/importJsonLd.js +1 -6
- package/lib/migrate.js +43 -11
- package/lib/readers/stanfordAton.js +0 -1
- package/lib/scatter.js +3 -3
- package/lib/schema.json +90 -217
- package/lib/spec/context.json +2 -13
- package/lib/witnesses.js +2 -2
- package/package.json +1 -1
package/lib/editionOps.js
CHANGED
|
@@ -10,7 +10,7 @@ import { substitutionsBetween } from "./substitution.js";
|
|
|
10
10
|
import { trackerBarOf } from "./systems/index.js";
|
|
11
11
|
import { applyShift, applyScale, revertShift, revertScale, revertShortening, shortenChains } from "./alignment.js";
|
|
12
12
|
import { assignReference, idOf } from "./Assumption.js";
|
|
13
|
-
import { conditions as conditionsAllowed, featuresBorneBy,
|
|
13
|
+
import { conditions as conditionsAllowed, featuresBorneBy, isPatch, withBorneFeatures } from "./Feature.js";
|
|
14
14
|
import { distance, mm, subtract } from "./Quantity.js";
|
|
15
15
|
const noChange = () => undefined;
|
|
16
16
|
const onCopy = (copyId, op) => draft => {
|
|
@@ -90,7 +90,6 @@ export const createVersion = (copy) => draft => {
|
|
|
90
90
|
const bar = barOf(copy);
|
|
91
91
|
draft.copies.push(copy);
|
|
92
92
|
draft.versions.push({
|
|
93
|
-
type: 'Version',
|
|
94
93
|
id: v4(),
|
|
95
94
|
system: systemOf(bar),
|
|
96
95
|
edits: asSymbols(featuresOf(copy), bar).map(insertion),
|
|
@@ -369,7 +368,7 @@ const goneWith = (features, named) => features.flatMap(feature => named.has(feat
|
|
|
369
368
|
: goneWith(featuresBorneBy(feature), named));
|
|
370
369
|
/** The feature with the named ones gone from what it bears, or the very same one where it bears none of them. */
|
|
371
370
|
const withoutBorne = (feature, named) => {
|
|
372
|
-
if (!
|
|
371
|
+
if (!isPatch(feature) || !feature.features)
|
|
373
372
|
return feature;
|
|
374
373
|
const borne = withoutFeatures(feature.features, named);
|
|
375
374
|
return borne === feature.features ? feature : { ...feature, features: borne };
|
|
@@ -443,7 +442,7 @@ const actFor = (copy, patch, act) => {
|
|
|
443
442
|
* the feature goes into an act of its own.
|
|
444
443
|
*/
|
|
445
444
|
export const addFeature = (copyId, feature, act = {}) => onCopy(copyId, copy => {
|
|
446
|
-
actFor(copy,
|
|
445
|
+
actFor(copy, isPatch(feature), act).push(feature);
|
|
447
446
|
});
|
|
448
447
|
/**
|
|
449
448
|
* States that the patch bears the feature. What a patch bears came onto
|
|
@@ -452,7 +451,7 @@ export const addFeature = (copyId, feature, act = {}) => onCopy(copyId, copy =>
|
|
|
452
451
|
*/
|
|
453
452
|
export const addBorneFeature = (copyId, patchId, feature) => onCopy(copyId, copy => {
|
|
454
453
|
const patch = featuresOf(copy).flatMap(withBorneFeatures).find(borne => borne.id === patchId);
|
|
455
|
-
if (!patch || !
|
|
454
|
+
if (!patch || !isPatch(patch))
|
|
456
455
|
return;
|
|
457
456
|
if (!patch.features)
|
|
458
457
|
patch.features = [];
|
|
@@ -502,7 +501,7 @@ const sayTheSame = (a, b) => {
|
|
|
502
501
|
*/
|
|
503
502
|
const nature = (feature) => {
|
|
504
503
|
const { id, horizontal, depiction, condition, ...rest } = feature;
|
|
505
|
-
return
|
|
504
|
+
return isPatch(feature) && feature.features
|
|
506
505
|
? { ...rest, features: feature.features.map(borne => borne.id) }
|
|
507
506
|
: rest;
|
|
508
507
|
};
|
|
@@ -707,7 +706,7 @@ const byExchange = (edits) => new Map(edits.map(edit => [exchangeKey((edit.inser
|
|
|
707
706
|
* child's symbols and not the parent's with themselves.
|
|
708
707
|
*/
|
|
709
708
|
export const connectVersions = (view, childId, parentId, tolerance = defaultCollationTolerance) => {
|
|
710
|
-
const child = view.
|
|
709
|
+
const child = view.version(childId);
|
|
711
710
|
const stated = child ? editsOf(child) : [];
|
|
712
711
|
const established = stated.filter(edit => !isCollationsOwn(edit));
|
|
713
712
|
const spokenFor = spokenForBy(established);
|
|
@@ -732,7 +731,7 @@ export const connectVersions = (view, childId, parentId, tolerance = defaultColl
|
|
|
732
731
|
* apart would make the apparatus a list of unexplained losses beside
|
|
733
732
|
* a list of unexplained gains.
|
|
734
733
|
*/
|
|
735
|
-
const substituted = differ(child, view.
|
|
734
|
+
const substituted = differ(child, view.version(parentId))
|
|
736
735
|
? substitutionsBetween(own.filter(symbol => !collated.has(symbol.id)), inherited.filter(symbol => !matched.has(symbol.id)), locate, tolerance)
|
|
737
736
|
: [];
|
|
738
737
|
const paired = new Set(substituted.flatMap(({ replaced, by }) => [...by, ...replaced].map(symbol => symbol.id)));
|
|
@@ -773,7 +772,7 @@ export const connectVersions = (view, childId, parentId, tolerance = defaultColl
|
|
|
773
772
|
* tolerance of the derivation, where the caller names none.
|
|
774
773
|
*/
|
|
775
774
|
export const collateSymbols = (view, versionId, symbolIds, tolerance) => {
|
|
776
|
-
const version = view.
|
|
775
|
+
const version = view.version(versionId);
|
|
777
776
|
const principal = version && principalDerivationOf(version);
|
|
778
777
|
if (!version || !principal)
|
|
779
778
|
return noChange;
|
|
@@ -843,7 +842,7 @@ const sharedWith = (view, symbol, copies) => {
|
|
|
843
842
|
* narrow the act to those; naming none separates the whole reading.
|
|
844
843
|
*/
|
|
845
844
|
export const separateReadings = (view, versionId, copies, symbolIds) => {
|
|
846
|
-
const version = view.
|
|
845
|
+
const version = view.version(versionId);
|
|
847
846
|
if (!version)
|
|
848
847
|
return noChange;
|
|
849
848
|
const chosen = symbolIds && new Set(symbolIds);
|
|
@@ -911,7 +910,6 @@ export const deriveVersion = (versionId, editIds) => onVersion(versionId, (versi
|
|
|
911
910
|
if (version.edits)
|
|
912
911
|
version.edits = without(version.edits, edit => chosen.has(edit.id));
|
|
913
912
|
draft.versions.push({
|
|
914
|
-
type: 'Version',
|
|
915
913
|
id: v4(),
|
|
916
914
|
system: stateOf(version).system,
|
|
917
915
|
basedOn: [assignReference(versionId)],
|
|
@@ -970,10 +968,10 @@ const replacementType = (view, inserted, deleted) => {
|
|
|
970
968
|
*/
|
|
971
969
|
const guessEditType = (view, versionId, edit) => {
|
|
972
970
|
const inserts = edit.insert ?? [];
|
|
973
|
-
const deletes = view.
|
|
971
|
+
const deletes = view.symbols(edit.delete ?? []);
|
|
974
972
|
const inserted = expressionTypesOf(inserts);
|
|
975
973
|
const deleted = expressionTypesOf(deletes);
|
|
976
|
-
const bar = trackerBarOf(view.
|
|
974
|
+
const bar = trackerBarOf(view.version(versionId)?.system);
|
|
977
975
|
const parentBar = trackerBarOf(view.predecessorOf(versionId)?.system);
|
|
978
976
|
/**
|
|
979
977
|
* Where the version is coded for another system than its parent, an
|
package/lib/importJsonLd.js
CHANGED
|
@@ -18,12 +18,7 @@ const fromJsonLdValue = (value) => {
|
|
|
18
18
|
return fromJsonLdEntity(value);
|
|
19
19
|
return value;
|
|
20
20
|
};
|
|
21
|
-
/**
|
|
22
|
-
* A node without what the export derived from it. A copy bears the
|
|
23
|
-
* features its acts brought about, and the graph has to be told so.
|
|
24
|
-
* In the edition the act that made a feature is the one place it
|
|
25
|
-
* stands.
|
|
26
|
-
*/
|
|
21
|
+
/** A node without what the export derived from it: what an act changed follows from where the act stands. */
|
|
27
22
|
const asStated = (json) => Object.keys(json).some(key => derivedKeys.has(key))
|
|
28
23
|
? Object.fromEntries(Object.entries(json).filter(([key]) => !derivedKeys.has(key)))
|
|
29
24
|
: json;
|
package/lib/migrate.js
CHANGED
|
@@ -11,6 +11,14 @@ const renamedKeys = {
|
|
|
11
11
|
annotates: 'depiction',
|
|
12
12
|
classification: 'editType'
|
|
13
13
|
};
|
|
14
|
+
/**
|
|
15
|
+
* Classes of feature renamed since: a chain of holes was named after a
|
|
16
|
+
* single hole, and a patch after the act that glued it on.
|
|
17
|
+
*/
|
|
18
|
+
const renamedTypes = {
|
|
19
|
+
Hole: 'HoleChain',
|
|
20
|
+
GluedOn: 'Patch'
|
|
21
|
+
};
|
|
14
22
|
const referenceKeys = ['alignedWith', 'pairedWith', 'basedOn'];
|
|
15
23
|
/**
|
|
16
24
|
* The five type terms that were capitalised while the rest of the
|
|
@@ -33,8 +41,9 @@ const withTypology = (node) => {
|
|
|
33
41
|
}
|
|
34
42
|
return node;
|
|
35
43
|
};
|
|
36
|
-
|
|
37
|
-
|
|
44
|
+
const withRenamedType = (node) => Object.hasOwn(renamedTypes, node['@type']) ? { ...node, '@type': renamedTypes[node['@type']] } : node;
|
|
45
|
+
/** Whether the feature is of the class under either name, since a node is migrated before its children are. */
|
|
46
|
+
const isOfType = (type) => (feature) => feature?.['@type'] === type || renamedTypes[feature?.['@type']] === type;
|
|
38
47
|
/** A version once stated whether it served as a master or stood on one copy. */
|
|
39
48
|
const withoutVersionType = (node) => {
|
|
40
49
|
if (!Object.hasOwn(node, 'versionType'))
|
|
@@ -147,7 +156,6 @@ const withPerforator = (node) => {
|
|
|
147
156
|
perforator: {
|
|
148
157
|
...perforator,
|
|
149
158
|
condition: {
|
|
150
|
-
'@type': 'ConditionState',
|
|
151
159
|
conditionType: 'setting',
|
|
152
160
|
...perforator.condition,
|
|
153
161
|
punchDiameter: diameter
|
|
@@ -187,6 +195,22 @@ const withoutPattern = (node) => {
|
|
|
187
195
|
const { pattern: _moved, ...rest } = node;
|
|
188
196
|
return rest;
|
|
189
197
|
};
|
|
198
|
+
/** A version and a condition state once stated their class, which the key they stand under entails. */
|
|
199
|
+
const withoutEntailedType = (node) => {
|
|
200
|
+
if (node['@type'] !== 'Version' && node['@type'] !== 'ConditionState')
|
|
201
|
+
return node;
|
|
202
|
+
const { '@type': _entailed, ...rest } = node;
|
|
203
|
+
return rest;
|
|
204
|
+
};
|
|
205
|
+
/** An export once stated what a copy or a patch bears, which a reasoner now derives from the acts. */
|
|
206
|
+
const withoutBearings = (node) => {
|
|
207
|
+
if (!Object.hasOwn(node, 'bears') && !Object.hasOwn(node, 'composedOf'))
|
|
208
|
+
return node;
|
|
209
|
+
if (node['@type'] !== 'RollCopy' && node['@type'] !== 'Patch')
|
|
210
|
+
return node;
|
|
211
|
+
const { bears: _bears, composedOf: _composedOf, ...rest } = node;
|
|
212
|
+
return rest;
|
|
213
|
+
};
|
|
190
214
|
/** A derivation written as a single one, before a version could name several. */
|
|
191
215
|
const isSingleDerivation = (basedOn) => basedOn !== null && typeof basedOn === 'object' && !Array.isArray(basedOn);
|
|
192
216
|
const withDerivationList = (node) => isSingleDerivation(node.basedOn) ? { ...node, basedOn: [node.basedOn] } : node;
|
|
@@ -195,8 +219,7 @@ const featuresOf = (copy) => [
|
|
|
195
219
|
...(Array.isArray(copy.features) ? copy.features : []),
|
|
196
220
|
...(Array.isArray(copy.production?.produced) ? copy.production.produced : [])
|
|
197
221
|
];
|
|
198
|
-
|
|
199
|
-
const isHoleChain = (feature) => feature?.['@type'] === 'HoleChain' || feature?.['@type'] === 'Hole';
|
|
222
|
+
const isHoleChain = isOfType('HoleChain');
|
|
200
223
|
/**
|
|
201
224
|
* A copy read on a roll reader was stated as a recording before a sound
|
|
202
225
|
* recording could be one. A sound recording gives no holes, so a recording
|
|
@@ -212,7 +235,7 @@ const withoutFeatureKind = (node) => {
|
|
|
212
235
|
const { kind: _typed, ...rest } = node;
|
|
213
236
|
return rest;
|
|
214
237
|
};
|
|
215
|
-
const isPatch = (
|
|
238
|
+
const isPatch = isOfType('Patch');
|
|
216
239
|
/**
|
|
217
240
|
* A feature a patch bears was sometimes written without an id, and what
|
|
218
241
|
* has no id can be referred to from nowhere: neither by a reading of it
|
|
@@ -303,9 +326,9 @@ const withTimeSpanDates = (node) => {
|
|
|
303
326
|
const { '@value': within, '@type': _typed, ...rest } = node;
|
|
304
327
|
return { ...rest, within };
|
|
305
328
|
};
|
|
306
|
-
const migrateNode = (node) => [withRenamedKeys, withTypology,
|
|
329
|
+
const migrateNode = (node) => [withRenamedKeys, withTypology, withRenamedType, withoutVersionType, withoutVersionSiglum, withLowerCaseTerms, withSplitMethod, withReferences, withKeeper, withoutEmptyKeeper,
|
|
307
330
|
withPerforator, withProductionNodes, withTypedPerforator, withScale, withDerivationList, withReadingKind, withTimeSpanDates,
|
|
308
|
-
withoutFeatureKind, withBorneFeaturesNamed, withFeaturesInActs, withDriveOfStaggering, withoutPattern]
|
|
331
|
+
withoutFeatureKind, withBorneFeaturesNamed, withFeaturesInActs, withDriveOfStaggering, withoutPattern, withoutBearings, withoutEntailedType]
|
|
309
332
|
.reduce((result, step) => step(result), node);
|
|
310
333
|
/** The items each walked, or the very same list where the walk changed none. */
|
|
311
334
|
const walked = (items) => {
|
|
@@ -382,6 +405,13 @@ const onOwnBar = (copy, rollSystem) => {
|
|
|
382
405
|
* roll that named no system was a T-100 roll, and the text a copy's
|
|
383
406
|
* production gave for it is kept as the system's name.
|
|
384
407
|
*/
|
|
408
|
+
/** An export once stated the class of the edition, which R17i was created by entails. */
|
|
409
|
+
const withoutEditionType = (edition) => {
|
|
410
|
+
if (edition['@type'] !== 'Edition')
|
|
411
|
+
return edition;
|
|
412
|
+
const { '@type': _entailed, ...rest } = edition;
|
|
413
|
+
return rest;
|
|
414
|
+
};
|
|
385
415
|
const withSystems = (edition) => {
|
|
386
416
|
if (!edition.roll || !namesSystemOnTheRoll(edition))
|
|
387
417
|
return edition;
|
|
@@ -453,14 +483,16 @@ const referenceOf = (statement) => {
|
|
|
453
483
|
}
|
|
454
484
|
};
|
|
455
485
|
};
|
|
456
|
-
/**
|
|
486
|
+
/** Whether the object states anything beside its id, which a reference to a node does not. */
|
|
487
|
+
const isNode = (value) => typeof value['@id'] === 'string' && Object.keys(value).some(key => key !== '@id' && key !== '@annotation');
|
|
488
|
+
/** The document with each quoted reference back on the node that makes it. */
|
|
457
489
|
const withReferencesOn = (value, bySubject) => {
|
|
458
490
|
if (Array.isArray(value))
|
|
459
491
|
return value.map(item => withReferencesOn(item, bySubject));
|
|
460
492
|
if (!value || typeof value !== 'object')
|
|
461
493
|
return value;
|
|
462
494
|
const walked = Object.fromEntries(Object.entries(value).map(([key, child]) => [key, withReferencesOn(child, bySubject)]));
|
|
463
|
-
const references =
|
|
495
|
+
const references = isNode(value)
|
|
464
496
|
? bySubject.get(value['@id']) ?? []
|
|
465
497
|
: [];
|
|
466
498
|
return references.reduce((node, { key, listed, reference }) => ({ ...node, [key]: listed ? [...(node[key] ?? []), reference] : reference }), walked);
|
|
@@ -482,5 +514,5 @@ const withQuotedStatementsInPlace = (edition) => {
|
|
|
482
514
|
const bySubject = Map.groupBy(statements.map(referenceOf), ({ subject }) => subject);
|
|
483
515
|
return withReferencesOn({ ...rest, ...(others.length > 0 && { '@included': others }) }, bySubject);
|
|
484
516
|
};
|
|
485
|
-
const editionSteps = [withQuotedStatementsInPlace, withSystems, withEditors, withDerivationTolerance];
|
|
517
|
+
const editionSteps = [withoutEditionType, withQuotedStatementsInPlace, withSystems, withEditors, withDerivationTolerance];
|
|
486
518
|
export const migrate = (edition) => walk(editionSteps.reduce((result, step) => step(result), edition));
|
|
@@ -164,7 +164,6 @@ export function readFromStanfordAton(atonString, { trackShift, system = welteT10
|
|
|
164
164
|
type: 'Perforator',
|
|
165
165
|
id: `perforator_${v4()}`,
|
|
166
166
|
condition: {
|
|
167
|
-
type: 'ConditionState',
|
|
168
167
|
conditionType: 'setting',
|
|
169
168
|
punchDiameter: { value: punchDiameter, unit: 'mm' }
|
|
170
169
|
}
|
package/lib/scatter.js
CHANGED
|
@@ -37,7 +37,7 @@ const sitsOn = (view, copies) => (feature) => {
|
|
|
37
37
|
export const readingsOf = (view, symbols, copies) => {
|
|
38
38
|
const tested = sitsOn(view, copies);
|
|
39
39
|
return symbols.flatMap((symbol) => {
|
|
40
|
-
const carriers = view.
|
|
40
|
+
const carriers = view.placedCarriersOf(symbol);
|
|
41
41
|
const here = carriers.filter(tested);
|
|
42
42
|
const there = carriers.filter(carrier => !tested(carrier));
|
|
43
43
|
if (here.length === 0 || there.length === 0)
|
|
@@ -220,12 +220,12 @@ const copiesBearing = (view, symbols) => {
|
|
|
220
220
|
* stopped saying and an editor has to.
|
|
221
221
|
*/
|
|
222
222
|
export const sidesOf = (view, versionId) => {
|
|
223
|
-
const version = view.
|
|
223
|
+
const version = view.version(versionId);
|
|
224
224
|
if (!version)
|
|
225
225
|
return undefined;
|
|
226
226
|
return {
|
|
227
227
|
child: copiesBearing(view, insertedBy(version)),
|
|
228
|
-
parent: copiesBearing(view, view.
|
|
228
|
+
parent: copiesBearing(view, view.symbols(deletedBy(version)))
|
|
229
229
|
};
|
|
230
230
|
};
|
|
231
231
|
const inMillimetres = (value) => `${value.toFixed(2)} mm`;
|