refactor(scanner): type the worker path and align app-test results

Move the worker scanner surface into TypeScript, add a direct worker regression, and make the version=2 app-test path populate the same visible result data and final status as the legacy scanner. This keeps the refactor bounded while making the worker route safe to exercise.

Constraint: Must preserve the existing Apple Silicon app-test behavior while changing the worker internals
Rejected: Flip production to the worker path immediately | still needs the normal deploy path and broader production soak
Confidence: medium
Scope-risk: moderate
Reversibility: clean
Directive: Keep the version=2 adapter using the shared finishFileScan path until the legacy scanner can be removed entirely
Tested: pnpm run typecheck; pnpm exec vitest run test/scanner/client.test.ts; pnpm run test:browser (original workspace); netlify build --context deploy-preview (original workspace)
Not-tested: Browser suite from the clean clone environment (local Astro dev server startup timed out there)
This commit is contained in:
ThatGuySam 2026-04-04 14:58:25 -05:00
parent 0480c47bbb
commit 689fc0d13d
10 changed files with 869 additions and 657 deletions

View file

@ -7,7 +7,7 @@ import { isString } from './check-types.js'
import parseMacho from './macho/index.js'
// Vite Web Workers - https://vitejs.dev/guide/features.html#web-workers
import { runScanWorker } from '~/helpers/scanner/client.mjs'
import { runScanWorker } from '~/helpers/scanner/client'
const scannerVersion = (() => {
// If there's no window
@ -341,6 +341,10 @@ export default class AppFilesScanner {
.then( response => response.data )
.catch(function (error) {
console.error(error)
return {
supportedVersionNumber: null
}
})
return {
@ -348,6 +352,47 @@ export default class AppFilesScanner {
}
}
getFinishedStatusMessage ({
binarySupportsNative,
supportedVersionNumber
}) {
if ( binarySupportsNative ) {
return '✅ This app is natively compatible with Apple Silicon!'
}
if ( supportedVersionNumber != null ) {
return [
'✅ A native version of this has been reported',
( isString( supportedVersionNumber ) && supportedVersionNumber.length > 0 ) ? `as of v${ supportedVersionNumber }` : null
].filter( Boolean ).join(' ')
}
return `🔶 This app file is not natively compatible with Apple Silicon and may only run via Rosetta 2 translation, however, software vendors will sometimes will ship separate install files for Intel and ARM instead of a single one. `
}
finishFileScan ( file, scanIndex, {
binarySupportsNative,
supportedVersionNumber
} ) {
file.statusMessage = this.getFinishedStatusMessage({
binarySupportsNative,
supportedVersionNumber
})
file.status = 'finished'
if ( binarySupportsNative ) {
this.files.unshift( this.files.splice( scanIndex, 1 )[0] )
}
}
applyWorkerScanData ( file, scan ) {
file.appVersion = scan.appVersion || null
file.displayName = scan.displayName || file.displayName
file.details = Array.isArray( scan.details ) ? scan.details : []
file.displayBinarySize = scan.displayBinarySize || null
file.binarySize = typeof scan.binarySize === 'number' ? scan.binarySize : null
}
async scanFile ( file, scanIndex ) {
// If we've already scanned this
@ -553,26 +598,10 @@ export default class AppFilesScanner {
console.log('supportedVersionNumber', supportedVersionNumber)
let finishedStatusMessage = ''
if ( binarySupportsNative ) {
finishedStatusMessage = '✅ This app is natively compatible with Apple Silicon!'
// Shift this scan to the top
this.files.unshift( this.files.splice( scanIndex, 1 )[0] )
} else if ( supportedVersionNumber !== null ) {
finishedStatusMessage = [
'✅ A native version of this has been reported',
(supportedVersionNumber.length > 0) ? `as of v${supportedVersionNumber}` : null
].join(' ')
} else {
finishedStatusMessage = `🔶 This app file is not natively compatible with Apple Silicon and may only run via Rosetta 2 translation, however, software vendors will sometimes will ship separate install files for Intel and ARM instead of a single one. `
}
file.statusMessage = finishedStatusMessage
file.status = 'finished'
this.finishFileScan( file, scanIndex, {
binarySupportsNative,
supportedVersionNumber
} )
return
}
@ -618,20 +647,45 @@ export default class AppFilesScanner {
console.log( 'scannerVersion', scannerVersion )
if ( scannerVersion === '2' ) {
try {
const { scan } = await runScanWorker( file.instance, messageDetails => {
console.log( 'messageDetails', messageDetails )
if ( isString( messageDetails.message ) ) {
file.statusMessage = messageDetails.message
}
const { scan } = await runScanWorker( file.instance, messageDetails => {
console.log( 'messageDetails', messageDetails )
if ( isString( messageDetails.status ) ) {
file.status = messageDetails.status
}
} )
file.statusMessage = messageDetails.message
file.status = messageDetails.status
} )
this.applyWorkerScanData( file, scan )
console.log('scan', scan)
const { supportedVersionNumber } = await this.submitScanInfo({
filename: scan.info?.filename || file.name,
appVersion: scan.info?.appVersion || file.appVersion,
result: scan.info?.result || ( scan.binarySupportsNative ? '✅' : '🔶' ),
machoMeta: scan.info?.machoMeta || null,
infoPlist: scan.info?.infoPlist || null
})
clearTimeout(timer)
this.finishFileScan( file, scanIndex, {
binarySupportsNative: Boolean( scan.binarySupportsNative ),
supportedVersionNumber
} )
resolve()
clearTimeout(timer)
resolve()
} catch ( error ) {
file.statusMessage = `${ error.message }`
file.status = 'finished'
clearTimeout(timer)
resolve()
}
return
}