Files
tech-log-frontend/src/application/ports/browser-transfer/image-cdn.ts
T
DongHyeonkaandClaude Opus 5 4bff9ca151 chore: sync the frontend template from 4dc033c to 8157ad4
The product was materialized from the template at `4dc033c` and has stayed
on it through 43 template commits, so it was missing all three rounds of
adapter remediation — including files it never had, such as the shared
`abortable-operation` primitive and the `exact-snapshot` decoder that
later fixes are written against. Taking only the newest round was not
possible for that reason: the delta is coherent only as a whole.

The product had not touched `src/adapters` at all since materialization,
so the 140-file delta applied with a three-way merge and no conflicts.
`package.json` was the single overlap and merged cleanly: the product owns
`name`, the template contributed `check:adapter-inventory`,
`check:remediation-ledger` and the image-resolve-signal type fixture.
All 24 product-owned files — README, index.html, CI workflow, i18n
catalog, home page, generated schemas, evidence scripts, component and
visual snapshots — are byte-identical to `main`.

`template.lock.json` now pins the synced revision and tree.

Verified in this repository, not inherited from the template: six type
projects, lint, nine gates (adapter inventory, remediation ledger,
registries, diagnostics, realtime boundaries, architecture, browser
file/storage boundaries, optional recipes, documentation), the production
build, and 2,054 of 2,073 tests. The 19 failures are all in
`tests/unit/ci-artifact-contract.test.ts` and are the same pre-existing
sandbox RLIMIT, EMFILE, umask and `/tmp` permission behaviour the template
records; four suites that failed once under parallel load pass in
isolation.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-15 12:04:58 +09:00

192 lines
5.5 KiB
TypeScript

