@ruan-cat/utils 3.0.1 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,96 +1,3 @@
1
- import { OptionalKeysOf } from 'type-fest';
2
-
3
- /**
4
- * rmmv特征基类
5
- * @description
6
- * 全部的rmmv类都具有 `initialize` 函数
7
- *
8
- * 此类型用于描述此
9
- */
10
- declare abstract class RmmvClass {
11
- initialize: (...args: any[]) => void;
12
- }
13
- /**
14
- * 获取对象的全部函数key名称
15
- * @description
16
- * 从一个类型内,获取值为函数的key名称
17
- */
18
- type FunctionKeys<T> = {
19
- [K in keyof T]: T[K] extends (...args: any[]) => any ? K : never;
20
- }[keyof T];
21
- /**
22
- * 属性提示工具
23
- * @description
24
- * 对继承的类进行属性提示
25
- *
26
- * 对自己新增的属性和函数做属性提示
27
- *
28
- * 对全部涉及到的函数,其this全部做判定
29
- */
30
- type AttributePromptTool<SourceCode extends RmmvClass, UserCode> = ThisType<SourceCode & UserCode> & Partial<SourceCode> & UserCode;
31
- /**
32
- * 默认处理策略
33
- * @description
34
- * 先回调rmmv源码 再加上用户代码
35
- */
36
- declare const defaultHandleStrategy: "source-first";
37
- /**
38
- * 处理策略
39
- * @description
40
- * 用户代码相对于rmmv源码的处理策略
41
- */
42
- declare const handleStrategy: readonly ["userCode-cover-source", "source-first", "userCode-first"];
43
- /**
44
- * 处理策略
45
- * @description
46
- * 用户代码相对于rmmv源码的处理策略
47
- */
48
- type HandleStrategy = (typeof handleStrategy)[number];
49
- /**
50
- * 被默认执行默认处理策略的函数名
51
- * @description
52
- * 初始化函数默认使用固定的处理策略。
53
- */
54
- type defaultHandleStrategy_FuncationName = FunctionKeys<RmmvClass>;
55
- /** 全部可选字段组成的对象 且该对象的全部字段必填 */
56
- type AllOptionalFieldObj<T extends object> = Required<Pick<T, OptionalKeysOf<T>>>;
57
- /** 给一个对象排除 init 字段 */
58
- type NoInit<T> = Omit<T, defaultHandleStrategy_FuncationName>;
59
- type AllOptionalFieldObj_noInit<T extends object> = NoInit<AllOptionalFieldObj<T>>;
60
- /** 处理策略配置的 全部有意义的配置键名 */
61
- type HandleStrategyConfigKeys<T extends object> = FunctionKeys<AllOptionalFieldObj_noInit<T>>;
62
- /**
63
- * 全部有意义函数的 处理策略配置
64
- * @description
65
- * 只有可能去覆盖,拓展的函数名,才值得去配置
66
- */
67
- type HandleStrategyConfig<T extends object> = Record<HandleStrategyConfigKeys<T>, HandleStrategy>;
68
- /** rmmv类拓展工具函数配置 */
69
- type RmmvClassExpandTools<SourceCode extends new (...args: any[]) => RmmvClass, UserCode extends object> = {
70
- /** 源码 一般是被拓展的类,往往是rmmv的源码类 */
71
- source: SourceCode;
72
- /** 用户代码 插件开发者编写的一个内部完备的对象 */
73
- userCode: UserCode;
74
- /**
75
- * 拓展配置 按照要求拓展
76
- * @description
77
- * 用户可以不提供配置 就默认按照标准的方式处理
78
- */
79
- config?: Partial<HandleStrategyConfig<UserCode>>;
80
- };
81
- /**
82
- * rmmv类拓展工具函数
83
- * @description
84
- * 预期处理5种情况
85
- *
86
- * - 1. 用户代码覆盖掉rmmv源码
87
- * - 2. 默认处理策略
88
- * - 3. 先执行用户代码 再回调rmmv源码
89
- * - 4. 初始化函数默认使用固定的处理策略
90
- * - 5. 继承对象没有这个属性时 说明是新的函数 直接添加到原型链上
91
- */
92
- declare function rmmvClassExpandTools<SourceCode extends new (...args: any[]) => RmmvClass, UserCode extends object = any>(params: RmmvClassExpandTools<SourceCode, UserCode>): void;
93
-
94
1
  type Condition = (...args: unknown[]) => boolean;
95
2
  /** @deprecated 没必要 */
96
3
  type Conditions = Condition[];
