Commit fa4a7b4

Anton Golub <antongolub@antongolub.com>
2024-03-17 14:42:57
feat: introduce `abort()` method (#734)
* feat: introduce `abort()` method closes #527 * chore: apply fmt
1 parent aeec7ae
src/core.ts
@@ -49,6 +49,7 @@ export interface Options {
   [processCwd]: string
   cwd?: string
   verbose: boolean
+  ac?: AbortController
   env: NodeJS.ProcessEnv
   shell: string | boolean
   nothrow: boolean
@@ -200,6 +201,7 @@ export class ProcessPromise extends Promise<ProcessOutput> {
     this.zurk = exec({
       cmd: $.prefix + this._command,
       cwd: $.cwd ?? $[processCwd],
+      ac: $.ac,
       shell: typeof $.shell === 'string' ? $.shell : true,
       env: $.env,
       spawn: $.spawn,
@@ -354,6 +356,13 @@ export class ProcessPromise extends Promise<ProcessOutput> {
     }
   }
 
+  abort(reason?: string) {
+    if (!this.child)
+      throw new Error('Trying to abort a process without creating one.')
+
+    this.zurk?.ac.abort(reason)
+  }
+
   async kill(signal = 'SIGTERM'): Promise<void> {
     if (!this.child)
       throw new Error('Trying to kill a process without creating one.')
test/core.test.js
@@ -254,6 +254,31 @@ describe('core', () => {
     })
   })
 
+  test('abort() method works', async () => {
+    const p = $`sleep 9999`
+    setTimeout(() => p.abort(), 100)
+
+    try {
+      await p
+      assert.unreachable('should have thrown')
+    } catch ({ message }) {
+      assert.match(message, /The operation was aborted/)
+    }
+  })
+
+  test('accepts optional AbortController', async () => {
+    const ac = new AbortController()
+    const p = $({ ac })`sleep 9999`
+    setTimeout(() => ac.abort(), 100)
+
+    try {
+      await p
+      assert.unreachable('should have thrown')
+    } catch ({ message }) {
+      assert.match(message, /The operation was aborted/)
+    }
+  })
+
   test('kill() method works', async () => {
     let p = $`sleep 9999`.nothrow()
     setTimeout(() => {
package-lock.json
@@ -37,7 +37,7 @@
         "webpod": "^0",
         "which": "^3.0.0",
         "yaml": "^2.3.4",
-        "zurk": "^0.0.27"
+        "zurk": "^0.0.31"
       },
       "engines": {
         "node": ">= 16.0.0"
@@ -6838,9 +6838,9 @@
       }
     },
     "node_modules/zurk": {
-      "version": "0.0.27",
-      "resolved": "https://registry.npmjs.org/zurk/-/zurk-0.0.27.tgz",
-      "integrity": "sha512-BwvvxnPmiiI0H8ThWj7XSUrMN33X/JTb+qiA7/2M03jwwFtCGPwDxpNzKbI9aNKRkJu1v6XD73Y5aYY+eNyGSg==",
+      "version": "0.0.31",
+      "resolved": "https://registry.npmjs.org/zurk/-/zurk-0.0.31.tgz",
+      "integrity": "sha512-rYp8YgJFaNgTEe9/s607CqIxhJtls8Uik6hQGiPOus+5iyKphc5Xk5stLzE1bO+JnY73T/6MXI8DbnpkJQXYpA==",
       "dev": true
     }
   },
@@ -11678,9 +11678,9 @@
       "dev": true
     },
     "zurk": {
-      "version": "0.0.27",
-      "resolved": "https://registry.npmjs.org/zurk/-/zurk-0.0.27.tgz",
-      "integrity": "sha512-BwvvxnPmiiI0H8ThWj7XSUrMN33X/JTb+qiA7/2M03jwwFtCGPwDxpNzKbI9aNKRkJu1v6XD73Y5aYY+eNyGSg==",
+      "version": "0.0.31",
+      "resolved": "https://registry.npmjs.org/zurk/-/zurk-0.0.31.tgz",
+      "integrity": "sha512-rYp8YgJFaNgTEe9/s607CqIxhJtls8Uik6hQGiPOus+5iyKphc5Xk5stLzE1bO+JnY73T/6MXI8DbnpkJQXYpA==",
       "dev": true
     }
   }
package.json
@@ -83,7 +83,7 @@
     "webpod": "^0",
     "which": "^3.0.0",
     "yaml": "^2.3.4",
-    "zurk": "^0.0.27"
+    "zurk": "^0.0.31"
   },
   "publishConfig": {
     "registry": "https://wombat-dressing-room.appspot.com"