@cratis/scene.engine 4.3.0 → 4.5.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 (141) hide show
  1. package/dist/cjs/editing/collectIconUsages.js +86 -0
  2. package/dist/cjs/editing/collectIconUsages.js.map +1 -0
  3. package/dist/cjs/editing/diagnoseIcons.js +67 -0
  4. package/dist/cjs/editing/diagnoseIcons.js.map +1 -0
  5. package/dist/cjs/editing/iconDiagnostics.js +103 -0
  6. package/dist/cjs/editing/iconDiagnostics.js.map +1 -0
  7. package/dist/cjs/editing/inspect.js +28 -1
  8. package/dist/cjs/editing/inspect.js.map +1 -1
  9. package/dist/cjs/editing/instanceEdits.js +15 -3
  10. package/dist/cjs/editing/instanceEdits.js.map +1 -1
  11. package/dist/cjs/editing/propertyEdits.js +7 -0
  12. package/dist/cjs/editing/propertyEdits.js.map +1 -1
  13. package/dist/cjs/icons/EffectiveIconCatalog.js +212 -0
  14. package/dist/cjs/icons/EffectiveIconCatalog.js.map +1 -0
  15. package/dist/cjs/icons/EffectiveIconEntry.js +22 -0
  16. package/dist/cjs/icons/EffectiveIconEntry.js.map +1 -0
  17. package/dist/cjs/icons/analyzeIconImpact.js +48 -0
  18. package/dist/cjs/icons/analyzeIconImpact.js.map +1 -0
  19. package/dist/cjs/icons/matchesIconQuery.js +22 -0
  20. package/dist/cjs/icons/matchesIconQuery.js.map +1 -0
  21. package/dist/cjs/icons/resolveIconLibraries.js +45 -0
  22. package/dist/cjs/icons/resolveIconLibraries.js.map +1 -0
  23. package/dist/cjs/index.js +16 -0
  24. package/dist/cjs/index.js.map +1 -1
  25. package/dist/esm/editing/EditingContext.d.ts +2 -0
  26. package/dist/esm/editing/EditingContext.d.ts.map +1 -1
  27. package/dist/esm/editing/collectIconUsages.d.ts +5 -0
  28. package/dist/esm/editing/collectIconUsages.d.ts.map +1 -0
  29. package/dist/esm/editing/collectIconUsages.js +84 -0
  30. package/dist/esm/editing/collectIconUsages.js.map +1 -0
  31. package/dist/esm/editing/diagnoseIcons.d.ts +4 -0
  32. package/dist/esm/editing/diagnoseIcons.d.ts.map +1 -0
  33. package/dist/esm/editing/diagnoseIcons.js +65 -0
  34. package/dist/esm/editing/diagnoseIcons.js.map +1 -0
  35. package/dist/esm/editing/iconDiagnostics.d.ts +11 -0
  36. package/dist/esm/editing/iconDiagnostics.d.ts.map +1 -0
  37. package/dist/esm/editing/iconDiagnostics.js +99 -0
  38. package/dist/esm/editing/iconDiagnostics.js.map +1 -0
  39. package/dist/esm/editing/index.d.ts +3 -0
  40. package/dist/esm/editing/index.d.ts.map +1 -1
  41. package/dist/esm/editing/index.js +3 -0
  42. package/dist/esm/editing/index.js.map +1 -1
  43. package/dist/esm/editing/inspect.d.ts.map +1 -1
  44. package/dist/esm/editing/inspect.js +29 -2
  45. package/dist/esm/editing/inspect.js.map +1 -1
  46. package/dist/esm/editing/instanceEdits.d.ts.map +1 -1
  47. package/dist/esm/editing/instanceEdits.js +17 -5
  48. package/dist/esm/editing/instanceEdits.js.map +1 -1
  49. package/dist/esm/editing/propertyEdits.d.ts.map +1 -1
  50. package/dist/esm/editing/propertyEdits.js +9 -2
  51. package/dist/esm/editing/propertyEdits.js.map +1 -1
  52. package/dist/esm/icons/EffectiveIconCatalog.d.ts +25 -0
  53. package/dist/esm/icons/EffectiveIconCatalog.d.ts.map +1 -0
  54. package/dist/esm/icons/EffectiveIconCatalog.js +210 -0
  55. package/dist/esm/icons/EffectiveIconCatalog.js.map +1 -0
  56. package/dist/esm/icons/EffectiveIconEntry.d.ts +9 -0
  57. package/dist/esm/icons/EffectiveIconEntry.d.ts.map +1 -0
  58. package/dist/esm/icons/EffectiveIconEntry.js +20 -0
  59. package/dist/esm/icons/EffectiveIconEntry.js.map +1 -0
  60. package/dist/esm/icons/IconCatalogSource.d.ts +6 -0
  61. package/dist/esm/icons/IconCatalogSource.d.ts.map +1 -0
  62. package/dist/esm/icons/IconCatalogSource.js +2 -0
  63. package/dist/esm/icons/IconCatalogSource.js.map +1 -0
  64. package/dist/esm/icons/IconDiagnostic.d.ts +9 -0
  65. package/dist/esm/icons/IconDiagnostic.d.ts.map +1 -0
  66. package/dist/esm/icons/IconDiagnostic.js +2 -0
  67. package/dist/esm/icons/IconDiagnostic.js.map +1 -0
  68. package/dist/esm/icons/IconImpactReport.d.ts +18 -0
  69. package/dist/esm/icons/IconImpactReport.d.ts.map +1 -0
  70. package/dist/esm/icons/IconImpactReport.js +2 -0
  71. package/dist/esm/icons/IconImpactReport.js.map +1 -0
  72. package/dist/esm/icons/IconLibraryResolution.d.ts +7 -0
  73. package/dist/esm/icons/IconLibraryResolution.d.ts.map +1 -0
  74. package/dist/esm/icons/IconLibraryResolution.js +2 -0
  75. package/dist/esm/icons/IconLibraryResolution.js.map +1 -0
  76. package/dist/esm/icons/IconQuery.d.ts +7 -0
  77. package/dist/esm/icons/IconQuery.d.ts.map +1 -0
  78. package/dist/esm/icons/IconQuery.js +2 -0
  79. package/dist/esm/icons/IconQuery.js.map +1 -0
  80. package/dist/esm/icons/IconResolution.d.ts +14 -0
  81. package/dist/esm/icons/IconResolution.d.ts.map +1 -0
  82. package/dist/esm/icons/IconResolution.js +2 -0
  83. package/dist/esm/icons/IconResolution.js.map +1 -0
  84. package/dist/esm/icons/IconSearchResult.d.ts +7 -0
  85. package/dist/esm/icons/IconSearchResult.d.ts.map +1 -0
  86. package/dist/esm/icons/IconSearchResult.js +2 -0
  87. package/dist/esm/icons/IconSearchResult.js.map +1 -0
  88. package/dist/esm/icons/IconUsage.d.ts +6 -0
  89. package/dist/esm/icons/IconUsage.d.ts.map +1 -0
  90. package/dist/esm/icons/IconUsage.js +2 -0
  91. package/dist/esm/icons/IconUsage.js.map +1 -0
  92. package/dist/esm/icons/ResolvedIconLibrary.d.ts +8 -0
  93. package/dist/esm/icons/ResolvedIconLibrary.d.ts.map +1 -0
  94. package/dist/esm/icons/ResolvedIconLibrary.js +2 -0
  95. package/dist/esm/icons/ResolvedIconLibrary.js.map +1 -0
  96. package/dist/esm/icons/analyzeIconImpact.d.ts +5 -0
  97. package/dist/esm/icons/analyzeIconImpact.d.ts.map +1 -0
  98. package/dist/esm/icons/analyzeIconImpact.js +46 -0
  99. package/dist/esm/icons/analyzeIconImpact.js.map +1 -0
  100. package/dist/esm/icons/index.d.ts +14 -0
  101. package/dist/esm/icons/index.d.ts.map +1 -0
  102. package/dist/esm/icons/index.js +14 -0
  103. package/dist/esm/icons/index.js.map +1 -0
  104. package/dist/esm/icons/matchesIconQuery.d.ts +4 -0
  105. package/dist/esm/icons/matchesIconQuery.d.ts.map +1 -0
  106. package/dist/esm/icons/matchesIconQuery.js +20 -0
  107. package/dist/esm/icons/matchesIconQuery.js.map +1 -0
  108. package/dist/esm/icons/resolveIconLibraries.d.ts +4 -0
  109. package/dist/esm/icons/resolveIconLibraries.d.ts.map +1 -0
  110. package/dist/esm/icons/resolveIconLibraries.js +43 -0
  111. package/dist/esm/icons/resolveIconLibraries.js.map +1 -0
  112. package/dist/esm/index.d.ts +1 -0
  113. package/dist/esm/index.d.ts.map +1 -1
  114. package/dist/esm/index.js +7 -0
  115. package/dist/esm/index.js.map +1 -1
  116. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  117. package/editing/EditingContext.ts +11 -0
  118. package/editing/collectIconUsages.ts +78 -0
  119. package/editing/diagnoseIcons.ts +60 -0
  120. package/editing/iconDiagnostics.ts +90 -0
  121. package/editing/index.ts +3 -0
  122. package/editing/inspect.ts +25 -2
  123. package/editing/instanceEdits.ts +13 -5
  124. package/editing/propertyEdits.ts +10 -2
  125. package/icons/EffectiveIconCatalog.ts +199 -0
  126. package/icons/EffectiveIconEntry.ts +36 -0
  127. package/icons/IconCatalogSource.ts +23 -0
  128. package/icons/IconDiagnostic.ts +45 -0
  129. package/icons/IconImpactReport.ts +63 -0
  130. package/icons/IconLibraryResolution.ts +22 -0
  131. package/icons/IconQuery.ts +27 -0
  132. package/icons/IconResolution.ts +25 -0
  133. package/icons/IconSearchResult.ts +21 -0
  134. package/icons/IconUsage.ts +21 -0
  135. package/icons/ResolvedIconLibrary.ts +32 -0
  136. package/icons/analyzeIconImpact.ts +41 -0
  137. package/icons/index.ts +16 -0
  138. package/icons/matchesIconQuery.ts +19 -0
  139. package/icons/resolveIconLibraries.ts +47 -0
  140. package/index.ts +1 -0
  141. package/package.json +3 -3
