deepline 0.1.24 → 0.1.26

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.
@@ -0,0 +1,418 @@
1
+ import {
2
+ applyCsvRenameProjection,
3
+ type CsvRenameOptions,
4
+ } from '../../../../shared_libs/play-runtime/csv-rename';
5
+ import {
6
+ createDeferredPlayDataset,
7
+ isPlayDataset,
8
+ type PlayDataset,
9
+ type PlayDatasetInput,
10
+ type PlayDatasetKind,
11
+ type PlayDatasetWorkProgressSummary,
12
+ } from '../../../../shared_libs/plays/dataset';
13
+
14
+ export const WORKER_DATASET_PREVIEW_ROWS = 5;
15
+ export const WORKER_DATASET_IN_MEMORY_ROWS = 100;
16
+ const STREAM_MATERIALIZE_CHUNK_ROWS = 5_000;
17
+ const STREAM_ITERATE_CHUNK_ROWS = 1_000;
18
+
19
+ export type DatasetRow = Record<string, unknown>;
20
+ export type WorkerDatasetHandle<T extends DatasetRow> = PlayDataset<T>;
21
+ export type WorkerDatasetInput<T extends DatasetRow> = PlayDatasetInput<T>;
22
+
23
+ type DatasetChunkReader<T extends DatasetRow> = (
24
+ chunkSize: number,
25
+ ) => AsyncIterable<T[]>;
26
+
27
+ const datasetChunkReaders = new WeakMap<object, DatasetChunkReader<DatasetRow>>();
28
+ const datasetCountHints = new WeakMap<object, number | null>();
29
+
30
+ function cloneRow<T extends DatasetRow>(row: T): T {
31
+ return { ...row };
32
+ }
33
+
34
+ function registerChunkReader<T extends DatasetRow>(
35
+ dataset: PlayDataset<T>,
36
+ reader: DatasetChunkReader<T>,
37
+ countHint: number | null,
38
+ ): PlayDataset<T> {
39
+ datasetChunkReaders.set(
40
+ dataset as object,
41
+ reader as DatasetChunkReader<DatasetRow>,
42
+ );
43
+ datasetCountHints.set(dataset as object, countHint);
44
+ return dataset;
45
+ }
46
+
47
+ function normalizedChunkSize(chunkSize: number): number {
48
+ return Math.max(1, Math.floor(chunkSize));
49
+ }
50
+
51
+ export function createMaterializedDatasetHandle<T extends DatasetRow>(input: {
52
+ name: string;
53
+ rows: readonly T[];
54
+ datasetKind?: PlayDatasetKind;
55
+ count?: number;
56
+ sourceLabel?: string | null;
57
+ workProgress?: PlayDatasetWorkProgressSummary;
58
+ }): WorkerDatasetHandle<T> {
59
+ const datasetKind = input.datasetKind ?? 'map';
60
+ const materializedRows = input.rows.map(cloneRow);
61
+ const dataset = createDeferredPlayDataset({
62
+ datasetKind,
63
+ datasetId: `${datasetKind}:${input.name}`,
64
+ count: Math.max(0, Math.floor(input.count ?? materializedRows.length)),
65
+ previewRows: materializedRows
66
+ .slice(0, WORKER_DATASET_PREVIEW_ROWS)
67
+ .map(cloneRow),
68
+ sourceLabel: input.sourceLabel ?? null,
69
+ tableNamespace: input.name,
70
+ workProgress: input.workProgress,
71
+ resolvers: {
72
+ count: async () =>
73
+ Math.max(0, Math.floor(input.count ?? materializedRows.length)),
74
+ peek: async (limit) => materializedRows.slice(0, Math.max(0, limit)),
75
+ materialize: async (limit) =>
76
+ limit === undefined
77
+ ? materializedRows.map(cloneRow)
78
+ : materializedRows.slice(0, Math.max(0, limit)).map(cloneRow),
79
+ iterate: () =>
80
+ ({
81
+ async *[Symbol.asyncIterator]() {
82
+ for (const row of materializedRows) {
83
+ yield cloneRow(row);
84
+ }
85
+ },
86
+ }) as AsyncIterable<T>,
87
+ },
88
+ });
89
+ return registerChunkReader(
90
+ dataset,
91
+ async function* (chunkSize: number) {
92
+ const size = normalizedChunkSize(chunkSize);
93
+ for (let offset = 0; offset < materializedRows.length; offset += size) {
94
+ yield materializedRows.slice(offset, offset + size).map(cloneRow);
95
+ }
96
+ },
97
+ Math.max(0, Math.floor(input.count ?? materializedRows.length)),
98
+ );
99
+ }
100
+
101
+ export function createPersistedDatasetHandle<T extends DatasetRow>(input: {
102
+ playName: string;
103
+ name: string;
104
+ count: number;
105
+ datasetKind?: PlayDatasetKind;
106
+ previewRows?: readonly T[];
107
+ cachedRows?: readonly T[] | null;
108
+ sourceLabel?: string | null;
109
+ workProgress?: PlayDatasetWorkProgressSummary;
110
+ readRows: (input: { limit: number; offset: number }) => Promise<readonly T[]>;
111
+ trace?: (
112
+ phase: string,
113
+ ms: number,
114
+ extra?: Record<string, unknown>,
115
+ ) => void;
116
+ nowMs: () => number;
117
+ }): WorkerDatasetHandle<T> {
118
+ const datasetKind = input.datasetKind ?? 'map';
119
+ const count = Math.max(0, Math.floor(input.count));
120
+ const previewRows = (input.previewRows ?? [])
121
+ .slice(0, WORKER_DATASET_PREVIEW_ROWS)
122
+ .map(cloneRow);
123
+ const cachedRows =
124
+ input.cachedRows && input.cachedRows.length <= WORKER_DATASET_IN_MEMORY_ROWS
125
+ ? input.cachedRows.map(cloneRow)
126
+ : null;
127
+
128
+ async function loadRows(limit: number, offset: number): Promise<T[]> {
129
+ if (limit <= 0) {
130
+ return [];
131
+ }
132
+ const normalizedLimit = normalizedChunkSize(limit);
133
+ const normalizedOffset = Math.max(0, Math.floor(offset));
134
+ if (
135
+ cachedRows &&
136
+ normalizedOffset < cachedRows.length &&
137
+ normalizedOffset + normalizedLimit <= cachedRows.length
138
+ ) {
139
+ return cachedRows
140
+ .slice(normalizedOffset, normalizedOffset + normalizedLimit)
141
+ .map(cloneRow);
142
+ }
143
+ const startedAt = input.nowMs();
144
+ const rows = await input.readRows({
145
+ limit: normalizedLimit,
146
+ offset: normalizedOffset,
147
+ });
148
+ input.trace?.('dataset.read', input.nowMs() - startedAt, {
149
+ datasetKind,
150
+ playName: input.playName,
151
+ tableNamespace: input.name,
152
+ limit: normalizedLimit,
153
+ offset: normalizedOffset,
154
+ rows: rows.length,
155
+ });
156
+ return rows.map(cloneRow);
157
+ }
158
+
159
+ async function* readChunks(chunkSize: number): AsyncGenerator<T[], void, void> {
160
+ const size = normalizedChunkSize(chunkSize);
161
+ let offset = 0;
162
+ while (offset < count) {
163
+ const rows = await loadRows(Math.min(size, count - offset), offset);
164
+ if (rows.length === 0) {
165
+ return;
166
+ }
167
+ yield rows;
168
+ offset += rows.length;
169
+ }
170
+ }
171
+
172
+ const dataset = createDeferredPlayDataset({
173
+ datasetKind,
174
+ datasetId: `${datasetKind}:${input.name}`,
175
+ count,
176
+ backing: {
177
+ storage: 'neon_sheet',
178
+ sheet: {
179
+ playName: input.playName,
180
+ tableNamespace: input.name,
181
+ },
182
+ },
183
+ previewRows,
184
+ sourceLabel: input.sourceLabel ?? null,
185
+ tableNamespace: input.name,
186
+ workProgress: input.workProgress,
187
+ resolvers: {
188
+ count: async () => count,
189
+ peek: async (limit) => await loadRows(Math.max(0, limit), 0),
190
+ materialize: async (limit) => {
191
+ const rows: T[] = [];
192
+ const maxRows = limit ?? count;
193
+ for await (const chunk of readChunks(STREAM_MATERIALIZE_CHUNK_ROWS)) {
194
+ for (const row of chunk) {
195
+ if (rows.length >= maxRows) return rows;
196
+ rows.push(row);
197
+ }
198
+ }
199
+ return rows;
200
+ },
201
+ iterate: () =>
202
+ ({
203
+ async *[Symbol.asyncIterator]() {
204
+ for await (const chunk of readChunks(STREAM_ITERATE_CHUNK_ROWS)) {
205
+ for (const row of chunk) yield row;
206
+ }
207
+ },
208
+ }) as AsyncIterable<T>,
209
+ },
210
+ });
211
+ return registerChunkReader(dataset, (chunkSize) => readChunks(chunkSize), count);
212
+ }
213
+
214
+ export function createCsvDatasetHandle<T extends DatasetRow>(input: {
215
+ name: string;
216
+ logicalPath: string;
217
+ expectedBytes?: number | null;
218
+ renameOptions?: CsvRenameOptions;
219
+ open: () => Promise<AsyncIterable<Uint8Array> | null>;
220
+ streamRows: (
221
+ byteChunks: AsyncIterable<Uint8Array>,
222
+ chunkSize: number,
223
+ ) => AsyncIterable<T[]>;
224
+ trace?: (
225
+ phase: string,
226
+ ms: number,
227
+ extra?: Record<string, unknown>,
228
+ ) => void;
229
+ nowMs: () => number;
230
+ }): WorkerDatasetHandle<T> {
231
+ const datasetId = `csv:${input.name}`;
232
+ let cachedCount: number | null = null;
233
+
234
+ async function* readChunks(chunkSize: number): AsyncGenerator<T[], void, void> {
235
+ const startedAt = input.nowMs();
236
+ let yieldedRows = 0;
237
+ let yieldedChunks = 0;
238
+ let observedBytes = 0;
239
+ let observedByteChunks = 0;
240
+ const body = await input.open();
241
+ if (!body) {
242
+ throw new Error(
243
+ `ctx.csv("${input.logicalPath}"): dataset source is not reachable from the play runner.`,
244
+ );
245
+ }
246
+ const size = normalizedChunkSize(chunkSize);
247
+ const countedBody = {
248
+ async *[Symbol.asyncIterator]() {
249
+ for await (const chunk of body) {
250
+ observedBytes += chunk.byteLength;
251
+ observedByteChunks += 1;
252
+ yield chunk;
253
+ }
254
+ },
255
+ } satisfies AsyncIterable<Uint8Array>;
256
+ try {
257
+ for await (const chunk of input.streamRows(countedBody, size)) {
258
+ yieldedRows += chunk.length;
259
+ yieldedChunks += 1;
260
+ yield applyCsvRenameProjection(chunk, input.renameOptions) as T[];
261
+ }
262
+ } finally {
263
+ input.trace?.('csv.stream', input.nowMs() - startedAt, {
264
+ name: input.name,
265
+ logicalPath: input.logicalPath,
266
+ expectedBytes: input.expectedBytes ?? null,
267
+ observedBytes,
268
+ observedByteChunks,
269
+ yieldedRows,
270
+ yieldedChunks,
271
+ chunkSize: size,
272
+ });
273
+ }
274
+ if (
275
+ typeof input.expectedBytes === 'number' &&
276
+ input.expectedBytes > 0 &&
277
+ yieldedRows === 0
278
+ ) {
279
+ throw new Error(
280
+ observedBytes === 0
281
+ ? `ctx.csv("${input.logicalPath}"): dataset source yielded 0 bytes for ` +
282
+ `a non-empty ${input.expectedBytes} byte staged file.`
283
+ : `ctx.csv("${input.logicalPath}"): parsed 0 rows after reading ` +
284
+ `${observedBytes} bytes from a non-empty ${input.expectedBytes} byte dataset source.`,
285
+ );
286
+ }
287
+ }
288
+
289
+ const dataset = createDeferredPlayDataset({
290
+ datasetKind: 'csv',
291
+ datasetId,
292
+ count: 0,
293
+ previewRows: [],
294
+ tableNamespace: input.name,
295
+ resolvers: {
296
+ count: async () => {
297
+ if (cachedCount !== null) return cachedCount;
298
+ let total = 0;
299
+ for await (const chunk of readChunks(STREAM_MATERIALIZE_CHUNK_ROWS)) {
300
+ total += chunk.length;
301
+ }
302
+ cachedCount = total;
303
+ return total;
304
+ },
305
+ peek: async (limit) => {
306
+ const rows: T[] = [];
307
+ for await (const chunk of readChunks(Math.max(1, limit))) {
308
+ for (const row of chunk) {
309
+ rows.push(row);
310
+ if (rows.length >= limit) return rows;
311
+ }
312
+ }
313
+ return rows;
314
+ },
315
+ materialize: async (limit) => {
316
+ const rows: T[] = [];
317
+ const maxRows = limit ?? Number.POSITIVE_INFINITY;
318
+ for await (const chunk of readChunks(STREAM_MATERIALIZE_CHUNK_ROWS)) {
319
+ for (const row of chunk) {
320
+ if (rows.length >= maxRows) return rows;
321
+ rows.push(row);
322
+ }
323
+ }
324
+ return rows;
325
+ },
326
+ iterate: () =>
327
+ ({
328
+ async *[Symbol.asyncIterator]() {
329
+ for await (const chunk of readChunks(STREAM_ITERATE_CHUNK_ROWS)) {
330
+ for (const row of chunk) yield row;
331
+ }
332
+ },
333
+ }) as AsyncIterable<T>,
334
+ },
335
+ });
336
+ return registerChunkReader(dataset, (chunkSize) => readChunks(chunkSize), null);
337
+ }
338
+
339
+ export function createInlineDatasetHandle<T extends DatasetRow>(
340
+ rows: readonly T[],
341
+ metadata?: {
342
+ name?: string;
343
+ kind?: PlayDatasetKind;
344
+ sourceLabel?: string | null;
345
+ },
346
+ ): WorkerDatasetHandle<T> {
347
+ return createMaterializedDatasetHandle({
348
+ name: metadata?.name ?? 'csv',
349
+ rows,
350
+ datasetKind: metadata?.kind ?? 'csv',
351
+ sourceLabel: metadata?.sourceLabel ?? null,
352
+ });
353
+ }
354
+
355
+ export function datasetRowCountHint<T extends DatasetRow>(
356
+ input: WorkerDatasetInput<T>,
357
+ ): number | null {
358
+ if (Array.isArray(input)) return input.length;
359
+ if (isPlayDataset<T>(input)) {
360
+ const hinted = datasetCountHints.get(input as object);
361
+ if (hinted !== undefined) return hinted;
362
+ }
363
+ return null;
364
+ }
365
+
366
+ export function isDatasetHandle<T extends DatasetRow>(
367
+ value: unknown,
368
+ ): value is WorkerDatasetHandle<T> {
369
+ return isPlayDataset<T>(value);
370
+ }
371
+
372
+ export function iterDatasetChunks<T extends DatasetRow>(
373
+ input: WorkerDatasetInput<T>,
374
+ chunkSize: number,
375
+ ): AsyncIterable<T[]> {
376
+ const size = normalizedChunkSize(chunkSize);
377
+ if (isPlayDataset<T>(input)) {
378
+ const chunkReader = datasetChunkReaders.get(input as object);
379
+ if (chunkReader) {
380
+ return chunkReader(size) as AsyncIterable<T[]>;
381
+ }
382
+ }
383
+ return {
384
+ async *[Symbol.asyncIterator]() {
385
+ let chunk: T[] = [];
386
+ const flush = function* () {
387
+ if (chunk.length > 0) {
388
+ yield chunk;
389
+ chunk = [];
390
+ }
391
+ };
392
+ const push = function* (row: T) {
393
+ chunk.push(row);
394
+ if (chunk.length >= size) {
395
+ yield chunk;
396
+ chunk = [];
397
+ }
398
+ };
399
+
400
+ if (isPlayDataset<T>(input)) {
401
+ for await (const row of input) yield* push(row);
402
+ yield* flush();
403
+ return;
404
+ }
405
+ if (
406
+ input != null &&
407
+ typeof input === 'object' &&
408
+ Symbol.asyncIterator in input
409
+ ) {
410
+ for await (const row of input as AsyncIterable<T>) yield* push(row);
411
+ yield* flush();
412
+ return;
413
+ }
414
+ for (const row of input as Iterable<T>) yield* push(row);
415
+ yield* flush();
416
+ },
417
+ };
418
+ }
@@ -225,7 +225,11 @@ function updatePlayLiveStatusState(
225
225
  : state.runId;
226
226
  const status = normalizeLiveStatus(payload.status) ?? state.status;
227
227
  const logs = readStringArray(payload.logs);
228
- if (logs.length > 0 || event.type === 'play.run.snapshot') {
228
+ if (
229
+ logs.length > 0 ||
230
+ event.type === 'play.run.snapshot' ||
231
+ event.type === 'play.run.final_status'
232
+ ) {
229
233
  state.logs = logs;
230
234
  }
231
235
  if ('result' in payload) {
@@ -43,7 +43,7 @@ export {
43
43
  extractDefinedPlayName,
44
44
  } from '../../../shared_libs/plays/bundling/index.js';
45
45
 
46
- const PLAY_BUNDLE_CACHE_VERSION = 26;
46
+ const PLAY_BUNDLE_CACHE_VERSION = 30;
47
47
  const MODULE_DIR = dirname(fileURLToPath(import.meta.url));
48
48
  const SDK_PACKAGE_ROOT = resolve(MODULE_DIR, '..', '..');
49
49
  const SOURCE_REPO_ROOT = resolve(SDK_PACKAGE_ROOT, '..');
@@ -37,6 +37,10 @@ import type {
37
37
  RuntimeApiCallInput,
38
38
  RuntimeApiCallResult,
39
39
  RuntimePayloadSchemaId,
40
+ SheetDatasetRowsInput,
41
+ SheetDatasetRowsResult,
42
+ StagedFileChunkInput,
43
+ StagedFileChunkResult,
40
44
  ValidatePayloadResult,
41
45
  } from '../../../apps/play-harness-worker/src/rpc-types';
42
46
 
@@ -46,9 +50,6 @@ import type {
46
50
  * promise-returning RPC stubs; the type matches `PlayHarnessRpc`.
47
51
  */
48
52
  export type HarnessBinding = PlayHarnessRpc;
49
- type HarnessFetchBinding = HarnessBinding & {
50
- fetch(input: RequestInfo, init?: RequestInit): Promise<Response>;
51
- };
52
53
 
53
54
  /**
54
55
  * Module-level holder for the binding. Set by the per-play harness on
@@ -122,6 +123,24 @@ export async function harnessRuntimeApiCall(
122
123
  return requireBinding().runtimeApiCall(input);
123
124
  }
124
125
 
126
+ /**
127
+ * Read a bounded staged-file byte range through typed harness RPC. This is the
128
+ * only staged-file data path for per-play Workers; there is intentionally no
129
+ * HTTP fetch fallback because stale parallel paths caused empty CSV streams in
130
+ * preview.
131
+ */
132
+ export async function harnessReadStagedFileChunk(
133
+ input: StagedFileChunkInput,
134
+ ): Promise<StagedFileChunkResult> {
135
+ return requireBinding().readStagedFileChunk(input);
136
+ }
137
+
138
+ export async function harnessReadSheetDatasetRows(
139
+ input: SheetDatasetRowsInput,
140
+ ): Promise<SheetDatasetRowsResult> {
141
+ return requireBinding().readSheetDatasetRows(input);
142
+ }
143
+
125
144
  /**
126
145
  * Warm Postgres sessions in the long-lived harness Worker. This preserves the
127
146
  * map fast path without bundling the Neon client into every dynamic play.
@@ -145,6 +164,7 @@ export async function harnessStartSheetDataset(input: {
145
164
  sheetContract: unknown;
146
165
  rows: Array<Record<string, unknown>>;
147
166
  runId: string;
167
+ inputOffset?: number;
148
168
  userEmail?: string | null;
149
169
  preloadedDbSessions?: PreloadedRuntimeDbSessionInput[] | null;
150
170
  }): Promise<{
@@ -176,38 +196,6 @@ export async function harnessPersistCompletedSheetRows(input: {
176
196
  return requireBinding().persistCompletedMapRows(input);
177
197
  }
178
198
 
179
- /**
180
- * Stream a staged R2 object through the harness Worker. Unlike the legacy
181
- * signed-URL helper this never touches the Vercel runtime route, and it keeps
182
- * large CSV bodies as streams instead of serializing them through RPC.
183
- */
184
- export async function harnessFetchStagedFile(input: {
185
- executorToken: string;
186
- storageKey: string;
187
- method?: 'GET' | 'HEAD';
188
- range?: { offset: number; length: number };
189
- }): Promise<Response> {
190
- const binding = requireBinding() as HarnessFetchBinding;
191
- if (typeof binding.fetch !== 'function') {
192
- throw new Error(
193
- '[harness-stub] env.HARNESS does not expose fetch(); cannot stream staged R2 files through the harness.',
194
- );
195
- }
196
- const url = new URL('https://play-harness.internal/r2/staged-file');
197
- url.searchParams.set('storageKey', input.storageKey);
198
- const headers: Record<string, string> = {
199
- authorization: `Bearer ${input.executorToken}`,
200
- };
201
- if (input.range) {
202
- const end = input.range.offset + input.range.length - 1;
203
- headers.range = `bytes=${input.range.offset}-${end}`;
204
- }
205
- return binding.fetch(url.toString(), {
206
- method: input.method ?? 'GET',
207
- headers,
208
- });
209
- }
210
-
211
199
  /**
212
200
  * Validate a payload against a named schema. The schema definitions
213
201
  * (and zod itself) live in the harness Worker — see
@@ -1,2 +1,2 @@
1
- export const SDK_VERSION = "0.1.24";
1
+ export const SDK_VERSION = "0.1.26";
2
2
  export const SDK_API_CONTRACT = "2026-05-runs-v2";
@@ -126,13 +126,29 @@ export function buildExecutionPlan(
126
126
  }
127
127
 
128
128
  export function chooseMapChunkSize(input: {
129
- totalRows: number;
129
+ /**
130
+ * Known input row count. Pass null for streaming datasets where counting
131
+ * would require an extra full scan; unknown counts use the preferred chunk.
132
+ */
133
+ totalRows: number | null;
130
134
  mapCount: number;
131
135
  stepsPerChunk: number;
132
136
  preferredChunkSize?: number | null;
133
137
  softWorkflowStepBudget?: number | null;
134
138
  }): number {
135
- const totalRows = Math.max(0, Math.floor(input.totalRows));
139
+ const totalRows =
140
+ typeof input.totalRows === 'number' && Number.isFinite(input.totalRows)
141
+ ? Math.max(0, Math.floor(input.totalRows))
142
+ : null;
143
+ const preferred = Math.max(
144
+ 1,
145
+ Math.floor(
146
+ input.preferredChunkSize ?? EXECUTION_PLAN_DEFAULTS.largeMapChunkSize,
147
+ ),
148
+ );
149
+ if (totalRows === null) {
150
+ return preferred;
151
+ }
136
152
  if (totalRows <= EXECUTION_PLAN_DEFAULTS.inlineRowsLimit) {
137
153
  return Math.max(1, totalRows || 1);
138
154
  }
@@ -157,12 +173,6 @@ export function chooseMapChunkSize(input: {
157
173
  1,
158
174
  Math.ceil(totalRows / maxChunksPerMap),
159
175
  );
160
- const preferred = Math.max(
161
- 1,
162
- Math.floor(
163
- input.preferredChunkSize ?? EXECUTION_PLAN_DEFAULTS.largeMapChunkSize,
164
- ),
165
- );
166
176
  return Math.max(preferred, minimumSurvivalChunkSize);
167
177
  }
168
178
 
@@ -52,13 +52,14 @@ export type PlaySchedulerSubmitInput = {
52
52
  storageKey?: string;
53
53
  fileName?: string;
54
54
  logicalPath?: string;
55
+ contentType?: string;
56
+ bytes?: number;
55
57
  } | null;
56
58
  inlineCsv?: { name: string; rows: Record<string, unknown>[] } | null;
57
59
  /**
58
- * Tiny input files (<= WORKERS_EDGE_INLINE_INPUT_MAX_BYTES) carried as raw
59
- * base64 bytes through the scheduler submit so the cf-workflows backend can
60
- * build inlineCsv without an R2 PUT+GET round trip. Mirrors the
61
- * Temporal-side `inlineInputFile` fast path.
60
+ * Temporal-only escape hatch for small legacy inputs. Workers-edge CSV
61
+ * inputs must be staged and streamed by handle instead of carried as raw
62
+ * scheduler payload bytes.
62
63
  */
63
64
  inlineInputFile?: {
64
65
  logicalPath: string;