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, contentDir,
}); });
let lookupMap = {};
/* @@LOOKUP_MAP_ASSIGNMENT@@ */
function createGlobLookup(glob) { function createGlobLookup(glob) {
return async (collection, lookupId) => { return async (collection, lookupId) => {
const { default: lookupMap } = await import('@@LOOKUP_MAP_PATH@@');
const filePath = lookupMap[collection]?.[lookupId]; const filePath = lookupMap[collection]?.[lookupId];
if (!filePath) return undefined; 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 { AstroError, AstroErrorData } from '../core/errors/index.js';
import { info, warn, type LogOptions } from '../core/logger/core.js'; import { info, warn, type LogOptions } from '../core/logger/core.js';
import { isRelativePath } from '../core/path.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 { import {
getContentPaths, getContentPaths,
getEntryInfo, getEntryInfo,
@ -21,7 +21,6 @@ import {
type ContentObservable, type ContentObservable,
type ContentPaths, type ContentPaths,
type EntryInfo, type EntryInfo,
updateLookupMaps,
getContentEntryConfigByExtMap, getContentEntryConfigByExtMap,
} from './utils.js'; } from './utils.js';
@ -280,12 +279,7 @@ export async function createContentTypesGenerator({
contentConfig: observable.status === 'loaded' ? observable.config : undefined, contentConfig: observable.status === 'loaded' ? observable.config : undefined,
contentEntryTypes: settings.contentEntryTypes, contentEntryTypes: settings.contentEntryTypes,
}); });
await updateLookupMaps({ invalidateVirtualMod(viteServer);
contentEntryConfigByExt,
contentPaths,
root: settings.config.root,
fs,
});
if (observable.status === 'loaded' && ['info', 'warn'].includes(logLevel)) { if (observable.status === 'loaded' && ['info', 'warn'].includes(logLevel)) {
warnNonexistentCollections({ warnNonexistentCollections({
logging, logging,
@ -298,6 +292,15 @@ export async function createContentTypesGenerator({
return { init, queueEvent }; 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) { function addCollection(contentMap: ContentTypes, collectionKey: string) {
contentMap[collectionKey] = {}; contentMap[collectionKey] = {};
} }

View file

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

View file

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