Correct Reader producer completion and prepare only the active source
Route durable completion to the initiating PresentationMount, guarded against stale navigation and unrelated fan-out. Publish Gutenberg passages directly, preserve unfinished manual drafts, and open completed documents in the main reader pane. Prepare the selected provider and explicitly opened inspector only. Consolidate Studio factory contracts so optional execution placement is determined by implementations. Support typed stateful presentation props and local-module role selection in the React build layer. Update integration, browser, portal, and authoring documentation.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { execFileSync } from "node:child_process";
|
||||
import { installDependencies } from "./install-dependencies.mjs";
|
||||
const config = JSON.parse(await fs.readFile(process.argv[2], "utf8"));
|
||||
const resource = JSON.parse(await fs.readFile(config.interface, "utf8"));
|
||||
if (resource.kind !== "interface") throw Error("React props belong to an interface resource");
|
||||
@@ -29,14 +30,24 @@ const metadata = await fs.readFile(packageFile, "utf8").then(JSON.parse, (error)
|
||||
throw error;
|
||||
});
|
||||
await fs.writeFile(packageFile, JSON.stringify({ ...metadata, type: "module" }));
|
||||
if (config.dependencies) await fs.symlink(config.dependencies, path.join(work, "node_modules"));
|
||||
const modules = path.join(output, "node_modules");
|
||||
await fs.mkdir(modules, { recursive: true });
|
||||
await installDependencies({
|
||||
destination: modules,
|
||||
application: config.dependencies,
|
||||
selected: config.reactSdk ? { "@quixos/camino-react": config.reactSdk } : {},
|
||||
reserved: ["@quixos/camino-react"],
|
||||
});
|
||||
await fs.symlink(modules, path.join(work, "node_modules"));
|
||||
const members = Object.create(null);
|
||||
let index = 0;
|
||||
for (const [id, entry] of Object.entries(config.members)) {
|
||||
const member = (iface.template?.members ?? iface.members).find((member) => member.id === id);
|
||||
if (
|
||||
member?.kind !== "module" ||
|
||||
!["org.quixos.react.component/1", "org.quixos.react.subject-only/1"].includes(member.contract)
|
||||
!["org.quixos.react.component/1", "org.quixos.react.component/2", "org.quixos.react.subject-only/1"].includes(
|
||||
member.contract,
|
||||
)
|
||||
)
|
||||
throw Error("Props entry is not a React module member: " + id);
|
||||
if (
|
||||
@@ -52,7 +63,7 @@ for (const [id, entry] of Object.entries(config.members)) {
|
||||
`import type {${entry.export} as Props} from ${typeImport};
|
||||
type Assert<T extends true> = T;
|
||||
type ObjectProps = Assert<Props extends object ? true : false>;
|
||||
type ReservedRendererProps = Assert<Extract<keyof Props, "subject" | "usingComponent" | "provider" | "coverage" | "componentCodeFallback"> extends never ? true : false>;
|
||||
type ReservedRendererProps = Assert<Extract<keyof Props, "subject" | "input" | "navigation" | "usingComponent" | "provider" | "coverage" | "componentCodeFallback"> extends never ? true : false>;
|
||||
${member.contract === "org.quixos.react.subject-only/1" ? "type SubjectOnly = Assert<{} extends Props ? true : false>;" : ""}
|
||||
export type {Props};\n`,
|
||||
);
|
||||
@@ -69,6 +80,8 @@ execFileSync(
|
||||
"--strict",
|
||||
"--target",
|
||||
"es2024",
|
||||
"--lib",
|
||||
"es2024,dom,dom.iterable,esnext.disposable",
|
||||
"--module",
|
||||
"nodenext",
|
||||
"--moduleResolution",
|
||||
@@ -88,7 +101,6 @@ for (const file of declarations) {
|
||||
await fs.copyFile(path.join(work, file), path.join(output, "types", file));
|
||||
}
|
||||
await fs.writeFile(path.join(output, "package.json"), JSON.stringify({ type: "module" }));
|
||||
if (config.dependencies) await fs.symlink(config.dependencies, path.join(output, "node_modules"));
|
||||
await fs.writeFile(
|
||||
path.join(output, "react-contracts.json"),
|
||||
JSON.stringify({ schemaVersion: 1, interfaceRevisionId: iface.revisionId, members }, null, 2),
|
||||
|
||||
@@ -11,6 +11,7 @@ let
|
||||
source = src;
|
||||
interface = context.interface;
|
||||
inherit members dependencies;
|
||||
reactSdk = context.reactSdk or null;
|
||||
node = "${pkgs.nodejs_24}/bin/node";
|
||||
tsc = "${context.typescript}/node_modules/typescript/bin/tsc";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user