@ash-cloud/ash-ui 0.0.1 → 0.0.2

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.
package/dist/index.js CHANGED
@@ -2312,7 +2312,226 @@ var inlineStyles = {
2312
2312
  borderRadius: borderRadius.lg
2313
2313
  }
2314
2314
  };
2315
+ function useMessageQueue({
2316
+ onProcessMessage,
2317
+ canProcess = true
2318
+ }) {
2319
+ const [queue, setQueue] = useState([]);
2320
+ const [isProcessing, setIsProcessing] = useState(false);
2321
+ const isProcessingRef = useRef(false);
2322
+ const onProcessMessageRef = useRef(onProcessMessage);
2323
+ useEffect(() => {
2324
+ onProcessMessageRef.current = onProcessMessage;
2325
+ }, [onProcessMessage]);
2326
+ const processQueue = useCallback(async () => {
2327
+ if (isProcessingRef.current || !canProcess) return;
2328
+ isProcessingRef.current = true;
2329
+ setIsProcessing(true);
2330
+ while (true) {
2331
+ let nextMessage;
2332
+ setQueue((prev) => {
2333
+ if (prev.length === 0) return prev;
2334
+ nextMessage = prev[0];
2335
+ return prev.slice(1);
2336
+ });
2337
+ await new Promise((resolve) => setTimeout(resolve, 0));
2338
+ if (!nextMessage) break;
2339
+ try {
2340
+ await onProcessMessageRef.current(nextMessage);
2341
+ } catch (error) {
2342
+ console.error("Error processing queued message:", error);
2343
+ }
2344
+ }
2345
+ isProcessingRef.current = false;
2346
+ setIsProcessing(false);
2347
+ }, [canProcess]);
2348
+ useEffect(() => {
2349
+ if (queue.length > 0 && !isProcessingRef.current && canProcess) {
2350
+ processQueue();
2351
+ }
2352
+ }, [queue, processQueue, canProcess]);
2353
+ const enqueue = useCallback((text, files) => {
2354
+ const message = {
2355
+ id: `queue-${Date.now()}-${Math.random().toString(36).slice(2)}`,
2356
+ text,
2357
+ files,
2358
+ queuedAt: Date.now()
2359
+ };
2360
+ setQueue((prev) => [...prev, message]);
2361
+ }, []);
2362
+ const cancel = useCallback((id) => {
2363
+ setQueue((prev) => prev.filter((m) => m.id !== id));
2364
+ }, []);
2365
+ const clearQueue = useCallback(() => {
2366
+ setQueue([]);
2367
+ }, []);
2368
+ return {
2369
+ queue,
2370
+ isProcessing,
2371
+ enqueue,
2372
+ cancel,
2373
+ clearQueue,
2374
+ queueLength: queue.length
2375
+ };
2376
+ }
2377
+ function useStopExecution({
2378
+ onServerStop
2379
+ } = {}) {
2380
+ const [canStop, setCanStop] = useState(false);
2381
+ const abortControllerRef = useRef(null);
2382
+ const sessionIdRef = useRef(null);
2383
+ const onServerStopRef = useRef(onServerStop);
2384
+ onServerStopRef.current = onServerStop;
2385
+ const startExecution = useCallback(() => {
2386
+ abortControllerRef.current = new AbortController();
2387
+ setCanStop(true);
2388
+ }, []);
2389
+ const endExecution = useCallback(() => {
2390
+ abortControllerRef.current = null;
2391
+ sessionIdRef.current = null;
2392
+ setCanStop(false);
2393
+ }, []);
2394
+ const setSessionId = useCallback((sessionId) => {
2395
+ sessionIdRef.current = sessionId;
2396
+ }, []);
2397
+ const stop = useCallback(async (explicitSessionId) => {
2398
+ if (abortControllerRef.current) {
2399
+ abortControllerRef.current.abort();
2400
+ }
2401
+ const sessionId = explicitSessionId || sessionIdRef.current;
2402
+ if (sessionId && onServerStopRef.current) {
2403
+ try {
2404
+ await onServerStopRef.current(sessionId);
2405
+ } catch (err) {
2406
+ console.warn("Server stop failed:", err);
2407
+ }
2408
+ }
2409
+ setCanStop(false);
2410
+ }, []);
2411
+ return {
2412
+ canStop,
2413
+ signal: abortControllerRef.current?.signal,
2414
+ startExecution,
2415
+ endExecution,
2416
+ stop,
2417
+ setSessionId
2418
+ };
2419
+ }
2420
+ function formatFileSize2(bytes) {
2421
+ if (bytes < 1024) return `${bytes} B`;
2422
+ if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
2423
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
2424
+ }
2425
+ async function readFileAsBase64(file) {
2426
+ return new Promise((resolve, reject) => {
2427
+ const reader = new FileReader();
2428
+ reader.onload = () => {
2429
+ const result = reader.result;
2430
+ const base64 = result.split(",")[1];
2431
+ resolve(base64 || "");
2432
+ };
2433
+ reader.onerror = () => reject(reader.error);
2434
+ reader.readAsDataURL(file);
2435
+ });
2436
+ }
2437
+ function useFileUpload({
2438
+ maxFileSize = 100 * 1024 * 1024,
2439
+ // 100MB
2440
+ maxFiles = 10,
2441
+ onValidationError
2442
+ } = {}) {
2443
+ const [files, setFiles] = useState([]);
2444
+ const [isDragOver, setIsDragOver] = useState(false);
2445
+ const fileInputRef = useRef(null);
2446
+ const addFiles = useCallback(
2447
+ async (fileList) => {
2448
+ if (!fileList) return;
2449
+ const newFiles = [];
2450
+ const currentCount = files.length;
2451
+ for (let i = 0; i < fileList.length && currentCount + newFiles.length < maxFiles; i++) {
2452
+ const file = fileList.item(i);
2453
+ if (!file) continue;
2454
+ if (file.size > maxFileSize) {
2455
+ onValidationError?.(
2456
+ file.name,
2457
+ `Exceeds maximum size of ${formatFileSize2(maxFileSize)}`
2458
+ );
2459
+ continue;
2460
+ }
2461
+ try {
2462
+ const content = await readFileAsBase64(file);
2463
+ newFiles.push({
2464
+ filename: file.name,
2465
+ content,
2466
+ mimeType: file.type || "application/octet-stream",
2467
+ size: file.size
2468
+ });
2469
+ } catch (error) {
2470
+ console.error(`Failed to read file ${file.name}:`, error);
2471
+ onValidationError?.(file.name, "Failed to read file");
2472
+ }
2473
+ }
2474
+ if (fileList.length > maxFiles - currentCount && currentCount + newFiles.length >= maxFiles) {
2475
+ onValidationError?.("", `Maximum ${maxFiles} files allowed`);
2476
+ }
2477
+ if (newFiles.length > 0) {
2478
+ setFiles((prev) => [...prev, ...newFiles]);
2479
+ }
2480
+ },
2481
+ [files.length, maxFiles, maxFileSize, onValidationError]
2482
+ );
2483
+ const removeFile = useCallback((index) => {
2484
+ setFiles((prev) => prev.filter((_, i) => i !== index));
2485
+ }, []);
2486
+ const clearFiles = useCallback(() => {
2487
+ setFiles([]);
2488
+ }, []);
2489
+ const handleDragOver = useCallback((e) => {
2490
+ e.preventDefault();
2491
+ setIsDragOver(true);
2492
+ }, []);
2493
+ const handleDragLeave = useCallback((e) => {
2494
+ e.preventDefault();
2495
+ setIsDragOver(false);
2496
+ }, []);
2497
+ const handleDrop = useCallback(
2498
+ (e) => {
2499
+ e.preventDefault();
2500
+ setIsDragOver(false);
2501
+ addFiles(e.dataTransfer.files);
2502
+ },
2503
+ [addFiles]
2504
+ );
2505
+ const handleFileInputChange = useCallback(
2506
+ (e) => {
2507
+ addFiles(e.target.files);
2508
+ if (fileInputRef.current) {
2509
+ fileInputRef.current.value = "";
2510
+ }
2511
+ },
2512
+ [addFiles]
2513
+ );
2514
+ const openFilePicker = useCallback(() => {
2515
+ fileInputRef.current?.click();
2516
+ }, []);
2517
+ return {
2518
+ files,
2519
+ isDragOver,
2520
+ addFiles,
2521
+ removeFile,
2522
+ clearFiles,
2523
+ canAddMore: files.length < maxFiles,
2524
+ dropZoneProps: {
2525
+ onDragOver: handleDragOver,
2526
+ onDragLeave: handleDragLeave,
2527
+ onDrop: handleDrop
2528
+ },
2529
+ handleFileInputChange,
2530
+ fileInputRef,
2531
+ openFilePicker
2532
+ };
2533
+ }
2315
2534
 
