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

_evaluateExprNode _evaluateExpression _setData _strictChecks adjustRootForSimpleExpressionImports allTagsPresent applyTransaction cacheTmpVarLocations callDataChangeCallbacks close compileMetaInfo createMetaInfos drainExecutionQueue evaluateNode executePlan extractFragmentIfNeeded fetchFromURL flow from generateChange generateDeferFunction generateErrorReportFunction generateForked generateJoined generateSet getCompilationTarget getDependencies getDependents getImport getMetaInfo handleMetaInfoCreation import initialize initializeImportedTemplate isConcurrentInitialization isEnabled isTempVarInScope localImport logOutput makeDepsAbsolute mutate out parseJsonPointer parseURL plan populateContextWithGeneratedFunctions populateContextWithSelf populateTemplateMeta processInitialization propagateTags queueInitializationPlan removeDataChangeCallback removeLeadingDollarsFromDependencies removeTemporaryVariables removeTransactionCallback resetInitialization resetTemplate restore restoreFromSnapshotObject restoreFunctions runInitializationPlugins setContentInTemplate setData setDataChangeCallback setDataForked setDataIntoTrackedLocation setExpression setTransactionCallback setUntrackedLocation setupContext setupDependees setupFunctionGenerators setupLogger shouldResetInitialization shouldResetTemplate snapshot sortMetaInfos to validateAsJSON withErrorHandling compileToJsonPointer constructFromSnapshotObject deepCopy dependsOnImportedTemplate fromSnapshot fromString load simpleUniqueId wrapInOrdinaryFunction

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
isExecutingPlan: boolean = false
isInitializing: boolean

Flag indicating if the template processor is currently initializing.

lifecycleManager: LifecycleManager = ...
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 ((jsonPtr, __namedParameters) => Promise<any>)

        • (jsonPtr, __namedParameters): Promise<any>
        • Parameters

          • jsonPtr: string
          • __namedParameters: {
                defaultVal: any;
                mutator: ((v) => Promise<any>);
            }
            • defaultVal: any
            • mutator: ((v) => Promise<any>)
                • (v): Promise<any>
                • Parameters

                  • v: any

                  Returns Promise<any>

          Returns Promise<any>

    • 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

      • jsonPtr: string
      • importedSubtemplate: undefined | {}

      Returns undefined | {}

    • 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

      • compilationTarget: {}
        • jsonPtr: string

        Returns Promise<void>

      • 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

        • importedSubtemplate: undefined | {}
        • jsonPtr: string
        • executionStatusSnapshot: undefined | Snapshot

        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 '/'.

      • Parameters

        • jsonPtr: string
        • executionStatusSnapshot: undefined | Snapshot

        Returns boolean

      • Parameters

        • importedSubtemplate: undefined | {}
        • jsonPtr: string

        Returns boolean

      • 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