@lionweb/core 0.8.0-beta.2 → 0.8.0-beta.4

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.
Files changed (62) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/deserializer.d.ts +43 -6
  3. package/dist/deserializer.d.ts.map +1 -1
  4. package/dist/deserializer.js +142 -129
  5. package/dist/deserializer.js.map +1 -1
  6. package/dist/functions.d.ts +6 -1
  7. package/dist/functions.d.ts.map +1 -1
  8. package/dist/functions.js +11 -0
  9. package/dist/functions.js.map +1 -1
  10. package/dist/index.d.ts +1 -1
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +1 -1
  13. package/dist/index.js.map +1 -1
  14. package/dist/m3/builtins.js +3 -3
  15. package/dist/m3/builtins.js.map +1 -1
  16. package/dist/m3/deserializer.d.ts +7 -3
  17. package/dist/m3/deserializer.d.ts.map +1 -1
  18. package/dist/m3/deserializer.js +14 -6
  19. package/dist/m3/deserializer.js.map +1 -1
  20. package/dist/m3/functions.d.ts +2 -2
  21. package/dist/m3/functions.d.ts.map +1 -1
  22. package/dist/m3/functions.js.map +1 -1
  23. package/dist/m3/reference-checker.js +2 -2
  24. package/dist/m3/reference-checker.js.map +1 -1
  25. package/dist/m3/serializer.d.ts.map +1 -1
  26. package/dist/m3/serializer.js +2 -2
  27. package/dist/m3/serializer.js.map +1 -1
  28. package/dist/m3/types.d.ts.map +1 -1
  29. package/dist/m3/types.js +4 -4
  30. package/dist/m3/types.js.map +1 -1
  31. package/dist/reading.d.ts +5 -4
  32. package/dist/reading.d.ts.map +1 -1
  33. package/dist/references.d.ts +14 -1
  34. package/dist/references.d.ts.map +1 -1
  35. package/dist/references.js +9 -0
  36. package/dist/references.js.map +1 -1
  37. package/dist/reporter.d.ts +49 -0
  38. package/dist/reporter.d.ts.map +1 -0
  39. package/dist/{handler.js → reporter.js} +15 -7
  40. package/dist/reporter.js.map +1 -0
  41. package/dist/serializer.d.ts +29 -7
  42. package/dist/serializer.d.ts.map +1 -1
  43. package/dist/serializer.js +14 -15
  44. package/dist/serializer.js.map +1 -1
  45. package/package.json +3 -3
  46. package/src/deserializer.ts +223 -168
  47. package/src/functions.ts +15 -1
  48. package/src/index.ts +1 -1
  49. package/src/m3/builtins.ts +3 -3
  50. package/src/m3/deserializer.ts +17 -12
  51. package/src/m3/functions.ts +2 -2
  52. package/src/m3/reference-checker.ts +2 -2
  53. package/src/m3/serializer.ts +2 -2
  54. package/src/m3/types.ts +4 -4
  55. package/src/reading.ts +5 -4
  56. package/src/references.ts +20 -1
  57. package/src/reporter.ts +78 -0
  58. package/src/serializer.ts +39 -23
  59. package/dist/handler.d.ts +0 -33
  60. package/dist/handler.d.ts.map +0 -1
  61. package/dist/handler.js.map +0 -1
  62. package/src/handler.ts +0 -57
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lionweb/core",
3
- "version": "0.8.0-beta.2",
3
+ "version": "0.8.0-beta.4",
4
4
  "description": "LionWeb core for {Java|Type}Script",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -27,7 +27,7 @@
27
27
  "release": "npm publish"
28
28
  },
29
29
  "dependencies": {
30
- "@lionweb/json": "0.8.0-beta.2",
31
- "@lionweb/ts-utils": "0.8.0-beta.2"
30
+ "@lionweb/json": "0.8.0-beta.4",
31
+ "@lionweb/ts-utils": "0.8.0-beta.4"
32
32
  }
33
33
  }
@@ -7,12 +7,8 @@ import {
7
7
  } from "@lionweb/json"
8
8
  import { byIdMap, groupBy, keepDefineds } from "@lionweb/ts-utils"
9
9
  import { Writer } from "./writing.js"
