@fgv/ts-res-ui-components 5.0.0-21 → 5.0.0-23

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 (192) hide show
  1. package/README.md +401 -155
  2. package/config/jest.setup.js +10 -0
  3. package/dist/ts-res-ui-components.d.ts +1657 -76
  4. package/lib/components/common/QualifierContextControl.js +4 -1
  5. package/lib/components/common/ResourceTreeView.js +4 -1
  6. package/lib/components/forms/GenericQualifierTypeEditForm.d.ts +26 -0
  7. package/lib/components/forms/GenericQualifierTypeEditForm.js +166 -0
  8. package/lib/components/forms/QualifierEditForm.d.ts +1 -1
  9. package/lib/components/forms/index.d.ts +2 -0
  10. package/lib/components/forms/index.js +1 -0
  11. package/lib/components/orchestrator/ResourceOrchestrator.d.ts +3 -0
  12. package/lib/components/orchestrator/ResourceOrchestrator.js +118 -51
  13. package/lib/components/pickers/ResourcePicker/ResourcePickerTree.js +32 -10
  14. package/lib/components/pickers/ResourcePicker/index.js +4 -2
  15. package/lib/components/views/CompiledView/index.js +75 -16
  16. package/lib/components/views/ConfigurationView/index.js +94 -35
  17. package/lib/components/views/FilterView/index.js +7 -4
  18. package/lib/components/views/GridView/EditableGridCell.d.ts +76 -0
  19. package/lib/components/views/GridView/EditableGridCell.js +224 -0
  20. package/lib/components/views/GridView/GridSelector.d.ts +43 -0
  21. package/lib/components/views/GridView/GridSelector.js +89 -0
  22. package/lib/components/views/GridView/MultiGridView.d.ts +85 -0
  23. package/lib/components/views/GridView/MultiGridView.js +196 -0
  24. package/lib/components/views/GridView/ResourceGrid.d.ts +38 -0
  25. package/lib/components/views/GridView/ResourceGrid.js +232 -0
  26. package/lib/components/views/GridView/SharedContextControls.d.ts +47 -0
  27. package/lib/components/views/GridView/SharedContextControls.js +95 -0
  28. package/lib/components/views/GridView/cells/BooleanCell.d.ts +44 -0
  29. package/lib/components/views/GridView/cells/BooleanCell.js +49 -0
  30. package/lib/components/views/GridView/cells/DropdownCell.d.ts +58 -0
  31. package/lib/components/views/GridView/cells/DropdownCell.js +182 -0
  32. package/lib/components/views/GridView/cells/StringCell.d.ts +57 -0
  33. package/lib/components/views/GridView/cells/StringCell.js +106 -0
  34. package/lib/components/views/GridView/cells/TriStateCell.d.ts +54 -0
  35. package/lib/components/views/GridView/cells/TriStateCell.js +112 -0
  36. package/lib/components/views/GridView/cells/index.d.ts +15 -0
  37. package/lib/components/views/GridView/cells/index.js +11 -0
  38. package/lib/components/views/GridView/index.d.ts +53 -0
  39. package/lib/components/views/GridView/index.js +212 -0
  40. package/lib/components/views/ImportView/index.js +22 -19
  41. package/lib/components/views/MessagesWindow/index.js +4 -1
  42. package/lib/components/views/ResolutionView/index.js +8 -5
  43. package/lib/contexts/ObservabilityContext.d.ts +85 -0
  44. package/lib/contexts/ObservabilityContext.js +98 -0
  45. package/lib/contexts/index.d.ts +2 -0
  46. package/lib/contexts/index.js +24 -0
  47. package/lib/hooks/useConfigurationState.d.ts +3 -3
  48. package/lib/hooks/useResolutionState.js +850 -246
  49. package/lib/hooks/useResourceData.d.ts +7 -4
  50. package/lib/hooks/useResourceData.js +185 -184
  51. package/lib/index.d.ts +5 -1
  52. package/lib/index.js +8 -1
  53. package/lib/namespaces/GridTools.d.ts +136 -0
  54. package/lib/namespaces/GridTools.js +138 -0
  55. package/lib/namespaces/ObservabilityTools.d.ts +3 -0
  56. package/lib/namespaces/ObservabilityTools.js +23 -0
  57. package/lib/namespaces/ResolutionTools.d.ts +2 -1
  58. package/lib/namespaces/ResolutionTools.js +2 -0
  59. package/lib/namespaces/index.d.ts +2 -0
  60. package/lib/namespaces/index.js +2 -0
  61. package/lib/test/integration/observability.integration.test.d.ts +2 -0
  62. package/lib/test/unit/hooks/useResourceData.test.d.ts +2 -0
  63. package/lib/test/unit/utils/downloadHelper.test.d.ts +2 -0
  64. package/lib/test/unit/workflows/resolutionWorkflows.test.d.ts +2 -0
  65. package/lib/test/unit/workflows/resourceCreation.test.d.ts +2 -0
  66. package/lib/test/unit/workflows/resultPatternExtensions.test.d.ts +2 -0
  67. package/lib/test/unit/workflows/validation.test.d.ts +2 -0
  68. package/lib/types/index.d.ts +387 -20
  69. package/lib/types/index.js +2 -1
  70. package/lib/utils/cellValidation.d.ts +113 -0
  71. package/lib/utils/cellValidation.js +248 -0
  72. package/lib/utils/downloadHelper.d.ts +66 -0
  73. package/lib/utils/downloadHelper.js +195 -0
  74. package/lib/utils/observability/factories.d.ts +29 -0
  75. package/lib/utils/observability/factories.js +58 -0
  76. package/lib/utils/observability/implementations.d.ts +61 -0
  77. package/lib/utils/observability/implementations.js +103 -0
  78. package/lib/utils/observability/index.d.ts +4 -0
  79. package/lib/utils/observability/index.js +26 -0
  80. package/lib/utils/observability/interfaces.d.ts +30 -0
  81. package/lib/utils/observability/interfaces.js +23 -0
  82. package/lib/utils/resolutionEditing.js +2 -1
  83. package/lib/utils/resourceSelector.d.ts +97 -0
  84. package/lib/utils/resourceSelector.js +195 -0
  85. package/lib/utils/resourceSelectors.d.ts +146 -0
  86. package/lib/utils/resourceSelectors.js +233 -0
  87. package/lib/utils/tsResIntegration.d.ts +6 -41
  88. package/lib/utils/tsResIntegration.js +20 -16
  89. package/lib/utils/zipLoader/zipProcessingHelpers.d.ts +3 -2
  90. package/lib/utils/zipLoader/zipProcessingHelpers.js +6 -5
  91. package/lib-commonjs/components/common/QualifierContextControl.js +4 -1
  92. package/lib-commonjs/components/common/ResourceTreeView.js +4 -1
  93. package/lib-commonjs/components/forms/GenericQualifierTypeEditForm.js +171 -0
  94. package/lib-commonjs/components/forms/index.js +3 -1
  95. package/lib-commonjs/components/orchestrator/ResourceOrchestrator.js +118 -51
  96. package/lib-commonjs/components/pickers/ResourcePicker/ResourcePickerTree.js +32 -10
  97. package/lib-commonjs/components/pickers/ResourcePicker/index.js +4 -2
  98. package/lib-commonjs/components/views/CompiledView/index.js +75 -16
  99. package/lib-commonjs/components/views/ConfigurationView/index.js +93 -34
  100. package/lib-commonjs/components/views/FilterView/index.js +7 -4
  101. package/lib-commonjs/components/views/GridView/EditableGridCell.js +232 -0
  102. package/lib-commonjs/components/views/GridView/GridSelector.js +94 -0
  103. package/lib-commonjs/components/views/GridView/MultiGridView.js +201 -0
  104. package/lib-commonjs/components/views/GridView/ResourceGrid.js +237 -0
  105. package/lib-commonjs/components/views/GridView/SharedContextControls.js +100 -0
  106. package/lib-commonjs/components/views/GridView/cells/BooleanCell.js +54 -0
  107. package/lib-commonjs/components/views/GridView/cells/DropdownCell.js +187 -0
  108. package/lib-commonjs/components/views/GridView/cells/StringCell.js +111 -0
  109. package/lib-commonjs/components/views/GridView/cells/TriStateCell.js +117 -0
  110. package/lib-commonjs/components/views/GridView/cells/index.js +18 -0
  111. package/lib-commonjs/components/views/GridView/index.js +217 -0
  112. package/lib-commonjs/components/views/ImportView/index.js +22 -19
  113. package/lib-commonjs/components/views/MessagesWindow/index.js +4 -1
  114. package/lib-commonjs/components/views/ResolutionView/index.js +8 -5
  115. package/lib-commonjs/contexts/ObservabilityContext.js +104 -0
  116. package/lib-commonjs/contexts/index.js +30 -0
  117. package/lib-commonjs/hooks/useResolutionState.js +849 -245
  118. package/lib-commonjs/hooks/useResourceData.js +184 -215
  119. package/lib-commonjs/index.js +15 -1
  120. package/lib-commonjs/namespaces/GridTools.js +161 -0
  121. package/lib-commonjs/namespaces/ObservabilityTools.js +33 -0
  122. package/lib-commonjs/namespaces/ResolutionTools.js +10 -1
  123. package/lib-commonjs/namespaces/index.js +3 -1
  124. package/lib-commonjs/types/index.js +10 -0
  125. package/lib-commonjs/utils/cellValidation.js +253 -0
  126. package/lib-commonjs/utils/downloadHelper.js +198 -0
  127. package/lib-commonjs/utils/observability/factories.js +63 -0
  128. package/lib-commonjs/utils/observability/implementations.js +109 -0
  129. package/lib-commonjs/utils/observability/index.js +36 -0
  130. package/lib-commonjs/utils/observability/interfaces.js +24 -0
  131. package/lib-commonjs/utils/resolutionEditing.js +2 -1
  132. package/lib-commonjs/utils/resourceSelector.js +200 -0
  133. package/lib-commonjs/utils/resourceSelectors.js +242 -0
  134. package/lib-commonjs/utils/tsResIntegration.js +21 -16
  135. package/lib-commonjs/utils/zipLoader/zipProcessingHelpers.js +7 -5
  136. package/package.json +7 -7
  137. package/src/components/common/QualifierContextControl.tsx +0 -338
  138. package/src/components/common/ResolutionContextOptionsControl.tsx +0 -450
  139. package/src/components/common/ResolutionResults/index.tsx +0 -481
  140. package/src/components/common/ResourceListView.tsx +0 -167
  141. package/src/components/common/ResourcePickerOptionsControl.tsx +0 -351
  142. package/src/components/common/ResourceTreeView.tsx +0 -417
  143. package/src/components/common/SourceResourceDetail/index.tsx +0 -493
  144. package/src/components/forms/HierarchyEditor.tsx +0 -285
  145. package/src/components/forms/QualifierEditForm.tsx +0 -487
  146. package/src/components/forms/QualifierTypeEditForm.tsx +0 -458
  147. package/src/components/forms/ResourceTypeEditForm.tsx +0 -437
  148. package/src/components/forms/index.ts +0 -11
  149. package/src/components/orchestrator/ResourceOrchestrator.tsx +0 -444
  150. package/src/components/pickers/ResourcePicker/README.md +0 -570
  151. package/src/components/pickers/ResourcePicker/ResourceItem.tsx +0 -127
  152. package/src/components/pickers/ResourcePicker/ResourcePickerList.tsx +0 -114
  153. package/src/components/pickers/ResourcePicker/ResourcePickerTree.tsx +0 -461
  154. package/src/components/pickers/ResourcePicker/index.tsx +0 -234
  155. package/src/components/pickers/ResourcePicker/types.ts +0 -301
  156. package/src/components/pickers/ResourcePicker/utils/treeNavigation.ts +0 -210
  157. package/src/components/views/CompiledView/index.tsx +0 -1342
  158. package/src/components/views/ConfigurationView/index.tsx +0 -848
  159. package/src/components/views/FilterView/index.tsx +0 -681
  160. package/src/components/views/ImportView/index.tsx +0 -789
  161. package/src/components/views/MessagesWindow/index.tsx +0 -325
  162. package/src/components/views/ResolutionView/EditableJsonView.tsx +0 -386
  163. package/src/components/views/ResolutionView/NewResourceModal.tsx +0 -158
  164. package/src/components/views/ResolutionView/UnifiedChangeControls.tsx +0 -163
  165. package/src/components/views/ResolutionView/index.tsx +0 -751
  166. package/src/components/views/SourceView/index.tsx +0 -291
  167. package/src/hooks/useConfigurationState.ts +0 -436
  168. package/src/hooks/useFilterState.ts +0 -150
  169. package/src/hooks/useResolutionState.ts +0 -893
  170. package/src/hooks/useResourceData.ts +0 -596
  171. package/src/hooks/useViewState.ts +0 -97
  172. package/src/index.ts +0 -68
  173. package/src/namespaces/ConfigurationTools.ts +0 -59
  174. package/src/namespaces/FilterTools.ts +0 -47
  175. package/src/namespaces/ImportTools.ts +0 -42
  176. package/src/namespaces/PickerTools.ts +0 -104
  177. package/src/namespaces/ResolutionTools.ts +0 -68
  178. package/src/namespaces/ResourceTools.ts +0 -106
  179. package/src/namespaces/TsResTools.ts +0 -49
  180. package/src/namespaces/ViewStateTools.ts +0 -91
  181. package/src/namespaces/ZipTools.ts +0 -49
  182. package/src/namespaces/index.ts +0 -49
  183. package/src/types/index.ts +0 -1273
  184. package/src/utils/configurationUtils.ts +0 -339
  185. package/src/utils/fileProcessing.ts +0 -164
  186. package/src/utils/filterResources.ts +0 -356
  187. package/src/utils/resolutionEditing.ts +0 -346
  188. package/src/utils/resolutionUtils.ts +0 -740
  189. package/src/utils/tsResIntegration.ts +0 -475
  190. package/src/utils/zipLoader/index.ts +0 -5
  191. package/src/utils/zipLoader/zipProcessingHelpers.ts +0 -46
  192. package/src/utils/zipLoader/zipUtils.ts +0 -7
