@miniben90/x-win 3.5.1 → 3.6.0

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 (2) hide show
  1. package/index.js +140 -27
  2. package/package.json +12 -12
package/index.js CHANGED
@@ -523,47 +523,163 @@ function requireNative() {
523
523
  }
524
524
  }
525
525
 
526
- nativeBinding = requireNative()
526
+ function createLoadErrorChain(errors) {
527
+ return errors.reduce((previous, current) => {
528
+ let message
529
+ try {
530
+ message =
531
+ current && typeof current.message === 'string'
532
+ ? current.message
533
+ : String(current)
534
+ } catch {
535
+ message = 'Unknown error'
536
+ }
537
+ const error = new Error(message)
538
+ error.cause = previous
539
+ return error
540
+ }, null)
541
+ }
527
542
 
528
543
  // NAPI_RS_FORCE_WASI is a tri-state flag:
529
544
  // unset / any other value → native binding preferred, WASI is only a fallback
530
- // 'true' → force WASI fallback even if native loaded
531
- // 'error' → force WASI and throw if no WASI binding is found
545
+ // 'true' → prefer WASI, but retain native as a lazy fallback
546
+ // 'error' → require WASI without initializing a native fallback
532
547
  // Treating any non-empty string as truthy (the historical behavior) meant
533
548
  // NAPI_RS_FORCE_WASI=false, NAPI_RS_FORCE_WASI=0, etc. inadvertently triggered
534
549
  // the WASI path, causing ENOENT for packages shipped without a .wasi.cjs file.
550
+ //
551
+ // NAPI_RS_WASI_FLAVOR selects one exact generated flavor and implies strict
552
+ // WASI loading. It never crosses into another flavor or falls back to native.
553
+ const __napiWasiFlavors = ["wasm32-wasi"]
554
+ const __napiWasiFlavor = process.env.NAPI_RS_WASI_FLAVOR
555
+ const __napiWasiFlavorRequested =
556
+ typeof __napiWasiFlavor === 'string' && __napiWasiFlavor.length > 0
557
+ if (
558
+ __napiWasiFlavorRequested &&
559
+ __napiWasiFlavors.indexOf(__napiWasiFlavor) === -1
560
+ ) {
561
+ throw new Error(
562
+ 'Unsupported WASI flavor "' +
563
+ __napiWasiFlavor +
564
+ '". Available flavors: ' +
565
+ __napiWasiFlavors.join(', '),
566
+ )
567
+ }
568
+ const forceWasiError = process.env.NAPI_RS_FORCE_WASI === 'error'
535
569
  const forceWasi =
536
- process.env.NAPI_RS_FORCE_WASI === 'true' || process.env.NAPI_RS_FORCE_WASI === 'error'
570
+ process.env.NAPI_RS_FORCE_WASI === 'true' ||
571
+ forceWasiError ||
572
+ __napiWasiFlavorRequested
573
+
574
+ if (!forceWasi) {
575
+ nativeBinding = requireNative()
576
+ }
537
577
 
