This is the main TemplateProcessor class.

Remarks

The TemplateProcessor class is responsible for processing templates and interfacing with your program that may provide changing inputs over time and react to changes with callbacks. Many examples can be found in src/test/TemplateProcessor.test.js

Example: Initialize a simple template stored in local object 'o'

//initialize a simple template stored in local object 'o'
test("test 6", async () => {
const o = {
"a": 10,
"b": [
"../${a}",
]
};
const tp = new TemplateProcessor(o);
await tp.initialize();
expect(o).toEqual({
"a": 10,
"b": [10]
});
});

Example: Pass the TemplateProcessor a context containing a function named `nozzle` and a variable named `ZOINK`

//Pass the TemplateProcessor a context containing a function named `nozzle` and a variable named `ZOINK`
test("context", async () => {
const nozzle = (something) => "nozzle got some " + something;
const context = {"nozzle": nozzle, "ZOINK": "ZOINK"}
const tp = new TemplateProcessor({
"a": "${$nozzle($ZOINK)}"
}, context);
await tp.initialize();
expect(tp.output).toEqual(
{
"a": "nozzle got some ZOINK",
}
);
});

Example: Parse template from JSON or YAML

    it('should correctly identify and parse JSON string', async () => {
const jsonString = '{"key": "value"}';
const instance = TemplateProcessor.fromString(jsonString);
await instance.initialize();
expect(instance).toBeInstanceOf(TemplateProcessor);
expect(instance.output).toEqual({ key: "value" }); // Assuming parsedObject is publicly accessible
});

it('should correctly identify and parse YAML string using ---', async () => {
const yamlString = `---
key: value`;
const instance = TemplateProcessor.fromString(yamlString);
await instance.initialize();
expect(instance).toBeInstanceOf(TemplateProcessor);
expect(instance.output).toEqual({ key: "value" });
});

Example: React to changes using data change callbacks on various locations in the template

 test("test 1", async () => {
const tp = new TemplateProcessor({
"a": "aaa",
"b": "${a}"
});
await tp.initialize();
const received = [];
tp.setDataChangeCallback("/a", (data, jsonPtr) => {
received.push({data, jsonPtr})
});
tp.setDataChangeCallback("/b", (data, jsonPtr) => {
received.push({data, jsonPtr})
});
tp.setDataChangeCallback("/", (data, jsonPtr) => {
received.push({data, jsonPtr})
});
await tp.setData("/a", 42);
expect(received).toEqual([
{
"data": 42,
"jsonPtr": "/a"
},
{
"data": 42,
"jsonPtr": "/b"
},
{
"data": {
"a": 42,
"b": 42
},
"jsonPtr": [
"/a",
"/b"
]
}
]);
});

Constructors

Properties

Methods

Constructors

Properties

changeCallbacks: Map<string, Set<DataChangeCallback>>

for every json pointer, we have multiple callbacks that are stored in a Set

context: any

Contextual data for the template processing.

debugger: any

Debugger utility for the template processor.

errorReport: {
    [key: JsonPointerString]: any;
} = {}

Contains any errors encountered during template processing.

Type declaration

executionPlans: {
    [key: JsonPointerString]: JsonPointerString[];
} = {}

Execution plans 'from' a given JSON Pointer. So key is JSON Pointer and value is array of JSON pointers (a plan)

Type declaration

executionQueue: (ExecutionPlan | SerialPlan | SnapshotPlan | Transaction)[] = []

A queue of execution plans awaiting processing.

executionStatus: ExecutionStatus
functionGenerators: Map<string, FunctionGenerator<MetaInfo>> = ...

function generators can be provided by a caller when functions need to be created in such a way that they are somehow 'responsive' or dependent on their location inside the template. Both the generator function, and the function it generates are asynchronous functions (ie they return a promise). $import is an example of this kind of behavior. When $import('http://mytemplate.com/foo.json') is called, the import function is actually generated on the fly, using knowledge of the json path that it was called at, to replace the content of the template at that path with the downloaded content.

generatorManager: GeneratorManager
input: any

Represents the raw input for the template processor.

isClosed: boolean = false
isInitializing: boolean

Flag indicating if the template processor is currently initializing.

lifecycleManager: LifecycleOwner = ...
logger: StatedLogger

Represents the logger used within the template processor.

metaInfoByJsonPointer: MetaInfoMap = {}

Maps JSON pointers of import paths to their associated meta information. So, for example the key "/" -> MetaInfo[]. the MetaInfo are in no particular order HOWEVER the individual MetaInfo objects are the same objects as memory as those in the templateMeta tree. Therefore, from any MetaInfo, you can navigate to it children as its children are simply field of the object that don't end in "". This explains why we name the MetaInfo fields with "" suffix, so they can be differentiated from 'real' fields of the template output nodes.

