veryfront 0.0.7 → 0.0.9
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/ai/index.js +173 -11
- package/dist/ai/index.js.map +2 -2
- package/dist/cli.js +1203 -596
- package/dist/components.js +125 -41
- package/dist/components.js.map +3 -3
- package/dist/config.js +12 -5
- package/dist/config.js.map +2 -2
- package/dist/data.js +2 -1
- package/dist/data.js.map +2 -2
- package/dist/index.js +129 -41
- package/dist/index.js.map +3 -3
- package/package.json +2 -2
package/dist/ai/index.js
CHANGED
|
@@ -1675,7 +1675,7 @@ var BYTES_PER_MB = 1024 * 1024;
|
|
|
1675
1675
|
// deno.json
|
|
1676
1676
|
var deno_default = {
|
|
1677
1677
|
name: "veryfront",
|
|
1678
|
-
version: "0.0.
|
|
1678
|
+
version: "0.0.8",
|
|
1679
1679
|
nodeModulesDir: "auto",
|
|
1680
1680
|
workspace: [
|
|
1681
1681
|
"./examples/async-worker-redis",
|
|
@@ -1804,6 +1804,7 @@ var deno_default = {
|
|
|
1804
1804
|
dev: "deno run --allow-all --no-lock --unstable-net --unstable-worker-options src/cli/main.ts dev",
|
|
1805
1805
|
build: "deno compile --allow-all --output ../../bin/veryfront src/cli/main.ts",
|
|
1806
1806
|
"build:npm": "deno run -A scripts/build-npm.ts",
|
|
1807
|
+
release: "deno run -A scripts/release.ts",
|
|
1807
1808
|
test: "DENO_JOBS=1 deno test --parallel --fail-fast --allow-all --unstable-worker-options --unstable-net",
|
|
1808
1809
|
"test:unit": "DENO_JOBS=1 deno test --parallel --allow-all --v8-flags=--max-old-space-size=8192 --ignore=tests --unstable-worker-options --unstable-net",
|
|
1809
1810
|
"test:integration": "DENO_JOBS=1 deno test --parallel --fail-fast --allow-all tests --unstable-worker-options --unstable-net",
|
|
@@ -3466,6 +3467,7 @@ var DEFAULT_CONFIG2 = {
|
|
|
3466
3467
|
}
|
|
3467
3468
|
};
|
|
3468
3469
|
var configCacheByProject = /* @__PURE__ */ new Map();
|
|
3470
|
+
var cacheRevision = 0;
|
|
3469
3471
|
function validateCorsConfig(userConfig) {
|
|
3470
3472
|
if (!userConfig || typeof userConfig !== "object") {
|
|
3471
3473
|
return;
|
|
@@ -3542,13 +3544,18 @@ var ConfigValidationError = class extends Error {
|
|
|
3542
3544
|
};
|
|
3543
3545
|
async function loadAndMergeConfig(configPath, projectDir) {
|
|
3544
3546
|
try {
|
|
3545
|
-
const configUrl = `file://${configPath}?t=${Date.now()}`;
|
|
3547
|
+
const configUrl = `file://${configPath}?t=${Date.now()}-${crypto.randomUUID()}`;
|
|
3546
3548
|
const configModule = await import(configUrl);
|
|
3547
3549
|
const userConfig = configModule.default || configModule;
|
|
3550
|
+
if (userConfig === null || typeof userConfig !== "object" || Array.isArray(userConfig)) {
|
|
3551
|
+
throw new ConfigValidationError(
|
|
3552
|
+
`Expected object, received ${userConfig === null ? "null" : typeof userConfig}`
|
|
3553
|
+
);
|
|
3554
|
+
}
|
|
3548
3555
|
validateCorsConfig(userConfig);
|
|
3549
3556
|
validateConfigShape(userConfig);
|
|
3550
3557
|
const merged = mergeConfigs(userConfig);
|
|
3551
|
-
configCacheByProject.set(projectDir, merged);
|
|
3558
|
+
configCacheByProject.set(projectDir, { revision: cacheRevision, config: merged });
|
|
3552
3559
|
return merged;
|
|
3553
3560
|
} catch (error) {
|
|
3554
3561
|
if (error instanceof ConfigValidationError) {
|
|
@@ -3562,8 +3569,8 @@ async function loadAndMergeConfig(configPath, projectDir) {
|
|
|
3562
3569
|
}
|
|
3563
3570
|
async function getConfig(projectDir, adapter) {
|
|
3564
3571
|
const cached = configCacheByProject.get(projectDir);
|
|
3565
|
-
if (cached)
|
|
3566
|
-
return cached;
|
|
3572
|
+
if (cached && cached.revision === cacheRevision)
|
|
3573
|
+
return cached.config;
|
|
3567
3574
|
const configFiles = ["veryfront.config.js", "veryfront.config.ts", "veryfront.config.mjs"];
|
|
3568
3575
|
for (const configFile of configFiles) {
|
|
3569
3576
|
const configPath = join(projectDir, configFile);
|
|
@@ -3589,7 +3596,7 @@ async function getConfig(projectDir, adapter) {
|
|
|
3589
3596
|
}
|
|
3590
3597
|
}
|
|
3591
3598
|
const defaultConfig = DEFAULT_CONFIG2;
|
|
3592
|
-
configCacheByProject.set(projectDir, defaultConfig);
|
|
3599
|
+
configCacheByProject.set(projectDir, { revision: cacheRevision, config: defaultConfig });
|
|
3593
3600
|
return defaultConfig;
|
|
3594
3601
|
}
|
|
3595
3602
|
|
|
@@ -5921,20 +5928,172 @@ var DAGExecutor = class {
|
|
|
5921
5928
|
return await this.executeStepNode(node, context);
|
|
5922
5929
|
case "parallel":
|
|
5923
5930
|
return await this.executeParallelNode(node, config, context, nodeStates);
|
|
5931
|
+
case "map":
|
|
5932
|
+
return await this.executeMapNode(node, config, context, nodeStates);
|
|
5924
5933
|
case "branch":
|
|
5925
5934
|
return await this.executeBranchNode(node, config, context, nodeStates);
|
|
5926
5935
|
case "wait":
|
|
5927
5936
|
return await this.executeWaitNode(node, config, context);
|
|
5928
5937
|
case "subWorkflow":
|
|
5929
|
-
|
|
5930
|
-
`Sub-workflow execution is not yet implemented for node "${node.id}". Workaround: Flatten your workflow by inlining the sub-workflow steps directly, or use the parallel() or branch() DSL helpers to compose workflows.`
|
|
5931
|
-
);
|
|
5938
|
+
return await this.executeSubWorkflowNode(node, config, context, nodeStates);
|
|
5932
5939
|
default:
|
|
5933
5940
|
throw new Error(
|
|
5934
|
-
`Unknown node type "${config.type}" for node "${node.id}". Valid types are: step, parallel, branch, wait, subWorkflow`
|
|
5941
|
+
`Unknown node type "${config.type}" for node "${node.id}". Valid types are: step, parallel, map, branch, wait, subWorkflow`
|
|
5935
5942
|
);
|
|
5936
5943
|
}
|
|
5937
5944
|
}
|
|
5945
|
+
/**
|
|
5946
|
+
* Execute a map node (dynamic fan-out)
|
|
5947
|
+
*/
|
|
5948
|
+
async executeMapNode(node, config, context, nodeStates) {
|
|
5949
|
+
const startTime = Date.now();
|
|
5950
|
+
const items = typeof config.items === "function" ? await config.items(context) : config.items;
|
|
5951
|
+
if (!Array.isArray(items)) {
|
|
5952
|
+
throw new Error(`Map node "${node.id}" items must be an array`);
|
|
5953
|
+
}
|
|
5954
|
+
if (items.length === 0) {
|
|
5955
|
+
const state = {
|
|
5956
|
+
nodeId: node.id,
|
|
5957
|
+
status: "completed",
|
|
5958
|
+
output: [],
|
|
5959
|
+
attempt: 1,
|
|
5960
|
+
startedAt: new Date(startTime),
|
|
5961
|
+
completedAt: /* @__PURE__ */ new Date()
|
|
5962
|
+
};
|
|
5963
|
+
return { state, contextUpdates: { [node.id]: [] }, waiting: false };
|
|
5964
|
+
}
|
|
5965
|
+
const childNodes = [];
|
|
5966
|
+
const isWorkflowDef = (p) => !!p.steps;
|
|
5967
|
+
for (let i = 0; i < items.length; i++) {
|
|
5968
|
+
const item = items[i];
|
|
5969
|
+
const childId = `${node.id}_${i}`;
|
|
5970
|
+
let childNode;
|
|
5971
|
+
if (isWorkflowDef(config.processor)) {
|
|
5972
|
+
childNode = {
|
|
5973
|
+
id: childId,
|
|
5974
|
+
config: {
|
|
5975
|
+
type: "subWorkflow",
|
|
5976
|
+
workflow: config.processor,
|
|
5977
|
+
input: item,
|
|
5978
|
+
retry: config.retry,
|
|
5979
|
+
checkpoint: false
|
|
5980
|
+
// Don't checkpoint individual map items by default
|
|
5981
|
+
}
|
|
5982
|
+
};
|
|
5983
|
+
} else {
|
|
5984
|
+
const processorConfig = { ...config.processor.config };
|
|
5985
|
+
if (processorConfig.type === "step") {
|
|
5986
|
+
processorConfig.input = item;
|
|
5987
|
+
}
|
|
5988
|
+
childNode = {
|
|
5989
|
+
id: childId,
|
|
5990
|
+
config: processorConfig
|
|
5991
|
+
};
|
|
5992
|
+
}
|
|
5993
|
+
childNodes.push(childNode);
|
|
5994
|
+
}
|
|
5995
|
+
const originalConcurrency = this.config.maxConcurrency;
|
|
5996
|
+
if (config.concurrency) {
|
|
5997
|
+
this.config.maxConcurrency = config.concurrency;
|
|
5998
|
+
}
|
|
5999
|
+
try {
|
|
6000
|
+
const result = await this.execute(childNodes, {
|
|
6001
|
+
id: `${node.id}_map`,
|
|
6002
|
+
workflowId: "",
|
|
6003
|
+
status: "running",
|
|
6004
|
+
input: context.input,
|
|
6005
|
+
nodeStates: {},
|
|
6006
|
+
// Start fresh for map iteration
|
|
6007
|
+
currentNodes: [],
|
|
6008
|
+
context: { ...context },
|
|
6009
|
+
// Pass copy of context so they can read global state
|
|
6010
|
+
checkpoints: [],
|
|
6011
|
+
pendingApprovals: [],
|
|
6012
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
6013
|
+
});
|
|
6014
|
+
Object.assign(nodeStates, result.nodeStates);
|
|
6015
|
+
const outputs = childNodes.map((child) => {
|
|
6016
|
+
const childState = result.nodeStates[child.id];
|
|
6017
|
+
return childState?.output;
|
|
6018
|
+
});
|
|
6019
|
+
const state = {
|
|
6020
|
+
nodeId: node.id,
|
|
6021
|
+
status: result.completed ? "completed" : result.waiting ? "running" : "failed",
|
|
6022
|
+
output: outputs,
|
|
6023
|
+
error: result.error,
|
|
6024
|
+
attempt: 1,
|
|
6025
|
+
startedAt: new Date(startTime),
|
|
6026
|
+
completedAt: result.completed ? /* @__PURE__ */ new Date() : void 0
|
|
6027
|
+
};
|
|
6028
|
+
this.config.onNodeComplete?.(node.id, state);
|
|
6029
|
+
return {
|
|
6030
|
+
state,
|
|
6031
|
+
contextUpdates: result.completed ? { [node.id]: outputs } : {},
|
|
6032
|
+
waiting: result.waiting
|
|
6033
|
+
};
|
|
6034
|
+
} finally {
|
|
6035
|
+
this.config.maxConcurrency = originalConcurrency;
|
|
6036
|
+
}
|
|
6037
|
+
}
|
|
6038
|
+
/**
|
|
6039
|
+
* Execute a sub-workflow node
|
|
6040
|
+
*/
|
|
6041
|
+
async executeSubWorkflowNode(node, config, context, nodeStates) {
|
|
6042
|
+
const startTime = Date.now();
|
|
6043
|
+
let workflowDef;
|
|
6044
|
+
if (typeof config.workflow === "string") {
|
|
6045
|
+
throw new Error("Resolving workflow by ID is not yet supported in this execution context. Pass the WorkflowDefinition object.");
|
|
6046
|
+
} else {
|
|
6047
|
+
workflowDef = config.workflow;
|
|
6048
|
+
}
|
|
6049
|
+
const input = typeof config.input === "function" ? await config.input(context) : config.input ?? context.input;
|
|
6050
|
+
let steps;
|
|
6051
|
+
if (typeof workflowDef.steps === "function") {
|
|
6052
|
+
steps = workflowDef.steps({
|
|
6053
|
+
input,
|
|
6054
|
+
context
|
|
6055
|
+
});
|
|
6056
|
+
} else {
|
|
6057
|
+
steps = workflowDef.steps;
|
|
6058
|
+
}
|
|
6059
|
+
const subRunId = `${node.id}_sub_${generateId()}`;
|
|
6060
|
+
const result = await this.execute(steps, {
|
|
6061
|
+
id: subRunId,
|
|
6062
|
+
workflowId: workflowDef.id,
|
|
6063
|
+
status: "running",
|
|
6064
|
+
input,
|
|
6065
|
+
nodeStates: {},
|
|
6066
|
+
currentNodes: [],
|
|
6067
|
+
context: {
|
|
6068
|
+
input
|
|
6069
|
+
// Subworkflow starts with fresh context scoped to its input
|
|
6070
|
+
// We do NOT inherit parent context to ensure isolation,
|
|
6071
|
+
// unless explicitly passed via input.
|
|
6072
|
+
},
|
|
6073
|
+
checkpoints: [],
|
|
6074
|
+
pendingApprovals: [],
|
|
6075
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
6076
|
+
});
|
|
6077
|
+
let finalOutput = result.context;
|
|
6078
|
+
if (result.completed && config.output) {
|
|
6079
|
+
finalOutput = config.output(result.context);
|
|
6080
|
+
}
|
|
6081
|
+
const state = {
|
|
6082
|
+
nodeId: node.id,
|
|
6083
|
+
status: result.completed ? "completed" : result.waiting ? "running" : "failed",
|
|
6084
|
+
output: finalOutput,
|
|
6085
|
+
error: result.error,
|
|
6086
|
+
attempt: 1,
|
|
6087
|
+
startedAt: new Date(startTime),
|
|
6088
|
+
completedAt: result.completed ? /* @__PURE__ */ new Date() : void 0
|
|
6089
|
+
};
|
|
6090
|
+
this.config.onNodeComplete?.(node.id, state);
|
|
6091
|
+
return {
|
|
6092
|
+
state,
|
|
6093
|
+
contextUpdates: result.completed ? { [node.id]: finalOutput } : {},
|
|
6094
|
+
waiting: result.waiting
|
|
6095
|
+
};
|
|
6096
|
+
}
|
|
5938
6097
|
/**
|
|
5939
6098
|
* Execute a step node
|
|
5940
6099
|
*/
|
|
@@ -6745,9 +6904,12 @@ var WorkflowExecutor = class _WorkflowExecutor {
|
|
|
6745
6904
|
if (Array.isArray(workflow2.steps)) {
|
|
6746
6905
|
nodes = workflow2.steps;
|
|
6747
6906
|
} else {
|
|
6907
|
+
if (!this.config.blobStorage) {
|
|
6908
|
+
}
|
|
6748
6909
|
const builderContext = {
|
|
6749
6910
|
input: context.input,
|
|
6750
|
-
context
|
|
6911
|
+
context,
|
|
6912
|
+
blobStorage: this.config.blobStorage
|
|
6751
6913
|
};
|
|
6752
6914
|
nodes = workflow2.steps(builderContext);
|
|
6753
6915
|
}
|