@lionweb/delta-protocol-common 0.7.0-beta.21

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 (93) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +33 -0
  3. package/dist/index.d.ts +5 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +21 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/logging/ansi.d.ts +44 -0
  8. package/dist/logging/ansi.d.ts.map +1 -0
  9. package/dist/logging/ansi.js +53 -0
  10. package/dist/logging/ansi.js.map +1 -0
  11. package/dist/logging/index.d.ts +4 -0
  12. package/dist/logging/index.d.ts.map +1 -0
  13. package/dist/logging/index.js +20 -0
  14. package/dist/logging/index.js.map +1 -0
  15. package/dist/logging/semantic-logging.d.ts +55 -0
  16. package/dist/logging/semantic-logging.d.ts.map +1 -0
  17. package/dist/logging/semantic-logging.js +88 -0
  18. package/dist/logging/semantic-logging.js.map +1 -0
  19. package/dist/logging/textual-logging.d.ts +22 -0
  20. package/dist/logging/textual-logging.d.ts.map +1 -0
  21. package/dist/logging/textual-logging.js +54 -0
  22. package/dist/logging/textual-logging.js.map +1 -0
  23. package/dist/payload/command-types.d.ts +319 -0
  24. package/dist/payload/command-types.d.ts.map +1 -0
  25. package/dist/payload/command-types.js +18 -0
  26. package/dist/payload/command-types.js.map +1 -0
  27. package/dist/payload/common.d.ts +13 -0
  28. package/dist/payload/common.d.ts.map +1 -0
  29. package/dist/payload/common.js +18 -0
  30. package/dist/payload/common.js.map +1 -0
  31. package/dist/payload/event-types.d.ts +378 -0
  32. package/dist/payload/event-types.d.ts.map +1 -0
  33. package/dist/payload/event-types.js +68 -0
  34. package/dist/payload/event-types.js.map +1 -0
  35. package/dist/payload/index.d.ts +5 -0
  36. package/dist/payload/index.d.ts.map +1 -0
  37. package/dist/payload/index.js +20 -0
  38. package/dist/payload/index.js.map +1 -0
  39. package/dist/payload/query-types.d.ts +73 -0
  40. package/dist/payload/query-types.d.ts.map +1 -0
  41. package/dist/payload/query-types.js +30 -0
  42. package/dist/payload/query-types.js.map +1 -0
  43. package/dist/translators/delta-to-command.d.ts +7 -0
  44. package/dist/translators/delta-to-command.d.ts.map +1 -0
  45. package/dist/translators/delta-to-command.js +297 -0
  46. package/dist/translators/delta-to-command.js.map +1 -0
  47. package/dist/translators/delta-to-event.d.ts +2 -0
  48. package/dist/translators/delta-to-event.d.ts.map +1 -0
  49. package/dist/translators/delta-to-event.js +19 -0
  50. package/dist/translators/delta-to-event.js.map +1 -0
  51. package/dist/translators/event-to-delta.d.ts +13 -0
  52. package/dist/translators/event-to-delta.d.ts.map +1 -0
  53. package/dist/translators/event-to-delta.js +293 -0
  54. package/dist/translators/event-to-delta.js.map +1 -0
  55. package/dist/translators/index.d.ts +4 -0
  56. package/dist/translators/index.d.ts.map +1 -0
  57. package/dist/translators/index.js +19 -0
  58. package/dist/translators/index.js.map +1 -0
  59. package/dist/utils/async.d.ts +13 -0
  60. package/dist/utils/async.d.ts.map +1 -0
  61. package/dist/utils/async.js +38 -0
  62. package/dist/utils/async.js.map +1 -0
  63. package/dist/utils/index.d.ts +5 -0
  64. package/dist/utils/index.d.ts.map +1 -0
  65. package/dist/utils/index.js +20 -0
  66. package/dist/utils/index.js.map +1 -0
  67. package/dist/utils/json.d.ts +7 -0
  68. package/dist/utils/json.d.ts.map +1 -0
  69. package/dist/utils/json.js +30 -0
  70. package/dist/utils/json.js.map +1 -0
  71. package/dist/utils/procedure.d.ts +14 -0
  72. package/dist/utils/procedure.d.ts.map +1 -0
  73. package/dist/utils/procedure.js +32 -0
  74. package/dist/utils/procedure.js.map +1 -0
  75. package/package.json +35 -0
  76. package/src/index.ts +22 -0
  77. package/src/logging/ansi.ts +63 -0
  78. package/src/logging/index.ts +21 -0
  79. package/src/logging/semantic-logging.ts +96 -0
  80. package/src/logging/textual-logging.ts +65 -0
  81. package/src/payload/command-types.ts +378 -0
  82. package/src/payload/common.ts +33 -0
  83. package/src/payload/event-types.ts +499 -0
  84. package/src/payload/index.ts +22 -0
  85. package/src/payload/query-types.ts +134 -0
  86. package/src/translators/delta-to-command.ts +378 -0
  87. package/src/translators/delta-to-event.ts +19 -0
  88. package/src/translators/event-to-delta.ts +384 -0
  89. package/src/translators/index.ts +21 -0
  90. package/src/utils/async.ts +50 -0
  91. package/src/utils/index.ts +22 -0
  92. package/src/utils/json.ts +32 -0
  93. package/src/utils/procedure.ts +43 -0
