@nubjs/nub-win32-x64 0.0.17 → 0.0.19
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/bin/nub.exe +0 -0
- package/bin/nubx.exe +0 -0
- package/package.json +1 -1
- package/runtime/addons/nub-native.node +0 -0
- package/runtime/pnp-bin-run.cjs +85 -0
- package/runtime/pnp-util.cjs +51 -0
- package/runtime/preload-async-hooks.mjs +38 -1
- package/runtime/preload-common.cjs +95 -1
- package/runtime/preload.cjs +6 -0
- package/runtime/preload.mjs +3 -1
- package/runtime/version.mjs +1 -1
package/bin/nub.exe
CHANGED
|
Binary file
|
package/bin/nubx.exe
ADDED
|
Binary file
|
package/package.json
CHANGED
|
Binary file
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
// nubx under Yarn PnP — resolve a bin name to its script and RUN it, the way
|
|
2
|
+
// `yarn exec` does. nub runs this file as its (augmented) entry, having injected
|
|
3
|
+
// `--require .pnp.cjs`, so `findPnpApi` is set up and the zipfs `fs` patch is live.
|
|
4
|
+
//
|
|
5
|
+
// Invoked as: nub <this> <binName> [args...]
|
|
6
|
+
//
|
|
7
|
+
// Two things matter:
|
|
8
|
+
// 1. PnP has no `node_modules/.bin`, so we find the bin by walking the top-level
|
|
9
|
+
// package's dependencies and matching `package.json#bin` (what Yarn's own bin
|
|
10
|
+
// registry does), via the public pnpapi.
|
|
11
|
+
// 2. We load the resolved script with `require()` — the CJS path, where PnP's `fs`
|
|
12
|
+
// patch reads zip-stored packages. Running it as a node *entry* instead would,
|
|
13
|
+
// on the compat tier (Node <22.15, where nub augments via an `--import` ESM
|
|
14
|
+
// preload), route the entry through the ESM loader whose existence check
|
|
15
|
+
// bypasses PnP's `fs` patch and throws ERR_MODULE_NOT_FOUND on the zip path.
|
|
16
|
+
// `require()` (with a dynamic-import fallback for an ESM bin) sidesteps that and
|
|
17
|
+
// keeps nub's augmentation active in-process — matching `yarn exec` on every
|
|
18
|
+
// supported Node.
|
|
19
|
+
const path = require("node:path");
|
|
20
|
+
const fs = require("node:fs");
|
|
21
|
+
const { pathToFileURL } = require("node:url");
|
|
22
|
+
const { cwdIssuer } = require("./pnp-util.cjs");
|
|
23
|
+
|
|
24
|
+
const want = process.argv[2];
|
|
25
|
+
const rest = process.argv.slice(3);
|
|
26
|
+
|
|
27
|
+
// `require("pnpapi")` throws for an out-of-tree issuer (this file lives in nub's
|
|
28
|
+
// install dir); `findPnpApi` resolves by the queried path, so it works here.
|
|
29
|
+
const api = require("node:module").findPnpApi(cwdIssuer());
|
|
30
|
+
if (!api) {
|
|
31
|
+
process.stderr.write("nubx: not a Yarn PnP project\n");
|
|
32
|
+
process.exit(127);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// bin name -> relative script path. A string `bin` is named after the package
|
|
36
|
+
// (its unscoped tail); an object maps explicit names.
|
|
37
|
+
function binsOf(pkg) {
|
|
38
|
+
const b = pkg.bin;
|
|
39
|
+
if (!b) return {};
|
|
40
|
+
if (typeof b === "string") return { [(pkg.name || "").split("/").pop()]: b };
|
|
41
|
+
return b;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
let script = null;
|
|
45
|
+
const top = api.getPackageInformation(api.topLevel);
|
|
46
|
+
for (const [name, reference] of top.packageDependencies) {
|
|
47
|
+
if (reference == null) continue;
|
|
48
|
+
const info = api.getPackageInformation(api.getLocator(name, reference));
|
|
49
|
+
if (!info) continue;
|
|
50
|
+
let pkg;
|
|
51
|
+
try {
|
|
52
|
+
pkg = JSON.parse(fs.readFileSync(path.join(info.packageLocation, "package.json"), "utf8"));
|
|
53
|
+
} catch {
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
const rel = binsOf(pkg)[want];
|
|
57
|
+
if (rel) {
|
|
58
|
+
script = path.join(info.packageLocation, rel);
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (!script) {
|
|
64
|
+
process.stderr.write(
|
|
65
|
+
`nubx: '${want}' not found in Yarn PnP dependencies.\n` +
|
|
66
|
+
` add it (yarn add ${want}), or run it ad-hoc with: yarn dlx ${want}\n`,
|
|
67
|
+
);
|
|
68
|
+
process.exit(127);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Run the bin as if it were the entry: present its own argv, then load it via the
|
|
72
|
+
// zip-safe CJS path. Fall back to dynamic import for an ESM bin.
|
|
73
|
+
process.argv = [process.argv[0], script, ...rest];
|
|
74
|
+
try {
|
|
75
|
+
require(script);
|
|
76
|
+
} catch (e) {
|
|
77
|
+
if (e && e.code === "ERR_REQUIRE_ESM") {
|
|
78
|
+
import(pathToFileURL(script).href).catch((err) => {
|
|
79
|
+
console.error(err);
|
|
80
|
+
process.exit(1);
|
|
81
|
+
});
|
|
82
|
+
} else {
|
|
83
|
+
throw e;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// Shared Yarn PnP ESM-resolution helper, used by BOTH realms that resolve modules:
|
|
2
|
+
// the main-thread preload (preload-common.cjs, fast tier) and the compat-tier
|
|
3
|
+
// loader worker (preload-async-hooks.mjs). Both resolve PnP specifiers identically
|
|
4
|
+
// — through PnP's public, conditions-free `resolveRequest` — and both must hand
|
|
5
|
+
// Node an explicit module `format`, so the logic lives here once rather than being
|
|
6
|
+
// copy-pasted across two threads where it could drift.
|
|
7
|
+
//
|
|
8
|
+
// Why the explicit format: without it, Node <= 20.11 mis-detects a zip-stored `.js`
|
|
9
|
+
// file from a `"type":"module"` package as CommonJS, routes it through the CJS
|
|
10
|
+
// translator, and `require()`s the ESM source -> ERR_REQUIRE_ESM. Newer Node gets
|
|
11
|
+
// it right on its own; emitting the format makes PnP ESM deps work down to the
|
|
12
|
+
// 18.19 floor. (CJS resolution stays in preload-common.cjs's `_resolveFilename`
|
|
13
|
+
// branch — it returns a path, not a hook result, and is main-thread-only.)
|
|
14
|
+
const { readFileSync } = require("node:fs");
|
|
15
|
+
const { join, sep } = require("node:path");
|
|
16
|
+
const { fileURLToPath, pathToFileURL } = require("node:url");
|
|
17
|
+
|
|
18
|
+
// A directory issuer for pnpapi.resolveRequest: cwd with a trailing separator so
|
|
19
|
+
// PnP treats it as a directory. `path.sep` (not a literal "/") keeps it correct on
|
|
20
|
+
// Windows, where cwd uses backslashes and a mixed "C:\x/" can confuse resolution.
|
|
21
|
+
const cwdIssuer = () => process.cwd() + sep;
|
|
22
|
+
|
|
23
|
+
// Module format of a PnP-resolved file. `.mjs`/`.cjs` are unambiguous; a `.js` file
|
|
24
|
+
// inherits its package's `type` (read via PnP — `fs` is zip-patched in both realms).
|
|
25
|
+
// `null` lets Node decide (non-JS, or detection failed).
|
|
26
|
+
function pnpFormat(pnp, resolvedPath) {
|
|
27
|
+
if (resolvedPath.endsWith(".mjs")) return "module";
|
|
28
|
+
if (resolvedPath.endsWith(".cjs")) return "commonjs";
|
|
29
|
+
if (!resolvedPath.endsWith(".js")) return null;
|
|
30
|
+
try {
|
|
31
|
+
const info = pnp.getPackageInformation(pnp.findPackageLocator(resolvedPath));
|
|
32
|
+
const pj = JSON.parse(readFileSync(join(info.packageLocation, "package.json"), "utf8"));
|
|
33
|
+
return pj.type === "module" ? "module" : "commonjs";
|
|
34
|
+
} catch {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Resolve an ESM `specifier` (from `parentURL`) through PnP and return a Node
|
|
40
|
+
// resolve-hook result `{ url, format?, shortCircuit }`, or `null` if PnP can't
|
|
41
|
+
// resolve it (then the caller delegates to Node's default resolver). Throwing is
|
|
42
|
+
// the caller's signal to fall through too — callers wrap in try/catch.
|
|
43
|
+
function pnpResolveEsm(pnp, specifier, parentURL) {
|
|
44
|
+
const issuer = parentURL ? fileURLToPath(parentURL) : cwdIssuer();
|
|
45
|
+
const resolved = pnp.resolveRequest(specifier, issuer);
|
|
46
|
+
if (!resolved) return null;
|
|
47
|
+
const format = pnpFormat(pnp, resolved);
|
|
48
|
+
return { url: pathToFileURL(resolved).href, shortCircuit: true, ...(format && { format }) };
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
module.exports = { pnpResolveEsm, cwdIssuer };
|
|
@@ -21,6 +21,34 @@ import {
|
|
|
21
21
|
TRANSPILE_EXTS, DATA_EXTS,
|
|
22
22
|
extname, resolveSpec, loadTranspile, loadData,
|
|
23
23
|
} from "./transform-core.mjs";
|
|
24
|
+
import { createRequire, isBuiltin } from "node:module";
|
|
25
|
+
import { existsSync } from "node:fs";
|
|
26
|
+
import { join, dirname } from "node:path";
|
|
27
|
+
import { pnpResolveEsm } from "./pnp-util.cjs";
|
|
28
|
+
|
|
29
|
+
// Yarn PnP handle for this loader worker. The worker runs in its own thread where
|
|
30
|
+
// `.pnp.cjs` was never --require'd, so neither the `pnpapi` builtin nor
|
|
31
|
+
// `module.findPnpApi` is installed here (the main-thread preload uses findPnpApi; it
|
|
32
|
+
// can't reach across to this realm). So bootstrap PnP for this thread directly: walk
|
|
33
|
+
// up from cwd to the `.pnp.cjs` Rust located and require it by absolute path — that
|
|
34
|
+
// returns the pnpapi object. nub then resolves PnP specifiers via
|
|
35
|
+
// `pnpapi.resolveRequest` (its public, conditions-free resolver), mirroring the main
|
|
36
|
+
// thread, so there is no need to register Yarn's `.pnp.loader.mjs` (which deadlocks
|
|
37
|
+
// against the fast tier's `module.registerHooks`). `null` when not a PnP run.
|
|
38
|
+
const __pnp = (() => {
|
|
39
|
+
if (!process.versions.pnp) return null;
|
|
40
|
+
const req = createRequire(import.meta.url);
|
|
41
|
+
try {
|
|
42
|
+
let dir = process.cwd();
|
|
43
|
+
for (;;) {
|
|
44
|
+
const candidate = join(dir, ".pnp.cjs");
|
|
45
|
+
if (existsSync(candidate)) return req(candidate);
|
|
46
|
+
const parent = dirname(dir);
|
|
47
|
+
if (parent === dir) return null;
|
|
48
|
+
dir = parent;
|
|
49
|
+
}
|
|
50
|
+
} catch { return null; }
|
|
51
|
+
})();
|
|
24
52
|
|
|
25
53
|
// Node calls this once per worker when the main thread invokes
|
|
26
54
|
// `module.register(url, parentURL, { data })`. We accept and ignore the payload
|
|
@@ -31,7 +59,16 @@ export async function initialize(_data) {}
|
|
|
31
59
|
// ── Resolve hook ────────────────────────────────────────────────────
|
|
32
60
|
export async function resolve(specifier, context, nextResolve) {
|
|
33
61
|
const r = resolveSpec(specifier, context.parentURL);
|
|
34
|
-
|
|
62
|
+
if (r) return r;
|
|
63
|
+
// Yarn PnP: resolve deps through PnP's own resolver — identical to the fast tier,
|
|
64
|
+
// via the shared helper (resolveRequest + module-format detection).
|
|
65
|
+
if (__pnp && !isBuiltin(specifier) && !specifier.startsWith("node:")) {
|
|
66
|
+
try {
|
|
67
|
+
const res = pnpResolveEsm(__pnp, specifier, context.parentURL);
|
|
68
|
+
if (res) return res;
|
|
69
|
+
} catch { /* fall through to Node's resolver */ }
|
|
70
|
+
}
|
|
71
|
+
return nextResolve(specifier, context);
|
|
35
72
|
}
|
|
36
73
|
|
|
37
74
|
// ── Load hook ───────────────────────────────────────────────────────
|
|
@@ -20,6 +20,44 @@ const { readdirSync } = require("node:fs");
|
|
|
20
20
|
const { fileURLToPath, pathToFileURL } = require("node:url");
|
|
21
21
|
const { join, dirname, extname: pathExtname } = require("node:path");
|
|
22
22
|
|
|
23
|
+
// Yarn PnP API handle, fetched lazily via Node's `module.findPnpApi`. `.pnp.cjs`
|
|
24
|
+
// (injected by the Rust spawn layer via --require, ahead of nub's preload) sets
|
|
25
|
+
// `process.versions.pnp` and installs `findPnpApi`, which returns the pnpapi object
|
|
26
|
+
// governing a given path. Unlike a bare `require("pnpapi")` — which throws here,
|
|
27
|
+
// since this preload lives in nub's install dir, OUTSIDE the user's PnP tree —
|
|
28
|
+
// `findPnpApi` resolves by the queried path, so an out-of-tree issuer works. Being
|
|
29
|
+
// a plain query it never re-enters nub's resolve hooks, so there is no ordering
|
|
30
|
+
// constraint with `module.registerHooks` (the reason the previous abs-path require
|
|
31
|
+
// was load-bearing-fragile). nub resolves PnP specifiers through
|
|
32
|
+
// `pnpapi.resolveRequest` (its public, conditions-free resolver) in both the
|
|
33
|
+
// registerHooks resolve hook and the `_resolveFilename` override below. No env var
|
|
34
|
+
// (brand boundary); `null` when this is not a PnP run.
|
|
35
|
+
let __pnpApi;
|
|
36
|
+
function pnpApi() {
|
|
37
|
+
if (__pnpApi) return __pnpApi; // cache only a SUCCESSFUL lookup (see below)
|
|
38
|
+
if (!process.versions.pnp) return null;
|
|
39
|
+
// `findPnpApi` matches by the queried path. A single synthesized `cwd + sep` anchor
|
|
40
|
+
// can miss on Windows (drive-letter casing, 8.3 short paths, trailing separator),
|
|
41
|
+
// and a transient early miss must NOT be cached sticky — otherwise every later
|
|
42
|
+
// resolution falls through to PnP's `_resolveFilename`, which rejects the
|
|
43
|
+
// `conditions` option Node injects under a registered hook (the intermittent
|
|
44
|
+
// Windows `conditions` crash). So try several real in-tree anchors and cache only
|
|
45
|
+
// on success: `argv[1]` is the user's entry file (in-tree for `nub <file>`); cwd
|
|
46
|
+
// covers `nub run` / `nub exec`.
|
|
47
|
+
for (const anchor of [process.argv[1], cwdIssuer(), process.cwd()]) {
|
|
48
|
+
if (!anchor) continue;
|
|
49
|
+
try {
|
|
50
|
+
const api = module_.findPnpApi(anchor);
|
|
51
|
+
if (api) return (__pnpApi = api);
|
|
52
|
+
} catch {}
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Shared PnP ESM resolution (resolveRequest + format) + the directory-issuer
|
|
58
|
+
// helper, identical to the compat worker's — see runtime/pnp-util.cjs.
|
|
59
|
+
const { pnpResolveEsm, cwdIssuer } = require("./pnp-util.cjs");
|
|
60
|
+
|
|
23
61
|
// ── Watch-mode dependency reporting (main thread only) ──────────────
|
|
24
62
|
// Under `nub watch`, Node's FilesWatcher only watches files in the import graph;
|
|
25
63
|
// config files (tsconfig.json, package.json) and `.env*` are NOT in any graph, so
|
|
@@ -103,7 +141,24 @@ function makeHooks(core, watchReporting) {
|
|
|
103
141
|
|
|
104
142
|
function resolve(specifier, context, nextResolve) {
|
|
105
143
|
const r = core.resolveSpec(specifier, context.parentURL);
|
|
106
|
-
|
|
144
|
+
if (r) return r;
|
|
145
|
+
// Under Yarn PnP, delegating to `nextResolve` flows into Node's default
|
|
146
|
+
// resolution, which calls PnP's patched `_resolveFilename` WITH a `conditions`
|
|
147
|
+
// option PnP rejects once a customization hook is registered ("aren't supported
|
|
148
|
+
// by PnP yet (conditions)"). PnP exposes its own conditions-free resolver —
|
|
149
|
+
// `pnpapi.resolveRequest` — so resolve through THAT and hand Node the file URL.
|
|
150
|
+
// Still "PnP does the resolution" (its public API); nub adds none of its own.
|
|
151
|
+
// Returns a virtual `.zip` path for zip-stored deps, which Node reads via the
|
|
152
|
+
// zipfs patch `.pnp.cjs` installed. Falls back to `nextResolve` if PnP can't
|
|
153
|
+
// resolve (e.g. a builtin or a relative path PnP defers to Node).
|
|
154
|
+
const pnp = pnpApi();
|
|
155
|
+
if (pnp && !module_.isBuiltin(specifier) && !specifier.startsWith("node:")) {
|
|
156
|
+
try {
|
|
157
|
+
const res = pnpResolveEsm(pnp, specifier, context && context.parentURL);
|
|
158
|
+
if (res) return res;
|
|
159
|
+
} catch { /* fall through to Node's resolver */ }
|
|
160
|
+
}
|
|
161
|
+
return nextResolve(specifier, context);
|
|
107
162
|
}
|
|
108
163
|
|
|
109
164
|
function load(url, context, nextLoad) {
|
|
@@ -247,6 +302,45 @@ function installCjsRequireHooks(core, withClassicTranspile) {
|
|
|
247
302
|
}
|
|
248
303
|
return resolved;
|
|
249
304
|
}
|
|
305
|
+
// Yarn PnP, FAST TIER ONLY. On the fast tier nub registers a sync
|
|
306
|
+
// `module.registerHooks` resolve hook, which makes Node thread a `conditions`
|
|
307
|
+
// option into PnP's patched `_resolveFilename` ("aren't supported by PnP yet
|
|
308
|
+
// (conditions)") AND re-inject it even if we pass none — so we must resolve
|
|
309
|
+
// everything ourselves via PnP's conditions-free `pnpapi.resolveRequest` and the
|
|
310
|
+
// native path primitives, never falling through to PnP's `_resolveFilename`. On
|
|
311
|
+
// the COMPAT tier there is no sync hook, so PnP's own `_resolveFilename` resolves
|
|
312
|
+
// CJS deps fine (no conditions option) and interposing here instead recurses to
|
|
313
|
+
// OOM on the Node 18 line — so the PnP branch is gated to where registerHooks
|
|
314
|
+
// exists. `pnpApi()` is null off-PnP, making this doubly safe.
|
|
315
|
+
// On a PnP tree + fast tier (sync `registerHooks` registered), resolve through
|
|
316
|
+
// PnP's conditions-free `resolveRequest` and NEVER fall through to
|
|
317
|
+
// `origResolveFilename` — that is PnP's patched `_resolveFilename`, which rejects
|
|
318
|
+
// the `conditions` option Node injects under a registered hook. The gate is
|
|
319
|
+
// `process.versions.pnp` (set the moment `.pnp.cjs` runs), NOT a non-null api:
|
|
320
|
+
// if `findPnpApi` momentarily misses we still avoid PnP's resolver and use Node's
|
|
321
|
+
// native `_findPath`, so a transient lookup miss can't leak a `conditions` crash.
|
|
322
|
+
const inPnp = typeof module_.registerHooks === "function" && !!process.versions.pnp;
|
|
323
|
+
if (inPnp) {
|
|
324
|
+
if (module_.isBuiltin(request)) return request; // PnP defers builtins to Node
|
|
325
|
+
const pnp = pnpApi();
|
|
326
|
+
if (pnp) {
|
|
327
|
+
try {
|
|
328
|
+
const issuer = parent && typeof parent.filename === "string" ? parent.filename : cwdIssuer();
|
|
329
|
+
const r = pnp.resolveRequest(request, issuer);
|
|
330
|
+
if (r) return r;
|
|
331
|
+
} catch { /* fall through to native path resolution below */ }
|
|
332
|
+
}
|
|
333
|
+
// PnP couldn't resolve it (nub's OWN vendored deps, whose issuer is nub's
|
|
334
|
+
// out-of-tree install dir) or the api was momentarily unavailable. Use Node's
|
|
335
|
+
// native path primitives (`_resolveLookupPaths` + `_findPath`), which PnP does
|
|
336
|
+
// NOT patch — never `origResolveFilename` (PnP's, + `conditions`).
|
|
337
|
+
const lookupPaths = module_._resolveLookupPaths(request, parent) || [];
|
|
338
|
+
const found = module_._findPath(request, lookupPaths, isMain);
|
|
339
|
+
if (found) return found;
|
|
340
|
+
const err = new Error(`Cannot find module '${request}'`);
|
|
341
|
+
err.code = "MODULE_NOT_FOUND";
|
|
342
|
+
throw err;
|
|
343
|
+
}
|
|
250
344
|
return origResolveFilename.call(this, request, parent, isMain, options);
|
|
251
345
|
};
|
|
252
346
|
|
package/runtime/preload.cjs
CHANGED
|
@@ -114,6 +114,12 @@ if (!requireEsmDisabled) {
|
|
|
114
114
|
const { resolve, load } = common.makeHooks(core, watchReporting);
|
|
115
115
|
module_.registerHooks({ resolve, load });
|
|
116
116
|
common.installCjsRequireHooks(core, false);
|
|
117
|
+
// NOTE: no Yarn `.pnp.loader.mjs` registration. nub's own `resolve` hook already
|
|
118
|
+
// routes PnP specifiers through `pnpapi.resolveRequest` (see makeHooks /
|
|
119
|
+
// installCjsRequireHooks), covering both `import` and `require` of PnP deps.
|
|
120
|
+
// Registering Yarn's ESM loader ON TOP of the sync `module.registerHooks` hooks
|
|
121
|
+
// deadlocks ESM entry loading (silent exit) — both hook systems intercept ESM
|
|
122
|
+
// resolution. The compat tier (preload-async-hooks.mjs) resolves PnP the same way.
|
|
117
123
|
|
|
118
124
|
// ── Sync polyfills + lazy ESM-side-effect polyfills ───────────────
|
|
119
125
|
installSyncPolyfills(__preloadedPolyfills);
|
package/runtime/preload.mjs
CHANGED
|
@@ -65,7 +65,9 @@ if (__isFastTier) {
|
|
|
65
65
|
module.registerHooks({ resolve, load });
|
|
66
66
|
common.installCjsRequireHooks(core, false);
|
|
67
67
|
} else if (__isCompatTier) {
|
|
68
|
-
// Compat path: ESM `import` hooks run in a dedicated loader worker thread.
|
|
68
|
+
// Compat path: ESM `import` hooks run in a dedicated loader worker thread. That
|
|
69
|
+
// worker resolves PnP deps via pnpapi.resolveRequest itself (preload-async-
|
|
70
|
+
// hooks.mjs), so no Yarn `.pnp.loader.mjs` registration is needed here either.
|
|
69
71
|
module.register("./preload-async-hooks.mjs", import.meta.url);
|
|
70
72
|
// (The main-thread require() shim's module-format + decorator detection is a
|
|
71
73
|
// synchronous native addon call now — no parser warm-up; the old
|
package/runtime/version.mjs
CHANGED
|
@@ -9,4 +9,4 @@
|
|
|
9
9
|
// previously lived as a literal inside preload.mjs, which `make version` patched,
|
|
10
10
|
// while the worker carried a hand-maintained "…-compat" copy that `make version`
|
|
11
11
|
// never touched — a latent staleness bug this module closes.)
|
|
12
|
-
export const NUB_VERSION = "0.0.
|
|
12
|
+
export const NUB_VERSION = "0.0.19";
|