@ai-ecoverse/slicc-kernel 1.36.0 → 1.37.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.
package/dist/node.js CHANGED
@@ -3249,6 +3249,35 @@ async function scanFilesystems(fs, modules) {
3249
3249
  }
3250
3250
  return found;
3251
3251
  }
3252
+ var SUFFIX = /^\.[A-Za-z0-9_+-][A-Za-z0-9._+-]*$/;
3253
+ async function scanBinfmts(fs, modules) {
3254
+ const found = /* @__PURE__ */ new Map();
3255
+ for (const pkg of await packagesIn(fs, modules)) {
3256
+ let manifest;
3257
+ try {
3258
+ manifest = JSON.parse(await fs.readFile(`${pkg}/package.json`));
3259
+ } catch {
3260
+ continue;
3261
+ }
3262
+ const declared = manifest.slicc?.binfmt;
3263
+ if (!declared || typeof declared !== "object") continue;
3264
+ for (const [suffix, command] of Object.entries(declared)) {
3265
+ if (!SUFFIX.test(suffix) || typeof command !== "string" || !NAME.test(command)) continue;
3266
+ if (!found.has(suffix)) found.set(suffix, command);
3267
+ }
3268
+ }
3269
+ return found;
3270
+ }
3271
+ function binfmtOf(binfmts, path) {
3272
+ const name2 = path.slice(path.lastIndexOf("/") + 1);
3273
+ let best;
3274
+ for (const suffix of binfmts.keys()) {
3275
+ if (name2.length > suffix.length && name2.endsWith(suffix)) {
3276
+ if (best === void 0 || suffix.length > best.length) best = suffix;
3277
+ }
3278
+ }
3279
+ return best === void 0 ? void 0 : binfmts.get(best);
3280
+ }
3252
3281
 
3253
3282
  // src/fs/commands.ts
3254
3283
  var S_IFDIR2 = 16384;
@@ -10110,6 +10139,7 @@ var PACKAGE_ROOT = /^(.*\/node_modules\/(?:@[^/]+\/)?[^/]+)\//;
10110
10139
  var ENV_REFERENCE = /\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g;
10111
10140
  var WASM_MAGIC = [0, 97, 115, 109];
10112
10141
  var SHEBANG_MAX = 256;
10142
+ var MAX_INTERPRETERS = 4;
10113
10143
  var NOT_FOUND = 127;
10114
10144
  var DECIDE_MS = 100;
10115
10145
  var INIT_PID = 1;
@@ -10161,6 +10191,17 @@ function targetOf(command) {
10161
10191
  ...command.preopenRoot ? { preopenRoot: true } : {}
10162
10192
  };
10163
10193
  }
10194
+ function withScriptEnv(target, command) {
10195
+ if (!command) return target;
10196
+ return {
10197
+ ...target,
10198
+ env: { ...target.env, ...command.env },
10199
+ unset: [
10200
+ ...(target.unset ?? []).filter((key) => !Object.hasOwn(command.env ?? {}, key)),
10201
+ ...command.unset ?? []
10202
+ ]
10203
+ };
10204
+ }
10164
10205
  function childHandle(handle) {
10165
10206
  return {
10166
10207
  pid: handle.pid,
@@ -10185,6 +10226,7 @@ var Launcher = class {
10185
10226
  modulesDir;
10186
10227
  env;
10187
10228
  catalog;
10229
+ binfmts;
10188
10230
  compiled = /* @__PURE__ */ new Map();
10189
10231
  processes = /* @__PURE__ */ new Map();
10190
10232
  zombies = /* @__PURE__ */ new Set();
@@ -10266,6 +10308,7 @@ var Launcher = class {
10266
10308
  this.fs = keepingOpen(fs, this.nodes);
10267
10309
  this.watchers.watch([this.modulesDir, this.pnpmHome], { recursive: true }, () => {
10268
10310
  this.catalog = void 0;
10311
+ this.binfmts = void 0;
10269
10312
  });
10270
10313
  }
10271
10314
  setRoutes(table) {
@@ -10275,6 +10318,10 @@ var Launcher = class {
10275
10318
  this.catalog ??= this.roots().then((roots) => scanCommands(this.base, roots));
10276
10319
  return this.catalog;
10277
10320
  }
10321
+ interpreters() {
10322
+ this.binfmts ??= this.roots().then((roots) => scanBinfmts(this.base, roots));
10323
+ return this.binfmts;
10324
+ }
10278
10325
  async roots() {
10279
10326
  return [this.modulesDir, ...await pnpmGlobalRoots(this.base, this.pnpmHome)];
10280
10327
  }
@@ -10320,30 +10367,28 @@ var Launcher = class {
10320
10367
  const command = (await this.commands()).get(name2);
10321
10368
  return command?.script ? command : void 0;
10322
10369
  }
10323
- async interpreted(file, argv, cwd) {
10370
+ async interpreted(file, argv, cwd, depth = 0) {
10324
10371
  const command = await this.scriptCommand(file);
10325
10372
  const script = command?.script ?? this.fs.resolvePath(cwd, file);
10326
- const words = shebang(await this.head(script) ?? new Uint8Array());
10373
+ const head = await this.head(script);
10374
+ if (!head) return void 0;
10375
+ const binfmt = isWasm(head) ? void 0 : binfmtOf(await this.interpreters(), script);
10376
+ const words = shebang(head) ?? (binfmt ? [binfmt] : void 0);
10327
10377
  if (!words) return void 0;
10328
10378
  if (baseName(words[0]) === "env") words.shift();
10329
10379
  const [interp, ...rest] = words;
10330
- const found = interp ? await this.resolve(interp, interp, cwd) : void 0;
10331
- if (!found) return void 0;
10332
- const target = command ? {
10333
- ...found,
10334
- env: { ...found.env, ...command.env },
10335
- unset: [...found.unset ?? [], ...command.unset ?? []]
10336
- } : found;
10337
10380
  const arg = rest.join(" ");
10338
- return {
10339
- target,
10340
- args: [
10341
- ...target.prefix ?? [],
10342
- ...arg ? [arg] : [],
10343
- command ? script : file,
10344
- ...argv.slice(1)
10345
- ]
10346
- };
10381
+ const passed = [...arg ? [arg] : [], command ? script : file, ...argv.slice(1)];
10382
+ const found = interp ? await this.resolve(interp, interp, cwd) : void 0;
10383
+ if (!found) {
10384
+ if (!interp || depth >= MAX_INTERPRETERS || !await this.scriptCommand(interp)) {
10385
+ return void 0;
10386
+ }
10387
+ const inner = await this.interpreted(interp, [interp, ...passed], cwd, depth + 1);
10388
+ return inner && { ...inner, target: withScriptEnv(inner.target, command) };
10389
+ }
10390
+ const target = withScriptEnv(found, command);
10391
+ return { target, args: [...target.prefix ?? [], ...passed] };
10347
10392
  }
10348
10393
  async plan(file, argv, cwd) {
10349
10394
  const direct = await this.resolve(file, argv[0] ?? file, cwd);
@@ -10351,8 +10396,10 @@ var Launcher = class {
10351
10396
  return this.interpreted(file, argv, cwd);
10352
10397
  }
10353
10398
  async unrunnable(file, cwd) {
10354
- const head = await this.base.readFileBuffer(this.fs.resolvePath(cwd, file)).catch(() => null);
10355
- return head && !(head[0] === 35 && head[1] === 33) ? "ENOEXEC" : "ENOENT";
10399
+ const path = this.fs.resolvePath(cwd, file);
10400
+ const head = await this.base.readFileBuffer(path).catch(() => null);
10401
+ if (!head || head[0] === 35 && head[1] === 33) return "ENOENT";
10402
+ return binfmtOf(await this.interpreters(), path) ? "ENOENT" : "ENOEXEC";
10356
10403
  }
10357
10404
  module(path) {
10358
10405
  return this.base.stat(path).then((st) => {
@@ -10812,6 +10859,7 @@ var Launcher = class {
10812
10859
  }
10813
10860
  async starting(argv, dir) {
10814
10861
  this.catalog = void 0;
10862
+ this.binfmts = void 0;
10815
10863
  const cwd = this.fs.resolvePath("/", dir ?? "/");
10816
10864
  const [file = ""] = argv;
10817
10865
  await this.base.mkdir(cwd, { recursive: true });