@vzn/vx-dte 0.0.650 → 0.0.652

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.
package/src/messages.ts CHANGED
@@ -2,15 +2,7 @@
2
2
  // (the relay never reads it): orders and status only. Every task's files
3
3
  // and output go through the workspace's cache, by the keys these name.
4
4
 
5
- import type { CacheFacts, CapturedChunk, ExecuteResult, SandboxConfig } from '@vzn/vx'
6
-
7
- /**
8
- * A worker says what it holds every this many heartbeats, and a task's
9
- * lease is three of them. Every heartbeat (2026-10-25: the fastest, not
10
- * a free plan's message count): a task its worker dropped while alive
11
- * goes back in 15 s, not 90.
12
- */
13
- export const HELD_EVERY = 1
5
+ import type { CacheFacts, ExecuteResult, SandboxConfig } from '@vzn/vx'
14
6
 
15
7
  /** A worker's `join` info. */
16
8
  export interface WorkerInfo {
@@ -72,15 +64,25 @@ export interface RunOrder {
72
64
  /**
73
65
  * Its `exec.sandbox`, and for a cached task the projects its key answers
74
66
  * for (workspace-relative): the worker builds the request on its own
75
- * paths and OS (`sandboxRequestFor`), as its orchestrator may run another.
67
+ * paths and OS (`sandboxRequestFor`), as its orchestrator may run another;
68
+ * `reads`, the dependencies' outputs it may read (workspace-relative).
76
69
  */
77
- sandbox?: { config: SandboxConfig; keyed?: string[] }
70
+ sandbox?: { config: SandboxConfig; keyed?: string[]; reads?: string[] }
78
71
  /** Its persistent dependencies (`ServerSpec`), `cwd` workspace-relative: the worker starts each once. */
79
72
  servers?: ServerOrder[]
80
73
  /** The runtime probes its key includes, as the orchestrator answered them: the worker's must answer the same. */
81
74
  runtime?: RuntimeOrder[]
82
75
  }
83
76
 
77
+ /**
78
+ * A dependency as an order carries it: whole the first time its worker is
79
+ * sent it under that key, then by its task's name alone.
80
+ */
81
+ export type WiredDep = DepOrder | string
82
+
83
+ /** A `RunOrder` as it travels: its deps `WiredDep`s, made whole again by the worker. */
84
+ export type SentOrder = Omit<RunOrder, 'deps'> & { deps: WiredDep[] }
85
+
84
86
  export interface RuntimeOrder {
85
87
  command: string
86
88
  output: string
@@ -100,18 +102,22 @@ export interface ServerOrder {
100
102
  }
101
103
 
102
104
  export type ToWorker =
103
- /** Tasks that fit what it has free, each begun at once; `root` is swapped for the worker's in `env`. */
105
+ /**
106
+ * Tasks that fit what it has free: taken, each runs at once. `n` counts
107
+ * its batches, so its report says which it had read.
108
+ */
104
109
  | {
105
110
  type: 'batch'
111
+ n: number
106
112
  root: string
107
113
  /** `root`'s real path, as sandbox paths spell it. */
108
114
  realRoot: string
109
- tasks: RunOrder[]
115
+ tasks: SentOrder[]
110
116
  /** The run's sandboxed tasks' `exec.sandbox`, in a worker's first batch that has a sandboxed task. */
111
117
  sandboxes?: SandboxConfig[]
112
118
  }
113
119
  /** Part of an order's `deps`, ahead of the batch whose order was too long for one frame. */
114
- | { type: 'deps'; task: string; deps: DepOrder[] }
120
+ | { type: 'deps'; task: string; deps: WiredDep[] }
115
121
  | { type: 'cancel'; task: string }
116
122
  /**
117
123
  * It was taken into the run, under the name the run's output gives it,
@@ -146,26 +152,48 @@ export interface Load {
146
152
  * `cpu` (one that sent 3, each as a task started, read 0.6 of 2.0 used).
147
153
  */
148
154
  readonly avg?: number
155
+ /** When it was read, by the worker's clock: its task times are read against it. */
156
+ readonly at?: number
157
+ }
158
+
159
+ /** A task's times on its worker, epoch ms by the worker's clock: begun, command ended. */
160
+ export interface Ran {
161
+ readonly startedAt: number
162
+ readonly ranAt: number
149
163
  }
150
164
 
151
165
  export type ToOrchestrator =
152
- /** It began the task. */
153
- | { type: 'start'; task: string; load?: Load }
154
- /** Its command is done; its outputs save now, its cores are free. */
155
- | { type: 'ran'; task: string; load?: Load }
156
- /** Each heartbeat while it runs any: what it runs, which renews its lease on each. */
157
- | { type: 'held'; running: string[]; load?: Load }
166
+ /**
167
+ * Its command is done; its outputs save now, its cores are free. Never
168
+ * sent alone: it rides the next message, or its `end` says it.
169
+ */
170
+ | ({ type: 'ran'; task: string; load?: Load } & Ran)
171
+ /**
172
+ * A heartbeat with nothing else said: what it runs, the last batch it
173
+ * read, its live load. A task of that batch or before it no longer
174
+ * names goes back.
175
+ */
176
+ | { type: 'report'; running: string[]; batch: number; load: Load }
177
+ /** Messages said at one moment, as one frame: waiting `ran`s and the event they ride. */
178
+ | { type: 'together'; messages: ToOrchestrator[] }
158
179
  /** It could not run a task it began, not a non-zero exit: a full disk, a failed unpack. */
159
- | { type: 'fault'; task: string; reason: string }
180
+ | { type: 'fault'; task: string; reason: string; load?: Load }
160
181
  /** It ran the task and saved it under `key`; its output is in that entry. */
161
- | { type: 'end'; task: string; key: string; result: WiredResult; load?: Load }
182
+ | ({
183
+ type: 'end'
184
+ task: string
185
+ key: string
186
+ result: WiredResult
187
+ endedAt: number
188
+ load?: Load
189
+ } & Ran)
162
190
  /**
163
191
  * Ahead of an `end` too long for one relay frame, some of its lists:
164
192
  * the `end` that follows adds its own to them. One `end` with a sandboxed
165
193
  * task's 9000 violations was over the relay's 1 MiB, and the run waited
166
194
  * for it (2026-10-25).
167
195
  */
168
- | ({ type: 'part'; task: string } & Partial<Pick<WiredResult, PartList>>)
196
+ | ({ type: 'part'; task: string; load?: Load } & Partial<Pick<WiredResult, PartList>>)
169
197
 
170
198
  /**
171
199
  * A message's JSON in UTF-8 bytes, what a relay frame holds: counted in
@@ -175,7 +203,7 @@ export type ToOrchestrator =
175
203
  export const bytesOf = (body: unknown): number => Buffer.byteLength(JSON.stringify(body))
176
204
 
177
205
  /** The lists a long result sends ahead of its `end`, in parts. */
178
- export const PART_LISTS = ['violations', 'changed', 'removed', 'output'] as const
206
+ export const PART_LISTS = ['violations', 'changed', 'removed'] as const
179
207
  export type PartList = (typeof PART_LISTS)[number]
180
208
 
181
209
  /** A result as JSON carries it: its output stays in the cache entry, and a violation's time is a string. */
@@ -187,13 +215,6 @@ export type WiredResult = Omit<ExecuteResult, 'violations' | 'outputs' | 'stdout
187
215
  removed?: string[]
188
216
  /** Dependency keys whose remote copy did not read back: this machine sends its own over them. */
189
217
  unread?: string[]
190
- /**
191
- * No remote took its entry's upload (too big, a 429): its files are on
192
- * that worker alone, and its output comes here in `output`.
193
- */
194
- unshared?: true
195
- /** Its output, both streams in the order written, when `unshared`. */
196
- output?: CapturedChunk[]
197
218
  }
198
219
 
199
220
  /**