@@ -0,0 +1,212 @@
1
+ import React, { useMemo, useCallback, useEffect } from 'react';
2
+ import { TableCellsIcon } from '@heroicons/react/24/outline';
3
+ import { selectResources } from '../../../utils/resourceSelector';
4
+ import { QualifierContextControl } from '../../common/QualifierContextControl';
5
+ import { UnifiedChangeControls } from '../ResolutionView/UnifiedChangeControls';
6
+ import { ResourceGrid } from './ResourceGrid';
7
+ /**
8
+ * GridView component for displaying multiple resources in a tabular format.
9
+ *
10
+ * Provides a grid-based interface for viewing and editing multiple resources
11
+ * simultaneously, with configurable column mappings and shared context management.
12
+ * Leverages the same state management and batch processing as ResolutionView.
13
+ *
14
+ * **Key Features:**
15
+ * - **Multi-resource display**: View multiple resources in rows with configurable columns
16
+ * - **Column mapping**: Host-defined extraction of properties from resolved resources
17
+ * - **Batch editing**: Edit multiple resource values with unified batch application
18
+ * - **Context integration**: Same context management as ResolutionView
19
+ * - **Resource filtering**: Flexible resource selection via built-in and custom selectors
20
+ * - **Change management**: Leverages existing UnifiedChangeControls for batch operations
21
+ *
22
+ * @example
23
+ * ```tsx
24
+ * import { GridView } from '@fgv/ts-res-ui-components';
25
+ *
26
+ * // Define grid configuration
27
+ * const gridConfig = {
28
+ * id: 'user-messages',
29
+ * title: 'User Messages',
30
+ * resourceSelection: { type: 'prefix', prefix: 'user.' },
31
+ * columnMapping: [{
32
+ * resourceType: 'text-resource',
33
+ * columns: [
34
+ * { id: 'text', title: 'Message Text', dataPath: 'text', editable: true },
35
+ * { id: 'locale', title: 'Locale', dataPath: 'locale' }
36
+ * ]
37
+ * }]
38
+ * };
39
+ *
40
+ * function MyGridApp() {
41
+ * return (
42
+ * <GridView
43
+ * gridConfig={gridConfig}
44
+ * resources={processedResources}
45
+ * resolutionState={resolutionState}
46
+ * resolutionActions={resolutionActions}
47
+ * availableQualifiers={['language', 'territory', 'platform']}
48
+ * />
49
+ * );
50
+ * }
51
+ * ```
52
+ *
53
+ * @public
54
+ */
55
+ export const GridView = ({ gridConfig, resources, resolutionState, resolutionActions, availableQualifiers = [], contextOptions, filterState, filterResult, showContextControls = true, showChangeControls = true, onMessage, className = '' }) => {
56
+ // Use filtered resources when filtering is active and successful
57
+ const isFilteringActive = filterState?.enabled && filterResult?.success === true;
58
+ const baseProcessedResources = isFilteringActive ? filterResult?.processedResources : resources;
59
+ // Select resources for this grid based on the configuration
60
+ const selectedResourceIds = useMemo(() => {
61
+ if (!baseProcessedResources || !gridConfig.resourceSelection) {
62
+ return [];
63
+ }
64
+ const selectionResult = selectResources(gridConfig.resourceSelection, baseProcessedResources);
65
+ if (selectionResult.isFailure()) {
66
+ onMessage?.('error', `Resource selection failed: ${selectionResult.message}`);
67
+ return [];
68
+ }
69
+ return selectionResult.value;
70
+ }, [baseProcessedResources, gridConfig.resourceSelection, onMessage]);
71
+ // Resolve all selected resources with current context
72
+ const resourceResolutions = useMemo(() => {
73
+ if (!resolutionState?.currentResolver || !selectedResourceIds.length) {
74
+ return new Map();
75
+ }
76
+ const resolutions = new Map();
77
+ const context = resolutionState.contextValues;
78
+ selectedResourceIds.forEach((resourceId) => {
79
+ try {
80
+ const resolver = resolutionState.currentResolver;
81
+ const resourceResult = resolver.resourceManager.getBuiltResource(resourceId);
82
+ if (resourceResult.isSuccess()) {
83
+ const resource = resourceResult.value;
84
+ // Resolve the resource with current context
85
+ const resolveResult = resolver.resolveComposedResourceValue(resourceId);
86
+ if (resolveResult.isSuccess()) {
87
+ resolutions.set(resourceId, {
88
+ success: true,
89
+ resourceId,
90
+ resource,
91
+ composedValue: resolveResult.value
92
+ // Note: For grid view, we mainly need the composed value
93
+ // Full candidate analysis is available but not needed for basic grid display
94
+ });
95
+ }
96
+ else {
97
+ resolutions.set(resourceId, {
98
+ success: false,
99
+ resourceId,
100
+ error: resolveResult.message
101
+ });
102
+ }
103
+ }
104
+ }
105
+ catch (error) {
106
+ resolutions.set(resourceId, {
107
+ success: false,
108
+ resourceId,
109
+ error: error instanceof Error ? error.message : 'Unknown resolution error'
110
+ });
111
+ }
112
+ });
113
+ return resolutions;
114
+ }, [selectedResourceIds, resolutionState?.currentResolver, resolutionState?.contextValues]);
115
+ // Handle context value changes using the shared pattern from ResolutionView
116
+ const handleQualifierChange = useCallback((qualifierName, value) => {
117
+ // Don't update context if this qualifier is host-managed
118
+ const qualifierOptions = contextOptions?.qualifierOptions?.[qualifierName];
119
+ const isHostManaged = qualifierOptions?.hostValue !== undefined;
120
+ if (!isHostManaged) {
121
+ resolutionActions?.updateContextValue(qualifierName, value);
122
+ }
123
+ }, [resolutionActions, contextOptions?.qualifierOptions]);
124
+ // Apply host-managed values when they change (same pattern as ResolutionView)
125
+ useEffect(() => {
126
+ if (!contextOptions?.hostManagedValues || !resolutionActions?.applyContext)
127
+ return;
128
+ resolutionActions.applyContext(contextOptions.hostManagedValues);
129
+ }, [contextOptions?.hostManagedValues, resolutionActions]);
130
+ // Determine which qualifiers to show
131
+ const visibleQualifiers = useMemo(() => {
132
+ if (!contextOptions?.qualifierOptions) {
133
+ return availableQualifiers;
134
+ }
135
+ return availableQualifiers.filter((qualifierName) => {
136
+ const options = contextOptions.qualifierOptions[qualifierName];
137
+ return options?.visible !== false;
138
+ });
139
+ }, [availableQualifiers, contextOptions?.qualifierOptions]);
140
+ // Get effective context values
141
+ const effectiveContextValues = useMemo(() => {
142
+ return resolutionState?.contextValues || {};
143
+ }, [resolutionState?.contextValues]);
144
+ if (!resources) {
145
+ return (React.createElement("div", { className: `p-6 ${className}` },
146
+ React.createElement("div", { className: "flex items-center space-x-3 mb-6" },
147
+ React.createElement(TableCellsIcon, { className: "h-8 w-8 text-blue-600" }),
148
+ React.createElement("h2", { className: "text-2xl font-bold text-gray-900" }, gridConfig.title || 'Resource Grid')),
149
+ React.createElement("div", { className: "bg-white rounded-lg shadow-sm border border-gray-200 p-8 text-center" },
150
+ React.createElement("div", { className: "max-w-2xl mx-auto" },
151
+ React.createElement("h3", { className: "text-xl font-semibold text-gray-900 mb-4" }, "No Resources Loaded"),
152
+ React.createElement("p", { className: "text-gray-600 mb-6" }, "Import resources first to view them in a grid format with customizable columns."),
153
+ React.createElement("div", { className: "bg-blue-50 rounded-lg p-4" },
154
+ React.createElement("p", { className: "text-sm text-blue-800" },
155
+ React.createElement("strong", null, "Grid View:"),
156
+ " Display multiple resources in a table format. Configure columns to extract and edit specific properties from resolved resources."))))));
157
+ }
158
+ return (React.createElement("div", { className: `p-6 ${className}` },
159
+ React.createElement("div", { className: "flex items-center space-x-3 mb-6" },
160
+ React.createElement(TableCellsIcon, { className: "h-8 w-8 text-blue-600" }),
161
+ React.createElement("h2", { className: "text-2xl font-bold text-gray-900" }, gridConfig.title || 'Resource Grid'),
162
+ isFilteringActive && (React.createElement("span", { className: "inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-purple-100 text-purple-800" }, "Filtered")),
163
+ React.createElement("span", { className: "inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-gray-100 text-gray-800" },
164
+ selectedResourceIds.length,
165
+ " resource",
166
+ selectedResourceIds.length !== 1 ? 's' : '')),
167
+ gridConfig.description && React.createElement("p", { className: "text-gray-600 mb-6" }, gridConfig.description),
168
+ React.createElement("div", { className: "bg-white rounded-lg shadow-sm border border-gray-200 p-6" },
169
+ showContextControls && contextOptions?.showContextControls !== false && (React.createElement("div", { className: "mb-6" },
170
+ React.createElement("h3", { className: "text-lg font-semibold text-gray-900 mb-4" }, contextOptions?.contextPanelTitle || 'Context Configuration'),
171
+ React.createElement("div", { className: `bg-gray-50 rounded-lg p-4 ${contextOptions?.contextPanelClassName || ''}` },
172
+ React.createElement("div", { className: "mb-4" },
173
+ React.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3" }, visibleQualifiers.map((qualifierName) => {
174
+ const qualifierOptions = contextOptions?.qualifierOptions?.[qualifierName];
175
+ const hostManagedValue = contextOptions?.hostManagedValues?.[qualifierName];
176
+ const globalPlaceholder = typeof contextOptions?.globalPlaceholder === 'function'
177
+ ? contextOptions.globalPlaceholder(qualifierName)
178
+ : contextOptions?.globalPlaceholder;
179
+ const mergedOptions = {
180
+ ...qualifierOptions,
181
+ hostValue: hostManagedValue !== undefined ? hostManagedValue : qualifierOptions?.hostValue
182
+ };
183
+ return (React.createElement(QualifierContextControl, { key: qualifierName, qualifierName: qualifierName, value: resolutionState?.pendingContextValues[qualifierName], onChange: handleQualifierChange, placeholder: globalPlaceholder || `Enter ${qualifierName} value`, resources: baseProcessedResources, options: mergedOptions }));
184
+ }))),
185
+ contextOptions?.showCurrentContext !== false && (React.createElement("div", { className: "flex items-center justify-between" },
186
+ React.createElement("div", { className: "text-sm text-gray-600" },
187
+ "Current:",
188
+ ' ',
189
+ Object.entries(effectiveContextValues)
190
+ .map(([key, value]) => `${key}=${value === undefined ? '(undefined)' : value}`)
191
+ .join(', ')),
192
+ contextOptions?.showContextActions !== false && (React.createElement("div", { className: "flex items-center space-x-2" },
193
+ React.createElement("button", { onClick: resolutionActions?.resetCache, className: "px-3 py-1 text-xs font-medium text-gray-600 bg-gray-100 rounded hover:bg-gray-200 focus:outline-none focus:ring-2 focus:ring-gray-500", title: "Clear resolution cache" }, "Clear Cache"),
194
+ React.createElement("button", { onClick: () => resolutionActions?.applyContext(), disabled: !resolutionState?.hasPendingChanges, className: `px-4 py-2 rounded-md text-sm font-medium ${resolutionState?.hasPendingChanges
195
+ ? 'bg-blue-600 text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500'
196
+ : 'bg-gray-300 text-gray-500 cursor-not-allowed'}` }, resolutionState?.hasPendingChanges
197
+ ? 'Apply Changes'
198
+ : resolutionState?.currentResolver
199
+ ? 'Context Applied'
200
+ : 'Apply Context')))))))),
201
+ React.createElement(ResourceGrid, { gridConfig: gridConfig, selectedResourceIds: selectedResourceIds, resourceResolutions: resourceResolutions, resolutionActions: resolutionActions, resolutionState: resolutionState, onMessage: onMessage }),
202
+ showChangeControls &&
203
+ (resolutionState?.hasUnsavedEdits || resolutionState?.hasPendingResourceChanges) && (React.createElement("div", { className: "mt-6" },
204
+ React.createElement(UnifiedChangeControls, { editCount: resolutionState?.editedResources?.size || 0, addCount: resolutionState?.pendingResources?.size || 0, deleteCount: resolutionState?.pendingResourceDeletions?.size || 0, isApplying: resolutionState?.isApplyingEdits, disabled: !resolutionState?.currentResolver, onApplyAll: async () => {
205
+ await resolutionActions?.applyPendingResources();
206
+ }, onDiscardAll: () => {
207
+ resolutionActions?.discardEdits?.();
208
+ resolutionActions?.discardPendingResources?.();
209
+ } }))))));
210
+ };
211
+ export default GridView;
212
+ //# sourceMappingURL=index.js.map
@@ -2,6 +2,7 @@ import React, { useState, useCallback, useRef } from 'react';
2
2
  import { DocumentArrowUpIcon, CheckCircleIcon, ExclamationTriangleIcon, ArchiveBoxIcon, FolderOpenIcon } from '@heroicons/react/24/outline';
