Add graph-aware React controls with stable asynchronous selection
Add typed command/live bindings, Choice and Toggle, CRDT text wrappers, and explicit browser-local controls. Migrate Reader and current example inputs. Enforce editable-control authoring checks in the React artifact backend. Command controls display query observations, permit one local execution at a time, and delay pending feedback for 200 ms. Include keyboard, focus, shadow-root, top-layer popup, rejection/no-op, native-field eligibility, and IME coverage. Verified SDK builds and tests, synchronous-editing browser qualification, Reader/Tasks qualification, presentation-mount qualification, and the review-dashboard browser test. Monorepo formatting and lint pass. The full composition qualification stops at the unchanged combined-to-review workspace fixture transition: STORAGE_MODEL_CHANGED from changed/removed stored conformance owners. Its dashboard browser test passes when run directly.
This commit is contained in:
@@ -3,6 +3,7 @@ import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { createHash } from "node:crypto";
|
||||
import { execFileSync } from "node:child_process";
|
||||
import { pathToFileURL } from "node:url";
|
||||
const digest = (bytes) => createHash("sha256").update(bytes).digest("hex");
|
||||
export async function buildComponents({ config, compiler, plan, pkg, output, recordFile, generated }) {
|
||||
const settings = config.components;
|
||||
@@ -158,6 +159,9 @@ export async function buildComponents({ config, compiler, plan, pkg, output, rec
|
||||
`\nexport {};\ndeclare module ${JSON.stringify("./" + bindingPath.replace(/\.ts$/, ".js"))} { interface ModuleProps {${propsMembers.join("\n")}} }\n`,
|
||||
);
|
||||
const components = [];
|
||||
const { checkControls } = await import(pathToFileURL(path.join(settings.sdk, "lint-controls.mjs")));
|
||||
const { default: ts } = await import(pathToFileURL(path.resolve(path.dirname(config.tsc), "../lib/typescript.js")));
|
||||
const checkedControls = new Set();
|
||||
for (const [id, entry] of entries) {
|
||||
const declaration = declarations.find((component) => component.id === id),
|
||||
source = compiler.artifactPath(entry.entry);
|
||||
@@ -225,6 +229,12 @@ export async function buildComponents({ config, compiler, plan, pkg, output, rec
|
||||
);
|
||||
const meta = JSON.parse(await fs.readFile(metadata, "utf8")),
|
||||
outputs = Object.entries(meta.outputs);
|
||||
for (const file of Object.keys(meta.inputs)) {
|
||||
if (!/\.[cm]?[jt]sx?$/.test(file) || file.includes("node_modules/") || checkedControls.has(file)) continue;
|
||||
checkedControls.add(file);
|
||||
const errors = checkControls(ts, await fs.readFile(path.resolve(work, file), "utf8"), file);
|
||||
if (errors.length) throw Error(errors.join("\n"));
|
||||
}
|
||||
const main = outputs.find(([file]) => file.endsWith("/module.mjs"))?.[1];
|
||||
if (!main?.exports.includes(entry.export)) throw Error("Component bundle lacks declared export");
|
||||
if (
|
||||
|
||||
Reference in New Issue
Block a user