@ruvector/ruvllm 2.6.0 → 2.6.2
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/cjs/engine.d.ts +2 -2
- package/dist/cjs/engine.d.ts.map +1 -1
- package/dist/cjs/engine.js +41 -19
- package/dist/cjs/native.d.ts +17 -8
- package/dist/cjs/native.d.ts.map +1 -1
- package/dist/cjs/native.js +1 -1
- package/dist/cjs/rlm/controller.d.ts +245 -0
- package/dist/cjs/rlm/controller.d.ts.map +1 -0
- package/dist/cjs/rlm/controller.js +554 -0
- package/dist/cjs/rlm/index.d.ts +62 -0
- package/dist/cjs/rlm/index.d.ts.map +1 -0
- package/dist/cjs/rlm/index.js +97 -0
- package/dist/cjs/rlm/training.d.ts +333 -0
- package/dist/cjs/rlm/training.d.ts.map +1 -0
- package/dist/cjs/rlm/training.js +680 -0
- package/dist/cjs/rlm/types.d.ts +189 -0
- package/dist/cjs/rlm/types.d.ts.map +1 -0
- package/dist/cjs/rlm/types.js +10 -0
- package/dist/cjs/types.d.ts +4 -2
- package/dist/cjs/types.d.ts.map +1 -1
- package/dist/cjs/types.js +1 -1
- package/dist/esm/benchmarks/index.d.ts +5 -5
- package/dist/esm/benchmarks/index.js +5 -5
- package/dist/esm/benchmarks/model-comparison.d.ts +2 -2
- package/dist/esm/benchmarks/model-comparison.js +2 -2
- package/dist/esm/contrastive.d.ts +1 -1
- package/dist/esm/engine.d.ts +2 -2
- package/dist/esm/engine.d.ts.map +1 -1
- package/dist/esm/engine.js +42 -20
- package/dist/esm/export.d.ts +2 -2
- package/dist/esm/federated.d.ts +1 -1
- package/dist/esm/federated.js +1 -1
- package/dist/esm/index.d.ts +16 -16
- package/dist/esm/index.js +16 -16
- package/dist/esm/lora.d.ts +1 -1
- package/dist/esm/native.d.ts +17 -8
- package/dist/esm/native.d.ts.map +1 -1
- package/dist/esm/native.js +1 -1
- package/dist/esm/rlm/controller.d.ts +245 -0
- package/dist/esm/rlm/controller.d.ts.map +1 -0
- package/dist/esm/rlm/controller.js +550 -0
- package/dist/esm/rlm/index.d.ts +62 -0
- package/dist/esm/rlm/index.d.ts.map +1 -0
- package/dist/esm/rlm/index.js +71 -0
- package/dist/esm/rlm/training.d.ts +333 -0
- package/dist/esm/rlm/training.d.ts.map +1 -0
- package/dist/esm/rlm/training.js +672 -0
- package/dist/esm/rlm/types.d.ts +189 -0
- package/dist/esm/rlm/types.d.ts.map +1 -0
- package/dist/esm/rlm/types.js +9 -0
- package/dist/esm/session.d.ts +1 -1
- package/dist/esm/simd.js +1 -1
- package/dist/esm/sona.d.ts +1 -1
- package/dist/esm/sona.js +1 -1
- package/dist/esm/streaming.d.ts +1 -1
- package/dist/esm/training.d.ts +3 -3
- package/dist/esm/training.js +2 -2
- package/dist/esm/types.d.ts +4 -2
- package/dist/esm/types.d.ts.map +1 -1
- package/dist/esm/types.js +1 -1
- package/package.json +4 -2
- package/scripts/fix-esm-extensions.mjs +181 -0
- package/scripts/smoke-esm.mjs +82 -0
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Post-build fixer for the ESM output of this package (#656).
|
|
4
|
+
*
|
|
5
|
+
* `tsconfig.esm.json` compiles with `"module": "ESNext"` +
|
|
6
|
+
* `"moduleResolution": "Node"` (classic resolution). In that mode
|
|
7
|
+
* TypeScript does not rewrite relative import/export specifiers to
|
|
8
|
+
* include a file extension, so the emitted `dist/esm/*.js` files contain
|
|
9
|
+
* specifiers like `from './types'`. Node's native ESM resolver requires an
|
|
10
|
+
* explicit extension for relative specifiers, so `import('@ruvector/ruvllm')`
|
|
11
|
+
* from a `"type": "module"` consumer throws `ERR_MODULE_NOT_FOUND`.
|
|
12
|
+
*
|
|
13
|
+
* This script walks the compiled `dist/esm/` tree after `tsc` runs and
|
|
14
|
+
* rewrites every extensionless relative specifier to whatever actually
|
|
15
|
+
* exists on disk (`<spec>.js` or `<spec>/index.js`), in both `.js` and
|
|
16
|
+
* `.d.ts` files — declaration files need the same `.js`-suffixed
|
|
17
|
+
* specifiers (the TypeScript NodeNext convention) even though they only
|
|
18
|
+
* carry types, so that consumers' type-checkers resolve them too.
|
|
19
|
+
*
|
|
20
|
+
* Zero external dependencies: only `node:fs`, `node:path`, `node:url`.
|
|
21
|
+
*
|
|
22
|
+
* Usage:
|
|
23
|
+
* node scripts/fix-esm-extensions.mjs # rewrite in place
|
|
24
|
+
* node scripts/fix-esm-extensions.mjs --verify # assert-only, no writes
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
import { readdirSync, statSync, readFileSync, writeFileSync } from 'node:fs';
|
|
28
|
+
import { join, extname, dirname } from 'node:path';
|
|
29
|
+
import { fileURLToPath } from 'node:url';
|
|
30
|
+
|
|
31
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
32
|
+
const DIST_ESM = join(__dirname, '..', 'dist', 'esm');
|
|
33
|
+
const VERIFY = process.argv.includes('--verify');
|
|
34
|
+
|
|
35
|
+
// Matches the specifier in `... from '<spec>'` / `... from "<spec>"` —
|
|
36
|
+
// covers `import X from`, `import { a } from`, `export { a } from`,
|
|
37
|
+
// `export * from`, `export * as ns from`.
|
|
38
|
+
const FROM_SPEC_RE = /\bfrom(\s*)(['"])(\.[^'"]+)\2/g;
|
|
39
|
+
|
|
40
|
+
// Matches a side-effect import: `import '<spec>';` — the bare form with no
|
|
41
|
+
// bindings and no `from` clause, anchored to the start of a line.
|
|
42
|
+
const SIDE_EFFECT_SPEC_RE = /^(\s*)import(\s*)(['"])(\.[^'"]+)\3/gm;
|
|
43
|
+
|
|
44
|
+
function walk(dir, out = []) {
|
|
45
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
46
|
+
const full = join(dir, entry.name);
|
|
47
|
+
if (entry.isDirectory()) {
|
|
48
|
+
walk(full, out);
|
|
49
|
+
} else if (entry.isFile() && (full.endsWith('.js') || full.endsWith('.d.ts'))) {
|
|
50
|
+
out.push(full);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return out;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function existsFile(p) {
|
|
57
|
+
try {
|
|
58
|
+
return statSync(p).isFile();
|
|
59
|
+
} catch {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Only extensionless relative specifiers are our concern; anything already
|
|
65
|
+
// carrying an extension (e.g. already-fixed `.js`, or a hypothetical
|
|
66
|
+
// `.json`) is left untouched — this is what makes the script idempotent.
|
|
67
|
+
function needsFix(spec) {
|
|
68
|
+
return (spec.startsWith('./') || spec.startsWith('../')) && extname(spec) === '';
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Resolve an extensionless relative specifier against the directory of the
|
|
72
|
+
// file that references it, against what actually exists in the compiled
|
|
73
|
+
// dist/esm tree. Returns the rewritten specifier, or null if neither the
|
|
74
|
+
// `<spec>.js` file nor the `<spec>/index.js` barrel exists on disk.
|
|
75
|
+
function resolveSpecifier(fileDir, spec) {
|
|
76
|
+
const asFile = join(fileDir, `${spec}.js`);
|
|
77
|
+
if (existsFile(asFile)) return `${spec}.js`;
|
|
78
|
+
const asIndex = join(fileDir, spec, 'index.js');
|
|
79
|
+
if (existsFile(asIndex)) return `${spec}/index.js`;
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Scans `text` for extensionless relative specifiers via both patterns.
|
|
84
|
+
// `onSpec(spec)` is called for each one found; if it returns a string, that
|
|
85
|
+
// string replaces the specifier's quoted body in the output. Returns
|
|
86
|
+
// { text, violations } where `violations` lists specifiers `onSpec`
|
|
87
|
+
// declined to rewrite (returned a falsy value).
|
|
88
|
+
function scanAndRewrite(source, onSpec) {
|
|
89
|
+
const violations = [];
|
|
90
|
+
|
|
91
|
+
const rewriteFrom = (fullMatch, ws, quote, spec) => {
|
|
92
|
+
if (!needsFix(spec)) return fullMatch;
|
|
93
|
+
const replacement = onSpec(spec);
|
|
94
|
+
if (!replacement) {
|
|
95
|
+
violations.push(spec);
|
|
96
|
+
return fullMatch;
|
|
97
|
+
}
|
|
98
|
+
return `from${ws}${quote}${replacement}${quote}`;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
const rewriteSideEffect = (fullMatch, lead, ws, quote, spec) => {
|
|
102
|
+
if (!needsFix(spec)) return fullMatch;
|
|
103
|
+
const replacement = onSpec(spec);
|
|
104
|
+
if (!replacement) {
|
|
105
|
+
violations.push(spec);
|
|
106
|
+
return fullMatch;
|
|
107
|
+
}
|
|
108
|
+
return `${lead}import${ws}${quote}${replacement}${quote}`;
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
let text = source.replace(FROM_SPEC_RE, rewriteFrom);
|
|
112
|
+
text = text.replace(SIDE_EFFECT_SPEC_RE, rewriteSideEffect);
|
|
113
|
+
|
|
114
|
+
return { text, violations };
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function fixFile(file) {
|
|
118
|
+
const dir = dirname(file);
|
|
119
|
+
const original = readFileSync(file, 'utf8');
|
|
120
|
+
|
|
121
|
+
const { text, violations } = scanAndRewrite(original, (spec) => resolveSpecifier(dir, spec));
|
|
122
|
+
|
|
123
|
+
if (violations.length > 0) {
|
|
124
|
+
for (const spec of violations) {
|
|
125
|
+
console.error(
|
|
126
|
+
`fix-esm-extensions: cannot resolve relative specifier '${spec}' referenced from ${file} ` +
|
|
127
|
+
`(looked for '${spec}.js' and '${spec}/index.js' in ${dir})`
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
process.exit(1);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (text !== original) {
|
|
134
|
+
writeFileSync(file, text, 'utf8');
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function verifyFile(file) {
|
|
141
|
+
const remaining = [];
|
|
142
|
+
// In verify mode we don't need resolution at all: any extensionless
|
|
143
|
+
// relative specifier still present after the fix step is itself the
|
|
144
|
+
// failure condition.
|
|
145
|
+
scanAndRewrite(readFileSync(file, 'utf8'), (spec) => {
|
|
146
|
+
remaining.push(spec);
|
|
147
|
+
return null; // never rewrite in verify mode; force it into `violations`
|
|
148
|
+
});
|
|
149
|
+
return remaining.map((spec) => ({ file, spec }));
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function main() {
|
|
153
|
+
let files;
|
|
154
|
+
try {
|
|
155
|
+
files = walk(DIST_ESM);
|
|
156
|
+
} catch (err) {
|
|
157
|
+
console.error(`fix-esm-extensions: cannot read ${DIST_ESM}: ${err.message}`);
|
|
158
|
+
process.exit(1);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (VERIFY) {
|
|
162
|
+
const remaining = files.flatMap(verifyFile);
|
|
163
|
+
if (remaining.length > 0) {
|
|
164
|
+
for (const { file, spec } of remaining) {
|
|
165
|
+
console.error(`fix-esm-extensions --verify: extensionless relative specifier '${spec}' in ${file}`);
|
|
166
|
+
}
|
|
167
|
+
console.error(`fix-esm-extensions --verify: FAILED — ${remaining.length} extensionless specifier(s) remain`);
|
|
168
|
+
process.exit(1);
|
|
169
|
+
}
|
|
170
|
+
console.log(`fix-esm-extensions --verify: OK — 0 extensionless relative specifiers across ${files.length} files`);
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
let changed = 0;
|
|
175
|
+
for (const file of files) {
|
|
176
|
+
if (fixFile(file)) changed += 1;
|
|
177
|
+
}
|
|
178
|
+
console.log(`fix-esm-extensions: rewrote ${changed}/${files.length} file(s) under dist/esm`);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
main();
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* CI smoke test for the ESM entry point (#656).
|
|
4
|
+
*
|
|
5
|
+
* Regresses the bug where `dist/esm/*.js` emitted extensionless relative
|
|
6
|
+
* specifiers, which made `import('@ruvector/ruvllm')` throw
|
|
7
|
+
* `ERR_MODULE_NOT_FOUND` under Node's native ESM resolver.
|
|
8
|
+
*
|
|
9
|
+
* This packs the current working tree with `npm pack`, installs the
|
|
10
|
+
* resulting tarball into a scratch directory whose own package.json
|
|
11
|
+
* declares `"type": "module"`, then dynamically imports the package
|
|
12
|
+
* exactly the way a real ESM consumer would and asserts the default
|
|
13
|
+
* export exists.
|
|
14
|
+
*
|
|
15
|
+
* NOTE: this requires the native napi `.node` addon to be present (built by
|
|
16
|
+
* the `build:native` npm script / the platform CI job) so that loading the
|
|
17
|
+
* compiled engine at import time succeeds. It is meant to run in CI after
|
|
18
|
+
* the native build step, not necessarily in a bare local checkout without
|
|
19
|
+
* a prebuilt addon.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import { execFileSync } from 'node:child_process';
|
|
23
|
+
import { mkdtempSync, writeFileSync, rmSync } from 'node:fs';
|
|
24
|
+
import { tmpdir } from 'node:os';
|
|
25
|
+
import { join } from 'node:path';
|
|
26
|
+
import { fileURLToPath } from 'node:url';
|
|
27
|
+
|
|
28
|
+
const PKG_ROOT = fileURLToPath(new URL('..', import.meta.url));
|
|
29
|
+
|
|
30
|
+
function main() {
|
|
31
|
+
console.log('smoke-esm: packing package with `npm pack`...');
|
|
32
|
+
const packOutput = execFileSync('npm', ['pack', '--json'], {
|
|
33
|
+
cwd: PKG_ROOT,
|
|
34
|
+
encoding: 'utf8',
|
|
35
|
+
});
|
|
36
|
+
const [{ filename }] = JSON.parse(packOutput);
|
|
37
|
+
const tarballPath = join(PKG_ROOT, filename);
|
|
38
|
+
|
|
39
|
+
const scratch = mkdtempSync(join(tmpdir(), 'ruvllm-esm-smoke-'));
|
|
40
|
+
|
|
41
|
+
try {
|
|
42
|
+
writeFileSync(
|
|
43
|
+
join(scratch, 'package.json'),
|
|
44
|
+
JSON.stringify(
|
|
45
|
+
{ name: 'ruvllm-esm-smoke', version: '0.0.0', private: true, type: 'module' },
|
|
46
|
+
null,
|
|
47
|
+
2
|
|
48
|
+
)
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
console.log('smoke-esm: installing tarball into scratch dir (as a "type":"module" consumer)...');
|
|
52
|
+
execFileSync(
|
|
53
|
+
'npm',
|
|
54
|
+
['install', '--no-audit', '--no-fund', '--no-package-lock', '--no-save', tarballPath],
|
|
55
|
+
{ cwd: scratch, stdio: 'inherit' }
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
console.log('smoke-esm: dynamically importing @ruvector/ruvllm...');
|
|
59
|
+
const assertionScript = [
|
|
60
|
+
"import('@ruvector/ruvllm').then((mod) => {",
|
|
61
|
+
" if (typeof mod.default === 'undefined') {",
|
|
62
|
+
" console.error('smoke-esm: FAIL - default export is undefined');",
|
|
63
|
+
' process.exit(1);',
|
|
64
|
+
' }',
|
|
65
|
+
" console.log('smoke-esm: OK - import() resolved, default export is', typeof mod.default);",
|
|
66
|
+
'}).catch((err) => {',
|
|
67
|
+
" console.error('smoke-esm: FAIL -', (err && err.stack) || err);",
|
|
68
|
+
' process.exit(1);',
|
|
69
|
+
'});',
|
|
70
|
+
].join('\n');
|
|
71
|
+
|
|
72
|
+
execFileSync(process.execPath, ['--input-type=module', '-e', assertionScript], {
|
|
73
|
+
cwd: scratch,
|
|
74
|
+
stdio: 'inherit',
|
|
75
|
+
});
|
|
76
|
+
} finally {
|
|
77
|
+
rmSync(tarballPath, { force: true });
|
|
78
|
+
rmSync(scratch, { recursive: true, force: true });
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
main();
|