refactor: unwrap PluginLoader namespace + self-reexport
This commit is contained in:
parent
f9aa3d77cd
commit
75cbba355e
1 changed files with 139 additions and 139 deletions
|
|
@ -11,30 +11,29 @@ import {
|
||||||
import { ConfigPlugin } from "@/config/plugin"
|
import { ConfigPlugin } from "@/config/plugin"
|
||||||
import { InstallationVersion } from "@/installation/version"
|
import { InstallationVersion } from "@/installation/version"
|
||||||
|
|
||||||
export namespace PluginLoader {
|
export type Plan = {
|
||||||
export type Plan = {
|
|
||||||
spec: string
|
spec: string
|
||||||
options: ConfigPlugin.Options | undefined
|
options: ConfigPlugin.Options | undefined
|
||||||
deprecated: boolean
|
deprecated: boolean
|
||||||
}
|
}
|
||||||
export type Resolved = Plan & {
|
export type Resolved = Plan & {
|
||||||
source: PluginSource
|
source: PluginSource
|
||||||
target: string
|
target: string
|
||||||
entry: string
|
entry: string
|
||||||
pkg?: PluginPackage
|
pkg?: PluginPackage
|
||||||
}
|
}
|
||||||
export type Missing = Plan & {
|
export type Missing = Plan & {
|
||||||
source: PluginSource
|
source: PluginSource
|
||||||
target: string
|
target: string
|
||||||
pkg?: PluginPackage
|
pkg?: PluginPackage
|
||||||
message: string
|
message: string
|
||||||
}
|
}
|
||||||
export type Loaded = Resolved & {
|
export type Loaded = Resolved & {
|
||||||
mod: Record<string, unknown>
|
mod: Record<string, unknown>
|
||||||
}
|
}
|
||||||
|
|
||||||
type Candidate = { origin: ConfigPlugin.Origin; plan: Plan }
|
type Candidate = { origin: ConfigPlugin.Origin; plan: Plan }
|
||||||
type Report = {
|
type Report = {
|
||||||
start?: (candidate: Candidate, retry: boolean) => void
|
start?: (candidate: Candidate, retry: boolean) => void
|
||||||
missing?: (candidate: Candidate, retry: boolean, message: string, resolved: Missing) => void
|
missing?: (candidate: Candidate, retry: boolean, message: string, resolved: Missing) => void
|
||||||
error?: (
|
error?: (
|
||||||
|
|
@ -44,21 +43,21 @@ export namespace PluginLoader {
|
||||||
error: unknown,
|
error: unknown,
|
||||||
resolved?: Resolved,
|
resolved?: Resolved,
|
||||||
) => void
|
) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
function plan(item: ConfigPlugin.Spec): Plan {
|
function plan(item: ConfigPlugin.Spec): Plan {
|
||||||
const spec = ConfigPlugin.pluginSpecifier(item)
|
const spec = ConfigPlugin.pluginSpecifier(item)
|
||||||
return { spec, options: ConfigPlugin.pluginOptions(item), deprecated: isDeprecatedPlugin(spec) }
|
return { spec, options: ConfigPlugin.pluginOptions(item), deprecated: isDeprecatedPlugin(spec) }
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function resolve(
|
export async function resolve(
|
||||||
plan: Plan,
|
plan: Plan,
|
||||||
kind: PluginKind,
|
kind: PluginKind,
|
||||||
): Promise<
|
): Promise<
|
||||||
| { ok: true; value: Resolved }
|
| { ok: true; value: Resolved }
|
||||||
| { ok: false; stage: "missing"; value: Missing }
|
| { ok: false; stage: "missing"; value: Missing }
|
||||||
| { ok: false; stage: "install" | "entry" | "compatibility"; error: unknown }
|
| { ok: false; stage: "install" | "entry" | "compatibility"; error: unknown }
|
||||||
> {
|
> {
|
||||||
let target = ""
|
let target = ""
|
||||||
try {
|
try {
|
||||||
target = await resolvePluginTarget(plan.spec)
|
target = await resolvePluginTarget(plan.spec)
|
||||||
|
|
@ -94,9 +93,9 @@ export namespace PluginLoader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return { ok: true, value: { ...plan, source: base.source, target: base.target, entry: base.entry, pkg: base.pkg } }
|
return { ok: true, value: { ...plan, source: base.source, target: base.target, entry: base.entry, pkg: base.pkg } }
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function load(row: Resolved): Promise<{ ok: true; value: Loaded } | { ok: false; error: unknown }> {
|
export async function load(row: Resolved): Promise<{ ok: true; value: Loaded } | { ok: false; error: unknown }> {
|
||||||
let mod
|
let mod
|
||||||
try {
|
try {
|
||||||
mod = await import(row.entry)
|
mod = await import(row.entry)
|
||||||
|
|
@ -105,16 +104,16 @@ export namespace PluginLoader {
|
||||||
}
|
}
|
||||||
if (!mod) return { ok: false, error: new Error(`Plugin ${row.spec} module is empty`) }
|
if (!mod) return { ok: false, error: new Error(`Plugin ${row.spec} module is empty`) }
|
||||||
return { ok: true, value: { ...row, mod } }
|
return { ok: true, value: { ...row, mod } }
|
||||||
}
|
}
|
||||||
|
|
||||||
async function attempt<R>(
|
async function attempt<R>(
|
||||||
candidate: Candidate,
|
candidate: Candidate,
|
||||||
kind: PluginKind,
|
kind: PluginKind,
|
||||||
retry: boolean,
|
retry: boolean,
|
||||||
finish: ((load: Loaded, origin: ConfigPlugin.Origin, retry: boolean) => Promise<R | undefined>) | undefined,
|
finish: ((load: Loaded, origin: ConfigPlugin.Origin, retry: boolean) => Promise<R | undefined>) | undefined,
|
||||||
missing: ((value: Missing, origin: ConfigPlugin.Origin, retry: boolean) => Promise<R | undefined>) | undefined,
|
missing: ((value: Missing, origin: ConfigPlugin.Origin, retry: boolean) => Promise<R | undefined>) | undefined,
|
||||||
report: Report | undefined,
|
report: Report | undefined,
|
||||||
): Promise<R | undefined> {
|
): Promise<R | undefined> {
|
||||||
const plan = candidate.plan
|
const plan = candidate.plan
|
||||||
if (plan.deprecated) return
|
if (plan.deprecated) return
|
||||||
report?.start?.(candidate, retry)
|
report?.start?.(candidate, retry)
|
||||||
|
|
@ -138,18 +137,18 @@ export namespace PluginLoader {
|
||||||
}
|
}
|
||||||
if (!finish) return loaded.value as R
|
if (!finish) return loaded.value as R
|
||||||
return finish(loaded.value, candidate.origin, retry)
|
return finish(loaded.value, candidate.origin, retry)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Input<R> = {
|
type Input<R> = {
|
||||||
items: ConfigPlugin.Origin[]
|
items: ConfigPlugin.Origin[]
|
||||||
kind: PluginKind
|
kind: PluginKind
|
||||||
wait?: () => Promise<void>
|
wait?: () => Promise<void>
|
||||||
finish?: (load: Loaded, origin: ConfigPlugin.Origin, retry: boolean) => Promise<R | undefined>
|
finish?: (load: Loaded, origin: ConfigPlugin.Origin, retry: boolean) => Promise<R | undefined>
|
||||||
missing?: (value: Missing, origin: ConfigPlugin.Origin, retry: boolean) => Promise<R | undefined>
|
missing?: (value: Missing, origin: ConfigPlugin.Origin, retry: boolean) => Promise<R | undefined>
|
||||||
report?: Report
|
report?: Report
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function loadExternal<R = Loaded>(input: Input<R>): Promise<R[]> {
|
export async function loadExternal<R = Loaded>(input: Input<R>): Promise<R[]> {
|
||||||
const candidates = input.items.map((origin) => ({ origin, plan: plan(origin.spec) }))
|
const candidates = input.items.map((origin) => ({ origin, plan: plan(origin.spec) }))
|
||||||
const list: Array<Promise<R | undefined>> = []
|
const list: Array<Promise<R | undefined>> = []
|
||||||
for (const candidate of candidates) {
|
for (const candidate of candidates) {
|
||||||
|
|
@ -170,5 +169,6 @@ export namespace PluginLoader {
|
||||||
const ready: R[] = []
|
const ready: R[] = []
|
||||||
for (const item of out) if (item !== undefined) ready.push(item)
|
for (const item of out) if (item !== undefined) ready.push(item)
|
||||||
return ready
|
return ready
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export * as PluginLoader from "./loader"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue