@kurot/ui-document 0.6.0 → 0.6.1

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 (49) hide show
  1. package/README.md +9 -5
  2. package/dist/kurot/document/create-asset-contract.d.ts +0 -4
  3. package/dist/kurot/document/create-asset-contract.d.ts.map +1 -1
  4. package/dist/kurot/document/create-asset-contract.js +0 -1
  5. package/dist/kurot/document/create-asset-contract.js.map +1 -1
  6. package/dist/kurot/model/UIAssetContract.d.ts +0 -4
  7. package/dist/kurot/model/UIAssetContract.d.ts.map +1 -1
  8. package/dist/kurot/model/index.d.ts +1 -0
  9. package/dist/kurot/model/index.d.ts.map +1 -1
  10. package/dist/kurot/model/index.js +1 -0
  11. package/dist/kurot/model/index.js.map +1 -1
  12. package/dist/kurot/model/synthetic-node-id.d.ts +9 -0
  13. package/dist/kurot/model/synthetic-node-id.d.ts.map +1 -0
  14. package/dist/kurot/model/synthetic-node-id.js +14 -0
  15. package/dist/kurot/model/synthetic-node-id.js.map +1 -0
  16. package/dist/kurot/serialization/xml/xml-node.d.ts +7 -2
  17. package/dist/kurot/serialization/xml/xml-node.d.ts.map +1 -1
  18. package/dist/kurot/serialization/xml/xml-node.js +141 -147
  19. package/dist/kurot/serialization/xml/xml-node.js.map +1 -1
  20. package/dist/kurot/serialization/xml/xml-values.d.ts +3 -11
  21. package/dist/kurot/serialization/xml/xml-values.d.ts.map +1 -1
  22. package/dist/kurot/serialization/xml/xml-values.js +24 -84
  23. package/dist/kurot/serialization/xml/xml-values.js.map +1 -1
  24. package/dist/kurot/serialization/xml.d.ts.map +1 -1
  25. package/dist/kurot/serialization/xml.js +85 -87
  26. package/dist/kurot/serialization/xml.js.map +1 -1
  27. package/dist/kurot/validation/validateUIAssetContract.d.ts.map +1 -1
  28. package/dist/kurot/validation/validateUIAssetContract.js +2 -7
  29. package/dist/kurot/validation/validateUIAssetContract.js.map +1 -1
  30. package/dist/kurot/validation/validateUIAssetModes.d.ts.map +1 -1
  31. package/dist/kurot/validation/validateUIAssetModes.js.map +1 -1
  32. package/dist/kurot/validation/validateUIComponentInstance.d.ts.map +1 -1
  33. package/dist/kurot/validation/validateUIComponentInstance.js +1 -7
  34. package/dist/kurot/validation/validateUIComponentInstance.js.map +1 -1
  35. package/dist/kurot/validation/validateUIDocument.d.ts.map +1 -1
  36. package/dist/kurot/validation/validateUIDocument.js +4 -17
  37. package/dist/kurot/validation/validateUIDocument.js.map +1 -1
  38. package/dist/kurot/validation/validationHelpers.d.ts.map +1 -1
  39. package/dist/kurot/validation/validationHelpers.js +1 -1
  40. package/dist/kurot/validation/validationHelpers.js.map +1 -1
  41. package/package.json +1 -1
  42. package/dist/kurot/serialization/xml/xml-contract-parser.d.ts +0 -7
  43. package/dist/kurot/serialization/xml/xml-contract-parser.d.ts.map +0 -1
  44. package/dist/kurot/serialization/xml/xml-contract-parser.js +0 -200
  45. package/dist/kurot/serialization/xml/xml-contract-parser.js.map +0 -1
  46. package/dist/kurot/serialization/xml/xml-contract-serializer.d.ts +0 -6
  47. package/dist/kurot/serialization/xml/xml-contract-serializer.d.ts.map +0 -1
  48. package/dist/kurot/serialization/xml/xml-contract-serializer.js +0 -111
  49. package/dist/kurot/serialization/xml/xml-contract-serializer.js.map +0 -1
package/README.md CHANGED
@@ -4,7 +4,7 @@ Headless semantic document foundation for Kurot UI tooling. It is intended to
4
4
  provide one format and one mutation model shared by the future visual UI
5
5
  builder, `@kurot/cli`, and Agent-driven UI generation.
6
6
 
7
- > **Early development (0.6.x).** KUI XML is the canonical authored format. The
7
+ > **Current release: 0.6.1.** KUI XML is the canonical authored format. The
8
8
  > schema remains pre-1.0, so later minor releases may still refine its contract.
9
9
 
10
10
  ## Installation
