@atolis-hq/wake 0.3.77 → 0.3.78

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.
@@ -4,7 +4,7 @@ import { correlationId, EventActorKind } from '../kernel/index.js';
4
4
  import { ApiCommandStatus, presentRun } from '../surfaces/index.js';
5
5
  import { projectionMeta, sampledMeta } from './surface-api-metadata.js';
6
6
  import { projectionPage } from './surface-api-projection-pages.js';
7
- import { withWorkflowContext } from './surface-api-run-context.js';
7
+ import { enrichRun } from './surface-api-run-context.js';
8
8
  import { readWorkTranscript } from './surface-api-transcripts.js';
9
9
  export function createExecutionApplications(root, now) {
10
10
  return {
@@ -43,7 +43,7 @@ export function createExecutionApplications(root, now) {
43
43
  });
44
44
  return {
45
45
  ...page,
46
- items: await Promise.all(page.items.map((item) => withWorkflowContext(root, item))),
46
+ items: await Promise.all(page.items.map((item) => enrichRun(root, item))),
47
47
  };
48
48
  },
49
49
  async get(runId) {
@@ -51,7 +51,7 @@ export function createExecutionApplications(root, now) {
51
51
  if (stored?.value.view == null)
52
52
  return undefined;
53
53
  return {
54
- data: await withWorkflowContext(root, presentRun(stored.value.view)),
54
+ data: await enrichRun(root, presentRun(stored.value.view)),
55
55
  meta: await projectionMeta(root.journal, [stored], now()),
56
56
  };
57
57
  },
@@ -1,5 +1,49 @@
1
+ import { ActivityOutcomeKind } from '../activities/index.js';
2
+ import { DeliveryState, IntegrationStreamKind, } from '../integrations/index.js';
1
3
  import { workflowInstanceId } from '../orchestration/index.js';
2
4
  export async function withWorkflowContext(root, run) {
3
5
  const instance = await root.orchestration.get(workflowInstanceId(run.workflowInstanceId));
4
6
  return instance === null ? run : { ...run, workflowName: instance.workflowName };
5
7
  }
8
+ const deliveryResolutionSentinels = {
9
+ [DeliveryState.Confirmed]: 'DONE',
10
+ [DeliveryState.Failed]: 'FAILED',
11
+ [DeliveryState.Ambiguous]: 'AMBIGUOUS',
12
+ };
13
+ /**
14
+ * A run whose own outcome was `waiting` on a delivery is frozen at that
15
+ * sentinel forever (the run itself never re-fires once terminal). Join it
16
+ * against the delivery intent it named to surface how that delivery has
17
+ * since resolved, without rewriting the run's own history.
18
+ */
19
+ export async function withDeliveryResolution(root, run) {
20
+ const intentEventId = waitingDeliveryIntentEventId(run);
21
+ if (intentEventId === undefined)
22
+ return run;
23
+ const stored = await root.projections.read(IntegrationStreamKind.Delivery, intentEventId);
24
+ const delivery = stored?.value;
25
+ if (delivery === undefined || delivery.resolvedAt === undefined)
26
+ return run;
27
+ const sentinel = deliveryResolutionSentinels[delivery.state];
28
+ return sentinel === undefined
29
+ ? run
30
+ : { ...run, resolution: { sentinel, resolvedAt: delivery.resolvedAt } };
31
+ }
32
+ /** Full read-time enrichment applied to every presented run. */
33
+ export async function enrichRun(root, run) {
34
+ return withDeliveryResolution(root, await withWorkflowContext(root, run));
35
+ }
36
+ function waitingDeliveryIntentEventId(run) {
37
+ if (typeof run.outcome !== 'object' || run.outcome === null)
38
+ return undefined;
39
+ if (Reflect.get(run.outcome, 'kind') !== ActivityOutcomeKind.Waiting)
40
+ return undefined;
41
+ const data = Reflect.get(run.outcome, 'data');
42
+ if (typeof data !== 'object' || data === null)
43
+ return undefined;
44
+ const intentEventId = Reflect.get(data, 'intentEventId');
45
+ const signalKind = Reflect.get(data, 'signalKind');
46
+ return typeof intentEventId === 'string' && signalKind === 'delivery-result'
47
+ ? intentEventId
48
+ : undefined;
49
+ }
@@ -8,7 +8,7 @@ import { workItemId, WorkStatus } from '../work/index.js';
8
8
  import { primaryExternalRef } from './external-ref.js';
9
9
  import { projectionMeta } from './surface-api-metadata.js';
10
10
  import { projectionPage } from './surface-api-projection-pages.js';
11
- import { withWorkflowContext } from './surface-api-run-context.js';
11
+ import { enrichRun } from './surface-api-run-context.js';
12
12
  import { readWorkTranscript, transcriptGroups } from './surface-api-transcripts.js';
13
13
  export function createSurfaceWorkApplications(root, now) {
14
14
  return {
@@ -115,7 +115,7 @@ async function workDetail(root, key, now) {
115
115
  .map(presentWorkflowInstance),
116
116
  },
117
117
  execution: {
118
- runs: await Promise.all(runs.map((run) => withWorkflowContext(root, presentRun(run)))),
118
+ runs: await Promise.all(runs.map((run) => enrichRun(root, presentRun(run)))),
119
119
  transcriptGroups: await transcriptGroups(root.transcriptStore, id, runs),
120
120
  },
121
121
  activities: presentPullRequest(pullRequest?.value),
@@ -108,4 +108,4 @@ export function resolveWakeVersion(options = {}) {
108
108
  return `g${headHash.slice(0, 7)}`;
109
109
  return '0.1.0-dev';
110
110
  }
111
- export const wakeVersion = "gd101844";
111
+ export const wakeVersion = "g8656e9f";
@@ -161,20 +161,26 @@ function foldDeliveryFact(previous, delivery) {
161
161
  case DeliveryEventType.AttemptStarted:
162
162
  return { ...current, attempts: current.attempts + 1 };
163
163
  case DeliveryEventType.Confirmed:
164
- return { ...current, state: DeliveryState.Confirmed };
164
+ return { ...current, state: DeliveryState.Confirmed, resolvedAt: delivery.occurredAt };
165
165
  case DeliveryEventType.Failed:
166
- return { ...current, state: DeliveryState.Failed };
166
+ return { ...current, state: DeliveryState.Failed, resolvedAt: delivery.occurredAt };
167
167
  case DeliveryEventType.Ambiguous:
168
168
  return {
169
169
  ...current,
170
170
  state: DeliveryState.Ambiguous,
171
+ resolvedAt: delivery.occurredAt,
171
172
  reconciliationKey: delivery.payload.reconciliationKey,
172
173
  };
173
174
  case DeliveryEventType.Escalated:
174
175
  return { ...current, escalation: { reason: delivery.payload.reason } };
175
176
  case DeliveryEventType.Reconciled:
176
177
  if (delivery.payload.result === DeliveryResultKind.Confirmed)
177
- return { ...current, state: DeliveryState.Confirmed, escalation: undefined };
178
+ return {
179
+ ...current,
180
+ state: DeliveryState.Confirmed,
181
+ resolvedAt: delivery.occurredAt,
182
+ escalation: undefined,
183
+ };
178
184
  return delivery.payload.result === DeliveryResultKind.Unknown
179
185
  ? { ...current, reconciliationAttempts: (current.reconciliationAttempts ?? 0) + 1 }
180
186
  : current;