diff --git a/.changeset/strong-catalogs-load.md b/.changeset/strong-catalogs-load.md new file mode 100644 index 0000000000..2cd5cf2de2 --- /dev/null +++ b/.changeset/strong-catalogs-load.md @@ -0,0 +1,5 @@ +--- +"@cloudflare/kumo": patch +--- + +Load catalog schemas when `initCatalog` is awaited so synchronous validation is ready to use. diff --git a/packages/kumo/AGENTS.md b/packages/kumo/AGENTS.md index 891062a551..023c792898 100644 --- a/packages/kumo/AGENTS.md +++ b/packages/kumo/AGENTS.md @@ -120,7 +120,6 @@ Output: ai/component-registry.{json,md} + ai/schemas.ts - **Compound components**: CommandPalette (14 sub-components), Dialog, Select use two-level contexts - **13 components use createContext**: SwitchGroup, PaginationContext, RadioGroup, FlowNodeAnchor, Diagram, Descendants, InputGroup, DialogRole, ComboboxSize, Grid, CheckboxGroup, CommandPalette (2) - **DateRangePicker**: Contains 150 lines of duplicated ternary logic (refactoring target) -- **Catalog `initCatalog`**: Appears to have race condition with async schema loading - **CLI path inconsistency**: `ls`/`doc` read from `catalog/`, `blocks` from `ai/` directory - **`PLOP_INJECT_EXPORT`** in `src/index.ts` and `PLOP_INJECT_COMPONENT_ENTRY` in `vite.config.ts` are scaffolding markers - **5th lint rule** (`no-deprecated-props`): Only in `packages/kumo/lint/`, reads deprecation data from registry diff --git a/packages/kumo/src/catalog/catalog.test.ts b/packages/kumo/src/catalog/catalog.test.ts index d1ada7df7b..2d4ebbceaa 100644 --- a/packages/kumo/src/catalog/catalog.test.ts +++ b/packages/kumo/src/catalog/catalog.test.ts @@ -3,6 +3,7 @@ */ import { describe, it, expect } from "vitest"; +import { createKumoCatalog, initCatalog } from "./catalog"; import { getByPath, setByPath, @@ -12,6 +13,30 @@ import { } from "./data"; import { evaluateVisibility, createVisibilityContext } from "./visibility"; +describe("catalog initialization", () => { + it("loads schemas before synchronous validation", async () => { + const catalog = createKumoCatalog(); + + await initCatalog(catalog); + + expect(catalog.componentNames).toContain("Button"); + expect(catalog.hasComponent("Button")).toBe(true); + expect(catalog.validateTree({})).toEqual({ + success: false, + error: [ + { + message: "Invalid input: expected string, received undefined", + path: ["root"], + }, + { + message: "Invalid input: expected record, received undefined", + path: ["elements"], + }, + ], + }); + }); +}); + describe("data utilities", () => { describe("getByPath", () => { it("returns root for empty path", () => { diff --git a/packages/kumo/src/catalog/catalog.ts b/packages/kumo/src/catalog/catalog.ts index e024aba833..94e7b11699 100644 --- a/packages/kumo/src/catalog/catalog.ts +++ b/packages/kumo/src/catalog/catalog.ts @@ -276,7 +276,6 @@ export function createKumoCatalog(config: CatalogConfig = {}): KumoCatalog { * Initialize the catalog by loading schemas. * Call this before using synchronous validation methods. */ -export async function initCatalog(catalog: KumoCatalog): Promise { - // Trigger a validation to load schemas - catalog.validateTree({}); +export async function initCatalog(_catalog: KumoCatalog): Promise { + await loadSchemas(); }