3
3
  import { Bundle, ZipArchive } from '@fgv/ts-res';
4
4
  import { isZipFile } from '../../../utils/zipLoader';
5
+ import { useObservability } from '../../../contexts';
5
6
  /**
6
7
  * ImportView component for importing resource files, directories, and bundles.
7
8
  *
@@ -49,7 +50,9 @@ import { isZipFile } from '../../../utils/zipLoader';
49
50
  *
50
51
  * @public
51
52
  */
52
- export const ImportView = ({ onImport, onBundleImport, onZipImport, acceptedFileTypes = ['.json', '.zip'], onMessage, className = '' }) => {
53
+ export const ImportView = ({ onImport, onBundleImport, onZipImport, acceptedFileTypes = ['.json', '.zip'], onMessage, className = '', importError }) => {
54
+ // Get observability context
55
+ const o11y = useObservability();
53
56
  const [isLoading, setIsLoading] = useState(false);
54
57
  const [importStatus, setImportStatus] = useState({
55
58
  hasImported: false,
@@ -65,7 +68,7 @@ export const ImportView = ({ onImport, onBundleImport, onZipImport, acceptedFile
65
68
  const isFileSystemAccessSupported = 'showDirectoryPicker' in window || 'showOpenFilePicker' in window;
66
69
  // Helper function to process ZIP files using zip-archive packlet
67
70
  const processZipFile = useCallback(async (file) => {
68
- console.log(`[ImportView] Processing ZIP file: ${file.name}`);
71
+ o11y.diag.info(`[ImportView] Processing ZIP file: ${file.name}`);
69
72
  onMessage?.('info', `Processing ZIP file: ${file.name}`);
70
73
  const loader = new ZipArchive.ZipArchiveLoader();
71
74
  const loadResult = await loader.loadFromFile(file, {
@@ -75,7 +78,7 @@ export const ImportView = ({ onImport, onBundleImport, onZipImport, acceptedFile
75
78
  throw new Error(`Failed to load ZIP: ${loadResult.message}`);
76
79
  }
77
80
  const zipData = loadResult.value;
78
- console.log(`[ImportView] ZIP loaded successfully:`, zipData);
81
+ o11y.diag.info(`[ImportView] ZIP loaded successfully:`, zipData);
79
82
  // Pass the ZIP data to the appropriate handler
80
83
  if (onZipImport) {
81
84
  // Pass both the directory/files and any configuration found
@@ -107,7 +110,7 @@ export const ImportView = ({ onImport, onBundleImport, onZipImport, acceptedFile
107
110
  const file = files[0];
108
111
  // Check if it's a ZIP file first
109
112
  if (isZipFile(file.name)) {
110
- console.log(`[ImportView] ✅ ${file.name} detected as ZIP file`);
113
+ o11y.diag.info(`[ImportView] ✅ ${file.name} detected as ZIP file`);
111
114
  const zipData = await processZipFile(file);
112
115
  setImportStatus({
113
116
  hasImported: true,
@@ -137,10 +140,10 @@ export const ImportView = ({ onImport, onBundleImport, onZipImport, acceptedFile
137
140
  let isCurrentFileBundle = false;
138
141
  try {
139
142
  const parsedData = JSON.parse(content);
140
- console.log(`[ImportView] Checking if ${file.name} is a bundle...`);
143
+ o11y.diag.info(`[ImportView] Checking if ${file.name} is a bundle...`);
141
144
  // Use BundleUtils for proper bundle detection
142
145
  if (Bundle.BundleUtils.isBundleFile(parsedData)) {
143
- console.log(`[ImportView] ✅ ${file.name} detected as bundle file`);
146
+ o11y.diag.info(`[ImportView] ✅ ${file.name} detected as bundle file`);
144
147
  bundleFile = { ...importedFile, bundle: parsedData };
145
148
  isCurrentFileBundle = true;
146
149
  }
@@ -149,11 +152,11 @@ export const ImportView = ({ onImport, onBundleImport, onZipImport, acceptedFile
149
152
  console.warn(`[ImportView] ⚠️ File ${file.name} appears to be a bundle by name but content doesn't match bundle structure`);
150
153
  }
151
154
  else {
152
- console.log(`[ImportView] ❌ ${file.name} is not a bundle file`);
155
+ o11y.diag.info(`[ImportView] ❌ ${file.name} is not a bundle file`);
153
156
  }
154
157
  }
155
158
  catch (parseError) {
156
- console.log(`[ImportView] ❌ ${file.name} failed JSON parsing:`, parseError);
159
+ o11y.diag.info(`[ImportView] ❌ ${file.name} failed JSON parsing:`, parseError);
157
160
  // Not valid JSON or not a bundle, treat as regular file
158
161
  }
159
162
  // Only add to regular files if this specific file is not a bundle
@@ -163,7 +166,7 @@ export const ImportView = ({ onImport, onBundleImport, onZipImport, acceptedFile
163
166
  }
164
167
  // Process results
165
168
  if (bundleFile) {
166
- console.log(`[ImportView] Processing bundle file: ${bundleFile.name}`, bundleFile.bundle);
169
+ o11y.diag.info(`[ImportView] Processing bundle file: ${bundleFile.name}`, bundleFile.bundle);
167
170
  setImportStatus({
168
171
  hasImported: true,
169
172
  fileCount: 1,
@@ -173,11 +176,11 @@ export const ImportView = ({ onImport, onBundleImport, onZipImport, acceptedFile
173
176
  });
174
177
  onMessage?.('info', `Bundle file detected: ${bundleFile.name}`);
175
178
  if (onBundleImport && bundleFile.bundle) {
176
- console.log(`[ImportView] Calling onBundleImport with bundle data`);
179
+ o11y.diag.info(`[ImportView] Calling onBundleImport with bundle data`);
177
180
  onBundleImport(bundleFile.bundle);
178
181
  }
179
182
  else {
180
- console.warn(`[ImportView] No bundle import handler or bundle data missing`);
183
+ o11y.diag.warn(`[ImportView] No bundle import handler or bundle data missing`);
181
184
  }
182
185
  }
183
186
  else if (importedFiles.length > 0) {
@@ -346,7 +349,7 @@ export const ImportView = ({ onImport, onBundleImport, onZipImport, acceptedFile
346
349
  if (fileHandles.length === 1) {
347
350
  const file = await fileHandles[0].getFile();
348
351
  if (isZipFile(file.name)) {
349
- console.log(`[ImportView] Modern API - ✅ ${file.name} detected as ZIP file`);
352
+ o11y.diag.info(`[ImportView] Modern API - ✅ ${file.name} detected as ZIP file`);
350
353
  const zipData = await processZipFile(file);
351
354
  setImportStatus({
352
355
  hasImported: true,
@@ -379,10 +382,10 @@ export const ImportView = ({ onImport, onBundleImport, onZipImport, acceptedFile
379
382
  let isCurrentFileBundle = false;
380
383
  try {
381
384
  const parsedData = JSON.parse(content);
382
- console.log(`[ImportView] Modern API - Checking if ${file.name} is a bundle...`);
385
+ o11y.diag.info(`[ImportView] Modern API - Checking if ${file.name} is a bundle...`);
383
386
  // Use BundleUtils for proper bundle detection
384
387
  if (Bundle.BundleUtils.isBundleFile(parsedData)) {
385
- console.log(`[ImportView] Modern API - ✅ ${file.name} detected as bundle file`);
388
+ o11y.diag.info(`[ImportView] Modern API - ✅ ${file.name} detected as bundle file`);
386
389
  bundleFile = { ...importedFile, bundle: parsedData };
387
390
  isCurrentFileBundle = true;
388
391
  }
@@ -390,11 +393,11 @@ export const ImportView = ({ onImport, onBundleImport, onZipImport, acceptedFile
390
393
  console.warn(`[ImportView] Modern API - ⚠️ File ${file.name} appears to be a bundle by name but content doesn't match bundle structure`);
391
394
  }
392
395
  else {
393
- console.log(`[ImportView] Modern API - ❌ ${file.name} is not a bundle file`);
396
+ o11y.diag.info(`[ImportView] Modern API - ❌ ${file.name} is not a bundle file`);
394
397
  }
395
398
  }
396
399
  catch (parseError) {
397
- console.log(`[ImportView] Modern API - ❌ ${file.name} failed JSON parsing:`, parseError);
400
+ o11y.diag.info(`[ImportView] Modern API - ❌ ${file.name} failed JSON parsing:`, parseError);
398
401
  }
399
402
  // Only add to regular files if this specific file is not a bundle
400
403
  if (!isCurrentFileBundle) {
@@ -513,13 +516,13 @@ export const ImportView = ({ onImport, onBundleImport, onZipImport, acceptedFile
513
516
  React.createElement(ArchiveBoxIcon, { className: "w-5 h-5 text-purple-500" }),
514
517
  React.createElement("span", { className: "text-sm text-purple-900" }, "ZIP archive processed")))),
515
518
  importStatus.hasImported && (React.createElement("button", { onClick: handleReset, className: "mt-4 px-4 py-2 text-sm bg-gray-100 text-gray-700 rounded-lg hover:bg-gray-200 transition-colors" }, "Clear Import"))),
516
- error && (React.createElement("div", { className: "bg-white rounded-lg shadow-sm border border-red-200 p-6" },
519
+ (error || importError) && (React.createElement("div", { className: "bg-white rounded-lg shadow-sm border border-red-200 p-6" },
517
520
  React.createElement("div", { className: "flex items-start space-x-2" },
518
521
  React.createElement(ExclamationTriangleIcon, { className: "w-5 h-5 text-red-600 mt-0.5" }),
519
522
  React.createElement("div", { className: "text-sm text-red-800" },
520
523
  React.createElement("p", { className: "font-medium" }, "Error"),
521
- React.createElement("p", null, error))))),
522
- importStatus.hasImported && !error && (React.createElement("div", { className: "bg-white rounded-lg shadow-sm border border-green-200 p-6" },
524
+ React.createElement("p", null, importError || error))))),
525
+ importStatus.hasImported && !error && !importError && (React.createElement("div", { className: "bg-white rounded-lg shadow-sm border border-green-200 p-6" },
523
526
  React.createElement("div", { className: "flex items-start space-x-2" },
524
527
  React.createElement(CheckCircleIcon, { className: "w-5 h-5 text-green-600 mt-0.5" }),
525
528
  React.createElement("div", { className: "text-sm text-green-800" },
@@ -1,6 +1,7 @@
1
1
  import React, { useState, useMemo } from 'react';
2
2
  import { InformationCircleIcon, ExclamationTriangleIcon, XCircleIcon, CheckCircleIcon, ChevronUpIcon, ChevronDownIcon, FunnelIcon, DocumentDuplicateIcon, MagnifyingGlassIcon } from '@heroicons/react/24/outline';
3
3
  import { CheckIcon } from '@heroicons/react/24/solid';
4
+ import { useObservability } from '../../../contexts';
4
5
  /**
5
6
  * MessagesWindow component for displaying and managing application messages.
6
7
  *
@@ -95,6 +96,8 @@ import { CheckIcon } from '@heroicons/react/24/solid';
95
96
  * @public
96
97
  */
97
98
  export const MessagesWindow = ({ messages, onClearMessages, className = '' }) => {
99
+ // Get observability context
100
+ const o11y = useObservability();
98
101
  const [isCollapsed, setIsCollapsed] = useState(false);
99
102
  const [filter, setFilter] = useState('all');
100
103
  const [searchTerm, setSearchTerm] = useState('');
@@ -119,7 +122,7 @@ export const MessagesWindow = ({ messages, onClearMessages, className = '' }) =>
119
122
  setTimeout(() => setCopySuccess(false), 2000);
120
123
  })
121
124
  .catch((err) => {
122
- console.error('Failed to copy messages:', err);
125
+ o11y.diag.error('Failed to copy messages:', err);
123
126
  });
124
127
  };
125
128
  if (messages.length === 0) {
@@ -7,6 +7,7 @@ import { ResourcePickerOptionsControl } from '../../common/ResourcePickerOptions
7
7
  import { ResolutionContextOptionsControl } from '../../common/ResolutionContextOptionsControl';
8
8
  import { ResolutionResults } from '../../common/ResolutionResults';
9
9
  import { NewResourceModal } from './NewResourceModal';
10
+ import { useObservability } from '../../../contexts';
10
11
  /**
11
12
  * ResolutionView component for resource resolution testing and editing.
12
13
  *
@@ -57,6 +58,8 @@ import { NewResourceModal } from './NewResourceModal';
57
58
  * @public
58
59
  */
59
60
  export const ResolutionView = ({ resources, filterState, filterResult, resolutionState, resolutionActions, availableQualifiers = [], resourceEditorFactory, onMessage, pickerOptions, pickerOptionsPresentation = 'hidden', contextOptions, lockedViewMode, sectionTitles, allowResourceCreation = false, defaultResourceType, resourceTypeFactory, onPendingResourcesApplied, showPendingResourcesInList = true, className = '' }) => {
61
+ // Get observability context
62
+ const o11y = useObservability();
60
63
  // State for picker options control
61
64
  const [currentPickerOptions, setCurrentPickerOptions] = useState(pickerOptions || {});
62
65
  // State for context options control
@@ -209,10 +212,10 @@ export const ResolutionView = ({ resources, filterState, filterResult, resolutio
209
212
  ? currentContextOptions.hostManagedValues
210
213
  : contextOptions?.hostManagedValues
211
214
  };
212
- console.log('ResolutionView - effectiveContextOptions:', merged);
213
- console.log('ResolutionView - contextOptions hostManagedValues:', contextOptions?.hostManagedValues);
214
- console.log('ResolutionView - currentContextOptions hostManagedValues:', currentContextOptions?.hostManagedValues);
215
- console.log('ResolutionView - final hostManagedValues:', merged.hostManagedValues);
215
+ o11y.diag.info('ResolutionView - effectiveContextOptions:', merged);
216
+ o11y.diag.info('ResolutionView - contextOptions hostManagedValues:', contextOptions?.hostManagedValues);
217
+ o11y.diag.info('ResolutionView - currentContextOptions hostManagedValues:', currentContextOptions?.hostManagedValues);
218
+ o11y.diag.info('ResolutionView - final hostManagedValues:', merged.hostManagedValues);
216
219
  return merged;
217
220
  }, [contextOptions, currentContextOptions]);
218
221
  // Handle context value changes using the shared component's callback pattern
@@ -304,7 +307,7 @@ export const ResolutionView = ({ resources, filterState, filterResult, resolutio
304
307
  }, [resolutionActions]);
305
308
  // Handle new resource creation
306
309
  const handleStartNewResource = useCallback(() => {
307
- resolutionActions?.startNewResource(defaultResourceType);
310
+ resolutionActions?.startNewResource({ defaultTypeName: defaultResourceType });
308
311
  setShowNewResourceModal(true);
309
312
  }, [resolutionActions]);
310
313
  const handleCloseNewResourceModal = useCallback(() => {
@@ -0,0 +1,85 @@
1
+ import React, { ReactNode } from 'react';
2
+ import * as ObservabilityTools from '../utils/observability';
3
+ /**
4
+ * React context for observability infrastructure.
5
+ * Provides access to diagnostic and user loggers throughout the component tree.
6
+ * @public
7
+ */
8
+ export declare const ObservabilityContext: React.Context<ObservabilityTools.IObservabilityContext>;
9
+ /**
10
+ * Props for the ObservabilityProvider component.
11
+ * @public
12
+ */
13
+ export interface ObservabilityProviderProps {
14
+ /** Child components that will have access to the observability context */
15
+ children: ReactNode;
16
+ /** Optional observability context to provide (defaults to console-based context) */
17
+ observabilityContext?: ObservabilityTools.IObservabilityContext;
18
+ }
19
+ /**
20
+ * Provider component that makes observability context available to all child components.
21
+ *
22
+ * @example
23
+ * ```tsx
24
+ * // Basic usage with default console logging
25
+ * <ObservabilityProvider>
26
+ * <MyApp />
27
+ * </ObservabilityProvider>
28
+ *
29
+ * // Custom observability context
30
+ * const customContext = ObservabilityTools.createConsoleObservabilityContext('debug', 'info');
31
+ * <ObservabilityProvider observabilityContext={customContext}>
32
+ * <MyApp />
33
+ * </ObservabilityProvider>
34
+ *
35
+ * // With custom user logger that forwards to app's message system
36
+ * const contextWithMessages = new ObservabilityTools.ObservabilityContext(
37
+ * new ObservabilityTools.ConsoleUserLogger('info'),
38
+ * createCallbackUserLogger((type, message) => showToast(type, message))
39
+ * );
40
+ * <ObservabilityProvider observabilityContext={contextWithMessages}>
41
+ * <MyApp />
42
+ * </ObservabilityProvider>
43
+ * ```
44
+ *
45
+ * @param props - Provider configuration
46
+ * @returns JSX provider element
47
+ * @public
48
+ */
49
+ export declare const ObservabilityProvider: React.FC<ObservabilityProviderProps>;
50
+ /**
51
+ * Hook to access the current observability context.
52
+ *
53
+ * Provides access to both diagnostic logging (for developers/debugging) and
54
+ * user logging (for user-facing messages and feedback).
55
+ *
56
+ * @example
57
+ * ```tsx
58
+ * function MyComponent() {
59
+ * const observability = useObservability();
60
+ *
61
+ * const handleAction = () => {
62
+ * // Log diagnostic info for developers
63
+ * observability.diag.info('User clicked action button');
64
+ *
65
+ * try {
66
+ * performAction();
67
+ * // Show success message to user
68
+ * observability.user.success('Action completed successfully!');
69
+ * } catch (error) {
70
+ * // Log error for debugging
71
+ * observability.diag.error('Action failed:', error);
72
+ * // Show error to user
73
+ * observability.user.error('Action failed. Please try again.');
74
+ * }
75
+ * };
76
+ *
77
+ * return <button onClick={handleAction}>Perform Action</button>;
78
+ * }
79
+ * ```
80
+ *
81
+ * @returns The current observability context with diag and user loggers
82
+ * @public
83
+ */
84
+ export declare const useObservability: () => ObservabilityTools.IObservabilityContext;
85
+ //# sourceMappingURL=ObservabilityContext.d.ts.map
@@ -0,0 +1,98 @@
1
+ /*
2
+ * Copyright (c) 2025 Erik Fortune
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in all
12
+ * copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+ import React, { createContext, useContext } from 'react';
23
+ import * as ObservabilityTools from '../utils/observability';
24
+ /**
25
+ * React context for observability infrastructure.
26
+ * Provides access to diagnostic and user loggers throughout the component tree.
27
+ * @public
28
+ */
29
+ export const ObservabilityContext = createContext(ObservabilityTools.DefaultObservabilityContext);
30
+ /**
31
+ * Provider component that makes observability context available to all child components.
32
+ *
33
+ * @example
34
+ * ```tsx
35
+ * // Basic usage with default console logging
36
+ * <ObservabilityProvider>
37
+ * <MyApp />
38
+ * </ObservabilityProvider>
39
+ *
40
+ * // Custom observability context
41
+ * const customContext = ObservabilityTools.createConsoleObservabilityContext('debug', 'info');
42
+ * <ObservabilityProvider observabilityContext={customContext}>
43
+ * <MyApp />
44
+ * </ObservabilityProvider>
45
+ *
46
+ * // With custom user logger that forwards to app's message system
47
+ * const contextWithMessages = new ObservabilityTools.ObservabilityContext(
48
+ * new ObservabilityTools.ConsoleUserLogger('info'),
49
+ * createCallbackUserLogger((type, message) => showToast(type, message))
50
+ * );
51
+ * <ObservabilityProvider observabilityContext={contextWithMessages}>
52
+ * <MyApp />
53
+ * </ObservabilityProvider>
54
+ * ```
55
+ *
56
+ * @param props - Provider configuration
57
+ * @returns JSX provider element
58
+ * @public
59
+ */
60
+ export const ObservabilityProvider = ({ children, observabilityContext = ObservabilityTools.DefaultObservabilityContext }) => React.createElement(ObservabilityContext.Provider, { value: observabilityContext }, children);
61
+ /**
62
+ * Hook to access the current observability context.
63
+ *
64
+ * Provides access to both diagnostic logging (for developers/debugging) and
65
+ * user logging (for user-facing messages and feedback).
66
+ *
67
+ * @example
68
+ * ```tsx
69
+ * function MyComponent() {
70
+ * const observability = useObservability();
71
+ *
72
+ * const handleAction = () => {
73
+ * // Log diagnostic info for developers
74
+ * observability.diag.info('User clicked action button');
75
+ *
76
+ * try {
77
+ * performAction();
78
+ * // Show success message to user
79
+ * observability.user.success('Action completed successfully!');
80
+ * } catch (error) {
81
+ * // Log error for debugging
82
+ * observability.diag.error('Action failed:', error);
83
+ * // Show error to user
84
+ * observability.user.error('Action failed. Please try again.');
85
+ * }
86
+ * };
87
+ *
88
+ * return <button onClick={handleAction}>Perform Action</button>;
89
+ * }
90
+ * ```
91
+ *
92
+ * @returns The current observability context with diag and user loggers
93
+ * @public
94
+ */
95
+ export const useObservability = () => {
96
+ return useContext(ObservabilityContext);
97
+ };
98
+ //# sourceMappingURL=ObservabilityContext.js.map
@@ -0,0 +1,2 @@
1
+ export { ObservabilityContext, ObservabilityProvider, useObservability, type ObservabilityProviderProps } from './ObservabilityContext';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,24 @@
1
+ /*
2
+ * Copyright (c) 2025 Erik Fortune
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in all
12
+ * copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+ // Export observability context components and hooks
23
+ export { ObservabilityContext, ObservabilityProvider, useObservability } from './ObservabilityContext';
24
+ //# sourceMappingURL=index.js.map