Implement durable typed journals, subscriptions, and Reader document connections
Add checked native journal/subscription bindings, managed-reference retention, bounded history and backpressure, atomic delivery receipts, and fenced hosting. Preserve source publication prediction and replica reconciliation; subscription attachment, controls, and delivery remain authoritative in this initial version. Connect independent manual/Gutenberg document producers to Reader bookshelves through typed adapters. Add connection inspection, shared provider selection, authoring documentation, and restart/rejection/fan-out integration coverage. Verified compiler suite (287 passed, two existing skips), Nix runtime and PostgreSQL qualification, five example assemblies, headless Reader integration, Chromium Reader integration, resource pins, formatting, and lint. No pinned workspace runtime was deployed.
This commit is contained in:
@@ -45,6 +45,8 @@ export interface PlannedOperation {
|
||||
operationId: string;
|
||||
scope: "object" | "class";
|
||||
execution: ExecutionContract;
|
||||
/** Installed implementation closure; the public execution contract above remains required. */
|
||||
availableTargets: string[];
|
||||
input: ValueType;
|
||||
output: ValueType;
|
||||
/** Concrete target after public forwarding. Never chosen by a runtime caller. */
|
||||
@@ -240,6 +242,7 @@ export function compileExecutionPlan(input: WorkspaceRevision): ExecutionPlan {
|
||||
operationId: operation,
|
||||
scope: publicContract.scope === "class" ? "class" : "object",
|
||||
execution: publicContract.execution ?? { kind: "remote" },
|
||||
availableTargets: [],
|
||||
input: publicContract.inputType,
|
||||
output: publicContract.outputType,
|
||||
binding,
|
||||
@@ -251,7 +254,8 @@ export function compileExecutionPlan(input: WorkspaceRevision): ExecutionPlan {
|
||||
checkValue(planned.input, `${key}/input`, true);
|
||||
checkValue(planned.output, `${key}/output`, true);
|
||||
}
|
||||
if (binding.kind === "state") planned.dependencies.push({ kind: "state", slot: binding.slotId });
|
||||
if (binding.kind === "state" || binding.kind === "journal" || binding.kind === "subscription")
|
||||
planned.dependencies.push({ kind: "state", slot: binding.slotId });
|
||||
else if (binding.kind === "edge")
|
||||
planned.dependencies.push({ kind: "edge", edge: binding.edgeTypeId, projection: binding.projectionId });
|
||||
else if (binding.kind === "package") {
|
||||
@@ -338,6 +342,46 @@ export function compileExecutionPlan(input: WorkspaceRevision): ExecutionPlan {
|
||||
};
|
||||
walk(root.key, [root.key]);
|
||||
}
|
||||
// Additional implementation targets are opportunities, not new public requirements.
|
||||
// Start with provider support and remove targets until the complete installed
|
||||
// dependency closure agrees. This also handles recursive call graphs without
|
||||
// mistaking an unfinished DFS for proof of availability.
|
||||
for (const node of operationMap.values()) {
|
||||
if (node.execution.kind === "remote") continue;
|
||||
const binding = node.binding;
|
||||
const provider =
|
||||
binding.kind === "package"
|
||||
? packages.get(binding.packageRevisionId)!.exports.find((entry) => entry.id === binding.exportId)!.execution
|
||||
: binding.kind === "lifecycle" || (binding.kind === "subscription" && binding.primitive !== "status")
|
||||
? { kind: "transaction" as const, targets: ["server" as const] }
|
||||
: { kind: node.execution.kind, targets: ["browser" as const, "server" as const] };
|
||||
if (provider && provider.kind !== "remote") node.availableTargets = [...provider.targets].sort();
|
||||
}
|
||||
let targetsChanged = true;
|
||||
while (targetsChanged) {
|
||||
targetsChanged = false;
|
||||
for (const node of operationMap.values()) {
|
||||
const available = node.availableTargets.filter((target) =>
|
||||
node.dependencies.every((dependency) => {
|
||||
if (dependency.kind === "operation")
|
||||
return operationMap.get(dependency.operation)!.availableTargets.includes(target);
|
||||
if (dependency.kind === "query") {
|
||||
const query = queryMap.get(dependency.query)!;
|
||||
return (
|
||||
node.execution.kind === "snapshot" &&
|
||||
query.checked.declaration.placement?.kind === "local" &&
|
||||
queryOperations(query).every((key) => operationMap.get(key)!.availableTargets.includes(target))
|
||||
);
|
||||
}
|
||||
return true;
|
||||
}),
|
||||
);
|
||||
if (available.length !== node.availableTargets.length) {
|
||||
node.availableTargets = available;
|
||||
targetsChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
const plannedQueries: PlannedQuery[] = queries.map((query) => ({
|
||||
id: queryKey(query.packageRevisionId, query.checked.declaration.id),
|
||||
query,
|
||||
|
||||
Reference in New Issue
Block a user