@nxtedition/yield 1.0.7 → 1.0.8

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/LICENSE +21 -0
  2. package/README.md +116 -0
  3. package/package.json +8 -3
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) nxtedition
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,116 @@
1
+ # @nxtedition/yield
2
+
3
+ Cooperative yielding for Node.js to keep servers and applications responsive.
4
+
5
+ When using synchronous APIs like `DatabaseSync`, sync fs API's such as `fs.readFileSync`, or `fs.statSync` — or simply performing lots of synchronous computation — the event loop is blocked and cannot process I/O, timers, or incoming requests. Even long-running chains of asynchronous microtasks (e.g. deeply nested `Promise.then` chains) can starve the event loop in the same way.
6
+
7
+ This library provides a simple mechanism to periodically yield control back to the event loop during these long-running operations, preventing event loop starvation and keeping your application responsive.
8
+
9
+ ## Install
10
+
11
+ ```sh
12
+ npm install @nxtedition/yield
13
+ ```
14
+
15
+ ## Usage
16
+
17
+ ### Promise-based
18
+
19
+ ```js
20
+ import { maybeYield } from '@nxtedition/yield'
21
+ import { DatabaseSync } from 'node:sqlite'
22
+
23
+ const db = new DatabaseSync('data.db')
24
+ const rows = db.prepare('SELECT * FROM large_table').all()
25
+
26
+ for (const row of rows) {
27
+ processRow(row)
28
+ const yielded = maybeYield()
29
+ if (yielded) {
30
+ await yielded // give the event loop a turn
31
+ }
32
+ }
33
+ ```
34
+
35
+ ### Callback-based
36
+
37
+ ```js
38
+ import { maybeYield } from '@nxtedition/yield'
39
+ import fs from 'node:fs'
40
+
41
+ function processFiles(files, i = 0) {
42
+ for (; i < files.length; i++) {
43
+ const data = fs.readFileSync(files[i])
44
+ transform(data)
45
+ if (maybeYield(processFiles, files, i + 1)) {
46
+ return // will resume via callback after yielding
47
+ }
48
+ }
49
+ }
50
+ ```
51
+
52
+ ### Unconditional yield
53
+
54
+ ```js
55
+ import { doYield } from '@nxtedition/yield'
56
+
57
+ // Promise-based
58
+ await doYield()
59
+
60
+ // Callback-based
61
+ doYield((opaque) => {
62
+ continueWork(opaque)
63
+ }, data)
64
+ ```
65
+
66
+ ### Checking without yielding
67
+
68
+ ```js
69
+ import { shouldYield } from '@nxtedition/yield'
70
+
71
+ while (hasWork()) {
72
+ doWork()
73
+ if (shouldYield()) {
74
+ scheduleMoreWork()
75
+ break
76
+ }
77
+ }
78
+ ```
79
+
80
+ ## API
81
+
82
+ ### `shouldYield(timeout?): boolean`
83
+
84
+ Returns `true` when the current synchronous execution has exceeded the timeout threshold (default: 40ms). Does not yield — only checks whether yielding is recommended.
85
+
86
+ ### `maybeYield(timeout?): Promise<void> | null`
87
+
88
+ If a yield is needed, queues a yield and returns a `Promise`. Otherwise returns `null`. Use this in `async` functions.
89
+
90
+ ### `maybeYield(callback, opaque?, timeout?): void`
91
+
92
+ If a yield is needed, defers `callback(opaque)` to after the yield. Otherwise calls `callback(opaque)` synchronously.
93
+
94
+ ### `doYield(): Promise<void>`
95
+
96
+ Unconditionally queues a yield and returns a `Promise` that resolves after the event loop has been given a turn.
97
+
98
+ ### `doYield(callback, opaque?): void`
99
+
100
+ Unconditionally defers `callback(opaque)` to after the next yield.
101
+
102
+ ### `setYieldTimeout(timeout): void`
103
+
104
+ Set the default yield timeout in milliseconds. Must be a non-negative number. Default: `40`.
105
+
106
+ ### `setYieldDispatcher(dispatcher): void`
107
+
108
+ Override the scheduling function used to defer work. The dispatcher receives a callback and should invoke it asynchronously (e.g. via `setTimeout` or `setImmediate`). Pass `null` to restore the default dispatcher.
109
+
110
+ ## How it works
111
+
112
+ The library tracks when the last yield occurred using `performance.now()`. When `shouldYield()` detects that more than `timeout` milliseconds have elapsed, it signals that a yield is due. `doYield` and `maybeYield` batch pending callbacks into a queue that is drained in a single microtask turn, yielding again if the timeout is exceeded during draining.
113
+
114
+ ## License
115
+
116
+ MIT
package/package.json CHANGED
@@ -1,13 +1,18 @@
1
1
  {
2
2
  "name": "@nxtedition/yield",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "type": "module",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
7
7
  "files": [
8
- "lib"
8
+ "lib",
9
+ "README.md",
10
+ "LICENSE"
9
11
  ],
10
- "license": "UNLICENSED",
12
+ "license": "MIT",
13
+ "publishConfig": {
14
+ "access": "public"
15
+ },
11
16
  "scripts": {
12
17
  "build": "rimraf lib && tsc && amaroc ./src/index.ts && mv src/index.js lib/",
13
18
  "prepublishOnly": "yarn build",