Global API

Everything in this page is available without require() - the globals registered at startup. Modeled after the Node.js / browser console environment.

On this page

console

Write to stdout/stderr. Multiple arguments are joined with a space and followed by a newline.

console.log(...args)

Print to stdout.

console.error(...args)

Print to stderr.

console.warn(...args)

Alias for console.error.

console.info(...args)

Alias for console.log.

console.assert(cond, ...args)

If cond is falsy, print "Assertion failed:" followed by the arguments.

console.dir(obj)

Pretty-print an object as JSON with indent 2.

console.time(label) / console.timeEnd(label)

Measure elapsed time between two calls with the same label. Resolution: 1 second - do not use for short timings; use performance.now() instead.

console.count(label) / console.countReset(label)

Maintain up to 16 named counters.

console.table(data)

Print an array of objects as a table. Limited to 16 columns and 30 chars per cell.

Math

All the standard numeric functions and constants.

Constants: PI, E, LN2, LN10, SQRT2, SQRT1_2, LOG10E, LOG2E.

One-argument: abs, floor, ceil, round, sqrt, cbrt, sin, cos, tan, asin, acos, atan, exp, log, log2, log10, sign, trunc, fround, clz32.

Two+ arguments: pow, atan2, hypot, imul, min, max.

Random: Math.random() - returns a value in [0, 1), seeded from system time at startup.

No FPU on MC68000

All floating-point math is software-emulated on plain 68000. Expect tight loops of trig/log to be slow on A500-class machines. On 68040/060 accelerators the FPU is used automatically (if built with -m68040/-m68060).

JSON

JSON.parse(text, reviver?)

Parse a JSON string. Optional reviver(key, value) is called for each key/value; return the new value or undefined to delete. Parse depth limit: 512.

JSON.stringify(value, replacer?, indent?)

Serialize a value to JSON. replacer may be a function (key, value) returning the new value (string/array replacers are NOT supported). indent is a number of spaces for pretty-printing. Detects circular references (stack depth 256).

undefined, functions, NaN, Infinity serialize as null.

Date

