Skip to content

Commit

Permalink
wip: simplify types. move legacy check to a file inside modules
Browse files Browse the repository at this point in the history
  • Loading branch information
Julusian committed Nov 24, 2024
1 parent 58246f1 commit 1ae05d9
Show file tree
Hide file tree
Showing 24 changed files with 111 additions and 137 deletions.
4 changes: 2 additions & 2 deletions companion/lib/Instance/Host.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import type { ConnectionConfig } from '@companion-app/shared/Model/Connections.j
import type { InstanceModules } from './Modules.js'
import type { ConnectionConfigStore } from './ConnectionConfigStore.js'
import { isModuleApiVersionCompatible } from '@companion-app/shared/ModuleApiVersionCheck.js'
import type { SomeModuleVersionInfo } from './Types.js'
import type { ModuleVersionInfo } from './Types.js'

/**
* A backoff sleep strategy
Expand Down Expand Up @@ -325,7 +325,7 @@ export class ModuleHost {
async queueRestartConnection(
connectionId: string,
config: ConnectionConfig | undefined,
moduleInfo: SomeModuleVersionInfo | undefined
moduleInfo: ModuleVersionInfo | undefined
): Promise<void> {
if (!config || !moduleInfo) return

Expand Down
28 changes: 14 additions & 14 deletions companion/lib/Instance/ModuleInfo.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { NewClientModuleInfo, NewClientModuleVersionInfo2 } from '@companion-app/shared/Model/ModuleInfo.js'
import type { SomeModuleVersionInfo } from './Types.js'
import type { ClientModuleInfo, ClientModuleVersionInfo } from '@companion-app/shared/Model/ModuleInfo.js'
import type { ModuleVersionInfo } from './Types.js'
import semver from 'semver'
import { compact } from 'lodash-es'
import { isModuleApiVersionCompatible } from '@companion-app/shared/ModuleApiVersionCheck.js'
Expand All @@ -12,44 +12,44 @@ export class InstanceModuleInfo {

replacedByIds: string[] = []

devModule: SomeModuleVersionInfo | null = null
devModule: ModuleVersionInfo | null = null

installedVersions: Record<string, SomeModuleVersionInfo | undefined> = {}
installedVersions: Record<string, ModuleVersionInfo | undefined> = {}

constructor(id: string) {
this.id = id
}

getVersion(versionId: string | null): SomeModuleVersionInfo | null {
getVersion(versionId: string | null): ModuleVersionInfo | null {
if (versionId === 'dev') return this.devModule

if (versionId === null) return null // TODO - is this correct?

return this.installedVersions[versionId] ?? null
}

getLatestVersion(isBeta: boolean): SomeModuleVersionInfo | null {
let latest: SomeModuleVersionInfo | null = null
getLatestVersion(isBeta: boolean): ModuleVersionInfo | null {
let latest: ModuleVersionInfo | null = null
for (const version of Object.values(this.installedVersions)) {
if (!version || version.isBeta !== isBeta) continue
if (!isModuleApiVersionCompatible(version.manifest.runtime.apiVersion)) continue
if (!latest || semver.compare(version.display.version, latest.display.version) > 0) {
if (!latest || semver.compare(version.versionId, latest.versionId) > 0) {
latest = version
}
}

return latest
}

toClientJson(): NewClientModuleInfo | null {
toClientJson(): ClientModuleInfo | null {
const stableVersion = this.getLatestVersion(false)
const betaVersion = this.getLatestVersion(true)

const baseVersion = stableVersion ?? betaVersion ?? Object.values(this.installedVersions)[0]
if (!baseVersion) return null

return {
baseInfo: baseVersion.display,
display: baseVersion.display,

devVersion: translateStableVersion(this.devModule),

Expand All @@ -61,7 +61,7 @@ export class InstanceModuleInfo {
}
}

function translateStableVersion(version: SomeModuleVersionInfo | null): NewClientModuleVersionInfo2 | null {
function translateStableVersion(version: ModuleVersionInfo | null): ClientModuleVersionInfo | null {
if (!version) return null
if (version.versionId === 'dev') {
return {
Expand All @@ -74,18 +74,18 @@ function translateStableVersion(version: SomeModuleVersionInfo | null): NewClien
} else {
return {
displayName: `Latest ${version.isBeta ? 'Beta' : 'Stable'} (v${version.versionId})`,
isLegacy: version.display.isLegacy ?? false,
isLegacy: version.isLegacy,
hasHelp: version.helpPath !== null,
isBeta: version.isBeta,
versionId: version.versionId,
}
}
}

function translateReleaseVersion(version: SomeModuleVersionInfo): NewClientModuleVersionInfo2 {
function translateReleaseVersion(version: ModuleVersionInfo): ClientModuleVersionInfo {
return {
displayName: `v${version.versionId}`,
isLegacy: version.display.isLegacy ?? false,
isLegacy: version.isLegacy,
isBeta: version.isBeta,
hasHelp: version.helpPath !== null,
versionId: version.versionId,
Expand Down
19 changes: 11 additions & 8 deletions companion/lib/Instance/ModuleScanner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import LogController from '../Log/Controller.js'
import path from 'path'
import fs from 'fs-extra'
import { ModuleManifest, validateManifest } from '@companion-module/base'
import type { SomeModuleVersionInfo } from './Types.js'
import type { ModuleVersionInfo } from './Types.js'
import type { ModuleDisplayInfo } from '@companion-app/shared/Model/ModuleInfo.js'

export class InstanceModuleScanner {
Expand All @@ -14,11 +14,11 @@ export class InstanceModuleScanner {
* @param searchDir - Path to search for modules
* @param checkForPackaged - Whether to check for a packaged version
*/
async loadInfoForModulesInDir(searchDir: string, checkForPackaged: boolean): Promise<SomeModuleVersionInfo[]> {
async loadInfoForModulesInDir(searchDir: string, checkForPackaged: boolean): Promise<ModuleVersionInfo[]> {
if (await fs.pathExists(searchDir)) {
const candidates = await fs.readdir(searchDir)

const ps: Promise<SomeModuleVersionInfo | undefined>[] = []
const ps: Promise<ModuleVersionInfo | undefined>[] = []

for (const candidate of candidates) {
const candidatePath = path.join(searchDir, candidate)
Expand All @@ -37,7 +37,7 @@ export class InstanceModuleScanner {
* @param fullpath - Fullpath to the module
* @param checkForPackaged - Whether to check for a packaged version
*/
async loadInfoForModule(fullpath: string, checkForPackaged: boolean): Promise<SomeModuleVersionInfo | undefined> {
async loadInfoForModule(fullpath: string, checkForPackaged: boolean): Promise<ModuleVersionInfo | undefined> {
try {
let isPackaged = false
const pkgDir = path.join(fullpath, 'pkg')
Expand All @@ -61,33 +61,36 @@ export class InstanceModuleScanner {
validateManifest(manifestJson)

const helpPath = path.join(fullpath, 'companion/HELP.md')
const isLegacyPath = path.join(fullpath, '.is-legacy') // TODO - provide for modules

const hasHelp = await fs.pathExists(helpPath)
const isLegacy = await fs.pathExists(isLegacyPath)

const moduleDisplay: ModuleDisplayInfo = {
id: manifestJson.id,
name: manifestJson.manufacturer + ': ' + manifestJson.products.join('; '),
version: manifestJson.version,
hasHelp: hasHelp,
// version: manifestJson.version,
// hasHelp: hasHelp,
bugUrl: manifestJson.bugs || manifestJson.repository,
shortname: manifestJson.shortname,
manufacturer: manifestJson.manufacturer,
products: manifestJson.products,
keywords: manifestJson.keywords,
}

const moduleManifestExt: SomeModuleVersionInfo = {
const moduleManifestExt: ModuleVersionInfo = {
versionId: manifestJson.version,
manifest: manifestJson,
basePath: path.resolve(fullpath),
helpPath: hasHelp ? helpPath : null,
display: moduleDisplay,
isPackaged: isPackaged,
isLegacy: isLegacy,
// @ts-expect-error Not in manifest schema yet
isBeta: manifestJson.releaseChannel === 'beta',
}

this.#logger.silly(`found module ${moduleDisplay.id}@${moduleDisplay.version}`)
this.#logger.silly(`found module ${moduleDisplay.id}@${manifestJson.version}`)

return moduleManifestExt
} catch (e) {
Expand Down
24 changes: 10 additions & 14 deletions companion/lib/Instance/Modules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ import { cloneDeep } from 'lodash-es'
import { InstanceModuleScanner } from './ModuleScanner.js'
import type express from 'express'
import { type ModuleManifest } from '@companion-module/base'
import type { NewClientModuleInfo } from '@companion-app/shared/Model/ModuleInfo.js'
import type { ClientModuleInfo } from '@companion-app/shared/Model/ModuleInfo.js'
import type { ClientSocket, UIHandler } from '../UI/Handler.js'
import type { HelpDescription } from '@companion-app/shared/Model/Common.js'
import LogController from '../Log/Controller.js'
import type { InstanceController } from './Controller.js'
import jsonPatch from 'fast-json-patch'
import type { SomeModuleVersionInfo } from './Types.js'
import type { ModuleVersionInfo } from './Types.js'
import { InstanceModuleInfo } from './ModuleInfo.js'

const ModulesRoom = 'modules'
Expand All @@ -48,7 +48,7 @@ export class InstanceModules {
/**
* Last module info sent to clients
*/
#lastModulesJson: Record<string, NewClientModuleInfo> | null = null
#lastModulesJson: Record<string, ClientModuleInfo> | null = null

/**
* Known module info
Expand Down Expand Up @@ -91,9 +91,8 @@ export class InstanceModules {

// Update the module info
const moduleInfo = this.#getOrCreateModuleEntry(manifest.id)
moduleInfo.installedVersions[loadedModuleInfo.display.version] = {
moduleInfo.installedVersions[loadedModuleInfo.versionId] = {
...loadedModuleInfo,
versionId: loadedModuleInfo.display.version,
isPackaged: true,
}

Expand Down Expand Up @@ -144,9 +143,8 @@ export class InstanceModules {
const storeModules = await this.#moduleScanner.loadInfoForModulesInDir(this.#installedModulesDir, true)
for (const candidate of storeModules) {
const moduleInfo = this.#getOrCreateModuleEntry(candidate.manifest.id)
moduleInfo.installedVersions[candidate.display.version] = {
moduleInfo.installedVersions[candidate.versionId] = {
...candidate,
versionId: candidate.display.version,
isPackaged: true,
}
}
Expand Down Expand Up @@ -197,7 +195,7 @@ export class InstanceModules {

for (const moduleVersion of Object.values(moduleInfo.installedVersions)) {
if (!moduleVersion) continue
this.#logger.info(`${moduleVersion.display.id}@${moduleVersion.display.version}: ${moduleVersion.display.name}`)
this.#logger.info(`${moduleVersion.display.id}@${moduleVersion.versionId}: ${moduleVersion.display.name}`)
}
}
}
Expand All @@ -210,9 +208,7 @@ export class InstanceModules {

const reloadedModule = await this.#moduleScanner.loadInfoForModule(fullpath, true)
if (reloadedModule) {
this.#logger.info(
`Found new module "${reloadedModule.display.id}" v${reloadedModule.display.version} in: ${fullpath}`
)
this.#logger.info(`Found new module ${reloadedModule.display.id}@${reloadedModule.versionId} in: ${fullpath}`)

// Replace any existing module
const moduleInfo = this.#getOrCreateModuleEntry(reloadedModule.manifest.id)
Expand Down Expand Up @@ -325,8 +321,8 @@ export class InstanceModules {
/**
* Get display version of module infos
*/
getModulesJson(): Record<string, NewClientModuleInfo> {
const result: Record<string, NewClientModuleInfo> = {}
getModulesJson(): Record<string, ClientModuleInfo> {
const result: Record<string, ClientModuleInfo> = {}

for (const [id, moduleInfo] of this.#knownModules.entries()) {
const clientModuleInfo = moduleInfo.toClientJson()
Expand All @@ -341,7 +337,7 @@ export class InstanceModules {
/**
* Get the manifest for a module
*/
getModuleManifest(moduleId: string, versionId: string | null): SomeModuleVersionInfo | undefined {
getModuleManifest(moduleId: string, versionId: string | null): ModuleVersionInfo | undefined {
return this.#knownModules.get(moduleId)?.getVersion(versionId) ?? undefined
}

Expand Down
16 changes: 2 additions & 14 deletions companion/lib/Instance/Types.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,13 @@
import type { ModuleDisplayInfo } from '@companion-app/shared/Model/ModuleInfo.js'
import type { ModuleManifest } from '@companion-module/base'

export interface SomeModuleVersionInfo {
export interface ModuleVersionInfo {
versionId: string // 'dev' or a semver version
basePath: string
helpPath: string | null
display: ModuleDisplayInfo
manifest: ModuleManifest
isPackaged: boolean
isBeta: boolean
isLegacy: boolean
}

// export interface ReleaseModuleVersionInfo extends ModuleVersionInfoBase {
// type: 'release'
// versionId: string
// isBeta: boolean
// isPackaged: true
// }
// export interface DevModuleVersionInfo extends ModuleVersionInfoBase {
// type: 'dev'
// isPackaged: boolean
// isBeta: false
// }
// export type SomeModuleVersionInfo = ReleaseModuleVersionInfo | DevModuleVersionInfo
29 changes: 8 additions & 21 deletions shared-lib/lib/Model/ModuleInfo.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,6 @@
import type { Operation as JsonPatchOperation } from 'fast-json-patch'

export interface ModuleDisplayInfo {
id: string
name: string
version: string
hasHelp: boolean
bugUrl: string
shortname: string
manufacturer: string
products: string[]
keywords: string[]
isLegacy?: boolean
}

export interface NewClientModuleBaseInfo {
id: string
name: string
// hasHelp: boolean
Expand All @@ -24,23 +11,23 @@ export interface NewClientModuleBaseInfo {
keywords: string[]
}

export interface NewClientModuleVersionInfo2 {
export interface ClientModuleVersionInfo {
displayName: string
isLegacy: boolean
isBeta: boolean
hasHelp: boolean
versionId: string
}

export interface NewClientModuleInfo {
baseInfo: NewClientModuleBaseInfo
export interface ClientModuleInfo {
display: ModuleDisplayInfo

devVersion: NewClientModuleVersionInfo2 | null
devVersion: ClientModuleVersionInfo | null

stableVersion: NewClientModuleVersionInfo2 | null
betaVersion: NewClientModuleVersionInfo2 | null
stableVersion: ClientModuleVersionInfo | null
betaVersion: ClientModuleVersionInfo | null

installedVersions: NewClientModuleVersionInfo2[]
installedVersions: ClientModuleVersionInfo[]
}

export type ModuleInfoUpdate = ModuleInfoUpdateAddOp | ModuleInfoUpdateUpdateOp | ModuleInfoUpdateRemoveOp
Expand All @@ -53,7 +40,7 @@ export interface ModuleInfoUpdateAddOp {
type: 'add'
id: string

info: NewClientModuleInfo
info: ClientModuleInfo
}
export interface ModuleInfoUpdateUpdateOp {
type: 'update'
Expand Down
4 changes: 2 additions & 2 deletions shared-lib/lib/SocketIO.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ import type { RecordSessionInfo, RecordSessionListInfo } from './Model/ActionRec
import type { ActionDefinitionUpdate, ClientActionDefinition } from './Model/ActionDefinitionModel.js'
import type { CloudControllerState, CloudRegionState } from './Model/Cloud.js'
import type { ClientConnectionsUpdate, ClientConnectionConfig, ConnectionUpdatePolicy } from './Model/Connections.js'
import type { ModuleInfoUpdate, NewClientModuleInfo } from './Model/ModuleInfo.js'
import type { ModuleInfoUpdate, ClientModuleInfo } from './Model/ModuleInfo.js'
import type { ModuleStoreListCacheStore, ModuleStoreModuleInfoStore } from './Model/ModulesStore.js'

export interface ClientToBackendEventsMap {
Expand Down Expand Up @@ -81,7 +81,7 @@ export interface ClientToBackendEventsMap {
'event-definitions:get': () => Record<string, ClientEventDefinition | undefined>
'custom-variables:subscribe': () => CustomVariablesModel
'custom-variables:unsubscribe': () => void
'modules:subscribe': () => Record<string, NewClientModuleInfo>
'modules:subscribe': () => Record<string, ClientModuleInfo>
'modules:unsubscribe': () => void
'connections:subscribe': () => Record<string, ClientConnectionConfig>
'connections:unsubscribe': () => void
Expand Down
4 changes: 2 additions & 2 deletions webui/src/Buttons/Presets/PresetsCategoryList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ import React, { useCallback } from 'react'
import { CAlert, CButton, CButtonGroup } from '@coreui/react'
import type { ClientConnectionConfig } from '@companion-app/shared/Model/Connections.js'
import type { UIPresetDefinition } from '@companion-app/shared/Model/Presets.js'
import type { NewClientModuleInfo } from '@companion-app/shared/Model/ModuleInfo.js'
import type { ClientModuleInfo } from '@companion-app/shared/Model/ModuleInfo.js'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faArrowLeft } from '@fortawesome/free-solid-svg-icons'

interface PresetsCategoryListProps {
presets: Record<string, UIPresetDefinition>
connectionInfo: ClientConnectionConfig | undefined
moduleInfo: NewClientModuleInfo | undefined
moduleInfo: ClientModuleInfo | undefined
selectedConnectionId: string
setConnectionAndCategory: (info: [connectionId: string | null, category: string | null]) => void
}
Expand Down
Loading

0 comments on commit 1ae05d9

Please sign in to comment.