Skip to content

Commit

Permalink
feat(manager): support new loader API
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed May 31, 2024
1 parent e81545e commit d771a32
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 66 deletions.
37 changes: 18 additions & 19 deletions plugins/insight/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,24 @@ export function apply(ctx: Context) {
}
}

function addNode(scope: EffectScope) {
const { uid, entry, disposables, status, runtime } = scope
assert(uid !== null)
const weight = disposables.length
const isGroup = !!runtime.plugin?.[Symbol.for('cordis.group')]
const isRoot = uid === 0
const name = getName(runtime.plugin)
const node = { uid, name, weight, status, isGroup, isRoot, services: services[uid!] }
if (entry) node.name += ` [${entry.options.id}]`
nodes.push(node)
}

function addEdge(type: 'dashed' | 'solid', source: number | null, target: number | null) {
assert(source !== null)
assert(target !== null)
edges.push({ type, source, target })
}

for (const runtime of ctx.registry.values()) {
// Suppose we have the following types of nodes:
// - A, B: parent plugin scopes
Expand All @@ -104,25 +122,6 @@ export function apply(ctx: Context) {
return true
}

const name = getName(runtime.plugin)

function addNode(scope: EffectScope) {
const { uid, entry, disposables, status, runtime } = scope
assert(uid !== null)
const weight = disposables.length
const isGroup = !!runtime.plugin?.[Symbol.for('cordis.group')]
const isRoot = uid === 0
const node = { uid, name, weight, status, isGroup, isRoot, services: services[uid!] }
if (entry) node.name += ` [${entry.options.id}]`
nodes.push(node)
}

function addEdge(type: 'dashed' | 'solid', source: number | null, target: number | null) {
assert(source !== null)
assert(target !== null)
edges.push({ type, source, target })
}

const addDeps = (scope: EffectScope) => {
for (const name of runtime.using) {
const instance = ctx.get(name)
Expand Down
3 changes: 2 additions & 1 deletion plugins/manager/client/components/forks.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<table>
<tr v-for="id in plugins.forks[dialogFork!]" :key="id">
<td class="text-left">
<span class="status-light" :class="ctx.manager.getStatus(plugins.entries[id])"></span>
<span class="status-light" :class="getStatusClass(plugins.entries[id].status)"></span>
<span class="path">{{ getFullPath(plugins.entries[id]) }}</span>
</td>
<td class="text-right">
Expand Down Expand Up @@ -43,6 +43,7 @@
import { computed } from 'vue'
import { send, router, useContext } from '@cordisjs/client'
import { getStatusClass } from './utils'
import { EntryData } from '../../src'
const ctx = useContext()
Expand Down
1 change: 0 additions & 1 deletion plugins/manager/client/components/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@
import { computed, ref, watch, nextTick } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { clone, message, send, useContext, Schema } from '@cordisjs/client'
import { Node } from '..'
import GroupSettings from './group.vue'
import TreeView from './tree.vue'
import PluginSettings from './plugin.vue'
Expand Down
19 changes: 14 additions & 5 deletions plugins/manager/client/components/tree.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@
<div class="label" :title="getLabel(node)">
{{ getLabel(node) }}
</div>
<!-- FIXME: subpath, relative, etc. -->
<div class="right">
<span v-if="node.data.name" class="status-light" :class="ctx.manager.getStatus(node.data)"></span>
<span class="status-light" :class="getStatusClass(node.data.status)"></span>
</div>
</div>
</el-tree>
Expand All @@ -41,13 +42,15 @@ import { useRoute } from 'vue-router'
import type { ElScrollbar, ElTree } from 'element-plus'
import type { FilterNodeMethodFunction, TreeOptionProps } from 'element-plus/es/components/tree/src/tree.type'
import type TreeNode from 'element-plus/es/components/tree/src/model/node'
import { send, useContext, useMenu } from '@cordisjs/client'
import { EntryData } from '../../src'
import { send, useContext, useMenu, useRpc } from '@cordisjs/client'
import { getStatusClass } from './utils'
import { Data, EntryData } from '../../src'
const props = defineProps<{
modelValue: string
}>()
const data = useRpc<Data>()
const ctx = useContext()
const route = useRoute()
const trigger = useMenu('config.tree')
Expand Down Expand Up @@ -138,9 +141,9 @@ function handleCollapse(data: EntryData, target: EntryNode, instance: any) {
function handleDrop(source: EntryNode, target: EntryNode, position: 'before' | 'after' | 'inner', event: DragEvent) {
const parent = position === 'inner' ? target : target.parent
const index = parent.childNodes.findIndex(node => node.data.id === source.data.id)
send('manager.config.transfer', {
send('manager.config.update', {
id: source.data.id,
parent: parent.data.id,
parent: parent.parent ? parent.data.id : null,
position: index,
})
}
Expand Down Expand Up @@ -186,6 +189,12 @@ watch(keyword, (val) => {
&.is-group > .el-tree-node__content {
font-weight: bold;
}
&.is-disabled {
.el-tree-node__content .status-light {
display: none;
}
}
}
.el-tree-node__content {
Expand Down
12 changes: 12 additions & 0 deletions plugins/manager/client/components/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { ScopeStatus } from '@cordisjs/client'

export function getStatusClass(status: ScopeStatus) {
switch (status) {
case ScopeStatus.PENDING: return 'pending'
case ScopeStatus.LOADING: return 'loading'
case ScopeStatus.ACTIVE: return 'active'
case ScopeStatus.FAILED: return 'failed'
case ScopeStatus.DISPOSED: return 'disposed'
default: return 'disabled'
}
}
14 changes: 2 additions & 12 deletions plugins/manager/client/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Context, Dict, router, ScopeStatus, send, Service } from '@cordisjs/client'
import { Context, Dict, router, send, Service } from '@cordisjs/client'
import { computed, defineComponent, h, Ref, ref, resolveComponent } from 'vue'
import type { Data, EntryData } from '../src'
import Settings from './components/index.vue'
Expand Down Expand Up @@ -59,6 +59,7 @@ export default class Manager extends Service {
const entries: Dict<EntryData> = Object.fromEntries(this.data.value.entries.map(options => [options.id, options]))
const buildChildren = (parent: string | null) => this.data.value.entries
.filter(entry => entry.parent === parent)
.sort((a, b) => a.position - b.position)
.map((options) => {
const node: Node = {
...options,
Expand Down Expand Up @@ -203,17 +204,6 @@ export default class Manager extends Service {
return this.plugins.value.forks[name]?.map(id => this.plugins.value.entries[id])
}

getStatus(data: EntryData) {
switch (this.data.value.packages[data.name]?.runtime?.forks?.[data.id]?.status) {
case ScopeStatus.PENDING: return 'pending'
case ScopeStatus.LOADING: return 'loading'
case ScopeStatus.ACTIVE: return 'active'
case ScopeStatus.FAILED: return 'failed'
case ScopeStatus.DISPOSED: return 'disposed'
default: return 'disabled'
}
}

getEnvInfo(name?: string) {
function setService(name: string, required: boolean) {
if (services.has(name)) return
Expand Down
45 changes: 17 additions & 28 deletions plugins/manager/src/shared.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,23 @@
import { Context, MainScope, Plugin, Schema, ScopeStatus, Service } from 'cordis'
import { Dict, pick } from 'cosmokit'
import { Entry as LoaderEntry } from '@cordisjs/loader'
import { EntryOptions } from '@cordisjs/loader'
import { Entry as ClientEntry } from '@cordisjs/plugin-webui'
import { LocalObject } from '@cordisjs/registry'
import {} from '@cordisjs/plugin-hmr'

declare module '@cordisjs/loader' {
namespace Entry {
interface Options {
label?: string | null
collapse?: boolean | null
}
interface EntryOptions {
label?: string | null
collapse?: boolean | null
}
}

declare module '@cordisjs/plugin-webui' {
interface Events {
'manager.config.list'(): EntryData[]
'manager.config.create'(options: Omit<LoaderEntry.Options, 'id'> & EntryLocation): Promise<string>
'manager.config.update'(options: Omit<LoaderEntry.Options, 'name'>): void
'manager.config.create'(options: Omit<EntryOptions, 'id'> & EntryLocation): Promise<string>
'manager.config.update'(options: Omit<EntryOptions, 'name'> & EntryLocation): void
'manager.config.remove'(options: { id: string }): void
'manager.config.transfer'(options: { id: string } & EntryLocation): void
'manager.package.list'(): Promise<LocalObject[]>
'manager.package.runtime'(options: { name: string }): Promise<RuntimeData>
'manager.service.list'(): Dict<string[]>
Expand All @@ -33,8 +30,9 @@ declare module '@cordisjs/registry' {
}
}

export interface EntryData extends LoaderEntry.Options, Required<EntryLocation> {
export interface EntryData extends EntryOptions, Required<EntryLocation> {
isGroup?: boolean
status?: ScopeStatus
}

export interface Data {
Expand All @@ -52,9 +50,6 @@ export interface RuntimeData {
required?: string[]
optional?: string[]
failed?: boolean
forks?: Dict<{
status?: ScopeStatus
}>
}

export interface EntryLocation {
Expand All @@ -77,12 +72,14 @@ export abstract class Manager extends Service {
}

getEntries() {
return Object.values(this.ctx.loader.entries).map<EntryData>((entry) => ({
return [...this.ctx.loader.entries()].map<EntryData>((entry) => ({
...entry.options,
config: entry.children?.data === entry.options.config ? undefined : entry.options.config,
parent: entry.parent.ctx.scope.entry?.options.id ?? null,
id: entry.id,
config: entry.subgroup?.data === entry.options.config ? undefined : entry.options.config,
parent: entry.parent.ctx.scope.entry?.id ?? null,
position: entry.parent.data.indexOf(entry.options),
isGroup: !!entry.children,
isGroup: !!entry.subgroup,
status: entry.fork?.status,
}))
}

Expand Down Expand Up @@ -114,7 +111,7 @@ export abstract class Manager extends Service {
services: this.getServices(),
}))

ctx.on('config', ctx.debounce(() => {
ctx.on('loader/config-update', ctx.debounce(() => {
this.entry?.patch({ entries: this.getEntries() })
}, 0))

Expand All @@ -140,19 +137,14 @@ export abstract class Manager extends Service {
})

ctx.webui.addListener('manager.config.update', (options) => {
const { id, ...rest } = options
return ctx.loader.update(id, rest)
const { id, parent, position, ...rest } = options
return ctx.loader.update(id, rest, parent, position)
})

ctx.webui.addListener('manager.config.remove', (options) => {
return ctx.loader.remove(options.id)
})

ctx.webui.addListener('manager.config.transfer', (options) => {
const { id, parent, position } = options
return ctx.loader.transfer(id, parent ?? '', position)
})

ctx.webui.addListener('manager.package.list', async () => {
return await this.getPackages()
})
Expand Down Expand Up @@ -202,9 +194,6 @@ export abstract class Manager extends Service {
parseRuntime(main: MainScope, runtime: RuntimeData) {
runtime.id = main.uid
runtime.forkable = main.isForkable
runtime.forks = Object.fromEntries(main.children
.filter(fork => fork.entry)
.map(fork => [fork.entry!.options.id, { status: fork.status }]))
}

async parseExports(name: string) {
Expand Down

0 comments on commit d771a32

Please sign in to comment.