@@ -200,4 +107,4 @@ type Prettify<T> = {
200
107
  */
201
108
  type ToNumberLike<T extends number> = T | `${T}`;
202
109
 
203
- export { type AttributePromptTool, type BaseTask, type Condition, type Conditions, type FunctionKeys, type HandleStrategy, type ParallelTasks, type PnpmWorkspace, type Prettify, type PromiseTasksConfig, type QueueTasks, RmmvClass, type SimpleAsyncTask, type SingleTasks, type Task, type TaskType, type TasksConfig, type ToNumberLike, defaultHandleStrategy, type defaultHandleStrategy_FuncationName, definePromiseTasks, executePromiseTasks, generateSimpleAsyncTask, initFlag, isConditionsEvery, isConditionsSome, rmmvClassExpandTools, runPromiseByConcurrency, runPromiseByQueue, taskTypes };
110
+ export { type BaseTask, type Condition, type Conditions, type ParallelTasks, type PnpmWorkspace, type Prettify, type PromiseTasksConfig, type QueueTasks, type SimpleAsyncTask, type SingleTasks, type Task, type TaskType, type TasksConfig, type ToNumberLike, definePromiseTasks, executePromiseTasks, generateSimpleAsyncTask, initFlag, isConditionsEvery, isConditionsSome, runPromiseByConcurrency, runPromiseByQueue, taskTypes };
package/dist/index.js CHANGED
@@ -1,67 +1,3 @@
1
- // src/rmmv-class-expand-tools.ts
2
- import { forIn, hasIn, isFunction, uniqueId } from "lodash-es";
3
- var defaultHandleStrategy = "source-first";
4
- function isSourceFirst(handleStrategy) {
5
- return handleStrategy === "source-first";
6
- }
7
- function isUserCodeCoverSource(handleStrategy) {
8
- return handleStrategy === "userCode-cover-source";
9
- }
10
- function isUserCodeFirst(handleStrategy) {
11
- return handleStrategy === "userCode-first";
12
- }
13
- var functionAlias = /* @__PURE__ */ new Map();
14
- function generateFunctionAliasId(key) {
15
- return uniqueId(`FunctionAliasId_${key}_`);
16
- }
17
- function rmmvClassExpandTools(params) {
18
- const { source, userCode, config } = params;
19
- const handleStrategyConfig = config;
20
- function getHandleStrategy(key) {
21
- return handleStrategyConfig?.[key] ?? defaultHandleStrategy;
22
- }
23
- const sourcePrototype = source.prototype;
24
- function isInSourcePrototype(key) {
25
- return hasIn(sourcePrototype, key);
26
- }
27
- function isInitialize(key) {
28
- return key === "initialize";
29
- }
30
- forIn(userCode, function(value, key, object) {
31
- console.log(` value, key, object `, value, key);
32
- if (isInSourcePrototype(key)) {
33
- if (isFunction(object[key])) {
34
- const handleStrategy = getHandleStrategy(key);
35
- if (isUserCodeCoverSource(handleStrategy)) {
36
- sourcePrototype[key] = value;
37
- }
38
- if (isInitialize(key) || isSourceFirst(handleStrategy)) {
39
- const functionAliasId = generateFunctionAliasId(key);
40
- functionAlias.set(functionAliasId, sourcePrototype[key]);
41
- sourcePrototype[key] = function() {
42
- console.log(` \u8FDB\u5165\u5230\u4E8C\u6B21\u5C01\u88C5\u7684\u51FD\u6570 \u51FD\u6570id = `, functionAliasId);
43
- functionAlias.get(functionAliasId).apply(this, arguments);
44
- value.apply(this, arguments);
45
- };
46
- }
47
- if (isUserCodeFirst(handleStrategy)) {
48
- const functionAliasId = generateFunctionAliasId(key);
49
- functionAlias.set(functionAliasId, sourcePrototype[key]);
50
- sourcePrototype[key] = function() {
51
- console.log(` \u8FDB\u5165\u5230\u4E8C\u6B21\u5C01\u88C5\u7684\u51FD\u6570 \u51FD\u6570id = `, functionAliasId);
52
- value.apply(this, arguments);
53
- functionAlias.get(functionAliasId).apply(this, arguments);
54
- };
55
- }
56
- }
57
- } else {
58
- if (isFunction(object[key])) {
59
- sourcePrototype[key] = value;
60
- }
61
- }
62
- });
63
- }
64
-
65
1
  // src/conditions.ts
66
2
  function isConditionsEvery(conditions) {
67
3
  return conditions.every((condition) => condition());
@@ -138,14 +74,12 @@ async function runPromiseByConcurrency(promises) {
138
74
  await Promise.all(promises.map((promise) => promise()));
139
75
  }
140
76
  export {
141
- defaultHandleStrategy,
142
77
  definePromiseTasks,
143
78
  executePromiseTasks,
144
79
  generateSimpleAsyncTask,
145
80
  initFlag,
146
81
  isConditionsEvery,
147
82
  isConditionsSome,
148
- rmmvClassExpandTools,
149
83
  runPromiseByConcurrency,
150
84
  runPromiseByQueue,
151
85
  taskTypes
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/rmmv-class-expand-tools.ts","../src/conditions.ts","../src/define-promise-tasks.ts","../src/simple-promise-tools.ts"],"sourcesContent":["import type { OptionalKeysOf } from \"type-fest\";\nimport { forIn, hasIn, isFunction, uniqueId } from \"lodash-es\";\n\n/**\n * rmmv特征基类\n * @description\n * 全部的rmmv类都具有 `initialize` 函数\n *\n * 此类型用于描述此\n */\nexport declare abstract class RmmvClass {\n\tinitialize: (...args: any[]) => void;\n}\n\n/**\n * 获取对象的全部函数key名称\n * @description\n * 从一个类型内,获取值为函数的key名称\n */\nexport type FunctionKeys<T> = {\n\t[K in keyof T]: T[K] extends (...args: any[]) => any ? K : never;\n}[keyof T];\n\n/**\n * 属性提示工具\n * @description\n * 对继承的类进行属性提示\n *\n * 对自己新增的属性和函数做属性提示\n *\n * 对全部涉及到的函数,其this全部做判定\n */\nexport type AttributePromptTool<SourceCode extends RmmvClass, UserCode> = ThisType<SourceCode & UserCode> &\n\tPartial<SourceCode> &\n\tUserCode;\n\ntype UserCodeClassAttributeType = {\n\tcounter: number;\n\tdrillCalendar: string[];\n\tsayFuck: () => void;\n\tisUserCodeClass(): true;\n\tgetDrillCalendar(): string[];\n};\n\n/**\n * 默认处理策略\n * @description\n * 先回调rmmv源码 再加上用户代码\n */\nexport const defaultHandleStrategy = <const>\"source-first\";\n\n/**\n * 处理策略\n * @description\n * 用户代码相对于rmmv源码的处理策略\n */\nconst handleStrategy = <const>[\n\t/** 用户代码覆盖掉rmmv源码 */\n\t\"userCode-cover-source\",\n\n\tdefaultHandleStrategy,\n\n\t/** 先执行用户代码 再回调rmmv源码 */\n\t\"userCode-first\",\n];\n\n/**\n * 处理策略\n * @description\n * 用户代码相对于rmmv源码的处理策略\n */\nexport type HandleStrategy = (typeof handleStrategy)[number];\n\nfunction isSourceFirst(handleStrategy: HandleStrategy): handleStrategy is \"source-first\" {\n\treturn handleStrategy === \"source-first\";\n}\n\nfunction isUserCodeCoverSource(handleStrategy: HandleStrategy): handleStrategy is \"userCode-cover-source\" {\n\treturn handleStrategy === \"userCode-cover-source\";\n}\n\nfunction isUserCodeFirst(handleStrategy: HandleStrategy): handleStrategy is \"userCode-first\" {\n\treturn handleStrategy === \"userCode-first\";\n}\n\n/**\n * 被默认执行默认处理策略的函数名\n * @description\n * 初始化函数默认使用固定的处理策略。\n */\nexport type defaultHandleStrategy_FuncationName = FunctionKeys<RmmvClass>;\n\n/** 全部可选字段组成的对象 且该对象的全部字段必填 */\ntype AllOptionalFieldObj<T extends object> = Required<Pick<T, OptionalKeysOf<T>>>;\n\n/** 给一个对象排除 init 字段 */\ntype NoInit<T> = Omit<T, defaultHandleStrategy_FuncationName>;\n\ntype AllOptionalFieldObj_noInit<T extends object> = NoInit<AllOptionalFieldObj<T>>;\n\n/** 处理策略配置的 全部有意义的配置键名 */\ntype HandleStrategyConfigKeys<T extends object> = FunctionKeys<AllOptionalFieldObj_noInit<T>>;\n\n/**\n * 全部有意义函数的 处理策略配置\n * @description\n * 只有可能去覆盖,拓展的函数名,才值得去配置\n */\ntype HandleStrategyConfig<T extends object> = Record<HandleStrategyConfigKeys<T>, HandleStrategy>;\n\n/** rmmv类拓展工具函数配置 */\ntype RmmvClassExpandTools<SourceCode extends new (...args: any[]) => RmmvClass, UserCode extends object> = {\n\t/** 源码 一般是被拓展的类,往往是rmmv的源码类 */\n\tsource: SourceCode;\n\n\t/** 用户代码 插件开发者编写的一个内部完备的对象 */\n\tuserCode: UserCode;\n\n\t/**\n\t * 拓展配置 按照要求拓展\n\t * @description\n\t * 用户可以不提供配置 就默认按照标准的方式处理\n\t */\n\tconfig?: Partial<HandleStrategyConfig<UserCode>>;\n};\n\n/** 函数别名存储对象 */\nconst functionAlias = new Map<string, Function>();\n\n/** 生成函数别名id */\nfunction generateFunctionAliasId(key: string) {\n\treturn uniqueId(`FunctionAliasId_${key}_`);\n}\n\n/**\n * rmmv类拓展工具函数\n * @description\n * 预期处理5种情况\n *\n * - 1. 用户代码覆盖掉rmmv源码\n * - 2. 默认处理策略\n * - 3. 先执行用户代码 再回调rmmv源码\n * - 4. 初始化函数默认使用固定的处理策略\n * - 5. 继承对象没有这个属性时 说明是新的函数 直接添加到原型链上\n */\nexport function rmmvClassExpandTools<\n\tSourceCode extends new (...args: any[]) => RmmvClass,\n\tUserCode extends object = any,\n>(params: RmmvClassExpandTools<SourceCode, UserCode>) {\n\tconst { source, userCode, config } = params;\n\tconst handleStrategyConfig = config;\n\n\tfunction getHandleStrategy(key: HandleStrategyConfigKeys<UserCode>): HandleStrategy {\n\t\treturn handleStrategyConfig?.[key] ?? defaultHandleStrategy;\n\t}\n\n\t/** 源对象的原型链 */\n\tconst sourcePrototype = source.prototype;\n\n\t/** 属性是否在源对象的原型链内? */\n\tfunction isInSourcePrototype(key: string) {\n\t\treturn hasIn(sourcePrototype, key);\n\t}\n\n\t/** 是不是初始化函数的名称? */\n\tfunction isInitialize(key: string): key is defaultHandleStrategy_FuncationName {\n\t\treturn key === \"initialize\";\n\t}\n\n\tforIn(userCode, function (value, key, object: Record<string, any>) {\n\t\tconsole.log(` value, key, object `, value, key);\n\n\t\t// 继承对象有没有这个属性?\n\t\tif (isInSourcePrototype(key)) {\n\t\t\tif (isFunction(object[key])) {\n\t\t\t\tconst handleStrategy = getHandleStrategy(key as HandleStrategyConfigKeys<UserCode>);\n\n\t\t\t\t// 1 用户代码覆盖掉rmmv源码\n\t\t\t\tif (isUserCodeCoverSource(handleStrategy)) {\n\t\t\t\t\tsourcePrototype[key] = value;\n\t\t\t\t}\n\n\t\t\t\t// 2 初始化函数默认使用固定的处理策略\n\t\t\t\t// 3 默认处理策略\n\t\t\t\tif (isInitialize(key) || isSourceFirst(handleStrategy)) {\n\t\t\t\t\tconst functionAliasId = generateFunctionAliasId(key);\n\t\t\t\t\tfunctionAlias.set(functionAliasId, sourcePrototype[key]);\n\n\t\t\t\t\tsourcePrototype[key] = function () {\n\t\t\t\t\t\tconsole.log(` 进入到二次封装的函数 函数id = `, functionAliasId);\n\t\t\t\t\t\t// 先回调rmmv源码\n\t\t\t\t\t\tfunctionAlias.get(functionAliasId)!.apply(this, arguments);\n\t\t\t\t\t\tvalue.apply(this, arguments);\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\t// 4 先执行用户代码 再回调rmmv源码\n\t\t\t\tif (isUserCodeFirst(handleStrategy)) {\n\t\t\t\t\tconst functionAliasId = generateFunctionAliasId(key);\n\t\t\t\t\tfunctionAlias.set(functionAliasId, sourcePrototype[key]);\n\n\t\t\t\t\tsourcePrototype[key] = function () {\n\t\t\t\t\t\tconsole.log(` 进入到二次封装的函数 函数id = `, functionAliasId);\n\t\t\t\t\t\t// 先执行用户代码\n\t\t\t\t\t\tvalue.apply(this, arguments);\n\t\t\t\t\t\tfunctionAlias.get(functionAliasId)!.apply(this, arguments);\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tif (isFunction(object[key])) {\n\t\t\t\t/**\n\t\t\t\t * 5 继承对象没有这个属性时 说明是新的函数\n\t\t\t\t * 直接添加到原型链上\n\t\t\t\t */\n\t\t\t\tsourcePrototype[key] = value;\n\t\t\t}\n\t\t}\n\t});\n}\n","export type Condition = (...args: unknown[]) => boolean;\n\n/** @deprecated 没必要 */\nexport type Conditions = Condition[];\n\n/**\n * 是否每一个条件函数都满足?\n * @description\n * ### 设计理由\n * 旨在于封装这样的代码段\n * ```js\n * const conditions = [\n * \t() => !isEqual(nAssetRecord, oAssetRecord),\n * \t() => !isEqual(nAssetRecord, defPropsAssets),\n * \t() => isEdit.value || isInfo.value,\n * ];\n * conditions.every((condition) => condition())\n * ```\n */\nexport function isConditionsEvery(conditions: Condition[]) {\n\treturn conditions.every((condition) => condition());\n}\n\nexport function isConditionsSome(conditions: Condition[]) {\n\treturn conditions.some((condition) => condition());\n}\n","import { type SimpleAsyncTask } from \"./simple-promise-tools.ts\";\n\nexport const taskTypes = <const>[\"single\", \"parallel\", \"queue\"];\n\nexport type TaskType = (typeof taskTypes)[number];\n\nexport interface BaseTask {\n\t/** 任务类型 */\n\ttype: TaskType;\n}\n\nexport type Task = SimpleAsyncTask | TasksConfig;\n\nexport interface SingleTasks extends BaseTask {\n\ttype: \"single\";\n\ttasks: Task;\n}\n\nexport interface ParallelTasks extends BaseTask {\n\ttype: \"parallel\";\n\ttasks: Task[];\n}\n\nexport interface QueueTasks extends BaseTask {\n\ttype: \"queue\";\n\ttasks: Task[];\n}\n\nexport type TasksConfig = SingleTasks | ParallelTasks | QueueTasks;\n\nexport type PromiseTasksConfig = TasksConfig;\n\nfunction isSingleTasks(config: TasksConfig): config is SingleTasks {\n\treturn config.type === \"single\";\n}\n\nfunction isParallelTasks(config: TasksConfig): config is ParallelTasks {\n\treturn config.type === \"parallel\";\n}\n\nfunction isQueueTasks(config: TasksConfig): config is QueueTasks {\n\treturn config.type === \"queue\";\n}\n\nfunction isSimpleAsyncTask(config: Task): config is SimpleAsyncTask {\n\treturn typeof config === \"function\";\n}\n\nfunction isTasksConfig(config: Task): config is TasksConfig {\n\treturn typeof config === \"object\";\n}\n\n/**\n * 定义异步任务对象\n * @description\n * 这个对象是一揽子异步任务的配置\n */\nexport function definePromiseTasks(config: TasksConfig) {\n\treturn config;\n}\n\n/**\n * @private 一个工具函数 用于生成异步函数数组\n * @deprecated 在处理串行任务时 疑似有故障\n */\nfunction getPromises(tasks: Task[]): ((...args: any) => Promise<any>)[] {\n\treturn tasks.map((task) => {\n\t\treturn async function (...args: any) {\n\t\t\tif (isSimpleAsyncTask(task)) {\n\t\t\t\treturn await task(...args);\n\t\t\t} else {\n\t\t\t\treturn await executePromiseTasks(task);\n\t\t\t}\n\t\t};\n\t});\n}\n\n/**\n * 执行异步函数对象\n */\nexport async function executePromiseTasks(\n\tconfig: TasksConfig,\n\t/**\n\t * 上一次递归执行时提供的参数\n\t * @description\n\t * 考虑到递归函数 这里提供了一个参数 用于传递上一次递归执行的结果\n\t */\n\tlastParams: any = null,\n): Promise<any> {\n\tif (isSingleTasks(config)) {\n\t\tif (isSimpleAsyncTask(config.tasks)) {\n\t\t\t// 实际执行的 tasks 往往是无参函数 这里为了保险,故主动传递参数\n\t\t\treturn await config.tasks(lastParams);\n\t\t}\n\n\t\treturn await executePromiseTasks(config.tasks, lastParams);\n\t}\n\n\tif (isParallelTasks(config)) {\n\t\treturn await Promise.all(\n\t\t\tconfig.tasks.map((task) => {\n\t\t\t\tif (isSimpleAsyncTask(task)) {\n\t\t\t\t\t// console.log(` 并行任务遇到单独的异步函数 `);\n\t\t\t\t\treturn task(lastParams);\n\t\t\t\t}\n\n\t\t\t\t// console.log(` 并行任务遇到嵌套结构 `);\n\t\t\t\treturn executePromiseTasks(task, lastParams);\n\t\t\t}),\n\t\t);\n\t}\n\n\tif (isQueueTasks(config)) {\n\t\tlet res: Awaited<any>;\n\t\tfor await (const task of config.tasks) {\n\t\t\tif (isSimpleAsyncTask(task)) {\n\t\t\t\t// console.log(` 串行任务遇到单独的异步函数 `);\n\n\t\t\t\tres = await task(lastParams);\n\t\t\t\tlastParams = res;\n\t\t\t\t// console.log(` 串行任务 单独 res `, res);\n\t\t\t} else {\n\t\t\t\tres = await executePromiseTasks(task, lastParams);\n\t\t\t\tlastParams = res;\n\t\t\t\t// console.log(` 串行任务 配置 res `, res);\n\t\t\t}\n\t\t}\n\n\t\treturn res;\n\t}\n}\n","// import { uniqueId } from \"lodash-es\";\n// const getCounter = () => uniqueId();\n\n/** 创建简单的异步任务 */\nexport function generateSimpleAsyncTask<T extends (...args: any) => any>(func: T) {\n\t// const taskId = getCounter();\n\n\treturn function (...args: any) {\n\t\t// consola.info(` 这是第 ${taskId} 个异步任务 `);\n\t\t// consola.start(\" 这里是新创建的异步函数 检查参数: \", ...args);\n\n\t\treturn new Promise<ReturnType<T>>((resolve, reject) => {\n\t\t\t// consola.start(\" 内部promise 检查参数: \", ...args);\n\t\t\tresolve(func(...args));\n\t\t});\n\t};\n}\n\nexport type SimpleAsyncTask = ReturnType<typeof generateSimpleAsyncTask>;\n\nexport const initFlag = <const>\"initFlag\";\n\n/**\n * 以队列串行的形式 串行运行异步函数\n * @see https://github.com/ascoders/weekly/blob/master/前沿技术/77.精读《用%20Reduce%20实现%20Promise%20串行执行》.md\n * @version 1\n */\nasync function runPromiseByQueueV1<T>(promises: ((...args: any) => Promise<T>)[]) {\n\tpromises.reduce(\n\t\tasync function (previousPromise, nextPromise, currentIndex) {\n\t\t\tconst response = await previousPromise;\n\t\t\t// consola.log(` reduce串行函数 currentIndex= ${currentIndex} res =`, response);\n\t\t\treturn await nextPromise(response);\n\t\t},\n\t\tPromise.resolve(initFlag) as Promise<any>,\n\t);\n}\n\n/**\n * 以队列串行的形式 串行运行异步函数\n * @version 2\n */\nexport async function runPromiseByQueue<T>(promises: ((...args: any) => Promise<T>)[]) {\n\tlet response: typeof initFlag | Awaited<T> = initFlag;\n\tfor await (const promise of promises) {\n\t\tresponse = await promise(response);\n\t}\n}\n\n/**\n * 以并行的形式 并发运行异步函数\n */\nexport async function runPromiseByConcurrency<T>(promises: ((...args: any) => Promise<T>)[]) {\n\tawait Promise.all(promises.map((promise) => promise()));\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/conditions.ts","../src/define-promise-tasks.ts","../src/simple-promise-tools.ts"],"sourcesContent":["export type Condition = (...args: unknown[]) => boolean;\n\n/** @deprecated 没必要 */\nexport type Conditions = Condition[];\n\n/**\n * 是否每一个条件函数都满足?\n * @description\n * ### 设计理由\n * 旨在于封装这样的代码段\n * ```js\n * const conditions = [\n * \t() => !isEqual(nAssetRecord, oAssetRecord),\n * \t() => !isEqual(nAssetRecord, defPropsAssets),\n * \t() => isEdit.value || isInfo.value,\n * ];\n * conditions.every((condition) => condition())\n * ```\n */\nexport function isConditionsEvery(conditions: Condition[]) {\n\treturn conditions.every((condition) => condition());\n}\n\nexport function isConditionsSome(conditions: Condition[]) {\n\treturn conditions.some((condition) => condition());\n}\n","import { type SimpleAsyncTask } from \"./simple-promise-tools.ts\";\n\nexport const taskTypes = <const>[\"single\", \"parallel\", \"queue\"];\n\nexport type TaskType = (typeof taskTypes)[number];\n\nexport interface BaseTask {\n\t/** 任务类型 */\n\ttype: TaskType;\n}\n\nexport type Task = SimpleAsyncTask | TasksConfig;\n\nexport interface SingleTasks extends BaseTask {\n\ttype: \"single\";\n\ttasks: Task;\n}\n\nexport interface ParallelTasks extends BaseTask {\n\ttype: \"parallel\";\n\ttasks: Task[];\n}\n\nexport interface QueueTasks extends BaseTask {\n\ttype: \"queue\";\n\ttasks: Task[];\n}\n\nexport type TasksConfig = SingleTasks | ParallelTasks | QueueTasks;\n\nexport type PromiseTasksConfig = TasksConfig;\n\nfunction isSingleTasks(config: TasksConfig): config is SingleTasks {\n\treturn config.type === \"single\";\n}\n\nfunction isParallelTasks(config: TasksConfig): config is ParallelTasks {\n\treturn config.type === \"parallel\";\n}\n\nfunction isQueueTasks(config: TasksConfig): config is QueueTasks {\n\treturn config.type === \"queue\";\n}\n\nfunction isSimpleAsyncTask(config: Task): config is SimpleAsyncTask {\n\treturn typeof config === \"function\";\n}\n\nfunction isTasksConfig(config: Task): config is TasksConfig {\n\treturn typeof config === \"object\";\n}\n\n/**\n * 定义异步任务对象\n * @description\n * 这个对象是一揽子异步任务的配置\n */\nexport function definePromiseTasks(config: TasksConfig) {\n\treturn config;\n}\n\n/**\n * @private 一个工具函数 用于生成异步函数数组\n * @deprecated 在处理串行任务时 疑似有故障\n */\nfunction getPromises(tasks: Task[]): ((...args: any) => Promise<any>)[] {\n\treturn tasks.map((task) => {\n\t\treturn async function (...args: any) {\n\t\t\tif (isSimpleAsyncTask(task)) {\n\t\t\t\treturn await task(...args);\n\t\t\t} else {\n\t\t\t\treturn await executePromiseTasks(task);\n\t\t\t}\n\t\t};\n\t});\n}\n\n/**\n * 执行异步函数对象\n */\nexport async function executePromiseTasks(\n\tconfig: TasksConfig,\n\t/**\n\t * 上一次递归执行时提供的参数\n\t * @description\n\t * 考虑到递归函数 这里提供了一个参数 用于传递上一次递归执行的结果\n\t */\n\tlastParams: any = null,\n): Promise<any> {\n\tif (isSingleTasks(config)) {\n\t\tif (isSimpleAsyncTask(config.tasks)) {\n\t\t\t// 实际执行的 tasks 往往是无参函数 这里为了保险,故主动传递参数\n\t\t\treturn await config.tasks(lastParams);\n\t\t}\n\n\t\treturn await executePromiseTasks(config.tasks, lastParams);\n\t}\n\n\tif (isParallelTasks(config)) {\n\t\treturn await Promise.all(\n\t\t\tconfig.tasks.map((task) => {\n\t\t\t\tif (isSimpleAsyncTask(task)) {\n\t\t\t\t\t// console.log(` 并行任务遇到单独的异步函数 `);\n\t\t\t\t\treturn task(lastParams);\n\t\t\t\t}\n\n\t\t\t\t// console.log(` 并行任务遇到嵌套结构 `);\n\t\t\t\treturn executePromiseTasks(task, lastParams);\n\t\t\t}),\n\t\t);\n\t}\n\n\tif (isQueueTasks(config)) {\n\t\tlet res: Awaited<any>;\n\t\tfor await (const task of config.tasks) {\n\t\t\tif (isSimpleAsyncTask(task)) {\n\t\t\t\t// console.log(` 串行任务遇到单独的异步函数 `);\n\n\t\t\t\tres = await task(lastParams);\n\t\t\t\tlastParams = res;\n\t\t\t\t// console.log(` 串行任务 单独 res `, res);\n\t\t\t} else {\n\t\t\t\tres = await executePromiseTasks(task, lastParams);\n\t\t\t\tlastParams = res;\n\t\t\t\t// console.log(` 串行任务 配置 res `, res);\n\t\t\t}\n\t\t}\n\n\t\treturn res;\n\t}\n}\n","// import { uniqueId } from \"lodash-es\";\n// const getCounter = () => uniqueId();\n\n/** 创建简单的异步任务 */\nexport function generateSimpleAsyncTask<T extends (...args: any) => any>(func: T) {\n\t// const taskId = getCounter();\n\n\treturn function (...args: any) {\n\t\t// consola.info(` 这是第 ${taskId} 个异步任务 `);\n\t\t// consola.start(\" 这里是新创建的异步函数 检查参数: \", ...args);\n\n\t\treturn new Promise<ReturnType<T>>((resolve, reject) => {\n\t\t\t// consola.start(\" 内部promise 检查参数: \", ...args);\n\t\t\tresolve(func(...args));\n\t\t});\n\t};\n}\n\nexport type SimpleAsyncTask = ReturnType<typeof generateSimpleAsyncTask>;\n\nexport const initFlag = <const>\"initFlag\";\n\n/**\n * 以队列串行的形式 串行运行异步函数\n * @see https://github.com/ascoders/weekly/blob/master/前沿技术/77.精读《用%20Reduce%20实现%20Promise%20串行执行》.md\n * @version 1\n */\nasync function runPromiseByQueueV1<T>(promises: ((...args: any) => Promise<T>)[]) {\n\tpromises.reduce(\n\t\tasync function (previousPromise, nextPromise, currentIndex) {\n\t\t\tconst response = await previousPromise;\n\t\t\t// consola.log(` reduce串行函数 currentIndex= ${currentIndex} res =`, response);\n\t\t\treturn await nextPromise(response);\n\t\t},\n\t\tPromise.resolve(initFlag) as Promise<any>,\n\t);\n}\n\n/**\n * 以队列串行的形式 串行运行异步函数\n * @version 2\n */\nexport async function runPromiseByQueue<T>(promises: ((...args: any) => Promise<T>)[]) {\n\tlet response: typeof initFlag | Awaited<T> = initFlag;\n\tfor await (const promise of promises) {\n\t\tresponse = await promise(response);\n\t}\n}\n\n/**\n * 以并行的形式 并发运行异步函数\n */\nexport async function runPromiseByConcurrency<T>(promises: ((...args: any) => Promise<T>)[]) {\n\tawait Promise.all(promises.map((promise) => promise()));\n}\n"],"mappings":";AAmBO,SAAS,kBAAkB,YAAyB;AAC1D,SAAO,WAAW,MAAM,CAAC,cAAc,UAAU,CAAC;AACnD;AAEO,SAAS,iBAAiB,YAAyB;AACzD,SAAO,WAAW,KAAK,CAAC,cAAc,UAAU,CAAC;AAClD;;;ACvBO,IAAM,YAAmB,CAAC,UAAU,YAAY,OAAO;AA8B9D,SAAS,cAAc,QAA4C;AAClE,SAAO,OAAO,SAAS;AACxB;AAEA,SAAS,gBAAgB,QAA8C;AACtE,SAAO,OAAO,SAAS;AACxB;AAEA,SAAS,aAAa,QAA2C;AAChE,SAAO,OAAO,SAAS;AACxB;AAEA,SAAS,kBAAkB,QAAyC;AACnE,SAAO,OAAO,WAAW;AAC1B;AAWO,SAAS,mBAAmB,QAAqB;AACvD,SAAO;AACR;AAqBA,eAAsB,oBACrB,QAMA,aAAkB,MACH;AACf,MAAI,cAAc,MAAM,GAAG;AAC1B,QAAI,kBAAkB,OAAO,KAAK,GAAG;AAEpC,aAAO,MAAM,OAAO,MAAM,UAAU;AAAA,IACrC;AAEA,WAAO,MAAM,oBAAoB,OAAO,OAAO,UAAU;AAAA,EAC1D;AAEA,MAAI,gBAAgB,MAAM,GAAG;AAC5B,WAAO,MAAM,QAAQ;AAAA,MACpB,OAAO,MAAM,IAAI,CAAC,SAAS;AAC1B,YAAI,kBAAkB,IAAI,GAAG;AAE5B,iBAAO,KAAK,UAAU;AAAA,QACvB;AAGA,eAAO,oBAAoB,MAAM,UAAU;AAAA,MAC5C,CAAC;AAAA,IACF;AAAA,EACD;AAEA,MAAI,aAAa,MAAM,GAAG;AACzB,QAAI;AACJ,qBAAiB,QAAQ,OAAO,OAAO;AACtC,UAAI,kBAAkB,IAAI,GAAG;AAG5B,cAAM,MAAM,KAAK,UAAU;AAC3B,qBAAa;AAAA,MAEd,OAAO;AACN,cAAM,MAAM,oBAAoB,MAAM,UAAU;AAChD,qBAAa;AAAA,MAEd;AAAA,IACD;AAEA,WAAO;AAAA,EACR;AACD;;;AC9HO,SAAS,wBAAyD,MAAS;AAGjF,SAAO,YAAa,MAAW;AAI9B,WAAO,IAAI,QAAuB,CAAC,SAAS,WAAW;AAEtD,cAAQ,KAAK,GAAG,IAAI,CAAC;AAAA,IACtB,CAAC;AAAA,EACF;AACD;AAIO,IAAM,WAAkB;AAsB/B,eAAsB,kBAAqB,UAA4C;AACtF,MAAI,WAAyC;AAC7C,mBAAiB,WAAW,UAAU;AACrC,eAAW,MAAM,QAAQ,QAAQ;AAAA,EAClC;AACD;AAKA,eAAsB,wBAA2B,UAA4C;AAC5F,QAAM,QAAQ,IAAI,SAAS,IAAI,CAAC,YAAY,QAAQ,CAAC,CAAC;AACvD;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ruan-cat/utils",
3
- "version": "3.0.1",
3
+ "version": "3.2.0",
4
4
  "description": "阮喵喵工具集合。一个纯typescript库,也提供纯js文件。",
5
5
  "type": "module",
6
6
  "main": "./src/index.ts",
@@ -58,23 +58,23 @@
58
58
  "tsconfig.json"
59
59
  ],
60
60
  "dependencies": {
61
- "@vueuse/integrations": "^12.3.0",
62
- "axios": "^1.7.9",
61
+ "@vueuse/integrations": "^12.7.0",
62
+ "axios": "^1.8.1",
63
63
  "consola": "^3.4.0",
64
64
  "lodash-es": "^4.17.21"
65
65
  },
66
66
  "devDependencies": {
67
- "@antfu/utils": "^0.7.10",
67
+ "@antfu/utils": "^9.1.0",
68
68
  "@types/lodash-es": "^4.17.12",
69
- "@types/node": "^22.13.1",
70
- "@types/qs": "^6.9.17",
71
- "qs": "^6.13.1",
72
- "tsup": "^8.3.5",
69
+ "@types/node": "^22.13.8",
70
+ "@types/qs": "^6.9.18",
71
+ "qs": "^6.14.0",
72
+ "tsup": "^8.4.0",
73
73
  "type-plus": "^7.6.2",
74
- "typedoc": "^0.27.0",
74
+ "typedoc": "^0.27.9",
75
75
  "typedoc-plugin-frontmatter": "^1.2.1",
76
- "typedoc-plugin-markdown": "^4.3.0",
77
- "typescript": "5.7.3",
76
+ "typedoc-plugin-markdown": "^4.4.2",
77
+ "typescript": "^5.8.2",
78
78
  "unplugin-vue-router": "^0.11.2",
79
79
  "vite-plugin-autogeneration-import-file": "^3.0.0",
80
80
  "@ruan-cat/vuepress-preset-config": "^0.1.19"
package/src/index.ts CHANGED
@@ -1,4 +1,3 @@
1
- export * from "./rmmv-class-expand-tools.ts";
2
1
  export * from "./conditions.ts";
3
2
  export * from "./define-promise-tasks.ts";
4
3
  export * from "./simple-promise-tools.ts";
@@ -38,6 +38,14 @@ pnpm i -P @vueuse/integrations axios
38
38
 
39
39
  :::
40
40
 
41
+ ## 基于项目二次封装 useAxiosWrapper 函数
42
+
43
+ ::: details
44
+
45
+ @[code](./tests/projectRequest.ts)
46
+
47
+ :::
48
+
41
49
  ## 定义接口
42
50
 
43
51
  如下:
@@ -13,6 +13,7 @@ export type KeyAxiosRequestConfig<D = any> = keyof AxiosRequestConfig<D>;
13
13
  export type KeyHelper<K extends KeyAxiosRequestConfig> = K;
14
14
 
15
15
  export type RemoveUrl<T extends KeyAxiosRequestConfig> = Exclude<T, "url">;
16
+ export type RemoveUrlMethod<T extends KeyAxiosRequestConfig> = Exclude<T, "url" | "method">;
16
17
 
17
18
  /**
18
19
  * 创建 AxiosRequestConfig 的各种变种类型
@@ -1,220 +0,0 @@
1
- import type { OptionalKeysOf } from "type-fest";
2
- import { forIn, hasIn, isFunction, uniqueId } from "lodash-es";
3
-
4
- /**
5
- * rmmv特征基类
6
- * @description
7
- * 全部的rmmv类都具有 `initialize` 函数
8
- *
9
- * 此类型用于描述此
10
- */
11
- export declare abstract class RmmvClass {
12
- initialize: (...args: any[]) => void;
13
- }
14
-
15
- /**
16
- * 获取对象的全部函数key名称
17
- * @description
18
- * 从一个类型内,获取值为函数的key名称
19
- */
20
- export type FunctionKeys<T> = {
21
- [K in keyof T]: T[K] extends (...args: any[]) => any ? K : never;
22
- }[keyof T];
23
-
24
- /**
25
- * 属性提示工具
26
- * @description
27
- * 对继承的类进行属性提示
28
- *
29
- * 对自己新增的属性和函数做属性提示
30
- *
31
- * 对全部涉及到的函数,其this全部做判定
32
- */
33
- export type AttributePromptTool<SourceCode extends RmmvClass, UserCode> = ThisType<SourceCode & UserCode> &
34
- Partial<SourceCode> &
35
- UserCode;
36
-
37
- type UserCodeClassAttributeType = {
38
- counter: number;
39
- drillCalendar: string[];
40
- sayFuck: () => void;
41
- isUserCodeClass(): true;
42
- getDrillCalendar(): string[];
43
- };
44
-
45
- /**
46
- * 默认处理策略
47
- * @description
48
- * 先回调rmmv源码 再加上用户代码
49
- */
50
- export const defaultHandleStrategy = <const>"source-first";
51
-
52
- /**
53
- * 处理策略
54
- * @description
55
- * 用户代码相对于rmmv源码的处理策略
56
- */
57
- const handleStrategy = <const>[
58
- /** 用户代码覆盖掉rmmv源码 */
59
- "userCode-cover-source",
60
-
61
- defaultHandleStrategy,
62
-
63
- /** 先执行用户代码 再回调rmmv源码 */
64
- "userCode-first",
65
- ];
66
-
67
- /**
68
- * 处理策略
69
- * @description
70
- * 用户代码相对于rmmv源码的处理策略
71
- */
72
- export type HandleStrategy = (typeof handleStrategy)[number];
73
-
74
- function isSourceFirst(handleStrategy: HandleStrategy): handleStrategy is "source-first" {
75
- return handleStrategy === "source-first";
76
- }
77
-
78
- function isUserCodeCoverSource(handleStrategy: HandleStrategy): handleStrategy is "userCode-cover-source" {
79
- return handleStrategy === "userCode-cover-source";
80
- }
81
-
82
- function isUserCodeFirst(handleStrategy: HandleStrategy): handleStrategy is "userCode-first" {
83
- return handleStrategy === "userCode-first";
84
- }
85
-
86
- /**
87
- * 被默认执行默认处理策略的函数名
88
- * @description
89
- * 初始化函数默认使用固定的处理策略。
90
- */
91
- export type defaultHandleStrategy_FuncationName = FunctionKeys<RmmvClass>;
92
-
93
- /** 全部可选字段组成的对象 且该对象的全部字段必填 */
94
- type AllOptionalFieldObj<T extends object> = Required<Pick<T, OptionalKeysOf<T>>>;
95
-
96
- /** 给一个对象排除 init 字段 */
97
- type NoInit<T> = Omit<T, defaultHandleStrategy_FuncationName>;
98
-
99
- type AllOptionalFieldObj_noInit<T extends object> = NoInit<AllOptionalFieldObj<T>>;
100
-
101
- /** 处理策略配置的 全部有意义的配置键名 */
102
- type HandleStrategyConfigKeys<T extends object> = FunctionKeys<AllOptionalFieldObj_noInit<T>>;
103
-
104
- /**
105
- * 全部有意义函数的 处理策略配置
106
- * @description
107
- * 只有可能去覆盖,拓展的函数名,才值得去配置
108
- */
109
- type HandleStrategyConfig<T extends object> = Record<HandleStrategyConfigKeys<T>, HandleStrategy>;
110
-
111
- /** rmmv类拓展工具函数配置 */
112
- type RmmvClassExpandTools<SourceCode extends new (...args: any[]) => RmmvClass, UserCode extends object> = {
113
- /** 源码 一般是被拓展的类,往往是rmmv的源码类 */
114
- source: SourceCode;
115
-
116
- /** 用户代码 插件开发者编写的一个内部完备的对象 */
117
- userCode: UserCode;
118
-
119
- /**
120
- * 拓展配置 按照要求拓展
121
- * @description
122
- * 用户可以不提供配置 就默认按照标准的方式处理
123
- */
124
- config?: Partial<HandleStrategyConfig<UserCode>>;
125
- };
126
-
127
- /** 函数别名存储对象 */
128
- const functionAlias = new Map<string, Function>();
129
-
130
- /** 生成函数别名id */
131
- function generateFunctionAliasId(key: string) {
132
- return uniqueId(`FunctionAliasId_${key}_`);
133
- }
134
-
135
- /**
136
- * rmmv类拓展工具函数
137
- * @description
138
- * 预期处理5种情况
139
- *
140
- * - 1. 用户代码覆盖掉rmmv源码
141
- * - 2. 默认处理策略
142
- * - 3. 先执行用户代码 再回调rmmv源码
143
- * - 4. 初始化函数默认使用固定的处理策略
144
- * - 5. 继承对象没有这个属性时 说明是新的函数 直接添加到原型链上
145
- */
146
- export function rmmvClassExpandTools<
147
- SourceCode extends new (...args: any[]) => RmmvClass,
148
- UserCode extends object = any,
149
- >(params: RmmvClassExpandTools<SourceCode, UserCode>) {
150
- const { source, userCode, config } = params;
151
- const handleStrategyConfig = config;
152
-
153
- function getHandleStrategy(key: HandleStrategyConfigKeys<UserCode>): HandleStrategy {
154
- return handleStrategyConfig?.[key] ?? defaultHandleStrategy;
155
- }
156
-
157
- /** 源对象的原型链 */
158
- const sourcePrototype = source.prototype;
159
-
160
- /** 属性是否在源对象的原型链内? */
161
- function isInSourcePrototype(key: string) {
162
- return hasIn(sourcePrototype, key);
163
- }
164
-
165
- /** 是不是初始化函数的名称? */
166
- function isInitialize(key: string): key is defaultHandleStrategy_FuncationName {
167
- return key === "initialize";
168
- }
169
-
170
- forIn(userCode, function (value, key, object: Record<string, any>) {
171
- console.log(` value, key, object `, value, key);
172
-
173
- // 继承对象有没有这个属性?
174
- if (isInSourcePrototype(key)) {
175
- if (isFunction(object[key])) {
176
- const handleStrategy = getHandleStrategy(key as HandleStrategyConfigKeys<UserCode>);
177
-
178
- // 1 用户代码覆盖掉rmmv源码
179
- if (isUserCodeCoverSource(handleStrategy)) {
180
- sourcePrototype[key] = value;
181
- }
182
-
183
- // 2 初始化函数默认使用固定的处理策略
184
- // 3 默认处理策略
185
- if (isInitialize(key) || isSourceFirst(handleStrategy)) {
186
- const functionAliasId = generateFunctionAliasId(key);
187
- functionAlias.set(functionAliasId, sourcePrototype[key]);
188
-
189
- sourcePrototype[key] = function () {
190
- console.log(` 进入到二次封装的函数 函数id = `, functionAliasId);
191
- // 先回调rmmv源码
192
- functionAlias.get(functionAliasId)!.apply(this, arguments);
193
- value.apply(this, arguments);
194
- };
195
- }
196
-
197
- // 4 先执行用户代码 再回调rmmv源码
198
- if (isUserCodeFirst(handleStrategy)) {
199
- const functionAliasId = generateFunctionAliasId(key);
200
- functionAlias.set(functionAliasId, sourcePrototype[key]);
201
-
202
- sourcePrototype[key] = function () {
203
- console.log(` 进入到二次封装的函数 函数id = `, functionAliasId);
204
- // 先执行用户代码
205
- value.apply(this, arguments);
206
- functionAlias.get(functionAliasId)!.apply(this, arguments);
207
- };
208
- }
209
- }
210
- } else {
211
- if (isFunction(object[key])) {
212
- /**
213
- * 5 继承对象没有这个属性时 说明是新的函数
214
- * 直接添加到原型链上
215
- */
216
- sourcePrototype[key] = value;
217
- }
218
- }
219
- });
220
- }