Added files for Juan
This commit is contained in:
16
ExACTRegressionScripts/node_modules/.bin/chromedriver
generated
vendored
Normal file
16
ExACTRegressionScripts/node_modules/.bin/chromedriver
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||
|
||||
case `uname` in
|
||||
*CYGWIN*|*MINGW*|*MSYS*)
|
||||
if command -v cygpath > /dev/null 2>&1; then
|
||||
basedir=`cygpath -w "$basedir"`
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -x "$basedir/node" ]; then
|
||||
exec "$basedir/node" "$basedir/../chromedriver/bin/chromedriver" "$@"
|
||||
else
|
||||
exec node "$basedir/../chromedriver/bin/chromedriver" "$@"
|
||||
fi
|
||||
17
ExACTRegressionScripts/node_modules/.bin/chromedriver.cmd
generated
vendored
Executable file
17
ExACTRegressionScripts/node_modules/.bin/chromedriver.cmd
generated
vendored
Executable file
@@ -0,0 +1,17 @@
|
||||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\chromedriver\bin\chromedriver" %*
|
||||
28
ExACTRegressionScripts/node_modules/.bin/chromedriver.ps1
generated
vendored
Normal file
28
ExACTRegressionScripts/node_modules/.bin/chromedriver.ps1
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../chromedriver/bin/chromedriver" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../chromedriver/bin/chromedriver" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../chromedriver/bin/chromedriver" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../chromedriver/bin/chromedriver" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
16
ExACTRegressionScripts/node_modules/.bin/crc32
generated
vendored
Normal file
16
ExACTRegressionScripts/node_modules/.bin/crc32
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||
|
||||
case `uname` in
|
||||
*CYGWIN*|*MINGW*|*MSYS*)
|
||||
if command -v cygpath > /dev/null 2>&1; then
|
||||
basedir=`cygpath -w "$basedir"`
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -x "$basedir/node" ]; then
|
||||
exec "$basedir/node" "$basedir/../crc-32/bin/crc32.njs" "$@"
|
||||
else
|
||||
exec node "$basedir/../crc-32/bin/crc32.njs" "$@"
|
||||
fi
|
||||
17
ExACTRegressionScripts/node_modules/.bin/crc32.cmd
generated
vendored
Executable file
17
ExACTRegressionScripts/node_modules/.bin/crc32.cmd
generated
vendored
Executable file
@@ -0,0 +1,17 @@
|
||||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\crc-32\bin\crc32.njs" %*
|
||||
28
ExACTRegressionScripts/node_modules/.bin/crc32.ps1
generated
vendored
Normal file
28
ExACTRegressionScripts/node_modules/.bin/crc32.ps1
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../crc-32/bin/crc32.njs" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../crc-32/bin/crc32.njs" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../crc-32/bin/crc32.njs" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../crc-32/bin/crc32.njs" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
16
ExACTRegressionScripts/node_modules/.bin/escodegen
generated
vendored
Normal file
16
ExACTRegressionScripts/node_modules/.bin/escodegen
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||
|
||||
case `uname` in
|
||||
*CYGWIN*|*MINGW*|*MSYS*)
|
||||
if command -v cygpath > /dev/null 2>&1; then
|
||||
basedir=`cygpath -w "$basedir"`
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -x "$basedir/node" ]; then
|
||||
exec "$basedir/node" "$basedir/../escodegen/bin/escodegen.js" "$@"
|
||||
else
|
||||
exec node "$basedir/../escodegen/bin/escodegen.js" "$@"
|
||||
fi
|
||||
17
ExACTRegressionScripts/node_modules/.bin/escodegen.cmd
generated
vendored
Executable file
17
ExACTRegressionScripts/node_modules/.bin/escodegen.cmd
generated
vendored
Executable file
@@ -0,0 +1,17 @@
|
||||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\escodegen\bin\escodegen.js" %*
|
||||
28
ExACTRegressionScripts/node_modules/.bin/escodegen.ps1
generated
vendored
Normal file
28
ExACTRegressionScripts/node_modules/.bin/escodegen.ps1
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../escodegen/bin/escodegen.js" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../escodegen/bin/escodegen.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../escodegen/bin/escodegen.js" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../escodegen/bin/escodegen.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
16
ExACTRegressionScripts/node_modules/.bin/esgenerate
generated
vendored
Normal file
16
ExACTRegressionScripts/node_modules/.bin/esgenerate
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||
|
||||
case `uname` in
|
||||
*CYGWIN*|*MINGW*|*MSYS*)
|
||||
if command -v cygpath > /dev/null 2>&1; then
|
||||
basedir=`cygpath -w "$basedir"`
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -x "$basedir/node" ]; then
|
||||
exec "$basedir/node" "$basedir/../escodegen/bin/esgenerate.js" "$@"
|
||||
else
|
||||
exec node "$basedir/../escodegen/bin/esgenerate.js" "$@"
|
||||
fi
|
||||
17
ExACTRegressionScripts/node_modules/.bin/esgenerate.cmd
generated
vendored
Executable file
17
ExACTRegressionScripts/node_modules/.bin/esgenerate.cmd
generated
vendored
Executable file
@@ -0,0 +1,17 @@
|
||||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\escodegen\bin\esgenerate.js" %*
|
||||
28
ExACTRegressionScripts/node_modules/.bin/esgenerate.ps1
generated
vendored
Normal file
28
ExACTRegressionScripts/node_modules/.bin/esgenerate.ps1
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../escodegen/bin/esgenerate.js" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../escodegen/bin/esgenerate.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../escodegen/bin/esgenerate.js" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../escodegen/bin/esgenerate.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
16
ExACTRegressionScripts/node_modules/.bin/esparse
generated
vendored
Normal file
16
ExACTRegressionScripts/node_modules/.bin/esparse
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||
|
||||
case `uname` in
|
||||
*CYGWIN*|*MINGW*|*MSYS*)
|
||||
if command -v cygpath > /dev/null 2>&1; then
|
||||
basedir=`cygpath -w "$basedir"`
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -x "$basedir/node" ]; then
|
||||
exec "$basedir/node" "$basedir/../esprima/bin/esparse.js" "$@"
|
||||
else
|
||||
exec node "$basedir/../esprima/bin/esparse.js" "$@"
|
||||
fi
|
||||
17
ExACTRegressionScripts/node_modules/.bin/esparse.cmd
generated
vendored
Executable file
17
ExACTRegressionScripts/node_modules/.bin/esparse.cmd
generated
vendored
Executable file
@@ -0,0 +1,17 @@
|
||||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\esprima\bin\esparse.js" %*
|
||||
28
ExACTRegressionScripts/node_modules/.bin/esparse.ps1
generated
vendored
Normal file
28
ExACTRegressionScripts/node_modules/.bin/esparse.ps1
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../esprima/bin/esparse.js" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../esprima/bin/esparse.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../esprima/bin/esparse.js" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../esprima/bin/esparse.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
16
ExACTRegressionScripts/node_modules/.bin/esvalidate
generated
vendored
Normal file
16
ExACTRegressionScripts/node_modules/.bin/esvalidate
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||
|
||||
case `uname` in
|
||||
*CYGWIN*|*MINGW*|*MSYS*)
|
||||
if command -v cygpath > /dev/null 2>&1; then
|
||||
basedir=`cygpath -w "$basedir"`
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -x "$basedir/node" ]; then
|
||||
exec "$basedir/node" "$basedir/../esprima/bin/esvalidate.js" "$@"
|
||||
else
|
||||
exec node "$basedir/../esprima/bin/esvalidate.js" "$@"
|
||||
fi
|
||||
17
ExACTRegressionScripts/node_modules/.bin/esvalidate.cmd
generated
vendored
Executable file
17
ExACTRegressionScripts/node_modules/.bin/esvalidate.cmd
generated
vendored
Executable file
@@ -0,0 +1,17 @@
|
||||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\esprima\bin\esvalidate.js" %*
|
||||
28
ExACTRegressionScripts/node_modules/.bin/esvalidate.ps1
generated
vendored
Normal file
28
ExACTRegressionScripts/node_modules/.bin/esvalidate.ps1
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../esprima/bin/esvalidate.js" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../esprima/bin/esvalidate.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../esprima/bin/esvalidate.js" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../esprima/bin/esvalidate.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
16
ExACTRegressionScripts/node_modules/.bin/extract-zip
generated
vendored
Normal file
16
ExACTRegressionScripts/node_modules/.bin/extract-zip
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||
|
||||
case `uname` in
|
||||
*CYGWIN*|*MINGW*|*MSYS*)
|
||||
if command -v cygpath > /dev/null 2>&1; then
|
||||
basedir=`cygpath -w "$basedir"`
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -x "$basedir/node" ]; then
|
||||
exec "$basedir/node" "$basedir/../extract-zip/cli.js" "$@"
|
||||
else
|
||||
exec node "$basedir/../extract-zip/cli.js" "$@"
|
||||
fi
|
||||
17
ExACTRegressionScripts/node_modules/.bin/extract-zip.cmd
generated
vendored
Executable file
17
ExACTRegressionScripts/node_modules/.bin/extract-zip.cmd
generated
vendored
Executable file
@@ -0,0 +1,17 @@
|
||||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\extract-zip\cli.js" %*
|
||||
28
ExACTRegressionScripts/node_modules/.bin/extract-zip.ps1
generated
vendored
Normal file
28
ExACTRegressionScripts/node_modules/.bin/extract-zip.ps1
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../extract-zip/cli.js" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../extract-zip/cli.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../extract-zip/cli.js" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../extract-zip/cli.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
16
ExACTRegressionScripts/node_modules/.bin/geckodriver
generated
vendored
Normal file
16
ExACTRegressionScripts/node_modules/.bin/geckodriver
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||
|
||||
case `uname` in
|
||||
*CYGWIN*|*MINGW*|*MSYS*)
|
||||
if command -v cygpath > /dev/null 2>&1; then
|
||||
basedir=`cygpath -w "$basedir"`
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -x "$basedir/node" ]; then
|
||||
exec "$basedir/node" "$basedir/../geckodriver/bin/geckodriver.js" "$@"
|
||||
else
|
||||
exec node "$basedir/../geckodriver/bin/geckodriver.js" "$@"
|
||||
fi
|
||||
17
ExACTRegressionScripts/node_modules/.bin/geckodriver.cmd
generated
vendored
Executable file
17
ExACTRegressionScripts/node_modules/.bin/geckodriver.cmd
generated
vendored
Executable file
@@ -0,0 +1,17 @@
|
||||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\geckodriver\bin\geckodriver.js" %*
|
||||
28
ExACTRegressionScripts/node_modules/.bin/geckodriver.ps1
generated
vendored
Normal file
28
ExACTRegressionScripts/node_modules/.bin/geckodriver.ps1
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../geckodriver/bin/geckodriver.js" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../geckodriver/bin/geckodriver.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../geckodriver/bin/geckodriver.js" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../geckodriver/bin/geckodriver.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
16
ExACTRegressionScripts/node_modules/.bin/mime
generated
vendored
Normal file
16
ExACTRegressionScripts/node_modules/.bin/mime
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||
|
||||
case `uname` in
|
||||
*CYGWIN*|*MINGW*|*MSYS*)
|
||||
if command -v cygpath > /dev/null 2>&1; then
|
||||
basedir=`cygpath -w "$basedir"`
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -x "$basedir/node" ]; then
|
||||
exec "$basedir/node" "$basedir/../mime/cli.js" "$@"
|
||||
else
|
||||
exec node "$basedir/../mime/cli.js" "$@"
|
||||
fi
|
||||
17
ExACTRegressionScripts/node_modules/.bin/mime.cmd
generated
vendored
Executable file
17
ExACTRegressionScripts/node_modules/.bin/mime.cmd
generated
vendored
Executable file
@@ -0,0 +1,17 @@
|
||||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\mime\cli.js" %*
|
||||
28
ExACTRegressionScripts/node_modules/.bin/mime.ps1
generated
vendored
Normal file
28
ExACTRegressionScripts/node_modules/.bin/mime.ps1
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../mime/cli.js" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../mime/cli.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../mime/cli.js" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../mime/cli.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
16
ExACTRegressionScripts/node_modules/.bin/node-which
generated
vendored
Normal file
16
ExACTRegressionScripts/node_modules/.bin/node-which
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||
|
||||
case `uname` in
|
||||
*CYGWIN*|*MINGW*|*MSYS*)
|
||||
if command -v cygpath > /dev/null 2>&1; then
|
||||
basedir=`cygpath -w "$basedir"`
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -x "$basedir/node" ]; then
|
||||
exec "$basedir/node" "$basedir/../which/bin/which.js" "$@"
|
||||
else
|
||||
exec node "$basedir/../which/bin/which.js" "$@"
|
||||
fi
|
||||
17
ExACTRegressionScripts/node_modules/.bin/node-which.cmd
generated
vendored
Executable file
17
ExACTRegressionScripts/node_modules/.bin/node-which.cmd
generated
vendored
Executable file
@@ -0,0 +1,17 @@
|
||||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\which\bin\which.js" %*
|
||||
28
ExACTRegressionScripts/node_modules/.bin/node-which.ps1
generated
vendored
Normal file
28
ExACTRegressionScripts/node_modules/.bin/node-which.ps1
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../which/bin/which.js" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../which/bin/which.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../which/bin/which.js" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../which/bin/which.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
16
ExACTRegressionScripts/node_modules/.bin/nodemon
generated
vendored
Normal file
16
ExACTRegressionScripts/node_modules/.bin/nodemon
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||
|
||||
case `uname` in
|
||||
*CYGWIN*|*MINGW*|*MSYS*)
|
||||
if command -v cygpath > /dev/null 2>&1; then
|
||||
basedir=`cygpath -w "$basedir"`
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -x "$basedir/node" ]; then
|
||||
exec "$basedir/node" "$basedir/../nodemon/bin/nodemon.js" "$@"
|
||||
else
|
||||
exec node "$basedir/../nodemon/bin/nodemon.js" "$@"
|
||||
fi
|
||||
17
ExACTRegressionScripts/node_modules/.bin/nodemon.cmd
generated
vendored
Executable file
17
ExACTRegressionScripts/node_modules/.bin/nodemon.cmd
generated
vendored
Executable file
@@ -0,0 +1,17 @@
|
||||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\nodemon\bin\nodemon.js" %*
|
||||
28
ExACTRegressionScripts/node_modules/.bin/nodemon.ps1
generated
vendored
Normal file
28
ExACTRegressionScripts/node_modules/.bin/nodemon.ps1
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../nodemon/bin/nodemon.js" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../nodemon/bin/nodemon.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../nodemon/bin/nodemon.js" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../nodemon/bin/nodemon.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
16
ExACTRegressionScripts/node_modules/.bin/nodetouch
generated
vendored
Normal file
16
ExACTRegressionScripts/node_modules/.bin/nodetouch
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||
|
||||
case `uname` in
|
||||
*CYGWIN*|*MINGW*|*MSYS*)
|
||||
if command -v cygpath > /dev/null 2>&1; then
|
||||
basedir=`cygpath -w "$basedir"`
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -x "$basedir/node" ]; then
|
||||
exec "$basedir/node" "$basedir/../touch/bin/nodetouch.js" "$@"
|
||||
else
|
||||
exec node "$basedir/../touch/bin/nodetouch.js" "$@"
|
||||
fi
|
||||
17
ExACTRegressionScripts/node_modules/.bin/nodetouch.cmd
generated
vendored
Executable file
17
ExACTRegressionScripts/node_modules/.bin/nodetouch.cmd
generated
vendored
Executable file
@@ -0,0 +1,17 @@
|
||||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\touch\bin\nodetouch.js" %*
|
||||
28
ExACTRegressionScripts/node_modules/.bin/nodetouch.ps1
generated
vendored
Normal file
28
ExACTRegressionScripts/node_modules/.bin/nodetouch.ps1
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../touch/bin/nodetouch.js" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../touch/bin/nodetouch.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../touch/bin/nodetouch.js" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../touch/bin/nodetouch.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
16
ExACTRegressionScripts/node_modules/.bin/semver
generated
vendored
Normal file
16
ExACTRegressionScripts/node_modules/.bin/semver
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||
|
||||
case `uname` in
|
||||
*CYGWIN*|*MINGW*|*MSYS*)
|
||||
if command -v cygpath > /dev/null 2>&1; then
|
||||
basedir=`cygpath -w "$basedir"`
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -x "$basedir/node" ]; then
|
||||
exec "$basedir/node" "$basedir/../semver/bin/semver.js" "$@"
|
||||
else
|
||||
exec node "$basedir/../semver/bin/semver.js" "$@"
|
||||
fi
|
||||
17
ExACTRegressionScripts/node_modules/.bin/semver.cmd
generated
vendored
Executable file
17
ExACTRegressionScripts/node_modules/.bin/semver.cmd
generated
vendored
Executable file
@@ -0,0 +1,17 @@
|
||||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\semver\bin\semver.js" %*
|
||||
28
ExACTRegressionScripts/node_modules/.bin/semver.ps1
generated
vendored
Normal file
28
ExACTRegressionScripts/node_modules/.bin/semver.ps1
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../semver/bin/semver.js" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../semver/bin/semver.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../semver/bin/semver.js" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../semver/bin/semver.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
16
ExACTRegressionScripts/node_modules/.bin/xlsx
generated
vendored
Normal file
16
ExACTRegressionScripts/node_modules/.bin/xlsx
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||
|
||||
case `uname` in
|
||||
*CYGWIN*|*MINGW*|*MSYS*)
|
||||
if command -v cygpath > /dev/null 2>&1; then
|
||||
basedir=`cygpath -w "$basedir"`
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -x "$basedir/node" ]; then
|
||||
exec "$basedir/node" "$basedir/../xlsx/bin/xlsx.njs" "$@"
|
||||
else
|
||||
exec node "$basedir/../xlsx/bin/xlsx.njs" "$@"
|
||||
fi
|
||||
17
ExACTRegressionScripts/node_modules/.bin/xlsx.cmd
generated
vendored
Executable file
17
ExACTRegressionScripts/node_modules/.bin/xlsx.cmd
generated
vendored
Executable file
@@ -0,0 +1,17 @@
|
||||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\xlsx\bin\xlsx.njs" %*
|
||||
28
ExACTRegressionScripts/node_modules/.bin/xlsx.ps1
generated
vendored
Normal file
28
ExACTRegressionScripts/node_modules/.bin/xlsx.ps1
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../xlsx/bin/xlsx.njs" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../xlsx/bin/xlsx.njs" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../xlsx/bin/xlsx.njs" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../xlsx/bin/xlsx.njs" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
2288
ExACTRegressionScripts/node_modules/.package-lock.json
generated
vendored
Normal file
2288
ExACTRegressionScripts/node_modules/.package-lock.json
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
33
ExACTRegressionScripts/node_modules/@testim/chrome-version/.eslintrc.json
generated
vendored
Normal file
33
ExACTRegressionScripts/node_modules/@testim/chrome-version/.eslintrc.json
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"env": {
|
||||
"commonjs": true,
|
||||
"es6": true,
|
||||
"node": true
|
||||
},
|
||||
"extends": "eslint:recommended",
|
||||
"globals": {
|
||||
"Atomics": "readonly",
|
||||
"SharedArrayBuffer": "readonly"
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2018
|
||||
},
|
||||
"rules": {
|
||||
"indent": [
|
||||
"error",
|
||||
4
|
||||
],
|
||||
"linebreak-style": [
|
||||
"error",
|
||||
"unix"
|
||||
],
|
||||
"quotes": [
|
||||
"error",
|
||||
"single"
|
||||
],
|
||||
"semi": [
|
||||
"error",
|
||||
"always"
|
||||
]
|
||||
}
|
||||
}
|
||||
19
ExACTRegressionScripts/node_modules/@testim/chrome-version/.github/workflows/ci.yml
generated
vendored
Normal file
19
ExACTRegressionScripts/node_modules/@testim/chrome-version/.github/workflows/ci.yml
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
name: Tests
|
||||
on: [push, pull_request]
|
||||
jobs:
|
||||
test:
|
||||
name: 'Test on Node.js v${{ matrix.node }} / ${{ matrix.os }}'
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macOS-latest]
|
||||
node: [10, 12, 14, 16]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: ${{ matrix.node }}
|
||||
- run: npm install
|
||||
- run: npm test
|
||||
76
ExACTRegressionScripts/node_modules/@testim/chrome-version/CODE_OF_CONDUCT.md
generated
vendored
Normal file
76
ExACTRegressionScripts/node_modules/@testim/chrome-version/CODE_OF_CONDUCT.md
generated
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to making participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, sex characteristics, gender identity and expression,
|
||||
level of experience, education, socio-economic status, nationality, personal
|
||||
appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces
|
||||
when an individual is representing the project or its community. Examples of
|
||||
representing a project or community include using an official project e-mail
|
||||
address, posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event. Representation of a project may be
|
||||
further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting the project team at benji@testim.io. All
|
||||
complaints will be reviewed and investigated and will result in a response that
|
||||
is deemed necessary and appropriate to the circumstances. The project team is
|
||||
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||
Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||
faith may face temporary or permanent repercussions as determined by other
|
||||
members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see
|
||||
https://www.contributor-covenant.org/faq
|
||||
21
ExACTRegressionScripts/node_modules/@testim/chrome-version/LICENSE
generated
vendored
Normal file
21
ExACTRegressionScripts/node_modules/@testim/chrome-version/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2018-2019 Testim.io
|
||||
|
||||
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.
|
||||
51
ExACTRegressionScripts/node_modules/@testim/chrome-version/chrome-finder/darwin.js
generated
vendored
Normal file
51
ExACTRegressionScripts/node_modules/@testim/chrome-version/chrome-finder/darwin.js
generated
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
const { execSync } = require('child_process');
|
||||
const path = require('path').posix;
|
||||
const { canAccess, newLineRegex, sort } = require('./util');
|
||||
|
||||
function darwin(includeChromium = false) {
|
||||
const suffixes = [
|
||||
// '/Contents/MacOS/Google Chrome Canary',
|
||||
'/Contents/MacOS/Google Chrome',
|
||||
... includeChromium ? ['/Contents/MacOS/Chromium'] : []
|
||||
];
|
||||
|
||||
const LSREGISTER = '/System/Library/Frameworks/CoreServices.framework' +
|
||||
'/Versions/A/Frameworks/LaunchServices.framework' +
|
||||
'/Versions/A/Support/lsregister';
|
||||
|
||||
const installations = [];
|
||||
|
||||
execSync(
|
||||
`${LSREGISTER} -dump` +
|
||||
' | grep -E -i \'(google chrome( canary)?' + (includeChromium ? '|chromium' : '') + ').app(\\s\\(0x[0-9a-f]+\\))?$\'' +
|
||||
' | awk \'sub(/\\(0x[0-9a-f]+\\)/, "")\'' +
|
||||
' | awk \'{$1=""; print $0}\'' +
|
||||
' | awk \'{ gsub(/^[ \\t]+|[ \\t]+$/, ""); print }\'')
|
||||
.toString()
|
||||
.split(newLineRegex)
|
||||
.forEach((inst) => {
|
||||
suffixes.forEach(suffix => {
|
||||
const execPath = path.join(inst.trim(), suffix);
|
||||
if (canAccess(execPath)) {
|
||||
installations.push(execPath);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Retains one per line to maintain readability.
|
||||
const priorities = [
|
||||
{ regex: new RegExp(`^${process.env.HOME}/Applications/.*Chromium.app`), weight: 49 },
|
||||
{ regex: new RegExp(`^${process.env.HOME}/Applications/.*Chrome.app`), weight: 50 },
|
||||
// { regex: new RegExp(`^${process.env.HOME}/Applications/.*Chrome Canary.app`), weight: 51 },
|
||||
{ regex: /^\/Applications\/.*Chromium.app/, weight: 99 },
|
||||
{ regex: /^\/Applications\/.*Chrome.app/, weight: 100 },
|
||||
// { regex: /^\/Applications\/.*Chrome Canary.app/, weight: 101 },
|
||||
{ regex: /^\/Volumes\/.*Chromium.app/, weight: -3 },
|
||||
{ regex: /^\/Volumes\/.*Chrome.app/, weight: -2 },
|
||||
// { regex: /^\/Volumes\/.*Chrome Canary.app/, weight: -1 }
|
||||
];
|
||||
|
||||
return sort(installations, priorities);
|
||||
}
|
||||
|
||||
module.exports = darwin;
|
||||
9
ExACTRegressionScripts/node_modules/@testim/chrome-version/chrome-finder/index.d.ts
generated
vendored
Normal file
9
ExACTRegressionScripts/node_modules/@testim/chrome-version/chrome-finder/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
/**
|
||||
* find a executable chrome for all support system
|
||||
* @returns {string} executable chrome full path
|
||||
* @throws
|
||||
* if no executable chrome find, ERROR_NO_INSTALLATIONS_FOUND will be throw
|
||||
* if platform is not one if ['win32','darwin','linux'], ERROR_PLATFORM_NOT_SUPPORT will be throw
|
||||
*/
|
||||
declare function findChrome(): string;
|
||||
export = findChrome;
|
||||
39
ExACTRegressionScripts/node_modules/@testim/chrome-version/chrome-finder/index.js
generated
vendored
Normal file
39
ExACTRegressionScripts/node_modules/@testim/chrome-version/chrome-finder/index.js
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
'use strict';
|
||||
const ERROR_PLATFORM_NOT_SUPPORT = new Error('platform not support');
|
||||
const ERROR_NO_INSTALLATIONS_FOUND = new Error('no chrome installations found');
|
||||
|
||||
/**
|
||||
* Find a executable Chrome (or Chromium) for all supported systems.
|
||||
*
|
||||
* Supports macOS, Linux, and Windows.
|
||||
*
|
||||
* @param {boolean} includeChromium true if we should consider Chromium in our search, false otherwise.
|
||||
* @returns {string} the first full path to an executable Chrome (or Chromium)
|
||||
* @throws
|
||||
* if no executable Chrome (or Chromium) find, ERROR_NO_INSTALLATIONS_FOUND will be throw
|
||||
* if platform is not one if ['win32','darwin','linux'], ERROR_PLATFORM_NOT_SUPPORT will be throw
|
||||
*/
|
||||
function findChrome(includeChromium = false) {
|
||||
const { platform } = process;
|
||||
let installations = [];
|
||||
switch (platform) {
|
||||
case 'win32':
|
||||
installations = require('./win32')(includeChromium);
|
||||
break;
|
||||
case 'darwin':
|
||||
installations = require('./darwin')(includeChromium);
|
||||
break;
|
||||
case 'linux':
|
||||
installations = require('./linux')(includeChromium);
|
||||
break;
|
||||
default:
|
||||
throw ERROR_PLATFORM_NOT_SUPPORT;
|
||||
}
|
||||
if (installations.length) {
|
||||
return installations[0];
|
||||
} else {
|
||||
throw ERROR_NO_INSTALLATIONS_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = findChrome;
|
||||
112
ExACTRegressionScripts/node_modules/@testim/chrome-version/chrome-finder/linux.js
generated
vendored
Normal file
112
ExACTRegressionScripts/node_modules/@testim/chrome-version/chrome-finder/linux.js
generated
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
const { execSync, execFileSync } = require('child_process');
|
||||
const path = require('path').posix;
|
||||
const fs = require('fs');
|
||||
const { canAccess, sort, isExecutable, newLineRegex } = require('./util');
|
||||
|
||||
|
||||
function findChromeExecutablesForLinuxDesktop(folder, includeChromium = false) {
|
||||
const argumentsRegex = /(^[^ ]+).*/; // Take everything up to the first space
|
||||
const chromeExecRegex = '^Exec=\/.*\/(google|chrome' + (includeChromium ? '|chromium' : '') + ')-.*';
|
||||
|
||||
let installations = [];
|
||||
if (canAccess(folder)) {
|
||||
// Output of the grep & print looks like:
|
||||
// /opt/google/chrome/google-chrome --profile-directory
|
||||
// /home/user/Downloads/chrome-linux/chrome-wrapper %U
|
||||
let execPaths;
|
||||
execPaths = execSync(`find "${folder}" -type f -exec grep -E "${chromeExecRegex}" "{}" \\; | awk -F '=' '{print $2}'`);
|
||||
|
||||
execPaths = execPaths
|
||||
.toString()
|
||||
.split(newLineRegex)
|
||||
.map((execPath) => execPath.replace(argumentsRegex, '$1'));
|
||||
|
||||
execPaths.forEach((execPath) => canAccess(execPath) && installations.push(execPath));
|
||||
}
|
||||
|
||||
return installations;
|
||||
}
|
||||
|
||||
function findChromeExecutablesForLinux(validChromePaths, includeChromium = false) {
|
||||
const executables = [
|
||||
'google-chrome-stable',
|
||||
'google-chrome',
|
||||
... includeChromium ? ['chromium', 'chromium-browser', 'chromium/chrome'] : [] // chromium/chrome is for toradex machines where "chromium" is a directory. seen on Angstrom v2016.12
|
||||
];
|
||||
|
||||
return executables.map(executable => {
|
||||
const existingPaths = validChromePaths.map(possiblePath => {
|
||||
try {
|
||||
const chromePathToTest = possiblePath + '/' + executable;
|
||||
if (fs.existsSync(chromePathToTest) && canAccess(chromePathToTest) && isExecutable(chromePathToTest)) {
|
||||
return [ chromePathToTest ];
|
||||
}
|
||||
} catch (err) {
|
||||
// not installed on this path or inaccessible
|
||||
}
|
||||
return [];
|
||||
}).reduce((acc, val) => acc.concat(val), []); //.filter((foundChromePath) => foundChromePath);
|
||||
|
||||
// skip asking "which" command if the binary was found by searching the known paths.
|
||||
if (existingPaths && existingPaths.length > 0) {
|
||||
return existingPaths;
|
||||
}
|
||||
|
||||
try {
|
||||
const chromePath = execFileSync('which', [executable]).toString().split(newLineRegex)[0];
|
||||
if (canAccess(chromePath)) {
|
||||
return [ chromePath ];
|
||||
}
|
||||
} catch (err) {
|
||||
// cmd which not installed.
|
||||
}
|
||||
|
||||
return [];
|
||||
|
||||
}).reduce((acc, val) => acc.concat(val), []);
|
||||
}
|
||||
|
||||
/**
|
||||
* Look for linux executables in 2 ways
|
||||
* 1. Look into the directories where .desktop are saved on gnome based distro's
|
||||
* 2. Look for google-chrome-stable and google-chrome executables by using the which command
|
||||
* If includeChromium is set, also look for chromium, chromium-browser, and chromium/chrome executables by using the which command
|
||||
*/
|
||||
function linux(includeChromium = false) {
|
||||
let installations = [];
|
||||
|
||||
// 1. Look into the directories where .desktop are saved on gnome based distro's
|
||||
const desktopInstallationFolders = [
|
||||
path.join(require('os').homedir(), '.local/share/applications/'),
|
||||
'/usr/share/applications/',
|
||||
];
|
||||
desktopInstallationFolders.forEach(folder => {
|
||||
installations = installations.concat(findChromeExecutablesForLinuxDesktop(folder, includeChromium));
|
||||
});
|
||||
|
||||
// 2. Look for google-chrome-stable and google-chrome (and optionally chromium, chromium-browser, and chromium-chrome) executables by using the which command
|
||||
// see http://tldp.org/LDP/Linux-Filesystem-Hierarchy/html/
|
||||
const validChromePaths = [
|
||||
'/usr/bin',
|
||||
'/usr/local/bin',
|
||||
'/usr/sbin',
|
||||
'/usr/local/sbin',
|
||||
'/opt/bin',
|
||||
'/usr/bin/X11',
|
||||
'/usr/X11R6/bin'
|
||||
];
|
||||
installations = installations.concat(findChromeExecutablesForLinux(validChromePaths, includeChromium));
|
||||
|
||||
const priorities = [
|
||||
{ regex: /chromium$/, weight: 52 },
|
||||
{ regex: /chrome-wrapper$/, weight: 51 },
|
||||
{ regex: /google-chrome-stable$/, weight: 50 },
|
||||
{ regex: /google-chrome$/, weight: 49 },
|
||||
{ regex: /chromium-browser$/, weight: 48 },
|
||||
{ regex: /chrome$/, weight: 47 },
|
||||
];
|
||||
|
||||
return sort(Array.from(new Set(installations.filter(Boolean))), priorities);
|
||||
}
|
||||
|
||||
module.exports = linux;
|
||||
56
ExACTRegressionScripts/node_modules/@testim/chrome-version/chrome-finder/util.js
generated
vendored
Normal file
56
ExACTRegressionScripts/node_modules/@testim/chrome-version/chrome-finder/util.js
generated
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
const fs = require('fs');
|
||||
|
||||
const newLineRegex = /\r?\n/;
|
||||
|
||||
function sort(installations, priorities) {
|
||||
const defaultPriority = 10;
|
||||
// assign priorities
|
||||
return installations
|
||||
.map((inst) => {
|
||||
for (const pair of priorities) {
|
||||
if (pair.regex.test(inst)) {
|
||||
return { path: inst, weight: pair.weight };
|
||||
}
|
||||
}
|
||||
return { path: inst, weight: defaultPriority };
|
||||
})
|
||||
// sort based on priorities
|
||||
.sort((a, b) => (b.weight - a.weight))
|
||||
// remove priority flag
|
||||
.map(pair => pair.path);
|
||||
}
|
||||
|
||||
function canAccess(file) {
|
||||
if (!file) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
fs.accessSync(file);
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function isExecutable(file) {
|
||||
if (!file) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
var stat = fs.statSync(file);
|
||||
return stat && typeof stat.isFile === "function" && stat.isFile();
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
sort,
|
||||
canAccess,
|
||||
isExecutable,
|
||||
newLineRegex,
|
||||
}
|
||||
|
||||
|
||||
30
ExACTRegressionScripts/node_modules/@testim/chrome-version/chrome-finder/win32.js
generated
vendored
Normal file
30
ExACTRegressionScripts/node_modules/@testim/chrome-version/chrome-finder/win32.js
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
const path = require('path').win32;
|
||||
const { canAccess } = require('./util');
|
||||
const procesEnv = process.env;
|
||||
|
||||
|
||||
function win32(includeChromium = false) {
|
||||
const installations = [];
|
||||
const suffixes = [
|
||||
'\\Google\\Chrome SxS\\Application\\chrome.exe',
|
||||
'\\Google\\Chrome\\Application\\chrome.exe',
|
||||
'\\chrome-win32\\chrome.exe',
|
||||
... includeChromium ? ['\\Chromium\\Application\\chrome.exe'] : [],
|
||||
// '\\Google\\Chrome Beta\\Application\\chrome.exe',
|
||||
];
|
||||
const prefixes = [
|
||||
procesEnv.LOCALAPPDATA,
|
||||
procesEnv.PROGRAMFILES,
|
||||
procesEnv['PROGRAMFILES(X86)']
|
||||
].filter(prefix => prefix); // filter out undefined
|
||||
|
||||
prefixes.forEach(prefix => suffixes.forEach(suffix => {
|
||||
const chromePath = path.join(prefix, suffix);
|
||||
if (canAccess(chromePath)) {
|
||||
installations.push(chromePath);
|
||||
}
|
||||
}));
|
||||
return installations;
|
||||
}
|
||||
|
||||
module.exports = win32;
|
||||
6
ExACTRegressionScripts/node_modules/@testim/chrome-version/example.js
generated
vendored
Normal file
6
ExACTRegressionScripts/node_modules/@testim/chrome-version/example.js
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
|
||||
(async () => {
|
||||
const { getChromeVersion } = require('./index');
|
||||
const version = await getChromeVersion();
|
||||
console.log(version);
|
||||
})();
|
||||
130
ExACTRegressionScripts/node_modules/@testim/chrome-version/index.js
generated
vendored
Normal file
130
ExACTRegressionScripts/node_modules/@testim/chrome-version/index.js
generated
vendored
Normal file
@@ -0,0 +1,130 @@
|
||||
'use strict';
|
||||
|
||||
const findChrome = require('./chrome-finder');
|
||||
const util = require('util');
|
||||
const exec = util.promisify(require('child_process').exec);
|
||||
const path = require('path');
|
||||
const readdir = util.promisify(require('fs').readdir);
|
||||
const { execSync } = require('child_process');
|
||||
|
||||
async function getChromeVersionFromCli(includeChromium) {
|
||||
|
||||
let chromePath;
|
||||
try {
|
||||
chromePath = findChrome(includeChromium);
|
||||
} catch (err) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const res = await exec(chromePath.replace(/ /g, '\\ ') + ' --version');
|
||||
|
||||
const version = extractChromeVersionNumer(res.stdout);
|
||||
return version;
|
||||
}
|
||||
|
||||
function extractChromeVersionNumer(chromeVersionString) {
|
||||
return chromeVersionString.replace(/\D*(([0-9]+\.?)+)\s?.*/, '$1');
|
||||
}
|
||||
|
||||
const chromeVersionRegex = /^(\d+\.){3}\d+$/g;
|
||||
|
||||
async function getChromeVersionWin(includeChromium) {
|
||||
|
||||
let chromePath;
|
||||
try {
|
||||
chromePath = findChrome(includeChromium);
|
||||
} catch (err) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const powershell = await execAndAttemptExtractingChromeVersion(`powershell -command "&{(Get-Item '${chromePath}').VersionInfo.ProductVersion}"`);
|
||||
if (powershell !== null) {
|
||||
return powershell;
|
||||
}
|
||||
|
||||
const registry = await execAndAttemptExtractingChromeVersion('reg query "HKEY_CURRENT_USER\\Software\\Google\\Chrome\\BLBeacon" /v version');
|
||||
if (registry !== null) {
|
||||
return registry;
|
||||
}
|
||||
|
||||
const versionPath = path.dirname(chromePath);
|
||||
|
||||
const contents = await readdir(versionPath);
|
||||
|
||||
const versions = contents.filter(a => chromeVersionRegex.test(a));
|
||||
|
||||
// returning oldest in case there is an updated version and chrome still hasn't relaunched
|
||||
const oldest = versions.sort((a, b) => a > b)[0];
|
||||
|
||||
return oldest;
|
||||
}
|
||||
|
||||
async function execAndAttemptExtractingChromeVersion(command) {
|
||||
try {
|
||||
const { stdout } = await exec(command);
|
||||
const version = extractChromeVersionNumer(stdout).trim();
|
||||
if (chromeVersionRegex.test(version)) {
|
||||
return version;
|
||||
}
|
||||
} catch (err) { ''; }
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function getChromeVersionFromOsa(includeChromium) {
|
||||
|
||||
try {
|
||||
const version = execSync('osascript -e \'tell application "Google Chrome" to get version\'').toString().trim();
|
||||
return version;
|
||||
} catch (err) {
|
||||
if (!includeChromium) {
|
||||
return null;
|
||||
}
|
||||
// else fall-through to check for Chromium below
|
||||
}
|
||||
|
||||
try {
|
||||
const version = execSync('osascript -e \'tell application "Chromium" to get version\'').toString().trim();
|
||||
return version;
|
||||
} catch (err) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async function innerGetChromeVersion(includeChromium = false) {
|
||||
|
||||
const os = process.platform;
|
||||
|
||||
if (os === 'darwin') return getChromeVersionFromOsa(includeChromium);
|
||||
if (os === 'linux') return getChromeVersionFromCli(includeChromium);
|
||||
if (os.includes('win')) return getChromeVersionWin(includeChromium);
|
||||
|
||||
console.log(`${os} is not supported`);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the version of Chrome (or Chromium) that is installed.
|
||||
*
|
||||
* Supports macOS, Linux, and Windows.
|
||||
*
|
||||
* @param {boolean} includeChromium true if we should consider Chromium in our search, false otherwise.
|
||||
* @returns {string} the version number of Chrome (or Chromium), or null if the OS is not supported.
|
||||
*/
|
||||
async function getChromeVersion(includeChromium = false) {
|
||||
const res = await innerGetChromeVersion(includeChromium);
|
||||
if (typeof res === 'string') {
|
||||
return res.trim();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
if (require.main == module) {
|
||||
getChromeVersion().then(v => console.log(v));
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getChromeVersion
|
||||
};
|
||||
27
ExACTRegressionScripts/node_modules/@testim/chrome-version/package.json
generated
vendored
Normal file
27
ExACTRegressionScripts/node_modules/@testim/chrome-version/package.json
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "@testim/chrome-version",
|
||||
"version": "1.1.4",
|
||||
"description": "Finds the version of Chrome that is installed on your machine",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"lint": "eslint *.js --fix",
|
||||
"test": "mocha"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/testimio/chrome-version.git"
|
||||
},
|
||||
"author": "Testim",
|
||||
"license": "MIT",
|
||||
"homepage": "https://github.com/testimio/chrome-version",
|
||||
"keywords": [
|
||||
"chrome",
|
||||
"version"
|
||||
],
|
||||
"devDependencies": {
|
||||
"chai": "4.3.4",
|
||||
"eslint": "8.7.0",
|
||||
"mocha": "9.1.4",
|
||||
"rewire": "6.0.0"
|
||||
}
|
||||
}
|
||||
27
ExACTRegressionScripts/node_modules/@testim/chrome-version/readme.MD
generated
vendored
Normal file
27
ExACTRegressionScripts/node_modules/@testim/chrome-version/readme.MD
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
# chrome-version
|
||||
|
||||
[](https://github.com/testimio/chrome-version/actions/workflows/ci.yml)
|
||||
|
||||
Finds the version of Chrome (or Chromium) that is installed on your machine.
|
||||
|
||||
## Installation
|
||||
```sh
|
||||
npm install @testim/chrome-version
|
||||
```
|
||||
|
||||
## Use
|
||||
```js
|
||||
(async () => {
|
||||
const { getChromeVersion } = require('@testim/chrome-version');
|
||||
const includeChromium = false; // NOTE: set to true to also search for Chromium
|
||||
const version = await getChromeVersion(includeChromium);
|
||||
console.log(version);
|
||||
})();
|
||||
```
|
||||
|
||||
## Testing
|
||||
```sh
|
||||
npm test
|
||||
```
|
||||
|
||||
* If no version of chrome is installed on your machine `getChromeVersion` will return null.
|
||||
370
ExACTRegressionScripts/node_modules/@testim/chrome-version/test/test.js
generated
vendored
Normal file
370
ExACTRegressionScripts/node_modules/@testim/chrome-version/test/test.js
generated
vendored
Normal file
@@ -0,0 +1,370 @@
|
||||
const chai = require('chai');
|
||||
const expect = chai.expect;
|
||||
const Buffer = require('buffer').Buffer;
|
||||
|
||||
// rewrite to get access for testing
|
||||
const rewire = require("rewire");
|
||||
const chromeVersionModule = rewire("../index.js");
|
||||
const extractChromeVersionNumer = chromeVersionModule.__get__('extractChromeVersionNumer');
|
||||
const getChromeVersionFromOsa = chromeVersionModule.__get__('getChromeVersionFromOsa');
|
||||
const chromeFinderLinuxModule = rewire("../chrome-finder/linux.js");
|
||||
const findChromeExecutablesForLinuxDesktop = chromeFinderLinuxModule.__get__('findChromeExecutablesForLinuxDesktop');
|
||||
const findChromeExecutablesForLinux = chromeFinderLinuxModule.__get__('findChromeExecutablesForLinux');
|
||||
const chromeFinderDarwinModule = rewire("../chrome-finder/darwin.js");
|
||||
const findChromeForDarwin = chromeFinderDarwinModule.__get__('darwin');
|
||||
const chromeFinderWin32Module = rewire("../chrome-finder/win32.js");
|
||||
const findChromeForWin32 = chromeFinderWin32Module.__get__('win32');
|
||||
|
||||
describe('Chrome Finder', function() {
|
||||
|
||||
describe('extractChromeVersionNumer from Google Chrome 95.0.4638', function() {
|
||||
it('should return "95.0.4638"', function() {
|
||||
const versionString = 'Google Chrome 95.0.4638';
|
||||
const versionNumber = extractChromeVersionNumer(versionString);
|
||||
expect(versionNumber).to.equal('95.0.4638');
|
||||
});
|
||||
});
|
||||
|
||||
describe('extractChromeVersionNumer from Google Chrome 96.0.4664.110', function() {
|
||||
it('should return "96.0.4664.110"', function() {
|
||||
const versionString = 'Google Chrome 96.0.4664.110';
|
||||
const versionNumber = extractChromeVersionNumer(versionString);
|
||||
expect(versionNumber).to.equal('96.0.4664.110');
|
||||
});
|
||||
});
|
||||
|
||||
describe('extractChromeVersionNumer from Google Chrome 97.0.4692.71', function() {
|
||||
it('should return "97.0.4692.71"', function() {
|
||||
const versionString = 'Google Chrome 97.0.4692.71';
|
||||
const versionNumber = extractChromeVersionNumer(versionString);
|
||||
expect(versionNumber).to.equal('97.0.4692.71');
|
||||
});
|
||||
});
|
||||
|
||||
describe('extractChromiumVersionNumer from Chromium 105.0.5195.102 built on Debian 11.4, running on Debian 11.5', function() {
|
||||
it('should return "105.0.5195.102"', function() {
|
||||
const versionString = 'Chromium 105.0.5195.102 built on Debian 11.4, running on Debian 11.5';
|
||||
const versionNumber = extractChromeVersionNumer(versionString);
|
||||
expect(versionNumber).to.equal('105.0.5195.102');
|
||||
});
|
||||
});
|
||||
|
||||
describe('extractChromiumVersionNumer from Chromium 90.0.4430.212 Fedora Project', function() {
|
||||
it('should return "90.0.4430.212"', function() {
|
||||
const versionString = 'Chromium 90.0.4430.212 Fedora Project';
|
||||
const versionNumber = extractChromeVersionNumer(versionString);
|
||||
expect(versionNumber).to.equal('90.0.4430.212');
|
||||
});
|
||||
});
|
||||
|
||||
describe('extractChromiumVersionNumer from Chromium 98.0.4753.0', function() {
|
||||
it('should return "98.0.4753.0"', function() {
|
||||
const versionString = 'Chromium 98.0.4753.0';
|
||||
const versionNumber = extractChromeVersionNumer(versionString);
|
||||
expect(versionNumber).to.equal('98.0.4753.0');
|
||||
});
|
||||
});
|
||||
|
||||
describe('getChromeVersionFromOsa when includeChromium=false', function() {
|
||||
it('should only find Chrome', function() {
|
||||
const includeChromium = false;
|
||||
|
||||
const mockVersion = '97.0.4692.71';
|
||||
|
||||
var execSyncCommand;
|
||||
chromeVersionModule.__set__('execSync', function(command) {
|
||||
execSyncCommand = command;
|
||||
return Buffer.from(mockVersion);
|
||||
});
|
||||
|
||||
const version = getChromeVersionFromOsa(includeChromium);
|
||||
|
||||
expect(execSyncCommand).to.include('Google Chrome');
|
||||
expect(execSyncCommand).to.not.include('Chromium');
|
||||
|
||||
expect(version).to.equal(mockVersion);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getChromeVersionFromOsa when includeChromium=true', function() {
|
||||
it('should only find Chromium', function() {
|
||||
const includeChromium = true;
|
||||
|
||||
const mockVersion = '98.0.4753.0';
|
||||
|
||||
var execSyncCommands = [];
|
||||
chromeVersionModule.__set__('execSync', function(command) {
|
||||
execSyncCommands.push(command);
|
||||
if (execSyncCommands.length == 1) {
|
||||
throw "not found"
|
||||
}
|
||||
return Buffer.from(mockVersion);
|
||||
});
|
||||
|
||||
const version = getChromeVersionFromOsa(includeChromium);
|
||||
|
||||
expect(execSyncCommands.length).equal(2);
|
||||
expect(execSyncCommands[0]).to.include('Google Chrome');
|
||||
expect(execSyncCommands[1]).to.include('Chromium');
|
||||
|
||||
expect(version).to.equal(mockVersion);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Chrome Finder Linux Module', function() {
|
||||
|
||||
describe('Linux Desktop when includeChromium=false', function() {
|
||||
it('should only find Chrome', function() {
|
||||
|
||||
const includeChromium = false;
|
||||
|
||||
const mockChromePaths = [
|
||||
'/opt/google/chrome/google-chrome',
|
||||
'/home/user/Downloads/chrome-linux/chrome-wrapper'
|
||||
];
|
||||
|
||||
chromeFinderLinuxModule.__set__('canAccess', function(file) {
|
||||
return true;
|
||||
});
|
||||
|
||||
var execSyncCommand;
|
||||
chromeFinderLinuxModule.__set__('execSync', function(command) {
|
||||
execSyncCommand = command;
|
||||
return Buffer.from(mockChromePaths.join('\n'));
|
||||
});
|
||||
|
||||
const mockDesktopFolder = "mock-desktop-folder";
|
||||
const executables = findChromeExecutablesForLinuxDesktop(mockDesktopFolder, includeChromium);
|
||||
|
||||
expect(execSyncCommand).to.include(mockDesktopFolder);
|
||||
expect(execSyncCommand).to.not.include('|chromium');
|
||||
|
||||
expect(executables).to.have.lengthOf(2);
|
||||
expect(executables).to.deep.equal(mockChromePaths);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Linux Desktop when includeChromium=true', function() {
|
||||
it('should find Chrome and Chromium', function() {
|
||||
|
||||
const includeChromium = true;
|
||||
|
||||
const mockChromePaths = [
|
||||
'/opt/google/chrome/google-chrome',
|
||||
'/home/user/Downloads/chrome-linux/chrome-wrapper',
|
||||
'/usr/local/bin/chromium-browser'
|
||||
];
|
||||
|
||||
chromeFinderLinuxModule.__set__('canAccess', function(file) {
|
||||
return true;
|
||||
});
|
||||
|
||||
var execSyncCommand;
|
||||
chromeFinderLinuxModule.__set__('execSync', function(command) {
|
||||
execSyncCommand = command;
|
||||
return Buffer.from(mockChromePaths.join('\n'));
|
||||
});
|
||||
|
||||
const mockDesktopFolder = "mock-desktop-folder";
|
||||
const executables = findChromeExecutablesForLinuxDesktop(mockDesktopFolder, includeChromium);
|
||||
|
||||
expect(execSyncCommand).to.include(mockDesktopFolder);
|
||||
expect(execSyncCommand).to.include('|chromium');
|
||||
|
||||
expect(executables).to.have.lengthOf(3);
|
||||
expect(executables).to.deep.equal(mockChromePaths);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Linux when includeChromium=false', function() {
|
||||
it('should only find Chrome', function() {
|
||||
|
||||
const includeChromium = false;
|
||||
|
||||
const mockPaths = [
|
||||
'/mock-path'
|
||||
];
|
||||
|
||||
chromeFinderLinuxModule.__set__('fs', {
|
||||
existsSync: function(file) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
chromeFinderLinuxModule.__set__('canAccess', function(file) {
|
||||
return true;
|
||||
});
|
||||
chromeFinderLinuxModule.__set__('isExecutable', function(file) {
|
||||
return true;
|
||||
});
|
||||
|
||||
const executables = findChromeExecutablesForLinux(mockPaths, includeChromium);
|
||||
expect(executables).to.have.lengthOf(2);
|
||||
|
||||
const expectedExecutables = mockPaths.map(mockPath => ['google-chrome-stable', 'google-chrome'].map(executable => mockPath + '/' + executable)).reduce((acc, val) => acc.concat(val), []);
|
||||
expect(executables).to.deep.equal(expectedExecutables);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Linux when includeChromium=true', function() {
|
||||
it('should find Chrome and Chromium', function() {
|
||||
|
||||
const includeChromium = true;
|
||||
|
||||
const mockPaths = [
|
||||
'/mock-path'
|
||||
];
|
||||
|
||||
chromeFinderLinuxModule.__set__('fs', {
|
||||
existsSync: function(file) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
chromeFinderLinuxModule.__set__('canAccess', function(file) {
|
||||
return true;
|
||||
});
|
||||
chromeFinderLinuxModule.__set__('isExecutable', function(file) {
|
||||
return true;
|
||||
});
|
||||
|
||||
const executables = findChromeExecutablesForLinux(mockPaths, includeChromium);
|
||||
expect(executables).to.have.lengthOf(5);
|
||||
|
||||
const expectedExecutables = mockPaths.map(mockPath => ['google-chrome-stable', 'google-chrome', 'chromium', 'chromium-browser', 'chromium/chrome'].map(executable => mockPath + '/' + executable)).reduce((acc, val) => acc.concat(val), []);
|
||||
expect(executables).to.deep.equal(expectedExecutables);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Chrome Finder Darwin Module', function() {
|
||||
|
||||
describe('Darwin when includeChromium=false', function() {
|
||||
it('should only find Chrome', function() {
|
||||
|
||||
const includeChromium = false;
|
||||
|
||||
const mockChromePaths = [
|
||||
'/Applications/Google Chrome.app'
|
||||
];
|
||||
|
||||
chromeFinderDarwinModule.__set__('canAccess', function(file) {
|
||||
return true;
|
||||
});
|
||||
|
||||
var execSyncCommand;
|
||||
chromeFinderDarwinModule.__set__('execSync', function(command) {
|
||||
execSyncCommand = command;
|
||||
return Buffer.from(mockChromePaths.join('\n'));
|
||||
});
|
||||
|
||||
const executables = findChromeForDarwin(includeChromium);
|
||||
expect(execSyncCommand).to.not.include('|chromium');
|
||||
|
||||
expect(executables).to.have.lengthOf(1);
|
||||
expect(executables).to.deep.equal(mockChromePaths.map(mockChromePath => mockChromePath + '/Contents/MacOS/Google Chrome'));
|
||||
});
|
||||
});
|
||||
|
||||
describe('Darwin when includeChromium=true', function() {
|
||||
it('should only find Chrome', function() {
|
||||
|
||||
const includeChromium = true;
|
||||
|
||||
const mockChromePaths = [
|
||||
'/Applications/Google Chrome.app',
|
||||
'/Applications/Chromium.app'
|
||||
];
|
||||
|
||||
const expectedExecutables = [
|
||||
'/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
|
||||
'/Applications/Chromium.app/Contents/MacOS/Chromium'
|
||||
];
|
||||
|
||||
chromeFinderDarwinModule.__set__('canAccess', function(file) {
|
||||
return expectedExecutables.includes(file);
|
||||
});
|
||||
|
||||
var execSyncCommand;
|
||||
chromeFinderDarwinModule.__set__('execSync', function(command) {
|
||||
execSyncCommand = command;
|
||||
return Buffer.from(mockChromePaths.join('\n'));
|
||||
});
|
||||
|
||||
const executables = findChromeForDarwin(includeChromium);
|
||||
expect(execSyncCommand).to.include('|chromium');
|
||||
|
||||
expect(executables).to.have.lengthOf(2);
|
||||
expect(executables).to.deep.equal(expectedExecutables);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Chrome Finder Win32 Module', function() {
|
||||
|
||||
describe('Win32 when includeChromium=false', function() {
|
||||
it('should only find Chrome', function() {
|
||||
|
||||
const includeChromium = false;
|
||||
|
||||
chromeFinderWin32Module.__set__('canAccess', function(file) {
|
||||
return true;
|
||||
});
|
||||
|
||||
chromeFinderWin32Module.__set__('procesEnv', {
|
||||
LOCALAPPDATA: 'mock-local-app-data',
|
||||
PROGRAMFILES: 'mock-program-files',
|
||||
'PROGRAMFILES(X86)': 'mock-program-files-x86'
|
||||
});
|
||||
|
||||
const executables = findChromeForWin32(includeChromium);
|
||||
|
||||
expect(executables).to.have.lengthOf(9);
|
||||
expect(executables).to.deep.equal([
|
||||
'mock-local-app-data\\Google\\Chrome SxS\\Application\\chrome.exe',
|
||||
'mock-local-app-data\\Google\\Chrome\\Application\\chrome.exe',
|
||||
'mock-local-app-data\\chrome-win32\\chrome.exe',
|
||||
'mock-program-files\\Google\\Chrome SxS\\Application\\chrome.exe',
|
||||
'mock-program-files\\Google\\Chrome\\Application\\chrome.exe',
|
||||
'mock-program-files\\chrome-win32\\chrome.exe',
|
||||
'mock-program-files-x86\\Google\\Chrome SxS\\Application\\chrome.exe',
|
||||
'mock-program-files-x86\\Google\\Chrome\\Application\\chrome.exe',
|
||||
'mock-program-files-x86\\chrome-win32\\chrome.exe'
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Win32 when includeChromium=true', function() {
|
||||
it('should only find Chrome', function() {
|
||||
|
||||
const includeChromium = true;
|
||||
|
||||
chromeFinderWin32Module.__set__('canAccess', function(file) {
|
||||
return true;
|
||||
});
|
||||
|
||||
chromeFinderWin32Module.__set__('procesEnv', {
|
||||
LOCALAPPDATA: 'mock-local-app-data',
|
||||
PROGRAMFILES: 'mock-program-files',
|
||||
'PROGRAMFILES(X86)': 'mock-program-files-x86'
|
||||
});
|
||||
|
||||
const executables = findChromeForWin32(includeChromium);
|
||||
|
||||
expect(executables).to.have.lengthOf(12);
|
||||
expect(executables).to.deep.equal([
|
||||
'mock-local-app-data\\Google\\Chrome SxS\\Application\\chrome.exe',
|
||||
'mock-local-app-data\\Google\\Chrome\\Application\\chrome.exe',
|
||||
'mock-local-app-data\\chrome-win32\\chrome.exe',
|
||||
'mock-local-app-data\\Chromium\\Application\\chrome.exe',
|
||||
'mock-program-files\\Google\\Chrome SxS\\Application\\chrome.exe',
|
||||
'mock-program-files\\Google\\Chrome\\Application\\chrome.exe',
|
||||
'mock-program-files\\chrome-win32\\chrome.exe',
|
||||
'mock-program-files\\Chromium\\Application\\chrome.exe',
|
||||
'mock-program-files-x86\\Google\\Chrome SxS\\Application\\chrome.exe',
|
||||
'mock-program-files-x86\\Google\\Chrome\\Application\\chrome.exe',
|
||||
'mock-program-files-x86\\chrome-win32\\chrome.exe',
|
||||
'mock-program-files-x86\\Chromium\\Application\\chrome.exe'
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
21
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/LICENSE
generated
vendored
Normal file
21
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
quickjs-emscripten copyright (c) 2019 Jake Teton-Landis
|
||||
|
||||
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.
|
||||
597
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/README.md
generated
vendored
Normal file
597
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/README.md
generated
vendored
Normal file
@@ -0,0 +1,597 @@
|
||||
# quickjs-emscripten
|
||||
|
||||
Javascript/Typescript bindings for QuickJS, a modern Javascript interpreter,
|
||||
compiled to WebAssembly.
|
||||
|
||||
- Safely evaluate untrusted Javascript (up to ES2020).
|
||||
- Create and manipulate values inside the QuickJS runtime ([more][values]).
|
||||
- Expose host functions to the QuickJS runtime ([more][functions]).
|
||||
- Execute synchronous code that uses asynchronous functions, with [asyncify][asyncify].
|
||||
|
||||
[Github] | [NPM] | [API Documentation][api] | [Examples][tests]
|
||||
|
||||
```typescript
|
||||
import { getQuickJS } from "quickjs-emscripten"
|
||||
|
||||
async function main() {
|
||||
const QuickJS = await getQuickJS()
|
||||
const vm = QuickJS.newContext()
|
||||
|
||||
const world = vm.newString("world")
|
||||
vm.setProp(vm.global, "NAME", world)
|
||||
world.dispose()
|
||||
|
||||
const result = vm.evalCode(`"Hello " + NAME + "!"`)
|
||||
if (result.error) {
|
||||
console.log("Execution failed:", vm.dump(result.error))
|
||||
result.error.dispose()
|
||||
} else {
|
||||
console.log("Success:", vm.dump(result.value))
|
||||
result.value.dispose()
|
||||
}
|
||||
|
||||
vm.dispose()
|
||||
}
|
||||
|
||||
main()
|
||||
```
|
||||
|
||||
[github]: https://github.com/justjake/quickjs-emscripten
|
||||
[npm]: https://www.npmjs.com/package/quickjs-emscripten
|
||||
[api]: https://github.com/justjake/quickjs-emscripten/blob/main/doc/modules.md
|
||||
[tests]: https://github.com/justjake/quickjs-emscripten/blob/main/ts/quickjs.test.ts
|
||||
[values]: #interfacing-with-the-interpreter
|
||||
[asyncify]: #asyncify
|
||||
[functions]: #exposing-apis
|
||||
|
||||
## Usage
|
||||
|
||||
Install from `npm`: `npm install --save quickjs-emscripten` or `yarn add quickjs-emscripten`.
|
||||
|
||||
The root entrypoint of this library is the `getQuickJS` function, which returns
|
||||
a promise that resolves to a [QuickJS singleton](./doc/classes/quickjs.md) when
|
||||
the QuickJS WASM module is ready.
|
||||
|
||||
Once `getQuickJS` has been awaited at least once, you also can use the `getQuickJSSync`
|
||||
function to directly access the singleton engine in your synchronous code.
|
||||
|
||||
### Safely evaluate Javascript code
|
||||
|
||||
See [QuickJS.evalCode](https://github.com/justjake/quickjs-emscripten/blob/main/doc/classes/quickjs.md#evalcode)
|
||||
|
||||
```typescript
|
||||
import { getQuickJS, shouldInterruptAfterDeadline } from "quickjs-emscripten"
|
||||
|
||||
getQuickJS().then((QuickJS) => {
|
||||
const result = QuickJS.evalCode("1 + 1", {
|
||||
shouldInterrupt: shouldInterruptAfterDeadline(Date.now() + 1000),
|
||||
memoryLimitBytes: 1024 * 1024,
|
||||
})
|
||||
console.log(result)
|
||||
})
|
||||
```
|
||||
|
||||
### Interfacing with the interpreter
|
||||
|
||||
You can use [QuickJSContext](https://github.com/justjake/quickjs-emscripten/blob/main/doc/classes/QuickJSContext.md)
|
||||
to build a scripting environment by modifying globals and exposing functions
|
||||
into the QuickJS interpreter.
|
||||
|
||||
Each `QuickJSContext` instance has its own environment -- globals, built-in
|
||||
classes -- and actions from one context won't leak into other contexts or
|
||||
runtimes (with one exception, see [Asyncify][asyncify]).
|
||||
|
||||
Every context is created inside a
|
||||
[QuickJSRuntime](https://github.com/justjake/quickjs-emscripten/blob/main/doc/classes/QuickJSRuntime.md).
|
||||
A runtime represents a Javascript heap, and you can even share values between
|
||||
contexts in the same runtime.
|
||||
|
||||
```typescript
|
||||
const vm = QuickJS.newContext()
|
||||
let state = 0
|
||||
|
||||
const fnHandle = vm.newFunction("nextId", () => {
|
||||
return vm.newNumber(++state)
|
||||
})
|
||||
|
||||
vm.setProp(vm.global, "nextId", fnHandle)
|
||||
fnHandle.dispose()
|
||||
|
||||
const nextId = vm.unwrapResult(vm.evalCode(`nextId(); nextId(); nextId()`))
|
||||
console.log("vm result:", vm.getNumber(nextId), "native state:", state)
|
||||
|
||||
nextId.dispose()
|
||||
vm.dispose()
|
||||
```
|
||||
|
||||
When you create a context from a top-level API like in the example above,
|
||||
instead of by calling `runtime.newContext()`, a runtime is automatically created
|
||||
for the lifetime of the context, and disposed of when you dispose the context.
|
||||
|
||||
#### Runtime
|
||||
|
||||
The runtime has APIs for CPU and memory limits that apply to all contexts within
|
||||
the runtime in aggregate. You can also use the runtime to configure EcmaScript
|
||||
module loading.
|
||||
|
||||
```typescript
|
||||
const runtime = QuickJS.newRuntime()
|
||||
// "Should be enough for everyone" -- attributed to B. Gates
|
||||
runtime.setMemoryLimit(1024 * 640)
|
||||
// Limit stack size
|
||||
runtime.setMaxStackSize(1024 * 320)
|
||||
// Interrupt computation after 1024 calls to the interrupt handler
|
||||
let interruptCycles = 0
|
||||
runtime.setInterruptHandler(() => ++interruptCycles > 1024)
|
||||
// Toy module system that always returns the module name
|
||||
// as the default export
|
||||
runtime.setModuleLoader((moduleName) => `export default '${moduleName}'`)
|
||||
const context = runtime.newContext()
|
||||
const ok = context.evalCode(`
|
||||
import fooName from './foo.js'
|
||||
globalThis.result = fooName
|
||||
`)
|
||||
context.unwrapResult(ok).dispose()
|
||||
// logs "foo.js"
|
||||
console.log(context.getProp(context.global, "result").consume(context.dump))
|
||||
context.dispose()
|
||||
runtime.dispose()
|
||||
```
|
||||
|
||||
### Memory Management
|
||||
|
||||
Many methods in this library return handles to memory allocated inside the
|
||||
WebAssembly heap. These types cannot be garbage-collected as usual in
|
||||
Javascript. Instead, you must manually manage their memory by calling a
|
||||
`.dispose()` method to free the underlying resources. Once a handle has been
|
||||
disposed, it cannot be used anymore. Note that in the example above, we call
|
||||
`.dispose()` on each handle once it is no longer needed.
|
||||
|
||||
Calling `QuickJSContext.dispose()` will throw a RuntimeError if you've forgotten to
|
||||
dispose any handles associated with that VM, so it's good practice to create a
|
||||
new VM instance for each of your tests, and to call `vm.dispose()` at the end
|
||||
of every test.
|
||||
|
||||
```typescript
|
||||
const vm = QuickJS.newContext()
|
||||
const numberHandle = vm.newNumber(42)
|
||||
// Note: numberHandle not disposed, so it leaks memory.
|
||||
vm.dispose()
|
||||
// throws RuntimeError: abort(Assertion failed: list_empty(&rt->gc_obj_list), at: quickjs/quickjs.c,1963,JS_FreeRuntime)
|
||||
```
|
||||
|
||||
Here are some strategies to reduce the toil of calling `.dispose()` on each
|
||||
handle you create:
|
||||
|
||||
#### Scope
|
||||
|
||||
A
|
||||
[`Scope`](https://github.com/justjake/quickjs-emscripten/blob/main/doc/classes/scope.md#class-scope)
|
||||
instance manages a set of disposables and calls their `.dispose()`
|
||||
method in the reverse order in which they're added to the scope. Here's the
|
||||
"Interfacing with the interpreter" example re-written using `Scope`:
|
||||
|
||||
```typescript
|
||||
Scope.withScope((scope) => {
|
||||
const vm = scope.manage(QuickJS.newContext())
|
||||
let state = 0
|
||||
|
||||
const fnHandle = scope.manage(
|
||||
vm.newFunction("nextId", () => {
|
||||
return vm.newNumber(++state)
|
||||
})
|
||||
)
|
||||
|
||||
vm.setProp(vm.global, "nextId", fnHandle)
|
||||
|
||||
const nextId = scope.manage(vm.unwrapResult(vm.evalCode(`nextId(); nextId(); nextId()`)))
|
||||
console.log("vm result:", vm.getNumber(nextId), "native state:", state)
|
||||
|
||||
// When the withScope block exits, it calls scope.dispose(), which in turn calls
|
||||
// the .dispose() methods of all the disposables managed by the scope.
|
||||
})
|
||||
```
|
||||
|
||||
You can also create `Scope` instances with `new Scope()` if you want to manage
|
||||
calling `scope.dispose()` yourself.
|
||||
|
||||
#### `Lifetime.consume(fn)`
|
||||
|
||||
[`Lifetime.consume`](https://github.com/justjake/quickjs-emscripten/blob/main/doc/classes/lifetime.md#consume)
|
||||
is sugar for the common pattern of using a handle and then
|
||||
immediately disposing of it. `Lifetime.consume` takes a `map` function that
|
||||
produces a result of any type. The `map` fuction is called with the handle,
|
||||
then the handle is disposed, then the result is returned.
|
||||
|
||||
Here's the "Interfacing with interpreter" example re-written using `.consume()`:
|
||||
|
||||
```typescript
|
||||
const vm = QuickJS.newContext()
|
||||
let state = 0
|
||||
|
||||
vm.newFunction("nextId", () => {
|
||||
return vm.newNumber(++state)
|
||||
}).consume((fnHandle) => vm.setProp(vm.global, "nextId", fnHandle))
|
||||
|
||||
vm.unwrapResult(vm.evalCode(`nextId(); nextId(); nextId()`)).consume((nextId) =>
|
||||
console.log("vm result:", vm.getNumber(nextId), "native state:", state)
|
||||
)
|
||||
|
||||
vm.dispose()
|
||||
```
|
||||
|
||||
Generally working with `Scope` leads to more straight-forward code, but
|
||||
`Lifetime.consume` can be handy sugar as part of a method call chain.
|
||||
|
||||
### Exposing APIs
|
||||
|
||||
To add APIs inside the QuickJS environment, you'll need to create objects to
|
||||
define the shape of your API, and add properties and functions to those objects
|
||||
to allow code inside QuickJS to call code on the host.
|
||||
|
||||
By default, no host functionality is exposed to code running inside QuickJS.
|
||||
|
||||
```typescript
|
||||
const vm = QuickJS.newContext()
|
||||
// `console.log`
|
||||
const logHandle = vm.newFunction("log", (...args) => {
|
||||
const nativeArgs = args.map(vm.dump)
|
||||
console.log("QuickJS:", ...nativeArgs)
|
||||
})
|
||||
// Partially implement `console` object
|
||||
const consoleHandle = vm.newObject()
|
||||
vm.setProp(consoleHandle, "log", logHandle)
|
||||
vm.setProp(vm.global, "console", consoleHandle)
|
||||
consoleHandle.dispose()
|
||||
logHandle.dispose()
|
||||
|
||||
vm.unwrapResult(vm.evalCode(`console.log("Hello from QuickJS!")`)).dispose()
|
||||
```
|
||||
|
||||
#### Promises
|
||||
|
||||
To expose an asynchronous function that _returns a promise_ to callers within
|
||||
QuickJS, your function can return the handle of a `QuickJSDeferredPromise`
|
||||
created via `context.newPromise()`.
|
||||
|
||||
When you resolve a `QuickJSDeferredPromise` -- and generally whenever async
|
||||
behavior completes for the VM -- pending listeners inside QuickJS may not
|
||||
execute immediately. Your code needs to explicitly call
|
||||
`runtime.executePendingJobs()` to resume execution inside QuickJS. This API
|
||||
gives your code maximum control to _schedule_ when QuickJS will block the host's
|
||||
event loop by resuming execution.
|
||||
|
||||
To work with QuickJS handles that contain a promise inside the environment, you
|
||||
can convert the QuickJSHandle into a native promise using
|
||||
`context.resolvePromise()`. Take care with this API to avoid 'deadlocks' where
|
||||
the host awaits a guest promise, but the guest cannot make progress until the
|
||||
host calls `runtime.executePendingJobs()`. The simplest way to avoid this kind
|
||||
of deadlock is to always schedule `executePendingJobs` after any promise is
|
||||
settled.
|
||||
|
||||
```typescript
|
||||
const vm = QuickJS.newContext()
|
||||
const fakeFileSystem = new Map([["example.txt", "Example file content"]])
|
||||
|
||||
// Function that simulates reading data asynchronously
|
||||
const readFileHandle = vm.newFunction("readFile", (pathHandle) => {
|
||||
const path = vm.getString(pathHandle)
|
||||
const promise = vm.newPromise()
|
||||
setTimeout(() => {
|
||||
const content = fakeFileSystem.get(path)
|
||||
promise.resolve(vm.newString(content || ""))
|
||||
}, 100)
|
||||
// IMPORTANT: Once you resolve an async action inside QuickJS,
|
||||
// call runtime.executePendingJobs() to run any code that was
|
||||
// waiting on the promise or callback.
|
||||
promise.settled.then(vm.runtime.executePendingJobs)
|
||||
return promise.handle
|
||||
})
|
||||
readFileHandle.consume((handle) => vm.setProp(vm.global, "readFile", handle))
|
||||
|
||||
// Evaluate code that uses `readFile`, which returns a promise
|
||||
const result = vm.evalCode(`(async () => {
|
||||
const content = await readFile('example.txt')
|
||||
return content.toUpperCase()
|
||||
})()`)
|
||||
const promiseHandle = vm.unwrapResult(result)
|
||||
|
||||
// Convert the promise handle into a native promise and await it.
|
||||
// If code like this deadlocks, make sure you are calling
|
||||
// runtime.executePendingJobs appropriately.
|
||||
const resolvedResult = await vm.resolvePromise(promiseHandle)
|
||||
promiseHandle.dispose()
|
||||
const resolvedHandle = vm.unwrapResult(resolvedResult)
|
||||
console.log("Result:", vm.getString(resolvedHandle))
|
||||
resolvedHandle.dispose()
|
||||
```
|
||||
|
||||
#### Asyncify
|
||||
|
||||
Sometimes, we want to create a function that's synchronous from the perspective
|
||||
of QuickJS, but prefer to implement that function _asynchronously_ in your host
|
||||
code. The most obvious use-case is for EcmaScript module loading. The underlying
|
||||
QuickJS C library expects the module loader function to return synchronously,
|
||||
but loading data synchronously in the browser or server is somewhere between "a
|
||||
bad idea" and "impossible". QuickJS also doesn't expose an API to "pause" the
|
||||
execution of a runtime, and adding such an API is tricky due to the VM's
|
||||
implementation.
|
||||
|
||||
As a work-around, we provide an alternate build of QuickJS processed by
|
||||
Emscripten/Binaryen's [ASYNCIFY](https://emscripten.org/docs/porting/asyncify.html)
|
||||
compiler transform. Here's how Emscripten's documentation describes Asyncify:
|
||||
|
||||
> Asyncify lets synchronous C or C++ code interact with asynchronous \[host] JavaScript. This allows things like:
|
||||
>
|
||||
> - A synchronous call in C that yields to the event loop, which allows browser events to be handled.
|
||||
>
|
||||
> - A synchronous call in C that waits for an asynchronous operation in \[host] JS to complete.
|
||||
>
|
||||
> Asyncify automatically transforms ... code into a form that can be paused and
|
||||
> resumed ..., so that it is asynchronous (hence the name “Asyncify”) even though
|
||||
> \[it is written] in a normal synchronous way.
|
||||
|
||||
This means we can suspend an _entire WebAssembly module_ (which could contain
|
||||
multiple runtimes and contexts) while our host Javascript loads data
|
||||
asynchronously, and then resume execution once the data load completes. This is
|
||||
a very handy superpower, but it comes with a couple of major limitations:
|
||||
|
||||
1. _An asyncified WebAssembly module can only suspend to wait for a single
|
||||
asynchronous call at a time_. You may call back into a suspended WebAssembly
|
||||
module eg. to create a QuickJS value to return a result, but the system will
|
||||
crash if this call tries to suspend again. Take a look at Emscripten's documentation
|
||||
on [reentrancy](https://emscripten.org/docs/porting/asyncify.html#reentrancy).
|
||||
|
||||
2. _Asyncified code is bigger and runs slower_. The asyncified build of
|
||||
Quickjs-emscripten library is 1M, 2x larger than the 500K of the default
|
||||
version. There may be room for further
|
||||
[optimization](https://emscripten.org/docs/porting/asyncify.html#optimizing)
|
||||
Of our build in the future.
|
||||
|
||||
To use asyncify features, use the following functions:
|
||||
|
||||
- [newAsyncRuntime][]: create a runtime inside a new WebAssembly module.
|
||||
- [newAsyncContext][]: create runtime and context together inside a new
|
||||
WebAssembly module.
|
||||
- [newQuickJSAsyncWASMModule][]: create an empty WebAssembly module.
|
||||
|
||||
[newasyncruntime]: https://github.com/justjake/quickjs-emscripten/blob/main/doc/modules.md#newasyncruntime
|
||||
[newasynccontext]: https://github.com/justjake/quickjs-emscripten/blob/main/doc/modules.md#newasynccontext
|
||||
[newquickjsasyncwasmmodule]: https://github.com/justjake/quickjs-emscripten/blob/main/doc/modules.md#newquickjsasyncwasmmodule
|
||||
|
||||
These functions are asynchronous because they always create a new underlying
|
||||
WebAssembly module so that each instance can suspend and resume independently,
|
||||
and instantiating a WebAssembly module is an async operation. This also adds
|
||||
substantial overhead compared to creating a runtime or context inside an
|
||||
existing module; if you only need to wait for a single async action at a time,
|
||||
you can create a single top-level module and create runtimes or contexts inside
|
||||
of it.
|
||||
|
||||
##### Async module loader
|
||||
|
||||
Here's an example of valuating a script that loads React asynchronously as an ES
|
||||
module. In our example, we're loading from the filesystem for reproducibility,
|
||||
but you can use this technique to load using `fetch`.
|
||||
|
||||
```typescript
|
||||
const module = await newQuickJSAsyncWASMModule()
|
||||
const runtime = module.newRuntime()
|
||||
const path = await import("path")
|
||||
const { promises: fs } = await import("fs")
|
||||
|
||||
const importsPath = path.join(__dirname, "../examples/imports") + "/"
|
||||
// Module loaders can return promises.
|
||||
// Execution will suspend until the promise resolves.
|
||||
runtime.setModuleLoader((moduleName) => {
|
||||
const modulePath = path.join(importsPath, moduleName)
|
||||
if (!modulePath.startsWith(importsPath)) {
|
||||
throw new Error("out of bounds")
|
||||
}
|
||||
console.log("loading", moduleName, "from", modulePath)
|
||||
return fs.readFile(modulePath, "utf-8")
|
||||
})
|
||||
|
||||
// evalCodeAsync is required when execution may suspend.
|
||||
const context = runtime.newContext()
|
||||
const result = await context.evalCodeAsync(`
|
||||
import * as React from 'esm.sh/react@17'
|
||||
import * as ReactDOMServer from 'esm.sh/react-dom@17/server'
|
||||
const e = React.createElement
|
||||
globalThis.html = ReactDOMServer.renderToStaticMarkup(
|
||||
e('div', null, e('strong', null, 'Hello world!'))
|
||||
)
|
||||
`)
|
||||
context.unwrapResult(result).dispose()
|
||||
const html = context.getProp(context.global, "html").consume(context.getString)
|
||||
console.log(html) // <div><strong>Hello world!</strong></div>
|
||||
```
|
||||
|
||||
##### Async on host, sync in QuickJS
|
||||
|
||||
Here's an example of turning an async function into a sync function inside the
|
||||
VM.
|
||||
|
||||
```typescript
|
||||
const context = await newAsyncContext()
|
||||
const path = await import("path")
|
||||
const { promises: fs } = await import("fs")
|
||||
|
||||
const importsPath = path.join(__dirname, "../examples/imports") + "/"
|
||||
const readFileHandle = context.newAsyncifiedFunction("readFile", async (pathHandle) => {
|
||||
const pathString = path.join(importsPath, context.getString(pathHandle))
|
||||
if (!pathString.startsWith(importsPath)) {
|
||||
throw new Error("out of bounds")
|
||||
}
|
||||
const data = await fs.readFile(pathString, "utf-8")
|
||||
return context.newString(data)
|
||||
})
|
||||
readFileHandle.consume((fn) => context.setProp(context.global, "readFile", fn))
|
||||
|
||||
// evalCodeAsync is required when execution may suspend.
|
||||
const result = await context.evalCodeAsync(`
|
||||
// Not a promise! Sync! vvvvvvvvvvvvvvvvvvvv
|
||||
const data = JSON.parse(readFile('data.json'))
|
||||
data.map(x => x.toUpperCase()).join(' ')
|
||||
`)
|
||||
const upperCaseData = context.unwrapResult(result).consume(context.getString)
|
||||
console.log(upperCaseData) // 'VERY USEFUL DATA'
|
||||
```
|
||||
|
||||
### Testing your code
|
||||
|
||||
This library is complicated to use, so please consider automated testing your
|
||||
implementation. We highly writing your test suite to run with both the "release"
|
||||
build variant of quickjs-emscripten, and also the [DEBUG_SYNC] build variant.
|
||||
The debug sync build variant has extra instrumentation code for detecting memory
|
||||
leaks.
|
||||
|
||||
The class [TestQuickJSWASMModule] exposes the memory leak detection API, although
|
||||
this API is only accurate when using `DEBUG_SYNC` variant.
|
||||
|
||||
```typescript
|
||||
// Define your test suite in a function, so that you can test against
|
||||
// different module loaders.
|
||||
function myTests(moduleLoader: () => Promise<QuickJSWASMModule>) {
|
||||
let QuickJS: TestQuickJSWASMModule
|
||||
beforeEach(async () => {
|
||||
// Get a unique TestQuickJSWASMModule instance for each test.
|
||||
const wasmModule = await moduleLoader()
|
||||
QuickJS = new TestQuickJSWASMModule(wasmModule)
|
||||
})
|
||||
afterEach(() => {
|
||||
// Assert that the test disposed all handles. The DEBUG_SYNC build
|
||||
// variant will show detailed traces for each leak.
|
||||
QuickJS.assertNoMemoryAllocated()
|
||||
})
|
||||
|
||||
it("works well", () => {
|
||||
// TODO: write a test using QuickJS
|
||||
const context = QuickJS.newContext()
|
||||
context.unwrapResult(context.evalCode("1 + 1")).dispose()
|
||||
context.dispose()
|
||||
})
|
||||
}
|
||||
|
||||
// Run the test suite against a matrix of module loaders.
|
||||
describe("Check for memory leaks with QuickJS DEBUG build", () => {
|
||||
const moduleLoader = memoizePromiseFactory(() => newQuickJSWASMModule(DEBUG_SYNC))
|
||||
myTests(moduleLoader)
|
||||
})
|
||||
|
||||
describe("Realistic test with QuickJS RELEASE build", () => {
|
||||
myTests(getQuickJS)
|
||||
})
|
||||
```
|
||||
|
||||
For more testing examples, please explore the typescript source of [quickjs-emscripten][ts] repository.
|
||||
|
||||
[ts]: https://github.com/justjake/quickjs-emscripten/blob/main/ts
|
||||
[debug_sync]: https://github.com/justjake/quickjs-emscripten/blob/main/doc/modules.md#debug_sync
|
||||
[testquickjswasmmodule]: https://github.com/justjake/quickjs-emscripten/blob/main/doc/classes/TestQuickJSWASMModule.md
|
||||
|
||||
### Debugging
|
||||
|
||||
- Switch to a DEBUG build variant of the WebAssembly module to see debug log messages from the C part of this library.
|
||||
- Set `process.env.QTS_DEBUG` to see debug log messages from the Javascript part of this library.
|
||||
|
||||
### More Documentation
|
||||
|
||||
[Github] | [NPM] | [API Documentation][api] | [Examples][tests]
|
||||
|
||||
## Background
|
||||
|
||||
This was inspired by seeing https://github.com/maple3142/duktape-eval
|
||||
[on Hacker News](https://news.ycombinator.com/item?id=21946565) and Figma's
|
||||
blogposts about using building a Javascript plugin runtime:
|
||||
|
||||
- [How Figma built the Figma plugin system](https://www.figma.com/blog/how-we-built-the-figma-plugin-system/): Describes the LowLevelJavascriptVm interface.
|
||||
- [An update on plugin security](https://www.figma.com/blog/an-update-on-plugin-security/): Figma switches to QuickJS.
|
||||
|
||||
## Status & Roadmap
|
||||
|
||||
**Stability**: Because the version number of this project is below `1.0.0`,
|
||||
\*expect occasional breaking API changes.
|
||||
|
||||
**Security**: This project makes every effort to be secure, but has not been
|
||||
audited. Please use with care in production settings.
|
||||
|
||||
**Roadmap**: I work on this project in my free time, for fun. Here's I'm
|
||||
thinking comes next. Last updated 2022-03-18.
|
||||
|
||||
1. Further work on module loading APIs:
|
||||
|
||||
- Create modules via Javascript, instead of source text.
|
||||
- Scan source text for imports, for ahead of time or concurrent loading.
|
||||
(This is possible with third-party tools, so lower priority.)
|
||||
|
||||
2. Higher-level tools for reading QuickJS values:
|
||||
|
||||
- Type guard functions: `context.isArray(handle)`, `context.isPromise(handle)`, etc.
|
||||
- Iteration utilities: `context.getIterable(handle)`, `context.iterateObjectEntries(handle)`.
|
||||
This better supports user-level code to deserialize complex handle objects.
|
||||
|
||||
3. Higher-level tools for creating QuickJS values:
|
||||
|
||||
- Devise a way to avoid needing to mess around with handles when setting up
|
||||
the environment.
|
||||
- Consider integrating
|
||||
[quickjs-emscripten-sync](https://github.com/reearth/quickjs-emscripten-sync)
|
||||
for automatic translation.
|
||||
- Consider class-based or interface-type-based marshalling.
|
||||
|
||||
4. EcmaScript Modules / WebAssembly files / Deno support. This requires me to
|
||||
learn a lot of new things, but should be interesting for modern browser usage.
|
||||
|
||||
5. SQLite integration.
|
||||
|
||||
## Related
|
||||
|
||||
- Duktape wrapped in Wasm: https://github.com/maple3142/duktape-eval/blob/main/src/Makefile
|
||||
- QuickJS wrapped in C++: https://github.com/ftk/quickjspp
|
||||
|
||||
## Developing
|
||||
|
||||
This library is implemented in two languages: C (compiled to WASM with
|
||||
Emscripten), and Typescript.
|
||||
|
||||
### The C parts
|
||||
|
||||
The ./c directory contains C code that wraps the QuickJS C library (in ./quickjs).
|
||||
Public functions (those starting with `QTS_`) in ./c/interface.c are
|
||||
automatically exported to native code (via a generated header) and to
|
||||
Typescript (via a generated FFI class). See ./generate.ts for how this works.
|
||||
|
||||
The C code builds as both with `emscripten` (using `emcc`), to produce WASM (or
|
||||
ASM.js) and with `clang`. Build outputs are checked in, so you can iterate on
|
||||
the Javascript parts of the library without setting up the Emscripten toolchain.
|
||||
|
||||
Intermediate object files from QuickJS end up in ./build/quickjs/.
|
||||
|
||||
This project uses `emscripten 3.1.32`.
|
||||
|
||||
- On ARM64, you should install `emscripten` on your machine. For example on macOS, `brew install emscripten`.
|
||||
- If _the correct version of emcc_ is not in your PATH, compilation falls back to using Docker.
|
||||
On ARM64, this is 10-50x slower than native compilation, but it's just fine on x64.
|
||||
|
||||
Related NPM scripts:
|
||||
|
||||
- `yarn update-quickjs` will sync the ./quickjs folder with a
|
||||
github repo tracking the upstream QuickJS.
|
||||
- `yarn make-debug` will rebuild C outputs into ./build/wrapper
|
||||
- `yarn make-release` will rebuild C outputs in release mode, which is the mode
|
||||
that should be checked into the repo.
|
||||
|
||||
### The Typescript parts
|
||||
|
||||
The ./ts directory contains Typescript types and wraps the generated Emscripten
|
||||
FFI in a more usable interface.
|
||||
|
||||
You'll need `node` and `yarn`. Install dependencies with `yarn install`.
|
||||
|
||||
- `yarn build` produces ./dist.
|
||||
- `yarn test` runs the tests.
|
||||
- `yarn test --watch` watches for changes and re-runs the tests.
|
||||
|
||||
### Yarn updates
|
||||
|
||||
Just run `yarn set version from sources` to upgrade the Yarn release.
|
||||
819
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/c/interface.c
generated
vendored
Normal file
819
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/c/interface.c
generated
vendored
Normal file
@@ -0,0 +1,819 @@
|
||||
/**
|
||||
* interface.c
|
||||
*
|
||||
* We primarily use JSValue* (pointer to JSValue) when communicating with the
|
||||
* host javascript environment, because pointers are trivial to use for calls
|
||||
* into emscripten because they're just a number!
|
||||
*
|
||||
* As with the quickjs.h API, a JSValueConst* value is "borrowed" and should
|
||||
* not be freed. A JSValue* is "owned" and should be freed by the owner.
|
||||
*
|
||||
* Functions starting with "QTS_" are exported by generate.ts to:
|
||||
* - interface.h for native C code.
|
||||
* - ffi.ts for emscripten.
|
||||
*
|
||||
* We support building the following build outputs:
|
||||
*
|
||||
* ## 1. Native machine code
|
||||
* For internal development testing purposes.
|
||||
*
|
||||
* ## 2. WASM via Emscripten
|
||||
* For general production use.
|
||||
*
|
||||
* ## 3. Experimental: Asyncified WASM via Emscripten with -s ASYNCIFY=1.
|
||||
* This variant supports treating async host Javascript calls as synchronous
|
||||
* from the perspective of the WASM c code.
|
||||
*
|
||||
* The way this works is described here:
|
||||
* https://emscripten.org/docs/porting/asyncify.html
|
||||
*
|
||||
* In this variant, any call into our C code could return a promise if it ended
|
||||
* up suspended. We mark the methods we suspect might suspend due to users' code
|
||||
* as returning MaybeAsync(T). This information is ignored for the regular
|
||||
* build.
|
||||
*/
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten.h>
|
||||
#endif
|
||||
|
||||
#include <math.h> // For NAN
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#ifdef QTS_SANITIZE_LEAK
|
||||
#include <sanitizer/lsan_interface.h>
|
||||
#endif
|
||||
|
||||
#include "../quickjs/cutils.h"
|
||||
#include "../quickjs/quickjs-libc.h"
|
||||
#include "../quickjs/quickjs.h"
|
||||
|
||||
#define PKG "quickjs-emscripten: "
|
||||
|
||||
#ifdef QTS_DEBUG_MODE
|
||||
#define QTS_DEBUG(msg) qts_log(msg);
|
||||
#define QTS_DUMP(value) qts_dump(ctx, value);
|
||||
#else
|
||||
#define QTS_DEBUG(msg) ;
|
||||
#define QTS_DUMP(value) ;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Signal to our FFI code generator that this string argument should be passed as a pointer
|
||||
* allocated by the caller on the heap, not a JS string on the stack.
|
||||
* https://github.com/emscripten-core/emscripten/issues/6860#issuecomment-405818401
|
||||
*/
|
||||
#define BorrowedHeapChar const char
|
||||
#define OwnedHeapChar char
|
||||
#define JSBorrowedChar const char
|
||||
|
||||
/**
|
||||
* Signal to our FFI code generator that this function should be called
|
||||
* asynchronously when compiled with ASYNCIFY.
|
||||
*/
|
||||
#define MaybeAsync(T) T
|
||||
|
||||
/**
|
||||
* Signal to our FFI code generator that this function is only available in
|
||||
* ASYNCIFY builds.
|
||||
*/
|
||||
#define AsyncifyOnly(T) T
|
||||
|
||||
#define JSVoid void
|
||||
|
||||
#define EvalFlags int
|
||||
#define EvalDetectModule int
|
||||
|
||||
void qts_log(char *msg) {
|
||||
fputs(PKG, stderr);
|
||||
fputs(msg, stderr);
|
||||
fputs("\n", stderr);
|
||||
}
|
||||
|
||||
void qts_dump(JSContext *ctx, JSValueConst value) {
|
||||
const char *str = JS_ToCString(ctx, value);
|
||||
if (!str) {
|
||||
QTS_DEBUG("QTS_DUMP: can't dump");
|
||||
return;
|
||||
}
|
||||
fputs(str, stderr);
|
||||
JS_FreeCString(ctx, str);
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
void copy_prop_if_needed(JSContext *ctx, JSValueConst dest, JSValueConst src, const char *prop_name) {
|
||||
JSAtom prop_atom = JS_NewAtom(ctx, prop_name);
|
||||
JSValue dest_prop = JS_GetProperty(ctx, dest, prop_atom);
|
||||
if (JS_IsUndefined(dest_prop)) {
|
||||
JSValue src_prop = JS_GetProperty(ctx, src, prop_atom);
|
||||
if (!JS_IsUndefined(src_prop) && !JS_IsException(src_prop)) {
|
||||
JS_SetProperty(ctx, dest, prop_atom, src_prop);
|
||||
}
|
||||
} else {
|
||||
JS_FreeValue(ctx, dest_prop);
|
||||
}
|
||||
JS_FreeAtom(ctx, prop_atom);
|
||||
}
|
||||
|
||||
JSValue *jsvalue_to_heap(JSValueConst value) {
|
||||
JSValue *result = malloc(sizeof(JSValue));
|
||||
if (result) {
|
||||
// Could be better optimized, but at -0z / -ftlo, it
|
||||
// appears to produce the same binary code as a memcpy.
|
||||
*result = value;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
JSValue *QTS_Throw(JSContext *ctx, JSValueConst *error) {
|
||||
JSValue copy = JS_DupValue(ctx, *error);
|
||||
return jsvalue_to_heap(JS_Throw(ctx, copy));
|
||||
}
|
||||
|
||||
JSValue *QTS_NewError(JSContext *ctx) {
|
||||
return jsvalue_to_heap(JS_NewError(ctx));
|
||||
}
|
||||
|
||||
/**
|
||||
* Limits.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Memory limit. Set to -1 to disable.
|
||||
*/
|
||||
void QTS_RuntimeSetMemoryLimit(JSRuntime *rt, size_t limit) {
|
||||
JS_SetMemoryLimit(rt, limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Memory diagnostics
|
||||
*/
|
||||
|
||||
JSValue *QTS_RuntimeComputeMemoryUsage(JSRuntime *rt, JSContext *ctx) {
|
||||
JSMemoryUsage s;
|
||||
JS_ComputeMemoryUsage(rt, &s);
|
||||
|
||||
// Note that we're going to allocate more memory just to report the memory usage.
|
||||
// A more sound approach would be to bind JSMemoryUsage struct directly - but that's
|
||||
// a lot of work. This should be okay in the mean time.
|
||||
JSValue result = JS_NewObject(ctx);
|
||||
|
||||
// Manually generated via editor-fu from JSMemoryUsage struct definition in quickjs.h
|
||||
JS_SetPropertyStr(ctx, result, "malloc_limit", JS_NewInt64(ctx, s.malloc_limit));
|
||||
JS_SetPropertyStr(ctx, result, "memory_used_size", JS_NewInt64(ctx, s.memory_used_size));
|
||||
JS_SetPropertyStr(ctx, result, "malloc_count", JS_NewInt64(ctx, s.malloc_count));
|
||||
JS_SetPropertyStr(ctx, result, "memory_used_count", JS_NewInt64(ctx, s.memory_used_count));
|
||||
JS_SetPropertyStr(ctx, result, "atom_count", JS_NewInt64(ctx, s.atom_count));
|
||||
JS_SetPropertyStr(ctx, result, "atom_size", JS_NewInt64(ctx, s.atom_size));
|
||||
JS_SetPropertyStr(ctx, result, "str_count", JS_NewInt64(ctx, s.str_count));
|
||||
JS_SetPropertyStr(ctx, result, "str_size", JS_NewInt64(ctx, s.str_size));
|
||||
JS_SetPropertyStr(ctx, result, "obj_count", JS_NewInt64(ctx, s.obj_count));
|
||||
JS_SetPropertyStr(ctx, result, "obj_size", JS_NewInt64(ctx, s.obj_size));
|
||||
JS_SetPropertyStr(ctx, result, "prop_count", JS_NewInt64(ctx, s.prop_count));
|
||||
JS_SetPropertyStr(ctx, result, "prop_size", JS_NewInt64(ctx, s.prop_size));
|
||||
JS_SetPropertyStr(ctx, result, "shape_count", JS_NewInt64(ctx, s.shape_count));
|
||||
JS_SetPropertyStr(ctx, result, "shape_size", JS_NewInt64(ctx, s.shape_size));
|
||||
JS_SetPropertyStr(ctx, result, "js_func_count", JS_NewInt64(ctx, s.js_func_count));
|
||||
JS_SetPropertyStr(ctx, result, "js_func_size", JS_NewInt64(ctx, s.js_func_size));
|
||||
JS_SetPropertyStr(ctx, result, "js_func_code_size", JS_NewInt64(ctx, s.js_func_code_size));
|
||||
JS_SetPropertyStr(ctx, result, "js_func_pc2line_count", JS_NewInt64(ctx, s.js_func_pc2line_count));
|
||||
JS_SetPropertyStr(ctx, result, "js_func_pc2line_size", JS_NewInt64(ctx, s.js_func_pc2line_size));
|
||||
JS_SetPropertyStr(ctx, result, "c_func_count", JS_NewInt64(ctx, s.c_func_count));
|
||||
JS_SetPropertyStr(ctx, result, "array_count", JS_NewInt64(ctx, s.array_count));
|
||||
JS_SetPropertyStr(ctx, result, "fast_array_count", JS_NewInt64(ctx, s.fast_array_count));
|
||||
JS_SetPropertyStr(ctx, result, "fast_array_elements", JS_NewInt64(ctx, s.fast_array_elements));
|
||||
JS_SetPropertyStr(ctx, result, "binary_object_count", JS_NewInt64(ctx, s.binary_object_count));
|
||||
JS_SetPropertyStr(ctx, result, "binary_object_size", JS_NewInt64(ctx, s.binary_object_size));
|
||||
|
||||
return jsvalue_to_heap(result);
|
||||
}
|
||||
|
||||
OwnedHeapChar *QTS_RuntimeDumpMemoryUsage(JSRuntime *rt) {
|
||||
char *result = malloc(sizeof(char) * 1024);
|
||||
FILE *memfile = fmemopen(result, 1024, "w");
|
||||
JSMemoryUsage s;
|
||||
JS_ComputeMemoryUsage(rt, &s);
|
||||
JS_DumpMemoryUsage(memfile, &s, rt);
|
||||
fclose(memfile);
|
||||
return result;
|
||||
}
|
||||
|
||||
int QTS_RecoverableLeakCheck() {
|
||||
#ifdef QTS_SANITIZE_LEAK
|
||||
return __lsan_do_recoverable_leak_check();
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int QTS_BuildIsSanitizeLeak() {
|
||||
#ifdef QTS_SANITIZE_LEAK
|
||||
return 1;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef QTS_ASYNCIFY
|
||||
EM_JS(void, set_asyncify_stack_size, (size_t size), {
|
||||
Asyncify.StackSize = size || 81920;
|
||||
});
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Set the stack size limit, in bytes. Set to 0 to disable.
|
||||
*/
|
||||
void QTS_RuntimeSetMaxStackSize(JSRuntime *rt, size_t stack_size) {
|
||||
#ifdef QTS_ASYNCIFY
|
||||
set_asyncify_stack_size(stack_size);
|
||||
#endif
|
||||
JS_SetMaxStackSize(rt, stack_size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constant pointers. Because we always use JSValue* from the host Javascript environment,
|
||||
* we need helper fuctions to return pointers to these constants.
|
||||
*/
|
||||
|
||||
JSValueConst QTS_Undefined = JS_UNDEFINED;
|
||||
JSValueConst *QTS_GetUndefined() {
|
||||
return &QTS_Undefined;
|
||||
}
|
||||
|
||||
JSValueConst QTS_Null = JS_NULL;
|
||||
JSValueConst *QTS_GetNull() {
|
||||
return &QTS_Null;
|
||||
}
|
||||
|
||||
JSValueConst QTS_False = JS_FALSE;
|
||||
JSValueConst *QTS_GetFalse() {
|
||||
return &QTS_False;
|
||||
}
|
||||
|
||||
JSValueConst QTS_True = JS_TRUE;
|
||||
JSValueConst *QTS_GetTrue() {
|
||||
return &QTS_True;
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard FFI functions
|
||||
*/
|
||||
|
||||
JSRuntime *QTS_NewRuntime() {
|
||||
return JS_NewRuntime();
|
||||
}
|
||||
|
||||
void QTS_FreeRuntime(JSRuntime *rt) {
|
||||
JS_FreeRuntime(rt);
|
||||
}
|
||||
|
||||
JSContext *QTS_NewContext(JSRuntime *rt) {
|
||||
return JS_NewContext(rt);
|
||||
}
|
||||
|
||||
void QTS_FreeContext(JSContext *ctx) {
|
||||
JS_FreeContext(ctx);
|
||||
}
|
||||
|
||||
void QTS_FreeValuePointer(JSContext *ctx, JSValue *value) {
|
||||
JS_FreeValue(ctx, *value);
|
||||
free(value);
|
||||
}
|
||||
|
||||
void QTS_FreeValuePointerRuntime(JSRuntime *rt, JSValue *value) {
|
||||
JS_FreeValueRT(rt, *value);
|
||||
free(value);
|
||||
}
|
||||
|
||||
void QTS_FreeVoidPointer(JSContext *ctx, JSVoid *ptr) {
|
||||
js_free(ctx, ptr);
|
||||
}
|
||||
|
||||
void QTS_FreeCString(JSContext *ctx, JSBorrowedChar *str) {
|
||||
JS_FreeCString(ctx, str);
|
||||
}
|
||||
|
||||
JSValue *QTS_DupValuePointer(JSContext *ctx, JSValueConst *val) {
|
||||
return jsvalue_to_heap(JS_DupValue(ctx, *val));
|
||||
}
|
||||
|
||||
JSValue *QTS_NewObject(JSContext *ctx) {
|
||||
return jsvalue_to_heap(JS_NewObject(ctx));
|
||||
}
|
||||
|
||||
JSValue *QTS_NewObjectProto(JSContext *ctx, JSValueConst *proto) {
|
||||
return jsvalue_to_heap(JS_NewObjectProto(ctx, *proto));
|
||||
}
|
||||
|
||||
JSValue *QTS_NewArray(JSContext *ctx) {
|
||||
return jsvalue_to_heap(JS_NewArray(ctx));
|
||||
}
|
||||
|
||||
JSValue *QTS_NewFloat64(JSContext *ctx, double num) {
|
||||
return jsvalue_to_heap(JS_NewFloat64(ctx, num));
|
||||
}
|
||||
|
||||
double QTS_GetFloat64(JSContext *ctx, JSValueConst *value) {
|
||||
double result = NAN;
|
||||
JS_ToFloat64(ctx, &result, *value);
|
||||
return result;
|
||||
}
|
||||
|
||||
JSValue *QTS_NewString(JSContext *ctx, BorrowedHeapChar *string) {
|
||||
return jsvalue_to_heap(JS_NewString(ctx, string));
|
||||
}
|
||||
|
||||
JSBorrowedChar *QTS_GetString(JSContext *ctx, JSValueConst *value) {
|
||||
return JS_ToCString(ctx, *value);
|
||||
}
|
||||
|
||||
JSValue qts_get_symbol_key(JSContext *ctx, JSValueConst *value) {
|
||||
JSValue global = JS_GetGlobalObject(ctx);
|
||||
JSValue Symbol = JS_GetPropertyStr(ctx, global, "Symbol");
|
||||
JS_FreeValue(ctx, global);
|
||||
|
||||
JSValue Symbol_keyFor = JS_GetPropertyStr(ctx, Symbol, "keyFor");
|
||||
JSValue key = JS_Call(ctx, Symbol_keyFor, Symbol, 1, value);
|
||||
JS_FreeValue(ctx, Symbol_keyFor);
|
||||
JS_FreeValue(ctx, Symbol);
|
||||
return key;
|
||||
}
|
||||
|
||||
JSValue *QTS_NewSymbol(JSContext *ctx, BorrowedHeapChar *description, int isGlobal) {
|
||||
JSValue global = JS_GetGlobalObject(ctx);
|
||||
JSValue Symbol = JS_GetPropertyStr(ctx, global, "Symbol");
|
||||
JS_FreeValue(ctx, global);
|
||||
JSValue descriptionValue = JS_NewString(ctx, description);
|
||||
JSValue symbol;
|
||||
|
||||
if (isGlobal != 0) {
|
||||
JSValue Symbol_for = JS_GetPropertyStr(ctx, Symbol, "for");
|
||||
symbol = JS_Call(ctx, Symbol_for, Symbol, 1, &descriptionValue);
|
||||
JS_FreeValue(ctx, descriptionValue);
|
||||
JS_FreeValue(ctx, Symbol_for);
|
||||
JS_FreeValue(ctx, Symbol);
|
||||
return jsvalue_to_heap(symbol);
|
||||
}
|
||||
|
||||
symbol = JS_Call(ctx, Symbol, JS_UNDEFINED, 1, &descriptionValue);
|
||||
JS_FreeValue(ctx, descriptionValue);
|
||||
JS_FreeValue(ctx, Symbol);
|
||||
|
||||
return jsvalue_to_heap(symbol);
|
||||
}
|
||||
|
||||
MaybeAsync(JSBorrowedChar *) QTS_GetSymbolDescriptionOrKey(JSContext *ctx, JSValueConst *value) {
|
||||
JSBorrowedChar *result;
|
||||
|
||||
JSValue key = qts_get_symbol_key(ctx, value);
|
||||
if (!JS_IsUndefined(key)) {
|
||||
result = JS_ToCString(ctx, key);
|
||||
JS_FreeValue(ctx, key);
|
||||
return result;
|
||||
}
|
||||
|
||||
JSValue description = JS_GetPropertyStr(ctx, *value, "description");
|
||||
result = JS_ToCString(ctx, description);
|
||||
JS_FreeValue(ctx, description);
|
||||
return result;
|
||||
}
|
||||
|
||||
int QTS_IsGlobalSymbol(JSContext *ctx, JSValueConst *value) {
|
||||
JSValue key = qts_get_symbol_key(ctx, value);
|
||||
int undefined = JS_IsUndefined(key);
|
||||
JS_FreeValue(ctx, key);
|
||||
|
||||
if (undefined) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int QTS_IsJobPending(JSRuntime *rt) {
|
||||
return JS_IsJobPending(rt);
|
||||
}
|
||||
|
||||
/*
|
||||
runs pending jobs (Promises/async functions) until it encounters
|
||||
an exception or it executed the passed maxJobsToExecute jobs.
|
||||
|
||||
Passing a negative value will run the loop until there are no more
|
||||
pending jobs or an exception happened
|
||||
|
||||
Returns the executed number of jobs or the exception encountered
|
||||
*/
|
||||
MaybeAsync(JSValue *) QTS_ExecutePendingJob(JSRuntime *rt, int maxJobsToExecute, JSContext **lastJobContext) {
|
||||
JSContext *pctx;
|
||||
int status = 1;
|
||||
int executed = 0;
|
||||
while (executed != maxJobsToExecute && status == 1) {
|
||||
status = JS_ExecutePendingJob(rt, &pctx);
|
||||
if (status == -1) {
|
||||
*lastJobContext = pctx;
|
||||
return jsvalue_to_heap(JS_GetException(pctx));
|
||||
} else if (status == 1) {
|
||||
*lastJobContext = pctx;
|
||||
executed++;
|
||||
}
|
||||
}
|
||||
#ifdef QTS_DEBUG_MODE
|
||||
char msg[500];
|
||||
sprintf(msg, "QTS_ExecutePendingJob(executed: %d, pctx: %p, lastJobExecuted: %p)", executed, pctx, *lastJobContext);
|
||||
QTS_DEBUG(msg)
|
||||
#endif
|
||||
return jsvalue_to_heap(JS_NewFloat64(pctx, executed));
|
||||
}
|
||||
|
||||
MaybeAsync(JSValue *) QTS_GetProp(JSContext *ctx, JSValueConst *this_val, JSValueConst *prop_name) {
|
||||
JSAtom prop_atom = JS_ValueToAtom(ctx, *prop_name);
|
||||
JSValue prop_val = JS_GetProperty(ctx, *this_val, prop_atom);
|
||||
JS_FreeAtom(ctx, prop_atom);
|
||||
return jsvalue_to_heap(prop_val);
|
||||
}
|
||||
|
||||
MaybeAsync(void) QTS_SetProp(JSContext *ctx, JSValueConst *this_val, JSValueConst *prop_name, JSValueConst *prop_value) {
|
||||
JSAtom prop_atom = JS_ValueToAtom(ctx, *prop_name);
|
||||
JSValue extra_prop_value = JS_DupValue(ctx, *prop_value);
|
||||
// TODO: should we use DefineProperty internally if this object doesn't have the property yet?
|
||||
JS_SetProperty(ctx, *this_val, prop_atom, extra_prop_value); // consumes extra_prop_value
|
||||
JS_FreeAtom(ctx, prop_atom);
|
||||
}
|
||||
|
||||
void QTS_DefineProp(JSContext *ctx, JSValueConst *this_val, JSValueConst *prop_name, JSValueConst *prop_value, JSValueConst *get, JSValueConst *set, bool configurable, bool enumerable, bool has_value) {
|
||||
JSAtom prop_atom = JS_ValueToAtom(ctx, *prop_name);
|
||||
|
||||
int flags = 0;
|
||||
if (configurable) {
|
||||
flags = flags | JS_PROP_CONFIGURABLE;
|
||||
if (has_value) {
|
||||
flags = flags | JS_PROP_HAS_CONFIGURABLE;
|
||||
}
|
||||
}
|
||||
if (enumerable) {
|
||||
flags = flags | JS_PROP_ENUMERABLE;
|
||||
if (has_value) {
|
||||
flags = flags | JS_PROP_HAS_ENUMERABLE;
|
||||
}
|
||||
}
|
||||
if (!JS_IsUndefined(*get)) {
|
||||
flags = flags | JS_PROP_HAS_GET;
|
||||
}
|
||||
if (!JS_IsUndefined(*set)) {
|
||||
flags = flags | JS_PROP_HAS_SET;
|
||||
}
|
||||
if (has_value) {
|
||||
flags = flags | JS_PROP_HAS_VALUE;
|
||||
}
|
||||
|
||||
JS_DefineProperty(ctx, *this_val, prop_atom, *prop_value, *get, *set, flags);
|
||||
JS_FreeAtom(ctx, prop_atom);
|
||||
}
|
||||
|
||||
MaybeAsync(JSValue *) QTS_Call(JSContext *ctx, JSValueConst *func_obj, JSValueConst *this_obj, int argc, JSValueConst **argv_ptrs) {
|
||||
// convert array of pointers to array of values
|
||||
JSValueConst argv[argc];
|
||||
int i;
|
||||
for (i = 0; i < argc; i++) {
|
||||
argv[i] = *(argv_ptrs[i]);
|
||||
}
|
||||
|
||||
return jsvalue_to_heap(JS_Call(ctx, *func_obj, *this_obj, argc, argv));
|
||||
}
|
||||
|
||||
/**
|
||||
* If maybe_exception is an exception, get the error.
|
||||
* Otherwise, return NULL.
|
||||
*/
|
||||
JSValue *QTS_ResolveException(JSContext *ctx, JSValue *maybe_exception) {
|
||||
if (JS_IsException(*maybe_exception)) {
|
||||
return jsvalue_to_heap(JS_GetException(ctx));
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MaybeAsync(JSBorrowedChar *) QTS_Dump(JSContext *ctx, JSValueConst *obj) {
|
||||
JSValue obj_json_value = JS_JSONStringify(ctx, *obj, JS_UNDEFINED, JS_UNDEFINED);
|
||||
if (!JS_IsException(obj_json_value)) {
|
||||
const char *obj_json_chars = JS_ToCString(ctx, obj_json_value);
|
||||
JS_FreeValue(ctx, obj_json_value);
|
||||
if (obj_json_chars != NULL) {
|
||||
JSValue enumerable_props = JS_ParseJSON(ctx, obj_json_chars, strlen(obj_json_chars), "<dump>");
|
||||
JS_FreeCString(ctx, obj_json_chars);
|
||||
if (!JS_IsException(enumerable_props)) {
|
||||
// Copy common non-enumerable props for different object types.
|
||||
// Errors:
|
||||
copy_prop_if_needed(ctx, enumerable_props, *obj, "name");
|
||||
copy_prop_if_needed(ctx, enumerable_props, *obj, "message");
|
||||
copy_prop_if_needed(ctx, enumerable_props, *obj, "stack");
|
||||
|
||||
// Serialize again.
|
||||
JSValue enumerable_json = JS_JSONStringify(ctx, enumerable_props, JS_UNDEFINED, JS_UNDEFINED);
|
||||
JS_FreeValue(ctx, enumerable_props);
|
||||
|
||||
JSBorrowedChar *result = QTS_GetString(ctx, &enumerable_json);
|
||||
JS_FreeValue(ctx, enumerable_json);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef QTS_DEBUG_MODE
|
||||
qts_log("Error dumping JSON:");
|
||||
js_std_dump_error(ctx);
|
||||
#endif
|
||||
|
||||
// Fallback: convert to string
|
||||
return QTS_GetString(ctx, obj);
|
||||
}
|
||||
|
||||
MaybeAsync(JSValue *) QTS_Eval(JSContext *ctx, BorrowedHeapChar *js_code, const char *filename, EvalDetectModule detectModule, EvalFlags evalFlags) {
|
||||
size_t js_code_len = strlen(js_code);
|
||||
|
||||
if (detectModule) {
|
||||
if (JS_DetectModule((const char *)js_code, js_code_len)) {
|
||||
QTS_DEBUG("QTS_Eval: Detected module = true");
|
||||
evalFlags |= JS_EVAL_TYPE_MODULE;
|
||||
} else {
|
||||
QTS_DEBUG("QTS_Eval: Detected module = false");
|
||||
}
|
||||
} else {
|
||||
QTS_DEBUG("QTS_Eval: do not detect module");
|
||||
}
|
||||
|
||||
return jsvalue_to_heap(JS_Eval(ctx, js_code, strlen(js_code), filename, evalFlags));
|
||||
}
|
||||
|
||||
OwnedHeapChar *QTS_Typeof(JSContext *ctx, JSValueConst *value) {
|
||||
const char *result = "unknown";
|
||||
uint32_t tag = JS_VALUE_GET_TAG(*value);
|
||||
|
||||
if (JS_IsNumber(*value)) {
|
||||
result = "number";
|
||||
} else if (JS_IsBigInt(ctx, *value)) {
|
||||
result = "bigint";
|
||||
} else if (JS_IsBigFloat(*value)) {
|
||||
result = "bigfloat";
|
||||
} else if (JS_IsBigDecimal(*value)) {
|
||||
result = "bigdecimal";
|
||||
} else if (JS_IsFunction(ctx, *value)) {
|
||||
result = "function";
|
||||
} else if (JS_IsBool(*value)) {
|
||||
result = "boolean";
|
||||
} else if (JS_IsNull(*value)) {
|
||||
result = "object";
|
||||
} else if (JS_IsUndefined(*value)) {
|
||||
result = "undefined";
|
||||
} else if (JS_IsUninitialized(*value)) {
|
||||
result = "undefined";
|
||||
} else if (JS_IsString(*value)) {
|
||||
result = "string";
|
||||
} else if (JS_IsSymbol(*value)) {
|
||||
result = "symbol";
|
||||
} else if (JS_IsObject(*value)) {
|
||||
result = "object";
|
||||
}
|
||||
|
||||
char *out = strdup(result);
|
||||
return out;
|
||||
}
|
||||
|
||||
JSValue *QTS_GetGlobalObject(JSContext *ctx) {
|
||||
return jsvalue_to_heap(JS_GetGlobalObject(ctx));
|
||||
}
|
||||
|
||||
JSValue *QTS_NewPromiseCapability(JSContext *ctx, JSValue **resolve_funcs_out) {
|
||||
JSValue resolve_funcs[2];
|
||||
JSValue promise = JS_NewPromiseCapability(ctx, resolve_funcs);
|
||||
resolve_funcs_out[0] = jsvalue_to_heap(resolve_funcs[0]);
|
||||
resolve_funcs_out[1] = jsvalue_to_heap(resolve_funcs[1]);
|
||||
return jsvalue_to_heap(promise);
|
||||
}
|
||||
|
||||
void QTS_TestStringArg(const char *string) {
|
||||
// pass
|
||||
}
|
||||
|
||||
int QTS_BuildIsDebug() {
|
||||
#ifdef QTS_DEBUG_MODE
|
||||
return 1;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int QTS_BuildIsAsyncify() {
|
||||
#ifdef QTS_ASYNCIFY
|
||||
return 1;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Module loading helpers
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// C -> Host Callbacks
|
||||
// Note: inside EM_JS, we need to use ['...'] subscript syntax for accessing JS
|
||||
// objects, because in optimized builds, Closure compiler will mangle all the
|
||||
// names.
|
||||
|
||||
// -------------------
|
||||
// function: C -> Host
|
||||
#ifdef __EMSCRIPTEN__
|
||||
EM_JS(MaybeAsync(JSValue *), qts_host_call_function, (JSContext * ctx, JSValueConst *this_ptr, int argc, JSValueConst *argv, uint32_t magic_func_id), {
|
||||
#ifdef QTS_ASYNCIFY
|
||||
const asyncify = {['handleSleep'] : Asyncify.handleSleep};
|
||||
#else
|
||||
const asyncify = undefined;
|
||||
#endif
|
||||
return Module['callbacks']['callFunction'](asyncify, ctx, this_ptr, argc, argv, magic_func_id);
|
||||
});
|
||||
#endif
|
||||
|
||||
// Function: QuickJS -> C
|
||||
JSValue qts_call_function(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) {
|
||||
JSValue *result_ptr = qts_host_call_function(ctx, &this_val, argc, argv, magic);
|
||||
if (result_ptr == NULL) {
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
JSValue result = *result_ptr;
|
||||
free(result_ptr);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Function: Host -> QuickJS
|
||||
JSValue *QTS_NewFunction(JSContext *ctx, uint32_t func_id, const char *name) {
|
||||
#ifdef QTS_DEBUG_MODE
|
||||
char msg[500];
|
||||
sprintf(msg, "new_function(name: %s, magic: %d)", name, func_id);
|
||||
QTS_DEBUG(msg)
|
||||
#endif
|
||||
JSValue func_obj = JS_NewCFunctionMagic(
|
||||
/* context */ ctx,
|
||||
/* JSCFunctionMagic* */ &qts_call_function,
|
||||
/* name */ name,
|
||||
/* min argc */ 0,
|
||||
/* function type */ JS_CFUNC_generic_magic,
|
||||
/* magic: fn id */ func_id);
|
||||
return jsvalue_to_heap(func_obj);
|
||||
}
|
||||
|
||||
JSValueConst *QTS_ArgvGetJSValueConstPointer(JSValueConst *argv, int index) {
|
||||
return &argv[index];
|
||||
}
|
||||
|
||||
// --------------------
|
||||
// interrupt: C -> Host
|
||||
#ifdef __EMSCRIPTEN__
|
||||
EM_JS(int, qts_host_interrupt_handler, (JSRuntime * rt), {
|
||||
// Async not supported here.
|
||||
// #ifdef QTS_ASYNCIFY
|
||||
// const asyncify = Asyncify;
|
||||
// #else
|
||||
const asyncify = undefined;
|
||||
// #endif
|
||||
return Module['callbacks']['shouldInterrupt'](asyncify, rt);
|
||||
});
|
||||
#endif
|
||||
|
||||
// interrupt: QuickJS -> C
|
||||
int qts_interrupt_handler(JSRuntime *rt, void *_unused) {
|
||||
return qts_host_interrupt_handler(rt);
|
||||
}
|
||||
|
||||
// interrupt: Host -> QuickJS
|
||||
void QTS_RuntimeEnableInterruptHandler(JSRuntime *rt) {
|
||||
JS_SetInterruptHandler(rt, &qts_interrupt_handler, NULL);
|
||||
}
|
||||
|
||||
void QTS_RuntimeDisableInterruptHandler(JSRuntime *rt) {
|
||||
JS_SetInterruptHandler(rt, NULL, NULL);
|
||||
}
|
||||
|
||||
// --------------------
|
||||
// load module: C -> Host
|
||||
// TODO: a future version can support host returning JSModuleDef* directly;
|
||||
// for now we only support loading module source code.
|
||||
|
||||
/*
|
||||
The module loading model under ASYNCIFY is convoluted. We need to make sure we
|
||||
never have an async request running concurrently for loading modules.
|
||||
|
||||
The first implemenation looked like this:
|
||||
|
||||
C HOST SUSPENDED
|
||||
qts_host_load_module(name) ------> false
|
||||
call rt.loadModule(name) false
|
||||
Start async load module false
|
||||
Suspend C true
|
||||
Async load complete true
|
||||
< --------------- QTS_CompileModule(source) true
|
||||
QTS_Eval(source, COMPILE_ONLY) true
|
||||
Loaded module has import true
|
||||
qts_host_load_module(dep) -------> true
|
||||
call rt.loadModule(dep) true
|
||||
Start async load module true
|
||||
ALREADY SUSPENDED, CRASH
|
||||
|
||||
We can solve this in two different ways:
|
||||
|
||||
1. Return to C as soon as we async load the module source.
|
||||
That way, we unsuspend before calling QTS_CompileModule.
|
||||
2. Once we load the module, use a new API to detect and async
|
||||
load the module's downstream dependencies. This way
|
||||
they're loaded synchronously so we don't need to suspend "again".
|
||||
|
||||
Probably we could optimize (2) to make it more performant, eg with parallel
|
||||
loading, but (1) seems much easier to implement in the sort run.
|
||||
*/
|
||||
|
||||
JSModuleDef *qts_compile_module(JSContext *ctx, const char *module_name, BorrowedHeapChar *module_body) {
|
||||
#ifdef QTS_DEBUG_MODE
|
||||
char msg[500];
|
||||
sprintf(msg, "QTS_CompileModule(ctx: %p, name: %s, bodyLength: %lu)", ctx, module_name, strlen(module_body));
|
||||
QTS_DEBUG(msg)
|
||||
#endif
|
||||
JSValue func_val = JS_Eval(ctx, module_body, strlen(module_body), module_name, JS_EVAL_TYPE_MODULE | JS_EVAL_FLAG_COMPILE_ONLY);
|
||||
if (JS_IsException(func_val)) {
|
||||
return NULL;
|
||||
}
|
||||
// TODO: Is exception ok?
|
||||
// TODO: set import.meta?
|
||||
JSModuleDef *module = JS_VALUE_GET_PTR(func_val);
|
||||
JS_FreeValue(ctx, func_val);
|
||||
return module;
|
||||
}
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
EM_JS(MaybeAsync(char *), qts_host_load_module_source, (JSRuntime * rt, JSContext *ctx, const char *module_name), {
|
||||
#ifdef QTS_ASYNCIFY
|
||||
const asyncify = {['handleSleep'] : Asyncify.handleSleep};
|
||||
#else
|
||||
const asyncify = undefined;
|
||||
#endif
|
||||
// https://emscripten.org/docs/api_reference/preamble.js.html#UTF8ToString
|
||||
const moduleNameString = UTF8ToString(module_name);
|
||||
return Module['callbacks']['loadModuleSource'](asyncify, rt, ctx, moduleNameString);
|
||||
});
|
||||
|
||||
EM_JS(MaybeAsync(char *), qts_host_normalize_module, (JSRuntime * rt, JSContext *ctx, const char *module_base_name, const char *module_name), {
|
||||
#ifdef QTS_ASYNCIFY
|
||||
const asyncify = {['handleSleep'] : Asyncify.handleSleep};
|
||||
#else
|
||||
const asyncify = undefined;
|
||||
#endif
|
||||
// https://emscripten.org/docs/api_reference/preamble.js.html#UTF8ToString
|
||||
const moduleBaseNameString = UTF8ToString(module_base_name);
|
||||
const moduleNameString = UTF8ToString(module_name);
|
||||
return Module['callbacks']['normalizeModule'](asyncify, rt, ctx, moduleBaseNameString, moduleNameString);
|
||||
});
|
||||
#endif
|
||||
|
||||
// load module: QuickJS -> C
|
||||
// See js_module_loader in quickjs/quickjs-libc.c:567
|
||||
JSModuleDef *qts_load_module(JSContext *ctx, const char *module_name, void *_unused) {
|
||||
JSRuntime *rt = JS_GetRuntime(ctx);
|
||||
#ifdef QTS_DEBUG_MODE
|
||||
char msg[500];
|
||||
sprintf(msg, "qts_load_module(rt: %p, ctx: %p, name: %s)", rt, ctx, module_name);
|
||||
QTS_DEBUG(msg)
|
||||
#endif
|
||||
char *module_source = qts_host_load_module_source(rt, ctx, module_name);
|
||||
if (module_source == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JSModuleDef *module = qts_compile_module(ctx, module_name, module_source);
|
||||
free(module_source);
|
||||
return module;
|
||||
}
|
||||
|
||||
char *qts_normalize_module(JSContext *ctx, const char *module_base_name, const char *module_name, void *_unused) {
|
||||
JSRuntime *rt = JS_GetRuntime(ctx);
|
||||
#ifdef QTS_DEBUG_MODE
|
||||
char msg[500];
|
||||
sprintf(msg, "qts_normalize_module(rt: %p, ctx: %p, base_name: %s, name: %s)", rt, ctx, module_base_name, module_name);
|
||||
QTS_DEBUG(msg)
|
||||
#endif
|
||||
char *em_module_name = qts_host_normalize_module(rt, ctx, module_base_name, module_name);
|
||||
char *js_module_name = js_strdup(ctx, em_module_name);
|
||||
free(em_module_name);
|
||||
return js_module_name;
|
||||
}
|
||||
|
||||
// Load module: Host -> QuickJS
|
||||
void QTS_RuntimeEnableModuleLoader(JSRuntime *rt, int use_custom_normalize) {
|
||||
JSModuleNormalizeFunc *module_normalize = NULL; /* use default name normalizer */
|
||||
if (use_custom_normalize) {
|
||||
module_normalize = &qts_normalize_module;
|
||||
}
|
||||
JS_SetModuleLoaderFunc(rt, module_normalize, &qts_load_module, NULL);
|
||||
}
|
||||
|
||||
void QTS_RuntimeDisableModuleLoader(JSRuntime *rt) {
|
||||
JS_SetModuleLoaderFunc(rt, NULL, NULL, NULL);
|
||||
}
|
||||
24
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/asyncify-helpers.d.ts
generated
vendored
Normal file
24
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/asyncify-helpers.d.ts
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
declare function awaitYield<T>(value: T | Promise<T>): Generator<T | Promise<T>, T, T>;
|
||||
declare function awaitYieldOf<T, Yielded>(generator: Generator<Yielded | Promise<Yielded>, T, Yielded>): Generator<T | Promise<T>, T, T>;
|
||||
export type AwaitYield = typeof awaitYield & {
|
||||
of: typeof awaitYieldOf;
|
||||
};
|
||||
/**
|
||||
* Create a function that may or may not be async, using a generator
|
||||
*
|
||||
* Within the generator, call `yield* awaited(maybePromise)` to await a value
|
||||
* that may or may not be a promise.
|
||||
*
|
||||
* If the inner function never yields a promise, it will return synchronously.
|
||||
*/
|
||||
export declare function maybeAsyncFn<
|
||||
/** Function arguments */
|
||||
Args extends any[], This,
|
||||
/** Function return type */
|
||||
Return,
|
||||
/** Yields to unwrap */
|
||||
Yielded>(that: This, fn: (this: This, awaited: AwaitYield, ...args: Args) => Generator<Yielded | Promise<Yielded>, Return, Yielded>): (...args: Args) => Return | Promise<Return>;
|
||||
export type MaybeAsyncBlock<Return, This, Yielded, Args extends any[] = []> = (this: This, awaited: AwaitYield, ...args: Args) => Generator<Yielded | Promise<Yielded>, Return, Yielded>;
|
||||
export declare function maybeAsync<Return, This, Yielded>(that: This, startGenerator: (this: This, await: AwaitYield) => Generator<Yielded | Promise<Yielded>, Return, Yielded>): Return | Promise<Return>;
|
||||
export declare function awaitEachYieldedPromise<Yielded, Returned>(gen: Generator<Yielded | Promise<Yielded>, Returned, Yielded>): Returned | Promise<Returned>;
|
||||
export {};
|
||||
53
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/asyncify-helpers.js
generated
vendored
Normal file
53
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/asyncify-helpers.js
generated
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.awaitEachYieldedPromise = exports.maybeAsync = exports.maybeAsyncFn = void 0;
|
||||
function* awaitYield(value) {
|
||||
return (yield value);
|
||||
}
|
||||
function awaitYieldOf(generator) {
|
||||
return awaitYield(awaitEachYieldedPromise(generator));
|
||||
}
|
||||
const AwaitYield = awaitYield;
|
||||
AwaitYield.of = awaitYieldOf;
|
||||
/**
|
||||
* Create a function that may or may not be async, using a generator
|
||||
*
|
||||
* Within the generator, call `yield* awaited(maybePromise)` to await a value
|
||||
* that may or may not be a promise.
|
||||
*
|
||||
* If the inner function never yields a promise, it will return synchronously.
|
||||
*/
|
||||
function maybeAsyncFn(that, fn) {
|
||||
return (...args) => {
|
||||
const generator = fn.call(that, AwaitYield, ...args);
|
||||
return awaitEachYieldedPromise(generator);
|
||||
};
|
||||
}
|
||||
exports.maybeAsyncFn = maybeAsyncFn;
|
||||
class Example {
|
||||
constructor() {
|
||||
this.maybeAsyncMethod = maybeAsyncFn(this, function* (awaited, a) {
|
||||
yield* awaited(new Promise((resolve) => setTimeout(resolve, a)));
|
||||
return 5;
|
||||
});
|
||||
}
|
||||
}
|
||||
function maybeAsync(that, startGenerator) {
|
||||
const generator = startGenerator.call(that, AwaitYield);
|
||||
return awaitEachYieldedPromise(generator);
|
||||
}
|
||||
exports.maybeAsync = maybeAsync;
|
||||
function awaitEachYieldedPromise(gen) {
|
||||
function handleNextStep(step) {
|
||||
if (step.done) {
|
||||
return step.value;
|
||||
}
|
||||
if (step.value instanceof Promise) {
|
||||
return step.value.then((value) => handleNextStep(gen.next(value)), (error) => handleNextStep(gen.throw(error)));
|
||||
}
|
||||
return handleNextStep(gen.next(step.value));
|
||||
}
|
||||
return handleNextStep(gen.next());
|
||||
}
|
||||
exports.awaitEachYieldedPromise = awaitEachYieldedPromise;
|
||||
//# sourceMappingURL=asyncify-helpers.js.map
|
||||
1
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/asyncify-helpers.js.map
generated
vendored
Normal file
1
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/asyncify-helpers.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"asyncify-helpers.js","sourceRoot":"","sources":["../ts/asyncify-helpers.ts"],"names":[],"mappings":";;;AAAA,QAAQ,CAAC,CAAC,UAAU,CAAI,KAAqB;IAC3C,OAAO,CAAC,MAAM,KAAK,CAAM,CAAA;AAC3B,CAAC;AAED,SAAS,YAAY,CACnB,SAA4D;IAE5D,OAAO,UAAU,CAAC,uBAAuB,CAAC,SAAS,CAAC,CAAC,CAAA;AACvD,CAAC;AAMD,MAAM,UAAU,GAAe,UAAwB,CAAA;AACvD,UAAU,CAAC,EAAE,GAAG,YAAY,CAAA;AAE5B;;;;;;;GAOG;AACH,SAAgB,YAAY,CAS1B,IAAU,EACV,EAI2D;IAE3D,OAAO,CAAC,GAAG,IAAU,EAAE,EAAE;QACvB,MAAM,SAAS,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,CAAA;QACpD,OAAO,uBAAuB,CAAC,SAAS,CAAC,CAAA;IAC3C,CAAC,CAAA;AACH,CAAC;AApBD,oCAoBC;AAED,MAAM,OAAO;IAAb;QACU,qBAAgB,GAAG,YAAY,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAS;YACzE,KAAK,CAAC,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;YAChE,OAAO,CAAC,CAAA;QACV,CAAC,CAAC,CAAA;IACJ,CAAC;CAAA;AAQD,SAAgB,UAAU,CACxB,IAAU,EACV,cAG2D;IAE3D,MAAM,SAAS,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAA;IACvD,OAAO,uBAAuB,CAAC,SAAS,CAAC,CAAA;AAC3C,CAAC;AATD,gCASC;AAED,SAAgB,uBAAuB,CACrC,GAA6D;IAI7D,SAAS,cAAc,CAAC,IAAgB;QACtC,IAAI,IAAI,CAAC,IAAI,EAAE;YACb,OAAO,IAAI,CAAC,KAAK,CAAA;SAClB;QAED,IAAI,IAAI,CAAC,KAAK,YAAY,OAAO,EAAE;YACjC,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CACpB,CAAC,KAAK,EAAE,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAC1C,CAAC,KAAK,EAAE,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAC5C,CAAA;SACF;QAED,OAAO,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;IAC7C,CAAC;IAED,OAAO,cAAc,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAA;AACnC,CAAC;AArBD,0DAqBC","sourcesContent":["function* awaitYield<T>(value: T | Promise<T>) {\n return (yield value) as T\n}\n\nfunction awaitYieldOf<T, Yielded>(\n generator: Generator<Yielded | Promise<Yielded>, T, Yielded>\n): Generator<T | Promise<T>, T, T> {\n return awaitYield(awaitEachYieldedPromise(generator))\n}\n\nexport type AwaitYield = typeof awaitYield & {\n of: typeof awaitYieldOf\n}\n\nconst AwaitYield: AwaitYield = awaitYield as AwaitYield\nAwaitYield.of = awaitYieldOf\n\n/**\n * Create a function that may or may not be async, using a generator\n *\n * Within the generator, call `yield* awaited(maybePromise)` to await a value\n * that may or may not be a promise.\n *\n * If the inner function never yields a promise, it will return synchronously.\n */\nexport function maybeAsyncFn<\n /** Function arguments */\n Args extends any[],\n This,\n /** Function return type */\n Return,\n /** Yields to unwrap */\n Yielded\n>(\n that: This,\n fn: (\n this: This,\n awaited: AwaitYield,\n ...args: Args\n ) => Generator<Yielded | Promise<Yielded>, Return, Yielded>\n): (...args: Args) => Return | Promise<Return> {\n return (...args: Args) => {\n const generator = fn.call(that, AwaitYield, ...args)\n return awaitEachYieldedPromise(generator)\n }\n}\n\nclass Example {\n private maybeAsyncMethod = maybeAsyncFn(this, function* (awaited, a: number) {\n yield* awaited(new Promise((resolve) => setTimeout(resolve, a)))\n return 5\n })\n}\n\nexport type MaybeAsyncBlock<Return, This, Yielded, Args extends any[] = []> = (\n this: This,\n awaited: AwaitYield,\n ...args: Args\n) => Generator<Yielded | Promise<Yielded>, Return, Yielded>\n\nexport function maybeAsync<Return, This, Yielded>(\n that: This,\n startGenerator: (\n this: This,\n await: AwaitYield\n ) => Generator<Yielded | Promise<Yielded>, Return, Yielded>\n): Return | Promise<Return> {\n const generator = startGenerator.call(that, AwaitYield)\n return awaitEachYieldedPromise(generator)\n}\n\nexport function awaitEachYieldedPromise<Yielded, Returned>(\n gen: Generator<Yielded | Promise<Yielded>, Returned, Yielded>\n): Returned | Promise<Returned> {\n type NextResult = ReturnType<typeof gen.next>\n\n function handleNextStep(step: NextResult): Returned | Promise<Returned> {\n if (step.done) {\n return step.value\n }\n\n if (step.value instanceof Promise) {\n return step.value.then(\n (value) => handleNextStep(gen.next(value)),\n (error) => handleNextStep(gen.throw(error))\n )\n }\n\n return handleNextStep(gen.next(step.value))\n }\n\n return handleNextStep(gen.next())\n}\n"]}
|
||||
48
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/context-asyncify.d.ts
generated
vendored
Normal file
48
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/context-asyncify.d.ts
generated
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
import { QuickJSContext } from "./context";
|
||||
import { QuickJSAsyncEmscriptenModule } from "./emscripten-types";
|
||||
import { QuickJSAsyncFFI } from "./variants";
|
||||
import { JSRuntimePointer } from "./types-ffi";
|
||||
import { Lifetime } from "./lifetime";
|
||||
import { QuickJSModuleCallbacks } from "./module";
|
||||
import { QuickJSAsyncRuntime } from "./runtime-asyncify";
|
||||
import { ContextEvalOptions, QuickJSHandle } from "./types";
|
||||
import { VmCallResult } from "./vm-interface";
|
||||
export type AsyncFunctionImplementation = (this: QuickJSHandle, ...args: QuickJSHandle[]) => Promise<QuickJSHandle | VmCallResult<QuickJSHandle> | void>;
|
||||
/**
|
||||
* Asyncified version of [[QuickJSContext]].
|
||||
*
|
||||
* *Asyncify* allows normally synchronous code to wait for asynchronous Promises
|
||||
* or callbacks. The asyncified version of QuickJSContext can wait for async
|
||||
* host functions as though they were synchronous.
|
||||
*/
|
||||
export declare class QuickJSAsyncContext extends QuickJSContext {
|
||||
runtime: QuickJSAsyncRuntime;
|
||||
/** @private */
|
||||
protected module: QuickJSAsyncEmscriptenModule;
|
||||
/** @private */
|
||||
protected ffi: QuickJSAsyncFFI;
|
||||
/** @private */
|
||||
protected rt: Lifetime<JSRuntimePointer>;
|
||||
/** @private */
|
||||
protected callbacks: QuickJSModuleCallbacks;
|
||||
/**
|
||||
* Asyncified version of [[evalCode]].
|
||||
*/
|
||||
evalCodeAsync(code: string, filename?: string,
|
||||
/** See [[EvalFlags]] for number semantics */
|
||||
options?: number | ContextEvalOptions): Promise<VmCallResult<QuickJSHandle>>;
|
||||
/**
|
||||
* Similar to [[newFunction]].
|
||||
* Convert an async host Javascript function into a synchronous QuickJS function value.
|
||||
*
|
||||
* Whenever QuickJS calls this function, the VM's stack will be unwound while
|
||||
* waiting the async function to complete, and then restored when the returned
|
||||
* promise resolves.
|
||||
*
|
||||
* Asyncified functions must never call other asyncified functions or
|
||||
* `import`, even indirectly, because the stack cannot be unwound twice.
|
||||
*
|
||||
* See [Emscripten's docs on Asyncify](https://emscripten.org/docs/porting/asyncify.html).
|
||||
*/
|
||||
newAsyncifiedFunction(name: string, fn: AsyncFunctionImplementation): QuickJSHandle;
|
||||
}
|
||||
58
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/context-asyncify.js
generated
vendored
Normal file
58
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/context-asyncify.js
generated
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.QuickJSAsyncContext = void 0;
|
||||
const context_1 = require("./context");
|
||||
const debug_1 = require("./debug");
|
||||
const types_1 = require("./types");
|
||||
/**
|
||||
* Asyncified version of [[QuickJSContext]].
|
||||
*
|
||||
* *Asyncify* allows normally synchronous code to wait for asynchronous Promises
|
||||
* or callbacks. The asyncified version of QuickJSContext can wait for async
|
||||
* host functions as though they were synchronous.
|
||||
*/
|
||||
class QuickJSAsyncContext extends context_1.QuickJSContext {
|
||||
/**
|
||||
* Asyncified version of [[evalCode]].
|
||||
*/
|
||||
async evalCodeAsync(code, filename = "eval.js",
|
||||
/** See [[EvalFlags]] for number semantics */
|
||||
options) {
|
||||
const detectModule = (options === undefined ? 1 : 0);
|
||||
const flags = (0, types_1.evalOptionsToFlags)(options);
|
||||
let resultPtr = 0;
|
||||
try {
|
||||
resultPtr = await this.memory
|
||||
.newHeapCharPointer(code)
|
||||
.consume((charHandle) => this.ffi.QTS_Eval_MaybeAsync(this.ctx.value, charHandle.value, filename, detectModule, flags));
|
||||
}
|
||||
catch (error) {
|
||||
(0, debug_1.debugLog)("QTS_Eval_MaybeAsync threw", error);
|
||||
throw error;
|
||||
}
|
||||
const errorPtr = this.ffi.QTS_ResolveException(this.ctx.value, resultPtr);
|
||||
if (errorPtr) {
|
||||
this.ffi.QTS_FreeValuePointer(this.ctx.value, resultPtr);
|
||||
return { error: this.memory.heapValueHandle(errorPtr) };
|
||||
}
|
||||
return { value: this.memory.heapValueHandle(resultPtr) };
|
||||
}
|
||||
/**
|
||||
* Similar to [[newFunction]].
|
||||
* Convert an async host Javascript function into a synchronous QuickJS function value.
|
||||
*
|
||||
* Whenever QuickJS calls this function, the VM's stack will be unwound while
|
||||
* waiting the async function to complete, and then restored when the returned
|
||||
* promise resolves.
|
||||
*
|
||||
* Asyncified functions must never call other asyncified functions or
|
||||
* `import`, even indirectly, because the stack cannot be unwound twice.
|
||||
*
|
||||
* See [Emscripten's docs on Asyncify](https://emscripten.org/docs/porting/asyncify.html).
|
||||
*/
|
||||
newAsyncifiedFunction(name, fn) {
|
||||
return this.newFunction(name, fn);
|
||||
}
|
||||
}
|
||||
exports.QuickJSAsyncContext = QuickJSAsyncContext;
|
||||
//# sourceMappingURL=context-asyncify.js.map
|
||||
1
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/context-asyncify.js.map
generated
vendored
Normal file
1
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/context-asyncify.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"context-asyncify.js","sourceRoot":"","sources":["../ts/context-asyncify.ts"],"names":[],"mappings":";;;AAAA,uCAA0C;AAC1C,mCAAkC;AAOlC,mCAA+E;AAQ/E;;;;;;GAMG;AACH,MAAa,mBAAoB,SAAQ,wBAAc;IAWrD;;OAEG;IACH,KAAK,CAAC,aAAa,CACjB,IAAY,EACZ,WAAmB,SAAS;IAC5B,6CAA6C;IAC7C,OAAqC;QAErC,MAAM,YAAY,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAqB,CAAA;QACxE,MAAM,KAAK,GAAG,IAAA,0BAAkB,EAAC,OAAO,CAAc,CAAA;QACtD,IAAI,SAAS,GAAG,CAAmB,CAAA;QACnC,IAAI;YACF,SAAS,GAAG,MAAM,IAAI,CAAC,MAAM;iBAC1B,kBAAkB,CAAC,IAAI,CAAC;iBACxB,OAAO,CAAC,CAAC,UAAU,EAAE,EAAE,CACtB,IAAI,CAAC,GAAG,CAAC,mBAAmB,CAC1B,IAAI,CAAC,GAAG,CAAC,KAAK,EACd,UAAU,CAAC,KAAK,EAChB,QAAQ,EACR,YAAY,EACZ,KAAK,CACN,CACF,CAAA;SACJ;QAAC,OAAO,KAAK,EAAE;YACd,IAAA,gBAAQ,EAAC,2BAA2B,EAAE,KAAK,CAAC,CAAA;YAC5C,MAAM,KAAK,CAAA;SACZ;QACD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,oBAAoB,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,CAAC,CAAA;QACzE,IAAI,QAAQ,EAAE;YACZ,IAAI,CAAC,GAAG,CAAC,oBAAoB,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,CAAC,CAAA;YACxD,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE,CAAA;SACxD;QACD,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,SAAS,CAAC,EAAE,CAAA;IAC1D,CAAC;IAED;;;;;;;;;;;;OAYG;IACH,qBAAqB,CAAC,IAAY,EAAE,EAA+B;QACjE,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,EAAS,CAAC,CAAA;IAC1C,CAAC;CACF;AA/DD,kDA+DC","sourcesContent":["import { QuickJSContext } from \"./context\"\nimport { debugLog } from \"./debug\"\nimport { QuickJSAsyncEmscriptenModule } from \"./emscripten-types\"\nimport { QuickJSAsyncFFI } from \"./variants\"\nimport { EvalDetectModule, EvalFlags, JSRuntimePointer, JSValuePointer } from \"./types-ffi\"\nimport { Lifetime } from \"./lifetime\"\nimport { QuickJSModuleCallbacks } from \"./module\"\nimport { QuickJSAsyncRuntime } from \"./runtime-asyncify\"\nimport { ContextEvalOptions, evalOptionsToFlags, QuickJSHandle } from \"./types\"\nimport { VmCallResult } from \"./vm-interface\"\n\nexport type AsyncFunctionImplementation = (\n this: QuickJSHandle,\n ...args: QuickJSHandle[]\n) => Promise<QuickJSHandle | VmCallResult<QuickJSHandle> | void>\n\n/**\n * Asyncified version of [[QuickJSContext]].\n *\n * *Asyncify* allows normally synchronous code to wait for asynchronous Promises\n * or callbacks. The asyncified version of QuickJSContext can wait for async\n * host functions as though they were synchronous.\n */\nexport class QuickJSAsyncContext extends QuickJSContext {\n public declare runtime: QuickJSAsyncRuntime\n /** @private */\n protected declare module: QuickJSAsyncEmscriptenModule\n /** @private */\n protected declare ffi: QuickJSAsyncFFI\n /** @private */\n protected declare rt: Lifetime<JSRuntimePointer>\n /** @private */\n protected declare callbacks: QuickJSModuleCallbacks\n\n /**\n * Asyncified version of [[evalCode]].\n */\n async evalCodeAsync(\n code: string,\n filename: string = \"eval.js\",\n /** See [[EvalFlags]] for number semantics */\n options?: number | ContextEvalOptions\n ): Promise<VmCallResult<QuickJSHandle>> {\n const detectModule = (options === undefined ? 1 : 0) as EvalDetectModule\n const flags = evalOptionsToFlags(options) as EvalFlags\n let resultPtr = 0 as JSValuePointer\n try {\n resultPtr = await this.memory\n .newHeapCharPointer(code)\n .consume((charHandle) =>\n this.ffi.QTS_Eval_MaybeAsync(\n this.ctx.value,\n charHandle.value,\n filename,\n detectModule,\n flags\n )\n )\n } catch (error) {\n debugLog(\"QTS_Eval_MaybeAsync threw\", error)\n throw error\n }\n const errorPtr = this.ffi.QTS_ResolveException(this.ctx.value, resultPtr)\n if (errorPtr) {\n this.ffi.QTS_FreeValuePointer(this.ctx.value, resultPtr)\n return { error: this.memory.heapValueHandle(errorPtr) }\n }\n return { value: this.memory.heapValueHandle(resultPtr) }\n }\n\n /**\n * Similar to [[newFunction]].\n * Convert an async host Javascript function into a synchronous QuickJS function value.\n *\n * Whenever QuickJS calls this function, the VM's stack will be unwound while\n * waiting the async function to complete, and then restored when the returned\n * promise resolves.\n *\n * Asyncified functions must never call other asyncified functions or\n * `import`, even indirectly, because the stack cannot be unwound twice.\n *\n * See [Emscripten's docs on Asyncify](https://emscripten.org/docs/porting/asyncify.html).\n */\n newAsyncifiedFunction(name: string, fn: AsyncFunctionImplementation): QuickJSHandle {\n return this.newFunction(name, fn as any)\n }\n}\n"]}
|
||||
371
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/context.d.ts
generated
vendored
Normal file
371
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/context.d.ts
generated
vendored
Normal file
@@ -0,0 +1,371 @@
|
||||
import { QuickJSDeferredPromise } from "./deferred-promise";
|
||||
import type { EitherModule } from "./emscripten-types";
|
||||
import { JSBorrowedCharPointer, JSContextPointer, JSRuntimePointer, JSValueConstPointer, JSValuePointer } from "./types-ffi";
|
||||
import { Disposable, Lifetime, Scope } from "./lifetime";
|
||||
import { ModuleMemory } from "./memory";
|
||||
import { QuickJSModuleCallbacks } from "./module";
|
||||
import { QuickJSRuntime } from "./runtime";
|
||||
import { ContextEvalOptions, EitherFFI, JSValue, PromiseExecutor, QuickJSHandle } from "./types";
|
||||
import { LowLevelJavascriptVm, SuccessOrFail, VmCallResult, VmFunctionImplementation, VmPropertyDescriptor } from "./vm-interface";
|
||||
/**
|
||||
* Property key for getting or setting a property on a handle with
|
||||
* [[QuickJSContext.getProp]], [[QuickJSContext.setProp]], or [[QuickJSContext.defineProp]].
|
||||
*/
|
||||
export type QuickJSPropertyKey = number | string | QuickJSHandle;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
declare class ContextMemory extends ModuleMemory implements Disposable {
|
||||
readonly owner: QuickJSRuntime;
|
||||
readonly ctx: Lifetime<JSContextPointer>;
|
||||
readonly rt: Lifetime<JSRuntimePointer>;
|
||||
readonly module: EitherModule;
|
||||
readonly ffi: EitherFFI;
|
||||
readonly scope: Scope;
|
||||
/** @private */
|
||||
constructor(args: {
|
||||
owner: QuickJSRuntime;
|
||||
module: EitherModule;
|
||||
ffi: EitherFFI;
|
||||
ctx: Lifetime<JSContextPointer>;
|
||||
rt: Lifetime<JSRuntimePointer>;
|
||||
ownedLifetimes?: Disposable[];
|
||||
});
|
||||
get alive(): boolean;
|
||||
dispose(): void;
|
||||
/**
|
||||
* Track `lifetime` so that it is disposed when this scope is disposed.
|
||||
*/
|
||||
manage<T extends Disposable>(lifetime: T): T;
|
||||
copyJSValue: (ptr: JSValuePointer | JSValueConstPointer) => any;
|
||||
freeJSValue: (ptr: JSValuePointer) => void;
|
||||
consumeJSCharPointer(ptr: JSBorrowedCharPointer): string;
|
||||
heapValueHandle(ptr: JSValuePointer): JSValue;
|
||||
}
|
||||
/**
|
||||
* QuickJSContext wraps a QuickJS Javascript context (JSContext*) within a
|
||||
* runtime. The contexts within the same runtime may exchange objects freely.
|
||||
* You can think of separate runtimes like different domains in a browser, and
|
||||
* the contexts within a runtime like the different windows open to the same
|
||||
* domain. The {@link runtime} references the context's runtime.
|
||||
*
|
||||
* This class's methods return {@link QuickJSHandle}, which wrap C pointers (JSValue*).
|
||||
* It's the caller's responsibility to call `.dispose()` on any
|
||||
* handles you create to free memory once you're done with the handle.
|
||||
*
|
||||
* Use {@link QuickJSRuntime.newContext} or {@link QuickJSWASMModule.newContext}
|
||||
* to create a new QuickJSContext.
|
||||
*
|
||||
* Create QuickJS values inside the interpreter with methods like
|
||||
* [[newNumber]], [[newString]], [[newArray]], [[newObject]],
|
||||
* [[newFunction]], and [[newPromise]].
|
||||
*
|
||||
* Call [[setProp]] or [[defineProp]] to customize objects. Use those methods
|
||||
* with [[global]] to expose the values you create to the interior of the
|
||||
* interpreter, so they can be used in [[evalCode]].
|
||||
*
|
||||
* Use [[evalCode]] or [[callFunction]] to execute Javascript inside the VM. If
|
||||
* you're using asynchronous code inside the QuickJSContext, you may need to also
|
||||
* call [[executePendingJobs]]. Executing code inside the runtime returns a
|
||||
* result object representing successful execution or an error. You must dispose
|
||||
* of any such results to avoid leaking memory inside the VM.
|
||||
*
|
||||
* Implement memory and CPU constraints at the runtime level, using [[runtime]].
|
||||
* See {@link QuickJSRuntime} for more information.
|
||||
*
|
||||
*/
|
||||
export declare class QuickJSContext implements LowLevelJavascriptVm<QuickJSHandle>, Disposable {
|
||||
/**
|
||||
* The runtime that created this context.
|
||||
*/
|
||||
readonly runtime: QuickJSRuntime;
|
||||
/** @private */
|
||||
protected readonly ctx: Lifetime<JSContextPointer>;
|
||||
/** @private */
|
||||
protected readonly rt: Lifetime<JSRuntimePointer>;
|
||||
/** @private */
|
||||
protected readonly module: EitherModule;
|
||||
/** @private */
|
||||
protected readonly ffi: EitherFFI;
|
||||
/** @private */
|
||||
protected memory: ContextMemory;
|
||||
/** @private */
|
||||
protected _undefined: QuickJSHandle | undefined;
|
||||
/** @private */
|
||||
protected _null: QuickJSHandle | undefined;
|
||||
/** @private */
|
||||
protected _false: QuickJSHandle | undefined;
|
||||
/** @private */
|
||||
protected _true: QuickJSHandle | undefined;
|
||||
/** @private */
|
||||
protected _global: QuickJSHandle | undefined;
|
||||
/** @private */
|
||||
protected _BigInt: QuickJSHandle | undefined;
|
||||
/**
|
||||
* Use {@link QuickJS.createVm} to create a QuickJSContext instance.
|
||||
*/
|
||||
constructor(args: {
|
||||
module: EitherModule;
|
||||
ffi: EitherFFI;
|
||||
ctx: Lifetime<JSContextPointer>;
|
||||
rt: Lifetime<JSRuntimePointer>;
|
||||
runtime: QuickJSRuntime;
|
||||
ownedLifetimes?: Disposable[];
|
||||
callbacks: QuickJSModuleCallbacks;
|
||||
});
|
||||
get alive(): boolean;
|
||||
/**
|
||||
* Dispose of this VM's underlying resources.
|
||||
*
|
||||
* @throws Calling this method without disposing of all created handles
|
||||
* will result in an error.
|
||||
*/
|
||||
dispose(): void;
|
||||
/**
|
||||
* [`undefined`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined).
|
||||
*/
|
||||
get undefined(): QuickJSHandle;
|
||||
/**
|
||||
* [`null`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null).
|
||||
*/
|
||||
get null(): QuickJSHandle;
|
||||
/**
|
||||
* [`true`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/true).
|
||||
*/
|
||||
get true(): QuickJSHandle;
|
||||
/**
|
||||
* [`false`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/false).
|
||||
*/
|
||||
get false(): QuickJSHandle;
|
||||
/**
|
||||
* [`global`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects).
|
||||
* A handle to the global object inside the interpreter.
|
||||
* You can set properties to create global variables.
|
||||
*/
|
||||
get global(): QuickJSHandle;
|
||||
/**
|
||||
* Converts a Javascript number into a QuickJS value.
|
||||
*/
|
||||
newNumber(num: number): QuickJSHandle;
|
||||
/**
|
||||
* Create a QuickJS [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) value.
|
||||
*/
|
||||
newString(str: string): QuickJSHandle;
|
||||
/**
|
||||
* Create a QuickJS [symbol](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol) value.
|
||||
* No two symbols created with this function will be the same value.
|
||||
*/
|
||||
newUniqueSymbol(description: string | symbol): QuickJSHandle;
|
||||
/**
|
||||
* Get a symbol from the [global registry](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol#shared_symbols_in_the_global_symbol_registry) for the given key.
|
||||
* All symbols created with the same key will be the same value.
|
||||
*/
|
||||
newSymbolFor(key: string | symbol): QuickJSHandle;
|
||||
/**
|
||||
* Create a QuickJS [bigint](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt) value.
|
||||
*/
|
||||
newBigInt(num: bigint): QuickJSHandle;
|
||||
/**
|
||||
* `{}`.
|
||||
* Create a new QuickJS [object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer).
|
||||
*
|
||||
* @param prototype - Like [`Object.create`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create).
|
||||
*/
|
||||
newObject(prototype?: QuickJSHandle): QuickJSHandle;
|
||||
/**
|
||||
* `[]`.
|
||||
* Create a new QuickJS [array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array).
|
||||
*/
|
||||
newArray(): QuickJSHandle;
|
||||
/**
|
||||
* Create a new [[QuickJSDeferredPromise]]. Use `deferred.resolve(handle)` and
|
||||
* `deferred.reject(handle)` to fulfill the promise handle available at `deferred.handle`.
|
||||
* Note that you are responsible for calling `deferred.dispose()` to free the underlying
|
||||
* resources; see the documentation on [[QuickJSDeferredPromise]] for details.
|
||||
*/
|
||||
newPromise(): QuickJSDeferredPromise;
|
||||
/**
|
||||
* Create a new [[QuickJSDeferredPromise]] that resolves when the
|
||||
* given native Promise<QuickJSHandle> resolves. Rejections will be coerced
|
||||
* to a QuickJS error.
|
||||
*
|
||||
* You can still resolve/reject the created promise "early" using its methods.
|
||||
*/
|
||||
newPromise(promise: Promise<QuickJSHandle>): QuickJSDeferredPromise;
|
||||
/**
|
||||
* Construct a new native Promise<QuickJSHandle>, and then convert it into a
|
||||
* [[QuickJSDeferredPromise]].
|
||||
*
|
||||
* You can still resolve/reject the created promise "early" using its methods.
|
||||
*/
|
||||
newPromise(newPromiseFn: PromiseExecutor<QuickJSHandle, Error | QuickJSHandle>): QuickJSDeferredPromise;
|
||||
/**
|
||||
* Convert a Javascript function into a QuickJS function value.
|
||||
* See [[VmFunctionImplementation]] for more details.
|
||||
*
|
||||
* A [[VmFunctionImplementation]] should not free its arguments or its return
|
||||
* value. A VmFunctionImplementation should also not retain any references to
|
||||
* its return value.
|
||||
*
|
||||
* To implement an async function, create a promise with [[newPromise]], then
|
||||
* return the deferred promise handle from `deferred.handle` from your
|
||||
* function implementation:
|
||||
*
|
||||
* ```
|
||||
* const deferred = vm.newPromise()
|
||||
* someNativeAsyncFunction().then(deferred.resolve)
|
||||
* return deferred.handle
|
||||
* ```
|
||||
*/
|
||||
newFunction(name: string, fn: VmFunctionImplementation<QuickJSHandle>): QuickJSHandle;
|
||||
newError(error: {
|
||||
name: string;
|
||||
message: string;
|
||||
}): QuickJSHandle;
|
||||
newError(message: string): QuickJSHandle;
|
||||
newError(): QuickJSHandle;
|
||||
/**
|
||||
* `typeof` operator. **Not** [standards compliant](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof).
|
||||
*
|
||||
* @remarks
|
||||
* Does not support BigInt values correctly.
|
||||
*/
|
||||
typeof(handle: QuickJSHandle): string;
|
||||
/**
|
||||
* Converts `handle` into a Javascript number.
|
||||
* @returns `NaN` on error, otherwise a `number`.
|
||||
*/
|
||||
getNumber(handle: QuickJSHandle): number;
|
||||
/**
|
||||
* Converts `handle` to a Javascript string.
|
||||
*/
|
||||
getString(handle: QuickJSHandle): string;
|
||||
/**
|
||||
* Converts `handle` into a Javascript symbol. If the symbol is in the global
|
||||
* registry in the guest, it will be created with Symbol.for on the host.
|
||||
*/
|
||||
getSymbol(handle: QuickJSHandle): symbol;
|
||||
/**
|
||||
* Converts `handle` to a Javascript bigint.
|
||||
*/
|
||||
getBigInt(handle: QuickJSHandle): bigint;
|
||||
/**
|
||||
* `Promise.resolve(value)`.
|
||||
* Convert a handle containing a Promise-like value inside the VM into an
|
||||
* actual promise on the host.
|
||||
*
|
||||
* @remarks
|
||||
* You may need to call [[executePendingJobs]] to ensure that the promise is resolved.
|
||||
*
|
||||
* @param promiseLikeHandle - A handle to a Promise-like value with a `.then(onSuccess, onError)` method.
|
||||
*/
|
||||
resolvePromise(promiseLikeHandle: QuickJSHandle): Promise<VmCallResult<QuickJSHandle>>;
|
||||
/**
|
||||
* `handle[key]`.
|
||||
* Get a property from a JSValue.
|
||||
*
|
||||
* @param key - The property may be specified as a JSValue handle, or as a
|
||||
* Javascript string (which will be converted automatically).
|
||||
*/
|
||||
getProp(handle: QuickJSHandle, key: QuickJSPropertyKey): QuickJSHandle;
|
||||
/**
|
||||
* `handle[key] = value`.
|
||||
* Set a property on a JSValue.
|
||||
*
|
||||
* @remarks
|
||||
* Note that the QuickJS authors recommend using [[defineProp]] to define new
|
||||
* properties.
|
||||
*
|
||||
* @param key - The property may be specified as a JSValue handle, or as a
|
||||
* Javascript string or number (which will be converted automatically to a JSValue).
|
||||
*/
|
||||
setProp(handle: QuickJSHandle, key: QuickJSPropertyKey, value: QuickJSHandle): void;
|
||||
/**
|
||||
* [`Object.defineProperty(handle, key, descriptor)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty).
|
||||
*
|
||||
* @param key - The property may be specified as a JSValue handle, or as a
|
||||
* Javascript string or number (which will be converted automatically to a JSValue).
|
||||
*/
|
||||
defineProp(handle: QuickJSHandle, key: QuickJSPropertyKey, descriptor: VmPropertyDescriptor<QuickJSHandle>): void;
|
||||
/**
|
||||
* [`func.call(thisVal, ...args)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call).
|
||||
* Call a JSValue as a function.
|
||||
*
|
||||
* See [[unwrapResult]], which will throw if the function returned an error, or
|
||||
* return the result handle directly. If evaluation returned a handle containing
|
||||
* a promise, use [[resolvePromise]] to convert it to a native promise and
|
||||
* [[executePendingJobs]] to finish evaluating the promise.
|
||||
*
|
||||
* @returns A result. If the function threw synchronously, `result.error` be a
|
||||
* handle to the exception. Otherwise `result.value` will be a handle to the
|
||||
* value.
|
||||
*/
|
||||
callFunction(func: QuickJSHandle, thisVal: QuickJSHandle, ...args: QuickJSHandle[]): VmCallResult<QuickJSHandle>;
|
||||
/**
|
||||
* Like [`eval(code)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval#Description).
|
||||
* Evaluates the Javascript source `code` in the global scope of this VM.
|
||||
* When working with async code, you many need to call [[executePendingJobs]]
|
||||
* to execute callbacks pending after synchronous evaluation returns.
|
||||
*
|
||||
* See [[unwrapResult]], which will throw if the function returned an error, or
|
||||
* return the result handle directly. If evaluation returned a handle containing
|
||||
* a promise, use [[resolvePromise]] to convert it to a native promise and
|
||||
* [[executePendingJobs]] to finish evaluating the promise.
|
||||
*
|
||||
* *Note*: to protect against infinite loops, provide an interrupt handler to
|
||||
* [[setInterruptHandler]]. You can use [[shouldInterruptAfterDeadline]] to
|
||||
* create a time-based deadline.
|
||||
*
|
||||
* @returns The last statement's value. If the code threw synchronously,
|
||||
* `result.error` will be a handle to the exception. If execution was
|
||||
* interrupted, the error will have name `InternalError` and message
|
||||
* `interrupted`.
|
||||
*/
|
||||
evalCode(code: string, filename?: string,
|
||||
/**
|
||||
* If no options are passed, a heuristic will be used to detect if `code` is
|
||||
* an ES module.
|
||||
*
|
||||
* See [[EvalFlags]] for number semantics.
|
||||
*/
|
||||
options?: number | ContextEvalOptions): VmCallResult<QuickJSHandle>;
|
||||
/**
|
||||
* Throw an error in the VM, interrupted whatever current execution is in progress when execution resumes.
|
||||
* @experimental
|
||||
*/
|
||||
throw(error: Error | QuickJSHandle): any;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
protected borrowPropertyKey(key: QuickJSPropertyKey): QuickJSHandle;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
getMemory(rt: JSRuntimePointer): ContextMemory;
|
||||
/**
|
||||
* Dump a JSValue to Javascript in a best-effort fashion.
|
||||
* Returns `handle.toString()` if it cannot be serialized to JSON.
|
||||
*/
|
||||
dump(handle: QuickJSHandle): any;
|
||||
/**
|
||||
* Unwrap a SuccessOrFail result such as a [[VmCallResult]] or a
|
||||
* [[ExecutePendingJobsResult]], where the fail branch contains a handle to a QuickJS error value.
|
||||
* If the result is a success, returns the value.
|
||||
* If the result is an error, converts the error to a native object and throws the error.
|
||||
*/
|
||||
unwrapResult<T>(result: SuccessOrFail<T, QuickJSHandle>): T;
|
||||
/** @private */
|
||||
protected fnNextId: number;
|
||||
/** @private */
|
||||
protected fnMaps: Map<number, Map<number, VmFunctionImplementation<QuickJSHandle>>>;
|
||||
/** @private */
|
||||
protected getFunction(fn_id: number): VmFunctionImplementation<QuickJSHandle> | undefined;
|
||||
/** @private */
|
||||
protected setFunction(fn_id: number, handle: VmFunctionImplementation<QuickJSHandle>): Map<number, VmFunctionImplementation<QuickJSHandle>>;
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
private cToHostCallbacks;
|
||||
private errorToHandle;
|
||||
}
|
||||
export {};
|
||||
691
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/context.js
generated
vendored
Normal file
691
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/context.js
generated
vendored
Normal file
@@ -0,0 +1,691 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.QuickJSContext = void 0;
|
||||
const debug_1 = require("./debug");
|
||||
const deferred_promise_1 = require("./deferred-promise");
|
||||
const errors_1 = require("./errors");
|
||||
const lifetime_1 = require("./lifetime");
|
||||
const memory_1 = require("./memory");
|
||||
const types_1 = require("./types");
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
class ContextMemory extends memory_1.ModuleMemory {
|
||||
/** @private */
|
||||
constructor(args) {
|
||||
super(args.module);
|
||||
this.scope = new lifetime_1.Scope();
|
||||
this.copyJSValue = (ptr) => {
|
||||
return this.ffi.QTS_DupValuePointer(this.ctx.value, ptr);
|
||||
};
|
||||
this.freeJSValue = (ptr) => {
|
||||
this.ffi.QTS_FreeValuePointer(this.ctx.value, ptr);
|
||||
};
|
||||
args.ownedLifetimes?.forEach((lifetime) => this.scope.manage(lifetime));
|
||||
this.owner = args.owner;
|
||||
this.module = args.module;
|
||||
this.ffi = args.ffi;
|
||||
this.rt = args.rt;
|
||||
this.ctx = this.scope.manage(args.ctx);
|
||||
}
|
||||
get alive() {
|
||||
return this.scope.alive;
|
||||
}
|
||||
dispose() {
|
||||
return this.scope.dispose();
|
||||
}
|
||||
/**
|
||||
* Track `lifetime` so that it is disposed when this scope is disposed.
|
||||
*/
|
||||
manage(lifetime) {
|
||||
return this.scope.manage(lifetime);
|
||||
}
|
||||
consumeJSCharPointer(ptr) {
|
||||
const str = this.module.UTF8ToString(ptr);
|
||||
this.ffi.QTS_FreeCString(this.ctx.value, ptr);
|
||||
return str;
|
||||
}
|
||||
heapValueHandle(ptr) {
|
||||
return new lifetime_1.Lifetime(ptr, this.copyJSValue, this.freeJSValue, this.owner);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* QuickJSContext wraps a QuickJS Javascript context (JSContext*) within a
|
||||
* runtime. The contexts within the same runtime may exchange objects freely.
|
||||
* You can think of separate runtimes like different domains in a browser, and
|
||||
* the contexts within a runtime like the different windows open to the same
|
||||
* domain. The {@link runtime} references the context's runtime.
|
||||
*
|
||||
* This class's methods return {@link QuickJSHandle}, which wrap C pointers (JSValue*).
|
||||
* It's the caller's responsibility to call `.dispose()` on any
|
||||
* handles you create to free memory once you're done with the handle.
|
||||
*
|
||||
* Use {@link QuickJSRuntime.newContext} or {@link QuickJSWASMModule.newContext}
|
||||
* to create a new QuickJSContext.
|
||||
*
|
||||
* Create QuickJS values inside the interpreter with methods like
|
||||
* [[newNumber]], [[newString]], [[newArray]], [[newObject]],
|
||||
* [[newFunction]], and [[newPromise]].
|
||||
*
|
||||
* Call [[setProp]] or [[defineProp]] to customize objects. Use those methods
|
||||
* with [[global]] to expose the values you create to the interior of the
|
||||
* interpreter, so they can be used in [[evalCode]].
|
||||
*
|
||||
* Use [[evalCode]] or [[callFunction]] to execute Javascript inside the VM. If
|
||||
* you're using asynchronous code inside the QuickJSContext, you may need to also
|
||||
* call [[executePendingJobs]]. Executing code inside the runtime returns a
|
||||
* result object representing successful execution or an error. You must dispose
|
||||
* of any such results to avoid leaking memory inside the VM.
|
||||
*
|
||||
* Implement memory and CPU constraints at the runtime level, using [[runtime]].
|
||||
* See {@link QuickJSRuntime} for more information.
|
||||
*
|
||||
*/
|
||||
// TODO: Manage own callback registration
|
||||
class QuickJSContext {
|
||||
/**
|
||||
* Use {@link QuickJS.createVm} to create a QuickJSContext instance.
|
||||
*/
|
||||
constructor(args) {
|
||||
/** @private */
|
||||
this._undefined = undefined;
|
||||
/** @private */
|
||||
this._null = undefined;
|
||||
/** @private */
|
||||
this._false = undefined;
|
||||
/** @private */
|
||||
this._true = undefined;
|
||||
/** @private */
|
||||
this._global = undefined;
|
||||
/** @private */
|
||||
this._BigInt = undefined;
|
||||
/** @private */
|
||||
this.fnNextId = -32768; // min value of signed 16bit int used by Quickjs
|
||||
/** @private */
|
||||
this.fnMaps = new Map();
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
this.cToHostCallbacks = {
|
||||
callFunction: (ctx, this_ptr, argc, argv, fn_id) => {
|
||||
if (ctx !== this.ctx.value) {
|
||||
throw new Error("QuickJSContext instance received C -> JS call with mismatched ctx");
|
||||
}
|
||||
const fn = this.getFunction(fn_id);
|
||||
if (!fn) {
|
||||
// this "throw" is not catch-able from the TS side. could we somehow handle this higher up?
|
||||
throw new Error(`QuickJSContext had no callback with id ${fn_id}`);
|
||||
}
|
||||
return lifetime_1.Scope.withScopeMaybeAsync(this, function* (awaited, scope) {
|
||||
const thisHandle = scope.manage(new lifetime_1.WeakLifetime(this_ptr, this.memory.copyJSValue, this.memory.freeJSValue, this.runtime));
|
||||
const argHandles = new Array(argc);
|
||||
for (let i = 0; i < argc; i++) {
|
||||
const ptr = this.ffi.QTS_ArgvGetJSValueConstPointer(argv, i);
|
||||
argHandles[i] = scope.manage(new lifetime_1.WeakLifetime(ptr, this.memory.copyJSValue, this.memory.freeJSValue, this.runtime));
|
||||
}
|
||||
try {
|
||||
const result = yield* awaited(fn.apply(thisHandle, argHandles));
|
||||
if (result) {
|
||||
if ("error" in result && result.error) {
|
||||
(0, debug_1.debugLog)("throw error", result.error);
|
||||
throw result.error;
|
||||
}
|
||||
const handle = scope.manage(result instanceof lifetime_1.Lifetime ? result : result.value);
|
||||
return this.ffi.QTS_DupValuePointer(this.ctx.value, handle.value);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
catch (error) {
|
||||
return this.errorToHandle(error).consume((errorHandle) => this.ffi.QTS_Throw(this.ctx.value, errorHandle.value));
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
this.runtime = args.runtime;
|
||||
this.module = args.module;
|
||||
this.ffi = args.ffi;
|
||||
this.rt = args.rt;
|
||||
this.ctx = args.ctx;
|
||||
this.memory = new ContextMemory({
|
||||
...args,
|
||||
owner: this.runtime,
|
||||
});
|
||||
args.callbacks.setContextCallbacks(this.ctx.value, this.cToHostCallbacks);
|
||||
this.dump = this.dump.bind(this);
|
||||
this.getString = this.getString.bind(this);
|
||||
this.getNumber = this.getNumber.bind(this);
|
||||
this.resolvePromise = this.resolvePromise.bind(this);
|
||||
}
|
||||
// @implement Disposable ----------------------------------------------------
|
||||
get alive() {
|
||||
return this.memory.alive;
|
||||
}
|
||||
/**
|
||||
* Dispose of this VM's underlying resources.
|
||||
*
|
||||
* @throws Calling this method without disposing of all created handles
|
||||
* will result in an error.
|
||||
*/
|
||||
dispose() {
|
||||
this.memory.dispose();
|
||||
}
|
||||
// Globals ------------------------------------------------------------------
|
||||
/**
|
||||
* [`undefined`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined).
|
||||
*/
|
||||
get undefined() {
|
||||
if (this._undefined) {
|
||||
return this._undefined;
|
||||
}
|
||||
// Undefined is a constant, immutable value in QuickJS.
|
||||
const ptr = this.ffi.QTS_GetUndefined();
|
||||
return (this._undefined = new lifetime_1.StaticLifetime(ptr));
|
||||
}
|
||||
/**
|
||||
* [`null`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null).
|
||||
*/
|
||||
get null() {
|
||||
if (this._null) {
|
||||
return this._null;
|
||||
}
|
||||
// Null is a constant, immutable value in QuickJS.
|
||||
const ptr = this.ffi.QTS_GetNull();
|
||||
return (this._null = new lifetime_1.StaticLifetime(ptr));
|
||||
}
|
||||
/**
|
||||
* [`true`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/true).
|
||||
*/
|
||||
get true() {
|
||||
if (this._true) {
|
||||
return this._true;
|
||||
}
|
||||
// True is a constant, immutable value in QuickJS.
|
||||
const ptr = this.ffi.QTS_GetTrue();
|
||||
return (this._true = new lifetime_1.StaticLifetime(ptr));
|
||||
}
|
||||
/**
|
||||
* [`false`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/false).
|
||||
*/
|
||||
get false() {
|
||||
if (this._false) {
|
||||
return this._false;
|
||||
}
|
||||
// False is a constant, immutable value in QuickJS.
|
||||
const ptr = this.ffi.QTS_GetFalse();
|
||||
return (this._false = new lifetime_1.StaticLifetime(ptr));
|
||||
}
|
||||
/**
|
||||
* [`global`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects).
|
||||
* A handle to the global object inside the interpreter.
|
||||
* You can set properties to create global variables.
|
||||
*/
|
||||
get global() {
|
||||
if (this._global) {
|
||||
return this._global;
|
||||
}
|
||||
// The global is a JSValue, but since it's lifetime is as long as the VM's,
|
||||
// we should manage it.
|
||||
const ptr = this.ffi.QTS_GetGlobalObject(this.ctx.value);
|
||||
// Automatically clean up this reference when we dispose
|
||||
this.memory.manage(this.memory.heapValueHandle(ptr));
|
||||
// This isn't technically a static lifetime, but since it has the same
|
||||
// lifetime as the VM, it's okay to fake one since when the VM is
|
||||
// disposed, no other functions will accept the value.
|
||||
this._global = new lifetime_1.StaticLifetime(ptr, this.runtime);
|
||||
return this._global;
|
||||
}
|
||||
// New values ---------------------------------------------------------------
|
||||
/**
|
||||
* Converts a Javascript number into a QuickJS value.
|
||||
*/
|
||||
newNumber(num) {
|
||||
return this.memory.heapValueHandle(this.ffi.QTS_NewFloat64(this.ctx.value, num));
|
||||
}
|
||||
/**
|
||||
* Create a QuickJS [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) value.
|
||||
*/
|
||||
newString(str) {
|
||||
const ptr = this.memory
|
||||
.newHeapCharPointer(str)
|
||||
.consume((charHandle) => this.ffi.QTS_NewString(this.ctx.value, charHandle.value));
|
||||
return this.memory.heapValueHandle(ptr);
|
||||
}
|
||||
/**
|
||||
* Create a QuickJS [symbol](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol) value.
|
||||
* No two symbols created with this function will be the same value.
|
||||
*/
|
||||
newUniqueSymbol(description) {
|
||||
const key = (typeof description === "symbol" ? description.description : description) ?? "";
|
||||
const ptr = this.memory
|
||||
.newHeapCharPointer(key)
|
||||
.consume((charHandle) => this.ffi.QTS_NewSymbol(this.ctx.value, charHandle.value, 0));
|
||||
return this.memory.heapValueHandle(ptr);
|
||||
}
|
||||
/**
|
||||
* Get a symbol from the [global registry](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol#shared_symbols_in_the_global_symbol_registry) for the given key.
|
||||
* All symbols created with the same key will be the same value.
|
||||
*/
|
||||
newSymbolFor(key) {
|
||||
const description = (typeof key === "symbol" ? key.description : key) ?? "";
|
||||
const ptr = this.memory
|
||||
.newHeapCharPointer(description)
|
||||
.consume((charHandle) => this.ffi.QTS_NewSymbol(this.ctx.value, charHandle.value, 1));
|
||||
return this.memory.heapValueHandle(ptr);
|
||||
}
|
||||
/**
|
||||
* Create a QuickJS [bigint](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt) value.
|
||||
*/
|
||||
newBigInt(num) {
|
||||
if (!this._BigInt) {
|
||||
const bigIntHandle = this.getProp(this.global, "BigInt");
|
||||
this.memory.manage(bigIntHandle);
|
||||
this._BigInt = new lifetime_1.StaticLifetime(bigIntHandle.value, this.runtime);
|
||||
}
|
||||
const bigIntHandle = this._BigInt;
|
||||
const asString = String(num);
|
||||
return this.newString(asString).consume((handle) => this.unwrapResult(this.callFunction(bigIntHandle, this.undefined, handle)));
|
||||
}
|
||||
/**
|
||||
* `{}`.
|
||||
* Create a new QuickJS [object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer).
|
||||
*
|
||||
* @param prototype - Like [`Object.create`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create).
|
||||
*/
|
||||
newObject(prototype) {
|
||||
if (prototype) {
|
||||
this.runtime.assertOwned(prototype);
|
||||
}
|
||||
const ptr = prototype
|
||||
? this.ffi.QTS_NewObjectProto(this.ctx.value, prototype.value)
|
||||
: this.ffi.QTS_NewObject(this.ctx.value);
|
||||
return this.memory.heapValueHandle(ptr);
|
||||
}
|
||||
/**
|
||||
* `[]`.
|
||||
* Create a new QuickJS [array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array).
|
||||
*/
|
||||
newArray() {
|
||||
const ptr = this.ffi.QTS_NewArray(this.ctx.value);
|
||||
return this.memory.heapValueHandle(ptr);
|
||||
}
|
||||
newPromise(value) {
|
||||
const deferredPromise = lifetime_1.Scope.withScope((scope) => {
|
||||
const mutablePointerArray = scope.manage(this.memory.newMutablePointerArray(2));
|
||||
const promisePtr = this.ffi.QTS_NewPromiseCapability(this.ctx.value, mutablePointerArray.value.ptr);
|
||||
const promiseHandle = this.memory.heapValueHandle(promisePtr);
|
||||
const [resolveHandle, rejectHandle] = Array.from(mutablePointerArray.value.typedArray).map((jsvaluePtr) => this.memory.heapValueHandle(jsvaluePtr));
|
||||
return new deferred_promise_1.QuickJSDeferredPromise({
|
||||
context: this,
|
||||
promiseHandle,
|
||||
resolveHandle,
|
||||
rejectHandle,
|
||||
});
|
||||
});
|
||||
if (value && typeof value === "function") {
|
||||
value = new Promise(value);
|
||||
}
|
||||
if (value) {
|
||||
Promise.resolve(value).then(deferredPromise.resolve, (error) => error instanceof lifetime_1.Lifetime
|
||||
? deferredPromise.reject(error)
|
||||
: this.newError(error).consume(deferredPromise.reject));
|
||||
}
|
||||
return deferredPromise;
|
||||
}
|
||||
/**
|
||||
* Convert a Javascript function into a QuickJS function value.
|
||||
* See [[VmFunctionImplementation]] for more details.
|
||||
*
|
||||
* A [[VmFunctionImplementation]] should not free its arguments or its return
|
||||
* value. A VmFunctionImplementation should also not retain any references to
|
||||
* its return value.
|
||||
*
|
||||
* To implement an async function, create a promise with [[newPromise]], then
|
||||
* return the deferred promise handle from `deferred.handle` from your
|
||||
* function implementation:
|
||||
*
|
||||
* ```
|
||||
* const deferred = vm.newPromise()
|
||||
* someNativeAsyncFunction().then(deferred.resolve)
|
||||
* return deferred.handle
|
||||
* ```
|
||||
*/
|
||||
newFunction(name, fn) {
|
||||
const fnId = ++this.fnNextId;
|
||||
this.setFunction(fnId, fn);
|
||||
return this.memory.heapValueHandle(this.ffi.QTS_NewFunction(this.ctx.value, fnId, name));
|
||||
}
|
||||
newError(error) {
|
||||
const errorHandle = this.memory.heapValueHandle(this.ffi.QTS_NewError(this.ctx.value));
|
||||
if (error && typeof error === "object") {
|
||||
if (error.name !== undefined) {
|
||||
this.newString(error.name).consume((handle) => this.setProp(errorHandle, "name", handle));
|
||||
}
|
||||
if (error.message !== undefined) {
|
||||
this.newString(error.message).consume((handle) => this.setProp(errorHandle, "message", handle));
|
||||
}
|
||||
}
|
||||
else if (typeof error === "string") {
|
||||
this.newString(error).consume((handle) => this.setProp(errorHandle, "message", handle));
|
||||
}
|
||||
else if (error !== undefined) {
|
||||
// This isn't supported in the type signature but maybe it will make life easier.
|
||||
this.newString(String(error)).consume((handle) => this.setProp(errorHandle, "message", handle));
|
||||
}
|
||||
return errorHandle;
|
||||
}
|
||||
// Read values --------------------------------------------------------------
|
||||
/**
|
||||
* `typeof` operator. **Not** [standards compliant](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof).
|
||||
*
|
||||
* @remarks
|
||||
* Does not support BigInt values correctly.
|
||||
*/
|
||||
typeof(handle) {
|
||||
this.runtime.assertOwned(handle);
|
||||
return this.memory.consumeHeapCharPointer(this.ffi.QTS_Typeof(this.ctx.value, handle.value));
|
||||
}
|
||||
/**
|
||||
* Converts `handle` into a Javascript number.
|
||||
* @returns `NaN` on error, otherwise a `number`.
|
||||
*/
|
||||
getNumber(handle) {
|
||||
this.runtime.assertOwned(handle);
|
||||
return this.ffi.QTS_GetFloat64(this.ctx.value, handle.value);
|
||||
}
|
||||
/**
|
||||
* Converts `handle` to a Javascript string.
|
||||
*/
|
||||
getString(handle) {
|
||||
this.runtime.assertOwned(handle);
|
||||
return this.memory.consumeJSCharPointer(this.ffi.QTS_GetString(this.ctx.value, handle.value));
|
||||
}
|
||||
/**
|
||||
* Converts `handle` into a Javascript symbol. If the symbol is in the global
|
||||
* registry in the guest, it will be created with Symbol.for on the host.
|
||||
*/
|
||||
getSymbol(handle) {
|
||||
this.runtime.assertOwned(handle);
|
||||
const key = this.memory.consumeJSCharPointer(this.ffi.QTS_GetSymbolDescriptionOrKey(this.ctx.value, handle.value));
|
||||
const isGlobal = this.ffi.QTS_IsGlobalSymbol(this.ctx.value, handle.value);
|
||||
return isGlobal ? Symbol.for(key) : Symbol(key);
|
||||
}
|
||||
/**
|
||||
* Converts `handle` to a Javascript bigint.
|
||||
*/
|
||||
getBigInt(handle) {
|
||||
this.runtime.assertOwned(handle);
|
||||
const asString = this.getString(handle);
|
||||
return BigInt(asString);
|
||||
}
|
||||
/**
|
||||
* `Promise.resolve(value)`.
|
||||
* Convert a handle containing a Promise-like value inside the VM into an
|
||||
* actual promise on the host.
|
||||
*
|
||||
* @remarks
|
||||
* You may need to call [[executePendingJobs]] to ensure that the promise is resolved.
|
||||
*
|
||||
* @param promiseLikeHandle - A handle to a Promise-like value with a `.then(onSuccess, onError)` method.
|
||||
*/
|
||||
resolvePromise(promiseLikeHandle) {
|
||||
this.runtime.assertOwned(promiseLikeHandle);
|
||||
const vmResolveResult = lifetime_1.Scope.withScope((scope) => {
|
||||
const vmPromise = scope.manage(this.getProp(this.global, "Promise"));
|
||||
const vmPromiseResolve = scope.manage(this.getProp(vmPromise, "resolve"));
|
||||
return this.callFunction(vmPromiseResolve, vmPromise, promiseLikeHandle);
|
||||
});
|
||||
if (vmResolveResult.error) {
|
||||
return Promise.resolve(vmResolveResult);
|
||||
}
|
||||
return new Promise((resolve) => {
|
||||
lifetime_1.Scope.withScope((scope) => {
|
||||
const resolveHandle = scope.manage(this.newFunction("resolve", (value) => {
|
||||
resolve({ value: value && value.dup() });
|
||||
}));
|
||||
const rejectHandle = scope.manage(this.newFunction("reject", (error) => {
|
||||
resolve({ error: error && error.dup() });
|
||||
}));
|
||||
const promiseHandle = scope.manage(vmResolveResult.value);
|
||||
const promiseThenHandle = scope.manage(this.getProp(promiseHandle, "then"));
|
||||
this.unwrapResult(this.callFunction(promiseThenHandle, promiseHandle, resolveHandle, rejectHandle)).dispose();
|
||||
});
|
||||
});
|
||||
}
|
||||
// Properties ---------------------------------------------------------------
|
||||
/**
|
||||
* `handle[key]`.
|
||||
* Get a property from a JSValue.
|
||||
*
|
||||
* @param key - The property may be specified as a JSValue handle, or as a
|
||||
* Javascript string (which will be converted automatically).
|
||||
*/
|
||||
getProp(handle, key) {
|
||||
this.runtime.assertOwned(handle);
|
||||
const ptr = this.borrowPropertyKey(key).consume((quickJSKey) => this.ffi.QTS_GetProp(this.ctx.value, handle.value, quickJSKey.value));
|
||||
const result = this.memory.heapValueHandle(ptr);
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* `handle[key] = value`.
|
||||
* Set a property on a JSValue.
|
||||
*
|
||||
* @remarks
|
||||
* Note that the QuickJS authors recommend using [[defineProp]] to define new
|
||||
* properties.
|
||||
*
|
||||
* @param key - The property may be specified as a JSValue handle, or as a
|
||||
* Javascript string or number (which will be converted automatically to a JSValue).
|
||||
*/
|
||||
setProp(handle, key, value) {
|
||||
this.runtime.assertOwned(handle);
|
||||
// free newly allocated value if key was a string or number. No-op if string was already
|
||||
// a QuickJS handle.
|
||||
this.borrowPropertyKey(key).consume((quickJSKey) => this.ffi.QTS_SetProp(this.ctx.value, handle.value, quickJSKey.value, value.value));
|
||||
}
|
||||
/**
|
||||
* [`Object.defineProperty(handle, key, descriptor)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty).
|
||||
*
|
||||
* @param key - The property may be specified as a JSValue handle, or as a
|
||||
* Javascript string or number (which will be converted automatically to a JSValue).
|
||||
*/
|
||||
defineProp(handle, key, descriptor) {
|
||||
this.runtime.assertOwned(handle);
|
||||
lifetime_1.Scope.withScope((scope) => {
|
||||
const quickJSKey = scope.manage(this.borrowPropertyKey(key));
|
||||
const value = descriptor.value || this.undefined;
|
||||
const configurable = Boolean(descriptor.configurable);
|
||||
const enumerable = Boolean(descriptor.enumerable);
|
||||
const hasValue = Boolean(descriptor.value);
|
||||
const get = descriptor.get
|
||||
? scope.manage(this.newFunction(descriptor.get.name, descriptor.get))
|
||||
: this.undefined;
|
||||
const set = descriptor.set
|
||||
? scope.manage(this.newFunction(descriptor.set.name, descriptor.set))
|
||||
: this.undefined;
|
||||
this.ffi.QTS_DefineProp(this.ctx.value, handle.value, quickJSKey.value, value.value, get.value, set.value, configurable, enumerable, hasValue);
|
||||
});
|
||||
}
|
||||
// Evaluation ---------------------------------------------------------------
|
||||
/**
|
||||
* [`func.call(thisVal, ...args)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call).
|
||||
* Call a JSValue as a function.
|
||||
*
|
||||
* See [[unwrapResult]], which will throw if the function returned an error, or
|
||||
* return the result handle directly. If evaluation returned a handle containing
|
||||
* a promise, use [[resolvePromise]] to convert it to a native promise and
|
||||
* [[executePendingJobs]] to finish evaluating the promise.
|
||||
*
|
||||
* @returns A result. If the function threw synchronously, `result.error` be a
|
||||
* handle to the exception. Otherwise `result.value` will be a handle to the
|
||||
* value.
|
||||
*/
|
||||
callFunction(func, thisVal, ...args) {
|
||||
this.runtime.assertOwned(func);
|
||||
const resultPtr = this.memory
|
||||
.toPointerArray(args)
|
||||
.consume((argsArrayPtr) => this.ffi.QTS_Call(this.ctx.value, func.value, thisVal.value, args.length, argsArrayPtr.value));
|
||||
const errorPtr = this.ffi.QTS_ResolveException(this.ctx.value, resultPtr);
|
||||
if (errorPtr) {
|
||||
this.ffi.QTS_FreeValuePointer(this.ctx.value, resultPtr);
|
||||
return { error: this.memory.heapValueHandle(errorPtr) };
|
||||
}
|
||||
return { value: this.memory.heapValueHandle(resultPtr) };
|
||||
}
|
||||
/**
|
||||
* Like [`eval(code)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval#Description).
|
||||
* Evaluates the Javascript source `code` in the global scope of this VM.
|
||||
* When working with async code, you many need to call [[executePendingJobs]]
|
||||
* to execute callbacks pending after synchronous evaluation returns.
|
||||
*
|
||||
* See [[unwrapResult]], which will throw if the function returned an error, or
|
||||
* return the result handle directly. If evaluation returned a handle containing
|
||||
* a promise, use [[resolvePromise]] to convert it to a native promise and
|
||||
* [[executePendingJobs]] to finish evaluating the promise.
|
||||
*
|
||||
* *Note*: to protect against infinite loops, provide an interrupt handler to
|
||||
* [[setInterruptHandler]]. You can use [[shouldInterruptAfterDeadline]] to
|
||||
* create a time-based deadline.
|
||||
*
|
||||
* @returns The last statement's value. If the code threw synchronously,
|
||||
* `result.error` will be a handle to the exception. If execution was
|
||||
* interrupted, the error will have name `InternalError` and message
|
||||
* `interrupted`.
|
||||
*/
|
||||
evalCode(code, filename = "eval.js",
|
||||
/**
|
||||
* If no options are passed, a heuristic will be used to detect if `code` is
|
||||
* an ES module.
|
||||
*
|
||||
* See [[EvalFlags]] for number semantics.
|
||||
*/
|
||||
options) {
|
||||
const detectModule = (options === undefined ? 1 : 0);
|
||||
const flags = (0, types_1.evalOptionsToFlags)(options);
|
||||
const resultPtr = this.memory
|
||||
.newHeapCharPointer(code)
|
||||
.consume((charHandle) => this.ffi.QTS_Eval(this.ctx.value, charHandle.value, filename, detectModule, flags));
|
||||
const errorPtr = this.ffi.QTS_ResolveException(this.ctx.value, resultPtr);
|
||||
if (errorPtr) {
|
||||
this.ffi.QTS_FreeValuePointer(this.ctx.value, resultPtr);
|
||||
return { error: this.memory.heapValueHandle(errorPtr) };
|
||||
}
|
||||
return { value: this.memory.heapValueHandle(resultPtr) };
|
||||
}
|
||||
/**
|
||||
* Throw an error in the VM, interrupted whatever current execution is in progress when execution resumes.
|
||||
* @experimental
|
||||
*/
|
||||
throw(error) {
|
||||
return this.errorToHandle(error).consume((handle) => this.ffi.QTS_Throw(this.ctx.value, handle.value));
|
||||
}
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
borrowPropertyKey(key) {
|
||||
if (typeof key === "number") {
|
||||
return this.newNumber(key);
|
||||
}
|
||||
if (typeof key === "string") {
|
||||
return this.newString(key);
|
||||
}
|
||||
// key is already a JSValue, but we're borrowing it. Return a static handle
|
||||
// for internal use only.
|
||||
return new lifetime_1.StaticLifetime(key.value, this.runtime);
|
||||
}
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
getMemory(rt) {
|
||||
if (rt === this.rt.value) {
|
||||
return this.memory;
|
||||
}
|
||||
else {
|
||||
throw new Error("Private API. Cannot get memory from a different runtime");
|
||||
}
|
||||
}
|
||||
// Utilities ----------------------------------------------------------------
|
||||
/**
|
||||
* Dump a JSValue to Javascript in a best-effort fashion.
|
||||
* Returns `handle.toString()` if it cannot be serialized to JSON.
|
||||
*/
|
||||
dump(handle) {
|
||||
this.runtime.assertOwned(handle);
|
||||
const type = this.typeof(handle);
|
||||
if (type === "string") {
|
||||
return this.getString(handle);
|
||||
}
|
||||
else if (type === "number") {
|
||||
return this.getNumber(handle);
|
||||
}
|
||||
else if (type === "bigint") {
|
||||
return this.getBigInt(handle);
|
||||
}
|
||||
else if (type === "undefined") {
|
||||
return undefined;
|
||||
}
|
||||
else if (type === "symbol") {
|
||||
return this.getSymbol(handle);
|
||||
}
|
||||
const str = this.memory.consumeJSCharPointer(this.ffi.QTS_Dump(this.ctx.value, handle.value));
|
||||
try {
|
||||
return JSON.parse(str);
|
||||
}
|
||||
catch (err) {
|
||||
return str;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Unwrap a SuccessOrFail result such as a [[VmCallResult]] or a
|
||||
* [[ExecutePendingJobsResult]], where the fail branch contains a handle to a QuickJS error value.
|
||||
* If the result is a success, returns the value.
|
||||
* If the result is an error, converts the error to a native object and throws the error.
|
||||
*/
|
||||
unwrapResult(result) {
|
||||
if (result.error) {
|
||||
const context = "context" in result.error ? result.error.context : this;
|
||||
const cause = result.error.consume((error) => this.dump(error));
|
||||
if (cause && typeof cause === "object" && typeof cause.message === "string") {
|
||||
const { message, name, stack } = cause;
|
||||
const exception = new errors_1.QuickJSUnwrapError("");
|
||||
const hostStack = exception.stack;
|
||||
if (typeof name === "string") {
|
||||
exception.name = cause.name;
|
||||
}
|
||||
if (typeof stack === "string") {
|
||||
exception.stack = `${name}: ${message}\n${cause.stack}Host: ${hostStack}`;
|
||||
}
|
||||
Object.assign(exception, { cause, context, message });
|
||||
throw exception;
|
||||
}
|
||||
throw new errors_1.QuickJSUnwrapError(cause, context);
|
||||
}
|
||||
return result.value;
|
||||
}
|
||||
/** @private */
|
||||
getFunction(fn_id) {
|
||||
const map_id = fn_id >> 8;
|
||||
const fnMap = this.fnMaps.get(map_id);
|
||||
if (!fnMap) {
|
||||
return undefined;
|
||||
}
|
||||
return fnMap.get(fn_id);
|
||||
}
|
||||
/** @private */
|
||||
setFunction(fn_id, handle) {
|
||||
const map_id = fn_id >> 8;
|
||||
let fnMap = this.fnMaps.get(map_id);
|
||||
if (!fnMap) {
|
||||
fnMap = new Map();
|
||||
this.fnMaps.set(map_id, fnMap);
|
||||
}
|
||||
return fnMap.set(fn_id, handle);
|
||||
}
|
||||
errorToHandle(error) {
|
||||
if (error instanceof lifetime_1.Lifetime) {
|
||||
return error;
|
||||
}
|
||||
return this.newError(error);
|
||||
}
|
||||
}
|
||||
exports.QuickJSContext = QuickJSContext;
|
||||
//# sourceMappingURL=context.js.map
|
||||
1
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/context.js.map
generated
vendored
Normal file
1
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/context.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
5
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/debug.d.ts
generated
vendored
Normal file
5
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/debug.d.ts
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
export declare const QTS_DEBUG: boolean;
|
||||
export declare let debugLog: {
|
||||
(...data: any[]): void;
|
||||
(message?: any, ...optionalParams: any[]): void;
|
||||
};
|
||||
6
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/debug.js
generated
vendored
Normal file
6
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/debug.js
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.debugLog = exports.QTS_DEBUG = void 0;
|
||||
exports.QTS_DEBUG = false || Boolean(typeof process === "object" && process.env.QTS_DEBUG);
|
||||
exports.debugLog = exports.QTS_DEBUG ? console.log.bind(console) : () => { };
|
||||
//# sourceMappingURL=debug.js.map
|
||||
1
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/debug.js.map
generated
vendored
Normal file
1
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/debug.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"debug.js","sourceRoot":"","sources":["../ts/debug.ts"],"names":[],"mappings":";;;AAAa,QAAA,SAAS,GAAG,KAAK,IAAI,OAAO,CAAC,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;AACpF,QAAA,QAAQ,GAAG,iBAAS,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,GAAE,CAAC,CAAA","sourcesContent":["export const QTS_DEBUG = false || Boolean(typeof process === \"object\" && process.env.QTS_DEBUG)\nexport let debugLog = QTS_DEBUG ? console.log.bind(console) : () => {}\n"]}
|
||||
75
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/deferred-promise.d.ts
generated
vendored
Normal file
75
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/deferred-promise.d.ts
generated
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
import type { Disposable } from "./lifetime";
|
||||
import type { QuickJSHandle } from "./types";
|
||||
import type { QuickJSRuntime } from "./runtime";
|
||||
import type { QuickJSContext } from "./context";
|
||||
export type { PromiseExecutor } from "./types";
|
||||
/**
|
||||
* QuickJSDeferredPromise wraps a QuickJS promise [[handle]] and allows
|
||||
* [[resolve]]ing or [[reject]]ing that promise. Use it to bridge asynchronous
|
||||
* code on the host to APIs inside a QuickJSContext.
|
||||
*
|
||||
* Managing the lifetime of promises is tricky. There are three
|
||||
* [[QuickJSHandle]]s inside of each deferred promise object: (1) the promise
|
||||
* itself, (2) the `resolve` callback, and (3) the `reject` callback.
|
||||
*
|
||||
* - If the promise will be fulfilled before the end of it's [[owner]]'s lifetime,
|
||||
* the only cleanup necessary is `deferred.handle.dispose()`, because
|
||||
* calling [[resolve]] or [[reject]] will dispose of both callbacks automatically.
|
||||
*
|
||||
* - As the return value of a [[VmFunctionImplementation]], return [[handle]],
|
||||
* and ensure that either [[resolve]] or [[reject]] will be called. No other
|
||||
* clean-up is necessary.
|
||||
*
|
||||
* - In other cases, call [[dispose]], which will dispose [[handle]] as well as the
|
||||
* QuickJS handles that back [[resolve]] and [[reject]]. For this object,
|
||||
* [[dispose]] is idempotent.
|
||||
*/
|
||||
export declare class QuickJSDeferredPromise implements Disposable {
|
||||
owner: QuickJSRuntime;
|
||||
context: QuickJSContext;
|
||||
/**
|
||||
* A handle of the Promise instance inside the QuickJSContext.
|
||||
* You must dispose [[handle]] or the entire QuickJSDeferredPromise once you
|
||||
* are finished with it.
|
||||
*/
|
||||
handle: QuickJSHandle;
|
||||
/**
|
||||
* A native promise that will resolve once this deferred is settled.
|
||||
*/
|
||||
settled: Promise<void>;
|
||||
private resolveHandle;
|
||||
private rejectHandle;
|
||||
private onSettled;
|
||||
/**
|
||||
* Use [[QuickJSContext.newPromise]] to create a new promise instead of calling
|
||||
* this constructor directly.
|
||||
* @unstable
|
||||
*/
|
||||
constructor(args: {
|
||||
context: QuickJSContext;
|
||||
promiseHandle: QuickJSHandle;
|
||||
resolveHandle: QuickJSHandle;
|
||||
rejectHandle: QuickJSHandle;
|
||||
});
|
||||
/**
|
||||
* Resolve [[handle]] with the given value, if any.
|
||||
* Calling this method after calling [[dispose]] is a no-op.
|
||||
*
|
||||
* Note that after resolving a promise, you may need to call
|
||||
* [[QuickJSContext.executePendingJobs]] to propagate the result to the promise's
|
||||
* callbacks.
|
||||
*/
|
||||
resolve: (value?: QuickJSHandle) => void;
|
||||
/**
|
||||
* Reject [[handle]] with the given value, if any.
|
||||
* Calling this method after calling [[dispose]] is a no-op.
|
||||
*
|
||||
* Note that after rejecting a promise, you may need to call
|
||||
* [[QuickJSContext.executePendingJobs]] to propagate the result to the promise's
|
||||
* callbacks.
|
||||
*/
|
||||
reject: (value?: QuickJSHandle) => void;
|
||||
get alive(): boolean;
|
||||
dispose: () => void;
|
||||
private disposeResolvers;
|
||||
}
|
||||
96
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/deferred-promise.js
generated
vendored
Normal file
96
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/deferred-promise.js
generated
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.QuickJSDeferredPromise = void 0;
|
||||
/**
|
||||
* QuickJSDeferredPromise wraps a QuickJS promise [[handle]] and allows
|
||||
* [[resolve]]ing or [[reject]]ing that promise. Use it to bridge asynchronous
|
||||
* code on the host to APIs inside a QuickJSContext.
|
||||
*
|
||||
* Managing the lifetime of promises is tricky. There are three
|
||||
* [[QuickJSHandle]]s inside of each deferred promise object: (1) the promise
|
||||
* itself, (2) the `resolve` callback, and (3) the `reject` callback.
|
||||
*
|
||||
* - If the promise will be fulfilled before the end of it's [[owner]]'s lifetime,
|
||||
* the only cleanup necessary is `deferred.handle.dispose()`, because
|
||||
* calling [[resolve]] or [[reject]] will dispose of both callbacks automatically.
|
||||
*
|
||||
* - As the return value of a [[VmFunctionImplementation]], return [[handle]],
|
||||
* and ensure that either [[resolve]] or [[reject]] will be called. No other
|
||||
* clean-up is necessary.
|
||||
*
|
||||
* - In other cases, call [[dispose]], which will dispose [[handle]] as well as the
|
||||
* QuickJS handles that back [[resolve]] and [[reject]]. For this object,
|
||||
* [[dispose]] is idempotent.
|
||||
*/
|
||||
class QuickJSDeferredPromise {
|
||||
/**
|
||||
* Use [[QuickJSContext.newPromise]] to create a new promise instead of calling
|
||||
* this constructor directly.
|
||||
* @unstable
|
||||
*/
|
||||
constructor(args) {
|
||||
/**
|
||||
* Resolve [[handle]] with the given value, if any.
|
||||
* Calling this method after calling [[dispose]] is a no-op.
|
||||
*
|
||||
* Note that after resolving a promise, you may need to call
|
||||
* [[QuickJSContext.executePendingJobs]] to propagate the result to the promise's
|
||||
* callbacks.
|
||||
*/
|
||||
this.resolve = (value) => {
|
||||
if (!this.resolveHandle.alive) {
|
||||
return;
|
||||
}
|
||||
this.context
|
||||
.unwrapResult(this.context.callFunction(this.resolveHandle, this.context.undefined, value || this.context.undefined))
|
||||
.dispose();
|
||||
this.disposeResolvers();
|
||||
this.onSettled();
|
||||
};
|
||||
/**
|
||||
* Reject [[handle]] with the given value, if any.
|
||||
* Calling this method after calling [[dispose]] is a no-op.
|
||||
*
|
||||
* Note that after rejecting a promise, you may need to call
|
||||
* [[QuickJSContext.executePendingJobs]] to propagate the result to the promise's
|
||||
* callbacks.
|
||||
*/
|
||||
this.reject = (value) => {
|
||||
if (!this.rejectHandle.alive) {
|
||||
return;
|
||||
}
|
||||
this.context
|
||||
.unwrapResult(this.context.callFunction(this.rejectHandle, this.context.undefined, value || this.context.undefined))
|
||||
.dispose();
|
||||
this.disposeResolvers();
|
||||
this.onSettled();
|
||||
};
|
||||
this.dispose = () => {
|
||||
if (this.handle.alive) {
|
||||
this.handle.dispose();
|
||||
}
|
||||
this.disposeResolvers();
|
||||
};
|
||||
this.context = args.context;
|
||||
this.owner = args.context.runtime;
|
||||
this.handle = args.promiseHandle;
|
||||
this.settled = new Promise((resolve) => {
|
||||
this.onSettled = resolve;
|
||||
});
|
||||
this.resolveHandle = args.resolveHandle;
|
||||
this.rejectHandle = args.rejectHandle;
|
||||
}
|
||||
get alive() {
|
||||
return this.handle.alive || this.resolveHandle.alive || this.rejectHandle.alive;
|
||||
}
|
||||
disposeResolvers() {
|
||||
if (this.resolveHandle.alive) {
|
||||
this.resolveHandle.dispose();
|
||||
}
|
||||
if (this.rejectHandle.alive) {
|
||||
this.rejectHandle.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.QuickJSDeferredPromise = QuickJSDeferredPromise;
|
||||
//# sourceMappingURL=deferred-promise.js.map
|
||||
1
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/deferred-promise.js.map
generated
vendored
Normal file
1
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/deferred-promise.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
97
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/emscripten-types.d.ts
generated
vendored
Normal file
97
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/emscripten-types.d.ts
generated
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
import { BorrowedHeapCharPointer, JSContextPointer, JSRuntimePointer, JSValueConstPointer, JSValuePointer, OwnedHeapCharPointer } from "./types-ffi";
|
||||
declare namespace Emscripten {
|
||||
interface FileSystemType {
|
||||
}
|
||||
type EnvironmentType = "WEB" | "NODE" | "SHELL" | "WORKER";
|
||||
type ValueType = "number" | "string" | "array" | "boolean";
|
||||
type TypeCompatibleWithC = number | string | any[] | boolean;
|
||||
type WebAssemblyImports = Array<{
|
||||
name: string;
|
||||
kind: string;
|
||||
}>;
|
||||
type WebAssemblyExports = Array<{
|
||||
module: string;
|
||||
name: string;
|
||||
kind: string;
|
||||
}>;
|
||||
interface CCallOpts {
|
||||
async?: boolean;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Typings for the features we use to interface with our Emscripten build of
|
||||
* QuickJS.
|
||||
*/
|
||||
interface EmscriptenModule {
|
||||
/**
|
||||
* Write JS `str` to HeapChar pointer.
|
||||
* https://emscripten.org/docs/api_reference/preamble.js.html#stringToUTF8
|
||||
*/
|
||||
stringToUTF8(str: string, outPtr: OwnedHeapCharPointer, maxBytesToRead?: number): void;
|
||||
/**
|
||||
* HeapChar to JS string.
|
||||
* https://emscripten.org/docs/api_reference/preamble.js.html#UTF8ToString
|
||||
*/
|
||||
UTF8ToString(ptr: BorrowedHeapCharPointer, maxBytesToRead?: number): string;
|
||||
lengthBytesUTF8(str: string): number;
|
||||
_malloc(size: number): number;
|
||||
_free(ptr: number): void;
|
||||
cwrap(ident: string, returnType: Emscripten.ValueType | null, argTypes: Emscripten.ValueType[], opts?: Emscripten.CCallOpts): (...args: any[]) => any;
|
||||
HEAP8: Int8Array;
|
||||
HEAP16: Int16Array;
|
||||
HEAP32: Int32Array;
|
||||
HEAPU8: Uint8Array;
|
||||
HEAPU16: Uint16Array;
|
||||
HEAPU32: Uint32Array;
|
||||
HEAPF32: Float32Array;
|
||||
HEAPF64: Float64Array;
|
||||
TOTAL_STACK: number;
|
||||
TOTAL_MEMORY: number;
|
||||
FAST_MEMORY: number;
|
||||
}
|
||||
declare const AsyncifySleepReturnValue: unique symbol;
|
||||
/** @private */
|
||||
export type AsyncifySleepResult<T> = T & typeof AsyncifySleepReturnValue;
|
||||
/**
|
||||
* Allows us to optionally suspend the Emscripten runtime to wait for a promise.
|
||||
* https://emscripten.org/docs/porting/asyncify.html#ways-to-use-async-apis-in-older-engines
|
||||
* ```
|
||||
* EM_JS(int, do_fetch, (), {
|
||||
* return Asyncify.handleSleep(function (wakeUp) {
|
||||
* out("waiting for a fetch");
|
||||
* fetch("a.html").then(function (response) {
|
||||
* out("got the fetch response");
|
||||
* // (normally you would do something with the fetch here)
|
||||
* wakeUp(42);
|
||||
* });
|
||||
* });
|
||||
* });
|
||||
* ```
|
||||
* @private
|
||||
*/
|
||||
export interface Asyncify {
|
||||
handleSleep<T>(maybeAsyncFn: (wakeUp: (result: T) => void) => void): AsyncifySleepResult<T>;
|
||||
}
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
export interface EmscriptenModuleCallbacks {
|
||||
callFunction: (asyncify: Asyncify | undefined, ctx: JSContextPointer, this_ptr: JSValueConstPointer, argc: number, argv: JSValueConstPointer, fn_id: number) => JSValuePointer | AsyncifySleepResult<JSValuePointer>;
|
||||
loadModuleSource: (asyncify: Asyncify | undefined, rt: JSRuntimePointer, ctx: JSContextPointer, module_name: string) => BorrowedHeapCharPointer | AsyncifySleepResult<BorrowedHeapCharPointer>;
|
||||
normalizeModule: (asyncify: Asyncify | undefined, rt: JSRuntimePointer, ctx: JSContextPointer, module_base_name: string, module_name: string) => BorrowedHeapCharPointer | AsyncifySleepResult<BorrowedHeapCharPointer>;
|
||||
shouldInterrupt: (asyncify: Asyncify | undefined, rt: JSRuntimePointer) => 0 | 1 | AsyncifySleepResult<0 | 1>;
|
||||
}
|
||||
export interface QuickJSEmscriptenModule extends EmscriptenModule {
|
||||
type: "sync";
|
||||
callbacks: EmscriptenModuleCallbacks;
|
||||
}
|
||||
export interface QuickJSAsyncEmscriptenModule extends EmscriptenModule {
|
||||
/** @todo Implement this field */
|
||||
type: "async";
|
||||
callbacks: EmscriptenModuleCallbacks;
|
||||
}
|
||||
export type EitherModule = QuickJSEmscriptenModule | QuickJSAsyncEmscriptenModule;
|
||||
export interface EmscriptenModuleLoader<T extends EmscriptenModule> {
|
||||
(): Promise<T>;
|
||||
}
|
||||
export {};
|
||||
15
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/emscripten-types.js
generated
vendored
Normal file
15
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/emscripten-types.js
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
"use strict";
|
||||
// This is a subset of the Emscripten type definitions from @types/emscripten
|
||||
// Project: http://kripken.github.io/emscripten-site/index.html
|
||||
// Definitions by: Kensuke Matsuzaki <https://github.com/zakki>
|
||||
// Periklis Tsirakidis <https://github.com/periklis>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
//
|
||||
// quickjs-emscripten doesn't use the full EmscriptenModule type from @types/emscripten because:
|
||||
//
|
||||
// - the upstream types define many properties that don't exist on our module due
|
||||
// to our build settings
|
||||
// - some upstream types reference web-only ambient types like WebGL stuff, which
|
||||
// we don't use.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
//# sourceMappingURL=emscripten-types.js.map
|
||||
1
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/emscripten-types.js.map
generated
vendored
Normal file
1
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/emscripten-types.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
28
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/errors.d.ts
generated
vendored
Normal file
28
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/errors.d.ts
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
import type { QuickJSContext } from "./context";
|
||||
/**
|
||||
* Error thrown if [[QuickJSContext.unwrapResult]] unwraps an error value that isn't an object.
|
||||
*/
|
||||
export declare class QuickJSUnwrapError extends Error {
|
||||
cause: unknown;
|
||||
context?: QuickJSContext | undefined;
|
||||
name: string;
|
||||
constructor(cause: unknown, context?: QuickJSContext | undefined);
|
||||
}
|
||||
export declare class QuickJSWrongOwner extends Error {
|
||||
name: string;
|
||||
}
|
||||
export declare class QuickJSUseAfterFree extends Error {
|
||||
name: string;
|
||||
}
|
||||
export declare class QuickJSNotImplemented extends Error {
|
||||
name: string;
|
||||
}
|
||||
export declare class QuickJSAsyncifyError extends Error {
|
||||
name: string;
|
||||
}
|
||||
export declare class QuickJSAsyncifySuspended extends Error {
|
||||
name: string;
|
||||
}
|
||||
export declare class QuickJSMemoryLeakDetected extends Error {
|
||||
name: string;
|
||||
}
|
||||
58
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/errors.js
generated
vendored
Normal file
58
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/errors.js
generated
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.QuickJSMemoryLeakDetected = exports.QuickJSAsyncifySuspended = exports.QuickJSAsyncifyError = exports.QuickJSNotImplemented = exports.QuickJSUseAfterFree = exports.QuickJSWrongOwner = exports.QuickJSUnwrapError = void 0;
|
||||
/**
|
||||
* Error thrown if [[QuickJSContext.unwrapResult]] unwraps an error value that isn't an object.
|
||||
*/
|
||||
class QuickJSUnwrapError extends Error {
|
||||
constructor(cause, context) {
|
||||
super(String(cause));
|
||||
this.cause = cause;
|
||||
this.context = context;
|
||||
this.name = "QuickJSUnwrapError";
|
||||
}
|
||||
}
|
||||
exports.QuickJSUnwrapError = QuickJSUnwrapError;
|
||||
class QuickJSWrongOwner extends Error {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.name = "QuickJSWrongOwner";
|
||||
}
|
||||
}
|
||||
exports.QuickJSWrongOwner = QuickJSWrongOwner;
|
||||
class QuickJSUseAfterFree extends Error {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.name = "QuickJSUseAfterFree";
|
||||
}
|
||||
}
|
||||
exports.QuickJSUseAfterFree = QuickJSUseAfterFree;
|
||||
class QuickJSNotImplemented extends Error {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.name = "QuickJSNotImplemented";
|
||||
}
|
||||
}
|
||||
exports.QuickJSNotImplemented = QuickJSNotImplemented;
|
||||
class QuickJSAsyncifyError extends Error {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.name = "QuickJSAsyncifyError";
|
||||
}
|
||||
}
|
||||
exports.QuickJSAsyncifyError = QuickJSAsyncifyError;
|
||||
class QuickJSAsyncifySuspended extends Error {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.name = "QuickJSAsyncifySuspended";
|
||||
}
|
||||
}
|
||||
exports.QuickJSAsyncifySuspended = QuickJSAsyncifySuspended;
|
||||
class QuickJSMemoryLeakDetected extends Error {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.name = "QuickJSMemoryLeakDetected";
|
||||
}
|
||||
}
|
||||
exports.QuickJSMemoryLeakDetected = QuickJSMemoryLeakDetected;
|
||||
//# sourceMappingURL=errors.js.map
|
||||
1
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/errors.js.map
generated
vendored
Normal file
1
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/errors.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../ts/errors.ts"],"names":[],"mappings":";;;AAEA;;GAEG;AACH,MAAa,kBAAmB,SAAQ,KAAK;IAE3C,YAAmB,KAAc,EAAS,OAAwB;QAChE,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;QADH,UAAK,GAAL,KAAK,CAAS;QAAS,YAAO,GAAP,OAAO,CAAiB;QADlE,SAAI,GAAG,oBAAoB,CAAA;IAG3B,CAAC;CACF;AALD,gDAKC;AAED,MAAa,iBAAkB,SAAQ,KAAK;IAA5C;;QACE,SAAI,GAAG,mBAAmB,CAAA;IAC5B,CAAC;CAAA;AAFD,8CAEC;AAED,MAAa,mBAAoB,SAAQ,KAAK;IAA9C;;QACE,SAAI,GAAG,qBAAqB,CAAA;IAC9B,CAAC;CAAA;AAFD,kDAEC;AAED,MAAa,qBAAsB,SAAQ,KAAK;IAAhD;;QACE,SAAI,GAAG,uBAAuB,CAAA;IAChC,CAAC;CAAA;AAFD,sDAEC;AAED,MAAa,oBAAqB,SAAQ,KAAK;IAA/C;;QACE,SAAI,GAAG,sBAAsB,CAAA;IAC/B,CAAC;CAAA;AAFD,oDAEC;AAED,MAAa,wBAAyB,SAAQ,KAAK;IAAnD;;QACE,SAAI,GAAG,0BAA0B,CAAA;IACnC,CAAC;CAAA;AAFD,4DAEC;AAED,MAAa,yBAA0B,SAAQ,KAAK;IAApD;;QACE,SAAI,GAAG,2BAA2B,CAAA;IACpC,CAAC;CAAA;AAFD,8DAEC","sourcesContent":["import type { QuickJSContext } from \"./context\"\n\n/**\n * Error thrown if [[QuickJSContext.unwrapResult]] unwraps an error value that isn't an object.\n */\nexport class QuickJSUnwrapError extends Error {\n name = \"QuickJSUnwrapError\"\n constructor(public cause: unknown, public context?: QuickJSContext) {\n super(String(cause))\n }\n}\n\nexport class QuickJSWrongOwner extends Error {\n name = \"QuickJSWrongOwner\"\n}\n\nexport class QuickJSUseAfterFree extends Error {\n name = \"QuickJSUseAfterFree\"\n}\n\nexport class QuickJSNotImplemented extends Error {\n name = \"QuickJSNotImplemented\"\n}\n\nexport class QuickJSAsyncifyError extends Error {\n name = \"QuickJSAsyncifyError\"\n}\n\nexport class QuickJSAsyncifySuspended extends Error {\n name = \"QuickJSAsyncifySuspended\"\n}\n\nexport class QuickJSMemoryLeakDetected extends Error {\n name = \"QuickJSMemoryLeakDetected\"\n}\n"]}
|
||||
9
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/esmHelpers.d.ts
generated
vendored
Normal file
9
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/esmHelpers.d.ts
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
/** Typescript thinks import('...js/.d.ts') needs mod.default.default */
|
||||
declare function fakeUnwrapDefault<T>(mod: {
|
||||
default: T;
|
||||
}): T;
|
||||
/** Typescript thinks import('...ts') doesn't need mod.default.default, but does */
|
||||
declare function actualUnwrapDefault<T>(mod: T): T;
|
||||
export declare const unwrapTypescript: typeof actualUnwrapDefault;
|
||||
export declare const unwrapJavascript: typeof fakeUnwrapDefault;
|
||||
export {};
|
||||
19
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/esmHelpers.js
generated
vendored
Normal file
19
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/esmHelpers.js
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.unwrapJavascript = exports.unwrapTypescript = void 0;
|
||||
/** Typescript thinks import('...js/.d.ts') needs mod.default.default */
|
||||
function fakeUnwrapDefault(mod) {
|
||||
// console.log("fakeUnwrapDefault", mod)
|
||||
return mod.default;
|
||||
}
|
||||
/** Typescript thinks import('...ts') doesn't need mod.default.default, but does */
|
||||
function actualUnwrapDefault(mod) {
|
||||
// console.log("actualUnwrapDefault", mod)
|
||||
const maybeUnwrap = mod.default;
|
||||
return maybeUnwrap ?? mod;
|
||||
}
|
||||
// I'm not sure if this behavior is needed in all runtimes,
|
||||
// or just for mocha + ts-node.
|
||||
exports.unwrapTypescript = actualUnwrapDefault;
|
||||
exports.unwrapJavascript = fakeUnwrapDefault;
|
||||
//# sourceMappingURL=esmHelpers.js.map
|
||||
1
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/esmHelpers.js.map
generated
vendored
Normal file
1
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/esmHelpers.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"esmHelpers.js","sourceRoot":"","sources":["../ts/esmHelpers.ts"],"names":[],"mappings":";;;AAAA,wEAAwE;AACxE,SAAS,iBAAiB,CAAI,GAAmB;IAC/C,wCAAwC;IACxC,OAAO,GAAG,CAAC,OAAY,CAAA;AACzB,CAAC;AAED,mFAAmF;AACnF,SAAS,mBAAmB,CAAI,GAAM;IACpC,0CAA0C;IAC1C,MAAM,WAAW,GAAI,GAAW,CAAC,OAAO,CAAA;IACxC,OAAO,WAAW,IAAI,GAAG,CAAA;AAC3B,CAAC;AAED,2DAA2D;AAC3D,+BAA+B;AAClB,QAAA,gBAAgB,GAAG,mBAAmB,CAAA;AACtC,QAAA,gBAAgB,GAAG,iBAAiB,CAAA","sourcesContent":["/** Typescript thinks import('...js/.d.ts') needs mod.default.default */\nfunction fakeUnwrapDefault<T>(mod: { default: T }): T {\n // console.log(\"fakeUnwrapDefault\", mod)\n return mod.default as T\n}\n\n/** Typescript thinks import('...ts') doesn't need mod.default.default, but does */\nfunction actualUnwrapDefault<T>(mod: T): T {\n // console.log(\"actualUnwrapDefault\", mod)\n const maybeUnwrap = (mod as any).default\n return maybeUnwrap ?? mod\n}\n\n// I'm not sure if this behavior is needed in all runtimes,\n// or just for mocha + ts-node.\nexport const unwrapTypescript = actualUnwrapDefault\nexport const unwrapJavascript = fakeUnwrapDefault\n"]}
|
||||
5
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/generated/emscripten-module.WASM_RELEASE_SYNC.d.ts
generated
vendored
Normal file
5
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/generated/emscripten-module.WASM_RELEASE_SYNC.d.ts
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
export = QuickJSRaw;
|
||||
declare function QuickJSRaw(QuickJSRaw?: {}): any;
|
||||
declare namespace QuickJSRaw {
|
||||
export { QuickJSRaw };
|
||||
}
|
||||
387
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/generated/emscripten-module.WASM_RELEASE_SYNC.js
generated
vendored
Normal file
387
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/generated/emscripten-module.WASM_RELEASE_SYNC.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
1
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/generated/emscripten-module.WASM_RELEASE_SYNC.js.map
generated
vendored
Normal file
1
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/generated/emscripten-module.WASM_RELEASE_SYNC.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
67
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/generated/ffi.WASM_RELEASE_SYNC.d.ts
generated
vendored
Normal file
67
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/generated/ffi.WASM_RELEASE_SYNC.d.ts
generated
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
import { QuickJSEmscriptenModule } from "../emscripten-types";
|
||||
import { JSRuntimePointer, JSContextPointer, JSContextPointerPointer, JSValuePointer, JSValueConstPointer, JSValuePointerPointer, JSValueConstPointerPointer, BorrowedHeapCharPointer, OwnedHeapCharPointer, JSBorrowedCharPointer, JSVoidPointer, EvalFlags, EvalDetectModule } from "../types-ffi";
|
||||
/**
|
||||
* Low-level FFI bindings to QuickJS's Emscripten module.
|
||||
* See instead [[QuickJSContext]], the public Javascript interface exposed by this
|
||||
* library.
|
||||
*
|
||||
* @unstable The FFI interface is considered private and may change.
|
||||
*/
|
||||
export declare class QuickJSFFI {
|
||||
private module;
|
||||
constructor(module: QuickJSEmscriptenModule);
|
||||
/** Set at compile time. */
|
||||
readonly DEBUG = false;
|
||||
QTS_Throw: (ctx: JSContextPointer, error: JSValuePointer | JSValueConstPointer) => JSValuePointer;
|
||||
QTS_NewError: (ctx: JSContextPointer) => JSValuePointer;
|
||||
QTS_RuntimeSetMemoryLimit: (rt: JSRuntimePointer, limit: number) => void;
|
||||
QTS_RuntimeComputeMemoryUsage: (rt: JSRuntimePointer, ctx: JSContextPointer) => JSValuePointer;
|
||||
QTS_RuntimeDumpMemoryUsage: (rt: JSRuntimePointer) => OwnedHeapCharPointer;
|
||||
QTS_RecoverableLeakCheck: () => number;
|
||||
QTS_BuildIsSanitizeLeak: () => number;
|
||||
QTS_RuntimeSetMaxStackSize: (rt: JSRuntimePointer, stack_size: number) => void;
|
||||
QTS_GetUndefined: () => JSValueConstPointer;
|
||||
QTS_GetNull: () => JSValueConstPointer;
|
||||
QTS_GetFalse: () => JSValueConstPointer;
|
||||
QTS_GetTrue: () => JSValueConstPointer;
|
||||
QTS_NewRuntime: () => JSRuntimePointer;
|
||||
QTS_FreeRuntime: (rt: JSRuntimePointer) => void;
|
||||
QTS_NewContext: (rt: JSRuntimePointer) => JSContextPointer;
|
||||
QTS_FreeContext: (ctx: JSContextPointer) => void;
|
||||
QTS_FreeValuePointer: (ctx: JSContextPointer, value: JSValuePointer) => void;
|
||||
QTS_FreeValuePointerRuntime: (rt: JSRuntimePointer, value: JSValuePointer) => void;
|
||||
QTS_FreeVoidPointer: (ctx: JSContextPointer, ptr: JSVoidPointer) => void;
|
||||
QTS_FreeCString: (ctx: JSContextPointer, str: JSBorrowedCharPointer) => void;
|
||||
QTS_DupValuePointer: (ctx: JSContextPointer, val: JSValuePointer | JSValueConstPointer) => JSValuePointer;
|
||||
QTS_NewObject: (ctx: JSContextPointer) => JSValuePointer;
|
||||
QTS_NewObjectProto: (ctx: JSContextPointer, proto: JSValuePointer | JSValueConstPointer) => JSValuePointer;
|
||||
QTS_NewArray: (ctx: JSContextPointer) => JSValuePointer;
|
||||
QTS_NewFloat64: (ctx: JSContextPointer, num: number) => JSValuePointer;
|
||||
QTS_GetFloat64: (ctx: JSContextPointer, value: JSValuePointer | JSValueConstPointer) => number;
|
||||
QTS_NewString: (ctx: JSContextPointer, string: BorrowedHeapCharPointer) => JSValuePointer;
|
||||
QTS_GetString: (ctx: JSContextPointer, value: JSValuePointer | JSValueConstPointer) => JSBorrowedCharPointer;
|
||||
QTS_NewSymbol: (ctx: JSContextPointer, description: BorrowedHeapCharPointer, isGlobal: number) => JSValuePointer;
|
||||
QTS_GetSymbolDescriptionOrKey: (ctx: JSContextPointer, value: JSValuePointer | JSValueConstPointer) => JSBorrowedCharPointer;
|
||||
QTS_IsGlobalSymbol: (ctx: JSContextPointer, value: JSValuePointer | JSValueConstPointer) => number;
|
||||
QTS_IsJobPending: (rt: JSRuntimePointer) => number;
|
||||
QTS_ExecutePendingJob: (rt: JSRuntimePointer, maxJobsToExecute: number, lastJobContext: JSContextPointerPointer) => JSValuePointer;
|
||||
QTS_GetProp: (ctx: JSContextPointer, this_val: JSValuePointer | JSValueConstPointer, prop_name: JSValuePointer | JSValueConstPointer) => JSValuePointer;
|
||||
QTS_SetProp: (ctx: JSContextPointer, this_val: JSValuePointer | JSValueConstPointer, prop_name: JSValuePointer | JSValueConstPointer, prop_value: JSValuePointer | JSValueConstPointer) => void;
|
||||
QTS_DefineProp: (ctx: JSContextPointer, this_val: JSValuePointer | JSValueConstPointer, prop_name: JSValuePointer | JSValueConstPointer, prop_value: JSValuePointer | JSValueConstPointer, get: JSValuePointer | JSValueConstPointer, set: JSValuePointer | JSValueConstPointer, configurable: boolean, enumerable: boolean, has_value: boolean) => void;
|
||||
QTS_Call: (ctx: JSContextPointer, func_obj: JSValuePointer | JSValueConstPointer, this_obj: JSValuePointer | JSValueConstPointer, argc: number, argv_ptrs: JSValueConstPointerPointer) => JSValuePointer;
|
||||
QTS_ResolveException: (ctx: JSContextPointer, maybe_exception: JSValuePointer) => JSValuePointer;
|
||||
QTS_Dump: (ctx: JSContextPointer, obj: JSValuePointer | JSValueConstPointer) => JSBorrowedCharPointer;
|
||||
QTS_Eval: (ctx: JSContextPointer, js_code: BorrowedHeapCharPointer, filename: string, detectModule: EvalDetectModule, evalFlags: EvalFlags) => JSValuePointer;
|
||||
QTS_Typeof: (ctx: JSContextPointer, value: JSValuePointer | JSValueConstPointer) => OwnedHeapCharPointer;
|
||||
QTS_GetGlobalObject: (ctx: JSContextPointer) => JSValuePointer;
|
||||
QTS_NewPromiseCapability: (ctx: JSContextPointer, resolve_funcs_out: JSValuePointerPointer) => JSValuePointer;
|
||||
QTS_TestStringArg: (string: string) => void;
|
||||
QTS_BuildIsDebug: () => number;
|
||||
QTS_BuildIsAsyncify: () => number;
|
||||
QTS_NewFunction: (ctx: JSContextPointer, func_id: number, name: string) => JSValuePointer;
|
||||
QTS_ArgvGetJSValueConstPointer: (argv: JSValuePointer | JSValueConstPointer, index: number) => JSValueConstPointer;
|
||||
QTS_RuntimeEnableInterruptHandler: (rt: JSRuntimePointer) => void;
|
||||
QTS_RuntimeDisableInterruptHandler: (rt: JSRuntimePointer) => void;
|
||||
QTS_RuntimeEnableModuleLoader: (rt: JSRuntimePointer, use_custom_normalize: number) => void;
|
||||
QTS_RuntimeDisableModuleLoader: (rt: JSRuntimePointer) => void;
|
||||
}
|
||||
71
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/generated/ffi.WASM_RELEASE_SYNC.js
generated
vendored
Normal file
71
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/generated/ffi.WASM_RELEASE_SYNC.js
generated
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.QuickJSFFI = void 0;
|
||||
/**
|
||||
* Low-level FFI bindings to QuickJS's Emscripten module.
|
||||
* See instead [[QuickJSContext]], the public Javascript interface exposed by this
|
||||
* library.
|
||||
*
|
||||
* @unstable The FFI interface is considered private and may change.
|
||||
*/
|
||||
class QuickJSFFI {
|
||||
constructor(module) {
|
||||
this.module = module;
|
||||
/** Set at compile time. */
|
||||
this.DEBUG = false;
|
||||
this.QTS_Throw = this.module.cwrap("QTS_Throw", "number", ["number", "number"]);
|
||||
this.QTS_NewError = this.module.cwrap("QTS_NewError", "number", ["number"]);
|
||||
this.QTS_RuntimeSetMemoryLimit = this.module.cwrap("QTS_RuntimeSetMemoryLimit", null, ["number", "number"]);
|
||||
this.QTS_RuntimeComputeMemoryUsage = this.module.cwrap("QTS_RuntimeComputeMemoryUsage", "number", ["number", "number"]);
|
||||
this.QTS_RuntimeDumpMemoryUsage = this.module.cwrap("QTS_RuntimeDumpMemoryUsage", "number", ["number"]);
|
||||
this.QTS_RecoverableLeakCheck = this.module.cwrap("QTS_RecoverableLeakCheck", "number", []);
|
||||
this.QTS_BuildIsSanitizeLeak = this.module.cwrap("QTS_BuildIsSanitizeLeak", "number", []);
|
||||
this.QTS_RuntimeSetMaxStackSize = this.module.cwrap("QTS_RuntimeSetMaxStackSize", null, ["number", "number"]);
|
||||
this.QTS_GetUndefined = this.module.cwrap("QTS_GetUndefined", "number", []);
|
||||
this.QTS_GetNull = this.module.cwrap("QTS_GetNull", "number", []);
|
||||
this.QTS_GetFalse = this.module.cwrap("QTS_GetFalse", "number", []);
|
||||
this.QTS_GetTrue = this.module.cwrap("QTS_GetTrue", "number", []);
|
||||
this.QTS_NewRuntime = this.module.cwrap("QTS_NewRuntime", "number", []);
|
||||
this.QTS_FreeRuntime = this.module.cwrap("QTS_FreeRuntime", null, ["number"]);
|
||||
this.QTS_NewContext = this.module.cwrap("QTS_NewContext", "number", ["number"]);
|
||||
this.QTS_FreeContext = this.module.cwrap("QTS_FreeContext", null, ["number"]);
|
||||
this.QTS_FreeValuePointer = this.module.cwrap("QTS_FreeValuePointer", null, ["number", "number"]);
|
||||
this.QTS_FreeValuePointerRuntime = this.module.cwrap("QTS_FreeValuePointerRuntime", null, ["number", "number"]);
|
||||
this.QTS_FreeVoidPointer = this.module.cwrap("QTS_FreeVoidPointer", null, ["number", "number"]);
|
||||
this.QTS_FreeCString = this.module.cwrap("QTS_FreeCString", null, ["number", "number"]);
|
||||
this.QTS_DupValuePointer = this.module.cwrap("QTS_DupValuePointer", "number", ["number", "number"]);
|
||||
this.QTS_NewObject = this.module.cwrap("QTS_NewObject", "number", ["number"]);
|
||||
this.QTS_NewObjectProto = this.module.cwrap("QTS_NewObjectProto", "number", ["number", "number"]);
|
||||
this.QTS_NewArray = this.module.cwrap("QTS_NewArray", "number", ["number"]);
|
||||
this.QTS_NewFloat64 = this.module.cwrap("QTS_NewFloat64", "number", ["number", "number"]);
|
||||
this.QTS_GetFloat64 = this.module.cwrap("QTS_GetFloat64", "number", ["number", "number"]);
|
||||
this.QTS_NewString = this.module.cwrap("QTS_NewString", "number", ["number", "number"]);
|
||||
this.QTS_GetString = this.module.cwrap("QTS_GetString", "number", ["number", "number"]);
|
||||
this.QTS_NewSymbol = this.module.cwrap("QTS_NewSymbol", "number", ["number", "number", "number"]);
|
||||
this.QTS_GetSymbolDescriptionOrKey = this.module.cwrap("QTS_GetSymbolDescriptionOrKey", "number", ["number", "number"]);
|
||||
this.QTS_IsGlobalSymbol = this.module.cwrap("QTS_IsGlobalSymbol", "number", ["number", "number"]);
|
||||
this.QTS_IsJobPending = this.module.cwrap("QTS_IsJobPending", "number", ["number"]);
|
||||
this.QTS_ExecutePendingJob = this.module.cwrap("QTS_ExecutePendingJob", "number", ["number", "number", "number"]);
|
||||
this.QTS_GetProp = this.module.cwrap("QTS_GetProp", "number", ["number", "number", "number"]);
|
||||
this.QTS_SetProp = this.module.cwrap("QTS_SetProp", null, ["number", "number", "number", "number"]);
|
||||
this.QTS_DefineProp = this.module.cwrap("QTS_DefineProp", null, ["number", "number", "number", "number", "number", "number", "boolean", "boolean", "boolean"]);
|
||||
this.QTS_Call = this.module.cwrap("QTS_Call", "number", ["number", "number", "number", "number", "number"]);
|
||||
this.QTS_ResolveException = this.module.cwrap("QTS_ResolveException", "number", ["number", "number"]);
|
||||
this.QTS_Dump = this.module.cwrap("QTS_Dump", "number", ["number", "number"]);
|
||||
this.QTS_Eval = this.module.cwrap("QTS_Eval", "number", ["number", "number", "string", "number", "number"]);
|
||||
this.QTS_Typeof = this.module.cwrap("QTS_Typeof", "number", ["number", "number"]);
|
||||
this.QTS_GetGlobalObject = this.module.cwrap("QTS_GetGlobalObject", "number", ["number"]);
|
||||
this.QTS_NewPromiseCapability = this.module.cwrap("QTS_NewPromiseCapability", "number", ["number", "number"]);
|
||||
this.QTS_TestStringArg = this.module.cwrap("QTS_TestStringArg", null, ["string"]);
|
||||
this.QTS_BuildIsDebug = this.module.cwrap("QTS_BuildIsDebug", "number", []);
|
||||
this.QTS_BuildIsAsyncify = this.module.cwrap("QTS_BuildIsAsyncify", "number", []);
|
||||
this.QTS_NewFunction = this.module.cwrap("QTS_NewFunction", "number", ["number", "number", "string"]);
|
||||
this.QTS_ArgvGetJSValueConstPointer = this.module.cwrap("QTS_ArgvGetJSValueConstPointer", "number", ["number", "number"]);
|
||||
this.QTS_RuntimeEnableInterruptHandler = this.module.cwrap("QTS_RuntimeEnableInterruptHandler", null, ["number"]);
|
||||
this.QTS_RuntimeDisableInterruptHandler = this.module.cwrap("QTS_RuntimeDisableInterruptHandler", null, ["number"]);
|
||||
this.QTS_RuntimeEnableModuleLoader = this.module.cwrap("QTS_RuntimeEnableModuleLoader", null, ["number", "number"]);
|
||||
this.QTS_RuntimeDisableModuleLoader = this.module.cwrap("QTS_RuntimeDisableModuleLoader", null, ["number"]);
|
||||
}
|
||||
}
|
||||
exports.QuickJSFFI = QuickJSFFI;
|
||||
//# sourceMappingURL=ffi.WASM_RELEASE_SYNC.js.map
|
||||
1
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/generated/ffi.WASM_RELEASE_SYNC.js.map
generated
vendored
Normal file
1
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/generated/ffi.WASM_RELEASE_SYNC.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
75
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/index.d.ts
generated
vendored
Normal file
75
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
import type { QuickJSWASMModule } from "./module";
|
||||
import type { QuickJSRuntime, InterruptHandler } from "./runtime";
|
||||
import type { QuickJSContext } from "./context";
|
||||
export type { QuickJSWASMModule, QuickJSContext, QuickJSRuntime };
|
||||
import type { QuickJSAsyncWASMModule } from "./module-asyncify";
|
||||
import type { QuickJSAsyncRuntime } from "./runtime-asyncify";
|
||||
import type { QuickJSAsyncContext, AsyncFunctionImplementation } from "./context-asyncify";
|
||||
import { AsyncRuntimeOptions, ContextOptions } from "./types";
|
||||
export type { QuickJSAsyncContext, QuickJSAsyncRuntime, QuickJSAsyncWASMModule, AsyncFunctionImplementation, };
|
||||
import { newQuickJSWASMModule, newQuickJSAsyncWASMModule, DEBUG_ASYNC, DEBUG_SYNC, RELEASE_ASYNC, RELEASE_SYNC, SyncBuildVariant, AsyncBuildVariant } from "./variants";
|
||||
export { newQuickJSWASMModule, newQuickJSAsyncWASMModule, DEBUG_ASYNC, DEBUG_SYNC, RELEASE_ASYNC, RELEASE_SYNC, SyncBuildVariant, AsyncBuildVariant, };
|
||||
export * from "./vm-interface";
|
||||
export * from "./lifetime";
|
||||
/** Collects the informative errors this library may throw. */
|
||||
export * as errors from "./errors";
|
||||
export * from "./deferred-promise";
|
||||
export * from "./module-test";
|
||||
export type { StaticJSValue, JSValueConst, JSValue, QuickJSHandle, ContextOptions, ContextEvalOptions, RuntimeOptions, AsyncRuntimeOptions, RuntimeOptionsBase, JSModuleLoader, JSModuleLoadResult, JSModuleLoaderAsync, JSModuleLoadSuccess, JSModuleLoadFailure, JSModuleNormalizer, JSModuleNormalizerAsync, JSModuleNormalizeResult, JSModuleNormalizeFailure, JSModuleNormalizeSuccess, } from "./types";
|
||||
export type { ModuleEvalOptions } from "./module";
|
||||
export type { InterruptHandler, ExecutePendingJobsResult } from "./runtime";
|
||||
export type { QuickJSPropertyKey } from "./context";
|
||||
/**
|
||||
* Get a shared singleton {@link QuickJSWASMModule}. Use this to evaluate code
|
||||
* or create Javascript environments.
|
||||
*
|
||||
* This is the top-level entrypoint for the quickjs-emscripten library.
|
||||
*
|
||||
* If you need strictest possible isolation guarantees, you may create a
|
||||
* separate {@link QuickJSWASMModule} via {@link newQuickJSWASMModule}.
|
||||
*
|
||||
* To work with the asyncified version of this library, see these functions:
|
||||
*
|
||||
* - {@link newAsyncRuntime}.
|
||||
* - {@link newAsyncContext}.
|
||||
* - {@link newQuickJSAsyncWASMModule}.
|
||||
*/
|
||||
export declare function getQuickJS(): Promise<QuickJSWASMModule>;
|
||||
/**
|
||||
* Provides synchronous access to the shared {@link QuickJSWASMModule} instance returned by {@link getQuickJS}, as long as
|
||||
* least once.
|
||||
* @throws If called before `getQuickJS` resolves.
|
||||
*/
|
||||
export declare function getQuickJSSync(): QuickJSWASMModule;
|
||||
/**
|
||||
* Create a new [[QuickJSAsyncRuntime]] in a separate WebAssembly module.
|
||||
*
|
||||
* Each runtime is isolated in a separate WebAssembly module, so that errors in
|
||||
* one runtime cannot contaminate another runtime, and each runtime can execute
|
||||
* an asynchronous action without conflicts.
|
||||
*
|
||||
* Note that there is a hard limit on the number of WebAssembly modules in older
|
||||
* versions of v8:
|
||||
* https://bugs.chromium.org/p/v8/issues/detail?id=12076
|
||||
*/
|
||||
export declare function newAsyncRuntime(options?: AsyncRuntimeOptions): Promise<QuickJSAsyncRuntime>;
|
||||
/**
|
||||
* Create a new [[QuickJSAsyncContext]] (with an associated runtime) in an
|
||||
* separate WebAssembly module.
|
||||
*
|
||||
* Each context is isolated in a separate WebAssembly module, so that errors in
|
||||
* one runtime cannot contaminate another runtime, and each runtime can execute
|
||||
* an asynchronous action without conflicts.
|
||||
*
|
||||
* Note that there is a hard limit on the number of WebAssembly modules in older
|
||||
* versions of v8:
|
||||
* https://bugs.chromium.org/p/v8/issues/detail?id=12076
|
||||
*/
|
||||
export declare function newAsyncContext(options?: ContextOptions): Promise<QuickJSAsyncContext>;
|
||||
/**
|
||||
* Returns an interrupt handler that interrupts Javascript execution after a deadline time.
|
||||
*
|
||||
* @param deadline - Interrupt execution if it's still running after this time.
|
||||
* Number values are compared against `Date.now()`
|
||||
*/
|
||||
export declare function shouldInterruptAfterDeadline(deadline: Date | number): InterruptHandler;
|
||||
128
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/index.js
generated
vendored
Normal file
128
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/index.js
generated
vendored
Normal file
@@ -0,0 +1,128 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
||||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
||||
};
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.shouldInterruptAfterDeadline = exports.newAsyncContext = exports.newAsyncRuntime = exports.getQuickJSSync = exports.getQuickJS = exports.errors = exports.RELEASE_SYNC = exports.RELEASE_ASYNC = exports.DEBUG_SYNC = exports.DEBUG_ASYNC = exports.newQuickJSAsyncWASMModule = exports.newQuickJSWASMModule = void 0;
|
||||
// Build variants
|
||||
const variants_1 = require("./variants");
|
||||
Object.defineProperty(exports, "newQuickJSWASMModule", { enumerable: true, get: function () { return variants_1.newQuickJSWASMModule; } });
|
||||
Object.defineProperty(exports, "newQuickJSAsyncWASMModule", { enumerable: true, get: function () { return variants_1.newQuickJSAsyncWASMModule; } });
|
||||
Object.defineProperty(exports, "DEBUG_ASYNC", { enumerable: true, get: function () { return variants_1.DEBUG_ASYNC; } });
|
||||
Object.defineProperty(exports, "DEBUG_SYNC", { enumerable: true, get: function () { return variants_1.DEBUG_SYNC; } });
|
||||
Object.defineProperty(exports, "RELEASE_ASYNC", { enumerable: true, get: function () { return variants_1.RELEASE_ASYNC; } });
|
||||
Object.defineProperty(exports, "RELEASE_SYNC", { enumerable: true, get: function () { return variants_1.RELEASE_SYNC; } });
|
||||
// Export helpers
|
||||
__exportStar(require("./vm-interface"), exports);
|
||||
__exportStar(require("./lifetime"), exports);
|
||||
/** Collects the informative errors this library may throw. */
|
||||
exports.errors = __importStar(require("./errors"));
|
||||
__exportStar(require("./deferred-promise"), exports);
|
||||
__exportStar(require("./module-test"), exports);
|
||||
let singleton = undefined;
|
||||
let singletonPromise = undefined;
|
||||
/**
|
||||
* Get a shared singleton {@link QuickJSWASMModule}. Use this to evaluate code
|
||||
* or create Javascript environments.
|
||||
*
|
||||
* This is the top-level entrypoint for the quickjs-emscripten library.
|
||||
*
|
||||
* If you need strictest possible isolation guarantees, you may create a
|
||||
* separate {@link QuickJSWASMModule} via {@link newQuickJSWASMModule}.
|
||||
*
|
||||
* To work with the asyncified version of this library, see these functions:
|
||||
*
|
||||
* - {@link newAsyncRuntime}.
|
||||
* - {@link newAsyncContext}.
|
||||
* - {@link newQuickJSAsyncWASMModule}.
|
||||
*/
|
||||
async function getQuickJS() {
|
||||
singletonPromise ?? (singletonPromise = (0, variants_1.newQuickJSWASMModule)().then((instance) => {
|
||||
singleton = instance;
|
||||
return instance;
|
||||
}));
|
||||
return await singletonPromise;
|
||||
}
|
||||
exports.getQuickJS = getQuickJS;
|
||||
/**
|
||||
* Provides synchronous access to the shared {@link QuickJSWASMModule} instance returned by {@link getQuickJS}, as long as
|
||||
* least once.
|
||||
* @throws If called before `getQuickJS` resolves.
|
||||
*/
|
||||
function getQuickJSSync() {
|
||||
if (!singleton) {
|
||||
throw new Error("QuickJS not initialized. Await getQuickJS() at least once.");
|
||||
}
|
||||
return singleton;
|
||||
}
|
||||
exports.getQuickJSSync = getQuickJSSync;
|
||||
/**
|
||||
* Create a new [[QuickJSAsyncRuntime]] in a separate WebAssembly module.
|
||||
*
|
||||
* Each runtime is isolated in a separate WebAssembly module, so that errors in
|
||||
* one runtime cannot contaminate another runtime, and each runtime can execute
|
||||
* an asynchronous action without conflicts.
|
||||
*
|
||||
* Note that there is a hard limit on the number of WebAssembly modules in older
|
||||
* versions of v8:
|
||||
* https://bugs.chromium.org/p/v8/issues/detail?id=12076
|
||||
*/
|
||||
async function newAsyncRuntime(options) {
|
||||
const module = await (0, variants_1.newQuickJSAsyncWASMModule)();
|
||||
return module.newRuntime(options);
|
||||
}
|
||||
exports.newAsyncRuntime = newAsyncRuntime;
|
||||
/**
|
||||
* Create a new [[QuickJSAsyncContext]] (with an associated runtime) in an
|
||||
* separate WebAssembly module.
|
||||
*
|
||||
* Each context is isolated in a separate WebAssembly module, so that errors in
|
||||
* one runtime cannot contaminate another runtime, and each runtime can execute
|
||||
* an asynchronous action without conflicts.
|
||||
*
|
||||
* Note that there is a hard limit on the number of WebAssembly modules in older
|
||||
* versions of v8:
|
||||
* https://bugs.chromium.org/p/v8/issues/detail?id=12076
|
||||
*/
|
||||
async function newAsyncContext(options) {
|
||||
const module = await (0, variants_1.newQuickJSAsyncWASMModule)();
|
||||
return module.newContext(options);
|
||||
}
|
||||
exports.newAsyncContext = newAsyncContext;
|
||||
/**
|
||||
* Returns an interrupt handler that interrupts Javascript execution after a deadline time.
|
||||
*
|
||||
* @param deadline - Interrupt execution if it's still running after this time.
|
||||
* Number values are compared against `Date.now()`
|
||||
*/
|
||||
function shouldInterruptAfterDeadline(deadline) {
|
||||
const deadlineAsNumber = typeof deadline === "number" ? deadline : deadline.getTime();
|
||||
return function () {
|
||||
return Date.now() > deadlineAsNumber;
|
||||
};
|
||||
}
|
||||
exports.shouldInterruptAfterDeadline = shouldInterruptAfterDeadline;
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/index.js.map
generated
vendored
Normal file
1
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/index.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
115
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/lifetime.d.ts
generated
vendored
Normal file
115
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/lifetime.d.ts
generated
vendored
Normal file
@@ -0,0 +1,115 @@
|
||||
import { MaybeAsyncBlock } from "./asyncify-helpers";
|
||||
import type { QuickJSHandle } from "./types";
|
||||
/**
|
||||
* An object that can be disposed.
|
||||
* [[Lifetime]] is the canonical implementation of Disposable.
|
||||
* Use [[Scope]] to manage cleaning up multiple disposables.
|
||||
*/
|
||||
export interface Disposable {
|
||||
/**
|
||||
* Dispose of the underlying resources used by this object.
|
||||
*/
|
||||
dispose(): void;
|
||||
/**
|
||||
* @returns true if the object is alive
|
||||
* @returns false after the object has been [[dispose]]d
|
||||
*/
|
||||
alive: boolean;
|
||||
}
|
||||
/**
|
||||
* A lifetime prevents access to a value after the lifetime has been
|
||||
* [[dispose]]ed.
|
||||
*
|
||||
* Typically, quickjs-emscripten uses Lifetimes to protect C memory pointers.
|
||||
*/
|
||||
export declare class Lifetime<T, TCopy = never, Owner = never> implements Disposable {
|
||||
protected readonly _value: T;
|
||||
protected readonly copier?: ((value: T | TCopy) => TCopy) | undefined;
|
||||
protected readonly disposer?: ((value: T | TCopy) => void) | undefined;
|
||||
protected readonly _owner?: Owner | undefined;
|
||||
protected _alive: boolean;
|
||||
protected _constructorStack: string | undefined;
|
||||
/**
|
||||
* When the Lifetime is disposed, it will call `disposer(_value)`. Use the
|
||||
* disposer function to implement whatever cleanup needs to happen at the end
|
||||
* of `value`'s lifetime.
|
||||
*
|
||||
* `_owner` is not used or controlled by the lifetime. It's just metadata for
|
||||
* the creator.
|
||||
*/
|
||||
constructor(_value: T, copier?: ((value: T | TCopy) => TCopy) | undefined, disposer?: ((value: T | TCopy) => void) | undefined, _owner?: Owner | undefined);
|
||||
get alive(): boolean;
|
||||
/**
|
||||
* The value this Lifetime protects. You must never retain the value - it
|
||||
* may become invalid, leading to memory errors.
|
||||
*
|
||||
* @throws If the lifetime has been [[dispose]]d already.
|
||||
*/
|
||||
get value(): T;
|
||||
get owner(): Owner | undefined;
|
||||
get dupable(): boolean;
|
||||
/**
|
||||
* Create a new handle pointing to the same [[value]].
|
||||
*/
|
||||
dup(): Lifetime<TCopy, TCopy, Owner>;
|
||||
/**
|
||||
* Call `map` with this lifetime, then dispose the lifetime.
|
||||
* @return the result of `map(this)`.
|
||||
*/
|
||||
consume<O>(map: (lifetime: this) => O): O;
|
||||
consume<O>(map: (lifetime: QuickJSHandle) => O): O;
|
||||
/**
|
||||
* Dispose of [[value]] and perform cleanup.
|
||||
*/
|
||||
dispose(): void;
|
||||
private assertAlive;
|
||||
}
|
||||
/**
|
||||
* A Lifetime that lives forever. Used for constants.
|
||||
*/
|
||||
export declare class StaticLifetime<T, Owner = never> extends Lifetime<T, T, Owner> {
|
||||
constructor(value: T, owner?: Owner);
|
||||
get dupable(): boolean;
|
||||
dup(): this;
|
||||
dispose(): void;
|
||||
}
|
||||
/**
|
||||
* A Lifetime that does not own its `value`. A WeakLifetime never calls its
|
||||
* `disposer` function, but can be `dup`ed to produce regular lifetimes that
|
||||
* do.
|
||||
*
|
||||
* Used for function arguments.
|
||||
*/
|
||||
export declare class WeakLifetime<T, TCopy = never, Owner = never> extends Lifetime<T, TCopy, Owner> {
|
||||
constructor(value: T, copier?: (value: T | TCopy) => TCopy, disposer?: (value: TCopy) => void, owner?: Owner);
|
||||
dispose(): void;
|
||||
}
|
||||
/**
|
||||
* Scope helps reduce the burden of manually tracking and disposing of
|
||||
* Lifetimes. See [[withScope]]. and [[withScopeAsync]].
|
||||
*/
|
||||
export declare class Scope implements Disposable {
|
||||
/**
|
||||
* Run `block` with a new Scope instance that will be disposed after the block returns.
|
||||
* Inside `block`, call `scope.manage` on each lifetime you create to have the lifetime
|
||||
* automatically disposed after the block returns.
|
||||
*
|
||||
* @warning Do not use with async functions. Instead, use [[withScopeAsync]].
|
||||
*/
|
||||
static withScope<R>(block: (scope: Scope) => R): R;
|
||||
static withScopeMaybeAsync<Return, This, Yielded>(_this: This, block: MaybeAsyncBlock<Return, This, Yielded, [Scope]>): Return | Promise<Return>;
|
||||
/**
|
||||
* Run `block` with a new Scope instance that will be disposed after the
|
||||
* block's returned promise settles. Inside `block`, call `scope.manage` on each
|
||||
* lifetime you create to have the lifetime automatically disposed after the
|
||||
* block returns.
|
||||
*/
|
||||
static withScopeAsync<R>(block: (scope: Scope) => Promise<R>): Promise<R>;
|
||||
private _disposables;
|
||||
/**
|
||||
* Track `lifetime` so that it is disposed when this scope is disposed.
|
||||
*/
|
||||
manage<T extends Disposable>(lifetime: T): T;
|
||||
get alive(): boolean;
|
||||
dispose(): void;
|
||||
}
|
||||
227
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/lifetime.js
generated
vendored
Normal file
227
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/lifetime.js
generated
vendored
Normal file
@@ -0,0 +1,227 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Scope = exports.WeakLifetime = exports.StaticLifetime = exports.Lifetime = void 0;
|
||||
const asyncify_helpers_1 = require("./asyncify-helpers");
|
||||
const debug_1 = require("./debug");
|
||||
const errors_1 = require("./errors");
|
||||
/**
|
||||
* A lifetime prevents access to a value after the lifetime has been
|
||||
* [[dispose]]ed.
|
||||
*
|
||||
* Typically, quickjs-emscripten uses Lifetimes to protect C memory pointers.
|
||||
*/
|
||||
class Lifetime {
|
||||
/**
|
||||
* When the Lifetime is disposed, it will call `disposer(_value)`. Use the
|
||||
* disposer function to implement whatever cleanup needs to happen at the end
|
||||
* of `value`'s lifetime.
|
||||
*
|
||||
* `_owner` is not used or controlled by the lifetime. It's just metadata for
|
||||
* the creator.
|
||||
*/
|
||||
constructor(_value, copier, disposer, _owner) {
|
||||
this._value = _value;
|
||||
this.copier = copier;
|
||||
this.disposer = disposer;
|
||||
this._owner = _owner;
|
||||
this._alive = true;
|
||||
this._constructorStack = debug_1.QTS_DEBUG ? new Error("Lifetime constructed").stack : undefined;
|
||||
}
|
||||
get alive() {
|
||||
return this._alive;
|
||||
}
|
||||
/**
|
||||
* The value this Lifetime protects. You must never retain the value - it
|
||||
* may become invalid, leading to memory errors.
|
||||
*
|
||||
* @throws If the lifetime has been [[dispose]]d already.
|
||||
*/
|
||||
get value() {
|
||||
this.assertAlive();
|
||||
return this._value;
|
||||
}
|
||||
get owner() {
|
||||
return this._owner;
|
||||
}
|
||||
get dupable() {
|
||||
return !!this.copier;
|
||||
}
|
||||
/**
|
||||
* Create a new handle pointing to the same [[value]].
|
||||
*/
|
||||
dup() {
|
||||
this.assertAlive();
|
||||
if (!this.copier) {
|
||||
throw new Error("Non-dupable lifetime");
|
||||
}
|
||||
return new Lifetime(this.copier(this._value), this.copier, this.disposer, this._owner);
|
||||
}
|
||||
consume(map) {
|
||||
this.assertAlive();
|
||||
const result = map(this);
|
||||
this.dispose();
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* Dispose of [[value]] and perform cleanup.
|
||||
*/
|
||||
dispose() {
|
||||
this.assertAlive();
|
||||
if (this.disposer) {
|
||||
this.disposer(this._value);
|
||||
}
|
||||
this._alive = false;
|
||||
}
|
||||
assertAlive() {
|
||||
if (!this.alive) {
|
||||
if (this._constructorStack) {
|
||||
throw new errors_1.QuickJSUseAfterFree(`Lifetime not alive\n${this._constructorStack}\nLifetime used`);
|
||||
}
|
||||
throw new errors_1.QuickJSUseAfterFree("Lifetime not alive");
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.Lifetime = Lifetime;
|
||||
/**
|
||||
* A Lifetime that lives forever. Used for constants.
|
||||
*/
|
||||
class StaticLifetime extends Lifetime {
|
||||
constructor(value, owner) {
|
||||
super(value, undefined, undefined, owner);
|
||||
}
|
||||
// Static lifetime doesn't need a copier to be copiable
|
||||
get dupable() {
|
||||
return true;
|
||||
}
|
||||
// Copy returns the same instance.
|
||||
dup() {
|
||||
return this;
|
||||
}
|
||||
// Dispose does nothing.
|
||||
dispose() { }
|
||||
}
|
||||
exports.StaticLifetime = StaticLifetime;
|
||||
/**
|
||||
* A Lifetime that does not own its `value`. A WeakLifetime never calls its
|
||||
* `disposer` function, but can be `dup`ed to produce regular lifetimes that
|
||||
* do.
|
||||
*
|
||||
* Used for function arguments.
|
||||
*/
|
||||
class WeakLifetime extends Lifetime {
|
||||
constructor(value, copier, disposer, owner) {
|
||||
// We don't care if the disposer doesn't support freeing T
|
||||
super(value, copier, disposer, owner);
|
||||
}
|
||||
dispose() {
|
||||
this._alive = false;
|
||||
}
|
||||
}
|
||||
exports.WeakLifetime = WeakLifetime;
|
||||
function scopeFinally(scope, blockError) {
|
||||
// console.log('scopeFinally', scope, blockError)
|
||||
let disposeError;
|
||||
try {
|
||||
scope.dispose();
|
||||
}
|
||||
catch (error) {
|
||||
disposeError = error;
|
||||
}
|
||||
if (blockError && disposeError) {
|
||||
Object.assign(blockError, {
|
||||
message: `${blockError.message}\n Then, failed to dispose scope: ${disposeError.message}`,
|
||||
disposeError,
|
||||
});
|
||||
throw blockError;
|
||||
}
|
||||
if (blockError || disposeError) {
|
||||
throw blockError || disposeError;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Scope helps reduce the burden of manually tracking and disposing of
|
||||
* Lifetimes. See [[withScope]]. and [[withScopeAsync]].
|
||||
*/
|
||||
class Scope {
|
||||
constructor() {
|
||||
this._disposables = new Lifetime(new Set());
|
||||
}
|
||||
/**
|
||||
* Run `block` with a new Scope instance that will be disposed after the block returns.
|
||||
* Inside `block`, call `scope.manage` on each lifetime you create to have the lifetime
|
||||
* automatically disposed after the block returns.
|
||||
*
|
||||
* @warning Do not use with async functions. Instead, use [[withScopeAsync]].
|
||||
*/
|
||||
static withScope(block) {
|
||||
const scope = new Scope();
|
||||
let blockError;
|
||||
try {
|
||||
return block(scope);
|
||||
}
|
||||
catch (error) {
|
||||
blockError = error;
|
||||
throw error;
|
||||
}
|
||||
finally {
|
||||
scopeFinally(scope, blockError);
|
||||
}
|
||||
}
|
||||
static withScopeMaybeAsync(_this, block) {
|
||||
return (0, asyncify_helpers_1.maybeAsync)(undefined, function* (awaited) {
|
||||
const scope = new Scope();
|
||||
let blockError;
|
||||
try {
|
||||
return yield* awaited.of(block.call(_this, awaited, scope));
|
||||
}
|
||||
catch (error) {
|
||||
blockError = error;
|
||||
throw error;
|
||||
}
|
||||
finally {
|
||||
scopeFinally(scope, blockError);
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Run `block` with a new Scope instance that will be disposed after the
|
||||
* block's returned promise settles. Inside `block`, call `scope.manage` on each
|
||||
* lifetime you create to have the lifetime automatically disposed after the
|
||||
* block returns.
|
||||
*/
|
||||
static async withScopeAsync(block) {
|
||||
const scope = new Scope();
|
||||
let blockError;
|
||||
try {
|
||||
return await block(scope);
|
||||
}
|
||||
catch (error) {
|
||||
blockError = error;
|
||||
throw error;
|
||||
}
|
||||
finally {
|
||||
scopeFinally(scope, blockError);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Track `lifetime` so that it is disposed when this scope is disposed.
|
||||
*/
|
||||
manage(lifetime) {
|
||||
this._disposables.value.add(lifetime);
|
||||
return lifetime;
|
||||
}
|
||||
get alive() {
|
||||
return this._disposables.alive;
|
||||
}
|
||||
dispose() {
|
||||
const lifetimes = Array.from(this._disposables.value.values()).reverse();
|
||||
for (const lifetime of lifetimes) {
|
||||
if (lifetime.alive) {
|
||||
lifetime.dispose();
|
||||
}
|
||||
}
|
||||
this._disposables.dispose();
|
||||
}
|
||||
}
|
||||
exports.Scope = Scope;
|
||||
//# sourceMappingURL=lifetime.js.map
|
||||
1
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/lifetime.js.map
generated
vendored
Normal file
1
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/lifetime.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
18
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/memory.d.ts
generated
vendored
Normal file
18
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/memory.d.ts
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
import { EitherModule } from "./emscripten-types";
|
||||
import { OwnedHeapCharPointer, JSContextPointerPointer, JSValueConstPointerPointer, JSValuePointerPointer } from "./types-ffi";
|
||||
import { Lifetime } from "./lifetime";
|
||||
import { QuickJSHandle } from "./types";
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
export declare class ModuleMemory {
|
||||
module: EitherModule;
|
||||
constructor(module: EitherModule);
|
||||
toPointerArray(handleArray: QuickJSHandle[]): Lifetime<JSValueConstPointerPointer>;
|
||||
newMutablePointerArray<T extends JSContextPointerPointer | JSValuePointerPointer>(length: number): Lifetime<{
|
||||
typedArray: Int32Array;
|
||||
ptr: T;
|
||||
}>;
|
||||
newHeapCharPointer(string: string): Lifetime<OwnedHeapCharPointer>;
|
||||
consumeHeapCharPointer(ptr: OwnedHeapCharPointer): string;
|
||||
}
|
||||
41
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/memory.js
generated
vendored
Normal file
41
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/memory.js
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ModuleMemory = void 0;
|
||||
const lifetime_1 = require("./lifetime");
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
class ModuleMemory {
|
||||
constructor(module) {
|
||||
this.module = module;
|
||||
}
|
||||
toPointerArray(handleArray) {
|
||||
const typedArray = new Int32Array(handleArray.map((handle) => handle.value));
|
||||
const numBytes = typedArray.length * typedArray.BYTES_PER_ELEMENT;
|
||||
const ptr = this.module._malloc(numBytes);
|
||||
var heapBytes = new Uint8Array(this.module.HEAPU8.buffer, ptr, numBytes);
|
||||
heapBytes.set(new Uint8Array(typedArray.buffer));
|
||||
return new lifetime_1.Lifetime(ptr, undefined, (ptr) => this.module._free(ptr));
|
||||
}
|
||||
newMutablePointerArray(length) {
|
||||
const zeros = new Int32Array(new Array(length).fill(0));
|
||||
const numBytes = zeros.length * zeros.BYTES_PER_ELEMENT;
|
||||
const ptr = this.module._malloc(numBytes);
|
||||
const typedArray = new Int32Array(this.module.HEAPU8.buffer, ptr, length);
|
||||
typedArray.set(zeros);
|
||||
return new lifetime_1.Lifetime({ typedArray, ptr }, undefined, (value) => this.module._free(value.ptr));
|
||||
}
|
||||
newHeapCharPointer(string) {
|
||||
const numBytes = this.module.lengthBytesUTF8(string) + 1;
|
||||
const ptr = this.module._malloc(numBytes);
|
||||
this.module.stringToUTF8(string, ptr, numBytes);
|
||||
return new lifetime_1.Lifetime(ptr, undefined, (value) => this.module._free(value));
|
||||
}
|
||||
consumeHeapCharPointer(ptr) {
|
||||
const str = this.module.UTF8ToString(ptr);
|
||||
this.module._free(ptr);
|
||||
return str;
|
||||
}
|
||||
}
|
||||
exports.ModuleMemory = ModuleMemory;
|
||||
//# sourceMappingURL=memory.js.map
|
||||
1
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/memory.js.map
generated
vendored
Normal file
1
ExACTRegressionScripts/node_modules/@tootallnate/quickjs-emscripten/dist/memory.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"memory.js","sourceRoot":"","sources":["../ts/memory.ts"],"names":[],"mappings":";;;AAOA,yCAAqC;AAGrC;;GAEG;AACH,MAAa,YAAY;IACvB,YAAmB,MAAoB;QAApB,WAAM,GAAN,MAAM,CAAc;IAAG,CAAC;IAE3C,cAAc,CAAC,WAA4B;QACzC,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;QAC5E,MAAM,QAAQ,GAAG,UAAU,CAAC,MAAM,GAAG,UAAU,CAAC,iBAAiB,CAAA;QACjE,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAA+B,CAAA;QACvE,IAAI,SAAS,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAA;QACxE,SAAS,CAAC,GAAG,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAA;QAChD,OAAO,IAAI,mBAAQ,CAAC,GAAG,EAAE,SAAS,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAA;IACtE,CAAC;IAED,sBAAsB,CACpB,MAAc;QAEd,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;QACvD,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,iBAAiB,CAAA;QACvD,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAM,CAAA;QAC9C,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,CAAA;QACzE,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QACrB,OAAO,IAAI,mBAAQ,CAAC,EAAE,UAAU,EAAE,GAAG,EAAE,EAAE,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAA;IAC9F,CAAC;IAED,kBAAkB,CAAC,MAAc;QAC/B,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QACxD,MAAM,GAAG,GAAyB,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAyB,CAAA;QACvF,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAA;QAC/C,OAAO,IAAI,mBAAQ,CAAC,GAAG,EAAE,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAA;IAC1E,CAAC;IAED,sBAAsB,CAAC,GAAyB;QAC9C,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAA;QACzC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QACtB,OAAO,GAAG,CAAA;IACZ,CAAC;CACF;AAnCD,oCAmCC","sourcesContent":["import { EitherModule } from \"./emscripten-types\"\nimport {\n OwnedHeapCharPointer,\n JSContextPointerPointer,\n JSValueConstPointerPointer,\n JSValuePointerPointer,\n} from \"./types-ffi\"\nimport { Lifetime } from \"./lifetime\"\nimport { EitherFFI, QuickJSHandle } from \"./types\"\n\n/**\n * @private\n */\nexport class ModuleMemory {\n constructor(public module: EitherModule) {}\n\n toPointerArray(handleArray: QuickJSHandle[]): Lifetime<JSValueConstPointerPointer> {\n const typedArray = new Int32Array(handleArray.map((handle) => handle.value))\n const numBytes = typedArray.length * typedArray.BYTES_PER_ELEMENT\n const ptr = this.module._malloc(numBytes) as JSValueConstPointerPointer\n var heapBytes = new Uint8Array(this.module.HEAPU8.buffer, ptr, numBytes)\n heapBytes.set(new Uint8Array(typedArray.buffer))\n return new Lifetime(ptr, undefined, (ptr) => this.module._free(ptr))\n }\n\n newMutablePointerArray<T extends JSContextPointerPointer | JSValuePointerPointer>(\n length: number\n ): Lifetime<{ typedArray: Int32Array; ptr: T }> {\n const zeros = new Int32Array(new Array(length).fill(0))\n const numBytes = zeros.length * zeros.BYTES_PER_ELEMENT\n const ptr = this.module._malloc(numBytes) as T\n const typedArray = new Int32Array(this.module.HEAPU8.buffer, ptr, length)\n typedArray.set(zeros)\n return new Lifetime({ typedArray, ptr }, undefined, (value) => this.module._free(value.ptr))\n }\n\n newHeapCharPointer(string: string): Lifetime<OwnedHeapCharPointer> {\n const numBytes = this.module.lengthBytesUTF8(string) + 1\n const ptr: OwnedHeapCharPointer = this.module._malloc(numBytes) as OwnedHeapCharPointer\n this.module.stringToUTF8(string, ptr, numBytes)\n return new Lifetime(ptr, undefined, (value) => this.module._free(value))\n }\n\n consumeHeapCharPointer(ptr: OwnedHeapCharPointer): string {\n const str = this.module.UTF8ToString(ptr)\n this.module._free(ptr)\n return str\n }\n}\n"]}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user