@teamkeel/functions-runtime 0.413.9 → 0.414.0
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/dist/index.cjs +65 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +30 -7
- package/dist/index.d.ts +30 -7
- package/dist/index.js +65 -12
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2454,9 +2454,16 @@ var selectOne = /* @__PURE__ */ __name((name, options) => {
|
|
|
2454
2454
|
}, "selectOne");
|
|
2455
2455
|
|
|
2456
2456
|
// src/flows/ui/page.ts
|
|
2457
|
-
async function page(options, data) {
|
|
2457
|
+
async function page(options, data, action) {
|
|
2458
2458
|
const content = options.content;
|
|
2459
2459
|
let hasValidationErrors = false;
|
|
2460
|
+
if (options.actions) {
|
|
2461
|
+
const isValidAction = options.actions.some((a) => {
|
|
2462
|
+
if (typeof a === "string") return a === action;
|
|
2463
|
+
return a && typeof a === "object" && "label" in a && a.label === action;
|
|
2464
|
+
});
|
|
2465
|
+
hasValidationErrors = !isValidAction;
|
|
2466
|
+
}
|
|
2460
2467
|
const contentUiConfig = await Promise.all(
|
|
2461
2468
|
content.map(async (c) => {
|
|
2462
2469
|
const isInput = "__type" in c && c.__type == "input";
|
|
@@ -2607,15 +2614,33 @@ var header = /* @__PURE__ */ __name((options) => {
|
|
|
2607
2614
|
|
|
2608
2615
|
// src/flows/index.ts
|
|
2609
2616
|
var defaultOpts = {
|
|
2610
|
-
|
|
2611
|
-
|
|
2617
|
+
retries: 5,
|
|
2618
|
+
timeout: 6e4
|
|
2612
2619
|
};
|
|
2613
|
-
function createFlowContext(runId, data, spanId) {
|
|
2620
|
+
function createFlowContext(runId, data, action, spanId, ctx) {
|
|
2621
|
+
const usedNames = /* @__PURE__ */ new Set();
|
|
2614
2622
|
return {
|
|
2623
|
+
env: ctx.env,
|
|
2624
|
+
now: ctx.now,
|
|
2625
|
+
secrets: ctx.secrets,
|
|
2615
2626
|
step: /* @__PURE__ */ __name(async (name, optionsOrFn, fn) => {
|
|
2616
2627
|
const options = typeof optionsOrFn === "function" ? {} : optionsOrFn;
|
|
2617
2628
|
const actualFn = typeof optionsOrFn === "function" ? optionsOrFn : fn;
|
|
2618
2629
|
const db = useDatabase();
|
|
2630
|
+
if (usedNames.has(name)) {
|
|
2631
|
+
await db.insertInto("keel.flow_step").values({
|
|
2632
|
+
run_id: runId,
|
|
2633
|
+
name,
|
|
2634
|
+
stage: options.stage,
|
|
2635
|
+
status: "FAILED" /* FAILED */,
|
|
2636
|
+
type: "FUNCTION" /* FUNCTION */,
|
|
2637
|
+
error: `Duplicate step name: ${name}`,
|
|
2638
|
+
startTime: /* @__PURE__ */ new Date(),
|
|
2639
|
+
endTime: /* @__PURE__ */ new Date()
|
|
2640
|
+
}).returningAll().executeTakeFirst();
|
|
2641
|
+
throw new Error(`Duplicate step name: ${name}`);
|
|
2642
|
+
}
|
|
2643
|
+
usedNames.add(name);
|
|
2619
2644
|
const past = await db.selectFrom("keel.flow_step").where("run_id", "=", runId).where("name", "=", name).selectAll().execute();
|
|
2620
2645
|
const newSteps = past.filter((step) => step.status === "NEW" /* NEW */);
|
|
2621
2646
|
const completedSteps = past.filter(
|
|
@@ -2646,7 +2671,7 @@ function createFlowContext(runId, data, spanId) {
|
|
|
2646
2671
|
try {
|
|
2647
2672
|
result = await withTimeout(
|
|
2648
2673
|
actualFn(),
|
|
2649
|
-
options.
|
|
2674
|
+
options.timeout ?? defaultOpts.timeout
|
|
2650
2675
|
);
|
|
2651
2676
|
} catch (e) {
|
|
2652
2677
|
await db.updateTable("keel.flow_step").set({
|
|
@@ -2655,7 +2680,7 @@ function createFlowContext(runId, data, spanId) {
|
|
|
2655
2680
|
endTime: /* @__PURE__ */ new Date(),
|
|
2656
2681
|
error: e instanceof Error ? e.message : "An error occurred"
|
|
2657
2682
|
}).where("id", "=", newSteps[0].id).returningAll().executeTakeFirst();
|
|
2658
|
-
if (failedSteps.length + 1 >= (options.
|
|
2683
|
+
if (failedSteps.length + 1 >= (options.retries ?? defaultOpts.retries)) {
|
|
2659
2684
|
throw new ExhuastedRetriesDisrupt();
|
|
2660
2685
|
}
|
|
2661
2686
|
await db.insertInto("keel.flow_step").values({
|
|
@@ -2687,8 +2712,25 @@ function createFlowContext(runId, data, spanId) {
|
|
|
2687
2712
|
ui: {
|
|
2688
2713
|
page: /* @__PURE__ */ __name(async (name, options) => {
|
|
2689
2714
|
const db = useDatabase();
|
|
2715
|
+
if (usedNames.has(name)) {
|
|
2716
|
+
await db.insertInto("keel.flow_step").values({
|
|
2717
|
+
run_id: runId,
|
|
2718
|
+
name,
|
|
2719
|
+
stage: options.stage,
|
|
2720
|
+
status: "FAILED" /* FAILED */,
|
|
2721
|
+
type: "UI" /* UI */,
|
|
2722
|
+
error: `Duplicate step name: ${name}`,
|
|
2723
|
+
startTime: /* @__PURE__ */ new Date(),
|
|
2724
|
+
endTime: /* @__PURE__ */ new Date()
|
|
2725
|
+
}).returningAll().executeTakeFirst();
|
|
2726
|
+
throw new Error(`Duplicate step name: ${name}`);
|
|
2727
|
+
}
|
|
2728
|
+
usedNames.add(name);
|
|
2690
2729
|
let step = await db.selectFrom("keel.flow_step").where("run_id", "=", runId).where("name", "=", name).selectAll().executeTakeFirst();
|
|
2691
2730
|
if (step && step.status === "COMPLETED" /* COMPLETED */) {
|
|
2731
|
+
if (step.action) {
|
|
2732
|
+
return { data: step.value, action: step.action };
|
|
2733
|
+
}
|
|
2692
2734
|
return step.value;
|
|
2693
2735
|
}
|
|
2694
2736
|
if (!step) {
|
|
@@ -2700,22 +2742,29 @@ function createFlowContext(runId, data, spanId) {
|
|
|
2700
2742
|
type: "UI" /* UI */,
|
|
2701
2743
|
startTime: /* @__PURE__ */ new Date()
|
|
2702
2744
|
}).returningAll().executeTakeFirst();
|
|
2703
|
-
throw new UIRenderDisrupt(
|
|
2745
|
+
throw new UIRenderDisrupt(
|
|
2746
|
+
step?.id,
|
|
2747
|
+
(await page(options, null, null)).page
|
|
2748
|
+
);
|
|
2704
2749
|
}
|
|
2705
2750
|
if (!data) {
|
|
2706
|
-
throw new UIRenderDisrupt(
|
|
2751
|
+
throw new UIRenderDisrupt(
|
|
2752
|
+
step?.id,
|
|
2753
|
+
(await page(options, null, null)).page
|
|
2754
|
+
);
|
|
2707
2755
|
}
|
|
2708
|
-
const p = await page(options, data);
|
|
2756
|
+
const p = await page(options, data, action);
|
|
2709
2757
|
if (p.hasValidationErrors) {
|
|
2710
2758
|
throw new UIRenderDisrupt(step?.id, p.page);
|
|
2711
2759
|
}
|
|
2712
2760
|
await db.updateTable("keel.flow_step").set({
|
|
2713
2761
|
status: "COMPLETED" /* COMPLETED */,
|
|
2714
2762
|
value: JSON.stringify(data),
|
|
2763
|
+
action,
|
|
2715
2764
|
spanId,
|
|
2716
2765
|
endTime: /* @__PURE__ */ new Date()
|
|
2717
2766
|
}).where("id", "=", step.id).returningAll().executeTakeFirst();
|
|
2718
|
-
return data;
|
|
2767
|
+
return { data, action };
|
|
2719
2768
|
}, "page"),
|
|
2720
2769
|
inputs: {
|
|
2721
2770
|
text: textInput,
|
|
@@ -2770,7 +2819,7 @@ async function handleFlow(request, config) {
|
|
|
2770
2819
|
if (!runId) {
|
|
2771
2820
|
throw new Error("no runId provided");
|
|
2772
2821
|
}
|
|
2773
|
-
const { flows } = config;
|
|
2822
|
+
const { flows, createFlowContextAPI } = config;
|
|
2774
2823
|
if (!(request.method in flows)) {
|
|
2775
2824
|
const message = `no corresponding flow found for '${request.method}'`;
|
|
2776
2825
|
span.setStatus({
|
|
@@ -2789,7 +2838,11 @@ async function handleFlow(request, config) {
|
|
|
2789
2838
|
const ctx = createFlowContext(
|
|
2790
2839
|
request.meta.runId,
|
|
2791
2840
|
request.meta.data,
|
|
2792
|
-
|
|
2841
|
+
request.meta.action,
|
|
2842
|
+
span.spanContext().spanId,
|
|
2843
|
+
createFlowContextAPI({
|
|
2844
|
+
meta: request.meta
|
|
2845
|
+
})
|
|
2793
2846
|
);
|
|
2794
2847
|
const flowFunction = flows[request.method].fn;
|
|
2795
2848
|
const rawFlowConfig = flows[request.method].config;
|