@aeolus-fleet/core 0.24.1 → 0.25.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 (158) hide show
  1. package/README.md +5 -5
  2. package/dist/adapters/prisma/generated/browser.d.ts +12 -3
  3. package/dist/adapters/prisma/generated/client.d.ts +12 -3
  4. package/dist/adapters/prisma/generated/commonInputTypes.d.ts +60 -0
  5. package/dist/adapters/prisma/generated/enums.d.ts +15 -1
  6. package/dist/adapters/prisma/generated/enums.js +13 -1
  7. package/dist/adapters/prisma/generated/enums.js.map +1 -1
  8. package/dist/adapters/prisma/generated/internal/class.d.ts +11 -0
  9. package/dist/adapters/prisma/generated/internal/class.js +4 -4
  10. package/dist/adapters/prisma/generated/internal/class.js.map +1 -1
  11. package/dist/adapters/prisma/generated/internal/prismaNamespace.d.ts +109 -1
  12. package/dist/adapters/prisma/generated/internal/prismaNamespace.js +16 -0
  13. package/dist/adapters/prisma/generated/internal/prismaNamespace.js.map +1 -1
  14. package/dist/adapters/prisma/generated/internal/prismaNamespaceBrowser.d.ts +17 -0
  15. package/dist/adapters/prisma/generated/internal/prismaNamespaceBrowser.js +16 -0
  16. package/dist/adapters/prisma/generated/internal/prismaNamespaceBrowser.js.map +1 -1
  17. package/dist/adapters/prisma/generated/models/Delivery.d.ts +304 -4
  18. package/dist/adapters/prisma/generated/models/Fleet.d.ts +267 -0
  19. package/dist/adapters/prisma/generated/models/Lease.d.ts +332 -1
  20. package/dist/adapters/prisma/generated/models/OverdueDelivery.d.ts +1687 -0
  21. package/dist/adapters/prisma/generated/models/OverdueDelivery.js +2 -0
  22. package/dist/adapters/prisma/generated/models/OverdueDelivery.js.map +1 -0
  23. package/dist/adapters/prisma/generated/models/Ship.d.ts +271 -0
  24. package/dist/adapters/prisma/generated/models.d.ts +1 -0
  25. package/dist/adapters/prisma/history.js +231 -46
  26. package/dist/adapters/prisma/history.js.map +1 -1
  27. package/dist/adapters/prisma/installation.js +30 -1
  28. package/dist/adapters/prisma/installation.js.map +1 -1
  29. package/dist/adapters/prisma/messaging.js +11 -7
  30. package/dist/adapters/prisma/messaging.js.map +1 -1
  31. package/dist/adapters/prisma/overdue.d.ts +4 -0
  32. package/dist/adapters/prisma/overdue.js +63 -0
  33. package/dist/adapters/prisma/overdue.js.map +1 -0
  34. package/dist/adapters/prisma/registry.js +32 -7
  35. package/dist/adapters/prisma/registry.js.map +1 -1
  36. package/dist/adapters/prisma/rows.d.ts +12 -1
  37. package/dist/adapters/prisma/rows.js +46 -1
  38. package/dist/adapters/prisma/rows.js.map +1 -1
  39. package/dist/adapters/prisma/unit-of-work.d.ts +2 -1
  40. package/dist/adapters/prisma/unit-of-work.js +2 -0
  41. package/dist/adapters/prisma/unit-of-work.js.map +1 -1
  42. package/dist/adapters/trpc/context.d.ts +16 -0
  43. package/dist/adapters/trpc/fleet.d.ts +232 -14
  44. package/dist/adapters/trpc/fleet.js +49 -6
  45. package/dist/adapters/trpc/fleet.js.map +1 -1
  46. package/dist/adapters/trpc/installation.d.ts +14 -0
  47. package/dist/adapters/trpc/installation.js +7 -1
  48. package/dist/adapters/trpc/installation.js.map +1 -1
  49. package/dist/adapters/trpc/router.d.ts +301 -9
  50. package/dist/adapters/trpc/ship-protocol.js +2 -2
  51. package/dist/adapters/trpc/ship-protocol.js.map +1 -1
  52. package/dist/adapters/trpc/ship.d.ts +87 -0
  53. package/dist/adapters/trpc/ship.js +96 -1
  54. package/dist/adapters/trpc/ship.js.map +1 -1
  55. package/dist/adapters/trpc/starting-prompt-text.d.ts +1 -1
  56. package/dist/adapters/trpc/starting-prompt-text.js +22 -25
  57. package/dist/adapters/trpc/starting-prompt-text.js.map +1 -1
  58. package/dist/adapters/trpc/trpc.js +3 -0
  59. package/dist/adapters/trpc/trpc.js.map +1 -1
  60. package/dist/app.d.ts +4 -2
  61. package/dist/app.js +21 -9
  62. package/dist/app.js.map +1 -1
  63. package/dist/domain/messaging/delivery.d.ts +88 -28
  64. package/dist/domain/messaging/delivery.js +213 -39
  65. package/dist/domain/messaging/delivery.js.map +1 -1
  66. package/dist/domain/messaging/dismiss-delivery.d.ts +1 -1
  67. package/dist/domain/messaging/dismiss-delivery.js +1 -1
  68. package/dist/domain/messaging/hand-over-delivery.d.ts +38 -0
  69. package/dist/domain/messaging/hand-over-delivery.js +46 -0
  70. package/dist/domain/messaging/hand-over-delivery.js.map +1 -0
  71. package/dist/domain/messaging/message.d.ts +12 -1
  72. package/dist/domain/messaging/message.js +2 -0
  73. package/dist/domain/messaging/message.js.map +1 -1
  74. package/dist/domain/messaging/overdue.d.ts +60 -0
  75. package/dist/domain/messaging/overdue.js +52 -0
  76. package/dist/domain/messaging/overdue.js.map +1 -0
  77. package/dist/domain/messaging/ports.d.ts +20 -0
  78. package/dist/domain/messaging/public.d.ts +1 -0
  79. package/dist/domain/messaging/public.js +2 -0
  80. package/dist/domain/messaging/public.js.map +1 -0
  81. package/dist/domain/messaging/push-receive-deliveries.d.ts +48 -0
  82. package/dist/domain/messaging/push-receive-deliveries.js +70 -0
  83. package/dist/domain/messaging/push-receive-deliveries.js.map +1 -0
  84. package/dist/domain/messaging/receive-deliveries.d.ts +39 -6
  85. package/dist/domain/messaging/receive-deliveries.js +80 -50
  86. package/dist/domain/messaging/receive-deliveries.js.map +1 -1
  87. package/dist/domain/messaging/report-handled.d.ts +22 -0
  88. package/dist/domain/messaging/report-handled.js +13 -0
  89. package/dist/domain/messaging/report-handled.js.map +1 -0
  90. package/dist/domain/messaging/report-not-handled.d.ts +22 -0
  91. package/dist/domain/messaging/report-not-handled.js +13 -0
  92. package/dist/domain/messaging/report-not-handled.js.map +1 -0
  93. package/dist/domain/messaging/report-turn-end.d.ts +29 -0
  94. package/dist/domain/messaging/report-turn-end.js +36 -0
  95. package/dist/domain/messaging/report-turn-end.js.map +1 -0
  96. package/dist/domain/messaging/resend-delivery.d.ts +1 -1
  97. package/dist/domain/messaging/resend-delivery.js +1 -1
  98. package/dist/domain/messaging/tell-overdue-deliveries.d.ts +25 -0
  99. package/dist/domain/messaging/tell-overdue-deliveries.js +30 -0
  100. package/dist/domain/messaging/tell-overdue-deliveries.js.map +1 -0
  101. package/dist/domain/registry/installation-fleet.d.ts +3 -2
  102. package/dist/domain/registry/installation-fleet.js.map +1 -1
  103. package/dist/domain/registry/leases.d.ts +26 -0
  104. package/dist/domain/registry/leases.js +26 -1
  105. package/dist/domain/registry/leases.js.map +1 -1
  106. package/dist/domain/registry/ping-status.d.ts +2 -2
  107. package/dist/domain/registry/ping-status.js +7 -4
  108. package/dist/domain/registry/ping-status.js.map +1 -1
  109. package/dist/domain/registry/ports.d.ts +40 -0
  110. package/dist/domain/registry/public.d.ts +2 -2
  111. package/dist/domain/registry/public.js +1 -1
  112. package/dist/domain/registry/public.js.map +1 -1
  113. package/dist/domain/registry/report-turn.d.ts +28 -0
  114. package/dist/domain/registry/report-turn.js +28 -0
  115. package/dist/domain/registry/report-turn.js.map +1 -0
  116. package/dist/domain/registry/turn.d.ts +25 -0
  117. package/dist/domain/registry/turn.js +30 -0
  118. package/dist/domain/registry/turn.js.map +1 -0
  119. package/dist/domain/shared/delivery-way.d.ts +83 -0
  120. package/dist/domain/shared/delivery-way.js +89 -0
  121. package/dist/domain/shared/delivery-way.js.map +1 -0
  122. package/dist/domain/shared/errors.d.ts +1 -1
  123. package/dist/domain/shared/errors.js.map +1 -1
  124. package/dist/domain/shared/history.d.ts +116 -19
  125. package/dist/domain/shared/history.js +1 -1
  126. package/dist/domain/shared/history.js.map +1 -1
  127. package/dist/domain/shared/read-message.d.ts +7 -3
  128. package/dist/domain/shared/read-message.js +7 -4
  129. package/dist/domain/shared/read-message.js.map +1 -1
  130. package/dist/domain/shared/read-needs-attention.d.ts +5 -5
  131. package/dist/domain/shared/read-needs-attention.js +4 -4
  132. package/dist/domain/shared/read-needs-attention.js.map +1 -1
  133. package/dist/domain/shared/read-no-ship-can-take.d.ts +13 -0
  134. package/dist/domain/shared/read-no-ship-can-take.js +12 -0
  135. package/dist/domain/shared/read-no-ship-can-take.js.map +1 -0
  136. package/dist/domain/shared/read-overdue.d.ts +13 -0
  137. package/dist/domain/shared/read-overdue.js +12 -0
  138. package/dist/domain/shared/read-overdue.js.map +1 -0
  139. package/dist/domain/shared/read-ship-messages.d.ts +4 -1
  140. package/dist/domain/shared/read-ship-messages.js +6 -1
  141. package/dist/domain/shared/read-ship-messages.js.map +1 -1
  142. package/dist/domain/shared/read-ship-way.d.ts +41 -0
  143. package/dist/domain/shared/read-ship-way.js +39 -0
  144. package/dist/domain/shared/read-ship-way.js.map +1 -0
  145. package/dist/repeating-pass.d.ts +15 -0
  146. package/dist/repeating-pass.js +31 -0
  147. package/dist/repeating-pass.js.map +1 -0
  148. package/dist/wiring.d.ts +19 -0
  149. package/dist/wiring.js +25 -0
  150. package/dist/wiring.js.map +1 -1
  151. package/package.json +2 -2
  152. package/src/adapters/prisma/migrations/20261012190000_delivery_handed/migration.sql +11 -0
  153. package/src/adapters/prisma/migrations/20261012210000_push_receive/migration.sql +7 -0
  154. package/src/adapters/prisma/migrations/20261013090000_handled/migration.sql +6 -0
  155. package/src/adapters/prisma/migrations/20261013100000_turn/migration.sql +6 -0
  156. package/src/adapters/prisma/migrations/20261013120000_overdue/migration.sql +28 -0
  157. package/src/adapters/prisma/migrations/20261013140000_delivery_state_index/migration.sql +4 -0
  158. package/src/adapters/prisma/schema.prisma +66 -4
