@yahoo/uds-create-config 4.5.2 → 4.7.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 (72) hide show
  1. package/dist/configs/CanvasConfig.d.ts +900 -80
  2. package/dist/configs/react-native-system.d.ts +603 -55
  3. package/dist/configs/system.d.ts +603 -55
  4. package/dist/configs/system.js +7 -1
  5. package/dist/entities/system/Component.d.ts +480 -39
  6. package/dist/entities/system/Component.js +264 -93
  7. package/dist/entities/system/File.d.ts +1 -1
  8. package/dist/entities/system/LinkedSystem.d.ts +2 -2
  9. package/dist/entities/system/Operation.d.ts +1 -1
  10. package/dist/entities/system/StyleProperty.d.ts +8 -0
  11. package/dist/entities/system/StyleProperty.js +12 -1
  12. package/dist/entities/system/Tool.d.ts +1 -1
  13. package/dist/entities/system/component-module.js +1 -1
  14. package/dist/entities/system/defineComponent.d.ts +45 -7
  15. package/dist/entities/system/defineComponent.js +52 -25
  16. package/dist/framework/Config.d.ts +8 -2
  17. package/dist/framework/Config.js +97 -23
  18. package/dist/framework/class-names.d.ts +4 -2
  19. package/dist/framework/class-names.js +56 -17
  20. package/dist/framework/defineDerivedEntity.d.ts +1 -1
  21. package/dist/framework/defineEntity.d.ts +2 -2
  22. package/dist/framework/defineSubEntity.d.ts +3 -2
  23. package/dist/framework/preview-store.d.ts +19 -0
  24. package/dist/framework/preview-store.js +18 -0
  25. package/dist/framework/projections.d.ts +28 -8
  26. package/dist/framework/projections.js +50 -16
  27. package/dist/framework/prop-surface.d.ts +21 -1
  28. package/dist/framework/prop-surface.js +99 -21
  29. package/dist/framework/render-spec.d.ts +103 -3
  30. package/dist/framework/render-spec.js +285 -37
  31. package/dist/framework/schema-version.d.ts +1 -1
  32. package/dist/framework/schema-version.js +5 -5
  33. package/dist/framework/source-integrity.d.ts +14 -1
  34. package/dist/framework/utils/refs.js +10 -1
  35. package/dist/framework/validate-spec.d.ts +2 -0
  36. package/dist/framework/validate-spec.js +13 -0
  37. package/dist/index.d.ts +15 -12
  38. package/dist/index.js +7 -6
  39. package/dist/migrations/2.0.0/v1-artifact.d.ts +305 -29
  40. package/dist/migrations/20260919051027_prop_conditions_and_anatomy_positions_at_rest.d.ts +22 -0
  41. package/dist/migrations/20260919051027_prop_conditions_and_anatomy_positions_at_rest.js +10 -0
  42. package/dist/migrations/20260920004019_preview_conditions_keyed.d.ts +27 -0
  43. package/dist/migrations/20260920004019_preview_conditions_keyed.js +148 -0
  44. package/dist/migrations/20260920161309_prefixed_token_group.d.ts +12 -0
  45. package/dist/migrations/20260920161309_prefixed_token_group.js +10 -0
  46. package/dist/renderer/wrapRegistry.js +8 -2
  47. package/dist/renderer/wrappers/component-refs.d.ts +14 -0
  48. package/dist/renderer/wrappers/component-refs.js +79 -0
  49. package/dist/renderer/wrappers/hex-normalize.d.ts +5 -7
  50. package/dist/renderer/wrappers/hex-normalize.js +11 -10
  51. package/dist/spec/cell.d.ts +171 -0
  52. package/dist/spec/cell.js +361 -0
  53. package/dist/spec/detach.d.ts +125 -0
  54. package/dist/spec/detach.js +511 -0
  55. package/dist/spec/empty-node-slots.d.ts +11 -23
  56. package/dist/spec/empty-node-slots.js +12 -39
  57. package/dist/spec/index.d.ts +5 -3
  58. package/dist/spec/index.js +3 -3
  59. package/dist/spec/instance.d.ts +77 -0
  60. package/dist/spec/instance.js +80 -0
  61. package/dist/spec/preview-content.d.ts +95 -0
  62. package/dist/spec/preview-content.js +149 -0
  63. package/dist/spec/preview-elements.d.ts +54 -15
  64. package/dist/spec/preview-elements.js +109 -29
  65. package/dist/spec/prop-conditions.d.ts +28 -0
  66. package/dist/spec/prop-conditions.js +39 -0
  67. package/dist/spec/slot.d.ts +206 -0
  68. package/dist/spec/slot.js +542 -0
  69. package/dist/spec/visibility.d.ts +82 -0
  70. package/dist/spec/visibility.js +109 -0
  71. package/dist/tsconfig.tsbuildinfo +1 -1
  72. package/package.json +18 -2
