perf(cli): commands start sooner by compiling registry schemas on first use (#5935)

* perf(cli): commands start sooner by compiling registry schemas on first use

* fix(cli): registry validation keeps its file comment-free
This commit is contained in:
Miguel Ángel
2026-10-20 07:38:59 +00:00
committed by GitHub
parent 0693839b52
commit d898ad89ee
2 changed files with 34 additions and 5 deletions
@@ -0,0 +1,24 @@
import { expect, it, vi } from "vitest";
const compiles = vi.hoisted(() => ({ count: 0 }));
vi.mock("ajv/dist/2020.js", async (importOriginal) => {
const real = await importOriginal<typeof import("ajv/dist/2020.js")>();
const compile = real.Ajv2020.prototype.compile;
real.Ajv2020.prototype.compile = function (this: unknown, ...args: unknown[]) {
compiles.count += 1;
return Reflect.apply(compile, this, args);
} as typeof compile;
return { ...real };
});
it("compiles the registry schemas on first use, not when the module is imported", async () => {
const { validRegistryItem } = await import("./validation.js");
expect(compiles.count).toBe(0);
validRegistryItem({}, "demo", "hyperframes:component");
expect(compiles.count).toBe(2);
validRegistryItem({}, "demo", "hyperframes:component");
expect(compiles.count).toBe(2);
});
+10 -5
View File
@@ -3,9 +3,14 @@ import registrySchema from "@hyperframes/core/schemas/registry.json";
import itemSchema from "@hyperframes/core/schemas/registry-item.json";
import type { RegistryManifest, RegistryItem, ItemType } from "@hyperframes/core";
const ajv = new Ajv2020({ strict: false, validateFormats: false });
const manifestShape = ajv.compile<RegistryManifest>(registrySchema);
const itemShape = ajv.compile<RegistryItem>(itemSchema);
function compileShapes() {
const ajv = new Ajv2020({ strict: false, validateFormats: false });
return {
manifest: ajv.compile<RegistryManifest>(registrySchema),
item: ajv.compile<RegistryItem>(itemSchema),
};
}
let shapesCompiledOnFirstUse: ReturnType<typeof compileShapes> | undefined;
export function validRegistryName(name: string): boolean {
return name.length <= 128 && /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/.test(name);
@@ -13,7 +18,7 @@ export function validRegistryName(name: string): boolean {
export function validRegistryManifest(value: unknown): value is RegistryManifest {
return (
manifestShape(value) &&
(shapesCompiledOnFirstUse ??= compileShapes()).manifest(value) &&
value.items.length <= 10_000 &&
value.items.every((item) => validRegistryName(item.name))
);
@@ -25,7 +30,7 @@ export function validRegistryItem(
type: ItemType,
): value is RegistryItem {
return (
itemShape(value) &&
(shapesCompiledOnFirstUse ??= compileShapes()).item(value) &&
value.name === name &&
value.type === type &&
validRegistryName(value.name) &&