• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Stevenic / vectra / 23930816581

03 Apr 2026 02:16AM UTC coverage: 44.639%. First build
23930816581

push

github

web-flow
Add browser and Electron support (#99)

* added support for browser and electron

* in progress browser support

* Browser Compatibility Enhancement (#95)

* Fix browser compatibility by replacing node:path with pathUtils

* Add webpack build for browser bundle

* Add Hugging Face Transformers.js support for local embeddings (#97)

* Replace node path imports with pathUtils in LocalDocument, LocalDocumentIndex, and LocalIndex specs

* Add @huggingface/transformers as dev and peer dependency

* Add transformers.js support

* Configure @huggingface/transformers as external in webpack browser build

* Remove Autotokenizer imports since not longer needed.

* updated memories and README

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* memory updates

* fixed cicd pipeline

* fix(ci): drop Node 20 from matrix — undici@8.0.0 requires Node >=22.19.0

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* updated node engine to 22.x

* fix(ci): add lcov reporter so Coveralls can find coverage data

.nycrc only had "html" reporter — Coveralls needs lcov.info.
Added lcov + text reporters and pointed the upload step at the file.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* added ESLint support

---------

Co-authored-by: Yen Colon <32972934+yencolon@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

271 of 737 branches covered (36.77%)

Branch coverage included in aggregate %.

29 of 256 new or added lines in 9 files covered. (11.33%)

724 of 1492 relevant lines covered (48.53%)

5.89 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

59.02
/src/utils/pathUtils.ts
1
/**
2
 * Universal path utilities that work in Node, Browser, and Electron.
3
 * Replaces Node's 'path' module for cross-platform compatibility.
4
 */
5
export const pathUtils = {
1✔
6
    /**
7
     * Path separator. Always '/' for consistency across platforms.
8
     */
9
    sep: '/' as const,
10
    /**
11
     * Join path segments together.
12
     */
13
    join(...parts: string[]): string {
14
        return parts
77✔
15
            .map((part, i) => {
16
                if (i === 0) return part.replace(/[/\\]+$/, '');
154✔
17
                return part.replace(/^[/\\]+|[/\\]+$/g, '');
77✔
18
            })
19
            .filter(Boolean)
20
            .join('/');
21
    },
22

23
    /**
24
     * Get the last portion of a path.
25
     */
26
    basename(filePath: string, ext?: string): string {
27
        const base = filePath.split(/[/\\]/).pop() || '';
190!
28
        if (ext && base.endsWith(ext)) {
190!
NEW
29
            return base.slice(0, -ext.length);
×
30
        }
31
        return base;
190✔
32
    },
33

34
    /**
35
     * Get the directory name of a path.
36
     */
37
    dirname(filePath: string): string {
NEW
38
        const parts = filePath.split(/[/\\]/);
×
NEW
39
        parts.pop();
×
NEW
40
        return parts.join('/') || '.';
×
41
    },
42

43
    /**
44
     * Get the extension of the path.
45
     */
46
    extname(filePath: string): string {
47
        const base = pathUtils.basename(filePath);
79✔
48
        const dotIndex = base.lastIndexOf('.');
79✔
49
        return dotIndex > 0 ? base.slice(dotIndex) : '';
79✔
50
    },
51

52
    /**
53
     * Normalize a path, resolving '..' and '.' segments.
54
     */
55
    normalize(filePath: string): string {
56
        const isAbsolute = filePath.startsWith('/') || /^[a-zA-Z]:/.test(filePath);
226✔
57
        const parts = filePath.split(/[/\\]/);
226✔
58
        const result: string[] = [];
226✔
59

60
        for (const part of parts) {
226✔
61
            if (part === '..') {
523✔
62
                result.pop();
1✔
63
            } else if (part !== '.' && part !== '') {
522✔
64
                result.push(part);
394✔
65
            }
66
        }
67

68
        return (isAbsolute && !(/^[a-zA-Z]:/.test(filePath)) ? '/' : '') + result.join('/');
226✔
69
    },
70

71
    /**
72
     * Determine if a path is absolute.
73
     */
74
    isAbsolute(filePath: string): boolean {
NEW
75
        return filePath.startsWith('/') || /^[a-zA-Z]:[/\\]/.test(filePath);
×
76
    },
77

78
    /**
79
     * Get the relative path from one path to another.
80
     */
81
    relative(from: string, to: string): string {
NEW
82
        const fromParts = pathUtils.normalize(from).split('/').filter(Boolean);
×
NEW
83
        const toParts = pathUtils.normalize(to).split('/').filter(Boolean);
×
84

85
        // Find common prefix
NEW
86
        let commonLength = 0;
×
NEW
87
        while (
×
88
            commonLength < fromParts.length &&
×
89
            commonLength < toParts.length &&
90
            fromParts[commonLength] === toParts[commonLength]
91
        ) {
NEW
92
            commonLength++;
×
93
        }
94

95
        // Build relative path
NEW
96
        const upCount = fromParts.length - commonLength;
×
NEW
97
        const relativeParts = [
×
98
            ...Array(upCount).fill('..'),
99
            ...toParts.slice(commonLength)
100
        ];
101

NEW
102
        return relativeParts.join('/') || '.';
×
103
    }
104
};
105

106
export default pathUtils;
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc