@boxxy/dispatch 0.1.0 → 0.1.3

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 (202) hide show
  1. package/README.md +4 -1
  2. package/dist/attempts/attempt-machine.d.ts +804 -0
  3. package/dist/attempts/attempt-moves.d.ts +2 -0
  4. package/dist/attempts/bind-attempt-session.d.ts +14 -0
  5. package/dist/attempts/build-attempt-change.d.ts +73 -0
  6. package/dist/attempts/build-attempt-fact.d.ts +3 -0
  7. package/dist/attempts/end-item-attempts.d.ts +18 -0
  8. package/dist/attempts/is-same-guard.d.ts +5 -0
  9. package/dist/attempts/pick-call-attempt.d.ts +10 -0
  10. package/dist/attempts/stop-stray-session.d.ts +11 -0
  11. package/dist/attempts/types.d.ts +142 -0
  12. package/dist/attempts/write-attempt-move.d.ts +7 -0
  13. package/dist/attempts/write-session-bind.d.ts +3 -0
  14. package/dist/claims/build-snapshot-hash.d.ts +2 -0
  15. package/dist/claims/claim-next.d.ts +6 -0
  16. package/dist/claims/pick-kept-session.d.ts +9 -0
  17. package/dist/claims/request-wake.d.ts +3 -0
  18. package/dist/claims/resume-claim.d.ts +3 -0
  19. package/dist/claims/start-claim.d.ts +3 -0
  20. package/dist/claims/types.d.ts +44 -0
  21. package/dist/closeouts/build-settle-plans.d.ts +17 -0
  22. package/dist/closeouts/close-out-attempt.d.ts +3 -0
  23. package/dist/closeouts/effect-handlers.d.ts +2 -0
  24. package/dist/closeouts/pick-settlement.d.ts +14 -0
  25. package/dist/closeouts/settle-attempt.d.ts +3 -0
  26. package/dist/closeouts/types.d.ts +50 -0
  27. package/dist/index.d.ts +38 -0
  28. package/dist/notices/constants.d.ts +4 -0
  29. package/dist/notices/create-null-notifier.d.ts +2 -0
  30. package/dist/notices/send-notices.d.ts +2 -0
  31. package/dist/notices/types.d.ts +11 -0
  32. package/dist/outbox/build-backoff-ms.d.ts +2 -0
  33. package/dist/outbox/build-initial-sender-state.d.ts +2 -0
  34. package/dist/outbox/build-outbox-status.d.ts +15 -0
  35. package/dist/outbox/constants.d.ts +2 -0
  36. package/dist/outbox/measure-wire-bytes.d.ts +2 -0
  37. package/dist/outbox/pick-sender-move.d.ts +10 -0
  38. package/dist/outbox/run-sender-once.d.ts +2 -0
  39. package/dist/outbox/take-batch.d.ts +3 -0
  40. package/dist/outbox/types.d.ts +61 -0
  41. package/dist/pull-requests/build-link-change.d.ts +11 -0
  42. package/dist/pull-requests/build-state-fact.d.ts +8 -0
  43. package/dist/pull-requests/collect-attempt-trailers.d.ts +2 -0
  44. package/dist/pull-requests/collect-seen-state.d.ts +7 -0
  45. package/dist/pull-requests/constants.d.ts +3 -0
  46. package/dist/pull-requests/link-pull-request.d.ts +2 -0
  47. package/dist/pull-requests/parse-pull-request-url.d.ts +2 -0
  48. package/dist/pull-requests/types.d.ts +37 -0
  49. package/dist/pull-requests/watch-pull-requests.d.ts +2 -0
  50. package/dist/readings/act-on-reading.d.ts +3 -0
  51. package/dist/readings/find-waiting-since.d.ts +9 -0
  52. package/dist/readings/pick-reading-action.d.ts +2 -0
  53. package/dist/readings/types.d.ts +79 -0
  54. package/dist/sessions/build-keep-writes.d.ts +9 -0
  55. package/dist/sessions/build-kept-clear.d.ts +2 -0
  56. package/dist/sessions/forget-sessions.d.ts +2 -0
  57. package/dist/sessions/is-kept-due.d.ts +2 -0
  58. package/dist/sessions/resume-kept-session.d.ts +6 -0
  59. package/dist/sessions/types.d.ts +19 -0
  60. package/dist/test-utils/apply-memory-change.d.ts +3 -0
  61. package/dist/test-utils/build-memory-reader.d.ts +3 -0
  62. package/dist/test-utils/build-mock-bind-change.d.ts +7 -0
  63. package/dist/test-utils/build-mock-claim-change.d.ts +2 -0
  64. package/dist/test-utils/build-mock-file-item-change.d.ts +2 -0
  65. package/dist/test-utils/build-mock-lever-change.d.ts +2 -0
  66. package/dist/test-utils/build-mock-new-id.d.ts +2 -0
  67. package/dist/test-utils/build-mock-note-change.d.ts +2 -0
  68. package/dist/test-utils/build-mock-pause-change.d.ts +2 -0
  69. package/dist/test-utils/build-mock-pull-request-change.d.ts +8 -0
  70. package/dist/test-utils/build-mock-relation-change.d.ts +7 -0
  71. package/dist/test-utils/build-mock-running-reading.d.ts +6 -0
  72. package/dist/test-utils/build-mock-settle-change.d.ts +7 -0
  73. package/dist/test-utils/build-mock-start-change.d.ts +2 -0
  74. package/dist/test-utils/claim-store-attempt-reader-cases.d.ts +2 -0
  75. package/dist/test-utils/claim-store-claim-cases.d.ts +2 -0
  76. package/dist/test-utils/claim-store-close-cases.d.ts +2 -0
  77. package/dist/test-utils/claim-store-contract.d.ts +2 -0
  78. package/dist/test-utils/claim-store-copy-cases.d.ts +2 -0
  79. package/dist/test-utils/claim-store-exclusive-cases.d.ts +2 -0
  80. package/dist/test-utils/claim-store-guard-cases.d.ts +2 -0
  81. package/dist/test-utils/claim-store-item-reader-cases.d.ts +2 -0
  82. package/dist/test-utils/claim-store-outbox-cases.d.ts +2 -0
  83. package/dist/test-utils/claim-store-race-cases.d.ts +2 -0
  84. package/dist/test-utils/claim-store-rollback-cases.d.ts +2 -0
  85. package/dist/test-utils/claim-store-seat-cases.d.ts +2 -0
  86. package/dist/test-utils/claim-store-session-cases.d.ts +2 -0
  87. package/dist/test-utils/collect-memory-limit-fills.d.ts +3 -0
  88. package/dist/test-utils/compare-text.d.ts +1 -0
  89. package/dist/test-utils/create-fake-backoff.d.ts +2 -0
  90. package/dist/test-utils/create-fake-clock.d.ts +5 -0
  91. package/dist/test-utils/create-fake-fact-sink.d.ts +8 -0
  92. package/dist/test-utils/create-fake-forge.d.ts +17 -0
  93. package/dist/test-utils/create-fake-worker.d.ts +42 -0
  94. package/dist/test-utils/create-memory-claim-store.d.ts +2 -0
  95. package/dist/test-utils/create-test-dispatch.d.ts +46 -0
  96. package/dist/test-utils/forge-contract.d.ts +15 -0
  97. package/dist/test-utils/is-same-held-seat.d.ts +2 -0
  98. package/dist/test-utils/types.d.ts +19 -0
  99. package/dist/test-utils/worker-contract.d.ts +14 -0
  100. package/dist/timeouts.d.ts +2 -0
  101. package/dist/types.d.ts +13 -0
  102. package/package.json +15 -2
  103. package/src/attempts/attempt-machine.ts +147 -0
  104. package/src/attempts/attempt-moves.ts +218 -0
  105. package/src/attempts/bind-attempt-session.ts +61 -0
  106. package/src/attempts/build-attempt-change.ts +540 -0
  107. package/src/attempts/build-attempt-fact.ts +135 -0
  108. package/src/attempts/end-item-attempts.ts +95 -0
  109. package/src/attempts/is-same-guard.ts +22 -0
  110. package/src/attempts/pick-call-attempt.ts +32 -0
  111. package/src/attempts/stop-stray-session.ts +48 -0
  112. package/src/attempts/types.ts +231 -0
  113. package/src/attempts/write-attempt-move.ts +41 -0
  114. package/src/attempts/write-session-bind.ts +47 -0
  115. package/src/claims/build-snapshot-hash.ts +9 -0
  116. package/src/claims/claim-next.ts +306 -0
  117. package/src/claims/pick-kept-session.ts +41 -0
  118. package/src/claims/request-wake.ts +17 -0
  119. package/src/claims/resume-claim.ts +56 -0
  120. package/src/claims/start-claim.ts +99 -0
  121. package/src/claims/types.ts +67 -0
  122. package/src/closeouts/build-settle-plans.ts +173 -0
  123. package/src/closeouts/close-out-attempt.ts +156 -0
  124. package/src/closeouts/effect-handlers.ts +232 -0
  125. package/src/closeouts/pick-settlement.ts +80 -0
  126. package/src/closeouts/settle-attempt.ts +161 -0
  127. package/src/closeouts/types.ts +87 -0
  128. package/src/index.ts +61 -0
  129. package/src/notices/constants.ts +7 -0
  130. package/src/notices/create-null-notifier.ts +6 -0
  131. package/src/notices/send-notices.ts +41 -0
  132. package/src/notices/types.ts +14 -0
  133. package/src/outbox/build-backoff-ms.ts +14 -0
  134. package/src/outbox/build-initial-sender-state.ts +14 -0
  135. package/src/outbox/build-outbox-status.ts +43 -0
  136. package/src/outbox/constants.ts +15 -0
  137. package/src/outbox/measure-wire-bytes.ts +31 -0
  138. package/src/outbox/pick-sender-move.ts +37 -0
  139. package/src/outbox/run-sender-once.ts +174 -0
  140. package/src/outbox/take-batch.ts +35 -0
  141. package/src/outbox/types.ts +76 -0
  142. package/src/pull-requests/build-link-change.ts +95 -0
  143. package/src/pull-requests/build-state-fact.ts +39 -0
  144. package/src/pull-requests/collect-attempt-trailers.ts +20 -0
  145. package/src/pull-requests/collect-seen-state.ts +19 -0
  146. package/src/pull-requests/constants.ts +5 -0
  147. package/src/pull-requests/link-pull-request.ts +119 -0
  148. package/src/pull-requests/parse-pull-request-url.ts +30 -0
  149. package/src/pull-requests/types.ts +63 -0
  150. package/src/pull-requests/watch-pull-requests.ts +308 -0
  151. package/src/readings/act-on-reading.ts +318 -0
  152. package/src/readings/find-waiting-since.ts +46 -0
  153. package/src/readings/pick-reading-action.ts +315 -0
  154. package/src/readings/types.ts +98 -0
  155. package/src/sessions/build-keep-writes.ts +55 -0
  156. package/src/sessions/build-kept-clear.ts +12 -0
  157. package/src/sessions/forget-sessions.ts +106 -0
  158. package/src/sessions/is-kept-due.ts +27 -0
  159. package/src/sessions/resume-kept-session.ts +25 -0
  160. package/src/sessions/types.ts +39 -0
  161. package/src/test-utils/apply-memory-change.ts +252 -0
  162. package/src/test-utils/build-memory-reader.ts +364 -0
  163. package/src/test-utils/build-mock-bind-change.ts +43 -0
  164. package/src/test-utils/build-mock-claim-change.ts +52 -0
  165. package/src/test-utils/build-mock-file-item-change.ts +20 -0
  166. package/src/test-utils/build-mock-lever-change.ts +18 -0
  167. package/src/test-utils/build-mock-new-id.ts +12 -0
  168. package/src/test-utils/build-mock-note-change.ts +18 -0
  169. package/src/test-utils/build-mock-pause-change.ts +19 -0
  170. package/src/test-utils/build-mock-pull-request-change.ts +63 -0
  171. package/src/test-utils/build-mock-relation-change.ts +40 -0
  172. package/src/test-utils/build-mock-running-reading.ts +19 -0
  173. package/src/test-utils/build-mock-settle-change.ts +70 -0
  174. package/src/test-utils/build-mock-start-change.ts +38 -0
  175. package/src/test-utils/claim-store-attempt-reader-cases.ts +357 -0
  176. package/src/test-utils/claim-store-claim-cases.ts +314 -0
  177. package/src/test-utils/claim-store-close-cases.ts +95 -0
  178. package/src/test-utils/claim-store-contract.ts +28 -0
  179. package/src/test-utils/claim-store-copy-cases.ts +100 -0
  180. package/src/test-utils/claim-store-exclusive-cases.ts +243 -0
  181. package/src/test-utils/claim-store-guard-cases.ts +383 -0
  182. package/src/test-utils/claim-store-item-reader-cases.ts +471 -0
  183. package/src/test-utils/claim-store-outbox-cases.ts +281 -0
  184. package/src/test-utils/claim-store-race-cases.ts +150 -0
  185. package/src/test-utils/claim-store-rollback-cases.ts +175 -0
  186. package/src/test-utils/claim-store-seat-cases.ts +270 -0
  187. package/src/test-utils/claim-store-session-cases.ts +289 -0
  188. package/src/test-utils/collect-memory-limit-fills.ts +15 -0
  189. package/src/test-utils/compare-text.ts +8 -0
  190. package/src/test-utils/create-fake-backoff.ts +16 -0
  191. package/src/test-utils/create-fake-clock.ts +20 -0
  192. package/src/test-utils/create-fake-fact-sink.ts +74 -0
  193. package/src/test-utils/create-fake-forge.ts +117 -0
  194. package/src/test-utils/create-fake-worker.ts +303 -0
  195. package/src/test-utils/create-memory-claim-store.ts +163 -0
  196. package/src/test-utils/create-test-dispatch.ts +597 -0
  197. package/src/test-utils/forge-contract.ts +171 -0
  198. package/src/test-utils/is-same-held-seat.ts +11 -0
  199. package/src/test-utils/types.ts +23 -0
  200. package/src/test-utils/worker-contract.ts +192 -0
  201. package/src/timeouts.ts +17 -0
  202. package/src/types.ts +32 -0
