@djangocfg/ui-nextjs 2.1.90 → 2.1.91

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 (161) hide show
  1. package/README.md +6 -15
  2. package/package.json +6 -25
  3. package/src/blocks/SplitHero/SplitHeroMedia.tsx +1 -1
  4. package/src/components/index.ts +0 -40
  5. package/src/hooks/index.ts +0 -6
  6. package/src/index.ts +2 -11
  7. package/src/components/button-download.tsx +0 -277
  8. package/src/components/markdown/MarkdownMessage.tsx +0 -340
  9. package/src/components/markdown/index.ts +0 -5
  10. package/src/components/menubar.tsx +0 -275
  11. package/src/components/multi-select-pro/async.tsx +0 -598
  12. package/src/components/multi-select-pro/helpers.tsx +0 -84
  13. package/src/components/multi-select-pro/index.tsx +0 -612
  14. package/src/components/navigation-menu.tsx +0 -154
  15. package/src/components/otp/index.tsx +0 -197
  16. package/src/components/otp/types.ts +0 -133
  17. package/src/components/otp/use-otp-input.ts +0 -225
  18. package/src/components/phone-input.tsx +0 -277
  19. package/src/components/sonner.tsx +0 -32
  20. package/src/hooks/useLocalStorage.ts +0 -300
  21. package/src/hooks/useSessionStorage.ts +0 -290
  22. package/src/lib/index.ts +0 -5
  23. package/src/lib/logger/index.ts +0 -10
  24. package/src/lib/logger/logStore.ts +0 -122
  25. package/src/lib/logger/logger.ts +0 -175
  26. package/src/lib/logger/types.ts +0 -82
  27. package/src/stores/index.ts +0 -8
  28. package/src/stores/mediaCache.ts +0 -534
  29. package/src/tools/AudioPlayer/README.md +0 -206
  30. package/src/tools/AudioPlayer/components/HybridAudioPlayer.tsx +0 -216
  31. package/src/tools/AudioPlayer/components/HybridSimplePlayer.tsx +0 -280
  32. package/src/tools/AudioPlayer/components/HybridWaveform.tsx +0 -279
  33. package/src/tools/AudioPlayer/components/ReactiveCover/AudioReactiveCover.tsx +0 -149
  34. package/src/tools/AudioPlayer/components/ReactiveCover/effects/GlowEffect.tsx +0 -110
  35. package/src/tools/AudioPlayer/components/ReactiveCover/effects/MeshEffect.tsx +0 -58
  36. package/src/tools/AudioPlayer/components/ReactiveCover/effects/OrbsEffect.tsx +0 -45
  37. package/src/tools/AudioPlayer/components/ReactiveCover/effects/SpotlightEffect.tsx +0 -82
  38. package/src/tools/AudioPlayer/components/ReactiveCover/effects/index.ts +0 -8
  39. package/src/tools/AudioPlayer/components/ReactiveCover/index.ts +0 -6
  40. package/src/tools/AudioPlayer/components/index.ts +0 -22
  41. package/src/tools/AudioPlayer/context/HybridAudioProvider.tsx +0 -158
  42. package/src/tools/AudioPlayer/context/index.ts +0 -16
  43. package/src/tools/AudioPlayer/effects/index.ts +0 -412
  44. package/src/tools/AudioPlayer/hooks/index.ts +0 -35
  45. package/src/tools/AudioPlayer/hooks/useHybridAudio.ts +0 -387
  46. package/src/tools/AudioPlayer/hooks/useHybridAudioAnalysis.ts +0 -95
  47. package/src/tools/AudioPlayer/hooks/useVisualization.tsx +0 -207
  48. package/src/tools/AudioPlayer/index.ts +0 -133
  49. package/src/tools/AudioPlayer/types/effects.ts +0 -73
  50. package/src/tools/AudioPlayer/types/index.ts +0 -27
  51. package/src/tools/AudioPlayer/utils/debug.ts +0 -14
  52. package/src/tools/AudioPlayer/utils/formatTime.ts +0 -10
  53. package/src/tools/AudioPlayer/utils/index.ts +0 -6
  54. package/src/tools/ImageViewer/@refactoring/00-PLAN.md +0 -71
  55. package/src/tools/ImageViewer/@refactoring/01-TYPES.md +0 -121
  56. package/src/tools/ImageViewer/@refactoring/02-UTILS.md +0 -143
  57. package/src/tools/ImageViewer/@refactoring/03-HOOKS.md +0 -261
  58. package/src/tools/ImageViewer/@refactoring/04-COMPONENTS.md +0 -427
  59. package/src/tools/ImageViewer/@refactoring/05-EXECUTION-CHECKLIST.md +0 -126
  60. package/src/tools/ImageViewer/README.md +0 -200
  61. package/src/tools/ImageViewer/components/ImageInfo.tsx +0 -44
  62. package/src/tools/ImageViewer/components/ImageToolbar.tsx +0 -150
  63. package/src/tools/ImageViewer/components/ImageViewer.tsx +0 -241
  64. package/src/tools/ImageViewer/components/index.ts +0 -7
  65. package/src/tools/ImageViewer/hooks/index.ts +0 -9
  66. package/src/tools/ImageViewer/hooks/useImageLoading.ts +0 -204
  67. package/src/tools/ImageViewer/hooks/useImageTransform.ts +0 -101
  68. package/src/tools/ImageViewer/index.ts +0 -60
  69. package/src/tools/ImageViewer/types.ts +0 -81
  70. package/src/tools/ImageViewer/utils/constants.ts +0 -59
  71. package/src/tools/ImageViewer/utils/debug.ts +0 -14
  72. package/src/tools/ImageViewer/utils/index.ts +0 -17
  73. package/src/tools/ImageViewer/utils/lqip.ts +0 -47
  74. package/src/tools/JsonForm/JsonSchemaForm.tsx +0 -197
  75. package/src/tools/JsonForm/examples/BotConfigExample.tsx +0 -249
  76. package/src/tools/JsonForm/examples/RealBotConfigExample.tsx +0 -161
  77. package/src/tools/JsonForm/index.ts +0 -46
  78. package/src/tools/JsonForm/templates/ArrayFieldItemTemplate.tsx +0 -47
  79. package/src/tools/JsonForm/templates/ArrayFieldTemplate.tsx +0 -74
  80. package/src/tools/JsonForm/templates/BaseInputTemplate.tsx +0 -107
  81. package/src/tools/JsonForm/templates/ErrorListTemplate.tsx +0 -35
  82. package/src/tools/JsonForm/templates/FieldTemplate.tsx +0 -62
  83. package/src/tools/JsonForm/templates/ObjectFieldTemplate.tsx +0 -116
  84. package/src/tools/JsonForm/templates/index.ts +0 -12
  85. package/src/tools/JsonForm/types.ts +0 -83
  86. package/src/tools/JsonForm/utils.ts +0 -213
  87. package/src/tools/JsonForm/widgets/CheckboxWidget.tsx +0 -37
  88. package/src/tools/JsonForm/widgets/ColorWidget.tsx +0 -219
  89. package/src/tools/JsonForm/widgets/NumberWidget.tsx +0 -89
  90. package/src/tools/JsonForm/widgets/SelectWidget.tsx +0 -97
  91. package/src/tools/JsonForm/widgets/SliderWidget.tsx +0 -148
  92. package/src/tools/JsonForm/widgets/SwitchWidget.tsx +0 -35
  93. package/src/tools/JsonForm/widgets/TextWidget.tsx +0 -96
  94. package/src/tools/JsonForm/widgets/index.ts +0 -14
  95. package/src/tools/JsonTree/index.tsx +0 -243
  96. package/src/tools/LottiePlayer/LottiePlayer.client.tsx +0 -213
  97. package/src/tools/LottiePlayer/index.tsx +0 -55
  98. package/src/tools/LottiePlayer/types.ts +0 -108
  99. package/src/tools/LottiePlayer/useLottie.ts +0 -164
  100. package/src/tools/Mermaid/Mermaid.client.tsx +0 -82
  101. package/src/tools/Mermaid/components/MermaidCodeViewer.tsx +0 -95
  102. package/src/tools/Mermaid/components/MermaidFullscreenModal.tsx +0 -103
  103. package/src/tools/Mermaid/hooks/index.ts +0 -4
  104. package/src/tools/Mermaid/hooks/useMermaidCleanup.ts +0 -73
  105. package/src/tools/Mermaid/hooks/useMermaidFullscreen.ts +0 -46
  106. package/src/tools/Mermaid/hooks/useMermaidRenderer.ts +0 -226
  107. package/src/tools/Mermaid/hooks/useMermaidValidation.ts +0 -29
  108. package/src/tools/Mermaid/index.tsx +0 -41
  109. package/src/tools/Mermaid/utils/mermaid-helpers.ts +0 -33
  110. package/src/tools/OpenapiViewer/components/EndpointInfo.tsx +0 -149
  111. package/src/tools/OpenapiViewer/components/EndpointsLibrary.tsx +0 -263
  112. package/src/tools/OpenapiViewer/components/PlaygroundLayout.tsx +0 -125
  113. package/src/tools/OpenapiViewer/components/PlaygroundStepper.tsx +0 -100
  114. package/src/tools/OpenapiViewer/components/RequestBuilder.tsx +0 -157
  115. package/src/tools/OpenapiViewer/components/RequestParametersForm.tsx +0 -253
  116. package/src/tools/OpenapiViewer/components/ResponseViewer.tsx +0 -173
  117. package/src/tools/OpenapiViewer/components/VersionSelector.tsx +0 -68
  118. package/src/tools/OpenapiViewer/components/index.ts +0 -14
  119. package/src/tools/OpenapiViewer/constants.ts +0 -39
  120. package/src/tools/OpenapiViewer/context/PlaygroundContext.tsx +0 -337
  121. package/src/tools/OpenapiViewer/hooks/index.ts +0 -8
  122. package/src/tools/OpenapiViewer/hooks/useMobile.ts +0 -10
  123. package/src/tools/OpenapiViewer/hooks/useOpenApiSchema.ts +0 -199
  124. package/src/tools/OpenapiViewer/index.tsx +0 -38
  125. package/src/tools/OpenapiViewer/types.ts +0 -151
  126. package/src/tools/OpenapiViewer/utils/apiKeyManager.ts +0 -149
  127. package/src/tools/OpenapiViewer/utils/formatters.ts +0 -71
  128. package/src/tools/OpenapiViewer/utils/index.ts +0 -9
  129. package/src/tools/OpenapiViewer/utils/versionManager.ts +0 -161
  130. package/src/tools/PrettyCode/PrettyCode.client.tsx +0 -208
  131. package/src/tools/PrettyCode/index.tsx +0 -45
  132. package/src/tools/VideoPlayer/@refactoring/00-PLAN.md +0 -91
  133. package/src/tools/VideoPlayer/@refactoring/01-TYPES.md +0 -284
  134. package/src/tools/VideoPlayer/@refactoring/02-UTILS.md +0 -141
  135. package/src/tools/VideoPlayer/@refactoring/03-HOOKS.md +0 -178
  136. package/src/tools/VideoPlayer/@refactoring/04-COMPONENTS.md +0 -95
  137. package/src/tools/VideoPlayer/@refactoring/05-EXECUTION-CHECKLIST.md +0 -139
  138. package/src/tools/VideoPlayer/README.md +0 -264
  139. package/src/tools/VideoPlayer/components/VideoControls.tsx +0 -138
  140. package/src/tools/VideoPlayer/components/VideoErrorFallback.tsx +0 -174
  141. package/src/tools/VideoPlayer/components/VideoPlayer.tsx +0 -201
  142. package/src/tools/VideoPlayer/components/index.ts +0 -14
  143. package/src/tools/VideoPlayer/context/VideoPlayerContext.tsx +0 -52
  144. package/src/tools/VideoPlayer/context/index.ts +0 -8
  145. package/src/tools/VideoPlayer/hooks/index.ts +0 -12
  146. package/src/tools/VideoPlayer/hooks/useVideoPlayerSettings.ts +0 -70
  147. package/src/tools/VideoPlayer/hooks/useVideoPositionCache.ts +0 -116
  148. package/src/tools/VideoPlayer/index.ts +0 -77
  149. package/src/tools/VideoPlayer/providers/NativeProvider.tsx +0 -284
  150. package/src/tools/VideoPlayer/providers/StreamProvider.tsx +0 -505
  151. package/src/tools/VideoPlayer/providers/VidstackProvider.tsx +0 -400
  152. package/src/tools/VideoPlayer/providers/index.ts +0 -8
  153. package/src/tools/VideoPlayer/types/index.ts +0 -38
  154. package/src/tools/VideoPlayer/types/player.ts +0 -116
  155. package/src/tools/VideoPlayer/types/provider.ts +0 -93
  156. package/src/tools/VideoPlayer/types/sources.ts +0 -97
  157. package/src/tools/VideoPlayer/utils/debug.ts +0 -14
  158. package/src/tools/VideoPlayer/utils/fileSource.ts +0 -78
  159. package/src/tools/VideoPlayer/utils/index.ts +0 -12
  160. package/src/tools/VideoPlayer/utils/resolvers.ts +0 -75
  161. package/src/tools/index.ts +0 -170
