@lionweb/utilities 0.7.0-beta.17 → 0.7.0-beta.19

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.
@@ -0,0 +1,43 @@
1
+ import { LionWebKey } from "@lionweb/json"
2
+
3
+ type OptionallyNamed = {
4
+ name?: string // == name when it can be looked up
5
+ }
6
+
7
+ type LanguagePointer = {
8
+ key: LionWebKey
9
+ version: string
10
+ } & OptionallyNamed
11
+
12
+ /* abstract */ type ClassifierMetric = {
13
+ language: LanguagePointer
14
+ key: LionWebKey // key of classifier
15
+ } & OptionallyNamed
16
+
17
+ type ClassifierMetaTypes = "annotation" | "concept" | "interface"
18
+
19
+ type ClassifierInstantiationMetric = {
20
+ metaType?: ClassifierMetaTypes
21
+ instantiations: number
22
+ } & ClassifierMetric
23
+
24
+ type LanguageMetric = {
25
+ instantiations: number
26
+ } & LanguagePointer
27
+
28
+ // TODO order?
29
+ type Metrics = {
30
+ languagesWithInstantiations: LanguageMetric[]
31
+ instantiatedClassifiers: ClassifierInstantiationMetric[]
32
+ uninstantiatedInstantiableClassifiers: ClassifierMetric[]
33
+ languagesWithoutInstantiations: LanguagePointer[]
34
+ }
35
+
36
+
37
+ export type {
38
+ ClassifierInstantiationMetric,
39
+ ClassifierMetaTypes,
40
+ LanguagePointer,
41
+ Metrics
42
+ }
43
+
@@ -0,0 +1,73 @@
1
+ import {
2
+ LionWebJsonChunk,
3
+ LionWebJsonContainment,
4
+ LionWebJsonMetaPointer,
5
+ LionWebJsonNode,
6
+ LionWebJsonProperty,
7
+ LionWebJsonReference,
8
+ LionWebJsonReferenceTarget,
9
+ LionWebJsonUsedLanguage
10
+ } from "@lionweb/json"
11
+
12
+ const orderedMetaPointer = ({ language, version, key }: LionWebJsonMetaPointer): LionWebJsonMetaPointer => ({
13
+ language,
14
+ version,
15
+ key
16
+ })
17
+
18
+ const orderedSerializedLanguageReference = ({ key, version }: LionWebJsonUsedLanguage): LionWebJsonUsedLanguage => ({
19
+ key,
20
+ version
21
+ })
22
+
23
+ const orderedSerializedReferenceTarget = ({ reference, resolveInfo }: LionWebJsonReferenceTarget): LionWebJsonReferenceTarget => ({
24
+ resolveInfo,
25
+ reference
26
+ })
27
+
28
+ const orderedSerializedProperty = ({ property, value }: LionWebJsonProperty): LionWebJsonProperty => ({
29
+ property: orderedMetaPointer(property),
30
+ value
31
+ })
32
+
33
+ const orderedSerializedContainment = ({ containment, children }: LionWebJsonContainment): LionWebJsonContainment => ({
34
+ containment: orderedMetaPointer(containment),
35
+ children // TODO ensure [] if empty
36
+ })
37
+
38
+ const orderedSerializedReference = ({ reference, targets }: LionWebJsonReference): LionWebJsonReference => ({
39
+ reference: orderedMetaPointer(reference),
40
+ targets: targets.map(orderedSerializedReferenceTarget) // TODO ensure [] if empty
41
+ })
42
+
43
+ const orderedSerializedNode = ({
44
+ id,
45
+ classifier,
46
+ properties,
47
+ containments,
48
+ references,
49
+ annotations,
50
+ parent
51
+ }: LionWebJsonNode): LionWebJsonNode => ({
52
+ id,
53
+ classifier: orderedMetaPointer(classifier),
54
+ properties: properties.map(orderedSerializedProperty),
55
+ containments: containments.map(orderedSerializedContainment),
56
+ references: references.map(orderedSerializedReference),
57
+ annotations, // TODO ensure [] if empty
58
+ parent
59
+ })
60
+
61
+ const orderedSerializationChunk = ({ serializationFormatVersion, languages, nodes }: LionWebJsonChunk): LionWebJsonChunk => ({
62
+ serializationFormatVersion,
63
+ languages: languages.map(orderedSerializedLanguageReference),
64
+ nodes: nodes.map(orderedSerializedNode)
65
+ })
66
+
67
+ export {
68
+ orderedMetaPointer,
69
+ orderedSerializationChunk,
70
+ orderedSerializedLanguageReference,
71
+ orderedSerializedProperty,
72
+ orderedSerializedReferenceTarget
73
+ }
@@ -0,0 +1,33 @@
1
+ import { LionWebJsonChunk } from "@lionweb/json"
2
+ import { sortByStringKey } from "@lionweb/ts-utils"
3
+ import { orderedMetaPointer, orderedSerializedLanguageReference, orderedSerializedProperty, orderedSerializedReferenceTarget } from "./ordering.js"
4
+
5
+
6
+ /**
7
+ * @return A sorted version of a {@link SerializedModel JSON serialization}, which should make it easier to inspect.
8
+ * Note that the sorted version destroy the order of links, which might effectively alter semantics.
9
+ */
10
+ export const sortedSerializationChunk = ({serializationFormatVersion, languages, nodes}: LionWebJsonChunk): LionWebJsonChunk =>
11
+ ({
12
+ serializationFormatVersion,
13
+ languages: sortByStringKey(languages, ({key}) => key).map(orderedSerializedLanguageReference),
14
+ nodes: sortByStringKey(nodes, ({id}) => id)
15
+ .map((node) => ({
16
+ id: node.id,
17
+ classifier: orderedMetaPointer(node.classifier),
18
+ properties: sortByStringKey(node.properties, ({property}) => property.key).map(orderedSerializedProperty),
19
+ containments: sortByStringKey(node.containments, ({containment}) => containment.key)
20
+ .map(({containment, children}) => ({
21
+ containment: orderedMetaPointer(containment),
22
+ children: children.sort()
23
+ })),
24
+ references: sortByStringKey(node.references, ({reference}) => reference.key)
25
+ .map(({reference, targets}) => ({
26
+ reference: orderedMetaPointer(reference),
27
+ targets: sortByStringKey(targets, ({reference}) => reference).map(orderedSerializedReferenceTarget)
28
+ })),
29
+ annotations: node.annotations.sort(),
30
+ parent: node.parent
31
+ }))
32
+ })
33
+
@@ -0,0 +1,93 @@
1
+ import { Enumeration, Language, MemoisingSymbolTable, Property } from "@lionweb/core"
2
+ import {
3
+ LionWebId,
4
+ LionWebJsonChunk,
5
+ LionWebJsonContainment,
6
+ LionWebJsonMetaPointer,
7
+ LionWebJsonNode,
8
+ LionWebJsonProperty,
9
+ LionWebJsonReference,
10
+ LionWebJsonReferenceTarget
11
+ } from "@lionweb/json"
12
+ import { byIdMap } from "@lionweb/ts-utils"
13
+ import { asString, indentWith, Template } from "littoral-templates"
14
+
15
+ const indent = indentWith(" ")(1)
16
+
17
+ const prependWith = (template: Template, prefix: string): Template => prefix + asString(template)
18
+
19
+ export const genericAsTreeText = ({ nodes }: LionWebJsonChunk, languages: Language[] = []) => {
20
+ const nodesById: { [id: LionWebId]: LionWebJsonNode } = byIdMap(nodes)
21
+ const symbolTable = new MemoisingSymbolTable(languages)
22
+
23
+ const nameOrKey = (classifier: LionWebJsonMetaPointer, feature: LionWebJsonMetaPointer): string =>
24
+ symbolTable.featureMatching(classifier, feature)?.name ?? `[${feature.key}]`
25
+
26
+ const propertyAsText = (classifier: LionWebJsonMetaPointer, { property: propertyMetaPointer, value }: LionWebJsonProperty) => {
27
+ const property = symbolTable.featureMatching(classifier, propertyMetaPointer)
28
+ const identification = nameOrKey(classifier, propertyMetaPointer)
29
+ const displayValue =
30
+ property instanceof Property
31
+ ? property.type instanceof Enumeration
32
+ ? (property.type.literals.find(literal => literal.key === value)?.name ?? value)
33
+ : (() => {
34
+ switch (property?.type?.name) {
35
+ case "String":
36
+ return `'${value}'`
37
+ default:
38
+ return value
39
+ }
40
+ })()
41
+ : value
42
+ return `${identification} = ${displayValue}`
43
+ }
44
+
45
+ const referenceTargetAsText = ({ reference: referenceId, resolveInfo }: LionWebJsonReferenceTarget) =>
46
+ `${referenceId}${resolveInfo === undefined ? `` : ` (${resolveInfo})`}`
47
+
48
+ const referenceAsText = (classifier: LionWebJsonMetaPointer, { reference, targets }: LionWebJsonReference) =>
49
+ `${nameOrKey(classifier, reference)} -> ${targets.length === 0 ? `<none>` : targets.map(referenceTargetAsText).join(", ")}`
50
+
51
+ const containmentAsText = (classifier: LionWebJsonMetaPointer, { containment, children }: LionWebJsonContainment) => [
52
+ `${nameOrKey(classifier, containment)}:${children.length === 0 ? ` <none>` : ``}`,
53
+ indent(
54
+ children.map(childId =>
55
+ childId in nodesById ? asText(nodesById[childId]) : `<child with id=${childId} not present in this chunk>`
56
+ )
57
+ )
58
+ ]
59
+
60
+ const annotationAsText = (annotationId: LionWebId) =>
61
+ annotationId in nodesById
62
+ ? prependWith(asText(nodesById[annotationId]), "@ ")
63
+ : `<annotation with id=${annotationId} not present in this chunk>`
64
+
65
+ const curry1 =
66
+ <T1, T2, R>(func: (t1: T1, t2: T2) => R, t1: T1): ((t2: T2) => R) =>
67
+ (t2: T2) =>
68
+ func(t1, t2)
69
+
70
+ const asText = ({
71
+ id,
72
+ classifier: classifierMetaPointer,
73
+ properties,
74
+ containments,
75
+ references,
76
+ annotations
77
+ }: LionWebJsonNode): Template => [
78
+ `${symbolTable.entityMatching(classifierMetaPointer)?.name ?? `[${classifierMetaPointer.key}]`} (id: ${id}) {`,
79
+ indent([
80
+ properties.map(curry1(propertyAsText, classifierMetaPointer)),
81
+ references.map(curry1(referenceAsText, classifierMetaPointer)),
82
+ containments.map(curry1(containmentAsText, classifierMetaPointer)),
83
+ annotations.map(annotationAsText)
84
+ ]),
85
+ `}`
86
+ ]
87
+
88
+ return asString(
89
+ nodes
90
+ .filter(node => node.parent === null) // root nodes
91
+ .map(asText)
92
+ )
93
+ }
@@ -0,0 +1,8 @@
1
+ import { asPrettyJsonString } from "@lionweb/ts-utils"
2
+ import { readFileSync, writeFileSync } from "fs"
3
+
4
+
5
+ export const writeJsonAsFile = (path: string, json: unknown) => writeFileSync(path, asPrettyJsonString(json))
6
+
7
+ export const readFileAsJson = (path: string): unknown => JSON.parse(readFileSync(path).toString())
8
+