added tailwind back, reenabled utilities which was causing the color issue
This commit is contained in:
+1
@@ -0,0 +1 @@
|
||||
../jiti/lib/jiti-cli.mjs
|
||||
+1
@@ -0,0 +1 @@
|
||||
../nanoid/bin/nanoid.cjs
|
||||
+1
@@ -0,0 +1 @@
|
||||
../rolldown/bin/cli.mjs
|
||||
+1
@@ -0,0 +1 @@
|
||||
../vite/bin/vite.js
|
||||
+558
@@ -0,0 +1,558 @@
|
||||
{
|
||||
"name": "routie2",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"node_modules/@emnapi/core": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz",
|
||||
"integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@emnapi/wasi-threads": "1.2.1",
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@emnapi/runtime": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz",
|
||||
"integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@emnapi/wasi-threads": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz",
|
||||
"integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/gen-mapping": {
|
||||
"version": "0.3.13",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
|
||||
"integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/sourcemap-codec": "^1.5.0",
|
||||
"@jridgewell/trace-mapping": "^0.3.24"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/remapping": {
|
||||
"version": "2.3.5",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
|
||||
"integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/gen-mapping": "^0.3.5",
|
||||
"@jridgewell/trace-mapping": "^0.3.24"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/resolve-uri": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
|
||||
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/sourcemap-codec": {
|
||||
"version": "1.5.5",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
|
||||
"integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@jridgewell/trace-mapping": {
|
||||
"version": "0.3.31",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
|
||||
"integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/resolve-uri": "^3.1.0",
|
||||
"@jridgewell/sourcemap-codec": "^1.4.14"
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/wasm-runtime": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz",
|
||||
"integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@tybys/wasm-util": "^0.10.1"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/Brooooooklyn"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@emnapi/core": "^1.7.1",
|
||||
"@emnapi/runtime": "^1.7.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxc-project/types": {
|
||||
"version": "0.127.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.127.0.tgz",
|
||||
"integrity": "sha512-aIYXQBo4lCbO4z0R3FHeucQHpF46l2LbMdxRvqvuRuW2OxdnSkcng5B8+K12spgLDj93rtN3+J2Vac/TIO+ciQ==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/Boshen"
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-darwin-arm64": {
|
||||
"version": "1.0.0-rc.17",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.17.tgz",
|
||||
"integrity": "sha512-4ksWc9n0mhlZpZ9PMZgTGjeOPRu8MB1Z3Tz0Mo02eWfWCHMW1zN82Qz/pL/rC+yQa+8ZnutMF0JjJe7PjwasYw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/pluginutils": {
|
||||
"version": "1.0.0-rc.17",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.17.tgz",
|
||||
"integrity": "sha512-n8iosDOt6Ig1UhJ2AYqoIhHWh/isz0xpicHTzpKBeotdVsTEcxsSA/i3EVM7gQAj0rU27OLAxCjzlj15IWY7bg==",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@tailwindcss/node": {
|
||||
"version": "4.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.2.4.tgz",
|
||||
"integrity": "sha512-Ai7+yQPxz3ddrDQzFfBKdHEVBg0w3Zl83jnjuwxnZOsnH9pGn93QHQtpU0p/8rYWxvbFZHneni6p1BSLK4DkGA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/remapping": "^2.3.5",
|
||||
"enhanced-resolve": "^5.19.0",
|
||||
"jiti": "^2.6.1",
|
||||
"lightningcss": "1.32.0",
|
||||
"magic-string": "^0.30.21",
|
||||
"source-map-js": "^1.2.1",
|
||||
"tailwindcss": "4.2.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide": {
|
||||
"version": "4.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.2.4.tgz",
|
||||
"integrity": "sha512-9El/iI069DKDSXwTvB9J4BwdO5JhRrOweGaK25taBAvBXyXqJAX+Jqdvs8r8gKpsI/1m0LeJLyQYTf/WLrBT1Q==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 20"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@tailwindcss/oxide-android-arm64": "4.2.4",
|
||||
"@tailwindcss/oxide-darwin-arm64": "4.2.4",
|
||||
"@tailwindcss/oxide-darwin-x64": "4.2.4",
|
||||
"@tailwindcss/oxide-freebsd-x64": "4.2.4",
|
||||
"@tailwindcss/oxide-linux-arm-gnueabihf": "4.2.4",
|
||||
"@tailwindcss/oxide-linux-arm64-gnu": "4.2.4",
|
||||
"@tailwindcss/oxide-linux-arm64-musl": "4.2.4",
|
||||
"@tailwindcss/oxide-linux-x64-gnu": "4.2.4",
|
||||
"@tailwindcss/oxide-linux-x64-musl": "4.2.4",
|
||||
"@tailwindcss/oxide-wasm32-wasi": "4.2.4",
|
||||
"@tailwindcss/oxide-win32-arm64-msvc": "4.2.4",
|
||||
"@tailwindcss/oxide-win32-x64-msvc": "4.2.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-darwin-arm64": {
|
||||
"version": "4.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.2.4.tgz",
|
||||
"integrity": "sha512-tSC/Kbqpz/5/o/C2sG7QvOxAKqyd10bq+ypZNf+9Fi2TvbVbv1zNpcEptcsU7DPROaSbVgUXmrzKhurFvo5eDg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 20"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/vite": {
|
||||
"version": "4.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.2.4.tgz",
|
||||
"integrity": "sha512-pCvohwOCspk3ZFn6eJzrrX3g4n2JY73H6MmYC87XfGPyTty4YsCjYTMArRZm/zOI8dIt3+EcrLHAFPe5A4bgtw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@tailwindcss/node": "4.2.4",
|
||||
"@tailwindcss/oxide": "4.2.4",
|
||||
"tailwindcss": "4.2.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vite": "^5.2.0 || ^6 || ^7 || ^8"
|
||||
}
|
||||
},
|
||||
"node_modules/@tybys/wasm-util": {
|
||||
"version": "0.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz",
|
||||
"integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/detect-libc": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
|
||||
"integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/enhanced-resolve": {
|
||||
"version": "5.21.0",
|
||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.21.0.tgz",
|
||||
"integrity": "sha512-otxSQPw4lkOZWkHpB3zaEQs6gWYEsmX4xQF68ElXC/TWvGxGMSGOvoNbaLXm6/cS/fSfHtsEdw90y20PCd+sCA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.2.4",
|
||||
"tapable": "^2.3.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/fdir": {
|
||||
"version": "6.5.0",
|
||||
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
|
||||
"integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"picomatch": "^3 || ^4"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"picomatch": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/graceful-fs": {
|
||||
"version": "4.2.11",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
|
||||
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/jiti": {
|
||||
"version": "2.6.1",
|
||||
"resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz",
|
||||
"integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==",
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"jiti": "lib/jiti-cli.mjs"
|
||||
}
|
||||
},
|
||||
"node_modules/lightningcss": {
|
||||
"version": "1.32.0",
|
||||
"resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz",
|
||||
"integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==",
|
||||
"license": "MPL-2.0",
|
||||
"dependencies": {
|
||||
"detect-libc": "^2.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 12.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"lightningcss-android-arm64": "1.32.0",
|
||||
"lightningcss-darwin-arm64": "1.32.0",
|
||||
"lightningcss-darwin-x64": "1.32.0",
|
||||
"lightningcss-freebsd-x64": "1.32.0",
|
||||
"lightningcss-linux-arm-gnueabihf": "1.32.0",
|
||||
"lightningcss-linux-arm64-gnu": "1.32.0",
|
||||
"lightningcss-linux-arm64-musl": "1.32.0",
|
||||
"lightningcss-linux-x64-gnu": "1.32.0",
|
||||
"lightningcss-linux-x64-musl": "1.32.0",
|
||||
"lightningcss-win32-arm64-msvc": "1.32.0",
|
||||
"lightningcss-win32-x64-msvc": "1.32.0"
|
||||
}
|
||||
},
|
||||
"node_modules/lightningcss-darwin-arm64": {
|
||||
"version": "1.32.0",
|
||||
"resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz",
|
||||
"integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 12.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/magic-string": {
|
||||
"version": "0.30.21",
|
||||
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
|
||||
"integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/sourcemap-codec": "^1.5.5"
|
||||
}
|
||||
},
|
||||
"node_modules/nanoid": {
|
||||
"version": "3.3.12",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz",
|
||||
"integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"nanoid": "bin/nanoid.cjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/picocolors": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
||||
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
|
||||
"license": "ISC",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/picomatch": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
|
||||
"integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss": {
|
||||
"version": "8.5.13",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.13.tgz",
|
||||
"integrity": "sha512-qif0+jGGZoLWdHey3UFHHWP0H7Gbmsk8T5VEqyYFbWqPr1XqvLGBbk/sl8V5exGmcYJklJOhOQq1pV9IcsiFag==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/postcss/"
|
||||
},
|
||||
{
|
||||
"type": "tidelift",
|
||||
"url": "https://tidelift.com/funding/github/npm/postcss"
|
||||
},
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"nanoid": "^3.3.11",
|
||||
"picocolors": "^1.1.1",
|
||||
"source-map-js": "^1.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10 || ^12 || >=14"
|
||||
}
|
||||
},
|
||||
"node_modules/rolldown": {
|
||||
"version": "1.0.0-rc.17",
|
||||
"resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.17.tgz",
|
||||
"integrity": "sha512-ZrT53oAKrtA4+YtBWPQbtPOxIbVDbxT0orcYERKd63VJTF13zPcgXTvD4843L8pcsI7M6MErt8QtON6lrB9tyA==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@oxc-project/types": "=0.127.0",
|
||||
"@rolldown/pluginutils": "1.0.0-rc.17"
|
||||
},
|
||||
"bin": {
|
||||
"rolldown": "bin/cli.mjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@rolldown/binding-android-arm64": "1.0.0-rc.17",
|
||||
"@rolldown/binding-darwin-arm64": "1.0.0-rc.17",
|
||||
"@rolldown/binding-darwin-x64": "1.0.0-rc.17",
|
||||
"@rolldown/binding-freebsd-x64": "1.0.0-rc.17",
|
||||
"@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.17",
|
||||
"@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.17",
|
||||
"@rolldown/binding-linux-arm64-musl": "1.0.0-rc.17",
|
||||
"@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.17",
|
||||
"@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.17",
|
||||
"@rolldown/binding-linux-x64-gnu": "1.0.0-rc.17",
|
||||
"@rolldown/binding-linux-x64-musl": "1.0.0-rc.17",
|
||||
"@rolldown/binding-openharmony-arm64": "1.0.0-rc.17",
|
||||
"@rolldown/binding-wasm32-wasi": "1.0.0-rc.17",
|
||||
"@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.17",
|
||||
"@rolldown/binding-win32-x64-msvc": "1.0.0-rc.17"
|
||||
}
|
||||
},
|
||||
"node_modules/source-map-js": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
||||
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
|
||||
"license": "BSD-3-Clause",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/tailwindcss": {
|
||||
"version": "4.2.4",
|
||||
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.4.tgz",
|
||||
"integrity": "sha512-HhKppgO81FQof5m6TEnuBWCZGgfRAWbaeOaGT00KOy/Pf/j6oUihdvBpA7ltCeAvZpFhW3j0PTclkxsd4IXYDA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/tapable": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.3.tgz",
|
||||
"integrity": "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/webpack"
|
||||
}
|
||||
},
|
||||
"node_modules/tinyglobby": {
|
||||
"version": "0.2.16",
|
||||
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz",
|
||||
"integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"fdir": "^6.5.0",
|
||||
"picomatch": "^4.0.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/SuperchupuDev"
|
||||
}
|
||||
},
|
||||
"node_modules/tslib": {
|
||||
"version": "2.8.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
|
||||
"license": "0BSD",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/vite": {
|
||||
"version": "8.0.10",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-8.0.10.tgz",
|
||||
"integrity": "sha512-rZuUu9j6J5uotLDs+cAA4O5H4K1SfPliUlQwqa6YEwSrWDZzP4rhm00oJR5snMewjxF5V/K3D4kctsUTsIU9Mw==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"lightningcss": "^1.32.0",
|
||||
"picomatch": "^4.0.4",
|
||||
"postcss": "^8.5.10",
|
||||
"rolldown": "1.0.0-rc.17",
|
||||
"tinyglobby": "^0.2.16"
|
||||
},
|
||||
"bin": {
|
||||
"vite": "bin/vite.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/vitejs/vite?sponsor=1"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"fsevents": "~2.3.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/node": "^20.19.0 || >=22.12.0",
|
||||
"@vitejs/devtools": "^0.1.0",
|
||||
"esbuild": "^0.27.0 || ^0.28.0",
|
||||
"jiti": ">=1.21.0",
|
||||
"less": "^4.0.0",
|
||||
"sass": "^1.70.0",
|
||||
"sass-embedded": "^1.70.0",
|
||||
"stylus": ">=0.54.8",
|
||||
"sugarss": "^5.0.0",
|
||||
"terser": "^5.16.0",
|
||||
"tsx": "^4.8.1",
|
||||
"yaml": "^2.4.2"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/node": {
|
||||
"optional": true
|
||||
},
|
||||
"@vitejs/devtools": {
|
||||
"optional": true
|
||||
},
|
||||
"esbuild": {
|
||||
"optional": true
|
||||
},
|
||||
"jiti": {
|
||||
"optional": true
|
||||
},
|
||||
"less": {
|
||||
"optional": true
|
||||
},
|
||||
"sass": {
|
||||
"optional": true
|
||||
},
|
||||
"sass-embedded": {
|
||||
"optional": true
|
||||
},
|
||||
"stylus": {
|
||||
"optional": true
|
||||
},
|
||||
"sugarss": {
|
||||
"optional": true
|
||||
},
|
||||
"terser": {
|
||||
"optional": true
|
||||
},
|
||||
"tsx": {
|
||||
"optional": true
|
||||
},
|
||||
"yaml": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021-present Toyobayashi
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
+1
@@ -0,0 +1 @@
|
||||
See [https://github.com/toyobayashi/emnapi](https://github.com/toyobayashi/emnapi)
|
||||
+7397
File diff suppressed because it is too large
Load Diff
+420
@@ -0,0 +1,420 @@
|
||||
/// <reference types="node" />
|
||||
|
||||
import type { Context } from '@emnapi/runtime';
|
||||
import type { ReferenceOwnership } from '@emnapi/runtime';
|
||||
import type { Worker as Worker_2 } from 'worker_threads';
|
||||
|
||||
/** @public */
|
||||
export declare type BaseCreateOptions = {
|
||||
filename?: string
|
||||
nodeBinding?: NodeBinding
|
||||
reuseWorker?: ThreadManagerOptionsMain['reuseWorker']
|
||||
asyncWorkPoolSize?: number
|
||||
waitThreadStart?: MainThreadBaseOptions['waitThreadStart']
|
||||
onCreateWorker?: (info: CreateWorkerInfo) => any
|
||||
print?: (str: string) => void
|
||||
printErr?: (str: string) => void
|
||||
postMessage?: (msg: any) => any
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface BaseOptions {
|
||||
wasi: WASIInstance;
|
||||
version?: 'preview1';
|
||||
wasm64?: boolean;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface ChildThreadOptions extends BaseOptions {
|
||||
childThread: true;
|
||||
postMessage?: (data: any) => void;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface CleanupThreadPayload {
|
||||
tid: number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface CommandInfo<T extends CommandType> {
|
||||
type: T;
|
||||
payload: CommandPayloadMap[T];
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface CommandPayloadMap {
|
||||
load: LoadPayload;
|
||||
loaded: LoadedPayload;
|
||||
start: StartPayload;
|
||||
'cleanup-thread': CleanupThreadPayload;
|
||||
'terminate-all-threads': TerminateAllThreadsPayload;
|
||||
'spawn-thread': SpawnThreadPayload;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare type CommandType = keyof CommandPayloadMap;
|
||||
|
||||
/** @public */
|
||||
export declare function createInstanceProxy(instance: WebAssembly.Instance, memory?: WebAssembly.Memory | (() => WebAssembly.Memory)): WebAssembly.Instance;
|
||||
|
||||
/** @public */
|
||||
export declare function createNapiModule (
|
||||
options: CreateOptions
|
||||
): NapiModule
|
||||
|
||||
/** @public */
|
||||
export declare type CreateOptions = BaseCreateOptions & ({
|
||||
context: Context
|
||||
childThread?: boolean
|
||||
} | {
|
||||
context?: Context
|
||||
childThread: true
|
||||
})
|
||||
|
||||
/** @public */
|
||||
export declare interface CreateWorkerInfo {
|
||||
type: 'thread' | 'async-work'
|
||||
name: string
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface InitOptions {
|
||||
instance: WebAssembly.Instance
|
||||
module: WebAssembly.Module
|
||||
memory?: WebAssembly.Memory
|
||||
table?: WebAssembly.Table
|
||||
}
|
||||
|
||||
export declare type InputType = string | URL | Response | BufferSource | WebAssembly.Module;
|
||||
|
||||
/** @public */
|
||||
export declare interface InstantiatedSource extends LoadedSource {
|
||||
napiModule: NapiModule;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare function instantiateNapiModule(
|
||||
/** Only support `BufferSource` or `WebAssembly.Module` on Node.js */
|
||||
wasmInput: InputType | Promise<InputType>, options: InstantiateOptions): Promise<InstantiatedSource>;
|
||||
|
||||
/** @public */
|
||||
export declare function instantiateNapiModuleSync(wasmInput: BufferSource | WebAssembly.Module, options: InstantiateOptions): InstantiatedSource;
|
||||
|
||||
/** @public */
|
||||
export declare type InstantiateOptions = CreateOptions & LoadOptions;
|
||||
|
||||
/** @public */
|
||||
export declare function isSharedArrayBuffer(value: any): value is SharedArrayBuffer;
|
||||
|
||||
/** @public */
|
||||
export declare function isTrapError(e: Error): e is WebAssembly.RuntimeError;
|
||||
|
||||
/** @public */
|
||||
export declare interface LoadedPayload {
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface LoadedSource extends WebAssembly.WebAssemblyInstantiatedSource {
|
||||
usedInstance: WebAssembly.Instance;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare function loadNapiModule(napiModule: NapiModule,
|
||||
/** Only support `BufferSource` or `WebAssembly.Module` on Node.js */
|
||||
wasmInput: InputType | Promise<InputType>, options?: LoadOptions): Promise<LoadedSource>;
|
||||
|
||||
/** @public */
|
||||
export declare function loadNapiModuleSync(napiModule: NapiModule, wasmInput: BufferSource | WebAssembly.Module, options?: LoadOptions): LoadedSource;
|
||||
|
||||
/** @public */
|
||||
export declare interface LoadOptions {
|
||||
wasi?: WASIInstance;
|
||||
overwriteImports?: (importObject: WebAssembly.Imports) => WebAssembly.Imports;
|
||||
beforeInit?: (source: WebAssembly.WebAssemblyInstantiatedSource) => void;
|
||||
getMemory?: (exports: WebAssembly.Exports) => WebAssembly.Memory;
|
||||
getTable?: (exports: WebAssembly.Exports) => WebAssembly.Table;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface LoadPayload {
|
||||
wasmModule: WebAssembly.Module;
|
||||
wasmMemory: WebAssembly.Memory;
|
||||
sab?: Int32Array;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface MainThreadBaseOptions extends BaseOptions {
|
||||
waitThreadStart?: boolean | number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare type MainThreadOptions = MainThreadOptionsWithThreadManager | MainThreadOptionsCreateThreadManager;
|
||||
|
||||
/** @public */
|
||||
export declare interface MainThreadOptionsCreateThreadManager extends MainThreadBaseOptions, ThreadManagerOptionsMain {
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface MainThreadOptionsWithThreadManager extends MainThreadBaseOptions {
|
||||
threadManager?: ThreadManager | (() => ThreadManager);
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface MessageEventData<T extends CommandType> {
|
||||
__emnapi__: CommandInfo<T>;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare class MessageHandler extends ThreadMessageHandler {
|
||||
napiModule: NapiModule | undefined;
|
||||
constructor(options: MessageHandlerOptions);
|
||||
instantiate(data: LoadPayload): InstantiatedSource | PromiseLike<InstantiatedSource>;
|
||||
handle(e: WorkerMessageEvent): void;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface MessageHandlerOptions extends ThreadMessageHandlerOptions {
|
||||
onLoad: (data: LoadPayload) => InstantiatedSource | PromiseLike<InstantiatedSource>;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface NapiModule {
|
||||
imports: {
|
||||
env: any
|
||||
napi: any
|
||||
emnapi: any
|
||||
}
|
||||
exports: any
|
||||
loaded: boolean
|
||||
filename: string
|
||||
childThread: boolean
|
||||
emnapi: {
|
||||
syncMemory<T extends ArrayBuffer | ArrayBufferView> (
|
||||
js_to_wasm: boolean,
|
||||
arrayBufferOrView: T,
|
||||
offset?: number,
|
||||
len?: number
|
||||
): T
|
||||
getMemoryAddress (arrayBufferOrView: ArrayBuffer | ArrayBufferView): PointerInfo
|
||||
addSendListener (worker: any): boolean
|
||||
}
|
||||
|
||||
init (options: InitOptions): any
|
||||
initWorker (arg: number, func: [number, number]): void
|
||||
postMessage?: (msg: any) => any
|
||||
|
||||
waitThreadStart: boolean | number
|
||||
/* Excluded from this release type: PThread */}
|
||||
|
||||
/** @public */
|
||||
export declare interface NodeBinding {
|
||||
node: {
|
||||
emitAsyncInit: Function
|
||||
emitAsyncDestroy: Function
|
||||
makeCallback: Function
|
||||
}
|
||||
napi: {
|
||||
asyncInit: Function
|
||||
asyncDestroy: Function
|
||||
makeCallback: Function
|
||||
}
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface PointerInfo {
|
||||
address: number
|
||||
ownership: ReferenceOwnership
|
||||
runtimeAllocated: 0 | 1
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface ReuseWorkerOptions {
|
||||
/**
|
||||
* @see {@link https://emscripten.org/docs/tools_reference/settings_reference.html#pthread-pool-size | PTHREAD_POOL_SIZE}
|
||||
*/
|
||||
size: number;
|
||||
/**
|
||||
* @see {@link https://emscripten.org/docs/tools_reference/settings_reference.html#pthread-pool-size-strict | PTHREAD_POOL_SIZE_STRICT}
|
||||
*/
|
||||
strict?: boolean;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface SpawnThreadPayload {
|
||||
startArg: number;
|
||||
errorOrTid: number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface StartPayload {
|
||||
tid: number;
|
||||
arg: number;
|
||||
sab?: Int32Array;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface StartResult {
|
||||
exitCode: number;
|
||||
instance: WebAssembly.Instance;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface TerminateAllThreadsPayload {
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare class ThreadManager {
|
||||
unusedWorkers: WorkerLike[];
|
||||
runningWorkers: WorkerLike[];
|
||||
pthreads: Record<number, WorkerLike>;
|
||||
get nextWorkerID(): number;
|
||||
wasmModule: WebAssembly.Module | null;
|
||||
wasmMemory: WebAssembly.Memory | null;
|
||||
private readonly messageEvents;
|
||||
private readonly _childThread;
|
||||
private readonly _onCreateWorker;
|
||||
private readonly _reuseWorker;
|
||||
private readonly _beforeLoad?;
|
||||
/* Excluded from this release type: printErr */
|
||||
threadSpawn?: ((startArg: number, errorOrTid?: number) => number);
|
||||
constructor(options: ThreadManagerOptions);
|
||||
init(): void;
|
||||
initMainThread(): void;
|
||||
private preparePool;
|
||||
shouldPreloadWorkers(): boolean;
|
||||
loadWasmModuleToAllWorkers(): Promise<WorkerLike[]>;
|
||||
preloadWorkers(): Promise<WorkerLike[]>;
|
||||
setup(wasmModule: WebAssembly.Module, wasmMemory: WebAssembly.Memory): void;
|
||||
markId(worker: WorkerLike): number;
|
||||
returnWorkerToPool(worker: WorkerLike): void;
|
||||
loadWasmModuleToWorker(worker: WorkerLike, sab?: Int32Array): Promise<WorkerLike>;
|
||||
allocateUnusedWorker(): WorkerLike;
|
||||
getNewWorker(sab?: Int32Array): WorkerLike | undefined;
|
||||
cleanThread(worker: WorkerLike, tid: number, force?: boolean): void;
|
||||
terminateWorker(worker: WorkerLike): void;
|
||||
terminateAllThreads(): void;
|
||||
addMessageEventListener(worker: WorkerLike, onMessage: (e: WorkerMessageEvent) => void): () => void;
|
||||
fireMessageEvent(worker: WorkerLike, e: WorkerMessageEvent): void;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare type ThreadManagerOptions = ThreadManagerOptionsMain | ThreadManagerOptionsChild;
|
||||
|
||||
/** @public */
|
||||
export declare interface ThreadManagerOptionsBase {
|
||||
printErr?: (message: string) => void;
|
||||
threadSpawn?: (startArg: number, errorOrTid?: number) => number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface ThreadManagerOptionsChild extends ThreadManagerOptionsBase {
|
||||
childThread: true;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface ThreadManagerOptionsMain extends ThreadManagerOptionsBase {
|
||||
beforeLoad?: (worker: WorkerLike) => any;
|
||||
reuseWorker?: boolean | number | ReuseWorkerOptions;
|
||||
onCreateWorker: WorkerFactory;
|
||||
childThread?: false;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare class ThreadMessageHandler {
|
||||
protected instance: WebAssembly.Instance | undefined;
|
||||
private messagesBeforeLoad;
|
||||
protected postMessage: (message: any) => void;
|
||||
protected onLoad?: (data: LoadPayload) => WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
|
||||
protected onError: (error: Error, type: WorkerMessageType) => void;
|
||||
constructor(options?: ThreadMessageHandlerOptions);
|
||||
/** @virtual */
|
||||
instantiate(data: LoadPayload): WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
|
||||
/** @virtual */
|
||||
handle(e: WorkerMessageEvent<MessageEventData<WorkerMessageType>>): void;
|
||||
private _load;
|
||||
private _start;
|
||||
protected _loaded(err: Error | null, source: WebAssembly.WebAssemblyInstantiatedSource | null, payload: LoadPayload): void;
|
||||
protected handleAfterLoad<E extends WorkerMessageEvent>(e: E, f: (e: E) => void): void;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface ThreadMessageHandlerOptions {
|
||||
onLoad?: (data: LoadPayload) => WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
|
||||
onError?: (error: Error, type: WorkerMessageType) => void;
|
||||
postMessage?: (message: any) => void;
|
||||
}
|
||||
|
||||
export declare const version: string;
|
||||
|
||||
/** @public */
|
||||
export declare interface WASIInstance {
|
||||
readonly wasiImport?: Record<string, any>;
|
||||
initialize(instance: object): void;
|
||||
start(instance: object): number;
|
||||
getImportObject?(): any;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare class WASIThreads {
|
||||
PThread: ThreadManager | undefined;
|
||||
private wasmMemory;
|
||||
private wasmInstance;
|
||||
private readonly threadSpawn;
|
||||
readonly childThread: boolean;
|
||||
private readonly postMessage;
|
||||
readonly wasi: WASIInstance;
|
||||
constructor(options: WASIThreadsOptions);
|
||||
getImportObject(): {
|
||||
wasi: WASIThreadsImports;
|
||||
};
|
||||
setup(wasmInstance: WebAssembly.Instance, wasmModule: WebAssembly.Module, wasmMemory?: WebAssembly.Memory): void;
|
||||
preloadWorkers(): Promise<WorkerLike[]>;
|
||||
/**
|
||||
* It's ok to call this method to a WASI command module.
|
||||
*
|
||||
* in child thread, must call this method instead of {@link WASIThreads.start} even if it's a WASI command module
|
||||
*
|
||||
* @returns A proxied WebAssembly instance if in child thread, other wise the original instance
|
||||
*/
|
||||
initialize(instance: WebAssembly.Instance, module: WebAssembly.Module, memory?: WebAssembly.Memory): WebAssembly.Instance;
|
||||
/**
|
||||
* Equivalent to calling {@link WASIThreads.initialize} and then calling {@link WASIInstance.start}
|
||||
* ```js
|
||||
* this.initialize(instance, module, memory)
|
||||
* this.wasi.start(instance)
|
||||
* ```
|
||||
*/
|
||||
start(instance: WebAssembly.Instance, module: WebAssembly.Module, memory?: WebAssembly.Memory): StartResult;
|
||||
terminateAllThreads(): void;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface WASIThreadsImports {
|
||||
'thread-spawn': (startArg: number, errorOrTid?: number) => number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare type WASIThreadsOptions = MainThreadOptions | ChildThreadOptions;
|
||||
|
||||
/** @public */
|
||||
export declare type WorkerFactory = (ctx: {
|
||||
type: string;
|
||||
name: string;
|
||||
}) => WorkerLike;
|
||||
|
||||
/** @public */
|
||||
export declare type WorkerLike = (Worker | Worker_2) & {
|
||||
whenLoaded?: Promise<WorkerLike>;
|
||||
loaded?: boolean;
|
||||
__emnapi_tid?: number;
|
||||
};
|
||||
|
||||
/** @public */
|
||||
export declare interface WorkerMessageEvent<T = any> {
|
||||
data: T;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare type WorkerMessageType = 'load' | 'start';
|
||||
|
||||
export { }
|
||||
+1
File diff suppressed because one or more lines are too long
+420
@@ -0,0 +1,420 @@
|
||||
/// <reference types="node" />
|
||||
|
||||
import type { Context } from '@emnapi/runtime';
|
||||
import type { ReferenceOwnership } from '@emnapi/runtime';
|
||||
import type { Worker as Worker_2 } from 'worker_threads';
|
||||
|
||||
/** @public */
|
||||
export declare type BaseCreateOptions = {
|
||||
filename?: string
|
||||
nodeBinding?: NodeBinding
|
||||
reuseWorker?: ThreadManagerOptionsMain['reuseWorker']
|
||||
asyncWorkPoolSize?: number
|
||||
waitThreadStart?: MainThreadBaseOptions['waitThreadStart']
|
||||
onCreateWorker?: (info: CreateWorkerInfo) => any
|
||||
print?: (str: string) => void
|
||||
printErr?: (str: string) => void
|
||||
postMessage?: (msg: any) => any
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface BaseOptions {
|
||||
wasi: WASIInstance;
|
||||
version?: 'preview1';
|
||||
wasm64?: boolean;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface ChildThreadOptions extends BaseOptions {
|
||||
childThread: true;
|
||||
postMessage?: (data: any) => void;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface CleanupThreadPayload {
|
||||
tid: number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface CommandInfo<T extends CommandType> {
|
||||
type: T;
|
||||
payload: CommandPayloadMap[T];
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface CommandPayloadMap {
|
||||
load: LoadPayload;
|
||||
loaded: LoadedPayload;
|
||||
start: StartPayload;
|
||||
'cleanup-thread': CleanupThreadPayload;
|
||||
'terminate-all-threads': TerminateAllThreadsPayload;
|
||||
'spawn-thread': SpawnThreadPayload;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare type CommandType = keyof CommandPayloadMap;
|
||||
|
||||
/** @public */
|
||||
export declare function createInstanceProxy(instance: WebAssembly.Instance, memory?: WebAssembly.Memory | (() => WebAssembly.Memory)): WebAssembly.Instance;
|
||||
|
||||
/** @public */
|
||||
export declare function createNapiModule (
|
||||
options: CreateOptions
|
||||
): NapiModule
|
||||
|
||||
/** @public */
|
||||
export declare type CreateOptions = BaseCreateOptions & ({
|
||||
context: Context
|
||||
childThread?: boolean
|
||||
} | {
|
||||
context?: Context
|
||||
childThread: true
|
||||
})
|
||||
|
||||
/** @public */
|
||||
export declare interface CreateWorkerInfo {
|
||||
type: 'thread' | 'async-work'
|
||||
name: string
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface InitOptions {
|
||||
instance: WebAssembly.Instance
|
||||
module: WebAssembly.Module
|
||||
memory?: WebAssembly.Memory
|
||||
table?: WebAssembly.Table
|
||||
}
|
||||
|
||||
export declare type InputType = string | URL | Response | BufferSource | WebAssembly.Module;
|
||||
|
||||
/** @public */
|
||||
export declare interface InstantiatedSource extends LoadedSource {
|
||||
napiModule: NapiModule;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare function instantiateNapiModule(
|
||||
/** Only support `BufferSource` or `WebAssembly.Module` on Node.js */
|
||||
wasmInput: InputType | Promise<InputType>, options: InstantiateOptions): Promise<InstantiatedSource>;
|
||||
|
||||
/** @public */
|
||||
export declare function instantiateNapiModuleSync(wasmInput: BufferSource | WebAssembly.Module, options: InstantiateOptions): InstantiatedSource;
|
||||
|
||||
/** @public */
|
||||
export declare type InstantiateOptions = CreateOptions & LoadOptions;
|
||||
|
||||
/** @public */
|
||||
export declare function isSharedArrayBuffer(value: any): value is SharedArrayBuffer;
|
||||
|
||||
/** @public */
|
||||
export declare function isTrapError(e: Error): e is WebAssembly.RuntimeError;
|
||||
|
||||
/** @public */
|
||||
export declare interface LoadedPayload {
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface LoadedSource extends WebAssembly.WebAssemblyInstantiatedSource {
|
||||
usedInstance: WebAssembly.Instance;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare function loadNapiModule(napiModule: NapiModule,
|
||||
/** Only support `BufferSource` or `WebAssembly.Module` on Node.js */
|
||||
wasmInput: InputType | Promise<InputType>, options?: LoadOptions): Promise<LoadedSource>;
|
||||
|
||||
/** @public */
|
||||
export declare function loadNapiModuleSync(napiModule: NapiModule, wasmInput: BufferSource | WebAssembly.Module, options?: LoadOptions): LoadedSource;
|
||||
|
||||
/** @public */
|
||||
export declare interface LoadOptions {
|
||||
wasi?: WASIInstance;
|
||||
overwriteImports?: (importObject: WebAssembly.Imports) => WebAssembly.Imports;
|
||||
beforeInit?: (source: WebAssembly.WebAssemblyInstantiatedSource) => void;
|
||||
getMemory?: (exports: WebAssembly.Exports) => WebAssembly.Memory;
|
||||
getTable?: (exports: WebAssembly.Exports) => WebAssembly.Table;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface LoadPayload {
|
||||
wasmModule: WebAssembly.Module;
|
||||
wasmMemory: WebAssembly.Memory;
|
||||
sab?: Int32Array;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface MainThreadBaseOptions extends BaseOptions {
|
||||
waitThreadStart?: boolean | number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare type MainThreadOptions = MainThreadOptionsWithThreadManager | MainThreadOptionsCreateThreadManager;
|
||||
|
||||
/** @public */
|
||||
export declare interface MainThreadOptionsCreateThreadManager extends MainThreadBaseOptions, ThreadManagerOptionsMain {
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface MainThreadOptionsWithThreadManager extends MainThreadBaseOptions {
|
||||
threadManager?: ThreadManager | (() => ThreadManager);
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface MessageEventData<T extends CommandType> {
|
||||
__emnapi__: CommandInfo<T>;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare class MessageHandler extends ThreadMessageHandler {
|
||||
napiModule: NapiModule | undefined;
|
||||
constructor(options: MessageHandlerOptions);
|
||||
instantiate(data: LoadPayload): InstantiatedSource | PromiseLike<InstantiatedSource>;
|
||||
handle(e: WorkerMessageEvent): void;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface MessageHandlerOptions extends ThreadMessageHandlerOptions {
|
||||
onLoad: (data: LoadPayload) => InstantiatedSource | PromiseLike<InstantiatedSource>;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface NapiModule {
|
||||
imports: {
|
||||
env: any
|
||||
napi: any
|
||||
emnapi: any
|
||||
}
|
||||
exports: any
|
||||
loaded: boolean
|
||||
filename: string
|
||||
childThread: boolean
|
||||
emnapi: {
|
||||
syncMemory<T extends ArrayBuffer | ArrayBufferView> (
|
||||
js_to_wasm: boolean,
|
||||
arrayBufferOrView: T,
|
||||
offset?: number,
|
||||
len?: number
|
||||
): T
|
||||
getMemoryAddress (arrayBufferOrView: ArrayBuffer | ArrayBufferView): PointerInfo
|
||||
addSendListener (worker: any): boolean
|
||||
}
|
||||
|
||||
init (options: InitOptions): any
|
||||
initWorker (arg: number, func: [number, number]): void
|
||||
postMessage?: (msg: any) => any
|
||||
|
||||
waitThreadStart: boolean | number
|
||||
/* Excluded from this release type: PThread */}
|
||||
|
||||
/** @public */
|
||||
export declare interface NodeBinding {
|
||||
node: {
|
||||
emitAsyncInit: Function
|
||||
emitAsyncDestroy: Function
|
||||
makeCallback: Function
|
||||
}
|
||||
napi: {
|
||||
asyncInit: Function
|
||||
asyncDestroy: Function
|
||||
makeCallback: Function
|
||||
}
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface PointerInfo {
|
||||
address: number
|
||||
ownership: ReferenceOwnership
|
||||
runtimeAllocated: 0 | 1
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface ReuseWorkerOptions {
|
||||
/**
|
||||
* @see {@link https://emscripten.org/docs/tools_reference/settings_reference.html#pthread-pool-size | PTHREAD_POOL_SIZE}
|
||||
*/
|
||||
size: number;
|
||||
/**
|
||||
* @see {@link https://emscripten.org/docs/tools_reference/settings_reference.html#pthread-pool-size-strict | PTHREAD_POOL_SIZE_STRICT}
|
||||
*/
|
||||
strict?: boolean;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface SpawnThreadPayload {
|
||||
startArg: number;
|
||||
errorOrTid: number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface StartPayload {
|
||||
tid: number;
|
||||
arg: number;
|
||||
sab?: Int32Array;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface StartResult {
|
||||
exitCode: number;
|
||||
instance: WebAssembly.Instance;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface TerminateAllThreadsPayload {
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare class ThreadManager {
|
||||
unusedWorkers: WorkerLike[];
|
||||
runningWorkers: WorkerLike[];
|
||||
pthreads: Record<number, WorkerLike>;
|
||||
get nextWorkerID(): number;
|
||||
wasmModule: WebAssembly.Module | null;
|
||||
wasmMemory: WebAssembly.Memory | null;
|
||||
private readonly messageEvents;
|
||||
private readonly _childThread;
|
||||
private readonly _onCreateWorker;
|
||||
private readonly _reuseWorker;
|
||||
private readonly _beforeLoad?;
|
||||
/* Excluded from this release type: printErr */
|
||||
threadSpawn?: ((startArg: number, errorOrTid?: number) => number);
|
||||
constructor(options: ThreadManagerOptions);
|
||||
init(): void;
|
||||
initMainThread(): void;
|
||||
private preparePool;
|
||||
shouldPreloadWorkers(): boolean;
|
||||
loadWasmModuleToAllWorkers(): Promise<WorkerLike[]>;
|
||||
preloadWorkers(): Promise<WorkerLike[]>;
|
||||
setup(wasmModule: WebAssembly.Module, wasmMemory: WebAssembly.Memory): void;
|
||||
markId(worker: WorkerLike): number;
|
||||
returnWorkerToPool(worker: WorkerLike): void;
|
||||
loadWasmModuleToWorker(worker: WorkerLike, sab?: Int32Array): Promise<WorkerLike>;
|
||||
allocateUnusedWorker(): WorkerLike;
|
||||
getNewWorker(sab?: Int32Array): WorkerLike | undefined;
|
||||
cleanThread(worker: WorkerLike, tid: number, force?: boolean): void;
|
||||
terminateWorker(worker: WorkerLike): void;
|
||||
terminateAllThreads(): void;
|
||||
addMessageEventListener(worker: WorkerLike, onMessage: (e: WorkerMessageEvent) => void): () => void;
|
||||
fireMessageEvent(worker: WorkerLike, e: WorkerMessageEvent): void;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare type ThreadManagerOptions = ThreadManagerOptionsMain | ThreadManagerOptionsChild;
|
||||
|
||||
/** @public */
|
||||
export declare interface ThreadManagerOptionsBase {
|
||||
printErr?: (message: string) => void;
|
||||
threadSpawn?: (startArg: number, errorOrTid?: number) => number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface ThreadManagerOptionsChild extends ThreadManagerOptionsBase {
|
||||
childThread: true;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface ThreadManagerOptionsMain extends ThreadManagerOptionsBase {
|
||||
beforeLoad?: (worker: WorkerLike) => any;
|
||||
reuseWorker?: boolean | number | ReuseWorkerOptions;
|
||||
onCreateWorker: WorkerFactory;
|
||||
childThread?: false;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare class ThreadMessageHandler {
|
||||
protected instance: WebAssembly.Instance | undefined;
|
||||
private messagesBeforeLoad;
|
||||
protected postMessage: (message: any) => void;
|
||||
protected onLoad?: (data: LoadPayload) => WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
|
||||
protected onError: (error: Error, type: WorkerMessageType) => void;
|
||||
constructor(options?: ThreadMessageHandlerOptions);
|
||||
/** @virtual */
|
||||
instantiate(data: LoadPayload): WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
|
||||
/** @virtual */
|
||||
handle(e: WorkerMessageEvent<MessageEventData<WorkerMessageType>>): void;
|
||||
private _load;
|
||||
private _start;
|
||||
protected _loaded(err: Error | null, source: WebAssembly.WebAssemblyInstantiatedSource | null, payload: LoadPayload): void;
|
||||
protected handleAfterLoad<E extends WorkerMessageEvent>(e: E, f: (e: E) => void): void;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface ThreadMessageHandlerOptions {
|
||||
onLoad?: (data: LoadPayload) => WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
|
||||
onError?: (error: Error, type: WorkerMessageType) => void;
|
||||
postMessage?: (message: any) => void;
|
||||
}
|
||||
|
||||
export declare const version: string;
|
||||
|
||||
/** @public */
|
||||
export declare interface WASIInstance {
|
||||
readonly wasiImport?: Record<string, any>;
|
||||
initialize(instance: object): void;
|
||||
start(instance: object): number;
|
||||
getImportObject?(): any;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare class WASIThreads {
|
||||
PThread: ThreadManager | undefined;
|
||||
private wasmMemory;
|
||||
private wasmInstance;
|
||||
private readonly threadSpawn;
|
||||
readonly childThread: boolean;
|
||||
private readonly postMessage;
|
||||
readonly wasi: WASIInstance;
|
||||
constructor(options: WASIThreadsOptions);
|
||||
getImportObject(): {
|
||||
wasi: WASIThreadsImports;
|
||||
};
|
||||
setup(wasmInstance: WebAssembly.Instance, wasmModule: WebAssembly.Module, wasmMemory?: WebAssembly.Memory): void;
|
||||
preloadWorkers(): Promise<WorkerLike[]>;
|
||||
/**
|
||||
* It's ok to call this method to a WASI command module.
|
||||
*
|
||||
* in child thread, must call this method instead of {@link WASIThreads.start} even if it's a WASI command module
|
||||
*
|
||||
* @returns A proxied WebAssembly instance if in child thread, other wise the original instance
|
||||
*/
|
||||
initialize(instance: WebAssembly.Instance, module: WebAssembly.Module, memory?: WebAssembly.Memory): WebAssembly.Instance;
|
||||
/**
|
||||
* Equivalent to calling {@link WASIThreads.initialize} and then calling {@link WASIInstance.start}
|
||||
* ```js
|
||||
* this.initialize(instance, module, memory)
|
||||
* this.wasi.start(instance)
|
||||
* ```
|
||||
*/
|
||||
start(instance: WebAssembly.Instance, module: WebAssembly.Module, memory?: WebAssembly.Memory): StartResult;
|
||||
terminateAllThreads(): void;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface WASIThreadsImports {
|
||||
'thread-spawn': (startArg: number, errorOrTid?: number) => number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare type WASIThreadsOptions = MainThreadOptions | ChildThreadOptions;
|
||||
|
||||
/** @public */
|
||||
export declare type WorkerFactory = (ctx: {
|
||||
type: string;
|
||||
name: string;
|
||||
}) => WorkerLike;
|
||||
|
||||
/** @public */
|
||||
export declare type WorkerLike = (Worker | Worker_2) & {
|
||||
whenLoaded?: Promise<WorkerLike>;
|
||||
loaded?: boolean;
|
||||
__emnapi_tid?: number;
|
||||
};
|
||||
|
||||
/** @public */
|
||||
export declare interface WorkerMessageEvent<T = any> {
|
||||
data: T;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare type WorkerMessageType = 'load' | 'start';
|
||||
|
||||
export { }
|
||||
+422
@@ -0,0 +1,422 @@
|
||||
/// <reference types="node" />
|
||||
|
||||
import type { Context } from '@emnapi/runtime';
|
||||
import type { ReferenceOwnership } from '@emnapi/runtime';
|
||||
import type { Worker as Worker_2 } from 'worker_threads';
|
||||
|
||||
/** @public */
|
||||
export declare type BaseCreateOptions = {
|
||||
filename?: string
|
||||
nodeBinding?: NodeBinding
|
||||
reuseWorker?: ThreadManagerOptionsMain['reuseWorker']
|
||||
asyncWorkPoolSize?: number
|
||||
waitThreadStart?: MainThreadBaseOptions['waitThreadStart']
|
||||
onCreateWorker?: (info: CreateWorkerInfo) => any
|
||||
print?: (str: string) => void
|
||||
printErr?: (str: string) => void
|
||||
postMessage?: (msg: any) => any
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface BaseOptions {
|
||||
wasi: WASIInstance;
|
||||
version?: 'preview1';
|
||||
wasm64?: boolean;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface ChildThreadOptions extends BaseOptions {
|
||||
childThread: true;
|
||||
postMessage?: (data: any) => void;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface CleanupThreadPayload {
|
||||
tid: number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface CommandInfo<T extends CommandType> {
|
||||
type: T;
|
||||
payload: CommandPayloadMap[T];
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface CommandPayloadMap {
|
||||
load: LoadPayload;
|
||||
loaded: LoadedPayload;
|
||||
start: StartPayload;
|
||||
'cleanup-thread': CleanupThreadPayload;
|
||||
'terminate-all-threads': TerminateAllThreadsPayload;
|
||||
'spawn-thread': SpawnThreadPayload;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare type CommandType = keyof CommandPayloadMap;
|
||||
|
||||
/** @public */
|
||||
export declare function createInstanceProxy(instance: WebAssembly.Instance, memory?: WebAssembly.Memory | (() => WebAssembly.Memory)): WebAssembly.Instance;
|
||||
|
||||
/** @public */
|
||||
export declare function createNapiModule (
|
||||
options: CreateOptions
|
||||
): NapiModule
|
||||
|
||||
/** @public */
|
||||
export declare type CreateOptions = BaseCreateOptions & ({
|
||||
context: Context
|
||||
childThread?: boolean
|
||||
} | {
|
||||
context?: Context
|
||||
childThread: true
|
||||
})
|
||||
|
||||
/** @public */
|
||||
export declare interface CreateWorkerInfo {
|
||||
type: 'thread' | 'async-work'
|
||||
name: string
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface InitOptions {
|
||||
instance: WebAssembly.Instance
|
||||
module: WebAssembly.Module
|
||||
memory?: WebAssembly.Memory
|
||||
table?: WebAssembly.Table
|
||||
}
|
||||
|
||||
export declare type InputType = string | URL | Response | BufferSource | WebAssembly.Module;
|
||||
|
||||
/** @public */
|
||||
export declare interface InstantiatedSource extends LoadedSource {
|
||||
napiModule: NapiModule;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare function instantiateNapiModule(
|
||||
/** Only support `BufferSource` or `WebAssembly.Module` on Node.js */
|
||||
wasmInput: InputType | Promise<InputType>, options: InstantiateOptions): Promise<InstantiatedSource>;
|
||||
|
||||
/** @public */
|
||||
export declare function instantiateNapiModuleSync(wasmInput: BufferSource | WebAssembly.Module, options: InstantiateOptions): InstantiatedSource;
|
||||
|
||||
/** @public */
|
||||
export declare type InstantiateOptions = CreateOptions & LoadOptions;
|
||||
|
||||
/** @public */
|
||||
export declare function isSharedArrayBuffer(value: any): value is SharedArrayBuffer;
|
||||
|
||||
/** @public */
|
||||
export declare function isTrapError(e: Error): e is WebAssembly.RuntimeError;
|
||||
|
||||
/** @public */
|
||||
export declare interface LoadedPayload {
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface LoadedSource extends WebAssembly.WebAssemblyInstantiatedSource {
|
||||
usedInstance: WebAssembly.Instance;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare function loadNapiModule(napiModule: NapiModule,
|
||||
/** Only support `BufferSource` or `WebAssembly.Module` on Node.js */
|
||||
wasmInput: InputType | Promise<InputType>, options?: LoadOptions): Promise<LoadedSource>;
|
||||
|
||||
/** @public */
|
||||
export declare function loadNapiModuleSync(napiModule: NapiModule, wasmInput: BufferSource | WebAssembly.Module, options?: LoadOptions): LoadedSource;
|
||||
|
||||
/** @public */
|
||||
export declare interface LoadOptions {
|
||||
wasi?: WASIInstance;
|
||||
overwriteImports?: (importObject: WebAssembly.Imports) => WebAssembly.Imports;
|
||||
beforeInit?: (source: WebAssembly.WebAssemblyInstantiatedSource) => void;
|
||||
getMemory?: (exports: WebAssembly.Exports) => WebAssembly.Memory;
|
||||
getTable?: (exports: WebAssembly.Exports) => WebAssembly.Table;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface LoadPayload {
|
||||
wasmModule: WebAssembly.Module;
|
||||
wasmMemory: WebAssembly.Memory;
|
||||
sab?: Int32Array;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface MainThreadBaseOptions extends BaseOptions {
|
||||
waitThreadStart?: boolean | number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare type MainThreadOptions = MainThreadOptionsWithThreadManager | MainThreadOptionsCreateThreadManager;
|
||||
|
||||
/** @public */
|
||||
export declare interface MainThreadOptionsCreateThreadManager extends MainThreadBaseOptions, ThreadManagerOptionsMain {
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface MainThreadOptionsWithThreadManager extends MainThreadBaseOptions {
|
||||
threadManager?: ThreadManager | (() => ThreadManager);
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface MessageEventData<T extends CommandType> {
|
||||
__emnapi__: CommandInfo<T>;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare class MessageHandler extends ThreadMessageHandler {
|
||||
napiModule: NapiModule | undefined;
|
||||
constructor(options: MessageHandlerOptions);
|
||||
instantiate(data: LoadPayload): InstantiatedSource | PromiseLike<InstantiatedSource>;
|
||||
handle(e: WorkerMessageEvent): void;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface MessageHandlerOptions extends ThreadMessageHandlerOptions {
|
||||
onLoad: (data: LoadPayload) => InstantiatedSource | PromiseLike<InstantiatedSource>;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface NapiModule {
|
||||
imports: {
|
||||
env: any
|
||||
napi: any
|
||||
emnapi: any
|
||||
}
|
||||
exports: any
|
||||
loaded: boolean
|
||||
filename: string
|
||||
childThread: boolean
|
||||
emnapi: {
|
||||
syncMemory<T extends ArrayBuffer | ArrayBufferView> (
|
||||
js_to_wasm: boolean,
|
||||
arrayBufferOrView: T,
|
||||
offset?: number,
|
||||
len?: number
|
||||
): T
|
||||
getMemoryAddress (arrayBufferOrView: ArrayBuffer | ArrayBufferView): PointerInfo
|
||||
addSendListener (worker: any): boolean
|
||||
}
|
||||
|
||||
init (options: InitOptions): any
|
||||
initWorker (arg: number, func: [number, number]): void
|
||||
postMessage?: (msg: any) => any
|
||||
|
||||
waitThreadStart: boolean | number
|
||||
/* Excluded from this release type: PThread */}
|
||||
|
||||
/** @public */
|
||||
export declare interface NodeBinding {
|
||||
node: {
|
||||
emitAsyncInit: Function
|
||||
emitAsyncDestroy: Function
|
||||
makeCallback: Function
|
||||
}
|
||||
napi: {
|
||||
asyncInit: Function
|
||||
asyncDestroy: Function
|
||||
makeCallback: Function
|
||||
}
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface PointerInfo {
|
||||
address: number
|
||||
ownership: ReferenceOwnership
|
||||
runtimeAllocated: 0 | 1
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface ReuseWorkerOptions {
|
||||
/**
|
||||
* @see {@link https://emscripten.org/docs/tools_reference/settings_reference.html#pthread-pool-size | PTHREAD_POOL_SIZE}
|
||||
*/
|
||||
size: number;
|
||||
/**
|
||||
* @see {@link https://emscripten.org/docs/tools_reference/settings_reference.html#pthread-pool-size-strict | PTHREAD_POOL_SIZE_STRICT}
|
||||
*/
|
||||
strict?: boolean;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface SpawnThreadPayload {
|
||||
startArg: number;
|
||||
errorOrTid: number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface StartPayload {
|
||||
tid: number;
|
||||
arg: number;
|
||||
sab?: Int32Array;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface StartResult {
|
||||
exitCode: number;
|
||||
instance: WebAssembly.Instance;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface TerminateAllThreadsPayload {
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare class ThreadManager {
|
||||
unusedWorkers: WorkerLike[];
|
||||
runningWorkers: WorkerLike[];
|
||||
pthreads: Record<number, WorkerLike>;
|
||||
get nextWorkerID(): number;
|
||||
wasmModule: WebAssembly.Module | null;
|
||||
wasmMemory: WebAssembly.Memory | null;
|
||||
private readonly messageEvents;
|
||||
private readonly _childThread;
|
||||
private readonly _onCreateWorker;
|
||||
private readonly _reuseWorker;
|
||||
private readonly _beforeLoad?;
|
||||
/* Excluded from this release type: printErr */
|
||||
threadSpawn?: ((startArg: number, errorOrTid?: number) => number);
|
||||
constructor(options: ThreadManagerOptions);
|
||||
init(): void;
|
||||
initMainThread(): void;
|
||||
private preparePool;
|
||||
shouldPreloadWorkers(): boolean;
|
||||
loadWasmModuleToAllWorkers(): Promise<WorkerLike[]>;
|
||||
preloadWorkers(): Promise<WorkerLike[]>;
|
||||
setup(wasmModule: WebAssembly.Module, wasmMemory: WebAssembly.Memory): void;
|
||||
markId(worker: WorkerLike): number;
|
||||
returnWorkerToPool(worker: WorkerLike): void;
|
||||
loadWasmModuleToWorker(worker: WorkerLike, sab?: Int32Array): Promise<WorkerLike>;
|
||||
allocateUnusedWorker(): WorkerLike;
|
||||
getNewWorker(sab?: Int32Array): WorkerLike | undefined;
|
||||
cleanThread(worker: WorkerLike, tid: number, force?: boolean): void;
|
||||
terminateWorker(worker: WorkerLike): void;
|
||||
terminateAllThreads(): void;
|
||||
addMessageEventListener(worker: WorkerLike, onMessage: (e: WorkerMessageEvent) => void): () => void;
|
||||
fireMessageEvent(worker: WorkerLike, e: WorkerMessageEvent): void;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare type ThreadManagerOptions = ThreadManagerOptionsMain | ThreadManagerOptionsChild;
|
||||
|
||||
/** @public */
|
||||
export declare interface ThreadManagerOptionsBase {
|
||||
printErr?: (message: string) => void;
|
||||
threadSpawn?: (startArg: number, errorOrTid?: number) => number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface ThreadManagerOptionsChild extends ThreadManagerOptionsBase {
|
||||
childThread: true;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface ThreadManagerOptionsMain extends ThreadManagerOptionsBase {
|
||||
beforeLoad?: (worker: WorkerLike) => any;
|
||||
reuseWorker?: boolean | number | ReuseWorkerOptions;
|
||||
onCreateWorker: WorkerFactory;
|
||||
childThread?: false;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare class ThreadMessageHandler {
|
||||
protected instance: WebAssembly.Instance | undefined;
|
||||
private messagesBeforeLoad;
|
||||
protected postMessage: (message: any) => void;
|
||||
protected onLoad?: (data: LoadPayload) => WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
|
||||
protected onError: (error: Error, type: WorkerMessageType) => void;
|
||||
constructor(options?: ThreadMessageHandlerOptions);
|
||||
/** @virtual */
|
||||
instantiate(data: LoadPayload): WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
|
||||
/** @virtual */
|
||||
handle(e: WorkerMessageEvent<MessageEventData<WorkerMessageType>>): void;
|
||||
private _load;
|
||||
private _start;
|
||||
protected _loaded(err: Error | null, source: WebAssembly.WebAssemblyInstantiatedSource | null, payload: LoadPayload): void;
|
||||
protected handleAfterLoad<E extends WorkerMessageEvent>(e: E, f: (e: E) => void): void;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface ThreadMessageHandlerOptions {
|
||||
onLoad?: (data: LoadPayload) => WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
|
||||
onError?: (error: Error, type: WorkerMessageType) => void;
|
||||
postMessage?: (message: any) => void;
|
||||
}
|
||||
|
||||
export declare const version: string;
|
||||
|
||||
/** @public */
|
||||
export declare interface WASIInstance {
|
||||
readonly wasiImport?: Record<string, any>;
|
||||
initialize(instance: object): void;
|
||||
start(instance: object): number;
|
||||
getImportObject?(): any;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare class WASIThreads {
|
||||
PThread: ThreadManager | undefined;
|
||||
private wasmMemory;
|
||||
private wasmInstance;
|
||||
private readonly threadSpawn;
|
||||
readonly childThread: boolean;
|
||||
private readonly postMessage;
|
||||
readonly wasi: WASIInstance;
|
||||
constructor(options: WASIThreadsOptions);
|
||||
getImportObject(): {
|
||||
wasi: WASIThreadsImports;
|
||||
};
|
||||
setup(wasmInstance: WebAssembly.Instance, wasmModule: WebAssembly.Module, wasmMemory?: WebAssembly.Memory): void;
|
||||
preloadWorkers(): Promise<WorkerLike[]>;
|
||||
/**
|
||||
* It's ok to call this method to a WASI command module.
|
||||
*
|
||||
* in child thread, must call this method instead of {@link WASIThreads.start} even if it's a WASI command module
|
||||
*
|
||||
* @returns A proxied WebAssembly instance if in child thread, other wise the original instance
|
||||
*/
|
||||
initialize(instance: WebAssembly.Instance, module: WebAssembly.Module, memory?: WebAssembly.Memory): WebAssembly.Instance;
|
||||
/**
|
||||
* Equivalent to calling {@link WASIThreads.initialize} and then calling {@link WASIInstance.start}
|
||||
* ```js
|
||||
* this.initialize(instance, module, memory)
|
||||
* this.wasi.start(instance)
|
||||
* ```
|
||||
*/
|
||||
start(instance: WebAssembly.Instance, module: WebAssembly.Module, memory?: WebAssembly.Memory): StartResult;
|
||||
terminateAllThreads(): void;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface WASIThreadsImports {
|
||||
'thread-spawn': (startArg: number, errorOrTid?: number) => number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare type WASIThreadsOptions = MainThreadOptions | ChildThreadOptions;
|
||||
|
||||
/** @public */
|
||||
export declare type WorkerFactory = (ctx: {
|
||||
type: string;
|
||||
name: string;
|
||||
}) => WorkerLike;
|
||||
|
||||
/** @public */
|
||||
export declare type WorkerLike = (Worker | Worker_2) & {
|
||||
whenLoaded?: Promise<WorkerLike>;
|
||||
loaded?: boolean;
|
||||
__emnapi_tid?: number;
|
||||
};
|
||||
|
||||
/** @public */
|
||||
export declare interface WorkerMessageEvent<T = any> {
|
||||
data: T;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare type WorkerMessageType = 'load' | 'start';
|
||||
|
||||
export { }
|
||||
|
||||
export as namespace emnapiCore;
|
||||
+8228
File diff suppressed because it is too large
Load Diff
+9231
File diff suppressed because it is too large
Load Diff
+420
@@ -0,0 +1,420 @@
|
||||
/// <reference types="node" />
|
||||
|
||||
import type { Context } from '@emnapi/runtime';
|
||||
import type { ReferenceOwnership } from '@emnapi/runtime';
|
||||
import type { Worker as Worker_2 } from 'worker_threads';
|
||||
|
||||
/** @public */
|
||||
export declare type BaseCreateOptions = {
|
||||
filename?: string
|
||||
nodeBinding?: NodeBinding
|
||||
reuseWorker?: ThreadManagerOptionsMain['reuseWorker']
|
||||
asyncWorkPoolSize?: number
|
||||
waitThreadStart?: MainThreadBaseOptions['waitThreadStart']
|
||||
onCreateWorker?: (info: CreateWorkerInfo) => any
|
||||
print?: (str: string) => void
|
||||
printErr?: (str: string) => void
|
||||
postMessage?: (msg: any) => any
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface BaseOptions {
|
||||
wasi: WASIInstance;
|
||||
version?: 'preview1';
|
||||
wasm64?: boolean;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface ChildThreadOptions extends BaseOptions {
|
||||
childThread: true;
|
||||
postMessage?: (data: any) => void;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface CleanupThreadPayload {
|
||||
tid: number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface CommandInfo<T extends CommandType> {
|
||||
type: T;
|
||||
payload: CommandPayloadMap[T];
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface CommandPayloadMap {
|
||||
load: LoadPayload;
|
||||
loaded: LoadedPayload;
|
||||
start: StartPayload;
|
||||
'cleanup-thread': CleanupThreadPayload;
|
||||
'terminate-all-threads': TerminateAllThreadsPayload;
|
||||
'spawn-thread': SpawnThreadPayload;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare type CommandType = keyof CommandPayloadMap;
|
||||
|
||||
/** @public */
|
||||
export declare function createInstanceProxy(instance: WebAssembly.Instance, memory?: WebAssembly.Memory | (() => WebAssembly.Memory)): WebAssembly.Instance;
|
||||
|
||||
/** @public */
|
||||
export declare function createNapiModule (
|
||||
options: CreateOptions
|
||||
): NapiModule
|
||||
|
||||
/** @public */
|
||||
export declare type CreateOptions = BaseCreateOptions & ({
|
||||
context: Context
|
||||
childThread?: boolean
|
||||
} | {
|
||||
context?: Context
|
||||
childThread: true
|
||||
})
|
||||
|
||||
/** @public */
|
||||
export declare interface CreateWorkerInfo {
|
||||
type: 'thread' | 'async-work'
|
||||
name: string
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface InitOptions {
|
||||
instance: WebAssembly.Instance
|
||||
module: WebAssembly.Module
|
||||
memory?: WebAssembly.Memory
|
||||
table?: WebAssembly.Table
|
||||
}
|
||||
|
||||
export declare type InputType = string | URL | Response | BufferSource | WebAssembly.Module;
|
||||
|
||||
/** @public */
|
||||
export declare interface InstantiatedSource extends LoadedSource {
|
||||
napiModule: NapiModule;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare function instantiateNapiModule(
|
||||
/** Only support `BufferSource` or `WebAssembly.Module` on Node.js */
|
||||
wasmInput: InputType | Promise<InputType>, options: InstantiateOptions): Promise<InstantiatedSource>;
|
||||
|
||||
/** @public */
|
||||
export declare function instantiateNapiModuleSync(wasmInput: BufferSource | WebAssembly.Module, options: InstantiateOptions): InstantiatedSource;
|
||||
|
||||
/** @public */
|
||||
export declare type InstantiateOptions = CreateOptions & LoadOptions;
|
||||
|
||||
/** @public */
|
||||
export declare function isSharedArrayBuffer(value: any): value is SharedArrayBuffer;
|
||||
|
||||
/** @public */
|
||||
export declare function isTrapError(e: Error): e is WebAssembly.RuntimeError;
|
||||
|
||||
/** @public */
|
||||
export declare interface LoadedPayload {
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface LoadedSource extends WebAssembly.WebAssemblyInstantiatedSource {
|
||||
usedInstance: WebAssembly.Instance;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare function loadNapiModule(napiModule: NapiModule,
|
||||
/** Only support `BufferSource` or `WebAssembly.Module` on Node.js */
|
||||
wasmInput: InputType | Promise<InputType>, options?: LoadOptions): Promise<LoadedSource>;
|
||||
|
||||
/** @public */
|
||||
export declare function loadNapiModuleSync(napiModule: NapiModule, wasmInput: BufferSource | WebAssembly.Module, options?: LoadOptions): LoadedSource;
|
||||
|
||||
/** @public */
|
||||
export declare interface LoadOptions {
|
||||
wasi?: WASIInstance;
|
||||
overwriteImports?: (importObject: WebAssembly.Imports) => WebAssembly.Imports;
|
||||
beforeInit?: (source: WebAssembly.WebAssemblyInstantiatedSource) => void;
|
||||
getMemory?: (exports: WebAssembly.Exports) => WebAssembly.Memory;
|
||||
getTable?: (exports: WebAssembly.Exports) => WebAssembly.Table;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface LoadPayload {
|
||||
wasmModule: WebAssembly.Module;
|
||||
wasmMemory: WebAssembly.Memory;
|
||||
sab?: Int32Array;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface MainThreadBaseOptions extends BaseOptions {
|
||||
waitThreadStart?: boolean | number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare type MainThreadOptions = MainThreadOptionsWithThreadManager | MainThreadOptionsCreateThreadManager;
|
||||
|
||||
/** @public */
|
||||
export declare interface MainThreadOptionsCreateThreadManager extends MainThreadBaseOptions, ThreadManagerOptionsMain {
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface MainThreadOptionsWithThreadManager extends MainThreadBaseOptions {
|
||||
threadManager?: ThreadManager | (() => ThreadManager);
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface MessageEventData<T extends CommandType> {
|
||||
__emnapi__: CommandInfo<T>;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare class MessageHandler extends ThreadMessageHandler {
|
||||
napiModule: NapiModule | undefined;
|
||||
constructor(options: MessageHandlerOptions);
|
||||
instantiate(data: LoadPayload): InstantiatedSource | PromiseLike<InstantiatedSource>;
|
||||
handle(e: WorkerMessageEvent): void;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface MessageHandlerOptions extends ThreadMessageHandlerOptions {
|
||||
onLoad: (data: LoadPayload) => InstantiatedSource | PromiseLike<InstantiatedSource>;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface NapiModule {
|
||||
imports: {
|
||||
env: any
|
||||
napi: any
|
||||
emnapi: any
|
||||
}
|
||||
exports: any
|
||||
loaded: boolean
|
||||
filename: string
|
||||
childThread: boolean
|
||||
emnapi: {
|
||||
syncMemory<T extends ArrayBuffer | ArrayBufferView> (
|
||||
js_to_wasm: boolean,
|
||||
arrayBufferOrView: T,
|
||||
offset?: number,
|
||||
len?: number
|
||||
): T
|
||||
getMemoryAddress (arrayBufferOrView: ArrayBuffer | ArrayBufferView): PointerInfo
|
||||
addSendListener (worker: any): boolean
|
||||
}
|
||||
|
||||
init (options: InitOptions): any
|
||||
initWorker (arg: number, func: [number, number]): void
|
||||
postMessage?: (msg: any) => any
|
||||
|
||||
waitThreadStart: boolean | number
|
||||
/* Excluded from this release type: PThread */}
|
||||
|
||||
/** @public */
|
||||
export declare interface NodeBinding {
|
||||
node: {
|
||||
emitAsyncInit: Function
|
||||
emitAsyncDestroy: Function
|
||||
makeCallback: Function
|
||||
}
|
||||
napi: {
|
||||
asyncInit: Function
|
||||
asyncDestroy: Function
|
||||
makeCallback: Function
|
||||
}
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface PointerInfo {
|
||||
address: number
|
||||
ownership: ReferenceOwnership
|
||||
runtimeAllocated: 0 | 1
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface ReuseWorkerOptions {
|
||||
/**
|
||||
* @see {@link https://emscripten.org/docs/tools_reference/settings_reference.html#pthread-pool-size | PTHREAD_POOL_SIZE}
|
||||
*/
|
||||
size: number;
|
||||
/**
|
||||
* @see {@link https://emscripten.org/docs/tools_reference/settings_reference.html#pthread-pool-size-strict | PTHREAD_POOL_SIZE_STRICT}
|
||||
*/
|
||||
strict?: boolean;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface SpawnThreadPayload {
|
||||
startArg: number;
|
||||
errorOrTid: number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface StartPayload {
|
||||
tid: number;
|
||||
arg: number;
|
||||
sab?: Int32Array;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface StartResult {
|
||||
exitCode: number;
|
||||
instance: WebAssembly.Instance;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface TerminateAllThreadsPayload {
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare class ThreadManager {
|
||||
unusedWorkers: WorkerLike[];
|
||||
runningWorkers: WorkerLike[];
|
||||
pthreads: Record<number, WorkerLike>;
|
||||
get nextWorkerID(): number;
|
||||
wasmModule: WebAssembly.Module | null;
|
||||
wasmMemory: WebAssembly.Memory | null;
|
||||
private readonly messageEvents;
|
||||
private readonly _childThread;
|
||||
private readonly _onCreateWorker;
|
||||
private readonly _reuseWorker;
|
||||
private readonly _beforeLoad?;
|
||||
/* Excluded from this release type: printErr */
|
||||
threadSpawn?: ((startArg: number, errorOrTid?: number) => number);
|
||||
constructor(options: ThreadManagerOptions);
|
||||
init(): void;
|
||||
initMainThread(): void;
|
||||
private preparePool;
|
||||
shouldPreloadWorkers(): boolean;
|
||||
loadWasmModuleToAllWorkers(): Promise<WorkerLike[]>;
|
||||
preloadWorkers(): Promise<WorkerLike[]>;
|
||||
setup(wasmModule: WebAssembly.Module, wasmMemory: WebAssembly.Memory): void;
|
||||
markId(worker: WorkerLike): number;
|
||||
returnWorkerToPool(worker: WorkerLike): void;
|
||||
loadWasmModuleToWorker(worker: WorkerLike, sab?: Int32Array): Promise<WorkerLike>;
|
||||
allocateUnusedWorker(): WorkerLike;
|
||||
getNewWorker(sab?: Int32Array): WorkerLike | undefined;
|
||||
cleanThread(worker: WorkerLike, tid: number, force?: boolean): void;
|
||||
terminateWorker(worker: WorkerLike): void;
|
||||
terminateAllThreads(): void;
|
||||
addMessageEventListener(worker: WorkerLike, onMessage: (e: WorkerMessageEvent) => void): () => void;
|
||||
fireMessageEvent(worker: WorkerLike, e: WorkerMessageEvent): void;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare type ThreadManagerOptions = ThreadManagerOptionsMain | ThreadManagerOptionsChild;
|
||||
|
||||
/** @public */
|
||||
export declare interface ThreadManagerOptionsBase {
|
||||
printErr?: (message: string) => void;
|
||||
threadSpawn?: (startArg: number, errorOrTid?: number) => number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface ThreadManagerOptionsChild extends ThreadManagerOptionsBase {
|
||||
childThread: true;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface ThreadManagerOptionsMain extends ThreadManagerOptionsBase {
|
||||
beforeLoad?: (worker: WorkerLike) => any;
|
||||
reuseWorker?: boolean | number | ReuseWorkerOptions;
|
||||
onCreateWorker: WorkerFactory;
|
||||
childThread?: false;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare class ThreadMessageHandler {
|
||||
protected instance: WebAssembly.Instance | undefined;
|
||||
private messagesBeforeLoad;
|
||||
protected postMessage: (message: any) => void;
|
||||
protected onLoad?: (data: LoadPayload) => WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
|
||||
protected onError: (error: Error, type: WorkerMessageType) => void;
|
||||
constructor(options?: ThreadMessageHandlerOptions);
|
||||
/** @virtual */
|
||||
instantiate(data: LoadPayload): WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
|
||||
/** @virtual */
|
||||
handle(e: WorkerMessageEvent<MessageEventData<WorkerMessageType>>): void;
|
||||
private _load;
|
||||
private _start;
|
||||
protected _loaded(err: Error | null, source: WebAssembly.WebAssemblyInstantiatedSource | null, payload: LoadPayload): void;
|
||||
protected handleAfterLoad<E extends WorkerMessageEvent>(e: E, f: (e: E) => void): void;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface ThreadMessageHandlerOptions {
|
||||
onLoad?: (data: LoadPayload) => WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
|
||||
onError?: (error: Error, type: WorkerMessageType) => void;
|
||||
postMessage?: (message: any) => void;
|
||||
}
|
||||
|
||||
export declare const version: string;
|
||||
|
||||
/** @public */
|
||||
export declare interface WASIInstance {
|
||||
readonly wasiImport?: Record<string, any>;
|
||||
initialize(instance: object): void;
|
||||
start(instance: object): number;
|
||||
getImportObject?(): any;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare class WASIThreads {
|
||||
PThread: ThreadManager | undefined;
|
||||
private wasmMemory;
|
||||
private wasmInstance;
|
||||
private readonly threadSpawn;
|
||||
readonly childThread: boolean;
|
||||
private readonly postMessage;
|
||||
readonly wasi: WASIInstance;
|
||||
constructor(options: WASIThreadsOptions);
|
||||
getImportObject(): {
|
||||
wasi: WASIThreadsImports;
|
||||
};
|
||||
setup(wasmInstance: WebAssembly.Instance, wasmModule: WebAssembly.Module, wasmMemory?: WebAssembly.Memory): void;
|
||||
preloadWorkers(): Promise<WorkerLike[]>;
|
||||
/**
|
||||
* It's ok to call this method to a WASI command module.
|
||||
*
|
||||
* in child thread, must call this method instead of {@link WASIThreads.start} even if it's a WASI command module
|
||||
*
|
||||
* @returns A proxied WebAssembly instance if in child thread, other wise the original instance
|
||||
*/
|
||||
initialize(instance: WebAssembly.Instance, module: WebAssembly.Module, memory?: WebAssembly.Memory): WebAssembly.Instance;
|
||||
/**
|
||||
* Equivalent to calling {@link WASIThreads.initialize} and then calling {@link WASIInstance.start}
|
||||
* ```js
|
||||
* this.initialize(instance, module, memory)
|
||||
* this.wasi.start(instance)
|
||||
* ```
|
||||
*/
|
||||
start(instance: WebAssembly.Instance, module: WebAssembly.Module, memory?: WebAssembly.Memory): StartResult;
|
||||
terminateAllThreads(): void;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface WASIThreadsImports {
|
||||
'thread-spawn': (startArg: number, errorOrTid?: number) => number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare type WASIThreadsOptions = MainThreadOptions | ChildThreadOptions;
|
||||
|
||||
/** @public */
|
||||
export declare type WorkerFactory = (ctx: {
|
||||
type: string;
|
||||
name: string;
|
||||
}) => WorkerLike;
|
||||
|
||||
/** @public */
|
||||
export declare type WorkerLike = (Worker | Worker_2) & {
|
||||
whenLoaded?: Promise<WorkerLike>;
|
||||
loaded?: boolean;
|
||||
__emnapi_tid?: number;
|
||||
};
|
||||
|
||||
/** @public */
|
||||
export declare interface WorkerMessageEvent<T = any> {
|
||||
data: T;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare type WorkerMessageType = 'load' | 'start';
|
||||
|
||||
export { }
|
||||
+1
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
+7386
File diff suppressed because it is too large
Load Diff
+5
@@ -0,0 +1,5 @@
|
||||
if (typeof process !== 'undefined' && process.env.NODE_ENV === 'production') {
|
||||
module.exports = require('./dist/emnapi-core.cjs.min.js')
|
||||
} else {
|
||||
module.exports = require('./dist/emnapi-core.cjs.js')
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"name": "@emnapi/core",
|
||||
"version": "1.10.0",
|
||||
"description": "emnapi core",
|
||||
"main": "index.js",
|
||||
"module": "./dist/emnapi-core.esm-bundler.js",
|
||||
"types": "./dist/emnapi-core.d.ts",
|
||||
"sideEffects": false,
|
||||
"exports": {
|
||||
".": {
|
||||
"types": {
|
||||
"module": "./dist/emnapi-core.d.ts",
|
||||
"import": "./dist/emnapi-core.d.mts",
|
||||
"default": "./dist/emnapi-core.d.ts"
|
||||
},
|
||||
"module": "./dist/emnapi-core.esm-bundler.js",
|
||||
"import": "./dist/emnapi-core.mjs",
|
||||
"default": "./index.js"
|
||||
},
|
||||
"./dist/emnapi-core.cjs.min": {
|
||||
"types": "./dist/emnapi-core.d.ts",
|
||||
"default": "./dist/emnapi-core.cjs.min.js"
|
||||
},
|
||||
"./dist/emnapi-core.min.mjs": {
|
||||
"types": "./dist/emnapi-core.d.mts",
|
||||
"default": "./dist/emnapi-core.min.mjs"
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@emnapi/wasi-threads": "1.2.1",
|
||||
"tslib": "^2.4.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "node ./script/build.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/toyobayashi/emnapi.git"
|
||||
},
|
||||
"author": "toyobayashi",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/toyobayashi/emnapi/issues"
|
||||
},
|
||||
"homepage": "https://github.com/toyobayashi/emnapi#readme",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021-present Toyobayashi
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
+1
@@ -0,0 +1 @@
|
||||
See [https://github.com/toyobayashi/emnapi](https://github.com/toyobayashi/emnapi)
|
||||
+1381
File diff suppressed because it is too large
Load Diff
+671
@@ -0,0 +1,671 @@
|
||||
export declare type Ptr = number | bigint
|
||||
|
||||
export declare interface IBuffer extends Uint8Array {}
|
||||
export declare interface BufferCtor {
|
||||
readonly prototype: IBuffer
|
||||
/** @deprecated */
|
||||
new (...args: any[]): IBuffer
|
||||
from: {
|
||||
(buffer: ArrayBufferLike): IBuffer
|
||||
(buffer: ArrayBufferLike, byteOffset: number, length: number): IBuffer
|
||||
}
|
||||
alloc: (size: number) => IBuffer
|
||||
isBuffer: (obj: unknown) => obj is IBuffer
|
||||
}
|
||||
|
||||
export declare const enum GlobalHandle {
|
||||
UNDEFINED = 1,
|
||||
NULL,
|
||||
FALSE,
|
||||
TRUE,
|
||||
GLOBAL
|
||||
}
|
||||
|
||||
export declare const enum Version {
|
||||
NODE_API_SUPPORTED_VERSION_MIN = 1,
|
||||
NODE_API_DEFAULT_MODULE_API_VERSION = 8,
|
||||
NODE_API_SUPPORTED_VERSION_MAX = 10,
|
||||
NAPI_VERSION_EXPERIMENTAL = 2147483647 // INT_MAX
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export declare type Pointer<T> = number
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export declare type PointerPointer<T> = number
|
||||
export declare type FunctionPointer<T extends (...args: any[]) => any> = Pointer<T>
|
||||
export declare type Const<T> = T
|
||||
|
||||
export declare type void_p = Pointer<void>
|
||||
export declare type void_pp = Pointer<void_p>
|
||||
export declare type bool = number
|
||||
export declare type char = number
|
||||
export declare type char_p = Pointer<char>
|
||||
export declare type unsigned_char = number
|
||||
export declare type const_char = Const<char>
|
||||
export declare type const_char_p = Pointer<const_char>
|
||||
export declare type char16_t_p = number
|
||||
export declare type const_char16_t_p = number
|
||||
|
||||
export declare type short = number
|
||||
export declare type unsigned_short = number
|
||||
export declare type int = number
|
||||
export declare type unsigned_int = number
|
||||
export declare type long = number
|
||||
export declare type unsigned_long = number
|
||||
export declare type long_long = bigint
|
||||
export declare type unsigned_long_long = bigint
|
||||
export declare type float = number
|
||||
export declare type double = number
|
||||
export declare type long_double = number
|
||||
export declare type size_t = number
|
||||
|
||||
export declare type int8_t = number
|
||||
export declare type uint8_t = number
|
||||
export declare type int16_t = number
|
||||
export declare type uint16_t = number
|
||||
export declare type int32_t = number
|
||||
export declare type uint32_t = number
|
||||
export declare type int64_t = bigint
|
||||
export declare type uint64_t = bigint
|
||||
export declare type napi_env = Pointer<unknown>
|
||||
|
||||
export declare type napi_value = Pointer<unknown>
|
||||
export declare type napi_ref = Pointer<unknown>
|
||||
export declare type napi_deferred = Pointer<unknown>
|
||||
export declare type napi_handle_scope = Pointer<unknown>
|
||||
export declare type napi_escapable_handle_scope = Pointer<unknown>
|
||||
|
||||
export declare type napi_addon_register_func = FunctionPointer<(env: napi_env, exports: napi_value) => napi_value>
|
||||
|
||||
export declare type napi_callback_info = Pointer<unknown>
|
||||
export declare type napi_callback = FunctionPointer<(env: napi_env, info: napi_callback_info) => napi_value>
|
||||
|
||||
export declare interface napi_extended_error_info {
|
||||
error_message: const_char_p
|
||||
engine_reserved: void_p
|
||||
engine_error_code: uint32_t
|
||||
error_code: napi_status
|
||||
}
|
||||
|
||||
export declare interface napi_property_descriptor {
|
||||
// One of utf8name or name should be NULL.
|
||||
utf8name: const_char_p
|
||||
name: napi_value
|
||||
|
||||
method: napi_callback
|
||||
getter: napi_callback
|
||||
setter: napi_callback
|
||||
value: napi_value
|
||||
/* napi_property_attributes */
|
||||
attributes: number
|
||||
data: void_p
|
||||
}
|
||||
|
||||
export declare type napi_finalize = FunctionPointer<(
|
||||
env: napi_env,
|
||||
finalize_data: void_p,
|
||||
finalize_hint: void_p
|
||||
) => void>
|
||||
|
||||
export declare interface node_module {
|
||||
nm_version: int32_t
|
||||
nm_flags: uint32_t
|
||||
nm_filename: Pointer<const_char>
|
||||
nm_register_func: napi_addon_register_func
|
||||
nm_modname: Pointer<const_char>
|
||||
nm_priv: Pointer<void>
|
||||
reserved: PointerPointer<void>
|
||||
}
|
||||
|
||||
export declare interface napi_node_version {
|
||||
major: uint32_t
|
||||
minor: uint32_t
|
||||
patch: uint32_t
|
||||
release: const_char_p
|
||||
}
|
||||
|
||||
export declare interface emnapi_emscripten_version {
|
||||
major: uint32_t
|
||||
minor: uint32_t
|
||||
patch: uint32_t
|
||||
}
|
||||
|
||||
export declare const enum napi_status {
|
||||
napi_ok,
|
||||
napi_invalid_arg,
|
||||
napi_object_expected,
|
||||
napi_string_expected,
|
||||
napi_name_expected,
|
||||
napi_function_expected,
|
||||
napi_number_expected,
|
||||
napi_boolean_expected,
|
||||
napi_array_expected,
|
||||
napi_generic_failure,
|
||||
napi_pending_exception,
|
||||
napi_cancelled,
|
||||
napi_escape_called_twice,
|
||||
napi_handle_scope_mismatch,
|
||||
napi_callback_scope_mismatch,
|
||||
napi_queue_full,
|
||||
napi_closing,
|
||||
napi_bigint_expected,
|
||||
napi_date_expected,
|
||||
napi_arraybuffer_expected,
|
||||
napi_detachable_arraybuffer_expected,
|
||||
napi_would_deadlock, // unused
|
||||
napi_no_external_buffers_allowed,
|
||||
napi_cannot_run_js
|
||||
}
|
||||
|
||||
export declare const enum napi_property_attributes {
|
||||
napi_default = 0,
|
||||
napi_writable = 1 << 0,
|
||||
napi_enumerable = 1 << 1,
|
||||
napi_configurable = 1 << 2,
|
||||
|
||||
// Used with napi_define_class to distinguish static properties
|
||||
// from instance properties. Ignored by napi_define_properties.
|
||||
napi_static = 1 << 10,
|
||||
|
||||
/// #ifdef NAPI_EXPERIMENTAL
|
||||
// Default for class methods.
|
||||
napi_default_method = napi_writable | napi_configurable,
|
||||
|
||||
// Default for object properties, like in JS obj[prop].
|
||||
napi_default_jsproperty = napi_writable | napi_enumerable | napi_configurable
|
||||
/// #endif // NAPI_EXPERIMENTAL
|
||||
}
|
||||
|
||||
export declare const enum napi_valuetype {
|
||||
napi_undefined,
|
||||
napi_null,
|
||||
napi_boolean,
|
||||
napi_number,
|
||||
napi_string,
|
||||
napi_symbol,
|
||||
napi_object,
|
||||
napi_function,
|
||||
napi_external,
|
||||
napi_bigint
|
||||
}
|
||||
|
||||
export declare const enum napi_typedarray_type {
|
||||
napi_int8_array,
|
||||
napi_uint8_array,
|
||||
napi_uint8_clamped_array,
|
||||
napi_int16_array,
|
||||
napi_uint16_array,
|
||||
napi_int32_array,
|
||||
napi_uint32_array,
|
||||
napi_float32_array,
|
||||
napi_float64_array,
|
||||
napi_bigint64_array,
|
||||
napi_biguint64_array,
|
||||
napi_float16_array,
|
||||
}
|
||||
|
||||
export declare const enum napi_key_collection_mode {
|
||||
napi_key_include_prototypes,
|
||||
napi_key_own_only
|
||||
}
|
||||
|
||||
export declare const enum napi_key_filter {
|
||||
napi_key_all_properties = 0,
|
||||
napi_key_writable = 1,
|
||||
napi_key_enumerable = 1 << 1,
|
||||
napi_key_configurable = 1 << 2,
|
||||
napi_key_skip_strings = 1 << 3,
|
||||
napi_key_skip_symbols = 1 << 4
|
||||
}
|
||||
|
||||
export declare const enum napi_key_conversion {
|
||||
napi_key_keep_numbers,
|
||||
napi_key_numbers_to_strings
|
||||
}
|
||||
|
||||
export declare const enum emnapi_memory_view_type {
|
||||
emnapi_int8_array,
|
||||
emnapi_uint8_array,
|
||||
emnapi_uint8_clamped_array,
|
||||
emnapi_int16_array,
|
||||
emnapi_uint16_array,
|
||||
emnapi_int32_array,
|
||||
emnapi_uint32_array,
|
||||
emnapi_float32_array,
|
||||
emnapi_float64_array,
|
||||
emnapi_bigint64_array,
|
||||
emnapi_biguint64_array,
|
||||
emnapi_float16_array,
|
||||
emnapi_data_view = -1,
|
||||
emnapi_buffer = -2
|
||||
}
|
||||
|
||||
export declare const enum napi_threadsafe_function_call_mode {
|
||||
napi_tsfn_nonblocking,
|
||||
napi_tsfn_blocking
|
||||
}
|
||||
|
||||
export declare const enum napi_threadsafe_function_release_mode {
|
||||
napi_tsfn_release,
|
||||
napi_tsfn_abort
|
||||
}
|
||||
export declare type CleanupHookCallbackFunction = number | ((arg: number) => void);
|
||||
|
||||
export declare class ConstHandle<S extends undefined | null | boolean | typeof globalThis> extends Handle<S> {
|
||||
constructor(id: number, value: S);
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export declare class Context {
|
||||
private _isStopping;
|
||||
private _canCallIntoJs;
|
||||
private _suppressDestroy;
|
||||
envStore: Store<Env>;
|
||||
scopeStore: ScopeStore;
|
||||
refStore: Store<Reference>;
|
||||
deferredStore: Store<Deferred<any>>;
|
||||
handleStore: HandleStore;
|
||||
private readonly refCounter?;
|
||||
private readonly cleanupQueue;
|
||||
private readonly _externalMemory;
|
||||
feature: {
|
||||
supportReflect: boolean;
|
||||
supportFinalizer: boolean;
|
||||
supportWeakSymbol: boolean;
|
||||
supportBigInt: boolean;
|
||||
supportNewFunction: boolean;
|
||||
canSetFunctionName: boolean;
|
||||
setImmediate: (callback: () => void) => void;
|
||||
Buffer: BufferCtor | undefined;
|
||||
MessageChannel: {
|
||||
new (): MessageChannel;
|
||||
prototype: MessageChannel;
|
||||
} | undefined;
|
||||
};
|
||||
constructor(options?: ContextOptions);
|
||||
/**
|
||||
* Suppress the destroy on `beforeExit` event in Node.js.
|
||||
* Call this method if you want to keep the context and
|
||||
* all associated {@link Env | Env} alive,
|
||||
* this also means that cleanup hooks will not be called.
|
||||
* After call this method, you should call
|
||||
* {@link Context.destroy | `Context.prototype.destroy`} method manually.
|
||||
*/
|
||||
suppressDestroy(): void;
|
||||
getRuntimeVersions(): {
|
||||
version: string;
|
||||
NODE_API_SUPPORTED_VERSION_MAX: Version;
|
||||
NAPI_VERSION_EXPERIMENTAL: Version;
|
||||
NODE_API_DEFAULT_MODULE_API_VERSION: Version;
|
||||
};
|
||||
createNotSupportWeakRefError(api: string, message: string): NotSupportWeakRefError;
|
||||
createNotSupportBufferError(api: string, message: string): NotSupportBufferError;
|
||||
createReference(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership): Reference;
|
||||
createReferenceWithData(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, data: void_p): Reference;
|
||||
createReferenceWithFinalizer(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, finalize_callback?: napi_finalize, finalize_data?: void_p, finalize_hint?: void_p): Reference;
|
||||
createDeferred<T = any>(value: IDeferrdValue<T>): Deferred<T>;
|
||||
adjustAmountOfExternalAllocatedMemory(changeInBytes: number | bigint): bigint;
|
||||
createEnv(filename: string, moduleApiVersion: number, makeDynCall_vppp: (cb: Ptr) => (a: Ptr, b: Ptr, c: Ptr) => void, makeDynCall_vp: (cb: Ptr) => (a: Ptr) => void, abort: (msg?: string) => never, nodeBinding?: any): Env;
|
||||
createTrackedFinalizer(envObject: Env, finalize_callback: napi_finalize, finalize_data: void_p, finalize_hint: void_p): TrackedFinalizer;
|
||||
getCurrentScope(): HandleScope | null;
|
||||
addToCurrentScope<V>(value: V): Handle<V>;
|
||||
openScope(envObject?: Env): HandleScope;
|
||||
closeScope(envObject?: Env, _scope?: HandleScope): void;
|
||||
ensureHandle<S>(value: S): Handle<S>;
|
||||
addCleanupHook(envObject: Env, fn: CleanupHookCallbackFunction, arg: number): void;
|
||||
removeCleanupHook(envObject: Env, fn: CleanupHookCallbackFunction, arg: number): void;
|
||||
runCleanup(): void;
|
||||
increaseWaitingRequestCounter(): void;
|
||||
decreaseWaitingRequestCounter(): void;
|
||||
setCanCallIntoJs(value: boolean): void;
|
||||
setStopping(value: boolean): void;
|
||||
canCallIntoJs(): boolean;
|
||||
/**
|
||||
* Destroy the context and call cleanup hooks.
|
||||
* Associated {@link Env | Env} will be destroyed.
|
||||
*/
|
||||
destroy(): void;
|
||||
}
|
||||
|
||||
export declare interface ContextOptions {
|
||||
onExternalMemoryChange?: (current: bigint, old: bigint, delta: bigint) => any;
|
||||
}
|
||||
|
||||
export declare function createContext(options?: ContextOptions): Context;
|
||||
|
||||
export declare class Deferred<T = any> implements IStoreValue {
|
||||
static create<T = any>(ctx: Context, value: IDeferrdValue<T>): Deferred;
|
||||
id: number;
|
||||
ctx: Context;
|
||||
value: IDeferrdValue<T>;
|
||||
constructor(ctx: Context, value: IDeferrdValue<T>);
|
||||
resolve(value: T): void;
|
||||
reject(reason?: any): void;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export declare class EmnapiError extends Error {
|
||||
constructor(message?: string);
|
||||
}
|
||||
|
||||
export declare abstract class Env implements IStoreValue {
|
||||
readonly ctx: Context;
|
||||
moduleApiVersion: number;
|
||||
makeDynCall_vppp: (cb: Ptr) => (a: Ptr, b: Ptr, c: Ptr) => void;
|
||||
makeDynCall_vp: (cb: Ptr) => (a: Ptr) => void;
|
||||
abort: (msg?: string) => never;
|
||||
id: number;
|
||||
openHandleScopes: number;
|
||||
instanceData: TrackedFinalizer | null;
|
||||
tryCatch: TryCatch;
|
||||
refs: number;
|
||||
reflist: RefTracker;
|
||||
finalizing_reflist: RefTracker;
|
||||
pendingFinalizers: RefTracker[];
|
||||
lastError: {
|
||||
errorCode: napi_status;
|
||||
engineErrorCode: number;
|
||||
engineReserved: Ptr;
|
||||
};
|
||||
inGcFinalizer: boolean;
|
||||
constructor(ctx: Context, moduleApiVersion: number, makeDynCall_vppp: (cb: Ptr) => (a: Ptr, b: Ptr, c: Ptr) => void, makeDynCall_vp: (cb: Ptr) => (a: Ptr) => void, abort: (msg?: string) => never);
|
||||
/** @virtual */
|
||||
canCallIntoJs(): boolean;
|
||||
terminatedOrTerminating(): boolean;
|
||||
ref(): void;
|
||||
unref(): void;
|
||||
ensureHandle<S>(value: S): Handle<S>;
|
||||
ensureHandleId(value: any): napi_value;
|
||||
clearLastError(): napi_status;
|
||||
setLastError(error_code: napi_status, engine_error_code?: uint32_t, engine_reserved?: void_p): napi_status;
|
||||
getReturnStatus(): napi_status;
|
||||
callIntoModule<T>(fn: (env: Env) => T, handleException?: (envObject: Env, value: any) => void): T;
|
||||
/** @virtual */
|
||||
abstract callFinalizer(cb: napi_finalize, data: void_p, hint: void_p): void;
|
||||
invokeFinalizerFromGC(finalizer: RefTracker): void;
|
||||
checkGCAccess(): void;
|
||||
/** @virtual */
|
||||
enqueueFinalizer(finalizer: RefTracker): void;
|
||||
/** @virtual */
|
||||
dequeueFinalizer(finalizer: RefTracker): void;
|
||||
/** @virtual */
|
||||
deleteMe(): void;
|
||||
dispose(): void;
|
||||
private readonly _bindingMap;
|
||||
initObjectBinding<S extends object>(value: S): IReferenceBinding;
|
||||
getObjectBinding<S extends object>(value: S): IReferenceBinding;
|
||||
setInstanceData(data: number, finalize_cb: number, finalize_hint: number): void;
|
||||
getInstanceData(): number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
declare interface External_2 extends Record<any, any> {
|
||||
}
|
||||
|
||||
/** @public */
|
||||
declare const External_2: {
|
||||
new (value: number | bigint): External_2;
|
||||
prototype: null;
|
||||
};
|
||||
export { External_2 as External }
|
||||
|
||||
export declare class Finalizer {
|
||||
envObject: Env;
|
||||
private _finalizeCallback;
|
||||
private _finalizeData;
|
||||
private _finalizeHint;
|
||||
private _makeDynCall_vppp;
|
||||
constructor(envObject: Env, _finalizeCallback?: napi_finalize, _finalizeData?: void_p, _finalizeHint?: void_p);
|
||||
callback(): napi_finalize;
|
||||
data(): void_p;
|
||||
hint(): void_p;
|
||||
resetEnv(): void;
|
||||
resetFinalizer(): void;
|
||||
callFinalizer(): void;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export declare function getDefaultContext(): Context;
|
||||
|
||||
/** @public */
|
||||
export declare function getExternalValue(external: External_2): number | bigint;
|
||||
|
||||
export declare class Handle<S> {
|
||||
id: number;
|
||||
value: S;
|
||||
constructor(id: number, value: S);
|
||||
data(): void_p;
|
||||
isNumber(): boolean;
|
||||
isBigInt(): boolean;
|
||||
isString(): boolean;
|
||||
isFunction(): boolean;
|
||||
isExternal(): boolean;
|
||||
isObject(): boolean;
|
||||
isArray(): boolean;
|
||||
isArrayBuffer(): boolean;
|
||||
isTypedArray(): boolean;
|
||||
isBuffer(BufferConstructor?: BufferCtor): boolean;
|
||||
isDataView(): boolean;
|
||||
isDate(): boolean;
|
||||
isPromise(): boolean;
|
||||
isBoolean(): boolean;
|
||||
isUndefined(): boolean;
|
||||
isSymbol(): boolean;
|
||||
isNull(): boolean;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export declare class HandleScope {
|
||||
handleStore: HandleStore;
|
||||
id: number;
|
||||
parent: HandleScope | null;
|
||||
child: HandleScope | null;
|
||||
start: number;
|
||||
end: number;
|
||||
private _escapeCalled;
|
||||
callbackInfo: ICallbackInfo;
|
||||
constructor(handleStore: HandleStore, id: number, parentScope: HandleScope | null, start: number, end?: number);
|
||||
add<V>(value: V): Handle<V>;
|
||||
addExternal(data: void_p): Handle<object>;
|
||||
dispose(): void;
|
||||
escape(handle: number): Handle<any> | null;
|
||||
escapeCalled(): boolean;
|
||||
}
|
||||
|
||||
export declare class HandleStore {
|
||||
static UNDEFINED: ConstHandle<undefined>;
|
||||
static NULL: ConstHandle<null>;
|
||||
static FALSE: ConstHandle<false>;
|
||||
static TRUE: ConstHandle<true>;
|
||||
static GLOBAL: ConstHandle<typeof globalThis>;
|
||||
static MIN_ID: 6;
|
||||
private readonly _values;
|
||||
private _next;
|
||||
push<S>(value: S): Handle<S>;
|
||||
erase(start: number, end: number): void;
|
||||
get(id: Ptr): Handle<any> | undefined;
|
||||
swap(a: number, b: number): void;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export declare interface ICallbackInfo {
|
||||
thiz: any;
|
||||
data: void_p;
|
||||
args: ArrayLike<any>;
|
||||
fn: Function;
|
||||
}
|
||||
|
||||
export declare interface IDeferrdValue<T = any> {
|
||||
resolve: (value: T) => void;
|
||||
reject: (reason?: any) => void;
|
||||
}
|
||||
|
||||
export declare interface IReferenceBinding {
|
||||
wrapped: number;
|
||||
tag: Uint32Array | null;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare function isExternal(object: unknown): object is External_2;
|
||||
|
||||
export declare function isReferenceType(v: any): v is object;
|
||||
|
||||
export declare interface IStoreValue {
|
||||
id: number;
|
||||
dispose(): void;
|
||||
[x: string]: any;
|
||||
}
|
||||
|
||||
export declare const NAPI_VERSION_EXPERIMENTAL = Version.NAPI_VERSION_EXPERIMENTAL;
|
||||
|
||||
export declare const NODE_API_DEFAULT_MODULE_API_VERSION = Version.NODE_API_DEFAULT_MODULE_API_VERSION;
|
||||
|
||||
export declare const NODE_API_SUPPORTED_VERSION_MAX = Version.NODE_API_SUPPORTED_VERSION_MAX;
|
||||
|
||||
export declare const NODE_API_SUPPORTED_VERSION_MIN = Version.NODE_API_SUPPORTED_VERSION_MIN;
|
||||
|
||||
export declare class NodeEnv extends Env {
|
||||
filename: string;
|
||||
private readonly nodeBinding?;
|
||||
destructing: boolean;
|
||||
finalizationScheduled: boolean;
|
||||
constructor(ctx: Context, filename: string, moduleApiVersion: number, makeDynCall_vppp: (cb: Ptr) => (a: Ptr, b: Ptr, c: Ptr) => void, makeDynCall_vp: (cb: Ptr) => (a: Ptr) => void, abort: (msg?: string) => never, nodeBinding?: any);
|
||||
deleteMe(): void;
|
||||
canCallIntoJs(): boolean;
|
||||
triggerFatalException(err: any): void;
|
||||
callbackIntoModule<T>(enforceUncaughtExceptionPolicy: boolean, fn: (env: Env) => T): T;
|
||||
callFinalizer(cb: napi_finalize, data: void_p, hint: void_p): void;
|
||||
callFinalizerInternal(forceUncaught: int, cb: napi_finalize, data: void_p, hint: void_p): void;
|
||||
enqueueFinalizer(finalizer: RefTracker): void;
|
||||
drainFinalizerQueue(): void;
|
||||
}
|
||||
|
||||
export declare class NotSupportBufferError extends EmnapiError {
|
||||
constructor(api: string, message: string);
|
||||
}
|
||||
|
||||
export declare class NotSupportWeakRefError extends EmnapiError {
|
||||
constructor(api: string, message: string);
|
||||
}
|
||||
|
||||
export declare class Persistent<T> {
|
||||
private _ref;
|
||||
private _param;
|
||||
private _callback;
|
||||
private static readonly _registry;
|
||||
constructor(value: T);
|
||||
setWeak<P>(param: P, callback: (param: P) => void): void;
|
||||
clearWeak(): void;
|
||||
reset(): void;
|
||||
isEmpty(): boolean;
|
||||
deref(): T | undefined;
|
||||
}
|
||||
|
||||
export declare class Reference extends RefTracker implements IStoreValue {
|
||||
private static weakCallback;
|
||||
id: number;
|
||||
envObject: Env;
|
||||
private readonly canBeWeak;
|
||||
private _refcount;
|
||||
private readonly _ownership;
|
||||
persistent: Persistent<object>;
|
||||
static create(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, _unused1?: void_p, _unused2?: void_p, _unused3?: void_p): Reference;
|
||||
protected constructor(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership);
|
||||
ref(): number;
|
||||
unref(): number;
|
||||
get(envObject?: Env): napi_value;
|
||||
/** @virtual */
|
||||
resetFinalizer(): void;
|
||||
/** @virtual */
|
||||
data(): void_p;
|
||||
refcount(): number;
|
||||
ownership(): ReferenceOwnership;
|
||||
/** @virtual */
|
||||
protected callUserFinalizer(): void;
|
||||
/** @virtual */
|
||||
protected invokeFinalizerFromGC(): void;
|
||||
private _setWeak;
|
||||
finalize(): void;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export declare enum ReferenceOwnership {
|
||||
kRuntime = 0,
|
||||
kUserland = 1
|
||||
}
|
||||
|
||||
export declare class ReferenceWithData extends Reference {
|
||||
private readonly _data;
|
||||
static create(envObject: Env, value: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, data: void_p): ReferenceWithData;
|
||||
private constructor();
|
||||
data(): void_p;
|
||||
}
|
||||
|
||||
export declare class ReferenceWithFinalizer extends Reference {
|
||||
private _finalizer;
|
||||
static create(envObject: Env, value: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, finalize_callback: napi_finalize, finalize_data: void_p, finalize_hint: void_p): ReferenceWithFinalizer;
|
||||
private constructor();
|
||||
resetFinalizer(): void;
|
||||
data(): void_p;
|
||||
protected callUserFinalizer(): void;
|
||||
protected invokeFinalizerFromGC(): void;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export declare class RefTracker {
|
||||
/** @virtual */
|
||||
dispose(): void;
|
||||
/** @virtual */
|
||||
finalize(): void;
|
||||
private _next;
|
||||
private _prev;
|
||||
link(list: RefTracker): void;
|
||||
unlink(): void;
|
||||
static finalizeAll(list: RefTracker): void;
|
||||
}
|
||||
|
||||
export declare class ScopeStore {
|
||||
private readonly _rootScope;
|
||||
currentScope: HandleScope;
|
||||
private readonly _values;
|
||||
constructor();
|
||||
get(id: number): HandleScope | undefined;
|
||||
openScope(handleStore: HandleStore): HandleScope;
|
||||
closeScope(): void;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export declare class Store<V extends IStoreValue> {
|
||||
protected _values: Array<V | undefined>;
|
||||
private _freeList;
|
||||
private _size;
|
||||
constructor();
|
||||
add(value: V): void;
|
||||
get(id: Ptr): V | undefined;
|
||||
has(id: Ptr): boolean;
|
||||
remove(id: Ptr): void;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export declare class TrackedFinalizer extends RefTracker {
|
||||
private _finalizer;
|
||||
static create(envObject: Env, finalize_callback: napi_finalize, finalize_data: void_p, finalize_hint: void_p): TrackedFinalizer;
|
||||
private constructor();
|
||||
data(): void_p;
|
||||
dispose(): void;
|
||||
finalize(): void;
|
||||
}
|
||||
|
||||
export declare class TryCatch {
|
||||
private _exception;
|
||||
private _caught;
|
||||
isEmpty(): boolean;
|
||||
hasCaught(): boolean;
|
||||
exception(): any;
|
||||
setError(err: any): void;
|
||||
reset(): void;
|
||||
extractException(): any;
|
||||
}
|
||||
|
||||
export declare const version: string;
|
||||
|
||||
export { }
|
||||
+1
File diff suppressed because one or more lines are too long
+671
@@ -0,0 +1,671 @@
|
||||
export declare type Ptr = number | bigint
|
||||
|
||||
export declare interface IBuffer extends Uint8Array {}
|
||||
export declare interface BufferCtor {
|
||||
readonly prototype: IBuffer
|
||||
/** @deprecated */
|
||||
new (...args: any[]): IBuffer
|
||||
from: {
|
||||
(buffer: ArrayBufferLike): IBuffer
|
||||
(buffer: ArrayBufferLike, byteOffset: number, length: number): IBuffer
|
||||
}
|
||||
alloc: (size: number) => IBuffer
|
||||
isBuffer: (obj: unknown) => obj is IBuffer
|
||||
}
|
||||
|
||||
export declare const enum GlobalHandle {
|
||||
UNDEFINED = 1,
|
||||
NULL,
|
||||
FALSE,
|
||||
TRUE,
|
||||
GLOBAL
|
||||
}
|
||||
|
||||
export declare const enum Version {
|
||||
NODE_API_SUPPORTED_VERSION_MIN = 1,
|
||||
NODE_API_DEFAULT_MODULE_API_VERSION = 8,
|
||||
NODE_API_SUPPORTED_VERSION_MAX = 10,
|
||||
NAPI_VERSION_EXPERIMENTAL = 2147483647 // INT_MAX
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export declare type Pointer<T> = number
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export declare type PointerPointer<T> = number
|
||||
export declare type FunctionPointer<T extends (...args: any[]) => any> = Pointer<T>
|
||||
export declare type Const<T> = T
|
||||
|
||||
export declare type void_p = Pointer<void>
|
||||
export declare type void_pp = Pointer<void_p>
|
||||
export declare type bool = number
|
||||
export declare type char = number
|
||||
export declare type char_p = Pointer<char>
|
||||
export declare type unsigned_char = number
|
||||
export declare type const_char = Const<char>
|
||||
export declare type const_char_p = Pointer<const_char>
|
||||
export declare type char16_t_p = number
|
||||
export declare type const_char16_t_p = number
|
||||
|
||||
export declare type short = number
|
||||
export declare type unsigned_short = number
|
||||
export declare type int = number
|
||||
export declare type unsigned_int = number
|
||||
export declare type long = number
|
||||
export declare type unsigned_long = number
|
||||
export declare type long_long = bigint
|
||||
export declare type unsigned_long_long = bigint
|
||||
export declare type float = number
|
||||
export declare type double = number
|
||||
export declare type long_double = number
|
||||
export declare type size_t = number
|
||||
|
||||
export declare type int8_t = number
|
||||
export declare type uint8_t = number
|
||||
export declare type int16_t = number
|
||||
export declare type uint16_t = number
|
||||
export declare type int32_t = number
|
||||
export declare type uint32_t = number
|
||||
export declare type int64_t = bigint
|
||||
export declare type uint64_t = bigint
|
||||
export declare type napi_env = Pointer<unknown>
|
||||
|
||||
export declare type napi_value = Pointer<unknown>
|
||||
export declare type napi_ref = Pointer<unknown>
|
||||
export declare type napi_deferred = Pointer<unknown>
|
||||
export declare type napi_handle_scope = Pointer<unknown>
|
||||
export declare type napi_escapable_handle_scope = Pointer<unknown>
|
||||
|
||||
export declare type napi_addon_register_func = FunctionPointer<(env: napi_env, exports: napi_value) => napi_value>
|
||||
|
||||
export declare type napi_callback_info = Pointer<unknown>
|
||||
export declare type napi_callback = FunctionPointer<(env: napi_env, info: napi_callback_info) => napi_value>
|
||||
|
||||
export declare interface napi_extended_error_info {
|
||||
error_message: const_char_p
|
||||
engine_reserved: void_p
|
||||
engine_error_code: uint32_t
|
||||
error_code: napi_status
|
||||
}
|
||||
|
||||
export declare interface napi_property_descriptor {
|
||||
// One of utf8name or name should be NULL.
|
||||
utf8name: const_char_p
|
||||
name: napi_value
|
||||
|
||||
method: napi_callback
|
||||
getter: napi_callback
|
||||
setter: napi_callback
|
||||
value: napi_value
|
||||
/* napi_property_attributes */
|
||||
attributes: number
|
||||
data: void_p
|
||||
}
|
||||
|
||||
export declare type napi_finalize = FunctionPointer<(
|
||||
env: napi_env,
|
||||
finalize_data: void_p,
|
||||
finalize_hint: void_p
|
||||
) => void>
|
||||
|
||||
export declare interface node_module {
|
||||
nm_version: int32_t
|
||||
nm_flags: uint32_t
|
||||
nm_filename: Pointer<const_char>
|
||||
nm_register_func: napi_addon_register_func
|
||||
nm_modname: Pointer<const_char>
|
||||
nm_priv: Pointer<void>
|
||||
reserved: PointerPointer<void>
|
||||
}
|
||||
|
||||
export declare interface napi_node_version {
|
||||
major: uint32_t
|
||||
minor: uint32_t
|
||||
patch: uint32_t
|
||||
release: const_char_p
|
||||
}
|
||||
|
||||
export declare interface emnapi_emscripten_version {
|
||||
major: uint32_t
|
||||
minor: uint32_t
|
||||
patch: uint32_t
|
||||
}
|
||||
|
||||
export declare const enum napi_status {
|
||||
napi_ok,
|
||||
napi_invalid_arg,
|
||||
napi_object_expected,
|
||||
napi_string_expected,
|
||||
napi_name_expected,
|
||||
napi_function_expected,
|
||||
napi_number_expected,
|
||||
napi_boolean_expected,
|
||||
napi_array_expected,
|
||||
napi_generic_failure,
|
||||
napi_pending_exception,
|
||||
napi_cancelled,
|
||||
napi_escape_called_twice,
|
||||
napi_handle_scope_mismatch,
|
||||
napi_callback_scope_mismatch,
|
||||
napi_queue_full,
|
||||
napi_closing,
|
||||
napi_bigint_expected,
|
||||
napi_date_expected,
|
||||
napi_arraybuffer_expected,
|
||||
napi_detachable_arraybuffer_expected,
|
||||
napi_would_deadlock, // unused
|
||||
napi_no_external_buffers_allowed,
|
||||
napi_cannot_run_js
|
||||
}
|
||||
|
||||
export declare const enum napi_property_attributes {
|
||||
napi_default = 0,
|
||||
napi_writable = 1 << 0,
|
||||
napi_enumerable = 1 << 1,
|
||||
napi_configurable = 1 << 2,
|
||||
|
||||
// Used with napi_define_class to distinguish static properties
|
||||
// from instance properties. Ignored by napi_define_properties.
|
||||
napi_static = 1 << 10,
|
||||
|
||||
/// #ifdef NAPI_EXPERIMENTAL
|
||||
// Default for class methods.
|
||||
napi_default_method = napi_writable | napi_configurable,
|
||||
|
||||
// Default for object properties, like in JS obj[prop].
|
||||
napi_default_jsproperty = napi_writable | napi_enumerable | napi_configurable
|
||||
/// #endif // NAPI_EXPERIMENTAL
|
||||
}
|
||||
|
||||
export declare const enum napi_valuetype {
|
||||
napi_undefined,
|
||||
napi_null,
|
||||
napi_boolean,
|
||||
napi_number,
|
||||
napi_string,
|
||||
napi_symbol,
|
||||
napi_object,
|
||||
napi_function,
|
||||
napi_external,
|
||||
napi_bigint
|
||||
}
|
||||
|
||||
export declare const enum napi_typedarray_type {
|
||||
napi_int8_array,
|
||||
napi_uint8_array,
|
||||
napi_uint8_clamped_array,
|
||||
napi_int16_array,
|
||||
napi_uint16_array,
|
||||
napi_int32_array,
|
||||
napi_uint32_array,
|
||||
napi_float32_array,
|
||||
napi_float64_array,
|
||||
napi_bigint64_array,
|
||||
napi_biguint64_array,
|
||||
napi_float16_array,
|
||||
}
|
||||
|
||||
export declare const enum napi_key_collection_mode {
|
||||
napi_key_include_prototypes,
|
||||
napi_key_own_only
|
||||
}
|
||||
|
||||
export declare const enum napi_key_filter {
|
||||
napi_key_all_properties = 0,
|
||||
napi_key_writable = 1,
|
||||
napi_key_enumerable = 1 << 1,
|
||||
napi_key_configurable = 1 << 2,
|
||||
napi_key_skip_strings = 1 << 3,
|
||||
napi_key_skip_symbols = 1 << 4
|
||||
}
|
||||
|
||||
export declare const enum napi_key_conversion {
|
||||
napi_key_keep_numbers,
|
||||
napi_key_numbers_to_strings
|
||||
}
|
||||
|
||||
export declare const enum emnapi_memory_view_type {
|
||||
emnapi_int8_array,
|
||||
emnapi_uint8_array,
|
||||
emnapi_uint8_clamped_array,
|
||||
emnapi_int16_array,
|
||||
emnapi_uint16_array,
|
||||
emnapi_int32_array,
|
||||
emnapi_uint32_array,
|
||||
emnapi_float32_array,
|
||||
emnapi_float64_array,
|
||||
emnapi_bigint64_array,
|
||||
emnapi_biguint64_array,
|
||||
emnapi_float16_array,
|
||||
emnapi_data_view = -1,
|
||||
emnapi_buffer = -2
|
||||
}
|
||||
|
||||
export declare const enum napi_threadsafe_function_call_mode {
|
||||
napi_tsfn_nonblocking,
|
||||
napi_tsfn_blocking
|
||||
}
|
||||
|
||||
export declare const enum napi_threadsafe_function_release_mode {
|
||||
napi_tsfn_release,
|
||||
napi_tsfn_abort
|
||||
}
|
||||
export declare type CleanupHookCallbackFunction = number | ((arg: number) => void);
|
||||
|
||||
export declare class ConstHandle<S extends undefined | null | boolean | typeof globalThis> extends Handle<S> {
|
||||
constructor(id: number, value: S);
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export declare class Context {
|
||||
private _isStopping;
|
||||
private _canCallIntoJs;
|
||||
private _suppressDestroy;
|
||||
envStore: Store<Env>;
|
||||
scopeStore: ScopeStore;
|
||||
refStore: Store<Reference>;
|
||||
deferredStore: Store<Deferred<any>>;
|
||||
handleStore: HandleStore;
|
||||
private readonly refCounter?;
|
||||
private readonly cleanupQueue;
|
||||
private readonly _externalMemory;
|
||||
feature: {
|
||||
supportReflect: boolean;
|
||||
supportFinalizer: boolean;
|
||||
supportWeakSymbol: boolean;
|
||||
supportBigInt: boolean;
|
||||
supportNewFunction: boolean;
|
||||
canSetFunctionName: boolean;
|
||||
setImmediate: (callback: () => void) => void;
|
||||
Buffer: BufferCtor | undefined;
|
||||
MessageChannel: {
|
||||
new (): MessageChannel;
|
||||
prototype: MessageChannel;
|
||||
} | undefined;
|
||||
};
|
||||
constructor(options?: ContextOptions);
|
||||
/**
|
||||
* Suppress the destroy on `beforeExit` event in Node.js.
|
||||
* Call this method if you want to keep the context and
|
||||
* all associated {@link Env | Env} alive,
|
||||
* this also means that cleanup hooks will not be called.
|
||||
* After call this method, you should call
|
||||
* {@link Context.destroy | `Context.prototype.destroy`} method manually.
|
||||
*/
|
||||
suppressDestroy(): void;
|
||||
getRuntimeVersions(): {
|
||||
version: string;
|
||||
NODE_API_SUPPORTED_VERSION_MAX: Version;
|
||||
NAPI_VERSION_EXPERIMENTAL: Version;
|
||||
NODE_API_DEFAULT_MODULE_API_VERSION: Version;
|
||||
};
|
||||
createNotSupportWeakRefError(api: string, message: string): NotSupportWeakRefError;
|
||||
createNotSupportBufferError(api: string, message: string): NotSupportBufferError;
|
||||
createReference(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership): Reference;
|
||||
createReferenceWithData(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, data: void_p): Reference;
|
||||
createReferenceWithFinalizer(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, finalize_callback?: napi_finalize, finalize_data?: void_p, finalize_hint?: void_p): Reference;
|
||||
createDeferred<T = any>(value: IDeferrdValue<T>): Deferred<T>;
|
||||
adjustAmountOfExternalAllocatedMemory(changeInBytes: number | bigint): bigint;
|
||||
createEnv(filename: string, moduleApiVersion: number, makeDynCall_vppp: (cb: Ptr) => (a: Ptr, b: Ptr, c: Ptr) => void, makeDynCall_vp: (cb: Ptr) => (a: Ptr) => void, abort: (msg?: string) => never, nodeBinding?: any): Env;
|
||||
createTrackedFinalizer(envObject: Env, finalize_callback: napi_finalize, finalize_data: void_p, finalize_hint: void_p): TrackedFinalizer;
|
||||
getCurrentScope(): HandleScope | null;
|
||||
addToCurrentScope<V>(value: V): Handle<V>;
|
||||
openScope(envObject?: Env): HandleScope;
|
||||
closeScope(envObject?: Env, _scope?: HandleScope): void;
|
||||
ensureHandle<S>(value: S): Handle<S>;
|
||||
addCleanupHook(envObject: Env, fn: CleanupHookCallbackFunction, arg: number): void;
|
||||
removeCleanupHook(envObject: Env, fn: CleanupHookCallbackFunction, arg: number): void;
|
||||
runCleanup(): void;
|
||||
increaseWaitingRequestCounter(): void;
|
||||
decreaseWaitingRequestCounter(): void;
|
||||
setCanCallIntoJs(value: boolean): void;
|
||||
setStopping(value: boolean): void;
|
||||
canCallIntoJs(): boolean;
|
||||
/**
|
||||
* Destroy the context and call cleanup hooks.
|
||||
* Associated {@link Env | Env} will be destroyed.
|
||||
*/
|
||||
destroy(): void;
|
||||
}
|
||||
|
||||
export declare interface ContextOptions {
|
||||
onExternalMemoryChange?: (current: bigint, old: bigint, delta: bigint) => any;
|
||||
}
|
||||
|
||||
export declare function createContext(options?: ContextOptions): Context;
|
||||
|
||||
export declare class Deferred<T = any> implements IStoreValue {
|
||||
static create<T = any>(ctx: Context, value: IDeferrdValue<T>): Deferred;
|
||||
id: number;
|
||||
ctx: Context;
|
||||
value: IDeferrdValue<T>;
|
||||
constructor(ctx: Context, value: IDeferrdValue<T>);
|
||||
resolve(value: T): void;
|
||||
reject(reason?: any): void;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export declare class EmnapiError extends Error {
|
||||
constructor(message?: string);
|
||||
}
|
||||
|
||||
export declare abstract class Env implements IStoreValue {
|
||||
readonly ctx: Context;
|
||||
moduleApiVersion: number;
|
||||
makeDynCall_vppp: (cb: Ptr) => (a: Ptr, b: Ptr, c: Ptr) => void;
|
||||
makeDynCall_vp: (cb: Ptr) => (a: Ptr) => void;
|
||||
abort: (msg?: string) => never;
|
||||
id: number;
|
||||
openHandleScopes: number;
|
||||
instanceData: TrackedFinalizer | null;
|
||||
tryCatch: TryCatch;
|
||||
refs: number;
|
||||
reflist: RefTracker;
|
||||
finalizing_reflist: RefTracker;
|
||||
pendingFinalizers: RefTracker[];
|
||||
lastError: {
|
||||
errorCode: napi_status;
|
||||
engineErrorCode: number;
|
||||
engineReserved: Ptr;
|
||||
};
|
||||
inGcFinalizer: boolean;
|
||||
constructor(ctx: Context, moduleApiVersion: number, makeDynCall_vppp: (cb: Ptr) => (a: Ptr, b: Ptr, c: Ptr) => void, makeDynCall_vp: (cb: Ptr) => (a: Ptr) => void, abort: (msg?: string) => never);
|
||||
/** @virtual */
|
||||
canCallIntoJs(): boolean;
|
||||
terminatedOrTerminating(): boolean;
|
||||
ref(): void;
|
||||
unref(): void;
|
||||
ensureHandle<S>(value: S): Handle<S>;
|
||||
ensureHandleId(value: any): napi_value;
|
||||
clearLastError(): napi_status;
|
||||
setLastError(error_code: napi_status, engine_error_code?: uint32_t, engine_reserved?: void_p): napi_status;
|
||||
getReturnStatus(): napi_status;
|
||||
callIntoModule<T>(fn: (env: Env) => T, handleException?: (envObject: Env, value: any) => void): T;
|
||||
/** @virtual */
|
||||
abstract callFinalizer(cb: napi_finalize, data: void_p, hint: void_p): void;
|
||||
invokeFinalizerFromGC(finalizer: RefTracker): void;
|
||||
checkGCAccess(): void;
|
||||
/** @virtual */
|
||||
enqueueFinalizer(finalizer: RefTracker): void;
|
||||
/** @virtual */
|
||||
dequeueFinalizer(finalizer: RefTracker): void;
|
||||
/** @virtual */
|
||||
deleteMe(): void;
|
||||
dispose(): void;
|
||||
private readonly _bindingMap;
|
||||
initObjectBinding<S extends object>(value: S): IReferenceBinding;
|
||||
getObjectBinding<S extends object>(value: S): IReferenceBinding;
|
||||
setInstanceData(data: number, finalize_cb: number, finalize_hint: number): void;
|
||||
getInstanceData(): number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
declare interface External_2 extends Record<any, any> {
|
||||
}
|
||||
|
||||
/** @public */
|
||||
declare const External_2: {
|
||||
new (value: number | bigint): External_2;
|
||||
prototype: null;
|
||||
};
|
||||
export { External_2 as External }
|
||||
|
||||
export declare class Finalizer {
|
||||
envObject: Env;
|
||||
private _finalizeCallback;
|
||||
private _finalizeData;
|
||||
private _finalizeHint;
|
||||
private _makeDynCall_vppp;
|
||||
constructor(envObject: Env, _finalizeCallback?: napi_finalize, _finalizeData?: void_p, _finalizeHint?: void_p);
|
||||
callback(): napi_finalize;
|
||||
data(): void_p;
|
||||
hint(): void_p;
|
||||
resetEnv(): void;
|
||||
resetFinalizer(): void;
|
||||
callFinalizer(): void;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export declare function getDefaultContext(): Context;
|
||||
|
||||
/** @public */
|
||||
export declare function getExternalValue(external: External_2): number | bigint;
|
||||
|
||||
export declare class Handle<S> {
|
||||
id: number;
|
||||
value: S;
|
||||
constructor(id: number, value: S);
|
||||
data(): void_p;
|
||||
isNumber(): boolean;
|
||||
isBigInt(): boolean;
|
||||
isString(): boolean;
|
||||
isFunction(): boolean;
|
||||
isExternal(): boolean;
|
||||
isObject(): boolean;
|
||||
isArray(): boolean;
|
||||
isArrayBuffer(): boolean;
|
||||
isTypedArray(): boolean;
|
||||
isBuffer(BufferConstructor?: BufferCtor): boolean;
|
||||
isDataView(): boolean;
|
||||
isDate(): boolean;
|
||||
isPromise(): boolean;
|
||||
isBoolean(): boolean;
|
||||
isUndefined(): boolean;
|
||||
isSymbol(): boolean;
|
||||
isNull(): boolean;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export declare class HandleScope {
|
||||
handleStore: HandleStore;
|
||||
id: number;
|
||||
parent: HandleScope | null;
|
||||
child: HandleScope | null;
|
||||
start: number;
|
||||
end: number;
|
||||
private _escapeCalled;
|
||||
callbackInfo: ICallbackInfo;
|
||||
constructor(handleStore: HandleStore, id: number, parentScope: HandleScope | null, start: number, end?: number);
|
||||
add<V>(value: V): Handle<V>;
|
||||
addExternal(data: void_p): Handle<object>;
|
||||
dispose(): void;
|
||||
escape(handle: number): Handle<any> | null;
|
||||
escapeCalled(): boolean;
|
||||
}
|
||||
|
||||
export declare class HandleStore {
|
||||
static UNDEFINED: ConstHandle<undefined>;
|
||||
static NULL: ConstHandle<null>;
|
||||
static FALSE: ConstHandle<false>;
|
||||
static TRUE: ConstHandle<true>;
|
||||
static GLOBAL: ConstHandle<typeof globalThis>;
|
||||
static MIN_ID: 6;
|
||||
private readonly _values;
|
||||
private _next;
|
||||
push<S>(value: S): Handle<S>;
|
||||
erase(start: number, end: number): void;
|
||||
get(id: Ptr): Handle<any> | undefined;
|
||||
swap(a: number, b: number): void;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export declare interface ICallbackInfo {
|
||||
thiz: any;
|
||||
data: void_p;
|
||||
args: ArrayLike<any>;
|
||||
fn: Function;
|
||||
}
|
||||
|
||||
export declare interface IDeferrdValue<T = any> {
|
||||
resolve: (value: T) => void;
|
||||
reject: (reason?: any) => void;
|
||||
}
|
||||
|
||||
export declare interface IReferenceBinding {
|
||||
wrapped: number;
|
||||
tag: Uint32Array | null;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare function isExternal(object: unknown): object is External_2;
|
||||
|
||||
export declare function isReferenceType(v: any): v is object;
|
||||
|
||||
export declare interface IStoreValue {
|
||||
id: number;
|
||||
dispose(): void;
|
||||
[x: string]: any;
|
||||
}
|
||||
|
||||
export declare const NAPI_VERSION_EXPERIMENTAL = Version.NAPI_VERSION_EXPERIMENTAL;
|
||||
|
||||
export declare const NODE_API_DEFAULT_MODULE_API_VERSION = Version.NODE_API_DEFAULT_MODULE_API_VERSION;
|
||||
|
||||
export declare const NODE_API_SUPPORTED_VERSION_MAX = Version.NODE_API_SUPPORTED_VERSION_MAX;
|
||||
|
||||
export declare const NODE_API_SUPPORTED_VERSION_MIN = Version.NODE_API_SUPPORTED_VERSION_MIN;
|
||||
|
||||
export declare class NodeEnv extends Env {
|
||||
filename: string;
|
||||
private readonly nodeBinding?;
|
||||
destructing: boolean;
|
||||
finalizationScheduled: boolean;
|
||||
constructor(ctx: Context, filename: string, moduleApiVersion: number, makeDynCall_vppp: (cb: Ptr) => (a: Ptr, b: Ptr, c: Ptr) => void, makeDynCall_vp: (cb: Ptr) => (a: Ptr) => void, abort: (msg?: string) => never, nodeBinding?: any);
|
||||
deleteMe(): void;
|
||||
canCallIntoJs(): boolean;
|
||||
triggerFatalException(err: any): void;
|
||||
callbackIntoModule<T>(enforceUncaughtExceptionPolicy: boolean, fn: (env: Env) => T): T;
|
||||
callFinalizer(cb: napi_finalize, data: void_p, hint: void_p): void;
|
||||
callFinalizerInternal(forceUncaught: int, cb: napi_finalize, data: void_p, hint: void_p): void;
|
||||
enqueueFinalizer(finalizer: RefTracker): void;
|
||||
drainFinalizerQueue(): void;
|
||||
}
|
||||
|
||||
export declare class NotSupportBufferError extends EmnapiError {
|
||||
constructor(api: string, message: string);
|
||||
}
|
||||
|
||||
export declare class NotSupportWeakRefError extends EmnapiError {
|
||||
constructor(api: string, message: string);
|
||||
}
|
||||
|
||||
export declare class Persistent<T> {
|
||||
private _ref;
|
||||
private _param;
|
||||
private _callback;
|
||||
private static readonly _registry;
|
||||
constructor(value: T);
|
||||
setWeak<P>(param: P, callback: (param: P) => void): void;
|
||||
clearWeak(): void;
|
||||
reset(): void;
|
||||
isEmpty(): boolean;
|
||||
deref(): T | undefined;
|
||||
}
|
||||
|
||||
export declare class Reference extends RefTracker implements IStoreValue {
|
||||
private static weakCallback;
|
||||
id: number;
|
||||
envObject: Env;
|
||||
private readonly canBeWeak;
|
||||
private _refcount;
|
||||
private readonly _ownership;
|
||||
persistent: Persistent<object>;
|
||||
static create(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, _unused1?: void_p, _unused2?: void_p, _unused3?: void_p): Reference;
|
||||
protected constructor(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership);
|
||||
ref(): number;
|
||||
unref(): number;
|
||||
get(envObject?: Env): napi_value;
|
||||
/** @virtual */
|
||||
resetFinalizer(): void;
|
||||
/** @virtual */
|
||||
data(): void_p;
|
||||
refcount(): number;
|
||||
ownership(): ReferenceOwnership;
|
||||
/** @virtual */
|
||||
protected callUserFinalizer(): void;
|
||||
/** @virtual */
|
||||
protected invokeFinalizerFromGC(): void;
|
||||
private _setWeak;
|
||||
finalize(): void;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export declare enum ReferenceOwnership {
|
||||
kRuntime = 0,
|
||||
kUserland = 1
|
||||
}
|
||||
|
||||
export declare class ReferenceWithData extends Reference {
|
||||
private readonly _data;
|
||||
static create(envObject: Env, value: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, data: void_p): ReferenceWithData;
|
||||
private constructor();
|
||||
data(): void_p;
|
||||
}
|
||||
|
||||
export declare class ReferenceWithFinalizer extends Reference {
|
||||
private _finalizer;
|
||||
static create(envObject: Env, value: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, finalize_callback: napi_finalize, finalize_data: void_p, finalize_hint: void_p): ReferenceWithFinalizer;
|
||||
private constructor();
|
||||
resetFinalizer(): void;
|
||||
data(): void_p;
|
||||
protected callUserFinalizer(): void;
|
||||
protected invokeFinalizerFromGC(): void;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export declare class RefTracker {
|
||||
/** @virtual */
|
||||
dispose(): void;
|
||||
/** @virtual */
|
||||
finalize(): void;
|
||||
private _next;
|
||||
private _prev;
|
||||
link(list: RefTracker): void;
|
||||
unlink(): void;
|
||||
static finalizeAll(list: RefTracker): void;
|
||||
}
|
||||
|
||||
export declare class ScopeStore {
|
||||
private readonly _rootScope;
|
||||
currentScope: HandleScope;
|
||||
private readonly _values;
|
||||
constructor();
|
||||
get(id: number): HandleScope | undefined;
|
||||
openScope(handleStore: HandleStore): HandleScope;
|
||||
closeScope(): void;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export declare class Store<V extends IStoreValue> {
|
||||
protected _values: Array<V | undefined>;
|
||||
private _freeList;
|
||||
private _size;
|
||||
constructor();
|
||||
add(value: V): void;
|
||||
get(id: Ptr): V | undefined;
|
||||
has(id: Ptr): boolean;
|
||||
remove(id: Ptr): void;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export declare class TrackedFinalizer extends RefTracker {
|
||||
private _finalizer;
|
||||
static create(envObject: Env, finalize_callback: napi_finalize, finalize_data: void_p, finalize_hint: void_p): TrackedFinalizer;
|
||||
private constructor();
|
||||
data(): void_p;
|
||||
dispose(): void;
|
||||
finalize(): void;
|
||||
}
|
||||
|
||||
export declare class TryCatch {
|
||||
private _exception;
|
||||
private _caught;
|
||||
isEmpty(): boolean;
|
||||
hasCaught(): boolean;
|
||||
exception(): any;
|
||||
setError(err: any): void;
|
||||
reset(): void;
|
||||
extractException(): any;
|
||||
}
|
||||
|
||||
export declare const version: string;
|
||||
|
||||
export { }
|
||||
+673
@@ -0,0 +1,673 @@
|
||||
export declare type Ptr = number | bigint
|
||||
|
||||
export declare interface IBuffer extends Uint8Array {}
|
||||
export declare interface BufferCtor {
|
||||
readonly prototype: IBuffer
|
||||
/** @deprecated */
|
||||
new (...args: any[]): IBuffer
|
||||
from: {
|
||||
(buffer: ArrayBufferLike): IBuffer
|
||||
(buffer: ArrayBufferLike, byteOffset: number, length: number): IBuffer
|
||||
}
|
||||
alloc: (size: number) => IBuffer
|
||||
isBuffer: (obj: unknown) => obj is IBuffer
|
||||
}
|
||||
|
||||
export declare const enum GlobalHandle {
|
||||
UNDEFINED = 1,
|
||||
NULL,
|
||||
FALSE,
|
||||
TRUE,
|
||||
GLOBAL
|
||||
}
|
||||
|
||||
export declare const enum Version {
|
||||
NODE_API_SUPPORTED_VERSION_MIN = 1,
|
||||
NODE_API_DEFAULT_MODULE_API_VERSION = 8,
|
||||
NODE_API_SUPPORTED_VERSION_MAX = 10,
|
||||
NAPI_VERSION_EXPERIMENTAL = 2147483647 // INT_MAX
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export declare type Pointer<T> = number
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export declare type PointerPointer<T> = number
|
||||
export declare type FunctionPointer<T extends (...args: any[]) => any> = Pointer<T>
|
||||
export declare type Const<T> = T
|
||||
|
||||
export declare type void_p = Pointer<void>
|
||||
export declare type void_pp = Pointer<void_p>
|
||||
export declare type bool = number
|
||||
export declare type char = number
|
||||
export declare type char_p = Pointer<char>
|
||||
export declare type unsigned_char = number
|
||||
export declare type const_char = Const<char>
|
||||
export declare type const_char_p = Pointer<const_char>
|
||||
export declare type char16_t_p = number
|
||||
export declare type const_char16_t_p = number
|
||||
|
||||
export declare type short = number
|
||||
export declare type unsigned_short = number
|
||||
export declare type int = number
|
||||
export declare type unsigned_int = number
|
||||
export declare type long = number
|
||||
export declare type unsigned_long = number
|
||||
export declare type long_long = bigint
|
||||
export declare type unsigned_long_long = bigint
|
||||
export declare type float = number
|
||||
export declare type double = number
|
||||
export declare type long_double = number
|
||||
export declare type size_t = number
|
||||
|
||||
export declare type int8_t = number
|
||||
export declare type uint8_t = number
|
||||
export declare type int16_t = number
|
||||
export declare type uint16_t = number
|
||||
export declare type int32_t = number
|
||||
export declare type uint32_t = number
|
||||
export declare type int64_t = bigint
|
||||
export declare type uint64_t = bigint
|
||||
export declare type napi_env = Pointer<unknown>
|
||||
|
||||
export declare type napi_value = Pointer<unknown>
|
||||
export declare type napi_ref = Pointer<unknown>
|
||||
export declare type napi_deferred = Pointer<unknown>
|
||||
export declare type napi_handle_scope = Pointer<unknown>
|
||||
export declare type napi_escapable_handle_scope = Pointer<unknown>
|
||||
|
||||
export declare type napi_addon_register_func = FunctionPointer<(env: napi_env, exports: napi_value) => napi_value>
|
||||
|
||||
export declare type napi_callback_info = Pointer<unknown>
|
||||
export declare type napi_callback = FunctionPointer<(env: napi_env, info: napi_callback_info) => napi_value>
|
||||
|
||||
export declare interface napi_extended_error_info {
|
||||
error_message: const_char_p
|
||||
engine_reserved: void_p
|
||||
engine_error_code: uint32_t
|
||||
error_code: napi_status
|
||||
}
|
||||
|
||||
export declare interface napi_property_descriptor {
|
||||
// One of utf8name or name should be NULL.
|
||||
utf8name: const_char_p
|
||||
name: napi_value
|
||||
|
||||
method: napi_callback
|
||||
getter: napi_callback
|
||||
setter: napi_callback
|
||||
value: napi_value
|
||||
/* napi_property_attributes */
|
||||
attributes: number
|
||||
data: void_p
|
||||
}
|
||||
|
||||
export declare type napi_finalize = FunctionPointer<(
|
||||
env: napi_env,
|
||||
finalize_data: void_p,
|
||||
finalize_hint: void_p
|
||||
) => void>
|
||||
|
||||
export declare interface node_module {
|
||||
nm_version: int32_t
|
||||
nm_flags: uint32_t
|
||||
nm_filename: Pointer<const_char>
|
||||
nm_register_func: napi_addon_register_func
|
||||
nm_modname: Pointer<const_char>
|
||||
nm_priv: Pointer<void>
|
||||
reserved: PointerPointer<void>
|
||||
}
|
||||
|
||||
export declare interface napi_node_version {
|
||||
major: uint32_t
|
||||
minor: uint32_t
|
||||
patch: uint32_t
|
||||
release: const_char_p
|
||||
}
|
||||
|
||||
export declare interface emnapi_emscripten_version {
|
||||
major: uint32_t
|
||||
minor: uint32_t
|
||||
patch: uint32_t
|
||||
}
|
||||
|
||||
export declare const enum napi_status {
|
||||
napi_ok,
|
||||
napi_invalid_arg,
|
||||
napi_object_expected,
|
||||
napi_string_expected,
|
||||
napi_name_expected,
|
||||
napi_function_expected,
|
||||
napi_number_expected,
|
||||
napi_boolean_expected,
|
||||
napi_array_expected,
|
||||
napi_generic_failure,
|
||||
napi_pending_exception,
|
||||
napi_cancelled,
|
||||
napi_escape_called_twice,
|
||||
napi_handle_scope_mismatch,
|
||||
napi_callback_scope_mismatch,
|
||||
napi_queue_full,
|
||||
napi_closing,
|
||||
napi_bigint_expected,
|
||||
napi_date_expected,
|
||||
napi_arraybuffer_expected,
|
||||
napi_detachable_arraybuffer_expected,
|
||||
napi_would_deadlock, // unused
|
||||
napi_no_external_buffers_allowed,
|
||||
napi_cannot_run_js
|
||||
}
|
||||
|
||||
export declare const enum napi_property_attributes {
|
||||
napi_default = 0,
|
||||
napi_writable = 1 << 0,
|
||||
napi_enumerable = 1 << 1,
|
||||
napi_configurable = 1 << 2,
|
||||
|
||||
// Used with napi_define_class to distinguish static properties
|
||||
// from instance properties. Ignored by napi_define_properties.
|
||||
napi_static = 1 << 10,
|
||||
|
||||
/// #ifdef NAPI_EXPERIMENTAL
|
||||
// Default for class methods.
|
||||
napi_default_method = napi_writable | napi_configurable,
|
||||
|
||||
// Default for object properties, like in JS obj[prop].
|
||||
napi_default_jsproperty = napi_writable | napi_enumerable | napi_configurable
|
||||
/// #endif // NAPI_EXPERIMENTAL
|
||||
}
|
||||
|
||||
export declare const enum napi_valuetype {
|
||||
napi_undefined,
|
||||
napi_null,
|
||||
napi_boolean,
|
||||
napi_number,
|
||||
napi_string,
|
||||
napi_symbol,
|
||||
napi_object,
|
||||
napi_function,
|
||||
napi_external,
|
||||
napi_bigint
|
||||
}
|
||||
|
||||
export declare const enum napi_typedarray_type {
|
||||
napi_int8_array,
|
||||
napi_uint8_array,
|
||||
napi_uint8_clamped_array,
|
||||
napi_int16_array,
|
||||
napi_uint16_array,
|
||||
napi_int32_array,
|
||||
napi_uint32_array,
|
||||
napi_float32_array,
|
||||
napi_float64_array,
|
||||
napi_bigint64_array,
|
||||
napi_biguint64_array,
|
||||
napi_float16_array,
|
||||
}
|
||||
|
||||
export declare const enum napi_key_collection_mode {
|
||||
napi_key_include_prototypes,
|
||||
napi_key_own_only
|
||||
}
|
||||
|
||||
export declare const enum napi_key_filter {
|
||||
napi_key_all_properties = 0,
|
||||
napi_key_writable = 1,
|
||||
napi_key_enumerable = 1 << 1,
|
||||
napi_key_configurable = 1 << 2,
|
||||
napi_key_skip_strings = 1 << 3,
|
||||
napi_key_skip_symbols = 1 << 4
|
||||
}
|
||||
|
||||
export declare const enum napi_key_conversion {
|
||||
napi_key_keep_numbers,
|
||||
napi_key_numbers_to_strings
|
||||
}
|
||||
|
||||
export declare const enum emnapi_memory_view_type {
|
||||
emnapi_int8_array,
|
||||
emnapi_uint8_array,
|
||||
emnapi_uint8_clamped_array,
|
||||
emnapi_int16_array,
|
||||
emnapi_uint16_array,
|
||||
emnapi_int32_array,
|
||||
emnapi_uint32_array,
|
||||
emnapi_float32_array,
|
||||
emnapi_float64_array,
|
||||
emnapi_bigint64_array,
|
||||
emnapi_biguint64_array,
|
||||
emnapi_float16_array,
|
||||
emnapi_data_view = -1,
|
||||
emnapi_buffer = -2
|
||||
}
|
||||
|
||||
export declare const enum napi_threadsafe_function_call_mode {
|
||||
napi_tsfn_nonblocking,
|
||||
napi_tsfn_blocking
|
||||
}
|
||||
|
||||
export declare const enum napi_threadsafe_function_release_mode {
|
||||
napi_tsfn_release,
|
||||
napi_tsfn_abort
|
||||
}
|
||||
export declare type CleanupHookCallbackFunction = number | ((arg: number) => void);
|
||||
|
||||
export declare class ConstHandle<S extends undefined | null | boolean | typeof globalThis> extends Handle<S> {
|
||||
constructor(id: number, value: S);
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export declare class Context {
|
||||
private _isStopping;
|
||||
private _canCallIntoJs;
|
||||
private _suppressDestroy;
|
||||
envStore: Store<Env>;
|
||||
scopeStore: ScopeStore;
|
||||
refStore: Store<Reference>;
|
||||
deferredStore: Store<Deferred<any>>;
|
||||
handleStore: HandleStore;
|
||||
private readonly refCounter?;
|
||||
private readonly cleanupQueue;
|
||||
private readonly _externalMemory;
|
||||
feature: {
|
||||
supportReflect: boolean;
|
||||
supportFinalizer: boolean;
|
||||
supportWeakSymbol: boolean;
|
||||
supportBigInt: boolean;
|
||||
supportNewFunction: boolean;
|
||||
canSetFunctionName: boolean;
|
||||
setImmediate: (callback: () => void) => void;
|
||||
Buffer: BufferCtor | undefined;
|
||||
MessageChannel: {
|
||||
new (): MessageChannel;
|
||||
prototype: MessageChannel;
|
||||
} | undefined;
|
||||
};
|
||||
constructor(options?: ContextOptions);
|
||||
/**
|
||||
* Suppress the destroy on `beforeExit` event in Node.js.
|
||||
* Call this method if you want to keep the context and
|
||||
* all associated {@link Env | Env} alive,
|
||||
* this also means that cleanup hooks will not be called.
|
||||
* After call this method, you should call
|
||||
* {@link Context.destroy | `Context.prototype.destroy`} method manually.
|
||||
*/
|
||||
suppressDestroy(): void;
|
||||
getRuntimeVersions(): {
|
||||
version: string;
|
||||
NODE_API_SUPPORTED_VERSION_MAX: Version;
|
||||
NAPI_VERSION_EXPERIMENTAL: Version;
|
||||
NODE_API_DEFAULT_MODULE_API_VERSION: Version;
|
||||
};
|
||||
createNotSupportWeakRefError(api: string, message: string): NotSupportWeakRefError;
|
||||
createNotSupportBufferError(api: string, message: string): NotSupportBufferError;
|
||||
createReference(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership): Reference;
|
||||
createReferenceWithData(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, data: void_p): Reference;
|
||||
createReferenceWithFinalizer(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, finalize_callback?: napi_finalize, finalize_data?: void_p, finalize_hint?: void_p): Reference;
|
||||
createDeferred<T = any>(value: IDeferrdValue<T>): Deferred<T>;
|
||||
adjustAmountOfExternalAllocatedMemory(changeInBytes: number | bigint): bigint;
|
||||
createEnv(filename: string, moduleApiVersion: number, makeDynCall_vppp: (cb: Ptr) => (a: Ptr, b: Ptr, c: Ptr) => void, makeDynCall_vp: (cb: Ptr) => (a: Ptr) => void, abort: (msg?: string) => never, nodeBinding?: any): Env;
|
||||
createTrackedFinalizer(envObject: Env, finalize_callback: napi_finalize, finalize_data: void_p, finalize_hint: void_p): TrackedFinalizer;
|
||||
getCurrentScope(): HandleScope | null;
|
||||
addToCurrentScope<V>(value: V): Handle<V>;
|
||||
openScope(envObject?: Env): HandleScope;
|
||||
closeScope(envObject?: Env, _scope?: HandleScope): void;
|
||||
ensureHandle<S>(value: S): Handle<S>;
|
||||
addCleanupHook(envObject: Env, fn: CleanupHookCallbackFunction, arg: number): void;
|
||||
removeCleanupHook(envObject: Env, fn: CleanupHookCallbackFunction, arg: number): void;
|
||||
runCleanup(): void;
|
||||
increaseWaitingRequestCounter(): void;
|
||||
decreaseWaitingRequestCounter(): void;
|
||||
setCanCallIntoJs(value: boolean): void;
|
||||
setStopping(value: boolean): void;
|
||||
canCallIntoJs(): boolean;
|
||||
/**
|
||||
* Destroy the context and call cleanup hooks.
|
||||
* Associated {@link Env | Env} will be destroyed.
|
||||
*/
|
||||
destroy(): void;
|
||||
}
|
||||
|
||||
export declare interface ContextOptions {
|
||||
onExternalMemoryChange?: (current: bigint, old: bigint, delta: bigint) => any;
|
||||
}
|
||||
|
||||
export declare function createContext(options?: ContextOptions): Context;
|
||||
|
||||
export declare class Deferred<T = any> implements IStoreValue {
|
||||
static create<T = any>(ctx: Context, value: IDeferrdValue<T>): Deferred;
|
||||
id: number;
|
||||
ctx: Context;
|
||||
value: IDeferrdValue<T>;
|
||||
constructor(ctx: Context, value: IDeferrdValue<T>);
|
||||
resolve(value: T): void;
|
||||
reject(reason?: any): void;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export declare class EmnapiError extends Error {
|
||||
constructor(message?: string);
|
||||
}
|
||||
|
||||
export declare abstract class Env implements IStoreValue {
|
||||
readonly ctx: Context;
|
||||
moduleApiVersion: number;
|
||||
makeDynCall_vppp: (cb: Ptr) => (a: Ptr, b: Ptr, c: Ptr) => void;
|
||||
makeDynCall_vp: (cb: Ptr) => (a: Ptr) => void;
|
||||
abort: (msg?: string) => never;
|
||||
id: number;
|
||||
openHandleScopes: number;
|
||||
instanceData: TrackedFinalizer | null;
|
||||
tryCatch: TryCatch;
|
||||
refs: number;
|
||||
reflist: RefTracker;
|
||||
finalizing_reflist: RefTracker;
|
||||
pendingFinalizers: RefTracker[];
|
||||
lastError: {
|
||||
errorCode: napi_status;
|
||||
engineErrorCode: number;
|
||||
engineReserved: Ptr;
|
||||
};
|
||||
inGcFinalizer: boolean;
|
||||
constructor(ctx: Context, moduleApiVersion: number, makeDynCall_vppp: (cb: Ptr) => (a: Ptr, b: Ptr, c: Ptr) => void, makeDynCall_vp: (cb: Ptr) => (a: Ptr) => void, abort: (msg?: string) => never);
|
||||
/** @virtual */
|
||||
canCallIntoJs(): boolean;
|
||||
terminatedOrTerminating(): boolean;
|
||||
ref(): void;
|
||||
unref(): void;
|
||||
ensureHandle<S>(value: S): Handle<S>;
|
||||
ensureHandleId(value: any): napi_value;
|
||||
clearLastError(): napi_status;
|
||||
setLastError(error_code: napi_status, engine_error_code?: uint32_t, engine_reserved?: void_p): napi_status;
|
||||
getReturnStatus(): napi_status;
|
||||
callIntoModule<T>(fn: (env: Env) => T, handleException?: (envObject: Env, value: any) => void): T;
|
||||
/** @virtual */
|
||||
abstract callFinalizer(cb: napi_finalize, data: void_p, hint: void_p): void;
|
||||
invokeFinalizerFromGC(finalizer: RefTracker): void;
|
||||
checkGCAccess(): void;
|
||||
/** @virtual */
|
||||
enqueueFinalizer(finalizer: RefTracker): void;
|
||||
/** @virtual */
|
||||
dequeueFinalizer(finalizer: RefTracker): void;
|
||||
/** @virtual */
|
||||
deleteMe(): void;
|
||||
dispose(): void;
|
||||
private readonly _bindingMap;
|
||||
initObjectBinding<S extends object>(value: S): IReferenceBinding;
|
||||
getObjectBinding<S extends object>(value: S): IReferenceBinding;
|
||||
setInstanceData(data: number, finalize_cb: number, finalize_hint: number): void;
|
||||
getInstanceData(): number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
declare interface External_2 extends Record<any, any> {
|
||||
}
|
||||
|
||||
/** @public */
|
||||
declare const External_2: {
|
||||
new (value: number | bigint): External_2;
|
||||
prototype: null;
|
||||
};
|
||||
export { External_2 as External }
|
||||
|
||||
export declare class Finalizer {
|
||||
envObject: Env;
|
||||
private _finalizeCallback;
|
||||
private _finalizeData;
|
||||
private _finalizeHint;
|
||||
private _makeDynCall_vppp;
|
||||
constructor(envObject: Env, _finalizeCallback?: napi_finalize, _finalizeData?: void_p, _finalizeHint?: void_p);
|
||||
callback(): napi_finalize;
|
||||
data(): void_p;
|
||||
hint(): void_p;
|
||||
resetEnv(): void;
|
||||
resetFinalizer(): void;
|
||||
callFinalizer(): void;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export declare function getDefaultContext(): Context;
|
||||
|
||||
/** @public */
|
||||
export declare function getExternalValue(external: External_2): number | bigint;
|
||||
|
||||
export declare class Handle<S> {
|
||||
id: number;
|
||||
value: S;
|
||||
constructor(id: number, value: S);
|
||||
data(): void_p;
|
||||
isNumber(): boolean;
|
||||
isBigInt(): boolean;
|
||||
isString(): boolean;
|
||||
isFunction(): boolean;
|
||||
isExternal(): boolean;
|
||||
isObject(): boolean;
|
||||
isArray(): boolean;
|
||||
isArrayBuffer(): boolean;
|
||||
isTypedArray(): boolean;
|
||||
isBuffer(BufferConstructor?: BufferCtor): boolean;
|
||||
isDataView(): boolean;
|
||||
isDate(): boolean;
|
||||
isPromise(): boolean;
|
||||
isBoolean(): boolean;
|
||||
isUndefined(): boolean;
|
||||
isSymbol(): boolean;
|
||||
isNull(): boolean;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export declare class HandleScope {
|
||||
handleStore: HandleStore;
|
||||
id: number;
|
||||
parent: HandleScope | null;
|
||||
child: HandleScope | null;
|
||||
start: number;
|
||||
end: number;
|
||||
private _escapeCalled;
|
||||
callbackInfo: ICallbackInfo;
|
||||
constructor(handleStore: HandleStore, id: number, parentScope: HandleScope | null, start: number, end?: number);
|
||||
add<V>(value: V): Handle<V>;
|
||||
addExternal(data: void_p): Handle<object>;
|
||||
dispose(): void;
|
||||
escape(handle: number): Handle<any> | null;
|
||||
escapeCalled(): boolean;
|
||||
}
|
||||
|
||||
export declare class HandleStore {
|
||||
static UNDEFINED: ConstHandle<undefined>;
|
||||
static NULL: ConstHandle<null>;
|
||||
static FALSE: ConstHandle<false>;
|
||||
static TRUE: ConstHandle<true>;
|
||||
static GLOBAL: ConstHandle<typeof globalThis>;
|
||||
static MIN_ID: 6;
|
||||
private readonly _values;
|
||||
private _next;
|
||||
push<S>(value: S): Handle<S>;
|
||||
erase(start: number, end: number): void;
|
||||
get(id: Ptr): Handle<any> | undefined;
|
||||
swap(a: number, b: number): void;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export declare interface ICallbackInfo {
|
||||
thiz: any;
|
||||
data: void_p;
|
||||
args: ArrayLike<any>;
|
||||
fn: Function;
|
||||
}
|
||||
|
||||
export declare interface IDeferrdValue<T = any> {
|
||||
resolve: (value: T) => void;
|
||||
reject: (reason?: any) => void;
|
||||
}
|
||||
|
||||
export declare interface IReferenceBinding {
|
||||
wrapped: number;
|
||||
tag: Uint32Array | null;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare function isExternal(object: unknown): object is External_2;
|
||||
|
||||
export declare function isReferenceType(v: any): v is object;
|
||||
|
||||
export declare interface IStoreValue {
|
||||
id: number;
|
||||
dispose(): void;
|
||||
[x: string]: any;
|
||||
}
|
||||
|
||||
export declare const NAPI_VERSION_EXPERIMENTAL = Version.NAPI_VERSION_EXPERIMENTAL;
|
||||
|
||||
export declare const NODE_API_DEFAULT_MODULE_API_VERSION = Version.NODE_API_DEFAULT_MODULE_API_VERSION;
|
||||
|
||||
export declare const NODE_API_SUPPORTED_VERSION_MAX = Version.NODE_API_SUPPORTED_VERSION_MAX;
|
||||
|
||||
export declare const NODE_API_SUPPORTED_VERSION_MIN = Version.NODE_API_SUPPORTED_VERSION_MIN;
|
||||
|
||||
export declare class NodeEnv extends Env {
|
||||
filename: string;
|
||||
private readonly nodeBinding?;
|
||||
destructing: boolean;
|
||||
finalizationScheduled: boolean;
|
||||
constructor(ctx: Context, filename: string, moduleApiVersion: number, makeDynCall_vppp: (cb: Ptr) => (a: Ptr, b: Ptr, c: Ptr) => void, makeDynCall_vp: (cb: Ptr) => (a: Ptr) => void, abort: (msg?: string) => never, nodeBinding?: any);
|
||||
deleteMe(): void;
|
||||
canCallIntoJs(): boolean;
|
||||
triggerFatalException(err: any): void;
|
||||
callbackIntoModule<T>(enforceUncaughtExceptionPolicy: boolean, fn: (env: Env) => T): T;
|
||||
callFinalizer(cb: napi_finalize, data: void_p, hint: void_p): void;
|
||||
callFinalizerInternal(forceUncaught: int, cb: napi_finalize, data: void_p, hint: void_p): void;
|
||||
enqueueFinalizer(finalizer: RefTracker): void;
|
||||
drainFinalizerQueue(): void;
|
||||
}
|
||||
|
||||
export declare class NotSupportBufferError extends EmnapiError {
|
||||
constructor(api: string, message: string);
|
||||
}
|
||||
|
||||
export declare class NotSupportWeakRefError extends EmnapiError {
|
||||
constructor(api: string, message: string);
|
||||
}
|
||||
|
||||
export declare class Persistent<T> {
|
||||
private _ref;
|
||||
private _param;
|
||||
private _callback;
|
||||
private static readonly _registry;
|
||||
constructor(value: T);
|
||||
setWeak<P>(param: P, callback: (param: P) => void): void;
|
||||
clearWeak(): void;
|
||||
reset(): void;
|
||||
isEmpty(): boolean;
|
||||
deref(): T | undefined;
|
||||
}
|
||||
|
||||
export declare class Reference extends RefTracker implements IStoreValue {
|
||||
private static weakCallback;
|
||||
id: number;
|
||||
envObject: Env;
|
||||
private readonly canBeWeak;
|
||||
private _refcount;
|
||||
private readonly _ownership;
|
||||
persistent: Persistent<object>;
|
||||
static create(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, _unused1?: void_p, _unused2?: void_p, _unused3?: void_p): Reference;
|
||||
protected constructor(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership);
|
||||
ref(): number;
|
||||
unref(): number;
|
||||
get(envObject?: Env): napi_value;
|
||||
/** @virtual */
|
||||
resetFinalizer(): void;
|
||||
/** @virtual */
|
||||
data(): void_p;
|
||||
refcount(): number;
|
||||
ownership(): ReferenceOwnership;
|
||||
/** @virtual */
|
||||
protected callUserFinalizer(): void;
|
||||
/** @virtual */
|
||||
protected invokeFinalizerFromGC(): void;
|
||||
private _setWeak;
|
||||
finalize(): void;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export declare enum ReferenceOwnership {
|
||||
kRuntime = 0,
|
||||
kUserland = 1
|
||||
}
|
||||
|
||||
export declare class ReferenceWithData extends Reference {
|
||||
private readonly _data;
|
||||
static create(envObject: Env, value: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, data: void_p): ReferenceWithData;
|
||||
private constructor();
|
||||
data(): void_p;
|
||||
}
|
||||
|
||||
export declare class ReferenceWithFinalizer extends Reference {
|
||||
private _finalizer;
|
||||
static create(envObject: Env, value: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, finalize_callback: napi_finalize, finalize_data: void_p, finalize_hint: void_p): ReferenceWithFinalizer;
|
||||
private constructor();
|
||||
resetFinalizer(): void;
|
||||
data(): void_p;
|
||||
protected callUserFinalizer(): void;
|
||||
protected invokeFinalizerFromGC(): void;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export declare class RefTracker {
|
||||
/** @virtual */
|
||||
dispose(): void;
|
||||
/** @virtual */
|
||||
finalize(): void;
|
||||
private _next;
|
||||
private _prev;
|
||||
link(list: RefTracker): void;
|
||||
unlink(): void;
|
||||
static finalizeAll(list: RefTracker): void;
|
||||
}
|
||||
|
||||
export declare class ScopeStore {
|
||||
private readonly _rootScope;
|
||||
currentScope: HandleScope;
|
||||
private readonly _values;
|
||||
constructor();
|
||||
get(id: number): HandleScope | undefined;
|
||||
openScope(handleStore: HandleStore): HandleScope;
|
||||
closeScope(): void;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export declare class Store<V extends IStoreValue> {
|
||||
protected _values: Array<V | undefined>;
|
||||
private _freeList;
|
||||
private _size;
|
||||
constructor();
|
||||
add(value: V): void;
|
||||
get(id: Ptr): V | undefined;
|
||||
has(id: Ptr): boolean;
|
||||
remove(id: Ptr): void;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export declare class TrackedFinalizer extends RefTracker {
|
||||
private _finalizer;
|
||||
static create(envObject: Env, finalize_callback: napi_finalize, finalize_data: void_p, finalize_hint: void_p): TrackedFinalizer;
|
||||
private constructor();
|
||||
data(): void_p;
|
||||
dispose(): void;
|
||||
finalize(): void;
|
||||
}
|
||||
|
||||
export declare class TryCatch {
|
||||
private _exception;
|
||||
private _caught;
|
||||
isEmpty(): boolean;
|
||||
hasCaught(): boolean;
|
||||
exception(): any;
|
||||
setError(err: any): void;
|
||||
reset(): void;
|
||||
extractException(): any;
|
||||
}
|
||||
|
||||
export declare const version: string;
|
||||
|
||||
export { }
|
||||
|
||||
export as namespace emnapi;
|
||||
+1438
File diff suppressed because it is too large
Load Diff
+426
@@ -0,0 +1,426 @@
|
||||
declare namespace emnapi {
|
||||
|
||||
export type CleanupHookCallbackFunction = number | ((arg: number) => void);
|
||||
|
||||
export class ConstHandle<S extends undefined | null | boolean | typeof globalThis> extends Handle<S> {
|
||||
constructor(id: number, value: S);
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export class Context {
|
||||
private _isStopping;
|
||||
private _canCallIntoJs;
|
||||
private _suppressDestroy;
|
||||
envStore: Store<Env>;
|
||||
scopeStore: ScopeStore;
|
||||
refStore: Store<Reference>;
|
||||
deferredStore: Store<Deferred<any>>;
|
||||
handleStore: HandleStore;
|
||||
private readonly refCounter?;
|
||||
private readonly cleanupQueue;
|
||||
private readonly _externalMemory;
|
||||
feature: {
|
||||
supportReflect: boolean;
|
||||
supportFinalizer: boolean;
|
||||
supportWeakSymbol: boolean;
|
||||
supportBigInt: boolean;
|
||||
supportNewFunction: boolean;
|
||||
canSetFunctionName: boolean;
|
||||
setImmediate: (callback: () => void) => void;
|
||||
Buffer: BufferCtor | undefined;
|
||||
MessageChannel: {
|
||||
new (): MessageChannel;
|
||||
prototype: MessageChannel;
|
||||
} | undefined;
|
||||
};
|
||||
constructor(options?: ContextOptions);
|
||||
/**
|
||||
* Suppress the destroy on `beforeExit` event in Node.js.
|
||||
* Call this method if you want to keep the context and
|
||||
* all associated {@link Env | Env} alive,
|
||||
* this also means that cleanup hooks will not be called.
|
||||
* After call this method, you should call
|
||||
* {@link Context.destroy | `Context.prototype.destroy`} method manually.
|
||||
*/
|
||||
suppressDestroy(): void;
|
||||
getRuntimeVersions(): {
|
||||
version: string;
|
||||
NODE_API_SUPPORTED_VERSION_MAX: Version;
|
||||
NAPI_VERSION_EXPERIMENTAL: Version;
|
||||
NODE_API_DEFAULT_MODULE_API_VERSION: Version;
|
||||
};
|
||||
createNotSupportWeakRefError(api: string, message: string): NotSupportWeakRefError;
|
||||
createNotSupportBufferError(api: string, message: string): NotSupportBufferError;
|
||||
createReference(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership): Reference;
|
||||
createReferenceWithData(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, data: void_p): Reference;
|
||||
createReferenceWithFinalizer(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, finalize_callback?: napi_finalize, finalize_data?: void_p, finalize_hint?: void_p): Reference;
|
||||
createDeferred<T = any>(value: IDeferrdValue<T>): Deferred<T>;
|
||||
adjustAmountOfExternalAllocatedMemory(changeInBytes: number | bigint): bigint;
|
||||
createEnv(filename: string, moduleApiVersion: number, makeDynCall_vppp: (cb: Ptr) => (a: Ptr, b: Ptr, c: Ptr) => void, makeDynCall_vp: (cb: Ptr) => (a: Ptr) => void, abort: (msg?: string) => never, nodeBinding?: any): Env;
|
||||
createTrackedFinalizer(envObject: Env, finalize_callback: napi_finalize, finalize_data: void_p, finalize_hint: void_p): TrackedFinalizer;
|
||||
getCurrentScope(): HandleScope | null;
|
||||
addToCurrentScope<V>(value: V): Handle<V>;
|
||||
openScope(envObject?: Env): HandleScope;
|
||||
closeScope(envObject?: Env, _scope?: HandleScope): void;
|
||||
ensureHandle<S>(value: S): Handle<S>;
|
||||
addCleanupHook(envObject: Env, fn: CleanupHookCallbackFunction, arg: number): void;
|
||||
removeCleanupHook(envObject: Env, fn: CleanupHookCallbackFunction, arg: number): void;
|
||||
runCleanup(): void;
|
||||
increaseWaitingRequestCounter(): void;
|
||||
decreaseWaitingRequestCounter(): void;
|
||||
setCanCallIntoJs(value: boolean): void;
|
||||
setStopping(value: boolean): void;
|
||||
canCallIntoJs(): boolean;
|
||||
/**
|
||||
* Destroy the context and call cleanup hooks.
|
||||
* Associated {@link Env | Env} will be destroyed.
|
||||
*/
|
||||
destroy(): void;
|
||||
}
|
||||
|
||||
export interface ContextOptions {
|
||||
onExternalMemoryChange?: (current: bigint, old: bigint, delta: bigint) => any;
|
||||
}
|
||||
|
||||
export function createContext(options?: ContextOptions): Context;
|
||||
|
||||
export class Deferred<T = any> implements IStoreValue {
|
||||
static create<T = any>(ctx: Context, value: IDeferrdValue<T>): Deferred;
|
||||
id: number;
|
||||
ctx: Context;
|
||||
value: IDeferrdValue<T>;
|
||||
constructor(ctx: Context, value: IDeferrdValue<T>);
|
||||
resolve(value: T): void;
|
||||
reject(reason?: any): void;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export class EmnapiError extends Error {
|
||||
constructor(message?: string);
|
||||
}
|
||||
|
||||
export abstract class Env implements IStoreValue {
|
||||
readonly ctx: Context;
|
||||
moduleApiVersion: number;
|
||||
makeDynCall_vppp: (cb: Ptr) => (a: Ptr, b: Ptr, c: Ptr) => void;
|
||||
makeDynCall_vp: (cb: Ptr) => (a: Ptr) => void;
|
||||
abort: (msg?: string) => never;
|
||||
id: number;
|
||||
openHandleScopes: number;
|
||||
instanceData: TrackedFinalizer | null;
|
||||
tryCatch: TryCatch;
|
||||
refs: number;
|
||||
reflist: RefTracker;
|
||||
finalizing_reflist: RefTracker;
|
||||
pendingFinalizers: RefTracker[];
|
||||
lastError: {
|
||||
errorCode: napi_status;
|
||||
engineErrorCode: number;
|
||||
engineReserved: Ptr;
|
||||
};
|
||||
inGcFinalizer: boolean;
|
||||
constructor(ctx: Context, moduleApiVersion: number, makeDynCall_vppp: (cb: Ptr) => (a: Ptr, b: Ptr, c: Ptr) => void, makeDynCall_vp: (cb: Ptr) => (a: Ptr) => void, abort: (msg?: string) => never);
|
||||
/** @virtual */
|
||||
canCallIntoJs(): boolean;
|
||||
terminatedOrTerminating(): boolean;
|
||||
ref(): void;
|
||||
unref(): void;
|
||||
ensureHandle<S>(value: S): Handle<S>;
|
||||
ensureHandleId(value: any): napi_value;
|
||||
clearLastError(): napi_status;
|
||||
setLastError(error_code: napi_status, engine_error_code?: uint32_t, engine_reserved?: void_p): napi_status;
|
||||
getReturnStatus(): napi_status;
|
||||
callIntoModule<T>(fn: (env: Env) => T, handleException?: (envObject: Env, value: any) => void): T;
|
||||
/** @virtual */
|
||||
abstract callFinalizer(cb: napi_finalize, data: void_p, hint: void_p): void;
|
||||
invokeFinalizerFromGC(finalizer: RefTracker): void;
|
||||
checkGCAccess(): void;
|
||||
/** @virtual */
|
||||
enqueueFinalizer(finalizer: RefTracker): void;
|
||||
/** @virtual */
|
||||
dequeueFinalizer(finalizer: RefTracker): void;
|
||||
/** @virtual */
|
||||
deleteMe(): void;
|
||||
dispose(): void;
|
||||
private readonly _bindingMap;
|
||||
initObjectBinding<S extends object>(value: S): IReferenceBinding;
|
||||
getObjectBinding<S extends object>(value: S): IReferenceBinding;
|
||||
setInstanceData(data: number, finalize_cb: number, finalize_hint: number): void;
|
||||
getInstanceData(): number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
interface External_2 extends Record<any, any> {
|
||||
}
|
||||
|
||||
/** @public */
|
||||
const External_2: {
|
||||
new (value: number | bigint): External_2;
|
||||
prototype: null;
|
||||
};
|
||||
export { External_2 as External }
|
||||
|
||||
export class Finalizer {
|
||||
envObject: Env;
|
||||
private _finalizeCallback;
|
||||
private _finalizeData;
|
||||
private _finalizeHint;
|
||||
private _makeDynCall_vppp;
|
||||
constructor(envObject: Env, _finalizeCallback?: napi_finalize, _finalizeData?: void_p, _finalizeHint?: void_p);
|
||||
callback(): napi_finalize;
|
||||
data(): void_p;
|
||||
hint(): void_p;
|
||||
resetEnv(): void;
|
||||
resetFinalizer(): void;
|
||||
callFinalizer(): void;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export function getDefaultContext(): Context;
|
||||
|
||||
/** @public */
|
||||
export function getExternalValue(external: External_2): number | bigint;
|
||||
|
||||
export class Handle<S> {
|
||||
id: number;
|
||||
value: S;
|
||||
constructor(id: number, value: S);
|
||||
data(): void_p;
|
||||
isNumber(): boolean;
|
||||
isBigInt(): boolean;
|
||||
isString(): boolean;
|
||||
isFunction(): boolean;
|
||||
isExternal(): boolean;
|
||||
isObject(): boolean;
|
||||
isArray(): boolean;
|
||||
isArrayBuffer(): boolean;
|
||||
isTypedArray(): boolean;
|
||||
isBuffer(BufferConstructor?: BufferCtor): boolean;
|
||||
isDataView(): boolean;
|
||||
isDate(): boolean;
|
||||
isPromise(): boolean;
|
||||
isBoolean(): boolean;
|
||||
isUndefined(): boolean;
|
||||
isSymbol(): boolean;
|
||||
isNull(): boolean;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export class HandleScope {
|
||||
handleStore: HandleStore;
|
||||
id: number;
|
||||
parent: HandleScope | null;
|
||||
child: HandleScope | null;
|
||||
start: number;
|
||||
end: number;
|
||||
private _escapeCalled;
|
||||
callbackInfo: ICallbackInfo;
|
||||
constructor(handleStore: HandleStore, id: number, parentScope: HandleScope | null, start: number, end?: number);
|
||||
add<V>(value: V): Handle<V>;
|
||||
addExternal(data: void_p): Handle<object>;
|
||||
dispose(): void;
|
||||
escape(handle: number): Handle<any> | null;
|
||||
escapeCalled(): boolean;
|
||||
}
|
||||
|
||||
export class HandleStore {
|
||||
static UNDEFINED: ConstHandle<undefined>;
|
||||
static NULL: ConstHandle<null>;
|
||||
static FALSE: ConstHandle<false>;
|
||||
static TRUE: ConstHandle<true>;
|
||||
static GLOBAL: ConstHandle<typeof globalThis>;
|
||||
static MIN_ID: 6;
|
||||
private readonly _values;
|
||||
private _next;
|
||||
push<S>(value: S): Handle<S>;
|
||||
erase(start: number, end: number): void;
|
||||
get(id: Ptr): Handle<any> | undefined;
|
||||
swap(a: number, b: number): void;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export interface ICallbackInfo {
|
||||
thiz: any;
|
||||
data: void_p;
|
||||
args: ArrayLike<any>;
|
||||
fn: Function;
|
||||
}
|
||||
|
||||
export interface IDeferrdValue<T = any> {
|
||||
resolve: (value: T) => void;
|
||||
reject: (reason?: any) => void;
|
||||
}
|
||||
|
||||
export interface IReferenceBinding {
|
||||
wrapped: number;
|
||||
tag: Uint32Array | null;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export function isExternal(object: unknown): object is External_2;
|
||||
|
||||
export function isReferenceType(v: any): v is object;
|
||||
|
||||
export interface IStoreValue {
|
||||
id: number;
|
||||
dispose(): void;
|
||||
[x: string]: any;
|
||||
}
|
||||
|
||||
export const NAPI_VERSION_EXPERIMENTAL = Version.NAPI_VERSION_EXPERIMENTAL;
|
||||
|
||||
export const NODE_API_DEFAULT_MODULE_API_VERSION = Version.NODE_API_DEFAULT_MODULE_API_VERSION;
|
||||
|
||||
export const NODE_API_SUPPORTED_VERSION_MAX = Version.NODE_API_SUPPORTED_VERSION_MAX;
|
||||
|
||||
export const NODE_API_SUPPORTED_VERSION_MIN = Version.NODE_API_SUPPORTED_VERSION_MIN;
|
||||
|
||||
export class NodeEnv extends Env {
|
||||
filename: string;
|
||||
private readonly nodeBinding?;
|
||||
destructing: boolean;
|
||||
finalizationScheduled: boolean;
|
||||
constructor(ctx: Context, filename: string, moduleApiVersion: number, makeDynCall_vppp: (cb: Ptr) => (a: Ptr, b: Ptr, c: Ptr) => void, makeDynCall_vp: (cb: Ptr) => (a: Ptr) => void, abort: (msg?: string) => never, nodeBinding?: any);
|
||||
deleteMe(): void;
|
||||
canCallIntoJs(): boolean;
|
||||
triggerFatalException(err: any): void;
|
||||
callbackIntoModule<T>(enforceUncaughtExceptionPolicy: boolean, fn: (env: Env) => T): T;
|
||||
callFinalizer(cb: napi_finalize, data: void_p, hint: void_p): void;
|
||||
callFinalizerInternal(forceUncaught: int, cb: napi_finalize, data: void_p, hint: void_p): void;
|
||||
enqueueFinalizer(finalizer: RefTracker): void;
|
||||
drainFinalizerQueue(): void;
|
||||
}
|
||||
|
||||
export class NotSupportBufferError extends EmnapiError {
|
||||
constructor(api: string, message: string);
|
||||
}
|
||||
|
||||
export class NotSupportWeakRefError extends EmnapiError {
|
||||
constructor(api: string, message: string);
|
||||
}
|
||||
|
||||
export class Persistent<T> {
|
||||
private _ref;
|
||||
private _param;
|
||||
private _callback;
|
||||
private static readonly _registry;
|
||||
constructor(value: T);
|
||||
setWeak<P>(param: P, callback: (param: P) => void): void;
|
||||
clearWeak(): void;
|
||||
reset(): void;
|
||||
isEmpty(): boolean;
|
||||
deref(): T | undefined;
|
||||
}
|
||||
|
||||
export class Reference extends RefTracker implements IStoreValue {
|
||||
private static weakCallback;
|
||||
id: number;
|
||||
envObject: Env;
|
||||
private readonly canBeWeak;
|
||||
private _refcount;
|
||||
private readonly _ownership;
|
||||
persistent: Persistent<object>;
|
||||
static create(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, _unused1?: void_p, _unused2?: void_p, _unused3?: void_p): Reference;
|
||||
protected constructor(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership);
|
||||
ref(): number;
|
||||
unref(): number;
|
||||
get(envObject?: Env): napi_value;
|
||||
/** @virtual */
|
||||
resetFinalizer(): void;
|
||||
/** @virtual */
|
||||
data(): void_p;
|
||||
refcount(): number;
|
||||
ownership(): ReferenceOwnership;
|
||||
/** @virtual */
|
||||
protected callUserFinalizer(): void;
|
||||
/** @virtual */
|
||||
protected invokeFinalizerFromGC(): void;
|
||||
private _setWeak;
|
||||
finalize(): void;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export enum ReferenceOwnership {
|
||||
kRuntime = 0,
|
||||
kUserland = 1
|
||||
}
|
||||
|
||||
export class ReferenceWithData extends Reference {
|
||||
private readonly _data;
|
||||
static create(envObject: Env, value: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, data: void_p): ReferenceWithData;
|
||||
private constructor();
|
||||
data(): void_p;
|
||||
}
|
||||
|
||||
export class ReferenceWithFinalizer extends Reference {
|
||||
private _finalizer;
|
||||
static create(envObject: Env, value: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, finalize_callback: napi_finalize, finalize_data: void_p, finalize_hint: void_p): ReferenceWithFinalizer;
|
||||
private constructor();
|
||||
resetFinalizer(): void;
|
||||
data(): void_p;
|
||||
protected callUserFinalizer(): void;
|
||||
protected invokeFinalizerFromGC(): void;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export class RefTracker {
|
||||
/** @virtual */
|
||||
dispose(): void;
|
||||
/** @virtual */
|
||||
finalize(): void;
|
||||
private _next;
|
||||
private _prev;
|
||||
link(list: RefTracker): void;
|
||||
unlink(): void;
|
||||
static finalizeAll(list: RefTracker): void;
|
||||
}
|
||||
|
||||
export class ScopeStore {
|
||||
private readonly _rootScope;
|
||||
currentScope: HandleScope;
|
||||
private readonly _values;
|
||||
constructor();
|
||||
get(id: number): HandleScope | undefined;
|
||||
openScope(handleStore: HandleStore): HandleScope;
|
||||
closeScope(): void;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export class Store<V extends IStoreValue> {
|
||||
protected _values: Array<V | undefined>;
|
||||
private _freeList;
|
||||
private _size;
|
||||
constructor();
|
||||
add(value: V): void;
|
||||
get(id: Ptr): V | undefined;
|
||||
has(id: Ptr): boolean;
|
||||
remove(id: Ptr): void;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export class TrackedFinalizer extends RefTracker {
|
||||
private _finalizer;
|
||||
static create(envObject: Env, finalize_callback: napi_finalize, finalize_data: void_p, finalize_hint: void_p): TrackedFinalizer;
|
||||
private constructor();
|
||||
data(): void_p;
|
||||
dispose(): void;
|
||||
finalize(): void;
|
||||
}
|
||||
|
||||
export class TryCatch {
|
||||
private _exception;
|
||||
private _caught;
|
||||
isEmpty(): boolean;
|
||||
hasCaught(): boolean;
|
||||
exception(): any;
|
||||
setError(err: any): void;
|
||||
reset(): void;
|
||||
extractException(): any;
|
||||
}
|
||||
|
||||
export const version: string;
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
+1509
File diff suppressed because it is too large
Load Diff
+1510
File diff suppressed because it is too large
Load Diff
+671
@@ -0,0 +1,671 @@
|
||||
export declare type Ptr = number | bigint
|
||||
|
||||
export declare interface IBuffer extends Uint8Array {}
|
||||
export declare interface BufferCtor {
|
||||
readonly prototype: IBuffer
|
||||
/** @deprecated */
|
||||
new (...args: any[]): IBuffer
|
||||
from: {
|
||||
(buffer: ArrayBufferLike): IBuffer
|
||||
(buffer: ArrayBufferLike, byteOffset: number, length: number): IBuffer
|
||||
}
|
||||
alloc: (size: number) => IBuffer
|
||||
isBuffer: (obj: unknown) => obj is IBuffer
|
||||
}
|
||||
|
||||
export declare const enum GlobalHandle {
|
||||
UNDEFINED = 1,
|
||||
NULL,
|
||||
FALSE,
|
||||
TRUE,
|
||||
GLOBAL
|
||||
}
|
||||
|
||||
export declare const enum Version {
|
||||
NODE_API_SUPPORTED_VERSION_MIN = 1,
|
||||
NODE_API_DEFAULT_MODULE_API_VERSION = 8,
|
||||
NODE_API_SUPPORTED_VERSION_MAX = 10,
|
||||
NAPI_VERSION_EXPERIMENTAL = 2147483647 // INT_MAX
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export declare type Pointer<T> = number
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export declare type PointerPointer<T> = number
|
||||
export declare type FunctionPointer<T extends (...args: any[]) => any> = Pointer<T>
|
||||
export declare type Const<T> = T
|
||||
|
||||
export declare type void_p = Pointer<void>
|
||||
export declare type void_pp = Pointer<void_p>
|
||||
export declare type bool = number
|
||||
export declare type char = number
|
||||
export declare type char_p = Pointer<char>
|
||||
export declare type unsigned_char = number
|
||||
export declare type const_char = Const<char>
|
||||
export declare type const_char_p = Pointer<const_char>
|
||||
export declare type char16_t_p = number
|
||||
export declare type const_char16_t_p = number
|
||||
|
||||
export declare type short = number
|
||||
export declare type unsigned_short = number
|
||||
export declare type int = number
|
||||
export declare type unsigned_int = number
|
||||
export declare type long = number
|
||||
export declare type unsigned_long = number
|
||||
export declare type long_long = bigint
|
||||
export declare type unsigned_long_long = bigint
|
||||
export declare type float = number
|
||||
export declare type double = number
|
||||
export declare type long_double = number
|
||||
export declare type size_t = number
|
||||
|
||||
export declare type int8_t = number
|
||||
export declare type uint8_t = number
|
||||
export declare type int16_t = number
|
||||
export declare type uint16_t = number
|
||||
export declare type int32_t = number
|
||||
export declare type uint32_t = number
|
||||
export declare type int64_t = bigint
|
||||
export declare type uint64_t = bigint
|
||||
export declare type napi_env = Pointer<unknown>
|
||||
|
||||
export declare type napi_value = Pointer<unknown>
|
||||
export declare type napi_ref = Pointer<unknown>
|
||||
export declare type napi_deferred = Pointer<unknown>
|
||||
export declare type napi_handle_scope = Pointer<unknown>
|
||||
export declare type napi_escapable_handle_scope = Pointer<unknown>
|
||||
|
||||
export declare type napi_addon_register_func = FunctionPointer<(env: napi_env, exports: napi_value) => napi_value>
|
||||
|
||||
export declare type napi_callback_info = Pointer<unknown>
|
||||
export declare type napi_callback = FunctionPointer<(env: napi_env, info: napi_callback_info) => napi_value>
|
||||
|
||||
export declare interface napi_extended_error_info {
|
||||
error_message: const_char_p
|
||||
engine_reserved: void_p
|
||||
engine_error_code: uint32_t
|
||||
error_code: napi_status
|
||||
}
|
||||
|
||||
export declare interface napi_property_descriptor {
|
||||
// One of utf8name or name should be NULL.
|
||||
utf8name: const_char_p
|
||||
name: napi_value
|
||||
|
||||
method: napi_callback
|
||||
getter: napi_callback
|
||||
setter: napi_callback
|
||||
value: napi_value
|
||||
/* napi_property_attributes */
|
||||
attributes: number
|
||||
data: void_p
|
||||
}
|
||||
|
||||
export declare type napi_finalize = FunctionPointer<(
|
||||
env: napi_env,
|
||||
finalize_data: void_p,
|
||||
finalize_hint: void_p
|
||||
) => void>
|
||||
|
||||
export declare interface node_module {
|
||||
nm_version: int32_t
|
||||
nm_flags: uint32_t
|
||||
nm_filename: Pointer<const_char>
|
||||
nm_register_func: napi_addon_register_func
|
||||
nm_modname: Pointer<const_char>
|
||||
nm_priv: Pointer<void>
|
||||
reserved: PointerPointer<void>
|
||||
}
|
||||
|
||||
export declare interface napi_node_version {
|
||||
major: uint32_t
|
||||
minor: uint32_t
|
||||
patch: uint32_t
|
||||
release: const_char_p
|
||||
}
|
||||
|
||||
export declare interface emnapi_emscripten_version {
|
||||
major: uint32_t
|
||||
minor: uint32_t
|
||||
patch: uint32_t
|
||||
}
|
||||
|
||||
export declare const enum napi_status {
|
||||
napi_ok,
|
||||
napi_invalid_arg,
|
||||
napi_object_expected,
|
||||
napi_string_expected,
|
||||
napi_name_expected,
|
||||
napi_function_expected,
|
||||
napi_number_expected,
|
||||
napi_boolean_expected,
|
||||
napi_array_expected,
|
||||
napi_generic_failure,
|
||||
napi_pending_exception,
|
||||
napi_cancelled,
|
||||
napi_escape_called_twice,
|
||||
napi_handle_scope_mismatch,
|
||||
napi_callback_scope_mismatch,
|
||||
napi_queue_full,
|
||||
napi_closing,
|
||||
napi_bigint_expected,
|
||||
napi_date_expected,
|
||||
napi_arraybuffer_expected,
|
||||
napi_detachable_arraybuffer_expected,
|
||||
napi_would_deadlock, // unused
|
||||
napi_no_external_buffers_allowed,
|
||||
napi_cannot_run_js
|
||||
}
|
||||
|
||||
export declare const enum napi_property_attributes {
|
||||
napi_default = 0,
|
||||
napi_writable = 1 << 0,
|
||||
napi_enumerable = 1 << 1,
|
||||
napi_configurable = 1 << 2,
|
||||
|
||||
// Used with napi_define_class to distinguish static properties
|
||||
// from instance properties. Ignored by napi_define_properties.
|
||||
napi_static = 1 << 10,
|
||||
|
||||
/// #ifdef NAPI_EXPERIMENTAL
|
||||
// Default for class methods.
|
||||
napi_default_method = napi_writable | napi_configurable,
|
||||
|
||||
// Default for object properties, like in JS obj[prop].
|
||||
napi_default_jsproperty = napi_writable | napi_enumerable | napi_configurable
|
||||
/// #endif // NAPI_EXPERIMENTAL
|
||||
}
|
||||
|
||||
export declare const enum napi_valuetype {
|
||||
napi_undefined,
|
||||
napi_null,
|
||||
napi_boolean,
|
||||
napi_number,
|
||||
napi_string,
|
||||
napi_symbol,
|
||||
napi_object,
|
||||
napi_function,
|
||||
napi_external,
|
||||
napi_bigint
|
||||
}
|
||||
|
||||
export declare const enum napi_typedarray_type {
|
||||
napi_int8_array,
|
||||
napi_uint8_array,
|
||||
napi_uint8_clamped_array,
|
||||
napi_int16_array,
|
||||
napi_uint16_array,
|
||||
napi_int32_array,
|
||||
napi_uint32_array,
|
||||
napi_float32_array,
|
||||
napi_float64_array,
|
||||
napi_bigint64_array,
|
||||
napi_biguint64_array,
|
||||
napi_float16_array,
|
||||
}
|
||||
|
||||
export declare const enum napi_key_collection_mode {
|
||||
napi_key_include_prototypes,
|
||||
napi_key_own_only
|
||||
}
|
||||
|
||||
export declare const enum napi_key_filter {
|
||||
napi_key_all_properties = 0,
|
||||
napi_key_writable = 1,
|
||||
napi_key_enumerable = 1 << 1,
|
||||
napi_key_configurable = 1 << 2,
|
||||
napi_key_skip_strings = 1 << 3,
|
||||
napi_key_skip_symbols = 1 << 4
|
||||
}
|
||||
|
||||
export declare const enum napi_key_conversion {
|
||||
napi_key_keep_numbers,
|
||||
napi_key_numbers_to_strings
|
||||
}
|
||||
|
||||
export declare const enum emnapi_memory_view_type {
|
||||
emnapi_int8_array,
|
||||
emnapi_uint8_array,
|
||||
emnapi_uint8_clamped_array,
|
||||
emnapi_int16_array,
|
||||
emnapi_uint16_array,
|
||||
emnapi_int32_array,
|
||||
emnapi_uint32_array,
|
||||
emnapi_float32_array,
|
||||
emnapi_float64_array,
|
||||
emnapi_bigint64_array,
|
||||
emnapi_biguint64_array,
|
||||
emnapi_float16_array,
|
||||
emnapi_data_view = -1,
|
||||
emnapi_buffer = -2
|
||||
}
|
||||
|
||||
export declare const enum napi_threadsafe_function_call_mode {
|
||||
napi_tsfn_nonblocking,
|
||||
napi_tsfn_blocking
|
||||
}
|
||||
|
||||
export declare const enum napi_threadsafe_function_release_mode {
|
||||
napi_tsfn_release,
|
||||
napi_tsfn_abort
|
||||
}
|
||||
export declare type CleanupHookCallbackFunction = number | ((arg: number) => void);
|
||||
|
||||
export declare class ConstHandle<S extends undefined | null | boolean | typeof globalThis> extends Handle<S> {
|
||||
constructor(id: number, value: S);
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export declare class Context {
|
||||
private _isStopping;
|
||||
private _canCallIntoJs;
|
||||
private _suppressDestroy;
|
||||
envStore: Store<Env>;
|
||||
scopeStore: ScopeStore;
|
||||
refStore: Store<Reference>;
|
||||
deferredStore: Store<Deferred<any>>;
|
||||
handleStore: HandleStore;
|
||||
private readonly refCounter?;
|
||||
private readonly cleanupQueue;
|
||||
private readonly _externalMemory;
|
||||
feature: {
|
||||
supportReflect: boolean;
|
||||
supportFinalizer: boolean;
|
||||
supportWeakSymbol: boolean;
|
||||
supportBigInt: boolean;
|
||||
supportNewFunction: boolean;
|
||||
canSetFunctionName: boolean;
|
||||
setImmediate: (callback: () => void) => void;
|
||||
Buffer: BufferCtor | undefined;
|
||||
MessageChannel: {
|
||||
new (): MessageChannel;
|
||||
prototype: MessageChannel;
|
||||
} | undefined;
|
||||
};
|
||||
constructor(options?: ContextOptions);
|
||||
/**
|
||||
* Suppress the destroy on `beforeExit` event in Node.js.
|
||||
* Call this method if you want to keep the context and
|
||||
* all associated {@link Env | Env} alive,
|
||||
* this also means that cleanup hooks will not be called.
|
||||
* After call this method, you should call
|
||||
* {@link Context.destroy | `Context.prototype.destroy`} method manually.
|
||||
*/
|
||||
suppressDestroy(): void;
|
||||
getRuntimeVersions(): {
|
||||
version: string;
|
||||
NODE_API_SUPPORTED_VERSION_MAX: Version;
|
||||
NAPI_VERSION_EXPERIMENTAL: Version;
|
||||
NODE_API_DEFAULT_MODULE_API_VERSION: Version;
|
||||
};
|
||||
createNotSupportWeakRefError(api: string, message: string): NotSupportWeakRefError;
|
||||
createNotSupportBufferError(api: string, message: string): NotSupportBufferError;
|
||||
createReference(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership): Reference;
|
||||
createReferenceWithData(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, data: void_p): Reference;
|
||||
createReferenceWithFinalizer(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, finalize_callback?: napi_finalize, finalize_data?: void_p, finalize_hint?: void_p): Reference;
|
||||
createDeferred<T = any>(value: IDeferrdValue<T>): Deferred<T>;
|
||||
adjustAmountOfExternalAllocatedMemory(changeInBytes: number | bigint): bigint;
|
||||
createEnv(filename: string, moduleApiVersion: number, makeDynCall_vppp: (cb: Ptr) => (a: Ptr, b: Ptr, c: Ptr) => void, makeDynCall_vp: (cb: Ptr) => (a: Ptr) => void, abort: (msg?: string) => never, nodeBinding?: any): Env;
|
||||
createTrackedFinalizer(envObject: Env, finalize_callback: napi_finalize, finalize_data: void_p, finalize_hint: void_p): TrackedFinalizer;
|
||||
getCurrentScope(): HandleScope | null;
|
||||
addToCurrentScope<V>(value: V): Handle<V>;
|
||||
openScope(envObject?: Env): HandleScope;
|
||||
closeScope(envObject?: Env, _scope?: HandleScope): void;
|
||||
ensureHandle<S>(value: S): Handle<S>;
|
||||
addCleanupHook(envObject: Env, fn: CleanupHookCallbackFunction, arg: number): void;
|
||||
removeCleanupHook(envObject: Env, fn: CleanupHookCallbackFunction, arg: number): void;
|
||||
runCleanup(): void;
|
||||
increaseWaitingRequestCounter(): void;
|
||||
decreaseWaitingRequestCounter(): void;
|
||||
setCanCallIntoJs(value: boolean): void;
|
||||
setStopping(value: boolean): void;
|
||||
canCallIntoJs(): boolean;
|
||||
/**
|
||||
* Destroy the context and call cleanup hooks.
|
||||
* Associated {@link Env | Env} will be destroyed.
|
||||
*/
|
||||
destroy(): void;
|
||||
}
|
||||
|
||||
export declare interface ContextOptions {
|
||||
onExternalMemoryChange?: (current: bigint, old: bigint, delta: bigint) => any;
|
||||
}
|
||||
|
||||
export declare function createContext(options?: ContextOptions): Context;
|
||||
|
||||
export declare class Deferred<T = any> implements IStoreValue {
|
||||
static create<T = any>(ctx: Context, value: IDeferrdValue<T>): Deferred;
|
||||
id: number;
|
||||
ctx: Context;
|
||||
value: IDeferrdValue<T>;
|
||||
constructor(ctx: Context, value: IDeferrdValue<T>);
|
||||
resolve(value: T): void;
|
||||
reject(reason?: any): void;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export declare class EmnapiError extends Error {
|
||||
constructor(message?: string);
|
||||
}
|
||||
|
||||
export declare abstract class Env implements IStoreValue {
|
||||
readonly ctx: Context;
|
||||
moduleApiVersion: number;
|
||||
makeDynCall_vppp: (cb: Ptr) => (a: Ptr, b: Ptr, c: Ptr) => void;
|
||||
makeDynCall_vp: (cb: Ptr) => (a: Ptr) => void;
|
||||
abort: (msg?: string) => never;
|
||||
id: number;
|
||||
openHandleScopes: number;
|
||||
instanceData: TrackedFinalizer | null;
|
||||
tryCatch: TryCatch;
|
||||
refs: number;
|
||||
reflist: RefTracker;
|
||||
finalizing_reflist: RefTracker;
|
||||
pendingFinalizers: RefTracker[];
|
||||
lastError: {
|
||||
errorCode: napi_status;
|
||||
engineErrorCode: number;
|
||||
engineReserved: Ptr;
|
||||
};
|
||||
inGcFinalizer: boolean;
|
||||
constructor(ctx: Context, moduleApiVersion: number, makeDynCall_vppp: (cb: Ptr) => (a: Ptr, b: Ptr, c: Ptr) => void, makeDynCall_vp: (cb: Ptr) => (a: Ptr) => void, abort: (msg?: string) => never);
|
||||
/** @virtual */
|
||||
canCallIntoJs(): boolean;
|
||||
terminatedOrTerminating(): boolean;
|
||||
ref(): void;
|
||||
unref(): void;
|
||||
ensureHandle<S>(value: S): Handle<S>;
|
||||
ensureHandleId(value: any): napi_value;
|
||||
clearLastError(): napi_status;
|
||||
setLastError(error_code: napi_status, engine_error_code?: uint32_t, engine_reserved?: void_p): napi_status;
|
||||
getReturnStatus(): napi_status;
|
||||
callIntoModule<T>(fn: (env: Env) => T, handleException?: (envObject: Env, value: any) => void): T;
|
||||
/** @virtual */
|
||||
abstract callFinalizer(cb: napi_finalize, data: void_p, hint: void_p): void;
|
||||
invokeFinalizerFromGC(finalizer: RefTracker): void;
|
||||
checkGCAccess(): void;
|
||||
/** @virtual */
|
||||
enqueueFinalizer(finalizer: RefTracker): void;
|
||||
/** @virtual */
|
||||
dequeueFinalizer(finalizer: RefTracker): void;
|
||||
/** @virtual */
|
||||
deleteMe(): void;
|
||||
dispose(): void;
|
||||
private readonly _bindingMap;
|
||||
initObjectBinding<S extends object>(value: S): IReferenceBinding;
|
||||
getObjectBinding<S extends object>(value: S): IReferenceBinding;
|
||||
setInstanceData(data: number, finalize_cb: number, finalize_hint: number): void;
|
||||
getInstanceData(): number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
declare interface External_2 extends Record<any, any> {
|
||||
}
|
||||
|
||||
/** @public */
|
||||
declare const External_2: {
|
||||
new (value: number | bigint): External_2;
|
||||
prototype: null;
|
||||
};
|
||||
export { External_2 as External }
|
||||
|
||||
export declare class Finalizer {
|
||||
envObject: Env;
|
||||
private _finalizeCallback;
|
||||
private _finalizeData;
|
||||
private _finalizeHint;
|
||||
private _makeDynCall_vppp;
|
||||
constructor(envObject: Env, _finalizeCallback?: napi_finalize, _finalizeData?: void_p, _finalizeHint?: void_p);
|
||||
callback(): napi_finalize;
|
||||
data(): void_p;
|
||||
hint(): void_p;
|
||||
resetEnv(): void;
|
||||
resetFinalizer(): void;
|
||||
callFinalizer(): void;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export declare function getDefaultContext(): Context;
|
||||
|
||||
/** @public */
|
||||
export declare function getExternalValue(external: External_2): number | bigint;
|
||||
|
||||
export declare class Handle<S> {
|
||||
id: number;
|
||||
value: S;
|
||||
constructor(id: number, value: S);
|
||||
data(): void_p;
|
||||
isNumber(): boolean;
|
||||
isBigInt(): boolean;
|
||||
isString(): boolean;
|
||||
isFunction(): boolean;
|
||||
isExternal(): boolean;
|
||||
isObject(): boolean;
|
||||
isArray(): boolean;
|
||||
isArrayBuffer(): boolean;
|
||||
isTypedArray(): boolean;
|
||||
isBuffer(BufferConstructor?: BufferCtor): boolean;
|
||||
isDataView(): boolean;
|
||||
isDate(): boolean;
|
||||
isPromise(): boolean;
|
||||
isBoolean(): boolean;
|
||||
isUndefined(): boolean;
|
||||
isSymbol(): boolean;
|
||||
isNull(): boolean;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export declare class HandleScope {
|
||||
handleStore: HandleStore;
|
||||
id: number;
|
||||
parent: HandleScope | null;
|
||||
child: HandleScope | null;
|
||||
start: number;
|
||||
end: number;
|
||||
private _escapeCalled;
|
||||
callbackInfo: ICallbackInfo;
|
||||
constructor(handleStore: HandleStore, id: number, parentScope: HandleScope | null, start: number, end?: number);
|
||||
add<V>(value: V): Handle<V>;
|
||||
addExternal(data: void_p): Handle<object>;
|
||||
dispose(): void;
|
||||
escape(handle: number): Handle<any> | null;
|
||||
escapeCalled(): boolean;
|
||||
}
|
||||
|
||||
export declare class HandleStore {
|
||||
static UNDEFINED: ConstHandle<undefined>;
|
||||
static NULL: ConstHandle<null>;
|
||||
static FALSE: ConstHandle<false>;
|
||||
static TRUE: ConstHandle<true>;
|
||||
static GLOBAL: ConstHandle<typeof globalThis>;
|
||||
static MIN_ID: 6;
|
||||
private readonly _values;
|
||||
private _next;
|
||||
push<S>(value: S): Handle<S>;
|
||||
erase(start: number, end: number): void;
|
||||
get(id: Ptr): Handle<any> | undefined;
|
||||
swap(a: number, b: number): void;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export declare interface ICallbackInfo {
|
||||
thiz: any;
|
||||
data: void_p;
|
||||
args: ArrayLike<any>;
|
||||
fn: Function;
|
||||
}
|
||||
|
||||
export declare interface IDeferrdValue<T = any> {
|
||||
resolve: (value: T) => void;
|
||||
reject: (reason?: any) => void;
|
||||
}
|
||||
|
||||
export declare interface IReferenceBinding {
|
||||
wrapped: number;
|
||||
tag: Uint32Array | null;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare function isExternal(object: unknown): object is External_2;
|
||||
|
||||
export declare function isReferenceType(v: any): v is object;
|
||||
|
||||
export declare interface IStoreValue {
|
||||
id: number;
|
||||
dispose(): void;
|
||||
[x: string]: any;
|
||||
}
|
||||
|
||||
export declare const NAPI_VERSION_EXPERIMENTAL = Version.NAPI_VERSION_EXPERIMENTAL;
|
||||
|
||||
export declare const NODE_API_DEFAULT_MODULE_API_VERSION = Version.NODE_API_DEFAULT_MODULE_API_VERSION;
|
||||
|
||||
export declare const NODE_API_SUPPORTED_VERSION_MAX = Version.NODE_API_SUPPORTED_VERSION_MAX;
|
||||
|
||||
export declare const NODE_API_SUPPORTED_VERSION_MIN = Version.NODE_API_SUPPORTED_VERSION_MIN;
|
||||
|
||||
export declare class NodeEnv extends Env {
|
||||
filename: string;
|
||||
private readonly nodeBinding?;
|
||||
destructing: boolean;
|
||||
finalizationScheduled: boolean;
|
||||
constructor(ctx: Context, filename: string, moduleApiVersion: number, makeDynCall_vppp: (cb: Ptr) => (a: Ptr, b: Ptr, c: Ptr) => void, makeDynCall_vp: (cb: Ptr) => (a: Ptr) => void, abort: (msg?: string) => never, nodeBinding?: any);
|
||||
deleteMe(): void;
|
||||
canCallIntoJs(): boolean;
|
||||
triggerFatalException(err: any): void;
|
||||
callbackIntoModule<T>(enforceUncaughtExceptionPolicy: boolean, fn: (env: Env) => T): T;
|
||||
callFinalizer(cb: napi_finalize, data: void_p, hint: void_p): void;
|
||||
callFinalizerInternal(forceUncaught: int, cb: napi_finalize, data: void_p, hint: void_p): void;
|
||||
enqueueFinalizer(finalizer: RefTracker): void;
|
||||
drainFinalizerQueue(): void;
|
||||
}
|
||||
|
||||
export declare class NotSupportBufferError extends EmnapiError {
|
||||
constructor(api: string, message: string);
|
||||
}
|
||||
|
||||
export declare class NotSupportWeakRefError extends EmnapiError {
|
||||
constructor(api: string, message: string);
|
||||
}
|
||||
|
||||
export declare class Persistent<T> {
|
||||
private _ref;
|
||||
private _param;
|
||||
private _callback;
|
||||
private static readonly _registry;
|
||||
constructor(value: T);
|
||||
setWeak<P>(param: P, callback: (param: P) => void): void;
|
||||
clearWeak(): void;
|
||||
reset(): void;
|
||||
isEmpty(): boolean;
|
||||
deref(): T | undefined;
|
||||
}
|
||||
|
||||
export declare class Reference extends RefTracker implements IStoreValue {
|
||||
private static weakCallback;
|
||||
id: number;
|
||||
envObject: Env;
|
||||
private readonly canBeWeak;
|
||||
private _refcount;
|
||||
private readonly _ownership;
|
||||
persistent: Persistent<object>;
|
||||
static create(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, _unused1?: void_p, _unused2?: void_p, _unused3?: void_p): Reference;
|
||||
protected constructor(envObject: Env, handle_id: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership);
|
||||
ref(): number;
|
||||
unref(): number;
|
||||
get(envObject?: Env): napi_value;
|
||||
/** @virtual */
|
||||
resetFinalizer(): void;
|
||||
/** @virtual */
|
||||
data(): void_p;
|
||||
refcount(): number;
|
||||
ownership(): ReferenceOwnership;
|
||||
/** @virtual */
|
||||
protected callUserFinalizer(): void;
|
||||
/** @virtual */
|
||||
protected invokeFinalizerFromGC(): void;
|
||||
private _setWeak;
|
||||
finalize(): void;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export declare enum ReferenceOwnership {
|
||||
kRuntime = 0,
|
||||
kUserland = 1
|
||||
}
|
||||
|
||||
export declare class ReferenceWithData extends Reference {
|
||||
private readonly _data;
|
||||
static create(envObject: Env, value: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, data: void_p): ReferenceWithData;
|
||||
private constructor();
|
||||
data(): void_p;
|
||||
}
|
||||
|
||||
export declare class ReferenceWithFinalizer extends Reference {
|
||||
private _finalizer;
|
||||
static create(envObject: Env, value: napi_value, initialRefcount: uint32_t, ownership: ReferenceOwnership, finalize_callback: napi_finalize, finalize_data: void_p, finalize_hint: void_p): ReferenceWithFinalizer;
|
||||
private constructor();
|
||||
resetFinalizer(): void;
|
||||
data(): void_p;
|
||||
protected callUserFinalizer(): void;
|
||||
protected invokeFinalizerFromGC(): void;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export declare class RefTracker {
|
||||
/** @virtual */
|
||||
dispose(): void;
|
||||
/** @virtual */
|
||||
finalize(): void;
|
||||
private _next;
|
||||
private _prev;
|
||||
link(list: RefTracker): void;
|
||||
unlink(): void;
|
||||
static finalizeAll(list: RefTracker): void;
|
||||
}
|
||||
|
||||
export declare class ScopeStore {
|
||||
private readonly _rootScope;
|
||||
currentScope: HandleScope;
|
||||
private readonly _values;
|
||||
constructor();
|
||||
get(id: number): HandleScope | undefined;
|
||||
openScope(handleStore: HandleStore): HandleScope;
|
||||
closeScope(): void;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export declare class Store<V extends IStoreValue> {
|
||||
protected _values: Array<V | undefined>;
|
||||
private _freeList;
|
||||
private _size;
|
||||
constructor();
|
||||
add(value: V): void;
|
||||
get(id: Ptr): V | undefined;
|
||||
has(id: Ptr): boolean;
|
||||
remove(id: Ptr): void;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export declare class TrackedFinalizer extends RefTracker {
|
||||
private _finalizer;
|
||||
static create(envObject: Env, finalize_callback: napi_finalize, finalize_data: void_p, finalize_hint: void_p): TrackedFinalizer;
|
||||
private constructor();
|
||||
data(): void_p;
|
||||
dispose(): void;
|
||||
finalize(): void;
|
||||
}
|
||||
|
||||
export declare class TryCatch {
|
||||
private _exception;
|
||||
private _caught;
|
||||
isEmpty(): boolean;
|
||||
hasCaught(): boolean;
|
||||
exception(): any;
|
||||
setError(err: any): void;
|
||||
reset(): void;
|
||||
extractException(): any;
|
||||
}
|
||||
|
||||
export declare const version: string;
|
||||
|
||||
export { }
|
||||
+1
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
+1350
File diff suppressed because it is too large
Load Diff
+5
@@ -0,0 +1,5 @@
|
||||
if (typeof process !== 'undefined' && process.env.NODE_ENV === 'production') {
|
||||
module.exports = require('./dist/emnapi.cjs.min.js')
|
||||
} else {
|
||||
module.exports = require('./dist/emnapi.cjs.js')
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"name": "@emnapi/runtime",
|
||||
"version": "1.10.0",
|
||||
"description": "emnapi runtime",
|
||||
"main": "index.js",
|
||||
"module": "./dist/emnapi.esm-bundler.js",
|
||||
"types": "./dist/emnapi.d.ts",
|
||||
"sideEffects": false,
|
||||
"exports": {
|
||||
".": {
|
||||
"types": {
|
||||
"module": "./dist/emnapi.d.ts",
|
||||
"import": "./dist/emnapi.d.mts",
|
||||
"default": "./dist/emnapi.d.ts"
|
||||
},
|
||||
"module": "./dist/emnapi.esm-bundler.js",
|
||||
"import": "./dist/emnapi.mjs",
|
||||
"default": "./index.js"
|
||||
},
|
||||
"./dist/emnapi.cjs.min": {
|
||||
"types": "./dist/emnapi.d.ts",
|
||||
"default": "./dist/emnapi.cjs.min.js"
|
||||
},
|
||||
"./dist/emnapi.min.mjs": {
|
||||
"types": "./dist/emnapi.d.mts",
|
||||
"default": "./dist/emnapi.min.mjs"
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "node ./script/build.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/toyobayashi/emnapi.git"
|
||||
},
|
||||
"author": "toyobayashi",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/toyobayashi/emnapi/issues"
|
||||
},
|
||||
"homepage": "https://github.com/toyobayashi/emnapi#readme",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021-present Toyobayashi
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
+203
@@ -0,0 +1,203 @@
|
||||
# @emnapi/wasi-threads
|
||||
|
||||
This package makes [wasi-threads proposal](https://github.com/WebAssembly/wasi-threads) based WASI modules work in Node.js and browser.
|
||||
|
||||
## Quick Start
|
||||
|
||||
`index.html`
|
||||
|
||||
```html
|
||||
<script src="./node_modules/@tybys/wasm-util/dist/wasm-util.js"></script>
|
||||
<script src="./node_modules/@emnapi/wasi-threads/dist/wasi-threads.js"></script>
|
||||
<script src="./index.js"></script>
|
||||
```
|
||||
|
||||
If your application will block browser main thread (for example `pthread_join`), please run it in worker instead.
|
||||
|
||||
```html
|
||||
<script>
|
||||
// pthread_join (Atomics.wait) cannot be called in browser main thread
|
||||
new Worker('./index.js')
|
||||
</script>
|
||||
```
|
||||
|
||||
`index.js`
|
||||
|
||||
```js
|
||||
const ENVIRONMENT_IS_NODE =
|
||||
typeof process === 'object' && process !== null &&
|
||||
typeof process.versions === 'object' && process.versions !== null &&
|
||||
typeof process.versions.node === 'string';
|
||||
|
||||
(function (main) {
|
||||
if (ENVIRONMENT_IS_NODE) {
|
||||
main(require)
|
||||
} else {
|
||||
if (typeof importScripts === 'function') {
|
||||
importScripts('./node_modules/@tybys/wasm-util/dist/wasm-util.js')
|
||||
importScripts('./node_modules/@emnapi/wasi-threads/dist/wasi-threads.js')
|
||||
}
|
||||
const nodeWasi = { WASI: globalThis.wasmUtil.WASI }
|
||||
const nodeWorkerThreads = {
|
||||
Worker: globalThis.Worker
|
||||
}
|
||||
const _require = function (request) {
|
||||
if (request === 'node:wasi' || request === 'wasi') return nodeWasi
|
||||
if (request === 'node:worker_threads' || request === 'worker_threads') return nodeWorkerThreads
|
||||
if (request === '@emnapi/wasi-threads') return globalThis.wasiThreads
|
||||
throw new Error('Can not find module: ' + request)
|
||||
}
|
||||
main(_require)
|
||||
}
|
||||
})(async function (require) {
|
||||
const { WASI } = require('wasi')
|
||||
const { Worker } = require('worker_threads')
|
||||
const { WASIThreads } = require('@emnapi/wasi-threads')
|
||||
|
||||
const wasi = new WASI({
|
||||
version: 'preview1'
|
||||
})
|
||||
const wasiThreads = new WASIThreads({
|
||||
wasi,
|
||||
|
||||
/**
|
||||
* avoid Atomics.wait() deadlock during thread creation in browser
|
||||
* see https://emscripten.org/docs/tools_reference/settings_reference.html#pthread-pool-size
|
||||
*/
|
||||
reuseWorker: ENVIRONMENT_IS_NODE
|
||||
? false
|
||||
: {
|
||||
size: 4 /** greater than actual needs (2) */,
|
||||
strict: true
|
||||
},
|
||||
|
||||
/**
|
||||
* Synchronous thread creation
|
||||
* pthread_create will not return until thread worker actually starts
|
||||
*/
|
||||
waitThreadStart: typeof window === 'undefined' ? 1000 : false,
|
||||
|
||||
onCreateWorker: () => {
|
||||
return new Worker('./worker.js', {
|
||||
execArgv: ['--experimental-wasi-unstable-preview1']
|
||||
})
|
||||
}
|
||||
})
|
||||
const memory = new WebAssembly.Memory({
|
||||
initial: 16777216 / 65536,
|
||||
maximum: 2147483648 / 65536,
|
||||
shared: true
|
||||
})
|
||||
let input
|
||||
const file = 'path/to/your/wasi-module.wasm'
|
||||
try {
|
||||
input = require('fs').readFileSync(require('path').join(__dirname, file))
|
||||
} catch (err) {
|
||||
const response = await fetch(file)
|
||||
input = await response.arrayBuffer()
|
||||
}
|
||||
let { module, instance } = await WebAssembly.instantiate(input, {
|
||||
env: { memory },
|
||||
wasi_snapshot_preview1: wasi.wasiImport,
|
||||
...wasiThreads.getImportObject()
|
||||
})
|
||||
|
||||
wasiThreads.setup(instance, module, memory)
|
||||
await wasiThreads.preloadWorkers()
|
||||
|
||||
if (typeof instance.exports._start === 'function') {
|
||||
return wasi.start(instance)
|
||||
} else {
|
||||
wasi.initialize(instance)
|
||||
// instance.exports.exported_wasm_function()
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
`worker.js`
|
||||
|
||||
```js
|
||||
(function (main) {
|
||||
const ENVIRONMENT_IS_NODE =
|
||||
typeof process === 'object' && process !== null &&
|
||||
typeof process.versions === 'object' && process.versions !== null &&
|
||||
typeof process.versions.node === 'string'
|
||||
|
||||
if (ENVIRONMENT_IS_NODE) {
|
||||
const _require = function (request) {
|
||||
return require(request)
|
||||
}
|
||||
|
||||
const _init = function () {
|
||||
const nodeWorkerThreads = require('worker_threads')
|
||||
const parentPort = nodeWorkerThreads.parentPort
|
||||
|
||||
parentPort.on('message', (data) => {
|
||||
globalThis.onmessage({ data })
|
||||
})
|
||||
|
||||
Object.assign(globalThis, {
|
||||
self: globalThis,
|
||||
require,
|
||||
Worker: nodeWorkerThreads.Worker,
|
||||
importScripts: function (f) {
|
||||
(0, eval)(require('fs').readFileSync(f, 'utf8') + '//# sourceURL=' + f)
|
||||
},
|
||||
postMessage: function (msg) {
|
||||
parentPort.postMessage(msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
main(_require, _init)
|
||||
} else {
|
||||
importScripts('./node_modules/@tybys/wasm-util/dist/wasm-util.js')
|
||||
importScripts('./node_modules/@emnapi/wasi-threads/dist/wasi-threads.js')
|
||||
|
||||
const nodeWasi = { WASI: globalThis.wasmUtil.WASI }
|
||||
const _require = function (request) {
|
||||
if (request === '@emnapi/wasi-threads') return globalThis.wasiThreads
|
||||
if (request === 'node:wasi' || request === 'wasi') return nodeWasi
|
||||
throw new Error('Can not find module: ' + request)
|
||||
}
|
||||
const _init = function () {}
|
||||
main(_require, _init)
|
||||
}
|
||||
})(function main (require, init) {
|
||||
init()
|
||||
|
||||
const { WASI } = require('wasi')
|
||||
const { ThreadMessageHandler, WASIThreads } = require('@emnapi/wasi-threads')
|
||||
|
||||
const handler = new ThreadMessageHandler({
|
||||
async onLoad ({ wasmModule, wasmMemory }) {
|
||||
const wasi = new WASI({
|
||||
version: 'preview1'
|
||||
})
|
||||
|
||||
const wasiThreads = new WASIThreads({
|
||||
wasi,
|
||||
childThread: true
|
||||
})
|
||||
|
||||
const originalInstance = await WebAssembly.instantiate(wasmModule, {
|
||||
env: {
|
||||
memory: wasmMemory,
|
||||
},
|
||||
wasi_snapshot_preview1: wasi.wasiImport,
|
||||
...wasiThreads.getImportObject()
|
||||
})
|
||||
|
||||
// must call `initialize` instead of `start` in child thread
|
||||
const instance = wasiThreads.initialize(originalInstance, wasmModule, wasmMemory)
|
||||
|
||||
return { module: wasmModule, instance }
|
||||
}
|
||||
})
|
||||
|
||||
globalThis.onmessage = function (e) {
|
||||
handler.handle(e)
|
||||
// handle other messages
|
||||
}
|
||||
})
|
||||
```
|
||||
+894
@@ -0,0 +1,894 @@
|
||||
const _WebAssembly = typeof WebAssembly !== 'undefined'
|
||||
? WebAssembly
|
||||
: typeof WXWebAssembly !== 'undefined'
|
||||
? WXWebAssembly
|
||||
: undefined;
|
||||
const ENVIRONMENT_IS_NODE = typeof process === 'object' && process !== null &&
|
||||
typeof process.versions === 'object' && process.versions !== null &&
|
||||
typeof process.versions.node === 'string';
|
||||
function getPostMessage(options) {
|
||||
return typeof (options === null || options === void 0 ? void 0 : options.postMessage) === 'function'
|
||||
? options.postMessage
|
||||
: typeof postMessage === 'function'
|
||||
? postMessage
|
||||
: undefined;
|
||||
}
|
||||
function serizeErrorToBuffer(sab, code, error) {
|
||||
const i32array = new Int32Array(sab);
|
||||
Atomics.store(i32array, 0, code);
|
||||
if (code > 1 && error) {
|
||||
const name = error.name;
|
||||
const message = error.message;
|
||||
const stack = error.stack;
|
||||
const nameBuffer = new TextEncoder().encode(name);
|
||||
const messageBuffer = new TextEncoder().encode(message);
|
||||
const stackBuffer = new TextEncoder().encode(stack);
|
||||
Atomics.store(i32array, 1, nameBuffer.length);
|
||||
Atomics.store(i32array, 2, messageBuffer.length);
|
||||
Atomics.store(i32array, 3, stackBuffer.length);
|
||||
const buffer = new Uint8Array(sab);
|
||||
buffer.set(nameBuffer, 16);
|
||||
buffer.set(messageBuffer, 16 + nameBuffer.length);
|
||||
buffer.set(stackBuffer, 16 + nameBuffer.length + messageBuffer.length);
|
||||
}
|
||||
}
|
||||
function deserizeErrorFromBuffer(sab) {
|
||||
var _a, _b;
|
||||
const i32array = new Int32Array(sab);
|
||||
const status = Atomics.load(i32array, 0);
|
||||
if (status <= 1) {
|
||||
return null;
|
||||
}
|
||||
const nameLength = Atomics.load(i32array, 1);
|
||||
const messageLength = Atomics.load(i32array, 2);
|
||||
const stackLength = Atomics.load(i32array, 3);
|
||||
const buffer = new Uint8Array(sab);
|
||||
const nameBuffer = buffer.slice(16, 16 + nameLength);
|
||||
const messageBuffer = buffer.slice(16 + nameLength, 16 + nameLength + messageLength);
|
||||
const stackBuffer = buffer.slice(16 + nameLength + messageLength, 16 + nameLength + messageLength + stackLength);
|
||||
const name = new TextDecoder().decode(nameBuffer);
|
||||
const message = new TextDecoder().decode(messageBuffer);
|
||||
const stack = new TextDecoder().decode(stackBuffer);
|
||||
const ErrorConstructor = (_a = globalThis[name]) !== null && _a !== void 0 ? _a : (name === 'RuntimeError' ? ((_b = _WebAssembly.RuntimeError) !== null && _b !== void 0 ? _b : Error) : Error);
|
||||
const error = new ErrorConstructor(message);
|
||||
Object.defineProperty(error, 'stack', {
|
||||
value: stack,
|
||||
writable: true,
|
||||
enumerable: false,
|
||||
configurable: true
|
||||
});
|
||||
return error;
|
||||
}
|
||||
function isSharedArrayBuffer(value) {
|
||||
return ((typeof SharedArrayBuffer === 'function' && value instanceof SharedArrayBuffer) ||
|
||||
(Object.prototype.toString.call(value) === '[object SharedArrayBuffer]'));
|
||||
}
|
||||
function isTrapError(e) {
|
||||
try {
|
||||
return e instanceof _WebAssembly.RuntimeError;
|
||||
}
|
||||
catch (_) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function createMessage(type, payload) {
|
||||
return {
|
||||
__emnapi__: {
|
||||
type,
|
||||
payload
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const WASI_THREADS_MAX_TID = 0x1FFFFFFF;
|
||||
function checkSharedWasmMemory(wasmMemory) {
|
||||
if (wasmMemory) {
|
||||
if (!isSharedArrayBuffer(wasmMemory.buffer)) {
|
||||
throw new Error('Multithread features require shared wasm memory. ' +
|
||||
'Try to compile with `-matomics -mbulk-memory` and use `--import-memory --shared-memory` during linking, ' +
|
||||
'then create WebAssembly.Memory with `shared: true` option');
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (typeof SharedArrayBuffer === 'undefined') {
|
||||
throw new Error('Current environment does not support SharedArrayBuffer, threads are not available!');
|
||||
}
|
||||
}
|
||||
}
|
||||
function getReuseWorker(value) {
|
||||
var _a;
|
||||
if (typeof value === 'boolean') {
|
||||
return value ? { size: 0, strict: false } : false;
|
||||
}
|
||||
if (typeof value === 'number') {
|
||||
if (!(value >= 0)) {
|
||||
throw new RangeError('reuseWorker: size must be a non-negative integer');
|
||||
}
|
||||
return { size: value, strict: false };
|
||||
}
|
||||
if (!value) {
|
||||
return false;
|
||||
}
|
||||
const size = (_a = Number(value.size)) !== null && _a !== void 0 ? _a : 0;
|
||||
const strict = Boolean(value.strict);
|
||||
if (!(size > 0) && strict) {
|
||||
throw new RangeError('reuseWorker: size must be set to positive integer if strict is set to true');
|
||||
}
|
||||
return { size, strict };
|
||||
}
|
||||
let nextWorkerID = 0;
|
||||
class ThreadManager {
|
||||
get nextWorkerID() { return nextWorkerID; }
|
||||
constructor(options) {
|
||||
var _a;
|
||||
this.unusedWorkers = [];
|
||||
this.runningWorkers = [];
|
||||
this.pthreads = Object.create(null);
|
||||
this.wasmModule = null;
|
||||
this.wasmMemory = null;
|
||||
this.messageEvents = new WeakMap();
|
||||
if (!options) {
|
||||
throw new TypeError('ThreadManager(): options is not provided');
|
||||
}
|
||||
if ('childThread' in options) {
|
||||
this._childThread = Boolean(options.childThread);
|
||||
}
|
||||
else {
|
||||
this._childThread = false;
|
||||
}
|
||||
if (this._childThread) {
|
||||
this._onCreateWorker = undefined;
|
||||
this._reuseWorker = false;
|
||||
this._beforeLoad = undefined;
|
||||
}
|
||||
else {
|
||||
this._onCreateWorker = options.onCreateWorker;
|
||||
this._reuseWorker = getReuseWorker(options.reuseWorker);
|
||||
this._beforeLoad = options.beforeLoad;
|
||||
}
|
||||
this.printErr = (_a = options.printErr) !== null && _a !== void 0 ? _a : console.error.bind(console);
|
||||
this.threadSpawn = options.threadSpawn;
|
||||
}
|
||||
init() {
|
||||
if (!this._childThread) {
|
||||
this.initMainThread();
|
||||
}
|
||||
}
|
||||
initMainThread() {
|
||||
this.preparePool();
|
||||
}
|
||||
preparePool() {
|
||||
if (this._reuseWorker) {
|
||||
if (this._reuseWorker.size) {
|
||||
let pthreadPoolSize = this._reuseWorker.size;
|
||||
while (pthreadPoolSize--) {
|
||||
const worker = this.allocateUnusedWorker();
|
||||
if (ENVIRONMENT_IS_NODE) {
|
||||
worker.once('message', () => { });
|
||||
worker.unref();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
shouldPreloadWorkers() {
|
||||
return !this._childThread && this._reuseWorker && this._reuseWorker.size > 0;
|
||||
}
|
||||
loadWasmModuleToAllWorkers() {
|
||||
const promises = Array(this.unusedWorkers.length);
|
||||
for (let i = 0; i < this.unusedWorkers.length; ++i) {
|
||||
const worker = this.unusedWorkers[i];
|
||||
if (ENVIRONMENT_IS_NODE)
|
||||
worker.ref();
|
||||
promises[i] = this.loadWasmModuleToWorker(worker).then((w) => {
|
||||
if (ENVIRONMENT_IS_NODE)
|
||||
worker.unref();
|
||||
return w;
|
||||
}, (e) => {
|
||||
if (ENVIRONMENT_IS_NODE)
|
||||
worker.unref();
|
||||
throw e;
|
||||
});
|
||||
}
|
||||
return Promise.all(promises).catch((err) => {
|
||||
this.terminateAllThreads();
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
preloadWorkers() {
|
||||
if (this.shouldPreloadWorkers()) {
|
||||
return this.loadWasmModuleToAllWorkers();
|
||||
}
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
setup(wasmModule, wasmMemory) {
|
||||
this.wasmModule = wasmModule;
|
||||
this.wasmMemory = wasmMemory;
|
||||
}
|
||||
markId(worker) {
|
||||
if (worker.__emnapi_tid)
|
||||
return worker.__emnapi_tid;
|
||||
const tid = nextWorkerID + 43;
|
||||
nextWorkerID = (nextWorkerID + 1) % (WASI_THREADS_MAX_TID - 42);
|
||||
this.pthreads[tid] = worker;
|
||||
worker.__emnapi_tid = tid;
|
||||
return tid;
|
||||
}
|
||||
returnWorkerToPool(worker) {
|
||||
var tid = worker.__emnapi_tid;
|
||||
if (tid !== undefined) {
|
||||
delete this.pthreads[tid];
|
||||
}
|
||||
this.unusedWorkers.push(worker);
|
||||
this.runningWorkers.splice(this.runningWorkers.indexOf(worker), 1);
|
||||
delete worker.__emnapi_tid;
|
||||
if (ENVIRONMENT_IS_NODE) {
|
||||
worker.unref();
|
||||
}
|
||||
}
|
||||
loadWasmModuleToWorker(worker, sab) {
|
||||
if (worker.whenLoaded)
|
||||
return worker.whenLoaded;
|
||||
const err = this.printErr;
|
||||
const beforeLoad = this._beforeLoad;
|
||||
const _this = this;
|
||||
worker.whenLoaded = new Promise((resolve, reject) => {
|
||||
const handleError = function (e) {
|
||||
let message = 'worker sent an error!';
|
||||
if (worker.__emnapi_tid !== undefined) {
|
||||
message = 'worker (tid = ' + worker.__emnapi_tid + ') sent an error!';
|
||||
}
|
||||
if ('message' in e) {
|
||||
err(message + ' ' + e.message);
|
||||
if (e.message.indexOf('RuntimeError') !== -1 || e.message.indexOf('unreachable') !== -1) {
|
||||
try {
|
||||
_this.terminateAllThreads();
|
||||
}
|
||||
catch (_) { }
|
||||
}
|
||||
}
|
||||
else {
|
||||
err(message);
|
||||
}
|
||||
reject(e);
|
||||
throw e;
|
||||
};
|
||||
const handleMessage = (data) => {
|
||||
if (data.__emnapi__) {
|
||||
const type = data.__emnapi__.type;
|
||||
const payload = data.__emnapi__.payload;
|
||||
if (type === 'loaded') {
|
||||
worker.loaded = true;
|
||||
if (ENVIRONMENT_IS_NODE && !worker.__emnapi_tid) {
|
||||
worker.unref();
|
||||
}
|
||||
resolve(worker);
|
||||
}
|
||||
else if (type === 'cleanup-thread') {
|
||||
if (payload.tid in this.pthreads) {
|
||||
this.cleanThread(worker, payload.tid);
|
||||
}
|
||||
}
|
||||
else if (type === 'spawn-thread') {
|
||||
this.threadSpawn(payload.startArg, payload.errorOrTid);
|
||||
}
|
||||
else if (type === 'terminate-all-threads') {
|
||||
this.terminateAllThreads();
|
||||
}
|
||||
}
|
||||
};
|
||||
worker.onmessage = (e) => {
|
||||
handleMessage(e.data);
|
||||
this.fireMessageEvent(worker, e);
|
||||
};
|
||||
worker.onerror = handleError;
|
||||
if (ENVIRONMENT_IS_NODE) {
|
||||
worker.on('message', function (data) {
|
||||
var _a, _b;
|
||||
(_b = (_a = worker).onmessage) === null || _b === void 0 ? void 0 : _b.call(_a, {
|
||||
data
|
||||
});
|
||||
});
|
||||
worker.on('error', function (e) {
|
||||
var _a, _b;
|
||||
(_b = (_a = worker).onerror) === null || _b === void 0 ? void 0 : _b.call(_a, e);
|
||||
});
|
||||
worker.on('detachedExit', function () { });
|
||||
}
|
||||
if (typeof beforeLoad === 'function') {
|
||||
beforeLoad(worker);
|
||||
}
|
||||
try {
|
||||
worker.postMessage(createMessage('load', {
|
||||
wasmModule: this.wasmModule,
|
||||
wasmMemory: this.wasmMemory,
|
||||
sab
|
||||
}));
|
||||
}
|
||||
catch (err) {
|
||||
checkSharedWasmMemory(this.wasmMemory);
|
||||
throw err;
|
||||
}
|
||||
});
|
||||
return worker.whenLoaded;
|
||||
}
|
||||
allocateUnusedWorker() {
|
||||
const _onCreateWorker = this._onCreateWorker;
|
||||
if (typeof _onCreateWorker !== 'function') {
|
||||
throw new TypeError('`options.onCreateWorker` is not provided');
|
||||
}
|
||||
const worker = _onCreateWorker({ type: 'thread', name: 'emnapi-pthread' });
|
||||
this.unusedWorkers.push(worker);
|
||||
return worker;
|
||||
}
|
||||
getNewWorker(sab) {
|
||||
if (this._reuseWorker) {
|
||||
if (this.unusedWorkers.length === 0) {
|
||||
if (this._reuseWorker.strict) {
|
||||
if (!ENVIRONMENT_IS_NODE) {
|
||||
const err = this.printErr;
|
||||
err('Tried to spawn a new thread, but the thread pool is exhausted.\n' +
|
||||
'This might result in a deadlock unless some threads eventually exit or the code explicitly breaks out to the event loop.');
|
||||
return;
|
||||
}
|
||||
}
|
||||
const worker = this.allocateUnusedWorker();
|
||||
this.loadWasmModuleToWorker(worker, sab);
|
||||
}
|
||||
return this.unusedWorkers.pop();
|
||||
}
|
||||
const worker = this.allocateUnusedWorker();
|
||||
this.loadWasmModuleToWorker(worker, sab);
|
||||
return this.unusedWorkers.pop();
|
||||
}
|
||||
cleanThread(worker, tid, force) {
|
||||
if (!force && this._reuseWorker) {
|
||||
this.returnWorkerToPool(worker);
|
||||
}
|
||||
else {
|
||||
delete this.pthreads[tid];
|
||||
const index = this.runningWorkers.indexOf(worker);
|
||||
if (index !== -1) {
|
||||
this.runningWorkers.splice(index, 1);
|
||||
}
|
||||
this.terminateWorker(worker);
|
||||
delete worker.__emnapi_tid;
|
||||
}
|
||||
}
|
||||
terminateWorker(worker) {
|
||||
var _a;
|
||||
const tid = worker.__emnapi_tid;
|
||||
worker.terminate();
|
||||
(_a = this.messageEvents.get(worker)) === null || _a === void 0 ? void 0 : _a.clear();
|
||||
this.messageEvents.delete(worker);
|
||||
worker.onmessage = (e) => {
|
||||
if (e.data.__emnapi__) {
|
||||
const err = this.printErr;
|
||||
err('received "' + e.data.__emnapi__.type + '" command from terminated worker: ' + tid);
|
||||
}
|
||||
};
|
||||
}
|
||||
terminateAllThreads() {
|
||||
for (let i = 0; i < this.runningWorkers.length; ++i) {
|
||||
this.terminateWorker(this.runningWorkers[i]);
|
||||
}
|
||||
for (let i = 0; i < this.unusedWorkers.length; ++i) {
|
||||
this.terminateWorker(this.unusedWorkers[i]);
|
||||
}
|
||||
this.unusedWorkers = [];
|
||||
this.runningWorkers = [];
|
||||
this.pthreads = Object.create(null);
|
||||
this.preparePool();
|
||||
}
|
||||
addMessageEventListener(worker, onMessage) {
|
||||
let listeners = this.messageEvents.get(worker);
|
||||
if (!listeners) {
|
||||
listeners = new Set();
|
||||
this.messageEvents.set(worker, listeners);
|
||||
}
|
||||
listeners.add(onMessage);
|
||||
return () => {
|
||||
listeners === null || listeners === void 0 ? void 0 : listeners.delete(onMessage);
|
||||
};
|
||||
}
|
||||
fireMessageEvent(worker, e) {
|
||||
const listeners = this.messageEvents.get(worker);
|
||||
if (!listeners)
|
||||
return;
|
||||
const err = this.printErr;
|
||||
listeners.forEach((listener) => {
|
||||
try {
|
||||
listener(e);
|
||||
}
|
||||
catch (e) {
|
||||
err(e.stack);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const kIsProxy = Symbol('kIsProxy');
|
||||
function createInstanceProxy(instance, memory) {
|
||||
if (instance[kIsProxy])
|
||||
return instance;
|
||||
const originalExports = instance.exports;
|
||||
const createHandler = function (target) {
|
||||
const handlers = [
|
||||
'apply',
|
||||
'construct',
|
||||
'defineProperty',
|
||||
'deleteProperty',
|
||||
'get',
|
||||
'getOwnPropertyDescriptor',
|
||||
'getPrototypeOf',
|
||||
'has',
|
||||
'isExtensible',
|
||||
'ownKeys',
|
||||
'preventExtensions',
|
||||
'set',
|
||||
'setPrototypeOf'
|
||||
];
|
||||
const handler = {};
|
||||
for (let i = 0; i < handlers.length; i++) {
|
||||
const name = handlers[i];
|
||||
handler[name] = function () {
|
||||
const args = Array.prototype.slice.call(arguments, 1);
|
||||
args.unshift(target);
|
||||
return Reflect[name].apply(Reflect, args);
|
||||
};
|
||||
}
|
||||
return handler;
|
||||
};
|
||||
const handler = createHandler(originalExports);
|
||||
const _initialize = () => { };
|
||||
const _start = () => 0;
|
||||
handler.get = function (_target, p, receiver) {
|
||||
var _a;
|
||||
if (p === 'memory') {
|
||||
return (_a = (typeof memory === 'function' ? memory() : memory)) !== null && _a !== void 0 ? _a : Reflect.get(originalExports, p, receiver);
|
||||
}
|
||||
if (p === '_initialize') {
|
||||
return p in originalExports ? _initialize : undefined;
|
||||
}
|
||||
if (p === '_start') {
|
||||
return p in originalExports ? _start : undefined;
|
||||
}
|
||||
return Reflect.get(originalExports, p, receiver);
|
||||
};
|
||||
handler.has = function (_target, p) {
|
||||
if (p === 'memory')
|
||||
return true;
|
||||
return Reflect.has(originalExports, p);
|
||||
};
|
||||
const exportsProxy = new Proxy(Object.create(null), handler);
|
||||
return new Proxy(instance, {
|
||||
get(target, p, receiver) {
|
||||
if (p === 'exports') {
|
||||
return exportsProxy;
|
||||
}
|
||||
if (p === kIsProxy) {
|
||||
return true;
|
||||
}
|
||||
return Reflect.get(target, p, receiver);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const patchedWasiInstances = new WeakMap();
|
||||
class WASIThreads {
|
||||
constructor(options) {
|
||||
if (!options) {
|
||||
throw new TypeError('WASIThreads(): options is not provided');
|
||||
}
|
||||
if (!options.wasi) {
|
||||
throw new TypeError('WASIThreads(): options.wasi is not provided');
|
||||
}
|
||||
patchedWasiInstances.set(this, new WeakSet());
|
||||
const wasi = options.wasi;
|
||||
patchWasiInstance(this, wasi);
|
||||
this.wasi = wasi;
|
||||
if ('childThread' in options) {
|
||||
this.childThread = Boolean(options.childThread);
|
||||
}
|
||||
else {
|
||||
this.childThread = false;
|
||||
}
|
||||
this.PThread = undefined;
|
||||
if ('threadManager' in options) {
|
||||
if (typeof options.threadManager === 'function') {
|
||||
this.PThread = options.threadManager();
|
||||
}
|
||||
else {
|
||||
this.PThread = options.threadManager;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!this.childThread) {
|
||||
this.PThread = new ThreadManager(options);
|
||||
this.PThread.init();
|
||||
}
|
||||
}
|
||||
let waitThreadStart = false;
|
||||
if ('waitThreadStart' in options) {
|
||||
waitThreadStart = typeof options.waitThreadStart === 'number' ? options.waitThreadStart : Boolean(options.waitThreadStart);
|
||||
}
|
||||
const postMessage = getPostMessage(options);
|
||||
if (this.childThread && typeof postMessage !== 'function') {
|
||||
throw new TypeError('options.postMessage is not a function');
|
||||
}
|
||||
this.postMessage = postMessage;
|
||||
const wasm64 = Boolean(options.wasm64);
|
||||
const threadSpawn = (startArg, errorOrTid) => {
|
||||
var _a;
|
||||
const EAGAIN = 6;
|
||||
const isNewABI = errorOrTid !== undefined;
|
||||
try {
|
||||
checkSharedWasmMemory(this.wasmMemory);
|
||||
}
|
||||
catch (err) {
|
||||
(_a = this.PThread) === null || _a === void 0 ? void 0 : _a.printErr(err.stack);
|
||||
if (isNewABI) {
|
||||
const struct = new Int32Array(this.wasmMemory.buffer, errorOrTid, 2);
|
||||
Atomics.store(struct, 0, 1);
|
||||
Atomics.store(struct, 1, EAGAIN);
|
||||
Atomics.notify(struct, 1);
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
return -EAGAIN;
|
||||
}
|
||||
}
|
||||
if (!isNewABI) {
|
||||
const malloc = this.wasmInstance.exports.malloc;
|
||||
errorOrTid = wasm64 ? Number(malloc(BigInt(8))) : (malloc(8) >>> 0);
|
||||
if (!errorOrTid) {
|
||||
return -48;
|
||||
}
|
||||
}
|
||||
const _free = this.wasmInstance.exports.free;
|
||||
const free = wasm64 ? (ptr) => { _free(BigInt(ptr)); } : _free;
|
||||
const struct = new Int32Array(this.wasmMemory.buffer, errorOrTid, 2);
|
||||
Atomics.store(struct, 0, 0);
|
||||
Atomics.store(struct, 1, 0);
|
||||
if (this.childThread) {
|
||||
postMessage(createMessage('spawn-thread', {
|
||||
startArg,
|
||||
errorOrTid: errorOrTid
|
||||
}));
|
||||
Atomics.wait(struct, 1, 0);
|
||||
const isError = Atomics.load(struct, 0);
|
||||
const result = Atomics.load(struct, 1);
|
||||
if (isNewABI) {
|
||||
return isError;
|
||||
}
|
||||
free(errorOrTid);
|
||||
return isError ? -result : result;
|
||||
}
|
||||
const shouldWait = waitThreadStart || (waitThreadStart === 0);
|
||||
let sab;
|
||||
if (shouldWait) {
|
||||
sab = new Int32Array(new SharedArrayBuffer(16 + 8192));
|
||||
Atomics.store(sab, 0, 0);
|
||||
}
|
||||
let worker;
|
||||
let tid;
|
||||
const PThread = this.PThread;
|
||||
try {
|
||||
worker = PThread.getNewWorker(sab);
|
||||
if (!worker) {
|
||||
throw new Error('failed to get new worker');
|
||||
}
|
||||
tid = PThread.markId(worker);
|
||||
if (ENVIRONMENT_IS_NODE) {
|
||||
worker.unref();
|
||||
}
|
||||
worker.postMessage(createMessage('start', {
|
||||
tid,
|
||||
arg: startArg,
|
||||
sab
|
||||
}));
|
||||
if (shouldWait) {
|
||||
if (typeof waitThreadStart === 'number') {
|
||||
const waitResult = Atomics.wait(sab, 0, 0, waitThreadStart);
|
||||
if (waitResult === 'timed-out') {
|
||||
try {
|
||||
PThread.cleanThread(worker, tid, true);
|
||||
}
|
||||
catch (_) { }
|
||||
throw new Error('Spawning thread timed out. Please check if the worker is created successfully and if message is handled properly in the worker.');
|
||||
}
|
||||
}
|
||||
else {
|
||||
Atomics.wait(sab, 0, 0);
|
||||
}
|
||||
const r = Atomics.load(sab, 0);
|
||||
if (r > 1) {
|
||||
try {
|
||||
PThread.cleanThread(worker, tid, true);
|
||||
}
|
||||
catch (_) { }
|
||||
throw deserizeErrorFromBuffer(sab.buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
Atomics.store(struct, 0, 1);
|
||||
Atomics.store(struct, 1, EAGAIN);
|
||||
Atomics.notify(struct, 1);
|
||||
PThread === null || PThread === void 0 ? void 0 : PThread.printErr(e.stack);
|
||||
if (isNewABI) {
|
||||
return 1;
|
||||
}
|
||||
free(errorOrTid);
|
||||
return -EAGAIN;
|
||||
}
|
||||
Atomics.store(struct, 0, 0);
|
||||
Atomics.store(struct, 1, tid);
|
||||
Atomics.notify(struct, 1);
|
||||
PThread.runningWorkers.push(worker);
|
||||
if (!shouldWait) {
|
||||
worker.whenLoaded.catch((err) => {
|
||||
delete worker.whenLoaded;
|
||||
PThread.cleanThread(worker, tid, true);
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
if (isNewABI) {
|
||||
return 0;
|
||||
}
|
||||
free(errorOrTid);
|
||||
return tid;
|
||||
};
|
||||
this.threadSpawn = threadSpawn;
|
||||
if (this.PThread) {
|
||||
this.PThread.threadSpawn = threadSpawn;
|
||||
}
|
||||
}
|
||||
getImportObject() {
|
||||
return {
|
||||
wasi: {
|
||||
'thread-spawn': this.threadSpawn
|
||||
}
|
||||
};
|
||||
}
|
||||
setup(wasmInstance, wasmModule, wasmMemory) {
|
||||
wasmMemory !== null && wasmMemory !== void 0 ? wasmMemory : (wasmMemory = wasmInstance.exports.memory);
|
||||
this.wasmInstance = wasmInstance;
|
||||
this.wasmMemory = wasmMemory;
|
||||
if (this.PThread) {
|
||||
this.PThread.setup(wasmModule, wasmMemory);
|
||||
}
|
||||
}
|
||||
preloadWorkers() {
|
||||
if (this.PThread) {
|
||||
return this.PThread.preloadWorkers();
|
||||
}
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
initialize(instance, module, memory) {
|
||||
const exports$1 = instance.exports;
|
||||
memory !== null && memory !== void 0 ? memory : (memory = exports$1.memory);
|
||||
if (this.childThread) {
|
||||
instance = createInstanceProxy(instance, memory);
|
||||
}
|
||||
this.setup(instance, module, memory);
|
||||
const wasi = this.wasi;
|
||||
if (('_start' in exports$1) && (typeof exports$1._start === 'function')) {
|
||||
if (this.childThread) {
|
||||
wasi.start(instance);
|
||||
try {
|
||||
const kStarted = getWasiSymbol(wasi, 'kStarted');
|
||||
wasi[kStarted] = false;
|
||||
}
|
||||
catch (_) { }
|
||||
}
|
||||
else {
|
||||
setupInstance(wasi, instance);
|
||||
}
|
||||
}
|
||||
else {
|
||||
wasi.initialize(instance);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
start(instance, module, memory) {
|
||||
const exports$1 = instance.exports;
|
||||
memory !== null && memory !== void 0 ? memory : (memory = exports$1.memory);
|
||||
if (this.childThread) {
|
||||
instance = createInstanceProxy(instance, memory);
|
||||
}
|
||||
this.setup(instance, module, memory);
|
||||
const exitCode = this.wasi.start(instance);
|
||||
return { exitCode, instance };
|
||||
}
|
||||
terminateAllThreads() {
|
||||
var _a;
|
||||
if (!this.childThread) {
|
||||
(_a = this.PThread) === null || _a === void 0 ? void 0 : _a.terminateAllThreads();
|
||||
}
|
||||
else {
|
||||
this.postMessage(createMessage('terminate-all-threads', {}));
|
||||
}
|
||||
}
|
||||
}
|
||||
function patchWasiInstance(wasiThreads, wasi) {
|
||||
const patched = patchedWasiInstances.get(wasiThreads);
|
||||
if (patched.has(wasi)) {
|
||||
return;
|
||||
}
|
||||
const _this = wasiThreads;
|
||||
const wasiImport = wasi.wasiImport;
|
||||
if (wasiImport) {
|
||||
const proc_exit = wasiImport.proc_exit;
|
||||
wasiImport.proc_exit = function (code) {
|
||||
_this.terminateAllThreads();
|
||||
return proc_exit.call(this, code);
|
||||
};
|
||||
}
|
||||
if (!_this.childThread) {
|
||||
const start = wasi.start;
|
||||
if (typeof start === 'function') {
|
||||
wasi.start = function (instance) {
|
||||
try {
|
||||
return start.call(this, instance);
|
||||
}
|
||||
catch (err) {
|
||||
if (isTrapError(err)) {
|
||||
_this.terminateAllThreads();
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
patched.add(wasi);
|
||||
}
|
||||
function getWasiSymbol(wasi, description) {
|
||||
const symbols = Object.getOwnPropertySymbols(wasi);
|
||||
const selectDescription = (description) => (s) => {
|
||||
if (s.description) {
|
||||
return s.description === description;
|
||||
}
|
||||
return s.toString() === `Symbol(${description})`;
|
||||
};
|
||||
if (Array.isArray(description)) {
|
||||
return description.map(d => symbols.filter(selectDescription(d))[0]);
|
||||
}
|
||||
return symbols.filter(selectDescription(description))[0];
|
||||
}
|
||||
function setupInstance(wasi, instance) {
|
||||
const [kInstance, kSetMemory] = getWasiSymbol(wasi, ['kInstance', 'kSetMemory']);
|
||||
wasi[kInstance] = instance;
|
||||
wasi[kSetMemory](instance.exports.memory);
|
||||
}
|
||||
|
||||
class ThreadMessageHandler {
|
||||
constructor(options) {
|
||||
const postMsg = getPostMessage(options);
|
||||
if (typeof postMsg !== 'function') {
|
||||
throw new TypeError('options.postMessage is not a function');
|
||||
}
|
||||
this.postMessage = postMsg;
|
||||
this.onLoad = options === null || options === void 0 ? void 0 : options.onLoad;
|
||||
this.onError = typeof (options === null || options === void 0 ? void 0 : options.onError) === 'function' ? options.onError : (_type, err) => { throw err; };
|
||||
this.instance = undefined;
|
||||
this.messagesBeforeLoad = [];
|
||||
}
|
||||
instantiate(data) {
|
||||
if (typeof this.onLoad === 'function') {
|
||||
return this.onLoad(data);
|
||||
}
|
||||
throw new Error('ThreadMessageHandler.prototype.instantiate is not implemented');
|
||||
}
|
||||
handle(e) {
|
||||
var _a;
|
||||
if ((_a = e === null || e === void 0 ? void 0 : e.data) === null || _a === void 0 ? void 0 : _a.__emnapi__) {
|
||||
const type = e.data.__emnapi__.type;
|
||||
const payload = e.data.__emnapi__.payload;
|
||||
try {
|
||||
if (type === 'load') {
|
||||
this._load(payload);
|
||||
}
|
||||
else if (type === 'start') {
|
||||
this.handleAfterLoad(e, () => {
|
||||
this._start(payload);
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
this.onError(err, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
_load(payload) {
|
||||
if (this.instance !== undefined)
|
||||
return;
|
||||
let source;
|
||||
try {
|
||||
source = this.instantiate(payload);
|
||||
}
|
||||
catch (err) {
|
||||
this._loaded(err, null, payload);
|
||||
return;
|
||||
}
|
||||
const then = source && 'then' in source ? source.then : undefined;
|
||||
if (typeof then === 'function') {
|
||||
then.call(source, (source) => { this._loaded(null, source, payload); }, (err) => { this._loaded(err, null, payload); });
|
||||
}
|
||||
else {
|
||||
this._loaded(null, source, payload);
|
||||
}
|
||||
}
|
||||
_start(payload) {
|
||||
const wasi_thread_start = this.instance.exports.wasi_thread_start;
|
||||
if (typeof wasi_thread_start !== 'function') {
|
||||
const err = new TypeError('wasi_thread_start is not exported');
|
||||
notifyPthreadCreateResult(payload.sab, 2, err);
|
||||
throw err;
|
||||
}
|
||||
const postMessage = this.postMessage;
|
||||
const tid = payload.tid;
|
||||
const startArg = payload.arg;
|
||||
notifyPthreadCreateResult(payload.sab, 1);
|
||||
try {
|
||||
wasi_thread_start(tid, startArg);
|
||||
}
|
||||
catch (err) {
|
||||
if (err !== 'unwind') {
|
||||
throw err;
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
postMessage(createMessage('cleanup-thread', { tid }));
|
||||
}
|
||||
_loaded(err, source, payload) {
|
||||
if (err) {
|
||||
notifyPthreadCreateResult(payload.sab, 2, err);
|
||||
throw err;
|
||||
}
|
||||
if (source == null) {
|
||||
const err = new TypeError('onLoad should return an object');
|
||||
notifyPthreadCreateResult(payload.sab, 2, err);
|
||||
throw err;
|
||||
}
|
||||
const instance = source.instance;
|
||||
if (!instance) {
|
||||
const err = new TypeError('onLoad should return an object which includes "instance"');
|
||||
notifyPthreadCreateResult(payload.sab, 2, err);
|
||||
throw err;
|
||||
}
|
||||
this.instance = instance;
|
||||
const postMessage = this.postMessage;
|
||||
postMessage(createMessage('loaded', {}));
|
||||
const messages = this.messagesBeforeLoad;
|
||||
this.messagesBeforeLoad = [];
|
||||
for (let i = 0; i < messages.length; i++) {
|
||||
const data = messages[i];
|
||||
this.handle({ data });
|
||||
}
|
||||
}
|
||||
handleAfterLoad(e, f) {
|
||||
if (this.instance !== undefined) {
|
||||
f.call(this, e);
|
||||
}
|
||||
else {
|
||||
this.messagesBeforeLoad.push(e.data);
|
||||
}
|
||||
}
|
||||
}
|
||||
function notifyPthreadCreateResult(sab, result, error) {
|
||||
if (sab) {
|
||||
serizeErrorToBuffer(sab.buffer, result, error);
|
||||
Atomics.notify(sab, 0);
|
||||
}
|
||||
}
|
||||
|
||||
exports.ThreadManager = ThreadManager;
|
||||
exports.ThreadMessageHandler = ThreadMessageHandler;
|
||||
exports.WASIThreads = WASIThreads;
|
||||
exports.createInstanceProxy = createInstanceProxy;
|
||||
exports.isSharedArrayBuffer = isSharedArrayBuffer;
|
||||
exports.isTrapError = isTrapError;
|
||||
+272
@@ -0,0 +1,272 @@
|
||||
/// <reference types="node" />
|
||||
|
||||
import type { Worker as Worker_2 } from 'worker_threads';
|
||||
|
||||
/** @public */
|
||||
export declare interface BaseOptions {
|
||||
wasi: WASIInstance;
|
||||
version?: 'preview1';
|
||||
wasm64?: boolean;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface ChildThreadOptions extends BaseOptions {
|
||||
childThread: true;
|
||||
postMessage?: (data: any) => void;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface CleanupThreadPayload {
|
||||
tid: number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface CommandInfo<T extends CommandType> {
|
||||
type: T;
|
||||
payload: CommandPayloadMap[T];
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface CommandPayloadMap {
|
||||
load: LoadPayload;
|
||||
loaded: LoadedPayload;
|
||||
start: StartPayload;
|
||||
'cleanup-thread': CleanupThreadPayload;
|
||||
'terminate-all-threads': TerminateAllThreadsPayload;
|
||||
'spawn-thread': SpawnThreadPayload;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare type CommandType = keyof CommandPayloadMap;
|
||||
|
||||
/** @public */
|
||||
export declare function createInstanceProxy(instance: WebAssembly.Instance, memory?: WebAssembly.Memory | (() => WebAssembly.Memory)): WebAssembly.Instance;
|
||||
|
||||
/** @public */
|
||||
export declare function isSharedArrayBuffer(value: any): value is SharedArrayBuffer;
|
||||
|
||||
/** @public */
|
||||
export declare function isTrapError(e: Error): e is WebAssembly.RuntimeError;
|
||||
|
||||
/** @public */
|
||||
export declare interface LoadedPayload {
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface LoadPayload {
|
||||
wasmModule: WebAssembly.Module;
|
||||
wasmMemory: WebAssembly.Memory;
|
||||
sab?: Int32Array;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface MainThreadBaseOptions extends BaseOptions {
|
||||
waitThreadStart?: boolean | number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare type MainThreadOptions = MainThreadOptionsWithThreadManager | MainThreadOptionsCreateThreadManager;
|
||||
|
||||
/** @public */
|
||||
export declare interface MainThreadOptionsCreateThreadManager extends MainThreadBaseOptions, ThreadManagerOptionsMain {
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface MainThreadOptionsWithThreadManager extends MainThreadBaseOptions {
|
||||
threadManager?: ThreadManager | (() => ThreadManager);
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface MessageEventData<T extends CommandType> {
|
||||
__emnapi__: CommandInfo<T>;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface ReuseWorkerOptions {
|
||||
/**
|
||||
* @see {@link https://emscripten.org/docs/tools_reference/settings_reference.html#pthread-pool-size | PTHREAD_POOL_SIZE}
|
||||
*/
|
||||
size: number;
|
||||
/**
|
||||
* @see {@link https://emscripten.org/docs/tools_reference/settings_reference.html#pthread-pool-size-strict | PTHREAD_POOL_SIZE_STRICT}
|
||||
*/
|
||||
strict?: boolean;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface SpawnThreadPayload {
|
||||
startArg: number;
|
||||
errorOrTid: number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface StartPayload {
|
||||
tid: number;
|
||||
arg: number;
|
||||
sab?: Int32Array;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface StartResult {
|
||||
exitCode: number;
|
||||
instance: WebAssembly.Instance;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface TerminateAllThreadsPayload {
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare class ThreadManager {
|
||||
unusedWorkers: WorkerLike[];
|
||||
runningWorkers: WorkerLike[];
|
||||
pthreads: Record<number, WorkerLike>;
|
||||
get nextWorkerID(): number;
|
||||
wasmModule: WebAssembly.Module | null;
|
||||
wasmMemory: WebAssembly.Memory | null;
|
||||
private readonly messageEvents;
|
||||
private readonly _childThread;
|
||||
private readonly _onCreateWorker;
|
||||
private readonly _reuseWorker;
|
||||
private readonly _beforeLoad?;
|
||||
/* Excluded from this release type: printErr */
|
||||
threadSpawn?: ((startArg: number, errorOrTid?: number) => number);
|
||||
constructor(options: ThreadManagerOptions);
|
||||
init(): void;
|
||||
initMainThread(): void;
|
||||
private preparePool;
|
||||
shouldPreloadWorkers(): boolean;
|
||||
loadWasmModuleToAllWorkers(): Promise<WorkerLike[]>;
|
||||
preloadWorkers(): Promise<WorkerLike[]>;
|
||||
setup(wasmModule: WebAssembly.Module, wasmMemory: WebAssembly.Memory): void;
|
||||
markId(worker: WorkerLike): number;
|
||||
returnWorkerToPool(worker: WorkerLike): void;
|
||||
loadWasmModuleToWorker(worker: WorkerLike, sab?: Int32Array): Promise<WorkerLike>;
|
||||
allocateUnusedWorker(): WorkerLike;
|
||||
getNewWorker(sab?: Int32Array): WorkerLike | undefined;
|
||||
cleanThread(worker: WorkerLike, tid: number, force?: boolean): void;
|
||||
terminateWorker(worker: WorkerLike): void;
|
||||
terminateAllThreads(): void;
|
||||
addMessageEventListener(worker: WorkerLike, onMessage: (e: WorkerMessageEvent) => void): () => void;
|
||||
fireMessageEvent(worker: WorkerLike, e: WorkerMessageEvent): void;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare type ThreadManagerOptions = ThreadManagerOptionsMain | ThreadManagerOptionsChild;
|
||||
|
||||
/** @public */
|
||||
export declare interface ThreadManagerOptionsBase {
|
||||
printErr?: (message: string) => void;
|
||||
threadSpawn?: (startArg: number, errorOrTid?: number) => number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface ThreadManagerOptionsChild extends ThreadManagerOptionsBase {
|
||||
childThread: true;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface ThreadManagerOptionsMain extends ThreadManagerOptionsBase {
|
||||
beforeLoad?: (worker: WorkerLike) => any;
|
||||
reuseWorker?: boolean | number | ReuseWorkerOptions;
|
||||
onCreateWorker: WorkerFactory;
|
||||
childThread?: false;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare class ThreadMessageHandler {
|
||||
protected instance: WebAssembly.Instance | undefined;
|
||||
private messagesBeforeLoad;
|
||||
protected postMessage: (message: any) => void;
|
||||
protected onLoad?: (data: LoadPayload) => WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
|
||||
protected onError: (error: Error, type: WorkerMessageType) => void;
|
||||
constructor(options?: ThreadMessageHandlerOptions);
|
||||
/** @virtual */
|
||||
instantiate(data: LoadPayload): WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
|
||||
/** @virtual */
|
||||
handle(e: WorkerMessageEvent<MessageEventData<WorkerMessageType>>): void;
|
||||
private _load;
|
||||
private _start;
|
||||
protected _loaded(err: Error | null, source: WebAssembly.WebAssemblyInstantiatedSource | null, payload: LoadPayload): void;
|
||||
protected handleAfterLoad<E extends WorkerMessageEvent>(e: E, f: (e: E) => void): void;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface ThreadMessageHandlerOptions {
|
||||
onLoad?: (data: LoadPayload) => WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
|
||||
onError?: (error: Error, type: WorkerMessageType) => void;
|
||||
postMessage?: (message: any) => void;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface WASIInstance {
|
||||
readonly wasiImport?: Record<string, any>;
|
||||
initialize(instance: object): void;
|
||||
start(instance: object): number;
|
||||
getImportObject?(): any;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare class WASIThreads {
|
||||
PThread: ThreadManager | undefined;
|
||||
private wasmMemory;
|
||||
private wasmInstance;
|
||||
private readonly threadSpawn;
|
||||
readonly childThread: boolean;
|
||||
private readonly postMessage;
|
||||
readonly wasi: WASIInstance;
|
||||
constructor(options: WASIThreadsOptions);
|
||||
getImportObject(): {
|
||||
wasi: WASIThreadsImports;
|
||||
};
|
||||
setup(wasmInstance: WebAssembly.Instance, wasmModule: WebAssembly.Module, wasmMemory?: WebAssembly.Memory): void;
|
||||
preloadWorkers(): Promise<WorkerLike[]>;
|
||||
/**
|
||||
* It's ok to call this method to a WASI command module.
|
||||
*
|
||||
* in child thread, must call this method instead of {@link WASIThreads.start} even if it's a WASI command module
|
||||
*
|
||||
* @returns A proxied WebAssembly instance if in child thread, other wise the original instance
|
||||
*/
|
||||
initialize(instance: WebAssembly.Instance, module: WebAssembly.Module, memory?: WebAssembly.Memory): WebAssembly.Instance;
|
||||
/**
|
||||
* Equivalent to calling {@link WASIThreads.initialize} and then calling {@link WASIInstance.start}
|
||||
* ```js
|
||||
* this.initialize(instance, module, memory)
|
||||
* this.wasi.start(instance)
|
||||
* ```
|
||||
*/
|
||||
start(instance: WebAssembly.Instance, module: WebAssembly.Module, memory?: WebAssembly.Memory): StartResult;
|
||||
terminateAllThreads(): void;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface WASIThreadsImports {
|
||||
'thread-spawn': (startArg: number, errorOrTid?: number) => number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare type WASIThreadsOptions = MainThreadOptions | ChildThreadOptions;
|
||||
|
||||
/** @public */
|
||||
export declare type WorkerFactory = (ctx: {
|
||||
type: string;
|
||||
name: string;
|
||||
}) => WorkerLike;
|
||||
|
||||
/** @public */
|
||||
export declare type WorkerLike = (Worker | Worker_2) & {
|
||||
whenLoaded?: Promise<WorkerLike>;
|
||||
loaded?: boolean;
|
||||
__emnapi_tid?: number;
|
||||
};
|
||||
|
||||
/** @public */
|
||||
export declare interface WorkerMessageEvent<T = any> {
|
||||
data: T;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare type WorkerMessageType = 'load' | 'start';
|
||||
|
||||
export { }
|
||||
+1
File diff suppressed because one or more lines are too long
+272
@@ -0,0 +1,272 @@
|
||||
/// <reference types="node" />
|
||||
|
||||
import type { Worker as Worker_2 } from 'worker_threads';
|
||||
|
||||
/** @public */
|
||||
export declare interface BaseOptions {
|
||||
wasi: WASIInstance;
|
||||
version?: 'preview1';
|
||||
wasm64?: boolean;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface ChildThreadOptions extends BaseOptions {
|
||||
childThread: true;
|
||||
postMessage?: (data: any) => void;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface CleanupThreadPayload {
|
||||
tid: number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface CommandInfo<T extends CommandType> {
|
||||
type: T;
|
||||
payload: CommandPayloadMap[T];
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface CommandPayloadMap {
|
||||
load: LoadPayload;
|
||||
loaded: LoadedPayload;
|
||||
start: StartPayload;
|
||||
'cleanup-thread': CleanupThreadPayload;
|
||||
'terminate-all-threads': TerminateAllThreadsPayload;
|
||||
'spawn-thread': SpawnThreadPayload;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare type CommandType = keyof CommandPayloadMap;
|
||||
|
||||
/** @public */
|
||||
export declare function createInstanceProxy(instance: WebAssembly.Instance, memory?: WebAssembly.Memory | (() => WebAssembly.Memory)): WebAssembly.Instance;
|
||||
|
||||
/** @public */
|
||||
export declare function isSharedArrayBuffer(value: any): value is SharedArrayBuffer;
|
||||
|
||||
/** @public */
|
||||
export declare function isTrapError(e: Error): e is WebAssembly.RuntimeError;
|
||||
|
||||
/** @public */
|
||||
export declare interface LoadedPayload {
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface LoadPayload {
|
||||
wasmModule: WebAssembly.Module;
|
||||
wasmMemory: WebAssembly.Memory;
|
||||
sab?: Int32Array;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface MainThreadBaseOptions extends BaseOptions {
|
||||
waitThreadStart?: boolean | number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare type MainThreadOptions = MainThreadOptionsWithThreadManager | MainThreadOptionsCreateThreadManager;
|
||||
|
||||
/** @public */
|
||||
export declare interface MainThreadOptionsCreateThreadManager extends MainThreadBaseOptions, ThreadManagerOptionsMain {
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface MainThreadOptionsWithThreadManager extends MainThreadBaseOptions {
|
||||
threadManager?: ThreadManager | (() => ThreadManager);
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface MessageEventData<T extends CommandType> {
|
||||
__emnapi__: CommandInfo<T>;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface ReuseWorkerOptions {
|
||||
/**
|
||||
* @see {@link https://emscripten.org/docs/tools_reference/settings_reference.html#pthread-pool-size | PTHREAD_POOL_SIZE}
|
||||
*/
|
||||
size: number;
|
||||
/**
|
||||
* @see {@link https://emscripten.org/docs/tools_reference/settings_reference.html#pthread-pool-size-strict | PTHREAD_POOL_SIZE_STRICT}
|
||||
*/
|
||||
strict?: boolean;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface SpawnThreadPayload {
|
||||
startArg: number;
|
||||
errorOrTid: number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface StartPayload {
|
||||
tid: number;
|
||||
arg: number;
|
||||
sab?: Int32Array;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface StartResult {
|
||||
exitCode: number;
|
||||
instance: WebAssembly.Instance;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface TerminateAllThreadsPayload {
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare class ThreadManager {
|
||||
unusedWorkers: WorkerLike[];
|
||||
runningWorkers: WorkerLike[];
|
||||
pthreads: Record<number, WorkerLike>;
|
||||
get nextWorkerID(): number;
|
||||
wasmModule: WebAssembly.Module | null;
|
||||
wasmMemory: WebAssembly.Memory | null;
|
||||
private readonly messageEvents;
|
||||
private readonly _childThread;
|
||||
private readonly _onCreateWorker;
|
||||
private readonly _reuseWorker;
|
||||
private readonly _beforeLoad?;
|
||||
/* Excluded from this release type: printErr */
|
||||
threadSpawn?: ((startArg: number, errorOrTid?: number) => number);
|
||||
constructor(options: ThreadManagerOptions);
|
||||
init(): void;
|
||||
initMainThread(): void;
|
||||
private preparePool;
|
||||
shouldPreloadWorkers(): boolean;
|
||||
loadWasmModuleToAllWorkers(): Promise<WorkerLike[]>;
|
||||
preloadWorkers(): Promise<WorkerLike[]>;
|
||||
setup(wasmModule: WebAssembly.Module, wasmMemory: WebAssembly.Memory): void;
|
||||
markId(worker: WorkerLike): number;
|
||||
returnWorkerToPool(worker: WorkerLike): void;
|
||||
loadWasmModuleToWorker(worker: WorkerLike, sab?: Int32Array): Promise<WorkerLike>;
|
||||
allocateUnusedWorker(): WorkerLike;
|
||||
getNewWorker(sab?: Int32Array): WorkerLike | undefined;
|
||||
cleanThread(worker: WorkerLike, tid: number, force?: boolean): void;
|
||||
terminateWorker(worker: WorkerLike): void;
|
||||
terminateAllThreads(): void;
|
||||
addMessageEventListener(worker: WorkerLike, onMessage: (e: WorkerMessageEvent) => void): () => void;
|
||||
fireMessageEvent(worker: WorkerLike, e: WorkerMessageEvent): void;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare type ThreadManagerOptions = ThreadManagerOptionsMain | ThreadManagerOptionsChild;
|
||||
|
||||
/** @public */
|
||||
export declare interface ThreadManagerOptionsBase {
|
||||
printErr?: (message: string) => void;
|
||||
threadSpawn?: (startArg: number, errorOrTid?: number) => number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface ThreadManagerOptionsChild extends ThreadManagerOptionsBase {
|
||||
childThread: true;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface ThreadManagerOptionsMain extends ThreadManagerOptionsBase {
|
||||
beforeLoad?: (worker: WorkerLike) => any;
|
||||
reuseWorker?: boolean | number | ReuseWorkerOptions;
|
||||
onCreateWorker: WorkerFactory;
|
||||
childThread?: false;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare class ThreadMessageHandler {
|
||||
protected instance: WebAssembly.Instance | undefined;
|
||||
private messagesBeforeLoad;
|
||||
protected postMessage: (message: any) => void;
|
||||
protected onLoad?: (data: LoadPayload) => WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
|
||||
protected onError: (error: Error, type: WorkerMessageType) => void;
|
||||
constructor(options?: ThreadMessageHandlerOptions);
|
||||
/** @virtual */
|
||||
instantiate(data: LoadPayload): WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
|
||||
/** @virtual */
|
||||
handle(e: WorkerMessageEvent<MessageEventData<WorkerMessageType>>): void;
|
||||
private _load;
|
||||
private _start;
|
||||
protected _loaded(err: Error | null, source: WebAssembly.WebAssemblyInstantiatedSource | null, payload: LoadPayload): void;
|
||||
protected handleAfterLoad<E extends WorkerMessageEvent>(e: E, f: (e: E) => void): void;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface ThreadMessageHandlerOptions {
|
||||
onLoad?: (data: LoadPayload) => WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
|
||||
onError?: (error: Error, type: WorkerMessageType) => void;
|
||||
postMessage?: (message: any) => void;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface WASIInstance {
|
||||
readonly wasiImport?: Record<string, any>;
|
||||
initialize(instance: object): void;
|
||||
start(instance: object): number;
|
||||
getImportObject?(): any;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare class WASIThreads {
|
||||
PThread: ThreadManager | undefined;
|
||||
private wasmMemory;
|
||||
private wasmInstance;
|
||||
private readonly threadSpawn;
|
||||
readonly childThread: boolean;
|
||||
private readonly postMessage;
|
||||
readonly wasi: WASIInstance;
|
||||
constructor(options: WASIThreadsOptions);
|
||||
getImportObject(): {
|
||||
wasi: WASIThreadsImports;
|
||||
};
|
||||
setup(wasmInstance: WebAssembly.Instance, wasmModule: WebAssembly.Module, wasmMemory?: WebAssembly.Memory): void;
|
||||
preloadWorkers(): Promise<WorkerLike[]>;
|
||||
/**
|
||||
* It's ok to call this method to a WASI command module.
|
||||
*
|
||||
* in child thread, must call this method instead of {@link WASIThreads.start} even if it's a WASI command module
|
||||
*
|
||||
* @returns A proxied WebAssembly instance if in child thread, other wise the original instance
|
||||
*/
|
||||
initialize(instance: WebAssembly.Instance, module: WebAssembly.Module, memory?: WebAssembly.Memory): WebAssembly.Instance;
|
||||
/**
|
||||
* Equivalent to calling {@link WASIThreads.initialize} and then calling {@link WASIInstance.start}
|
||||
* ```js
|
||||
* this.initialize(instance, module, memory)
|
||||
* this.wasi.start(instance)
|
||||
* ```
|
||||
*/
|
||||
start(instance: WebAssembly.Instance, module: WebAssembly.Module, memory?: WebAssembly.Memory): StartResult;
|
||||
terminateAllThreads(): void;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface WASIThreadsImports {
|
||||
'thread-spawn': (startArg: number, errorOrTid?: number) => number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare type WASIThreadsOptions = MainThreadOptions | ChildThreadOptions;
|
||||
|
||||
/** @public */
|
||||
export declare type WorkerFactory = (ctx: {
|
||||
type: string;
|
||||
name: string;
|
||||
}) => WorkerLike;
|
||||
|
||||
/** @public */
|
||||
export declare type WorkerLike = (Worker | Worker_2) & {
|
||||
whenLoaded?: Promise<WorkerLike>;
|
||||
loaded?: boolean;
|
||||
__emnapi_tid?: number;
|
||||
};
|
||||
|
||||
/** @public */
|
||||
export declare interface WorkerMessageEvent<T = any> {
|
||||
data: T;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare type WorkerMessageType = 'load' | 'start';
|
||||
|
||||
export { }
|
||||
+274
@@ -0,0 +1,274 @@
|
||||
/// <reference types="node" />
|
||||
|
||||
import type { Worker as Worker_2 } from 'worker_threads';
|
||||
|
||||
/** @public */
|
||||
export declare interface BaseOptions {
|
||||
wasi: WASIInstance;
|
||||
version?: 'preview1';
|
||||
wasm64?: boolean;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface ChildThreadOptions extends BaseOptions {
|
||||
childThread: true;
|
||||
postMessage?: (data: any) => void;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface CleanupThreadPayload {
|
||||
tid: number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface CommandInfo<T extends CommandType> {
|
||||
type: T;
|
||||
payload: CommandPayloadMap[T];
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface CommandPayloadMap {
|
||||
load: LoadPayload;
|
||||
loaded: LoadedPayload;
|
||||
start: StartPayload;
|
||||
'cleanup-thread': CleanupThreadPayload;
|
||||
'terminate-all-threads': TerminateAllThreadsPayload;
|
||||
'spawn-thread': SpawnThreadPayload;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare type CommandType = keyof CommandPayloadMap;
|
||||
|
||||
/** @public */
|
||||
export declare function createInstanceProxy(instance: WebAssembly.Instance, memory?: WebAssembly.Memory | (() => WebAssembly.Memory)): WebAssembly.Instance;
|
||||
|
||||
/** @public */
|
||||
export declare function isSharedArrayBuffer(value: any): value is SharedArrayBuffer;
|
||||
|
||||
/** @public */
|
||||
export declare function isTrapError(e: Error): e is WebAssembly.RuntimeError;
|
||||
|
||||
/** @public */
|
||||
export declare interface LoadedPayload {
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface LoadPayload {
|
||||
wasmModule: WebAssembly.Module;
|
||||
wasmMemory: WebAssembly.Memory;
|
||||
sab?: Int32Array;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface MainThreadBaseOptions extends BaseOptions {
|
||||
waitThreadStart?: boolean | number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare type MainThreadOptions = MainThreadOptionsWithThreadManager | MainThreadOptionsCreateThreadManager;
|
||||
|
||||
/** @public */
|
||||
export declare interface MainThreadOptionsCreateThreadManager extends MainThreadBaseOptions, ThreadManagerOptionsMain {
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface MainThreadOptionsWithThreadManager extends MainThreadBaseOptions {
|
||||
threadManager?: ThreadManager | (() => ThreadManager);
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface MessageEventData<T extends CommandType> {
|
||||
__emnapi__: CommandInfo<T>;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface ReuseWorkerOptions {
|
||||
/**
|
||||
* @see {@link https://emscripten.org/docs/tools_reference/settings_reference.html#pthread-pool-size | PTHREAD_POOL_SIZE}
|
||||
*/
|
||||
size: number;
|
||||
/**
|
||||
* @see {@link https://emscripten.org/docs/tools_reference/settings_reference.html#pthread-pool-size-strict | PTHREAD_POOL_SIZE_STRICT}
|
||||
*/
|
||||
strict?: boolean;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface SpawnThreadPayload {
|
||||
startArg: number;
|
||||
errorOrTid: number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface StartPayload {
|
||||
tid: number;
|
||||
arg: number;
|
||||
sab?: Int32Array;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface StartResult {
|
||||
exitCode: number;
|
||||
instance: WebAssembly.Instance;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface TerminateAllThreadsPayload {
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare class ThreadManager {
|
||||
unusedWorkers: WorkerLike[];
|
||||
runningWorkers: WorkerLike[];
|
||||
pthreads: Record<number, WorkerLike>;
|
||||
get nextWorkerID(): number;
|
||||
wasmModule: WebAssembly.Module | null;
|
||||
wasmMemory: WebAssembly.Memory | null;
|
||||
private readonly messageEvents;
|
||||
private readonly _childThread;
|
||||
private readonly _onCreateWorker;
|
||||
private readonly _reuseWorker;
|
||||
private readonly _beforeLoad?;
|
||||
/* Excluded from this release type: printErr */
|
||||
threadSpawn?: ((startArg: number, errorOrTid?: number) => number);
|
||||
constructor(options: ThreadManagerOptions);
|
||||
init(): void;
|
||||
initMainThread(): void;
|
||||
private preparePool;
|
||||
shouldPreloadWorkers(): boolean;
|
||||
loadWasmModuleToAllWorkers(): Promise<WorkerLike[]>;
|
||||
preloadWorkers(): Promise<WorkerLike[]>;
|
||||
setup(wasmModule: WebAssembly.Module, wasmMemory: WebAssembly.Memory): void;
|
||||
markId(worker: WorkerLike): number;
|
||||
returnWorkerToPool(worker: WorkerLike): void;
|
||||
loadWasmModuleToWorker(worker: WorkerLike, sab?: Int32Array): Promise<WorkerLike>;
|
||||
allocateUnusedWorker(): WorkerLike;
|
||||
getNewWorker(sab?: Int32Array): WorkerLike | undefined;
|
||||
cleanThread(worker: WorkerLike, tid: number, force?: boolean): void;
|
||||
terminateWorker(worker: WorkerLike): void;
|
||||
terminateAllThreads(): void;
|
||||
addMessageEventListener(worker: WorkerLike, onMessage: (e: WorkerMessageEvent) => void): () => void;
|
||||
fireMessageEvent(worker: WorkerLike, e: WorkerMessageEvent): void;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare type ThreadManagerOptions = ThreadManagerOptionsMain | ThreadManagerOptionsChild;
|
||||
|
||||
/** @public */
|
||||
export declare interface ThreadManagerOptionsBase {
|
||||
printErr?: (message: string) => void;
|
||||
threadSpawn?: (startArg: number, errorOrTid?: number) => number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface ThreadManagerOptionsChild extends ThreadManagerOptionsBase {
|
||||
childThread: true;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface ThreadManagerOptionsMain extends ThreadManagerOptionsBase {
|
||||
beforeLoad?: (worker: WorkerLike) => any;
|
||||
reuseWorker?: boolean | number | ReuseWorkerOptions;
|
||||
onCreateWorker: WorkerFactory;
|
||||
childThread?: false;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare class ThreadMessageHandler {
|
||||
protected instance: WebAssembly.Instance | undefined;
|
||||
private messagesBeforeLoad;
|
||||
protected postMessage: (message: any) => void;
|
||||
protected onLoad?: (data: LoadPayload) => WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
|
||||
protected onError: (error: Error, type: WorkerMessageType) => void;
|
||||
constructor(options?: ThreadMessageHandlerOptions);
|
||||
/** @virtual */
|
||||
instantiate(data: LoadPayload): WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
|
||||
/** @virtual */
|
||||
handle(e: WorkerMessageEvent<MessageEventData<WorkerMessageType>>): void;
|
||||
private _load;
|
||||
private _start;
|
||||
protected _loaded(err: Error | null, source: WebAssembly.WebAssemblyInstantiatedSource | null, payload: LoadPayload): void;
|
||||
protected handleAfterLoad<E extends WorkerMessageEvent>(e: E, f: (e: E) => void): void;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface ThreadMessageHandlerOptions {
|
||||
onLoad?: (data: LoadPayload) => WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
|
||||
onError?: (error: Error, type: WorkerMessageType) => void;
|
||||
postMessage?: (message: any) => void;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface WASIInstance {
|
||||
readonly wasiImport?: Record<string, any>;
|
||||
initialize(instance: object): void;
|
||||
start(instance: object): number;
|
||||
getImportObject?(): any;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare class WASIThreads {
|
||||
PThread: ThreadManager | undefined;
|
||||
private wasmMemory;
|
||||
private wasmInstance;
|
||||
private readonly threadSpawn;
|
||||
readonly childThread: boolean;
|
||||
private readonly postMessage;
|
||||
readonly wasi: WASIInstance;
|
||||
constructor(options: WASIThreadsOptions);
|
||||
getImportObject(): {
|
||||
wasi: WASIThreadsImports;
|
||||
};
|
||||
setup(wasmInstance: WebAssembly.Instance, wasmModule: WebAssembly.Module, wasmMemory?: WebAssembly.Memory): void;
|
||||
preloadWorkers(): Promise<WorkerLike[]>;
|
||||
/**
|
||||
* It's ok to call this method to a WASI command module.
|
||||
*
|
||||
* in child thread, must call this method instead of {@link WASIThreads.start} even if it's a WASI command module
|
||||
*
|
||||
* @returns A proxied WebAssembly instance if in child thread, other wise the original instance
|
||||
*/
|
||||
initialize(instance: WebAssembly.Instance, module: WebAssembly.Module, memory?: WebAssembly.Memory): WebAssembly.Instance;
|
||||
/**
|
||||
* Equivalent to calling {@link WASIThreads.initialize} and then calling {@link WASIInstance.start}
|
||||
* ```js
|
||||
* this.initialize(instance, module, memory)
|
||||
* this.wasi.start(instance)
|
||||
* ```
|
||||
*/
|
||||
start(instance: WebAssembly.Instance, module: WebAssembly.Module, memory?: WebAssembly.Memory): StartResult;
|
||||
terminateAllThreads(): void;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface WASIThreadsImports {
|
||||
'thread-spawn': (startArg: number, errorOrTid?: number) => number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare type WASIThreadsOptions = MainThreadOptions | ChildThreadOptions;
|
||||
|
||||
/** @public */
|
||||
export declare type WorkerFactory = (ctx: {
|
||||
type: string;
|
||||
name: string;
|
||||
}) => WorkerLike;
|
||||
|
||||
/** @public */
|
||||
export declare type WorkerLike = (Worker | Worker_2) & {
|
||||
whenLoaded?: Promise<WorkerLike>;
|
||||
loaded?: boolean;
|
||||
__emnapi_tid?: number;
|
||||
};
|
||||
|
||||
/** @public */
|
||||
export declare interface WorkerMessageEvent<T = any> {
|
||||
data: T;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare type WorkerMessageType = 'load' | 'start';
|
||||
|
||||
export { }
|
||||
|
||||
export as namespace wasiThreads;
|
||||
+942
@@ -0,0 +1,942 @@
|
||||
var _WebAssembly = typeof WebAssembly !== 'undefined'
|
||||
? WebAssembly
|
||||
: typeof WXWebAssembly !== 'undefined'
|
||||
? WXWebAssembly
|
||||
: undefined;
|
||||
var ENVIRONMENT_IS_NODE = typeof process === 'object' && process !== null &&
|
||||
typeof process.versions === 'object' && process.versions !== null &&
|
||||
typeof process.versions.node === 'string';
|
||||
function getPostMessage(options) {
|
||||
return typeof (options === null || options === void 0 ? void 0 : options.postMessage) === 'function'
|
||||
? options.postMessage
|
||||
: typeof postMessage === 'function'
|
||||
? postMessage
|
||||
: undefined;
|
||||
}
|
||||
function serizeErrorToBuffer(sab, code, error) {
|
||||
var i32array = new Int32Array(sab);
|
||||
Atomics.store(i32array, 0, code);
|
||||
if (code > 1 && error) {
|
||||
var name_1 = error.name;
|
||||
var message = error.message;
|
||||
var stack = error.stack;
|
||||
var nameBuffer = new TextEncoder().encode(name_1);
|
||||
var messageBuffer = new TextEncoder().encode(message);
|
||||
var stackBuffer = new TextEncoder().encode(stack);
|
||||
Atomics.store(i32array, 1, nameBuffer.length);
|
||||
Atomics.store(i32array, 2, messageBuffer.length);
|
||||
Atomics.store(i32array, 3, stackBuffer.length);
|
||||
var buffer = new Uint8Array(sab);
|
||||
buffer.set(nameBuffer, 16);
|
||||
buffer.set(messageBuffer, 16 + nameBuffer.length);
|
||||
buffer.set(stackBuffer, 16 + nameBuffer.length + messageBuffer.length);
|
||||
}
|
||||
}
|
||||
function deserizeErrorFromBuffer(sab) {
|
||||
var _a, _b;
|
||||
var i32array = new Int32Array(sab);
|
||||
var status = Atomics.load(i32array, 0);
|
||||
if (status <= 1) {
|
||||
return null;
|
||||
}
|
||||
var nameLength = Atomics.load(i32array, 1);
|
||||
var messageLength = Atomics.load(i32array, 2);
|
||||
var stackLength = Atomics.load(i32array, 3);
|
||||
var buffer = new Uint8Array(sab);
|
||||
var nameBuffer = buffer.slice(16, 16 + nameLength);
|
||||
var messageBuffer = buffer.slice(16 + nameLength, 16 + nameLength + messageLength);
|
||||
var stackBuffer = buffer.slice(16 + nameLength + messageLength, 16 + nameLength + messageLength + stackLength);
|
||||
var name = new TextDecoder().decode(nameBuffer);
|
||||
var message = new TextDecoder().decode(messageBuffer);
|
||||
var stack = new TextDecoder().decode(stackBuffer);
|
||||
var ErrorConstructor = (_a = globalThis[name]) !== null && _a !== void 0 ? _a : (name === 'RuntimeError' ? ((_b = _WebAssembly.RuntimeError) !== null && _b !== void 0 ? _b : Error) : Error);
|
||||
var error = new ErrorConstructor(message);
|
||||
Object.defineProperty(error, 'stack', {
|
||||
value: stack,
|
||||
writable: true,
|
||||
enumerable: false,
|
||||
configurable: true
|
||||
});
|
||||
return error;
|
||||
}
|
||||
/** @public */
|
||||
function isSharedArrayBuffer(value) {
|
||||
return ((typeof SharedArrayBuffer === 'function' && value instanceof SharedArrayBuffer) ||
|
||||
(Object.prototype.toString.call(value) === '[object SharedArrayBuffer]'));
|
||||
}
|
||||
/** @public */
|
||||
function isTrapError(e) {
|
||||
try {
|
||||
return e instanceof _WebAssembly.RuntimeError;
|
||||
}
|
||||
catch (_) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function createMessage(type, payload) {
|
||||
return {
|
||||
__emnapi__: {
|
||||
type: type,
|
||||
payload: payload
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
var WASI_THREADS_MAX_TID = 0x1FFFFFFF;
|
||||
function checkSharedWasmMemory(wasmMemory) {
|
||||
if (wasmMemory) {
|
||||
if (!isSharedArrayBuffer(wasmMemory.buffer)) {
|
||||
throw new Error('Multithread features require shared wasm memory. ' +
|
||||
'Try to compile with `-matomics -mbulk-memory` and use `--import-memory --shared-memory` during linking, ' +
|
||||
'then create WebAssembly.Memory with `shared: true` option');
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (typeof SharedArrayBuffer === 'undefined') {
|
||||
throw new Error('Current environment does not support SharedArrayBuffer, threads are not available!');
|
||||
}
|
||||
}
|
||||
}
|
||||
function getReuseWorker(value) {
|
||||
var _a;
|
||||
if (typeof value === 'boolean') {
|
||||
return value ? { size: 0, strict: false } : false;
|
||||
}
|
||||
if (typeof value === 'number') {
|
||||
if (!(value >= 0)) {
|
||||
throw new RangeError('reuseWorker: size must be a non-negative integer');
|
||||
}
|
||||
return { size: value, strict: false };
|
||||
}
|
||||
if (!value) {
|
||||
return false;
|
||||
}
|
||||
var size = (_a = Number(value.size)) !== null && _a !== void 0 ? _a : 0;
|
||||
var strict = Boolean(value.strict);
|
||||
if (!(size > 0) && strict) {
|
||||
throw new RangeError('reuseWorker: size must be set to positive integer if strict is set to true');
|
||||
}
|
||||
return { size: size, strict: strict };
|
||||
}
|
||||
var nextWorkerID = 0;
|
||||
/** @public */
|
||||
var ThreadManager = /*#__PURE__*/ (function () {
|
||||
function ThreadManager(options) {
|
||||
var _a;
|
||||
this.unusedWorkers = [];
|
||||
this.runningWorkers = [];
|
||||
this.pthreads = Object.create(null);
|
||||
this.wasmModule = null;
|
||||
this.wasmMemory = null;
|
||||
this.messageEvents = new WeakMap();
|
||||
if (!options) {
|
||||
throw new TypeError('ThreadManager(): options is not provided');
|
||||
}
|
||||
if ('childThread' in options) {
|
||||
this._childThread = Boolean(options.childThread);
|
||||
}
|
||||
else {
|
||||
this._childThread = false;
|
||||
}
|
||||
if (this._childThread) {
|
||||
this._onCreateWorker = undefined;
|
||||
this._reuseWorker = false;
|
||||
this._beforeLoad = undefined;
|
||||
}
|
||||
else {
|
||||
this._onCreateWorker = options.onCreateWorker;
|
||||
this._reuseWorker = getReuseWorker(options.reuseWorker);
|
||||
this._beforeLoad = options.beforeLoad;
|
||||
}
|
||||
this.printErr = (_a = options.printErr) !== null && _a !== void 0 ? _a : console.error.bind(console);
|
||||
this.threadSpawn = options.threadSpawn;
|
||||
}
|
||||
Object.defineProperty(ThreadManager.prototype, "nextWorkerID", {
|
||||
get: function () { return nextWorkerID; },
|
||||
enumerable: false,
|
||||
configurable: true
|
||||
});
|
||||
ThreadManager.prototype.init = function () {
|
||||
if (!this._childThread) {
|
||||
this.initMainThread();
|
||||
}
|
||||
};
|
||||
ThreadManager.prototype.initMainThread = function () {
|
||||
this.preparePool();
|
||||
};
|
||||
ThreadManager.prototype.preparePool = function () {
|
||||
if (this._reuseWorker) {
|
||||
if (this._reuseWorker.size) {
|
||||
var pthreadPoolSize = this._reuseWorker.size;
|
||||
while (pthreadPoolSize--) {
|
||||
var worker = this.allocateUnusedWorker();
|
||||
if (ENVIRONMENT_IS_NODE) {
|
||||
// https://github.com/nodejs/node/issues/53036
|
||||
worker.once('message', function () { });
|
||||
worker.unref();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
ThreadManager.prototype.shouldPreloadWorkers = function () {
|
||||
return !this._childThread && this._reuseWorker && this._reuseWorker.size > 0;
|
||||
};
|
||||
ThreadManager.prototype.loadWasmModuleToAllWorkers = function () {
|
||||
var _this_1 = this;
|
||||
var promises = Array(this.unusedWorkers.length);
|
||||
var _loop_1 = function (i) {
|
||||
var worker = this_1.unusedWorkers[i];
|
||||
if (ENVIRONMENT_IS_NODE)
|
||||
worker.ref();
|
||||
promises[i] = this_1.loadWasmModuleToWorker(worker).then(function (w) {
|
||||
if (ENVIRONMENT_IS_NODE)
|
||||
worker.unref();
|
||||
return w;
|
||||
}, function (e) {
|
||||
if (ENVIRONMENT_IS_NODE)
|
||||
worker.unref();
|
||||
throw e;
|
||||
});
|
||||
};
|
||||
var this_1 = this;
|
||||
for (var i = 0; i < this.unusedWorkers.length; ++i) {
|
||||
_loop_1(i);
|
||||
}
|
||||
return Promise.all(promises).catch(function (err) {
|
||||
_this_1.terminateAllThreads();
|
||||
throw err;
|
||||
});
|
||||
};
|
||||
ThreadManager.prototype.preloadWorkers = function () {
|
||||
if (this.shouldPreloadWorkers()) {
|
||||
return this.loadWasmModuleToAllWorkers();
|
||||
}
|
||||
return Promise.resolve([]);
|
||||
};
|
||||
ThreadManager.prototype.setup = function (wasmModule, wasmMemory) {
|
||||
this.wasmModule = wasmModule;
|
||||
this.wasmMemory = wasmMemory;
|
||||
};
|
||||
ThreadManager.prototype.markId = function (worker) {
|
||||
if (worker.__emnapi_tid)
|
||||
return worker.__emnapi_tid;
|
||||
var tid = nextWorkerID + 43;
|
||||
nextWorkerID = (nextWorkerID + 1) % (WASI_THREADS_MAX_TID - 42);
|
||||
this.pthreads[tid] = worker;
|
||||
worker.__emnapi_tid = tid;
|
||||
return tid;
|
||||
};
|
||||
ThreadManager.prototype.returnWorkerToPool = function (worker) {
|
||||
var tid = worker.__emnapi_tid;
|
||||
if (tid !== undefined) {
|
||||
delete this.pthreads[tid];
|
||||
}
|
||||
this.unusedWorkers.push(worker);
|
||||
this.runningWorkers.splice(this.runningWorkers.indexOf(worker), 1);
|
||||
delete worker.__emnapi_tid;
|
||||
if (ENVIRONMENT_IS_NODE) {
|
||||
worker.unref();
|
||||
}
|
||||
};
|
||||
ThreadManager.prototype.loadWasmModuleToWorker = function (worker, sab) {
|
||||
var _this_1 = this;
|
||||
if (worker.whenLoaded)
|
||||
return worker.whenLoaded;
|
||||
var err = this.printErr;
|
||||
var beforeLoad = this._beforeLoad;
|
||||
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
||||
var _this = this;
|
||||
worker.whenLoaded = new Promise(function (resolve, reject) {
|
||||
var handleError = function (e) {
|
||||
var message = 'worker sent an error!';
|
||||
if (worker.__emnapi_tid !== undefined) {
|
||||
message = 'worker (tid = ' + worker.__emnapi_tid + ') sent an error!';
|
||||
}
|
||||
if ('message' in e) {
|
||||
err(message + ' ' + e.message);
|
||||
if (e.message.indexOf('RuntimeError') !== -1 || e.message.indexOf('unreachable') !== -1) {
|
||||
try {
|
||||
_this.terminateAllThreads();
|
||||
}
|
||||
catch (_) { }
|
||||
}
|
||||
}
|
||||
else {
|
||||
err(message);
|
||||
}
|
||||
reject(e);
|
||||
throw e;
|
||||
};
|
||||
var handleMessage = function (data) {
|
||||
if (data.__emnapi__) {
|
||||
var type = data.__emnapi__.type;
|
||||
var payload = data.__emnapi__.payload;
|
||||
if (type === 'loaded') {
|
||||
worker.loaded = true;
|
||||
if (ENVIRONMENT_IS_NODE && !worker.__emnapi_tid) {
|
||||
worker.unref();
|
||||
}
|
||||
resolve(worker);
|
||||
// if (payload.err) {
|
||||
// err('failed to load in child thread: ' + (payload.err.message || payload.err))
|
||||
// }
|
||||
}
|
||||
else if (type === 'cleanup-thread') {
|
||||
if (payload.tid in _this_1.pthreads) {
|
||||
_this_1.cleanThread(worker, payload.tid);
|
||||
}
|
||||
}
|
||||
else if (type === 'spawn-thread') {
|
||||
_this_1.threadSpawn(payload.startArg, payload.errorOrTid);
|
||||
}
|
||||
else if (type === 'terminate-all-threads') {
|
||||
_this_1.terminateAllThreads();
|
||||
}
|
||||
}
|
||||
};
|
||||
worker.onmessage = function (e) {
|
||||
handleMessage(e.data);
|
||||
_this_1.fireMessageEvent(worker, e);
|
||||
};
|
||||
worker.onerror = handleError;
|
||||
if (ENVIRONMENT_IS_NODE) {
|
||||
worker.on('message', function (data) {
|
||||
var _a, _b;
|
||||
(_b = (_a = worker).onmessage) === null || _b === void 0 ? void 0 : _b.call(_a, {
|
||||
data: data
|
||||
});
|
||||
});
|
||||
worker.on('error', function (e) {
|
||||
var _a, _b;
|
||||
(_b = (_a = worker).onerror) === null || _b === void 0 ? void 0 : _b.call(_a, e);
|
||||
});
|
||||
worker.on('detachedExit', function () { });
|
||||
}
|
||||
if (typeof beforeLoad === 'function') {
|
||||
beforeLoad(worker);
|
||||
}
|
||||
try {
|
||||
worker.postMessage(createMessage('load', {
|
||||
wasmModule: _this_1.wasmModule,
|
||||
wasmMemory: _this_1.wasmMemory,
|
||||
sab: sab
|
||||
}));
|
||||
}
|
||||
catch (err) {
|
||||
checkSharedWasmMemory(_this_1.wasmMemory);
|
||||
throw err;
|
||||
}
|
||||
});
|
||||
return worker.whenLoaded;
|
||||
};
|
||||
ThreadManager.prototype.allocateUnusedWorker = function () {
|
||||
var _onCreateWorker = this._onCreateWorker;
|
||||
if (typeof _onCreateWorker !== 'function') {
|
||||
throw new TypeError('`options.onCreateWorker` is not provided');
|
||||
}
|
||||
var worker = _onCreateWorker({ type: 'thread', name: 'emnapi-pthread' });
|
||||
this.unusedWorkers.push(worker);
|
||||
return worker;
|
||||
};
|
||||
ThreadManager.prototype.getNewWorker = function (sab) {
|
||||
if (this._reuseWorker) {
|
||||
if (this.unusedWorkers.length === 0) {
|
||||
if (this._reuseWorker.strict) {
|
||||
if (!ENVIRONMENT_IS_NODE) {
|
||||
var err = this.printErr;
|
||||
err('Tried to spawn a new thread, but the thread pool is exhausted.\n' +
|
||||
'This might result in a deadlock unless some threads eventually exit or the code explicitly breaks out to the event loop.');
|
||||
return;
|
||||
}
|
||||
}
|
||||
var worker_1 = this.allocateUnusedWorker();
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
this.loadWasmModuleToWorker(worker_1, sab);
|
||||
}
|
||||
return this.unusedWorkers.pop();
|
||||
}
|
||||
var worker = this.allocateUnusedWorker();
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
this.loadWasmModuleToWorker(worker, sab);
|
||||
return this.unusedWorkers.pop();
|
||||
};
|
||||
ThreadManager.prototype.cleanThread = function (worker, tid, force) {
|
||||
if (!force && this._reuseWorker) {
|
||||
this.returnWorkerToPool(worker);
|
||||
}
|
||||
else {
|
||||
delete this.pthreads[tid];
|
||||
var index = this.runningWorkers.indexOf(worker);
|
||||
if (index !== -1) {
|
||||
this.runningWorkers.splice(index, 1);
|
||||
}
|
||||
this.terminateWorker(worker);
|
||||
delete worker.__emnapi_tid;
|
||||
}
|
||||
};
|
||||
ThreadManager.prototype.terminateWorker = function (worker) {
|
||||
var _this_1 = this;
|
||||
var _a;
|
||||
var tid = worker.__emnapi_tid;
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
worker.terminate();
|
||||
(_a = this.messageEvents.get(worker)) === null || _a === void 0 ? void 0 : _a.clear();
|
||||
this.messageEvents.delete(worker);
|
||||
worker.onmessage = function (e) {
|
||||
if (e.data.__emnapi__) {
|
||||
var err = _this_1.printErr;
|
||||
err('received "' + e.data.__emnapi__.type + '" command from terminated worker: ' + tid);
|
||||
}
|
||||
};
|
||||
};
|
||||
ThreadManager.prototype.terminateAllThreads = function () {
|
||||
for (var i = 0; i < this.runningWorkers.length; ++i) {
|
||||
this.terminateWorker(this.runningWorkers[i]);
|
||||
}
|
||||
for (var i = 0; i < this.unusedWorkers.length; ++i) {
|
||||
this.terminateWorker(this.unusedWorkers[i]);
|
||||
}
|
||||
this.unusedWorkers = [];
|
||||
this.runningWorkers = [];
|
||||
this.pthreads = Object.create(null);
|
||||
this.preparePool();
|
||||
};
|
||||
ThreadManager.prototype.addMessageEventListener = function (worker, onMessage) {
|
||||
var listeners = this.messageEvents.get(worker);
|
||||
if (!listeners) {
|
||||
listeners = new Set();
|
||||
this.messageEvents.set(worker, listeners);
|
||||
}
|
||||
listeners.add(onMessage);
|
||||
return function () {
|
||||
listeners === null || listeners === void 0 ? void 0 : listeners.delete(onMessage);
|
||||
};
|
||||
};
|
||||
ThreadManager.prototype.fireMessageEvent = function (worker, e) {
|
||||
var listeners = this.messageEvents.get(worker);
|
||||
if (!listeners)
|
||||
return;
|
||||
var err = this.printErr;
|
||||
listeners.forEach(function (listener) {
|
||||
try {
|
||||
listener(e);
|
||||
}
|
||||
catch (e) {
|
||||
err(e.stack);
|
||||
}
|
||||
});
|
||||
};
|
||||
return ThreadManager;
|
||||
}());
|
||||
|
||||
var kIsProxy = Symbol('kIsProxy');
|
||||
/** @public */
|
||||
function createInstanceProxy(instance, memory) {
|
||||
if (instance[kIsProxy])
|
||||
return instance;
|
||||
// https://github.com/nodejs/help/issues/4102
|
||||
var originalExports = instance.exports;
|
||||
var createHandler = function (target) {
|
||||
var handlers = [
|
||||
'apply',
|
||||
'construct',
|
||||
'defineProperty',
|
||||
'deleteProperty',
|
||||
'get',
|
||||
'getOwnPropertyDescriptor',
|
||||
'getPrototypeOf',
|
||||
'has',
|
||||
'isExtensible',
|
||||
'ownKeys',
|
||||
'preventExtensions',
|
||||
'set',
|
||||
'setPrototypeOf'
|
||||
];
|
||||
var handler = {};
|
||||
var _loop_1 = function (i) {
|
||||
var name_1 = handlers[i];
|
||||
handler[name_1] = function () {
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
args.unshift(target);
|
||||
return Reflect[name_1].apply(Reflect, args);
|
||||
};
|
||||
};
|
||||
for (var i = 0; i < handlers.length; i++) {
|
||||
_loop_1(i);
|
||||
}
|
||||
return handler;
|
||||
};
|
||||
var handler = createHandler(originalExports);
|
||||
var _initialize = function () { };
|
||||
var _start = function () { return 0; };
|
||||
handler.get = function (_target, p, receiver) {
|
||||
var _a;
|
||||
if (p === 'memory') {
|
||||
return (_a = (typeof memory === 'function' ? memory() : memory)) !== null && _a !== void 0 ? _a : Reflect.get(originalExports, p, receiver);
|
||||
}
|
||||
if (p === '_initialize') {
|
||||
return p in originalExports ? _initialize : undefined;
|
||||
}
|
||||
if (p === '_start') {
|
||||
return p in originalExports ? _start : undefined;
|
||||
}
|
||||
return Reflect.get(originalExports, p, receiver);
|
||||
};
|
||||
handler.has = function (_target, p) {
|
||||
if (p === 'memory')
|
||||
return true;
|
||||
return Reflect.has(originalExports, p);
|
||||
};
|
||||
var exportsProxy = new Proxy(Object.create(null), handler);
|
||||
return new Proxy(instance, {
|
||||
get: function (target, p, receiver) {
|
||||
if (p === 'exports') {
|
||||
return exportsProxy;
|
||||
}
|
||||
if (p === kIsProxy) {
|
||||
return true;
|
||||
}
|
||||
return Reflect.get(target, p, receiver);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var patchedWasiInstances = new WeakMap();
|
||||
/** @public */
|
||||
var WASIThreads = /*#__PURE__*/ (function () {
|
||||
function WASIThreads(options) {
|
||||
var _this_1 = this;
|
||||
if (!options) {
|
||||
throw new TypeError('WASIThreads(): options is not provided');
|
||||
}
|
||||
if (!options.wasi) {
|
||||
throw new TypeError('WASIThreads(): options.wasi is not provided');
|
||||
}
|
||||
patchedWasiInstances.set(this, new WeakSet());
|
||||
var wasi = options.wasi;
|
||||
patchWasiInstance(this, wasi);
|
||||
this.wasi = wasi;
|
||||
if ('childThread' in options) {
|
||||
this.childThread = Boolean(options.childThread);
|
||||
}
|
||||
else {
|
||||
this.childThread = false;
|
||||
}
|
||||
this.PThread = undefined;
|
||||
if ('threadManager' in options) {
|
||||
if (typeof options.threadManager === 'function') {
|
||||
this.PThread = options.threadManager();
|
||||
}
|
||||
else {
|
||||
this.PThread = options.threadManager;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!this.childThread) {
|
||||
this.PThread = new ThreadManager(options);
|
||||
this.PThread.init();
|
||||
}
|
||||
}
|
||||
var waitThreadStart = false;
|
||||
if ('waitThreadStart' in options) {
|
||||
waitThreadStart = typeof options.waitThreadStart === 'number' ? options.waitThreadStart : Boolean(options.waitThreadStart);
|
||||
}
|
||||
var postMessage = getPostMessage(options);
|
||||
if (this.childThread && typeof postMessage !== 'function') {
|
||||
throw new TypeError('options.postMessage is not a function');
|
||||
}
|
||||
this.postMessage = postMessage;
|
||||
var wasm64 = Boolean(options.wasm64);
|
||||
var threadSpawn = function (startArg, errorOrTid) {
|
||||
var _a;
|
||||
var EAGAIN = 6;
|
||||
var isNewABI = errorOrTid !== undefined;
|
||||
try {
|
||||
checkSharedWasmMemory(_this_1.wasmMemory);
|
||||
}
|
||||
catch (err) {
|
||||
(_a = _this_1.PThread) === null || _a === void 0 ? void 0 : _a.printErr(err.stack);
|
||||
if (isNewABI) {
|
||||
var struct_1 = new Int32Array(_this_1.wasmMemory.buffer, errorOrTid, 2);
|
||||
Atomics.store(struct_1, 0, 1);
|
||||
Atomics.store(struct_1, 1, EAGAIN);
|
||||
Atomics.notify(struct_1, 1);
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
return -EAGAIN;
|
||||
}
|
||||
}
|
||||
if (!isNewABI) {
|
||||
var malloc = _this_1.wasmInstance.exports.malloc;
|
||||
errorOrTid = wasm64 ? Number(malloc(BigInt(8))) : (malloc(8) >>> 0);
|
||||
if (!errorOrTid) {
|
||||
return -48; /* ENOMEM */
|
||||
}
|
||||
}
|
||||
var _free = _this_1.wasmInstance.exports.free;
|
||||
var free = wasm64 ? function (ptr) { _free(BigInt(ptr)); } : _free;
|
||||
var struct = new Int32Array(_this_1.wasmMemory.buffer, errorOrTid, 2);
|
||||
Atomics.store(struct, 0, 0);
|
||||
Atomics.store(struct, 1, 0);
|
||||
if (_this_1.childThread) {
|
||||
postMessage(createMessage('spawn-thread', {
|
||||
startArg: startArg,
|
||||
errorOrTid: errorOrTid
|
||||
}));
|
||||
Atomics.wait(struct, 1, 0);
|
||||
var isError = Atomics.load(struct, 0);
|
||||
var result = Atomics.load(struct, 1);
|
||||
if (isNewABI) {
|
||||
return isError;
|
||||
}
|
||||
free(errorOrTid);
|
||||
return isError ? -result : result;
|
||||
}
|
||||
var shouldWait = waitThreadStart || (waitThreadStart === 0);
|
||||
var sab;
|
||||
if (shouldWait) {
|
||||
sab = new Int32Array(new SharedArrayBuffer(16 + 8192));
|
||||
Atomics.store(sab, 0, 0);
|
||||
}
|
||||
var worker;
|
||||
var tid;
|
||||
var PThread = _this_1.PThread;
|
||||
try {
|
||||
worker = PThread.getNewWorker(sab);
|
||||
if (!worker) {
|
||||
throw new Error('failed to get new worker');
|
||||
}
|
||||
tid = PThread.markId(worker);
|
||||
if (ENVIRONMENT_IS_NODE) {
|
||||
worker.unref();
|
||||
}
|
||||
worker.postMessage(createMessage('start', {
|
||||
tid: tid,
|
||||
arg: startArg,
|
||||
sab: sab
|
||||
}));
|
||||
if (shouldWait) {
|
||||
if (typeof waitThreadStart === 'number') {
|
||||
var waitResult = Atomics.wait(sab, 0, 0, waitThreadStart);
|
||||
if (waitResult === 'timed-out') {
|
||||
try {
|
||||
PThread.cleanThread(worker, tid, true);
|
||||
}
|
||||
catch (_) { }
|
||||
throw new Error('Spawning thread timed out. Please check if the worker is created successfully and if message is handled properly in the worker.');
|
||||
}
|
||||
}
|
||||
else {
|
||||
Atomics.wait(sab, 0, 0);
|
||||
}
|
||||
var r = Atomics.load(sab, 0);
|
||||
if (r > 1) {
|
||||
try {
|
||||
PThread.cleanThread(worker, tid, true);
|
||||
}
|
||||
catch (_) { }
|
||||
throw deserizeErrorFromBuffer(sab.buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
Atomics.store(struct, 0, 1);
|
||||
Atomics.store(struct, 1, EAGAIN);
|
||||
Atomics.notify(struct, 1);
|
||||
PThread === null || PThread === void 0 ? void 0 : PThread.printErr(e.stack);
|
||||
if (isNewABI) {
|
||||
return 1;
|
||||
}
|
||||
free(errorOrTid);
|
||||
return -EAGAIN;
|
||||
}
|
||||
Atomics.store(struct, 0, 0);
|
||||
Atomics.store(struct, 1, tid);
|
||||
Atomics.notify(struct, 1);
|
||||
PThread.runningWorkers.push(worker);
|
||||
if (!shouldWait) {
|
||||
worker.whenLoaded.catch(function (err) {
|
||||
delete worker.whenLoaded;
|
||||
PThread.cleanThread(worker, tid, true);
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
if (isNewABI) {
|
||||
return 0;
|
||||
}
|
||||
free(errorOrTid);
|
||||
return tid;
|
||||
};
|
||||
this.threadSpawn = threadSpawn;
|
||||
if (this.PThread) {
|
||||
this.PThread.threadSpawn = threadSpawn;
|
||||
}
|
||||
}
|
||||
WASIThreads.prototype.getImportObject = function () {
|
||||
return {
|
||||
wasi: {
|
||||
'thread-spawn': this.threadSpawn
|
||||
}
|
||||
};
|
||||
};
|
||||
WASIThreads.prototype.setup = function (wasmInstance, wasmModule, wasmMemory) {
|
||||
wasmMemory !== null && wasmMemory !== void 0 ? wasmMemory : (wasmMemory = wasmInstance.exports.memory);
|
||||
this.wasmInstance = wasmInstance;
|
||||
this.wasmMemory = wasmMemory;
|
||||
if (this.PThread) {
|
||||
this.PThread.setup(wasmModule, wasmMemory);
|
||||
}
|
||||
};
|
||||
WASIThreads.prototype.preloadWorkers = function () {
|
||||
if (this.PThread) {
|
||||
return this.PThread.preloadWorkers();
|
||||
}
|
||||
return Promise.resolve([]);
|
||||
};
|
||||
/**
|
||||
* It's ok to call this method to a WASI command module.
|
||||
*
|
||||
* in child thread, must call this method instead of {@link WASIThreads.start} even if it's a WASI command module
|
||||
*
|
||||
* @returns A proxied WebAssembly instance if in child thread, other wise the original instance
|
||||
*/
|
||||
WASIThreads.prototype.initialize = function (instance, module, memory) {
|
||||
var exports$1 = instance.exports;
|
||||
memory !== null && memory !== void 0 ? memory : (memory = exports$1.memory);
|
||||
if (this.childThread) {
|
||||
instance = createInstanceProxy(instance, memory);
|
||||
}
|
||||
this.setup(instance, module, memory);
|
||||
var wasi = this.wasi;
|
||||
if (('_start' in exports$1) && (typeof exports$1._start === 'function')) {
|
||||
if (this.childThread) {
|
||||
wasi.start(instance);
|
||||
try {
|
||||
var kStarted = getWasiSymbol(wasi, 'kStarted');
|
||||
wasi[kStarted] = false;
|
||||
}
|
||||
catch (_) { }
|
||||
}
|
||||
else {
|
||||
setupInstance(wasi, instance);
|
||||
}
|
||||
}
|
||||
else {
|
||||
wasi.initialize(instance);
|
||||
}
|
||||
return instance;
|
||||
};
|
||||
/**
|
||||
* Equivalent to calling {@link WASIThreads.initialize} and then calling {@link WASIInstance.start}
|
||||
* ```js
|
||||
* this.initialize(instance, module, memory)
|
||||
* this.wasi.start(instance)
|
||||
* ```
|
||||
*/
|
||||
WASIThreads.prototype.start = function (instance, module, memory) {
|
||||
var exports$1 = instance.exports;
|
||||
memory !== null && memory !== void 0 ? memory : (memory = exports$1.memory);
|
||||
if (this.childThread) {
|
||||
instance = createInstanceProxy(instance, memory);
|
||||
}
|
||||
this.setup(instance, module, memory);
|
||||
var exitCode = this.wasi.start(instance);
|
||||
return { exitCode: exitCode, instance: instance };
|
||||
};
|
||||
WASIThreads.prototype.terminateAllThreads = function () {
|
||||
var _a;
|
||||
if (!this.childThread) {
|
||||
(_a = this.PThread) === null || _a === void 0 ? void 0 : _a.terminateAllThreads();
|
||||
}
|
||||
else {
|
||||
this.postMessage(createMessage('terminate-all-threads', {}));
|
||||
}
|
||||
};
|
||||
return WASIThreads;
|
||||
}());
|
||||
function patchWasiInstance(wasiThreads, wasi) {
|
||||
var patched = patchedWasiInstances.get(wasiThreads);
|
||||
if (patched.has(wasi)) {
|
||||
return;
|
||||
}
|
||||
var _this = wasiThreads;
|
||||
var wasiImport = wasi.wasiImport;
|
||||
if (wasiImport) {
|
||||
var proc_exit_1 = wasiImport.proc_exit;
|
||||
wasiImport.proc_exit = function (code) {
|
||||
_this.terminateAllThreads();
|
||||
return proc_exit_1.call(this, code);
|
||||
};
|
||||
}
|
||||
if (!_this.childThread) {
|
||||
var start_1 = wasi.start;
|
||||
if (typeof start_1 === 'function') {
|
||||
wasi.start = function (instance) {
|
||||
try {
|
||||
return start_1.call(this, instance);
|
||||
}
|
||||
catch (err) {
|
||||
if (isTrapError(err)) {
|
||||
_this.terminateAllThreads();
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
patched.add(wasi);
|
||||
}
|
||||
function getWasiSymbol(wasi, description) {
|
||||
var symbols = Object.getOwnPropertySymbols(wasi);
|
||||
var selectDescription = function (description) { return function (s) {
|
||||
if (s.description) {
|
||||
return s.description === description;
|
||||
}
|
||||
return s.toString() === "Symbol(".concat(description, ")");
|
||||
}; };
|
||||
if (Array.isArray(description)) {
|
||||
return description.map(function (d) { return symbols.filter(selectDescription(d))[0]; });
|
||||
}
|
||||
return symbols.filter(selectDescription(description))[0];
|
||||
}
|
||||
function setupInstance(wasi, instance) {
|
||||
var _a = getWasiSymbol(wasi, ['kInstance', 'kSetMemory']), kInstance = _a[0], kSetMemory = _a[1];
|
||||
wasi[kInstance] = instance;
|
||||
wasi[kSetMemory](instance.exports.memory);
|
||||
}
|
||||
|
||||
/** @public */
|
||||
var ThreadMessageHandler = /*#__PURE__*/ (function () {
|
||||
function ThreadMessageHandler(options) {
|
||||
var postMsg = getPostMessage(options);
|
||||
if (typeof postMsg !== 'function') {
|
||||
throw new TypeError('options.postMessage is not a function');
|
||||
}
|
||||
this.postMessage = postMsg;
|
||||
this.onLoad = options === null || options === void 0 ? void 0 : options.onLoad;
|
||||
this.onError = typeof (options === null || options === void 0 ? void 0 : options.onError) === 'function' ? options.onError : function (_type, err) { throw err; };
|
||||
this.instance = undefined;
|
||||
// this.module = undefined
|
||||
this.messagesBeforeLoad = [];
|
||||
}
|
||||
/** @virtual */
|
||||
ThreadMessageHandler.prototype.instantiate = function (data) {
|
||||
if (typeof this.onLoad === 'function') {
|
||||
return this.onLoad(data);
|
||||
}
|
||||
throw new Error('ThreadMessageHandler.prototype.instantiate is not implemented');
|
||||
};
|
||||
/** @virtual */
|
||||
ThreadMessageHandler.prototype.handle = function (e) {
|
||||
var _this = this;
|
||||
var _a;
|
||||
if ((_a = e === null || e === void 0 ? void 0 : e.data) === null || _a === void 0 ? void 0 : _a.__emnapi__) {
|
||||
var type = e.data.__emnapi__.type;
|
||||
var payload_1 = e.data.__emnapi__.payload;
|
||||
try {
|
||||
if (type === 'load') {
|
||||
this._load(payload_1);
|
||||
}
|
||||
else if (type === 'start') {
|
||||
this.handleAfterLoad(e, function () {
|
||||
_this._start(payload_1);
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
this.onError(err, type);
|
||||
}
|
||||
}
|
||||
};
|
||||
ThreadMessageHandler.prototype._load = function (payload) {
|
||||
var _this = this;
|
||||
if (this.instance !== undefined)
|
||||
return;
|
||||
var source;
|
||||
try {
|
||||
source = this.instantiate(payload);
|
||||
}
|
||||
catch (err) {
|
||||
this._loaded(err, null, payload);
|
||||
return;
|
||||
}
|
||||
var then = source && 'then' in source ? source.then : undefined;
|
||||
if (typeof then === 'function') {
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
then.call(source, function (source) { _this._loaded(null, source, payload); }, function (err) { _this._loaded(err, null, payload); });
|
||||
}
|
||||
else {
|
||||
this._loaded(null, source, payload);
|
||||
}
|
||||
};
|
||||
ThreadMessageHandler.prototype._start = function (payload) {
|
||||
var wasi_thread_start = this.instance.exports.wasi_thread_start;
|
||||
if (typeof wasi_thread_start !== 'function') {
|
||||
var err = new TypeError('wasi_thread_start is not exported');
|
||||
notifyPthreadCreateResult(payload.sab, 2, err);
|
||||
throw err;
|
||||
}
|
||||
var postMessage = this.postMessage;
|
||||
var tid = payload.tid;
|
||||
var startArg = payload.arg;
|
||||
notifyPthreadCreateResult(payload.sab, 1);
|
||||
try {
|
||||
wasi_thread_start(tid, startArg);
|
||||
}
|
||||
catch (err) {
|
||||
if (err !== 'unwind') {
|
||||
throw err;
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
postMessage(createMessage('cleanup-thread', { tid: tid }));
|
||||
};
|
||||
ThreadMessageHandler.prototype._loaded = function (err, source, payload) {
|
||||
if (err) {
|
||||
notifyPthreadCreateResult(payload.sab, 2, err);
|
||||
throw err;
|
||||
}
|
||||
if (source == null) {
|
||||
var err_1 = new TypeError('onLoad should return an object');
|
||||
notifyPthreadCreateResult(payload.sab, 2, err_1);
|
||||
throw err_1;
|
||||
}
|
||||
var instance = source.instance;
|
||||
if (!instance) {
|
||||
var err_2 = new TypeError('onLoad should return an object which includes "instance"');
|
||||
notifyPthreadCreateResult(payload.sab, 2, err_2);
|
||||
throw err_2;
|
||||
}
|
||||
this.instance = instance;
|
||||
var postMessage = this.postMessage;
|
||||
postMessage(createMessage('loaded', {}));
|
||||
var messages = this.messagesBeforeLoad;
|
||||
this.messagesBeforeLoad = [];
|
||||
for (var i = 0; i < messages.length; i++) {
|
||||
var data = messages[i];
|
||||
this.handle({ data: data });
|
||||
}
|
||||
};
|
||||
ThreadMessageHandler.prototype.handleAfterLoad = function (e, f) {
|
||||
if (this.instance !== undefined) {
|
||||
f.call(this, e);
|
||||
}
|
||||
else {
|
||||
this.messagesBeforeLoad.push(e.data);
|
||||
}
|
||||
};
|
||||
return ThreadMessageHandler;
|
||||
}());
|
||||
function notifyPthreadCreateResult(sab, result, error) {
|
||||
if (sab) {
|
||||
serizeErrorToBuffer(sab.buffer, result, error);
|
||||
Atomics.notify(sab, 0);
|
||||
}
|
||||
}
|
||||
|
||||
export { ThreadManager, ThreadMessageHandler, WASIThreads, createInstanceProxy, isSharedArrayBuffer, isTrapError };
|
||||
+954
@@ -0,0 +1,954 @@
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
||||
typeof define === 'function' && define.amd ? define(['exports'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.wasiThreads = {}));
|
||||
})(this, (function (exports) {
|
||||
var _WebAssembly = typeof WebAssembly !== 'undefined'
|
||||
? WebAssembly
|
||||
: typeof WXWebAssembly !== 'undefined'
|
||||
? WXWebAssembly
|
||||
: undefined;
|
||||
var ENVIRONMENT_IS_NODE = typeof process === 'object' && process !== null &&
|
||||
typeof process.versions === 'object' && process.versions !== null &&
|
||||
typeof process.versions.node === 'string';
|
||||
function getPostMessage(options) {
|
||||
return typeof (options === null || options === void 0 ? void 0 : options.postMessage) === 'function'
|
||||
? options.postMessage
|
||||
: typeof postMessage === 'function'
|
||||
? postMessage
|
||||
: undefined;
|
||||
}
|
||||
function serizeErrorToBuffer(sab, code, error) {
|
||||
var i32array = new Int32Array(sab);
|
||||
Atomics.store(i32array, 0, code);
|
||||
if (code > 1 && error) {
|
||||
var name_1 = error.name;
|
||||
var message = error.message;
|
||||
var stack = error.stack;
|
||||
var nameBuffer = new TextEncoder().encode(name_1);
|
||||
var messageBuffer = new TextEncoder().encode(message);
|
||||
var stackBuffer = new TextEncoder().encode(stack);
|
||||
Atomics.store(i32array, 1, nameBuffer.length);
|
||||
Atomics.store(i32array, 2, messageBuffer.length);
|
||||
Atomics.store(i32array, 3, stackBuffer.length);
|
||||
var buffer = new Uint8Array(sab);
|
||||
buffer.set(nameBuffer, 16);
|
||||
buffer.set(messageBuffer, 16 + nameBuffer.length);
|
||||
buffer.set(stackBuffer, 16 + nameBuffer.length + messageBuffer.length);
|
||||
}
|
||||
}
|
||||
function deserizeErrorFromBuffer(sab) {
|
||||
var _a, _b;
|
||||
var i32array = new Int32Array(sab);
|
||||
var status = Atomics.load(i32array, 0);
|
||||
if (status <= 1) {
|
||||
return null;
|
||||
}
|
||||
var nameLength = Atomics.load(i32array, 1);
|
||||
var messageLength = Atomics.load(i32array, 2);
|
||||
var stackLength = Atomics.load(i32array, 3);
|
||||
var buffer = new Uint8Array(sab);
|
||||
var nameBuffer = buffer.slice(16, 16 + nameLength);
|
||||
var messageBuffer = buffer.slice(16 + nameLength, 16 + nameLength + messageLength);
|
||||
var stackBuffer = buffer.slice(16 + nameLength + messageLength, 16 + nameLength + messageLength + stackLength);
|
||||
var name = new TextDecoder().decode(nameBuffer);
|
||||
var message = new TextDecoder().decode(messageBuffer);
|
||||
var stack = new TextDecoder().decode(stackBuffer);
|
||||
var ErrorConstructor = (_a = globalThis[name]) !== null && _a !== void 0 ? _a : (name === 'RuntimeError' ? ((_b = _WebAssembly.RuntimeError) !== null && _b !== void 0 ? _b : Error) : Error);
|
||||
var error = new ErrorConstructor(message);
|
||||
Object.defineProperty(error, 'stack', {
|
||||
value: stack,
|
||||
writable: true,
|
||||
enumerable: false,
|
||||
configurable: true
|
||||
});
|
||||
return error;
|
||||
}
|
||||
/** @public */
|
||||
function isSharedArrayBuffer(value) {
|
||||
return ((typeof SharedArrayBuffer === 'function' && value instanceof SharedArrayBuffer) ||
|
||||
(Object.prototype.toString.call(value) === '[object SharedArrayBuffer]'));
|
||||
}
|
||||
/** @public */
|
||||
function isTrapError(e) {
|
||||
try {
|
||||
return e instanceof _WebAssembly.RuntimeError;
|
||||
}
|
||||
catch (_) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function createMessage(type, payload) {
|
||||
return {
|
||||
__emnapi__: {
|
||||
type: type,
|
||||
payload: payload
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
var WASI_THREADS_MAX_TID = 0x1FFFFFFF;
|
||||
function checkSharedWasmMemory(wasmMemory) {
|
||||
if (wasmMemory) {
|
||||
if (!isSharedArrayBuffer(wasmMemory.buffer)) {
|
||||
throw new Error('Multithread features require shared wasm memory. ' +
|
||||
'Try to compile with `-matomics -mbulk-memory` and use `--import-memory --shared-memory` during linking, ' +
|
||||
'then create WebAssembly.Memory with `shared: true` option');
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (typeof SharedArrayBuffer === 'undefined') {
|
||||
throw new Error('Current environment does not support SharedArrayBuffer, threads are not available!');
|
||||
}
|
||||
}
|
||||
}
|
||||
function getReuseWorker(value) {
|
||||
var _a;
|
||||
if (typeof value === 'boolean') {
|
||||
return value ? { size: 0, strict: false } : false;
|
||||
}
|
||||
if (typeof value === 'number') {
|
||||
if (!(value >= 0)) {
|
||||
throw new RangeError('reuseWorker: size must be a non-negative integer');
|
||||
}
|
||||
return { size: value, strict: false };
|
||||
}
|
||||
if (!value) {
|
||||
return false;
|
||||
}
|
||||
var size = (_a = Number(value.size)) !== null && _a !== void 0 ? _a : 0;
|
||||
var strict = Boolean(value.strict);
|
||||
if (!(size > 0) && strict) {
|
||||
throw new RangeError('reuseWorker: size must be set to positive integer if strict is set to true');
|
||||
}
|
||||
return { size: size, strict: strict };
|
||||
}
|
||||
var nextWorkerID = 0;
|
||||
/** @public */
|
||||
var ThreadManager = /*#__PURE__*/ (function () {
|
||||
function ThreadManager(options) {
|
||||
var _a;
|
||||
this.unusedWorkers = [];
|
||||
this.runningWorkers = [];
|
||||
this.pthreads = Object.create(null);
|
||||
this.wasmModule = null;
|
||||
this.wasmMemory = null;
|
||||
this.messageEvents = new WeakMap();
|
||||
if (!options) {
|
||||
throw new TypeError('ThreadManager(): options is not provided');
|
||||
}
|
||||
if ('childThread' in options) {
|
||||
this._childThread = Boolean(options.childThread);
|
||||
}
|
||||
else {
|
||||
this._childThread = false;
|
||||
}
|
||||
if (this._childThread) {
|
||||
this._onCreateWorker = undefined;
|
||||
this._reuseWorker = false;
|
||||
this._beforeLoad = undefined;
|
||||
}
|
||||
else {
|
||||
this._onCreateWorker = options.onCreateWorker;
|
||||
this._reuseWorker = getReuseWorker(options.reuseWorker);
|
||||
this._beforeLoad = options.beforeLoad;
|
||||
}
|
||||
this.printErr = (_a = options.printErr) !== null && _a !== void 0 ? _a : console.error.bind(console);
|
||||
this.threadSpawn = options.threadSpawn;
|
||||
}
|
||||
Object.defineProperty(ThreadManager.prototype, "nextWorkerID", {
|
||||
get: function () { return nextWorkerID; },
|
||||
enumerable: false,
|
||||
configurable: true
|
||||
});
|
||||
ThreadManager.prototype.init = function () {
|
||||
if (!this._childThread) {
|
||||
this.initMainThread();
|
||||
}
|
||||
};
|
||||
ThreadManager.prototype.initMainThread = function () {
|
||||
this.preparePool();
|
||||
};
|
||||
ThreadManager.prototype.preparePool = function () {
|
||||
if (this._reuseWorker) {
|
||||
if (this._reuseWorker.size) {
|
||||
var pthreadPoolSize = this._reuseWorker.size;
|
||||
while (pthreadPoolSize--) {
|
||||
var worker = this.allocateUnusedWorker();
|
||||
if (ENVIRONMENT_IS_NODE) {
|
||||
// https://github.com/nodejs/node/issues/53036
|
||||
worker.once('message', function () { });
|
||||
worker.unref();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
ThreadManager.prototype.shouldPreloadWorkers = function () {
|
||||
return !this._childThread && this._reuseWorker && this._reuseWorker.size > 0;
|
||||
};
|
||||
ThreadManager.prototype.loadWasmModuleToAllWorkers = function () {
|
||||
var _this_1 = this;
|
||||
var promises = Array(this.unusedWorkers.length);
|
||||
var _loop_1 = function (i) {
|
||||
var worker = this_1.unusedWorkers[i];
|
||||
if (ENVIRONMENT_IS_NODE)
|
||||
worker.ref();
|
||||
promises[i] = this_1.loadWasmModuleToWorker(worker).then(function (w) {
|
||||
if (ENVIRONMENT_IS_NODE)
|
||||
worker.unref();
|
||||
return w;
|
||||
}, function (e) {
|
||||
if (ENVIRONMENT_IS_NODE)
|
||||
worker.unref();
|
||||
throw e;
|
||||
});
|
||||
};
|
||||
var this_1 = this;
|
||||
for (var i = 0; i < this.unusedWorkers.length; ++i) {
|
||||
_loop_1(i);
|
||||
}
|
||||
return Promise.all(promises).catch(function (err) {
|
||||
_this_1.terminateAllThreads();
|
||||
throw err;
|
||||
});
|
||||
};
|
||||
ThreadManager.prototype.preloadWorkers = function () {
|
||||
if (this.shouldPreloadWorkers()) {
|
||||
return this.loadWasmModuleToAllWorkers();
|
||||
}
|
||||
return Promise.resolve([]);
|
||||
};
|
||||
ThreadManager.prototype.setup = function (wasmModule, wasmMemory) {
|
||||
this.wasmModule = wasmModule;
|
||||
this.wasmMemory = wasmMemory;
|
||||
};
|
||||
ThreadManager.prototype.markId = function (worker) {
|
||||
if (worker.__emnapi_tid)
|
||||
return worker.__emnapi_tid;
|
||||
var tid = nextWorkerID + 43;
|
||||
nextWorkerID = (nextWorkerID + 1) % (WASI_THREADS_MAX_TID - 42);
|
||||
this.pthreads[tid] = worker;
|
||||
worker.__emnapi_tid = tid;
|
||||
return tid;
|
||||
};
|
||||
ThreadManager.prototype.returnWorkerToPool = function (worker) {
|
||||
var tid = worker.__emnapi_tid;
|
||||
if (tid !== undefined) {
|
||||
delete this.pthreads[tid];
|
||||
}
|
||||
this.unusedWorkers.push(worker);
|
||||
this.runningWorkers.splice(this.runningWorkers.indexOf(worker), 1);
|
||||
delete worker.__emnapi_tid;
|
||||
if (ENVIRONMENT_IS_NODE) {
|
||||
worker.unref();
|
||||
}
|
||||
};
|
||||
ThreadManager.prototype.loadWasmModuleToWorker = function (worker, sab) {
|
||||
var _this_1 = this;
|
||||
if (worker.whenLoaded)
|
||||
return worker.whenLoaded;
|
||||
var err = this.printErr;
|
||||
var beforeLoad = this._beforeLoad;
|
||||
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
||||
var _this = this;
|
||||
worker.whenLoaded = new Promise(function (resolve, reject) {
|
||||
var handleError = function (e) {
|
||||
var message = 'worker sent an error!';
|
||||
if (worker.__emnapi_tid !== undefined) {
|
||||
message = 'worker (tid = ' + worker.__emnapi_tid + ') sent an error!';
|
||||
}
|
||||
if ('message' in e) {
|
||||
err(message + ' ' + e.message);
|
||||
if (e.message.indexOf('RuntimeError') !== -1 || e.message.indexOf('unreachable') !== -1) {
|
||||
try {
|
||||
_this.terminateAllThreads();
|
||||
}
|
||||
catch (_) { }
|
||||
}
|
||||
}
|
||||
else {
|
||||
err(message);
|
||||
}
|
||||
reject(e);
|
||||
throw e;
|
||||
};
|
||||
var handleMessage = function (data) {
|
||||
if (data.__emnapi__) {
|
||||
var type = data.__emnapi__.type;
|
||||
var payload = data.__emnapi__.payload;
|
||||
if (type === 'loaded') {
|
||||
worker.loaded = true;
|
||||
if (ENVIRONMENT_IS_NODE && !worker.__emnapi_tid) {
|
||||
worker.unref();
|
||||
}
|
||||
resolve(worker);
|
||||
// if (payload.err) {
|
||||
// err('failed to load in child thread: ' + (payload.err.message || payload.err))
|
||||
// }
|
||||
}
|
||||
else if (type === 'cleanup-thread') {
|
||||
if (payload.tid in _this_1.pthreads) {
|
||||
_this_1.cleanThread(worker, payload.tid);
|
||||
}
|
||||
}
|
||||
else if (type === 'spawn-thread') {
|
||||
_this_1.threadSpawn(payload.startArg, payload.errorOrTid);
|
||||
}
|
||||
else if (type === 'terminate-all-threads') {
|
||||
_this_1.terminateAllThreads();
|
||||
}
|
||||
}
|
||||
};
|
||||
worker.onmessage = function (e) {
|
||||
handleMessage(e.data);
|
||||
_this_1.fireMessageEvent(worker, e);
|
||||
};
|
||||
worker.onerror = handleError;
|
||||
if (ENVIRONMENT_IS_NODE) {
|
||||
worker.on('message', function (data) {
|
||||
var _a, _b;
|
||||
(_b = (_a = worker).onmessage) === null || _b === void 0 ? void 0 : _b.call(_a, {
|
||||
data: data
|
||||
});
|
||||
});
|
||||
worker.on('error', function (e) {
|
||||
var _a, _b;
|
||||
(_b = (_a = worker).onerror) === null || _b === void 0 ? void 0 : _b.call(_a, e);
|
||||
});
|
||||
worker.on('detachedExit', function () { });
|
||||
}
|
||||
if (typeof beforeLoad === 'function') {
|
||||
beforeLoad(worker);
|
||||
}
|
||||
try {
|
||||
worker.postMessage(createMessage('load', {
|
||||
wasmModule: _this_1.wasmModule,
|
||||
wasmMemory: _this_1.wasmMemory,
|
||||
sab: sab
|
||||
}));
|
||||
}
|
||||
catch (err) {
|
||||
checkSharedWasmMemory(_this_1.wasmMemory);
|
||||
throw err;
|
||||
}
|
||||
});
|
||||
return worker.whenLoaded;
|
||||
};
|
||||
ThreadManager.prototype.allocateUnusedWorker = function () {
|
||||
var _onCreateWorker = this._onCreateWorker;
|
||||
if (typeof _onCreateWorker !== 'function') {
|
||||
throw new TypeError('`options.onCreateWorker` is not provided');
|
||||
}
|
||||
var worker = _onCreateWorker({ type: 'thread', name: 'emnapi-pthread' });
|
||||
this.unusedWorkers.push(worker);
|
||||
return worker;
|
||||
};
|
||||
ThreadManager.prototype.getNewWorker = function (sab) {
|
||||
if (this._reuseWorker) {
|
||||
if (this.unusedWorkers.length === 0) {
|
||||
if (this._reuseWorker.strict) {
|
||||
if (!ENVIRONMENT_IS_NODE) {
|
||||
var err = this.printErr;
|
||||
err('Tried to spawn a new thread, but the thread pool is exhausted.\n' +
|
||||
'This might result in a deadlock unless some threads eventually exit or the code explicitly breaks out to the event loop.');
|
||||
return;
|
||||
}
|
||||
}
|
||||
var worker_1 = this.allocateUnusedWorker();
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
this.loadWasmModuleToWorker(worker_1, sab);
|
||||
}
|
||||
return this.unusedWorkers.pop();
|
||||
}
|
||||
var worker = this.allocateUnusedWorker();
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
this.loadWasmModuleToWorker(worker, sab);
|
||||
return this.unusedWorkers.pop();
|
||||
};
|
||||
ThreadManager.prototype.cleanThread = function (worker, tid, force) {
|
||||
if (!force && this._reuseWorker) {
|
||||
this.returnWorkerToPool(worker);
|
||||
}
|
||||
else {
|
||||
delete this.pthreads[tid];
|
||||
var index = this.runningWorkers.indexOf(worker);
|
||||
if (index !== -1) {
|
||||
this.runningWorkers.splice(index, 1);
|
||||
}
|
||||
this.terminateWorker(worker);
|
||||
delete worker.__emnapi_tid;
|
||||
}
|
||||
};
|
||||
ThreadManager.prototype.terminateWorker = function (worker) {
|
||||
var _this_1 = this;
|
||||
var _a;
|
||||
var tid = worker.__emnapi_tid;
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
worker.terminate();
|
||||
(_a = this.messageEvents.get(worker)) === null || _a === void 0 ? void 0 : _a.clear();
|
||||
this.messageEvents.delete(worker);
|
||||
worker.onmessage = function (e) {
|
||||
if (e.data.__emnapi__) {
|
||||
var err = _this_1.printErr;
|
||||
err('received "' + e.data.__emnapi__.type + '" command from terminated worker: ' + tid);
|
||||
}
|
||||
};
|
||||
};
|
||||
ThreadManager.prototype.terminateAllThreads = function () {
|
||||
for (var i = 0; i < this.runningWorkers.length; ++i) {
|
||||
this.terminateWorker(this.runningWorkers[i]);
|
||||
}
|
||||
for (var i = 0; i < this.unusedWorkers.length; ++i) {
|
||||
this.terminateWorker(this.unusedWorkers[i]);
|
||||
}
|
||||
this.unusedWorkers = [];
|
||||
this.runningWorkers = [];
|
||||
this.pthreads = Object.create(null);
|
||||
this.preparePool();
|
||||
};
|
||||
ThreadManager.prototype.addMessageEventListener = function (worker, onMessage) {
|
||||
var listeners = this.messageEvents.get(worker);
|
||||
if (!listeners) {
|
||||
listeners = new Set();
|
||||
this.messageEvents.set(worker, listeners);
|
||||
}
|
||||
listeners.add(onMessage);
|
||||
return function () {
|
||||
listeners === null || listeners === void 0 ? void 0 : listeners.delete(onMessage);
|
||||
};
|
||||
};
|
||||
ThreadManager.prototype.fireMessageEvent = function (worker, e) {
|
||||
var listeners = this.messageEvents.get(worker);
|
||||
if (!listeners)
|
||||
return;
|
||||
var err = this.printErr;
|
||||
listeners.forEach(function (listener) {
|
||||
try {
|
||||
listener(e);
|
||||
}
|
||||
catch (e) {
|
||||
err(e.stack);
|
||||
}
|
||||
});
|
||||
};
|
||||
return ThreadManager;
|
||||
}());
|
||||
|
||||
var kIsProxy = Symbol('kIsProxy');
|
||||
/** @public */
|
||||
function createInstanceProxy(instance, memory) {
|
||||
if (instance[kIsProxy])
|
||||
return instance;
|
||||
// https://github.com/nodejs/help/issues/4102
|
||||
var originalExports = instance.exports;
|
||||
var createHandler = function (target) {
|
||||
var handlers = [
|
||||
'apply',
|
||||
'construct',
|
||||
'defineProperty',
|
||||
'deleteProperty',
|
||||
'get',
|
||||
'getOwnPropertyDescriptor',
|
||||
'getPrototypeOf',
|
||||
'has',
|
||||
'isExtensible',
|
||||
'ownKeys',
|
||||
'preventExtensions',
|
||||
'set',
|
||||
'setPrototypeOf'
|
||||
];
|
||||
var handler = {};
|
||||
var _loop_1 = function (i) {
|
||||
var name_1 = handlers[i];
|
||||
handler[name_1] = function () {
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
args.unshift(target);
|
||||
return Reflect[name_1].apply(Reflect, args);
|
||||
};
|
||||
};
|
||||
for (var i = 0; i < handlers.length; i++) {
|
||||
_loop_1(i);
|
||||
}
|
||||
return handler;
|
||||
};
|
||||
var handler = createHandler(originalExports);
|
||||
var _initialize = function () { };
|
||||
var _start = function () { return 0; };
|
||||
handler.get = function (_target, p, receiver) {
|
||||
var _a;
|
||||
if (p === 'memory') {
|
||||
return (_a = (typeof memory === 'function' ? memory() : memory)) !== null && _a !== void 0 ? _a : Reflect.get(originalExports, p, receiver);
|
||||
}
|
||||
if (p === '_initialize') {
|
||||
return p in originalExports ? _initialize : undefined;
|
||||
}
|
||||
if (p === '_start') {
|
||||
return p in originalExports ? _start : undefined;
|
||||
}
|
||||
return Reflect.get(originalExports, p, receiver);
|
||||
};
|
||||
handler.has = function (_target, p) {
|
||||
if (p === 'memory')
|
||||
return true;
|
||||
return Reflect.has(originalExports, p);
|
||||
};
|
||||
var exportsProxy = new Proxy(Object.create(null), handler);
|
||||
return new Proxy(instance, {
|
||||
get: function (target, p, receiver) {
|
||||
if (p === 'exports') {
|
||||
return exportsProxy;
|
||||
}
|
||||
if (p === kIsProxy) {
|
||||
return true;
|
||||
}
|
||||
return Reflect.get(target, p, receiver);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var patchedWasiInstances = new WeakMap();
|
||||
/** @public */
|
||||
var WASIThreads = /*#__PURE__*/ (function () {
|
||||
function WASIThreads(options) {
|
||||
var _this_1 = this;
|
||||
if (!options) {
|
||||
throw new TypeError('WASIThreads(): options is not provided');
|
||||
}
|
||||
if (!options.wasi) {
|
||||
throw new TypeError('WASIThreads(): options.wasi is not provided');
|
||||
}
|
||||
patchedWasiInstances.set(this, new WeakSet());
|
||||
var wasi = options.wasi;
|
||||
patchWasiInstance(this, wasi);
|
||||
this.wasi = wasi;
|
||||
if ('childThread' in options) {
|
||||
this.childThread = Boolean(options.childThread);
|
||||
}
|
||||
else {
|
||||
this.childThread = false;
|
||||
}
|
||||
this.PThread = undefined;
|
||||
if ('threadManager' in options) {
|
||||
if (typeof options.threadManager === 'function') {
|
||||
this.PThread = options.threadManager();
|
||||
}
|
||||
else {
|
||||
this.PThread = options.threadManager;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!this.childThread) {
|
||||
this.PThread = new ThreadManager(options);
|
||||
this.PThread.init();
|
||||
}
|
||||
}
|
||||
var waitThreadStart = false;
|
||||
if ('waitThreadStart' in options) {
|
||||
waitThreadStart = typeof options.waitThreadStart === 'number' ? options.waitThreadStart : Boolean(options.waitThreadStart);
|
||||
}
|
||||
var postMessage = getPostMessage(options);
|
||||
if (this.childThread && typeof postMessage !== 'function') {
|
||||
throw new TypeError('options.postMessage is not a function');
|
||||
}
|
||||
this.postMessage = postMessage;
|
||||
var wasm64 = Boolean(options.wasm64);
|
||||
var threadSpawn = function (startArg, errorOrTid) {
|
||||
var _a;
|
||||
var EAGAIN = 6;
|
||||
var isNewABI = errorOrTid !== undefined;
|
||||
try {
|
||||
checkSharedWasmMemory(_this_1.wasmMemory);
|
||||
}
|
||||
catch (err) {
|
||||
(_a = _this_1.PThread) === null || _a === void 0 ? void 0 : _a.printErr(err.stack);
|
||||
if (isNewABI) {
|
||||
var struct_1 = new Int32Array(_this_1.wasmMemory.buffer, errorOrTid, 2);
|
||||
Atomics.store(struct_1, 0, 1);
|
||||
Atomics.store(struct_1, 1, EAGAIN);
|
||||
Atomics.notify(struct_1, 1);
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
return -EAGAIN;
|
||||
}
|
||||
}
|
||||
if (!isNewABI) {
|
||||
var malloc = _this_1.wasmInstance.exports.malloc;
|
||||
errorOrTid = wasm64 ? Number(malloc(BigInt(8))) : (malloc(8) >>> 0);
|
||||
if (!errorOrTid) {
|
||||
return -48; /* ENOMEM */
|
||||
}
|
||||
}
|
||||
var _free = _this_1.wasmInstance.exports.free;
|
||||
var free = wasm64 ? function (ptr) { _free(BigInt(ptr)); } : _free;
|
||||
var struct = new Int32Array(_this_1.wasmMemory.buffer, errorOrTid, 2);
|
||||
Atomics.store(struct, 0, 0);
|
||||
Atomics.store(struct, 1, 0);
|
||||
if (_this_1.childThread) {
|
||||
postMessage(createMessage('spawn-thread', {
|
||||
startArg: startArg,
|
||||
errorOrTid: errorOrTid
|
||||
}));
|
||||
Atomics.wait(struct, 1, 0);
|
||||
var isError = Atomics.load(struct, 0);
|
||||
var result = Atomics.load(struct, 1);
|
||||
if (isNewABI) {
|
||||
return isError;
|
||||
}
|
||||
free(errorOrTid);
|
||||
return isError ? -result : result;
|
||||
}
|
||||
var shouldWait = waitThreadStart || (waitThreadStart === 0);
|
||||
var sab;
|
||||
if (shouldWait) {
|
||||
sab = new Int32Array(new SharedArrayBuffer(16 + 8192));
|
||||
Atomics.store(sab, 0, 0);
|
||||
}
|
||||
var worker;
|
||||
var tid;
|
||||
var PThread = _this_1.PThread;
|
||||
try {
|
||||
worker = PThread.getNewWorker(sab);
|
||||
if (!worker) {
|
||||
throw new Error('failed to get new worker');
|
||||
}
|
||||
tid = PThread.markId(worker);
|
||||
if (ENVIRONMENT_IS_NODE) {
|
||||
worker.unref();
|
||||
}
|
||||
worker.postMessage(createMessage('start', {
|
||||
tid: tid,
|
||||
arg: startArg,
|
||||
sab: sab
|
||||
}));
|
||||
if (shouldWait) {
|
||||
if (typeof waitThreadStart === 'number') {
|
||||
var waitResult = Atomics.wait(sab, 0, 0, waitThreadStart);
|
||||
if (waitResult === 'timed-out') {
|
||||
try {
|
||||
PThread.cleanThread(worker, tid, true);
|
||||
}
|
||||
catch (_) { }
|
||||
throw new Error('Spawning thread timed out. Please check if the worker is created successfully and if message is handled properly in the worker.');
|
||||
}
|
||||
}
|
||||
else {
|
||||
Atomics.wait(sab, 0, 0);
|
||||
}
|
||||
var r = Atomics.load(sab, 0);
|
||||
if (r > 1) {
|
||||
try {
|
||||
PThread.cleanThread(worker, tid, true);
|
||||
}
|
||||
catch (_) { }
|
||||
throw deserizeErrorFromBuffer(sab.buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
Atomics.store(struct, 0, 1);
|
||||
Atomics.store(struct, 1, EAGAIN);
|
||||
Atomics.notify(struct, 1);
|
||||
PThread === null || PThread === void 0 ? void 0 : PThread.printErr(e.stack);
|
||||
if (isNewABI) {
|
||||
return 1;
|
||||
}
|
||||
free(errorOrTid);
|
||||
return -EAGAIN;
|
||||
}
|
||||
Atomics.store(struct, 0, 0);
|
||||
Atomics.store(struct, 1, tid);
|
||||
Atomics.notify(struct, 1);
|
||||
PThread.runningWorkers.push(worker);
|
||||
if (!shouldWait) {
|
||||
worker.whenLoaded.catch(function (err) {
|
||||
delete worker.whenLoaded;
|
||||
PThread.cleanThread(worker, tid, true);
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
if (isNewABI) {
|
||||
return 0;
|
||||
}
|
||||
free(errorOrTid);
|
||||
return tid;
|
||||
};
|
||||
this.threadSpawn = threadSpawn;
|
||||
if (this.PThread) {
|
||||
this.PThread.threadSpawn = threadSpawn;
|
||||
}
|
||||
}
|
||||
WASIThreads.prototype.getImportObject = function () {
|
||||
return {
|
||||
wasi: {
|
||||
'thread-spawn': this.threadSpawn
|
||||
}
|
||||
};
|
||||
};
|
||||
WASIThreads.prototype.setup = function (wasmInstance, wasmModule, wasmMemory) {
|
||||
wasmMemory !== null && wasmMemory !== void 0 ? wasmMemory : (wasmMemory = wasmInstance.exports.memory);
|
||||
this.wasmInstance = wasmInstance;
|
||||
this.wasmMemory = wasmMemory;
|
||||
if (this.PThread) {
|
||||
this.PThread.setup(wasmModule, wasmMemory);
|
||||
}
|
||||
};
|
||||
WASIThreads.prototype.preloadWorkers = function () {
|
||||
if (this.PThread) {
|
||||
return this.PThread.preloadWorkers();
|
||||
}
|
||||
return Promise.resolve([]);
|
||||
};
|
||||
/**
|
||||
* It's ok to call this method to a WASI command module.
|
||||
*
|
||||
* in child thread, must call this method instead of {@link WASIThreads.start} even if it's a WASI command module
|
||||
*
|
||||
* @returns A proxied WebAssembly instance if in child thread, other wise the original instance
|
||||
*/
|
||||
WASIThreads.prototype.initialize = function (instance, module, memory) {
|
||||
var exports$1 = instance.exports;
|
||||
memory !== null && memory !== void 0 ? memory : (memory = exports$1.memory);
|
||||
if (this.childThread) {
|
||||
instance = createInstanceProxy(instance, memory);
|
||||
}
|
||||
this.setup(instance, module, memory);
|
||||
var wasi = this.wasi;
|
||||
if (('_start' in exports$1) && (typeof exports$1._start === 'function')) {
|
||||
if (this.childThread) {
|
||||
wasi.start(instance);
|
||||
try {
|
||||
var kStarted = getWasiSymbol(wasi, 'kStarted');
|
||||
wasi[kStarted] = false;
|
||||
}
|
||||
catch (_) { }
|
||||
}
|
||||
else {
|
||||
setupInstance(wasi, instance);
|
||||
}
|
||||
}
|
||||
else {
|
||||
wasi.initialize(instance);
|
||||
}
|
||||
return instance;
|
||||
};
|
||||
/**
|
||||
* Equivalent to calling {@link WASIThreads.initialize} and then calling {@link WASIInstance.start}
|
||||
* ```js
|
||||
* this.initialize(instance, module, memory)
|
||||
* this.wasi.start(instance)
|
||||
* ```
|
||||
*/
|
||||
WASIThreads.prototype.start = function (instance, module, memory) {
|
||||
var exports$1 = instance.exports;
|
||||
memory !== null && memory !== void 0 ? memory : (memory = exports$1.memory);
|
||||
if (this.childThread) {
|
||||
instance = createInstanceProxy(instance, memory);
|
||||
}
|
||||
this.setup(instance, module, memory);
|
||||
var exitCode = this.wasi.start(instance);
|
||||
return { exitCode: exitCode, instance: instance };
|
||||
};
|
||||
WASIThreads.prototype.terminateAllThreads = function () {
|
||||
var _a;
|
||||
if (!this.childThread) {
|
||||
(_a = this.PThread) === null || _a === void 0 ? void 0 : _a.terminateAllThreads();
|
||||
}
|
||||
else {
|
||||
this.postMessage(createMessage('terminate-all-threads', {}));
|
||||
}
|
||||
};
|
||||
return WASIThreads;
|
||||
}());
|
||||
function patchWasiInstance(wasiThreads, wasi) {
|
||||
var patched = patchedWasiInstances.get(wasiThreads);
|
||||
if (patched.has(wasi)) {
|
||||
return;
|
||||
}
|
||||
var _this = wasiThreads;
|
||||
var wasiImport = wasi.wasiImport;
|
||||
if (wasiImport) {
|
||||
var proc_exit_1 = wasiImport.proc_exit;
|
||||
wasiImport.proc_exit = function (code) {
|
||||
_this.terminateAllThreads();
|
||||
return proc_exit_1.call(this, code);
|
||||
};
|
||||
}
|
||||
if (!_this.childThread) {
|
||||
var start_1 = wasi.start;
|
||||
if (typeof start_1 === 'function') {
|
||||
wasi.start = function (instance) {
|
||||
try {
|
||||
return start_1.call(this, instance);
|
||||
}
|
||||
catch (err) {
|
||||
if (isTrapError(err)) {
|
||||
_this.terminateAllThreads();
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
patched.add(wasi);
|
||||
}
|
||||
function getWasiSymbol(wasi, description) {
|
||||
var symbols = Object.getOwnPropertySymbols(wasi);
|
||||
var selectDescription = function (description) { return function (s) {
|
||||
if (s.description) {
|
||||
return s.description === description;
|
||||
}
|
||||
return s.toString() === "Symbol(".concat(description, ")");
|
||||
}; };
|
||||
if (Array.isArray(description)) {
|
||||
return description.map(function (d) { return symbols.filter(selectDescription(d))[0]; });
|
||||
}
|
||||
return symbols.filter(selectDescription(description))[0];
|
||||
}
|
||||
function setupInstance(wasi, instance) {
|
||||
var _a = getWasiSymbol(wasi, ['kInstance', 'kSetMemory']), kInstance = _a[0], kSetMemory = _a[1];
|
||||
wasi[kInstance] = instance;
|
||||
wasi[kSetMemory](instance.exports.memory);
|
||||
}
|
||||
|
||||
/** @public */
|
||||
var ThreadMessageHandler = /*#__PURE__*/ (function () {
|
||||
function ThreadMessageHandler(options) {
|
||||
var postMsg = getPostMessage(options);
|
||||
if (typeof postMsg !== 'function') {
|
||||
throw new TypeError('options.postMessage is not a function');
|
||||
}
|
||||
this.postMessage = postMsg;
|
||||
this.onLoad = options === null || options === void 0 ? void 0 : options.onLoad;
|
||||
this.onError = typeof (options === null || options === void 0 ? void 0 : options.onError) === 'function' ? options.onError : function (_type, err) { throw err; };
|
||||
this.instance = undefined;
|
||||
// this.module = undefined
|
||||
this.messagesBeforeLoad = [];
|
||||
}
|
||||
/** @virtual */
|
||||
ThreadMessageHandler.prototype.instantiate = function (data) {
|
||||
if (typeof this.onLoad === 'function') {
|
||||
return this.onLoad(data);
|
||||
}
|
||||
throw new Error('ThreadMessageHandler.prototype.instantiate is not implemented');
|
||||
};
|
||||
/** @virtual */
|
||||
ThreadMessageHandler.prototype.handle = function (e) {
|
||||
var _this = this;
|
||||
var _a;
|
||||
if ((_a = e === null || e === void 0 ? void 0 : e.data) === null || _a === void 0 ? void 0 : _a.__emnapi__) {
|
||||
var type = e.data.__emnapi__.type;
|
||||
var payload_1 = e.data.__emnapi__.payload;
|
||||
try {
|
||||
if (type === 'load') {
|
||||
this._load(payload_1);
|
||||
}
|
||||
else if (type === 'start') {
|
||||
this.handleAfterLoad(e, function () {
|
||||
_this._start(payload_1);
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
this.onError(err, type);
|
||||
}
|
||||
}
|
||||
};
|
||||
ThreadMessageHandler.prototype._load = function (payload) {
|
||||
var _this = this;
|
||||
if (this.instance !== undefined)
|
||||
return;
|
||||
var source;
|
||||
try {
|
||||
source = this.instantiate(payload);
|
||||
}
|
||||
catch (err) {
|
||||
this._loaded(err, null, payload);
|
||||
return;
|
||||
}
|
||||
var then = source && 'then' in source ? source.then : undefined;
|
||||
if (typeof then === 'function') {
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
then.call(source, function (source) { _this._loaded(null, source, payload); }, function (err) { _this._loaded(err, null, payload); });
|
||||
}
|
||||
else {
|
||||
this._loaded(null, source, payload);
|
||||
}
|
||||
};
|
||||
ThreadMessageHandler.prototype._start = function (payload) {
|
||||
var wasi_thread_start = this.instance.exports.wasi_thread_start;
|
||||
if (typeof wasi_thread_start !== 'function') {
|
||||
var err = new TypeError('wasi_thread_start is not exported');
|
||||
notifyPthreadCreateResult(payload.sab, 2, err);
|
||||
throw err;
|
||||
}
|
||||
var postMessage = this.postMessage;
|
||||
var tid = payload.tid;
|
||||
var startArg = payload.arg;
|
||||
notifyPthreadCreateResult(payload.sab, 1);
|
||||
try {
|
||||
wasi_thread_start(tid, startArg);
|
||||
}
|
||||
catch (err) {
|
||||
if (err !== 'unwind') {
|
||||
throw err;
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
postMessage(createMessage('cleanup-thread', { tid: tid }));
|
||||
};
|
||||
ThreadMessageHandler.prototype._loaded = function (err, source, payload) {
|
||||
if (err) {
|
||||
notifyPthreadCreateResult(payload.sab, 2, err);
|
||||
throw err;
|
||||
}
|
||||
if (source == null) {
|
||||
var err_1 = new TypeError('onLoad should return an object');
|
||||
notifyPthreadCreateResult(payload.sab, 2, err_1);
|
||||
throw err_1;
|
||||
}
|
||||
var instance = source.instance;
|
||||
if (!instance) {
|
||||
var err_2 = new TypeError('onLoad should return an object which includes "instance"');
|
||||
notifyPthreadCreateResult(payload.sab, 2, err_2);
|
||||
throw err_2;
|
||||
}
|
||||
this.instance = instance;
|
||||
var postMessage = this.postMessage;
|
||||
postMessage(createMessage('loaded', {}));
|
||||
var messages = this.messagesBeforeLoad;
|
||||
this.messagesBeforeLoad = [];
|
||||
for (var i = 0; i < messages.length; i++) {
|
||||
var data = messages[i];
|
||||
this.handle({ data: data });
|
||||
}
|
||||
};
|
||||
ThreadMessageHandler.prototype.handleAfterLoad = function (e, f) {
|
||||
if (this.instance !== undefined) {
|
||||
f.call(this, e);
|
||||
}
|
||||
else {
|
||||
this.messagesBeforeLoad.push(e.data);
|
||||
}
|
||||
};
|
||||
return ThreadMessageHandler;
|
||||
}());
|
||||
function notifyPthreadCreateResult(sab, result, error) {
|
||||
if (sab) {
|
||||
serizeErrorToBuffer(sab.buffer, result, error);
|
||||
Atomics.notify(sab, 0);
|
||||
}
|
||||
}
|
||||
|
||||
exports.ThreadManager = ThreadManager;
|
||||
exports.ThreadMessageHandler = ThreadMessageHandler;
|
||||
exports.WASIThreads = WASIThreads;
|
||||
exports.createInstanceProxy = createInstanceProxy;
|
||||
exports.isSharedArrayBuffer = isSharedArrayBuffer;
|
||||
exports.isTrapError = isTrapError;
|
||||
|
||||
}));
|
||||
+272
@@ -0,0 +1,272 @@
|
||||
/// <reference types="node" />
|
||||
|
||||
import type { Worker as Worker_2 } from 'worker_threads';
|
||||
|
||||
/** @public */
|
||||
export declare interface BaseOptions {
|
||||
wasi: WASIInstance;
|
||||
version?: 'preview1';
|
||||
wasm64?: boolean;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface ChildThreadOptions extends BaseOptions {
|
||||
childThread: true;
|
||||
postMessage?: (data: any) => void;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface CleanupThreadPayload {
|
||||
tid: number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface CommandInfo<T extends CommandType> {
|
||||
type: T;
|
||||
payload: CommandPayloadMap[T];
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface CommandPayloadMap {
|
||||
load: LoadPayload;
|
||||
loaded: LoadedPayload;
|
||||
start: StartPayload;
|
||||
'cleanup-thread': CleanupThreadPayload;
|
||||
'terminate-all-threads': TerminateAllThreadsPayload;
|
||||
'spawn-thread': SpawnThreadPayload;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare type CommandType = keyof CommandPayloadMap;
|
||||
|
||||
/** @public */
|
||||
export declare function createInstanceProxy(instance: WebAssembly.Instance, memory?: WebAssembly.Memory | (() => WebAssembly.Memory)): WebAssembly.Instance;
|
||||
|
||||
/** @public */
|
||||
export declare function isSharedArrayBuffer(value: any): value is SharedArrayBuffer;
|
||||
|
||||
/** @public */
|
||||
export declare function isTrapError(e: Error): e is WebAssembly.RuntimeError;
|
||||
|
||||
/** @public */
|
||||
export declare interface LoadedPayload {
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface LoadPayload {
|
||||
wasmModule: WebAssembly.Module;
|
||||
wasmMemory: WebAssembly.Memory;
|
||||
sab?: Int32Array;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface MainThreadBaseOptions extends BaseOptions {
|
||||
waitThreadStart?: boolean | number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare type MainThreadOptions = MainThreadOptionsWithThreadManager | MainThreadOptionsCreateThreadManager;
|
||||
|
||||
/** @public */
|
||||
export declare interface MainThreadOptionsCreateThreadManager extends MainThreadBaseOptions, ThreadManagerOptionsMain {
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface MainThreadOptionsWithThreadManager extends MainThreadBaseOptions {
|
||||
threadManager?: ThreadManager | (() => ThreadManager);
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface MessageEventData<T extends CommandType> {
|
||||
__emnapi__: CommandInfo<T>;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface ReuseWorkerOptions {
|
||||
/**
|
||||
* @see {@link https://emscripten.org/docs/tools_reference/settings_reference.html#pthread-pool-size | PTHREAD_POOL_SIZE}
|
||||
*/
|
||||
size: number;
|
||||
/**
|
||||
* @see {@link https://emscripten.org/docs/tools_reference/settings_reference.html#pthread-pool-size-strict | PTHREAD_POOL_SIZE_STRICT}
|
||||
*/
|
||||
strict?: boolean;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface SpawnThreadPayload {
|
||||
startArg: number;
|
||||
errorOrTid: number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface StartPayload {
|
||||
tid: number;
|
||||
arg: number;
|
||||
sab?: Int32Array;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface StartResult {
|
||||
exitCode: number;
|
||||
instance: WebAssembly.Instance;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface TerminateAllThreadsPayload {
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare class ThreadManager {
|
||||
unusedWorkers: WorkerLike[];
|
||||
runningWorkers: WorkerLike[];
|
||||
pthreads: Record<number, WorkerLike>;
|
||||
get nextWorkerID(): number;
|
||||
wasmModule: WebAssembly.Module | null;
|
||||
wasmMemory: WebAssembly.Memory | null;
|
||||
private readonly messageEvents;
|
||||
private readonly _childThread;
|
||||
private readonly _onCreateWorker;
|
||||
private readonly _reuseWorker;
|
||||
private readonly _beforeLoad?;
|
||||
/* Excluded from this release type: printErr */
|
||||
threadSpawn?: ((startArg: number, errorOrTid?: number) => number);
|
||||
constructor(options: ThreadManagerOptions);
|
||||
init(): void;
|
||||
initMainThread(): void;
|
||||
private preparePool;
|
||||
shouldPreloadWorkers(): boolean;
|
||||
loadWasmModuleToAllWorkers(): Promise<WorkerLike[]>;
|
||||
preloadWorkers(): Promise<WorkerLike[]>;
|
||||
setup(wasmModule: WebAssembly.Module, wasmMemory: WebAssembly.Memory): void;
|
||||
markId(worker: WorkerLike): number;
|
||||
returnWorkerToPool(worker: WorkerLike): void;
|
||||
loadWasmModuleToWorker(worker: WorkerLike, sab?: Int32Array): Promise<WorkerLike>;
|
||||
allocateUnusedWorker(): WorkerLike;
|
||||
getNewWorker(sab?: Int32Array): WorkerLike | undefined;
|
||||
cleanThread(worker: WorkerLike, tid: number, force?: boolean): void;
|
||||
terminateWorker(worker: WorkerLike): void;
|
||||
terminateAllThreads(): void;
|
||||
addMessageEventListener(worker: WorkerLike, onMessage: (e: WorkerMessageEvent) => void): () => void;
|
||||
fireMessageEvent(worker: WorkerLike, e: WorkerMessageEvent): void;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare type ThreadManagerOptions = ThreadManagerOptionsMain | ThreadManagerOptionsChild;
|
||||
|
||||
/** @public */
|
||||
export declare interface ThreadManagerOptionsBase {
|
||||
printErr?: (message: string) => void;
|
||||
threadSpawn?: (startArg: number, errorOrTid?: number) => number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface ThreadManagerOptionsChild extends ThreadManagerOptionsBase {
|
||||
childThread: true;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface ThreadManagerOptionsMain extends ThreadManagerOptionsBase {
|
||||
beforeLoad?: (worker: WorkerLike) => any;
|
||||
reuseWorker?: boolean | number | ReuseWorkerOptions;
|
||||
onCreateWorker: WorkerFactory;
|
||||
childThread?: false;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare class ThreadMessageHandler {
|
||||
protected instance: WebAssembly.Instance | undefined;
|
||||
private messagesBeforeLoad;
|
||||
protected postMessage: (message: any) => void;
|
||||
protected onLoad?: (data: LoadPayload) => WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
|
||||
protected onError: (error: Error, type: WorkerMessageType) => void;
|
||||
constructor(options?: ThreadMessageHandlerOptions);
|
||||
/** @virtual */
|
||||
instantiate(data: LoadPayload): WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
|
||||
/** @virtual */
|
||||
handle(e: WorkerMessageEvent<MessageEventData<WorkerMessageType>>): void;
|
||||
private _load;
|
||||
private _start;
|
||||
protected _loaded(err: Error | null, source: WebAssembly.WebAssemblyInstantiatedSource | null, payload: LoadPayload): void;
|
||||
protected handleAfterLoad<E extends WorkerMessageEvent>(e: E, f: (e: E) => void): void;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface ThreadMessageHandlerOptions {
|
||||
onLoad?: (data: LoadPayload) => WebAssembly.WebAssemblyInstantiatedSource | PromiseLike<WebAssembly.WebAssemblyInstantiatedSource>;
|
||||
onError?: (error: Error, type: WorkerMessageType) => void;
|
||||
postMessage?: (message: any) => void;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface WASIInstance {
|
||||
readonly wasiImport?: Record<string, any>;
|
||||
initialize(instance: object): void;
|
||||
start(instance: object): number;
|
||||
getImportObject?(): any;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare class WASIThreads {
|
||||
PThread: ThreadManager | undefined;
|
||||
private wasmMemory;
|
||||
private wasmInstance;
|
||||
private readonly threadSpawn;
|
||||
readonly childThread: boolean;
|
||||
private readonly postMessage;
|
||||
readonly wasi: WASIInstance;
|
||||
constructor(options: WASIThreadsOptions);
|
||||
getImportObject(): {
|
||||
wasi: WASIThreadsImports;
|
||||
};
|
||||
setup(wasmInstance: WebAssembly.Instance, wasmModule: WebAssembly.Module, wasmMemory?: WebAssembly.Memory): void;
|
||||
preloadWorkers(): Promise<WorkerLike[]>;
|
||||
/**
|
||||
* It's ok to call this method to a WASI command module.
|
||||
*
|
||||
* in child thread, must call this method instead of {@link WASIThreads.start} even if it's a WASI command module
|
||||
*
|
||||
* @returns A proxied WebAssembly instance if in child thread, other wise the original instance
|
||||
*/
|
||||
initialize(instance: WebAssembly.Instance, module: WebAssembly.Module, memory?: WebAssembly.Memory): WebAssembly.Instance;
|
||||
/**
|
||||
* Equivalent to calling {@link WASIThreads.initialize} and then calling {@link WASIInstance.start}
|
||||
* ```js
|
||||
* this.initialize(instance, module, memory)
|
||||
* this.wasi.start(instance)
|
||||
* ```
|
||||
*/
|
||||
start(instance: WebAssembly.Instance, module: WebAssembly.Module, memory?: WebAssembly.Memory): StartResult;
|
||||
terminateAllThreads(): void;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare interface WASIThreadsImports {
|
||||
'thread-spawn': (startArg: number, errorOrTid?: number) => number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare type WASIThreadsOptions = MainThreadOptions | ChildThreadOptions;
|
||||
|
||||
/** @public */
|
||||
export declare type WorkerFactory = (ctx: {
|
||||
type: string;
|
||||
name: string;
|
||||
}) => WorkerLike;
|
||||
|
||||
/** @public */
|
||||
export declare type WorkerLike = (Worker | Worker_2) & {
|
||||
whenLoaded?: Promise<WorkerLike>;
|
||||
loaded?: boolean;
|
||||
__emnapi_tid?: number;
|
||||
};
|
||||
|
||||
/** @public */
|
||||
export declare interface WorkerMessageEvent<T = any> {
|
||||
data: T;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare type WorkerMessageType = 'load' | 'start';
|
||||
|
||||
export { }
|
||||
+1
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
+889
@@ -0,0 +1,889 @@
|
||||
const _WebAssembly = typeof WebAssembly !== 'undefined'
|
||||
? WebAssembly
|
||||
: typeof WXWebAssembly !== 'undefined'
|
||||
? WXWebAssembly
|
||||
: undefined;
|
||||
const ENVIRONMENT_IS_NODE = typeof process === 'object' && process !== null &&
|
||||
typeof process.versions === 'object' && process.versions !== null &&
|
||||
typeof process.versions.node === 'string';
|
||||
function getPostMessage(options) {
|
||||
return typeof (options === null || options === void 0 ? void 0 : options.postMessage) === 'function'
|
||||
? options.postMessage
|
||||
: typeof postMessage === 'function'
|
||||
? postMessage
|
||||
: undefined;
|
||||
}
|
||||
function serizeErrorToBuffer(sab, code, error) {
|
||||
const i32array = new Int32Array(sab);
|
||||
Atomics.store(i32array, 0, code);
|
||||
if (code > 1 && error) {
|
||||
const name = error.name;
|
||||
const message = error.message;
|
||||
const stack = error.stack;
|
||||
const nameBuffer = new TextEncoder().encode(name);
|
||||
const messageBuffer = new TextEncoder().encode(message);
|
||||
const stackBuffer = new TextEncoder().encode(stack);
|
||||
Atomics.store(i32array, 1, nameBuffer.length);
|
||||
Atomics.store(i32array, 2, messageBuffer.length);
|
||||
Atomics.store(i32array, 3, stackBuffer.length);
|
||||
const buffer = new Uint8Array(sab);
|
||||
buffer.set(nameBuffer, 16);
|
||||
buffer.set(messageBuffer, 16 + nameBuffer.length);
|
||||
buffer.set(stackBuffer, 16 + nameBuffer.length + messageBuffer.length);
|
||||
}
|
||||
}
|
||||
function deserizeErrorFromBuffer(sab) {
|
||||
var _a, _b;
|
||||
const i32array = new Int32Array(sab);
|
||||
const status = Atomics.load(i32array, 0);
|
||||
if (status <= 1) {
|
||||
return null;
|
||||
}
|
||||
const nameLength = Atomics.load(i32array, 1);
|
||||
const messageLength = Atomics.load(i32array, 2);
|
||||
const stackLength = Atomics.load(i32array, 3);
|
||||
const buffer = new Uint8Array(sab);
|
||||
const nameBuffer = buffer.slice(16, 16 + nameLength);
|
||||
const messageBuffer = buffer.slice(16 + nameLength, 16 + nameLength + messageLength);
|
||||
const stackBuffer = buffer.slice(16 + nameLength + messageLength, 16 + nameLength + messageLength + stackLength);
|
||||
const name = new TextDecoder().decode(nameBuffer);
|
||||
const message = new TextDecoder().decode(messageBuffer);
|
||||
const stack = new TextDecoder().decode(stackBuffer);
|
||||
const ErrorConstructor = (_a = globalThis[name]) !== null && _a !== void 0 ? _a : (name === 'RuntimeError' ? ((_b = _WebAssembly.RuntimeError) !== null && _b !== void 0 ? _b : Error) : Error);
|
||||
const error = new ErrorConstructor(message);
|
||||
Object.defineProperty(error, 'stack', {
|
||||
value: stack,
|
||||
writable: true,
|
||||
enumerable: false,
|
||||
configurable: true
|
||||
});
|
||||
return error;
|
||||
}
|
||||
function isSharedArrayBuffer(value) {
|
||||
return ((typeof SharedArrayBuffer === 'function' && value instanceof SharedArrayBuffer) ||
|
||||
(Object.prototype.toString.call(value) === '[object SharedArrayBuffer]'));
|
||||
}
|
||||
function isTrapError(e) {
|
||||
try {
|
||||
return e instanceof _WebAssembly.RuntimeError;
|
||||
}
|
||||
catch (_) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function createMessage(type, payload) {
|
||||
return {
|
||||
__emnapi__: {
|
||||
type,
|
||||
payload
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const WASI_THREADS_MAX_TID = 0x1FFFFFFF;
|
||||
function checkSharedWasmMemory(wasmMemory) {
|
||||
if (wasmMemory) {
|
||||
if (!isSharedArrayBuffer(wasmMemory.buffer)) {
|
||||
throw new Error('Multithread features require shared wasm memory. ' +
|
||||
'Try to compile with `-matomics -mbulk-memory` and use `--import-memory --shared-memory` during linking, ' +
|
||||
'then create WebAssembly.Memory with `shared: true` option');
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (typeof SharedArrayBuffer === 'undefined') {
|
||||
throw new Error('Current environment does not support SharedArrayBuffer, threads are not available!');
|
||||
}
|
||||
}
|
||||
}
|
||||
function getReuseWorker(value) {
|
||||
var _a;
|
||||
if (typeof value === 'boolean') {
|
||||
return value ? { size: 0, strict: false } : false;
|
||||
}
|
||||
if (typeof value === 'number') {
|
||||
if (!(value >= 0)) {
|
||||
throw new RangeError('reuseWorker: size must be a non-negative integer');
|
||||
}
|
||||
return { size: value, strict: false };
|
||||
}
|
||||
if (!value) {
|
||||
return false;
|
||||
}
|
||||
const size = (_a = Number(value.size)) !== null && _a !== void 0 ? _a : 0;
|
||||
const strict = Boolean(value.strict);
|
||||
if (!(size > 0) && strict) {
|
||||
throw new RangeError('reuseWorker: size must be set to positive integer if strict is set to true');
|
||||
}
|
||||
return { size, strict };
|
||||
}
|
||||
let nextWorkerID = 0;
|
||||
class ThreadManager {
|
||||
get nextWorkerID() { return nextWorkerID; }
|
||||
constructor(options) {
|
||||
var _a;
|
||||
this.unusedWorkers = [];
|
||||
this.runningWorkers = [];
|
||||
this.pthreads = Object.create(null);
|
||||
this.wasmModule = null;
|
||||
this.wasmMemory = null;
|
||||
this.messageEvents = new WeakMap();
|
||||
if (!options) {
|
||||
throw new TypeError('ThreadManager(): options is not provided');
|
||||
}
|
||||
if ('childThread' in options) {
|
||||
this._childThread = Boolean(options.childThread);
|
||||
}
|
||||
else {
|
||||
this._childThread = false;
|
||||
}
|
||||
if (this._childThread) {
|
||||
this._onCreateWorker = undefined;
|
||||
this._reuseWorker = false;
|
||||
this._beforeLoad = undefined;
|
||||
}
|
||||
else {
|
||||
this._onCreateWorker = options.onCreateWorker;
|
||||
this._reuseWorker = getReuseWorker(options.reuseWorker);
|
||||
this._beforeLoad = options.beforeLoad;
|
||||
}
|
||||
this.printErr = (_a = options.printErr) !== null && _a !== void 0 ? _a : console.error.bind(console);
|
||||
this.threadSpawn = options.threadSpawn;
|
||||
}
|
||||
init() {
|
||||
if (!this._childThread) {
|
||||
this.initMainThread();
|
||||
}
|
||||
}
|
||||
initMainThread() {
|
||||
this.preparePool();
|
||||
}
|
||||
preparePool() {
|
||||
if (this._reuseWorker) {
|
||||
if (this._reuseWorker.size) {
|
||||
let pthreadPoolSize = this._reuseWorker.size;
|
||||
while (pthreadPoolSize--) {
|
||||
const worker = this.allocateUnusedWorker();
|
||||
if (ENVIRONMENT_IS_NODE) {
|
||||
worker.once('message', () => { });
|
||||
worker.unref();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
shouldPreloadWorkers() {
|
||||
return !this._childThread && this._reuseWorker && this._reuseWorker.size > 0;
|
||||
}
|
||||
loadWasmModuleToAllWorkers() {
|
||||
const promises = Array(this.unusedWorkers.length);
|
||||
for (let i = 0; i < this.unusedWorkers.length; ++i) {
|
||||
const worker = this.unusedWorkers[i];
|
||||
if (ENVIRONMENT_IS_NODE)
|
||||
worker.ref();
|
||||
promises[i] = this.loadWasmModuleToWorker(worker).then((w) => {
|
||||
if (ENVIRONMENT_IS_NODE)
|
||||
worker.unref();
|
||||
return w;
|
||||
}, (e) => {
|
||||
if (ENVIRONMENT_IS_NODE)
|
||||
worker.unref();
|
||||
throw e;
|
||||
});
|
||||
}
|
||||
return Promise.all(promises).catch((err) => {
|
||||
this.terminateAllThreads();
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
preloadWorkers() {
|
||||
if (this.shouldPreloadWorkers()) {
|
||||
return this.loadWasmModuleToAllWorkers();
|
||||
}
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
setup(wasmModule, wasmMemory) {
|
||||
this.wasmModule = wasmModule;
|
||||
this.wasmMemory = wasmMemory;
|
||||
}
|
||||
markId(worker) {
|
||||
if (worker.__emnapi_tid)
|
||||
return worker.__emnapi_tid;
|
||||
const tid = nextWorkerID + 43;
|
||||
nextWorkerID = (nextWorkerID + 1) % (WASI_THREADS_MAX_TID - 42);
|
||||
this.pthreads[tid] = worker;
|
||||
worker.__emnapi_tid = tid;
|
||||
return tid;
|
||||
}
|
||||
returnWorkerToPool(worker) {
|
||||
var tid = worker.__emnapi_tid;
|
||||
if (tid !== undefined) {
|
||||
delete this.pthreads[tid];
|
||||
}
|
||||
this.unusedWorkers.push(worker);
|
||||
this.runningWorkers.splice(this.runningWorkers.indexOf(worker), 1);
|
||||
delete worker.__emnapi_tid;
|
||||
if (ENVIRONMENT_IS_NODE) {
|
||||
worker.unref();
|
||||
}
|
||||
}
|
||||
loadWasmModuleToWorker(worker, sab) {
|
||||
if (worker.whenLoaded)
|
||||
return worker.whenLoaded;
|
||||
const err = this.printErr;
|
||||
const beforeLoad = this._beforeLoad;
|
||||
const _this = this;
|
||||
worker.whenLoaded = new Promise((resolve, reject) => {
|
||||
const handleError = function (e) {
|
||||
let message = 'worker sent an error!';
|
||||
if (worker.__emnapi_tid !== undefined) {
|
||||
message = 'worker (tid = ' + worker.__emnapi_tid + ') sent an error!';
|
||||
}
|
||||
if ('message' in e) {
|
||||
err(message + ' ' + e.message);
|
||||
if (e.message.indexOf('RuntimeError') !== -1 || e.message.indexOf('unreachable') !== -1) {
|
||||
try {
|
||||
_this.terminateAllThreads();
|
||||
}
|
||||
catch (_) { }
|
||||
}
|
||||
}
|
||||
else {
|
||||
err(message);
|
||||
}
|
||||
reject(e);
|
||||
throw e;
|
||||
};
|
||||
const handleMessage = (data) => {
|
||||
if (data.__emnapi__) {
|
||||
const type = data.__emnapi__.type;
|
||||
const payload = data.__emnapi__.payload;
|
||||
if (type === 'loaded') {
|
||||
worker.loaded = true;
|
||||
if (ENVIRONMENT_IS_NODE && !worker.__emnapi_tid) {
|
||||
worker.unref();
|
||||
}
|
||||
resolve(worker);
|
||||
}
|
||||
else if (type === 'cleanup-thread') {
|
||||
if (payload.tid in this.pthreads) {
|
||||
this.cleanThread(worker, payload.tid);
|
||||
}
|
||||
}
|
||||
else if (type === 'spawn-thread') {
|
||||
this.threadSpawn(payload.startArg, payload.errorOrTid);
|
||||
}
|
||||
else if (type === 'terminate-all-threads') {
|
||||
this.terminateAllThreads();
|
||||
}
|
||||
}
|
||||
};
|
||||
worker.onmessage = (e) => {
|
||||
handleMessage(e.data);
|
||||
this.fireMessageEvent(worker, e);
|
||||
};
|
||||
worker.onerror = handleError;
|
||||
if (ENVIRONMENT_IS_NODE) {
|
||||
worker.on('message', function (data) {
|
||||
var _a, _b;
|
||||
(_b = (_a = worker).onmessage) === null || _b === void 0 ? void 0 : _b.call(_a, {
|
||||
data
|
||||
});
|
||||
});
|
||||
worker.on('error', function (e) {
|
||||
var _a, _b;
|
||||
(_b = (_a = worker).onerror) === null || _b === void 0 ? void 0 : _b.call(_a, e);
|
||||
});
|
||||
worker.on('detachedExit', function () { });
|
||||
}
|
||||
if (typeof beforeLoad === 'function') {
|
||||
beforeLoad(worker);
|
||||
}
|
||||
try {
|
||||
worker.postMessage(createMessage('load', {
|
||||
wasmModule: this.wasmModule,
|
||||
wasmMemory: this.wasmMemory,
|
||||
sab
|
||||
}));
|
||||
}
|
||||
catch (err) {
|
||||
checkSharedWasmMemory(this.wasmMemory);
|
||||
throw err;
|
||||
}
|
||||
});
|
||||
return worker.whenLoaded;
|
||||
}
|
||||
allocateUnusedWorker() {
|
||||
const _onCreateWorker = this._onCreateWorker;
|
||||
if (typeof _onCreateWorker !== 'function') {
|
||||
throw new TypeError('`options.onCreateWorker` is not provided');
|
||||
}
|
||||
const worker = _onCreateWorker({ type: 'thread', name: 'emnapi-pthread' });
|
||||
this.unusedWorkers.push(worker);
|
||||
return worker;
|
||||
}
|
||||
getNewWorker(sab) {
|
||||
if (this._reuseWorker) {
|
||||
if (this.unusedWorkers.length === 0) {
|
||||
if (this._reuseWorker.strict) {
|
||||
if (!ENVIRONMENT_IS_NODE) {
|
||||
const err = this.printErr;
|
||||
err('Tried to spawn a new thread, but the thread pool is exhausted.\n' +
|
||||
'This might result in a deadlock unless some threads eventually exit or the code explicitly breaks out to the event loop.');
|
||||
return;
|
||||
}
|
||||
}
|
||||
const worker = this.allocateUnusedWorker();
|
||||
this.loadWasmModuleToWorker(worker, sab);
|
||||
}
|
||||
return this.unusedWorkers.pop();
|
||||
}
|
||||
const worker = this.allocateUnusedWorker();
|
||||
this.loadWasmModuleToWorker(worker, sab);
|
||||
return this.unusedWorkers.pop();
|
||||
}
|
||||
cleanThread(worker, tid, force) {
|
||||
if (!force && this._reuseWorker) {
|
||||
this.returnWorkerToPool(worker);
|
||||
}
|
||||
else {
|
||||
delete this.pthreads[tid];
|
||||
const index = this.runningWorkers.indexOf(worker);
|
||||
if (index !== -1) {
|
||||
this.runningWorkers.splice(index, 1);
|
||||
}
|
||||
this.terminateWorker(worker);
|
||||
delete worker.__emnapi_tid;
|
||||
}
|
||||
}
|
||||
terminateWorker(worker) {
|
||||
var _a;
|
||||
const tid = worker.__emnapi_tid;
|
||||
worker.terminate();
|
||||
(_a = this.messageEvents.get(worker)) === null || _a === void 0 ? void 0 : _a.clear();
|
||||
this.messageEvents.delete(worker);
|
||||
worker.onmessage = (e) => {
|
||||
if (e.data.__emnapi__) {
|
||||
const err = this.printErr;
|
||||
err('received "' + e.data.__emnapi__.type + '" command from terminated worker: ' + tid);
|
||||
}
|
||||
};
|
||||
}
|
||||
terminateAllThreads() {
|
||||
for (let i = 0; i < this.runningWorkers.length; ++i) {
|
||||
this.terminateWorker(this.runningWorkers[i]);
|
||||
}
|
||||
for (let i = 0; i < this.unusedWorkers.length; ++i) {
|
||||
this.terminateWorker(this.unusedWorkers[i]);
|
||||
}
|
||||
this.unusedWorkers = [];
|
||||
this.runningWorkers = [];
|
||||
this.pthreads = Object.create(null);
|
||||
this.preparePool();
|
||||
}
|
||||
addMessageEventListener(worker, onMessage) {
|
||||
let listeners = this.messageEvents.get(worker);
|
||||
if (!listeners) {
|
||||
listeners = new Set();
|
||||
this.messageEvents.set(worker, listeners);
|
||||
}
|
||||
listeners.add(onMessage);
|
||||
return () => {
|
||||
listeners === null || listeners === void 0 ? void 0 : listeners.delete(onMessage);
|
||||
};
|
||||
}
|
||||
fireMessageEvent(worker, e) {
|
||||
const listeners = this.messageEvents.get(worker);
|
||||
if (!listeners)
|
||||
return;
|
||||
const err = this.printErr;
|
||||
listeners.forEach((listener) => {
|
||||
try {
|
||||
listener(e);
|
||||
}
|
||||
catch (e) {
|
||||
err(e.stack);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const kIsProxy = Symbol('kIsProxy');
|
||||
function createInstanceProxy(instance, memory) {
|
||||
if (instance[kIsProxy])
|
||||
return instance;
|
||||
const originalExports = instance.exports;
|
||||
const createHandler = function (target) {
|
||||
const handlers = [
|
||||
'apply',
|
||||
'construct',
|
||||
'defineProperty',
|
||||
'deleteProperty',
|
||||
'get',
|
||||
'getOwnPropertyDescriptor',
|
||||
'getPrototypeOf',
|
||||
'has',
|
||||
'isExtensible',
|
||||
'ownKeys',
|
||||
'preventExtensions',
|
||||
'set',
|
||||
'setPrototypeOf'
|
||||
];
|
||||
const handler = {};
|
||||
for (let i = 0; i < handlers.length; i++) {
|
||||
const name = handlers[i];
|
||||
handler[name] = function () {
|
||||
const args = Array.prototype.slice.call(arguments, 1);
|
||||
args.unshift(target);
|
||||
return Reflect[name].apply(Reflect, args);
|
||||
};
|
||||
}
|
||||
return handler;
|
||||
};
|
||||
const handler = createHandler(originalExports);
|
||||
const _initialize = () => { };
|
||||
const _start = () => 0;
|
||||
handler.get = function (_target, p, receiver) {
|
||||
var _a;
|
||||
if (p === 'memory') {
|
||||
return (_a = (typeof memory === 'function' ? memory() : memory)) !== null && _a !== void 0 ? _a : Reflect.get(originalExports, p, receiver);
|
||||
}
|
||||
if (p === '_initialize') {
|
||||
return p in originalExports ? _initialize : undefined;
|
||||
}
|
||||
if (p === '_start') {
|
||||
return p in originalExports ? _start : undefined;
|
||||
}
|
||||
return Reflect.get(originalExports, p, receiver);
|
||||
};
|
||||
handler.has = function (_target, p) {
|
||||
if (p === 'memory')
|
||||
return true;
|
||||
return Reflect.has(originalExports, p);
|
||||
};
|
||||
const exportsProxy = new Proxy(Object.create(null), handler);
|
||||
return new Proxy(instance, {
|
||||
get(target, p, receiver) {
|
||||
if (p === 'exports') {
|
||||
return exportsProxy;
|
||||
}
|
||||
if (p === kIsProxy) {
|
||||
return true;
|
||||
}
|
||||
return Reflect.get(target, p, receiver);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const patchedWasiInstances = new WeakMap();
|
||||
class WASIThreads {
|
||||
constructor(options) {
|
||||
if (!options) {
|
||||
throw new TypeError('WASIThreads(): options is not provided');
|
||||
}
|
||||
if (!options.wasi) {
|
||||
throw new TypeError('WASIThreads(): options.wasi is not provided');
|
||||
}
|
||||
patchedWasiInstances.set(this, new WeakSet());
|
||||
const wasi = options.wasi;
|
||||
patchWasiInstance(this, wasi);
|
||||
this.wasi = wasi;
|
||||
if ('childThread' in options) {
|
||||
this.childThread = Boolean(options.childThread);
|
||||
}
|
||||
else {
|
||||
this.childThread = false;
|
||||
}
|
||||
this.PThread = undefined;
|
||||
if ('threadManager' in options) {
|
||||
if (typeof options.threadManager === 'function') {
|
||||
this.PThread = options.threadManager();
|
||||
}
|
||||
else {
|
||||
this.PThread = options.threadManager;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!this.childThread) {
|
||||
this.PThread = new ThreadManager(options);
|
||||
this.PThread.init();
|
||||
}
|
||||
}
|
||||
let waitThreadStart = false;
|
||||
if ('waitThreadStart' in options) {
|
||||
waitThreadStart = typeof options.waitThreadStart === 'number' ? options.waitThreadStart : Boolean(options.waitThreadStart);
|
||||
}
|
||||
const postMessage = getPostMessage(options);
|
||||
if (this.childThread && typeof postMessage !== 'function') {
|
||||
throw new TypeError('options.postMessage is not a function');
|
||||
}
|
||||
this.postMessage = postMessage;
|
||||
const wasm64 = Boolean(options.wasm64);
|
||||
const threadSpawn = (startArg, errorOrTid) => {
|
||||
var _a;
|
||||
const EAGAIN = 6;
|
||||
const isNewABI = errorOrTid !== undefined;
|
||||
try {
|
||||
checkSharedWasmMemory(this.wasmMemory);
|
||||
}
|
||||
catch (err) {
|
||||
(_a = this.PThread) === null || _a === void 0 ? void 0 : _a.printErr(err.stack);
|
||||
if (isNewABI) {
|
||||
const struct = new Int32Array(this.wasmMemory.buffer, errorOrTid, 2);
|
||||
Atomics.store(struct, 0, 1);
|
||||
Atomics.store(struct, 1, EAGAIN);
|
||||
Atomics.notify(struct, 1);
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
return -EAGAIN;
|
||||
}
|
||||
}
|
||||
if (!isNewABI) {
|
||||
const malloc = this.wasmInstance.exports.malloc;
|
||||
errorOrTid = wasm64 ? Number(malloc(BigInt(8))) : (malloc(8) >>> 0);
|
||||
if (!errorOrTid) {
|
||||
return -48;
|
||||
}
|
||||
}
|
||||
const _free = this.wasmInstance.exports.free;
|
||||
const free = wasm64 ? (ptr) => { _free(BigInt(ptr)); } : _free;
|
||||
const struct = new Int32Array(this.wasmMemory.buffer, errorOrTid, 2);
|
||||
Atomics.store(struct, 0, 0);
|
||||
Atomics.store(struct, 1, 0);
|
||||
if (this.childThread) {
|
||||
postMessage(createMessage('spawn-thread', {
|
||||
startArg,
|
||||
errorOrTid: errorOrTid
|
||||
}));
|
||||
Atomics.wait(struct, 1, 0);
|
||||
const isError = Atomics.load(struct, 0);
|
||||
const result = Atomics.load(struct, 1);
|
||||
if (isNewABI) {
|
||||
return isError;
|
||||
}
|
||||
free(errorOrTid);
|
||||
return isError ? -result : result;
|
||||
}
|
||||
const shouldWait = waitThreadStart || (waitThreadStart === 0);
|
||||
let sab;
|
||||
if (shouldWait) {
|
||||
sab = new Int32Array(new SharedArrayBuffer(16 + 8192));
|
||||
Atomics.store(sab, 0, 0);
|
||||
}
|
||||
let worker;
|
||||
let tid;
|
||||
const PThread = this.PThread;
|
||||
try {
|
||||
worker = PThread.getNewWorker(sab);
|
||||
if (!worker) {
|
||||
throw new Error('failed to get new worker');
|
||||
}
|
||||
tid = PThread.markId(worker);
|
||||
if (ENVIRONMENT_IS_NODE) {
|
||||
worker.unref();
|
||||
}
|
||||
worker.postMessage(createMessage('start', {
|
||||
tid,
|
||||
arg: startArg,
|
||||
sab
|
||||
}));
|
||||
if (shouldWait) {
|
||||
if (typeof waitThreadStart === 'number') {
|
||||
const waitResult = Atomics.wait(sab, 0, 0, waitThreadStart);
|
||||
if (waitResult === 'timed-out') {
|
||||
try {
|
||||
PThread.cleanThread(worker, tid, true);
|
||||
}
|
||||
catch (_) { }
|
||||
throw new Error('Spawning thread timed out. Please check if the worker is created successfully and if message is handled properly in the worker.');
|
||||
}
|
||||
}
|
||||
else {
|
||||
Atomics.wait(sab, 0, 0);
|
||||
}
|
||||
const r = Atomics.load(sab, 0);
|
||||
if (r > 1) {
|
||||
try {
|
||||
PThread.cleanThread(worker, tid, true);
|
||||
}
|
||||
catch (_) { }
|
||||
throw deserizeErrorFromBuffer(sab.buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
Atomics.store(struct, 0, 1);
|
||||
Atomics.store(struct, 1, EAGAIN);
|
||||
Atomics.notify(struct, 1);
|
||||
PThread === null || PThread === void 0 ? void 0 : PThread.printErr(e.stack);
|
||||
if (isNewABI) {
|
||||
return 1;
|
||||
}
|
||||
free(errorOrTid);
|
||||
return -EAGAIN;
|
||||
}
|
||||
Atomics.store(struct, 0, 0);
|
||||
Atomics.store(struct, 1, tid);
|
||||
Atomics.notify(struct, 1);
|
||||
PThread.runningWorkers.push(worker);
|
||||
if (!shouldWait) {
|
||||
worker.whenLoaded.catch((err) => {
|
||||
delete worker.whenLoaded;
|
||||
PThread.cleanThread(worker, tid, true);
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
if (isNewABI) {
|
||||
return 0;
|
||||
}
|
||||
free(errorOrTid);
|
||||
return tid;
|
||||
};
|
||||
this.threadSpawn = threadSpawn;
|
||||
if (this.PThread) {
|
||||
this.PThread.threadSpawn = threadSpawn;
|
||||
}
|
||||
}
|
||||
getImportObject() {
|
||||
return {
|
||||
wasi: {
|
||||
'thread-spawn': this.threadSpawn
|
||||
}
|
||||
};
|
||||
}
|
||||
setup(wasmInstance, wasmModule, wasmMemory) {
|
||||
wasmMemory !== null && wasmMemory !== void 0 ? wasmMemory : (wasmMemory = wasmInstance.exports.memory);
|
||||
this.wasmInstance = wasmInstance;
|
||||
this.wasmMemory = wasmMemory;
|
||||
if (this.PThread) {
|
||||
this.PThread.setup(wasmModule, wasmMemory);
|
||||
}
|
||||
}
|
||||
preloadWorkers() {
|
||||
if (this.PThread) {
|
||||
return this.PThread.preloadWorkers();
|
||||
}
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
initialize(instance, module, memory) {
|
||||
const exports$1 = instance.exports;
|
||||
memory !== null && memory !== void 0 ? memory : (memory = exports$1.memory);
|
||||
if (this.childThread) {
|
||||
instance = createInstanceProxy(instance, memory);
|
||||
}
|
||||
this.setup(instance, module, memory);
|
||||
const wasi = this.wasi;
|
||||
if (('_start' in exports$1) && (typeof exports$1._start === 'function')) {
|
||||
if (this.childThread) {
|
||||
wasi.start(instance);
|
||||
try {
|
||||
const kStarted = getWasiSymbol(wasi, 'kStarted');
|
||||
wasi[kStarted] = false;
|
||||
}
|
||||
catch (_) { }
|
||||
}
|
||||
else {
|
||||
setupInstance(wasi, instance);
|
||||
}
|
||||
}
|
||||
else {
|
||||
wasi.initialize(instance);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
start(instance, module, memory) {
|
||||
const exports$1 = instance.exports;
|
||||
memory !== null && memory !== void 0 ? memory : (memory = exports$1.memory);
|
||||
if (this.childThread) {
|
||||
instance = createInstanceProxy(instance, memory);
|
||||
}
|
||||
this.setup(instance, module, memory);
|
||||
const exitCode = this.wasi.start(instance);
|
||||
return { exitCode, instance };
|
||||
}
|
||||
terminateAllThreads() {
|
||||
var _a;
|
||||
if (!this.childThread) {
|
||||
(_a = this.PThread) === null || _a === void 0 ? void 0 : _a.terminateAllThreads();
|
||||
}
|
||||
else {
|
||||
this.postMessage(createMessage('terminate-all-threads', {}));
|
||||
}
|
||||
}
|
||||
}
|
||||
function patchWasiInstance(wasiThreads, wasi) {
|
||||
const patched = patchedWasiInstances.get(wasiThreads);
|
||||
if (patched.has(wasi)) {
|
||||
return;
|
||||
}
|
||||
const _this = wasiThreads;
|
||||
const wasiImport = wasi.wasiImport;
|
||||
if (wasiImport) {
|
||||
const proc_exit = wasiImport.proc_exit;
|
||||
wasiImport.proc_exit = function (code) {
|
||||
_this.terminateAllThreads();
|
||||
return proc_exit.call(this, code);
|
||||
};
|
||||
}
|
||||
if (!_this.childThread) {
|
||||
const start = wasi.start;
|
||||
if (typeof start === 'function') {
|
||||
wasi.start = function (instance) {
|
||||
try {
|
||||
return start.call(this, instance);
|
||||
}
|
||||
catch (err) {
|
||||
if (isTrapError(err)) {
|
||||
_this.terminateAllThreads();
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
patched.add(wasi);
|
||||
}
|
||||
function getWasiSymbol(wasi, description) {
|
||||
const symbols = Object.getOwnPropertySymbols(wasi);
|
||||
const selectDescription = (description) => (s) => {
|
||||
if (s.description) {
|
||||
return s.description === description;
|
||||
}
|
||||
return s.toString() === `Symbol(${description})`;
|
||||
};
|
||||
if (Array.isArray(description)) {
|
||||
return description.map(d => symbols.filter(selectDescription(d))[0]);
|
||||
}
|
||||
return symbols.filter(selectDescription(description))[0];
|
||||
}
|
||||
function setupInstance(wasi, instance) {
|
||||
const [kInstance, kSetMemory] = getWasiSymbol(wasi, ['kInstance', 'kSetMemory']);
|
||||
wasi[kInstance] = instance;
|
||||
wasi[kSetMemory](instance.exports.memory);
|
||||
}
|
||||
|
||||
class ThreadMessageHandler {
|
||||
constructor(options) {
|
||||
const postMsg = getPostMessage(options);
|
||||
if (typeof postMsg !== 'function') {
|
||||
throw new TypeError('options.postMessage is not a function');
|
||||
}
|
||||
this.postMessage = postMsg;
|
||||
this.onLoad = options === null || options === void 0 ? void 0 : options.onLoad;
|
||||
this.onError = typeof (options === null || options === void 0 ? void 0 : options.onError) === 'function' ? options.onError : (_type, err) => { throw err; };
|
||||
this.instance = undefined;
|
||||
this.messagesBeforeLoad = [];
|
||||
}
|
||||
instantiate(data) {
|
||||
if (typeof this.onLoad === 'function') {
|
||||
return this.onLoad(data);
|
||||
}
|
||||
throw new Error('ThreadMessageHandler.prototype.instantiate is not implemented');
|
||||
}
|
||||
handle(e) {
|
||||
var _a;
|
||||
if ((_a = e === null || e === void 0 ? void 0 : e.data) === null || _a === void 0 ? void 0 : _a.__emnapi__) {
|
||||
const type = e.data.__emnapi__.type;
|
||||
const payload = e.data.__emnapi__.payload;
|
||||
try {
|
||||
if (type === 'load') {
|
||||
this._load(payload);
|
||||
}
|
||||
else if (type === 'start') {
|
||||
this.handleAfterLoad(e, () => {
|
||||
this._start(payload);
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
this.onError(err, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
_load(payload) {
|
||||
if (this.instance !== undefined)
|
||||
return;
|
||||
let source;
|
||||
try {
|
||||
source = this.instantiate(payload);
|
||||
}
|
||||
catch (err) {
|
||||
this._loaded(err, null, payload);
|
||||
return;
|
||||
}
|
||||
const then = source && 'then' in source ? source.then : undefined;
|
||||
if (typeof then === 'function') {
|
||||
then.call(source, (source) => { this._loaded(null, source, payload); }, (err) => { this._loaded(err, null, payload); });
|
||||
}
|
||||
else {
|
||||
this._loaded(null, source, payload);
|
||||
}
|
||||
}
|
||||
_start(payload) {
|
||||
const wasi_thread_start = this.instance.exports.wasi_thread_start;
|
||||
if (typeof wasi_thread_start !== 'function') {
|
||||
const err = new TypeError('wasi_thread_start is not exported');
|
||||
notifyPthreadCreateResult(payload.sab, 2, err);
|
||||
throw err;
|
||||
}
|
||||
const postMessage = this.postMessage;
|
||||
const tid = payload.tid;
|
||||
const startArg = payload.arg;
|
||||
notifyPthreadCreateResult(payload.sab, 1);
|
||||
try {
|
||||
wasi_thread_start(tid, startArg);
|
||||
}
|
||||
catch (err) {
|
||||
if (err !== 'unwind') {
|
||||
throw err;
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
postMessage(createMessage('cleanup-thread', { tid }));
|
||||
}
|
||||
_loaded(err, source, payload) {
|
||||
if (err) {
|
||||
notifyPthreadCreateResult(payload.sab, 2, err);
|
||||
throw err;
|
||||
}
|
||||
if (source == null) {
|
||||
const err = new TypeError('onLoad should return an object');
|
||||
notifyPthreadCreateResult(payload.sab, 2, err);
|
||||
throw err;
|
||||
}
|
||||
const instance = source.instance;
|
||||
if (!instance) {
|
||||
const err = new TypeError('onLoad should return an object which includes "instance"');
|
||||
notifyPthreadCreateResult(payload.sab, 2, err);
|
||||
throw err;
|
||||
}
|
||||
this.instance = instance;
|
||||
const postMessage = this.postMessage;
|
||||
postMessage(createMessage('loaded', {}));
|
||||
const messages = this.messagesBeforeLoad;
|
||||
this.messagesBeforeLoad = [];
|
||||
for (let i = 0; i < messages.length; i++) {
|
||||
const data = messages[i];
|
||||
this.handle({ data });
|
||||
}
|
||||
}
|
||||
handleAfterLoad(e, f) {
|
||||
if (this.instance !== undefined) {
|
||||
f.call(this, e);
|
||||
}
|
||||
else {
|
||||
this.messagesBeforeLoad.push(e.data);
|
||||
}
|
||||
}
|
||||
}
|
||||
function notifyPthreadCreateResult(sab, result, error) {
|
||||
if (sab) {
|
||||
serizeErrorToBuffer(sab.buffer, result, error);
|
||||
Atomics.notify(sab, 0);
|
||||
}
|
||||
}
|
||||
|
||||
export { ThreadManager, ThreadMessageHandler, WASIThreads, createInstanceProxy, isSharedArrayBuffer, isTrapError };
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
if (typeof process !== 'undefined' && process.env.NODE_ENV === 'production') {
|
||||
module.exports = require('./dist/wasi-threads.cjs.min.js')
|
||||
} else {
|
||||
module.exports = require('./dist/wasi-threads.cjs.js')
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"name": "@emnapi/wasi-threads",
|
||||
"version": "1.2.1",
|
||||
"description": "WASI threads proposal implementation in JavaScript",
|
||||
"main": "index.js",
|
||||
"module": "./dist/wasi-threads.esm-bundler.js",
|
||||
"types": "./dist/wasi-threads.d.ts",
|
||||
"sideEffects": false,
|
||||
"exports": {
|
||||
".": {
|
||||
"types": {
|
||||
"module": "./dist/wasi-threads.d.ts",
|
||||
"import": "./dist/wasi-threads.d.mts",
|
||||
"default": "./dist/wasi-threads.d.ts"
|
||||
},
|
||||
"module": "./dist/wasi-threads.esm-bundler.js",
|
||||
"import": "./dist/wasi-threads.mjs",
|
||||
"default": "./index.js"
|
||||
},
|
||||
"./dist/wasi-threads.cjs.min": {
|
||||
"types": "./dist/wasi-threads.d.ts",
|
||||
"default": "./dist/wasi-threads.cjs.min.js"
|
||||
},
|
||||
"./dist/wasi-threads.min.mjs": {
|
||||
"types": "./dist/wasi-threads.d.mts",
|
||||
"default": "./dist/wasi-threads.min.mjs"
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "node ./script/build.js",
|
||||
"build:test": "node ./test/build.js",
|
||||
"test": "node ./test/index.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/toyobayashi/emnapi.git"
|
||||
},
|
||||
"author": "toyobayashi",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/toyobayashi/emnapi/issues"
|
||||
},
|
||||
"homepage": "https://github.com/toyobayashi/emnapi#readme",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
Copyright 2024 Justin Ridgewell <justin@ridgewell.name>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
+227
@@ -0,0 +1,227 @@
|
||||
# @jridgewell/gen-mapping
|
||||
|
||||
> Generate source maps
|
||||
|
||||
`gen-mapping` allows you to generate a source map during transpilation or minification.
|
||||
With a source map, you're able to trace the original location in the source file, either in Chrome's
|
||||
DevTools or using a library like [`@jridgewell/trace-mapping`][trace-mapping].
|
||||
|
||||
You may already be familiar with the [`source-map`][source-map] package's `SourceMapGenerator`. This
|
||||
provides the same `addMapping` and `setSourceContent` API.
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
npm install @jridgewell/gen-mapping
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```typescript
|
||||
import { GenMapping, addMapping, setSourceContent, toEncodedMap, toDecodedMap } from '@jridgewell/gen-mapping';
|
||||
|
||||
const map = new GenMapping({
|
||||
file: 'output.js',
|
||||
sourceRoot: 'https://example.com/',
|
||||
});
|
||||
|
||||
setSourceContent(map, 'input.js', `function foo() {}`);
|
||||
|
||||
addMapping(map, {
|
||||
// Lines start at line 1, columns at column 0.
|
||||
generated: { line: 1, column: 0 },
|
||||
source: 'input.js',
|
||||
original: { line: 1, column: 0 },
|
||||
});
|
||||
|
||||
addMapping(map, {
|
||||
generated: { line: 1, column: 9 },
|
||||
source: 'input.js',
|
||||
original: { line: 1, column: 9 },
|
||||
name: 'foo',
|
||||
});
|
||||
|
||||
assert.deepEqual(toDecodedMap(map), {
|
||||
version: 3,
|
||||
file: 'output.js',
|
||||
names: ['foo'],
|
||||
sourceRoot: 'https://example.com/',
|
||||
sources: ['input.js'],
|
||||
sourcesContent: ['function foo() {}'],
|
||||
mappings: [
|
||||
[ [0, 0, 0, 0], [9, 0, 0, 9, 0] ]
|
||||
],
|
||||
});
|
||||
|
||||
assert.deepEqual(toEncodedMap(map), {
|
||||
version: 3,
|
||||
file: 'output.js',
|
||||
names: ['foo'],
|
||||
sourceRoot: 'https://example.com/',
|
||||
sources: ['input.js'],
|
||||
sourcesContent: ['function foo() {}'],
|
||||
mappings: 'AAAA,SAASA',
|
||||
});
|
||||
```
|
||||
|
||||
### Smaller Sourcemaps
|
||||
|
||||
Not everything needs to be added to a sourcemap, and needless markings can cause signficantly
|
||||
larger file sizes. `gen-mapping` exposes `maybeAddSegment`/`maybeAddMapping` APIs that will
|
||||
intelligently determine if this marking adds useful information. If not, the marking will be
|
||||
skipped.
|
||||
|
||||
```typescript
|
||||
import { maybeAddMapping } from '@jridgewell/gen-mapping';
|
||||
|
||||
const map = new GenMapping();
|
||||
|
||||
// Adding a sourceless marking at the beginning of a line isn't useful.
|
||||
maybeAddMapping(map, {
|
||||
generated: { line: 1, column: 0 },
|
||||
});
|
||||
|
||||
// Adding a new source marking is useful.
|
||||
maybeAddMapping(map, {
|
||||
generated: { line: 1, column: 0 },
|
||||
source: 'input.js',
|
||||
original: { line: 1, column: 0 },
|
||||
});
|
||||
|
||||
// But adding another marking pointing to the exact same original location isn't, even if the
|
||||
// generated column changed.
|
||||
maybeAddMapping(map, {
|
||||
generated: { line: 1, column: 9 },
|
||||
source: 'input.js',
|
||||
original: { line: 1, column: 0 },
|
||||
});
|
||||
|
||||
assert.deepEqual(toEncodedMap(map), {
|
||||
version: 3,
|
||||
names: [],
|
||||
sources: ['input.js'],
|
||||
sourcesContent: [null],
|
||||
mappings: 'AAAA',
|
||||
});
|
||||
```
|
||||
|
||||
## Benchmarks
|
||||
|
||||
```
|
||||
node v18.0.0
|
||||
|
||||
amp.js.map
|
||||
Memory Usage:
|
||||
gen-mapping: addSegment 5852872 bytes
|
||||
gen-mapping: addMapping 7716042 bytes
|
||||
source-map-js 6143250 bytes
|
||||
source-map-0.6.1 6124102 bytes
|
||||
source-map-0.8.0 6121173 bytes
|
||||
Smallest memory usage is gen-mapping: addSegment
|
||||
|
||||
Adding speed:
|
||||
gen-mapping: addSegment x 441 ops/sec ±2.07% (90 runs sampled)
|
||||
gen-mapping: addMapping x 350 ops/sec ±2.40% (86 runs sampled)
|
||||
source-map-js: addMapping x 169 ops/sec ±2.42% (80 runs sampled)
|
||||
source-map-0.6.1: addMapping x 167 ops/sec ±2.56% (80 runs sampled)
|
||||
source-map-0.8.0: addMapping x 168 ops/sec ±2.52% (80 runs sampled)
|
||||
Fastest is gen-mapping: addSegment
|
||||
|
||||
Generate speed:
|
||||
gen-mapping: decoded output x 150,824,370 ops/sec ±0.07% (102 runs sampled)
|
||||
gen-mapping: encoded output x 663 ops/sec ±0.22% (98 runs sampled)
|
||||
source-map-js: encoded output x 197 ops/sec ±0.45% (84 runs sampled)
|
||||
source-map-0.6.1: encoded output x 198 ops/sec ±0.33% (85 runs sampled)
|
||||
source-map-0.8.0: encoded output x 197 ops/sec ±0.06% (93 runs sampled)
|
||||
Fastest is gen-mapping: decoded output
|
||||
|
||||
|
||||
***
|
||||
|
||||
|
||||
babel.min.js.map
|
||||
Memory Usage:
|
||||
gen-mapping: addSegment 37578063 bytes
|
||||
gen-mapping: addMapping 37212897 bytes
|
||||
source-map-js 47638527 bytes
|
||||
source-map-0.6.1 47690503 bytes
|
||||
source-map-0.8.0 47470188 bytes
|
||||
Smallest memory usage is gen-mapping: addMapping
|
||||
|
||||
Adding speed:
|
||||
gen-mapping: addSegment x 31.05 ops/sec ±8.31% (43 runs sampled)
|
||||
gen-mapping: addMapping x 29.83 ops/sec ±7.36% (51 runs sampled)
|
||||
source-map-js: addMapping x 20.73 ops/sec ±6.22% (38 runs sampled)
|
||||
source-map-0.6.1: addMapping x 20.03 ops/sec ±10.51% (38 runs sampled)
|
||||
source-map-0.8.0: addMapping x 19.30 ops/sec ±8.27% (37 runs sampled)
|
||||
Fastest is gen-mapping: addSegment
|
||||
|
||||
Generate speed:
|
||||
gen-mapping: decoded output x 381,379,234 ops/sec ±0.29% (96 runs sampled)
|
||||
gen-mapping: encoded output x 95.15 ops/sec ±2.98% (72 runs sampled)
|
||||
source-map-js: encoded output x 15.20 ops/sec ±7.41% (33 runs sampled)
|
||||
source-map-0.6.1: encoded output x 16.36 ops/sec ±10.46% (31 runs sampled)
|
||||
source-map-0.8.0: encoded output x 16.06 ops/sec ±6.45% (31 runs sampled)
|
||||
Fastest is gen-mapping: decoded output
|
||||
|
||||
|
||||
***
|
||||
|
||||
|
||||
preact.js.map
|
||||
Memory Usage:
|
||||
gen-mapping: addSegment 416247 bytes
|
||||
gen-mapping: addMapping 419824 bytes
|
||||
source-map-js 1024619 bytes
|
||||
source-map-0.6.1 1146004 bytes
|
||||
source-map-0.8.0 1113250 bytes
|
||||
Smallest memory usage is gen-mapping: addSegment
|
||||
|
||||
Adding speed:
|
||||
gen-mapping: addSegment x 13,755 ops/sec ±0.15% (98 runs sampled)
|
||||
gen-mapping: addMapping x 13,013 ops/sec ±0.11% (101 runs sampled)
|
||||
source-map-js: addMapping x 4,564 ops/sec ±0.21% (98 runs sampled)
|
||||
source-map-0.6.1: addMapping x 4,562 ops/sec ±0.11% (99 runs sampled)
|
||||
source-map-0.8.0: addMapping x 4,593 ops/sec ±0.11% (100 runs sampled)
|
||||
Fastest is gen-mapping: addSegment
|
||||
|
||||
Generate speed:
|
||||
gen-mapping: decoded output x 379,864,020 ops/sec ±0.23% (93 runs sampled)
|
||||
gen-mapping: encoded output x 14,368 ops/sec ±4.07% (82 runs sampled)
|
||||
source-map-js: encoded output x 5,261 ops/sec ±0.21% (99 runs sampled)
|
||||
source-map-0.6.1: encoded output x 5,124 ops/sec ±0.58% (99 runs sampled)
|
||||
source-map-0.8.0: encoded output x 5,434 ops/sec ±0.33% (96 runs sampled)
|
||||
Fastest is gen-mapping: decoded output
|
||||
|
||||
|
||||
***
|
||||
|
||||
|
||||
react.js.map
|
||||
Memory Usage:
|
||||
gen-mapping: addSegment 975096 bytes
|
||||
gen-mapping: addMapping 1102981 bytes
|
||||
source-map-js 2918836 bytes
|
||||
source-map-0.6.1 2885435 bytes
|
||||
source-map-0.8.0 2874336 bytes
|
||||
Smallest memory usage is gen-mapping: addSegment
|
||||
|
||||
Adding speed:
|
||||
gen-mapping: addSegment x 4,772 ops/sec ±0.15% (100 runs sampled)
|
||||
gen-mapping: addMapping x 4,456 ops/sec ±0.13% (97 runs sampled)
|
||||
source-map-js: addMapping x 1,618 ops/sec ±0.24% (97 runs sampled)
|
||||
source-map-0.6.1: addMapping x 1,622 ops/sec ±0.12% (99 runs sampled)
|
||||
source-map-0.8.0: addMapping x 1,631 ops/sec ±0.12% (100 runs sampled)
|
||||
Fastest is gen-mapping: addSegment
|
||||
|
||||
Generate speed:
|
||||
gen-mapping: decoded output x 379,107,695 ops/sec ±0.07% (99 runs sampled)
|
||||
gen-mapping: encoded output x 5,421 ops/sec ±1.60% (89 runs sampled)
|
||||
source-map-js: encoded output x 2,113 ops/sec ±1.81% (98 runs sampled)
|
||||
source-map-0.6.1: encoded output x 2,126 ops/sec ±0.10% (100 runs sampled)
|
||||
source-map-0.8.0: encoded output x 2,176 ops/sec ±0.39% (98 runs sampled)
|
||||
Fastest is gen-mapping: decoded output
|
||||
```
|
||||
|
||||
[source-map]: https://www.npmjs.com/package/source-map
|
||||
[trace-mapping]: https://github.com/jridgewell/sourcemaps/tree/main/packages/trace-mapping
|
||||
+292
@@ -0,0 +1,292 @@
|
||||
// src/set-array.ts
|
||||
var SetArray = class {
|
||||
constructor() {
|
||||
this._indexes = { __proto__: null };
|
||||
this.array = [];
|
||||
}
|
||||
};
|
||||
function cast(set) {
|
||||
return set;
|
||||
}
|
||||
function get(setarr, key) {
|
||||
return cast(setarr)._indexes[key];
|
||||
}
|
||||
function put(setarr, key) {
|
||||
const index = get(setarr, key);
|
||||
if (index !== void 0) return index;
|
||||
const { array, _indexes: indexes } = cast(setarr);
|
||||
const length = array.push(key);
|
||||
return indexes[key] = length - 1;
|
||||
}
|
||||
function remove(setarr, key) {
|
||||
const index = get(setarr, key);
|
||||
if (index === void 0) return;
|
||||
const { array, _indexes: indexes } = cast(setarr);
|
||||
for (let i = index + 1; i < array.length; i++) {
|
||||
const k = array[i];
|
||||
array[i - 1] = k;
|
||||
indexes[k]--;
|
||||
}
|
||||
indexes[key] = void 0;
|
||||
array.pop();
|
||||
}
|
||||
|
||||
// src/gen-mapping.ts
|
||||
import {
|
||||
encode
|
||||
} from "@jridgewell/sourcemap-codec";
|
||||
import { TraceMap, decodedMappings } from "@jridgewell/trace-mapping";
|
||||
|
||||
// src/sourcemap-segment.ts
|
||||
var COLUMN = 0;
|
||||
var SOURCES_INDEX = 1;
|
||||
var SOURCE_LINE = 2;
|
||||
var SOURCE_COLUMN = 3;
|
||||
var NAMES_INDEX = 4;
|
||||
|
||||
// src/gen-mapping.ts
|
||||
var NO_NAME = -1;
|
||||
var GenMapping = class {
|
||||
constructor({ file, sourceRoot } = {}) {
|
||||
this._names = new SetArray();
|
||||
this._sources = new SetArray();
|
||||
this._sourcesContent = [];
|
||||
this._mappings = [];
|
||||
this.file = file;
|
||||
this.sourceRoot = sourceRoot;
|
||||
this._ignoreList = new SetArray();
|
||||
}
|
||||
};
|
||||
function cast2(map) {
|
||||
return map;
|
||||
}
|
||||
function addSegment(map, genLine, genColumn, source, sourceLine, sourceColumn, name, content) {
|
||||
return addSegmentInternal(
|
||||
false,
|
||||
map,
|
||||
genLine,
|
||||
genColumn,
|
||||
source,
|
||||
sourceLine,
|
||||
sourceColumn,
|
||||
name,
|
||||
content
|
||||
);
|
||||
}
|
||||
function addMapping(map, mapping) {
|
||||
return addMappingInternal(false, map, mapping);
|
||||
}
|
||||
var maybeAddSegment = (map, genLine, genColumn, source, sourceLine, sourceColumn, name, content) => {
|
||||
return addSegmentInternal(
|
||||
true,
|
||||
map,
|
||||
genLine,
|
||||
genColumn,
|
||||
source,
|
||||
sourceLine,
|
||||
sourceColumn,
|
||||
name,
|
||||
content
|
||||
);
|
||||
};
|
||||
var maybeAddMapping = (map, mapping) => {
|
||||
return addMappingInternal(true, map, mapping);
|
||||
};
|
||||
function setSourceContent(map, source, content) {
|
||||
const {
|
||||
_sources: sources,
|
||||
_sourcesContent: sourcesContent
|
||||
// _originalScopes: originalScopes,
|
||||
} = cast2(map);
|
||||
const index = put(sources, source);
|
||||
sourcesContent[index] = content;
|
||||
}
|
||||
function setIgnore(map, source, ignore = true) {
|
||||
const {
|
||||
_sources: sources,
|
||||
_sourcesContent: sourcesContent,
|
||||
_ignoreList: ignoreList
|
||||
// _originalScopes: originalScopes,
|
||||
} = cast2(map);
|
||||
const index = put(sources, source);
|
||||
if (index === sourcesContent.length) sourcesContent[index] = null;
|
||||
if (ignore) put(ignoreList, index);
|
||||
else remove(ignoreList, index);
|
||||
}
|
||||
function toDecodedMap(map) {
|
||||
const {
|
||||
_mappings: mappings,
|
||||
_sources: sources,
|
||||
_sourcesContent: sourcesContent,
|
||||
_names: names,
|
||||
_ignoreList: ignoreList
|
||||
// _originalScopes: originalScopes,
|
||||
// _generatedRanges: generatedRanges,
|
||||
} = cast2(map);
|
||||
removeEmptyFinalLines(mappings);
|
||||
return {
|
||||
version: 3,
|
||||
file: map.file || void 0,
|
||||
names: names.array,
|
||||
sourceRoot: map.sourceRoot || void 0,
|
||||
sources: sources.array,
|
||||
sourcesContent,
|
||||
mappings,
|
||||
// originalScopes,
|
||||
// generatedRanges,
|
||||
ignoreList: ignoreList.array
|
||||
};
|
||||
}
|
||||
function toEncodedMap(map) {
|
||||
const decoded = toDecodedMap(map);
|
||||
return Object.assign({}, decoded, {
|
||||
// originalScopes: decoded.originalScopes.map((os) => encodeOriginalScopes(os)),
|
||||
// generatedRanges: encodeGeneratedRanges(decoded.generatedRanges as GeneratedRange[]),
|
||||
mappings: encode(decoded.mappings)
|
||||
});
|
||||
}
|
||||
function fromMap(input) {
|
||||
const map = new TraceMap(input);
|
||||
const gen = new GenMapping({ file: map.file, sourceRoot: map.sourceRoot });
|
||||
putAll(cast2(gen)._names, map.names);
|
||||
putAll(cast2(gen)._sources, map.sources);
|
||||
cast2(gen)._sourcesContent = map.sourcesContent || map.sources.map(() => null);
|
||||
cast2(gen)._mappings = decodedMappings(map);
|
||||
if (map.ignoreList) putAll(cast2(gen)._ignoreList, map.ignoreList);
|
||||
return gen;
|
||||
}
|
||||
function allMappings(map) {
|
||||
const out = [];
|
||||
const { _mappings: mappings, _sources: sources, _names: names } = cast2(map);
|
||||
for (let i = 0; i < mappings.length; i++) {
|
||||
const line = mappings[i];
|
||||
for (let j = 0; j < line.length; j++) {
|
||||
const seg = line[j];
|
||||
const generated = { line: i + 1, column: seg[COLUMN] };
|
||||
let source = void 0;
|
||||
let original = void 0;
|
||||
let name = void 0;
|
||||
if (seg.length !== 1) {
|
||||
source = sources.array[seg[SOURCES_INDEX]];
|
||||
original = { line: seg[SOURCE_LINE] + 1, column: seg[SOURCE_COLUMN] };
|
||||
if (seg.length === 5) name = names.array[seg[NAMES_INDEX]];
|
||||
}
|
||||
out.push({ generated, source, original, name });
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
function addSegmentInternal(skipable, map, genLine, genColumn, source, sourceLine, sourceColumn, name, content) {
|
||||
const {
|
||||
_mappings: mappings,
|
||||
_sources: sources,
|
||||
_sourcesContent: sourcesContent,
|
||||
_names: names
|
||||
// _originalScopes: originalScopes,
|
||||
} = cast2(map);
|
||||
const line = getIndex(mappings, genLine);
|
||||
const index = getColumnIndex(line, genColumn);
|
||||
if (!source) {
|
||||
if (skipable && skipSourceless(line, index)) return;
|
||||
return insert(line, index, [genColumn]);
|
||||
}
|
||||
assert(sourceLine);
|
||||
assert(sourceColumn);
|
||||
const sourcesIndex = put(sources, source);
|
||||
const namesIndex = name ? put(names, name) : NO_NAME;
|
||||
if (sourcesIndex === sourcesContent.length) sourcesContent[sourcesIndex] = content != null ? content : null;
|
||||
if (skipable && skipSource(line, index, sourcesIndex, sourceLine, sourceColumn, namesIndex)) {
|
||||
return;
|
||||
}
|
||||
return insert(
|
||||
line,
|
||||
index,
|
||||
name ? [genColumn, sourcesIndex, sourceLine, sourceColumn, namesIndex] : [genColumn, sourcesIndex, sourceLine, sourceColumn]
|
||||
);
|
||||
}
|
||||
function assert(_val) {
|
||||
}
|
||||
function getIndex(arr, index) {
|
||||
for (let i = arr.length; i <= index; i++) {
|
||||
arr[i] = [];
|
||||
}
|
||||
return arr[index];
|
||||
}
|
||||
function getColumnIndex(line, genColumn) {
|
||||
let index = line.length;
|
||||
for (let i = index - 1; i >= 0; index = i--) {
|
||||
const current = line[i];
|
||||
if (genColumn >= current[COLUMN]) break;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
function insert(array, index, value) {
|
||||
for (let i = array.length; i > index; i--) {
|
||||
array[i] = array[i - 1];
|
||||
}
|
||||
array[index] = value;
|
||||
}
|
||||
function removeEmptyFinalLines(mappings) {
|
||||
const { length } = mappings;
|
||||
let len = length;
|
||||
for (let i = len - 1; i >= 0; len = i, i--) {
|
||||
if (mappings[i].length > 0) break;
|
||||
}
|
||||
if (len < length) mappings.length = len;
|
||||
}
|
||||
function putAll(setarr, array) {
|
||||
for (let i = 0; i < array.length; i++) put(setarr, array[i]);
|
||||
}
|
||||
function skipSourceless(line, index) {
|
||||
if (index === 0) return true;
|
||||
const prev = line[index - 1];
|
||||
return prev.length === 1;
|
||||
}
|
||||
function skipSource(line, index, sourcesIndex, sourceLine, sourceColumn, namesIndex) {
|
||||
if (index === 0) return false;
|
||||
const prev = line[index - 1];
|
||||
if (prev.length === 1) return false;
|
||||
return sourcesIndex === prev[SOURCES_INDEX] && sourceLine === prev[SOURCE_LINE] && sourceColumn === prev[SOURCE_COLUMN] && namesIndex === (prev.length === 5 ? prev[NAMES_INDEX] : NO_NAME);
|
||||
}
|
||||
function addMappingInternal(skipable, map, mapping) {
|
||||
const { generated, source, original, name, content } = mapping;
|
||||
if (!source) {
|
||||
return addSegmentInternal(
|
||||
skipable,
|
||||
map,
|
||||
generated.line - 1,
|
||||
generated.column,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
);
|
||||
}
|
||||
assert(original);
|
||||
return addSegmentInternal(
|
||||
skipable,
|
||||
map,
|
||||
generated.line - 1,
|
||||
generated.column,
|
||||
source,
|
||||
original.line - 1,
|
||||
original.column,
|
||||
name,
|
||||
content
|
||||
);
|
||||
}
|
||||
export {
|
||||
GenMapping,
|
||||
addMapping,
|
||||
addSegment,
|
||||
allMappings,
|
||||
fromMap,
|
||||
maybeAddMapping,
|
||||
maybeAddSegment,
|
||||
setIgnore,
|
||||
setSourceContent,
|
||||
toDecodedMap,
|
||||
toEncodedMap
|
||||
};
|
||||
//# sourceMappingURL=gen-mapping.mjs.map
|
||||
+6
File diff suppressed because one or more lines are too long
+358
@@ -0,0 +1,358 @@
|
||||
(function (global, factory) {
|
||||
if (typeof exports === 'object' && typeof module !== 'undefined') {
|
||||
factory(module, require('@jridgewell/sourcemap-codec'), require('@jridgewell/trace-mapping'));
|
||||
module.exports = def(module);
|
||||
} else if (typeof define === 'function' && define.amd) {
|
||||
define(['module', '@jridgewell/sourcemap-codec', '@jridgewell/trace-mapping'], function(mod) {
|
||||
factory.apply(this, arguments);
|
||||
mod.exports = def(mod);
|
||||
});
|
||||
} else {
|
||||
const mod = { exports: {} };
|
||||
factory(mod, global.sourcemapCodec, global.traceMapping);
|
||||
global = typeof globalThis !== 'undefined' ? globalThis : global || self;
|
||||
global.genMapping = def(mod);
|
||||
}
|
||||
function def(m) { return 'default' in m.exports ? m.exports.default : m.exports; }
|
||||
})(this, (function (module, require_sourcemapCodec, require_traceMapping) {
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __commonJS = (cb, mod) => function __require() {
|
||||
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
||||
};
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// umd:@jridgewell/sourcemap-codec
|
||||
var require_sourcemap_codec = __commonJS({
|
||||
"umd:@jridgewell/sourcemap-codec"(exports, module2) {
|
||||
module2.exports = require_sourcemapCodec;
|
||||
}
|
||||
});
|
||||
|
||||
// umd:@jridgewell/trace-mapping
|
||||
var require_trace_mapping = __commonJS({
|
||||
"umd:@jridgewell/trace-mapping"(exports, module2) {
|
||||
module2.exports = require_traceMapping;
|
||||
}
|
||||
});
|
||||
|
||||
// src/gen-mapping.ts
|
||||
var gen_mapping_exports = {};
|
||||
__export(gen_mapping_exports, {
|
||||
GenMapping: () => GenMapping,
|
||||
addMapping: () => addMapping,
|
||||
addSegment: () => addSegment,
|
||||
allMappings: () => allMappings,
|
||||
fromMap: () => fromMap,
|
||||
maybeAddMapping: () => maybeAddMapping,
|
||||
maybeAddSegment: () => maybeAddSegment,
|
||||
setIgnore: () => setIgnore,
|
||||
setSourceContent: () => setSourceContent,
|
||||
toDecodedMap: () => toDecodedMap,
|
||||
toEncodedMap: () => toEncodedMap
|
||||
});
|
||||
module.exports = __toCommonJS(gen_mapping_exports);
|
||||
|
||||
// src/set-array.ts
|
||||
var SetArray = class {
|
||||
constructor() {
|
||||
this._indexes = { __proto__: null };
|
||||
this.array = [];
|
||||
}
|
||||
};
|
||||
function cast(set) {
|
||||
return set;
|
||||
}
|
||||
function get(setarr, key) {
|
||||
return cast(setarr)._indexes[key];
|
||||
}
|
||||
function put(setarr, key) {
|
||||
const index = get(setarr, key);
|
||||
if (index !== void 0) return index;
|
||||
const { array, _indexes: indexes } = cast(setarr);
|
||||
const length = array.push(key);
|
||||
return indexes[key] = length - 1;
|
||||
}
|
||||
function remove(setarr, key) {
|
||||
const index = get(setarr, key);
|
||||
if (index === void 0) return;
|
||||
const { array, _indexes: indexes } = cast(setarr);
|
||||
for (let i = index + 1; i < array.length; i++) {
|
||||
const k = array[i];
|
||||
array[i - 1] = k;
|
||||
indexes[k]--;
|
||||
}
|
||||
indexes[key] = void 0;
|
||||
array.pop();
|
||||
}
|
||||
|
||||
// src/gen-mapping.ts
|
||||
var import_sourcemap_codec = __toESM(require_sourcemap_codec());
|
||||
var import_trace_mapping = __toESM(require_trace_mapping());
|
||||
|
||||
// src/sourcemap-segment.ts
|
||||
var COLUMN = 0;
|
||||
var SOURCES_INDEX = 1;
|
||||
var SOURCE_LINE = 2;
|
||||
var SOURCE_COLUMN = 3;
|
||||
var NAMES_INDEX = 4;
|
||||
|
||||
// src/gen-mapping.ts
|
||||
var NO_NAME = -1;
|
||||
var GenMapping = class {
|
||||
constructor({ file, sourceRoot } = {}) {
|
||||
this._names = new SetArray();
|
||||
this._sources = new SetArray();
|
||||
this._sourcesContent = [];
|
||||
this._mappings = [];
|
||||
this.file = file;
|
||||
this.sourceRoot = sourceRoot;
|
||||
this._ignoreList = new SetArray();
|
||||
}
|
||||
};
|
||||
function cast2(map) {
|
||||
return map;
|
||||
}
|
||||
function addSegment(map, genLine, genColumn, source, sourceLine, sourceColumn, name, content) {
|
||||
return addSegmentInternal(
|
||||
false,
|
||||
map,
|
||||
genLine,
|
||||
genColumn,
|
||||
source,
|
||||
sourceLine,
|
||||
sourceColumn,
|
||||
name,
|
||||
content
|
||||
);
|
||||
}
|
||||
function addMapping(map, mapping) {
|
||||
return addMappingInternal(false, map, mapping);
|
||||
}
|
||||
var maybeAddSegment = (map, genLine, genColumn, source, sourceLine, sourceColumn, name, content) => {
|
||||
return addSegmentInternal(
|
||||
true,
|
||||
map,
|
||||
genLine,
|
||||
genColumn,
|
||||
source,
|
||||
sourceLine,
|
||||
sourceColumn,
|
||||
name,
|
||||
content
|
||||
);
|
||||
};
|
||||
var maybeAddMapping = (map, mapping) => {
|
||||
return addMappingInternal(true, map, mapping);
|
||||
};
|
||||
function setSourceContent(map, source, content) {
|
||||
const {
|
||||
_sources: sources,
|
||||
_sourcesContent: sourcesContent
|
||||
// _originalScopes: originalScopes,
|
||||
} = cast2(map);
|
||||
const index = put(sources, source);
|
||||
sourcesContent[index] = content;
|
||||
}
|
||||
function setIgnore(map, source, ignore = true) {
|
||||
const {
|
||||
_sources: sources,
|
||||
_sourcesContent: sourcesContent,
|
||||
_ignoreList: ignoreList
|
||||
// _originalScopes: originalScopes,
|
||||
} = cast2(map);
|
||||
const index = put(sources, source);
|
||||
if (index === sourcesContent.length) sourcesContent[index] = null;
|
||||
if (ignore) put(ignoreList, index);
|
||||
else remove(ignoreList, index);
|
||||
}
|
||||
function toDecodedMap(map) {
|
||||
const {
|
||||
_mappings: mappings,
|
||||
_sources: sources,
|
||||
_sourcesContent: sourcesContent,
|
||||
_names: names,
|
||||
_ignoreList: ignoreList
|
||||
// _originalScopes: originalScopes,
|
||||
// _generatedRanges: generatedRanges,
|
||||
} = cast2(map);
|
||||
removeEmptyFinalLines(mappings);
|
||||
return {
|
||||
version: 3,
|
||||
file: map.file || void 0,
|
||||
names: names.array,
|
||||
sourceRoot: map.sourceRoot || void 0,
|
||||
sources: sources.array,
|
||||
sourcesContent,
|
||||
mappings,
|
||||
// originalScopes,
|
||||
// generatedRanges,
|
||||
ignoreList: ignoreList.array
|
||||
};
|
||||
}
|
||||
function toEncodedMap(map) {
|
||||
const decoded = toDecodedMap(map);
|
||||
return Object.assign({}, decoded, {
|
||||
// originalScopes: decoded.originalScopes.map((os) => encodeOriginalScopes(os)),
|
||||
// generatedRanges: encodeGeneratedRanges(decoded.generatedRanges as GeneratedRange[]),
|
||||
mappings: (0, import_sourcemap_codec.encode)(decoded.mappings)
|
||||
});
|
||||
}
|
||||
function fromMap(input) {
|
||||
const map = new import_trace_mapping.TraceMap(input);
|
||||
const gen = new GenMapping({ file: map.file, sourceRoot: map.sourceRoot });
|
||||
putAll(cast2(gen)._names, map.names);
|
||||
putAll(cast2(gen)._sources, map.sources);
|
||||
cast2(gen)._sourcesContent = map.sourcesContent || map.sources.map(() => null);
|
||||
cast2(gen)._mappings = (0, import_trace_mapping.decodedMappings)(map);
|
||||
if (map.ignoreList) putAll(cast2(gen)._ignoreList, map.ignoreList);
|
||||
return gen;
|
||||
}
|
||||
function allMappings(map) {
|
||||
const out = [];
|
||||
const { _mappings: mappings, _sources: sources, _names: names } = cast2(map);
|
||||
for (let i = 0; i < mappings.length; i++) {
|
||||
const line = mappings[i];
|
||||
for (let j = 0; j < line.length; j++) {
|
||||
const seg = line[j];
|
||||
const generated = { line: i + 1, column: seg[COLUMN] };
|
||||
let source = void 0;
|
||||
let original = void 0;
|
||||
let name = void 0;
|
||||
if (seg.length !== 1) {
|
||||
source = sources.array[seg[SOURCES_INDEX]];
|
||||
original = { line: seg[SOURCE_LINE] + 1, column: seg[SOURCE_COLUMN] };
|
||||
if (seg.length === 5) name = names.array[seg[NAMES_INDEX]];
|
||||
}
|
||||
out.push({ generated, source, original, name });
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
function addSegmentInternal(skipable, map, genLine, genColumn, source, sourceLine, sourceColumn, name, content) {
|
||||
const {
|
||||
_mappings: mappings,
|
||||
_sources: sources,
|
||||
_sourcesContent: sourcesContent,
|
||||
_names: names
|
||||
// _originalScopes: originalScopes,
|
||||
} = cast2(map);
|
||||
const line = getIndex(mappings, genLine);
|
||||
const index = getColumnIndex(line, genColumn);
|
||||
if (!source) {
|
||||
if (skipable && skipSourceless(line, index)) return;
|
||||
return insert(line, index, [genColumn]);
|
||||
}
|
||||
assert(sourceLine);
|
||||
assert(sourceColumn);
|
||||
const sourcesIndex = put(sources, source);
|
||||
const namesIndex = name ? put(names, name) : NO_NAME;
|
||||
if (sourcesIndex === sourcesContent.length) sourcesContent[sourcesIndex] = content != null ? content : null;
|
||||
if (skipable && skipSource(line, index, sourcesIndex, sourceLine, sourceColumn, namesIndex)) {
|
||||
return;
|
||||
}
|
||||
return insert(
|
||||
line,
|
||||
index,
|
||||
name ? [genColumn, sourcesIndex, sourceLine, sourceColumn, namesIndex] : [genColumn, sourcesIndex, sourceLine, sourceColumn]
|
||||
);
|
||||
}
|
||||
function assert(_val) {
|
||||
}
|
||||
function getIndex(arr, index) {
|
||||
for (let i = arr.length; i <= index; i++) {
|
||||
arr[i] = [];
|
||||
}
|
||||
return arr[index];
|
||||
}
|
||||
function getColumnIndex(line, genColumn) {
|
||||
let index = line.length;
|
||||
for (let i = index - 1; i >= 0; index = i--) {
|
||||
const current = line[i];
|
||||
if (genColumn >= current[COLUMN]) break;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
function insert(array, index, value) {
|
||||
for (let i = array.length; i > index; i--) {
|
||||
array[i] = array[i - 1];
|
||||
}
|
||||
array[index] = value;
|
||||
}
|
||||
function removeEmptyFinalLines(mappings) {
|
||||
const { length } = mappings;
|
||||
let len = length;
|
||||
for (let i = len - 1; i >= 0; len = i, i--) {
|
||||
if (mappings[i].length > 0) break;
|
||||
}
|
||||
if (len < length) mappings.length = len;
|
||||
}
|
||||
function putAll(setarr, array) {
|
||||
for (let i = 0; i < array.length; i++) put(setarr, array[i]);
|
||||
}
|
||||
function skipSourceless(line, index) {
|
||||
if (index === 0) return true;
|
||||
const prev = line[index - 1];
|
||||
return prev.length === 1;
|
||||
}
|
||||
function skipSource(line, index, sourcesIndex, sourceLine, sourceColumn, namesIndex) {
|
||||
if (index === 0) return false;
|
||||
const prev = line[index - 1];
|
||||
if (prev.length === 1) return false;
|
||||
return sourcesIndex === prev[SOURCES_INDEX] && sourceLine === prev[SOURCE_LINE] && sourceColumn === prev[SOURCE_COLUMN] && namesIndex === (prev.length === 5 ? prev[NAMES_INDEX] : NO_NAME);
|
||||
}
|
||||
function addMappingInternal(skipable, map, mapping) {
|
||||
const { generated, source, original, name, content } = mapping;
|
||||
if (!source) {
|
||||
return addSegmentInternal(
|
||||
skipable,
|
||||
map,
|
||||
generated.line - 1,
|
||||
generated.column,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
);
|
||||
}
|
||||
assert(original);
|
||||
return addSegmentInternal(
|
||||
skipable,
|
||||
map,
|
||||
generated.line - 1,
|
||||
generated.column,
|
||||
source,
|
||||
original.line - 1,
|
||||
original.column,
|
||||
name,
|
||||
content
|
||||
);
|
||||
}
|
||||
}));
|
||||
//# sourceMappingURL=gen-mapping.umd.js.map
|
||||
+6
File diff suppressed because one or more lines are too long
+88
@@ -0,0 +1,88 @@
|
||||
import type { SourceMapInput } from '@jridgewell/trace-mapping';
|
||||
import type { DecodedSourceMap, EncodedSourceMap, Pos, Mapping } from './types';
|
||||
export type { DecodedSourceMap, EncodedSourceMap, Mapping };
|
||||
export type Options = {
|
||||
file?: string | null;
|
||||
sourceRoot?: string | null;
|
||||
};
|
||||
/**
|
||||
* Provides the state to generate a sourcemap.
|
||||
*/
|
||||
export declare class GenMapping {
|
||||
private _names;
|
||||
private _sources;
|
||||
private _sourcesContent;
|
||||
private _mappings;
|
||||
private _ignoreList;
|
||||
file: string | null | undefined;
|
||||
sourceRoot: string | null | undefined;
|
||||
constructor({ file, sourceRoot }?: Options);
|
||||
}
|
||||
/**
|
||||
* A low-level API to associate a generated position with an original source position. Line and
|
||||
* column here are 0-based, unlike `addMapping`.
|
||||
*/
|
||||
export declare function addSegment(map: GenMapping, genLine: number, genColumn: number, source?: null, sourceLine?: null, sourceColumn?: null, name?: null, content?: null): void;
|
||||
export declare function addSegment(map: GenMapping, genLine: number, genColumn: number, source: string, sourceLine: number, sourceColumn: number, name?: null, content?: string | null): void;
|
||||
export declare function addSegment(map: GenMapping, genLine: number, genColumn: number, source: string, sourceLine: number, sourceColumn: number, name: string, content?: string | null): void;
|
||||
/**
|
||||
* A high-level API to associate a generated position with an original source position. Line is
|
||||
* 1-based, but column is 0-based, due to legacy behavior in `source-map` library.
|
||||
*/
|
||||
export declare function addMapping(map: GenMapping, mapping: {
|
||||
generated: Pos;
|
||||
source?: null;
|
||||
original?: null;
|
||||
name?: null;
|
||||
content?: null;
|
||||
}): void;
|
||||
export declare function addMapping(map: GenMapping, mapping: {
|
||||
generated: Pos;
|
||||
source: string;
|
||||
original: Pos;
|
||||
name?: null;
|
||||
content?: string | null;
|
||||
}): void;
|
||||
export declare function addMapping(map: GenMapping, mapping: {
|
||||
generated: Pos;
|
||||
source: string;
|
||||
original: Pos;
|
||||
name: string;
|
||||
content?: string | null;
|
||||
}): void;
|
||||
/**
|
||||
* Same as `addSegment`, but will only add the segment if it generates useful information in the
|
||||
* resulting map. This only works correctly if segments are added **in order**, meaning you should
|
||||
* not add a segment with a lower generated line/column than one that came before.
|
||||
*/
|
||||
export declare const maybeAddSegment: typeof addSegment;
|
||||
/**
|
||||
* Same as `addMapping`, but will only add the mapping if it generates useful information in the
|
||||
* resulting map. This only works correctly if mappings are added **in order**, meaning you should
|
||||
* not add a mapping with a lower generated line/column than one that came before.
|
||||
*/
|
||||
export declare const maybeAddMapping: typeof addMapping;
|
||||
/**
|
||||
* Adds/removes the content of the source file to the source map.
|
||||
*/
|
||||
export declare function setSourceContent(map: GenMapping, source: string, content: string | null): void;
|
||||
export declare function setIgnore(map: GenMapping, source: string, ignore?: boolean): void;
|
||||
/**
|
||||
* Returns a sourcemap object (with decoded mappings) suitable for passing to a library that expects
|
||||
* a sourcemap, or to JSON.stringify.
|
||||
*/
|
||||
export declare function toDecodedMap(map: GenMapping): DecodedSourceMap;
|
||||
/**
|
||||
* Returns a sourcemap object (with encoded mappings) suitable for passing to a library that expects
|
||||
* a sourcemap, or to JSON.stringify.
|
||||
*/
|
||||
export declare function toEncodedMap(map: GenMapping): EncodedSourceMap;
|
||||
/**
|
||||
* Constructs a new GenMapping, using the already present mappings of the input.
|
||||
*/
|
||||
export declare function fromMap(input: SourceMapInput): GenMapping;
|
||||
/**
|
||||
* Returns an array of high-level mapping objects for every recorded segment, which could then be
|
||||
* passed to the `source-map` library.
|
||||
*/
|
||||
export declare function allMappings(map: GenMapping): Mapping[];
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
type Key = string | number | symbol;
|
||||
/**
|
||||
* SetArray acts like a `Set` (allowing only one occurrence of a string `key`), but provides the
|
||||
* index of the `key` in the backing array.
|
||||
*
|
||||
* This is designed to allow synchronizing a second array with the contents of the backing array,
|
||||
* like how in a sourcemap `sourcesContent[i]` is the source content associated with `source[i]`,
|
||||
* and there are never duplicates.
|
||||
*/
|
||||
export declare class SetArray<T extends Key = Key> {
|
||||
private _indexes;
|
||||
array: readonly T[];
|
||||
constructor();
|
||||
}
|
||||
/**
|
||||
* Gets the index associated with `key` in the backing array, if it is already present.
|
||||
*/
|
||||
export declare function get<T extends Key>(setarr: SetArray<T>, key: T): number | undefined;
|
||||
/**
|
||||
* Puts `key` into the backing array, if it is not already present. Returns
|
||||
* the index of the `key` in the backing array.
|
||||
*/
|
||||
export declare function put<T extends Key>(setarr: SetArray<T>, key: T): number;
|
||||
/**
|
||||
* Pops the last added item out of the SetArray.
|
||||
*/
|
||||
export declare function pop<T extends Key>(setarr: SetArray<T>): void;
|
||||
/**
|
||||
* Removes the key, if it exists in the set.
|
||||
*/
|
||||
export declare function remove<T extends Key>(setarr: SetArray<T>, key: T): void;
|
||||
export {};
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
type GeneratedColumn = number;
|
||||
type SourcesIndex = number;
|
||||
type SourceLine = number;
|
||||
type SourceColumn = number;
|
||||
type NamesIndex = number;
|
||||
export type SourceMapSegment = [GeneratedColumn] | [GeneratedColumn, SourcesIndex, SourceLine, SourceColumn] | [GeneratedColumn, SourcesIndex, SourceLine, SourceColumn, NamesIndex];
|
||||
export declare const COLUMN = 0;
|
||||
export declare const SOURCES_INDEX = 1;
|
||||
export declare const SOURCE_LINE = 2;
|
||||
export declare const SOURCE_COLUMN = 3;
|
||||
export declare const NAMES_INDEX = 4;
|
||||
export {};
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
import type { SourceMapSegment } from './sourcemap-segment';
|
||||
export interface SourceMapV3 {
|
||||
file?: string | null;
|
||||
names: readonly string[];
|
||||
sourceRoot?: string;
|
||||
sources: readonly (string | null)[];
|
||||
sourcesContent?: readonly (string | null)[];
|
||||
version: 3;
|
||||
ignoreList?: readonly number[];
|
||||
}
|
||||
export interface EncodedSourceMap extends SourceMapV3 {
|
||||
mappings: string;
|
||||
}
|
||||
export interface DecodedSourceMap extends SourceMapV3 {
|
||||
mappings: readonly SourceMapSegment[][];
|
||||
}
|
||||
export interface Pos {
|
||||
line: number;
|
||||
column: number;
|
||||
}
|
||||
export interface OriginalPos extends Pos {
|
||||
source: string;
|
||||
}
|
||||
export interface BindingExpressionRange {
|
||||
start: Pos;
|
||||
expression: string;
|
||||
}
|
||||
export type Mapping = {
|
||||
generated: Pos;
|
||||
source: undefined;
|
||||
original: undefined;
|
||||
name: undefined;
|
||||
} | {
|
||||
generated: Pos;
|
||||
source: string;
|
||||
original: Pos;
|
||||
name: string;
|
||||
} | {
|
||||
generated: Pos;
|
||||
source: string;
|
||||
original: Pos;
|
||||
name: undefined;
|
||||
};
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
{
|
||||
"name": "@jridgewell/gen-mapping",
|
||||
"version": "0.3.13",
|
||||
"description": "Generate source maps",
|
||||
"keywords": [
|
||||
"source",
|
||||
"map"
|
||||
],
|
||||
"main": "dist/gen-mapping.umd.js",
|
||||
"module": "dist/gen-mapping.mjs",
|
||||
"types": "types/gen-mapping.d.cts",
|
||||
"files": [
|
||||
"dist",
|
||||
"src",
|
||||
"types"
|
||||
],
|
||||
"exports": {
|
||||
".": [
|
||||
{
|
||||
"import": {
|
||||
"types": "./types/gen-mapping.d.mts",
|
||||
"default": "./dist/gen-mapping.mjs"
|
||||
},
|
||||
"default": {
|
||||
"types": "./types/gen-mapping.d.cts",
|
||||
"default": "./dist/gen-mapping.umd.js"
|
||||
}
|
||||
},
|
||||
"./dist/gen-mapping.umd.js"
|
||||
],
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"scripts": {
|
||||
"benchmark": "run-s build:code benchmark:*",
|
||||
"benchmark:install": "cd benchmark && npm install",
|
||||
"benchmark:only": "node --expose-gc benchmark/index.js",
|
||||
"build": "run-s -n build:code build:types",
|
||||
"build:code": "node ../../esbuild.mjs gen-mapping.ts",
|
||||
"build:types": "run-s build:types:force build:types:emit build:types:mts",
|
||||
"build:types:force": "rimraf tsconfig.build.tsbuildinfo",
|
||||
"build:types:emit": "tsc --project tsconfig.build.json",
|
||||
"build:types:mts": "node ../../mts-types.mjs",
|
||||
"clean": "run-s -n clean:code clean:types",
|
||||
"clean:code": "tsc --build --clean tsconfig.build.json",
|
||||
"clean:types": "rimraf dist types",
|
||||
"test": "run-s -n test:types test:only test:format",
|
||||
"test:format": "prettier --check '{src,test}/**/*.ts'",
|
||||
"test:only": "mocha",
|
||||
"test:types": "eslint '{src,test}/**/*.ts'",
|
||||
"lint": "run-s -n lint:types lint:format",
|
||||
"lint:format": "npm run test:format -- --write",
|
||||
"lint:types": "npm run test:types -- --fix",
|
||||
"prepublishOnly": "npm run-s -n build test"
|
||||
},
|
||||
"homepage": "https://github.com/jridgewell/sourcemaps/tree/main/packages/gen-mapping",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/jridgewell/sourcemaps.git",
|
||||
"directory": "packages/gen-mapping"
|
||||
},
|
||||
"author": "Justin Ridgewell <justin@ridgewell.name>",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/sourcemap-codec": "^1.5.0",
|
||||
"@jridgewell/trace-mapping": "^0.3.24"
|
||||
}
|
||||
}
|
||||
+614
@@ -0,0 +1,614 @@
|
||||
import { SetArray, put, remove } from './set-array';
|
||||
import {
|
||||
encode,
|
||||
// encodeGeneratedRanges,
|
||||
// encodeOriginalScopes
|
||||
} from '@jridgewell/sourcemap-codec';
|
||||
import { TraceMap, decodedMappings } from '@jridgewell/trace-mapping';
|
||||
|
||||
import {
|
||||
COLUMN,
|
||||
SOURCES_INDEX,
|
||||
SOURCE_LINE,
|
||||
SOURCE_COLUMN,
|
||||
NAMES_INDEX,
|
||||
} from './sourcemap-segment';
|
||||
|
||||
import type { SourceMapInput } from '@jridgewell/trace-mapping';
|
||||
// import type { OriginalScope, GeneratedRange } from '@jridgewell/sourcemap-codec';
|
||||
import type { SourceMapSegment } from './sourcemap-segment';
|
||||
import type {
|
||||
DecodedSourceMap,
|
||||
EncodedSourceMap,
|
||||
Pos,
|
||||
Mapping,
|
||||
// BindingExpressionRange,
|
||||
// OriginalPos,
|
||||
// OriginalScopeInfo,
|
||||
// GeneratedRangeInfo,
|
||||
} from './types';
|
||||
|
||||
export type { DecodedSourceMap, EncodedSourceMap, Mapping };
|
||||
|
||||
export type Options = {
|
||||
file?: string | null;
|
||||
sourceRoot?: string | null;
|
||||
};
|
||||
|
||||
const NO_NAME = -1;
|
||||
|
||||
/**
|
||||
* Provides the state to generate a sourcemap.
|
||||
*/
|
||||
export class GenMapping {
|
||||
declare private _names: SetArray<string>;
|
||||
declare private _sources: SetArray<string>;
|
||||
declare private _sourcesContent: (string | null)[];
|
||||
declare private _mappings: SourceMapSegment[][];
|
||||
// private declare _originalScopes: OriginalScope[][];
|
||||
// private declare _generatedRanges: GeneratedRange[];
|
||||
declare private _ignoreList: SetArray<number>;
|
||||
declare file: string | null | undefined;
|
||||
declare sourceRoot: string | null | undefined;
|
||||
|
||||
constructor({ file, sourceRoot }: Options = {}) {
|
||||
this._names = new SetArray();
|
||||
this._sources = new SetArray();
|
||||
this._sourcesContent = [];
|
||||
this._mappings = [];
|
||||
// this._originalScopes = [];
|
||||
// this._generatedRanges = [];
|
||||
this.file = file;
|
||||
this.sourceRoot = sourceRoot;
|
||||
this._ignoreList = new SetArray();
|
||||
}
|
||||
}
|
||||
|
||||
interface PublicMap {
|
||||
_names: GenMapping['_names'];
|
||||
_sources: GenMapping['_sources'];
|
||||
_sourcesContent: GenMapping['_sourcesContent'];
|
||||
_mappings: GenMapping['_mappings'];
|
||||
// _originalScopes: GenMapping['_originalScopes'];
|
||||
// _generatedRanges: GenMapping['_generatedRanges'];
|
||||
_ignoreList: GenMapping['_ignoreList'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Typescript doesn't allow friend access to private fields, so this just casts the map into a type
|
||||
* with public access modifiers.
|
||||
*/
|
||||
function cast(map: unknown): PublicMap {
|
||||
return map as any;
|
||||
}
|
||||
|
||||
/**
|
||||
* A low-level API to associate a generated position with an original source position. Line and
|
||||
* column here are 0-based, unlike `addMapping`.
|
||||
*/
|
||||
export function addSegment(
|
||||
map: GenMapping,
|
||||
genLine: number,
|
||||
genColumn: number,
|
||||
source?: null,
|
||||
sourceLine?: null,
|
||||
sourceColumn?: null,
|
||||
name?: null,
|
||||
content?: null,
|
||||
): void;
|
||||
export function addSegment(
|
||||
map: GenMapping,
|
||||
genLine: number,
|
||||
genColumn: number,
|
||||
source: string,
|
||||
sourceLine: number,
|
||||
sourceColumn: number,
|
||||
name?: null,
|
||||
content?: string | null,
|
||||
): void;
|
||||
export function addSegment(
|
||||
map: GenMapping,
|
||||
genLine: number,
|
||||
genColumn: number,
|
||||
source: string,
|
||||
sourceLine: number,
|
||||
sourceColumn: number,
|
||||
name: string,
|
||||
content?: string | null,
|
||||
): void;
|
||||
export function addSegment(
|
||||
map: GenMapping,
|
||||
genLine: number,
|
||||
genColumn: number,
|
||||
source?: string | null,
|
||||
sourceLine?: number | null,
|
||||
sourceColumn?: number | null,
|
||||
name?: string | null,
|
||||
content?: string | null,
|
||||
): void {
|
||||
return addSegmentInternal(
|
||||
false,
|
||||
map,
|
||||
genLine,
|
||||
genColumn,
|
||||
source,
|
||||
sourceLine,
|
||||
sourceColumn,
|
||||
name,
|
||||
content,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* A high-level API to associate a generated position with an original source position. Line is
|
||||
* 1-based, but column is 0-based, due to legacy behavior in `source-map` library.
|
||||
*/
|
||||
export function addMapping(
|
||||
map: GenMapping,
|
||||
mapping: {
|
||||
generated: Pos;
|
||||
source?: null;
|
||||
original?: null;
|
||||
name?: null;
|
||||
content?: null;
|
||||
},
|
||||
): void;
|
||||
export function addMapping(
|
||||
map: GenMapping,
|
||||
mapping: {
|
||||
generated: Pos;
|
||||
source: string;
|
||||
original: Pos;
|
||||
name?: null;
|
||||
content?: string | null;
|
||||
},
|
||||
): void;
|
||||
export function addMapping(
|
||||
map: GenMapping,
|
||||
mapping: {
|
||||
generated: Pos;
|
||||
source: string;
|
||||
original: Pos;
|
||||
name: string;
|
||||
content?: string | null;
|
||||
},
|
||||
): void;
|
||||
export function addMapping(
|
||||
map: GenMapping,
|
||||
mapping: {
|
||||
generated: Pos;
|
||||
source?: string | null;
|
||||
original?: Pos | null;
|
||||
name?: string | null;
|
||||
content?: string | null;
|
||||
},
|
||||
): void {
|
||||
return addMappingInternal(false, map, mapping as Parameters<typeof addMappingInternal>[2]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as `addSegment`, but will only add the segment if it generates useful information in the
|
||||
* resulting map. This only works correctly if segments are added **in order**, meaning you should
|
||||
* not add a segment with a lower generated line/column than one that came before.
|
||||
*/
|
||||
export const maybeAddSegment: typeof addSegment = (
|
||||
map,
|
||||
genLine,
|
||||
genColumn,
|
||||
source,
|
||||
sourceLine,
|
||||
sourceColumn,
|
||||
name,
|
||||
content,
|
||||
) => {
|
||||
return addSegmentInternal(
|
||||
true,
|
||||
map,
|
||||
genLine,
|
||||
genColumn,
|
||||
source,
|
||||
sourceLine,
|
||||
sourceColumn,
|
||||
name,
|
||||
content,
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Same as `addMapping`, but will only add the mapping if it generates useful information in the
|
||||
* resulting map. This only works correctly if mappings are added **in order**, meaning you should
|
||||
* not add a mapping with a lower generated line/column than one that came before.
|
||||
*/
|
||||
export const maybeAddMapping: typeof addMapping = (map, mapping) => {
|
||||
return addMappingInternal(true, map, mapping as Parameters<typeof addMappingInternal>[2]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds/removes the content of the source file to the source map.
|
||||
*/
|
||||
export function setSourceContent(map: GenMapping, source: string, content: string | null): void {
|
||||
const {
|
||||
_sources: sources,
|
||||
_sourcesContent: sourcesContent,
|
||||
// _originalScopes: originalScopes,
|
||||
} = cast(map);
|
||||
const index = put(sources, source);
|
||||
sourcesContent[index] = content;
|
||||
// if (index === originalScopes.length) originalScopes[index] = [];
|
||||
}
|
||||
|
||||
export function setIgnore(map: GenMapping, source: string, ignore = true) {
|
||||
const {
|
||||
_sources: sources,
|
||||
_sourcesContent: sourcesContent,
|
||||
_ignoreList: ignoreList,
|
||||
// _originalScopes: originalScopes,
|
||||
} = cast(map);
|
||||
const index = put(sources, source);
|
||||
if (index === sourcesContent.length) sourcesContent[index] = null;
|
||||
// if (index === originalScopes.length) originalScopes[index] = [];
|
||||
if (ignore) put(ignoreList, index);
|
||||
else remove(ignoreList, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a sourcemap object (with decoded mappings) suitable for passing to a library that expects
|
||||
* a sourcemap, or to JSON.stringify.
|
||||
*/
|
||||
export function toDecodedMap(map: GenMapping): DecodedSourceMap {
|
||||
const {
|
||||
_mappings: mappings,
|
||||
_sources: sources,
|
||||
_sourcesContent: sourcesContent,
|
||||
_names: names,
|
||||
_ignoreList: ignoreList,
|
||||
// _originalScopes: originalScopes,
|
||||
// _generatedRanges: generatedRanges,
|
||||
} = cast(map);
|
||||
removeEmptyFinalLines(mappings);
|
||||
|
||||
return {
|
||||
version: 3,
|
||||
file: map.file || undefined,
|
||||
names: names.array,
|
||||
sourceRoot: map.sourceRoot || undefined,
|
||||
sources: sources.array,
|
||||
sourcesContent,
|
||||
mappings,
|
||||
// originalScopes,
|
||||
// generatedRanges,
|
||||
ignoreList: ignoreList.array,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a sourcemap object (with encoded mappings) suitable for passing to a library that expects
|
||||
* a sourcemap, or to JSON.stringify.
|
||||
*/
|
||||
export function toEncodedMap(map: GenMapping): EncodedSourceMap {
|
||||
const decoded = toDecodedMap(map);
|
||||
return Object.assign({}, decoded, {
|
||||
// originalScopes: decoded.originalScopes.map((os) => encodeOriginalScopes(os)),
|
||||
// generatedRanges: encodeGeneratedRanges(decoded.generatedRanges as GeneratedRange[]),
|
||||
mappings: encode(decoded.mappings as SourceMapSegment[][]),
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new GenMapping, using the already present mappings of the input.
|
||||
*/
|
||||
export function fromMap(input: SourceMapInput): GenMapping {
|
||||
const map = new TraceMap(input);
|
||||
const gen = new GenMapping({ file: map.file, sourceRoot: map.sourceRoot });
|
||||
|
||||
putAll(cast(gen)._names, map.names);
|
||||
putAll(cast(gen)._sources, map.sources as string[]);
|
||||
cast(gen)._sourcesContent = map.sourcesContent || map.sources.map(() => null);
|
||||
cast(gen)._mappings = decodedMappings(map) as GenMapping['_mappings'];
|
||||
// TODO: implement originalScopes/generatedRanges
|
||||
if (map.ignoreList) putAll(cast(gen)._ignoreList, map.ignoreList);
|
||||
|
||||
return gen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of high-level mapping objects for every recorded segment, which could then be
|
||||
* passed to the `source-map` library.
|
||||
*/
|
||||
export function allMappings(map: GenMapping): Mapping[] {
|
||||
const out: Mapping[] = [];
|
||||
const { _mappings: mappings, _sources: sources, _names: names } = cast(map);
|
||||
|
||||
for (let i = 0; i < mappings.length; i++) {
|
||||
const line = mappings[i];
|
||||
for (let j = 0; j < line.length; j++) {
|
||||
const seg = line[j];
|
||||
|
||||
const generated = { line: i + 1, column: seg[COLUMN] };
|
||||
let source: string | undefined = undefined;
|
||||
let original: Pos | undefined = undefined;
|
||||
let name: string | undefined = undefined;
|
||||
|
||||
if (seg.length !== 1) {
|
||||
source = sources.array[seg[SOURCES_INDEX]];
|
||||
original = { line: seg[SOURCE_LINE] + 1, column: seg[SOURCE_COLUMN] };
|
||||
|
||||
if (seg.length === 5) name = names.array[seg[NAMES_INDEX]];
|
||||
}
|
||||
|
||||
out.push({ generated, source, original, name } as Mapping);
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
// This split declaration is only so that terser can elminiate the static initialization block.
|
||||
function addSegmentInternal<S extends string | null | undefined>(
|
||||
skipable: boolean,
|
||||
map: GenMapping,
|
||||
genLine: number,
|
||||
genColumn: number,
|
||||
source: S,
|
||||
sourceLine: S extends string ? number : null | undefined,
|
||||
sourceColumn: S extends string ? number : null | undefined,
|
||||
name: S extends string ? string | null | undefined : null | undefined,
|
||||
content: S extends string ? string | null | undefined : null | undefined,
|
||||
): void {
|
||||
const {
|
||||
_mappings: mappings,
|
||||
_sources: sources,
|
||||
_sourcesContent: sourcesContent,
|
||||
_names: names,
|
||||
// _originalScopes: originalScopes,
|
||||
} = cast(map);
|
||||
const line = getIndex(mappings, genLine);
|
||||
const index = getColumnIndex(line, genColumn);
|
||||
|
||||
if (!source) {
|
||||
if (skipable && skipSourceless(line, index)) return;
|
||||
return insert(line, index, [genColumn]);
|
||||
}
|
||||
|
||||
// Sigh, TypeScript can't figure out sourceLine and sourceColumn aren't nullish if source
|
||||
// isn't nullish.
|
||||
assert<number>(sourceLine);
|
||||
assert<number>(sourceColumn);
|
||||
|
||||
const sourcesIndex = put(sources, source);
|
||||
const namesIndex = name ? put(names, name) : NO_NAME;
|
||||
if (sourcesIndex === sourcesContent.length) sourcesContent[sourcesIndex] = content ?? null;
|
||||
// if (sourcesIndex === originalScopes.length) originalScopes[sourcesIndex] = [];
|
||||
|
||||
if (skipable && skipSource(line, index, sourcesIndex, sourceLine, sourceColumn, namesIndex)) {
|
||||
return;
|
||||
}
|
||||
|
||||
return insert(
|
||||
line,
|
||||
index,
|
||||
name
|
||||
? [genColumn, sourcesIndex, sourceLine, sourceColumn, namesIndex]
|
||||
: [genColumn, sourcesIndex, sourceLine, sourceColumn],
|
||||
);
|
||||
}
|
||||
|
||||
function assert<T>(_val: unknown): asserts _val is T {
|
||||
// noop.
|
||||
}
|
||||
|
||||
function getIndex<T>(arr: T[][], index: number): T[] {
|
||||
for (let i = arr.length; i <= index; i++) {
|
||||
arr[i] = [];
|
||||
}
|
||||
return arr[index];
|
||||
}
|
||||
|
||||
function getColumnIndex(line: SourceMapSegment[], genColumn: number): number {
|
||||
let index = line.length;
|
||||
for (let i = index - 1; i >= 0; index = i--) {
|
||||
const current = line[i];
|
||||
if (genColumn >= current[COLUMN]) break;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
function insert<T>(array: T[], index: number, value: T) {
|
||||
for (let i = array.length; i > index; i--) {
|
||||
array[i] = array[i - 1];
|
||||
}
|
||||
array[index] = value;
|
||||
}
|
||||
|
||||
function removeEmptyFinalLines(mappings: SourceMapSegment[][]) {
|
||||
const { length } = mappings;
|
||||
let len = length;
|
||||
for (let i = len - 1; i >= 0; len = i, i--) {
|
||||
if (mappings[i].length > 0) break;
|
||||
}
|
||||
if (len < length) mappings.length = len;
|
||||
}
|
||||
|
||||
function putAll<T extends string | number>(setarr: SetArray<T>, array: T[]) {
|
||||
for (let i = 0; i < array.length; i++) put(setarr, array[i]);
|
||||
}
|
||||
|
||||
function skipSourceless(line: SourceMapSegment[], index: number): boolean {
|
||||
// The start of a line is already sourceless, so adding a sourceless segment to the beginning
|
||||
// doesn't generate any useful information.
|
||||
if (index === 0) return true;
|
||||
|
||||
const prev = line[index - 1];
|
||||
// If the previous segment is also sourceless, then adding another sourceless segment doesn't
|
||||
// genrate any new information. Else, this segment will end the source/named segment and point to
|
||||
// a sourceless position, which is useful.
|
||||
return prev.length === 1;
|
||||
}
|
||||
|
||||
function skipSource(
|
||||
line: SourceMapSegment[],
|
||||
index: number,
|
||||
sourcesIndex: number,
|
||||
sourceLine: number,
|
||||
sourceColumn: number,
|
||||
namesIndex: number,
|
||||
): boolean {
|
||||
// A source/named segment at the start of a line gives position at that genColumn
|
||||
if (index === 0) return false;
|
||||
|
||||
const prev = line[index - 1];
|
||||
|
||||
// If the previous segment is sourceless, then we're transitioning to a source.
|
||||
if (prev.length === 1) return false;
|
||||
|
||||
// If the previous segment maps to the exact same source position, then this segment doesn't
|
||||
// provide any new position information.
|
||||
return (
|
||||
sourcesIndex === prev[SOURCES_INDEX] &&
|
||||
sourceLine === prev[SOURCE_LINE] &&
|
||||
sourceColumn === prev[SOURCE_COLUMN] &&
|
||||
namesIndex === (prev.length === 5 ? prev[NAMES_INDEX] : NO_NAME)
|
||||
);
|
||||
}
|
||||
|
||||
function addMappingInternal<S extends string | null | undefined>(
|
||||
skipable: boolean,
|
||||
map: GenMapping,
|
||||
mapping: {
|
||||
generated: Pos;
|
||||
source: S;
|
||||
original: S extends string ? Pos : null | undefined;
|
||||
name: S extends string ? string | null | undefined : null | undefined;
|
||||
content: S extends string ? string | null | undefined : null | undefined;
|
||||
},
|
||||
) {
|
||||
const { generated, source, original, name, content } = mapping;
|
||||
if (!source) {
|
||||
return addSegmentInternal(
|
||||
skipable,
|
||||
map,
|
||||
generated.line - 1,
|
||||
generated.column,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
}
|
||||
assert<Pos>(original);
|
||||
return addSegmentInternal(
|
||||
skipable,
|
||||
map,
|
||||
generated.line - 1,
|
||||
generated.column,
|
||||
source as string,
|
||||
original.line - 1,
|
||||
original.column,
|
||||
name,
|
||||
content,
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
export function addOriginalScope(
|
||||
map: GenMapping,
|
||||
data: {
|
||||
start: Pos;
|
||||
end: Pos;
|
||||
source: string;
|
||||
kind: string;
|
||||
name?: string;
|
||||
variables?: string[];
|
||||
},
|
||||
): OriginalScopeInfo {
|
||||
const { start, end, source, kind, name, variables } = data;
|
||||
const {
|
||||
_sources: sources,
|
||||
_sourcesContent: sourcesContent,
|
||||
_originalScopes: originalScopes,
|
||||
_names: names,
|
||||
} = cast(map);
|
||||
const index = put(sources, source);
|
||||
if (index === sourcesContent.length) sourcesContent[index] = null;
|
||||
if (index === originalScopes.length) originalScopes[index] = [];
|
||||
|
||||
const kindIndex = put(names, kind);
|
||||
const scope: OriginalScope = name
|
||||
? [start.line - 1, start.column, end.line - 1, end.column, kindIndex, put(names, name)]
|
||||
: [start.line - 1, start.column, end.line - 1, end.column, kindIndex];
|
||||
if (variables) {
|
||||
scope.vars = variables.map((v) => put(names, v));
|
||||
}
|
||||
const len = originalScopes[index].push(scope);
|
||||
return [index, len - 1, variables];
|
||||
}
|
||||
*/
|
||||
|
||||
// Generated Ranges
|
||||
/*
|
||||
export function addGeneratedRange(
|
||||
map: GenMapping,
|
||||
data: {
|
||||
start: Pos;
|
||||
isScope: boolean;
|
||||
originalScope?: OriginalScopeInfo;
|
||||
callsite?: OriginalPos;
|
||||
},
|
||||
): GeneratedRangeInfo {
|
||||
const { start, isScope, originalScope, callsite } = data;
|
||||
const {
|
||||
_originalScopes: originalScopes,
|
||||
_sources: sources,
|
||||
_sourcesContent: sourcesContent,
|
||||
_generatedRanges: generatedRanges,
|
||||
} = cast(map);
|
||||
|
||||
const range: GeneratedRange = [
|
||||
start.line - 1,
|
||||
start.column,
|
||||
0,
|
||||
0,
|
||||
originalScope ? originalScope[0] : -1,
|
||||
originalScope ? originalScope[1] : -1,
|
||||
];
|
||||
if (originalScope?.[2]) {
|
||||
range.bindings = originalScope[2].map(() => [[-1]]);
|
||||
}
|
||||
if (callsite) {
|
||||
const index = put(sources, callsite.source);
|
||||
if (index === sourcesContent.length) sourcesContent[index] = null;
|
||||
if (index === originalScopes.length) originalScopes[index] = [];
|
||||
range.callsite = [index, callsite.line - 1, callsite.column];
|
||||
}
|
||||
if (isScope) range.isScope = true;
|
||||
generatedRanges.push(range);
|
||||
|
||||
return [range, originalScope?.[2]];
|
||||
}
|
||||
|
||||
export function setEndPosition(range: GeneratedRangeInfo, pos: Pos) {
|
||||
range[0][2] = pos.line - 1;
|
||||
range[0][3] = pos.column;
|
||||
}
|
||||
|
||||
export function addBinding(
|
||||
map: GenMapping,
|
||||
range: GeneratedRangeInfo,
|
||||
variable: string,
|
||||
expression: string | BindingExpressionRange,
|
||||
) {
|
||||
const { _names: names } = cast(map);
|
||||
const bindings = (range[0].bindings ||= []);
|
||||
const vars = range[1];
|
||||
|
||||
const index = vars!.indexOf(variable);
|
||||
const binding = getIndex(bindings, index);
|
||||
|
||||
if (typeof expression === 'string') binding[0] = [put(names, expression)];
|
||||
else {
|
||||
const { start } = expression;
|
||||
binding.push([put(names, expression.expression), start.line - 1, start.column]);
|
||||
}
|
||||
}
|
||||
*/
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
type Key = string | number | symbol;
|
||||
|
||||
/**
|
||||
* SetArray acts like a `Set` (allowing only one occurrence of a string `key`), but provides the
|
||||
* index of the `key` in the backing array.
|
||||
*
|
||||
* This is designed to allow synchronizing a second array with the contents of the backing array,
|
||||
* like how in a sourcemap `sourcesContent[i]` is the source content associated with `source[i]`,
|
||||
* and there are never duplicates.
|
||||
*/
|
||||
export class SetArray<T extends Key = Key> {
|
||||
declare private _indexes: Record<T, number | undefined>;
|
||||
declare array: readonly T[];
|
||||
|
||||
constructor() {
|
||||
this._indexes = { __proto__: null } as any;
|
||||
this.array = [];
|
||||
}
|
||||
}
|
||||
|
||||
interface PublicSet<T extends Key> {
|
||||
array: T[];
|
||||
_indexes: SetArray<T>['_indexes'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Typescript doesn't allow friend access to private fields, so this just casts the set into a type
|
||||
* with public access modifiers.
|
||||
*/
|
||||
function cast<T extends Key>(set: SetArray<T>): PublicSet<T> {
|
||||
return set as any;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the index associated with `key` in the backing array, if it is already present.
|
||||
*/
|
||||
export function get<T extends Key>(setarr: SetArray<T>, key: T): number | undefined {
|
||||
return cast(setarr)._indexes[key];
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts `key` into the backing array, if it is not already present. Returns
|
||||
* the index of the `key` in the backing array.
|
||||
*/
|
||||
export function put<T extends Key>(setarr: SetArray<T>, key: T): number {
|
||||
// The key may or may not be present. If it is present, it's a number.
|
||||
const index = get(setarr, key);
|
||||
if (index !== undefined) return index;
|
||||
|
||||
const { array, _indexes: indexes } = cast(setarr);
|
||||
|
||||
const length = array.push(key);
|
||||
return (indexes[key] = length - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pops the last added item out of the SetArray.
|
||||
*/
|
||||
export function pop<T extends Key>(setarr: SetArray<T>): void {
|
||||
const { array, _indexes: indexes } = cast(setarr);
|
||||
if (array.length === 0) return;
|
||||
|
||||
const last = array.pop()!;
|
||||
indexes[last] = undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the key, if it exists in the set.
|
||||
*/
|
||||
export function remove<T extends Key>(setarr: SetArray<T>, key: T): void {
|
||||
const index = get(setarr, key);
|
||||
if (index === undefined) return;
|
||||
|
||||
const { array, _indexes: indexes } = cast(setarr);
|
||||
for (let i = index + 1; i < array.length; i++) {
|
||||
const k = array[i];
|
||||
array[i - 1] = k;
|
||||
indexes[k]!--;
|
||||
}
|
||||
indexes[key] = undefined;
|
||||
array.pop();
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
type GeneratedColumn = number;
|
||||
type SourcesIndex = number;
|
||||
type SourceLine = number;
|
||||
type SourceColumn = number;
|
||||
type NamesIndex = number;
|
||||
|
||||
export type SourceMapSegment =
|
||||
| [GeneratedColumn]
|
||||
| [GeneratedColumn, SourcesIndex, SourceLine, SourceColumn]
|
||||
| [GeneratedColumn, SourcesIndex, SourceLine, SourceColumn, NamesIndex];
|
||||
|
||||
export const COLUMN = 0;
|
||||
export const SOURCES_INDEX = 1;
|
||||
export const SOURCE_LINE = 2;
|
||||
export const SOURCE_COLUMN = 3;
|
||||
export const NAMES_INDEX = 4;
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
// import type { GeneratedRange, OriginalScope } from '@jridgewell/sourcemap-codec';
|
||||
import type { SourceMapSegment } from './sourcemap-segment';
|
||||
|
||||
export interface SourceMapV3 {
|
||||
file?: string | null;
|
||||
names: readonly string[];
|
||||
sourceRoot?: string;
|
||||
sources: readonly (string | null)[];
|
||||
sourcesContent?: readonly (string | null)[];
|
||||
version: 3;
|
||||
ignoreList?: readonly number[];
|
||||
}
|
||||
|
||||
export interface EncodedSourceMap extends SourceMapV3 {
|
||||
mappings: string;
|
||||
// originalScopes: string[];
|
||||
// generatedRanges: string;
|
||||
}
|
||||
|
||||
export interface DecodedSourceMap extends SourceMapV3 {
|
||||
mappings: readonly SourceMapSegment[][];
|
||||
// originalScopes: readonly OriginalScope[][];
|
||||
// generatedRanges: readonly GeneratedRange[];
|
||||
}
|
||||
|
||||
export interface Pos {
|
||||
line: number; // 1-based
|
||||
column: number; // 0-based
|
||||
}
|
||||
|
||||
export interface OriginalPos extends Pos {
|
||||
source: string;
|
||||
}
|
||||
|
||||
export interface BindingExpressionRange {
|
||||
start: Pos;
|
||||
expression: string;
|
||||
}
|
||||
|
||||
// export type OriginalScopeInfo = [number, number, string[] | undefined];
|
||||
// export type GeneratedRangeInfo = [GeneratedRange, string[] | undefined];
|
||||
|
||||
export type Mapping =
|
||||
| {
|
||||
generated: Pos;
|
||||
source: undefined;
|
||||
original: undefined;
|
||||
name: undefined;
|
||||
}
|
||||
| {
|
||||
generated: Pos;
|
||||
source: string;
|
||||
original: Pos;
|
||||
name: string;
|
||||
}
|
||||
| {
|
||||
generated: Pos;
|
||||
source: string;
|
||||
original: Pos;
|
||||
name: undefined;
|
||||
};
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
import type { SourceMapInput } from '@jridgewell/trace-mapping';
|
||||
import type { DecodedSourceMap, EncodedSourceMap, Pos, Mapping } from './types.cts';
|
||||
export type { DecodedSourceMap, EncodedSourceMap, Mapping };
|
||||
export type Options = {
|
||||
file?: string | null;
|
||||
sourceRoot?: string | null;
|
||||
};
|
||||
/**
|
||||
* Provides the state to generate a sourcemap.
|
||||
*/
|
||||
export declare class GenMapping {
|
||||
private _names;
|
||||
private _sources;
|
||||
private _sourcesContent;
|
||||
private _mappings;
|
||||
private _ignoreList;
|
||||
file: string | null | undefined;
|
||||
sourceRoot: string | null | undefined;
|
||||
constructor({ file, sourceRoot }?: Options);
|
||||
}
|
||||
/**
|
||||
* A low-level API to associate a generated position with an original source position. Line and
|
||||
* column here are 0-based, unlike `addMapping`.
|
||||
*/
|
||||
export declare function addSegment(map: GenMapping, genLine: number, genColumn: number, source?: null, sourceLine?: null, sourceColumn?: null, name?: null, content?: null): void;
|
||||
export declare function addSegment(map: GenMapping, genLine: number, genColumn: number, source: string, sourceLine: number, sourceColumn: number, name?: null, content?: string | null): void;
|
||||
export declare function addSegment(map: GenMapping, genLine: number, genColumn: number, source: string, sourceLine: number, sourceColumn: number, name: string, content?: string | null): void;
|
||||
/**
|
||||
* A high-level API to associate a generated position with an original source position. Line is
|
||||
* 1-based, but column is 0-based, due to legacy behavior in `source-map` library.
|
||||
*/
|
||||
export declare function addMapping(map: GenMapping, mapping: {
|
||||
generated: Pos;
|
||||
source?: null;
|
||||
original?: null;
|
||||
name?: null;
|
||||
content?: null;
|
||||
}): void;
|
||||
export declare function addMapping(map: GenMapping, mapping: {
|
||||
generated: Pos;
|
||||
source: string;
|
||||
original: Pos;
|
||||
name?: null;
|
||||
content?: string | null;
|
||||
}): void;
|
||||
export declare function addMapping(map: GenMapping, mapping: {
|
||||
generated: Pos;
|
||||
source: string;
|
||||
original: Pos;
|
||||
name: string;
|
||||
content?: string | null;
|
||||
}): void;
|
||||
/**
|
||||
* Same as `addSegment`, but will only add the segment if it generates useful information in the
|
||||
* resulting map. This only works correctly if segments are added **in order**, meaning you should
|
||||
* not add a segment with a lower generated line/column than one that came before.
|
||||
*/
|
||||
export declare const maybeAddSegment: typeof addSegment;
|
||||
/**
|
||||
* Same as `addMapping`, but will only add the mapping if it generates useful information in the
|
||||
* resulting map. This only works correctly if mappings are added **in order**, meaning you should
|
||||
* not add a mapping with a lower generated line/column than one that came before.
|
||||
*/
|
||||
export declare const maybeAddMapping: typeof addMapping;
|
||||
/**
|
||||
* Adds/removes the content of the source file to the source map.
|
||||
*/
|
||||
export declare function setSourceContent(map: GenMapping, source: string, content: string | null): void;
|
||||
export declare function setIgnore(map: GenMapping, source: string, ignore?: boolean): void;
|
||||
/**
|
||||
* Returns a sourcemap object (with decoded mappings) suitable for passing to a library that expects
|
||||
* a sourcemap, or to JSON.stringify.
|
||||
*/
|
||||
export declare function toDecodedMap(map: GenMapping): DecodedSourceMap;
|
||||
/**
|
||||
* Returns a sourcemap object (with encoded mappings) suitable for passing to a library that expects
|
||||
* a sourcemap, or to JSON.stringify.
|
||||
*/
|
||||
export declare function toEncodedMap(map: GenMapping): EncodedSourceMap;
|
||||
/**
|
||||
* Constructs a new GenMapping, using the already present mappings of the input.
|
||||
*/
|
||||
export declare function fromMap(input: SourceMapInput): GenMapping;
|
||||
/**
|
||||
* Returns an array of high-level mapping objects for every recorded segment, which could then be
|
||||
* passed to the `source-map` library.
|
||||
*/
|
||||
export declare function allMappings(map: GenMapping): Mapping[];
|
||||
//# sourceMappingURL=gen-mapping.d.ts.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"gen-mapping.d.ts","sourceRoot":"","sources":["../src/gen-mapping.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAGhE,OAAO,KAAK,EACV,gBAAgB,EAChB,gBAAgB,EAChB,GAAG,EACH,OAAO,EAKR,MAAM,SAAS,CAAC;AAEjB,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,OAAO,EAAE,CAAC;AAE5D,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,CAAC;AAIF;;GAEG;AACH,qBAAa,UAAU;IACrB,QAAgB,MAAM,CAAmB;IACzC,QAAgB,QAAQ,CAAmB;IAC3C,QAAgB,eAAe,CAAoB;IACnD,QAAgB,SAAS,CAAuB;IAGhD,QAAgB,WAAW,CAAmB;IACtC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAChC,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;gBAElC,EAAE,IAAI,EAAE,UAAU,EAAE,GAAE,OAAY;CAW/C;AAoBD;;;GAGG;AACH,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,IAAI,EACb,UAAU,CAAC,EAAE,IAAI,EACjB,YAAY,CAAC,EAAE,IAAI,EACnB,IAAI,CAAC,EAAE,IAAI,EACX,OAAO,CAAC,EAAE,IAAI,GACb,IAAI,CAAC;AACR,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,IAAI,CAAC,EAAE,IAAI,EACX,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GACtB,IAAI,CAAC;AACR,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GACtB,IAAI,CAAC;AAwBR;;;GAGG;AACH,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE;IACP,SAAS,EAAE,GAAG,CAAC;IACf,MAAM,CAAC,EAAE,IAAI,CAAC;IACd,QAAQ,CAAC,EAAE,IAAI,CAAC;IAChB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,OAAO,CAAC,EAAE,IAAI,CAAC;CAChB,GACA,IAAI,CAAC;AACR,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE;IACP,SAAS,EAAE,GAAG,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,GAAG,CAAC;IACd,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,GACA,IAAI,CAAC;AACR,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE;IACP,SAAS,EAAE,GAAG,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,GAAG,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,GACA,IAAI,CAAC;AAcR;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,OAAO,UAqBpC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,OAAO,UAEpC,CAAC;AAEF;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAS9F;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,UAAO,QAYvE;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,UAAU,GAAG,gBAAgB,CAwB9D;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,UAAU,GAAG,gBAAgB,CAO9D;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,cAAc,GAAG,UAAU,CAYzD;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,EAAE,CA0BtD"}
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
import type { SourceMapInput } from '@jridgewell/trace-mapping';
|
||||
import type { DecodedSourceMap, EncodedSourceMap, Pos, Mapping } from './types.mts';
|
||||
export type { DecodedSourceMap, EncodedSourceMap, Mapping };
|
||||
export type Options = {
|
||||
file?: string | null;
|
||||
sourceRoot?: string | null;
|
||||
};
|
||||
/**
|
||||
* Provides the state to generate a sourcemap.
|
||||
*/
|
||||
export declare class GenMapping {
|
||||
private _names;
|
||||
private _sources;
|
||||
private _sourcesContent;
|
||||
private _mappings;
|
||||
private _ignoreList;
|
||||
file: string | null | undefined;
|
||||
sourceRoot: string | null | undefined;
|
||||
constructor({ file, sourceRoot }?: Options);
|
||||
}
|
||||
/**
|
||||
* A low-level API to associate a generated position with an original source position. Line and
|
||||
* column here are 0-based, unlike `addMapping`.
|
||||
*/
|
||||
export declare function addSegment(map: GenMapping, genLine: number, genColumn: number, source?: null, sourceLine?: null, sourceColumn?: null, name?: null, content?: null): void;
|
||||
export declare function addSegment(map: GenMapping, genLine: number, genColumn: number, source: string, sourceLine: number, sourceColumn: number, name?: null, content?: string | null): void;
|
||||
export declare function addSegment(map: GenMapping, genLine: number, genColumn: number, source: string, sourceLine: number, sourceColumn: number, name: string, content?: string | null): void;
|
||||
/**
|
||||
* A high-level API to associate a generated position with an original source position. Line is
|
||||
* 1-based, but column is 0-based, due to legacy behavior in `source-map` library.
|
||||
*/
|
||||
export declare function addMapping(map: GenMapping, mapping: {
|
||||
generated: Pos;
|
||||
source?: null;
|
||||
original?: null;
|
||||
name?: null;
|
||||
content?: null;
|
||||
}): void;
|
||||
export declare function addMapping(map: GenMapping, mapping: {
|
||||
generated: Pos;
|
||||
source: string;
|
||||
original: Pos;
|
||||
name?: null;
|
||||
content?: string | null;
|
||||
}): void;
|
||||
export declare function addMapping(map: GenMapping, mapping: {
|
||||
generated: Pos;
|
||||
source: string;
|
||||
original: Pos;
|
||||
name: string;
|
||||
content?: string | null;
|
||||
}): void;
|
||||
/**
|
||||
* Same as `addSegment`, but will only add the segment if it generates useful information in the
|
||||
* resulting map. This only works correctly if segments are added **in order**, meaning you should
|
||||
* not add a segment with a lower generated line/column than one that came before.
|
||||
*/
|
||||
export declare const maybeAddSegment: typeof addSegment;
|
||||
/**
|
||||
* Same as `addMapping`, but will only add the mapping if it generates useful information in the
|
||||
* resulting map. This only works correctly if mappings are added **in order**, meaning you should
|
||||
* not add a mapping with a lower generated line/column than one that came before.
|
||||
*/
|
||||
export declare const maybeAddMapping: typeof addMapping;
|
||||
/**
|
||||
* Adds/removes the content of the source file to the source map.
|
||||
*/
|
||||
export declare function setSourceContent(map: GenMapping, source: string, content: string | null): void;
|
||||
export declare function setIgnore(map: GenMapping, source: string, ignore?: boolean): void;
|
||||
/**
|
||||
* Returns a sourcemap object (with decoded mappings) suitable for passing to a library that expects
|
||||
* a sourcemap, or to JSON.stringify.
|
||||
*/
|
||||
export declare function toDecodedMap(map: GenMapping): DecodedSourceMap;
|
||||
/**
|
||||
* Returns a sourcemap object (with encoded mappings) suitable for passing to a library that expects
|
||||
* a sourcemap, or to JSON.stringify.
|
||||
*/
|
||||
export declare function toEncodedMap(map: GenMapping): EncodedSourceMap;
|
||||
/**
|
||||
* Constructs a new GenMapping, using the already present mappings of the input.
|
||||
*/
|
||||
export declare function fromMap(input: SourceMapInput): GenMapping;
|
||||
/**
|
||||
* Returns an array of high-level mapping objects for every recorded segment, which could then be
|
||||
* passed to the `source-map` library.
|
||||
*/
|
||||
export declare function allMappings(map: GenMapping): Mapping[];
|
||||
//# sourceMappingURL=gen-mapping.d.ts.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"gen-mapping.d.ts","sourceRoot":"","sources":["../src/gen-mapping.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAGhE,OAAO,KAAK,EACV,gBAAgB,EAChB,gBAAgB,EAChB,GAAG,EACH,OAAO,EAKR,MAAM,SAAS,CAAC;AAEjB,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,OAAO,EAAE,CAAC;AAE5D,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,CAAC;AAIF;;GAEG;AACH,qBAAa,UAAU;IACrB,QAAgB,MAAM,CAAmB;IACzC,QAAgB,QAAQ,CAAmB;IAC3C,QAAgB,eAAe,CAAoB;IACnD,QAAgB,SAAS,CAAuB;IAGhD,QAAgB,WAAW,CAAmB;IACtC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAChC,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;gBAElC,EAAE,IAAI,EAAE,UAAU,EAAE,GAAE,OAAY;CAW/C;AAoBD;;;GAGG;AACH,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,IAAI,EACb,UAAU,CAAC,EAAE,IAAI,EACjB,YAAY,CAAC,EAAE,IAAI,EACnB,IAAI,CAAC,EAAE,IAAI,EACX,OAAO,CAAC,EAAE,IAAI,GACb,IAAI,CAAC;AACR,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,IAAI,CAAC,EAAE,IAAI,EACX,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GACtB,IAAI,CAAC;AACR,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GACtB,IAAI,CAAC;AAwBR;;;GAGG;AACH,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE;IACP,SAAS,EAAE,GAAG,CAAC;IACf,MAAM,CAAC,EAAE,IAAI,CAAC;IACd,QAAQ,CAAC,EAAE,IAAI,CAAC;IAChB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,OAAO,CAAC,EAAE,IAAI,CAAC;CAChB,GACA,IAAI,CAAC;AACR,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE;IACP,SAAS,EAAE,GAAG,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,GAAG,CAAC;IACd,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,GACA,IAAI,CAAC;AACR,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE;IACP,SAAS,EAAE,GAAG,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,GAAG,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,GACA,IAAI,CAAC;AAcR;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,OAAO,UAqBpC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,OAAO,UAEpC,CAAC;AAEF;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAS9F;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,UAAO,QAYvE;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,UAAU,GAAG,gBAAgB,CAwB9D;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,UAAU,GAAG,gBAAgB,CAO9D;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,cAAc,GAAG,UAAU,CAYzD;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,EAAE,CA0BtD"}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
type Key = string | number | symbol;
|
||||
/**
|
||||
* SetArray acts like a `Set` (allowing only one occurrence of a string `key`), but provides the
|
||||
* index of the `key` in the backing array.
|
||||
*
|
||||
* This is designed to allow synchronizing a second array with the contents of the backing array,
|
||||
* like how in a sourcemap `sourcesContent[i]` is the source content associated with `source[i]`,
|
||||
* and there are never duplicates.
|
||||
*/
|
||||
export declare class SetArray<T extends Key = Key> {
|
||||
private _indexes;
|
||||
array: readonly T[];
|
||||
constructor();
|
||||
}
|
||||
/**
|
||||
* Gets the index associated with `key` in the backing array, if it is already present.
|
||||
*/
|
||||
export declare function get<T extends Key>(setarr: SetArray<T>, key: T): number | undefined;
|
||||
/**
|
||||
* Puts `key` into the backing array, if it is not already present. Returns
|
||||
* the index of the `key` in the backing array.
|
||||
*/
|
||||
export declare function put<T extends Key>(setarr: SetArray<T>, key: T): number;
|
||||
/**
|
||||
* Pops the last added item out of the SetArray.
|
||||
*/
|
||||
export declare function pop<T extends Key>(setarr: SetArray<T>): void;
|
||||
/**
|
||||
* Removes the key, if it exists in the set.
|
||||
*/
|
||||
export declare function remove<T extends Key>(setarr: SetArray<T>, key: T): void;
|
||||
export {};
|
||||
//# sourceMappingURL=set-array.d.ts.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"set-array.d.ts","sourceRoot":"","sources":["../src/set-array.ts"],"names":[],"mappings":"AAAA,KAAK,GAAG,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAEpC;;;;;;;GAOG;AACH,qBAAa,QAAQ,CAAC,CAAC,SAAS,GAAG,GAAG,GAAG;IACvC,QAAgB,QAAQ,CAAgC;IAChD,KAAK,EAAE,SAAS,CAAC,EAAE,CAAC;;CAM7B;AAeD;;GAEG;AACH,wBAAgB,GAAG,CAAC,CAAC,SAAS,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,MAAM,GAAG,SAAS,CAElF;AAED;;;GAGG;AACH,wBAAgB,GAAG,CAAC,CAAC,SAAS,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,MAAM,CAStE;AAED;;GAEG;AACH,wBAAgB,GAAG,CAAC,CAAC,SAAS,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,CAM5D;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,CAAC,SAAS,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,IAAI,CAYvE"}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
type Key = string | number | symbol;
|
||||
/**
|
||||
* SetArray acts like a `Set` (allowing only one occurrence of a string `key`), but provides the
|
||||
* index of the `key` in the backing array.
|
||||
*
|
||||
* This is designed to allow synchronizing a second array with the contents of the backing array,
|
||||
* like how in a sourcemap `sourcesContent[i]` is the source content associated with `source[i]`,
|
||||
* and there are never duplicates.
|
||||
*/
|
||||
export declare class SetArray<T extends Key = Key> {
|
||||
private _indexes;
|
||||
array: readonly T[];
|
||||
constructor();
|
||||
}
|
||||
/**
|
||||
* Gets the index associated with `key` in the backing array, if it is already present.
|
||||
*/
|
||||
export declare function get<T extends Key>(setarr: SetArray<T>, key: T): number | undefined;
|
||||
/**
|
||||
* Puts `key` into the backing array, if it is not already present. Returns
|
||||
* the index of the `key` in the backing array.
|
||||
*/
|
||||
export declare function put<T extends Key>(setarr: SetArray<T>, key: T): number;
|
||||
/**
|
||||
* Pops the last added item out of the SetArray.
|
||||
*/
|
||||
export declare function pop<T extends Key>(setarr: SetArray<T>): void;
|
||||
/**
|
||||
* Removes the key, if it exists in the set.
|
||||
*/
|
||||
export declare function remove<T extends Key>(setarr: SetArray<T>, key: T): void;
|
||||
export {};
|
||||
//# sourceMappingURL=set-array.d.ts.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"set-array.d.ts","sourceRoot":"","sources":["../src/set-array.ts"],"names":[],"mappings":"AAAA,KAAK,GAAG,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAEpC;;;;;;;GAOG;AACH,qBAAa,QAAQ,CAAC,CAAC,SAAS,GAAG,GAAG,GAAG;IACvC,QAAgB,QAAQ,CAAgC;IAChD,KAAK,EAAE,SAAS,CAAC,EAAE,CAAC;;CAM7B;AAeD;;GAEG;AACH,wBAAgB,GAAG,CAAC,CAAC,SAAS,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,MAAM,GAAG,SAAS,CAElF;AAED;;;GAGG;AACH,wBAAgB,GAAG,CAAC,CAAC,SAAS,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,MAAM,CAStE;AAED;;GAEG;AACH,wBAAgB,GAAG,CAAC,CAAC,SAAS,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,CAM5D;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,CAAC,SAAS,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,IAAI,CAYvE"}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
type GeneratedColumn = number;
|
||||
type SourcesIndex = number;
|
||||
type SourceLine = number;
|
||||
type SourceColumn = number;
|
||||
type NamesIndex = number;
|
||||
export type SourceMapSegment = [GeneratedColumn] | [GeneratedColumn, SourcesIndex, SourceLine, SourceColumn] | [GeneratedColumn, SourcesIndex, SourceLine, SourceColumn, NamesIndex];
|
||||
export declare const COLUMN = 0;
|
||||
export declare const SOURCES_INDEX = 1;
|
||||
export declare const SOURCE_LINE = 2;
|
||||
export declare const SOURCE_COLUMN = 3;
|
||||
export declare const NAMES_INDEX = 4;
|
||||
export {};
|
||||
//# sourceMappingURL=sourcemap-segment.d.ts.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"sourcemap-segment.d.ts","sourceRoot":"","sources":["../src/sourcemap-segment.ts"],"names":[],"mappings":"AAAA,KAAK,eAAe,GAAG,MAAM,CAAC;AAC9B,KAAK,YAAY,GAAG,MAAM,CAAC;AAC3B,KAAK,UAAU,GAAG,MAAM,CAAC;AACzB,KAAK,YAAY,GAAG,MAAM,CAAC;AAC3B,KAAK,UAAU,GAAG,MAAM,CAAC;AAEzB,MAAM,MAAM,gBAAgB,GACxB,CAAC,eAAe,CAAC,GACjB,CAAC,eAAe,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,CAAC,GACzD,CAAC,eAAe,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,CAAC,CAAC;AAE1E,eAAO,MAAM,MAAM,IAAI,CAAC;AACxB,eAAO,MAAM,aAAa,IAAI,CAAC;AAC/B,eAAO,MAAM,WAAW,IAAI,CAAC;AAC7B,eAAO,MAAM,aAAa,IAAI,CAAC;AAC/B,eAAO,MAAM,WAAW,IAAI,CAAC"}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
type GeneratedColumn = number;
|
||||
type SourcesIndex = number;
|
||||
type SourceLine = number;
|
||||
type SourceColumn = number;
|
||||
type NamesIndex = number;
|
||||
export type SourceMapSegment = [GeneratedColumn] | [GeneratedColumn, SourcesIndex, SourceLine, SourceColumn] | [GeneratedColumn, SourcesIndex, SourceLine, SourceColumn, NamesIndex];
|
||||
export declare const COLUMN = 0;
|
||||
export declare const SOURCES_INDEX = 1;
|
||||
export declare const SOURCE_LINE = 2;
|
||||
export declare const SOURCE_COLUMN = 3;
|
||||
export declare const NAMES_INDEX = 4;
|
||||
export {};
|
||||
//# sourceMappingURL=sourcemap-segment.d.ts.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"sourcemap-segment.d.ts","sourceRoot":"","sources":["../src/sourcemap-segment.ts"],"names":[],"mappings":"AAAA,KAAK,eAAe,GAAG,MAAM,CAAC;AAC9B,KAAK,YAAY,GAAG,MAAM,CAAC;AAC3B,KAAK,UAAU,GAAG,MAAM,CAAC;AACzB,KAAK,YAAY,GAAG,MAAM,CAAC;AAC3B,KAAK,UAAU,GAAG,MAAM,CAAC;AAEzB,MAAM,MAAM,gBAAgB,GACxB,CAAC,eAAe,CAAC,GACjB,CAAC,eAAe,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,CAAC,GACzD,CAAC,eAAe,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,CAAC,CAAC;AAE1E,eAAO,MAAM,MAAM,IAAI,CAAC;AACxB,eAAO,MAAM,aAAa,IAAI,CAAC;AAC/B,eAAO,MAAM,WAAW,IAAI,CAAC;AAC7B,eAAO,MAAM,aAAa,IAAI,CAAC;AAC/B,eAAO,MAAM,WAAW,IAAI,CAAC"}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
import type { SourceMapSegment } from './sourcemap-segment.cts';
|
||||
export interface SourceMapV3 {
|
||||
file?: string | null;
|
||||
names: readonly string[];
|
||||
sourceRoot?: string;
|
||||
sources: readonly (string | null)[];
|
||||
sourcesContent?: readonly (string | null)[];
|
||||
version: 3;
|
||||
ignoreList?: readonly number[];
|
||||
}
|
||||
export interface EncodedSourceMap extends SourceMapV3 {
|
||||
mappings: string;
|
||||
}
|
||||
export interface DecodedSourceMap extends SourceMapV3 {
|
||||
mappings: readonly SourceMapSegment[][];
|
||||
}
|
||||
export interface Pos {
|
||||
line: number;
|
||||
column: number;
|
||||
}
|
||||
export interface OriginalPos extends Pos {
|
||||
source: string;
|
||||
}
|
||||
export interface BindingExpressionRange {
|
||||
start: Pos;
|
||||
expression: string;
|
||||
}
|
||||
export type Mapping = {
|
||||
generated: Pos;
|
||||
source: undefined;
|
||||
original: undefined;
|
||||
name: undefined;
|
||||
} | {
|
||||
generated: Pos;
|
||||
source: string;
|
||||
original: Pos;
|
||||
name: string;
|
||||
} | {
|
||||
generated: Pos;
|
||||
source: string;
|
||||
original: Pos;
|
||||
name: undefined;
|
||||
};
|
||||
//# sourceMappingURL=types.d.ts.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE5D,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;IACpC,cAAc,CAAC,EAAE,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;IAC5C,OAAO,EAAE,CAAC,CAAC;IACX,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,gBAAiB,SAAQ,WAAW;IACnD,QAAQ,EAAE,MAAM,CAAC;CAGlB;AAED,MAAM,WAAW,gBAAiB,SAAQ,WAAW;IACnD,QAAQ,EAAE,SAAS,gBAAgB,EAAE,EAAE,CAAC;CAGzC;AAED,MAAM,WAAW,GAAG;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAY,SAAQ,GAAG;IACtC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,GAAG,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;CACpB;AAKD,MAAM,MAAM,OAAO,GACf;IACE,SAAS,EAAE,GAAG,CAAC;IACf,MAAM,EAAE,SAAS,CAAC;IAClB,QAAQ,EAAE,SAAS,CAAC;IACpB,IAAI,EAAE,SAAS,CAAC;CACjB,GACD;IACE,SAAS,EAAE,GAAG,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,GAAG,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd,GACD;IACE,SAAS,EAAE,GAAG,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,GAAG,CAAC;IACd,IAAI,EAAE,SAAS,CAAC;CACjB,CAAC"}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
import type { SourceMapSegment } from './sourcemap-segment.mts';
|
||||
export interface SourceMapV3 {
|
||||
file?: string | null;
|
||||
names: readonly string[];
|
||||
sourceRoot?: string;
|
||||
sources: readonly (string | null)[];
|
||||
sourcesContent?: readonly (string | null)[];
|
||||
version: 3;
|
||||
ignoreList?: readonly number[];
|
||||
}
|
||||
export interface EncodedSourceMap extends SourceMapV3 {
|
||||
mappings: string;
|
||||
}
|
||||
export interface DecodedSourceMap extends SourceMapV3 {
|
||||
mappings: readonly SourceMapSegment[][];
|
||||
}
|
||||
export interface Pos {
|
||||
line: number;
|
||||
column: number;
|
||||
}
|
||||
export interface OriginalPos extends Pos {
|
||||
source: string;
|
||||
}
|
||||
export interface BindingExpressionRange {
|
||||
start: Pos;
|
||||
expression: string;
|
||||
}
|
||||
export type Mapping = {
|
||||
generated: Pos;
|
||||
source: undefined;
|
||||
original: undefined;
|
||||
name: undefined;
|
||||
} | {
|
||||
generated: Pos;
|
||||
source: string;
|
||||
original: Pos;
|
||||
name: string;
|
||||
} | {
|
||||
generated: Pos;
|
||||
source: string;
|
||||
original: Pos;
|
||||
name: undefined;
|
||||
};
|
||||
//# sourceMappingURL=types.d.ts.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE5D,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;IACpC,cAAc,CAAC,EAAE,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;IAC5C,OAAO,EAAE,CAAC,CAAC;IACX,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,gBAAiB,SAAQ,WAAW;IACnD,QAAQ,EAAE,MAAM,CAAC;CAGlB;AAED,MAAM,WAAW,gBAAiB,SAAQ,WAAW;IACnD,QAAQ,EAAE,SAAS,gBAAgB,EAAE,EAAE,CAAC;CAGzC;AAED,MAAM,WAAW,GAAG;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAY,SAAQ,GAAG;IACtC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,GAAG,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;CACpB;AAKD,MAAM,MAAM,OAAO,GACf;IACE,SAAS,EAAE,GAAG,CAAC;IACf,MAAM,EAAE,SAAS,CAAC;IAClB,QAAQ,EAAE,SAAS,CAAC;IACpB,IAAI,EAAE,SAAS,CAAC;CACjB,GACD;IACE,SAAS,EAAE,GAAG,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,GAAG,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd,GACD;IACE,SAAS,EAAE,GAAG,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,GAAG,CAAC;IACd,IAAI,EAAE,SAAS,CAAC;CACjB,CAAC"}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
Copyright 2024 Justin Ridgewell <justin@ridgewell.name>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
+218
@@ -0,0 +1,218 @@
|
||||
# @jridgewell/remapping
|
||||
|
||||
> Remap sequential sourcemaps through transformations to point at the original source code
|
||||
|
||||
Remapping allows you to take the sourcemaps generated through transforming your code and "remap"
|
||||
them to the original source locations. Think "my minified code, transformed with babel and bundled
|
||||
with webpack", all pointing to the correct location in your original source code.
|
||||
|
||||
With remapping, none of your source code transformations need to be aware of the input's sourcemap,
|
||||
they only need to generate an output sourcemap. This greatly simplifies building custom
|
||||
transformations (think a find-and-replace).
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
npm install @jridgewell/remapping
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```typescript
|
||||
function remapping(
|
||||
map: SourceMap | SourceMap[],
|
||||
loader: (file: string, ctx: LoaderContext) => (SourceMap | null | undefined),
|
||||
options?: { excludeContent: boolean, decodedMappings: boolean }
|
||||
): SourceMap;
|
||||
|
||||
// LoaderContext gives the loader the importing sourcemap, tree depth, the ability to override the
|
||||
// "source" location (where child sources are resolved relative to, or the location of original
|
||||
// source), and the ability to override the "content" of an original source for inclusion in the
|
||||
// output sourcemap.
|
||||
type LoaderContext = {
|
||||
readonly importer: string;
|
||||
readonly depth: number;
|
||||
source: string;
|
||||
content: string | null | undefined;
|
||||
}
|
||||
```
|
||||
|
||||
`remapping` takes the final output sourcemap, and a `loader` function. For every source file pointer
|
||||
in the sourcemap, the `loader` will be called with the resolved path. If the path itself represents
|
||||
a transformed file (it has a sourcmap associated with it), then the `loader` should return that
|
||||
sourcemap. If not, the path will be treated as an original, untransformed source code.
|
||||
|
||||
```js
|
||||
// Babel transformed "helloworld.js" into "transformed.js"
|
||||
const transformedMap = JSON.stringify({
|
||||
file: 'transformed.js',
|
||||
// 1st column of 2nd line of output file translates into the 1st source
|
||||
// file, line 3, column 2
|
||||
mappings: ';CAEE',
|
||||
sources: ['helloworld.js'],
|
||||
version: 3,
|
||||
});
|
||||
|
||||
// Uglify minified "transformed.js" into "transformed.min.js"
|
||||
const minifiedTransformedMap = JSON.stringify({
|
||||
file: 'transformed.min.js',
|
||||
// 0th column of 1st line of output file translates into the 1st source
|
||||
// file, line 2, column 1.
|
||||
mappings: 'AACC',
|
||||
names: [],
|
||||
sources: ['transformed.js'],
|
||||
version: 3,
|
||||
});
|
||||
|
||||
const remapped = remapping(
|
||||
minifiedTransformedMap,
|
||||
(file, ctx) => {
|
||||
|
||||
// The "transformed.js" file is an transformed file.
|
||||
if (file === 'transformed.js') {
|
||||
// The root importer is empty.
|
||||
console.assert(ctx.importer === '');
|
||||
// The depth in the sourcemap tree we're currently loading.
|
||||
// The root `minifiedTransformedMap` is depth 0, and its source children are depth 1, etc.
|
||||
console.assert(ctx.depth === 1);
|
||||
|
||||
return transformedMap;
|
||||
}
|
||||
|
||||
// Loader will be called to load transformedMap's source file pointers as well.
|
||||
console.assert(file === 'helloworld.js');
|
||||
// `transformed.js`'s sourcemap points into `helloworld.js`.
|
||||
console.assert(ctx.importer === 'transformed.js');
|
||||
// This is a source child of `transformed`, which is a source child of `minifiedTransformedMap`.
|
||||
console.assert(ctx.depth === 2);
|
||||
return null;
|
||||
}
|
||||
);
|
||||
|
||||
console.log(remapped);
|
||||
// {
|
||||
// file: 'transpiled.min.js',
|
||||
// mappings: 'AAEE',
|
||||
// sources: ['helloworld.js'],
|
||||
// version: 3,
|
||||
// };
|
||||
```
|
||||
|
||||
In this example, `loader` will be called twice:
|
||||
|
||||
1. `"transformed.js"`, the first source file pointer in the `minifiedTransformedMap`. We return the
|
||||
associated sourcemap for it (its a transformed file, after all) so that sourcemap locations can
|
||||
be traced through it into the source files it represents.
|
||||
2. `"helloworld.js"`, our original, unmodified source code. This file does not have a sourcemap, so
|
||||
we return `null`.
|
||||
|
||||
The `remapped` sourcemap now points from `transformed.min.js` into locations in `helloworld.js`. If
|
||||
you were to read the `mappings`, it says "0th column of the first line output line points to the 1st
|
||||
column of the 2nd line of the file `helloworld.js`".
|
||||
|
||||
### Multiple transformations of a file
|
||||
|
||||
As a convenience, if you have multiple single-source transformations of a file, you may pass an
|
||||
array of sourcemap files in the order of most-recent transformation sourcemap first. Note that this
|
||||
changes the `importer` and `depth` of each call to our loader. So our above example could have been
|
||||
written as:
|
||||
|
||||
```js
|
||||
const remapped = remapping(
|
||||
[minifiedTransformedMap, transformedMap],
|
||||
() => null
|
||||
);
|
||||
|
||||
console.log(remapped);
|
||||
// {
|
||||
// file: 'transpiled.min.js',
|
||||
// mappings: 'AAEE',
|
||||
// sources: ['helloworld.js'],
|
||||
// version: 3,
|
||||
// };
|
||||
```
|
||||
|
||||
### Advanced control of the loading graph
|
||||
|
||||
#### `source`
|
||||
|
||||
The `source` property can overridden to any value to change the location of the current load. Eg,
|
||||
for an original source file, it allows us to change the location to the original source regardless
|
||||
of what the sourcemap source entry says. And for transformed files, it allows us to change the
|
||||
relative resolving location for child sources of the loaded sourcemap.
|
||||
|
||||
```js
|
||||
const remapped = remapping(
|
||||
minifiedTransformedMap,
|
||||
(file, ctx) => {
|
||||
|
||||
if (file === 'transformed.js') {
|
||||
// We pretend the transformed.js file actually exists in the 'src/' directory. When the nested
|
||||
// source files are loaded, they will now be relative to `src/`.
|
||||
ctx.source = 'src/transformed.js';
|
||||
return transformedMap;
|
||||
}
|
||||
|
||||
console.assert(file === 'src/helloworld.js');
|
||||
// We could futher change the source of this original file, eg, to be inside a nested directory
|
||||
// itself. This will be reflected in the remapped sourcemap.
|
||||
ctx.source = 'src/nested/transformed.js';
|
||||
return null;
|
||||
}
|
||||
);
|
||||
|
||||
console.log(remapped);
|
||||
// {
|
||||
// …,
|
||||
// sources: ['src/nested/helloworld.js'],
|
||||
// };
|
||||
```
|
||||
|
||||
|
||||
#### `content`
|
||||
|
||||
The `content` property can be overridden when we encounter an original source file. Eg, this allows
|
||||
you to manually provide the source content of the original file regardless of whether the
|
||||
`sourcesContent` field is present in the parent sourcemap. It can also be set to `null` to remove
|
||||
the source content.
|
||||
|
||||
```js
|
||||
const remapped = remapping(
|
||||
minifiedTransformedMap,
|
||||
(file, ctx) => {
|
||||
|
||||
if (file === 'transformed.js') {
|
||||
// transformedMap does not include a `sourcesContent` field, so usually the remapped sourcemap
|
||||
// would not include any `sourcesContent` values.
|
||||
return transformedMap;
|
||||
}
|
||||
|
||||
console.assert(file === 'helloworld.js');
|
||||
// We can read the file to provide the source content.
|
||||
ctx.content = fs.readFileSync(file, 'utf8');
|
||||
return null;
|
||||
}
|
||||
);
|
||||
|
||||
console.log(remapped);
|
||||
// {
|
||||
// …,
|
||||
// sourcesContent: [
|
||||
// 'console.log("Hello world!")',
|
||||
// ],
|
||||
// };
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
#### excludeContent
|
||||
|
||||
By default, `excludeContent` is `false`. Passing `{ excludeContent: true }` will exclude the
|
||||
`sourcesContent` field from the returned sourcemap. This is mainly useful when you want to reduce
|
||||
the size out the sourcemap.
|
||||
|
||||
#### decodedMappings
|
||||
|
||||
By default, `decodedMappings` is `false`. Passing `{ decodedMappings: true }` will leave the
|
||||
`mappings` field in a [decoded state](https://github.com/rich-harris/sourcemap-codec) instead of
|
||||
encoding into a VLQ string.
|
||||
+144
@@ -0,0 +1,144 @@
|
||||
// src/build-source-map-tree.ts
|
||||
import { TraceMap } from "@jridgewell/trace-mapping";
|
||||
|
||||
// src/source-map-tree.ts
|
||||
import { GenMapping, maybeAddSegment, setIgnore, setSourceContent } from "@jridgewell/gen-mapping";
|
||||
import { traceSegment, decodedMappings } from "@jridgewell/trace-mapping";
|
||||
var SOURCELESS_MAPPING = /* @__PURE__ */ SegmentObject("", -1, -1, "", null, false);
|
||||
var EMPTY_SOURCES = [];
|
||||
function SegmentObject(source, line, column, name, content, ignore) {
|
||||
return { source, line, column, name, content, ignore };
|
||||
}
|
||||
function Source(map, sources, source, content, ignore) {
|
||||
return {
|
||||
map,
|
||||
sources,
|
||||
source,
|
||||
content,
|
||||
ignore
|
||||
};
|
||||
}
|
||||
function MapSource(map, sources) {
|
||||
return Source(map, sources, "", null, false);
|
||||
}
|
||||
function OriginalSource(source, content, ignore) {
|
||||
return Source(null, EMPTY_SOURCES, source, content, ignore);
|
||||
}
|
||||
function traceMappings(tree) {
|
||||
const gen = new GenMapping({ file: tree.map.file });
|
||||
const { sources: rootSources, map } = tree;
|
||||
const rootNames = map.names;
|
||||
const rootMappings = decodedMappings(map);
|
||||
for (let i = 0; i < rootMappings.length; i++) {
|
||||
const segments = rootMappings[i];
|
||||
for (let j = 0; j < segments.length; j++) {
|
||||
const segment = segments[j];
|
||||
const genCol = segment[0];
|
||||
let traced = SOURCELESS_MAPPING;
|
||||
if (segment.length !== 1) {
|
||||
const source2 = rootSources[segment[1]];
|
||||
traced = originalPositionFor(
|
||||
source2,
|
||||
segment[2],
|
||||
segment[3],
|
||||
segment.length === 5 ? rootNames[segment[4]] : ""
|
||||
);
|
||||
if (traced == null) continue;
|
||||
}
|
||||
const { column, line, name, content, source, ignore } = traced;
|
||||
maybeAddSegment(gen, i, genCol, source, line, column, name);
|
||||
if (source && content != null) setSourceContent(gen, source, content);
|
||||
if (ignore) setIgnore(gen, source, true);
|
||||
}
|
||||
}
|
||||
return gen;
|
||||
}
|
||||
function originalPositionFor(source, line, column, name) {
|
||||
if (!source.map) {
|
||||
return SegmentObject(source.source, line, column, name, source.content, source.ignore);
|
||||
}
|
||||
const segment = traceSegment(source.map, line, column);
|
||||
if (segment == null) return null;
|
||||
if (segment.length === 1) return SOURCELESS_MAPPING;
|
||||
return originalPositionFor(
|
||||
source.sources[segment[1]],
|
||||
segment[2],
|
||||
segment[3],
|
||||
segment.length === 5 ? source.map.names[segment[4]] : name
|
||||
);
|
||||
}
|
||||
|
||||
// src/build-source-map-tree.ts
|
||||
function asArray(value) {
|
||||
if (Array.isArray(value)) return value;
|
||||
return [value];
|
||||
}
|
||||
function buildSourceMapTree(input, loader) {
|
||||
const maps = asArray(input).map((m) => new TraceMap(m, ""));
|
||||
const map = maps.pop();
|
||||
for (let i = 0; i < maps.length; i++) {
|
||||
if (maps[i].sources.length > 1) {
|
||||
throw new Error(
|
||||
`Transformation map ${i} must have exactly one source file.
|
||||
Did you specify these with the most recent transformation maps first?`
|
||||
);
|
||||
}
|
||||
}
|
||||
let tree = build(map, loader, "", 0);
|
||||
for (let i = maps.length - 1; i >= 0; i--) {
|
||||
tree = MapSource(maps[i], [tree]);
|
||||
}
|
||||
return tree;
|
||||
}
|
||||
function build(map, loader, importer, importerDepth) {
|
||||
const { resolvedSources, sourcesContent, ignoreList } = map;
|
||||
const depth = importerDepth + 1;
|
||||
const children = resolvedSources.map((sourceFile, i) => {
|
||||
const ctx = {
|
||||
importer,
|
||||
depth,
|
||||
source: sourceFile || "",
|
||||
content: void 0,
|
||||
ignore: void 0
|
||||
};
|
||||
const sourceMap = loader(ctx.source, ctx);
|
||||
const { source, content, ignore } = ctx;
|
||||
if (sourceMap) return build(new TraceMap(sourceMap, source), loader, source, depth);
|
||||
const sourceContent = content !== void 0 ? content : sourcesContent ? sourcesContent[i] : null;
|
||||
const ignored = ignore !== void 0 ? ignore : ignoreList ? ignoreList.includes(i) : false;
|
||||
return OriginalSource(source, sourceContent, ignored);
|
||||
});
|
||||
return MapSource(map, children);
|
||||
}
|
||||
|
||||
// src/source-map.ts
|
||||
import { toDecodedMap, toEncodedMap } from "@jridgewell/gen-mapping";
|
||||
var SourceMap = class {
|
||||
constructor(map, options) {
|
||||
const out = options.decodedMappings ? toDecodedMap(map) : toEncodedMap(map);
|
||||
this.version = out.version;
|
||||
this.file = out.file;
|
||||
this.mappings = out.mappings;
|
||||
this.names = out.names;
|
||||
this.ignoreList = out.ignoreList;
|
||||
this.sourceRoot = out.sourceRoot;
|
||||
this.sources = out.sources;
|
||||
if (!options.excludeContent) {
|
||||
this.sourcesContent = out.sourcesContent;
|
||||
}
|
||||
}
|
||||
toString() {
|
||||
return JSON.stringify(this);
|
||||
}
|
||||
};
|
||||
|
||||
// src/remapping.ts
|
||||
function remapping(input, loader, options) {
|
||||
const opts = typeof options === "object" ? options : { excludeContent: !!options, decodedMappings: false };
|
||||
const tree = buildSourceMapTree(input, loader);
|
||||
return new SourceMap(traceMappings(tree), opts);
|
||||
}
|
||||
export {
|
||||
remapping as default
|
||||
};
|
||||
//# sourceMappingURL=remapping.mjs.map
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": ["../src/build-source-map-tree.ts", "../src/source-map-tree.ts", "../src/source-map.ts", "../src/remapping.ts"],
|
||||
"mappings": ";AAAA,SAAS,gBAAgB;;;ACAzB,SAAS,YAAY,iBAAiB,WAAW,wBAAwB;AACzE,SAAS,cAAc,uBAAuB;AA+B9C,IAAM,qBAAqC,8BAAc,IAAI,IAAI,IAAI,IAAI,MAAM,KAAK;AACpF,IAAM,gBAA2B,CAAC;AAElC,SAAS,cACP,QACA,MACA,QACA,MACA,SACA,QACwB;AACxB,SAAO,EAAE,QAAQ,MAAM,QAAQ,MAAM,SAAS,OAAO;AACvD;AAgBA,SAAS,OACP,KACA,SACA,QACA,SACA,QACS;AACT,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAMO,SAAS,UAAU,KAAe,SAA+B;AACtE,SAAO,OAAO,KAAK,SAAS,IAAI,MAAM,KAAK;AAC7C;AAMO,SAAS,eACd,QACA,SACA,QACgB;AAChB,SAAO,OAAO,MAAM,eAAe,QAAQ,SAAS,MAAM;AAC5D;AAMO,SAAS,cAAc,MAA6B;AAGzD,QAAM,MAAM,IAAI,WAAW,EAAE,MAAM,KAAK,IAAI,KAAK,CAAC;AAClD,QAAM,EAAE,SAAS,aAAa,IAAI,IAAI;AACtC,QAAM,YAAY,IAAI;AACtB,QAAM,eAAe,gBAAgB,GAAG;AAExC,WAAS,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;AAC5C,UAAM,WAAW,aAAa,CAAC;AAE/B,aAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACxC,YAAM,UAAU,SAAS,CAAC;AAC1B,YAAM,SAAS,QAAQ,CAAC;AACxB,UAAI,SAAwC;AAI5C,UAAI,QAAQ,WAAW,GAAG;AACxB,cAAMA,UAAS,YAAY,QAAQ,CAAC,CAAC;AACrC,iBAAS;AAAA,UACPA;AAAA,UACA,QAAQ,CAAC;AAAA,UACT,QAAQ,CAAC;AAAA,UACT,QAAQ,WAAW,IAAI,UAAU,QAAQ,CAAC,CAAC,IAAI;AAAA,QACjD;AAIA,YAAI,UAAU,KAAM;AAAA,MACtB;AAEA,YAAM,EAAE,QAAQ,MAAM,MAAM,SAAS,QAAQ,OAAO,IAAI;AAExD,sBAAgB,KAAK,GAAG,QAAQ,QAAQ,MAAM,QAAQ,IAAI;AAC1D,UAAI,UAAU,WAAW,KAAM,kBAAiB,KAAK,QAAQ,OAAO;AACpE,UAAI,OAAQ,WAAU,KAAK,QAAQ,IAAI;AAAA,IACzC;AAAA,EACF;AAEA,SAAO;AACT;AAMO,SAAS,oBACd,QACA,MACA,QACA,MAC+B;AAC/B,MAAI,CAAC,OAAO,KAAK;AACf,WAAO,cAAc,OAAO,QAAQ,MAAM,QAAQ,MAAM,OAAO,SAAS,OAAO,MAAM;AAAA,EACvF;AAEA,QAAM,UAAU,aAAa,OAAO,KAAK,MAAM,MAAM;AAGrD,MAAI,WAAW,KAAM,QAAO;AAG5B,MAAI,QAAQ,WAAW,EAAG,QAAO;AAEjC,SAAO;AAAA,IACL,OAAO,QAAQ,QAAQ,CAAC,CAAC;AAAA,IACzB,QAAQ,CAAC;AAAA,IACT,QAAQ,CAAC;AAAA,IACT,QAAQ,WAAW,IAAI,OAAO,IAAI,MAAM,QAAQ,CAAC,CAAC,IAAI;AAAA,EACxD;AACF;;;ADpKA,SAAS,QAAW,OAAqB;AACvC,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO;AACjC,SAAO,CAAC,KAAK;AACf;AAae,SAAR,mBACL,OACA,QACe;AACf,QAAM,OAAO,QAAQ,KAAK,EAAE,IAAI,CAAC,MAAM,IAAI,SAAS,GAAG,EAAE,CAAC;AAC1D,QAAM,MAAM,KAAK,IAAI;AAErB,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,QAAI,KAAK,CAAC,EAAE,QAAQ,SAAS,GAAG;AAC9B,YAAM,IAAI;AAAA,QACR,sBAAsB,CAAC;AAAA;AAAA,MAEzB;AAAA,IACF;AAAA,EACF;AAEA,MAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC;AACnC,WAAS,IAAI,KAAK,SAAS,GAAG,KAAK,GAAG,KAAK;AACzC,WAAO,UAAU,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;AAAA,EAClC;AACA,SAAO;AACT;AAEA,SAAS,MACP,KACA,QACA,UACA,eACe;AACf,QAAM,EAAE,iBAAiB,gBAAgB,WAAW,IAAI;AAExD,QAAM,QAAQ,gBAAgB;AAC9B,QAAM,WAAW,gBAAgB,IAAI,CAAC,YAA2B,MAAuB;AAKtF,UAAM,MAAqB;AAAA,MACzB;AAAA,MACA;AAAA,MACA,QAAQ,cAAc;AAAA,MACtB,SAAS;AAAA,MACT,QAAQ;AAAA,IACV;AAIA,UAAM,YAAY,OAAO,IAAI,QAAQ,GAAG;AAExC,UAAM,EAAE,QAAQ,SAAS,OAAO,IAAI;AAGpC,QAAI,UAAW,QAAO,MAAM,IAAI,SAAS,WAAW,MAAM,GAAG,QAAQ,QAAQ,KAAK;AAMlF,UAAM,gBACJ,YAAY,SAAY,UAAU,iBAAiB,eAAe,CAAC,IAAI;AACzE,UAAM,UAAU,WAAW,SAAY,SAAS,aAAa,WAAW,SAAS,CAAC,IAAI;AACtF,WAAO,eAAe,QAAQ,eAAe,OAAO;AAAA,EACtD,CAAC;AAED,SAAO,UAAU,KAAK,QAAQ;AAChC;;;AExFA,SAAS,cAAc,oBAAoB;AAS3C,IAAqB,YAArB,MAA+B;AAAA,EAU7B,YAAY,KAAiB,SAAkB;AAC7C,UAAM,MAAM,QAAQ,kBAAkB,aAAa,GAAG,IAAI,aAAa,GAAG;AAC1E,SAAK,UAAU,IAAI;AACnB,SAAK,OAAO,IAAI;AAChB,SAAK,WAAW,IAAI;AACpB,SAAK,QAAQ,IAAI;AACjB,SAAK,aAAa,IAAI;AACtB,SAAK,aAAa,IAAI;AAEtB,SAAK,UAAU,IAAI;AACnB,QAAI,CAAC,QAAQ,gBAAgB;AAC3B,WAAK,iBAAiB,IAAI;AAAA,IAC5B;AAAA,EACF;AAAA,EAEA,WAAmB;AACjB,WAAO,KAAK,UAAU,IAAI;AAAA,EAC5B;AACF;;;ACLe,SAAR,UACL,OACA,QACA,SACW;AACX,QAAM,OACJ,OAAO,YAAY,WAAW,UAAU,EAAE,gBAAgB,CAAC,CAAC,SAAS,iBAAiB,MAAM;AAC9F,QAAM,OAAO,mBAAmB,OAAO,MAAM;AAC7C,SAAO,IAAI,UAAU,cAAc,IAAI,GAAG,IAAI;AAChD;",
|
||||
"names": ["source"]
|
||||
}
|
||||
+212
@@ -0,0 +1,212 @@
|
||||
(function (global, factory) {
|
||||
if (typeof exports === 'object' && typeof module !== 'undefined') {
|
||||
factory(module, require('@jridgewell/gen-mapping'), require('@jridgewell/trace-mapping'));
|
||||
module.exports = def(module);
|
||||
} else if (typeof define === 'function' && define.amd) {
|
||||
define(['module', '@jridgewell/gen-mapping', '@jridgewell/trace-mapping'], function(mod) {
|
||||
factory.apply(this, arguments);
|
||||
mod.exports = def(mod);
|
||||
});
|
||||
} else {
|
||||
const mod = { exports: {} };
|
||||
factory(mod, global.genMapping, global.traceMapping);
|
||||
global = typeof globalThis !== 'undefined' ? globalThis : global || self;
|
||||
global.remapping = def(mod);
|
||||
}
|
||||
function def(m) { return 'default' in m.exports ? m.exports.default : m.exports; }
|
||||
})(this, (function (module, require_genMapping, require_traceMapping) {
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __commonJS = (cb, mod) => function __require() {
|
||||
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
||||
};
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// umd:@jridgewell/trace-mapping
|
||||
var require_trace_mapping = __commonJS({
|
||||
"umd:@jridgewell/trace-mapping"(exports, module2) {
|
||||
module2.exports = require_traceMapping;
|
||||
}
|
||||
});
|
||||
|
||||
// umd:@jridgewell/gen-mapping
|
||||
var require_gen_mapping = __commonJS({
|
||||
"umd:@jridgewell/gen-mapping"(exports, module2) {
|
||||
module2.exports = require_genMapping;
|
||||
}
|
||||
});
|
||||
|
||||
// src/remapping.ts
|
||||
var remapping_exports = {};
|
||||
__export(remapping_exports, {
|
||||
default: () => remapping
|
||||
});
|
||||
module.exports = __toCommonJS(remapping_exports);
|
||||
|
||||
// src/build-source-map-tree.ts
|
||||
var import_trace_mapping2 = __toESM(require_trace_mapping());
|
||||
|
||||
// src/source-map-tree.ts
|
||||
var import_gen_mapping = __toESM(require_gen_mapping());
|
||||
var import_trace_mapping = __toESM(require_trace_mapping());
|
||||
var SOURCELESS_MAPPING = /* @__PURE__ */ SegmentObject("", -1, -1, "", null, false);
|
||||
var EMPTY_SOURCES = [];
|
||||
function SegmentObject(source, line, column, name, content, ignore) {
|
||||
return { source, line, column, name, content, ignore };
|
||||
}
|
||||
function Source(map, sources, source, content, ignore) {
|
||||
return {
|
||||
map,
|
||||
sources,
|
||||
source,
|
||||
content,
|
||||
ignore
|
||||
};
|
||||
}
|
||||
function MapSource(map, sources) {
|
||||
return Source(map, sources, "", null, false);
|
||||
}
|
||||
function OriginalSource(source, content, ignore) {
|
||||
return Source(null, EMPTY_SOURCES, source, content, ignore);
|
||||
}
|
||||
function traceMappings(tree) {
|
||||
const gen = new import_gen_mapping.GenMapping({ file: tree.map.file });
|
||||
const { sources: rootSources, map } = tree;
|
||||
const rootNames = map.names;
|
||||
const rootMappings = (0, import_trace_mapping.decodedMappings)(map);
|
||||
for (let i = 0; i < rootMappings.length; i++) {
|
||||
const segments = rootMappings[i];
|
||||
for (let j = 0; j < segments.length; j++) {
|
||||
const segment = segments[j];
|
||||
const genCol = segment[0];
|
||||
let traced = SOURCELESS_MAPPING;
|
||||
if (segment.length !== 1) {
|
||||
const source2 = rootSources[segment[1]];
|
||||
traced = originalPositionFor(
|
||||
source2,
|
||||
segment[2],
|
||||
segment[3],
|
||||
segment.length === 5 ? rootNames[segment[4]] : ""
|
||||
);
|
||||
if (traced == null) continue;
|
||||
}
|
||||
const { column, line, name, content, source, ignore } = traced;
|
||||
(0, import_gen_mapping.maybeAddSegment)(gen, i, genCol, source, line, column, name);
|
||||
if (source && content != null) (0, import_gen_mapping.setSourceContent)(gen, source, content);
|
||||
if (ignore) (0, import_gen_mapping.setIgnore)(gen, source, true);
|
||||
}
|
||||
}
|
||||
return gen;
|
||||
}
|
||||
function originalPositionFor(source, line, column, name) {
|
||||
if (!source.map) {
|
||||
return SegmentObject(source.source, line, column, name, source.content, source.ignore);
|
||||
}
|
||||
const segment = (0, import_trace_mapping.traceSegment)(source.map, line, column);
|
||||
if (segment == null) return null;
|
||||
if (segment.length === 1) return SOURCELESS_MAPPING;
|
||||
return originalPositionFor(
|
||||
source.sources[segment[1]],
|
||||
segment[2],
|
||||
segment[3],
|
||||
segment.length === 5 ? source.map.names[segment[4]] : name
|
||||
);
|
||||
}
|
||||
|
||||
// src/build-source-map-tree.ts
|
||||
function asArray(value) {
|
||||
if (Array.isArray(value)) return value;
|
||||
return [value];
|
||||
}
|
||||
function buildSourceMapTree(input, loader) {
|
||||
const maps = asArray(input).map((m) => new import_trace_mapping2.TraceMap(m, ""));
|
||||
const map = maps.pop();
|
||||
for (let i = 0; i < maps.length; i++) {
|
||||
if (maps[i].sources.length > 1) {
|
||||
throw new Error(
|
||||
`Transformation map ${i} must have exactly one source file.
|
||||
Did you specify these with the most recent transformation maps first?`
|
||||
);
|
||||
}
|
||||
}
|
||||
let tree = build(map, loader, "", 0);
|
||||
for (let i = maps.length - 1; i >= 0; i--) {
|
||||
tree = MapSource(maps[i], [tree]);
|
||||
}
|
||||
return tree;
|
||||
}
|
||||
function build(map, loader, importer, importerDepth) {
|
||||
const { resolvedSources, sourcesContent, ignoreList } = map;
|
||||
const depth = importerDepth + 1;
|
||||
const children = resolvedSources.map((sourceFile, i) => {
|
||||
const ctx = {
|
||||
importer,
|
||||
depth,
|
||||
source: sourceFile || "",
|
||||
content: void 0,
|
||||
ignore: void 0
|
||||
};
|
||||
const sourceMap = loader(ctx.source, ctx);
|
||||
const { source, content, ignore } = ctx;
|
||||
if (sourceMap) return build(new import_trace_mapping2.TraceMap(sourceMap, source), loader, source, depth);
|
||||
const sourceContent = content !== void 0 ? content : sourcesContent ? sourcesContent[i] : null;
|
||||
const ignored = ignore !== void 0 ? ignore : ignoreList ? ignoreList.includes(i) : false;
|
||||
return OriginalSource(source, sourceContent, ignored);
|
||||
});
|
||||
return MapSource(map, children);
|
||||
}
|
||||
|
||||
// src/source-map.ts
|
||||
var import_gen_mapping2 = __toESM(require_gen_mapping());
|
||||
var SourceMap = class {
|
||||
constructor(map, options) {
|
||||
const out = options.decodedMappings ? (0, import_gen_mapping2.toDecodedMap)(map) : (0, import_gen_mapping2.toEncodedMap)(map);
|
||||
this.version = out.version;
|
||||
this.file = out.file;
|
||||
this.mappings = out.mappings;
|
||||
this.names = out.names;
|
||||
this.ignoreList = out.ignoreList;
|
||||
this.sourceRoot = out.sourceRoot;
|
||||
this.sources = out.sources;
|
||||
if (!options.excludeContent) {
|
||||
this.sourcesContent = out.sourcesContent;
|
||||
}
|
||||
}
|
||||
toString() {
|
||||
return JSON.stringify(this);
|
||||
}
|
||||
};
|
||||
|
||||
// src/remapping.ts
|
||||
function remapping(input, loader, options) {
|
||||
const opts = typeof options === "object" ? options : { excludeContent: !!options, decodedMappings: false };
|
||||
const tree = buildSourceMapTree(input, loader);
|
||||
return new SourceMap(traceMappings(tree), opts);
|
||||
}
|
||||
}));
|
||||
//# sourceMappingURL=remapping.umd.js.map
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": ["umd:@jridgewell/trace-mapping", "umd:@jridgewell/gen-mapping", "../src/remapping.ts", "../src/build-source-map-tree.ts", "../src/source-map-tree.ts", "../src/source-map.ts"],
|
||||
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA,2CAAAA,SAAA;AAAA,IAAAA,QAAO,UAAU;AAAA;AAAA;;;ACAjB;AAAA,yCAAAC,SAAA;AAAA,IAAAA,QAAO,UAAU;AAAA;AAAA;;;ACAjB;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAAAC,wBAAyB;;;ACAzB,yBAAyE;AACzE,2BAA8C;AA+B9C,IAAM,qBAAqC,8BAAc,IAAI,IAAI,IAAI,IAAI,MAAM,KAAK;AACpF,IAAM,gBAA2B,CAAC;AAElC,SAAS,cACP,QACA,MACA,QACA,MACA,SACA,QACwB;AACxB,SAAO,EAAE,QAAQ,MAAM,QAAQ,MAAM,SAAS,OAAO;AACvD;AAgBA,SAAS,OACP,KACA,SACA,QACA,SACA,QACS;AACT,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAMO,SAAS,UAAU,KAAe,SAA+B;AACtE,SAAO,OAAO,KAAK,SAAS,IAAI,MAAM,KAAK;AAC7C;AAMO,SAAS,eACd,QACA,SACA,QACgB;AAChB,SAAO,OAAO,MAAM,eAAe,QAAQ,SAAS,MAAM;AAC5D;AAMO,SAAS,cAAc,MAA6B;AAGzD,QAAM,MAAM,IAAI,8BAAW,EAAE,MAAM,KAAK,IAAI,KAAK,CAAC;AAClD,QAAM,EAAE,SAAS,aAAa,IAAI,IAAI;AACtC,QAAM,YAAY,IAAI;AACtB,QAAM,mBAAe,sCAAgB,GAAG;AAExC,WAAS,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;AAC5C,UAAM,WAAW,aAAa,CAAC;AAE/B,aAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACxC,YAAM,UAAU,SAAS,CAAC;AAC1B,YAAM,SAAS,QAAQ,CAAC;AACxB,UAAI,SAAwC;AAI5C,UAAI,QAAQ,WAAW,GAAG;AACxB,cAAMC,UAAS,YAAY,QAAQ,CAAC,CAAC;AACrC,iBAAS;AAAA,UACPA;AAAA,UACA,QAAQ,CAAC;AAAA,UACT,QAAQ,CAAC;AAAA,UACT,QAAQ,WAAW,IAAI,UAAU,QAAQ,CAAC,CAAC,IAAI;AAAA,QACjD;AAIA,YAAI,UAAU,KAAM;AAAA,MACtB;AAEA,YAAM,EAAE,QAAQ,MAAM,MAAM,SAAS,QAAQ,OAAO,IAAI;AAExD,8CAAgB,KAAK,GAAG,QAAQ,QAAQ,MAAM,QAAQ,IAAI;AAC1D,UAAI,UAAU,WAAW,KAAM,0CAAiB,KAAK,QAAQ,OAAO;AACpE,UAAI,OAAQ,mCAAU,KAAK,QAAQ,IAAI;AAAA,IACzC;AAAA,EACF;AAEA,SAAO;AACT;AAMO,SAAS,oBACd,QACA,MACA,QACA,MAC+B;AAC/B,MAAI,CAAC,OAAO,KAAK;AACf,WAAO,cAAc,OAAO,QAAQ,MAAM,QAAQ,MAAM,OAAO,SAAS,OAAO,MAAM;AAAA,EACvF;AAEA,QAAM,cAAU,mCAAa,OAAO,KAAK,MAAM,MAAM;AAGrD,MAAI,WAAW,KAAM,QAAO;AAG5B,MAAI,QAAQ,WAAW,EAAG,QAAO;AAEjC,SAAO;AAAA,IACL,OAAO,QAAQ,QAAQ,CAAC,CAAC;AAAA,IACzB,QAAQ,CAAC;AAAA,IACT,QAAQ,CAAC;AAAA,IACT,QAAQ,WAAW,IAAI,OAAO,IAAI,MAAM,QAAQ,CAAC,CAAC,IAAI;AAAA,EACxD;AACF;;;ADpKA,SAAS,QAAW,OAAqB;AACvC,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO;AACjC,SAAO,CAAC,KAAK;AACf;AAae,SAAR,mBACL,OACA,QACe;AACf,QAAM,OAAO,QAAQ,KAAK,EAAE,IAAI,CAAC,MAAM,IAAI,+BAAS,GAAG,EAAE,CAAC;AAC1D,QAAM,MAAM,KAAK,IAAI;AAErB,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,QAAI,KAAK,CAAC,EAAE,QAAQ,SAAS,GAAG;AAC9B,YAAM,IAAI;AAAA,QACR,sBAAsB,CAAC;AAAA;AAAA,MAEzB;AAAA,IACF;AAAA,EACF;AAEA,MAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC;AACnC,WAAS,IAAI,KAAK,SAAS,GAAG,KAAK,GAAG,KAAK;AACzC,WAAO,UAAU,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;AAAA,EAClC;AACA,SAAO;AACT;AAEA,SAAS,MACP,KACA,QACA,UACA,eACe;AACf,QAAM,EAAE,iBAAiB,gBAAgB,WAAW,IAAI;AAExD,QAAM,QAAQ,gBAAgB;AAC9B,QAAM,WAAW,gBAAgB,IAAI,CAAC,YAA2B,MAAuB;AAKtF,UAAM,MAAqB;AAAA,MACzB;AAAA,MACA;AAAA,MACA,QAAQ,cAAc;AAAA,MACtB,SAAS;AAAA,MACT,QAAQ;AAAA,IACV;AAIA,UAAM,YAAY,OAAO,IAAI,QAAQ,GAAG;AAExC,UAAM,EAAE,QAAQ,SAAS,OAAO,IAAI;AAGpC,QAAI,UAAW,QAAO,MAAM,IAAI,+BAAS,WAAW,MAAM,GAAG,QAAQ,QAAQ,KAAK;AAMlF,UAAM,gBACJ,YAAY,SAAY,UAAU,iBAAiB,eAAe,CAAC,IAAI;AACzE,UAAM,UAAU,WAAW,SAAY,SAAS,aAAa,WAAW,SAAS,CAAC,IAAI;AACtF,WAAO,eAAe,QAAQ,eAAe,OAAO;AAAA,EACtD,CAAC;AAED,SAAO,UAAU,KAAK,QAAQ;AAChC;;;AExFA,IAAAC,sBAA2C;AAS3C,IAAqB,YAArB,MAA+B;AAAA,EAU7B,YAAY,KAAiB,SAAkB;AAC7C,UAAM,MAAM,QAAQ,sBAAkB,kCAAa,GAAG,QAAI,kCAAa,GAAG;AAC1E,SAAK,UAAU,IAAI;AACnB,SAAK,OAAO,IAAI;AAChB,SAAK,WAAW,IAAI;AACpB,SAAK,QAAQ,IAAI;AACjB,SAAK,aAAa,IAAI;AACtB,SAAK,aAAa,IAAI;AAEtB,SAAK,UAAU,IAAI;AACnB,QAAI,CAAC,QAAQ,gBAAgB;AAC3B,WAAK,iBAAiB,IAAI;AAAA,IAC5B;AAAA,EACF;AAAA,EAEA,WAAmB;AACjB,WAAO,KAAK,UAAU,IAAI;AAAA,EAC5B;AACF;;;AHLe,SAAR,UACL,OACA,QACA,SACW;AACX,QAAM,OACJ,OAAO,YAAY,WAAW,UAAU,EAAE,gBAAgB,CAAC,CAAC,SAAS,iBAAiB,MAAM;AAC9F,QAAM,OAAO,mBAAmB,OAAO,MAAM;AAC7C,SAAO,IAAI,UAAU,cAAc,IAAI,GAAG,IAAI;AAChD;",
|
||||
"names": ["module", "module", "import_trace_mapping", "source", "import_gen_mapping"]
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
{
|
||||
"name": "@jridgewell/remapping",
|
||||
"version": "2.3.5",
|
||||
"description": "Remap sequential sourcemaps through transformations to point at the original source code",
|
||||
"keywords": [
|
||||
"source",
|
||||
"map",
|
||||
"remap"
|
||||
],
|
||||
"main": "dist/remapping.umd.js",
|
||||
"module": "dist/remapping.mjs",
|
||||
"types": "types/remapping.d.cts",
|
||||
"files": [
|
||||
"dist",
|
||||
"src",
|
||||
"types"
|
||||
],
|
||||
"exports": {
|
||||
".": [
|
||||
{
|
||||
"import": {
|
||||
"types": "./types/remapping.d.mts",
|
||||
"default": "./dist/remapping.mjs"
|
||||
},
|
||||
"default": {
|
||||
"types": "./types/remapping.d.cts",
|
||||
"default": "./dist/remapping.umd.js"
|
||||
}
|
||||
},
|
||||
"./dist/remapping.umd.js"
|
||||
],
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"scripts": {
|
||||
"benchmark": "run-s build:code benchmark:*",
|
||||
"benchmark:install": "cd benchmark && npm install",
|
||||
"benchmark:only": "node --expose-gc benchmark/index.js",
|
||||
"build": "run-s -n build:code build:types",
|
||||
"build:code": "node ../../esbuild.mjs remapping.ts",
|
||||
"build:types": "run-s build:types:force build:types:emit build:types:mts",
|
||||
"build:types:force": "rimraf tsconfig.build.tsbuildinfo",
|
||||
"build:types:emit": "tsc --project tsconfig.build.json",
|
||||
"build:types:mts": "node ../../mts-types.mjs",
|
||||
"clean": "run-s -n clean:code clean:types",
|
||||
"clean:code": "tsc --build --clean tsconfig.build.json",
|
||||
"clean:types": "rimraf dist types",
|
||||
"test": "run-s -n test:types test:only test:format",
|
||||
"test:format": "prettier --check '{src,test}/**/*.ts'",
|
||||
"test:only": "mocha",
|
||||
"test:types": "eslint '{src,test}/**/*.ts'",
|
||||
"lint": "run-s -n lint:types lint:format",
|
||||
"lint:format": "npm run test:format -- --write",
|
||||
"lint:types": "npm run test:types -- --fix",
|
||||
"prepublishOnly": "npm run-s -n build test"
|
||||
},
|
||||
"homepage": "https://github.com/jridgewell/sourcemaps/tree/main/packages/remapping",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/jridgewell/sourcemaps.git",
|
||||
"directory": "packages/remapping"
|
||||
},
|
||||
"author": "Justin Ridgewell <justin@ridgewell.name>",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/gen-mapping": "^0.3.5",
|
||||
"@jridgewell/trace-mapping": "^0.3.24"
|
||||
},
|
||||
"devDependencies": {
|
||||
"source-map": "0.6.1"
|
||||
}
|
||||
}
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
import { TraceMap } from '@jridgewell/trace-mapping';
|
||||
|
||||
import { OriginalSource, MapSource } from './source-map-tree';
|
||||
|
||||
import type { Sources, MapSource as MapSourceType } from './source-map-tree';
|
||||
import type { SourceMapInput, SourceMapLoader, LoaderContext } from './types';
|
||||
|
||||
function asArray<T>(value: T | T[]): T[] {
|
||||
if (Array.isArray(value)) return value;
|
||||
return [value];
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively builds a tree structure out of sourcemap files, with each node
|
||||
* being either an `OriginalSource` "leaf" or a `SourceMapTree` composed of
|
||||
* `OriginalSource`s and `SourceMapTree`s.
|
||||
*
|
||||
* Every sourcemap is composed of a collection of source files and mappings
|
||||
* into locations of those source files. When we generate a `SourceMapTree` for
|
||||
* the sourcemap, we attempt to load each source file's own sourcemap. If it
|
||||
* does not have an associated sourcemap, it is considered an original,
|
||||
* unmodified source file.
|
||||
*/
|
||||
export default function buildSourceMapTree(
|
||||
input: SourceMapInput | SourceMapInput[],
|
||||
loader: SourceMapLoader,
|
||||
): MapSourceType {
|
||||
const maps = asArray(input).map((m) => new TraceMap(m, ''));
|
||||
const map = maps.pop()!;
|
||||
|
||||
for (let i = 0; i < maps.length; i++) {
|
||||
if (maps[i].sources.length > 1) {
|
||||
throw new Error(
|
||||
`Transformation map ${i} must have exactly one source file.\n` +
|
||||
'Did you specify these with the most recent transformation maps first?',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let tree = build(map, loader, '', 0);
|
||||
for (let i = maps.length - 1; i >= 0; i--) {
|
||||
tree = MapSource(maps[i], [tree]);
|
||||
}
|
||||
return tree;
|
||||
}
|
||||
|
||||
function build(
|
||||
map: TraceMap,
|
||||
loader: SourceMapLoader,
|
||||
importer: string,
|
||||
importerDepth: number,
|
||||
): MapSourceType {
|
||||
const { resolvedSources, sourcesContent, ignoreList } = map;
|
||||
|
||||
const depth = importerDepth + 1;
|
||||
const children = resolvedSources.map((sourceFile: string | null, i: number): Sources => {
|
||||
// The loading context gives the loader more information about why this file is being loaded
|
||||
// (eg, from which importer). It also allows the loader to override the location of the loaded
|
||||
// sourcemap/original source, or to override the content in the sourcesContent field if it's
|
||||
// an unmodified source file.
|
||||
const ctx: LoaderContext = {
|
||||
importer,
|
||||
depth,
|
||||
source: sourceFile || '',
|
||||
content: undefined,
|
||||
ignore: undefined,
|
||||
};
|
||||
|
||||
// Use the provided loader callback to retrieve the file's sourcemap.
|
||||
// TODO: We should eventually support async loading of sourcemap files.
|
||||
const sourceMap = loader(ctx.source, ctx);
|
||||
|
||||
const { source, content, ignore } = ctx;
|
||||
|
||||
// If there is a sourcemap, then we need to recurse into it to load its source files.
|
||||
if (sourceMap) return build(new TraceMap(sourceMap, source), loader, source, depth);
|
||||
|
||||
// Else, it's an unmodified source file.
|
||||
// The contents of this unmodified source file can be overridden via the loader context,
|
||||
// allowing it to be explicitly null or a string. If it remains undefined, we fall back to
|
||||
// the importing sourcemap's `sourcesContent` field.
|
||||
const sourceContent =
|
||||
content !== undefined ? content : sourcesContent ? sourcesContent[i] : null;
|
||||
const ignored = ignore !== undefined ? ignore : ignoreList ? ignoreList.includes(i) : false;
|
||||
return OriginalSource(source, sourceContent, ignored);
|
||||
});
|
||||
|
||||
return MapSource(map, children);
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
import buildSourceMapTree from './build-source-map-tree';
|
||||
import { traceMappings } from './source-map-tree';
|
||||
import SourceMap from './source-map';
|
||||
|
||||
import type { SourceMapInput, SourceMapLoader, Options } from './types';
|
||||
export type {
|
||||
SourceMapSegment,
|
||||
EncodedSourceMap,
|
||||
EncodedSourceMap as RawSourceMap,
|
||||
DecodedSourceMap,
|
||||
SourceMapInput,
|
||||
SourceMapLoader,
|
||||
LoaderContext,
|
||||
Options,
|
||||
} from './types';
|
||||
export type { SourceMap };
|
||||
|
||||
/**
|
||||
* Traces through all the mappings in the root sourcemap, through the sources
|
||||
* (and their sourcemaps), all the way back to the original source location.
|
||||
*
|
||||
* `loader` will be called every time we encounter a source file. If it returns
|
||||
* a sourcemap, we will recurse into that sourcemap to continue the trace. If
|
||||
* it returns a falsey value, that source file is treated as an original,
|
||||
* unmodified source file.
|
||||
*
|
||||
* Pass `excludeContent` to exclude any self-containing source file content
|
||||
* from the output sourcemap.
|
||||
*
|
||||
* Pass `decodedMappings` to receive a SourceMap with decoded (instead of
|
||||
* VLQ encoded) mappings.
|
||||
*/
|
||||
export default function remapping(
|
||||
input: SourceMapInput | SourceMapInput[],
|
||||
loader: SourceMapLoader,
|
||||
options?: boolean | Options,
|
||||
): SourceMap {
|
||||
const opts =
|
||||
typeof options === 'object' ? options : { excludeContent: !!options, decodedMappings: false };
|
||||
const tree = buildSourceMapTree(input, loader);
|
||||
return new SourceMap(traceMappings(tree), opts);
|
||||
}
|
||||
+172
@@ -0,0 +1,172 @@
|
||||
import { GenMapping, maybeAddSegment, setIgnore, setSourceContent } from '@jridgewell/gen-mapping';
|
||||
import { traceSegment, decodedMappings } from '@jridgewell/trace-mapping';
|
||||
|
||||
import type { TraceMap } from '@jridgewell/trace-mapping';
|
||||
|
||||
export type SourceMapSegmentObject = {
|
||||
column: number;
|
||||
line: number;
|
||||
name: string;
|
||||
source: string;
|
||||
content: string | null;
|
||||
ignore: boolean;
|
||||
};
|
||||
|
||||
export type OriginalSource = {
|
||||
map: null;
|
||||
sources: Sources[];
|
||||
source: string;
|
||||
content: string | null;
|
||||
ignore: boolean;
|
||||
};
|
||||
|
||||
export type MapSource = {
|
||||
map: TraceMap;
|
||||
sources: Sources[];
|
||||
source: string;
|
||||
content: null;
|
||||
ignore: false;
|
||||
};
|
||||
|
||||
export type Sources = OriginalSource | MapSource;
|
||||
|
||||
const SOURCELESS_MAPPING = /* #__PURE__ */ SegmentObject('', -1, -1, '', null, false);
|
||||
const EMPTY_SOURCES: Sources[] = [];
|
||||
|
||||
function SegmentObject(
|
||||
source: string,
|
||||
line: number,
|
||||
column: number,
|
||||
name: string,
|
||||
content: string | null,
|
||||
ignore: boolean,
|
||||
): SourceMapSegmentObject {
|
||||
return { source, line, column, name, content, ignore };
|
||||
}
|
||||
|
||||
function Source(
|
||||
map: TraceMap,
|
||||
sources: Sources[],
|
||||
source: '',
|
||||
content: null,
|
||||
ignore: false,
|
||||
): MapSource;
|
||||
function Source(
|
||||
map: null,
|
||||
sources: Sources[],
|
||||
source: string,
|
||||
content: string | null,
|
||||
ignore: boolean,
|
||||
): OriginalSource;
|
||||
function Source(
|
||||
map: TraceMap | null,
|
||||
sources: Sources[],
|
||||
source: string | '',
|
||||
content: string | null,
|
||||
ignore: boolean,
|
||||
): Sources {
|
||||
return {
|
||||
map,
|
||||
sources,
|
||||
source,
|
||||
content,
|
||||
ignore,
|
||||
} as any;
|
||||
}
|
||||
|
||||
/**
|
||||
* MapSource represents a single sourcemap, with the ability to trace mappings into its child nodes
|
||||
* (which may themselves be SourceMapTrees).
|
||||
*/
|
||||
export function MapSource(map: TraceMap, sources: Sources[]): MapSource {
|
||||
return Source(map, sources, '', null, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* A "leaf" node in the sourcemap tree, representing an original, unmodified source file. Recursive
|
||||
* segment tracing ends at the `OriginalSource`.
|
||||
*/
|
||||
export function OriginalSource(
|
||||
source: string,
|
||||
content: string | null,
|
||||
ignore: boolean,
|
||||
): OriginalSource {
|
||||
return Source(null, EMPTY_SOURCES, source, content, ignore);
|
||||
}
|
||||
|
||||
/**
|
||||
* traceMappings is only called on the root level SourceMapTree, and begins the process of
|
||||
* resolving each mapping in terms of the original source files.
|
||||
*/
|
||||
export function traceMappings(tree: MapSource): GenMapping {
|
||||
// TODO: Eventually support sourceRoot, which has to be removed because the sources are already
|
||||
// fully resolved. We'll need to make sources relative to the sourceRoot before adding them.
|
||||
const gen = new GenMapping({ file: tree.map.file });
|
||||
const { sources: rootSources, map } = tree;
|
||||
const rootNames = map.names;
|
||||
const rootMappings = decodedMappings(map);
|
||||
|
||||
for (let i = 0; i < rootMappings.length; i++) {
|
||||
const segments = rootMappings[i];
|
||||
|
||||
for (let j = 0; j < segments.length; j++) {
|
||||
const segment = segments[j];
|
||||
const genCol = segment[0];
|
||||
let traced: SourceMapSegmentObject | null = SOURCELESS_MAPPING;
|
||||
|
||||
// 1-length segments only move the current generated column, there's no source information
|
||||
// to gather from it.
|
||||
if (segment.length !== 1) {
|
||||
const source = rootSources[segment[1]];
|
||||
traced = originalPositionFor(
|
||||
source,
|
||||
segment[2],
|
||||
segment[3],
|
||||
segment.length === 5 ? rootNames[segment[4]] : '',
|
||||
);
|
||||
|
||||
// If the trace is invalid, then the trace ran into a sourcemap that doesn't contain a
|
||||
// respective segment into an original source.
|
||||
if (traced == null) continue;
|
||||
}
|
||||
|
||||
const { column, line, name, content, source, ignore } = traced;
|
||||
|
||||
maybeAddSegment(gen, i, genCol, source, line, column, name);
|
||||
if (source && content != null) setSourceContent(gen, source, content);
|
||||
if (ignore) setIgnore(gen, source, true);
|
||||
}
|
||||
}
|
||||
|
||||
return gen;
|
||||
}
|
||||
|
||||
/**
|
||||
* originalPositionFor is only called on children SourceMapTrees. It recurses down into its own
|
||||
* child SourceMapTrees, until we find the original source map.
|
||||
*/
|
||||
export function originalPositionFor(
|
||||
source: Sources,
|
||||
line: number,
|
||||
column: number,
|
||||
name: string,
|
||||
): SourceMapSegmentObject | null {
|
||||
if (!source.map) {
|
||||
return SegmentObject(source.source, line, column, name, source.content, source.ignore);
|
||||
}
|
||||
|
||||
const segment = traceSegment(source.map, line, column);
|
||||
|
||||
// If we couldn't find a segment, then this doesn't exist in the sourcemap.
|
||||
if (segment == null) return null;
|
||||
// 1-length segments only move the current generated column, there's no source information
|
||||
// to gather from it.
|
||||
if (segment.length === 1) return SOURCELESS_MAPPING;
|
||||
|
||||
return originalPositionFor(
|
||||
source.sources[segment[1]],
|
||||
segment[2],
|
||||
segment[3],
|
||||
segment.length === 5 ? source.map.names[segment[4]] : name,
|
||||
);
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
import { toDecodedMap, toEncodedMap } from '@jridgewell/gen-mapping';
|
||||
|
||||
import type { GenMapping } from '@jridgewell/gen-mapping';
|
||||
import type { DecodedSourceMap, EncodedSourceMap, Options } from './types';
|
||||
|
||||
/**
|
||||
* A SourceMap v3 compatible sourcemap, which only includes fields that were
|
||||
* provided to it.
|
||||
*/
|
||||
export default class SourceMap {
|
||||
declare file?: string | null;
|
||||
declare mappings: EncodedSourceMap['mappings'] | DecodedSourceMap['mappings'];
|
||||
declare sourceRoot?: string;
|
||||
declare names: string[];
|
||||
declare sources: (string | null)[];
|
||||
declare sourcesContent?: (string | null)[];
|
||||
declare version: 3;
|
||||
declare ignoreList: number[] | undefined;
|
||||
|
||||
constructor(map: GenMapping, options: Options) {
|
||||
const out = options.decodedMappings ? toDecodedMap(map) : toEncodedMap(map);
|
||||
this.version = out.version; // SourceMap spec says this should be first.
|
||||
this.file = out.file;
|
||||
this.mappings = out.mappings as SourceMap['mappings'];
|
||||
this.names = out.names as SourceMap['names'];
|
||||
this.ignoreList = out.ignoreList as SourceMap['ignoreList'];
|
||||
this.sourceRoot = out.sourceRoot;
|
||||
|
||||
this.sources = out.sources as SourceMap['sources'];
|
||||
if (!options.excludeContent) {
|
||||
this.sourcesContent = out.sourcesContent as SourceMap['sourcesContent'];
|
||||
}
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return JSON.stringify(this);
|
||||
}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
import type { SourceMapInput } from '@jridgewell/trace-mapping';
|
||||
|
||||
export type {
|
||||
SourceMapSegment,
|
||||
DecodedSourceMap,
|
||||
EncodedSourceMap,
|
||||
} from '@jridgewell/trace-mapping';
|
||||
|
||||
export type { SourceMapInput };
|
||||
|
||||
export type LoaderContext = {
|
||||
readonly importer: string;
|
||||
readonly depth: number;
|
||||
source: string;
|
||||
content: string | null | undefined;
|
||||
ignore: boolean | undefined;
|
||||
};
|
||||
|
||||
export type SourceMapLoader = (
|
||||
file: string,
|
||||
ctx: LoaderContext,
|
||||
) => SourceMapInput | null | undefined | void;
|
||||
|
||||
export type Options = {
|
||||
excludeContent?: boolean;
|
||||
decodedMappings?: boolean;
|
||||
};
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
import type { MapSource as MapSourceType } from './source-map-tree.cts';
|
||||
import type { SourceMapInput, SourceMapLoader } from './types.cts';
|
||||
/**
|
||||
* Recursively builds a tree structure out of sourcemap files, with each node
|
||||
* being either an `OriginalSource` "leaf" or a `SourceMapTree` composed of
|
||||
* `OriginalSource`s and `SourceMapTree`s.
|
||||
*
|
||||
* Every sourcemap is composed of a collection of source files and mappings
|
||||
* into locations of those source files. When we generate a `SourceMapTree` for
|
||||
* the sourcemap, we attempt to load each source file's own sourcemap. If it
|
||||
* does not have an associated sourcemap, it is considered an original,
|
||||
* unmodified source file.
|
||||
*/
|
||||
export = function buildSourceMapTree(input: SourceMapInput | SourceMapInput[], loader: SourceMapLoader): MapSourceType;
|
||||
//# sourceMappingURL=build-source-map-tree.d.ts.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"build-source-map-tree.d.ts","sourceRoot":"","sources":["../src/build-source-map-tree.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAW,SAAS,IAAI,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAC7E,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAiB,MAAM,SAAS,CAAC;AAO9E;;;;;;;;;;GAUG;AACH,MAAM,CAAC,OAAO,UAAU,kBAAkB,CACxC,KAAK,EAAE,cAAc,GAAG,cAAc,EAAE,EACxC,MAAM,EAAE,eAAe,GACtB,aAAa,CAkBf"}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
import type { MapSource as MapSourceType } from './source-map-tree.mts';
|
||||
import type { SourceMapInput, SourceMapLoader } from './types.mts';
|
||||
/**
|
||||
* Recursively builds a tree structure out of sourcemap files, with each node
|
||||
* being either an `OriginalSource` "leaf" or a `SourceMapTree` composed of
|
||||
* `OriginalSource`s and `SourceMapTree`s.
|
||||
*
|
||||
* Every sourcemap is composed of a collection of source files and mappings
|
||||
* into locations of those source files. When we generate a `SourceMapTree` for
|
||||
* the sourcemap, we attempt to load each source file's own sourcemap. If it
|
||||
* does not have an associated sourcemap, it is considered an original,
|
||||
* unmodified source file.
|
||||
*/
|
||||
export default function buildSourceMapTree(input: SourceMapInput | SourceMapInput[], loader: SourceMapLoader): MapSourceType;
|
||||
//# sourceMappingURL=build-source-map-tree.d.ts.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"build-source-map-tree.d.ts","sourceRoot":"","sources":["../src/build-source-map-tree.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAW,SAAS,IAAI,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAC7E,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAiB,MAAM,SAAS,CAAC;AAO9E;;;;;;;;;;GAUG;AACH,MAAM,CAAC,OAAO,UAAU,kBAAkB,CACxC,KAAK,EAAE,cAAc,GAAG,cAAc,EAAE,EACxC,MAAM,EAAE,eAAe,GACtB,aAAa,CAkBf"}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
import SourceMap from './source-map.cts';
|
||||
import type { SourceMapInput, SourceMapLoader, Options } from './types.cts';
|
||||
export type { SourceMapSegment, EncodedSourceMap, EncodedSourceMap as RawSourceMap, DecodedSourceMap, SourceMapInput, SourceMapLoader, LoaderContext, Options, } from './types.cts';
|
||||
export type { SourceMap };
|
||||
/**
|
||||
* Traces through all the mappings in the root sourcemap, through the sources
|
||||
* (and their sourcemaps), all the way back to the original source location.
|
||||
*
|
||||
* `loader` will be called every time we encounter a source file. If it returns
|
||||
* a sourcemap, we will recurse into that sourcemap to continue the trace. If
|
||||
* it returns a falsey value, that source file is treated as an original,
|
||||
* unmodified source file.
|
||||
*
|
||||
* Pass `excludeContent` to exclude any self-containing source file content
|
||||
* from the output sourcemap.
|
||||
*
|
||||
* Pass `decodedMappings` to receive a SourceMap with decoded (instead of
|
||||
* VLQ encoded) mappings.
|
||||
*/
|
||||
export = function remapping(input: SourceMapInput | SourceMapInput[], loader: SourceMapLoader, options?: boolean | Options): SourceMap;
|
||||
//# sourceMappingURL=remapping.d.ts.map
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user