@milkdown/utils
Advanced tools
Comparing version 4.14.2 to 5.0.0
import { MilkdownPlugin } from '@milkdown/core'; | ||
import { Origin, PluginWithMetadata, UnknownRecord } from '../types'; | ||
declare type Atom = PluginWithMetadata<string, UnknownRecord>; | ||
declare type Plugin = Atom | MilkdownPlugin; | ||
import { AddMetadata, AnyFn, Metadata } from '../types'; | ||
declare type PluginWithMetadata = MilkdownPlugin & Metadata; | ||
declare type Plugin = MilkdownPlugin | PluginWithMetadata; | ||
declare type Factory<T extends AnyFn = AnyFn> = AddMetadata<T>; | ||
export declare class AtomList<T extends Plugin = Plugin> extends Array<T> { | ||
private findThenRun; | ||
configure<U extends Origin>(target: U, config: Parameters<U>[0]): this; | ||
replace<U extends Origin, Next extends Plugin>(target: U, next: Next): this; | ||
remove<U extends Origin>(target: U): this; | ||
configure<U extends Factory>(target: U, config: Parameters<U>[0]): this; | ||
replace<U extends Factory, Next extends Plugin>(target: U, next: Next): this; | ||
remove<U extends Factory>(target: U): this; | ||
headless(): this; | ||
@@ -11,0 +12,0 @@ static create<T extends Plugin = Plugin>(from: T[]): AtomList<T>; |
@@ -1,5 +0,6 @@ | ||
const isAtom = (x) => Object.prototype.hasOwnProperty.call(x, 'origin'); | ||
/* Copyright 2021, Milkdown by Mirone. */ | ||
const hasMetadata = (x) => Object.prototype.hasOwnProperty.call(x, 'origin'); | ||
export class AtomList extends Array { | ||
findThenRun(target, callback) { | ||
const index = this.findIndex((x) => isAtom(x) && x.origin === target); | ||
const index = this.findIndex((x) => hasMetadata(x) && x.origin === target); | ||
if (index < 0) | ||
@@ -26,3 +27,3 @@ return this; | ||
headless() { | ||
this.filter(isAtom).forEach((x) => { | ||
this.filter(hasMetadata).forEach((x) => { | ||
this.configure(x.origin, { headless: true }); | ||
@@ -29,0 +30,0 @@ }); |
@@ -1,5 +0,8 @@ | ||
import { Attrs, Ctx } from '@milkdown/core'; | ||
import { CommonOptions, Utils } from '../types'; | ||
import { Attrs, CmdKey, Ctx } from '@milkdown/core'; | ||
import { AddMetadata, AnyFn, CommandConfig, CommonOptions, Methods, UnknownRecord, Utils } from '../types'; | ||
export declare const getClassName: (className: CommonOptions['className']) => (attrs: Attrs, ...defaultValue: (string | null | undefined)[]) => string; | ||
export declare const commonPlugin: <Ret, Op extends CommonOptions<string, import("../types").UnknownRecord>>(factory: (options: Op | undefined, utils: Utils) => Ret, ctx: Ctx, options?: Op | undefined) => Ret; | ||
export declare const createShortcut: <T>(commandKey: CmdKey<T>, defaultKey: string, args?: T | undefined) => CommandConfig<unknown>; | ||
export declare const getUtils: <Options extends UnknownRecord>(ctx: Ctx, options?: Options | undefined) => Utils; | ||
export declare const applyMethods: <Keys extends string, Type, Options extends UnknownRecord>(ctx: Ctx, plugin: Methods<Keys, Type>, getType: () => Promise<Type>, options?: Partial<CommonOptions<Keys, Options>> | undefined) => Promise<void>; | ||
export declare const addMetadata: <T extends AnyFn>(x: T) => AddMetadata<T>; | ||
//# sourceMappingURL=common.d.ts.map |
@@ -0,4 +1,6 @@ | ||
import { __awaiter } from "tslib"; | ||
/* Copyright 2021, Milkdown by Mirone. */ | ||
import { themeToolCtx } from '@milkdown/core'; | ||
import { commandsCtx, InitReady, inputRulesCtx, prosePluginsCtx, remarkPluginsCtx, themeToolCtx, } from '@milkdown/core'; | ||
import { themeMustInstalled } from '@milkdown/exception'; | ||
import { keymap } from '@milkdown/prose'; | ||
export const getClassName = (className) => (attrs, ...defaultValue) => { | ||
@@ -9,11 +11,11 @@ var _a; | ||
}; | ||
export const commonPlugin = (factory, ctx, options) => { | ||
export const createShortcut = (commandKey, defaultKey, args) => [commandKey, defaultKey, args]; | ||
export const getUtils = (ctx, options) => { | ||
try { | ||
const themeTool = ctx.get(themeToolCtx); | ||
const utils = { | ||
ctx, | ||
return { | ||
getClassName: getClassName(options === null || options === void 0 ? void 0 : options.className), | ||
getStyle: (style) => ((options === null || options === void 0 ? void 0 : options.headless) ? '' : style(themeTool)), | ||
themeTool, | ||
}; | ||
return factory(options, utils); | ||
} | ||
@@ -24,2 +26,49 @@ catch (_a) { | ||
}; | ||
export const applyMethods = (ctx, plugin, getType, options) => __awaiter(void 0, void 0, void 0, function* () { | ||
yield ctx.wait(InitReady); | ||
if (plugin.remarkPlugins) { | ||
const remarkPlugins = plugin.remarkPlugins(ctx); | ||
ctx.update(remarkPluginsCtx, (ps) => [...ps, ...remarkPlugins]); | ||
} | ||
const type = yield getType(); | ||
if (plugin.commands) { | ||
const commands = plugin.commands(type, ctx); | ||
commands.forEach(([key, command]) => { | ||
ctx.get(commandsCtx).create(key, command); | ||
}); | ||
} | ||
if (plugin.inputRules) { | ||
const inputRules = plugin.inputRules(type, ctx); | ||
ctx.update(inputRulesCtx, (ir) => [...ir, ...inputRules]); | ||
} | ||
if (plugin.shortcuts) { | ||
const getKey = (key, defaultValue) => { | ||
var _a, _b; | ||
return (_b = (_a = options === null || options === void 0 ? void 0 : options.keymap) === null || _a === void 0 ? void 0 : _a[key]) !== null && _b !== void 0 ? _b : defaultValue; | ||
}; | ||
const tuples = Object.entries(plugin.shortcuts) | ||
.flatMap(([id, [commandKey, defaultKey, args]]) => { | ||
const runner = () => ctx.get(commandsCtx).call(commandKey, args); | ||
const key = getKey(id, defaultKey); | ||
if (Array.isArray(key)) { | ||
return key.map((k) => ({ key: k, runner })); | ||
} | ||
return { key, runner }; | ||
}) | ||
.map((x) => [x.key, x.runner]); | ||
ctx.update(prosePluginsCtx, (ps) => ps.concat(keymap(Object.fromEntries(tuples)))); | ||
} | ||
if (plugin.prosePlugins) { | ||
const prosePlugins = plugin.prosePlugins(type, ctx); | ||
ctx.update(prosePluginsCtx, (ps) => [...ps, ...prosePlugins]); | ||
} | ||
}); | ||
export const addMetadata = (x) => { | ||
const fn = (...args) => { | ||
const result = x(...args); | ||
result.origin = fn; | ||
return result; | ||
}; | ||
return fn; | ||
}; | ||
//# sourceMappingURL=common.js.map |
@@ -1,4 +0,11 @@ | ||
import { Mark } from '@milkdown/core'; | ||
import { Factory, Origin, UnknownRecord } from '../types'; | ||
export declare const createMark: <SupportedKeys extends string = string, T extends UnknownRecord = UnknownRecord>(factory: Factory<SupportedKeys, T, Mark>) => Origin<SupportedKeys, T, Mark>; | ||
import { Ctx, MarkSchema, MilkdownPlugin } from '@milkdown/core'; | ||
import { MarkType, MarkViewFactory } from '@milkdown/prose'; | ||
import { CommonOptions, Methods, UnknownRecord, Utils } from '../types'; | ||
declare type MarkFactory<SupportedKeys extends string = string, Options extends UnknownRecord = UnknownRecord> = (utils: Utils, options?: Partial<CommonOptions<SupportedKeys, Options>>) => { | ||
id: string; | ||
schema: (ctx: Ctx) => MarkSchema; | ||
view?: (ctx: Ctx) => MarkViewFactory; | ||
} & Methods<SupportedKeys, MarkType>; | ||
export declare const createMark: <SupportedKeys extends string = string, Options extends UnknownRecord = UnknownRecord>(factory: MarkFactory<SupportedKeys, Options>) => import("../types").AddMetadata<(options?: Partial<Options> | undefined) => MilkdownPlugin>; | ||
export {}; | ||
//# sourceMappingURL=create-mark.d.ts.map |
/* Copyright 2021, Milkdown by Mirone. */ | ||
import { markFactory } from '@milkdown/core'; | ||
import { commonPlugin } from './common'; | ||
import { createKeymap } from './keymap'; | ||
export const createMark = (factory) => { | ||
const origin = (options) => { | ||
const plugin = markFactory((ctx) => { | ||
var _a; | ||
const mark = commonPlugin(factory, ctx, options); | ||
const view = (_a = options === null || options === void 0 ? void 0 : options.view) !== null && _a !== void 0 ? _a : mark.view; | ||
const keymap = createKeymap(mark.shortcuts, options === null || options === void 0 ? void 0 : options.keymap); | ||
plugin.id = mark.id; | ||
return Object.assign(Object.assign({}, mark), { view, | ||
keymap }); | ||
}); | ||
plugin.origin = origin; | ||
return plugin; | ||
}; | ||
return origin; | ||
}; | ||
import { __awaiter } from "tslib"; | ||
import { marksCtx, schemaCtx, SchemaReady, viewCtx } from '@milkdown/core'; | ||
import { addMetadata, applyMethods, getUtils } from '.'; | ||
export const createMark = (factory) => addMetadata((options) => () => (ctx) => __awaiter(void 0, void 0, void 0, function* () { | ||
const utils = getUtils(ctx, options); | ||
const plugin = factory(utils, options); | ||
yield applyMethods(ctx, plugin, () => __awaiter(void 0, void 0, void 0, function* () { | ||
const node = plugin.schema(ctx); | ||
ctx.update(marksCtx, (ns) => [...ns, [plugin.id, node]]); | ||
yield ctx.wait(SchemaReady); | ||
const schema = ctx.get(schemaCtx); | ||
return schema.marks[plugin.id]; | ||
}), options); | ||
if (plugin.view) { | ||
const view = plugin.view(ctx); | ||
ctx.update(viewCtx, (v) => [...v, [plugin.id, view]]); | ||
} | ||
})); | ||
//# sourceMappingURL=create-mark.js.map |
@@ -1,4 +0,11 @@ | ||
import { Node } from '@milkdown/core'; | ||
import { Factory, Origin, UnknownRecord } from '../types'; | ||
export declare const createNode: <SupportedKeys extends string = string, T extends UnknownRecord = UnknownRecord>(factory: Factory<SupportedKeys, T, Node>) => Origin<SupportedKeys, T, Node>; | ||
import { Ctx, MilkdownPlugin, NodeSchema } from '@milkdown/core'; | ||
import { NodeType, NodeViewFactory } from '@milkdown/prose'; | ||
import { CommonOptions, Methods, UnknownRecord, Utils } from '../types'; | ||
declare type NodeFactory<SupportedKeys extends string = string, Options extends UnknownRecord = UnknownRecord> = (utils: Utils, options?: Partial<CommonOptions<SupportedKeys, Options>>) => { | ||
id: string; | ||
schema: (ctx: Ctx) => NodeSchema; | ||
view?: (ctx: Ctx) => NodeViewFactory; | ||
} & Methods<SupportedKeys, NodeType>; | ||
export declare const createNode: <SupportedKeys extends string = string, Options extends UnknownRecord = UnknownRecord>(factory: NodeFactory<SupportedKeys, Options>) => import("../types").AddMetadata<(options?: Partial<CommonOptions<SupportedKeys, Options>> | undefined) => MilkdownPlugin>; | ||
export {}; | ||
//# sourceMappingURL=create-node.d.ts.map |
/* Copyright 2021, Milkdown by Mirone. */ | ||
import { nodeFactory } from '@milkdown/core'; | ||
import { commonPlugin } from './common'; | ||
import { createKeymap } from './keymap'; | ||
export const createNode = (factory) => { | ||
const origin = (options) => { | ||
const plugin = nodeFactory((ctx) => { | ||
var _a; | ||
const node = commonPlugin(factory, ctx, options); | ||
const view = (_a = options === null || options === void 0 ? void 0 : options.view) !== null && _a !== void 0 ? _a : node.view; | ||
const keymap = createKeymap(node.shortcuts, options === null || options === void 0 ? void 0 : options.keymap); | ||
plugin.id = node.id; | ||
return Object.assign(Object.assign({}, node), { view, | ||
keymap }); | ||
}); | ||
plugin.origin = origin; | ||
return plugin; | ||
}; | ||
return origin; | ||
}; | ||
import { __awaiter } from "tslib"; | ||
import { nodesCtx, schemaCtx, SchemaReady, viewCtx } from '@milkdown/core'; | ||
import { addMetadata, applyMethods } from '.'; | ||
import { getUtils } from './common'; | ||
export const createNode = (factory) => addMetadata((options) => () => (ctx) => __awaiter(void 0, void 0, void 0, function* () { | ||
const utils = getUtils(ctx, options); | ||
const plugin = factory(utils, options); | ||
yield applyMethods(ctx, plugin, () => __awaiter(void 0, void 0, void 0, function* () { | ||
const node = plugin.schema(ctx); | ||
ctx.update(nodesCtx, (ns) => [...ns, [plugin.id, node]]); | ||
yield ctx.wait(SchemaReady); | ||
const schema = ctx.get(schemaCtx); | ||
return schema.nodes[plugin.id]; | ||
}), options); | ||
if (plugin.view) { | ||
const view = plugin.view(ctx); | ||
ctx.update(viewCtx, (v) => [...v, [plugin.id, view]]); | ||
} | ||
})); | ||
//# sourceMappingURL=create-node.js.map |
@@ -0,6 +1,5 @@ | ||
export * from './common'; | ||
export * from './create-mark'; | ||
export * from './create-node'; | ||
export * from './create-prose-plugin'; | ||
export * from './create-shortcut'; | ||
export * from './keymap'; | ||
export * from './create-plugin'; | ||
//# sourceMappingURL=index.d.ts.map |
/* Copyright 2021, Milkdown by Mirone. */ | ||
export * from './common'; | ||
export * from './create-mark'; | ||
export * from './create-node'; | ||
export * from './create-prose-plugin'; | ||
export * from './create-shortcut'; | ||
export * from './keymap'; | ||
export * from './create-plugin'; | ||
//# sourceMappingURL=index.js.map |
export * from './atom'; | ||
export * from './factory'; | ||
export { CommonOptions, Utils } from './types'; | ||
export { CommonOptions, Methods, Utils } from './types'; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -1,15 +0,11 @@ | ||
import type { Attrs, CmdKey, Ctx, Mark, MilkdownPlugin, Node, ThemeTool } from '@milkdown/core'; | ||
import type { MarkViewFactory, NodeViewFactory } from '@milkdown/prose'; | ||
import type { Attrs, CmdKey, ThemeTool } from '@milkdown/core'; | ||
import { CmdTuple, Ctx, RemarkPlugin } from '@milkdown/core'; | ||
import { InputRule, Plugin } from '@milkdown/prose'; | ||
export declare type Utils = { | ||
readonly getClassName: (attrs: Attrs, ...defaultValue: (string | null | undefined)[]) => string; | ||
readonly getStyle: (style: (themeTool: ThemeTool) => string | void) => string | undefined; | ||
readonly themeTool: ThemeTool; | ||
}; | ||
export declare type UnknownRecord = Record<string, unknown>; | ||
export declare type CommandConfig<T = unknown> = { | ||
commandKey: CmdKey<T>; | ||
defaultKey: string; | ||
args?: T; | ||
}; | ||
export declare type Shortcuts<T extends string> = Record<T, CommandConfig>; | ||
export declare type UserKeymap<T extends string> = Partial<Record<T, string | string[]>>; | ||
export interface AtomOptional<SupportedKeys extends string> { | ||
readonly shortcuts?: Shortcuts<SupportedKeys>; | ||
readonly styles?: (attrs: Attrs) => string; | ||
} | ||
export declare type CommandConfig<T = unknown> = [commandKey: CmdKey<T>, defaultKey: string, args?: T]; | ||
export declare type CommonOptions<SupportedKeys extends string = string, Obj = UnknownRecord> = Obj & { | ||
@@ -20,21 +16,14 @@ className?: (attrs: Attrs) => string; | ||
}; | ||
declare type NodeOptions<SupportedKeys extends string, Obj> = CommonOptions<SupportedKeys, Obj> & { | ||
readonly view?: NodeViewFactory; | ||
export declare type Methods<Keys extends string, Type> = { | ||
remarkPlugins?: (ctx: Ctx) => RemarkPlugin[]; | ||
inputRules?: (types: Type, ctx: Ctx) => InputRule[]; | ||
prosePlugins?: (types: Type, ctx: Ctx) => Plugin[]; | ||
commands?: (types: Type, ctx: Ctx) => CmdTuple[]; | ||
shortcuts?: Record<Keys, CommandConfig>; | ||
}; | ||
declare type MarkOptions<SupportedKeys extends string, Obj> = CommonOptions<SupportedKeys, Obj> & { | ||
readonly view?: MarkViewFactory; | ||
export declare type AnyFn = (...args: any[]) => any; | ||
export declare type Metadata<T = unknown> = { | ||
origin: T; | ||
}; | ||
export declare type Options<SupportedKeys extends string, Obj extends UnknownRecord, Type> = Partial<Type extends Mark ? MarkOptions<SupportedKeys, Obj> : Type extends Node ? NodeOptions<SupportedKeys, Obj> : CommonOptions<SupportedKeys, Obj>>; | ||
export declare type Factory<SupportedKeys extends string, Obj extends UnknownRecord, Type = unknown> = (options: Options<SupportedKeys, Obj, Type> | undefined, utils: Utils) => Type & AtomOptional<SupportedKeys>; | ||
export declare type Utils = { | ||
readonly getClassName: (attrs: Attrs, ...defaultValue: (string | null | undefined)[]) => string; | ||
readonly getStyle: (style: (themeTool: ThemeTool) => string | void) => string | undefined; | ||
readonly ctx: Ctx; | ||
}; | ||
export declare type Origin<S extends string = string, Obj extends UnknownRecord = UnknownRecord, Type = unknown> = (options?: Options<S, Obj, Type>) => PluginWithMetadata<S, Obj, Type>; | ||
export declare type PluginWithMetadata<SupportedKeys extends string = string, Obj extends UnknownRecord = UnknownRecord, Type = unknown> = MilkdownPlugin & { | ||
origin: Origin<SupportedKeys, Obj, Type>; | ||
id: string; | ||
}; | ||
export {}; | ||
export declare type AddMetadata<T extends AnyFn = AnyFn> = (...args: Parameters<T>) => Metadata<T> & ReturnType<T>; | ||
//# sourceMappingURL=types.d.ts.map |
{ | ||
"name": "@milkdown/utils", | ||
"version": "4.14.2", | ||
"version": "5.0.0", | ||
"main": "lib/index.js", | ||
@@ -18,3 +18,3 @@ "module": "lib/index.js", | ||
"@milkdown/exception": " *", | ||
"tslib": "^2.2.0" | ||
"tslib": "^2.3.1" | ||
}, | ||
@@ -21,0 +21,0 @@ "scripts": { |
/* Copyright 2021, Milkdown by Mirone. */ | ||
import { MilkdownPlugin } from '@milkdown/core'; | ||
import { Origin, PluginWithMetadata, UnknownRecord } from '../types'; | ||
import { AddMetadata, AnyFn, Metadata } from '../types'; | ||
type Atom = PluginWithMetadata<string, UnknownRecord>; | ||
type Plugin = Atom | MilkdownPlugin; | ||
type PluginWithMetadata = MilkdownPlugin & Metadata; | ||
type Plugin = MilkdownPlugin | PluginWithMetadata; | ||
const isAtom = (x: Plugin): x is Atom => Object.prototype.hasOwnProperty.call(x, 'origin'); | ||
type Factory<T extends AnyFn = AnyFn> = AddMetadata<T>; | ||
const hasMetadata = (x: Plugin): x is PluginWithMetadata => Object.prototype.hasOwnProperty.call(x, 'origin'); | ||
export class AtomList<T extends Plugin = Plugin> extends Array<T> { | ||
private findThenRun<U extends Origin>(target: U, callback: (index: number) => void): this { | ||
const index = this.findIndex((x) => isAtom(x) && x.origin === target); | ||
private findThenRun<U extends Factory>(target: U, callback: (index: number) => void): this { | ||
const index = this.findIndex((x) => hasMetadata(x) && x.origin === target); | ||
if (index < 0) return this; | ||
@@ -21,3 +24,3 @@ | ||
configure<U extends Origin>(target: U, config: Parameters<U>[0]): this { | ||
configure<U extends Factory>(target: U, config: Parameters<U>[0]): this { | ||
return this.findThenRun(target, (index) => { | ||
@@ -28,3 +31,3 @@ this.splice(index, 1, target(config) as T); | ||
replace<U extends Origin, Next extends Plugin>(target: U, next: Next): this { | ||
replace<U extends Factory, Next extends Plugin>(target: U, next: Next): this { | ||
return this.findThenRun(target, (index) => { | ||
@@ -35,3 +38,3 @@ this.splice(index, 1, next as Plugin as T); | ||
remove<U extends Origin>(target: U): this { | ||
remove<U extends Factory>(target: U): this { | ||
return this.findThenRun(target, (index) => { | ||
@@ -43,4 +46,4 @@ this.splice(index, 1); | ||
headless(): this { | ||
this.filter(isAtom).forEach((x) => { | ||
this.configure((x as Atom).origin, { headless: true }); | ||
this.filter(hasMetadata).forEach((x) => { | ||
this.configure((x as PluginWithMetadata).origin as Factory, { headless: true }); | ||
}); | ||
@@ -47,0 +50,0 @@ return this; |
/* Copyright 2021, Milkdown by Mirone. */ | ||
import { Attrs, Ctx, themeToolCtx } from '@milkdown/core'; | ||
import { | ||
Attrs, | ||
CmdKey, | ||
commandsCtx, | ||
Ctx, | ||
InitReady, | ||
inputRulesCtx, | ||
prosePluginsCtx, | ||
remarkPluginsCtx, | ||
themeToolCtx, | ||
} from '@milkdown/core'; | ||
import { themeMustInstalled } from '@milkdown/exception'; | ||
import { keymap } from '@milkdown/prose'; | ||
import { CommonOptions, Utils } from '../types'; | ||
import { AddMetadata, AnyFn, CommandConfig, CommonOptions, Methods, UnknownRecord, Utils } from '../types'; | ||
export const getClassName = | ||
(className: CommonOptions['className']) => | ||
(attrs: Attrs, ...defaultValue: (string | null | undefined)[]) => { | ||
(attrs: Attrs, ...defaultValue: (string | null | undefined)[]): string => { | ||
const classList = className?.(attrs) ?? defaultValue; | ||
@@ -14,16 +25,14 @@ return Array.isArray(classList) ? classList.filter((x) => x).join(' ') : classList; | ||
export const commonPlugin = <Ret, Op extends CommonOptions>( | ||
factory: (options: Op | undefined, utils: Utils) => Ret, | ||
ctx: Ctx, | ||
options?: Op, | ||
): Ret => { | ||
export const createShortcut = <T>(commandKey: CmdKey<T>, defaultKey: string, args?: T) => | ||
[commandKey, defaultKey, args] as CommandConfig<unknown>; | ||
export const getUtils = <Options extends UnknownRecord>(ctx: Ctx, options?: Options): Utils => { | ||
try { | ||
const themeTool = ctx.get(themeToolCtx); | ||
const utils: Utils = { | ||
ctx, | ||
getClassName: getClassName(options?.className), | ||
return { | ||
getClassName: getClassName(options?.className as undefined), | ||
getStyle: (style) => (options?.headless ? '' : (style(themeTool) as string | undefined)), | ||
themeTool, | ||
}; | ||
return factory(options, utils); | ||
} catch { | ||
@@ -33,1 +42,61 @@ throw themeMustInstalled(); | ||
}; | ||
export const applyMethods = async <Keys extends string, Type, Options extends UnknownRecord>( | ||
ctx: Ctx, | ||
plugin: Methods<Keys, Type>, | ||
getType: () => Promise<Type>, | ||
options?: Partial<CommonOptions<Keys, Options>>, | ||
): Promise<void> => { | ||
await ctx.wait(InitReady); | ||
if (plugin.remarkPlugins) { | ||
const remarkPlugins = plugin.remarkPlugins(ctx); | ||
ctx.update(remarkPluginsCtx, (ps) => [...ps, ...remarkPlugins]); | ||
} | ||
const type = await getType(); | ||
if (plugin.commands) { | ||
const commands = plugin.commands(type, ctx); | ||
commands.forEach(([key, command]) => { | ||
ctx.get(commandsCtx).create(key, command); | ||
}); | ||
} | ||
if (plugin.inputRules) { | ||
const inputRules = plugin.inputRules(type, ctx); | ||
ctx.update(inputRulesCtx, (ir) => [...ir, ...inputRules]); | ||
} | ||
if (plugin.shortcuts) { | ||
const getKey = (key: Keys, defaultValue: string): string | string[] => { | ||
return options?.keymap?.[key] ?? defaultValue; | ||
}; | ||
const tuples = Object.entries<CommandConfig>(plugin.shortcuts) | ||
.flatMap(([id, [commandKey, defaultKey, args]]) => { | ||
const runner = () => ctx.get(commandsCtx).call(commandKey, args); | ||
const key = getKey(id as Keys, defaultKey); | ||
if (Array.isArray(key)) { | ||
return key.map((k) => ({ key: k, runner })); | ||
} | ||
return { key, runner }; | ||
}) | ||
.map((x) => [x.key, x.runner] as [string, () => boolean]); | ||
ctx.update(prosePluginsCtx, (ps) => ps.concat(keymap(Object.fromEntries(tuples)))); | ||
} | ||
if (plugin.prosePlugins) { | ||
const prosePlugins = plugin.prosePlugins(type, ctx); | ||
ctx.update(prosePluginsCtx, (ps) => [...ps, ...prosePlugins]); | ||
} | ||
}; | ||
export const addMetadata = <T extends AnyFn>(x: T) => { | ||
const fn: AddMetadata<T> = (...args) => { | ||
const result = x(...args); | ||
result.origin = fn; | ||
return result; | ||
}; | ||
return fn; | ||
}; |
/* Copyright 2021, Milkdown by Mirone. */ | ||
import { Mark, markFactory } from '@milkdown/core'; | ||
import { Factory, Origin, PluginWithMetadata, UnknownRecord } from '../types'; | ||
import { commonPlugin } from './common'; | ||
import { createKeymap } from './keymap'; | ||
import { Ctx, MarkSchema, marksCtx, MilkdownPlugin, schemaCtx, SchemaReady, viewCtx } from '@milkdown/core'; | ||
import { MarkType, MarkViewFactory, ViewFactory } from '@milkdown/prose'; | ||
export const createMark = <SupportedKeys extends string = string, T extends UnknownRecord = UnknownRecord>( | ||
factory: Factory<SupportedKeys, T, Mark>, | ||
): Origin<SupportedKeys, T, Mark> => { | ||
const origin: Origin<SupportedKeys, T, Mark> = (options) => { | ||
const plugin = markFactory((ctx) => { | ||
const mark = commonPlugin(factory, ctx, options); | ||
const view = options?.view ?? mark.view; | ||
const keymap = createKeymap(mark.shortcuts, options?.keymap); | ||
plugin.id = mark.id; | ||
import { CommonOptions, Methods, UnknownRecord, Utils } from '../types'; | ||
import { addMetadata, applyMethods, getUtils } from '.'; | ||
return { | ||
...mark, | ||
view, | ||
keymap, | ||
}; | ||
}) as PluginWithMetadata<SupportedKeys, T, Mark>; | ||
plugin.origin = origin; | ||
type MarkFactory<SupportedKeys extends string = string, Options extends UnknownRecord = UnknownRecord> = ( | ||
utils: Utils, | ||
options?: Partial<CommonOptions<SupportedKeys, Options>>, | ||
) => { | ||
id: string; | ||
schema: (ctx: Ctx) => MarkSchema; | ||
view?: (ctx: Ctx) => MarkViewFactory; | ||
} & Methods<SupportedKeys, MarkType>; | ||
return plugin; | ||
}; | ||
export const createMark = <SupportedKeys extends string = string, Options extends UnknownRecord = UnknownRecord>( | ||
factory: MarkFactory<SupportedKeys, Options>, | ||
) => | ||
addMetadata( | ||
(options?: Partial<Options>): MilkdownPlugin => | ||
() => | ||
async (ctx) => { | ||
const utils = getUtils(ctx, options); | ||
return origin; | ||
}; | ||
const plugin = factory(utils, options); | ||
await applyMethods( | ||
ctx, | ||
plugin, | ||
async () => { | ||
const node = plugin.schema(ctx); | ||
ctx.update(marksCtx, (ns) => [...ns, [plugin.id, node] as [string, MarkSchema]]); | ||
await ctx.wait(SchemaReady); | ||
const schema = ctx.get(schemaCtx); | ||
return schema.marks[plugin.id]; | ||
}, | ||
options, | ||
); | ||
if (plugin.view) { | ||
const view = plugin.view(ctx); | ||
ctx.update(viewCtx, (v) => [...v, [plugin.id, view] as [string, ViewFactory]]); | ||
} | ||
}, | ||
); |
/* Copyright 2021, Milkdown by Mirone. */ | ||
import { Node, nodeFactory } from '@milkdown/core'; | ||
import { Factory, Origin, PluginWithMetadata, UnknownRecord } from '../types'; | ||
import { commonPlugin } from './common'; | ||
import { createKeymap } from './keymap'; | ||
import { Ctx, MilkdownPlugin, NodeSchema, nodesCtx, schemaCtx, SchemaReady, viewCtx } from '@milkdown/core'; | ||
import { NodeType, NodeViewFactory, ViewFactory } from '@milkdown/prose'; | ||
export const createNode = <SupportedKeys extends string = string, T extends UnknownRecord = UnknownRecord>( | ||
factory: Factory<SupportedKeys, T, Node>, | ||
): Origin<SupportedKeys, T, Node> => { | ||
const origin: Origin<SupportedKeys, T, Node> = (options) => { | ||
const plugin = nodeFactory((ctx) => { | ||
const node = commonPlugin(factory, ctx, options); | ||
const view = options?.view ?? node.view; | ||
const keymap = createKeymap(node.shortcuts, options?.keymap); | ||
plugin.id = node.id; | ||
import { CommonOptions, Methods, UnknownRecord, Utils } from '../types'; | ||
import { addMetadata, applyMethods } from '.'; | ||
import { getUtils } from './common'; | ||
return { | ||
...node, | ||
view, | ||
keymap, | ||
}; | ||
}) as PluginWithMetadata<SupportedKeys, T, Node>; | ||
plugin.origin = origin; | ||
type NodeFactory<SupportedKeys extends string = string, Options extends UnknownRecord = UnknownRecord> = ( | ||
utils: Utils, | ||
options?: Partial<CommonOptions<SupportedKeys, Options>>, | ||
) => { | ||
id: string; | ||
schema: (ctx: Ctx) => NodeSchema; | ||
view?: (ctx: Ctx) => NodeViewFactory; | ||
} & Methods<SupportedKeys, NodeType>; | ||
return plugin; | ||
}; | ||
export const createNode = <SupportedKeys extends string = string, Options extends UnknownRecord = UnknownRecord>( | ||
factory: NodeFactory<SupportedKeys, Options>, | ||
) => | ||
addMetadata( | ||
(options?: Partial<CommonOptions<SupportedKeys, Options>>): MilkdownPlugin => | ||
() => | ||
async (ctx) => { | ||
const utils = getUtils(ctx, options); | ||
return origin; | ||
}; | ||
const plugin = factory(utils, options); | ||
await applyMethods( | ||
ctx, | ||
plugin, | ||
async () => { | ||
const node = plugin.schema(ctx); | ||
ctx.update(nodesCtx, (ns) => [...ns, [plugin.id, node] as [string, NodeSchema]]); | ||
await ctx.wait(SchemaReady); | ||
const schema = ctx.get(schemaCtx); | ||
return schema.nodes[plugin.id]; | ||
}, | ||
options, | ||
); | ||
if (plugin.view) { | ||
const view = plugin.view(ctx); | ||
ctx.update(viewCtx, (v) => [...v, [plugin.id, view] as [string, ViewFactory]]); | ||
} | ||
}, | ||
); |
/* Copyright 2021, Milkdown by Mirone. */ | ||
export * from './common'; | ||
export * from './create-mark'; | ||
export * from './create-node'; | ||
export * from './create-prose-plugin'; | ||
export * from './create-shortcut'; | ||
export * from './keymap'; | ||
export * from './create-plugin'; |
/* Copyright 2021, Milkdown by Mirone. */ | ||
export * from './atom'; | ||
export * from './factory'; | ||
export { CommonOptions, Utils } from './types'; | ||
export { CommonOptions, Methods, Utils } from './types'; |
/* Copyright 2021, Milkdown by Mirone. */ | ||
import type { Attrs, CmdKey, Ctx, Mark, MilkdownPlugin, Node, ThemeTool } from '@milkdown/core'; | ||
import type { MarkViewFactory, NodeViewFactory } from '@milkdown/prose'; | ||
import type { Attrs, CmdKey, ThemeTool } from '@milkdown/core'; | ||
import { CmdTuple, Ctx, RemarkPlugin } from '@milkdown/core'; | ||
import { InputRule, Plugin } from '@milkdown/prose'; | ||
export type UnknownRecord = Record<string, unknown>; | ||
export type CommandConfig<T = unknown> = { | ||
commandKey: CmdKey<T>; | ||
defaultKey: string; | ||
args?: T; | ||
export type Utils = { | ||
readonly getClassName: (attrs: Attrs, ...defaultValue: (string | null | undefined)[]) => string; | ||
readonly getStyle: (style: (themeTool: ThemeTool) => string | void) => string | undefined; | ||
readonly themeTool: ThemeTool; | ||
}; | ||
export type Shortcuts<T extends string> = Record<T, CommandConfig>; | ||
export type UserKeymap<T extends string> = Partial<Record<T, string | string[]>>; | ||
export type UnknownRecord = Record<string, unknown>; | ||
export interface AtomOptional<SupportedKeys extends string> { | ||
readonly shortcuts?: Shortcuts<SupportedKeys>; | ||
readonly styles?: (attrs: Attrs) => string; | ||
} | ||
export type CommandConfig<T = unknown> = [commandKey: CmdKey<T>, defaultKey: string, args?: T]; | ||
@@ -27,37 +22,15 @@ export type CommonOptions<SupportedKeys extends string = string, Obj = UnknownRecord> = Obj & { | ||
type NodeOptions<SupportedKeys extends string, Obj> = CommonOptions<SupportedKeys, Obj> & { | ||
readonly view?: NodeViewFactory; | ||
export type Methods<Keys extends string, Type> = { | ||
remarkPlugins?: (ctx: Ctx) => RemarkPlugin[]; | ||
inputRules?: (types: Type, ctx: Ctx) => InputRule[]; | ||
prosePlugins?: (types: Type, ctx: Ctx) => Plugin[]; | ||
commands?: (types: Type, ctx: Ctx) => CmdTuple[]; | ||
shortcuts?: Record<Keys, CommandConfig>; | ||
}; | ||
type MarkOptions<SupportedKeys extends string, Obj> = CommonOptions<SupportedKeys, Obj> & { | ||
readonly view?: MarkViewFactory; | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
export type AnyFn = (...args: any[]) => any; | ||
export type Metadata<T = unknown> = { | ||
origin: T; | ||
}; | ||
export type Options<SupportedKeys extends string, Obj extends UnknownRecord, Type> = Partial< | ||
Type extends Mark | ||
? MarkOptions<SupportedKeys, Obj> | ||
: Type extends Node | ||
? NodeOptions<SupportedKeys, Obj> | ||
: CommonOptions<SupportedKeys, Obj> | ||
>; | ||
export type Factory<SupportedKeys extends string, Obj extends UnknownRecord, Type = unknown> = ( | ||
options: Options<SupportedKeys, Obj, Type> | undefined, | ||
utils: Utils, | ||
) => Type & AtomOptional<SupportedKeys>; | ||
export type Utils = { | ||
readonly getClassName: (attrs: Attrs, ...defaultValue: (string | null | undefined)[]) => string; | ||
readonly getStyle: (style: (themeTool: ThemeTool) => string | void) => string | undefined; | ||
readonly ctx: Ctx; | ||
}; | ||
export type Origin<S extends string = string, Obj extends UnknownRecord = UnknownRecord, Type = unknown> = ( | ||
options?: Options<S, Obj, Type>, | ||
) => PluginWithMetadata<S, Obj, Type>; | ||
export type PluginWithMetadata< | ||
SupportedKeys extends string = string, | ||
Obj extends UnknownRecord = UnknownRecord, | ||
Type = unknown, | ||
> = MilkdownPlugin & { origin: Origin<SupportedKeys, Obj, Type>; id: string }; | ||
export type AddMetadata<T extends AnyFn = AnyFn> = (...args: Parameters<T>) => Metadata<T> & ReturnType<T>; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
47604
633
48
1
Updatedtslib@^2.3.1