fix: too many files opened for collections with many entries (#6313)

* fix: too many files opened for collections with many entries

* Update packages/astro/src/content/types-generator.ts

* Update packages/astro/src/content/types-generator.ts

* Update packages/astro/src/content/types-generator.ts

* Update packages/astro/src/content/types-generator.ts

* Update packages/astro/src/content/types-generator.ts

* Update packages/astro/src/content/types-generator.ts

---------

Co-authored-by: Nate Moore <natemoo-re@users.noreply.github.com>
This commit is contained in:
John Beene 2023-02-23 14:05:17 -06:00 committed by GitHub
parent 504c7bacb8
commit de3d79e06b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -41,6 +41,11 @@ type CreateContentGeneratorParams = {
type EventOpts = { logLevel: 'info' | 'warn' }; type EventOpts = { logLevel: 'info' | 'warn' };
type EventWithOptions = {
type: ContentEvent;
opts: EventOpts | undefined;
};
class UnsupportedFileTypeError extends Error {} class UnsupportedFileTypeError extends Error {}
export async function createContentTypesGenerator({ export async function createContentTypesGenerator({
@ -53,7 +58,7 @@ export async function createContentTypesGenerator({
const contentTypes: ContentTypes = {}; const contentTypes: ContentTypes = {};
const contentPaths = getContentPaths(settings.config, fs); const contentPaths = getContentPaths(settings.config, fs);
let events: Promise<{ shouldGenerateTypes: boolean; error?: Error }>[] = []; let events: EventWithOptions[] = [];
let debounceTimeout: NodeJS.Timeout | undefined; let debounceTimeout: NodeJS.Timeout | undefined;
const contentTypesBase = await fs.promises.readFile(contentPaths.typesTemplate, 'utf-8'); const contentTypesBase = await fs.promises.readFile(contentPaths.typesTemplate, 'utf-8');
@ -65,7 +70,11 @@ export async function createContentTypesGenerator({
return { typesGenerated: false, reason: 'no-content-dir' }; return { typesGenerated: false, reason: 'no-content-dir' };
} }
events.push(handleEvent({ name: 'add', entry: contentPaths.config.url }, { logLevel: 'warn' })); events.push({
type: { name: 'add', entry: contentPaths.config.url },
opts: { logLevel: 'warn' },
});
const globResult = await glob('**', { const globResult = await glob('**', {
cwd: fileURLToPath(contentPaths.contentDir), cwd: fileURLToPath(contentPaths.contentDir),
fs: { fs: {
@ -80,7 +89,7 @@ export async function createContentTypesGenerator({
(e) => !e.href.startsWith(contentPaths.config.url.href) (e) => !e.href.startsWith(contentPaths.config.url.href)
); );
for (const entry of entries) { for (const entry of entries) {
events.push(handleEvent({ name: 'add', entry }, { logLevel: 'warn' })); events.push({ type: { name: 'add', entry }, opts: { logLevel: 'warn' } });
} }
await runEvents(); await runEvents();
return { typesGenerated: true }; return { typesGenerated: true };
@ -204,12 +213,15 @@ export async function createContentTypesGenerator({
function queueEvent(rawEvent: RawContentEvent, opts?: EventOpts) { function queueEvent(rawEvent: RawContentEvent, opts?: EventOpts) {
const event = { const event = {
type: {
entry: pathToFileURL(rawEvent.entry), entry: pathToFileURL(rawEvent.entry),
name: rawEvent.name, name: rawEvent.name,
},
opts,
}; };
if (!event.entry.pathname.startsWith(contentPaths.contentDir.pathname)) return; if (!event.type.entry.pathname.startsWith(contentPaths.contentDir.pathname)) return;
events.push(handleEvent(event, opts)); events.push(event);
debounceTimeout && clearTimeout(debounceTimeout); debounceTimeout && clearTimeout(debounceTimeout);
debounceTimeout = setTimeout( debounceTimeout = setTimeout(
@ -220,7 +232,13 @@ export async function createContentTypesGenerator({
async function runEvents(opts?: EventOpts) { async function runEvents(opts?: EventOpts) {
const logLevel = opts?.logLevel ?? 'info'; const logLevel = opts?.logLevel ?? 'info';
const eventResponses = await Promise.all(events); const eventResponses = [];
for (const event of events) {
const response = await handleEvent(event.type, event.opts);
eventResponses.push(response);
}
events = []; events = [];
let unsupportedFiles = []; let unsupportedFiles = [];
for (const response of eventResponses) { for (const response of eventResponses) {