@fgv/ts-res-ui-components 5.0.0-10

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 (231) hide show
  1. package/.rush/temp/03c8b056281d9db0a97d8a6e25eea798a160d393.tar.log +271 -0
  2. package/.rush/temp/chunked-rush-logs/ts-res-ui-components.build.chunks.jsonl +9 -0
  3. package/.rush/temp/operation/build/all.log +9 -0
  4. package/.rush/temp/operation/build/log-chunks.jsonl +9 -0
  5. package/.rush/temp/operation/build/state.json +3 -0
  6. package/.rush/temp/shrinkwrap-deps.json +1111 -0
  7. package/README.md +18 -0
  8. package/REFACTORING_PLAN.md +171 -0
  9. package/config/jest.config.json +16 -0
  10. package/config/jest.setup.js +64 -0
  11. package/config/rig.json +16 -0
  12. package/lib/components/common/QualifierContextControl.d.ts +14 -0
  13. package/lib/components/common/QualifierContextControl.d.ts.map +1 -0
  14. package/lib/components/common/QualifierContextControl.js +78 -0
  15. package/lib/components/common/QualifierContextControl.js.map +1 -0
  16. package/lib/components/common/ResourceListView.d.ts +11 -0
  17. package/lib/components/common/ResourceListView.d.ts.map +1 -0
  18. package/lib/components/common/ResourceListView.js +20 -0
  19. package/lib/components/common/ResourceListView.js.map +1 -0
  20. package/lib/components/common/ResourceTreeView.d.ts +12 -0
  21. package/lib/components/common/ResourceTreeView.d.ts.map +1 -0
  22. package/lib/components/common/ResourceTreeView.js +162 -0
  23. package/lib/components/common/ResourceTreeView.js.map +1 -0
  24. package/lib/components/forms/HierarchyEditor.d.ts +10 -0
  25. package/lib/components/forms/HierarchyEditor.d.ts.map +1 -0
  26. package/lib/components/forms/HierarchyEditor.js +106 -0
  27. package/lib/components/forms/HierarchyEditor.js.map +1 -0
  28. package/lib/components/forms/QualifierEditForm.d.ts +11 -0
  29. package/lib/components/forms/QualifierEditForm.d.ts.map +1 -0
  30. package/lib/components/forms/QualifierEditForm.js +181 -0
  31. package/lib/components/forms/QualifierEditForm.js.map +1 -0
  32. package/lib/components/forms/QualifierTypeEditForm.d.ts +10 -0
  33. package/lib/components/forms/QualifierTypeEditForm.d.ts.map +1 -0
  34. package/lib/components/forms/QualifierTypeEditForm.js +172 -0
  35. package/lib/components/forms/QualifierTypeEditForm.js.map +1 -0
  36. package/lib/components/forms/ResourceTypeEditForm.d.ts +10 -0
  37. package/lib/components/forms/ResourceTypeEditForm.d.ts.map +1 -0
  38. package/lib/components/forms/ResourceTypeEditForm.js +188 -0
  39. package/lib/components/forms/ResourceTypeEditForm.js.map +1 -0
  40. package/lib/components/forms/index.d.ts +9 -0
  41. package/lib/components/forms/index.d.ts.map +1 -0
  42. package/lib/components/forms/index.js +5 -0
  43. package/lib/components/forms/index.js.map +1 -0
  44. package/lib/components/orchestrator/ResourceOrchestrator.d.ts +14 -0
  45. package/lib/components/orchestrator/ResourceOrchestrator.d.ts.map +1 -0
  46. package/lib/components/orchestrator/ResourceOrchestrator.js +278 -0
  47. package/lib/components/orchestrator/ResourceOrchestrator.js.map +1 -0
  48. package/lib/components/views/CompiledView/index.d.ts +5 -0
  49. package/lib/components/views/CompiledView/index.d.ts.map +1 -0
  50. package/lib/components/views/CompiledView/index.js +595 -0
  51. package/lib/components/views/CompiledView/index.js.map +1 -0
  52. package/lib/components/views/ConfigurationView/index.d.ts +5 -0
  53. package/lib/components/views/ConfigurationView/index.d.ts.map +1 -0
  54. package/lib/components/views/ConfigurationView/index.js +363 -0
  55. package/lib/components/views/ConfigurationView/index.js.map +1 -0
  56. package/lib/components/views/FilterView/index.d.ts +5 -0
  57. package/lib/components/views/FilterView/index.d.ts.map +1 -0
  58. package/lib/components/views/FilterView/index.js +463 -0
  59. package/lib/components/views/FilterView/index.js.map +1 -0
  60. package/lib/components/views/ImportView/index.d.ts +5 -0
  61. package/lib/components/views/ImportView/index.d.ts.map +1 -0
  62. package/lib/components/views/ImportView/index.js +514 -0
  63. package/lib/components/views/ImportView/index.js.map +1 -0
  64. package/lib/components/views/ResolutionView/EditableJsonView.d.ts +21 -0
  65. package/lib/components/views/ResolutionView/EditableJsonView.d.ts.map +1 -0
  66. package/lib/components/views/ResolutionView/EditableJsonView.js +109 -0
  67. package/lib/components/views/ResolutionView/EditableJsonView.js.map +1 -0
  68. package/lib/components/views/ResolutionView/ResolutionEditControls.d.ts +19 -0
  69. package/lib/components/views/ResolutionView/ResolutionEditControls.d.ts.map +1 -0
  70. package/lib/components/views/ResolutionView/ResolutionEditControls.js +82 -0
  71. package/lib/components/views/ResolutionView/ResolutionEditControls.js.map +1 -0
  72. package/lib/components/views/ResolutionView/index.d.ts +5 -0
  73. package/lib/components/views/ResolutionView/index.d.ts.map +1 -0
  74. package/lib/components/views/ResolutionView/index.js +255 -0
  75. package/lib/components/views/ResolutionView/index.js.map +1 -0
  76. package/lib/components/views/SourceView/index.d.ts +5 -0
  77. package/lib/components/views/SourceView/index.d.ts.map +1 -0
  78. package/lib/components/views/SourceView/index.js +316 -0
  79. package/lib/components/views/SourceView/index.js.map +1 -0
  80. package/lib/components/views/ZipLoaderView/index.d.ts +5 -0
  81. package/lib/components/views/ZipLoaderView/index.d.ts.map +1 -0
  82. package/lib/components/views/ZipLoaderView/index.js +313 -0
  83. package/lib/components/views/ZipLoaderView/index.js.map +1 -0
  84. package/lib/hooks/useConfigurationState.d.ts +46 -0
  85. package/lib/hooks/useConfigurationState.d.ts.map +1 -0
  86. package/lib/hooks/useConfigurationState.js +239 -0
  87. package/lib/hooks/useConfigurationState.js.map +1 -0
  88. package/lib/hooks/useFilterState.d.ts +7 -0
  89. package/lib/hooks/useFilterState.d.ts.map +1 -0
  90. package/lib/hooks/useFilterState.js +80 -0
  91. package/lib/hooks/useFilterState.js.map +1 -0
  92. package/lib/hooks/useResolutionState.d.ts +8 -0
  93. package/lib/hooks/useResolutionState.d.ts.map +1 -0
  94. package/lib/hooks/useResolutionState.js +253 -0
  95. package/lib/hooks/useResolutionState.js.map +1 -0
  96. package/lib/hooks/useResourceData.d.ts +19 -0
  97. package/lib/hooks/useResourceData.d.ts.map +1 -0
  98. package/lib/hooks/useResourceData.js +368 -0
  99. package/lib/hooks/useResourceData.js.map +1 -0
  100. package/lib/hooks/useViewState.d.ts +10 -0
  101. package/lib/hooks/useViewState.d.ts.map +1 -0
  102. package/lib/hooks/useViewState.js +29 -0
  103. package/lib/hooks/useViewState.js.map +1 -0
  104. package/lib/index.d.ts +27 -0
  105. package/lib/index.d.ts.map +1 -0
  106. package/lib/index.js +34 -0
  107. package/lib/index.js.map +1 -0
  108. package/lib/test/helpers/testDataLoader.d.ts +37 -0
  109. package/lib/test/helpers/testDataLoader.d.ts.map +1 -0
  110. package/lib/test/helpers/testDataLoader.js +171 -0
  111. package/lib/test/helpers/testDataLoader.js.map +1 -0
  112. package/lib/test/unit/utils/configurationUtils.test.d.ts +2 -0
  113. package/lib/test/unit/utils/configurationUtils.test.d.ts.map +1 -0
  114. package/lib/test/unit/utils/configurationUtils.test.js +497 -0
  115. package/lib/test/unit/utils/configurationUtils.test.js.map +1 -0
  116. package/lib/test/unit/utils/fileProcessing.test.d.ts +2 -0
  117. package/lib/test/unit/utils/fileProcessing.test.d.ts.map +1 -0
  118. package/lib/test/unit/utils/fileProcessing.test.js +321 -0
  119. package/lib/test/unit/utils/fileProcessing.test.js.map +1 -0
  120. package/lib/test/unit/utils/filterResources.test.d.ts +2 -0
  121. package/lib/test/unit/utils/filterResources.test.d.ts.map +1 -0
  122. package/lib/test/unit/utils/filterResources.test.js +403 -0
  123. package/lib/test/unit/utils/filterResources.test.js.map +1 -0
  124. package/lib/test/unit/utils/resolutionEditing.test.d.ts +2 -0
  125. package/lib/test/unit/utils/resolutionEditing.test.d.ts.map +1 -0
  126. package/lib/test/unit/utils/resolutionEditing.test.js +439 -0
  127. package/lib/test/unit/utils/resolutionEditing.test.js.map +1 -0
  128. package/lib/test/unit/utils/resolutionUtils.test.d.ts +2 -0
  129. package/lib/test/unit/utils/resolutionUtils.test.d.ts.map +1 -0
  130. package/lib/test/unit/utils/resolutionUtils.test.js +397 -0
  131. package/lib/test/unit/utils/resolutionUtils.test.js.map +1 -0
  132. package/lib/test/unit/utils/tsResIntegration.test.d.ts +2 -0
  133. package/lib/test/unit/utils/tsResIntegration.test.d.ts.map +1 -0
  134. package/lib/test/unit/utils/tsResIntegration.test.js +376 -0
  135. package/lib/test/unit/utils/tsResIntegration.test.js.map +1 -0
  136. package/lib/types/index.d.ts +251 -0
  137. package/lib/types/index.d.ts.map +1 -0
  138. package/lib/types/index.js +2 -0
  139. package/lib/types/index.js.map +1 -0
  140. package/lib/utils/configurationUtils.d.ts +74 -0
  141. package/lib/utils/configurationUtils.d.ts.map +1 -0
  142. package/lib/utils/configurationUtils.js +359 -0
  143. package/lib/utils/configurationUtils.js.map +1 -0
  144. package/lib/utils/fileProcessing.d.ts +18 -0
  145. package/lib/utils/fileProcessing.d.ts.map +1 -0
  146. package/lib/utils/fileProcessing.js +142 -0
  147. package/lib/utils/fileProcessing.js.map +1 -0
  148. package/lib/utils/filterResources.d.ts +38 -0
  149. package/lib/utils/filterResources.d.ts.map +1 -0
  150. package/lib/utils/filterResources.js +153 -0
  151. package/lib/utils/filterResources.js.map +1 -0
  152. package/lib/utils/resolutionEditing.d.ts +58 -0
  153. package/lib/utils/resolutionEditing.d.ts.map +1 -0
  154. package/lib/utils/resolutionEditing.js +246 -0
  155. package/lib/utils/resolutionEditing.js.map +1 -0
  156. package/lib/utils/resolutionUtils.d.ts +28 -0
  157. package/lib/utils/resolutionUtils.d.ts.map +1 -0
  158. package/lib/utils/resolutionUtils.js +216 -0
  159. package/lib/utils/resolutionUtils.js.map +1 -0
  160. package/lib/utils/tsResIntegration.d.ts +71 -0
  161. package/lib/utils/tsResIntegration.d.ts.map +1 -0
  162. package/lib/utils/tsResIntegration.js +294 -0
  163. package/lib/utils/tsResIntegration.js.map +1 -0
  164. package/lib/utils/zipLoader/browserZipLoader.d.ts +48 -0
  165. package/lib/utils/zipLoader/browserZipLoader.d.ts.map +1 -0
  166. package/lib/utils/zipLoader/browserZipLoader.js +247 -0
  167. package/lib/utils/zipLoader/browserZipLoader.js.map +1 -0
  168. package/lib/utils/zipLoader/index.d.ts +8 -0
  169. package/lib/utils/zipLoader/index.d.ts.map +1 -0
  170. package/lib/utils/zipLoader/index.js +13 -0
  171. package/lib/utils/zipLoader/index.js.map +1 -0
  172. package/lib/utils/zipLoader/nodeZipBuilder.d.ts +55 -0
  173. package/lib/utils/zipLoader/nodeZipBuilder.d.ts.map +1 -0
  174. package/lib/utils/zipLoader/nodeZipBuilder.js +98 -0
  175. package/lib/utils/zipLoader/nodeZipBuilder.js.map +1 -0
  176. package/lib/utils/zipLoader/types.d.ts +139 -0
  177. package/lib/utils/zipLoader/types.d.ts.map +1 -0
  178. package/lib/utils/zipLoader/types.js +2 -0
  179. package/lib/utils/zipLoader/types.js.map +1 -0
  180. package/lib/utils/zipLoader/zipUtils.d.ts +53 -0
  181. package/lib/utils/zipLoader/zipUtils.d.ts.map +1 -0
  182. package/lib/utils/zipLoader/zipUtils.js +229 -0
  183. package/lib/utils/zipLoader/zipUtils.js.map +1 -0
  184. package/package.json +69 -0
  185. package/rush-logs/ts-res-ui-components.build.cache.log +3 -0
  186. package/rush-logs/ts-res-ui-components.build.log +9 -0
  187. package/src/components/common/QualifierContextControl.tsx +151 -0
  188. package/src/components/common/ResourceListView.tsx +63 -0
  189. package/src/components/common/ResourceTreeView.tsx +271 -0
  190. package/src/components/forms/HierarchyEditor.tsx +204 -0
  191. package/src/components/forms/QualifierEditForm.tsx +355 -0
  192. package/src/components/forms/QualifierTypeEditForm.tsx +347 -0
  193. package/src/components/forms/ResourceTypeEditForm.tsx +331 -0
  194. package/src/components/forms/index.ts +11 -0
  195. package/src/components/orchestrator/ResourceOrchestrator.tsx +372 -0
  196. package/src/components/views/CompiledView/index.tsx +922 -0
  197. package/src/components/views/ConfigurationView/index.tsx +800 -0
  198. package/src/components/views/FilterView/index.tsx +825 -0
  199. package/src/components/views/ImportView/index.tsx +717 -0
  200. package/src/components/views/ResolutionView/EditableJsonView.tsx +214 -0
  201. package/src/components/views/ResolutionView/ResolutionEditControls.tsx +170 -0
  202. package/src/components/views/ResolutionView/index.tsx +591 -0
  203. package/src/components/views/SourceView/index.tsx +536 -0
  204. package/src/components/views/ZipLoaderView/index.tsx +485 -0
  205. package/src/hooks/useConfigurationState.ts +374 -0
  206. package/src/hooks/useFilterState.ts +97 -0
  207. package/src/hooks/useResolutionState.ts +355 -0
  208. package/src/hooks/useResourceData.ts +467 -0
  209. package/src/hooks/useViewState.ts +44 -0
  210. package/src/index.ts +45 -0
  211. package/src/test/helpers/testDataLoader.ts +195 -0
  212. package/src/test/unit/utils/configurationUtils.test.ts +630 -0
  213. package/src/test/unit/utils/fileProcessing.test.ts +391 -0
  214. package/src/test/unit/utils/filterResources.test.ts +574 -0
  215. package/src/test/unit/utils/resolutionEditing.test.ts +556 -0
  216. package/src/test/unit/utils/resolutionUtils.test.ts +521 -0
  217. package/src/test/unit/utils/tsResIntegration.test.ts +433 -0
  218. package/src/types/index.ts +322 -0
  219. package/src/utils/configurationUtils.ts +424 -0
  220. package/src/utils/fileProcessing.ts +160 -0
  221. package/src/utils/filterResources.ts +206 -0
  222. package/src/utils/resolutionEditing.ts +319 -0
  223. package/src/utils/resolutionUtils.ts +289 -0
  224. package/src/utils/tsResIntegration.ts +440 -0
  225. package/src/utils/zipLoader/browserZipLoader.ts +319 -0
  226. package/src/utils/zipLoader/index.ts +26 -0
  227. package/src/utils/zipLoader/nodeZipBuilder.ts +153 -0
  228. package/src/utils/zipLoader/types.ts +175 -0
  229. package/src/utils/zipLoader/zipUtils.ts +266 -0
  230. package/temp/build/typescript/ts_gZid87Hu.json +1 -0
  231. package/tsconfig.json +15 -0
