@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,467 @@
1
+ import { useState, useCallback } from 'react';
2
+ import { Result, succeed, fail } from '@fgv/ts-utils';
3
+ import {
4
+ ResourceManagerState,
5
+ ProcessedResources,
6
+ ImportedDirectory,
7
+ ImportedFile,
8
+ JsonValue
9
+ } from '../types';
10
+ import {
11
+ Config,
12
+ Bundle,
13
+ Runtime,
14
+ Resources,
15
+ Import,
16
+ QualifierTypes,
17
+ Qualifiers,
18
+ ResourceTypes
19
+ } from '@fgv/ts-res';
20
+ import {
21
+ processImportedFiles,
22
+ processImportedDirectory,
23
+ createSimpleContext,
24
+ createTsResSystemFromConfig
25
+ } from '../utils/tsResIntegration';
26
+
27
+ export interface UseResourceDataReturn {
28
+ state: ResourceManagerState;
29
+ actions: {
30
+ processDirectory: (directory: ImportedDirectory) => Promise<void>;
31
+ processDirectoryWithConfig: (
32
+ directory: ImportedDirectory,
33
+ config: Config.Model.ISystemConfiguration
34
+ ) => Promise<void>;
35
+ processFiles: (files: ImportedFile[]) => Promise<void>;
36
+ processBundleFile: (bundle: Bundle.IBundle) => Promise<void>;
37
+ clearError: () => void;
38
+ reset: () => void;
39
+ resolveResource: (resourceId: string, context?: Record<string, string>) => Promise<Result<JsonValue>>;
40
+ applyConfiguration: (config: Config.Model.ISystemConfiguration) => void;
41
+ updateProcessedResources: (processedResources: ProcessedResources) => void;
42
+ };
43
+ }
44
+
45
+ const initialState: ResourceManagerState = {
46
+ isProcessing: false,
47
+ processedResources: null,
48
+ error: null,
49
+ hasProcessedData: false,
50
+ activeConfiguration: null,
51
+ isLoadedFromBundle: false,
52
+ bundleMetadata: null
53
+ };
54
+
55
+ export function useResourceData(): UseResourceDataReturn {
56
+ const [state, setState] = useState<ResourceManagerState>(initialState);
57
+
58
+ const processDirectory = useCallback(
59
+ async (directory: ImportedDirectory) => {
60
+ setState((prev) => ({ ...prev, isProcessing: true, error: null }));
61
+
62
+ try {
63
+ const result = processImportedDirectory(directory, state.activeConfiguration || undefined);
64
+
65
+ if (result.isSuccess()) {
66
+ setState((prev) => ({
67
+ ...prev,
68
+ isProcessing: false,
69
+ processedResources: result.value,
70
+ hasProcessedData: true,
71
+ isLoadedFromBundle: false,
72
+ bundleMetadata: null
73
+ }));
74
+ } else {
75
+ throw new Error(result.message);
76
+ }
77
+ } catch (error) {
78
+ setState((prev) => ({
79
+ ...prev,
80
+ isProcessing: false,
81
+ error: error instanceof Error ? error.message : String(error)
82
+ }));
83
+ }
84
+ },
85
+ [state.activeConfiguration]
86
+ );
87
+
88
+ const processDirectoryWithConfig = useCallback(
89
+ async (directory: ImportedDirectory, config: Config.Model.ISystemConfiguration) => {
90
+ setState((prev) => ({ ...prev, isProcessing: true, error: null, activeConfiguration: config }));
91
+
92
+ try {
93
+ const result = processImportedDirectory(directory, config);
94
+
95
+ if (result.isSuccess()) {
96
+ setState((prev) => ({
97
+ ...prev,
98
+ isProcessing: false,
99
+ processedResources: result.value,
100
+ hasProcessedData: true,
101
+ isLoadedFromBundle: false,
102
+ bundleMetadata: null,
103
+ activeConfiguration: config
104
+ }));
105
+ } else {
106
+ throw new Error(result.message);
107
+ }
108
+ } catch (error) {
109
+ setState((prev) => ({
110
+ ...prev,
111
+ isProcessing: false,
112
+ error: error instanceof Error ? error.message : String(error)
113
+ }));
114
+ }
115
+ },
116
+ []
117
+ );
118
+
119
+ const processFiles = useCallback(
120
+ async (files: ImportedFile[]) => {
121
+ setState((prev) => ({ ...prev, isProcessing: true, error: null }));
122
+
123
+ try {
124
+ const result = processImportedFiles(files, state.activeConfiguration || undefined);
125
+
126
+ if (result.isSuccess()) {
127
+ setState((prev) => ({
128
+ ...prev,
129
+ isProcessing: false,
130
+ processedResources: result.value,
131
+ hasProcessedData: true,
132
+ isLoadedFromBundle: false,
133
+ bundleMetadata: null
134
+ }));
135
+ } else {
136
+ throw new Error(result.message);
137
+ }
138
+ } catch (error) {
139
+ setState((prev) => ({
140
+ ...prev,
141
+ isProcessing: false,
142
+ error: error instanceof Error ? error.message : String(error)
143
+ }));
144
+ }
145
+ },
146
+ [state.activeConfiguration]
147
+ );
148
+
149
+ const processBundleFile = useCallback(async (bundle: Bundle.IBundle) => {
150
+ console.log('[Bundle Processing] Starting bundle processing...', bundle);
151
+ setState((prev) => ({ ...prev, isProcessing: true, error: null }));
152
+
153
+ try {
154
+ console.log('[Bundle Processing] Attempting to extract bundle components...');
155
+
156
+ // Extract bundle components (configuration and compiled collection)
157
+ const componentsResult = Bundle.BundleUtils.extractBundleComponents(bundle);
158
+ console.log(
159
+ '[Bundle Processing] Component extraction result:',
160
+ componentsResult.isSuccess() ? 'SUCCESS' : `FAILED: ${componentsResult.message}`
161
+ );
162
+
163
+ if (componentsResult.isFailure()) {
164
+ throw new Error(`Failed to extract bundle components: ${componentsResult.message}`);
165
+ }
166
+
167
+ const { systemConfiguration, compiledCollection, metadata } = componentsResult.value;
168
+ console.log('[Bundle Processing] Extracted components:', {
169
+ hasSystemConfiguration: !!systemConfiguration,
170
+ hasCompiledCollection: !!compiledCollection,
171
+ hasMetadata: !!metadata,
172
+ systemConfiguration: systemConfiguration
173
+ });
174
+
175
+ // Use BundleLoader to create a fully functional resource manager from the bundle
176
+ console.log('[Bundle Processing] Using BundleLoader to create resource manager from bundle');
177
+
178
+ const bundleManagerResult = Bundle.BundleLoader.createManagerFromBundle({
179
+ bundle: bundle,
180
+ skipChecksumVerification: true // Skip for now since we're in a browser environment
181
+ });
182
+
183
+ if (bundleManagerResult.isFailure()) {
184
+ throw new Error(`Failed to create resource manager from bundle: ${bundleManagerResult.message}`);
185
+ }
186
+
187
+ // The bundle's IResourceManager contains all the resources and candidates
188
+ // We'll use it directly for both UI and resolution
189
+ const bundleResourceManager = bundleManagerResult.value;
190
+
191
+ // Debug: Check what resources are in the original bundle manager
192
+ console.log('[Bundle Processing] Original bundle manager resources:', {
193
+ numResources: bundleResourceManager.numResources,
194
+ numCandidates: bundleResourceManager.numCandidates,
195
+ resourceIds: Array.from(bundleResourceManager.builtResources.keys())
196
+ });
197
+
198
+ // Convert the compiled collection to an editable ResourceManagerBuilder
199
+ // using createFromCompiledResourceCollection for exact reconstruction
200
+ const reconstructedBuilderResult =
201
+ Resources.ResourceManagerBuilder.createFromCompiledResourceCollection(
202
+ compiledCollection,
203
+ systemConfiguration
204
+ );
205
+ if (reconstructedBuilderResult.isFailure()) {
206
+ throw new Error(
207
+ `Failed to reconstruct builder from compiled collection: ${reconstructedBuilderResult.message}`
208
+ );
209
+ }
210
+
211
+ const editableResourceManager = reconstructedBuilderResult.value;
212
+ console.log('[Bundle Processing] Normalized builder resources:', {
213
+ numResources: editableResourceManager.resources.size,
214
+ numCandidates: Array.from(editableResourceManager.getAllCandidates()).length,
215
+ resourceIds: Array.from(editableResourceManager.resources.keys())
216
+ });
217
+
218
+ // Create the system using the normalized, editable resource manager
219
+ const system = {
220
+ qualifierTypes: systemConfiguration.qualifierTypes,
221
+ qualifiers: systemConfiguration.qualifiers,
222
+ resourceTypes: systemConfiguration.resourceTypes,
223
+ resourceManager: editableResourceManager, // Now editable ResourceManagerBuilder
224
+ importManager: Import.ImportManager.create({
225
+ resources: Resources.ResourceManagerBuilder.create({
226
+ qualifiers: systemConfiguration.qualifiers,
227
+ resourceTypes: systemConfiguration.resourceTypes
228
+ }).orThrow()
229
+ }).orThrow(),
230
+ contextQualifierProvider: Runtime.Context.ValidatingSimpleContextQualifierProvider.create({
231
+ qualifiers: systemConfiguration.qualifiers
232
+ }).orThrow()
233
+ };
234
+
235
+ // Extract configuration for UI display using the collector API
236
+ // Note: The collectors contain instantiated objects, not raw config
237
+ const configForStorage: Config.Model.ISystemConfiguration = {
238
+ name: 'Bundle Configuration',
239
+ description: metadata?.description || 'Configuration extracted from bundle',
240
+ qualifierTypes: Array.from(system.qualifierTypes.values()).map((qt) => {
241
+ console.log('[Bundle Processing] Extracting qualifier type:', qt);
242
+ // Determine the system type based on the class name
243
+ let systemType: 'literal' | 'language' | 'territory' = 'literal';
244
+ if (qt.constructor?.name === 'LanguageQualifierType') {
245
+ systemType = 'language';
246
+ } else if (qt.constructor?.name === 'TerritoryQualifierType') {
247
+ systemType = 'territory';
248
+ } else if (qt.constructor?.name === 'LiteralQualifierType') {
249
+ systemType = 'literal';
250
+ }
251
+
252
+ // Extract configuration properties based on type
253
+ const configuration: Record<string, unknown> = {};
254
+
255
+ // Common properties
256
+ if (qt.allowContextList !== undefined) {
257
+ configuration.allowContextList = qt.allowContextList;
258
+ }
259
+
260
+ // LiteralQualifierType specific
261
+ if (systemType === 'literal') {
262
+ const qtAny = qt as unknown as Record<string, unknown>;
263
+ if (qtAny.caseSensitive !== undefined) {
264
+ configuration.caseSensitive = qtAny.caseSensitive;
265
+ }
266
+ if (qtAny.enumeratedValues) {
267
+ configuration.enumeratedValues = qtAny.enumeratedValues;
268
+ }
269
+ if (qtAny.hierarchy) {
270
+ configuration.hierarchy = qtAny.hierarchy;
271
+ }
272
+ }
273
+
274
+ // TerritoryQualifierType specific
275
+ if (systemType === 'territory') {
276
+ const qtAny = qt as unknown as Record<string, unknown>;
277
+ if (qtAny.acceptLowercase !== undefined) {
278
+ configuration.acceptLowercase = qtAny.acceptLowercase;
279
+ }
280
+ if (qtAny.allowedTerritories) {
281
+ configuration.allowedTerritories = qtAny.allowedTerritories;
282
+ }
283
+ }
284
+
285
+ return {
286
+ name: qt.name,
287
+ systemType: systemType,
288
+ configuration: configuration
289
+ };
290
+ }),
291
+ qualifiers: Array.from(system.qualifiers.values()).map((q) => {
292
+ console.log('[Bundle Processing] Extracting qualifier:', q);
293
+ // Instantiated Qualifier objects have .type property which is a QualifierType object
294
+ const qAny = q as unknown as Record<string, unknown>;
295
+ const typeName = (q.type as QualifierTypes.QualifierType)?.name || qAny.typeName;
296
+ if (!typeName) {
297
+ console.error('[Bundle Processing] Missing typeName for qualifier:', q);
298
+ }
299
+ return {
300
+ name: q.name,
301
+ typeName: (typeName || 'unknown') as string,
302
+ token: q.token,
303
+ defaultPriority: q.defaultPriority || 500,
304
+ defaultValue: q.defaultValue,
305
+ tokenIsOptional: q.tokenIsOptional || false
306
+ } as Qualifiers.IQualifierDecl;
307
+ }),
308
+ resourceTypes: Array.from(system.resourceTypes.values()).map((rt, index: number) => {
309
+ console.log('[Bundle Processing] Extracting resource type:', rt);
310
+ // ResourceTypes in bundles might not have a name property
311
+ // Default to 'json' for JsonResourceType
312
+ const rtAny = rt as unknown as Record<string, unknown>;
313
+ const typeName = rt.constructor?.name === 'JsonResourceType' ? 'json' : rtAny.typeName || 'json';
314
+ return {
315
+ name: (rtAny.name || `resourceType${index}`) as string, // Provide a default name if missing
316
+ typeName: typeName as string
317
+ } as ResourceTypes.Config.IResourceTypeConfig;
318
+ })
319
+ };
320
+
321
+ console.log('[Bundle Processing] Extracted configuration for UI:', configForStorage);
322
+
323
+ // Extract resource IDs from the loaded resource manager
324
+ const resourceIds: string[] = [];
325
+ let resourceCount = 0;
326
+
327
+ // The resource manager is now fully loaded with all bundle resources
328
+ // Extract resource IDs from the compiled collection for tracking
329
+ if (compiledCollection.resources) {
330
+ for (const resource of compiledCollection.resources) {
331
+ const resourceId = resource.id || `resource-${resourceCount}`;
332
+ resourceIds.push(resourceId);
333
+ resourceCount++;
334
+ }
335
+ }
336
+
337
+ console.log(`Bundle loaded with ${resourceCount} resources (with candidates):`, resourceIds);
338
+
339
+ // Create a resolver using the bundle's resource manager
340
+ const resolverResult = Runtime.ResourceResolver.create({
341
+ resourceManager: system.resourceManager,
342
+ qualifierTypes: system.qualifierTypes,
343
+ contextQualifierProvider: system.contextQualifierProvider
344
+ });
345
+
346
+ if (resolverResult.isFailure()) {
347
+ throw new Error(`Failed to create resolver: ${resolverResult.message}`);
348
+ }
349
+
350
+ // No longer create a separate CompiledResourceCollection manager
351
+ // We'll derive the compiled collection from ResourceManagerBuilder when needed
352
+
353
+ // Create the processed resources structure with bundle data
354
+ const processedResources: ProcessedResources = {
355
+ system: {
356
+ qualifierTypes: system.qualifierTypes,
357
+ qualifiers: system.qualifiers,
358
+ resourceTypes: system.resourceTypes,
359
+ resourceManager: system.resourceManager,
360
+ importManager: system.importManager,
361
+ contextQualifierProvider: system.contextQualifierProvider
362
+ },
363
+ compiledCollection,
364
+ resolver: resolverResult.value,
365
+ resourceCount,
366
+ summary: {
367
+ totalResources: resourceCount,
368
+ resourceIds,
369
+ errorCount: 0,
370
+ warnings: [`Bundle loaded with ${resourceCount} resources from compiled collection`]
371
+ }
372
+ };
373
+
374
+ console.log('[Bundle Processing] Setting final state...', {
375
+ resourceCount,
376
+ resourceIds,
377
+ configForStorage,
378
+ hasProcessedResources: !!processedResources
379
+ });
380
+
381
+ setState((prev) => ({
382
+ ...prev,
383
+ isProcessing: false,
384
+ processedResources,
385
+ hasProcessedData: true,
386
+ error: null,
387
+ activeConfiguration: configForStorage,
388
+ isLoadedFromBundle: true,
389
+ bundleMetadata: metadata
390
+ }));
391
+
392
+ console.log('[Bundle Processing] Bundle processing completed successfully!');
393
+ } catch (error) {
394
+ setState((prev) => ({
395
+ ...prev,
396
+ isProcessing: false,
397
+ error: error instanceof Error ? error.message : String(error)
398
+ }));
399
+ }
400
+ }, []);
401
+
402
+ const clearError = useCallback(() => {
403
+ setState((prev) => ({ ...prev, error: null }));
404
+ }, []);
405
+
406
+ const reset = useCallback(() => {
407
+ setState(initialState);
408
+ }, []);
409
+
410
+ const resolveResource = useCallback(
411
+ async (resourceId: string, context?: Record<string, string>): Promise<Result<JsonValue>> => {
412
+ if (!state.processedResources?.system?.resourceManager) {
413
+ return fail('No resources loaded');
414
+ }
415
+
416
+ try {
417
+ // Get the resource from the resource manager
418
+ const resourceResult = state.processedResources.system.resourceManager.getBuiltResource(resourceId);
419
+ if (resourceResult.isFailure()) {
420
+ return fail(`Resource not found: ${resourceId}`);
421
+ }
422
+
423
+ // Get the resource and convert to JSON
424
+ const resource = resourceResult.value;
425
+
426
+ // For now, return a simple representation since we don't have full resolution context
427
+ // TODO: Use proper converters from ts-json-base when implementing full resolution
428
+ const resourceJson = {
429
+ id: resource.id as string,
430
+ type: resource.resourceType as unknown,
431
+ candidateCount: resource.candidates.length
432
+ };
433
+ return succeed(resourceJson as unknown as JsonValue);
434
+ } catch (error) {
435
+ return fail(`Failed to resolve resource: ${error instanceof Error ? error.message : String(error)}`);
436
+ }
437
+ },
438
+ [state.processedResources]
439
+ );
440
+
441
+ const applyConfiguration = useCallback((config: Config.Model.ISystemConfiguration) => {
442
+ setState((prev) => ({ ...prev, activeConfiguration: config }));
443
+ }, []);
444
+
445
+ const updateProcessedResources = useCallback((processedResources: ProcessedResources) => {
446
+ setState((prev) => ({
447
+ ...prev,
448
+ processedResources,
449
+ hasProcessedData: true
450
+ }));
451
+ }, []);
452
+
453
+ return {
454
+ state,
455
+ actions: {
456
+ processDirectory,
457
+ processDirectoryWithConfig,
458
+ processFiles,
459
+ processBundleFile,
460
+ clearError,
461
+ reset,
462
+ resolveResource,
463
+ applyConfiguration,
464
+ updateProcessedResources
465
+ }
466
+ };
467
+ }
@@ -0,0 +1,44 @@
1
+ import { useState, useCallback } from 'react';
2
+ import { Message } from '../types';
3
+
4
+ export interface UseViewStateReturn {
5
+ messages: Message[];
6
+ selectedResourceId: string | null;
7
+ addMessage: (type: Message['type'], message: string) => void;
8
+ clearMessages: () => void;
9
+ selectResource: (resourceId: string | null) => void;
10
+ }
11
+
12
+ export function useViewState(): UseViewStateReturn {
13
+ const [messages, setMessages] = useState<Message[]>([]);
14
+ const [selectedResourceId, setSelectedResourceId] = useState<string | null>(null);
15
+
16
+ const addMessage = useCallback((type: Message['type'], message: string) => {
17
+ const newMessage: Message = {
18
+ id: `msg-${Date.now()}-${Math.random()}`,
19
+ type,
20
+ message,
21
+ timestamp: new Date()
22
+ };
23
+
24
+ setMessages((prev) => [...prev, newMessage]);
25
+
26
+ // No auto-clearing - let users manage messages with filters
27
+ }, []);
28
+
29
+ const clearMessages = useCallback(() => {
30
+ setMessages([]);
31
+ }, []);
32
+
33
+ const selectResource = useCallback((resourceId: string | null) => {
34
+ setSelectedResourceId(resourceId);
35
+ }, []);
36
+
37
+ return {
38
+ messages,
39
+ selectedResourceId,
40
+ addMessage,
41
+ clearMessages,
42
+ selectResource
43
+ };
44
+ }
package/src/index.ts ADDED
@@ -0,0 +1,45 @@
1
+ // Export types
2
+ export * from './types';
3
+
4
+ // Export views
5
+ export { ImportView } from './components/views/ImportView';
6
+ export { SourceView } from './components/views/SourceView';
7
+ export { FilterView } from './components/views/FilterView';
8
+ export { CompiledView } from './components/views/CompiledView';
9
+ export { ResolutionView } from './components/views/ResolutionView';
10
+ export { ZipLoaderView } from './components/views/ZipLoaderView';
11
+ export { ConfigurationView } from './components/views/ConfigurationView';
12
+
13
+ // Export orchestrator
14
+ export { ResourceOrchestrator } from './components/orchestrator/ResourceOrchestrator';
15
+
16
+ // Export forms
17
+ export { QualifierTypeEditForm } from './components/forms/QualifierTypeEditForm';
18
+ export { QualifierEditForm } from './components/forms/QualifierEditForm';
19
+ export { ResourceTypeEditForm } from './components/forms/ResourceTypeEditForm';
20
+
21
+ // Export common components
22
+ export { ResourceTreeView } from './components/common/ResourceTreeView';
23
+ export { ResourceListView } from './components/common/ResourceListView';
24
+ export { QualifierContextControl } from './components/common/QualifierContextControl';
25
+
26
+ // Export hooks
27
+ export { useResourceData } from './hooks/useResourceData';
28
+ export { useFilterState } from './hooks/useFilterState';
29
+ export { useViewState } from './hooks/useViewState';
30
+ export { useResolutionState } from './hooks/useResolutionState';
31
+ export { useConfigurationState } from './hooks/useConfigurationState';
32
+
33
+ // Export utilities
34
+ export * from './utils/tsResIntegration';
35
+ export * from './utils/fileProcessing';
36
+ export {
37
+ createFilteredResourceManagerSimple,
38
+ analyzeFilteredResources,
39
+ hasFilterValues,
40
+ getFilterSummary,
41
+ type FilterOptions
42
+ } from './utils/filterResources';
43
+ export * from './utils/resolutionUtils';
44
+ export * from './utils/zipLoader';
45
+ export * from './utils/configurationUtils';