Skip to content

Commit

Permalink
start from workflows branch, squashed
Browse files Browse the repository at this point in the history
  • Loading branch information
RamIdeas committed Oct 17, 2024
1 parent 8c7c3b5 commit 197f336
Show file tree
Hide file tree
Showing 43 changed files with 1,279 additions and 7 deletions.
7 changes: 7 additions & 0 deletions fixtures/workflow/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# worker-ts

## 0.0.1

### Patch Changes

- [#3588](https://github.com/cloudflare/workers-sdk/pull/3588) [`64631d8b`](https://github.com/cloudflare/workers-sdk/commit/64631d8b59572f49d65325d8f6fec098c5e912b9) Thanks [@penalosa](https://github.com/penalosa)! - fix: Preserve email handlers when applying middleware to user workers.
15 changes: 15 additions & 0 deletions fixtures/workflow/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "my-workflow",
"private": true,
"scripts": {
"deploy": "wrangler deploy",
"start": "wrangler dev --x-dev-env"
},
"devDependencies": {
"@cloudflare/workers-types": "^4.20240909.0",
"wrangler": "workspace:*"
},
"volta": {
"extends": "../../package.json"
}
}
50 changes: 50 additions & 0 deletions fixtures/workflow/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import {
WorkerEntrypoint,
Workflow,
WorkflowEvent,
WorkflowStep,
} from "cloudflare:workers";

type Params = {
name: string;
};
export class Demo extends Workflow<{}, Params> {
async run(events: Array<WorkflowEvent<Params>>, step: WorkflowStep) {
const { timestamp, payload } = events[0];
const result = await step.do("First step", async function () {
return {
output: "First step result",
};
});

await step.sleep("Wait", "1 minute");

const result2 = await step.do("Second step", async function () {
return {
output: "Second step result",
};
});

return {
result,
result2,
timestamp,
payload,
};
}
}

type Env = {
WORKFLOW: {
create: (id: string) => {
pause: () => {};
};
};
};
export default class extends WorkerEntrypoint<Env> {
async fetch() {
const handle = await this.env.WORKFLOW.create(crypto.randomUUID());
await handle.pause();
return new Response();
}
}
13 changes: 13 additions & 0 deletions fixtures/workflow/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"compilerOptions": {
"target": "es2021",
"lib": ["es2021"],
"module": "es2022",
"types": ["@cloudflare/workers-types/experimental"],
"noEmit": true,
"isolatedModules": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true
}
}
10 changes: 10 additions & 0 deletions fixtures/workflow/wrangler.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#:schema node_modules/wrangler/config-schema.json
name = "my-workflow-demo"
main = "src/index.ts"
compatibility_date = "2024-09-02"
compatibility_flags = ["experimental"]