import type { BrowserDataResult } from "../browser-file-storage/shared.ts";
declare const imageAssetReferenceBrand: unique symbol;
declare const imagePresetReferenceBrand: unique symbol;
export type ImageRasterMediaType =
| "image/avif"
| "image/jpeg"
| "image/png"
| "image/webp";
export type ImageOutputFormat = "avif" | "jpeg" | "png" | "webp";
export type ImageFit = "contain" | "cover" | "fill" | "inside" | "outside";
/**
* Identity capability backed by an adapter-owned WeakMap. A structurally equal
* object or a reference issued by another runtime must be rejected.
*/
export type ImageAssetReference = Readonly<{
readonly [imageAssetReferenceBrand]: "ImageAssetReference";
}>;
/**
* Composition-issued named preset reference. Presentation cannot submit
* width, height, DPR, quality, format, URL or query overrides.
*/
export type ImagePresetReference = Readonly<{
presetKey: string;
intention: string;
readonly [imagePresetReferenceBrand]: "ImagePresetReference";
}>;
export type PublicImmutableImageAsset = Readonly<{
kind: "ALLOWLISTED_PUBLIC";
originKey: string;
assetId: string;
revision: string;
mediaType: ImageRasterMediaType;
contentKind: "RASTER_STATIC";
intrinsicWidth: number;
intrinsicHeight: number;
}>;
/**
* Server-issued descriptor for private signed delivery. It contains no URL or
* request headers. The signature covers every immutable field and the exact
* set of registry-owned preset binding IDs.
*/
export type BackendIssuedImageAsset = Readonly<{
kind: "BACKEND_ISSUED_PRIVATE";
issuer: string;
originKey: string;
assetId: string;
revision: string;
mediaType: ImageRasterMediaType;
contentKind: "RASTER_STATIC";
intrinsicWidth: number;
intrinsicHeight: number;
capabilityId: string;
issuedAtEpochMs: number;
expiresAtEpochMs: number;
allowedPresetBindingIds: readonly string[];
signature: Readonly<{
algorithm: "ECDSA_P256_SHA256";
keyId: string;
capabilityBindingDigestHex: string;
valueBase64Url: string;
}>;
}>;
export type ImageCapabilityVerificationRequest = Readonly<{
algorithm: "ECDSA_P256_SHA256";
keyId: string;
canonicalPayload: Uint8Array;
signatureBase64Url: string;
}>;
export interface ImageCapabilityVerifier {
/** Exact membership check against the verifier's immutable key registry. */
acceptsKey(keyId: string): boolean;
verify(
request: ImageCapabilityVerificationRequest,
): Promise<boolean>;
}
export interface ImageAssetAcceptancePort {
acceptPublicImmutable(
descriptor: PublicImmutableImageAsset,
): BrowserDataResult<ImageAssetReference>;
acceptBackendIssued(
descriptor: BackendIssuedImageAsset,
options?: Readonly<{ signal?: AbortSignal }>,
): Promise<BrowserDataResult<ImageAssetReference>>;
}
export type ImageDeliveryClass =
| "PUBLIC_IMMUTABLE"
| "PRIVATE_SIGNED";
export type ImageProbeRequest = Readonly<{
absoluteUrl: string;
expectedMediaType: ImageRasterMediaType;
expectedWidth: number;
expectedHeight: number;
maxEncodedBytes: number;
maxDecodedPixels: number;
maxDecodedBytes: number;
delivery: ImageDeliveryClass;
minimumPublicMaxAgeSeconds: number;
referrerPolicy: "no-referrer" | "strict-origin-when-cross-origin";
signal: AbortSignal;
}>;
export type ImageProbeReceipt = Readonly<{
absoluteUrl: string;
mediaType: ImageRasterMediaType;
encodedBytes: number;
decodedWidth: number;
decodedHeight: number;
}>;
/**
* Optional browser-native seam. Implementations must bound the encoded body
* before buffering and close the decoded ImageBitmap after inspecting it.
*/
export interface ImageResourceProbePort {
probe(
request: ImageProbeRequest,
): Promise<BrowserDataResult<ImageProbeReceipt>>;
}
export type ImagePresentationSource = Readonly<{
type: ImageRasterMediaType;
srcSet: string;
}>;
export type ImagePresentationDescriptor = Readonly<{
src: string;
srcSet: string;
sources: readonly ImagePresentationSource[];
sizes: string;
width: number;
height: number;
fallbackMediaType: ImageRasterMediaType;
loading: "eager" | "lazy";
decoding: "async" | "sync";
fetchPriority: "high" | "low" | "auto";
referrerPolicy: "no-referrer" | "strict-origin-when-cross-origin";
crossOrigin: "anonymous";
delivery: Readonly<{
class: ImageDeliveryClass;
assetVersion: string;
browserCache: "PUBLIC_IMMUTABLE" | "NO_STORE";
sharedCache: "PUBLIC_IMMUTABLE" | "FORBIDDEN";
purge:
| "REVISION_ROLLOVER"
| "CAPABILITY_REVOCATION_OR_EXPIRY";
expiresAtEpochMs: number | null;
}>;
decodeBudget: Readonly<{
maximumCandidatePixels: number;
maximumDecodedBytes: number;
maximumEncodedBytes: number;
}>;
}>;
export interface ImageCdnPresentationPort {
/**
* BT-IMG-01. The lifetime signal is required.
*
* It used to be optional, so the `PRIMARY_REQUIRED` preset expressed a
* missing signal as a runtime `UNSUPPORTED` result - a hidden preset
* precondition. Requiring it at the type level removes that hidden rule
* instead of discovering it at runtime.
*/
resolve(request: Readonly<{
asset: ImageAssetReference;
preset: ImagePresetReference;
signal: AbortSignal;
}>): Promise<BrowserDataResult<ImagePresentationDescriptor>>;
}
export type ImageCdnRuntime = Readonly<{
assets: ImageAssetAcceptancePort;
presentation: ImageCdnPresentationPort;
/**
* Terminal and idempotent. Aborts in-flight verification/probing, revokes
* every issued reference and makes later accept/resolve calls unavailable.
*/
close(): void;
}>;