@@ -0,0 +1,384 @@
1
+ // Copyright 2025 TRUMPF Laser SE and other contributors
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License")
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ //
15
+ // SPDX-FileCopyrightText: 2025 TRUMPF Laser SE and other contributors
16
+ // SPDX-License-Identifier: Apache-2.0
17
+
18
+ import {
19
+ AnnotationAddedDelta,
20
+ AnnotationDeletedDelta,
21
+ AnnotationMovedAndReplacedFromOtherParentDelta,
22
+ AnnotationMovedAndReplacedInSameParentDelta,
23
+ AnnotationMovedFromOtherParentDelta,
24
+ AnnotationMovedInSameParentDelta,
25
+ AnnotationReplacedDelta,
26
+ ChildAddedDelta,
27
+ ChildDeletedDelta,
28
+ ChildMovedAndReplacedFromOtherContainmentDelta,
29
+ ChildMovedAndReplacedFromOtherContainmentInSameParentDelta,
30
+ ChildMovedAndReplacedInSameContainmentDelta,
31
+ ChildMovedFromOtherContainmentDelta,
32
+ ChildMovedFromOtherContainmentInSameParentDelta,
33
+ ChildMovedInSameContainmentDelta,
34
+ ChildReplacedDelta,
35
+ CompositeDelta,
36
+ Deserializer,
37
+ EntryMovedAndReplacedFromOtherReferenceDelta,
38
+ EntryMovedAndReplacedFromOtherReferenceInSameParentDelta,
39
+ EntryMovedAndReplacedInSameReferenceDelta,
40
+ EntryMovedFromOtherReferenceDelta,
41
+ EntryMovedFromOtherReferenceInSameParentDelta,
42
+ EntryMovedInSameReferenceDelta,
43
+ IDelta,
44
+ IdMapping,
45
+ ILanguageBase,
46
+ INodeBase,
47
+ NoOpDelta,
48
+ PartitionAddedDelta,
49
+ PartitionDeletedDelta,
50
+ PropertyAddedDelta,
51
+ PropertyChangedDelta,
52
+ PropertyDeletedDelta,
53
+ ReferenceAddedDelta,
54
+ ReferenceChangedDelta,
55
+ ReferenceDeletedDelta
56
+ } from "@lionweb/class-core"
57
+ import { featureResolversFor, unresolved } from "@lionweb/core"
58
+ import { LionWebId, LionWebJsonChunk } from "@lionweb/json"
59
+ import {
60
+ AnnotationAddedEvent,
61
+ AnnotationDeletedEvent,
62
+ AnnotationMovedAndReplacedFromOtherParentEvent,
63
+ AnnotationMovedAndReplacedInSameParentEvent,
64
+ AnnotationMovedFromOtherParentEvent,
65
+ AnnotationMovedInSameParentEvent,
66
+ AnnotationReplacedEvent,
67
+ ChildAddedEvent,
68
+ ChildDeletedEvent,
69
+ ChildMovedAndReplacedFromOtherContainmentEvent,
70
+ ChildMovedAndReplacedFromOtherContainmentInSameParentEvent,
71
+ ChildMovedAndReplacedInSameContainmentEvent,
72
+ ChildMovedFromOtherContainmentEvent,
73
+ ChildMovedFromOtherContainmentInSameParentEvent,
74
+ ChildMovedInSameContainmentEvent,
75
+ ChildReplacedEvent,
76
+ CompositeEvent,
77
+ EntryMovedAndReplacedFromOtherReferenceEvent,
78
+ EntryMovedAndReplacedFromOtherReferenceInSameParentEvent,
79
+ EntryMovedAndReplacedInSameReferenceEvent,
80
+ EntryMovedFromOtherReferenceEvent,
81
+ EntryMovedFromOtherReferenceInSameParentEvent,
82
+ EntryMovedInSameReferenceEvent,
83
+ Event,
84
+ PartitionAddedEvent,
85
+ PartitionDeletedEvent,
86
+ PropertyAddedEvent,
87
+ PropertyChangedEvent,
88
+ PropertyDeletedEvent,
89
+ ReferenceAddedEvent,
90
+ ReferenceChangedEvent,
91
+ ReferenceDeletedEvent
92
+ } from "../payload/event-types.js"
93
+
94
+ /**
95
+ * Type def. for a function that translates {@link Event events} to their corresponding {@link IDelta deltas},
96
+ * or {@code undefined} in case no equivalent delta exists for a given event.
97
+ */
98
+ export type EventToDeltaTranslator = (event: Event, idMapping: IdMapping) => IDelta | undefined
99
+
100
+ /**
101
+ * @return a {@link EventToDeltaTranslator} for the languages given as {@link ILanguageBase language bases},
102
+ * with the given {@link IdMapping `idMapping`} and {@link Deserializer `deserialized` deserializer function}.
103
+ */
104
+ export const eventToDeltaTranslator = (languageBases: ILanguageBase[], deserialized: Deserializer<INodeBase[]>): EventToDeltaTranslator => {
105
+
106
+ const eventAsDelta = (event: Event, idMapping: IdMapping): IDelta | undefined => {
107
+
108
+ const deserializedNodeFrom = (chunk: LionWebJsonChunk): INodeBase => {
109
+ const nodes = deserialized(chunk, undefined, idMapping) // (deserializer should take care of installing delta receiver)
110
+ if (nodes.length !== 1) {
111
+ throw new Error(`expected exactly 1 root node in deserialization of chunk in event, but got ${nodes.length}`)
112
+ }
113
+ return nodes[0]
114
+ }
115
+ const { resolvedPropertyFrom, resolvedContainmentFrom, resolvedReferenceFrom } = featureResolversFor(languageBases.map(({language}) => language));
116
+ const resolvedRefTo = (ref: LionWebId | null) =>
117
+ ref === null ? unresolved : idMapping.fromId(ref)
118
+
119
+ switch (event.messageKind) {
120
+
121
+ // in order of the specification (§ 6.6):
122
+
123
+ case "PartitionAdded": { // § 6.6.1.1
124
+ const { newPartition } = event as PartitionAddedEvent
125
+ return new PartitionAddedDelta(deserializedNodeFrom(newPartition))
126
+ }
127
+ case "PartitionDeleted": { // § 6.6.1.2
128
+ const { deletedPartition } = event as PartitionDeletedEvent
129
+ return new PartitionDeletedDelta(idMapping.fromId(deletedPartition))
130
+ }
131
+ case "ClassifierChanged": { // § 6.6.2.1
132
+ return undefined
133
+ }
134
+ case "PropertyAdded": { // § 6.6.3.1
135
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
136
+ const { node, property, newValue } = event as PropertyAddedEvent<any>
137
+ const resolvedNode = idMapping.fromId(node)
138
+ const resolvedProperty = resolvedPropertyFrom(property, resolvedNode.classifier)
139
+ return new PropertyAddedDelta(resolvedNode, resolvedProperty, newValue)
140
+ }
141
+ case "PropertyDeleted": { // § 6.6.3.2
142
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
143
+ const { node, property, oldValue } = event as PropertyDeletedEvent<any>
144
+ const resolvedNode = idMapping.fromId(node)
145
+ const resolvedProperty = resolvedPropertyFrom(property, resolvedNode.classifier)
146
+ return new PropertyDeletedDelta(resolvedNode, resolvedProperty, oldValue)
147
+ }
148
+ case "PropertyChanged": { // § 6.6.3.3
149
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
150
+ const { node, property, newValue, oldValue } = event as PropertyChangedEvent<any>
151
+ const resolvedNode = idMapping.fromId(node)
152
+ const resolvedProperty = resolvedPropertyFrom(property, resolvedNode.classifier)
153
+ return new PropertyChangedDelta(resolvedNode, resolvedProperty, oldValue, newValue)
154
+ }
155
+ case "ChildAdded": { // § 6.6.4.1
156
+ const { parent, newChild, containment, index } = event as ChildAddedEvent
157
+ const resolvedNode = idMapping.fromId(parent)
158
+ const resolvedContainment = resolvedContainmentFrom(containment, resolvedNode.classifier)
159
+ return new ChildAddedDelta(resolvedNode, resolvedContainment, index, deserializedNodeFrom(newChild))
160
+ }
161
+ case "ChildDeleted": { // § 6.6.4.2
162
+ const { parent, deletedChild, containment, index } = event as ChildDeletedEvent
163
+ const resolvedNode = idMapping.fromId(parent)
164
+ const resolvedContainment = resolvedContainmentFrom(containment, resolvedNode.classifier)
165
+ const resolvedDeletedChild = idMapping.fromId(deletedChild)
166
+ return new ChildDeletedDelta(resolvedNode, resolvedContainment, index, resolvedDeletedChild)
167
+ }
168
+ case "ChildReplaced": { // § 6.6.4.3
169
+ const { newChild, replacedChild, parent, containment, index } = event as ChildReplacedEvent
170
+ const resolvedParent = idMapping.fromId(parent)
171
+ const resolvedContainment = resolvedContainmentFrom(containment, resolvedParent.classifier)
172
+ const resolvedReplacedChild = idMapping.fromId(replacedChild)
173
+ return new ChildReplacedDelta(resolvedParent, resolvedContainment, index, resolvedReplacedChild, deserializedNodeFrom(newChild))
174
+ }
175
+ case "ChildMovedFromOtherContainment": { // § 6.6.4.4
176
+ const { newParent, newContainment, newIndex, movedChild, oldParent, oldContainment, oldIndex } = event as ChildMovedFromOtherContainmentEvent
177
+ const resolvedOldParent = idMapping.fromId(oldParent)
178
+ const resolvedOldContainment = resolvedContainmentFrom(oldContainment, resolvedOldParent.classifier)
179
+ const resolvedNewParent = idMapping.fromId(newParent)
180
+ const resolvedNewContainment = resolvedContainmentFrom(newContainment, resolvedOldParent.classifier)
181
+ const resolvedMovedChild = idMapping.fromId(movedChild)
182
+ return new ChildMovedFromOtherContainmentDelta(resolvedOldParent, resolvedOldContainment, oldIndex, resolvedNewParent, resolvedNewContainment, newIndex, resolvedMovedChild)
183
+ }
184
+ case "ChildMovedFromOtherContainmentInSameParent": { // § 6.6.4.5
185
+ const { parent, oldContainment, oldIndex, newContainment, newIndex, movedChild } = event as ChildMovedFromOtherContainmentInSameParentEvent
186
+ const resolvedParent = idMapping.fromId(parent)
187
+ const resolvedOldContainment = resolvedContainmentFrom(oldContainment, resolvedParent.classifier)
188
+ const resolvedNewContainment = resolvedContainmentFrom(newContainment, resolvedParent.classifier)
189
+ const resolvedMovedChild = idMapping.fromId(movedChild)
190
+ return new ChildMovedFromOtherContainmentInSameParentDelta(resolvedParent, resolvedOldContainment, oldIndex, resolvedMovedChild, resolvedNewContainment, newIndex)
191
+ }
192
+ case "ChildMovedInSameContainment": { // § 6.6.4.6
193
+ const { parent, containment, oldIndex, newIndex, movedChild } = event as ChildMovedInSameContainmentEvent
194
+ const resolvedParent = idMapping.fromId(parent)
195
+ const resolvedContainment = resolvedContainmentFrom(containment, resolvedParent.classifier)
196
+ const resolvedMovedChild = idMapping.fromId(movedChild)
197
+ return new ChildMovedInSameContainmentDelta(resolvedParent, resolvedContainment, oldIndex, newIndex, resolvedMovedChild)
198
+ }
199
+ case "ChildMovedAndReplacedFromOtherContainment": { // § 6.6.4.7
200
+ const { newParent, newContainment, newIndex, movedChild, oldParent, oldContainment, oldIndex, replacedChild } = event as ChildMovedAndReplacedFromOtherContainmentEvent
201
+ const resolvedNewParent = idMapping.fromId(newParent)
202
+ const resolvedNewContainment = resolvedContainmentFrom(newContainment, resolvedNewParent.classifier)
203
+ const resolvedMovedChild = idMapping.fromId(movedChild)
204
+ const resolvedOldParent = idMapping.fromId(oldParent)
205
+ const resolvedOldContainment = resolvedContainmentFrom(oldContainment, resolvedOldParent.classifier)
206
+ const resolvedReplacedChild = idMapping.fromId(replacedChild)
207
+ return new ChildMovedAndReplacedFromOtherContainmentDelta(resolvedNewParent, resolvedNewContainment, newIndex, resolvedMovedChild, resolvedOldParent, resolvedOldContainment, oldIndex, resolvedReplacedChild)
208
+ }
209
+ case "ChildMovedAndReplacedFromOtherContainmentInSameParent": { // § 6.6.4.8
210
+ const { parent, oldContainment, oldIndex, newContainment, newIndex, movedChild, replacedChild } = event as ChildMovedAndReplacedFromOtherContainmentInSameParentEvent
211
+ const resolvedParent = idMapping.fromId(parent)
212
+ const resolvedOldContainment = resolvedContainmentFrom(oldContainment, resolvedParent.classifier)
213
+ const resolvedNewContainment = resolvedContainmentFrom(newContainment, resolvedParent.classifier)
214
+ const resolvedMovedChild = idMapping.fromId(movedChild)
215
+ const resolvedReplacedChild = idMapping.fromId(replacedChild)
216
+ return new ChildMovedAndReplacedFromOtherContainmentInSameParentDelta(resolvedParent, resolvedOldContainment, oldIndex, resolvedNewContainment, newIndex, resolvedMovedChild, resolvedReplacedChild)
217
+ }
218
+ case "ChildMovedAndReplacedInSameContainment": { // § 6.6.4.9
219
+ const { parent, containment, oldIndex, newIndex, movedChild, replacedChild } = event as ChildMovedAndReplacedInSameContainmentEvent
220
+ const resolvedParent = idMapping.fromId(parent)
221
+ const resolvedContainment = resolvedContainmentFrom(containment, resolvedParent.classifier)
222
+ const resolvedMovedChild = idMapping.fromId(movedChild)
223
+ const resolvedReplacedChild = idMapping.fromId(replacedChild)
224
+ return new ChildMovedAndReplacedInSameContainmentDelta(resolvedParent, resolvedContainment, oldIndex, newIndex, resolvedMovedChild, resolvedReplacedChild)
225
+ }
226
+ case "AnnotationAdded": { // § 6.6.5.1
227
+ const { parent, index, newAnnotation } = event as AnnotationAddedEvent
228
+ const resolvedParent = idMapping.fromId(parent)
229
+ return new AnnotationAddedDelta(resolvedParent, index, deserializedNodeFrom(newAnnotation))
230
+ }
231
+ case "AnnotationDeleted": { // § 6.6.5.2
232
+ const { parent, index, deletedAnnotation } = event as AnnotationDeletedEvent
233
+ const resolvedParent = idMapping.fromId(parent)
234
+ const resolvedDeletedAnnotation = idMapping.fromId(deletedAnnotation)
235
+ return new AnnotationDeletedDelta(resolvedParent, index, resolvedDeletedAnnotation)
236
+ }
237
+ case "AnnotationReplaced": { // § 6.6.5.3
238
+ const { newAnnotation, replacedAnnotation, parent, index } = event as AnnotationReplacedEvent
239
+ const resolvedParent = idMapping.fromId(parent)
240
+ const resolvedReplacedAnnotation = idMapping.fromId(replacedAnnotation)
241
+ return new AnnotationReplacedDelta(resolvedParent, index, resolvedReplacedAnnotation, deserializedNodeFrom(newAnnotation))
242
+ }
243
+ case "AnnotationMovedFromOtherParent": { // § 6.6.5.4
244
+ const { oldParent, oldIndex, newParent, newIndex, movedAnnotation } = event as AnnotationMovedFromOtherParentEvent
245
+ const resolvedOldParent = idMapping.fromId(oldParent)
246
+ const resolvedNewParent = idMapping.fromId(newParent)
247
+ const resolvedMovedAnnotation = idMapping.fromId(movedAnnotation)
248
+ return new AnnotationMovedFromOtherParentDelta(resolvedOldParent, oldIndex, resolvedNewParent, newIndex, resolvedMovedAnnotation)
249
+ }
250
+ case "AnnotationMovedInSameParent": { // § 6.6.5.5
251
+ const { parent, oldIndex, newIndex, movedAnnotation } = event as AnnotationMovedInSameParentEvent
252
+ const resolvedParent = idMapping.fromId(parent)
253
+ const resolvedMovedAnnotation = idMapping.fromId(movedAnnotation)
254
+ return new AnnotationMovedInSameParentDelta(resolvedParent, oldIndex, newIndex, resolvedMovedAnnotation)
255
+ }
256
+ case "AnnotationMovedAndReplacedFromOtherParent": { // § 6.6.5.6
257
+ const { oldParent, oldIndex, replacedAnnotation, newParent, newIndex, movedAnnotation } = event as AnnotationMovedAndReplacedFromOtherParentEvent
258
+ const resolvedOldParent = idMapping.fromId(oldParent)
259
+ const resolvedReplacedAnnotation = idMapping.fromId(replacedAnnotation)
260
+ const resolvedNewParent = idMapping.fromId(newParent)
261
+ const resolvedMovedAnnotation = idMapping.fromId(movedAnnotation)
262
+ return new AnnotationMovedAndReplacedFromOtherParentDelta(resolvedOldParent, oldIndex, resolvedReplacedAnnotation, resolvedNewParent, newIndex, resolvedMovedAnnotation)
263
+ }
264
+ case "AnnotationMovedAndReplacedInSameParent": { // § 6.6.5.7
265
+ const { parent, oldIndex, newIndex, replacedAnnotation, movedAnnotation } = event as AnnotationMovedAndReplacedInSameParentEvent
266
+ const resolvedParent = idMapping.fromId(parent)
267
+ const resolvedReplacedAnnotation = idMapping.fromId(replacedAnnotation)
268
+ const resolvedMovedAnnotation = idMapping.fromId(movedAnnotation)
269
+ return new AnnotationMovedAndReplacedInSameParentDelta(resolvedParent, oldIndex, newIndex, resolvedReplacedAnnotation, resolvedMovedAnnotation)
270
+ }
271
+ case "ReferenceAdded": { // § 6.6.6.1
272
+ const { parent, reference, index, newTarget } = event as ReferenceAddedEvent
273
+ const resolvedParent = idMapping.fromId(parent)
274
+ const resolvedReference = resolvedReferenceFrom(reference, resolvedParent.classifier)
275
+ const resolvedNewTarget = resolvedRefTo(newTarget)
276
+ return new ReferenceAddedDelta(resolvedParent, resolvedReference, index, resolvedNewTarget)
277
+ }
278
+ case "ReferenceDeleted": { // § 6.6.6.2
279
+ const { parent, reference, index, deletedTarget } = event as ReferenceDeletedEvent
280
+ const resolvedParent = idMapping.fromId(parent)
281
+ const resolvedReference = resolvedReferenceFrom(reference, resolvedParent.classifier)
282
+ const resolvedDeletedTarget = resolvedRefTo(deletedTarget)
283
+ return new ReferenceDeletedDelta(resolvedParent, resolvedReference, index, resolvedDeletedTarget)
284
+ }
285
+ case "ReferenceChanged": { // § 6.6.6.3
286
+ const { parent, reference, index, oldTarget, newTarget } = event as ReferenceChangedEvent
287
+ const resolvedParent = idMapping.fromId(parent)
288
+ const resolvedReference = resolvedReferenceFrom(reference, resolvedParent.classifier)
289
+ const resolvedOldTarget = resolvedRefTo(oldTarget)
290
+ const resolvedNewTarget = resolvedRefTo(newTarget)
291
+ return new ReferenceChangedDelta(resolvedParent, resolvedReference, index, resolvedNewTarget, resolvedOldTarget)
292
+ }
293
+ case "EntryMovedFromOtherReference": { // § 6.6.6.4
294
+ const { newParent, newReference, newIndex, oldParent, oldReference, oldIndex, movedTarget } = event as EntryMovedFromOtherReferenceEvent
295
+ const resolvedNewParent = idMapping.fromId(newParent)
296
+ const resolvedNewReference = resolvedReferenceFrom(newReference, resolvedNewParent.classifier)
297
+ const resolvedOldParent = idMapping.fromId(oldParent)
298
+ const resolvedOldReference = resolvedReferenceFrom(oldReference, resolvedOldParent.classifier)
299
+ const resolvedMovedTarget = resolvedRefTo(movedTarget)
300
+ return new EntryMovedFromOtherReferenceDelta(resolvedOldParent, resolvedOldReference, oldIndex, resolvedNewParent, resolvedNewReference, newIndex, resolvedMovedTarget)
301
+ }
302
+ case "EntryMovedFromOtherReferenceInSameParent": { // § 6.6.6.5
303
+ const { parent, oldReference, oldIndex, newReference, newIndex, movedTarget } = event as EntryMovedFromOtherReferenceInSameParentEvent
304
+ const resolvedParent = idMapping.fromId(parent)
305
+ const resolvedOldReference = resolvedReferenceFrom(oldReference, resolvedParent.classifier)
306
+ const resolvedNewReference = resolvedReferenceFrom(newReference, resolvedParent.classifier)
307
+ const resolvedMovedTarget = resolvedRefTo(movedTarget)
308
+ return new EntryMovedFromOtherReferenceInSameParentDelta(resolvedParent, resolvedOldReference, oldIndex, resolvedNewReference, newIndex, resolvedMovedTarget)
309
+ }
310
+ case "EntryMovedInSameReference": { // § 6.6.6.6
311
+ const { parent, reference, oldIndex, newIndex, movedTarget } = event as EntryMovedInSameReferenceEvent
312
+ const resolvedParent = idMapping.fromId(parent)
313
+ const resolvedReference = resolvedReferenceFrom(reference, resolvedParent.classifier)
314
+ const resolvedMovedTarget = resolvedRefTo(movedTarget)
315
+ return new EntryMovedInSameReferenceDelta(resolvedParent, resolvedReference, oldIndex, newIndex, resolvedMovedTarget)
316
+ }
317
+ case "EntryMovedAndReplacedFromOtherReference": { // § 6.6.6.7
318
+ const { newParent, newReference, newIndex, movedTarget, oldParent, oldReference, oldIndex, replacedTarget } = event as EntryMovedAndReplacedFromOtherReferenceEvent
319
+ const resolvedNewParent = idMapping.fromId(newParent)
320
+ const resolvedNewReference = resolvedReferenceFrom(newReference, resolvedNewParent.classifier)
321
+ const resolvedMovedTarget = resolvedRefTo(movedTarget)
322
+ const resolvedOldParent = idMapping.fromId(oldParent)
323
+ const resolvedOldReference = resolvedReferenceFrom(oldReference, resolvedOldParent.classifier)
324
+ const resolvedReplacedTarget = resolvedRefTo(replacedTarget)
325
+ return new EntryMovedAndReplacedFromOtherReferenceDelta(resolvedNewParent, resolvedNewReference, newIndex, resolvedMovedTarget, resolvedOldParent, resolvedOldReference, oldIndex, resolvedReplacedTarget)
326
+ }
327
+ case "EntryMovedAndReplacedFromOtherReferenceInSameParent": { // § 6.6.6.8
328
+ const { parent, oldReference, oldIndex, newReference, newIndex, movedTarget, replacedTarget } = event as EntryMovedAndReplacedFromOtherReferenceInSameParentEvent
329
+ const resolvedParent = idMapping.fromId(parent)
330
+ const resolvedOldReference = resolvedReferenceFrom(oldReference, resolvedParent.classifier)
331
+ const resolvedNewReference = resolvedReferenceFrom(newReference, resolvedParent.classifier)
332
+ const resolvedMovedTarget = resolvedRefTo(movedTarget)
333
+ const resolvedReplacedTarget= resolvedRefTo(replacedTarget)
334
+ return new EntryMovedAndReplacedFromOtherReferenceInSameParentDelta(resolvedParent, resolvedOldReference, oldIndex, resolvedNewReference, newIndex, resolvedMovedTarget, resolvedReplacedTarget)
335
+ }
336
+ case "EntryMovedAndReplacedInSameReference": { // § 6.6.6.9
337
+ const { parent, reference, oldIndex, newIndex, movedTarget, replacedTarget } = event as EntryMovedAndReplacedInSameReferenceEvent
338
+ const resolvedParent = idMapping.fromId(parent)
339
+ const resolvedReference = resolvedReferenceFrom(reference, resolvedParent.classifier)
340
+ const resolvedMovedTarget = resolvedRefTo(movedTarget)
341
+ const resolvedReplacedTarget = resolvedRefTo(replacedTarget)
342
+ return new EntryMovedAndReplacedInSameReferenceDelta(resolvedParent, resolvedReference, oldIndex, newIndex, resolvedMovedTarget, resolvedReplacedTarget)
343
+ }
344
+ case "ReferenceResolveInfoAdded": { // § 6.6.6.10
345
+ return undefined
346
+ }
347
+ case "ReferenceResolveInfoDeleted": { // § 6.6.6.11
348
+ return undefined
349
+ }
350
+ case "ReferenceResolveInfoChanged": { // § 6.6.6.12
351
+ return undefined
352
+ }
353
+ case "ReferenceTargetAdded": { // § 6.6.6.13
354
+ return undefined
355
+ }
356
+ case "ReferenceTargetDeleted": { // § 6.6.6.14
357
+ return undefined
358
+ }
359
+ case "ReferenceTargetChanged": { // § 6.6.6.15
360
+ return undefined
361
+ }
362
+ case "CompositeEvent": { // § 6.6.7.1
363
+ const { parts } = event as CompositeEvent
364
+ return new CompositeDelta(
365
+ parts
366
+ .map((part) => eventAsDelta(part, idMapping))
367
+ .filter((deltaOrUndefined) => deltaOrUndefined !== undefined) as IDelta[]
368
+ )
369
+ }
370
+ case "NoOp": { // § 6.6.7.2
371
+ return new NoOpDelta()
372
+ }
373
+ case "Error": { // § 6.6.7.3
374
+ return undefined
375
+ }
376
+
377
+ default:
378
+ throw new Error(`can't handle event of kind ${event.messageKind}`)
379
+ }
380
+ }
381
+
382
+ return eventAsDelta
383
+ }
384
+
@@ -0,0 +1,21 @@
1
+ // Copyright 2025 TRUMPF Laser SE and other contributors
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License")
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ //
15
+ // SPDX-FileCopyrightText: 2025 TRUMPF Laser SE and other contributors
16
+ // SPDX-License-Identifier: Apache-2.0
17
+
18
+ export { deltaAsCommand } from "./delta-to-command.js"
19
+ export { eventToDeltaTranslator } from "./event-to-delta.js"
20
+ export type { EventToDeltaTranslator } from "./event-to-delta.js"
21
+
@@ -0,0 +1,50 @@
1
+ // Copyright 2025 TRUMPF Laser SE and other contributors
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License")
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ //
15
+ // SPDX-FileCopyrightText: 2025 TRUMPF Laser SE and other contributors
16
+ // SPDX-License-Identifier: Apache-2.0
17
+
18
+
19
+ /**
20
+ * A type for callback functions of the shape present in the WebSocket API.
21
+ */
22
+ export type Callback = (error?: Error) => void
23
+
24
+ /**
25
+ * A generic implementation of {@link Callback} that just throws a received {@link Error error}.
26
+ */
27
+ export const throwingCallback: Callback = (error) => {
28
+ if (error !== undefined) {
29
+ throw error
30
+ }
31
+ }
32
+
33
+
34
+ /**
35
+ * @return the given procedure with callback, but wrapped properly as a {@link Promise}.
36
+ */
37
+ export const wrappedAsPromise = (procedure: (callback: Callback) => void): Promise<void> =>
38
+ new Promise<void>((resolve, reject) => {
39
+ procedure(
40
+ (optionalError) => {
41
+ if (optionalError === undefined || optionalError === null) { // also check for null, because that's what happens in real life
42
+ resolve()
43
+ } else {
44
+ reject()
45
+ }
46
+ }
47
+ )
48
+ })
49
+
50
+
@@ -0,0 +1,22 @@
1
+ // Copyright 2025 TRUMPF Laser SE and other contributors
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License")
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ //
15
+ // SPDX-FileCopyrightText: 2025 TRUMPF Laser SE and other contributors
16
+ // SPDX-License-Identifier: Apache-2.0
17
+
18
+ export { wrappedAsPromise } from "./async.js"
19
+ export { tryParseJson } from "./json.js"
20
+ export { combine, noOpProcedure } from "./procedure.js"
21
+ export type { Procedure } from "./procedure.js"
22
+
@@ -0,0 +1,32 @@
1
+ // Copyright 2025 TRUMPF Laser SE and other contributors
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License")
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ //
15
+ // SPDX-FileCopyrightText: 2025 TRUMPF Laser SE and other contributors
16
+ // SPDX-License-Identifier: Apache-2.0
17
+
18
+ import { TextualLogger } from "../logging/textual-logging.js"
19
+
20
+ /**
21
+ * @return the given text parsed as JSON.
22
+ * @throws an exception when parsing fails, but not before printing the text being parsed on the error console.
23
+ */
24
+ export const tryParseJson = (jsonText: string, log: TextualLogger): unknown => {
25
+ try {
26
+ return JSON.parse(jsonText)
27
+ } catch (e) {
28
+ log(`problem occurs when parsing the following text as JSON: ${jsonText}`, true)
29
+ throw e
30
+ }
31
+ }
32
+
@@ -0,0 +1,43 @@
1
+ // Copyright 2025 TRUMPF Laser SE and other contributors
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License")
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ //
15
+ // SPDX-FileCopyrightText: 2025 TRUMPF Laser SE and other contributors
16
+ // SPDX-License-Identifier: Apache-2.0
17
+
18
+
19
+ /**
20
+ * (self-explanatory)
21
+ */
22
+ export type Procedure<T> = (t: T) => void
23
+
24
+ /**
25
+ * @return a {@link Procedure procedure} that executes the procedures in the given order.
26
+ * Any procedure that's {@code undefined} will be skipped.
27
+ */
28
+ export const combine = <T>(...procedures: (Procedure<T> | undefined)[]): Procedure<T> =>
29
+ (t) => {
30
+ procedures.forEach((procedure) => {
31
+ if (procedure !== undefined) {
32
+ procedure(t)
33
+ }
34
+ })
35
+ }
36
+
37
+
38
+ /**
39
+ * Implementation of {@link Procedure} that does nothing.
40
+ */
41
+ export const noOpProcedure: Procedure<void> = (_) =>
42
+ undefined // ~void
43
+