gabby-query-protocol-lib

Library Support for the Gabby Query Protocol

Usage no npm install needed!

<script type="module">
  import gabbyQueryProtocolLib from 'https://cdn.skypack.dev/gabby-query-protocol-lib';
</script>

README

gabby-query-protocol-lib

codecov awesome Gabby Query Protocol Total alerts Language grade: JavaScript

This package is the base library for Gabby Query Protocol. It mostly focuses on the Predicate Formula aspects of GQP.

Installation

Using npm:

$ npm install gabby-query-protocol-lib

Documentation

This Repo's docs

Project's docs

./examples/* contains executable snippets found in documentation.

Description

This is a sub-project the Gabby Query Protocol. The purpose of this project is to provide utilities for building Predicate Trees.

Terminology

Predicate - a simple expression that evaluates to to true or false. Properties: operator, subjectId, value. Example: {subjectId: "firstname", operator: "$eq", value: "barney"}.

Predicate Junction - an disjunction or conjunction expression. Properties: operator Example: {operator: "$and"}.

Predicate Formula - coherent collection of predicate statements.

Predicate Tree - The shape (coherent part) of the predicate statements. Externally this is json representation of a Directed Tree Graph. (I had better luck googling 'directed tree'). Each node exactly 1 parent, except root. Any branch will have 2 or more children, AKA: no single child rule. This is differs from traditional directed trees.

Predicate Tree

Main Classes/Types

  • see: src/common/type.ts - for pseudo-atomic types. Too many to list here
  • See Repo documentation for further explanation.
  • Examples (./examples/*ts) have working examples.

IPredicateTree

export interface IPredicateTree {
  // visitor pattern.
  acceptVisitor(visitor: IVisitor<TPredicateNode>): void;

  appendPredicate(parentId: string, predicate: TPredicateNode): string;

  getChildrenIds(predicateId: string): string[];

  // returns TPredicateProperties | TPredicateJunctionPropsWithChildIds | null
  getPredicateById(predicateId: string): TPredicateNode | null;

  getPredicateByIdOrThrow(predicateId: string): TPredicateNode;

  // getPredicate - as TPredicateJunctionPropsWithChildIds  *preferred*
  getPredicateJunctionPropsById(
    predicateId: string
  ): TPredicateJunctionPropsWithChildIds | null;

  // getPredicate - as TPredicateProperties  *preferred*
  getPredicatePropsById(predicateId: string): TPredicateProperties | null;

  getPredicatePropsByIdOrThrow(predicateId: string): TPredicateProperties;

  getPredicateJunctionPropsByIdOrThrow(
    predicateId: string
  ): TPredicateJunctionPropsWithChildIds;

  isBranch(predicateId: string): boolean;

  removePredicate(predicateId: string): void;

  // for update purposes, alias coming soon.
  replacePredicate(predicateId: string, predicate: TPredicateNode): void;
  rootNodeId: string;

  toJson(): TSerializedPredicateTree;
}

Leaf Predicate (TPredicateProperties)

type TPredicateProperties = {
  subjectId: string;
  operator: TPredicateOperator;
  value: number | string; // this is the instance of Predicate, the type of this is
  // determined by the subject definition {subjectId, validOps, datatype...}
};

Branch Predicate (TPredicatePropertiesJunction)

type TPredicatePropertiesJunction = {
  operator: TPredicateJunctionOperator;
};

IPredicateSubjectDictionary

Should only be readOnly operators used for default values and validation.

export interface IPredicateSubjectDictionary
  extends IExportToJson<IPredicateSubjectDictionary, TPredicateSubjectDictionaryJson> {
  getOptionsList(subjectId: string): TPredicateSubjectOptionsList;
  // getAllSubjects(): TPredicateSubjectDictionary; // internal dictionary
  getSubjectIds(): string[];
  getSubject(subjectId: string): TPredicateSubjectWithId;
  //   getSubjectOrThrow(subjectId: string): TPredicateSubjectWithId;
  getDefaultSubject(): TPredicateSubjectWithId;
  makeEmptyPredicate(): TPredicateProperties;
  getColumns(): TPredicateSubjectAsColumnDefinition[];
  toJson(): TPredicateSubjectDictionaryJson;
}

Example

import { PredicateFormulaEditorFactory, TPredicateProperties } from "../src";
import { EXAMPLE_JSON_BLUE_SKIES } from "../src";

const { predicateTreeJson } = EXAMPLE_JSON_BLUE_SKIES;
const { predicateSubjectsDictionaryJson: subjectDictionaryJson } =
  EXAMPLE_JSON_BLUE_SKIES;

export const predicateFormula = PredicateFormulaEditorFactory.fromJson({
  predicateTreeJson: predicateTreeJson,
  // predicateTreeJson is optional.
  // if undefined tree will be empty (like new document, start from scratch)

  subjectDictionaryJson: subjectDictionaryJson,
});

const newPredicate: TPredicateProperties = {
  operator: "$eq",
  subjectId: "firstName",
  value: "Barney",
};

const newPredicateId = predicateFormula.predicatesAppend(
  predicateFormula.rootNodeId,
  newPredicate
);

const toBeUpdatedPredicate = predicateFormula.predicatesGetPropertiesById(newPredicateId);
toBeUpdatedPredicate.value = "Betty";

predicateFormula.predicatesReplace(newPredicateId, toBeUpdatedPredicate);
console.log(JSON.stringify(predicateFormula.toJson(), null, 2));

npm run

gabby:build
Transpile to js includes source map and types, target directory './dist'

gabby:pack
Create npm friendly tgz package