@@ -0,0 +1,289 @@
1
+ import { Result, succeed, fail, MessageAggregator } from '@fgv/ts-utils';
2
+ import { Runtime } from '@fgv/ts-res';
3
+ import { ProcessedResources, ResolutionResult, CandidateInfo, ConditionEvaluationResult } from '../types';
4
+
5
+ export interface ResolutionOptions {
6
+ enableCaching?: boolean;
7
+ enableDebugLogging?: boolean;
8
+ }
9
+
10
+ // Helper function for conditional debug logging
11
+ const debugLog = (enableDebug: boolean, ...args: any[]) => {
12
+ if (enableDebug) {
13
+ console.log(...args);
14
+ }
15
+ };
16
+
17
+ /**
18
+ * Create a resolver with context for resource resolution
19
+ */
20
+ export function createResolverWithContext(
21
+ processedResources: ProcessedResources,
22
+ contextValues: Record<string, string | undefined>,
23
+ options: ResolutionOptions = {}
24
+ ): Result<Runtime.ResourceResolver> {
25
+ const enableDebug = options.enableDebugLogging === true;
26
+
27
+ debugLog(enableDebug, '=== CREATING RESOLVER WITH CONTEXT ===');
28
+ debugLog(enableDebug, 'Context values:', contextValues);
29
+
30
+ // Create context provider with filtered values (remove undefined)
31
+ const filteredContext = Object.fromEntries(
32
+ Object.entries(contextValues).filter(([, value]) => value !== undefined)
33
+ ) as Record<string, string>;
34
+
35
+ return Runtime.ValidatingSimpleContextQualifierProvider.create({
36
+ qualifiers: processedResources.system.qualifiers
37
+ })
38
+ .withErrorFormat((e) => `Failed to create context provider: ${e}`)
39
+ .onSuccess((contextProvider) => {
40
+ const errors = new MessageAggregator();
41
+ // Set context values
42
+ for (const [qualifierName, value] of Object.entries(filteredContext)) {
43
+ contextProvider.validating
44
+ .set(qualifierName, value)
45
+ .withErrorFormat((e) => `Failed to set context value ${qualifierName}=${value}: ${e}`)
46
+ .aggregateError(errors);
47
+ }
48
+
49
+ if (errors.hasMessages) {
50
+ return fail(`Errors setting context values: ${errors.toString()}`);
51
+ }
52
+
53
+ // Create resolver
54
+ const resolverParams: any = {
55
+ resourceManager: processedResources.system.resourceManager,
56
+ qualifierTypes: processedResources.system.qualifierTypes,
57
+ contextQualifierProvider: contextProvider
58
+ };
59
+
60
+ // Add cache metrics listener if caching is enabled
61
+ if (options.enableCaching) {
62
+ const metricsListener = new Runtime.ResourceResolverCacheMetricsListener(
63
+ () => new Runtime.AggregateCacheMetrics()
64
+ );
65
+ resolverParams.listener = metricsListener;
66
+ }
67
+
68
+ return Runtime.ResourceResolver.create(resolverParams)
69
+ .withErrorFormat((e) => `Failed to create resolver: ${e}`)
70
+ .onSuccess((resolver) => {
71
+ debugLog(enableDebug, 'Resolver created successfully');
72
+ return succeed(resolver);
73
+ });
74
+ });
75
+ }
76
+
77
+ /**
78
+ * Evaluate conditions for a specific candidate
79
+ */
80
+ export function evaluateConditionsForCandidate(
81
+ resolver: Runtime.ResourceResolver,
82
+ candidateIndex: number,
83
+ compiledResource: any,
84
+ compiledCollection: any
85
+ ): ConditionEvaluationResult[] {
86
+ try {
87
+ const decision = compiledCollection.decisions[compiledResource.decision];
88
+ if (!decision || !decision.conditionSets || candidateIndex >= decision.conditionSets.length) {
89
+ return [];
90
+ }
91
+
92
+ const conditionSetIndex = decision.conditionSets[candidateIndex];
93
+ const conditionSet = compiledCollection.conditionSets[conditionSetIndex];
94
+ if (!conditionSet || !conditionSet.conditions) {
95
+ return [];
96
+ }
97
+
98
+ const evaluations: ConditionEvaluationResult[] = [];
99
+
100
+ for (const conditionIndex of conditionSet.conditions) {
101
+ const condition = compiledCollection.conditions[conditionIndex];
102
+ if (!condition) continue;
103
+
104
+ const qualifier = compiledCollection.qualifiers[condition.qualifierIndex];
105
+ if (!qualifier) continue;
106
+
107
+ // Get the qualifier value from context
108
+ const qualifierValueResult = resolver.contextQualifierProvider.get(qualifier);
109
+ const qualifierValue = qualifierValueResult.orDefault();
110
+
111
+ // Get the cached condition result from resolver (if available)
112
+ const cachedResult = resolver.conditionCache?.[conditionIndex];
113
+ const score = cachedResult?.score || 0;
114
+ const matchType = cachedResult?.matchType || 'noMatch';
115
+ const matched = matchType !== 'noMatch';
116
+
117
+ evaluations.push({
118
+ qualifierName: qualifier.name,
119
+ qualifierValue,
120
+ conditionValue: condition.value,
121
+ operator: condition.operator || 'matches',
122
+ score,
123
+ matched,
124
+ matchType,
125
+ scoreAsDefault: condition.scoreAsDefault,
126
+ conditionIndex
127
+ });
128
+ }
129
+
130
+ return evaluations;
131
+ } catch (error) {
132
+ console.warn('Error evaluating conditions for candidate:', error);
133
+ return [];
134
+ }
135
+ }
136
+
137
+ /**
138
+ * Resolve a resource and create detailed resolution result
139
+ */
140
+ export function resolveResourceDetailed(
141
+ resolver: Runtime.ResourceResolver,
142
+ resourceId: string,
143
+ processedResources: ProcessedResources,
144
+ options: ResolutionOptions = {}
145
+ ): Result<ResolutionResult> {
146
+ const enableDebug = options.enableDebugLogging === true;
147
+
148
+ debugLog(enableDebug, '=== RESOLVING RESOURCE ===');
149
+ debugLog(enableDebug, 'Resource ID:', resourceId);
150
+
151
+ const resourceResult = processedResources.system.resourceManager.getBuiltResource(resourceId);
152
+ if (resourceResult.isFailure()) {
153
+ return succeed({
154
+ success: false,
155
+ resourceId,
156
+ error: `Failed to get resource: ${resourceResult.message}`
157
+ });
158
+ }
159
+
160
+ const resource = resourceResult.value;
161
+ const compiledCollection = processedResources.compiledCollection;
162
+
163
+ // Find the compiled resource for condition analysis
164
+ const compiledResource = compiledCollection.resources.find((r) => r.id === resourceId);
165
+ if (!compiledResource) {
166
+ return succeed({
167
+ success: false,
168
+ resourceId,
169
+ error: 'Failed to find compiled resource'
170
+ });
171
+ }
172
+
173
+ // Resolve best candidate
174
+ const bestResult = resolver.resolveResource(resource);
175
+
176
+ // Resolve all candidates
177
+ const allResult = resolver.resolveAllResourceCandidates(resource);
178
+
179
+ // Resolve composed value
180
+ const composedResult = resolver.resolveComposedResourceValue(resource);
181
+
182
+ // Get decision resolution result
183
+ const decisionResult = resolver.resolveDecision(resource.decision.baseDecision);
184
+ if (decisionResult.isFailure()) {
185
+ return succeed({
186
+ success: false,
187
+ resourceId,
188
+ error: `Failed to resolve decision: ${decisionResult.message}`
189
+ });
190
+ }
191
+
192
+ const decision = decisionResult.value;
193
+
194
+ // Build detailed candidate information
195
+ const candidateDetails: CandidateInfo[] = [];
196
+ const matchedCandidates = allResult.isSuccess() ? allResult.value : [];
197
+
198
+ // Create lookup sets for regular and default matches
199
+ const regularMatchIndices = new Set(decision?.success ? decision.instanceIndices : []);
200
+ const defaultMatchIndices = new Set(decision?.success ? decision.defaultInstanceIndices : []);
201
+
202
+ // Add matched candidates first
203
+ matchedCandidates.forEach((matchedCandidate) => {
204
+ const index = resource.candidates.findIndex((candidate: any) => candidate === matchedCandidate);
205
+ if (index !== -1) {
206
+ const conditionSetKey = `cs-${index}`;
207
+ const conditionEvaluations = evaluateConditionsForCandidate(
208
+ resolver,
209
+ index,
210
+ compiledResource,
211
+ compiledCollection
212
+ );
213
+
214
+ const isDefaultMatch = defaultMatchIndices.has(index);
215
+ const isRegularMatch = regularMatchIndices.has(index);
216
+
217
+ const candidateMatchType = isRegularMatch ? 'match' : isDefaultMatch ? 'matchAsDefault' : 'noMatch';
218
+
219
+ candidateDetails.push({
220
+ candidate: resource.candidates[index],
221
+ conditionSetKey,
222
+ candidateIndex: index,
223
+ matched: true,
224
+ matchType: candidateMatchType,
225
+ isDefaultMatch,
226
+ conditionEvaluations
227
+ });
228
+ }
229
+ });
230
+
231
+ // Add non-matching candidates
232
+ resource.candidates.forEach((candidate: any, index: number) => {
233
+ const isMatched = matchedCandidates.some((mc) => mc === candidate);
234
+ if (!isMatched) {
235
+ // Handle different candidate formats - IResourceCandidate doesn't have conditions
236
+ const conditionSetKey = candidate.conditions?.toHash ? candidate.conditions.toHash() : `cs-${index}`;
237
+ const conditionEvaluations = evaluateConditionsForCandidate(
238
+ resolver,
239
+ index,
240
+ compiledResource,
241
+ compiledCollection
242
+ );
243
+
244
+ candidateDetails.push({
245
+ candidate,
246
+ conditionSetKey,
247
+ candidateIndex: index,
248
+ matched: false,
249
+ matchType: 'noMatch',
250
+ isDefaultMatch: false,
251
+ conditionEvaluations
252
+ });
253
+ }
254
+ });
255
+
256
+ const result: ResolutionResult = {
257
+ success: true,
258
+ resourceId,
259
+ resource,
260
+ bestCandidate: bestResult.isSuccess() ? bestResult.value : undefined,
261
+ allCandidates: allResult.isSuccess() ? allResult.value : undefined,
262
+ candidateDetails,
263
+ composedValue: composedResult.isSuccess() ? composedResult.value : undefined,
264
+ error: bestResult.isFailure() ? bestResult.message : undefined
265
+ };
266
+
267
+ debugLog(enableDebug, 'Resolution completed successfully');
268
+ return succeed(result);
269
+ }
270
+
271
+ /**
272
+ * Get available qualifiers from processed resources
273
+ */
274
+ export function getAvailableQualifiers(processedResources: ProcessedResources): string[] {
275
+ if (processedResources.compiledCollection.qualifiers) {
276
+ return processedResources.compiledCollection.qualifiers.map((q) => q.name);
277
+ }
278
+ return [];
279
+ }
280
+
281
+ /**
282
+ * Check if context has any pending changes
283
+ */
284
+ export function hasPendingContextChanges(
285
+ contextValues: Record<string, string | undefined>,
286
+ pendingContextValues: Record<string, string | undefined>
287
+ ): boolean {
288
+ return JSON.stringify(contextValues) !== JSON.stringify(pendingContextValues);
289
+ }