@tai-kun/surrealdb
Version:
The SurrealDB SDK for JavaScript
128 lines (106 loc) • 3.12 kB
text/typescript
import { Future as Base } from "@tai-kun/surrealdb/encodable-datatypes";
import { SurrealTypeError, SurrealValueError } from "@tai-kun/surrealdb/errors";
import { toSurql } from "@tai-kun/surrealdb/utils";
import { escapeTb, toString } from "../_internals/thing";
import type { Standard } from "./spec";
export type * from "../encodable/future";
/**
* [API Reference](https://tai-kun.github.io/surrealdb.js/v2/api/data/future)
* @experimental
*/
export default class Future extends Base implements Standard {
static raw(value: RawValue): Raw {
return new Raw(value);
}
static surql(
texts: readonly string[] | TemplateStringsArray,
...values: unknown[]
): string {
if (texts.length - values.length !== 1) {
throw new SurrealValueError(
"template string",
`texts.length=${texts.length} and values.length=${values.length}`,
);
}
let text = "";
for (
let i = 0,
j: number,
v,
len = texts.length,
cache: Record<number, string> = {};
i < len;
i++
) {
text += texts[i];
if (i + 1 === len) {
break;
}
for (j = 0; j < i; j++) {
if (Object.is(values[j], values[i])) {
break;
}
}
v = values[j];
if (v instanceof Raw) {
text += v.toString();
} else {
text += cache[j] ??= toSurql(v);
}
}
return text;
}
// @ts-expect-error readonly を外すだけ
block: string;
clone(): this {
const This = this.constructor as typeof Future;
return new This(this.block) as this;
}
}
const THING = /* @__PURE__ */ Symbol.for("@tai-kun/surrealdb/thing-datatypes");
function isThing(o: unknown): o is {
readonly table: string;
readonly id: unknown;
} {
return !!o
&& typeof o === "object"
// @ts-expect-error
&& o["$$datatype"] === THING;
}
function isGenerator(id: unknown): id is string {
return id === "uuid()" || id === "ulid()" || id === "rand()";
}
export type RawValue =
| string
| { readonly toSurql: () => string }
| { readonly toString: () => string }
| { readonly [Symbol.toPrimitive]: (hint: "string") => string };
class Raw {
protected _val: RawValue;
protected _str: string;
constructor(value: RawValue) {
this._val = value;
if (typeof value === "string") {
this._str = value;
} else if (value && typeof value === "object") {
if (isThing(value)) {
this._str = isGenerator(value.id)
? escapeTb(value.table) + ":" + value.id
: toString(value);
} else if ("toSurql" in value) {
this._str = value.toSurql();
} else if (Object.hasOwn(value, "toString")) {
this._str = value.toString();
} else if (Object.hasOwn(value, Symbol.toPrimitive)) {
this._str = (value as any)[Symbol.toPrimitive]!("string");
} else {
throw new SurrealValueError("Object contains encode methods", value);
}
} else {
throw new SurrealTypeError(["String", "Object"], value);
}
}
toString(): string {
return this._str;
}
}