Standard Date object. Epoch origin is 1 Jan 1970 (not AmigaOS's 1 Jan 1978 - NodeAmiga internally translates).

new Date() / new Date(ms) / new Date(y, m, d, h, mn, s, ms)

Construct with the current time, a millisecond timestamp, or separate components. Years 0-99 are interpreted as 1900+.

Instance methods: getTime, getFullYear, getMonth, getDate, getDay, getHours, getMinutes, getSeconds, getMilliseconds, setTime, setFullYear/Month/Date/Hours/Minutes/Seconds/Milliseconds, toISOString, toString, toDateString, toTimeString, toUTCString, toLocaleString/LocaleDateString/LocaleTimeString (no locale support - same as regular), toJSON, valueOf, getTimezoneOffset.

Static: Date.now(), Date.UTC(y, m, d, h, mn, s, ms), Date.parse(isoString).

Time zone

getTimezoneOffset() always returns 0. AmigaOS has no portable time-zone database, so NodeAmiga treats all times as UTC. The UTC getters/setters (getUTCFullYear, etc.) are aliases for their non-UTC counterparts.

String / Number / Boolean

String.prototype - charAt, charCodeAt, codePointAt, at, indexOf, lastIndexOf, substring, slice, substr, toLowerCase, toUpperCase, trim, trimStart, trimEnd, includes, startsWith, endsWith, localeCompare, repeat (max 1,000,000 chars), padStart, padEnd, concat, replace, replaceAll, split, match, matchAll, search, normalize (no-op), toString, valueOf.

String statics: String.fromCharCode, String.fromCodePoint, String.raw (tagged template).

Number.prototype - toString(radix), valueOf, toFixed(digits), toExponential(digits), toPrecision(digits).

Number statics: isInteger, isFinite, isNaN, isSafeInteger, constants MAX_VALUE, MIN_VALUE, POSITIVE_INFINITY, NEGATIVE_INFINITY, NaN, MAX_SAFE_INTEGER, MIN_SAFE_INTEGER, EPSILON.

Boolean - constructor; no meaningful prototype extensions.

fromCharCode is low-byte only

String.fromCharCode(0x1F600) won't produce the expected character; only the low byte is used. If you need real Unicode escape sequences, use "\u{1F600}" in source code - the parser handles them correctly.

Array

Instance methods: at, push, pop, shift, unshift, indexOf, lastIndexOf, includes, join, toString, reverse, slice, concat, splice, fill, copyWithin, forEach, map, filter, reduce, reduceRight, entries, keys, values, find, findIndex, findLast, findLastIndex, every, some, sort, flat, flatMap, and the ES2023 immutable pair: toReversed, toSorted, toSpliced, with.

Statics: Array.isArray, Array.from (iterable / array-like / string + mapFn), Array.of.

sort performance

Both Array.prototype.sort (since 0.22) and typed-array sort (since 0.26) use bottom-up iterative merge sort - O(n log n), stable, no recursion (so no m68k stack pressure on large inputs). Tens of thousands of elements sort comfortably; the only concern is the O(n) auxiliary buffer allocation, which falls back to insertion sort if RAM is tight.

Object

Statics: keys, values, entries, assign, create, freeze, seal, isFrozen, isSealed, fromEntries, is (SameValue - NaN==NaN, +0!=-0), defineProperty, defineProperties, hasOwn, getPrototypeOf, setPrototypeOf, getOwnPropertyDescriptor, getOwnPropertyDescriptors, getOwnPropertySymbols, preventExtensions, isExtensible, groupBy.

Prototype methods: hasOwnProperty, isPrototypeOf, propertyIsEnumerable.

Property descriptors are spec-correct: writable, enumerable and configurable all enforced. Missing keys in the descriptor passed to defineProperty default to false (per ES5.1). Redefining a non-configurable property cannot promote it to configurable, change enumerable, switch between accessor/data, flip writable from false to true, or change the value when non-writable - defineProperty throws a TypeError in those cases. delete on a non-configurable own property returns false instead of removing it. Object.freeze marks every own property non-writable + non-configurable; Object.seal marks them non-configurable. Accessor descriptors ({get, set}) are returned by getOwnPropertyDescriptor without value/writable keys.

Object.keys / values / entries, for...in, and Object.assign / object spread all skip non-enumerable own properties.

RegExp

Literal /pattern/flags syntax and new RegExp(pattern, flags). Flags: g (global), i (ignore case), m (multiline), s (dotAll), u (unicode - parsed but behavior is identical), y (sticky).

Supported syntax: literals, ., character classes [abc] / [a-z] / [^...], built-ins \d \D \w \W \s \S, anchors ^ $, word boundary \b \B, quantifiers * + ? {n} {n,m} (greedy and lazy ?), groups (...), non-capturing (?:...), alternation |, backreferences \1-\9, lookahead (?=...) / (?!...), lookbehind (?<=...) / (?<!...), named groups (?<name>...).

Methods: test(str), exec(str), toString(). lastIndex is respected for g and y flags.

Match results from exec() include the standard index and input properties, numbered captures via m[1]..m[n], and - if the pattern uses (?<name>...) - an additional m.groups object mapping each capture name to its captured string. m.groups is undefined when the pattern has no named groups.

Catastrophic backtracking is capped

Deeply nested quantifiers like (a+)+b against aaaaaa...X will hit an internal step limit (100,000) and silently return "no match". Use non-greedy quantifiers or rewrite pathological patterns.

Error

Constructors: Error, TypeError, RangeError, SyntaxError, ReferenceError, URIError, EvalError.

Errors have name, message, stack and optionally cause (the second argument to the constructor). The stack is a multi-line string with up to 10 frames; each frame is formatted as at NAME (file:LINE:COL). The line/column reflect the call site recorded at eval_call/eval_new time, and file is the basename of __filename at the moment of error construction. Native frames and untracked call sites render without parentheses (just at NAME).

Error.captureStackTrace(target, ctor?)

Set target.stack to the current stack. Node.js compatibility.

Promise

new Promise(executor)

executor(resolve, reject) runs synchronously; call either resolver once.

Instance: then(onFulfilled, onRejected), catch(onRejected), finally(cb).

Statics: Promise.resolve(v), Promise.reject(r), Promise.all(iter), Promise.race(iter), Promise.allSettled(iter), Promise.any(iter).

NodeAmiga has a microtask queue. Promise callbacks run after the current synchronous code completes. Use queueMicrotask(fn) or process.nextTick(fn) to schedule your own.

all / race / any are simplified

The all-family statics only inspect the immediate state of their inputs. A promise still pending when they run is treated as resolved-with-undefined (in all/race) or skipped (in any). This is usually what you want for fire-and-forget flows, but is not spec-compliant.

async / await

Both are supported. await internally spins the event loop + microtask queue until the Promise settles or a ~100-second timeout - at which point it throws an Error. Long-running network operations should complete well within that window.

Timers (setTimeout / setInterval)

setTimeout(fn, ms, ...args) → id

Schedule a one-shot timer. Returns a numeric id.

setInterval(fn, ms, ...args) → id

Schedule a repeating timer.

clearTimeout(id) / clearInterval(id)

Cancel a pending timer. Safe even if the id is already fired or invalid.

queueMicrotask(fn)

Run fn after the current task finishes but before the next timer tick.

1-second resolution

Timers are bucketed to whole seconds by the current implementation. setTimeout(fn, 50) may fire between 0 and ~1000 ms. Use performance.now() or the timer.device ECLOCK via the FFI module if you need sub-second precision.

Buffer

Node.js-compatible binary buffer backed by a contiguous malloc'd byte array.

Buffer.from(input, encoding?)

input may be a string (optionally with encoding 'utf8' / 'hex' / 'base64'), an array of bytes, or another Buffer.

Buffer.alloc(size, fill?)

Allocate a zero-filled buffer, or fill with a number / string (cycled).

Buffer.concat(list)

Concatenate multiple buffers into a new one.

Buffer.isBuffer(value)

Type check.

Instance: length, toString(encoding?), slice(start, end), copy(target, destOffset, srcStart, srcEnd), fill(value, start, end), readUInt8(offset), writeUInt8(value, offset), readUInt16BE, writeUInt16BE, indexOf(value), equals(other), and direct indexing buf[i].

Big-endian on Amiga

Buffers read/write 16- and 32-bit integers in big-endian by default (matching m68k byte order). Use DataView if you need little-endian.

Typed arrays & ArrayBuffer

Nine typed array views: Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array. Max length: 1,048,576 elements.

Each supports the usual constructor forms (length, array, ArrayBuffer+offset+count), BYTES_PER_ELEMENT, buffer, byteOffset, byteLength, and methods set, subarray, slice, fill, indexOf, includes, join, reverse, forEach, map, filter, find, findIndex, every, some, reduce, sort (insertion - O(n²)), copyWithin, toString, plus statics from, of.

ArrayBuffer - new ArrayBuffer(byteLength), .byteLength, .slice(start, end), static ArrayBuffer.isView(v).

DataView - new DataView(buffer, byteOffset?, byteLength?), with getInt8/Uint8/Int16/Uint16/Int32/Uint32/Float32/Float64 and setX counterparts. All multi-byte methods take an optional littleEndian flag (default big-endian).

Typed arrays are always big-endian on NodeAmiga; use DataView if you need little-endian.

Map / Set / WeakMap / WeakSet

Standard collection types. Map and Set fully support set/get/has/delete/clear/size/forEach/keys/values/entries, and are iterable via for-of. Constructors accept an iterable of [key, value] pairs (or just values, for Set).

Weak variants aren't truly weak

WeakMap/WeakSet keep their entries alive via refcounting - real weakness would require a garbage collector. The API is there for Node.js compatibility but entries are effectively strong references.

Lookup is O(1) average - 64-bucket hash table with chaining since 0.26. Insertion order is preserved on iteration via an internal doubly-linked list. SameValueZero key comparison: NaN === NaN, +0 === -0. Tens of thousands of entries are practical.

Symbol

Symbol(description?), Symbol.for(key), Symbol.keyFor(sym), and the well-known symbols Symbol.iterator, Symbol.hasInstance, Symbol.toPrimitive, Symbol.toStringTag.

Symbol keys can be used on objects. Retrieve them with Object.getOwnPropertySymbols(obj).

Hard limit: 256 unique symbols per process (not usually a concern, but beware if you Symbol() in a loop).

BigInt

BigInt(value) or the literal suffix 123n. Supports + - * / % ** == === < <= > >=, and the unary -. Cannot be mixed with regular numbers in arithmetic (throws TypeError).

Internally stored in base 10000 with unlimited digits in principle; however ** caps the exponent at ~10000 to avoid runaway memory growth.

TextEncoder / TextDecoder

new TextEncoder()

Always UTF-8. .encode(str) returns a Buffer.

new TextDecoder(encoding?)

.decode(buffer) returns a string. Only 'utf-8' is handled specially.

fetch

fetch(url, options?)

Synchronous HTTP fetch (not a Promise despite the name - returns directly). Options: {method, body, headers}. Returns a Response-shaped object: {ok, status, headers, body, text(), json(), arrayBuffer()}. The headers object has get(name) and has(name) methods that are case-insensitive and return null on missing.

Network errors (refused connection, DNS failure, AmiSSL handshake fail) still return a fully-formed Response with ok=false, status=0, an empty headers object and body="" - so reading res.headers.get(...) or await res.text() never crashes.

Requires bsdsocket.library. HTTPS requires AmiSSL. The underlying TCP socket has a 10-second send/receive timeout.

var res = fetch('http://aminet.net/');
if (res.ok) {
    console.log(res.headers.get('content-type'));
    console.log(res.body.length, 'bytes');
}

URI helpers

encodeURI(str), decodeURI(str), encodeURIComponent(str), decodeURIComponent(str).

Global functions / values

parseInt(str, radix?), parseFloat(str), isNaN(x), isFinite(x), eval(code).

Values: undefined, NaN, Infinity, globalThis (currently a stub - do not rely on it to access globals dynamically).

The standard constructors/classes are all global: Object, Array, String, Number, Boolean, Function, Date, RegExp, Error (and subclasses), Promise, Map, Set, WeakMap, WeakSet, Symbol, BigInt, ArrayBuffer, DataView, all typed-array constructors, Buffer, TextEncoder, TextDecoder.

process

Node-style process object. Available without require().

PropertyValue
process.platform"amigaos"
process.arch"m68k"
process.version"0.27.0"
process.pidCurrent process id (from AmigaOS)
process.argvArray of command-line arguments. argv[0]="nodeamiga", argv[1]=script path, user args from index 2.
process.envObject mirroring common AmigaOS ENV: variables read via getenv() at startup: PATH, Language, Workbench, Kickstart, Editor, TZ, USER, HOSTNAME, WBStartup, PUBSCREEN. Missing variables are simply absent from the object. For any other ENV: file, fall back to fs.readFileSync('ENV:VarName', 'utf8').
process.cwd()Current working directory (using CurrentDir+NameFromLock)
process.exit(code?)Terminate the process
process.memoryUsage()Returns {heapUsed, heapTotal, rss, external, arrayBuffers}. Based on AvailMem.
process.poolStats()Live {alloc, free, live} counters per internal pool: jsval, jsobj, jsfn, jsprop, env. Useful for tracking down leaks across cycles of long-running scripts.
process.gc()Run a mark-and-sweep over the JsObject and JsFunction pools, breaking refcount cycles. Roots: global env, every active call frame's env, the well-known prototypes (String.prototype etc.), the require() module cache, current thrown value, current native function. No automatic GC - call this at quiescence points if you create lots of cycles (e.g. Foo.prototype.constructor = Foo).
process.heapSnapshot()Returns {version, timestamp, pools} - a labeled, timestamped snapshot of process.poolStats(). Useful for diff'ing memory growth across long-running scripts.
process.on(event, handler)Register an event listener. Currently only 'unhandledRejection' is wired - handler(reason) fires for promise rejections that never had a .catch() attached. Other events are accepted silently for forward compatibility.
process.flushRejections()Synchronously drain the pending unhandled-rejection list, firing the registered handler for each. The sync runtime has no natural drain point, so call this explicitly at quiescence (or at the end of your script).
process.hrtime()[seconds, nanoseconds] high-resolution time. Pass the previous result to get a diff.
process.hrtime.bigint()High-resolution time as BigInt (ns). Simplified - uses time(), not eclock.
process.nextTick(fn)Queue a microtask
process.stdout.write(str) / process.stdin.read()Stream-like sync I/O helpers

performance

performance.now() → number

Milliseconds since process start, at ECLOCK resolution (microseconds on hardware with timer.device UNIT_ECLOCK, which is essentially every Amiga from A500 up).

structuredClone

structuredClone(value)

Deep-clone a value. Depth limit 64. Internal runtime markers (buffer data pointers, regex compile state, promise handles, Map/Set internals) are not followed - clones of those types won't preserve their state fully.