@@ -0,0 +1,52 @@
1
+ import { SYSTEM } from '../shared/events.js';
2
+ const MINUTE_MS = 60_000;
3
+ /** A delivery handed and not confirmed this long is overdue, whatever the turn. */
4
+ export const NOT_CONFIRMED_MINUTES = 10;
5
+ /** A delivery waiting this long while the session is idle is overdue. */
6
+ export const IDLE_MINUTES = 10;
7
+ /** A delivery waiting this long while the session is busy is overdue. */
8
+ export const BUSY_MINUTES = 60;
9
+ /**
10
+ * The crew's oldest waiting delivery whose clock ran out, if any. A handed
11
+ * delivery runs the 10 minute clock from its hand-over. A pending or received
12
+ * one runs 10 minutes while the session is idle and 60 while it is busy,
13
+ * counted from the latest of its state, the turn and the lease's push: a
14
+ * lease with no turn reported is idle since it was pushed.
15
+ */
16
+ export function overdueDelivery(crew, now) {
17
+ const turn = crew.turn ?? { state: 'idle', at: crew.pushedAt };
18
+ const oldestFirst = crew.waiting.toSorted((first, second) => first.sentAt.getTime() - second.sentAt.getTime() || first.deliveryId.localeCompare(second.deliveryId));
19
+ for (const delivery of oldestFirst) {
20
+ const { clock, minutes, from } = clockOf(delivery, { turn, pushedAt: crew.pushedAt });
21
+ if (now.getTime() - from.getTime() >= minutes * MINUTE_MS) {
22
+ return { fleetId: crew.fleetId, shipId: crew.shipId, leaseId: crew.leaseId, delivery, clock, minutes };
23
+ }
24
+ }
25
+ return undefined;
26
+ }
27
+ function clockOf(delivery, crew) {
28
+ if (delivery.state === 'handed') {
29
+ return { clock: 'notConfirmed', minutes: NOT_CONFIRMED_MINUTES, from: delivery.since };
30
+ }
31
+ const from = new Date(Math.max(delivery.since.getTime(), crew.turn.at.getTime(), crew.pushedAt.getTime()));
32
+ switch (crew.turn.state) {
33
+ case 'idle':
34
+ return { clock: 'idle', minutes: IDLE_MINUTES, from };
35
+ case 'busy':
36
+ return { clock: 'busy', minutes: BUSY_MINUTES, from };
37
+ }
38
+ }
39
+ /** DeliveryOverdue: the fleet told argo, as the system, that the delivery's clock ran out. */
40
+ export function overdueEvent(overdue, at) {
41
+ return {
42
+ fleetId: overdue.fleetId,
43
+ type: 'DeliveryOverdue',
44
+ occurredAt: at,
45
+ actor: SYSTEM,
46
+ shipId: overdue.shipId,
47
+ messageId: overdue.delivery.messageId,
48
+ deliveryId: overdue.delivery.deliveryId,
49
+ details: { leaseId: overdue.leaseId, clock: overdue.clock, minutes: overdue.minutes },
50
+ };
51
+ }
52
+ //# sourceMappingURL=overdue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overdue.js","sourceRoot":"","sources":["../../../src/domain/messaging/overdue.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import type { DeliveryId, FleetId, LeaseId, MessageId, ShipId } from '@aeolus-fleet/common';
2
2
  import type { Delivery, Message } from './message.js';
3
+ import type { Overdue, PushedCrew } from './overdue.js';
3
4
  /** One sender's idempotency key, in its fleet. */
4
5
  export interface SenderKey {
5
6
  fleetId: FleetId;
@@ -116,3 +117,22 @@ export interface ReceiverWatch {
116
117
  /** Stops watching. */
117
118
  stop(): void;
118
119
  }
120
+ /** Outbound port: the fleet's open pushed leases, for the 10 and 60 minute clocks. Read without a lock. */
121
+ export interface PushedCrews {
122
+ /**
123
+ * Every open pushed lease of the fleet, with its turn and the deliveries
124
+ * waiting for it: pending for its ship or its type, or received or handed
125
+ * with the lease, each with when it entered its state.
126
+ */
127
+ waiting(fleetId: FleetId): Promise<PushedCrew[]>;
128
+ }
129
+ /** Outbound port: the deliveries argo was told are overdue, once per lease and delivery. */
130
+ export interface OverdueDeliveryRepository {
131
+ /**
132
+ * Stores that argo is told the delivery is overdue on the lease, at `at`,
133
+ * only while the delivery is still in the state it was judged in and argo
134
+ * was not told of it on that lease before. Whether it stored it: two passes
135
+ * at once store it once.
136
+ */
137
+ tell(overdue: Overdue, at: Date): Promise<boolean>;
138
+ }
@@ -0,0 +1 @@
1
+ export type { OverdueClock, WaitingState } from './overdue.js';
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=public.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"public.js","sourceRoot":"","sources":["../../../src/domain/messaging/public.ts"],"names":[],"mappings":""}
@@ -0,0 +1,48 @@
1
+ import type { IdGenerator } from '@aeolus-fleet/common';
2
+ import { type HoldLeaseTx, type LeaseRepository } from '../registry/public.js';
3
+ import type { Crew } from '../shared/caller.js';
4
+ import type { Clock } from '../shared/clock.js';
5
+ import { type EventLog } from '../shared/events.js';
6
+ import { type Result } from '../shared/result.js';
7
+ import type { UnitOfWork } from '../shared/unit-of-work.js';
8
+ import type { DeliveryRepository, ReceiverWakeups } from './ports.js';
9
+ import { type ReceivedDelivery, type ReceiveRefusal } from './receive-deliveries.js';
10
+ export interface PushReceiveDeliveriesTx extends HoldLeaseTx {
11
+ leases: Pick<LeaseRepository, 'findOpenByIdForShare' | 'markPushed'>;
12
+ deliveries: DeliveryRepository;
13
+ events: EventLog;
14
+ }
15
+ /** One delivery a push receive took, as the computer side keeps it: where it stands, and its last hand-over number. */
16
+ export interface PushReceivedDelivery extends ReceivedDelivery {
17
+ /** Received: not yet handed to the agent. Handed: handed already, its hand-over number reported. */
18
+ state: 'received' | 'handed';
19
+ /** The last hand-over number the crew reported; none while received, or when a plain receive handed it. */
20
+ handOverNumber: number | null;
21
+ }
22
+ export interface DeliveriesPushReceived {
23
+ /** None when the wait ended without a delivery. */
24
+ deliveries: PushReceivedDelivery[];
25
+ }
26
+ export type PushReceiveDeliveries = (crew: Crew, input: {
27
+ max?: number;
28
+ }) => Promise<Result<DeliveriesPushReceived, ReceiveRefusal>>;
29
+ /**
30
+ * Use case: the crew's computer side, the trierarch or the plugin watcher,
31
+ * receives for the agent (`pushReceive`, decision 0040), up to `max`, 1 to
32
+ * 10, one by default. Its scope (messages:receive) is checked before this
33
+ * runs. Each look is one unit of work (see `pushReceiptForCrew`). A pending
34
+ * delivery becomes received, in flight with the crew's ship and lease, and
35
+ * counts no attempt; the computer side reports handed once it hands it to
36
+ * the agent. Its own in flight comes again first, changing nothing, so a
37
+ * restart or a lost answer loses nothing. From its first push receive until
38
+ * it ends, the lease is pushed: the agent's plain receive answers nothing.
39
+ * When nothing is there it waits as a receive does, about 25 seconds.
40
+ */
41
+ export declare function createPushReceiveDeliveries(deps: {
42
+ uow: UnitOfWork<PushReceiveDeliveriesTx>;
43
+ clock: Clock;
44
+ ids: IdGenerator;
45
+ wakeups: ReceiverWakeups;
46
+ /** How long a push receive waits on an empty inbox; about 25 seconds unless a test says otherwise. */
47
+ waitMs?: number;
48
+ }): PushReceiveDeliveries;
@@ -0,0 +1,70 @@
1
+ import { holdLease, markLeasePushed } from '../registry/public.js';
2
+ import { recordEvent } from '../shared/events.js';
3
+ import { ok } from '../shared/result.js';
4
+ import { pushReceiveDelivery } from './delivery.js';
5
+ import { RECEIVE_WAIT_MS, receivedDeliveryOf, waitForDeliveries, } from './receive-deliveries.js';
6
+ import { receiveMax } from './receive-max.js';
7
+ /**
8
+ * Takes up to `max` deliveries for the crew in one unit of work: marks its
9
+ * lease pushed (LeasePushed the first time), holds it, then takes its own in
10
+ * flight, received or handed,
11
+ * and then the oldest pending for its ship or its type, each received.
12
+ */
13
+ async function pushReceiptForCrew(deps, receipt) {
14
+ const { tx, ids, at } = deps;
15
+ const { crew, max } = receipt;
16
+ await markLeasePushed({ tx, ids }, { fleetId: crew.fleetId, shipId: crew.shipId, leaseId: crew.leaseId, at });
17
+ const ship = await holdLease(tx, crew);
18
+ if (!ship.isOk) {
19
+ return ship;
20
+ }
21
+ const taken = await tx.deliveries.findClaimableForUpdate({
22
+ fleetId: crew.fleetId,
23
+ shipId: crew.shipId,
24
+ type: ship.value.type,
25
+ leaseId: crew.leaseId,
26
+ limit: max,
27
+ excluding: [],
28
+ });
29
+ const received = [];
30
+ for (const { delivery, message } of taken) {
31
+ const { delivery: changed, events } = pushReceiveDelivery(delivery, { crew, at });
32
+ await tx.deliveries.update(changed);
33
+ for (const event of events) {
34
+ await recordEvent({ events: tx.events, ids }, event);
35
+ }
36
+ const handedOut = await receivedDeliveryOf(tx, { delivery: changed, message });
37
+ if (!handedOut.isOk) {
38
+ return handedOut;
39
+ }
40
+ received.push({
41
+ ...handedOut.value,
42
+ state: changed.state === 'handed' ? 'handed' : 'received',
43
+ handOverNumber: changed.handOverNumber,
44
+ });
45
+ }
46
+ return ok({ ship: ship.value, deliveries: received });
47
+ }
48
+ /**
49
+ * Use case: the crew's computer side, the trierarch or the plugin watcher,
50
+ * receives for the agent (`pushReceive`, decision 0040), up to `max`, 1 to
51
+ * 10, one by default. Its scope (messages:receive) is checked before this
52
+ * runs. Each look is one unit of work (see `pushReceiptForCrew`). A pending
53
+ * delivery becomes received, in flight with the crew's ship and lease, and
54
+ * counts no attempt; the computer side reports handed once it hands it to
55
+ * the agent. Its own in flight comes again first, changing nothing, so a
56
+ * restart or a lost answer loses nothing. From its first push receive until
57
+ * it ends, the lease is pushed: the agent's plain receive answers nothing.
58
+ * When nothing is there it waits as a receive does, about 25 seconds.
59
+ */
60
+ export function createPushReceiveDeliveries(deps) {
61
+ const waitMs = deps.waitMs ?? RECEIVE_WAIT_MS;
62
+ return async (crew, input) => {
63
+ const max = receiveMax(input.max);
64
+ if (!max.isOk) {
65
+ return max;
66
+ }
67
+ return waitForDeliveries({ clock: deps.clock, wakeups: deps.wakeups, waitMs }, { crew, look: () => deps.uow.run((tx) => pushReceiptForCrew({ tx, ids: deps.ids, at: deps.clock.now() }, { crew, max: max.value })) });
68
+ };
69
+ }
70
+ //# sourceMappingURL=push-receive-deliveries.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"push-receive-deliveries.js","sourceRoot":"","sources":["../../../src/domain/messaging/push-receive-deliveries.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import type { DeliveryId, IdGenerator, MessageId, ShipId } from '@aeolus-fleet/common';
2
- import { type HoldLeaseTx, type LeaseEnded } from '../registry/public.js';
2
+ import { type FindShipTx, type HoldLeaseTx, type LeaseEnded, type LeaseRepository, type Ship } from '../registry/public.js';
3
3
  import type { Crew } from '../shared/caller.js';
4
4
  import type { Clock } from '../shared/clock.js';
5
5
  import type { DomainError } from '../shared/errors.js';
@@ -7,8 +7,10 @@ import { type EventLog } from '../shared/events.js';
7
7
  import { type Result } from '../shared/result.js';
8
8
  import type { Recipient } from '../shared/selector.js';
9
9
  import type { UnitOfWork } from '../shared/unit-of-work.js';
10
+ import type { Delivery, Message } from './message.js';
10
11
  import type { DeliveryRepository, ReceiverWakeups } from './ports.js';
11
12
  export interface ReceiveDeliveriesTx extends HoldLeaseTx {
13
+ leases: Pick<LeaseRepository, 'findOpenByIdForShare' | 'isPushed'>;
12
14
  deliveries: DeliveryRepository;
13
15
  events: EventLog;
14
16
  }
@@ -28,7 +30,7 @@ export interface ReceivedDelivery {
28
30
  model: string | null;
29
31
  inReplyTo: MessageId | null;
30
32
  sentAt: Date;
31
- /** How many times the delivery has been claimed, this time included. */
33
+ /** How many times the delivery has been handed over, this time included: its attempts. */
32
34
  attempts: number;
33
35
  }
34
36
  export interface DeliveriesReceived {
@@ -41,15 +43,25 @@ export type ReceiveDeliveries = (crew: Crew, input: {
41
43
  }) => Promise<Result<DeliveriesReceived, ReceiveRefusal>>;
42
44
  /** How long a receive waits for a delivery when none is there: about 25 seconds, then it returns empty. */
43
45
  export declare const RECEIVE_WAIT_MS = 25000;
46
+ /**
47
+ * The delivery as its crew gets it: with its message, and its sender by id
48
+ * and by the name and type it has in Registry now.
49
+ */
50
+ export declare function receivedDeliveryOf(tx: FindShipTx, held: {
51
+ delivery: Delivery;
52
+ message: Message;
53
+ }): Promise<Result<ReceivedDelivery, DomainError<'SHIP_NOT_FOUND'>>>;
44
54
  /**
45
55
  * Use case: a crew receives its deliveries (`receive`), up to `max`, 1 to 10,
46
56
  * one by default. Its scope (messages:receive) is checked before this runs.
47
57
  * Each attempt is one unit of work (see `claimForCrew`): every delivery it
48
- * returns is in flight, claimed by the crew's ship and lease, until the ship
49
- * acknowledges it or the lease ends, and the crew's next receive returns it
50
- * again, counted as another claim, so a lost reply loses nothing. Its fifth
51
- * claim makes it undeliverable instead. Each delivery names its sender by id,
58
+ * returns is handed at once, in flight with the crew's ship and lease, until
59
+ * the ship acknowledges it or the lease ends, and the crew's next receive
60
+ * hands it again, counted as another attempt, so a lost reply loses nothing.
61
+ * Its fifth attempt makes it undeliverable instead. Each delivery names its sender by id,
52
62
  * and by the name and type the sender has now, so the crew can answer by name.
63
+ * On a pushed lease it hands nothing, its pending deliveries included: the
64
+ * computer side takes them with a push receive (decision 0040).
53
65
  *
54
66
  * When nothing is there it waits, about 25 seconds, for a wake-up for its ship
55
67
  * or its type (ADR 0003: LISTEN/NOTIFY after commit), then returns empty. It
@@ -66,3 +78,24 @@ export declare function createReceiveDeliveries(deps: {
66
78
  /** How long a receive waits on an empty inbox; about 25 seconds unless a test says otherwise. */
67
79
  waitMs?: number;
68
80
  }): ReceiveDeliveries;
