superlock 1.4.4 → 1.4.6

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.
Files changed (3) hide show
  1. package/README.md +19 -8
  2. package/package.json +14 -3
  3. package/src/create.js +12 -4
package/README.md CHANGED
@@ -1,8 +1,19 @@
1
- [![Last version](https://img.shields.io/github/v/tag/Kikobeats/superlock?style=flat-square)](https://github.com/Kikobeats/superlock/releases)
2
- [![Coverage Status](https://img.shields.io/coverallsCoverage/github/Kikobeats/superlock?style=flat-square)](https://coveralls.io/github/Kikobeats/superlock)
3
- [![NPM Status](https://img.shields.io/npm/dm/superlock?style=flat-square)](https://www.npmjs.com/package/superlock)
4
-
5
- > A mutex/semaphore implementation made easy to use.
1
+ <p align="center">
2
+ <a href="https://superlock.js.org/">
3
+ <picture>
4
+ <source media="(prefers-color-scheme: dark)" srcset="docs/anatomy/wordmark.svg">
5
+ <img alt="superlock" src="docs/anatomy/wordmark-light.svg" width="640">
6
+ </picture>
7
+ </a>
8
+ </p>
9
+
10
+ <p align="center" class="subtitle">The minimal Node.js concurrency toolkit.</p>
11
+
12
+ <p align="center" class="badges">
13
+ <a href="https://github.com/Kikobeats/superlock/releases"><img alt="Last version" src="https://img.shields.io/github/v/tag/Kikobeats/superlock?style=flat-square"></a>
14
+ <a href="https://coveralls.io/github/Kikobeats/superlock"><img alt="Coverage Status" src="https://img.shields.io/coverallsCoverage/github/Kikobeats/superlock?style=flat-square"></a>
15
+ <a href="https://www.npmjs.com/package/superlock"><img alt="NPM Status" src="https://img.shields.io/npm/dm/superlock?style=flat-square"></a>
16
+ </p>
6
17
 
7
18
  ## Why
8
19
 
@@ -26,7 +37,7 @@ $ npm install superlock --save
26
37
 
27
38
  The lock is a mutex by default: one caller holds it, the rest wait in arrival order.
28
39
 
29
- <a href="https://kikobeats.github.io/superlock/#/?id=as-mutex">
40
+ <a href="https://superlock.js.org/#/?id=as-mutex">
30
41
  <picture>
31
42
  <source media="(prefers-color-scheme: dark)" srcset="docs/anatomy/mutex.svg">
32
43
  <img alt="A coin-feed escapement: tokens queue in a column, a pusher one token thick carries exactly one at a time to a press, and the next drops in only after release()." src="docs/anatomy/mutex-light.svg">
@@ -55,7 +66,7 @@ console.log(executions)
55
66
 
56
67
  Call `withLock(n)` with `n` as the maximum concurrency for the lock. Up to `n` callers hold it at once; a freed slot goes to the oldest waiter:
57
68
 
58
- <a href="https://kikobeats.github.io/superlock/#/?id=as-semaphore">
69
+ <a href="https://superlock.js.org/#/?id=as-semaphore">
59
70
  <picture>
60
71
  <source media="(prefers-color-scheme: dark)" srcset="docs/anatomy/semaphore.svg">
61
72
  <img alt="Twin lanes fed by one column: a diverter drops the oldest waiting token into whichever of two lanes is free, and each lane releases on its own." src="docs/anatomy/semaphore-light.svg">
@@ -86,7 +97,7 @@ console.log(executions)
86
97
 
87
98
  `withFairQueue` is [fair queuing](https://en.wikipedia.org/wiki/Fair_queuing): one queue per key, and a free slot rotates across those keys. The same key is still served in arrival order. Callers that omit the key share one queue.
88
99
 
89
- <a href="https://kikobeats.github.io/superlock/#/?id=as-fair-queue">
100
+ <a href="https://superlock.js.org/#/?id=as-fair-queue">
90
101
  <picture>
91
102
  <source media="(prefers-color-scheme: dark)" srcset="docs/anatomy/fair-queue.svg">
92
103
  <img alt="An indexing table: one column per key around a rotating dial that feeds one press, visiting the keys in turn so a deep column cannot starve the others." src="docs/anatomy/fair-queue-light.svg">
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "superlock",
3
- "description": "Minimal async mutex and semaphore for serializing critical sections in Node.js.",
4
- "homepage": "https://kikobeats.github.io/superlock/",
5
- "version": "1.4.4",
3
+ "description": "The minimal Node.js concurrency toolkit: mutex, semaphore and fair queue for async/await, with no dependencies.",
4
+ "homepage": "https://superlock.js.org/",
5
+ "version": "1.4.6",
6
6
  "types": "src/index.d.ts",
7
7
  "main": "src/index.js",
8
8
  "exports": {
@@ -73,6 +73,7 @@
73
73
  "dev": "concurrently \"gulp\" \"npm run dev:server\"",
74
74
  "dev:server": "browser-sync start --server --files \"index.html, README.md, static/**/*.(css|js)\"",
75
75
  "lint": "standard",
76
+ "og": "node docs/og/build.mjs",
76
77
  "postrelease": "npm run release:tags && npm run release:github && (ci-publish || npm publish --access=public)",
77
78
  "prerelease": "npm run contributors",
78
79
  "pretest": "npm run lint",
@@ -88,6 +89,16 @@
88
89
  "!test/helpers.js"
89
90
  ]
90
91
  },
92
+ "c8": {
93
+ "branches": 100,
94
+ "check-coverage": true,
95
+ "functions": 100,
96
+ "include": [
97
+ "src/**/*.js"
98
+ ],
99
+ "lines": 100,
100
+ "statements": 100
101
+ },
91
102
  "commitlint": {
92
103
  "extends": [
93
104
  "@commitlint/config-conventional"
package/src/create.js CHANGED
@@ -11,18 +11,25 @@ module.exports = (slots = 1) => {
11
11
  if (waiter) return waiter.acquire()
12
12
  }
13
13
 
14
+ const ready = Promise.resolve(release)
15
+
14
16
  const acquire = resolve => {
15
17
  --slots
16
18
  resolve(release)
17
19
  }
18
20
 
19
- const lock = signal =>
20
- new Promise(resolve => {
21
+ const lock = signal => {
22
+ if (signal == null && slots !== 0) {
23
+ --slots
24
+ return ready
25
+ }
26
+
27
+ return new Promise(resolve => {
21
28
  if (signal != null && typeof signal.addEventListener !== 'function') {
22
29
  throw new TypeError('`signal` needs to be an AbortSignal.')
23
30
  }
24
- if (signal?.aborted) return resolve(null)
25
- if (!lock.isLocked()) return acquire(resolve)
31
+ if (signal != null && signal.aborted) return resolve(null)
32
+ if (slots !== 0) return acquire(resolve)
26
33
 
27
34
  const waiter = { acquire: () => acquire(resolve) }
28
35
  const node = queue.enqueue(waiter)
@@ -39,6 +46,7 @@ module.exports = (slots = 1) => {
39
46
  signal.addEventListener('abort', onAbort, { once: true })
40
47
  }
41
48
  })
49
+ }
42
50
 
43
51
  lock.isLocked = () => slots === 0
44
52