mirror of
https://github.com/anomalyco/opencode.git
synced 2026-10-24 06:35:26 +08:00
53 lines
2.0 KiB
TypeScript
53 lines
2.0 KiB
TypeScript
import { registerHooks } from "node:module"
|
|
import path from "node:path"
|
|
import { fileURLToPath } from "node:url"
|
|
import { localSource } from "./source.js"
|
|
import { missingPackageTarget } from "./source.package.js"
|
|
import { Host } from "./host.js"
|
|
|
|
let generation = Date.now()
|
|
|
|
export async function prepareSource(entrypoint: string, track: (file: string, directory?: boolean) => void) {
|
|
const version = String(++generation)
|
|
const fresh = (specifier: string) => {
|
|
const url = new URL(specifier)
|
|
url.searchParams.set("__opencode_reload", version)
|
|
return url.href
|
|
}
|
|
const hook = registerHooks({
|
|
resolve(specifier, context, nextResolve) {
|
|
if (!context.parentURL || new URL(context.parentURL).searchParams.get("__opencode_reload") !== version)
|
|
return nextResolve(specifier, context)
|
|
const local =
|
|
specifier.startsWith("./") || specifier.startsWith("../")
|
|
? new URL(specifier, context.parentURL)
|
|
: localSource(specifier, path.dirname(fileURLToPath(context.parentURL)))
|
|
if (!local) {
|
|
try {
|
|
return nextResolve(specifier, context)
|
|
} catch (error) {
|
|
const target = missingPackageTarget(specifier, fileURLToPath(context.parentURL))
|
|
if (target) track(target, true)
|
|
throw error
|
|
}
|
|
}
|
|
if (fileURLToPath(local).split(path.sep).includes("node_modules")) return nextResolve(specifier, context)
|
|
const resolved = (() => {
|
|
try {
|
|
return nextResolve(specifier, context)
|
|
} catch (error) {
|
|
track(path.dirname(fileURLToPath(local)), true)
|
|
throw error
|
|
}
|
|
})()
|
|
if (!resolved.url.startsWith("file:")) return resolved
|
|
const file = fileURLToPath(resolved.url)
|
|
if (file.split(path.sep).includes("node_modules")) return resolved
|
|
track(file)
|
|
return { ...resolved, url: fresh(resolved.url) }
|
|
},
|
|
})
|
|
const specifier = fresh(entrypoint)
|
|
return { version: specifier, load: () => Host.load(specifier), dispose: () => hook.deregister() }
|
|
}
|