chore: initialize from frontend template 4dc033c

This commit is contained in:
DongHyeonka
2026-08-13 18:23:26 +09:00
commit 40107eec84
897 changed files with 234824 additions and 0 deletions
+119
View File
@@ -0,0 +1,119 @@
import type {
CommandEffectDescriptor,
CommandEffectClassification,
} from "../../contracts/external-contract-runtime.ts";
/**
* §8.7–§8.9. Mutation effect certainty.
*
* The frontend never infers "not applied" from an HTTP status alone. Anything
* observed after the request was dispatched but before a classified terminal
* response is `MAYBE_APPLIED`, which forbids automatic resend.
*/
export type MutationEffectCertainty =
| "NOT_STARTED"
| "NOT_APPLIED"
| "MAYBE_APPLIED"
| "APPLIED_CONFIRMED";
export type PhysicalAttemptState =
| "NOT_STARTED"
| "PREPARING"
| "READY_TO_SEND"
| "DISPATCHED"
| "RESPONSE_HEADERS"
| "READING_BODY"
| "VALIDATING"
| "MAPPING_READY"
| "SETTLED";
/**
* `READY_TO_SEND` is recorded immediately before entering the `fetch()`
* invocation expression and `DISPATCHED` immediately after the promise is
* returned. A synchronous throw therefore leaves the attempt `NOT_STARTED`.
*/
export function certaintyForAbandonedAttempt(
state: PhysicalAttemptState,
isCommand: boolean,
): MutationEffectCertainty {
if (!isCommand) return "NOT_STARTED";
switch (state) {
case "NOT_STARTED":
case "PREPARING":
case "READY_TO_SEND":
return "NOT_STARTED";
default:
return "MAYBE_APPLIED";
}
}
export type ProblemEffectInput<Problem> = Readonly<{
status: number;
problem: Problem;
descriptor: CommandEffectDescriptor<Problem> | null;
}>;
export type ProblemEffectOutcome = Readonly<{
effect: MutationEffectCertainty;
contractRuntimeFailure: boolean;
}>;
const CLASSIFICATIONS: ReadonlySet<CommandEffectClassification> = new Set([
"NOT_APPLIED",
"APPLIED_CONFIRMED",
"MAYBE_APPLIED",
]);
/**
* §4.4. The classifier is package-owned and pure. A throw or an unrecognised
* return value fails safe to `MAYBE_APPLIED` and is recorded as a contract
* runtime failure rather than being silently treated as "not applied".
*/
export function classifyProblemEffect<Problem>(
input: ProblemEffectInput<Problem>,
): ProblemEffectOutcome {
if (!input.descriptor) {
// A read operation carries no command effect; there is nothing to apply.
return Object.freeze({
effect: "NOT_STARTED" as const,
contractRuntimeFailure: false,
});
}
let classification: CommandEffectClassification;
try {
classification = input.descriptor.classifyProblem({
status: input.status,
problem: input.problem,
});
} catch {
return Object.freeze({
effect: "MAYBE_APPLIED" as const,
contractRuntimeFailure: true,
});
}
if (!CLASSIFICATIONS.has(classification)) {
return Object.freeze({
effect: "MAYBE_APPLIED" as const,
contractRuntimeFailure: true,
});
}
return Object.freeze({
effect: classification,
contractRuntimeFailure: false,
});
}
/** §8.10. Certainty to UI intent. The copy itself is owned by the i18n catalog. */
export function projectCertaintyToUi(
certainty: MutationEffectCertainty,
): "RETRYABLE" | "CHECK_STATUS" | "SUCCESS" {
switch (certainty) {
case "APPLIED_CONFIRMED":
return "SUCCESS";
case "MAYBE_APPLIED":
return "CHECK_STATUS";
default:
return "RETRYABLE";
}
}