@@ -0,0 +1,61 @@
1
+ import type { ClaimStore, Clock, FactSink, Instant, OutboxFact, OutboxStatus } from '@boxxy/model';
2
+ export interface OutboxLimits {
3
+ readonly batchFacts: 100;
4
+ readonly factBytes: 262_144;
5
+ readonly batchBytes: 900_000;
6
+ readonly envelopeBytes: 512;
7
+ readonly requestTimeoutMs: 10_000;
8
+ readonly backoff: {
9
+ readonly firstMs: 1000;
10
+ readonly factor: 2;
11
+ readonly maxMs: 300_000;
12
+ readonly jitter: 0.2;
13
+ };
14
+ readonly blockedRetryMs: 300_000;
15
+ readonly parkRun: 25;
16
+ }
17
+ export type TakenBatch = {
18
+ readonly kind: 'batch';
19
+ readonly facts: readonly OutboxFact[];
20
+ } | {
21
+ readonly kind: 'oversize';
22
+ readonly fact: OutboxFact;
23
+ };
24
+ export type SenderMove = {
25
+ readonly kind: 'mark-sent';
26
+ } | {
27
+ readonly kind: 'retry-same';
28
+ } | {
29
+ readonly kind: 'split';
30
+ } | {
31
+ readonly kind: 'park';
32
+ readonly reason: string;
33
+ } | {
34
+ readonly kind: 'block';
35
+ readonly reason: string;
36
+ };
37
+ export type SenderStep = 'idle' | 'stored' | 'retry' | 'split' | 'parked' | 'blocked';
38
+ type SenderPhase = 'idle' | 'backing-off' | 'blocked';
39
+ type LastError = NonNullable<OutboxStatus['lastError']>;
40
+ export interface SenderState {
41
+ readonly queue: readonly (readonly OutboxFact[])[];
42
+ readonly retries: number;
43
+ readonly parkRun: number;
44
+ readonly phase: SenderPhase;
45
+ readonly failingSince: Instant | null;
46
+ readonly nextTryAt: Instant | null;
47
+ readonly lastError: LastError | null;
48
+ readonly lastStoredAt: Instant | null;
49
+ }
50
+ export interface SenderDeps {
51
+ readonly store: ClaimStore;
52
+ readonly sink: FactSink;
53
+ readonly clock: Clock;
54
+ readonly limits: OutboxLimits;
55
+ readonly random: () => number;
56
+ }
57
+ export interface SenderTurn {
58
+ readonly step: SenderStep;
59
+ readonly state: SenderState;
60
+ }
61
+ export {};
@@ -0,0 +1,11 @@
1
+ import type { ActorRef, AttemptRow, Instant, NewId, PullRequestReading, PullRequestRef, StoreChange } from '@boxxy/model';
2
+ export interface LinkChangeInput {
3
+ readonly attempt: AttemptRow;
4
+ readonly ref: PullRequestRef;
5
+ readonly reading: PullRequestReading;
6
+ readonly source: 'hook' | 'watch';
7
+ readonly actor: ActorRef;
8
+ readonly now: Instant;
9
+ readonly newId: NewId;
10
+ }
11
+ export declare function buildLinkChange(input: LinkChangeInput): StoreChange;
@@ -0,0 +1,8 @@
1
+ import type { ActorRef, AnyNewFact, FactId, ItemId, PullRequestRow } from '@boxxy/model';
2
+ export interface StateFactInput {
3
+ readonly row: PullRequestRow;
4
+ readonly item: ItemId;
5
+ readonly actor: ActorRef;
6
+ readonly id: FactId;
7
+ }
8
+ export declare function buildStateFact(input: StateFactInput): AnyNewFact | null;
@@ -0,0 +1,2 @@
1
+ import type { AttemptId } from '@boxxy/model';
2
+ export declare function collectAttemptTrailers(message: string): AttemptId[];
@@ -0,0 +1,7 @@
1
+ import type { CommitSha, Instant, PullRequestReading, PullRequestRow } from '@boxxy/model';
2
+ export interface SeenState {
3
+ readonly state: PullRequestRow['state'];
4
+ readonly mergedAt: Instant | null;
5
+ readonly mergeCommit: CommitSha | null;
6
+ }
7
+ export declare function collectSeenState(reading: PullRequestReading): SeenState;
@@ -0,0 +1,3 @@
1
+ export declare const watchLimits: {
2
+ readonly linkWindowMs: number;
3
+ };
@@ -0,0 +1,2 @@
1
+ import type { LinkPullRequestInput, LinkPullRequestResult } from './types.ts';
2
+ export declare function linkPullRequest(input: LinkPullRequestInput): Promise<LinkPullRequestResult>;
@@ -0,0 +1,2 @@
1
+ import type { PullRequestRef } from '@boxxy/model';
2
+ export declare function parsePullRequestUrl(url: string): PullRequestRef | null;
@@ -0,0 +1,37 @@
1
+ import type { ClaimStore, Forge, Instant, ItemRules, NewId, RepoName, RunnerId } from '@boxxy/model';
2
+ import type { CallRef } from '../closeouts/types.ts';
3
+ export interface LinkPullRequestInput {
4
+ readonly store: ClaimStore;
5
+ readonly forge: Forge;
6
+ readonly rules: ItemRules;
7
+ readonly call: CallRef;
8
+ readonly url: string;
9
+ readonly now: Instant;
10
+ readonly newId: NewId;
11
+ }
12
+ export type LinkPullRequestResult = {
13
+ readonly kind: 'linked';
14
+ readonly repo: RepoName;
15
+ readonly number: number;
16
+ readonly repeat: boolean;
17
+ } | {
18
+ readonly kind: 'retry';
19
+ } | {
20
+ readonly kind: 'refused';
21
+ readonly reason: 'not-a-pull-request-url' | 'linked-elsewhere' | 'no-attempt' | 'not-current';
22
+ };
23
+ export interface WatchPullRequestsInput {
24
+ readonly store: ClaimStore;
25
+ readonly forge: Forge;
26
+ readonly rules: ItemRules;
27
+ readonly runner: RunnerId;
28
+ readonly now: Instant;
29
+ readonly newId: NewId;
30
+ }
31
+ export interface WatchReport {
32
+ readonly linked: number;
33
+ readonly commitsLinked: number;
34
+ readonly merged: number;
35
+ readonly closed: number;
36
+ readonly unanswered: number;
37
+ }
@@ -0,0 +1,2 @@
1
+ import type { WatchPullRequestsInput, WatchReport } from './types.ts';
2
+ export declare function watchPullRequests(input: WatchPullRequestsInput): Promise<WatchReport>;
@@ -0,0 +1,3 @@
1
+ import type { SessionFault } from '@boxxy/model';
2
+ import type { ActOnReadingInput } from './types.ts';
3
+ export declare function actOnReading(input: ActOnReadingInput): Promise<SessionFault | null>;
@@ -0,0 +1,9 @@
1
+ import type { AttemptRow, Instant, SessionReading } from '@boxxy/model';
2
+ interface WaitingInput {
3
+ readonly attempt: AttemptRow;
4
+ readonly reading: SessionReading;
5
+ readonly quietAfterMinutes: number;
6
+ readonly now: Instant;
7
+ }
8
+ export declare function findWaitingSince(input: WaitingInput): Instant | null;
9
+ export {};
@@ -0,0 +1,2 @@
1
+ import type { ReadingAction, ReadingInput } from './types.ts';
2
+ export declare function pickReadingAction(input: ReadingInput): ReadingAction;
@@ -0,0 +1,79 @@
1
+ import type { AttemptRow, CapacityBackoff, ClaimStore, ForcedFailure, Instant, LiveAttemptState, LoadedRules, NewId, PipelineStep, SessionReading, SleepRules, WakeSource, WorkerKind } from '@boxxy/model';
2
+ export type ReadingAction = {
3
+ readonly kind: 'nothing';
4
+ } | {
5
+ readonly kind: 'bind-only';
6
+ } | {
7
+ readonly kind: 'move-to-running';
8
+ readonly via: 'reconcile' | 'resume';
9
+ } | {
10
+ readonly kind: 'respawn';
11
+ } | {
12
+ readonly kind: 'clear-mark';
13
+ } | {
14
+ readonly kind: 'sleep-if-idle';
15
+ readonly waitingSince: Instant;
16
+ } | {
17
+ readonly kind: 'sleep-unattended';
18
+ readonly since: Instant;
19
+ } | {
20
+ readonly kind: 'await-spawn';
21
+ } | {
22
+ readonly kind: 'sleep';
23
+ readonly requestWake: boolean;
24
+ } | {
25
+ readonly kind: 'request-wake';
26
+ readonly by: WakeSource;
27
+ } | {
28
+ readonly kind: 'wake-over-cap';
29
+ } | {
30
+ readonly kind: 'resume';
31
+ } | {
32
+ readonly kind: 'close';
33
+ readonly cause: 'timed-out';
34
+ readonly afterMinutes: number;
35
+ } | {
36
+ readonly kind: 'close';
37
+ readonly cause: 'turn-ended' | 'stalled';
38
+ } | {
39
+ readonly kind: 'close';
40
+ readonly cause: 'usage-limit';
41
+ readonly resetsAt: Instant;
42
+ } | {
43
+ readonly kind: 'stop';
44
+ } | {
45
+ readonly kind: 'settle';
46
+ readonly forced: ForcedFailure | null;
47
+ readonly sessionStopped: boolean;
48
+ };
49
+ export interface ReadingInput<Reading extends SessionReading = SessionReading> {
50
+ readonly attempt: AttemptRow;
51
+ readonly reading: Reading;
52
+ readonly step: PipelineStep | null;
53
+ readonly sleep: SleepRules;
54
+ readonly now: Instant;
55
+ }
56
+ type ReadingRule<Kind extends SessionReading['kind']> = (input: ReadingInput<Extract<SessionReading, {
57
+ kind: Kind;
58
+ }>>) => ReadingAction;
59
+ export type ReadingTable = {
60
+ readonly [Kind in SessionReading['kind']]: Readonly<Record<LiveAttemptState, ReadingRule<Kind>>>;
61
+ };
62
+ export interface ActOnReadingInput {
63
+ readonly store: ClaimStore;
64
+ readonly worker: WorkerKind;
65
+ readonly rules: LoadedRules;
66
+ readonly backoff: CapacityBackoff;
67
+ readonly attempt: AttemptRow;
68
+ readonly reading: SessionReading;
69
+ readonly action: ReadingAction;
70
+ readonly now: Instant;
71
+ readonly newId: NewId;
72
+ }
73
+ export interface RunningBound {
74
+ readonly name: string;
75
+ readonly pick: (input: ReadingInput<Extract<SessionReading, {
76
+ kind: 'running';
77
+ }>>) => ReadingAction | null;
78
+ }
79
+ export {};
@@ -0,0 +1,9 @@
1
+ import type { AttemptRow, Instant, ItemView, LoadedRules, RowWrite } from '@boxxy/model';
2
+ interface KeepInput {
3
+ readonly attempt: AttemptRow;
4
+ readonly item: ItemView;
5
+ readonly rules: LoadedRules;
6
+ readonly now: Instant;
7
+ }
8
+ export declare function buildKeepWrites(input: KeepInput): RowWrite[];
9
+ export {};
@@ -0,0 +1,2 @@
1
+ import type { ItemId, KeptSession, RowWrite } from '@boxxy/model';
2
+ export declare function buildKeptClear(item: ItemId, kept: KeptSession): RowWrite;
@@ -0,0 +1,2 @@
1
+ import type { ForgetReport, ForgetSessionsInput } from './types.ts';
2
+ export declare function forgetSessions(input: ForgetSessionsInput): Promise<ForgetReport>;
@@ -0,0 +1,2 @@
1
+ import type { KeptForgetInput } from './types.ts';
2
+ export declare function isKeptDue(input: KeptForgetInput): boolean;
@@ -0,0 +1,6 @@
1
+ import type { KeptSession, SpawnRequest, StartOutcome, WorkerKind } from '@boxxy/model';
2
+ export interface ResumedSession {
3
+ readonly outcome: StartOutcome;
4
+ readonly resumeFallback: boolean;
5
+ }
6
+ export declare function resumeKeptSession(worker: WorkerKind, kept: KeptSession, spawn: SpawnRequest): Promise<ResumedSession>;
@@ -0,0 +1,19 @@
1
+ import type { ActorRef, AtcSessionId, AttemptRow, ClaimStore, Instant, ItemView, KeptSession, LoadedRules, NewId, WorkerKind } from '@boxxy/model';
2
+ export interface ForgetSessionsInput {
3
+ readonly store: ClaimStore;
4
+ readonly worker: WorkerKind;
5
+ readonly rules: LoadedRules;
6
+ readonly actor: ActorRef;
7
+ readonly now: Instant;
8
+ readonly newId: NewId;
9
+ }
10
+ export interface ForgetReport {
11
+ readonly forgotten: readonly AtcSessionId[];
12
+ readonly failed: readonly AtcSessionId[];
13
+ }
14
+ export interface KeptForgetInput {
15
+ readonly kept: KeptSession;
16
+ readonly item: ItemView | null;
17
+ readonly latest: AttemptRow | null;
18
+ readonly now: Instant;
19
+ }
@@ -0,0 +1,3 @@
1
+ import type { ApplyResult, StoreChange } from '@boxxy/model';
2
+ import type { MemoryTables } from './types.ts';
3
+ export declare function applyMemoryChange(tables: MemoryTables, change: StoreChange): ApplyResult;
@@ -0,0 +1,3 @@
1
+ import type { StoreReader } from '@boxxy/model';
2
+ import type { MemoryTables } from './types.ts';
3
+ export declare function buildMemoryReader(getLiveTables: () => MemoryTables): StoreReader;
@@ -0,0 +1,7 @@
1
+ import type { AgentSessionId, AttemptRow, StoreChange } from '@boxxy/model';
2
+ interface BindInput {
3
+ readonly attempt: AttemptRow;
4
+ readonly agentSession: AgentSessionId;
5
+ }
6
+ export declare function buildMockBindChange(input: BindInput): StoreChange;
7
+ export {};
@@ -0,0 +1,2 @@
1
+ import type { AttemptRow, LimitName, StoreChange } from '@boxxy/model';
2
+ export declare function buildMockClaimChange(attempt: AttemptRow, limits?: readonly LimitName[]): StoreChange;
@@ -0,0 +1,2 @@
1
+ import type { ItemRow, StoreChange } from '@boxxy/model';
2
+ export declare function buildMockFileItemChange(item: ItemRow): StoreChange;
@@ -0,0 +1,2 @@
1
+ import type { LeverRow, StoreChange } from '@boxxy/model';
2
+ export declare function buildMockLeverChange(lever: LeverRow): StoreChange;
@@ -0,0 +1,2 @@
1
+ import type { NewId } from '@boxxy/model';
2
+ export declare function buildMockNewId(): NewId;
@@ -0,0 +1,2 @@
1
+ import type { NoteRow, StoreChange } from '@boxxy/model';
2
+ export declare function buildMockNoteChange(note: NoteRow): StoreChange;
@@ -0,0 +1,2 @@
1
+ import type { RunnerId, StoreChange } from '@boxxy/model';
2
+ export declare function buildMockPauseChange(runner: RunnerId): StoreChange;
@@ -0,0 +1,8 @@
1
+ import type { AttemptRow, PullRequestRow, StoreChange } from '@boxxy/model';
2
+ interface PullRequestInput {
3
+ readonly attempt: AttemptRow;
4
+ readonly state: PullRequestRow['state'];
5
+ readonly number?: number;
6
+ }
7
+ export declare function buildMockPullRequestChange(input: PullRequestInput): StoreChange;
8
+ export {};
@@ -0,0 +1,7 @@
1
+ import type { ItemId, StoreChange } from '@boxxy/model';
2
+ interface RelationInput {
3
+ readonly source: ItemId;
4
+ readonly target: ItemId;
5
+ }
6
+ export declare function buildMockRelationChange(input: RelationInput): StoreChange;
7
+ export {};
@@ -0,0 +1,6 @@
1
+ import type { SessionReading } from '@boxxy/model';
2
+ type RunningReading = Extract<SessionReading, {
3
+ kind: 'running';
4
+ }>;
5
+ export declare function buildMockRunningReading(overrides?: Partial<RunningReading>): RunningReading;
6
+ export {};
@@ -0,0 +1,7 @@
1
+ import type { AttemptRow, StoreChange } from '@boxxy/model';
2
+ interface SettleInput {
3
+ readonly attempt: AttemptRow;
4
+ readonly state: 'succeeded' | 'failed';
5
+ }
6
+ export declare function buildMockSettleChange(input: SettleInput): StoreChange;
7
+ export {};
@@ -0,0 +1,2 @@
1
+ import type { AttemptRow, CallerIdentity, StoreChange } from '@boxxy/model';
2
+ export declare function buildMockStartChange(attempt: AttemptRow, caller?: CallerIdentity | null): StoreChange;
@@ -0,0 +1,2 @@
1
+ import type { ClaimStoreCase } from './types.ts';
2
+ export declare const claimStoreAttemptReaderCases: readonly ClaimStoreCase[];
@@ -0,0 +1,2 @@
1
+ import type { ClaimStoreCase } from './types.ts';
2
+ export declare const claimStoreClaimCases: readonly ClaimStoreCase[];
@@ -0,0 +1,2 @@
1
+ import type { ClaimStoreCase } from './types.ts';
2
+ export declare const claimStoreCloseCases: readonly ClaimStoreCase[];
@@ -0,0 +1,2 @@
1
+ import type { ClaimStoreCase } from './types.ts';
2
+ export declare const claimStoreContract: readonly ClaimStoreCase[];
@@ -0,0 +1,2 @@
1
+ import type { ClaimStoreCase } from './types.ts';
2
+ export declare const claimStoreCopyCases: readonly ClaimStoreCase[];
@@ -0,0 +1,2 @@
1
+ import type { ClaimStoreCase } from './types.ts';
2
+ export declare const claimStoreExclusiveCases: readonly ClaimStoreCase[];
@@ -0,0 +1,2 @@
1
+ import type { ClaimStoreCase } from './types.ts';
2
+ export declare const claimStoreGuardCases: readonly ClaimStoreCase[];
@@ -0,0 +1,2 @@
1
+ import type { ClaimStoreCase } from './types.ts';
2
+ export declare const claimStoreItemReaderCases: readonly ClaimStoreCase[];
@@ -0,0 +1,2 @@
1
+ import type { ClaimStoreCase } from './types.ts';
2
+ export declare const claimStoreOutboxCases: readonly ClaimStoreCase[];
@@ -0,0 +1,2 @@
1
+ import type { ClaimStoreCase } from './types.ts';
2
+ export declare const claimStoreRaceCases: readonly ClaimStoreCase[];
@@ -0,0 +1,2 @@
1
+ import type { ClaimStoreCase } from './types.ts';
2
+ export declare const claimStoreRollbackCases: readonly ClaimStoreCase[];
@@ -0,0 +1,2 @@
1
+ import type { ClaimStoreCase } from './types.ts';
2
+ export declare const claimStoreSeatCases: readonly ClaimStoreCase[];
@@ -0,0 +1,2 @@
1
+ import type { ClaimStoreCase } from './types.ts';
2
+ export declare const claimStoreSessionCases: readonly ClaimStoreCase[];
@@ -0,0 +1,3 @@
1
+ import type { LimitFill } from '@boxxy/model';
2
+ import type { MemoryTables } from './types.ts';
3
+ export declare function collectMemoryLimitFills(tables: MemoryTables): LimitFill[];
@@ -0,0 +1 @@
1
+ export declare function compareText(first: string, second: string): number;
@@ -0,0 +1,2 @@
1
+ import type { CapacityBackoff } from '@boxxy/model';
2
+ export declare function createFakeBackoff(): CapacityBackoff;
@@ -0,0 +1,5 @@
1
+ import type { Clock, Instant } from '@boxxy/model';
2
+ export interface FakeClock extends Clock {
3
+ advance: (byMs: number) => Instant;
4
+ }
5
+ export declare function createFakeClock(startMs?: number): FakeClock;
@@ -0,0 +1,8 @@
1
+ import type { FactId, FactSink, OutboxFact, SinkAnswer } from '@boxxy/model';
2
+ export interface FakeFactSink extends FactSink {
3
+ readonly sends: readonly (readonly FactId[])[];
4
+ readonly facts: ReadonlyMap<FactId, OutboxFact>;
5
+ answerNext: (...answers: SinkAnswer[]) => void;
6
+ refuseFact: (id: FactId, status: 413 | 422) => void;
7
+ }
8
+ export declare function createFakeFactSink(): FakeFactSink;
@@ -0,0 +1,17 @@
1
+ import type { Forge, PullRequestReading, PullRequestRef } from '@boxxy/model';
2
+ export interface SeededPullRequest {
3
+ readonly ref: PullRequestRef;
4
+ readonly githubId: number;
5
+ readonly reading: Omit<PullRequestReading, 'githubId' | 'url'>;
6
+ }
7
+ export interface ReadHold {
8
+ readonly entered: Promise<void>;
9
+ readonly release: () => void;
10
+ }
11
+ export interface FakeForge extends Forge {
12
+ readonly calls: readonly string[];
13
+ seed: (pullRequest: SeededPullRequest) => void;
14
+ setDown: (isDown: boolean) => void;
15
+ holdNextRead: () => ReadHold;
16
+ }
17
+ export declare function createFakeForge(): FakeForge;
@@ -0,0 +1,42 @@
1
+ import type { AgentSessionId, AttemptId, Attention, Clock, Instant, WorkerKind } from '@boxxy/model';
2
+ type FailableMethod = 'start' | 'suspend' | 'resume' | 'stop' | 'forget' | 'resumeKept';
3
+ export type FakeFailure = {
4
+ readonly kind: 'refused';
5
+ readonly cause: 'capacity' | 'other';
6
+ readonly reason: string;
7
+ } | {
8
+ readonly kind: 'unknown';
9
+ readonly reason: string;
10
+ };
11
+ export type FakeSession = {
12
+ readonly state: 'running';
13
+ readonly attention?: Attention;
14
+ readonly lastActivityAt?: Instant;
15
+ readonly lastOwnerAt?: Instant;
16
+ readonly agentSession?: AgentSessionId | null;
17
+ readonly usageLimitResetsAt?: Instant | null;
18
+ } | {
19
+ readonly state: 'suspended';
20
+ readonly asked?: boolean;
21
+ readonly agentSession?: AgentSessionId | null;
22
+ } | {
23
+ readonly state: 'ended';
24
+ readonly agentSession?: AgentSessionId | null;
25
+ } | {
26
+ readonly state: 'absent';
27
+ };
28
+ export interface FakeWorkerCall {
29
+ readonly method: keyof WorkerKind;
30
+ readonly subject: string;
31
+ }
32
+ export interface FakeWorker extends WorkerKind {
33
+ readonly calls: readonly FakeWorkerCall[];
34
+ setSession: (attempt: AttemptId, session: FakeSession) => void;
35
+ failNext: (method: FailableMethod, failure: FakeFailure) => void;
36
+ failAlways: (method: FailableMethod, failure: FakeFailure) => void;
37
+ }
38
+ interface FakeWorkerInput {
39
+ readonly clock: Clock;
40
+ }
41
+ export declare function createFakeWorker(input: FakeWorkerInput): FakeWorker;
42
+ export {};
@@ -0,0 +1,2 @@
1
+ import type { ClosableClaimStore } from './types.ts';
2
+ export declare function createMemoryClaimStore(): ClosableClaimStore;
@@ -0,0 +1,46 @@
1
+ import type { ApplyResult, AttemptId, AttemptRow, CallerIdentity, CapacityBackoff, Claim, DesignMode, FactType, ItemId, LoadedRules, NewId, OutboxFact, PhaseName, RunnerId } from '@boxxy/model';
2
+ import type { SpawnSettings } from '../claims/types.ts';
3
+ import type { CallRef } from '../closeouts/types.ts';
4
+ import type { FakeClock } from './create-fake-clock.ts';
5
+ import type { FakeWorker } from './create-fake-worker.ts';
6
+ import type { ClosableClaimStore } from './types.ts';
7
+ export interface SeedItemInput {
8
+ readonly phase?: PhaseName;
9
+ readonly designMode?: DesignMode;
10
+ }
11
+ export interface ReworkInput {
12
+ readonly keptCaller?: CallerIdentity | null;
13
+ readonly startByWorker?: boolean;
14
+ }
15
+ export interface Rework {
16
+ readonly first: AttemptRow;
17
+ readonly claimed: AttemptRow;
18
+ readonly second: AttemptRow;
19
+ readonly firstBody: unknown;
20
+ }
21
+ export interface TestDispatch {
22
+ readonly store: ClosableClaimStore;
23
+ readonly clock: FakeClock;
24
+ readonly worker: FakeWorker;
25
+ readonly backoff: CapacityBackoff;
26
+ readonly newId: NewId;
27
+ readonly runner: RunnerId;
28
+ readonly spawn: SpawnSettings;
29
+ readonly rules: () => LoadedRules;
30
+ readonly setRules: (rules: LoadedRules) => void;
31
+ readonly tick: () => Promise<void>;
32
+ readonly claim: () => Promise<Claim | null>;
33
+ readonly seedItem: (input: SeedItemInput) => Promise<ItemId>;
34
+ readonly seedBuild: () => Promise<AttemptRow>;
35
+ readonly seedRework: (input: ReworkInput) => Promise<Rework>;
36
+ readonly seedReworkAfter: (first: AttemptRow) => Promise<AttemptRow>;
37
+ readonly closeItem: (item: ItemId, reason: string) => Promise<ApplyResult>;
38
+ readonly readAttempt: (id: AttemptId) => Promise<AttemptRow>;
39
+ readonly heldSeats: (attempt: AttemptId) => Promise<string[]>;
40
+ readonly listFacts: (type: FactType) => Promise<OutboxFact[]>;
41
+ readonly buildCallRef: (attempt: AttemptRow) => CallRef;
42
+ }
43
+ export interface TestDispatchOptions {
44
+ readonly store?: ClosableClaimStore;
45
+ }
46
+ export declare function createTestDispatch(options?: TestDispatchOptions): Promise<TestDispatch>;
@@ -0,0 +1,15 @@
1
+ import type { Forge } from '@boxxy/model';
2
+ import type { SeededPullRequest } from './create-fake-forge.ts';
3
+ export interface ForgeHarness {
4
+ readonly forge: Forge;
5
+ seed: (pullRequest: SeededPullRequest) => void;
6
+ }
7
+ export interface ForgeContractOutcome {
8
+ readonly received: unknown;
9
+ readonly expected: unknown;
10
+ }
11
+ export type ForgeContractCase = readonly [
12
+ title: string,
13
+ check: (harness: ForgeHarness) => Promise<ForgeContractOutcome>
14
+ ];
15
+ export declare const forgeContract: readonly ForgeContractCase[];
@@ -0,0 +1,2 @@
1
+ import type { LimitSeatRow } from '@boxxy/model';
2
+ export declare function isSameHeldSeat(seat: LimitSeatRow, held: LimitSeatRow): boolean;
@@ -0,0 +1,19 @@
1
+ import type { ClaimStore, Limit, LimitSeatRow, OutboxFact, TableName, Tables } from '@boxxy/model';
2
+ export interface ClosableClaimStore extends ClaimStore {
3
+ close: () => Promise<void>;
4
+ }
5
+ export interface ClaimStoreOutcome {
6
+ readonly received: unknown;
7
+ readonly expected: unknown;
8
+ }
9
+ export type ClaimStoreCase = readonly [
10
+ title: string,
11
+ check: (store: ClosableClaimStore) => Promise<ClaimStoreOutcome>
12
+ ];
13
+ export type MemoryTables = {
14
+ [T in TableName]: Tables[T][];
15
+ } & {
16
+ outbox: OutboxFact[];
17
+ limits: Limit[];
18
+ limit_seats: LimitSeatRow[];
19
+ };