@@ -1,18 +1,46 @@
1
+ import { kindOf } from "../framework/utils/refs.js";
1
2
  //#region src/spec/preview-elements.ts
3
+ /**
4
+ * A preview element is the JSON-safe form of JSX stored in a component's preview props.
5
+ *
6
+ * It is authoring data, not a React element and not yet a json-render node. The helpers in this file
7
+ * own the conversion into the UDS spec dialect so every render host receives the same shape.
8
+ */
2
9
  /** Whether a stored value names an element to render. */
3
10
  function isPreviewElement(value) {
4
11
  if (typeof value !== "object" || value === null) return false;
5
12
  const { element } = value;
6
13
  return typeof element === "string" || typeof element === "object" && element !== null && typeof element.__ref === "string";
7
14
  }
15
+ /** Whether a stored value is a bare `{ __ref }` and nothing else, whatever kind it names. */
16
+ function isPreviewRef(value) {
17
+ if (typeof value !== "object" || value === null) return false;
18
+ const keys = Object.keys(value);
19
+ return keys.length === 1 && keys[0] === "__ref" && typeof value.__ref === "string";
20
+ }
21
+ /** The ref kinds a registry keys a renderer under. */
22
+ const RENDERABLE_KINDS = new Set([
23
+ "component",
24
+ "icon",
25
+ "package",
26
+ "file"
27
+ ]);
28
+ /**
29
+ * Whether a stored value names a component to hand over. A `token:` or `value:` ref is data a prop
30
+ * carries and has the same bare shape, so the kind is what tells them apart.
31
+ */
32
+ function isComponentRef(value) {
33
+ return isPreviewRef(value) && RENDERABLE_KINDS.has(kindOf(value.__ref));
34
+ }
8
35
  /**
9
- * Whether anything under a value is a stored preview element. Stops at live React elements: walking
10
- * through their owner Fiber reaches a circular structure.
36
+ * Whether anything under a value is a stored preview element or component ref, so a reviver knows
37
+ * the bag needs work. Stops at live React elements: walking through their owner Fiber reaches a
38
+ * circular structure.
11
39
  */
12
40
  function hasPreviewElementDeep(value) {
13
41
  if (typeof value !== "object" || value === null) return false;
14
42
  if ("$$typeof" in value) return false;
15
- if (isPreviewElement(value)) return true;
43
+ if (isPreviewElement(value) || isComponentRef(value)) return true;
16
44
  return (Array.isArray(value) ? value : Object.values(value)).some(hasPreviewElementDeep);
17
45
  }
18
46
  /** The json-render `type` a stored element names. */
@@ -28,13 +56,19 @@ function previewElementNodes(root, rootKey, taken = /* @__PURE__ */ new Set()) {
28
56
  while (used.has(key)) key = `${key}_`;
29
57
  used.add(key);
30
58
  const children = (node.children ?? []).map((child, index) => add(child, `${key}_${index}`));
59
+ const props = {};
60
+ const slots = {};
61
+ for (const [prop, value] of Object.entries(node.props ?? {})) if (isPreviewElement(value)) slots[prop] = [add(value, `${key}_${prop}`)];
62
+ else if (Array.isArray(value) && value.every(isPreviewElement)) slots[prop] = value.map((held, index) => add(held, `${key}_${prop}_${index}`));
63
+ else props[prop] = value;
31
64
  elements[key] = {
32
65
  type: previewElementType(node.element),
33
66
  props: {
34
- ...node.props ?? {},
67
+ ...props,
35
68
  ...node.text !== void 0 ? { children: node.text } : {}
36
69
  },
37
- ...children.length > 0 ? { children } : {}
70
+ ...children.length > 0 ? { children } : {},
71
+ ...Object.keys(slots).length > 0 ? { slots } : {}
38
72
  };
39
73
  return key;
40
74
  };
