polydup-node 0.1.0

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 (2) hide show
  1. package/README.md +181 -0
  2. package/package.json +62 -0
package/README.md ADDED
@@ -0,0 +1,181 @@
1
+ # @polydup/core
2
+
3
+ Node.js bindings for PolyDup - a cross-language duplicate code detector powered by Rust.
4
+
5
+ ## Features
6
+
7
+ - 🚀 **Fast**: Built in Rust with Tree-sitter for efficient parsing
8
+ - 🔄 **Multi-language**: Supports Rust, Python, JavaScript/TypeScript
9
+ - ⚡ **Non-blocking**: Async API runs on background threads
10
+ - 🎯 **Type-2 clones**: Detects structurally similar code with different variable names
11
+ - 📊 **Detailed reports**: Statistics and similarity scores
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ npm install @polydup/core
17
+ ```
18
+
19
+ ## Quick Start
20
+
21
+ ```javascript
22
+ const { findDuplicates } = require('@polydup/core');
23
+
24
+ findDuplicates(['./src', './lib'], 50, 0.85)
25
+ .then(report => {
26
+ console.log(`Found ${report.duplicates.length} duplicates`);
27
+ console.log(`Scanned ${report.filesScanned} files in ${report.stats.durationMs}ms`);
28
+
29
+ report.duplicates.forEach(dup => {
30
+ console.log(`${dup.file1} ↔️ ${dup.file2} (${(dup.similarity * 100).toFixed(1)}%)`);
31
+ });
32
+ })
33
+ .catch(err => console.error('Scan failed:', err));
34
+ ```
35
+
36
+ ## API
37
+
38
+ ### `findDuplicates(paths, minBlockSize?, threshold?)`
39
+
40
+ Asynchronously scans for duplicate code (recommended).
41
+
42
+ **Parameters:**
43
+ - `paths: string[]` - File or directory paths to scan
44
+ - `minBlockSize?: number` - Minimum code block size in tokens (default: 50)
45
+ - `threshold?: number` - Similarity threshold 0.0-1.0 (default: 0.85)
46
+
47
+ **Returns:** `Promise<Report>`
48
+
49
+ **Example:**
50
+ ```javascript
51
+ const report = await findDuplicates(['./src'], 30, 0.9);
52
+ ```
53
+
54
+ ### `findDuplicatesSync(paths, minBlockSize?, threshold?)`
55
+
56
+ Synchronously scans for duplicate code (blocks event loop - use sparingly).
57
+
58
+ **Parameters:** Same as `findDuplicates`
59
+
60
+ **Returns:** `Report`
61
+
62
+ **Example:**
63
+ ```javascript
64
+ const report = findDuplicatesSync(['./src'], 50, 0.85);
65
+ ```
66
+
67
+ ### `version()`
68
+
69
+ Returns the library version string.
70
+
71
+ **Returns:** `string`
72
+
73
+ ## TypeScript
74
+
75
+ Type definitions are automatically generated:
76
+
77
+ ```typescript
78
+ import { findDuplicates, Report, DuplicateMatch } from '@polydup/core';
79
+
80
+ const report: Report = await findDuplicates(['./src']);
81
+
82
+ report.duplicates.forEach((dup: DuplicateMatch) => {
83
+ console.log(`${dup.file1} ↔️ ${dup.file2}`);
84
+ });
85
+ ```
86
+
87
+ ## Report Structure
88
+
89
+ ```typescript
90
+ interface Report {
91
+ filesScanned: number;
92
+ functionsAnalyzed: number;
93
+ duplicates: DuplicateMatch[];
94
+ stats: ScanStats;
95
+ }
96
+
97
+ interface DuplicateMatch {
98
+ file1: string;
99
+ file2: string;
100
+ startLine1: number;
101
+ startLine2: number;
102
+ length: number; // Block size in tokens
103
+ similarity: number; // 0.0 - 1.0
104
+ hash: string; // Hash signature
105
+ }
106
+
107
+ interface ScanStats {
108
+ totalLines: number;
109
+ totalTokens: number;
110
+ uniqueHashes: number;
111
+ durationMs: number;
112
+ }
113
+ ```
114
+
115
+ ## Performance Tips
116
+
117
+ 1. **Use async API**: Always prefer `findDuplicates()` over `findDuplicatesSync()` to avoid blocking
118
+ 2. **Adjust window size**: Smaller `minBlockSize` finds more matches but may include false positives
119
+ 3. **Filter results**: Apply post-processing to filter duplicates by file patterns or directories
120
+ 4. **Parallel scans**: Use Promise.all for multiple independent scans
121
+
122
+ ## Example: Custom Analysis
123
+
124
+ ```javascript
125
+ const { findDuplicates } = require('@polydup/core');
126
+
127
+ async function analyzeCrossProject() {
128
+ const [frontend, backend] = await Promise.all([
129
+ findDuplicates(['./frontend/src'], 40, 0.9),
130
+ findDuplicates(['./backend/src'], 40, 0.9),
131
+ ]);
132
+
133
+ console.log('Frontend duplicates:', frontend.duplicates.length);
134
+ console.log('Backend duplicates:', backend.duplicates.length);
135
+
136
+ // Find cross-project duplicates
137
+ const allPaths = ['./frontend', './backend'];
138
+ const crossProject = await findDuplicates(allPaths, 50, 0.95);
139
+
140
+ const crossDuplicates = crossProject.duplicates.filter(d =>
141
+ d.file1.includes('frontend') && d.file2.includes('backend')
142
+ );
143
+
144
+ console.log('Cross-project duplicates:', crossDuplicates.length);
145
+ }
146
+
147
+ analyzeCrossProject();
148
+ ```
149
+
150
+ ## Building from Source
151
+
152
+ ```bash
153
+ cd crates/dupe-node
154
+ npm install
155
+ npm run build
156
+ npm test
157
+ ```
158
+
159
+ ## Generating Type Definitions
160
+
161
+ Type definitions are auto-generated during build:
162
+
163
+ ```bash
164
+ npm run typegen
165
+ ```
166
+
167
+ This creates `index.d.ts` with TypeScript definitions for all exported functions.
168
+
169
+ ## Supported Platforms
170
+
171
+ - macOS (Intel & Apple Silicon)
172
+ - Linux (x64 & ARM64)
173
+ - Windows (x64)
174
+
175
+ ## License
176
+
177
+ MIT
178
+
179
+ ## Repository
180
+
181
+ https://github.com/wiesnerbernard/polydup
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "polydup-node",
3
+ "version": "0.1.0",
4
+ "description": "Cross-language duplicate code detector - Node.js bindings",
5
+ "main": "index.js",
6
+ "types": "index.d.ts",
7
+ "keywords": [
8
+ "duplicate",
9
+ "code",
10
+ "detection",
11
+ "tree-sitter",
12
+ "ast",
13
+ "clone",
14
+ "rust",
15
+ "napi"
16
+ ],
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "https://github.com/wiesnerbernard/polydup.git"
20
+ },
21
+ "license": "MIT",
22
+ "napi": {
23
+ "name": "dupe-node",
24
+ "triples": {
25
+ "additional": [
26
+ "aarch64-apple-darwin",
27
+ "x86_64-apple-darwin",
28
+ "x86_64-unknown-linux-gnu",
29
+ "x86_64-pc-windows-msvc",
30
+ "aarch64-unknown-linux-gnu"
31
+ ]
32
+ }
33
+ },
34
+ "scripts": {
35
+ "artifacts": "napi artifacts",
36
+ "build": "napi build --platform --release",
37
+ "build:debug": "napi build --platform",
38
+ "prepublishOnly": "napi prepublish -t npm",
39
+ "test": "node test.js",
40
+ "version": "napi version",
41
+ "typegen": "napi build --platform --release --dts index.d.ts"
42
+ },
43
+ "devDependencies": {
44
+ "@napi-rs/cli": "^2.18.0",
45
+ "prettier": "^3.1.0"
46
+ },
47
+ "engines": {
48
+ "node": ">= 12"
49
+ },
50
+ "files": [
51
+ "index.js",
52
+ "index.d.ts",
53
+ "README.md"
54
+ ],
55
+ "optionalDependencies": {
56
+ "polydup-node-win32-x64-msvc": "0.1.0",
57
+ "polydup-node-darwin-x64": "0.1.0",
58
+ "polydup-node-linux-x64-gnu": "0.1.0",
59
+ "polydup-node-darwin-arm64": "0.1.0",
60
+ "polydup-node-linux-arm64-gnu": "0.1.0"
61
+ }
62
+ }