81
+ /**
82
+ * Looks for the crew's deliveries, one unit of work per `look`, and
83
+ * when there are none waits for a wake-up for its ship or its type, until
84
+ * `waitMs` has passed. It starts watching before it looks a second time, so a
85
+ * delivery that commits between its first look and its watch is found by that
86
+ * second look. A wake-up that brings nothing for it leaves it waiting for the
87
+ * rest of its time.
88
+ */
89
+ export declare function waitForDeliveries<Found, Refusal>(deps: {
90
+ clock: Clock;
91
+ wakeups: ReceiverWakeups;
92
+ waitMs: number;
93
+ }, wait: {
94
+ crew: Crew;
95
+ look: () => Promise<Result<{
96
+ ship: Ship;
97
+ deliveries: Found[];
98
+ }, Refusal>>;
99
+ }): Promise<Result<{
100
+ deliveries: Found[];
101
+ }, Refusal>>;
@@ -1,10 +1,36 @@
1
- import { findShip, holdLease } from '../registry/public.js';
1
+ import { findShip, holdLease, isLeasePushed } from '../registry/public.js';
2
2
  import { recordEvent } from '../shared/events.js';
3
3
  import { ok } from '../shared/result.js';
4
- import { claimDelivery } from './delivery.js';
4
+ import { handDelivery } from './delivery.js';
5
5
  import { receiveMax } from './receive-max.js';