@@ -1,290 +0,0 @@
1
- 'use client';
2
-
3
- import { useState } from 'react';
4
-
5
- /**
6
- * Storage wrapper format with metadata
7
- * Used when TTL is specified
8
- */
9
- interface StorageWrapper<T> {
10
- _meta: {
11
- createdAt: number;
12
- ttl: number;
13
- };
14
- _value: T;
15
- }
16
-
17
- /**
18
- * Options for useSessionStorage hook
19
- */
20
- export interface UseSessionStorageOptions {
21
- /**
22
- * Time-to-live in milliseconds.
23
- * After this time, value is considered expired and initialValue is returned.
24
- * Data is automatically cleaned up on next read.
25
- * @example 24 * 60 * 60 * 1000 // 24 hours
26
- */
27
- ttl?: number;
28
- }
29
-
30
- /**
31
- * Check if data is in new wrapped format with _meta
32
- */
33
- function isWrappedFormat<T>(data: unknown): data is StorageWrapper<T> {
34
- return (
35
- data !== null &&
36
- typeof data === 'object' &&
37
- '_meta' in data &&
38
- '_value' in data &&
39
- typeof (data as StorageWrapper<T>)._meta === 'object' &&
40
- typeof (data as StorageWrapper<T>)._meta.createdAt === 'number'
41
- );
42
- }
43
-
44
- /**
45
- * Check if wrapped data is expired
46
- */
47
- function isExpired<T>(wrapped: StorageWrapper<T>): boolean {
48
- if (!wrapped._meta.ttl) return false;
49
- const age = Date.now() - wrapped._meta.createdAt;
50
- return age > wrapped._meta.ttl;
51
- }
52
-
53
- /**
54
- * Simple sessionStorage hook with better error handling and optional TTL support
55
- *
56
- * @param key - Storage key
57
- * @param initialValue - Default value if key doesn't exist
58
- * @param options - Optional configuration (ttl for auto-expiration)
59
- * @returns [value, setValue, removeValue] - Current value, setter function, and remove function
60
- *
61
- * @example
62
- * // Without TTL (backwards compatible)
63
- * const [value, setValue] = useSessionStorage('key', 'default');
64
- *
65
- * @example
66
- * // With TTL (1 hour)
67
- * const [value, setValue] = useSessionStorage('key', 'default', {
68
- * ttl: 60 * 60 * 1000
69
- * });
70
- */
71
- export function useSessionStorage<T>(
72
- key: string,
73
- initialValue: T,
74
- options?: UseSessionStorageOptions
75
- ) {
76
- const ttl = options?.ttl;
77
-
78
- // Get initial value from sessionStorage or use provided initialValue
79
- const [storedValue, setStoredValue] = useState<T>(() => {
80
- if (typeof window === 'undefined') {
81
- return initialValue;
82
- }
83
-
84
- try {
85
- const item = window.sessionStorage.getItem(key);
86
- if (item === null) return initialValue;
87
-
88
- try {
89
- const parsed = JSON.parse(item);
90
-
91
- // Check if new format with _meta
92
- if (isWrappedFormat<T>(parsed)) {
93
- // Check TTL expiration
94
- if (isExpired(parsed)) {
95
- // Expired! Clean up and use initial value
96
- window.sessionStorage.removeItem(key);
97
- return initialValue;
98
- }
99
- // Not expired, extract value
100
- return parsed._value;
101
- }
102
-
103
- // Old format (backwards compatible)
104
- return parsed as T;
105
- } catch {
106
- // If JSON.parse fails, return as string
107
- return item as T;
108
- }
109
- } catch (error) {
110
- console.error(`Error reading sessionStorage key "${key}":`, error);
111
- return initialValue;
112
- }
113
- });
114
-
115
- // Check data size and limit
116
- const checkDataSize = (data: any): boolean => {
117
- try {
118
- const jsonString = JSON.stringify(data);
119
- const sizeInBytes = new Blob([jsonString]).size;
120
- const sizeInKB = sizeInBytes / 1024;
121
-
122
- // Limit to 1MB per item
123
- if (sizeInKB > 1024) {
124
- console.warn(`Data size (${sizeInKB.toFixed(2)}KB) exceeds 1MB limit for key "${key}"`);
125
- return false;
126
- }
127
-
128
- return true;
129
- } catch (error) {
130
- console.error(`Error checking data size for key "${key}":`, error);
131
- return false;
132
- }
133
- };
134
-
135
- // Clear old data when sessionStorage is full
136
- const clearOldData = () => {
137
- try {
138
- const keys = Object.keys(sessionStorage).filter(k => k && typeof k === 'string');
139
- // Remove oldest items if we have more than 50 items
140
- if (keys.length > 50) {
141
- const itemsToRemove = Math.ceil(keys.length * 0.2);
142
- for (let i = 0; i < itemsToRemove; i++) {
143
- try {
144
- const k = keys[i];
145
- if (k) {
146
- sessionStorage.removeItem(k);
147
- }
148
- } catch {
149
- // Ignore errors when removing items
150
- }
151
- }
152
- }
153
- } catch (error) {
154
- console.error('Error clearing old sessionStorage data:', error);
155
- }
156
- };
157
-
158
- // Force clear all data if quota is exceeded
159
- const forceClearAll = () => {
160
- try {
161
- const keys = Object.keys(sessionStorage);
162
- for (const k of keys) {
163
- try {
164
- sessionStorage.removeItem(k);
165
- } catch {
166
- // Ignore errors when removing items
167
- }
168
- }
169
- } catch (error) {
170
- console.error('Error force clearing sessionStorage:', error);
171
- }
172
- };
173
-
174
- // Prepare data for storage (with or without TTL wrapper)
175
- const prepareForStorage = (value: T): string => {
176
- if (ttl) {
177
- // Wrap with _meta for TTL support
178
- const wrapped: StorageWrapper<T> = {
179
- _meta: {
180
- createdAt: Date.now(),
181
- ttl,
182
- },
183
- _value: value,
184
- };
185
- return JSON.stringify(wrapped);
186
- }
187
- // Old format (no wrapper) - for strings, store directly
188
- if (typeof value === 'string') {
189
- return value;
190
- }
191
- return JSON.stringify(value);
192
- };
193
-
194
- // Update sessionStorage when value changes
195
- const setValue = (value: T | ((val: T) => T)) => {
196
- try {
197
- const valueToStore = value instanceof Function ? value(storedValue) : value;
198
-
199
- // Check data size before attempting to save
200
- if (!checkDataSize(valueToStore)) {
201
- console.warn(`Data size too large for key "${key}", removing key`);
202
- // Remove the key if data is too large
203
- try {
204
- window.sessionStorage.removeItem(key);
205
- } catch {
206
- // Ignore errors when removing
207
- }
208
- // Still update the state
209
- setStoredValue(valueToStore);
210
- return;
211
- }
212
-
213
- setStoredValue(valueToStore);
214
-
215
- if (typeof window !== 'undefined') {
216
- const dataToStore = prepareForStorage(valueToStore);
217
-
218
- // Try to set the value
219
- try {
220
- window.sessionStorage.setItem(key, dataToStore);
221
- } catch (storageError: any) {
222
- // If quota exceeded, clear old data and try again
223
- if (storageError.name === 'QuotaExceededError' ||
224
- storageError.code === 22 ||
225
- storageError.message?.includes('quota')) {
226
- console.warn('sessionStorage quota exceeded, clearing old data...');
227
- clearOldData();
228
-
229
- // Try again after clearing
230
- try {
231
- window.sessionStorage.setItem(key, dataToStore);
232
- } catch (retryError) {
233
- console.error(`Failed to set sessionStorage key "${key}" after clearing old data:`, retryError);
234
- // If still fails, force clear all and try one more time
235
- try {
236
- forceClearAll();
237
- window.sessionStorage.setItem(key, dataToStore);
238
- } catch (finalError) {
239
- console.error(`Failed to set sessionStorage key "${key}" after force clearing:`, finalError);
240
- // If still fails, just update the state without sessionStorage
241
- setStoredValue(valueToStore);
242
- }
243
- }
244
- } else {
245
- throw storageError;
246
- }
247
- }
248
- }
249
- } catch (error) {
250
- console.error(`Error setting sessionStorage key "${key}":`, error);
251
- // Still update the state even if sessionStorage fails
252
- const valueToStore = value instanceof Function ? value(storedValue) : value;
253
- setStoredValue(valueToStore);
254
- }
255
- };
256
-
257
- // Remove value from sessionStorage
258
- const removeValue = () => {
259
- try {
260
- setStoredValue(initialValue);
261
- if (typeof window !== 'undefined') {
262
- try {
263
- window.sessionStorage.removeItem(key);
264
- } catch (removeError: any) {
265
- // If removal fails due to quota, try to clear some data first
266
- if (removeError.name === 'QuotaExceededError' ||
267
- removeError.code === 22 ||
268
- removeError.message?.includes('quota')) {
269
- console.warn('sessionStorage quota exceeded during removal, clearing old data...');
270
- clearOldData();
271
-
272
- try {
273
- window.sessionStorage.removeItem(key);
274
- } catch (retryError) {
275
- console.error(`Failed to remove sessionStorage key "${key}" after clearing:`, retryError);
276
- // If still fails, force clear all
277
- forceClearAll();
278
- }
279
- } else {
280
- throw removeError;
281
- }
282
- }
283
- }
284
- } catch (error) {
285
- console.error(`Error removing sessionStorage key "${key}":`, error);
286
- }
287
- };
288
-
289
- return [storedValue, setValue, removeValue] as const;
290
- }
package/src/lib/index.ts DELETED
@@ -1,5 +0,0 @@
1
- // Re-export from ui-core
2
- export * from '@djangocfg/ui-core/lib';
3
-
4
- // Logger (consola + zustand for Console panel)
5
- export * from './logger';
@@ -1,10 +0,0 @@
1
- /**
2
- * Universal Logger
3
- *
4
- * Combines console logging with zustand store for Console panel.
5
- * Use createMediaLogger for media tools (AudioPlayer, VideoPlayer, ImageViewer).
6
- */
7
-
8
- export { createLogger, createMediaLogger, logger, log } from './logger';
9
- export { useLogStore, useFilteredLogs, useLogCount, useErrorCount } from './logStore';
10
- export type { LogEntry, LogLevel, LogFilter, LogStore, Logger, MediaLogger } from './types';
@@ -1,122 +0,0 @@
1
- /**
2
- * Log Store
3
- *
4
- * Zustand store for log accumulation and filtering.
5
- * Keeps logs in memory for Console panel display.
6
- */
7
-
8
- 'use client';
9
-
10
- import { create } from 'zustand';
11
- import type { LogStore, LogEntry, LogFilter } from './types';
12
-
13
- const DEFAULT_FILTER: LogFilter = {
14
- levels: ['debug', 'info', 'warn', 'error', 'success'],
15
- component: undefined,
16
- search: undefined,
17
- since: undefined,
18
- };
19
-
20
- const MAX_LOGS = 1000;
21
-
22
- function generateId(): string {
23
- return `log-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
24
- }
25
-
26
- function matchesFilter(entry: LogEntry, filter: LogFilter): boolean {
27
- // Level filter
28
- if (!filter.levels.includes(entry.level)) {
29
- return false;
30
- }
31
-
32
- // Component filter (case-insensitive partial match)
33
- if (filter.component) {
34
- const comp = filter.component.toLowerCase();
35
- if (!entry.component.toLowerCase().includes(comp)) {
36
- return false;
37
- }
38
- }
39
-
40
- // Search filter (case-insensitive, searches message and data)
41
- if (filter.search) {
42
- const search = filter.search.toLowerCase();
43
- const inMessage = entry.message.toLowerCase().includes(search);
44
- const inData = entry.data
45
- ? JSON.stringify(entry.data).toLowerCase().includes(search)
46
- : false;
47
- if (!inMessage && !inData) {
48
- return false;
49
- }
50
- }
51
-
52
- // Time filter
53
- if (filter.since && entry.timestamp < filter.since) {
54
- return false;
55
- }
56
-
57
- return true;
58
- }
59
-
60
- export const useLogStore = create<LogStore>((set, get) => ({
61
- logs: [],
62
- filter: DEFAULT_FILTER,
63
- maxLogs: MAX_LOGS,
64
-
65
- addLog: (entry) => {
66
- const newEntry: LogEntry = {
67
- ...entry,
68
- id: generateId(),
69
- timestamp: new Date(),
70
- };
71
-
72
- set((state) => {
73
- const newLogs = [...state.logs, newEntry];
74
- // Trim to max size
75
- if (newLogs.length > state.maxLogs) {
76
- return { logs: newLogs.slice(-state.maxLogs) };
77
- }
78
- return { logs: newLogs };
79
- });
80
- },
81
-
82
- clearLogs: () => {
83
- set({ logs: [] });
84
- },
85
-
86
- setFilter: (filter) => {
87
- set((state) => ({
88
- filter: { ...state.filter, ...filter },
89
- }));
90
- },
91
-
92
- resetFilter: () => {
93
- set({ filter: DEFAULT_FILTER });
94
- },
95
-
96
- getFilteredLogs: () => {
97
- const { logs, filter } = get();
98
- return logs.filter((entry) => matchesFilter(entry, filter));
99
- },
100
-
101
- exportLogs: () => {
102
- const { logs } = get();
103
- return JSON.stringify(logs, null, 2);
104
- },
105
- }));
106
-
107
- // Selector hooks for performance
108
- export const useFilteredLogs = () => {
109
- const logs = useLogStore((state) => state.logs);
110
- const filter = useLogStore((state) => state.filter);
111
- return logs.filter((entry) => matchesFilter(entry, filter));
112
- };
113
-
114
- export const useLogCount = () => {
115
- return useLogStore((state) => state.logs.length);
116
- };
117
-
118
- export const useErrorCount = () => {
119
- return useLogStore((state) =>
120
- state.logs.filter((log) => log.level === 'error').length
121
- );
122
- };
@@ -1,175 +0,0 @@
1
- /**
2
- * Logger
3
- *
4
- * Universal logger with consola + zustand store integration.
5
- * Logs are accumulated for Console panel display.
6
- * In production, only logs to store (no console output).
7
- */
8
-
9
- 'use client';
10
-
11
- import { consola, type ConsolaInstance } from 'consola';
12
- import { useLogStore } from './logStore';
13
- import type { Logger, LogLevel, MediaLogger } from './types';
14
-
15
- // Check environment
16
- const isDev = process.env.NODE_ENV !== 'production';
17
- const isBrowser = typeof window !== 'undefined';
18
-
19
- // Create base consola instance
20
- const baseConsola = consola.create({
21
- level: isDev ? 4 : 2, // 4 = debug, 2 = warn
22
- });
23
-
24
- /**
25
- * Extract error details from unknown error type
26
- */
27
- function extractErrorData(data?: Record<string, unknown>): {
28
- cleanData: Record<string, unknown> | undefined;
29
- stack: string | undefined;
30
- } {
31
- if (!data) return { cleanData: undefined, stack: undefined };
32
-
33
- const cleanData = { ...data };
34
- let stack: string | undefined;
35
-
36
- // Extract stack from error object
37
- if (data.error instanceof Error) {
38
- stack = data.error.stack;
39
- cleanData.error = {
40
- name: data.error.name,
41
- message: data.error.message,
42
- };
43
- } else if (typeof data.error === 'object' && data.error !== null) {
44
- const errObj = data.error as Record<string, unknown>;
45
- if (typeof errObj.stack === 'string') {
46
- stack = errObj.stack;
47
- }
48
- if (typeof errObj.message === 'string') {
49
- cleanData.error = errObj.message;
50
- }
51
- }
52
-
53
- return { cleanData, stack };
54
- }
55
-
56
- /**
57
- * Format buffer ranges for logging
58
- */
59
- function formatBufferRanges(buffered: TimeRanges, duration: number): string {
60
- if (buffered.length === 0) return 'empty';
61
-
62
- const ranges: string[] = [];
63
- for (let i = 0; i < buffered.length; i++) {
64
- const start = buffered.start(i);
65
- const end = buffered.end(i);
66
- const percent = ((end - start) / duration * 100).toFixed(1);
67
- ranges.push(`${start.toFixed(1)}-${end.toFixed(1)}s (${percent}%)`);
68
- }
69
- return ranges.join(', ');
70
- }
71
-
72
- /**
73
- * Create a logger for a specific component/module
74
- */
75
- export function createLogger(component: string): Logger {
76
- const consolaTagged = baseConsola.withTag(component);
77
-
78
- const log = (level: LogLevel, message: string, data?: Record<string, unknown>) => {
79
- const { cleanData, stack } = extractErrorData(data);
80
-
81
- // Add to store (for Console panel)
82
- if (isBrowser) {
83
- useLogStore.getState().addLog({
84
- level,
85
- component,
86
- message,
87
- data: cleanData,
88
- stack,
89
- });
90
- }
91
-
92
- // Log to console via consola (in dev mode)
93
- if (isDev) {
94
- const consolaMethod = level === 'success' ? 'success' : level;
95
- if (cleanData) {
96
- consolaTagged[consolaMethod](message, cleanData);
97
- } else {
98
- consolaTagged[consolaMethod](message);
99
- }
100
- }
101
- };
102
-
103
- return {
104
- debug: (message, data) => log('debug', message, data),
105
- info: (message, data) => log('info', message, data),
106
- warn: (message, data) => log('warn', message, data),
107
- error: (message, data) => log('error', message, data),
108
- success: (message, data) => log('success', message, data),
109
- };
110
- }
111
-
112
- /**
113
- * Create a media-specific logger with helper methods
114
- * for AudioPlayer, VideoPlayer, ImageViewer
115
- */
116
- export function createMediaLogger(component: string): MediaLogger {
117
- const baseLogger = createLogger(component);
118
-
119
- return {
120
- ...baseLogger,
121
-
122
- load: (src: string, type?: string) => {
123
- const typeStr = type ? ` (${type})` : '';
124
- baseLogger.info(`LOAD: ${src}${typeStr}`);
125
- },
126
-
127
- state: (state: string, details?: Record<string, unknown>) => {
128
- baseLogger.debug(`STATE: ${state}`, details);
129
- },
130
-
131
- seek: (from: number, to: number, duration: number) => {
132
- baseLogger.debug(`SEEK: ${from.toFixed(2)}s -> ${to.toFixed(2)}s`, {
133
- from,
134
- to,
135
- duration,
136
- progress: `${((to / duration) * 100).toFixed(1)}%`,
137
- });
138
- },
139
-
140
- buffer: (buffered: TimeRanges, duration: number) => {
141
- if (buffered.length > 0) {
142
- baseLogger.debug(`BUFFER: ${formatBufferRanges(buffered, duration)}`);
143
- }
144
- },
145
-
146
- event: (name: string, data?: unknown) => {
147
- if (data !== undefined) {
148
- baseLogger.debug(`EVENT: ${name}`, { data });
149
- } else {
150
- baseLogger.debug(`EVENT: ${name}`);
151
- }
152
- },
153
- };
154
- }
155
-
156
- /**
157
- * Global logger for non-component code
158
- */
159
- export const logger = createLogger('App');
160
-
161
- /**
162
- * Quick access for one-off logs
163
- */
164
- export const log = {
165
- debug: (component: string, message: string, data?: Record<string, unknown>) =>
166
- createLogger(component).debug(message, data),
167
- info: (component: string, message: string, data?: Record<string, unknown>) =>
168
- createLogger(component).info(message, data),
169
- warn: (component: string, message: string, data?: Record<string, unknown>) =>
170
- createLogger(component).warn(message, data),
171
- error: (component: string, message: string, data?: Record<string, unknown>) =>
172
- createLogger(component).error(message, data),
173
- success: (component: string, message: string, data?: Record<string, unknown>) =>
174
- createLogger(component).success(message, data),
175
- };
@@ -1,82 +0,0 @@
1
- /**
2
- * Logger Types
3
- *
4
- * Type definitions for the universal logging system.
5
- * Compatible with Console panel in FileWorkspace IDE layout.
6
- */
7
-
8
- export type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'success';
9
-
10
- export interface LogEntry {
11
- /** Unique log ID */
12
- id: string;
13
- /** Timestamp when log was created */
14
- timestamp: Date;
15
- /** Log level */
16
- level: LogLevel;
17
- /** Component/module name that created the log */
18
- component: string;
19
- /** Log message */
20
- message: string;
21
- /** Additional data (objects, errors, etc.) */
22
- data?: Record<string, unknown>;
23
- /** Error stack trace (for error level) */
24
- stack?: string;
25
- }
26
-
27
- export interface LogFilter {
28
- /** Filter by log levels */
29
- levels: LogLevel[];
30
- /** Filter by component name (partial match) */
31
- component?: string;
32
- /** Filter by message text (partial match) */
33
- search?: string;
34
- /** Filter by time range */
35
- since?: Date;
36
- }
37
-
38
- export interface LogStore {
39
- /** All accumulated logs */
40
- logs: LogEntry[];
41
- /** Current filter settings */
42
- filter: LogFilter;
43
- /** Maximum logs to keep */
44
- maxLogs: number;
45
-
46
- /** Add new log entry */
47
- addLog: (entry: Omit<LogEntry, 'id' | 'timestamp'>) => void;
48
- /** Clear all logs */
49
- clearLogs: () => void;
50
- /** Update filter settings */
51
- setFilter: (filter: Partial<LogFilter>) => void;
52
- /** Reset filter to defaults */
53
- resetFilter: () => void;
54
- /** Get filtered logs */
55
- getFilteredLogs: () => LogEntry[];
56
- /** Export logs as JSON string */
57
- exportLogs: () => string;
58
- }
59
-
60
- export interface Logger {
61
- debug: (message: string, data?: Record<string, unknown>) => void;
62
- info: (message: string, data?: Record<string, unknown>) => void;
63
- warn: (message: string, data?: Record<string, unknown>) => void;
64
- error: (message: string, data?: Record<string, unknown>) => void;
65
- success: (message: string, data?: Record<string, unknown>) => void;
66
- }
67
-
68
- /**
69
- * Media-specific log helper methods
70
- */
71
- export interface MediaLogger extends Logger {
72
- /** Log source load event */
73
- load: (src: string, type?: string) => void;
74
- /** Log state change */
75
- state: (state: string, details?: Record<string, unknown>) => void;
76
- /** Log seek event */
77
- seek: (from: number, to: number, duration: number) => void;
78
- /** Log buffer ranges */
79
- buffer: (buffered: TimeRanges, duration: number) => void;
80
- /** Log generic event */
81
- event: (name: string, data?: unknown) => void;
82
- }
@@ -1,8 +0,0 @@
1
- export {
2
- useMediaCacheStore,
3
- useImageCache,
4
- useAudioCache,
5
- useVideoCache,
6
- useBlobUrlCleanup,
7
- generateContentKey,
8
- } from './mediaCache';