Skip to content

Scripting

TypeScript API reference

Reference the async execution model, binary-safe Redis facade, utility globals, permissions, and transformer inputs available to Varc scripts.

Varc runs TypeScript and JavaScript in its built-in scripting engine. Scripts support standard language features such as Array, Map, Date, Promise, and typed arrays, plus the Varc APIs documented on this page.

Execution and return values

Top-level await works in every execution class. Only an explicit return supplies the terminal result:

const values = await Promise.all([redis.get("one"), redis.get("two")]);
return values;

Use return await operation when returning a Promise directly. Varc rejects unresolved Promises and Promises nested inside returned arrays or objects rather than publishing a misleading partial result.

Redis, Fetch, and sleep are asynchronous and share the script’s cancellation and execution deadline. Varc allows up to 64 operations to wait at once and stops the script if that bound is exceeded.

Redis values and keys

Redis keys, fields, and members are binary-safe:

type RedisBytes = Uint8Array;
type RedisKey = string | Uint8Array;

Text helpers decode bulk strings as UTF-8 for convenience. Use the corresponding byte method or redis.call when exact bytes matter. Integer replies use number when safe and bigint when the value exceeds JavaScript’s safe-integer range.

Redis facade

redis.database is the immutable logical database targeted by the facade. redis.db(index) returns another complete facade routed to index; it does not mutate the root object.

Method Result Purpose
redis.db(index) Redis Route subsequent calls through another logical database.
redis.call(name, ...args) Promise<unknown> Issue any command allowed by policy while preserving the raw reply shape and bytes.
redis.text(value) decoded value Decode a byte reply element as UTF-8.
redis.textArray(value) decoded array Decode each byte reply element as UTF-8.

Use redis.call(name, ...args) as the supported raw-command escape hatch when a typed helper is not available.

Strings

Method Return
get(key) Promise<string | null>
getBytes(key) Promise<Uint8Array | null>
set(key, value, ...options) Promise<string | null>
setnx(key, value) Promise<number>
getset(key, value) Promise<string | null>
append(key, value) Promise<number>
strlen(key) Promise<number>
incr(key) / decr(key) Promise<number>
incrBy(key, amount) / decrBy(key, amount) Promise<number>
mget(...keys) Promise<(string | null)[]>

Keys and expiry

Method Return
del(...keys) / unlink(...keys) Promise<number>
exists(...keys) Promise<number>
expire(key, seconds) / pexpire(key, milliseconds) Promise<number>
persist(key) Promise<number>
ttl(key) / pttl(key) Promise<number>
type(key) Promise<string | null>
rename(key, newKey) Promise<string | null>

Hashes

Method Return
hget(key, field) Promise<string | null>
hset(key, field, value) Promise<number>
hdel(key, ...fields) Promise<number>
hexists(key, field) Promise<number>
hlen(key) Promise<number>
hgetall(key) Promise<Record<string, string>>

Use redis.call("HGETALL", key) when fields or values may not be UTF-8 and must remain bytes.

Lists

Method Return
lpush(key, ...values) / rpush(key, ...values) Promise<number>
lpop(key) / rpop(key) Promise<string | null>
llen(key) Promise<number>
lrange(key, start, stop) Promise<string[]>

Sets

Method Return
sadd(key, ...members) / srem(key, ...members) Promise<number>
scard(key) Promise<number>
sismember(key, member) Promise<number>
smembers(key) Promise<string[]>

Sorted sets

Method Return
zadd(key, score, member) Promise<number>
zrem(key, ...members) Promise<number>
zcard(key) Promise<number>
zscore(key, member) Promise<number | null>
zrange(key, start, stop, ...options) Promise<string[] | { value: string; score: number }[]>

Server and incremental scans

Method Return
ping() Promise<string | null>
dbsize() Promise<number>
scan(cursor, options?) Promise<{ cursor: string; keys: string[] }>
sscan(key, cursor, options?) Promise<{ cursor: string; members: string[] }>
hscan(key, cursor, options?) Promise<{ cursor: string; fields: Record<string, string> }>
zscan(key, cursor, options?) Promise<{ cursor: string; members: { value: string; score: number }[] }>
keys(pattern?, options?) Promise<string[]>