@@ -27,8 +27,8 @@ import {
27
27
  } from '@kurot/ui-document';
28
28
 
29
29
  const document = createUIDocument({
30
- id: 'main-screen',
31
- assetKind: 'screen',
30
+ id: 'game.MainSkin',
31
+ assetKind: 'appearance',
32
32
  root: createUINode({
33
33
  id: 'root',
34
34
  type: 'kui.Group',
@@ -51,6 +51,10 @@ const source = serializeUIDocument(document);
51
51
  `type` is an external registry key; this package does not import or instantiate
52
52
  the corresponding `@kurot/ui` class.
53
53
 
54
+ KUI XML serializes Skin documents only. Screen and reusable-component
55
+ documents are programmatic semantic models and do not share the authored Skin
56
+ file pipeline.
57
+
54
58
  ## Current capabilities
55
59
 
56
60
  - explicit screen, reusable-component, and appearance assets;
@@ -207,7 +211,7 @@ It defines the abstract semantic bases `kurot.DisplayObject`,
207
211
  `kui.ToggleButton`, `kui.ProgressBar`, and `kui.TextInput` nodes. `Group`
208
212
  accepts ordered children; the other concrete nodes are leaves.
209
213
 
210
- `kui.*` is the canonical Kurot UI namespace. Authored files use the
214
+ `kui.*` is the canonical Kurot UI namespace. Authored Skin files use the
211
215
  [`KUI XML format`](./docs/kui-xml.md); EUI names and EXML are not stored in the
212
216
  semantic document.
213
217
 
@@ -251,7 +255,7 @@ or network I/O, or model-provider integration. Those concerns belong to
251
255
  `@kurot/ui`, the visual builder, CLI orchestration, and Agent adapters
252
256
  respectively.
253
257
 
254
- `@kurot/ui-runtime@0.4.x` validates and materializes format-version-2 assets,
258
+ `@kurot/ui-runtime@0.5.x` validates and materializes format-version-2 assets,
255
259
  including reusable instances, parameter bindings, Slots, component variants,
256
260
  part overrides, design tokens, resource hooks, and native appearance
257
261
  skins/states. It also executes the bounded data, action, and transition
@@ -3,10 +3,6 @@ import type { UIAssetContract, UIDataBindingDefinition, UIParameterDefinition, U
3
3
  * Input accepted by createUIAssetContract.
4
4
  */
5
5
  export interface CreateUIAssetContractOptions {
6
- /**
7
- * Whether this appearance is the project's default for its target type.
8
- */
9
- readonly isDefault?: boolean;
10
6
  /**
11
7
  * Typed external data accepted by this asset.
12
8
  */
@@ -1 +1 @@
1
- {"version":3,"file":"create-asset-contract.d.ts","sourceRoot":"","sources":["../../../src/kurot/document/create-asset-contract.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,eAAe,EACf,uBAAuB,EACvB,qBAAqB,EACrB,gBAAgB,EAChB,0BAA0B,EAC1B,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,MAAM,6BAA6B,CAAC;AAErC;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC5C;;OAEG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAE7B;;OAEG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,eAAe,CAAC,YAAY,CAAC,CAAC;IAEpD;;OAEG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC,CAAC;IAE1E;;OAEG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,0BAA0B,CAAC,CAAC,CAAC;IAExE;;OAEG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAEhC;;OAEG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAE7B;;OAEG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC,CAAC;IAEtE;;OAEG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAE5D;;OAEG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAE5D;;OAEG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC;IAE9D;;OAEG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC,CAAC;CAClE;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACpC,OAAO,GAAE,4BAAiC,GACxC,eAAe,CAgBjB"}
1
+ {"version":3,"file":"create-asset-contract.d.ts","sourceRoot":"","sources":["../../../src/kurot/document/create-asset-contract.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,eAAe,EACf,uBAAuB,EACvB,qBAAqB,EACrB,gBAAgB,EAChB,0BAA0B,EAC1B,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,MAAM,6BAA6B,CAAC;AAErC;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC5C;;OAEG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,eAAe,CAAC,YAAY,CAAC,CAAC;IAEpD;;OAEG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC,CAAC;IAE1E;;OAEG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,0BAA0B,CAAC,CAAC,CAAC;IAExE;;OAEG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAEhC;;OAEG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAE7B;;OAEG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC,CAAC;IAEtE;;OAEG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAE5D;;OAEG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAE5D;;OAEG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC;IAE9D;;OAEG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC,CAAC;CAClE;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACpC,OAAO,GAAE,4BAAiC,GACxC,eAAe,CAejB"}
@@ -3,7 +3,6 @@
3
3
  */
4
4
  export function createUIAssetContract(options = {}) {
5
5
  return {
6
- ...(options.isDefault === undefined ? {} : { isDefault: options.isDefault }),
7
6
  ...(options.componentType === undefined
8
7
  ? {}
9
8
  : { componentType: options.componentType }),
@@ -1 +1 @@
1
- {"version":3,"file":"create-asset-contract.js","sourceRoot":"","sources":["../../../src/kurot/document/create-asset-contract.ts"],"names":[],"mappings":"AAuEA;;GAEG;AACH,MAAM,UAAU,qBAAqB,CACpC,UAAwC,EAAE;IAE1C,OAAO;QACN,GAAG,CAAC,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC;QAC5E,GAAG,CAAC,OAAO,CAAC,aAAa,KAAK,SAAS;YACtC,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC;QAC5C,GAAG,CAAC,OAAO,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC;QAC/E,UAAU,EAAE,EAAE,GAAG,OAAO,CAAC,UAAU,EAAE;QACrC,KAAK,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,EAAE;QAC3B,KAAK,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,EAAE;QAC3B,MAAM,EAAE,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE;QAC7B,QAAQ,EAAE,EAAE,GAAG,OAAO,CAAC,QAAQ,EAAE;QACjC,UAAU,EAAE,EAAE,GAAG,OAAO,CAAC,UAAU,EAAE;QACrC,YAAY,EAAE,EAAE,GAAG,OAAO,CAAC,YAAY,EAAE;QACzC,OAAO,EAAE,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE;KAC/B,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"create-asset-contract.js","sourceRoot":"","sources":["../../../src/kurot/document/create-asset-contract.ts"],"names":[],"mappings":"AAkEA;;GAEG;AACH,MAAM,UAAU,qBAAqB,CACpC,UAAwC,EAAE;IAE1C,OAAO;QACN,GAAG,CAAC,OAAO,CAAC,aAAa,KAAK,SAAS;YACtC,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC;QAC5C,GAAG,CAAC,OAAO,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC;QAC/E,UAAU,EAAE,EAAE,GAAG,OAAO,CAAC,UAAU,EAAE;QACrC,KAAK,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,EAAE;QAC3B,KAAK,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,EAAE;QAC3B,MAAM,EAAE,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE;QAC7B,QAAQ,EAAE,EAAE,GAAG,OAAO,CAAC,QAAQ,EAAE;QACjC,UAAU,EAAE,EAAE,GAAG,OAAO,CAAC,UAAU,EAAE;QACrC,YAAY,EAAE,EAAE,GAAG,OAAO,CAAC,YAAY,EAAE;QACzC,OAAO,EAAE,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE;KAC/B,CAAC;AACH,CAAC"}
@@ -171,10 +171,6 @@ export interface UIVariantDefinition {
171
171
  * Public authoring contract exposed by one UI asset.
172
172
  */
173
173
  export interface UIAssetContract {
174
- /**
175
- * Whether this appearance is the project's default for its target type.
176
- */
177
- readonly isDefault?: boolean;
178
174
  /**
179
175
  * Canonical component key published by a component asset.
180
176
  */
@@ -1 +1 @@
1
- {"version":3,"file":"UIAssetContract.d.ts","sourceRoot":"","sources":["../../../src/kurot/model/UIAssetContract.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"UIAssetContract.d.ts","sourceRoot":"","sources":["../../../src/kurot/model/UIAssetContract.ts"],"names":[],"mappings":"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"}
@@ -6,5 +6,6 @@ export { isUIAssetReference, isUIDesignTokenReference, isUIResourceReference, UI
6
6
  export { UI_DOCUMENT_KIND } from './UIDocument.js';
7
7
  export type { UIDocument } from './UIDocument.js';
8
8
  export type { UINode } from './UINode.js';
9
+ export { isSyntheticNodeId } from './synthetic-node-id.js';
9
10
  export type { UIPropertyObject, UIPropertyPrimitive, UIPropertyValue, } from './UIPropertyValue.js';
10
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/kurot/model/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,YAAY,EACX,eAAe,EACf,uBAAuB,EACvB,kBAAkB,EAClB,qBAAqB,EACrB,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,EACpB,0BAA0B,EAC1B,uBAAuB,EACvB,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,GACnB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EACX,mBAAmB,EACnB,kBAAkB,GAClB,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACX,gBAAgB,EAChB,qBAAqB,EACrB,sBAAsB,EACtB,iBAAiB,EACjB,mBAAmB,EACnB,cAAc,GACd,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACN,kBAAkB,EAClB,wBAAwB,EACxB,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,GACjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,YAAY,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,YAAY,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,YAAY,EACX,gBAAgB,EAChB,mBAAmB,EACnB,eAAe,GACf,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/kurot/model/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,YAAY,EACX,eAAe,EACf,uBAAuB,EACvB,kBAAkB,EAClB,qBAAqB,EACrB,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,EACpB,0BAA0B,EAC1B,uBAAuB,EACvB,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,GACnB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EACX,mBAAmB,EACnB,kBAAkB,GAClB,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACX,gBAAgB,EAChB,qBAAqB,EACrB,sBAAsB,EACtB,iBAAiB,EACjB,mBAAmB,EACnB,cAAc,GACd,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACN,kBAAkB,EAClB,wBAAwB,EACxB,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,GACjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,YAAY,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,YAAY,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,YAAY,EACX,gBAAgB,EAChB,mBAAmB,EACnB,eAAe,GACf,MAAM,sBAAsB,CAAC"}
@@ -1,3 +1,4 @@
1
1
  export { isUIAssetReference, isUIDesignTokenReference, isUIResourceReference, UI_DESIGN_TOKEN_TYPES, UI_RESOURCE_TYPES, } from './UIReference.js';
2
2
  export { UI_DOCUMENT_KIND } from './UIDocument.js';
3
+ export { isSyntheticNodeId } from './synthetic-node-id.js';
3
4
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/kurot/model/index.ts"],"names":[],"mappings":"AA4BA,OAAO,EACN,kBAAkB,EAClB,wBAAwB,EACxB,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,GACjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/kurot/model/index.ts"],"names":[],"mappings":"AA4BA,OAAO,EACN,kBAAkB,EAClB,wBAAwB,EACxB,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,GACjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAGnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Creates a deterministic semantic id for an unnamed authored node.
3
+ */
4
+ export declare function createSyntheticNodeId(path: string): string;
5
+ /**
6
+ * Returns whether an id exists only to connect the semantic model internally.
7
+ */
8
+ export declare function isSyntheticNodeId(id: string): boolean;
9
+ //# sourceMappingURL=synthetic-node-id.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"synthetic-node-id.d.ts","sourceRoot":"","sources":["../../../src/kurot/model/synthetic-node-id.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAErD"}
@@ -0,0 +1,14 @@
1
+ const SYNTHETIC_NODE_ID_PREFIX = '__kui_node_';
2
+ /**
3
+ * Creates a deterministic semantic id for an unnamed authored node.
4
+ */
5
+ export function createSyntheticNodeId(path) {
6
+ return `${SYNTHETIC_NODE_ID_PREFIX}${path.replaceAll('.', '_')}`;
7
+ }
8
+ /**
9
+ * Returns whether an id exists only to connect the semantic model internally.
10
+ */
11
+ export function isSyntheticNodeId(id) {
12
+ return id.startsWith(SYNTHETIC_NODE_ID_PREFIX);
13
+ }
14
+ //# sourceMappingURL=synthetic-node-id.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"synthetic-node-id.js","sourceRoot":"","sources":["../../../src/kurot/model/synthetic-node-id.ts"],"names":[],"mappings":"AAAA,MAAM,wBAAwB,GAAG,aAAa,CAAC;AAE/C;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAAY;IACjD,OAAO,GAAG,wBAAwB,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC;AAClE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,EAAU;IAC3C,OAAO,EAAE,CAAC,UAAU,CAAC,wBAAwB,CAAC,CAAC;AAChD,CAAC"}
@@ -1,8 +1,13 @@
1
+ import type { UIPropertyOverride, UIStateDefinition } from '../../model/UIAssetContract.js';
1
2
  import type { UINode } from '../../model/UINode.js';
2
3
  import type { XMLElement } from './xml-parser.js';
3
4
  export interface XMLNamespaces {
4
5
  readonly prefixes: Readonly<Record<string, string>>;
5
6
  }
7
+ export interface XMLNodeParseContext extends XMLNamespaces {
8
+ readonly states: ReadonlySet<string>;
9
+ readonly stateOverrides: Map<string, UIPropertyOverride[]>;
10
+ }
6
11
  /**
7
12
  * Collects custom component namespace prefixes used by a node tree.
8
13
  */
@@ -10,9 +15,9 @@ export declare function collectNodePrefixes(node: UINode, prefixes: Set<string>)
10
15
  /**
11
16
  * Serializes one semantic node using component tags.
12
17
  */
13
- export declare function serializeNode(node: UINode, depth: number): string[];
18
+ export declare function serializeNode(node: UINode, depth: number, states?: Readonly<Record<string, UIStateDefinition>>): string[];
14
19
  /**
15
20
  * Parses one component element into a semantic node.
16
21
  */
17
- export declare function parseNode(element: XMLElement, namespaces: XMLNamespaces): UINode;
22
+ export declare function parseNode(element: XMLElement, context: XMLNodeParseContext, path?: string): UINode;
18
23
  //# sourceMappingURL=xml-node.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"xml-node.d.ts","sourceRoot":"","sources":["../../../../src/kurot/serialization/xml/xml-node.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAGpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAWlD,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACpD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,CAc7E;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CA+CnE;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,GAAG,MAAM,CA0ChF"}
1
+ {"version":3,"file":"xml-node.d.ts","sourceRoot":"","sources":["../../../../src/kurot/serialization/xml/xml-node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAC5F,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAKpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAOlD,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACpD;AAED,MAAM,WAAW,mBAAoB,SAAQ,aAAa;IACzD,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACrC,QAAQ,CAAC,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,kBAAkB,EAAE,CAAC,CAAC;CAC3D;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,CAO7E;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC5B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,MAAM,GAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAM,GACtD,MAAM,EAAE,CAiEV;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,mBAAmB,EAAE,IAAI,SAAM,GAAG,MAAM,CAyD/F"}
@@ -1,6 +1,10 @@
1
+ import { createSyntheticNodeId, isSyntheticNodeId } from '../../model/synthetic-node-id.js';
2
+ import { createKurotUIFoundationRegistry } from '../../catalog/kurot-ui-foundation.js';
1
3
  import { compareStrings } from '../../shared/strings.js';
2
- import { decodeXMLValue, encodeXMLValue, escapeXML, parseComplexValue, serializeComplexValue, } from './xml-values.js';
3
- const RESERVED_ATTRIBUTES = new Set(['appearance', 'appearanceVariant', 'id', 'xmlns']);
4
+ import { decodeXMLValue, encodeXMLValue, escapeXML } from './xml-values.js';
5
+ const RESERVED_ATTRIBUTES = new Set(['id', 'xmlns']);
6
+ const FOUNDATION_COMPONENTS = createKurotUIFoundationRegistry();
7
+ const LAYOUT_TYPES = new Set(['BasicLayout', 'HorizontalLayout', 'TileLayout', 'VerticalLayout']);
4
8
  /**
5
9
  * Collects custom component namespace prefixes used by a node tree.
6
10
  */
@@ -12,60 +16,65 @@ export function collectNodePrefixes(node, prefixes) {
12
16
  for (const child of node.children) {
13
17
  collectNodePrefixes(child, prefixes);
14
18
  }
15
- if (node.instance) {
16
- for (const nodes of Object.values(node.instance.slots)) {
17
- for (const child of nodes) {
18
- collectNodePrefixes(child, prefixes);
19
- }
20
- }
21
- }
22
19
  }
23
20
  /**
24
21
  * Serializes one semantic node using component tags.
25
22
  */
26
- export function serializeNode(node, depth) {
23
+ export function serializeNode(node, depth, states = {}) {
27
24
  const indent = ' '.repeat(depth);
28
25
  const tag = componentTag(node.type);
29
- const attributes = [`id="${escapeXML(node.id)}"`];
30
- const complex = [];
31
- if (node.appearance) {
32
- attributes.push(`appearance="${escapeXML(node.appearance.assetId)}"`);
33
- if (node.appearance.variant !== undefined) {
34
- attributes.push(`appearanceVariant="${escapeXML(node.appearance.variant)}"`);
35
- }
26
+ const attributes = isSyntheticNodeId(node.id) ? [] : [`id="${escapeXML(node.id)}"`];
27
+ const stateProperties = new Set();
28
+ let layout;
29
+ if (node.appearance !== undefined || node.instance !== undefined) {
30
+ throw new Error('Skin XML nodes do not serialize semantic asset composition metadata.');
36
31
  }
37
32
  for (const [name, value] of sortedEntries(node.properties)) {
38
- const encoded = encodeXMLValue(value);
39
- if (encoded === undefined || RESERVED_ATTRIBUTES.has(name) || name.startsWith('xmlns')) {
40
- complex.push([name, value]);
33
+ if (name === 'layout') {
34
+ layout = value;
35
+ continue;
41
36
  }
42
- else {
43
- attributes.push(`${name}="${escapeXML(encoded)}"`);
37
+ if (name.includes('.')) {
38
+ throw new Error(`Skin property name "${name}" must not contain a dot.`);
44
39
  }
45
- }
46
- if (complex.length === 0 && node.instance === undefined && node.children.length === 0) {
47
- return [`${indent}<${tag} ${attributes.join(' ')} />`];
48
- }
49
- const lines = [`${indent}<${tag} ${attributes.join(' ')}>`];
50
- if (complex.length > 0) {
51
- lines.push(`${indent} <properties>`);
52
- for (const [name, value] of complex) {
53
- const encoded = encodeXMLValue(value);
54
- if (encoded !== undefined) {
55
- lines.push(`${indent} <property name="${escapeXML(name)}" value="${escapeXML(encoded)}" />`);
40
+ const encoded = encodeXMLValue(value, propertyDefinition(node.type, name));
41
+ if (encoded === undefined || RESERVED_ATTRIBUTES.has(name) || name.startsWith('xmlns')) {
42
+ throw new Error(`Skin property "${name}" must be a scalar value.`);
43
+ }
44
+ attributes.push(`${name}="${escapeXML(encoded)}"`);
45
+ }
46
+ for (const [stateName, state] of Object.entries(states)) {
47
+ for (const override of state.overrides) {
48
+ if (override.targetId !== node.id)
49
+ continue;
50
+ if (override.property.includes('.')) {
51
+ throw new Error(`Skin state property name "${override.property}" must not contain a dot.`);
52
+ }
53
+ const stateProperty = `${override.property}.${stateName}`;
54
+ if (stateProperties.has(stateProperty)) {
55
+ throw new Error(`Skin XML cannot serialize duplicate state property "${stateProperty}".`);
56
56
  }
57
- else {
58
- lines.push(`${indent} <property name="${escapeXML(name)}">`);
59
- lines.push(...serializeComplexValue(value, depth + 3));
60
- lines.push(`${indent} </property>`);
57
+ stateProperties.add(stateProperty);
58
+ if (override.transition !== undefined) {
59
+ throw new Error(`Skin XML does not serialize transitions for state "${stateName}".`);
61
60
  }
61
+ const encoded = encodeXMLValue(override.value, propertyDefinition(node.type, override.property));
62
+ if (encoded === undefined) {
63
+ throw new Error(`State property "${override.property}.${stateName}" must be a scalar value.`);
64
+ }
65
+ attributes.push(`${stateProperty}="${escapeXML(encoded)}"`);
62
66
  }
63
- lines.push(`${indent} </properties>`);
64
67
  }
65
- if (node.instance)
66
- lines.push(...serializeInstance(node.instance, depth + 1));
68
+ const attributeSuffix = attributes.length === 0 ? '' : ` ${attributes.join(' ')}`;
69
+ if (layout === undefined && node.children.length === 0) {
70
+ return [`${indent}<${tag}${attributeSuffix} />`];
71
+ }
72
+ const lines = [`${indent}<${tag}${attributeSuffix}>`];
73
+ if (layout !== undefined) {
74
+ lines.push(...serializeLayout(layout, depth + 1));
75
+ }
67
76
  for (const child of node.children) {
68
- lines.push(...serializeNode(child, depth + 1));
77
+ lines.push(...serializeNode(child, depth + 1, states));
69
78
  }
70
79
  lines.push(`${indent}</${tag}>`);
71
80
  return lines;
@@ -73,133 +82,121 @@ export function serializeNode(node, depth) {
73
82
  /**
74
83
  * Parses one component element into a semantic node.
75
84
  */
76
- export function parseNode(element, namespaces) {
77
- const id = requiredAttribute(element, 'id');
85
+ export function parseNode(element, context, path = '0') {
86
+ const authoredId = element.attributes.id;
87
+ if (authoredId !== undefined && isSyntheticNodeId(authoredId)) {
88
+ throw new Error(`Skin component id "${authoredId}" uses a reserved internal prefix.`);
89
+ }
90
+ const id = authoredId ?? createSyntheticNodeId(path);
91
+ const type = componentType(element.name, context);
78
92
  const properties = {};
79
- let appearance;
80
- let instance;
81
93
  const children = [];
82
- const appearanceId = element.attributes.appearance;
83
- if (appearanceId !== undefined) {
84
- appearance = {
85
- kind: 'asset',
86
- assetId: appearanceId,
87
- ...(element.attributes.appearanceVariant === undefined
88
- ? {}
89
- : { variant: element.attributes.appearanceVariant }),
90
- };
91
- }
92
94
  for (const [name, value] of Object.entries(element.attributes)) {
93
95
  if (RESERVED_ATTRIBUTES.has(name) || name.startsWith('xmlns:'))
94
96
  continue;
95
- properties[name] = decodeXMLValue(value);
97
+ if (name === 'appearance' || name === 'appearanceVariant') {
98
+ throw new Error(`Skin component <${element.name}> does not support ${name}.`);
99
+ }
100
+ const stateSeparator = name.lastIndexOf('.');
101
+ if (stateSeparator !== -1) {
102
+ const property = name.slice(0, stateSeparator);
103
+ const stateName = name.slice(stateSeparator + 1);
104
+ if (property.length === 0 || !context.states.has(stateName)) {
105
+ throw new Error(`State property "${name}" references an undeclared state.`);
106
+ }
107
+ const overrides = context.stateOverrides.get(stateName);
108
+ if (overrides === undefined) {
109
+ throw new Error(`State "${stateName}" has no override collection.`);
110
+ }
111
+ overrides.push({
112
+ targetId: id,
113
+ property,
114
+ value: decodeXMLValue(value, propertyDefinition(type, property)),
115
+ });
116
+ continue;
117
+ }
118
+ properties[name] = decodeXMLValue(value, propertyDefinition(type, name));
96
119
  }
120
+ let childIndex = 0;
97
121
  for (const child of element.children) {
98
- if (child.name === 'properties') {
99
- parseProperties(child, properties);
122
+ if (child.name === 'layout') {
123
+ if (properties.layout !== undefined) {
124
+ throw new Error(`<${element.name}> contains duplicate layout metadata.`);
125
+ }
126
+ properties.layout = parseLayout(child);
100
127
  }
101
- else if (child.name === 'instance') {
102
- if (instance !== undefined)
103
- throw new Error(`<${element.name}> contains duplicate <instance> metadata.`);
104
- instance = parseInstance(child, namespaces);
128
+ else if (child.name === 'properties' || child.name === 'instance') {
129
+ throw new Error(`<${child.name}> is not Skin XML syntax.`);
105
130
  }
106
131
  else {
107
- children.push(parseNode(child, namespaces));
132
+ children.push(parseNode(child, context, `${path}.${childIndex}`));
133
+ childIndex++;
108
134
  }
109
135
  }
110
136
  return {
111
137
  id,
112
- type: componentType(element.name, namespaces),
138
+ type,
113
139
  properties,
114
- ...(instance === undefined ? {} : { instance }),
115
- ...(appearance === undefined ? {} : { appearance }),
116
140
  children,
117
141
  };
118
142
  }
119
- function serializeInstance(instance, depth) {
120
- const indent = ' '.repeat(depth);
121
- const variant = instance.variant === undefined ? '' : ` variant="${escapeXML(instance.variant)}"`;
122
- const lines = [`${indent}<instance source="${escapeXML(instance.source.assetId)}"${variant}>`];
123
- for (const [name, value] of sortedEntries(instance.parameters)) {
124
- lines.push(...serializeNamedValue('parameter', name, value, depth + 1));
125
- }
126
- for (const override of instance.overrides) {
127
- lines.push(...serializeOverride(override, depth + 1));
128
- }
129
- for (const [name, nodes] of sortedEntries(instance.slots)) {
130
- lines.push(`${indent} <slot name="${escapeXML(name)}">`);
131
- for (const node of nodes) {
132
- lines.push(...serializeNode(node, depth + 2));
133
- }
134
- lines.push(`${indent} </slot>`);
135
- }
136
- lines.push(`${indent}</instance>`);
137
- return lines;
138
- }
139
- function parseInstance(element, namespaces) {
140
- const parameters = {};
141
- const overrides = [];
142
- const slots = {};
143
- for (const child of element.children) {
144
- if (child.name === 'parameter') {
145
- parameters[requiredAttribute(child, 'name')] = parseNamedValue(child);
146
- }
147
- else if (child.name === 'override') {
148
- overrides.push({
149
- part: requiredAttribute(child, 'part'),
150
- property: requiredAttribute(child, 'property'),
151
- value: parseNamedValue(child),
152
- });
153
- }
154
- else if (child.name === 'slot') {
155
- const name = requiredAttribute(child, 'name');
156
- slots[name] = child.children.map(node => parseNode(node, namespaces));
157
- }
158
- else {
159
- throw new Error(`Unexpected <${child.name}> inside <instance>.`);
143
+ function serializeLayout(value, depth) {
144
+ const descriptor = requirePropertyObject(value, 'Layout descriptor');
145
+ const type = descriptor.type;
146
+ if (typeof type !== 'string' || !type.startsWith('kui.')) {
147
+ throw new Error('Layout descriptor requires a kui.* type.');
148
+ }
149
+ const name = type.slice('kui.'.length);
150
+ if (!LAYOUT_TYPES.has(name)) {
151
+ throw new Error(`Unsupported layout type "${type}".`);
152
+ }
153
+ const properties = descriptor.properties === undefined
154
+ ? {}
155
+ : requirePropertyObject(descriptor.properties, 'Layout properties');
156
+ const attributes = [];
157
+ for (const [property, propertyValue] of sortedEntries(properties)) {
158
+ const encoded = encodeXMLValue(propertyValue);
159
+ if (encoded === undefined) {
160
+ throw new Error(`Layout property "${property}" must be a scalar value.`);
160
161
  }
162
+ attributes.push(`${property}="${escapeXML(encoded)}"`);
161
163
  }
162
- return {
163
- source: { kind: 'asset', assetId: requiredAttribute(element, 'source') },
164
- parameters,
165
- ...(element.attributes.variant === undefined ? {} : { variant: element.attributes.variant }),
166
- overrides,
167
- slots,
168
- };
169
- }
170
- function serializeOverride(override, depth) {
171
- const attributes = `part="${escapeXML(override.part)}" property="${escapeXML(override.property)}"`;
172
- return serializeValueElement('override', attributes, override.value, depth);
173
- }
174
- function serializeNamedValue(tag, name, value, depth) {
175
- return serializeValueElement(tag, `name="${escapeXML(name)}"`, value, depth);
176
- }
177
- function serializeValueElement(tag, attributes, value, depth) {
178
164
  const indent = ' '.repeat(depth);
179
- const encoded = encodeXMLValue(value);
180
- if (encoded !== undefined) {
181
- return [`${indent}<${tag} ${attributes} value="${escapeXML(encoded)}" />`];
182
- }
165
+ const suffix = attributes.length === 0 ? '' : ` ${attributes.join(' ')}`;
183
166
  return [
184
- `${indent}<${tag} ${attributes}>`,
185
- ...serializeComplexValue(value, depth + 1),
186
- `${indent}</${tag}>`,
167
+ `${indent}<layout>`,
168
+ `${indent} <${name}${suffix} />`,
169
+ `${indent}</layout>`,
187
170
  ];
188
171
  }
189
- function parseProperties(element, properties) {
190
- for (const child of element.children) {
191
- if (child.name !== 'property')
192
- throw new Error(`Unexpected <${child.name}> inside <properties>.`);
193
- properties[requiredAttribute(child, 'name')] = parseNamedValue(child);
172
+ function parseLayout(element) {
173
+ if (Object.keys(element.attributes).length > 0) {
174
+ throw new Error('<layout> does not accept attributes.');
194
175
  }
195
- }
196
- function parseNamedValue(element) {
197
- if (element.attributes.value !== undefined)
198
- return decodeXMLValue(element.attributes.value);
199
176
  if (element.children.length !== 1 || element.children[0] === undefined) {
200
- throw new Error(`<${element.name}> requires a value attribute or one complex value.`);
177
+ throw new Error('<layout> requires exactly one layout component.');
178
+ }
179
+ const layout = element.children[0];
180
+ if (!LAYOUT_TYPES.has(layout.name)) {
181
+ throw new Error(`Unsupported layout component <${layout.name}>.`);
182
+ }
183
+ if (layout.children.length > 0) {
184
+ throw new Error(`<${layout.name}> cannot contain child elements.`);
185
+ }
186
+ const properties = {};
187
+ for (const [name, value] of Object.entries(layout.attributes)) {
188
+ properties[name] = decodeXMLValue(value);
201
189
  }
202
- return parseComplexValue(element.children[0]);
190
+ return {
191
+ type: `kui.${layout.name}`,
192
+ properties,
193
+ };
194
+ }
195
+ function requirePropertyObject(value, label) {
196
+ if (typeof value !== 'object' || Array.isArray(value) || 'kind' in value) {
197
+ throw new Error(`${label} must be an object.`);
198
+ }
199
+ return value;
203
200
  }
204
201
  function componentTag(type) {
205
202
  const separator = type.indexOf('.');
@@ -218,13 +215,10 @@ function componentType(tag, namespaces) {
218
215
  throw new Error(`Undeclared component namespace prefix "${prefix}".`);
219
216
  return `${prefix}.${tag.slice(separator + 1)}`;
220
217
  }
221
- function requiredAttribute(element, name) {
222
- const value = element.attributes[name];
223
- if (value === undefined || value.length === 0)
224
- throw new Error(`<${element.name}> requires ${name}.`);
225
- return value;
226
- }
227
218
  function sortedEntries(record) {
228
219
  return Object.entries(record).sort(([left], [right]) => compareStrings(left, right));
229
220
  }
221
+ function propertyDefinition(type, property) {
222
+ return FOUNDATION_COMPONENTS.resolve(type)?.properties[property];
223
+ }
230
224
  //# sourceMappingURL=xml-node.js.map