@oomol-lab/open-flow 0.1.0-beta.72 → 0.1.0-beta.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/LICENSE +36 -0
- package/NOTICE +7 -0
- package/README.md +40 -0
- package/dist/browser/{createResourceDialog-BWJkjiOO.js → createResourceDialog-DI9pL-Yr.js} +2 -2
- package/dist/browser/{dialog-CUy_fwx9.js → dialog-BYJGvItc.js} +54 -19
- package/dist/browser/{flowChanges-CgSnSqqP.js → flowChanges-RL-H4CjD.js} +306 -48
- package/dist/browser/{flowWorkspace-Bf7H-r0t.js → flowWorkspace-BkDsETj0.js} +20745 -20186
- package/dist/browser/preview.css +73 -3
- package/dist/browser/preview.js +21410 -20607
- package/dist/browser/{typeScriptSession-B0hC-C8y.js → typeScriptSession-CSRwWmZm.js} +1 -1
- package/dist/browser/ui.css +72 -2
- package/dist/browser/workbench.css +73 -3
- package/dist/browser/workbench.js +14 -76
- package/dist/browser/{workbenchSelect-C3e4J93X.js → workbenchSelect-BcWPWGzw.js} +1 -1
- package/dist/command/index.js +34 -34
- package/dist/common/authoring.d.ts +1 -1
- package/dist/common/authoringFields.d.ts +1 -1
- package/dist/common/authoringSchema.d.ts +28 -4
- package/dist/common/connector-proxy.d.ts +1 -1
- package/dist/common/control-api-conformance.d.ts +1 -1
- package/dist/common/control-api-conformance.js +61 -24
- package/dist/common/control-api.d.ts +4 -3
- package/dist/common/control-api.js +90 -42
- package/dist/common/control-requests.d.ts +2 -1
- package/dist/common/control-requests.js +204 -42
- package/dist/common/cron-trigger.d.ts +1 -1
- package/dist/common/decision.d.ts +1 -1
- package/dist/common/draftOperations.d.ts +1 -1
- package/dist/common/engine-contract.d.ts +3 -2
- package/dist/common/event-source-definition.d.ts +1 -1
- package/dist/common/flow-agent.d.ts +1 -1
- package/dist/{browser → common}/flow-authoring-node.d.ts +3 -3
- package/dist/{browser → common}/flow-authoring.js +75 -23
- package/dist/{browser → common}/flow-change-schema.d.ts +177 -6
- package/dist/{browser → common}/flow-change.d.ts +35 -15
- package/dist/{browser → common}/flow-change.js +77 -25
- package/dist/common/flow-connectionUsage.d.ts +1 -1
- package/dist/common/flow-encoding.d.ts +1 -1
- package/dist/common/flow-encoding.js +34 -16
- package/dist/common/flow-errorHandling.d.ts +1 -1
- package/dist/common/flow-graph.d.ts +1 -1
- package/dist/common/flow-modules.d.ts +1 -1
- package/dist/common/flow-promptTemplate.d.ts +1 -1
- package/dist/common/flow-retry.d.ts +1 -1
- package/dist/common/flow-semantics.d.ts +1 -1
- package/dist/common/flow-semantics.js +151 -32
- package/dist/common/flow-workflowFile.d.ts +1 -1
- package/dist/common/flowInspection.d.ts +3 -3
- package/dist/common/integration-trigger.d.ts +1 -1
- package/dist/common/licenses.md +118 -1
- package/dist/common/liveDetails.d.ts +1 -1
- package/dist/common/mcp.d.ts +2 -1
- package/dist/common/mcp.js +59 -22
- package/dist/common/openapi.d.ts +1 -1
- package/dist/common/poll-trigger.d.ts +1 -1
- package/dist/common/run-results.d.ts +8 -1
- package/dist/common/runtime-contract.d.ts +8 -2
- package/dist/common/runtime-contract.js +22 -5
- package/dist/common/scheduler-checkpoint.d.ts +1 -1
- package/dist/common/scheduler-dependencies.d.ts +1 -1
- package/dist/common/scheduler-node-execution.d.ts +1 -1
- package/dist/common/scheduler.d.ts +2 -2
- package/dist/common/scheduler.js +31 -12
- package/dist/common/trigger-catalog.d.ts +1 -1
- package/dist/common/trigger-config-options.d.ts +1 -1
- package/dist/common/trigger-config.d.ts +1 -1
- package/dist/common/trigger-contract.d.ts +2 -2
- package/dist/common/trigger-localization.d.ts +1 -1
- package/dist/common/webhook-response.d.ts +1 -1
- package/dist/common/webhook-trigger.d.ts +1 -1
- package/dist/common/workflow.d.ts +17 -1
- package/dist/common/workflow.js +68 -22
- package/dist/index.d.ts +6 -3
- package/package.json +7 -6
- package/src/base/common/json.ts +90 -0
- package/src/canvas/common/commands.ts +15 -0
- package/src/connector/common/actionSchema.ts +168 -0
- package/src/connector/common/proxy.ts +44 -0
- package/src/control/common/api.ts +1505 -0
- package/src/control/common/authoring.ts +912 -0
- package/src/control/common/authoringCondition.ts +110 -0
- package/src/control/common/authoringDiagnosticFields.ts +136 -0
- package/src/control/common/authoringExamples.ts +192 -0
- package/src/control/common/authoringFields.ts +53 -0
- package/src/control/common/authoringLlm.ts +70 -0
- package/src/control/common/authoringOpenApi.ts +129 -0
- package/src/control/common/authoringSchema.ts +404 -0
- package/src/control/common/authoringTools.ts +123 -0
- package/src/control/common/authoringTriggers.ts +26 -0
- package/src/control/common/checkDecoders.ts +65 -0
- package/src/control/common/conformance.ts +1989 -0
- package/src/control/common/connectorDecoders.ts +370 -0
- package/src/control/common/connectorQueries.ts +61 -0
- package/src/control/common/decoding.ts +60 -0
- package/src/control/common/draftOperations.ts +61 -0
- package/src/control/common/errors.ts +114 -0
- package/src/control/common/eventSourceSchemas.ts +13 -0
- package/src/control/common/eventSources.ts +186 -0
- package/src/control/common/flowDecoders.ts +153 -0
- package/src/control/common/flowInspection.ts +181 -0
- package/src/control/common/flowNotifications.ts +37 -0
- package/src/control/common/liveDetails.ts +124 -0
- package/src/control/common/mcp.ts +241 -0
- package/src/control/common/mcpConformance.ts +142 -0
- package/src/control/common/providerAccess.ts +28 -0
- package/src/control/common/providerIconSprite.ts +42 -0
- package/src/control/common/publicationDecoders.ts +98 -0
- package/src/control/common/random.ts +16 -0
- package/src/control/common/requests.ts +112 -0
- package/src/control/common/resultQuery.ts +8 -0
- package/src/control/common/results.ts +176 -0
- package/src/control/common/revisionDecoders.ts +52 -0
- package/src/control/common/runDecoders.ts +240 -0
- package/src/control/common/triggerCatalog.ts +89 -0
- package/src/control/common/triggerDecoders.ts +175 -0
- package/src/decision/common/decision.ts +168 -0
- package/src/event-source/common/catalog.generated.json +65 -0
- package/src/event-source/common/definition.ts +66 -0
- package/src/event-source/common/index.ts +99 -0
- package/src/execution/common/checkpoint.ts +311 -0
- package/src/execution/common/dependencies.ts +440 -0
- package/src/execution/common/engineContract.ts +80 -0
- package/src/execution/common/events.ts +328 -0
- package/src/execution/common/node-execution.ts +467 -0
- package/src/execution/common/runLifecycle.ts +250 -0
- package/src/execution/common/runtime.ts +563 -0
- package/src/execution/common/scheduler.ts +696 -0
- package/src/execution/common/wait.ts +36 -0
- package/src/flow/common/agent.ts +305 -0
- package/src/flow/common/authoring.ts +30 -0
- package/src/flow/common/change.ts +1036 -0
- package/src/flow/common/changeSchema.ts +783 -0
- package/src/flow/common/codePermissions.ts +2 -0
- package/src/flow/common/condition.ts +265 -0
- package/src/flow/common/connectionUsage.ts +131 -0
- package/src/flow/common/edgeChanges.ts +35 -0
- package/src/flow/common/encoding.ts +437 -0
- package/src/flow/common/errorHandling.ts +34 -0
- package/src/flow/common/graph.ts +892 -0
- package/src/flow/common/inputValue.ts +16 -0
- package/src/flow/common/json.ts +8 -0
- package/src/flow/common/moduleChanges.ts +31 -0
- package/src/flow/common/modules.ts +292 -0
- package/src/flow/common/nodeChanges.ts +762 -0
- package/src/flow/common/portChanges.ts +36 -0
- package/src/flow/common/promptTemplate.ts +15 -0
- package/src/flow/common/retry.ts +20 -0
- package/src/flow/common/schema.ts +162 -0
- package/src/flow/common/schemaCompare.ts +176 -0
- package/src/flow/common/schemaComparer.ts +178 -0
- package/src/flow/common/schemaKeywords.ts +53 -0
- package/src/flow/common/semantics.ts +474 -0
- package/src/flow/common/sourceField.ts +35 -0
- package/src/flow/common/triggerScheduleSchema.ts +8 -0
- package/src/flow/common/wait.ts +30 -0
- package/src/flow/common/webhookMethod.ts +7 -0
- package/src/flow/common/webhookResponse.ts +75 -0
- package/src/flow/common/workflowFile.ts +97 -0
- package/src/json-schema-subset/checker/array.ts +142 -0
- package/src/json-schema-subset/checker/cache.ts +57 -0
- package/src/json-schema-subset/checker/checker.ts +230 -0
- package/src/json-schema-subset/checker/enumAndConst.ts +113 -0
- package/src/json-schema-subset/checker/equals.ts +93 -0
- package/src/json-schema-subset/checker/numeric/checker.ts +50 -0
- package/src/json-schema-subset/checker/numeric/float.ts +121 -0
- package/src/json-schema-subset/checker/numeric/index.ts +1 -0
- package/src/json-schema-subset/checker/numeric/integer.ts +119 -0
- package/src/json-schema-subset/checker/numeric/integerNormalizer.ts +72 -0
- package/src/json-schema-subset/checker/object.ts +354 -0
- package/src/json-schema-subset/checker/range.ts +91 -0
- package/src/json-schema-subset/checker/string.ts +60 -0
- package/src/json-schema-subset/checker/tools/index.ts +3 -0
- package/src/json-schema-subset/checker/tools/mark.ts +82 -0
- package/src/json-schema-subset/checker/tools/quantum.ts +106 -0
- package/src/json-schema-subset/checker/tools/range.ts +210 -0
- package/src/json-schema-subset/checker/validator.ts +23 -0
- package/src/json-schema-subset/compiler/array.ts +163 -0
- package/src/json-schema-subset/compiler/combination.ts +109 -0
- package/src/json-schema-subset/compiler/common.ts +99 -0
- package/src/json-schema-subset/compiler/compiler.ts +188 -0
- package/src/json-schema-subset/compiler/enumAndConst.ts +75 -0
- package/src/json-schema-subset/compiler/index.ts +11 -0
- package/src/json-schema-subset/compiler/object.ts +411 -0
- package/src/json-schema-subset/compiler/primitive.ts +144 -0
- package/src/json-schema-subset/compiler/utils.ts +24 -0
- package/src/json-schema-subset/compiler/wrapper.ts +192 -0
- package/src/json-schema-subset/error.ts +55 -0
- package/src/json-schema-subset/expression/calculator.ts +442 -0
- package/src/json-schema-subset/expression/combination.ts +49 -0
- package/src/json-schema-subset/expression/expression.ts +191 -0
- package/src/json-schema-subset/expression/index.ts +25 -0
- package/src/json-schema-subset/expression/result.ts +88 -0
- package/src/json-schema-subset/expression/types.ts +36 -0
- package/src/json-schema-subset/extends/extendsContext.ts +89 -0
- package/src/json-schema-subset/extends/index.ts +2 -0
- package/src/json-schema-subset/extends/types.ts +12 -0
- package/src/json-schema-subset/global.ts +60 -0
- package/src/json-schema-subset/index.ts +8 -0
- package/src/json-schema-subset/preprocessing.ts +74 -0
- package/src/json-schema-subset/types.ts +8 -0
- package/src/json-schema-subset/utils.ts +95 -0
- package/src/localization/common/languages.ts +118 -0
- package/src/localization/common/timeZone.ts +25 -0
- package/src/openapi/common/authBindings.ts +12 -0
- package/src/openapi/common/openapi.ts +459 -0
- package/src/trigger/common/config.ts +56 -0
- package/src/trigger/common/configOptions.ts +15 -0
- package/src/trigger/common/configSchema.ts +8 -0
- package/src/trigger/common/contract.ts +132 -0
- package/src/trigger/common/cron.ts +151 -0
- package/src/trigger/common/integration.ts +498 -0
- package/src/trigger/common/poll.ts +187 -0
- package/src/trigger/common/webhook.ts +412 -0
- package/src/trigger/providers/airtable/locales/fr.json +18 -0
- package/src/trigger/providers/airtable/locales/ja.json +18 -0
- package/src/trigger/providers/airtable/locales/ko.json +18 -0
- package/src/trigger/providers/airtable/locales/ru.json +18 -0
- package/src/trigger/providers/airtable/locales/zh-CN.json +18 -0
- package/src/trigger/providers/airtable/locales/zh-TW.json +18 -0
- package/src/trigger/providers/asana/locales/fr.json +15 -0
- package/src/trigger/providers/asana/locales/ja.json +15 -0
- package/src/trigger/providers/asana/locales/ko.json +15 -0
- package/src/trigger/providers/asana/locales/ru.json +15 -0
- package/src/trigger/providers/asana/locales/zh-CN.json +15 -0
- package/src/trigger/providers/asana/locales/zh-TW.json +15 -0
- package/src/trigger/providers/calendly/locales/fr.json +16 -0
- package/src/trigger/providers/calendly/locales/ja.json +16 -0
- package/src/trigger/providers/calendly/locales/ko.json +16 -0
- package/src/trigger/providers/calendly/locales/ru.json +16 -0
- package/src/trigger/providers/calendly/locales/zh-CN.json +16 -0
- package/src/trigger/providers/calendly/locales/zh-TW.json +16 -0
- package/src/trigger/providers/catalog.generated.json +4996 -0
- package/src/trigger/providers/clickup/locales/fr.json +16 -0
- package/src/trigger/providers/clickup/locales/ja.json +16 -0
- package/src/trigger/providers/clickup/locales/ko.json +16 -0
- package/src/trigger/providers/clickup/locales/ru.json +16 -0
- package/src/trigger/providers/clickup/locales/zh-CN.json +16 -0
- package/src/trigger/providers/clickup/locales/zh-TW.json +16 -0
- package/src/trigger/providers/definitions.ts +19 -0
- package/src/trigger/providers/feishu/locales/fr.json +20 -0
- package/src/trigger/providers/feishu/locales/ja.json +20 -0
- package/src/trigger/providers/feishu/locales/ko.json +20 -0
- package/src/trigger/providers/feishu/locales/ru.json +20 -0
- package/src/trigger/providers/feishu/locales/zh-CN.json +20 -0
- package/src/trigger/providers/feishu/locales/zh-TW.json +20 -0
- package/src/trigger/providers/fieldDescriptions.ts +392 -0
- package/src/trigger/providers/fieldLabels.ts +256 -0
- package/src/trigger/providers/fireflies/locales/fr.json +17 -0
- package/src/trigger/providers/fireflies/locales/ja.json +17 -0
- package/src/trigger/providers/fireflies/locales/ko.json +17 -0
- package/src/trigger/providers/fireflies/locales/ru.json +17 -0
- package/src/trigger/providers/fireflies/locales/zh-CN.json +17 -0
- package/src/trigger/providers/fireflies/locales/zh-TW.json +17 -0
- package/src/trigger/providers/github/locales/fr.json +30 -0
- package/src/trigger/providers/github/locales/ja.json +30 -0
- package/src/trigger/providers/github/locales/ko.json +30 -0
- package/src/trigger/providers/github/locales/ru.json +30 -0
- package/src/trigger/providers/github/locales/zh-CN.json +30 -0
- package/src/trigger/providers/github/locales/zh-TW.json +30 -0
- package/src/trigger/providers/gitlab/locales/fr.json +18 -0
- package/src/trigger/providers/gitlab/locales/ja.json +18 -0
- package/src/trigger/providers/gitlab/locales/ko.json +18 -0
- package/src/trigger/providers/gitlab/locales/ru.json +18 -0
- package/src/trigger/providers/gitlab/locales/zh-CN.json +18 -0
- package/src/trigger/providers/gitlab/locales/zh-TW.json +18 -0
- package/src/trigger/providers/gmail/locales/fr.json +18 -0
- package/src/trigger/providers/gmail/locales/ja.json +18 -0
- package/src/trigger/providers/gmail/locales/ko.json +18 -0
- package/src/trigger/providers/gmail/locales/ru.json +18 -0
- package/src/trigger/providers/gmail/locales/zh-CN.json +18 -0
- package/src/trigger/providers/gmail/locales/zh-TW.json +18 -0
- package/src/trigger/providers/google-calendar/locales/fr.json +15 -0
- package/src/trigger/providers/google-calendar/locales/ja.json +15 -0
- package/src/trigger/providers/google-calendar/locales/ko.json +15 -0
- package/src/trigger/providers/google-calendar/locales/ru.json +15 -0
- package/src/trigger/providers/google-calendar/locales/zh-CN.json +15 -0
- package/src/trigger/providers/google-calendar/locales/zh-TW.json +15 -0
- package/src/trigger/providers/google-drive/locales/fr.json +48 -0
- package/src/trigger/providers/google-drive/locales/ja.json +48 -0
- package/src/trigger/providers/google-drive/locales/ko.json +48 -0
- package/src/trigger/providers/google-drive/locales/ru.json +48 -0
- package/src/trigger/providers/google-drive/locales/zh-CN.json +48 -0
- package/src/trigger/providers/google-drive/locales/zh-TW.json +48 -0
- package/src/trigger/providers/google-sheets/locales/fr.json +19 -0
- package/src/trigger/providers/google-sheets/locales/ja.json +19 -0
- package/src/trigger/providers/google-sheets/locales/ko.json +19 -0
- package/src/trigger/providers/google-sheets/locales/ru.json +19 -0
- package/src/trigger/providers/google-sheets/locales/zh-CN.json +19 -0
- package/src/trigger/providers/google-sheets/locales/zh-TW.json +19 -0
- package/src/trigger/providers/intercom/locales/fr.json +17 -0
- package/src/trigger/providers/intercom/locales/ja.json +17 -0
- package/src/trigger/providers/intercom/locales/ko.json +17 -0
- package/src/trigger/providers/intercom/locales/ru.json +17 -0
- package/src/trigger/providers/intercom/locales/zh-CN.json +17 -0
- package/src/trigger/providers/intercom/locales/zh-TW.json +17 -0
- package/src/trigger/providers/jira/locales/fr.json +17 -0
- package/src/trigger/providers/jira/locales/ja.json +17 -0
- package/src/trigger/providers/jira/locales/ko.json +17 -0
- package/src/trigger/providers/jira/locales/ru.json +17 -0
- package/src/trigger/providers/jira/locales/zh-CN.json +17 -0
- package/src/trigger/providers/jira/locales/zh-TW.json +17 -0
- package/src/trigger/providers/linear/locales/fr.json +13 -0
- package/src/trigger/providers/linear/locales/ja.json +13 -0
- package/src/trigger/providers/linear/locales/ko.json +13 -0
- package/src/trigger/providers/linear/locales/ru.json +13 -0
- package/src/trigger/providers/linear/locales/zh-CN.json +13 -0
- package/src/trigger/providers/linear/locales/zh-TW.json +13 -0
- package/src/trigger/providers/locales/fr.ts +71 -0
- package/src/trigger/providers/locales/ja.ts +71 -0
- package/src/trigger/providers/locales/ko.ts +71 -0
- package/src/trigger/providers/locales/ru.ts +71 -0
- package/src/trigger/providers/locales/zh-CN.ts +71 -0
- package/src/trigger/providers/locales/zh-TW.ts +71 -0
- package/src/trigger/providers/localization.ts +59 -0
- package/src/trigger/providers/notion/locales/fr.json +16 -0
- package/src/trigger/providers/notion/locales/ja.json +16 -0
- package/src/trigger/providers/notion/locales/ko.json +16 -0
- package/src/trigger/providers/notion/locales/ru.json +16 -0
- package/src/trigger/providers/notion/locales/zh-CN.json +16 -0
- package/src/trigger/providers/notion/locales/zh-TW.json +16 -0
- package/src/trigger/providers/one-drive/locales/fr.json +16 -0
- package/src/trigger/providers/one-drive/locales/ja.json +16 -0
- package/src/trigger/providers/one-drive/locales/ko.json +16 -0
- package/src/trigger/providers/one-drive/locales/ru.json +16 -0
- package/src/trigger/providers/one-drive/locales/zh-CN.json +16 -0
- package/src/trigger/providers/one-drive/locales/zh-TW.json +16 -0
- package/src/trigger/providers/outlook/locales/fr.json +18 -0
- package/src/trigger/providers/outlook/locales/ja.json +18 -0
- package/src/trigger/providers/outlook/locales/ko.json +18 -0
- package/src/trigger/providers/outlook/locales/ru.json +18 -0
- package/src/trigger/providers/outlook/locales/zh-CN.json +18 -0
- package/src/trigger/providers/outlook/locales/zh-TW.json +18 -0
- package/src/trigger/providers/pandadoc/locales/fr.json +12 -0
- package/src/trigger/providers/pandadoc/locales/ja.json +12 -0
- package/src/trigger/providers/pandadoc/locales/ko.json +12 -0
- package/src/trigger/providers/pandadoc/locales/ru.json +12 -0
- package/src/trigger/providers/pandadoc/locales/zh-CN.json +12 -0
- package/src/trigger/providers/pandadoc/locales/zh-TW.json +12 -0
- package/src/trigger/providers/pipedrive/locales/fr.json +15 -0
- package/src/trigger/providers/pipedrive/locales/ja.json +15 -0
- package/src/trigger/providers/pipedrive/locales/ko.json +15 -0
- package/src/trigger/providers/pipedrive/locales/ru.json +15 -0
- package/src/trigger/providers/pipedrive/locales/zh-CN.json +15 -0
- package/src/trigger/providers/pipedrive/locales/zh-TW.json +15 -0
- package/src/trigger/providers/remote.ts +163 -0
- package/src/trigger/providers/resend/locales/fr.json +16 -0
- package/src/trigger/providers/resend/locales/ja.json +16 -0
- package/src/trigger/providers/resend/locales/ko.json +16 -0
- package/src/trigger/providers/resend/locales/ru.json +16 -0
- package/src/trigger/providers/resend/locales/zh-CN.json +16 -0
- package/src/trigger/providers/resend/locales/zh-TW.json +16 -0
- package/src/trigger/providers/sentry/locales/fr.json +19 -0
- package/src/trigger/providers/sentry/locales/ja.json +19 -0
- package/src/trigger/providers/sentry/locales/ko.json +19 -0
- package/src/trigger/providers/sentry/locales/ru.json +19 -0
- package/src/trigger/providers/sentry/locales/zh-CN.json +19 -0
- package/src/trigger/providers/sentry/locales/zh-TW.json +19 -0
- package/src/trigger/providers/shopify/locales/fr.json +18 -0
- package/src/trigger/providers/shopify/locales/ja.json +18 -0
- package/src/trigger/providers/shopify/locales/ko.json +18 -0
- package/src/trigger/providers/shopify/locales/ru.json +18 -0
- package/src/trigger/providers/shopify/locales/zh-CN.json +18 -0
- package/src/trigger/providers/shopify/locales/zh-TW.json +18 -0
- package/src/trigger/providers/slack/locales/fr.json +18 -0
- package/src/trigger/providers/slack/locales/ja.json +18 -0
- package/src/trigger/providers/slack/locales/ko.json +18 -0
- package/src/trigger/providers/slack/locales/ru.json +18 -0
- package/src/trigger/providers/slack/locales/zh-CN.json +18 -0
- package/src/trigger/providers/slack/locales/zh-TW.json +18 -0
- package/src/trigger/providers/slackbot/locales/fr.json +23 -0
- package/src/trigger/providers/slackbot/locales/ja.json +23 -0
- package/src/trigger/providers/slackbot/locales/ko.json +23 -0
- package/src/trigger/providers/slackbot/locales/ru.json +23 -0
- package/src/trigger/providers/slackbot/locales/zh-CN.json +23 -0
- package/src/trigger/providers/slackbot/locales/zh-TW.json +23 -0
- package/src/trigger/providers/source-events.ts +25 -0
- package/src/trigger/providers/stripe/locales/fr.json +17 -0
- package/src/trigger/providers/stripe/locales/ja.json +17 -0
- package/src/trigger/providers/stripe/locales/ko.json +17 -0
- package/src/trigger/providers/stripe/locales/ru.json +17 -0
- package/src/trigger/providers/stripe/locales/zh-CN.json +17 -0
- package/src/trigger/providers/stripe/locales/zh-TW.json +17 -0
- package/src/trigger/providers/tally/locales/fr.json +12 -0
- package/src/trigger/providers/tally/locales/ja.json +12 -0
- package/src/trigger/providers/tally/locales/ko.json +12 -0
- package/src/trigger/providers/tally/locales/ru.json +12 -0
- package/src/trigger/providers/tally/locales/zh-CN.json +12 -0
- package/src/trigger/providers/tally/locales/zh-TW.json +12 -0
- package/src/trigger/providers/telegram/locales/fr.json +17 -0
- package/src/trigger/providers/telegram/locales/ja.json +17 -0
- package/src/trigger/providers/telegram/locales/ko.json +17 -0
- package/src/trigger/providers/telegram/locales/ru.json +17 -0
- package/src/trigger/providers/telegram/locales/zh-CN.json +17 -0
- package/src/trigger/providers/telegram/locales/zh-TW.json +17 -0
- package/src/trigger/providers/typeform/locales/fr.json +12 -0
- package/src/trigger/providers/typeform/locales/ja.json +12 -0
- package/src/trigger/providers/typeform/locales/ko.json +12 -0
- package/src/trigger/providers/typeform/locales/ru.json +12 -0
- package/src/trigger/providers/typeform/locales/zh-CN.json +12 -0
- package/src/trigger/providers/typeform/locales/zh-TW.json +12 -0
- package/src/trigger/providers/vercel/locales/fr.json +18 -0
- package/src/trigger/providers/vercel/locales/ja.json +18 -0
- package/src/trigger/providers/vercel/locales/ko.json +18 -0
- package/src/trigger/providers/vercel/locales/ru.json +18 -0
- package/src/trigger/providers/vercel/locales/zh-CN.json +18 -0
- package/src/trigger/providers/vercel/locales/zh-TW.json +18 -0
- package/src/trigger/providers/woocommerce/locales/fr.json +19 -0
- package/src/trigger/providers/woocommerce/locales/ja.json +19 -0
- package/src/trigger/providers/woocommerce/locales/ko.json +19 -0
- package/src/trigger/providers/woocommerce/locales/ru.json +19 -0
- package/src/trigger/providers/woocommerce/locales/zh-CN.json +19 -0
- package/src/trigger/providers/woocommerce/locales/zh-TW.json +19 -0
- package/src/trigger/providers/zendesk/locales/fr.json +15 -0
- package/src/trigger/providers/zendesk/locales/ja.json +15 -0
- package/src/trigger/providers/zendesk/locales/ko.json +15 -0
- package/src/trigger/providers/zendesk/locales/ru.json +15 -0
- package/src/trigger/providers/zendesk/locales/zh-CN.json +15 -0
- package/src/trigger/providers/zendesk/locales/zh-TW.json +15 -0
- package/src/trigger/providers/zoom/locales/fr.json +17 -0
- package/src/trigger/providers/zoom/locales/ja.json +17 -0
- package/src/trigger/providers/zoom/locales/ko.json +17 -0
- package/src/trigger/providers/zoom/locales/ru.json +17 -0
- package/src/trigger/providers/zoom/locales/zh-CN.json +17 -0
- package/src/trigger/providers/zoom/locales/zh-TW.json +17 -0
- package/src/types/index.ts +112 -0
- package/src/workflow/common/workflow.ts +273 -0
- package/dist/browser/lib-DrKav3HG.js +0 -11403
- /package/dist/{browser → common}/flow-authoring-edge.d.ts +0 -0
- /package/dist/{browser → common}/flow-authoring-module.d.ts +0 -0
- /package/dist/{browser → common}/flow-authoring.d.ts +0 -0
- /package/dist/{browser → common}/flow-input-value.d.ts +0 -0
- /package/dist/{browser → common}/webhook-method.d.ts +0 -0
|
@@ -0,0 +1,440 @@
|
|
|
1
|
+
import type { Graph, JsonValue } from '../../flow/common/change.ts'
|
|
2
|
+
|
|
3
|
+
import { z } from 'zod'
|
|
4
|
+
import { isTriggerNode } from '../../flow/common/change.ts'
|
|
5
|
+
|
|
6
|
+
export interface DependenciesCheckpoint {
|
|
7
|
+
nextId: number
|
|
8
|
+
iterations: Record<string, number>
|
|
9
|
+
nodes: Record<string, DependencyState>
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
interface DependencyState {
|
|
13
|
+
id: number
|
|
14
|
+
status: 'pending' | 'running' | 'completed' | 'skipped'
|
|
15
|
+
input: Record<
|
|
16
|
+
string,
|
|
17
|
+
{ readonly execution: number; readonly outputs: Readonly<Record<string, JsonValue>>; readonly systemOutputs?: Readonly<Record<string, JsonValue>> }
|
|
18
|
+
>
|
|
19
|
+
systemOutputs?: Readonly<Record<string, JsonValue>>
|
|
20
|
+
output?: Readonly<Record<string, JsonValue>>
|
|
21
|
+
previous: string[]
|
|
22
|
+
released: string[]
|
|
23
|
+
jobId?: string
|
|
24
|
+
seeded: boolean
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const outputsSchema = z.record(z.string(), z.json() as z.ZodType<JsonValue>)
|
|
28
|
+
const inputSchema = z.record(
|
|
29
|
+
z.string(),
|
|
30
|
+
z.strictObject({ execution: z.number().int().nonnegative(), outputs: outputsSchema, systemOutputs: outputsSchema.optional() }),
|
|
31
|
+
)
|
|
32
|
+
type InputSnapshot = DependenciesCheckpoint['nodes'][string]['input']
|
|
33
|
+
type InputFrame =
|
|
34
|
+
| { values: InputSnapshot }
|
|
35
|
+
| { values?: InputSnapshot; source: string; result: InputSnapshot[string]; parent: InputFrame; cache: Map<string, InputSnapshot[string] | undefined> }
|
|
36
|
+
|
|
37
|
+
export function dependencyValues(input: InputSnapshot): Readonly<Record<string, Readonly<Record<string, JsonValue>>>> {
|
|
38
|
+
return Object.fromEntries(Object.entries(input).map(([id, result]) => [id, result.outputs]))
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const stateSchema = z.strictObject({
|
|
42
|
+
id: z.number().int().nonnegative(),
|
|
43
|
+
status: z.enum(['pending', 'running', 'completed', 'skipped']),
|
|
44
|
+
input: inputSchema,
|
|
45
|
+
output: outputsSchema.optional(),
|
|
46
|
+
systemOutputs: outputsSchema.optional(),
|
|
47
|
+
previous: z.array(z.string()),
|
|
48
|
+
released: z.array(z.string()),
|
|
49
|
+
jobId: z.string().optional(),
|
|
50
|
+
seeded: z.boolean(),
|
|
51
|
+
})
|
|
52
|
+
export const dependenciesSchema = z.strictObject({
|
|
53
|
+
nextId: z.number().int().nonnegative(),
|
|
54
|
+
iterations: z.record(z.string(), z.number().int().nonnegative()),
|
|
55
|
+
nodes: z.record(z.string(), stateSchema),
|
|
56
|
+
})
|
|
57
|
+
type Edge = Graph['edges'][number]
|
|
58
|
+
interface Loop {
|
|
59
|
+
readonly header: string
|
|
60
|
+
readonly feedback: readonly Edge[]
|
|
61
|
+
readonly body: ReadonlySet<string>
|
|
62
|
+
readonly continuation: ReadonlySet<string>
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** Dependency completion belongs to an invocation, never to a Run-wide latest-result table. */
|
|
66
|
+
export class Dependencies {
|
|
67
|
+
readonly state: DependenciesCheckpoint
|
|
68
|
+
private readonly forward: Edge[] = []
|
|
69
|
+
private readonly loops = new Map<string, Loop>()
|
|
70
|
+
private readonly innerLoopsFirst: readonly Loop[]
|
|
71
|
+
private readonly outgoing = new Map<string, Edge[]>()
|
|
72
|
+
private readonly incoming = new Map<string, Edge[]>()
|
|
73
|
+
private readonly candidates = new Set<string>()
|
|
74
|
+
private readonly frames = new Map<string, InputFrame>()
|
|
75
|
+
private readonly graph: Graph
|
|
76
|
+
|
|
77
|
+
constructor(graph: Graph, saved?: DependenciesCheckpoint) {
|
|
78
|
+
this.graph = graph
|
|
79
|
+
// A deterministic DFS cuts recurrence edges. Removing these edges gives the
|
|
80
|
+
// dependency DAG; their targets are iteration entries, including nested loops.
|
|
81
|
+
const feedback = new Map<string, Edge[]>()
|
|
82
|
+
const visited = new Set<string>()
|
|
83
|
+
const stack = new Set<string>()
|
|
84
|
+
const outgoing = new Map<string, Edge[]>()
|
|
85
|
+
for (const edge of graph.edges) {
|
|
86
|
+
const edges = outgoing.get(edge.source) ?? []
|
|
87
|
+
edges.push(edge)
|
|
88
|
+
outgoing.set(edge.source, edges)
|
|
89
|
+
}
|
|
90
|
+
for (const edges of outgoing.values()) edges.sort((a, b) => a.target.localeCompare(b.target) || (a.sourceHandle ?? '').localeCompare(b.sourceHandle ?? ''))
|
|
91
|
+
const visit = (id: string) => {
|
|
92
|
+
if (visited.has(id)) return
|
|
93
|
+
visited.add(id)
|
|
94
|
+
stack.add(id)
|
|
95
|
+
for (const edge of outgoing.get(id) ?? []) {
|
|
96
|
+
if (stack.has(edge.target)) {
|
|
97
|
+
const edges = feedback.get(edge.target) ?? []
|
|
98
|
+
edges.push(edge)
|
|
99
|
+
feedback.set(edge.target, edges)
|
|
100
|
+
} else {
|
|
101
|
+
this.forward.push(edge)
|
|
102
|
+
visit(edge.target)
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
stack.delete(id)
|
|
106
|
+
}
|
|
107
|
+
const ids = Object.keys(graph.nodes).toSorted()
|
|
108
|
+
for (const triggerId of ids.filter((id) => isTriggerNode(graph.nodes[id]!))) visit(triggerId)
|
|
109
|
+
for (const id of ids) visit(id)
|
|
110
|
+
for (const edge of this.forward) {
|
|
111
|
+
const edges = this.incoming.get(edge.target) ?? []
|
|
112
|
+
edges.push(edge)
|
|
113
|
+
this.incoming.set(edge.target, edges)
|
|
114
|
+
const children = this.outgoing.get(edge.source) ?? []
|
|
115
|
+
children.push(edge)
|
|
116
|
+
this.outgoing.set(edge.source, children)
|
|
117
|
+
}
|
|
118
|
+
for (const [header, edges] of feedback) {
|
|
119
|
+
const descendants = new Set([header])
|
|
120
|
+
const walk = (id: string) => {
|
|
121
|
+
for (const edge of this.outgoing.get(id) ?? []) {
|
|
122
|
+
if (descendants.has(edge.target)) continue
|
|
123
|
+
descendants.add(edge.target)
|
|
124
|
+
walk(edge.target)
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
walk(header)
|
|
128
|
+
const body = new Set([header])
|
|
129
|
+
const backwards = (id: string) => {
|
|
130
|
+
if (!descendants.has(id) || body.has(id)) return
|
|
131
|
+
body.add(id)
|
|
132
|
+
for (const edge of this.incoming.get(id) ?? []) backwards(edge.source)
|
|
133
|
+
}
|
|
134
|
+
for (const edge of edges) backwards(edge.source)
|
|
135
|
+
this.loops.set(header, { header, feedback: edges, body, continuation: descendants })
|
|
136
|
+
}
|
|
137
|
+
this.innerLoopsFirst = [...this.loops.values()].toSorted((a, b) => a.body.size - b.body.size || a.header.localeCompare(b.header))
|
|
138
|
+
this.state = saved == null ? { nextId: 0, iterations: {}, nodes: {} } : structuredClone(saved)
|
|
139
|
+
if (saved == null) for (const id of ids) this.state.nodes[id] = this.fresh()
|
|
140
|
+
else this.validate()
|
|
141
|
+
for (const id of ids) {
|
|
142
|
+
if (this.state.nodes[id]!.status == 'pending') this.candidates.add(id)
|
|
143
|
+
this.frames.set(id, { values: this.state.nodes[id]!.input })
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
private fresh(): DependencyState {
|
|
148
|
+
return { id: this.state.nextId++, status: 'pending', input: {}, previous: [], released: [], seeded: false }
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
private validate() {
|
|
152
|
+
const { nodes, nextId, iterations } = this.state
|
|
153
|
+
if (Object.keys(nodes).length != Object.keys(this.graph.nodes).length) throw new Error('Checkpoint dependency nodes do not match the graph.')
|
|
154
|
+
const ids = new Set<number>()
|
|
155
|
+
for (const [id, state] of Object.entries(nodes)) {
|
|
156
|
+
if (this.graph.nodes[id] == null || state.id >= nextId || ids.has(state.id)) throw new Error('Checkpoint dependency identity is invalid.')
|
|
157
|
+
ids.add(state.id)
|
|
158
|
+
if (state.status == 'running' && state.jobId == null) throw new Error('Checkpoint running dependency has no job.')
|
|
159
|
+
if (
|
|
160
|
+
(state.status == 'pending' || state.status == 'skipped') &&
|
|
161
|
+
(state.jobId != null || state.output != null || state.systemOutputs != null || state.released.length != 0)
|
|
162
|
+
)
|
|
163
|
+
throw new Error('Checkpoint inactive dependency contains an execution.')
|
|
164
|
+
if (state.status == 'skipped' && (state.seeded || state.previous.length != 0 || Object.keys(state.input).length != 0))
|
|
165
|
+
throw new Error('Checkpoint skipped dependency contains values.')
|
|
166
|
+
if (state.seeded && (!this.loops.has(id) || state.previous.some((source) => !this.loops.get(id)!.feedback.some((edge) => edge.source == source))))
|
|
167
|
+
throw new Error('Checkpoint recurrence seed is invalid.')
|
|
168
|
+
if (state.released.length != new Set(state.released).size) throw new Error('Checkpoint released handles are duplicated.')
|
|
169
|
+
if (state.previous.some((source) => !this.graph.edges.some((edge) => edge.source == source && edge.target == id)))
|
|
170
|
+
throw new Error('Checkpoint predecessor does not match the graph.')
|
|
171
|
+
if (state.previous.length != new Set(state.previous).size) throw new Error('Checkpoint predecessors are duplicated.')
|
|
172
|
+
if (state.status == 'completed' && state.output == null) throw new Error('Checkpoint completed dependency has no output.')
|
|
173
|
+
if (state.previous.some((source) => state.input[source] == null)) throw new Error('Checkpoint predecessor has no input snapshot.')
|
|
174
|
+
for (const [source, result] of Object.entries(state.input)) {
|
|
175
|
+
if (nodes[source] == null || result.execution > nodes[source]!.id || result.execution >= nextId)
|
|
176
|
+
throw new Error('Checkpoint dependency result identity is invalid.')
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
if (Object.keys(iterations).some((id) => !this.loops.has(id))) throw new Error('Checkpoint loop scope is invalid.')
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
start(nodeId: string, outputs: Readonly<Record<string, JsonValue>>) {
|
|
183
|
+
for (const [id, node] of Object.entries(this.graph.nodes)) {
|
|
184
|
+
if (!isTriggerNode(node)) continue
|
|
185
|
+
const state = this.state.nodes[id]!
|
|
186
|
+
state.status = id == nodeId ? 'completed' : 'skipped'
|
|
187
|
+
if (id == nodeId) {
|
|
188
|
+
state.output = outputs
|
|
189
|
+
state.released = Object.keys(outputs)
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
private edge(edge: Edge): 'pending' | 'selected' | 'skipped' {
|
|
195
|
+
const source = this.state.nodes[edge.source]!
|
|
196
|
+
if (source.status == 'skipped') return 'skipped'
|
|
197
|
+
if (edge.sourceHandle != null && source.released.includes(edge.sourceHandle)) return 'selected'
|
|
198
|
+
if (source.status != 'completed') return 'pending'
|
|
199
|
+
return edge.sourceHandle == null ? 'selected' : 'skipped'
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
private edgeResult(edge: Edge): InputSnapshot[string] {
|
|
203
|
+
const source = this.state.nodes[edge.source]!
|
|
204
|
+
const outputs =
|
|
205
|
+
edge.sourceHandle != null && this.graph.nodes[edge.source]!.kind != 'condition'
|
|
206
|
+
? Object.fromEntries(Object.entries(source.output!).filter(([handle]) => handle == edge.sourceHandle))
|
|
207
|
+
: source.output!
|
|
208
|
+
return { execution: source.id, outputs, ...(source.systemOutputs == null ? {} : { systemOutputs: source.systemOutputs }) }
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
input(nodeId: string, sourceId: string): InputSnapshot[string] | undefined {
|
|
212
|
+
if (this.loops.size != 0) return this.state.nodes[nodeId]!.input[sourceId]
|
|
213
|
+
let frame = this.frames.get(nodeId)!
|
|
214
|
+
const visited: Extract<InputFrame, { source: string }>[] = []
|
|
215
|
+
let result: InputSnapshot[string] | undefined
|
|
216
|
+
for (;;) {
|
|
217
|
+
if (!('source' in frame) || frame.values != null) {
|
|
218
|
+
result = frame.values![sourceId]
|
|
219
|
+
break
|
|
220
|
+
}
|
|
221
|
+
if (frame.source == sourceId) {
|
|
222
|
+
result = frame.result
|
|
223
|
+
break
|
|
224
|
+
}
|
|
225
|
+
if (frame.cache.has(sourceId)) {
|
|
226
|
+
result = frame.cache.get(sourceId)
|
|
227
|
+
break
|
|
228
|
+
}
|
|
229
|
+
visited.push(frame)
|
|
230
|
+
frame = frame.parent
|
|
231
|
+
}
|
|
232
|
+
for (const ancestor of visited) ancestor.cache.set(sourceId, result)
|
|
233
|
+
return result
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
private snapshot(frame: InputFrame): InputSnapshot {
|
|
237
|
+
const pending: Extract<InputFrame, { source: string }>[] = []
|
|
238
|
+
while ('source' in frame && frame.values == null) {
|
|
239
|
+
pending.push(frame)
|
|
240
|
+
frame = frame.parent
|
|
241
|
+
}
|
|
242
|
+
let values = frame.values!
|
|
243
|
+
for (const current of pending.toReversed()) {
|
|
244
|
+
values = Object.assign({}, values, { [current.source]: current.result })
|
|
245
|
+
current.values = values
|
|
246
|
+
current.cache.clear()
|
|
247
|
+
}
|
|
248
|
+
return values
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
private collectInputs(edges: readonly Edge[]): InputSnapshot {
|
|
252
|
+
const input: InputSnapshot = {}
|
|
253
|
+
const merge = (id: string, result: InputSnapshot[string]) => {
|
|
254
|
+
const previous = input[id]
|
|
255
|
+
if (previous == null || result.execution > previous.execution) input[id] = result
|
|
256
|
+
else if (result !== previous && result.execution == previous.execution)
|
|
257
|
+
input[id] = {
|
|
258
|
+
execution: result.execution,
|
|
259
|
+
outputs: { ...previous.outputs, ...result.outputs },
|
|
260
|
+
...(previous.systemOutputs || result.systemOutputs ? { systemOutputs: { ...previous.systemOutputs, ...result.systemOutputs } } : {}),
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
for (const edge of edges) {
|
|
264
|
+
const source = this.state.nodes[edge.source]!
|
|
265
|
+
for (const id in source.input) merge(id, source.input[id]!)
|
|
266
|
+
merge(edge.source, this.edgeResult(edge))
|
|
267
|
+
}
|
|
268
|
+
for (const id of Object.keys(input)) {
|
|
269
|
+
if (this.state.nodes[id]!.status == 'skipped') delete input[id]
|
|
270
|
+
}
|
|
271
|
+
return input
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
private loopSettled(loop: Loop): boolean {
|
|
275
|
+
return [...loop.body].every((id) => {
|
|
276
|
+
const state = this.state.nodes[id]!
|
|
277
|
+
return state.status == 'completed' || state.status == 'skipped'
|
|
278
|
+
})
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
private blockedByLoop(edge: Edge): boolean {
|
|
282
|
+
// An unselected exit is not a completed dependency until that loop finishes.
|
|
283
|
+
// Pending notifications deliberately leave a suspended loop immediately.
|
|
284
|
+
if (this.edge(edge) == 'selected') return false
|
|
285
|
+
for (const loop of this.loops.values()) {
|
|
286
|
+
const { body } = loop
|
|
287
|
+
if (!body.has(edge.source) || body.has(edge.target)) continue
|
|
288
|
+
if (!this.loopSettled(loop)) return true
|
|
289
|
+
if (loop.feedback.some((back) => this.edge(back) == 'selected')) return true
|
|
290
|
+
}
|
|
291
|
+
return false
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
private continuationPending(loop: Loop): boolean {
|
|
295
|
+
const { body } = loop
|
|
296
|
+
const exitBlocked = new Map<string, boolean>()
|
|
297
|
+
const awaitsExit = (id: string): boolean => {
|
|
298
|
+
if (exitBlocked.has(id)) return exitBlocked.get(id)!
|
|
299
|
+
const blocked = (this.incoming.get(id) ?? []).some(
|
|
300
|
+
(edge) =>
|
|
301
|
+
this.edge(edge) != 'selected' &&
|
|
302
|
+
((body.has(edge.source) && !body.has(id) && this.blockedByLoop(edge)) ||
|
|
303
|
+
(this.state.nodes[edge.source]!.status == 'pending' && awaitsExit(edge.source))),
|
|
304
|
+
)
|
|
305
|
+
exitBlocked.set(id, blocked)
|
|
306
|
+
return blocked
|
|
307
|
+
}
|
|
308
|
+
const visited = new Set<string>()
|
|
309
|
+
const visit = (id: string): boolean => {
|
|
310
|
+
if (visited.has(id) || body.has(id)) return false
|
|
311
|
+
visited.add(id)
|
|
312
|
+
const state = this.state.nodes[id]!
|
|
313
|
+
if (state.status == 'running') return true
|
|
314
|
+
if (state.status == 'pending') return !awaitsExit(id)
|
|
315
|
+
return (this.outgoing.get(id) ?? []).some((edge) => this.edge(edge) == 'selected' && visit(edge.target))
|
|
316
|
+
}
|
|
317
|
+
return this.forward.some((edge) => body.has(edge.source) && !body.has(edge.target) && this.edge(edge) == 'selected' && visit(edge.target))
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
private selectedIncoming(nodeId: string): readonly Edge[] | undefined {
|
|
321
|
+
const edges = this.incoming.get(nodeId) ?? []
|
|
322
|
+
if (edges.some((edge) => this.edge(edge) == 'pending' || this.blockedByLoop(edge))) return undefined
|
|
323
|
+
return edges.filter((edge) => this.edge(edge) == 'selected')
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
private readyAcyclic(): string[] {
|
|
327
|
+
const ready = new Set<string>()
|
|
328
|
+
for (const id of this.candidates) {
|
|
329
|
+
this.candidates.delete(id)
|
|
330
|
+
const state = this.state.nodes[id]!
|
|
331
|
+
if (state.status != 'pending') continue
|
|
332
|
+
const selected = this.selectedIncoming(id)
|
|
333
|
+
if (selected == null) continue
|
|
334
|
+
if (selected.length == 0) {
|
|
335
|
+
state.status = 'skipped'
|
|
336
|
+
for (const edge of this.outgoing.get(id) ?? []) this.candidates.add(edge.target)
|
|
337
|
+
} else {
|
|
338
|
+
if (selected.length == 1) {
|
|
339
|
+
const edge = selected[0]!
|
|
340
|
+
const frame: InputFrame = { source: edge.source, result: this.edgeResult(edge), parent: this.frames.get(edge.source)!, cache: new Map() }
|
|
341
|
+
this.frames.set(id, frame)
|
|
342
|
+
// Preserve the checkpoint shape while sharing single-predecessor snapshots during execution.
|
|
343
|
+
Object.defineProperty(state, 'input', {
|
|
344
|
+
configurable: true,
|
|
345
|
+
enumerable: true,
|
|
346
|
+
get: () => this.snapshot(frame),
|
|
347
|
+
})
|
|
348
|
+
} else {
|
|
349
|
+
const input = this.collectInputs(selected)
|
|
350
|
+
Object.defineProperty(state, 'input', { configurable: true, enumerable: true, writable: true, value: input })
|
|
351
|
+
this.frames.set(id, { values: input })
|
|
352
|
+
}
|
|
353
|
+
state.previous = [...new Set(selected.map((edge) => edge.source))].toSorted()
|
|
354
|
+
ready.add(id)
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
// Keep unadmitted nodes eligible when ready is read again before begin.
|
|
358
|
+
for (const id of ready) this.candidates.add(id)
|
|
359
|
+
return [...ready].toSorted()
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/** Resolve skips and iteration boundaries before admitting another invocation. */
|
|
363
|
+
ready(): string[] {
|
|
364
|
+
if (this.loops.size == 0) return this.readyAcyclic()
|
|
365
|
+
let changed = true
|
|
366
|
+
while (changed) {
|
|
367
|
+
changed = false
|
|
368
|
+
// Inner scopes settle before their enclosing scope. A recurrence replaces
|
|
369
|
+
// only its forward continuation; unrelated and outer invocations are reused.
|
|
370
|
+
for (const loop of this.innerLoopsFirst) {
|
|
371
|
+
const { header, feedback: edges, continuation: affected } = loop
|
|
372
|
+
if (!this.loopSettled(loop)) continue
|
|
373
|
+
const selected = edges.filter((edge) => this.edge(edge) == 'selected')
|
|
374
|
+
if (selected.length == 0) continue
|
|
375
|
+
if (this.continuationPending(loop) || [...affected].some((id) => this.state.nodes[id]!.status == 'running')) continue
|
|
376
|
+
const input = this.collectInputs(selected)
|
|
377
|
+
this.state.iterations[header] = (this.state.iterations[header] ?? 0) + 1
|
|
378
|
+
for (const nested of this.loops.keys()) {
|
|
379
|
+
if (nested != header && affected.has(nested)) {
|
|
380
|
+
delete this.state.iterations[nested]
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
for (const id of affected) this.state.nodes[id] = this.fresh()
|
|
384
|
+
const entry = this.state.nodes[header]!
|
|
385
|
+
entry.input = input
|
|
386
|
+
entry.previous = [...new Set(selected.map((edge) => edge.source))].toSorted()
|
|
387
|
+
entry.seeded = true
|
|
388
|
+
changed = true
|
|
389
|
+
break
|
|
390
|
+
}
|
|
391
|
+
for (const [id, state] of Object.entries(this.state.nodes)) {
|
|
392
|
+
if (state.status != 'pending' || state.seeded) continue
|
|
393
|
+
if (this.selectedIncoming(id)?.length == 0) {
|
|
394
|
+
state.status = 'skipped'
|
|
395
|
+
changed = true
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
return Object.entries(this.state.nodes).flatMap(([id, state]) => {
|
|
400
|
+
if (state.status != 'pending') return []
|
|
401
|
+
if (state.seeded) return [id]
|
|
402
|
+
const selected = this.selectedIncoming(id)
|
|
403
|
+
if (selected == null || selected.length == 0) return []
|
|
404
|
+
state.input = this.collectInputs(selected)
|
|
405
|
+
// Entering a nested scope through its ordinary entry starts fresh. Only an
|
|
406
|
+
// actual recurrence seed carries that scope's previous iteration values.
|
|
407
|
+
for (const member of this.loops.get(id)?.body ?? []) {
|
|
408
|
+
delete state.input[member]
|
|
409
|
+
}
|
|
410
|
+
state.previous = [...new Set(selected.map((edge) => edge.source))].toSorted()
|
|
411
|
+
return [id]
|
|
412
|
+
})
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
begin(nodeId: string, jobId: string) {
|
|
416
|
+
const state = this.state.nodes[nodeId]!
|
|
417
|
+
state.status = 'running'
|
|
418
|
+
state.jobId = jobId
|
|
419
|
+
this.candidates.delete(nodeId)
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
release(
|
|
423
|
+
nodeId: string,
|
|
424
|
+
outputs: Readonly<Record<string, JsonValue>>,
|
|
425
|
+
handles: readonly string[],
|
|
426
|
+
complete: boolean,
|
|
427
|
+
systemOutputs?: Readonly<Record<string, JsonValue>>,
|
|
428
|
+
) {
|
|
429
|
+
const state = this.state.nodes[nodeId]!
|
|
430
|
+
state.output = outputs
|
|
431
|
+
state.systemOutputs = systemOutputs
|
|
432
|
+
state.released = [...new Set([...state.released, ...handles])]
|
|
433
|
+
if (complete) state.status = 'completed'
|
|
434
|
+
if (this.loops.size == 0) for (const edge of this.outgoing.get(nodeId) ?? []) this.candidates.add(edge.target)
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
get incomplete(): boolean {
|
|
438
|
+
return Object.values(this.state.nodes).some((state) => state.status == 'pending' || state.status == 'running')
|
|
439
|
+
}
|
|
440
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
export interface EngineContract {
|
|
2
|
+
readonly builtinModules?: ReadonlySet<string>
|
|
3
|
+
readonly platformExports: ReadonlySet<string>
|
|
4
|
+
readonly platformModule: string
|
|
5
|
+
readonly platformSource: string
|
|
6
|
+
readonly waitAutoContinue?: boolean
|
|
7
|
+
readonly webhookResponses?: boolean
|
|
8
|
+
readonly workflowTools?: boolean
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const currentEngineContract = 'open-flow-engine/v8'
|
|
12
|
+
export const nodejsEngineContract = 'open-flow-engine/v8/nodejs-compat-v1'
|
|
13
|
+
|
|
14
|
+
const currentContract: EngineContract = {
|
|
15
|
+
workflowTools: true,
|
|
16
|
+
waitAutoContinue: true,
|
|
17
|
+
webhookResponses: true,
|
|
18
|
+
platformExports: new Set(['engineContract', 'identity']),
|
|
19
|
+
platformModule: 'open-flow:platform',
|
|
20
|
+
platformSource: `export const engineContract = ${JSON.stringify(currentEngineContract)}
|
|
21
|
+
export function identity(value) { return value }
|
|
22
|
+
`,
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const nodejsContract: EngineContract = {
|
|
26
|
+
...currentContract,
|
|
27
|
+
builtinModules: new Set(
|
|
28
|
+
[
|
|
29
|
+
'assert',
|
|
30
|
+
'assert/strict',
|
|
31
|
+
'buffer',
|
|
32
|
+
'console',
|
|
33
|
+
'constants',
|
|
34
|
+
'crypto',
|
|
35
|
+
'events',
|
|
36
|
+
'fs',
|
|
37
|
+
'fs/promises',
|
|
38
|
+
'os',
|
|
39
|
+
'path',
|
|
40
|
+
'path/posix',
|
|
41
|
+
'process',
|
|
42
|
+
'punycode',
|
|
43
|
+
'querystring',
|
|
44
|
+
'stream',
|
|
45
|
+
'stream/promises',
|
|
46
|
+
'stream/web',
|
|
47
|
+
'string_decoder',
|
|
48
|
+
'timers',
|
|
49
|
+
'timers/promises',
|
|
50
|
+
'url',
|
|
51
|
+
'util',
|
|
52
|
+
'zlib',
|
|
53
|
+
].flatMap((name) => [name, `node:${name}`]),
|
|
54
|
+
),
|
|
55
|
+
platformSource: `export const engineContract = ${JSON.stringify(nodejsEngineContract)}
|
|
56
|
+
export function identity(value) { return value }
|
|
57
|
+
`,
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function findEngineContract(contract: string): EngineContract | undefined {
|
|
61
|
+
if (contract == currentEngineContract) return currentContract
|
|
62
|
+
if (contract == nodejsEngineContract) return nodejsContract
|
|
63
|
+
if (contract == 'open-flow-engine/v7' || contract == 'open-flow-engine/v7/nodejs-compat-v1')
|
|
64
|
+
return {
|
|
65
|
+
...(contract.endsWith('/nodejs-compat-v1') ? nodejsContract : currentContract),
|
|
66
|
+
workflowTools: false,
|
|
67
|
+
platformSource: `export const engineContract = ${JSON.stringify(contract)}\nexport function identity(value) { return value }\n`,
|
|
68
|
+
}
|
|
69
|
+
if (contract == 'open-flow-engine/v6' || contract == 'open-flow-engine/v6/nodejs-compat-v1')
|
|
70
|
+
return {
|
|
71
|
+
...(contract == 'open-flow-engine/v6' ? currentContract : nodejsContract),
|
|
72
|
+
workflowTools: false,
|
|
73
|
+
waitAutoContinue: false,
|
|
74
|
+
webhookResponses: false,
|
|
75
|
+
platformSource: `export const engineContract = ${JSON.stringify(contract)}
|
|
76
|
+
export function identity(value) { return value }
|
|
77
|
+
`,
|
|
78
|
+
}
|
|
79
|
+
return undefined
|
|
80
|
+
}
|