@cratis/scene.engine 4.2.1 → 4.3.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.
Files changed (205) hide show
  1. package/dist/cjs/editing/DescriptorCatalog.js +42 -0
  2. package/dist/cjs/editing/DescriptorCatalog.js.map +1 -0
  3. package/dist/cjs/editing/EditSession.js +44 -0
  4. package/dist/cjs/editing/EditSession.js.map +1 -0
  5. package/dist/cjs/editing/applyEdit.js +83 -0
  6. package/dist/cjs/editing/applyEdit.js.map +1 -0
  7. package/dist/cjs/editing/applyEffectiveConfiguration.js +62 -0
  8. package/dist/cjs/editing/applyEffectiveConfiguration.js.map +1 -0
  9. package/dist/cjs/editing/collectComponents.js +34 -0
  10. package/dist/cjs/editing/collectComponents.js.map +1 -0
  11. package/dist/cjs/editing/describeNode.js +63 -0
  12. package/dist/cjs/editing/describeNode.js.map +1 -0
  13. package/dist/cjs/editing/diagnostics.js +36 -0
  14. package/dist/cjs/editing/diagnostics.js.map +1 -0
  15. package/dist/cjs/editing/documentPaths.js +45 -0
  16. package/dist/cjs/editing/documentPaths.js.map +1 -0
  17. package/dist/cjs/editing/exposureEdits.js +106 -0
  18. package/dist/cjs/editing/exposureEdits.js.map +1 -0
  19. package/dist/cjs/editing/exposureGrants.js +115 -0
  20. package/dist/cjs/editing/exposureGrants.js.map +1 -0
  21. package/dist/cjs/editing/indexDocument.js +400 -0
  22. package/dist/cjs/editing/indexDocument.js.map +1 -0
  23. package/dist/cjs/editing/inspect.js +127 -0
  24. package/dist/cjs/editing/inspect.js.map +1 -0
  25. package/dist/cjs/editing/instanceEdits.js +255 -0
  26. package/dist/cjs/editing/instanceEdits.js.map +1 -0
  27. package/dist/cjs/editing/layoutTypeDescriptors.js +425 -0
  28. package/dist/cjs/editing/layoutTypeDescriptors.js.map +1 -0
  29. package/dist/cjs/editing/layoutTypeEdits.js +141 -0
  30. package/dist/cjs/editing/layoutTypeEdits.js.map +1 -0
  31. package/dist/cjs/editing/nodeIds.js +115 -0
  32. package/dist/cjs/editing/nodeIds.js.map +1 -0
  33. package/dist/cjs/editing/pathAccess.js +53 -0
  34. package/dist/cjs/editing/pathAccess.js.map +1 -0
  35. package/dist/cjs/editing/propertyEdits.js +118 -0
  36. package/dist/cjs/editing/propertyEdits.js.map +1 -0
  37. package/dist/cjs/editing/resolveEffectiveConfiguration.js +200 -0
  38. package/dist/cjs/editing/resolveEffectiveConfiguration.js.map +1 -0
  39. package/dist/cjs/editing/resolveTemplateChain.js +100 -0
  40. package/dist/cjs/editing/resolveTemplateChain.js.map +1 -0
  41. package/dist/cjs/editing/structureEdits.js +231 -0
  42. package/dist/cjs/editing/structureEdits.js.map +1 -0
  43. package/dist/cjs/editing/validateBinding.js +111 -0
  44. package/dist/cjs/editing/validateBinding.js.map +1 -0
  45. package/dist/cjs/editing/validateValue.js +114 -0
  46. package/dist/cjs/editing/validateValue.js.map +1 -0
  47. package/dist/cjs/index.js +51 -0
  48. package/dist/cjs/index.js.map +1 -1
  49. package/dist/esm/editing/DescriptorCatalog.d.ts +9 -0
  50. package/dist/esm/editing/DescriptorCatalog.d.ts.map +1 -0
  51. package/dist/esm/editing/DescriptorCatalog.js +38 -0
  52. package/dist/esm/editing/DescriptorCatalog.js.map +1 -0
  53. package/dist/esm/editing/DocumentIndex.d.ts +31 -0
  54. package/dist/esm/editing/DocumentIndex.d.ts.map +1 -0
  55. package/dist/esm/editing/DocumentIndex.js +2 -0
  56. package/dist/esm/editing/DocumentIndex.js.map +1 -0
  57. package/dist/esm/editing/EditOutcome.d.ts +7 -0
  58. package/dist/esm/editing/EditOutcome.d.ts.map +1 -0
  59. package/dist/esm/editing/EditOutcome.js +2 -0
  60. package/dist/esm/editing/EditOutcome.js.map +1 -0
  61. package/dist/esm/editing/EditSession.d.ts +20 -0
  62. package/dist/esm/editing/EditSession.d.ts.map +1 -0
  63. package/dist/esm/editing/EditSession.js +42 -0
  64. package/dist/esm/editing/EditSession.js.map +1 -0
  65. package/dist/esm/editing/EditingContext.d.ts +8 -0
  66. package/dist/esm/editing/EditingContext.d.ts.map +1 -0
  67. package/dist/esm/editing/EditingContext.js +2 -0
  68. package/dist/esm/editing/EditingContext.js.map +1 -0
  69. package/dist/esm/editing/TemplateChain.d.ts +13 -0
  70. package/dist/esm/editing/TemplateChain.d.ts.map +1 -0
  71. package/dist/esm/editing/TemplateChain.js +2 -0
  72. package/dist/esm/editing/TemplateChain.js.map +1 -0
  73. package/dist/esm/editing/applyEdit.d.ts +5 -0
  74. package/dist/esm/editing/applyEdit.d.ts.map +1 -0
  75. package/dist/esm/editing/applyEdit.js +81 -0
  76. package/dist/esm/editing/applyEdit.js.map +1 -0
  77. package/dist/esm/editing/applyEffectiveConfiguration.d.ts +3 -0
  78. package/dist/esm/editing/applyEffectiveConfiguration.d.ts.map +1 -0
  79. package/dist/esm/editing/applyEffectiveConfiguration.js +60 -0
  80. package/dist/esm/editing/applyEffectiveConfiguration.js.map +1 -0
  81. package/dist/esm/editing/collectComponents.d.ts +3 -0
  82. package/dist/esm/editing/collectComponents.d.ts.map +1 -0
  83. package/dist/esm/editing/collectComponents.js +32 -0
  84. package/dist/esm/editing/collectComponents.js.map +1 -0
  85. package/dist/esm/editing/describeNode.d.ts +11 -0
  86. package/dist/esm/editing/describeNode.d.ts.map +1 -0
  87. package/dist/esm/editing/describeNode.js +60 -0
  88. package/dist/esm/editing/describeNode.js.map +1 -0
  89. package/dist/esm/editing/diagnostics.d.ts +6 -0
  90. package/dist/esm/editing/diagnostics.d.ts.map +1 -0
  91. package/dist/esm/editing/diagnostics.js +32 -0
  92. package/dist/esm/editing/diagnostics.js.map +1 -0
  93. package/dist/esm/editing/documentPaths.d.ts +8 -0
  94. package/dist/esm/editing/documentPaths.d.ts.map +1 -0
  95. package/dist/esm/editing/documentPaths.js +41 -0
  96. package/dist/esm/editing/documentPaths.js.map +1 -0
  97. package/dist/esm/editing/exposureEdits.d.ts +5 -0
  98. package/dist/esm/editing/exposureEdits.d.ts.map +1 -0
  99. package/dist/esm/editing/exposureEdits.js +103 -0
  100. package/dist/esm/editing/exposureEdits.js.map +1 -0
  101. package/dist/esm/editing/exposureGrants.d.ts +21 -0
  102. package/dist/esm/editing/exposureGrants.d.ts.map +1 -0
  103. package/dist/esm/editing/exposureGrants.js +112 -0
  104. package/dist/esm/editing/exposureGrants.js.map +1 -0
  105. package/dist/esm/editing/given/a_layout_document.d.ts +14 -0
  106. package/dist/esm/editing/given/a_layout_document.d.ts.map +1 -0
  107. package/dist/esm/editing/given/a_layout_document.js +67 -0
  108. package/dist/esm/editing/given/a_layout_document.js.map +1 -0
  109. package/dist/esm/editing/given/a_scene_document.d.ts +20 -0
  110. package/dist/esm/editing/given/a_scene_document.d.ts.map +1 -0
  111. package/dist/esm/editing/given/a_scene_document.js +110 -0
  112. package/dist/esm/editing/given/a_scene_document.js.map +1 -0
  113. package/dist/esm/editing/index.d.ts +19 -0
  114. package/dist/esm/editing/index.d.ts.map +1 -0
  115. package/dist/esm/editing/index.js +19 -0
  116. package/dist/esm/editing/index.js.map +1 -0
  117. package/dist/esm/editing/indexDocument.d.ts +6 -0
  118. package/dist/esm/editing/indexDocument.d.ts.map +1 -0
  119. package/dist/esm/editing/indexDocument.js +396 -0
  120. package/dist/esm/editing/indexDocument.js.map +1 -0
  121. package/dist/esm/editing/inspect.d.ts +8 -0
  122. package/dist/esm/editing/inspect.d.ts.map +1 -0
  123. package/dist/esm/editing/inspect.js +124 -0
  124. package/dist/esm/editing/inspect.js.map +1 -0
  125. package/dist/esm/editing/instanceEdits.d.ts +9 -0
  126. package/dist/esm/editing/instanceEdits.d.ts.map +1 -0
  127. package/dist/esm/editing/instanceEdits.js +248 -0
  128. package/dist/esm/editing/instanceEdits.js.map +1 -0
  129. package/dist/esm/editing/layoutTypeDescriptors.d.ts +5 -0
  130. package/dist/esm/editing/layoutTypeDescriptors.d.ts.map +1 -0
  131. package/dist/esm/editing/layoutTypeDescriptors.js +421 -0
  132. package/dist/esm/editing/layoutTypeDescriptors.js.map +1 -0
  133. package/dist/esm/editing/layoutTypeEdits.d.ts +4 -0
  134. package/dist/esm/editing/layoutTypeEdits.d.ts.map +1 -0
  135. package/dist/esm/editing/layoutTypeEdits.js +139 -0
  136. package/dist/esm/editing/layoutTypeEdits.js.map +1 -0
  137. package/dist/esm/editing/nodeIds.d.ts +14 -0
  138. package/dist/esm/editing/nodeIds.d.ts.map +1 -0
  139. package/dist/esm/editing/nodeIds.js +102 -0
  140. package/dist/esm/editing/nodeIds.js.map +1 -0
  141. package/dist/esm/editing/pathAccess.d.ts +7 -0
  142. package/dist/esm/editing/pathAccess.d.ts.map +1 -0
  143. package/dist/esm/editing/pathAccess.js +48 -0
  144. package/dist/esm/editing/pathAccess.js.map +1 -0
  145. package/dist/esm/editing/propertyEdits.d.ts +15 -0
  146. package/dist/esm/editing/propertyEdits.d.ts.map +1 -0
  147. package/dist/esm/editing/propertyEdits.js +113 -0
  148. package/dist/esm/editing/propertyEdits.js.map +1 -0
  149. package/dist/esm/editing/resolveEffectiveConfiguration.d.ts +5 -0
  150. package/dist/esm/editing/resolveEffectiveConfiguration.d.ts.map +1 -0
  151. package/dist/esm/editing/resolveEffectiveConfiguration.js +198 -0
  152. package/dist/esm/editing/resolveEffectiveConfiguration.js.map +1 -0
  153. package/dist/esm/editing/resolveTemplateChain.d.ts +4 -0
  154. package/dist/esm/editing/resolveTemplateChain.d.ts.map +1 -0
  155. package/dist/esm/editing/resolveTemplateChain.js +98 -0
  156. package/dist/esm/editing/resolveTemplateChain.js.map +1 -0
  157. package/dist/esm/editing/structureEdits.d.ts +6 -0
  158. package/dist/esm/editing/structureEdits.d.ts.map +1 -0
  159. package/dist/esm/editing/structureEdits.js +227 -0
  160. package/dist/esm/editing/structureEdits.js.map +1 -0
  161. package/dist/esm/editing/validateBinding.d.ts +7 -0
  162. package/dist/esm/editing/validateBinding.d.ts.map +1 -0
  163. package/dist/esm/editing/validateBinding.js +108 -0
  164. package/dist/esm/editing/validateBinding.js.map +1 -0
  165. package/dist/esm/editing/validateValue.d.ts +8 -0
  166. package/dist/esm/editing/validateValue.d.ts.map +1 -0
  167. package/dist/esm/editing/validateValue.js +111 -0
  168. package/dist/esm/editing/validateValue.js.map +1 -0
  169. package/dist/esm/index.d.ts +1 -0
  170. package/dist/esm/index.d.ts.map +1 -1
  171. package/dist/esm/index.js +14 -0
  172. package/dist/esm/index.js.map +1 -1
  173. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  174. package/editing/DescriptorCatalog.ts +51 -0
  175. package/editing/DocumentIndex.ts +73 -0
  176. package/editing/EditOutcome.ts +21 -0
  177. package/editing/EditSession.ts +50 -0
  178. package/editing/EditingContext.ts +23 -0
  179. package/editing/TemplateChain.ts +36 -0
  180. package/editing/applyEdit.ts +69 -0
  181. package/editing/applyEffectiveConfiguration.ts +53 -0
  182. package/editing/collectComponents.ts +36 -0
  183. package/editing/describeNode.ts +61 -0
  184. package/editing/diagnostics.ts +30 -0
  185. package/editing/documentPaths.ts +40 -0
  186. package/editing/exposureEdits.ts +119 -0
  187. package/editing/exposureGrants.ts +159 -0
  188. package/editing/given/a_layout_document.ts +88 -0
  189. package/editing/given/a_scene_document.ts +135 -0
  190. package/editing/index.ts +21 -0
  191. package/editing/indexDocument.ts +237 -0
  192. package/editing/inspect.ts +142 -0
  193. package/editing/instanceEdits.ts +243 -0
  194. package/editing/layoutTypeDescriptors.ts +191 -0
  195. package/editing/layoutTypeEdits.ts +135 -0
  196. package/editing/nodeIds.ts +111 -0
  197. package/editing/pathAccess.ts +81 -0
  198. package/editing/propertyEdits.ts +119 -0
  199. package/editing/resolveEffectiveConfiguration.ts +202 -0
  200. package/editing/resolveTemplateChain.ts +109 -0
  201. package/editing/structureEdits.ts +234 -0
  202. package/editing/validateBinding.ts +103 -0
  203. package/editing/validateValue.ts +130 -0
  204. package/index.ts +1 -0
  205. package/package.json +3 -3
