uilint-react 0.1.32 → 0.1.33
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/{ElementBadges-IQIPOHBN.js → ElementBadges-TBAUB3KM.js} +1 -1
- package/dist/{InspectionPanel-AU4SJPQN.js → InspectionPanel-JNLWBL4D.js} +2 -2
- package/dist/{LocatorOverlay-XCNSUM34.js → LocatorOverlay-6SAH7LN2.js} +2 -2
- package/dist/{UILintToolbar-PRX3LYZD.js → UILintToolbar-WNV5RS2L.js} +2 -2
- package/dist/{chunk-K7SUEWNV.js → chunk-HTNIKCEM.js} +219 -2
- package/dist/{chunk-NY7Q5DSG.js → chunk-JBBUE3Y5.js} +55 -712
- package/dist/{chunk-Y44J7QO6.js → chunk-MO4NS6EG.js} +146 -118
- package/dist/{chunk-VBU72FKU.js → chunk-Z6PWYQGW.js} +1 -1
- package/dist/index.d.ts +3 -55
- package/dist/index.js +4 -51
- package/package.json +2 -2
|
@@ -272,53 +272,25 @@ function getDataLocFromId(id) {
|
|
|
272
272
|
}
|
|
273
273
|
async function scanFileForIssues(sourceFile, store) {
|
|
274
274
|
if (sourceFile.elements.length === 0) {
|
|
275
|
-
return { issues: []
|
|
275
|
+
return { issues: [] };
|
|
276
276
|
}
|
|
277
277
|
const filePath = sourceFile.path;
|
|
278
|
-
let
|
|
279
|
-
let llmIssues = [];
|
|
278
|
+
let issues = [];
|
|
280
279
|
if (store.wsConnected && store.wsConnection) {
|
|
281
280
|
try {
|
|
282
|
-
|
|
281
|
+
issues = await store.requestFileLint(filePath);
|
|
282
|
+
console.log("[UILint] ESLint issues:", issues);
|
|
283
283
|
} catch (err) {
|
|
284
|
-
console.warn("[UILint] WebSocket lint failed
|
|
284
|
+
console.warn("[UILint] WebSocket lint failed:", err);
|
|
285
|
+
return { issues: [], error: true };
|
|
285
286
|
}
|
|
287
|
+
} else {
|
|
288
|
+
console.warn("[UILint] WebSocket not connected");
|
|
289
|
+
return { issues: [], error: true };
|
|
286
290
|
}
|
|
287
|
-
|
|
288
|
-
const sourceResponse = await fetch(
|
|
289
|
-
`/api/.uilint/source?path=${encodeURIComponent(filePath)}`
|
|
290
|
-
);
|
|
291
|
-
if (!sourceResponse.ok) {
|
|
292
|
-
return { issues: [], eslintIssues, error: true };
|
|
293
|
-
}
|
|
294
|
-
const sourceData = await sourceResponse.json();
|
|
295
|
-
const dataLocs = [];
|
|
296
|
-
for (const el of sourceFile.elements) {
|
|
297
|
-
const dataLoc = getDataLocFromId(el.id);
|
|
298
|
-
if (dataLoc) {
|
|
299
|
-
dataLocs.push(dataLoc);
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
const analyzeResponse = await fetch("/api/.uilint/analyze", {
|
|
303
|
-
method: "POST",
|
|
304
|
-
headers: { "Content-Type": "application/json" },
|
|
305
|
-
body: JSON.stringify({
|
|
306
|
-
sourceCode: sourceData.content,
|
|
307
|
-
filePath: sourceData.relativePath || filePath,
|
|
308
|
-
dataLocs
|
|
309
|
-
})
|
|
310
|
-
});
|
|
311
|
-
if (!analyzeResponse.ok) {
|
|
312
|
-
return { issues: [], eslintIssues, error: true };
|
|
313
|
-
}
|
|
314
|
-
const result = await analyzeResponse.json();
|
|
315
|
-
llmIssues = result.issues || [];
|
|
316
|
-
} catch {
|
|
317
|
-
return { issues: [], eslintIssues, error: true };
|
|
318
|
-
}
|
|
319
|
-
return { issues: llmIssues, eslintIssues };
|
|
291
|
+
return { issues };
|
|
320
292
|
}
|
|
321
|
-
function distributeIssuesToElements(issues,
|
|
293
|
+
function distributeIssuesToElements(issues, elements, updateElementIssue, hasError) {
|
|
322
294
|
const dataLocToElementId = /* @__PURE__ */ new Map();
|
|
323
295
|
for (const el of elements) {
|
|
324
296
|
const dataLoc = getDataLocFromId(el.id);
|
|
@@ -337,24 +309,11 @@ function distributeIssuesToElements(issues, eslintIssues, elements, updateElemen
|
|
|
337
309
|
}
|
|
338
310
|
}
|
|
339
311
|
}
|
|
340
|
-
const eslintByElement = /* @__PURE__ */ new Map();
|
|
341
|
-
for (const issue of eslintIssues) {
|
|
342
|
-
if (issue.dataLoc) {
|
|
343
|
-
const elementId = dataLocToElementId.get(issue.dataLoc);
|
|
344
|
-
if (elementId) {
|
|
345
|
-
const existing = eslintByElement.get(elementId) || [];
|
|
346
|
-
existing.push(issue);
|
|
347
|
-
eslintByElement.set(elementId, existing);
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
312
|
for (const el of elements) {
|
|
352
313
|
const elementIssues = issuesByElement.get(el.id) || [];
|
|
353
|
-
const elementEslintIssues = eslintByElement.get(el.id) || [];
|
|
354
314
|
updateElementIssue(el.id, {
|
|
355
315
|
elementId: el.id,
|
|
356
316
|
issues: elementIssues,
|
|
357
|
-
eslintIssues: elementEslintIssues,
|
|
358
317
|
status: hasError ? "error" : "complete"
|
|
359
318
|
});
|
|
360
319
|
}
|
|
@@ -363,6 +322,15 @@ var DEFAULT_WS_URL = "ws://localhost:9234";
|
|
|
363
322
|
var MAX_RECONNECT_ATTEMPTS = 5;
|
|
364
323
|
var RECONNECT_BASE_DELAY = 1e3;
|
|
365
324
|
var pendingRequests = /* @__PURE__ */ new Map();
|
|
325
|
+
var WS_REQUEST_TIMEOUT_MS = 12e4;
|
|
326
|
+
function makeRequestId() {
|
|
327
|
+
try {
|
|
328
|
+
const c = globalThis.crypto;
|
|
329
|
+
if (c?.randomUUID) return c.randomUUID();
|
|
330
|
+
} catch {
|
|
331
|
+
}
|
|
332
|
+
return `req_${Date.now()}_${Math.random().toString(16).slice(2)}`;
|
|
333
|
+
}
|
|
366
334
|
var useUILintStore = create()((set, get) => ({
|
|
367
335
|
// ============ Settings ============
|
|
368
336
|
settings: DEFAULT_SETTINGS,
|
|
@@ -389,31 +357,6 @@ var useUILintStore = create()((set, get) => ({
|
|
|
389
357
|
// ============ Inspection ============
|
|
390
358
|
inspectedElement: null,
|
|
391
359
|
setInspectedElement: (el) => set({ inspectedElement: el }),
|
|
392
|
-
// ============ Manual Scan (InspectionPanel) ============
|
|
393
|
-
manualScanCache: /* @__PURE__ */ new Map(),
|
|
394
|
-
upsertManualScan: (key, patch) => set((state) => {
|
|
395
|
-
const next = new Map(state.manualScanCache);
|
|
396
|
-
const existing = next.get(key);
|
|
397
|
-
const base = existing ?? {
|
|
398
|
-
key,
|
|
399
|
-
status: "idle",
|
|
400
|
-
issues: [],
|
|
401
|
-
updatedAt: Date.now()
|
|
402
|
-
};
|
|
403
|
-
next.set(key, {
|
|
404
|
-
...base,
|
|
405
|
-
...patch,
|
|
406
|
-
key,
|
|
407
|
-
updatedAt: Date.now()
|
|
408
|
-
});
|
|
409
|
-
return { manualScanCache: next };
|
|
410
|
-
}),
|
|
411
|
-
clearManualScan: (key) => set((state) => {
|
|
412
|
-
if (!state.manualScanCache.has(key)) return state;
|
|
413
|
-
const next = new Map(state.manualScanCache);
|
|
414
|
-
next.delete(key);
|
|
415
|
-
return { manualScanCache: next };
|
|
416
|
-
}),
|
|
417
360
|
// ============ Auto-Scan ============
|
|
418
361
|
autoScanState: DEFAULT_AUTO_SCAN_STATE,
|
|
419
362
|
elementIssuesCache: /* @__PURE__ */ new Map(),
|
|
@@ -519,14 +462,16 @@ var useUILintStore = create()((set, get) => ({
|
|
|
519
462
|
});
|
|
520
463
|
}
|
|
521
464
|
await new Promise((resolve) => requestAnimationFrame(resolve));
|
|
522
|
-
const { issues,
|
|
465
|
+
const { issues, error } = await scanFileForIssues(sourceFile, get());
|
|
523
466
|
distributeIssuesToElements(
|
|
524
467
|
issues,
|
|
525
|
-
eslintIssues,
|
|
526
468
|
sourceFile.elements,
|
|
527
469
|
get().updateElementIssue,
|
|
528
470
|
error ?? false
|
|
529
471
|
);
|
|
472
|
+
if (get().wsConnected && get().wsConnection) {
|
|
473
|
+
get().subscribeToFile(sourceFile.path);
|
|
474
|
+
}
|
|
530
475
|
processedElements += sourceFile.elements.length;
|
|
531
476
|
await new Promise((resolve) => requestAnimationFrame(resolve));
|
|
532
477
|
}
|
|
@@ -546,6 +491,8 @@ var useUILintStore = create()((set, get) => ({
|
|
|
546
491
|
wsReconnectAttempts: 0,
|
|
547
492
|
eslintIssuesCache: /* @__PURE__ */ new Map(),
|
|
548
493
|
wsProgressPhase: /* @__PURE__ */ new Map(),
|
|
494
|
+
wsLastActivity: null,
|
|
495
|
+
wsRecentResults: [],
|
|
549
496
|
connectWebSocket: (url) => {
|
|
550
497
|
const targetUrl = url || get().wsUrl;
|
|
551
498
|
const existing = get().wsConnection;
|
|
@@ -572,7 +519,9 @@ var useUILintStore = create()((set, get) => ({
|
|
|
572
519
|
const attempts = get().wsReconnectAttempts;
|
|
573
520
|
if (attempts < MAX_RECONNECT_ATTEMPTS) {
|
|
574
521
|
const delay = RECONNECT_BASE_DELAY * Math.pow(2, attempts);
|
|
575
|
-
console.log(
|
|
522
|
+
console.log(
|
|
523
|
+
`[UILint] Reconnecting in ${delay}ms (attempt ${attempts + 1})`
|
|
524
|
+
);
|
|
576
525
|
setTimeout(() => {
|
|
577
526
|
set({ wsReconnectAttempts: attempts + 1 });
|
|
578
527
|
get()._reconnectWebSocket();
|
|
@@ -599,13 +548,18 @@ var useUILintStore = create()((set, get) => ({
|
|
|
599
548
|
const ws = get().wsConnection;
|
|
600
549
|
if (ws) {
|
|
601
550
|
ws.close();
|
|
602
|
-
set({
|
|
551
|
+
set({
|
|
552
|
+
wsConnection: null,
|
|
553
|
+
wsConnected: false,
|
|
554
|
+
wsReconnectAttempts: MAX_RECONNECT_ATTEMPTS
|
|
555
|
+
});
|
|
603
556
|
}
|
|
604
557
|
},
|
|
605
558
|
requestFileLint: async (filePath) => {
|
|
606
559
|
const { wsConnection, wsConnected, eslintIssuesCache } = get();
|
|
607
560
|
const cached = eslintIssuesCache.get(filePath);
|
|
608
561
|
if (cached) {
|
|
562
|
+
console.log("[UILint] using cached issues for", filePath);
|
|
609
563
|
return cached;
|
|
610
564
|
}
|
|
611
565
|
if (!wsConnected || !wsConnection) {
|
|
@@ -613,16 +567,20 @@ var useUILintStore = create()((set, get) => ({
|
|
|
613
567
|
return [];
|
|
614
568
|
}
|
|
615
569
|
return new Promise((resolve, reject) => {
|
|
616
|
-
const
|
|
617
|
-
pendingRequests.set(
|
|
618
|
-
const message = {
|
|
570
|
+
const requestId = makeRequestId();
|
|
571
|
+
pendingRequests.set(requestId, { resolve, reject });
|
|
572
|
+
const message = {
|
|
573
|
+
type: "lint:file",
|
|
574
|
+
filePath,
|
|
575
|
+
requestId
|
|
576
|
+
};
|
|
619
577
|
wsConnection.send(JSON.stringify(message));
|
|
620
578
|
setTimeout(() => {
|
|
621
|
-
if (pendingRequests.has(
|
|
622
|
-
pendingRequests.delete(
|
|
579
|
+
if (pendingRequests.has(requestId)) {
|
|
580
|
+
pendingRequests.delete(requestId);
|
|
623
581
|
reject(new Error("Request timed out"));
|
|
624
582
|
}
|
|
625
|
-
},
|
|
583
|
+
}, WS_REQUEST_TIMEOUT_MS);
|
|
626
584
|
});
|
|
627
585
|
},
|
|
628
586
|
requestElementLint: async (filePath, dataLoc) => {
|
|
@@ -632,16 +590,21 @@ var useUILintStore = create()((set, get) => ({
|
|
|
632
590
|
return [];
|
|
633
591
|
}
|
|
634
592
|
return new Promise((resolve, reject) => {
|
|
635
|
-
const
|
|
636
|
-
pendingRequests.set(
|
|
637
|
-
const message = {
|
|
593
|
+
const requestId = makeRequestId();
|
|
594
|
+
pendingRequests.set(requestId, { resolve, reject });
|
|
595
|
+
const message = {
|
|
596
|
+
type: "lint:element",
|
|
597
|
+
filePath,
|
|
598
|
+
dataLoc,
|
|
599
|
+
requestId
|
|
600
|
+
};
|
|
638
601
|
wsConnection.send(JSON.stringify(message));
|
|
639
602
|
setTimeout(() => {
|
|
640
|
-
if (pendingRequests.has(
|
|
641
|
-
pendingRequests.delete(
|
|
603
|
+
if (pendingRequests.has(requestId)) {
|
|
604
|
+
pendingRequests.delete(requestId);
|
|
642
605
|
reject(new Error("Request timed out"));
|
|
643
606
|
}
|
|
644
|
-
},
|
|
607
|
+
}, WS_REQUEST_TIMEOUT_MS);
|
|
645
608
|
});
|
|
646
609
|
},
|
|
647
610
|
subscribeToFile: (filePath) => {
|
|
@@ -662,36 +625,59 @@ var useUILintStore = create()((set, get) => ({
|
|
|
662
625
|
set({ eslintIssuesCache: /* @__PURE__ */ new Map() });
|
|
663
626
|
}
|
|
664
627
|
if (wsConnected && wsConnection) {
|
|
665
|
-
const message = {
|
|
628
|
+
const message = {
|
|
629
|
+
type: "cache:invalidate",
|
|
630
|
+
filePath
|
|
631
|
+
};
|
|
666
632
|
wsConnection.send(JSON.stringify(message));
|
|
667
633
|
}
|
|
668
634
|
},
|
|
669
635
|
_handleWsMessage: (data) => {
|
|
670
636
|
switch (data.type) {
|
|
671
637
|
case "lint:result": {
|
|
672
|
-
const { filePath, issues } = data;
|
|
673
|
-
set((
|
|
674
|
-
const next = new Map(
|
|
638
|
+
const { filePath, issues, requestId } = data;
|
|
639
|
+
set((state2) => {
|
|
640
|
+
const next = new Map(state2.eslintIssuesCache);
|
|
675
641
|
next.set(filePath, issues);
|
|
676
642
|
return { eslintIssuesCache: next };
|
|
677
643
|
});
|
|
678
|
-
|
|
679
|
-
|
|
644
|
+
const state = get();
|
|
645
|
+
if (state.autoScanState.status !== "idle") {
|
|
646
|
+
const sourceFiles = groupBySourceFile(state.autoScanState.elements);
|
|
647
|
+
const sf = sourceFiles.find((s) => s.path === filePath);
|
|
648
|
+
if (sf) {
|
|
649
|
+
distributeIssuesToElements(
|
|
650
|
+
issues,
|
|
651
|
+
sf.elements,
|
|
652
|
+
state.updateElementIssue,
|
|
653
|
+
false
|
|
654
|
+
);
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
set((state2) => {
|
|
658
|
+
const next = new Map(state2.wsProgressPhase);
|
|
680
659
|
next.delete(filePath);
|
|
681
660
|
return { wsProgressPhase: next };
|
|
682
661
|
});
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
662
|
+
set((state2) => {
|
|
663
|
+
const next = [
|
|
664
|
+
{ filePath, issueCount: issues.length, updatedAt: Date.now() },
|
|
665
|
+
...state2.wsRecentResults.filter((r) => r.filePath !== filePath)
|
|
666
|
+
].slice(0, 8);
|
|
667
|
+
return { wsRecentResults: next };
|
|
668
|
+
});
|
|
669
|
+
set({
|
|
670
|
+
wsLastActivity: {
|
|
671
|
+
filePath,
|
|
672
|
+
phase: `Done (${issues.length} issues)`,
|
|
673
|
+
updatedAt: Date.now()
|
|
674
|
+
}
|
|
675
|
+
});
|
|
676
|
+
if (requestId) {
|
|
677
|
+
const pending = pendingRequests.get(requestId);
|
|
678
|
+
if (pending) {
|
|
679
|
+
pending.resolve(issues);
|
|
680
|
+
pendingRequests.delete(requestId);
|
|
695
681
|
}
|
|
696
682
|
}
|
|
697
683
|
break;
|
|
@@ -701,17 +687,45 @@ var useUILintStore = create()((set, get) => ({
|
|
|
701
687
|
set((state) => {
|
|
702
688
|
const next = new Map(state.wsProgressPhase);
|
|
703
689
|
next.set(filePath, phase);
|
|
704
|
-
return {
|
|
690
|
+
return {
|
|
691
|
+
wsProgressPhase: next,
|
|
692
|
+
wsLastActivity: { filePath, phase, updatedAt: Date.now() }
|
|
693
|
+
};
|
|
705
694
|
});
|
|
706
695
|
break;
|
|
707
696
|
}
|
|
708
697
|
case "file:changed": {
|
|
709
698
|
const { filePath } = data;
|
|
710
|
-
set((
|
|
711
|
-
const next = new Map(
|
|
699
|
+
set((state2) => {
|
|
700
|
+
const next = new Map(state2.eslintIssuesCache);
|
|
712
701
|
next.delete(filePath);
|
|
713
702
|
return { eslintIssuesCache: next };
|
|
714
703
|
});
|
|
704
|
+
const state = get();
|
|
705
|
+
if (state.autoScanState.status !== "idle") {
|
|
706
|
+
const sourceFiles = groupBySourceFile(state.autoScanState.elements);
|
|
707
|
+
const sf = sourceFiles.find((s) => s.path === filePath);
|
|
708
|
+
if (sf) {
|
|
709
|
+
for (const el of sf.elements) {
|
|
710
|
+
const existing = state.elementIssuesCache.get(el.id);
|
|
711
|
+
state.updateElementIssue(el.id, {
|
|
712
|
+
elementId: el.id,
|
|
713
|
+
issues: existing?.issues || [],
|
|
714
|
+
status: "scanning"
|
|
715
|
+
});
|
|
716
|
+
}
|
|
717
|
+
state.requestFileLint(filePath).catch(() => {
|
|
718
|
+
for (const el of sf.elements) {
|
|
719
|
+
const existing = state.elementIssuesCache.get(el.id);
|
|
720
|
+
state.updateElementIssue(el.id, {
|
|
721
|
+
elementId: el.id,
|
|
722
|
+
issues: existing?.issues || [],
|
|
723
|
+
status: "error"
|
|
724
|
+
});
|
|
725
|
+
}
|
|
726
|
+
});
|
|
727
|
+
}
|
|
728
|
+
}
|
|
715
729
|
break;
|
|
716
730
|
}
|
|
717
731
|
}
|
|
@@ -788,6 +802,12 @@ function UILintProvider({
|
|
|
788
802
|
const pauseAutoScan = useUILintStore((s) => s.pauseAutoScan);
|
|
789
803
|
const resumeAutoScan = useUILintStore((s) => s.resumeAutoScan);
|
|
790
804
|
const stopAutoScan = useUILintStore((s) => s.stopAutoScan);
|
|
805
|
+
const connectWebSocket = useUILintStore(
|
|
806
|
+
(s) => s.connectWebSocket
|
|
807
|
+
);
|
|
808
|
+
const disconnectWebSocket = useUILintStore(
|
|
809
|
+
(s) => s.disconnectWebSocket
|
|
810
|
+
);
|
|
791
811
|
const effectiveLocatorTarget = useEffectiveLocatorTarget();
|
|
792
812
|
const getLocatorTargetFromElement = useCallback(
|
|
793
813
|
(element) => {
|
|
@@ -957,6 +977,14 @@ function UILintProvider({
|
|
|
957
977
|
useEffect(() => {
|
|
958
978
|
setIsMounted(true);
|
|
959
979
|
}, []);
|
|
980
|
+
useEffect(() => {
|
|
981
|
+
if (!isBrowser() || !enabled) return;
|
|
982
|
+
if (!isMounted) return;
|
|
983
|
+
connectWebSocket();
|
|
984
|
+
return () => {
|
|
985
|
+
disconnectWebSocket();
|
|
986
|
+
};
|
|
987
|
+
}, [enabled, isMounted, connectWebSocket, disconnectWebSocket]);
|
|
960
988
|
const wrappedStartAutoScan = useCallback(() => {
|
|
961
989
|
startAutoScan(settings.hideNodeModules);
|
|
962
990
|
}, [startAutoScan, settings.hideNodeModules]);
|
|
@@ -1005,10 +1033,10 @@ function UILintUI() {
|
|
|
1005
1033
|
const [components, setComponents] = useState(null);
|
|
1006
1034
|
useEffect(() => {
|
|
1007
1035
|
Promise.all([
|
|
1008
|
-
import("./UILintToolbar-
|
|
1009
|
-
import("./InspectionPanel-
|
|
1010
|
-
import("./LocatorOverlay-
|
|
1011
|
-
import("./ElementBadges-
|
|
1036
|
+
import("./UILintToolbar-WNV5RS2L.js"),
|
|
1037
|
+
import("./InspectionPanel-JNLWBL4D.js"),
|
|
1038
|
+
import("./LocatorOverlay-6SAH7LN2.js"),
|
|
1039
|
+
import("./ElementBadges-TBAUB3KM.js")
|
|
1012
1040
|
]).then(([toolbar, panel, locator, badges]) => {
|
|
1013
1041
|
setComponents({
|
|
1014
1042
|
Toolbar: toolbar.UILintToolbar,
|
package/dist/index.d.ts
CHANGED
|
@@ -58,17 +58,6 @@ interface AutoScanState {
|
|
|
58
58
|
totalElements: number;
|
|
59
59
|
elements: ScannedElement[];
|
|
60
60
|
}
|
|
61
|
-
/**
|
|
62
|
-
* A single issue found during scanning
|
|
63
|
-
*/
|
|
64
|
-
interface ScanIssue {
|
|
65
|
-
/** Line number in source file */
|
|
66
|
-
line?: number;
|
|
67
|
-
/** Issue description */
|
|
68
|
-
message: string;
|
|
69
|
-
/** data-loc value to match to DOM element (format: path:line:column) */
|
|
70
|
-
dataLoc?: string;
|
|
71
|
-
}
|
|
72
61
|
/**
|
|
73
62
|
* ESLint issue from WebSocket server (uilint serve)
|
|
74
63
|
*/
|
|
@@ -89,10 +78,8 @@ interface ESLintIssue {
|
|
|
89
78
|
*/
|
|
90
79
|
interface ElementIssue {
|
|
91
80
|
elementId: string;
|
|
92
|
-
/**
|
|
93
|
-
issues:
|
|
94
|
-
/** ESLint rule violations from uilint-eslint */
|
|
95
|
-
eslintIssues?: ESLintIssue[];
|
|
81
|
+
/** ESLint rule violations from uilint-eslint (including semantic rule) */
|
|
82
|
+
issues: ESLintIssue[];
|
|
96
83
|
status: "pending" | "scanning" | "complete" | "error";
|
|
97
84
|
}
|
|
98
85
|
/**
|
|
@@ -379,43 +366,4 @@ declare function isJSDOM(): boolean;
|
|
|
379
366
|
*/
|
|
380
367
|
declare function isNode(): boolean;
|
|
381
368
|
|
|
382
|
-
|
|
383
|
-
* LLM client for browser environment
|
|
384
|
-
* Wraps API calls to the dev server analyze route (browser environment)
|
|
385
|
-
*/
|
|
386
|
-
type UILintScanIssue = {
|
|
387
|
-
line?: number;
|
|
388
|
-
message: string;
|
|
389
|
-
dataLoc?: string;
|
|
390
|
-
};
|
|
391
|
-
interface LLMClientOptions {
|
|
392
|
-
apiEndpoint?: string;
|
|
393
|
-
model?: string;
|
|
394
|
-
}
|
|
395
|
-
/**
|
|
396
|
-
* Client for communicating with the LLM via API route (browser environment)
|
|
397
|
-
*/
|
|
398
|
-
declare class LLMClient {
|
|
399
|
-
private apiEndpoint;
|
|
400
|
-
private model;
|
|
401
|
-
constructor(options?: LLMClientOptions);
|
|
402
|
-
/**
|
|
403
|
-
* Analyze a source file/snippet and return issues.
|
|
404
|
-
*
|
|
405
|
-
* NOTE: This matches the (simplified) `/api/.uilint/analyze` route which is
|
|
406
|
-
* now source-only (no styleSummary / styleguide generation).
|
|
407
|
-
*/
|
|
408
|
-
analyzeSource(input: {
|
|
409
|
-
sourceCode: string;
|
|
410
|
-
filePath?: string;
|
|
411
|
-
styleGuide?: string | null;
|
|
412
|
-
componentName?: string;
|
|
413
|
-
componentLine?: number;
|
|
414
|
-
includeChildren?: boolean;
|
|
415
|
-
dataLocs?: string[];
|
|
416
|
-
}): Promise<{
|
|
417
|
-
issues: UILintScanIssue[];
|
|
418
|
-
}>;
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
export { type CachedSource, type ComponentInfo, ConsistencyHighlighter, DATA_UILINT_ID, DEFAULT_SETTINGS, FILE_COLORS, type InspectedElement, InspectionPanel, LLMClient, LocatorOverlay, type LocatorTarget, type ScannedElement, type SourceApiResponse, type SourceFile, type SourceLocation, type UILintContextValue, UILintProvider, type UILintProviderProps, type UILintSettings, UILintToolbar, buildEditorUrl, cleanupDataAttributes, cleanupDataElements, clearSourceCache, createSnapshot, fetchSource, fetchSourceWithContext, getCachedSource, getComponentStack, getDebugOwner, getDebugSource, getDisplayName, getElementById, getElementBySnapshotId, getFiberFromElement, groupBySourceFile, isBrowser, isJSDOM, isNode, isNodeModulesPath, prefetchSources, scanDOM, scanDOMForSources, updateElementRects, useUILintContext };
|
|
369
|
+
export { type CachedSource, type ComponentInfo, ConsistencyHighlighter, DATA_UILINT_ID, DEFAULT_SETTINGS, FILE_COLORS, type InspectedElement, InspectionPanel, LocatorOverlay, type LocatorTarget, type ScannedElement, type SourceApiResponse, type SourceFile, type SourceLocation, type UILintContextValue, UILintProvider, type UILintProviderProps, type UILintSettings, UILintToolbar, buildEditorUrl, cleanupDataAttributes, cleanupDataElements, clearSourceCache, createSnapshot, fetchSource, fetchSourceWithContext, getCachedSource, getComponentStack, getDebugOwner, getDebugSource, getDisplayName, getElementById, getElementBySnapshotId, getFiberFromElement, groupBySourceFile, isBrowser, isJSDOM, isNode, isNodeModulesPath, prefetchSources, scanDOM, scanDOMForSources, updateElementRects, useUILintContext };
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import {
|
|
3
3
|
UILintToolbar
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-HTNIKCEM.js";
|
|
5
5
|
import {
|
|
6
6
|
InspectionPanel,
|
|
7
7
|
clearSourceCache,
|
|
@@ -9,10 +9,10 @@ import {
|
|
|
9
9
|
fetchSourceWithContext,
|
|
10
10
|
getCachedSource,
|
|
11
11
|
prefetchSources
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-JBBUE3Y5.js";
|
|
13
13
|
import {
|
|
14
14
|
LocatorOverlay
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-Z6PWYQGW.js";
|
|
16
16
|
import {
|
|
17
17
|
DATA_UILINT_ID,
|
|
18
18
|
DEFAULT_SETTINGS,
|
|
@@ -31,7 +31,7 @@ import {
|
|
|
31
31
|
scanDOMForSources,
|
|
32
32
|
updateElementRects,
|
|
33
33
|
useUILintContext
|
|
34
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-MO4NS6EG.js";
|
|
35
35
|
|
|
36
36
|
// src/consistency/snapshot.ts
|
|
37
37
|
var DATA_ELEMENTS_ATTR = "data-elements";
|
|
@@ -441,52 +441,6 @@ import {
|
|
|
441
441
|
serializeStyles as serializeStyles2,
|
|
442
442
|
createStyleSummary as createStyleSummary2
|
|
443
443
|
} from "uilint-core";
|
|
444
|
-
|
|
445
|
-
// src/analyzer/llm-client.ts
|
|
446
|
-
import { UILINT_DEFAULT_OLLAMA_MODEL } from "uilint-core";
|
|
447
|
-
var DEFAULT_API_ENDPOINT = "/api/.uilint/analyze";
|
|
448
|
-
var LLMClient = class {
|
|
449
|
-
apiEndpoint;
|
|
450
|
-
model;
|
|
451
|
-
constructor(options = {}) {
|
|
452
|
-
this.apiEndpoint = options.apiEndpoint || DEFAULT_API_ENDPOINT;
|
|
453
|
-
this.model = options.model || UILINT_DEFAULT_OLLAMA_MODEL;
|
|
454
|
-
}
|
|
455
|
-
/**
|
|
456
|
-
* Analyze a source file/snippet and return issues.
|
|
457
|
-
*
|
|
458
|
-
* NOTE: This matches the (simplified) `/api/.uilint/analyze` route which is
|
|
459
|
-
* now source-only (no styleSummary / styleguide generation).
|
|
460
|
-
*/
|
|
461
|
-
async analyzeSource(input) {
|
|
462
|
-
try {
|
|
463
|
-
const response = await fetch(this.apiEndpoint, {
|
|
464
|
-
method: "POST",
|
|
465
|
-
headers: { "Content-Type": "application/json" },
|
|
466
|
-
body: JSON.stringify({
|
|
467
|
-
sourceCode: input.sourceCode,
|
|
468
|
-
filePath: input.filePath,
|
|
469
|
-
styleGuide: input.styleGuide ?? void 0,
|
|
470
|
-
componentName: input.componentName,
|
|
471
|
-
componentLine: input.componentLine,
|
|
472
|
-
includeChildren: input.includeChildren,
|
|
473
|
-
dataLocs: input.dataLocs,
|
|
474
|
-
model: this.model
|
|
475
|
-
})
|
|
476
|
-
});
|
|
477
|
-
if (!response.ok) {
|
|
478
|
-
throw new Error(`API request failed: ${response.status}`);
|
|
479
|
-
}
|
|
480
|
-
const data = await response.json();
|
|
481
|
-
return { issues: data.issues || [] };
|
|
482
|
-
} catch (error) {
|
|
483
|
-
console.error("[UILint] Analysis failed:", error);
|
|
484
|
-
return { issues: [] };
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
};
|
|
488
|
-
|
|
489
|
-
// src/index.ts
|
|
490
444
|
import { parseStyleGuide } from "uilint-core";
|
|
491
445
|
import { generateStyleGuideFromStyles } from "uilint-core";
|
|
492
446
|
import { createEmptyStyleGuide, mergeStyleGuides } from "uilint-core";
|
|
@@ -496,7 +450,6 @@ export {
|
|
|
496
450
|
DEFAULT_SETTINGS,
|
|
497
451
|
FILE_COLORS,
|
|
498
452
|
InspectionPanel,
|
|
499
|
-
LLMClient,
|
|
500
453
|
LocatorOverlay,
|
|
501
454
|
UILintProvider,
|
|
502
455
|
UILintToolbar,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "uilint-react",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.33",
|
|
4
4
|
"description": "React component for AI-powered UI consistency checking",
|
|
5
5
|
"author": "Peter Suggate",
|
|
6
6
|
"repository": {
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"node": ">=20.0.0"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"uilint-core": "^0.1.
|
|
37
|
+
"uilint-core": "^0.1.33",
|
|
38
38
|
"zustand": "^5.0.5"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|