@yahoo/uds-create-config 4.36.0 → 4.37.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 (73) hide show
  1. package/dist/configs/CanvasConfig.d.ts +68 -5167
  2. package/dist/configs/CanvasConfig.js +0 -76
  3. package/dist/configs/documentation.d.ts +11 -251
  4. package/dist/configs/documentation.js +0 -1
  5. package/dist/configs/react-native-system.d.ts +39 -4239
  6. package/dist/configs/react-native-system.js +0 -11
  7. package/dist/configs/system.d.ts +44 -4209
  8. package/dist/configs/system.js +2 -9
  9. package/dist/entities/documentation/Documentation.d.ts +5 -18
  10. package/dist/entities/documentation/Documentation.js +0 -1
  11. package/dist/entities/native/NativeModifier.d.ts +6 -3
  12. package/dist/entities/native/NativeSettings.d.ts +6 -3
  13. package/dist/entities/native/NativeSettings.js +0 -1
  14. package/dist/entities/native/NativeStyleProperty.d.ts +1 -20
  15. package/dist/entities/native/NativeToken.d.ts +2 -6
  16. package/dist/entities/system/CanvasRole.d.ts +6 -7
  17. package/dist/entities/system/Component.d.ts +86 -1588
  18. package/dist/entities/system/Component.js +0 -9
  19. package/dist/entities/system/Composite.d.ts +8 -6
  20. package/dist/entities/system/Composite.js +0 -1
  21. package/dist/entities/system/Device.d.ts +6 -3
  22. package/dist/entities/system/Device.js +0 -6
  23. package/dist/entities/system/File.d.ts +43 -8
  24. package/dist/entities/system/File.js +0 -51
  25. package/dist/entities/system/Font.d.ts +10 -11
  26. package/dist/entities/system/Font.js +0 -21
  27. package/dist/entities/system/GlobalStyle.d.ts +6 -3
  28. package/dist/entities/system/Guidance.d.ts +6 -3
  29. package/dist/entities/system/GuidanceStyle.d.ts +6 -3
  30. package/dist/entities/system/Icon.d.ts +8 -8
  31. package/dist/entities/system/Icon.js +0 -16
  32. package/dist/entities/system/LinkedSystem.d.ts +13 -155
  33. package/dist/entities/system/LinkedSystem.js +22 -12
  34. package/dist/entities/system/Modifier.d.ts +8 -8
  35. package/dist/entities/system/Motion.d.ts +6 -3
  36. package/dist/entities/system/Operation.d.ts +5 -2
  37. package/dist/entities/system/Package.d.ts +24 -4
  38. package/dist/entities/system/Package.js +0 -46
  39. package/dist/entities/system/Settings.d.ts +18 -7
  40. package/dist/entities/system/Settings.js +0 -6
  41. package/dist/entities/system/StyleProperty.d.ts +14 -27
  42. package/dist/entities/system/StyleProperty.js +0 -6
  43. package/dist/entities/system/Token.d.ts +12 -9
  44. package/dist/entities/system/Tool.d.ts +7 -90
  45. package/dist/entities/system/composed-values.d.ts +1 -1
  46. package/dist/entities/system/copy-plan.d.ts +2 -2
  47. package/dist/entities/system/copy-plan.js +32 -10
  48. package/dist/entities/system/defineComponent.d.ts +1 -1
  49. package/dist/entities/system/icon-metadata.d.ts +2 -6
  50. package/dist/entities/system/link-plan.d.ts +26 -5
  51. package/dist/entities/system/link-plan.js +71 -15
  52. package/dist/entities/system/style-bag.d.ts +27 -1
  53. package/dist/entities/system/style-bag.js +0 -10
  54. package/dist/framework/Config.d.ts +19 -3
  55. package/dist/framework/Config.js +71 -16
  56. package/dist/framework/class-names.js +1 -0
  57. package/dist/framework/defineConfig.d.ts +2 -2
  58. package/dist/framework/defineEntity.d.ts +27 -7
  59. package/dist/framework/named.d.ts +9 -0
  60. package/dist/framework/plan.d.ts +3 -0
  61. package/dist/framework/plan.js +4 -1
  62. package/dist/framework/schema-version.d.ts +1 -1
  63. package/dist/framework/schema-version.js +5 -5
  64. package/dist/framework/utils/group.d.ts +15 -5
  65. package/dist/index.d.ts +47 -46
  66. package/dist/migrations/2.0.0/v1-artifact.d.ts +38 -2109
  67. package/dist/migrations/20260928180801_link_on_linked.d.ts +10 -0
  68. package/dist/migrations/20260928180801_link_on_linked.js +8 -0
  69. package/dist/renderer/wrappers/html-aliases.js +1 -0
  70. package/dist/spec/cell.d.ts +1 -1
  71. package/dist/spec/preview-content.d.ts +1 -1
  72. package/dist/tsconfig.tsbuildinfo +1 -1
  73. package/package.json +2 -2
@@ -1,6 +1,7 @@
1
1
  import { Ref } from "../../framework/utils/ref-grammar.js";
