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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "esm.dev",
3
- "version": "2.0.3",
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/esmd',
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 'lodash.debounce'
2
- import throat from 'throat'
1
+ import { debounce, Mutex } from 'es-toolkit'
3
2
 
4
- export async function queue<TResult, TArgs extends any[] = []>(
5
- fn: (...args: TArgs) => Promise<TResult>,
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
- return _queue((...args) => {
9
+ await mutex.acquire()
10
+ try {
9
11
  signal?.throwIfAborted()
10
- return fn(...(args as any))
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(async (...args: Args) => {
34
- try {
35
- const result = await fn(...args)
36
- promiseWithResolvers?.resolve(result)
37
- } catch (error: any) {
38
- promiseWithResolvers?.reject(error)
39
- } finally {
40
- promiseWithResolvers = undefined
41
- }
42
- }, delay)
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(port: number, esmOrigin: string): () => void {
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
- return () => {
29
- console.info('closing the server')
30
- server.closeAllConnections()
31
- server.close()
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 /*, signal: abortController.signal */ },
65
+ { recursive: true, signal: abortController.signal },
66
66
  (_, filename) =>
67
67
  (filename && ignorer.ignores(filename)) ||
68
68
  republish(filename ?? '').catch((error) => {
69
- if (error.name !== 'AbortError') throw error
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 | undefined) => Promise<void>,
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,