10
- import { defaultSimplisticHandler, SimplisticHandler } from "./handler.js"
11
- import {
12
- builtinPropertyValueDeserializer,
13
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
14
- BuiltinPropertyValueDeserializer
15
- } from "./m3/builtins.js"
10
+ import { consoleProblemReporter, ProblemReporter } from "./reporter.js"
11
+ import { builtinPropertyValueDeserializer } from "./m3/builtins.js"
16
12
  import { MemoisingSymbolTable } from "./m3/symbol-table.js"
17
13
  import { Classifier, Containment, Enumeration, Language, PrimitiveType, Property, Reference } from "./m3/types.js"
18
14
  import { unresolved } from "./references.js"
@@ -30,199 +26,258 @@ export interface PropertyValueDeserializer {
30
26
  */
31
27
  export interface PrimitiveTypeDeserializer extends PropertyValueDeserializer {}
32
28
 
29
+
33
30
  /**
34
- * @return a deserialization of a {@link LionWebJsonChunk}
35
- *
36
- * @param serializationChunk - a {@link SerializedModel model} from its LionWeb serialization JSON format
37
- * @param writer - a {@link Writer} that is used to instantiate nodes and set values on them
38
- * @param languages - a {@link Language language} that the serialized model is expected to conform to
39
- * @param dependentNodes - a collection of nodes from dependent models against which all references in the serialized model are supposed to resolve against
40
- * @param propertyValueDeserializer - a deserializer for values of properties (by default a {@link BuiltinPropertyValueDeserializer})
41
- * @param problemHandler - a handler for reporting problems (by default a {@link defaultSimplisticHandler})
31
+ * Type definition for functions that deserialize a given {@link LionWebJsonChunk serialization chunk},
32
+ * being able to link to the given `dependentNodes` (as children/containments or reference targets).
42
33
  */
43
- export const deserializeSerializationChunk = <NT extends Node>(
44
- serializationChunk: LionWebJsonChunk,
34
+ export type Deserializer<NT extends Node> = (serializationChunk: LionWebJsonChunk, dependentNodes?: Node[]) => NT[]
35
+
36
+
37
+ /**
38
+ * Configuration parameters for a deserializer that are unchanging per invocation of the deserializer
39
+ * (and partially optional).
40
+ */
41
+ export type DeserializerConfiguration<NT extends Node> = {
42
+ /**
43
+ * A {@link Writer} that is used to instantiate nodes (with classifiers coming from the `languages` property) and set values on them.
44
+ */
45
45
  writer: Writer<NT>,
46
+ /**
47
+ * An array of {@link Language languages} that the serialization chunk is expected to conform to.
48
+ */
46
49
  languages: Language[],
47
- // TODO facades <--> languages, so it's weird that it looks split up like this
48
- dependentNodes: Node[],
49
- // TODO (#13) see if you can turn this into [nodes: Node[], writer: Writer<Node>][] after all
50
- propertyValueDeserializer: PropertyValueDeserializer = builtinPropertyValueDeserializer,
51
- problemHandler: SimplisticHandler = defaultSimplisticHandler
52
- ): NT[] => {
53
- if (serializationChunk.serializationFormatVersion !== currentSerializationFormatVersion) {
54
- problemHandler.reportProblem(
55
- `can't deserialize from serialization format other than version "${currentSerializationFormatVersion}" - assuming that version`
56
- )
57
- }
50
+ /**
51
+ * A deserializer for values of properties.
52
+ * Default: {@link builtinPropertyValueDeserializer}.
53
+ */
54
+ propertyValueDeserializer?: PropertyValueDeserializer,
55
+ /**
56
+ * An object for reporting problems to.
57
+ * Default: {@link consoleProblemReporter}.
58
+ */
59
+ problemReporter?: ProblemReporter
60
+ }
58
61
 
59
- const symbolTable = new MemoisingSymbolTable(languages)
60
62
 
61
- const { nodes: serializedNodes } = serializationChunk
63
+ /**
64
+ * @return a {@link Deserializer} function.
65
+ *
66
+ * @param configuration - a {@link DeserializerConfiguration} object to configure the deserializer to return with.
67
+ */
68
+ export const deserializerWith = <NT extends Node>(configuration: DeserializerConfiguration<NT>): Deserializer<NT> => {
62
69
 
63
- const serializedNodeById = byIdMap(serializedNodes)
70
+ const symbolTable = new MemoisingSymbolTable(configuration.languages)
71
+ const { writer } = configuration
64
72
 
65
- const deserializedNodeById: { [id: LionWebId]: NT } = {}
73
+ const propertyValueDeserializer = configuration.propertyValueDeserializer ?? builtinPropertyValueDeserializer
74
+ const problemReporter = configuration.problemReporter ?? consoleProblemReporter
66
75
 
67
- /**
68
- * Instantiates a {@link Node} from the given {@link LionWebJsonNode},
69
- * and stores it under its ID so references to it can be resolved.
70
- * For every serialized node, only one instance will ever be constructed (through memoisation).
71
- */
72
- const instantiateMemoised = (serNode: LionWebJsonNode, parent?: NT): NT | null => {
73
- if (serNode.id in deserializedNodeById) {
74
- return deserializedNodeById[serNode.id]
75
- }
76
- const node = instantiate(serNode, parent)
77
- if (node !== null) {
78
- deserializedNodeById[node.id] = node
79
- }
80
- return node
81
- }
76
+ return (serializationChunk, dependentNodes = []) => {
82
77
 
83
- type ReferenceToInstall = [node: NT, feature: Reference, refId: LionWebId]
84
- const referencesToInstall: ReferenceToInstall[] = []
85
-
86
- const tryInstantiate = (
87
- parent: NT | undefined,
88
- classifier: Classifier,
89
- id: LionWebId,
90
- propertySettings: { [propertyKey: LionWebKey]: unknown }
91
- ): NT | null => {
92
- try {
93
- return writer.nodeFor(parent, classifier, id, propertySettings)
94
- } catch (e: unknown) {
95
- problemHandler.reportProblem(
96
- `error occurred during instantiation of a node for classifier ${classifier.name} with meta-pointer (${classifier.language.key}, ${classifier.language.version}, ${classifier.key}); reason:`
78
+ if (serializationChunk.serializationFormatVersion !== currentSerializationFormatVersion) {
79
+ problemReporter.reportProblem(
80
+ `can't deserialize from serialization format other than version "${currentSerializationFormatVersion}" - assuming that version`
97
81
  )
98
- problemHandler.reportProblem((e as Error).toString())
99
- return null
100
82
  }
101
- }
102
83
 
103
- /**
104
- * Instantiates a {@link Node} from its {@link LionWebJsonNode serialization}.
105
- */
106
- const instantiate = (
107
- { id, classifier: classifierMetaPointer, properties, containments, references, annotations }: LionWebJsonNode,
108
- parent?: NT
109
- ): NT | null => {
110
- const classifier = symbolTable.entityMatching(classifierMetaPointer)
111
-
112
- if (classifier === undefined || !(classifier instanceof Classifier)) {
113
- problemHandler.reportProblem(
114
- `can't deserialize node with id=${id}: can't find the classifier with key ${classifierMetaPointer.key} in language (${classifierMetaPointer.language}, ${classifierMetaPointer.version})`
115
- )
116
- return null
117
- }
84
+ const { nodes: serializedNodes } = serializationChunk
85
+ const serializedNodeById = byIdMap(serializedNodes)
86
+ const deserializedNodeById: { [id: LionWebId]: NT } = {}
118
87
 
119
- const allFeatures = symbolTable.allFeaturesOfEntityMatching(classifierMetaPointer)
120
-
121
- const propertySettings: { [propertyKey: LionWebKey]: unknown } = {}
122
-
123
- const serializedPropertiesPerKey = properties === undefined ? {} : groupBy(properties, sp => sp.property.key) // (this assumes no duplicate keys among properties!)
124
- if (properties !== undefined) {
125
- allFeatures
126
- .filter(feature => feature instanceof Property)
127
- .map(feature => feature as Property)
128
- .forEach(property => {
129
- if (property.key in serializedPropertiesPerKey) {
130
- const value = serializedPropertiesPerKey[property.key][0].value
131
- if (property.type instanceof PrimitiveType) {
132
- propertySettings[property.key] =
133
- value === null ? undefined : propertyValueDeserializer.deserializeValue(value, property as Property)
134
- return
135
- }
136
- if (property.type instanceof Enumeration) {
137
- const literal = property.type.literals.find(literal => literal.key === value)
138
- if (literal !== undefined) {
139
- propertySettings[property.key] = writer.encodingOf(literal)
140
- }
141
- return
142
- }
143
- // (property is not handled, because neither a primitive type nor of enumeration type)
144
- }
145
- })
88
+ /**
89
+ * Instantiates a {@link Node} from the given {@link LionWebJsonNode},
90
+ * and stores it under its ID so references to it can be resolved.
91
+ * For every serialized node, only one instance will ever be constructed (through memoisation).
92
+ */
93
+ const instantiateMemoised = (serNode: LionWebJsonNode, parent?: NT): NT | null => {
94
+ if (serNode.id in deserializedNodeById) {
95
+ return deserializedNodeById[serNode.id]
96
+ }
97
+ const node = instantiate(serNode, parent)
98
+ if (node !== null) {
99
+ deserializedNodeById[node.id] = node
100
+ }
101
+ return node
146
102
  }
147
103
 
148
- const node = tryInstantiate(parent, classifier, id, propertySettings)
149
- if (node === null) {
150
- return null
104
+ type ReferenceToInstall = [node: NT, feature: Reference, refId: LionWebId]
105
+ const referencesToInstall: ReferenceToInstall[] = []
106
+
107
+ const tryInstantiate = (
108
+ parent: NT | undefined,
109
+ classifier: Classifier,
110
+ id: LionWebId,
111
+ propertySettings: { [propertyKey: LionWebKey]: unknown }
112
+ ): NT | null => {
113
+ try {
114
+ return writer.nodeFor(parent, classifier, id, propertySettings)
115
+ } catch (e: unknown) {
116
+ problemReporter.reportProblem(
117
+ `error occurred during instantiation of a node for classifier ${classifier.name} with meta-pointer (${classifier.language.key}, ${classifier.language.version}, ${classifier.key}); reason:`
118
+ )
119
+ problemReporter.reportProblem((e as Error).toString())
120
+ return null
121
+ }
151
122
  }
152
123
 
153
- const serializedContainmentsPerKey = containments === undefined ? {} : groupBy(containments, sp => sp.containment.key) // (this assumes no duplicate keys among containments!)
154
- const serializedReferencesPerKey = references === undefined ? {} : groupBy(references, sp => sp.reference.key) // (this assumes no duplicate keys among references!)
155
-
156
- allFeatures.forEach(feature => {
157
- if (feature instanceof Property && properties !== undefined && feature.key in serializedPropertiesPerKey) {
158
- writer.setFeatureValue(node, feature, propertySettings[feature.key])
159
- } else if (feature instanceof Containment && containments !== undefined && feature.key in serializedContainmentsPerKey) {
160
- const childIds = serializedContainmentsPerKey[feature.key].flatMap(serChildren => serChildren.children) as LionWebId[]
161
- if (feature.multiple) {
162
- childIds.forEach(childId => {
163
- if (childId in serializedNodeById) {
164
- writer.setFeatureValue(node, feature, instantiateMemoised(serializedNodeById[childId], node))
124
+ /**
125
+ * Instantiates a {@link Node} from its {@link LionWebJsonNode serialization}.
126
+ */
127
+ const instantiate = (
128
+ {
129
+ id,
130
+ classifier: classifierMetaPointer,
131
+ properties,
132
+ containments,
133
+ references,
134
+ annotations
135
+ }: LionWebJsonNode,
136
+ parent?: NT
137
+ ): NT | null => {
138
+ const classifier = symbolTable.entityMatching(classifierMetaPointer)
139
+
140
+ if (classifier === undefined || !(classifier instanceof Classifier)) {
141
+ problemReporter.reportProblem(
142
+ `can't deserialize node with id=${id}: can't find the classifier with key ${classifierMetaPointer.key} in language (${classifierMetaPointer.language}, ${classifierMetaPointer.version})`
143
+ )
144
+ return null
145
+ }
146
+
147
+ const allFeatures = symbolTable.allFeaturesOfEntityMatching(classifierMetaPointer)
148
+
149
+ const propertySettings: { [propertyKey: LionWebKey]: unknown } = {}
150
+
151
+ const serializedPropertiesPerKey = properties === undefined ? {} : groupBy(properties, sp => sp.property.key) // (this assumes no duplicate keys among properties!)
152
+ if (properties !== undefined) {
153
+ allFeatures
154
+ .filter(feature => feature instanceof Property)
155
+ .map(feature => feature as Property)
156
+ .forEach(property => {
157
+ if (property.key in serializedPropertiesPerKey) {
158
+ const value = serializedPropertiesPerKey[property.key][0].value
159
+ if (property.type instanceof PrimitiveType) {
160
+ propertySettings[property.key] =
161
+ value === null ? undefined : propertyValueDeserializer.deserializeValue(value, property as Property)
162
+ return
163
+ }
164
+ if (property.type instanceof Enumeration) {
165
+ const literal = property.type.literals.find(literal => literal.key === value)
166
+ if (literal !== undefined) {
167
+ propertySettings[property.key] = writer.encodingOf(literal)
168
+ }
169
+ return
170
+ }
171
+ problemReporter.reportProblem(`property ${property.name} on classifier ${classifier.name} is not handled, because its type is neither a primitive type nor an enumeration`)
165
172
  }
166
173
  })
167
- } else {
168
- if (childIds.length > 0) {
169
- // just set the 1st one:
170
- const firstChildId = childIds[0]
171
- if (firstChildId in serializedNodeById) {
172
- writer.setFeatureValue(node, feature, instantiateMemoised(serializedNodeById[firstChildId], node))
174
+ }
175
+
176
+ const node = tryInstantiate(parent, classifier, id, propertySettings)
177
+ if (node === null) {
178
+ return null
179
+ }
180
+
181
+ const serializedContainmentsPerKey = containments === undefined ? {} : groupBy(containments, sp => sp.containment.key) // (this assumes no duplicate keys among containments!)
182
+ const serializedReferencesPerKey = references === undefined ? {} : groupBy(references, sp => sp.reference.key) // (this assumes no duplicate keys among references!)
183
+
184
+ allFeatures.forEach(feature => {
185
+ if (feature instanceof Property && properties !== undefined && feature.key in serializedPropertiesPerKey) {
186
+ writer.setFeatureValue(node, feature, propertySettings[feature.key])
187
+ } else if (feature instanceof Containment && containments !== undefined && feature.key in serializedContainmentsPerKey) {
188
+ const childIds = serializedContainmentsPerKey[feature.key].flatMap(serChildren => serChildren.children) as LionWebId[]
189
+ if (feature.multiple) {
190
+ childIds.forEach(childId => {
191
+ if (childId in serializedNodeById) {
192
+ writer.setFeatureValue(node, feature, instantiateMemoised(serializedNodeById[childId], node))
193
+ }
194
+ })
195
+ } else {
196
+ if (childIds.length > 0) {
197
+ // just set the 1st one:
198
+ const firstChildId = childIds[0]
199
+ if (firstChildId in serializedNodeById) {
200
+ writer.setFeatureValue(node, feature, instantiateMemoised(serializedNodeById[firstChildId], node))
201
+ }
173
202
  }
174
203
  }
175
- }
176
- } else if (feature instanceof Reference && references !== undefined && feature.key in serializedReferencesPerKey) {
177
- const serRefs = (serializedReferencesPerKey[feature.key] ?? []).flatMap(serReferences =>
178
- serReferences.targets.map(t => t.reference)
179
- )
180
- referencesToInstall.push(
181
- ...(serRefs.filter(serRef => typeof serRef === "string") as LionWebId[]).map(
182
- refId => [node, feature, refId] as ReferenceToInstall
204
+ } else if (feature instanceof Reference && references !== undefined && feature.key in serializedReferencesPerKey) {
205
+ const serRefs = (serializedReferencesPerKey[feature.key] ?? []).flatMap(serReferences =>
206
+ serReferences.targets.map(t => t.reference)
183
207
  )
184
- )
185
- }
186
- })
208
+ referencesToInstall.push(
209
+ ...(serRefs.filter(serRef => typeof serRef === "string") as LionWebId[]).map(
210
+ refId => [node, feature, refId] as ReferenceToInstall
211
+ )
212
+ )
213
+ }
214
+ })
187
215
 
188
- node.annotations = keepDefineds(
189
- annotations
190
- .filter(annotationId => annotationId in serializedNodeById)
191
- .map(annotationId => instantiateMemoised(serializedNodeById[annotationId]))
216
+ node.annotations = keepDefineds(
217
+ annotations
218
+ .filter(annotationId => annotationId in serializedNodeById)
219
+ .map(annotationId => instantiateMemoised(serializedNodeById[annotationId]))
220
+ )
221
+ .map(annotation => annotation!)
222
+
223
+ return node
224
+ }
225
+
226
+ const rootLikeNodes = keepDefineds(
227
+ serializedNodes
228
+ .filter(({ parent }) => parent === null || !(parent in serializedNodeById))
229
+ .map(serializedNode => instantiateMemoised(serializedNode))
192
230
  )
193
- .map(annotation => annotation!)
231
+ .map(node => node!)
194
232
 
195
- return node
196
- }
233
+ const dependentNodesById = byIdMap(dependentNodes)
197
234
 
198
- const rootLikeNodes = keepDefineds(
199
- serializedNodes
200
- .filter(({ parent }) => parent === null || !(parent in serializedNodeById))
201
- .map(serializedNode => instantiateMemoised(serializedNode))
202
- )
203
- .map(node => node!)
204
-
205
- const dependentNodesById = byIdMap(dependentNodes)
206
-
207
- referencesToInstall.forEach(([node, reference, refId]) => {
208
- const target = deserializedNodeById[refId] ?? dependentNodesById[refId]
209
- const value = (() => {
210
- if (target === undefined) {
211
- const metaTypeMessage = "concept" in node ? ` and (meta-)type ${node.concept}` : ""
212
- problemHandler.reportProblem(
213
- `couldn't resolve the target with id=${refId} of a "${reference.name}" reference on the node with id=${node.id}${metaTypeMessage}`
214
- )
215
- return unresolved
216
- }
217
- return target
218
- })()
219
- writer.setFeatureValue(node, reference, value)
220
- })
235
+ referencesToInstall.forEach(([node, reference, refId]) => {
236
+ const target = deserializedNodeById[refId] ?? dependentNodesById[refId]
237
+ const value = (() => {
238
+ if (target === undefined) {
239
+ const metaTypeMessage = "concept" in node ? ` and (meta-)type ${node.concept}` : ""
240
+ problemReporter.reportProblem(
241
+ `couldn't resolve the target with id=${refId} of a "${reference.name}" reference on the node with id=${node.id}${metaTypeMessage}`
242
+ )
243
+ return unresolved
244
+ }
245
+ return target
246
+ })()
247
+ writer.setFeatureValue(node, reference, value)
248
+ })
249
+
250
+ return rootLikeNodes
251
+ }
221
252
 
222
- return rootLikeNodes
223
253
  }
224
254
 
255
+
256
+ /**
257
+ * @return a deserialization of a {@link LionWebJsonChunk}.
258
+ *
259
+ * @param serializationChunk - a {@link SerializedModel model} from its LionWeb serialization JSON format
260
+ * @param writer - a {@link Writer} that is used to instantiate nodes and set values on them
261
+ * @param languages - {@link Language languages} that the serialized model is expected to conform to
262
+ * @param dependentNodes - a collection of nodes from dependent models against which all references in the serialized model are supposed to resolve against
263
+ * @param propertyValueDeserializer - a deserializer for values of properties (by default a {@link BuiltinPropertyValueDeserializer})
264
+ * @param problemReporter - an object for reporting problems (by default a {@link consoleProblemReporter})
265
+ *
266
+ * This is a legacy variant of {@link deserializerWith}, kept for backward compatibility, and to be deprecated and removed later.
267
+ */
268
+ export const deserializeSerializationChunk = <NT extends Node>(
269
+ serializationChunk: LionWebJsonChunk,
270
+ writer: Writer<NT>,
271
+ languages: Language[],
272
+ // TODO facades <--> languages, so it's weird that it looks split up like this
273
+ dependentNodes: Node[],
274
+ // TODO (#13) see if you can turn this into [nodes: Node[], writer: Writer<Node>][] after all
275
+ propertyValueDeserializer: PropertyValueDeserializer = builtinPropertyValueDeserializer,
276
+ problemReporter: ProblemReporter = consoleProblemReporter
277
+ ): NT[] => deserializerWith({ writer, languages, propertyValueDeserializer, problemReporter: problemReporter })(serializationChunk, dependentNodes)
278
+
225
279
  /**
226
280
  * Alias for {@link deserializeSerializationChunk}.
227
281
  */
228
282
  export const deserializeChunk = deserializeSerializationChunk
283
+
package/src/functions.ts CHANGED
@@ -1,6 +1,7 @@
1
- import { LionWebId } from "@lionweb/json"
1
+ import { LionWebId, LionWebJsonMetaPointer } from "@lionweb/json"
2
2
  import { flatMapNonCyclingFollowing, trivialFlatMapper } from "@lionweb/ts-utils"
3
3
  import { Node } from "./types.js"
4
+ import { Feature } from "./m3/index.js"
4
5
 
5
6
 
6
7
  /**
@@ -26,3 +27,16 @@ export const asIds = (nodeOrNulls: (Node | null)[]): (LionWebId | null)[] =>
26
27
  export const idOf = <T extends Node>({id}: T): LionWebId =>
27
28
  id
28
29
 
30
+
31
+ /**
32
+ * @return the {@link LionWebJsonMetaPointer} for the given {@link Feature}.
33
+ */
34
+ export const metaPointerFor = (feature: Feature): LionWebJsonMetaPointer => {
35
+ const { language } = feature.classifier
36
+ return {
37
+ language: language.key,
38
+ version: language.version,
39
+ key: feature.key
40
+ }
41
+ }
42
+
package/src/index.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  export * from "./deserializer.js"
2
2
  export * from "./dynamic-facade.js"
3
3
  export * from "./extraction.js"
4
- export * from "./handler.js"
5
4
  export * from "./functions.js"
6
5
  export * from "./reading.js"
7
6
  export * from "./references.js"
7
+ export * from "./reporter.js"
8
8
  export * from "./serializer.js"
9
9
  export * from "./types.js"
10
10
  export * from "./version.js"
@@ -4,7 +4,7 @@ import { PropertyValueSerializer } from "../serializer.js"
4
4
  import { currentReleaseVersion } from "../version.js"
5
5
  import { LanguageFactory } from "./factory.js"
6
6
  import { Classifier, Concept, DataType, lioncoreBuiltinsKey, Property } from "./types.js"
7
- import { unresolved } from "../references.js"
7
+ import { isUnresolvedReference } from "../references.js"
8
8
 
9
9
  const lioncoreBuiltinsIdAndKeyGenerator: StringsMapper = (...names) => [lioncoreBuiltinsKey, ...names.slice(1)].join("-")
10
10
 
@@ -129,7 +129,7 @@ export class BuiltinPropertyValueDeserializer
129
129
  throw new Error(`can't deserialize undefined as the value of required property "${property.name}" (on classifier "${property.classifier.name}" in language "${property.classifier.language.name}")`)
130
130
  }
131
131
  const { type } = property
132
- if (type === unresolved) {
132
+ if (isUnresolvedReference(type)) {
133
133
  throw new Error(`can't deserialize property "${property.name}" (on classifier "${property.classifier.name}" in language "${property.classifier.language.name}") with unspecified type`)
134
134
  }
135
135
  const specificDeserializer = this.byType(type)
@@ -172,7 +172,7 @@ export class BuiltinPropertyValueSerializer extends DataTypeRegister<(value: unk
172
172
  throw new Error(`can't serialize undefined as the value of required property "${property.name}" (on classifier "${property.classifier.name}" in language "${property.classifier.language.name}")`)
173
173
  }
174
174
  const { type } = property
175
- if (type === unresolved) {
175
+ if (isUnresolvedReference(type)) {
176
176
  throw new Error(`can't serialize property "${property.name}" (on classifier "${property.classifier.name}" in language "${property.classifier.language.name}") with unspecified type`)
177
177
  }
178
178
  const specificSerializer = this.byType(type)
@@ -1,8 +1,8 @@
1
1
  import { LionWebJsonChunk } from "@lionweb/json"
2
- import { deserializeSerializationChunk } from "../deserializer.js"
2
+ import { deserializerWith } from "../deserializer.js"
3
3
  import { nodesExtractorUsing } from "../extraction.js"
4
- import { defaultSimplisticHandler, SimplisticHandler } from "../handler.js"
5
- import { builtinPropertyValueDeserializer, lioncoreBuiltins } from "./builtins.js"
4
+ import { consoleProblemReporter, ProblemReporter } from "../reporter.js"
5
+ import { lioncoreBuiltins } from "./builtins.js"
6
6
  import { lioncoreReader, lioncoreWriter } from "./facade.js"
7
7
  import { lioncore } from "./lioncore.js"
8
8
  import { Language } from "./types.js"
@@ -13,26 +13,31 @@ import { Language } from "./types.js"
13
13
  * as an instance of the LionCore metametamodel, using {@link _M3Concept these type definitions}.
14
14
  */
15
15
  export const deserializeLanguages = (serializationChunk: LionWebJsonChunk, ...dependentLanguages: Language[]): Language[] =>
16
- deserializeLanguagesWithHandler(serializationChunk, defaultSimplisticHandler, ...dependentLanguages)
16
+ deserializeLanguagesWithReporter(serializationChunk, consoleProblemReporter, ...dependentLanguages)
17
17
 
18
18
  /**
19
19
  * Deserializes languages that have been serialized into the LionWeb serialization JSON format
20
20
  * as an instance of the LionCore metametamodel, using {@link _M3Concept these type definitions}.
21
- * This function takes a handler to be able to see what problems occurred.
21
+ * This function takes a {@link ProblemReporter} to be able to see what problems occurred.
22
22
  */
23
- export const deserializeLanguagesWithHandler = (
23
+ export const deserializeLanguagesWithReporter = (
24
24
  serializationChunk: LionWebJsonChunk,
25
- handler: SimplisticHandler,
25
+ problemReporter: ProblemReporter,
26
26
  ...dependentLanguages: Language[]
27
27
  ): Language[] =>
28
- deserializeSerializationChunk(
28
+ deserializerWith({
29
+ writer: lioncoreWriter,
30
+ languages: [lioncore, ...dependentLanguages],
31
+ problemReporter: problemReporter
32
+ })(
29
33
  serializationChunk,
30
- lioncoreWriter,
31
- [lioncore, ...dependentLanguages],
32
34
  [lioncoreBuiltins, ...dependentLanguages].flatMap(nodesExtractorUsing(lioncoreReader)),
33
- builtinPropertyValueDeserializer,
34
- handler
35
35
  )
36
36
  .filter((rootNode) => rootNode instanceof Language)
37
37
  .map((language) => (language as Language).dependingOn(...dependentLanguages))
38
38
 
39
+ /**
40
+ * Legacy alias for {@link deserializeLanguagesWithReporter}, kept for backward compatibility, and to be deprecated and removed later.
41
+ */
42
+ export const deserializeLanguagesWithHandler = deserializeLanguagesWithReporter
43
+
@@ -7,7 +7,7 @@ import { LionWebId, LionWebKey } from "@lionweb/json"
7
7
  import { cycleWith, flatMapNonCyclingFollowing, sortByStringKey } from "@lionweb/ts-utils"
8
8
  import { containmentChain } from "../functions.js"
9
9
  import { ClassifierDeducer } from "../reading.js"
10
- import { isRef, unresolved } from "../references.js"
10
+ import { isRef, UnresolvedReference } from "../references.js"
11
11
  import { Node } from "../types.js"
12
12
  import {
13
13
  Annotation,
@@ -34,7 +34,7 @@ import {
34
34
  /**
35
35
  * @return The type of the given {@link Feature}
36
36
  */
37
- const type = (feature: Feature): Classifier | DataType | typeof unresolved =>
37
+ const type = (feature: Feature): Classifier | DataType | UnresolvedReference =>
38
38
  (feature as (Link | Property)).type
39
39
 
40
40
 
@@ -1,4 +1,4 @@
1
- import { SingleRef, unresolved } from "../references.js"
1
+ import { isUnresolvedReference, SingleRef } from "../references.js"
2
2
  import { flatMap, qualifiedNameOf } from "./functions.js"
3
3
  import { Concept, Containment, Language, Property, Reference } from "./types.js"
4
4
  import { Node } from "../types.js"
@@ -14,7 +14,7 @@ export const checkReferences = (language: Language): string[] =>
14
14
 
15
15
  const locations: string[] = []
16
16
  const check = (location: string, ref?: SingleRef<Node>) => {
17
- if (ref === unresolved) {
17
+ if (isUnresolvedReference(ref)) {
18
18
  locations.push(location)
19
19
  }
20
20
  }
@@ -1,5 +1,5 @@
1
1
  import { LionWebJsonChunk } from "@lionweb/json"
2
- import { nodeSerializer } from "../serializer.js"
2
+ import { serializerWith } from "../serializer.js"
3
3
  import { lioncoreReader } from "./facade.js"
4
4
  import { Language } from "./types.js"
5
5
 
@@ -9,5 +9,5 @@ import { Language } from "./types.js"
9
9
  * into the LionWeb serialization JSON format.
10
10
  */
11
11
  export const serializeLanguages = (...languages: Language[]): LionWebJsonChunk =>
12
- nodeSerializer(lioncoreReader)(languages)
12
+ serializerWith({ reader: lioncoreReader })(languages)
13
13