yann-useorderfun 1.0.0 → 1.1.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/AI_USAGE.md +103 -0
- package/README.md +206 -69
- package/dist/index.js +1 -1
- package/dist/index.umd.cjs +1 -1
- package/package.json +3 -2
package/AI_USAGE.md
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# yann-useorderfun:AI 集成指南
|
|
2
|
+
|
|
3
|
+
用途:帮助 AI 在使用该库的应用中生成正确代码。完整示例与参考见 [README.md](./README.md)。本文描述当前仓库 API;集成其他版本时,以安装包的 `index.d.ts` 为准。
|
|
4
|
+
|
|
5
|
+
## 集成步骤
|
|
6
|
+
|
|
7
|
+
1. 确认应用使用 Vue 3.2+,安装 `yann-useorderfun`,通过包名导入公开 API。
|
|
8
|
+
2. 根据列表来源与结果消费方式,从下表选择运行器。
|
|
9
|
+
3. 把任务写成单参数函数,显式返回下一步需要的数据。优先使用统一的数据结构,明确输入与输出类型。
|
|
10
|
+
4. 调用 `start(input)`,处理 `[err, value]`;按需要展示只读 Ref 状态。
|
|
11
|
+
5. 列表变化后按所选入口重置;组件 / effect scope 外的实例在使用结束时 `dispose()`。
|
|
12
|
+
|
|
13
|
+
完成标准:导入名和方法存在于公开声明;任务输出能作为下一任务输入;处理错误和可能的 `undefined` 结果;明确列表更新与释放方式。
|
|
14
|
+
|
|
15
|
+
## API 选择
|
|
16
|
+
|
|
17
|
+
| 条件 | 创建方式 | 消费结果 |
|
|
18
|
+
| --- | --- | --- |
|
|
19
|
+
| 普通数组,固定或手动替换列表 | `useOrderFun<T, U>(list, options?)` | `await start(input)` / `await resume()`;列表替换用 `update(newList)` |
|
|
20
|
+
| Vue Ref 列表,自动跟踪成员或顺序变化 | `useWatchOrderFun<T, U>(listRef, options?)` | `await start(input)` / `await resume()` |
|
|
21
|
+
| Vue Ref 列表,需要纯同步流程立即返回 | `useWatchOrderFunSync<T, U>(listRef, options?)` | `start(input, callback?)` / `resume(callback?)`;返回元组或 `undefined` |
|
|
22
|
+
|
|
23
|
+
默认选择 `useOrderFun`。监听入口仅监听列表并重置状态,执行始终由 `start()` 显式触发。`update()` 仅存在于手动入口。同步入口也支持异步任务;涉及 Promise / thenable 时,用回调处理最终交付,或直接选择异步入口。
|
|
24
|
+
|
|
25
|
+
## 最小模板
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
import { useOrderFun } from 'yann-useorderfun';
|
|
29
|
+
import type { FunctionType } from 'yann-useorderfun';
|
|
30
|
+
|
|
31
|
+
type Data = { count: number };
|
|
32
|
+
const tasks: Array<FunctionType<Data, Data>> = [
|
|
33
|
+
data => ({ ...data, count: data.count + 1 }),
|
|
34
|
+
async data => ({ ...data, count: data.count * 2 })
|
|
35
|
+
];
|
|
36
|
+
|
|
37
|
+
export async function process(input: Data) {
|
|
38
|
+
const runner = useOrderFun<Data>(tasks);
|
|
39
|
+
try {
|
|
40
|
+
const [err, value] = await runner.start(input);
|
|
41
|
+
if (err) throw err; // 由应用选择记录、展示或重新抛出
|
|
42
|
+
return value; // Data | undefined
|
|
43
|
+
} finally {
|
|
44
|
+
runner.dispose();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
组件中需要跨按钮保留状态时,在 `setup` / `<script setup>` 中创建一个运行器并复用,作用域销毁时会自动释放。脚本通过 `.value` 读取 Ref;模板可自动解包。
|
|
50
|
+
|
|
51
|
+
## 数据与类型契约
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
type FunctionType<T, U> = (data: T) => U | PromiseLike<U>;
|
|
55
|
+
type OrderResult<U> = [Error, undefined] | [null, U | undefined];
|
|
56
|
+
interface OrderOptions {
|
|
57
|
+
clone?: boolean | (<V>(value: V) => V);
|
|
58
|
+
retainResults?: boolean;
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
- 任务顺序执行,第一步收到 `start(input)`,下一步收到前一步的返回值。省略输入会传入 `undefined`。
|
|
63
|
+
- `<T, U = T>` 是整个列表的公共签名,不会逐步推导异构任务链。多步流程优先使用 `T = U` 或兼容的公共数据结构;默认泛型为 `unknown`。
|
|
64
|
+
- 无返回值任务向后传递 `undefined`。空列表透传输入;成功元组的值可以是 `undefined`,以 `err === null` 判断成功。
|
|
65
|
+
- 使用命名导入;公开入口只有上述三个,不存在 `useOrderFunSync`。类型用 `import type` 导入。
|
|
66
|
+
- `FunctionTypeSync` 等价于 `FunctionType`;回调参数是一个结果元组,即 `([err, value]) => { ... }`。
|
|
67
|
+
|
|
68
|
+
## 状态与交付
|
|
69
|
+
|
|
70
|
+
| 只读 Ref | 初始值 / 含义 |
|
|
71
|
+
| --- | --- |
|
|
72
|
+
| `result` | `undefined`;本段执行完成或暂停时写入当前输出 |
|
|
73
|
+
| `error` | `null`;任务失败时为 `Error` |
|
|
74
|
+
| `isSuspend` | `false`;表示已请求暂停 |
|
|
75
|
+
| `statusList` | 与任务等长;每项为 `{ status, data }`,数据是该步输出 |
|
|
76
|
+
|
|
77
|
+
步骤状态精确取值:`unStart`、`start`、`fulfilled`、`rejected`。通过运行器方法修改流程,状态和嵌套结果按只读数据消费。
|
|
78
|
+
|
|
79
|
+
任务失败(抛异常、Promise 拒绝或拷贝失败)交付 `[Error, undefined]`,停止后续任务。创建入口的参数校验以及 `update()` 的非法调用会同步抛出异常,这与任务错误元组不同。
|
|
80
|
+
|
|
81
|
+
同步入口的完成回调在纯同步流程中会在调用返回前执行;遇到异步步骤,立即返回 `undefined`,稍后交付回调。每次启动或续跑的回调至多调用一次;统一在回调中处理结果,避免返回值与回调重复触发应用副作用。回调本身由应用负责错误处理。
|
|
82
|
+
|
|
83
|
+
## 列表、暂停与生命周期
|
|
84
|
+
|
|
85
|
+
- 手动入口:`update(newList)` 替换列表并重置结果、错误与步骤状态。直接修改普通数组不会触发监听;每次 `start()` 会读取列表并保存本次执行快照。
|
|
86
|
+
- 监听入口:传入 `ref(functions)`;替换、增删和重排会触发重置,函数内部属性不被监听。列表修改后紧接启动时,先 `await nextTick()`,避免排队中的监听重置刚启动的流程。
|
|
87
|
+
- `suspend()` 始终返回 `Promise<OrderResult<U>>`。它等待当前步骤完成后暂停,当前 `start()` 的 Promise / 回调也会交付这个暂停结果。`isSuspend` 为真时,当前异步任务可能仍在运行。
|
|
88
|
+
- 等待暂停结果后调用 `resume()`,从下一步继续并产生新的交付。最后一步完成即结束流程;空闲时暂停或恢复只交付当前结果。执行中恢复可撤销暂停请求。
|
|
89
|
+
- 重复启动、列表更新或释放会作废旧执行,并向旧调用交付错误元组。旧任务的迟到结果不会覆盖新状态。这不是任务级取消;请求和定时器需由任务管理 `AbortController` 或清理函数。
|
|
90
|
+
- `dispose()` 可重复调用,停止监听并清空状态。释放后需要新实例:`start()` 交付错误元组,手动 `update()` 抛出异常。
|
|
91
|
+
- 在组件 / effect scope 内同步创建可自动释放;在 scope 外创建时显式释放。纯同步流程通常在 `start()` 返回前完成,外部 UI 暂停适用于有等待点的流程。
|
|
92
|
+
|
|
93
|
+
## 配置决策
|
|
94
|
+
|
|
95
|
+
默认 `clone: true`:深拷贝每个任务输入与对外交付的结果。需要减少拷贝开销且允许共享引用时,显式设置 `clone: false`;任务修改共享对象会影响原始输入。自定义拷贝器应满足 `<V>(value: V) => V`,并覆盖流程可能出现的值,包括 `undefined`。
|
|
96
|
+
|
|
97
|
+
默认 `retainResults: true`:保留每一步输出。仅需要状态与最终结果时,可以设为 `false`;新步骤成功后上一项的 `data` 被清除,当前最近成功项的数据仍保留。
|
|
98
|
+
|
|
99
|
+
## 查阅路径
|
|
100
|
+
|
|
101
|
+
- 使用示例、API 参考、开发命令:[README.md](./README.md)。
|
|
102
|
+
- 当前公开类型:[index.d.ts](./index.d.ts)。
|
|
103
|
+
- 在本仓库修改库实现时:阅读 `index.ts`,通过 `pnpm build` 生成声明,通过 `pnpm test` 验证;性能分析见 [OPTIMIZATION.md](./OPTIMIZATION.md)。
|
package/README.md
CHANGED
|
@@ -1,94 +1,231 @@
|
|
|
1
1
|
# yann-useOrderFun
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Vue 3.2+ 的函数流水线工具:按数组顺序执行任务,把上一步的返回值传给下一步,并提供只读响应式状态、暂停和恢复能力。支持同步函数、Promise 和 thenable,适合数据处理、分步提交和需要展示步骤状态的流程。
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
开发者从本页开始;AI 在生成集成代码、选择 API 或处理生命周期时,请先阅读 [AI 使用指南](./AI_USAGE.md)。
|
|
6
|
+
|
|
7
|
+
## 安装
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
pnpm add yann-useorderfun vue
|
|
11
|
+
# 或 npm install yann-useorderfun vue
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Vue 是 peer dependency,使用项目中已有的 Vue 3.2+ 即可。包提供 ESM、CommonJS 和 TypeScript 声明,无需注册 Vue 插件。
|
|
15
|
+
|
|
16
|
+
```ts
|
|
17
|
+
import { useOrderFun } from 'yann-useorderfun';
|
|
18
|
+
```
|
|
6
19
|
|
|
7
20
|
```js
|
|
8
|
-
|
|
9
|
-
|
|
21
|
+
const { useOrderFun } = require('yann-useorderfun');
|
|
22
|
+
```
|
|
10
23
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
// 方案一 手动更新list,手动执行update更新statusList,update可以传递新的list
|
|
38
|
-
// start执行时,会根据list重置statusList的状态
|
|
39
|
-
const list = [f1, f2, f3];
|
|
40
|
-
const { statusList, result, error, start, suspend, update } = useOrderFun(list);
|
|
41
|
-
const [err, res] = await start(data);
|
|
42
|
-
// 如果需要更新 list,可以执行更新函数 update
|
|
43
|
-
update([f1, f2]);
|
|
44
|
-
const [err, res] = await start(data);
|
|
45
|
-
|
|
46
|
-
// 方案二 自动监听listRef变化,自动更新statusList
|
|
47
|
-
// start执行时,会根据listRef重置statusList的状态
|
|
48
|
-
const listRef = ref([f1, f2, f3]);
|
|
49
|
-
const { statusList, result, error, start, suspend } = useWatchOrderFun(listRef);
|
|
24
|
+
## 快速开始
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
import { useOrderFun } from 'yann-useorderfun';
|
|
28
|
+
|
|
29
|
+
const runner = useOrderFun<number>([
|
|
30
|
+
value => value + 1,
|
|
31
|
+
async value => value + 10,
|
|
32
|
+
value => value * 2
|
|
33
|
+
]);
|
|
34
|
+
|
|
35
|
+
async function main() {
|
|
36
|
+
const [err, value] = await runner.start(1);
|
|
37
|
+
if (err) {
|
|
38
|
+
console.error(err.message);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
console.log(value); // 24
|
|
42
|
+
console.log(runner.result.value); // 24
|
|
43
|
+
console.log(runner.statusList.value);
|
|
44
|
+
// [{ status: 'fulfilled', data: 2 },
|
|
45
|
+
// { status: 'fulfilled', data: 12 },
|
|
46
|
+
// { status: 'fulfilled', data: 24 }]
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
main().finally(() => runner.dispose()); // Vue scope 外手动释放
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
每个任务只接收一个参数。第一个任务接收 `start(data)` 的输入,后续任务接收上一步的输出。任务必须返回下一步需要的值;无返回值会把 `undefined` 传给下一步。异步任务完成后才执行下一步。
|
|
53
|
+
|
|
54
|
+
## 选择运行器
|
|
53
55
|
|
|
54
|
-
|
|
|
55
|
-
|
|
|
56
|
-
|
|
|
57
|
-
|
|
|
58
|
-
|
|
|
59
|
-
| start | function | 执行函数 |
|
|
60
|
-
| suspend | function | 暂停函数 |
|
|
61
|
-
| resume | function | 恢复执行 |
|
|
62
|
-
| update | function | 更新函数 |
|
|
63
|
-
| dispose | function | 停止监听并释放保存的数据 |
|
|
56
|
+
| API | 任务列表 | 启动与恢复的返回值 | 适用情况 |
|
|
57
|
+
| --- | --- | --- | --- |
|
|
58
|
+
| `useOrderFun(list, options?)` | 普通函数数组,通过 `update(list)` 替换 | `Promise<OrderResult<U>>` | 固定列表或手动管理列表 |
|
|
59
|
+
| `useWatchOrderFun(listRef, options?)` | Vue `Ref`,监听成员与顺序变化 | `Promise<OrderResult<U>>` | 列表随 Vue 状态变化 |
|
|
60
|
+
| `useWatchOrderFunSync(listRef, options?)` | Vue `Ref`,监听成员与顺序变化 | `OrderResult<U> \| undefined`,可传完成回调 | 需要立即取得纯同步流程的结果 |
|
|
64
61
|
|
|
65
|
-
|
|
62
|
+
三者都需要显式调用 `start()`。监听列表只会重置状态,不会自动执行任务;只有 `useOrderFun` 提供 `update()`。
|
|
63
|
+
|
|
64
|
+
### 手动替换任务列表
|
|
66
65
|
|
|
67
66
|
```ts
|
|
68
|
-
const runner = useOrderFun<number
|
|
67
|
+
const runner = useOrderFun<number>([value => value + 1]);
|
|
68
|
+
await runner.start(1); // [null, 2]
|
|
69
|
+
runner.update([value => value * 3]); // 清空结果和错误,重建步骤状态
|
|
70
|
+
await runner.start(2); // [null, 6]
|
|
71
|
+
runner.dispose();
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
手动模式不监听原数组的修改。需要立即重置状态时,调用 `update(newList)`;每次 `start()` 都会读取当前列表并创建本次执行的快照。
|
|
75
|
+
|
|
76
|
+
### 在 Vue 组件中使用
|
|
77
|
+
|
|
78
|
+
```vue
|
|
79
|
+
<script setup lang="ts">
|
|
80
|
+
import { nextTick, ref } from 'vue';
|
|
81
|
+
import { useWatchOrderFun } from 'yann-useorderfun';
|
|
82
|
+
import type { FunctionType } from 'yann-useorderfun';
|
|
83
|
+
|
|
84
|
+
const tasks = ref<Array<FunctionType<number, number>>>([
|
|
69
85
|
value => value + 1,
|
|
70
|
-
async value => value
|
|
71
|
-
]
|
|
72
|
-
|
|
73
|
-
|
|
86
|
+
async value => value * 2
|
|
87
|
+
]);
|
|
88
|
+
const { start, result, error, statusList, isSuspend, suspend, resume } =
|
|
89
|
+
useWatchOrderFun(tasks);
|
|
90
|
+
|
|
91
|
+
async function run() {
|
|
92
|
+
const [err] = await start(1);
|
|
93
|
+
if (err) console.error(err.message);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async function replaceTasks() {
|
|
97
|
+
tasks.value = [value => value + 10];
|
|
98
|
+
await nextTick(); // 等待列表监听完成重置,再启动新流程
|
|
99
|
+
await run();
|
|
100
|
+
}
|
|
101
|
+
</script>
|
|
102
|
+
|
|
103
|
+
<template>
|
|
104
|
+
<button @click="run">开始</button>
|
|
105
|
+
<button @click="suspend()">暂停</button>
|
|
106
|
+
<button @click="resume()">继续</button>
|
|
107
|
+
<button @click="replaceTasks">替换任务并执行</button>
|
|
108
|
+
<p>结果:{{ result }};暂停:{{ isSuspend }}</p>
|
|
109
|
+
<p v-if="error">{{ error.message }}</p>
|
|
110
|
+
<ul>
|
|
111
|
+
<li v-for="(step, index) in statusList" :key="index">
|
|
112
|
+
{{ index + 1 }}:{{ step.status }},输出:{{ step.data }}
|
|
113
|
+
</li>
|
|
114
|
+
</ul>
|
|
115
|
+
</template>
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
JavaScript / TypeScript 中通过 `.value` 读取状态,Vue 模板会自动解包。监听采用 Vue 默认调度;替换、增删或重排列表后,若要紧接着启动,请先 `await nextTick()`。函数内部属性变化不属于列表监听范围。
|
|
119
|
+
|
|
120
|
+
### 同步返回与异步回调
|
|
121
|
+
|
|
122
|
+
```ts
|
|
123
|
+
import { ref } from 'vue';
|
|
124
|
+
import { useWatchOrderFunSync } from 'yann-useorderfun';
|
|
125
|
+
|
|
126
|
+
const sync = useWatchOrderFunSync<number>(ref([
|
|
127
|
+
value => value + 1,
|
|
128
|
+
value => value * 2
|
|
129
|
+
]));
|
|
130
|
+
const outcome = sync.start(1); // [null, 4]
|
|
131
|
+
sync.dispose();
|
|
132
|
+
|
|
133
|
+
const hybrid = useWatchOrderFunSync<number>(ref([
|
|
134
|
+
value => value + 1,
|
|
135
|
+
async value => value * 2
|
|
136
|
+
]));
|
|
137
|
+
const immediate = hybrid.start(1, ([err, value]) => {
|
|
138
|
+
if (err) console.error(err.message);
|
|
139
|
+
else console.log(value); // 4
|
|
140
|
+
hybrid.dispose();
|
|
74
141
|
});
|
|
75
|
-
|
|
142
|
+
console.log(immediate); // undefined,尚未完成
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
同步入口也支持异步任务。遇到 Promise / thenable 时立即返回 `undefined`,完成或暂停后通过回调交付元组。纯同步流程的回调会在 `start()` 返回前执行;同一次启动或续跑的回调至多调用一次。统一在回调里处理结果,可避免同时处理返回值和回调造成重复副作用。同步运行器的 `resume(callback?)` 遵循相同规则,`suspend()` 仍返回 Promise。
|
|
146
|
+
|
|
147
|
+
## API 与状态
|
|
148
|
+
|
|
149
|
+
```ts
|
|
150
|
+
type OrderResult<U> = [Error, undefined] | [null, U | undefined];
|
|
151
|
+
type FunctionType<T, U> = (data: T) => U | PromiseLike<U>;
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
| 成员 | 含义 |
|
|
155
|
+
| --- | --- |
|
|
156
|
+
| `start(data?)` | 从第一步开始新流程,清空结果、错误与步骤状态;省略输入时第一步收到 `undefined` |
|
|
157
|
+
| `suspend()` | 请求暂停,等待当前步骤完成后返回本段结果 |
|
|
158
|
+
| `resume()` | 从暂停后的下一步继续;异步入口返回新的结果 Promise |
|
|
159
|
+
| `update(list)` | 仅手动运行器提供,替换列表并重置状态 |
|
|
160
|
+
| `dispose()` | 停止监听、作废在途执行并清空状态;可以重复调用 |
|
|
161
|
+
| `result` | 只读 Ref,初始或重置后为 `undefined`,完成或暂停时更新为当前结果 |
|
|
162
|
+
| `error` | 只读 Ref,初始为 `null`,任务失败时保存 `Error` |
|
|
163
|
+
| `isSuspend` | 只读 Ref,表示已请求挂起;不代表当前异步任务已经结束 |
|
|
164
|
+
| `statusList` | 只读 Ref,按任务顺序保存 `{ status, data }`,`data` 是该步骤的输出 |
|
|
165
|
+
|
|
166
|
+
步骤状态为 `unStart`(未开始)、`start`(执行中)、`fulfilled`(成功)或 `rejected`(失败)。失败后后续步骤保持 `unStart`。
|
|
167
|
+
|
|
168
|
+
### 暂停与恢复
|
|
169
|
+
|
|
170
|
+
```ts
|
|
171
|
+
const runner = useOrderFun<number>([
|
|
172
|
+
async value => value + 1,
|
|
173
|
+
value => value * 2
|
|
174
|
+
]);
|
|
175
|
+
const started = runner.start(1);
|
|
176
|
+
const paused = await runner.suspend(); // [null, 2],第一步完成后暂停
|
|
177
|
+
await started; // 同样交付本段暂停结果
|
|
178
|
+
const finished = await runner.resume(); // [null, 4]
|
|
76
179
|
runner.dispose();
|
|
77
180
|
```
|
|
78
181
|
|
|
79
|
-
|
|
182
|
+
暂停不会中断当前任务。若当前步骤是最后一步,会直接完成流程并将 `isSuspend` 设为 `false`。无在途执行时,`suspend()` / `resume()` 返回现有结果或错误;执行中调用 `resume()` 会撤销暂停请求。纯同步流程通常在 `start()` 返回前全部完成,外部按钮无法在它执行期间插入暂停。
|
|
183
|
+
|
|
184
|
+
### 错误与执行替换
|
|
185
|
+
|
|
186
|
+
任务抛出异常、Promise 拒绝或拷贝失败时,执行返回 `[Error, undefined]`,并停止后续步骤。非 `Error` 异常会被转换为 `Error`,使用返回元组判断成功或失败。
|
|
187
|
+
|
|
188
|
+
再次 `start()`、更新列表或 `dispose()` 会作废旧执行。旧执行收到错误元组,其任务随后完成不会覆盖新状态。运行器不会强制终止任务中的请求或定时器;需要实际取消时,由任务自己管理 `AbortController` 或清理函数。
|
|
189
|
+
|
|
190
|
+
创建运行器时传入非法列表、给监听入口传入非 Ref,或非法调用 `update()`,会同步抛出异常。释放后的 `start()` 返回错误元组,`update()` 抛出异常;重新使用时创建新运行器。
|
|
191
|
+
|
|
192
|
+
空列表会返回输入:`await useOrderFun<number>([]).start(1)` 得到 `[null, 1]`。省略输入或任务无返回值时,成功结果也可以是 `undefined`。
|
|
193
|
+
|
|
194
|
+
## 配置与 TypeScript
|
|
195
|
+
|
|
196
|
+
| 选项 | 类型 | 默认值 | 行为 |
|
|
197
|
+
| --- | --- | --- | --- |
|
|
198
|
+
| `clone` | `boolean \| (<V>(value: V) => V)` | `true` | 深拷贝每一步输入及对外交付的结果;`false` 共享引用;函数提供自定义拷贝 |
|
|
199
|
+
| `retainResults` | `boolean` | `true` | 保留所有步骤输出;`false` 在新步骤成功后清除上一项的 `data`,仍保留步骤状态 |
|
|
200
|
+
|
|
201
|
+
```ts
|
|
202
|
+
const runner = useOrderFun<number>([
|
|
203
|
+
value => value + 1,
|
|
204
|
+
async value => value + 10
|
|
205
|
+
], { clone: false, retainResults: false });
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
关闭拷贝可以减少大对象的开销,但任务对共享对象的修改会影响原始输入。关闭结果保留后,最终结果仍可用;新步骤尚未成功时,上一成功步骤的数据仍会保留。
|
|
80
209
|
|
|
81
|
-
`
|
|
210
|
+
泛型 `<T, U = T>` 分别描述任务输入与输出,默认是 `unknown`。常见流程使用同一种数据结构,例如 `useOrderFun<number>(...)`。这不是逐步骤推导类型的异构管道:所有任务声明为 `(data: T) => U | PromiseLike<U>`,而运行时上一项的 `U` 会作为下一项输入。类型不同的多步流程应先设计兼容的公共数据结构。
|
|
82
211
|
|
|
83
|
-
`
|
|
212
|
+
导出的类型包括 `Status`、`StatusList`、`OrderResult`、`FunctionType`、`FunctionTypeSync`、`CallbackSync`、`OrderOptions`、`OrderRunner`、`ManualOrderRunner` 和 `SyncOrderRunner`。`FunctionTypeSync` 与 `FunctionType` 等价。
|
|
84
213
|
|
|
85
|
-
|
|
214
|
+
## 生命周期与本地开发
|
|
86
215
|
|
|
87
|
-
|
|
216
|
+
在 Vue 组件 `setup` 或 effect scope 内同步创建时,运行器随 scope 销毁自动释放。scope 外创建的运行器,在使用结束后调用 `dispose()`。
|
|
88
217
|
|
|
89
218
|
```sh
|
|
90
219
|
pnpm install --frozen-lockfile
|
|
91
|
-
pnpm
|
|
92
|
-
pnpm
|
|
93
|
-
pnpm
|
|
220
|
+
pnpm dev # 启动 Vue 示例
|
|
221
|
+
pnpm typecheck # 检查库、类型用例和 Vue 示例
|
|
222
|
+
pnpm build # 构建 ESM / CommonJS 产物并生成声明
|
|
223
|
+
pnpm test # 构建并执行回归测试
|
|
224
|
+
pnpm benchmark # 构建并测量耗时与保留堆内存
|
|
94
225
|
```
|
|
226
|
+
|
|
227
|
+
库实现位于 `index.ts`,发布声明为生成的 `index.d.ts`,Vue 示例位于 `src/App.vue`,测试位于 `tests/`。修改 API 后通过构建重新生成声明。
|
|
228
|
+
|
|
229
|
+
## License
|
|
230
|
+
|
|
231
|
+
[MIT](./LICENSE)
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! yann-useorderfun v1.
|
|
1
|
+
/*! yann-useorderfun v1.1.0 by Yann */
|
|
2
2
|
import { isRef as zt, shallowRef as Z, ref as ve, getCurrentScope as ye, onScopeDispose as $e, readonly as H, watch as _e, triggerRef as Q } from "vue";
|
|
3
3
|
function Te() {
|
|
4
4
|
this.__data__ = [], this.size = 0;
|
package/dist/index.umd.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
/*! yann-useorderfun v1.
|
|
1
|
+
/*! yann-useorderfun v1.1.0 by Yann */
|
|
2
2
|
(function(p,g){typeof exports=="object"&&typeof module<"u"?g(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],g):(p=typeof globalThis<"u"?globalThis:p||self,g(p.YannUseOrderFun={},p.Vue))})(this,function(p,g){"use strict";function lt(){this.__data__=[],this.size=0}function pe(e,t){return e===t||e!==e&&t!==t}function W(e,t){for(var r=e.length;r--;)if(pe(e[r][0],t))return r;return-1}var dt=Array.prototype,pt=dt.splice;function gt(e){var t=this.__data__,r=W(t,e);if(r<0)return!1;var a=t.length-1;return r==a?t.pop():pt.call(t,r,1),--this.size,!0}function ht(e){var t=this.__data__,r=W(t,e);return r<0?void 0:t[r][1]}function bt(e){return W(this.__data__,e)>-1}function yt(e,t){var r=this.__data__,a=W(r,e);return a<0?(++this.size,r.push([e,t])):r[a][1]=t,this}function j(e){var t=-1,r=e==null?0:e.length;for(this.clear();++t<r;){var a=e[t];this.set(a[0],a[1])}}j.prototype.clear=lt,j.prototype.delete=gt,j.prototype.get=ht,j.prototype.has=bt,j.prototype.set=yt;function vt(){this.__data__=new j,this.size=0}function $t(e){var t=this.__data__,r=t.delete(e);return this.size=t.size,r}function _t(e){return this.__data__.get(e)}function Tt(e){return this.__data__.has(e)}var mt=typeof global=="object"&&global&&global.Object===Object&&global;const ge=mt;var jt=typeof self=="object"&&self&&self.Object===Object&&self,wt=ge||jt||Function("return this")();const T=wt;var Ot=T.Symbol;const I=Ot;var he=Object.prototype,At=he.hasOwnProperty,St=he.toString,D=I?I.toStringTag:void 0;function Pt(e){var t=At.call(e,D),r=e[D];try{e[D]=void 0;var a=!0}catch{}var c=St.call(e);return a&&(t?e[D]=r:delete e[D]),c}var Et=Object.prototype,Ct=Et.toString;function It(e){return Ct.call(e)}var xt="[object Null]",Ft="[object Undefined]",be=I?I.toStringTag:void 0;function U(e){return e==null?e===void 0?Ft:xt:be&&be in Object(e)?Pt(e):It(e)}function B(e){var t=typeof e;return e!=null&&(t=="object"||t=="function")}var Mt="[object AsyncFunction]",Rt="[object Function]",Dt="[object GeneratorFunction]",Ut="[object Proxy]";function ye(e){if(!B(e))return!1;var t=U(e);return t==Rt||t==Dt||t==Mt||t==Ut}var Bt=T["__core-js_shared__"];const X=Bt;var ve=function(){var e=/[^.]+$/.exec(X&&X.keys&&X.keys.IE_PROTO||"");return e?"Symbol(src)_1."+e:""}();function Lt(e){return!!ve&&ve in e}var Gt=Function.prototype,Nt=Gt.toString;function A(e){if(e!=null){try{return Nt.call(e)}catch{}try{return e+""}catch{}}return""}var zt=/[\\^$.*+?()[\]{}|]/g,Kt=/^\[object .+?Constructor\]$/,Ht=Function.prototype,Vt=Object.prototype,Wt=Ht.toString,qt=Vt.hasOwnProperty,Yt=RegExp("^"+Wt.call(qt).replace(zt,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");function Jt(e){if(!B(e)||Lt(e))return!1;var t=ye(e)?Yt:Kt;return t.test(A(e))}function Xt(e,t){return e==null?void 0:e[t]}function S(e,t){var r=Xt(e,t);return Jt(r)?r:void 0}var Zt=S(T,"Map");const L=Zt;var Qt=S(Object,"create");const G=Qt;function kt(){this.__data__=G?G(null):{},this.size=0}function er(e){var t=this.has(e)&&delete this.__data__[e];return this.size-=t?1:0,t}var tr="__lodash_hash_undefined__",rr=Object.prototype,nr=rr.hasOwnProperty;function ar(e){var t=this.__data__;if(G){var r=t[e];return r===tr?void 0:r}return nr.call(t,e)?t[e]:void 0}var or=Object.prototype,ir=or.hasOwnProperty;function sr(e){var t=this.__data__;return G?t[e]!==void 0:ir.call(t,e)}var cr="__lodash_hash_undefined__";function ur(e,t){var r=this.__data__;return this.size+=this.has(e)?0:1,r[e]=G&&t===void 0?cr:t,this}function P(e){var t=-1,r=e==null?0:e.length;for(this.clear();++t<r;){var a=e[t];this.set(a[0],a[1])}}P.prototype.clear=kt,P.prototype.delete=er,P.prototype.get=ar,P.prototype.has=sr,P.prototype.set=ur;function fr(){this.size=0,this.__data__={hash:new P,map:new(L||j),string:new P}}function lr(e){var t=typeof e;return t=="string"||t=="number"||t=="symbol"||t=="boolean"?e!=="__proto__":e===null}function q(e,t){var r=e.__data__;return lr(t)?r[typeof t=="string"?"string":"hash"]:r.map}function dr(e){var t=q(this,e).delete(e);return this.size-=t?1:0,t}function pr(e){return q(this,e).get(e)}function gr(e){return q(this,e).has(e)}function hr(e,t){var r=q(this,e),a=r.size;return r.set(e,t),this.size+=r.size==a?0:1,this}function x(e){var t=-1,r=e==null?0:e.length;for(this.clear();++t<r;){var a=e[t];this.set(a[0],a[1])}}x.prototype.clear=fr,x.prototype.delete=dr,x.prototype.get=pr,x.prototype.has=gr,x.prototype.set=hr;var br=200;function yr(e,t){var r=this.__data__;if(r instanceof j){var a=r.__data__;if(!L||a.length<br-1)return a.push([e,t]),this.size=++r.size,this;r=this.__data__=new x(a)}return r.set(e,t),this.size=r.size,this}function F(e){var t=this.__data__=new j(e);this.size=t.size}F.prototype.clear=vt,F.prototype.delete=$t,F.prototype.get=_t,F.prototype.has=Tt,F.prototype.set=yr;function vr(e,t){for(var r=-1,a=e==null?0:e.length;++r<a&&t(e[r],r,e)!==!1;);return e}var $r=function(){try{var e=S(Object,"defineProperty");return e({},"",{}),e}catch{}}();const $e=$r;function _e(e,t,r){t=="__proto__"&&$e?$e(e,t,{configurable:!0,enumerable:!0,value:r,writable:!0}):e[t]=r}var _r=Object.prototype,Tr=_r.hasOwnProperty;function Te(e,t,r){var a=e[t];(!(Tr.call(e,t)&&pe(a,r))||r===void 0&&!(t in e))&&_e(e,t,r)}function Y(e,t,r,a){var c=!r;r||(r={});for(var s=-1,i=t.length;++s<i;){var h=t[s],v=a?a(r[h],e[h],h,r,e):void 0;v===void 0&&(v=e[h]),c?_e(r,h,v):Te(r,h,v)}return r}function mr(e,t){for(var r=-1,a=Array(e);++r<e;)a[r]=t(r);return a}function N(e){return e!=null&&typeof e=="object"}var jr="[object Arguments]";function me(e){return N(e)&&U(e)==jr}var je=Object.prototype,wr=je.hasOwnProperty,Or=je.propertyIsEnumerable,Ar=me(function(){return arguments}())?me:function(e){return N(e)&&wr.call(e,"callee")&&!Or.call(e,"callee")};const Sr=Ar;var Pr=Array.isArray;const Z=Pr;function Er(){return!1}var we=typeof p=="object"&&p&&!p.nodeType&&p,Oe=we&&typeof module=="object"&&module&&!module.nodeType&&module,Cr=Oe&&Oe.exports===we,Ae=Cr?T.Buffer:void 0,Ir=Ae?Ae.isBuffer:void 0,xr=Ir||Er;const Se=xr;var Fr=9007199254740991,Mr=/^(?:0|[1-9]\d*)$/;function Rr(e,t){var r=typeof e;return t=t??Fr,!!t&&(r=="number"||r!="symbol"&&Mr.test(e))&&e>-1&&e%1==0&&e<t}var Dr=9007199254740991;function Pe(e){return typeof e=="number"&&e>-1&&e%1==0&&e<=Dr}var Ur="[object Arguments]",Br="[object Array]",Lr="[object Boolean]",Gr="[object Date]",Nr="[object Error]",zr="[object Function]",Kr="[object Map]",Hr="[object Number]",Vr="[object Object]",Wr="[object RegExp]",qr="[object Set]",Yr="[object String]",Jr="[object WeakMap]",Xr="[object ArrayBuffer]",Zr="[object DataView]",Qr="[object Float32Array]",kr="[object Float64Array]",en="[object Int8Array]",tn="[object Int16Array]",rn="[object Int32Array]",nn="[object Uint8Array]",an="[object Uint8ClampedArray]",on="[object Uint16Array]",sn="[object Uint32Array]",f={};f[Qr]=f[kr]=f[en]=f[tn]=f[rn]=f[nn]=f[an]=f[on]=f[sn]=!0,f[Ur]=f[Br]=f[Xr]=f[Lr]=f[Zr]=f[Gr]=f[Nr]=f[zr]=f[Kr]=f[Hr]=f[Vr]=f[Wr]=f[qr]=f[Yr]=f[Jr]=!1;function cn(e){return N(e)&&Pe(e.length)&&!!f[U(e)]}function Q(e){return function(t){return e(t)}}var Ee=typeof p=="object"&&p&&!p.nodeType&&p,z=Ee&&typeof module=="object"&&module&&!module.nodeType&&module,un=z&&z.exports===Ee,k=un&&ge.process,fn=function(){try{var e=z&&z.require&&z.require("util").types;return e||k&&k.binding&&k.binding("util")}catch{}}();const M=fn;var Ce=M&&M.isTypedArray,ln=Ce?Q(Ce):cn;const dn=ln;var pn=Object.prototype,gn=pn.hasOwnProperty;function Ie(e,t){var r=Z(e),a=!r&&Sr(e),c=!r&&!a&&Se(e),s=!r&&!a&&!c&&dn(e),i=r||a||c||s,h=i?mr(e.length,String):[],v=h.length;for(var b in e)(t||gn.call(e,b))&&!(i&&(b=="length"||c&&(b=="offset"||b=="parent")||s&&(b=="buffer"||b=="byteLength"||b=="byteOffset")||Rr(b,v)))&&h.push(b);return h}var hn=Object.prototype;function ee(e){var t=e&&e.constructor,r=typeof t=="function"&&t.prototype||hn;return e===r}function xe(e,t){return function(r){return e(t(r))}}var bn=xe(Object.keys,Object);const yn=bn;var vn=Object.prototype,$n=vn.hasOwnProperty;function _n(e){if(!ee(e))return yn(e);var t=[];for(var r in Object(e))$n.call(e,r)&&r!="constructor"&&t.push(r);return t}function Fe(e){return e!=null&&Pe(e.length)&&!ye(e)}function te(e){return Fe(e)?Ie(e):_n(e)}function Tn(e,t){return e&&Y(t,te(t),e)}function mn(e){var t=[];if(e!=null)for(var r in Object(e))t.push(r);return t}var jn=Object.prototype,wn=jn.hasOwnProperty;function On(e){if(!B(e))return mn(e);var t=ee(e),r=[];for(var a in e)a=="constructor"&&(t||!wn.call(e,a))||r.push(a);return r}function re(e){return Fe(e)?Ie(e,!0):On(e)}function An(e,t){return e&&Y(t,re(t),e)}var Me=typeof p=="object"&&p&&!p.nodeType&&p,Re=Me&&typeof module=="object"&&module&&!module.nodeType&&module,Sn=Re&&Re.exports===Me,De=Sn?T.Buffer:void 0,Ue=De?De.allocUnsafe:void 0;function Pn(e,t){if(t)return e.slice();var r=e.length,a=Ue?Ue(r):new e.constructor(r);return e.copy(a),a}function En(e,t){var r=-1,a=e.length;for(t||(t=Array(a));++r<a;)t[r]=e[r];return t}function Cn(e,t){for(var r=-1,a=e==null?0:e.length,c=0,s=[];++r<a;){var i=e[r];t(i,r,e)&&(s[c++]=i)}return s}function Be(){return[]}var In=Object.prototype,xn=In.propertyIsEnumerable,Le=Object.getOwnPropertySymbols,Fn=Le?function(e){return e==null?[]:(e=Object(e),Cn(Le(e),function(t){return xn.call(e,t)}))}:Be;const ne=Fn;function Mn(e,t){return Y(e,ne(e),t)}function Ge(e,t){for(var r=-1,a=t.length,c=e.length;++r<a;)e[c+r]=t[r];return e}var Rn=xe(Object.getPrototypeOf,Object);const Ne=Rn;var Dn=Object.getOwnPropertySymbols,Un=Dn?function(e){for(var t=[];e;)Ge(t,ne(e)),e=Ne(e);return t}:Be;const ze=Un;function Bn(e,t){return Y(e,ze(e),t)}function Ke(e,t,r){var a=t(e);return Z(e)?a:Ge(a,r(e))}function Ln(e){return Ke(e,te,ne)}function Gn(e){return Ke(e,re,ze)}var Nn=S(T,"DataView");const ae=Nn;var zn=S(T,"Promise");const oe=zn;var Kn=S(T,"Set");const ie=Kn;var Hn=S(T,"WeakMap");const se=Hn;var He="[object Map]",Vn="[object Object]",Ve="[object Promise]",We="[object Set]",qe="[object WeakMap]",Ye="[object DataView]",Wn=A(ae),qn=A(L),Yn=A(oe),Jn=A(ie),Xn=A(se),E=U;(ae&&E(new ae(new ArrayBuffer(1)))!=Ye||L&&E(new L)!=He||oe&&E(oe.resolve())!=Ve||ie&&E(new ie)!=We||se&&E(new se)!=qe)&&(E=function(e){var t=U(e),r=t==Vn?e.constructor:void 0,a=r?A(r):"";if(a)switch(a){case Wn:return Ye;case qn:return He;case Yn:return Ve;case Jn:return We;case Xn:return qe}return t});const ce=E;var Zn=Object.prototype,Qn=Zn.hasOwnProperty;function kn(e){var t=e.length,r=new e.constructor(t);return t&&typeof e[0]=="string"&&Qn.call(e,"index")&&(r.index=e.index,r.input=e.input),r}var ea=T.Uint8Array;const Je=ea;function ue(e){var t=new e.constructor(e.byteLength);return new Je(t).set(new Je(e)),t}function ta(e,t){var r=t?ue(e.buffer):e.buffer;return new e.constructor(r,e.byteOffset,e.byteLength)}var ra=/\w*$/;function na(e){var t=new e.constructor(e.source,ra.exec(e));return t.lastIndex=e.lastIndex,t}var Xe=I?I.prototype:void 0,Ze=Xe?Xe.valueOf:void 0;function aa(e){return Ze?Object(Ze.call(e)):{}}function oa(e,t){var r=t?ue(e.buffer):e.buffer;return new e.constructor(r,e.byteOffset,e.length)}var ia="[object Boolean]",sa="[object Date]",ca="[object Map]",ua="[object Number]",fa="[object RegExp]",la="[object Set]",da="[object String]",pa="[object Symbol]",ga="[object ArrayBuffer]",ha="[object DataView]",ba="[object Float32Array]",ya="[object Float64Array]",va="[object Int8Array]",$a="[object Int16Array]",_a="[object Int32Array]",Ta="[object Uint8Array]",ma="[object Uint8ClampedArray]",ja="[object Uint16Array]",wa="[object Uint32Array]";function Oa(e,t,r){var a=e.constructor;switch(t){case ga:return ue(e);case ia:case sa:return new a(+e);case ha:return ta(e,r);case ba:case ya:case va:case $a:case _a:case Ta:case ma:case ja:case wa:return oa(e,r);case ca:return new a;case ua:case da:return new a(e);case fa:return na(e);case la:return new a;case pa:return aa(e)}}var Qe=Object.create,Aa=function(){function e(){}return function(t){if(!B(t))return{};if(Qe)return Qe(t);e.prototype=t;var r=new e;return e.prototype=void 0,r}}();const Sa=Aa;function Pa(e){return typeof e.constructor=="function"&&!ee(e)?Sa(Ne(e)):{}}var Ea="[object Map]";function Ca(e){return N(e)&&ce(e)==Ea}var ke=M&&M.isMap,Ia=ke?Q(ke):Ca;const xa=Ia;var Fa="[object Set]";function Ma(e){return N(e)&&ce(e)==Fa}var et=M&&M.isSet,Ra=et?Q(et):Ma;const Da=Ra;var Ua=1,Ba=2,La=4,tt="[object Arguments]",Ga="[object Array]",Na="[object Boolean]",za="[object Date]",Ka="[object Error]",rt="[object Function]",Ha="[object GeneratorFunction]",Va="[object Map]",Wa="[object Number]",nt="[object Object]",qa="[object RegExp]",Ya="[object Set]",Ja="[object String]",Xa="[object Symbol]",Za="[object WeakMap]",Qa="[object ArrayBuffer]",ka="[object DataView]",eo="[object Float32Array]",to="[object Float64Array]",ro="[object Int8Array]",no="[object Int16Array]",ao="[object Int32Array]",oo="[object Uint8Array]",io="[object Uint8ClampedArray]",so="[object Uint16Array]",co="[object Uint32Array]",u={};u[tt]=u[Ga]=u[Qa]=u[ka]=u[Na]=u[za]=u[eo]=u[to]=u[ro]=u[no]=u[ao]=u[Va]=u[Wa]=u[nt]=u[qa]=u[Ya]=u[Ja]=u[Xa]=u[oo]=u[io]=u[so]=u[co]=!0,u[Ka]=u[rt]=u[Za]=!1;function J(e,t,r,a,c,s){var i,h=t&Ua,v=t&Ba,b=t&La;if(r&&(i=c?r(e,a,c,s):r(e)),i!==void 0)return i;if(!B(e))return e;var m=Z(e);if(m){if(i=kn(e),!h)return En(e,i)}else{var $=ce(e),w=$==rt||$==Ha;if(Se(e))return Pn(e,h);if($==nt||$==tt||w&&!c){if(i=v||w?{}:Pa(e),!h)return v?Bn(e,An(i,e)):Mn(e,Tn(i,e))}else{if(!u[$])return c?e:{};i=Oa(e,$,h)}}s||(s=new F);var O=s.get(e);if(O)return O;s.set(e,i),Da(e)?e.forEach(function(y){i.add(J(y,t,r,y,e,s))}):xa(e)&&e.forEach(function(y,_){i.set(_,J(y,t,r,_,e,s))});var R=b?v?Gn:Ln:v?re:te,H=m?void 0:R(e);return vr(H||e,function(y,_){H&&(_=y,y=e[_]),Te(i,_,J(y,t,r,_,e,s))}),i}var uo=1,fo=4;function lo(e){return J(e,uo|fo)}const at=e=>e instanceof Error?e:new Error(String(e));function po(e){return e!==null&&(typeof e=="object"||typeof e=="function")&&typeof e.then=="function"}function K(e){if(!Array.isArray(e))throw new Error("Entry must be a list of functions")}function fe(e,t,r){K(e());const a=g.shallowRef(null),c=g.shallowRef(),s=g.ref(!1),i=g.shallowRef([]),h=r.clone??!0,v=r.retainResults??!0,b=n=>h===!1?n:typeof h=="function"?h(n):lo(n);let m,$=!1,w=0,O,R=[];function H(){if(a.value)return[a.value,void 0];try{return[null,b(c.value)]}catch(n){return[at(n),void 0]}}function y(n,o){if(n.settled)return;n.active=!1,n.settled=!0,n.outcome=o,n.resolve(o);const l=n.callback;n.callback=void 0,l==null||l(o)}function _(n){const o=++w,l=m;return m=void 0,l&&(l.cancelled=!0,l.tasks=[],l.data=void 0,y(l,[new Error(n),void 0])),o}function le(n){R=n.slice(),i.value=n.map(()=>({status:"unStart",data:void 0}))}le(e());function V(n,o){if(n.cancelled||n.settled)return;const l=at(o),d=i.value[n.index];d&&(d.status="rejected"),c.value=void 0,!n.cancelled&&(a.value=l,!n.cancelled&&(s.value=!1,!n.cancelled&&(g.triggerRef(i),!n.cancelled&&(m=void 0,n.tasks=[],n.data=void 0,y(n,[l,void 0])))))}function it(n){if(n.cancelled||n.settled)return;let o;try{o=[null,b(n.data)]}catch(l){V(n,l);return}c.value=n.data,!n.cancelled&&(a.value=null,!n.cancelled&&(n.index===n.tasks.length&&(m=void 0,n.tasks=[],n.data=void 0,s.value=!1),y(n,o)))}function st(n,o){n.cancelled||(!v&&n.index>0&&(i.value[n.index-1].data=void 0),i.value[n.index]={status:"fulfilled",data:o},n.data=o,n.index++,g.triggerRef(i))}function de(n){for(;!n.cancelled&&n.index<n.tasks.length;){const o=n.tasks[n.index];if(typeof o!="function"){V(n,new Error(`The parameter at index ${n.index} is not a function.`));return}if(i.value[n.index].status="start",g.triggerRef(i),n.cancelled)return;let l,d;try{l=o(b(n.data)),d=t||po(l)}catch(C){V(n,C);return}if(d){Promise.resolve(l).then(C=>{n.cancelled||(st(n,C),s.value||n.index===n.tasks.length?it(n):de(n))},C=>V(n,C)).catch(C=>V(n,C));return}if(st(n,l),s.value)break}it(n)}function ct(n,o){n.active=!0,n.settled=!1,n.outcome=void 0,n.callback=o,n.promise=new Promise(l=>{n.resolve=l})}function yo(n,o){K(e());const l=_("Execution superseded by start()"),d={tasks:e().slice(),index:0,data:n,active:!1,cancelled:!1,settled:!1,promise:Promise.resolve([null,void 0]),resolve:()=>{}};return ct(d,o),l!==w?(y(d,[new Error("Execution superseded by a newer operation"),void 0]),d):$?(y(d,[new Error("Runner has been disposed"),void 0]),d):(m=d,s.value=!1,d.cancelled||(a.value=null,d.cancelled)||(c.value=void 0,d.cancelled)||(le(d.tasks),de(d)),d)}function vo(n){const o=m;if(!(!o||$))return s.value=!1,o.cancelled||o.active||(ct(o,n),de(o)),o}function $o(){const n=m;if(!n)return Promise.resolve(H());const o=n.promise;return s.value=!0,o}function ut(n){if($)throw new Error("Runner has been disposed");K(n);const o=_("Execution invalidated by a list update");o===w&&(s.value=!1,o===w&&(c.value=void 0,o===w&&(a.value=null,o===w&&le(n))))}function _o(n){O=g.watch(()=>n.value.slice(),o=>{(o.length!==R.length||o.some((l,d)=>l!==R[d]))&&ut(o)})}function ft(){$||($=!0,O==null||O(),O=void 0,_("Runner has been disposed"),e=()=>[],R=[],s.value=!1,c.value=void 0,a.value=null,i.value=[])}return g.getCurrentScope()&&g.onScopeDispose(ft),{state:{error:g.readonly(a),result:g.readonly(c),statusList:g.readonly(i),isSuspend:g.readonly(s),suspend:$o,dispose:ft},start:yo,resume:vo,currentOutcome:H,reset:ut,observe:_o}}function ot(e){return{...e.state,start:t=>e.start(t).promise,resume:()=>{var t;return((t=e.resume())==null?void 0:t.promise)??Promise.resolve(e.currentOutcome())}}}function go(e,t={}){K(e);let r=e;const a=fe(()=>r,!0,t);return{...ot(a),dispose:()=>{a.state.dispose(),r=[]},update:c=>{K(c);const s=r;r=c;try{a.reset(c)}catch(i){throw r=s,i}}}}function ho(e,t={}){if(!g.isRef(e))throw new Error("Entry must be a ref");const r=fe(()=>e.value,!0,t);return r.observe(e),ot(r)}function bo(e,t={}){if(!g.isRef(e))throw new Error("Entry must be a ref");const r=fe(()=>e.value,!1,t);return r.observe(e),{...r.state,start:(a,c)=>r.start(a,c).outcome,resume:a=>{const c=r.resume(a);if(c)return c.outcome;const s=r.currentOutcome();return a==null||a(s),s}}}p.useOrderFun=go,p.useWatchOrderFun=ho,p.useWatchOrderFunSync=bo,Object.defineProperty(p,Symbol.toStringTag,{value:"Module"})});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "yann-useorderfun",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "yann-useOrderFun",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.umd.cjs",
|
|
@@ -39,7 +39,8 @@
|
|
|
39
39
|
},
|
|
40
40
|
"files": [
|
|
41
41
|
"dist",
|
|
42
|
-
"index.d.ts"
|
|
42
|
+
"index.d.ts",
|
|
43
|
+
"AI_USAGE.md"
|
|
43
44
|
],
|
|
44
45
|
"publishConfig": {
|
|
45
46
|
"registry": "https://registry.npmjs.org/"
|