@@ -0,0 +1,102 @@
1
+ import { EditingScopeKind } from '@cratis/scene.model';
2
+
3
+ // Copyright (c) Cratis. All rights reserved.
4
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
5
+ const separator = '#';
6
+ function child(parentId, segment) {
7
+ return [
8
+ parentId,
9
+ segment
10
+ ].join(separator);
11
+ }
12
+ /**
13
+ * The id of a layout node.
14
+ */ function layoutNodeId(name) {
15
+ return `layout:${name}`;
16
+ }
17
+ /**
18
+ * The id of a screen template node.
19
+ */ function screenTemplateNodeId(name) {
20
+ return `screenTemplate:${name}`;
21
+ }
22
+ /**
23
+ * The id of a dialog template node.
24
+ */ function dialogTemplateNodeId(name) {
25
+ return `dialogTemplate:${name}`;
26
+ }
27
+ /**
28
+ * The id of a screen node.
29
+ */ function screenNodeId(name) {
30
+ return `screen:${name}`;
31
+ }
32
+ /**
33
+ * The id of a named slot of a layout, template or screen.
34
+ */ function slotNodeId(ownerNodeId, slotName) {
35
+ return child(ownerNodeId, `slot:${slotName}`);
36
+ }
37
+ /**
38
+ * The id of an element. Element ids are unique across a document and survive moves, so this is the stable way to
39
+ * address a component an author has placed.
40
+ */ function elementNodeId(elementId) {
41
+ return `element:${elementId}`;
42
+ }
43
+ /**
44
+ * The id of the arrangement a layout, template or dialog positions its own slots with.
45
+ */ function ownerArrangementId(ownerNodeId) {
46
+ return child(ownerNodeId, 'arrangement');
47
+ }
48
+ /**
49
+ * The id of a node of a flow arrangement.
50
+ *
51
+ * `holderId` is the slot or owner arrangement the flow belongs to, `variant` is `root` or `override<n>`, and
52
+ * `indexPath` walks down from that variant's root through each container's children. A flow node has no identity
53
+ * of its own, so the id is a structural address and only names the same node until the tree around it changes -
54
+ * read it from the same revision of the document you act on.
55
+ */ function flowNodeId(holderId, variant, indexPath) {
56
+ return child(holderId, `flow:${[
57
+ variant,
58
+ ...indexPath
59
+ ].join('.')}`);
60
+ }
61
+ /**
62
+ * The id of a freeform arrangement.
63
+ */ function freeformNodeId(holderId) {
64
+ return child(holderId, 'freeform');
65
+ }
66
+ /**
67
+ * The id of one placement within a freeform variant. `key` is the placed element's id, or the placed slot's name.
68
+ */ function placementNodeId(holderId, variantIndex, key) {
69
+ return child(`${freeformNodeId(holderId)}:${variantIndex}`, `placement:${key}`);
70
+ }
71
+ /**
72
+ * The node id of the thing an editing scope names.
73
+ */ function scopeNodeId(scope) {
74
+ switch(scope.kind){
75
+ case EditingScopeKind.Screen:
76
+ return screenNodeId(scope.name);
77
+ case EditingScopeKind.ScreenTemplate:
78
+ return screenTemplateNodeId(scope.name);
79
+ case EditingScopeKind.DialogTemplate:
80
+ return dialogTemplateNodeId(scope.name);
81
+ default:
82
+ return layoutNodeId(scope.name);
83
+ }
84
+ }
85
+ /**
86
+ * The instance id an editing scope contributes under: `screen:<name>`, `template:<name>`, `dialog:<name>` or
87
+ * `layout:<name>`. It is what an {@link InstanceContribution} is keyed by.
88
+ */ function scopeInstanceId(scope) {
89
+ switch(scope.kind){
90
+ case EditingScopeKind.Screen:
91
+ return `screen:${scope.name}`;
92
+ case EditingScopeKind.ScreenTemplate:
93
+ return `template:${scope.name}`;
94
+ case EditingScopeKind.DialogTemplate:
95
+ return `dialog:${scope.name}`;
96
+ default:
97
+ return `layout:${scope.name}`;
98
+ }
99
+ }
100
+
101
+ export { dialogTemplateNodeId, elementNodeId, flowNodeId, freeformNodeId, layoutNodeId, ownerArrangementId, placementNodeId, scopeInstanceId, scopeNodeId, screenNodeId, screenTemplateNodeId, slotNodeId };
102
+ //# sourceMappingURL=nodeIds.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nodeIds.js","sources":["../../../editing/nodeIds.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { EditingScope, EditingScopeKind } from '@cratis/scene.model';\n\nconst separator = '#';\n\nfunction child(parentId: string, segment: string): string {\n return [parentId, segment].join(separator);\n}\n\n/**\n * The id of a layout node.\n */\nexport function layoutNodeId(name: string): string {\n return `layout:${name}`;\n}\n\n/**\n * The id of a screen template node.\n */\nexport function screenTemplateNodeId(name: string): string {\n return `screenTemplate:${name}`;\n}\n\n/**\n * The id of a dialog template node.\n */\nexport function dialogTemplateNodeId(name: string): string {\n return `dialogTemplate:${name}`;\n}\n\n/**\n * The id of a screen node.\n */\nexport function screenNodeId(name: string): string {\n return `screen:${name}`;\n}\n\n/**\n * The id of a named slot of a layout, template or screen.\n */\nexport function slotNodeId(ownerNodeId: string, slotName: string): string {\n return child(ownerNodeId, `slot:${slotName}`);\n}\n\n/**\n * The id of an element. Element ids are unique across a document and survive moves, so this is the stable way to\n * address a component an author has placed.\n */\nexport function elementNodeId(elementId: string): string {\n return `element:${elementId}`;\n}\n\n/**\n * The id of the arrangement a layout, template or dialog positions its own slots with.\n */\nexport function ownerArrangementId(ownerNodeId: string): string {\n return child(ownerNodeId, 'arrangement');\n}\n\n/**\n * The id of a node of a flow arrangement.\n *\n * `holderId` is the slot or owner arrangement the flow belongs to, `variant` is `root` or `override<n>`, and\n * `indexPath` walks down from that variant's root through each container's children. A flow node has no identity\n * of its own, so the id is a structural address and only names the same node until the tree around it changes -\n * read it from the same revision of the document you act on.\n */\nexport function flowNodeId(holderId: string, variant: string, indexPath: number[]): string {\n return child(holderId, `flow:${[variant, ...indexPath].join('.')}`);\n}\n\n/**\n * The id of a freeform arrangement.\n */\nexport function freeformNodeId(holderId: string): string {\n return child(holderId, 'freeform');\n}\n\n/**\n * The id of one placement within a freeform variant. `key` is the placed element's id, or the placed slot's name.\n */\nexport function placementNodeId(holderId: string, variantIndex: number, key: string): string {\n return child(`${freeformNodeId(holderId)}:${variantIndex}`, `placement:${key}`);\n}\n\n/**\n * The node id of the thing an editing scope names.\n */\nexport function scopeNodeId(scope: EditingScope): string {\n switch (scope.kind) {\n case EditingScopeKind.Screen: return screenNodeId(scope.name);\n case EditingScopeKind.ScreenTemplate: return screenTemplateNodeId(scope.name);\n case EditingScopeKind.DialogTemplate: return dialogTemplateNodeId(scope.name);\n default: return layoutNodeId(scope.name);\n }\n}\n\n/**\n * The instance id an editing scope contributes under: `screen:<name>`, `template:<name>`, `dialog:<name>` or\n * `layout:<name>`. It is what an {@link InstanceContribution} is keyed by.\n */\nexport function scopeInstanceId(scope: EditingScope): string {\n switch (scope.kind) {\n case EditingScopeKind.Screen: return `screen:${scope.name}`;\n case EditingScopeKind.ScreenTemplate: return `template:${scope.name}`;\n case EditingScopeKind.DialogTemplate: return `dialog:${scope.name}`;\n default: return `layout:${scope.name}`;\n }\n}\n"],"names":["separator","child","parentId","segment","join","layoutNodeId","name","screenTemplateNodeId","dialogTemplateNodeId","screenNodeId","slotNodeId","ownerNodeId","slotName","elementNodeId","elementId","ownerArrangementId","flowNodeId","holderId","variant","indexPath","freeformNodeId","placementNodeId","variantIndex","key","scopeNodeId","scope","kind","EditingScopeKind","Screen","ScreenTemplate","DialogTemplate","scopeInstanceId"],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export declare function getValueAtPath(bag: Record<string, unknown>, path: string): unknown;
2
+ export declare function hasValueAtPath(bag: Record<string, unknown>, path: string): boolean;
3
+ export declare function setValueAtPath(bag: Record<string, unknown>, path: string, value: unknown): void;
4
+ export declare function removeValueAtPath(bag: Record<string, unknown>, path: string): void;
5
+ export declare function cloneData<T>(value: T): T;
6
+ export declare function dataEquals(left: unknown, right: unknown): boolean;
7
+ //# sourceMappingURL=pathAccess.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pathAccess.d.ts","sourceRoot":"","sources":["../../../editing/pathAccess.ts"],"names":[],"mappings":"AAOA,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAQlF;AAKD,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAElF;AAKD,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAa/F;AAKD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAWlF;AAKD,wBAAgB,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAExC;AAKD,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAYjE"}
@@ -0,0 +1,48 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+ /**
4
+ * Reads a value at a dotted path in a plain object - `a.b.c` reads `bag.a.b.c` - or `undefined` when any step is
5
+ * missing.
6
+ */ function getValueAtPath(bag, path) {
7
+ let current = bag;
8
+ for (const key of path.split('.')){
9
+ if (current === null || typeof current !== 'object') return undefined;
10
+ current = current[key];
11
+ }
12
+ return current;
13
+ }
14
+ /**
15
+ * Sets a value at a dotted path, creating intermediate objects. Mutates `bag`: callers hold a copy.
16
+ */ function setValueAtPath(bag, path, value) {
17
+ const keys = path.split('.');
18
+ let current = bag;
19
+ for (const key of keys.slice(0, -1)){
20
+ const next = current[key];
21
+ if (next === null || typeof next !== 'object' || Array.isArray(next)) {
22
+ current[key] = {};
23
+ }
24
+ current = current[key];
25
+ }
26
+ current[keys[keys.length - 1]] = value;
27
+ }
28
+ /**
29
+ * Removes the value at a dotted path, leaving intermediate objects in place. Mutates `bag`.
30
+ */ function removeValueAtPath(bag, path) {
31
+ const keys = path.split('.');
32
+ let current = bag;
33
+ for (const key of keys.slice(0, -1)){
34
+ if (current === null || typeof current !== 'object') return;
35
+ current = current[key];
36
+ }
37
+ if (current !== null && typeof current === 'object') {
38
+ delete current[keys[keys.length - 1]];
39
+ }
40
+ }
41
+ /**
42
+ * A copy of plain JSON-shaped data that shares nothing with the original.
43
+ */ function cloneData(value) {
44
+ return structuredClone(value);
45
+ }
46
+
47
+ export { cloneData, getValueAtPath, removeValueAtPath, setValueAtPath };
48
+ //# sourceMappingURL=pathAccess.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pathAccess.js","sources":["../../../editing/pathAccess.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\n/**\n * Reads a value at a dotted path in a plain object - `a.b.c` reads `bag.a.b.c` - or `undefined` when any step is\n * missing.\n */\nexport function getValueAtPath(bag: Record<string, unknown>, path: string): unknown {\n let current: unknown = bag;\n for (const key of path.split('.')) {\n if (current === null || typeof current !== 'object') return undefined;\n current = (current as Record<string, unknown>)[key];\n }\n\n return current;\n}\n\n/**\n * Whether a dotted path holds a value.\n */\nexport function hasValueAtPath(bag: Record<string, unknown>, path: string): boolean {\n return getValueAtPath(bag, path) !== undefined;\n}\n\n/**\n * Sets a value at a dotted path, creating intermediate objects. Mutates `bag`: callers hold a copy.\n */\nexport function setValueAtPath(bag: Record<string, unknown>, path: string, value: unknown): void {\n const keys = path.split('.');\n let current = bag;\n for (const key of keys.slice(0, -1)) {\n const next = current[key];\n if (next === null || typeof next !== 'object' || Array.isArray(next)) {\n current[key] = {};\n }\n\n current = current[key] as Record<string, unknown>;\n }\n\n current[keys[keys.length - 1]] = value;\n}\n\n/**\n * Removes the value at a dotted path, leaving intermediate objects in place. Mutates `bag`.\n */\nexport function removeValueAtPath(bag: Record<string, unknown>, path: string): void {\n const keys = path.split('.');\n let current: unknown = bag;\n for (const key of keys.slice(0, -1)) {\n if (current === null || typeof current !== 'object') return;\n current = (current as Record<string, unknown>)[key];\n }\n\n if (current !== null && typeof current === 'object') {\n delete (current as Record<string, unknown>)[keys[keys.length - 1]];\n }\n}\n\n/**\n * A copy of plain JSON-shaped data that shares nothing with the original.\n */\nexport function cloneData<T>(value: T): T {\n return structuredClone(value);\n}\n\n/**\n * Whether two plain values are structurally equal.\n */\nexport function dataEquals(left: unknown, right: unknown): boolean {\n if (left === right) return true;\n if (left === null || right === null || typeof left !== 'object' || typeof right !== 'object') return false;\n if (Array.isArray(left) !== Array.isArray(right)) return false;\n\n const leftKeys = Object.keys(left as object);\n const rightKeys = Object.keys(right as object);\n if (leftKeys.length !== rightKeys.length) return false;\n\n return leftKeys.every(key =>\n Object.prototype.hasOwnProperty.call(right, key)\n && dataEquals((left as Record<string, unknown>)[key], (right as Record<string, unknown>)[key]));\n}\n"],"names":["getValueAtPath","bag","path","current","key","split","undefined","setValueAtPath","value","keys","slice","next","Array","isArray","length","removeValueAtPath","cloneData","structuredClone"],"mappings":"AAAA;AACA;AAEA;;;AAGC,IACM,SAASA,cAAAA,CAAeC,GAA4B,EAAEC,IAAY,EAAA;AACrE,IAAA,IAAIC,OAAAA,GAAmBF,GAAAA;AACvB,IAAA,KAAK,MAAMG,GAAAA,IAAOF,IAAAA,CAAKG,KAAK,CAAC,GAAA,CAAA,CAAM;AAC/B,QAAA,IAAIF,OAAAA,KAAY,IAAA,IAAQ,OAAOA,OAAAA,KAAY,UAAU,OAAOG,SAAAA;QAC5DH,OAAAA,GAAWA,OAAmC,CAACC,GAAAA,CAAI;AACvD,IAAA;IAEA,OAAOD,OAAAA;AACX;AASA;;AAEC,IACM,SAASI,cAAAA,CAAeN,GAA4B,EAAEC,IAAY,EAAEM,KAAc,EAAA;IACrF,MAAMC,IAAAA,GAAOP,IAAAA,CAAKG,KAAK,CAAC,GAAA,CAAA;AACxB,IAAA,IAAIF,OAAAA,GAAUF,GAAAA;AACd,IAAA,KAAK,MAAMG,GAAAA,IAAOK,IAAAA,CAAKC,KAAK,CAAC,CAAA,EAAG,EAAC,CAAA,CAAI;QACjC,MAAMC,IAAAA,GAAOR,OAAO,CAACC,GAAAA,CAAI;QACzB,IAAIO,IAAAA,KAAS,QAAQ,OAAOA,IAAAA,KAAS,YAAYC,KAAAA,CAAMC,OAAO,CAACF,IAAAA,CAAAA,EAAO;YAClER,OAAO,CAACC,GAAAA,CAAI,GAAG,EAAC;AACpB,QAAA;QAEAD,OAAAA,GAAUA,OAAO,CAACC,GAAAA,CAAI;AAC1B,IAAA;IAEAD,OAAO,CAACM,IAAI,CAACA,IAAAA,CAAKK,MAAM,GAAG,CAAA,CAAE,CAAC,GAAGN,KAAAA;AACrC;AAEA;;AAEC,IACM,SAASO,iBAAAA,CAAkBd,GAA4B,EAAEC,IAAY,EAAA;IACxE,MAAMO,IAAAA,GAAOP,IAAAA,CAAKG,KAAK,CAAC,GAAA,CAAA;AACxB,IAAA,IAAIF,OAAAA,GAAmBF,GAAAA;AACvB,IAAA,KAAK,MAAMG,GAAAA,IAAOK,IAAAA,CAAKC,KAAK,CAAC,CAAA,EAAG,EAAC,CAAA,CAAI;AACjC,QAAA,IAAIP,OAAAA,KAAY,IAAA,IAAQ,OAAOA,OAAAA,KAAY,QAAA,EAAU;QACrDA,OAAAA,GAAWA,OAAmC,CAACC,GAAAA,CAAI;AACvD,IAAA;AAEA,IAAA,IAAID,OAAAA,KAAY,IAAA,IAAQ,OAAOA,OAAAA,KAAY,QAAA,EAAU;QACjD,OAAQA,OAAmC,CAACM,IAAI,CAACA,IAAAA,CAAKK,MAAM,GAAG,CAAA,CAAE,CAAC;AACtE,IAAA;AACJ;AAEA;;IAGO,SAASE,SAAAA,CAAaR,KAAQ,EAAA;AACjC,IAAA,OAAOS,eAAAA,CAAgBT,KAAAA,CAAAA;AAC3B;;"}
@@ -0,0 +1,15 @@
1
+ import { PropertyDescriptor, ResetPropertyEdit, SceneDiagnostic, SceneDocument, SetPropertyEdit } from '@cratis/scene.model';
2
+ import { NodeRecord } from './DocumentIndex';
3
+ import { EditSession } from './EditSession';
4
+ export declare function resolveEditableProperty(session: EditSession, nodeId: string, path: string, diagnostics: SceneDiagnostic[]): {
5
+ record: NodeRecord;
6
+ descriptor: PropertyDescriptor;
7
+ } | undefined;
8
+ export declare function checkValue(session: EditSession, descriptor: PropertyDescriptor, value: unknown, context: {
9
+ nodeId?: string;
10
+ component?: string;
11
+ instance?: string;
12
+ }, diagnostics: SceneDiagnostic[]): boolean;
13
+ export declare function applySetProperty(session: EditSession, edit: SetPropertyEdit, clone: SceneDocument, diagnostics: SceneDiagnostic[]): void;
14
+ export declare function applyResetProperty(session: EditSession, edit: ResetPropertyEdit, clone: SceneDocument, diagnostics: SceneDiagnostic[]): void;
15
+ //# sourceMappingURL=propertyEdits.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"propertyEdits.d.ts","sourceRoot":"","sources":["../../../editing/propertyEdits.ts"],"names":[],"mappings":"AAGA,OAAO,EACa,kBAAkB,EAAmC,iBAAiB,EAAE,eAAe,EAAE,aAAa,EACvG,eAAe,EACjC,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAQ5C,wBAAgB,uBAAuB,CACnC,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,eAAe,EAAE,GAC/B;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,UAAU,EAAE,kBAAkB,CAAA;CAAE,GAAG,SAAS,CA+BpE;AAOD,wBAAgB,UAAU,CAAC,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,kBAAkB,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,WAAW,EAAE,eAAe,EAAE,GAAG,OAAO,CAgB7M;AAaD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,eAAe,EAAE,GAAG,IAAI,CASxI;AAKD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,eAAe,EAAE,GAAG,IAAI,CAa5I"}
@@ -0,0 +1,113 @@
1
+ import { DiagnosticCode, PropertyValueType, SceneNodeKind } from '@cratis/scene.model';
2
+ import { describeNode } from './describeNode.js';
3
+ import { errorDiagnostic } from './diagnostics.js';
4
+ import { mirroredPaths, getAtPath } from './documentPaths.js';
5
+ import { removeValueAtPath, setValueAtPath, cloneData } from './pathAccess.js';
6
+ import { validateBinding } from './validateBinding.js';
7
+ import { validateValue } from './validateValue.js';
8
+
9
+ // Copyright (c) Cratis. All rights reserved.
10
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
11
+ /**
12
+ * Finds the node and descriptor an edit of a property addresses, or says why it cannot.
13
+ */ function resolveEditableProperty(session, nodeId, path, diagnostics) {
14
+ const record = session.index.nodes.get(nodeId);
15
+ if (!record) {
16
+ diagnostics.push(errorDiagnostic(DiagnosticCode.UnknownNode, `There is no node '${nodeId}'.`, {
17
+ nodeId
18
+ }));
19
+ return undefined;
20
+ }
21
+ if (!session.isLocal(record)) {
22
+ diagnostics.push(errorDiagnostic(DiagnosticCode.NodeNotEditable, `'${nodeId}' is inherited from '${session.sourceOf(record)}'. An exposed property is configured with an instance edit, not by changing the node.`, {
23
+ nodeId,
24
+ path
25
+ }));
26
+ return undefined;
27
+ }
28
+ const description = describeNode(record, session.context.catalog);
29
+ const descriptor = description.properties.find((candidate)=>candidate.path === path);
30
+ if (!descriptor) {
31
+ diagnostics.push(errorDiagnostic(description.diagnostics.length > 0 ? DiagnosticCode.MissingComponentDescriptor : DiagnosticCode.UnknownProperty, description.diagnostics[0]?.message ?? `'${record.typeId}' has no property '${path}'.`, {
32
+ nodeId,
33
+ path
34
+ }));
35
+ return undefined;
36
+ }
37
+ if (descriptor.readOnly) {
38
+ diagnostics.push(errorDiagnostic(DiagnosticCode.ReadOnlyProperty, `'${descriptor.label}' is read-only.`, {
39
+ nodeId,
40
+ path
41
+ }));
42
+ return undefined;
43
+ }
44
+ return {
45
+ record,
46
+ descriptor
47
+ };
48
+ }
49
+ /**
50
+ * Checks a value for a property, including a query binding against the host's candidates.
51
+ *
52
+ * @returns Whether the value is acceptable; the reasons are added to `diagnostics`.
53
+ */ function checkValue(session, descriptor, value, context, diagnostics) {
54
+ const problem = validateValue(descriptor, value);
55
+ if (problem) {
56
+ diagnostics.push(errorDiagnostic(DiagnosticCode.InvalidValue, `'${descriptor.label}': ${problem}.`, {
57
+ ...context,
58
+ path: descriptor.path
59
+ }));
60
+ return false;
61
+ }
62
+ const candidates = session.context.queryCandidates;
63
+ if (descriptor.valueType === PropertyValueType.QueryReference && candidates && typeof value === 'object' && value !== null) {
64
+ const binding = value;
65
+ const problems = validateBinding(descriptor, candidates.find((candidate)=>candidate.id === binding.queryId), binding);
66
+ diagnostics.push(...problems.map((problemDiagnostic)=>({
67
+ ...problemDiagnostic,
68
+ ...context
69
+ })));
70
+ return problems.length === 0;
71
+ }
72
+ return true;
73
+ }
74
+ function bagFor(root, record, path) {
75
+ const target = getAtPath(root, path);
76
+ if (!target) return undefined;
77
+ const isComponent = record.kind === SceneNodeKind.Element && target.componentName !== undefined;
78
+ if (!isComponent) return target;
79
+ return target.properties ??= {};
80
+ }
81
+ /**
82
+ * Applies a property set to a copy of the document.
83
+ */ function applySetProperty(session, edit, clone, diagnostics) {
84
+ const resolved = resolveEditableProperty(session, edit.nodeId, edit.path, diagnostics);
85
+ if (!resolved) return;
86
+ if (!checkValue(session, resolved.descriptor, edit.value, {
87
+ nodeId: edit.nodeId
88
+ }, diagnostics)) return;
89
+ for (const path of mirroredPaths(resolved.record.mirror, resolved.record.path)){
90
+ const bag = bagFor(clone, resolved.record, path);
91
+ if (bag) setValueAtPath(bag, edit.path, cloneData(edit.value));
92
+ }
93
+ }
94
+ /**
95
+ * Applies a property reset to a copy of the document.
96
+ */ function applyResetProperty(session, edit, clone, diagnostics) {
97
+ const resolved = resolveEditableProperty(session, edit.nodeId, edit.path, diagnostics);
98
+ if (!resolved) return;
99
+ if (resolved.descriptor.constraints?.required && resolved.descriptor.default === undefined) {
100
+ diagnostics.push(errorDiagnostic(DiagnosticCode.InvalidValue, `'${resolved.descriptor.label}' is required and has no default to go back to.`, {
101
+ nodeId: edit.nodeId,
102
+ path: edit.path
103
+ }));
104
+ return;
105
+ }
106
+ for (const path of mirroredPaths(resolved.record.mirror, resolved.record.path)){
107
+ const bag = bagFor(clone, resolved.record, path);
108
+ if (bag) removeValueAtPath(bag, edit.path);
109
+ }
110
+ }
111
+
112
+ export { applyResetProperty, applySetProperty, checkValue, resolveEditableProperty };
113
+ //# sourceMappingURL=propertyEdits.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"propertyEdits.js","sources":["../../../editing/propertyEdits.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport {\n DiagnosticCode, PropertyDescriptor, PropertyValueType, QueryBinding, ResetPropertyEdit, SceneDiagnostic, SceneDocument,\n SceneNodeKind, SetPropertyEdit,\n} from '@cratis/scene.model';\nimport { describeNode } from './describeNode';\nimport { errorDiagnostic } from './diagnostics';\nimport { NodeRecord } from './DocumentIndex';\nimport { getAtPath, mirroredPaths } from './documentPaths';\nimport { EditSession } from './EditSession';\nimport { cloneData, removeValueAtPath, setValueAtPath } from './pathAccess';\nimport { validateBinding } from './validateBinding';\nimport { validateValue } from './validateValue';\n\n/**\n * Finds the node and descriptor an edit of a property addresses, or says why it cannot.\n */\nexport function resolveEditableProperty(\n session: EditSession,\n nodeId: string,\n path: string,\n diagnostics: SceneDiagnostic[],\n): { record: NodeRecord; descriptor: PropertyDescriptor } | undefined {\n const record = session.index.nodes.get(nodeId);\n if (!record) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.UnknownNode, `There is no node '${nodeId}'.`, { nodeId }));\n return undefined;\n }\n\n if (!session.isLocal(record)) {\n diagnostics.push(errorDiagnostic(\n DiagnosticCode.NodeNotEditable,\n `'${nodeId}' is inherited from '${session.sourceOf(record)}'. An exposed property is configured with an instance edit, not by changing the node.`,\n { nodeId, path }));\n return undefined;\n }\n\n const description = describeNode(record, session.context.catalog);\n const descriptor = description.properties.find(candidate => candidate.path === path);\n if (!descriptor) {\n diagnostics.push(errorDiagnostic(\n description.diagnostics.length > 0 ? DiagnosticCode.MissingComponentDescriptor : DiagnosticCode.UnknownProperty,\n description.diagnostics[0]?.message ?? `'${record.typeId}' has no property '${path}'.`,\n { nodeId, path }));\n return undefined;\n }\n\n if (descriptor.readOnly) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.ReadOnlyProperty, `'${descriptor.label}' is read-only.`, { nodeId, path }));\n return undefined;\n }\n\n return { record, descriptor };\n}\n\n/**\n * Checks a value for a property, including a query binding against the host's candidates.\n *\n * @returns Whether the value is acceptable; the reasons are added to `diagnostics`.\n */\nexport function checkValue(session: EditSession, descriptor: PropertyDescriptor, value: unknown, context: { nodeId?: string; component?: string; instance?: string }, diagnostics: SceneDiagnostic[]): boolean {\n const problem = validateValue(descriptor, value);\n if (problem) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.InvalidValue, `'${descriptor.label}': ${problem}.`, { ...context, path: descriptor.path }));\n return false;\n }\n\n const candidates = session.context.queryCandidates;\n if (descriptor.valueType === PropertyValueType.QueryReference && candidates && typeof value === 'object' && value !== null) {\n const binding = value as QueryBinding;\n const problems = validateBinding(descriptor, candidates.find(candidate => candidate.id === binding.queryId), binding);\n diagnostics.push(...problems.map(problemDiagnostic => ({ ...problemDiagnostic, ...context })));\n return problems.length === 0;\n }\n\n return true;\n}\n\nfunction bagFor(root: SceneDocument, record: NodeRecord, path: string[]): Record<string, unknown> | undefined {\n const target = getAtPath(root, path) as Record<string, unknown> | undefined;\n if (!target) return undefined;\n const isComponent = record.kind === SceneNodeKind.Element && target.componentName !== undefined;\n if (!isComponent) return target;\n return (target.properties ??= {}) as Record<string, unknown>;\n}\n\n/**\n * Applies a property set to a copy of the document.\n */\nexport function applySetProperty(session: EditSession, edit: SetPropertyEdit, clone: SceneDocument, diagnostics: SceneDiagnostic[]): void {\n const resolved = resolveEditableProperty(session, edit.nodeId, edit.path, diagnostics);\n if (!resolved) return;\n if (!checkValue(session, resolved.descriptor, edit.value, { nodeId: edit.nodeId }, diagnostics)) return;\n\n for (const path of mirroredPaths(resolved.record.mirror, resolved.record.path)) {\n const bag = bagFor(clone, resolved.record, path as string[]);\n if (bag) setValueAtPath(bag, edit.path, cloneData(edit.value));\n }\n}\n\n/**\n * Applies a property reset to a copy of the document.\n */\nexport function applyResetProperty(session: EditSession, edit: ResetPropertyEdit, clone: SceneDocument, diagnostics: SceneDiagnostic[]): void {\n const resolved = resolveEditableProperty(session, edit.nodeId, edit.path, diagnostics);\n if (!resolved) return;\n\n if (resolved.descriptor.constraints?.required && resolved.descriptor.default === undefined) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.InvalidValue, `'${resolved.descriptor.label}' is required and has no default to go back to.`, { nodeId: edit.nodeId, path: edit.path }));\n return;\n }\n\n for (const path of mirroredPaths(resolved.record.mirror, resolved.record.path)) {\n const bag = bagFor(clone, resolved.record, path as string[]);\n if (bag) removeValueAtPath(bag, edit.path);\n }\n}\n"],"names":["resolveEditableProperty","session","nodeId","path","diagnostics","record","index","nodes","get","push","errorDiagnostic","DiagnosticCode","UnknownNode","undefined","isLocal","NodeNotEditable","sourceOf","description","describeNode","context","catalog","descriptor","properties","find","candidate","length","MissingComponentDescriptor","UnknownProperty","message","typeId","readOnly","ReadOnlyProperty","label","checkValue","value","problem","validateValue","InvalidValue","candidates","queryCandidates","valueType","PropertyValueType","QueryReference","binding","problems","validateBinding","id","queryId","map","problemDiagnostic","bagFor","root","target","getAtPath","isComponent","kind","SceneNodeKind","Element","componentName","applySetProperty","edit","clone","resolved","mirroredPaths","mirror","bag","setValueAtPath","cloneData","applyResetProperty","constraints","required","default","removeValueAtPath"],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import { EffectiveConfiguration, InstanceContribution } from '@cratis/scene.model';
2
+ import { DescriptorCatalog } from './DescriptorCatalog';
3
+ import { TemplateChain } from './TemplateChain';
4
+ export declare function resolveEffectiveConfiguration(templateChain: TemplateChain, instanceContributions: InstanceContribution[], catalog: DescriptorCatalog): EffectiveConfiguration;
5
+ //# sourceMappingURL=resolveEffectiveConfiguration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolveEffectiveConfiguration.d.ts","sourceRoot":"","sources":["../../../editing/resolveEffectiveConfiguration.ts"],"names":[],"mappings":"AAGA,OAAO,EAEH,sBAAsB,EAA0B,oBAAoB,EACvE,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,iBAAiB,EAA2B,MAAM,qBAAqB,CAAC;AAIjF,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAoGhD,wBAAgB,6BAA6B,CACzC,aAAa,EAAE,aAAa,EAC5B,qBAAqB,EAAE,oBAAoB,EAAE,EAC7C,OAAO,EAAE,iBAAiB,GAC3B,sBAAsB,CAsFxB"}
@@ -0,0 +1,198 @@
1
+ import { PropertyValueType, ValueSource, DiagnosticCode, CollectionOperation } from '@cratis/scene.model';
2
+ import { findComponentDescriptor } from './DescriptorCatalog.js';
3
+ import { errorDiagnostic } from './diagnostics.js';
4
+ import { computeExposureGrants, grantKey } from './exposureGrants.js';
5
+ import { cloneData, getValueAtPath, setValueAtPath } from './pathAccess.js';
6
+ import { validateItemValues, validateValue } from './validateValue.js';
7
+
8
+ // Copyright (c) Cratis. All rights reserved.
9
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
10
+ /**
11
+ * Splits a flat collection item as it is stored on an element - `{ id, label, ... }` - into its id and fields.
12
+ */ function toEffectiveItem(item, index) {
13
+ const { id, ...values } = item !== null && typeof item === 'object' ? item : {};
14
+ return {
15
+ id: typeof id === 'string' && id.length > 0 ? id : `owner-${index}`,
16
+ values,
17
+ origin: 'owner',
18
+ fixed: true
19
+ };
20
+ }
21
+ function toFlatItem(item) {
22
+ return {
23
+ id: item.id,
24
+ ...item.values
25
+ };
26
+ }
27
+ function scalarValue(grant, matching, instance, current, diagnostics) {
28
+ for (const contribution of matching){
29
+ const problem = contribution.value === undefined ? 'a value is required' : validateValue(grant.descriptor, contribution.value);
30
+ if (problem) {
31
+ diagnostics.push(errorDiagnostic(DiagnosticCode.ContributionTypeMismatch, `The saved value of '${grant.path}' set by '${instance}' is ignored: ${problem}. It is kept, and applies again when it fits.`, {
32
+ instance,
33
+ component: grant.component,
34
+ path: grant.path
35
+ }));
36
+ continue;
37
+ }
38
+ current.value = contribution.value;
39
+ current.source = ValueSource.Instance;
40
+ current.contributedBy = instance;
41
+ }
42
+ }
43
+ function collectionValue(grant, matching, instance, items, diagnostics) {
44
+ let contributed = false;
45
+ for (const contribution of matching){
46
+ const context = {
47
+ instance,
48
+ component: grant.component,
49
+ path: grant.path
50
+ };
51
+ if (contribution.items === undefined) {
52
+ diagnostics.push(errorDiagnostic(DiagnosticCode.ContributionTypeMismatch, `The saved value of '${grant.path}' set by '${instance}' is ignored: a collection takes items.`, context));
53
+ continue;
54
+ }
55
+ if (contribution.items.length > 0 && !grant.operations.includes(CollectionOperation.Add)) {
56
+ diagnostics.push(errorDiagnostic(DiagnosticCode.ContributionOperationNotPermitted, `'${instance}' has items in '${grant.path}', but adding items is not exposed. They are ignored and kept.`, context));
57
+ continue;
58
+ }
59
+ for (const item of contribution.items){
60
+ const itemContext = {
61
+ ...context,
62
+ itemId: item.id
63
+ };
64
+ if (items.some((existing)=>existing.id === item.id)) {
65
+ diagnostics.push(errorDiagnostic(DiagnosticCode.DuplicateCollectionItem, `The item id '${item.id}' in '${grant.path}' is already used.`, itemContext));
66
+ continue;
67
+ }
68
+ const values = {};
69
+ for (const [field, value] of Object.entries(item.values)){
70
+ if (grant.editableFields !== undefined && !grant.editableFields.includes(field)) {
71
+ diagnostics.push(errorDiagnostic(DiagnosticCode.ContributionOperationNotPermitted, `The field '${field}' of '${grant.path}' is not exposed for editing.`, itemContext));
72
+ continue;
73
+ }
74
+ const problem = validateItemValues(grant.descriptor.item, {
75
+ [field]: value
76
+ }).find((candidate)=>candidate.field === field);
77
+ if (problem) {
78
+ diagnostics.push(errorDiagnostic(problem.problem.startsWith('is not a field') ? DiagnosticCode.UnknownCollectionField : DiagnosticCode.ContributionTypeMismatch, `The field '${field}' of an item in '${grant.path}' is ignored: ${problem.problem}.`, itemContext));
79
+ continue;
80
+ }
81
+ values[field] = value;
82
+ }
83
+ items.push({
84
+ id: item.id,
85
+ values,
86
+ origin: instance,
87
+ fixed: false
88
+ });
89
+ contributed = true;
90
+ }
91
+ }
92
+ return contributed;
93
+ }
94
+ /**
95
+ * Resolves what every configurable component in a template chain is worth: the owner's own values, with each
96
+ * instance's contributions applied in nesting order.
97
+ *
98
+ * This is the one merge. The editor shows its result and the runtime renders from it, so what an author sees is
99
+ * what Play renders. Order is fixed: the owner's value first, then each level from the outermost inwards, so a
100
+ * later level wins a scalar and appends to a collection after the earlier ones.
101
+ *
102
+ * Nothing in the persisted data is changed. A contribution that cannot apply - the exposure was withdrawn, the
103
+ * property's type changed, the component is gone - is reported in `diagnostics` and left out of the result, and
104
+ * stays in `instanceContributions`, so restoring the exposure brings its value back.
105
+ *
106
+ * @param templateChain The nesting, from {@link resolveTemplateChain} or built by hand.
107
+ * @param instanceContributions What each instance has set.
108
+ * @param catalog The descriptors saying what each component supports.
109
+ */ function resolveEffectiveConfiguration(templateChain, instanceContributions, catalog) {
110
+ const grants = computeExposureGrants(templateChain, catalog);
111
+ const diagnostics = [
112
+ ...templateChain.diagnostics,
113
+ ...grants.diagnostics
114
+ ];
115
+ const handled = new Set();
116
+ const components = new Map();
117
+ for (const grant of grants.exposed){
118
+ const owner = templateChain.levels[grant.ownerLevel];
119
+ const element = owner.elements.find((candidate)=>candidate.id === grant.component);
120
+ let configuration = components.get(grant.component);
121
+ if (!configuration) {
122
+ configuration = {
123
+ component: grant.component,
124
+ owner: owner.owner,
125
+ properties: cloneData(element.properties),
126
+ values: []
127
+ };
128
+ components.set(grant.component, configuration);
129
+ }
130
+ const stored = getValueAtPath(element.properties, grant.path);
131
+ const base = stored === undefined ? cloneData(grant.descriptor.default) : cloneData(stored);
132
+ const isCollection = grant.descriptor.valueType === PropertyValueType.Collection;
133
+ const baseItems = isCollection && Array.isArray(base) ? base.map(toEffectiveItem) : [];
134
+ const items = [
135
+ ...baseItems
136
+ ];
137
+ const current = {
138
+ path: grant.path,
139
+ value: base,
140
+ source: stored === undefined ? ValueSource.Default : ValueSource.Local,
141
+ inheritedValue: base
142
+ };
143
+ let contributed = false;
144
+ for(let index = grant.ownerLevel + 1; index < templateChain.levels.length; index++){
145
+ const instance = templateChain.levels[index].instance;
146
+ if (!grants.byInstance.get(instance)?.has(grantKey(grant.component, grant.path))) continue;
147
+ const effectiveGrant = grants.byInstance.get(instance).get(grantKey(grant.component, grant.path));
148
+ const matching = instanceContributions.filter((contribution)=>contribution.instance === instance && contribution.component === grant.component && contribution.path === grant.path);
149
+ for (const contribution of matching)handled.add(contribution);
150
+ if (isCollection) {
151
+ if (collectionValue(effectiveGrant, matching, instance, items, diagnostics)) {
152
+ contributed = true;
153
+ current.contributedBy = instance;
154
+ }
155
+ } else {
156
+ scalarValue(effectiveGrant, matching, instance, current, diagnostics);
157
+ }
158
+ }
159
+ if (isCollection) {
160
+ current.items = items;
161
+ current.inheritedValue = baseItems.map(toFlatItem);
162
+ current.value = items.map(toFlatItem);
163
+ if (contributed) current.source = ValueSource.Instance;
164
+ }
165
+ if (current.value !== undefined) setValueAtPath(configuration.properties, grant.path, current.value);
166
+ configuration.values.push(current);
167
+ }
168
+ const levelOf = new Map(templateChain.levels.map((chainLevel, index)=>[
169
+ chainLevel.instance,
170
+ index
171
+ ]));
172
+ for (const contribution of instanceContributions){
173
+ const contributorLevel = levelOf.get(contribution.instance);
174
+ if (contributorLevel === undefined || handled.has(contribution)) continue;
175
+ const context = {
176
+ instance: contribution.instance,
177
+ component: contribution.component,
178
+ path: contribution.path
179
+ };
180
+ const owner = templateChain.levels.slice(0, contributorLevel).find((chainLevel)=>chainLevel.elements.some((element)=>element.id === contribution.component));
181
+ if (!owner) {
182
+ diagnostics.push(errorDiagnostic(DiagnosticCode.ContributionTargetMissing, `'${contribution.instance}' has saved values for '${contribution.component}', which is not in any layout or template above it. They are kept.`, context));
183
+ } else if (!findComponentDescriptor(catalog, owner.elements.find((element)=>element.id === contribution.component).componentName)) {
184
+ diagnostics.push(errorDiagnostic(DiagnosticCode.MissingComponentDescriptor, `'${contribution.instance}' has saved values for '${contribution.component}', but nothing describes that component any more. They are kept.`, context));
185
+ } else {
186
+ diagnostics.push(errorDiagnostic(DiagnosticCode.ContributionNotExposed, `'${contribution.instance}' has a saved value for '${contribution.path}' on '${contribution.component}', which is not exposed to it. It is ignored and kept.`, context));
187
+ }
188
+ }
189
+ return {
190
+ components: [
191
+ ...components.values()
192
+ ],
193
+ diagnostics
194
+ };
195
+ }
196
+
197
+ export { resolveEffectiveConfiguration };
198
+ //# sourceMappingURL=resolveEffectiveConfiguration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolveEffectiveConfiguration.js","sources":["../../../editing/resolveEffectiveConfiguration.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport {\n CollectionOperation, DiagnosticCode, EffectiveCollectionItem, EffectiveComponentConfiguration,\n EffectiveConfiguration, EffectivePropertyValue, InstanceContribution, PropertyValueType, SceneDiagnostic, ValueSource,\n} from '@cratis/scene.model';\nimport { DescriptorCatalog, findComponentDescriptor } from './DescriptorCatalog';\nimport { errorDiagnostic } from './diagnostics';\nimport { computeExposureGrants, ExposureGrant, grantKey } from './exposureGrants';\nimport { cloneData, getValueAtPath, setValueAtPath } from './pathAccess';\nimport { TemplateChain } from './TemplateChain';\nimport { validateItemValues, validateValue } from './validateValue';\n\n/**\n * Splits a flat collection item as it is stored on an element - `{ id, label, ... }` - into its id and fields.\n */\nfunction toEffectiveItem(item: unknown, index: number): EffectiveCollectionItem {\n const { id, ...values } = (item !== null && typeof item === 'object' ? item : {}) as Record<string, unknown>;\n return { id: typeof id === 'string' && id.length > 0 ? id : `owner-${index}`, values, origin: 'owner', fixed: true };\n}\n\nfunction toFlatItem(item: EffectiveCollectionItem): Record<string, unknown> {\n return { id: item.id, ...item.values };\n}\n\nfunction scalarValue(grant: ExposureGrant, matching: InstanceContribution[], instance: string, current: EffectivePropertyValue, diagnostics: SceneDiagnostic[]): void {\n for (const contribution of matching) {\n const problem = contribution.value === undefined ? 'a value is required' : validateValue(grant.descriptor, contribution.value);\n if (problem) {\n diagnostics.push(errorDiagnostic(\n DiagnosticCode.ContributionTypeMismatch,\n `The saved value of '${grant.path}' set by '${instance}' is ignored: ${problem}. It is kept, and applies again when it fits.`,\n { instance, component: grant.component, path: grant.path }));\n continue;\n }\n\n current.value = contribution.value;\n current.source = ValueSource.Instance;\n current.contributedBy = instance;\n }\n}\n\nfunction collectionValue(grant: ExposureGrant, matching: InstanceContribution[], instance: string, items: EffectiveCollectionItem[], diagnostics: SceneDiagnostic[]): boolean {\n let contributed = false;\n\n for (const contribution of matching) {\n const context = { instance, component: grant.component, path: grant.path };\n if (contribution.items === undefined) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.ContributionTypeMismatch, `The saved value of '${grant.path}' set by '${instance}' is ignored: a collection takes items.`, context));\n continue;\n }\n\n if (contribution.items.length > 0 && !grant.operations.includes(CollectionOperation.Add)) {\n diagnostics.push(errorDiagnostic(\n DiagnosticCode.ContributionOperationNotPermitted,\n `'${instance}' has items in '${grant.path}', but adding items is not exposed. They are ignored and kept.`,\n context));\n continue;\n }\n\n for (const item of contribution.items) {\n const itemContext = { ...context, itemId: item.id };\n if (items.some(existing => existing.id === item.id)) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.DuplicateCollectionItem, `The item id '${item.id}' in '${grant.path}' is already used.`, itemContext));\n continue;\n }\n\n const values: Record<string, unknown> = {};\n for (const [field, value] of Object.entries(item.values)) {\n if (grant.editableFields !== undefined && !grant.editableFields.includes(field)) {\n diagnostics.push(errorDiagnostic(DiagnosticCode.ContributionOperationNotPermitted, `The field '${field}' of '${grant.path}' is not exposed for editing.`, itemContext));\n continue;\n }\n\n const problem = validateItemValues(grant.descriptor.item, { [field]: value }).find(candidate => candidate.field === field);\n if (problem) {\n diagnostics.push(errorDiagnostic(\n problem.problem.startsWith('is not a field') ? DiagnosticCode.UnknownCollectionField : DiagnosticCode.ContributionTypeMismatch,\n `The field '${field}' of an item in '${grant.path}' is ignored: ${problem.problem}.`,\n itemContext));\n continue;\n }\n\n values[field] = value;\n }\n\n items.push({ id: item.id, values, origin: instance, fixed: false });\n contributed = true;\n }\n }\n\n return contributed;\n}\n\n/**\n * Resolves what every configurable component in a template chain is worth: the owner's own values, with each\n * instance's contributions applied in nesting order.\n *\n * This is the one merge. The editor shows its result and the runtime renders from it, so what an author sees is\n * what Play renders. Order is fixed: the owner's value first, then each level from the outermost inwards, so a\n * later level wins a scalar and appends to a collection after the earlier ones.\n *\n * Nothing in the persisted data is changed. A contribution that cannot apply - the exposure was withdrawn, the\n * property's type changed, the component is gone - is reported in `diagnostics` and left out of the result, and\n * stays in `instanceContributions`, so restoring the exposure brings its value back.\n *\n * @param templateChain The nesting, from {@link resolveTemplateChain} or built by hand.\n * @param instanceContributions What each instance has set.\n * @param catalog The descriptors saying what each component supports.\n */\nexport function resolveEffectiveConfiguration(\n templateChain: TemplateChain,\n instanceContributions: InstanceContribution[],\n catalog: DescriptorCatalog,\n): EffectiveConfiguration {\n const grants = computeExposureGrants(templateChain, catalog);\n const diagnostics: SceneDiagnostic[] = [...templateChain.diagnostics, ...grants.diagnostics];\n const handled = new Set<InstanceContribution>();\n const components = new Map<string, EffectiveComponentConfiguration>();\n\n for (const grant of grants.exposed) {\n const owner = templateChain.levels[grant.ownerLevel];\n const element = owner.elements.find(candidate => candidate.id === grant.component)!;\n\n let configuration = components.get(grant.component);\n if (!configuration) {\n configuration = { component: grant.component, owner: owner.owner, properties: cloneData(element.properties), values: [] };\n components.set(grant.component, configuration);\n }\n\n const stored = getValueAtPath(element.properties, grant.path);\n const base = stored === undefined ? cloneData(grant.descriptor.default) : cloneData(stored);\n const isCollection = grant.descriptor.valueType === PropertyValueType.Collection;\n const baseItems = isCollection && Array.isArray(base) ? base.map(toEffectiveItem) : [];\n const items = [...baseItems];\n\n const current: EffectivePropertyValue = {\n path: grant.path,\n value: base,\n source: stored === undefined ? ValueSource.Default : ValueSource.Local,\n inheritedValue: base,\n };\n let contributed = false;\n\n for (let index = grant.ownerLevel + 1; index < templateChain.levels.length; index++) {\n const instance = templateChain.levels[index].instance;\n if (!grants.byInstance.get(instance)?.has(grantKey(grant.component, grant.path))) continue;\n\n const effectiveGrant = grants.byInstance.get(instance)!.get(grantKey(grant.component, grant.path))!;\n const matching = instanceContributions.filter(contribution =>\n contribution.instance === instance && contribution.component === grant.component && contribution.path === grant.path);\n for (const contribution of matching) handled.add(contribution);\n\n if (isCollection) {\n if (collectionValue(effectiveGrant, matching, instance, items, diagnostics)) {\n contributed = true;\n current.contributedBy = instance;\n }\n } else {\n scalarValue(effectiveGrant, matching, instance, current, diagnostics);\n }\n }\n\n if (isCollection) {\n current.items = items;\n current.inheritedValue = baseItems.map(toFlatItem);\n current.value = items.map(toFlatItem);\n if (contributed) current.source = ValueSource.Instance;\n }\n\n if (current.value !== undefined) setValueAtPath(configuration.properties, grant.path, current.value);\n configuration.values.push(current);\n }\n\n const levelOf = new Map(templateChain.levels.map((chainLevel, index) => [chainLevel.instance, index]));\n for (const contribution of instanceContributions) {\n const contributorLevel = levelOf.get(contribution.instance);\n if (contributorLevel === undefined || handled.has(contribution)) continue;\n\n const context = { instance: contribution.instance, component: contribution.component, path: contribution.path };\n const owner = templateChain.levels.slice(0, contributorLevel).find(chainLevel => chainLevel.elements.some(element => element.id === contribution.component));\n if (!owner) {\n diagnostics.push(errorDiagnostic(\n DiagnosticCode.ContributionTargetMissing,\n `'${contribution.instance}' has saved values for '${contribution.component}', which is not in any layout or template above it. They are kept.`,\n context));\n } else if (!findComponentDescriptor(catalog, owner.elements.find(element => element.id === contribution.component)!.componentName)) {\n diagnostics.push(errorDiagnostic(\n DiagnosticCode.MissingComponentDescriptor,\n `'${contribution.instance}' has saved values for '${contribution.component}', but nothing describes that component any more. They are kept.`,\n context));\n } else {\n diagnostics.push(errorDiagnostic(\n DiagnosticCode.ContributionNotExposed,\n `'${contribution.instance}' has a saved value for '${contribution.path}' on '${contribution.component}', which is not exposed to it. It is ignored and kept.`,\n context));\n }\n }\n\n return { components: [...components.values()], diagnostics };\n}\n"],"names":["toEffectiveItem","item","index","id","values","length","origin","fixed","toFlatItem","scalarValue","grant","matching","instance","current","diagnostics","contribution","problem","value","undefined","validateValue","descriptor","push","errorDiagnostic","DiagnosticCode","ContributionTypeMismatch","path","component","source","ValueSource","Instance","contributedBy","collectionValue","items","contributed","context","operations","includes","CollectionOperation","Add","ContributionOperationNotPermitted","itemContext","itemId","some","existing","DuplicateCollectionItem","field","Object","entries","editableFields","validateItemValues","find","candidate","startsWith","UnknownCollectionField","resolveEffectiveConfiguration","templateChain","instanceContributions","catalog","grants","computeExposureGrants","handled","Set","components","Map","exposed","owner","levels","ownerLevel","element","elements","configuration","get","properties","cloneData","set","stored","getValueAtPath","base","default","isCollection","valueType","PropertyValueType","Collection","baseItems","Array","isArray","map","Default","Local","inheritedValue","byInstance","has","grantKey","effectiveGrant","filter","add","setValueAtPath","levelOf","chainLevel","contributorLevel","slice","ContributionTargetMissing","findComponentDescriptor","componentName","MissingComponentDescriptor","ContributionNotExposed"],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { EditingScope, SceneDocument } from '@cratis/scene.model';
2
+ import { TemplateChain } from './TemplateChain';
3
+ export declare function resolveTemplateChain(document: SceneDocument, scope: EditingScope): TemplateChain;
4
+ //# sourceMappingURL=resolveTemplateChain.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolveTemplateChain.d.ts","sourceRoot":"","sources":["../../../editing/resolveTemplateChain.ts"],"names":[],"mappings":"AAGA,OAAO,EAC6B,YAAY,EAA6C,aAAa,EAEzG,MAAM,qBAAqB,CAAC;AAI7B,OAAO,EAAE,aAAa,EAAsB,MAAM,iBAAiB,CAAC;AAoDpE,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,aAAa,EAAE,KAAK,EAAE,YAAY,GAAG,aAAa,CA8ChG"}