onInitialize: Map<string, (() => void | Promise<void>)>

Allows caller to set a callback to propagate initialization into their framework

Type declaration

    • (): void | Promise<void>
    • Returns void | Promise<void>

Deprecated

use lifecycleManager instead

options: any = {}

Configuration options for the template processor.

output: {} = {}

Contains the processed output after template processing.

Type declaration

    planStepFunctionGenerators: Map<string, FunctionGenerator<PlanStep>> = ...
    planner: Planner

    An instance of the Planner interface used to manage execution plans.

    The planner is responsible for generating and executing ExecutionPlans, which define the steps necessary to process templates. It provides methods to initialize plans based on metadata and execute those plans. The planner can be replaced by any valid Planner. We have SerialPlanner and ParallelPlanner

    See

    • Planner
    • ExecutionPlan
    postInitialize: (() => Promise<void>) = ...

    Allows a caller to receive a callback after the template is evaluated, but before any temporary variables are removed. This function is slated to be replaced with a map of functions like onInitialize

    Type declaration

      • (): Promise<void>
      • Allows a caller to receive a callback after the template is evaluated, but before any temporary variables are removed. This function is slated to be replaced with a map of functions like onInitialize

        Returns Promise<void>

        Deprecated

        use lifecycleManager instead

    Deprecated

    use lifecycleManager instead

    tagSet: Set<string>

    A set of tags associated with the template.

    tempVars: string[] = []
    templateMeta: Record<string, MetaInfo> = {}

    This object mirrors the template output in structure but where the output contains actual data, this object contains MetaInfo nodes that track metadata on the actual nodes

    timerManager: TimerManager
    uniqueId: string

    A unique string identifier for the template processor instance like '3b12f1df-5232-4e1f-9c1b-3c6fc5ac7d3f'.

    warnings: any[] = []

    List of warnings generated during template processing.

    DEFAULT_FUNCTIONS: {
        Date: DateConstructor;
        console: Console;
        debounce: (<T>(func, wait?) => T);
        env: ((variableName, defaultValue?) => string);
        fetch: ((url, opts?) => Promise<Response>);
        rateLimit: (<T>(func, maxWait?) => T);
    } = ...

    Default set of functions provided for the template processor.

    Type declaration

    • Date: DateConstructor
    • console: Console
    • debounce: (<T>(func, wait?) => T)
        • <T>(func, wait?): T
        • Debounces a function, ensuring that it is only called once after a specified time has elapsed since the last call.

          Type Parameters

          • T extends AnyFunction

          Parameters

          • func: T

            The function to debounce.

          • wait: number = 200

            The number of milliseconds to wait before invoking the function.

          Returns T

          A debounced function with the same type as the original function.

          Example

          // Example usage:
          function myFunction(value: string) {
          console.log('Value:', value);
          }

          const debouncedFunction = debounce(myFunction, 500);

          debouncedFunction('First call');
          debouncedFunction('Second call');
          debouncedFunction('Third call');
    • env: ((variableName, defaultValue?) => string)
        • (variableName, defaultValue?): string
        • Parameters

          • variableName: string
          • Optional defaultValue: string

          Returns string

    • fetch: ((url, opts?) => Promise<Response>)
        • (url, opts?): Promise<Response>
        • Performs a fetch request and enhances error handling. If the response is not ok, it rejects with a custom error object that includes a .json() method. This .json() method, when called, returns the error object itself, facilitating error handling for scenarios where the caller expects to call .json() on the response.

          Parameters

          • url: string

            The URL to fetch.

          • Optional opts: object

            Optional fetch options.

          Returns Promise<Response>

          A promise that resolves to the fetch response. If the response is not ok, it rejects with a custom error object consistent with Stated template-level error handling e.g. {error:{message:"..."}}.

          Throws

          The custom error object with a .json() method if the response is not ok. The error object structure is: { error: { message: string } }.

    • rateLimit: (<T>(func, maxWait?) => T)
        • <T>(func, maxWait?): T
        • Type Parameters

          • T extends AnyFunction

          Parameters

          • func: T
          • maxWait: number = 1000

          Returns T

    Remarks

    These functions are commonly used utilities available for usage within the template processor's context. You can replace set this to determine which functions are available from templates

    Static

    NOOP: symbol = ...
    _isNodeJS: boolean = ...

    Methods

    • Private

      Sometimes we need to import a simple expression string that is not nested in an object. for example if we {"msg":"$import('${'hello ' & to }')"), then we are importing an expression directly into the parent, not nesting in an object. In this case we must slice off the last element of the rootJsonPointer, because to not slice it off would imply that the target of the expression is inside the msg field, but the intention when we import a simple expression is target the parent object which holds the msg field.

      Parameters

      • template: any
      • rootJsonPtr: any[]

      Returns any[]

      either the original rootJsonPointer, or one that has been trimmed to point to the parent of rootJsonPtr

    • Private

      Applies a transaction by processing each mutation within the transaction.

      For each mutation, this method applies the specified operation (set or delete) to the output object based on the jsonPtr (JSON pointer). It also triggers data change callbacks after each mutation.

      Parameters

      • transaction: Transaction

        The transaction object containing a list of mutations to apply.

      Returns Promise<void>

      Throws

      If the operation (op) is neither "set" nor "delete".

      The transaction is processed as follows:

      • "set": Sets the value at the location specified by jsonPtr using jp.set.
      • "delete": Removes the value at the location specified by jsonPtr using jp.remove.

      After each mutation, callDataChangeCallbacks is called to notify of the change. Finally, a batch data change callback is triggered for all affected JSON pointers.

    • Parameters

      • data: any
      • jsonPointer: string | string[]
      • removed: boolean = false
      • op: Op = "set"

      Returns Promise<void>

    • Parameters

      • removeTmpVars: boolean = true

      Returns Promise<void>

    • Controls the flow of data and retrieves root nodes based on the specified level.

      Parameters

      • level: FlowOpt

        The level specifying the granularity of the data flow.

      Returns DataFlowNode[]

      An array of root nodes that are computed based on the specified level.

    • Parameters

      Returns ((jsonPointer, timeoutMs) => object)

        • (jsonPointer, timeoutMs): object
        • Parameters

          • jsonPointer: string
          • timeoutMs: number

          Returns object

    • Private

      When $forked is called, it must push the current output onto the forkStack so it can be restored on $joined, and it must replace the output with a copy of the output.

      Parameters

      Returns ((jsonPtr, data, op?) => Promise<void>)

        • (jsonPtr, data, op?): Promise<void>
        • Parameters

          • jsonPtr: string
          • data: any
          • op: Op = 'set'

          Returns Promise<void>

    • Private

      The $joined(/foo, data) function pops the forkstack and can return us to ordinary non-forked operation if the pop operation empties the fork stack

      Parameters

      Returns ((jsonPtr, data, op?) => Promise<void>)

        • (jsonPtr, data, op?): Promise<void>
        • Parameters

          • jsonPtr: string
          • data: any
          • op: Op = 'set'

          Returns Promise<void>

    • Private

      The $set(/foo, data) command may be operating inside the context of a $forked. If this is the case then $setData is intercepted here and we use the setDataForked function which applies changes to forked output

      Parameters

      Returns ((jsonPtr, data?, op?) => Promise<string[]>) | ((jsonPtr, data, op?) => Promise<void>)

    • Parameters

      Returns ((templateToImport, mergeMe?) => Promise<symbol>)

        • (templateToImport, mergeMe?): Promise<symbol>
        • Parameters

          • templateToImport: string
          • Optional mergeMe: object

          Returns Promise<symbol>

    • Retrieves the metadata information for a given JSON Pointer string.

      Parameters

      • jsonPtr: string

        The JSON Pointer string that identifies the template node.

      Returns MetaInfo

      The MetaInfo object corresponding to the provided JSON Pointer.

      Throws

      If the JSON Pointer does not exist in the templateMeta.

    • Parameters

      • template: string | object
      • jsonPtrImportPath: string

      Returns Promise<void>

    • Template processor initialize can be called from 2 major use cases

      1. initialize a new importedSubtemplate processor importedSubtemplate
      2. $import a new importedSubtemplate for an existing importedSubtemplate processor in the second case we need to reset the importedSubtemplate processor data holders

      Parameters

      • importedSubtemplate: undefined | {} = undefined

        the object representing the importedSubtemplate

      • jsonPtr: string = "/"

        defaults to "/" which is to say, this importedSubtemplate is the root importedSubtemplate. When we $import a importedSubtemplate inside an existing importedSubtemplate, then we must provide a path other than root to import into. Typically, we would use the json pointer of the expression where the $import function is used.

      • executionStatusSnapshot: undefined | Snapshot = undefined

      Returns Promise<void>

    • Private

      temp vars are in scope if all tags are present OR the expression's fieldname ends in !, which makes it an absolutely temporary variable since.

      Parameters

      Returns boolean

    • Private

      Certain functions callable in a JSONata expression must be dynamically generated. They cannot be static generated because the function instance needs to hold a reference to some kind of runtime state, either a MetaInfo or a PlanStep (see FunctionGenerator type). This method, for a given list of function names, generates the function by finding and calling the corresponding FunctionGenerator.

      Parameters

      Returns Promise<void>

    • Parameters

      • tmpVars: string[]
      • jsonPtrOfTemplate: string

      Returns void

    • Removes a previously registered transaction callback.

      This method removes the callback that was registered with setTransactionCallback for the root path '/'.

      Parameters

      • cb: DataChangeCallback

        The callback function to remove, which should match the previously registered callback.

      Returns void

    • Parameters

      • literalTemplateToImport: any
      • metaInfo: MetaInfo

      Returns Promise<void>

    • Sets or deletes data based on the specified operation.

      Parameters

      • jsonPtr: string

        The JSON pointer indicating where to apply the operation.

      • Optional data: any = null

        The data to be used with the set or setDeferred operation.

      • Optional op: Op = "set"

        The operation to perform - setDeferred is for internal use

      Returns Promise<string[]>

      A promise with the list of json pointers touched by the plan

      Async

    • Sets a data change callback function that will be called whenever the value at the json pointer has changed

      Parameters

      • jsonPtr: string
      • cbFn: DataChangeCallback

        of form (data, ptr:JsonPointerString, removed?:boolean)=>void

      Returns void

    • Calling setDataForked allows the mutation and its reaction (fromPlan) to begin executing immediately without queuing/seriealizing/blocking on other plans. This is possible because a forked planStep contains a write-safe copy of this.output (essentially a 'snapshot' in MVCC terminology) and therefore the mutation and propagation of the fromPlan are isolated, just like snapshot isolation levels on Postres or other MVCC databases. So, do not await this method. Just let 'er rip.

      Parameters

      Returns Promise<string[]>

    • allows direct injection of ${expression} into template at given jsonPointer.

      Parameters

      • expression: string
      • jsonPointer: string

      Returns Promise<void>

    • Registers a transaction callback to handle batched data changes.

      When setData is called, a set of changes (a DAG) is calculated and the changes are sequentially applied. These changes can be 'bundled' into a single Transaction for the purpose of capturing a single set of changes that if atomically applied, has the exact same effect as the DAG propagation. Therefore, a Transaction can be a less chatty way to capture and apply changes from one template instance A to template instance B without incurring the cost of for B to compute the change DAG.

      Parameters

      • cb: ((transaction) => Promise<void>)

        A callback function that handles a Transaction object. The callback is expected to return a Promise<void>.

          • (transaction): Promise<void>
          • Parameters

            Returns Promise<void>

      Returns void

      Throws

      If the callback is registered for any path other than '/'.

    • Creates a stringified snapshot of the current state of the TemplateProcessor instance, including its execution status, input, output, and options.

      Returns Promise<string>

      A JSON string representing the snapshot of the TemplateProcessor's current state, including template input, processed output, and options.

      Example

      const tp = new TemplateProcessor(template, context, options);
      const snapshotString = await tp.snapshot();
      // snapshotString contains a JSON string with the execution plans, mvcc, template, output, and options of the
      TemplateProcessor
    • Type Parameters

      • T extends any[]

      Parameters

      • fn: ((...args) => any)
          • (...args): any
          • Parameters

            • Rest ...args: T

            Returns any

      Returns ((...args) => any)

        • (...args): any
        • Parameters

          • Rest ...args: T

          Returns any

    • Constructs a new TemplateProcessor instance from a given snapshot object, but does NOT initialize it. This method allows the caller the opportunity to register dataChangeCallbacks and so forth before template evaluation begins, providing more control over the initialization process.

      Parameters

      • snapshot: Snapshot

        A snapshot object containing template, options, and output data for initializing the TemplateProcessor.

      • Optional context: {} = {}

        An optional context object to be used by the TemplateProcessor.

        Returns default

        A new TemplateProcessor instance constructed from the snapshot data, not yet initialized.

        Example

        const snapshot = {"template":"...", "options":{}, "output":"..."};
        const tp = TemplateProcessor.constructFromSnapshot(snapshot);
        // Register callbacks or perform other setup operations here
        await tp.initialize();
      • this function is used to make a deep copy of the output so that when we $fork we are operating on a copy of the output, not co-mutating the original

        Parameters

        • output: object

        Returns any

      • Loads a template and initializes a new template processor instance.

        Parameters

        • template: object

          The template data to be processed.

        • Optional context: {} = {}

          Optional context data for the template.

          • options: object = {}

          Returns Promise<default>

          Returns an initialized instance of TemplateProcessor.

          Static

        • Parameters

          • jsonataLambda: any

          Returns {
              _stated_function__: boolean;
              apply(_this, args): any;
              (...args): any;
          }

            • (...args): any
            • Parameters

              • Rest ...args: any[]

              Returns any

          • _stated_function__: boolean
          • apply:function

        Generated using TypeDoc