shimmer-progress.ts 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. import { Worker } from 'worker_threads';
  2. import * as path from 'path';
  3. const PHASE_NAMES: Record<string, string> = {
  4. scanning: 'Scanning files',
  5. parsing: 'Parsing code',
  6. storing: 'Storing data',
  7. finalizing: 'Finalizing',
  8. resolving: 'Resolving refs',
  9. };
  10. export interface IndexProgress {
  11. phase: string;
  12. current: number;
  13. total: number;
  14. }
  15. export interface ShimmerProgress {
  16. onProgress: (progress: IndexProgress) => void;
  17. stop: () => Promise<void>;
  18. }
  19. export function createShimmerProgress(): ShimmerProgress {
  20. let lastPhase = '';
  21. const workerPath = path.join(__dirname, 'shimmer-worker.js');
  22. const worker = new Worker(workerPath, {
  23. workerData: { startTime: Date.now() },
  24. });
  25. return {
  26. onProgress(progress: IndexProgress) {
  27. const phaseName = PHASE_NAMES[progress.phase] || progress.phase;
  28. if (progress.phase !== lastPhase && lastPhase) {
  29. worker.postMessage({ type: 'finish-phase' });
  30. }
  31. lastPhase = progress.phase;
  32. let percent = -1;
  33. let count = 0;
  34. if (progress.total > 0) {
  35. percent = Math.round((progress.current / progress.total) * 100);
  36. } else if (progress.current > 0) {
  37. count = progress.current;
  38. }
  39. worker.postMessage({
  40. type: 'update',
  41. phase: progress.phase,
  42. phaseName,
  43. percent,
  44. count,
  45. });
  46. },
  47. stop() {
  48. return new Promise<void>((resolve) => {
  49. const timeout = setTimeout(() => {
  50. worker.terminate().then(() => resolve());
  51. }, 2000);
  52. worker.on('message', (msg: { type: string }) => {
  53. if (msg.type === 'stopped') {
  54. clearTimeout(timeout);
  55. worker.terminate().then(() => resolve());
  56. }
  57. });
  58. worker.postMessage({ type: 'stop' });
  59. });
  60. },
  61. };
  62. }