esm.dev 2.0.3 → 2.0.4
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/package.json +3 -5
- package/src/commands/InitCommand.ts +1 -1
- package/src/lib/queue.ts +25 -19
- package/src/lib/server.ts +17 -7
- package/src/lib/watch.ts +7 -3
- package/src/lib/watchIgnoreList.ts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "esm.dev",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.4",
|
|
4
4
|
"description": "TypeScript library template",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -35,7 +35,6 @@
|
|
|
35
35
|
"@commitlint/config-conventional": "19.8.1",
|
|
36
36
|
"@commitlint/types": "19.8.1",
|
|
37
37
|
"@types/http-proxy": "^1.17.16",
|
|
38
|
-
"@types/lodash.debounce": "^4.0.9",
|
|
39
38
|
"@types/mustache": "^4.2.6",
|
|
40
39
|
"@types/node": "^22.15.27",
|
|
41
40
|
"@types/ramda": "^0.31.0",
|
|
@@ -44,7 +43,7 @@
|
|
|
44
43
|
"prettier": "3.6.2",
|
|
45
44
|
"rimraf": "6.0.1",
|
|
46
45
|
"semantic-release": "^24.2.4",
|
|
47
|
-
"typescript": "5.8.3",
|
|
46
|
+
"typescript": "~5.8.3",
|
|
48
47
|
"vitest": "^3.1.4"
|
|
49
48
|
},
|
|
50
49
|
"lint-staged": {
|
|
@@ -55,17 +54,16 @@
|
|
|
55
54
|
"dependencies": {
|
|
56
55
|
"clipanion": "^4.0.0-rc.4",
|
|
57
56
|
"clipanion-generator-command": "^1.3.1",
|
|
57
|
+
"es-toolkit": "^1.39.10",
|
|
58
58
|
"escape-string-regexp": "^5.0.0",
|
|
59
59
|
"glob": "^11.0.2",
|
|
60
60
|
"http-proxy": "^1.18.1",
|
|
61
61
|
"ignore": "^7.0.4",
|
|
62
|
-
"lodash.debounce": "^4.0.8",
|
|
63
62
|
"minimatch": "^10.0.1",
|
|
64
63
|
"minipass": "^7.1.2",
|
|
65
64
|
"mustache": "^4.2.0",
|
|
66
65
|
"npm": "^11.4.1",
|
|
67
66
|
"ramda": "^0.31.0",
|
|
68
|
-
"throat": "^6.0.2",
|
|
69
67
|
"tslib": "^2.8.1",
|
|
70
68
|
"typanion": "^3.14.0",
|
|
71
69
|
"zx": "^8.5.4"
|
|
@@ -25,7 +25,7 @@ export class InitCommand extends PackagePathSpecific(MustacheGeneratorCommand) {
|
|
|
25
25
|
|
|
26
26
|
readonly esmStoragePath = Option.String(
|
|
27
27
|
'-s,--esm-storage-path',
|
|
28
|
-
'./docker-storage/esm
|
|
28
|
+
'./docker-storage/esm',
|
|
29
29
|
{
|
|
30
30
|
description: "Path to ESM.sh's storage",
|
|
31
31
|
},
|
package/src/lib/queue.ts
CHANGED
|
@@ -1,18 +1,20 @@
|
|
|
1
|
-
import debounce from '
|
|
2
|
-
import throat from 'throat'
|
|
1
|
+
import { debounce, Mutex } from 'es-toolkit'
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
const mutex = new Mutex()
|
|
4
|
+
|
|
5
|
+
export async function queue<TResult>(
|
|
6
|
+
fn: () => Promise<TResult>,
|
|
6
7
|
signal?: AbortSignal,
|
|
7
8
|
): Promise<TResult> {
|
|
8
|
-
|
|
9
|
+
await mutex.acquire()
|
|
10
|
+
try {
|
|
9
11
|
signal?.throwIfAborted()
|
|
10
|
-
return fn(
|
|
11
|
-
}
|
|
12
|
+
return await fn()
|
|
13
|
+
} finally {
|
|
14
|
+
mutex.release()
|
|
15
|
+
}
|
|
12
16
|
}
|
|
13
17
|
|
|
14
|
-
const _queue = throat.default(1)
|
|
15
|
-
|
|
16
18
|
/**
|
|
17
19
|
* Just like debounce, but the first call will add a promise to the queue
|
|
18
20
|
* and that promise won't resolve until the debounced function is finally called.
|
|
@@ -30,16 +32,20 @@ export function queuedDebounce<Args extends unknown[], R>(
|
|
|
30
32
|
promiseWithResolvers?.reject(reason)
|
|
31
33
|
})
|
|
32
34
|
|
|
33
|
-
const debounced = debounce(
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
35
|
+
const debounced = debounce(
|
|
36
|
+
async (...args: Args) => {
|
|
37
|
+
try {
|
|
38
|
+
const result = await fn(...args)
|
|
39
|
+
promiseWithResolvers?.resolve(result)
|
|
40
|
+
} catch (error: any) {
|
|
41
|
+
promiseWithResolvers?.reject(error)
|
|
42
|
+
} finally {
|
|
43
|
+
promiseWithResolvers = undefined
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
delay,
|
|
47
|
+
{ signal },
|
|
48
|
+
)
|
|
43
49
|
|
|
44
50
|
return (...args: Args) => {
|
|
45
51
|
const promise = start()
|
package/src/lib/server.ts
CHANGED
|
@@ -2,8 +2,12 @@ import { queue } from './queue.ts'
|
|
|
2
2
|
import { createServer } from 'node:http'
|
|
3
3
|
import httpProxy from 'http-proxy'
|
|
4
4
|
|
|
5
|
-
export function serve(
|
|
5
|
+
export async function serve(
|
|
6
|
+
port: number,
|
|
7
|
+
esmOrigin: string,
|
|
8
|
+
): Promise<() => Promise<void>> {
|
|
6
9
|
const proxy = httpProxy.createProxyServer()
|
|
10
|
+
const { promise, resolve } = Promise.withResolvers<void>()
|
|
7
11
|
|
|
8
12
|
const server = createServer((req, res) => {
|
|
9
13
|
queue(
|
|
@@ -13,7 +17,7 @@ export function serve(port: number, esmOrigin: string): () => void {
|
|
|
13
17
|
req.on('error', reject)
|
|
14
18
|
res.on('error', reject)
|
|
15
19
|
res.on('close', resolve)
|
|
16
|
-
proxy.web(req, res, { target: esmOrigin })
|
|
20
|
+
proxy.web(req, res, { followRedirects: true, target: esmOrigin })
|
|
17
21
|
}),
|
|
18
22
|
).catch((error) => {
|
|
19
23
|
res.statusCode = 500
|
|
@@ -23,11 +27,17 @@ export function serve(port: number, esmOrigin: string): () => void {
|
|
|
23
27
|
})
|
|
24
28
|
}).listen(port, () => {
|
|
25
29
|
console.info('ESM proxy server listining on', server.address())
|
|
30
|
+
resolve()
|
|
26
31
|
})
|
|
27
32
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
+
await promise
|
|
34
|
+
|
|
35
|
+
return () =>
|
|
36
|
+
new Promise<void>((resolve, reject) => {
|
|
37
|
+
console.info('closing the server')
|
|
38
|
+
server.close((error) => {
|
|
39
|
+
if (error) reject(error)
|
|
40
|
+
else resolve()
|
|
41
|
+
})
|
|
42
|
+
})
|
|
33
43
|
}
|
package/src/lib/watch.ts
CHANGED
|
@@ -62,11 +62,15 @@ async function modernWatch(
|
|
|
62
62
|
const ignorer = await getWatchIgnorer(dirname)
|
|
63
63
|
const watcher = fsWatch(
|
|
64
64
|
dirname,
|
|
65
|
-
{ recursive: true
|
|
65
|
+
{ recursive: true, signal: abortController.signal },
|
|
66
66
|
(_, filename) =>
|
|
67
67
|
(filename && ignorer.ignores(filename)) ||
|
|
68
68
|
republish(filename ?? '').catch((error) => {
|
|
69
|
-
if (
|
|
69
|
+
if (
|
|
70
|
+
!(error instanceof Event && error.target instanceof AbortSignal) &&
|
|
71
|
+
error.name !== 'AbortError'
|
|
72
|
+
)
|
|
73
|
+
throw error
|
|
70
74
|
}),
|
|
71
75
|
)
|
|
72
76
|
|
|
@@ -76,7 +80,7 @@ async function modernWatch(
|
|
|
76
80
|
async function legacyWatch(
|
|
77
81
|
abortController: AbortController,
|
|
78
82
|
dirname: string,
|
|
79
|
-
republish: (filename?: string
|
|
83
|
+
republish: (filename?: string) => Promise<void>,
|
|
80
84
|
) {
|
|
81
85
|
const ignorer = await getWatchIgnorer(dirname)
|
|
82
86
|
const filename = tempfile()
|
|
@@ -51,7 +51,7 @@ async function getIgnoreList(dirname: string) {
|
|
|
51
51
|
})
|
|
52
52
|
|
|
53
53
|
const ignoreList: string[] = []
|
|
54
|
-
for await (const line of rl) if (line) ignoreList.push(line.trim())
|
|
54
|
+
for await (const line of rl) if (line.trim()) ignoreList.push(line.trim())
|
|
55
55
|
|
|
56
56
|
return {
|
|
57
57
|
basename,
|