refactor: generated .json
to in-memory map
This commit is contained in:
parent
87e9e072cf
commit
cc50ee68d4
4 changed files with 39 additions and 24 deletions
|
@ -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;
|
||||||
|
|
|
@ -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] = {};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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[]) {
|
||||||
|
|
|
@ -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};`
|
||||||
|
),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue