refactor
parent
8e1392cad5
commit
f727f17c22
|
|
@ -51,25 +51,6 @@ const cfg = (options: Record<string, unknown> | undefined) => {
|
|||
}
|
||||
}
|
||||
|
||||
const boot = (meta?: TuiPluginInit) => {
|
||||
if (!meta) {
|
||||
return {
|
||||
state: "unknown",
|
||||
first: false,
|
||||
updated: false,
|
||||
count: 0,
|
||||
source: "n/a",
|
||||
}
|
||||
}
|
||||
return {
|
||||
state: meta.state,
|
||||
first: meta.first,
|
||||
updated: meta.updated,
|
||||
count: meta.entry.load_count,
|
||||
source: meta.entry.source,
|
||||
}
|
||||
}
|
||||
|
||||
const names = (input: ReturnType<typeof cfg>) => {
|
||||
return {
|
||||
modal: `${input.route}.modal`,
|
||||
|
|
@ -358,7 +339,7 @@ const Screen = (props: {
|
|||
input: ReturnType<typeof cfg>
|
||||
route: ReturnType<typeof names>
|
||||
keys: Keys
|
||||
meta: ReturnType<typeof boot>
|
||||
meta: TuiPluginInit
|
||||
params?: Record<string, unknown>
|
||||
}) => {
|
||||
const dim = useTerminalDimensions()
|
||||
|
|
@ -549,9 +530,9 @@ const Screen = (props: {
|
|||
<text fg={skin.muted}>plugin state: {props.meta.state}</text>
|
||||
<text fg={skin.muted}>
|
||||
first: {props.meta.first ? "yes" : "no"} · updated: {props.meta.updated ? "yes" : "no"} · loads:{" "}
|
||||
{props.meta.count}
|
||||
{props.meta.entry.load_count}
|
||||
</text>
|
||||
<text fg={skin.muted}>plugin source: {props.meta.source}</text>
|
||||
<text fg={skin.muted}>plugin source: {props.meta.entry.source}</text>
|
||||
<text fg={skin.muted}>source: {value.source}</text>
|
||||
<text fg={skin.muted}>note: {value.note || "(none)"}</text>
|
||||
<text fg={skin.muted}>selected: {value.selected || "(none)"}</text>
|
||||
|
|
@ -875,24 +856,23 @@ const reg = (api: TuiApi, input: ReturnType<typeof cfg>, keys: Keys) => {
|
|||
])
|
||||
}
|
||||
|
||||
const tui = async (input: TuiPluginInput, options?: Record<string, unknown>, meta?: TuiPluginInit) => {
|
||||
const tui = async (input: TuiPluginInput, options: Record<string, unknown> | null, meta: TuiPluginInit) => {
|
||||
if (options?.enabled === false) return
|
||||
|
||||
await input.api.theme.install("./smoke-theme.json")
|
||||
input.api.theme.set("smoke-theme")
|
||||
|
||||
const value = cfg(options)
|
||||
const value = cfg(options ?? undefined)
|
||||
const route = names(value)
|
||||
const keys = input.api.keybind.create(bind, value.keybinds)
|
||||
const fx = new VignetteEffect(value.vignette)
|
||||
const info = boot(meta)
|
||||
input.renderer.addPostProcessFn(fx.apply.bind(fx))
|
||||
|
||||
input.api.route.register([
|
||||
{
|
||||
name: route.screen,
|
||||
render: ({ params }) => (
|
||||
<Screen api={input.api} input={value} route={route} keys={keys} meta={info} params={params} />
|
||||
<Screen api={input.api} input={value} route={route} keys={keys} meta={meta} params={params} />
|
||||
),
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -129,15 +129,6 @@ function makeInstallFn(meta: TuiConfig.PluginMeta, root: string): TuiTheme["inst
|
|||
}
|
||||
}
|
||||
|
||||
function initData(meta: { state: PluginMeta.State; entry: PluginMeta.Entry }): TuiPluginInit {
|
||||
return {
|
||||
state: meta.state,
|
||||
first: meta.state === "new",
|
||||
updated: meta.state === "changed",
|
||||
entry: meta.entry,
|
||||
}
|
||||
}
|
||||
|
||||
export namespace TuiPlugin {
|
||||
const log = Log.create({ service: "tui.plugin" })
|
||||
let loaded: Promise<void> | undefined
|
||||
|
|
@ -225,6 +216,31 @@ export namespace TuiPlugin {
|
|||
})
|
||||
}
|
||||
|
||||
const now = Date.now()
|
||||
const init: TuiPluginInit = meta
|
||||
? {
|
||||
state: meta.state,
|
||||
first: meta.state === "new",
|
||||
updated: meta.state === "changed",
|
||||
entry: meta.entry,
|
||||
}
|
||||
: {
|
||||
state: "new",
|
||||
first: true,
|
||||
updated: false,
|
||||
entry: {
|
||||
name: spec,
|
||||
source: spec.startsWith("file://") ? "file" : "npm",
|
||||
spec,
|
||||
target,
|
||||
first_time: now,
|
||||
last_time: now,
|
||||
time_changed: now,
|
||||
load_count: 1,
|
||||
fingerprint: target,
|
||||
},
|
||||
}
|
||||
|
||||
const root = pluginRoot(spec, target)
|
||||
const install = makeInstallFn(getPluginMeta(config, item), root)
|
||||
const mod = await import(target).catch((error) => {
|
||||
|
|
@ -238,7 +254,7 @@ export namespace TuiPlugin {
|
|||
spec,
|
||||
mod,
|
||||
install,
|
||||
init: meta ? initData(meta) : undefined,
|
||||
init,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -293,7 +309,7 @@ export namespace TuiPlugin {
|
|||
}),
|
||||
},
|
||||
},
|
||||
Config.pluginOptions(load.item),
|
||||
Config.pluginOptions(load.item) ?? null,
|
||||
load.init,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ mock.module("@opentui/solid/jsx-runtime", () => ({
|
|||
}))
|
||||
const { allThemes, addTheme } = await import("../../../src/cli/cmd/tui/context/theme")
|
||||
const { TuiPlugin } = await import("../../../src/cli/cmd/tui/plugin")
|
||||
const { PluginMeta } = await import("../../../src/plugin/meta")
|
||||
|
||||
async function waitForLog(text: string, timeout = 1000) {
|
||||
const start = Date.now()
|
||||
|
|
@ -281,6 +282,12 @@ export const object_plugin = {
|
|||
})
|
||||
process.env.OPENCODE_PLUGIN_META_FILE = path.join(tmp.path, "plugin-meta.json")
|
||||
if (!process.env.OPENCODE_PLUGIN_META_FILE) throw new Error("missing meta file")
|
||||
await PluginMeta.touch(tmp.extra.localSpec, tmp.extra.localSpec)
|
||||
await PluginMeta.touch(tmp.extra.globalSpec, tmp.extra.globalSpec)
|
||||
await PluginMeta.persist()
|
||||
await Bun.sleep(20)
|
||||
const text = await Bun.file(tmp.extra.globalPluginPath).text()
|
||||
await Bun.write(tmp.extra.globalPluginPath, `${text}\n`)
|
||||
|
||||
const cwd = spyOn(process, "cwd").mockImplementation(() => tmp.path)
|
||||
let selected = "opencode"
|
||||
|
|
@ -410,21 +417,21 @@ export const object_plugin = {
|
|||
expect(local.depth_after).toBe(1)
|
||||
expect(local.open_after).toBe(true)
|
||||
expect(local.open_clear).toBe(false)
|
||||
expect(local.init_state).toBe("new")
|
||||
expect(local.init_first).toBe(true)
|
||||
expect(local.init_state).toBe("same")
|
||||
expect(local.init_first).toBe(false)
|
||||
expect(local.init_updated).toBe(false)
|
||||
expect(local.init_source).toBe("file")
|
||||
expect(local.init_load_count).toBe(1)
|
||||
expect(local.init_load_count).toBe(2)
|
||||
|
||||
const global = JSON.parse(await fs.readFile(tmp.extra.globalMarker, "utf8"))
|
||||
expect(global.has).toBe(true)
|
||||
expect(global.set_installed).toBe(true)
|
||||
expect(global.selected).toBe(tmp.extra.globalThemeName)
|
||||
expect(global.init_state).toBe("new")
|
||||
expect(global.init_first).toBe(true)
|
||||
expect(global.init_updated).toBe(false)
|
||||
expect(global.init_state).toBe("changed")
|
||||
expect(global.init_first).toBe(false)
|
||||
expect(global.init_updated).toBe(true)
|
||||
expect(global.init_source).toBe("file")
|
||||
expect(global.init_load_count).toBe(1)
|
||||
expect(global.init_load_count).toBe(2)
|
||||
|
||||
const preloaded = JSON.parse(await fs.readFile(tmp.extra.preloadedMarker, "utf8"))
|
||||
expect(preloaded.before).toBe(true)
|
||||
|
|
@ -470,9 +477,12 @@ export const object_plugin = {
|
|||
|
||||
const meta = JSON.parse(await fs.readFile(path.join(tmp.path, "plugin-meta.json"), "utf8")) as Record<
|
||||
string,
|
||||
{ spec: string; load_count: number }
|
||||
{ name: string; load_count: number }
|
||||
>
|
||||
expect(Object.keys(meta).length > 0).toBe(true)
|
||||
const rows = Object.values(meta)
|
||||
expect(rows.find((item) => item.name === "local-plugin")?.load_count).toBe(2)
|
||||
expect(rows.find((item) => item.name === "global-plugin")?.load_count).toBe(2)
|
||||
expect(rows.find((item) => item.name === "preloaded-plugin")?.load_count).toBe(1)
|
||||
} finally {
|
||||
cwd.mockRestore()
|
||||
if (backup === undefined) {
|
||||
|
|
|
|||
|
|
@ -6,12 +6,6 @@ mock.module("@opentui/solid/jsx-runtime", () => ({
|
|||
jsxs: () => null,
|
||||
jsxDEV: () => null,
|
||||
}))
|
||||
mock.module("@opentui/solid", () => ({
|
||||
useRenderer: () => ({
|
||||
getPalette: async () => ({ palette: [] as string[] }),
|
||||
clearPaletteCache: () => {},
|
||||
}),
|
||||
}))
|
||||
|
||||
const { DEFAULT_THEMES, allThemes, addTheme, hasTheme } = await import("../../../src/cli/cmd/tui/context/theme")
|
||||
|
||||
|
|
|
|||
|
|
@ -223,8 +223,8 @@ export type TuiPluginInput<Renderer = CliRenderer, Node = unknown> = {
|
|||
|
||||
export type TuiPlugin<Renderer = CliRenderer, Node = unknown> = (
|
||||
input: TuiPluginInput<Renderer, Node>,
|
||||
options?: PluginOptions,
|
||||
init?: TuiPluginInit,
|
||||
options: PluginOptions | null,
|
||||
init: TuiPluginInit,
|
||||
) => Promise<void>
|
||||
|
||||
export type TuiPluginModule<Renderer = CliRenderer, Node = unknown> = {
|
||||
|
|
|
|||
Loading…
Reference in New Issue