@kurot/ui-document 0.5.2 → 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 (53) hide show
  1. package/README.md +16 -15
  2. package/dist/kurot/model/UIDocument.d.ts +1 -1
  3. package/dist/kurot/model/index.d.ts +2 -0
  4. package/dist/kurot/model/index.d.ts.map +1 -1
  5. package/dist/kurot/model/index.js +2 -0
  6. package/dist/kurot/model/index.js.map +1 -1
  7. package/dist/kurot/model/synthetic-node-id.d.ts +9 -0
  8. package/dist/kurot/model/synthetic-node-id.d.ts.map +1 -0
  9. package/dist/kurot/model/synthetic-node-id.js +14 -0
  10. package/dist/kurot/model/synthetic-node-id.js.map +1 -0
  11. package/dist/kurot/serialization/UIDocumentParseError.d.ts +1 -1
  12. package/dist/kurot/serialization/UIDocumentParseError.js +1 -1
  13. package/dist/kurot/serialization/index.d.ts +1 -1
  14. package/dist/kurot/serialization/index.d.ts.map +1 -1
  15. package/dist/kurot/serialization/index.js +1 -1
  16. package/dist/kurot/serialization/index.js.map +1 -1
  17. package/dist/kurot/serialization/xml/xml-node.d.ts +23 -0
  18. package/dist/kurot/serialization/xml/xml-node.d.ts.map +1 -0
  19. package/dist/kurot/serialization/xml/xml-node.js +224 -0
  20. package/dist/kurot/serialization/xml/xml-node.js.map +1 -0
  21. package/dist/kurot/serialization/xml/xml-parser.d.ts +10 -0
  22. package/dist/kurot/serialization/xml/xml-parser.d.ts.map +1 -0
  23. package/dist/kurot/serialization/xml/xml-parser.js +134 -0
  24. package/dist/kurot/serialization/xml/xml-parser.js.map +1 -0
  25. package/dist/kurot/serialization/xml/xml-values.d.ts +15 -0
  26. package/dist/kurot/serialization/xml/xml-values.d.ts.map +1 -0
  27. package/dist/kurot/serialization/xml/xml-values.js +73 -0
  28. package/dist/kurot/serialization/xml/xml-values.js.map +1 -0
  29. package/dist/kurot/serialization/xml.d.ts +14 -0
  30. package/dist/kurot/serialization/xml.d.ts.map +1 -0
  31. package/dist/kurot/serialization/xml.js +162 -0
  32. package/dist/kurot/serialization/xml.js.map +1 -0
  33. package/dist/kurot/validation/UIDiagnostic.d.ts +1 -1
  34. package/dist/kurot/validation/UIDiagnostic.d.ts.map +1 -1
  35. package/dist/kurot/validation/validateUIAssetContract.d.ts.map +1 -1
  36. package/dist/kurot/validation/validateUIAssetContract.js +3 -1
  37. package/dist/kurot/validation/validateUIAssetContract.js.map +1 -1
  38. package/dist/kurot/validation/validateUIAssetModes.d.ts.map +1 -1
  39. package/dist/kurot/validation/validateUIAssetModes.js.map +1 -1
  40. package/dist/kurot/validation/validateUIComponentInstance.d.ts.map +1 -1
  41. package/dist/kurot/validation/validateUIComponentInstance.js +1 -7
  42. package/dist/kurot/validation/validateUIComponentInstance.js.map +1 -1
  43. package/dist/kurot/validation/validateUIDocument.d.ts.map +1 -1
  44. package/dist/kurot/validation/validateUIDocument.js +4 -17
  45. package/dist/kurot/validation/validateUIDocument.js.map +1 -1
  46. package/dist/kurot/validation/validationHelpers.d.ts.map +1 -1
  47. package/dist/kurot/validation/validationHelpers.js +1 -1
  48. package/dist/kurot/validation/validationHelpers.js.map +1 -1
  49. package/package.json +1 -1
  50. package/dist/kurot/serialization/json.d.ts +0 -10
  51. package/dist/kurot/serialization/json.d.ts.map +0 -1
  52. package/dist/kurot/serialization/json.js +0 -234
  53. package/dist/kurot/serialization/json.js.map +0 -1
