Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reuse template proessor #27

Merged
merged 6 commits into from
Dec 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions src/CliCore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,18 +120,28 @@ export default class CliCore {
const input = await this.readFileAndParse(filepath, importPath);
const contextData = contextFilePath ? await this.readFileAndParse(contextFilePath, importPath) : {};
options.importPath = importPath; //path is where local imports will be sourced from. We sneak path in with the options
this.templateProcessor = new TemplateProcessor(input, contextData, options);
// if we initialize for the first time, we need to create a new instance of TemplateProcessor
if (!this.templateProcessor) {
this.templateProcessor = new TemplateProcessor(input, contextData, options);
} else { // if we are re-initializing, we need to reset the tagSet and options, if provided
this.templateProcessor.tagSet = new Set();
this.templateProcessor.options = options;
if (contextData) {
this.templateProcessor.setupContext(contextData);
}
}
if(this.replServer){
//make variable called 'template' accessible in REPL
this.replServer.context.template = this.templateProcessor;
}
this.templateProcessor.onInitialize = this.onInit;
tags.forEach(a => this.templateProcessor.tagSet.add(a));
// set options
this.templateProcessor.logger.level = this.logLevel;
this.templateProcessor.logger.debug(`arguments: ${JSON.stringify(parsed)}`);

try {
await this.templateProcessor.initialize();
await this.templateProcessor.initialize(input);
if (oneshot === true) {
return this.templateProcessor.output;
}
Expand Down Expand Up @@ -192,15 +202,15 @@ export default class CliCore {
if (!this.templateProcessor) {
throw new Error('Initialize the template first.');
}
const parsed = CliCore.minimistArgs(replCmdInputStr)
const parsed = CliCore.minimistArgs(replCmdInputStr === undefined ? "" : replCmdInputStr)
let {_:jsonPointer=""} = parsed;
if(Array.isArray(jsonPointer)){
jsonPointer = jsonPointer[0];
if(jsonPointer===undefined){
jsonPointer = "";
}
}
return this.templateProcessor.out(jsonPointer);
return this.templateProcessor.out(jsonPointer);
}

state() {
Expand Down
35 changes: 25 additions & 10 deletions src/TemplateProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,22 +179,27 @@ export default class TemplateProcessor {
this.import = this.import.bind(this); // allows clients to directly call import on this TemplateProcessor
this.logger = new ConsoleLogger("info");
this.setupContext(context);
this.resetTemplate(template);
this.options = options;
this.debugger = new Debugger(this.templateMeta, this.logger);
this.isInitializing = false;
this.changeCallbacks = new Map();
this.functionGenerators = new Map();
this.tagSet = new Set();
}

// resetting template means that we are resetting all data holders and set up new template
private resetTemplate(template) {
this.input = JSON.parse(JSON.stringify(template));
this.output = template; //initial output is input template
this.templateMeta = JSON.parse(JSON.stringify(this.output));// Copy the given template to `initialize the templateMeta
this.templateMeta = JSON.parse(JSON.stringify(template));// Copy the given template to `initialize the templateMeta
this.warnings = [];
this.metaInfoByJsonPointer = {}; //there will be one key "/" for the root and one additional key for each import statement in the template
this.tagSet = new Set();
this.options = options;
this.debugger = new Debugger(this.templateMeta, this.logger);
this.errorReport = {}
this.isInitializing = false;
this.tempVars = [];
this.changeCallbacks = new Map();
this.functionGenerators = new Map();
}

private setupContext(context: {}) {
setupContext(context: {}) {
this.context = merge(
{},
TemplateProcessor.DEFAULT_FUNCTIONS,
Expand All @@ -214,8 +219,18 @@ export default class TemplateProcessor {
}
}

public async initialize(template = this.input, jsonPtr = "/") {
// Template processor initialize can be called from 2 major use cases
// 1. initialize a new template processor template
// 2. initialize a new template for an existing template processor
// in the second case we need to reset the template processor data holders
public async initialize(template: {} = undefined, jsonPtr = "/") {
this.timerManager.clearAll();

// if initialize is called with a template and root json pointer (which is "/" b default)
// we need to reset the template. Otherwise, we rely on the one provided in the constructor
if (template !== undefined && jsonPtr === "/") {
this.resetTemplate(template)
}
this.onInitialize && await this.onInitialize();
if (jsonPtr === "/" && this.isInitializing) {
console.error("-----Initialization '/' is already in progress. Ignoring concurrent call to initialize!!!! Strongly consider checking your JS code for errors.-----");
Expand All @@ -240,7 +255,7 @@ export default class TemplateProcessor {
this.executionPlans = {}; //clear execution plans
let parsedJsonPtr = jp.parse(jsonPtr);
parsedJsonPtr = isEqual(parsedJsonPtr, [""]) ? [] : parsedJsonPtr; //correct [""] to []
const metaInfos = await this.createMetaInfos(template, parsedJsonPtr);
const metaInfos = await this.createMetaInfos(template === undefined ? this.output : template , parsedJsonPtr);
this.metaInfoByJsonPointer[jsonPtr] = metaInfos; //dictionary for template meta info, by import path (jsonPtr)
this.sortMetaInfos(metaInfos);
this.populateTemplateMeta(metaInfos);
Expand Down
Loading