/ src / api.ts
api.ts
   1  import { ByteView } from 'multiformats'
   2  import { Task, Invocation } from './task.js'
   3  
   4  export type { ByteView, Task }
   5  
   6  /**
   7   * Generic reader interface that can be used to read `O` value form the
   8   * input `I` value. Reader may fail and error is denoted by `X` type.
   9   *
  10   * @template O - The output type of this reader
  11   * @template I - The input type of this reader.
  12   * @template X - The error type denotes failure reader may produce.
  13   */
  14  export interface TryFrom<
  15    Type extends {
  16      Self: unknown
  17      Input: unknown
  18    },
  19  > {
  20    tryFrom: (input: Type['Input']) => Result<Type['Self'], Error>
  21  }
  22  
  23  /**
  24   * Defines result type as per invocation spec
  25   *
  26   * @see https://github.com/ucan-wg/invocation/#6-result
  27   */
  28  
  29  export type Result<T = unknown, X extends {} = {}> = Variant<{
  30    ok: T
  31    error: X
  32  }>
  33  
  34  /**
  35   * Utility type for defining a [keyed union] type as in IPLD Schema. In practice
  36   * this just works around typescript limitation that requires discriminant field
  37   * on all variants.
  38   *
  39   * ```ts
  40   * type Result<T, X> =
  41   *   | { ok: T }
  42   *   | { error: X }
  43   *
  44   * const demo = (result: Result<string, Error>) => {
  45   *   if (result.ok) {
  46   *   //  ^^^^^^^^^ Property 'ok' does not exist on type '{ error: Error; }`
  47   *   }
  48   * }
  49   * ```
  50   *
  51   * Using `Variant` type we can define same union type that works as expected:
  52   *
  53   * ```ts
  54   * type Result<T, X> = Variant<{
  55   *   ok: T
  56   *   error: X
  57   * }>
  58   *
  59   * const demo = (result: Result<string, Error>) => {
  60   *   if (result.ok) {
  61   *     result.ok.toUpperCase()
  62   *   }
  63   * }
  64   * ```
  65   *
  66   * [keyed union]:https://ipld.io/docs/schemas/features/representation-strategies/#union-keyed-representation
  67   */
  68  export type Variant<U extends Record<string, unknown>> = {
  69    [Key in keyof U]: { [K in Exclude<keyof U, Key>]?: never } & {
  70      [K in Key]: U[Key]
  71    }
  72  }[keyof U]
  73  
  74  export type Tagged<T> = {
  75    [Case in keyof T]: Exclude<keyof T, Case> extends never ? T
  76    : InferenceError<'It may only contain one key'>
  77  }[keyof T]
  78  
  79  /**
  80   * Utility type for including type errors in the typescript checking. It
  81   * defines impossible type (object with non-existent unique symbol field).
  82   * This type can be used in cases where typically `never` is used, but
  83   * where some error message would be useful.
  84   */
  85  interface InferenceError<message> {
  86    [Marker]: never & message
  87  }
  88  
  89  export declare const Marker: unique symbol
  90  
  91  /**
  92   * A utility type to retain an unused type parameter `T`.
  93   * Similar to [phantom type parameters in Rust](https://doc.rust-lang.org/rust-by-example/generics/phantom.html).
  94   *
  95   * Capturing unused type parameters allows us to define "nominal types," which
  96   * TypeScript does not natively support. Nominal types in turn allow us to capture
  97   * semantics not represented in the actual type structure, without requiring us to define
  98   * new classes or pay additional runtime costs.
  99   *
 100   * For a concrete example, see {@link ByteView}, which extends the `Uint8Array` type to capture
 101   * type information about the structure of the data encoded into the array.
 102   */
 103  export interface Phantom<T> {
 104    // This field can not be represented because field name is non-existent
 105    // unique symbol. But given that field is optional any object will valid
 106    // type constraint.
 107    [Marker]?: T
 108  }
 109  
 110  export type New<T, Type = Tagged<T>> = Tagged<T>[keyof Tagged<T>] &
 111    Phantom<Type>
 112  
 113  /**
 114   * Type representing a unit value.
 115   */
 116  export interface Unit {}
 117  
 118  /**
 119   * Variable integer.
 120   */
 121  export type Integer = New<{ Integer: number }>
 122  
 123  export type Float = New<{ Float: number }>
 124  
 125  /**
 126   * Type representing a raw bytes.
 127   */
 128  export type Bytes = Uint8Array
 129  
 130  export type Null = null
 131  
 132  export type Reference = New<{ Reference: string }>
 133  
 134  export type Name = New<{ Name: string }>
 135  
 136  export type Position = New<{ Position: string }>
 137  
 138  /**
 139   * Type representing an IPLD link.
 140   */
 141  export interface Link<
 142    Data extends {} | null = {} | null,
 143    Format extends number = number,
 144    Alg extends number = number,
 145  > {
 146    ['/']: ByteView<this>
 147  }
 148  
 149  /**
 150   * All the constants in the system represented as a union of the following types.
 151   *
 152   * We are likely to introduce uint32, int8, uint8 and etc but for now we have
 153   * chosen to keep things simple.
 154   */
 155  export type Scalar =
 156    | null
 157    | boolean
 158    | bigint
 159    | Integer
 160    | Float
 161    | string
 162    | Bytes
 163    | Link
 164  
 165  /**
 166   * @deprecated Use `Scalar` instead.
 167   */
 168  export type Constant = Scalar
 169  
 170  /**
 171   * Supported primitive types. Definition utilizes `Phantom` type to describe
 172   * the type for compile type inference and `Variant` type to describe it for
 173   * the runtime inference.
 174   *
 175   * Note we denote lexical order between types via `order` field. This is used
 176   * when comparing data across types.
 177   */
 178  export type Type<T extends Scalar = Scalar> = Phantom<T> &
 179    Variant<{
 180      Null: {}
 181      Boolean: {}
 182      Integer: {}
 183      Float: {}
 184      String: {}
 185      Bytes: {}
 186      Entity: {}
 187      Name: {}
 188      Position: {}
 189      Reference: {}
 190      Unknown: {}
 191    }>
 192  
 193  // /**
 194  //  * Variable is placeholder for a value that will be ed against by the
 195  //  * query engine. It is represented as an abstract `Reader` that will attempt
 196  //  * to read arbitrary {@type Data} and return result with either `ok` of the
 197  //  * `Type` or an `error`.
 198  //  *
 199  //  * Variables will be assigned unique `bindingKey` by a query engine that will
 200  //  * be used as unique identifier for the variable.
 201  //  */
 202  // export interface Variable<T extends Constant = Constant>
 203  //   extends TryFrom<{ Self: T; Input: Constant }> {
 204  //   type: RowType
 205  //   [VARIABLE_ID]?: VariableID
 206  // }
 207  
 208  /**
 209   * Variable is placeholder for a value that will be matched against by the
 210   * query engine.
 211   */
 212  export interface Variable<T extends Scalar = Scalar> {
 213    ['?']: {
 214      type?: Type<T>
 215      id: VariableID
 216    }
 217  
 218    // is(term: Term): Conjunct
 219    // not(term: Term): Conjunct
 220  }
 221  
 222  export type VariableID = number
 223  
 224  /**
 225   * Term is either a constant or a {@link Variable}. Terms are used to describe
 226   * predicates of the query.
 227   */
 228  export type Term<T extends Scalar = Scalar> = T | Variable<T>
 229  
 230  /**
 231   * Describes association between `entity`, `attribute`, `value` of the
 232   * {@link Fact}. Each component of the {@link _Relation} is a {@link Term}
 233   * that is either a constant or a {@link Variable}.
 234   *
 235   * Query engine during execution will attempt to match {@link _Relation} against
 236   * all facts in the database and unify {@link Variable}s across them to identify
 237   * all possible solutions.
 238   */
 239  export type Pattern = readonly [
 240    entity: Term<Entity>,
 241    attribute: Term<Attribute>,
 242    value: Term<Scalar>,
 243  ]
 244  
 245  export type Is = readonly [binding: Term<Scalar>, value: Term<Scalar>]
 246  
 247  export type Clause = Variant<{
 248    // and clause
 249    And: Clause[]
 250    // or clause
 251    Or: Clause[]
 252    // negation
 253    Not: Clause
 254    // pattern match a fact
 255    Case: Pattern
 256  
 257    // rule application
 258    Rule: RuleApplication
 259    // assign bindings
 260    Is: Is
 261  
 262    Match: Formula
 263  }>
 264  
 265  export type InferCase<
 266    Methods extends Record<string, (input: any, context: any) => any> = {},
 267  > = {
 268    [Case in keyof Methods]: {
 269      Case: Case
 270      Input: Parameters<Methods[Case]>[0]
 271      Context: Parameters<Methods[Case]>[1]
 272      Output: ReturnType<Methods[Case]>
 273    }
 274  }
 275  
 276  export type DispatchCase<
 277    Methods extends Record<string, (input: {}, context: {}) => {}> = {},
 278  > = {
 279    <Case extends keyof Methods>(
 280      input: InferCase<Methods>[Case]['Input'],
 281      context: InferCase<Methods>[Case]['Context']
 282    ): InferCase<Methods>[Case]['Output']
 283  }
 284  export type Dispatch<
 285    Methods extends Record<string, (input: any, context: any) => any> = {},
 286  > = DispatchCase<Methods> & {
 287    with<Extension extends Record<string, (input: any, context: any) => any>>(
 288      extension: Extension
 289    ): Dispatch<Methods & Extension>
 290  }
 291  
 292  export type Terms = Record<string, Term> | [Term, ...Term[]] | Term
 293  
 294  /**
 295   * Row is a named set of values which by default are {@link Term}s. It is meant
 296   * to represent a non-nested tuple with named members as opposed to indexed
 297   * members.
 298   */
 299  export interface Row<T = Term> {
 300    [Key: string]: T
 301  }
 302  
 303  export type Numeric = Integer | Float
 304  
 305  /**
 306   * Describes operand of the operator.
 307   */
 308  export type Operand = Scalar | Record<string, Scalar> | [Scalar, ...Scalar[]]
 309  
 310  type EphemeralEntity =
 311    | Term<Entity>
 312    | Record<string, Term>
 313    | [Term<Entity>, ...Term<Entity>[]]
 314  
 315  export type InferOperand<T, K = T> = K extends Scalar ? Term<T & Scalar>
 316  : K extends Array<infer U extends Scalar> ? Term<U>[]
 317  : {
 318      [Key in keyof K]: T[Key & keyof T] & K[Key] extends infer U extends Scalar ?
 319        Term<U>
 320      : never
 321    }
 322  
 323  export type TypeName =
 324    | 'null'
 325    | 'boolean'
 326    | 'string'
 327    | 'bigint'
 328    | 'integer'
 329    | 'float'
 330    | 'bytes'
 331    | 'reference'
 332  
 333  export type Tuple<T> = [T, ...T[]]
 334  
 335  export type InferYield<T> = T extends Iterable<infer U> ? U : never
 336  
 337  export type InferFormula<
 338    Operator extends string,
 339    Formula extends (input: In) => Iterable<Out>,
 340    In extends Operand = Parameters<Formula>[0],
 341    Out extends Operand = InferYield<ReturnType<Formula>>,
 342  > = readonly [
 343    input: InferOperand<In>,
 344    operator: Operator,
 345    output?: InferOperand<Out>,
 346  ]
 347  
 348  import * as DataOperators from './formula/data.js'
 349  import * as TextOperators from './formula/text.js'
 350  import * as UTF8Operators from './formula/utf8.js'
 351  import * as MathOperators from './formula/math.js'
 352  
 353  export type Formula =
 354    | InferFormula<'==', typeof DataOperators.is>
 355    | InferFormula<'>', typeof DataOperators.greater>
 356    | InferFormula<'>=', typeof DataOperators.greaterOrEqual>
 357    | InferFormula<'<', typeof DataOperators.less>
 358    | InferFormula<'<=', typeof DataOperators.lessOrEqual>
 359    | InferFormula<'data/type', typeof DataOperators.type>
 360    | InferFormula<'data/refer', typeof DataOperators.refer>
 361    | InferFormula<'text/like', typeof TextOperators.like>
 362    | InferFormula<'text/length', typeof TextOperators.length>
 363    | InferFormula<'text/words', typeof TextOperators.words>
 364    | InferFormula<'text/lines', typeof TextOperators.lines>
 365    | InferFormula<'text/case/upper', typeof TextOperators.toUpperCase>
 366    | InferFormula<'text/case/lower', typeof TextOperators.toUpperCase>
 367    | InferFormula<'text/trim', typeof TextOperators.trim>
 368    | InferFormula<'text/trim/start', typeof TextOperators.trimStart>
 369    | InferFormula<'text/trim/end', typeof TextOperators.trimEnd>
 370    | InferFormula<'utf8/to/text', typeof UTF8Operators.fromUTF8>
 371    | InferFormula<'text/to/utf8', typeof UTF8Operators.toUTF8>
 372    | InferFormula<'text/includes', typeof TextOperators.includes>
 373    | InferFormula<'text/slice', typeof TextOperators.slice>
 374    | InferFormula<'text/concat', typeof TextOperators.concat>
 375    | InferFormula<'+', typeof MathOperators.addition>
 376    | InferFormula<'-', typeof MathOperators.subtraction>
 377    | InferFormula<'*', typeof MathOperators.multiplication>
 378    | InferFormula<'/', typeof MathOperators.division>
 379    | InferFormula<'%', typeof MathOperators.modulo>
 380    | InferFormula<'**', typeof MathOperators.power>
 381    | InferFormula<'math/absolute', typeof MathOperators.absolute>
 382  
 383  export type InferTerms<T extends Terms> =
 384    T extends Term<infer U> ? U
 385    : { [Key in keyof T]: T[Key] extends Term<infer U> ? U : never }
 386  
 387  export type Frame = Record<PropertyKey, Term>
 388  
 389  export type Entity = Link
 390  export type Attribute = string
 391  
 392  /**
 393   * An atomic fact in the database, associating an `entity` , `attribute` ,
 394   * `value`.
 395   *
 396   * - `entity` - The first component is `entity` that specifies who or what the fact is about.
 397   * - `attribute` - Something that can be said about an `entity` . An attribute has a name,
 398   *    e.g. "firstName" and a value type, e.g. string, and a cardinality.
 399   * - `value` - Something that does not change e.g. 42, "John", true. Fact relates
 400   *    an `entity` to a particular `value` through an `attribute`.ich
 401   */
 402  export interface Fact<
 403    T extends The = The,
 404    Of extends Entity = Entity,
 405    Is extends Scalar = Scalar,
 406  > {
 407    the: The
 408    of: Of
 409    is: Is
 410  }
 411  
 412  /**
 413   * An atomic {@link Fact} with a `cause` field providing a causal relationship
 414   * that acts like timestamp.
 415   */
 416  export interface Datum<
 417    T extends The = The,
 418    Of extends Entity = Entity,
 419    Is extends Scalar = Scalar,
 420  > extends Fact<T, Of, Is> {
 421    cause: Entity
 422  }
 423  
 424  /**
 425   * Set of {@link Fact}s associating several attributes with the same new entity.
 426   * Each key represents an `attribute` and corresponding value represents it's
 427   * `value`.
 428   *
 429   * If value is an array of {@link Scalar}s then entity is associated each
 430   * value with a same attribute.
 431   *
 432   * If value is an `Instantiation` then entity is associated with a new entity
 433   * that is described by that `Instantiation`.
 434   *
 435   * If value is an array of `Instantiation`s then entity is associated with a
 436   * each `Instantiation` in the array with an attribute corresponding to the
 437   * key.
 438   */
 439  export interface DataImport {
 440    [Key: string]: Scalar | Scalar[] | DataImport | DataImport[]
 441  }
 442  
 443  export interface FactsSelector {
 444    the?: Attribute
 445    of?: Entity
 446    is?: Scalar
 447  }
 448  
 449  export type Instruction = Variant<{
 450    assert: Fact
 451    retract: Fact
 452  }>
 453  
 454  export interface Transaction extends Iterable<Instruction> {}
 455  
 456  export interface Transactor<Ok extends {} = {}> {
 457    transact(transaction: Transaction): Task<Ok, Error>
 458  }
 459  
 460  export interface Querier {
 461    select(selector?: FactsSelector): Task<Datum[], Error>
 462  }
 463  
 464  export type Proposition = Row<Variable> & {
 465    this?: Variable
 466  }
 467  
 468  export type Rule<Match extends Proposition = Proposition> = DeductiveRule<Match>
 469  
 470  export interface DeductiveRule<Match extends Proposition = Proposition> {
 471    readonly match: Match
 472    readonly when?: When<Conjunct | Recur>
 473  }
 474  
 475  export type Constraint = SelectForm | MatchRule | SystemOperator
 476  
 477  export interface Negation {
 478    not: Constraint
 479  
 480    operator?: undefined
 481    fact?: undefined
 482    rule?: undefined
 483    match?: undefined
 484    recur?: undefined
 485  }
 486  
 487  export type Conjunct = Constraint | Negation
 488  export type Recur<Match extends Proposition = Proposition> = {
 489    recur: RuleBindings<Match>
 490  
 491    operator?: undefined
 492    fact?: undefined
 493    rule?: undefined
 494    match?: undefined
 495    not?: undefined
 496  }
 497  
 498  export type Every<T extends Conjunct | Recur = Conjunct> = Iterable<T>
 499  export interface Some<T extends Conjunct | Recur = Conjunct> {
 500    readonly [Case: string]: Every<T>
 501  }
 502  
 503  export type When<T extends Conjunct | Recur = Conjunct> = Some<T>
 504  
 505  export type WhenBuilder<T extends RuleDescriptor> =
 506    | SomeBuilder<T>
 507    | EveryBuilder<T>
 508  
 509  export type SomeBuilder<T extends RuleDescriptor> = (
 510    variables: InferSchemaAttributes<T> & { _: Variable<any> }
 511  ) => SomeView
 512  export type EveryBuilder<T extends RuleDescriptor> = (
 513    variables: InferSchemaAttributes<T> & { _: Variable<any> }
 514  ) => EveryView
 515  
 516  export type ProjectionBuilder<
 517    T extends RuleDescriptor,
 518    Projection extends Selector,
 519  > = (variables: InferSchemaAttributes<T>) => Projection
 520  
 521  export type WhenView = EveryView | SomeView
 522  export type EveryView = ConjunctView[]
 523  export type ConjunctView = Conjunct | MatchView<unknown> | void
 524  
 525  export interface SomeView {
 526    [Case: string]: EveryView
 527  }
 528  
 529  export interface MatchRule<Match extends Proposition = Proposition> {
 530    readonly match: Partial<RuleBindings<Match>>
 531    readonly rule: Rule<Match>
 532  
 533    operator?: undefined
 534    fact?: undefined
 535  
 536    not?: undefined
 537  
 538    recur?: undefined
 539  }
 540  
 541  export interface Syntax {
 542    toJSON(): object
 543    toDebugString(): string
 544  
 545    plan(scope: Scope): EvaluationPlan
 546  }
 547  
 548  export interface SelectSyntax extends Syntax, SelectForm {}
 549  
 550  export interface RuleSyntax<Match extends Proposition = Proposition>
 551    extends Syntax,
 552      DeductiveRule<Match> {
 553    plan(scope: Scope): RulePlan
 554  }
 555  
 556  export interface RuleApplicationSyntax<Match extends Proposition = Proposition>
 557    extends Syntax,
 558      MatchRule<Match> {
 559    negate(): NegationSyntax
 560    plan(scope: Scope): RuleApplicationPlan<Match>
 561    prepare(): RuleApplicationPlan<Match>
 562  }
 563  
 564  export interface DeductiveRuleSyntax<Match extends Proposition = Proposition>
 565    extends Syntax,
 566      DeductiveRule<Match> {
 567    apply(terms?: RuleBindings<Match>): RuleApplicationSyntax<Match>
 568  }
 569  
 570  export interface RuleRecursionSyntax<Match extends Proposition = Proposition>
 571    extends Recur<Match> {}
 572  
 573  export interface NegationSyntax extends Syntax, Negation {}
 574  
 575  export interface SelectForm {
 576    match: Select
 577  
 578    /**
 579     * The `fact` field is reserved for the future use where it could be used to
 580     * specify data source or
 581     */
 582    fact?: {}
 583  
 584    /**
 585     * The `rule` field can not be defined in order to be distinguishable
 586     * from the {@link RuleApplication} type.
 587     */
 588    rule?: undefined
 589  
 590    /**
 591     * The `not` field can not be defined in order to be distinguishable
 592     * from the {@link Negation} type.
 593     */
 594    not?: undefined
 595  
 596    operator?: undefined
 597  
 598    recur?: undefined
 599  }
 600  
 601  export type Select = SelectByAttribute | SelectByEntity | SelectByValue
 602  
 603  type SelectBy = {
 604    /**
 605     * {@link Term} representing a relation an entity `of` has with the value
 606     * `is`. In RDF notation this will correspond to a predicate.
 607     */
 608    the?: Term<Attribute>
 609  
 610    /**
 611     * {@link Term} representing the entity / subject.
 612     */
 613    of?: Term<Entity>
 614  
 615    /**
 616     * {@link Term} representing the value of the attribute on the entity (denoted
 617     * by `of`). In RDF notation this will correspond to an object.
 618     */
 619    is?: Term<Scalar>
 620  
 621    /**
 622     * The `this` field is reserved for the future use where it could be used to
 623     * bind the merkle reference for this fact.
 624     */
 625    this?: never
 626  }
 627  
 628  interface SelectByAttribute extends SelectBy {
 629    // Selection by attribute requires an attribute to be specified.
 630    the: Term<Attribute>
 631  }
 632  
 633  interface SelectByEntity extends SelectBy {
 634    // Selection by entity requires an entity to be specified.
 635    of: Term<Entity>
 636  }
 637  
 638  interface SelectByValue extends SelectBy {
 639    // Selection by value requires a value to be specified.
 640    is: Term<Scalar>
 641  }
 642  
 643  export interface FactSelection {
 644    select: Pattern
 645    rule?: undefined
 646  }
 647  
 648  export interface FormulaApplication {
 649    compute: string
 650    from: Pattern
 651  }
 652  
 653  export type InferFormulaApplication<
 654    Operator extends string,
 655    Formula extends (input: In) => Iterable<Out>,
 656    In extends Operand = Parameters<Formula>[0],
 657    Out extends Operand = InferYield<ReturnType<Formula>>,
 658  > = {
 659    compute: Operator
 660    from: InferOperand<In>
 661    to?: InferOperand<Out>
 662  }
 663  
 664  // export interface InductiveRule<
 665  //   Match extends Conclusion = Conclusion,
 666  //   Repeat extends Match = Match,
 667  // > {
 668  //   match: Match
 669  //   when: Conjuncts
 670  //   repeat: Repeat
 671  //   while: When
 672  // }
 673  
 674  export type SystemOperator = {
 675    [Operator in keyof SystemOperators]: MatchOperator<
 676      SystemOperators[Operator],
 677      Operator
 678    >
 679  }[keyof SystemOperators]
 680  
 681  export type MatchOperator<Formula = unknown, Identifier = Formula> = {
 682    readonly match: InferFormulaMatch<Formula>
 683    readonly operator: Identifier
 684  
 685    formula?: Formula
 686  
 687    fact?: undefined
 688    rule?: undefined
 689    not?: undefined
 690    recur?: undefined
 691  }
 692  
 693  export type InferFormulaMatch<F> =
 694    F extends (input: infer In) => Iterable<infer Out> ? FormulaMatch<In, Out>
 695    : never
 696  
 697  export type FormulaMatch<In, Out> = InferCells<In, 'of'> &
 698    Partial<InferCells<Out, 'is'>>
 699  
 700  export type InferCells<In, DefaultName extends string> = In extends Scalar ?
 701    { [key in DefaultName]: Term<In> }
 702  : In extends any[] ?
 703    {
 704      [key in DefaultName]: {
 705        [Key in keyof In]: In[Key] extends Scalar ? Term<In[Key]> : never
 706      }
 707    }
 708  : {
 709      [Key in keyof In]: In[Key] extends Scalar ? Term<In[Key]> : never
 710    }
 711  
 712  type SystemOperators = {
 713    '==': typeof DataOperators.is
 714    '>=': typeof DataOperators.greaterOrEqual
 715    '>': typeof DataOperators.greater
 716    '<': typeof DataOperators.less
 717    '<=': typeof DataOperators.lessOrEqual
 718    '!': typeof DataOperators.not
 719    'data/type': typeof DataOperators.type
 720    'data/refer': typeof DataOperators.refer
 721    'text/like': typeof TextOperators.like
 722    'text/length': typeof TextOperators.length
 723    'text/words': typeof TextOperators.words
 724    'text/lines': typeof TextOperators.lines
 725    'text/case/upper': typeof TextOperators.toUpperCase
 726    'text/case/lower': typeof TextOperators.toUpperCase
 727    'text/trim': typeof TextOperators.trim
 728    'text/trim/start': typeof TextOperators.trimStart
 729    'text/trim/end': typeof TextOperators.trimEnd
 730    'utf8/to/text': typeof UTF8Operators.fromUTF8
 731    'text/to/utf8': typeof UTF8Operators.toUTF8
 732    'text/includes': typeof TextOperators.includes
 733    'text/slice': typeof TextOperators.slice
 734    'text/concat': typeof TextOperators.concat
 735    '+': typeof MathOperators.addition
 736    '-': typeof MathOperators.subtraction
 737    '*': typeof MathOperators.multiplication
 738    '/': typeof MathOperators.division
 739    '%': typeof MathOperators.modulo
 740    '**': typeof MathOperators.power
 741    'math/absolute': typeof MathOperators.absolute
 742  }
 743  
 744  export type RuleBindings<Case extends Proposition = Proposition> = {
 745    [Key in keyof Case]: Term<Scalar>
 746  }
 747  
 748  export interface RuleApplication<Match extends Proposition = Proposition> {
 749    // ⚠️ This is actually Partial<RuleBindings<Match>> but we still type it
 750    // without `Partial` because at the type level we have no good way of
 751    // omitting variables that could be ignored
 752    match: RuleBindings<Match>
 753    rule: Rule<Match>
 754  }
 755  
 756  export type InferRuleMatch<Case extends Proposition> = {
 757    [Key in keyof Case]: Case[Key] extends Variable<infer U> ?
 758      U extends any ?
 759        Term<Scalar>
 760      : Term<U>
 761    : never
 762  }
 763  
 764  export interface Variables extends Record<PropertyKey, Variable> {}
 765  
 766  export interface Bindings extends Record<PropertyKey, Term> {}
 767  
 768  /**
 769   * Selection describes set of (named) variables that query engine will attempt
 770   * to find values for that satisfy the query.
 771   */
 772  // export interface Selector
 773  //   extends Record<PropertyKey, Term | Term[] | Selector | Selector[]> {}
 774  export type Selector = AggregateSelector | NamedSelector
 775  
 776  /**
 777   * Where clause describes the conditions that must be satisfied for the query
 778   * to return a result.
 779   */
 780  export type Where = Iterable<Clause>
 781  
 782  /**
 783   * Query that can be evaluated against the database.
 784   */
 785  export type Query<Select extends Selector = Selector> = {
 786    select: Select
 787    where: Where
 788  }
 789  
 790  export type AggregateSelector = [Selector | Term]
 791  
 792  export interface NamedSelector extends Record<string, Selector | Term> {}
 793  
 794  export interface Variables extends Record<string, Term> {}
 795  
 796  export type Selection = Selector | Variable<Link<Bindings>>
 797  
 798  export interface Not {
 799    not: Constraint
 800    match?: void
 801    rule?: void
 802  }
 803  
 804  export type Combinator = Variant<{}>
 805  
 806  export type Confirmation = Variant<{
 807    ok: Unit
 808    error: Error
 809  }>
 810  
 811  export type InferBindings<Selection extends Selector> = {
 812    [Key in keyof Selection]: Selection[Key] extends Term<infer T> ? T
 813    : Selection[Key] extends Term<infer T>[] ? T[]
 814    : Selection[Key] extends Selector[] ? InferBindings<Selection[Key][0]>[]
 815    : Selection[Key] extends Selector ? InferBindings<Selection[Key]>
 816    : never
 817  }
 818  
 819  export type InferTerm<T extends Term> = T extends Term<infer U> ? U : never
 820  
 821  export interface Analysis {
 822    dependencies: Set<VariableID>
 823    binds: Set<VariableID>
 824    cost: number
 825  }
 826  
 827  export interface Unplannable extends Error {
 828    error: this
 829  }
 830  
 831  export interface EvaluationPlan {
 832    evaluate(context: EvaluationContext): Task<MatchFrame[], EvaluationError>
 833  }
 834  
 835  /**
 836   * Represents a local variable references to a remote variables. This is n:1
 837   * relation meaning multiple local variables may point to the same remote one
 838   * but local variable can point to at most one remote variable.
 839   */
 840  export type Cursor = Map<Variable, Set<Variable>>
 841  
 842  /**
 843   * Represents set of bound variables.
 844   */
 845  export type QueryBindings = Map<Variable, Scalar>
 846  
 847  export interface Scope {
 848    references: Cursor
 849    bindings: QueryBindings
 850  }
 851  
 852  export type Plan = Unplannable | EvaluationPlan
 853  
 854  export interface RulePlan extends EvaluationPlan {
 855    cost: number
 856    match: Proposition
 857  }
 858  
 859  export interface RuleApplicationPlan<Match extends Proposition>
 860    extends EvaluationPlan {
 861    cost: number
 862    toJSON(): object
 863    query(source: { from: Querier }): Task<MatchFrame[], Error>
 864  }
 865  
 866  export interface EvaluationContext {
 867    selection: MatchFrame[]
 868    source: Querier
 869    self: RulePlan
 870    recur: [MatchFrame, MatchFrame][] // Array of pairs [nextBindings, originalContext] for recursive processing
 871  }
 872  
 873  export interface Evaluator extends EvaluationContext {
 874    evaluate(context: EvaluationContext): Task<Bindings[], EvaluationError>
 875  }
 876  
 877  export interface EvaluationError extends Error {}
 878  
 879  export type $ = Variable<any> &
 880    Record<PropertyKey, Variable<any>> & {
 881      new (): $
 882      (): $
 883  
 884      name: Variable<string>
 885      length: Variable<number>
 886      prototype: Variable
 887    }
 888  
 889  export interface MatchFrame extends Map<Variable, Scalar> {
 890    parent?: MatchFrame
 891  }
 892  
 893  /**
 894   * Describes the effects that clause performs when evaluated.
 895   */
 896  export interface Effects {
 897    /**
 898     * Query an underlying data source for facts.
 899     */
 900    readonly query: readonly QueryEffect[]
 901    /**
 902     * Evaluate underlying clause in a loop potentially many times.
 903     */
 904    readonly loop: readonly LoopEffect[]
 905  }
 906  
 907  /**
 908   * Describes looping effect, meaning that that clause with this effect
 909   * may be evaluated multiple times. In a future we may capture more details
 910   * about the loop.
 911   */
 912  export interface LoopEffect {}
 913  
 914  export interface QueryEffect {
 915    select: Pattern
 916  }
 917  
 918  export type ObjectDescriptor = {
 919    [Key: string]: TypeDescriptor
 920  }
 921  
 922  export type ArrayDescriptor = [TypeDescriptor] & {
 923    Object?: undefined
 924    Rule?: undefined
 925  }
 926  
 927  export type UnknownDescriptor = {
 928    Unknown: {}
 929  }
 930  
 931  export type TypeDescriptor =
 932    | Scalar
 933    | ScalarConstructor
 934    | Type
 935    | ObjectDescriptor
 936    | ArrayDescriptor
 937  
 938  export type InferDescriptorType<T> =
 939    T extends null ? null
 940    : T extends { Null: {} } ? null
 941    : T extends BooleanConstructor ? boolean
 942    : T extends { Boolean: {} } ? boolean
 943    : T extends boolean ? T
 944    : T extends StringConstructor ? string
 945    : T extends { String: {} } ? string
 946    : T extends string ? T
 947    : T extends NumberConstructor ? Integer
 948    : T extends { Integer: {} } ? Integer
 949    : T extends { Float: {} } ? Float
 950    : T extends number ? T
 951    : T extends BigIntConstructor ? bigint
 952    : T extends bigint ? T
 953    : T extends Uint8ArrayConstructor ? Bytes
 954    : T extends { Bytes: {} } ? Bytes
 955    : T extends Uint8Array ? T
 956    : T extends ObjectConstructor ? Entity
 957    : T extends UnknownDescriptor ? Scalar
 958    : never
 959  
 960  export type ScalarConstructor =
 961    | BooleanConstructor
 962    | StringConstructor
 963    | NumberConstructor
 964    | BigIntConstructor
 965    | Uint8ArrayConstructor
 966    | ObjectConstructor
 967  
 968  export type ScalarDescriptor = Variant<{
 969    Null: {}
 970    Boolean: {}
 971    String: {}
 972    Int32: {}
 973    Float32: {}
 974    Int64: {}
 975    Bytes: {}
 976    Reference: {}
 977    Entity: {}
 978    Unknown: {}
 979  }> & { Object?: undefined; Fact?: undefined; Scalar?: undefined }
 980  
 981  export type ModelDescriptor<
 982    Descriptor extends ObjectDescriptor = ObjectDescriptor,
 983  > = {
 984    Object: Descriptor
 985  }
 986  
 987  export type InferTypeTerms<T, U = T> = T extends Scalar ?
 988    Term<U extends Scalar ? U : never>
 989  : unknown extends T ? Term
 990  : InferEntityTerms<T>
 991  
 992  export type TypeTest<T> = T extends Scalar ? Box<T> : never
 993  
 994  export type Box<T> = {
 995    t: T
 996  }
 997  export type InferEntityTerms<T> = Partial<
 998    { this: Term<Entity> } & { [Key in keyof T]: InferTypeTerms<T[Key]> }
 999  >
1000  
1001  export type InferTypeVariables<T, U = T> = T extends Scalar ?
1002    Variable<U extends Scalar ? U : never>
1003  : unknown extends T ? Variable<any>
1004  : { this: Term<Entity> } & {
1005      [Key in keyof T]: InferTypeVariables<T[Key]>
1006    }
1007  
1008  export interface RuleDescriptor {
1009    [key: string]: ScalarConstructor | Type | Scalar
1010  }
1011  
1012  export interface FactSchema extends RuleDescriptor {
1013    this: ObjectConstructor
1014  }
1015  
1016  export type InferSchemaAttributes<Schema> = {
1017    [Key in keyof Schema]: Variable<InferDescriptorType<Schema[Key]>>
1018  }
1019  
1020  export type InferSchemaTerms<T> = {
1021    [Key in keyof T]: Term<InferDescriptorType<T[Key]>>
1022  }
1023  
1024  export type InferFact<Schema extends RuleDescriptor> = {
1025    [Key in keyof Schema]: InferDescriptorType<Schema[Key]>
1026  }
1027  
1028  export type InferRuleAssert<T extends RuleDescriptor> = {
1029    [Key in keyof T as T[Key] extends Scalar ? never : Key]: T[Key] extends (
1030      Scalar
1031    ) ?
1032      undefined
1033    : InferDescriptorType<T[Key]>
1034  }
1035  
1036  export type ScalarTerms<T extends Scalar> = Term<T> | { this: Term<T> }
1037  
1038  export interface MatchView<Model = unknown>
1039    extends Iterable<Recur | Conjunct> {}
1040  
1041  export interface QueryView<Model> extends Iterable<Conjunct> {
1042    select(source: { from: Querier }): Invocation<Model[], Error>
1043  }
1044  
1045  export type EntityModel<T extends {} = {}> = {
1046    this: Entity
1047  } & T
1048  
1049  export type FactModel = {
1050    the?: The
1051    of?: EntityModel
1052    is?: Scalar | {}
1053  }
1054  
1055  export interface RuleApplicationView<View>
1056    extends RuleApplication,
1057      MatchView<View> {
1058    select(source: { from: Querier }): Invocation<View[], Error>
1059  }
1060  
1061  export type EntityView<Model> = Model & {
1062    this: Entity
1063  }
1064  
1065  export type TermTree = {
1066    [Key: string]: Term | TermTree
1067  }
1068  
1069  export type The = `${string}/${string}`
1070  
1071  export interface FactCells {
1072    the: Variable<string>
1073    of: Variable<Entity>
1074    is: Variable<Scalar>
1075  }
1076  
1077  export type Descriptor = null | boolean
1078  
1079  interface TextVariable extends Variable<string> {
1080    like(pattern: Term<string>): Constraint
1081    toUpperCase(is: Term<string>): Constraint
1082    toLowerCase(is: Term<string>): Constraint
1083  }
1084  
1085  export type InferFactTerms<T extends FactSchema> = {
1086    [Key in keyof Omit<T, 'this'>]: Term<InferDescriptorType<T[Key]>>
1087  } & {
1088    this?: Term<Entity>
1089  }
1090  
1091  export type InferAssert<Schema extends FactSchema> = InferFact<
1092    Omit<Schema, 'this'>
1093  > & { this?: Entity }
1094  
1095  export type InferClaimTerms<Schema extends FactSchema> = InferFactTerms<Schema>
1096  
1097  export type InferAttributes<Schema> = {
1098    [Key in keyof Schema]: Variable<InferDescriptorType<Schema[Key]>>
1099  }
1100  
1101  export interface Premise<The extends string, Schema extends FactSchema> {
1102    readonly the: The
1103    readonly attributes: InferAttributes<Schema & { this: ObjectDescriptor }>
1104    readonly schema: Schema
1105  }
1106  
1107  export interface Conclusion<
1108    Fact,
1109    The extends string,
1110    Schema extends FactSchema,
1111  > {
1112    assert(fact: InferAssert<Schema>): Fact
1113  }
1114  
1115  export interface Claim<
1116    Fact,
1117    The extends string,
1118    Schema extends FactSchema,
1119    Context extends RuleDescriptor,
1120  > extends Relation<Fact, The, Schema> {
1121    the: The
1122    attributes: InferSchemaAttributes<Schema>
1123    schema: Schema
1124  
1125    /**
1126     * Defines temporary variables made available in the {@link when} /
1127     * {@link where} builder methods so they can be used inside the rule body.
1128     */
1129    with<Extension extends Exclude<RuleDescriptor, Schema & Context>>(
1130      extension: Extension
1131    ): Claim<Fact, The, Schema, Context & Extension>
1132  
1133    /**
1134     * Defines a rule that concludes fact corresponding to this premise whenever
1135     * all of the predicates returne by `derive` method are true. This is a
1136     * shortuct for {@link when} which is convinient in cases with a single
1137     * branch.
1138     */
1139    where(
1140      derive: EveryBuilder<Schema & Context>
1141    ): Deduction<Fact, The, Schema, {}>
1142  
1143    /**
1144     * Defines a rule that deduces this fact whenever any of the branches are true.
1145     * Takes a `build` function that will be given set of variables corresponding
1146     * to the fact members which must return object where keys represent disjuncts
1147     * and values are arrays representing conjuncts for those disjuncts. In other
1148     * works each member of the returned object represent OR branches where each
1149     * branch is an AND joined predicates by passed variables.
1150     */
1151    when(derive: SomeBuilder<Schema & Context>): Deduction<Fact, The, Schema, {}>
1152  
1153    map<View>(mapper: (fact: Fact) => View): Claim<View, The, Schema, Context>
1154  
1155    aggregate<State, View>(
1156      compressor: Aggregator<View, Fact, State>
1157    ): Aggregation<View, Fact, The, Schema>
1158  }
1159  
1160  export interface Aggregator<Output, Input, State> {
1161    open(): State
1162    merge(state: State, input: Input): State
1163    close(state: State): Output
1164  }
1165  
1166  export interface Aggregation<View, Fact, The, Schema extends FactSchema> {
1167    /**
1168     * Creates a predicate that matches this premise. This is just like
1169     * {@link match} except it requires passing all members explicitly,
1170     * this allows type checker to ensure that no members are left out by
1171     * accident.
1172     */
1173    (terms?: InferFactTerms<Schema>): Aggregate<View>
1174  
1175    /**
1176     * Creates predicate that matches this premise. It may be passed terms for
1177     * the subset of the fact members. Omitted members are treated as `_` meaning
1178     * any value would satisfy them.
1179     */
1180    match(terms?: Partial<InferFactTerms<Schema>>): Aggregate<View>
1181  
1182    /**
1183     * Creates negation (anti-join) that will omit all the facts that match
1184     * the premise with the given terms.
1185     */
1186    not(terms: Partial<InferSchemaTerms<Schema>>): NegationPredicate
1187  
1188    /**
1189     * Creates an assertion for this the fact denoted by this premise, which can
1190     * be transacted in the DB.
1191     */
1192    assert(fact: InferAssert<Schema>): Fact
1193  
1194    the: The
1195    schema: Schema
1196  }
1197  
1198  export interface Aggregate<View> extends Iterable<Recur | Conjunct> {
1199    query(source: { from: Querier }): Invocation<View, Error>
1200  }
1201  
1202  export interface NegationPredicate extends Iterable<Negation> {}
1203  
1204  /**
1205   *
1206   */
1207  export interface Predicate<Fact, The extends string, Schema extends FactSchema>
1208    extends Iterable<Recur | Conjunct> {
1209    query(source: { from: Querier }): Invocation<Fact[], Error>
1210  }
1211  
1212  export interface Assertion extends Iterable<{ assert: Fact }> {}
1213  
1214  export type FactView<
1215    The extends string,
1216    Schema extends FactSchema,
1217  > = InferFact<Schema> & {
1218    the: The
1219    toJSON(): InferFact<Schema> & { the: The }
1220  } & Assertion &
1221    Retractable
1222  
1223  export interface Retractable {
1224    retract(): Iterable<{ retract: Fact }>
1225  }
1226  
1227  export interface Relation<Fact, The extends string, Schema extends FactSchema> {
1228    /**
1229     * Creates a predicate that matches this premise. This is just like
1230     * {@link match} except it requires passing all members explicitly,
1231     * this allows type checker to ensure that no members are left out by
1232     * accident.
1233     */
1234    (terms?: InferFactTerms<Schema>): Predicate<Fact, The, Schema>
1235  
1236    /**
1237     * Creates predicate that matches this premise. It may be passed terms for
1238     * the subset of the fact members. Omitted members are treated as `_` meaning
1239     * any value would satisfy them.
1240     */
1241    match(terms?: Partial<InferFactTerms<Schema>>): Predicate<Fact, The, Schema>
1242  
1243    /**
1244     * Creates negation (anti-join) that will omit all the facts that match
1245     * the premise with the given terms.
1246     */
1247    not(terms: Partial<InferSchemaTerms<Schema>>): NegationPredicate
1248  
1249    /**
1250     * Creates an assertion for this the fact denoted by this premise, which can
1251     * be transacted in the DB.
1252     */
1253    assert(fact: InferAssert<Schema>): Fact
1254  }
1255  
1256  export interface Deduction<
1257    Fact,
1258    The extends string,
1259    Schema extends FactSchema,
1260    Context extends RuleDescriptor,
1261  > extends Claim<Fact, The, Schema, Context> {
1262    inductive: Relation<Fact, The, Schema>
1263    /**
1264     * Creates an assertion for this the fact denoted by this premise, which can
1265     * be transacted in the DB.
1266     */
1267    claim(fact: InferFactTerms<Schema>): Iterable<Conjunct>
1268  
1269    select<Terms extends Selector>(
1270      derive: ProjectionBuilder<Schema & Context, Terms>
1271    ): Projection<Schema, Terms>
1272  
1273    map<View>(mapper: (fact: Fact) => View): Deduction<View, The, Schema, Context>
1274  }
1275  
1276  export interface Projection<Schema extends FactSchema, Terms extends Selector> {
1277    (terms?: InferSchemaTerms<Schema>): SelectionPredicate<Terms>
1278    match(terms?: Partial<InferSchemaTerms<Schema>>): SelectionPredicate<Terms>
1279  }
1280  
1281  export interface SelectionPredicate<Terms extends Selector>
1282    extends Iterable<Recur | Conjunct> {
1283    query(source: { from: Querier }): Invocation<InferBindings<Terms>[], Error>
1284  }