@@ -0,0 +1,23 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import { IconEntry } from '@cratis/scene.model';
5
+
6
+ /**
7
+ * Where one icon library's catalog comes from. The library's module provides it; the engine only asks
8
+ * for it when something needs the library's icons, so resolving a profile never loads a catalog.
9
+ *
10
+ * A source supplies metadata only. The artwork for each icon is loaded separately, per icon, by the
11
+ * renderer's adapter for the library.
12
+ */
13
+ export interface IconCatalogSource {
14
+ /**
15
+ * The library the catalog belongs to.
16
+ */
17
+ library: string;
18
+
19
+ /**
20
+ * Loads the library's icon entries. Called at most once per successful load.
21
+ */
22
+ loadEntries(): Promise<IconEntry[]>;
23
+ }
@@ -0,0 +1,45 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import { IconReference } from '@cratis/scene.model';
5
+
6
+ /**
7
+ * What can be wrong with an icon library or an icon reference. Each is a distinct, reportable condition -
8
+ * none of them is ever resolved by quietly substituting another icon.
9
+ */
10
+ export type IconDiagnosticKind =
11
+ /** The reference names a library that is not active in the profile. */
12
+ | 'missing-library'
13
+ /** The library is active but its catalog has no icon with the reference's key. */
14
+ | 'missing-icon'
15
+ /** The icon exists but not in the variant the reference asks for. */
16
+ | 'missing-variant'
17
+ /** The library is active but at a version a package that needs it does not accept. */
18
+ | 'incompatible-version'
19
+ /** The library is active but its catalog could not be loaded. */
20
+ | 'catalog-unavailable';
21
+
22
+ /**
23
+ * One finding about an icon library or reference, carrying enough to explain it to an author.
24
+ */
25
+ export interface IconDiagnostic {
26
+ /**
27
+ * What kind of problem this is.
28
+ */
29
+ kind: IconDiagnosticKind;
30
+
31
+ /**
32
+ * The library the finding is about.
33
+ */
34
+ library: string;
35
+
36
+ /**
37
+ * A sentence an author can act on.
38
+ */
39
+ message: string;
40
+
41
+ /**
42
+ * The reference the finding is about, when it is about one reference rather than a whole library.
43
+ */
44
+ reference?: IconReference;
45
+ }
@@ -0,0 +1,63 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import { EffectiveIconEntry } from './EffectiveIconEntry';
5
+ import { IconDiagnostic } from './IconDiagnostic';
6
+ import { IconUsage } from './IconUsage';
7
+
8
+ /**
9
+ * A reference the proposed change would leave without an icon.
10
+ */
11
+ export interface AffectedIconUsage {
12
+ /**
13
+ * The usage that would break.
14
+ */
15
+ usage: IconUsage;
16
+
17
+ /**
18
+ * Why it would no longer resolve.
19
+ */
20
+ diagnostic: IconDiagnostic;
21
+
22
+ /**
23
+ * Whether it resolved before the change. `false` marks a reference that was already broken, so a
24
+ * report can tell new damage from old.
25
+ */
26
+ wasResolvable: boolean;
27
+ }
28
+
29
+ /**
30
+ * A legacy bare icon string the report leaves untouched, with the icons it could be migrated to.
31
+ */
32
+ export interface LegacyIconUsage {
33
+ /**
34
+ * The usage holding the legacy string.
35
+ */
36
+ usage: IconUsage;
37
+
38
+ /**
39
+ * The icons in the proposed catalog whose name or key equals the string. Empty means nothing to
40
+ * migrate to; more than one means the author has to choose a library.
41
+ */
42
+ candidates: EffectiveIconEntry[];
43
+ }
44
+
45
+ /**
46
+ * What a library change would do to a set of persisted icon values. It describes; it never rewrites.
47
+ */
48
+ export interface IconImpactReport {
49
+ /**
50
+ * References that resolve now (or did) and would not after the change.
51
+ */
52
+ affected: AffectedIconUsage[];
53
+
54
+ /**
55
+ * How many references resolve after the change.
56
+ */
57
+ unaffectedCount: number;
58
+
59
+ /**
60
+ * Legacy strings, which are neither affected nor rewritten by a library change.
61
+ */
62
+ legacy: LegacyIconUsage[];
63
+ }
@@ -0,0 +1,22 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import { IconDiagnostic } from './IconDiagnostic';
5
+ import { ResolvedIconLibrary } from './ResolvedIconLibrary';
6
+
7
+ /**
8
+ * The icon libraries a set of packages makes active, and what is wrong with them.
9
+ */
10
+ export interface IconLibraryResolution {
11
+ /**
12
+ * Every active icon library - selected or required transitively - in the dependency order of
13
+ * {@link resolvePackageDependencies}. Order carries no precedence: libraries coexist, and the library
14
+ * is part of every icon's identity.
15
+ */
16
+ libraries: ResolvedIconLibrary[];
17
+
18
+ /**
19
+ * Problems with the libraries themselves, such as a version a dependent does not accept.
20
+ */
21
+ diagnostics: IconDiagnostic[];
22
+ }
@@ -0,0 +1,27 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ /**
5
+ * What a picker asks the effective catalog for. Every field narrows; an empty query returns everything.
6
+ */
7
+ export interface IconQuery {
8
+ /**
9
+ * Free text, matched case-insensitively against each icon's name, key, aliases and tags.
10
+ */
11
+ text?: string;
12
+
13
+ /**
14
+ * Only the icons of this library. Narrowing to one library also means only that library's catalog is loaded.
15
+ */
16
+ library?: string;
17
+
18
+ /**
19
+ * Only the icons filed under this category.
20
+ */
21
+ category?: string;
22
+
23
+ /**
24
+ * Only the icons that exist in this variant.
25
+ */
26
+ variant?: string;
27
+ }
@@ -0,0 +1,25 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import { IconEntry, IconReference } from '@cratis/scene.model';
5
+ import { IconDiagnostic } from './IconDiagnostic';
6
+ import { ResolvedIconLibrary } from './ResolvedIconLibrary';
7
+
8
+ /**
9
+ * The outcome of looking one reference up in the effective catalog: either the icon it names, or the
10
+ * precise reason there is none.
11
+ */
12
+ export type IconResolution =
13
+ | {
14
+ /** The reference resolved. */
15
+ isResolved: true;
16
+ reference: IconReference;
17
+ library: ResolvedIconLibrary;
18
+ entry: IconEntry;
19
+ }
20
+ | {
21
+ /** The reference did not resolve. */
22
+ isResolved: false;
23
+ reference: IconReference;
24
+ diagnostic: IconDiagnostic;
25
+ };
@@ -0,0 +1,21 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import { EffectiveIconEntry } from './EffectiveIconEntry';
5
+ import { IconDiagnostic } from './IconDiagnostic';
6
+
7
+ /**
8
+ * The outcome of querying the effective catalog.
9
+ */
10
+ export interface IconSearchResult {
11
+ /**
12
+ * The icons that matched, library by library in resolution order and in each catalog's own order.
13
+ */
14
+ entries: EffectiveIconEntry[];
15
+
16
+ /**
17
+ * Libraries whose catalog could not be loaded and so contributed nothing - reported rather than
18
+ * dropped, so an absent icon is never mistaken for one that does not exist.
19
+ */
20
+ diagnostics: IconDiagnostic[];
21
+ }
@@ -0,0 +1,21 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import { IconReference } from '@cratis/scene.model';
5
+
6
+ /**
7
+ * One place an icon is used - a persisted value somewhere in a screen, template, blueprint or profile.
8
+ */
9
+ export interface IconUsage {
10
+ /**
11
+ * The icon value as persisted: an {@link IconReference}, or a legacy bare string (an icon font class
12
+ * such as `pi pi-home`) from before icons were library-qualified.
13
+ */
14
+ value: IconReference | string;
15
+
16
+ /**
17
+ * Where the value lives, in whatever terms the caller wants reported back (a screen name, a path).
18
+ * Never interpreted.
19
+ */
20
+ location?: string;
21
+ }
@@ -0,0 +1,32 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import { ScenePackage } from '@cratis/scene.model';
5
+
6
+ /**
7
+ * An icon library that is active in a profile, with the reason it is.
8
+ */
9
+ export interface ResolvedIconLibrary {
10
+ /**
11
+ * The library's identity - what an {@link IconReference.library} names.
12
+ */
13
+ library: string;
14
+
15
+ /**
16
+ * The package declaration behind the library: version, license, attribution, renderers.
17
+ */
18
+ package: ScenePackage;
19
+
20
+ /**
21
+ * Whether the profile lists the library itself. `false` means it is only active because something
22
+ * else needs it.
23
+ */
24
+ isSelected: boolean;
25
+
26
+ /**
27
+ * The names of the active packages that declare a dependency on the library. Together with
28
+ * {@link isSelected} this is the library's provenance: why it is here, and what stops depending on it
29
+ * when it is removed.
30
+ */
31
+ requiredBy: string[];
32
+ }
@@ -0,0 +1,41 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import { isIconReference } from '@cratis/scene.model';
5
+ import { AffectedIconUsage, IconImpactReport, LegacyIconUsage } from './IconImpactReport';
6
+ import { EffectiveIconCatalog } from './EffectiveIconCatalog';
7
+ import { IconUsage } from './IconUsage';
8
+
9
+ /**
10
+ * Reports what changing a profile's icon libraries - removing one, upgrading one to a version that dropped
11
+ * icons, swapping one - would do to icon values already persisted, without touching them.
12
+ *
13
+ * Build `proposed` from the packages the profile would have after the change (with
14
+ * {@link resolveIconLibraries} and that package set's catalog sources) and compare it with the `current`
15
+ * one. A reference is *affected* when it does not resolve in `proposed`; `wasResolvable` says whether it did in
16
+ * `current`. Legacy bare strings are listed with the icons in `proposed` that share their name, but are never
17
+ * counted as affected and never rewritten - migrating them is an author's decision, one reference at a time.
18
+ */
19
+ export async function analyzeIconImpact(usages: IconUsage[], current: EffectiveIconCatalog, proposed: EffectiveIconCatalog): Promise<IconImpactReport> {
20
+ const affected: AffectedIconUsage[] = [];
21
+ const legacy: LegacyIconUsage[] = [];
22
+ let unaffectedCount = 0;
23
+
24
+ for (const usage of usages) {
25
+ if (!isIconReference(usage.value)) {
26
+ legacy.push({ usage, candidates: await proposed.findByName(String(usage.value)) });
27
+ continue;
28
+ }
29
+
30
+ const after = await proposed.resolve(usage.value);
31
+ if (after.isResolved) {
32
+ unaffectedCount++;
33
+ continue;
34
+ }
35
+
36
+ const before = await current.resolve(usage.value);
37
+ affected.push({ usage, diagnostic: after.diagnostic, wasResolvable: before.isResolved });
38
+ }
39
+
40
+ return { affected, unaffectedCount, legacy };
41
+ }
package/icons/index.ts ADDED
@@ -0,0 +1,16 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ export * from './IconDiagnostic';
5
+ export * from './ResolvedIconLibrary';
6
+ export * from './IconLibraryResolution';
7
+ export * from './resolveIconLibraries';
8
+ export * from './IconCatalogSource';
9
+ export * from './EffectiveIconEntry';
10
+ export * from './IconQuery';
11
+ export * from './IconSearchResult';
12
+ export * from './IconResolution';
13
+ export * from './EffectiveIconCatalog';
14
+ export * from './IconUsage';
15
+ export * from './IconImpactReport';
16
+ export * from './analyzeIconImpact';
@@ -0,0 +1,19 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import { IconEntry } from '@cratis/scene.model';
5
+ import { IconQuery } from './IconQuery';
6
+
7
+ /**
8
+ * Whether a catalog entry satisfies the entry-level parts of a query - text, category and variant. The
9
+ * library part is decided earlier, because it decides which catalogs get loaded at all.
10
+ */
11
+ export function matchesIconQuery(entry: IconEntry, query: IconQuery): boolean {
12
+ if (query.category !== undefined && !entry.categories.includes(query.category)) return false;
13
+ if (query.variant !== undefined && !(entry.variants ?? []).includes(query.variant)) return false;
14
+
15
+ const text = query.text?.trim().toLowerCase();
16
+ if (!text) return true;
17
+
18
+ return [entry.name, entry.key, ...(entry.aliases ?? []), ...(entry.tags ?? [])].some((term) => term.toLowerCase().includes(text));
19
+ }
@@ -0,0 +1,47 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import { PackageKind, ScenePackage } from '@cratis/scene.model';
5
+ import { resolvePackageDependencies } from '../resolvePackageDependencies';
6
+ import { IconDiagnostic } from './IconDiagnostic';
7
+ import { IconLibraryResolution } from './IconLibraryResolution';
8
+
9
+ /**
10
+ * Finds the icon libraries a profile's packages make active - the ones it lists and the ones its other
11
+ * packages declare a dependency on - through the normal package resolver, so an icon library is
12
+ * selected, ordered and version-checked exactly as any other package is.
13
+ *
14
+ * Several libraries coexist. Nothing here ranks them: two libraries that both ship `home` stay two
15
+ * different icons, told apart by the library in their {@link IconReference}.
16
+ *
17
+ * @param selected The package names the profile lists.
18
+ * @param catalog Every package that could be selected.
19
+ */
20
+ export function resolveIconLibraries(selected: string[], catalog: ScenePackage[]): IconLibraryResolution {
21
+ const selection = resolvePackageDependencies(selected, catalog);
22
+ const index = new Map(catalog.map((scenePackage) => [scenePackage.name, scenePackage]));
23
+ const chosen = new Set(selected);
24
+ const active = selection.packages.map((name) => index.get(name)).filter((scenePackage): scenePackage is ScenePackage => scenePackage !== undefined);
25
+
26
+ const libraries = active
27
+ .filter((scenePackage) => scenePackage.kind === PackageKind.IconLibrary)
28
+ .map((scenePackage) => ({
29
+ library: scenePackage.name,
30
+ package: scenePackage,
31
+ isSelected: chosen.has(scenePackage.name),
32
+ requiredBy: active
33
+ .filter((other) => other.dependencies.some((dependency) => dependency.name === scenePackage.name))
34
+ .map((other) => other.name),
35
+ }));
36
+
37
+ const libraryNames = new Set(libraries.map((resolved) => resolved.library));
38
+ const diagnostics: IconDiagnostic[] = selection.versionConflicts
39
+ .filter((conflict) => libraryNames.has(conflict.dependsOn))
40
+ .map((conflict) => ({
41
+ kind: 'incompatible-version',
42
+ library: conflict.dependsOn,
43
+ message: `'${conflict.package}' needs the icon library '${conflict.dependsOn}' at '${conflict.requiredRange}', but version ${conflict.actualVersion} is what is available`,
44
+ }));
45
+
46
+ return { libraries, diagnostics };
47
+ }
package/index.ts CHANGED
@@ -8,6 +8,7 @@ export * from './elementKind';
8
8
  export * from './panelKind';
9
9
  export * from './flowNodeKind';
10
10
  export * from './ComponentResolution';
11
+ export * from './icons';
11
12
  export * from './resolveComponentName';
12
13
  export * from './computeSizeClass';
13
14
  export * from './evaluateFlowArrangement';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cratis/scene.engine",
3
- "version": "4.3.0",
3
+ "version": "4.5.0",
4
4
  "description": "The Scene runtime: walks a Scene element tree and drives whichever renderer is plugged in. Does not know React, or any other rendering platform, exists.",
5
5
  "keywords": [
6
6
  "cratis",
@@ -48,9 +48,9 @@
48
48
  "up": "yarn g:up"
49
49
  },
50
50
  "dependencies": {
51
- "@cratis/scene.model": "4.3.0"
51
+ "@cratis/scene.model": "4.5.0"
52
52
  },
53
53
  "devDependencies": {
54
- "@cratis/scene.model": "4.3.0"
54
+ "@cratis/scene.model": "4.5.0"
55
55
  }
56
56
  }