relaxnative 0.1.0-beta.1

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 (130) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +592 -0
  3. package/dist/chunk-22W76CYR.js +607 -0
  4. package/dist/chunk-24NXCU65.js +254 -0
  5. package/dist/chunk-2APMRURB.js +65 -0
  6. package/dist/chunk-2CHBHJPT.js +607 -0
  7. package/dist/chunk-2I4JHZI7.js +287 -0
  8. package/dist/chunk-2JOHYYQO.js +607 -0
  9. package/dist/chunk-3GW77EWF.js +505 -0
  10. package/dist/chunk-5J5CAKCD.js +266 -0
  11. package/dist/chunk-5NTDZ7YZ.js +377 -0
  12. package/dist/chunk-5TA6MROS.js +529 -0
  13. package/dist/chunk-5WVEBKMJ.js +1019 -0
  14. package/dist/chunk-6O5TIEEI.js +545 -0
  15. package/dist/chunk-6XU5DETO.js +896 -0
  16. package/dist/chunk-7BIZ6P3B.js +176 -0
  17. package/dist/chunk-7DKO777J.js +285 -0
  18. package/dist/chunk-7JYWUH4Y.js +268 -0
  19. package/dist/chunk-7NMCEP2V.js +756 -0
  20. package/dist/chunk-A7N4YBP2.js +379 -0
  21. package/dist/chunk-AZTCDV6R.js +572 -0
  22. package/dist/chunk-B34XEGM6.js +559 -0
  23. package/dist/chunk-BFHBLVXW.js +607 -0
  24. package/dist/chunk-BLOJ33LO.js +65 -0
  25. package/dist/chunk-BYPXCWTI.js +375 -0
  26. package/dist/chunk-C4KJD2AN.js +1044 -0
  27. package/dist/chunk-CJALJTRQ.js +814 -0
  28. package/dist/chunk-D4PK367Z.js +627 -0
  29. package/dist/chunk-DCWBZPEV.js +287 -0
  30. package/dist/chunk-DI7KSUEC.js +676 -0
  31. package/dist/chunk-DQ2KXIOO.js +665 -0
  32. package/dist/chunk-DV5STE3W.js +986 -0
  33. package/dist/chunk-EG5KNEKP.js +1027 -0
  34. package/dist/chunk-EOA2OWFA.js +1020 -0
  35. package/dist/chunk-ES3B6EZJ.js +56 -0
  36. package/dist/chunk-ETIXNPU5.js +741 -0
  37. package/dist/chunk-EUZBU2H7.js +824 -0
  38. package/dist/chunk-F6V7XDEB.js +150 -0
  39. package/dist/chunk-FNJKUFNF.js +1019 -0
  40. package/dist/chunk-FZB37DWL.js +453 -0
  41. package/dist/chunk-G3NDHZNZ.js +453 -0
  42. package/dist/chunk-G4YR34LE.js +410 -0
  43. package/dist/chunk-GU4XXISM.js +264 -0
  44. package/dist/chunk-GVPSQXGJ.js +1027 -0
  45. package/dist/chunk-HD5C4RNU.js +676 -0
  46. package/dist/chunk-HDIVY47T.js +287 -0
  47. package/dist/chunk-HFLRTDNK.js +985 -0
  48. package/dist/chunk-HGWRCVQ5.js +287 -0
  49. package/dist/chunk-HRG3SVKK.js +995 -0
  50. package/dist/chunk-HUGFULJ3.js +1027 -0
  51. package/dist/chunk-IDYSBXYS.js +344 -0
  52. package/dist/chunk-ISDDUQVI.js +1019 -0
  53. package/dist/chunk-IZ632ZCJ.js +286 -0
  54. package/dist/chunk-J5XI4L52.js +218 -0
  55. package/dist/chunk-JTIO7BUH.js +582 -0
  56. package/dist/chunk-JTWSFMF2.js +1020 -0
  57. package/dist/chunk-K5TV62T4.js +736 -0
  58. package/dist/chunk-K7MTG53V.js +985 -0
  59. package/dist/chunk-KGLZB3H2.js +676 -0
  60. package/dist/chunk-KYAB35P5.js +741 -0
  61. package/dist/chunk-KYDW3YVX.js +453 -0
  62. package/dist/chunk-L3MEMPRH.js +361 -0
  63. package/dist/chunk-LFTO3Z7N.js +757 -0
  64. package/dist/chunk-LLZ4I4OR.js +405 -0
  65. package/dist/chunk-LMRUM4U4.js +207 -0
  66. package/dist/chunk-LT5OGU6T.js +559 -0
  67. package/dist/chunk-LZQQOC3M.js +741 -0
  68. package/dist/chunk-LZYUNF6Q.js +1017 -0
  69. package/dist/chunk-MCTPVW4G.js +453 -0
  70. package/dist/chunk-MGLWXBIB.js +65 -0
  71. package/dist/chunk-MLKGABMK.js +9 -0
  72. package/dist/chunk-MTE6XDGC.js +541 -0
  73. package/dist/chunk-NDJUNDAE.js +676 -0
  74. package/dist/chunk-NG7SNFUD.js +1027 -0
  75. package/dist/chunk-ONVWKYK7.js +739 -0
  76. package/dist/chunk-OVMTFGE7.js +1042 -0
  77. package/dist/chunk-P5RQPRJ4.js +741 -0
  78. package/dist/chunk-PFABSW6Y.js +401 -0
  79. package/dist/chunk-PVVUJA2M.js +65 -0
  80. package/dist/chunk-Q3CDTGTX.js +676 -0
  81. package/dist/chunk-QKAKWDOQ.js +967 -0
  82. package/dist/chunk-QMPRDU6I.js +598 -0
  83. package/dist/chunk-R5U7XKVJ.js +16 -0
  84. package/dist/chunk-RB6RHB6C.js +254 -0
  85. package/dist/chunk-RD2K7ODW.js +175 -0
  86. package/dist/chunk-RHBHJND2.js +582 -0
  87. package/dist/chunk-RUP6POSE.js +453 -0
  88. package/dist/chunk-RYNSM23L.js +582 -0
  89. package/dist/chunk-S72S7XXS.js +255 -0
  90. package/dist/chunk-SDV5AAPW.js +213 -0
  91. package/dist/chunk-STXQPXUY.js +242 -0
  92. package/dist/chunk-TUSF5AEG.js +140 -0
  93. package/dist/chunk-V74SNTE6.js +736 -0
  94. package/dist/chunk-VHM5XETC.js +453 -0
  95. package/dist/chunk-VKQIXLNL.js +273 -0
  96. package/dist/chunk-VPG23Z7Y.js +545 -0
  97. package/dist/chunk-VSP234PR.js +627 -0
  98. package/dist/chunk-WH4JPUWF.js +598 -0
  99. package/dist/chunk-WLAUJL3K.js +409 -0
  100. package/dist/chunk-WXCN2QJ7.js +350 -0
  101. package/dist/chunk-X3JZKLJC.js +896 -0
  102. package/dist/chunk-X7SAP7FC.js +582 -0
  103. package/dist/chunk-XEH6PRYE.js +968 -0
  104. package/dist/chunk-XI65CAQV.js +211 -0
  105. package/dist/chunk-Y7OSHR6W.js +235 -0
  106. package/dist/chunk-YN4WUMVD.js +1020 -0
  107. package/dist/chunk-YUWJ2C4Y.js +1020 -0
  108. package/dist/chunk-YXLBPWNU.js +263 -0
  109. package/dist/chunk-YYJJHO7R.js +407 -0
  110. package/dist/chunk-Z2RBHUIH.js +757 -0
  111. package/dist/chunk-Z6G3KIOM.js +1027 -0
  112. package/dist/chunk-ZPPXCDSH.js +361 -0
  113. package/dist/chunk-ZRTY24SZ.js +582 -0
  114. package/dist/chunk-ZSDFBCQG.js +741 -0
  115. package/dist/cli.d.ts +1 -0
  116. package/dist/cli.js +339 -0
  117. package/dist/esmLoader.d.ts +10 -0
  118. package/dist/esmLoader.js +112 -0
  119. package/dist/index.d.ts +407 -0
  120. package/dist/index.js +126 -0
  121. package/dist/memory/memory.selftest.d.ts +2 -0
  122. package/dist/memory/memory.selftest.js +25 -0
  123. package/dist/worker/processEntry.d.ts +2 -0
  124. package/dist/worker/processEntry.js +160 -0
  125. package/dist/worker/workerEntry.d.ts +2 -0
  126. package/dist/worker/workerEntry.js +27 -0
  127. package/native/examples/add.c +6 -0
  128. package/native/examples/add_test.c +23 -0
  129. package/native/relaxnative_test.h +36 -0
  130. package/package.json +81 -0
