@opentrace/components 0.1.1-rc.47 → 0.1.1-rc.62
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/README.md +306 -0
- package/bin/copy-wasm.js +125 -0
- package/dist/opentrace-components.cjs +354 -246
- package/dist/opentrace-components.cjs.map +1 -1
- package/dist/opentrace-components.js +355 -247
- package/dist/opentrace-components.js.map +1 -1
- package/dist/pipeline-wasm.cjs +58 -0
- package/dist/pipeline-wasm.cjs.map +1 -0
- package/dist/pipeline-wasm.js +57 -0
- package/dist/pipeline-wasm.js.map +1 -0
- package/dist/pipeline.cjs +3481 -0
- package/dist/pipeline.cjs.map +1 -0
- package/dist/pipeline.js +3481 -0
- package/dist/pipeline.js.map +1 -0
- package/dist/src/GraphCanvas.d.ts +5 -0
- package/dist/src/GraphCanvas.d.ts.map +1 -1
- package/dist/src/colors/communityColors.d.ts.map +1 -1
- package/dist/src/config/graphLayout.d.ts +9 -9
- package/dist/src/config/graphLayout.d.ts.map +1 -1
- package/dist/src/graph/LayoutPipeline.d.ts +4 -6
- package/dist/src/graph/LayoutPipeline.d.ts.map +1 -1
- package/dist/src/graph/spacingWorker.d.ts +4 -0
- package/dist/src/graph/spacingWorker.d.ts.map +1 -1
- package/dist/src/graph/useGraphFilters.d.ts.map +1 -1
- package/dist/src/graph/useGraphInstance.d.ts.map +1 -1
- package/dist/src/graph/useGraphVisuals.d.ts.map +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/pipeline/__tests__/cross-repo.test.d.ts +2 -0
- package/dist/src/pipeline/__tests__/cross-repo.test.d.ts.map +1 -0
- package/dist/src/pipeline/__tests__/fixture.test.d.ts +2 -0
- package/dist/src/pipeline/__tests__/fixture.test.d.ts.map +1 -0
- package/dist/src/pipeline/__tests__/github.test.d.ts +2 -0
- package/dist/src/pipeline/__tests__/github.test.d.ts.map +1 -0
- package/dist/src/pipeline/__tests__/helpers.d.ts +16 -0
- package/dist/src/pipeline/__tests__/helpers.d.ts.map +1 -0
- package/dist/src/pipeline/__tests__/loading.test.d.ts +2 -0
- package/dist/src/pipeline/__tests__/loading.test.d.ts.map +1 -0
- package/dist/src/pipeline/__tests__/parsing.test.d.ts +2 -0
- package/dist/src/pipeline/__tests__/parsing.test.d.ts.map +1 -0
- package/dist/src/pipeline/__tests__/pipeline.test.d.ts +2 -0
- package/dist/src/pipeline/__tests__/pipeline.test.d.ts.map +1 -0
- package/dist/src/pipeline/index.d.ts +19 -0
- package/dist/src/pipeline/index.d.ts.map +1 -0
- package/dist/src/pipeline/parser/callResolver.d.ts +52 -0
- package/dist/src/pipeline/parser/callResolver.d.ts.map +1 -0
- package/dist/src/pipeline/parser/extractors/generic.d.ts +15 -0
- package/dist/src/pipeline/parser/extractors/generic.d.ts.map +1 -0
- package/dist/src/pipeline/parser/extractors/go.d.ts +8 -0
- package/dist/src/pipeline/parser/extractors/go.d.ts.map +1 -0
- package/dist/src/pipeline/parser/extractors/python.d.ts +8 -0
- package/dist/src/pipeline/parser/extractors/python.d.ts.map +1 -0
- package/dist/src/pipeline/parser/extractors/typescript.d.ts +8 -0
- package/dist/src/pipeline/parser/extractors/typescript.d.ts.map +1 -0
- package/dist/src/pipeline/parser/importAnalyzer.d.ts +25 -0
- package/dist/src/pipeline/parser/importAnalyzer.d.ts.map +1 -0
- package/dist/src/pipeline/parser/manifestParser.d.ts +42 -0
- package/dist/src/pipeline/parser/manifestParser.d.ts.map +1 -0
- package/dist/src/pipeline/pipeline.d.ts +10 -0
- package/dist/src/pipeline/pipeline.d.ts.map +1 -0
- package/dist/src/pipeline/stages/loading.d.ts +6 -0
- package/dist/src/pipeline/stages/loading.d.ts.map +1 -0
- package/dist/src/pipeline/stages/parsing.d.ts +20 -0
- package/dist/src/pipeline/stages/parsing.d.ts.map +1 -0
- package/dist/src/pipeline/stages/processing.d.ts +15 -0
- package/dist/src/pipeline/stages/processing.d.ts.map +1 -0
- package/dist/src/pipeline/stages/resolving.d.ts +11 -0
- package/dist/src/pipeline/stages/resolving.d.ts.map +1 -0
- package/dist/src/pipeline/stages/saving.d.ts +7 -0
- package/dist/src/pipeline/stages/saving.d.ts.map +1 -0
- package/dist/src/pipeline/stages/scanning.d.ts +7 -0
- package/dist/src/pipeline/stages/scanning.d.ts.map +1 -0
- package/dist/src/pipeline/stages/summarizing.d.ts +16 -0
- package/dist/src/pipeline/stages/summarizing.d.ts.map +1 -0
- package/dist/src/pipeline/store/memory.d.ts +8 -0
- package/dist/src/pipeline/store/memory.d.ts.map +1 -0
- package/dist/src/pipeline/summarizer/templateSummarizer.d.ts +40 -0
- package/dist/src/pipeline/summarizer/templateSummarizer.d.ts.map +1 -0
- package/dist/src/pipeline/summarizer/types.d.ts +62 -0
- package/dist/src/pipeline/summarizer/types.d.ts.map +1 -0
- package/dist/src/pipeline/types.d.ts +119 -0
- package/dist/src/pipeline/types.d.ts.map +1 -0
- package/dist/src/pipeline/wasm.d.ts +14 -0
- package/dist/src/pipeline/wasm.d.ts.map +1 -0
- package/dist/src/sigma/useSelectionPulse.d.ts +3 -0
- package/dist/src/sigma/useSelectionPulse.d.ts.map +1 -0
- package/dist/{useHighlights-DbMfb0-p.js → useHighlights-CmOAWaLE.js} +60 -53
- package/dist/{useHighlights-DbMfb0-p.js.map → useHighlights-CmOAWaLE.js.map} +1 -1
- package/dist/{useHighlights-fRWg-A_c.cjs → useHighlights-zx7DM4V0.cjs} +60 -53
- package/dist/{useHighlights-fRWg-A_c.cjs.map → useHighlights-zx7DM4V0.cjs.map} +1 -1
- package/dist/utils.cjs +1 -1
- package/dist/utils.js +1 -1
- package/package.json +32 -4
- package/public/wasm/tree-sitter-bash.wasm +0 -0
- package/public/wasm/tree-sitter-c.wasm +0 -0
- package/public/wasm/tree-sitter-c_sharp.wasm +0 -0
- package/public/wasm/tree-sitter-cpp.wasm +0 -0
- package/public/wasm/tree-sitter-go.wasm +0 -0
- package/public/wasm/tree-sitter-java.wasm +0 -0
- package/public/wasm/tree-sitter-json.wasm +0 -0
- package/public/wasm/tree-sitter-kotlin.wasm +0 -0
- package/public/wasm/tree-sitter-python.wasm +0 -0
- package/public/wasm/tree-sitter-ruby.wasm +0 -0
- package/public/wasm/tree-sitter-rust.wasm +0 -0
- package/public/wasm/tree-sitter-swift.wasm +0 -0
- package/public/wasm/tree-sitter-toml.wasm +0 -0
- package/public/wasm/tree-sitter-tsx.wasm +0 -0
- package/public/wasm/tree-sitter-typescript.wasm +0 -0
- package/public/wasm/web-tree-sitter.wasm +0 -0
- package/dist/assets/spacingWorker-hXLGHyRg.js +0 -123
- package/dist/assets/spacingWorker-hXLGHyRg.js.map +0 -1
package/README.md
ADDED
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
# @opentrace/components
|
|
2
|
+
|
|
3
|
+
Shared library for the [OpenTrace](https://github.com/opentrace/opentrace) platform. Ships two independent feature sets:
|
|
4
|
+
|
|
5
|
+
1. **Graph visualization** — React components powered by Sigma.js and Graphology
|
|
6
|
+
2. **Ingest pipeline** — framework-free code parsing pipeline (no React required)
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install @opentrace/components
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Entry points
|
|
15
|
+
|
|
16
|
+
| Import path | Needs React | Description |
|
|
17
|
+
|---|---|---|
|
|
18
|
+
| `@opentrace/components` | Yes | Graph visualization components |
|
|
19
|
+
| `@opentrace/components/pipeline` | No | Code parsing & knowledge graph pipeline |
|
|
20
|
+
| `@opentrace/components/pipeline/wasm` | No (Node.js only) | WASM file path helpers |
|
|
21
|
+
| `@opentrace/components/utils` | No | Shared utility functions |
|
|
22
|
+
| `@opentrace/components/indexing` | Yes | Indexing UI components |
|
|
23
|
+
| `@opentrace/components/style.css` | — | Base CSS styles |
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Graph visualization
|
|
28
|
+
|
|
29
|
+
Interactive knowledge graph renderer built on [Sigma.js](https://www.sigmajs.org/).
|
|
30
|
+
|
|
31
|
+
### Quick start
|
|
32
|
+
|
|
33
|
+
```tsx
|
|
34
|
+
import { GraphCanvas } from '@opentrace/components';
|
|
35
|
+
import '@opentrace/components/style.css';
|
|
36
|
+
|
|
37
|
+
const data = {
|
|
38
|
+
nodes: [
|
|
39
|
+
{ id: '1', type: 'Service', name: 'api-gateway', properties: {} },
|
|
40
|
+
{ id: '2', type: 'Service', name: 'user-service', properties: {} },
|
|
41
|
+
],
|
|
42
|
+
links: [
|
|
43
|
+
{ source: '1', target: '2', type: 'CALLS', id: 'e1' },
|
|
44
|
+
],
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
function App() {
|
|
48
|
+
return <GraphCanvas data={data} height={600} />;
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Components
|
|
53
|
+
|
|
54
|
+
- **`GraphCanvas`** — main graph renderer with layout, filtering, and interaction
|
|
55
|
+
- **`FilterPanel`** — node type / relationship type filter controls
|
|
56
|
+
- **`GraphToolbar`** — zoom, fit, layout toggle controls
|
|
57
|
+
- **`GraphLegend`** — color legend for node types
|
|
58
|
+
- **`GraphBadge`** — node/edge count badge
|
|
59
|
+
- **`DiscoverPanel`** — tree-based graph explorer
|
|
60
|
+
- **`AddRepoModal`** — repository URL input modal
|
|
61
|
+
- **`IndexingProgress`** — multi-stage indexing progress display
|
|
62
|
+
|
|
63
|
+
### Hooks
|
|
64
|
+
|
|
65
|
+
- `useGraphInstance` — access the underlying Graphology/Sigma instances
|
|
66
|
+
- `useGraphFilters` — manage filter state
|
|
67
|
+
- `useGraphVisuals` — control visual properties (colors, sizes, opacity)
|
|
68
|
+
- `useCommunities` — Louvain community detection
|
|
69
|
+
- `useHighlights` — node/edge highlight state
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Ingest pipeline
|
|
74
|
+
|
|
75
|
+
Pure TypeScript pipeline that parses source code into a knowledge graph using [web-tree-sitter](https://github.com/nicolo-ribaudo/tree-sitter-wasm-prebuilt). No React, no browser APIs — works in Node.js, workers, or the browser.
|
|
76
|
+
|
|
77
|
+
### Peer dependency
|
|
78
|
+
|
|
79
|
+
The pipeline requires `web-tree-sitter` at runtime:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
npm install web-tree-sitter
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Browser setup
|
|
86
|
+
|
|
87
|
+
WASM grammar files must be served as static assets. Copy them to your app's public directory:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
# All languages (~25 MB)
|
|
91
|
+
npx opentrace-copy-wasm public/
|
|
92
|
+
|
|
93
|
+
# Only the languages you need
|
|
94
|
+
npx opentrace-copy-wasm --languages python,typescript,go public/
|
|
95
|
+
|
|
96
|
+
# Just the runtime (if you load grammars separately)
|
|
97
|
+
npx opentrace-copy-wasm --runtime-only public/
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Add this to `package.json` to keep them in sync:
|
|
101
|
+
|
|
102
|
+
```json
|
|
103
|
+
{
|
|
104
|
+
"scripts": {
|
|
105
|
+
"postinstall": "opentrace-copy-wasm public/"
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Running the pipeline
|
|
111
|
+
|
|
112
|
+
```ts
|
|
113
|
+
import { Parser, Language } from 'web-tree-sitter';
|
|
114
|
+
import {
|
|
115
|
+
runPipeline,
|
|
116
|
+
initParsers,
|
|
117
|
+
collectPipeline,
|
|
118
|
+
type RepoTree,
|
|
119
|
+
type PipelineEvent,
|
|
120
|
+
} from '@opentrace/components/pipeline';
|
|
121
|
+
|
|
122
|
+
// 1. Initialize tree-sitter parsers
|
|
123
|
+
await Parser.init({ locateFile: (file) => `/${file}` });
|
|
124
|
+
|
|
125
|
+
const pyParser = new Parser();
|
|
126
|
+
pyParser.setLanguage(await Language.load('/tree-sitter-python.wasm'));
|
|
127
|
+
|
|
128
|
+
initParsers(new Map([['python', pyParser]]));
|
|
129
|
+
|
|
130
|
+
// 2. Build a RepoTree (your files)
|
|
131
|
+
const repo: RepoTree = {
|
|
132
|
+
owner: 'myorg',
|
|
133
|
+
repo: 'myproject',
|
|
134
|
+
ref: 'main',
|
|
135
|
+
files: [
|
|
136
|
+
{ path: 'app.py', content: 'def hello():\n print("hi")\n' },
|
|
137
|
+
{ path: 'utils.py', content: 'def helper():\n pass\n' },
|
|
138
|
+
],
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
// 3. Run the pipeline (streaming)
|
|
142
|
+
for (const event of runPipeline({ repo }, { cancelled: false })) {
|
|
143
|
+
if (event.nodes) {
|
|
144
|
+
console.log(`${event.phase}: ${event.nodes.length} nodes`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Or collect everything at once
|
|
149
|
+
const { nodes, relationships } = collectPipeline(
|
|
150
|
+
{ repo },
|
|
151
|
+
{ cancelled: false },
|
|
152
|
+
);
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Pipeline stages
|
|
156
|
+
|
|
157
|
+
The pipeline is a chain of synchronous generators. Each stage yields `PipelineEvent` objects:
|
|
158
|
+
|
|
159
|
+
```
|
|
160
|
+
runPipeline()
|
|
161
|
+
saving(inner, store) <- persists nodes/rels to the store
|
|
162
|
+
wrapWithSummaries(inner) <- adds summary property to every node
|
|
163
|
+
corePipeline() <- produces events via:
|
|
164
|
+
yield* scanning() <- repo structure (files, dirs, packages)
|
|
165
|
+
yield* processing() <- symbol extraction (classes, functions)
|
|
166
|
+
yield* resolving() <- call resolution (CALLS relationships)
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
**Scanning** — builds the structural graph: Repository, Directory, File, Package nodes + DEFINED_IN, DEPENDS_ON relationships. Parses dependency manifests (package.json, go.mod, requirements.txt, pyproject.toml, Cargo.toml).
|
|
170
|
+
|
|
171
|
+
**Processing** — parses each file with tree-sitter, extracts Class/Function nodes, analyzes imports, and builds registries for call resolution.
|
|
172
|
+
|
|
173
|
+
**Resolving** — resolves function calls using a 7-strategy priority resolver (self/this, Go receiver, ClassName.method, import-based, constructor, intra-file, cross-file).
|
|
174
|
+
|
|
175
|
+
**Summarizing** — generates one-sentence summaries for every node using identifier analysis and template patterns. No ML required.
|
|
176
|
+
|
|
177
|
+
### Using the in-memory store
|
|
178
|
+
|
|
179
|
+
```ts
|
|
180
|
+
import {
|
|
181
|
+
runPipeline,
|
|
182
|
+
MemoryStore,
|
|
183
|
+
type RepoTree,
|
|
184
|
+
} from '@opentrace/components/pipeline';
|
|
185
|
+
|
|
186
|
+
const store = new MemoryStore();
|
|
187
|
+
const repo: RepoTree = { /* ... */ };
|
|
188
|
+
|
|
189
|
+
for (const event of runPipeline({ repo }, { cancelled: false }, store)) {
|
|
190
|
+
// events flow through
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Query the store
|
|
194
|
+
console.log(`${store.nodes.size} nodes, ${store.relationships.size} relationships`);
|
|
195
|
+
|
|
196
|
+
const classes = [...store.nodes.values()].filter(n => n.type === 'Class');
|
|
197
|
+
const calls = [...store.relationships.values()].filter(r => r.type === 'CALLS');
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Supported languages
|
|
201
|
+
|
|
202
|
+
| Language | Extractor | Import analysis | Call resolution |
|
|
203
|
+
|---|---|---|---|
|
|
204
|
+
| Python | Bespoke | Yes | Yes |
|
|
205
|
+
| TypeScript/TSX | Bespoke | Yes | Yes |
|
|
206
|
+
| JavaScript/JSX | Bespoke (shared with TS) | Yes | Yes |
|
|
207
|
+
| Go | Bespoke | Yes (with module path) | Yes |
|
|
208
|
+
| Rust | Generic | Yes | No |
|
|
209
|
+
| Ruby | Generic | Yes | No |
|
|
210
|
+
| Java | Generic | No | No |
|
|
211
|
+
| Kotlin | Generic | No | No |
|
|
212
|
+
| C# | Generic | No | No |
|
|
213
|
+
| C | Generic | No | No |
|
|
214
|
+
| C++ | Generic | No | No |
|
|
215
|
+
| Swift | Generic | No | No |
|
|
216
|
+
|
|
217
|
+
### Node.js WASM helpers
|
|
218
|
+
|
|
219
|
+
For Node.js scripts, tests, or CLI tools, use the WASM path helpers to locate grammar files without hardcoding paths:
|
|
220
|
+
|
|
221
|
+
```ts
|
|
222
|
+
import { readFile } from 'node:fs/promises';
|
|
223
|
+
import { Parser, Language } from 'web-tree-sitter';
|
|
224
|
+
import { getWasmPath, getWasmDir } from '@opentrace/components/pipeline/wasm';
|
|
225
|
+
|
|
226
|
+
// Initialize the runtime
|
|
227
|
+
const runtimeBuf = await readFile(getWasmPath('runtime'));
|
|
228
|
+
await Parser.init({
|
|
229
|
+
locateFile: () => getWasmPath('runtime'),
|
|
230
|
+
wasmBinary: runtimeBuf,
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
// Load a specific grammar
|
|
234
|
+
const parser = new Parser();
|
|
235
|
+
const lang = await Language.load(await readFile(getWasmPath('python')));
|
|
236
|
+
parser.setLanguage(lang);
|
|
237
|
+
|
|
238
|
+
// Or get the directory for bulk operations
|
|
239
|
+
const wasmDir = getWasmDir(); // absolute path to .wasm files
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
> **Note:** `@opentrace/components/pipeline/wasm` uses `node:fs` and `node:path` internally. Import it only in Node.js contexts — not in browser bundles.
|
|
243
|
+
|
|
244
|
+
### Using individual parsers
|
|
245
|
+
|
|
246
|
+
The extractors, import analyzer, and manifest parser are all exported individually:
|
|
247
|
+
|
|
248
|
+
```ts
|
|
249
|
+
import {
|
|
250
|
+
extractPython,
|
|
251
|
+
extractTypeScript,
|
|
252
|
+
extractGo,
|
|
253
|
+
extractGeneric,
|
|
254
|
+
analyzeImports,
|
|
255
|
+
parseManifest,
|
|
256
|
+
isManifestFile,
|
|
257
|
+
resolveCalls,
|
|
258
|
+
summarizeFromMetadata,
|
|
259
|
+
} from '@opentrace/components/pipeline';
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
---
|
|
263
|
+
|
|
264
|
+
## Graph node types
|
|
265
|
+
|
|
266
|
+
The pipeline produces these node types:
|
|
267
|
+
|
|
268
|
+
| Type | Description | ID format |
|
|
269
|
+
|---|---|---|
|
|
270
|
+
| Repository | Source code repository | `owner/repo` |
|
|
271
|
+
| Directory | Directory in the repo | `owner/repo/path` |
|
|
272
|
+
| File | Source file | `owner/repo/path/file` |
|
|
273
|
+
| Class | Class, struct, interface, enum | `fileId::ClassName` |
|
|
274
|
+
| Function | Function or method | `fileId::funcName` or `classId::methodName` |
|
|
275
|
+
| Package | External dependency | `pkg:registry:name` |
|
|
276
|
+
|
|
277
|
+
## Relationship types
|
|
278
|
+
|
|
279
|
+
| Type | Description |
|
|
280
|
+
|---|---|
|
|
281
|
+
| DEFINED_IN | Child is defined in parent (File in Dir, Class in File, etc.) |
|
|
282
|
+
| CALLS | Function/method calls another function/method |
|
|
283
|
+
| IMPORTS | File imports another file or package |
|
|
284
|
+
| DEPENDS_ON | Repository depends on a package |
|
|
285
|
+
|
|
286
|
+
---
|
|
287
|
+
|
|
288
|
+
## Development
|
|
289
|
+
|
|
290
|
+
```bash
|
|
291
|
+
# Build the library
|
|
292
|
+
npm run build
|
|
293
|
+
|
|
294
|
+
# Run tests
|
|
295
|
+
npm test
|
|
296
|
+
|
|
297
|
+
# Format
|
|
298
|
+
npm run fmt
|
|
299
|
+
|
|
300
|
+
# Lint
|
|
301
|
+
npm run lint
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
## License
|
|
305
|
+
|
|
306
|
+
Apache 2.0 — see [LICENSE](../LICENSE).
|
package/bin/copy-wasm.js
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* Copyright 2026 OpenTrace Contributors
|
|
5
|
+
*
|
|
6
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
* you may not use this file except in compliance with the License.
|
|
8
|
+
* You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
* See the License for the specific language governing permissions and
|
|
16
|
+
* limitations under the License.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Copy tree-sitter WASM files to your app's public directory.
|
|
21
|
+
*
|
|
22
|
+
* Usage:
|
|
23
|
+
* npx opentrace-copy-wasm <dest-dir>
|
|
24
|
+
* npx opentrace-copy-wasm public/
|
|
25
|
+
* npx opentrace-copy-wasm --languages python,typescript,go public/
|
|
26
|
+
*
|
|
27
|
+
* Options:
|
|
28
|
+
* --languages <list> Comma-separated list of languages to copy (default: all)
|
|
29
|
+
* --runtime-only Copy only the web-tree-sitter runtime WASM
|
|
30
|
+
* --help Show this help message
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
import { readdir, copyFile, mkdir } from 'node:fs/promises';
|
|
34
|
+
import { join, dirname, resolve } from 'node:path';
|
|
35
|
+
import { fileURLToPath } from 'node:url';
|
|
36
|
+
|
|
37
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
38
|
+
const __dirname = dirname(__filename);
|
|
39
|
+
const WASM_DIR = join(__dirname, '..', 'public', 'wasm');
|
|
40
|
+
|
|
41
|
+
function printUsage() {
|
|
42
|
+
console.log(`Usage: opentrace-copy-wasm [options] <dest-dir>
|
|
43
|
+
|
|
44
|
+
Copy tree-sitter WASM files to your app's public directory so they can
|
|
45
|
+
be served as static assets for browser-based code parsing.
|
|
46
|
+
|
|
47
|
+
Options:
|
|
48
|
+
--languages <list> Comma-separated list of languages (default: all)
|
|
49
|
+
Available: python, typescript, tsx, go, rust, java,
|
|
50
|
+
kotlin, ruby, c, cpp, csharp, swift, bash, json, toml
|
|
51
|
+
--runtime-only Copy only the web-tree-sitter.wasm runtime
|
|
52
|
+
--help Show this help message
|
|
53
|
+
|
|
54
|
+
Examples:
|
|
55
|
+
opentrace-copy-wasm public/
|
|
56
|
+
opentrace-copy-wasm --languages python,typescript,go public/
|
|
57
|
+
opentrace-copy-wasm --runtime-only public/`);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async function main() {
|
|
61
|
+
const args = process.argv.slice(2);
|
|
62
|
+
|
|
63
|
+
if (args.includes('--help') || args.length === 0) {
|
|
64
|
+
printUsage();
|
|
65
|
+
process.exit(args.includes('--help') ? 0 : 1);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
let languages = null;
|
|
69
|
+
let runtimeOnly = false;
|
|
70
|
+
let destDir = null;
|
|
71
|
+
|
|
72
|
+
for (let i = 0; i < args.length; i++) {
|
|
73
|
+
if (args[i] === '--languages' && i + 1 < args.length) {
|
|
74
|
+
languages = new Set(args[++i].split(',').map((s) => s.trim()));
|
|
75
|
+
} else if (args[i] === '--runtime-only') {
|
|
76
|
+
runtimeOnly = true;
|
|
77
|
+
} else if (!args[i].startsWith('-')) {
|
|
78
|
+
destDir = args[i];
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (!destDir) {
|
|
83
|
+
console.error('Error: destination directory is required');
|
|
84
|
+
printUsage();
|
|
85
|
+
process.exit(1);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const dest = resolve(destDir);
|
|
89
|
+
await mkdir(dest, { recursive: true });
|
|
90
|
+
|
|
91
|
+
const files = await readdir(WASM_DIR);
|
|
92
|
+
let copied = 0;
|
|
93
|
+
|
|
94
|
+
for (const file of files) {
|
|
95
|
+
if (!file.endsWith('.wasm')) continue;
|
|
96
|
+
|
|
97
|
+
// Always copy the runtime
|
|
98
|
+
if (file === 'web-tree-sitter.wasm') {
|
|
99
|
+
await copyFile(join(WASM_DIR, file), join(dest, file));
|
|
100
|
+
copied++;
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (runtimeOnly) continue;
|
|
105
|
+
|
|
106
|
+
// Filter by language if specified
|
|
107
|
+
if (languages) {
|
|
108
|
+
const lang = file
|
|
109
|
+
.replace('tree-sitter-', '')
|
|
110
|
+
.replace('.wasm', '')
|
|
111
|
+
.replace('c_sharp', 'csharp');
|
|
112
|
+
if (!languages.has(lang)) continue;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
await copyFile(join(WASM_DIR, file), join(dest, file));
|
|
116
|
+
copied++;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
console.log(`Copied ${copied} WASM file${copied !== 1 ? 's' : ''} to ${dest}`);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
main().catch((err) => {
|
|
123
|
+
console.error(err.message);
|
|
124
|
+
process.exit(1);
|
|
125
|
+
});
|