/*!
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
/** Names of known types (traits) within the runtime */
export declare enum TypeName {
Comparable = 0,
Error = 1,
Numeric = 2,
Readable = 3,
Reference = 4
}
/** An immutable map of known types */
export interface TypeMap {
readonly [TypeName.Comparable]?: ComparableType;
readonly [TypeName.Error]?: ErrorType;
readonly [TypeName.Numeric]?: NumericType;
readonly [TypeName.Readable]?: ReadableType;
readonly [TypeName.Reference]?: ReferenceType;
}
export declare type Primitive = boolean | number | string;
export interface CalcObj {
/**
* An object's type map describes the behaviours the object
* supports. Type maps are immutable.
*
* The purpose of the `this` type is to allow authors to implement
* types using more specific interfaces.
*
*/
typeMap(): TypeMap;
serialise(context: C): string;
}
/** A CalcObj that is known to implement types `T` */
export interface TypedCalcObj {
typeMap: () => Pick>, T>;
serialise: (context: C) => string;
}
/**
* A CalcFun accepts two contexts:
* - CLex is lexically scoped and active when the function is created.
* - CDyn is dynamically scoped and active when the function is called.
*
* We do not capture the context (removing CDyn) because certain
* functions want to maintain dynamic dependencies and linking them
* against the lexical context would be wrong.
*
* The type constraints say that the dynamic context must be (at
* least) as specific as the lexical context.
*
*/
export interface CalcFun {
(runtime: Runtime, context: CDyn, args: CalcValue[]): CalcValue | Delay;
}
export declare type CalcValue = Primitive | CalcObj | CalcFun;
export declare type DataValue = Primitive | CalcObj;
/** Dispatch pattern for a binary operator */
export declare enum DispatchPattern {
/** Left operand has the type, right is primitive */
L = -1,
/** Right operand has the type, left is primitive */
R = 1,
/** Both operands have the correct type (which are equal up to pointer equality) */
Both = 0
}
export interface ComparableType {
/**
* Compares two values.
*
* The compare function should follow the same comparator rules as
* a JavaScript comparator, but may optionally return an object in
* the event of error.
*
* 0 ~ GT, (<0) ~ LT, (>0) ~ GT.
*
* @param pattern
* @param l
* @param r
* @param context
*/
compare(pattern: DispatchPattern, l: A | Primitive, r: A | Primitive, context: C): number | CalcObj;
}
export interface ErrorType {
/**
* Error types support enriching with additional information which
* they may choose to ignore.
*
* @param value
* @param message
* @param context
*/
enrich(value: A, message: string, context: C): A;
}
/**
* Numeric operations that can be overloaded
*
* A numeric type should support operations with primitive numbers and
* other objects of the same numeric type.
*/
export interface NumericType {
plus(pattern: DispatchPattern, l: A | number, r: A | number, context: C): CalcValue;
minus(pattern: DispatchPattern, l: A | number, r: A | number, context: C): CalcValue;
mult(pattern: DispatchPattern, l: A | number, r: A | number, context: C): CalcValue;
div(pattern: DispatchPattern, l: A | number, r: A | number, context: C): CalcValue;
negate(value: A, context: C): CalcValue;
}
export interface Pending {
kind: "Pending";
estimate?: T;
}
/**
* A Readable type supports the dot operator.
*/
export interface ReadableType {
read(value: A, property: string, context: C): CalcValue | Pending>;
}
/**
* A ReferenceType type holds a pointer to another value.
*
* Operators will attempt to dereference a reference before applying
* the operator. This happens once and is not recursive.
*/
export interface ReferenceType {
dereference(value: A, context: C): CalcValue | Pending>;
}
export declare type CheckFn = (context: C, value: DataValue, pos: number) => value is DataValue & A;
export declare type BlameFn = (context: C, value: CalcValue, pos: number) => CalcValue;
export interface TypedUnaryOp {
check: CheckFn;
fn: (context: C, value: A) => CalcValue;
blame: BlameFn;
}
export interface TypedBinOp {
check: CheckFn;
fn: (context: C, value1: A, value2: A) => CalcValue;
blame: BlameFn;
}
/**
* Evaluation Runtime
*/
export interface Runtime {
isDelayed: (v: unknown) => v is Delay;
read: (context: C, receiver: CalcValue | Delay, prop: string, fallback: F) => CalcValue | F | Delay;
ifS: (cond: boolean | Delay, cont: (cond: boolean) => T | Delay) => T | Delay;
app1: (context: C, op: TypedUnaryOp, expr: CalcValue | Delay) => CalcValue | Delay;
app2: (context: C, op: TypedBinOp, l: CalcValue | Delay, r: CalcValue | Delay) => CalcValue | Delay;
appN: (context: C, fn: CalcValue | Delay, args: (CalcValue | Delay)[], fallback: F) => CalcValue | F | Delay;
}
export interface Resolver {
resolve: (context: C, ref: Ref, failure: F) => CalcValue | F | Delay;
}
/**
* The interface for an object that can bind to an IProducer.
*
* Any object that implements IConsumer is expected to provide a
* callback whenever the component it is bound to changes in value and a reference
* to the data that the consumer is bound to.
*/
export interface IConsumer {
/**
* Invoked whenever the data this object is bound to is changed.
*/
valueChanged(property: K, producer: IProducer): void;
}
export interface IReader {
/**
* Return the value associated with `property`.
* @param property - The property of the Producer to read.
*/
get(property: K): T[K] | Pending;
/**
* A reference to the underlying producer that provides values for this reader.
*/
readonly producer: IProducer;
}
export interface IWriter {
set(property: K, value: T[K]): void;
delete(property: K): void;
}
/**
* The interface for an object whose data can be bound to. We use this contract for
* components that want to expose their data and its changes to other components.
*
* Any component that implements IProducer is expected to provide some registration
* functionality and to notify consumers whenever the data they are bound to changes.
*/
export interface IProducer {
/**
* Acquire a reader for this producer's values and implicitly subscribe the consumer
* to value change notifications.
*
* @param consumer - The consumer to be notified of value changes.
*/
open(consumer: IConsumer): IReader;
/**
* Unsubscribe the consumer from this producer's change notifications.
*
* @param consumer - The consumer to unregister from the producer.
*/
close(consumer: IConsumer): void;
}
export interface IVectorConsumer {
/** Notification that a range of items have been inserted, removed, and/or replaced in the given vector. */
itemsChanged(start: number, removedCount: number, insertedCount: number, producer: IVectorProducer): void;
}
export interface IVectorReader {
readonly length: number;
getItem(index: number): T;
/**
* A reference to the underlying vector producer that provides values for this reader.
*/
readonly vectorProducer: IVectorProducer;
}
export interface IVectorWriter {
splice(start: number, deleteCount: number, insertCount: number): void;
setItem(index: number, item: T): void;
}
/** Provides more efficient access to 1D data for vector-aware consumers. */
export interface IVectorProducer {
/**
* Acquire a reader for this vector's values and implicitly subscribe the consumer
* to value change notifications.
*
* @param consumer - The consumer to be notified of vector changes.
*/
openVector(consumer: IVectorConsumer): IVectorReader;
/**
* Unsubscribe the consumer from this vector's change notifications.
*
* @param consumer - The consumer to unregister from the vector.
*/
closeVector(consumer: IVectorConsumer): void;
}
export interface IMatrixConsumer {
/** Notification that rows have been inserted, removed, and/or replaced in the given matrix. */
rowsChanged(rowStart: number, removedCount: number, insertedCount: number, producer: IMatrixProducer): void;
/** Notification that cols have been inserted, removed, and/or replaced in the given matrix. */
colsChanged(colStart: number, removedCount: number, insertedCount: number, producer: IMatrixProducer): void;
/**
* Notification that a range of cells have been replaced in the given matrix. If the source
* matrix has the new cell values already in an array, it may optionally pass these to consumers
* as an optimization.
*/
cellsChanged(rowStart: number, colStart: number, rowCount: number, colCount: number, producer: IMatrixProducer): void;
}
export interface IMatrixReader {
readonly rowCount: number;
readonly colCount: number;
getCell(row: number, col: number): T;
/**
* A reference to the underlying matrix producer that provides values for this reader.
*/
readonly matrixProducer: IMatrixProducer;
}
export interface IMatrixWriter {
setCell(row: number, col: number, value: T): void;
}
/** Provides more efficient access to 2D data for matrix-aware consumers. */
export interface IMatrixProducer {
/**
* Acquire a reader for this matrix's values and implicitly subscribe the consumer
* to value change notifications.
*
* @param consumer - The consumer to be notified of matrix changes.
*/
openMatrix(consumer: IMatrixConsumer): IMatrixReader;
/**
* Unsubscribe the consumer from this matrix's change notifications.
*
* @param consumer - The consumer to unregister from the matrix.
*/
closeMatrix(consumer: IMatrixConsumer): void;
}
//# sourceMappingURL=types.d.ts.map