deepline 0.1.73 → 0.1.74
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 +7 -6
- package/dist/cli/index.js +8 -12
- package/dist/cli/index.mjs +8 -12
- package/dist/index.d.mts +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +12 -4
- package/dist/index.mjs +12 -4
- package/dist/repo/apps/play-runner-workers/src/entry.ts +41 -19
- package/dist/repo/sdk/src/play.ts +57 -8
- package/dist/repo/sdk/src/release.ts +2 -2
- package/dist/repo/sdk/src/worker-play-entry.ts +36 -3
- package/dist/repo/shared_libs/play-runtime/step-program-dataset-builder.ts +125 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -242,12 +242,12 @@ deepline play run --file rate-limit-repro.play.ts --watch
|
|
|
242
242
|
|
|
243
243
|
### 4. Fallback variant (multi-step with rate limits)
|
|
244
244
|
|
|
245
|
-
Use `steps()`
|
|
246
|
-
conditional steps yield `null`.
|
|
245
|
+
Use `steps()` with `{ runIf }` options to express row-level fallback sequences.
|
|
246
|
+
Skipped conditional steps yield `null`.
|
|
247
247
|
|
|
248
248
|
```bash
|
|
249
249
|
cat > rate-limit-waterfall.play.ts << 'TS'
|
|
250
|
-
import { definePlay,
|
|
250
|
+
import { definePlay, steps } from 'deepline';
|
|
251
251
|
|
|
252
252
|
export default definePlay('rate-limit-waterfall', async (ctx) => {
|
|
253
253
|
const leads = Array.from({ length: 24 }, (_, i) => ({
|
|
@@ -267,8 +267,8 @@ export default definePlay('rate-limit-waterfall', async (ctx) => {
|
|
|
267
267
|
},
|
|
268
268
|
description: 'Exercise primary rate-limit behavior.',
|
|
269
269
|
}))
|
|
270
|
-
.step(
|
|
271
|
-
|
|
270
|
+
.step(
|
|
271
|
+
"backup_probe",
|
|
272
272
|
(row, ctx) =>
|
|
273
273
|
ctx.tools.execute({
|
|
274
274
|
id: 'rate_limit_probe_backup',
|
|
@@ -280,7 +280,8 @@ export default definePlay('rate-limit-waterfall', async (ctx) => {
|
|
|
280
280
|
},
|
|
281
281
|
description: 'Exercise fallback rate-limit behavior.',
|
|
282
282
|
}),
|
|
283
|
-
|
|
283
|
+
{ runIf: (row) => !row.primary_probe },
|
|
284
|
+
)
|
|
284
285
|
.return((row) => row.primary_probe ?? row.backup_probe ?? null);
|
|
285
286
|
|
|
286
287
|
// Fan out over leads — each gets a row-level fallback sequence
|
package/dist/cli/index.js
CHANGED
|
@@ -229,10 +229,10 @@ var import_node_path2 = require("path");
|
|
|
229
229
|
|
|
230
230
|
// src/release.ts
|
|
231
231
|
var SDK_RELEASE = {
|
|
232
|
-
version: "0.1.
|
|
232
|
+
version: "0.1.74",
|
|
233
233
|
apiContract: "2026-06-dataset-column-syntax-cutover",
|
|
234
234
|
supportPolicy: {
|
|
235
|
-
latest: "0.1.
|
|
235
|
+
latest: "0.1.74",
|
|
236
236
|
minimumSupported: "0.1.53",
|
|
237
237
|
deprecatedBelow: "0.1.53"
|
|
238
238
|
}
|
|
@@ -6885,9 +6885,6 @@ function playInspectionComments(playRef, indent) {
|
|
|
6885
6885
|
function accessorExpression(base, field) {
|
|
6886
6886
|
return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(field) ? `${base}.${field}` : `${base}[${jsString(field)}]`;
|
|
6887
6887
|
}
|
|
6888
|
-
function needsRunIfImport(options) {
|
|
6889
|
-
return stageProviders(options.email).length > 1 || stageProviders(options.phone).length > 1;
|
|
6890
|
-
}
|
|
6891
6888
|
function sourceCollectionTypeName(entity) {
|
|
6892
6889
|
return entity === "company" ? "CompanySourceRow" : "ContactSourceRow";
|
|
6893
6890
|
}
|
|
@@ -7238,10 +7235,10 @@ function generateFinderProviderStep(input2) {
|
|
|
7238
7235
|
const priorCandidates = input2.stepNames.slice(0, input2.index).map((name) => `row.${name}`).join(", ");
|
|
7239
7236
|
return `.withColumn(
|
|
7240
7237
|
${jsString(stepName)},
|
|
7241
|
-
|
|
7242
|
-
|
|
7243
|
-
${input2.
|
|
7244
|
-
|
|
7238
|
+
${input2.resolver},
|
|
7239
|
+
{
|
|
7240
|
+
runIf: (row) => ![${priorCandidates}].some((candidate) => ${optionalFinderValueExpression("candidate", input2.outputField)}),
|
|
7241
|
+
},
|
|
7245
7242
|
)`;
|
|
7246
7243
|
}
|
|
7247
7244
|
}
|
|
@@ -7272,7 +7269,7 @@ function generateFinderProviderWaterfall(input2) {
|
|
|
7272
7269
|
);
|
|
7273
7270
|
const candidateNames = stepNames.map((name) => `row.${name}`).join(", ");
|
|
7274
7271
|
return `// ${input2.aggregateStepName} provider waterfall. Each provider leg is active once its TODO throw is removed;
|
|
7275
|
-
// delete or comment out legs you do not want before running. Later legs are gated with runIf
|
|
7272
|
+
// delete or comment out legs you do not want before running. Later legs are gated with { runIf }.
|
|
7276
7273
|
${providerSteps.join("\n ")}
|
|
7277
7274
|
.withColumn(${jsString(input2.aggregateStepName)}, (row) => {
|
|
7278
7275
|
const candidates = [${candidateNames}];
|
|
@@ -7329,8 +7326,7 @@ function generateBootstrapPlaySource(input2) {
|
|
|
7329
7326
|
rowTypeDefinitions,
|
|
7330
7327
|
finderPlayResultTypes
|
|
7331
7328
|
].filter((definition) => definition.trim().length > 0).join("\n\n");
|
|
7332
|
-
|
|
7333
|
-
return `import { ${importNames} } from 'deepline';
|
|
7329
|
+
return `import { definePlay } from 'deepline';
|
|
7334
7330
|
|
|
7335
7331
|
${typeDefinitions}
|
|
7336
7332
|
|
package/dist/cli/index.mjs
CHANGED
|
@@ -206,10 +206,10 @@ import { join as join2 } from "path";
|
|
|
206
206
|
|
|
207
207
|
// src/release.ts
|
|
208
208
|
var SDK_RELEASE = {
|
|
209
|
-
version: "0.1.
|
|
209
|
+
version: "0.1.74",
|
|
210
210
|
apiContract: "2026-06-dataset-column-syntax-cutover",
|
|
211
211
|
supportPolicy: {
|
|
212
|
-
latest: "0.1.
|
|
212
|
+
latest: "0.1.74",
|
|
213
213
|
minimumSupported: "0.1.53",
|
|
214
214
|
deprecatedBelow: "0.1.53"
|
|
215
215
|
}
|
|
@@ -6888,9 +6888,6 @@ function playInspectionComments(playRef, indent) {
|
|
|
6888
6888
|
function accessorExpression(base, field) {
|
|
6889
6889
|
return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(field) ? `${base}.${field}` : `${base}[${jsString(field)}]`;
|
|
6890
6890
|
}
|
|
6891
|
-
function needsRunIfImport(options) {
|
|
6892
|
-
return stageProviders(options.email).length > 1 || stageProviders(options.phone).length > 1;
|
|
6893
|
-
}
|
|
6894
6891
|
function sourceCollectionTypeName(entity) {
|
|
6895
6892
|
return entity === "company" ? "CompanySourceRow" : "ContactSourceRow";
|
|
6896
6893
|
}
|
|
@@ -7241,10 +7238,10 @@ function generateFinderProviderStep(input2) {
|
|
|
7241
7238
|
const priorCandidates = input2.stepNames.slice(0, input2.index).map((name) => `row.${name}`).join(", ");
|
|
7242
7239
|
return `.withColumn(
|
|
7243
7240
|
${jsString(stepName)},
|
|
7244
|
-
|
|
7245
|
-
|
|
7246
|
-
${input2.
|
|
7247
|
-
|
|
7241
|
+
${input2.resolver},
|
|
7242
|
+
{
|
|
7243
|
+
runIf: (row) => ![${priorCandidates}].some((candidate) => ${optionalFinderValueExpression("candidate", input2.outputField)}),
|
|
7244
|
+
},
|
|
7248
7245
|
)`;
|
|
7249
7246
|
}
|
|
7250
7247
|
}
|
|
@@ -7275,7 +7272,7 @@ function generateFinderProviderWaterfall(input2) {
|
|
|
7275
7272
|
);
|
|
7276
7273
|
const candidateNames = stepNames.map((name) => `row.${name}`).join(", ");
|
|
7277
7274
|
return `// ${input2.aggregateStepName} provider waterfall. Each provider leg is active once its TODO throw is removed;
|
|
7278
|
-
// delete or comment out legs you do not want before running. Later legs are gated with runIf
|
|
7275
|
+
// delete or comment out legs you do not want before running. Later legs are gated with { runIf }.
|
|
7279
7276
|
${providerSteps.join("\n ")}
|
|
7280
7277
|
.withColumn(${jsString(input2.aggregateStepName)}, (row) => {
|
|
7281
7278
|
const candidates = [${candidateNames}];
|
|
@@ -7332,8 +7329,7 @@ function generateBootstrapPlaySource(input2) {
|
|
|
7332
7329
|
rowTypeDefinitions,
|
|
7333
7330
|
finderPlayResultTypes
|
|
7334
7331
|
].filter((definition) => definition.trim().length > 0).join("\n\n");
|
|
7335
|
-
|
|
7336
|
-
return `import { ${importNames} } from 'deepline';
|
|
7332
|
+
return `import { definePlay } from 'deepline';
|
|
7337
7333
|
|
|
7338
7334
|
${typeDefinitions}
|
|
7339
7335
|
|
package/dist/index.d.mts
CHANGED
|
@@ -2143,12 +2143,16 @@ type ConditionalStepResolver<Row, Value, Else = null> = {
|
|
|
2143
2143
|
readonly elseValue: Else;
|
|
2144
2144
|
else<ValueElse>(value: ValueElse): ConditionalStepResolver<Row, Value, ValueElse>;
|
|
2145
2145
|
};
|
|
2146
|
+
type StepOptions<Row> = {
|
|
2147
|
+
readonly runIf?: (row: Row, index: number) => boolean | Promise<boolean>;
|
|
2148
|
+
};
|
|
2146
2149
|
type StepProgram<Input, Output, Return = Output> = {
|
|
2147
2150
|
readonly kind: 'steps';
|
|
2148
2151
|
readonly steps: readonly PlayStepProgramStep[];
|
|
2149
2152
|
readonly returnResolver?: StepResolver<Output, Return>;
|
|
2150
2153
|
readonly __inputType?: (input: Input) => void;
|
|
2151
2154
|
step<Name extends string, Value>(name: Name, resolver: StepResolver<Output, Value> | ConditionalStepResolver<Output, Value> | StepProgramResolver<Output, Value>): StepProgram<Input, Output & Record<Name, Value>, Return>;
|
|
2155
|
+
step<Name extends string, Value>(name: Name, resolver: StepResolver<Output, Value> | StepProgramResolver<Output, Value>, options: StepOptions<Output>): StepProgram<Input, Output & Record<Name, Value | null>, Return>;
|
|
2152
2156
|
return<Value>(resolver: StepResolver<Output, Value>): StepProgram<Input, Output, Value>;
|
|
2153
2157
|
};
|
|
2154
2158
|
type StepProgramResolver<Input, Return> = {
|
|
@@ -2162,6 +2166,7 @@ type PlayStepProgramStep = {
|
|
|
2162
2166
|
readonly resolver: StepResolver<Record<string, unknown>, unknown> | ConditionalStepResolver<Record<string, unknown>, unknown> | StepProgramResolver<Record<string, unknown>, unknown>;
|
|
2163
2167
|
};
|
|
2164
2168
|
type ColumnResolver<Row, Value> = StepResolver<Row, Value> | ConditionalStepResolver<Row, Value> | StepProgramResolver<Row, Value>;
|
|
2169
|
+
type StepProgramOutput<TProgram> = TProgram extends StepProgram<any, infer Output, any> ? Output : never;
|
|
2165
2170
|
type DatasetBuilder<InputRow extends object, OutputRow extends object> = {
|
|
2166
2171
|
/**
|
|
2167
2172
|
* Define one output column for every row in this dataset.
|
|
@@ -2177,6 +2182,8 @@ type DatasetBuilder<InputRow extends object, OutputRow extends object> = {
|
|
|
2177
2182
|
* @returns The same dataset builder with the new column type.
|
|
2178
2183
|
*/
|
|
2179
2184
|
withColumn<Name extends string, Value>(name: Name, resolver: ColumnResolver<OutputRow, Value>): DatasetBuilder<InputRow, OutputRow & Record<Name, Value>>;
|
|
2185
|
+
withColumn<Name extends string, Value>(name: Name, resolver: StepResolver<OutputRow, Value> | StepProgramResolver<OutputRow, Value>, options: StepOptions<OutputRow>): DatasetBuilder<InputRow, OutputRow & Record<Name, Value | null>>;
|
|
2186
|
+
withColumns<Program extends StepProgram<OutputRow, object, unknown>>(program: Program): DatasetBuilder<InputRow, StepProgramOutput<Program>>;
|
|
2180
2187
|
/** @deprecated Dataset `.step(...)` was replaced by `.withColumn(...)`. */
|
|
2181
2188
|
step<Name extends string, Value>(name: Name, resolver: ColumnResolver<OutputRow, Value>): never;
|
|
2182
2189
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -2143,12 +2143,16 @@ type ConditionalStepResolver<Row, Value, Else = null> = {
|
|
|
2143
2143
|
readonly elseValue: Else;
|
|
2144
2144
|
else<ValueElse>(value: ValueElse): ConditionalStepResolver<Row, Value, ValueElse>;
|
|
2145
2145
|
};
|
|
2146
|
+
type StepOptions<Row> = {
|
|
2147
|
+
readonly runIf?: (row: Row, index: number) => boolean | Promise<boolean>;
|
|
2148
|
+
};
|
|
2146
2149
|
type StepProgram<Input, Output, Return = Output> = {
|
|
2147
2150
|
readonly kind: 'steps';
|
|
2148
2151
|
readonly steps: readonly PlayStepProgramStep[];
|
|
2149
2152
|
readonly returnResolver?: StepResolver<Output, Return>;
|
|
2150
2153
|
readonly __inputType?: (input: Input) => void;
|
|
2151
2154
|
step<Name extends string, Value>(name: Name, resolver: StepResolver<Output, Value> | ConditionalStepResolver<Output, Value> | StepProgramResolver<Output, Value>): StepProgram<Input, Output & Record<Name, Value>, Return>;
|
|
2155
|
+
step<Name extends string, Value>(name: Name, resolver: StepResolver<Output, Value> | StepProgramResolver<Output, Value>, options: StepOptions<Output>): StepProgram<Input, Output & Record<Name, Value | null>, Return>;
|
|
2152
2156
|
return<Value>(resolver: StepResolver<Output, Value>): StepProgram<Input, Output, Value>;
|
|
2153
2157
|
};
|
|
2154
2158
|
type StepProgramResolver<Input, Return> = {
|
|
@@ -2162,6 +2166,7 @@ type PlayStepProgramStep = {
|
|
|
2162
2166
|
readonly resolver: StepResolver<Record<string, unknown>, unknown> | ConditionalStepResolver<Record<string, unknown>, unknown> | StepProgramResolver<Record<string, unknown>, unknown>;
|
|
2163
2167
|
};
|
|
2164
2168
|
type ColumnResolver<Row, Value> = StepResolver<Row, Value> | ConditionalStepResolver<Row, Value> | StepProgramResolver<Row, Value>;
|
|
2169
|
+
type StepProgramOutput<TProgram> = TProgram extends StepProgram<any, infer Output, any> ? Output : never;
|
|
2165
2170
|
type DatasetBuilder<InputRow extends object, OutputRow extends object> = {
|
|
2166
2171
|
/**
|
|
2167
2172
|
* Define one output column for every row in this dataset.
|
|
@@ -2177,6 +2182,8 @@ type DatasetBuilder<InputRow extends object, OutputRow extends object> = {
|
|
|
2177
2182
|
* @returns The same dataset builder with the new column type.
|
|
2178
2183
|
*/
|
|
2179
2184
|
withColumn<Name extends string, Value>(name: Name, resolver: ColumnResolver<OutputRow, Value>): DatasetBuilder<InputRow, OutputRow & Record<Name, Value>>;
|
|
2185
|
+
withColumn<Name extends string, Value>(name: Name, resolver: StepResolver<OutputRow, Value> | StepProgramResolver<OutputRow, Value>, options: StepOptions<OutputRow>): DatasetBuilder<InputRow, OutputRow & Record<Name, Value | null>>;
|
|
2186
|
+
withColumns<Program extends StepProgram<OutputRow, object, unknown>>(program: Program): DatasetBuilder<InputRow, StepProgramOutput<Program>>;
|
|
2180
2187
|
/** @deprecated Dataset `.step(...)` was replaced by `.withColumn(...)`. */
|
|
2181
2188
|
step<Name extends string, Value>(name: Name, resolver: ColumnResolver<OutputRow, Value>): never;
|
|
2182
2189
|
/**
|
package/dist/index.js
CHANGED
|
@@ -241,10 +241,10 @@ var import_node_path2 = require("path");
|
|
|
241
241
|
|
|
242
242
|
// src/release.ts
|
|
243
243
|
var SDK_RELEASE = {
|
|
244
|
-
version: "0.1.
|
|
244
|
+
version: "0.1.74",
|
|
245
245
|
apiContract: "2026-06-dataset-column-syntax-cutover",
|
|
246
246
|
supportPolicy: {
|
|
247
|
-
latest: "0.1.
|
|
247
|
+
latest: "0.1.74",
|
|
248
248
|
minimumSupported: "0.1.53",
|
|
249
249
|
deprecatedBelow: "0.1.53"
|
|
250
250
|
}
|
|
@@ -2410,18 +2410,23 @@ var DeeplineStepProgram = class _DeeplineStepProgram {
|
|
|
2410
2410
|
steps;
|
|
2411
2411
|
returnResolver;
|
|
2412
2412
|
kind = "steps";
|
|
2413
|
-
step(name, resolver) {
|
|
2413
|
+
step(name, resolver, options) {
|
|
2414
2414
|
if (!name.trim()) {
|
|
2415
2415
|
throw new Error(
|
|
2416
2416
|
"steps().step(name, ...) requires a non-empty step name."
|
|
2417
2417
|
);
|
|
2418
2418
|
}
|
|
2419
|
+
const stepResolver = options?.runIf && !isConditionalStepResolver(resolver) ? new DeeplineConditionalStepResolver(
|
|
2420
|
+
options.runIf,
|
|
2421
|
+
resolver,
|
|
2422
|
+
null
|
|
2423
|
+
) : resolver;
|
|
2419
2424
|
return new _DeeplineStepProgram(
|
|
2420
2425
|
[
|
|
2421
2426
|
...this.steps,
|
|
2422
2427
|
{
|
|
2423
2428
|
name,
|
|
2424
|
-
resolver
|
|
2429
|
+
resolver: stepResolver
|
|
2425
2430
|
}
|
|
2426
2431
|
],
|
|
2427
2432
|
this.returnResolver
|
|
@@ -2431,6 +2436,9 @@ var DeeplineStepProgram = class _DeeplineStepProgram {
|
|
|
2431
2436
|
return new _DeeplineStepProgram(this.steps, resolver);
|
|
2432
2437
|
}
|
|
2433
2438
|
};
|
|
2439
|
+
function isConditionalStepResolver(value) {
|
|
2440
|
+
return value !== null && typeof value === "object" && value.kind === "conditional";
|
|
2441
|
+
}
|
|
2434
2442
|
function steps() {
|
|
2435
2443
|
return new DeeplineStepProgram([]);
|
|
2436
2444
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -179,10 +179,10 @@ import { join as join2 } from "path";
|
|
|
179
179
|
|
|
180
180
|
// src/release.ts
|
|
181
181
|
var SDK_RELEASE = {
|
|
182
|
-
version: "0.1.
|
|
182
|
+
version: "0.1.74",
|
|
183
183
|
apiContract: "2026-06-dataset-column-syntax-cutover",
|
|
184
184
|
supportPolicy: {
|
|
185
|
-
latest: "0.1.
|
|
185
|
+
latest: "0.1.74",
|
|
186
186
|
minimumSupported: "0.1.53",
|
|
187
187
|
deprecatedBelow: "0.1.53"
|
|
188
188
|
}
|
|
@@ -2348,18 +2348,23 @@ var DeeplineStepProgram = class _DeeplineStepProgram {
|
|
|
2348
2348
|
steps;
|
|
2349
2349
|
returnResolver;
|
|
2350
2350
|
kind = "steps";
|
|
2351
|
-
step(name, resolver) {
|
|
2351
|
+
step(name, resolver, options) {
|
|
2352
2352
|
if (!name.trim()) {
|
|
2353
2353
|
throw new Error(
|
|
2354
2354
|
"steps().step(name, ...) requires a non-empty step name."
|
|
2355
2355
|
);
|
|
2356
2356
|
}
|
|
2357
|
+
const stepResolver = options?.runIf && !isConditionalStepResolver(resolver) ? new DeeplineConditionalStepResolver(
|
|
2358
|
+
options.runIf,
|
|
2359
|
+
resolver,
|
|
2360
|
+
null
|
|
2361
|
+
) : resolver;
|
|
2357
2362
|
return new _DeeplineStepProgram(
|
|
2358
2363
|
[
|
|
2359
2364
|
...this.steps,
|
|
2360
2365
|
{
|
|
2361
2366
|
name,
|
|
2362
|
-
resolver
|
|
2367
|
+
resolver: stepResolver
|
|
2363
2368
|
}
|
|
2364
2369
|
],
|
|
2365
2370
|
this.returnResolver
|
|
@@ -2369,6 +2374,9 @@ var DeeplineStepProgram = class _DeeplineStepProgram {
|
|
|
2369
2374
|
return new _DeeplineStepProgram(this.steps, resolver);
|
|
2370
2375
|
}
|
|
2371
2376
|
};
|
|
2377
|
+
function isConditionalStepResolver(value) {
|
|
2378
|
+
return value !== null && typeof value === "object" && value.kind === "conditional";
|
|
2379
|
+
}
|
|
2372
2380
|
function steps() {
|
|
2373
2381
|
return new DeeplineStepProgram([]);
|
|
2374
2382
|
}
|
|
@@ -151,6 +151,10 @@ import {
|
|
|
151
151
|
isHardBillingToolHttpError,
|
|
152
152
|
normalizeToolHttpErrorMessage,
|
|
153
153
|
} from './runtime/tool-http-errors';
|
|
154
|
+
import {
|
|
155
|
+
StepProgramDatasetBuilder,
|
|
156
|
+
type StepProgramDatasetOptions,
|
|
157
|
+
} from '../../../shared_libs/play-runtime/step-program-dataset-builder';
|
|
154
158
|
|
|
155
159
|
// The play's default export. The bundler injects this — see bundle-play-file.ts.
|
|
156
160
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
@@ -4017,37 +4021,55 @@ function createMinimalWorkerCtx(
|
|
|
4017
4021
|
};
|
|
4018
4022
|
|
|
4019
4023
|
class WorkerDatasetBuilder<T extends Record<string, unknown>> {
|
|
4020
|
-
private readonly
|
|
4021
|
-
|
|
4022
|
-
|
|
4023
|
-
|
|
4024
|
+
private readonly builder: StepProgramDatasetBuilder<
|
|
4025
|
+
WorkerStepProgramStep,
|
|
4026
|
+
WorkerStepProgramStep['resolver'],
|
|
4027
|
+
WorkerMapOptions,
|
|
4028
|
+
Promise<unknown>
|
|
4029
|
+
>;
|
|
4024
4030
|
|
|
4025
4031
|
constructor(
|
|
4026
4032
|
private readonly name: string,
|
|
4027
4033
|
private readonly rows: WorkerDatasetInput<T>,
|
|
4028
|
-
) {
|
|
4034
|
+
) {
|
|
4035
|
+
this.builder = new StepProgramDatasetBuilder(
|
|
4036
|
+
(program, opts) => {
|
|
4037
|
+
const fields = Object.fromEntries(
|
|
4038
|
+
program.steps.map((step) => [step.name, step.resolver]),
|
|
4039
|
+
);
|
|
4040
|
+
return runMap(this.name, this.rows, fields, opts);
|
|
4041
|
+
},
|
|
4042
|
+
{
|
|
4043
|
+
emptyColumnName:
|
|
4044
|
+
'ctx.dataset(...).withColumn(name, ...) requires a name.',
|
|
4045
|
+
invalidColumnsProgram:
|
|
4046
|
+
'ctx.dataset(...).withColumns(...) requires a steps() program.',
|
|
4047
|
+
legacyStep:
|
|
4048
|
+
'ctx.dataset(...).step(...) has been replaced by ctx.dataset(...).withColumn(...).',
|
|
4049
|
+
},
|
|
4050
|
+
);
|
|
4051
|
+
}
|
|
4029
4052
|
|
|
4030
|
-
withColumn(
|
|
4031
|
-
|
|
4032
|
-
|
|
4033
|
-
|
|
4034
|
-
|
|
4035
|
-
|
|
4036
|
-
|
|
4053
|
+
withColumn(
|
|
4054
|
+
name: string,
|
|
4055
|
+
resolver: WorkerStepProgramStep['resolver'],
|
|
4056
|
+
options?: StepProgramDatasetOptions,
|
|
4057
|
+
): this {
|
|
4058
|
+
this.builder.withColumn(name, resolver, options);
|
|
4059
|
+
return this;
|
|
4060
|
+
}
|
|
4061
|
+
|
|
4062
|
+
withColumns(program: WorkerStepProgram): this {
|
|
4063
|
+
this.builder.withColumns(program);
|
|
4037
4064
|
return this;
|
|
4038
4065
|
}
|
|
4039
4066
|
|
|
4040
4067
|
step(): never {
|
|
4041
|
-
|
|
4042
|
-
'ctx.dataset(...).step(...) has been replaced by ctx.dataset(...).withColumn(...).',
|
|
4043
|
-
);
|
|
4068
|
+
return this.builder.step();
|
|
4044
4069
|
}
|
|
4045
4070
|
|
|
4046
4071
|
run(opts?: WorkerMapOptions): Promise<unknown> {
|
|
4047
|
-
|
|
4048
|
-
this.program.steps.map((step) => [step.name, step.resolver]),
|
|
4049
|
-
);
|
|
4050
|
-
return runMap(this.name, this.rows, fields, opts);
|
|
4072
|
+
return this.builder.run(opts);
|
|
4051
4073
|
}
|
|
4052
4074
|
}
|
|
4053
4075
|
|
|
@@ -222,6 +222,10 @@ export type ConditionalStepResolver<Row, Value, Else = null> = {
|
|
|
222
222
|
): ConditionalStepResolver<Row, Value, ValueElse>;
|
|
223
223
|
};
|
|
224
224
|
|
|
225
|
+
export type StepOptions<Row> = {
|
|
226
|
+
readonly runIf?: (row: Row, index: number) => boolean | Promise<boolean>;
|
|
227
|
+
};
|
|
228
|
+
|
|
225
229
|
export type StepProgram<Input, Output, Return = Output> = {
|
|
226
230
|
readonly kind: 'steps';
|
|
227
231
|
readonly steps: readonly PlayStepProgramStep[];
|
|
@@ -234,6 +238,11 @@ export type StepProgram<Input, Output, Return = Output> = {
|
|
|
234
238
|
| ConditionalStepResolver<Output, Value>
|
|
235
239
|
| StepProgramResolver<Output, Value>,
|
|
236
240
|
): StepProgram<Input, Output & Record<Name, Value>, Return>;
|
|
241
|
+
step<Name extends string, Value>(
|
|
242
|
+
name: Name,
|
|
243
|
+
resolver: StepResolver<Output, Value> | StepProgramResolver<Output, Value>,
|
|
244
|
+
options: StepOptions<Output>,
|
|
245
|
+
): StepProgram<Input, Output & Record<Name, Value | null>, Return>;
|
|
237
246
|
return<Value>(
|
|
238
247
|
resolver: StepResolver<Output, Value>,
|
|
239
248
|
): StepProgram<Input, Output, Value>;
|
|
@@ -259,6 +268,9 @@ export type ColumnResolver<Row, Value> =
|
|
|
259
268
|
| ConditionalStepResolver<Row, Value>
|
|
260
269
|
| StepProgramResolver<Row, Value>;
|
|
261
270
|
|
|
271
|
+
export type StepProgramOutput<TProgram> =
|
|
272
|
+
TProgram extends StepProgram<any, infer Output, any> ? Output : never;
|
|
273
|
+
|
|
262
274
|
export type DatasetBuilder<
|
|
263
275
|
InputRow extends object,
|
|
264
276
|
OutputRow extends object,
|
|
@@ -280,6 +292,16 @@ export type DatasetBuilder<
|
|
|
280
292
|
name: Name,
|
|
281
293
|
resolver: ColumnResolver<OutputRow, Value>,
|
|
282
294
|
): DatasetBuilder<InputRow, OutputRow & Record<Name, Value>>;
|
|
295
|
+
withColumn<Name extends string, Value>(
|
|
296
|
+
name: Name,
|
|
297
|
+
resolver:
|
|
298
|
+
| StepResolver<OutputRow, Value>
|
|
299
|
+
| StepProgramResolver<OutputRow, Value>,
|
|
300
|
+
options: StepOptions<OutputRow>,
|
|
301
|
+
): DatasetBuilder<InputRow, OutputRow & Record<Name, Value | null>>;
|
|
302
|
+
withColumns<Program extends StepProgram<OutputRow, object, unknown>>(
|
|
303
|
+
program: Program,
|
|
304
|
+
): DatasetBuilder<InputRow, StepProgramOutput<Program>>;
|
|
283
305
|
/** @deprecated Dataset `.step(...)` was replaced by `.withColumn(...)`. */
|
|
284
306
|
step<Name extends string, Value>(
|
|
285
307
|
name: Name,
|
|
@@ -307,7 +329,6 @@ export type DatasetBuilder<
|
|
|
307
329
|
}): Promise<PlayDataset<OutputRow>>;
|
|
308
330
|
};
|
|
309
331
|
|
|
310
|
-
|
|
311
332
|
export type CsvRenameMap = Record<string, string | readonly string[]>;
|
|
312
333
|
|
|
313
334
|
/**
|
|
@@ -478,10 +499,7 @@ export interface DeeplinePlayRuntimeContext {
|
|
|
478
499
|
/**
|
|
479
500
|
* @deprecated `ctx.map(...)` was replaced by `ctx.dataset(...)`.
|
|
480
501
|
*/
|
|
481
|
-
map<TItem extends object>(
|
|
482
|
-
key: string,
|
|
483
|
-
items: PlayDatasetInput<TItem>,
|
|
484
|
-
): never;
|
|
502
|
+
map<TItem extends object>(key: string, items: PlayDatasetInput<TItem>): never;
|
|
485
503
|
|
|
486
504
|
/** Tool execution namespace. */
|
|
487
505
|
tools: {
|
|
@@ -863,22 +881,43 @@ class DeeplineStepProgram<Input, Output, ReturnValue> implements StepProgram<
|
|
|
863
881
|
| StepResolver<Output, Value>
|
|
864
882
|
| ConditionalStepResolver<Output, Value>
|
|
865
883
|
| StepProgramResolver<Output, Value>,
|
|
866
|
-
): StepProgram<Input, Output & Record<Name, Value>, ReturnValue
|
|
884
|
+
): StepProgram<Input, Output & Record<Name, Value>, ReturnValue>;
|
|
885
|
+
step<Name extends string, Value>(
|
|
886
|
+
name: Name,
|
|
887
|
+
resolver: StepResolver<Output, Value> | StepProgramResolver<Output, Value>,
|
|
888
|
+
options: StepOptions<Output>,
|
|
889
|
+
): StepProgram<Input, Output & Record<Name, Value | null>, ReturnValue>;
|
|
890
|
+
step<Name extends string, Value>(
|
|
891
|
+
name: Name,
|
|
892
|
+
resolver:
|
|
893
|
+
| StepResolver<Output, Value>
|
|
894
|
+
| ConditionalStepResolver<Output, Value>
|
|
895
|
+
| StepProgramResolver<Output, Value>,
|
|
896
|
+
options?: StepOptions<Output>,
|
|
897
|
+
): StepProgram<Input, Output & Record<Name, Value | null>, ReturnValue> {
|
|
867
898
|
if (!name.trim()) {
|
|
868
899
|
throw new Error(
|
|
869
900
|
'steps().step(name, ...) requires a non-empty step name.',
|
|
870
901
|
);
|
|
871
902
|
}
|
|
903
|
+
const stepResolver =
|
|
904
|
+
options?.runIf && !isConditionalStepResolver(resolver)
|
|
905
|
+
? new DeeplineConditionalStepResolver(
|
|
906
|
+
options.runIf,
|
|
907
|
+
resolver as StepResolver<Output, Value>,
|
|
908
|
+
null,
|
|
909
|
+
)
|
|
910
|
+
: resolver;
|
|
872
911
|
return new DeeplineStepProgram(
|
|
873
912
|
[
|
|
874
913
|
...this.steps,
|
|
875
914
|
{
|
|
876
915
|
name,
|
|
877
|
-
resolver:
|
|
916
|
+
resolver: stepResolver as PlayStepProgramStep['resolver'],
|
|
878
917
|
},
|
|
879
918
|
],
|
|
880
919
|
this.returnResolver as StepResolver<
|
|
881
|
-
Output & Record<Name, Value>,
|
|
920
|
+
Output & Record<Name, Value | null>,
|
|
882
921
|
ReturnValue
|
|
883
922
|
>,
|
|
884
923
|
);
|
|
@@ -891,6 +930,16 @@ class DeeplineStepProgram<Input, Output, ReturnValue> implements StepProgram<
|
|
|
891
930
|
}
|
|
892
931
|
}
|
|
893
932
|
|
|
933
|
+
function isConditionalStepResolver(
|
|
934
|
+
value: unknown,
|
|
935
|
+
): value is ConditionalStepResolver<unknown, unknown> {
|
|
936
|
+
return (
|
|
937
|
+
value !== null &&
|
|
938
|
+
typeof value === 'object' &&
|
|
939
|
+
(value as { kind?: unknown }).kind === 'conditional'
|
|
940
|
+
);
|
|
941
|
+
}
|
|
942
|
+
|
|
894
943
|
export function steps<TInput>(): StepProgram<TInput, TInput, TInput> {
|
|
895
944
|
return new DeeplineStepProgram<TInput, TInput, TInput>([]);
|
|
896
945
|
}
|
|
@@ -50,10 +50,10 @@ export type SdkRelease = {
|
|
|
50
50
|
};
|
|
51
51
|
|
|
52
52
|
export const SDK_RELEASE = {
|
|
53
|
-
version: '0.1.
|
|
53
|
+
version: '0.1.74',
|
|
54
54
|
apiContract: '2026-06-dataset-column-syntax-cutover',
|
|
55
55
|
supportPolicy: {
|
|
56
|
-
latest: '0.1.
|
|
56
|
+
latest: '0.1.74',
|
|
57
57
|
minimumSupported: '0.1.53',
|
|
58
58
|
deprecatedBelow: '0.1.53',
|
|
59
59
|
},
|
|
@@ -19,6 +19,7 @@ import type {
|
|
|
19
19
|
PlayStepProgramStep,
|
|
20
20
|
StepProgram,
|
|
21
21
|
StepProgramResolver,
|
|
22
|
+
StepOptions,
|
|
22
23
|
StepResolver,
|
|
23
24
|
} from './play.js';
|
|
24
25
|
|
|
@@ -43,6 +44,7 @@ export type {
|
|
|
43
44
|
PrebuiltPlayRef,
|
|
44
45
|
StepProgram,
|
|
45
46
|
StepProgramResolver,
|
|
47
|
+
StepOptions,
|
|
46
48
|
StepResolver,
|
|
47
49
|
ToolExecuteResult,
|
|
48
50
|
} from './play.js';
|
|
@@ -95,20 +97,41 @@ class WorkerStepProgram<Input, Output, ReturnValue> implements StepProgram<
|
|
|
95
97
|
| StepResolver<Output, Value>
|
|
96
98
|
| ConditionalStepResolver<Output, Value>
|
|
97
99
|
| StepProgramResolver<Output, Value>,
|
|
98
|
-
): StepProgram<Input, Output & Record<Name, Value>, ReturnValue
|
|
100
|
+
): StepProgram<Input, Output & Record<Name, Value>, ReturnValue>;
|
|
101
|
+
step<Name extends string, Value>(
|
|
102
|
+
name: Name,
|
|
103
|
+
resolver: StepResolver<Output, Value> | StepProgramResolver<Output, Value>,
|
|
104
|
+
options: StepOptions<Output>,
|
|
105
|
+
): StepProgram<Input, Output & Record<Name, Value | null>, ReturnValue>;
|
|
106
|
+
step<Name extends string, Value>(
|
|
107
|
+
name: Name,
|
|
108
|
+
resolver:
|
|
109
|
+
| StepResolver<Output, Value>
|
|
110
|
+
| ConditionalStepResolver<Output, Value>
|
|
111
|
+
| StepProgramResolver<Output, Value>,
|
|
112
|
+
options?: StepOptions<Output>,
|
|
113
|
+
): StepProgram<Input, Output & Record<Name, Value | null>, ReturnValue> {
|
|
99
114
|
if (!name.trim()) {
|
|
100
115
|
throw new Error('Step name required.');
|
|
101
116
|
}
|
|
117
|
+
const stepResolver =
|
|
118
|
+
options?.runIf && !isConditionalStepResolver(resolver)
|
|
119
|
+
? new WorkerConditionalStepResolver(
|
|
120
|
+
options.runIf,
|
|
121
|
+
resolver as StepResolver<Output, Value>,
|
|
122
|
+
null,
|
|
123
|
+
)
|
|
124
|
+
: resolver;
|
|
102
125
|
return new WorkerStepProgram(
|
|
103
126
|
[
|
|
104
127
|
...this.steps,
|
|
105
128
|
{
|
|
106
129
|
name,
|
|
107
|
-
resolver:
|
|
130
|
+
resolver: stepResolver as PlayStepProgramStep['resolver'],
|
|
108
131
|
},
|
|
109
132
|
],
|
|
110
133
|
this.returnResolver as StepResolver<
|
|
111
|
-
Output & Record<Name, Value>,
|
|
134
|
+
Output & Record<Name, Value | null>,
|
|
112
135
|
ReturnValue
|
|
113
136
|
>,
|
|
114
137
|
);
|
|
@@ -121,6 +144,16 @@ class WorkerStepProgram<Input, Output, ReturnValue> implements StepProgram<
|
|
|
121
144
|
}
|
|
122
145
|
}
|
|
123
146
|
|
|
147
|
+
function isConditionalStepResolver(
|
|
148
|
+
value: unknown,
|
|
149
|
+
): value is ConditionalStepResolver<unknown, unknown> {
|
|
150
|
+
return (
|
|
151
|
+
value !== null &&
|
|
152
|
+
typeof value === 'object' &&
|
|
153
|
+
(value as { kind?: unknown }).kind === 'conditional'
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
|
|
124
157
|
export function steps<TInput>(): StepProgram<TInput, TInput, TInput> {
|
|
125
158
|
return new WorkerStepProgram<TInput, TInput, TInput>([]);
|
|
126
159
|
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
export type StepProgramDatasetOptions = {
|
|
2
|
+
runIf?: (
|
|
3
|
+
row: Record<string, unknown>,
|
|
4
|
+
index: number,
|
|
5
|
+
) => boolean | Promise<boolean>;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export type StepProgramDatasetStep<TResolver> = {
|
|
9
|
+
name: string;
|
|
10
|
+
resolver: TResolver;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export type StepProgramDatasetProgram<TStep> = {
|
|
14
|
+
kind: 'steps';
|
|
15
|
+
steps: readonly TStep[];
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export type StepProgramDatasetConditionalResolver<TResolver> = {
|
|
19
|
+
kind: 'conditional';
|
|
20
|
+
when: (
|
|
21
|
+
row: Record<string, unknown>,
|
|
22
|
+
index: number,
|
|
23
|
+
) => boolean | Promise<boolean>;
|
|
24
|
+
run: TResolver;
|
|
25
|
+
elseValue?: unknown;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export function isStepProgramDatasetProgram<TStep>(
|
|
29
|
+
value: unknown,
|
|
30
|
+
): value is StepProgramDatasetProgram<TStep> {
|
|
31
|
+
return (
|
|
32
|
+
value !== null &&
|
|
33
|
+
typeof value === 'object' &&
|
|
34
|
+
(value as { kind?: unknown }).kind === 'steps' &&
|
|
35
|
+
Array.isArray((value as { steps?: unknown }).steps)
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function isStepProgramDatasetConditionalResolver<TResolver>(
|
|
40
|
+
value: unknown,
|
|
41
|
+
): value is StepProgramDatasetConditionalResolver<TResolver> {
|
|
42
|
+
return (
|
|
43
|
+
value !== null &&
|
|
44
|
+
typeof value === 'object' &&
|
|
45
|
+
(value as { kind?: unknown }).kind === 'conditional' &&
|
|
46
|
+
typeof (value as { when?: unknown }).when === 'function' &&
|
|
47
|
+
typeof (value as { run?: unknown }).run === 'function'
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export class StepProgramDatasetBuilder<
|
|
52
|
+
TStep extends StepProgramDatasetStep<TResolver>,
|
|
53
|
+
TResolver,
|
|
54
|
+
TRunOptions,
|
|
55
|
+
TResult,
|
|
56
|
+
> {
|
|
57
|
+
private readonly program: StepProgramDatasetProgram<TStep> = {
|
|
58
|
+
kind: 'steps',
|
|
59
|
+
steps: [],
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
constructor(
|
|
63
|
+
private readonly runProgram: (
|
|
64
|
+
program: StepProgramDatasetProgram<TStep>,
|
|
65
|
+
options?: TRunOptions,
|
|
66
|
+
) => TResult,
|
|
67
|
+
private readonly messages: {
|
|
68
|
+
emptyColumnName: string;
|
|
69
|
+
invalidColumnsProgram: string;
|
|
70
|
+
legacyStep: string;
|
|
71
|
+
},
|
|
72
|
+
) {}
|
|
73
|
+
|
|
74
|
+
withColumn(
|
|
75
|
+
name: string,
|
|
76
|
+
resolver: TResolver,
|
|
77
|
+
options?: StepProgramDatasetOptions,
|
|
78
|
+
): this {
|
|
79
|
+
if (!name.trim()) {
|
|
80
|
+
throw new Error(this.messages.emptyColumnName);
|
|
81
|
+
}
|
|
82
|
+
this.program.steps = [
|
|
83
|
+
...this.program.steps,
|
|
84
|
+
{
|
|
85
|
+
name,
|
|
86
|
+
resolver: this.applyDerivationOptions(resolver, options),
|
|
87
|
+
} as TStep,
|
|
88
|
+
];
|
|
89
|
+
return this;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
withColumns(program: StepProgramDatasetProgram<TStep>): this {
|
|
93
|
+
if (!isStepProgramDatasetProgram<TStep>(program)) {
|
|
94
|
+
throw new Error(this.messages.invalidColumnsProgram);
|
|
95
|
+
}
|
|
96
|
+
this.program.steps = [...this.program.steps, ...program.steps];
|
|
97
|
+
return this;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
step(): never {
|
|
101
|
+
throw new Error(this.messages.legacyStep);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
run(options?: TRunOptions): TResult {
|
|
105
|
+
return this.runProgram(this.program, options);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
private applyDerivationOptions(
|
|
109
|
+
resolver: TResolver,
|
|
110
|
+
options?: StepProgramDatasetOptions,
|
|
111
|
+
): TResolver {
|
|
112
|
+
if (
|
|
113
|
+
!options?.runIf ||
|
|
114
|
+
isStepProgramDatasetConditionalResolver<TResolver>(resolver)
|
|
115
|
+
) {
|
|
116
|
+
return resolver;
|
|
117
|
+
}
|
|
118
|
+
return {
|
|
119
|
+
kind: 'conditional',
|
|
120
|
+
when: options.runIf,
|
|
121
|
+
run: resolver,
|
|
122
|
+
elseValue: null,
|
|
123
|
+
} as TResolver;
|
|
124
|
+
}
|
|
125
|
+
}
|