foldkit-remote 0.20.0 → 0.22.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.
Files changed (198) hide show
  1. package/README.md +987 -198
  2. package/dist/answerGaps.d.ts +16 -0
  3. package/dist/answerGaps.d.ts.map +1 -0
  4. package/dist/answerGaps.js +60 -0
  5. package/dist/answerGaps.js.map +1 -0
  6. package/dist/client-B055kQuP.d.ts +110 -0
  7. package/dist/client-B055kQuP.d.ts.map +1 -0
  8. package/dist/client.d.ts +2 -0
  9. package/dist/client.js +142 -0
  10. package/dist/client.js.map +1 -0
  11. package/dist/coalesce-CLAr92Nk.d.ts +34 -0
  12. package/dist/coalesce-CLAr92Nk.d.ts.map +1 -0
  13. package/dist/coalesce.d.ts +2 -0
  14. package/dist/coalesce.js +131 -0
  15. package/dist/coalesce.js.map +1 -0
  16. package/dist/connection-BRyaJy89.d.ts +45 -0
  17. package/dist/connection-BRyaJy89.d.ts.map +1 -0
  18. package/dist/connection.d.ts +2 -0
  19. package/dist/connection.js +170 -0
  20. package/dist/connection.js.map +1 -0
  21. package/dist/data.d.ts +7 -0
  22. package/dist/data.d.ts.map +1 -0
  23. package/dist/data.js +21 -0
  24. package/dist/data.js.map +1 -0
  25. package/dist/diagnostics-DHhVYflV.d.ts +125 -0
  26. package/dist/diagnostics-DHhVYflV.d.ts.map +1 -0
  27. package/dist/diagnostics.d.ts +2 -0
  28. package/dist/diagnostics.js +60 -0
  29. package/dist/diagnostics.js.map +1 -0
  30. package/dist/entity-CgsG5Uel.d.ts +196 -0
  31. package/dist/entity-CgsG5Uel.d.ts.map +1 -0
  32. package/dist/entity-DuDxaa3n.js +279 -0
  33. package/dist/entity-DuDxaa3n.js.map +1 -0
  34. package/dist/entity.d.ts +2 -0
  35. package/dist/entity.js +1 -0
  36. package/dist/held.d.ts +19 -0
  37. package/dist/held.d.ts.map +1 -0
  38. package/dist/held.js +70 -0
  39. package/dist/held.js.map +1 -0
  40. package/dist/impact.d.ts +79 -0
  41. package/dist/impact.d.ts.map +1 -0
  42. package/dist/impact.js +166 -0
  43. package/dist/impact.js.map +1 -0
  44. package/dist/index.d.ts +1542 -0
  45. package/dist/index.d.ts.map +1 -0
  46. package/dist/index.js +2791 -0
  47. package/dist/index.js.map +1 -0
  48. package/dist/inspect-DtRQGCRP.d.ts +134 -0
  49. package/dist/inspect-DtRQGCRP.d.ts.map +1 -0
  50. package/dist/inspect.d.ts +2 -0
  51. package/dist/inspect.js +33 -0
  52. package/dist/inspect.js.map +1 -0
  53. package/dist/json-DowLl1eB.d.ts +52 -0
  54. package/dist/json-DowLl1eB.d.ts.map +1 -0
  55. package/dist/json.d.ts +2 -0
  56. package/dist/json.js +123 -0
  57. package/dist/json.js.map +1 -0
  58. package/dist/law.d.ts +56 -0
  59. package/dist/law.d.ts.map +1 -0
  60. package/dist/law.js +201 -0
  61. package/dist/law.js.map +1 -0
  62. package/dist/live-BpTzlCnY.d.ts +79 -0
  63. package/dist/live-BpTzlCnY.d.ts.map +1 -0
  64. package/dist/live.d.ts +2 -0
  65. package/dist/live.js +126 -0
  66. package/dist/live.js.map +1 -0
  67. package/dist/matching-DF5F9Us8.d.ts +100 -0
  68. package/dist/matching-DF5F9Us8.d.ts.map +1 -0
  69. package/dist/matching.d.ts +2 -0
  70. package/dist/matching.js +172 -0
  71. package/dist/matching.js.map +1 -0
  72. package/dist/model-B6zk1NMB.d.ts +710 -0
  73. package/dist/model-B6zk1NMB.d.ts.map +1 -0
  74. package/dist/model.d.ts +2 -0
  75. package/dist/model.js +1308 -0
  76. package/dist/model.js.map +1 -0
  77. package/dist/mutation.d.ts +2 -0
  78. package/dist/mutation.js +612 -0
  79. package/dist/mutation.js.map +1 -0
  80. package/dist/optimistic-CECsfNGY.d.ts +523 -0
  81. package/dist/optimistic-CECsfNGY.d.ts.map +1 -0
  82. package/dist/optimistic.d.ts +2 -0
  83. package/dist/optimistic.js +336 -0
  84. package/dist/optimistic.js.map +1 -0
  85. package/dist/outbox-DNuc4kZp.d.ts +259 -0
  86. package/dist/outbox-DNuc4kZp.d.ts.map +1 -0
  87. package/dist/outbox.d.ts +2 -0
  88. package/dist/outbox.js +326 -0
  89. package/dist/outbox.js.map +1 -0
  90. package/dist/patchValues.d.ts +10 -0
  91. package/dist/patchValues.d.ts.map +1 -0
  92. package/dist/patchValues.js +57 -0
  93. package/dist/patchValues.js.map +1 -0
  94. package/dist/persistence-CCMnvg7-.d.ts +114 -0
  95. package/dist/persistence-CCMnvg7-.d.ts.map +1 -0
  96. package/dist/persistence.d.ts +2 -0
  97. package/dist/persistence.js +205 -0
  98. package/dist/persistence.js.map +1 -0
  99. package/dist/placement-jZdsIpmj.d.ts +50 -0
  100. package/dist/placement-jZdsIpmj.d.ts.map +1 -0
  101. package/dist/placement.d.ts +2 -0
  102. package/dist/placement.js +116 -0
  103. package/dist/placement.js.map +1 -0
  104. package/dist/plan-D9cftxC_.d.ts +35 -0
  105. package/dist/plan-D9cftxC_.d.ts.map +1 -0
  106. package/dist/plan.d.ts +2 -0
  107. package/dist/plan.js +100 -0
  108. package/dist/plan.js.map +1 -0
  109. package/dist/policy-DsWHmIAq.d.ts +42 -0
  110. package/dist/policy-DsWHmIAq.d.ts.map +1 -0
  111. package/dist/policy.d.ts +2 -0
  112. package/dist/policy.js +32 -0
  113. package/dist/policy.js.map +1 -0
  114. package/dist/{port.d.mts → port.d.ts} +3 -2
  115. package/dist/port.d.ts.map +1 -0
  116. package/dist/{port.mjs → port.js} +3 -2
  117. package/dist/port.js.map +1 -0
  118. package/dist/query-BuIU93xA.d.ts +141 -0
  119. package/dist/query-BuIU93xA.d.ts.map +1 -0
  120. package/dist/query.d.ts +2 -0
  121. package/dist/query.js +0 -0
  122. package/dist/query.js.map +1 -0
  123. package/dist/record.d.ts +11 -0
  124. package/dist/record.d.ts.map +1 -0
  125. package/dist/record.js +21 -0
  126. package/dist/record.js.map +1 -0
  127. package/dist/relation-BLBGOZom.d.ts +59 -0
  128. package/dist/relation-BLBGOZom.d.ts.map +1 -0
  129. package/dist/relation.d.ts +2 -0
  130. package/dist/relation.js +93 -0
  131. package/dist/relation.js.map +1 -0
  132. package/dist/remoteData-mK1suYi1.d.ts +148 -0
  133. package/dist/remoteData-mK1suYi1.d.ts.map +1 -0
  134. package/dist/remoteData.d.ts +2 -0
  135. package/dist/remoteData.js +179 -0
  136. package/dist/remoteData.js.map +1 -0
  137. package/dist/reporting.d.ts +12 -0
  138. package/dist/reporting.d.ts.map +1 -0
  139. package/dist/reporting.js +45 -0
  140. package/dist/reporting.js.map +1 -0
  141. package/dist/requirement-D57S2LpH.d.ts +64 -0
  142. package/dist/requirement-D57S2LpH.d.ts.map +1 -0
  143. package/dist/requirement.d.ts +2 -0
  144. package/dist/requirement.js +114 -0
  145. package/dist/requirement.js.map +1 -0
  146. package/dist/resume-Ct5R6yli.d.ts +92 -0
  147. package/dist/resume-Ct5R6yli.d.ts.map +1 -0
  148. package/dist/resume.d.ts +2 -0
  149. package/dist/resume.js +222 -0
  150. package/dist/resume.js.map +1 -0
  151. package/dist/retain-BfNTvBRb.d.ts +48 -0
  152. package/dist/retain-BfNTvBRb.d.ts.map +1 -0
  153. package/dist/retain.d.ts +2 -0
  154. package/dist/retain.js +107 -0
  155. package/dist/retain.js.map +1 -0
  156. package/dist/selection.d.ts +2 -0
  157. package/dist/selection.js +1 -0
  158. package/dist/shown.d.ts +20 -0
  159. package/dist/shown.d.ts.map +1 -0
  160. package/dist/shown.js +40 -0
  161. package/dist/shown.js.map +1 -0
  162. package/dist/sse-C7LhdbiQ.d.ts +17 -0
  163. package/dist/sse-C7LhdbiQ.d.ts.map +1 -0
  164. package/dist/sse.d.ts +2 -0
  165. package/dist/sse.js +127 -0
  166. package/dist/sse.js.map +1 -0
  167. package/dist/store-ah2qjcJW.d.ts +100 -0
  168. package/dist/store-ah2qjcJW.d.ts.map +1 -0
  169. package/dist/store.d.ts +2 -0
  170. package/dist/store.js +218 -0
  171. package/dist/store.js.map +1 -0
  172. package/dist/testing.d.ts +133 -0
  173. package/dist/testing.d.ts.map +1 -0
  174. package/dist/testing.js +0 -0
  175. package/dist/testing.js.map +1 -0
  176. package/dist/why-kgp_Wr3z.d.ts +483 -0
  177. package/dist/why-kgp_Wr3z.d.ts.map +1 -0
  178. package/dist/why.d.ts +2 -0
  179. package/dist/why.js +293 -0
  180. package/dist/why.js.map +1 -0
  181. package/dist/whyReasons.d.ts +42 -0
  182. package/dist/whyReasons.d.ts.map +1 -0
  183. package/dist/whyReasons.js +211 -0
  184. package/dist/whyReasons.js.map +1 -0
  185. package/dist/wire-DthPcTM6.d.ts +787 -0
  186. package/dist/wire-DthPcTM6.d.ts.map +1 -0
  187. package/dist/wire.d.ts +2 -0
  188. package/dist/wire.js +329 -0
  189. package/dist/wire.js.map +1 -0
  190. package/package.json +19 -14
  191. package/dist/index-BEvVAL76.d.mts +0 -4097
  192. package/dist/index-BEvVAL76.d.mts.map +0 -1
  193. package/dist/index.d.mts +0 -2
  194. package/dist/index.mjs +0 -1
  195. package/dist/port.d.mts.map +0 -1
  196. package/dist/port.mjs.map +0 -1
  197. package/dist/src-BDqn7Ocr.mjs +0 -6344
  198. package/dist/src-BDqn7Ocr.mjs.map +0 -1
