@wyw-in-js/transform 1.0.7 → 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm/cache.js +60 -5
- package/esm/cache.js.map +1 -1
- package/esm/module.js +8 -3
- package/esm/module.js.map +1 -1
- package/esm/transform/Entrypoint.js +8 -3
- package/esm/transform/Entrypoint.js.map +1 -1
- package/esm/transform/actions/BaseAction.js +2 -1
- package/esm/transform/actions/BaseAction.js.map +1 -1
- package/esm/transform/actions/actionRunner.js +2 -2
- package/esm/transform/actions/actionRunner.js.map +1 -1
- package/esm/transform/generators/processEntrypoint.js +5 -1
- package/esm/transform/generators/processEntrypoint.js.map +1 -1
- package/esm/transform/types.js.map +1 -1
- package/esm/transform.js +45 -23
- package/esm/transform.js.map +1 -1
- package/esm/utils/collectTemplateDependencies.js +9 -0
- package/esm/utils/collectTemplateDependencies.js.map +1 -1
- package/lib/cache.js +60 -5
- package/lib/cache.js.map +1 -1
- package/lib/module.js +10 -5
- package/lib/module.js.map +1 -1
- package/lib/transform/Entrypoint.js +8 -3
- package/lib/transform/Entrypoint.js.map +1 -1
- package/lib/transform/actions/BaseAction.js +2 -1
- package/lib/transform/actions/BaseAction.js.map +1 -1
- package/lib/transform/actions/actionRunner.js +2 -2
- package/lib/transform/actions/actionRunner.js.map +1 -1
- package/lib/transform/generators/processEntrypoint.js +5 -1
- package/lib/transform/generators/processEntrypoint.js.map +1 -1
- package/lib/transform/types.js.map +1 -1
- package/lib/transform.js +45 -23
- package/lib/transform.js.map +1 -1
- package/lib/utils/collectTemplateDependencies.js +9 -0
- package/lib/utils/collectTemplateDependencies.js.map +1 -1
- package/package.json +1 -1
- package/types/cache.d.ts +7 -0
- package/types/cache.js +59 -3
- package/types/module.js +8 -3
- package/types/transform/Entrypoint.d.ts +1 -1
- package/types/transform/Entrypoint.js +8 -3
- package/types/transform/actions/BaseAction.d.ts +2 -1
- package/types/transform/actions/BaseAction.js +3 -1
- package/types/transform/actions/actionRunner.js +2 -2
- package/types/transform/generators/processEntrypoint.js +4 -1
- package/types/transform/types.d.ts +1 -0
- package/types/transform.js +47 -23
- package/types/utils/collectTemplateDependencies.js +9 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collectTemplateDependencies.js","names":["_template","require","_types","_shared","_createId","_findIdentifiers","_getSource","_scopeHelpers","_valueToLiteral","staticEval","ex","evaluate","undefined","result","confident","hasEvalMeta","value","expressionDeclarationTpl","statement","preserveComments","unsupported","reason","buildCodeFrameError","isIdentifier","getUidInRootScope","path","name","node","rootScope","scope","getProgramParent","hasBinding","generateUid","hoistVariableDeclarator","parent","referencedIdentifiers","findIdentifiers","forEach","identifier","hoistIdentifier","bindingIdentifiers","newName","rename","statementInRoot","findParent","p","_p$parentPath","parentPath","isProgram","declaration","type","kind","declarations","cloneNode","inserted","insertBefore","referenceAll","registerDeclaration","idPath","isReferenced","binding","getBinding","includes","bindingPath","isVariableDeclarator","extractExpression","imports","isLiteral","ValueType","CONST","loc","_p$parentPath2","isFunction","isFunctionExpression","isArrowFunctionExpression","expUid","evaluated","id","evaluatedId","mutate","replaceWith","valueToLiteral","FUNCTION","LAZY","expId","createId","expression","importedFrom","findImportSourceOfIdentifier","_idPath$scope$getBind","_imports$find","exBindingIdentifier","exImport","find","i","local","push","source","traverse","Identifier","callee","arguments","debug","logger","extend","collectTemplateDependencies","quasi","get","quasis","expressions","length","expressionValues","map","bind","getSource","isExpression","extracted"],"sources":["../../src/utils/collectTemplateDependencies.ts"],"sourcesContent":["/* eslint @typescript-eslint/no-use-before-define: [\"error\", { \"functions\": false }] */\n\n/**\n * This file is a visitor that checks TaggedTemplateExpressions and look for WYW template literals.\n * For each template it makes a list of dependencies, try to evaluate expressions, and if it is not possible, mark them as lazy dependencies.\n */\n\nimport { statement } from '@babel/template';\nimport type { NodePath } from '@babel/traverse';\nimport type {\n Expression,\n Identifier,\n JSXIdentifier,\n Statement,\n TaggedTemplateExpression,\n TemplateElement,\n TSType,\n VariableDeclaration,\n VariableDeclarator,\n} from '@babel/types';\nimport { cloneNode } from '@babel/types';\n\nimport type {\n ConstValue,\n ExpressionValue,\n FunctionValue,\n LazyValue,\n} from '@wyw-in-js/shared';\nimport { hasEvalMeta, ValueType, logger } from '@wyw-in-js/shared';\n\nimport type { IImport } from './collectExportsAndImports';\nimport { createId } from './createId';\nimport { findIdentifiers } from './findIdentifiers';\nimport { getSource } from './getSource';\nimport { mutate, referenceAll } from './scopeHelpers';\nimport { valueToLiteral } from './valueToLiteral';\n\nfunction staticEval(\n ex: NodePath<Expression>,\n evaluate = false\n): [unknown] | undefined {\n if (!evaluate) return undefined;\n\n const result = ex.evaluate();\n if (result.confident && !hasEvalMeta(result.value)) {\n return [result.value];\n }\n\n return undefined;\n}\n\nconst expressionDeclarationTpl = statement(\n 'const %%expId%% = () => %%expression%%',\n {\n preserveComments: true,\n }\n);\n\nconst unsupported = (ex: NodePath, reason?: string): Error =>\n ex.buildCodeFrameError(\n `This ${\n ex.isIdentifier() ? 'identifier' : 'expression'\n } cannot be used in the template${reason ? `, because it ${reason}` : ''}.`\n );\n\nfunction getUidInRootScope(path: NodePath<Identifier | JSXIdentifier>): string {\n const { name } = path.node;\n const rootScope = path.scope.getProgramParent();\n if (rootScope.hasBinding(name)) {\n return rootScope.generateUid(name);\n }\n\n return name;\n}\n\nfunction hoistVariableDeclarator(ex: NodePath<VariableDeclarator>) {\n if (!ex.scope.parent) {\n // It is already in the root scope\n return;\n }\n\n const referencedIdentifiers = findIdentifiers([ex], 'reference');\n referencedIdentifiers.forEach((identifier) => {\n if (identifier.isIdentifier()) {\n hoistIdentifier(identifier);\n }\n });\n\n const bindingIdentifiers = findIdentifiers([ex], 'declaration');\n\n bindingIdentifiers.forEach((path) => {\n const newName = getUidInRootScope(path);\n if (newName !== path.node.name) {\n path.scope.rename(path.node.name, newName);\n }\n });\n\n const rootScope = ex.scope.getProgramParent();\n\n const statementInRoot = ex.findParent(\n (p) => p.parentPath?.isProgram() === true\n ) as NodePath<Statement>;\n\n const declaration: VariableDeclaration = {\n type: 'VariableDeclaration',\n kind: 'let',\n declarations: [cloneNode(ex.node)],\n };\n\n const [inserted] = statementInRoot.insertBefore(declaration);\n referenceAll(inserted);\n rootScope.registerDeclaration(inserted);\n}\n\nfunction hoistIdentifier(idPath: NodePath<Identifier>): void {\n if (!idPath.isReferenced()) {\n throw unsupported(idPath);\n }\n\n const binding = idPath.scope.getBinding(idPath.node.name);\n if (!binding) {\n // It's something strange\n throw unsupported(idPath, 'is undefined');\n }\n\n if (binding.kind === 'module') {\n // Modules are global by default\n return;\n }\n\n if (!['var', 'let', 'const', 'hoisted'].includes(binding.kind)) {\n // This is not a variable, we can't hoist it\n throw unsupported(binding.path, 'is a function parameter');\n }\n\n const { scope, path: bindingPath } = binding;\n // parent here can be null or undefined in different versions of babel\n if (!scope.parent) {\n // The variable is already in the root scope\n return;\n }\n\n if (bindingPath.isVariableDeclarator()) {\n hoistVariableDeclarator(bindingPath);\n\n return;\n }\n\n throw unsupported(idPath);\n}\n\n/**\n * Only an expression that can be evaluated in the root scope can be\n * used in a WYW template. This function tries to hoist the expression.\n * @param ex The expression to hoist.\n * @param evaluate If true, we try to statically evaluate the expression.\n * @param imports All the imports of the file.\n */\nexport function extractExpression(\n ex: NodePath<Expression>,\n evaluate = false,\n imports: IImport[] = []\n): Omit<ExpressionValue, 'buildCodeFrameError' | 'source'> {\n if (\n ex.isLiteral() &&\n ('value' in ex.node || ex.node.type === 'NullLiteral')\n ) {\n return {\n ex: ex.node,\n kind: ValueType.CONST,\n value: ex.node.type === 'NullLiteral' ? null : ex.node.value,\n } as Omit<ConstValue, 'buildCodeFrameError' | 'source'>;\n }\n\n const { loc } = ex.node;\n\n const rootScope = ex.scope.getProgramParent();\n const statementInRoot = ex.findParent(\n (p) => p.parentPath?.isProgram() === true\n ) as NodePath<Statement>;\n\n const isFunction =\n ex.isFunctionExpression() || ex.isArrowFunctionExpression();\n\n // Generate next _expN name\n const expUid = rootScope.generateUid('exp');\n\n const evaluated = staticEval(ex, evaluate);\n\n if (!evaluated) {\n // If expression is not statically evaluable,\n // we need to hoist all its referenced identifiers\n\n // Collect all referenced identifiers\n findIdentifiers([ex], 'reference').forEach((id) => {\n if (!id.isIdentifier()) return;\n\n // Try to evaluate and inline them…\n const evaluatedId = staticEval(id, evaluate);\n if (evaluatedId) {\n mutate(id, (p) => {\n p.replaceWith(valueToLiteral(evaluatedId[0], ex));\n });\n } else {\n // … or hoist them to the root scope\n hoistIdentifier(id);\n }\n });\n }\n\n const kind = isFunction ? ValueType.FUNCTION : ValueType.LAZY;\n\n // Declare _expN const with the lazy expression\n const declaration = expressionDeclarationTpl({\n expId: createId(expUid),\n expression: evaluated\n ? valueToLiteral(evaluated[0], ex)\n : cloneNode(ex.node),\n }) as VariableDeclaration;\n\n // Insert the declaration as close as possible to the original expression\n const [inserted] = statementInRoot.insertBefore(declaration);\n referenceAll(inserted);\n rootScope.registerDeclaration(inserted);\n\n const importedFrom: string[] = [];\n function findImportSourceOfIdentifier(idPath: NodePath<Identifier>) {\n const exBindingIdentifier = idPath.scope.getBinding(idPath.node.name)\n ?.identifier;\n const exImport =\n imports.find((i) => i.local.node === exBindingIdentifier) ?? null;\n if (exImport) {\n importedFrom.push(exImport.source);\n }\n }\n\n if (ex.isIdentifier()) {\n findImportSourceOfIdentifier(ex);\n } else {\n ex.traverse({\n Identifier: findImportSourceOfIdentifier,\n });\n }\n\n // Replace the expression with the _expN() call\n mutate(ex, (p) => {\n p.replaceWith({\n type: 'CallExpression',\n callee: createId(expUid),\n arguments: [],\n });\n });\n\n // eslint-disable-next-line no-param-reassign\n ex.node.loc = loc;\n\n // noinspection UnnecessaryLocalVariableJS\n const result: Omit<\n LazyValue | FunctionValue,\n 'buildCodeFrameError' | 'source'\n > = {\n kind,\n ex: createId(expUid, loc),\n importedFrom,\n };\n\n return result;\n}\n\nconst debug = logger.extend('template-parse:identify-expressions');\n\n/**\n * Collects, hoists, and makes lazy all expressions in the given template\n * If evaluate is true, it will try to evaluate the expressions\n */\nexport function collectTemplateDependencies(\n path: NodePath<TaggedTemplateExpression>,\n evaluate = false\n): [quasis: TemplateElement[], expressionValues: ExpressionValue[]] {\n const quasi = path.get('quasi');\n const quasis = quasi.get('quasis');\n const expressions = quasi.get('expressions');\n\n debug('Found: %s', expressions.length);\n\n const expressionValues: ExpressionValue[] = expressions.map(\n (ex: NodePath<Expression | TSType>): ExpressionValue => {\n const buildCodeFrameError = ex.buildCodeFrameError.bind(ex);\n const source = getSource(ex);\n\n if (!ex.isExpression()) {\n throw buildCodeFrameError(\n `The expression '${source}' is not supported.`\n );\n }\n\n const extracted = extractExpression(ex, evaluate);\n\n return {\n ...extracted,\n source,\n buildCodeFrameError,\n } as ExpressionValue;\n }\n );\n\n return [quasis.map((p) => p.node), expressionValues];\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"collectTemplateDependencies.js","names":["_template","require","_types","_shared","_createId","_findIdentifiers","_getSource","_scopeHelpers","_valueToLiteral","staticEval","ex","evaluate","undefined","isIdentifier","binding","scope","getBinding","node","name","path","isVariableDeclarator","get","result","confident","hasEvalMeta","value","expressionDeclarationTpl","statement","preserveComments","unsupported","reason","buildCodeFrameError","getUidInRootScope","rootScope","getProgramParent","hasBinding","generateUid","hoistVariableDeclarator","parent","referencedIdentifiers","findIdentifiers","forEach","identifier","hoistIdentifier","bindingIdentifiers","newName","rename","statementInRoot","findParent","p","_p$parentPath","parentPath","isProgram","declaration","type","kind","declarations","cloneNode","inserted","insertBefore","referenceAll","registerDeclaration","idPath","isReferenced","includes","bindingPath","extractExpression","imports","isLiteral","ValueType","CONST","loc","_p$parentPath2","isFunction","isFunctionExpression","isArrowFunctionExpression","expUid","evaluated","id","evaluatedId","mutate","replaceWith","valueToLiteral","FUNCTION","LAZY","expId","createId","expression","importedFrom","findImportSourceOfIdentifier","_idPath$scope$getBind","_imports$find","exBindingIdentifier","exImport","find","i","local","push","source","traverse","Identifier","callee","arguments","debug","logger","extend","collectTemplateDependencies","quasi","quasis","expressions","length","expressionValues","map","bind","getSource","isExpression","extracted"],"sources":["../../src/utils/collectTemplateDependencies.ts"],"sourcesContent":["/* eslint @typescript-eslint/no-use-before-define: [\"error\", { \"functions\": false }] */\n\n/**\n * This file is a visitor that checks TaggedTemplateExpressions and look for WYW template literals.\n * For each template it makes a list of dependencies, try to evaluate expressions, and if it is not possible, mark them as lazy dependencies.\n */\n\nimport { statement } from '@babel/template';\nimport type { NodePath } from '@babel/traverse';\nimport type {\n Expression,\n Identifier,\n JSXIdentifier,\n Statement,\n TaggedTemplateExpression,\n TemplateElement,\n TSType,\n VariableDeclaration,\n VariableDeclarator,\n} from '@babel/types';\nimport { cloneNode } from '@babel/types';\n\nimport type {\n ConstValue,\n ExpressionValue,\n FunctionValue,\n LazyValue,\n} from '@wyw-in-js/shared';\nimport { hasEvalMeta, ValueType, logger } from '@wyw-in-js/shared';\n\nimport type { IImport } from './collectExportsAndImports';\nimport { createId } from './createId';\nimport { findIdentifiers } from './findIdentifiers';\nimport { getSource } from './getSource';\nimport { mutate, referenceAll } from './scopeHelpers';\nimport { valueToLiteral } from './valueToLiteral';\n\nfunction staticEval(\n ex: NodePath<Expression>,\n evaluate = false\n): [unknown] | undefined {\n if (!evaluate) return undefined;\n\n if (ex.isIdentifier()) {\n const binding = ex.scope.getBinding(ex.node.name);\n\n // Babel may \"evaluate\" a destructured binding to its source container\n // object/array instead of the bound value, which changes template semantics.\n if (\n binding?.path.isVariableDeclarator() &&\n !binding.path.get('id').isIdentifier()\n ) {\n return undefined;\n }\n }\n\n const result = ex.evaluate();\n if (result.confident && !hasEvalMeta(result.value)) {\n return [result.value];\n }\n\n return undefined;\n}\n\nconst expressionDeclarationTpl = statement(\n 'const %%expId%% = () => %%expression%%',\n {\n preserveComments: true,\n }\n);\n\nconst unsupported = (ex: NodePath, reason?: string): Error =>\n ex.buildCodeFrameError(\n `This ${\n ex.isIdentifier() ? 'identifier' : 'expression'\n } cannot be used in the template${reason ? `, because it ${reason}` : ''}.`\n );\n\nfunction getUidInRootScope(path: NodePath<Identifier | JSXIdentifier>): string {\n const { name } = path.node;\n const rootScope = path.scope.getProgramParent();\n if (rootScope.hasBinding(name)) {\n return rootScope.generateUid(name);\n }\n\n return name;\n}\n\nfunction hoistVariableDeclarator(ex: NodePath<VariableDeclarator>) {\n if (!ex.scope.parent) {\n // It is already in the root scope\n return;\n }\n\n const referencedIdentifiers = findIdentifiers([ex], 'reference');\n referencedIdentifiers.forEach((identifier) => {\n if (identifier.isIdentifier()) {\n hoistIdentifier(identifier);\n }\n });\n\n const bindingIdentifiers = findIdentifiers([ex], 'declaration');\n\n bindingIdentifiers.forEach((path) => {\n const newName = getUidInRootScope(path);\n if (newName !== path.node.name) {\n path.scope.rename(path.node.name, newName);\n }\n });\n\n const rootScope = ex.scope.getProgramParent();\n\n const statementInRoot = ex.findParent(\n (p) => p.parentPath?.isProgram() === true\n ) as NodePath<Statement>;\n\n const declaration: VariableDeclaration = {\n type: 'VariableDeclaration',\n kind: 'let',\n declarations: [cloneNode(ex.node)],\n };\n\n const [inserted] = statementInRoot.insertBefore(declaration);\n referenceAll(inserted);\n rootScope.registerDeclaration(inserted);\n}\n\nfunction hoistIdentifier(idPath: NodePath<Identifier>): void {\n if (!idPath.isReferenced()) {\n throw unsupported(idPath);\n }\n\n const binding = idPath.scope.getBinding(idPath.node.name);\n if (!binding) {\n // It's something strange\n throw unsupported(idPath, 'is undefined');\n }\n\n if (binding.kind === 'module') {\n // Modules are global by default\n return;\n }\n\n if (!['var', 'let', 'const', 'hoisted'].includes(binding.kind)) {\n // This is not a variable, we can't hoist it\n throw unsupported(binding.path, 'is a function parameter');\n }\n\n const { scope, path: bindingPath } = binding;\n // parent here can be null or undefined in different versions of babel\n if (!scope.parent) {\n // The variable is already in the root scope\n return;\n }\n\n if (bindingPath.isVariableDeclarator()) {\n hoistVariableDeclarator(bindingPath);\n\n return;\n }\n\n throw unsupported(idPath);\n}\n\n/**\n * Only an expression that can be evaluated in the root scope can be\n * used in a WYW template. This function tries to hoist the expression.\n * @param ex The expression to hoist.\n * @param evaluate If true, we try to statically evaluate the expression.\n * @param imports All the imports of the file.\n */\nexport function extractExpression(\n ex: NodePath<Expression>,\n evaluate = false,\n imports: IImport[] = []\n): Omit<ExpressionValue, 'buildCodeFrameError' | 'source'> {\n if (\n ex.isLiteral() &&\n ('value' in ex.node || ex.node.type === 'NullLiteral')\n ) {\n return {\n ex: ex.node,\n kind: ValueType.CONST,\n value: ex.node.type === 'NullLiteral' ? null : ex.node.value,\n } as Omit<ConstValue, 'buildCodeFrameError' | 'source'>;\n }\n\n const { loc } = ex.node;\n\n const rootScope = ex.scope.getProgramParent();\n const statementInRoot = ex.findParent(\n (p) => p.parentPath?.isProgram() === true\n ) as NodePath<Statement>;\n\n const isFunction =\n ex.isFunctionExpression() || ex.isArrowFunctionExpression();\n\n // Generate next _expN name\n const expUid = rootScope.generateUid('exp');\n\n const evaluated = staticEval(ex, evaluate);\n\n if (!evaluated) {\n // If expression is not statically evaluable,\n // we need to hoist all its referenced identifiers\n\n // Collect all referenced identifiers\n findIdentifiers([ex], 'reference').forEach((id) => {\n if (!id.isIdentifier()) return;\n\n // Try to evaluate and inline them…\n const evaluatedId = staticEval(id, evaluate);\n if (evaluatedId) {\n mutate(id, (p) => {\n p.replaceWith(valueToLiteral(evaluatedId[0], ex));\n });\n } else {\n // … or hoist them to the root scope\n hoistIdentifier(id);\n }\n });\n }\n\n const kind = isFunction ? ValueType.FUNCTION : ValueType.LAZY;\n\n // Declare _expN const with the lazy expression\n const declaration = expressionDeclarationTpl({\n expId: createId(expUid),\n expression: evaluated\n ? valueToLiteral(evaluated[0], ex)\n : cloneNode(ex.node),\n }) as VariableDeclaration;\n\n // Insert the declaration as close as possible to the original expression\n const [inserted] = statementInRoot.insertBefore(declaration);\n referenceAll(inserted);\n rootScope.registerDeclaration(inserted);\n\n const importedFrom: string[] = [];\n function findImportSourceOfIdentifier(idPath: NodePath<Identifier>) {\n const exBindingIdentifier = idPath.scope.getBinding(idPath.node.name)\n ?.identifier;\n const exImport =\n imports.find((i) => i.local.node === exBindingIdentifier) ?? null;\n if (exImport) {\n importedFrom.push(exImport.source);\n }\n }\n\n if (ex.isIdentifier()) {\n findImportSourceOfIdentifier(ex);\n } else {\n ex.traverse({\n Identifier: findImportSourceOfIdentifier,\n });\n }\n\n // Replace the expression with the _expN() call\n mutate(ex, (p) => {\n p.replaceWith({\n type: 'CallExpression',\n callee: createId(expUid),\n arguments: [],\n });\n });\n\n // eslint-disable-next-line no-param-reassign\n ex.node.loc = loc;\n\n // noinspection UnnecessaryLocalVariableJS\n const result: Omit<\n LazyValue | FunctionValue,\n 'buildCodeFrameError' | 'source'\n > = {\n kind,\n ex: createId(expUid, loc),\n importedFrom,\n };\n\n return result;\n}\n\nconst debug = logger.extend('template-parse:identify-expressions');\n\n/**\n * Collects, hoists, and makes lazy all expressions in the given template\n * If evaluate is true, it will try to evaluate the expressions\n */\nexport function collectTemplateDependencies(\n path: NodePath<TaggedTemplateExpression>,\n evaluate = false\n): [quasis: TemplateElement[], expressionValues: ExpressionValue[]] {\n const quasi = path.get('quasi');\n const quasis = quasi.get('quasis');\n const expressions = quasi.get('expressions');\n\n debug('Found: %s', expressions.length);\n\n const expressionValues: ExpressionValue[] = expressions.map(\n (ex: NodePath<Expression | TSType>): ExpressionValue => {\n const buildCodeFrameError = ex.buildCodeFrameError.bind(ex);\n const source = getSource(ex);\n\n if (!ex.isExpression()) {\n throw buildCodeFrameError(\n `The expression '${source}' is not supported.`\n );\n }\n\n const extracted = extractExpression(ex, evaluate);\n\n return {\n ...extracted,\n source,\n buildCodeFrameError,\n } as ExpressionValue;\n }\n );\n\n return [quasis.map((p) => p.node), expressionValues];\n}\n"],"mappings":";;;;;;;AAOA,IAAAA,SAAA,GAAAC,OAAA;AAaA,IAAAC,MAAA,GAAAD,OAAA;AAQA,IAAAE,OAAA,GAAAF,OAAA;AAGA,IAAAG,SAAA,GAAAH,OAAA;AACA,IAAAI,gBAAA,GAAAJ,OAAA;AACA,IAAAK,UAAA,GAAAL,OAAA;AACA,IAAAM,aAAA,GAAAN,OAAA;AACA,IAAAO,eAAA,GAAAP,OAAA;AAnCA;;AAEA;AACA;AACA;AACA;;AAgCA,SAASQ,UAAUA,CACjBC,EAAwB,EACxBC,QAAQ,GAAG,KAAK,EACO;EACvB,IAAI,CAACA,QAAQ,EAAE,OAAOC,SAAS;EAE/B,IAAIF,EAAE,CAACG,YAAY,CAAC,CAAC,EAAE;IACrB,MAAMC,OAAO,GAAGJ,EAAE,CAACK,KAAK,CAACC,UAAU,CAACN,EAAE,CAACO,IAAI,CAACC,IAAI,CAAC;;IAEjD;IACA;IACA,IACEJ,OAAO,aAAPA,OAAO,eAAPA,OAAO,CAAEK,IAAI,CAACC,oBAAoB,CAAC,CAAC,IACpC,CAACN,OAAO,CAACK,IAAI,CAACE,GAAG,CAAC,IAAI,CAAC,CAACR,YAAY,CAAC,CAAC,EACtC;MACA,OAAOD,SAAS;IAClB;EACF;EAEA,MAAMU,MAAM,GAAGZ,EAAE,CAACC,QAAQ,CAAC,CAAC;EAC5B,IAAIW,MAAM,CAACC,SAAS,IAAI,CAAC,IAAAC,mBAAW,EAACF,MAAM,CAACG,KAAK,CAAC,EAAE;IAClD,OAAO,CAACH,MAAM,CAACG,KAAK,CAAC;EACvB;EAEA,OAAOb,SAAS;AAClB;AAEA,MAAMc,wBAAwB,GAAG,IAAAC,mBAAS,EACxC,wCAAwC,EACxC;EACEC,gBAAgB,EAAE;AACpB,CACF,CAAC;AAED,MAAMC,WAAW,GAAGA,CAACnB,EAAY,EAAEoB,MAAe,KAChDpB,EAAE,CAACqB,mBAAmB,CACpB,QACErB,EAAE,CAACG,YAAY,CAAC,CAAC,GAAG,YAAY,GAAG,YAAY,kCACfiB,MAAM,GAAG,gBAAgBA,MAAM,EAAE,GAAG,EAAE,GAC1E,CAAC;AAEH,SAASE,iBAAiBA,CAACb,IAA0C,EAAU;EAC7E,MAAM;IAAED;EAAK,CAAC,GAAGC,IAAI,CAACF,IAAI;EAC1B,MAAMgB,SAAS,GAAGd,IAAI,CAACJ,KAAK,CAACmB,gBAAgB,CAAC,CAAC;EAC/C,IAAID,SAAS,CAACE,UAAU,CAACjB,IAAI,CAAC,EAAE;IAC9B,OAAOe,SAAS,CAACG,WAAW,CAAClB,IAAI,CAAC;EACpC;EAEA,OAAOA,IAAI;AACb;AAEA,SAASmB,uBAAuBA,CAAC3B,EAAgC,EAAE;EACjE,IAAI,CAACA,EAAE,CAACK,KAAK,CAACuB,MAAM,EAAE;IACpB;IACA;EACF;EAEA,MAAMC,qBAAqB,GAAG,IAAAC,gCAAe,EAAC,CAAC9B,EAAE,CAAC,EAAE,WAAW,CAAC;EAChE6B,qBAAqB,CAACE,OAAO,CAAEC,UAAU,IAAK;IAC5C,IAAIA,UAAU,CAAC7B,YAAY,CAAC,CAAC,EAAE;MAC7B8B,eAAe,CAACD,UAAU,CAAC;IAC7B;EACF,CAAC,CAAC;EAEF,MAAME,kBAAkB,GAAG,IAAAJ,gCAAe,EAAC,CAAC9B,EAAE,CAAC,EAAE,aAAa,CAAC;EAE/DkC,kBAAkB,CAACH,OAAO,CAAEtB,IAAI,IAAK;IACnC,MAAM0B,OAAO,GAAGb,iBAAiB,CAACb,IAAI,CAAC;IACvC,IAAI0B,OAAO,KAAK1B,IAAI,CAACF,IAAI,CAACC,IAAI,EAAE;MAC9BC,IAAI,CAACJ,KAAK,CAAC+B,MAAM,CAAC3B,IAAI,CAACF,IAAI,CAACC,IAAI,EAAE2B,OAAO,CAAC;IAC5C;EACF,CAAC,CAAC;EAEF,MAAMZ,SAAS,GAAGvB,EAAE,CAACK,KAAK,CAACmB,gBAAgB,CAAC,CAAC;EAE7C,MAAMa,eAAe,GAAGrC,EAAE,CAACsC,UAAU,CAClCC,CAAC;IAAA,IAAAC,aAAA;IAAA,OAAK,EAAAA,aAAA,GAAAD,CAAC,CAACE,UAAU,cAAAD,aAAA,uBAAZA,aAAA,CAAcE,SAAS,CAAC,CAAC,MAAK,IAAI;EAAA,CAC3C,CAAwB;EAExB,MAAMC,WAAgC,GAAG;IACvCC,IAAI,EAAE,qBAAqB;IAC3BC,IAAI,EAAE,KAAK;IACXC,YAAY,EAAE,CAAC,IAAAC,gBAAS,EAAC/C,EAAE,CAACO,IAAI,CAAC;EACnC,CAAC;EAED,MAAM,CAACyC,QAAQ,CAAC,GAAGX,eAAe,CAACY,YAAY,CAACN,WAAW,CAAC;EAC5D,IAAAO,0BAAY,EAACF,QAAQ,CAAC;EACtBzB,SAAS,CAAC4B,mBAAmB,CAACH,QAAQ,CAAC;AACzC;AAEA,SAASf,eAAeA,CAACmB,MAA4B,EAAQ;EAC3D,IAAI,CAACA,MAAM,CAACC,YAAY,CAAC,CAAC,EAAE;IAC1B,MAAMlC,WAAW,CAACiC,MAAM,CAAC;EAC3B;EAEA,MAAMhD,OAAO,GAAGgD,MAAM,CAAC/C,KAAK,CAACC,UAAU,CAAC8C,MAAM,CAAC7C,IAAI,CAACC,IAAI,CAAC;EACzD,IAAI,CAACJ,OAAO,EAAE;IACZ;IACA,MAAMe,WAAW,CAACiC,MAAM,EAAE,cAAc,CAAC;EAC3C;EAEA,IAAIhD,OAAO,CAACyC,IAAI,KAAK,QAAQ,EAAE;IAC7B;IACA;EACF;EAEA,IAAI,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,CAAC,CAACS,QAAQ,CAAClD,OAAO,CAACyC,IAAI,CAAC,EAAE;IAC9D;IACA,MAAM1B,WAAW,CAACf,OAAO,CAACK,IAAI,EAAE,yBAAyB,CAAC;EAC5D;EAEA,MAAM;IAAEJ,KAAK;IAAEI,IAAI,EAAE8C;EAAY,CAAC,GAAGnD,OAAO;EAC5C;EACA,IAAI,CAACC,KAAK,CAACuB,MAAM,EAAE;IACjB;IACA;EACF;EAEA,IAAI2B,WAAW,CAAC7C,oBAAoB,CAAC,CAAC,EAAE;IACtCiB,uBAAuB,CAAC4B,WAAW,CAAC;IAEpC;EACF;EAEA,MAAMpC,WAAW,CAACiC,MAAM,CAAC;AAC3B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASI,iBAAiBA,CAC/BxD,EAAwB,EACxBC,QAAQ,GAAG,KAAK,EAChBwD,OAAkB,GAAG,EAAE,EACkC;EACzD,IACEzD,EAAE,CAAC0D,SAAS,CAAC,CAAC,KACb,OAAO,IAAI1D,EAAE,CAACO,IAAI,IAAIP,EAAE,CAACO,IAAI,CAACqC,IAAI,KAAK,aAAa,CAAC,EACtD;IACA,OAAO;MACL5C,EAAE,EAAEA,EAAE,CAACO,IAAI;MACXsC,IAAI,EAAEc,iBAAS,CAACC,KAAK;MACrB7C,KAAK,EAAEf,EAAE,CAACO,IAAI,CAACqC,IAAI,KAAK,aAAa,GAAG,IAAI,GAAG5C,EAAE,CAACO,IAAI,CAACQ;IACzD,CAAC;EACH;EAEA,MAAM;IAAE8C;EAAI,CAAC,GAAG7D,EAAE,CAACO,IAAI;EAEvB,MAAMgB,SAAS,GAAGvB,EAAE,CAACK,KAAK,CAACmB,gBAAgB,CAAC,CAAC;EAC7C,MAAMa,eAAe,GAAGrC,EAAE,CAACsC,UAAU,CAClCC,CAAC;IAAA,IAAAuB,cAAA;IAAA,OAAK,EAAAA,cAAA,GAAAvB,CAAC,CAACE,UAAU,cAAAqB,cAAA,uBAAZA,cAAA,CAAcpB,SAAS,CAAC,CAAC,MAAK,IAAI;EAAA,CAC3C,CAAwB;EAExB,MAAMqB,UAAU,GACd/D,EAAE,CAACgE,oBAAoB,CAAC,CAAC,IAAIhE,EAAE,CAACiE,yBAAyB,CAAC,CAAC;;EAE7D;EACA,MAAMC,MAAM,GAAG3C,SAAS,CAACG,WAAW,CAAC,KAAK,CAAC;EAE3C,MAAMyC,SAAS,GAAGpE,UAAU,CAACC,EAAE,EAAEC,QAAQ,CAAC;EAE1C,IAAI,CAACkE,SAAS,EAAE;IACd;IACA;;IAEA;IACA,IAAArC,gCAAe,EAAC,CAAC9B,EAAE,CAAC,EAAE,WAAW,CAAC,CAAC+B,OAAO,CAAEqC,EAAE,IAAK;MACjD,IAAI,CAACA,EAAE,CAACjE,YAAY,CAAC,CAAC,EAAE;;MAExB;MACA,MAAMkE,WAAW,GAAGtE,UAAU,CAACqE,EAAE,EAAEnE,QAAQ,CAAC;MAC5C,IAAIoE,WAAW,EAAE;QACf,IAAAC,oBAAM,EAACF,EAAE,EAAG7B,CAAC,IAAK;UAChBA,CAAC,CAACgC,WAAW,CAAC,IAAAC,8BAAc,EAACH,WAAW,CAAC,CAAC,CAAC,EAAErE,EAAE,CAAC,CAAC;QACnD,CAAC,CAAC;MACJ,CAAC,MAAM;QACL;QACAiC,eAAe,CAACmC,EAAE,CAAC;MACrB;IACF,CAAC,CAAC;EACJ;EAEA,MAAMvB,IAAI,GAAGkB,UAAU,GAAGJ,iBAAS,CAACc,QAAQ,GAAGd,iBAAS,CAACe,IAAI;;EAE7D;EACA,MAAM/B,WAAW,GAAG3B,wBAAwB,CAAC;IAC3C2D,KAAK,EAAE,IAAAC,kBAAQ,EAACV,MAAM,CAAC;IACvBW,UAAU,EAAEV,SAAS,GACjB,IAAAK,8BAAc,EAACL,SAAS,CAAC,CAAC,CAAC,EAAEnE,EAAE,CAAC,GAChC,IAAA+C,gBAAS,EAAC/C,EAAE,CAACO,IAAI;EACvB,CAAC,CAAwB;;EAEzB;EACA,MAAM,CAACyC,QAAQ,CAAC,GAAGX,eAAe,CAACY,YAAY,CAACN,WAAW,CAAC;EAC5D,IAAAO,0BAAY,EAACF,QAAQ,CAAC;EACtBzB,SAAS,CAAC4B,mBAAmB,CAACH,QAAQ,CAAC;EAEvC,MAAM8B,YAAsB,GAAG,EAAE;EACjC,SAASC,4BAA4BA,CAAC3B,MAA4B,EAAE;IAAA,IAAA4B,qBAAA,EAAAC,aAAA;IAClE,MAAMC,mBAAmB,IAAAF,qBAAA,GAAG5B,MAAM,CAAC/C,KAAK,CAACC,UAAU,CAAC8C,MAAM,CAAC7C,IAAI,CAACC,IAAI,CAAC,cAAAwE,qBAAA,uBAAzCA,qBAAA,CACxBhD,UAAU;IACd,MAAMmD,QAAQ,IAAAF,aAAA,GACZxB,OAAO,CAAC2B,IAAI,CAAEC,CAAC,IAAKA,CAAC,CAACC,KAAK,CAAC/E,IAAI,KAAK2E,mBAAmB,CAAC,cAAAD,aAAA,cAAAA,aAAA,GAAI,IAAI;IACnE,IAAIE,QAAQ,EAAE;MACZL,YAAY,CAACS,IAAI,CAACJ,QAAQ,CAACK,MAAM,CAAC;IACpC;EACF;EAEA,IAAIxF,EAAE,CAACG,YAAY,CAAC,CAAC,EAAE;IACrB4E,4BAA4B,CAAC/E,EAAE,CAAC;EAClC,CAAC,MAAM;IACLA,EAAE,CAACyF,QAAQ,CAAC;MACVC,UAAU,EAAEX;IACd,CAAC,CAAC;EACJ;;EAEA;EACA,IAAAT,oBAAM,EAACtE,EAAE,EAAGuC,CAAC,IAAK;IAChBA,CAAC,CAACgC,WAAW,CAAC;MACZ3B,IAAI,EAAE,gBAAgB;MACtB+C,MAAM,EAAE,IAAAf,kBAAQ,EAACV,MAAM,CAAC;MACxB0B,SAAS,EAAE;IACb,CAAC,CAAC;EACJ,CAAC,CAAC;;EAEF;EACA5F,EAAE,CAACO,IAAI,CAACsD,GAAG,GAAGA,GAAG;;EAEjB;EACA,MAAMjD,MAGL,GAAG;IACFiC,IAAI;IACJ7C,EAAE,EAAE,IAAA4E,kBAAQ,EAACV,MAAM,EAAEL,GAAG,CAAC;IACzBiB;EACF,CAAC;EAED,OAAOlE,MAAM;AACf;AAEA,MAAMiF,KAAK,GAAGC,cAAM,CAACC,MAAM,CAAC,qCAAqC,CAAC;;AAElE;AACA;AACA;AACA;AACO,SAASC,2BAA2BA,CACzCvF,IAAwC,EACxCR,QAAQ,GAAG,KAAK,EACkD;EAClE,MAAMgG,KAAK,GAAGxF,IAAI,CAACE,GAAG,CAAC,OAAO,CAAC;EAC/B,MAAMuF,MAAM,GAAGD,KAAK,CAACtF,GAAG,CAAC,QAAQ,CAAC;EAClC,MAAMwF,WAAW,GAAGF,KAAK,CAACtF,GAAG,CAAC,aAAa,CAAC;EAE5CkF,KAAK,CAAC,WAAW,EAAEM,WAAW,CAACC,MAAM,CAAC;EAEtC,MAAMC,gBAAmC,GAAGF,WAAW,CAACG,GAAG,CACxDtG,EAAiC,IAAsB;IACtD,MAAMqB,mBAAmB,GAAGrB,EAAE,CAACqB,mBAAmB,CAACkF,IAAI,CAACvG,EAAE,CAAC;IAC3D,MAAMwF,MAAM,GAAG,IAAAgB,oBAAS,EAACxG,EAAE,CAAC;IAE5B,IAAI,CAACA,EAAE,CAACyG,YAAY,CAAC,CAAC,EAAE;MACtB,MAAMpF,mBAAmB,CACvB,mBAAmBmE,MAAM,qBAC3B,CAAC;IACH;IAEA,MAAMkB,SAAS,GAAGlD,iBAAiB,CAACxD,EAAE,EAAEC,QAAQ,CAAC;IAEjD,OAAO;MACL,GAAGyG,SAAS;MACZlB,MAAM;MACNnE;IACF,CAAC;EACH,CACF,CAAC;EAED,OAAO,CAAC6E,MAAM,CAACI,GAAG,CAAE/D,CAAC,IAAKA,CAAC,CAAChC,IAAI,CAAC,EAAE8F,gBAAgB,CAAC;AACtD","ignoreList":[]}
|
package/package.json
CHANGED
package/types/cache.d.ts
CHANGED
|
@@ -25,6 +25,7 @@ export declare class TransformCacheCollection<TEntrypoint extends IBaseCachedEnt
|
|
|
25
25
|
readonly exports: Map<string, string[]>;
|
|
26
26
|
private readonly barrelManifestDependencies;
|
|
27
27
|
private contentHashes;
|
|
28
|
+
private fileMtimes;
|
|
28
29
|
private readonly exportDependencies;
|
|
29
30
|
constructor(caches?: Partial<ICaches<TEntrypoint>>);
|
|
30
31
|
add<TCache extends CacheNames, TValue extends MapValue<ICaches<TEntrypoint>[TCache]>>(cacheName: TCache, key: string, value: TValue): void;
|
|
@@ -40,6 +41,12 @@ export declare class TransformCacheCollection<TEntrypoint extends IBaseCachedEnt
|
|
|
40
41
|
private getCachedDependencies;
|
|
41
42
|
private getDependencyCache;
|
|
42
43
|
private hasCachedDependencies;
|
|
44
|
+
/**
|
|
45
|
+
* Fast check if a file changed on disk since last seen.
|
|
46
|
+
* Uses mtime as a fast path — only reads the file if mtime differs.
|
|
47
|
+
* Returns true if the file changed (cache was invalidated).
|
|
48
|
+
*/
|
|
49
|
+
checkFreshness(filename: string, strippedFilename: string): boolean;
|
|
43
50
|
private setContentHash;
|
|
44
51
|
}
|
|
45
52
|
export {};
|
package/types/cache.js
CHANGED
|
@@ -12,6 +12,13 @@ const parseRequest_1 = require("./utils/parseRequest");
|
|
|
12
12
|
function hashContent(content) {
|
|
13
13
|
return (0, crypto_1.createHash)('sha256').update(content).digest('hex');
|
|
14
14
|
}
|
|
15
|
+
function isMissingFileError(error) {
|
|
16
|
+
if (!error || typeof error !== 'object') {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
const { code } = error;
|
|
20
|
+
return code === 'ENOENT' || code === 'ENOTDIR';
|
|
21
|
+
}
|
|
15
22
|
const cacheLogger = shared_1.logger.extend('cache');
|
|
16
23
|
const cacheNames = ['barrelManifests', 'entrypoints', 'exports'];
|
|
17
24
|
const loggers = cacheNames.reduce((acc, key) => ({
|
|
@@ -24,6 +31,7 @@ class TransformCacheCollection {
|
|
|
24
31
|
exports;
|
|
25
32
|
barrelManifestDependencies = new Map();
|
|
26
33
|
contentHashes = new Map();
|
|
34
|
+
fileMtimes = new Map();
|
|
27
35
|
exportDependencies = new Map();
|
|
28
36
|
constructor(caches = {}) {
|
|
29
37
|
this.barrelManifests = caches.barrelManifests || new Map();
|
|
@@ -157,7 +165,19 @@ class TransformCacheCollection {
|
|
|
157
165
|
for (const [, dependency] of dependenciesToCheck) {
|
|
158
166
|
const dependencyFilename = dependency.resolved;
|
|
159
167
|
if (dependencyFilename) {
|
|
160
|
-
|
|
168
|
+
let dependencyContent;
|
|
169
|
+
try {
|
|
170
|
+
dependencyContent = node_fs_1.default.readFileSync((0, parseRequest_1.stripQueryAndHash)(dependencyFilename), 'utf8');
|
|
171
|
+
}
|
|
172
|
+
catch (error) {
|
|
173
|
+
if (!isMissingFileError(error)) {
|
|
174
|
+
throw error;
|
|
175
|
+
}
|
|
176
|
+
this.invalidateForFile(dependencyFilename);
|
|
177
|
+
anyDepChanged = true;
|
|
178
|
+
// eslint-disable-next-line no-continue
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
161
181
|
const dependencyChanged = this.invalidateIfChanged(dependencyFilename, dependencyContent, visitedFiles, 'fs', changedFiles);
|
|
162
182
|
if (dependencyChanged &&
|
|
163
183
|
invalidateOnDependencyChange?.has(dependencyFilename)) {
|
|
@@ -249,13 +269,49 @@ class TransformCacheCollection {
|
|
|
249
269
|
hasCachedDependencies(filename) {
|
|
250
270
|
return this.getCachedDependencies(filename).size > 0;
|
|
251
271
|
}
|
|
272
|
+
/**
|
|
273
|
+
* Fast check if a file changed on disk since last seen.
|
|
274
|
+
* Uses mtime as a fast path — only reads the file if mtime differs.
|
|
275
|
+
* Returns true if the file changed (cache was invalidated).
|
|
276
|
+
*/
|
|
277
|
+
checkFreshness(filename, strippedFilename) {
|
|
278
|
+
try {
|
|
279
|
+
const currentMtime = node_fs_1.default.statSync(strippedFilename).mtimeMs;
|
|
280
|
+
const cachedMtime = this.fileMtimes.get(filename);
|
|
281
|
+
if (cachedMtime !== undefined && currentMtime === cachedMtime) {
|
|
282
|
+
return false;
|
|
283
|
+
}
|
|
284
|
+
const content = node_fs_1.default.readFileSync(strippedFilename, 'utf-8');
|
|
285
|
+
this.fileMtimes.set(filename, currentMtime);
|
|
286
|
+
if (this.invalidateIfChanged(filename, content, undefined, 'fs')) {
|
|
287
|
+
return true;
|
|
288
|
+
}
|
|
289
|
+
return false;
|
|
290
|
+
}
|
|
291
|
+
catch (error) {
|
|
292
|
+
if (!isMissingFileError(error)) {
|
|
293
|
+
throw error;
|
|
294
|
+
}
|
|
295
|
+
this.invalidateForFile(filename);
|
|
296
|
+
return true;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
252
299
|
setContentHash(filename, source, hash) {
|
|
253
300
|
const current = this.contentHashes.get(filename);
|
|
254
301
|
if (current) {
|
|
255
302
|
current[source] = hash;
|
|
256
|
-
return;
|
|
257
303
|
}
|
|
258
|
-
|
|
304
|
+
else {
|
|
305
|
+
this.contentHashes.set(filename, { [source]: hash });
|
|
306
|
+
}
|
|
307
|
+
if (source === 'fs') {
|
|
308
|
+
try {
|
|
309
|
+
this.fileMtimes.set(filename, node_fs_1.default.statSync((0, parseRequest_1.stripQueryAndHash)(filename)).mtimeMs);
|
|
310
|
+
}
|
|
311
|
+
catch {
|
|
312
|
+
// ignore
|
|
313
|
+
}
|
|
314
|
+
}
|
|
259
315
|
}
|
|
260
316
|
}
|
|
261
317
|
exports.TransformCacheCollection = TransformCacheCollection;
|
package/types/module.js
CHANGED
|
@@ -326,10 +326,15 @@ class Module {
|
|
|
326
326
|
if (extension !== '.json' && !this.extensions.includes(extension)) {
|
|
327
327
|
return null;
|
|
328
328
|
}
|
|
329
|
-
|
|
329
|
+
let entrypoint = this.cache.get('entrypoints', filename);
|
|
330
330
|
if (entrypoint && (0, Entrypoint_helpers_1.isSuperSet)(entrypoint.evaluatedOnly ?? [], only)) {
|
|
331
|
-
|
|
332
|
-
|
|
331
|
+
if (this.cache.checkFreshness(filename, strippedFilename)) {
|
|
332
|
+
entrypoint = undefined;
|
|
333
|
+
}
|
|
334
|
+
if (entrypoint) {
|
|
335
|
+
log('✅ file has been already evaluated');
|
|
336
|
+
return entrypoint;
|
|
337
|
+
}
|
|
333
338
|
}
|
|
334
339
|
if (entrypoint?.ignored) {
|
|
335
340
|
log('✅ file has been ignored during prepare stage. Original code will be used');
|
|
@@ -43,7 +43,7 @@ export declare class Entrypoint extends BaseEntrypoint {
|
|
|
43
43
|
assertNotSuperseded(): void;
|
|
44
44
|
assertTransformed(): void;
|
|
45
45
|
beginProcessing(): void;
|
|
46
|
-
createAction<TType extends ActionTypes, TAction extends ActionByType<TType>>(actionType: TType, data: TAction['data'], abortSignal?: AbortSignal | null): BaseAction<TAction>;
|
|
46
|
+
createAction<TType extends ActionTypes, TAction extends ActionByType<TType>>(actionType: TType, data: TAction['data'], abortSignal?: AbortSignal | null, actionContext?: unknown): BaseAction<TAction>;
|
|
47
47
|
createChild(name: string, only: string[], loadedCode?: string): Entrypoint | 'loop';
|
|
48
48
|
createEvaluated(): EvaluatedEntrypoint;
|
|
49
49
|
endProcessing(): void;
|
|
@@ -14,6 +14,7 @@ const BaseAction_1 = require("./actions/BaseAction");
|
|
|
14
14
|
const UnprocessedEntrypointError_1 = require("./actions/UnprocessedEntrypointError");
|
|
15
15
|
const parseRequest_1 = require("../utils/parseRequest");
|
|
16
16
|
const EMPTY_FILE = '=== empty file ===';
|
|
17
|
+
const DEFAULT_ACTION_CONTEXT = Symbol('defaultActionContext');
|
|
17
18
|
function hasLoop(name, parent, processed = []) {
|
|
18
19
|
if (parent.name === name || processed.includes(parent.name)) {
|
|
19
20
|
return true;
|
|
@@ -201,16 +202,20 @@ class Entrypoint extends BaseEntrypoint_1.BaseEntrypoint {
|
|
|
201
202
|
beginProcessing() {
|
|
202
203
|
this.#isProcessing = true;
|
|
203
204
|
}
|
|
204
|
-
createAction(actionType, data, abortSignal = null) {
|
|
205
|
+
createAction(actionType, data, abortSignal = null, actionContext = DEFAULT_ACTION_CONTEXT) {
|
|
205
206
|
if (!this.actionsCache.has(actionType)) {
|
|
206
207
|
this.actionsCache.set(actionType, new Map());
|
|
207
208
|
}
|
|
208
|
-
const
|
|
209
|
+
const contexts = this.actionsCache.get(actionType);
|
|
210
|
+
if (!contexts.has(actionContext)) {
|
|
211
|
+
contexts.set(actionContext, new Map());
|
|
212
|
+
}
|
|
213
|
+
const cache = contexts.get(actionContext);
|
|
209
214
|
const cached = cache.get(data);
|
|
210
215
|
if (cached && !cached.abortSignal?.aborted) {
|
|
211
216
|
return cached;
|
|
212
217
|
}
|
|
213
|
-
const newAction = new BaseAction_1.BaseAction(actionType, this.services, this, data, abortSignal);
|
|
218
|
+
const newAction = new BaseAction_1.BaseAction(actionType, this.services, this, data, abortSignal, actionContext);
|
|
214
219
|
cache.set(data, newAction);
|
|
215
220
|
this.services.eventEmitter.entrypointEvent(this.seqId, {
|
|
216
221
|
type: 'actionCreated',
|
|
@@ -13,13 +13,14 @@ export declare class BaseAction<TAction extends ActionQueueItem> implements GetB
|
|
|
13
13
|
readonly entrypoint: Entrypoint;
|
|
14
14
|
readonly data: TAction['data'];
|
|
15
15
|
readonly abortSignal: AbortSignal | null;
|
|
16
|
+
readonly actionContext: unknown;
|
|
16
17
|
readonly idx: string;
|
|
17
18
|
result: TypeOfResult<TAction> | typeof Pending;
|
|
18
19
|
private activeScenario;
|
|
19
20
|
private activeScenarioError?;
|
|
20
21
|
private activeScenarioNextResults;
|
|
21
22
|
private handler;
|
|
22
|
-
constructor(type: TAction['type'], services: Services, entrypoint: Entrypoint, data: TAction['data'], abortSignal: AbortSignal | null);
|
|
23
|
+
constructor(type: TAction['type'], services: Services, entrypoint: Entrypoint, data: TAction['data'], abortSignal: AbortSignal | null, actionContext: unknown);
|
|
23
24
|
get log(): Debugger;
|
|
24
25
|
get ref(): string;
|
|
25
26
|
createAbortSignal(): AbortSignal & Disposable;
|
|
@@ -11,18 +11,20 @@ class BaseAction {
|
|
|
11
11
|
entrypoint;
|
|
12
12
|
data;
|
|
13
13
|
abortSignal;
|
|
14
|
+
actionContext;
|
|
14
15
|
idx;
|
|
15
16
|
result = types_1.Pending;
|
|
16
17
|
activeScenario = null;
|
|
17
18
|
activeScenarioError;
|
|
18
19
|
activeScenarioNextResults = [];
|
|
19
20
|
handler = null;
|
|
20
|
-
constructor(type, services, entrypoint, data, abortSignal) {
|
|
21
|
+
constructor(type, services, entrypoint, data, abortSignal, actionContext) {
|
|
21
22
|
this.type = type;
|
|
22
23
|
this.services = services;
|
|
23
24
|
this.entrypoint = entrypoint;
|
|
24
25
|
this.data = data;
|
|
25
26
|
this.abortSignal = abortSignal;
|
|
27
|
+
this.actionContext = actionContext;
|
|
26
28
|
actionIdx += 1;
|
|
27
29
|
this.idx = actionIdx.toString(16).padStart(6, '0');
|
|
28
30
|
}
|
|
@@ -36,7 +36,7 @@ async function asyncActionRunner(action, actionHandlers, stack = [getActionRef(a
|
|
|
36
36
|
return result.value;
|
|
37
37
|
}
|
|
38
38
|
const [type, entrypoint, data, abortSignal] = result.value;
|
|
39
|
-
const nextAction = entrypoint.createAction(type, data, abortSignal);
|
|
39
|
+
const nextAction = entrypoint.createAction(type, data, abortSignal, action.actionContext);
|
|
40
40
|
try {
|
|
41
41
|
actionResult = await asyncActionRunner(nextAction, actionHandlers, [
|
|
42
42
|
...stack,
|
|
@@ -70,7 +70,7 @@ function syncActionRunner(action, actionHandlers, stack = [getActionRef(action.t
|
|
|
70
70
|
return result.value;
|
|
71
71
|
}
|
|
72
72
|
const [type, entrypoint, data, abortSignal] = result.value;
|
|
73
|
-
const nextAction = entrypoint.createAction(type, data, abortSignal);
|
|
73
|
+
const nextAction = entrypoint.createAction(type, data, abortSignal, action.actionContext);
|
|
74
74
|
try {
|
|
75
75
|
actionResult = syncActionRunner(nextAction, actionHandlers, [
|
|
76
76
|
...stack,
|
|
@@ -57,7 +57,10 @@ const shaker_1 = require("../../shaker");
|
|
|
57
57
|
const AbortError_1 = require("../actions/AbortError");
|
|
58
58
|
const barrelManifest_1 = require("../barrelManifest");
|
|
59
59
|
const shouldSkipExplodeReexports = (action) => {
|
|
60
|
-
const { loadedAndParsed } = action.entrypoint;
|
|
60
|
+
const { loadedAndParsed, only } = action.entrypoint;
|
|
61
|
+
if (only.length === 1 && only[0] === '__wywPreval') {
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
61
64
|
if (loadedAndParsed.evaluator !== shaker_1.shaker || !loadedAndParsed.ast) {
|
|
62
65
|
return false;
|
|
63
66
|
}
|
|
@@ -34,6 +34,7 @@ export type AnyIteratorResult<TMode extends 'async' | 'sync', TResult> = {
|
|
|
34
34
|
sync: IteratorResult<YieldArg, TResult>;
|
|
35
35
|
}[TMode];
|
|
36
36
|
export interface IBaseAction<TAction extends ActionQueueItem, TResult, TData> extends IBaseNode {
|
|
37
|
+
actionContext: unknown;
|
|
37
38
|
abortSignal: AbortSignal | null;
|
|
38
39
|
createAbortSignal: () => AbortSignal & Disposable;
|
|
39
40
|
data: TData;
|
package/types/transform.js
CHANGED
|
@@ -21,6 +21,24 @@ const resolveImports_1 = require("./transform/generators/resolveImports");
|
|
|
21
21
|
const withDefaultServices_1 = require("./transform/helpers/withDefaultServices");
|
|
22
22
|
const memoizedSyncResolve = new WeakMap();
|
|
23
23
|
const memoizedAsyncResolve = new WeakMap();
|
|
24
|
+
const EMPTY_CUSTOM_HANDLERS = {};
|
|
25
|
+
const memoizedActionContexts = new WeakMap();
|
|
26
|
+
const getActionContext = (resolveImportsHandler, customHandlers) => {
|
|
27
|
+
const customHandlersKey = Object.keys(customHandlers).length === 0
|
|
28
|
+
? EMPTY_CUSTOM_HANDLERS
|
|
29
|
+
: customHandlers;
|
|
30
|
+
let actionContextsByHandlers = memoizedActionContexts.get(resolveImportsHandler);
|
|
31
|
+
if (!actionContextsByHandlers) {
|
|
32
|
+
actionContextsByHandlers = new WeakMap();
|
|
33
|
+
memoizedActionContexts.set(resolveImportsHandler, actionContextsByHandlers);
|
|
34
|
+
}
|
|
35
|
+
let actionContext = actionContextsByHandlers.get(customHandlersKey);
|
|
36
|
+
if (!actionContext) {
|
|
37
|
+
actionContext = {};
|
|
38
|
+
actionContextsByHandlers.set(customHandlersKey, actionContext);
|
|
39
|
+
}
|
|
40
|
+
return actionContext;
|
|
41
|
+
};
|
|
24
42
|
function transformSync(partialServices, originalCode, syncResolve, customHandlers = {}) {
|
|
25
43
|
const { options } = partialServices;
|
|
26
44
|
const pluginOptions = (0, loadWywOptions_1.loadWywOptions)(options.pluginOptions);
|
|
@@ -35,6 +53,18 @@ function transformSync(partialServices, originalCode, syncResolve, customHandler
|
|
|
35
53
|
// If global cache is disabled, we need to create a new cache for each file
|
|
36
54
|
services.cache = new cache_1.TransformCacheCollection();
|
|
37
55
|
}
|
|
56
|
+
if (!memoizedSyncResolve.has(syncResolve)) {
|
|
57
|
+
memoizedSyncResolve.set(syncResolve, function resolveImports() {
|
|
58
|
+
return resolveImports_1.syncResolveImports.call(this, syncResolve);
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
const resolveImportsHandler = memoizedSyncResolve.get(syncResolve);
|
|
62
|
+
const actionHandlers = {
|
|
63
|
+
...generators_1.baseHandlers,
|
|
64
|
+
...customHandlers,
|
|
65
|
+
resolveImports: resolveImportsHandler,
|
|
66
|
+
};
|
|
67
|
+
const actionContext = getActionContext(resolveImportsHandler, customHandlers);
|
|
38
68
|
const entrypoint = Entrypoint_1.Entrypoint.createRoot(services, options.filename, ['__wywPreval'], originalCode);
|
|
39
69
|
if (entrypoint.ignored) {
|
|
40
70
|
return {
|
|
@@ -42,18 +72,9 @@ function transformSync(partialServices, originalCode, syncResolve, customHandler
|
|
|
42
72
|
sourceMap: options.inputSourceMap,
|
|
43
73
|
};
|
|
44
74
|
}
|
|
45
|
-
const workflowAction = entrypoint.createAction('workflow', undefined);
|
|
46
|
-
if (!memoizedSyncResolve.has(syncResolve)) {
|
|
47
|
-
memoizedSyncResolve.set(syncResolve, function resolveImports() {
|
|
48
|
-
return resolveImports_1.syncResolveImports.call(this, syncResolve);
|
|
49
|
-
});
|
|
50
|
-
}
|
|
75
|
+
const workflowAction = entrypoint.createAction('workflow', undefined, null, actionContext);
|
|
51
76
|
try {
|
|
52
|
-
const result = (0, actionRunner_1.syncActionRunner)(workflowAction,
|
|
53
|
-
...generators_1.baseHandlers,
|
|
54
|
-
...customHandlers,
|
|
55
|
-
resolveImports: memoizedSyncResolve.get(syncResolve),
|
|
56
|
-
});
|
|
77
|
+
const result = (0, actionRunner_1.syncActionRunner)(workflowAction, actionHandlers);
|
|
57
78
|
entrypoint.log('%s is ready', entrypoint.name);
|
|
58
79
|
return result;
|
|
59
80
|
}
|
|
@@ -92,6 +113,19 @@ async function transform(partialServices, originalCode, asyncResolve, customHand
|
|
|
92
113
|
* but the "only" option has changed, the file will be re-processed using
|
|
93
114
|
* the combined "only" option.
|
|
94
115
|
*/
|
|
116
|
+
if (!memoizedAsyncResolve.has(asyncResolve)) {
|
|
117
|
+
const resolveImports = function resolveImports() {
|
|
118
|
+
return resolveImports_1.asyncResolveImports.call(this, asyncResolve);
|
|
119
|
+
};
|
|
120
|
+
memoizedAsyncResolve.set(asyncResolve, resolveImports);
|
|
121
|
+
}
|
|
122
|
+
const resolveImportsHandler = memoizedAsyncResolve.get(asyncResolve);
|
|
123
|
+
const actionHandlers = {
|
|
124
|
+
...generators_1.baseHandlers,
|
|
125
|
+
...customHandlers,
|
|
126
|
+
resolveImports: resolveImportsHandler,
|
|
127
|
+
};
|
|
128
|
+
const actionContext = getActionContext(resolveImportsHandler, customHandlers);
|
|
95
129
|
const entrypoint = Entrypoint_1.Entrypoint.createRoot(services, options.filename, ['__wywPreval'], originalCode);
|
|
96
130
|
if (entrypoint.ignored) {
|
|
97
131
|
return {
|
|
@@ -99,19 +133,9 @@ async function transform(partialServices, originalCode, asyncResolve, customHand
|
|
|
99
133
|
sourceMap: options.inputSourceMap,
|
|
100
134
|
};
|
|
101
135
|
}
|
|
102
|
-
const workflowAction = entrypoint.createAction('workflow', undefined);
|
|
103
|
-
if (!memoizedAsyncResolve.has(asyncResolve)) {
|
|
104
|
-
const resolveImports = function resolveImports() {
|
|
105
|
-
return resolveImports_1.asyncResolveImports.call(this, asyncResolve);
|
|
106
|
-
};
|
|
107
|
-
memoizedAsyncResolve.set(asyncResolve, resolveImports);
|
|
108
|
-
}
|
|
136
|
+
const workflowAction = entrypoint.createAction('workflow', undefined, null, actionContext);
|
|
109
137
|
try {
|
|
110
|
-
const result = await (0, actionRunner_1.asyncActionRunner)(workflowAction,
|
|
111
|
-
...generators_1.baseHandlers,
|
|
112
|
-
...customHandlers,
|
|
113
|
-
resolveImports: memoizedAsyncResolve.get(asyncResolve),
|
|
114
|
-
});
|
|
138
|
+
const result = await (0, actionRunner_1.asyncActionRunner)(workflowAction, actionHandlers);
|
|
115
139
|
entrypoint.log('%s is ready', entrypoint.name);
|
|
116
140
|
return result;
|
|
117
141
|
}
|
|
@@ -18,6 +18,15 @@ const valueToLiteral_1 = require("./valueToLiteral");
|
|
|
18
18
|
function staticEval(ex, evaluate = false) {
|
|
19
19
|
if (!evaluate)
|
|
20
20
|
return undefined;
|
|
21
|
+
if (ex.isIdentifier()) {
|
|
22
|
+
const binding = ex.scope.getBinding(ex.node.name);
|
|
23
|
+
// Babel may "evaluate" a destructured binding to its source container
|
|
24
|
+
// object/array instead of the bound value, which changes template semantics.
|
|
25
|
+
if (binding?.path.isVariableDeclarator() &&
|
|
26
|
+
!binding.path.get('id').isIdentifier()) {
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
21
30
|
const result = ex.evaluate();
|
|
22
31
|
if (result.confident && !(0, shared_1.hasEvalMeta)(result.value)) {
|
|
23
32
|
return [result.value];
|