2
2
  import { Ref as Ref$1 } from "../../framework/utils/refs.js";
3
3
  import { EntityClass } from "../../framework/defineEntity.js";
4
+ import { Named } from "../../framework/named.js";
4
5
  import { Config } from "../../framework/Config.js";
5
6
  import { z } from "zod";
6
7
 
@@ -97,13 +98,9 @@ declare function classifyStylePropValue({
97
98
  config: Config;
98
99
  entry: StylePropValue;
99
100
  }): StylePropValueKind;
100
- /**
101
- * `StyleProperty.ref('bg')` keeps the path literal in its type, so a component prop declared as the
102
- * ref is typed by the property it points at: `bg: StyleProperty.ref('bg')` offers the registered `bg`
103
- * values, and `columns: StyleProperty.ref('gridTemplateColumns')` offers the target's rather than
104
- * the name's.
105
- */
106
- declare const StyleProperty: EntityClass<z.ZodObject<{
101
+ /** StyleProperty (`flex/direction`) — a prop a component can expose, mapped to a CSS
102
+ * property with an allowed value set. Grouping (`flex`) is emergent from the path. */
103
+ declare const StylePropertyEntity: EntityClass<z.ZodObject<{
107
104
  properties: z.ZodArray<z.ZodString>;
108
105
  values: z.ZodOptional<z.ZodArray<z.ZodType<StylePropValue, unknown, z.core.$ZodTypeInternals<StylePropValue, unknown>>>>;
109
106
  responsive: z.ZodDefault<z.ZodBoolean>;
@@ -111,25 +108,15 @@ declare const StyleProperty: EntityClass<z.ZodObject<{
111
108
  arbitrary: z.ZodDefault<z.ZodBoolean>;
112
109
  negates: z.ZodDefault<z.ZodBoolean>;
113
110
  opacityOf: z.ZodOptional<z.ZodLazy<z.ZodType<Ref, unknown, z.core.$ZodTypeInternals<Ref, unknown>>>>;
114
- }, z.core.$strip>, z.ZodObject<Record<never, never>, z.core.$strip>, "style-property", {
115
- readonly rename: {
116
- readonly to: z.ZodString;
117
- };
118
- readonly create: {
119
- readonly path: z.ZodString;
120
- readonly description: `Create a style property \u2014 the prop a component exposes for one CSS effect. \`path\` is the prop's JSX name, camelCase (\`borderRadius\`), never a CSS name; the CSS goes in \`properties\`. \`values\` is a ref to a token GROUP (\`${string}\`), which offers every token in it and keeps the prop in step with modes and edits; \`{ "alias": "brand", "value": ${string} }\` offers one token under a name of the prop's own; a literal (\`"row"\`, \`{ "alias": "full", "value": "9999px" }\`) is for a keyword the system has no token for. Restating a token's value as a literal instead of referencing it is refused.`;
121
- readonly example: ({
122
- config
123
- }: {
124
- config: Config;
125
- kind: string;
126
- path: string;
127
- }) => {
128
- path: string;
129
- data: Record<string, unknown>;
130
- } | undefined;
131
- };
132
- }, Record<never, never>, false, Record<never, never>, Record<never, never>>;
111
+ }, z.core.$strip>, z.ZodObject<Record<never, never>, z.core.$strip>, "style-property", {}, Record<never, never>, false, Record<never, never>, Record<never, never>>;
112
+ /**
113
+ * `StyleProperty.ref('bg')` keeps the path literal in its type, so a component prop declared as the
114
+ * ref is typed by the property it points at: `bg: StyleProperty.ref('bg')` offers the registered `bg`
115
+ * values, and `columns: StyleProperty.ref('gridTemplateColumns')` offers the target's rather than
116
+ * the name's.
117
+ */
118
+ interface StylePropertyClass extends Named<typeof StylePropertyEntity> {}
119
+ declare const StyleProperty: StylePropertyClass;
133
120
  /** `flexDirection` → `flex-direction`. A name already spelled as CSS comes back unchanged. */
134
121
  declare function toCssPropertyName(property: string): string;
135
122
  /**
@@ -145,4 +132,4 @@ declare function cssPropertyNames(styleProp: {
145
132
  readonly properties: readonly string[];
146
133
  }): string[];
147
134
  //#endregion
148
- export { RefMember, STYLE_PROP_VALUE_FORMS, STYLE_PROP_VALUE_LEAVES, StylePropLeaf, StylePropValue, StylePropValueCtx, StylePropValueKind, StyleProperty, classifyStylePropValue, cssPropertyNames, leavesOfStylePropValue, stylePropValueFormOf, stylePropValueSchema, toCssPropertyName };
135
+ export { RefMember, STYLE_PROP_VALUE_FORMS, STYLE_PROP_VALUE_LEAVES, StylePropLeaf, StylePropValue, StylePropValueCtx, StylePropValueKind, StyleProperty, StylePropertyClass, classifyStylePropValue, cssPropertyNames, leavesOfStylePropValue, stylePropValueFormOf, stylePropValueSchema, toCssPropertyName };
@@ -417,12 +417,6 @@ function freePath(config, path) {
417
417
  for (let n = 2; config.resolve("style-property", candidate); n += 1) candidate = `${path}${n}`;
418
418
  return candidate;
419
419
  }
420
- /**
421
- * `StyleProperty.ref('bg')` keeps the path literal in its type, so a component prop declared as the
422
- * ref is typed by the property it points at: `bg: StyleProperty.ref('bg')` offers the registered `bg`
423
- * values, and `columns: StyleProperty.ref('gridTemplateColumns')` offers the target's rather than
424
- * the name's.
425
- */
426
420
  const StyleProperty = defineEntity({
427
421
  kind: "style-property",
428
422
  label: "Style property",
@@ -61,11 +61,7 @@ declare const TokenEntity: EntityClass<z.ZodObject<{
61
61
  }, z.core.$strip>>>;
62
62
  }, z.core.$strip>, z.ZodObject<{
63
63
  cssPrefix: z.ZodOptional<z.ZodString>;
64
- }, z.core.$strip>, "token", {
65
- readonly create: {
66
- readonly description: `Create a token at \`<group>/<name>\` \u2014 \`data.value\` is the CSS value. The first path segment is its group, and a style property takes a whole group as one ref (\`${string}\`), so put the tokens one prop should offer in one group rather than listing values on the prop.`;
67
- };
68
- }, Record<never, never>, false, Record<never, never>, Record<never, never>>;
64
+ }, z.core.$strip>, "token", {}, Record<never, never>, false, Record<never, never>, Record<never, never>>;
69
65
  /** A token ref as an authoring file holds it: the marker, `extend`, and the value readers. */
70
66
  type TokenReference<Path extends string> = KindRef<typeof tokenFields, 'token', Path> & TokenReaders<Path>;
71
67
  /**
@@ -73,9 +69,16 @@ type TokenReference<Path extends string> = KindRef<typeof tokenFields, 'token',
73
69
  * registered group — `` `spacing/${gutter}` `` — whose readers stay open since no one token is named.
74
70
  */
75
71
  type TokenRefPath = PathOf<'token'> | `${PathOf<'token'>}/${string}`;
76
- declare function tokenRef<const Path extends TokenRefPath>(path: Path): TokenReference<Path>;
77
- declare const Token: Omit<typeof TokenEntity, "ref"> & {
72
+ /**
73
+ * `Path` when `Token.ref` should take it, else `never`. A completion under a registered path is only
74
+ * open when it is known at runtime alone: `` `spacing/${gutter}` `` passes, and a literal
75
+ * `'color/nope'` doesn't, since a literal names one token and that token has to be registered.
76
+ */
77
+ type CheckedTokenRefPath<Path extends string> = Path extends PathOf<'token'> ? Path : Path extends `${PathOf<'token'>}/${infer Rest}` ? Record<never, never> extends Record<Rest, unknown> ? Path : never : never;
78
+ declare function tokenRef<const Path extends TokenRefPath>(path: Path & CheckedTokenRefPath<Path>): TokenReference<Path>;
79
+ declare const Token: TokenClass;
80
+ interface TokenClass extends Omit<typeof TokenEntity, 'ref'> {
78
81
  readonly ref: typeof tokenRef;
79
- };
82
+ }
80
83
  //#endregion
81
- export { OverrideCondition, Token, TokenBody, TokenRefPath, TokenReference, defineOverride, overrideCondition, overrideKey, overrideKeyModifiers, overrideModifiers };
84
+ export { CheckedTokenRefPath, OverrideCondition, Token, TokenBody, TokenClass, TokenRefPath, TokenReference, defineOverride, overrideCondition, overrideKey, overrideKeyModifiers, overrideModifiers };
@@ -1,98 +1,13 @@
1
1
  import { ComputedInput } from "../../framework/registry.js";
2
2
  import { DerivedEntityClass } from "../../framework/defineDerivedEntity.js";
3
+ import { Named } from "../../framework/named.js";
3
4
  import { Config } from "../../framework/Config.js";
5
+ import { OperationClass } from "./Operation.js";
4
6
  import { z } from "zod";
5
7
 
6
8
  //#region src/entities/system/Tool.d.ts
7
- declare const Tool: DerivedEntityClass<z.ZodObject<{
8
- operation: DerivedEntityClass<z.ZodObject<{
9
- kind: z.ZodString;
10
- verb: z.ZodString;
11
- readOnly: z.ZodBoolean;
12
- label: z.ZodString;
13
- description: z.ZodString;
14
- scope: z.ZodString;
15
- creates: z.ZodBoolean;
16
- approval: z.ZodOptional<z.ZodEnum<{
17
- destructive: "destructive";
18
- "reference-change": "reference-change";
19
- }>>;
20
- }, z.core.$strip>, {
21
- inputSchema: ({
22
- member: op,
23
- config
24
- }: Omit<ComputedInput, "member"> & {
25
- member: {
26
- kind: string;
27
- verb: string;
28
- readOnly: boolean;
29
- label: string;
30
- description: string;
31
- scope: string;
32
- creates: boolean;
33
- approval?: "destructive" | "reference-change" | undefined;
34
- };
35
- }) => z.ZodTypeAny<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>> | undefined;
36
- execute: ({
37
- member: op,
38
- config: declaring
39
- }: Omit<ComputedInput, "member"> & {
40
- member: {
41
- kind: string;
42
- verb: string;
43
- readOnly: boolean;
44
- label: string;
45
- description: string;
46
- scope: string;
47
- creates: boolean;
48
- approval?: "destructive" | "reference-change" | undefined;
49
- };
50
- }) => ((input: Record<string, unknown>, config: Config) => unknown) | undefined;
51
- field: ({
52
- member: op
53
- }: Omit<ComputedInput, "member"> & {
54
- member: {
55
- kind: string;
56
- verb: string;
57
- readOnly: boolean;
58
- label: string;
59
- description: string;
60
- scope: string;
61
- creates: boolean;
62
- approval?: "destructive" | "reference-change" | undefined;
63
- };
64
- }) => string | undefined;
65
- title: ({
66
- member: op,
67
- config
68
- }: Omit<ComputedInput, "member"> & {
69
- member: {
70
- kind: string;
71
- verb: string;
72
- readOnly: boolean;
73
- label: string;
74
- description: string;
75
- scope: string;
76
- creates: boolean;
77
- approval?: "destructive" | "reference-change" | undefined;
78
- };
79
- }) => ((entity: string) => string) | undefined;
80
- example: ({
81
- member: op,
82
- config
83
- }: Omit<ComputedInput, "member"> & {
84
- member: {
85
- kind: string;
86
- verb: string;
87
- readOnly: boolean;
88
- label: string;
89
- description: string;
90
- scope: string;
91
- creates: boolean;
92
- approval?: "destructive" | "reference-change" | undefined;
93
- };
94
- }) => Record<string, unknown> | undefined;
95
- }>;
9
+ declare const ToolDefinition: DerivedEntityClass<z.ZodObject<{
10
+ operation: OperationClass;
96
11
  name: z.ZodString;
97
12
  description: z.ZodString;
98
13
  enabled: z.ZodDefault<z.ZodBoolean>;
@@ -130,5 +45,7 @@ declare const Tool: DerivedEntityClass<z.ZodObject<{
130
45
  shortLabel: (input: ComputedInput) => string | undefined; /** Bound to a real entity in this config — built by the op from its own input shape. */
131
46
  example: (input: ComputedInput) => Record<string, unknown> | undefined;
132
47
  }>;
48
+ interface ToolClass extends Named<typeof ToolDefinition> {}
49
+ declare const Tool: ToolClass;
133
50
  //#endregion
134
- export { Tool };
51
+ export { Tool, ToolClass };
@@ -1,5 +1,5 @@
1
- import { DerivedColor, Gradient } from "./color.js";
2
1
  import { Transition } from "./transition.js";
2
+ import { DerivedColor, Gradient } from "./color.js";
3
3
  import { z } from "zod";
4
4
 
5
5
  //#region src/entities/system/composed-values.d.ts
@@ -42,8 +42,8 @@ interface CopyPlanRow {
42
42
  /** Where it lands here, which is also the path the source spells. */
43
43
  readonly path: string;
44
44
  /**
45
- * `create` for a path nothing of yours holds, or one inherited by the pin's declaration; `replace`
46
- * for a pointer stored at the path, which becomes the literal it stood for; `overwrite` for a row of
45
+ * `create` for a path nothing of yours holds; `replace` for a pointer at the path, authored or minted
46
+ * by the link, which becomes the literal it stood for; `overwrite` for a row of
47
47
  * yours, or one held through another pin, that the call asked to write over (`onConflict: 'replace'`).
48
48
  */
49
49
  readonly status: 'create' | 'replace' | 'overwrite';
@@ -98,6 +98,7 @@ function planCopy({ config, input }) {
98
98
  const reused = [];
99
99
  /** Every `kind:path` `take` has answered, whichever way, so the walk below visits each once. */
100
100
  const seen = /* @__PURE__ */ new Set();
101
+ const declared = declarationOf(config, slug);
101
102
  const folder = (kind, path) => {
102
103
  if (!folders.some((f) => f.kind === kind && f.path === path)) folders.push({
103
104
  kind,
@@ -110,7 +111,7 @@ function planCopy({ config, input }) {
110
111
  * about this source's values and neither is one of them. `replace` writes theirs over a row of
111
112
  * yours, and over a row held through another pin when the call named it; a row reached only through
112
113
  * a ref stays that pin's, since the person pointed at what named it. A pointer through this pin is
113
- * replaced by the literal it stood for.
114
+ * replaced by the literal it stood for, and a row its declaration minted is reused unless named.
114
115
  */
115
116
  const take = ({ kind, theirs, at, named }) => {
116
117
  const key = `${kind}:${at}`;
@@ -151,13 +152,26 @@ function planCopy({ config, input }) {
151
152
  });
152
153
  if (!fit.ok) return fit;
153
154
  const stored = held ? config.storedBody(kind, at) : void 0;
155
+ const minted = stored !== void 0 && isMintedRow(stored);
156
+ if (!named && minted && covers({
157
+ declared,
158
+ accessor: config.accessorOf(kind) ?? kind,
159
+ path: at
160
+ })) {
161
+ reused.push({
162
+ kind,
163
+ path: at
164
+ });
165
+ return { ok: true };
166
+ }
154
167
  const extend = stored ? stored.extend : void 0;
155
168
  taking.push({
156
169
  kind,
157
170
  theirs,
158
171
  at,
159
172
  named,
160
- ...stored ? { extend: extend ?? {} } : {}
173
+ ...stored ? { extend: extend ?? {} } : {},
174
+ ...minted ? { minted } : {}
161
175
  });
162
176
  return { ok: true };
163
177
  };
@@ -244,9 +258,8 @@ function planCopy({ config, input }) {
244
258
  }
245
259
  }
246
260
  if (taking.length === 0 && wholesale) rejectData(`"${slug}" has nothing to copy.`);
247
- for (let index = 0; index < taking.length; index++) {
248
- const row = taking[index];
249
- const body = source.resolve(row.kind, row.theirs)?.toJSON();
261
+ /** Take what `body` points at by ref. */
262
+ const follow = (body) => {
250
263
  for (const target of collectRefs(body)) {
251
264
  if (sourceOf(target) !== void 0) continue;
252
265
  const depKind = kindOf(target);
@@ -275,6 +288,17 @@ function planCopy({ config, input }) {
275
288
  });
276
289
  folder(depKind, depPath);
277
290
  }
291
+ };
292
+ let walkedFolders = 0;
293
+ for (let index = 0; index < taking.length || walkedFolders < folders.length;) {
294
+ if (walkedFolders < folders.length) {
295
+ const { kind, path } = folders[walkedFolders++];
296
+ follow(ownMeta(source.groups(kind).find((group) => group.path === path)?.meta ?? {}));
297
+ continue;
298
+ }
299
+ const row = taking[index++];
300
+ const body = source.resolve(row.kind, row.theirs)?.toJSON();
301
+ follow(body);
278
302
  for (const named of source.entityOf(row.kind)?.nameEdges?.(body) ?? []) {
279
303
  const depKind = kindOf(named);
280
304
  const dep = source.resolve(depKind, pathOf(named));
@@ -358,7 +382,7 @@ function planCopy({ config, input }) {
358
382
  taking,
359
383
  source
360
384
  });
361
- for (const { kind, theirs, at, extend } of ordered) {
385
+ for (const { kind, theirs, at, extend, minted } of ordered) {
362
386
  const body = config.copyOf({
363
387
  slug,
364
388
  kind,
@@ -371,7 +395,7 @@ function planCopy({ config, input }) {
371
395
  ...body,
372
396
  copiedFrom: `${theirs}@${slug}`
373
397
  };
374
- patches.push(extend === void 0 ? {
398
+ patches.push(extend === void 0 || minted ? {
375
399
  kind,
376
400
  operation: "create",
377
401
  path: at,
@@ -385,13 +409,11 @@ function planCopy({ config, input }) {
385
409
  }
386
410
  for (const { kind, theirs, at } of taking) respell(`${kind}:${theirs}@${slug}`, `${kind}:${at}`);
387
411
  for (const { kind, path } of folders) respell(`${kind}:${path}@${slug}`, `${kind}:${path}`);
388
- const declared = declarationOf(config, slug);
389
412
  if (declared !== void 0) {
390
413
  const removal = /* @__PURE__ */ new Map();
391
414
  for (const { kind, at, named } of taking) {
392
415
  if (!named) continue;
393
- const stored = config.storedBody(kind, at);
394
- if (!stored || !isMintedRow(stored)) continue;
416
+ if (config.storedBody(kind, at) === void 0) continue;
395
417
  if (config.resolve(kind, at)?.borrowedFrom !== slug) continue;
396
418
  const accessor = config.accessorOf(kind) ?? kind;
397
419
  if (!covers({
@@ -777,4 +777,4 @@ interface DefineComponent {
777
777
  declare function definePropsFirst<const P extends PropMap<LayerPath>>(props: P & NoInfer<{ [K in keyof P]: Exact<P[K], AuthoredProp<LayerPath>> }>): ComponentBuilder<LayerMap, P>;
778
778
  declare const defineComponent: DefineComponent;
779
779
  //#endregion
780
- export { AsInput, AuthoredComponent, AuthoredProp, ComponentBuilder, ComponentPropsOf, GlyphComponent, GlyphValue, LayerElement, LayerMap, PhantomCallProps, PhantomReadProps, PropCondition, PropDecl, PropMap, RegisteredMembers, RenderArgs, SlotCodeForm, SlotDecl, StyleRuleInput, defineComponent };
780
+ export { AsInput, AuthoredComponent, AuthoredProp, ComponentBuilder, ComponentPropsOf, DefaultsOf, GlyphComponent, GlyphValue, LayerElement, LayerMap, PhantomCallProps, PhantomReadProps, PropCondition, PropDecl, PropMap, RegisteredMembers, RenderArgs, SlotCodeForm, SlotDecl, StyleRuleInput, defineComponent };
@@ -1,5 +1,4 @@
1
- import { SubEntityClass } from "../../framework/defineSubEntity.js";
2
- import { EntityClass } from "../../framework/defineEntity.js";
1
+ import { PackageClass } from "./Package.js";
3
2
  import { z } from "zod";
4
3
 
5
4
  //#region src/entities/system/icon-metadata.d.ts
@@ -41,10 +40,7 @@ type IconMemberMetadata = z.infer<typeof iconMemberMetadata>;
41
40
  * kind that exists; when `File`/`Url` land, `from` widens to a union — the shape stays.
42
41
  */
43
42
  declare const iconMetadataDeclaration: z.ZodObject<{
44
- from: EntityClass<z.ZodObject<{
45
- version: z.ZodOptional<z.ZodString>;
46
- exports: z.ZodOptional<SubEntityClass<z.ZodObject<{}, z.core.$strict>>>;
47
- }, z.core.$strict>, z.ZodObject<Record<never, never>, z.core.$strip>, "package", Record<never, never>, Record<never, never>, false, Record<never, never>, Record<never, never>>;
43
+ from: PackageClass;
48
44
  format: z.ZodEnum<{
49
45
  uds: "uds";
50
46
  phosphor: "phosphor";
@@ -6,10 +6,21 @@ import { Config, Patch, TreeNode } from "../../framework/Config.js";
6
6
  /** What one op names, keyed by accessor the way the pin's `link` is: every entry of the kind, or the
7
7
  * source's paths, where a folder names its members. `'*'` alone is every kind the source offers. */
8
8
  type LinkPaths = '*' | Readonly<Record<string, '*' | readonly string[]>>;
9
+ /** What a link does at a path held through another linked system: `'take'` makes the row follow this
10
+ * source, `'keep'` leaves it with the system it comes from. */
11
+ type OnLinked = 'keep' | 'take';
9
12
  interface LinkPlanInput {
10
13
  /** The pin's slug. */
11
14
  readonly path: string;
12
15
  readonly data: LinkPaths;
16
+ /** Planned as `'take'` when omitted; the `link` op refuses without it while `linked` is not empty. */
17
+ readonly onLinked?: OnLinked;
18
+ }
19
+ /** A path the link reaches that another linked system provides, or declares under a row of this
20
+ * config's own. */
21
+ interface LinkedElsewhere extends EntityAddress {
22
+ /** The slug of the pin it comes through. */
23
+ readonly from: string;
13
24
  }
14
25
  /** One row a link mints. `named` when a path the call named covers it; otherwise it comes along
15
26
  * because something linked points at it. */
@@ -25,6 +36,8 @@ interface LinkPlan {
25
36
  readonly replaces: number;
26
37
  /** Rows of this config's own deleted so the source's row shows through at the path. */
27
38
  readonly addresses: readonly EntityAddress[];
39
+ /** Every path the link reaches that another linked system provides, whatever `onLinked` says. */
40
+ readonly linked: readonly LinkedElsewhere[];
28
41
  /** Rows held through another pin, turned into extensions through this one. */
29
42
  readonly extended: readonly EntityAddress[];
30
43
  /** Members already here from the source's own origin, left alone and kept out of the declaration. */
@@ -79,10 +92,17 @@ interface SourceRowState {
79
92
  readonly name: string;
80
93
  /** Members this config can hold. A folder counts its leaves, an item counts one. */
81
94
  readonly members: number;
95
+ /** Members held through this pin, whether linked by name or come along with another link. */
96
+ readonly held: number;
82
97
  /** Every member is held through this pin. */
83
98
  readonly linked: boolean;
84
99
  /** Rows of this config's own a `link` would write over. */
85
100
  readonly replaces: number;
101
+ /** Members another linked system provides or also declares, which a `link` asks about through
102
+ * `onLinked`. */
103
+ readonly linkedElsewhere: number;
104
+ /** The slugs of the pins those come through. */
105
+ readonly linkedFrom: readonly string[];
86
106
  /** Members already here from the source's own origin, through another pin. */
87
107
  readonly shared: number;
88
108
  /** That origin's name, when `shared` is above zero. */
@@ -95,10 +115,11 @@ interface SourceRowState {
95
115
  * The declaration goes first. A row of this config's own that other rows point at can only be deleted
96
116
  * once the declaration covers the path, since the config refuses a delete that leaves a referrer
97
117
  * dangling. A row held through another pin is not deleted — that pin's declaration would mint it
98
- * again, and declaring one path on two pins is a collision nothing derives — so it becomes an
99
- * extension through this pin: a row of this config's own that shadows the other pin's and follows this
100
- * source. A member already here from the source's own origin is left alone and kept out of the
101
- * declaration, so a folder that holds one is declared by its other members.
118
+ * again, and declaring one path on two pins is a collision nothing derives. With `onLinked: 'take'` it
119
+ * becomes an extension through this pin: a row of this config's own that shadows the other pin's and
120
+ * follows this source. With `'keep'` it stays with the other pin and out of the declaration. A member
121
+ * already here from the source's own origin is left alone and kept out of the declaration, so a
122
+ * folder that holds one is declared by its other members.
102
123
  */
103
124
  declare function planLink({
104
125
  config,
@@ -157,4 +178,4 @@ declare function sourceRowStates({
157
178
  readonly slug: string;
158
179
  }): SourceRowState[];
159
180
  //#endregion
160
- export { BreakOutcome, BreakPlan, BreakPlanInput, BreakPlanRow, BreakReach, LinkArrival, LinkPaths, LinkPlan, LinkPlanInput, SourceRowState, UnlinkPlan, UnlinkPlanInput, planBreak, planLink, planUnlink, sourceRowStates };
181
+ export { BreakOutcome, BreakPlan, BreakPlanInput, BreakPlanRow, BreakReach, LinkArrival, LinkPaths, LinkPlan, LinkPlanInput, LinkedElsewhere, OnLinked, SourceRowState, UnlinkPlan, UnlinkPlanInput, planBreak, planLink, planUnlink, sourceRowStates };
@@ -42,6 +42,20 @@ function sharedWithOrigin({ config, source, slug, kind, path }) {
42
42
  if (!theirs || !mine || theirs.key !== mine.key) return void 0;
43
43
  return theirs.pin.displayName ?? theirs.key;
44
44
  }
45
+ /** Another pin whose declaration covers the path and whose source has it: the pin the path would
46
+ * derive from if this config held nothing there. */
47
+ function declaredElsewhere({ config, slug, kind, path }) {
48
+ const accessor = config.accessorOf(kind) ?? kind;
49
+ for (const pin of config.list(PIN_KIND)) {
50
+ if (pin.path === slug) continue;
51
+ if (!covers({
52
+ declared: declarationOf(config, pin.path),
53
+ accessor,
54
+ path
55
+ })) continue;
56
+ if (config.sourceFor(pin.path)?.resolve(kind, path)) return pin.path;
57
+ }
58
+ }
45
59
  /**
46
60
  * Link paths of a source: the declaration that mints them, then the edits that let them show through
47
61
  * where this config already holds something.
@@ -49,10 +63,11 @@ function sharedWithOrigin({ config, source, slug, kind, path }) {
49
63
  * The declaration goes first. A row of this config's own that other rows point at can only be deleted
50
64
  * once the declaration covers the path, since the config refuses a delete that leaves a referrer
51
65
  * dangling. A row held through another pin is not deleted — that pin's declaration would mint it
52
- * again, and declaring one path on two pins is a collision nothing derives — so it becomes an
53
- * extension through this pin: a row of this config's own that shadows the other pin's and follows this
54
- * source. A member already here from the source's own origin is left alone and kept out of the
55
- * declaration, so a folder that holds one is declared by its other members.
66
+ * again, and declaring one path on two pins is a collision nothing derives. With `onLinked: 'take'` it
67
+ * becomes an extension through this pin: a row of this config's own that shadows the other pin's and
68
+ * follows this source. With `'keep'` it stays with the other pin and out of the declaration. A member
69
+ * already here from the source's own origin is left alone and kept out of the declaration, so a
70
+ * folder that holds one is declared by its other members.
56
71
  */
57
72
  function planLink({ config, input }) {
58
73
  const { path: slug } = input;
@@ -66,12 +81,13 @@ function planLink({ config, input }) {
66
81
  verb: "link"
67
82
  });
68
83
  const addresses = [];
84
+ const linked = [];
69
85
  const extended = [];
70
86
  const shared = [];
71
87
  const shadows = [];
72
88
  /** Per accessor, what the declaration gains: the kind whole, or paths. */
73
89
  const gains = /* @__PURE__ */ new Map();
74
- let sharedAnywhere = false;
90
+ let leftAnywhere = false;
75
91
  const shadow = (kind, path) => {
76
92
  const held = config.resolve(kind, path);
77
93
  if (!held || held.borrowedFrom === slug) return true;
@@ -86,10 +102,16 @@ function planLink({ config, input }) {
86
102
  kind,
87
103
  path
88
104
  });
89
- sharedAnywhere = true;
105
+ leftAnywhere = true;
90
106
  return false;
91
107
  }
92
- if (held.borrowedFrom === void 0) {
108
+ const from = held.borrowedFrom ?? declaredElsewhere({
109
+ config,
110
+ slug,
111
+ kind,
112
+ path
113
+ });
114
+ if (from === void 0) {
93
115
  addresses.push({
94
116
  kind,
95
117
  path
@@ -101,6 +123,20 @@ function planLink({ config, input }) {
101
123
  });
102
124
  return true;
103
125
  }
126
+ linked.push({
127
+ kind,
128
+ path,
129
+ from
130
+ });
131
+ if (input.onLinked === "keep") {
132
+ if (held.borrowedFrom === void 0) shadows.push({
133
+ kind,
134
+ operation: "delete",
135
+ path
136
+ });
137
+ leftAnywhere = true;
138
+ return false;
139
+ }
104
140
  const stored = config.storedBody(kind, path);
105
141
  const minted = stored !== void 0 && isMintedRow(stored);
106
142
  extended.push({
@@ -145,7 +181,7 @@ function planLink({ config, input }) {
145
181
  }
146
182
  const declares = [];
147
183
  let declared = current;
148
- if (current !== "*") if (input.data === "*" && !sharedAnywhere) {
184
+ if (current !== "*") if (input.data === "*" && !leftAnywhere) {
149
185
  declared = "*";
150
186
  declares.push({
151
187
  kind: PIN_KIND,
@@ -192,6 +228,7 @@ function planLink({ config, input }) {
192
228
  }),
193
229
  replaces: addresses.length,
194
230
  addresses,
231
+ linked,
195
232
  extended,
196
233
  shared,
197
234
  patches
@@ -485,7 +522,7 @@ function planBreak({ config, input }) {
485
522
  const pointing = /* @__PURE__ */ new Map();
486
523
  /** Folders drawn through the pin by a pointer of this config's own, released once their members are copied. */
487
524
  const pointedFolders = [];
488
- const reach = ({ kind, path, reach }) => {
525
+ const reach = ({ kind, path, reach: how }) => {
489
526
  const held = config.resolve(kind, path);
490
527
  if (held?.borrowedFrom === slug) {
491
528
  copying.path(kind, path);
@@ -495,7 +532,7 @@ function planBreak({ config, input }) {
495
532
  folder: false,
496
533
  refs: [ref(kind, path, slug).__ref],
497
534
  outcome: "copied",
498
- reach
535
+ reach: how
499
536
  });
500
537
  return;
501
538
  }
@@ -516,9 +553,15 @@ function planBreak({ config, input }) {
516
553
  folder: true,
517
554
  refs: [ref(kind, path, slug).__ref],
518
555
  outcome: "copied",
519
- reach
556
+ reach: how
520
557
  });
558
+ return;
521
559
  }
560
+ for (const member of config.members(kind, path)) if (member.borrowedFrom === slug) reach({
561
+ kind,
562
+ path: member.path,
563
+ reach: "taken"
564
+ });
522
565
  return;
523
566
  }
524
567
  const refs = drawnThroughPin({
@@ -534,7 +577,7 @@ function planBreak({ config, input }) {
534
577
  }
535
578
  pointing.set(`${kind}:${path}`, {
536
579
  refs,
537
- reach
580
+ reach: how
538
581
  });
539
582
  };
540
583
  if (scoped) for (const { kind, accessor, paths } of wantedKinds({
@@ -730,6 +773,8 @@ function sourceRowStates({ config, slug }) {
730
773
  if (members.length === 0) continue;
731
774
  let linked = 0;
732
775
  let local = 0;
776
+ let elsewhere = 0;
777
+ const linkedFrom = /* @__PURE__ */ new Set();
733
778
  let shared = 0;
734
779
  let sharedOrigin;
735
780
  for (const leaf of members) {
@@ -739,7 +784,6 @@ function sourceRowStates({ config, slug }) {
739
784
  linked += 1;
740
785
  continue;
741
786
  }
742
- local += 1;
743
787
  const origin = sharedWithOrigin({
744
788
  config: derived,
745
789
  source,
@@ -747,10 +791,19 @@ function sourceRowStates({ config, slug }) {
747
791
  kind,
748
792
  path: leaf.path
749
793
  });
794
+ const from = origin === void 0 ? held.borrowedFrom ?? declaredElsewhere({
795
+ config: derived,
796
+ slug,
797
+ kind,
798
+ path: leaf.path
799
+ }) : void 0;
750
800
  if (origin !== void 0) {
751
801
  shared += 1;
752
802
  sharedOrigin ??= origin;
753
- }
803
+ } else if (from !== void 0) {
804
+ elsewhere += 1;
805
+ linkedFrom.add(from);
806
+ } else local += 1;
754
807
  }
755
808
  rows.push({
756
809
  kind,
@@ -758,8 +811,11 @@ function sourceRowStates({ config, slug }) {
758
811
  type: node.type,
759
812
  name: node.item?.displayLabel ?? node.name,
760
813
  members: members.length,
814
+ held: linked,
761
815
  linked: linked === members.length,
762
- replaces: local - shared,
816
+ replaces: local,
817
+ linkedElsewhere: elsewhere,
818
+ linkedFrom: [...linkedFrom],
763
819
  shared,
764
820
  ...sharedOrigin === void 0 ? {} : { sharedOrigin }
765
821
  });