@@ -48,11 +82,52 @@ function isElementValue(value) {
48
82
  return isPreviewElement(value) || Array.isArray(value) && value.some(isPreviewElement);
49
83
  }
50
84
  /**
51
- * Lower direct element-valued props into json-render's native slot form.
85
+ * Graft a slot's content under its host: the elements join the spec's keyed element map as
86
+ * `<host>__<prop>__<index>` subtrees, and the host's `slots[into]` names their roots — json-render
87
+ * traverses `slots` itself, so the keys join neither `props` nor `children`. What an earlier graft
88
+ * of the same slot put there goes first, so the same keys are minted again for the content this
89
+ * pass holds and nothing stale is left for the next key to collide with. The spec comes back
90
+ * unchanged, by reference, when the grafted content is already what is there.
52
91
  *
53
- * The element subtrees join the spec's keyed element map, and the root's `slots` record names their
54
- * keys under the prop that carried them — json-render traverses `slots` itself, so the keys join
55
- * neither `props` nor `children`. Plain values—including text in `props.children`—remain props.
92
+ * Every host that grafts slot content goes through here: the tile projection, the matrix cell and
93
+ * the cell panel, so their keys agree and the layers rail and the drop hit-test read one scheme.
94
+ */
95
+ function graftSlotContent({ spec, hostKey, prop, into, elements: content }) {
96
+ const host = spec.elements[hostKey];
97
+ if (!host) return spec;
98
+ const prefix = `${hostKey}__${prop}__`;
99
+ const kept = Object.fromEntries(Object.entries(spec.elements).filter(([key]) => !key.startsWith(prefix)));
100
+ const grafted = {};
101
+ const used = new Set(Object.keys(kept));
102
+ const roots = content.map((node, index) => {
103
+ const built = previewElementNodes(node, `${prefix}${index}`, used);
104
+ for (const [key, element] of Object.entries(built.elements)) {
105
+ grafted[key] = element;
106
+ used.add(key);
107
+ }
108
+ return built.root;
109
+ });
110
+ const current = host.slots?.[into];
111
+ if (current !== void 0 && current.length === roots.length && roots.every((root, index) => current[index] === root) && Object.keys(spec.elements).filter((key) => key.startsWith(prefix)).length === Object.keys(grafted).length && Object.entries(grafted).every(([key, element]) => JSON.stringify(spec.elements[key]) === JSON.stringify(element))) return spec;
112
+ return {
113
+ ...spec,
114
+ elements: {
115
+ ...kept,
116
+ ...grafted,
117
+ [hostKey]: {
118
+ ...host,
119
+ slots: {
120
+ ...host.slots,
121
+ [into]: roots
122
+ }
123
+ }
124
+ }
125
+ };
126
+ }
127
+ /**
128
+ * Lower the root's direct element-valued props into json-render's native slot form, one
129
+ * {@link graftSlotContent} per prop, under the prop's own name. Plain values — including text in
130
+ * `props.children` — remain props.
56
131
  *
57
132
  * Elements nested inside arbitrary structured data are deliberately left for runtime marker
58
133
  * revival. A `slots` entry identifies a component prop, not a path inside an opaque application
@@ -61,29 +136,34 @@ function isElementValue(value) {
61
136
  function graftPreviewElements(spec, values) {
62
137
  const entries = Object.entries(values).filter(([, value]) => isElementValue(value));
63
138
  if (entries.length === 0) return spec;
64
- const next = structuredClone(spec);
65
- const elements = next.elements;
66
- const rootKey = next.root;
67
- const rootElement = elements[rootKey];
68
- if (!rootElement) return spec;
69
- const used = new Set(Object.keys(elements));
70
- const rootProps = { ...rootElement.props ?? {} };
71
- const rootSlots = { ...rootElement.slots ?? {} };
139
+ const rootKey = spec.root;
140
+ if (!spec.elements[rootKey]) return spec;
141
+ let next = spec;
72
142
  for (const [prop, value] of entries) {
73
- const keys = (Array.isArray(value) ? value.filter(isPreviewElement) : [value]).map((node, index) => {
74
- const graft = previewElementNodes(node, `${rootKey}__${prop}__${index}`, used);
75
- for (const [key, element] of Object.entries(graft.elements)) {
76
- elements[key] = element;
77
- used.add(key);
78
- }
79
- return graft.root;
143
+ const content = Array.isArray(value) ? value.filter(isPreviewElement) : [value];
144
+ next = graftSlotContent({
145
+ spec: next,
146
+ hostKey: rootKey,
147
+ prop,
148
+ into: prop,
149
+ elements: content
80
150
  });
81
- delete rootProps[prop];
82
- rootSlots[prop] = keys;
151
+ const root = next.elements[rootKey];
152
+ if (root?.props && prop in root.props) {
153
+ const { [prop]: _lowered, ...rest } = root.props;
154
+ next = {
155
+ ...next,
156
+ elements: {
157
+ ...next.elements,
158
+ [rootKey]: {
159
+ ...root,
160
+ props: rest
161
+ }
162
+ }
163
+ };
164
+ }
83
165
  }
84
- rootElement.props = rootProps;
85
- rootElement.slots = rootSlots;
86
166
  return next;
87
167
  }
88
168
  //#endregion
89
- export { graftPreviewElements, hasPreviewElementDeep, isPreviewElement, previewElementNodes, previewElementType };
169
+ export { graftPreviewElements, graftSlotContent, hasPreviewElementDeep, isComponentRef, isPreviewElement, isPreviewRef, previewElementNodes, previewElementType };
@@ -0,0 +1,28 @@
1
+ import { Config } from "../framework/Config.js";
2
+
3
+ //#region src/spec/prop-conditions.d.ts
4
+ /** A sibling a prop's condition may name, with the values the condition may hold it at. A boolean
5
+ * offers `true`/`false` as the strings a form works in; a number offers no list, since any number
6
+ * is a value. */
7
+ interface ConditionableProp {
8
+ readonly name: string;
9
+ readonly kind: 'variant' | 'boolean' | 'number';
10
+ readonly values: readonly string[];
11
+ }
12
+ /**
13
+ * The siblings a condition on one of a component's props may name: its own declared props that are
14
+ * a closed axis or a scalar the condition schema coerces. A name exposed only through `forwards` is
15
+ * not one, since `when` is validated against the component's own declarations. `except` leaves out
16
+ * the prop being conditioned.
17
+ */
18
+ declare function conditionableProps({
19
+ config,
20
+ path,
21
+ except
22
+ }: {
23
+ config: Config;
24
+ path: string;
25
+ except?: string;
26
+ }): ConditionableProp[];
27
+ //#endregion
28
+ export { ConditionableProp, conditionableProps };
@@ -0,0 +1,39 @@
1
+ import { surfaceProps } from "../framework/prop-surface.js";
2
+ import { Component } from "../entities/system/Component.js";
3
+ //#region src/spec/prop-conditions.ts
4
+ /**
5
+ * What a prop's `when` may name, for the form that authors one.
6
+ */
7
+ const BOOLEAN_CONDITION_VALUES = ["true", "false"];
8
+ /**
9
+ * The siblings a condition on one of a component's props may name: its own declared props that are
10
+ * a closed axis or a scalar the condition schema coerces. A name exposed only through `forwards` is
11
+ * not one, since `when` is validated against the component's own declarations. `except` leaves out
12
+ * the prop being conditioned.
13
+ */
14
+ function conditionableProps({ config, path, except }) {
15
+ const own = Component.get(config, path)?.props ?? {};
16
+ const out = [];
17
+ for (const prop of surfaceProps(config, path)) {
18
+ if (prop.name === except) continue;
19
+ if (own[prop.name] === null || own[prop.name] === void 0) continue;
20
+ if (prop.kind === "variant") out.push({
21
+ name: prop.name,
22
+ kind: "variant",
23
+ values: prop.values
24
+ });
25
+ else if (prop.kind === "boolean") out.push({
26
+ name: prop.name,
27
+ kind: "boolean",
28
+ values: BOOLEAN_CONDITION_VALUES
29
+ });
30
+ else if (prop.kind === "number") out.push({
31
+ name: prop.name,
32
+ kind: "number",
33
+ values: []
34
+ });
35
+ }
36
+ return out;
37
+ }
38
+ //#endregion
39
+ export { conditionableProps };
@@ -0,0 +1,206 @@
1
+ import { ConfigEdit } from "../framework/config-op.js";
2
+ import { Ref } from "../framework/utils/refs.js";
3
+ import { Config } from "../framework/Config.js";
4
+ import { SlotTarget } from "../framework/render-spec.js";
5
+ import { PreviewElement } from "./preview-elements.js";
6
+ import { PreviewContentAddress, PreviewValueSource } from "./preview-content.js";
7
+
8
+ //#region src/spec/slot.d.ts
9
+ /** A cell's coordinate: the axis values it pins. Empty for the component's own row. */
10
+ type SlotCell = Readonly<Record<string, unknown>>;
11
+ /** What one slot is, apart from the config it is read over. */
12
+ interface SlotFacts extends SlotTarget {
13
+ readonly accepts: readonly string[];
14
+ }
15
+ declare class Slot implements SlotTarget {
16
+ private readonly config;
17
+ /** The component that declares the slot. */
18
+ readonly component: string;
19
+ /** The prop the content arrives as on the instance (`children`, `startIcon`). */
20
+ readonly from: string;
21
+ /** The layer that holds the content. */
22
+ readonly layer: string;
23
+ /** The prop the content lands under on the layer's element. */
24
+ readonly into: string;
25
+ /** The refs the slot accepts (`component:X`, `icon:phosphor`); empty when unconstrained. */
26
+ readonly accepts: readonly string[];
27
+ /** Built by {@link listSlots}; a surface reaches one through `Component.slots` or `Component.slot`. */
28
+ constructor(config: Config, component: string, facts: SlotFacts);
29
+ /** Whether this is the component's `children`, positioned inside one of its layers. */
30
+ get isChildren(): boolean;
31
+ /**
32
+ * Whether the slot takes an element: anything when it accepts nothing in particular, else an
33
+ * element whose ref one of the accepted refs names, exactly or as a member of a group the ref
34
+ * names (`icon:phosphor` takes `icon:phosphor/StarIcon`). A `@source` marker on either side is
35
+ * not part of the name. `element` is a spec type, a bare component path, or the ref a preview
36
+ * element stores.
37
+ */
38
+ takes(element: string | Ref): boolean;
39
+ /** The stored field a cell reads the slot's content from, or `undefined` when nothing is stored. */
40
+ source(cell: SlotCell): PreviewValueSource | undefined;
41
+ /** The elements a cell shows in the slot, in order. */
42
+ content(cell: SlotCell): PreviewElement[];
43
+ /**
44
+ * Append `element` to the content under `cell`: the entry keyed on exactly that coordinate, `*`
45
+ * for none, created where none spells it yet and seeded with the list the coordinate shows, so the
46
+ * cells it covers gain the element and every other cell keeps what it had.
47
+ */
48
+ append({
49
+ cell,
50
+ element
51
+ }: {
52
+ cell: SlotCell;
53
+ element: PreviewElement;
54
+ }): ConfigEdit[];
55
+ /**
56
+ * The content shown under `cell` with `element` placed at `address`: at `index` of the list when
57
+ * the path is empty, past the end appending; otherwise inside the element at `index`, where a
58
+ * number step is the position among that element's children and a string step the element-valued
59
+ * prop it becomes. `undefined` when the address names another slot or a path that reaches nothing.
60
+ * What a surface paints while a drop is still being decided, and what {@link insertAt} writes.
61
+ */
62
+ placed({
63
+ cell,
64
+ address,
65
+ element
66
+ }: {
67
+ cell: SlotCell;
68
+ address: PreviewContentAddress;
69
+ element: PreviewElement;
70
+ }): PreviewElement[] | undefined;
71
+ /**
72
+ * The element at `from` moved to `to`, both in this slot's content under `cell`, on the entry the
73
+ * cell reads the content from. `to` names a position in the content with the moved element
74
+ * already taken out, the way a drop between the remaining elements resolves it. Empty when either
75
+ * address names nothing, or `to` reaches inside the moved element.
76
+ */
77
+ moveAt({
78
+ cell,
79
+ from,
80
+ to
81
+ }: {
82
+ cell: SlotCell;
83
+ from: PreviewContentAddress;
84
+ to: PreviewContentAddress;
85
+ }): ConfigEdit[];
86
+ /** The element at `address` in the content shown under `cell`, or `undefined` when it names nothing. */
87
+ elementAt({
88
+ cell,
89
+ address
90
+ }: {
91
+ cell: SlotCell;
92
+ address: PreviewContentAddress;
93
+ }): PreviewElement | undefined;
94
+ /**
95
+ * A copy of the element at `address`, placed right after it: the next index of the list, or the
96
+ * next position among its parent's children. Written on the entry the cell reads the content
97
+ * from, like {@link replaceAt}, so a copy made in a conditional cell of `*` content is every
98
+ * cell's. An element held as a prop has no "after", so it is not duplicated. Empty when the
99
+ * address names nothing.
100
+ */
101
+ duplicateAt({
102
+ cell,
103
+ address
104
+ }: {
105
+ cell: SlotCell;
106
+ address: PreviewContentAddress;
107
+ }): ConfigEdit[];
108
+ /** Write the content {@link placed} gives, onto the cell's own entry the way `append` writes.
109
+ * Empty when nothing is placed. */
110
+ insertAt({
111
+ cell,
112
+ address,
113
+ element
114
+ }: {
115
+ cell: SlotCell;
116
+ address: PreviewContentAddress;
117
+ element: PreviewElement;
118
+ }): ConfigEdit[];
119
+ /**
120
+ * Swap the element at `address` for `element`, on the entry the cell reads the content from —
121
+ * `*` included, so a `*` value shown in a conditional cell changes for every cell rather than
122
+ * being copied into a new keyed entry. Empty when the address names nothing.
123
+ */
124
+ replaceAt({
125
+ cell,
126
+ address,
127
+ element
128
+ }: {
129
+ cell: SlotCell;
130
+ address: PreviewContentAddress;
131
+ element: PreviewElement;
132
+ }): ConfigEdit[];
133
+ /**
134
+ * Take the element at `address` out, on the entry the cell reads the content from. A list emptied
135
+ * this way clears the prop, and an entry left with no props goes with it. Empty when the address
136
+ * names nothing.
137
+ */
138
+ removeAt({
139
+ cell,
140
+ address
141
+ }: {
142
+ cell: SlotCell;
143
+ address: PreviewContentAddress;
144
+ }): ConfigEdit[];
145
+ /**
146
+ * Store `elements` as the whole content under `cell`: one `sub-update` on the `preview` entry
147
+ * keyed on the coordinate, `*` for none, created where none spells it and joined where one does.
148
+ * What a picker that shows the whole list writes; the verbs above build on it.
149
+ */
150
+ set({
151
+ cell,
152
+ elements
153
+ }: {
154
+ cell: SlotCell;
155
+ elements: readonly PreviewElement[];
156
+ }): ConfigEdit[];
157
+ private stored;
158
+ /** `replaceAt` and `removeAt`: one element rewritten or dropped, written back where it was read. */
159
+ private rewrite;
160
+ /** The edits that store `content` on `source`: the field the content came from, cleared when the
161
+ * list is empty, and the entry it leaves with nothing else going with it. */
162
+ private writeSource;
163
+ }
164
+ /**
165
+ * Every slot of a component that content can be placed in: its named node slots, and its `children`
166
+ * when a layer of several positions them. A text slot is typed in place rather than filled, so it is
167
+ * not one; nor is `children` landing on the root, which is the open hole every container has. The
168
+ * same array comes back for the same config.
169
+ */
170
+ declare function listSlots({
171
+ config,
172
+ path
173
+ }: {
174
+ config: Config;
175
+ path: string;
176
+ }): readonly Slot[];
177
+ /** The named node slots alone: what a design node's render injects an empty placeholder for. */
178
+ declare function namedSlots({
179
+ config,
180
+ path
181
+ }: {
182
+ config: Config;
183
+ path: string;
184
+ }): readonly Slot[];
185
+ /** The slot a prop names, or `undefined` when the prop is not a slot content is placed in. */
186
+ declare function slotOf({
187
+ config,
188
+ path,
189
+ slot
190
+ }: {
191
+ config: Config;
192
+ path: string;
193
+ slot: string;
194
+ }): Slot | undefined;
195
+ /** The slot whose content lands in `layer`, or `undefined` when the layer hosts none. */
196
+ declare function slotHostedBy({
197
+ config,
198
+ path,
199
+ layer
200
+ }: {
201
+ config: Config;
202
+ path: string;
203
+ layer: string;
204
+ }): Slot | undefined;
205
+ //#endregion
206
+ export { Slot, SlotCell, listSlots, namedSlots, slotHostedBy, slotOf };