feat: release design system engine, studio and component contracts

This commit is contained in:
Clintchiz committed 2026-10-19 13:09:03 +05:30
1 parent ff1065fb27
commit 3943b946d6
693 files changed
+175546 -3894

No files matched your search

+53 -15
View File
@@ -11,22 +11,43 @@ const code = new Bun.Transpiler({ loader: "ts" })
test("partial registration failure cleans the backend and live region on mount and refresh", () => {
for (const failingMount of [1, 2]) {
const window = new Window(), root = window.document.createElement("div");
const window = new Window(),
root = window.document.createElement("div");
window.document.body.append(root);
root.innerHTML = '<div data-block-id="a" data-block-parent="root" data-block-slot="content"></div><div data-block-id="b" data-block-parent="root" data-block-slot="content"></div>';
let mounts = 0, destroyed = 0, cleaned = 0;
root.innerHTML =
'<div data-block-id="a" data-block-parent="root" data-block-slot="content"></div><div data-block-id="b" data-block-parent="root" data-block-slot="content"></div>';
let mounts = 0,
destroyed = 0,
cleaned = 0;
const mount = new Function("createDndManager", code + ";return mountBlockEditor;")(() => {
const number = ++mounts; let registrations = 0;
return { registerSortable() { if (++registrations === 2 && number === failingMount) throw new Error("registration failed"); return () => { cleaned++; }; }, destroy() { destroyed++; } };
const number = ++mounts;
let registrations = 0;
return {
registerSortable() {
if (++registrations === 2 && number === failingMount)
throw new Error("registration failed");
return () => {
cleaned++;
};
},
destroy() {
destroyed++;
},
};
});
let editor: MountedEditor | undefined;
if (failingMount === 1) expect(() => mount(root, { onMove() {} })).toThrow("registration failed");
else { editor = mount(root, { onMove() {} }); expect(() => editor!.refresh()).toThrow("registration failed"); }
if (failingMount === 1)
expect(() => mount(root, { onMove() {} })).toThrow("registration failed");
else {
editor = mount(root, { onMove() {} });
expect(() => editor!.refresh()).toThrow("registration failed");
}
expect(root.querySelector('[role="status"]')).toBeNull();
expect(root.querySelectorAll('[data-block-id]')).toHaveLength(2);
expect(root.querySelectorAll("[data-block-id]")).toHaveLength(2);
expect(destroyed).toBe(failingMount);
expect(cleaned).toBe(failingMount === 1 ? 1 : 3);
editor?.destroy(); editor?.refresh();
editor?.destroy();
editor?.refresh();
expect(destroyed).toBe(failingMount);
}
});
@@ -46,7 +67,12 @@ function fixture(onMove: MountEditorOptions["onMove"] = () => false) {
}> = [];
const mount = new Function("createDndManager", code + ";return mountBlockEditor;")(
(options: DndManagerOptions) => {
const backend = { options, registrations: [] as SortableRegistration[], zones: [] as DropZoneRegistration[], destroyed: 0 };
const backend = {
options,
registrations: [] as SortableRegistration[],
zones: [] as DropZoneRegistration[],
destroyed: 0,
};
backends.push(backend);
return {
registerDropZone: (registration: DropZoneRegistration) => {
@@ -100,9 +126,15 @@ test("large canvas registration scans blocks once and preserves interleaved slot
const backend = f.backends.at(-1)!;
expect(scans).toBe(1);
expect(backend.registrations.map(({ id, group, index }) => ({ id, group, index }))).toEqual(
Array.from({ length: 300 }, (_, i) => ({ id: String(i), group: JSON.stringify([`parent:${i % 3}`, "content"]), index: Math.floor(i / 3) })),
Array.from({ length: 300 }, (_, i) => ({
id: String(i),
group: JSON.stringify([`parent:${i % 3}`, "content"]),
index: Math.floor(i / 3),
})),
);
expect(backend.zones.map(zone => zone.group)).toEqual([JSON.stringify(["parent:3", "content"])]);
expect(backend.zones.map((zone) => zone.group)).toEqual([
JSON.stringify(["parent:3", "content"]),
]);
f.editor.destroy();
});
@@ -127,7 +159,10 @@ test("cancelled optimistic moves restore original DOM nodes across containers",
test("empty named slot targets produce validated editor move intents and refresh away when populated", async () => {
const moves: unknown[] = [];
const f = fixture(intent => { moves.push(intent); return true; });
const f = fixture((intent) => {
moves.push(intent);
return true;
});
const target = f.document.createElement("div");
target.dataset.blockParent = "parent:empty";
target.dataset.blockSlotTarget = "content:empty";
@@ -138,9 +173,12 @@ test("empty named slot targets produce validated editor move intents and refresh
const zone = backend.zones[0]!;
expect(backend.options.accept!(["a"], { group: zone.group, index: 0 })).toBe(true);
await backend.options.onMoveIntent({ ids: ["a"], from: [], to: { group: zone.group, index: 0 } });
expect(moves).toEqual([{ nodeIds: ["a"], to: { parentId: "parent:empty", slot: "content:empty", index: 0 } }]);
expect(moves).toEqual([
{ nodeIds: ["a"], to: { parentId: "parent:empty", slot: "content:empty", index: 0 } },
]);
const child = f.root.querySelector('[data-block-id="a"]')! as any;
child.dataset.blockParent = "parent:empty"; child.dataset.blockSlot = "content:empty";
child.dataset.blockParent = "parent:empty";
child.dataset.blockSlot = "content:empty";
target.append(child);
f.editor.refresh();
expect(f.backends.at(-1)!.zones).toHaveLength(0);