foldkit-remote 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/store.ts","../src/mutation.ts","../src/query.ts","../src/wire.ts","../src/coalesce.ts","../src/client.ts","../src/connection.ts","../src/inspect.ts","../src/optimistic.ts","../src/live.ts","../src/relation.ts","../src/plan.ts","../src/retain.ts","../src/persistence.ts","../src/remoteData.ts","../src/model.ts","../src/policy.ts","../src/entity.ts","../src/selection.ts","../src/index.ts"],"sourcesContent":["/**\n * The pure entity store: values, per-field presence, staleness, and tombstones.\n *\n * Presence is tracked **separately** from values, so `undefined`/`null`/absent/\n * stale/not-found are distinct states and a missing field is never inferred from\n * `value === undefined`. Nothing here performs I/O; every operation returns a\n * new store.\n */\nimport { Option } from 'effect'\n\nexport type EntityKey = string\n\nexport interface EntityEntry {\n readonly values: Readonly<Record<string, unknown>>\n readonly present: ReadonlySet<string>\n /** Present fields whose value may be outdated (revalidation needed). */\n readonly stale: ReadonlySet<string>\n /** The entity is known to be absent; a later write clears this. */\n readonly tombstone: boolean\n /** Injected clock reading of the last write; never read from ambient state. */\n readonly updatedAt: number\n /**\n * The canonical window each present field was fetched with (`\"\"` for none).\n * A later request with a *known, different* window is planned as missing.\n */\n readonly windows: Readonly<Record<string, string>>\n}\n\nexport type EntityStore = Readonly<Record<EntityKey, EntityEntry>>\n\n/** The separator keeps an untrusted id from colliding with a prototype key. */\nexport const entityKey = (entity: string, id: string): EntityKey => `${entity}:${id}`\n\nconst emptyEntry: EntityEntry = {\n values: {},\n present: new Set(),\n stale: new Set(),\n tombstone: false,\n updatedAt: 0,\n windows: {},\n}\n\nexport const emptyStore: EntityStore = {}\n\nconst replace = (store: EntityStore, key: EntityKey, entry: EntityEntry): EntityStore => ({\n ...store,\n [key]: entry,\n})\n\nconst written = (\n previous: EntityEntry,\n values: Readonly<Record<string, unknown>>,\n now: number,\n windows?: Readonly<Record<string, string>>,\n): EntityEntry => {\n const present = new Set(previous.present)\n const stale = new Set(previous.stale)\n const nextWindows: Record<string, string> = { ...previous.windows }\n for (const field of Object.keys(values)) {\n present.add(field)\n stale.delete(field)\n // A write without a window clears any remembered one: the value changed.\n const requested = windows?.[field]\n if (requested !== undefined && requested !== '') nextWindows[field] = requested\n else delete nextWindows[field]\n }\n return {\n values: { ...previous.values, ...values },\n present,\n stale,\n tombstone: false,\n updatedAt: now,\n windows: nextWindows,\n }\n}\n\nexport interface EntityWrite {\n readonly key: EntityKey\n readonly values: Readonly<Record<string, unknown>>\n /** The canonical window each written relation field was fetched with. */\n readonly windows?: Readonly<Record<string, string>> | undefined\n}\n\n/**\n * Merges known values into many entities, copying the store once. Every\n * written field becomes present and non-stale; a tombstone is cleared because\n * the entity is evidently not absent.\n */\nexport const writeEntities = (\n store: EntityStore,\n writes: ReadonlyArray<EntityWrite>,\n now = 0,\n): EntityStore => {\n if (writes.length === 0) return store\n const next: Record<EntityKey, EntityEntry> = { ...store }\n for (const write of writes) {\n next[write.key] = written(next[write.key] ?? emptyEntry, write.values, now, write.windows)\n }\n return next\n}\n\n/** `writeEntities` for one entity. */\nexport const writeEntity = (\n store: EntityStore,\n key: EntityKey,\n values: Readonly<Record<string, unknown>>,\n now = 0,\n windows?: Readonly<Record<string, string>>,\n): EntityStore => writeEntities(store, [{ key, values, windows }], now)\n\n/**\n * Marks present fields stale (`true`) or ends their staleness (`false`) across\n * many entities, copying the store once. A field never present stays missing;\n * an unknown entity is left alone.\n */\nexport const setStale = (\n store: EntityStore,\n marks: ReadonlyArray<readonly [key: EntityKey, fields: Iterable<string>]>,\n stale: boolean,\n): EntityStore => {\n let next: Record<EntityKey, EntityEntry> | undefined\n for (const [key, fields] of marks) {\n const previous = (next ?? store)[key]\n if (previous === undefined) continue\n const staleFields = new Set(previous.stale)\n for (const field of fields) {\n if (stale) {\n if (previous.present.has(field)) staleFields.add(field)\n } else staleFields.delete(field)\n }\n next ??= { ...store }\n next[key] = { ...previous, stale: staleFields }\n }\n return next ?? store\n}\n\n/** Marks present fields stale; fields that were never present stay missing. */\nexport const markStale = (\n store: EntityStore,\n key: EntityKey,\n fields: Iterable<string>,\n): EntityStore => setStale(store, [[key, fields]], true)\n\n/** Ends a refresh that did not land: the fields are present again as they were. */\nexport const clearStale = (\n store: EntityStore,\n key: EntityKey,\n fields: Iterable<string>,\n): EntityStore => setStale(store, [[key, fields]], false)\n\n/** Records that the entity is known to be absent, so it is not refetched. */\nexport const tombstone = (store: EntityStore, key: EntityKey): EntityStore =>\n replace(store, key, {\n values: {},\n present: new Set(),\n stale: new Set(),\n tombstone: true,\n updatedAt: 0,\n windows: {},\n })\n\n/** Forgets everything known about the entity, including a tombstone. */\nexport const remove = (store: EntityStore, key: EntityKey): EntityStore => {\n if (store[key] === undefined) return store\n const next = { ...store }\n delete next[key]\n return next\n}\n\nexport const entry = (store: EntityStore, key: EntityKey): Option.Option<EntityEntry> => {\n const value = store[key]\n return value === undefined ? Option.none() : Option.some(value)\n}\n\nexport const isTombstone = (store: EntityStore, key: EntityKey): boolean =>\n store[key]?.tombstone === true\n\n/** A field is known only if it is present and not stale. */\nexport const hasField = (store: EntityStore, key: EntityKey, field: string): boolean => {\n const value = store[key]\n return (\n value !== undefined && !value.tombstone && value.present.has(field) && !value.stale.has(field)\n )\n}\n\n/** A present field whose value may be outdated; absent fields are not stale. */\nexport const isFieldStale = (store: EntityStore, key: EntityKey, field: string): boolean => {\n const value = store[key]\n return value !== undefined && !value.tombstone && value.stale.has(field)\n}\n\n/**\n * Reads a present field, stale or not. Absence and a tombstone both yield\n * `Option.none()`; a present `undefined`/`null` yields `Option.some`.\n */\nexport const readField = (\n store: EntityStore,\n key: EntityKey,\n field: string,\n): Option.Option<unknown> => {\n const value = store[key]\n if (value === undefined || value.tombstone || !value.present.has(field)) return Option.none()\n return Option.some(value.values[field])\n}\n\n/**\n * The fields the planner must fetch. A tombstone makes every field known\n * (absent), so it returns an empty list and the entity is not refetched. A\n * requested window that differs from the one a field was fetched with also\n * marks it missing, but only when the stored window is known (never `\"\"`), so a\n * writer that does not record windows cannot cause a refetch loop.\n */\nexport const missingFields = (\n store: EntityStore,\n key: EntityKey,\n fields: Iterable<string>,\n windows?: Readonly<Record<string, string>>,\n): ReadonlyArray<string> => {\n const value = store[key]\n if (value !== undefined && value.tombstone) return []\n return [...fields].filter(field => {\n if (value === undefined || !value.present.has(field) || value.stale.has(field)) return true\n const requested = windows?.[field]\n const stored = value.windows[field]\n return requested !== undefined && stored !== undefined && stored !== '' && stored !== requested\n })\n}\n","/**\n * Mutation status and idempotent reconciliation.\n *\n * A mutation result is reconciled into the store **at most once per\n * `requestId`**, so a transport retry cannot apply the same change twice. An\n * unknown or already-applied result is a no-op.\n */\nimport { Schema } from 'effect'\nimport { entityKey, writeEntity, type EntityStore } from './store.js'\n\nexport interface NormalizedPatch {\n readonly entity: string\n readonly id: string\n readonly values: Readonly<Record<string, unknown>>\n}\n\nexport interface MutationState {\n readonly pending: ReadonlySet<string>\n readonly applied: ReadonlySet<string>\n readonly failed: ReadonlySet<string>\n /**\n * How many mutations this model has started. A bound domain takes its next\n * request id from here, so `update` stays pure and the id exists before the\n * Command runs.\n */\n readonly sequence: number\n}\n\nexport const emptyMutationState: MutationState = {\n pending: new Set(),\n applied: new Set(),\n failed: new Set(),\n sequence: 0,\n}\n\n/**\n * How many settled request ids a mutation state retains. A retry settles well\n * inside this window, so bounding the ledger stops a long-lived application\n * from growing it without limit; a retry older than the window would re-apply\n * its entities.\n */\nconst MUTATION_ID_WINDOW = 1024\n\n/** Records `id` as most recent, evicting the oldest once the window is full. */\nconst remember = (ids: ReadonlySet<string>, id: string): ReadonlySet<string> => {\n const next = new Set(ids)\n // Re-inserting an existing id moves it to the most-recent end.\n next.delete(id)\n next.add(id)\n if (next.size <= MUTATION_ID_WINDOW) return next\n return new Set([...next].slice(next.size - MUTATION_ID_WINDOW))\n}\n\nexport const beginMutation = (state: MutationState, requestId: string): MutationState => ({\n ...state,\n pending: new Set([...state.pending, requestId]),\n sequence: state.sequence + 1,\n})\n\nexport const failMutation = (state: MutationState, requestId: string): MutationState => {\n const pending = new Set(state.pending)\n pending.delete(requestId)\n return { ...state, pending, failed: remember(state.failed, requestId) }\n}\n\nexport interface Reconciled {\n readonly store: EntityStore\n readonly state: MutationState\n}\n\n/**\n * Applies a mutation result once and marks the request settled. A second call\n * with the same `requestId` (a retry, or a live event describing the same change)\n * does not re-apply the entities, but still clears `pending`.\n */\nexport const reconcileMutation = (\n store: EntityStore,\n state: MutationState,\n requestId: string,\n entities: ReadonlyArray<NormalizedPatch>,\n): Reconciled => {\n const next = state.applied.has(requestId)\n ? store\n : entities.reduce(\n (current, entity) =>\n writeEntity(current, entityKey(entity.entity, entity.id), entity.values),\n store,\n )\n const applied = remember(state.applied, requestId)\n const pending = new Set(state.pending)\n pending.delete(requestId)\n return { store: next, state: { ...state, applied, pending } }\n}\n\n/** A mutation an application declares: its name and input/output codecs. */\nexport interface MutationDescriptor<Name extends string, Input, Output> {\n readonly name: Name\n readonly Input: Schema.Codec<Input>\n readonly Output: Schema.Codec<Output>\n}\n\n/** A codec, or the fields of a `Schema.Struct` where one is expected. */\nexport type SchemaOrFields = Schema.Codec<any, any, any, any> | Schema.Struct.Fields\n\n/** The decoded type of a codec, or of the Struct the fields describe. */\nexport type TypeOf<S extends SchemaOrFields> =\n S extends Schema.Codec<infer T, any, any, any>\n ? T\n : S extends Schema.Struct.Fields\n ? Schema.Struct.Type<S>\n : never\n\n/** The codec itself, or a `Schema.Struct` over the fields. */\nexport const schemaOf = <S extends SchemaOrFields>(shape: S): Schema.Codec<TypeOf<S>> =>\n (Schema.isSchema(shape) ? shape : Schema.Struct(shape as Schema.Struct.Fields)) as Schema.Codec<\n TypeOf<S>\n >\n\nexport const Mutation = {\n /**\n * Declares a mutation. `Input` and `Output` are codecs, or the fields of the\n * `Schema.Struct` they would be (`{ id: ProjectId, name: Schema.String }`).\n */\n make: <const Name extends string, Input extends SchemaOrFields, Output extends SchemaOrFields>(\n name: Name,\n config: { readonly Input: Input; readonly Output: Output },\n ): MutationDescriptor<Name, TypeOf<Input>, TypeOf<Output>> => ({\n name,\n Input: schemaOf(config.Input),\n Output: schemaOf(config.Output),\n }),\n}\n","/**\n * Queries and connections. A connection's identity is its descriptor plus the\n * canonical encoded filter/sort input — **never** the pagination window, so\n * `first(25)` and `after(cursor).first(25)` address the same logical connection.\n */\nimport { Schema } from 'effect'\nimport type { Cursor } from './connection.js'\nimport { schemaOf, type SchemaOrFields, type TypeOf } from './mutation.js'\n\nexport type LiveInsertion = 'visible' | 'boundary' | 'invalidate' | 'ignore'\n\nexport interface LivePolicy {\n readonly prepend?: LiveInsertion\n readonly append?: LiveInsertion\n}\n\nexport interface ConnectionSpec<Entity extends string = string> {\n readonly entity: Entity\n readonly edgeKey?: Schema.Schema<unknown>\n readonly live?: LivePolicy\n}\n\nexport interface QueryWindow {\n readonly first?: number | undefined\n readonly last?: number | undefined\n readonly after?: Cursor | undefined\n readonly before?: Cursor | undefined\n}\n\nexport interface QueryRef<Name extends string, Input> {\n readonly query: Name\n readonly input: Input\n /** The input codec, so a `QueryRef` can encode itself without its descriptor. */\n readonly Input: Schema.Codec<Input>\n readonly window: QueryWindow\n /** Connection identity: descriptor + canonical input, excluding the window. */\n readonly identity: string\n}\n\nexport interface QueryDescriptor<Name extends string, Input, Result> {\n readonly name: Name\n readonly Input: Schema.Codec<Input>\n readonly Result: Result\n readonly ref: (input: Input) => QueryRef<Name, Input>\n}\n\n/** Stable stringify: object keys sorted, undefined-valued keys dropped, so equal inputs encode equally. */\nexport const stableStringify = (value: unknown): string => {\n if (value === undefined) return 'null'\n if (value === null || typeof value !== 'object') return JSON.stringify(value)\n if (Array.isArray(value)) return `[${value.map(stableStringify).join(',')}]`\n const record = value as Record<string, unknown>\n return `{${Object.keys(record)\n .filter(key => record[key] !== undefined)\n .sort()\n .map(key => `${JSON.stringify(key)}:${stableStringify(record[key])}`)\n .join(',')}}`\n}\n\n/**\n * `Result: Project` (or anything with the entity's `name`, as `Query.connection`\n * takes) means a connection over it; a `ConnectionSpec` names its `entity`\n * instead and is the result as given.\n */\nexport type ResultOf<Result> = Result extends { readonly name: infer Entity extends string }\n ? ConnectionSpec<Entity>\n : Result\n\nconst isEntityName = (result: unknown): result is { readonly name: string } =>\n typeof result === 'object' &&\n result !== null &&\n typeof (result as { readonly name?: unknown }).name === 'string'\n\nexport const Query = {\n /** Declares the entity and options a query's result is a connection over. */\n connection: <Entity extends string>(\n entity: { readonly name: Entity },\n options?: { readonly edgeKey?: Schema.Schema<unknown>; readonly live?: LivePolicy },\n ): ConnectionSpec<Entity> => ({\n entity: entity.name,\n ...(options?.edgeKey === undefined ? {} : { edgeKey: options.edgeKey }),\n ...(options?.live === undefined ? {} : { live: options.live }),\n }),\n\n /**\n * Declares a query. `Input` is a codec or the fields of the `Schema.Struct` it\n * would be; `Result` is a `Query.connection(...)`, or the entity the result is\n * a connection over.\n */\n make: <const Name extends string, Input extends SchemaOrFields, Result>(\n name: Name,\n config: { readonly Input: Input; readonly Result: Result },\n ): QueryDescriptor<Name, TypeOf<Input>, ResultOf<Result>> => {\n const Input = schemaOf(config.Input)\n const encode = Schema.encodeSync(Input)\n return {\n name,\n Input,\n Result: (isEntityName(config.Result)\n ? Query.connection(config.Result)\n : config.Result) as ResultOf<Result>,\n ref: input => ({\n query: name,\n input,\n Input,\n window: {},\n identity: `${name}\\u0000${stableStringify(encode(input))}`,\n }),\n }\n },\n\n first:\n (count: number) =>\n <R extends QueryRef<string, unknown>>(ref: R): R => ({\n ...ref,\n window: { ...ref.window, first: count },\n }),\n\n last:\n (count: number) =>\n <R extends QueryRef<string, unknown>>(ref: R): R => ({\n ...ref,\n window: { ...ref.window, last: count },\n }),\n\n after:\n (cursor: Cursor) =>\n <R extends QueryRef<string, unknown>>(ref: R): R => ({\n ...ref,\n window: { ...ref.window, after: cursor },\n }),\n\n before:\n (cursor: Cursor) =>\n <R extends QueryRef<string, unknown>>(ref: R): R => ({\n ...ref,\n window: { ...ref.window, before: cursor },\n }),\n}\n","/**\n * The Remote wire: Effect RPC semantics over `effect/unstable/rpc`. Remote owns\n * the message shapes; Effect owns the transport. `Make`ing reads batch, mutations\n * preserve order, and live data is a stream.\n */\nimport { Schema } from 'effect'\nimport { Rpc, RpcGroup } from 'effect/unstable/rpc'\nimport type { RelationRequirement, Requirement } from 'foldkit-surface'\n\n/**\n * The read/live protocol version. A batch names the version it speaks and the\n * server refuses a mismatch with `RemoteProtocolError`, so a shape change never\n * drifts silently: bump it whenever `ReadRequest` or `LiveRequirement` change.\n */\nexport const REMOTE_PROTOCOL_VERSION = 3\n\nexport class RemoteReadError extends Schema.TaggedError<RemoteReadError>()('RemoteReadError', {\n message: Schema.String,\n}) {}\n\nexport class RemoteMutationError extends Schema.TaggedError<RemoteMutationError>()(\n 'RemoteMutationError',\n { message: Schema.String },\n) {}\n\nexport class RemoteLiveError extends Schema.TaggedError<RemoteLiveError>()('RemoteLiveError', {\n message: Schema.String,\n}) {}\n\n/** The peer speaks another protocol version; nothing was read. */\nexport class RemoteProtocolError extends Schema.TaggedError<RemoteProtocolError>()(\n 'RemoteProtocolError',\n { message: Schema.String, expected: Schema.Number, received: Schema.Number },\n) {}\n\n/** A page size: a non-negative integer, refused at decode otherwise rather than defaulted. */\nexport const PageSize = Schema.Number.check(Schema.isInt(), Schema.isGreaterThanOrEqualTo(0))\n\nexport const WindowSchema = Schema.Struct({\n first: Schema.optional(PageSize),\n last: Schema.optional(PageSize),\n after: Schema.optional(Schema.String),\n before: Schema.optional(Schema.String),\n})\n\n/** A request may not name more fields of one entity than this; a selection never does. */\nexport const MAX_FIELDS_PER_REQUEST = 256\n/** A selection may not nest relations deeper than this; the wire refuses more. */\nexport const MAX_RELATION_DEPTH = 8\n\nconst Fields = Schema.Array(Schema.String).check(Schema.isMaxLength(MAX_FIELDS_PER_REQUEST))\n\n/**\n * The slice required of a relation's target; the ids come from the parent's\n * refs. Built as `MAX_RELATION_DEPTH` nested structs rather than a recursive\n * schema, so a deeper selection is refused at decode with a schema error.\n */\nconst relationLevel = (depth: number): Schema.Codec<RelationRequirement, RelationRequirement> => {\n const slice = {\n entity: Schema.String,\n fields: Fields,\n windows: Schema.optional(Schema.Record(Schema.String, WindowSchema)),\n }\n // A struct drops an unknown key silently; the last level refuses one instead.\n return (depth === 0\n ? Schema.Struct({ ...slice, relations: Schema.optionalKey(Schema.Never) })\n : Schema.Struct({\n ...slice,\n relations: Schema.optional(Schema.Record(Schema.String, relationLevel(depth - 1))),\n })) as unknown as Schema.Codec<RelationRequirement, RelationRequirement>\n}\n\nexport const RelationRequest = relationLevel(MAX_RELATION_DEPTH - 1)\n\nexport const ReadRequest: Schema.Codec<Requirement, Requirement> = Schema.Struct({\n entity: Schema.String,\n id: Schema.String,\n fields: Fields,\n /** Pagination window per relation field. */\n windows: Schema.optional(Schema.Record(Schema.String, WindowSchema)),\n /** The slice required of each relation field's target, resolved in the same read. */\n relations: Schema.optional(Schema.Record(Schema.String, RelationRequest)),\n}) as unknown as Schema.Codec<Requirement, Requirement>\n\nexport const ReadBatch = Schema.Struct({\n version: Schema.Number,\n requests: Schema.Array(ReadRequest),\n})\n\nexport const NormalizedEntity = Schema.Struct({\n entity: Schema.String,\n id: Schema.String,\n values: Schema.Record(Schema.String, Schema.Unknown),\n})\n\nexport const ReadBatchResult = Schema.Struct({ entities: Schema.Array(NormalizedEntity) })\n\nexport const MutationRequest = Schema.Struct({\n /** Stable across transport retries so a mutation is not applied twice. */\n requestId: Schema.String,\n mutation: Schema.String,\n input: Schema.Unknown,\n})\n\nexport const LiveEdge = Schema.Struct({\n entity: Schema.String,\n id: Schema.String,\n key: Schema.String,\n})\n\n/** A connection change a mutation confirms: the same facts a live event carries, without a cursor. */\nexport const ConnectionChangeSchema = Schema.Union([\n Schema.Struct({\n _tag: Schema.Literal('Insert'),\n connection: Schema.String,\n position: Schema.Union([Schema.Literal('prepend'), Schema.Literal('append')]),\n edge: LiveEdge,\n }),\n Schema.Struct({ _tag: Schema.Literal('Remove'), connection: Schema.String, edge: LiveEdge }),\n])\n\nexport const MutationResult = Schema.Struct({\n output: Schema.Unknown,\n entities: Schema.Array(NormalizedEntity),\n /** Connection changes the mutation made, applied alongside its entity patches. */\n connections: Schema.optional(Schema.Array(ConnectionChangeSchema)),\n})\n\nexport const LiveRequirement = Schema.Struct({\n version: Schema.Number,\n requirements: Schema.Array(ReadRequest),\n /** Resume cursor; events at or before it are duplicates. */\n after: Schema.Number,\n})\n\n/**\n * A live change. Entity changes update the store; connection changes alter\n * membership and ordering; both carry a per-stream cursor.\n */\nexport const LiveChange = Schema.Union([\n Schema.Struct({\n _tag: Schema.Literal('EntityPatched'),\n cursor: Schema.Number,\n entity: Schema.String,\n id: Schema.String,\n values: Schema.Record(Schema.String, Schema.Unknown),\n changed: Schema.Array(Schema.String),\n }),\n Schema.Struct({\n _tag: Schema.Literal('EntityDeleted'),\n cursor: Schema.Number,\n entity: Schema.String,\n id: Schema.String,\n }),\n Schema.Struct({\n _tag: Schema.Literal('ConnectionInsert'),\n cursor: Schema.Number,\n connection: Schema.String,\n position: Schema.Union([Schema.Literal('prepend'), Schema.Literal('append')]),\n edge: LiveEdge,\n }),\n Schema.Struct({\n _tag: Schema.Literal('ConnectionRemove'),\n cursor: Schema.Number,\n connection: Schema.String,\n edge: LiveEdge,\n }),\n Schema.Struct({\n _tag: Schema.Literal('ConnectionInvalidate'),\n cursor: Schema.Number,\n connection: Schema.String,\n }),\n])\n\nexport const Read = Rpc.make('FoldkitRemoteRead', {\n payload: ReadBatch,\n success: ReadBatchResult,\n error: Schema.Union([RemoteReadError, RemoteProtocolError]),\n})\n\nexport const Mutate = Rpc.make('FoldkitRemoteMutate', {\n payload: MutationRequest,\n success: MutationResult,\n error: RemoteMutationError,\n})\n\nexport const Live = Rpc.make('FoldkitRemoteLive', {\n payload: LiveRequirement,\n success: LiveChange,\n error: Schema.Union([RemoteLiveError, RemoteProtocolError]),\n stream: true,\n})\n\nexport class RemoteQueryError extends Schema.TaggedError<RemoteQueryError>()('RemoteQueryError', {\n message: Schema.String,\n}) {}\n\nexport const WireBoundary = Schema.Union([\n Schema.Struct({ _tag: Schema.Literal('Terminal') }),\n Schema.Struct({ _tag: Schema.Literal('Cursor'), cursor: Schema.String }),\n Schema.Struct({ _tag: Schema.Literal('Unknown') }),\n])\n\nexport const QueryRequest = Schema.Struct({\n query: Schema.String,\n input: Schema.Unknown,\n window: WindowSchema,\n})\n\nexport const QueryEdge = Schema.Struct({\n entity: Schema.String,\n id: Schema.String,\n key: Schema.String,\n})\n\nexport const QueryResult = Schema.Struct({\n edges: Schema.Array(QueryEdge),\n start: WireBoundary,\n end: WireBoundary,\n})\n\nexport const QueryRpc = Rpc.make('FoldkitRemoteQuery', {\n payload: QueryRequest,\n success: QueryResult,\n error: RemoteQueryError,\n})\n\nexport const RemoteRpc = RpcGroup.make(Read, Mutate, QueryRpc, Live)\n","/**\n * Read coalescing: every requirement a client asks for goes through one\n * `RequestResolver`, so requirements issued together become one `ReadBatch`\n * (ids batched, fields unioned) and a requirement already in flight is joined\n * rather than re-requested. The planner stays pure; this is the transport\n * seam's concern, and the store is still the only cache.\n */\nimport {\n Deferred,\n Duration,\n Effect,\n Request,\n RequestResolver,\n type Exit,\n type Schema,\n} from 'effect'\nimport { Requirement, type RelationRequirement } from 'foldkit-surface'\nimport { stableStringify } from './query.js'\nimport {\n REMOTE_PROTOCOL_VERSION,\n type QueryRequest,\n type QueryResult,\n type ReadBatch,\n type ReadBatchResult,\n} from './wire.js'\nimport type { RemoteProtocolError, RemoteQueryError, RemoteReadError } from './wire.js'\n\ntype Batch = Schema.Schema.Type<typeof ReadBatch>\ntype BatchResult = Schema.Schema.Type<typeof ReadBatchResult>\ntype ReadError = RemoteReadError | RemoteProtocolError\nexport type BatchRead = (batch: Batch) => Effect.Effect<BatchResult, ReadError>\ntype QueryRequestValue = Schema.Schema.Type<typeof QueryRequest>\ntype QueryResultValue = Schema.Schema.Type<typeof QueryResult>\nexport type QueryRun = (\n request: QueryRequestValue,\n) => Effect.Effect<QueryResultValue, RemoteQueryError>\n\nexport interface CoalesceOptions {\n /**\n * How long a batch waits to collect more requirements before it runs.\n * Requirements issued concurrently coalesce even at the default of no wait.\n */\n readonly window?: Duration.Input | undefined\n}\n\n/** A stable key for a requirement, so an equal requirement in flight is joined. */\nexport const requirementKey = (requirement: Requirement): string =>\n stableStringify([\n requirement.entity,\n requirement.id,\n [...requirement.fields].sort(),\n requirement.windows ?? null,\n requirement.relations ?? null,\n ])\n\n/** Whether a requirement pages a relation anywhere in its graph. */\nconst hasWindows = (requirement: RelationRequirement): boolean =>\n requirement.windows !== undefined || Object.values(requirement.relations ?? {}).some(hasWindows)\n\n/**\n * The reads a batch runs. Requirements that page nothing union into one read\n * per entity and id, and every waiter may write its whole result, since\n * plain values are the same whoever asked. A requirement that pages a\n * relation reads alone: a page answers exactly one window, and a waiter\n * cannot tell which of two pages for the same entity was its own.\n */\nconst readsOf = (\n owned: ReadonlyMap<string, Requirement>,\n): ReadonlyArray<{\n readonly keys: ReadonlyArray<string>\n readonly requests: ReadonlyArray<Requirement>\n}> => {\n const plain = [...owned].filter(([, requirement]) => !hasWindows(requirement))\n const paged = [...owned].filter(([, requirement]) => hasWindows(requirement))\n return [\n ...(plain.length === 0\n ? []\n : [\n {\n keys: plain.map(([key]) => key),\n requests: Requirement.merge(plain.map(([, requirement]) => requirement)),\n },\n ]),\n ...paged.map(([key, requirement]) => ({ keys: [key], requests: [requirement] })),\n ]\n}\n\nclass QueryRead extends Request.Class<\n { readonly key: string; readonly request: QueryRequestValue },\n QueryResultValue,\n RemoteQueryError\n> {}\n\n/**\n * Wraps a raw query so that an identical query in flight (same query, input,\n * and window) is joined rather than run again; distinct queries run\n * concurrently. A page answers exactly one window, so nothing is batched.\n */\nexport const coalesceQueries = (\n query: QueryRun,\n options: CoalesceOptions = {},\n): Effect.Effect<QueryRun> =>\n Effect.gen(function* () {\n const runAll = (entries: ReadonlyArray<Request.Entry<QueryRead>>) =>\n Effect.gen(function* () {\n const distinct = new Map<string, QueryRequestValue>()\n for (const entry of entries) distinct.set(entry.request.key, entry.request.request)\n const results = new Map<string, Exit.Exit<QueryResultValue, RemoteQueryError>>()\n yield* Effect.forEach(\n distinct,\n ([key, request]) =>\n Effect.exit(query(request)).pipe(Effect.map(exit => void results.set(key, exit))),\n { concurrency: 'unbounded', discard: true },\n )\n for (const entry of entries) {\n yield* Request.completeEffect(entry, results.get(entry.request.key)!)\n }\n })\n let resolver = RequestResolver.make<QueryRead>(runAll)\n if (options.window !== undefined) {\n resolver = RequestResolver.setDelay(resolver, Duration.fromInputUnsafe(options.window))\n }\n return request =>\n Effect.request(\n new QueryRead({\n key: stableStringify([request.query, request.input, request.window]),\n request,\n }),\n resolver,\n )\n })\n\nclass ReadRequirement extends Request.Class<\n { readonly key: string; readonly requirement: Requirement },\n BatchResult,\n ReadError\n> {}\n\n/**\n * Wraps a raw batch read so that requirements are batched and deduplicated.\n * Every waiter receives the whole batch result; `Remote.writeRead` is\n * idempotent, so writing it more than once is harmless.\n */\nexport const coalesceReads = (\n read: BatchRead,\n options: CoalesceOptions = {},\n): Effect.Effect<BatchRead> =>\n Effect.gen(function* () {\n // Requirements a batch is currently reading; a later equal requirement\n // joins the deferred instead of starting another read.\n const inFlight = new Map<string, Deferred.Deferred<BatchResult, ReadError>>()\n\n // A batch runs to completion even when every requester is interrupted, so\n // an in-flight requirement is always settled and released by its read.\n const runAll = (entries: ReadonlyArray<Request.Entry<ReadRequirement>>) =>\n Effect.gen(function* () {\n // Per requirement key: the deferred this batch's entries wait on. One\n // already in flight from an earlier batch is joined; the rest are\n // owned here and settled by this batch's read.\n const joins = new Map<string, Deferred.Deferred<BatchResult, ReadError>>()\n const own = new Map<string, Deferred.Deferred<BatchResult, ReadError>>()\n for (const entry of entries) {\n const key = entry.request.key\n if (joins.has(key)) continue\n const existing = inFlight.get(key)\n if (existing !== undefined) {\n joins.set(key, existing)\n continue\n }\n const deferred = yield* Deferred.make<BatchResult, ReadError>()\n inFlight.set(key, deferred)\n own.set(key, deferred)\n joins.set(key, deferred)\n }\n if (own.size > 0) {\n const owned = new Map<string, Requirement>()\n for (const entry of entries) {\n if (own.has(entry.request.key)) owned.set(entry.request.key, entry.request.requirement)\n }\n yield* Effect.forEach(\n readsOf(owned),\n ({ keys, requests }) =>\n Effect.gen(function* () {\n const exit = yield* Effect.exit(\n read({ version: REMOTE_PROTOCOL_VERSION, requests }),\n )\n // Settle exactly the requirements this read answered.\n for (const key of keys) {\n inFlight.delete(key)\n yield* Deferred.done(own.get(key)!, exit)\n }\n }),\n { concurrency: 'unbounded', discard: true },\n )\n }\n for (const entry of entries) {\n yield* Request.completeEffect(entry, Deferred.await(joins.get(entry.request.key)!))\n }\n })\n\n let resolver = RequestResolver.make<ReadRequirement>(runAll)\n if (options.window !== undefined) {\n resolver = RequestResolver.setDelay(resolver, Duration.fromInputUnsafe(options.window))\n }\n\n return batch =>\n batch.requests.length === 0\n ? Effect.succeed({ entities: [] })\n : Effect.forEach(\n batch.requests,\n requirement =>\n Effect.request(\n new ReadRequirement({ key: requirementKey(requirement), requirement }),\n resolver,\n ),\n { concurrency: 'unbounded' },\n ).pipe(\n Effect.map(results => ({\n entities: [...new Set(results)].flatMap(result => result.entities),\n })),\n )\n })\n","/**\n * The transport seam: the `RemoteClient` Effect service, the RPC client it is\n * built from, the wire-to-client reconstructions, and the mutation call.\n */\nimport { Context, Effect, Layer, Schema, Stream } from 'effect'\nimport type { Requirement } from 'foldkit-surface'\nimport { coalesceQueries, coalesceReads, type CoalesceOptions } from './coalesce.js'\nimport type { LiveCursor, LiveEvent } from './live.js'\nimport type { MutationDescriptor } from './mutation.js'\nimport type { ConnectionChange } from './optimistic.js'\nimport type { RemoteError } from './remoteData.js'\nimport {\n MutationRequest,\n MutationResult,\n QueryRequest,\n QueryResult,\n ReadBatch,\n ReadBatchResult,\n type ConnectionChangeSchema,\n RemoteLiveError,\n RemoteMutationError,\n RemoteProtocolError,\n RemoteQueryError,\n RemoteReadError,\n type LiveChange,\n type LiveRequirement,\n} from './wire.js'\n\n/**\n * The transport boundary. `foldkit-remote` never talks to a transport directly;\n * it depends on this Effect service, which a later phase wires to Effect RPC.\n */\nexport class RemoteClient extends Context.Service<\n RemoteClient,\n {\n readonly read: (\n batch: Schema.Schema.Type<typeof ReadBatch>,\n ) => Effect.Effect<\n Schema.Schema.Type<typeof ReadBatchResult>,\n RemoteReadError | RemoteProtocolError\n >\n readonly query: (\n request: Schema.Schema.Type<typeof QueryRequest>,\n ) => Effect.Effect<Schema.Schema.Type<typeof QueryResult>, RemoteQueryError>\n readonly mutate: (\n request: Schema.Schema.Type<typeof MutationRequest>,\n ) => Effect.Effect<Schema.Schema.Type<typeof MutationResult>, RemoteMutationError>\n readonly live: (request: {\n readonly requirements: ReadonlyArray<Requirement>\n readonly after: LiveCursor\n }) => Stream.Stream<LiveEvent, RemoteLiveError | RemoteProtocolError>\n }\n>()('foldkit-remote/RemoteClient') {}\n\n/**\n * The methods an Effect RPC client for `RemoteRpc` exposes. `R` is the\n * environment a handler needs; it defaults to `never`, which is what a real\n * transport client satisfies. `RemoteServer.handlers` returns this type with its\n * own `R`, so the two sides cannot drift apart.\n */\nexport interface RemoteRpcClient<R = never> {\n readonly FoldkitRemoteRead: (\n payload: Schema.Schema.Type<typeof ReadBatch>,\n ) => Effect.Effect<\n Schema.Schema.Type<typeof ReadBatchResult>,\n RemoteReadError | RemoteProtocolError,\n R\n >\n readonly FoldkitRemoteQuery: (\n payload: Schema.Schema.Type<typeof QueryRequest>,\n ) => Effect.Effect<Schema.Schema.Type<typeof QueryResult>, RemoteQueryError, R>\n readonly FoldkitRemoteMutate: (\n payload: Schema.Schema.Type<typeof MutationRequest>,\n ) => Effect.Effect<Schema.Schema.Type<typeof MutationResult>, RemoteMutationError, R>\n readonly FoldkitRemoteLive: (\n payload: Schema.Schema.Type<typeof LiveRequirement>,\n ) => Stream.Stream<\n Schema.Schema.Type<typeof LiveChange>,\n RemoteLiveError | RemoteProtocolError,\n R\n >\n}\n\n/** Reconstructs the client's `ConnectionChange` from the wire's flattened edge. */\nexport const connectionChangeOf = (\n change: Schema.Schema.Type<typeof ConnectionChangeSchema>,\n): ConnectionChange => {\n const edge = { key: change.edge.key, ref: { entity: change.edge.entity, id: change.edge.id } }\n return change._tag === 'Insert'\n ? { _tag: 'Insert', connection: change.connection, position: change.position, edge }\n : { _tag: 'Remove', connection: change.connection, edge }\n}\n\n/** Reconstructs the client's `LiveEvent` from the wire's flattened `LiveChange`. */\nexport const liveEventOf = (change: Schema.Schema.Type<typeof LiveChange>): LiveEvent => {\n switch (change._tag) {\n case 'EntityPatched':\n return {\n _tag: 'EntityPatched',\n ref: { entity: change.entity, id: change.id },\n values: change.values,\n changed: change.changed,\n cursor: change.cursor,\n }\n case 'EntityDeleted':\n return {\n _tag: 'EntityDeleted',\n ref: { entity: change.entity, id: change.id },\n cursor: change.cursor,\n }\n case 'ConnectionInsert':\n return {\n _tag: 'ConnectionInsert',\n connection: change.connection,\n position: change.position,\n edge: { key: change.edge.key, ref: { entity: change.edge.entity, id: change.edge.id } },\n cursor: change.cursor,\n }\n case 'ConnectionRemove':\n return {\n _tag: 'ConnectionRemove',\n connection: change.connection,\n edge: { key: change.edge.key, ref: { entity: change.edge.entity, id: change.edge.id } },\n cursor: change.cursor,\n }\n case 'ConnectionInvalidate':\n return { _tag: 'ConnectionInvalidate', connection: change.connection, cursor: change.cursor }\n }\n}\n\nexport const remoteError = (error: {\n readonly _tag: string\n readonly message: string\n}): RemoteError => ({\n _tag: error._tag,\n message: error.message,\n})\n\nexport const coalescedLayer = <E, R>(\n layer: Layer.Layer<RemoteClient, E, R>,\n options: CoalesceOptions = {},\n): Layer.Layer<RemoteClient, E, R> =>\n Layer.effect(\n RemoteClient,\n Effect.gen(function* () {\n const client = yield* RemoteClient\n const read = yield* coalesceReads(client.read, options)\n const query = yield* coalesceQueries(client.query, options)\n return { ...client, read, query }\n }),\n ).pipe(Layer.provide(layer))\n\n/**\n * `Remote.mutate` as a standalone effect, so `Remote.mutateInto` can reuse it\n * without the object literal referencing itself.\n */\nexport const mutateRemote = Effect.fn('Remote.mutate')(function* <\n Name extends string,\n Input,\n Output,\n>(mutation: MutationDescriptor<Name, Input, Output>, input: Input, requestId: string) {\n yield* Effect.annotateCurrentSpan({ mutation: mutation.name, requestId })\n const client = yield* RemoteClient\n const encoded = yield* Schema.encodeUnknownEffect(mutation.Input)(input).pipe(\n Effect.catchTag('SchemaError', error =>\n Effect.fail(new RemoteMutationError({ message: error.message })),\n ),\n )\n const result = yield* client.mutate({\n requestId,\n mutation: mutation.name,\n input: encoded,\n })\n const output = yield* Schema.decodeUnknownEffect(mutation.Output)(result.output).pipe(\n Effect.catchTag('SchemaError', error =>\n Effect.fail(new RemoteMutationError({ message: error.message })),\n ),\n )\n return {\n output,\n entities: result.entities,\n connections: (result.connections ?? []).map(connectionChangeOf),\n }\n})\n","/**\n * The pure connection model: an ordered normalized structure of edges with\n * explicit known boundaries. Pages, live events, and optimistic inserts are all\n * evidence about one connection; `merge` is the single deterministic reducer and\n * performs no I/O.\n *\n * Optimistic overlays and live state arrive in later phases.\n */\nimport { entityKey } from './store.js'\n\nexport interface EdgeRef {\n readonly entity: string\n readonly id: string\n}\n\n/** `key` is the edge identity used for de-duplication. */\nexport interface Edge {\n readonly key: string\n readonly ref: EdgeRef\n}\n\nexport const edge = (ref: EdgeRef, key: string = entityKey(ref.entity, ref.id)): Edge => ({\n key,\n ref,\n})\n\nexport type Cursor = string\n\nexport type Boundary =\n | { readonly _tag: 'Terminal' }\n | { readonly _tag: 'Cursor'; readonly cursor: Cursor }\n | { readonly _tag: 'Unknown' }\n\nexport const terminal: Boundary = { _tag: 'Terminal' }\nexport const unknown: Boundary = { _tag: 'Unknown' }\nexport const cursor = (value: Cursor): Boundary => ({ _tag: 'Cursor', cursor: value })\n\nexport interface Segment {\n readonly edges: readonly Edge[]\n readonly start: Boundary\n readonly end: Boundary\n}\n\nexport interface Connection {\n readonly segments: readonly Segment[]\n readonly stale: boolean\n}\n\nexport const emptyConnection: Connection = { segments: [], stale: false }\n\nexport const segment = (edges: readonly Edge[], start: Boundary, end: Boundary): Segment => ({\n edges,\n start,\n end,\n})\n\nconst dedupeEdges = (edges: readonly Edge[]): Edge[] => {\n const seen = new Set<string>()\n const out: Edge[] = []\n for (const value of edges) {\n if (seen.has(value.key)) continue\n seen.add(value.key)\n out.push(value)\n }\n return out\n}\n\nconst normalize = (segment: Segment): Segment => ({ ...segment, edges: dedupeEdges(segment.edges) })\n\n/** Longest suffix of `a` that is a prefix of `b`, matched by edge identity. */\nconst overlapLength = (a: readonly Edge[], b: readonly Edge[]): number => {\n const most = Math.min(a.length, b.length)\n for (let length = most; length > 0; length--) {\n let matches = true\n for (let i = 0; i < length; i++) {\n if (a[a.length - length + i]!.key !== b[i]!.key) {\n matches = false\n break\n }\n }\n if (matches) return length\n }\n return 0\n}\n\nconst cursorJoinable = (a: Boundary, b: Boundary): boolean =>\n a._tag === 'Cursor' && b._tag === 'Cursor' && a.cursor === b.cursor\n\n/** Joins `a` immediately before `b`, or returns `undefined` when they are not contiguous. */\nconst join = (a: Segment, b: Segment): Segment | undefined => {\n if (cursorJoinable(a.end, b.start)) {\n return { edges: dedupeEdges([...a.edges, ...b.edges]), start: a.start, end: b.end }\n }\n const overlap = overlapLength(a.edges, b.edges)\n if (overlap > 0) {\n return {\n edges: dedupeEdges([...a.edges, ...b.edges]),\n start: a.start,\n end: b.end,\n }\n }\n return undefined\n}\n\n/**\n * Global by edge identity: an edge appears once per connection. Dropping a\n * shared edge from the middle of a segment would otherwise imply that its\n * surviving neighbours are adjacent, so a segment with holes is split at each\n * hole and the new inner boundaries are `Unknown`.\n */\nconst dedupeConnection = (segments: readonly Segment[]): Segment[] => {\n const seen = new Set<string>()\n const out: Segment[] = []\n for (const segmentValue of segments) {\n const runs: Edge[][] = []\n let run: Edge[] = []\n for (const edgeValue of segmentValue.edges) {\n if (seen.has(edgeValue.key)) {\n if (run.length > 0) {\n runs.push(run)\n run = []\n }\n continue\n }\n seen.add(edgeValue.key)\n run.push(edgeValue)\n }\n if (run.length > 0) runs.push(run)\n if (runs.length === 0) continue\n if (runs.length === 1) {\n out.push({ ...segmentValue, edges: runs[0]! })\n continue\n }\n runs.forEach((edges, index) => {\n out.push({\n edges,\n start: index === 0 ? segmentValue.start : unknown,\n end: index === runs.length - 1 ? segmentValue.end : unknown,\n })\n })\n }\n return out\n}\n\n/** Adds a page to the connection, joining contiguous or overlapping segments. */\nexport const merge = (current: Connection, page: Segment): Connection => {\n // A zero-edge page carries no ordering evidence; joining it would let its\n // boundary overwrite a real segment's end. Ignore it.\n const incoming = normalize(page)\n if (incoming.edges.length === 0) return current\n\n const segments = [...current.segments.map(normalize), incoming]\n let joined = true\n while (joined) {\n joined = false\n outer: for (let i = 0; i < segments.length; i++) {\n for (let j = 0; j < segments.length; j++) {\n if (i === j) continue\n const result = join(segments[i]!, segments[j]!)\n if (result === undefined) continue\n segments[i] = result\n segments.splice(j, 1)\n joined = true\n break outer\n }\n }\n }\n return { ...current, segments: orderSegments(dedupeConnection(segments)) }\n}\n\n/**\n * Disjoint segments have no cursor linking them, so their relative order is\n * whatever it was; the two exceptions are known: a segment starting at the\n * terminal boundary is first, one ending at it is last.\n */\nconst orderSegments = (segments: readonly Segment[]): Segment[] => {\n const first = segments.filter(value => value.start._tag === 'Terminal')\n const last = segments.filter(value => value.end._tag === 'Terminal' && !first.includes(value))\n const middle = segments.filter(value => !first.includes(value) && !last.includes(value))\n return [...first, ...middle, ...last]\n}\n\n/** Visible edges, segment by segment. */\nexport const items = (connection: Connection): ReadonlyArray<Edge> =>\n connection.segments.flatMap(value => value.edges)\n\n/** There is more before the known region. Derived from boundaries, never row count. */\nexport const hasPrevious = (connection: Connection): boolean => {\n const first = connection.segments[0]\n return first !== undefined && first.start._tag !== 'Terminal'\n}\n\n/** There is more after the known region. Derived from boundaries, never row count. */\nexport const hasNext = (connection: Connection): boolean => {\n const last = connection.segments[connection.segments.length - 1]\n return last !== undefined && last.end._tag !== 'Terminal'\n}\n\n/** A connection with more than one segment has an explicit unknown gap. */\nexport const isGapped = (connection: Connection): boolean => connection.segments.length > 1\n","/** A serializable summary of a RemoteModel for DevTools and diagnostics. */\nimport type { RemoteModel } from './model.js'\nimport type { EntityEntry } from './store.js'\n\n/** A serializable summary of a RemoteModel for DevTools and diagnostics. */\nexport interface RemoteInspection {\n readonly entities: ReadonlyArray<{\n readonly key: string\n readonly present: ReadonlyArray<string>\n readonly stale: ReadonlyArray<string>\n readonly tombstone: boolean\n readonly updatedAt: number\n readonly windows: Readonly<Record<string, string>>\n }>\n readonly connections: ReadonlyArray<string>\n readonly live: ReadonlyArray<string>\n readonly gaps: ReadonlyArray<string>\n readonly mutations: {\n readonly pending: ReadonlyArray<string>\n readonly failed: ReadonlyArray<string>\n readonly applied: number\n }\n}\n\nconst inspectEntry = (key: string, entry: EntityEntry): RemoteInspection['entities'][number] => ({\n key,\n present: [...entry.present],\n stale: [...entry.stale],\n tombstone: entry.tombstone,\n updatedAt: entry.updatedAt,\n windows: { ...entry.windows },\n})\n\n/** A pure, serializable view of the whole cache. */\nexport const inspectRemote = (model: RemoteModel): RemoteInspection => ({\n entities: Object.entries(model.entities).map(([key, entry]) => inspectEntry(key, entry)),\n connections: Object.keys(model.connections),\n live: Object.keys(model.live),\n gaps: [...model.gaps],\n mutations: {\n pending: [...model.mutations.pending],\n failed: [...model.mutations.failed],\n applied: model.mutations.applied.size,\n },\n})\n\n/** A pure, serializable view of one entity, or `undefined` if unknown. */\nexport const inspectEntity = (\n model: RemoteModel,\n key: string,\n): RemoteInspection['entities'][number] | undefined => {\n const entry = model.entities[key]\n return entry === undefined ? undefined : inspectEntry(key, entry)\n}\n","/**\n * Optimistic layers. Pending changes are held as ordered layers over a base\n * store and as overlays over a connection; the visible value is recomputed, never\n * patched with inverses. Settling is remove-the-layer, so overlapping layers\n * rebase for free.\n */\nimport { type Connection, type Edge, edge, items } from './connection.js'\nimport { reconcileMutation, type MutationState, type NormalizedPatch } from './mutation.js'\nimport { entityKey, isTombstone, writeEntity, type EntityStore } from './store.js'\n\nexport interface EntityLayer {\n readonly id: string\n readonly patches: ReadonlyArray<NormalizedPatch>\n}\n\n/**\n * Edges placed outside a connection's server-known region (`prepend`,\n * `append`) or hidden from it (`remove`), owned by the request or live event\n * that produced them.\n */\nexport interface ConnectionOverlay {\n readonly id: string\n readonly connection: string\n readonly edges: ReadonlyArray<Edge>\n readonly position: 'prepend' | 'append' | 'remove'\n}\n\n/** A connection change a request makes optimistically or a mutation result confirms. */\nexport type ConnectionChange =\n | {\n readonly _tag: 'Insert'\n readonly connection: string\n readonly position: 'prepend' | 'append'\n readonly edge: Edge\n }\n | { readonly _tag: 'Remove'; readonly connection: string; readonly edge: Edge }\n\n/** What a request changes before the server answers: entity patches and connection changes. */\nexport type OptimisticOperation = NormalizedPatch | ConnectionChange\n\nconst isConnectionChange = (operation: OptimisticOperation): operation is ConnectionChange =>\n '_tag' in operation\n\nconst toOverlays = (id: string, changes: ReadonlyArray<ConnectionChange>): ConnectionOverlay[] =>\n changes.map(change => ({\n id,\n connection: change.connection,\n edges: [change.edge],\n position: change._tag === 'Insert' ? change.position : 'remove',\n }))\n\n/** A connection, by identity string or by anything that carries one (a `QueryRef`). */\nexport type ConnectionIdentity = string | { readonly identity: string }\n\nexport const connectionIdentity = (connection: ConnectionIdentity): string =>\n typeof connection === 'string' ? connection : connection.identity\n\nconst change = (\n connection: ConnectionIdentity,\n ref: { readonly entity: string; readonly id: string },\n position: 'prepend' | 'append' | 'remove',\n): ConnectionChange =>\n position === 'remove'\n ? { _tag: 'Remove', connection: connectionIdentity(connection), edge: edge(ref) }\n : { _tag: 'Insert', connection: connectionIdentity(connection), position, edge: edge(ref) }\n\n/**\n * Constructors for connection changes: what a request shows optimistically\n * (`MutateOptions.optimistic`) and what a mutation source reports it made\n * (`MutationOutcome.connections`).\n */\nexport const ConnectionChange = {\n /** Show `ref` at the front of the connection until the request settles. */\n prepend: (\n connection: ConnectionIdentity,\n ref: { readonly entity: string; readonly id: string },\n ): ConnectionChange => change(connection, ref, 'prepend'),\n\n /** Show `ref` at the end of the connection until the request settles. */\n append: (\n connection: ConnectionIdentity,\n ref: { readonly entity: string; readonly id: string },\n ): ConnectionChange => change(connection, ref, 'append'),\n\n /** Hide `ref` from the connection until the request settles. */\n remove: (\n connection: ConnectionIdentity,\n ref: { readonly entity: string; readonly id: string },\n ): ConnectionChange => change(connection, ref, 'remove'),\n}\n\n/**\n * Applies a request's operations: its patches become one layer and its\n * connection changes become overlays, all owned by `requestId` so settling\n * removes every one of them together.\n */\nexport const beginOptimistic = (\n optimistic: OptimisticState,\n requestId: string,\n operations: ReadonlyArray<OptimisticOperation>,\n): OptimisticState => {\n const patches = operations.filter(\n (operation): operation is NormalizedPatch => !isConnectionChange(operation),\n )\n const changes = operations.filter(isConnectionChange)\n return {\n layers:\n patches.length === 0 ? optimistic.layers : [...optimistic.layers, { id: requestId, patches }],\n overlays: [...optimistic.overlays, ...toOverlays(requestId, changes)],\n }\n}\n\n/**\n * Replaces a request's overlays with the server-confirmed changes, owned by\n * `id`, in the position the request's overlays held, so a confirmed edge keeps\n * its place among other pending inserts.\n */\nconst confirm = (\n optimistic: OptimisticState,\n requestId: string,\n id: string,\n changes: ReadonlyArray<ConnectionChange>,\n): OptimisticState => {\n const confirmed = toOverlays(id, changes)\n const at = optimistic.overlays.findIndex(overlay => overlay.id === requestId)\n const others = optimistic.overlays.filter(overlay => overlay.id !== requestId)\n return {\n ...optimistic,\n overlays:\n at === -1\n ? [...others, ...confirmed]\n : [...others.slice(0, at), ...confirmed, ...others.slice(at)],\n }\n}\n\n/** Pending entity layers and connection overlays over the base store. */\nexport interface OptimisticState {\n readonly layers: ReadonlyArray<EntityLayer>\n readonly overlays: ReadonlyArray<ConnectionOverlay>\n}\n\nexport const emptyOptimistic: OptimisticState = { layers: [], overlays: [] }\n\nexport const addLayer = (optimistic: OptimisticState, layer: EntityLayer): OptimisticState => ({\n ...optimistic,\n layers: [...optimistic.layers, layer],\n})\n\nexport const removeLayer = (optimistic: OptimisticState, id: string): OptimisticState => ({\n ...optimistic,\n layers: optimistic.layers.filter(layer => layer.id !== id),\n})\n\nexport const addOverlay = (\n optimistic: OptimisticState,\n overlay: ConnectionOverlay,\n): OptimisticState => ({\n ...optimistic,\n overlays: [...optimistic.overlays, overlay],\n})\n\nexport const removeOverlay = (optimistic: OptimisticState, id: string): OptimisticState => ({\n ...optimistic,\n overlays: optimistic.overlays.filter(overlay => overlay.id !== id),\n})\n\n/** Base store with every layer applied in order. Later layers win. */\nexport const visibleStore = (base: EntityStore, optimistic: OptimisticState): EntityStore =>\n optimistic.layers.reduce(\n (store, layer) =>\n layer.patches.reduce(\n (current, patch) => writeEntity(current, entityKey(patch.entity, patch.id), patch.values),\n store,\n ),\n base,\n )\n\n/**\n * A fresh page is newer than any settled overlay it covers: an edge the page\n * carries no longer needs an insert overlay, and a `remove` overlay hiding it\n * is stale (the server says it is back). A pending request's overlays are\n * left alone; they settle with the request.\n */\nexport const pruneOverlays = (\n optimistic: OptimisticState,\n connection: string,\n covered: ReadonlySet<string>,\n pending: ReadonlySet<string>,\n): OptimisticState => ({\n ...optimistic,\n overlays: optimistic.overlays.flatMap(overlay => {\n if (overlay.connection !== connection || pending.has(overlay.id)) return [overlay]\n const edges = overlay.edges.filter(edge => !covered.has(edge.key))\n return edges.length === 0 ? [] : [{ ...overlay, edges }]\n }),\n})\n\n/** Everything a request owns: its layer and its overlays. */\nconst release = (optimistic: OptimisticState, requestId: string): OptimisticState =>\n removeOverlay(removeLayer(optimistic, requestId), requestId)\n\n/**\n * Applies a result idempotently and releases the request's layer and overlays:\n * a later layer re-wins on rebase. Confirmed connection changes are recorded\n * once per request, as overlays the request no longer owns.\n */\nexport const settleSuccess = (\n base: EntityStore,\n optimistic: OptimisticState,\n state: MutationState,\n requestId: string,\n entities: ReadonlyArray<NormalizedPatch>,\n connections: ReadonlyArray<ConnectionChange> = [],\n): {\n readonly store: EntityStore\n readonly state: MutationState\n readonly optimistic: OptimisticState\n} => {\n const reconciled = reconcileMutation(base, state, requestId, entities)\n return {\n store: reconciled.store,\n state: reconciled.state,\n optimistic: state.applied.has(requestId)\n ? release(optimistic, requestId)\n : confirm(\n removeLayer(optimistic, requestId),\n requestId,\n `confirmed:${requestId}`,\n connections,\n ),\n }\n}\n\n/** A failed request's layer and overlays are dropped; the base was never mutated. */\nexport const settleFailure = (optimistic: OptimisticState, requestId: string): OptimisticState =>\n release(optimistic, requestId)\n\n/**\n * Visible edges for one connection: applicable overlays are placed outside the\n * server-known segments and de-duplicated by edge identity (across overlays too),\n * so a pending insert never corrupts server-known ordering; a `remove` overlay\n * hides its edges wherever they are, and so does a tombstone on the edge's\n * target when `store` is given. A later prepend lands before an earlier one, a\n * later append after, so pending inserts read in the order they were made.\n * Boundaries still come from the connection's segments.\n */\nexport const visibleItems = (\n connection: Connection,\n connectionId: string,\n overlays: ReadonlyArray<ConnectionOverlay>,\n store?: EntityStore,\n): ReadonlyArray<Edge> => {\n const applicable = overlays.filter(overlay => overlay.connection === connectionId)\n // Overlays are ordered evidence: the last word on an edge wins, so a remove\n // hides it only until a later insert brings it back.\n const hidden = new Set<string>()\n for (const overlay of applicable) {\n for (const edge of overlay.edges) {\n if (overlay.position === 'remove') hidden.add(edge.key)\n else hidden.delete(edge.key)\n }\n }\n const gone = (edge: Edge): boolean =>\n hidden.has(edge.key) ||\n (store !== undefined && isTombstone(store, entityKey(edge.ref.entity, edge.ref.id)))\n const known = items(connection).filter(edge => !gone(edge))\n const seen = new Set(known.map(edge => edge.key))\n\n const take = (position: 'prepend' | 'append'): ReadonlyArray<Edge> => {\n const edges: Edge[] = []\n const ordered = applicable.filter(value => value.position === position)\n for (const overlay of position === 'prepend' ? [...ordered].reverse() : ordered) {\n for (const edge of overlay.edges) {\n if (seen.has(edge.key) || gone(edge)) continue\n seen.add(edge.key)\n edges.push(edge)\n }\n }\n return edges\n }\n\n return [...take('prepend'), ...known, ...take('append')]\n}\n","/**\n * Live data. Entity facts update the store; connection facts change ordering and\n * membership. Events carry a monotonic cursor ordered **per stream**: duplicates\n * are ignored, and a gap is surfaced so the caller can resume or invalidate.\n * Subscriptions are selection-aware and driven by active Surfaces.\n */\nimport type { EdgeRef } from './connection.js'\nimport { type Connection, type Edge, hasNext, hasPrevious } from './connection.js'\nimport { addOverlay, type OptimisticState } from './optimistic.js'\nimport type { LiveInsertion, LivePolicy } from './query.js'\nimport { entityKey, tombstone, writeEntity, type EntityStore } from './store.js'\n\nexport type LiveCursor = number\n\nexport type LiveEvent =\n | {\n readonly _tag: 'EntityPatched'\n readonly ref: EdgeRef\n readonly values: Readonly<Record<string, unknown>>\n readonly changed: ReadonlyArray<string>\n readonly cursor: LiveCursor\n }\n | { readonly _tag: 'EntityDeleted'; readonly ref: EdgeRef; readonly cursor: LiveCursor }\n | {\n readonly _tag: 'ConnectionInsert'\n readonly connection: string\n readonly position: 'prepend' | 'append'\n readonly edge: Edge\n readonly cursor: LiveCursor\n }\n | {\n readonly _tag: 'ConnectionRemove'\n readonly connection: string\n readonly edge: Edge\n readonly cursor: LiveCursor\n }\n | {\n readonly _tag: 'ConnectionInvalidate'\n readonly connection: string\n readonly cursor: LiveCursor\n }\n\nexport interface BoundaryCounts {\n readonly before: number\n readonly after: number\n}\n\nexport interface LiveState {\n /** Last applied cursor for this stream. */\n readonly cursor: LiveCursor\n /** Connections marked stale by an invalidating event. */\n readonly stale: ReadonlySet<string>\n /** Edges recorded outside the loaded boundary, not visible in `items`. */\n readonly boundary: Readonly<Record<string, BoundaryCounts>>\n}\n\nexport const emptyLiveState: LiveState = { cursor: 0, stale: new Set(), boundary: {} }\n\nexport type LiveOutcome = 'applied' | 'duplicate' | 'gap'\n\n/**\n * Ordering per stream: at most the next cursor; ahead is a gap. Cursor `0` means\n * \"no baseline yet\" (cursors are 1-based), so the first event of a stream is\n * accepted whatever its cursor — otherwise a stream not starting at 1 would be a\n * spurious gap.\n */\nexport const classifyLive = (state: LiveState, cursor: LiveCursor): LiveOutcome =>\n cursor <= state.cursor\n ? 'duplicate'\n : state.cursor === 0 || cursor === state.cursor + 1\n ? 'applied'\n : 'gap'\n\nconst advance = (state: LiveState, cursor: LiveCursor): LiveState => ({ ...state, cursor })\n\nconst recordBoundary = (\n state: LiveState,\n connection: string,\n position: 'prepend' | 'append',\n): LiveState => {\n const current = state.boundary[connection] ?? { before: 0, after: 0 }\n const next =\n position === 'prepend'\n ? { ...current, before: current.before + 1 }\n : { ...current, after: current.after + 1 }\n return { ...state, boundary: { ...state.boundary, [connection]: next } }\n}\n\nexport const invalidateConnection = (state: LiveState, connection: string): LiveState => ({\n ...state,\n stale: new Set([...state.stale, connection]),\n})\n\n/**\n * A subscriber is woken only if the event changed a field it selects. A\n * change to an unselected field is skipped entirely.\n */\nexport const shouldWake = (\n changed: ReadonlyArray<string>,\n selected: ReadonlyArray<string>,\n): boolean => changed.some(field => selected.includes(field))\n\nexport interface EntityApplied {\n readonly state: LiveState\n readonly store: EntityStore\n readonly outcome: LiveOutcome\n}\n\nexport const applyEntityEvent = (\n state: LiveState,\n store: EntityStore,\n event: Extract<LiveEvent, { _tag: 'EntityPatched' | 'EntityDeleted' }>,\n now = 0,\n): EntityApplied => {\n const outcome = classifyLive(state, event.cursor)\n if (outcome !== 'applied') return { state, store, outcome }\n const key = entityKey(event.ref.entity, event.ref.id)\n const next =\n event._tag === 'EntityPatched'\n ? writeEntity(store, key, event.values, now)\n : tombstone(store, key)\n return { state: advance(state, event.cursor), store: next, outcome }\n}\n\nexport interface ConnectionApplied {\n readonly state: LiveState\n readonly optimistic: OptimisticState\n readonly outcome: LiveOutcome\n}\n\nconst removeEdgeOverlays = (\n optimistic: OptimisticState,\n connection: string,\n key: string,\n): OptimisticState => ({\n ...optimistic,\n overlays: optimistic.overlays.map(overlay =>\n overlay.connection !== connection || overlay.position === 'remove'\n ? overlay\n : { ...overlay, edges: overlay.edges.filter(edge => edge.key !== key) },\n ),\n})\n\nexport const applyConnectionEvent = (\n state: LiveState,\n optimistic: OptimisticState,\n event: Extract<\n LiveEvent,\n { _tag: 'ConnectionInsert' | 'ConnectionRemove' | 'ConnectionInvalidate' }\n >,\n policy: LivePolicy = {},\n): ConnectionApplied => {\n const outcome = classifyLive(state, event.cursor)\n if (outcome !== 'applied') return { state, optimistic, outcome }\n\n switch (event._tag) {\n case 'ConnectionInsert': {\n const selection: LiveInsertion =\n (event.position === 'prepend' ? policy.prepend : policy.append) ?? 'visible'\n switch (selection) {\n case 'visible':\n return {\n state: advance(state, event.cursor),\n optimistic: addOverlay(optimistic, {\n id: `live:${event.cursor}`,\n connection: event.connection,\n edges: [event.edge],\n position: event.position,\n }),\n outcome,\n }\n case 'boundary':\n return {\n state: recordBoundary(advance(state, event.cursor), event.connection, event.position),\n optimistic,\n outcome,\n }\n case 'invalidate':\n return {\n state: invalidateConnection(advance(state, event.cursor), event.connection),\n optimistic,\n outcome,\n }\n case 'ignore':\n return { state: advance(state, event.cursor), optimistic, outcome }\n }\n }\n case 'ConnectionRemove':\n // Strip the edge from pending inserts and hide it wherever else it is\n // (a server-known segment included) until a fresh page says otherwise.\n return {\n state: advance(state, event.cursor),\n optimistic: addOverlay(removeEdgeOverlays(optimistic, event.connection, event.edge.key), {\n id: `live:${event.cursor}`,\n connection: event.connection,\n edges: [event.edge],\n position: 'remove',\n }),\n outcome,\n }\n case 'ConnectionInvalidate':\n return {\n state: invalidateConnection(advance(state, event.cursor), event.connection),\n optimistic,\n outcome,\n }\n }\n}\n\nexport const isStale = (state: LiveState, connection: string): boolean =>\n state.stale.has(connection)\n\n/**\n * Clears a connection's stale mark once a fresh page has been adopted. An\n * invalidating event only records that a refetch is due; whoever merges the\n * refetched page calls this so `isStale` stops reporting.\n */\nexport const refreshConnection = (state: LiveState, connection: string): LiveState => {\n if (!state.stale.has(connection)) return state\n const stale = new Set(state.stale)\n stale.delete(connection)\n return { ...state, stale }\n}\n\n/** `hasPrevious` accounting for edges recorded outside the loaded boundary. */\nexport const liveHasPrevious = (\n connection: Connection,\n state: LiveState,\n connectionId: string,\n): boolean => hasPrevious(connection) || (state.boundary[connectionId]?.before ?? 0) > 0\n\n/** `hasNext` accounting for edges recorded outside the loaded boundary. */\nexport const liveHasNext = (\n connection: Connection,\n state: LiveState,\n connectionId: string,\n): boolean => hasNext(connection) || (state.boundary[connectionId]?.after ?? 0) > 0\n","/**\n * Relation values on the wire and in the store: a ref key (`\"Entity:id\"`), a\n * nullable ref key, an array of ref keys, or a page of ref keys. The planner\n * follows them into the store; the server follows them into the next read.\n */\nimport type { Schema } from 'effect'\nimport type { RelationRequirement } from 'foldkit-surface'\n\nexport interface RefParts {\n readonly entity: string\n readonly id: string\n}\n\n/** A page of refs as the wire and the store hold it. */\nexport interface RefPageValue {\n readonly refs: ReadonlyArray<string>\n readonly hasNext: boolean\n readonly hasPrevious: boolean\n}\n\n/** Marks the codec `Entity.ref`/`Entity.refPage` produce, so a Selection can tell the field's shape. */\nexport const RelationAnnotation = 'foldkitRemoteRelation'\n/** The target entity's name on the same codec, so a nested selection of another entity is refused. */\nexport const RelationEntityAnnotation = 'foldkitRemoteRelationEntity'\n\nexport type RelationKind = 'one' | 'many' | 'page'\n\nexport interface RelationShape {\n readonly kind: RelationKind\n readonly nullable: boolean\n readonly entity: string\n}\n\n/** Splits a ref key (`\"Entity:id\"`, the store key too) back into its parts. */\nexport const refParts = (encoded: string): RefParts => {\n const separator = encoded.indexOf(':')\n return separator === -1\n ? { entity: encoded, id: '' }\n : { entity: encoded.slice(0, separator), id: encoded.slice(separator + 1) }\n}\n\n/**\n * The refs a relation value carries, in order. Anything that is not a ref key,\n * an array of them, or a page of them contributes nothing.\n */\nexport const refsIn = (value: unknown): ReadonlyArray<RefParts> => {\n if (typeof value === 'string') return [refParts(value)]\n if (Array.isArray(value)) return value.filter(item => typeof item === 'string').map(refParts)\n if (value !== null && typeof value === 'object') {\n const refs = (value as { readonly refs?: unknown }).refs\n if (Array.isArray(refs)) return refs.filter(item => typeof item === 'string').map(refParts)\n }\n return []\n}\n\n/** The refs in a relation value that name the relation's target entity, and no other. */\nexport const targetsOf = (value: unknown, relation: RelationRequirement): ReadonlyArray<RefParts> =>\n refsIn(value).filter(ref => ref.entity === relation.entity)\n\nexport const isRefPage = (value: unknown): value is RefPageValue => {\n if (value === null || typeof value !== 'object') return false\n const page = value as Record<string, unknown>\n return (\n Array.isArray(page.refs) &&\n page.refs.every(ref => typeof ref === 'string') &&\n typeof page.hasNext === 'boolean' &&\n typeof page.hasPrevious === 'boolean'\n )\n}\n\ninterface AstLike {\n readonly _tag: string\n readonly annotations?: Readonly<Record<string, unknown>> | undefined\n readonly types?: ReadonlyArray<AstLike> | undefined\n readonly rest?: ReadonlyArray<AstLike> | undefined\n}\n\n/**\n * The relation shape an entity field schema declares: a ref (`one`), a nullable\n * ref, an array of refs (`many`), or a page of refs (`page`). `undefined` for a\n * scalar field, which cannot take a nested selection.\n */\nexport const relationShape = (schema: Schema.Top): RelationShape | undefined =>\n shapeOf(schema.ast as unknown as AstLike, false)\n\nconst shapeOf = (ast: AstLike, nullable: boolean): RelationShape | undefined => {\n const annotated = ast.annotations?.[RelationAnnotation]\n if (annotated === 'one' || annotated === 'page') {\n return {\n kind: annotated,\n nullable,\n entity: String(ast.annotations?.[RelationEntityAnnotation]),\n }\n }\n if (ast._tag === 'Arrays') {\n const item = ast.rest?.[0]\n const inner = item === undefined ? undefined : shapeOf(item, false)\n return inner?.kind === 'one' ? { kind: 'many', nullable, entity: inner.entity } : undefined\n }\n if (ast._tag === 'Union') {\n const members = ast.types ?? []\n const optional = members.some(member => member._tag === 'Null' || member._tag === 'Undefined')\n for (const member of members) {\n const shape = shapeOf(member, optional)\n if (shape !== undefined) return shape\n }\n }\n return undefined\n}\n","/**\n * The pure requirement planner.\n *\n * A `Requirement` is plain data: which entity fields a Remote projection needs,\n * and through `relations`, which fields of each relation's target. `plan` diffs\n * requirements against the store and returns only the missing fields, grouped\n * and deterministically ordered. A relation whose field is being fetched keeps\n * its nested requirement on the request, so the server resolves the graph in\n * one read; a relation whose refs the store already holds is followed into\n * concrete requirements for the targets. Time enters through `PlanFreshness`,\n * never from ambient state; `force` plans every field.\n */\nimport { Requirement, type RelationRequirement } from 'foldkit-surface'\nimport { stableStringify } from './query.js'\nimport { targetsOf } from './relation.js'\nimport { entityKey, missingFields, readField, type EntityStore } from './store.js'\n\nexport type { RelationRequirement, Requirement } from 'foldkit-surface'\n\ntype Window = NonNullable<Requirement['windows']>[string]\n\n/** A stable key for a window, so two equal windows compare equal. */\nexport const windowKey = (window: Window): string => stableStringify(window)\n\nexport interface PlanFreshness {\n readonly now: number\n /** A present entry older than this many milliseconds is refreshed whole. */\n readonly freshness: number\n}\n\nexport interface PlanOptions {\n readonly freshness?: PlanFreshness | undefined\n /** Plan every requested field, present or not, tombstoned or not. */\n readonly force?: boolean | undefined\n}\n\nconst pickFields = <T>(\n record: Readonly<Record<string, T>> | undefined,\n fields: ReadonlySet<string>,\n): Readonly<Record<string, T>> | undefined => {\n if (record === undefined) return undefined\n const picked = Object.fromEntries(Object.entries(record).filter(([field]) => fields.has(field)))\n return Object.keys(picked).length === 0 ? undefined : picked\n}\n\n/** The concrete requirements a known relation value contributes for its targets. */\nconst followRelation = (\n value: unknown,\n relation: RelationRequirement,\n): ReadonlyArray<Requirement> =>\n targetsOf(value, relation).map(ref => ({ ...relation, id: ref.id }))\n\nexport const plan = (\n store: EntityStore,\n requirements: readonly Requirement[],\n options: PlanOptions = {},\n): ReadonlyArray<Requirement> => {\n const { freshness, force = false } = options\n const planned: Requirement[] = []\n const followed: Requirement[] = []\n\n for (const group of Requirement.merge(requirements)) {\n const key = entityKey(group.entity, group.id)\n const entry = store[key]\n const expired =\n freshness !== undefined &&\n entry !== undefined &&\n !entry.tombstone &&\n freshness.now - entry.updatedAt > freshness.freshness\n const windowKeys = Object.fromEntries(\n Object.entries(group.windows ?? {}).map(([field, window]) => [field, windowKey(window)]),\n )\n const missing =\n force || expired ? group.fields : missingFields(store, key, group.fields, windowKeys)\n const missingSet = new Set(missing)\n\n // A relation the store already holds is followed into its targets; one\n // being fetched rides on the request instead.\n for (const [field, relation] of Object.entries(group.relations ?? {})) {\n if (missingSet.has(field)) continue\n const value = readField(store, key, field)\n if (value._tag === 'Some') followed.push(...followRelation(value.value, relation))\n }\n\n if (missing.length === 0) continue\n // Only a field being fetched carries its window and its relation.\n const windows = pickFields(group.windows, missingSet)\n const relations = pickFields(group.relations, missingSet)\n planned.push({\n entity: group.entity,\n id: group.id,\n fields: missing,\n ...(windows === undefined ? {} : { windows }),\n ...(relations === undefined ? {} : { relations }),\n })\n }\n\n const nested = followed.length === 0 ? [] : plan(store, followed, options)\n return [...Requirement.merge([...planned, ...nested])].sort((a, b) =>\n entityKey(a.entity, a.id) < entityKey(b.entity, b.id) ? -1 : 1,\n )\n}\n","/**\n * Cache lifetime. Retention roots are the requirements (and connections) the\n * application's active Surfaces observe; `gc` keeps what they reach through\n * the store's refs plus every pending optimistic change, and drops the rest.\n * Roots live outside the Model, so GC arrives as a Message.\n */\nimport type { RelationRequirement, Requirement } from 'foldkit-surface'\nimport { refsIn } from './relation.js'\nimport { entityKey, readField, type EntityKey, type EntityStore } from './store.js'\nimport type { Connection } from './connection.js'\nimport type { OptimisticState } from './optimistic.js'\nimport type { MutationState } from './mutation.js'\n\n/** A connection to keep: its identity, and what a page of it selects of each item, if a projection reads it. */\nexport interface ConnectionRoot {\n readonly identity: string\n readonly select?: RelationRequirement | undefined\n}\n\nexport interface RetentionRoots {\n readonly requirements: ReadonlyArray<Requirement>\n /** Connections (`QueryRef.identity`) to keep, with their edges' targets and what `select` reaches through them. */\n readonly connections: ReadonlyArray<ConnectionRoot>\n}\n\nexport interface Retained {\n readonly entities: EntityStore\n readonly connections: Readonly<Record<string, Connection>>\n readonly optimistic: OptimisticState\n}\n\n/**\n * The entity keys the roots reach: each root entity, the targets its retained\n * fields refer to, and recursively the targets a nested relation selects.\n */\nexport const reachable = (\n store: EntityStore,\n roots: RetentionRoots,\n connections: Readonly<Record<string, Connection>>,\n optimistic: OptimisticState,\n pending: ReadonlySet<string>,\n): ReadonlySet<EntityKey> => {\n const kept = new Set<EntityKey>()\n const rootConnections = new Set(roots.connections.map(root => root.identity))\n // A target is walked once per relation spec that reaches it: two specs may\n // select different nested relations of the same entity, and a spec tree is\n // finite, so this terminates on cyclic data too.\n const walked = new Map<EntityKey, Set<Omit<Requirement, 'id'>>>()\n const visit = (key: EntityKey, requirement: Omit<Requirement, 'id'>): void => {\n kept.add(key)\n const seen = walked.get(key) ?? new Set()\n if (seen.has(requirement)) return\n seen.add(requirement)\n walked.set(key, seen)\n for (const field of requirement.fields) {\n const value = readField(store, key, field)\n if (value._tag === 'None') continue\n const relation = requirement.relations?.[field]\n for (const ref of refsIn(value.value)) {\n const target = entityKey(ref.entity, ref.id)\n if (relation === undefined || ref.entity !== relation.entity) {\n kept.add(target)\n continue\n }\n visit(target, relation)\n }\n }\n }\n for (const root of roots.requirements) visit(entityKey(root.entity, root.id), root)\n // A connection root keeps its edges' targets, and what a page's `select`\n // reaches through them (an item's owner, say), so the page stays readable.\n for (const { identity, select } of roots.connections) {\n for (const segment of connections[identity]?.segments ?? []) {\n for (const edge of segment.edges) {\n const target = entityKey(edge.ref.entity, edge.ref.id)\n if (select === undefined || edge.ref.entity !== select.entity) kept.add(target)\n else visit(target, select)\n }\n }\n }\n // A pending request's changes are kept whole; a settled overlay (a live or\n // confirmed insert) is kept only with a retained connection, below.\n for (const layer of optimistic.layers) {\n if (!pending.has(layer.id)) continue\n for (const patch of layer.patches) kept.add(entityKey(patch.entity, patch.id))\n }\n for (const overlay of optimistic.overlays) {\n if (!pending.has(overlay.id) && !rootConnections.has(overlay.connection)) continue\n for (const edge of overlay.edges) kept.add(entityKey(edge.ref.entity, edge.ref.id))\n }\n return kept\n}\n\n/**\n * Drops every entity the roots do not reach, every connection they do not\n * name, and every settled overlay on a dropped connection, keeping whatever a\n * pending request's layer or overlays touch. Pure.\n */\nexport const gc = (\n state: Retained & { readonly mutations: MutationState },\n roots: RetentionRoots,\n): Retained => {\n const pending = state.mutations.pending\n const kept = reachable(state.entities, roots, state.connections, state.optimistic, pending)\n const entities = Object.fromEntries(\n Object.entries(state.entities).filter(([key]) => kept.has(key)),\n )\n const keptConnections = new Set([\n ...roots.connections.map(root => root.identity),\n ...state.optimistic.overlays\n .filter(overlay => pending.has(overlay.id))\n .map(overlay => overlay.connection),\n ])\n const connections = Object.fromEntries(\n Object.entries(state.connections).filter(([identity]) => keptConnections.has(identity)),\n )\n const optimistic: OptimisticState = {\n layers: state.optimistic.layers,\n overlays: state.optimistic.overlays.filter(\n overlay => pending.has(overlay.id) || keptConnections.has(overlay.connection),\n ),\n }\n return { entities, connections, optimistic }\n}\n","/**\n * Remote cache persistence: a snapshot of the entity store and nothing else.\n * Runtime state (connections' live cursors, optimistic layers, the mutation\n * ledger, gaps, retention roots) is never in a snapshot; it belongs to the\n * session that produced it.\n *\n * The cache is server-derived and disposable: an incompatible, oversized, or\n * corrupt snapshot is discarded (and removed from a `KeyValueStore`) so the\n * planner refetches. `dehydrate`/`hydrate` are the string forms, for SSR and\n * any other transport; `save`/`restore` put them behind Effect's\n * `KeyValueStore`, so the backend (memory, filesystem, SQL, Web Storage) is the\n * application's choice.\n */\nimport { Effect } from 'effect'\nimport { KeyValueStore } from 'effect/unstable/persistence'\nimport { stableStringify } from './query.js'\nimport { emptyStore, type EntityEntry, type EntityStore } from './store.js'\n\n/** Bump when the serialized shape changes; a mismatch discards the cache. */\nexport const REMOTE_CACHE_VERSION = 3\n\nexport interface SnapshotOptions {\n /**\n * Who or what the snapshot is for (a user id, a tenant, a build). A snapshot\n * taken under another scope is discarded rather than shown to the wrong\n * reader. Default: unscoped, which only matches unscoped.\n */\n readonly scope?: string | undefined\n /** Snapshots larger than this many bytes are not written and not read. */\n readonly maxBytes?: number | undefined\n}\n\n/** How a snapshot meets a store that already has entries. */\nexport type MergePolicy = 'replace' | 'preserve-existing'\n\ninterface SerializedEntry {\n readonly values: Readonly<Record<string, unknown>>\n readonly present: ReadonlyArray<string>\n readonly stale: ReadonlyArray<string>\n readonly tombstone: boolean\n readonly updatedAt: number\n readonly windows: Readonly<Record<string, string>>\n}\n\ninterface SerializedStore {\n readonly version: number\n readonly scope: string | null\n readonly entities: Readonly<Record<string, SerializedEntry>>\n}\n\nconst sorted = <T>(values: Iterable<T>): T[] => [...values].sort()\n\n/**\n * The snapshot's data shape. `stableStringify` sorts object keys, and the\n * field sets are sorted here, so equal stores give byte-equal snapshots\n * whatever order they were built in.\n */\nconst serializeStore = (store: EntityStore, scope?: string): SerializedStore => ({\n version: REMOTE_CACHE_VERSION,\n scope: scope ?? null,\n entities: Object.fromEntries(\n Object.entries(store).map(([key, entry]) => [\n key,\n {\n values: entry.values,\n present: sorted(entry.present),\n stale: sorted(entry.stale),\n tombstone: entry.tombstone,\n updatedAt: entry.updatedAt,\n windows: entry.windows,\n },\n ]),\n ),\n})\n\nconst isStringArray = (value: unknown): value is ReadonlyArray<string> =>\n Array.isArray(value) && value.every(item => typeof item === 'string')\n\nconst isStringRecord = (value: unknown): value is Readonly<Record<string, string>> =>\n value !== null &&\n typeof value === 'object' &&\n !Array.isArray(value) &&\n Object.values(value as Record<string, unknown>).every(item => typeof item === 'string')\n\n/** Throws on a malformed entry so the whole snapshot is discarded. */\nconst parseEntry = (value: unknown): EntityEntry => {\n if (value === null || typeof value !== 'object') throw new Error('entry is not an object')\n const entry = value as Record<string, unknown>\n if (entry.values === null || typeof entry.values !== 'object' || Array.isArray(entry.values)) {\n throw new Error('entry.values is not a record')\n }\n if (!isStringArray(entry.present)) throw new Error('entry.present is not a string array')\n if (!isStringArray(entry.stale)) throw new Error('entry.stale is not a string array')\n if (typeof entry.tombstone !== 'boolean') throw new Error('entry.tombstone is not a boolean')\n if (typeof entry.updatedAt !== 'number') throw new Error('entry.updatedAt is not a number')\n if (!isStringRecord(entry.windows)) throw new Error('entry.windows is not a string record')\n return {\n values: entry.values as Readonly<Record<string, unknown>>,\n present: new Set(entry.present),\n stale: new Set(entry.stale),\n tombstone: entry.tombstone,\n updatedAt: entry.updatedAt,\n windows: entry.windows,\n }\n}\n\nconst deserializeStore = (serialized: SerializedStore): EntityStore =>\n Object.fromEntries(\n Object.entries(serialized.entities).map(([key, entry]) => [key, parseEntry(entry)]),\n )\n\n/**\n * The snapshot text, or `undefined` when it would exceed `maxBytes`. Only the\n * entity store goes in; pass `model.entities`, never the whole `RemoteModel`.\n */\nconst dehydrate = (store: EntityStore, options: SnapshotOptions = {}): string | undefined => {\n const text = stableStringify(serializeStore(store, options.scope))\n return exceeds(text, options.maxBytes) ? undefined : text\n}\n\n/**\n * Whether the UTF-8 size of `text` exceeds `maxBytes`. A character is one to\n * three bytes, so most texts are decided from their length alone; only the\n * rest are measured.\n */\nconst exceeds = (text: string, maxBytes: number | undefined): boolean => {\n if (maxBytes === undefined) return false\n if (text.length > maxBytes) return true\n if (text.length * 3 <= maxBytes) return false\n return new TextEncoder().encode(text).length > maxBytes\n}\n\n/**\n * The store a snapshot text holds, or `undefined` when the text is missing,\n * oversized, not this version, for another scope, or malformed. Hydrating the\n * same text twice yields equal stores.\n */\nconst hydrate = (\n raw: string | undefined | null,\n options: SnapshotOptions = {},\n): EntityStore | undefined => {\n if (raw === undefined || raw === null) return undefined\n if (exceeds(raw, options.maxBytes)) return undefined\n let parsed: unknown\n try {\n parsed = JSON.parse(raw)\n } catch {\n return undefined\n }\n if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) return undefined\n const candidate = parsed as {\n readonly version?: unknown\n readonly scope?: unknown\n readonly entities?: unknown\n }\n if (candidate.version !== REMOTE_CACHE_VERSION) return undefined\n if ((candidate.scope ?? null) !== (options.scope ?? null)) return undefined\n if (candidate.entities === null || typeof candidate.entities !== 'object') return undefined\n if (Array.isArray(candidate.entities)) return undefined\n try {\n return deserializeStore(candidate as SerializedStore)\n } catch {\n return undefined\n }\n}\n\n/**\n * Brings a snapshot into a store that may already hold entries. `replace`\n * takes the snapshot's entry for every key it has; `preserve-existing` keeps\n * an entry the current store already has (it is at least as fresh as a\n * snapshot taken earlier). Either way, keys only the current store has stay.\n */\nconst mergeStores = (\n current: EntityStore,\n snapshot: EntityStore,\n policy: MergePolicy,\n): EntityStore => (policy === 'replace' ? { ...current, ...snapshot } : { ...snapshot, ...current })\n\nexport const RemotePersistence = {\n /** The snapshot text, or `undefined` when it would exceed `maxBytes`. */\n dehydrate,\n /** The store a snapshot text holds, or `undefined` when it is refused. */\n hydrate,\n /** A snapshot brought into a store by policy. */\n mergeStores,\n\n /**\n * Writes the snapshot under `key`, or removes the key when the store would\n * exceed `maxBytes`, so a stale smaller snapshot cannot outlive a larger\n * store it no longer describes.\n */\n save: (store: EntityStore, options: { readonly key: string } & SnapshotOptions) =>\n Effect.gen(function* () {\n const kv = yield* KeyValueStore.KeyValueStore\n const text = dehydrate(store, options)\n if (text === undefined) yield* kv.remove(options.key)\n else yield* kv.set(options.key, text)\n }),\n\n /**\n * Reads the cache. A missing key yields `emptyStore`; anything `hydrate`\n * refuses yields `emptyStore` and removes the key, so the next `restore` is\n * clean and the planner refetches.\n */\n restore: (options: { readonly key: string } & SnapshotOptions) =>\n Effect.gen(function* () {\n const kv = yield* KeyValueStore.KeyValueStore\n const raw = yield* kv.get(options.key)\n if (raw === undefined) return emptyStore\n const restored = hydrate(raw, options)\n if (restored === undefined) {\n yield* kv.remove(options.key)\n return emptyStore\n }\n return restored\n }),\n}\n","/** `RemoteData`: the state of a value the store may not hold yet. */\nimport { Option, Schema } from 'effect'\n\nexport interface RemoteError {\n readonly _tag: string\n readonly message: string\n}\n\nexport type RemoteData<A> =\n | { readonly _tag: 'Initial' }\n | { readonly _tag: 'Loading' }\n | { readonly _tag: 'Ready'; readonly value: A }\n | { readonly _tag: 'Refreshing'; readonly value: A }\n | { readonly _tag: 'Failed'; readonly error: RemoteError; readonly previous?: A }\n | { readonly _tag: 'NotFound' }\n\nexport const remoteErrorSchema = Schema.Struct({ _tag: Schema.String, message: Schema.String })\n\n/** A `RemoteData` schema, so a projection that reads remote state is typed. */\n// A projection is rebuilt on every Model change (a Surface's `model` callback\n// runs per dependency computation), so the schema for a value schema is built\n// once and shared: the value schema is a module-level constant in practice.\nconst remoteDataSchemas = new WeakMap<object, Schema.Schema<unknown>>()\n\nexport const remoteDataSchema = <A>(value: Schema.Schema<A>): Schema.Schema<RemoteData<A>> => {\n const cached = remoteDataSchemas.get(value)\n if (cached !== undefined) return cached as Schema.Schema<RemoteData<A>>\n const built = Schema.Union([\n Schema.Struct({ _tag: Schema.Literal('Initial') }),\n Schema.Struct({ _tag: Schema.Literal('Loading') }),\n Schema.Struct({ _tag: Schema.Literal('Ready'), value }),\n Schema.Struct({ _tag: Schema.Literal('Refreshing'), value }),\n Schema.Struct({\n _tag: Schema.Literal('Failed'),\n error: remoteErrorSchema,\n previous: Schema.optional(value),\n }),\n Schema.Struct({ _tag: Schema.Literal('NotFound') }),\n ]) as unknown as Schema.Schema<RemoteData<A>>\n remoteDataSchemas.set(value, built as Schema.Schema<unknown>)\n return built\n}\n\nexport const RemoteData = {\n /**\n * The `RemoteData` schema for a value schema. Exposed so a `RemoteData` can\n * be embedded in a hand-written Model schema, not only through `Remote.select`.\n */\n schema: <A>(value: Schema.Schema<A>): Schema.Schema<RemoteData<A>> => remoteDataSchema(value),\n\n /** Exhaustive: omitting a state is a compile error. */\n match: <A, R>(\n data: RemoteData<A>,\n cases: {\n readonly Initial: () => R\n readonly Loading: () => R\n readonly Ready: (value: A) => R\n readonly Refreshing: (value: A) => R\n readonly Failed: (error: RemoteError, previous: Option.Option<A>) => R\n readonly NotFound: () => R\n },\n ): R => {\n switch (data._tag) {\n case 'Initial':\n return cases.Initial()\n case 'Loading':\n return cases.Loading()\n case 'Ready':\n return cases.Ready(data.value)\n case 'Refreshing':\n return cases.Refreshing(data.value)\n case 'Failed':\n return cases.Failed(\n data.error,\n data.previous === undefined ? Option.none() : Option.some(data.previous),\n )\n case 'NotFound':\n return cases.NotFound()\n }\n },\n\n map: <A, B>(data: RemoteData<A>, f: (value: A) => B): RemoteData<B> => {\n switch (data._tag) {\n case 'Ready':\n return { _tag: 'Ready', value: f(data.value) }\n case 'Refreshing':\n return { _tag: 'Refreshing', value: f(data.value) }\n case 'Failed':\n return data.previous === undefined\n ? { _tag: 'Failed', error: data.error }\n : { _tag: 'Failed', error: data.error, previous: f(data.previous) }\n default:\n return data\n }\n },\n}\n","/**\n * The Remote submodel: the store, connections, mutations, live state, and\n * optimistic layers an application keeps in its Model, the Messages that\n * change it, and the pure reducer over them.\n */\nimport { Schema } from 'effect'\nimport type { Requirement } from 'foldkit-surface'\nimport { emptyConnection, merge, type Connection, type Segment } from './connection.js'\nimport {\n beginOptimistic,\n emptyOptimistic,\n pruneOverlays,\n settleFailure,\n settleSuccess,\n type ConnectionChange,\n type OptimisticState,\n type OptimisticOperation,\n} from './optimistic.js'\nimport {\n applyConnectionEvent,\n applyEntityEvent,\n emptyLiveState,\n type LiveEvent,\n type LiveState,\n} from './live.js'\nimport {\n beginMutation,\n emptyMutationState,\n failMutation,\n type MutationState,\n type NormalizedPatch,\n} from './mutation.js'\nimport {\n entityKey,\n emptyStore,\n setStale,\n writeEntities,\n type EntityStore,\n type EntityWrite,\n} from './store.js'\nimport { windowKey } from './plan.js'\nimport { isRefPage, targetsOf, type RefPageValue } from './relation.js'\nimport { gc, type RetentionRoots } from './retain.js'\nimport { RemotePersistence, type MergePolicy } from './persistence.js'\nimport { NormalizedEntity, ReadBatchResult, ReadRequest, RelationRequest } from './wire.js'\nimport { remoteErrorSchema, type RemoteError } from './remoteData.js'\nimport type { LivePolicy } from './query.js'\n\n/**\n * The normalized cache as a Foldkit Submodel. `Remote.make` returns a schema and\n * an `update` for this shape; `Remote.update` reconciles every producer.\n */\nexport interface RemoteModel {\n /** Entity values, presence, staleness, tombstones, and applied windows. */\n readonly entities: EntityStore\n /** Normalized ordered connections, keyed by connection identity. */\n readonly connections: Readonly<Record<string, Connection>>\n /** Optimistic entity layers and connection overlays over the base store. */\n readonly optimistic: OptimisticState\n /** Live cursor and boundary state, keyed by the subscription's stream key. */\n readonly live: Readonly<Record<string, LiveState>>\n /** Mutation pending/applied/failed ledger. */\n readonly mutations: MutationState\n /** Streams whose live cursor fell behind; the caller should resync or refetch. */\n readonly gaps: ReadonlySet<string>\n}\n\nexport const initialRemoteModel: RemoteModel = {\n entities: emptyStore,\n connections: {},\n optimistic: emptyOptimistic,\n live: {},\n mutations: emptyMutationState,\n gaps: new Set(),\n}\n\n/** The entity store and the mutation ledger are runtime values, not wire shapes. */\nconst runtimeSchema = Schema.Unknown\n\nexport const remoteModelSchema = (): Schema.Schema<RemoteModel> =>\n Schema.Struct({\n entities: runtimeSchema,\n connections: Schema.Record(Schema.String, runtimeSchema),\n optimistic: runtimeSchema,\n live: Schema.Record(Schema.String, runtimeSchema),\n mutations: runtimeSchema,\n gaps: runtimeSchema,\n }) as unknown as Schema.Schema<RemoteModel>\n\n/** The submodel's Messages; each reduces to `RemoteModel` through `Remote.update`. */\nexport type RemoteMessage =\n | {\n readonly _tag: 'ReadReceived'\n readonly requests: readonly Requirement[]\n readonly result: Schema.Schema.Type<typeof ReadBatchResult>\n readonly now: number\n }\n | {\n readonly _tag: 'ReadFailed'\n readonly requests: readonly Requirement[]\n readonly error: RemoteError\n }\n /** A refetch of present fields began; they read as `Refreshing` until it lands. */\n | { readonly _tag: 'RefreshStarted'; readonly requests: readonly Requirement[] }\n /** The active Surfaces' roots changed; everything they do not reach is collected. */\n | { readonly _tag: 'RetentionChanged'; readonly roots: RetentionRoots }\n /** A restored snapshot meets the store; runtime state is untouched. */\n | { readonly _tag: 'Hydrated'; readonly entities: EntityStore; readonly merge: MergePolicy }\n /** A mutation began; its optimistic operations show until it settles. */\n | {\n readonly _tag: 'MutationStarted'\n readonly requestId: string\n readonly optimistic?: ReadonlyArray<OptimisticOperation> | undefined\n }\n | {\n readonly _tag: 'MutationSucceeded'\n readonly requestId: string\n readonly entities: readonly NormalizedPatch[]\n /** Connection changes the server confirmed; they replace the request's own. */\n readonly connections?: ReadonlyArray<ConnectionChange> | undefined\n }\n | { readonly _tag: 'MutationFailed'; readonly requestId: string; readonly error: RemoteError }\n | {\n readonly _tag: 'LiveReceived'\n readonly stream: string\n readonly event: LiveEvent\n readonly policy?: LivePolicy\n readonly now: number\n }\n | { readonly _tag: 'GapCleared'; readonly stream: string }\n | {\n readonly _tag: 'ConnectionMerged'\n readonly connection: string\n readonly page: Segment\n /** The page answers the connection's refresh, so the merge also clears `stale`. */\n readonly refreshes?: boolean | undefined\n }\n | { readonly _tag: 'ConnectionInvalidated'; readonly connection: string }\n | { readonly _tag: 'ConnectionRefreshed'; readonly connection: string }\n /** A query for the connection failed; it reads as it did before the request. */\n | { readonly _tag: 'QueryFailed'; readonly connection: string; readonly error: RemoteError }\n\nexport const retentionRootsSchema = Schema.Struct({\n requirements: Schema.Array(ReadRequest),\n connections: Schema.Array(\n Schema.Struct({ identity: Schema.String, select: Schema.optional(RelationRequest) }),\n ),\n})\n\n/**\n * The Messages' fields by tag, without `_tag`: what `defineMessageUnion` takes,\n * so an application spreads them into its own union (`Remote.messages`).\n */\nexport const remoteMessageCases = {\n ReadReceived: {\n requests: Schema.Array(ReadRequest),\n result: ReadBatchResult,\n now: Schema.Number,\n },\n ReadFailed: { requests: Schema.Array(ReadRequest), error: remoteErrorSchema },\n RefreshStarted: { requests: Schema.Array(ReadRequest) },\n RetentionChanged: { roots: retentionRootsSchema },\n Hydrated: {\n entities: runtimeSchema,\n merge: Schema.Union([Schema.Literal('replace'), Schema.Literal('preserve-existing')]),\n },\n MutationStarted: {\n requestId: Schema.String,\n optimistic: Schema.optional(Schema.Array(Schema.Unknown)),\n },\n MutationSucceeded: {\n requestId: Schema.String,\n entities: Schema.Array(NormalizedEntity),\n connections: Schema.optional(Schema.Array(Schema.Unknown)),\n },\n MutationFailed: { requestId: Schema.String, error: remoteErrorSchema },\n LiveReceived: {\n stream: Schema.String,\n event: Schema.Unknown,\n policy: Schema.optional(Schema.Unknown),\n now: Schema.Number,\n },\n GapCleared: { stream: Schema.String },\n ConnectionMerged: {\n connection: Schema.String,\n page: Schema.Unknown,\n refreshes: Schema.optional(Schema.Boolean),\n },\n ConnectionInvalidated: { connection: Schema.String },\n ConnectionRefreshed: { connection: Schema.String },\n QueryFailed: { connection: Schema.String, error: remoteErrorSchema },\n} satisfies Record<RemoteMessage['_tag'], Schema.Struct.Fields>\n\nexport type RemoteMessageTag = RemoteMessage['_tag']\n\n/**\n * A Remote Message as an application's union constructs it from\n * `remoteMessageCases`: the same shape `RemoteMessage` names, with the runtime\n * slots (`entities`, `event`, `page`) typed `unknown` by their schemas.\n */\nexport type RemoteMessageInput = {\n [Tag in RemoteMessageTag]: { readonly _tag: Tag } & Schema.Struct.Type<\n (typeof remoteMessageCases)[Tag]\n >\n}[RemoteMessageTag]\n\n/**\n * Whether a Message is one of Remote's, by tag. Narrows an application's union\n * to its Remote cases, and its complement to the application's own.\n */\nexport const isRemoteMessage = <M extends { readonly _tag: string }>(\n message: M,\n): message is Extract<M, { readonly _tag: RemoteMessageTag }> =>\n Object.hasOwn(remoteMessageCases, message._tag)\n\nexport const remoteMessageSchema = Schema.Union(\n Object.entries(remoteMessageCases).map(([tag, fields]) =>\n Schema.Struct({ _tag: Schema.Literal(tag), ...fields }),\n ),\n) as unknown as Schema.Schema<RemoteMessage>\n\nconst marksOf = (\n requests: ReadonlyArray<Requirement>,\n): ReadonlyArray<readonly [string, ReadonlyArray<string>]> =>\n requests.map(request => [entityKey(request.entity, request.id), request.fields] as const)\n\nconst setConnectionStale = (\n connections: Readonly<Record<string, Connection>>,\n connection: string,\n stale: boolean,\n): Readonly<Record<string, Connection>> => {\n const current = connections[connection] ?? emptyConnection\n return { ...connections, [connection]: { ...current, stale } }\n}\n\nconst markGap = (model: RemoteModel, stream: string): RemoteModel =>\n model.gaps.has(stream) ? model : { ...model, gaps: new Set([...model.gaps, stream]) }\n\nconst clearGap = (model: RemoteModel, stream: string): RemoteModel =>\n model.gaps.has(stream)\n ? { ...model, gaps: new Set([...model.gaps].filter(entry => entry !== stream)) }\n : model\n\n/**\n * The pure reducer all four producers share. A live event that arrives ahead of\n * its cursor is a gap: it is not applied, and the stream is recorded so the host\n * can resubscribe rather than silently miss facts.\n */\nexport const updateRemote = (model: RemoteModel, message: RemoteMessage): RemoteModel => {\n switch (message._tag) {\n case 'ReadReceived':\n return {\n ...model,\n entities: writeRead(model.entities, message.requests, message.result, message.now),\n }\n case 'ReadFailed':\n // The refresh is over; the fields read as they did before it started.\n return { ...model, entities: setStale(model.entities, marksOf(message.requests), false) }\n case 'RetentionChanged':\n return { ...model, ...gc(model, message.roots) }\n case 'Hydrated':\n return {\n ...model,\n entities: RemotePersistence.mergeStores(model.entities, message.entities, message.merge),\n }\n case 'RefreshStarted':\n return { ...model, entities: setStale(model.entities, marksOf(message.requests), true) }\n case 'MutationStarted':\n return {\n ...model,\n mutations: beginMutation(model.mutations, message.requestId),\n optimistic: beginOptimistic(model.optimistic, message.requestId, message.optimistic ?? []),\n }\n case 'MutationSucceeded': {\n // Settling is release-the-layer-and-overlays, so overlapping optimistic\n // layers rebase instead of needing inverse patches.\n const settled = settleSuccess(\n model.entities,\n model.optimistic,\n model.mutations,\n message.requestId,\n message.entities,\n message.connections ?? [],\n )\n return {\n ...model,\n entities: settled.store,\n mutations: settled.state,\n optimistic: settled.optimistic,\n }\n }\n case 'MutationFailed':\n return {\n ...model,\n mutations: failMutation(model.mutations, message.requestId),\n optimistic: settleFailure(model.optimistic, message.requestId),\n }\n case 'LiveReceived': {\n const state = model.live[message.stream] ?? emptyLiveState\n if (message.event._tag === 'EntityPatched' || message.event._tag === 'EntityDeleted') {\n const applied = applyEntityEvent(state, model.entities, message.event, message.now)\n return applied.outcome === 'gap'\n ? markGap(model, message.stream)\n : clearGap(\n {\n ...model,\n entities: applied.store,\n live: { ...model.live, [message.stream]: applied.state },\n },\n message.stream,\n )\n }\n const applied = applyConnectionEvent(state, model.optimistic, message.event, message.policy)\n return applied.outcome === 'gap'\n ? markGap(model, message.stream)\n : clearGap(\n {\n ...model,\n optimistic: applied.optimistic,\n live: { ...model.live, [message.stream]: applied.state },\n },\n message.stream,\n )\n }\n case 'GapCleared':\n return clearGap(model, message.stream)\n case 'ConnectionMerged': {\n const current = model.connections[message.connection] ?? emptyConnection\n const merged = merge(current, message.page)\n return {\n ...model,\n connections: {\n ...model.connections,\n [message.connection]: message.refreshes === true ? { ...merged, stale: false } : merged,\n },\n optimistic: pruneOverlays(\n model.optimistic,\n message.connection,\n new Set(message.page.edges.map(edge => edge.key)),\n model.mutations.pending,\n ),\n }\n }\n case 'ConnectionInvalidated':\n return {\n ...model,\n connections: setConnectionStale(model.connections, message.connection, true),\n }\n case 'QueryFailed':\n // The refresh is over; the connection reads as it did before it started,\n // and one the Model never held stays absent.\n return message.connection in model.connections\n ? {\n ...model,\n connections: setConnectionStale(model.connections, message.connection, false),\n }\n : model\n case 'ConnectionRefreshed':\n return {\n ...model,\n connections: setConnectionStale(model.connections, message.connection, false),\n }\n }\n}\n\n/** Appends (after) or prepends (before) an incoming page onto the stored one. */\nconst mergeWireRefPages = (\n current: RefPageValue,\n next: RefPageValue,\n direction: 'after' | 'before',\n): RefPageValue => {\n const refs =\n direction === 'after'\n ? [...new Set([...current.refs, ...next.refs])]\n : [...new Set([...next.refs, ...current.refs])]\n // The far boundary is the incoming page's; the near one is still the stored page's.\n return direction === 'after'\n ? { refs, hasNext: next.hasNext, hasPrevious: current.hasPrevious }\n : { refs, hasNext: current.hasNext, hasPrevious: next.hasPrevious }\n}\n\n/**\n * Writes a read result into the store, recording each field's applied window so\n * a later request with a different window refetches. A relation page requested\n * with a cursor is merged onto the page already stored, so \"load more\"\n * accumulates rather than replaces. Every read path should use this rather than\n * reducing `writeEntity` by hand.\n */\nexport const writeRead = (\n store: EntityStore,\n requests: ReadonlyArray<Requirement>,\n result: Schema.Schema.Type<typeof ReadBatchResult>,\n now = 0,\n): EntityStore => {\n const returned = new Map<string, Record<string, unknown>>()\n for (const entity of result.entities) {\n const key = entityKey(entity.entity, entity.id)\n returned.set(key, { ...returned.get(key), ...entity.values })\n }\n const byEntity = new Map<\n string,\n { windows: Record<string, string>; merge: Map<string, 'after' | 'before'> }\n >()\n // A request's windows apply to its entity; a relation's windows apply to\n // each target the returned refs name, and so on down the graph.\n const record = (\n key: string,\n windows: Requirement['windows'],\n relations: Requirement['relations'],\n ): void => {\n let entry = byEntity.get(key)\n if (entry === undefined) {\n entry = { windows: {}, merge: new Map() }\n byEntity.set(key, entry)\n }\n for (const [field, window] of Object.entries(windows ?? {})) {\n entry.windows[field] = windowKey(window)\n const direction =\n window.after !== undefined ? 'after' : window.before !== undefined ? 'before' : undefined\n if (direction !== undefined) entry.merge.set(field, direction)\n }\n const values = returned.get(key)\n if (values === undefined) return\n for (const [field, relation] of Object.entries(relations ?? {})) {\n for (const ref of targetsOf(values[field], relation)) {\n record(entityKey(ref.entity, ref.id), relation.windows, relation.relations)\n }\n }\n }\n for (const request of requests) {\n record(entityKey(request.entity, request.id), request.windows, request.relations)\n }\n\n const writes: EntityWrite[] = []\n const pending = new Map<string, Record<string, unknown>>()\n for (const entity of result.entities) {\n const key = entityKey(entity.entity, entity.id)\n const entry = byEntity.get(key)\n let values = entity.values\n if (entry !== undefined && entry.merge.size > 0) {\n // A cursor page merges onto the page stored (or written earlier in this result).\n const previous = pending.get(key) ?? store[key]?.values\n if (previous !== undefined) {\n const merged: Record<string, unknown> = { ...values }\n for (const [field, direction] of entry.merge) {\n const incoming = values[field]\n const existing = previous[field]\n if (isRefPage(incoming) && isRefPage(existing)) {\n merged[field] = mergeWireRefPages(existing, incoming, direction)\n }\n }\n values = merged\n }\n }\n pending.set(key, { ...pending.get(key), ...values })\n writes.push({ key, values, windows: entry?.windows })\n }\n return writeEntities(store, writes, now)\n}\n","/**\n * Request policies: how a read treats fields the store already holds. A policy\n * compiles to planner options; it is not a second cache. `Remote.observe` and\n * `Remote.prefetch` take one, and the planner itself stays pure and\n * time-injected.\n */\nimport type { PlanOptions } from './plan.js'\n\nexport type RemotePolicy =\n /** Fetch only fields the store lacks (missing, stale, or re-windowed). */\n | { readonly _tag: 'CacheFirst' }\n /**\n * Keep present values visible, read them as `Refreshing`, and refetch an\n * entry older than `maxAge` milliseconds.\n */\n | { readonly _tag: 'StaleWhileRevalidate'; readonly maxAge: number }\n /** Fetch every selected field regardless of coverage; cached values stay visible meanwhile. */\n | { readonly _tag: 'NetworkOnly' }\n\nexport const RemotePolicy = {\n /** Fetch only what the store lacks. */\n cacheFirst: { _tag: 'CacheFirst' } as const satisfies RemotePolicy,\n\n /** Keep present values visible, read as `Refreshing`, and refetch an entry older than `maxAge` ms. */\n staleWhileRevalidate: (options: { readonly maxAge: number }): RemotePolicy => ({\n _tag: 'StaleWhileRevalidate',\n maxAge: options.maxAge,\n }),\n\n /** Fetch every selected field regardless of coverage; cached values stay visible meanwhile. */\n networkOnly: { _tag: 'NetworkOnly' } as const satisfies RemotePolicy,\n\n /** The planner options a policy compiles to at `now`. */\n toPlan: (policy: RemotePolicy, now: number): PlanOptions => {\n switch (policy._tag) {\n case 'CacheFirst':\n return {}\n case 'StaleWhileRevalidate':\n return { freshness: { now, freshness: policy.maxAge } }\n case 'NetworkOnly':\n return { force: true }\n }\n },\n\n /**\n * Whether a read under this policy may refetch fields the store already\n * holds, so an observer marks them stale (read as `Refreshing`) while the\n * request is pending.\n */\n refreshes: (policy: RemotePolicy): boolean => policy._tag !== 'CacheFirst',\n}\n","/**\n * Entities: the descriptor an application declares, refs, ref pages, and\n * patches, with the codecs that carry refs on the wire.\n */\nimport { Schema, SchemaGetter } from 'effect'\nimport { RelationAnnotation, RelationEntityAnnotation, refParts } from './relation.js'\n// selection.ts imports this module too; both only use the other inside\n// function bodies, so the cycle is never observed at module evaluation.\nimport { Selection, type SelectionOf, type SelectionValue } from './selection.js'\nimport { entityKey } from './store.js'\n\nexport type AnySchema = Schema.Schema<unknown>\n\ndeclare const entityRefFields: unique symbol\n\n/**\n * A normalized reference to an entity. `F` is a phantom carrying the entity's\n * fields so `Entity.patch` can type its patch; it is absent at runtime.\n */\nexport interface EntityRef<\n Name extends string,\n F extends Schema.Struct.Fields = Schema.Struct.Fields,\n> {\n readonly entity: Name\n readonly id: string\n readonly [entityRefFields]?: F\n}\n\nexport interface EntityDescriptor<Name extends string, F extends Schema.Struct.Fields> {\n readonly name: Name\n readonly schema: Schema.Struct<F>\n readonly fields: F\n // Methods, not properties: method signatures are bivariant, so a concrete\n // descriptor stays assignable to `EntityDescriptor<any, any>` (which appears\n // in every heterogeneous collection, e.g. `Remote.make`'s entities).\n ref(id: Schema.Schema.Type<F['id']>): EntityRef<Name, F>\n /** The fields a Surface reads of this entity; `Selection.make(entity, …)` with the entity as receiver. */\n select<const Sel extends SelectionOf<F>>(\n selection: Sel,\n ): Selection<SelectionValue<F, Sel>, Name, 'entity'>\n /** A patch of this entity's wire-shaped values; `Entity.patch(entity.ref(id), values)`. */\n patch(\n id: Schema.Schema.Type<F['id']>,\n values: Partial<Schema.Struct.Encoded<F>>,\n ): EntityPatch<Name, F>\n}\n\n/**\n * Relations are **references**, never inline target schemas: a ref cannot\n * reconstruct a full entity, and dereferencing is a store concern. Because the\n * target schema is not inlined, recursive relations cannot arise through the\n * schema graph.\n */\nconst refCodec = <Name extends string, F extends Schema.Struct.Fields>(\n entity: Name,\n): Schema.Codec<EntityRef<Name, F>, string> =>\n Schema.Struct({ entity: Schema.String, id: Schema.String })\n .pipe(\n Schema.encodeTo(Schema.String, {\n decode: SchemaGetter.transform(refParts),\n encode: SchemaGetter.transform((ref: EntityRef<string>) => entityKey(ref.entity, ref.id)),\n }),\n )\n .annotate({\n [RelationAnnotation]: 'one',\n [RelationEntityAnnotation]: entity,\n }) as unknown as Schema.Codec<EntityRef<Name, F>, string>\n\n/**\n * A patch in wire shape: the values the store holds, so a relation is its ref\n * key (`Entity.refKey`), not an `EntityRef`.\n */\nexport interface EntityPatch<Name extends string, F extends Schema.Struct.Fields> {\n readonly entity: Name\n readonly id: string\n readonly values: Partial<Schema.Struct.Encoded<F>>\n}\n\n/**\n * One authoritative page of a paginated relation: refs (never inline entities)\n * plus whether more exist. The adapter does not hold segmentation state; the\n * client merges pages.\n */\nexport interface RefPage<\n Name extends string,\n F extends Schema.Struct.Fields = Schema.Struct.Fields,\n> {\n readonly refs: ReadonlyArray<EntityRef<Name, F>>\n readonly hasNext: boolean\n readonly hasPrevious: boolean\n}\n\nconst refPageCodec = <Name extends string, F extends Schema.Struct.Fields>(\n entity: Name,\n): Schema.Codec<\n RefPage<Name, F>,\n {\n readonly refs: ReadonlyArray<string>\n readonly hasNext: boolean\n readonly hasPrevious: boolean\n }\n> =>\n Schema.Struct({\n refs: Schema.Array(refCodec<Name, F>(entity)),\n hasNext: Schema.Boolean,\n hasPrevious: Schema.Boolean,\n }).annotate({\n [RelationAnnotation]: 'page',\n [RelationEntityAnnotation]: entity,\n }) as unknown as Schema.Codec<\n RefPage<Name, F>,\n {\n readonly refs: ReadonlyArray<string>\n readonly hasNext: boolean\n readonly hasPrevious: boolean\n }\n >\n\nexport const Entity = {\n make: <\n const Name extends string,\n const F extends Schema.Struct.Fields & { readonly id: Schema.Schema<unknown> },\n >(\n name: Name,\n schema: Schema.Struct<F>,\n ): EntityDescriptor<Name, F> => {\n const descriptor: EntityDescriptor<Name, F> = {\n name,\n schema,\n fields: schema.fields,\n ref: id => ({ entity: name, id: String(id) }) as EntityRef<Name, F>,\n select: selection => Selection.make(descriptor, selection),\n patch: (id, values) => ({ entity: name, id: String(id), values }),\n }\n return descriptor\n },\n\n /** A relation to a known entity, decoded as a reference. */\n ref: <Name extends string, F extends Schema.Struct.Fields>(\n entity: EntityDescriptor<Name, F>,\n ): Schema.Codec<EntityRef<Name, F>, string> => refCodec<Name, F>(entity.name),\n\n /** A relation by name, for recursive or forward references. */\n refTo: <Name extends string>(name: Name): Schema.Codec<EntityRef<Name>, string> =>\n refCodec<Name, Schema.Struct.Fields>(name),\n\n /**\n * The wire key a relation field carries (`\"Entity:id\"`). Adapters that read a\n * foreign key emit this so the ref codec can decode it on the client.\n */\n refKey: (ref: { readonly entity: string; readonly id: string }): string =>\n entityKey(ref.entity, ref.id),\n\n /** Splits a ref key back into its entity and id. */\n refParts,\n\n /** A relation value of one authoritative page of refs. */\n refPage: <Name extends string, F extends Schema.Struct.Fields>(\n entity: EntityDescriptor<Name, F>,\n ): Schema.Codec<\n RefPage<Name, F>,\n {\n readonly refs: ReadonlyArray<string>\n readonly hasNext: boolean\n readonly hasPrevious: boolean\n }\n > => refPageCodec<Name, F>(entity.name),\n\n /**\n * A normalized patch for an entity, typed against its fields' wire shape:\n * write a relation as its ref key (`Entity.refKey`), as the server does.\n */\n patch: <Name extends string, F extends Schema.Struct.Fields>(\n ref: EntityRef<Name, F>,\n patch: Partial<Schema.Struct.Encoded<F>>,\n ): EntityPatch<Name, F> => ({ entity: ref.entity, id: ref.id, values: patch }),\n}\n","/**\n * Selections: the fields a Surface picks of an entity (nested through\n * relations, paged through connections), the requirement graph they imply,\n * and their assembly from the normalized store.\n */\nimport { Option, Schema } from 'effect'\nimport type { RelationRequirement } from 'foldkit-surface'\nimport {\n Entity,\n type AnySchema,\n type EntityDescriptor,\n type EntityRef,\n type RefPage,\n} from './entity.js'\nimport type { QueryWindow } from './query.js'\nimport { isRefPage, relationShape, targetsOf } from './relation.js'\nimport { entityKey, isFieldStale, isTombstone, readField, type EntityStore } from './store.js'\n\n/** One page of a paginated relation with each target assembled through a nested selection. */\nexport interface Page<Item> {\n readonly items: ReadonlyArray<Item>\n readonly hasNext: boolean\n readonly hasPrevious: boolean\n}\n\n/**\n * The fields a projection reads of one entity, plus the slice it reads of each\n * relation's target. `Shape` tells a parent selection whether this one is a\n * paginated relation (`connection`) or a plain entity slice (`entity`).\n */\nexport interface Selection<\n Value,\n Name extends string = string,\n Shape extends 'entity' | 'connection' = 'entity' | 'connection',\n> {\n readonly entity: Name\n readonly fields: readonly string[]\n /** A pure codec: entity fields carry no decoding or encoding services. */\n readonly schema: Schema.Codec<Value, unknown, never, never>\n /** Pagination windows for nested relation fields, keyed by field name. */\n readonly connections?: Readonly<Record<string, QueryWindow>> | undefined\n /** The slice required of each nested relation's target, keyed by field name. */\n readonly relations?: Readonly<Record<string, RelationRequirement>> | undefined\n /** Present when this selection is itself a paginated relation. */\n readonly window?: QueryWindow | undefined\n /** Phantom: see `Shape`. */\n readonly shape?: Shape | undefined\n}\n\n/** Flattens a mapped type so hovers show the picked fields, not the machinery. */\ntype Simplify<T> = T extends infer O ? { readonly [K in keyof O]: O[K] } : never\n\n/** The value a Selection reads: `Selection.Value<typeof ProjectCard>`. */\nexport type SelectionValueOf<S> = S extends Selection<infer V, any, any> ? V : never\n\n/** The nested selections a relation field admits: of its target entity, in the shapes its value takes. */\ntype NestedFor<Field> =\n Exclude<Field, null | undefined> extends ReadonlyArray<EntityRef<infer Name, any>>\n ? Selection<unknown, Name, 'entity' | 'connection'>\n : Exclude<Field, null | undefined> extends RefPage<infer Name, any>\n ? Selection<unknown, Name, 'entity' | 'connection'>\n : Exclude<Field, null | undefined> extends EntityRef<infer Name, any>\n ? Selection<unknown, Name, 'entity'>\n : never\n\n/** What a selection of an entity with fields `F` may pick: `true` per scalar, a nested selection per relation. */\nexport type SelectionOf<F extends Schema.Struct.Fields> = {\n readonly [K in keyof F]?: true | NestedFor<Schema.Schema.Type<F[K]>>\n}\n\n/** `T | null` when the field admits `null` or `undefined` (both assemble to `null`). */\ntype Nullable<Field, T> = [Extract<Field, null | undefined>] extends [never] ? T : T | null\n\n/** A nested selection's value takes the shape of the field it selects through. */\ntype NestedValue<Field, Sel> =\n Sel extends Selection<infer V, string, 'connection'>\n ? Nullable<Field, V>\n : Sel extends Selection<infer V, string, 'entity'>\n ? Nullable<\n Field,\n Exclude<Field, null | undefined> extends ReadonlyArray<EntityRef<any, any>>\n ? ReadonlyArray<V>\n : Exclude<Field, null | undefined> extends RefPage<any, any>\n ? Page<V>\n : V\n >\n : never\n\n/** The value a selection `Sel` of fields `F` reads. */\nexport type SelectionValue<F extends Schema.Struct.Fields, Sel> = Simplify<{\n readonly [K in keyof Sel & keyof F]: Sel[K] extends true\n ? Schema.Schema.Type<F[K]>\n : NestedValue<Schema.Schema.Type<F[K]>, Sel[K]>\n}>\n\n// Built once per item schema, as `remoteDataSchema` is: a query projection is\n// rebuilt on every Model change.\nconst pageSchemas = new WeakMap<object, AnySchema>()\n\nexport const pageSchema = (item: AnySchema): AnySchema => {\n const cached = pageSchemas.get(item)\n if (cached !== undefined) return cached\n const built = Schema.Struct({\n items: Schema.Array(item),\n hasNext: Schema.Boolean,\n hasPrevious: Schema.Boolean,\n }) as unknown as AnySchema\n pageSchemas.set(item, built)\n return built\n}\n\n/** The requirement a nested selection contributes for its relation's target. */\nexport const relationOf = (selection: Selection<unknown>): RelationRequirement => ({\n entity: selection.entity,\n fields: selection.fields,\n ...(selection.connections === undefined ? {} : { windows: selection.connections }),\n ...(selection.relations === undefined ? {} : { relations: selection.relations }),\n})\n\nexport const Selection = {\n /**\n * The fields to read of `entity`. A nested `Selection` on a relation field\n * reads through the ref (or refs, or page of refs) the field holds into the\n * target's fields; a scalar field cannot take one.\n */\n make: <Name extends string, F extends Schema.Struct.Fields, const Sel extends SelectionOf<F>>(\n entity: EntityDescriptor<Name, F>,\n selection: Sel,\n ): Selection<SelectionValue<F, Sel>, Name, 'entity'> => {\n if (Object.keys(selection).length === 0) {\n throw new Error(`Selection.make: a selection of \"${entity.name}\" picks at least one field`)\n }\n const picked: Record<string, AnySchema> = {}\n const connections: Record<string, QueryWindow> = {}\n const relations: Record<string, RelationRequirement> = {}\n for (const key of Object.keys(selection)) {\n const choice = (selection as Record<string, unknown>)[key]\n if (choice === true) {\n picked[key] = entity.fields[key] as AnySchema\n continue\n }\n const nested = choice as Selection<unknown>\n const shape = relationShape(entity.fields[key] as Schema.Top)\n if (shape === undefined) {\n throw new Error(\n `Selection.make: \"${key}\" on \"${entity.name}\" is not a relation field, so it cannot take a nested selection`,\n )\n }\n if (nested.entity !== shape.entity) {\n throw new Error(\n `Selection.make: \"${key}\" on \"${entity.name}\" refers to \"${shape.entity}\", not \"${nested.entity}\"`,\n )\n }\n const nullable = (codec: AnySchema): AnySchema =>\n shape.nullable ? (Schema.NullOr(codec) as unknown as AnySchema) : codec\n if (nested.window !== undefined) {\n // A connection: the nested selection already carries its page codec.\n connections[key] = nested.window\n picked[key] = nullable(nested.schema as AnySchema)\n if (nested.fields.length > 0) relations[key] = relationOf(nested)\n continue\n }\n const item = nested.schema as AnySchema\n picked[key] = nullable(\n shape.kind === 'many'\n ? (Schema.Array(item) as unknown as AnySchema)\n : shape.kind === 'page'\n ? pageSchema(item)\n : item,\n )\n relations[key] = relationOf(nested)\n }\n return {\n entity: entity.name,\n fields: Object.keys(selection),\n schema: Schema.Struct(picked) as unknown as Schema.Codec<\n SelectionValue<F, Sel>,\n unknown,\n never,\n never\n >,\n ...(Object.keys(connections).length === 0 ? {} : { connections }),\n ...(Object.keys(relations).length === 0 ? {} : { relations }),\n }\n },\n\n /**\n * A paginated relation: one page of refs to `entity` with a window, or, with\n * a nested selection, one page of targets assembled through it.\n */\n connection: (<Name extends string, F extends Schema.Struct.Fields, Item = never>(\n entity: EntityDescriptor<Name, F>,\n window: QueryWindow,\n selection?: Selection<Item, Name, 'entity'>,\n ): Selection<RefPage<Name, F> | Page<Item>, Name, 'connection'> => {\n if (selection !== undefined && selection.entity !== entity.name) {\n throw new Error(\n `Selection.connection: a page of \"${entity.name}\" cannot select \"${selection.entity}\"`,\n )\n }\n return {\n entity: entity.name,\n fields: selection?.fields ?? [],\n schema: (selection === undefined\n ? Entity.refPage(entity)\n : pageSchema(selection.schema as AnySchema)) as unknown as Schema.Codec<\n RefPage<Name, F> | Page<Item>,\n unknown,\n never,\n never\n >,\n window,\n ...(selection?.connections === undefined ? {} : { connections: selection.connections }),\n ...(selection?.relations === undefined ? {} : { relations: selection.relations }),\n }\n }) as {\n <Name extends string, F extends Schema.Struct.Fields>(\n entity: EntityDescriptor<Name, F>,\n window: QueryWindow,\n ): Selection<RefPage<Name, F>, Name, 'connection'>\n <Name extends string, F extends Schema.Struct.Fields, Item>(\n entity: EntityDescriptor<Name, F>,\n window: QueryWindow,\n selection: Selection<Item, NoInfer<Name>, 'entity'>,\n ): Selection<Page<Item>, Name, 'connection'>\n },\n}\n\ninterface Assembled {\n readonly values: unknown\n readonly refreshing: boolean\n}\n\n/**\n * Reads an entity's selected fields out of the store, following each nested\n * relation into its targets. `undefined` means some field, at any depth, is\n * not present yet. A tombstoned target reads as `null` (or is dropped from a\n * list), so the Selection's codec decides whether that is a failure.\n */\nexport const assemble = (\n store: EntityStore,\n key: string,\n requirement: RelationRequirement,\n): Assembled | undefined => {\n const values: Record<string, unknown> = {}\n let refreshing = false\n for (const field of requirement.fields) {\n const value = readField(store, key, field)\n if (Option.isNone(value)) return undefined\n refreshing ||= isFieldStale(store, key, field)\n const relation = requirement.relations?.[field]\n if (relation === undefined) {\n values[field] = value.value\n continue\n }\n const nested = assembleRelation(store, value.value, relation)\n if (nested === undefined) return undefined\n values[field] = nested.values\n refreshing ||= nested.refreshing\n }\n return { values, refreshing }\n}\n\nconst assembleTarget = (\n store: EntityStore,\n ref: { readonly entity: string; readonly id: string },\n relation: RelationRequirement,\n): Assembled | 'absent' | undefined => {\n const key = entityKey(ref.entity, ref.id)\n return isTombstone(store, key) ? 'absent' : assemble(store, key, relation)\n}\n\n/** Assembles the targets a relation value refers to, in the value's own shape. */\nconst assembleRelation = (\n store: EntityStore,\n value: unknown,\n relation: RelationRequirement,\n): Assembled | undefined => {\n if (value === null || value === undefined) return { values: null, refreshing: false }\n const targets: unknown[] = []\n let refreshing = false\n for (const ref of targetsOf(value, relation)) {\n const target = assembleTarget(store, ref, relation)\n if (target === undefined) return undefined\n if (target === 'absent') continue\n targets.push(target.values)\n refreshing ||= target.refreshing\n }\n if (typeof value === 'string') {\n return { values: targets.length === 0 ? null : targets[0], refreshing }\n }\n if (isRefPage(value)) {\n return {\n values: { items: targets, hasNext: value.hasNext, hasPrevious: value.hasPrevious },\n refreshing,\n }\n }\n return { values: targets, refreshing }\n}\n","/**\n * `foldkit-remote` — normalized application-facing server state.\n *\n * The pure core (entities, selections, the store, the planner, connections,\n * live classification, optimistic layers) performs no I/O. The `Remote.*`\n * helpers that read or mutate go through the `RemoteClient` Effect service.\n */\nimport { Effect, Layer, Result, Schema, Stream } from 'effect'\nimport type { Duration } from 'effect'\nimport type { Command } from 'foldkit/command'\nimport type { EntryWithoutKeepAlive } from 'foldkit/subscription'\nimport {\n Requirement,\n type ActiveSurface,\n type ConnectionRequirement,\n type Contract,\n type Invalid,\n type ModelRef,\n type Projection,\n type Surface,\n} from 'foldkit-surface'\nimport {\n RemoteClient,\n coalescedLayer,\n liveEventOf,\n mutateRemote,\n remoteError,\n type RemoteRpcClient,\n} from './client.js'\nimport { emptyConnection, hasNext, hasPrevious, type Edge } from './connection.js'\nimport type { EntityDescriptor } from './entity.js'\nimport { inspectEntity, inspectRemote, type RemoteInspection } from './inspect.js'\nimport type { LiveCursor } from './live.js'\nimport {\n initialRemoteModel,\n isRemoteMessage,\n remoteMessageCases,\n remoteMessageSchema,\n remoteModelSchema,\n retentionRootsSchema,\n updateRemote,\n writeRead,\n type RemoteMessage,\n type RemoteMessageInput,\n type RemoteModel,\n} from './model.js'\nimport type { MutationDescriptor } from './mutation.js'\nimport {\n connectionIdentity,\n visibleItems,\n visibleStore,\n type ConnectionIdentity,\n type OptimisticState,\n type OptimisticOperation,\n} from './optimistic.js'\nimport { plan, type PlanOptions } from './plan.js'\nimport { RemotePolicy } from './policy.js'\nimport { stableStringify } from './query.js'\nimport type { ConnectionSpec, QueryDescriptor, QueryRef, QueryWindow } from './query.js'\nimport { remoteDataSchema, type RemoteData } from './remoteData.js'\nimport type { ConnectionRoot, RetentionRoots } from './retain.js'\nimport { assemble, pageSchema, relationOf, type Page, type Selection } from './selection.js'\nimport { entityKey, isTombstone, type EntityStore } from './store.js'\nimport {\n QueryRequest,\n QueryResult,\n ReadRequest,\n RelationRequest,\n REMOTE_PROTOCOL_VERSION,\n WindowSchema,\n RemoteLiveError,\n RemoteProtocolError,\n RemoteQueryError,\n RemoteReadError,\n RemoteRpc,\n} from './wire.js'\nimport type { CoalesceOptions } from './coalesce.js'\nimport type { RelationRequirement } from './plan.js'\n\nexport * from './client.js'\nexport * from './coalesce.js'\nexport * from './connection.js'\nexport * from './entity.js'\nexport * from './inspect.js'\nexport * from './live.js'\nexport * from './model.js'\nexport * from './mutation.js'\nexport * from './optimistic.js'\nexport * from './persistence.js'\nexport * from './plan.js'\nexport * from './policy.js'\nexport * from './query.js'\nexport * from './relation.js'\nexport * from './remoteData.js'\nexport * from './retain.js'\nexport * from './selection.js'\nexport * from './store.js'\nexport * from './wire.js'\n\ntype EntityName<D> = D extends EntityDescriptor<infer Name, any> ? Name : never\ntype QueryName<D> = D extends QueryDescriptor<infer Name, any, any> ? Name : never\ntype MutationName<D> = D extends MutationDescriptor<infer Name, any, any> ? Name : never\n\n/**\n * Nothing when `Name` is one of the domain's registered `Names`; otherwise a\n * branded failure naming the descriptor, so `Data.get(Team.select(…))` for an\n * unregistered `Team` errors at the selection in one line.\n */\nexport type Registered<Name extends string, Names extends string, Kind extends string> = [\n Name,\n] extends [Names]\n ? unknown\n : Invalid<`${Kind} \"${Name}\" is not registered with this Remote domain`>\n\n/** Nothing when a selection is of the query's entity; otherwise a branded failure naming both. */\nexport type SelectsEntity<Entity extends string, Of extends string> = [Entity] extends [Of]\n ? unknown\n : Invalid<`the selection is of \"${Entity}\", but the query lists \"${Of}\"`>\n\nexport interface RemoteDescriptor<\n Entities extends readonly EntityDescriptor<any, any>[] = readonly EntityDescriptor<any, any>[],\n Queries extends readonly QueryDescriptor<any, any, any>[] = readonly QueryDescriptor<\n any,\n any,\n any\n >[],\n Mutations extends readonly MutationDescriptor<any, any, any>[] = readonly MutationDescriptor<\n any,\n any,\n any\n >[],\n> {\n readonly entities: Entities\n readonly queries: Queries\n readonly mutations: Mutations\n readonly Model: Schema.Schema<RemoteModel>\n readonly initial: RemoteModel\n readonly Message: Schema.Schema<RemoteMessage>\n readonly update: (model: RemoteModel, message: RemoteMessage) => RemoteModel\n readonly rpc: typeof RemoteRpc\n /** Name-keyed lookups built from the declared entities, queries, and mutations. */\n readonly registry: {\n readonly entities: ReadonlyMap<string, EntityDescriptor<any, any>>\n readonly queries: ReadonlyMap<string, QueryDescriptor<any, any, any>>\n readonly mutations: ReadonlyMap<string, MutationDescriptor<any, any, any>>\n }\n}\n\ndeclare const boundRemoteNames: unique symbol\n\nexport interface BoundRemote<AppModel, Store extends RemoteModel, Names extends string = string> {\n readonly definition: RemoteDescriptor\n readonly store: ModelRef<AppModel, Store>\n /** For `Module`: owns the store's Model path. */\n readonly contract: Contract\n /** Phantom: the entity names this Remote definition registers. */\n readonly [boundRemoteNames]?: Names\n}\n\ntype MutationInput<M> = M extends MutationDescriptor<any, infer Input, any> ? Input : never\n\nexport interface DomainMutateOptions {\n /** Overrides the generated id, for a retry, a durable bridge, or a test. */\n readonly requestId?: string | undefined\n /**\n * What the request changes before the server answers, released when it\n * settles. A function receives the generated ids, so a created entity can\n * carry `tempId` until the result names the real one.\n */\n readonly optimistic?:\n | ReadonlyArray<OptimisticOperation>\n | ((ids: {\n readonly requestId: string\n readonly tempId: string\n }) => ReadonlyArray<OptimisticOperation>)\n | undefined\n}\n\n/** A Foldkit Subscription entry of the Remote domain, emitting its Messages through `RemoteClient`. */\nexport type RemoteEntry<AppModel, Dependencies> = EntryWithoutKeepAlive<\n AppModel,\n RemoteMessage,\n Dependencies,\n RemoteClient\n>\n\nexport interface SubscriptionsOptions extends ObserveOptions, LiveOptions, RetainOptions {}\n\n/** What `RemoteDomain.mutate` hands `update`: the Model with the request started, and the Command that settles it. */\nexport interface MutationStarted<AppModel> {\n readonly model: AppModel\n readonly requestId: string\n readonly tempId: string\n /** Yields `MutationSucceeded` or `MutationFailed`; never fails. */\n readonly command: Command<RemoteMessage, never, RemoteClient>\n}\n\n/**\n * A Remote domain bound to its place in the application Model: the descriptor\n * (`Remote.define`), the binding (`Remote.at`), and the application-facing\n * operations over them. Every method compiles to the `Remote.*` function of the\n * same name, which stays exported for tooling, SSR, and tests.\n */\nexport interface RemoteDomain<\n AppModel,\n Store extends RemoteModel,\n Entities extends readonly EntityDescriptor<any, any>[],\n Queries extends readonly QueryDescriptor<any, any, any>[],\n Mutations extends readonly MutationDescriptor<any, any, any>[],\n>\n extends\n BoundRemote<AppModel, Store, EntityName<Entities[number]>>,\n RemoteDescriptor<Entities, Queries, Mutations> {\n /** `Remote.select`: a Projection reading one entity through a selection of a registered entity. */\n get<Value, Name extends string>(\n selection: Selection<Value, Name, 'entity'> &\n Registered<Name, EntityName<Entities[number]>, 'Entity'>,\n id: string,\n ): Projection<AppModel, RemoteData<Value>>\n /**\n * `get`, and the projection also subscribes to the entity's changes: its\n * requirements are marked `live`, so `subscriptions` derives a live entry for\n * the Surfaces that read it.\n */\n live<Value, Name extends string>(\n selection: Selection<Value, Name, 'entity'> &\n Registered<Name, EntityName<Entities[number]>, 'Entity'>,\n id: string,\n ): Projection<AppModel, RemoteData<Value>>\n /**\n * A query connection read as a `Page` of items selected of the query's\n * entity: `Initial` until the page and every item's selected fields are\n * present, `Refreshing` while any of them is being refetched. The window is\n * the page first asked for; the pages `next`, `previous` and `fetch` merge\n * onto the connection read through the same projection.\n */\n query<Q extends QueryDescriptor<any, any, any>, Value, Entity extends string>(\n query: Q & Registered<Q['name'], QueryName<Queries[number]>, 'Query'>,\n input: QueryInput<Q>,\n options: QueryOptions<Value, Entity, QueryEntity<Q>>,\n ): QueryProjection<AppModel, Value, Q['name'], QueryInput<Q>>\n /** The `QueryRef` for the page after the loaded end (same page size), or `undefined` when there is none or its cursor is unknown. */\n next<Name extends string, Input>(\n model: AppModel,\n projection: QueryProjection<AppModel, any, Name, Input>,\n ): QueryRef<Name, Input> | undefined\n /** The `QueryRef` for the page before the loaded start, or `undefined`. */\n previous<Name extends string, Input>(\n model: AppModel,\n projection: QueryProjection<AppModel, any, Name, Input>,\n ): QueryRef<Name, Input> | undefined\n /** A Command that runs the query and yields the `ConnectionMerged` (or `QueryFailed`) that reduces it: \"load more\". */\n fetch(ref: QueryRef<string, unknown>): Command<RemoteMessage, never, RemoteClient>\n /**\n * The Foldkit Subscription entries for the active Surfaces, keyed for\n * `Subscription.make`: a read entry per Surface (`Remote.observe`), a live\n * entry per Surface that reads through `live` (`Remote.live`), and one\n * retain entry with every active Surface as a root (`Remote.retain`). A\n * Surface's params are a function of the Model (`Surface.at`), so what is\n * fetched, subscribed, and retained follows the Model.\n */\n subscriptions(\n active: Readonly<Record<string, ActiveSurface<AppModel> | Surface<AppModel, any, any, void>>>,\n options?: SubscriptionsOptions,\n ): Readonly<Record<string, RemoteEntry<AppModel, any>>>\n /** `Remote.plan`: the requirements the store does not satisfy. */\n plan<Value>(\n model: AppModel,\n projection: Projection<AppModel, Value>,\n options?: PlanOptions,\n ): ReadonlyArray<Requirement>\n /** `Remote.storeOf`: the visible store, base under the pending optimistic layers. */\n storeOf(model: AppModel): EntityStore\n /**\n * The plan run through `RemoteClient` and reduced into the Model: the\n * projection's pending queries first, then the fields it lacks (the pages'\n * items included). For SSR, route or hover prefetch, and tests.\n */\n prefetch<Value>(\n model: AppModel,\n projection: Projection<AppModel, Value>,\n options?: ObserveOptions,\n ): Effect.Effect<AppModel, RemoteReadError | RemoteProtocolError | RemoteQueryError, RemoteClient>\n /**\n * Starts a registered mutation from `update`: applies `MutationStarted` (with\n * the optimistic operations) to the Model and returns the Command that runs\n * it and yields the settling Message. The request id comes from the model's\n * mutation sequence unless `options.requestId` is given.\n */\n mutate<M extends MutationDescriptor<any, any, any>>(\n model: AppModel,\n mutation: M & Registered<M['name'], MutationName<Mutations[number]>, 'Mutation'>,\n input: MutationInput<M>,\n options?: DomainMutateOptions,\n ): MutationStarted<AppModel>\n /** `Remote.update` on the bound slice: reduces one of Remote's Messages, as `RemoteMessage` or as the application's union constructs it. */\n reduce(model: AppModel, message: RemoteMessage | RemoteMessageInput): AppModel\n /** `Remote.inspect` of the bound slice. */\n inspect(model: AppModel): RemoteInspection\n}\n\n/** A projection's connection requirement with the `QueryRef` that runs it. */\nexport interface QueryRequirement extends ConnectionRequirement {\n readonly ref: QueryRef<string, unknown>\n}\n\n/** A page forward (`first`, `after`) or back (`last`, `before`); mixing the two is a type error. */\nexport type QueryWindowOptions =\n | {\n readonly first?: number | undefined\n readonly after?: string | undefined\n readonly last?: undefined\n readonly before?: undefined\n }\n | {\n readonly last: number\n readonly before?: string | undefined\n readonly first?: undefined\n readonly after?: undefined\n }\n\nexport type QueryOptions<Value, Entity extends string, Of extends string = Entity> = {\n /** What to read of each item: a selection of the query's entity (`Of`). */\n readonly select: Selection<Value, Entity, 'entity'> & SelectsEntity<Entity, Of>\n} & QueryWindowOptions\n\n/** A query connection read as a `Page` of selected items; `ref` is the connection with its first window. */\nexport interface QueryProjection<AppModel, Value, Name extends string, Input> extends Projection<\n AppModel,\n RemoteData<Page<Value>>\n> {\n readonly ref: QueryRef<Name, Input>\n}\n\n/** The input of a query descriptor. */\nexport type QueryInput<Q> = Q extends QueryDescriptor<any, infer Input, any> ? Input : never\n/** The entity a query's connection is over. */\nexport type QueryEntity<Q> =\n Q extends QueryDescriptor<any, any, ConnectionSpec<infer Entity>> ? Entity : string\n\n/**\n * The store a read or plan sees: the base with every pending optimistic layer\n * applied, so a request's patches show until it settles and a temporary id is\n * not planned as a fetch.\n */\nconst storeOf = <AppModel, Store extends RemoteModel, Names extends string>(\n bound: BoundRemote<AppModel, Store, Names>,\n model: AppModel,\n): EntityStore => {\n const remote = bound.store.get(model)\n return visibleStoreOf(remote.entities, remote.optimistic)\n}\n\n// The visible store is recomputed only when the base store or the layers\n// change, so reads and plans across renders of one Model share it.\nconst visibleStores = new WeakMap<OptimisticState, WeakMap<EntityStore, EntityStore>>()\n\nconst visibleStoreOf = (entities: EntityStore, optimistic: OptimisticState): EntityStore => {\n let byStore = visibleStores.get(optimistic)\n if (byStore === undefined) {\n byStore = new WeakMap()\n visibleStores.set(optimistic, byStore)\n }\n let visible = byStore.get(entities)\n if (visible === undefined) {\n visible = visibleStore(entities, optimistic)\n byStore.set(entities, visible)\n }\n return visible\n}\n\n// A read's result per store snapshot. `Remote.storeOf` is shared across every\n// read of one Model state, so equal reads of one render assemble and decode\n// once and return one value (a view may compare by identity). A query read\n// also depends on its connection, which changes independently of the store,\n// so it keys on that object too. Weak on both, bounded by what is read.\nconst readResults = new WeakMap<object, WeakMap<object, Map<string, unknown>>>()\n\nconst memoRead = <T>(snapshot: object, by: object, key: string, compute: () => T): T => {\n let byScope = readResults.get(snapshot)\n if (byScope === undefined) {\n byScope = new WeakMap()\n readResults.set(snapshot, byScope)\n }\n let results = byScope.get(by)\n if (results === undefined) {\n results = new Map()\n byScope.set(by, results)\n }\n if (results.has(key)) return results.get(key) as T\n const value = compute()\n results.set(key, value)\n return value\n}\n\nexport interface MutateOptions {\n /** What the request changes before the server answers; released when it settles. */\n readonly optimistic?: ReadonlyArray<OptimisticOperation> | undefined\n}\n\n/** The default `toMessage`: the application reduces `RemoteMessage` itself. */\nconst identityMessage = (message: RemoteMessage): RemoteMessage => message\n\nexport interface RetainOptions {\n /** The query connections the application shows, by `QueryRef` or identity. */\n readonly connections?: ReadonlyArray<ConnectionIdentity> | undefined\n /** How long the roots must be stable before collecting; default none. */\n readonly grace?: Duration.Input | undefined\n}\n\n/** How `Remote.observe` and `Remote.prefetch` treat fields the store already holds. */\nexport interface ObserveOptions {\n /** Default `RemotePolicy.cacheFirst`. */\n readonly policy?: RemotePolicy | undefined\n /** The clock a refreshing policy reads; default `Date.now`. */\n readonly now?: (() => number) | undefined\n}\n\nexport interface LiveOptions {\n /** The clock `LiveReceived` stamps events with; default `Date.now`. */\n readonly now?: (() => number) | undefined\n}\n\n/** A stable key for a live subscription's requirement set. */\nconst liveStreamKey = (requirements: readonly Requirement[]): string =>\n requirements\n .map(\n requirement =>\n `${entityKey(requirement.entity, requirement.id)}:${[...requirement.fields].sort().join(',')}`,\n )\n .sort()\n .join('|')\n\n/** Declares a Remote domain: its entities, queries, and mutations, plus the submodel. */\nconst defineRemote = <\n const Entities extends readonly EntityDescriptor<any, any>[],\n const Queries extends readonly QueryDescriptor<any, any, any>[] = readonly QueryDescriptor<\n any,\n any,\n any\n >[],\n const Mutations extends readonly MutationDescriptor<any, any, any>[] =\n readonly MutationDescriptor<any, any, any>[],\n>(config: {\n readonly entities: Entities\n readonly queries?: Queries\n readonly mutations?: Mutations\n}): RemoteDescriptor<Entities, Queries, Mutations> => ({\n entities: config.entities,\n queries: (config.queries ?? []) as unknown as Queries,\n mutations: (config.mutations ?? []) as unknown as Mutations,\n Model: remoteModelSchema(),\n initial: initialRemoteModel,\n Message: remoteMessageSchema,\n update: updateRemote,\n rpc: RemoteRpc,\n registry: {\n entities: new Map(config.entities.map(entity => [entity.name, entity])),\n queries: new Map((config.queries ?? []).map(query => [query.name, query])),\n mutations: new Map((config.mutations ?? []).map(mutation => [mutation.name, mutation])),\n },\n})\n\n/** Binds a Remote domain to its store's location in the application Model. */\nconst bindRemote = <\n AppModel,\n Store extends RemoteModel,\n Entities extends readonly EntityDescriptor<any, any>[],\n Queries extends readonly QueryDescriptor<any, any, any>[],\n Mutations extends readonly MutationDescriptor<any, any, any>[],\n>(\n definition: RemoteDescriptor<Entities, Queries, Mutations>,\n store: ModelRef<AppModel, Store>,\n): BoundRemote<AppModel, Store, EntityName<Entities[number]>> => ({\n definition,\n store,\n contract: {\n kind: 'remote',\n name: store.dependency.join('.') || 'remote',\n // A generated field reference knows its application and its path; a raw\n // optic (`ModelRef.fromOptic`) knows neither, so it claims nothing.\n owner: (store as { readonly owner?: object }).owner,\n owns: store.dependency.length === 0 ? [] : [store.dependency],\n observes: store.dependency.length === 0 ? [] : [store.dependency],\n messages: [],\n requirements: [],\n },\n})\n\n/** The runtime half of `Registered`: a descriptor the domain never declared is an error naming both. */\nconst assertRegistered = (\n bound: BoundRemote<any, any>,\n kind: 'Entity' | 'Query' | 'Mutation',\n registered: ReadonlyMap<string, unknown>,\n name: string,\n): void => {\n if (!registered.has(name)) {\n throw new Error(\n `Remote: ${kind} \"${name}\" is not registered with domain \"${bound.contract.name}\"`,\n )\n }\n}\n\n/** What a projection asks of the remote: entity requirements and query connections. */\ninterface Asked {\n readonly requirements: ReadonlyArray<Requirement>\n readonly connections: ReadonlyArray<ConnectionRequirement>\n}\n\nconst nothingAsked: Asked = { requirements: [], connections: [] }\n\nconst askedOf = (projection: Projection<any, unknown> | undefined): Asked =>\n projection === undefined ? nothingAsked : projection\n\n/** The plan for what a projection asks: the entity fields to read, and the queries to run. */\ninterface Planned {\n readonly requirements: ReadonlyArray<Requirement>\n readonly queries: ReadonlyArray<QueryRequirement>\n}\n\n/**\n * Plans what a projection asks against the Model. A connection the Model holds\n * fresh contributes its visible items' selected fields to the entity plan; one\n * it does not hold, or holds stale, is a query to run (its items are planned\n * once the page arrives).\n */\nconst planAsked = (remote: RemoteModel, asked: Asked, options: PlanOptions): Planned => {\n const queries: QueryRequirement[] = []\n const items: Requirement[] = []\n const connections = Requirement.mergeConnections(\n asked.connections,\n ) as ReadonlyArray<QueryRequirement>\n for (const connection of connections) {\n const known = remote.connections[connection.identity]\n if (known === undefined || known.stale || options.force === true) {\n queries.push(connection)\n continue\n }\n const edges = visibleItems(\n known,\n connection.identity,\n remote.optimistic.overlays,\n remote.entities,\n )\n items.push(\n ...itemsOf(\n edges.map(edge => edge.ref),\n connection.select,\n ),\n )\n }\n return {\n requirements: plan(\n visibleStoreOf(remote.entities, remote.optimistic),\n [...asked.requirements, ...items],\n options,\n ),\n queries,\n }\n}\n\n/** The entity requirements a page's edges add under a selection. */\nconst itemsOf = (\n edges: ReadonlyArray<{ readonly entity: string; readonly id: string }>,\n select: RelationRequirement,\n): ReadonlyArray<Requirement> =>\n edges.filter(edge => edge.entity === select.entity).map(edge => ({ ...select, id: edge.id }))\n\n/**\n * The wire request of a planned query; a `QueryRef` identity carries the query\n * name and the canonical encoded input. A connection requirement built by hand\n * with another identity cannot be run, and fails as a query would.\n */\nconst queryRequestOf = (query: {\n readonly identity: string\n readonly window: QueryWindow\n}): Effect.Effect<Schema.Schema.Type<typeof QueryRequest>, RemoteQueryError> => {\n const separator = query.identity.indexOf('\\u0000')\n if (separator < 0) {\n return Effect.fail(\n new RemoteQueryError({\n message: `connection \"${query.identity}\" is not a query's: only a QueryRef identity can be run`,\n }),\n )\n }\n return Effect.try({\n try: () => ({\n query: query.identity.slice(0, separator),\n input: JSON.parse(query.identity.slice(separator + 1)) as unknown,\n window: query.window,\n }),\n catch: () =>\n new RemoteQueryError({ message: `connection \"${query.identity}\" carries no encoded input` }),\n })\n}\n\n/**\n * The `ConnectionMerged` for a query result, in the client's edge shape.\n * `refreshes` marks the page as answering the connection's refresh, so one\n * Message both merges it and clears `stale`.\n */\nconst pageMessage = (\n connection: string,\n result: Schema.Schema.Type<typeof QueryResult>,\n refreshes = false,\n): RemoteMessage => ({\n _tag: 'ConnectionMerged',\n connection,\n page: {\n edges: result.edges.map(edge => ({ key: edge.key, ref: { entity: edge.entity, id: edge.id } })),\n start: result.start,\n end: result.end,\n },\n ...(refreshes ? { refreshes } : {}),\n})\n\n/**\n * The retention roots of some projections: their requirements, their\n * connections (each with the union of what the projections select of its\n * items), and the connections listed by identity alone.\n */\nconst rootsOf = (\n projections: ReadonlyArray<Projection<any, unknown>>,\n options: RetainOptions,\n): RetentionRoots => {\n const connections = new Map<string, ConnectionRoot>()\n for (const identity of (options.connections ?? []).map(connectionIdentity)) {\n connections.set(identity, { identity })\n }\n for (const { identity, select } of projections.flatMap(projection => projection.connections)) {\n const current = connections.get(identity)?.select\n connections.set(identity, {\n identity,\n select: current === undefined ? select : Requirement.mergeRelation(current, select),\n })\n }\n return {\n requirements: Requirement.merge(projections.flatMap(projection => projection.requirements)),\n connections: [...connections.values()].sort((a, b) => (a.identity < b.identity ? -1 : 1)),\n }\n}\n\n/** A query the read entry runs, as its dependencies carry it: plain data Foldkit compares. */\nconst PlannedQuery = Schema.Struct({\n identity: Schema.String,\n window: WindowSchema,\n select: RelationRequest,\n})\n\n/** The dependencies of the read entry: the entity fields to read and the queries to run. */\nexport interface ReadDependencies {\n readonly requirements: ReadonlyArray<Requirement>\n readonly queries: ReadonlyArray<Schema.Schema.Type<typeof PlannedQuery>>\n}\n\n/**\n * The read entry: plans what `askedOf(model)` asks against the Model and runs\n * the entity read and the queries concurrently. Each Message it emits changes\n * the Model, so Foldkit recomputes the dependencies and restarts the stream\n * (`switchMap`): a merged page's items are planned by that next computation,\n * against the store as it then is, rather than read here unplanned. Nothing\n * the entry needs is spread over two Messages, since the second could be lost\n * to the restart; a page and its refresh are one `ConnectionMerged`.\n */\nconst observeEntry = <AppModel, Store extends RemoteModel, Message>(\n bound: BoundRemote<AppModel, Store>,\n askedOf: (model: AppModel) => Asked,\n toMessage: (message: RemoteMessage) => Message,\n options: ObserveOptions,\n): EntryWithoutKeepAlive<AppModel, Message, ReadDependencies, RemoteClient> => {\n const { policy = RemotePolicy.cacheFirst, now = Date.now } = options\n const read = (requirements: ReadonlyArray<Requirement>) =>\n Effect.gen(function* () {\n const client = yield* RemoteClient\n const at = now()\n const result = yield* Effect.result(\n client.read({ version: REMOTE_PROTOCOL_VERSION, requests: requirements }),\n )\n return Result.isFailure(result)\n ? toMessage({\n _tag: 'ReadFailed',\n requests: requirements,\n error: remoteError(result.failure),\n })\n : toMessage({\n _tag: 'ReadReceived',\n requests: requirements,\n result: result.success,\n now: at,\n })\n })\n const run = (query: ReadDependencies['queries'][number]) =>\n Effect.gen(function* () {\n const client = yield* RemoteClient\n const result = yield* Effect.result(\n queryRequestOf(query).pipe(Effect.flatMap(request => client.query(request))),\n )\n return Result.isFailure(result)\n ? toMessage({\n _tag: 'QueryFailed',\n connection: query.identity,\n error: remoteError(result.failure),\n })\n : toMessage(pageMessage(query.identity, result.success, true))\n })\n return {\n dependenciesSchema: Schema.Struct({\n requirements: Schema.Array(ReadRequest),\n queries: Schema.Array(PlannedQuery),\n }),\n modelToDependencies: model => {\n const planned = planAsked(\n bound.store.get(model),\n askedOf(model),\n RemotePolicy.toPlan(policy, now()),\n )\n return {\n requirements: planned.requirements,\n queries: planned.queries.map(({ identity, window, select }) => ({\n identity,\n window,\n select,\n })),\n }\n },\n dependenciesToStream: ({ requirements, queries }) =>\n Stream.concat(\n RemotePolicy.refreshes(policy) && requirements.length > 0\n ? Stream.succeed(toMessage({ _tag: 'RefreshStarted', requests: requirements }))\n : Stream.empty,\n Stream.mergeAll(\n [\n ...(requirements.length === 0 ? [] : [Stream.fromEffect(read(requirements))]),\n ...queries.map(query => Stream.fromEffect(run(query))),\n ],\n { concurrency: 'unbounded' },\n ),\n ),\n }\n}\n\n/** The live entry: subscribes to `requirementsOf(model)` from the Model's resume cursor. */\nconst liveEntry = <AppModel, Store extends RemoteModel, Message>(\n bound: BoundRemote<AppModel, Store>,\n requirementsOf: (model: AppModel) => ReadonlyArray<Requirement>,\n toMessage: (message: RemoteMessage) => Message,\n options: LiveOptions,\n): EntryWithoutKeepAlive<\n AppModel,\n Message,\n { readonly requirements: ReadonlyArray<Requirement>; readonly cursor: LiveCursor },\n RemoteClient\n> => ({\n dependenciesSchema: Schema.Struct({\n requirements: Schema.Array(ReadRequest),\n cursor: Schema.Number,\n }),\n modelToDependencies: model => {\n const requirements = requirementsOf(model)\n const stream = liveStreamKey(requirements)\n return {\n requirements,\n cursor: bound.store.get(model).live[stream]?.cursor ?? 0,\n }\n },\n dependenciesToStream: ({ requirements, cursor }) =>\n requirements.length === 0\n ? Stream.empty\n : Stream.unwrap(\n Effect.gen(function* () {\n const client = yield* RemoteClient\n return client.live({ requirements, after: cursor })\n }),\n ).pipe(\n Stream.map(event =>\n toMessage({\n _tag: 'LiveReceived',\n stream: liveStreamKey(requirements),\n event,\n now: (options.now ?? Date.now)(),\n }),\n ),\n Stream.catchIf(\n (_error): _error is RemoteLiveError | RemoteProtocolError => true,\n error =>\n Stream.succeed(\n toMessage({\n _tag: 'ReadFailed',\n requests: requirements,\n error: remoteError(error),\n }),\n ),\n ),\n ),\n})\n\n/** The projection an active Surface has for this Model, if it is active. */\nconst projectionOf = <AppModel>(\n entry: ActiveSurface<AppModel> | Surface<AppModel, any, any, void>,\n model: AppModel,\n): Projection<AppModel, unknown> | undefined =>\n 'projectionOf' in entry ? entry.projectionOf(model) : entry.projection()\n\n/**\n * `projectionOf` computed once per Model: the read, live, and retain entries\n * all derive their dependencies from the same projection on the same Model\n * change, and a Surface's `model` callback (which lifts and builds schemas)\n * need not run three times for it. Models are objects, so the memo is weak.\n */\nconst memoizedProjectionOf = <AppModel>(\n entry: ActiveSurface<AppModel> | Surface<AppModel, any, any, void>,\n): ((model: AppModel) => Projection<AppModel, unknown> | undefined) => {\n const cache = new WeakMap<object, Projection<AppModel, unknown> | undefined>()\n return model => {\n const key: unknown = model\n if (typeof key !== 'object' || key === null) return projectionOf(entry, model)\n if (cache.has(key)) return cache.get(key)\n const projection = projectionOf(entry, model)\n cache.set(key, projection)\n return projection\n }\n}\n\nexport const Remote = {\n /** The submodel's schema, the same for every domain; embed it in the application Model. */\n Model: remoteModelSchema(),\n /** The submodel's initial value. */\n initial: initialRemoteModel,\n /**\n * Remote's Message cases for `defineMessageUnion`: spread them into the\n * application's union, and reduce the ones `Remote.reduces` recognizes with\n * `RemoteDomain.reduce`.\n */\n messages: remoteMessageCases,\n /** Whether a Message is one of Remote's, by tag. */\n reduces: isRemoteMessage,\n\n /**\n * Declares a Remote domain and binds it to its place in the application Model\n * in one step; the result carries the application-facing operations. The\n * descriptor alone is `Remote.define`, the binding alone `Remote.at`.\n */\n make: <\n AppModel,\n Store extends RemoteModel,\n const Entities extends readonly EntityDescriptor<any, any>[],\n const Queries extends readonly QueryDescriptor<any, any, any>[] = readonly [],\n const Mutations extends readonly MutationDescriptor<any, any, any>[] = readonly [],\n >(config: {\n readonly model: ModelRef<AppModel, Store>\n readonly entities: Entities\n readonly queries?: Queries\n readonly mutations?: Mutations\n }): RemoteDomain<AppModel, Store, Entities, Queries, Mutations> =>\n bindDomain(defineRemote(config), config.model),\n\n /**\n * Declares a Remote domain without binding it: its entities, queries, and\n * mutations, plus the submodel. For a domain reused across applications or\n * bound in a test; `Remote.make` is the one-step form.\n */\n define: defineRemote,\n\n /**\n * Binds a Remote domain to its store's location in the application Model. The\n * registered entity names are carried on the returned value, so `Remote.select`\n * rejects a selection for an entity this domain never declared.\n */\n at: bindRemote,\n\n /**\n * A Projection node that reads a `RemoteData` value out of the store. The id\n * is supplied by the caller, usually from a Surface's params. The assembled\n * value is decoded against the Selection, so malformed server data surfaces\n * as `Failed` instead of being asserted into `Value`. A present value with a\n * stale field reads as `Refreshing`: an observer is refetching it.\n */\n select: <AppModel, Store extends RemoteModel, Names extends string, Value, Name extends string>(\n bound: BoundRemote<AppModel, Store, Names>,\n selection: Selection<Value, Name, 'entity'> & Registered<Name, Names, 'Entity'>,\n ) => {\n assertRegistered(bound, 'Entity', bound.definition.registry.entities, selection.entity)\n const relation = relationOf(selection)\n return (id: string): Projection<AppModel, RemoteData<Value>> => ({\n Model: remoteDataSchema(selection.schema),\n dependencies: [],\n requirements: [{ ...relation, id }],\n connections: [],\n read: (root: AppModel): RemoteData<Value> => {\n const store = storeOf(bound, root)\n const key = entityKey(selection.entity, id)\n return memoRead(store, store, `${key}\\u0000${stableStringify(relation)}`, () => {\n if (isTombstone(store, key)) return { _tag: 'NotFound' }\n const assembled = assemble(store, key, relation)\n if (assembled === undefined) return { _tag: 'Initial' }\n const decoded = Schema.decodeUnknownResult(selection.schema)(assembled.values)\n return Result.isFailure(decoded)\n ? { _tag: 'Failed', error: { _tag: 'DecodeError', message: decoded.failure.message } }\n : assembled.refreshing\n ? { _tag: 'Refreshing', value: decoded.success }\n : { _tag: 'Ready', value: decoded.success }\n })\n },\n })\n },\n\n /**\n * The pure plan for a projection against a Model: the requirements its\n * remote store does not satisfy, under `options` (freshness, force). A\n * Surface's projection is `surface.projection(params)`.\n */\n plan: <AppModel, Store extends RemoteModel, Value>(\n bound: BoundRemote<AppModel, Store>,\n model: AppModel,\n projection: Projection<AppModel, Value>,\n options?: PlanOptions,\n ): ReadonlyArray<Requirement> =>\n planAsked(bound.store.get(model), projection, options ?? {}).requirements,\n\n /**\n * The queries a projection needs run before its connections read: those the\n * Model does not hold, or holds stale (every one under `force`).\n */\n planQueries: <AppModel, Store extends RemoteModel, Value>(\n bound: BoundRemote<AppModel, Store>,\n model: AppModel,\n projection: Projection<AppModel, Value>,\n options?: PlanOptions,\n ): ReadonlyArray<QueryRef<string, unknown>> =>\n planAsked(bound.store.get(model), projection, options ?? {}).queries.flatMap(query =>\n query.ref === undefined ? [] : [query.ref],\n ),\n\n /**\n * The store reads see: the base store under the pending optimistic layers.\n * One store is shared by every read and plan of a Model whose remote state\n * has not changed.\n */\n storeOf: <AppModel, Store extends RemoteModel>(\n bound: BoundRemote<AppModel, Store>,\n model: AppModel,\n ): EntityStore => storeOf(bound, model),\n\n /**\n * Executes the plan against the `RemoteClient` and returns a new store. Used\n * for SSR route prefetch, hover prefetch, and tests. Never called during render.\n * `policy` decides what a present field means (default cache-first); `now`\n * is the clock it reads, so the planner itself stays pure and time-injected.\n */\n prefetch: Effect.fn('Remote.prefetch')(function* <AppModel, Store extends RemoteModel, Value>(\n bound: BoundRemote<AppModel, Store>,\n model: AppModel,\n projection: Projection<AppModel, Value>,\n options: ObserveOptions = {},\n ) {\n const store = storeOf(bound, model)\n const { policy = RemotePolicy.cacheFirst, now = Date.now } = options\n const at = now()\n const missing = plan(store, projection.requirements, RemotePolicy.toPlan(policy, at))\n if (missing.length === 0) return store\n yield* Effect.annotateCurrentSpan('requirementCount', missing.length)\n const client = yield* RemoteClient\n const result = yield* client.read({ version: REMOTE_PROTOCOL_VERSION, requests: missing })\n return writeRead(store, missing, result, at)\n }),\n\n /**\n * Writes a read result into the store, recording each field's applied window.\n * `requests` are the planned requirements the result answers.\n */\n writeRead,\n\n /**\n * Adapts an Effect RPC client for `RemoteRpc` to `RemoteClient`, so an\n * application provides the transport's RPC layer instead of writing the\n * `LiveChange`-to-`LiveEvent` mapping by hand.\n */\n clientLayer: <R = never>(\n client: RemoteRpcClient<R>,\n options: CoalesceOptions = {},\n ): Layer.Layer<RemoteClient, never, R> =>\n coalescedLayer(\n Layer.effect(\n RemoteClient,\n Effect.gen(function* () {\n // What the RPC client needs (a database under in-process handlers,\n // nothing under a transport) is supplied once, when the layer is built.\n const context = yield* Effect.context<R>()\n return {\n read: batch => client.FoldkitRemoteRead(batch).pipe(Effect.provideContext(context)),\n query: request =>\n client.FoldkitRemoteQuery(request).pipe(Effect.provideContext(context)),\n mutate: request =>\n client.FoldkitRemoteMutate(request).pipe(Effect.provideContext(context)),\n live: ({ requirements, after }) =>\n client\n .FoldkitRemoteLive({ version: REMOTE_PROTOCOL_VERSION, requirements, after })\n .pipe(Stream.map(liveEventOf), Stream.provideContext(context)),\n }\n }),\n ),\n options,\n ),\n\n /**\n * Wraps a `RemoteClient` layer so its reads coalesce: requirements issued\n * together become one batch, and a requirement already in flight is joined.\n * `Remote.clientLayer` applies this; use it on a hand-written client.\n */\n coalesced: coalescedLayer,\n\n /**\n * A Foldkit Subscription entry that keeps the cache to what the active\n * Surfaces reach. `projections` are the ones the application observes (the\n * same it passes to `Remote.observe`), `connections` the query connections\n * it shows; anything else is collected once the roots have been stable for\n * `grace`, so a route transition that comes straight back does not thrash.\n */\n retain: <AppModel, Message = RemoteMessage>(\n projections: ReadonlyArray<Projection<AppModel, unknown>>,\n toMessage: (message: RemoteMessage) => Message = identityMessage as never,\n options: RetainOptions = {},\n ): EntryWithoutKeepAlive<AppModel, Message, RetentionRoots, never> => {\n const roots = rootsOf(projections, options)\n return {\n dependenciesSchema: retentionRootsSchema,\n modelToDependencies: () => roots,\n dependenciesToStream: current =>\n Stream.fromEffect(\n Effect.succeed(toMessage({ _tag: 'RetentionChanged', roots: current })).pipe(\n Effect.delay(options.grace ?? 0),\n ),\n ),\n }\n },\n\n /**\n * Runs a `Query` through `RemoteClient`, encoding its input from the ref.\n * Pair the result with `Remote.queryMessage` to merge the page into the Model.\n */\n query: Effect.fn('Remote.query')(function* <Name extends string, Input>(\n ref: QueryRef<Name, Input>,\n ) {\n const client = yield* RemoteClient\n const input = yield* Schema.encodeUnknownEffect(ref.Input)(ref.input).pipe(\n Effect.catchTag('SchemaError', error =>\n Effect.fail(new RemoteQueryError({ message: error.message })),\n ),\n )\n return yield* client.query({ query: ref.query, input, window: ref.window })\n }),\n\n /** The `RemoteMessage` that merges a query page into its connection. */\n queryMessage: <Name extends string, Input>(\n ref: QueryRef<Name, Input>,\n result: Schema.Schema.Type<typeof QueryResult>,\n ): RemoteMessage => pageMessage(ref.identity, result),\n\n /**\n * The edges a connection shows: its server-known region with pending and\n * confirmed overlays placed around it, minus removed edges and edges whose\n * target is a tombstone.\n */\n visibleItems: (model: RemoteModel, connection: ConnectionIdentity): ReadonlyArray<Edge> => {\n const identity = connectionIdentity(connection)\n return visibleItems(\n model.connections[identity] ?? emptyConnection,\n identity,\n model.optimistic.overlays,\n model.entities,\n )\n },\n\n /** A pure, serializable view of the whole cache. */\n inspect: inspectRemote,\n\n /** A pure, serializable view of one entity, or `undefined` if unknown. */\n inspectEntity,\n\n /**\n * Runs a mutation through `RemoteClient`, decoding its typed Output and\n * returning the result's normalized patches so the caller can reconcile them\n * through `Remote.update`'s `MutationSucceeded` (or `Remote.mutateInto`).\n */\n mutate: mutateRemote,\n\n /**\n * Runs a mutation and reconciles its patches into a `RemoteModel` in one step,\n * returning the new model alongside the typed Output. The model-level form of\n * `MutationStarted` → `RemoteClient.mutate` → `MutationSucceeded`; in an\n * application the three are `update` (with `optimistic`), a Command, and the\n * Message the Command returns, so the optimistic operations show meanwhile.\n */\n mutateInto: Effect.fn('Remote.mutateInto')(function* <\n Name extends string,\n Input,\n Output,\n AppModel,\n Store extends RemoteModel,\n >(\n bound: BoundRemote<AppModel, Store>,\n model: AppModel,\n mutation: MutationDescriptor<Name, Input, Output>,\n input: Input,\n requestId: string,\n options: MutateOptions = {},\n ) {\n const started = updateRemote(bound.store.get(model), {\n _tag: 'MutationStarted',\n requestId,\n ...(options.optimistic === undefined ? {} : { optimistic: options.optimistic }),\n })\n const outcome = yield* mutateRemote(mutation, input, requestId)\n const settled = updateRemote(started, {\n _tag: 'MutationSucceeded',\n requestId,\n entities: outcome.entities,\n connections: outcome.connections,\n })\n return {\n output: outcome.output,\n model: bound.store.set(model, settled as Store),\n }\n }),\n\n /**\n * A Foldkit Subscription entry that plans a Surface's missing fields from the\n * Model and fetches them through `RemoteClient`, emitting a `RemoteMessage`\n * per outcome. Wrap it in an application Message (`toMessage`) and reduce it\n * with the domain's `update`. Under a refreshing `policy` the entry first\n * emits `RefreshStarted`, so the fields being refetched read as `Refreshing`\n * while the request is pending.\n */\n observe: <\n AppModel,\n Store extends RemoteModel,\n Names extends string,\n Model,\n SurfaceMessage,\n Params,\n Message = RemoteMessage,\n >(\n bound: BoundRemote<AppModel, Store, Names>,\n surface: Surface<AppModel, Model, SurfaceMessage, Params>,\n params: Params,\n toMessage: (message: RemoteMessage) => Message = identityMessage as never,\n options: ObserveOptions = {},\n ): EntryWithoutKeepAlive<AppModel, Message, ReadDependencies, RemoteClient> =>\n observeEntry(bound, () => surface.projection(params), toMessage, options),\n\n /**\n * A Foldkit Subscription entry that consumes the live stream for a Surface's\n * requirements, emitting a `LiveReceived` per event and a `ReadFailed` when\n * the stream breaks (including `ResumeUnavailable`). The resume cursor is read\n * from `RemoteModel.live`, so the application tracks no cursor of its own.\n */\n live: <\n AppModel,\n Store extends RemoteModel,\n Names extends string,\n Model,\n SurfaceMessage,\n Params,\n Message = RemoteMessage,\n >(\n bound: BoundRemote<AppModel, Store, Names>,\n surface: Surface<AppModel, Model, SurfaceMessage, Params>,\n params: Params,\n toMessage: (message: RemoteMessage) => Message = identityMessage as never,\n options: LiveOptions = {},\n ): EntryWithoutKeepAlive<\n AppModel,\n Message,\n { readonly requirements: ReadonlyArray<Requirement>; readonly cursor: LiveCursor },\n RemoteClient\n > => liveEntry(bound, () => surface.projection(params).requirements, toMessage, options),\n}\n\n/** The bound domain: the descriptor, the binding, and the operations over them. */\nconst bindDomain = <\n AppModel,\n Store extends RemoteModel,\n Entities extends readonly EntityDescriptor<any, any>[],\n Queries extends readonly QueryDescriptor<any, any, any>[],\n Mutations extends readonly MutationDescriptor<any, any, any>[],\n>(\n definition: RemoteDescriptor<Entities, Queries, Mutations>,\n store: ModelRef<AppModel, Store>,\n): RemoteDomain<AppModel, Store, Entities, Queries, Mutations> => {\n const bound = bindRemote(definition, store)\n // An application-union case has the runtime shape of the `RemoteMessage` it names.\n const reduce = (model: AppModel, message: RemoteMessage | RemoteMessageInput): AppModel =>\n store.set(model, updateRemote(store.get(model), message as RemoteMessage) as Store)\n return {\n ...definition,\n ...bound,\n get: (selection, id) => Remote.select(bound, selection)(id),\n live: (selection, id) => {\n const projection = Remote.select(bound, selection)(id)\n return {\n ...projection,\n requirements: projection.requirements.map(requirement => ({ ...requirement, live: true })),\n }\n },\n subscriptions: (active, options = {}) => {\n // Dependencies differ per entry, as in Foldkit's own `Subscriptions` record.\n const entries: Record<string, RemoteEntry<AppModel, any>> = {}\n const projections: Array<(model: AppModel) => Projection<AppModel, unknown> | undefined> = []\n for (const [key, entry] of Object.entries(active)) {\n // Two applications can have the same Model type; the owner token tells them apart.\n if (bound.contract.owner !== undefined && entry.owner !== bound.contract.owner) {\n throw new Error(\n `Remote: Surface \"${entry.name}\" belongs to another application than domain \"${bound.contract.name}\"`,\n )\n }\n const projectionAt = memoizedProjectionOf(entry)\n projections.push(projectionAt)\n const asked = (model: AppModel) => askedOf(projectionAt(model))\n entries[`${key}.read`] = observeEntry(bound, asked, identityMessage, options)\n entries[`${key}.live`] = liveEntry(\n bound,\n model => asked(model).requirements.filter(requirement => requirement.live === true),\n identityMessage,\n options,\n )\n }\n entries.retain = {\n dependenciesSchema: retentionRootsSchema,\n modelToDependencies: model =>\n rootsOf(\n projections.flatMap(projectionAt => {\n const projection = projectionAt(model)\n return projection === undefined ? [] : [projection]\n }),\n options,\n ),\n dependenciesToStream: (current: RetentionRoots) =>\n Stream.fromEffect(\n Effect.succeed<RemoteMessage>({ _tag: 'RetentionChanged', roots: current }).pipe(\n Effect.delay(options.grace ?? 0),\n ),\n ),\n }\n return entries\n },\n plan: (model, projection, options) => Remote.plan(bound, model, projection, options),\n storeOf: model => storeOf(bound, model),\n prefetch: (model, projection, options = {}) =>\n Effect.gen(function* () {\n const { policy = RemotePolicy.cacheFirst, now = Date.now } = options\n const client = yield* RemoteClient\n const planOptions = RemotePolicy.toPlan(policy, now())\n let current = model\n // The pages first, so their items join the one entity read below.\n for (const query of planAsked(store.get(current), projection, planOptions).queries) {\n const page = yield* queryRequestOf(query).pipe(\n Effect.flatMap(request => client.query(request)),\n )\n current = reduce(current, pageMessage(query.identity, page, true))\n }\n const requirements = planAsked(store.get(current), projection, planOptions).requirements\n if (requirements.length === 0) return current\n const at = now()\n const result = yield* client.read({\n version: REMOTE_PROTOCOL_VERSION,\n requests: requirements,\n })\n return reduce(current, { _tag: 'ReadReceived', requests: requirements, result, now: at })\n }),\n query: <Q extends QueryDescriptor<any, any, any>, Value, Entity extends string>(\n query: Q,\n input: QueryInput<Q>,\n options: QueryOptions<Value, Entity, QueryEntity<Q>>,\n ): QueryProjection<AppModel, Value, Q['name'], QueryInput<Q>> => {\n assertRegistered(bound, 'Query', definition.registry.queries, query.name)\n const { select, ...window } = options\n for (const [side, size] of [\n ['first', window.first],\n ['last', window.last],\n ] as const) {\n if (size !== undefined && !(Number.isInteger(size) && size >= 0)) {\n throw new Error(\n `Remote: query \"${query.name}\" asks for ${side}: ${String(size)}; a page size is a non-negative integer`,\n )\n }\n }\n const listed = (query.Result as Partial<ConnectionSpec>).entity\n if (listed === undefined) {\n throw new Error(\n `Remote: query \"${query.name}\" is not a connection over an entity, so it has no page to select`,\n )\n }\n if (select.entity !== listed) {\n throw new Error(\n `Remote: the selection is of \"${select.entity}\", but query \"${query.name}\" lists \"${listed}\"`,\n )\n }\n const ref: QueryRef<Q['name'], QueryInput<Q>> = {\n ...query.ref(input),\n window: pickWindow(window),\n }\n const relation = relationOf(select)\n const relationKey = stableStringify(relation)\n const requirement: QueryRequirement = {\n identity: ref.identity,\n window: ref.window,\n select: relation,\n ref,\n }\n return {\n Model: remoteDataSchema(pageSchema(select.schema)) as Schema.Schema<\n RemoteData<Page<Value>>\n >,\n dependencies: [],\n requirements: [],\n connections: [requirement],\n ref,\n read: (root: AppModel): RemoteData<Page<Value>> => {\n const remote = store.get(root)\n const connection = remote.connections[ref.identity]\n // Invalidating a connection the Model never loaded records it stale with no\n // segments: still nothing to show. (A loaded empty page is not stale.)\n if (connection === undefined || (connection.stale && connection.segments.length === 0)) {\n return { _tag: 'Initial' }\n }\n const visible = visibleStoreOf(remote.entities, remote.optimistic)\n return memoRead(visible, connection, `${ref.identity}\\u0000${relationKey}`, () => {\n const items: Value[] = []\n let refreshing = connection.stale\n const edges = visibleItems(\n connection,\n ref.identity,\n remote.optimistic.overlays,\n remote.entities,\n )\n for (const edge of edges) {\n const assembled = assemble(visible, entityKey(edge.ref.entity, edge.ref.id), relation)\n if (assembled === undefined) return { _tag: 'Initial' }\n const decoded = Schema.decodeUnknownResult(select.schema)(assembled.values)\n if (Result.isFailure(decoded)) {\n return {\n _tag: 'Failed',\n error: { _tag: 'DecodeError', message: decoded.failure.message },\n }\n }\n refreshing ||= assembled.refreshing\n items.push(decoded.success)\n }\n const page = {\n items,\n hasNext: hasNext(connection),\n hasPrevious: hasPrevious(connection),\n }\n return refreshing ? { _tag: 'Refreshing', value: page } : { _tag: 'Ready', value: page }\n })\n },\n }\n },\n next: (model, projection) => {\n const segments = store.get(model).connections[projection.ref.identity]?.segments ?? []\n const end = segments[segments.length - 1]?.end\n return end?._tag === 'Cursor'\n ? {\n ...projection.ref,\n window: { ...pageSize(projection.ref.window, 'first'), after: end.cursor },\n }\n : undefined\n },\n previous: (model, projection) => {\n const start = store.get(model).connections[projection.ref.identity]?.segments[0]?.start\n return start?._tag === 'Cursor'\n ? {\n ...projection.ref,\n window: { ...pageSize(projection.ref.window, 'last'), before: start.cursor },\n }\n : undefined\n },\n fetch: ref => ({\n name: `Remote.query(${ref.query})`,\n args: { connection: ref.identity, window: ref.window },\n effect: Remote.query(ref).pipe(\n Effect.match({\n onFailure: (error): RemoteMessage => ({\n _tag: 'QueryFailed',\n connection: ref.identity,\n error: remoteError(error),\n }),\n onSuccess: (page): RemoteMessage => pageMessage(ref.identity, page),\n }),\n ),\n }),\n mutate: (model, mutation, input, options = {}) => {\n assertRegistered(bound, 'Mutation', definition.registry.mutations, mutation.name)\n const remote = store.get(model)\n const requestId =\n options.requestId ?? `${bound.contract.name}-${remote.mutations.sequence + 1}`\n const tempId = `${requestId}.tmp`\n const optimistic =\n typeof options.optimistic === 'function'\n ? options.optimistic({ requestId, tempId })\n : options.optimistic\n const started = updateRemote(remote, {\n _tag: 'MutationStarted',\n requestId,\n ...(optimistic === undefined ? {} : { optimistic }),\n })\n return {\n model: store.set(model, started as Store),\n requestId,\n tempId,\n command: {\n name: `Remote.mutate(${mutation.name})`,\n args: { requestId },\n effect: mutateRemote(mutation, input, requestId).pipe(\n Effect.match({\n onFailure: (error): RemoteMessage => ({\n _tag: 'MutationFailed',\n requestId,\n error: remoteError(error),\n }),\n onSuccess: (outcome): RemoteMessage => ({\n _tag: 'MutationSucceeded',\n requestId,\n entities: outcome.entities,\n connections: outcome.connections,\n }),\n }),\n ),\n },\n }\n },\n reduce,\n inspect: model => inspectRemote(store.get(model)),\n }\n}\n\n/** The window keys of a `QueryOptions`, and only those, without the undefined ones. */\nconst pickWindow = (window: QueryWindowOptions): QueryWindow => ({\n ...(window.first === undefined ? {} : { first: window.first }),\n ...(window.last === undefined ? {} : { last: window.last }),\n ...(window.after === undefined ? {} : { after: window.after }),\n ...(window.before === undefined ? {} : { before: window.before }),\n})\n\n/** The page size of a window, carried onto the next or previous page's window under `key`. */\nconst pageSize = (window: QueryWindow, key: 'first' | 'last'): QueryWindow => {\n const size = window.first ?? window.last\n return size === undefined ? {} : { [key]: size }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/store.ts","../src/mutation.ts","../src/query.ts","../src/wire.ts","../src/coalesce.ts","../src/client.ts","../src/connection.ts","../src/inspect.ts","../src/optimistic.ts","../src/live.ts","../src/relation.ts","../src/plan.ts","../src/retain.ts","../src/persistence.ts","../src/remoteData.ts","../src/model.ts","../src/policy.ts","../src/entity.ts","../src/selection.ts","../src/index.ts"],"sourcesContent":["/**\n * The pure entity store: values, per-field presence, staleness, and tombstones.\n *\n * Presence is tracked **separately** from values, so `undefined`/`null`/absent/\n * stale/not-found are distinct states and a missing field is never inferred from\n * `value === undefined`. Nothing here performs I/O; every operation returns a\n * new store.\n */\nimport { Option } from 'effect'\n\nexport type EntityKey = string\n\nexport interface EntityEntry {\n readonly values: Readonly<Record<string, unknown>>\n readonly present: ReadonlySet<string>\n /** Present fields whose value may be outdated (revalidation needed). */\n readonly stale: ReadonlySet<string>\n /** The entity is known to be absent; a later write clears this. */\n readonly tombstone: boolean\n /** Injected clock reading of the last write; never read from ambient state. */\n readonly updatedAt: number\n /**\n * The canonical window each present field was fetched with (`\"\"` for none).\n * A later request with a *known, different* window is planned as missing.\n */\n readonly windows: Readonly<Record<string, string>>\n}\n\nexport type EntityStore = Readonly<Record<EntityKey, EntityEntry>>\n\n/** The separator keeps an untrusted id from colliding with a prototype key. */\nexport const entityKey = (entity: string, id: string): EntityKey => `${entity}:${id}`\n\nconst emptyEntry: EntityEntry = {\n values: {},\n present: new Set(),\n stale: new Set(),\n tombstone: false,\n updatedAt: 0,\n windows: {},\n}\n\nexport const emptyStore: EntityStore = {}\n\nconst replace = (store: EntityStore, key: EntityKey, entry: EntityEntry): EntityStore => ({\n ...store,\n [key]: entry,\n})\n\nconst written = (\n previous: EntityEntry,\n values: Readonly<Record<string, unknown>>,\n now: number,\n windows?: Readonly<Record<string, string>>,\n): EntityEntry => {\n const present = new Set(previous.present)\n const stale = new Set(previous.stale)\n const nextWindows: Record<string, string> = { ...previous.windows }\n for (const field of Object.keys(values)) {\n present.add(field)\n stale.delete(field)\n // A write without a window clears any remembered one: the value changed.\n const requested = windows?.[field]\n if (requested !== undefined && requested !== '') nextWindows[field] = requested\n else delete nextWindows[field]\n }\n return {\n values: { ...previous.values, ...values },\n present,\n stale,\n tombstone: false,\n updatedAt: now,\n windows: nextWindows,\n }\n}\n\nexport interface EntityWrite {\n readonly key: EntityKey\n readonly values: Readonly<Record<string, unknown>>\n /** The canonical window each written relation field was fetched with. */\n readonly windows?: Readonly<Record<string, string>> | undefined\n}\n\n/**\n * Merges known values into many entities, copying the store once. Every\n * written field becomes present and non-stale; a tombstone is cleared because\n * the entity is evidently not absent.\n */\nexport const writeEntities = (\n store: EntityStore,\n writes: ReadonlyArray<EntityWrite>,\n now = 0,\n): EntityStore => {\n if (writes.length === 0) return store\n const next: Record<EntityKey, EntityEntry> = { ...store }\n for (const write of writes) {\n next[write.key] = written(next[write.key] ?? emptyEntry, write.values, now, write.windows)\n }\n return next\n}\n\n/** `writeEntities` for one entity. */\nexport const writeEntity = (\n store: EntityStore,\n key: EntityKey,\n values: Readonly<Record<string, unknown>>,\n now = 0,\n windows?: Readonly<Record<string, string>>,\n): EntityStore => writeEntities(store, [{ key, values, windows }], now)\n\n/**\n * Marks present fields stale (`true`) or ends their staleness (`false`) across\n * many entities, copying the store once. A field never present stays missing;\n * an unknown entity is left alone.\n */\nexport const setStale = (\n store: EntityStore,\n marks: ReadonlyArray<readonly [key: EntityKey, fields: Iterable<string>]>,\n stale: boolean,\n): EntityStore => {\n let next: Record<EntityKey, EntityEntry> | undefined\n for (const [key, fields] of marks) {\n const previous = (next ?? store)[key]\n if (previous === undefined) continue\n const staleFields = new Set(previous.stale)\n for (const field of fields) {\n if (stale) {\n if (previous.present.has(field)) staleFields.add(field)\n } else staleFields.delete(field)\n }\n next ??= { ...store }\n next[key] = { ...previous, stale: staleFields }\n }\n return next ?? store\n}\n\n/** Marks present fields stale; fields that were never present stay missing. */\nexport const markStale = (\n store: EntityStore,\n key: EntityKey,\n fields: Iterable<string>,\n): EntityStore => setStale(store, [[key, fields]], true)\n\n/** Ends a refresh that did not land: the fields are present again as they were. */\nexport const clearStale = (\n store: EntityStore,\n key: EntityKey,\n fields: Iterable<string>,\n): EntityStore => setStale(store, [[key, fields]], false)\n\n/** Records that the entity is known to be absent, so it is not refetched. */\nexport const tombstone = (store: EntityStore, key: EntityKey): EntityStore =>\n replace(store, key, {\n values: {},\n present: new Set(),\n stale: new Set(),\n tombstone: true,\n updatedAt: 0,\n windows: {},\n })\n\n/** Forgets everything known about the entity, including a tombstone. */\nexport const remove = (store: EntityStore, key: EntityKey): EntityStore => {\n if (store[key] === undefined) return store\n const next = { ...store }\n delete next[key]\n return next\n}\n\nexport const entry = (store: EntityStore, key: EntityKey): Option.Option<EntityEntry> => {\n const value = store[key]\n return value === undefined ? Option.none() : Option.some(value)\n}\n\nexport const isTombstone = (store: EntityStore, key: EntityKey): boolean =>\n store[key]?.tombstone === true\n\n/** A field is known only if it is present and not stale. */\nexport const hasField = (store: EntityStore, key: EntityKey, field: string): boolean => {\n const value = store[key]\n return (\n value !== undefined && !value.tombstone && value.present.has(field) && !value.stale.has(field)\n )\n}\n\n/** A present field whose value may be outdated; absent fields are not stale. */\nexport const isFieldStale = (store: EntityStore, key: EntityKey, field: string): boolean => {\n const value = store[key]\n return value !== undefined && !value.tombstone && value.stale.has(field)\n}\n\n/**\n * Reads a present field, stale or not. Absence and a tombstone both yield\n * `Option.none()`; a present `undefined`/`null` yields `Option.some`.\n */\nexport const readField = (\n store: EntityStore,\n key: EntityKey,\n field: string,\n): Option.Option<unknown> => {\n const value = store[key]\n if (value === undefined || value.tombstone || !value.present.has(field)) return Option.none()\n return Option.some(value.values[field])\n}\n\n/**\n * The fields the planner must fetch. A tombstone makes every field known\n * (absent), so it returns an empty list and the entity is not refetched. A\n * requested window that differs from the one a field was fetched with also\n * marks it missing, but only when the stored window is known (never `\"\"`), so a\n * writer that does not record windows cannot cause a refetch loop.\n */\nexport const missingFields = (\n store: EntityStore,\n key: EntityKey,\n fields: Iterable<string>,\n windows?: Readonly<Record<string, string>>,\n): ReadonlyArray<string> => {\n const value = store[key]\n if (value !== undefined && value.tombstone) return []\n return [...fields].filter(field => {\n if (value === undefined || !value.present.has(field) || value.stale.has(field)) return true\n const requested = windows?.[field]\n const stored = value.windows[field]\n return requested !== undefined && stored !== undefined && stored !== '' && stored !== requested\n })\n}\n","/**\n * Mutation status and idempotent reconciliation.\n *\n * A mutation result is reconciled into the store **at most once per\n * `requestId`**, so a transport retry cannot apply the same change twice. An\n * unknown or already-applied result is a no-op.\n */\nimport { Schema } from 'effect'\nimport { entityKey, writeEntity, type EntityStore } from './store.js'\n\nexport interface NormalizedPatch {\n readonly entity: string\n readonly id: string\n readonly values: Readonly<Record<string, unknown>>\n}\n\nexport interface MutationState {\n readonly pending: ReadonlySet<string>\n readonly applied: ReadonlySet<string>\n readonly failed: ReadonlySet<string>\n /**\n * How many mutations this model has started. A bound domain takes its next\n * request id from here, so `update` stays pure and the id exists before the\n * Command runs.\n */\n readonly sequence: number\n}\n\nexport const emptyMutationState: MutationState = {\n pending: new Set(),\n applied: new Set(),\n failed: new Set(),\n sequence: 0,\n}\n\n/**\n * How many settled request ids a mutation state retains. A retry settles well\n * inside this window, so bounding the ledger stops a long-lived application\n * from growing it without limit; a retry older than the window would re-apply\n * its entities.\n */\nconst MUTATION_ID_WINDOW = 1024\n\n/** Records `id` as most recent, evicting the oldest once the window is full. */\nconst remember = (ids: ReadonlySet<string>, id: string): ReadonlySet<string> => {\n const next = new Set(ids)\n // Re-inserting an existing id moves it to the most-recent end.\n next.delete(id)\n next.add(id)\n if (next.size <= MUTATION_ID_WINDOW) return next\n return new Set([...next].slice(next.size - MUTATION_ID_WINDOW))\n}\n\nexport const beginMutation = (state: MutationState, requestId: string): MutationState => ({\n ...state,\n pending: new Set([...state.pending, requestId]),\n sequence: state.sequence + 1,\n})\n\nexport const failMutation = (state: MutationState, requestId: string): MutationState => {\n const pending = new Set(state.pending)\n pending.delete(requestId)\n return { ...state, pending, failed: remember(state.failed, requestId) }\n}\n\nexport interface Reconciled {\n readonly store: EntityStore\n readonly state: MutationState\n}\n\n/**\n * Applies a mutation result once and marks the request settled. A second call\n * with the same `requestId` (a retry, or a live event describing the same change)\n * does not re-apply the entities, but still clears `pending`.\n */\nexport const reconcileMutation = (\n store: EntityStore,\n state: MutationState,\n requestId: string,\n entities: ReadonlyArray<NormalizedPatch>,\n): Reconciled => {\n const next = state.applied.has(requestId)\n ? store\n : entities.reduce(\n (current, entity) =>\n writeEntity(current, entityKey(entity.entity, entity.id), entity.values),\n store,\n )\n const applied = remember(state.applied, requestId)\n const pending = new Set(state.pending)\n pending.delete(requestId)\n return { store: next, state: { ...state, applied, pending } }\n}\n\n/** A mutation an application declares: its name and input/output codecs. */\nexport interface MutationDescriptor<Name extends string, Input, Output> {\n readonly name: Name\n readonly Input: Schema.Codec<Input>\n readonly Output: Schema.Codec<Output>\n}\n\n/** A codec, or the fields of a `Schema.Struct` where one is expected. */\nexport type SchemaOrFields = Schema.Codec<any, any, any, any> | Schema.Struct.Fields\n\n/** The decoded type of a codec, or of the Struct the fields describe. */\nexport type TypeOf<S extends SchemaOrFields> =\n S extends Schema.Codec<infer T, any, any, any>\n ? T\n : S extends Schema.Struct.Fields\n ? Schema.Struct.Type<S>\n : never\n\n/** The codec itself, or a `Schema.Struct` over the fields. */\nexport const schemaOf = <S extends SchemaOrFields>(shape: S): Schema.Codec<TypeOf<S>> =>\n (Schema.isSchema(shape) ? shape : Schema.Struct(shape as Schema.Struct.Fields)) as Schema.Codec<\n TypeOf<S>\n >\n\nexport const Mutation = {\n /**\n * Declares a mutation. `Input` and `Output` are codecs, or the fields of the\n * `Schema.Struct` they would be (`{ id: ProjectId, name: Schema.String }`).\n */\n make: <const Name extends string, Input extends SchemaOrFields, Output extends SchemaOrFields>(\n name: Name,\n config: { readonly Input: Input; readonly Output: Output },\n ): MutationDescriptor<Name, TypeOf<Input>, TypeOf<Output>> => ({\n name,\n Input: schemaOf(config.Input),\n Output: schemaOf(config.Output),\n }),\n}\n","/**\n * Queries and connections. A connection's identity is its descriptor plus the\n * canonical encoded filter/sort input — **never** the pagination window, so\n * `first(25)` and `after(cursor).first(25)` address the same logical connection.\n */\nimport { Schema } from 'effect'\nimport type { Cursor } from './connection.js'\nimport { schemaOf, type SchemaOrFields, type TypeOf } from './mutation.js'\n\nexport type LiveInsertion = 'visible' | 'boundary' | 'invalidate' | 'ignore'\n\nexport interface LivePolicy {\n readonly prepend?: LiveInsertion\n readonly append?: LiveInsertion\n}\n\nexport interface ConnectionSpec<Entity extends string = string> {\n readonly entity: Entity\n readonly edgeKey?: Schema.Schema<unknown>\n readonly live?: LivePolicy\n}\n\nexport interface QueryWindow {\n readonly first?: number | undefined\n readonly last?: number | undefined\n readonly after?: Cursor | undefined\n readonly before?: Cursor | undefined\n}\n\nexport interface QueryRef<Name extends string, Input> {\n readonly query: Name\n readonly input: Input\n /** The input codec, so a `QueryRef` can encode itself without its descriptor. */\n readonly Input: Schema.Codec<Input>\n readonly window: QueryWindow\n /** Connection identity: descriptor + canonical input, excluding the window. */\n readonly identity: string\n}\n\nexport interface QueryDescriptor<Name extends string, Input, Result> {\n readonly name: Name\n readonly Input: Schema.Codec<Input>\n readonly Result: Result\n readonly ref: (input: Input) => QueryRef<Name, Input>\n}\n\n/** Stable stringify: object keys sorted, undefined-valued keys dropped, so equal inputs encode equally. */\nexport const stableStringify = (value: unknown): string => {\n if (value === undefined) return 'null'\n if (value === null || typeof value !== 'object') return JSON.stringify(value)\n if (Array.isArray(value)) return `[${value.map(stableStringify).join(',')}]`\n const record = value as Record<string, unknown>\n return `{${Object.keys(record)\n .filter(key => record[key] !== undefined)\n .sort()\n .map(key => `${JSON.stringify(key)}:${stableStringify(record[key])}`)\n .join(',')}}`\n}\n\n/**\n * `Result: Project` (or anything with the entity's `name`, as `Query.connection`\n * takes) means a connection over it; a `ConnectionSpec` names its `entity`\n * instead and is the result as given.\n */\nexport type ResultOf<Result> = Result extends { readonly name: infer Entity extends string }\n ? ConnectionSpec<Entity>\n : Result\n\nconst isEntityName = (result: unknown): result is { readonly name: string } =>\n typeof result === 'object' &&\n result !== null &&\n typeof (result as { readonly name?: unknown }).name === 'string'\n\nexport const Query = {\n /** Declares the entity and options a query's result is a connection over. */\n connection: <Entity extends string>(\n entity: { readonly name: Entity },\n options?: { readonly edgeKey?: Schema.Schema<unknown>; readonly live?: LivePolicy },\n ): ConnectionSpec<Entity> => ({\n entity: entity.name,\n ...(options?.edgeKey === undefined ? {} : { edgeKey: options.edgeKey }),\n ...(options?.live === undefined ? {} : { live: options.live }),\n }),\n\n /**\n * Declares a query. `Input` is a codec or the fields of the `Schema.Struct` it\n * would be; `Result` is a `Query.connection(...)`, or the entity the result is\n * a connection over.\n */\n make: <const Name extends string, Input extends SchemaOrFields, Result>(\n name: Name,\n config: { readonly Input: Input; readonly Result: Result },\n ): QueryDescriptor<Name, TypeOf<Input>, ResultOf<Result>> => {\n const Input = schemaOf(config.Input)\n const encode = Schema.encodeSync(Input)\n return {\n name,\n Input,\n Result: (isEntityName(config.Result)\n ? Query.connection(config.Result)\n : config.Result) as ResultOf<Result>,\n ref: input => ({\n query: name,\n input,\n Input,\n window: {},\n identity: `${name}\\u0000${stableStringify(encode(input))}`,\n }),\n }\n },\n\n first:\n (count: number) =>\n <R extends QueryRef<string, unknown>>(ref: R): R => ({\n ...ref,\n window: { ...ref.window, first: count },\n }),\n\n last:\n (count: number) =>\n <R extends QueryRef<string, unknown>>(ref: R): R => ({\n ...ref,\n window: { ...ref.window, last: count },\n }),\n\n after:\n (cursor: Cursor) =>\n <R extends QueryRef<string, unknown>>(ref: R): R => ({\n ...ref,\n window: { ...ref.window, after: cursor },\n }),\n\n before:\n (cursor: Cursor) =>\n <R extends QueryRef<string, unknown>>(ref: R): R => ({\n ...ref,\n window: { ...ref.window, before: cursor },\n }),\n}\n","/**\n * The Remote wire: Effect RPC semantics over `effect/unstable/rpc`. Remote owns\n * the message shapes; Effect owns the transport. `Make`ing reads batch, mutations\n * preserve order, and live data is a stream.\n */\nimport { Schema } from 'effect'\nimport { Rpc, RpcGroup } from 'effect/unstable/rpc'\nimport type { RelationRequirement, Requirement } from 'foldkit-surface'\n\n/**\n * The read/live protocol version. A batch names the version it speaks and the\n * server refuses a mismatch with `RemoteProtocolError`, so a shape change never\n * drifts silently: bump it whenever `ReadRequest` or `LiveRequirement` change.\n */\nexport const REMOTE_PROTOCOL_VERSION = 3\n\nexport class RemoteReadError extends Schema.TaggedError<RemoteReadError>()('RemoteReadError', {\n message: Schema.String,\n}) {}\n\nexport class RemoteMutationError extends Schema.TaggedError<RemoteMutationError>()(\n 'RemoteMutationError',\n { message: Schema.String },\n) {}\n\nexport class RemoteLiveError extends Schema.TaggedError<RemoteLiveError>()('RemoteLiveError', {\n message: Schema.String,\n}) {}\n\n/** The peer speaks another protocol version; nothing was read. */\nexport class RemoteProtocolError extends Schema.TaggedError<RemoteProtocolError>()(\n 'RemoteProtocolError',\n { message: Schema.String, expected: Schema.Number, received: Schema.Number },\n) {}\n\n/** A page size: a non-negative integer, refused at decode otherwise rather than defaulted. */\nexport const PageSize = Schema.Number.check(Schema.isInt(), Schema.isGreaterThanOrEqualTo(0))\n\nexport const WindowSchema = Schema.Struct({\n first: Schema.optional(PageSize),\n last: Schema.optional(PageSize),\n after: Schema.optional(Schema.String),\n before: Schema.optional(Schema.String),\n})\n\n/** A request may not name more fields of one entity than this; a selection never does. */\nexport const MAX_FIELDS_PER_REQUEST = 256\n/** A selection may not nest relations deeper than this; the wire refuses more. */\nexport const MAX_RELATION_DEPTH = 8\n\nconst Fields = Schema.Array(Schema.String).check(Schema.isMaxLength(MAX_FIELDS_PER_REQUEST))\n\n/**\n * The slice required of a relation's target; the ids come from the parent's\n * refs. Built as `MAX_RELATION_DEPTH` nested structs rather than a recursive\n * schema, so a deeper selection is refused at decode with a schema error.\n */\nconst relationLevel = (depth: number): Schema.Codec<RelationRequirement, RelationRequirement> => {\n const slice = {\n entity: Schema.String,\n fields: Fields,\n windows: Schema.optional(Schema.Record(Schema.String, WindowSchema)),\n }\n // A struct drops an unknown key silently; the last level refuses one instead.\n return (depth === 0\n ? Schema.Struct({ ...slice, relations: Schema.optionalKey(Schema.Never) })\n : Schema.Struct({\n ...slice,\n relations: Schema.optional(Schema.Record(Schema.String, relationLevel(depth - 1))),\n })) as unknown as Schema.Codec<RelationRequirement, RelationRequirement>\n}\n\nexport const RelationRequest = relationLevel(MAX_RELATION_DEPTH - 1)\n\nexport const ReadRequest: Schema.Codec<Requirement, Requirement> = Schema.Struct({\n entity: Schema.String,\n id: Schema.String,\n fields: Fields,\n /** Pagination window per relation field. */\n windows: Schema.optional(Schema.Record(Schema.String, WindowSchema)),\n /** The slice required of each relation field's target, resolved in the same read. */\n relations: Schema.optional(Schema.Record(Schema.String, RelationRequest)),\n}) as unknown as Schema.Codec<Requirement, Requirement>\n\nexport const ReadBatch = Schema.Struct({\n version: Schema.Number,\n requests: Schema.Array(ReadRequest),\n})\n\nexport const NormalizedEntity = Schema.Struct({\n entity: Schema.String,\n id: Schema.String,\n values: Schema.Record(Schema.String, Schema.Unknown),\n})\n\nexport const ReadBatchResult = Schema.Struct({ entities: Schema.Array(NormalizedEntity) })\n\nexport const MutationRequest = Schema.Struct({\n /** Stable across transport retries so a mutation is not applied twice. */\n requestId: Schema.String,\n mutation: Schema.String,\n input: Schema.Unknown,\n})\n\nexport const LiveEdge = Schema.Struct({\n entity: Schema.String,\n id: Schema.String,\n key: Schema.String,\n})\n\n/** A connection change a mutation confirms: the same facts a live event carries, without a cursor. */\nexport const ConnectionChangeSchema = Schema.Union([\n Schema.Struct({\n _tag: Schema.Literal('Insert'),\n connection: Schema.String,\n position: Schema.Union([Schema.Literal('prepend'), Schema.Literal('append')]),\n edge: LiveEdge,\n }),\n Schema.Struct({ _tag: Schema.Literal('Remove'), connection: Schema.String, edge: LiveEdge }),\n])\n\nexport const MutationResult = Schema.Struct({\n output: Schema.Unknown,\n entities: Schema.Array(NormalizedEntity),\n /** Connection changes the mutation made, applied alongside its entity patches. */\n connections: Schema.optional(Schema.Array(ConnectionChangeSchema)),\n})\n\nexport const LiveRequirement = Schema.Struct({\n version: Schema.Number,\n requirements: Schema.Array(ReadRequest),\n /** Resume cursor; events at or before it are duplicates. */\n after: Schema.Number,\n})\n\n/**\n * A live change. Entity changes update the store; connection changes alter\n * membership and ordering; both carry a per-stream cursor.\n */\nexport const LiveChange = Schema.Union([\n Schema.Struct({\n _tag: Schema.Literal('EntityPatched'),\n cursor: Schema.Number,\n entity: Schema.String,\n id: Schema.String,\n values: Schema.Record(Schema.String, Schema.Unknown),\n changed: Schema.Array(Schema.String),\n }),\n Schema.Struct({\n _tag: Schema.Literal('EntityDeleted'),\n cursor: Schema.Number,\n entity: Schema.String,\n id: Schema.String,\n }),\n Schema.Struct({\n _tag: Schema.Literal('ConnectionInsert'),\n cursor: Schema.Number,\n connection: Schema.String,\n position: Schema.Union([Schema.Literal('prepend'), Schema.Literal('append')]),\n edge: LiveEdge,\n }),\n Schema.Struct({\n _tag: Schema.Literal('ConnectionRemove'),\n cursor: Schema.Number,\n connection: Schema.String,\n edge: LiveEdge,\n }),\n Schema.Struct({\n _tag: Schema.Literal('ConnectionInvalidate'),\n cursor: Schema.Number,\n connection: Schema.String,\n }),\n])\n\nexport const Read = Rpc.make('FoldkitRemoteRead', {\n payload: ReadBatch,\n success: ReadBatchResult,\n error: Schema.Union([RemoteReadError, RemoteProtocolError]),\n})\n\nexport const Mutate = Rpc.make('FoldkitRemoteMutate', {\n payload: MutationRequest,\n success: MutationResult,\n error: RemoteMutationError,\n})\n\nexport const Live = Rpc.make('FoldkitRemoteLive', {\n payload: LiveRequirement,\n success: LiveChange,\n error: Schema.Union([RemoteLiveError, RemoteProtocolError]),\n stream: true,\n})\n\nexport class RemoteQueryError extends Schema.TaggedError<RemoteQueryError>()('RemoteQueryError', {\n message: Schema.String,\n}) {}\n\nexport const WireBoundary = Schema.Union([\n Schema.Struct({ _tag: Schema.Literal('Terminal') }),\n Schema.Struct({ _tag: Schema.Literal('Cursor'), cursor: Schema.String }),\n Schema.Struct({ _tag: Schema.Literal('Unknown') }),\n])\n\nexport const QueryRequest = Schema.Struct({\n query: Schema.String,\n input: Schema.Unknown,\n window: WindowSchema,\n})\n\nexport const QueryEdge = Schema.Struct({\n entity: Schema.String,\n id: Schema.String,\n key: Schema.String,\n})\n\nexport const QueryResult = Schema.Struct({\n edges: Schema.Array(QueryEdge),\n start: WireBoundary,\n end: WireBoundary,\n})\n\nexport const QueryRpc = Rpc.make('FoldkitRemoteQuery', {\n payload: QueryRequest,\n success: QueryResult,\n error: RemoteQueryError,\n})\n\nexport const RemoteRpc = RpcGroup.make(Read, Mutate, QueryRpc, Live)\n","/**\n * Read coalescing: every requirement a client asks for goes through one\n * `RequestResolver`, so requirements issued together become one `ReadBatch`\n * (ids batched, fields unioned) and a requirement already in flight is joined\n * rather than re-requested. The planner stays pure; this is the transport\n * seam's concern, and the store is still the only cache.\n */\nimport {\n Deferred,\n Duration,\n Effect,\n Request,\n RequestResolver,\n type Exit,\n type Schema,\n} from 'effect'\nimport { Requirement, type RelationRequirement } from 'foldkit-surface'\nimport { stableStringify } from './query.js'\nimport {\n REMOTE_PROTOCOL_VERSION,\n type QueryRequest,\n type QueryResult,\n type ReadBatch,\n type ReadBatchResult,\n} from './wire.js'\nimport type { RemoteProtocolError, RemoteQueryError, RemoteReadError } from './wire.js'\n\ntype Batch = Schema.Schema.Type<typeof ReadBatch>\ntype BatchResult = Schema.Schema.Type<typeof ReadBatchResult>\ntype ReadError = RemoteReadError | RemoteProtocolError\nexport type BatchRead = (batch: Batch) => Effect.Effect<BatchResult, ReadError>\ntype QueryRequestValue = Schema.Schema.Type<typeof QueryRequest>\ntype QueryResultValue = Schema.Schema.Type<typeof QueryResult>\nexport type QueryRun = (\n request: QueryRequestValue,\n) => Effect.Effect<QueryResultValue, RemoteQueryError>\n\nexport interface CoalesceOptions {\n /**\n * How long a batch waits to collect more requirements before it runs.\n * Requirements issued concurrently coalesce even at the default of no wait.\n */\n readonly window?: Duration.Input | undefined\n}\n\n/** A stable key for a requirement, so an equal requirement in flight is joined. */\nexport const requirementKey = (requirement: Requirement): string =>\n stableStringify([\n requirement.entity,\n requirement.id,\n [...requirement.fields].sort(),\n requirement.windows ?? null,\n requirement.relations ?? null,\n ])\n\n/** Whether a requirement pages a relation anywhere in its graph. */\nconst hasWindows = (requirement: RelationRequirement): boolean =>\n requirement.windows !== undefined || Object.values(requirement.relations ?? {}).some(hasWindows)\n\n/**\n * The reads a batch runs. Requirements that page nothing union into one read\n * per entity and id, and every waiter may write its whole result, since\n * plain values are the same whoever asked. A requirement that pages a\n * relation reads alone: a page answers exactly one window, and a waiter\n * cannot tell which of two pages for the same entity was its own.\n */\nconst readsOf = (\n owned: ReadonlyMap<string, Requirement>,\n): ReadonlyArray<{\n readonly keys: ReadonlyArray<string>\n readonly requests: ReadonlyArray<Requirement>\n}> => {\n const plain = [...owned].filter(([, requirement]) => !hasWindows(requirement))\n const paged = [...owned].filter(([, requirement]) => hasWindows(requirement))\n return [\n ...(plain.length === 0\n ? []\n : [\n {\n keys: plain.map(([key]) => key),\n requests: Requirement.merge(plain.map(([, requirement]) => requirement)),\n },\n ]),\n ...paged.map(([key, requirement]) => ({ keys: [key], requests: [requirement] })),\n ]\n}\n\nclass QueryRead extends Request.Class<\n { readonly key: string; readonly request: QueryRequestValue },\n QueryResultValue,\n RemoteQueryError\n> {}\n\n/**\n * Wraps a raw query so that an identical query in flight (same query, input,\n * and window) is joined rather than run again; distinct queries run\n * concurrently. A page answers exactly one window, so nothing is batched.\n */\nexport const coalesceQueries = (\n query: QueryRun,\n options: CoalesceOptions = {},\n): Effect.Effect<QueryRun> =>\n Effect.gen(function* () {\n const runAll = (entries: ReadonlyArray<Request.Entry<QueryRead>>) =>\n Effect.gen(function* () {\n const distinct = new Map<string, QueryRequestValue>()\n for (const entry of entries) distinct.set(entry.request.key, entry.request.request)\n const results = new Map<string, Exit.Exit<QueryResultValue, RemoteQueryError>>()\n yield* Effect.forEach(\n distinct,\n ([key, request]) =>\n Effect.exit(query(request)).pipe(Effect.map(exit => void results.set(key, exit))),\n { concurrency: 'unbounded', discard: true },\n )\n for (const entry of entries) {\n yield* Request.completeEffect(entry, results.get(entry.request.key)!)\n }\n })\n let resolver = RequestResolver.make<QueryRead>(runAll)\n if (options.window !== undefined) {\n resolver = RequestResolver.setDelay(resolver, Duration.fromInputUnsafe(options.window))\n }\n return request =>\n Effect.request(\n new QueryRead({\n key: stableStringify([request.query, request.input, request.window]),\n request,\n }),\n resolver,\n )\n })\n\nclass ReadRequirement extends Request.Class<\n { readonly key: string; readonly requirement: Requirement },\n BatchResult,\n ReadError\n> {}\n\n/**\n * Wraps a raw batch read so that requirements are batched and deduplicated.\n * Every waiter receives the whole batch result; `Remote.writeRead` is\n * idempotent, so writing it more than once is harmless.\n */\nexport const coalesceReads = (\n read: BatchRead,\n options: CoalesceOptions = {},\n): Effect.Effect<BatchRead> =>\n Effect.gen(function* () {\n // Requirements a batch is currently reading; a later equal requirement\n // joins the deferred instead of starting another read.\n const inFlight = new Map<string, Deferred.Deferred<BatchResult, ReadError>>()\n\n // A batch runs to completion even when every requester is interrupted, so\n // an in-flight requirement is always settled and released by its read.\n const runAll = (entries: ReadonlyArray<Request.Entry<ReadRequirement>>) =>\n Effect.gen(function* () {\n // Per requirement key: the deferred this batch's entries wait on. One\n // already in flight from an earlier batch is joined; the rest are\n // owned here and settled by this batch's read.\n const joins = new Map<string, Deferred.Deferred<BatchResult, ReadError>>()\n const own = new Map<string, Deferred.Deferred<BatchResult, ReadError>>()\n for (const entry of entries) {\n const key = entry.request.key\n if (joins.has(key)) continue\n const existing = inFlight.get(key)\n if (existing !== undefined) {\n joins.set(key, existing)\n continue\n }\n const deferred = yield* Deferred.make<BatchResult, ReadError>()\n inFlight.set(key, deferred)\n own.set(key, deferred)\n joins.set(key, deferred)\n }\n if (own.size > 0) {\n const owned = new Map<string, Requirement>()\n for (const entry of entries) {\n if (own.has(entry.request.key)) owned.set(entry.request.key, entry.request.requirement)\n }\n yield* Effect.forEach(\n readsOf(owned),\n ({ keys, requests }) =>\n Effect.gen(function* () {\n const exit = yield* Effect.exit(\n read({ version: REMOTE_PROTOCOL_VERSION, requests }),\n )\n // Settle exactly the requirements this read answered.\n for (const key of keys) {\n inFlight.delete(key)\n yield* Deferred.done(own.get(key)!, exit)\n }\n }),\n { concurrency: 'unbounded', discard: true },\n )\n }\n for (const entry of entries) {\n yield* Request.completeEffect(entry, Deferred.await(joins.get(entry.request.key)!))\n }\n })\n\n let resolver = RequestResolver.make<ReadRequirement>(runAll)\n if (options.window !== undefined) {\n resolver = RequestResolver.setDelay(resolver, Duration.fromInputUnsafe(options.window))\n }\n\n return batch =>\n batch.requests.length === 0\n ? Effect.succeed({ entities: [] })\n : Effect.forEach(\n batch.requests,\n requirement =>\n Effect.request(\n new ReadRequirement({ key: requirementKey(requirement), requirement }),\n resolver,\n ),\n { concurrency: 'unbounded' },\n ).pipe(\n Effect.map(results => ({\n entities: [...new Set(results)].flatMap(result => result.entities),\n })),\n )\n })\n","/**\n * The transport seam: the `RemoteClient` Effect service, the RPC client it is\n * built from, the wire-to-client reconstructions, and the mutation call.\n */\nimport { Context, Effect, Layer, Schema, Stream } from 'effect'\nimport type { Requirement } from 'foldkit-surface'\nimport { coalesceQueries, coalesceReads, type CoalesceOptions } from './coalesce.js'\nimport type { LiveCursor, LiveEvent } from './live.js'\nimport type { MutationDescriptor } from './mutation.js'\nimport type { ConnectionChange } from './optimistic.js'\nimport type { RemoteError } from './remoteData.js'\nimport {\n MutationRequest,\n MutationResult,\n QueryRequest,\n QueryResult,\n ReadBatch,\n ReadBatchResult,\n type ConnectionChangeSchema,\n RemoteLiveError,\n RemoteMutationError,\n RemoteProtocolError,\n RemoteQueryError,\n RemoteReadError,\n type LiveChange,\n type LiveRequirement,\n} from './wire.js'\n\n/**\n * The transport boundary. `foldkit-remote` never talks to a transport directly;\n * it depends on this Effect service, which a later phase wires to Effect RPC.\n */\nexport class RemoteClient extends Context.Service<\n RemoteClient,\n {\n readonly read: (\n batch: Schema.Schema.Type<typeof ReadBatch>,\n ) => Effect.Effect<\n Schema.Schema.Type<typeof ReadBatchResult>,\n RemoteReadError | RemoteProtocolError\n >\n readonly query: (\n request: Schema.Schema.Type<typeof QueryRequest>,\n ) => Effect.Effect<Schema.Schema.Type<typeof QueryResult>, RemoteQueryError>\n readonly mutate: (\n request: Schema.Schema.Type<typeof MutationRequest>,\n ) => Effect.Effect<Schema.Schema.Type<typeof MutationResult>, RemoteMutationError>\n readonly live: (request: {\n readonly requirements: ReadonlyArray<Requirement>\n readonly after: LiveCursor\n }) => Stream.Stream<LiveEvent, RemoteLiveError | RemoteProtocolError>\n }\n>()('foldkit-remote/RemoteClient') {}\n\n/**\n * The methods an Effect RPC client for `RemoteRpc` exposes. `R` is the\n * environment a handler needs; it defaults to `never`, which is what a real\n * transport client satisfies. `RemoteServer.handlers` returns this type with its\n * own `R`, so the two sides cannot drift apart.\n */\nexport interface RemoteRpcClient<R = never> {\n readonly FoldkitRemoteRead: (\n payload: Schema.Schema.Type<typeof ReadBatch>,\n ) => Effect.Effect<\n Schema.Schema.Type<typeof ReadBatchResult>,\n RemoteReadError | RemoteProtocolError,\n R\n >\n readonly FoldkitRemoteQuery: (\n payload: Schema.Schema.Type<typeof QueryRequest>,\n ) => Effect.Effect<Schema.Schema.Type<typeof QueryResult>, RemoteQueryError, R>\n readonly FoldkitRemoteMutate: (\n payload: Schema.Schema.Type<typeof MutationRequest>,\n ) => Effect.Effect<Schema.Schema.Type<typeof MutationResult>, RemoteMutationError, R>\n readonly FoldkitRemoteLive: (\n payload: Schema.Schema.Type<typeof LiveRequirement>,\n ) => Stream.Stream<\n Schema.Schema.Type<typeof LiveChange>,\n RemoteLiveError | RemoteProtocolError,\n R\n >\n}\n\n/** Reconstructs the client's `ConnectionChange` from the wire's flattened edge. */\nexport const connectionChangeOf = (\n change: Schema.Schema.Type<typeof ConnectionChangeSchema>,\n): ConnectionChange => {\n const edge = { key: change.edge.key, ref: { entity: change.edge.entity, id: change.edge.id } }\n return change._tag === 'Insert'\n ? { _tag: 'Insert', connection: change.connection, position: change.position, edge }\n : { _tag: 'Remove', connection: change.connection, edge }\n}\n\n/** Reconstructs the client's `LiveEvent` from the wire's flattened `LiveChange`. */\nexport const liveEventOf = (change: Schema.Schema.Type<typeof LiveChange>): LiveEvent => {\n switch (change._tag) {\n case 'EntityPatched':\n return {\n _tag: 'EntityPatched',\n ref: { entity: change.entity, id: change.id },\n values: change.values,\n changed: change.changed,\n cursor: change.cursor,\n }\n case 'EntityDeleted':\n return {\n _tag: 'EntityDeleted',\n ref: { entity: change.entity, id: change.id },\n cursor: change.cursor,\n }\n case 'ConnectionInsert':\n return {\n _tag: 'ConnectionInsert',\n connection: change.connection,\n position: change.position,\n edge: { key: change.edge.key, ref: { entity: change.edge.entity, id: change.edge.id } },\n cursor: change.cursor,\n }\n case 'ConnectionRemove':\n return {\n _tag: 'ConnectionRemove',\n connection: change.connection,\n edge: { key: change.edge.key, ref: { entity: change.edge.entity, id: change.edge.id } },\n cursor: change.cursor,\n }\n case 'ConnectionInvalidate':\n return { _tag: 'ConnectionInvalidate', connection: change.connection, cursor: change.cursor }\n }\n}\n\nexport const remoteError = (error: {\n readonly _tag: string\n readonly message: string\n}): RemoteError => ({\n _tag: error._tag,\n message: error.message,\n})\n\nexport const coalescedLayer = <E, R>(\n layer: Layer.Layer<RemoteClient, E, R>,\n options: CoalesceOptions = {},\n): Layer.Layer<RemoteClient, E, R> =>\n Layer.effect(\n RemoteClient,\n Effect.gen(function* () {\n const client = yield* RemoteClient\n const read = yield* coalesceReads(client.read, options)\n const query = yield* coalesceQueries(client.query, options)\n return { ...client, read, query }\n }),\n ).pipe(Layer.provide(layer))\n\n/**\n * `Remote.mutate` as a standalone effect, so `Remote.mutateInto` can reuse it\n * without the object literal referencing itself.\n */\nexport const mutateRemote = Effect.fn('Remote.mutate')(function* <\n Name extends string,\n Input,\n Output,\n>(mutation: MutationDescriptor<Name, Input, Output>, input: Input, requestId: string) {\n yield* Effect.annotateCurrentSpan({ mutation: mutation.name, requestId })\n const client = yield* RemoteClient\n const encoded = yield* Schema.encodeUnknownEffect(mutation.Input)(input).pipe(\n Effect.catchTag('SchemaError', error =>\n Effect.fail(new RemoteMutationError({ message: error.message })),\n ),\n )\n const result = yield* client.mutate({\n requestId,\n mutation: mutation.name,\n input: encoded,\n })\n const output = yield* Schema.decodeUnknownEffect(mutation.Output)(result.output).pipe(\n Effect.catchTag('SchemaError', error =>\n Effect.fail(new RemoteMutationError({ message: error.message })),\n ),\n )\n return {\n output,\n entities: result.entities,\n connections: (result.connections ?? []).map(connectionChangeOf),\n }\n})\n","/**\n * The pure connection model: an ordered normalized structure of edges with\n * explicit known boundaries. Pages, live events, and optimistic inserts are all\n * evidence about one connection; `merge` is the single deterministic reducer and\n * performs no I/O.\n *\n * Optimistic overlays and live state arrive in later phases.\n */\nimport { entityKey } from './store.js'\n\nexport interface EdgeRef {\n readonly entity: string\n readonly id: string\n}\n\n/** `key` is the edge identity used for de-duplication. */\nexport interface Edge {\n readonly key: string\n readonly ref: EdgeRef\n}\n\nexport const edge = (ref: EdgeRef, key: string = entityKey(ref.entity, ref.id)): Edge => ({\n key,\n ref,\n})\n\nexport type Cursor = string\n\nexport type Boundary =\n | { readonly _tag: 'Terminal' }\n | { readonly _tag: 'Cursor'; readonly cursor: Cursor }\n | { readonly _tag: 'Unknown' }\n\nexport const terminal: Boundary = { _tag: 'Terminal' }\nexport const unknown: Boundary = { _tag: 'Unknown' }\nexport const cursor = (value: Cursor): Boundary => ({ _tag: 'Cursor', cursor: value })\n\nexport interface Segment {\n readonly edges: readonly Edge[]\n readonly start: Boundary\n readonly end: Boundary\n}\n\nexport interface Connection {\n readonly segments: readonly Segment[]\n readonly stale: boolean\n}\n\nexport const emptyConnection: Connection = { segments: [], stale: false }\n\nexport const segment = (edges: readonly Edge[], start: Boundary, end: Boundary): Segment => ({\n edges,\n start,\n end,\n})\n\nconst dedupeEdges = (edges: readonly Edge[]): Edge[] => {\n const seen = new Set<string>()\n const out: Edge[] = []\n for (const value of edges) {\n if (seen.has(value.key)) continue\n seen.add(value.key)\n out.push(value)\n }\n return out\n}\n\nconst normalize = (segment: Segment): Segment => ({ ...segment, edges: dedupeEdges(segment.edges) })\n\n/** Longest suffix of `a` that is a prefix of `b`, matched by edge identity. */\nconst overlapLength = (a: readonly Edge[], b: readonly Edge[]): number => {\n const most = Math.min(a.length, b.length)\n for (let length = most; length > 0; length--) {\n let matches = true\n for (let i = 0; i < length; i++) {\n if (a[a.length - length + i]!.key !== b[i]!.key) {\n matches = false\n break\n }\n }\n if (matches) return length\n }\n return 0\n}\n\nconst cursorJoinable = (a: Boundary, b: Boundary): boolean =>\n a._tag === 'Cursor' && b._tag === 'Cursor' && a.cursor === b.cursor\n\n/** Joins `a` immediately before `b`, or returns `undefined` when they are not contiguous. */\nconst join = (a: Segment, b: Segment): Segment | undefined => {\n if (cursorJoinable(a.end, b.start)) {\n return { edges: dedupeEdges([...a.edges, ...b.edges]), start: a.start, end: b.end }\n }\n const overlap = overlapLength(a.edges, b.edges)\n if (overlap > 0) {\n return {\n edges: dedupeEdges([...a.edges, ...b.edges]),\n start: a.start,\n end: b.end,\n }\n }\n return undefined\n}\n\n/**\n * Global by edge identity: an edge appears once per connection. Dropping a\n * shared edge from the middle of a segment would otherwise imply that its\n * surviving neighbours are adjacent, so a segment with holes is split at each\n * hole and the new inner boundaries are `Unknown`.\n */\nconst dedupeConnection = (segments: readonly Segment[]): Segment[] => {\n const seen = new Set<string>()\n const out: Segment[] = []\n for (const segmentValue of segments) {\n const runs: Edge[][] = []\n let run: Edge[] = []\n for (const edgeValue of segmentValue.edges) {\n if (seen.has(edgeValue.key)) {\n if (run.length > 0) {\n runs.push(run)\n run = []\n }\n continue\n }\n seen.add(edgeValue.key)\n run.push(edgeValue)\n }\n if (run.length > 0) runs.push(run)\n if (runs.length === 0) continue\n if (runs.length === 1) {\n out.push({ ...segmentValue, edges: runs[0]! })\n continue\n }\n runs.forEach((edges, index) => {\n out.push({\n edges,\n start: index === 0 ? segmentValue.start : unknown,\n end: index === runs.length - 1 ? segmentValue.end : unknown,\n })\n })\n }\n return out\n}\n\n/** Adds a page to the connection, joining contiguous or overlapping segments. */\nexport const merge = (current: Connection, page: Segment): Connection => {\n // A zero-edge page carries no ordering evidence; joining it would let its\n // boundary overwrite a real segment's end. Ignore it.\n const incoming = normalize(page)\n if (incoming.edges.length === 0) return current\n\n const segments = [...current.segments.map(normalize), incoming]\n let joined = true\n while (joined) {\n joined = false\n outer: for (let i = 0; i < segments.length; i++) {\n for (let j = 0; j < segments.length; j++) {\n if (i === j) continue\n const result = join(segments[i]!, segments[j]!)\n if (result === undefined) continue\n segments[i] = result\n segments.splice(j, 1)\n joined = true\n break outer\n }\n }\n }\n return { ...current, segments: orderSegments(dedupeConnection(segments)) }\n}\n\n/**\n * Disjoint segments have no cursor linking them, so their relative order is\n * whatever it was; the two exceptions are known: a segment starting at the\n * terminal boundary is first, one ending at it is last.\n */\nconst orderSegments = (segments: readonly Segment[]): Segment[] => {\n const first = segments.filter(value => value.start._tag === 'Terminal')\n const last = segments.filter(value => value.end._tag === 'Terminal' && !first.includes(value))\n const middle = segments.filter(value => !first.includes(value) && !last.includes(value))\n return [...first, ...middle, ...last]\n}\n\n/** Visible edges, segment by segment. */\nexport const items = (connection: Connection): ReadonlyArray<Edge> =>\n connection.segments.flatMap(value => value.edges)\n\n/** There is more before the known region. Derived from boundaries, never row count. */\nexport const hasPrevious = (connection: Connection): boolean => {\n const first = connection.segments[0]\n return first !== undefined && first.start._tag !== 'Terminal'\n}\n\n/** There is more after the known region. Derived from boundaries, never row count. */\nexport const hasNext = (connection: Connection): boolean => {\n const last = connection.segments[connection.segments.length - 1]\n return last !== undefined && last.end._tag !== 'Terminal'\n}\n\n/** A connection with more than one segment has an explicit unknown gap. */\nexport const isGapped = (connection: Connection): boolean => connection.segments.length > 1\n","/** A serializable summary of a RemoteModel for DevTools and diagnostics. */\nimport type { RemoteModel } from './model.js'\nimport type { EntityEntry } from './store.js'\n\n/** A serializable summary of a RemoteModel for DevTools and diagnostics. */\nexport interface RemoteInspection {\n readonly entities: ReadonlyArray<{\n readonly key: string\n readonly present: ReadonlyArray<string>\n readonly stale: ReadonlyArray<string>\n readonly tombstone: boolean\n readonly updatedAt: number\n readonly windows: Readonly<Record<string, string>>\n }>\n readonly connections: ReadonlyArray<string>\n readonly live: ReadonlyArray<string>\n readonly gaps: ReadonlyArray<string>\n readonly mutations: {\n readonly pending: ReadonlyArray<string>\n readonly failed: ReadonlyArray<string>\n readonly applied: number\n }\n}\n\nconst inspectEntry = (key: string, entry: EntityEntry): RemoteInspection['entities'][number] => ({\n key,\n present: [...entry.present],\n stale: [...entry.stale],\n tombstone: entry.tombstone,\n updatedAt: entry.updatedAt,\n windows: { ...entry.windows },\n})\n\n/** A pure, serializable view of the whole cache. */\nexport const inspectRemote = (model: RemoteModel): RemoteInspection => ({\n entities: Object.entries(model.entities).map(([key, entry]) => inspectEntry(key, entry)),\n connections: Object.keys(model.connections),\n live: Object.keys(model.live),\n gaps: [...model.gaps],\n mutations: {\n pending: [...model.mutations.pending],\n failed: [...model.mutations.failed],\n applied: model.mutations.applied.size,\n },\n})\n\n/** A pure, serializable view of one entity, or `undefined` if unknown. */\nexport const inspectEntity = (\n model: RemoteModel,\n key: string,\n): RemoteInspection['entities'][number] | undefined => {\n const entry = model.entities[key]\n return entry === undefined ? undefined : inspectEntry(key, entry)\n}\n","/**\n * Optimistic layers. Pending changes are held as ordered layers over a base\n * store and as overlays over a connection; the visible value is recomputed, never\n * patched with inverses. Settling is remove-the-layer, so overlapping layers\n * rebase for free.\n */\nimport { type Connection, type Edge, edge, items } from './connection.js'\nimport { reconcileMutation, type MutationState, type NormalizedPatch } from './mutation.js'\nimport { entityKey, isTombstone, writeEntity, type EntityStore } from './store.js'\n\nexport interface EntityLayer {\n readonly id: string\n readonly patches: ReadonlyArray<NormalizedPatch>\n}\n\n/**\n * Edges placed outside a connection's server-known region (`prepend`,\n * `append`) or hidden from it (`remove`), owned by the request or live event\n * that produced them.\n */\nexport interface ConnectionOverlay {\n readonly id: string\n readonly connection: string\n readonly edges: ReadonlyArray<Edge>\n readonly position: 'prepend' | 'append' | 'remove'\n}\n\n/** A connection change a request makes optimistically or a mutation result confirms. */\nexport type ConnectionChange =\n | {\n readonly _tag: 'Insert'\n readonly connection: string\n readonly position: 'prepend' | 'append'\n readonly edge: Edge\n }\n | { readonly _tag: 'Remove'; readonly connection: string; readonly edge: Edge }\n\n/** What a request changes before the server answers: entity patches and connection changes. */\nexport type OptimisticOperation = NormalizedPatch | ConnectionChange\n\nconst isConnectionChange = (operation: OptimisticOperation): operation is ConnectionChange =>\n '_tag' in operation\n\nconst toOverlays = (id: string, changes: ReadonlyArray<ConnectionChange>): ConnectionOverlay[] =>\n changes.map(change => ({\n id,\n connection: change.connection,\n edges: [change.edge],\n position: change._tag === 'Insert' ? change.position : 'remove',\n }))\n\n/** A connection, by identity string or by anything that carries one (a `QueryRef`). */\nexport type ConnectionIdentity = string | { readonly identity: string }\n\nexport const connectionIdentity = (connection: ConnectionIdentity): string =>\n typeof connection === 'string' ? connection : connection.identity\n\nconst change = (\n connection: ConnectionIdentity,\n ref: { readonly entity: string; readonly id: string },\n position: 'prepend' | 'append' | 'remove',\n): ConnectionChange =>\n position === 'remove'\n ? { _tag: 'Remove', connection: connectionIdentity(connection), edge: edge(ref) }\n : { _tag: 'Insert', connection: connectionIdentity(connection), position, edge: edge(ref) }\n\n/**\n * Constructors for connection changes: what a request shows optimistically\n * (`MutateOptions.optimistic`) and what a mutation source reports it made\n * (`MutationOutcome.connections`).\n */\nexport const ConnectionChange = {\n /** Show `ref` at the front of the connection until the request settles. */\n prepend: (\n connection: ConnectionIdentity,\n ref: { readonly entity: string; readonly id: string },\n ): ConnectionChange => change(connection, ref, 'prepend'),\n\n /** Show `ref` at the end of the connection until the request settles. */\n append: (\n connection: ConnectionIdentity,\n ref: { readonly entity: string; readonly id: string },\n ): ConnectionChange => change(connection, ref, 'append'),\n\n /** Hide `ref` from the connection until the request settles. */\n remove: (\n connection: ConnectionIdentity,\n ref: { readonly entity: string; readonly id: string },\n ): ConnectionChange => change(connection, ref, 'remove'),\n}\n\n/**\n * Applies a request's operations: its patches become one layer and its\n * connection changes become overlays, all owned by `requestId` so settling\n * removes every one of them together.\n */\nexport const beginOptimistic = (\n optimistic: OptimisticState,\n requestId: string,\n operations: ReadonlyArray<OptimisticOperation>,\n): OptimisticState => {\n const patches = operations.filter(\n (operation): operation is NormalizedPatch => !isConnectionChange(operation),\n )\n const changes = operations.filter(isConnectionChange)\n return {\n layers:\n patches.length === 0 ? optimistic.layers : [...optimistic.layers, { id: requestId, patches }],\n overlays: [...optimistic.overlays, ...toOverlays(requestId, changes)],\n }\n}\n\n/**\n * Replaces a request's overlays with the server-confirmed changes, owned by\n * `id`, in the position the request's overlays held, so a confirmed edge keeps\n * its place among other pending inserts.\n */\nconst confirm = (\n optimistic: OptimisticState,\n requestId: string,\n id: string,\n changes: ReadonlyArray<ConnectionChange>,\n): OptimisticState => {\n const confirmed = toOverlays(id, changes)\n const at = optimistic.overlays.findIndex(overlay => overlay.id === requestId)\n const others = optimistic.overlays.filter(overlay => overlay.id !== requestId)\n return {\n ...optimistic,\n overlays:\n at === -1\n ? [...others, ...confirmed]\n : [...others.slice(0, at), ...confirmed, ...others.slice(at)],\n }\n}\n\n/** Pending entity layers and connection overlays over the base store. */\nexport interface OptimisticState {\n readonly layers: ReadonlyArray<EntityLayer>\n readonly overlays: ReadonlyArray<ConnectionOverlay>\n}\n\nexport const emptyOptimistic: OptimisticState = { layers: [], overlays: [] }\n\nexport const addLayer = (optimistic: OptimisticState, layer: EntityLayer): OptimisticState => ({\n ...optimistic,\n layers: [...optimistic.layers, layer],\n})\n\nexport const removeLayer = (optimistic: OptimisticState, id: string): OptimisticState => ({\n ...optimistic,\n layers: optimistic.layers.filter(layer => layer.id !== id),\n})\n\nexport const addOverlay = (\n optimistic: OptimisticState,\n overlay: ConnectionOverlay,\n): OptimisticState => ({\n ...optimistic,\n overlays: [...optimistic.overlays, overlay],\n})\n\nexport const removeOverlay = (optimistic: OptimisticState, id: string): OptimisticState => ({\n ...optimistic,\n overlays: optimistic.overlays.filter(overlay => overlay.id !== id),\n})\n\n/** Base store with every layer applied in order. Later layers win. */\nexport const visibleStore = (base: EntityStore, optimistic: OptimisticState): EntityStore =>\n optimistic.layers.reduce(\n (store, layer) =>\n layer.patches.reduce(\n (current, patch) => writeEntity(current, entityKey(patch.entity, patch.id), patch.values),\n store,\n ),\n base,\n )\n\n/**\n * A fresh page is newer than any settled overlay it covers: an edge the page\n * carries no longer needs an insert overlay, and a `remove` overlay hiding it\n * is stale (the server says it is back). A pending request's overlays are\n * left alone; they settle with the request.\n */\nexport const pruneOverlays = (\n optimistic: OptimisticState,\n connection: string,\n covered: ReadonlySet<string>,\n pending: ReadonlySet<string>,\n): OptimisticState => ({\n ...optimistic,\n overlays: optimistic.overlays.flatMap(overlay => {\n if (overlay.connection !== connection || pending.has(overlay.id)) return [overlay]\n const edges = overlay.edges.filter(edge => !covered.has(edge.key))\n return edges.length === 0 ? [] : [{ ...overlay, edges }]\n }),\n})\n\n/** Everything a request owns: its layer and its overlays. */\nconst release = (optimistic: OptimisticState, requestId: string): OptimisticState =>\n removeOverlay(removeLayer(optimistic, requestId), requestId)\n\n/**\n * Applies a result idempotently and releases the request's layer and overlays:\n * a later layer re-wins on rebase. Confirmed connection changes are recorded\n * once per request, as overlays the request no longer owns.\n */\nexport const settleSuccess = (\n base: EntityStore,\n optimistic: OptimisticState,\n state: MutationState,\n requestId: string,\n entities: ReadonlyArray<NormalizedPatch>,\n connections: ReadonlyArray<ConnectionChange> = [],\n): {\n readonly store: EntityStore\n readonly state: MutationState\n readonly optimistic: OptimisticState\n} => {\n const reconciled = reconcileMutation(base, state, requestId, entities)\n return {\n store: reconciled.store,\n state: reconciled.state,\n optimistic: state.applied.has(requestId)\n ? release(optimistic, requestId)\n : confirm(\n removeLayer(optimistic, requestId),\n requestId,\n `confirmed:${requestId}`,\n connections,\n ),\n }\n}\n\n/** A failed request's layer and overlays are dropped; the base was never mutated. */\nexport const settleFailure = (optimistic: OptimisticState, requestId: string): OptimisticState =>\n release(optimistic, requestId)\n\n/**\n * Visible edges for one connection: applicable overlays are placed outside the\n * server-known segments and de-duplicated by edge identity (across overlays too),\n * so a pending insert never corrupts server-known ordering; a `remove` overlay\n * hides its edges wherever they are, and so does a tombstone on the edge's\n * target when `store` is given. A later prepend lands before an earlier one, a\n * later append after, so pending inserts read in the order they were made.\n * Boundaries still come from the connection's segments.\n */\nexport const visibleItems = (\n connection: Connection,\n connectionId: string,\n overlays: ReadonlyArray<ConnectionOverlay>,\n store?: EntityStore,\n): ReadonlyArray<Edge> => {\n const applicable = overlays.filter(overlay => overlay.connection === connectionId)\n // Overlays are ordered evidence: the last word on an edge wins, so a remove\n // hides it only until a later insert brings it back.\n const hidden = new Set<string>()\n for (const overlay of applicable) {\n for (const edge of overlay.edges) {\n if (overlay.position === 'remove') hidden.add(edge.key)\n else hidden.delete(edge.key)\n }\n }\n const gone = (edge: Edge): boolean =>\n hidden.has(edge.key) ||\n (store !== undefined && isTombstone(store, entityKey(edge.ref.entity, edge.ref.id)))\n const known = items(connection).filter(edge => !gone(edge))\n const seen = new Set(known.map(edge => edge.key))\n\n const take = (position: 'prepend' | 'append'): ReadonlyArray<Edge> => {\n const edges: Edge[] = []\n const ordered = applicable.filter(value => value.position === position)\n for (const overlay of position === 'prepend' ? [...ordered].reverse() : ordered) {\n for (const edge of overlay.edges) {\n if (seen.has(edge.key) || gone(edge)) continue\n seen.add(edge.key)\n edges.push(edge)\n }\n }\n return edges\n }\n\n return [...take('prepend'), ...known, ...take('append')]\n}\n","/**\n * Live data. Entity facts update the store; connection facts change ordering and\n * membership. Events carry a monotonic cursor ordered **per stream**: duplicates\n * are ignored, and a gap is surfaced so the caller can resume or invalidate.\n * Subscriptions are selection-aware and driven by active Surfaces.\n */\nimport type { EdgeRef } from './connection.js'\nimport { type Connection, type Edge, hasNext, hasPrevious } from './connection.js'\nimport { addOverlay, type OptimisticState } from './optimistic.js'\nimport type { LiveInsertion, LivePolicy } from './query.js'\nimport { entityKey, tombstone, writeEntity, type EntityStore } from './store.js'\n\nexport type LiveCursor = number\n\nexport type LiveEvent =\n | {\n readonly _tag: 'EntityPatched'\n readonly ref: EdgeRef\n readonly values: Readonly<Record<string, unknown>>\n readonly changed: ReadonlyArray<string>\n readonly cursor: LiveCursor\n }\n | { readonly _tag: 'EntityDeleted'; readonly ref: EdgeRef; readonly cursor: LiveCursor }\n | {\n readonly _tag: 'ConnectionInsert'\n readonly connection: string\n readonly position: 'prepend' | 'append'\n readonly edge: Edge\n readonly cursor: LiveCursor\n }\n | {\n readonly _tag: 'ConnectionRemove'\n readonly connection: string\n readonly edge: Edge\n readonly cursor: LiveCursor\n }\n | {\n readonly _tag: 'ConnectionInvalidate'\n readonly connection: string\n readonly cursor: LiveCursor\n }\n\nexport interface BoundaryCounts {\n readonly before: number\n readonly after: number\n}\n\nexport interface LiveState {\n /** Last applied cursor for this stream. */\n readonly cursor: LiveCursor\n /** Connections marked stale by an invalidating event. */\n readonly stale: ReadonlySet<string>\n /** Edges recorded outside the loaded boundary, not visible in `items`. */\n readonly boundary: Readonly<Record<string, BoundaryCounts>>\n}\n\nexport const emptyLiveState: LiveState = { cursor: 0, stale: new Set(), boundary: {} }\n\nexport type LiveOutcome = 'applied' | 'duplicate' | 'gap'\n\n/**\n * Ordering per stream: at most the next cursor; ahead is a gap. Cursor `0` means\n * \"no baseline yet\" (cursors are 1-based), so the first event of a stream is\n * accepted whatever its cursor — otherwise a stream not starting at 1 would be a\n * spurious gap.\n */\nexport const classifyLive = (state: LiveState, cursor: LiveCursor): LiveOutcome =>\n cursor <= state.cursor\n ? 'duplicate'\n : state.cursor === 0 || cursor === state.cursor + 1\n ? 'applied'\n : 'gap'\n\nconst advance = (state: LiveState, cursor: LiveCursor): LiveState => ({ ...state, cursor })\n\nconst recordBoundary = (\n state: LiveState,\n connection: string,\n position: 'prepend' | 'append',\n): LiveState => {\n const current = state.boundary[connection] ?? { before: 0, after: 0 }\n const next =\n position === 'prepend'\n ? { ...current, before: current.before + 1 }\n : { ...current, after: current.after + 1 }\n return { ...state, boundary: { ...state.boundary, [connection]: next } }\n}\n\nexport const invalidateConnection = (state: LiveState, connection: string): LiveState => ({\n ...state,\n stale: new Set([...state.stale, connection]),\n})\n\n/**\n * A subscriber is woken only if the event changed a field it selects. A\n * change to an unselected field is skipped entirely.\n */\nexport const shouldWake = (\n changed: ReadonlyArray<string>,\n selected: ReadonlyArray<string>,\n): boolean => changed.some(field => selected.includes(field))\n\nexport interface EntityApplied {\n readonly state: LiveState\n readonly store: EntityStore\n readonly outcome: LiveOutcome\n}\n\nexport const applyEntityEvent = (\n state: LiveState,\n store: EntityStore,\n event: Extract<LiveEvent, { _tag: 'EntityPatched' | 'EntityDeleted' }>,\n now = 0,\n): EntityApplied => {\n const outcome = classifyLive(state, event.cursor)\n if (outcome !== 'applied') return { state, store, outcome }\n const key = entityKey(event.ref.entity, event.ref.id)\n const next =\n event._tag === 'EntityPatched'\n ? writeEntity(store, key, event.values, now)\n : tombstone(store, key)\n return { state: advance(state, event.cursor), store: next, outcome }\n}\n\nexport interface ConnectionApplied {\n readonly state: LiveState\n readonly optimistic: OptimisticState\n readonly outcome: LiveOutcome\n}\n\nconst removeEdgeOverlays = (\n optimistic: OptimisticState,\n connection: string,\n key: string,\n): OptimisticState => ({\n ...optimistic,\n overlays: optimistic.overlays.map(overlay =>\n overlay.connection !== connection || overlay.position === 'remove'\n ? overlay\n : { ...overlay, edges: overlay.edges.filter(edge => edge.key !== key) },\n ),\n})\n\nexport const applyConnectionEvent = (\n state: LiveState,\n optimistic: OptimisticState,\n event: Extract<\n LiveEvent,\n { _tag: 'ConnectionInsert' | 'ConnectionRemove' | 'ConnectionInvalidate' }\n >,\n policy: LivePolicy = {},\n): ConnectionApplied => {\n const outcome = classifyLive(state, event.cursor)\n if (outcome !== 'applied') return { state, optimistic, outcome }\n\n switch (event._tag) {\n case 'ConnectionInsert': {\n const selection: LiveInsertion =\n (event.position === 'prepend' ? policy.prepend : policy.append) ?? 'visible'\n switch (selection) {\n case 'visible':\n return {\n state: advance(state, event.cursor),\n optimistic: addOverlay(optimistic, {\n id: `live:${event.cursor}`,\n connection: event.connection,\n edges: [event.edge],\n position: event.position,\n }),\n outcome,\n }\n case 'boundary':\n return {\n state: recordBoundary(advance(state, event.cursor), event.connection, event.position),\n optimistic,\n outcome,\n }\n case 'invalidate':\n return {\n state: invalidateConnection(advance(state, event.cursor), event.connection),\n optimistic,\n outcome,\n }\n case 'ignore':\n return { state: advance(state, event.cursor), optimistic, outcome }\n }\n }\n case 'ConnectionRemove':\n // Strip the edge from pending inserts and hide it wherever else it is\n // (a server-known segment included) until a fresh page says otherwise.\n return {\n state: advance(state, event.cursor),\n optimistic: addOverlay(removeEdgeOverlays(optimistic, event.connection, event.edge.key), {\n id: `live:${event.cursor}`,\n connection: event.connection,\n edges: [event.edge],\n position: 'remove',\n }),\n outcome,\n }\n case 'ConnectionInvalidate':\n return {\n state: invalidateConnection(advance(state, event.cursor), event.connection),\n optimistic,\n outcome,\n }\n }\n}\n\nexport const isStale = (state: LiveState, connection: string): boolean =>\n state.stale.has(connection)\n\n/**\n * Clears a connection's stale mark once a fresh page has been adopted. An\n * invalidating event only records that a refetch is due; whoever merges the\n * refetched page calls this so `isStale` stops reporting.\n */\nexport const refreshConnection = (state: LiveState, connection: string): LiveState => {\n if (!state.stale.has(connection)) return state\n const stale = new Set(state.stale)\n stale.delete(connection)\n return { ...state, stale }\n}\n\n/** `hasPrevious` accounting for edges recorded outside the loaded boundary. */\nexport const liveHasPrevious = (\n connection: Connection,\n state: LiveState,\n connectionId: string,\n): boolean => hasPrevious(connection) || (state.boundary[connectionId]?.before ?? 0) > 0\n\n/** `hasNext` accounting for edges recorded outside the loaded boundary. */\nexport const liveHasNext = (\n connection: Connection,\n state: LiveState,\n connectionId: string,\n): boolean => hasNext(connection) || (state.boundary[connectionId]?.after ?? 0) > 0\n","/**\n * Relation values on the wire and in the store: a ref key (`\"Entity:id\"`), a\n * nullable ref key, an array of ref keys, or a page of ref keys. The planner\n * follows them into the store; the server follows them into the next read.\n */\nimport type { Schema } from 'effect'\nimport type { RelationRequirement } from 'foldkit-surface'\n\nexport interface RefParts {\n readonly entity: string\n readonly id: string\n}\n\n/** A page of refs as the wire and the store hold it. */\nexport interface RefPageValue {\n readonly refs: ReadonlyArray<string>\n readonly hasNext: boolean\n readonly hasPrevious: boolean\n}\n\n/** Marks the codec `Entity.ref`/`Entity.refPage` produce, so a Selection can tell the field's shape. */\nexport const RelationAnnotation = 'foldkitRemoteRelation'\n/** The target entity's name on the same codec, so a nested selection of another entity is refused. */\nexport const RelationEntityAnnotation = 'foldkitRemoteRelationEntity'\n\nexport type RelationKind = 'one' | 'many' | 'page'\n\nexport interface RelationShape {\n readonly kind: RelationKind\n readonly nullable: boolean\n readonly entity: string\n}\n\n/** Splits a ref key (`\"Entity:id\"`, the store key too) back into its parts. */\nexport const refParts = (encoded: string): RefParts => {\n const separator = encoded.indexOf(':')\n return separator === -1\n ? { entity: encoded, id: '' }\n : { entity: encoded.slice(0, separator), id: encoded.slice(separator + 1) }\n}\n\n/**\n * The refs a relation value carries, in order. Anything that is not a ref key,\n * an array of them, or a page of them contributes nothing.\n */\nexport const refsIn = (value: unknown): ReadonlyArray<RefParts> => {\n if (typeof value === 'string') return [refParts(value)]\n if (Array.isArray(value)) return value.filter(item => typeof item === 'string').map(refParts)\n if (value !== null && typeof value === 'object') {\n const refs = (value as { readonly refs?: unknown }).refs\n if (Array.isArray(refs)) return refs.filter(item => typeof item === 'string').map(refParts)\n }\n return []\n}\n\n/** The refs in a relation value that name the relation's target entity, and no other. */\nexport const targetsOf = (value: unknown, relation: RelationRequirement): ReadonlyArray<RefParts> =>\n refsIn(value).filter(ref => ref.entity === relation.entity)\n\nexport const isRefPage = (value: unknown): value is RefPageValue => {\n if (value === null || typeof value !== 'object') return false\n const page = value as Record<string, unknown>\n return (\n Array.isArray(page.refs) &&\n page.refs.every(ref => typeof ref === 'string') &&\n typeof page.hasNext === 'boolean' &&\n typeof page.hasPrevious === 'boolean'\n )\n}\n\ninterface AstLike {\n readonly _tag: string\n readonly annotations?: Readonly<Record<string, unknown>> | undefined\n readonly types?: ReadonlyArray<AstLike> | undefined\n readonly rest?: ReadonlyArray<AstLike> | undefined\n}\n\n/**\n * The relation shape an entity field schema declares: a ref (`one`), a nullable\n * ref, an array of refs (`many`), or a page of refs (`page`). `undefined` for a\n * scalar field, which cannot take a nested selection.\n */\nexport const relationShape = (schema: Schema.Top): RelationShape | undefined =>\n shapeOf(schema.ast as unknown as AstLike, false)\n\nconst shapeOf = (ast: AstLike, nullable: boolean): RelationShape | undefined => {\n const annotated = ast.annotations?.[RelationAnnotation]\n if (annotated === 'one' || annotated === 'page') {\n return {\n kind: annotated,\n nullable,\n entity: String(ast.annotations?.[RelationEntityAnnotation]),\n }\n }\n if (ast._tag === 'Arrays') {\n const item = ast.rest?.[0]\n const inner = item === undefined ? undefined : shapeOf(item, false)\n return inner?.kind === 'one' ? { kind: 'many', nullable, entity: inner.entity } : undefined\n }\n if (ast._tag === 'Union') {\n const members = ast.types ?? []\n const optional = members.some(member => member._tag === 'Null' || member._tag === 'Undefined')\n for (const member of members) {\n const shape = shapeOf(member, optional)\n if (shape !== undefined) return shape\n }\n }\n return undefined\n}\n","/**\n * The pure requirement planner.\n *\n * A `Requirement` is plain data: which entity fields a Remote projection needs,\n * and through `relations`, which fields of each relation's target. `plan` diffs\n * requirements against the store and returns only the missing fields, grouped\n * and deterministically ordered. A relation whose field is being fetched keeps\n * its nested requirement on the request, so the server resolves the graph in\n * one read; a relation whose refs the store already holds is followed into\n * concrete requirements for the targets. Time enters through `PlanFreshness`,\n * never from ambient state; `force` plans every field.\n */\nimport { Requirement, type RelationRequirement } from 'foldkit-surface'\nimport { stableStringify } from './query.js'\nimport { targetsOf } from './relation.js'\nimport { entityKey, missingFields, readField, type EntityStore } from './store.js'\n\nexport type { RelationRequirement, Requirement } from 'foldkit-surface'\n\ntype Window = NonNullable<Requirement['windows']>[string]\n\n/** A stable key for a window, so two equal windows compare equal. */\nexport const windowKey = (window: Window): string => stableStringify(window)\n\nexport interface PlanFreshness {\n readonly now: number\n /** A present entry older than this many milliseconds is refreshed whole. */\n readonly freshness: number\n}\n\nexport interface PlanOptions {\n readonly freshness?: PlanFreshness | undefined\n /** Plan every requested field, present or not, tombstoned or not. */\n readonly force?: boolean | undefined\n}\n\nconst pickFields = <T>(\n record: Readonly<Record<string, T>> | undefined,\n fields: ReadonlySet<string>,\n): Readonly<Record<string, T>> | undefined => {\n if (record === undefined) return undefined\n const picked = Object.fromEntries(Object.entries(record).filter(([field]) => fields.has(field)))\n return Object.keys(picked).length === 0 ? undefined : picked\n}\n\n/** The concrete requirements a known relation value contributes for its targets. */\nconst followRelation = (\n value: unknown,\n relation: RelationRequirement,\n): ReadonlyArray<Requirement> =>\n targetsOf(value, relation).map(ref => ({ ...relation, id: ref.id }))\n\nexport const plan = (\n store: EntityStore,\n requirements: readonly Requirement[],\n options: PlanOptions = {},\n): ReadonlyArray<Requirement> => {\n const { freshness, force = false } = options\n const planned: Requirement[] = []\n const followed: Requirement[] = []\n\n for (const group of Requirement.merge(requirements)) {\n const key = entityKey(group.entity, group.id)\n const entry = store[key]\n const expired =\n freshness !== undefined &&\n entry !== undefined &&\n !entry.tombstone &&\n freshness.now - entry.updatedAt > freshness.freshness\n const windowKeys = Object.fromEntries(\n Object.entries(group.windows ?? {}).map(([field, window]) => [field, windowKey(window)]),\n )\n const missing =\n force || expired ? group.fields : missingFields(store, key, group.fields, windowKeys)\n const missingSet = new Set(missing)\n\n // A relation the store already holds is followed into its targets; one\n // being fetched rides on the request instead.\n for (const [field, relation] of Object.entries(group.relations ?? {})) {\n if (missingSet.has(field)) continue\n const value = readField(store, key, field)\n if (value._tag === 'Some') followed.push(...followRelation(value.value, relation))\n }\n\n if (missing.length === 0) continue\n // Only a field being fetched carries its window and its relation.\n const windows = pickFields(group.windows, missingSet)\n const relations = pickFields(group.relations, missingSet)\n planned.push({\n entity: group.entity,\n id: group.id,\n fields: missing,\n ...(windows === undefined ? {} : { windows }),\n ...(relations === undefined ? {} : { relations }),\n })\n }\n\n const nested = followed.length === 0 ? [] : plan(store, followed, options)\n return [...Requirement.merge([...planned, ...nested])].sort((a, b) =>\n entityKey(a.entity, a.id) < entityKey(b.entity, b.id) ? -1 : 1,\n )\n}\n","/**\n * Cache lifetime. Retention roots are the requirements (and connections) the\n * application's active Surfaces observe; `gc` keeps what they reach through\n * the store's refs plus every pending optimistic change, and drops the rest.\n * Roots live outside the Model, so GC arrives as a Message.\n */\nimport type { RelationRequirement, Requirement } from 'foldkit-surface'\nimport { refsIn } from './relation.js'\nimport { entityKey, readField, type EntityKey, type EntityStore } from './store.js'\nimport type { Connection } from './connection.js'\nimport type { OptimisticState } from './optimistic.js'\nimport type { MutationState } from './mutation.js'\n\n/** A connection to keep: its identity, and what a page of it selects of each item, if a projection reads it. */\nexport interface ConnectionRoot {\n readonly identity: string\n readonly select?: RelationRequirement | undefined\n}\n\nexport interface RetentionRoots {\n readonly requirements: ReadonlyArray<Requirement>\n /** Connections (`QueryRef.identity`) to keep, with their edges' targets and what `select` reaches through them. */\n readonly connections: ReadonlyArray<ConnectionRoot>\n}\n\nexport interface Retained {\n readonly entities: EntityStore\n readonly connections: Readonly<Record<string, Connection>>\n readonly optimistic: OptimisticState\n}\n\n/**\n * The entity keys the roots reach: each root entity, the targets its retained\n * fields refer to, and recursively the targets a nested relation selects.\n */\nexport const reachable = (\n store: EntityStore,\n roots: RetentionRoots,\n connections: Readonly<Record<string, Connection>>,\n optimistic: OptimisticState,\n pending: ReadonlySet<string>,\n): ReadonlySet<EntityKey> => {\n const kept = new Set<EntityKey>()\n const rootConnections = new Set(roots.connections.map(root => root.identity))\n // A target is walked once per relation spec that reaches it: two specs may\n // select different nested relations of the same entity, and a spec tree is\n // finite, so this terminates on cyclic data too.\n const walked = new Map<EntityKey, Set<Omit<Requirement, 'id'>>>()\n const visit = (key: EntityKey, requirement: Omit<Requirement, 'id'>): void => {\n kept.add(key)\n const seen = walked.get(key) ?? new Set()\n if (seen.has(requirement)) return\n seen.add(requirement)\n walked.set(key, seen)\n for (const field of requirement.fields) {\n const value = readField(store, key, field)\n if (value._tag === 'None') continue\n const relation = requirement.relations?.[field]\n for (const ref of refsIn(value.value)) {\n const target = entityKey(ref.entity, ref.id)\n if (relation === undefined || ref.entity !== relation.entity) {\n kept.add(target)\n continue\n }\n visit(target, relation)\n }\n }\n }\n for (const root of roots.requirements) visit(entityKey(root.entity, root.id), root)\n // A connection root keeps its edges' targets, and what a page's `select`\n // reaches through them (an item's owner, say), so the page stays readable.\n for (const { identity, select } of roots.connections) {\n for (const segment of connections[identity]?.segments ?? []) {\n for (const edge of segment.edges) {\n const target = entityKey(edge.ref.entity, edge.ref.id)\n if (select === undefined || edge.ref.entity !== select.entity) kept.add(target)\n else visit(target, select)\n }\n }\n }\n // A pending request's changes are kept whole; a settled overlay (a live or\n // confirmed insert) is kept only with a retained connection, below.\n for (const layer of optimistic.layers) {\n if (!pending.has(layer.id)) continue\n for (const patch of layer.patches) kept.add(entityKey(patch.entity, patch.id))\n }\n for (const overlay of optimistic.overlays) {\n if (!pending.has(overlay.id) && !rootConnections.has(overlay.connection)) continue\n for (const edge of overlay.edges) kept.add(entityKey(edge.ref.entity, edge.ref.id))\n }\n return kept\n}\n\n/**\n * Drops every entity the roots do not reach, every connection they do not\n * name, and every settled overlay on a dropped connection, keeping whatever a\n * pending request's layer or overlays touch. Pure.\n */\nexport const gc = (\n state: Retained & { readonly mutations: MutationState },\n roots: RetentionRoots,\n): Retained => {\n const pending = state.mutations.pending\n const kept = reachable(state.entities, roots, state.connections, state.optimistic, pending)\n const entities = Object.fromEntries(\n Object.entries(state.entities).filter(([key]) => kept.has(key)),\n )\n const keptConnections = new Set([\n ...roots.connections.map(root => root.identity),\n ...state.optimistic.overlays\n .filter(overlay => pending.has(overlay.id))\n .map(overlay => overlay.connection),\n ])\n const connections = Object.fromEntries(\n Object.entries(state.connections).filter(([identity]) => keptConnections.has(identity)),\n )\n const optimistic: OptimisticState = {\n layers: state.optimistic.layers,\n overlays: state.optimistic.overlays.filter(\n overlay => pending.has(overlay.id) || keptConnections.has(overlay.connection),\n ),\n }\n return { entities, connections, optimistic }\n}\n","/**\n * Remote cache persistence: a snapshot of the entity store and nothing else.\n * Runtime state (connections' live cursors, optimistic layers, the mutation\n * ledger, gaps, retention roots) is never in a snapshot; it belongs to the\n * session that produced it.\n *\n * The cache is server-derived and disposable: an incompatible, oversized, or\n * corrupt snapshot is discarded (and removed from a `KeyValueStore`) so the\n * planner refetches. `dehydrate`/`hydrate` are the string forms, for SSR and\n * any other transport; `save`/`restore` put them behind Effect's\n * `KeyValueStore`, so the backend (memory, filesystem, SQL, Web Storage) is the\n * application's choice.\n */\nimport { Effect } from 'effect'\nimport { KeyValueStore } from 'effect/unstable/persistence'\nimport { stableStringify } from './query.js'\nimport { emptyStore, type EntityEntry, type EntityStore } from './store.js'\n\n/** Bump when the serialized shape changes; a mismatch discards the cache. */\nexport const REMOTE_CACHE_VERSION = 3\n\nexport interface SnapshotOptions {\n /**\n * Who or what the snapshot is for (a user id, a tenant, a build). A snapshot\n * taken under another scope is discarded rather than shown to the wrong\n * reader. Default: unscoped, which only matches unscoped.\n */\n readonly scope?: string | undefined\n /** Snapshots larger than this many bytes are not written and not read. */\n readonly maxBytes?: number | undefined\n}\n\n/** How a snapshot meets a store that already has entries. */\nexport type MergePolicy = 'replace' | 'preserve-existing'\n\ninterface SerializedEntry {\n readonly values: Readonly<Record<string, unknown>>\n readonly present: ReadonlyArray<string>\n readonly stale: ReadonlyArray<string>\n readonly tombstone: boolean\n readonly updatedAt: number\n readonly windows: Readonly<Record<string, string>>\n}\n\ninterface SerializedStore {\n readonly version: number\n readonly scope: string | null\n readonly entities: Readonly<Record<string, SerializedEntry>>\n}\n\nconst sorted = <T>(values: Iterable<T>): T[] => [...values].sort()\n\n/**\n * The snapshot's data shape. `stableStringify` sorts object keys, and the\n * field sets are sorted here, so equal stores give byte-equal snapshots\n * whatever order they were built in.\n */\nconst serializeStore = (store: EntityStore, scope?: string): SerializedStore => ({\n version: REMOTE_CACHE_VERSION,\n scope: scope ?? null,\n entities: Object.fromEntries(\n Object.entries(store).map(([key, entry]) => [\n key,\n {\n values: entry.values,\n present: sorted(entry.present),\n stale: sorted(entry.stale),\n tombstone: entry.tombstone,\n updatedAt: entry.updatedAt,\n windows: entry.windows,\n },\n ]),\n ),\n})\n\nconst isStringArray = (value: unknown): value is ReadonlyArray<string> =>\n Array.isArray(value) && value.every(item => typeof item === 'string')\n\nconst isStringRecord = (value: unknown): value is Readonly<Record<string, string>> =>\n value !== null &&\n typeof value === 'object' &&\n !Array.isArray(value) &&\n Object.values(value as Record<string, unknown>).every(item => typeof item === 'string')\n\n/** Throws on a malformed entry so the whole snapshot is discarded. */\nconst parseEntry = (value: unknown): EntityEntry => {\n if (value === null || typeof value !== 'object') throw new Error('entry is not an object')\n const entry = value as Record<string, unknown>\n if (entry.values === null || typeof entry.values !== 'object' || Array.isArray(entry.values)) {\n throw new Error('entry.values is not a record')\n }\n if (!isStringArray(entry.present)) throw new Error('entry.present is not a string array')\n if (!isStringArray(entry.stale)) throw new Error('entry.stale is not a string array')\n if (typeof entry.tombstone !== 'boolean') throw new Error('entry.tombstone is not a boolean')\n if (typeof entry.updatedAt !== 'number') throw new Error('entry.updatedAt is not a number')\n if (!isStringRecord(entry.windows)) throw new Error('entry.windows is not a string record')\n return {\n values: entry.values as Readonly<Record<string, unknown>>,\n present: new Set(entry.present),\n stale: new Set(entry.stale),\n tombstone: entry.tombstone,\n updatedAt: entry.updatedAt,\n windows: entry.windows,\n }\n}\n\nconst deserializeStore = (serialized: SerializedStore): EntityStore =>\n Object.fromEntries(\n Object.entries(serialized.entities).map(([key, entry]) => [key, parseEntry(entry)]),\n )\n\n/**\n * The snapshot text, or `undefined` when it would exceed `maxBytes`. Only the\n * entity store goes in; pass `model.entities`, never the whole `RemoteModel`.\n */\nconst dehydrate = (store: EntityStore, options: SnapshotOptions = {}): string | undefined => {\n const text = stableStringify(serializeStore(store, options.scope))\n return exceeds(text, options.maxBytes) ? undefined : text\n}\n\n/**\n * Whether the UTF-8 size of `text` exceeds `maxBytes`. A character is one to\n * three bytes, so most texts are decided from their length alone; only the\n * rest are measured.\n */\nconst exceeds = (text: string, maxBytes: number | undefined): boolean => {\n if (maxBytes === undefined) return false\n if (text.length > maxBytes) return true\n if (text.length * 3 <= maxBytes) return false\n return new TextEncoder().encode(text).length > maxBytes\n}\n\n/**\n * The store a snapshot text holds, or `undefined` when the text is missing,\n * oversized, not this version, for another scope, or malformed. Hydrating the\n * same text twice yields equal stores.\n */\nconst hydrate = (\n raw: string | undefined | null,\n options: SnapshotOptions = {},\n): EntityStore | undefined => {\n if (raw === undefined || raw === null) return undefined\n if (exceeds(raw, options.maxBytes)) return undefined\n let parsed: unknown\n try {\n parsed = JSON.parse(raw)\n } catch {\n return undefined\n }\n if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) return undefined\n const candidate = parsed as {\n readonly version?: unknown\n readonly scope?: unknown\n readonly entities?: unknown\n }\n if (candidate.version !== REMOTE_CACHE_VERSION) return undefined\n if ((candidate.scope ?? null) !== (options.scope ?? null)) return undefined\n if (candidate.entities === null || typeof candidate.entities !== 'object') return undefined\n if (Array.isArray(candidate.entities)) return undefined\n try {\n return deserializeStore(candidate as SerializedStore)\n } catch {\n return undefined\n }\n}\n\n/**\n * Brings a snapshot into a store that may already hold entries. `replace`\n * takes the snapshot's entry for every key it has; `preserve-existing` keeps\n * an entry the current store already has (it is at least as fresh as a\n * snapshot taken earlier). Either way, keys only the current store has stay.\n */\nconst mergeStores = (\n current: EntityStore,\n snapshot: EntityStore,\n policy: MergePolicy,\n): EntityStore => (policy === 'replace' ? { ...current, ...snapshot } : { ...snapshot, ...current })\n\nexport const RemotePersistence = {\n /** The snapshot text, or `undefined` when it would exceed `maxBytes`. */\n dehydrate,\n /** The store a snapshot text holds, or `undefined` when it is refused. */\n hydrate,\n /** A snapshot brought into a store by policy. */\n mergeStores,\n\n /**\n * Writes the snapshot under `key`, or removes the key when the store would\n * exceed `maxBytes`, so a stale smaller snapshot cannot outlive a larger\n * store it no longer describes.\n */\n save: (store: EntityStore, options: { readonly key: string } & SnapshotOptions) =>\n Effect.gen(function* () {\n const kv = yield* KeyValueStore.KeyValueStore\n const text = dehydrate(store, options)\n if (text === undefined) yield* kv.remove(options.key)\n else yield* kv.set(options.key, text)\n }),\n\n /**\n * Reads the cache. A missing key yields `emptyStore`; anything `hydrate`\n * refuses yields `emptyStore` and removes the key, so the next `restore` is\n * clean and the planner refetches.\n */\n restore: (options: { readonly key: string } & SnapshotOptions) =>\n Effect.gen(function* () {\n const kv = yield* KeyValueStore.KeyValueStore\n const raw = yield* kv.get(options.key)\n if (raw === undefined) return emptyStore\n const restored = hydrate(raw, options)\n if (restored === undefined) {\n yield* kv.remove(options.key)\n return emptyStore\n }\n return restored\n }),\n}\n","/** `RemoteData`: the state of a value the store may not hold yet. */\nimport { Option, Schema } from 'effect'\n\nexport interface RemoteError {\n readonly _tag: string\n readonly message: string\n}\n\nexport type RemoteData<A> =\n | { readonly _tag: 'Initial' }\n | { readonly _tag: 'Loading' }\n | { readonly _tag: 'Ready'; readonly value: A }\n | { readonly _tag: 'Refreshing'; readonly value: A }\n | { readonly _tag: 'Failed'; readonly error: RemoteError; readonly previous?: A }\n | { readonly _tag: 'NotFound' }\n\nexport const remoteErrorSchema = Schema.Struct({ _tag: Schema.String, message: Schema.String })\n\n/** A `RemoteData` schema, so a projection that reads remote state is typed. */\n// A projection is rebuilt on every Model change (a Surface's `model` callback\n// runs per dependency computation), so the schema for a value schema is built\n// once and shared: the value schema is a module-level constant in practice.\nconst remoteDataSchemas = new WeakMap<object, Schema.Schema<unknown>>()\n\nexport const remoteDataSchema = <A>(value: Schema.Schema<A>): Schema.Schema<RemoteData<A>> => {\n const cached = remoteDataSchemas.get(value)\n if (cached !== undefined) return cached as Schema.Schema<RemoteData<A>>\n const built = Schema.Union([\n Schema.Struct({ _tag: Schema.Literal('Initial') }),\n Schema.Struct({ _tag: Schema.Literal('Loading') }),\n Schema.Struct({ _tag: Schema.Literal('Ready'), value }),\n Schema.Struct({ _tag: Schema.Literal('Refreshing'), value }),\n Schema.Struct({\n _tag: Schema.Literal('Failed'),\n error: remoteErrorSchema,\n previous: Schema.optional(value),\n }),\n Schema.Struct({ _tag: Schema.Literal('NotFound') }),\n ]) as unknown as Schema.Schema<RemoteData<A>>\n remoteDataSchemas.set(value, built as Schema.Schema<unknown>)\n return built\n}\n\nexport const RemoteData = {\n /**\n * The `RemoteData` schema for a value schema. Exposed so a `RemoteData` can\n * be embedded in a hand-written Model schema, not only through `Remote.select`.\n */\n schema: <A>(value: Schema.Schema<A>): Schema.Schema<RemoteData<A>> => remoteDataSchema(value),\n\n /** Exhaustive: omitting a state is a compile error. */\n match: <A, R>(\n data: RemoteData<A>,\n cases: {\n readonly Initial: () => R\n readonly Loading: () => R\n readonly Ready: (value: A) => R\n readonly Refreshing: (value: A) => R\n readonly Failed: (error: RemoteError, previous: Option.Option<A>) => R\n readonly NotFound: () => R\n },\n ): R => {\n switch (data._tag) {\n case 'Initial':\n return cases.Initial()\n case 'Loading':\n return cases.Loading()\n case 'Ready':\n return cases.Ready(data.value)\n case 'Refreshing':\n return cases.Refreshing(data.value)\n case 'Failed':\n return cases.Failed(\n data.error,\n data.previous === undefined ? Option.none() : Option.some(data.previous),\n )\n case 'NotFound':\n return cases.NotFound()\n }\n },\n\n map: <A, B>(data: RemoteData<A>, f: (value: A) => B): RemoteData<B> => {\n switch (data._tag) {\n case 'Ready':\n return { _tag: 'Ready', value: f(data.value) }\n case 'Refreshing':\n return { _tag: 'Refreshing', value: f(data.value) }\n case 'Failed':\n return data.previous === undefined\n ? { _tag: 'Failed', error: data.error }\n : { _tag: 'Failed', error: data.error, previous: f(data.previous) }\n default:\n return data\n }\n },\n}\n","/**\n * The Remote submodel: the store, connections, mutations, live state, and\n * optimistic layers an application keeps in its Model, the Messages that\n * change it, and the pure reducer over them.\n */\nimport { Schema } from 'effect'\nimport type { Requirement } from 'foldkit-surface'\nimport { emptyConnection, merge, type Connection, type Segment } from './connection.js'\nimport {\n beginOptimistic,\n emptyOptimistic,\n pruneOverlays,\n settleFailure,\n settleSuccess,\n type ConnectionChange,\n type OptimisticState,\n type OptimisticOperation,\n} from './optimistic.js'\nimport {\n applyConnectionEvent,\n applyEntityEvent,\n emptyLiveState,\n type LiveEvent,\n type LiveState,\n} from './live.js'\nimport {\n beginMutation,\n emptyMutationState,\n failMutation,\n type MutationState,\n type NormalizedPatch,\n} from './mutation.js'\nimport {\n entityKey,\n emptyStore,\n setStale,\n writeEntities,\n type EntityStore,\n type EntityWrite,\n} from './store.js'\nimport { windowKey } from './plan.js'\nimport { isRefPage, targetsOf, type RefPageValue } from './relation.js'\nimport { gc, type RetentionRoots } from './retain.js'\nimport { RemotePersistence, type MergePolicy } from './persistence.js'\nimport { NormalizedEntity, ReadBatchResult, ReadRequest, RelationRequest } from './wire.js'\nimport { remoteErrorSchema, type RemoteError } from './remoteData.js'\nimport type { LivePolicy } from './query.js'\n\n/**\n * The normalized cache as a Foldkit Submodel. `Remote.define` returns a schema\n * and an `update` for this shape; `updateRemote` reconciles every producer.\n */\nexport interface RemoteModel {\n /** Entity values, presence, staleness, tombstones, and applied windows. */\n readonly entities: EntityStore\n /** Normalized ordered connections, keyed by connection identity. */\n readonly connections: Readonly<Record<string, Connection>>\n /** Optimistic entity layers and connection overlays over the base store. */\n readonly optimistic: OptimisticState\n /** Live cursor and boundary state, keyed by the subscription's stream key. */\n readonly live: Readonly<Record<string, LiveState>>\n /** Mutation pending/applied/failed ledger. */\n readonly mutations: MutationState\n /** Streams whose live cursor fell behind; the caller should resync or refetch. */\n readonly gaps: ReadonlySet<string>\n /**\n * The `entity\\0id\\0field` marks a read is currently fetching. A field absent\n * from the store reads as `Loading` while its mark is here and `Initial`\n * otherwise, which is what separates \"being fetched\" from \"nothing is\n * fetching this\".\n */\n readonly loading: ReadonlySet<string>\n}\n\nexport const initialRemoteModel: RemoteModel = {\n entities: emptyStore,\n connections: {},\n optimistic: emptyOptimistic,\n live: {},\n mutations: emptyMutationState,\n gaps: new Set(),\n loading: new Set(),\n}\n\n/** The entity store and the mutation ledger are runtime values, not wire shapes. */\nconst runtimeSchema = Schema.Unknown\n\nexport const remoteModelSchema = (): Schema.Schema<RemoteModel> =>\n Schema.Struct({\n entities: runtimeSchema,\n connections: Schema.Record(Schema.String, runtimeSchema),\n optimistic: runtimeSchema,\n live: Schema.Record(Schema.String, runtimeSchema),\n mutations: runtimeSchema,\n gaps: runtimeSchema,\n loading: runtimeSchema,\n }) as unknown as Schema.Schema<RemoteModel>\n\n/** The submodel's Messages; each reduces to `RemoteModel` through `updateRemote`. */\nexport type RemoteMessage =\n | {\n readonly _tag: 'ReadReceived'\n readonly requests: readonly Requirement[]\n readonly result: Schema.Schema.Type<typeof ReadBatchResult>\n readonly now: number\n }\n | {\n readonly _tag: 'ReadFailed'\n readonly requests: readonly Requirement[]\n readonly error: RemoteError\n }\n /** A refetch of present fields began; they read as `Refreshing` until it lands. */\n | { readonly _tag: 'RefreshStarted'; readonly requests: readonly Requirement[] }\n /** A read began; the fields it asks for that the store lacks read as `Loading`. */\n | { readonly _tag: 'ReadStarted'; readonly requests: readonly Requirement[] }\n /** The active Surfaces' roots changed; everything they do not reach is collected. */\n | { readonly _tag: 'RetentionChanged'; readonly roots: RetentionRoots }\n /** A restored snapshot meets the store; runtime state is untouched. */\n | { readonly _tag: 'Hydrated'; readonly entities: EntityStore; readonly merge: MergePolicy }\n /** A mutation began; its optimistic operations show until it settles. */\n | {\n readonly _tag: 'MutationStarted'\n readonly requestId: string\n readonly optimistic?: ReadonlyArray<OptimisticOperation> | undefined\n }\n | {\n readonly _tag: 'MutationSucceeded'\n readonly requestId: string\n readonly entities: readonly NormalizedPatch[]\n /** Connection changes the server confirmed; they replace the request's own. */\n readonly connections?: ReadonlyArray<ConnectionChange> | undefined\n }\n | { readonly _tag: 'MutationFailed'; readonly requestId: string; readonly error: RemoteError }\n | {\n readonly _tag: 'LiveReceived'\n readonly stream: string\n readonly event: LiveEvent\n readonly policy?: LivePolicy\n readonly now: number\n }\n | { readonly _tag: 'GapCleared'; readonly stream: string }\n | {\n readonly _tag: 'ConnectionMerged'\n readonly connection: string\n readonly page: Segment\n /** The page answers the connection's refresh, so the merge also clears `stale`. */\n readonly refreshes?: boolean | undefined\n }\n | { readonly _tag: 'ConnectionInvalidated'; readonly connection: string }\n | { readonly _tag: 'ConnectionRefreshed'; readonly connection: string }\n /** A query for the connection failed; it reads as it did before the request. */\n | { readonly _tag: 'QueryFailed'; readonly connection: string; readonly error: RemoteError }\n\nexport const retentionRootsSchema = Schema.Struct({\n requirements: Schema.Array(ReadRequest),\n connections: Schema.Array(\n Schema.Struct({ identity: Schema.String, select: Schema.optional(RelationRequest) }),\n ),\n})\n\n/**\n * The Messages' fields by tag, without `_tag`: what `defineMessageUnion` takes,\n * so an application spreads them into its own union (`Remote.messages`).\n */\nexport const remoteMessageCases = {\n ReadReceived: {\n requests: Schema.Array(ReadRequest),\n result: ReadBatchResult,\n now: Schema.Number,\n },\n ReadFailed: { requests: Schema.Array(ReadRequest), error: remoteErrorSchema },\n RefreshStarted: { requests: Schema.Array(ReadRequest) },\n ReadStarted: { requests: Schema.Array(ReadRequest) },\n RetentionChanged: { roots: retentionRootsSchema },\n Hydrated: {\n entities: runtimeSchema,\n merge: Schema.Union([Schema.Literal('replace'), Schema.Literal('preserve-existing')]),\n },\n MutationStarted: {\n requestId: Schema.String,\n optimistic: Schema.optional(Schema.Array(Schema.Unknown)),\n },\n MutationSucceeded: {\n requestId: Schema.String,\n entities: Schema.Array(NormalizedEntity),\n connections: Schema.optional(Schema.Array(Schema.Unknown)),\n },\n MutationFailed: { requestId: Schema.String, error: remoteErrorSchema },\n LiveReceived: {\n stream: Schema.String,\n event: Schema.Unknown,\n policy: Schema.optional(Schema.Unknown),\n now: Schema.Number,\n },\n GapCleared: { stream: Schema.String },\n ConnectionMerged: {\n connection: Schema.String,\n page: Schema.Unknown,\n refreshes: Schema.optional(Schema.Boolean),\n },\n ConnectionInvalidated: { connection: Schema.String },\n ConnectionRefreshed: { connection: Schema.String },\n QueryFailed: { connection: Schema.String, error: remoteErrorSchema },\n} satisfies Record<RemoteMessage['_tag'], Schema.Struct.Fields>\n\nexport type RemoteMessageTag = RemoteMessage['_tag']\n\n/**\n * A Remote Message as an application's union constructs it from\n * `remoteMessageCases`: the same shape `RemoteMessage` names, with the runtime\n * slots (`entities`, `event`, `page`) typed `unknown` by their schemas.\n */\nexport type RemoteMessageInput = {\n [Tag in RemoteMessageTag]: { readonly _tag: Tag } & Schema.Struct.Type<\n (typeof remoteMessageCases)[Tag]\n >\n}[RemoteMessageTag]\n\n/**\n * Whether a Message is one of Remote's, by tag. Narrows an application's union\n * to its Remote cases, and its complement to the application's own.\n */\nexport const isRemoteMessage = <M extends { readonly _tag: string }>(\n message: M,\n): message is Extract<M, { readonly _tag: RemoteMessageTag }> =>\n Object.hasOwn(remoteMessageCases, message._tag)\n\nexport const remoteMessageSchema = Schema.Union(\n Object.entries(remoteMessageCases).map(([tag, fields]) =>\n Schema.Struct({ _tag: Schema.Literal(tag), ...fields }),\n ),\n) as unknown as Schema.Schema<RemoteMessage>\n\nconst marksOf = (\n requests: ReadonlyArray<Requirement>,\n): ReadonlyArray<readonly [string, ReadonlyArray<string>]> =>\n requests.map(request => [entityKey(request.entity, request.id), request.fields] as const)\n\n/**\n * One mark per requested field. A read is identified by what it asks for, not by\n * a request id: two reads asking for one field share its mark, so the first\n * answer clears it. Over-clearing shows `Initial` rather than a spinner, which\n * is the safer way to be wrong.\n */\nconst loadingMarks = function* (requests: ReadonlyArray<Requirement>): Generator<string> {\n for (const request of requests) {\n const key = entityKey(request.entity, request.id)\n for (const field of request.fields) yield `${key}\\u0000${field}`\n }\n}\n\nconst withLoading = (\n loading: ReadonlySet<string>,\n requests: ReadonlyArray<Requirement>,\n): ReadonlySet<string> => {\n const next = new Set(loading)\n for (const mark of loadingMarks(requests)) next.add(mark)\n return next\n}\n\nconst withoutLoading = (\n loading: ReadonlySet<string>,\n requests: ReadonlyArray<Requirement>,\n): ReadonlySet<string> => {\n if (loading.size === 0) return loading\n const next = new Set(loading)\n for (const mark of loadingMarks(requests)) next.delete(mark)\n return next\n}\n\n/**\n * Whether a read is fetching any of `fields` for this entity. Consulted only\n * when the store lacks the value, which is what separates `Loading` from\n * `Initial`.\n */\nexport const isLoading = (\n model: RemoteModel,\n entity: string,\n id: string,\n fields: ReadonlyArray<string>,\n): boolean => {\n if (model.loading.size === 0) return false\n const key = entityKey(entity, id)\n return fields.some(field => model.loading.has(`${key}\\u0000${field}`))\n}\n\nconst setConnectionStale = (\n connections: Readonly<Record<string, Connection>>,\n connection: string,\n stale: boolean,\n): Readonly<Record<string, Connection>> => {\n const current = connections[connection] ?? emptyConnection\n return { ...connections, [connection]: { ...current, stale } }\n}\n\nconst markGap = (model: RemoteModel, stream: string): RemoteModel =>\n model.gaps.has(stream) ? model : { ...model, gaps: new Set([...model.gaps, stream]) }\n\nconst clearGap = (model: RemoteModel, stream: string): RemoteModel =>\n model.gaps.has(stream)\n ? { ...model, gaps: new Set([...model.gaps].filter(entry => entry !== stream)) }\n : model\n\n/**\n * The pure reducer all four producers share. A live event that arrives ahead of\n * its cursor is a gap: it is not applied, and the stream is recorded so the host\n * can resubscribe rather than silently miss facts.\n */\nexport const updateRemote = (model: RemoteModel, message: RemoteMessage): RemoteModel => {\n switch (message._tag) {\n case 'ReadReceived':\n return {\n ...model,\n entities: writeRead(model.entities, message.requests, message.result, message.now),\n loading: withoutLoading(model.loading, message.requests),\n }\n case 'ReadFailed':\n // The read is over; the fields read as they did before it started. A field\n // it never delivered goes back to `Initial`, not a spinner that never ends.\n return {\n ...model,\n entities: setStale(model.entities, marksOf(message.requests), false),\n loading: withoutLoading(model.loading, message.requests),\n }\n case 'RetentionChanged':\n return { ...model, ...gc(model, message.roots) }\n case 'Hydrated':\n return {\n ...model,\n entities: RemotePersistence.mergeStores(model.entities, message.entities, message.merge),\n }\n case 'RefreshStarted':\n return { ...model, entities: setStale(model.entities, marksOf(message.requests), true) }\n case 'ReadStarted':\n return { ...model, loading: withLoading(model.loading, message.requests) }\n case 'MutationStarted':\n return {\n ...model,\n mutations: beginMutation(model.mutations, message.requestId),\n optimistic: beginOptimistic(model.optimistic, message.requestId, message.optimistic ?? []),\n }\n case 'MutationSucceeded': {\n // Settling is release-the-layer-and-overlays, so overlapping optimistic\n // layers rebase instead of needing inverse patches.\n const settled = settleSuccess(\n model.entities,\n model.optimistic,\n model.mutations,\n message.requestId,\n message.entities,\n message.connections ?? [],\n )\n return {\n ...model,\n entities: settled.store,\n mutations: settled.state,\n optimistic: settled.optimistic,\n }\n }\n case 'MutationFailed':\n return {\n ...model,\n mutations: failMutation(model.mutations, message.requestId),\n optimistic: settleFailure(model.optimistic, message.requestId),\n }\n case 'LiveReceived': {\n const state = model.live[message.stream] ?? emptyLiveState\n if (message.event._tag === 'EntityPatched' || message.event._tag === 'EntityDeleted') {\n const applied = applyEntityEvent(state, model.entities, message.event, message.now)\n return applied.outcome === 'gap'\n ? markGap(model, message.stream)\n : clearGap(\n {\n ...model,\n entities: applied.store,\n live: { ...model.live, [message.stream]: applied.state },\n },\n message.stream,\n )\n }\n const applied = applyConnectionEvent(state, model.optimistic, message.event, message.policy)\n return applied.outcome === 'gap'\n ? markGap(model, message.stream)\n : clearGap(\n {\n ...model,\n optimistic: applied.optimistic,\n live: { ...model.live, [message.stream]: applied.state },\n },\n message.stream,\n )\n }\n case 'GapCleared':\n return clearGap(model, message.stream)\n case 'ConnectionMerged': {\n const current = model.connections[message.connection] ?? emptyConnection\n const merged = merge(current, message.page)\n return {\n ...model,\n connections: {\n ...model.connections,\n [message.connection]: message.refreshes === true ? { ...merged, stale: false } : merged,\n },\n optimistic: pruneOverlays(\n model.optimistic,\n message.connection,\n new Set(message.page.edges.map(edge => edge.key)),\n model.mutations.pending,\n ),\n }\n }\n case 'ConnectionInvalidated':\n return {\n ...model,\n connections: setConnectionStale(model.connections, message.connection, true),\n }\n case 'QueryFailed':\n // The refresh is over; the connection reads as it did before it started,\n // and one the Model never held stays absent.\n return message.connection in model.connections\n ? {\n ...model,\n connections: setConnectionStale(model.connections, message.connection, false),\n }\n : model\n case 'ConnectionRefreshed':\n return {\n ...model,\n connections: setConnectionStale(model.connections, message.connection, false),\n }\n }\n}\n\n/** Appends (after) or prepends (before) an incoming page onto the stored one. */\nconst mergeWireRefPages = (\n current: RefPageValue,\n next: RefPageValue,\n direction: 'after' | 'before',\n): RefPageValue => {\n const refs =\n direction === 'after'\n ? [...new Set([...current.refs, ...next.refs])]\n : [...new Set([...next.refs, ...current.refs])]\n // The far boundary is the incoming page's; the near one is still the stored page's.\n return direction === 'after'\n ? { refs, hasNext: next.hasNext, hasPrevious: current.hasPrevious }\n : { refs, hasNext: current.hasNext, hasPrevious: next.hasPrevious }\n}\n\n/**\n * Writes a read result into the store, recording each field's applied window so\n * a later request with a different window refetches. A relation page requested\n * with a cursor is merged onto the page already stored, so \"load more\"\n * accumulates rather than replaces. Every read path should use this rather than\n * reducing `writeEntity` by hand.\n */\nexport const writeRead = (\n store: EntityStore,\n requests: ReadonlyArray<Requirement>,\n result: Schema.Schema.Type<typeof ReadBatchResult>,\n now = 0,\n): EntityStore => {\n const returned = new Map<string, Record<string, unknown>>()\n for (const entity of result.entities) {\n const key = entityKey(entity.entity, entity.id)\n returned.set(key, { ...returned.get(key), ...entity.values })\n }\n const byEntity = new Map<\n string,\n { windows: Record<string, string>; merge: Map<string, 'after' | 'before'> }\n >()\n // A request's windows apply to its entity; a relation's windows apply to\n // each target the returned refs name, and so on down the graph.\n const record = (\n key: string,\n windows: Requirement['windows'],\n relations: Requirement['relations'],\n ): void => {\n let entry = byEntity.get(key)\n if (entry === undefined) {\n entry = { windows: {}, merge: new Map() }\n byEntity.set(key, entry)\n }\n for (const [field, window] of Object.entries(windows ?? {})) {\n entry.windows[field] = windowKey(window)\n const direction =\n window.after !== undefined ? 'after' : window.before !== undefined ? 'before' : undefined\n if (direction !== undefined) entry.merge.set(field, direction)\n }\n const values = returned.get(key)\n if (values === undefined) return\n for (const [field, relation] of Object.entries(relations ?? {})) {\n for (const ref of targetsOf(values[field], relation)) {\n record(entityKey(ref.entity, ref.id), relation.windows, relation.relations)\n }\n }\n }\n for (const request of requests) {\n record(entityKey(request.entity, request.id), request.windows, request.relations)\n }\n\n const writes: EntityWrite[] = []\n const pending = new Map<string, Record<string, unknown>>()\n for (const entity of result.entities) {\n const key = entityKey(entity.entity, entity.id)\n const entry = byEntity.get(key)\n let values = entity.values\n if (entry !== undefined && entry.merge.size > 0) {\n // A cursor page merges onto the page stored (or written earlier in this result).\n const previous = pending.get(key) ?? store[key]?.values\n if (previous !== undefined) {\n const merged: Record<string, unknown> = { ...values }\n for (const [field, direction] of entry.merge) {\n const incoming = values[field]\n const existing = previous[field]\n if (isRefPage(incoming) && isRefPage(existing)) {\n merged[field] = mergeWireRefPages(existing, incoming, direction)\n }\n }\n values = merged\n }\n }\n pending.set(key, { ...pending.get(key), ...values })\n writes.push({ key, values, windows: entry?.windows })\n }\n return writeEntities(store, writes, now)\n}\n","/**\n * Request policies: how a read treats fields the store already holds. A policy\n * compiles to planner options; it is not a second cache. `Remote.observe` and\n * `Remote.prefetch` take one, and the planner itself stays pure and\n * time-injected.\n */\nimport type { PlanOptions } from './plan.js'\n\nexport type RemotePolicy =\n /** Fetch only fields the store lacks (missing, stale, or re-windowed). */\n | { readonly _tag: 'CacheFirst' }\n /**\n * Keep present values visible, read them as `Refreshing`, and refetch an\n * entry older than `maxAge` milliseconds.\n */\n | { readonly _tag: 'StaleWhileRevalidate'; readonly maxAge: number }\n /** Fetch every selected field regardless of coverage; cached values stay visible meanwhile. */\n | { readonly _tag: 'NetworkOnly' }\n\nexport const RemotePolicy = {\n /** Fetch only what the store lacks. */\n cacheFirst: { _tag: 'CacheFirst' } as const satisfies RemotePolicy,\n\n /** Keep present values visible, read as `Refreshing`, and refetch an entry older than `maxAge` ms. */\n staleWhileRevalidate: (options: { readonly maxAge: number }): RemotePolicy => ({\n _tag: 'StaleWhileRevalidate',\n maxAge: options.maxAge,\n }),\n\n /** Fetch every selected field regardless of coverage; cached values stay visible meanwhile. */\n networkOnly: { _tag: 'NetworkOnly' } as const satisfies RemotePolicy,\n\n /** The planner options a policy compiles to at `now`. */\n toPlan: (policy: RemotePolicy, now: number): PlanOptions => {\n switch (policy._tag) {\n case 'CacheFirst':\n return {}\n case 'StaleWhileRevalidate':\n return { freshness: { now, freshness: policy.maxAge } }\n case 'NetworkOnly':\n return { force: true }\n }\n },\n\n /**\n * Whether a read under this policy may refetch fields the store already\n * holds, so an observer marks them stale (read as `Refreshing`) while the\n * request is pending.\n */\n refreshes: (policy: RemotePolicy): boolean => policy._tag !== 'CacheFirst',\n}\n","/**\n * Entities: the descriptor an application declares, refs, ref pages, and\n * patches, with the codecs that carry refs on the wire.\n */\nimport { Schema, SchemaGetter } from 'effect'\nimport { RelationAnnotation, RelationEntityAnnotation, refParts } from './relation.js'\n// selection.ts imports this module too; both only use the other inside\n// function bodies, so the cycle is never observed at module evaluation.\nimport { Selection, type SelectionOf, type SelectionValue } from './selection.js'\nimport { entityKey } from './store.js'\n\nexport type AnySchema = Schema.Schema<unknown>\n\ndeclare const entityRefFields: unique symbol\n\n/**\n * A normalized reference to an entity. `F` is a phantom carrying the entity's\n * fields so `Entity.patch` can type its patch; it is absent at runtime.\n */\nexport interface EntityRef<\n Name extends string,\n F extends Schema.Struct.Fields = Schema.Struct.Fields,\n> {\n readonly entity: Name\n readonly id: string\n readonly [entityRefFields]?: F\n}\n\nexport interface EntityDescriptor<Name extends string, F extends Schema.Struct.Fields> {\n readonly name: Name\n readonly schema: Schema.Struct<F>\n readonly fields: F\n // Methods, not properties: method signatures are bivariant, so a concrete\n // descriptor stays assignable to `EntityDescriptor<any, any>` (which appears\n // in every heterogeneous collection, e.g. `Remote.make`'s entities).\n ref(id: Schema.Schema.Type<F['id']>): EntityRef<Name, F>\n /** The fields a Surface reads of this entity; `Selection.make(entity, …)` with the entity as receiver. */\n select<const Sel extends SelectionOf<F>>(\n selection: Sel,\n ): Selection<SelectionValue<F, Sel>, Name, 'entity'>\n /** A patch of this entity's wire-shaped values; `Entity.patch(entity.ref(id), values)`. */\n patch(\n id: Schema.Schema.Type<F['id']>,\n values: Partial<Schema.Struct.Encoded<F>>,\n ): EntityPatch<Name, F>\n}\n\n/**\n * Relations are **references**, never inline target schemas: a ref cannot\n * reconstruct a full entity, and dereferencing is a store concern. Because the\n * target schema is not inlined, recursive relations cannot arise through the\n * schema graph.\n */\nconst refCodec = <Name extends string, F extends Schema.Struct.Fields>(\n entity: Name,\n): Schema.Codec<EntityRef<Name, F>, string> =>\n Schema.Struct({ entity: Schema.String, id: Schema.String })\n .pipe(\n Schema.encodeTo(Schema.String, {\n decode: SchemaGetter.transform(refParts),\n encode: SchemaGetter.transform((ref: EntityRef<string>) => entityKey(ref.entity, ref.id)),\n }),\n )\n .annotate({\n [RelationAnnotation]: 'one',\n [RelationEntityAnnotation]: entity,\n }) as unknown as Schema.Codec<EntityRef<Name, F>, string>\n\n/**\n * A patch in wire shape: the values the store holds, so a relation is its ref\n * key (`Entity.refKey`), not an `EntityRef`.\n */\nexport interface EntityPatch<Name extends string, F extends Schema.Struct.Fields> {\n readonly entity: Name\n readonly id: string\n readonly values: Partial<Schema.Struct.Encoded<F>>\n}\n\n/**\n * One authoritative page of a paginated relation: refs (never inline entities)\n * plus whether more exist. The adapter does not hold segmentation state; the\n * client merges pages.\n */\nexport interface RefPage<\n Name extends string,\n F extends Schema.Struct.Fields = Schema.Struct.Fields,\n> {\n readonly refs: ReadonlyArray<EntityRef<Name, F>>\n readonly hasNext: boolean\n readonly hasPrevious: boolean\n}\n\nconst refPageCodec = <Name extends string, F extends Schema.Struct.Fields>(\n entity: Name,\n): Schema.Codec<\n RefPage<Name, F>,\n {\n readonly refs: ReadonlyArray<string>\n readonly hasNext: boolean\n readonly hasPrevious: boolean\n }\n> =>\n Schema.Struct({\n refs: Schema.Array(refCodec<Name, F>(entity)),\n hasNext: Schema.Boolean,\n hasPrevious: Schema.Boolean,\n }).annotate({\n [RelationAnnotation]: 'page',\n [RelationEntityAnnotation]: entity,\n }) as unknown as Schema.Codec<\n RefPage<Name, F>,\n {\n readonly refs: ReadonlyArray<string>\n readonly hasNext: boolean\n readonly hasPrevious: boolean\n }\n >\n\nexport const Entity = {\n make: <\n const Name extends string,\n const F extends Schema.Struct.Fields & { readonly id: Schema.Schema<unknown> },\n >(\n name: Name,\n schema: Schema.Struct<F>,\n ): EntityDescriptor<Name, F> => {\n const descriptor: EntityDescriptor<Name, F> = {\n name,\n schema,\n fields: schema.fields,\n ref: id => ({ entity: name, id: String(id) }) as EntityRef<Name, F>,\n select: selection => Selection.make(descriptor, selection),\n patch: (id, values) => ({ entity: name, id: String(id), values }),\n }\n return descriptor\n },\n\n /** A relation to a known entity, decoded as a reference. */\n ref: <Name extends string, F extends Schema.Struct.Fields>(\n entity: EntityDescriptor<Name, F>,\n ): Schema.Codec<EntityRef<Name, F>, string> => refCodec<Name, F>(entity.name),\n\n /** A relation by name, for recursive or forward references. */\n refTo: <Name extends string>(name: Name): Schema.Codec<EntityRef<Name>, string> =>\n refCodec<Name, Schema.Struct.Fields>(name),\n\n /**\n * The wire key a relation field carries (`\"Entity:id\"`). Adapters that read a\n * foreign key emit this so the ref codec can decode it on the client.\n */\n refKey: (ref: { readonly entity: string; readonly id: string }): string =>\n entityKey(ref.entity, ref.id),\n\n /** Splits a ref key back into its entity and id. */\n refParts,\n\n /** A relation value of one authoritative page of refs. */\n refPage: <Name extends string, F extends Schema.Struct.Fields>(\n entity: EntityDescriptor<Name, F>,\n ): Schema.Codec<\n RefPage<Name, F>,\n {\n readonly refs: ReadonlyArray<string>\n readonly hasNext: boolean\n readonly hasPrevious: boolean\n }\n > => refPageCodec<Name, F>(entity.name),\n\n /**\n * A normalized patch for an entity, typed against its fields' wire shape:\n * write a relation as its ref key (`Entity.refKey`), as the server does.\n */\n patch: <Name extends string, F extends Schema.Struct.Fields>(\n ref: EntityRef<Name, F>,\n patch: Partial<Schema.Struct.Encoded<F>>,\n ): EntityPatch<Name, F> => ({ entity: ref.entity, id: ref.id, values: patch }),\n}\n","/**\n * Selections: the fields a Surface picks of an entity (nested through\n * relations, paged through connections), the requirement graph they imply,\n * and their assembly from the normalized store.\n */\nimport { Option, Schema } from 'effect'\nimport type { RelationRequirement } from 'foldkit-surface'\nimport {\n Entity,\n type AnySchema,\n type EntityDescriptor,\n type EntityRef,\n type RefPage,\n} from './entity.js'\nimport type { QueryWindow } from './query.js'\nimport { isRefPage, relationShape, targetsOf } from './relation.js'\nimport { entityKey, isFieldStale, isTombstone, readField, type EntityStore } from './store.js'\n\n/** One page of a paginated relation with each target assembled through a nested selection. */\nexport interface Page<Item> {\n readonly items: ReadonlyArray<Item>\n readonly hasNext: boolean\n readonly hasPrevious: boolean\n}\n\n/**\n * The fields a projection reads of one entity, plus the slice it reads of each\n * relation's target. `Shape` tells a parent selection whether this one is a\n * paginated relation (`connection`) or a plain entity slice (`entity`).\n */\nexport interface Selection<\n Value,\n Name extends string = string,\n Shape extends 'entity' | 'connection' = 'entity' | 'connection',\n> {\n readonly entity: Name\n readonly fields: readonly string[]\n /** A pure codec: entity fields carry no decoding or encoding services. */\n readonly schema: Schema.Codec<Value, unknown, never, never>\n /** Pagination windows for nested relation fields, keyed by field name. */\n readonly connections?: Readonly<Record<string, QueryWindow>> | undefined\n /** The slice required of each nested relation's target, keyed by field name. */\n readonly relations?: Readonly<Record<string, RelationRequirement>> | undefined\n /** Present when this selection is itself a paginated relation. */\n readonly window?: QueryWindow | undefined\n /** Phantom: see `Shape`. */\n readonly shape?: Shape | undefined\n}\n\n/** Flattens a mapped type so hovers show the picked fields, not the machinery. */\ntype Simplify<T> = T extends infer O ? { readonly [K in keyof O]: O[K] } : never\n\n/** The value a Selection reads: `Selection.Value<typeof ProjectCard>`. */\nexport type SelectionValueOf<S> = S extends Selection<infer V, any, any> ? V : never\n\n/** The nested selections a relation field admits: of its target entity, in the shapes its value takes. */\ntype NestedFor<Field> =\n Exclude<Field, null | undefined> extends ReadonlyArray<EntityRef<infer Name, any>>\n ? Selection<unknown, Name, 'entity' | 'connection'>\n : Exclude<Field, null | undefined> extends RefPage<infer Name, any>\n ? Selection<unknown, Name, 'entity' | 'connection'>\n : Exclude<Field, null | undefined> extends EntityRef<infer Name, any>\n ? Selection<unknown, Name, 'entity'>\n : never\n\n/** What a selection of an entity with fields `F` may pick: `true` per scalar, a nested selection per relation. */\nexport type SelectionOf<F extends Schema.Struct.Fields> = {\n readonly [K in keyof F]?: true | NestedFor<Schema.Schema.Type<F[K]>>\n}\n\n/** `T | null` when the field admits `null` or `undefined` (both assemble to `null`). */\ntype Nullable<Field, T> = [Extract<Field, null | undefined>] extends [never] ? T : T | null\n\n/** A nested selection's value takes the shape of the field it selects through. */\ntype NestedValue<Field, Sel> =\n Sel extends Selection<infer V, string, 'connection'>\n ? Nullable<Field, V>\n : Sel extends Selection<infer V, string, 'entity'>\n ? Nullable<\n Field,\n Exclude<Field, null | undefined> extends ReadonlyArray<EntityRef<any, any>>\n ? ReadonlyArray<V>\n : Exclude<Field, null | undefined> extends RefPage<any, any>\n ? Page<V>\n : V\n >\n : never\n\n/** The value a selection `Sel` of fields `F` reads. */\nexport type SelectionValue<F extends Schema.Struct.Fields, Sel> = Simplify<{\n readonly [K in keyof Sel & keyof F]: Sel[K] extends true\n ? Schema.Schema.Type<F[K]>\n : NestedValue<Schema.Schema.Type<F[K]>, Sel[K]>\n}>\n\n// Built once per item schema, as `remoteDataSchema` is: a query projection is\n// rebuilt on every Model change.\nconst pageSchemas = new WeakMap<object, AnySchema>()\n\nexport const pageSchema = (item: AnySchema): AnySchema => {\n const cached = pageSchemas.get(item)\n if (cached !== undefined) return cached\n const built = Schema.Struct({\n items: Schema.Array(item),\n hasNext: Schema.Boolean,\n hasPrevious: Schema.Boolean,\n }) as unknown as AnySchema\n pageSchemas.set(item, built)\n return built\n}\n\n/** The requirement a nested selection contributes for its relation's target. */\nexport const relationOf = (selection: Selection<unknown>): RelationRequirement => ({\n entity: selection.entity,\n fields: selection.fields,\n ...(selection.connections === undefined ? {} : { windows: selection.connections }),\n ...(selection.relations === undefined ? {} : { relations: selection.relations }),\n})\n\nexport const Selection = {\n /**\n * The fields to read of `entity`. A nested `Selection` on a relation field\n * reads through the ref (or refs, or page of refs) the field holds into the\n * target's fields; a scalar field cannot take one.\n */\n make: <Name extends string, F extends Schema.Struct.Fields, const Sel extends SelectionOf<F>>(\n entity: EntityDescriptor<Name, F>,\n selection: Sel,\n ): Selection<SelectionValue<F, Sel>, Name, 'entity'> => {\n if (Object.keys(selection).length === 0) {\n throw new Error(`Selection.make: a selection of \"${entity.name}\" picks at least one field`)\n }\n const picked: Record<string, AnySchema> = {}\n const connections: Record<string, QueryWindow> = {}\n const relations: Record<string, RelationRequirement> = {}\n for (const key of Object.keys(selection)) {\n const choice = (selection as Record<string, unknown>)[key]\n if (choice === true) {\n picked[key] = entity.fields[key] as AnySchema\n continue\n }\n const nested = choice as Selection<unknown>\n const shape = relationShape(entity.fields[key] as Schema.Top)\n if (shape === undefined) {\n throw new Error(\n `Selection.make: \"${key}\" on \"${entity.name}\" is not a relation field, so it cannot take a nested selection`,\n )\n }\n if (nested.entity !== shape.entity) {\n throw new Error(\n `Selection.make: \"${key}\" on \"${entity.name}\" refers to \"${shape.entity}\", not \"${nested.entity}\"`,\n )\n }\n const nullable = (codec: AnySchema): AnySchema =>\n shape.nullable ? (Schema.NullOr(codec) as unknown as AnySchema) : codec\n if (nested.window !== undefined) {\n // A connection: the nested selection already carries its page codec.\n connections[key] = nested.window\n picked[key] = nullable(nested.schema as AnySchema)\n if (nested.fields.length > 0) relations[key] = relationOf(nested)\n continue\n }\n const item = nested.schema as AnySchema\n picked[key] = nullable(\n shape.kind === 'many'\n ? (Schema.Array(item) as unknown as AnySchema)\n : shape.kind === 'page'\n ? pageSchema(item)\n : item,\n )\n relations[key] = relationOf(nested)\n }\n return {\n entity: entity.name,\n fields: Object.keys(selection),\n schema: Schema.Struct(picked) as unknown as Schema.Codec<\n SelectionValue<F, Sel>,\n unknown,\n never,\n never\n >,\n ...(Object.keys(connections).length === 0 ? {} : { connections }),\n ...(Object.keys(relations).length === 0 ? {} : { relations }),\n }\n },\n\n /**\n * A paginated relation: one page of refs to `entity` with a window, or, with\n * a nested selection, one page of targets assembled through it.\n */\n connection: (<Name extends string, F extends Schema.Struct.Fields, Item = never>(\n entity: EntityDescriptor<Name, F>,\n window: QueryWindow,\n selection?: Selection<Item, Name, 'entity'>,\n ): Selection<RefPage<Name, F> | Page<Item>, Name, 'connection'> => {\n if (selection !== undefined && selection.entity !== entity.name) {\n throw new Error(\n `Selection.connection: a page of \"${entity.name}\" cannot select \"${selection.entity}\"`,\n )\n }\n return {\n entity: entity.name,\n fields: selection?.fields ?? [],\n schema: (selection === undefined\n ? Entity.refPage(entity)\n : pageSchema(selection.schema as AnySchema)) as unknown as Schema.Codec<\n RefPage<Name, F> | Page<Item>,\n unknown,\n never,\n never\n >,\n window,\n ...(selection?.connections === undefined ? {} : { connections: selection.connections }),\n ...(selection?.relations === undefined ? {} : { relations: selection.relations }),\n }\n }) as {\n <Name extends string, F extends Schema.Struct.Fields>(\n entity: EntityDescriptor<Name, F>,\n window: QueryWindow,\n ): Selection<RefPage<Name, F>, Name, 'connection'>\n <Name extends string, F extends Schema.Struct.Fields, Item>(\n entity: EntityDescriptor<Name, F>,\n window: QueryWindow,\n selection: Selection<Item, NoInfer<Name>, 'entity'>,\n ): Selection<Page<Item>, Name, 'connection'>\n },\n}\n\ninterface Assembled {\n readonly values: unknown\n readonly refreshing: boolean\n}\n\n/**\n * Reads an entity's selected fields out of the store, following each nested\n * relation into its targets. `undefined` means some field, at any depth, is\n * not present yet. A tombstoned target reads as `null` (or is dropped from a\n * list), so the Selection's codec decides whether that is a failure.\n */\nexport const assemble = (\n store: EntityStore,\n key: string,\n requirement: RelationRequirement,\n): Assembled | undefined => {\n const values: Record<string, unknown> = {}\n let refreshing = false\n for (const field of requirement.fields) {\n const value = readField(store, key, field)\n if (Option.isNone(value)) return undefined\n refreshing ||= isFieldStale(store, key, field)\n const relation = requirement.relations?.[field]\n if (relation === undefined) {\n values[field] = value.value\n continue\n }\n const nested = assembleRelation(store, value.value, relation)\n if (nested === undefined) return undefined\n values[field] = nested.values\n refreshing ||= nested.refreshing\n }\n return { values, refreshing }\n}\n\nconst assembleTarget = (\n store: EntityStore,\n ref: { readonly entity: string; readonly id: string },\n relation: RelationRequirement,\n): Assembled | 'absent' | undefined => {\n const key = entityKey(ref.entity, ref.id)\n return isTombstone(store, key) ? 'absent' : assemble(store, key, relation)\n}\n\n/** Assembles the targets a relation value refers to, in the value's own shape. */\nconst assembleRelation = (\n store: EntityStore,\n value: unknown,\n relation: RelationRequirement,\n): Assembled | undefined => {\n if (value === null || value === undefined) return { values: null, refreshing: false }\n const targets: unknown[] = []\n let refreshing = false\n for (const ref of targetsOf(value, relation)) {\n const target = assembleTarget(store, ref, relation)\n if (target === undefined) return undefined\n if (target === 'absent') continue\n targets.push(target.values)\n refreshing ||= target.refreshing\n }\n if (typeof value === 'string') {\n return { values: targets.length === 0 ? null : targets[0], refreshing }\n }\n if (isRefPage(value)) {\n return {\n values: { items: targets, hasNext: value.hasNext, hasPrevious: value.hasPrevious },\n refreshing,\n }\n }\n return { values: targets, refreshing }\n}\n","/**\n * `foldkit-remote` — normalized application-facing server state.\n *\n * The pure core (entities, selections, the store, the planner, connections,\n * live classification, optimistic layers) performs no I/O. The `Remote.*`\n * helpers that read or mutate go through the `RemoteClient` Effect service.\n */\nimport { Effect, Layer, Result, Schema, Stream } from 'effect'\nimport type { Duration } from 'effect'\nimport type { Command } from 'foldkit/command'\nimport type { EntryWithoutKeepAlive } from 'foldkit/subscription'\nimport {\n Requirement,\n type ActiveSurface,\n type ConnectionRequirement,\n type Contract,\n type Invalid,\n type ModelRef,\n type Projection,\n type Surface,\n} from 'foldkit-surface'\nimport {\n RemoteClient,\n coalescedLayer,\n liveEventOf,\n mutateRemote,\n remoteError,\n type RemoteRpcClient,\n} from './client.js'\nimport { emptyConnection, hasNext, hasPrevious, type Edge } from './connection.js'\nimport type { EntityDescriptor } from './entity.js'\nimport { inspectEntity, inspectRemote, type RemoteInspection } from './inspect.js'\nimport type { LiveCursor } from './live.js'\nimport {\n initialRemoteModel,\n isLoading,\n isRemoteMessage,\n remoteMessageCases,\n remoteMessageSchema,\n remoteModelSchema,\n retentionRootsSchema,\n updateRemote,\n writeRead,\n type RemoteMessage,\n type RemoteMessageInput,\n type RemoteModel,\n} from './model.js'\nimport type { MutationDescriptor } from './mutation.js'\nimport {\n connectionIdentity,\n visibleItems,\n visibleStore,\n type ConnectionIdentity,\n type OptimisticState,\n type OptimisticOperation,\n} from './optimistic.js'\nimport { plan, type PlanOptions } from './plan.js'\nimport { RemotePolicy } from './policy.js'\nimport { stableStringify } from './query.js'\nimport type { ConnectionSpec, QueryDescriptor, QueryRef, QueryWindow } from './query.js'\nimport { remoteDataSchema, type RemoteData } from './remoteData.js'\nimport type { ConnectionRoot, RetentionRoots } from './retain.js'\nimport { assemble, pageSchema, relationOf, type Page, type Selection } from './selection.js'\nimport { entityKey, isTombstone, type EntityStore } from './store.js'\nimport {\n QueryRequest,\n QueryResult,\n ReadRequest,\n RelationRequest,\n REMOTE_PROTOCOL_VERSION,\n WindowSchema,\n RemoteLiveError,\n RemoteProtocolError,\n RemoteQueryError,\n RemoteReadError,\n RemoteRpc,\n} from './wire.js'\nimport type { CoalesceOptions } from './coalesce.js'\nimport type { RelationRequirement } from './plan.js'\n\nexport * from './client.js'\nexport * from './coalesce.js'\nexport * from './connection.js'\nexport * from './entity.js'\nexport * from './inspect.js'\nexport * from './live.js'\nexport * from './model.js'\nexport * from './mutation.js'\nexport * from './optimistic.js'\nexport * from './persistence.js'\nexport * from './plan.js'\nexport * from './policy.js'\nexport * from './query.js'\nexport * from './relation.js'\nexport * from './remoteData.js'\nexport * from './retain.js'\nexport * from './selection.js'\nexport * from './store.js'\nexport * from './wire.js'\n\ntype EntityName<D> = D extends EntityDescriptor<infer Name, any> ? Name : never\ntype QueryName<D> = D extends QueryDescriptor<infer Name, any, any> ? Name : never\ntype MutationName<D> = D extends MutationDescriptor<infer Name, any, any> ? Name : never\n\n/**\n * Nothing when `Name` is one of the domain's registered `Names`; otherwise a\n * branded failure naming the descriptor, so `Data.get(Team.select(…))` for an\n * unregistered `Team` errors at the selection in one line.\n */\nexport type Registered<Name extends string, Names extends string, Kind extends string> = [\n Name,\n] extends [Names]\n ? unknown\n : Invalid<`${Kind} \"${Name}\" is not registered with this Remote domain`>\n\n/** Nothing when a selection is of the query's entity; otherwise a branded failure naming both. */\nexport type SelectsEntity<Entity extends string, Of extends string> = [Entity] extends [Of]\n ? unknown\n : Invalid<`the selection is of \"${Entity}\", but the query lists \"${Of}\"`>\n\nexport interface RemoteDescriptor<\n Entities extends readonly EntityDescriptor<any, any>[] = readonly EntityDescriptor<any, any>[],\n Queries extends readonly QueryDescriptor<any, any, any>[] = readonly QueryDescriptor<\n any,\n any,\n any\n >[],\n Mutations extends readonly MutationDescriptor<any, any, any>[] = readonly MutationDescriptor<\n any,\n any,\n any\n >[],\n> {\n readonly entities: Entities\n readonly queries: Queries\n readonly mutations: Mutations\n readonly Model: Schema.Schema<RemoteModel>\n readonly initial: RemoteModel\n readonly Message: Schema.Schema<RemoteMessage>\n readonly update: (model: RemoteModel, message: RemoteMessage) => RemoteModel\n readonly rpc: typeof RemoteRpc\n /** Name-keyed lookups built from the declared entities, queries, and mutations. */\n readonly registry: {\n readonly entities: ReadonlyMap<string, EntityDescriptor<any, any>>\n readonly queries: ReadonlyMap<string, QueryDescriptor<any, any, any>>\n readonly mutations: ReadonlyMap<string, MutationDescriptor<any, any, any>>\n }\n}\n\ndeclare const boundRemoteNames: unique symbol\n\nexport interface BoundRemote<AppModel, Store extends RemoteModel, Names extends string = string> {\n readonly definition: RemoteDescriptor\n readonly store: ModelRef<AppModel, Store>\n /** For `Module`: owns the store's Model path. */\n readonly contract: Contract\n /** Phantom: the entity names this Remote definition registers. */\n readonly [boundRemoteNames]?: Names\n}\n\ntype MutationInput<M> = M extends MutationDescriptor<any, infer Input, any> ? Input : never\n\nexport interface DomainMutateOptions {\n /** Overrides the generated id, for a retry, a durable bridge, or a test. */\n readonly requestId?: string | undefined\n /**\n * What the request changes before the server answers, released when it\n * settles. A function receives the generated ids, so a created entity can\n * carry `tempId` until the result names the real one.\n */\n readonly optimistic?:\n | ReadonlyArray<OptimisticOperation>\n | ((ids: {\n readonly requestId: string\n readonly tempId: string\n }) => ReadonlyArray<OptimisticOperation>)\n | undefined\n}\n\n/** A Foldkit Subscription entry of the Remote domain, emitting its Messages through `RemoteClient`. */\nexport type RemoteEntry<AppModel, Dependencies> = EntryWithoutKeepAlive<\n AppModel,\n RemoteMessage,\n Dependencies,\n RemoteClient\n>\n\nexport interface SubscriptionsOptions extends ObserveOptions, LiveOptions, RetainOptions {}\n\n/** What `RemoteDomain.mutate` hands `update`: the Model with the request started, and the Command that settles it. */\nexport interface MutationStarted<AppModel> {\n readonly model: AppModel\n readonly requestId: string\n readonly tempId: string\n /** Yields `MutationSucceeded` or `MutationFailed`; never fails. */\n readonly command: Command<RemoteMessage, never, RemoteClient>\n}\n\n/**\n * A Remote domain bound to its place in the application Model: the descriptor\n * (`Remote.define`), the binding (`Remote.at`), and the application-facing\n * operations over them. Every method compiles to the `Remote.*` function of the\n * same name, which stays exported for tooling, SSR, and tests.\n */\nexport interface RemoteDomain<\n AppModel,\n Store extends RemoteModel,\n Entities extends readonly EntityDescriptor<any, any>[],\n Queries extends readonly QueryDescriptor<any, any, any>[],\n Mutations extends readonly MutationDescriptor<any, any, any>[],\n>\n extends\n BoundRemote<AppModel, Store, EntityName<Entities[number]>>,\n RemoteDescriptor<Entities, Queries, Mutations> {\n /** `Remote.select`: a Projection reading one entity through a selection of a registered entity. */\n get<Value, Name extends string>(\n selection: Selection<Value, Name, 'entity'> &\n Registered<Name, EntityName<Entities[number]>, 'Entity'>,\n id: string,\n ): Projection<AppModel, RemoteData<Value>>\n /**\n * `get`, and the projection also subscribes to the entity's changes: its\n * requirements are marked `live`, so `subscriptions` derives a live entry for\n * the Surfaces that read it.\n */\n live<Value, Name extends string>(\n selection: Selection<Value, Name, 'entity'> &\n Registered<Name, EntityName<Entities[number]>, 'Entity'>,\n id: string,\n ): Projection<AppModel, RemoteData<Value>>\n /**\n * A query connection read as a `Page` of items selected of the query's\n * entity: `Initial` until the page and every item's selected fields are\n * present, `Refreshing` while any of them is being refetched. The window is\n * the page first asked for; the pages `next`, `previous` and `fetch` merge\n * onto the connection read through the same projection.\n */\n query<Q extends QueryDescriptor<any, any, any>, Value, Entity extends string>(\n query: Q & Registered<Q['name'], QueryName<Queries[number]>, 'Query'>,\n input: QueryInput<Q>,\n options: QueryOptions<Value, Entity, QueryEntity<Q>>,\n ): QueryProjection<AppModel, Value, Q['name'], QueryInput<Q>>\n /** The `QueryRef` for the page after the loaded end (same page size), or `undefined` when there is none or its cursor is unknown. */\n next<Name extends string, Input>(\n model: AppModel,\n projection: QueryProjection<AppModel, any, Name, Input>,\n ): QueryRef<Name, Input> | undefined\n /** The `QueryRef` for the page before the loaded start, or `undefined`. */\n previous<Name extends string, Input>(\n model: AppModel,\n projection: QueryProjection<AppModel, any, Name, Input>,\n ): QueryRef<Name, Input> | undefined\n /** A Command that runs the query and yields the `ConnectionMerged` (or `QueryFailed`) that reduces it: \"load more\". */\n fetch(ref: QueryRef<string, unknown>): Command<RemoteMessage, never, RemoteClient>\n /**\n * The Foldkit Subscription entries for the active Surfaces, keyed for\n * `Subscription.make`: a read entry per Surface (`Remote.observe`), a live\n * entry per Surface that reads through `live` (`Remote.live`), and one\n * retain entry with every active Surface as a root (`Remote.retain`). A\n * Surface's params are a function of the Model (`Surface.at`), so what is\n * fetched, subscribed, and retained follows the Model.\n */\n subscriptions(\n active: Readonly<Record<string, ActiveSurface<AppModel> | Surface<AppModel, any, any, void>>>,\n options?: SubscriptionsOptions,\n ): Readonly<Record<string, RemoteEntry<AppModel, any>>>\n /** `Remote.plan`: the requirements the store does not satisfy. */\n plan<Value>(\n model: AppModel,\n projection: Projection<AppModel, Value>,\n options?: PlanOptions,\n ): ReadonlyArray<Requirement>\n /** `Remote.storeOf`: the visible store, base under the pending optimistic layers. */\n storeOf(model: AppModel): EntityStore\n /**\n * The plan run through `RemoteClient` and reduced into the Model: the\n * projection's pending queries first, then the fields it lacks (the pages'\n * items included). For SSR, route or hover prefetch, and tests.\n */\n prefetch<Value>(\n model: AppModel,\n projection: Projection<AppModel, Value>,\n options?: ObserveOptions,\n ): Effect.Effect<AppModel, RemoteReadError | RemoteProtocolError | RemoteQueryError, RemoteClient>\n /**\n * Starts a registered mutation from `update`: applies `MutationStarted` (with\n * the optimistic operations) to the Model and returns the Command that runs\n * it and yields the settling Message. The request id comes from the model's\n * mutation sequence unless `options.requestId` is given.\n */\n mutate<M extends MutationDescriptor<any, any, any>>(\n model: AppModel,\n mutation: M & Registered<M['name'], MutationName<Mutations[number]>, 'Mutation'>,\n input: MutationInput<M>,\n options?: DomainMutateOptions,\n ): MutationStarted<AppModel>\n /** `updateRemote` on the bound slice: reduces one of Remote's Messages, as `RemoteMessage` or as the application's union constructs it. */\n reduce(model: AppModel, message: RemoteMessage | RemoteMessageInput): AppModel\n /** `Remote.inspect` of the bound slice. */\n inspect(model: AppModel): RemoteInspection\n}\n\n/** A projection's connection requirement with the `QueryRef` that runs it. */\nexport interface QueryRequirement extends ConnectionRequirement {\n readonly ref: QueryRef<string, unknown>\n}\n\n/** A page forward (`first`, `after`) or back (`last`, `before`); mixing the two is a type error. */\nexport type QueryWindowOptions =\n | {\n readonly first?: number | undefined\n readonly after?: string | undefined\n readonly last?: undefined\n readonly before?: undefined\n }\n | {\n readonly last: number\n readonly before?: string | undefined\n readonly first?: undefined\n readonly after?: undefined\n }\n\nexport type QueryOptions<Value, Entity extends string, Of extends string = Entity> = {\n /** What to read of each item: a selection of the query's entity (`Of`). */\n readonly select: Selection<Value, Entity, 'entity'> & SelectsEntity<Entity, Of>\n} & QueryWindowOptions\n\n/** A query connection read as a `Page` of selected items; `ref` is the connection with its first window. */\nexport interface QueryProjection<AppModel, Value, Name extends string, Input> extends Projection<\n AppModel,\n RemoteData<Page<Value>>\n> {\n readonly ref: QueryRef<Name, Input>\n}\n\n/** The input of a query descriptor. */\nexport type QueryInput<Q> = Q extends QueryDescriptor<any, infer Input, any> ? Input : never\n/** The entity a query's connection is over. */\nexport type QueryEntity<Q> =\n Q extends QueryDescriptor<any, any, ConnectionSpec<infer Entity>> ? Entity : string\n\n/**\n * The store a read or plan sees: the base with every pending optimistic layer\n * applied, so a request's patches show until it settles and a temporary id is\n * not planned as a fetch.\n */\nconst storeOf = <AppModel, Store extends RemoteModel, Names extends string>(\n bound: BoundRemote<AppModel, Store, Names>,\n model: AppModel,\n): EntityStore => {\n const remote = bound.store.get(model)\n return visibleStoreOf(remote.entities, remote.optimistic)\n}\n\n// The visible store is recomputed only when the base store or the layers\n// change, so reads and plans across renders of one Model share it.\nconst visibleStores = new WeakMap<OptimisticState, WeakMap<EntityStore, EntityStore>>()\n\nconst visibleStoreOf = (entities: EntityStore, optimistic: OptimisticState): EntityStore => {\n let byStore = visibleStores.get(optimistic)\n if (byStore === undefined) {\n byStore = new WeakMap()\n visibleStores.set(optimistic, byStore)\n }\n let visible = byStore.get(entities)\n if (visible === undefined) {\n visible = visibleStore(entities, optimistic)\n byStore.set(entities, visible)\n }\n return visible\n}\n\n// A read's result per store snapshot. `Remote.storeOf` is shared across every\n// read of one Model state, so equal reads of one render assemble and decode\n// once and return one value (a view may compare by identity). A query read\n// also depends on its connection, which changes independently of the store,\n// so it keys on that object too. Weak on both, bounded by what is read.\nconst readResults = new WeakMap<object, WeakMap<object, Map<string, unknown>>>()\n\nconst memoRead = <T>(snapshot: object, by: object, key: string, compute: () => T): T => {\n let byScope = readResults.get(snapshot)\n if (byScope === undefined) {\n byScope = new WeakMap()\n readResults.set(snapshot, byScope)\n }\n let results = byScope.get(by)\n if (results === undefined) {\n results = new Map()\n byScope.set(by, results)\n }\n if (results.has(key)) return results.get(key) as T\n const value = compute()\n results.set(key, value)\n return value\n}\n\nexport interface MutateOptions {\n /** What the request changes before the server answers; released when it settles. */\n readonly optimistic?: ReadonlyArray<OptimisticOperation> | undefined\n}\n\n/** The default `toMessage`: the application reduces `RemoteMessage` itself. */\nconst identityMessage = (message: RemoteMessage): RemoteMessage => message\n\nexport interface RetainOptions {\n /** The query connections the application shows, by `QueryRef` or identity. */\n readonly connections?: ReadonlyArray<ConnectionIdentity> | undefined\n /** How long the roots must be stable before collecting; default none. */\n readonly grace?: Duration.Input | undefined\n}\n\n/** How `Remote.observe` and `Remote.prefetch` treat fields the store already holds. */\nexport interface ObserveOptions {\n /** Default `RemotePolicy.cacheFirst`. */\n readonly policy?: RemotePolicy | undefined\n /** The clock a refreshing policy reads; default `Date.now`. */\n readonly now?: (() => number) | undefined\n}\n\nexport interface LiveOptions {\n /** The clock `LiveReceived` stamps events with; default `Date.now`. */\n readonly now?: (() => number) | undefined\n}\n\n/** A stable key for a live subscription's requirement set. */\nconst liveStreamKey = (requirements: readonly Requirement[]): string =>\n requirements\n .map(\n requirement =>\n `${entityKey(requirement.entity, requirement.id)}:${[...requirement.fields].sort().join(',')}`,\n )\n .sort()\n .join('|')\n\n/** Declares a Remote domain: its entities, queries, and mutations, plus the submodel. */\nconst defineRemote = <\n const Entities extends readonly EntityDescriptor<any, any>[],\n const Queries extends readonly QueryDescriptor<any, any, any>[] = readonly QueryDescriptor<\n any,\n any,\n any\n >[],\n const Mutations extends readonly MutationDescriptor<any, any, any>[] =\n readonly MutationDescriptor<any, any, any>[],\n>(config: {\n readonly entities: Entities\n readonly queries?: Queries\n readonly mutations?: Mutations\n}): RemoteDescriptor<Entities, Queries, Mutations> => ({\n entities: config.entities,\n queries: (config.queries ?? []) as unknown as Queries,\n mutations: (config.mutations ?? []) as unknown as Mutations,\n Model: remoteModelSchema(),\n initial: initialRemoteModel,\n Message: remoteMessageSchema,\n update: updateRemote,\n rpc: RemoteRpc,\n registry: {\n entities: new Map(config.entities.map(entity => [entity.name, entity])),\n queries: new Map((config.queries ?? []).map(query => [query.name, query])),\n mutations: new Map((config.mutations ?? []).map(mutation => [mutation.name, mutation])),\n },\n})\n\n/** Binds a Remote domain to its store's location in the application Model. */\nconst bindRemote = <\n AppModel,\n Store extends RemoteModel,\n Entities extends readonly EntityDescriptor<any, any>[],\n Queries extends readonly QueryDescriptor<any, any, any>[],\n Mutations extends readonly MutationDescriptor<any, any, any>[],\n>(\n definition: RemoteDescriptor<Entities, Queries, Mutations>,\n store: ModelRef<AppModel, Store>,\n): BoundRemote<AppModel, Store, EntityName<Entities[number]>> => ({\n definition,\n store,\n contract: {\n kind: 'remote',\n name: store.dependency.join('.') || 'remote',\n // A generated field reference knows its application and its path; a raw\n // optic (`ModelRef.fromOptic`) knows neither, so it claims nothing.\n owner: (store as { readonly owner?: object }).owner,\n owns: store.dependency.length === 0 ? [] : [store.dependency],\n observes: store.dependency.length === 0 ? [] : [store.dependency],\n messages: [],\n requirements: [],\n },\n})\n\n/** The runtime half of `Registered`: a descriptor the domain never declared is an error naming both. */\nconst assertRegistered = (\n bound: BoundRemote<any, any>,\n kind: 'Entity' | 'Query' | 'Mutation',\n registered: ReadonlyMap<string, unknown>,\n name: string,\n): void => {\n if (!registered.has(name)) {\n throw new Error(\n `Remote: ${kind} \"${name}\" is not registered with domain \"${bound.contract.name}\"`,\n )\n }\n}\n\n/** What a projection asks of the remote: entity requirements and query connections. */\ninterface Asked {\n readonly requirements: ReadonlyArray<Requirement>\n readonly connections: ReadonlyArray<ConnectionRequirement>\n}\n\nconst nothingAsked: Asked = { requirements: [], connections: [] }\n\nconst askedOf = (projection: Projection<any, unknown> | undefined): Asked =>\n projection === undefined ? nothingAsked : projection\n\n/** The plan for what a projection asks: the entity fields to read, and the queries to run. */\ninterface Planned {\n readonly requirements: ReadonlyArray<Requirement>\n readonly queries: ReadonlyArray<QueryRequirement>\n}\n\n/**\n * Plans what a projection asks against the Model. A connection the Model holds\n * fresh contributes its visible items' selected fields to the entity plan; one\n * it does not hold, or holds stale, is a query to run (its items are planned\n * once the page arrives).\n */\nconst planAsked = (remote: RemoteModel, asked: Asked, options: PlanOptions): Planned => {\n const queries: QueryRequirement[] = []\n const items: Requirement[] = []\n const connections = Requirement.mergeConnections(\n asked.connections,\n ) as ReadonlyArray<QueryRequirement>\n for (const connection of connections) {\n const known = remote.connections[connection.identity]\n if (known === undefined || known.stale || options.force === true) {\n queries.push(connection)\n continue\n }\n const edges = visibleItems(\n known,\n connection.identity,\n remote.optimistic.overlays,\n remote.entities,\n )\n items.push(\n ...itemsOf(\n edges.map(edge => edge.ref),\n connection.select,\n ),\n )\n }\n return {\n requirements: plan(\n visibleStoreOf(remote.entities, remote.optimistic),\n [...asked.requirements, ...items],\n options,\n ),\n queries,\n }\n}\n\n/** The entity requirements a page's edges add under a selection. */\nconst itemsOf = (\n edges: ReadonlyArray<{ readonly entity: string; readonly id: string }>,\n select: RelationRequirement,\n): ReadonlyArray<Requirement> =>\n edges.filter(edge => edge.entity === select.entity).map(edge => ({ ...select, id: edge.id }))\n\n/**\n * The wire request of a planned query; a `QueryRef` identity carries the query\n * name and the canonical encoded input. A connection requirement built by hand\n * with another identity cannot be run, and fails as a query would.\n */\nconst queryRequestOf = (query: {\n readonly identity: string\n readonly window: QueryWindow\n}): Effect.Effect<Schema.Schema.Type<typeof QueryRequest>, RemoteQueryError> => {\n const separator = query.identity.indexOf('\\u0000')\n if (separator < 0) {\n return Effect.fail(\n new RemoteQueryError({\n message: `connection \"${query.identity}\" is not a query's: only a QueryRef identity can be run`,\n }),\n )\n }\n return Effect.try({\n try: () => ({\n query: query.identity.slice(0, separator),\n input: JSON.parse(query.identity.slice(separator + 1)) as unknown,\n window: query.window,\n }),\n catch: () =>\n new RemoteQueryError({ message: `connection \"${query.identity}\" carries no encoded input` }),\n })\n}\n\n/**\n * The `ConnectionMerged` for a query result, in the client's edge shape.\n * `refreshes` marks the page as answering the connection's refresh, so one\n * Message both merges it and clears `stale`.\n */\nconst pageMessage = (\n connection: string,\n result: Schema.Schema.Type<typeof QueryResult>,\n refreshes = false,\n): RemoteMessage => ({\n _tag: 'ConnectionMerged',\n connection,\n page: {\n edges: result.edges.map(edge => ({ key: edge.key, ref: { entity: edge.entity, id: edge.id } })),\n start: result.start,\n end: result.end,\n },\n ...(refreshes ? { refreshes } : {}),\n})\n\n/**\n * The retention roots of some projections: their requirements, their\n * connections (each with the union of what the projections select of its\n * items), and the connections listed by identity alone.\n */\nconst rootsOf = (\n projections: ReadonlyArray<Projection<any, unknown>>,\n options: RetainOptions,\n): RetentionRoots => {\n const connections = new Map<string, ConnectionRoot>()\n for (const identity of (options.connections ?? []).map(connectionIdentity)) {\n connections.set(identity, { identity })\n }\n for (const { identity, select } of projections.flatMap(projection => projection.connections)) {\n const current = connections.get(identity)?.select\n connections.set(identity, {\n identity,\n select: current === undefined ? select : Requirement.mergeRelation(current, select),\n })\n }\n return {\n requirements: Requirement.merge(projections.flatMap(projection => projection.requirements)),\n connections: [...connections.values()].sort((a, b) => (a.identity < b.identity ? -1 : 1)),\n }\n}\n\n/** A query the read entry runs, as its dependencies carry it: plain data Foldkit compares. */\nconst PlannedQuery = Schema.Struct({\n identity: Schema.String,\n window: WindowSchema,\n select: RelationRequest,\n})\n\n/** The dependencies of the read entry: the entity fields to read and the queries to run. */\nexport interface ReadDependencies {\n readonly requirements: ReadonlyArray<Requirement>\n readonly queries: ReadonlyArray<Schema.Schema.Type<typeof PlannedQuery>>\n}\n\n/**\n * The read entry: plans what `askedOf(model)` asks against the Model and runs\n * the entity read and the queries concurrently. Each Message it emits changes\n * the Model, so Foldkit recomputes the dependencies and restarts the stream\n * (`switchMap`): a merged page's items are planned by that next computation,\n * against the store as it then is, rather than read here unplanned. Nothing\n * the entry needs is spread over two Messages, since the second could be lost\n * to the restart; a page and its refresh are one `ConnectionMerged`.\n */\nconst observeEntry = <AppModel, Store extends RemoteModel, Message>(\n bound: BoundRemote<AppModel, Store>,\n askedOf: (model: AppModel) => Asked,\n toMessage: (message: RemoteMessage) => Message,\n options: ObserveOptions,\n): EntryWithoutKeepAlive<AppModel, Message, ReadDependencies, RemoteClient> => {\n const { policy = RemotePolicy.cacheFirst, now = Date.now } = options\n const read = (requirements: ReadonlyArray<Requirement>) =>\n Effect.gen(function* () {\n const client = yield* RemoteClient\n const at = now()\n const result = yield* Effect.result(\n client.read({ version: REMOTE_PROTOCOL_VERSION, requests: requirements }),\n )\n return Result.isFailure(result)\n ? toMessage({\n _tag: 'ReadFailed',\n requests: requirements,\n error: remoteError(result.failure),\n })\n : toMessage({\n _tag: 'ReadReceived',\n requests: requirements,\n result: result.success,\n now: at,\n })\n })\n const run = (query: ReadDependencies['queries'][number]) =>\n Effect.gen(function* () {\n const client = yield* RemoteClient\n const result = yield* Effect.result(\n queryRequestOf(query).pipe(Effect.flatMap(request => client.query(request))),\n )\n return Result.isFailure(result)\n ? toMessage({\n _tag: 'QueryFailed',\n connection: query.identity,\n error: remoteError(result.failure),\n })\n : toMessage(pageMessage(query.identity, result.success, true))\n })\n return {\n dependenciesSchema: Schema.Struct({\n requirements: Schema.Array(ReadRequest),\n queries: Schema.Array(PlannedQuery),\n }),\n modelToDependencies: model => {\n const planned = planAsked(\n bound.store.get(model),\n askedOf(model),\n RemotePolicy.toPlan(policy, now()),\n )\n return {\n requirements: planned.requirements,\n queries: planned.queries.map(({ identity, window, select }) => ({\n identity,\n window,\n select,\n })),\n }\n },\n dependenciesToStream: ({ requirements, queries }) =>\n Stream.concat(\n requirements.length === 0\n ? Stream.empty\n : Stream.fromIterable([\n // Absent fields read as `Loading` until the read lands.\n toMessage({ _tag: 'ReadStarted', requests: requirements }),\n // A refreshing policy also marks the present ones stale.\n ...(RemotePolicy.refreshes(policy)\n ? [toMessage({ _tag: 'RefreshStarted', requests: requirements })]\n : []),\n ]),\n Stream.mergeAll(\n [\n ...(requirements.length === 0 ? [] : [Stream.fromEffect(read(requirements))]),\n ...queries.map(query => Stream.fromEffect(run(query))),\n ],\n { concurrency: 'unbounded' },\n ),\n ),\n }\n}\n\n/** The live entry: subscribes to `requirementsOf(model)` from the Model's resume cursor. */\nconst liveEntry = <AppModel, Store extends RemoteModel, Message>(\n bound: BoundRemote<AppModel, Store>,\n requirementsOf: (model: AppModel) => ReadonlyArray<Requirement>,\n toMessage: (message: RemoteMessage) => Message,\n options: LiveOptions,\n): EntryWithoutKeepAlive<\n AppModel,\n Message,\n { readonly requirements: ReadonlyArray<Requirement>; readonly cursor: LiveCursor },\n RemoteClient\n> => ({\n dependenciesSchema: Schema.Struct({\n requirements: Schema.Array(ReadRequest),\n cursor: Schema.Number,\n }),\n modelToDependencies: model => {\n const requirements = requirementsOf(model)\n const stream = liveStreamKey(requirements)\n return {\n requirements,\n cursor: bound.store.get(model).live[stream]?.cursor ?? 0,\n }\n },\n dependenciesToStream: ({ requirements, cursor }) =>\n requirements.length === 0\n ? Stream.empty\n : Stream.unwrap(\n Effect.gen(function* () {\n const client = yield* RemoteClient\n return client.live({ requirements, after: cursor })\n }),\n ).pipe(\n Stream.map(event =>\n toMessage({\n _tag: 'LiveReceived',\n stream: liveStreamKey(requirements),\n event,\n now: (options.now ?? Date.now)(),\n }),\n ),\n Stream.catchIf(\n (_error): _error is RemoteLiveError | RemoteProtocolError => true,\n error =>\n Stream.succeed(\n toMessage({\n _tag: 'ReadFailed',\n requests: requirements,\n error: remoteError(error),\n }),\n ),\n ),\n ),\n})\n\n/** The projection an active Surface has for this Model, if it is active. */\nconst projectionOf = <AppModel>(\n entry: ActiveSurface<AppModel> | Surface<AppModel, any, any, void>,\n model: AppModel,\n): Projection<AppModel, unknown> | undefined =>\n 'projectionOf' in entry ? entry.projectionOf(model) : entry.projection()\n\n/**\n * `projectionOf` computed once per Model: the read, live, and retain entries\n * all derive their dependencies from the same projection on the same Model\n * change, and a Surface's `model` callback (which lifts and builds schemas)\n * need not run three times for it. Models are objects, so the memo is weak.\n */\nconst memoizedProjectionOf = <AppModel>(\n entry: ActiveSurface<AppModel> | Surface<AppModel, any, any, void>,\n): ((model: AppModel) => Projection<AppModel, unknown> | undefined) => {\n const cache = new WeakMap<object, Projection<AppModel, unknown> | undefined>()\n return model => {\n const key: unknown = model\n if (typeof key !== 'object' || key === null) return projectionOf(entry, model)\n if (cache.has(key)) return cache.get(key)\n const projection = projectionOf(entry, model)\n cache.set(key, projection)\n return projection\n }\n}\n\nexport const Remote = {\n /** The submodel's schema, the same for every domain; embed it in the application Model. */\n Model: remoteModelSchema(),\n /** The submodel's initial value. */\n initial: initialRemoteModel,\n /**\n * Remote's Message cases for `defineMessageUnion`: spread them into the\n * application's union, and reduce the ones `Remote.reduces` recognizes with\n * `RemoteDomain.reduce`.\n */\n messages: remoteMessageCases,\n /** Whether a Message is one of Remote's, by tag. */\n reduces: isRemoteMessage,\n\n /**\n * Declares a Remote domain and binds it to its place in the application Model\n * in one step; the result carries the application-facing operations. The\n * descriptor alone is `Remote.define`, the binding alone `Remote.at`.\n */\n make: <\n AppModel,\n Store extends RemoteModel,\n const Entities extends readonly EntityDescriptor<any, any>[],\n const Queries extends readonly QueryDescriptor<any, any, any>[] = readonly [],\n const Mutations extends readonly MutationDescriptor<any, any, any>[] = readonly [],\n >(config: {\n readonly model: ModelRef<AppModel, Store>\n readonly entities: Entities\n readonly queries?: Queries\n readonly mutations?: Mutations\n }): RemoteDomain<AppModel, Store, Entities, Queries, Mutations> =>\n bindDomain(defineRemote(config), config.model),\n\n /**\n * Declares a Remote domain without binding it: its entities, queries, and\n * mutations, plus the submodel. For a domain reused across applications or\n * bound in a test; `Remote.make` is the one-step form.\n */\n define: defineRemote,\n\n /**\n * Binds a Remote domain to its store's location in the application Model. The\n * registered entity names are carried on the returned value, so `Remote.select`\n * rejects a selection for an entity this domain never declared.\n */\n at: bindRemote,\n\n /**\n * A Projection node that reads a `RemoteData` value out of the store. The id\n * is supplied by the caller, usually from a Surface's params. The assembled\n * value is decoded against the Selection, so malformed server data surfaces\n * as `Failed` instead of being asserted into `Value`. A present value with a\n * stale field reads as `Refreshing`: an observer is refetching it.\n */\n select: <AppModel, Store extends RemoteModel, Names extends string, Value, Name extends string>(\n bound: BoundRemote<AppModel, Store, Names>,\n selection: Selection<Value, Name, 'entity'> & Registered<Name, Names, 'Entity'>,\n ) => {\n assertRegistered(bound, 'Entity', bound.definition.registry.entities, selection.entity)\n const relation = relationOf(selection)\n return (id: string): Projection<AppModel, RemoteData<Value>> => ({\n Model: remoteDataSchema(selection.schema),\n dependencies: [],\n requirements: [{ ...relation, id }],\n connections: [],\n read: (root: AppModel): RemoteData<Value> => {\n const store = storeOf(bound, root)\n const key = entityKey(selection.entity, id)\n // The store-dependent half is memoized per store snapshot; `undefined`\n // means the store lacks the value. Whether that reads as `Loading` or\n // `Initial` depends on the in-flight marks, which change independently\n // of the store, so it is decided outside the memo.\n const present = memoRead<RemoteData<Value> | undefined>(\n store,\n store,\n `${key}\\u0000${stableStringify(relation)}`,\n () => {\n if (isTombstone(store, key)) return { _tag: 'NotFound' }\n const assembled = assemble(store, key, relation)\n if (assembled === undefined) return undefined\n const decoded = Schema.decodeUnknownResult(selection.schema)(assembled.values)\n return Result.isFailure(decoded)\n ? { _tag: 'Failed', error: { _tag: 'DecodeError', message: decoded.failure.message } }\n : assembled.refreshing\n ? { _tag: 'Refreshing', value: decoded.success }\n : { _tag: 'Ready', value: decoded.success }\n },\n )\n if (present !== undefined) return present\n // Nothing is fetching this: usually a projection no active Surface\n // observes, rather than a slow network.\n return isLoading(bound.store.get(root), selection.entity, id, relation.fields)\n ? { _tag: 'Loading' }\n : { _tag: 'Initial' }\n },\n })\n },\n\n /**\n * The pure plan for a projection against a Model: the requirements its\n * remote store does not satisfy, under `options` (freshness, force). A\n * Surface's projection is `surface.projection(params)`.\n */\n plan: <AppModel, Store extends RemoteModel, Value>(\n bound: BoundRemote<AppModel, Store>,\n model: AppModel,\n projection: Projection<AppModel, Value>,\n options?: PlanOptions,\n ): ReadonlyArray<Requirement> =>\n planAsked(bound.store.get(model), projection, options ?? {}).requirements,\n\n /**\n * The queries a projection needs run before its connections read: those the\n * Model does not hold, or holds stale (every one under `force`).\n */\n planQueries: <AppModel, Store extends RemoteModel, Value>(\n bound: BoundRemote<AppModel, Store>,\n model: AppModel,\n projection: Projection<AppModel, Value>,\n options?: PlanOptions,\n ): ReadonlyArray<QueryRef<string, unknown>> =>\n planAsked(bound.store.get(model), projection, options ?? {}).queries.flatMap(query =>\n query.ref === undefined ? [] : [query.ref],\n ),\n\n /**\n * The store reads see: the base store under the pending optimistic layers.\n * One store is shared by every read and plan of a Model whose remote state\n * has not changed.\n */\n storeOf: <AppModel, Store extends RemoteModel>(\n bound: BoundRemote<AppModel, Store>,\n model: AppModel,\n ): EntityStore => storeOf(bound, model),\n\n /**\n * Executes the plan against the `RemoteClient` and returns a new store. Used\n * for SSR route prefetch, hover prefetch, and tests. Never called during render.\n * `policy` decides what a present field means (default cache-first); `now`\n * is the clock it reads, so the planner itself stays pure and time-injected.\n */\n prefetch: Effect.fn('Remote.prefetch')(function* <AppModel, Store extends RemoteModel, Value>(\n bound: BoundRemote<AppModel, Store>,\n model: AppModel,\n projection: Projection<AppModel, Value>,\n options: ObserveOptions = {},\n ) {\n const store = storeOf(bound, model)\n const { policy = RemotePolicy.cacheFirst, now = Date.now } = options\n const at = now()\n const missing = plan(store, projection.requirements, RemotePolicy.toPlan(policy, at))\n if (missing.length === 0) return store\n yield* Effect.annotateCurrentSpan('requirementCount', missing.length)\n const client = yield* RemoteClient\n const result = yield* client.read({ version: REMOTE_PROTOCOL_VERSION, requests: missing })\n return writeRead(store, missing, result, at)\n }),\n\n /**\n * Writes a read result into the store, recording each field's applied window.\n * `requests` are the planned requirements the result answers.\n */\n writeRead,\n\n /**\n * Adapts an Effect RPC client for `RemoteRpc` to `RemoteClient`, so an\n * application provides the transport's RPC layer instead of writing the\n * `LiveChange`-to-`LiveEvent` mapping by hand.\n */\n clientLayer: <R = never>(\n client: RemoteRpcClient<R>,\n options: CoalesceOptions = {},\n ): Layer.Layer<RemoteClient, never, R> =>\n coalescedLayer(\n Layer.effect(\n RemoteClient,\n Effect.gen(function* () {\n // What the RPC client needs (a database under in-process handlers,\n // nothing under a transport) is supplied once, when the layer is built.\n const context = yield* Effect.context<R>()\n return {\n read: batch => client.FoldkitRemoteRead(batch).pipe(Effect.provideContext(context)),\n query: request =>\n client.FoldkitRemoteQuery(request).pipe(Effect.provideContext(context)),\n mutate: request =>\n client.FoldkitRemoteMutate(request).pipe(Effect.provideContext(context)),\n live: ({ requirements, after }) =>\n client\n .FoldkitRemoteLive({ version: REMOTE_PROTOCOL_VERSION, requirements, after })\n .pipe(Stream.map(liveEventOf), Stream.provideContext(context)),\n }\n }),\n ),\n options,\n ),\n\n /**\n * Wraps a `RemoteClient` layer so its reads coalesce: requirements issued\n * together become one batch, and a requirement already in flight is joined.\n * `Remote.clientLayer` applies this; use it on a hand-written client.\n */\n coalesced: coalescedLayer,\n\n /**\n * A Foldkit Subscription entry that keeps the cache to what the active\n * Surfaces reach. `projections` are the ones the application observes (the\n * same it passes to `Remote.observe`), `connections` the query connections\n * it shows; anything else is collected once the roots have been stable for\n * `grace`, so a route transition that comes straight back does not thrash.\n */\n retain: <AppModel, Message = RemoteMessage>(\n projections: ReadonlyArray<Projection<AppModel, unknown>>,\n toMessage: (message: RemoteMessage) => Message = identityMessage as never,\n options: RetainOptions = {},\n ): EntryWithoutKeepAlive<AppModel, Message, RetentionRoots, never> => {\n const roots = rootsOf(projections, options)\n return {\n dependenciesSchema: retentionRootsSchema,\n modelToDependencies: () => roots,\n dependenciesToStream: current =>\n Stream.fromEffect(\n Effect.succeed(toMessage({ _tag: 'RetentionChanged', roots: current })).pipe(\n Effect.delay(options.grace ?? 0),\n ),\n ),\n }\n },\n\n /**\n * Runs a `Query` through `RemoteClient`, encoding its input from the ref.\n * Pair the result with `Remote.queryMessage` to merge the page into the Model.\n */\n query: Effect.fn('Remote.query')(function* <Name extends string, Input>(\n ref: QueryRef<Name, Input>,\n ) {\n const client = yield* RemoteClient\n const input = yield* Schema.encodeUnknownEffect(ref.Input)(ref.input).pipe(\n Effect.catchTag('SchemaError', error =>\n Effect.fail(new RemoteQueryError({ message: error.message })),\n ),\n )\n return yield* client.query({ query: ref.query, input, window: ref.window })\n }),\n\n /** The `RemoteMessage` that merges a query page into its connection. */\n queryMessage: <Name extends string, Input>(\n ref: QueryRef<Name, Input>,\n result: Schema.Schema.Type<typeof QueryResult>,\n ): RemoteMessage => pageMessage(ref.identity, result),\n\n /**\n * The edges a connection shows: its server-known region with pending and\n * confirmed overlays placed around it, minus removed edges and edges whose\n * target is a tombstone.\n */\n visibleItems: (model: RemoteModel, connection: ConnectionIdentity): ReadonlyArray<Edge> => {\n const identity = connectionIdentity(connection)\n return visibleItems(\n model.connections[identity] ?? emptyConnection,\n identity,\n model.optimistic.overlays,\n model.entities,\n )\n },\n\n /** A pure, serializable view of the whole cache. */\n inspect: inspectRemote,\n\n /** A pure, serializable view of one entity, or `undefined` if unknown. */\n inspectEntity,\n\n /**\n * Runs a mutation through `RemoteClient`, decoding its typed Output and\n * returning the result's normalized patches so the caller can reconcile them\n * through `updateRemote`'s `MutationSucceeded` (or `Remote.mutateInto`).\n */\n mutate: mutateRemote,\n\n /**\n * Runs a mutation and reconciles its patches into a `RemoteModel` in one step,\n * returning the new model alongside the typed Output. The model-level form of\n * `MutationStarted` → `RemoteClient.mutate` → `MutationSucceeded`; in an\n * application the three are `update` (with `optimistic`), a Command, and the\n * Message the Command returns, so the optimistic operations show meanwhile.\n */\n mutateInto: Effect.fn('Remote.mutateInto')(function* <\n Name extends string,\n Input,\n Output,\n AppModel,\n Store extends RemoteModel,\n >(\n bound: BoundRemote<AppModel, Store>,\n model: AppModel,\n mutation: MutationDescriptor<Name, Input, Output>,\n input: Input,\n requestId: string,\n options: MutateOptions = {},\n ) {\n const started = updateRemote(bound.store.get(model), {\n _tag: 'MutationStarted',\n requestId,\n ...(options.optimistic === undefined ? {} : { optimistic: options.optimistic }),\n })\n const outcome = yield* mutateRemote(mutation, input, requestId)\n const settled = updateRemote(started, {\n _tag: 'MutationSucceeded',\n requestId,\n entities: outcome.entities,\n connections: outcome.connections,\n })\n return {\n output: outcome.output,\n model: bound.store.set(model, settled as Store),\n }\n }),\n\n /**\n * A Foldkit Subscription entry that plans a Surface's missing fields from the\n * Model and fetches them through `RemoteClient`, emitting a `RemoteMessage`\n * per outcome. Wrap it in an application Message (`toMessage`) and reduce it\n * with the domain's `update`. Under a refreshing `policy` the entry first\n * emits `RefreshStarted`, so the fields being refetched read as `Refreshing`\n * while the request is pending.\n */\n observe: <\n AppModel,\n Store extends RemoteModel,\n Names extends string,\n Model,\n SurfaceMessage,\n Params,\n Message = RemoteMessage,\n >(\n bound: BoundRemote<AppModel, Store, Names>,\n surface: Surface<AppModel, Model, SurfaceMessage, Params>,\n params: Params,\n toMessage: (message: RemoteMessage) => Message = identityMessage as never,\n options: ObserveOptions = {},\n ): EntryWithoutKeepAlive<AppModel, Message, ReadDependencies, RemoteClient> =>\n observeEntry(bound, () => surface.projection(params), toMessage, options),\n\n /**\n * A Foldkit Subscription entry that consumes the live stream for a Surface's\n * requirements, emitting a `LiveReceived` per event and a `ReadFailed` when\n * the stream breaks (including `ResumeUnavailable`). The resume cursor is read\n * from `RemoteModel.live`, so the application tracks no cursor of its own.\n */\n live: <\n AppModel,\n Store extends RemoteModel,\n Names extends string,\n Model,\n SurfaceMessage,\n Params,\n Message = RemoteMessage,\n >(\n bound: BoundRemote<AppModel, Store, Names>,\n surface: Surface<AppModel, Model, SurfaceMessage, Params>,\n params: Params,\n toMessage: (message: RemoteMessage) => Message = identityMessage as never,\n options: LiveOptions = {},\n ): EntryWithoutKeepAlive<\n AppModel,\n Message,\n { readonly requirements: ReadonlyArray<Requirement>; readonly cursor: LiveCursor },\n RemoteClient\n > => liveEntry(bound, () => surface.projection(params).requirements, toMessage, options),\n}\n\n/** The bound domain: the descriptor, the binding, and the operations over them. */\nconst bindDomain = <\n AppModel,\n Store extends RemoteModel,\n Entities extends readonly EntityDescriptor<any, any>[],\n Queries extends readonly QueryDescriptor<any, any, any>[],\n Mutations extends readonly MutationDescriptor<any, any, any>[],\n>(\n definition: RemoteDescriptor<Entities, Queries, Mutations>,\n store: ModelRef<AppModel, Store>,\n): RemoteDomain<AppModel, Store, Entities, Queries, Mutations> => {\n const bound = bindRemote(definition, store)\n // An application-union case has the runtime shape of the `RemoteMessage` it names.\n const reduce = (model: AppModel, message: RemoteMessage | RemoteMessageInput): AppModel =>\n store.set(model, updateRemote(store.get(model), message as RemoteMessage) as Store)\n return {\n ...definition,\n ...bound,\n get: (selection, id) => Remote.select(bound, selection)(id),\n live: (selection, id) => {\n const projection = Remote.select(bound, selection)(id)\n return {\n ...projection,\n requirements: projection.requirements.map(requirement => ({ ...requirement, live: true })),\n }\n },\n subscriptions: (active, options = {}) => {\n // Dependencies differ per entry, as in Foldkit's own `Subscriptions` record.\n const entries: Record<string, RemoteEntry<AppModel, any>> = {}\n const projections: Array<(model: AppModel) => Projection<AppModel, unknown> | undefined> = []\n for (const [key, entry] of Object.entries(active)) {\n // Two applications can have the same Model type; the owner token tells them apart.\n if (bound.contract.owner !== undefined && entry.owner !== bound.contract.owner) {\n throw new Error(\n `Remote: Surface \"${entry.name}\" belongs to another application than domain \"${bound.contract.name}\"`,\n )\n }\n const projectionAt = memoizedProjectionOf(entry)\n projections.push(projectionAt)\n const asked = (model: AppModel) => askedOf(projectionAt(model))\n entries[`${key}.read`] = observeEntry(bound, asked, identityMessage, options)\n entries[`${key}.live`] = liveEntry(\n bound,\n model => asked(model).requirements.filter(requirement => requirement.live === true),\n identityMessage,\n options,\n )\n }\n entries.retain = {\n dependenciesSchema: retentionRootsSchema,\n modelToDependencies: model =>\n rootsOf(\n projections.flatMap(projectionAt => {\n const projection = projectionAt(model)\n return projection === undefined ? [] : [projection]\n }),\n options,\n ),\n dependenciesToStream: (current: RetentionRoots) =>\n Stream.fromEffect(\n Effect.succeed<RemoteMessage>({ _tag: 'RetentionChanged', roots: current }).pipe(\n Effect.delay(options.grace ?? 0),\n ),\n ),\n }\n return entries\n },\n plan: (model, projection, options) => Remote.plan(bound, model, projection, options),\n storeOf: model => storeOf(bound, model),\n prefetch: (model, projection, options = {}) =>\n Effect.gen(function* () {\n const { policy = RemotePolicy.cacheFirst, now = Date.now } = options\n const client = yield* RemoteClient\n const planOptions = RemotePolicy.toPlan(policy, now())\n let current = model\n // The pages first, so their items join the one entity read below.\n for (const query of planAsked(store.get(current), projection, planOptions).queries) {\n const page = yield* queryRequestOf(query).pipe(\n Effect.flatMap(request => client.query(request)),\n )\n current = reduce(current, pageMessage(query.identity, page, true))\n }\n const requirements = planAsked(store.get(current), projection, planOptions).requirements\n if (requirements.length === 0) return current\n const at = now()\n const result = yield* client.read({\n version: REMOTE_PROTOCOL_VERSION,\n requests: requirements,\n })\n return reduce(current, { _tag: 'ReadReceived', requests: requirements, result, now: at })\n }),\n query: <Q extends QueryDescriptor<any, any, any>, Value, Entity extends string>(\n query: Q,\n input: QueryInput<Q>,\n options: QueryOptions<Value, Entity, QueryEntity<Q>>,\n ): QueryProjection<AppModel, Value, Q['name'], QueryInput<Q>> => {\n assertRegistered(bound, 'Query', definition.registry.queries, query.name)\n const { select, ...window } = options\n for (const [side, size] of [\n ['first', window.first],\n ['last', window.last],\n ] as const) {\n if (size !== undefined && !(Number.isInteger(size) && size >= 0)) {\n throw new Error(\n `Remote: query \"${query.name}\" asks for ${side}: ${String(size)}; a page size is a non-negative integer`,\n )\n }\n }\n const listed = (query.Result as Partial<ConnectionSpec>).entity\n if (listed === undefined) {\n throw new Error(\n `Remote: query \"${query.name}\" is not a connection over an entity, so it has no page to select`,\n )\n }\n if (select.entity !== listed) {\n throw new Error(\n `Remote: the selection is of \"${select.entity}\", but query \"${query.name}\" lists \"${listed}\"`,\n )\n }\n const ref: QueryRef<Q['name'], QueryInput<Q>> = {\n ...query.ref(input),\n window: pickWindow(window),\n }\n const relation = relationOf(select)\n const relationKey = stableStringify(relation)\n const requirement: QueryRequirement = {\n identity: ref.identity,\n window: ref.window,\n select: relation,\n ref,\n }\n return {\n Model: remoteDataSchema(pageSchema(select.schema)) as Schema.Schema<\n RemoteData<Page<Value>>\n >,\n dependencies: [],\n requirements: [],\n connections: [requirement],\n ref,\n read: (root: AppModel): RemoteData<Page<Value>> => {\n const remote = store.get(root)\n const connection = remote.connections[ref.identity]\n // Invalidating a connection the Model never loaded records it stale with no\n // segments: still nothing to show. (A loaded empty page is not stale.)\n if (connection === undefined || (connection.stale && connection.segments.length === 0)) {\n return { _tag: 'Initial' }\n }\n const visible = visibleStoreOf(remote.entities, remote.optimistic)\n return memoRead(visible, connection, `${ref.identity}\\u0000${relationKey}`, () => {\n const items: Value[] = []\n let refreshing = connection.stale\n const edges = visibleItems(\n connection,\n ref.identity,\n remote.optimistic.overlays,\n remote.entities,\n )\n for (const edge of edges) {\n const assembled = assemble(visible, entityKey(edge.ref.entity, edge.ref.id), relation)\n if (assembled === undefined) return { _tag: 'Initial' }\n const decoded = Schema.decodeUnknownResult(select.schema)(assembled.values)\n if (Result.isFailure(decoded)) {\n return {\n _tag: 'Failed',\n error: { _tag: 'DecodeError', message: decoded.failure.message },\n }\n }\n refreshing ||= assembled.refreshing\n items.push(decoded.success)\n }\n const page = {\n items,\n hasNext: hasNext(connection),\n hasPrevious: hasPrevious(connection),\n }\n return refreshing ? { _tag: 'Refreshing', value: page } : { _tag: 'Ready', value: page }\n })\n },\n }\n },\n next: (model, projection) => {\n const segments = store.get(model).connections[projection.ref.identity]?.segments ?? []\n const end = segments[segments.length - 1]?.end\n return end?._tag === 'Cursor'\n ? {\n ...projection.ref,\n window: { ...pageSize(projection.ref.window, 'first'), after: end.cursor },\n }\n : undefined\n },\n previous: (model, projection) => {\n const start = store.get(model).connections[projection.ref.identity]?.segments[0]?.start\n return start?._tag === 'Cursor'\n ? {\n ...projection.ref,\n window: { ...pageSize(projection.ref.window, 'last'), before: start.cursor },\n }\n : undefined\n },\n fetch: ref => ({\n name: `Remote.query(${ref.query})`,\n args: { connection: ref.identity, window: ref.window },\n effect: Remote.query(ref).pipe(\n Effect.match({\n onFailure: (error): RemoteMessage => ({\n _tag: 'QueryFailed',\n connection: ref.identity,\n error: remoteError(error),\n }),\n onSuccess: (page): RemoteMessage => pageMessage(ref.identity, page),\n }),\n ),\n }),\n mutate: (model, mutation, input, options = {}) => {\n assertRegistered(bound, 'Mutation', definition.registry.mutations, mutation.name)\n const remote = store.get(model)\n const requestId =\n options.requestId ?? `${bound.contract.name}-${remote.mutations.sequence + 1}`\n const tempId = `${requestId}.tmp`\n const optimistic =\n typeof options.optimistic === 'function'\n ? options.optimistic({ requestId, tempId })\n : options.optimistic\n const started = updateRemote(remote, {\n _tag: 'MutationStarted',\n requestId,\n ...(optimistic === undefined ? {} : { optimistic }),\n })\n return {\n model: store.set(model, started as Store),\n requestId,\n tempId,\n command: {\n name: `Remote.mutate(${mutation.name})`,\n args: { requestId },\n effect: mutateRemote(mutation, input, requestId).pipe(\n Effect.match({\n onFailure: (error): RemoteMessage => ({\n _tag: 'MutationFailed',\n requestId,\n error: remoteError(error),\n }),\n onSuccess: (outcome): RemoteMessage => ({\n _tag: 'MutationSucceeded',\n requestId,\n entities: outcome.entities,\n connections: outcome.connections,\n }),\n }),\n ),\n },\n }\n },\n reduce,\n inspect: model => inspectRemote(store.get(model)),\n }\n}\n\n/** The window keys of a `QueryOptions`, and only those, without the undefined ones. */\nconst pickWindow = (window: QueryWindowOptions): QueryWindow => ({\n ...(window.first === undefined ? {} : { first: window.first }),\n ...(window.last === undefined ? {} : { last: window.last }),\n ...(window.after === undefined ? {} : { after: window.after }),\n ...(window.before === undefined ? {} : { before: window.before }),\n})\n\n/** The page size of a window, carried onto the next or previous page's window under `key`. */\nconst pageSize = (window: QueryWindow, key: 'first' | 'last'): QueryWindow => {\n const size = window.first ?? window.last\n return size === undefined ? {} : { [key]: size }\n}\n"],"mappings":"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"}