6
6
  /** How long a receive waits for a delivery when none is there: about 25 seconds, then it returns empty. */
7
7
  export const RECEIVE_WAIT_MS = 25_000;
8
+ /**
9
+ * The delivery as its crew gets it: with its message, and its sender by id
10
+ * and by the name and type it has in Registry now.
11
+ */
12
+ export async function receivedDeliveryOf(tx, held) {
13
+ const { delivery, message } = held;
14
+ const sender = await findShip(tx, { fleetId: delivery.fleetId, shipId: message.senderShipId });
15
+ if (!sender.isOk) {
16
+ // A message's sender always exists: ships are never deleted, and the foreign key keeps the sender in its fleet.
17
+ return sender;
18
+ }
19
+ return ok({
20
+ deliveryId: delivery.id,
21
+ messageId: message.id,
22
+ senderShipId: message.senderShipId,
23
+ senderName: sender.value.name,
24
+ senderType: sender.value.type,
25
+ recipient: delivery.recipient,
26
+ payload: message.payload,
27
+ contentType: message.contentType,
28
+ model: message.model,
29
+ inReplyTo: message.inReplyToMessageId,
30
+ sentAt: message.createdAt,
31
+ attempts: delivery.attempts,
32
+ });
33
+ }
8
34
  /**
9
35
  * Claims up to `max` deliveries for the crew in one unit of work: holds its
10
36
  * lease, then takes its own deliveries in flight, then the oldest pending ones
@@ -19,6 +45,10 @@ async function claimForCrew(deps, claim) {
19
45
  if (!ship.isOk) {
20
46
  return ship;
21
47
  }
48
+ if (await isLeasePushed(tx, crew)) {
49
+ // The computer side takes a pushed lease's deliveries; the agent's own receive never gets one (decision 0040).
50
+ return ok({ ship: ship.value, deliveries: [] });
51
+ }
22
52
  const handedOut = [];
23
53
  const claimed = [];
24
54
  let hasMore = true;
@@ -35,31 +65,17 @@ async function claimForCrew(deps, claim) {
35
65
  hasMore = claimable.length === limit;
36
66
  for (const { delivery, message } of claimable) {
37
67
  claimed.push(delivery.id);
38
- const { outcome, delivery: changed, events } = claimDelivery(delivery, { crew, at });
68
+ const { outcome, delivery: changed, events } = handDelivery(delivery, { crew, at });
39
69
  await tx.deliveries.update(changed);
40
70
  for (const event of events) {
41
71
  await recordEvent({ events: tx.events, ids }, event);
42
72
  }
43
- if (outcome === 'claimed') {
44
- const sender = await findShip(tx, { fleetId: crew.fleetId, shipId: message.senderShipId });
45
- if (!sender.isOk) {
46
- // A message's sender always exists: ships are never deleted, and the foreign key keeps the sender in its fleet.
47
- return sender;
73
+ if (outcome === 'handed') {
74
+ const received = await receivedDeliveryOf(tx, { delivery: changed, message });
75
+ if (!received.isOk) {
76
+ return received;
48
77
  }
49
- handedOut.push({
50
- deliveryId: changed.id,
51
- messageId: message.id,
52
- senderShipId: message.senderShipId,
53
- senderName: sender.value.name,
54
- senderType: sender.value.type,
55
- recipient: changed.recipient,
56
- payload: message.payload,
57
- contentType: message.contentType,
58
- model: message.model,
59
- inReplyTo: message.inReplyToMessageId,
60
- sentAt: message.createdAt,
61
- attempts: changed.attempts,
62
- });
78
+ handedOut.push(received.value);
63
79
  }
64
80
  }
65
81
  }
@@ -69,11 +85,13 @@ async function claimForCrew(deps, claim) {
69
85
  * Use case: a crew receives its deliveries (`receive`), up to `max`, 1 to 10,
70
86
  * one by default. Its scope (messages:receive) is checked before this runs.
71
87
  * Each attempt is one unit of work (see `claimForCrew`): every delivery it
72
- * returns is in flight, claimed by the crew's ship and lease, until the ship
73
- * acknowledges it or the lease ends, and the crew's next receive returns it
74
- * again, counted as another claim, so a lost reply loses nothing. Its fifth
75
- * claim makes it undeliverable instead. Each delivery names its sender by id,
88
+ * returns is handed at once, in flight with the crew's ship and lease, until
89
+ * the ship acknowledges it or the lease ends, and the crew's next receive
90
+ * hands it again, counted as another attempt, so a lost reply loses nothing.
91
+ * Its fifth attempt makes it undeliverable instead. Each delivery names its sender by id,
76
92
  * and by the name and type the sender has now, so the crew can answer by name.
93
+ * On a pushed lease it hands nothing, its pending deliveries included: the
94
+ * computer side takes them with a push receive (decision 0040).
77
95
  *
78
96
  * When nothing is there it waits, about 25 seconds, for a wake-up for its ship
79
97
  * or its type (ADR 0003: LISTEN/NOTIFY after commit), then returns empty. It
@@ -89,31 +107,43 @@ export function createReceiveDeliveries(deps) {
89
107
  if (!max.isOk) {
90
108
  return max;
91
109
  }
92
- const until = deps.clock.now().getTime() + waitMs;
93
- let watch;
94
- try {
95
- for (;;) {
96
- const attempt = await deps.uow.run((tx) => claimForCrew({ tx, ids: deps.ids, at: deps.clock.now() }, { crew, max: max.value }));
97
- if (!attempt.isOk) {
98
- return attempt;
99
- }
100
- const { ship, deliveries } = attempt.value;
101
- if (deliveries.length > 0) {
102
- return ok({ deliveries });
103
- }
104
- if (watch === undefined) {
105
- watch = deps.wakeups.watch({ fleetId: crew.fleetId, shipId: crew.shipId, type: ship.type });
106
- continue;
107
- }
108
- const remainingMs = until - deps.clock.now().getTime();
109
- if (remainingMs <= 0 || (await watch.next(remainingMs)) === 'timedOut') {
110
- return ok({ deliveries: [] });
111
- }
110
+ return waitForDeliveries({ clock: deps.clock, wakeups: deps.wakeups, waitMs }, { crew, look: () => deps.uow.run((tx) => claimForCrew({ tx, ids: deps.ids, at: deps.clock.now() }, { crew, max: max.value })) });
111
+ };
112
+ }
113
+ /**
114
+ * Looks for the crew's deliveries, one unit of work per `look`, and
115
+ * when there are none waits for a wake-up for its ship or its type, until
116
+ * `waitMs` has passed. It starts watching before it looks a second time, so a
117
+ * delivery that commits between its first look and its watch is found by that
118
+ * second look. A wake-up that brings nothing for it leaves it waiting for the
119
+ * rest of its time.
120
+ */
121
+ export async function waitForDeliveries(deps, wait) {
122
+ const { crew, look } = wait;
123
+ const until = deps.clock.now().getTime() + deps.waitMs;
124
+ let watch;
125
+ try {
126
+ for (;;) {
127
+ const attempt = await look();
128
+ if (!attempt.isOk) {
129
+ return attempt;
130
+ }
131
+ const { ship, deliveries } = attempt.value;
132
+ if (deliveries.length > 0) {
133
+ return ok({ deliveries });
134
+ }
135
+ if (watch === undefined) {
136
+ watch = deps.wakeups.watch({ fleetId: crew.fleetId, shipId: crew.shipId, type: ship.type });
137
+ continue;
138
+ }
139
+ const remainingMs = until - deps.clock.now().getTime();
140
+ if (remainingMs <= 0 || (await watch.next(remainingMs)) === 'timedOut') {
141
+ return ok({ deliveries: [] });
112
142
  }
113
143
  }
114
- finally {
115
- watch?.stop();
116
- }
117
- };
144
+ }
145
+ finally {
146
+ watch?.stop();
147
+ }
118
148
  }