2316
- export { ActionIcon, AlertCircleIcon, AlertTriangleIcon, AssistantMessage, BotIcon, BrainIcon, BugIcon, CheckCircleIcon, CheckIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, CircleIcon, ClipboardListIcon, CodeBlock, CodeIcon, CompactToolStatusLine, CopyIcon, DEFAULT_DISPLAY_CONFIG, DisplayModeProvider, EditIcon, ErrorMessage, FileIcon, FilePlusIcon, FolderSearchIcon, GlobeIcon, InfoIcon, JsonDisplay, ListChecksIcon, LoaderIcon, LoadingIndicator, LogsPanel, MessageEntry, MessageList, MessageSquareIcon, MoonIcon, OptionCards, PaperclipIcon, PlugIcon, SearchIcon, SendIcon, SparklesIcon, StatusIndicator, StopCircleIcon, StreamingText, SunIcon, TerminalIcon, ThemeProvider, ThinkingMessage, TodoPanel, ToolCallCard, ToolCallMessage, ToolExecutionGroup, ToolIcon, TypewriterText, UserIcon, UserMessage, XCircleIcon, XIcon, allKeyframesCss, borderRadius, cn, colors, createToolCall, extractTextContent, extractToolCallsFromGroup, formatFileSize, formatTimestamp, formatToolName, generateToolSummary, getActionIcon, getActionLabel, groupEntriesForCompactMode, inlineStyles, isCommandRunAction, isErrorEntry, isFileEditAction, isFileReadAction, isFileWriteAction, isGenericToolAction, isGlobAction, isMcpToolAction, isSearchAction, isTodoWriteAction, isToolCallEntry, isWebFetchAction, isWebSearchAction, keyframes, keyframesCss, mapToolToActionType, normalizeToolResult, parseCommandResult, parseMcpToolName, parseOptionsFromContent, shadows, spacing, tokensToCssVariables, transitions, truncate, typography, updateToolCallWithResult, useDisplayConfig, useDisplayMode, useTheme, widget, zIndex };
2535
+ export { ActionIcon, AlertCircleIcon, AlertTriangleIcon, AssistantMessage, BotIcon, BrainIcon, BugIcon, CheckCircleIcon, CheckIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, CircleIcon, ClipboardListIcon, CodeBlock, CodeIcon, CompactToolStatusLine, CopyIcon, DEFAULT_DISPLAY_CONFIG, DisplayModeProvider, EditIcon, ErrorMessage, FileIcon, FilePlusIcon, FolderSearchIcon, GlobeIcon, InfoIcon, JsonDisplay, ListChecksIcon, LoaderIcon, LoadingIndicator, LogsPanel, MessageEntry, MessageList, MessageSquareIcon, MoonIcon, OptionCards, PaperclipIcon, PlugIcon, SearchIcon, SendIcon, SparklesIcon, StatusIndicator, StopCircleIcon, StreamingText, SunIcon, TerminalIcon, ThemeProvider, ThinkingMessage, TodoPanel, ToolCallCard, ToolCallMessage, ToolExecutionGroup, ToolIcon, TypewriterText, UserIcon, UserMessage, XCircleIcon, XIcon, allKeyframesCss, borderRadius, cn, colors, createToolCall, extractTextContent, extractToolCallsFromGroup, formatFileSize, formatTimestamp, formatToolName, generateToolSummary, getActionIcon, getActionLabel, groupEntriesForCompactMode, inlineStyles, isCommandRunAction, isErrorEntry, isFileEditAction, isFileReadAction, isFileWriteAction, isGenericToolAction, isGlobAction, isMcpToolAction, isSearchAction, isTodoWriteAction, isToolCallEntry, isWebFetchAction, isWebSearchAction, keyframes, keyframesCss, mapToolToActionType, normalizeToolResult, parseCommandResult, parseMcpToolName, parseOptionsFromContent, shadows, spacing, tokensToCssVariables, transitions, truncate, typography, updateToolCallWithResult, useDisplayConfig, useDisplayMode, useFileUpload, useMessageQueue, useStopExecution, useTheme, widget, zIndex };
2317
2536
  //# sourceMappingURL=index.js.map
2318
2537
  //# sourceMappingURL=index.js.map