deepline 0.1.243 → 0.1.244
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/README.md +1 -1
- package/dist/bundling-sources/sdk/src/plays/bundle-play-file.ts +5 -25
- package/dist/bundling-sources/sdk/src/release.ts +23 -21
- package/dist/bundling-sources/sdk/src/types.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/backend.ts +2 -21
- package/dist/bundling-sources/shared_libs/play-runtime/governor/governor.ts +5 -6
- package/dist/bundling-sources/shared_libs/play-runtime/governor/policy.ts +6 -13
- package/dist/bundling-sources/shared_libs/play-runtime/governor/rate-state-backend.ts +9 -26
- package/dist/bundling-sources/shared_libs/play-runtime/internal-step-ids.ts +1 -2
- package/dist/bundling-sources/shared_libs/play-runtime/map-row-identity.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/output-size-limits.ts +191 -29
- package/dist/bundling-sources/shared_libs/play-runtime/play-latency-trace.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/providers.ts +1 -36
- package/dist/bundling-sources/shared_libs/play-runtime/run-ledger.ts +2 -3
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/index.ts +0 -7
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +1 -12
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-pg-driver-pg.ts +2 -3
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-pg-driver.ts +5 -15
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backend.ts +6 -21
- package/dist/bundling-sources/shared_libs/play-runtime/tool-result.ts +3 -4
- package/dist/bundling-sources/shared_libs/plays/artifact-kind-guard.ts +16 -29
- package/dist/bundling-sources/shared_libs/plays/artifact-types.ts +4 -8
- package/dist/bundling-sources/shared_libs/plays/bundling/index.ts +21 -712
- package/dist/bundling-sources/shared_libs/plays/bundling/limits.ts +1 -18
- package/dist/cli/index.js +29 -71
- package/dist/cli/index.mjs +29 -71
- package/dist/{compiler-manifest-CYcwzSOJ.d.ts → compiler-manifest-DlE7dnRm.d.mts} +2 -8
- package/dist/{compiler-manifest-CYcwzSOJ.d.mts → compiler-manifest-DlE7dnRm.d.ts} +2 -8
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +24 -22
- package/dist/index.mjs +24 -22
- package/dist/plays/bundle-play-file.d.mts +7 -22
- package/dist/plays/bundle-play-file.d.ts +7 -22
- package/dist/plays/bundle-play-file.mjs +26 -614
- package/package.json +2 -2
- package/dist/bundling-sources/apps/play-runner-workers/src/coordinator-entry.ts +0 -4504
- package/dist/bundling-sources/apps/play-runner-workers/src/dedup-do.ts +0 -1386
- package/dist/bundling-sources/apps/play-runner-workers/src/durable-object-deploy-handoff.ts +0 -30
- package/dist/bundling-sources/apps/play-runner-workers/src/entry.ts +0 -8385
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/README.md +0 -21
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/batching.ts +0 -251
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/coordinator-progress.ts +0 -289
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/csv-rows.ts +0 -85
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/customer-console.ts +0 -23
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/dataset-handles.ts +0 -528
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/harness-receipt-store.ts +0 -229
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/ledger-event-batches.ts +0 -81
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/live-progress.ts +0 -22
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/map-chunk-plan.ts +0 -920
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/map-latency-profile.ts +0 -90
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/output-datasets.ts +0 -475
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/receipts.ts +0 -570
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/result-dataset-persistence.ts +0 -50
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/row-isolation.ts +0 -5
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/run-work-dispatcher.ts +0 -519
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/tool-batch.ts +0 -107
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/tool-dispatch.ts +0 -2541
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/tool-http-errors.ts +0 -7
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/tool-receipts.ts +0 -227
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/work-budget.ts +0 -130
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/worker-platform-budget.ts +0 -39
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/workflow-preview.ts +0 -26
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime-api-retry.ts +0 -23
- package/dist/bundling-sources/apps/play-runner-workers/src/workflow-instance-create.ts +0 -47
- package/dist/bundling-sources/apps/play-runner-workers/src/workflow-retry-state.ts +0 -167
- package/dist/bundling-sources/apps/play-runner-workers/src/workflow-retry.ts +0 -91
- package/dist/bundling-sources/sdk/src/plays/harness-stub.ts +0 -329
- package/dist/bundling-sources/sdk/src/worker-play-entry.ts +0 -240
- package/dist/bundling-sources/shared_libs/play-runtime/governor/coordinator-rate-state-backend.ts +0 -252
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-pg-driver-neon-serverless.ts +0 -217
|
@@ -1,528 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
applyCsvRenameProjection,
|
|
3
|
-
cloneCsvAliasedRow,
|
|
4
|
-
stripCsvProjectedFields,
|
|
5
|
-
type CsvRenameOptions,
|
|
6
|
-
} from '../../../../shared_libs/play-runtime/csv-rename';
|
|
7
|
-
import {
|
|
8
|
-
createDeferredPlayDataset,
|
|
9
|
-
isPlayDataset,
|
|
10
|
-
type PlayDataset,
|
|
11
|
-
type PlayDatasetInput,
|
|
12
|
-
type PlayDatasetKind,
|
|
13
|
-
type PlayDatasetWorkProgressSummary,
|
|
14
|
-
} from '../../../../shared_libs/plays/dataset';
|
|
15
|
-
|
|
16
|
-
export const WORKER_DATASET_PREVIEW_ROWS = 5;
|
|
17
|
-
export const WORKER_DATASET_IN_MEMORY_ROWS = 100;
|
|
18
|
-
const STREAM_MATERIALIZE_CHUNK_ROWS = 5_000;
|
|
19
|
-
const STREAM_ITERATE_CHUNK_ROWS = 1_000;
|
|
20
|
-
|
|
21
|
-
export type DatasetRow = Record<string, unknown>;
|
|
22
|
-
export type WorkerDatasetHandle<T extends DatasetRow> = PlayDataset<T>;
|
|
23
|
-
export type WorkerDatasetInput<T extends DatasetRow> = PlayDatasetInput<T>;
|
|
24
|
-
|
|
25
|
-
type DatasetChunkReader<T extends DatasetRow> = (
|
|
26
|
-
chunkSize: number,
|
|
27
|
-
) => AsyncIterable<T[]>;
|
|
28
|
-
|
|
29
|
-
export type WorkerDatasetCapabilities = {
|
|
30
|
-
storage: 'materialized' | 'runtime_sheet' | 'csv_stream' | 'iterable';
|
|
31
|
-
chunkReadable: boolean;
|
|
32
|
-
pageBacked: boolean;
|
|
33
|
-
replayable: boolean;
|
|
34
|
-
countHint: number | null;
|
|
35
|
-
materialization: 'bounded' | 'in_memory';
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
const datasetChunkReaders = new WeakMap<
|
|
39
|
-
object,
|
|
40
|
-
DatasetChunkReader<DatasetRow>
|
|
41
|
-
>();
|
|
42
|
-
const datasetCountHints = new WeakMap<object, number | null>();
|
|
43
|
-
const datasetCapabilities = new WeakMap<object, WorkerDatasetCapabilities>();
|
|
44
|
-
|
|
45
|
-
function cloneRow<T extends DatasetRow>(row: T): T {
|
|
46
|
-
const cloned: DatasetRow = {};
|
|
47
|
-
for (const key of Reflect.ownKeys(row)) {
|
|
48
|
-
const descriptor = Object.getOwnPropertyDescriptor(row, key);
|
|
49
|
-
if (!descriptor) continue;
|
|
50
|
-
Object.defineProperty(cloned, key, descriptor);
|
|
51
|
-
}
|
|
52
|
-
return cloned as T;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
function internalDatasetRow<T extends DatasetRow>(row: T): T {
|
|
56
|
-
const stripped = cloneCsvAliasedRow(row);
|
|
57
|
-
const publicRow: DatasetRow = {};
|
|
58
|
-
for (const key of Reflect.ownKeys(stripped)) {
|
|
59
|
-
if (
|
|
60
|
-
typeof key === 'string' &&
|
|
61
|
-
/^__deepline(?!CsvProjectedValues$)/.test(key)
|
|
62
|
-
) {
|
|
63
|
-
continue;
|
|
64
|
-
}
|
|
65
|
-
const descriptor = Object.getOwnPropertyDescriptor(stripped, key);
|
|
66
|
-
if (!descriptor) continue;
|
|
67
|
-
Object.defineProperty(publicRow, key, descriptor);
|
|
68
|
-
}
|
|
69
|
-
return publicRow as T;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
function materializedDatasetRow<T extends DatasetRow>(row: T): T {
|
|
73
|
-
const stripped = stripCsvProjectedFields(row) as DatasetRow;
|
|
74
|
-
return Object.fromEntries(
|
|
75
|
-
Object.entries(stripped).filter(([key]) => !key.startsWith('__deepline')),
|
|
76
|
-
) as T;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
function registerChunkReader<T extends DatasetRow>(
|
|
80
|
-
dataset: PlayDataset<T>,
|
|
81
|
-
reader: DatasetChunkReader<T>,
|
|
82
|
-
countHint: number | null,
|
|
83
|
-
capabilities: Omit<WorkerDatasetCapabilities, 'countHint'>,
|
|
84
|
-
): PlayDataset<T> {
|
|
85
|
-
datasetChunkReaders.set(
|
|
86
|
-
dataset as object,
|
|
87
|
-
reader as DatasetChunkReader<DatasetRow>,
|
|
88
|
-
);
|
|
89
|
-
datasetCountHints.set(dataset as object, countHint);
|
|
90
|
-
datasetCapabilities.set(dataset as object, { ...capabilities, countHint });
|
|
91
|
-
return dataset;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
function normalizedChunkSize(chunkSize: number): number {
|
|
95
|
-
return Math.max(1, Math.floor(chunkSize));
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
export function createMaterializedDatasetHandle<T extends DatasetRow>(input: {
|
|
99
|
-
name: string;
|
|
100
|
-
rows: readonly T[];
|
|
101
|
-
datasetKind?: PlayDatasetKind;
|
|
102
|
-
count?: number;
|
|
103
|
-
sourceLabel?: string | null;
|
|
104
|
-
workProgress?: PlayDatasetWorkProgressSummary;
|
|
105
|
-
}): WorkerDatasetHandle<T> {
|
|
106
|
-
const datasetKind = input.datasetKind ?? 'map';
|
|
107
|
-
const materializedRows = input.rows.map(cloneRow);
|
|
108
|
-
const dataset = createDeferredPlayDataset({
|
|
109
|
-
datasetKind,
|
|
110
|
-
datasetId: `${datasetKind}:${input.name}`,
|
|
111
|
-
count: Math.max(0, Math.floor(input.count ?? materializedRows.length)),
|
|
112
|
-
previewRows: materializedRows
|
|
113
|
-
.slice(0, WORKER_DATASET_PREVIEW_ROWS)
|
|
114
|
-
.map(cloneRow),
|
|
115
|
-
sourceLabel: input.sourceLabel ?? null,
|
|
116
|
-
tableNamespace: input.name,
|
|
117
|
-
workProgress: input.workProgress,
|
|
118
|
-
resolvers: {
|
|
119
|
-
count: async () =>
|
|
120
|
-
Math.max(0, Math.floor(input.count ?? materializedRows.length)),
|
|
121
|
-
peek: async (limit) => materializedRows.slice(0, Math.max(0, limit)),
|
|
122
|
-
materialize: async (limit) =>
|
|
123
|
-
limit === undefined
|
|
124
|
-
? materializedRows.map(cloneRow)
|
|
125
|
-
: materializedRows.slice(0, Math.max(0, limit)).map(cloneRow),
|
|
126
|
-
iterate: () =>
|
|
127
|
-
({
|
|
128
|
-
async *[Symbol.asyncIterator]() {
|
|
129
|
-
for (const row of materializedRows) {
|
|
130
|
-
yield cloneRow(row);
|
|
131
|
-
}
|
|
132
|
-
},
|
|
133
|
-
}) as AsyncIterable<T>,
|
|
134
|
-
},
|
|
135
|
-
});
|
|
136
|
-
return registerChunkReader(
|
|
137
|
-
dataset,
|
|
138
|
-
async function* (chunkSize: number) {
|
|
139
|
-
const size = normalizedChunkSize(chunkSize);
|
|
140
|
-
for (let offset = 0; offset < materializedRows.length; offset += size) {
|
|
141
|
-
yield materializedRows.slice(offset, offset + size).map(cloneRow);
|
|
142
|
-
}
|
|
143
|
-
},
|
|
144
|
-
Math.max(0, Math.floor(input.count ?? materializedRows.length)),
|
|
145
|
-
{
|
|
146
|
-
storage: 'materialized',
|
|
147
|
-
chunkReadable: true,
|
|
148
|
-
pageBacked: false,
|
|
149
|
-
replayable: true,
|
|
150
|
-
materialization: 'in_memory',
|
|
151
|
-
},
|
|
152
|
-
);
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
export function createPersistedDatasetHandle<T extends DatasetRow>(input: {
|
|
156
|
-
playName: string;
|
|
157
|
-
name: string;
|
|
158
|
-
count: number;
|
|
159
|
-
datasetKind?: PlayDatasetKind;
|
|
160
|
-
previewRows?: readonly T[];
|
|
161
|
-
cachedRows?: readonly T[] | null;
|
|
162
|
-
sourceLabel?: string | null;
|
|
163
|
-
workProgress?: PlayDatasetWorkProgressSummary;
|
|
164
|
-
readRows: (input: { limit: number; offset: number }) => Promise<readonly T[]>;
|
|
165
|
-
trace?: (phase: string, ms: number, extra?: Record<string, unknown>) => void;
|
|
166
|
-
nowMs: () => number;
|
|
167
|
-
}): WorkerDatasetHandle<T> {
|
|
168
|
-
const datasetKind = input.datasetKind ?? 'map';
|
|
169
|
-
const count = Math.max(0, Math.floor(input.count));
|
|
170
|
-
const previewRows = (input.previewRows ?? [])
|
|
171
|
-
.slice(0, WORKER_DATASET_PREVIEW_ROWS)
|
|
172
|
-
.map(materializedDatasetRow);
|
|
173
|
-
const cachedRows =
|
|
174
|
-
input.cachedRows && input.cachedRows.length <= WORKER_DATASET_IN_MEMORY_ROWS
|
|
175
|
-
? input.cachedRows.map(internalDatasetRow)
|
|
176
|
-
: null;
|
|
177
|
-
|
|
178
|
-
async function loadRows(limit: number, offset: number): Promise<T[]> {
|
|
179
|
-
if (limit <= 0) {
|
|
180
|
-
return [];
|
|
181
|
-
}
|
|
182
|
-
const normalizedLimit = normalizedChunkSize(limit);
|
|
183
|
-
const normalizedOffset = Math.max(0, Math.floor(offset));
|
|
184
|
-
if (
|
|
185
|
-
cachedRows &&
|
|
186
|
-
normalizedOffset < cachedRows.length &&
|
|
187
|
-
normalizedOffset + normalizedLimit <= cachedRows.length
|
|
188
|
-
) {
|
|
189
|
-
return cachedRows
|
|
190
|
-
.slice(normalizedOffset, normalizedOffset + normalizedLimit)
|
|
191
|
-
.map(internalDatasetRow);
|
|
192
|
-
}
|
|
193
|
-
const startedAt = input.nowMs();
|
|
194
|
-
const rows = await input.readRows({
|
|
195
|
-
limit: normalizedLimit,
|
|
196
|
-
offset: normalizedOffset,
|
|
197
|
-
});
|
|
198
|
-
input.trace?.('dataset.read', input.nowMs() - startedAt, {
|
|
199
|
-
datasetKind,
|
|
200
|
-
playName: input.playName,
|
|
201
|
-
tableNamespace: input.name,
|
|
202
|
-
limit: normalizedLimit,
|
|
203
|
-
offset: normalizedOffset,
|
|
204
|
-
rows: rows.length,
|
|
205
|
-
});
|
|
206
|
-
return rows.map(internalDatasetRow);
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
async function* readChunks(
|
|
210
|
-
chunkSize: number,
|
|
211
|
-
): AsyncGenerator<T[], void, void> {
|
|
212
|
-
const size = normalizedChunkSize(chunkSize);
|
|
213
|
-
let offset = 0;
|
|
214
|
-
while (offset < count) {
|
|
215
|
-
const rows = await loadRows(Math.min(size, count - offset), offset);
|
|
216
|
-
if (rows.length === 0) {
|
|
217
|
-
return;
|
|
218
|
-
}
|
|
219
|
-
yield rows;
|
|
220
|
-
offset += rows.length;
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
const dataset = createDeferredPlayDataset({
|
|
225
|
-
datasetKind,
|
|
226
|
-
datasetId: `${datasetKind}:${input.name}`,
|
|
227
|
-
count,
|
|
228
|
-
backing: {
|
|
229
|
-
storage: 'neon_sheet',
|
|
230
|
-
sheet: {
|
|
231
|
-
playName: input.playName,
|
|
232
|
-
tableNamespace: input.name,
|
|
233
|
-
},
|
|
234
|
-
},
|
|
235
|
-
previewRows,
|
|
236
|
-
sourceLabel: input.sourceLabel ?? null,
|
|
237
|
-
tableNamespace: input.name,
|
|
238
|
-
workProgress: input.workProgress,
|
|
239
|
-
resolvers: {
|
|
240
|
-
count: async () => count,
|
|
241
|
-
peek: async (limit) =>
|
|
242
|
-
(await loadRows(Math.max(0, limit), 0)).map(materializedDatasetRow),
|
|
243
|
-
materialize: async (limit) => {
|
|
244
|
-
const rows: T[] = [];
|
|
245
|
-
const maxRows = limit ?? count;
|
|
246
|
-
for await (const chunk of readChunks(STREAM_MATERIALIZE_CHUNK_ROWS)) {
|
|
247
|
-
for (const row of chunk) {
|
|
248
|
-
if (rows.length >= maxRows) return rows;
|
|
249
|
-
rows.push(materializedDatasetRow(row));
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
return rows;
|
|
253
|
-
},
|
|
254
|
-
iterate: () =>
|
|
255
|
-
({
|
|
256
|
-
async *[Symbol.asyncIterator]() {
|
|
257
|
-
for await (const chunk of readChunks(STREAM_ITERATE_CHUNK_ROWS)) {
|
|
258
|
-
for (const row of chunk) yield row;
|
|
259
|
-
}
|
|
260
|
-
},
|
|
261
|
-
}) as AsyncIterable<T>,
|
|
262
|
-
},
|
|
263
|
-
});
|
|
264
|
-
return registerChunkReader(
|
|
265
|
-
dataset,
|
|
266
|
-
(chunkSize) => readChunks(chunkSize),
|
|
267
|
-
count,
|
|
268
|
-
{
|
|
269
|
-
storage: 'runtime_sheet',
|
|
270
|
-
chunkReadable: true,
|
|
271
|
-
pageBacked: true,
|
|
272
|
-
replayable: true,
|
|
273
|
-
materialization: 'bounded',
|
|
274
|
-
},
|
|
275
|
-
);
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
export function createCsvDatasetHandle<T extends DatasetRow>(input: {
|
|
279
|
-
name: string;
|
|
280
|
-
logicalPath: string;
|
|
281
|
-
expectedBytes?: number | null;
|
|
282
|
-
renameOptions?: CsvRenameOptions;
|
|
283
|
-
open: () => Promise<AsyncIterable<Uint8Array> | null>;
|
|
284
|
-
streamRows: (
|
|
285
|
-
byteChunks: AsyncIterable<Uint8Array>,
|
|
286
|
-
chunkSize: number,
|
|
287
|
-
) => AsyncIterable<T[]>;
|
|
288
|
-
trace?: (phase: string, ms: number, extra?: Record<string, unknown>) => void;
|
|
289
|
-
nowMs: () => number;
|
|
290
|
-
}): WorkerDatasetHandle<T> {
|
|
291
|
-
const datasetId = `csv:${input.name}`;
|
|
292
|
-
let cachedCount: number | null = null;
|
|
293
|
-
|
|
294
|
-
async function* readChunks(
|
|
295
|
-
chunkSize: number,
|
|
296
|
-
): AsyncGenerator<T[], void, void> {
|
|
297
|
-
const startedAt = input.nowMs();
|
|
298
|
-
let yieldedRows = 0;
|
|
299
|
-
let yieldedChunks = 0;
|
|
300
|
-
let observedBytes = 0;
|
|
301
|
-
let observedByteChunks = 0;
|
|
302
|
-
const body = await input.open();
|
|
303
|
-
if (!body) {
|
|
304
|
-
throw new Error(
|
|
305
|
-
`ctx.csv("${input.logicalPath}"): dataset source is not reachable from the play runner.`,
|
|
306
|
-
);
|
|
307
|
-
}
|
|
308
|
-
const size = normalizedChunkSize(chunkSize);
|
|
309
|
-
const countedBody = {
|
|
310
|
-
async *[Symbol.asyncIterator]() {
|
|
311
|
-
for await (const chunk of body) {
|
|
312
|
-
observedBytes += chunk.byteLength;
|
|
313
|
-
observedByteChunks += 1;
|
|
314
|
-
yield chunk;
|
|
315
|
-
}
|
|
316
|
-
},
|
|
317
|
-
} satisfies AsyncIterable<Uint8Array>;
|
|
318
|
-
try {
|
|
319
|
-
for await (const chunk of input.streamRows(countedBody, size)) {
|
|
320
|
-
yieldedRows += chunk.length;
|
|
321
|
-
yieldedChunks += 1;
|
|
322
|
-
yield applyCsvRenameProjection(chunk, input.renameOptions) as T[];
|
|
323
|
-
}
|
|
324
|
-
} finally {
|
|
325
|
-
input.trace?.('csv.stream', input.nowMs() - startedAt, {
|
|
326
|
-
name: input.name,
|
|
327
|
-
logicalPath: input.logicalPath,
|
|
328
|
-
expectedBytes: input.expectedBytes ?? null,
|
|
329
|
-
observedBytes,
|
|
330
|
-
observedByteChunks,
|
|
331
|
-
yieldedRows,
|
|
332
|
-
yieldedChunks,
|
|
333
|
-
chunkSize: size,
|
|
334
|
-
});
|
|
335
|
-
}
|
|
336
|
-
if (
|
|
337
|
-
typeof input.expectedBytes === 'number' &&
|
|
338
|
-
input.expectedBytes > 0 &&
|
|
339
|
-
yieldedRows === 0
|
|
340
|
-
) {
|
|
341
|
-
throw new Error(
|
|
342
|
-
observedBytes === 0
|
|
343
|
-
? `ctx.csv("${input.logicalPath}"): dataset source yielded 0 bytes for ` +
|
|
344
|
-
`a non-empty ${input.expectedBytes} byte staged file.`
|
|
345
|
-
: `ctx.csv("${input.logicalPath}"): parsed 0 rows after reading ` +
|
|
346
|
-
`${observedBytes} bytes from a non-empty ${input.expectedBytes} byte dataset source.`,
|
|
347
|
-
);
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
const dataset = createDeferredPlayDataset({
|
|
352
|
-
datasetKind: 'csv',
|
|
353
|
-
datasetId,
|
|
354
|
-
count: 0,
|
|
355
|
-
previewRows: [],
|
|
356
|
-
tableNamespace: input.name,
|
|
357
|
-
resolvers: {
|
|
358
|
-
count: async () => {
|
|
359
|
-
if (cachedCount !== null) return cachedCount;
|
|
360
|
-
let total = 0;
|
|
361
|
-
for await (const chunk of readChunks(STREAM_MATERIALIZE_CHUNK_ROWS)) {
|
|
362
|
-
total += chunk.length;
|
|
363
|
-
}
|
|
364
|
-
cachedCount = total;
|
|
365
|
-
return total;
|
|
366
|
-
},
|
|
367
|
-
peek: async (limit) => {
|
|
368
|
-
const rows: T[] = [];
|
|
369
|
-
for await (const chunk of readChunks(Math.max(1, limit))) {
|
|
370
|
-
for (const row of chunk) {
|
|
371
|
-
rows.push(row);
|
|
372
|
-
if (rows.length >= limit) return rows;
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
return rows;
|
|
376
|
-
},
|
|
377
|
-
materialize: async (limit) => {
|
|
378
|
-
const rows: T[] = [];
|
|
379
|
-
const maxRows = limit ?? Number.POSITIVE_INFINITY;
|
|
380
|
-
for await (const chunk of readChunks(STREAM_MATERIALIZE_CHUNK_ROWS)) {
|
|
381
|
-
for (const row of chunk) {
|
|
382
|
-
if (rows.length >= maxRows) return rows;
|
|
383
|
-
rows.push(row);
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
return rows;
|
|
387
|
-
},
|
|
388
|
-
iterate: () =>
|
|
389
|
-
({
|
|
390
|
-
async *[Symbol.asyncIterator]() {
|
|
391
|
-
for await (const chunk of readChunks(STREAM_ITERATE_CHUNK_ROWS)) {
|
|
392
|
-
for (const row of chunk) yield row;
|
|
393
|
-
}
|
|
394
|
-
},
|
|
395
|
-
}) as AsyncIterable<T>,
|
|
396
|
-
},
|
|
397
|
-
});
|
|
398
|
-
return registerChunkReader(
|
|
399
|
-
dataset,
|
|
400
|
-
(chunkSize) => readChunks(chunkSize),
|
|
401
|
-
null,
|
|
402
|
-
{
|
|
403
|
-
storage: 'csv_stream',
|
|
404
|
-
chunkReadable: true,
|
|
405
|
-
pageBacked: false,
|
|
406
|
-
replayable: true,
|
|
407
|
-
materialization: 'bounded',
|
|
408
|
-
},
|
|
409
|
-
);
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
export function createInlineDatasetHandle<T extends DatasetRow>(
|
|
413
|
-
rows: readonly T[],
|
|
414
|
-
metadata?: {
|
|
415
|
-
name?: string;
|
|
416
|
-
kind?: PlayDatasetKind;
|
|
417
|
-
sourceLabel?: string | null;
|
|
418
|
-
},
|
|
419
|
-
): WorkerDatasetHandle<T> {
|
|
420
|
-
return createMaterializedDatasetHandle({
|
|
421
|
-
name: metadata?.name ?? 'csv',
|
|
422
|
-
rows,
|
|
423
|
-
datasetKind: metadata?.kind ?? 'csv',
|
|
424
|
-
sourceLabel: metadata?.sourceLabel ?? null,
|
|
425
|
-
});
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
export function datasetRowCountHint<T extends DatasetRow>(
|
|
429
|
-
input: WorkerDatasetInput<T>,
|
|
430
|
-
): number | null {
|
|
431
|
-
if (Array.isArray(input)) return input.length;
|
|
432
|
-
if (isPlayDataset<T>(input)) {
|
|
433
|
-
const hinted = datasetCountHints.get(input as object);
|
|
434
|
-
if (hinted !== undefined) return hinted;
|
|
435
|
-
}
|
|
436
|
-
return null;
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
export function datasetHandleCapabilities<T extends DatasetRow>(
|
|
440
|
-
input: WorkerDatasetInput<T>,
|
|
441
|
-
): WorkerDatasetCapabilities {
|
|
442
|
-
if (Array.isArray(input)) {
|
|
443
|
-
return {
|
|
444
|
-
storage: 'materialized',
|
|
445
|
-
chunkReadable: true,
|
|
446
|
-
pageBacked: false,
|
|
447
|
-
replayable: true,
|
|
448
|
-
countHint: input.length,
|
|
449
|
-
materialization: 'in_memory',
|
|
450
|
-
};
|
|
451
|
-
}
|
|
452
|
-
if (isPlayDataset<T>(input)) {
|
|
453
|
-
const capabilities = datasetCapabilities.get(input as object);
|
|
454
|
-
if (capabilities) {
|
|
455
|
-
return capabilities;
|
|
456
|
-
}
|
|
457
|
-
return {
|
|
458
|
-
storage: 'iterable',
|
|
459
|
-
chunkReadable: false,
|
|
460
|
-
pageBacked: Boolean(input.backing),
|
|
461
|
-
replayable: true,
|
|
462
|
-
countHint: null,
|
|
463
|
-
materialization: 'bounded',
|
|
464
|
-
};
|
|
465
|
-
}
|
|
466
|
-
return {
|
|
467
|
-
storage: 'iterable',
|
|
468
|
-
chunkReadable: false,
|
|
469
|
-
pageBacked: false,
|
|
470
|
-
replayable: false,
|
|
471
|
-
countHint: null,
|
|
472
|
-
materialization: 'bounded',
|
|
473
|
-
};
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
export function isDatasetHandle<T extends DatasetRow>(
|
|
477
|
-
value: unknown,
|
|
478
|
-
): value is WorkerDatasetHandle<T> {
|
|
479
|
-
return isPlayDataset<T>(value);
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
export function iterDatasetChunks<T extends DatasetRow>(
|
|
483
|
-
input: WorkerDatasetInput<T>,
|
|
484
|
-
chunkSize: number,
|
|
485
|
-
): AsyncIterable<T[]> {
|
|
486
|
-
const size = normalizedChunkSize(chunkSize);
|
|
487
|
-
if (isPlayDataset<T>(input)) {
|
|
488
|
-
const chunkReader = datasetChunkReaders.get(input as object);
|
|
489
|
-
if (chunkReader) {
|
|
490
|
-
return chunkReader(size) as AsyncIterable<T[]>;
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
return {
|
|
494
|
-
async *[Symbol.asyncIterator]() {
|
|
495
|
-
let chunk: T[] = [];
|
|
496
|
-
const flush = function* () {
|
|
497
|
-
if (chunk.length > 0) {
|
|
498
|
-
yield chunk;
|
|
499
|
-
chunk = [];
|
|
500
|
-
}
|
|
501
|
-
};
|
|
502
|
-
const push = function* (row: T) {
|
|
503
|
-
chunk.push(row);
|
|
504
|
-
if (chunk.length >= size) {
|
|
505
|
-
yield chunk;
|
|
506
|
-
chunk = [];
|
|
507
|
-
}
|
|
508
|
-
};
|
|
509
|
-
|
|
510
|
-
if (isPlayDataset<T>(input)) {
|
|
511
|
-
for await (const row of input) yield* push(row);
|
|
512
|
-
yield* flush();
|
|
513
|
-
return;
|
|
514
|
-
}
|
|
515
|
-
if (
|
|
516
|
-
input != null &&
|
|
517
|
-
typeof input === 'object' &&
|
|
518
|
-
Symbol.asyncIterator in input
|
|
519
|
-
) {
|
|
520
|
-
for await (const row of input as AsyncIterable<T>) yield* push(row);
|
|
521
|
-
yield* flush();
|
|
522
|
-
return;
|
|
523
|
-
}
|
|
524
|
-
for (const row of input as Iterable<T>) yield* push(row);
|
|
525
|
-
yield* flush();
|
|
526
|
-
},
|
|
527
|
-
};
|
|
528
|
-
}
|