package/README.md CHANGED
@@ -4,9 +4,8 @@ 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.5.x).** The reusable authoring model and headless
8
- > editing kernel are implemented, but the schema remains pre-1.0 and is not yet
9
- > a production file format.
7
+ > **Current release: 0.6.1.** KUI XML is the canonical authored format. The
8
+ > schema remains pre-1.0, so later minor releases may still refine its contract.
10
9
 
11
10
  ## Installation
12
11
 
@@ -28,8 +27,8 @@ import {
28
27
  } from '@kurot/ui-document';
29
28
 
30
29
  const document = createUIDocument({
31
- id: 'main-screen',
32
- assetKind: 'screen',
30
+ id: 'game.MainSkin',
31
+ assetKind: 'appearance',
33
32
  root: createUINode({
34
33
  id: 'root',
35
34
  type: 'kui.Group',
@@ -52,6 +51,10 @@ const source = serializeUIDocument(document);
52
51
  `type` is an external registry key; this package does not import or instantiate
53
52
  the corresponding `@kurot/ui` class.
54
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
+
55
58
  ## Current capabilities
56
59
 
57
60
  - explicit screen, reusable-component, and appearance assets;
@@ -72,8 +75,7 @@ the corresponding `@kurot/ui` class.
72
75
  - strict validation of schema keys, versions, identifiers, unique node IDs,
73
76
  plain property values, finite numbers, and acyclic trees;
74
77
  - structured diagnostics with stable codes and JSON-style paths;
75
- - validated JSON parsing and deterministic serialization with sorted property
76
- keys;
78
+ - validated KUI XML parsing and deterministic canonical serialization;
77
79
  - runtime-independent component definitions and an isolated component registry;
78
80
  - inherited appearance-state, native-part, and emitted-event capabilities;
79
81
  - abstract base definitions, single-parent inheritance, deterministic schema
@@ -209,8 +211,9 @@ It defines the abstract semantic bases `kurot.DisplayObject`,
209
211
  `kui.ToggleButton`, `kui.ProgressBar`, and `kui.TextInput` nodes. `Group`
210
212
  accepts ordered children; the other concrete nodes are leaves.
211
213
 
212
- `kui.*` is the canonical Kurot UI namespace. EUI names belong only to legacy
213
- EXML adapters and are not stored in the semantic document.
214
+ `kui.*` is the canonical Kurot UI namespace. Authored Skin files use the
215
+ [`KUI XML format`](./docs/kui-xml.md); EUI names and EXML are not stored in the
216
+ semantic document.
214
217
 
215
218
  The foundation catalog declares the serializable authoring properties inherited
216
219
  from Kurot display objects and UI layout elements, then adds the audited direct
@@ -242,19 +245,17 @@ package boundaries.
242
245
 
243
246
  ## Intended boundary
244
247
 
245
- The package owns the serializable UI asset model and its deterministic
246
- operations. Planned layers include:
248
+ The package owns the serializable UI asset model, KUI XML syntax, and its
249
+ deterministic operations. Planned work includes:
247
250
 
248
- - the remaining component catalog and nested structured-value constraints;
249
- - document migrations;
250
- - adapters for formats such as EXML.
251
+ - the remaining component catalog and nested structured-value constraints.
251
252
 
252
253
  It will not own rendering, runtime UI components, editor panels, filesystem
253
254
  or network I/O, or model-provider integration. Those concerns belong to
254
255
  `@kurot/ui`, the visual builder, CLI orchestration, and Agent adapters
255
256
  respectively.
256
257
 
257
- `@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,
258
259
  including reusable instances, parameter bindings, Slots, component variants,
259
260
  part overrides, design tokens, resource hooks, and native appearance
260
261
  skins/states. It also executes the bounded data, action, and transition
@@ -10,7 +10,7 @@ export declare const UI_DOCUMENT_KIND = "kurot-ui-document";
10
10
  */
11
11
  export interface UIDocument {
12
12
  /**
13
- * Stable discriminator used to reject unrelated JSON documents.
13
+ * Stable discriminator used to reject unrelated semantic values.
14
14
  */
15
15
  readonly kind: typeof UI_DOCUMENT_KIND;
16
16
  /**
@@ -2,8 +2,10 @@ export type { UIAssetKind } from './UIAssetKind.js';
2
2
  export type { UIAssetContract, UIDataBindingDefinition, UIParameterBinding, UIParameterDefinition, UIPartDefinition, UIPropertyOverride, UIPropertyTransition, UISemanticActionDefinition, UISemanticActionTrigger, UISlotDefinition, UIStateDefinition, UITransitionEasing, UIVariantDefinition, } from './UIAssetContract.js';
3
3
  export type { UIComponentInstance, UIInstanceOverride, } from './UIComponentInstance.js';
4
4
  export type { UIAssetReference, UIAppearanceReference, UIDesignTokenReference, UIDesignTokenType, UIResourceReference, UIResourceType, } from './UIReference.js';
5
+ export { isUIAssetReference, isUIDesignTokenReference, isUIResourceReference, UI_DESIGN_TOKEN_TYPES, UI_RESOURCE_TYPES, } from './UIReference.js';
5
6
  export { UI_DOCUMENT_KIND } from './UIDocument.js';
6
7
  export type { UIDocument } from './UIDocument.js';
7
8
  export type { UINode } from './UINode.js';
9
+ export { isSyntheticNodeId } from './synthetic-node-id.js';
8
10
  export type { UIPropertyObject, UIPropertyPrimitive, UIPropertyValue, } from './UIPropertyValue.js';
9
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,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,2 +1,4 @@
1
+ export { isUIAssetReference, isUIDesignTokenReference, isUIResourceReference, UI_DESIGN_TOKEN_TYPES, UI_RESOURCE_TYPES, } from './UIReference.js';
1
2
  export { UI_DOCUMENT_KIND } from './UIDocument.js';
3
+ export { isSyntheticNodeId } from './synthetic-node-id.js';
2
4
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/kurot/model/index.ts"],"names":[],"mappings":"AA4BA,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,6 +1,6 @@
1
1
  import type { UIDiagnostic } from '../validation/UIDiagnostic.js';
2
2
  /**
3
- * Error raised when JSON cannot be decoded as a current-format UI document.
3
+ * Error raised when KUI XML cannot be decoded as a current-format UI document.
4
4
  */
5
5
  export declare class UIDocumentParseError extends Error {
6
6
  /**
@@ -1,6 +1,6 @@
1
1
  import { firstDiagnosticMessage } from './first-diagnostic-message.js';
2
2
  /**
3
- * Error raised when JSON cannot be decoded as a current-format UI document.
3
+ * Error raised when KUI XML cannot be decoded as a current-format UI document.
4
4
  */
5
5
  export class UIDocumentParseError extends Error {
6
6
  /**
@@ -1,4 +1,4 @@
1
1
  export { UIDocumentParseError } from './UIDocumentParseError.js';
2
2
  export { UIDocumentValidationError } from './UIDocumentValidationError.js';
3
- export { parseUIDocument, serializeUIDocument } from './json.js';
3
+ export { KUI_XML_NAMESPACE, parseUIDocument, serializeUIDocument } from './xml.js';
4
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/kurot/serialization/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAC3E,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/kurot/serialization/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAC3E,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC"}
@@ -1,4 +1,4 @@
1
1
  export { UIDocumentParseError } from './UIDocumentParseError.js';
2
2
  export { UIDocumentValidationError } from './UIDocumentValidationError.js';
3
- export { parseUIDocument, serializeUIDocument } from './json.js';
3
+ export { KUI_XML_NAMESPACE, parseUIDocument, serializeUIDocument } from './xml.js';
4
4
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/kurot/serialization/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAC3E,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/kurot/serialization/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAC3E,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1,23 @@
1
+ import type { UIPropertyOverride, UIStateDefinition } from '../../model/UIAssetContract.js';
2
+ import type { UINode } from '../../model/UINode.js';
3
+ import type { XMLElement } from './xml-parser.js';
4
+ export interface XMLNamespaces {
5
+ readonly prefixes: Readonly<Record<string, string>>;
6
+ }
7
+ export interface XMLNodeParseContext extends XMLNamespaces {
8
+ readonly states: ReadonlySet<string>;
9
+ readonly stateOverrides: Map<string, UIPropertyOverride[]>;
10
+ }
11
+ /**
12
+ * Collects custom component namespace prefixes used by a node tree.
13
+ */
14
+ export declare function collectNodePrefixes(node: UINode, prefixes: Set<string>): void;
15
+ /**
16
+ * Serializes one semantic node using component tags.
17
+ */
18
+ export declare function serializeNode(node: UINode, depth: number, states?: Readonly<Record<string, UIStateDefinition>>): string[];
19
+ /**
20
+ * Parses one component element into a semantic node.
21
+ */
22
+ export declare function parseNode(element: XMLElement, context: XMLNodeParseContext, path?: string): UINode;
23
+ //# sourceMappingURL=xml-node.d.ts.map
@@ -0,0 +1 @@
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"}
@@ -0,0 +1,224 @@
1
+ import { createSyntheticNodeId, isSyntheticNodeId } from '../../model/synthetic-node-id.js';
2
+ import { createKurotUIFoundationRegistry } from '../../catalog/kurot-ui-foundation.js';
3
+ import { compareStrings } from '../../shared/strings.js';
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']);
8
+ /**
9
+ * Collects custom component namespace prefixes used by a node tree.
10
+ */
11
+ export function collectNodePrefixes(node, prefixes) {
12
+ const separator = node.type.indexOf('.');
13
+ const prefix = separator === -1 ? 'kui' : node.type.slice(0, separator);
14
+ if (prefix !== 'kui')
15
+ prefixes.add(prefix);
16
+ for (const child of node.children) {
17
+ collectNodePrefixes(child, prefixes);
18
+ }
19
+ }
20
+ /**
21
+ * Serializes one semantic node using component tags.
22
+ */
23
+ export function serializeNode(node, depth, states = {}) {
24
+ const indent = ' '.repeat(depth);
25
+ const tag = componentTag(node.type);
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.');
31
+ }
32
+ for (const [name, value] of sortedEntries(node.properties)) {
33
+ if (name === 'layout') {
34
+ layout = value;
35
+ continue;
36
+ }
37
+ if (name.includes('.')) {
38
+ throw new Error(`Skin property name "${name}" must not contain a dot.`);
39
+ }
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
+ }
57
+ stateProperties.add(stateProperty);
58
+ if (override.transition !== undefined) {
59
+ throw new Error(`Skin XML does not serialize transitions for state "${stateName}".`);
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)}"`);
66
+ }
67
+ }
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
+ }
76
+ for (const child of node.children) {
77
+ lines.push(...serializeNode(child, depth + 1, states));
78
+ }
79
+ lines.push(`${indent}</${tag}>`);
80
+ return lines;
81
+ }
82
+ /**
83
+ * Parses one component element into a semantic node.
84
+ */
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);
92
+ const properties = {};
93
+ const children = [];
94
+ for (const [name, value] of Object.entries(element.attributes)) {
95
+ if (RESERVED_ATTRIBUTES.has(name) || name.startsWith('xmlns:'))
96
+ continue;
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));
119
+ }
120
+ let childIndex = 0;
121
+ for (const child of element.children) {
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);
127
+ }
128
+ else if (child.name === 'properties' || child.name === 'instance') {
129
+ throw new Error(`<${child.name}> is not Skin XML syntax.`);
130
+ }
131
+ else {
132
+ children.push(parseNode(child, context, `${path}.${childIndex}`));
133
+ childIndex++;
134
+ }
135
+ }
136
+ return {
137
+ id,
138
+ type,
139
+ properties,
140
+ children,
141
+ };
142
+ }
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.`);
161
+ }
162
+ attributes.push(`${property}="${escapeXML(encoded)}"`);
163
+ }
164
+ const indent = ' '.repeat(depth);
165
+ const suffix = attributes.length === 0 ? '' : ` ${attributes.join(' ')}`;
166
+ return [
167
+ `${indent}<layout>`,
168
+ `${indent} <${name}${suffix} />`,
169
+ `${indent}</layout>`,
170
+ ];
171
+ }
172
+ function parseLayout(element) {
173
+ if (Object.keys(element.attributes).length > 0) {
174
+ throw new Error('<layout> does not accept attributes.');
175
+ }
176
+ if (element.children.length !== 1 || element.children[0] === undefined) {
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);
189
+ }
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;
200
+ }
201
+ function componentTag(type) {
202
+ const separator = type.indexOf('.');
203
+ if (separator === -1)
204
+ return type;
205
+ const prefix = type.slice(0, separator);
206
+ const name = type.slice(separator + 1);
207
+ return prefix === 'kui' ? name : `${prefix}:${name}`;
208
+ }
209
+ function componentType(tag, namespaces) {
210
+ const separator = tag.indexOf(':');
211
+ if (separator === -1)
212
+ return `kui.${tag}`;
213
+ const prefix = tag.slice(0, separator);
214
+ if (!Object.hasOwn(namespaces.prefixes, prefix))
215
+ throw new Error(`Undeclared component namespace prefix "${prefix}".`);
216
+ return `${prefix}.${tag.slice(separator + 1)}`;
217
+ }
218
+ function sortedEntries(record) {
219
+ return Object.entries(record).sort(([left], [right]) => compareStrings(left, right));
220
+ }
221
+ function propertyDefinition(type, property) {
222
+ return FOUNDATION_COMPONENTS.resolve(type)?.properties[property];
223
+ }
224
+ //# sourceMappingURL=xml-node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"xml-node.js","sourceRoot":"","sources":["../../../../src/kurot/serialization/xml/xml-node.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export interface XMLElement {
2
+ readonly name: string;
3
+ readonly attributes: Readonly<Record<string, string>>;
4
+ readonly children: readonly XMLElement[];
5
+ }
6
+ /**
7
+ * Parses the XML subset used by canonical KUI documents.
8
+ */
9
+ export declare function parseXML(source: string): XMLElement;
10
+ //# sourceMappingURL=xml-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"xml-parser.d.ts","sourceRoot":"","sources":["../../../../src/kurot/serialization/xml/xml-parser.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACtD,QAAQ,CAAC,QAAQ,EAAE,SAAS,UAAU,EAAE,CAAC;CACzC;AAOD;;GAEG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAGnD"}
@@ -0,0 +1,134 @@
1
+ const NAME = '[A-Za-z_][\\w:.-]*';
2
+ const OPEN_PATTERN = new RegExp(`^<(${NAME})`);
3
+ const CLOSE_PATTERN = new RegExp(`^<\\/(${NAME})\\s*>`);
4
+ const ATTRIBUTE_PATTERN = new RegExp(`^(${NAME})\\s*=\\s*(?:"([^"]*)"|'([^']*)')`);
5
+ /**
6
+ * Parses the XML subset used by canonical KUI documents.
7
+ */
8
+ export function parseXML(source) {
9
+ const parser = new XMLParser(source);
10
+ return parser.parse();
11
+ }
12
+ class XMLParser {
13
+ _source;
14
+ _position = 0;
15
+ constructor(_source) {
16
+ this._source = _source;
17
+ }
18
+ parse() {
19
+ this._skipMiscellaneous();
20
+ const root = this._parseElement();
21
+ this._skipMiscellaneous();
22
+ if (this._position !== this._source.length) {
23
+ throw this._error('Unexpected content after the root element.');
24
+ }
25
+ return root;
26
+ }
27
+ _parseElement() {
28
+ const opening = this._source.slice(this._position).match(OPEN_PATTERN);
29
+ if (!opening || opening[1] === undefined) {
30
+ throw this._error('Expected an XML element.');
31
+ }
32
+ const name = opening[1];
33
+ this._position += opening[0].length;
34
+ const attributes = {};
35
+ for (;;) {
36
+ this._skipWhitespace();
37
+ if (this._source.startsWith('/>', this._position)) {
38
+ this._position += 2;
39
+ return { name, attributes, children: [] };
40
+ }
41
+ if (this._source[this._position] === '>') {
42
+ this._position++;
43
+ break;
44
+ }
45
+ const attribute = this._source.slice(this._position).match(ATTRIBUTE_PATTERN);
46
+ if (!attribute || attribute[1] === undefined) {
47
+ throw this._error(`Invalid attribute in <${name}>.`);
48
+ }
49
+ if (Object.hasOwn(attributes, attribute[1])) {
50
+ throw this._error(`Duplicate attribute "${attribute[1]}" in <${name}>.`);
51
+ }
52
+ attributes[attribute[1]] = decodeXML(attribute[2] ?? attribute[3] ?? '');
53
+ this._position += attribute[0].length;
54
+ }
55
+ const children = [];
56
+ for (;;) {
57
+ this._skipMiscellaneous();
58
+ const closing = this._source.slice(this._position).match(CLOSE_PATTERN);
59
+ if (closing) {
60
+ if (closing[1] !== name) {
61
+ throw this._error(`Expected </${name}>, received </${String(closing[1])}>.`);
62
+ }
63
+ this._position += closing[0].length;
64
+ return { name, attributes, children };
65
+ }
66
+ if (this._position >= this._source.length) {
67
+ throw this._error(`Missing closing tag </${name}>.`);
68
+ }
69
+ if (this._source[this._position] !== '<') {
70
+ const text = this._readText();
71
+ if (text.trim().length > 0) {
72
+ throw this._error(`Text content is not allowed inside <${name}>.`);
73
+ }
74
+ continue;
75
+ }
76
+ children.push(this._parseElement());
77
+ }
78
+ }
79
+ _readText() {
80
+ const start = this._position;
81
+ while (this._position < this._source.length && this._source[this._position] !== '<') {
82
+ this._position++;
83
+ }
84
+ return decodeXML(this._source.slice(start, this._position));
85
+ }
86
+ _skipMiscellaneous() {
87
+ for (;;) {
88
+ this._skipWhitespace();
89
+ if (this._source.startsWith('<!--', this._position)) {
90
+ this._skipThrough('-->', 'Unterminated XML comment.');
91
+ continue;
92
+ }
93
+ if (this._source.startsWith('<?', this._position)) {
94
+ this._skipThrough('?>', 'Unterminated processing instruction.');
95
+ continue;
96
+ }
97
+ return;
98
+ }
99
+ }
100
+ _skipThrough(terminator, message) {
101
+ const end = this._source.indexOf(terminator, this._position + 2);
102
+ if (end === -1) {
103
+ throw this._error(message);
104
+ }
105
+ this._position = end + terminator.length;
106
+ }
107
+ _skipWhitespace() {
108
+ while (/\s/.test(this._source[this._position] ?? '')) {
109
+ this._position++;
110
+ }
111
+ }
112
+ _error(message) {
113
+ return new Error(`${message} (offset ${this._position})`);
114
+ }
115
+ }
116
+ function decodeXML(value) {
117
+ const named = {
118
+ amp: '&',
119
+ apos: "'",
120
+ gt: '>',
121
+ lt: '<',
122
+ quot: '"',
123
+ };
124
+ return value.replace(/&(#x[0-9a-f]+|#\d+|amp|apos|gt|lt|quot);/gi, (match, entity) => {
125
+ if (entity.startsWith('#x')) {
126
+ return String.fromCodePoint(Number.parseInt(entity.slice(2), 16));
127
+ }
128
+ if (entity.startsWith('#')) {
129
+ return String.fromCodePoint(Number.parseInt(entity.slice(1), 10));
130
+ }
131
+ return named[entity] ?? match;
132
+ });
133
+ }
134
+ //# sourceMappingURL=xml-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"xml-parser.js","sourceRoot":"","sources":["../../../../src/kurot/serialization/xml/xml-parser.ts"],"names":[],"mappings":"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"}