Skip to content

Commit

Permalink
feat(utils): support segment.transformAsync()
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Apr 21, 2021
1 parent 5425e52 commit 861c322
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 9 deletions.
9 changes: 2 additions & 7 deletions packages/koishi-core/src/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -449,13 +449,8 @@ export class Context {

async transformAssets(content: string, assets = this.assets) {
if (!assets) return content
const urlMap: Record<string, string> = {}
await Promise.all(segment.parse(content).map(async ({ type, data }) => {
if (!assets.types.includes(type as Assets.Type)) return
urlMap[data.url] = await assets.upload(data.url, data.file)
}))
return segment.transform(content, Object.fromEntries(assets.types.map((type) => {
return [type, (data) => segment(type, { url: urlMap[data.url] })]
return segment.transformAsync(content, Object.fromEntries(assets.types.map((type) => {
return [type, (data) => assets.upload(data.url, data.file)]
})))
}

Expand Down
16 changes: 14 additions & 2 deletions packages/koishi-utils/src/segment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export namespace segment {
export type Chain = segment.Parsed[]
export type Data = Record<string, primitive>
export type Transformer = string | ((data: Record<string, string>, index: number, chain: Chain) => string)
export type AsyncTransformer = string | ((data: Record<string, string>, index: number, chain: Chain) => string | Promise<string>)

export interface Parsed extends segment {
data: Record<string, string>
Expand All @@ -44,8 +45,8 @@ export namespace segment {
.replace(/&amp;/g, '&')
}

export function join(codes: segment[]) {
return codes.map(code => segment(code.type, code.data)).join('')
export function join(chain: segment[]) {
return chain.map(node => segment(node.type, node.data)).join('')
}

export interface FindOptions {
Expand Down Expand Up @@ -91,6 +92,17 @@ export namespace segment {
}).join('')
}

export async function transformAsync(source: string, rules: Record<string, AsyncTransformer>) {
const chain = segment.parse(source)
const cache = new Map<Parsed, string>()
await Promise.all(chain.map(async (node, index, chain) => {
const transformer = rules[node.type]
if (!transformer) return
cache.set(node, typeof transformer === 'string' ? transformer : await transformer(node.data, index, chain))
}))
return chain.map(node => cache.get(node) || segment(node.type, node.data)).join('')
}

export type Factory<T> = (value: T, data?: segment.Data) => string

function createFactory(type: string, key: string): Factory<primitive> {
Expand Down

0 comments on commit 861c322

Please sign in to comment.