119
149
  //# sourceMappingURL=receive-deliveries.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"receive-deliveries.js","sourceRoot":"","sources":["../../../src/domain/messaging/receive-deliveries.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"receive-deliveries.js","sourceRoot":"","sources":["../../../src/domain/messaging/receive-deliveries.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import type { DeliveryId, IdGenerator } from '@aeolus-fleet/common';
2
+ import type { Crew } from '../shared/caller.js';
3
+ import type { Clock } from '../shared/clock.js';
4
+ import type { Result } from '../shared/result.js';
5
+ import type { UnitOfWork } from '../shared/unit-of-work.js';
6
+ import { type ReportTurnEndRefusal, type ReportTurnEndTx } from './report-turn-end.js';
7
+ export type ReportHandled = (crew: Crew, input: {
8
+ deliveryId: DeliveryId;
9
+ }) => Promise<Result<undefined, ReportTurnEndRefusal>>;
10
+ /**
11
+ * Use case: a pushed crew reports the turn that took an acknowledged
12
+ * delivery ended by itself (`handled`, decision 0040). Its scope
13
+ * (messages:receive) is checked before this runs. In one unit of work it
14
+ * holds the crew's lease, so a release waits for it, locks the delivery and
15
+ * moves it to handled with DeliveryHandled. Reporting it again is OK and
16
+ * changes nothing.
17
+ */
18
+ export declare function createReportHandled(deps: {
19
+ uow: UnitOfWork<ReportTurnEndTx>;
20
+ clock: Clock;
21
+ ids: IdGenerator;
22
+ }): ReportHandled;
@@ -0,0 +1,13 @@
1
+ import { reportTurnEnd } from './report-turn-end.js';
2
+ /**
3
+ * Use case: a pushed crew reports the turn that took an acknowledged
4
+ * delivery ended by itself (`handled`, decision 0040). Its scope
5
+ * (messages:receive) is checked before this runs. In one unit of work it
6
+ * holds the crew's lease, so a release waits for it, locks the delivery and
7
+ * moves it to handled with DeliveryHandled. Reporting it again is OK and
8
+ * changes nothing.
9
+ */
10
+ export function createReportHandled(deps) {
11
+ return (crew, input) => deps.uow.run((tx) => reportTurnEnd({ tx, clock: deps.clock, ids: deps.ids }, { crew, ...input, end: 'handled' }));
12
+ }
13
+ //# sourceMappingURL=report-handled.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report-handled.js","sourceRoot":"","sources":["../../../src/domain/messaging/report-handled.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,aAAa,EAAmD,MAAM,sBAAsB,CAAC;AAItG;;;;;;;GAOG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAA0E;IAC5G,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,aAAa,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;AAC5I,CAAC"}
@@ -0,0 +1,22 @@
1
+ import type { DeliveryId, IdGenerator } from '@aeolus-fleet/common';
2
+ import type { Crew } from '../shared/caller.js';
3
+ import type { Clock } from '../shared/clock.js';
4
+ import type { Result } from '../shared/result.js';
5
+ import type { UnitOfWork } from '../shared/unit-of-work.js';
6
+ import { type ReportTurnEndRefusal, type ReportTurnEndTx } from './report-turn-end.js';
7
+ export type ReportNotHandled = (crew: Crew, input: {
8
+ deliveryId: DeliveryId;
9
+ }) => Promise<Result<undefined, ReportTurnEndRefusal>>;
10
+ /**
11
+ * Use case: a pushed crew reports the turn a confirmed message was handed
12
+ * once more to died too (`notHandled`, decision 0040). Its scope
13
+ * (messages:receive) is checked before this runs. In one unit of work it
14
+ * holds the crew's lease, locks the delivery and moves it to not handled
15
+ * with DeliveryNotHandled, which puts it in Needs attention. Reporting it
16
+ * again is OK and changes nothing.
17
+ */
18
+ export declare function createReportNotHandled(deps: {
19
+ uow: UnitOfWork<ReportTurnEndTx>;
20
+ clock: Clock;
21
+ ids: IdGenerator;
22
+ }): ReportNotHandled;
@@ -0,0 +1,13 @@
1
+ import { reportTurnEnd } from './report-turn-end.js';
2
+ /**
3
+ * Use case: a pushed crew reports the turn a confirmed message was handed
4
+ * once more to died too (`notHandled`, decision 0040). Its scope
5
+ * (messages:receive) is checked before this runs. In one unit of work it
6
+ * holds the crew's lease, locks the delivery and moves it to not handled
7
+ * with DeliveryNotHandled, which puts it in Needs attention. Reporting it
8
+ * again is OK and changes nothing.
9
+ */
10
+ export function createReportNotHandled(deps) {
11
+ return (crew, input) => deps.uow.run((tx) => reportTurnEnd({ tx, clock: deps.clock, ids: deps.ids }, { crew, ...input, end: 'notHandled' }));
12
+ }
13
+ //# sourceMappingURL=report-not-handled.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report-not-handled.js","sourceRoot":"","sources":["../../../src/domain/messaging/report-not-handled.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,aAAa,EAAmD,MAAM,sBAAsB,CAAC;AAItG;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB,CAAC,IAA0E;IAC/G,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,aAAa,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,KAAK,EAAE,GAAG,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC;AAC/I,CAAC"}
@@ -0,0 +1,29 @@
1
+ import type { DeliveryId, IdGenerator } from '@aeolus-fleet/common';
2
+ import { type HoldLeaseTx, type LeaseEnded } from '../registry/public.js';
3
+ import type { Crew } from '../shared/caller.js';
4
+ import type { Clock } from '../shared/clock.js';
5
+ import { type DomainError } from '../shared/errors.js';
6
+ import { type EventLog } from '../shared/events.js';
7
+ import { type Result } from '../shared/result.js';
8
+ import { type TurnEnd, type TurnEndRefusal } from './delivery.js';
9
+ import type { DeliveryRepository } from './ports.js';
10
+ export interface ReportTurnEndTx extends HoldLeaseTx {
11
+ deliveries: Pick<DeliveryRepository, 'findForUpdate' | 'update'>;
12
+ events: EventLog;
13
+ }
14
+ export type ReportTurnEndRefusal = DomainError<'DELIVERY_NOT_FOUND'> | TurnEndRefusal | LeaseEnded;
15
+ /**
16
+ * The unit of work of handled and not handled, which differ only in how the
17
+ * turn ended: hold the crew's lease, so a release waits for it and an ended
18
+ * lease is refused; lock the delivery, so two reports take turns; apply the
19
+ * report and write its event.
20
+ */
21
+ export declare function reportTurnEnd(deps: {
22
+ tx: ReportTurnEndTx;
23
+ clock: Clock;
24
+ ids: IdGenerator;
25
+ }, report: {
26
+ crew: Crew;
27
+ deliveryId: DeliveryId;
28
+ end: TurnEnd;
29
+ }): Promise<Result<undefined, ReportTurnEndRefusal>>;