env-runner
Advanced tools
| var ImportType; | ||
| (function(A) { | ||
| A[A.Static = 1] = "Static", A[A.Dynamic = 2] = "Dynamic", A[A.ImportMeta = 3] = "ImportMeta", A[A.StaticSourcePhase = 4] = "StaticSourcePhase", A[A.DynamicSourcePhase = 5] = "DynamicSourcePhase", A[A.StaticDeferPhase = 6] = "StaticDeferPhase", A[A.DynamicDeferPhase = 7] = "DynamicDeferPhase"; | ||
| })(ImportType || (ImportType = {})); | ||
| const A = 1 === new Uint8Array(new Uint16Array([1]).buffer)[0]; | ||
| function parse(E, g = "@") { | ||
| if (!C) return init.then((() => parse(E))); | ||
| const I = E.length + 1, o = (C.__heap_base.value || C.__heap_base) + 4 * I - C.memory.buffer.byteLength; | ||
| o > 0 && C.memory.grow(Math.ceil(o / 65536)); | ||
| const D = C.sa(I - 1); | ||
| if ((A ? B : Q)(E, new Uint16Array(C.memory.buffer, D, I)), !C.parse()) throw Object.assign(/* @__PURE__ */ new Error(`Parse error ${g}:${E.slice(0, C.e()).split("\n").length}:${C.e() - E.lastIndexOf("\n", C.e() - 1)}`), { idx: C.e() }); | ||
| const K = [], k = []; | ||
| for (; C.ri();) { | ||
| const A = C.is(), Q = C.ie(), B = C.it(), g = C.ai(), I = C.id(), o = C.ss(), D = C.se(); | ||
| let k; | ||
| C.ip() && (k = w(E.slice(-1 === I ? A - 1 : A, -1 === I ? Q + 1 : Q))); | ||
| const i = []; | ||
| for (C.rsa(); C.ra();) { | ||
| const A = C.aks(), Q = C.ake(), B = C.avs(), g = C.ave(); | ||
| i.push([N(E.slice(A, Q)), N(E.slice(B, g))]); | ||
| } | ||
| K.push({ | ||
| n: k, | ||
| t: B, | ||
| s: A, | ||
| e: Q, | ||
| ss: o, | ||
| se: D, | ||
| d: I, | ||
| a: g, | ||
| at: i.length > 0 ? i : null | ||
| }); | ||
| } | ||
| for (; C.re();) { | ||
| const A = C.es(), Q = C.ee(), B = C.els(), g = C.ele(), I = N(E.slice(A, Q)), o = B < 0 ? void 0 : N(E.slice(B, g)); | ||
| k.push({ | ||
| s: A, | ||
| e: Q, | ||
| ls: B, | ||
| le: g, | ||
| n: I, | ||
| ln: o | ||
| }); | ||
| } | ||
| function w(A) { | ||
| try { | ||
| return (0, eval)(A); | ||
| } catch (A) {} | ||
| } | ||
| function N(A) { | ||
| if (!A) return A; | ||
| const Q = A[0]; | ||
| return ("\"" === Q || "'" === Q) && w(A) || A; | ||
| } | ||
| return [ | ||
| K, | ||
| k, | ||
| !!C.f(), | ||
| !!C.ms() | ||
| ]; | ||
| } | ||
| function Q(A, Q) { | ||
| const B = A.length; | ||
| let C = 0; | ||
| for (; C < B;) { | ||
| const B = A.charCodeAt(C); | ||
| Q[C++] = (255 & B) << 8 | B >>> 8; | ||
| } | ||
| } | ||
| function B(A, Q) { | ||
| const B = A.length; | ||
| let C = 0; | ||
| for (; C < B;) Q[C] = A.charCodeAt(C++); | ||
| } | ||
| let C; | ||
| const E = () => { | ||
| return A = "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", "undefined" != typeof Buffer ? Buffer.from(A, "base64") : Uint8Array.from(atob(A), ((A) => A.charCodeAt(0))); | ||
| var A; | ||
| }; | ||
| const init = WebAssembly.compile(E()).then(WebAssembly.instantiate).then((({ exports: A }) => { | ||
| C = A; | ||
| })); | ||
| export { init, parse }; |
@@ -40,5 +40,8 @@ import { EnvRunner, RunnerMessageListener, WorkerAddress, WorkerHooks } from "./types.mjs"; | ||
| protected _data?: EnvRunnerData; | ||
| protected _virtualSources?: VirtualModules; | ||
| protected _hooks: Partial<WorkerHooks>; | ||
| protected _address?: WorkerAddress; | ||
| protected _messageListeners: Set<(data: unknown) => void>; | ||
| protected _pendingRequests: Set<(cause?: unknown) => void>; | ||
| protected _virtualResolved?: Promise<void>; | ||
| constructor(opts: { | ||
@@ -67,6 +70,31 @@ name: string; | ||
| reloadModule(timeout?: number): Promise<void>; | ||
| /** | ||
| * Invalidate a virtual module so the next `reloadModule()` re-evaluates it. | ||
| * A factory-valued `data.virtual` source is re-run on the host and the fresh | ||
| * source is shipped to the worker along with the invalidation. Rejects when | ||
| * the specifier is not a registered virtual module. | ||
| */ | ||
| invalidateModule(specifier: string, timeout?: number): Promise<void>; | ||
| close(cause?: unknown): Promise<void>; | ||
| [Symbol.asyncDispose](): Promise<void>; | ||
| /** | ||
| * Resolve a relative fetch input (e.g. `"/path"`) against a placeholder | ||
| * `http://localhost` origin so it parses as a full URL. The origin is a | ||
| * placeholder — requests are dispatched to the worker address regardless. | ||
| */ | ||
| protected _resolveFetchInput(input: string | URL | Request): string | URL | Request; | ||
| protected _handleMessage(message: any): void; | ||
| /** | ||
| * Send a message and await a matching response message. Shared by `rpc()`, | ||
| * `reloadModule()`, and `invalidateModule()`. Rejects on timeout, on a | ||
| * response carrying an `error`, and promptly when the runner closes mid-wait | ||
| * (instead of letting callers wait out the timeout on a dead worker). | ||
| */ | ||
| protected _request<T = unknown>(message: unknown, opts: { | ||
| match: (msg: any) => boolean; | ||
| timeout: number; | ||
| timeoutError: string; | ||
| send?: (message: unknown) => void; | ||
| }): Promise<T>; | ||
| /** | ||
| * Resolve any factory-valued `data.virtual` sources to strings before the | ||
@@ -80,2 +108,8 @@ * worker is spawned. Returns a pending promise only when there is async work | ||
| /** | ||
| * Re-run a factory-valued virtual source on the host and sync the resolved | ||
| * `data.virtual` map. Returns the fresh source, or `undefined` when the | ||
| * source is a plain string or unknown (nothing to re-evaluate). | ||
| */ | ||
| protected _refreshVirtualSource(specifier: string): Promise<string | undefined>; | ||
| /** | ||
| * Run a subclass spawn callback after `data.virtual` is resolved. | ||
@@ -82,0 +116,0 @@ * Synchronous when no factory-valued source is present; otherwise defers |
@@ -9,5 +9,8 @@ import { resolveVirtualModules } from "./virtual-loader.mjs"; | ||
| _data; | ||
| _virtualSources; | ||
| _hooks; | ||
| _address; | ||
| _messageListeners; | ||
| _pendingRequests; | ||
| _virtualResolved; | ||
| constructor(opts) { | ||
@@ -19,2 +22,3 @@ this._name = opts.name; | ||
| this._messageListeners = /* @__PURE__ */ new Set(); | ||
| this._pendingRequests = /* @__PURE__ */ new Set(); | ||
| } | ||
@@ -27,3 +31,3 @@ get ready() { | ||
| if (!this._address) return new Response(`${this._runtimeType()} env runner is unavailable`, { status: 503 }); | ||
| return proxyFetch(this._address, input, init); | ||
| return proxyFetch(this._address, this._resolveFetchInput(input), init); | ||
| } | ||
@@ -64,51 +68,36 @@ async upgrade(context) { | ||
| const id = Math.random().toString(36).slice(2); | ||
| const timeout = opts?.timeout ?? 3e3; | ||
| return new Promise((resolve, reject) => { | ||
| const timer = setTimeout(() => { | ||
| cleanup(); | ||
| reject(/* @__PURE__ */ new Error(`RPC "${name}" timed out`)); | ||
| }, timeout); | ||
| const listener = (msg) => { | ||
| if (msg?.__rpc_id === id) { | ||
| cleanup(); | ||
| if (msg.error) reject(typeof msg.error === "string" ? new Error(msg.error) : msg.error); | ||
| else resolve(msg.data); | ||
| } | ||
| }; | ||
| const cleanup = () => { | ||
| clearTimeout(timer); | ||
| this.offMessage(listener); | ||
| }; | ||
| this.onMessage(listener); | ||
| this.sendMessage({ | ||
| __rpc: name, | ||
| __rpc_id: id, | ||
| data | ||
| }); | ||
| }); | ||
| return this._request({ | ||
| __rpc: name, | ||
| __rpc_id: id, | ||
| data | ||
| }, { | ||
| match: (msg) => msg?.__rpc_id === id, | ||
| timeout: opts?.timeout ?? 3e3, | ||
| timeoutError: `RPC "${name}" timed out` | ||
| }).then((msg) => msg.data); | ||
| } | ||
| async reloadModule(timeout = 5e3) { | ||
| return new Promise((resolve, reject) => { | ||
| const timer = setTimeout(() => { | ||
| cleanup(); | ||
| reject(/* @__PURE__ */ new Error("Module reload timed out")); | ||
| }, timeout); | ||
| const listener = (msg) => { | ||
| if (msg?.event === "module-reloaded") { | ||
| cleanup(); | ||
| if (msg.error) reject(typeof msg.error === "string" ? new Error(msg.error) : msg.error); | ||
| else resolve(); | ||
| } | ||
| }; | ||
| const cleanup = () => { | ||
| clearTimeout(timer); | ||
| this.offMessage(listener); | ||
| }; | ||
| this.onMessage(listener); | ||
| this.sendMessage({ event: "reload-module" }); | ||
| await this._request({ event: "reload-module" }, { | ||
| match: (msg) => msg?.event === "module-reloaded", | ||
| timeout, | ||
| timeoutError: "Module reload timed out" | ||
| }); | ||
| } | ||
| async invalidateModule(specifier, timeout = 5e3) { | ||
| const source = await this._refreshVirtualSource(specifier); | ||
| await this._request({ | ||
| event: "invalidate-module", | ||
| specifier, | ||
| source | ||
| }, { | ||
| match: (msg) => msg?.event === "module-invalidated" && msg.specifier === specifier, | ||
| timeout, | ||
| timeoutError: `Module invalidation timed out for "${specifier}"` | ||
| }); | ||
| } | ||
| async close(cause) { | ||
| if (this.closed) return; | ||
| this.closed = true; | ||
| for (const rejectPending of this._pendingRequests) rejectPending(cause); | ||
| this._pendingRequests.clear(); | ||
| this._hooks.onClose?.(this, cause); | ||
@@ -127,2 +116,6 @@ this._hooks = {}; | ||
| } | ||
| _resolveFetchInput(input) { | ||
| if (typeof input === "string" && !URL.canParse(input)) return new URL(input, "http://localhost"); | ||
| return input; | ||
| } | ||
| _handleMessage(message) { | ||
@@ -136,6 +129,40 @@ if (message?.address) { | ||
| } | ||
| _request(message, opts) { | ||
| if (this.closed) return Promise.reject(/* @__PURE__ */ new Error("Runner is closed")); | ||
| return new Promise((resolve, reject) => { | ||
| const timer = setTimeout(() => { | ||
| cleanup(); | ||
| reject(new Error(opts.timeoutError)); | ||
| }, opts.timeout); | ||
| const listener = (msg) => { | ||
| if (opts.match(msg)) { | ||
| cleanup(); | ||
| if (msg.error) reject(typeof msg.error === "string" ? new Error(msg.error) : msg.error); | ||
| else resolve(msg); | ||
| } | ||
| }; | ||
| const onClose = (cause) => { | ||
| cleanup(); | ||
| reject(new Error("Runner closed before responding", cause ? { cause } : void 0)); | ||
| }; | ||
| const cleanup = () => { | ||
| clearTimeout(timer); | ||
| this.offMessage(listener); | ||
| this._pendingRequests.delete(onClose); | ||
| }; | ||
| this.onMessage(listener); | ||
| this._pendingRequests.add(onClose); | ||
| try { | ||
| (opts.send ?? ((m) => this.sendMessage(m)))(message); | ||
| } catch (error) { | ||
| cleanup(); | ||
| reject(error); | ||
| } | ||
| }); | ||
| } | ||
| _resolveVirtualData() { | ||
| const virtual = this._data?.virtual; | ||
| this._virtualSources = virtual; | ||
| if (!virtual || !Object.values(virtual).some((v) => typeof v === "function")) return; | ||
| return resolveVirtualModules(virtual).then((resolved) => { | ||
| this._virtualResolved = resolveVirtualModules(virtual).then((resolved) => { | ||
| this._data = { | ||
@@ -146,3 +173,13 @@ ...this._data, | ||
| }); | ||
| return this._virtualResolved; | ||
| } | ||
| async _refreshVirtualSource(specifier) { | ||
| await this._virtualResolved?.catch(() => {}); | ||
| const original = this._virtualSources?.[specifier]; | ||
| if (typeof original !== "function") return; | ||
| const source = await original(); | ||
| const resolved = this._data?.virtual; | ||
| if (resolved) resolved[specifier] = source; | ||
| return source; | ||
| } | ||
| _initWithVirtualData(init) { | ||
@@ -149,0 +186,0 @@ const pending = this._resolveVirtualData(); |
@@ -73,2 +73,14 @@ import { WorkerHooks } from "./types.mjs"; | ||
| reloadModule(timeout?: number): Promise<void>; | ||
| /** | ||
| * Invalidate a virtual module so the next `reloadModule()` re-evaluates it. | ||
| * | ||
| * Host-side only (no worker round-trip): the module fallback service serves | ||
| * virtual sources from a live map, so re-running a factory source and | ||
| * bumping the per-specifier versions — the module plus its transitive | ||
| * virtual importers — is enough. Import specifiers in re-served module code | ||
| * are rewritten to the versioned form, giving workerd fresh module | ||
| * identities (it caches by name). A `persistent` instance is evicted from | ||
| * the cache, since its served sources no longer match the cache key. | ||
| */ | ||
| invalidateModule(specifier: string, _timeout?: number): Promise<void>; | ||
| protected _hasRuntime(): boolean; | ||
@@ -75,0 +87,0 @@ protected _runtimeType(): string; |
+90
-51
@@ -1,4 +0,5 @@ | ||
| import { virtualModuleFormat } from "./virtual-loader.mjs"; | ||
| import { expandVirtualInvalidation, stripVirtualTypeScript, virtualModuleFormat } from "./virtual-loader.mjs"; | ||
| import { BaseEnvRunner } from "./base-runner.mjs"; | ||
| import { init, parse } from "./libs/cjs-module-lexer.mjs"; | ||
| import { init as init$1, parse as parse$1 } from "./libs/es-module-lexer.mjs"; | ||
| import { isVirtualSpecifier } from "./worker-utils.mjs"; | ||
@@ -187,2 +188,5 @@ import { createRequire } from "node:module"; | ||
| #reloadCounter = 0; | ||
| #virtual; | ||
| #virtualVersions = /* @__PURE__ */ new Map(); | ||
| #cacheEntry; | ||
| #ws; | ||
@@ -219,3 +223,3 @@ #persistent; | ||
| } | ||
| if (this.#cacheKey) _miniflareCache.delete(this.#cacheKey); | ||
| if (this.#cacheKey && _miniflareCache.get(this.#cacheKey)?.mf === this.#miniflare) _miniflareCache.delete(this.#cacheKey); | ||
| await this.#miniflare.dispose(); | ||
@@ -229,3 +233,4 @@ this.#miniflare = void 0; | ||
| if (!this.#miniflare || this.closed) return new Response("miniflare env runner is unavailable", { status: 503 }); | ||
| const url = typeof input === "string" ? input : input instanceof URL ? input.href : input.url; | ||
| const resolved = this._resolveFetchInput(input); | ||
| const url = typeof resolved === "string" ? resolved : resolved instanceof URL ? resolved.href : resolved.url; | ||
| const res = await this.#miniflare.dispatchFetch(url, init); | ||
@@ -257,26 +262,23 @@ if (res instanceof Response) return res; | ||
| this.#reloadCounter++; | ||
| const version = this.#reloadCounter; | ||
| return new Promise((resolve, reject) => { | ||
| const timer = setTimeout(() => { | ||
| cleanup(); | ||
| reject(/* @__PURE__ */ new Error("Module reload timed out")); | ||
| }, timeout); | ||
| const listener = (msg) => { | ||
| if (msg?.event === "module-reloaded") { | ||
| cleanup(); | ||
| if (msg.error) reject(typeof msg.error === "string" ? new Error(msg.error) : msg.error); | ||
| else resolve(); | ||
| } | ||
| }; | ||
| const cleanup = () => { | ||
| clearTimeout(timer); | ||
| this.offMessage(listener); | ||
| }; | ||
| this.onMessage(listener); | ||
| this.#ws.send(JSON.stringify({ | ||
| type: "reload", | ||
| version | ||
| })); | ||
| await this._request({ | ||
| type: "reload", | ||
| version: this.#reloadCounter | ||
| }, { | ||
| match: (msg) => msg?.event === "module-reloaded", | ||
| timeout, | ||
| timeoutError: "Module reload timed out", | ||
| send: (message) => this.#ws.send(JSON.stringify(message)) | ||
| }); | ||
| } | ||
| async invalidateModule(specifier, _timeout) { | ||
| const virtual = this.#virtual; | ||
| if (!virtual || !Object.hasOwn(virtual, specifier)) { | ||
| const hasVirtual = Object.keys(this._data?.virtual ?? {}).length > 0; | ||
| throw !virtual && hasVirtual && !this.closed ? /* @__PURE__ */ new Error("Miniflare env runner should be initialized before invalidating modules.") : /* @__PURE__ */ new Error(`Cannot invalidate "${specifier}" (not a registered virtual module)`); | ||
| } | ||
| const source = await this._refreshVirtualSource(specifier); | ||
| if (source !== void 0) virtual[specifier] = await this.#prepareVirtualSource(specifier, source); | ||
| for (const key of expandVirtualInvalidation(virtual, specifier)) this.#virtualVersions.set(key, (this.#virtualVersions.get(key) ?? 0) + 1); | ||
| if (this.#cacheKey && _miniflareCache.get(this.#cacheKey) === this.#cacheEntry) _miniflareCache.delete(this.#cacheKey); | ||
| } | ||
| _hasRuntime() { | ||
@@ -295,10 +297,8 @@ return Boolean(this.#miniflare); | ||
| } | ||
| if (this.#persistent && this.#cacheKey) { | ||
| const cached = _miniflareCache.get(this.#cacheKey); | ||
| if (cached) { | ||
| cached.refCount--; | ||
| if (cached.refCount <= 0) { | ||
| _miniflareCache.delete(this.#cacheKey); | ||
| await this.#miniflare.dispose(); | ||
| } | ||
| const entry = this.#cacheEntry; | ||
| if (entry) { | ||
| entry.refCount--; | ||
| if (entry.refCount <= 0) { | ||
| if (this.#cacheKey && _miniflareCache.get(this.#cacheKey) === entry) _miniflareCache.delete(this.#cacheKey); | ||
| await this.#miniflare.dispose(); | ||
| } | ||
@@ -330,13 +330,12 @@ } else await this.#miniflare.dispose(); | ||
| const out = {}; | ||
| let strip; | ||
| for (const [specifier, source] of Object.entries(virtual)) if (virtualModuleFormat(specifier) === "module-typescript") { | ||
| if (!strip) { | ||
| const { stripTypeScriptTypes } = await import("node:module"); | ||
| if (typeof stripTypeScriptTypes !== "function") throw new TypeError(`[env-runner] virtual TypeScript module "${specifier}" requires \`module.stripTypeScriptTypes\` on the host (workerd does not parse TypeScript); upgrade Node.js or provide a pre-transpiled JavaScript source instead.`); | ||
| strip = stripTypeScriptTypes; | ||
| } | ||
| out[specifier] = strip(source); | ||
| } else out[specifier] = source; | ||
| for (const [specifier, source] of Object.entries(virtual)) out[specifier] = await this.#prepareVirtualSource(specifier, source); | ||
| return out; | ||
| } | ||
| async #prepareVirtualSource(specifier, source) { | ||
| if (virtualModuleFormat(specifier) !== "module-typescript") return source; | ||
| return stripVirtualTypeScript(specifier, source, await _getStripTypeScriptTypes(), { | ||
| requirement: "on the host (workerd does not parse TypeScript)", | ||
| remedy: "upgrade Node.js" | ||
| }); | ||
| } | ||
| async #initAsync() { | ||
@@ -346,2 +345,3 @@ const { Miniflare } = await import("miniflare"); | ||
| const virtual = await this.#prepareVirtualModules(); | ||
| this.#virtual = virtual; | ||
| const userFlags = this.#miniflareOptions.compatibilityFlags || []; | ||
@@ -405,9 +405,11 @@ const userDirectSockets = this.#miniflareOptions.unsafeDirectSockets || []; | ||
| const _virtual = virtual; | ||
| const _virtualVersions = this.#virtualVersions; | ||
| const _transformRequest = this.#transformRequest; | ||
| const _exportConditions = this.#exportConditions; | ||
| const _applyVirtualVersions = (code) => applyVirtualVersions(code, _virtualVersions); | ||
| options.unsafeUseModuleFallbackService = true; | ||
| const modulePathMap = /* @__PURE__ */ new Map(); | ||
| const _cjsLexerReady = ensureCjsLexer(); | ||
| const _lexersReady = Promise.all([ensureCjsLexer(), init$1]); | ||
| options.unsafeModuleFallbackService = async (request) => { | ||
| await _cjsLexerReady; | ||
| await _lexersReady; | ||
| const url = new URL(request.url); | ||
@@ -435,3 +437,3 @@ const specifier = url.searchParams.get("specifier"); | ||
| name, | ||
| esModule: source | ||
| esModule: _applyVirtualVersions(source) | ||
| }); | ||
@@ -492,3 +494,3 @@ } | ||
| name, | ||
| esModule: result.code | ||
| esModule: _applyVirtualVersions(result.code) | ||
| }); | ||
@@ -502,3 +504,3 @@ } | ||
| name, | ||
| esModule: contents | ||
| esModule: _applyVirtualVersions(contents) | ||
| }); | ||
@@ -531,2 +533,5 @@ const cjsSuffix = "?__cjs"; | ||
| cached.refCount++; | ||
| this.#cacheEntry = cached; | ||
| this.#virtual = cached.virtual; | ||
| this.#virtualVersions = cached.versions; | ||
| } | ||
@@ -537,6 +542,11 @@ } | ||
| await this.#miniflare.ready; | ||
| if (this.#persistent && this.#cacheKey) _miniflareCache.set(this.#cacheKey, { | ||
| mf: this.#miniflare, | ||
| refCount: 1 | ||
| }); | ||
| if (this.#persistent && this.#cacheKey) { | ||
| this.#cacheEntry = { | ||
| mf: this.#miniflare, | ||
| refCount: 1, | ||
| virtual, | ||
| versions: this.#virtualVersions | ||
| }; | ||
| _miniflareCache.set(this.#cacheKey, this.#cacheEntry); | ||
| } | ||
| } | ||
@@ -587,2 +597,31 @@ const initRes = await this.#miniflare.dispatchFetch("http://localhost/__env_runner_ipc", { headers: { upgrade: "websocket" } }); | ||
| } | ||
| function applyVirtualVersions(code, versions) { | ||
| if (versions.size === 0) return code; | ||
| let imports; | ||
| try { | ||
| [imports] = parse$1(code); | ||
| } catch { | ||
| return code; | ||
| } | ||
| let out = ""; | ||
| let last = 0; | ||
| for (const imp of imports) { | ||
| let specifier = imp.n; | ||
| if (specifier === void 0 && imp.d > -1) { | ||
| const expr = code.slice(imp.s, imp.e); | ||
| if (expr.length > 1 && expr[0] === "`" && expr.endsWith("`") && !expr.includes("${")) specifier = expr.slice(1, -1); | ||
| } | ||
| const version = specifier === void 0 ? void 0 : versions.get(specifier); | ||
| if (!version) continue; | ||
| const versioned = `${specifier}?v=${version}`; | ||
| out += code.slice(last, imp.s) + (imp.d > -1 ? JSON.stringify(versioned) : versioned); | ||
| last = imp.e; | ||
| } | ||
| return out + code.slice(last); | ||
| } | ||
| let _stripTypesPromise; | ||
| function _getStripTypeScriptTypes() { | ||
| _stripTypesPromise ??= import("node:module").then((m) => m.stripTypeScriptTypes); | ||
| return _stripTypesPromise; | ||
| } | ||
| let _cjsLexerReady; | ||
@@ -589,0 +628,0 @@ function ensureCjsLexer() { |
@@ -59,2 +59,3 @@ import { NodeWorkerEnvRunner } from "./runner3.mjs"; | ||
| async fetch(input, init) { | ||
| input = this._resolveFetchInput(input); | ||
| const headers = new Headers(input instanceof Request ? input.headers : init?.headers); | ||
@@ -61,0 +62,0 @@ const requestId = generateVercelId(); |
@@ -13,2 +13,3 @@ import { NodeWorkerEnvRunner } from "./runner3.mjs"; | ||
| async fetch(input, init) { | ||
| input = this._resolveFetchInput(input); | ||
| const headers = new Headers(input instanceof Request ? input.headers : init?.headers); | ||
@@ -15,0 +16,0 @@ const clientIp = headers.get("x-forwarded-for")?.split(",")[0]?.trim() || headers.get("x-real-ip") || "127.0.0.1"; |
+37
-10
@@ -8,2 +8,4 @@ import { watch } from "node:fs"; | ||
| _reloading = false; | ||
| _moduleInvalidated = false; | ||
| _pendingModuleReload; | ||
| _closeListeners = /* @__PURE__ */ new Set(); | ||
@@ -22,8 +24,16 @@ _readyListeners = /* @__PURE__ */ new Set(); | ||
| this._reloading = true; | ||
| const prev = this._runner; | ||
| this._detach(); | ||
| this._attach(runner); | ||
| this._reloading = false; | ||
| if (prev) await prev.close(); | ||
| try { | ||
| runner ??= await this._createRunner(); | ||
| const prev = this._runner; | ||
| this._detach(); | ||
| this._attach(runner); | ||
| this._moduleInvalidated = false; | ||
| if (prev) await prev.close(); | ||
| } finally { | ||
| this._reloading = false; | ||
| } | ||
| } | ||
| _createRunner() { | ||
| throw new Error("reload() requires a runner argument (this manager has no runner factory)"); | ||
| } | ||
| fetch = (input, init) => this._fetch(input, init); | ||
@@ -33,4 +43,13 @@ async _fetch(input, init) { | ||
| if (!runner) return new Response("Runner is unavailable", { status: 503 }); | ||
| if (this._moduleInvalidated) await this._flushInvalidation(runner); | ||
| return runner.fetch(input, init); | ||
| } | ||
| _flushInvalidation(runner) { | ||
| this._pendingModuleReload ??= Promise.resolve(runner.reloadModule?.()).then(() => { | ||
| this._moduleInvalidated = false; | ||
| }).finally(() => { | ||
| this._pendingModuleReload = void 0; | ||
| }); | ||
| return this._pendingModuleReload; | ||
| } | ||
| upgrade = (context) => { | ||
@@ -100,4 +119,10 @@ this._runner?.upgrade?.(context); | ||
| if (!this._runner?.reloadModule) throw new Error("Active runner does not support reloadModule()"); | ||
| return this._runner.reloadModule(timeout); | ||
| await this._runner.reloadModule(timeout); | ||
| this._moduleInvalidated = false; | ||
| } | ||
| async invalidateModule(specifier, timeout) { | ||
| if (!this._runner?.invalidateModule) throw new Error("Active runner does not support invalidateModule()"); | ||
| await this._runner.invalidateModule(specifier, timeout); | ||
| this._moduleInvalidated = true; | ||
| } | ||
| async close() { | ||
@@ -209,2 +234,6 @@ this._closed = true; | ||
| } | ||
| async reload(runner) { | ||
| this.runner = runner ?? await this._createRunner(); | ||
| await super.reload(this.runner); | ||
| } | ||
| async close() { | ||
@@ -219,4 +248,3 @@ this._stopWatching(); | ||
| async _start() { | ||
| this.runner = await this._createRunner(); | ||
| await this.reload(this.runner); | ||
| await this.reload(); | ||
| if (this._opts.watch) this._startWatching(); | ||
@@ -254,4 +282,3 @@ return this; | ||
| try { | ||
| this.runner = await this._createRunner(); | ||
| await this.reload(this.runner); | ||
| await this.reload(); | ||
| for (const fn of this._reloadListeners) fn(); | ||
@@ -258,0 +285,0 @@ } catch (error) { |
| import { IncomingMessage } from "node:http"; | ||
| import { Socket } from "node:net"; | ||
| /** Handler for proxying HTTP requests to the worker. */ | ||
| /** | ||
| * Handler for proxying HTTP requests to the worker. | ||
| * | ||
| * A relative string input (e.g. `"/path"`) is resolved against a placeholder | ||
| * `http://localhost` origin before dispatching. | ||
| */ | ||
| type FetchHandler = (input: string | URL | Request, init?: RequestInit) => Promise<Response>; | ||
@@ -70,2 +75,7 @@ /** Callback for receiving messages from the worker. */ | ||
| reloadModule?(timeout?: number): Promise<void>; | ||
| /** | ||
| * Invalidate a virtual module so the next `reloadModule()` re-evaluates it. | ||
| * A factory-valued source is re-run for fresh contents. | ||
| */ | ||
| invalidateModule?(specifier: string, timeout?: number): Promise<void>; | ||
| /** Gracefully shut down the worker. */ | ||
@@ -72,0 +82,0 @@ close(): Promise<void>; |
@@ -6,8 +6,12 @@ async function resolveVirtualModules(virtual) { | ||
| const VIRTUAL_SCHEME = "virtual:"; | ||
| function createVirtualHooks(virtual) { | ||
| function createVirtualHooks(virtual, versions) { | ||
| const resolve = (specifier, context, nextResolve) => { | ||
| if (Object.hasOwn(virtual, _stripQuery(specifier))) return { | ||
| url: VIRTUAL_SCHEME + encodeURIComponent(specifier), | ||
| shortCircuit: true | ||
| }; | ||
| const key = _stripQuery(specifier); | ||
| if (Object.hasOwn(virtual, key)) { | ||
| const version = versions?.get(key); | ||
| return { | ||
| url: VIRTUAL_SCHEME + encodeURIComponent(specifier) + (version ? `?v=${version}` : ""), | ||
| shortCircuit: true | ||
| }; | ||
| } | ||
| return nextResolve(specifier, context); | ||
@@ -36,2 +40,22 @@ }; | ||
| } | ||
| function stripVirtualTypeScript(specifier, source, stripTypeScriptTypes, hints) { | ||
| if (typeof stripTypeScriptTypes !== "function") throw new TypeError(`[env-runner] virtual TypeScript module "${specifier}" requires \`module.stripTypeScriptTypes\` ${hints.requirement}; ${hints.remedy} or provide a pre-transpiled JavaScript source instead.`); | ||
| return stripTypeScriptTypes(source); | ||
| } | ||
| function expandVirtualInvalidation(virtual, specifier) { | ||
| const invalidated = [specifier]; | ||
| const seen = new Set(invalidated); | ||
| for (const target of invalidated) { | ||
| const refs = [ | ||
| `"${target}"`, | ||
| `'${target}'`, | ||
| "`" + target + "`" | ||
| ]; | ||
| for (const [key, source] of Object.entries(virtual)) if (!seen.has(key) && refs.some((ref) => source.includes(ref))) { | ||
| seen.add(key); | ||
| invalidated.push(key); | ||
| } | ||
| } | ||
| return invalidated; | ||
| } | ||
| function _stripQuery(specifier) { | ||
@@ -41,2 +65,2 @@ const qIndex = specifier.indexOf("?"); | ||
| } | ||
| export { createVirtualHooks, resolveVirtualModules, virtualModuleFormat }; | ||
| export { createVirtualHooks, expandVirtualInvalidation, resolveVirtualModules, stripVirtualTypeScript, virtualModuleFormat }; |
@@ -1,2 +0,2 @@ | ||
| import { createVirtualHooks, virtualModuleFormat } from "./virtual-loader.mjs"; | ||
| import { createVirtualHooks, expandVirtualInvalidation, stripVirtualTypeScript, virtualModuleFormat } from "./virtual-loader.mjs"; | ||
| import { existsSync, readFileSync } from "node:fs"; | ||
@@ -9,5 +9,21 @@ import { pathToFileURL } from "node:url"; | ||
| if (typeof registerHooks === "function") { | ||
| if ("Deno" in globalThis) virtual = _transformForDeno(virtual, stripTypeScriptTypes); | ||
| const hooks = registerHooks(createVirtualHooks(virtual)); | ||
| return _once(() => hooks.deregister()); | ||
| let transformSource; | ||
| if ("Deno" in globalThis) { | ||
| transformSource = (specifier, source) => _transformSourceForDeno(specifier, source, stripTypeScriptTypes); | ||
| const transformed = {}; | ||
| for (const [specifier, source] of Object.entries(virtual)) transformed[specifier] = transformSource(specifier, source); | ||
| virtual = transformed; | ||
| } | ||
| const registration = { | ||
| virtual, | ||
| versions: /* @__PURE__ */ new Map(), | ||
| transformSource | ||
| }; | ||
| const hooks = registerHooks(createVirtualHooks(virtual, registration.versions)); | ||
| _hooksRegistrations.unshift(registration); | ||
| return _once(() => { | ||
| const index = _hooksRegistrations.indexOf(registration); | ||
| if (index !== -1) _hooksRegistrations.splice(index, 1); | ||
| hooks.deregister(); | ||
| }); | ||
| } | ||
@@ -29,2 +45,26 @@ if (typeof globalThis.Bun?.plugin === "function") { | ||
| } | ||
| function invalidateVirtualModule(specifier, source) { | ||
| for (const registration of _hooksRegistrations) { | ||
| if (!Object.hasOwn(registration.virtual, specifier)) continue; | ||
| const { virtual, versions, transformSource } = registration; | ||
| if (source !== void 0) virtual[specifier] = transformSource ? transformSource(specifier, source) : source; | ||
| for (const key of expandVirtualInvalidation(virtual, specifier)) versions.set(key, (versions.get(key) ?? 0) + 1); | ||
| return true; | ||
| } | ||
| if (_bunVirtual && Object.hasOwn(_bunVirtual, specifier)) { | ||
| if (source !== void 0) _bunVirtual[specifier] = source; | ||
| _registerBunModules(expandVirtualInvalidation(_bunVirtual, specifier)); | ||
| return true; | ||
| } | ||
| return false; | ||
| } | ||
| function handleInvalidateModule(message, sendMessage) { | ||
| const ok = invalidateVirtualModule(message.specifier, message.source); | ||
| sendMessage({ | ||
| event: "module-invalidated", | ||
| specifier: message.specifier, | ||
| error: ok ? void 0 : `Cannot invalidate "${message.specifier}" (not a registered virtual module)` | ||
| }); | ||
| } | ||
| const _hooksRegistrations = []; | ||
| let _bunVirtual; | ||
@@ -51,13 +91,10 @@ function _registerBunModules(specifiers) { | ||
| } | ||
| function _transformForDeno(virtual, stripTypeScriptTypes) { | ||
| const out = {}; | ||
| for (const [specifier, source] of Object.entries(virtual)) { | ||
| const format = virtualModuleFormat(specifier); | ||
| if (format === "module-typescript") { | ||
| if (typeof stripTypeScriptTypes !== "function") throw new TypeError(`[env-runner] virtual TypeScript module "${specifier}" requires \`module.stripTypeScriptTypes\` (custom load hooks bypass Deno's native type stripping); upgrade Deno or provide a pre-transpiled JavaScript source instead.`); | ||
| out[specifier] = stripTypeScriptTypes(source); | ||
| } else if (format === "json") out[specifier] = `export default JSON.parse(${JSON.stringify(source)});`; | ||
| else out[specifier] = source; | ||
| } | ||
| return out; | ||
| function _transformSourceForDeno(specifier, source, stripTypeScriptTypes) { | ||
| const format = virtualModuleFormat(specifier); | ||
| if (format === "module-typescript") return stripVirtualTypeScript(specifier, source, stripTypeScriptTypes, { | ||
| requirement: "(custom load hooks bypass Deno's native type stripping)", | ||
| remedy: "upgrade Deno" | ||
| }); | ||
| if (format === "json") return `export default JSON.parse(${JSON.stringify(source)});`; | ||
| return source; | ||
| } | ||
@@ -117,2 +154,2 @@ const _noop = () => {}; | ||
| } | ||
| export { isVirtualSpecifier, parseServerAddress, registerVirtualModules, reloadEntryModule, resolveEntry }; | ||
| export { handleInvalidateModule, isVirtualSpecifier, parseServerAddress, registerVirtualModules, reloadEntryModule, resolveEntry }; |
+29
-3
@@ -19,2 +19,4 @@ import { EnvRunner, FetchHandler, NodeUpgradeContext, RPCOptions, RunnerMessageListener, RunnerRPCHooks, UpgradeContext, UpgradeHandler, WorkerAddress, WorkerHooks } from "./_chunks/types.mjs"; | ||
| private _reloading; | ||
| private _moduleInvalidated; | ||
| private _pendingModuleReload; | ||
| private _closeListeners; | ||
@@ -25,6 +27,19 @@ private _readyListeners; | ||
| get closed(): boolean; | ||
| /** Replace the active runner with a new one. Closes the previous runner. */ | ||
| reload(runner: EnvRunner): Promise<void>; | ||
| /** | ||
| * Replace the active runner with a new one. Closes the previous runner. | ||
| * | ||
| * When called without a runner, a fresh one is created via `_createRunner()` | ||
| * (only available on subclasses with a runner factory, e.g. `EnvServer`). | ||
| */ | ||
| reload(runner?: EnvRunner): Promise<void>; | ||
| /** Create a fresh runner for argument-less `reload()`. Overridden by subclasses with a runner factory. */ | ||
| protected _createRunner(): EnvRunner | Promise<EnvRunner>; | ||
| fetch: FetchHandler; | ||
| protected _fetch(input: string | URL | Request, init?: RequestInit): Promise<Response>; | ||
| /** | ||
| * Lazily satisfy a pending `invalidateModule()` with a single entry reload | ||
| * before serving — concurrent fetches share the same reload. A failed reload | ||
| * keeps the invalidation pending, so the next fetch retries. | ||
| */ | ||
| private _flushInvalidation; | ||
| upgrade: UpgradeHandler; | ||
@@ -39,2 +54,8 @@ sendMessage(message: unknown): void; | ||
| reloadModule(timeout?: number): Promise<void>; | ||
| /** | ||
| * Invalidate a virtual module on the active runner and mark the manager | ||
| * dirty: the next `fetch()` reloads the entry automatically, so callers | ||
| * don't need to pair the call with an explicit `reloadModule()`. | ||
| */ | ||
| invalidateModule(specifier: string, timeout?: number): Promise<void>; | ||
| close(): Promise<void>; | ||
@@ -101,2 +122,7 @@ [Symbol.asyncDispose](): Promise<void>; | ||
| start(): Promise<this>; | ||
| /** | ||
| * Replace the active runner. When called without an argument, a fresh | ||
| * runner is created from the server options. | ||
| */ | ||
| reload(runner?: EnvRunner): Promise<void>; | ||
| close(): Promise<void>; | ||
@@ -106,3 +132,3 @@ /** Auto-start on first fetch so an explicit `start()` call is optional. */ | ||
| private _start; | ||
| private _createRunner; | ||
| protected _createRunner(): Promise<EnvRunner>; | ||
| private _startWatching; | ||
@@ -109,0 +135,0 @@ private _stopWatching; |
@@ -1,2 +0,2 @@ | ||
| import { isVirtualSpecifier, parseServerAddress, registerVirtualModules, reloadEntryModule, resolveEntry } from "../../_chunks/worker-utils.mjs"; | ||
| import { handleInvalidateModule, isVirtualSpecifier, parseServerAddress, registerVirtualModules, reloadEntryModule, resolveEntry } from "../../_chunks/worker-utils.mjs"; | ||
| import { serve } from "srvx"; | ||
@@ -61,2 +61,6 @@ import { plugin } from "crossws/server"; | ||
| } | ||
| if (message?.event === "invalidate-module") { | ||
| handleInvalidateModule(message, sendMessage); | ||
| return; | ||
| } | ||
| if (message?.type === "ping") { | ||
@@ -63,0 +67,0 @@ process.send({ |
@@ -1,2 +0,2 @@ | ||
| import { isVirtualSpecifier, parseServerAddress, registerVirtualModules, reloadEntryModule, resolveEntry } from "../../_chunks/worker-utils.mjs"; | ||
| import { handleInvalidateModule, isVirtualSpecifier, parseServerAddress, registerVirtualModules, reloadEntryModule, resolveEntry } from "../../_chunks/worker-utils.mjs"; | ||
| import { serve } from "srvx"; | ||
@@ -82,2 +82,6 @@ import { plugin } from "crossws/server"; | ||
| } | ||
| if (message?.event === "invalidate-module") { | ||
| handleInvalidateModule(message, sendMessage); | ||
| return; | ||
| } | ||
| if (message?.type === "ping") { | ||
@@ -84,0 +88,0 @@ sendMessage({ |
@@ -1,2 +0,2 @@ | ||
| import { isVirtualSpecifier, parseServerAddress, registerVirtualModules, reloadEntryModule, resolveEntry } from "../../_chunks/worker-utils.mjs"; | ||
| import { handleInvalidateModule, isVirtualSpecifier, parseServerAddress, registerVirtualModules, reloadEntryModule, resolveEntry } from "../../_chunks/worker-utils.mjs"; | ||
| import { serve } from "srvx"; | ||
@@ -61,2 +61,6 @@ import { plugin } from "crossws/server/node"; | ||
| } | ||
| if (message?.event === "invalidate-module") { | ||
| handleInvalidateModule(message, sendMessage); | ||
| return; | ||
| } | ||
| if (message?.type === "ping") { | ||
@@ -63,0 +67,0 @@ process.send({ |
@@ -1,2 +0,2 @@ | ||
| import { isVirtualSpecifier, parseServerAddress, registerVirtualModules, reloadEntryModule, resolveEntry } from "../../_chunks/worker-utils.mjs"; | ||
| import { handleInvalidateModule, isVirtualSpecifier, parseServerAddress, registerVirtualModules, reloadEntryModule, resolveEntry } from "../../_chunks/worker-utils.mjs"; | ||
| import { parentPort, workerData } from "node:worker_threads"; | ||
@@ -61,2 +61,6 @@ import { serve } from "srvx"; | ||
| } | ||
| if (message?.event === "invalidate-module") { | ||
| handleInvalidateModule(message, sendMessage); | ||
| return; | ||
| } | ||
| if (message?.type === "ping") { | ||
@@ -63,0 +67,0 @@ parentPort?.postMessage({ |
@@ -19,2 +19,3 @@ import { WorkerHooks } from "../../_chunks/types.mjs"; | ||
| sendMessage(message: unknown): void; | ||
| invalidateModule(specifier: string): Promise<void>; | ||
| reloadModule(): Promise<void>; | ||
@@ -21,0 +22,0 @@ protected _hasRuntime(): boolean; |
@@ -16,3 +16,3 @@ import { BaseEnvRunner } from "../../_chunks/base-runner.mjs"; | ||
| if (!this.#entry || this.closed) return new Response("self env runner is unavailable", { status: 503 }); | ||
| const request = input instanceof Request ? input : new Request(input, init); | ||
| const request = input instanceof Request ? input : new Request(this._resolveFetchInput(input), init); | ||
| return this.#entry.fetch(request); | ||
@@ -39,2 +39,5 @@ } | ||
| } | ||
| async invalidateModule(specifier) { | ||
| throw new Error(`Cannot invalidate "${specifier}": the self runner does not support virtual modules`); | ||
| } | ||
| async reloadModule() { | ||
@@ -41,0 +44,0 @@ const entryPath = this._data?.entry; |
@@ -24,1 +24,20 @@ # Licenses of Bundled Dependencies | ||
| > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| --------------------------------------- | ||
| ## es-module-lexer | ||
| License: MIT | ||
| By: Guy Bedford | ||
| Repository: https://github.com/guybedford/es-module-lexer | ||
| > MIT License | ||
| > ----------- | ||
| > | ||
| > Copyright (C) 2018-2022 Guy Bedford | ||
| > | ||
| > Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: | ||
| > | ||
| > The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. | ||
| > | ||
| > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
+2
-1
| { | ||
| "name": "env-runner", | ||
| "version": "0.1.10", | ||
| "version": "0.1.11", | ||
| "description": "Generic environment runner for JavaScript runtimes.", | ||
@@ -61,2 +61,3 @@ "license": "MIT", | ||
| "env-runner-fixture": "link:", | ||
| "es-module-lexer": "^2.1.0", | ||
| "miniflare": "^4.20260603.0", | ||
@@ -63,0 +64,0 @@ "obuild": "^0.4.36", |
+18
-1
@@ -70,2 +70,5 @@ # env-runner | ||
| // Restart with a fresh runner created from the server options | ||
| await envServer.reload(); | ||
| // Use with any HTTP server | ||
@@ -145,3 +148,4 @@ const server = serve({ | ||
| // Proxy HTTP requests (retries with exponential backoff) | ||
| const response = await runner.fetch("http://localhost/api"); | ||
| // Relative URLs are resolved against a placeholder origin | ||
| const response = await runner.fetch("/api"); | ||
@@ -164,2 +168,6 @@ // Proxy WebSocket upgrades | ||
| // Invalidate a virtual module (re-runs a factory source), then reload | ||
| await runner.invalidateModule("#config.json"); | ||
| await runner.reloadModule(); | ||
| // Graceful shutdown happens automatically at the end of the scope | ||
@@ -244,2 +252,11 @@ // (`await using`) — or call `await runner.close()` explicitly | ||
| To refresh a single virtual module without restarting the worker, call `invalidateModule(specifier)`: a factory-valued source is re-run on the host and the module is invalidated in the worker so its **next import evaluates fresh**. Virtual modules that import the invalidated one (directly or transitively) are invalidated along with it, so the fresh module is picked up even through intermediate virtual importers. Already-imported modules keep their instances, so pair it with `reloadModule()` to re-import the entry graph: | ||
| ```ts | ||
| await runner.invalidateModule("#config"); // re-runs the factory, busts the module | ||
| await runner.reloadModule(); // re-imports the entry, picking up the fresh module | ||
| ``` | ||
| When fetching through `RunnerManager` or `EnvServer`, the reload is automatic: `invalidateModule()` marks the manager dirty and the next `fetch()` reloads the entry once before serving (concurrent fetches share the reload), so no explicit `reloadModule()` call is needed. | ||
| The module format is derived from the specifier extension: `.ts`/`.mts` sources are served as **TypeScript** and `.json` sources as **JSON modules**; everything else is plain JavaScript ESM: | ||
@@ -246,0 +263,0 @@ |
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Unidentified License
LicenseSomething that seems like a license was found, but its contents could not be matched with a known license.
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
Found 2 instances
187556
18.74%58
1.75%2869
12.55%589
2.97%31
-3.12%16
6.67%1
Infinity%80
-20%