-
-
Notifications
You must be signed in to change notification settings - Fork 5
Standard Library
The DScript.Extras package provides a JavaScript-compatible standard library. Register it with:
new EngineFunctionLoader().RegisterFunctions(engine);
// or with permission restrictions:
new EngineFunctionLoader().RegisterFunctions(engine, EnginePermissions.FileSystem | EnginePermissions.Network);See Permissions for the full list of flags.
var buf = new ArrayBuffer(16); // 16 zero-initialised bytes
buf.byteLength; // → 16
var copy = buf.slice(4, 12); // new 8-byte ArrayBuffer
ArrayBuffer.isView(new Int32Array(buf)); // → trueAll eleven typed array types are available: Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array, BigInt64Array, BigUint64Array.
// From a length (zero-filled)
var a = new Float64Array(4);
a[0] = 1.5;
a[1] = 2.5;
a.length; // → 4
a.byteLength; // → 32
a.byteOffset; // → 0
a.BYTES_PER_ELEMENT; // → 8
Float64Array.BYTES_PER_ELEMENT; // → 8 (static)
// From an ArrayBuffer (shared storage)
var buf = new ArrayBuffer(16);
var f64 = new Float64Array(buf); // two elements
var i32 = new Int32Array(buf); // four elements — same bytes
f64[0] = 1.5;
// i32[0] and i32[1] now reflect the same bytes as f64[0]
// From an array-like
var b = new Int32Array([10, 20, 30]);
b[1]; // → 20
// From a typed array (copy)
var c = new Float64Array(a);
// Methods (shared by all typed array subtypes)
a.forEach(fn) // iterate with callback(value, index)
a.map(fn) // returns new TypedArray of same kind
a.filter(fn) // returns new TypedArray of same kind
a.find(fn) // first element where fn returns true
a.findIndex(fn) // index of first match, or -1
a.indexOf(val) // index of first exact match, or -1
a.includes(val) // true/false
a.every(fn) / a.some(fn)
a.reduce(fn, initial)
a.fill(value, start?, end?)
a.set(array, offset?) // copy from array or TypedArray
a.subarray(begin?, end?) // view into same buffer (no copy)
a.slice(begin?, end?) // copy into new TypedArray
a.join(sep?) // like Array.join
a.reverse() // in-place
a.copyWithin(target, start, end?)
a.keys() / a.values() / a.entries()Provides explicit endian-controlled access to an ArrayBuffer.
var buf = new ArrayBuffer(16);
var dv = new DataView(buf);
// or: new DataView(buf, byteOffset, byteLength)
dv.byteOffset; // → 0
dv.byteLength; // → 16
dv.buffer; // → the ArrayBuffer
// Readers — second arg is littleEndian (default false = big-endian)
dv.getInt8(0)
dv.getUint8(0)
dv.getInt16(0, true) // little-endian
dv.getUint16(0)
dv.getInt32(0, true)
dv.getUint32(0)
dv.getFloat32(0, true)
dv.getFloat64(0, true)
dv.getBigInt64(0)
dv.getBigUint64(0)
// Writers
dv.setInt8(0, 42)
dv.setUint8(0, 255)
dv.setInt16(0, -1, true)
dv.setUint16(0, 0xABCD)
dv.setInt32(0, 0x7FFFFFFF, true)
dv.setUint32(0, 0xDEADBEEF)
dv.setFloat32(0, 1.5, true)
dv.setFloat64(0, 3.14159, true)
dv.setBigInt64(0, 9007199254740992n)
dv.setBigUint64(0, 18446744073709551615n)Built into the engine (no DScript.Extras required).
// Constructor
var p = new Promise(function(resolve, reject) {
resolve(42); // or reject("reason")
});
// Static factory methods
Promise.resolve(42) // already-fulfilled Promise
Promise.reject("oops") // already-rejected Promise
Promise.all([p1, p2]) // resolves when all resolve; rejects on first rejection
Promise.allSettled([p1, p2]) // always resolves with [{status, value/reason}, …]
Promise.race([p1, p2]) // settles with whichever input settles first
Promise.any([p1, p2]) // resolves with first fulfillment; rejects (AggregateError) if all reject
// Instance methods
p.then(function(v) { /* fulfilled */ })
.catch(function(e) { /* rejected */ })
.finally(function() { /* runs on both paths; propagates original value/reason */ });Promise.any rejects with an AggregateError object when all inputs reject:
Promise.any([Promise.reject("a"), Promise.reject("b")])
.catch(function(e) {
e.name; // "AggregateError"
e.message; // "All promises were rejected"
e.errors; // ["a", "b"]
});Built into the engine (no DScript.Extras required).
// Create a symbol (each call returns a unique value)
var s = Symbol(); // anonymous symbol
var s2 = Symbol('label'); // symbol with description
// Symbols are unique even with the same description
Symbol('x') === Symbol('x') // false
// typeof
typeof Symbol() // "symbol"
// Global symbol registry
var s1 = Symbol.for('app.id'); // creates or retrieves from registry
var s2 = Symbol.for('app.id'); // same symbol
s1 === s2 // true
Symbol.keyFor(s1) // "app.id"
Symbol.keyFor(Symbol('x')) // undefined (not in registry)
// Symbol as a property key
var id = Symbol('id');
var obj = {};
obj[id] = 42;
obj[id]; // 42
// Well-known symbols
Symbol.iterator // used by for...of — define [Symbol.iterator]() to make objects iterable
Symbol.hasInstance // customise instanceof
Symbol.toPrimitive // customise type coercion
Symbol.toStringTag // customise Object.prototype.toString tagvar range = {};
range[Symbol.iterator] = function() {
var i = 0;
return {
next: function() {
if (i < 3) return { value: i++, done: false };
return { value: undefined, done: true };
}
};
};
for (var x of range) { /* x = 0, 1, 2 */ }var Even = {};
Even[Symbol.hasInstance] = function(n) { return n % 2 === 0; };
4 instanceof Even // true
3 instanceof Even // falseBuilt into the engine (no DScript.Extras required).
BigInt(value) is a factory function — do not use new BigInt() (throws TypeError).
// Literal syntax (suffix n)
var a = 42n;
var b = 0xDEADBEEFn;
// Factory — converts number, string, or boolean
BigInt(42); // 42n
BigInt("12345"); // 12345n
BigInt(true); // 1n
BigInt(false); // 0n
BigInt(42n); // 42n (identity)
// Arithmetic — both operands must be BigInt
10n + 20n // 30n
100n / 3n // 33n (truncated)
100n % 7n // 2n
-42n // negation
// Bitwise
0b1100n & 0b1010n // 8n
0b1100n | 0b1010n // 14n
0b1100n ^ 0b1010n // 6n
~5n // -6n
// Comparison
10n < 20n // true
42n === 42n // true
// typeof
typeof 42n // "bigint"
// Prototype methods (resolve on BigInt primitives)
(255n).toString() // "255"
(255n).toString(16) // "ff" — any radix 2..36
(35n).toString(36) // "z"
(42n).valueOf() // 42nRestrictions:
- Mixing BigInt with regular numbers throws
TypeError:1n + 1→ error - BigInt literals cannot have a decimal point or exponent:
1.5nis a syntax error
Built into the engine (no DScript.Extras required).
new Proxy(target, handler) wraps any object or function and intercepts fundamental operations via trap functions on the handler:
| Trap | Triggered by |
|---|---|
get(target, key, receiver) |
proxy.key, proxy[key]
|
set(target, key, value, receiver) |
proxy.key = v, proxy[key] = v
|
has(target, key) |
key in proxy |
deleteProperty(target, key) |
delete proxy.key |
apply(target, thisArg, argsList) |
proxy(…) (function proxy) |
construct(target, argsList, newTarget) |
new proxy(…) |
ownKeys(target) |
for (var k in proxy) |
// Log all property reads
var handler = {
get: function(target, key) {
console.log('get', key);
return target[key];
}
};
var proxy = new Proxy({ x: 1 }, handler);
proxy.x; // logs "get x", returns 1
// Virtualise properties that don't exist on the target
var virtual = new Proxy({}, {
get: function(target, key) { return key.length; }
});
virtual.hello; // 5
// Intercept function calls
var fnProxy = new Proxy(function(x) { return x; }, {
apply: function(target, thisArg, args) { return args[0] * 2; }
});
fnProxy(21); // 42Returns { proxy, revoke }. Calling revoke() permanently disables the proxy.
var r = Proxy.revocable({ x: 5 }, {});
var proxy = r.proxy;
proxy.x; // 5
r.revoke();
proxy.x; // undefined (target nulled)Built into the engine (no DScript.Extras required).
Reflect is a plain object that mirrors the fundamental object operations as named functions. All methods correspond to a Proxy trap of the same name.
// Reflect.apply(fn, thisArg, argsList)
Reflect.apply(Math.max, null, [1, 2, 3]); // 3
// Reflect.construct(ctor, argsList)
function Point(x, y) { this.x = x; this.y = y; }
var p = Reflect.construct(Point, [3, 4]);
p.x; // 3
// Reflect.get(target, key)
var obj = { a: 1 };
Reflect.get(obj, 'a'); // 1
// Reflect.set(target, key, value)
Reflect.set(obj, 'b', 2);
obj.b; // 2
// Reflect.has(target, key)
Reflect.has(obj, 'a'); // true
// Reflect.deleteProperty(target, key)
Reflect.deleteProperty(obj, 'a');
Reflect.has(obj, 'a'); // false
// Reflect.ownKeys(target) — own property names as array
Reflect.ownKeys({ x: 1, y: 2 }); // ["x", "y"]
// Reflect.defineProperty(target, key, descriptor)
Reflect.defineProperty(obj, 'z', { value: 99 });
obj.z; // 99
// Reflect.getOwnPropertyDescriptor(target, key)
Reflect.getOwnPropertyDescriptor(obj, 'z'); // { value: 99, writable: true, … }
// Reflect.getPrototypeOf / setPrototypeOf
var proto = { greet: function() { return 'hi'; } };
Reflect.setPrototypeOf(obj, proto);
Reflect.getPrototypeOf(obj) === proto; // true
// Reflect.isExtensible / preventExtensions
Reflect.isExtensible(obj); // true (DScript objects are always extensible)| Function | Description |
|---|---|
eval(str) |
Parse and execute a string as DScript code |
exec(str) |
Execute a statement string (alias of eval for statements) |
trace(val) |
Print a debug representation of any value |
parseInt(str, radix?) |
Parse an integer; radix defaults to 10 |
parseFloat(str) |
Parse a floating-point number |
isNaN(val) |
True if val is NaN |
isFinite(val) |
True if val is a finite number |
encodeURIComponent(str) |
Percent-encode a URI component |
decodeURIComponent(str) |
Decode a percent-encoded URI component |
encodeURI(str) |
Encode a full URI (preserves : / ? # …) |
decodeURI(str) |
Decode a full URI |
btoa(str) |
Base-64 encode a string |
atob(str) |
Base-64 decode a string |
charToInt(ch) |
Return the Unicode code point of the first character |
structuredClone(val) |
Deep-clone any value |
queueMicrotask(fn) |
Queue fn on the microtask queue |
Built into the engine (no DScript.Extras required). Backed by .NET globalization APIs.
Normalizes one or more BCP 47 locale tags and returns an array of canonical forms.
Intl.getCanonicalLocales('en-US'); // ["en-US"]
Intl.getCanonicalLocales(['en-gb', 'FR']); // ["en-GB", "fr"]Locale-aware string comparison. compare(a, b) returns a negative, zero, or positive integer.
var c = new Intl.Collator('sv');
['ö', 'a', 'z'].sort(c.compare); // locale-aware sort
c.resolvedOptions(); // { locale: "sv", usage: "sort", sensitivity: "variant" }Formats a number for a locale. Options: style ("decimal" | "percent" | "currency"), currency, minimumFractionDigits, maximumFractionDigits.
var nf = new Intl.NumberFormat('en-US', { style: 'decimal', minimumFractionDigits: 2 });
nf.format(1234.5); // locale-formatted string
nf.formatToParts(1234.5); // array of { type, value } parts
nf.resolvedOptions(); // { locale, style, minimumFractionDigits, maximumFractionDigits }Formats a Unix timestamp (milliseconds) for a locale. Options: dateStyle ("short" | "medium" | "long" | "full").
var dtf = new Intl.DateTimeFormat('en-US', { dateStyle: 'long' });
dtf.format(0); // "January 1, 1970"
dtf.formatToParts(0); // array of { type, value } parts
dtf.resolvedOptions(); // { locale, dateStyle }Returns display names for language codes, region codes, scripts, or currency codes. type: "language" | "region" | "script" | "currency".
var dn = new Intl.DisplayNames('en', { type: 'language' });
dn.of('fr'); // "French"
var regions = new Intl.DisplayNames('en', { type: 'region' });
regions.of('US'); // "United States"Returns the plural category for a number: "zero", "one", "two", "few", "many", or "other".
var pr = new Intl.PluralRules('en-US');
pr.select(1); // "one"
pr.select(2); // "other"
pr.resolvedOptions(); // { locale, type: "cardinal" }console.log / .error / .warn / .info / .debug are variadic — multiple
arguments are printed space-separated.
console.log("hello");
console.log("Checksum:", 12345); // "Checksum:" 12345
console.error("oops");
console.warn("careful");
console.info("fyi");
console.clear();
console.time("label");
// ... work ...
console.timeEnd("label"); // prints elapsed ms
console.timeLog("label"); // prints elapsed ms without stoppingRedirecting output from C# — set static delegates before registering:
ConsoleFunctionProvider.SetOutput(
stdout: msg => myLog.Info(msg),
stderr: msg => myLog.Error(msg)
);Math.abs(-5) // 5
Math.ceil(1.2) // 2
Math.floor(1.9) // 1
Math.round(1.5) // 2
Math.trunc(1.9) // 1
Math.sign(-3) // -1
Math.min(1, 2, 3) // 1
Math.max(1, 2, 3) // 3
Math.pow(2, 10) // 1024
Math.sqrt(16) // 4
Math.cbrt(27) // 3
Math.hypot(3, 4) // 5
Math.random() // float in [0,1)
Math.log(Math.E) // 1
Math.log2(8) // 3
Math.log10(1000) // 3
Math.sin(x) Math.cos(x) Math.tan(x)
Math.asin(x) Math.acos(x) Math.atan(x) Math.atan2(y, x)
Math.sinh(x) Math.cosh(x) Math.tanh(x)
Math.exp(x)
Math.clz32(x) // count leading zeros in 32-bit int
Math.fround(x) // nearest 32-bit float
Math.imul(a,b) // 32-bit integer multiplyConstants: Math.PI, Math.E, Math.SQRT2, Math.SQRT1_2, Math.LN2, Math.LN10, Math.LOG2E, Math.LOG10E
Instance methods are available on all string values.
var s = "Hello, World!";
s.length // 13
s.charAt(0) // "H"
s.charCodeAt(0) // 72
s.codePointAt(0) // 72
s.indexOf("o") // 4
s.lastIndexOf("o") // 8
s.includes("World") // true
s.startsWith("Hello") // true
s.endsWith("!") // true
s.slice(7, 12) // "World"
s.substring(7, 12) // "World"
s.toUpperCase() // "HELLO, WORLD!"
s.toLowerCase() // "hello, world!"
s.trim() // strips whitespace
s.trimStart() // strips leading whitespace
s.trimEnd() // strips trailing whitespace
s.split(", ") // ["Hello", "World!"]
s.replace("World", "DScript") // "Hello, DScript!"
s.replaceAll("l", "L") // "HeLLo, WorLd!"
s.repeat(2) // "Hello, World!Hello, World!"
s.padStart(15, "*") // "**Hello, World!"
s.padEnd(15, "-") // "Hello, World!--"
s.concat(" ", "More") // "Hello, World! More"
s.match(/\w+/g) // ["Hello", "World"]
s.matchAll(/(\w+)/g) // iterator of match arrays
s.normalize("NFC") // Unicode normalization
s.at(-1) // "!"
String.fromCharCode(72, 101, 108) // "Hel"
String.fromCodePoint(128512) // emoji 😀
String.raw`C:\Users\alice` // "C:\\Users\\alice" — no escape processingInstance methods are available on all array values.
var a = [3, 1, 4, 1, 5];
// Mutating
a.push(9) // append; returns new length
a.pop() // remove last; returns element
a.shift() // remove first; returns element
a.unshift(0) // prepend; returns new length
a.splice(1, 2) // remove 2 at index 1; returns removed
a.splice(1, 0, 99) // insert 99 at index 1
a.reverse() // in-place reverse
a.sort() // in-place sort (lexicographic by default)
a.sort((a,b) => a - b) // with comparator
a.fill(0, 2, 4) // fill indices 2..3 with 0
a.copyWithin(0, 2) // copy from index 2 to start
// Non-mutating
a.slice(1, 3) // copy of indices 1..2
a.concat([6, 7]) // new array
a.join(", ") // "3, 1, 4, 1, 5"
a.indexOf(1) // 1
a.lastIndexOf(1) // 3
a.includes(4) // true
a.find(x => x > 3) // 4
a.findIndex(x => x > 3) // 2
a.every(x => x > 0) // true
a.some(x => x > 4) // true
a.flat() // flatten one level
a.flat(Infinity) // flatten all levels
a.at(-1) // last element
// Higher-order
a.map(x => x * 2)
a.filter(x => x > 2)
a.forEach(x => console.log(x))
a.reduce((acc, x) => acc + x, 0)
a.reduceRight((acc, x) => acc + x, 0)
a.flatMap(x => [x, x * 2])
// Immutable copies (ES2023)
a.toSorted() // sorted copy
a.toReversed() // reversed copy
a.toSpliced(1, 1) // splice copy
a.with(2, 99) // copy with index 2 replaced
// Iteration
a.keys() // index iterator
a.values() // value iterator
a.entries() // [index, value] iterator
// Static
Array.isArray(a) // true
Array.from("abc") // ["a","b","c"]
Array.of(1, 2, 3) // [1,2,3]Function.prototype methods are available on all function values.
function greet() { return this.name; }
var obj = { name: 'Alice' };
// call — invoke with explicit this and individual args
greet.call(obj); // "Alice"
Math.max.call(null, 1, 5, 3); // 5
// apply — invoke with explicit this and args as array
greet.apply(obj); // "Alice"
Math.max.apply(null, [1, 5, 3]); // 5
// bind — return a new function with fixed this (and optional partial args)
var boundGreet = greet.bind(obj);
boundGreet(); // "Alice"
function add(a, b) { return a + b; }
var add10 = add.bind(null, 10);
add10(5); // 15
add10.name; // "bound add"
add10.length; // 1 (original 2 minus 1 partial arg)
// Chained bind — first this wins
var boundOnce = greet.bind({ name: 'First' });
boundOnce.bind({ name: 'Second' })(); // "First"var obj = { a: 1, b: 2, c: 3 };
// Enumeration (respects enumerable descriptor)
Object.keys(obj) // ["a","b","c"]
Object.values(obj) // [1,2,3]
Object.entries(obj) // [["a",1],["b",2],["c",3]]
Object.fromEntries([["a",1]]) // { a: 1 }
Object.getOwnPropertyNames(obj) // all own keys regardless of enumerable
// Composition / prototype
Object.assign({}, obj, { d: 4 }) // shallow merge
Object.create(proto) // new object with prototype
Object.getPrototypeOf(obj) // the prototype object or undefined
Object.setPrototypeOf(obj, proto) // replace prototype chain
// Property descriptors (ES5)
Object.defineProperty(obj, 'x', {
value: 1, writable: false, enumerable: true, configurable: false
});
Object.defineProperty(obj, 'y', {
get() { return this._y; },
set(v) { this._y = v; }
});
Object.defineProperties(obj, {
a: { value: 1, writable: true },
b: { value: 2, enumerable: false }
});
Object.getOwnPropertyDescriptor(obj, 'x') // { value:1, writable:false, … }
Object.getOwnPropertyDescriptors(obj) // map of all own descriptors
// Integrity
Object.freeze(obj) // prevent all mutation and extension
Object.isFrozen(obj) // true/false
Object.seal(obj) // prevent add/delete but allow value writes
Object.isSealed(obj) // true/false
Object.preventExtensions(obj) // prevent new properties
Object.isExtensible(obj) // true/false
// Identity / misc
Object.hasOwn(obj, "a") // true (ES2022)
Object.is(NaN, NaN) // true (handles NaN and -0 correctly)
Object.groupBy(arr, fn) // group array items into an object by key
obj.hasOwnProperty("a") // trueNumber.isInteger(42) // true
Number.isFinite(1/0) // false
Number.isNaN(NaN) // true
Number.isSafeInteger(2**53) // false
Number.parseInt("42px") // 42
Number.parseFloat("3.14x") // 3.14
(3.14159).toFixed(2) // "3.14"
(3.14159).toPrecision(4) // "3.142"
(255).toString(16) // "ff"
(1234).toExponential(2) // "1.23e+3"Constants: Number.MAX_VALUE, Number.MIN_VALUE, Number.MAX_SAFE_INTEGER, Number.MIN_SAFE_INTEGER, Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY, Number.NaN, Number.EPSILON
var obj = JSON.parse('{"a":1,"b":[2,3]}');
var json = JSON.stringify(obj); // '{"a":1,"b":[2,3]}'
var pretty = JSON.stringify(obj, null, 2); // indentedvar m = new Map();
m.set("key", 42);
m.get("key"); // 42
m.has("key"); // true
m.delete("key");
m.size; // 0
m.clear();
m.forEach((v, k) => console.log(k, v));
m.keys(); m.values(); m.entries();
// ES2024 groupBy
var grouped = Map.groupBy([1,2,3,4], x => x % 2 === 0 ? "even" : "odd");var s = new Set([1, 2, 3, 2, 1]);
s.size; // 3
s.has(2); // true
s.add(4);
s.delete(1);
s.clear();
s.forEach(v => console.log(v));
s.keys(); s.values(); s.entries();Object-keyed map that does not prevent garbage collection of its keys (in DScript, keys are always live — the weak semantics are preserved structurally).
var wm = new WeakMap();
var key = {};
wm.set(key, "value");
wm.get(key); // "value"
wm.has(key); // true
wm.delete(key); // true| Method | Description |
|---|---|
get(key) |
Returns the value for key, or undefined
|
set(key, val) |
Sets the value; returns the WeakMap |
has(key) |
Returns true if key is present |
delete(key) |
Removes the entry; returns true if found |
Object-keyed set that does not prevent garbage collection of its members.
var ws = new WeakSet();
var obj = {};
ws.add(obj);
ws.has(obj); // true
ws.delete(obj); // true
ws.has(obj); // false| Method | Description |
|---|---|
add(obj) |
Adds the object; returns the WeakSet |
has(obj) |
Returns true if obj is a member |
delete(obj) |
Removes the member; returns true if found |
Holds a weak reference to an object. In DScript's GC-less engine, deref() always returns the original target.
var target = { x: 1 };
var ref = new WeakRef(target);
ref.deref(); // the original target object
ref.deref().x; // 1| Method | Description |
|---|---|
deref() |
Returns the referenced object (always live in DScript) |
// Constructors
new Date() // current time
new Date(1704067200000) // from Unix ms
new Date('2024-01-01T00:00:00Z') // from ISO-8601 string
new Date(2024, 0, 15) // local: year, month (0-based), day, …
new Date('bad') // invalid date — getTime() returns NaN
// Static methods
Date.now() // current Unix ms
Date.parse('2024-01-01T00:00:00Z') // parse string → ms, or NaN
Date.UTC(2024, 0, 1) // UTC ms for year/month/day/…
// Get (local)
d.getFullYear() d.getMonth() d.getDate() d.getDay()
d.getHours() d.getMinutes() d.getSeconds() d.getMilliseconds()
d.getTime() d.valueOf() d.getTimezoneOffset()
// Get (UTC)
d.getUTCFullYear() d.getUTCMonth() d.getUTCDate() d.getUTCDay()
d.getUTCHours() d.getUTCMinutes() d.getUTCSeconds() d.getUTCMilliseconds()
// Set (local)
d.setTime(ms)
d.setFullYear(y) d.setMonth(m) d.setDate(day)
d.setHours(h) d.setMinutes(m) d.setSeconds(s) d.setMilliseconds(ms)
// Formatting
d.toISOString() // "2024-01-15T00:00:00.000Z"
d.toJSON() // same as toISOString()
d.toUTCString() d.toString()
d.toDateString() d.toTimeString()
d.toLocaleDateString() d.toLocaleTimeString() d.toLocaleString()var re = new RegExp("(\\d+)", "g");
re.test("abc123"); // true
re.exec("abc123"); // ["123","123"]
re.source // "(\\d+)"
re.flags // "g"
re.global // true
re.ignoreCase // false
re.multiline // falseError, TypeError, RangeError, ReferenceError, SyntaxError, URIError, EvalError, and AggregateError are all constructable. Each can be called with or without new.
var e = new TypeError("bad type");
e.name; // "TypeError"
e.message; // "bad type"
e.stack; // "TypeError: bad type"
e instanceof TypeError; // true
e instanceof Error; // true
// Subtype hierarchy
new RangeError("x") instanceof Error; // true
new ReferenceError("x") instanceof Error; // true
new SyntaxError("x") instanceof Error; // true
// Error.cause (ES2022)
var cause = new Error("root");
var wrapped = new Error("outer", { cause: cause });
wrapped.cause === cause; // trueBinary data backed by a byte[].
// Creating
var b1 = Buffer.from("hello", "utf8");
var b2 = Buffer.from([72, 101, 108, 108, 111]);
var b3 = Buffer.alloc(10); // zeroed
var b4 = Buffer.allocUnsafe(10); // uninitialized
// Checking
Buffer.isBuffer(b1); // true
// Reading
b1.length; // 5
b1.toString("utf8"); // "hello"
b1.toString("hex"); // "68656c6c6f"
b1.toString("base64"); // "aGVsbG8="
b1.readUInt8(0); // 72
// Modifying
b3.writeUInt8(255, 0);
// Operations
Buffer.concat([b1, b2]);
b1.slice(1, 3);
b1.copy(b3, 0); // copy b1 into b3 starting at offset 0
b1.equals(b2); // falsevar emitter = new EventEmitter();
emitter.on("data", function(chunk) {
console.log("received:", chunk);
});
emitter.once("end", function() {
console.log("stream ended");
});
emitter.emit("data", "hello");
emitter.emit("end");
emitter.listeners("data"); // array of listeners
emitter.listenerCount("data"); // 0 (once fired and removed)
emitter.removeAllListeners("data");
emitter.off("data", myHandler);EventEmitter.defaultMaxListeners (default 10) — a warning is printed when exceeded.
var id = setTimeout(function() {
console.log("fired after 100ms");
}, 100);
clearTimeout(id);
var interval = setInterval(function() {
console.log("tick");
}, 1000);
clearInterval(interval);Timers do not fire automatically — the host must call engine.DrainTimers() periodically:
engine.Run(program);
while (engine.HasPendingTimers)
{
Thread.Sleep(10);
engine.DrainTimers();
}process.platform // "win32", "linux", "darwin", …
process.version // engine version string
process.argv // array of command-line arguments
process.env // object of environment variables
process.getenv("PATH") // read one environment variable
process.cwd() // current working directory
process.exit(0) // exit with code
// Lifecycle hooks
process.on("exit", function(code) {
console.log("exiting with", code);
});
process.on("uncaughtException", function(err) {
console.error("unhandled error:", err.message);
});
process.on("unhandledRejection", function(reason) {
console.error("unhandled rejection:", reason);
});Reading process.env and calling process.exit require the appropriate EnginePermissions flags.
assert(value, "message"); // alias of assert.ok
assert.ok(value, "msg"); // throws if falsy
assert.equal(a, b, "msg"); // == comparison
assert.strictEqual(a, b, "msg"); // === comparison
assert.notEqual(a, b);
assert.notStrictEqual(a, b);
assert.deepEqual(a, b); // recursive value equality
assert.throws(fn, errorMatcher?); // asserts fn throws
assert.doesNotThrow(fn);
assert.fail("forced failure");util.format("%s is %d years old", "Alice", 30);
// "Alice is 30 years old"
// Placeholders: %s (string), %d/%i (int), %f (float), %o (inspect), %j (JSON)
util.inspect({ a: 1, b: [2, 3] });
// "{ a: 1, b: [ 2, 3 ] }"
var readFileAsync = util.promisify(fs.readFile);
readFileAsync("data.txt").then(contents => console.log(contents));
var oldFn = util.deprecate(function() {}, "use newFn instead");
oldFn(); // prints deprecation warning on first callpath.join("a", "b", "c.txt") // "a/b/c.txt" (or "a\b\c.txt" on Windows)
path.resolve(".", "src", "app") // absolute path
path.dirname("/foo/bar/baz.txt") // "/foo/bar"
path.basename("/foo/bar/baz.txt") // "baz.txt"
path.basename("/foo/bar/baz.txt", ".txt") // "baz"
path.extname("baz.txt") // ".txt"
path.isAbsolute("/foo") // true
path.normalize("/foo//bar/../baz") // "/foo/baz"
path.sep // "/" or "\\"os.hostname() // "mypc"
os.platform() // "linux" / "win32" / "darwin"
os.arch() // "x64" / "arm64"
os.homedir() // "/home/user"
os.tmpdir() // "/tmp"
os.totalmem() // total RAM in bytes
os.freemem() // free RAM in bytes
os.cpus() // number of logical CPUs
os.EOL // "\n" or "\r\n"All methods are synchronous. Requires EnginePermissions.FileSystem.
fs.readFileSync("file.txt") // string (UTF-8)
fs.readFileSync("file.bin", "binary") // binary string
fs.writeFileSync("out.txt", "hello")
fs.appendFileSync("log.txt", "line\n")
fs.existsSync("file.txt") // true/false
fs.mkdirSync("new/dir", { recursive: true })
fs.rmdirSync("old/dir")
fs.unlinkSync("file.txt")
fs.readdirSync(".") // array of entry names
fs.renameSync("old.txt", "new.txt")
fs.copyFileSync("src.txt", "dst.txt")
var stat = fs.statSync("file.txt");
stat.size // bytes
stat.isFile() // true/false
stat.isDirectory() // true/false
stat.mtime // last-modified timestampcrypto.randomUUID() // "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx"
crypto.randomBytes(16) // Buffer of 16 random bytes
crypto.getRandomValues(arr) // fills a script array with random ints
var hash = crypto.createHash("sha256");
hash.update("hello");
hash.digest("hex"); // "2cf24dba…"
hash.digest("base64"); // base64-encoded
hash.digest(); // Buffer
var hmac = crypto.createHmac("sha256", "secret");
hmac.update("message");
hmac.digest("hex");Supported algorithms: sha256, sha512, sha1, md5.
Synchronous HTTP client. Requires EnginePermissions.Network.
var res = fetch("https://api.example.com/data");
// or
var res = fetch("https://api.example.com/data", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ key: "value" })
});
res.ok; // true if status 200–299
res.status; // 200
res.statusText; // "OK"
res.headers; // object of response headers
res.text(); // response body as string
res.json(); // parsed JSON object
res.arrayBuffer(); // BufferHTTP server. Requires EnginePermissions.Network.
var server = http.createServer(function(req, res) {
console.log(req.method, req.url);
req.on("data", function(chunk) { /* request body */ });
req.on("end", function() {
res.writeHead(200, { "Content-Type": "text/plain" });
res.end("Hello, World!");
});
server.close(); // stop after one request
});
server.listen(8080, "localhost", function() {
console.log("listening on port 8080");
});server.listen blocks until server.close() is called.
Requires EnginePermissions.ProcessSpawn.
// Synchronous — blocks until done
var out = child_process.execSync("echo hello"); // stdout string
// throws ScriptException on non-zero exit
var result = child_process.spawnSync("node", ["-e", "console.log(1)"]);
result.stdout // string
result.stderr // string
result.status // exit code (int)
result.signal // null or "SIGTERM"
// Async (callback style)
child_process.exec("echo hello", function(err, stdout, stderr) {
if (err) { console.error(err); return; }
console.log(stdout);
});
// Spawn — returns process object
var proc = child_process.spawn("node", ["-e", "console.log('hi')"]);
proc.on("exit", function(code) { console.log("exited:", code); });
proc.on("data", function(chunk) { console.log("stdout:", chunk); });
proc.pid; // process IDvar rl = readline.createInterface({
input: process.stdin, // or any Readable with a TextReader via SetData
output: process.stdout
});
rl.question("What is your name? ", function(answer) {
console.log("Hello,", answer);
rl.close();
});
rl.on("line", function(line) { console.log("got:", line); });
rl.on("close", function() { console.log("closed"); });TCP networking. Requires EnginePermissions.Network.
// TCP server
var server = net.createServer(function(socket) {
var data = socket.read();
socket.write("echo: " + data);
socket.end();
server.close();
});
server.listen(9000, "127.0.0.1", function() {
console.log("listening");
});
server.on("connection", function(socket) { /* alternative handler */ });
// TCP client
var sock = net.createConnection(9000, "127.0.0.1", function() {
console.log("connected");
});
sock.write("hello");
sock.read(); // returns available data (non-blocking)
sock.end();
sock.on("data", function(chunk) { });
sock.on("close", function() { });
sock.on("connect", function() { });
sock.remoteAddress; // "127.0.0.1"
sock.remotePort; // 9000// Readable
var r = new stream.Readable();
r.on("data", function(chunk) { console.log("chunk:", chunk); });
r.on("end", function() { console.log("done"); });
r.push("hello ");
r.push("world");
r.push(null); // signals end of stream
r.read(); // returns and clears the internal buffer
// Writable
var w = new stream.Writable();
w.on("finish", function() { console.log("finished"); });
w.write("foo");
w.end("bar");
w.getBuffer(); // "foobar" — returns accumulated content (non-Node API)
// Pipe
r.pipe(w); // writes all buffered Readable data into Writable then calls end()
// Transform (combined Readable + Writable)
var t = new stream.Transform();
t.on("data", function(chunk) { /* receive transformed output */ });
t.write("input");
t.end();var compressed = zlib.gzipSync("hello world"); // Buffer
var decompressed = zlib.gunzipSync(compressed); // Buffer
decompressed.toString("utf8"); // "hello world"
var deflated = zlib.deflateSync("hello");
var inflated = zlib.inflateSync(deflated);
inflated.toString("utf8"); // "hello"Input can be a Buffer or a plain string (treated as UTF-8). All methods are synchronous.
var u = new URL("https://user:pass@example.com:8080/path?a=1&b=2#frag");
u.href // full URL string
u.protocol // "https:"
u.host // "example.com:8080"
u.hostname // "example.com"
u.port // "8080"
u.pathname // "/path"
u.search // "?a=1&b=2"
u.hash // "#frag"
u.origin // "https://example.com:8080"
u.username // "user"
u.password // "pass"
u.toString() // same as href
u.searchParams.get("a") // "1"
u.searchParams.getAll("a") // ["1"]
u.searchParams.has("b") // true
u.searchParams.set("a", "99")
u.searchParams.append("c", "3")
u.searchParams.delete("b")
u.searchParams.toString() // "a=99&c=3"
// Relative URL
var rel = new URL("/other", "https://example.com");
rel.href; // "https://example.com/other"
// Standalone URLSearchParams
var sp = new URLSearchParams("x=1&y=2");
sp.set("x", "hello");
sp.toString(); // "x=hello&y=2"var enc = new TextEncoder();
enc.encoding; // "utf-8"
var buf = enc.encode("hello 😀"); // Buffer
var dec = new TextDecoder(); // defaults to "utf-8"
dec.decode(buf); // "hello 😀"
var decLatin = new TextDecoder("latin1");
decLatin.encoding; // "latin1"
decLatin.decode(buf); // (Latin-1 decoded string)Supported encodings: utf-8 (default), ascii, latin1 / iso-8859-1 / binary.