Skip to content

Commit

Permalink
refa: upgrade cordis api
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Dec 1, 2024
1 parent f4d8d6b commit 63fdff3
Show file tree
Hide file tree
Showing 15 changed files with 79 additions and 88 deletions.
2 changes: 0 additions & 2 deletions packages/client/app/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ root.plugin(status)
root.plugin(styles)
root.plugin(theme)

root.start()

if (!global.static) {
const endpoint = new URL(global.endpoint, location.origin).toString()
connect(root, () => new WebSocket(endpoint.replace(/^http/, 'ws')))
Expand Down
12 changes: 6 additions & 6 deletions packages/client/app/styles/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ $white: #ffffff;

@mixin apply-color($name, $base) {
--k-color-#{$name}: #{$base};
--k-color-#{$name}-shade: #{mix($base, $black, 90%)};
--k-color-#{$name}-tint: #{mix($base, $white, 80%)};
--k-color-#{$name}-fade: #{fade-out($base, 0.9)};
--k-color-#{$name}-shade: #{color.mix($base, $black, 90%)};
--k-color-#{$name}-tint: #{color.mix($base, $white, 80%)};
--k-color-#{$name}-fade: #{color.scale($base, $alpha: -90%)};
}

@include apply-color(primary, #409eff);
Expand Down Expand Up @@ -89,9 +89,9 @@ html.dark, .theme-root.dark {

@mixin apply-color($name, $base) {
--k-color-#{$name}: #{$base};
--k-color-#{$name}-shade: #{mix($base, $black, 80%)};
--k-color-#{$name}-tint: #{mix($base, $white, 90%)};
--k-color-#{$name}-fade: #{fade-out($base, 0.9)};
--k-color-#{$name}-shade: #{color.mix($base, $black, 80%)};
--k-color-#{$name}-tint: #{color.mix($base, $white, 90%)};
--k-color-#{$name}-fade: #{color.scale($base, $alpha: -90%)};
}

@include apply-color(primary, #7459ff);
Expand Down
2 changes: 1 addition & 1 deletion packages/client/client/plugins/action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export function useMenu<K extends keyof ActionContext>(id: K) {

export default class ActionService extends Service {
constructor(ctx: Context) {
super(ctx, '$action', true)
super(ctx, '$action')
ctx.mixin('$action', ['action', 'menu', 'define'])

ctx.internal.scope = shallowReactive({})
Expand Down
2 changes: 1 addition & 1 deletion packages/client/client/plugins/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export default class I18nService extends Service {
})

constructor(ctx: Context) {
super(ctx, '$i18n', true)
super(ctx, '$i18n')

ctx.effect(() => watchEffect(() => {
this.i18n.global.locale.value = config.value.locale
Expand Down
16 changes: 8 additions & 8 deletions packages/client/client/plugins/loader.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Ref, ref, shallowReactive } from 'vue'
import { Context } from '../context'
import { Service } from '../utils'
import { ForkScope } from 'cordis'
import { EffectScope } from 'cordis'
import { defineProperty, Dict } from 'cosmokit'
import { clientId } from '../data'

Expand All @@ -23,7 +23,7 @@ export function unwrapExports(module: any) {
return module?.default || module
}

type LoaderFactory = (ctx: Context, url: string) => Promise<ForkScope>
type LoaderFactory = (ctx: Context, url: string) => Promise<EffectScope>

function jsLoader(ctx: Context, exports: {}) {
return ctx.plugin(unwrapExports(exports), ctx.$entry.data)
Expand All @@ -48,7 +48,7 @@ const loaders: Dict<LoaderFactory> = {
const link = document.createElement('link')
link.rel = 'stylesheet'
link.href = url
return ctx.plugin(cssLoader, link)
return ctx.plugin(cssLoader, link as any)
},
async [``](ctx, url) {
const exports = await import(/* @vite-ignore */ url)
Expand All @@ -57,8 +57,8 @@ const loaders: Dict<LoaderFactory> = {
}

export interface LoadState {
forks: ForkScope[]
paths: string[]
forks: EffectScope[]
entryId?: string
done: Ref<boolean>
data: Ref
}
Expand All @@ -69,7 +69,7 @@ export default class LoaderService extends Service {
public entries: Dict<LoadState> = shallowReactive({})

constructor(ctx: Context) {
super(ctx, '$loader', true)
super(ctx, '$loader')

ctx.on('entry:update', ({ id, data }) => {
const entry = this.entries[id]
Expand Down Expand Up @@ -113,11 +113,11 @@ export default class LoaderService extends Service {
return
}

const { files, paths = [], data } = body
const { files, entryId, data } = body
const ctx = this.ctx.isolate('$entry')
ctx.$entry = this.entries[key] = {
done: ref(false),
paths,
entryId,
data: ref(data),
forks: [],
}
Expand Down
65 changes: 37 additions & 28 deletions packages/client/client/plugins/router.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createRouter, createWebHistory, START_LOCATION } from 'vue-router'
import { createRouter, createWebHistory, RouteLocation, START_LOCATION } from 'vue-router'
import { Context } from '../context'
import { insert, Service } from '../utils'
import { Component, MaybeRefOrGetter, reactive, ref, toValue } from 'vue'
Expand Down Expand Up @@ -50,19 +50,31 @@ function getActivityId(path: string) {
export const redirectTo = ref<string>()

export class Activity {
id: string
id!: string
_disposables: Disposable[] = []

constructor(public ctx: Context, public options: Activity.Options) {
options.order ??= 0
options.position ??= 'top'
Object.assign(this, omit(options, ['icon', 'name', 'desc', 'disabled']))
const { path, id = getActivityId(path), component } = options
this._disposables.push(ctx.$router.router.addRoute({ path, name: id, component, meta: { activity: this } }))
}

*setup() {
const { path, id = getActivityId(path), component } = this.options
yield this.ctx.$router.router.addRoute({ path, name: id, component, meta: { activity: this } })
this.id ??= id
this.handleUpdate()
this.authority ??= 0
ctx.$router.pages[this.id] = this
this.ctx.$router.pages[this.id] = this
yield () => delete this.ctx.$router.pages[this.id]
this.handleUpdate()
yield () => {
const { meta, fullPath } = this.ctx.$router.router.currentRoute.value
this._disposables.forEach(dispose => dispose())
if (meta?.activity === this) {
redirectTo.value = fullPath
this.ctx.$router.router.replace(this.ctx.$router.cache['home'] || '/')
}
}
}

handleUpdate() {
Expand Down Expand Up @@ -91,16 +103,6 @@ export class Activity {
if (this.ctx.bail('activity', this)) return true
if (this.options.disabled?.()) return true
}

dispose() {
const { meta, fullPath } = this.ctx.$router.router.currentRoute.value
this._disposables.forEach(dispose => dispose())
if (meta?.activity === this) {
redirectTo.value = fullPath
this.ctx.$router.router.replace(this.ctx.$router.cache['home'] || '/')
}
return delete this.ctx.$router.pages[this.id]
}
}

export default class RouterService extends Service {
Expand All @@ -114,20 +116,26 @@ export default class RouterService extends Service {
})

constructor(ctx: Context) {
super(ctx, '$router', true)
super(ctx, '$router')
ctx.mixin('$router', ['slot', 'page'])

const initialTitle = document.title
ctx.effect(() => this.router.afterEach((route) => {
const { name, fullPath } = this.router.currentRoute.value
this.cache[name!] = fullPath
if (route.meta.activity) {
document.title = `${route.meta.activity.name}`
if (initialTitle) document.title += ` | ${initialTitle}`
ctx.effect(() => {
const initialTitle = document.title
const dispose = this.router.afterEach((route) => {
const { name, fullPath } = this.router.currentRoute.value
this.cache[name!] = fullPath
if (route.meta.activity) {
document.title = `${route.meta.activity.name}`
if (initialTitle) document.title += ` | ${initialTitle}`
}
})
return () => {
document.title = initialTitle
dispose()
}
}))
})

this.router.beforeEach(async (to, from) => {
ctx.effect(() => this.router.beforeEach(async (to: RouteLocation, from) => {
if (to.matched.length) {
if (to.matched[0].path !== '/') {
redirectTo.value = undefined
Expand All @@ -145,7 +153,7 @@ export default class RouterService extends Service {
const result = this.cache['home'] || '/'
if (result === to.fullPath) return
return result
})
}))
}

slot(options: SlotOptions) {
Expand All @@ -164,7 +172,8 @@ export default class RouterService extends Service {
page(options: Activity.Options) {
options.component = this.ctx.wrapComponent(options.component)
return this.ctx.effect(() => {
return new Activity(this.ctx, options)
const activity = new Activity(this.ctx, options)
return activity.setup()
})
}
}
2 changes: 1 addition & 1 deletion packages/client/client/plugins/setting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export const useConfig = (useOriginal = false) => useOriginal ? original : resol

export default class SettingService extends Service {
constructor(ctx: Context) {
super(ctx, '$setting', true)
super(ctx, '$setting')
ctx.mixin('$setting', {
settings: 'settings',
extendSchema: 'schema',
Expand Down
2 changes: 1 addition & 1 deletion packages/client/client/plugins/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export const useColorMode = () => colorMode

export default class ThemeService extends Service {
constructor(ctx: Context) {
super(ctx, '$theme', true)
super(ctx, '$theme')
ctx.mixin('$theme', ['theme'])

ctx.internal.themes = reactive({})
Expand Down
4 changes: 2 additions & 2 deletions packages/client/client/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ import { markRaw } from 'vue'
import * as cordis from 'cordis'
import { Context } from './context'

export abstract class Service<T = unknown, C extends Context = Context> extends cordis.Service<T, C> {}
export abstract class Service<C extends Context = Context> extends cordis.Service<C> {}

export interface Ordered {
order?: number
}

export function insert<T extends Ordered>(list: T[], item: T) {
markRaw(item)
const index = list.findIndex(a => a.order < item.order)
const index = list.findIndex(a => a.order! < item.order!)
if (index >= 0) {
list.splice(index, 0, item)
} else {
Expand Down
4 changes: 2 additions & 2 deletions plugins/insight/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Context, EffectScope, ForkScope, Plugin, Schema, ScopeStatus } from 'cordis'
import { Context, EffectScope, Plugin, Schema, ScopeStatus } from 'cordis'
import { camelize, capitalize } from 'cosmokit'
import {} from '@cordisjs/plugin-webui'
import {} from 'cordis/loader'
Expand Down Expand Up @@ -35,7 +35,7 @@ function getName(plugin: Plugin) {
return format(plugin.name)
}

function getSourceId(child: ForkScope) {
function getSourceId(child: EffectScope) {
const { scope } = child.parent
if (scope.runtime.isForkable) {
return scope.uid
Expand Down
11 changes: 1 addition & 10 deletions plugins/manager/client/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,6 @@ export interface SubRoute {
}

export default class Manager extends Service {
static inject = {
optional: ['manager'],
}

changes = reactive<Dict<Partial<EntryData>>>({})

_dialogFork = ref<string>()
Expand Down Expand Up @@ -187,7 +183,7 @@ export default class Manager extends Service {
routes = reactive<SubRoute[]>([])

constructor(ctx: Context, public data: Ref<Data>) {
super(ctx, 'manager', true)
super(ctx, 'manager')

watch(data, (value) => {
const old = { ...this.changes }
Expand Down Expand Up @@ -551,11 +547,6 @@ export default class Manager extends Service {
setService(name, info)
}

// check reusability
if (local.runtime?.id && !local.runtime?.forkable) {
result.warning = true
}

// check schema
if (!local.runtime?.schema) {
result.warning = true
Expand Down
2 changes: 1 addition & 1 deletion plugins/manager/client/routes/main.vue
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
<!-- implements -->
<k-slot-item :order="400">
<template v-for="(activity, key) in ctx.$router.pages" :key="key">
<k-comment type="success" v-if="activity.ctx.$entry?.paths.includes(current.id) && !activity.disabled()">
<k-comment type="success" v-if="activity.ctx.$entry?.entryId === current.id && !activity.disabled()">
<p>
<span>此插件提供了页面:</span>
<k-activity-link :id="activity.id" />
Expand Down
26 changes: 12 additions & 14 deletions plugins/notifier/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Context, Schema, Service } from 'cordis'
import { Context, Service } from 'cordis'
import { Dict, isNullable, remove } from 'cosmokit'
import { h } from '@cordisjs/element'
import {} from 'cordis/loader'
Expand Down Expand Up @@ -27,13 +27,15 @@ export class Notifier {
type: 'primary',
content: [],
}
ctx.notifier.store.push(this)
this.update(options)
ctx.notifier.entry?.refresh()
this.dispose = ctx.collect('entry', () => {
this.clearActions()
remove(ctx.notifier.store, this)
this.dispose = ctx.effect(() => {
ctx.notifier.store.push(this)
this.update(options)
ctx.notifier.entry?.refresh()
return () => {
this.clearActions()
remove(ctx.notifier.store, this)
ctx.notifier.entry?.refresh()
}
})
}

Expand Down Expand Up @@ -71,7 +73,7 @@ export class Notifier {
return {
...this.options,
content: this.options.content.join(''),
paths: this.ctx.get('loader')?.locate(),
entryId: this.ctx.get('loader')?.locate(),
}
}
}
Expand All @@ -90,19 +92,17 @@ export namespace Notifier {

export interface Data extends Required<Options> {
content: string
paths?: string[]
entryId?: string
}
}

class NotifierService extends Service {
static inject = { optional: ['notifier'] }

public store: Notifier[] = []
public actions: Dict<() => void> = Object.create(null)
public entry?: Entry<NotifierService.Data>

constructor(ctx: Context, public config: NotifierService.Config) {
super(ctx, 'notifier', true)
super(ctx, 'notifier')

ctx.inject(['webui'], (ctx) => {
ctx.on('dispose', () => this.entry = undefined)
Expand Down Expand Up @@ -143,8 +143,6 @@ namespace NotifierService {
}

export interface Config {}

export const Config: Schema<Config> = Schema.object({})
}

export default NotifierService
Loading

0 comments on commit 63fdff3

Please sign in to comment.