[[workflows]]
binding = "WORKFLOW"
name = "my-workflow"
class_name = "Demo"
2 changes: 2 additions & 0 deletions packages/wrangler/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,9 @@
"@esbuild-plugins/node-modules-polyfill": "^0.2.2",
"blake3-wasm": "^2.1.5",
"chokidar": "^3.5.3",
"date-fns": "^4.1.0",
"esbuild": "0.17.19",
"itty-time": "^1.0.6",
"miniflare": "workspace:*",
"nanoid": "^3.3.3",
"path-to-regexp": "^6.3.0",
Expand Down
2 changes: 2 additions & 0 deletions packages/wrangler/src/__tests__/navigator-user-agent.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ describe("defineNavigatorUserAgent is respected", () => {
serveLegacyAssetsFromWorker: false,
mockAnalyticsEngineDatasets: [],
doBindings: [],
workflowBindings: [],
define: {},
alias: {},
checkFetch: false,
Expand Down Expand Up @@ -175,6 +176,7 @@ describe("defineNavigatorUserAgent is respected", () => {
moduleCollector: noopModuleCollector,
serveLegacyAssetsFromWorker: false,
doBindings: [],
workflowBindings: [],
define: {},
alias: {},
mockAnalyticsEngineDatasets: [],
Expand Down
1 change: 1 addition & 0 deletions packages/wrangler/src/__tests__/type-generation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ const bindingsConfigMock: Omit<
},
],
},
workflows: [],
r2_buckets: [
{
binding: "R2_BUCKET_BINDING",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ function createWorkerBundleFormData(
ai: config?.ai,
version_metadata: config?.version_metadata,
durable_objects: config?.durable_objects,
workflows: config?.workflows,
queues: config?.queues.producers?.map((producer) => {
return { binding: producer.binding, queue_name: producer.queue };
}),
Expand Down
2 changes: 2 additions & 0 deletions packages/wrangler/src/api/startDevWorker/BundlerController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ export class BundlerController extends Controller<BundlerControllerEventMap> {
serveLegacyAssetsFromWorker: Boolean(
config.legacy?.legacyAssets && !config.dev?.remote
),
workflowBindings: bindings?.workflows ?? [],
doBindings: bindings?.durable_objects?.bindings ?? [],
jsxFactory: config.build.jsxFactory,
jsxFragment: config.build.jsxFactory,
Expand Down Expand Up @@ -238,6 +239,7 @@ export class BundlerController extends Controller<BundlerControllerEventMap> {
noBundle: !config.build?.bundle,
findAdditionalModules: config.build?.findAdditionalModules,
durableObjects: bindings?.durable_objects ?? { bindings: [] },
workflows: bindings?.workflows ?? [],
mockAnalyticsEngineDatasets: bindings.analytics_engine_datasets ?? [],
local: !config.dev?.remote,
// startDevWorker only applies to "dev"
Expand Down
2 changes: 2 additions & 0 deletions packages/wrangler/src/api/startDevWorker/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import type {
CfService,
CfUnsafe,
CfVectorize,
CfWorkflow,
} from "../../deployment-bundle/worker";
import type { WorkerRegistry } from "../../dev-registry";
import type { CfAccount } from "../../dev/create-worker-preview";
Expand Down Expand Up @@ -254,6 +255,7 @@ export type Binding =
| { type: "version_metadata" }
| { type: "data_blob"; source: BinaryFile }
| ({ type: "durable_object_namespace" } & BindingOmit<CfDurableObject>)
| ({ type: "workflow" } & BindingOmit<CfWorkflow>)
| ({ type: "queue" } & BindingOmit<CfQueue>)
| ({ type: "r2_bucket" } & BindingOmit<CfR2Bucket>)
| ({ type: "d1" } & Omit<CfD1Database, "binding">)
Expand Down
7 changes: 7 additions & 0 deletions packages/wrangler/src/api/startDevWorker/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,12 @@ export function convertCfWorkerInitBindingstoBindings(
}
break;
}
case "workflows": {
for (const { binding, ...x } of info) {
output[binding] = { type: "workflow", ...x };
}
break;
}
case "queues": {
for (const { binding, ...x } of info) {
output[binding] = { type: "queue", ...x };
Expand Down Expand Up @@ -278,6 +284,7 @@ export async function convertBindingsToCfWorkerInitBindings(
durable_objects: undefined,
queues: undefined,
r2_buckets: undefined,
workflows: undefined,
d1_databases: undefined,
vectorize: undefined,
hyperdrive: undefined,
Expand Down
1 change: 1 addition & 0 deletions packages/wrangler/src/config/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,7 @@ export const defaultWranglerConfig: Config = {
d1_databases: [],
vectorize: [],
hyperdrive: [],
workflows: [],
services: [],
analytics_engine_datasets: [],
ai: undefined,
Expand Down
22 changes: 22 additions & 0 deletions packages/wrangler/src/config/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,17 @@ export type DurableObjectBindings = {
environment?: string;
}[];

export type WorkflowBinding = {
/** The name of the binding used to refer to the Workflow */
binding: string;
/** The name of the Workflow */
name: string;
/** The exported class name of the Workflow */
class_name: string;
/** The script where the Workflow is defined (if it's external to this Worker) */
script_name?: string;
};

/**
* The `EnvironmentNonInheritable` interface declares all the configuration fields for an environment
* that cannot be inherited from the top-level environment, and must be defined specifically.
Expand Down Expand Up @@ -417,6 +428,17 @@ export interface EnvironmentNonInheritable {
bindings: DurableObjectBindings;
};

/**
* A list of workflows that your Worker should be bound to.
*
* NOTE: This field is not automatically inherited from the top level environment,
* and so must be specified in every named environment.
*
* @default `[]`
* @nonInheritable
*/
workflows: WorkflowBinding[];

/**
* Cloudchamber configuration
*
Expand Down
18 changes: 18 additions & 0 deletions packages/wrangler/src/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ export function printBindings(
const {
data_blobs,
durable_objects,
workflows,
kv_namespaces,
send_email,
queues,
Expand Down Expand Up @@ -278,6 +279,23 @@ export function printBindings(
});
}

if (workflows !== undefined && workflows.length > 0) {
output.push({
type: "Workflows",
entries: workflows.map(({ class_name, script_name, binding }) => {
let value = class_name;
if (script_name) {
value += ` (defined in ${script_name})`;
}

return {
key: binding,
value,
};
}),
});
}

if (kv_namespaces !== undefined && kv_namespaces.length > 0) {
output.push({
type: "KV Namespaces",
Expand Down
67 changes: 67 additions & 0 deletions packages/wrangler/src/config/validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1286,6 +1286,16 @@ function normalizeAndValidateEnvironment(
bindings: [],
}
),
workflows: notInheritable(
diagnostics,
topLevelEnv,
rawConfig,
rawEnv,
envName,
"workflows",
validateBindingArray(envName, validateWorkflowBinding),
[]
),
migrations: inheritable(
diagnostics,
topLevelEnv,
Expand Down Expand Up @@ -2008,6 +2018,63 @@ const validateDurableObjectBinding: ValidatorFn = (
return isValid;
};

/**
* Check that the given field is a valid "workflow" binding object.
*/
const validateWorkflowBinding: ValidatorFn = (_diagnostics, _field, _value) => {
// if (typeof value !== "object" || value === null) {
// diagnostics.errors.push(
// `Expected "${field}" to be an object but got ${JSON.stringify(value)}`
// );
// return false;
// }

// Workflow bindings must have a name, class_name and binding, and optionally a script_name and an environment.
const isValid = true;
// if (!isRequiredProperty(value, "name", "string")) {
// diagnostics.errors.push(`binding should have a string "name" field.`);
// isValid = false;
// }
// if (!isRequiredProperty(value, "binding", "string")) {
// diagnostics.errors.push(`binding should have a string "binding" field.`);
// isValid = false;
// }
// if (!isRequiredProperty(value, "class_name", "string")) {
// diagnostics.errors.push(`binding should have a string "class_name" field.`);
// isValid = false;
// }
// if (!isOptionalProperty(value, "script_name", "string")) {
// diagnostics.errors.push(
// `the field "script_name", when present, should be a string.`
// );
// isValid = false;
// }
// // environment requires a script_name
// if (!isOptionalProperty(value, "environment", "string")) {
// diagnostics.errors.push(
// `the field "environment", when present, should be a string.`
// );
// isValid = false;
// }

// if ("environment" in value && !("script_name" in value)) {
// diagnostics.errors.push(
// `binding should have a "script_name" field if "environment" is present.`
// );
// isValid = false;
// }

// validateAdditionalProperties(diagnostics, field, Object.keys(value), [
// "class_name",
// "environment",
// "name",
// "script_name",
// "binding",
// ]);

return isValid;
};

const validateCflogfwdrObject: (env: string) => ValidatorFn =
(envName) => (diagnostics, field, value, topLevelEnv) => {
//validate the bindings property first, as this also validates that it's an object, etc.
Expand Down
2 changes: 2 additions & 0 deletions packages/wrangler/src/deploy/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,7 @@ See https://developers.cloudflare.com/workers/platform/compatibility-dates for m
serveLegacyAssetsFromWorker:
!props.isWorkersSite && Boolean(props.legacyAssetPaths),
doBindings: config.durable_objects.bindings,
workflowBindings: config.workflows ?? [],
jsxFactory,
jsxFragment,
tsconfig: props.tsconfig ?? config.tsconfig,
Expand Down Expand Up @@ -674,6 +675,7 @@ See https://developers.cloudflare.com/workers/platform/compatibility-dates for m
},
data_blobs: config.data_blobs,
durable_objects: config.durable_objects,
workflows: config.workflows,
queues: config.queues.producers?.map((producer) => {
return { binding: producer.binding, queue_name: producer.queue };
}),
Expand Down
Loading

0 comments on commit 197f336

Please sign in to comment.