@enableai-job-runtime/core 0.0.5
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/core.cjs.js +899 -0
- package/dist/core.cjs.prod.js +899 -0
- package/dist/core.d.ts +768 -0
- package/dist/core.esm-bundler.mjs +870 -0
- package/index.js +7 -0
- package/package.json +38 -0
package/dist/core.d.ts
ADDED
|
@@ -0,0 +1,768 @@
|
|
|
1
|
+
import { Scheduler, SchedulerPriority } from '@enableai-job-runtime/scheduler';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 异步任务的执行状态。
|
|
5
|
+
*
|
|
6
|
+
* - Idle:尚未开始执行
|
|
7
|
+
* - Running:正在执行中
|
|
8
|
+
* - Finished:执行已完成(成功或失败)
|
|
9
|
+
*/
|
|
10
|
+
export declare enum AsyncStatus {
|
|
11
|
+
Idle = 0,
|
|
12
|
+
Running = 1,
|
|
13
|
+
Finished = 2
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* 同一个 key 的并发控制策略
|
|
18
|
+
*
|
|
19
|
+
* - allow 允许并发运行
|
|
20
|
+
* - skip 若同 key 有 Job 正在运行,则忽略新任务
|
|
21
|
+
* - replace 若同 key 有 Job 正在运行,则取消旧任务并启动新任务
|
|
22
|
+
* - queue 同 key Job 排队串行执行
|
|
23
|
+
*/
|
|
24
|
+
export type ConcurrencyPolicy = 'allow' | 'skip' | 'replace' | 'queue';
|
|
25
|
+
/**
|
|
26
|
+
* 默认并发策略:允许并发
|
|
27
|
+
*/
|
|
28
|
+
export declare const DEFAULT_CONCURRENCY_POLICY: ConcurrencyPolicy;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Job 内部使用的错误码。
|
|
32
|
+
*/
|
|
33
|
+
export declare enum JobErrorCode {
|
|
34
|
+
/**
|
|
35
|
+
* Hook 或 Job 内部用来表示“需要让出时间片”的信号。
|
|
36
|
+
* 这不是一个真正的错误,而是控制流的一部分。
|
|
37
|
+
*/
|
|
38
|
+
ShouldYield = "ShouldYield"
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Job 运行时错误。
|
|
42
|
+
*
|
|
43
|
+
* - 对于 ShouldYield 来说,这只是一个控制流信号;
|
|
44
|
+
* - 对于其他错误码,则代表真正的异常。
|
|
45
|
+
*/
|
|
46
|
+
export declare class JobError extends Error {
|
|
47
|
+
readonly code: JobErrorCode;
|
|
48
|
+
constructor(code: JobErrorCode, message?: string);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* 工具函数:判断是否为“让出时间片”的控制流错误。
|
|
52
|
+
*/
|
|
53
|
+
export declare function isShouldYieldError(error: unknown): error is JobError;
|
|
54
|
+
/**
|
|
55
|
+
* 创建一个 ShouldYield 错误实例,供 Hook 内部复用。
|
|
56
|
+
*/
|
|
57
|
+
export declare function createShouldYieldError(): JobError;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* HookSlot 类型体系
|
|
61
|
+
*
|
|
62
|
+
* 每个 Hook 对应一种 slot,用于保存内部状态。
|
|
63
|
+
* JobContext 内部维护一个 HookSlot[] 数组,
|
|
64
|
+
* Hook 调用顺序必须稳定,以保证 slot 索引稳定。
|
|
65
|
+
*/
|
|
66
|
+
/**
|
|
67
|
+
* Hook 类型标识
|
|
68
|
+
*/
|
|
69
|
+
export type HookKind = 'state' | 'effect' | 'async' | 'sleep' | 'loop';
|
|
70
|
+
/**
|
|
71
|
+
* Slot 基类
|
|
72
|
+
*/
|
|
73
|
+
export interface BaseSlot {
|
|
74
|
+
kind: HookKind;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* useJobState
|
|
78
|
+
*/
|
|
79
|
+
export interface StateSlot<T = any> extends BaseSlot {
|
|
80
|
+
kind: 'state';
|
|
81
|
+
value: T;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* useJobEffect
|
|
85
|
+
*/
|
|
86
|
+
export interface EffectSlot extends BaseSlot {
|
|
87
|
+
kind: 'effect';
|
|
88
|
+
cleanup?: () => void;
|
|
89
|
+
deps?: unknown[];
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* useJobAsync
|
|
93
|
+
*/
|
|
94
|
+
export interface AsyncSlot<T = any> extends BaseSlot {
|
|
95
|
+
kind: 'async';
|
|
96
|
+
/**
|
|
97
|
+
* 当前异步任务状态
|
|
98
|
+
*/
|
|
99
|
+
status: AsyncStatus;
|
|
100
|
+
/**
|
|
101
|
+
* 是否已经启动过(用于保证只执行一次)
|
|
102
|
+
*/
|
|
103
|
+
started: boolean;
|
|
104
|
+
/**
|
|
105
|
+
* 成功结果
|
|
106
|
+
*/
|
|
107
|
+
value?: T;
|
|
108
|
+
/**
|
|
109
|
+
* 错误结果
|
|
110
|
+
*/
|
|
111
|
+
error?: unknown;
|
|
112
|
+
/**
|
|
113
|
+
* 中止控制器,用于在 Job destroy 时 abort
|
|
114
|
+
*/
|
|
115
|
+
controller?: AbortController;
|
|
116
|
+
/**
|
|
117
|
+
* 用户提供的额外 cancel 函数
|
|
118
|
+
*/
|
|
119
|
+
cancel?: () => void;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* useJobSleep
|
|
123
|
+
*/
|
|
124
|
+
export interface SleepSlot extends BaseSlot {
|
|
125
|
+
kind: 'sleep';
|
|
126
|
+
/**
|
|
127
|
+
* 唤醒时间戳(performance.now / Date.now)
|
|
128
|
+
* 为 null 表示尚未设定
|
|
129
|
+
*/
|
|
130
|
+
until: number | null;
|
|
131
|
+
/**
|
|
132
|
+
* 当前 sleep 是否已经完成。
|
|
133
|
+
* 完成后,再次调用 useJobSleep 不会重新进入等待。
|
|
134
|
+
*/
|
|
135
|
+
done: boolean;
|
|
136
|
+
promise?: Promise<void>;
|
|
137
|
+
resolve?: () => void;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* useJobLoop
|
|
141
|
+
*/
|
|
142
|
+
export interface LoopSlot extends BaseSlot {
|
|
143
|
+
kind: 'loop';
|
|
144
|
+
index: number;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Job 所有 Slot 联合类型
|
|
148
|
+
*/
|
|
149
|
+
export type HookSlot = StateSlot | EffectSlot | AsyncSlot | SleepSlot | LoopSlot;
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Job 逻辑函数(JobComponent)
|
|
153
|
+
*
|
|
154
|
+
* - Props 为 Job 的参数类型;
|
|
155
|
+
* - 函数内部可以使用 Job Hooks;
|
|
156
|
+
* - 返回值当前未使用,预留为 void。
|
|
157
|
+
*/
|
|
158
|
+
export type JobComponent<Props = unknown> = (props: Props) => void;
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* JobContext
|
|
162
|
+
*
|
|
163
|
+
* 每个 Job 拥有独立的上下文,
|
|
164
|
+
* 内部包含所有 hook slot 数据。
|
|
165
|
+
*
|
|
166
|
+
* Job 每次执行一个“运行帧”时,JobContext.beginFrame() 会被调用,
|
|
167
|
+
* 用于重置 hookIndex,让 hooks 以固定顺序运行。
|
|
168
|
+
*/
|
|
169
|
+
export declare class JobContext {
|
|
170
|
+
/**
|
|
171
|
+
* HookSlot 数组,顺序即为 hook 调用顺序
|
|
172
|
+
*/
|
|
173
|
+
private slots;
|
|
174
|
+
/**
|
|
175
|
+
* 当前执行帧中的 slot 游标
|
|
176
|
+
*/
|
|
177
|
+
private hookIndex;
|
|
178
|
+
/**
|
|
179
|
+
* 获取当前帧的全部 slot
|
|
180
|
+
*/
|
|
181
|
+
getAllSlots(): readonly HookSlot[];
|
|
182
|
+
/**
|
|
183
|
+
* Job 在每次运行步骤开始时调用
|
|
184
|
+
* 重置 hookIndex,确保从 slot[0] 开始
|
|
185
|
+
*/
|
|
186
|
+
beginFrame(): void;
|
|
187
|
+
/**
|
|
188
|
+
* 获取或初始化一个 slot,
|
|
189
|
+
* 根据调用顺序递增 hookIndex。
|
|
190
|
+
*/
|
|
191
|
+
useSlot<T extends HookSlot>(kind: HookKind, init: () => T): T;
|
|
192
|
+
/**
|
|
193
|
+
* 在 Job 结束(Completed / Cancelled / Error)时调用
|
|
194
|
+
*
|
|
195
|
+
* - 执行所有 effect cleanup
|
|
196
|
+
* - 清理 async promise(可选增强功能)
|
|
197
|
+
* - 清理 sleep timers(可选增强功能)
|
|
198
|
+
*/
|
|
199
|
+
destroy(): void;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Job 生命周期状态
|
|
204
|
+
*/
|
|
205
|
+
export declare enum JobStatus {
|
|
206
|
+
/**
|
|
207
|
+
* 已创建但尚未开始执行
|
|
208
|
+
*/
|
|
209
|
+
Idle = "Idle",
|
|
210
|
+
/**
|
|
211
|
+
* 当前正在执行(本时间片内)
|
|
212
|
+
*/
|
|
213
|
+
Running = "Running",
|
|
214
|
+
/**
|
|
215
|
+
* 执行中主动让出时间片,等待下一次调度
|
|
216
|
+
*/
|
|
217
|
+
Yield = "Yield",
|
|
218
|
+
/**
|
|
219
|
+
* 被外部暂停,不会被调度执行
|
|
220
|
+
*/
|
|
221
|
+
Paused = "Paused",
|
|
222
|
+
/**
|
|
223
|
+
* 被外部取消或内部主动终止
|
|
224
|
+
*/
|
|
225
|
+
Cancelled = "Cancelled",
|
|
226
|
+
/**
|
|
227
|
+
* 正常执行结束
|
|
228
|
+
*/
|
|
229
|
+
Completed = "Completed",
|
|
230
|
+
/**
|
|
231
|
+
* 执行过程中发生未处理错误
|
|
232
|
+
*/
|
|
233
|
+
Error = "Error"
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
export interface JobEvents<Props = unknown> {
|
|
237
|
+
/**
|
|
238
|
+
* Job 从 Idle -> Running 的第一次启动
|
|
239
|
+
*/
|
|
240
|
+
start: (props: Props) => void;
|
|
241
|
+
/**
|
|
242
|
+
* Job 从 Paused -> Running 的恢复
|
|
243
|
+
*/
|
|
244
|
+
resume: (props: Props) => void;
|
|
245
|
+
/**
|
|
246
|
+
* Job 正常完成(进入 Completed)
|
|
247
|
+
*/
|
|
248
|
+
complete: (props: Props) => void;
|
|
249
|
+
/**
|
|
250
|
+
* Job 被取消(进入 Cancelled)
|
|
251
|
+
*/
|
|
252
|
+
cancel: (props: Props) => void;
|
|
253
|
+
/**
|
|
254
|
+
* Job 执行出错(进入 Error)
|
|
255
|
+
*/
|
|
256
|
+
error: (payload: {
|
|
257
|
+
error: unknown;
|
|
258
|
+
props: Props;
|
|
259
|
+
}) => void;
|
|
260
|
+
/**
|
|
261
|
+
* 任意状态变更
|
|
262
|
+
*/
|
|
263
|
+
statusChange: (status: JobStatus) => void;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* 状态迁移时的上下文参数
|
|
268
|
+
*/
|
|
269
|
+
interface TransitionContext<Props> {
|
|
270
|
+
props: Props;
|
|
271
|
+
error?: unknown;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Job 生命周期管理器
|
|
275
|
+
*/
|
|
276
|
+
export declare class JobLifecycle<Props = unknown> {
|
|
277
|
+
private _status;
|
|
278
|
+
private emitter;
|
|
279
|
+
get status(): JobStatus;
|
|
280
|
+
/**
|
|
281
|
+
* 判断一个 Job 是否处于终态
|
|
282
|
+
*
|
|
283
|
+
* - 终态:Cancelled / Completed / Error
|
|
284
|
+
*/
|
|
285
|
+
static isTerminalStatus(status: JobStatus): boolean;
|
|
286
|
+
/**
|
|
287
|
+
* 判断一个 Job 是否仍然处于活动状态
|
|
288
|
+
*
|
|
289
|
+
* - 活动状态:Idle / Running / Yield / Paused
|
|
290
|
+
* - 终态:Cancelled / Completed / Error
|
|
291
|
+
*/
|
|
292
|
+
static isActiveStatus(status: JobStatus): boolean;
|
|
293
|
+
/**
|
|
294
|
+
* 状态迁移 + 自动触发事件
|
|
295
|
+
*/
|
|
296
|
+
transitionTo(next: JobStatus, ctx: TransitionContext<Props>): void;
|
|
297
|
+
on<E extends keyof JobEvents<Props>>(event: E, listener: JobEvents<Props>[E]): () => void;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* 最小 Job 运行时宿主接口。
|
|
302
|
+
*
|
|
303
|
+
* - 真正的 Job 类会实现这个接口;
|
|
304
|
+
* - 这里不直接依赖具体 Job 类型,避免循环依赖。
|
|
305
|
+
* - 增加 shouldYield() 供 Hook 查询调度器是否需要让权。
|
|
306
|
+
*/
|
|
307
|
+
export interface JobRuntimeHost {
|
|
308
|
+
readonly context: JobContext;
|
|
309
|
+
shouldYield(): boolean;
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* 将一个 Job 压入当前执行栈。
|
|
313
|
+
* 由 Job 在每次执行步骤开始时调用。
|
|
314
|
+
*/
|
|
315
|
+
export declare function pushCurrentJob(job: JobRuntimeHost): void;
|
|
316
|
+
/**
|
|
317
|
+
* 将当前 Job 从执行栈弹出。
|
|
318
|
+
* 由 Job 在每次执行步骤结束(无论正常或异常)时调用。
|
|
319
|
+
*/
|
|
320
|
+
export declare function popCurrentJob(job: JobRuntimeHost): void;
|
|
321
|
+
/**
|
|
322
|
+
* 获取当前正在运行的 Job。
|
|
323
|
+
* 若在非 Job 执行上下文中调用,则抛出中文错误提示。
|
|
324
|
+
* 如果传入 `allowNoJob` 为 true,则在没有 Job 执行上下文时不抛出错误。
|
|
325
|
+
*/
|
|
326
|
+
export declare function getCurrentJob(allowNoJob?: boolean): JobRuntimeHost;
|
|
327
|
+
/**
|
|
328
|
+
* 直接获取当前 Job 的 JobContext。
|
|
329
|
+
* 是大部分 Hook 的主要入口。
|
|
330
|
+
*/
|
|
331
|
+
export declare function getCurrentJobContext(): JobContext;
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* Job 类
|
|
335
|
+
*/
|
|
336
|
+
export declare class Job<Props = unknown> implements JobRuntimeHost {
|
|
337
|
+
readonly id: string;
|
|
338
|
+
readonly key?: string;
|
|
339
|
+
readonly props: Props;
|
|
340
|
+
readonly parent?: Job<any>;
|
|
341
|
+
readonly children: Set<Job<any>>;
|
|
342
|
+
private _error;
|
|
343
|
+
get error(): unknown;
|
|
344
|
+
/**
|
|
345
|
+
* Job 生命周期管理器
|
|
346
|
+
*/
|
|
347
|
+
private lifecycle;
|
|
348
|
+
/**
|
|
349
|
+
* 监听 Job 生命周期事件
|
|
350
|
+
*/
|
|
351
|
+
on<E extends keyof JobEvents<Props>>(event: E, listener: JobEvents<Props>[E]): () => void;
|
|
352
|
+
/**
|
|
353
|
+
* 内部调度器
|
|
354
|
+
*/
|
|
355
|
+
private scheduler;
|
|
356
|
+
/**
|
|
357
|
+
* Job 执行优先级
|
|
358
|
+
*/
|
|
359
|
+
private priority;
|
|
360
|
+
/**
|
|
361
|
+
* Job 执行上下文(保存 hooks slot)
|
|
362
|
+
*/
|
|
363
|
+
readonly context: JobContext;
|
|
364
|
+
/**
|
|
365
|
+
* Job 对应的运行逻辑函数
|
|
366
|
+
*/
|
|
367
|
+
private component;
|
|
368
|
+
/**
|
|
369
|
+
* 当前调度任务句柄(用于取消)
|
|
370
|
+
*/
|
|
371
|
+
private currentTask;
|
|
372
|
+
/**
|
|
373
|
+
* 是否已destroy,防止重复销毁
|
|
374
|
+
*/
|
|
375
|
+
private destroyed;
|
|
376
|
+
constructor(component: JobComponent<Props>, options: JobOptions<Props>, schedulerFallback: Scheduler);
|
|
377
|
+
/**
|
|
378
|
+
* Job 当前状态(只读)
|
|
379
|
+
*/
|
|
380
|
+
get status(): JobStatus;
|
|
381
|
+
/**
|
|
382
|
+
* 提供给 Hook 使用的 shouldYield 查询接口
|
|
383
|
+
*/
|
|
384
|
+
shouldYield(): boolean;
|
|
385
|
+
/**
|
|
386
|
+
* 生成简单自增 ID
|
|
387
|
+
*/
|
|
388
|
+
private static _idCounter;
|
|
389
|
+
private static generateId;
|
|
390
|
+
/**
|
|
391
|
+
* 启动 Job
|
|
392
|
+
*/
|
|
393
|
+
start(): void;
|
|
394
|
+
/**
|
|
395
|
+
* 调度下一帧运行
|
|
396
|
+
*/
|
|
397
|
+
private scheduleNext;
|
|
398
|
+
/**
|
|
399
|
+
* 执行一帧 Job
|
|
400
|
+
*/
|
|
401
|
+
private runStep;
|
|
402
|
+
/**
|
|
403
|
+
* 正常完成 Job
|
|
404
|
+
*/
|
|
405
|
+
private finishSuccessfully;
|
|
406
|
+
/**
|
|
407
|
+
* 错误处理
|
|
408
|
+
*/
|
|
409
|
+
private handleError;
|
|
410
|
+
/**
|
|
411
|
+
* 释放上下文资源
|
|
412
|
+
*/
|
|
413
|
+
destroy(): void;
|
|
414
|
+
/**
|
|
415
|
+
* 暂停 Job:
|
|
416
|
+
* - 仅在 Running / Yield 状态下生效
|
|
417
|
+
* - 取消当前已调度但尚未执行的 task
|
|
418
|
+
* - 不销毁上下文,后续可以 resume() 继续执行
|
|
419
|
+
*/
|
|
420
|
+
pause(): void;
|
|
421
|
+
/**
|
|
422
|
+
* 恢复 Job:
|
|
423
|
+
* - 仅在 Paused 状态下生效
|
|
424
|
+
* - 重新调度下一帧执行
|
|
425
|
+
*/
|
|
426
|
+
resume(): void;
|
|
427
|
+
/**
|
|
428
|
+
* 取消 Job:
|
|
429
|
+
* - 将状态置为 Cancelled
|
|
430
|
+
* - 调用 destroy() 统一清理资源
|
|
431
|
+
*/
|
|
432
|
+
cancel(): void;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
* Job 实例配置。
|
|
437
|
+
*
|
|
438
|
+
* - id:实例唯一标识(可选,通常由 JobManager 自动注入);
|
|
439
|
+
* - key:逻辑标识,用于并发控制;
|
|
440
|
+
* - policy:并发策略(allow/skip/replace/queue);
|
|
441
|
+
* - priority:调度优先级;
|
|
442
|
+
* - scheduler:可选调度器,未提供时由 JobManager 注入默认值;
|
|
443
|
+
* - props:传给 JobComponent 的参数。
|
|
444
|
+
*/
|
|
445
|
+
export interface JobOptions<Props = unknown> {
|
|
446
|
+
/**
|
|
447
|
+
* 父 Job(可选)
|
|
448
|
+
*/
|
|
449
|
+
parent?: Job;
|
|
450
|
+
/**
|
|
451
|
+
* Job 实例唯一标识(内部使用,可选)
|
|
452
|
+
*/
|
|
453
|
+
id?: string;
|
|
454
|
+
/**
|
|
455
|
+
* Job 逻辑标识,用于并发控制(可选)
|
|
456
|
+
*/
|
|
457
|
+
key?: string;
|
|
458
|
+
/**
|
|
459
|
+
* 调度优先级(默认 SchedulerPriority.Normal)
|
|
460
|
+
*/
|
|
461
|
+
priority?: SchedulerPriority;
|
|
462
|
+
/**
|
|
463
|
+
* 该 Job 使用的调度器(可选)
|
|
464
|
+
* - 未指定时由 JobManager 提供默认调度器
|
|
465
|
+
*/
|
|
466
|
+
scheduler?: Scheduler;
|
|
467
|
+
/**
|
|
468
|
+
* JobComponent 的参数
|
|
469
|
+
*/
|
|
470
|
+
props: Props;
|
|
471
|
+
}
|
|
472
|
+
/**
|
|
473
|
+
* JobManager.run 的入参。
|
|
474
|
+
*
|
|
475
|
+
* 对外暴露时通常不包含 id(由 JobManager 自动生成)。
|
|
476
|
+
*/
|
|
477
|
+
export interface RunOptions<Props = unknown> {
|
|
478
|
+
/**
|
|
479
|
+
* 父 Job(可选)
|
|
480
|
+
*/
|
|
481
|
+
parent?: Job;
|
|
482
|
+
/**
|
|
483
|
+
* Job 的逻辑标识(可选)
|
|
484
|
+
*
|
|
485
|
+
* - 用于按 key 管理 / 取消 / 暂停 / 恢复 Job
|
|
486
|
+
* - 支持并发控制策略
|
|
487
|
+
*/
|
|
488
|
+
key?: string;
|
|
489
|
+
/**
|
|
490
|
+
* 透传给 JobComponent 的参数
|
|
491
|
+
*/
|
|
492
|
+
props: Props;
|
|
493
|
+
/**
|
|
494
|
+
* 并发策略(可选)
|
|
495
|
+
*/
|
|
496
|
+
policy?: ConcurrencyPolicy;
|
|
497
|
+
/**
|
|
498
|
+
* 最大并发数(仅对 allow 策略生效,可选)
|
|
499
|
+
*/
|
|
500
|
+
maxConcurrency?: number;
|
|
501
|
+
/**
|
|
502
|
+
* 调度优先级(可选)
|
|
503
|
+
*/
|
|
504
|
+
priority?: SchedulerPriority;
|
|
505
|
+
/**
|
|
506
|
+
* 调度器(可选)
|
|
507
|
+
*/
|
|
508
|
+
scheduler?: Scheduler;
|
|
509
|
+
/**
|
|
510
|
+
* 延迟时间(可选)
|
|
511
|
+
*/
|
|
512
|
+
delay?: number;
|
|
513
|
+
/**
|
|
514
|
+
* 间隔时间(可选)
|
|
515
|
+
*/
|
|
516
|
+
interval?: number;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
/**
|
|
520
|
+
* 异步任务的执行状态。
|
|
521
|
+
*
|
|
522
|
+
* 保留原来的枚举导出,方便外部使用。
|
|
523
|
+
*/
|
|
524
|
+
|
|
525
|
+
/**
|
|
526
|
+
* 执行异步任务并自动集成调度控制
|
|
527
|
+
*
|
|
528
|
+
* - 在首次执行时自动启动异步任务(只执行一次)
|
|
529
|
+
* - 状态管理:AsyncStatus(Idle -> Running -> Finished)
|
|
530
|
+
* - 当任务仍在进行中,会抛出 ShouldYield,以中断当前调度
|
|
531
|
+
* - 支持传入 AbortSignal(AbortController)以及 { promise, cancel } 形式
|
|
532
|
+
*
|
|
533
|
+
* 使用方式:
|
|
534
|
+
*
|
|
535
|
+
* const [result, error] = useAsync(signal => fetchData(signal))
|
|
536
|
+
*/
|
|
537
|
+
export declare const useJobAsync: <T>(fn: (signal: AbortSignal) => {
|
|
538
|
+
promise: Promise<T>;
|
|
539
|
+
cancel?: () => void;
|
|
540
|
+
} | Promise<T>) => [T | undefined, unknown | undefined];
|
|
541
|
+
|
|
542
|
+
/**
|
|
543
|
+
* useJobEffect
|
|
544
|
+
*
|
|
545
|
+
* - 语义上接近 React.useEffect
|
|
546
|
+
* - deps 为空数组 []:只在第一次执行时触发一次 effect
|
|
547
|
+
* - 省略 deps:每一帧都会重新执行 effect,并在执行前调用上一次 cleanup
|
|
548
|
+
* - deps 为数组:当依赖数组变化时,调用上一次 cleanup 并重新执行 effect
|
|
549
|
+
* - Job 完成 / 取消 / 出错销毁时,会调用最后一次 effect 的 cleanup
|
|
550
|
+
*/
|
|
551
|
+
export declare function useJobEffect(effect: () => void | (() => void), deps?: unknown[]): void;
|
|
552
|
+
|
|
553
|
+
/**
|
|
554
|
+
* useJobLoop
|
|
555
|
+
*
|
|
556
|
+
* 用于在 Job 内部分片执行长循环任务。
|
|
557
|
+
*
|
|
558
|
+
* - length:循环总长度(通常是数组长度)
|
|
559
|
+
* - body:每次迭代的处理函数,接收当前 index
|
|
560
|
+
*
|
|
561
|
+
* 运行机制:
|
|
562
|
+
* - 内部通过 LoopSlot 记录当前已经执行到的 index
|
|
563
|
+
* - 每次执行时从 slot.index 开始继续往后处理
|
|
564
|
+
* - 每次 body 执行后检查 job.shouldYield()
|
|
565
|
+
* - 若需要让权,则抛出 ShouldYield 错误,交由 Job 捕获并在下一帧继续
|
|
566
|
+
* - 当 index 走到 length 时,循环结束,slot.index 记录为 length
|
|
567
|
+
*/
|
|
568
|
+
export declare function useJobLoop(length: number, body: (index: number) => void): void;
|
|
569
|
+
|
|
570
|
+
/**
|
|
571
|
+
* useJobSleep
|
|
572
|
+
*
|
|
573
|
+
* 在 Job 内“睡眠”一段时间:
|
|
574
|
+
* - 第一次调用时记录唤醒时间 until = now + ms;
|
|
575
|
+
* - 在 now < until 期间,每次调用都会抛出 ShouldYield,让出时间片;
|
|
576
|
+
* - 当 now >= until 时,本次 sleep 结束,不再抛错,后续逻辑继续执行;
|
|
577
|
+
*
|
|
578
|
+
* ⚠️ 使用约束:
|
|
579
|
+
* - 必须在 Job 顶层调用(遵守 Hook 规则),不要在循环体或回调中动态增删;
|
|
580
|
+
* - 尤其不要在 useJobLoop 的 body 里调用 useJobSleep,这会让控制流难以推理。
|
|
581
|
+
*/
|
|
582
|
+
export declare function useJobSleep(ms: number): void;
|
|
583
|
+
|
|
584
|
+
/**
|
|
585
|
+
* useJobState
|
|
586
|
+
*
|
|
587
|
+
* - 与 React.useState 类似,用于在 Job 内部存储状态
|
|
588
|
+
* - 状态存储在当前 Job 的 JobContext 中,不会泄漏到其他 Job
|
|
589
|
+
* - 不会自动触发“重渲染”,Job 的推进依然由其他 Hook(loop/sleep/async)控制
|
|
590
|
+
*/
|
|
591
|
+
export declare function useJobState<T>(initial: T | (() => T)): [T, (next: T) => void];
|
|
592
|
+
|
|
593
|
+
/**
|
|
594
|
+
* 运行时断言工具。
|
|
595
|
+
*
|
|
596
|
+
* - condition 为 false 时抛出带中文信息的错误;
|
|
597
|
+
* - 主要用于内部开发态校验,不用于业务异常控制。
|
|
598
|
+
*/
|
|
599
|
+
export declare function invariant(condition: unknown, message: string): asserts condition;
|
|
600
|
+
|
|
601
|
+
/**
|
|
602
|
+
* Job 对外暴露的句柄类型
|
|
603
|
+
*
|
|
604
|
+
* - 业务侧通过 JobHandle 控制 Job
|
|
605
|
+
* - 不建议直接操作 Job 实例本身
|
|
606
|
+
*/
|
|
607
|
+
export interface JobHandle<Props = unknown> {
|
|
608
|
+
/**
|
|
609
|
+
* 逻辑标识(可选),通常对应 RunOptions.key
|
|
610
|
+
*/
|
|
611
|
+
readonly key?: string;
|
|
612
|
+
/**
|
|
613
|
+
* 当前 Job 状态(读取自底层 Job)
|
|
614
|
+
*/
|
|
615
|
+
readonly status: JobStatus;
|
|
616
|
+
/**
|
|
617
|
+
* 直接暴露 Job 实例(主要用于测试场景)
|
|
618
|
+
*
|
|
619
|
+
* - 业务代码建议只使用 handle 提供的方法,不直接操作 Job
|
|
620
|
+
*/
|
|
621
|
+
readonly job: Job<Props>;
|
|
622
|
+
/**
|
|
623
|
+
* 取消 Job
|
|
624
|
+
*/
|
|
625
|
+
cancel(cascade?: boolean): void;
|
|
626
|
+
/**
|
|
627
|
+
* 暂停 Job
|
|
628
|
+
*/
|
|
629
|
+
pause(): void;
|
|
630
|
+
/**
|
|
631
|
+
* 恢复 Job
|
|
632
|
+
*/
|
|
633
|
+
resume(): void;
|
|
634
|
+
/**
|
|
635
|
+
* 监听 Job 事件
|
|
636
|
+
*/
|
|
637
|
+
on<E extends keyof JobEvents<Props>>(event: E, listener: JobEvents<Props>[E]): () => void;
|
|
638
|
+
/**
|
|
639
|
+
* 将 Job 状态转换为 Promise:
|
|
640
|
+
*/
|
|
641
|
+
toPromise: () => Promise<void>;
|
|
642
|
+
}
|
|
643
|
+
/**
|
|
644
|
+
* JobHandle 的默认实现
|
|
645
|
+
*
|
|
646
|
+
* - 目前只是简单地代理到底层 Job
|
|
647
|
+
* - 后续如果需要可以在这里加更多 handle 级的逻辑(如埋点、缓存等)
|
|
648
|
+
*/
|
|
649
|
+
export declare class JobHandleImpl<Props = unknown> implements JobHandle<Props> {
|
|
650
|
+
readonly job: Job<Props>;
|
|
651
|
+
readonly key?: string | undefined;
|
|
652
|
+
private _promise?;
|
|
653
|
+
constructor(job: Job<Props>, key?: string | undefined);
|
|
654
|
+
get status(): JobStatus;
|
|
655
|
+
get error(): unknown;
|
|
656
|
+
cancel(cascade?: boolean): void;
|
|
657
|
+
pause(): void;
|
|
658
|
+
resume(): void;
|
|
659
|
+
toPromise(): Promise<void>;
|
|
660
|
+
on<E extends keyof JobEvents<Props>>(event: E, listener: JobEvents<Props>[E]): () => void;
|
|
661
|
+
}
|
|
662
|
+
/**
|
|
663
|
+
* 工具函数:从 Job 创建一个 JobHandle
|
|
664
|
+
*/
|
|
665
|
+
export declare function createJobHandle<Props>(job: Job<Props>, key?: string): JobHandle<Props>;
|
|
666
|
+
/**
|
|
667
|
+
* 工具函数:创建一个 Noop JobHandle
|
|
668
|
+
*/
|
|
669
|
+
export declare function createNoopHandle<Props = unknown>(key?: string): JobHandle<Props>;
|
|
670
|
+
|
|
671
|
+
/**
|
|
672
|
+
* JobManager:Job 的集合管理器
|
|
673
|
+
*
|
|
674
|
+
* - 负责创建并启动 Job
|
|
675
|
+
* - 通过 key 管理 Job 引用
|
|
676
|
+
* - 提供 cancel/pause/resume 能力
|
|
677
|
+
* - 带基础并发策略
|
|
678
|
+
*/
|
|
679
|
+
export declare class JobManager {
|
|
680
|
+
private readonly registry;
|
|
681
|
+
private concurrency;
|
|
682
|
+
constructor(scheduler: Scheduler);
|
|
683
|
+
/**
|
|
684
|
+
* 创建并启动一个新的 Job,并根据并发策略处理同 key Job,并返回 JobHandle。
|
|
685
|
+
*/
|
|
686
|
+
run<Props>(component: JobComponent<Props>, options: RunOptions<Props>): JobHandle<Props>;
|
|
687
|
+
/**
|
|
688
|
+
* 按 key 取消 Job:
|
|
689
|
+
* - 当前实现:取消该 key 下所有 Job(包含活动和终态,终态调用 cancel 为 no-op)
|
|
690
|
+
*/
|
|
691
|
+
cancel(key: string): void;
|
|
692
|
+
/**
|
|
693
|
+
* 按 key 暂停 Job:
|
|
694
|
+
* - 暂停该 key 下所有活跃 Job
|
|
695
|
+
*/
|
|
696
|
+
pause(key: string): void;
|
|
697
|
+
/**
|
|
698
|
+
* 按 key 恢复 Job:
|
|
699
|
+
* - 恢复该 key 下所有处于 Paused 状态的 Job
|
|
700
|
+
*/
|
|
701
|
+
resume(key: string): void;
|
|
702
|
+
/**
|
|
703
|
+
* 获取指定 key 对应的“最近的一个 Job”(主要用于测试/调试)
|
|
704
|
+
*/
|
|
705
|
+
getJob<Props = unknown>(key: string): Job<Props> | undefined;
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
/**
|
|
709
|
+
* JobKeyRegistry
|
|
710
|
+
*
|
|
711
|
+
* - 按 key 管理 Job 引用
|
|
712
|
+
* - 当前版本:每个 key 下可以存在多个 Job 实例(用于 allow 并发)
|
|
713
|
+
* - 后续扩展并发策略时,可以基于此实现 skip/replace/queue 等行为
|
|
714
|
+
*/
|
|
715
|
+
export declare class JobKeyRegistry {
|
|
716
|
+
private readonly jobsByKey;
|
|
717
|
+
/**
|
|
718
|
+
* 注册一个 Job 到指定 key 下
|
|
719
|
+
*/
|
|
720
|
+
register(key: string, job: Job<any>): void;
|
|
721
|
+
/**
|
|
722
|
+
* 获取指定 key 下的所有 Job(可能为空数组)
|
|
723
|
+
*/
|
|
724
|
+
getJobs<Props = unknown>(key: string): Job<Props>[];
|
|
725
|
+
/**
|
|
726
|
+
* 获取指定 key 下最近注册的一个 Job。
|
|
727
|
+
*
|
|
728
|
+
* - 用于 getJob 等场景,默认返回“最后一个创建”的 Job
|
|
729
|
+
*/
|
|
730
|
+
getLatest<Props = unknown>(key: string): Job<Props> | undefined;
|
|
731
|
+
/**
|
|
732
|
+
* 删除指定 key 下的某个 Job 引用
|
|
733
|
+
*/
|
|
734
|
+
deleteJob(key: string, job: Job<any>): void;
|
|
735
|
+
/**
|
|
736
|
+
* 删除整个 key(通常在全量 reset 或不再需要管理该 key 时使用)
|
|
737
|
+
*/
|
|
738
|
+
deleteKey(key: string): void;
|
|
739
|
+
/**
|
|
740
|
+
* 清空所有 key → Job 关联(通常在全量 reset 时使用)
|
|
741
|
+
*/
|
|
742
|
+
clear(): void;
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
/**
|
|
746
|
+
* 并发控制器:根据不同并发策略管理 Job 的创建和启动
|
|
747
|
+
*/
|
|
748
|
+
export declare class ConcurrencyController {
|
|
749
|
+
private defaultScheduler;
|
|
750
|
+
private onCreateJob;
|
|
751
|
+
private queueManager;
|
|
752
|
+
constructor(defaultScheduler: Scheduler, onCreateJob: <Props>(job: Job<Props>) => void);
|
|
753
|
+
/**
|
|
754
|
+
* 统一入口,按 policy 决定如何处理
|
|
755
|
+
*/
|
|
756
|
+
run<Props>(component: JobComponent<Props>, options: JobOptions<Props> & {
|
|
757
|
+
policy: ConcurrencyPolicy;
|
|
758
|
+
maxConcurrency?: number;
|
|
759
|
+
}, getExistingJobs: () => Job<Props>[]): Job<Props> | null;
|
|
760
|
+
private createJob;
|
|
761
|
+
private enqueueJob;
|
|
762
|
+
private runAllow;
|
|
763
|
+
private runSkip;
|
|
764
|
+
private runReplace;
|
|
765
|
+
private runQueue;
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
|