Skip to content

Latest commit

 

History

History
244 lines (185 loc) · 9.19 KB

9.valueproxy.md

File metadata and controls

244 lines (185 loc) · 9.19 KB
title ValueProxy
description The ValueProxy class that query callbacks receive, and its operators on any value, numbers, dates, strings, arrays, and objects.
mode reference

The ValueProxy<T> class is a proxy to a value in the database. An operation on a ValueProxy does not run right away. The proxy records it as a query stage. Callbacks of map, filter, do, update, join, and other query methods receive ValueProxy objects.

Class definition

Which ValueProxy methods compile depends on the type of the underlying value. This page groups the operations by that type.

Create a ValueProxy

Query methods that take a callback create the ValueProxy instances they pass to it. ValueProxy.constant() creates one from a constant value:

import { ValueProxy } from "@antelopejs/interface-database";

const constant = ValueProxy.constant(42);
const strConst = ValueProxy.constant("hello");

A constant, and any operand a stage records (eq, ne, default, gt, includes, merge and the others), holds a QueryValue: another proxy or query, text, a number, a boolean, null, undefined, a Date, a list of operands or a record of operands. A bigint, a symbol or a function does not compile.

eq, ne, gt, ge, lt, le and includes check the operand against the type of the proxy, so a record type declared with interface is accepted there. ValueProxy.constant, default, sub, merge and the default of key infer their type from the argument and need a QueryValue: an interface has no implicit index signature and does not compile, so declare the record with type.

General operations

These methods are available on every ValueProxy.

default(value)

Returns the given value if the proxy is null.

const phone = user.key("phone").default("N/A");

eq(value) and ne(value)

Equality and inequality comparison.

const isActive = user.key("status").eq("active");
const isNotAdmin = user.key("role").ne("admin");

and(value), or(value), and not()

Logical operators that combine boolean expressions. The operand of and and or compiles when it is a boolean, null, undefined, any, or a ValueProxy of boolean, boolean | null or boolean | undefined. A string, a number, a ValueProxy<string>, a ValueProxy<unknown>, a generic ValueProxy<T> and a union such as ValueProxy<boolean> | undefined are compile-time errors. The database evaluates operands by truthiness, so the type accepts less than the runtime does.

const canAccess = user.key("active").and(user.key("verified"));
const isSpecial = user
  .key("role")
  .eq("admin")
  .or(user.key("plan").eq("premium"));
const isInactive = user.key("active").not();

cast<U>()

Changes the TypeScript type without a runtime conversion. Nothing checks that the new type matches the value.

Number operations

These methods compile when the proxy wraps a number.

Arithmetic

const next = age.add(1);
const diff = total.sub(discount);
const doubled = price.mul(2);
const half = amount.div(2);
const remainder = count.mod(10);

Rounding

const rounded = score.round();
const ceiling = value.ceil();
const floored = value.floor();

Bitwise

const bitwiseAnd = flags.band(0xff);
const bitwiseOr = flags.bor(0x01);
const bitwiseXor = flags.bxor(mask);
const bitwiseNot = flags.bnot();
const shifted = flags.blshift(2);
const unshifted = flags.brshift(2);
const signPreserved = flags.brshiftPreserveSign(2);

Comparison operations

These methods compile for number, string, and Date proxy values.

const isAdult = age.gt(17);
const isMinor = age.le(17);
const isRecent = date.ge(new Date("2024-01-01"));
const isBefore = date.lt(deadline);
Method Description
gt(v) Greater than
ge(v) Greater than or equal
lt(v) Less than
le(v) Less than or equal

Date operations

These methods compile when the proxy wraps a Date value. Every component method except epoch() accepts an optional timezone parameter. add takes a number of seconds.

Arithmetic

const threeDaysLater = created.add(3 * 24 * 60 * 60);
const elapsed = now.sub(created); // difference in seconds

Components

const y = created.year();
const m = created.month();
const d = created.day();
const dow = created.dayofweek();
const doy = created.dayofyear();
const h = created.hours();
const min = created.minutes();
const sec = created.seconds();
const tod = created.timeofday(); // seconds since midnight
const epoch = created.epoch(); // seconds since UNIX epoch

Range check

const inRange = created.during(
  ValueProxy.constant(new Date("2024-01-01")),
  ValueProxy.constant(new Date("2025-01-01")),
);

The lower bound of during is inclusive, and the upper bound is exclusive. during also takes plain Date bounds, or bounds as milliseconds since the UNIX epoch, as new Date(n) reads them.

String operations

These methods compile when the proxy wraps a string value. add concatenates two strings, as concat does, and two lists on a list. A null operand answers null for any receiver of add.

const upper = name.upcase();
const lower = name.downcase();
const parts = email.split("@");
const full = first.concat(last);
const len = name.strlen();
const matches = email.match("^.*@gmail\\.com$");
Method Description
upcase() Convert to uppercase
downcase() Convert to lowercase
split(sep?, max?) Split by separator
concat(other) Concatenate with another string
strlen() Number of Unicode codepoints
match(regex) Test against a regex pattern

Array operations

These methods compile when the proxy wraps an array value.

const first = tags.index(0);
const hasAdmin = tags.includes("admin");
const sub = tags.slice(0, 3);
const upper = tags.map((t) => t.upcase());
const long = tags.filter((t) => t.strlen().gt(5));
const empty = tags.isempty();
const len = tags.count();
const total = scores.sum();
const average = scores.avg();
const lowest = scores.min();
const highest = scores.max();
Method Description
index(n) Element at position n
includes(val) Check if the array contains a value
slice(s, e?) Extract a sub-array from s (inclusive) to e (exclusive)
map(fn) Transform each element
filter(fn) Keep elements matching a predicate. A number keeps the element unless it is 0
isempty() Check if the array is empty
count() Number of elements
sum() Sum of numeric elements
avg() Average of numeric elements
min() Minimum of numeric, string or date elements
max() Maximum of numeric, string or date elements

Object operations

These methods compile when the proxy wraps an object value.

key(field, fallback) keeps the declared field type when the fallback is omitted or undefined. Otherwise, the proxy's value type is Exclude<FieldType, undefined | null> | FallbackType. The fallback can itself be a ValueProxy, and then its value type is part of the result.

const email = user.key("email");
const emailOrDefault = user.key("email", "none@example.com");
const merged = user.merge({ lastSeen: new Date() });
const fieldNames = user.keys();
const fieldValues = user.values();
const hasRequired = user.hasfields("email", "name");
Method Description
key(k, def?) Access a field, with optional default
merge(other) Merge with another object
keys() Array of field names
values() Array of field values
hasfields(...fs) Check if all specified fields exist

Compose expressions

You can chain ValueProxy methods to build larger expressions inside query callbacks:

const result = await users.filter((user) =>
  user
    .key("age")
    .ge(18)
    .and(user.key("status").eq("active"))
    .and(user.key("role").eq("admin").or(user.key("plan").eq("premium"))),
);