mirror of
https://github.com/docmost/docmost.git
synced 2026-08-30 02:25:01 +08:00
feat(base-formula): add AST and value types
This commit is contained in:
@@ -0,0 +1,33 @@
|
|||||||
|
export type OpCode =
|
||||||
|
| "+" | "-" | "*" | "/" | "%"
|
||||||
|
| "==" | "!=" | ">" | "<" | ">=" | "<="
|
||||||
|
| "neg" | "not";
|
||||||
|
|
||||||
|
export type FormulaAST =
|
||||||
|
| { t: "num"; v: number }
|
||||||
|
| { t: "str"; v: string }
|
||||||
|
| { t: "bool"; v: boolean }
|
||||||
|
| { t: "null" }
|
||||||
|
| { t: "prop"; id: string }
|
||||||
|
| { t: "op"; op: OpCode; args: FormulaAST[] }
|
||||||
|
| { t: "if"; cond: FormulaAST; then: FormulaAST; else: FormulaAST }
|
||||||
|
| { t: "and"; args: FormulaAST[] }
|
||||||
|
| { t: "or"; args: FormulaAST[] }
|
||||||
|
| { t: "call"; fn: string; args: FormulaAST[] };
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Raw AST: what the parser produces before resolving property names to IDs.
|
||||||
|
* Only the `propName` variant differs from FormulaAST — every other node is
|
||||||
|
* reused directly. We deliberately keep this type-level to avoid duplicating
|
||||||
|
* the tree shape.
|
||||||
|
*/
|
||||||
|
export type RawFormulaAST =
|
||||||
|
| Exclude<FormulaAST, { t: "prop" }>
|
||||||
|
| { t: "propName"; name: string }
|
||||||
|
| { t: "op"; op: OpCode; args: RawFormulaAST[] }
|
||||||
|
| { t: "if"; cond: RawFormulaAST; then: RawFormulaAST; else: RawFormulaAST }
|
||||||
|
| { t: "and"; args: RawFormulaAST[] }
|
||||||
|
| { t: "or"; args: RawFormulaAST[] }
|
||||||
|
| { t: "call"; fn: string; args: RawFormulaAST[] };
|
||||||
|
|
||||||
|
export const AST_VERSION = 1 as const;
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
// Minimal stub: FormulaFn type will be expanded in Task 10.
|
||||||
|
export type FormulaFn = unknown;
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
// Client-side public surface: parse, typecheck, cycle-detect, pretty-print.
|
// Client-side public surface: parse, typecheck, cycle-detect, pretty-print.
|
||||||
// Does NOT export eval or the function registry.
|
// Does NOT export eval or the function registry.
|
||||||
export {};
|
export * from "./ast";
|
||||||
|
export * from "./types";
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
// Server-side public surface: everything in client + evaluator + registry.
|
// Server-side public surface: everything in client + evaluator + registry.
|
||||||
export {};
|
export * from "./ast";
|
||||||
|
export * from "./types";
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
import type { FormulaAST } from "./ast";
|
||||||
|
|
||||||
|
export type FormulaResultType =
|
||||||
|
| "number"
|
||||||
|
| "string"
|
||||||
|
| "boolean"
|
||||||
|
| "date"
|
||||||
|
| "null";
|
||||||
|
|
||||||
|
export type FormulaTypeOptions = {
|
||||||
|
source: string;
|
||||||
|
ast: FormulaAST;
|
||||||
|
resultType: FormulaResultType;
|
||||||
|
dependencies: string[];
|
||||||
|
astVersion: 1;
|
||||||
|
formatOptions?: Record<string, unknown>;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The runtime value produced by evaluating a node. Strings and numbers are
|
||||||
|
* their JS equivalents; dates are ISO 8601 UTC strings (matches how the date
|
||||||
|
* property type already stores cells); booleans are booleans; missing or
|
||||||
|
* filtered-out values are null. Errors are distinguishable from all valid
|
||||||
|
* values because they are objects with a `__err` key.
|
||||||
|
*/
|
||||||
|
export type Value = number | string | boolean | null | ErrorCell;
|
||||||
|
|
||||||
|
export type ErrorCell = {
|
||||||
|
__err: ErrorCode;
|
||||||
|
msg: string;
|
||||||
|
v: 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ErrorCode =
|
||||||
|
| "MISSING_PROP"
|
||||||
|
| "TYPE_MISMATCH"
|
||||||
|
| "DIV_BY_ZERO"
|
||||||
|
| "DATE_INVALID"
|
||||||
|
| "DEPTH_EXCEEDED"
|
||||||
|
| "DEPENDENCY_ERROR";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* EvalContext carries everything the evaluator needs that isn't in the AST:
|
||||||
|
* the function registry (server-only), the property map for resolving `prop`
|
||||||
|
* nodes to their formula ASTs when nested, and the current recursion depth.
|
||||||
|
*/
|
||||||
|
export type EvalContext = {
|
||||||
|
registry: ReadonlyMap<string, import("./functions/registry").FormulaFn>;
|
||||||
|
properties: ReadonlyMap<string, PropertyLookup>;
|
||||||
|
depth: number;
|
||||||
|
maxDepth: number;
|
||||||
|
memo: Map<string, Value>; // keyed by propId for the current row-eval
|
||||||
|
};
|
||||||
|
|
||||||
|
export type PropertyLookup = {
|
||||||
|
id: string;
|
||||||
|
type: string;
|
||||||
|
typeOptions: unknown;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const DEFAULT_MAX_DEPTH = 64;
|
||||||
Reference in New Issue
Block a user