@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.
Files changed (111) hide show
  1. package/README.md +306 -0
  2. package/bin/copy-wasm.js +125 -0
  3. package/dist/opentrace-components.cjs +354 -246
  4. package/dist/opentrace-components.cjs.map +1 -1
  5. package/dist/opentrace-components.js +355 -247
  6. package/dist/opentrace-components.js.map +1 -1
  7. package/dist/pipeline-wasm.cjs +58 -0
  8. package/dist/pipeline-wasm.cjs.map +1 -0
  9. package/dist/pipeline-wasm.js +57 -0
  10. package/dist/pipeline-wasm.js.map +1 -0
  11. package/dist/pipeline.cjs +3481 -0
  12. package/dist/pipeline.cjs.map +1 -0
  13. package/dist/pipeline.js +3481 -0
  14. package/dist/pipeline.js.map +1 -0
  15. package/dist/src/GraphCanvas.d.ts +5 -0
  16. package/dist/src/GraphCanvas.d.ts.map +1 -1
  17. package/dist/src/colors/communityColors.d.ts.map +1 -1
  18. package/dist/src/config/graphLayout.d.ts +9 -9
  19. package/dist/src/config/graphLayout.d.ts.map +1 -1
  20. package/dist/src/graph/LayoutPipeline.d.ts +4 -6
  21. package/dist/src/graph/LayoutPipeline.d.ts.map +1 -1
  22. package/dist/src/graph/spacingWorker.d.ts +4 -0
  23. package/dist/src/graph/spacingWorker.d.ts.map +1 -1
  24. package/dist/src/graph/useGraphFilters.d.ts.map +1 -1
  25. package/dist/src/graph/useGraphInstance.d.ts.map +1 -1
  26. package/dist/src/graph/useGraphVisuals.d.ts.map +1 -1
  27. package/dist/src/index.d.ts +1 -1
  28. package/dist/src/index.d.ts.map +1 -1
  29. package/dist/src/pipeline/__tests__/cross-repo.test.d.ts +2 -0
  30. package/dist/src/pipeline/__tests__/cross-repo.test.d.ts.map +1 -0
  31. package/dist/src/pipeline/__tests__/fixture.test.d.ts +2 -0
  32. package/dist/src/pipeline/__tests__/fixture.test.d.ts.map +1 -0
  33. package/dist/src/pipeline/__tests__/github.test.d.ts +2 -0
  34. package/dist/src/pipeline/__tests__/github.test.d.ts.map +1 -0
  35. package/dist/src/pipeline/__tests__/helpers.d.ts +16 -0
  36. package/dist/src/pipeline/__tests__/helpers.d.ts.map +1 -0
  37. package/dist/src/pipeline/__tests__/loading.test.d.ts +2 -0
  38. package/dist/src/pipeline/__tests__/loading.test.d.ts.map +1 -0
  39. package/dist/src/pipeline/__tests__/parsing.test.d.ts +2 -0
  40. package/dist/src/pipeline/__tests__/parsing.test.d.ts.map +1 -0
  41. package/dist/src/pipeline/__tests__/pipeline.test.d.ts +2 -0
  42. package/dist/src/pipeline/__tests__/pipeline.test.d.ts.map +1 -0
  43. package/dist/src/pipeline/index.d.ts +19 -0
  44. package/dist/src/pipeline/index.d.ts.map +1 -0
  45. package/dist/src/pipeline/parser/callResolver.d.ts +52 -0
  46. package/dist/src/pipeline/parser/callResolver.d.ts.map +1 -0
  47. package/dist/src/pipeline/parser/extractors/generic.d.ts +15 -0
  48. package/dist/src/pipeline/parser/extractors/generic.d.ts.map +1 -0
  49. package/dist/src/pipeline/parser/extractors/go.d.ts +8 -0
  50. package/dist/src/pipeline/parser/extractors/go.d.ts.map +1 -0
  51. package/dist/src/pipeline/parser/extractors/python.d.ts +8 -0
  52. package/dist/src/pipeline/parser/extractors/python.d.ts.map +1 -0
  53. package/dist/src/pipeline/parser/extractors/typescript.d.ts +8 -0
  54. package/dist/src/pipeline/parser/extractors/typescript.d.ts.map +1 -0
  55. package/dist/src/pipeline/parser/importAnalyzer.d.ts +25 -0
  56. package/dist/src/pipeline/parser/importAnalyzer.d.ts.map +1 -0
  57. package/dist/src/pipeline/parser/manifestParser.d.ts +42 -0
  58. package/dist/src/pipeline/parser/manifestParser.d.ts.map +1 -0
  59. package/dist/src/pipeline/pipeline.d.ts +10 -0
  60. package/dist/src/pipeline/pipeline.d.ts.map +1 -0
  61. package/dist/src/pipeline/stages/loading.d.ts +6 -0
  62. package/dist/src/pipeline/stages/loading.d.ts.map +1 -0
  63. package/dist/src/pipeline/stages/parsing.d.ts +20 -0
  64. package/dist/src/pipeline/stages/parsing.d.ts.map +1 -0
  65. package/dist/src/pipeline/stages/processing.d.ts +15 -0
  66. package/dist/src/pipeline/stages/processing.d.ts.map +1 -0
  67. package/dist/src/pipeline/stages/resolving.d.ts +11 -0
  68. package/dist/src/pipeline/stages/resolving.d.ts.map +1 -0
  69. package/dist/src/pipeline/stages/saving.d.ts +7 -0
  70. package/dist/src/pipeline/stages/saving.d.ts.map +1 -0
  71. package/dist/src/pipeline/stages/scanning.d.ts +7 -0
  72. package/dist/src/pipeline/stages/scanning.d.ts.map +1 -0
  73. package/dist/src/pipeline/stages/summarizing.d.ts +16 -0
  74. package/dist/src/pipeline/stages/summarizing.d.ts.map +1 -0
  75. package/dist/src/pipeline/store/memory.d.ts +8 -0
  76. package/dist/src/pipeline/store/memory.d.ts.map +1 -0
  77. package/dist/src/pipeline/summarizer/templateSummarizer.d.ts +40 -0
  78. package/dist/src/pipeline/summarizer/templateSummarizer.d.ts.map +1 -0
  79. package/dist/src/pipeline/summarizer/types.d.ts +62 -0
  80. package/dist/src/pipeline/summarizer/types.d.ts.map +1 -0
  81. package/dist/src/pipeline/types.d.ts +119 -0
  82. package/dist/src/pipeline/types.d.ts.map +1 -0
  83. package/dist/src/pipeline/wasm.d.ts +14 -0
  84. package/dist/src/pipeline/wasm.d.ts.map +1 -0
  85. package/dist/src/sigma/useSelectionPulse.d.ts +3 -0
  86. package/dist/src/sigma/useSelectionPulse.d.ts.map +1 -0
  87. package/dist/{useHighlights-DbMfb0-p.js → useHighlights-CmOAWaLE.js} +60 -53
  88. package/dist/{useHighlights-DbMfb0-p.js.map → useHighlights-CmOAWaLE.js.map} +1 -1
  89. package/dist/{useHighlights-fRWg-A_c.cjs → useHighlights-zx7DM4V0.cjs} +60 -53
  90. package/dist/{useHighlights-fRWg-A_c.cjs.map → useHighlights-zx7DM4V0.cjs.map} +1 -1
  91. package/dist/utils.cjs +1 -1
  92. package/dist/utils.js +1 -1
  93. package/package.json +32 -4
  94. package/public/wasm/tree-sitter-bash.wasm +0 -0
  95. package/public/wasm/tree-sitter-c.wasm +0 -0
  96. package/public/wasm/tree-sitter-c_sharp.wasm +0 -0
  97. package/public/wasm/tree-sitter-cpp.wasm +0 -0
  98. package/public/wasm/tree-sitter-go.wasm +0 -0
  99. package/public/wasm/tree-sitter-java.wasm +0 -0
  100. package/public/wasm/tree-sitter-json.wasm +0 -0
  101. package/public/wasm/tree-sitter-kotlin.wasm +0 -0
  102. package/public/wasm/tree-sitter-python.wasm +0 -0
  103. package/public/wasm/tree-sitter-ruby.wasm +0 -0
  104. package/public/wasm/tree-sitter-rust.wasm +0 -0
  105. package/public/wasm/tree-sitter-swift.wasm +0 -0
  106. package/public/wasm/tree-sitter-toml.wasm +0 -0
  107. package/public/wasm/tree-sitter-tsx.wasm +0 -0
  108. package/public/wasm/tree-sitter-typescript.wasm +0 -0
  109. package/public/wasm/web-tree-sitter.wasm +0 -0
  110. package/dist/assets/spacingWorker-hXLGHyRg.js +0 -123
  111. 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).
@@ -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
+ });