feat: properly deal with duplicated api registration

This commit is contained in:
impart我的impart呢 2024-03-09 01:46:40 +08:00
parent 25a78dbc7d
commit 49d12becef
No known key found for this signature in database
GPG Key ID: 68ED75B1D060D166

View File

@ -1,4 +1,5 @@
import type { Methods } from '../types' import type { Methods } from '../types'
import { bgMagenta, cyan, white } from '../utils/colors'
import { l } from './logger' import { l } from './logger'
const notimplSym = Symbol('chronocat.internal.notimpl') const notimplSym = Symbol('chronocat.internal.notimpl')
@ -9,6 +10,7 @@ export type ApiImpl<M extends keyof Methods> = ((
[notimplSym]: boolean [notimplSym]: boolean
engine: string engine: string
priority: number
} }
export type Api = { export type Api = {
@ -18,6 +20,7 @@ export type Api = {
register: ( register: (
engine: string, engine: string,
priority?: number,
) => <M extends keyof Methods>( ) => <M extends keyof Methods>(
method: M, method: M,
impl: (...args: Methods[M][0]) => Promise<Methods[M][1]>, impl: (...args: Methods[M][0]) => Promise<Methods[M][1]>,
@ -31,11 +34,11 @@ const buildNotimpl = (name: string) => {
throw: true, throw: true,
}) })
;( ; (
fn as unknown as { fn as unknown as {
[notimplSym]: boolean [notimplSym]: boolean
} }
)[notimplSym] = true )[notimplSym] = true
return fn return fn
} }
@ -43,7 +46,7 @@ const buildNotimpl = (name: string) => {
const handler: ProxyHandler<Api> = { const handler: ProxyHandler<Api> = {
get: (target, name) => get: (target, name) =>
typeof name === 'symbol' || typeof name === 'symbol' ||
Object.prototype.hasOwnProperty.call(target, name) Object.prototype.hasOwnProperty.call(target, name)
? target[name as keyof Methods] ? target[name as keyof Methods]
: buildNotimpl(name), : buildNotimpl(name),
} }
@ -51,12 +54,21 @@ const handler: ProxyHandler<Api> = {
export const api = new Proxy({} as Api, handler) export const api = new Proxy({} as Api, handler)
api.register = api.register =
(engine: string) => (engine: string, defaultPriority: number = 0) =>
<M extends keyof Methods>( <M extends keyof Methods>(
method: M, method: M,
impl: (...args: Methods[M][0]) => Promise<Methods[M][1]>, impl: (...args: Methods[M][0]) => Promise<Methods[M][1]>,
) => { priority: number = -1,
// FIXME: Do not use type assertion ) => {
api[method] = impl /* ApiImpl<M> */ as Api[M] const newPriority = priority === -1 ? defaultPriority : priority
api[method].engine = engine if (api[method]) {
} l.warn(`${cyan(engine)}(${newPriority}) 与 ${cyan(api[method].engine)}(${api[method].priority
}) ${bgMagenta(white(method))} ${newPriority > api[method].priority ? engine : api[method].engine} `)
if (newPriority < api[method].priority) return
}
// FIXME: Do not use type assertion
api[method] = impl /* ApiImpl<M> */ as Api[M]
api[method].engine = engine
api[method].priority = newPriority
}