@@ -0,0 +1,1542 @@
1
+ import { a as remoteDataSchema, i as RemoteError, n as Freshness, o as remoteErrorSchema, r as RemoteData, t as Denied } from "./remoteData-mK1suYi1.js";
2
+ import { a as PredictionPart, i as PredictionMismatch, n as OutboxUnreadable, o as RemoteDiagnostic, r as OutboxUnsaved, s as WriteUnheard, t as LiveRefused } from "./diagnostics-DHhVYflV.js";
3
+ import { _ as unknown, a as EdgeRef, c as edge, d as hasPrevious, f as isGapped, g as terminal, h as segment, i as Edge, l as emptyConnection, m as merge, n as Connection, o as Segment, p as items, r as Cursor, s as cursor, t as Boundary, u as hasNext } from "./connection-BRyaJy89.js";
4
+ import { S as writeEntity, _ as remove, a as askAgain, b as tombstone, c as entityKey, d as isFieldStale, f as isFieldUnavailable, g as readField, h as missingFields, i as EntityWrite, l as entry, m as markStale, n as EntityKey, o as clearStale, p as isTombstone, r as EntityStore, s as emptyStore, t as EntityEntry, u as hasField, v as setStale, x as writeEntities, y as setUnavailable } from "./store-ah2qjcJW.js";
5
+ import { A as PendingDelete, B as derivedOfWrite, C as DerivedBy, D as MutationState, E as MutationDescriptor, F as SchemaOrFields, G as mutationStatus, H as failMutation, I as StartedWrite, J as predictionOfWrite, K as optimisticOfWrite, L as TypeOf, M as Reconciled, N as Refusal, O as MutationStatus, P as RefusalOfWrite, R as beginMutation, S as visibleStore, T as MutationAnswer, U as forbiddenByWrite, V as emptyMutationState, W as forgetFailure, X as schemaOf, Y as reconcileMutation, Z as settledLater, _ as removeOverlay, a as OptimisticOperation, b as settleSuccess, c as addOverlay, d as emptyOptimistic, f as goneIn, g as removeLayer, h as pruneOverlays, i as EntityLayer, j as PendingPatch, k as NormalizedPatch, l as beginOptimistic, m as plannedStore, n as ConnectionIdentity, o as OptimisticState, p as heldOnlyByRequests, q as patchOfWrite, r as ConnectionOverlay, s as addLayer, t as ConnectionChange, u as connectionIdentity, v as resolvedPatches, w as Mutation, x as visibleItems, y as settleFailure, z as brokenByWrite } from "./optimistic-CECsfNGY.js";
6
+ import { a as Query, c as QueryRef, d as queryIdentity, f as stableStringify, i as LivePolicy, l as QueryWindow, n as IDENTITY_SEPARATOR, o as QueryDescriptor, r as LiveInsertion, s as QueryInputs, t as ConnectionSpec, u as ResultOf } from "./query-BuIU93xA.js";
7
+ import { a as Requirement, i as RemoteRequirements, n as RelationRequirement, o as connectionsOf, r as RemoteConnections, s as requirementsOf, t as ConnectionRequirement } from "./requirement-D57S2LpH.js";
8
+ import { A as RemoteMutationError, B as WireBoundary, C as ReadBatch, D as RemoteForbidden, E as RelationRequest, F as RemoteUnauthenticated, I as RemoteUnreachable, L as SettledFields, M as RemoteQueryError, N as RemoteReadError, O as RemoteLiveError, P as RemoteRpc, R as ShownSlice, S as Read, T as ReadRequest, _ as QueryEdge, a as LiveEdge, b as QueryRpc, c as MAX_LIVE_QUERIES, d as Mutate, f as MutationRequest, g as PageSize, h as OperationId, i as LiveChange, j as RemoteProtocolError, k as RemoteLiveRefused, l as MAX_RELATION_DEPTH, m as NormalizedEntity, n as ConnectionChangeSchema, o as LiveRequirement, p as MutationResult, r as Live, s as MAX_FIELDS_PER_REQUEST, t as AnswerRead, u as MAX_SHOWN_ENTITIES, v as QueryRequest, w as ReadBatchResult, x as REMOTE_PROTOCOL_VERSION, y as QueryResult, z as WindowSchema } from "./wire-DthPcTM6.js";
9
+ import { a as coalesceReads, i as coalesceQueries, n as CoalesceOptions, o as requirementKey, r as QueryRun, t as BatchRead } from "./coalesce-CLAr92Nk.js";
10
+ import { a as LiveEvent, c as applyConnectionEvent, d as emptyLiveState, f as liveHasNext, i as LiveCursor, l as applyEntityEvent, n as ConnectionApplied, o as LiveOutcome, p as liveHasPrevious, r as EntityApplied, s as LiveState, t as BoundaryCounts, u as classifyLive } from "./live-BpTzlCnY.js";
11
+ import { a as connectionChangeOf, c as mutateRemote, i as coalescedLayer, l as remoteError, n as RemoteJsonClient, o as liveEventOf, r as RemoteRpcClient, s as mintOperation, t as RemoteClient } from "./client-B055kQuP.js";
12
+ import { a as RelationEntityAnnotation, c as aliasedField, d as refsIn, f as relationAlias, i as RelationAnnotation, l as isRefPage, m as targetsOf, n as RefPageValue, o as RelationKind, p as relationShape, r as RefParts, s as RelationShape, t as RELATION_ALIAS, u as refParts } from "./relation-BLBGOZom.js";
13
+ import { _ as relationOf, a as EntityRef, c as RefKey, d as Selection, f as SelectionOf, g as pageSchema, h as assemble, i as EntityPatch, l as RefPage, m as SelectionValueOf, n as Entity, o as FieldsFrom, p as SelectionValue, r as EntityDescriptor, s as PatchValues, t as AnySchema, u as Page, v as unavailableOf } from "./entity-CgsG5Uel.js";
14
+ import { a as belongsEncoded, i as MatchingOptions, n as Judged, o as matching, r as Matched, t as Belongs } from "./matching-DF5F9Us8.js";
15
+ import { a as Why, i as ShownBy, n as ReadStep, o as WhyTerm, r as ReadWhy } from "./why-kgp_Wr3z.js";
16
+ import { a as OutboxStatus, l as RetryOptions, n as OutboxItemState, t as OutboxItem } from "./outbox-DNuc4kZp.js";
17
+ import { a as gc, i as departedLimit, n as Retained, o as reachable, r as RetentionRoots, s as recentRoots, t as ConnectionRoot } from "./retain-BfNTvBRb.js";
18
+ import { a as SnapshotOptions, i as Snapshot, n as REMOTE_CACHE_VERSION, r as RemotePersistence, t as MergePolicy } from "./persistence-CCMnvg7-.js";
19
+ import { A as updateRemote, C as overlaysOf, D as remoteMessageSchema, E as remoteMessageCases, M as withRefreshRequested, N as writeRead, O as remoteModelSchema, S as onlyOverlaid, T as refreshedAt, _ as isLoading, a as RemoteMessageInput, b as isRemoteMessage, c as StreamHealth, d as failureOf, f as fieldMark, g as isFieldFailed, h as invalidateConnections, i as RemoteMessage, j as windowGrowthKey, k as retentionRootsSchema, l as dismissQueued, m as initialRemoteModel, n as PlacedOrder, o as RemoteMessageTag, p as forgetRemote, r as RefreshState, s as RemoteModel, t as Failures, u as emptyRefresh, v as isLoadingThrough, w as refreshIsInFlight, x as noFailures, y as isQueryLoading } from "./model-B6zk1NMB.js";
20
+ import { a as inspectRemote, i as inspectEntity, n as QueryExplanation, r as RemoteInspection, t as ExplainedDependencies } from "./inspect-DtRQGCRP.js";
21
+ import { a as plan, i as deadlineOf, n as PlanFreshness, o as windowKey, r as PlanOptions, t as Deadline } from "./plan-D9cftxC_.js";
22
+ import { t as RemotePolicy } from "./policy-DsWHmIAq.js";
23
+ import { r as RemoteResumePart, s as resumePart } from "./resume-Ct5R6yli.js";
24
+ import { a as json, i as http, n as RemoteJsonRequest, r as RemoteJsonSend, t as RemoteJsonAnswer } from "./json-DowLl1eB.js";
25
+ import { n as httpWithLive, r as liveFetch, t as LiveFetchOptions } from "./sse-C7LhdbiQ.js";
26
+ import { n as placeIn, t as RowPlace } from "./placement-jZdsIpmj.js";
27
+ import { Duration, Effect, Layer, Option, Schema } from "effect";
28
+ import { ActiveSurface, Contract, Diagnostic, Diagnostics, Focus, Invalid, ModelRef, Projection, ReportDiagnostic, Surface, SurfaceSource, Wiring } from "foldkit-surface";
29
+ import * as Domain from "foldkit-entity";
30
+ import { MemoryOperators } from "foldkit-entity";
31
+ import { RpcClientError } from "effect/rpc";
32
+ import { KeyValueStore } from "effect/persistence";
33
+ import { Command } from "foldkit/command";
34
+ import { EntryWithoutKeepAlive } from "foldkit/subscription";
35
+ import * as Update from "foldkit/update";
36
+ /** What a domain registers: a Remote descriptor, or a `foldkit-entity` Entity (read through `Entity.from`). */
37
+ export type EntityLike = EntityDescriptor<any, any> | Domain.AnyEntity;
38
+ /**
39
+ * What a read selects: a Remote Selection, or a `foldkit-entity` Selection
40
+ * (read through `Selection.from`).
41
+ */
42
+ export type EntitySelection<Value, Name extends string, Id extends string = string> = Selection<Value, Name, 'entity'> | Domain.Selection<Name, unknown, Schema.Constraint & {
43
+ readonly Type: Value;
44
+ }, Id>;
45
+ /** The Remote descriptor either kind of entity reads as, at the type level. */
46
+ type DescriptorOf<E extends EntityLike> = E extends EntityDescriptor<any, any> ? E : E extends Domain.AnyEntity ? EntityDescriptor<E['name'], FieldsFrom<E>> : never;
47
+ type NameOf<E extends EntityLike> = DescriptorOf<E> extends EntityDescriptor<infer N, any> ? N : never;
48
+ type FieldsOf<E extends EntityLike> = DescriptorOf<E> extends EntityDescriptor<any, infer F> ? F : never;
49
+ type EntityName<D> = D extends {
50
+ readonly name: infer Name extends string;
51
+ } ? Name : never;
52
+ type QueryName<D> = D extends QueryDescriptor<infer Name, any, any> ? Name : never;
53
+ type MutationName<D> = D extends MutationDescriptor<infer Name, any, any> ? Name : never;
54
+ /**
55
+ * Nothing when `Name` is one of the domain's registered `Names`; otherwise a
56
+ * branded failure naming the descriptor, so `Data.get(Team.select(…))` for an
57
+ * unregistered `Team` errors at the selection in one line.
58
+ */
59
+ export type Registered<Name extends string, Names extends string, Kind extends string> = [Name] extends [Names] ? unknown : Invalid<`${Kind} "${Name}" is not registered with this Remote domain`>;
60
+ /** Nothing when a selection is of the query's entity; otherwise a branded failure naming both. */
61
+ export type SelectsEntity<Entity extends string, Of extends string> = [Entity] extends [Of] ? unknown : Invalid<`the selection is of "${Entity}", but the query lists "${Of}"`>;
62
+ export interface RemoteDescriptor<Entities extends readonly EntityLike[] = readonly EntityLike[], Queries extends readonly QueryDescriptor<any, any, any>[] = readonly QueryDescriptor<any, any, any>[], Mutations extends readonly MutationDescriptor<any, any, any>[] = readonly MutationDescriptor<any, any, any>[]> {
63
+ readonly entities: Entities;
64
+ readonly queries: Queries;
65
+ readonly mutations: Mutations;
66
+ readonly Model: Schema.Codec<RemoteModel, unknown>;
67
+ readonly initial: RemoteModel;
68
+ readonly Message: Schema.Schema<RemoteMessage>;
69
+ readonly update: (model: RemoteModel, message: RemoteMessage) => RemoteModel;
70
+ readonly rpc: typeof RemoteRpc;
71
+ /** Name-keyed lookups built from the declared entities, queries, and mutations. */
72
+ readonly registry: {
73
+ readonly entities: ReadonlyMap<string, EntityDescriptor<any, any>>;
74
+ readonly queries: ReadonlyMap<string, QueryDescriptor<any, any, any>>;
75
+ readonly mutations: ReadonlyMap<string, MutationDescriptor<any, any, any>>;
76
+ /**
77
+ * Per entity name, the members its server filters rows by under a rule
78
+ * the client does not run (`ReadFilter`), so a change to one is fetched,
79
+ * not placed.
80
+ */
81
+ readonly filtered: ReadonlyMap<string, ReadonlyArray<string>>;
82
+ /**
83
+ * Per entity name, the members other registered Entities derive over its
84
+ * relations (`Derived.count`, `Derived.exists`), which a write of it
85
+ * moves: what a declared write predicts.
86
+ */
87
+ readonly derived: ReadonlyMap<string, ReadonlyArray<DerivedBy>>;
88
+ };
89
+ }
90
+ declare const boundRemoteNames: unique symbol;
91
+ export interface BoundRemote<AppModel, Store extends RemoteModel, Names extends string = string> {
92
+ readonly definition: RemoteDescriptor;
93
+ /** The focus of the store's place in the application Model. */
94
+ readonly store: Focus<AppModel, Store>;
95
+ /** For `Module`: owns the store's Model path. */
96
+ readonly contract: Contract;
97
+ /**
98
+ * How the client runs primitive operators: `Remote.make`'s table, which a
99
+ * pending computed assignment is predicted by wherever the store is read.
100
+ */
101
+ readonly operators: MemoryOperators;
102
+ /** Phantom: the entity names this Remote definition registers. */
103
+ readonly [boundRemoteNames]?: Names;
104
+ }
105
+ type MutationInput<M> = M extends MutationDescriptor<any, infer Input, any> ? Input : never;
106
+ type MutationRefusal<M> = M extends MutationDescriptor<any, any, any, infer Refused> ? Refused : never;
107
+ /** How `Data.persistence` keeps the cache across a reload. */
108
+ export interface PersistenceOptions<AppModel> {
109
+ /**
110
+ * Where the snapshot is stored, from the Model: one key per principal, so a
111
+ * change of principal reads and writes another snapshot.
112
+ */
113
+ readonly key: (model: AppModel) => string;
114
+ /** Who the snapshot is for; one taken under another scope is discarded. */
115
+ readonly scope: (model: AppModel) => string;
116
+ /** The query connections whose rows survive a reload; none by default. */
117
+ readonly connections?: ReadonlyArray<ConnectionIdentity> | undefined;
118
+ /** What to keep, when it is not `snapshotOf` the `connections`. */
119
+ readonly snapshot?: ((remote: RemoteModel) => Snapshot) | undefined;
120
+ /** A snapshot larger than this is neither written nor read. */
121
+ readonly maxBytes?: number | undefined;
122
+ /** How long the cache must be unchanged before it is written; default 250 milliseconds. */
123
+ readonly debounce?: Duration.Input | undefined;
124
+ }
125
+ /** `Data.persistence`'s wiring, and the restore its runtime's `init` starts from. */
126
+ export interface PersistenceWiring<AppModel> extends Wiring<AppModel, RemoteMessage, KeyValueStore.KeyValueStore> {
127
+ /**
128
+ * The Model with the snapshot stored under its `key` restored, as the wiring
129
+ * would restore it. Resolve it as the runtime's `flags` and start `init`
130
+ * from it, so the first frame draws the stored rows; the wiring then
131
+ * restores only when `key` changes. A store it cannot read leaves the Model
132
+ * as it is, and the wiring tries again.
133
+ */
134
+ readonly restore: (model: AppModel) => Effect.Effect<AppModel, never, KeyValueStore.KeyValueStore>;
135
+ }
136
+ /** How `Data.outbox` keeps durable writes across a reload. */
137
+ export interface OutboxOptions<AppModel> {
138
+ /**
139
+ * Where the queue is stored, from the Model: one key per principal, so one
140
+ * person's waiting writes are never sent as another's.
141
+ */
142
+ readonly key: (model: AppModel) => string;
143
+ /**
144
+ * Who the queue is for, the principal. One stored under another scope reads
145
+ * as empty and is never written over; a page whose scope changes sends
146
+ * nothing it read for the old one, and reads the new one's.
147
+ */
148
+ readonly scope: (model: AppModel) => string;
149
+ /** The wait between sends nothing answered: 1 second doubling to 30, unless given. */
150
+ readonly retry?: RetryOptions | undefined;
151
+ }
152
+ /** `Data.outbox`'s wiring, and the restore its runtime's `init` starts from. */
153
+ export interface OutboxWiring<AppModel> extends Wiring<AppModel, RemoteMessage, KeyValueStore.KeyValueStore | RemoteClient> {
154
+ /**
155
+ * The Model with the stored queue under its `key` read back, as the wiring
156
+ * would read it, and this page's session minted. Resolve it as the runtime's
157
+ * `flags` and start `init` from it: a durable write needs the session, and
158
+ * the first frame then shows the waiting writes.
159
+ */
160
+ readonly restore: (model: AppModel) => Effect.Effect<AppModel, never, KeyValueStore.KeyValueStore>;
161
+ }
162
+ export interface DomainMutateOptions {
163
+ /** Overrides the generated id, for a retry, a durable bridge, or a test. Not with `durable`. */
164
+ readonly requestId?: string | undefined;
165
+ /**
166
+ * Queues the write in `Data.outbox` rather than sending it: stored first,
167
+ * sent in order by one tab, sent again after a reload with the same
168
+ * operation id and `now`, and after a failure that nothing answered. Its
169
+ * Command answers `MutationQueued`; the outbox's Subscriptions send it. Needs
170
+ * the outbox's `restore` to have run, and an input its Mutation encodes.
171
+ */
172
+ readonly durable?: boolean | undefined;
173
+ /**
174
+ * What the request changes before the server answers, released when it
175
+ * settles. A function receives the generated ids, so a created entity can
176
+ * carry `tempId` until the result names the real one.
177
+ */
178
+ readonly optimistic?: ReadonlyArray<OptimisticOperation> | ((ids: {
179
+ readonly requestId: string;
180
+ readonly tempId: string;
181
+ }) => ReadonlyArray<OptimisticOperation>) | undefined;
182
+ /**
183
+ * When the reader acted, in milliseconds since the epoch: what a time the
184
+ * write sets (`Expr.now` in `Entity.sets`) is predicted as, and the same
185
+ * number the request sends, which the server takes within its `clockSkew`.
186
+ * Read it where the action is, with `Remote.now`, since `update` reads no
187
+ * clock. Without it the time is not predicted, and the server's clock decides.
188
+ */
189
+ readonly now?: number | undefined;
190
+ /**
191
+ * For a mutation that is a `Write`: the input keys to write, when only some
192
+ * changed (what an author edited). The rest of the input is still sent, whole.
193
+ */
194
+ readonly keys?: ReadonlyArray<string> | undefined;
195
+ }
196
+ /**
197
+ * One entry of the active record `subscriptions`, `wiring` and `satisfy`
198
+ * take: a Surface as the Model activates it (`Surface.at`/`Surface.when`),
199
+ * a source of keyed instances (`Surface.each`, or any `SurfaceSource`), or a
200
+ * Surface without params read whole. A family joins its parent's
201
+ * requirements with its instances', so passing the family alone fetches both
202
+ * the page and what the page reveals.
203
+ */
204
+ export type ActiveEntry<AppModel> = ActiveSurface<AppModel> | Surface<AppModel, any, any, void> | SurfaceSource<AppModel>;
205
+ /** A Foldkit Subscription entry of the Remote domain, emitting its Messages through `RemoteClient`. */
206
+ export type RemoteEntry<AppModel, Dependencies> = EntryWithoutKeepAlive<AppModel, RemoteMessage, Dependencies, RemoteClient>;
207
+ /**
208
+ * The entries `RemoteDomain.subscriptions` returns for an active record: a read
209
+ * and a live entry per key (the live one idles when nothing is read live), and
210
+ * `retain`.
211
+ */
212
+ export type SubscriptionEntries<AppModel, Active, Message = RemoteMessage> = { readonly [K in keyof Active & (string | number) as `${K}.read`]: EntryWithoutKeepAlive<AppModel, Message, ReadDependencies, RemoteClient>; } & { readonly [K in keyof Active & (string | number) as `${K}.live`]: EntryWithoutKeepAlive<AppModel, Message, LiveDependencies, RemoteClient>; } & {
213
+ readonly retain: EntryWithoutKeepAlive<AppModel, Message, RetentionRoots, never>;
214
+ };
215
+ /** The dependencies of a live entry: what it subscribes to, and where a restart resumes. */
216
+ export interface LiveDependencies {
217
+ readonly requirements: ReadonlyArray<Requirement>;
218
+ /** The lists read live, each as its read sends it. */
219
+ readonly queries: ReadonlyArray<Schema.Schema.Type<typeof QueryRequest>>;
220
+ readonly cursor: LiveCursor;
221
+ readonly floor: number;
222
+ /** How many times the stream broke; each break restarts it. */
223
+ readonly restarts: number;
224
+ /** Breaks since its last applied event, which the restart's backoff grows with. */
225
+ readonly failures: number;
226
+ }
227
+ /**
228
+ * Whether what an active entry reads live is arriving. `Reconnecting` is a
229
+ * stream that broke and waits to resubscribe; until it has, changes are
230
+ * missed, and its rows may be out of date. `Refused` is a stream the server
231
+ * would not open for what it asks: it is not retried until that changes.
232
+ */
233
+ export type LiveStatus =
234
+ /** It reads nothing live. */
235
+ {
236
+ readonly _tag: 'Idle';
237
+ } |
238
+ /** Subscribed, and not broken since. */
239
+ {
240
+ readonly _tag: 'Live';
241
+ } | {
242
+ readonly _tag: 'Reconnecting';
243
+ /** Breaks in a row, the first being 1. */
244
+ readonly attempt: number;
245
+ /** Why it broke; none for a gap in its events. */
246
+ readonly error: Option.Option<RemoteError>;
247
+ } |
248
+ /** The server refused it (`RemoteLiveRefused`); it waits for what it asks to change. */
249
+ {
250
+ readonly _tag: 'Refused';
251
+ readonly error: RemoteError;
252
+ };
253
+ export interface SubscriptionsOptions extends ObserveOptions, LiveOptions, RetainOptions {}
254
+ /**
255
+ * A Remote domain's wiring for an assembly: it routes Remote's Messages into
256
+ * `reduce`, brings its Subscriptions and contract, and requires `RemoteClient`
257
+ * from the runtime's resources Layer. The `Shared` tags reach the
258
+ * application's own update too, after Remote has reduced them.
259
+ */
260
+ export type RemoteWiring<AppModel, Shared extends RemoteMessageTag = never> = Wiring<AppModel, RemoteMessage | RemoteMessageInput, RemoteClient, RemoteMessageTag> & {
261
+ readonly shared: ReadonlyArray<Shared>;
262
+ };
263
+ /** How `Data.wiring` joins an assembly: its Subscriptions' options, and what the application hears. */
264
+ export interface WiringOptions<Shared extends RemoteMessageTag = never> extends SubscriptionsOptions {
265
+ /**
266
+ * Remote's Messages the application's own `update` receives as well, after
267
+ * Remote has reduced them, so the Model it gets already holds what they say:
268
+ * `['MutationFailed']` to react to a write that failed.
269
+ */
270
+ readonly shared?: ReadonlyArray<Shared> | undefined;
271
+ }
272
+ /**
273
+ * A write that failed and is neither retried nor dismissed, typed by its
274
+ * mutation: what `Data.failedWrites` lists.
275
+ */
276
+ export interface FailedWrite<M extends MutationDescriptor<any, any, any, any>> {
277
+ readonly requestId: string;
278
+ readonly mutation: M;
279
+ /** The input it was started with, to show or give back. */
280
+ readonly input: MutationInput<M>;
281
+ readonly error: RemoteError;
282
+ /** Why the server refused it, as `mutation` declares; none for any other failure. */
283
+ readonly refusal: Option.Option<MutationRefusal<M>>;
284
+ }
285
+ /** `FailedWrite` of each of a union of mutations. */
286
+ export type FailedWriteOf<M> = M extends MutationDescriptor<any, any, any, any> ? FailedWrite<M> : never;
287
+ /** What `RemoteDomain.mutate` hands `update`: the Model with the request started, and the Command that settles it. */
288
+ export interface MutationStarted<AppModel> {
289
+ readonly model: AppModel;
290
+ readonly requestId: string;
291
+ readonly tempId: string;
292
+ /** Yields `MutationSucceeded` or `MutationFailed`; never fails. */
293
+ readonly command: Command<RemoteMessage, never, RemoteClient>;
294
+ }
295
+ /**
296
+ * A Remote domain bound to its place in the application Model: the descriptor
297
+ * (`Remote.define`), the binding (`Remote.at`), and the application-facing
298
+ * operations over them. Every method compiles to the `Remote.*` function of the
299
+ * same name, which stays exported for tooling, SSR, and tests.
300
+ */
301
+ export interface RemoteDomain<AppModel, Store extends RemoteModel, Entities extends readonly EntityLike[], Queries extends readonly QueryDescriptor<any, any, any>[], Mutations extends readonly MutationDescriptor<any, any, any>[]> extends BoundRemote<AppModel, Store, EntityName<Entities[number]>>, RemoteDescriptor<Entities, Queries, Mutations> {
302
+ /** `Remote.select`: a Projection reading one entity through a selection of a registered entity. */
303
+ get<Value, Name extends string, Id extends string = string>(selection: EntitySelection<Value, Name, Id> & Registered<Name, EntityName<Entities[number]>, 'Entity'>, id: NoInfer<Id>): Projection<AppModel, RemoteData<Value>>;
304
+ /**
305
+ * `get`, and the projection also subscribes to the entity's changes: its
306
+ * requirements are marked `live`, so `subscriptions` derives a live entry for
307
+ * the Surfaces that read it.
308
+ */
309
+ live<Value, Name extends string, Id extends string = string>(selection: EntitySelection<Value, Name, Id> & Registered<Name, EntityName<Entities[number]>, 'Entity'>, id: NoInfer<Id>): Projection<AppModel, RemoteData<Value>>;
310
+ /**
311
+ * A query connection read as a `Page` of items selected of the query's
312
+ * entity: `Initial` until the page and every item's selected fields are
313
+ * present, `Refreshing` while any of them is being refetched. The window is
314
+ * the page first asked for; the pages `next`, `previous` and `fetch` merge
315
+ * onto the connection read through the same projection.
316
+ */
317
+ query<Q extends QueryDescriptor<any, any, any>, Value, Entity extends string>(query: Q & Registered<Q['name'], QueryName<Queries[number]>, 'Query'>, input: QueryInput<Q>, options: QueryOptions<Value, Entity, QueryEntity<Q>>): QueryProjection<AppModel, Value, Q['name'], QueryInput<Q>>;
318
+ /**
319
+ * "Load more": the Model with the read's window grown by one page, so it
320
+ * shows that many more rows; the read entry fetches what the connection
321
+ * lacks. None when the read shows everything there is (or is not a sized
322
+ * window). Called from `update`.
323
+ */
324
+ more<Name extends string, Input>(model: AppModel, projection: QueryProjection<AppModel, any, Name, Input>): Option.Option<AppModel>;
325
+ /**
326
+ * What a query read is and what it currently is, as one serializable value —
327
+ * data-query-DESIGN §29.1: the domain, the definition and its input, the
328
+ * connection identity, the window, the Selection, the body as readable text
329
+ * with what it depends on, and what the read answers from this Model.
330
+ *
331
+ * Pure, so a DevTools panel showing it shows something the Model can be
332
+ * replayed to.
333
+ *
334
+ * Given `surfaces` — the same active record `subscriptions` takes — it also
335
+ * reports which of them read this connection, and why each is active where
336
+ * that is a readable fact (`Surface.when`) rather than a callback
337
+ * (`Surface.at`). A Projection cannot carry this itself: several Surfaces may
338
+ * read one connection, so it is not a property of the read.
339
+ */
340
+ explain<Name extends string, Input>(model: AppModel, projection: QueryProjection<AppModel, any, Name, Input>, options?: {
341
+ readonly surfaces?: Readonly<Record<string, ActiveSurface<AppModel> | SurfaceSource<AppModel>>> | undefined;
342
+ }): QueryExplanation;
343
+ /**
344
+ * Why a read shows what it shows. Any Remote read: `Data.get`, `Data.live`
345
+ * or `Data.query`, or a projection made of them.
346
+ *
347
+ * `because` is every fact the Model holds about what it reads, as typed
348
+ * references: a list or a row's fields missing, stale, in flight or
349
+ * failed; a pending write showing a value, and which `where` term put a row
350
+ * in a list or took it out. The reason that decides the state comes first,
351
+ * and `message` says it, with what restarts it. For `Initial`, given
352
+ * `surfaces` (the record `subscriptions` takes), it tells the two wiring
353
+ * mistakes apart: no active Surface reads it, or one does and Remote's
354
+ * Subscriptions are not running. Pure: it reads the Model and plans nothing.
355
+ */
356
+ why(model: AppModel, projection: Projection<AppModel, RemoteData<unknown>>, options?: {
357
+ readonly surfaces?: Readonly<Record<string, ActiveSurface<AppModel> | SurfaceSource<AppModel>>> | undefined;
358
+ }): ReadWhy;
359
+ /**
360
+ * Each change of each read's tag across a recorded history (the Messages
361
+ * `update` handled, each with the Model it left, as Foldkit's devtools
362
+ * records them), with the Message that made it and `why` at the Model it
363
+ * changed to. `regression` marks a read that showed a value and stopped
364
+ * with no reason a reader can see (#234).
365
+ */
366
+ timeline<Message>(start: AppModel, history: ReadonlyArray<{
367
+ readonly message: Message;
368
+ readonly model: AppModel;
369
+ }>, reads: Readonly<Record<string, Projection<AppModel, RemoteData<unknown>>>>, options?: {
370
+ readonly surfaces?: Readonly<Record<string, ActiveSurface<AppModel> | SurfaceSource<AppModel>>> | undefined;
371
+ }): ReadonlyArray<ReadStep<Message>>;
372
+ /**
373
+ * The rows of a loaded list that a body matches, decoded as the list decodes
374
+ * them — a filter that asks the server nothing.
375
+ *
376
+ * **It filters a list; it does not run a query.** That distinction is what
377
+ * keeps it honest. "Which rows match" would need to know that the list holds
378
+ * every row the body could match, which is predicate containment and is
379
+ * deliberately not built. "Which rows *of this list* match" is decidable from
380
+ * what is already here, and is what a search box over a loaded page actually
381
+ * wants.
382
+ *
383
+ * `complete` says whether the answer is about the whole list: every edge
384
+ * judged, and the connection terminal at both ends. An incomplete answer is
385
+ * not wrong — it is about less than the caller may have meant, which is why
386
+ * it is said rather than left for a view to assume.
387
+ *
388
+ * Creates no connection, so there is nothing new to retain and nothing new to
389
+ * fetch. The server stays authoritative for which rows exist.
390
+ */
391
+ filtered<Value, Name extends string, Input, Q extends QueryDescriptor<any, any, any>>(model: AppModel, over: QueryProjection<AppModel, Value, Name, Input>, by: Q & Registered<Q['name'], QueryName<Queries[number]>, 'Query'>, input: QueryInput<Q>): Matched<Value>;
392
+ /**
393
+ * Shows operations over the store with no request behind them, as a mutation's
394
+ * `optimistic` ones show while it is in flight: every Selection and view draws
395
+ * them. For a preview of a change nobody has made. They stay until `lift`;
396
+ * showing an id again replaces what it showed. Called from `update`. A read
397
+ * of an entity only overlays show, lacking a field it selects, is `Failed`
398
+ * (`Overlaid`): nothing will fetch that field.
399
+ */
400
+ overlay(model: AppModel, id: string, optimistic: ReadonlyArray<OptimisticOperation>): AppModel;
401
+ /** Lifts what `overlay` showed under this id. Lifting nothing returns the same Model. */
402
+ lift(model: AppModel, id: string): AppModel;
403
+ /**
404
+ * The ids `overlay` shows now, in the order they are drawn, a later one over
405
+ * an earlier: what a caller that overlays from its own state reconciles
406
+ * against.
407
+ */
408
+ overlays(model: AppModel): ReadonlyArray<string>;
409
+ /**
410
+ * The edges a connection shows, as its reads draw them: the server's pages
411
+ * with pending edits placed, each inserted row where the body's order puts
412
+ * it (or at the end its overlay names, when it cannot be placed), minus
413
+ * removed edges and tombstones. Takes the `RemoteModel`, so a persistence
414
+ * `snapshot` can store a list as it is shown.
415
+ */
416
+ visibleItems(remote: RemoteModel, connection: ConnectionIdentity): ReadonlyArray<Edge>;
417
+ /**
418
+ * `Remote.refresh`: marks what `target` reads for this Model as due, for its
419
+ * read entries to refetch. `target` is a projection, a Surface without
420
+ * params, one entry of the active record, or the record itself, whose
421
+ * params come from the Model as they do for `subscriptions`; or a
422
+ * registered query's ref, which invalidates that list whatever its window. With
423
+ * `{ failed: true }` only what failed is asked again: a "Try again".
424
+ */
425
+ refresh(model: AppModel, target: RefreshTarget<AppModel, QueryName<Queries[number]>>, options?: RefreshOptions): AppModel;
426
+ /** `Remote.forget`: the Model with every server-derived fact gone, for a change of principal. */
427
+ forget(model: AppModel): AppModel;
428
+ /**
429
+ * A read of this domain as an active Surface, for `subscriptions` and
430
+ * `wiring`: `projectionOf` is what it reads for a Model, none while it
431
+ * reads nothing. It belongs to the domain's application, and lists no
432
+ * Messages: it is a requirement, not a sender. A domain made from a raw
433
+ * optic names no application, so this throws for one.
434
+ */
435
+ active<Value>(name: string, projectionOf: (model: AppModel) => Option.Option<Projection<AppModel, Value>>): ActiveSurface<AppModel, Value>;
436
+ /**
437
+ * The Foldkit Subscription entries for the active record, keyed for
438
+ * `Subscription.make`: a read entry per record entry (`Remote.observe`), a
439
+ * live entry per record entry that reads through `live` (`Remote.live`), and
440
+ * one retain entry (`Remote.retain`). A `Surface.each` family is one record
441
+ * entry whose read unions its parent's requirements with its instances'.
442
+ * Retention is the domain's: the retain entry of every call roots the active
443
+ * Surfaces of every call, so reads split over calls (one per policy) do not
444
+ * collect each other's data. A Surface's params are a function of the Model
445
+ * (`Surface.at`), so what is fetched, subscribed, and retained follows the
446
+ * Model.
447
+ */
448
+ subscriptions<const Active extends Readonly<Record<string, ActiveEntry<AppModel>>>>(active: Active, options?: SubscriptionsOptions): SubscriptionEntries<AppModel, Active>;
449
+ /** `Remote.plan`: the requirements the store does not satisfy. */
450
+ plan<Value>(model: AppModel, projection: Projection<AppModel, Value>, options?: PlanOptions): ReadonlyArray<Requirement>;
451
+ /** `Remote.meta`: when what a projection shows was last received, and whether it is stale or loading. */
452
+ meta<Value>(model: AppModel, projection: Projection<AppModel, Value>): ReadMeta;
453
+ /** `Remote.storeOf`: the visible store, base under the pending optimistic layers. */
454
+ storeOf(model: AppModel): EntityStore;
455
+ /**
456
+ * `Remote.confirmed`: the same projection read against the server-derived
457
+ * store alone, with every pending optimistic layer and connection overlay
458
+ * left off. What it plans is unchanged — the requirements are the
459
+ * projection's own — so observing it reads exactly what observing the
460
+ * projection reads; only what it *shows* differs.
461
+ *
462
+ * A view usually wants the projection itself, which is the visible read:
463
+ * the optimistic layers are there so a change shows before the server has
464
+ * agreed to it. This is for the reader that must not believe a change until
465
+ * the server has confirmed it, which in practice is an Agent capability
466
+ * reporting that what it was asked to do is done:
467
+ *
468
+ * ```ts
469
+ * Agent.when({
470
+ * projection: Data.confirmed(ProjectPage.model.project),
471
+ * predicate: (project, request) => project.name === request.name,
472
+ * })
473
+ * ```
474
+ *
475
+ * There is deliberately no `visible`: a projection is already the visible
476
+ * read, and a wrapper that only forwards would be a second name for it.
477
+ */
478
+ confirmed<P extends Projection<AppModel, any>>(projection: P): P;
479
+ /**
480
+ * The plan run through `RemoteClient` and reduced into the Model: the
481
+ * projection's pending queries first, then the fields it lacks (the pages'
482
+ * items included). For SSR, route or hover prefetch, and tests.
483
+ */
484
+ prefetch<Value>(model: AppModel, projection: Projection<AppModel, Value>, options?: ObserveOptions): Effect.Effect<AppModel, RemoteReadError | RemoteProtocolError | RemoteQueryError | RemoteUnauthenticated, RemoteClient>;
485
+ /**
486
+ * The Model with everything the active Surfaces read, for a render that
487
+ * fetches nothing (SSR, a prerender). Each pass prefetches every Surface
488
+ * that plans a read, over the Model the one before it left, so a Surface
489
+ * active only once another's read has arrived is read in the next pass (or
490
+ * the same one, when it comes later in `active`). It stops at the first
491
+ * pass that plans nothing, and fails with `RemoteUnsatisfied` when
492
+ * `options.passes` run out first. Reads are cache-first: a field already
493
+ * held is not asked again. A server that could not tell who is asking
494
+ * fails it with `RemoteUnauthenticated`, for the host to answer as it
495
+ * answers a lost session.
496
+ */
497
+ satisfy(model: AppModel, active: Readonly<Record<string, ActiveEntry<AppModel>>>, options?: SatisfyOptions): Effect.Effect<AppModel, RemoteReadError | RemoteProtocolError | RemoteQueryError | RemoteUnauthenticated | RemoteUnsatisfied, RemoteClient>;
498
+ /**
499
+ * `satisfy` from `update`, for a destination the reader has not reached:
500
+ * a hover over a link, or a navigation the app expects. `model` is the
501
+ * Model as it would be there (the route set to the target's); the Command
502
+ * reads what `active` would read in it and yields one `Preloaded`
503
+ * carrying the Messages that wrote it, which reduce into the Model as it is
504
+ * by then. It never fails: a read that fails is one the destination makes
505
+ * again, and what was read before it still arrives.
506
+ *
507
+ * What it reads is kept like any other read until the next change of what
508
+ * is retained, so preload close to the navigation it expects.
509
+ */
510
+ preload(model: AppModel, active: Readonly<Record<string, ActiveEntry<AppModel>>>, options?: SatisfyOptions): Command<RemoteMessage, never, RemoteClient>;
511
+ /**
512
+ * Starts a registered mutation from `update`: applies `MutationStarted` (with
513
+ * the optimistic operations) to the Model and returns the Command that runs
514
+ * it and yields the settling Message. The request id comes from the model's
515
+ * mutation sequence unless `options.requestId` is given.
516
+ */
517
+ mutate<M extends MutationDescriptor<any, any, any>>(model: AppModel, mutation: M & Registered<M['name'], MutationName<Mutations[number]>, 'Mutation'>, input: MutationInput<M>, options?: DomainMutateOptions): MutationStarted<AppModel>;
518
+ /**
519
+ * What Remote knows of a mutation `mutate` started, by its request id:
520
+ * pending, applied, or failed with the error the server or transport gave.
521
+ */
522
+ mutation(model: AppModel, requestId: string): MutationStatus;
523
+ /**
524
+ * Why the server refused a mutation, as the value its `Refusal` declares:
525
+ * none while it is pending or applied, when it failed for another reason,
526
+ * or when the refusal does not decode as `mutation`'s.
527
+ */
528
+ refusal<Refused>(model: AppModel, requestId: string, mutation: MutationDescriptor<string, any, any, Refused>): Option.Option<Refused>;
529
+ /**
530
+ * The writes that failed and are still owed an answer, oldest first, each
531
+ * with its mutation, the input it was started with, and why it failed. Given
532
+ * a mutation, only its writes, with its input type. A write is listed until
533
+ * `retry` sends it again, `dismiss` forgets it, or `forget` changes the
534
+ * principal; nothing drops one on a timer, since that would hide a failure
535
+ * the reader has not seen.
536
+ */
537
+ failedWrites(model: AppModel): ReadonlyArray<FailedWriteOf<Mutations[number]>>;
538
+ failedWrites<M extends MutationDescriptor<any, any, any, any>>(model: AppModel, mutation: M & Registered<M['name'], MutationName<Mutations[number]>, 'Mutation'>): ReadonlyArray<FailedWrite<M>>;
539
+ /**
540
+ * Sends a failed write again as itself: the same input, request id and
541
+ * operation id (so a server that applied it answers from its record), with
542
+ * its optimistic operations shown again. None unless `failedWrites` lists it.
543
+ * A durable one is queued again, and the outbox sends it.
544
+ */
545
+ retry(model: AppModel, requestId: string): Option.Option<MutationStarted<AppModel>>;
546
+ /**
547
+ * Forgets a failed write, so `failedWrites` no longer lists it; a durable one,
548
+ * or one the outbox cannot read, goes from its store and every tab. Anything
549
+ * else (a write still waiting, too) returns the same Model.
550
+ */
551
+ dismiss(model: AppModel, requestId: string): AppModel;
552
+ /**
553
+ * The durable writes not yet settled, every tab's, in the order the outbox
554
+ * sends them: how many wait, how many the server refused, and each one's
555
+ * state, for a "3 changes waiting" line.
556
+ */
557
+ outboxStatus(model: AppModel): OutboxStatus;
558
+ /**
559
+ * Whether what `active` reads live is arriving: `Reconnecting` from the
560
+ * moment its stream breaks until it resubscribes, which its live entry does
561
+ * on its own, with backoff.
562
+ */
563
+ liveStatus(model: AppModel, active: ActiveEntry<AppModel>): LiveStatus;
564
+ /** `updateRemote` on the bound slice: reduces one of Remote's Messages, as `RemoteMessage` or as the application's union constructs it. */
565
+ reduce(model: AppModel, message: RemoteMessage | RemoteMessageInput): AppModel;
566
+ /**
567
+ * How this domain joins an assembly: it routes Remote's Messages into
568
+ * `reduce`, brings its Subscriptions and contract, and requires
569
+ * `RemoteClient` from the runtime's resources Layer. One assembly holds at
570
+ * most one Remote wiring: every domain claims the same tags, and routing
571
+ * takes the first claimant. `shared` names the Messages the application's
572
+ * own update hears too.
573
+ */
574
+ wiring: <const Active extends Readonly<Record<string, ActiveEntry<AppModel>>>, const Shared extends RemoteMessageTag = never>(active: Active, options?: WiringOptions<Shared>) => RemoteWiring<AppModel, Shared>;
575
+ /**
576
+ * Keeps the cache across a reload, as a wiring beside `wiring`: the stored
577
+ * snapshot for `key` is restored (`Hydrated`, with what the store already
578
+ * holds kept over it, so a page resumed from the server wins) whenever the
579
+ * Model is not yet restored from `key`; and the cache is written back when it
580
+ * changes, once its own snapshot is in. Start `init` from its `restore` so
581
+ * the first frame already holds the snapshot. Overlays, optimistic layers,
582
+ * the mutation ledger, live cursors and gaps are never stored. A change of
583
+ * principal should `forget` in `update`, and name another `key`.
584
+ */
585
+ persistence(options: PersistenceOptions<AppModel>): PersistenceWiring<AppModel>;
586
+ /**
587
+ * Keeps durable writes (`mutate`'s `durable`) across a reload and sends
588
+ * them, as a wiring beside `wiring`: the queue is written to `key` before a
589
+ * write is sent, sent oldest first by one tab (a Web Lock), sent again after
590
+ * a failure that nothing answered with a backoff, and read back by every
591
+ * tab. Start `init` from its `restore`. A change of principal should
592
+ * `forget` in `update`, and name another `key`.
593
+ */
594
+ outbox(options: OutboxOptions<AppModel>): OutboxWiring<AppModel>;
595
+ /** `Remote.inspect` of the bound slice. */
596
+ inspect(model: AppModel): RemoteInspection;
597
+ }
598
+ /** What `Remote.fold(Data, …).mutate` starts: `Data.mutate`'s result with its Command lifted. */
599
+ export type FoldedMutationStarted<AppModel, ParentMessage> = Omit<MutationStarted<AppModel>, 'command'> & {
600
+ readonly command: Command<ParentMessage, never, RemoteClient>;
601
+ };
602
+ /**
603
+ * A bound domain folded under one of the application's own Message variants,
604
+ * from `Remote.fold`. Calling it reduces a Remote Message into the Model; the
605
+ * members that produce Messages, `fetch`, `mutate`, and `subscriptions`,
606
+ * yield the wrapper Message instead of `RemoteMessage`, with the lift recorded
607
+ * so Story and Scene can resolve a fetch or a mutation by Remote's own answer.
608
+ * Members that only read or write the Model (`get`, `refresh`, `next`,
609
+ * `overlay`, and the rest) stay on the domain itself.
610
+ */
611
+ export interface RemoteFold<AppModel, ParentMessage, Domain extends RemoteDomain<AppModel, any, any, any, any>> {
612
+ (model: AppModel, message: RemoteMessage | RemoteMessageInput): Update.Return<AppModel, ParentMessage>;
613
+ /** `Data.mutate`, its Command lifted. */
614
+ readonly mutate: (...args: Parameters<Domain['mutate']>) => FoldedMutationStarted<AppModel, ParentMessage>;
615
+ /** `Data.retry`, its Command lifted. */
616
+ readonly retry: (...args: Parameters<Domain['retry']>) => Option.Option<FoldedMutationStarted<AppModel, ParentMessage>>;
617
+ /** `Data.preload`, its Command lifted. */
618
+ readonly preload: (...args: Parameters<Domain['preload']>) => Command<ParentMessage, never, RemoteClient>;
619
+ /** `Data.subscriptions`, every entry lifted to the wrapper Message. */
620
+ readonly subscriptions: <const Active extends Readonly<Record<string, ActiveEntry<AppModel>>>>(active: Active, options?: SubscriptionsOptions) => SubscriptionEntries<AppModel, Active, ParentMessage>;
621
+ }
622
+ /** The application Model a bound domain is over. */
623
+ export type ModelOfDomain<Domain> = Domain extends RemoteDomain<infer AppModel, any, any, any, any> ? AppModel : never;
624
+ /** A projection's connection requirement with the `QueryRef` that runs it. */
625
+ export interface QueryRequirement extends ConnectionRequirement {
626
+ readonly ref: QueryRef<string, unknown>;
627
+ }
628
+ /** A page forward (`first`, `after`) or back (`last`, `before`); mixing the two is a type error. */
629
+ export type QueryWindowOptions = {
630
+ readonly first?: number | undefined;
631
+ readonly after?: string | undefined;
632
+ readonly last?: undefined;
633
+ readonly before?: undefined;
634
+ } | {
635
+ readonly last: number;
636
+ readonly before?: string | undefined;
637
+ readonly first?: undefined;
638
+ readonly after?: undefined;
639
+ };
640
+ export type QueryOptions<Value, Entity extends string, Of extends string = Entity> = {
641
+ /** What to read of each item: a selection of the query's entity (`Of`). */
642
+ readonly select: EntitySelection<Value, Entity> & SelectsEntity<Entity, Of>;
643
+ /**
644
+ * Watch the list live while a Surface reads it: rows that join, change or
645
+ * leave it are streamed (by a live source that watches queries, such as
646
+ * `foldkit-remote-drizzle`'s `pollLive`). Needs `first`.
647
+ */
648
+ readonly live?: boolean | undefined;
649
+ } & QueryWindowOptions;
650
+ /** A query connection read as a `Page` of selected items; `ref` is the connection with its first window. */
651
+ export interface QueryProjection<AppModel, Value, Name extends string, Input> extends Projection<AppModel, RemoteData<Page<Value>>> {
652
+ readonly ref: QueryRef<Name, Input>;
653
+ /** What it reads of each item, so a filter over the same list decodes identically. */
654
+ readonly selection: Selection<Value, string>;
655
+ }
656
+ /** The input of a query descriptor. */
657
+ export type QueryInput<Q> = Q extends QueryDescriptor<any, infer Input, any> ? Input : never;
658
+ /** The entity a query's connection is over. */
659
+ export type QueryEntity<Q> = Q extends QueryDescriptor<any, any, ConnectionSpec<infer Entity>> ? Entity : string;
660
+ /**
661
+ * When what a projection shows was last received, and whether it is stale
662
+ * or loading. See `Remote.meta`.
663
+ */
664
+ export interface ReadMeta {
665
+ /** The newest server write among what is shown; none received reads `undefined`. */
666
+ readonly updatedAt: number | undefined;
667
+ /** Any shown field or connection is marked stale. */
668
+ readonly stale: boolean;
669
+ /** Any shown field or connection is in flight. */
670
+ readonly loading: boolean;
671
+ }
672
+ export interface MutateOptions {
673
+ /** What the request changes before the server answers; released when it settles. */
674
+ readonly optimistic?: ReadonlyArray<OptimisticOperation> | undefined;
675
+ /**
676
+ * When the reader acted, in milliseconds since the epoch, as `Remote.now`
677
+ * read it: sent for a time the write sets, which the server takes within
678
+ * its `clockSkew`.
679
+ */
680
+ readonly now?: number | undefined;
681
+ }
682
+ export interface RetainOptions {
683
+ /** The query connections the application shows, by `QueryRef` or identity. */
684
+ readonly connections?: ReadonlyArray<ConnectionIdentity> | undefined;
685
+ /** How long the roots must be stable before collecting; default none. */
686
+ readonly grace?: Duration.Input | undefined;
687
+ }
688
+ /** How `Remote.observe` and `Remote.prefetch` treat fields the store already holds. */
689
+ export interface ObserveOptions {
690
+ /** Default `RemotePolicy.cacheFirst`. */
691
+ readonly policy?: RemotePolicy | undefined;
692
+ /** The clock a refreshing policy reads; default `Date.now`, read at each use. */
693
+ readonly now?: (() => number) | undefined;
694
+ }
695
+ /** How `Data.satisfy` reads: how many passes it may take, and the clock. */
696
+ export interface SatisfyOptions {
697
+ /** At most this many passes over the Surfaces; default 8. */
698
+ readonly passes?: number | undefined;
699
+ /** The clock the reads are stamped with; default `Date.now`, read at each use. */
700
+ readonly now?: (() => number) | undefined;
701
+ }
702
+ declare const RemoteUnsatisfied_base: Schema.Class<RemoteUnsatisfied, Schema.TaggedStruct<"RemoteUnsatisfied", {
703
+ readonly surfaces: Schema.$Array<Schema.String>;
704
+ readonly passes: Schema.Number;
705
+ }>, import("effect/Cause").YieldableError>;
706
+ /**
707
+ * `Data.satisfy` reached its bound with Surfaces still reading, such as a
708
+ * chain whose every read reveals one more. It names them, so a page that
709
+ * would have rendered them loading fails instead. (A read the server leaves
710
+ * unanswered settles as missing and ends the loop.)
711
+ */
712
+ export declare class RemoteUnsatisfied extends RemoteUnsatisfied_base {}
713
+ export interface LiveOptions {
714
+ /** The clock `LiveReceived` stamps events with; default `Date.now`, read at each use. */
715
+ readonly now?: (() => number) | undefined;
716
+ /**
717
+ * The first restart's delay after a stream breaks, doubled for each break in
718
+ * a row, with ±20% jitter: Sync's transport policy. Default `50 millis`.
719
+ */
720
+ readonly retryBase?: Duration.Input | undefined;
721
+ /** The longest a restart waits. Default `5 seconds`. */
722
+ readonly maxRetryDelay?: Duration.Input | undefined;
723
+ }
724
+ /** Declares a Remote domain: its entities, queries, and mutations, plus the submodel. */
725
+ declare const defineRemote: <const Entities extends readonly EntityLike[], const Queries extends readonly QueryDescriptor<any, any, any>[] = readonly QueryDescriptor<any, any, any>[], const Mutations extends readonly MutationDescriptor<any, any, any>[] = readonly MutationDescriptor<any, any, any>[]>(config: {
726
+ readonly entities: Entities;
727
+ readonly queries?: Queries;
728
+ readonly mutations?: Mutations;
729
+ }) => RemoteDescriptor<Entities, Queries, Mutations>;
730
+ /** A query the read entry runs, as its dependencies carry it: plain data Foldkit compares. */
731
+ declare const PlannedQuery: Schema.Struct<{
732
+ readonly identity: Schema.String;
733
+ readonly window: Schema.Struct<{
734
+ readonly first: Schema.optional<Schema.Number>;
735
+ readonly last: Schema.optional<Schema.Number>;
736
+ readonly after: Schema.optional<Schema.String>;
737
+ readonly before: Schema.optional<Schema.String>;
738
+ }>;
739
+ readonly select: Schema.Codec<RelationRequirement, RelationRequirement, never, never>;
740
+ }>;
741
+ /** The dependencies of the read entry: the entity fields to read and the queries to run. */
742
+ export interface ReadDependencies {
743
+ readonly requirements: ReadonlyArray<Requirement>;
744
+ readonly queries: ReadonlyArray<Schema.Schema.Type<typeof PlannedQuery>>;
745
+ /**
746
+ * The highest generation the fields this entry reads were refreshed at: a
747
+ * refresh of any of them restarts the entry, and a refresh of anything else
748
+ * leaves it running.
749
+ */
750
+ readonly refresh: number;
751
+ /**
752
+ * Under a refreshing policy, when a value the entry holds next ages out and
753
+ * what is due then. Time reaches Remote only as a Message: the entry sleeps
754
+ * until then and emits `RefreshStarted`, which marks the fields stale, and
755
+ * the plan that follows fetches them. A Model that does not change past its
756
+ * `maxAge` is otherwise never looked at again.
757
+ */
758
+ readonly expires: Deadline | null;
759
+ }
760
+ /**
761
+ * What `Data.refresh` asks again: a projection, a Surface without params, one
762
+ * entry of the active record (a `Surface.at`/`Surface.when` value, a family),
763
+ * the whole record, or one list by its query and input (`Everyone.ref({})`),
764
+ * whatever window reads it.
765
+ */
766
+ export type RefreshTarget<AppModel, Queries extends string = string> = Projection<AppModel, unknown> | ActiveEntry<AppModel> | Readonly<Record<string, ActiveEntry<AppModel>>> | QueryRef<Queries, any>;
767
+ /** How `Data.refresh` asks again. */
768
+ export interface RefreshOptions {
769
+ /** Only what failed: a "Try again" leaves what loaded as it is. */
770
+ readonly failed?: boolean | undefined;
771
+ }
772
+ export declare const Remote: {
773
+ /** The submodel's schema, the same for every domain; embed it in the application Model. */
774
+ Model: Schema.Codec<RemoteModel, unknown, never, never>;
775
+ /** The submodel's initial value. */
776
+ initial: RemoteModel;
777
+ /**
778
+ * Remote's Message cases for `defineMessageUnion`: spread them into the
779
+ * application's union, and reduce the ones `Remote.reduces` recognizes with
780
+ * `RemoteDomain.reduce`.
781
+ */
782
+ messages: {
783
+ ReadReceived: {
784
+ requests: Schema.$Array<Schema.Codec<Requirement, Requirement, never, never>>;
785
+ result: Schema.Struct<{
786
+ readonly entities: Schema.$Array<Schema.Struct<{
787
+ readonly entity: Schema.String;
788
+ readonly id: Schema.String;
789
+ readonly values: Schema.$Record<Schema.String, Schema.Unknown>;
790
+ }>>;
791
+ readonly settled: Schema.$Array<Schema.Struct<{
792
+ readonly entity: Schema.String;
793
+ readonly id: Schema.String;
794
+ readonly fields: Schema.$Array<Schema.String>;
795
+ }>>;
796
+ }>;
797
+ now: Schema.Number;
798
+ };
799
+ ReadFailed: {
800
+ requests: Schema.$Array<Schema.Codec<Requirement, Requirement, never, never>>;
801
+ error: Schema.Struct<{
802
+ readonly _tag: Schema.String;
803
+ readonly message: Schema.String;
804
+ readonly refusal: Schema.optional<Schema.Unknown>;
805
+ readonly reason: Schema.optional<Schema.String>;
806
+ }>;
807
+ stream: Schema.optional<Schema.String>;
808
+ };
809
+ RefreshStarted: {
810
+ requests: Schema.$Array<Schema.Codec<Requirement, Requirement, never, never>>;
811
+ };
812
+ ReadStarted: {
813
+ requests: Schema.$Array<Schema.Codec<Requirement, Requirement, never, never>>;
814
+ refresh: Schema.optional<Schema.Number>;
815
+ };
816
+ QueryStarted: {
817
+ connections: Schema.$Array<Schema.String>;
818
+ };
819
+ RetentionChanged: {
820
+ roots: Schema.Struct<{
821
+ readonly requirements: Schema.$Array<Schema.Codec<Requirement, Requirement, never, never>>;
822
+ readonly connections: Schema.$Array<Schema.Struct<{
823
+ readonly identity: Schema.String;
824
+ readonly select: Schema.optional<Schema.Codec<RelationRequirement, RelationRequirement, never, never>>;
825
+ }>>;
826
+ }>;
827
+ };
828
+ Hydrated: {
829
+ connections: Schema.optional<Schema.Unknown>;
830
+ from: Schema.optional<Schema.String>;
831
+ entities: Schema.Unknown;
832
+ merge: Schema.Union<readonly [Schema.Literal<"replace">, Schema.Literal<"preserve-existing">]>;
833
+ };
834
+ MutationStarted: {
835
+ requestId: Schema.String;
836
+ optimistic: Schema.optional<Schema.$Array<Schema.Unknown>>;
837
+ viewer: Schema.optional<Schema.Struct<{
838
+ readonly entity: Schema.String;
839
+ readonly id: Schema.String;
840
+ }>>;
841
+ write: Schema.optional<Schema.Struct<{
842
+ readonly mutation: Schema.String;
843
+ readonly input: Schema.Unknown;
844
+ readonly keys: Schema.optional<Schema.$Array<Schema.String>>;
845
+ readonly now: Schema.optional<Schema.Number>;
846
+ readonly durable: Schema.optional<Schema.Struct<{
847
+ readonly input: Schema.Unknown;
848
+ readonly shown: Schema.$Array<Schema.Codec<RelationRequirement, RelationRequirement, never, never>>;
849
+ }>>;
850
+ }>>;
851
+ };
852
+ MutationQueued: {
853
+ requestId: Schema.String;
854
+ };
855
+ OutboxRead: {
856
+ key: Schema.String;
857
+ scope: Schema.String;
858
+ session: Schema.optional<Schema.String>;
859
+ entries: Schema.$Array<Schema.Unknown>;
860
+ done: Schema.$Array<Schema.String>;
861
+ unsaved: Schema.optional<Schema.String>;
862
+ };
863
+ OutboxDelayed: {
864
+ requestId: Schema.String;
865
+ attempt: Schema.Number;
866
+ error: Schema.Struct<{
867
+ readonly _tag: Schema.String;
868
+ readonly message: Schema.String;
869
+ readonly refusal: Schema.optional<Schema.Unknown>;
870
+ readonly reason: Schema.optional<Schema.String>;
871
+ }>;
872
+ };
873
+ MutationSucceeded: {
874
+ requestId: Schema.String;
875
+ entities: Schema.$Array<Schema.Struct<{
876
+ readonly entity: Schema.String;
877
+ readonly id: Schema.String;
878
+ readonly values: Schema.$Record<Schema.String, Schema.Unknown>;
879
+ }>>;
880
+ connections: Schema.optional<Schema.$Array<Schema.Unknown>>;
881
+ deleted: Schema.optional<Schema.$Array<Schema.Struct<{
882
+ readonly entity: Schema.String;
883
+ readonly id: Schema.String;
884
+ }>>>;
885
+ read: Schema.optional<Schema.Struct<{
886
+ readonly requests: Schema.$Array<Schema.Codec<Requirement, Requirement, never, never>>;
887
+ readonly result: Schema.Struct<{
888
+ readonly entities: Schema.$Array<Schema.Struct<{
889
+ readonly entity: Schema.String;
890
+ readonly id: Schema.String;
891
+ readonly values: Schema.$Record<Schema.String, Schema.Unknown>;
892
+ }>>;
893
+ readonly settled: Schema.$Array<Schema.Struct<{
894
+ readonly entity: Schema.String;
895
+ readonly id: Schema.String;
896
+ readonly fields: Schema.$Array<Schema.String>;
897
+ }>>;
898
+ }>;
899
+ }>>;
900
+ now: Schema.Number;
901
+ };
902
+ MutationFailed: {
903
+ requestId: Schema.String;
904
+ error: Schema.Struct<{
905
+ readonly _tag: Schema.String;
906
+ readonly message: Schema.String;
907
+ readonly refusal: Schema.optional<Schema.Unknown>;
908
+ readonly reason: Schema.optional<Schema.String>;
909
+ }>;
910
+ operation: Schema.String;
911
+ };
912
+ OverlayShown: {
913
+ id: Schema.String;
914
+ optimistic: Schema.$Array<Schema.Unknown>;
915
+ };
916
+ OverlayLifted: {
917
+ id: Schema.String;
918
+ };
919
+ WindowGrown: {
920
+ window: Schema.String;
921
+ size: Schema.Number;
922
+ };
923
+ LiveReceived: {
924
+ stream: Schema.String;
925
+ event: Schema.Unknown;
926
+ policy: Schema.optional<Schema.Unknown>;
927
+ now: Schema.Number;
928
+ };
929
+ GapCleared: {
930
+ stream: Schema.String;
931
+ };
932
+ ConnectionMerged: {
933
+ connection: Schema.String;
934
+ page: Schema.Unknown;
935
+ refreshes: Schema.optional<Schema.Boolean>;
936
+ select: Schema.optional<Schema.Codec<RelationRequirement, RelationRequirement, never, never>>;
937
+ entities: Schema.optional<Schema.$Array<Schema.Struct<{
938
+ readonly entity: Schema.String;
939
+ readonly id: Schema.String;
940
+ readonly values: Schema.$Record<Schema.String, Schema.Unknown>;
941
+ }>>>;
942
+ settled: Schema.optional<Schema.$Array<Schema.Struct<{
943
+ readonly entity: Schema.String;
944
+ readonly id: Schema.String;
945
+ readonly fields: Schema.$Array<Schema.String>;
946
+ }>>>;
947
+ now: Schema.optional<Schema.Number>;
948
+ };
949
+ ConnectionInvalidated: {
950
+ connection: Schema.String;
951
+ };
952
+ ConnectionRefreshed: {
953
+ connection: Schema.String;
954
+ };
955
+ QueryFailed: {
956
+ connection: Schema.String;
957
+ error: Schema.Struct<{
958
+ readonly _tag: Schema.String;
959
+ readonly message: Schema.String;
960
+ readonly refusal: Schema.optional<Schema.Unknown>;
961
+ readonly reason: Schema.optional<Schema.String>;
962
+ }>;
963
+ };
964
+ Preloaded: {
965
+ messages: Schema.$Array<Schema.suspend<Schema.Codec<RemoteMessage, unknown, never, never>>>;
966
+ };
967
+ CompletedReportDiagnostics: {};
968
+ };
969
+ /** Whether a Message is one of Remote's, by tag. */
970
+ reduces: typeof isRemoteMessage;
971
+ /**
972
+ * Remote's Messages as one Schema, for a wrapper variant in the
973
+ * application's union: `GotRemoteMessage: { message: Remote.Message }`. With
974
+ * a wrapper, `update` matches the application's union exhaustively and
975
+ * `Remote.fold` reduces what arrives inside it.
976
+ */
977
+ Message: import("foldkit/message").MessageUnion<{
978
+ ReadReceived: {
979
+ requests: Schema.$Array<Schema.Codec<Requirement, Requirement, never, never>>;
980
+ result: Schema.Struct<{
981
+ readonly entities: Schema.$Array<Schema.Struct<{
982
+ readonly entity: Schema.String;
983
+ readonly id: Schema.String;
984
+ readonly values: Schema.$Record<Schema.String, Schema.Unknown>;
985
+ }>>;
986
+ readonly settled: Schema.$Array<Schema.Struct<{
987
+ readonly entity: Schema.String;
988
+ readonly id: Schema.String;
989
+ readonly fields: Schema.$Array<Schema.String>;
990
+ }>>;
991
+ }>;
992
+ now: Schema.Number;
993
+ };
994
+ ReadFailed: {
995
+ requests: Schema.$Array<Schema.Codec<Requirement, Requirement, never, never>>;
996
+ error: Schema.Struct<{
997
+ readonly _tag: Schema.String;
998
+ readonly message: Schema.String;
999
+ readonly refusal: Schema.optional<Schema.Unknown>;
1000
+ readonly reason: Schema.optional<Schema.String>;
1001
+ }>;
1002
+ stream: Schema.optional<Schema.String>;
1003
+ };
1004
+ RefreshStarted: {
1005
+ requests: Schema.$Array<Schema.Codec<Requirement, Requirement, never, never>>;
1006
+ };
1007
+ ReadStarted: {
1008
+ requests: Schema.$Array<Schema.Codec<Requirement, Requirement, never, never>>;
1009
+ refresh: Schema.optional<Schema.Number>;
1010
+ };
1011
+ QueryStarted: {
1012
+ connections: Schema.$Array<Schema.String>;
1013
+ };
1014
+ RetentionChanged: {
1015
+ roots: Schema.Struct<{
1016
+ readonly requirements: Schema.$Array<Schema.Codec<Requirement, Requirement, never, never>>;
1017
+ readonly connections: Schema.$Array<Schema.Struct<{
1018
+ readonly identity: Schema.String;
1019
+ readonly select: Schema.optional<Schema.Codec<RelationRequirement, RelationRequirement, never, never>>;
1020
+ }>>;
1021
+ }>;
1022
+ };
1023
+ Hydrated: {
1024
+ connections: Schema.optional<Schema.Unknown>;
1025
+ from: Schema.optional<Schema.String>;
1026
+ entities: Schema.Unknown;
1027
+ merge: Schema.Union<readonly [Schema.Literal<"replace">, Schema.Literal<"preserve-existing">]>;
1028
+ };
1029
+ MutationStarted: {
1030
+ requestId: Schema.String;
1031
+ optimistic: Schema.optional<Schema.$Array<Schema.Unknown>>;
1032
+ viewer: Schema.optional<Schema.Struct<{
1033
+ readonly entity: Schema.String;
1034
+ readonly id: Schema.String;
1035
+ }>>;
1036
+ write: Schema.optional<Schema.Struct<{
1037
+ readonly mutation: Schema.String;
1038
+ readonly input: Schema.Unknown;
1039
+ readonly keys: Schema.optional<Schema.$Array<Schema.String>>;
1040
+ readonly now: Schema.optional<Schema.Number>;
1041
+ readonly durable: Schema.optional<Schema.Struct<{
1042
+ readonly input: Schema.Unknown;
1043
+ readonly shown: Schema.$Array<Schema.Codec<RelationRequirement, RelationRequirement, never, never>>;
1044
+ }>>;
1045
+ }>>;
1046
+ };
1047
+ MutationQueued: {
1048
+ requestId: Schema.String;
1049
+ };
1050
+ OutboxRead: {
1051
+ key: Schema.String;
1052
+ scope: Schema.String;
1053
+ session: Schema.optional<Schema.String>;
1054
+ entries: Schema.$Array<Schema.Unknown>;
1055
+ done: Schema.$Array<Schema.String>;
1056
+ unsaved: Schema.optional<Schema.String>;
1057
+ };
1058
+ OutboxDelayed: {
1059
+ requestId: Schema.String;
1060
+ attempt: Schema.Number;
1061
+ error: Schema.Struct<{
1062
+ readonly _tag: Schema.String;
1063
+ readonly message: Schema.String;
1064
+ readonly refusal: Schema.optional<Schema.Unknown>;
1065
+ readonly reason: Schema.optional<Schema.String>;
1066
+ }>;
1067
+ };
1068
+ MutationSucceeded: {
1069
+ requestId: Schema.String;
1070
+ entities: Schema.$Array<Schema.Struct<{
1071
+ readonly entity: Schema.String;
1072
+ readonly id: Schema.String;
1073
+ readonly values: Schema.$Record<Schema.String, Schema.Unknown>;
1074
+ }>>;
1075
+ connections: Schema.optional<Schema.$Array<Schema.Unknown>>;
1076
+ deleted: Schema.optional<Schema.$Array<Schema.Struct<{
1077
+ readonly entity: Schema.String;
1078
+ readonly id: Schema.String;
1079
+ }>>>;
1080
+ read: Schema.optional<Schema.Struct<{
1081
+ readonly requests: Schema.$Array<Schema.Codec<Requirement, Requirement, never, never>>;
1082
+ readonly result: Schema.Struct<{
1083
+ readonly entities: Schema.$Array<Schema.Struct<{
1084
+ readonly entity: Schema.String;
1085
+ readonly id: Schema.String;
1086
+ readonly values: Schema.$Record<Schema.String, Schema.Unknown>;
1087
+ }>>;
1088
+ readonly settled: Schema.$Array<Schema.Struct<{
1089
+ readonly entity: Schema.String;
1090
+ readonly id: Schema.String;
1091
+ readonly fields: Schema.$Array<Schema.String>;
1092
+ }>>;
1093
+ }>;
1094
+ }>>;
1095
+ now: Schema.Number;
1096
+ };
1097
+ MutationFailed: {
1098
+ requestId: Schema.String;
1099
+ error: Schema.Struct<{
1100
+ readonly _tag: Schema.String;
1101
+ readonly message: Schema.String;
1102
+ readonly refusal: Schema.optional<Schema.Unknown>;
1103
+ readonly reason: Schema.optional<Schema.String>;
1104
+ }>;
1105
+ operation: Schema.String;
1106
+ };
1107
+ OverlayShown: {
1108
+ id: Schema.String;
1109
+ optimistic: Schema.$Array<Schema.Unknown>;
1110
+ };
1111
+ OverlayLifted: {
1112
+ id: Schema.String;
1113
+ };
1114
+ WindowGrown: {
1115
+ window: Schema.String;
1116
+ size: Schema.Number;
1117
+ };
1118
+ LiveReceived: {
1119
+ stream: Schema.String;
1120
+ event: Schema.Unknown;
1121
+ policy: Schema.optional<Schema.Unknown>;
1122
+ now: Schema.Number;
1123
+ };
1124
+ GapCleared: {
1125
+ stream: Schema.String;
1126
+ };
1127
+ ConnectionMerged: {
1128
+ connection: Schema.String;
1129
+ page: Schema.Unknown;
1130
+ refreshes: Schema.optional<Schema.Boolean>;
1131
+ select: Schema.optional<Schema.Codec<RelationRequirement, RelationRequirement, never, never>>;
1132
+ entities: Schema.optional<Schema.$Array<Schema.Struct<{
1133
+ readonly entity: Schema.String;
1134
+ readonly id: Schema.String;
1135
+ readonly values: Schema.$Record<Schema.String, Schema.Unknown>;
1136
+ }>>>;
1137
+ settled: Schema.optional<Schema.$Array<Schema.Struct<{
1138
+ readonly entity: Schema.String;
1139
+ readonly id: Schema.String;
1140
+ readonly fields: Schema.$Array<Schema.String>;
1141
+ }>>>;
1142
+ now: Schema.optional<Schema.Number>;
1143
+ };
1144
+ ConnectionInvalidated: {
1145
+ connection: Schema.String;
1146
+ };
1147
+ ConnectionRefreshed: {
1148
+ connection: Schema.String;
1149
+ };
1150
+ QueryFailed: {
1151
+ connection: Schema.String;
1152
+ error: Schema.Struct<{
1153
+ readonly _tag: Schema.String;
1154
+ readonly message: Schema.String;
1155
+ readonly refusal: Schema.optional<Schema.Unknown>;
1156
+ readonly reason: Schema.optional<Schema.String>;
1157
+ }>;
1158
+ };
1159
+ Preloaded: {
1160
+ messages: Schema.$Array<Schema.suspend<Schema.Codec<RemoteMessage, unknown, never, never>>>;
1161
+ };
1162
+ CompletedReportDiagnostics: {};
1163
+ }>;
1164
+ /**
1165
+ * A bound domain under one wrapper variant of the application's union, the
1166
+ * same shape Foldkit gives a Submodel: `toParentMessage` wraps Remote's
1167
+ * Messages, the fold reduces them, and its `fetch`, `mutate`, and
1168
+ * `subscriptions` yield the wrapper. Spreading `Remote.messages` and
1169
+ * narrowing with `Remote.reduces` remains the shorter path for an
1170
+ * application whose `update` only reduces.
1171
+ *
1172
+ * @example
1173
+ * ```ts
1174
+ * const Message = defineMessageUnion({ GotRemoteMessage: { message: Remote.Message } })
1175
+ * const foldData = Remote.fold(Data, message => Message.GotRemoteMessage({ message }))
1176
+ *
1177
+ * const update = (model: Model, message: Message): Return =>
1178
+ * Message.match(message, {
1179
+ * GotRemoteMessage: ({ message }) => foldData(model, message),
1180
+ * })
1181
+ * const subscriptions = Subscription.make<Model, Message, RemoteClient>()(() =>
1182
+ * foldData.subscriptions({ page: Surface.at(ProjectPage, …) }),
1183
+ * )
1184
+ * ```
1185
+ */
1186
+ fold: <Domain extends RemoteDomain<any, any, any, any, any>, ParentMessage>(domain: Domain, toParentMessage: (message: RemoteMessage) => ParentMessage) => RemoteFold<ModelOfDomain<Domain>, ParentMessage, Domain>;
1187
+ /**
1188
+ * A patch of one entity's values, for a mutation's `optimistic` list or an
1189
+ * overlay. Takes a `foldkit-entity` Entity or a Remote descriptor alike, so
1190
+ * the domain you declared once is the one you patch:
1191
+ * `Remote.patch(Project, 'p1', { name: 'Apollo II' })`. Values are the
1192
+ * fields' wire shape, as the server writes them, except a relation, which is
1193
+ * a ref (`owner: Remote.ref(User, 'u1')`), an array of refs, or `null` where
1194
+ * it is optional. A ref key typed by hand, or a ref to another Entity, is
1195
+ * refused, in the type and when the patch is made.
1196
+ */
1197
+ patch: <E extends EntityLike>(entity: E, id: string, values: PatchValues<FieldsOf<E>>) => EntityPatch<NameOf<E>, FieldsOf<E>>;
1198
+ /**
1199
+ * A deletion of one entity, for a mutation's `optimistic` list or an
1200
+ * overlay: `Remote.tombstone(Post, 'p1')`. Until it settles the row reads
1201
+ * `NotFound` and leaves every list and relation, as an answer's `deleted`
1202
+ * does; a failure brings it back. Keeping it gone is the answer's to say.
1203
+ */
1204
+ tombstone: <E extends EntityLike>(entity: E, id: string) => PendingDelete;
1205
+ /**
1206
+ * A reference to one entity, for `ConnectionChange` and anything else that
1207
+ * names a row: `Remote.ref(Project, 'p3')`. Either kind of entity, as with
1208
+ * `Remote.patch`.
1209
+ */
1210
+ ref: <E extends EntityLike>(entity: E, id: string) => EntityRef<NameOf<E>, FieldsOf<E>>;
1211
+ /**
1212
+ * Declares a Remote domain and binds it to its place in the application Model
1213
+ * in one step; the result carries the application-facing operations. The
1214
+ * descriptor alone is `Remote.define`, the binding alone `Remote.at`.
1215
+ */
1216
+ make: <AppModel, Store extends RemoteModel, const Entities extends readonly EntityLike[], const Queries extends readonly QueryDescriptor<any, any, any>[] = readonly [], const Mutations extends readonly MutationDescriptor<any, any, any>[] = readonly []>(config: {
1217
+ readonly model: ModelRef<AppModel, Store>;
1218
+ readonly entities: Entities;
1219
+ readonly queries?: Queries;
1220
+ readonly mutations?: Mutations;
1221
+ /**
1222
+ * Checks each prediction against the server's answer, and records a
1223
+ * `PredictionMismatch` in `diagnostics` for each part that disagrees:
1224
+ * `Value`, a field a pending write showed that the answer holds otherwise;
1225
+ * `Placement`, a list placed in an order the server's first page does not
1226
+ * keep (each placed list is fetched too, for its page; a pending edit is
1227
+ * not checked, since the server does not have it yet); `Gap`, a row whose
1228
+ * answer left out fields the client showed while it was pending and the
1229
+ * store does not otherwise hold, so they are read again and the row reads
1230
+ * `Loading` meanwhile. Everything else behaves as without it. For
1231
+ * development and tests.
1232
+ */
1233
+ readonly verifyPredictions?: boolean | undefined;
1234
+ /**
1235
+ * How the client runs a body's primitive operators when it judges rows it
1236
+ * holds (`Operators`): the kernel's when not given. A body calling one this
1237
+ * table lacks is judged by the server instead, as any row the client cannot
1238
+ * judge is.
1239
+ */
1240
+ readonly operators?: MemoryOperators | undefined;
1241
+ /**
1242
+ * Who reads, as a row (`Remote.ref(User, model.me)`), or none for a
1243
+ * visitor: whom a declared write predicts each `Derived.exists` for. The
1244
+ * store holds one viewer's values, as it holds one principal's: a change
1245
+ * of viewer is a change of principal, which `Data.forget`s. Without it, an
1246
+ * exists is predicted only where a write takes it away.
1247
+ */
1248
+ readonly viewer?: ((model: AppModel) => Option.Option<{
1249
+ readonly entity: string;
1250
+ readonly id: string;
1251
+ }>) | undefined;
1252
+ }) => RemoteDomain<AppModel, Store, Entities, Queries, Mutations>;
1253
+ /**
1254
+ * Declares a Remote domain without binding it: its entities, queries, and
1255
+ * mutations, plus the submodel. For a domain reused across applications or
1256
+ * bound in a test; `Remote.make` is the one-step form.
1257
+ */
1258
+ define: typeof defineRemote;
1259
+ /**
1260
+ * Binds a Remote domain to its store's location in the application Model. The
1261
+ * registered entity names are carried on the returned value, so `Remote.select`
1262
+ * rejects a selection for an entity this domain never declared. `operators`
1263
+ * is the client's table, which a pending computed assignment is predicted by
1264
+ * (`Operators.kernel` when not given), as `Remote.make`'s is.
1265
+ */
1266
+ at: <AppModel, Store extends RemoteModel, Entities extends readonly EntityLike[], Queries extends readonly QueryDescriptor<any, any, any>[], Mutations extends readonly MutationDescriptor<any, any, any>[]>(definition: RemoteDescriptor<Entities, Queries, Mutations>, store: ModelRef<AppModel, Store>, options?: {
1267
+ readonly operators?: MemoryOperators | undefined;
1268
+ }) => BoundRemote<AppModel, Store, EntityName<Entities[number]>>;
1269
+ /**
1270
+ * The resume part for this domain, for `foldkit-ssr`'s `SSR.plan({ parts })`:
1271
+ * a server render sends what the plan's active Surfaces read from the store,
1272
+ * each connection with its boundaries and each live cursor with it, and
1273
+ * nothing else. `id` tells two domains in one application apart.
1274
+ */
1275
+ resume: typeof resumePart;
1276
+ /**
1277
+ * A Projection node that reads a `RemoteData` value out of the store. The id
1278
+ * is supplied by the caller, usually from a Surface's params. The assembled
1279
+ * value is decoded against the Selection, so malformed server data surfaces
1280
+ * as `Failed` instead of being asserted into `Value`. A present value with a
1281
+ * stale field reads as `Refreshing`: an observer is refetching it.
1282
+ */
1283
+ select: <AppModel, Store extends RemoteModel, Names extends string, Value, Name extends string>(bound: BoundRemote<AppModel, Store, Names>, given: EntitySelection<Value, Name> & Registered<Name, Names, 'Entity'>) => (id: string) => Projection<AppModel, RemoteData<Value>>;
1284
+ /**
1285
+ * When what a projection shows was last received, and whether it is stale
1286
+ * or loading. Pure, so a view can show "updated 5s ago" without I/O.
1287
+ *
1288
+ * `updatedAt` is the newest server write among what is shown, as the
1289
+ * store dates it; `undefined` when nothing shown was received (nothing
1290
+ * loaded, or only an optimistic preview). `stale` is any shown field or
1291
+ * connection marked stale; `loading` is any of them in flight. Optimistic
1292
+ * previews do not date: showing only one reads `updatedAt: undefined`.
1293
+ */
1294
+ meta: <AppModel, Store extends RemoteModel, Value>(bound: BoundRemote<AppModel, Store>, model: AppModel, projection: Projection<AppModel, Value>) => ReadMeta;
1295
+ /**
1296
+ * The pure plan for a projection against a Model: the requirements its
1297
+ * remote store does not satisfy, under `options` (freshness, force). A
1298
+ * Surface's projection is `surface.projection(params)`.
1299
+ */
1300
+ plan: <AppModel, Store extends RemoteModel, Value>(bound: BoundRemote<AppModel, Store>, model: AppModel, projection: Projection<AppModel, Value>, options?: PlanOptions) => ReadonlyArray<Requirement>;
1301
+ /**
1302
+ * The queries a projection needs run before its connections read: those the
1303
+ * Model does not hold, or holds stale (every one under `force`).
1304
+ */
1305
+ planQueries: <AppModel, Store extends RemoteModel, Value>(bound: BoundRemote<AppModel, Store>, model: AppModel, projection: Projection<AppModel, Value>, options?: PlanOptions) => ReadonlyArray<QueryRef<string, unknown>>;
1306
+ /**
1307
+ * The store reads see: the base store under the pending optimistic layers.
1308
+ * One store is shared by every read and plan of a Model whose remote state
1309
+ * has not changed.
1310
+ */
1311
+ storeOf: <AppModel, Store extends RemoteModel>(bound: BoundRemote<AppModel, Store>, model: AppModel) => EntityStore;
1312
+ /**
1313
+ * The projection read against the server-derived store alone: the same
1314
+ * requirements, planned the same way, with the pending optimistic layers and
1315
+ * connection overlays left off. See the bound `Remote.confirmed`.
1316
+ */
1317
+ confirmed: <AppModel, Store extends RemoteModel, P extends Projection<AppModel, any>>(bound: BoundRemote<AppModel, Store>, projection: P) => P;
1318
+ /**
1319
+ * Executes the plan against the `RemoteClient` and returns a new store. Used
1320
+ * for SSR route prefetch, hover prefetch, and tests. Never called during render.
1321
+ * `policy` decides what a present field means (default cache-first); `now`
1322
+ * is the clock it reads, so the planner itself stays pure and time-injected.
1323
+ */
1324
+ prefetch: <AppModel, Store extends RemoteModel, Value>(bound: BoundRemote<AppModel, Store, string>, model: AppModel, projection: Projection<AppModel, Value>, options?: ObserveOptions | undefined) => Effect.Effect<Readonly<Record<string, EntityEntry>>, RemoteProtocolError | RemoteReadError | RemoteUnauthenticated, RemoteClient>;
1325
+ /**
1326
+ * Marks what a read requires as due again: a projection, a Surface without
1327
+ * params, one entry of the active record, or the whole record, each entry
1328
+ * resolved for this Model as `subscriptions` resolves it. Called from
1329
+ * `update`: every selected field the store holds reads `Refreshing`, and
1330
+ * every loaded query connection is invalidated. Nothing is fetched here.
1331
+ * The read entries `Data.subscriptions` derives refetch it, because a stale
1332
+ * field or connection is planned again under every policy, so a refresh never
1333
+ * sends a request beside the entry already observing the same data.
1334
+ *
1335
+ * A refreshed connection's page replaces its pages, so items the server removed
1336
+ * or reordered follow it; pages loaded past the first are dropped and paged
1337
+ * again with `next`/`previous`. The read entries restart, so a read or query
1338
+ * sent before the refresh is not applied after it.
1339
+ *
1340
+ * It is also how a failed read is retried: nothing that failed is asked
1341
+ * again on its own, so its read stays `Failed` until this asks. A failed
1342
+ * read with nothing to show reads `Loading` from here, and `Failed` again if
1343
+ * the retry fails. `{ failed: true }` asks again only what failed, which is
1344
+ * what a "Try again" means: what loaded keeps its value and its pages.
1345
+ *
1346
+ * The projection must be observed, which it is while it is on screen. Live
1347
+ * subscriptions are left as they are. For data nothing observes (SSR, tests),
1348
+ * use `Remote.prefetch` with `RemotePolicy.networkOnly`. Refreshing what is
1349
+ * already being refreshed returns the same Model.
1350
+ */
1351
+ refresh: <AppModel, Store extends RemoteModel>(bound: BoundRemote<AppModel, Store>, model: AppModel, target: RefreshTarget<AppModel>, options?: RefreshOptions) => AppModel;
1352
+ /**
1353
+ * Forgets everything the server told this Model: values, tombstones,
1354
+ * unavailable fields, connections, live cursors, failures. What is known is
1355
+ * known for a principal, and this is the one boundary for a login, a logout
1356
+ * or a switch of organization: called from `update`, it performs no I/O, and
1357
+ * every active Surface's read and live entries restart, so the screen asks
1358
+ * again as whoever the client now is. A read or stream begun before is
1359
+ * interrupted rather than landing after. A mutation in flight is treated as
1360
+ * applied: its answer writes nothing here.
1361
+ */
1362
+ forget: <AppModel, Store extends RemoteModel>(bound: BoundRemote<AppModel, Store>, model: AppModel) => AppModel;
1363
+ /**
1364
+ * Writes a read result into the store, recording each field's applied window.
1365
+ * `requests` are the planned requirements the result answers.
1366
+ */
1367
+ writeRead: typeof writeRead;
1368
+ /**
1369
+ * Adapts an Effect RPC client for `RemoteRpc` to `RemoteClient`, so an
1370
+ * application provides the transport's RPC layer instead of writing the
1371
+ * `LiveChange`-to-`LiveEvent` mapping by hand. The client `RpcClient.make`
1372
+ * builds is accepted as it is: when its transport fails (`RpcClientError`),
1373
+ * the call fails with its own Remote error, which the application shows and
1374
+ * retries like any failed read, query, mutation or live stream.
1375
+ */
1376
+ /**
1377
+ * Remote's client over any way of sending one JSON request and receiving its
1378
+ * answer, for `clientLayer`: a worker, a server in the page. `RemoteServer.answer`
1379
+ * is the other end.
1380
+ */
1381
+ json: typeof json;
1382
+ /**
1383
+ * Remote's client over HTTP, for `clientLayer`: each call a `POST` of the JSON
1384
+ * request to `url`. `headers` is read per request (a session token, say).
1385
+ */
1386
+ http: typeof http;
1387
+ /**
1388
+ * Remote's client over HTTP with live, for `clientLayer`: reads, queries,
1389
+ * and mutations as `http` sends them, live requirements as one `POST`
1390
+ * answered with a `text/event-stream` of changes.
1391
+ * `foldkit-remote-server/fetch` is the other end.
1392
+ */
1393
+ httpWithLive: typeof httpWithLive;
1394
+ clientLayer: <R = never>(client: RemoteRpcClient<R, RpcClientError.RpcClientError | RemoteUnreachable>, options?: CoalesceOptions) => Layer.Layer<RemoteClient, never, R>;
1395
+ /**
1396
+ * Wraps a `RemoteClient` layer so its reads coalesce: requirements issued
1397
+ * together become one batch, and a requirement already in flight is joined.
1398
+ * `Remote.clientLayer` applies this; use it on a hand-written client.
1399
+ */
1400
+ coalesced: typeof coalescedLayer;
1401
+ /**
1402
+ * A Foldkit Subscription entry that keeps the cache to what the active
1403
+ * Surfaces reach. `projections` are the ones the application observes (the
1404
+ * same it passes to `Remote.observe`), `connections` the query connections
1405
+ * it shows; anything else is collected once the roots have been stable for
1406
+ * `grace`, so a route transition that comes straight back does not thrash.
1407
+ */
1408
+ retain: <AppModel, Message = RemoteMessage>(projections: ReadonlyArray<Projection<AppModel, unknown>>, toMessage?: (message: RemoteMessage) => Message, options?: RetainOptions) => EntryWithoutKeepAlive<AppModel, Message, RetentionRoots, never>;
1409
+ /**
1410
+ * Runs a `Query` through `RemoteClient`, encoding its input from the ref.
1411
+ * Pair the result with `Remote.queryMessage` to merge the page into the Model.
1412
+ * With `select`, the server also returns the selected fields of the page's
1413
+ * items, so one response populates both the connection and the store.
1414
+ */
1415
+ query: <Name extends string, Input>(ref: QueryRef<Name, Input>, select?: RelationRequirement | undefined) => Effect.Effect<{
1416
+ readonly edges: readonly {
1417
+ readonly entity: string;
1418
+ readonly id: string;
1419
+ readonly key: string;
1420
+ }[];
1421
+ readonly start: {
1422
+ readonly _tag: "Terminal";
1423
+ } | {
1424
+ readonly _tag: "Cursor";
1425
+ readonly cursor: string;
1426
+ } | {
1427
+ readonly _tag: "Unknown";
1428
+ };
1429
+ readonly end: {
1430
+ readonly _tag: "Terminal";
1431
+ } | {
1432
+ readonly _tag: "Cursor";
1433
+ readonly cursor: string;
1434
+ } | {
1435
+ readonly _tag: "Unknown";
1436
+ };
1437
+ readonly entities?: readonly {
1438
+ readonly entity: string;
1439
+ readonly id: string;
1440
+ readonly values: {
1441
+ readonly [x: string]: unknown;
1442
+ };
1443
+ }[] | undefined;
1444
+ readonly settled?: readonly {
1445
+ readonly entity: string;
1446
+ readonly id: string;
1447
+ readonly fields: readonly string[];
1448
+ }[] | undefined;
1449
+ }, RemoteQueryError | RemoteUnauthenticated, RemoteClient>;
1450
+ /** The `RemoteMessage` that merges a query page into its connection. */
1451
+ queryMessage: <Name extends string, Input>(ref: QueryRef<Name, Input>, result: Schema.Schema.Type<typeof QueryResult>, select?: RelationRequirement | undefined, now?: number | undefined) => RemoteMessage;
1452
+ /** A pure, serializable view of the whole cache. */
1453
+ inspect: typeof inspectRemote;
1454
+ /** A pure, serializable view of one entity, or `undefined` if unknown. */
1455
+ inspectEntity: typeof inspectEntity;
1456
+ /**
1457
+ * Runs a mutation through `RemoteClient`, decoding its typed Output and
1458
+ * returning the result's normalized patches so the caller can reconcile them
1459
+ * through `updateRemote`'s `MutationSucceeded` (or `Remote.mutateInto`).
1460
+ */
1461
+ mutate: <Name extends string, Input, Output>(mutation: MutationDescriptor<Name, Input, Output, unknown>, input: Input, requestId: string, options?: {
1462
+ readonly keys?: ReadonlyArray<string> | undefined;
1463
+ readonly operation?: string | undefined;
1464
+ readonly shown?: ReadonlyArray<RelationRequirement> | undefined;
1465
+ readonly now?: number | undefined;
1466
+ } | undefined) => Effect.Effect<{
1467
+ output: Output;
1468
+ entities: readonly {
1469
+ readonly entity: string;
1470
+ readonly id: string;
1471
+ readonly values: {
1472
+ readonly [x: string]: unknown;
1473
+ };
1474
+ }[];
1475
+ connections: ConnectionChange[];
1476
+ deleted: readonly {
1477
+ readonly entity: string;
1478
+ readonly id: string;
1479
+ }[];
1480
+ read: {
1481
+ readonly requests: readonly Requirement[];
1482
+ readonly result: {
1483
+ readonly entities: readonly {
1484
+ readonly entity: string;
1485
+ readonly id: string;
1486
+ readonly values: {
1487
+ readonly [x: string]: unknown;
1488
+ };
1489
+ }[];
1490
+ readonly settled: readonly {
1491
+ readonly entity: string;
1492
+ readonly id: string;
1493
+ readonly fields: readonly string[];
1494
+ }[];
1495
+ };
1496
+ } | undefined;
1497
+ }, RemoteForbidden | RemoteMutationError | RemoteUnauthenticated | RemoteUnreachable, RemoteClient>;
1498
+ /**
1499
+ * Reads the clock where the reader acts, for `Data.mutate`'s `now`: a
1500
+ * Command that yields `toMessage(now)`, the time in milliseconds since the
1501
+ * epoch. It reads Effect's `Clock`, so a test pins it, and `Trace.run`
1502
+ * runs it at the trace's time. Chirp's compose box answers a submit with
1503
+ * `Remote.now(now => Message.ClockedPost({ post, now }))`, and
1504
+ * `ClockedPost` starts the write.
1505
+ */
1506
+ now: <M>(toMessage: (now: number) => M) => {
1507
+ readonly name: 'Remote.now';
1508
+ readonly effect: Effect.Effect<M>;
1509
+ };
1510
+ /**
1511
+ * Runs a mutation and reconciles its patches into a `RemoteModel` in one step,
1512
+ * returning the new model alongside the typed Output. The model-level form of
1513
+ * `MutationStarted` → `RemoteClient.mutate` → `MutationSucceeded`; in an
1514
+ * application the three are `update` (with `optimistic`), a Command, and the
1515
+ * Message the Command returns, so the optimistic operations show meanwhile.
1516
+ */
1517
+ mutateInto: <Name extends string, Input, Output, AppModel, Store extends RemoteModel>(bound: BoundRemote<AppModel, Store, string>, model: AppModel, mutation: MutationDescriptor<Name, Input, Output, unknown>, input: Input, requestId: string, options?: MutateOptions | undefined) => Effect.Effect<{
1518
+ output: Output;
1519
+ model: AppModel;
1520
+ }, RemoteForbidden | RemoteMutationError | RemoteUnauthenticated | RemoteUnreachable, RemoteClient>;
1521
+ /**
1522
+ * A Foldkit Subscription entry that plans a Surface's missing fields from the
1523
+ * Model and fetches them through `RemoteClient`, emitting a `RemoteMessage`
1524
+ * per outcome. Wrap it in an application Message (`toMessage`) and reduce it
1525
+ * with the domain's `update`. Under a refreshing `policy` the entry first
1526
+ * emits `RefreshStarted`, so the fields being refetched read as `Refreshing`
1527
+ * while the request is pending.
1528
+ */
1529
+ observe: <AppModel, Store extends RemoteModel, Names extends string, Model, SurfaceMessage, Params, Message = RemoteMessage>(bound: BoundRemote<AppModel, Store, Names>, surface: Surface<AppModel, Model, SurfaceMessage, Params>, params: Params, toMessage?: (message: RemoteMessage) => Message, options?: ObserveOptions) => EntryWithoutKeepAlive<AppModel, Message, ReadDependencies, RemoteClient>;
1530
+ /**
1531
+ * A Foldkit Subscription entry that consumes the live stream for a Surface's
1532
+ * requirements, emitting a `LiveReceived` per event and a `ReadFailed`
1533
+ * carrying its `stream` when the stream breaks (including
1534
+ * `ResumeUnavailable`). That records a gap on the stream rather than a failed
1535
+ * read, since nothing was being read, and restarts the entry after a
1536
+ * backoff; the restart refetches what it covers. The resume cursor is read
1537
+ * from `RemoteModel.live`, so the application tracks no cursor of its own.
1538
+ */
1539
+ live: <AppModel, Store extends RemoteModel, Names extends string, Model, SurfaceMessage, Params, Message = RemoteMessage>(bound: BoundRemote<AppModel, Store, Names>, surface: Surface<AppModel, Model, SurfaceMessage, Params>, params: Params, toMessage?: (message: RemoteMessage) => Message, options?: LiveOptions) => EntryWithoutKeepAlive<AppModel, Message, LiveDependencies, RemoteClient>;
1540
+ };
1541
+ export { AnswerRead, AnySchema, BatchRead, Belongs, Boundary, BoundaryCounts, CoalesceOptions, Connection, ConnectionApplied, ConnectionChange, ConnectionChangeSchema, ConnectionIdentity, ConnectionOverlay, ConnectionRequirement, ConnectionRoot, ConnectionSpec, Cursor, Deadline, Denied, DerivedBy, type Diagnostic, Diagnostics, Edge, EdgeRef, Entity, EntityApplied, EntityDescriptor, EntityEntry, EntityKey, EntityLayer, EntityPatch, EntityRef, EntityStore, EntityWrite, ExplainedDependencies, Failures, FieldsFrom, Freshness, IDENTITY_SEPARATOR, Judged, Live, LiveChange, LiveCursor, LiveEdge, LiveEvent, type LiveFetchOptions, LiveInsertion, LiveOutcome, LivePolicy, type LiveRefused, LiveRequirement, LiveState, MAX_FIELDS_PER_REQUEST, MAX_LIVE_QUERIES, MAX_RELATION_DEPTH, MAX_SHOWN_ENTITIES, Matched, MatchingOptions, MergePolicy, Mutate, Mutation, MutationAnswer, MutationDescriptor, MutationRequest, MutationResult, MutationState, MutationStatus, NormalizedEntity, NormalizedPatch, OperationId, OptimisticOperation, OptimisticState, type OutboxItem, OutboxItemState, type OutboxStatus, type OutboxUnreadable, type OutboxUnsaved, Page, PageSize, PatchValues, PendingDelete, PendingPatch, PlacedOrder, PlanFreshness, PlanOptions, type PredictionMismatch, PredictionPart, Query, QueryDescriptor, QueryEdge, QueryExplanation, QueryInputs, QueryRef, QueryRequest, QueryResult, QueryRpc, QueryRun, QueryWindow, RELATION_ALIAS, REMOTE_CACHE_VERSION, REMOTE_PROTOCOL_VERSION, Read, ReadBatch, ReadBatchResult, ReadRequest, type ReadStep, ReadWhy, Reconciled, RefKey, RefPage, RefPageValue, RefParts, RefreshState, Refusal, RefusalOfWrite, RelationAnnotation, RelationEntityAnnotation, RelationKind, RelationRequest, RelationRequirement, RelationShape, RemoteClient, RemoteConnections, RemoteData, type RemoteDiagnostic, RemoteError, RemoteForbidden, RemoteInspection, RemoteJsonAnswer, RemoteJsonClient, RemoteJsonRequest, type RemoteJsonSend, RemoteLiveError, RemoteLiveRefused, RemoteMessage, RemoteMessageInput, RemoteMessageTag, RemoteModel, RemoteMutationError, RemotePersistence, RemotePolicy, RemoteProtocolError, RemoteQueryError, RemoteReadError, RemoteRequirements, type RemoteResumePart, RemoteRpc, RemoteRpcClient, RemoteUnauthenticated, RemoteUnreachable, type ReportDiagnostic, Requirement, ResultOf, Retained, RetentionRoots, type RetryOptions, RowPlace, SchemaOrFields, Segment, Selection, SelectionOf, SelectionValue, SelectionValueOf, SettledFields, ShownBy, ShownSlice, Snapshot, SnapshotOptions, StartedWrite, StreamHealth, TypeOf, Why, WhyTerm, WindowSchema, WireBoundary, type WriteUnheard, addLayer, addOverlay, aliasedField, applyConnectionEvent, applyEntityEvent, askAgain, assemble, beginMutation, beginOptimistic, belongsEncoded, brokenByWrite, classifyLive, clearStale, coalesceQueries, coalesceReads, coalescedLayer, connectionChangeOf, connectionIdentity, connectionsOf, cursor, deadlineOf, departedLimit, derivedOfWrite, dismissQueued, edge, emptyConnection, emptyLiveState, emptyMutationState, emptyOptimistic, emptyRefresh, emptyStore, entityKey, entry, failMutation, failureOf, fieldMark, forbiddenByWrite, forgetFailure, forgetRemote, gc, goneIn, hasField, hasNext, hasPrevious, heldOnlyByRequests, httpWithLive, initialRemoteModel, inspectEntity, inspectRemote, invalidateConnections, isFieldFailed, isFieldStale, isFieldUnavailable, isGapped, isLoading, isLoadingThrough, isQueryLoading, isRefPage, isRemoteMessage, isTombstone, items, liveEventOf, liveFetch, liveHasNext, liveHasPrevious, markStale, matching, merge, mintOperation, missingFields, mutateRemote, mutationStatus, noFailures, onlyOverlaid, optimisticOfWrite, overlaysOf, pageSchema, patchOfWrite, placeIn, plan, plannedStore, predictionOfWrite, pruneOverlays, queryIdentity, reachable, readField, recentRoots, reconcileMutation, refParts, refreshIsInFlight, refreshedAt, refsIn, relationAlias, relationOf, relationShape, remoteDataSchema, remoteError, remoteErrorSchema, remoteMessageCases, remoteMessageSchema, remoteModelSchema, remove, removeLayer, removeOverlay, requirementKey, requirementsOf, resolvedPatches, retentionRootsSchema, schemaOf, segment, setStale, setUnavailable, settleFailure, settleSuccess, settledLater, stableStringify, targetsOf, terminal, tombstone, unavailableOf, unknown, updateRemote, visibleItems, visibleStore, windowGrowthKey, windowKey, withRefreshRequested, writeEntities, writeEntity, writeRead };
1542
+ //# sourceMappingURL=index.d.ts.map