ts-run-test 1.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/.idea/dictionaries/project.xml +7 -0
- package/.idea/inspectionProfiles/Project_Default.xml +22 -0
- package/.idea/jsLibraryMappings.xml +6 -0
- package/.idea/misc.xml +10 -0
- package/.idea/modules.xml +8 -0
- package/.idea/ts-run-test.iml +12 -0
- package/.idea/vcs.xml +6 -0
- package/.release-it.json +23 -0
- package/CHANGELOG.md +6 -0
- package/_test_/EventBus.ts +33 -0
- package/_test_/EventLoop.js +60 -0
- package/_test_/EventLoop.ts +85 -0
- package/_test_/IO.ts +62 -0
- package/_test_/ShengBei.html +84 -0
- package/_test_/__dirname.ts +17 -0
- package/_test_/aaaa.cjs +4 -0
- package/_test_/array.ts +26 -0
- package/_test_/async.ts +58 -0
- package/_test_/bfc.html +28 -0
- package/_test_/bin.ts +26 -0
- package/_test_/buffer.ts +21 -0
- package/_test_/build-icons/icon.ico +0 -0
- package/_test_/build-icons/icon_1024x1024.png +0 -0
- package/_test_/build-icons/icon_128x128.png +0 -0
- package/_test_/build-icons/icon_16x16.png +0 -0
- package/_test_/build-icons/icon_256x256.png +0 -0
- package/_test_/build-icons/icon_32x32.png +0 -0
- package/_test_/build-icons/icon_48x48.png +0 -0
- package/_test_/build-icons/icon_512x512.png +0 -0
- package/_test_/build-icons/icon_64x64.png +0 -0
- package/_test_/build-icons/splash/splash_100.png +0 -0
- package/_test_/build-icons/splash/splash_200.png +0 -0
- package/_test_/build-icons/tray/tray_black.png +0 -0
- package/_test_/build-icons/tray/tray_white.png +0 -0
- package/_test_/check.ts +65 -0
- package/_test_/closures.ts +12 -0
- package/_test_/copy.ts +25 -0
- package/_test_/debounce.ts +71 -0
- package/_test_/decorator.ts +37 -0
- package/_test_/deepCopy.ts +35 -0
- package/_test_/dom.ts +19 -0
- package/_test_/fetch.ts +45 -0
- package/_test_/get-template-version.ts +48 -0
- package/_test_/get.ts +52 -0
- package/_test_/gh.ts +19 -0
- package/_test_/gh_test.ts +93 -0
- package/_test_/icon.ico +0 -0
- package/_test_/icon.png +0 -0
- package/_test_/icon.ts +120 -0
- package/_test_/iconsize.ts +30 -0
- package/_test_/iterator.ts +112 -0
- package/_test_/link.ts +10 -0
- package/_test_/my/instanceof.ts +35 -0
- package/_test_/my/new.ts +22 -0
- package/_test_/new.ts +6 -0
- package/_test_/object.ts +2 -0
- package/_test_/observer.html +40 -0
- package/_test_/package.json +49 -0
- package/_test_/prototype.ts +27 -0
- package/_test_/proxy.ts +6 -0
- package/_test_/random.ts +29 -0
- package/_test_/react.ts +0 -0
- package/_test_/reg.ts +1 -0
- package/_test_/register.ts +61 -0
- package/_test_/release.config.cts +11 -0
- package/_test_/result.ts +37 -0
- package/_test_/task.ts +196 -0
- package/_test_/temp.md +8 -0
- package/_test_/tesp.ts +23 -0
- package/_test_/test.ts +59 -0
- package/_test_/typed.ts +55 -0
- package/_test_/worker.html +23 -0
- package/_test_/worker.js +4 -0
- package/_test_/worker.ts +5 -0
- package/_test_/xhr.ts +27 -0
- package/_test_//347/210/254/350/231/253.html +93 -0
- package/cache/00a25bc33880251d135060b213749534.jpg +0 -0
- package/cache/10_1730106978_t_NW.jpg +0 -0
- package/cache/11_1730104692_t_NW.jpg +0 -0
- package/cache/15_1730601804_t_NW.jpg +0 -0
- package/cache/17_1730434147_t_NW.jpg +0 -0
- package/cache/19ca581d7f9bf915d3cfb64299a9d5e0.jpg +0 -0
- package/cache/1ccf0b78ab293de8b2aa984773cf315b.jpg +0 -0
- package/cache/21a7518978f91278e75600b75390654e.jpg +0 -0
- package/cache/26ec1ad41910fa9f6236a98c8165a4f3.jpg +0 -0
- package/cache/2_1730114275_t_NW.jpg +0 -0
- package/cache/2a8542fbba235dda9d40c417a94083b5.jpg +0 -0
- package/cache/38_1730084632_t_NW.jpg +0 -0
- package/cache/45205cfc98b45aba7284124f730d37a4.jpg +0 -0
- package/cache/4_1730111766_t_NW.jpg +0 -0
- package/cache/544139e9bbc38597242c2a3d2ba9ede3.jpg +0 -0
- package/cache/60_1729079556_t_NW.jpg +0 -0
- package/cache/61_1729079251_t_NW.jpg +0 -0
- package/cache/65_1729078235_t_NW.jpg +0 -0
- package/cache/6b553b33cb2bc5423ca0a825a9596d7e.jpg +0 -0
- package/cache/74f7bbcd04af36cd224ebed548ba9f96.jpg +0 -0
- package/cache/762fa502959439d4ab1cc2f124c5fe31.jpg +0 -0
- package/cache/7_1730108771_t_NW.jpg +0 -0
- package/cache/82_1730202406_t_NW.jpg +0 -0
- package/cache/861641b72e0aa40abd4ad87c473100f6.jpg +0 -0
- package/cache/91_1730201579_t_NW.jpg +0 -0
- package/cache/95c1eceb38272ac57be2d1f14af3baa5.jpg +0 -0
- package/cache/99cae3416ed7d4ebce46003c291d5cc2.jpg +0 -0
- package/cache/9cf9878a0e979c6b9965ef415cfb43f1.jpg +0 -0
- package/cache/9e9db2fd267dc561244225efc1a872b3.jpg +0 -0
- package/cache/bc7bde2766d07dadd7fafd80854d6c5c.jpg +0 -0
- package/cache/c18d359f69c6b975604549f56237bfa8.jpg +0 -0
- package/cache/cf8143cd193619f57fc1ae06aed1ffec.jpg +0 -0
- package/cache/f3a5f2b40033da74d857c8dc0244948a.jpg +0 -0
- package/cache/f5d0336a68ec2b35eeb76706b02576bd.jpg +0 -0
- package/dist/index.d.ts +0 -0
- package/dist/index.js +2 -0
- package/dist/ip2region.cjs +11 -0
- package/dist/ip2region.d.cts +1 -0
- package/dist/ip2region.d.ts +1 -0
- package/dist/ip2region.js +20 -0
- package/dist/npm.d.ts +1 -0
- package/dist/npm.js +3 -0
- package/dist/pkg-filed.d.ts +1 -0
- package/dist/pkg-filed.js +18 -0
- package/dist/restore-wechat-images.d.ts +1 -0
- package/dist/restore-wechat-images.js +39 -0
- package/package.json +43 -0
- package/record.md +59 -0
- package/src/copyDir.ts +21 -0
- package/src/example.png +0 -0
- package/src/formatText.ts +83 -0
- package/src/index.ts +1 -0
- package/src/ip2region.cts +13 -0
- package/src/npm.ts +5 -0
- package/src/pkg-filed.ts +30 -0
- package/src/puppeteer.ts +51 -0
- package/src/restore-wechat-images.ts +50 -0
- package/src/try.ts +9 -0
- package/src/useCrawler.ts +31 -0
- package/tsconfig.json +20 -0
- package/tsdown.config.ts +15 -0
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
interface MyIterator {
|
|
2
|
+
data: number[];
|
|
3
|
+
|
|
4
|
+
[Symbol.iterator](): Iterator<number>;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
const myIterator: MyIterator = {
|
|
8
|
+
data: [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ],
|
|
9
|
+
[Symbol.iterator]() {
|
|
10
|
+
let idx = 0
|
|
11
|
+
const data = this.data
|
|
12
|
+
return {
|
|
13
|
+
next() {
|
|
14
|
+
if (idx < data.length) {
|
|
15
|
+
return { done: false, value: data[idx++] }
|
|
16
|
+
} else {
|
|
17
|
+
return { done: true, value: undefined }
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
for (const input of myIterator) {
|
|
25
|
+
console.log(input)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// ------------------------------------------
|
|
29
|
+
|
|
30
|
+
function* myGenerator(): Generator<number> {
|
|
31
|
+
yield 1
|
|
32
|
+
yield 2
|
|
33
|
+
yield 3
|
|
34
|
+
yield 4
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const gen: Generator<number> = myGenerator()
|
|
38
|
+
for (const number of gen) {
|
|
39
|
+
console.log(number)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// ------------------------------------------
|
|
43
|
+
|
|
44
|
+
type IteratorMode = 'entries' | 'keys' | 'values'
|
|
45
|
+
|
|
46
|
+
type ElementType<T, M extends IteratorMode> = M extends 'entries'
|
|
47
|
+
? [ keyof T, T[keyof T] ]
|
|
48
|
+
: M extends 'keys'
|
|
49
|
+
? keyof T
|
|
50
|
+
: T[keyof T];
|
|
51
|
+
|
|
52
|
+
type IterableReturn<T, M extends IteratorMode> = T & Iterable<ElementType<T, M>>;
|
|
53
|
+
|
|
54
|
+
const makeIterable = <T extends object, M extends IteratorMode>(obj: T, mode: M): IterableReturn<T, M> => {
|
|
55
|
+
const iterable: Iterable<ElementType<T, M>> =
|
|
56
|
+
mode === 'entries'
|
|
57
|
+
? Object.entries(obj)
|
|
58
|
+
: mode === 'keys'
|
|
59
|
+
? Object.keys(obj)
|
|
60
|
+
: Object.values(obj)
|
|
61
|
+
|
|
62
|
+
function* iteratorFactory(): Generator<ElementType<T, M>> {
|
|
63
|
+
for (const item of iterable) {
|
|
64
|
+
yield item
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return Object.assign(obj, {
|
|
69
|
+
[Symbol.iterator]: iteratorFactory,
|
|
70
|
+
})
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const makeIterable1 = <T extends object, M extends IteratorMode>(obj: T, mode: M): IterableReturn<T, M> => {
|
|
74
|
+
let temp: ElementType<T, M>[]
|
|
75
|
+
switch (mode) {
|
|
76
|
+
case 'entries':
|
|
77
|
+
temp = Object.entries(obj) as ElementType<T, M>[]
|
|
78
|
+
break
|
|
79
|
+
case 'keys':
|
|
80
|
+
temp = Object.keys(obj) as ElementType<T, M>[]
|
|
81
|
+
break
|
|
82
|
+
case 'values':
|
|
83
|
+
default:
|
|
84
|
+
temp = Object.values(obj) as ElementType<T, M>[]
|
|
85
|
+
break
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const iteratorFactory = (): Iterator<ElementType<T, M>> => {
|
|
89
|
+
let index = 0
|
|
90
|
+
return {
|
|
91
|
+
next(): IteratorResult<ElementType<T, M>> {
|
|
92
|
+
if (index < temp.length) {
|
|
93
|
+
return { done: false, value: temp[index++] }
|
|
94
|
+
} else {
|
|
95
|
+
return { done: true, value: undefined }
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return Object.assign(obj, {
|
|
102
|
+
[Symbol.iterator]: iteratorFactory,
|
|
103
|
+
})
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const make: IterableReturn<{ a: number; b: number; }, 'entries'> = makeIterable({ a: 1, b: 2 }, 'entries')
|
|
107
|
+
|
|
108
|
+
for (const [ key, val ] of make) {
|
|
109
|
+
console.log(key, val)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// ------------------------------------------
|
package/_test_/link.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export const pathToLink = (path: string, rootDir = '.', srcDir = '.'): string => path
|
|
2
|
+
.replace(new RegExp(`(^(\/?)${ rootDir }\/)+`, 'g'), '/')
|
|
3
|
+
.replace(new RegExp(`(^(\/?)${ srcDir }\/)+`, 'g'), '/')
|
|
4
|
+
.replace(/\.md$/i, '')
|
|
5
|
+
.replace(/\/index$/g, '/')
|
|
6
|
+
.replace(/\/+/g, '/')
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
console.log(pathToLink('docs/src/guide/index.md', 'docs', 'src'))
|
|
10
|
+
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// const instanceOf = <I, C extends object>(inst: I, Constructor: C) => {
|
|
2
|
+
// let proto = Object.getPrototypeOf(inst)
|
|
3
|
+
//
|
|
4
|
+
// while (proto) {
|
|
5
|
+
// if (proto === Constructor.prototype) {
|
|
6
|
+
// return true
|
|
7
|
+
// }
|
|
8
|
+
// proto = Object.getPrototypeOf(proto)
|
|
9
|
+
// }
|
|
10
|
+
//
|
|
11
|
+
// return false
|
|
12
|
+
// }
|
|
13
|
+
|
|
14
|
+
const instanceOf = <T extends object>(
|
|
15
|
+
inst: unknown,
|
|
16
|
+
Constructor: new (...args: any[]) => T,
|
|
17
|
+
): inst is T => {
|
|
18
|
+
let proto = Object.getPrototypeOf(inst)
|
|
19
|
+
|
|
20
|
+
while (proto) {
|
|
21
|
+
if (proto === Constructor.prototype) {
|
|
22
|
+
return true
|
|
23
|
+
}
|
|
24
|
+
proto = Object.getPrototypeOf(proto)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return false
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
console.log(instanceOf({}, Object))
|
|
32
|
+
|
|
33
|
+
console.log(instanceOf([], Object))
|
|
34
|
+
|
|
35
|
+
console.log(instanceOf({}, String))
|
package/_test_/my/new.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
function myNew<C extends new (...args: any[]) => any>(
|
|
2
|
+
constructor: C,
|
|
3
|
+
...args: ConstructorParameters<C>
|
|
4
|
+
): InstanceType<C> {
|
|
5
|
+
const obj = Object.create(constructor.prototype)
|
|
6
|
+
|
|
7
|
+
const result = constructor.apply(obj, args)
|
|
8
|
+
|
|
9
|
+
return (typeof result === 'object' && result !== null) ? result : obj
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
function myNew1(Func: Function, ...args: any[]) {
|
|
14
|
+
// 1. 创建一个空对象
|
|
15
|
+
const obj = Object.create(null)
|
|
16
|
+
// 2. 将构造函数原型对象指向新对象原型
|
|
17
|
+
obj.__proto__ = Func.prototype
|
|
18
|
+
// 3. 将构造函数的 this 指向新对象
|
|
19
|
+
const result = Func.apply(obj, args)
|
|
20
|
+
// 4. 根据返回值判断
|
|
21
|
+
return result instanceof Object ? result : obj
|
|
22
|
+
}
|
package/_test_/new.ts
ADDED
package/_test_/object.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<title>Observer</title>
|
|
6
|
+
<style>
|
|
7
|
+
* {
|
|
8
|
+
margin: 0;
|
|
9
|
+
padding: 0;
|
|
10
|
+
}
|
|
11
|
+
</style>
|
|
12
|
+
</head>
|
|
13
|
+
|
|
14
|
+
<body>
|
|
15
|
+
<div class="wrapper">
|
|
16
|
+
<div class="container">
|
|
17
|
+
<h1>Observer</h1>
|
|
18
|
+
<div>55</div>
|
|
19
|
+
</div>
|
|
20
|
+
<!-- /.container -->
|
|
21
|
+
</div>
|
|
22
|
+
</body>
|
|
23
|
+
|
|
24
|
+
<script >
|
|
25
|
+
const observer = new MutationObserver((mutations) => {
|
|
26
|
+
console.log(mutations)
|
|
27
|
+
})
|
|
28
|
+
observer.observe(document.body, {
|
|
29
|
+
childList: true
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
const resize = new ResizeObserver((entries) => {
|
|
34
|
+
console.log(entries)
|
|
35
|
+
})
|
|
36
|
+
resize.observe(document.body, {
|
|
37
|
+
box: 'border-box'
|
|
38
|
+
})
|
|
39
|
+
</script>
|
|
40
|
+
</html>
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "electron-app",
|
|
3
|
+
"productName": "electron-app",
|
|
4
|
+
"version": "0.0.0",
|
|
5
|
+
"description": "",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"main": ".vite/build/main.js",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"dev": "electron-forge start",
|
|
10
|
+
"build": "electron-forge make"
|
|
11
|
+
},
|
|
12
|
+
"devDependencies": {
|
|
13
|
+
"@electron-forge/cli": "^7.10.2",
|
|
14
|
+
"@electron-forge/maker-deb": "^7.10.2",
|
|
15
|
+
"@electron-forge/maker-dmg": "^7.10.2",
|
|
16
|
+
"@electron-forge/maker-msix": "^7.10.2",
|
|
17
|
+
"@electron-forge/maker-rpm": "^7.10.2",
|
|
18
|
+
"@electron-forge/maker-squirrel": "^7.10.2",
|
|
19
|
+
"@electron-forge/maker-zip": "^7.10.2",
|
|
20
|
+
"@electron-forge/plugin-auto-unpack-natives": "^7.10.2",
|
|
21
|
+
"@electron-forge/plugin-electronegativity": "^7.10.2",
|
|
22
|
+
"@electron-forge/plugin-fuses": "^7.10.2",
|
|
23
|
+
"@electron-forge/plugin-vite": "^7.10.2",
|
|
24
|
+
"@electron-forge/publisher-github": "^7.10.2",
|
|
25
|
+
"@electron-forge/shared-types": "^7.10.2",
|
|
26
|
+
"@electron/fuses": "^2.0.0",
|
|
27
|
+
"electron": "^39.2.4",
|
|
28
|
+
"typescript": "^5.9.3",
|
|
29
|
+
"vite": "7.2.6",
|
|
30
|
+
"vite-plugin-html": "^3.2.2"
|
|
31
|
+
},
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"@peiyanlu/electron-ipc": "^1.0.10",
|
|
34
|
+
"@peiyanlu/ts-utils": "^0.0.1"
|
|
35
|
+
},
|
|
36
|
+
"author": {
|
|
37
|
+
"name": "",
|
|
38
|
+
"email": ""
|
|
39
|
+
},
|
|
40
|
+
"os": [
|
|
41
|
+
"win32",
|
|
42
|
+
"darwin",
|
|
43
|
+
"linux"
|
|
44
|
+
],
|
|
45
|
+
"cpu": [
|
|
46
|
+
"x64",
|
|
47
|
+
"arm64"
|
|
48
|
+
]
|
|
49
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
class Person {
|
|
2
|
+
protected age: number = 18
|
|
3
|
+
|
|
4
|
+
constructor() {
|
|
5
|
+
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
clone() {
|
|
9
|
+
return cloneInstance(this)
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const cloneInstance = <T extends {}>(source: T): T => {
|
|
14
|
+
return Object.assign<T, T>(Object.create(Object.getPrototypeOf(source)), source)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
const person = new Person()
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
console.log(cloneInstance(person), 'constructor')
|
|
22
|
+
console.log(person.clone(), 'constructor')
|
|
23
|
+
|
|
24
|
+
const obj: Record<string, number> = { a: 1, b: 2 }
|
|
25
|
+
const clone = cloneInstance(obj)
|
|
26
|
+
clone.c = 122
|
|
27
|
+
console.log(obj, clone, 'object')
|
package/_test_/proxy.ts
ADDED
package/_test_/random.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// [min, max]
|
|
2
|
+
const random = (min: number, max: number) => {
|
|
3
|
+
return Math.floor(Math.random() * (max - min + 1)) + min
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
// [min, max)
|
|
7
|
+
const random1 = (min: number, max: number) => {
|
|
8
|
+
return Math.floor(Math.random() * (max - min)) + min
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// (min, max)
|
|
12
|
+
const random2 = (min: number, max: number) => {
|
|
13
|
+
return Math.ceil(Math.random() * (max - min - 1)) + min
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// (min, max]
|
|
17
|
+
const random3 = (min: number, max: number) => {
|
|
18
|
+
return Math.ceil(Math.random() * (max - min)) + min
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
for (let i = 0; i < 1000; i++) {
|
|
23
|
+
const r = random2(1, 5)
|
|
24
|
+
// console.log(r)
|
|
25
|
+
|
|
26
|
+
if ([ 1, 5 ].includes(r)) {
|
|
27
|
+
console.log(r)
|
|
28
|
+
}
|
|
29
|
+
}
|
package/_test_/react.ts
ADDED
|
File without changes
|
package/_test_/reg.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/src\/index.ts$/.test('')
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process'
|
|
2
|
+
import { existsSync } from 'node:fs'
|
|
3
|
+
import { resolve } from 'node:path'
|
|
4
|
+
import { pathToFileURL } from 'node:url'
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
export function isTSFile(file: string) {
|
|
8
|
+
return /\.(ts|mts|cts)$/.test(file)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
export async function loadConfig<T = unknown>(file: string): Promise<T> {
|
|
13
|
+
const url = pathToFileURL(file).href
|
|
14
|
+
console.log(url)
|
|
15
|
+
const mod = await import(url)
|
|
16
|
+
// 兼容 export default / module.exports
|
|
17
|
+
return mod.default ?? mod
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
export function findConfigFile(cwd = process.cwd()) {
|
|
22
|
+
const files = [
|
|
23
|
+
'release.config.ts',
|
|
24
|
+
'release.config.mts',
|
|
25
|
+
'release.config.cts',
|
|
26
|
+
'release.config.js',
|
|
27
|
+
'release.config.mjs',
|
|
28
|
+
'release.config.cjs',
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
for (const file of files) {
|
|
32
|
+
const absPath = resolve(cwd, file)
|
|
33
|
+
if (existsSync(absPath)) {
|
|
34
|
+
return absPath
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export async function resolveConfig<T = unknown>(cwd?: string): Promise<T | null> {
|
|
42
|
+
const configFile = findConfigFile(cwd)
|
|
43
|
+
|
|
44
|
+
if (!configFile) return null
|
|
45
|
+
|
|
46
|
+
return await loadConfig<T>(configFile)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
resolveConfig().then(res => {
|
|
50
|
+
console.log(res)
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
const spawnAsync = (...args: Parameters<typeof spawn>) => {
|
|
55
|
+
return new Promise((resolve) => {
|
|
56
|
+
spawn(...args).on('close', code => {
|
|
57
|
+
return 1 === code ? resolve(true) : resolve(false)
|
|
58
|
+
})
|
|
59
|
+
})
|
|
60
|
+
}
|
|
61
|
+
|
package/_test_/result.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
console.log([] == ![]) // true
|
|
2
|
+
|
|
3
|
+
console.log(![]) // fase
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
console.log(1 + 2 + '3')
|
|
7
|
+
console.log(1 + '2' + 3)
|
|
8
|
+
|
|
9
|
+
queueMicrotask(() => {
|
|
10
|
+
console.log('queueMicrotask')
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
setTimeout(()=>{
|
|
14
|
+
console.log('setTimeout')
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
console.log(8888)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
console.log(Object.create(null))
|
|
21
|
+
|
|
22
|
+
console.log(({}) + [])
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
let a = { n: 1 };
|
|
26
|
+
let b = a;
|
|
27
|
+
a.x = a = { n: 2 }
|
|
28
|
+
|
|
29
|
+
console.log(a)
|
|
30
|
+
console.log(b)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
console.log([ , , , ].length)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
console.log(0 in [ undefined ])
|
|
37
|
+
console.log(0 in [ , ])
|
package/_test_/task.ts
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
// ✅ 高级任务池 TaskPool,支持:
|
|
2
|
+
// - 并发控制
|
|
3
|
+
// - 优先级调度
|
|
4
|
+
// - 任务取消(AbortController)
|
|
5
|
+
// - DAG(依赖图)调度
|
|
6
|
+
// - UMD 支持(适配浏览器和 Node)
|
|
7
|
+
|
|
8
|
+
// ------- 类型定义 --------
|
|
9
|
+
type TaskFn<T> = (signal?: AbortSignal) => Promise<T>
|
|
10
|
+
|
|
11
|
+
type TaskState = 'pending' | 'running' | 'completed' | 'failed' | 'canceled'
|
|
12
|
+
|
|
13
|
+
interface TaskNode<T> {
|
|
14
|
+
id: string
|
|
15
|
+
run: TaskFn<T>
|
|
16
|
+
priority: number
|
|
17
|
+
dependencies: string[]
|
|
18
|
+
controller: AbortController
|
|
19
|
+
state: TaskState
|
|
20
|
+
retries: number
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
interface TaskPoolOptions {
|
|
24
|
+
concurrency?: number
|
|
25
|
+
maxRetries?: number
|
|
26
|
+
onProgress?: (done: number, total: number) => void
|
|
27
|
+
onError?: (id: string, error: any) => void
|
|
28
|
+
onComplete?: () => void
|
|
29
|
+
onStart?: (id: string) => void
|
|
30
|
+
onSuccess?: (id: string) => void
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// ------- TaskPool 实现 --------
|
|
34
|
+
export class TaskPool<T = any> {
|
|
35
|
+
private tasks: Map<string, TaskNode<T>> = new Map()
|
|
36
|
+
private running = 0
|
|
37
|
+
private done = 0
|
|
38
|
+
private readonly concurrency: number
|
|
39
|
+
private readonly maxRetries: number
|
|
40
|
+
private options: TaskPoolOptions
|
|
41
|
+
|
|
42
|
+
constructor(options: TaskPoolOptions = {}) {
|
|
43
|
+
this.concurrency = options.concurrency ?? 2
|
|
44
|
+
this.maxRetries = options.maxRetries ?? 0
|
|
45
|
+
this.options = options
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
addTask(
|
|
49
|
+
id: string,
|
|
50
|
+
taskFn: TaskFn<T>,
|
|
51
|
+
priority = 0,
|
|
52
|
+
dependencies: string[] = [],
|
|
53
|
+
) {
|
|
54
|
+
const controller = new AbortController()
|
|
55
|
+
const task: TaskNode<T> = {
|
|
56
|
+
id,
|
|
57
|
+
run: taskFn,
|
|
58
|
+
priority,
|
|
59
|
+
dependencies,
|
|
60
|
+
controller,
|
|
61
|
+
state: 'pending',
|
|
62
|
+
retries: 0,
|
|
63
|
+
}
|
|
64
|
+
this.tasks.set(id, task)
|
|
65
|
+
this.schedule()
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
cancelTask(id: string) {
|
|
69
|
+
const task = this.tasks.get(id)
|
|
70
|
+
if (task && task.state === 'pending') {
|
|
71
|
+
task.controller.abort()
|
|
72
|
+
task.state = 'canceled'
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
cancelAll() {
|
|
77
|
+
for (const task of this.tasks.values()) {
|
|
78
|
+
if (task.state === 'pending') {
|
|
79
|
+
task.controller.abort()
|
|
80
|
+
task.state = 'canceled'
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
private getRunnableTasks(): TaskNode<T>[] {
|
|
86
|
+
return [ ...this.tasks.values() ]
|
|
87
|
+
.filter(t =>
|
|
88
|
+
t.state === 'pending' &&
|
|
89
|
+
t.dependencies.every(dep => this.tasks.get(dep)?.state === 'completed'),
|
|
90
|
+
)
|
|
91
|
+
.sort((a, b) => b.priority - a.priority)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
private schedule() {
|
|
95
|
+
while (this.running < this.concurrency) {
|
|
96
|
+
const task = this.getRunnableTasks()[0]
|
|
97
|
+
if (!task) break
|
|
98
|
+
this.runTask(task).finally()
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
private async runTask(task: TaskNode<T>) {
|
|
103
|
+
task.state = 'running'
|
|
104
|
+
this.running++
|
|
105
|
+
this.options.onStart?.(task.id)
|
|
106
|
+
try {
|
|
107
|
+
await task.run(task.controller.signal)
|
|
108
|
+
task.state = 'completed'
|
|
109
|
+
this.options.onSuccess?.(task.id)
|
|
110
|
+
} catch (e) {
|
|
111
|
+
if (task.controller.signal.aborted) {
|
|
112
|
+
task.state = 'canceled'
|
|
113
|
+
} else if (task.retries < this.maxRetries) {
|
|
114
|
+
task.retries++
|
|
115
|
+
task.state = 'pending'
|
|
116
|
+
this.running--
|
|
117
|
+
return this.schedule()
|
|
118
|
+
} else {
|
|
119
|
+
task.state = 'failed'
|
|
120
|
+
this.options.onError?.(task.id, e)
|
|
121
|
+
}
|
|
122
|
+
} finally {
|
|
123
|
+
this.running--
|
|
124
|
+
|
|
125
|
+
if ([ 'completed', 'failed', 'canceled' ].includes(task.state)) {
|
|
126
|
+
this.done++
|
|
127
|
+
this.options.onProgress?.(this.done, this.tasks.size)
|
|
128
|
+
if (this.done === this.tasks.size) {
|
|
129
|
+
this.options.onComplete?.()
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
this.schedule()
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// ------- 浏览器/Node 兼容(UMD 支持) --------
|
|
138
|
+
// 可用 Rollup/Webpack 打包为 UMD 模块,或如下方式直接挂载:
|
|
139
|
+
|
|
140
|
+
// @ts-ignore
|
|
141
|
+
if (typeof window !== 'undefined') {
|
|
142
|
+
// @ts-ignore
|
|
143
|
+
window.TaskPool = TaskPool
|
|
144
|
+
}
|
|
145
|
+
// @ts-ignore
|
|
146
|
+
if (typeof global !== 'undefined') {
|
|
147
|
+
// @ts-ignore
|
|
148
|
+
global.TaskPool = TaskPool
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
const sleep = (ms: number, label: string, fail = false) => () =>
|
|
153
|
+
new Promise<string>((resolve, reject) => {
|
|
154
|
+
setTimeout(() => {
|
|
155
|
+
if (fail && Math.random() < 0.5) return reject(new Error(label + ' fail'))
|
|
156
|
+
resolve(label)
|
|
157
|
+
}, ms)
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
const delay = (ms: number) => new Promise(resolve => setTimeout(resolve, ms))
|
|
161
|
+
|
|
162
|
+
const pool = new TaskPool({
|
|
163
|
+
concurrency: 2,
|
|
164
|
+
maxRetries: 1,
|
|
165
|
+
onStart: id => console.log(`[START] ${ id }`),
|
|
166
|
+
onSuccess: id => console.log(`[SUCCESS] ${ id }`),
|
|
167
|
+
onError: (id, err) => console.warn(`[ERROR] ${ id }:`, err),
|
|
168
|
+
onProgress: (done, total) => console.log(`[PROGRESS] ${ done }/${ total }`),
|
|
169
|
+
onComplete: () => console.log(`[COMPLETE] all tasks finished`),
|
|
170
|
+
})
|
|
171
|
+
|
|
172
|
+
pool.addTask('A', async () => {
|
|
173
|
+
await delay(1000)
|
|
174
|
+
console.log('Task A finished')
|
|
175
|
+
}, 1)
|
|
176
|
+
|
|
177
|
+
pool.addTask('B', async () => {
|
|
178
|
+
await delay(500)
|
|
179
|
+
console.log('Task B finished')
|
|
180
|
+
}, 2)
|
|
181
|
+
|
|
182
|
+
pool.addTask('C', async () => {
|
|
183
|
+
await delay(300)
|
|
184
|
+
console.log('Task C finished')
|
|
185
|
+
}, 1, [ 'A', 'B' ])
|
|
186
|
+
|
|
187
|
+
pool.addTask('D', async signal => {
|
|
188
|
+
await delay(400)
|
|
189
|
+
if (signal?.aborted) throw new Error('Task D was aborted')
|
|
190
|
+
console.log('Task D finished')
|
|
191
|
+
}, 3)
|
|
192
|
+
|
|
193
|
+
// 模拟取消 D
|
|
194
|
+
setTimeout(() => {
|
|
195
|
+
// pool.cancelTask('D')
|
|
196
|
+
}, 100)
|
package/_test_/temp.md
ADDED
package/_test_/tesp.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync } from 'node:fs'
|
|
2
|
+
import { join } from 'node:path'
|
|
3
|
+
import { format } from 'node:util'
|
|
4
|
+
import semver from 'semver'
|
|
5
|
+
import minimist from 'minimist'
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
// const { name, type } = minimist(process.argv.slice(2))
|
|
9
|
+
//
|
|
10
|
+
// const templatePath = join('templates', name, 'template.json')
|
|
11
|
+
//
|
|
12
|
+
// const tpl = JSON.parse(readFileSync(templatePath, 'utf8'))
|
|
13
|
+
// tpl.version = semver.inc(tpl.version, type)!
|
|
14
|
+
//
|
|
15
|
+
// writeFileSync(templatePath, JSON.stringify(tpl, null, 2) + '\n')
|
|
16
|
+
//
|
|
17
|
+
// console.log(`✔ ${ name } bumped to ${ tpl.version }`)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
const context = Object.assign({}, { version: '*' });
|
|
21
|
+
const match = format('${version}', context);
|
|
22
|
+
|
|
23
|
+
console.log(match)
|