538
578
  if (!nativeBinding || forceWasi) {
539
579
  let wasiBinding = null
540
- let wasiBindingError = null
541
- try {
542
- wasiBinding = require('./x-win.wasi.cjs')
543
- nativeBinding = wasiBinding
544
- } catch (err) {
545
- if (forceWasi) {
546
- wasiBindingError = err
580
+ let wasiBindingLoaded = false
581
+ const wasiBindingErrors = []
582
+ const __napiWasiResolveCandidate = (specifier, isPackage, localArtifacts) => {
583
+ try {
584
+ require.resolve(specifier)
585
+ } catch (resolveError) {
586
+ if (!resolveError || resolveError.code !== 'MODULE_NOT_FOUND') {
587
+ throw resolveError
588
+ }
589
+ if (isPackage) {
590
+ try {
591
+ require.resolve(specifier + '/package.json')
592
+ } catch (packageError) {
593
+ if (packageError && packageError.code === 'MODULE_NOT_FOUND') {
594
+ return resolveError
595
+ }
596
+ // An exports restriction proves the package exists even when its
597
+ // package.json is not public. Preserve the root resolution failure.
598
+ throw resolveError
599
+ }
600
+ // The package exists but its main/export target is broken.
601
+ throw resolveError
602
+ }
603
+ return resolveError
604
+ }
605
+ if (localArtifacts) {
606
+ let artifactError = null
607
+ for (let i = 0; i < localArtifacts.length; i++) {
608
+ try {
609
+ require.resolve(localArtifacts[i])
610
+ return null
611
+ } catch (resolveError) {
612
+ if (!resolveError || resolveError.code !== 'MODULE_NOT_FOUND') {
613
+ throw resolveError
614
+ }
615
+ artifactError = resolveError
616
+ }
617
+ }
618
+ return artifactError
547
619
  }
620
+ return null
548
621
  }
549
- if (!nativeBinding || forceWasi) {
622
+ if (!wasiBindingLoaded && (!__napiWasiFlavorRequested || __napiWasiFlavor === "wasm32-wasi")) {
623
+ let candidateError = null
624
+ let candidateFailed = false
550
625
  try {
551
- wasiBinding = require('@miniben90/x-win-wasm32-wasi')
552
- nativeBinding = wasiBinding
626
+ candidateError = __napiWasiResolveCandidate('./x-win.wasi.cjs', false, ["./x-win.wasm32-wasi.debug.wasm","./x-win.wasm32-wasi.wasm"])
627
+ candidateFailed = candidateError !== null
628
+ if (!candidateFailed) {
629
+ wasiBinding = require('./x-win.wasi.cjs')
630
+ nativeBinding = wasiBinding
631
+ wasiBindingLoaded = true
632
+ }
553
633
  } catch (err) {
554
- if (forceWasi) {
555
- if (!wasiBindingError) {
556
- wasiBindingError = err
557
- } else {
558
- wasiBindingError.cause = err
634
+ candidateError = err
635
+ candidateFailed = true
636
+ }
637
+ if (candidateFailed) {
638
+ wasiBindingErrors.push(candidateError)
639
+ loadErrors.push(candidateError)
640
+ }
641
+ }
642
+ if (!wasiBindingLoaded && (!__napiWasiFlavorRequested || __napiWasiFlavor === "wasm32-wasi")) {
643
+ let candidateError = null
644
+ let candidateFailed = false
645
+ try {
646
+ candidateError = __napiWasiResolveCandidate('@miniben90/x-win-wasm32-wasi', true, undefined)
647
+ candidateFailed = candidateError !== null
648
+ if (!candidateFailed) {
649
+ if (process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
650
+ const bindingPackageVersion = require('@miniben90/x-win-wasm32-wasi/package.json').version
651
+ if (bindingPackageVersion !== '1.6.0') {
652
+ throw new Error(`WASI binding package version mismatch, expected 1.6.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
653
+ }
559
654
  }
560
- loadErrors.push(err)
655
+ wasiBinding = require('@miniben90/x-win-wasm32-wasi')
656
+ nativeBinding = wasiBinding
657
+ wasiBindingLoaded = true
561
658
  }
659
+ } catch (err) {
660
+ candidateError = err
661
+ candidateFailed = true
662
+ }
663
+ if (candidateFailed) {
664
+ wasiBindingErrors.push(candidateError)
665
+ loadErrors.push(candidateError)
562
666
  }
563
667
  }
564
- if (process.env.NAPI_RS_FORCE_WASI === 'error' && !wasiBinding) {
565
- const error = new Error('WASI binding not found and NAPI_RS_FORCE_WASI is set to error')
566
- error.cause = wasiBindingError
668
+ if (
669
+ !wasiBindingLoaded &&
670
+ forceWasi &&
671
+ !forceWasiError &&
672
+ !__napiWasiFlavorRequested
673
+ ) {
674
+ nativeBinding = requireNative()
675
+ }
676
+ if ((forceWasiError || __napiWasiFlavorRequested) && !wasiBindingLoaded) {
677
+ const error = new Error(
678
+ __napiWasiFlavorRequested
679
+ ? 'WASI binding for flavor "' + __napiWasiFlavor + '" not found'
680
+ : 'WASI binding not found and NAPI_RS_FORCE_WASI is set to error',
681
+ )
682
+ error.cause = createLoadErrorChain(wasiBindingErrors)
567
683
  throw error
568
684
  }
569
685
  }
@@ -577,10 +693,7 @@ if (!nativeBinding) {
577
693
  )
578
694
  // assign instead of the `new Error(message, { cause })` options form,
579
695
  // which Node < 16.9 silently ignores
580
- error.cause = loadErrors.reduce((err, cur) => {
581
- cur.cause = err
582
- return cur
583
- })
696
+ error.cause = createLoadErrorChain(loadErrors)
584
697
  throw error
585
698
  }
586
699
  throw new Error(`Failed to load native binding`)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@miniben90/x-win",
3
3
  "description": "This package allows you to retrieve precise information about active and open windows on Windows, MacOS, and Linux. You can obtain the position, size, title, and other memory of windows.",
4
- "version": "3.5.1",
4
+ "version": "3.6.0",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
7
7
  "files": [
@@ -56,7 +56,7 @@
56
56
  "@oxc-node/core": "^0.1.0",
57
57
  "@taplo/cli": "^0.7.0",
58
58
  "@tybys/wasm-util": "^0.10.3",
59
- "@types/node": "^25.9.4",
59
+ "@types/node": "^26.1.2",
60
60
  "ava": "^8.0.1",
61
61
  "chalk": "^5.6.2",
62
62
  "husky": "^9.1.7",
@@ -65,7 +65,7 @@
65
65
  "oxlint": "^1.71.0",
66
66
  "prettier": "^3.8.4",
67
67
  "tinybench": "^6.0.2",
68
- "typescript": "^6.0.3"
68
+ "typescript": "^7.0.2"
69
69
  },
70
70
  "lint-staged": {
71
71
  "*.@(js|ts|tsx)": [
@@ -127,15 +127,15 @@
127
127
  "checkall": "yarn format && yarn lint && yarn clippy && yarn fmt",
128
128
  "universalize": "napi universalize"
129
129
  },
130
- "packageManager": "yarn@4.17.0",
130
+ "packageManager": "yarn@4.17.1",
131
131
  "optionalDependencies": {
132
- "@miniben90/x-win-darwin-x64": "3.5.1",
133
- "@miniben90/x-win-darwin-arm64": "3.5.1",
134
- "@miniben90/x-win-linux-x64-gnu": "3.5.1",
135
- "@miniben90/x-win-linux-x64-musl": "3.5.1",
136
- "@miniben90/x-win-win32-ia32-msvc": "3.5.1",
137
- "@miniben90/x-win-win32-x64-msvc": "3.5.1",
138
- "@miniben90/x-win-win32-arm64-msvc": "3.5.1",
139
- "@miniben90/x-win-darwin-universal": "3.5.1"
132
+ "@miniben90/x-win-darwin-x64": "3.6.0",
133
+ "@miniben90/x-win-darwin-arm64": "3.6.0",
134
+ "@miniben90/x-win-linux-x64-gnu": "3.6.0",
135
+ "@miniben90/x-win-linux-x64-musl": "3.6.0",
136
+ "@miniben90/x-win-win32-ia32-msvc": "3.6.0",
137
+ "@miniben90/x-win-win32-x64-msvc": "3.6.0",
138
+ "@miniben90/x-win-win32-arm64-msvc": "3.6.0",
139
+ "@miniben90/x-win-darwin-universal": "3.6.0"
140
140
  }
141
141
  }