quickjs-emscripten
Advanced tools
Comparing version 0.4.1 to 0.5.0
@@ -80,2 +80,4 @@ import { QuickJSEmscriptenModule } from "./emscripten-types"; | ||
QTS_GetString: (ctx: JSContextPointer, value: JSValuePointer | JSValueConstPointer) => string; | ||
QTS_IsJobPending: (rt: JSRuntimePointer) => number; | ||
QTS_ExecutePendingJob: (rt: JSRuntimePointer, maxJobsToExecute: number) => JSValuePointer; | ||
QTS_GetProp: (ctx: JSContextPointer, this_val: JSValuePointer | JSValueConstPointer, prop_name: JSValuePointer | JSValueConstPointer) => JSValuePointer; | ||
@@ -82,0 +84,0 @@ QTS_SetProp: (ctx: JSContextPointer, this_val: JSValuePointer | JSValueConstPointer, prop_name: JSValuePointer | JSValueConstPointer, prop_value: JSValuePointer | JSValueConstPointer) => void; |
@@ -38,2 +38,4 @@ "use strict"; | ||
this.QTS_GetString = this.module.cwrap("QTS_GetString", "string", ["number", "number"]); | ||
this.QTS_IsJobPending = this.module.cwrap("QTS_IsJobPending", "number", ["number"]); | ||
this.QTS_ExecutePendingJob = this.module.cwrap("QTS_ExecutePendingJob", "number", ["number", "number"]); | ||
this.QTS_GetProp = this.module.cwrap("QTS_GetProp", "number", ["number", "number", "number"]); | ||
@@ -40,0 +42,0 @@ this.QTS_SetProp = this.module.cwrap("QTS_SetProp", null, ["number", "number", "number", "number"]); |
import { QuickJSFFI, JSContextPointer, JSValuePointer, JSRuntimePointer, JSValueConstPointer } from './ffi'; | ||
import { LowLevelJavascriptVm, VmPropertyDescriptor, VmCallResult, VmFunctionImplementation } from './vm-interface'; | ||
import { LowLevelJavascriptVm, VmPropertyDescriptor, VmCallResult, VmFunctionImplementation, SuccessOrFail } from './vm-interface'; | ||
import { QuickJSEmscriptenModule } from './emscripten-types'; | ||
@@ -60,2 +60,9 @@ /** | ||
/** | ||
* Used as an optional for the results of executing pendingJobs. | ||
* On success, `value` contains the number of async jobs executed | ||
* by the runtime. | ||
* `{ value: number } | { error: QuickJSHandle }`. | ||
*/ | ||
export declare type ExecutePendingJobsResult = SuccessOrFail<number, QuickJSHandle>; | ||
/** | ||
* QuickJSVm wraps a QuickJS Javascript runtime (JSRuntime*) and context (JSContext*). | ||
@@ -76,2 +83,5 @@ * This class's methods return {@link QuickJSHandle}, which wrap C pointers (JSValue*). | ||
* 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 QuickJSVm, you may need to also call [[executePendingJobs]]. | ||
*/ | ||
@@ -205,2 +215,4 @@ export declare class QuickJSVm implements LowLevelJavascriptVm<QuickJSHandle> { | ||
* Evauatetes 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. | ||
* | ||
@@ -214,2 +226,3 @@ * See [[unwrapResult]], which will throw if the function returned an error, or | ||
* | ||
* | ||
* @returns The last statement's value. If the code threw, result `error` will be | ||
@@ -221,2 +234,24 @@ * a handle to the exception. If execution was interrupted, the error will | ||
/** | ||
* Execute pendingJobs on the VM until `maxJobsToExecute` jobs are executed | ||
* (default all pendingJobs), the queue is exhausted, or the runtime | ||
* encounters an exception. | ||
* | ||
* In QuickJS, promises and async functions create pendingJobs. These do not execute | ||
* immediately and need to triggered to run. | ||
* | ||
* @param maxJobsToExecute - When negative, run all pending jobs. Otherwise execute | ||
* at most `maxJobsToExecute` before returning. | ||
* | ||
* @return On success, the number of executed jobs. On error, the exception | ||
* that stopped execution. | ||
*/ | ||
executePendingJobs(maxJobsToExecute?: number): ExecutePendingJobsResult; | ||
/** | ||
* In QuickJS, promises and async functions create pendingJobs. These do not execute | ||
* immediately and need to be run by calling [[executePendingJobs]]. | ||
* | ||
* @return true if there is at least one pendingJob queued up. | ||
*/ | ||
hasPendingJob(): boolean; | ||
/** | ||
* Dump a JSValue to Javascript in a best-effort fashion. | ||
@@ -227,6 +262,8 @@ * Returns `handle.toString()` if it cannot be serialized to JSON. | ||
/** | ||
* Unwrap a VmCallResult, returning it's value on success, and throwing the dumped | ||
* error on failure. | ||
* 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: VmCallResult<QuickJSHandle>): QuickJSHandle; | ||
unwrapResult<T>(result: SuccessOrFail<T, QuickJSHandle>): T; | ||
private interruptHandler; | ||
@@ -352,2 +389,5 @@ /** | ||
* | ||
* Asynchronous callbacks may not run during the first call to `evalCode`. If you need to | ||
* work with async code inside QuickJS, you should create a VM and use [[QuickJSVm.executePendingJobs]]. | ||
* | ||
* @returns The result is coerced to a native Javascript value using JSON | ||
@@ -378,2 +418,8 @@ * serialization, so properties and values unsupported by JSON will be dropped. | ||
export declare function getQuickJS(): Promise<QuickJS>; | ||
/** | ||
* Provides synchronous access to the QuickJS API once [[getQuickJS]] has resolved at | ||
* least once. | ||
* @throws If called before `getQuickJS` resolves. | ||
*/ | ||
export declare function getQuickJSSync(): QuickJS; | ||
export {}; |
@@ -170,2 +170,5 @@ "use strict"; | ||
* 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 QuickJSVm, you may need to also call [[executePendingJobs]]. | ||
*/ | ||
@@ -505,2 +508,4 @@ var QuickJSVm = /** @class */ (function () { | ||
* Evauatetes 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. | ||
* | ||
@@ -514,2 +519,3 @@ * See [[unwrapResult]], which will throw if the function returned an error, or | ||
* | ||
* | ||
* @returns The last statement's value. If the code threw, result `error` will be | ||
@@ -528,2 +534,38 @@ * a handle to the exception. If execution was interrupted, the error will | ||
}; | ||
/** | ||
* Execute pendingJobs on the VM until `maxJobsToExecute` jobs are executed | ||
* (default all pendingJobs), the queue is exhausted, or the runtime | ||
* encounters an exception. | ||
* | ||
* In QuickJS, promises and async functions create pendingJobs. These do not execute | ||
* immediately and need to triggered to run. | ||
* | ||
* @param maxJobsToExecute - When negative, run all pending jobs. Otherwise execute | ||
* at most `maxJobsToExecute` before returning. | ||
* | ||
* @return On success, the number of executed jobs. On error, the exception | ||
* that stopped execution. | ||
*/ | ||
QuickJSVm.prototype.executePendingJobs = function (maxJobsToExecute) { | ||
if (maxJobsToExecute === void 0) { maxJobsToExecute = -1; } | ||
var resultValue = this.heapValueHandle(this.ffi.QTS_ExecutePendingJob(this.rt.value, maxJobsToExecute)); | ||
var typeOfRet = this.typeof(resultValue); | ||
if (typeOfRet === 'number') { | ||
var executedJobs = this.getNumber(resultValue); | ||
resultValue.dispose(); | ||
return { value: executedJobs }; | ||
} | ||
else { | ||
return { error: resultValue }; | ||
} | ||
}; | ||
/** | ||
* In QuickJS, promises and async functions create pendingJobs. These do not execute | ||
* immediately and need to be run by calling [[executePendingJobs]]. | ||
* | ||
* @return true if there is at least one pendingJob queued up. | ||
*/ | ||
QuickJSVm.prototype.hasPendingJob = function () { | ||
return Boolean(this.ffi.QTS_IsJobPending(this.rt.value)); | ||
}; | ||
// customizations | ||
@@ -555,4 +597,6 @@ /** | ||
/** | ||
* Unwrap a VmCallResult, returning it's value on success, and throwing the dumped | ||
* error on failure. | ||
* 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. | ||
*/ | ||
@@ -776,2 +820,5 @@ QuickJSVm.prototype.unwrapResult = function (result) { | ||
* | ||
* Asynchronous callbacks may not run during the first call to `evalCode`. If you need to | ||
* work with async code inside QuickJS, you should create a VM and use [[QuickJSVm.executePendingJobs]]. | ||
* | ||
* @returns The result is coerced to a native Javascript value using JSON | ||
@@ -841,2 +888,14 @@ * serialization, so properties and values unsupported by JSON will be dropped. | ||
exports.getQuickJS = getQuickJS; | ||
/** | ||
* Provides synchronous access to the QuickJS API once [[getQuickJS]] has resolved at | ||
* 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; | ||
//# sourceMappingURL=quickjs.js.map |
@@ -271,2 +271,32 @@ "use strict"; | ||
}); | ||
mocha_1.describe('.executePendingJobs', function () { | ||
mocha_1.it('runs pending jobs', function () { | ||
var i = 0; | ||
var fnHandle = vm.newFunction('nextId', function () { | ||
return vm.newNumber(++i); | ||
}); | ||
vm.setProp(vm.global, 'nextId', fnHandle); | ||
fnHandle.dispose(); | ||
var result = vm.unwrapResult(vm.evalCode("(new Promise(resolve => resolve())).then(nextId).then(nextId).then(nextId);1")); | ||
assert_1.default.equal(i, 0); | ||
vm.executePendingJobs(); | ||
assert_1.default.equal(i, 3); | ||
assert_1.default.equal(vm.getNumber(result), 1); | ||
}); | ||
}); | ||
mocha_1.describe('.hasPendingJob', function () { | ||
mocha_1.it('returns true when job pending', function () { | ||
var i = 0; | ||
var fnHandle = vm.newFunction('nextId', function () { | ||
return vm.newNumber(++i); | ||
}); | ||
vm.setProp(vm.global, 'nextId', fnHandle); | ||
fnHandle.dispose(); | ||
vm.unwrapResult(vm.evalCode("(new Promise(resolve => resolve(5)).then(nextId));1")).dispose(); | ||
assert_1.default.strictEqual(vm.hasPendingJob(), true, 'has a pending job after creating a promise'); | ||
var executed = vm.unwrapResult(vm.executePendingJobs()); | ||
assert_1.default.strictEqual(executed, 1, 'executed exactly 1 job'); | ||
assert_1.default.strictEqual(vm.hasPendingJob(), false, 'no longer any jobs after execution'); | ||
}); | ||
}); | ||
mocha_1.describe('.dump', function () { | ||
@@ -273,0 +303,0 @@ function dumpTestExample(val) { |
{ | ||
"name": "quickjs-emscripten", | ||
"version": "0.4.1", | ||
"version": "0.5.0", | ||
"main": "dist/quickjs.js", | ||
@@ -5,0 +5,0 @@ "license": "MIT", |
@@ -44,2 +44,5 @@ # quickjs-emscripten | ||
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 | ||
@@ -46,0 +49,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
1125146
6067
173