dx: refactor with a better name
Massimo Melina committed
Oct 12, 2025 at 18:30 UTC
eb073f7ffb0c414e483fae1342dc360cdac83373
4 files changed
+24
-24
src/api.plugins.ts
+3
-3
@@ -1,7 +1,7 @@
1
// This file is part of HFS - Copyright 2021-2023, Massimo Melina <a@rejetto.com> - License https://www.gnu.org/licenses/gpl-3.0.txt
2
3
import {
4
- AvailablePlugin, enablePlugins, getAvailablePlugins, getPluginConfigFields, mapPlugins, Plugin, pluginsConfig,
4
+ InactivePlugin, enablePlugins, getInactivePlugins, getPluginConfigFields, mapPlugins, Plugin, pluginsConfig,
5
PATH as PLUGINS_PATH, enablePlugin, getPluginInfo, setPluginConfig, isPluginRunning,
6
stopPlugin, startPlugin, CommonPluginInterface, getMissingDependencies, findPluginByRepo, suspendPlugins,
7
} from './plugins'
@@ -19,7 +19,7 @@ import { SendListReadable } from './SendList'
19
const apis: ApiHandlers = {
20
21
get_plugins({}, ctx) {
22
- const list = new SendListReadable({ addAtStart: [ ...mapPlugins(serialize, false), ...getAvailablePlugins().map(serialize) ] })
22
+ const list = new SendListReadable({ addAtStart: [ ...mapPlugins(serialize, false), ...getInactivePlugins().map(serialize) ] })
23
return list.events(ctx, {
24
pluginInstalled: p => list.add(serialize(p)),
25
'pluginStarted pluginStopped pluginUpdated': p => {
@@ -185,7 +185,7 @@ const apis: ApiHandlers = {
185
186
export default apis
187
188
-function serialize(p: Readonly<Plugin> | AvailablePlugin) {
188
+function serialize(p: Readonly<Plugin> | InactivePlugin) {
189
let o = 'getData' in p ? Object.assign(_.pick(p, ['id','started']), p.getData())
190
: { ...p } // _.defaults mutates object, and we don't want that
191
if (typeof o.repo === 'object') // custom repo
src/commands.ts
+2
-2
@@ -9,7 +9,7 @@ import yaml from 'yaml'
9
import { BUILD_TIMESTAMP, VERSION } from './const'
10
import { createInterface, cursorTo } from 'node:readline'
11
import { quitting } from './first'
12
-import { getAvailablePlugins, mapPlugins, startPlugin, stopPlugin } from './plugins'
12
+import { getInactivePlugins, mapPlugins, startPlugin, stopPlugin } from './plugins'
13
import { purgeFileAttr } from './fileAttr'
14
import { downloadPlugin } from './github'
15
import { Dict, formatBytes, formatSpeed, formatTimestamp, makeMatcher } from './cross'
@@ -181,7 +181,7 @@ const commands = {
181
params: '',
182
cb() {
183
mapPlugins(p => console.log('ON:', p.id), false)
184
- getAvailablePlugins().map(p => console.log('OFF:', p.id))
184
+ getInactivePlugins().map(p => console.log('OFF:', p.id))
185
}
186
},
187
'purge-file-attr': {
src/github.ts
+2
-2
@@ -5,7 +5,7 @@ import {
5
httpString, httpStream, unzip, AsapStream, debounceAsync, asyncGeneratorToArray, wait, popKey, onlyTruthy, HOUR
6
} from './misc'
7
import {
8
- DISABLING_SUFFIX, enablePlugin, findPluginByRepo, getAvailablePlugins, getPluginInfo, isPluginRunning, mapPlugins,
8
+ DISABLING_SUFFIX, enablePlugin, findPluginByRepo, getInactivePlugins, getPluginInfo, isPluginRunning, mapPlugins,
9
parsePluginSource, PATH as PLUGINS_PATH, Repo, startPlugin, stopPlugin, STORAGE_FOLDER, DELETE_ME_SUFFIX,
10
PLUGIN_MAIN_FILE
11
} from './plugins'
@@ -190,7 +190,7 @@ export async function readOnlineCompatiblePlugin(repo: Repo, branch='') {
190
}
191
192
export function getFolder2repo() {
193
- const ret = Object.fromEntries(getAvailablePlugins().map(x => [x.id, x.repo]))
193
+ const ret = Object.fromEntries(getInactivePlugins().map(x => [x.id, x.repo]))
194
Object.assign(ret, Object.fromEntries(mapPlugins(x => [x.id, x.getData().repo])))
195
return ret
196
}
src/plugins.ts
+17
-17
@@ -103,14 +103,14 @@ export function setPluginConfig(id: string, changes: Dict | null) {
103
104
export function getPluginInfo(id: string) {
105
const running = plugins.get(id)
106
- return running && { ...running.getData(), ...running } || availablePlugins[id]
106
+ return running && { ...running.getData(), ...running } || inactivePlugins[id]
107
}
108
109
export function findPluginByRepo<T>(repo: string) {
110
for (const pl of plugins.values())
111
if (match(pl.getData()))
112
return pl
113
- return _.find(availablePlugins, match)
113
+ return _.find(inactivePlugins, match)
114
115
function match(rec: any) {
116
return repo === (rec?.repo?.main ?? rec?.repo)
@@ -385,16 +385,16 @@ export interface CommonPluginInterface {
385
preview?: string | string[]
386
changelog?: unknown
387
}
388
-export interface AvailablePlugin extends CommonPluginInterface {
388
+export interface InactivePlugin extends CommonPluginInterface {
389
branch?: string
390
badApi?: string
391
error?: string
392
}
393
394
-let availablePlugins: Record<string, AvailablePlugin> = {}
394
+let inactivePlugins: Record<string, InactivePlugin> = {}
395
396
-export function getAvailablePlugins() {
397
- return Object.values(availablePlugins)
396
+export function getInactivePlugins() {
397
+ return Object.values(inactivePlugins)
398
}
399
400
const rescanAsap = debounceAsync(rescan, { wait: 1000 })
@@ -447,14 +447,14 @@ function watchPlugin(id: string, path: string) {
447
stop()
448
}, [enablePlugins, suspendPlugins])
449
const { unwatch } = watchLoad(module, async source => {
450
- const notRunning = availablePlugins[id]
450
+ const notRunning = inactivePlugins[id]
451
if (!source)
452
return onUninstalled()
453
if (isPluginEnabled(id, true))
454
return start()
455
const p = parsePluginSource(id, source)
456
if (same(notRunning, p)) return
457
- availablePlugins[id] = p
457
+ inactivePlugins[id] = p
458
events.emit(notRunning ? 'pluginUpdated' : 'pluginInstalled', p)
459
})
460
return () => {
@@ -467,13 +467,13 @@ function watchPlugin(id: string, path: string) {
467
async function onUninstalled() {
468
await stop()
469
if (!getPluginInfo(id)) return // already missing
470
- delete availablePlugins[id]
470
+ delete inactivePlugins[id]
471
events.emit('pluginUninstalled', id)
472
}
473
474
- async function markItAvailable() {
474
+ async function markItInactive() {
475
plugins.delete(id)
476
- availablePlugins[id] = await parsePlugin()
476
+ inactivePlugins[id] = await parsePlugin()
477
}
478
479
async function parsePlugin() {
@@ -485,7 +485,7 @@ function watchPlugin(id: string, path: string) {
485
const p = plugins.get(id)
486
if (!p) return
487
await p.unload()
488
- await markItAvailable().catch(() =>
488
+ await markItInactive().catch(() =>
489
events.emit('pluginUninstalled', id)) // when a running plugin is deleted, avoid error and report
490
events.emit('pluginStopped', p)
491
}
@@ -583,14 +583,14 @@ function watchPlugin(id: string, path: string) {
583
if (alreadyRunning)
584
events.emit('pluginUpdated', Object.assign(_.pick(plugin, 'started'), getPluginInfo(id)))
585
else {
586
- const wasInstalled = availablePlugins[id]
586
+ const wasInstalled = inactivePlugins[id]
587
if (wasInstalled)
588
- delete availablePlugins[id]
588
+ delete inactivePlugins[id]
589
events.emit(wasInstalled ? 'pluginStarted' : 'pluginInstalled', plugin)
590
}
591
events.emit('pluginStarted:'+id)
592
} catch (e: any) {
593
- await markItAvailable()
593
+ await markItInactive()
594
const parsed = e.stack?.split('\n\n') // this form is used by syntax-errors inside the plugin, which is useful to show
595
const where = parsed?.length > 1 ? `\n${parsed[0]}` : ''
596
e = prefix('', e.message, where) || String(e)
@@ -648,7 +648,7 @@ onProcessExit(() =>
648
Promise.allSettled(mapPlugins(pl => pl.unload())))
649
650
export function parsePluginSource(id: string, source: string) {
651
- const pl: AvailablePlugin = { id }
651
+ const pl: InactivePlugin = { id }
652
pl.description = tryJson(/exports.description\s*=\s*(".*")/.exec(source)?.[1])
653
pl.repo = tryJson(/exports.repo\s*=\s*(\S*)/.exec(source)?.[1])
654
pl.version = Number(/exports.version\s*=\s*(\d*\.?\d+)/.exec(source)?.[1]) ?? undefined
@@ -665,7 +665,7 @@ export function parsePluginSource(id: string, source: string) {
665
return pl
666
}
667
668
-function calculateBadApi(data: AvailablePlugin) {
668
+function calculateBadApi(data: InactivePlugin) {
669
const r = data.apiRequired
670
const [min, max] = Array.isArray(r) ? r : [r, r] // normalize data type
671
data.badApi = min! > API_VERSION ? "may not work correctly as it is designed for a newer version of HFS - check for updates"