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,133 @@
1
+ import { r as RemoteData } from "./remoteData-mK1suYi1.js";
2
+ import { E as MutationDescriptor } from "./optimistic-CECsfNGY.js";
3
+ import { c as QueryRef } from "./query-BuIU93xA.js";
4
+ import { A as RemoteMutationError, D as RemoteForbidden, F as RemoteUnauthenticated, I as RemoteUnreachable, M as RemoteQueryError, N as RemoteReadError, j as RemoteProtocolError } from "./wire-DthPcTM6.js";
5
+ import { t as RemoteClient } from "./client-B055kQuP.js";
6
+ import { n as ReadStep, r as ReadWhy } from "./why-kgp_Wr3z.js";
7
+ import { i as RemoteMessage } from "./model-B6zk1NMB.js";
8
+ import { EntityLike, OutboxWiring, RemoteDomain, SubscriptionsOptions } from "./index.js";
9
+ import { Law, LawConfig, LawPart, LawReport } from "./law.js";
10
+ import { Option } from "effect";
11
+ import { ActiveSurface, Projection, SurfaceSource } from "foldkit-surface";
12
+ import * as Update from "foldkit/update";
13
+ type Tag = RemoteData<unknown>['_tag'];
14
+ type Client = RemoteClient['Service'];
15
+ /** A step that lets held requests go on: from `Respond`, never built by hand. */
16
+ declare class Release {
17
+ readonly label: string;
18
+ /** None for `Respond.all`, which lets every held request go on. */
19
+ readonly key: Option.Option<string>;
20
+ readonly fail: Option.Option<unknown>;
21
+ constructor(label: string,
22
+ /** None for `Respond.all`, which lets every held request go on. */
23
+ key: Option.Option<string>, fail: Option.Option<unknown>);
24
+ }
25
+ /** A step of a trace that answers held requests. */
26
+ export type Respond = Release;
27
+ /** The steps that answer what the application asked, each in the order the test puts it. */
28
+ export declare const Respond: {
29
+ /**
30
+ * Answers the oldest held query of `ref`'s connection (any window of it)
31
+ * with what `client` returns for it, or fails it with `fail`.
32
+ */
33
+ query: (ref: QueryRef<string, unknown>, options?: {
34
+ readonly fail?: RemoteQueryError | RemoteUnauthenticated;
35
+ }) => Respond;
36
+ /**
37
+ * Answers the oldest held read batch that asks for this row. A batch is
38
+ * answered whole, other rows included, as the server answers it.
39
+ */
40
+ read: (entity: EntityLike, id: string, options?: {
41
+ readonly fail?: RemoteReadError | RemoteProtocolError | RemoteUnauthenticated;
42
+ }) => Respond;
43
+ /** Answers the oldest held request of this mutation. */
44
+ mutation: (mutation: MutationDescriptor<string, any, any>, options?: {
45
+ readonly fail?: RemoteMutationError | RemoteForbidden | RemoteUnauthenticated | RemoteUnreachable;
46
+ }) => Respond;
47
+ /**
48
+ * Answers every held request, then every request those answers lead to,
49
+ * until none is held: none at all, when nothing is.
50
+ */
51
+ all: Release;
52
+ };
53
+ /** One Message the application handled, and the Model it left. */
54
+ export interface TraceEntry<AppModel, Message> {
55
+ /** The step it followed: 0 while the Subscriptions start, 1 for the first step. */
56
+ readonly step: number;
57
+ readonly message: Message;
58
+ readonly model: AppModel;
59
+ /** The Commands its `update` returned that the trace did not run: every one but Remote's. */
60
+ readonly skipped: ReadonlyArray<string>;
61
+ }
62
+ /** What `Trace.run` recorded. */
63
+ export interface Trace<AppModel, Message> {
64
+ readonly start: AppModel;
65
+ /** Every Message in the order `update` handled it, with the Model after it. */
66
+ readonly entries: ReadonlyArray<TraceEntry<AppModel, Message>>;
67
+ /** The requests still held when the steps ran out. */
68
+ readonly pending: ReadonlyArray<string>;
69
+ /** `Data.why` of a read at a Model, given the trace's active record. */
70
+ readonly why: (model: AppModel, read: Projection<AppModel, RemoteData<unknown>>) => ReadWhy;
71
+ /** `Data.timeline` over the trace, given its active record. */
72
+ readonly timeline: (reads: Readonly<Record<string, Projection<AppModel, RemoteData<unknown>>>>) => ReadonlyArray<ReadStep<Message>>;
73
+ }
74
+ /** A read that showed a value, and then did not, though nothing removed the value. */
75
+ export interface Regression<Message> {
76
+ /** The read's name, as `regressions` was given it. */
77
+ readonly read: string;
78
+ readonly step: number;
79
+ /** The Message after which it no longer showed its value. */
80
+ readonly message: Message;
81
+ readonly from: Tag;
82
+ readonly to: Tag;
83
+ /** `Data.why`, for the Model it regressed in. */
84
+ readonly why: ReadWhy;
85
+ }
86
+ export interface TraceConfig<AppModel, Message> {
87
+ /** The Model the trace starts from; its Subscriptions start at it. */
88
+ readonly start: AppModel;
89
+ /**
90
+ * The application's `update`. Remote's Subscriptions send it Remote's
91
+ * Messages, so its union must hold them. Its Commands other than Remote's are
92
+ * not run.
93
+ */
94
+ readonly update: ((model: AppModel, message: Message) => Update.Return<AppModel, Message, unknown>) & ((model: AppModel, message: RemoteMessage) => unknown);
95
+ /** The active record, as `Data.subscriptions` and `Data.why` take it. */
96
+ readonly active: Readonly<Record<string, ActiveSurface<AppModel> | SurfaceSource<AppModel>>>;
97
+ /** As `Data.subscriptions` takes them; the trace's clock stands still, so it sets `now`. */
98
+ readonly options?: Omit<SubscriptionsOptions, 'now'>;
99
+ /**
100
+ * The time the trace's clock stands at, in milliseconds since the epoch:
101
+ * what every Command and Subscription it runs reads (`Remote.now`, an
102
+ * answer's date), and what the answers it asks for are given. Default 0.
103
+ */
104
+ readonly now?: number;
105
+ /** What answers each request once a step lets it go on: a fake, or a server's in-process client. */
106
+ readonly client: Client;
107
+ /**
108
+ * The application's `Data.outbox`, when it makes durable writes: the trace
109
+ * starts from its `restore` over an empty store of its own, and runs its
110
+ * Subscriptions as one tab does (without Web Locks, and with no other tab
111
+ * to hear), so a durable write is stored and sent by it.
112
+ */
113
+ readonly outbox?: OutboxWiring<AppModel>;
114
+ readonly steps: ReadonlyArray<NoInfer<Message> | Respond>;
115
+ }
116
+ declare const run: <AppModel, Message>(Data: RemoteDomain<AppModel, any, any, any, any>, config: TraceConfig<AppModel, Message>) => Promise<Trace<AppModel, Message>>;
117
+ export declare const Trace: {
118
+ run: typeof run;
119
+ /**
120
+ * What the read showed across the trace, the start first: each change of
121
+ * tag, so a one-Message blink reads `['Ready', 'Loading', 'Ready']`.
122
+ */
123
+ tags: <AppModel>(trace: Trace<AppModel, unknown>, read: Projection<AppModel, RemoteData<unknown>>) => ReadonlyArray<Tag>;
124
+ /**
125
+ * Every time a read that showed a value (`Ready`, `Refreshing`) stopped
126
+ * showing it without a reason a reader can see: it read `Loading` or
127
+ * `Initial`, or `Failed` without the value (#234). `NotFound` is a reason:
128
+ * the server said the row is gone.
129
+ */
130
+ regressions: <AppModel, Message>(trace: Trace<AppModel, Message>, reads: Readonly<Record<string, Projection<AppModel, RemoteData<unknown>>>>) => ReadonlyArray<Regression<Message>>;
131
+ };
132
+ export { Law, type LawConfig, type LawPart, type LawReport };
133
+ //# sourceMappingURL=testing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testing.d.ts","names":[],"sources":["../src/testing.ts"],"mappings":";;;;;;;;;;;;KAiCK,MAAM;KACN,SAAS;;cAiBR;WAEO;;WAEA,KAAK,OAAO;WACZ,MAAM,OAAO;EAJxB,YACW;;EAEA,KAAK,OAAO,gBACZ,MAAM,OAAO;;;YAKd,UAAU;;qBAGT;;;;;EAKX,QAAK,KACE,2BAAyB;aACV,OAAO,mBAAmB;QAC7C;;;;;EAUH,OAAI,QACM,YAAU,YACR;aAEC,OAAO,kBAAkB,sBAAsB;QAEzD;;EAOH,WAAQ,UACI,sCAAoC;aAEnC,OACL,sBACA,kBACA,wBACA;QAEL;;;;;EAUH,KAAG;;;iBAIY,WAAW,UAAU;;WAE3B;WACA,SAAS;WACT,OAAO;;WAEP,SAAS;;;iBAIH,MAAM,UAAU;WACtB,OAAO;;WAEP,SAAS,cAAc,WAAW,UAAU;;WAE5C,SAAS;;WAET,MAAM,OAAO,UAAU,MAAM,WAAW,UAAU,yBAAyB;;WAE3E,WACP,OAAO,SAAS,eAAe,WAAW,UAAU,2BACjD,cAAc,SAAS;;;iBAIb,WAAW;;WAEjB;WACA;;WAEA,SAAS;WACT,MAAM;WACN,IAAI;;WAEJ,KAAK;;iBAGC,YAAY,UAAU;;WAE5B,OAAO;;;;;;WAMP,UACP,OAAO,UACP,SAAS,YACN,OAAO,OAAO,UAAU,uBAEzB,OAAO,UAAU,SAAS;;WAErB,QAAQ,SAAS,eAAe,cAAc,YAAY,cAAc;;WAExE,UAAU,KAAK;;;;;;WAMf;;WAEA,QAAQ;;;;;;;WAOR,SAAS,aAAa;WACtB,OAAO,cAAc,QAAQ,WAAW;;cAmE7C,MAAa,UAAU,SAAO,MAC5B,aAAa,+BAA6B,QACxC,YAAY,UAAU,aAC7B,QAAQ,MAAM,UAAU;qBA0Od;;;;;;EAMJ,OAAA,UAAQ,OACN,MAAM,oBAAkB,MACzB,WAAW,UAAU,yBAC1B,cAAc;;;;;;;EAYH,cAAA,UAAU,SAAO,OACtB,MAAM,UAAU,UAAQ,OACxB,SAAS,eAAe,WAAW,UAAU,2BACnD,cAAc,WAAW"}
Binary file
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testing.js","names":[],"sources":["../src/testing.ts"],"sourcesContent":["/**\n * `foldkit-remote/testing`: what every read shows, Model by Model, while an\n * application runs over scripted Messages and answers (#250).\n *\n * A list that blinks to `Loading` for one frame is a property of the reducer,\n * the Subscriptions and the order answers land in, so it can be caught without\n * a browser: run the real `update` and the real read entries, hold every\n * request they make, and release each when the test says. Every Model in\n * between is recorded, so nothing falls between samples.\n */\nimport { Cause, Clock, Duration, Effect, Exit, type Fiber, Option, Schema, Stream } from 'effect'\nimport { KeyValueStore } from 'effect/persistence'\nimport type { Equivalence } from 'effect'\nimport type * as Update from 'foldkit/update'\nimport type { ActiveSurface, Projection, SurfaceSource } from 'foldkit-surface'\nimport { RemoteClient } from './client.js'\nimport type { EntityLike, OutboxWiring, RemoteDomain, SubscriptionsOptions } from './index.js'\nimport type { RemoteMessage } from './model.js'\nimport type { MutationDescriptor } from './mutation.js'\nimport { OutboxLocks } from './outbox.js'\nimport { IDENTITY_SEPARATOR, queryIdentity, stableStringify, type QueryRef } from './query.js'\nimport type { RemoteData } from './remoteData.js'\nimport type { ReadStep, ReadWhy } from './why.js'\nimport type {\n RemoteForbidden,\n RemoteMutationError,\n RemoteProtocolError,\n RemoteQueryError,\n RemoteReadError,\n RemoteUnauthenticated,\n RemoteUnreachable,\n} from './wire.js'\n\ntype Tag = RemoteData<unknown>['_tag']\ntype Client = RemoteClient['Service']\n\n/** A request the trace holds: what it asked, and how to let it go on. */\ninterface Held {\n /** What `Respond` matches it by: one per row a read batch asks for. */\n readonly keys: ReadonlySet<string>\n readonly description: string\n readonly ask: (client: Client) => Effect.Effect<unknown, unknown>\n readonly resume: (exit: Exit.Exit<unknown, unknown>) => void\n}\n\nconst queryKey = (identity: string) => `query${IDENTITY_SEPARATOR}${identity}`\nconst readKey = (entity: string, id: string) =>\n `read${IDENTITY_SEPARATOR}${entity}${IDENTITY_SEPARATOR}${id}`\nconst mutationKey = (name: string) => `mutation${IDENTITY_SEPARATOR}${name}`\n\n/** A step that lets held requests go on: from `Respond`, never built by hand. */\nclass Release {\n constructor(\n readonly label: string,\n /** None for `Respond.all`, which lets every held request go on. */\n readonly key: Option.Option<string>,\n readonly fail: Option.Option<unknown>,\n ) {}\n}\n\n/** A step of a trace that answers held requests. */\nexport type Respond = Release\n\n/** The steps that answer what the application asked, each in the order the test puts it. */\nexport const Respond = {\n /**\n * Answers the oldest held query of `ref`'s connection (any window of it)\n * with what `client` returns for it, or fails it with `fail`.\n */\n query: (\n ref: QueryRef<string, unknown>,\n options: { readonly fail?: RemoteQueryError | RemoteUnauthenticated } = {},\n ): Respond =>\n new Release(\n `Respond.query(${ref.query})`,\n Option.some(queryKey(ref.identity)),\n Option.fromUndefinedOr(options.fail),\n ),\n /**\n * Answers the oldest held read batch that asks for this row. A batch is\n * answered whole, other rows included, as the server answers it.\n */\n read: (\n entity: EntityLike,\n id: string,\n options: {\n readonly fail?: RemoteReadError | RemoteProtocolError | RemoteUnauthenticated\n } = {},\n ): Respond =>\n new Release(\n `Respond.read(${entity.name}, ${id})`,\n Option.some(readKey(entity.name, id)),\n Option.fromUndefinedOr(options.fail),\n ),\n /** Answers the oldest held request of this mutation. */\n mutation: (\n mutation: MutationDescriptor<string, any, any>,\n options: {\n readonly fail?:\n | RemoteMutationError\n | RemoteForbidden\n | RemoteUnauthenticated\n | RemoteUnreachable\n } = {},\n ): Respond =>\n new Release(\n `Respond.mutation(${mutation.name})`,\n Option.some(mutationKey(mutation.name)),\n Option.fromUndefinedOr(options.fail),\n ),\n /**\n * Answers every held request, then every request those answers lead to,\n * until none is held: none at all, when nothing is.\n */\n all: new Release('Respond.all', Option.none(), Option.none()),\n}\n\n/** One Message the application handled, and the Model it left. */\nexport interface TraceEntry<AppModel, Message> {\n /** The step it followed: 0 while the Subscriptions start, 1 for the first step. */\n readonly step: number\n readonly message: Message\n readonly model: AppModel\n /** The Commands its `update` returned that the trace did not run: every one but Remote's. */\n readonly skipped: ReadonlyArray<string>\n}\n\n/** What `Trace.run` recorded. */\nexport interface Trace<AppModel, Message> {\n readonly start: AppModel\n /** Every Message in the order `update` handled it, with the Model after it. */\n readonly entries: ReadonlyArray<TraceEntry<AppModel, Message>>\n /** The requests still held when the steps ran out. */\n readonly pending: ReadonlyArray<string>\n /** `Data.why` of a read at a Model, given the trace's active record. */\n readonly why: (model: AppModel, read: Projection<AppModel, RemoteData<unknown>>) => ReadWhy\n /** `Data.timeline` over the trace, given its active record. */\n readonly timeline: (\n reads: Readonly<Record<string, Projection<AppModel, RemoteData<unknown>>>>,\n ) => ReadonlyArray<ReadStep<Message>>\n}\n\n/** A read that showed a value, and then did not, though nothing removed the value. */\nexport interface Regression<Message> {\n /** The read's name, as `regressions` was given it. */\n readonly read: string\n readonly step: number\n /** The Message after which it no longer showed its value. */\n readonly message: Message\n readonly from: Tag\n readonly to: Tag\n /** `Data.why`, for the Model it regressed in. */\n readonly why: ReadWhy\n}\n\nexport interface TraceConfig<AppModel, Message> {\n /** The Model the trace starts from; its Subscriptions start at it. */\n readonly start: AppModel\n /**\n * The application's `update`. Remote's Subscriptions send it Remote's\n * Messages, so its union must hold them. Its Commands other than Remote's are\n * not run.\n */\n readonly update: ((\n model: AppModel,\n message: Message,\n ) => Update.Return<AppModel, Message, unknown>) &\n // Said apart, so the application's union is inferred from `update` alone.\n ((model: AppModel, message: RemoteMessage) => unknown)\n /** The active record, as `Data.subscriptions` and `Data.why` take it. */\n readonly active: Readonly<Record<string, ActiveSurface<AppModel> | SurfaceSource<AppModel>>>\n /** As `Data.subscriptions` takes them; the trace's clock stands still, so it sets `now`. */\n readonly options?: Omit<SubscriptionsOptions, 'now'>\n /**\n * The time the trace's clock stands at, in milliseconds since the epoch:\n * what every Command and Subscription it runs reads (`Remote.now`, an\n * answer's date), and what the answers it asks for are given. Default 0.\n */\n readonly now?: number\n /** What answers each request once a step lets it go on: a fake, or a server's in-process client. */\n readonly client: Client\n /**\n * The application's `Data.outbox`, when it makes durable writes: the trace\n * starts from its `restore` over an empty store of its own, and runs its\n * Subscriptions as one tab does (without Web Locks, and with no other tab\n * to hear), so a durable write is stored and sent by it.\n */\n readonly outbox?: OutboxWiring<AppModel>\n readonly steps: ReadonlyArray<NoInfer<Message> | Respond>\n}\n\n/** Subscription entries as the trace drives them: Foldkit's shape, with or without keep-alive. */\ninterface Entry<AppModel, Message> {\n readonly dependenciesSchema: Schema.Top\n readonly modelToDependencies: (model: AppModel) => unknown\n readonly keepAliveEquivalence?: Equivalence.Equivalence<unknown>\n readonly dependenciesToStream: (\n dependencies: unknown,\n read: () => unknown,\n ) => Stream.Stream<Message, never, RemoteClient | KeyValueStore.KeyValueStore>\n}\n\n/** A Command as the trace runs it: one of Remote's needs `RemoteClient` alone. */\ntype Runnable<Message> = Effect.Effect<Message, never, RemoteClient>\n\n/** Remote's Commands, `Remote.mutate(…)` and `Remote.preload`, are the ones the trace runs. */\nconst isRemoteCommand = (name: string) => name.startsWith('Remote.')\n\n/** How many Messages one step may cause before the trace calls it a loop. */\nconst MESSAGES_PER_STEP = 10_000\n/** How many requests one `Respond.all` answers before it calls it a loop. */\nconst ANSWERS = 1_000\n\n/**\n * A scheduler that runs fiber tasks only when told: after each Message, the\n * trace runs every fiber until each waits on a held request.\n */\nconst makeScheduler = () => {\n const tasks: Array<() => void> = []\n const dispatcher = {\n scheduleTask: (task: () => void) => {\n tasks.push(task)\n },\n flush: () => {\n while (tasks.length > 0) tasks.shift()!()\n },\n }\n return {\n flush: dispatcher.flush,\n scheduler: {\n executionMode: 'sync' as const,\n shouldYield: () => false,\n makeDispatcher: () => dispatcher,\n },\n }\n}\n\n/**\n * A clock that stands still at `at`: a wait of no time ends, as the next tick\n * would end it, and every longer one never does, so age-outs, a retention\n * `grace` and live restarts wait for good.\n */\nconst stopped = (at: number): Clock.Clock => {\n const nanos = BigInt(at) * 1_000_000n\n return {\n currentTimeMillisUnsafe: () => at,\n currentTimeMillis: Effect.succeed(at),\n currentTimeNanosUnsafe: () => nanos,\n currentTimeNanos: Effect.succeed(nanos),\n monotonicTimeNanosUnsafe: () => nanos,\n monotonicTimeNanos: Effect.succeed(nanos),\n sleep: duration => (Duration.isZero(duration) ? Effect.void : Effect.never),\n }\n}\n\nconst run = async <AppModel, Message>(\n Data: RemoteDomain<AppModel, any, any, any, any>,\n config: TraceConfig<AppModel, Message>,\n): Promise<Trace<AppModel, Message>> => {\n const { scheduler, flush } = makeScheduler()\n const at = config.now ?? 0\n const clock = stopped(at)\n const held: Array<Held> = []\n const queue: Array<Message> = []\n const entries: Array<TraceEntry<AppModel, Message>> = []\n const defects: Array<Cause.Cause<unknown>> = []\n const fibers = new Set<Fiber.Fiber<unknown, unknown>>()\n // One tab's own store: an outbox restores from it and writes to it.\n const store = Effect.runSync(\n Effect.gen(function* () {\n return yield* KeyValueStore.KeyValueStore\n }).pipe(Effect.provide(KeyValueStore.layerMemory)),\n )\n let model =\n config.outbox === undefined\n ? config.start\n : Effect.runSync(\n config.outbox\n .restore(config.start)\n .pipe(Effect.provideService(KeyValueStore.KeyValueStore, store)),\n )\n let step = 0\n\n const hold = <A, E>(\n keys: ReadonlyArray<string>,\n description: string,\n ask: (client: Client) => Effect.Effect<A, E>,\n ): Effect.Effect<A, E> =>\n Effect.callback<A, E>(resume => {\n const request: Held = {\n keys: new Set(keys),\n description,\n ask,\n // The answer is the one `ask` gave for this very request.\n resume: exit => resume(exit as Exit.Exit<A, E>),\n }\n held.push(request)\n // A restarted stream abandons its request: its answer reaches no one.\n return Effect.sync(() => {\n const at = held.indexOf(request)\n if (at >= 0) held.splice(at, 1)\n })\n })\n\n const client: Client = {\n read: batch =>\n hold(\n batch.requests.map(request => readKey(request.entity, request.id)),\n `read ${batch.requests.map(request => `${request.entity}:${request.id}`).join(', ')}`,\n answer => answer.read(batch),\n ),\n query: request =>\n hold(\n [queryKey(queryIdentity(request.query, request.input))],\n `query ${request.query} ${stableStringify(request.input)}`,\n answer => answer.query(request),\n ),\n mutate: request =>\n hold([mutationKey(request.mutation)], `mutation ${request.mutation}`, answer =>\n answer.mutate(request),\n ),\n // A live stream is never answered: its events are scripted as Messages.\n live: () => Stream.never,\n }\n\n const fork = (effect: Effect.Effect<void, never, RemoteClient | KeyValueStore.KeyValueStore>) => {\n const fiber = Effect.runFork(\n effect.pipe(\n Effect.provideService(RemoteClient, client),\n Effect.provideService(KeyValueStore.KeyValueStore, store),\n Effect.provideService(OutboxLocks, Option.none()),\n Effect.provideService(Clock.Clock, clock),\n ),\n { scheduler },\n )\n fibers.add(fiber)\n fiber.addObserver(exit => {\n fibers.delete(fiber)\n if (Exit.isFailure(exit) && !Cause.hasInterruptsOnly(exit.cause)) defects.push(exit.cause)\n })\n return fiber\n }\n\n /** Runs every fiber until each waits, and fails loudly on a defect, as the runtime crashes on one. */\n const settle = () => {\n flush()\n const defect = defects.shift()\n if (defect !== undefined) {\n throw new Error(\n `Trace: a Subscription or Command died at step ${step}\\n${Cause.pretty(defect)}`,\n )\n }\n }\n\n const send = (message: Message) => Effect.sync(() => void queue.push(message))\n\n // The entries send Remote's Messages, which `update`'s type makes the application's own.\n const subscriptions = [\n ...Object.entries(Data.subscriptions(config.active, { ...config.options, now: () => at })),\n // A trace is one tab: there is no other to hear over the channel.\n ...Object.entries(config.outbox?.subscriptions ?? {}).filter(([key]) => key !== 'outbox.watch'),\n ] as unknown as ReadonlyArray<[string, Entry<AppModel, Message>]>\n const running = new Map<\n string,\n { readonly dependencies: unknown; readonly fiber: Fiber.Fiber<unknown, unknown> }\n >()\n const latest = new Map<string, unknown>()\n const equivalences = new Map(\n subscriptions.map(([key, entry]) => [\n key,\n entry.keepAliveEquivalence ?? Schema.toEquivalence(entry.dependenciesSchema),\n ]),\n )\n\n /** Restarts each entry whose dependencies changed, as Foldkit's runtime does (`switchMap`). */\n const reconcile = () => {\n for (const [key, entry] of subscriptions) {\n const dependencies = entry.modelToDependencies(model)\n latest.set(key, dependencies)\n const current = running.get(key)\n if (current !== undefined && equivalences.get(key)!(current.dependencies, dependencies)) {\n continue\n }\n current?.fiber.interruptUnsafe()\n const stream = entry.dependenciesToStream(dependencies, () => latest.get(key))\n running.set(key, {\n dependencies,\n fiber: fork(Stream.runForEach(stream, send)),\n })\n }\n settle()\n }\n\n const handle = (message: Message) => {\n const result = config.update(model, message)\n model = result.model\n const skipped: Array<string> = []\n for (const command of result.commands ?? []) {\n if (isRemoteCommand(command.name)) {\n fork(Effect.flatMap(command.effect as Runnable<Message>, send))\n } else {\n skipped.push(command.name)\n }\n }\n entries.push({ step, message, model, skipped })\n reconcile()\n }\n\n const drain = () => {\n let handled = 0\n while (queue.length > 0) {\n if (++handled > MESSAGES_PER_STEP) {\n throw new Error(`Trace: step ${step} caused more than ${MESSAGES_PER_STEP} Messages`)\n }\n handle(queue.shift()!)\n }\n }\n\n const answer = async (request: Held, fail: Option.Option<unknown>) => {\n held.splice(held.indexOf(request), 1)\n const exit = await Effect.runPromiseExit(\n Option.match(fail, {\n onNone: () => request.ask(config.client),\n onSome: error => Effect.fail(error),\n }).pipe(Effect.provideService(Clock.Clock, clock)),\n )\n request.resume(exit)\n settle()\n drain()\n }\n\n const describeHeld = () =>\n held.length === 0 ? 'none' : held.map(request => request.description).join('; ')\n\n const answerOne = async (key: string, respond: Release) => {\n const found = held.find(request => request.keys.has(key))\n if (found === undefined) {\n throw new Error(\n `Trace: step ${step}, ${respond.label}, answers nothing: no such request is held. Held: ${describeHeld()}`,\n )\n }\n await answer(found, respond.fail)\n }\n\n const answerAll = async () => {\n for (let answered = 0; held.length > 0; answered++) {\n if (answered >= ANSWERS) {\n throw new Error(\n `Trace: step ${step}, Respond.all, still holds requests after ${ANSWERS} answers: ${describeHeld()}`,\n )\n }\n await answer(held[0]!, Option.none())\n }\n }\n\n const release = (respond: Release) =>\n Option.match(respond.key, {\n onNone: answerAll,\n onSome: key => answerOne(key, respond),\n })\n\n try {\n reconcile()\n drain()\n for (const next of config.steps) {\n step++\n if (next instanceof Release) {\n await release(next)\n } else {\n queue.push(next)\n drain()\n }\n }\n return {\n start: config.start,\n entries,\n pending: held.map(request => request.description),\n why: (at, read) => Data.why(at, read, { surfaces: config.active }),\n timeline: reads => Data.timeline(config.start, entries, reads, { surfaces: config.active }),\n }\n } finally {\n for (const fiber of [...fibers]) fiber.interruptUnsafe()\n flush()\n }\n}\n\n/** The Models of a trace, the start first. */\nconst models = <AppModel>(trace: Trace<AppModel, unknown>): ReadonlyArray<AppModel> => [\n trace.start,\n ...trace.entries.map(entry => entry.model),\n]\n\nexport const Trace = {\n run,\n /**\n * What the read showed across the trace, the start first: each change of\n * tag, so a one-Message blink reads `['Ready', 'Loading', 'Ready']`.\n */\n tags: <AppModel>(\n trace: Trace<AppModel, unknown>,\n read: Projection<AppModel, RemoteData<unknown>>,\n ): ReadonlyArray<Tag> =>\n models(trace).reduce<Array<Tag>>((tags, model) => {\n const tag = read.read(model)._tag\n if (tags.at(-1) !== tag) tags.push(tag)\n return tags\n }, []),\n /**\n * Every time a read that showed a value (`Ready`, `Refreshing`) stopped\n * showing it without a reason a reader can see: it read `Loading` or\n * `Initial`, or `Failed` without the value (#234). `NotFound` is a reason:\n * the server said the row is gone.\n */\n regressions: <AppModel, Message>(\n trace: Trace<AppModel, Message>,\n reads: Readonly<Record<string, Projection<AppModel, RemoteData<unknown>>>>,\n ): ReadonlyArray<Regression<Message>> =>\n trace\n .timeline(reads)\n .filter(change => change.regression)\n .map(({ read, index, message, from, to, why }) => ({\n read,\n step: trace.entries[index]!.step,\n message,\n from,\n to,\n why,\n })),\n}\n\nexport { Law, type LawConfig, type LawPart, type LawReport } from './law.js'\n"],"mappings":"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"}