refactor: generated .json to in-memory map

This commit is contained in:
bholmesdev 2023-04-26 16:06:02 -04:00
parent 87e9e072cf
commit cc50ee68d4
4 changed files with 39 additions and 24 deletions

View file

@ -28,9 +28,11 @@ const collectionToEntryMap = createCollectionToGlobResultMap({
contentDir,
});
let lookupMap = {};
/* @@LOOKUP_MAP_ASSIGNMENT@@ */
function createGlobLookup(glob) {
return async (collection, lookupId) => {
const { default: lookupMap } = await import('@@LOOKUP_MAP_PATH@@');
const filePath = lookupMap[collection]?.[lookupId];
if (!filePath) return undefined;

View file

@ -8,7 +8,7 @@ import type { AstroSettings, ContentEntryType } from '../@types/astro.js';
import { AstroError, AstroErrorData } from '../core/errors/index.js';
import { info, warn, type LogOptions } from '../core/logger/core.js';
import { isRelativePath } from '../core/path.js';
import { CONTENT_TYPES_FILE } from './consts.js';
import { CONTENT_TYPES_FILE, VIRTUAL_MODULE_ID } from './consts.js';
import {
getContentPaths,
getEntryInfo,
@ -21,7 +21,6 @@ import {
type ContentObservable,
type ContentPaths,
type EntryInfo,
updateLookupMaps,
getContentEntryConfigByExtMap,
} from './utils.js';
@ -280,12 +279,7 @@ export async function createContentTypesGenerator({
contentConfig: observable.status === 'loaded' ? observable.config : undefined,
contentEntryTypes: settings.contentEntryTypes,
});
await updateLookupMaps({
contentEntryConfigByExt,
contentPaths,
root: settings.config.root,
fs,
});
invalidateVirtualMod(viteServer);
if (observable.status === 'loaded' && ['info', 'warn'].includes(logLevel)) {
warnNonexistentCollections({
logging,
@ -298,6 +292,15 @@ export async function createContentTypesGenerator({
return { init, queueEvent };
}
// The virtual module contains a lookup map from slugs to content imports.
// Invalidate whenever content types change.
function invalidateVirtualMod(viteServer: ViteDevServer) {
const virtualMod = viteServer.moduleGraph.getModuleById('\0' + VIRTUAL_MODULE_ID);
if (!virtualMod) return;
viteServer.moduleGraph.invalidateModule(virtualMod);
}
function addCollection(contentMap: ContentTypes, collectionKey: string) {
contentMap[collectionKey] = {};
}

View file

@ -388,7 +388,7 @@ function search(fs: typeof fsMod, srcDir: URL) {
return { exists: false, url: paths[0] };
}
export async function updateLookupMaps({
export async function getStringifiedLookupMap({
contentPaths,
contentEntryConfigByExt,
root,
@ -434,10 +434,7 @@ export async function updateLookupMaps({
filePathByLookupId[collection][slug] = rootRelativePath(root, filePath);
}
await fs.promises.writeFile(
new URL('lookup-map.json', contentPaths.cacheDir),
JSON.stringify(filePathByLookupId, null, 2)
);
return JSON.stringify(filePathByLookupId);
}
export function getExtGlob(exts: string[]) {

View file

@ -2,7 +2,13 @@ import fsMod from 'node:fs';
import type { Plugin } from 'vite';
import type { AstroSettings } from '../@types/astro.js';
import { VIRTUAL_MODULE_ID } from './consts.js';
import { getContentEntryExts, getContentPaths, getExtGlob } from './utils.js';
import {
getContentEntryConfigByExtMap,
getContentEntryExts,
getContentPaths,
getExtGlob,
getStringifiedLookupMap,
} from './utils.js';
import { rootRelativePath } from '../core/util.js';
interface AstroContentVirtualModPluginParams {
@ -14,17 +20,14 @@ export function astroContentVirtualModPlugin({
}: AstroContentVirtualModPluginParams): Plugin {
const contentPaths = getContentPaths(settings.config);
const relContentDir = rootRelativePath(settings.config.root, contentPaths.contentDir);
const contentEntryExts = getContentEntryExts(settings);
const extGlob =
contentEntryExts.length === 1
? // Wrapping {...} breaks when there is only one extension
contentEntryExts[0]
: `{${contentEntryExts.join(',')}}`;
const contentEntryConfigByExt = getContentEntryConfigByExtMap(settings);
const contentEntryExts = [...contentEntryConfigByExt.keys()];
const extGlob = getExtGlob(contentEntryExts);
const entryGlob = `${relContentDir}**/*${extGlob}`;
const virtualModContents = fsMod
.readFileSync(contentPaths.virtualModTemplate, 'utf-8')
.replace('@@LOOKUP_MAP_PATH@@', new URL('lookup-map.json', contentPaths.cacheDir).pathname)
.replace('@@CONTENT_DIR@@', relContentDir)
.replace('@@ENTRY_GLOB_PATH@@', entryGlob)
.replace('@@RENDER_ENTRY_GLOB_PATH@@', entryGlob);
@ -39,10 +42,20 @@ export function astroContentVirtualModPlugin({
return astroContentVirtualModuleId;
}
},
load(id) {
async load(id) {
const stringifiedLookupMap = await getStringifiedLookupMap({
fs: fsMod,
contentPaths,
contentEntryConfigByExt,
root: settings.config.root,
});
if (id === astroContentVirtualModuleId) {
return {
code: virtualModContents,
code: virtualModContents.replace(
'/* @@LOOKUP_MAP_ASSIGNMENT@@ */',
`lookupMap = ${stringifiedLookupMap};`
),
};
}
},