@jsreport/jsreport-core
Advanced tools
Comparing version 4.2.1 to 4.2.2
@@ -17,4 +17,6 @@ /*! | ||
const contextExecutionChainMap = new WeakMap() | ||
const executionFnParsedParamsMap = new Map() | ||
const executionAsyncResultsMap = new Map() | ||
const executionAsyncCallChainMap = new Map() | ||
const executionFinishListenersMap = new Map() | ||
@@ -52,2 +54,3 @@ | ||
executionAsyncResultsMap.delete(executionId) | ||
executionAsyncCallChainMap.delete(executionId) | ||
executionFinishListenersMap.delete(executionId) | ||
@@ -57,3 +60,5 @@ } | ||
reporter.templatingEngines.evaluate = (executionInfo, entityInfo, req) => templatingEnginesEvaluate(true, executionInfo, entityInfo, req) | ||
reporter.templatingEngines.evaluate = (executionInfo, entityInfo, req) => { | ||
return templatingEnginesEvaluate(true, executionInfo, entityInfo, req) | ||
} | ||
@@ -70,5 +75,8 @@ reporter.extendProxy((proxy, req, { | ||
waitForAsyncHelper: async (maybeAsyncContent) => { | ||
const executionChain = contextExecutionChainMap.get(context) || [] | ||
const executionId = executionChain[executionChain.length - 1] | ||
if ( | ||
context.__executionId == null || | ||
!executionAsyncResultsMap.has(context.__executionId) || | ||
executionId == null || | ||
!executionAsyncResultsMap.has(executionId) || | ||
typeof maybeAsyncContent !== 'string' | ||
@@ -79,3 +87,3 @@ ) { | ||
const asyncResultMap = executionAsyncResultsMap.get(context.__executionId) | ||
const asyncResultMap = executionAsyncResultsMap.get(executionId) | ||
const asyncHelperResultRegExp = /{#asyncHelperResult ([^{}]+)}/ | ||
@@ -99,14 +107,30 @@ let content = maybeAsyncContent | ||
waitForAsyncHelpers: async () => { | ||
if (context.__executionId != null && executionAsyncResultsMap.has(context.__executionId)) { | ||
const asyncResultMap = executionAsyncResultsMap.get(context.__executionId) | ||
return Promise.all([...asyncResultMap.keys()].map((k) => asyncResultMap.get(k))) | ||
const executionChain = contextExecutionChainMap.get(context) || [] | ||
const executionId = executionChain[executionChain.length - 1] | ||
if (executionId != null && executionAsyncResultsMap.has(executionId)) { | ||
const asyncCallChainSet = executionAsyncCallChainMap.get(executionId) | ||
const lastAsyncCall = [...asyncCallChainSet].pop() | ||
const asyncResultMap = executionAsyncResultsMap.get(executionId) | ||
// we should exclude the last async call because if it exists it represents the parent | ||
// async call that called .waitForAsyncHelpers, it is not going to be resolved at this point | ||
const targetAsyncResultKeys = [...asyncResultMap.keys()].filter((key) => key !== lastAsyncCall) | ||
return Promise.all(targetAsyncResultKeys.map((k) => asyncResultMap.get(k))) | ||
} | ||
}, | ||
addFinishListener: (fn) => { | ||
if (executionFinishListenersMap.has(context.__executionId)) { | ||
executionFinishListenersMap.get(context.__executionId).add('finish', fn) | ||
const executionChain = contextExecutionChainMap.get(context) || [] | ||
const executionId = executionChain[executionChain.length - 1] | ||
if (executionId && executionFinishListenersMap.has(executionId)) { | ||
executionFinishListenersMap.get(executionId).add('finish', fn) | ||
} | ||
}, | ||
createAsyncHelperResult: (v) => { | ||
const asyncResultMap = executionAsyncResultsMap.get(context.__executionId) | ||
const executionChain = contextExecutionChainMap.get(context) || [] | ||
const executionId = executionChain[executionChain.length - 1] | ||
const asyncResultMap = executionAsyncResultsMap.get(executionId) | ||
const asyncResultId = nanoid(7) | ||
@@ -142,2 +166,3 @@ asyncResultMap.set(asyncResultId, v) | ||
executionAsyncResultsMap.delete(executionId) | ||
executionAsyncCallChainMap.delete(executionId) | ||
} | ||
@@ -157,6 +182,2 @@ } | ||
const initFn = async (getTopLevelFunctions, compileScript) => { | ||
if (reporter.options.trustUserCode === false) { | ||
return null | ||
} | ||
if (systemHelpersCache != null) { | ||
@@ -204,6 +225,12 @@ return systemHelpersCache | ||
const asyncResultMap = new Map() | ||
const asyncCallChainSet = new Set() | ||
context.__executionId = executionId | ||
if (!contextExecutionChainMap.has(context)) { | ||
contextExecutionChainMap.set(context, []) | ||
} | ||
contextExecutionChainMap.get(context).push(executionId) | ||
executionAsyncResultsMap.set(executionId, asyncResultMap) | ||
executionAsyncCallChainMap.set(executionId, asyncCallChainSet) | ||
executionFinishListenersMap.set(executionId, reporter.createListenerCollection()) | ||
@@ -235,3 +262,3 @@ executionFnParsedParamsMap.get(req.context.id).get(executionFnParsedParamsKey).resolve({ require, console, topLevelFunctions, context }) | ||
} else { | ||
wrappedTopLevelFunctions[h] = wrapHelperForAsyncSupport(wrappedTopLevelFunctions[h], asyncResultMap) | ||
wrappedTopLevelFunctions[h] = wrapHelperForAsyncSupport(wrappedTopLevelFunctions[h], asyncResultMap, asyncCallChainSet) | ||
} | ||
@@ -244,7 +271,9 @@ } | ||
// we need to use the cloned map, becuase there can be a waitForAsyncHelper pending that needs the asyncResultMap values | ||
// we need to use the cloned map, because there can be a waitForAsyncHelper pending that needs the asyncResultMap values | ||
const clonedMap = new Map(asyncResultMap) | ||
while (clonedMap.size > 0) { | ||
await Promise.all([...clonedMap.keys()].map(async (k) => { | ||
resolvedResultsMap.set(k, `${await clonedMap.get(k)}`) | ||
const result = await clonedMap.get(k) | ||
asyncCallChainSet.delete(k) | ||
resolvedResultsMap.set(k, `${result}`) | ||
clonedMap.delete(k) | ||
@@ -259,3 +288,3 @@ })) | ||
// this can happen if a child jsreport.templatingEngines.evaluate receives an async value from outer scope | ||
// because every evaluate uses a unique map of async resuts | ||
// because every evaluate uses a unique map of async results | ||
// example is the case when component receives as a value async thing | ||
@@ -272,4 +301,6 @@ // instead of returning "undefined" we let the outer eval to do the replace | ||
await executionFinishListenersMap.get(context.__executionId).fire() | ||
await executionFinishListenersMap.get(executionId).fire() | ||
contextExecutionChainMap.set(context, contextExecutionChainMap.get(context).filter((id) => id !== executionId)) | ||
return { | ||
@@ -303,20 +334,2 @@ // handlebars escapes single brackets before execution to prevent errors on {#asset} | ||
let helpersStr = normalizedHelpers | ||
if (reporter.options.trustUserCode === false) { | ||
const registerResults = await reporter.registerHelpersListeners.fire() | ||
const systemHelpers = [] | ||
for (const result of registerResults) { | ||
if (result == null) { | ||
continue | ||
} | ||
if (typeof result === 'string') { | ||
systemHelpers.push(result) | ||
} | ||
} | ||
const systemHelpersStr = systemHelpers.join('\n') | ||
helpersStr = normalizedHelpers + '\n' + systemHelpersStr | ||
} | ||
try { | ||
@@ -327,3 +340,3 @@ return await reporter.runInSandbox({ | ||
}, | ||
userCode: helpersStr, | ||
userCode: normalizedHelpers, | ||
initFn, | ||
@@ -381,3 +394,3 @@ executionFn, | ||
function wrapHelperForAsyncSupport (fn, asyncResultMap) { | ||
function wrapHelperForAsyncSupport (fn, asyncResultMap, asyncCallChainSet) { | ||
return function (...args) { | ||
@@ -393,2 +406,3 @@ // important to call the helper with the current this to preserve the same behavior | ||
asyncResultMap.set(asyncResultId, fnResult) | ||
asyncCallChainSet.add(asyncResultId) | ||
@@ -395,0 +409,0 @@ return `{#asyncHelperResult ${asyncResultId}}` |
{ | ||
"name": "@jsreport/jsreport-core", | ||
"version": "4.2.1", | ||
"version": "4.2.2", | ||
"description": "javascript based business reporting", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
@@ -285,2 +285,10 @@ # @jsreport/jsreport-core | ||
### 4.2.2 | ||
- fix recursive component rendering | ||
### 4.2.1 | ||
- response.output.update now accepts Web ReadableStream (which is what new version of puppeteer returns) | ||
### 4.2.0 | ||
@@ -287,0 +295,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
409827
9900
434