Skip to content

Commit 0cacb99

Browse files
authored
Support nested "use step" declarations in non-workflow functions (#418)
1 parent 87ad24b commit 0cacb99

File tree

21 files changed

+774
-99
lines changed

21 files changed

+774
-99
lines changed

.changeset/sixty-carpets-join.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@workflow/swc-plugin": patch
3+
---
4+
5+
Support nested "use step" declarations in non-workflow functions

packages/swc-plugin-workflow/transform/src/lib.rs

Lines changed: 395 additions & 56 deletions
Large diffs are not rendered by default.

packages/swc-plugin-workflow/transform/tests/errors/non-async-functions/output-client.js

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,6 @@ export const syncWorkflow = ()=>{
99
'use workflow';
1010
return 'test';
1111
};
12-
// Error: sync method with use step
13-
const obj = {
14-
syncMethod () {
15-
'use step';
16-
return true;
17-
}
18-
};
1912
// These are ok
2013
export async function validStep() {
2114
return 42;

packages/swc-plugin-workflow/transform/tests/errors/non-async-functions/output-workflow.js

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,6 @@ export const syncWorkflow = ()=>{
99
'use workflow';
1010
return 'test';
1111
};
12-
// Error: sync method with use step
13-
const obj = {
14-
syncMethod () {
15-
'use step';
16-
return true;
17-
}
18-
};
1912
// These are ok
2013
export var validStep = globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//input.js//validStep");
2114
export const validWorkflow = async ()=>{
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Test case for functions used in default parameter values
2+
// The createDefaultDownloadFunction should NOT be removed by DCE
3+
4+
const createDefaultDownloadFunction = (download = defaultDownload) => (requestedDownloads) =>
5+
Promise.all(requestedDownloads.map(async (r) => r.isUrlSupportedByModel ? null : download(r)));
6+
7+
async function defaultDownload(request) {
8+
return fetch(request.url);
9+
}
10+
11+
// This function uses createDefaultDownloadFunction in a default parameter value
12+
// DCE must NOT remove createDefaultDownloadFunction
13+
async function convertToLanguageModelPrompt({
14+
prompt,
15+
supportedUrls,
16+
download = createDefaultDownloadFunction()
17+
}) {
18+
return { prompt, supportedUrls, download };
19+
}
20+
21+
export async function myWorkflow(input) {
22+
'use workflow';
23+
24+
const result = await convertToLanguageModelPrompt({
25+
prompt: input.prompt,
26+
supportedUrls: {},
27+
download: undefined
28+
});
29+
30+
return result;
31+
}
32+
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// Test case for functions used in default parameter values
2+
// The createDefaultDownloadFunction should NOT be removed by DCE
3+
/**__internal_workflows{"workflows":{"input.js":{"myWorkflow":{"workflowId":"workflow//input.js//myWorkflow"}}}}*/;
4+
export async function myWorkflow(input) {
5+
throw new Error("You attempted to execute workflow myWorkflow function directly. To start a workflow, use start(myWorkflow) from workflow/api");
6+
}
7+
myWorkflow.workflowId = "workflow//input.js//myWorkflow";
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Test case for functions used in default parameter values
2+
// The createDefaultDownloadFunction should NOT be removed by DCE
3+
/**__internal_workflows{"workflows":{"input.js":{"myWorkflow":{"workflowId":"workflow//input.js//myWorkflow"}}}}*/;
4+
const createDefaultDownloadFunction = (download = defaultDownload)=>(requestedDownloads)=>Promise.all(requestedDownloads.map(async (r)=>r.isUrlSupportedByModel ? null : download(r)));
5+
async function defaultDownload(request) {
6+
return fetch(request.url);
7+
}
8+
// This function uses createDefaultDownloadFunction in a default parameter value
9+
// DCE must NOT remove createDefaultDownloadFunction
10+
async function convertToLanguageModelPrompt({ prompt, supportedUrls, download = createDefaultDownloadFunction() }) {
11+
return {
12+
prompt,
13+
supportedUrls,
14+
download
15+
};
16+
}
17+
export async function myWorkflow(input) {
18+
'use workflow';
19+
const result = await convertToLanguageModelPrompt({
20+
prompt: input.prompt,
21+
supportedUrls: {},
22+
download: undefined
23+
});
24+
return result;
25+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Test case for functions used in default parameter values
2+
// The createDefaultDownloadFunction should NOT be removed by DCE
3+
/**__internal_workflows{"workflows":{"input.js":{"myWorkflow":{"workflowId":"workflow//input.js//myWorkflow"}}}}*/;
4+
const createDefaultDownloadFunction = (download = defaultDownload)=>(requestedDownloads)=>Promise.all(requestedDownloads.map(async (r)=>r.isUrlSupportedByModel ? null : download(r)));
5+
async function defaultDownload(request) {
6+
return fetch(request.url);
7+
}
8+
// This function uses createDefaultDownloadFunction in a default parameter value
9+
// DCE must NOT remove createDefaultDownloadFunction
10+
async function convertToLanguageModelPrompt({ prompt, supportedUrls, download = createDefaultDownloadFunction() }) {
11+
return {
12+
prompt,
13+
supportedUrls,
14+
download
15+
};
16+
}
17+
export async function myWorkflow(input) {
18+
const result = await convertToLanguageModelPrompt({
19+
prompt: input.prompt,
20+
supportedUrls: {},
21+
download: undefined
22+
});
23+
return result;
24+
}
25+
myWorkflow.workflowId = "workflow//input.js//myWorkflow";

packages/swc-plugin-workflow/transform/tests/fixture/module-level-step/output-client.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
/**__internal_workflows{"steps":{"input.js":{"step":{"stepId":"step//input.js//step"},"stepArrow":{"stepId":"step//input.js//stepArrow"}}}}*/;
2-
const localArrow = async (input)=>{
3-
return input.bar;
4-
};
52
export async function step(input) {
63
return input.foo;
74
}
Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
/**__internal_workflows{"steps":{"input.js":{"step":{"stepId":"step//input.js//step"},"stepArrow":{"stepId":"step//input.js//stepArrow"}}}}*/;
22
'use step';
3-
const localArrow = async (input)=>{
4-
return input.bar;
5-
};
63
export var step = globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//input.js//step");
74
export const stepArrow = globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//input.js//stepArrow");

0 commit comments

Comments
 (0)