@zk-tech/bedrock 0.0.1 → 0.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/dist/async/index.cjs.map +1 -1
- package/dist/async/index.d.cts +2 -2
- package/dist/async/index.d.ts +2 -2
- package/dist/async/index.js.map +1 -1
- package/dist/error/index.cjs.map +1 -1
- package/dist/error/index.d.cts +19 -19
- package/dist/error/index.d.ts +19 -19
- package/dist/error/index.js.map +1 -1
- package/dist/{error-base-B4zaiJ5m.d.cts → error-base-DOFtBFla.d.cts} +8 -8
- package/dist/{error-base-B4zaiJ5m.d.ts → error-base-DOFtBFla.d.ts} +8 -8
- package/dist/promise/index.cjs.map +1 -1
- package/dist/promise/index.d.cts +4 -4
- package/dist/promise/index.d.ts +4 -4
- package/dist/promise/index.js.map +1 -1
- package/dist/worker/index.cjs.map +1 -1
- package/dist/worker/index.d.cts +2 -2
- package/dist/worker/index.d.ts +2 -2
- package/dist/worker/index.js.map +1 -1
- package/package.json +1 -2
- package/src/_internal/logger.ts +0 -59
- package/src/array/array.test.ts +0 -35
- package/src/array/array.ts +0 -25
- package/src/array/index.ts +0 -1
- package/src/assert/assert.test.ts +0 -86
- package/src/assert/assert.ts +0 -42
- package/src/assert/index.ts +0 -2
- package/src/async/barrier.test.ts +0 -90
- package/src/async/barrier.ts +0 -58
- package/src/async/cancellation.test.ts +0 -85
- package/src/async/cancellation.ts +0 -193
- package/src/async/index.ts +0 -18
- package/src/async/queue/queue.test.ts +0 -70
- package/src/async/queue/queue.ts +0 -56
- package/src/async/queue/task.test.ts +0 -155
- package/src/async/queue/task.ts +0 -67
- package/src/async/utils.test.ts +0 -28
- package/src/async/utils.ts +0 -8
- package/src/async/wait.ts +0 -9
- package/src/byte/format.test.ts +0 -64
- package/src/byte/format.ts +0 -44
- package/src/byte/index.ts +0 -2
- package/src/byte/node_modules/.vitest/results.json +0 -1
- package/src/byte/var.ts +0 -11
- package/src/cache/index.ts +0 -2
- package/src/cache/lru-with-timeout.test.ts +0 -88
- package/src/cache/lru-with-timeout.ts +0 -85
- package/src/cache/lru.test.ts +0 -56
- package/src/cache/lru.ts +0 -59
- package/src/context/context.test.ts +0 -17
- package/src/context/context.ts +0 -60
- package/src/context/index.ts +0 -8
- package/src/di/base.ts +0 -73
- package/src/di/container-service.test.ts +0 -179
- package/src/di/context.web.tsx +0 -41
- package/src/di/descriptor.ts +0 -31
- package/src/di/idle-value.test.ts +0 -73
- package/src/di/idle-value.ts +0 -63
- package/src/di/index.common.ts +0 -32
- package/src/di/index.ts +0 -2
- package/src/di/instantiation-service.interface.ts +0 -46
- package/src/di/instantiation-service.test.ts +0 -337
- package/src/di/instantiation-service.ts +0 -468
- package/src/di/lazy/foo.mock.ts +0 -28
- package/src/di/lazy/idle-load.ts +0 -39
- package/src/di/lazy/index.ts +0 -4
- package/src/di/lazy/lazy-service.test.ts +0 -65
- package/src/di/lazy/lazy-service.ts +0 -71
- package/src/di/lazy/type.ts +0 -5
- package/src/di/node_modules/.vitest/results.json +0 -1
- package/src/di/proxy-builder.test.ts +0 -45
- package/src/di/proxy-builder.ts +0 -38
- package/src/di/service-collection.test.ts +0 -27
- package/src/di/service-collection.ts +0 -46
- package/src/di/service-ownership-collection.test.ts +0 -39
- package/src/di/service-ownership-collection.ts +0 -38
- package/src/di/service-registry.test.ts +0 -66
- package/src/di/service-registry.ts +0 -99
- package/src/di/trace.ts +0 -85
- package/src/dispose/disposable-store.test.ts +0 -57
- package/src/dispose/disposable-store.ts +0 -80
- package/src/dispose/disposable-t.test.ts +0 -123
- package/src/dispose/disposable-t.ts +0 -238
- package/src/dispose/disposable-utils.test.ts +0 -15
- package/src/dispose/disposable-utils.ts +0 -28
- package/src/dispose/dispose-base.ts +0 -9
- package/src/dispose/index.ts +0 -34
- package/src/dispose/logger.test.ts +0 -65
- package/src/dispose/logger.ts +0 -39
- package/src/dispose/timer.test.ts +0 -30
- package/src/dispose/timer.ts +0 -16
- package/src/dispose/tracker.test.ts +0 -51
- package/src/dispose/tracker.ts +0 -105
- package/src/error/error-base.ts +0 -45
- package/src/error/error-code.ts +0 -39
- package/src/error/error-const.test.ts +0 -30
- package/src/error/error-const.ts +0 -16
- package/src/error/error-or.test.ts +0 -44
- package/src/error/error-or.ts +0 -2
- package/src/error/error-t.test.ts +0 -116
- package/src/error/error-t.ts +0 -100
- package/src/error/index.ts +0 -24
- package/src/error/node_modules/.vitest/results.json +0 -1
- package/src/event/disposable-linked-list.ts +0 -29
- package/src/event/emitter.test.ts +0 -191
- package/src/event/emitter.ts +0 -162
- package/src/event/error-handler.ts +0 -22
- package/src/event/index.ts +0 -34
- package/src/event/once.ts +0 -29
- package/src/event/phase-emitter.test.ts +0 -212
- package/src/event/phase-emitter.ts +0 -209
- package/src/event/shortcut-event-utils.ts +0 -33
- package/src/event/utils.ts +0 -6
- package/src/event/when.ts +0 -40
- package/src/function/debounce.test.ts +0 -274
- package/src/function/debounce.ts +0 -168
- package/src/function/index.ts +0 -2
- package/src/function/node_modules/.vitest/results.json +0 -1
- package/src/function/throttle.test.ts +0 -179
- package/src/function/throttle.ts +0 -26
- package/src/hash/hash-t.test.ts +0 -100
- package/src/hash/hash-t.ts +0 -51
- package/src/hash/index.ts +0 -3
- package/src/json/index.ts +0 -1
- package/src/json/node_modules/.vitest/results.json +0 -1
- package/src/json/parse.ts +0 -19
- package/src/launch/abstract-job.ts +0 -45
- package/src/launch/cost-recorder.ts +0 -22
- package/src/launch/index.ts +0 -2
- package/src/launch/job-scheduler.test.ts +0 -122
- package/src/launch/job-scheduler.ts +0 -118
- package/src/launch/node_modules/.vitest/deps/_metadata.json +0 -8
- package/src/launch/node_modules/.vitest/deps/package.json +0 -3
- package/src/launch/node_modules/.vitest/results.json +0 -1
- package/src/lock/README.md +0 -11
- package/src/lock/capability.test.ts +0 -110
- package/src/lock/capability.ts +0 -89
- package/src/lock/index.ts +0 -15
- package/src/lock/node_modules/.vitest/results.json +0 -1
- package/src/lock/semaphore.ts +0 -21
- package/src/lock/shared-mutex.test.ts +0 -537
- package/src/lock/shared-mutex.ts +0 -242
- package/src/lock/utils.test.ts +0 -165
- package/src/lock/utils.ts +0 -135
- package/src/lodash-es/index.ts +0 -1
- package/src/math/degree.ts +0 -16
- package/src/math/index.ts +0 -7
- package/src/math/math.test.ts +0 -40
- package/src/math/math.ts +0 -64
- package/src/math/node_modules/.vitest/results.json +0 -1
- package/src/math/vector.test.ts +0 -73
- package/src/math/vector.ts +0 -114
- package/src/network/client.interface.ts +0 -104
- package/src/network/client.web.ts +0 -24
- package/src/network/index.common.ts +0 -10
- package/src/network/index.ts +0 -2
- package/src/network/plugins/retry.ts +0 -98
- package/src/objects/deep-clone.test.ts +0 -40
- package/src/objects/deep-clone.ts +0 -13
- package/src/objects/deep-equal.test.ts +0 -86
- package/src/objects/deep-equal.ts +0 -60
- package/src/objects/index.ts +0 -4
- package/src/platform/index.ts +0 -64
- package/src/promise/index.ts +0 -16
- package/src/promise/promise.test.ts +0 -254
- package/src/promise/promise.ts +0 -212
- package/src/scheduler/callback-token.ts +0 -31
- package/src/scheduler/core/actuator-args.test.ts +0 -47
- package/src/scheduler/core/actuator.test.ts +0 -82
- package/src/scheduler/core/actuator.ts +0 -58
- package/src/scheduler/core/chunk-scheduler.test.ts +0 -54
- package/src/scheduler/core/chunk-scheduler.ts +0 -28
- package/src/scheduler/core/node_modules/.vitest/results.json +0 -1
- package/src/scheduler/core/scheduler.test.ts +0 -328
- package/src/scheduler/core/scheduler.ts +0 -172
- package/src/scheduler/core/task-queue.test.ts +0 -78
- package/src/scheduler/core/task-queue.ts +0 -44
- package/src/scheduler/core/task.test.ts +0 -34
- package/src/scheduler/core/task.ts +0 -52
- package/src/scheduler/core/utils.ts +0 -48
- package/src/scheduler/executor/abstract-executor.test.ts +0 -44
- package/src/scheduler/executor/abstract-executor.ts +0 -38
- package/src/scheduler/executor/executor.interface.ts +0 -39
- package/src/scheduler/executor/idle-callback-executor.test.ts +0 -70
- package/src/scheduler/executor/idle-callback-executor.ts +0 -98
- package/src/scheduler/executor/make-executor.ts +0 -18
- package/src/scheduler/executor/post-message-executor.test.ts +0 -66
- package/src/scheduler/executor/post-message-executor.ts +0 -52
- package/src/scheduler/index.ts +0 -15
- package/src/scheduler/lv-scheduler-callback.ts +0 -19
- package/src/scheduler/lv-scheduler-config.ts +0 -17
- package/src/scheduler/type.ts +0 -48
- package/src/sprintf/index.ts +0 -2
- package/src/sprintf/sprintf.test.ts +0 -95
- package/src/sprintf/sprintf.ts +0 -97
- package/src/structure/graph.test.ts +0 -181
- package/src/structure/graph.ts +0 -105
- package/src/structure/index.ts +0 -8
- package/src/structure/linked-list.test.ts +0 -74
- package/src/structure/linked-list.ts +0 -145
- package/src/structure/min-heap.test.ts +0 -71
- package/src/structure/min-heap.ts +0 -91
- package/src/type/REAME.md +0 -2
- package/src/type/distributive-omit.interface.ts +0 -4
- package/src/type/index.ts +0 -3
- package/src/type/object-key-paths.interface.ts +0 -40
- package/src/undo-redo-stack/README.md +0 -61
- package/src/undo-redo-stack/action-stack.test.ts +0 -330
- package/src/undo-redo-stack/action-stack.ts +0 -150
- package/src/undo-redo-stack/element.ts +0 -4
- package/src/undo-redo-stack/index.ts +0 -7
- package/src/undo-redo-stack/state-stack.test.ts +0 -118
- package/src/undo-redo-stack/state-stack.ts +0 -133
- package/src/uuid/index.ts +0 -7
- package/src/uuid/uuid.ts +0 -86
- package/src/worker/cors-worker.ts +0 -38
- package/src/worker/index.ts +0 -4
- package/src/worker/node_modules/.vitest/results.json +0 -1
- package/src/worker/promise-worker-main-thread.test.ts +0 -91
- package/src/worker/promise-worker-main-thread.ts +0 -76
- package/src/worker/promise-worker-worker-thread.ts +0 -64
- package/src/worker/promise-worker.interface.ts +0 -15
package/src/scheduler/index.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
// 任务调度优先级
|
|
2
|
-
export { PriorityLevel } from './type';
|
|
3
|
-
|
|
4
|
-
// 分片调度器
|
|
5
|
-
export type { IChunkScheduler, IOptions as ISchedulerCallbackOptions } from './type';
|
|
6
|
-
|
|
7
|
-
// 执行一个调度任务
|
|
8
|
-
export { lvSchedulerCallback } from './lv-scheduler-callback';
|
|
9
|
-
export type { ILvCallbackToken } from './lv-scheduler-callback';
|
|
10
|
-
|
|
11
|
-
// 设置调度器配置
|
|
12
|
-
export { lvSchedulerConfig } from './lv-scheduler-config';
|
|
13
|
-
|
|
14
|
-
// 重置调度器配置
|
|
15
|
-
export { lvSchedulerResetConfig } from './lv-scheduler-config';
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { type IDisposable } from '../dispose';
|
|
2
|
-
import { getScheduler } from './core/scheduler';
|
|
3
|
-
import type { IOptions, IScheduledCallback, PriorityLevel } from './type';
|
|
4
|
-
import { makeTask } from './core/utils';
|
|
5
|
-
import { CallbackToken } from './callback-token';
|
|
6
|
-
|
|
7
|
-
export interface ILvCallbackToken extends IDisposable {
|
|
8
|
-
/**
|
|
9
|
-
* 更新优先级
|
|
10
|
-
*/
|
|
11
|
-
updatePriorityLevel: (priorityLevel: PriorityLevel) => void;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export function lvSchedulerCallback(callback: IScheduledCallback, options: IOptions = {}): ILvCallbackToken {
|
|
15
|
-
const newTask = makeTask(callback, options);
|
|
16
|
-
getScheduler().addTask(newTask);
|
|
17
|
-
|
|
18
|
-
return new CallbackToken(newTask);
|
|
19
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { getScheduler } from './core/scheduler';
|
|
2
|
-
import type { IConfig } from './type';
|
|
3
|
-
|
|
4
|
-
export function lvSchedulerConfig(config: IConfig) {
|
|
5
|
-
if (config.fps !== undefined) {
|
|
6
|
-
getScheduler().executor.setFrameRate(config.fps);
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
if (config.enableInputPending !== undefined) {
|
|
10
|
-
getScheduler().setEnableInputPending(config.enableInputPending);
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export function lvSchedulerResetConfig() {
|
|
15
|
-
getScheduler().executor.resetFrameRate();
|
|
16
|
-
getScheduler().setEnableInputPending(true);
|
|
17
|
-
}
|
package/src/scheduler/type.ts
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
// 任务调度的优先级,从高到低
|
|
2
|
-
export enum PriorityLevel {
|
|
3
|
-
/** 立即执行任务的优先级 */
|
|
4
|
-
ImmediatePriority,
|
|
5
|
-
/** 用户阻塞的优先级 */
|
|
6
|
-
UserBlockingPriority,
|
|
7
|
-
/** 普通优先级 */
|
|
8
|
-
NormalPriority,
|
|
9
|
-
/** 低优先级 */
|
|
10
|
-
LowPriority,
|
|
11
|
-
/** 闲置优先级 */
|
|
12
|
-
IdlePriority,
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export interface IOptions {
|
|
16
|
-
delay?: number;
|
|
17
|
-
priorityLevel?: PriorityLevel;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export interface IConfig {
|
|
21
|
-
fps?: number;
|
|
22
|
-
enableInputPending?: boolean;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export interface IScheduledCallback {
|
|
26
|
-
/**
|
|
27
|
-
* @param chunkScheduler 分片调度器
|
|
28
|
-
* @param didUserCallbackTimeout 该callback执行时,是否已经超过了注册时设置的过期时间
|
|
29
|
-
* @param remainingTime 该callback执行时,当前调度loop中剩余的可用时间
|
|
30
|
-
*/
|
|
31
|
-
(chunkScheduler: IChunkScheduler, didUserCallbackTimeout: boolean, remainingTime: number): void;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* 分片调度器
|
|
36
|
-
* 支持将某个大的宏任务,拆成小的粒度执行
|
|
37
|
-
*/
|
|
38
|
-
export interface IChunkScheduler {
|
|
39
|
-
/**
|
|
40
|
-
* 在分片结束状态下,启动一个新的任务进入调度器
|
|
41
|
-
*/
|
|
42
|
-
execute: (callback: IScheduledCallback, options?: IOptions) => void;
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* 在分片结束状态下,延续当前任务(本质上是立即执行任务)
|
|
46
|
-
*/
|
|
47
|
-
continueExecute: (callback: IScheduledCallback) => void;
|
|
48
|
-
}
|
package/src/sprintf/index.ts
DELETED
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
import { sprintf } from './sprintf';
|
|
2
|
-
|
|
3
|
-
describe('sprintf', () => {
|
|
4
|
-
it('case1', () => {
|
|
5
|
-
expect(sprintf('lvweb yyds!!')).toBe('lvweb yyds!!');
|
|
6
|
-
});
|
|
7
|
-
|
|
8
|
-
// 没有传递参数,不进入匹配模式
|
|
9
|
-
it('case2', () => {
|
|
10
|
-
expect(sprintf('lv%% %dweb yyds!!')).toBe('lv%% %dweb yyds!!');
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
// 匹配数值
|
|
14
|
-
it('case3', () => {
|
|
15
|
-
expect(sprintf('lvweb %d yyds!!', 666)).toBe('lvweb 666 yyds!!');
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
// 匹配非数值
|
|
19
|
-
it('case4', () => {
|
|
20
|
-
expect(sprintf('lvweb %d yyds!!', 'not number')).toBe('lvweb NaN yyds!!');
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
// 匹配浮点数
|
|
24
|
-
it('case5', () => {
|
|
25
|
-
expect(sprintf('lvweb %d yyds!!', 1.888)).toBe('lvweb 1.888 yyds!!');
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
// 匹配字符串
|
|
29
|
-
it('case6', () => {
|
|
30
|
-
expect(sprintf('lvweb %s yyds!!', 'dddd')).toBe('lvweb dddd yyds!!');
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
// 匹配布尔
|
|
34
|
-
it('case7', () => {
|
|
35
|
-
expect(sprintf('lvweb %b yyds!!', true)).toBe('lvweb true yyds!!');
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
// 匹配布尔
|
|
39
|
-
it('case8', () => {
|
|
40
|
-
expect(sprintf('lvweb %b yyds!!', false)).toBe('lvweb false yyds!!');
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
// 转义%
|
|
44
|
-
it('case9', () => {
|
|
45
|
-
expect(sprintf('lvweb %% %s yyds!!', 'run')).toBe('lvweb % run yyds!!');
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
// 匹配对象
|
|
49
|
-
it('case10', () => {
|
|
50
|
-
expect(sprintf('lvweb %v yyds!!', { foo: 'bar' })).toBe('lvweb {"foo":"bar"} yyds!!');
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
it('case11', () => {
|
|
54
|
-
expect(sprintf('lvweb %v yyds!!', 233)).toBe('lvweb 233 yyds!!');
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
it('case12', () => {
|
|
58
|
-
expect(sprintf('lvweb %v yyds!!', false)).toBe('lvweb false yyds!!');
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
it('case13', () => {
|
|
62
|
-
expect(sprintf('lvweb %v yyds!!', 'dddd')).toBe('lvweb "dddd" yyds!!');
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
// 匹配对象,序列化错误
|
|
66
|
-
it('case14', () => {
|
|
67
|
-
const a: { [key: string]: any } = {};
|
|
68
|
-
a.a = a;
|
|
69
|
-
expect(sprintf('lvweb %v yyds!!', a)).toBe('[invalid formatted message]lvweb %v yyds!!');
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
// 匹配很多
|
|
73
|
-
it('case15', () => {
|
|
74
|
-
expect(sprintf('lvweb %d %b %s %v!!', 233, true, 'yyds', { foo: 'bar' })).toBe(
|
|
75
|
-
'lvweb 233 true yyds {"foo":"bar"}!!',
|
|
76
|
-
);
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
// 参数数量对不上
|
|
80
|
-
it('case16', () => {
|
|
81
|
-
expect(sprintf('lvweb %d %b %s %s %v!!', 233, true, 'yyds', { foo: 'bar' })).toBe(
|
|
82
|
-
'lvweb 233 true yyds [object Object] undefined!!',
|
|
83
|
-
);
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
// 参数数量多了,多余部分追加
|
|
87
|
-
it('case17', () => {
|
|
88
|
-
expect(sprintf('lvweb', 233, true, 'yyds', { foo: 'bar' })).toBe('lvweb 233 true yyds [object Object]');
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
// 参数数量多了,多余部分追加
|
|
92
|
-
it('case18', () => {
|
|
93
|
-
expect(sprintf('lvweb %d!!', 233, true, 'yyds')).toBe('lvweb 233!! true yyds');
|
|
94
|
-
});
|
|
95
|
-
});
|
package/src/sprintf/sprintf.ts
DELETED
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
import { lvAssertNotHere } from '../assert';
|
|
2
|
-
|
|
3
|
-
const regex = {
|
|
4
|
-
text: /^[^\x25]+/, // \x25 是 % 的十六进制表示
|
|
5
|
-
modulo: /^\x25\x25/, // %%转义
|
|
6
|
-
placeholder: /^\x25([vVbBdDsS])/,
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
type ParseResult = (string | { placeholder: string })[];
|
|
10
|
-
|
|
11
|
-
const cache = new Map<string, ParseResult>();
|
|
12
|
-
|
|
13
|
-
function parse(str: string) {
|
|
14
|
-
const result: ParseResult = [];
|
|
15
|
-
if (cache.has(str)) {
|
|
16
|
-
return cache.get(str)!;
|
|
17
|
-
}
|
|
18
|
-
let sub = str;
|
|
19
|
-
while (sub) {
|
|
20
|
-
let match = regex.text.exec(sub);
|
|
21
|
-
if (match) {
|
|
22
|
-
result.push(match[0]);
|
|
23
|
-
sub = sub.substring(match[0].length);
|
|
24
|
-
continue;
|
|
25
|
-
}
|
|
26
|
-
match = regex.modulo.exec(sub);
|
|
27
|
-
if (match) {
|
|
28
|
-
result.push('%');
|
|
29
|
-
sub = sub.substring(match[0].length);
|
|
30
|
-
continue;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// 一定匹配到了占位符
|
|
34
|
-
match = regex.placeholder.exec(sub);
|
|
35
|
-
if (match && match.length > 1) {
|
|
36
|
-
result.push({
|
|
37
|
-
placeholder: match[1],
|
|
38
|
-
});
|
|
39
|
-
sub = sub.substring(match[0].length);
|
|
40
|
-
} else {
|
|
41
|
-
lvAssertNotHere();
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
cache.set(str, result);
|
|
45
|
-
return result;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function replace(parseResult: ParseResult, ...args: any[]) {
|
|
49
|
-
let message = '';
|
|
50
|
-
let index = 0;
|
|
51
|
-
for (const t of parseResult) {
|
|
52
|
-
if (typeof t === 'string') {
|
|
53
|
-
message += t;
|
|
54
|
-
continue;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
if (args[index] === undefined) {
|
|
58
|
-
message += 'undefined';
|
|
59
|
-
continue;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
switch (t.placeholder.toLowerCase()) {
|
|
63
|
-
case 's':
|
|
64
|
-
message += String(args[index++]);
|
|
65
|
-
break;
|
|
66
|
-
case 'd':
|
|
67
|
-
message += Number(args[index++] as number);
|
|
68
|
-
break;
|
|
69
|
-
case 'b':
|
|
70
|
-
message += args[index++] as boolean;
|
|
71
|
-
break;
|
|
72
|
-
case 'v':
|
|
73
|
-
message += JSON.stringify(args[index++]);
|
|
74
|
-
break;
|
|
75
|
-
default:
|
|
76
|
-
lvAssertNotHere();
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
for (; index < args.length; index++) {
|
|
80
|
-
message += ` ${args[index]}`;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
return message;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
export function sprintf(message: string, ...args: any[]) {
|
|
87
|
-
if (!args.length) {
|
|
88
|
-
return message;
|
|
89
|
-
}
|
|
90
|
-
try {
|
|
91
|
-
const parseResult = parse(message);
|
|
92
|
-
const formatted = replace(parseResult, ...args);
|
|
93
|
-
return formatted;
|
|
94
|
-
} catch (e) {
|
|
95
|
-
return `[invalid formatted message]${message}`;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
/* eslint-disable max-lines-per-function */
|
|
2
|
-
import { Graph } from './graph';
|
|
3
|
-
|
|
4
|
-
describe('Graph', () => {
|
|
5
|
-
let graph: Graph<string, string>;
|
|
6
|
-
|
|
7
|
-
beforeEach(() => {
|
|
8
|
-
graph = new Graph<string, string>((v) => v);
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
it('should create an empty graph', () => {
|
|
12
|
-
expect(graph.isEmpty()).toBe(true);
|
|
13
|
-
expect(graph.toString()).toBe('');
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
it('should add nodes to the graph', () => {
|
|
17
|
-
const nodeA = graph.lookupOrInsertNode('A');
|
|
18
|
-
const nodeB = graph.lookupOrInsertNode('B');
|
|
19
|
-
const nodeC = graph.lookupOrInsertNode('C');
|
|
20
|
-
|
|
21
|
-
expect(graph.isEmpty()).toBe(false);
|
|
22
|
-
expect(graph.toString().replace(/\s/g, '')).toBe(
|
|
23
|
-
`
|
|
24
|
-
A
|
|
25
|
-
(-> incoming)[]
|
|
26
|
-
(outgoing ->)[]
|
|
27
|
-
|
|
28
|
-
B
|
|
29
|
-
(-> incoming)[]
|
|
30
|
-
(outgoing ->)[]
|
|
31
|
-
|
|
32
|
-
C
|
|
33
|
-
(-> incoming)[]
|
|
34
|
-
(outgoing ->)[]`.replace(/\s/g, ''),
|
|
35
|
-
);
|
|
36
|
-
|
|
37
|
-
expect(nodeA).toBe(graph.lookup('A'));
|
|
38
|
-
expect(nodeB).toBe(graph.lookup('B'));
|
|
39
|
-
expect(nodeC).toBe(graph.lookup('C'));
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
it('should add edges to the graph', () => {
|
|
43
|
-
const nodeA = graph.lookupOrInsertNode('A');
|
|
44
|
-
const nodeB = graph.lookupOrInsertNode('B');
|
|
45
|
-
const nodeC = graph.lookupOrInsertNode('C');
|
|
46
|
-
|
|
47
|
-
graph.insertEdge(nodeA.data, nodeB.data);
|
|
48
|
-
graph.insertEdge(nodeA.data, nodeC.data);
|
|
49
|
-
|
|
50
|
-
expect(graph.toString().replace(/\s/g, '')).toBe(
|
|
51
|
-
`
|
|
52
|
-
A
|
|
53
|
-
(-> incoming)[]
|
|
54
|
-
(outgoing ->)[B,C]
|
|
55
|
-
|
|
56
|
-
B
|
|
57
|
-
(-> incoming)[A]
|
|
58
|
-
(outgoing ->)[]
|
|
59
|
-
|
|
60
|
-
C
|
|
61
|
-
(-> incoming)[A]
|
|
62
|
-
(outgoing ->)[]`.replace(/\s/g, ''),
|
|
63
|
-
);
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
it('should remove nodes and edges from the graph', () => {
|
|
67
|
-
const nodeA = graph.lookupOrInsertNode('A');
|
|
68
|
-
const nodeB = graph.lookupOrInsertNode('B');
|
|
69
|
-
const nodeC = graph.lookupOrInsertNode('C');
|
|
70
|
-
const nodeD = graph.lookupOrInsertNode('D');
|
|
71
|
-
|
|
72
|
-
expect(graph.isEmpty()).toBe(false);
|
|
73
|
-
expect(graph.toString().replace(/\s/g, '')).toBe(
|
|
74
|
-
`
|
|
75
|
-
A
|
|
76
|
-
(-> incoming)[]
|
|
77
|
-
(outgoing ->)[]
|
|
78
|
-
|
|
79
|
-
B
|
|
80
|
-
(-> incoming)[]
|
|
81
|
-
(outgoing ->)[]
|
|
82
|
-
|
|
83
|
-
C
|
|
84
|
-
(-> incoming)[]
|
|
85
|
-
(outgoing ->)[]
|
|
86
|
-
|
|
87
|
-
D
|
|
88
|
-
(-> incoming)[]
|
|
89
|
-
(outgoing ->)[]`.replace(/\s/g, ''),
|
|
90
|
-
);
|
|
91
|
-
|
|
92
|
-
graph.insertEdge(nodeA.data, nodeB.data);
|
|
93
|
-
graph.insertEdge(nodeA.data, nodeC.data);
|
|
94
|
-
graph.insertEdge(nodeB.data, nodeD.data);
|
|
95
|
-
graph.insertEdge(nodeC.data, nodeD.data);
|
|
96
|
-
|
|
97
|
-
expect(graph.toString().replace(/\s/g, '')).toBe(
|
|
98
|
-
`
|
|
99
|
-
A
|
|
100
|
-
(-> incoming)[]
|
|
101
|
-
(outgoing ->)[B,C]
|
|
102
|
-
|
|
103
|
-
B
|
|
104
|
-
(-> incoming)[A]
|
|
105
|
-
(outgoing ->)[D]
|
|
106
|
-
|
|
107
|
-
C
|
|
108
|
-
(-> incoming)[A]
|
|
109
|
-
(outgoing ->)[D]
|
|
110
|
-
|
|
111
|
-
D
|
|
112
|
-
(-> incoming)[B, C]
|
|
113
|
-
(outgoing ->)[]`.replace(/\s/g, ''),
|
|
114
|
-
);
|
|
115
|
-
|
|
116
|
-
graph.removeNode(nodeC.data);
|
|
117
|
-
expect(graph.toString().replace(/\s/g, '')).toBe(
|
|
118
|
-
`
|
|
119
|
-
A
|
|
120
|
-
(-> incoming)[]
|
|
121
|
-
(outgoing ->)[B]
|
|
122
|
-
|
|
123
|
-
B
|
|
124
|
-
(-> incoming)[A]
|
|
125
|
-
(outgoing ->)[D]
|
|
126
|
-
|
|
127
|
-
D
|
|
128
|
-
(-> incoming)[B]
|
|
129
|
-
(outgoing ->)[]`.replace(/\s/g, ''),
|
|
130
|
-
);
|
|
131
|
-
|
|
132
|
-
graph.removeNode(nodeD.data);
|
|
133
|
-
expect(graph.toString().replace(/\s/g, '')).toBe(
|
|
134
|
-
`
|
|
135
|
-
A
|
|
136
|
-
(-> incoming)[]
|
|
137
|
-
(outgoing ->)[B]
|
|
138
|
-
|
|
139
|
-
B
|
|
140
|
-
(-> incoming)[A]
|
|
141
|
-
(outgoing ->)[]`.replace(/\s/g, ''),
|
|
142
|
-
);
|
|
143
|
-
|
|
144
|
-
graph.removeNode(nodeA.data);
|
|
145
|
-
expect(graph.toString().replace(/\s/g, '')).toBe(
|
|
146
|
-
`
|
|
147
|
-
B
|
|
148
|
-
(-> incoming)[]
|
|
149
|
-
(outgoing ->)[]`.replace(/\s/g, ''),
|
|
150
|
-
);
|
|
151
|
-
|
|
152
|
-
graph.removeNode(nodeB.data);
|
|
153
|
-
expect(graph.isEmpty()).toBe(true);
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
it('should find the leafs of a graph', () => {
|
|
157
|
-
const nodeA = graph.lookupOrInsertNode('A');
|
|
158
|
-
const nodeB = graph.lookupOrInsertNode('B');
|
|
159
|
-
const nodeC = graph.lookupOrInsertNode('C');
|
|
160
|
-
const nodeD = graph.lookupOrInsertNode('D');
|
|
161
|
-
|
|
162
|
-
graph.insertEdge(nodeA.data, nodeB.data);
|
|
163
|
-
graph.insertEdge(nodeA.data, nodeC.data);
|
|
164
|
-
graph.insertEdge(nodeB.data, nodeD.data);
|
|
165
|
-
graph.insertEdge(nodeC.data, nodeD.data);
|
|
166
|
-
|
|
167
|
-
expect(graph.leafs().length).toBe(1);
|
|
168
|
-
expect(graph.leafs()[0].data).toBe(nodeD.data);
|
|
169
|
-
|
|
170
|
-
graph.removeNode(nodeA.data);
|
|
171
|
-
|
|
172
|
-
expect(graph.leafs().length).toBe(1);
|
|
173
|
-
expect(graph.leafs()[0].data).toBe(nodeD.data);
|
|
174
|
-
|
|
175
|
-
graph.removeNode(nodeD.data);
|
|
176
|
-
|
|
177
|
-
expect(graph.leafs().length).toBe(2);
|
|
178
|
-
expect(graph.leafs()[0].data).toBe(nodeB.data);
|
|
179
|
-
expect(graph.leafs()[1].data).toBe(nodeC.data);
|
|
180
|
-
});
|
|
181
|
-
});
|
package/src/structure/graph.ts
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
class Node<K, T> {
|
|
2
|
-
readonly incoming = new Map<K, Node<K, T>>();
|
|
3
|
-
readonly outgoing = new Map<K, Node<K, T>>();
|
|
4
|
-
|
|
5
|
-
constructor(
|
|
6
|
-
public key: K,
|
|
7
|
-
public data: T,
|
|
8
|
-
) {}
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export class Graph<K, T> {
|
|
12
|
-
private readonly _nodes = new Map<K, Node<K, T>>();
|
|
13
|
-
|
|
14
|
-
constructor(private readonly _hashFn: (element: T) => K) {}
|
|
15
|
-
|
|
16
|
-
// 寻找所有的叶子节点
|
|
17
|
-
public leafs(): Node<K, T>[] {
|
|
18
|
-
const ret: Node<K, T>[] = [];
|
|
19
|
-
for (const node of this._nodes.values()) {
|
|
20
|
-
if (node.outgoing.size === 0) {
|
|
21
|
-
ret.push(node);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
return ret;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// 插入一条边
|
|
28
|
-
public insertEdge(from: T, to: T): void {
|
|
29
|
-
const fromNode = this.lookupOrInsertNode(from);
|
|
30
|
-
const toNode = this.lookupOrInsertNode(to);
|
|
31
|
-
|
|
32
|
-
fromNode.outgoing.set(toNode.key, toNode);
|
|
33
|
-
toNode.incoming.set(fromNode.key, fromNode);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// 移除某个节点
|
|
37
|
-
public removeNode(data: T): void {
|
|
38
|
-
const key = this._hashFn(data);
|
|
39
|
-
this._nodes.delete(key);
|
|
40
|
-
for (const node of this._nodes.values()) {
|
|
41
|
-
node.outgoing.delete(key);
|
|
42
|
-
node.incoming.delete(key);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// 查找某个节点
|
|
47
|
-
public lookup(data: T): Node<K, T> | undefined {
|
|
48
|
-
return this._nodes.get(this._hashFn(data));
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// 查找某个节点,不存在则插入
|
|
52
|
-
public lookupOrInsertNode(data: T): Node<K, T> {
|
|
53
|
-
const key = this._hashFn(data);
|
|
54
|
-
let node = this._nodes.get(key);
|
|
55
|
-
|
|
56
|
-
if (!node) {
|
|
57
|
-
node = new Node(key, data);
|
|
58
|
-
this._nodes.set(key, node);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
return node;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
public isEmpty(): boolean {
|
|
65
|
-
return this._nodes.size === 0;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
public toString(): string {
|
|
69
|
-
const data: string[] = [];
|
|
70
|
-
for (const [key, value] of this._nodes) {
|
|
71
|
-
data.push(
|
|
72
|
-
`${key}\n\t(-> incoming)[${[...value.incoming.keys()].join(', ')}]\n\t(outgoing ->)[${[
|
|
73
|
-
...value.outgoing.keys(),
|
|
74
|
-
].join(',')}]\n`,
|
|
75
|
-
);
|
|
76
|
-
}
|
|
77
|
-
return data.join('\n');
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
public findCycleSlow() {
|
|
81
|
-
for (const [id, node] of this._nodes) {
|
|
82
|
-
const seen = new Set<K>([id]);
|
|
83
|
-
const res = this._findCycle(node, seen);
|
|
84
|
-
if (res) {
|
|
85
|
-
return res;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
return undefined;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
private _findCycle(node: Node<K, T>, seen: Set<K>): string | undefined {
|
|
92
|
-
for (const [id, outgoing] of node.outgoing) {
|
|
93
|
-
if (seen.has(id)) {
|
|
94
|
-
return [...seen, id].join(' -> ');
|
|
95
|
-
}
|
|
96
|
-
seen.add(id);
|
|
97
|
-
const value = this._findCycle(outgoing, seen);
|
|
98
|
-
if (value) {
|
|
99
|
-
return value;
|
|
100
|
-
}
|
|
101
|
-
seen.delete(id);
|
|
102
|
-
}
|
|
103
|
-
return undefined;
|
|
104
|
-
}
|
|
105
|
-
}
|
package/src/structure/index.ts
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import { LinkedList } from './linked-list';
|
|
2
|
-
|
|
3
|
-
describe('LinkedList', () => {
|
|
4
|
-
let list: LinkedList<number>;
|
|
5
|
-
|
|
6
|
-
beforeEach(() => {
|
|
7
|
-
list = new LinkedList<number>();
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
it('isEmpty should return true for an empty list', () => {
|
|
11
|
-
expect(list.isEmpty()).toBe(true);
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
it('isEmpty should return false when the list contains elements', () => {
|
|
15
|
-
list.push(1);
|
|
16
|
-
|
|
17
|
-
expect(list.isEmpty()).toBe(false);
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
it('clear should remove all elements from the list', () => {
|
|
21
|
-
list.push(1);
|
|
22
|
-
list.push(2);
|
|
23
|
-
list.push(3);
|
|
24
|
-
list.clear();
|
|
25
|
-
|
|
26
|
-
expect(list.isEmpty()).toBe(true);
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
it('unshift should add elements to the front of the list', () => {
|
|
30
|
-
list.unshift(1);
|
|
31
|
-
list.unshift(2);
|
|
32
|
-
list.unshift(3);
|
|
33
|
-
|
|
34
|
-
expect(list.toArray()).toEqual([3, 2, 1]);
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
it('push should add elements to the end of the list', () => {
|
|
38
|
-
list.push(1);
|
|
39
|
-
list.push(2);
|
|
40
|
-
list.push(3);
|
|
41
|
-
|
|
42
|
-
expect(list.toArray()).toEqual([1, 2, 3]);
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
it('shift should remove and return the first element of the list', () => {
|
|
46
|
-
list.push(1);
|
|
47
|
-
list.push(2);
|
|
48
|
-
list.push(3);
|
|
49
|
-
|
|
50
|
-
const value = list.shift();
|
|
51
|
-
expect(value).toBe(1);
|
|
52
|
-
expect(list.toArray()).toEqual([2, 3]);
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it('shift should return undefined for an empty list', () => {
|
|
56
|
-
const value = list.shift();
|
|
57
|
-
expect(value).toBeNull();
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
it('pop should remove and return the last element of the list', () => {
|
|
61
|
-
list.push(1);
|
|
62
|
-
list.push(2);
|
|
63
|
-
list.push(3);
|
|
64
|
-
|
|
65
|
-
const value = list.pop();
|
|
66
|
-
expect(value).toBe(3);
|
|
67
|
-
expect(list.toArray()).toEqual([1, 2]);
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
it('pop should return undefined for an empty list', () => {
|
|
71
|
-
const value = list.pop();
|
|
72
|
-
expect(value).toBeNull();
|
|
73
|
-
});
|
|
74
|
-
});
|