UNPKG

@vue/language-core

Version:
234 lines 9.76 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.computedEmbeddedCodes = computedEmbeddedCodes; exports.resolveCommonLanguageId = resolveCommonLanguageId; const alien_signals_1 = require("alien-signals"); const muggle_string_1 = require("muggle-string"); const buildMappings_1 = require("../utils/buildMappings"); const embeddedFile_1 = require("./embeddedFile"); function computedEmbeddedCodes(plugins, fileName, sfc) { const getNameToBlockMap = (0, alien_signals_1.computed)(() => { const blocks = {}; if (sfc.template) { blocks[sfc.template.name] = sfc.template; } if (sfc.script) { blocks[sfc.script.name] = sfc.script; } if (sfc.scriptSetup) { blocks[sfc.scriptSetup.name] = sfc.scriptSetup; } for (const block of sfc.styles) { blocks[block.name] = block; } for (const block of sfc.customBlocks) { blocks[block.name] = block; } return blocks; }); const getPluginsResult = plugins.map(plugin => computedPluginEmbeddedCodes(plugins, plugin, fileName, sfc, name => getNameToBlockMap()[name])); const getFlatResult = (0, alien_signals_1.computed)(() => getPluginsResult.map(r => r()).flat()); const getStructuredResult = (0, alien_signals_1.computed)(() => { const embeddedCodes = []; let remain = [...getFlatResult()]; while (remain.length) { const beforeLength = remain.length; consumeRemain(); if (beforeLength === remain.length) { break; } } for (const { code } of remain) { console.error('Unable to resolve embedded: ' + code.parentCodeId + ' -> ' + code.id); } return embeddedCodes; function consumeRemain() { for (let i = remain.length - 1; i >= 0; i--) { const { code, snapshot, mappings } = remain[i]; if (!code.parentCodeId) { embeddedCodes.push({ id: code.id, languageId: resolveCommonLanguageId(code.lang), linkedCodeMappings: code.linkedCodeMappings, snapshot, mappings, embeddedCodes: [], }); remain.splice(i, 1); } else { const parent = findParentStructure(code.parentCodeId, embeddedCodes); if (parent) { parent.embeddedCodes ??= []; parent.embeddedCodes.push({ id: code.id, languageId: resolveCommonLanguageId(code.lang), linkedCodeMappings: code.linkedCodeMappings, snapshot, mappings, embeddedCodes: [], }); remain.splice(i, 1); } } } } function findParentStructure(id, current) { for (const child of current) { if (child.id === id) { return child; } let parent = findParentStructure(id, child.embeddedCodes ?? []); if (parent) { return parent; } } } }); return getStructuredResult; } function computedPluginEmbeddedCodes(plugins, plugin, fileName, sfc, getBlockByName) { const computeds = new Map(); const getComputedKey = (code) => code.id + '__' + code.lang; const getCodes = (0, alien_signals_1.computed)(() => { try { if (!plugin.getEmbeddedCodes) { return [...computeds.values()]; } const embeddedCodeInfos = plugin.getEmbeddedCodes(fileName, sfc); for (const oldId of computeds.keys()) { if (!embeddedCodeInfos.some(code => getComputedKey(code) === oldId)) { computeds.delete(oldId); } } for (const codeInfo of embeddedCodeInfos) { if (!computeds.has(getComputedKey(codeInfo))) { computeds.set(getComputedKey(codeInfo), (0, alien_signals_1.computed)(() => { const content = []; const code = new embeddedFile_1.VueEmbeddedCode(codeInfo.id, codeInfo.lang, content); for (const plugin of plugins) { if (!plugin.resolveEmbeddedCode) { continue; } try { plugin.resolveEmbeddedCode(fileName, sfc, code); } catch (e) { console.error(e); } } const newText = (0, muggle_string_1.toString)(code.content); const changeRanges = new Map(); const snapshot = { getText: (start, end) => newText.slice(start, end), getLength: () => newText.length, getChangeRange(oldSnapshot) { if (!changeRanges.has(oldSnapshot)) { changeRanges.set(oldSnapshot, undefined); const oldText = oldSnapshot.getText(0, oldSnapshot.getLength()); const changeRange = fullDiffTextChangeRange(oldText, newText); if (changeRange) { changeRanges.set(oldSnapshot, changeRange); } } return changeRanges.get(oldSnapshot); }, }; return { code, snapshot, }; })); } } } catch (e) { console.error(e); } return [...computeds.values()]; }); return (0, alien_signals_1.computed)(() => { return getCodes().map(_file => { const { code, snapshot } = _file(); const mappings = (0, buildMappings_1.buildMappings)(code.content.map(segment => { if (typeof segment === 'string') { return segment; } const source = segment[1]; if (source === undefined) { return segment; } const block = getBlockByName(source); if (!block) { // console.warn('Unable to find block: ' + source); return segment; } return [ segment[0], undefined, segment[2] + block.startTagEnd, segment[3], ]; })); const newMappings = []; for (let i = 0; i < mappings.length; i++) { const mapping = mappings[i]; if (mapping.data.__combineOffset !== undefined) { const offsetMapping = mappings[i - mapping.data.__combineOffset]; if (typeof offsetMapping === 'string' || !offsetMapping) { throw new Error('Invalid offset mapping, mappings: ' + mappings.length + ', i: ' + i + ', offset: ' + mapping.data.__combineOffset); } offsetMapping.sourceOffsets.push(...mapping.sourceOffsets); offsetMapping.generatedOffsets.push(...mapping.generatedOffsets); offsetMapping.lengths.push(...mapping.lengths); continue; } newMappings.push(mapping); } return { code, snapshot, mappings: newMappings, }; }); }); } function fullDiffTextChangeRange(oldText, newText) { for (let start = 0; start < oldText.length && start < newText.length; start++) { if (oldText[start] !== newText[start]) { let end = oldText.length; for (let i = 0; i < oldText.length - start && i < newText.length - start; i++) { if (oldText[oldText.length - i - 1] !== newText[newText.length - i - 1]) { break; } end--; } let length = end - start; let newLength = length + (newText.length - oldText.length); if (newLength < 0) { length -= newLength; newLength = 0; } return { span: { start, length }, newLength, }; } } } function resolveCommonLanguageId(lang) { switch (lang) { case 'js': return 'javascript'; case 'cjs': return 'javascript'; case 'mjs': return 'javascript'; case 'ts': return 'typescript'; case 'cts': return 'typescript'; case 'mts': return 'typescript'; case 'jsx': return 'javascriptreact'; case 'tsx': return 'typescriptreact'; case 'pug': return 'jade'; case 'md': return 'markdown'; } return lang; } //# sourceMappingURL=computedEmbeddedCodes.js.map