// @effect-diagnostics asyncFunction:off globalDate:off globalRandom:off globalTimers:off newPromise:off strictBooleanExpressions:off /** * Data-platform envelope (`x-modernjs-data-envelope`): the TRANSPORT/CACHE * contract of the effect lane — protocol versioning, cache scope keys, * selection plans, batching and hydration checksums. * * Boundary note (one envelope system per concern): cross-project * AUTHORIZATION is the bff-core policy's job (`x-modernjs-bff-envelope` + * operation contracts, evaluated server-side in both the hono and effect * lanes). Nothing in this module is a trust boundary; treat every value * here as client-asserted cache metadata. */ export type DataRequestMode = | 'cache-first' | 'stale-while-revalidate' | 'network-only'; export type DataMutationMode = 'optimistic' | 'pessimistic' | 'fire-and-forget'; export type SelectionPlan = { [field: string]: true | SelectionPlan; }; export interface OperationDescriptor { appNamespace: string; apiId: string; group: string; endpoint: string; schemaHash?: string; version?: number; } export interface CacheScope { appNamespace: string; origin: string; tenantId?: string; userId?: string; sessionId?: string; } export interface TraceContext { traceId: string; spanId: string; sampled: boolean; parentSpanId?: string; } export interface RequestEnvelope { protocolVersion: 1; operationId: string; appNamespace: string; origin: string; requestMode: DataRequestMode; mutationMode?: DataMutationMode; scopeKey: string; input: Input; inputHash: string; selectionPlan?: SelectionPlan; selectionHash?: string; traceparent?: string; timestamp: number; } export interface HydrationEnvelope { protocolVersion: 1; runtimeVersion: string; appNamespace: string; origin: string; createdAt: number; payload: Payload; checksum: string; } export interface InvalidationEvent { sourceNamespace: string; sourceOperationId: string; scopeKey: string; targetNamespaces?: string[]; targetOperationIds?: string[]; } export interface InvalidationSubscriber { namespace: string; operationIds?: string[]; scopeKey?: string; acceptCrossNamespace?: boolean; } export interface DataBatchRequestItem { id: string; path: string; method: string; headers?: Record; body?: DataBatchBody; } export interface DataBatchRequestPayload { protocolVersion: 2; batchId: string; sentAt: number; items: DataBatchRequestItem[]; } export interface DataBatchResponseItem { id: string; status: number; headers?: DataBatchHeader[]; body?: DataBatchBody; } export interface DataBatchBody { encoding: 'base64'; data: string; } export type DataBatchHeader = [name: string, value: string]; export interface DataBatchResponsePayload { protocolVersion: 2; batchId: string; receivedAt: number; items: DataBatchResponseItem[]; } export interface DataBatchTransportEvent { type: 'enqueue' | 'flush' | 'fallback' | 'disable'; endpoint: string; batchId?: string; size?: number; reason?: string; } export type DataBatchTransportTelemetryAttributes = Record< string, string | number | boolean >; export interface DataBatchTransportOptions { endpoint?: string; fetch?: ( input: DataTransportRequestInfo, init?: RequestInit, ) => Promise; flushIntervalMs?: number; maxBatchSize?: number; maxBatchBytes?: number; requestTimeoutMs?: number; allowedMethods?: string[]; onEvent?: (event: DataBatchTransportEvent) => void; } export interface SelectionPlanValidationOptions { maxDepth?: number; maxFields?: number; allowedLeafPaths?: ReadonlyArray; } export interface SelectionPlanValidationResult { ok: boolean; errors: string[]; stats: { maxDepth: number; fieldCount: number; }; } export interface RequestEnvelopeValidationOptions { expectedProtocolVersion?: number; expectedNamespace?: string; expectedOrigin?: string; requireTraceContext?: boolean; } export interface HydrationEnvelopeValidationOptions { expectedProtocolVersion?: number; expectedNamespace?: string; expectedOrigin?: string; expectedRuntimeVersion?: string; } export const DEFAULT_DATA_ENVELOPE_HEADER = 'x-modernjs-data-envelope'; export const DEFAULT_DATA_BATCH_ENDPOINT = '/_data/batch'; export const DEFAULT_DATA_BATCH_HEADER = 'x-modernjs-data-batch'; export type DataTransportRequestInfo = string | URL | Request;