@@ -0,0 +1,401 @@
1
+ import {
2
+ compileWithCache,
3
+ detectCompilers,
4
+ detectLanguage,
5
+ loadNative,
6
+ parseNativeSource
7
+ } from "./chunk-3GW77EWF.js";
8
+ import {
9
+ loadFfi
10
+ } from "./chunk-WXCN2QJ7.js";
11
+
12
+ // src/registry/registryPaths.ts
13
+ import { join, resolve } from "path";
14
+ function getProjectRoot(cwd = process.cwd()) {
15
+ return cwd;
16
+ }
17
+ function getRegistryRoot(projectRoot = getProjectRoot()) {
18
+ return join(projectRoot, "native", "registry");
19
+ }
20
+ function getInstalledPackageDir(pkg, projectRoot = getProjectRoot()) {
21
+ return join(getRegistryRoot(projectRoot), pkg);
22
+ }
23
+ function resolveRegistryImport(specifier, projectRoot = getProjectRoot()) {
24
+ const prefix = "relaxnative/";
25
+ if (!specifier.startsWith(prefix)) return null;
26
+ const pkg = specifier.slice(prefix.length);
27
+ return resolve(getInstalledPackageDir(pkg, projectRoot));
28
+ }
29
+
30
+ // src/registry/relaxJson.ts
31
+ import { readFileSync } from "fs";
32
+ import { join as join2 } from "path";
33
+ function readRelaxJson(pkgDir) {
34
+ const jsonPath = join2(pkgDir, "relax.json");
35
+ const raw = readFileSync(jsonPath, "utf8");
36
+ const parsed = JSON.parse(raw);
37
+ if (!parsed?.name || !parsed?.version || !Array.isArray(parsed?.exports)) {
38
+ throw new Error(`Invalid relax.json at ${jsonPath}`);
39
+ }
40
+ return parsed;
41
+ }
42
+
43
+ // src/registry/installer.ts
44
+ import {
45
+ mkdirSync,
46
+ readFileSync as readFileSync3,
47
+ rmSync,
48
+ writeFileSync,
49
+ existsSync,
50
+ readdirSync
51
+ } from "fs";
52
+ import { join as join3 } from "path";
53
+
54
+ // src/registry/staticScan.ts
55
+ import { readFileSync as readFileSync2 } from "fs";
56
+ function staticScanNativeSource(sourcePath) {
57
+ const src = readFileSync2(sourcePath, "utf8");
58
+ const lines = src.split(/\r?\n/);
59
+ const rules = [
60
+ {
61
+ rule: "process-spawn",
62
+ re: /\b(system|popen|fork|execv|execve|execvp|execvpe|execl|execlp|CreateProcessW|WinExec)\b/,
63
+ message: "Potential process execution API found"
64
+ },
65
+ {
66
+ rule: "raw-syscall",
67
+ re: /\b(syscall|__syscall)\b/,
68
+ message: "Raw syscall usage found"
69
+ },
70
+ {
71
+ rule: "file-io",
72
+ re: /\b(fopen|open|CreateFileW|unlink|remove|rename)\b/,
73
+ message: "Potential filesystem API found"
74
+ },
75
+ {
76
+ rule: "network",
77
+ re: /\b(socket|connect|bind|listen|accept|recv|send|getaddrinfo)\b/,
78
+ message: "Potential network API found"
79
+ },
80
+ {
81
+ rule: "w-x-memory",
82
+ re: /\b(mprotect|VirtualProtect|PROT_EXEC|PAGE_EXECUTE_READWRITE)\b/,
83
+ message: "Writable/executable memory pattern found"
84
+ },
85
+ {
86
+ rule: "dynamic-loader",
87
+ re: /\b(dlopen|LoadLibraryA|LoadLibraryW)\b/,
88
+ message: "Dynamic loader API found"
89
+ }
90
+ ];
91
+ const findings = [];
92
+ for (let i = 0; i < lines.length; i++) {
93
+ const line = lines[i];
94
+ for (const r of rules) {
95
+ if (r.re.test(line)) {
96
+ findings.push({ rule: r.rule, message: r.message, line: i + 1 });
97
+ }
98
+ }
99
+ }
100
+ return findings;
101
+ }
102
+
103
+ // src/registry/installer.ts
104
+ function installPackage(pkgSpecifier, projectRoot = process.cwd()) {
105
+ const warnings = [];
106
+ const registryRoot = getRegistryRoot(projectRoot);
107
+ mkdirSync(registryRoot, { recursive: true });
108
+ const isFile = pkgSpecifier.startsWith("file:");
109
+ if (!isFile) {
110
+ throw new Error(
111
+ `Only file: installs are supported right now (deterministic, offline). Got: ${pkgSpecifier}`
112
+ );
113
+ }
114
+ const srcDir = pkgSpecifier.slice("file:".length);
115
+ const manifest = readRelaxJson(srcDir);
116
+ const destDir = getInstalledPackageDir(manifest.name, projectRoot);
117
+ rmSync(destDir, { recursive: true, force: true });
118
+ mkdirSync(destDir, { recursive: true });
119
+ writeFileSync(join3(destDir, "relax.json"), readFileSync3(join3(srcDir, "relax.json")));
120
+ for (const exp of manifest.exports) {
121
+ const srcPath = join3(srcDir, exp.source);
122
+ const dstPath = join3(destDir, exp.source);
123
+ mkdirSync(join3(dstPath, ".."), { recursive: true });
124
+ if (!existsSync(srcPath)) {
125
+ throw new Error(`Missing export source: ${srcPath}`);
126
+ }
127
+ const findings = staticScanNativeSource(srcPath);
128
+ for (const f of findings) {
129
+ warnings.push(`${exp.source}:${f.line ?? "?"} ${f.rule}: ${f.message}`);
130
+ }
131
+ writeFileSync(dstPath, readFileSync3(srcPath));
132
+ }
133
+ return { pkg: manifest.name, dir: destDir, warnings };
134
+ }
135
+ function removePackage(pkg, projectRoot = process.cwd()) {
136
+ const destDir = getInstalledPackageDir(pkg, projectRoot);
137
+ rmSync(destDir, { recursive: true, force: true });
138
+ }
139
+ function listPackages(projectRoot = process.cwd()) {
140
+ const root = getRegistryRoot(projectRoot);
141
+ if (!existsSync(root)) return [];
142
+ return readdirSync(root, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name).sort();
143
+ }
144
+ function updateIndex(projectRoot = process.cwd()) {
145
+ const root = getRegistryRoot(projectRoot);
146
+ if (!existsSync(root)) return;
147
+ const pkgs = listPackages(projectRoot);
148
+ writeFileSync(join3(root, ".index"), pkgs.join("\n") + (pkgs.length ? "\n" : ""));
149
+ }
150
+
151
+ // src/nativeTestHarness.ts
152
+ import { readdirSync as readdirSync2, existsSync as existsSync2, readFileSync as readFileSync4 } from "fs";
153
+ import { extname, join as join4 } from "path";
154
+ var NATIVE_EXTS = /* @__PURE__ */ new Set([".c", ".cpp", ".cc", ".cxx", ".rs"]);
155
+ function isNativeFile(p) {
156
+ return NATIVE_EXTS.has(extname(p));
157
+ }
158
+ function discoverNativeTestFiles(rootDir) {
159
+ const out = [];
160
+ function walk(dir) {
161
+ for (const ent of readdirSync2(dir, { withFileTypes: true })) {
162
+ const p = join4(dir, ent.name);
163
+ if (ent.isDirectory()) walk(p);
164
+ else if (ent.isFile() && isNativeFile(p)) out.push(p);
165
+ }
166
+ }
167
+ if (!existsSync2(rootDir)) return [];
168
+ walk(rootDir);
169
+ out.sort((a, b) => {
170
+ const at = /_test\./.test(a) ? 0 : 1;
171
+ const bt = /_test\./.test(b) ? 0 : 1;
172
+ return at - bt || a.localeCompare(b);
173
+ });
174
+ return out;
175
+ }
176
+ function discoverNativeTestsFromFile(sourcePath) {
177
+ const language = detectLanguage(sourcePath);
178
+ const bindings = parseNativeSource(sourcePath, language);
179
+ const tests = [];
180
+ for (const [name, fn] of Object.entries(bindings.functions ?? {})) {
181
+ if (!name.startsWith("test_")) continue;
182
+ const ret = fn.returns;
183
+ let kind = null;
184
+ if (ret === "int" || ret === "uint" || ret === "long" || ret === "size_t") kind = "int";
185
+ if (ret === "cstring" || ret === "char*") kind = "cstring";
186
+ if (!kind) continue;
187
+ tests.push({
188
+ name,
189
+ sourcePath,
190
+ line: fn.sourceLine,
191
+ kind
192
+ });
193
+ }
194
+ return tests;
195
+ }
196
+ function discoverNativeTests(rootDir) {
197
+ const files = discoverNativeTestFiles(rootDir);
198
+ const all = [];
199
+ for (const f of files) {
200
+ all.push(...discoverNativeTestsFromFile(f));
201
+ }
202
+ return all;
203
+ }
204
+ function formatLocation(sourcePath, line) {
205
+ if (!line) return sourcePath;
206
+ return `${sourcePath}:${line}`;
207
+ }
208
+ function formatNativeTestResults(results) {
209
+ const lines = [];
210
+ for (const r of results) {
211
+ if (r.ok) {
212
+ lines.push(`\u2713 ${r.name}`);
213
+ } else {
214
+ const loc = formatLocation(r.sourcePath, r.line);
215
+ const msg = r.message ? ` (${r.message})` : "";
216
+ lines.push(`\u2717 ${r.name}${msg}`);
217
+ lines.push(` at ${loc}`);
218
+ }
219
+ }
220
+ const passed = results.filter((r) => r.ok).length;
221
+ const failed = results.length - passed;
222
+ lines.push("");
223
+ lines.push(`${passed} passed, ${failed} failed`);
224
+ return lines.join("\n");
225
+ }
226
+ async function runNativeTests(rootDir, opts) {
227
+ const tests = discoverNativeTests(rootDir);
228
+ if (!tests.length) {
229
+ return { results: [], exitCode: 0 };
230
+ }
231
+ const { c, rust, platform } = detectCompilers();
232
+ const byFile = /* @__PURE__ */ new Map();
233
+ for (const t of tests) {
234
+ const arr = byFile.get(t.sourcePath) ?? [];
235
+ arr.push(t);
236
+ byFile.set(t.sourcePath, arr);
237
+ }
238
+ const results = [];
239
+ for (const [sourcePath, cases] of byFile) {
240
+ const language = detectLanguage(sourcePath);
241
+ const compiler = language === "rust" ? rust : c;
242
+ if (!compiler) throw new Error(`No compiler for ${language}`);
243
+ const compileRes = compileWithCache(compiler, platform, {
244
+ sourcePath,
245
+ outDir: ".cache/native"
246
+ });
247
+ const bindings = parseNativeSource(sourcePath, language);
248
+ const api = loadFfi(compileRes.outputPath, bindings);
249
+ for (const tc of cases) {
250
+ const fn = api[tc.name];
251
+ if (typeof fn !== "function") continue;
252
+ const start = process.hrtime.bigint();
253
+ let ok = false;
254
+ let message;
255
+ try {
256
+ const out = fn();
257
+ if (tc.kind === "int") {
258
+ ok = Number(out) === 0;
259
+ if (!ok) message = `returned ${String(out)}`;
260
+ } else {
261
+ ok = out == null || String(out).length === 0;
262
+ if (!ok) message = String(out);
263
+ }
264
+ } catch (err) {
265
+ ok = false;
266
+ message = err?.message ?? String(err);
267
+ }
268
+ const end = process.hrtime.bigint();
269
+ const durationMs = Number(end - start) / 1e6;
270
+ results.push({
271
+ name: tc.name,
272
+ ok,
273
+ message,
274
+ sourcePath: tc.sourcePath,
275
+ line: tc.line,
276
+ durationMs
277
+ });
278
+ }
279
+ }
280
+ const failed = results.some((r) => !r.ok);
281
+ return { results, exitCode: failed ? 1 : 0 };
282
+ }
283
+ function getSourceLine(sourcePath, line) {
284
+ if (!line) return null;
285
+ try {
286
+ const src = readFileSync4(sourcePath, "utf8");
287
+ const lines = src.split(/\r?\n/);
288
+ return lines[line - 1] ?? null;
289
+ } catch {
290
+ return null;
291
+ }
292
+ }
293
+
294
+ // src/benchmark.ts
295
+ function nowNs() {
296
+ return process.hrtime.bigint();
297
+ }
298
+ function nsToMs(ns) {
299
+ return Number(ns) / 1e6;
300
+ }
301
+ function assertSafeRun(iterations) {
302
+ if (iterations > 2e6) {
303
+ throw new Error(
304
+ `Refusing to run benchmark with iterations=${iterations} (cap=2,000,000). Pass a smaller value.`
305
+ );
306
+ }
307
+ }
308
+ async function benchmarkNativeFunction(nativePath, fnName, opts) {
309
+ const iterations = opts?.iterations ?? 1e5;
310
+ const warmup = opts?.warmup ?? Math.min(1e4, Math.max(100, Math.floor(iterations * 0.05)));
311
+ const mode = opts?.mode ?? "sync";
312
+ assertSafeRun(iterations);
313
+ const isolation = mode === "worker" ? "worker" : "in-process";
314
+ const mod = await loadNative(nativePath, { isolation });
315
+ const fn = mod?.[fnName];
316
+ if (typeof fn !== "function") {
317
+ throw new Error(`Function not found: ${fnName}`);
318
+ }
319
+ for (let i = 0; i < warmup; i++) {
320
+ const out = fn(1, 2);
321
+ if (out instanceof Promise) await out;
322
+ }
323
+ const latencies = [];
324
+ const startAll = nowNs();
325
+ for (let i = 0; i < iterations; i++) {
326
+ const t0 = nowNs();
327
+ const out = fn(1, 2);
328
+ if (out instanceof Promise) await out;
329
+ const t1 = nowNs();
330
+ latencies.push(nsToMs(t1 - t0));
331
+ }
332
+ const endAll = nowNs();
333
+ const totalMs = nsToMs(endAll - startAll);
334
+ let min = Infinity;
335
+ let max = -Infinity;
336
+ let sum = 0;
337
+ for (const l of latencies) {
338
+ if (l < min) min = l;
339
+ if (l > max) max = l;
340
+ sum += l;
341
+ }
342
+ const avg = sum / latencies.length;
343
+ const callsPerSec = iterations / (totalMs / 1e3);
344
+ return {
345
+ fnName,
346
+ mode,
347
+ iterations,
348
+ warmup,
349
+ callsPerSec,
350
+ avgLatencyMs: avg,
351
+ minLatencyMs: min,
352
+ maxLatencyMs: max
353
+ };
354
+ }
355
+ async function benchmarkCompareSyncVsWorker(nativePath, fnName, opts) {
356
+ const sync = await benchmarkNativeFunction(nativePath, fnName, {
357
+ ...opts,
358
+ mode: "sync"
359
+ });
360
+ const worker = await benchmarkNativeFunction(nativePath, fnName, {
361
+ ...opts,
362
+ mode: "worker"
363
+ });
364
+ return { sync, worker };
365
+ }
366
+ function formatBenchmarkResult(r) {
367
+ const f = (n) => Number.isFinite(n) ? n.toFixed(3) : String(n);
368
+ return [
369
+ `${r.fnName} (${r.mode})`,
370
+ ` iterations: ${r.iterations} (warmup ${r.warmup})`,
371
+ ` calls/sec: ${f(r.callsPerSec)}`,
372
+ ` avg ms: ${f(r.avgLatencyMs)}`,
373
+ ` min ms: ${f(r.minLatencyMs)}`,
374
+ ` max ms: ${f(r.maxLatencyMs)}`
375
+ ].join("\n");
376
+ }
377
+ function formatBenchmarkCompare(res) {
378
+ return [formatBenchmarkResult(res.sync), "", formatBenchmarkResult(res.worker)].join("\n");
379
+ }
380
+
381
+ export {
382
+ getProjectRoot,
383
+ getRegistryRoot,
384
+ getInstalledPackageDir,
385
+ resolveRegistryImport,
386
+ readRelaxJson,
387
+ installPackage,
388
+ removePackage,
389
+ listPackages,
390
+ updateIndex,
391
+ discoverNativeTestFiles,
392
+ discoverNativeTestsFromFile,
393
+ discoverNativeTests,
394
+ formatNativeTestResults,
395
+ runNativeTests,
396
+ getSourceLine,
397
+ benchmarkNativeFunction,
398
+ benchmarkCompareSyncVsWorker,
399
+ formatBenchmarkResult,
400
+ formatBenchmarkCompare
401
+ };
@@ -0,0 +1,65 @@
1
+ import {
2
+ InvalidFreeError,
3
+ MemoryError,
4
+ NativeBuffer,
5
+ NativePointer,
6
+ NullPointerError,
7
+ UseAfterFreeError
8
+ } from "./chunk-WXCN2QJ7.js";
9
+ import {
10
+ __export
11
+ } from "./chunk-MLKGABMK.js";
12
+
13
+ // src/memory/nativeMemory.ts
14
+ import koffi from "koffi";
15
+ function allocRaw(size) {
16
+ if (!Number.isInteger(size) || size <= 0) {
17
+ throw new TypeError(`native.alloc(size): size must be a positive integer, got ${size}`);
18
+ }
19
+ const handle = koffi.alloc("char", size);
20
+ const ab = koffi.view(handle, size);
21
+ const view = new Uint8Array(ab);
22
+ return { handle, view };
23
+ }
24
+ function freeRaw(ptr) {
25
+ koffi.free(ptr);
26
+ }
27
+
28
+ // src/memory/index.ts
29
+ var memory_exports = {};
30
+ __export(memory_exports, {
31
+ InvalidFreeError: () => InvalidFreeError,
32
+ MemoryError: () => MemoryError,
33
+ NativeBuffer: () => NativeBuffer,
34
+ NativePointer: () => NativePointer,
35
+ NullPointerError: () => NullPointerError,
36
+ UseAfterFreeError: () => UseAfterFreeError,
37
+ alloc: () => alloc,
38
+ allocRaw: () => allocRaw,
39
+ free: () => free,
40
+ freeRaw: () => freeRaw
41
+ });
42
+ function alloc(size, opts) {
43
+ const allocation = allocRaw(size);
44
+ return new NativeBuffer(allocation, { ownership: "js", autoFree: opts?.autoFree });
45
+ }
46
+ function free(ptr) {
47
+ if (NativeBuffer.isNativeBuffer(ptr)) {
48
+ ptr.free();
49
+ return;
50
+ }
51
+ if (NativePointer.isNativePointer(ptr)) {
52
+ throw new InvalidFreeError(
53
+ `native.free(ptr): cannot free a raw NativePointer (unknown allocator). Use a NativeBuffer allocated by native.alloc().`
54
+ );
55
+ }
56
+ throw new TypeError("native.free(ptr): expected NativeBuffer or NativePointer");
57
+ }
58
+
59
+ export {
60
+ allocRaw,
61
+ freeRaw,
62
+ alloc,
63
+ free,
64
+ memory_exports
65
+ };