scan options are { match?, count?, type? }. Continue until the returned cursor is "0".

redis.keys() is not the blocking Redis KEYS command. It collects results by repeatedly calling SCAN and stops at Varc’s scan-iteration and returned-key quotas. Prefer explicit scan loops when the caller should process one bounded page at a time.

Command policy

All helpers and redis.call pass through one command-policy gate. Manual scripts and macros may perform ordinary reads and writes, but Varc rejects destructive administration, connection-affine commands, subscriptions, server-side Lua, and Redis Functions. Examples include FLUSHALL, CONFIG, CLIENT, SELECT, MULTI, EVAL, SCRIPT, FCALL, and FUNCTION.

Transformers deny every Redis command. Dashboard widgets use a separate read-only policy described in execution classes.

Environment variables

env is a frozen record containing the active Script environment:

const endpoint = env.API_ORIGIN;
return { environmentConfigured: endpoint !== undefined };

Member completion reflects the environment selected in the workspace status bar. Reading a declared secret that has no value on this device throws scriptSecretUnavailable. Values printed or returned by a script are not redacted. See environments and permissions.

Byte and text codecs

Global Methods Behavior
base64 encode(value), decode(text) Strict standard Base64 with mandatory padding; decode returns bytes.
hex encode(value), decode(text) Lowercase output; decode accepts either case and returns bytes.
utf8 encode(text), decode(bytes) Strict UTF-8 conversion in both directions.

Invalid input fails instead of being repaired or guessed.

Hashing and randomness

Global Signature Notes
hash.sha1 (value: string | Uint8Array) => Uint8Array Legacy interoperability only.
hash.sha256 (value: string | Uint8Array) => Uint8Array SHA-256 digest bytes.
hash.md5 (value: string | Uint8Array) => Uint8Array Legacy interoperability only.
hash.hmacSha256 (key, value) => Uint8Array HMAC-SHA256 tag bytes.
uuid () => string Random RFC 4122 version 4 UUID.
randomBytes (length: number) => Uint8Array Cryptographically random bytes, up to 64 KiB.
crypto.getRandomValues (target: Uint8Array) => target Web-compatible in-place random fill.
crypto.randomUUID () => string Web-compatible random UUID.

Use hex.encode(hash.sha256(value)) when a hexadecimal digest is required. Use varc:seed rather than these globals for repeatable fixture data.

Cooperative sleep

await sleep(milliseconds) pauses without busy-spinning. It uses the run’s host-I/O queue and shares the same deadline and cancellation budget.

for (let attempt = 0; attempt < 5; attempt += 1) {
  if (await redis.exists("job:complete")) return true;
  await sleep(100);
}
return false;

Console

console.log, console.info, console.warn, console.error, and console.debug write bounded messages to Run output. Varc caps the number and size of retained messages and reports how many were dropped.

Host capabilities

The following globals exist in manual scripts and macros, but each saved script needs the corresponding permission:

Global API Permission
clipboard write(value) Clipboard
dialog info(message), warn(message), error(message) Dialogs
notifications show(title, body?) Notifications
fetch fetch(input, init?) Network

Clipboard access is write-only. Dialog and notification calls are fire-and-forget. All are size- and rate-limited. See environments and permissions and the full Fetch API reference.

Fetch and web-compatible globals

Network-enabled scripts and macros also receive Request, Response, Headers, Blob, FormData, AbortController, AbortSignal, ReadableStream, URL, URLSearchParams, TextEncoder, and TextDecoder.

These globals implement the documented Fetch workflow; they do not install a browser DOM, navigation, cookie store, service workers, arbitrary sockets, or Node APIs.

Transformer input

Only transformer runs receive:

declare const value: Uint8Array;
declare const complete: boolean;

value contains the exact bytes being decoded. complete is currently always true; truncated values are not sent to transformers. A transformer returns a bounded render result and cannot access Redis, Fetch, or host capabilities.