Просмотр исходного кода

fix(webworker): scope Linux-only CI checks

imccyu 2 недель назад
Родитель
Сommit
be852d4e9b

+ 38 - 19
packages/experimental/webworker-runtime/src/node/builtin_modules/implemented/fs.ts

@@ -481,6 +481,40 @@ export interface WriteStreamOptions {
 /** Node implements file-stream `autoClose` through the stream's `autoDestroy` state. */
 const streamAutoDestroy = (autoClose: boolean | undefined): boolean => autoClose ?? true
 
+interface FileStreamState {
+  fd: number | null
+  pending: boolean
+}
+
+/** Release the descriptor and abort listener shared by both file-stream directions. */
+function destroyFileStream(
+  stream: FileStreamState,
+  signal: AbortSignal | undefined,
+  onAbort: (() => void) | undefined,
+  error: Error | null,
+  callback: (error: Error | null) => void,
+): void {
+  signal?.removeEventListener('abort', onAbort as () => void)
+  if (stream.fd !== null) closeSync(stream.fd)
+  stream.fd = null
+  stream.pending = false
+  callback(error)
+}
+
+interface ClosableFileStream {
+  once(event: string, listener: () => void): unknown
+  destroy(): unknown
+}
+
+/** Register an optional completion callback and explicitly destroy a file stream. */
+function closeFileStream(
+  stream: ClosableFileStream,
+  callback?: (error?: NodeJS.ErrnoException | null) => void,
+): void {
+  if (callback !== undefined) stream.once('close', () => { callback(null) })
+  stream.destroy()
+}
+
 /** Read stream over one VFS file. */
 export class ReadStream extends Readable {
   /** Resolved path opened by this stream. */
@@ -560,11 +594,7 @@ export class ReadStream extends Readable {
   }
 
   override _destroy(error: Error | null, callback: (error?: Error | null) => void): void {
-    this.signal?.removeEventListener('abort', this.onAbort as () => void)
-    if (this.fd !== null) closeSync(this.fd)
-    this.fd = null
-    this.pending = false
-    callback(error)
+    destroyFileStream(this, this.signal, this.onAbort, error, callback)
   }
 
   /**
@@ -572,8 +602,7 @@ export class ReadStream extends Readable {
    * @param callback - Optional completion callback after `close`.
    */
   close(callback?: (error?: NodeJS.ErrnoException | null) => void): void {
-    if (callback !== undefined) this.once('close', () => { callback(null) })
-    this.destroy()
+    closeFileStream(this, callback)
   }
 }
 
@@ -647,11 +676,7 @@ export class WriteStream extends Writable {
   }
 
   override _destroy(error: Error | null, callback: (error: Error | null) => void): void {
-    this.signal?.removeEventListener('abort', this.onAbort as () => void)
-    closeDescriptor(this.fd)
-    this.fd = null
-    this.pending = false
-    callback(error)
+    destroyFileStream(this, this.signal, this.onAbort, error, callback)
   }
 
   /**
@@ -659,16 +684,10 @@ export class WriteStream extends Writable {
    * @param callback - Optional completion callback after `close`.
    */
   close(callback?: (error?: NodeJS.ErrnoException | null) => void): void {
-    if (callback !== undefined) this.once('close', () => { callback(null) })
-    this.destroy()
+    closeFileStream(this, callback)
   }
 }
 
-/** Close a stream-owned descriptor when it has opened successfully. */
-function closeDescriptor(fd: number | null): void {
-  if (fd !== null) closeSync(fd)
-}
-
 /**
  * Create a Node-compatible readable file stream over the VFS.
  * @param path - File path.

+ 1 - 1
packages/experimental/webworker-runtime/tests/node/fs-watch-stream.spec.ts

@@ -279,7 +279,7 @@ describe('file streams', () => {
     expect(workerStream.default._isArrayBufferView(new Uint8Array())).toBe(true)
   })
 
-  it('matches Node file-stream defaults and abort error identity', async () => {
+  it('uses Node 22 Linux file-stream defaults and abort error identity', async () => {
     const nativeRoot = mkdtempSync(join(tmpdir(), 'dsh-stream-diff-'))
     nativeRoots.push(nativeRoot)
     const nativePath = join(nativeRoot, 'input.txt')

+ 14 - 3
vitest.config.ts

@@ -57,6 +57,17 @@ const windowsUnsupportedTests = process.platform === 'win32'
     ]
   : []
 
+// These suites compare against or assemble the Worker's fixed Linux platform.
+// Host-native Windows and macOS behavior is not their oracle.
+const nonLinuxWebWorkerTests = process.platform === 'linux'
+  ? []
+  : [
+      'packages/experimental/webworker-runtime/tests/node/fs-watch-stream.spec.ts',
+      'packages/experimental/webworker-runtime/tests/node/sandbox-stack.spec.ts',
+    ]
+
+const platformUnsupportedTests = [...windowsUnsupportedTests, ...nonLinuxWebWorkerTests]
+
 const windowsUnsupportedCoveragePackages = process.platform === 'win32'
   ? [...windowsUnsupportedPackages, 'packages/subprocess/*']
   : []
@@ -142,7 +153,7 @@ export default defineConfig({
     setupFiles: ['./scripts/test-invariants.ts'],
     // .tsx: client component specs (jsdom via per-file @vitest-environment pragma).
     include: testIncludes,
-    exclude: windowsUnsupportedTests,
+    exclude: platformUnsupportedTests,
     // One coverage invocation aggregates both projects. Every suite forks for
     // Node stability; process-bound suites stay separate for inventory control.
     projects: [
@@ -158,7 +169,7 @@ export default defineConfig({
           setupFiles: ['./scripts/test-invariants.ts'],
           include: testIncludes,
           exclude: [
-            ...windowsUnsupportedTests,
+            ...platformUnsupportedTests,
             ...processBoundTests,
             ...coverageExemptExcludes,
           ],
@@ -173,7 +184,7 @@ export default defineConfig({
           setupFiles: ['./scripts/test-invariants.ts'],
           include: processBoundTests,
           exclude: [
-            ...windowsUnsupportedTests,
+            ...platformUnsupportedTests,
             ...coverageExemptExcludes,
           ],
         },