@temelj/workflow 0.0.0-alpha.1 → 0.0.0-alpha.2

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.
Files changed (64) hide show
  1. package/dist/bundle.d.mts +29 -0
  2. package/dist/bundle.mjs +28 -0
  3. package/dist/client/create.d.mts +10 -2
  4. package/dist/client/create.mjs +5 -3
  5. package/dist/client/facades.mjs +6 -3
  6. package/dist/client/run-handle.d.mts +1 -0
  7. package/dist/client/run-handle.mjs +3 -1
  8. package/dist/cloudflare/cloudflare.d.mts +12 -0
  9. package/dist/cloudflare/codec.d.mts +16 -0
  10. package/dist/cloudflare/codec.mjs +25 -0
  11. package/dist/cloudflare/entrypoint.d.mts +12 -0
  12. package/dist/cloudflare/entrypoint.mjs +18 -0
  13. package/dist/cloudflare/execution.d.mts +13 -0
  14. package/dist/cloudflare/execution.mjs +28 -0
  15. package/dist/cloudflare/host.d.mts +19 -0
  16. package/dist/cloudflare/host.mjs +24 -0
  17. package/dist/cloudflare/mod.d.mts +8 -0
  18. package/dist/cloudflare/mod.mjs +7 -0
  19. package/dist/cloudflare/name.d.mts +5 -0
  20. package/dist/cloudflare/name.mjs +22 -0
  21. package/dist/cloudflare/registry.d.mts +24 -0
  22. package/dist/cloudflare/registry.mjs +26 -0
  23. package/dist/cloudflare/runtime.d.mts +30 -0
  24. package/dist/cloudflare/runtime.mjs +226 -0
  25. package/dist/cloudflare/step.d.mts +22 -0
  26. package/dist/cloudflare/step.mjs +160 -0
  27. package/dist/cloudflare/types.d.mts +87 -0
  28. package/dist/cloudflare/types.mjs +1 -0
  29. package/dist/engine/inspection-api.mjs +2 -1
  30. package/dist/engine/inspection.mjs +7 -5
  31. package/dist/engine/message.mjs +16 -13
  32. package/dist/engine/observation.mjs +1 -3
  33. package/dist/engine/run-data.mjs +2 -1
  34. package/dist/engine/run-service.mjs +2 -1
  35. package/dist/engine/start-api.mjs +2 -1
  36. package/dist/engine/state.mjs +2 -1
  37. package/dist/engine/stream.d.mts +1 -0
  38. package/dist/engine/stream.mjs +1 -0
  39. package/dist/engine/task.mjs +2 -1
  40. package/dist/errors/definition.d.mts +1 -0
  41. package/dist/errors/definition.mjs +3 -0
  42. package/dist/errors/details.mjs +2 -1
  43. package/dist/history/replay-projection.mjs +1 -3
  44. package/dist/mod.d.mts +2 -1
  45. package/dist/mod.mjs +2 -1
  46. package/dist/otel.mjs +4 -2
  47. package/dist/runtime.d.mts +1 -0
  48. package/dist/runtime.mjs +7 -3
  49. package/dist/store/cleanup.mjs +3 -26
  50. package/dist/store/message-index.mjs +2 -1
  51. package/dist/store/query.mjs +5 -3
  52. package/dist/store/run.mjs +9 -6
  53. package/dist/store/schedule.mjs +5 -3
  54. package/dist/store/step-attempt.mjs +5 -3
  55. package/dist/store-keys.d.mts +2 -1
  56. package/dist/store-keys.mjs +24 -1
  57. package/dist/types/common.d.mts +1 -0
  58. package/dist/types/common.mjs +1 -0
  59. package/dist/types/runtime.d.mts +10 -2
  60. package/dist/worker/error.d.mts +1 -0
  61. package/dist/worker/error.mjs +1 -0
  62. package/dist/worker.d.mts +1 -0
  63. package/dist/worker.mjs +1 -0
  64. package/package.json +15 -10
@@ -0,0 +1,29 @@
1
+ import { Registry, WorkflowDefinitionConfig, WorkflowImplementation } from "./types/definition.mjs";
2
+ import { Schema } from "@temelj/standard-schema";
3
+ //#region src/bundle.d.ts
4
+ interface WorkflowImplementationLike {
5
+ readonly kind: "implementation";
6
+ readonly definition: {
7
+ readonly kind: "definition";
8
+ readonly config: WorkflowDefinitionConfig<Schema | undefined>;
9
+ readonly name: string;
10
+ readonly version?: string;
11
+ };
12
+ readonly config: WorkflowDefinitionConfig<Schema | undefined>;
13
+ readonly name: string;
14
+ readonly version?: string;
15
+ readonly handler: (...args: never[]) => unknown;
16
+ }
17
+ /** Workflow value accepted by an immutable workflow bundle. */
18
+ type WorkflowBundleEntry = WorkflowImplementationLike | ((...args: never[]) => unknown);
19
+ /** Immutable collection of workflow implementations shared by workflow hosts. */
20
+ interface WorkflowBundle {
21
+ readonly kind: "workflow-bundle";
22
+ readonly workflows: readonly WorkflowImplementation<unknown, unknown>[];
23
+ }
24
+ /** Defines an immutable workflow collection for local and deployed workflow hosts. */
25
+ declare function defineWorkflowBundle(entries: readonly WorkflowBundleEntry[]): WorkflowBundle;
26
+ /** Creates an independent mutable registry populated from a workflow bundle. */
27
+ declare function createWorkflowBundleRegistry(bundle: WorkflowBundle): Registry;
28
+ //#endregion
29
+ export { WorkflowBundle, WorkflowBundleEntry, createWorkflowBundleRegistry, defineWorkflowBundle };
@@ -0,0 +1,28 @@
1
+ import { WorkflowDefinitionError } from "./errors/definition.mjs";
2
+ import "./errors/mod.mjs";
3
+ import { getCompiledWorkflowDefinition } from "./compiled-function.mjs";
4
+ import { Registry } from "./registry.mjs";
5
+ //#region src/bundle.ts
6
+ /** Defines an immutable workflow collection for local and deployed workflow hosts. */
7
+ function defineWorkflowBundle(entries) {
8
+ const registry = new Registry();
9
+ for (const entry of entries) registry.register(workflowImplementationFromBundleEntry(entry));
10
+ return Object.freeze({
11
+ kind: "workflow-bundle",
12
+ workflows: Object.freeze([...registry.entries()])
13
+ });
14
+ }
15
+ /** Creates an independent mutable registry populated from a workflow bundle. */
16
+ function createWorkflowBundleRegistry(bundle) {
17
+ const registry = new Registry();
18
+ for (const workflow of bundle.workflows) registry.register(workflow);
19
+ return registry;
20
+ }
21
+ function workflowImplementationFromBundleEntry(entry) {
22
+ if (typeof entry !== "function") return entry;
23
+ const implementation = getCompiledWorkflowDefinition(entry);
24
+ if (implementation === void 0) WorkflowDefinitionError.compiledMetadataMissing();
25
+ return implementation;
26
+ }
27
+ //#endregion
28
+ export { createWorkflowBundleRegistry, defineWorkflowBundle };
@@ -1,14 +1,22 @@
1
1
  import { RegistryLike, WorkflowDefinition, WorkflowHandler, WorkflowImplementation } from "../types/definition.mjs";
2
+ import { WorkflowBundle } from "../bundle.mjs";
2
3
  import { CreateWorkflowEngineOptions } from "../types/engine-options.mjs";
3
4
  import { WorkflowClientEngine, WorkflowWorkerEngine } from "../types/engine.mjs";
4
5
  import { WorkflowClient as WorkflowClient$1, WorkflowClientAdminApi, WorkflowClientHooksApi, WorkflowClientLocksApi, WorkflowClientMessagesApi, WorkflowClientRunsApi, WorkflowClientSchedulesApi, WorkflowClientStreamsApi, WorkflowClientWorkersApi, WorkflowRunnable } from "../types/client.mjs";
5
6
  //#region src/client/create.d.ts
6
7
  type WorkflowClientEngineOptions = Omit<CreateWorkflowEngineOptions, "storage" | "store">;
7
- interface CreateWorkflowClientOptions extends WorkflowClientEngineOptions {
8
+ interface CreateWorkflowClientBaseOptions extends WorkflowClientEngineOptions {
8
9
  readonly engine?: WorkflowClientEngine;
9
10
  readonly workerEngine?: WorkflowWorkerEngine;
10
- readonly registry?: RegistryLike;
11
11
  }
12
+ /** Options for creating a workflow client with either a registry or an immutable bundle. */
13
+ type CreateWorkflowClientOptions = CreateWorkflowClientBaseOptions & ({
14
+ readonly registry?: RegistryLike;
15
+ readonly workflows?: never;
16
+ } | {
17
+ readonly registry?: never;
18
+ readonly workflows?: WorkflowBundle;
19
+ });
12
20
  declare function createWorkflowClient(options?: CreateWorkflowClientOptions): WorkflowClient$1;
13
21
  /** Workflow client facade implementation. */
14
22
  declare class WorkflowClient implements WorkflowClient$1 {
@@ -1,6 +1,7 @@
1
+ import { Registry } from "../registry.mjs";
2
+ import { createWorkflowBundleRegistry } from "../bundle.mjs";
1
3
  import { createWorkflowClientAdminApi, createWorkflowClientHooksApi, createWorkflowClientLocksApi, createWorkflowClientMessagesApi, createWorkflowClientRunsApi, createWorkflowClientSchedulesApi, createWorkflowClientStreamsApi, createWorkflowClientWorkersApi } from "./facades.mjs";
2
4
  import { createWorkflowEngine } from "../engine/create.mjs";
3
- import { Registry } from "../registry.mjs";
4
5
  //#region src/client/create.ts
5
6
  function createWorkflowClient(options = {}) {
6
7
  return new WorkflowClient(options);
@@ -20,14 +21,15 @@ var WorkflowClient = class {
20
21
  #now;
21
22
  #registry;
22
23
  constructor(options = {}) {
23
- const { engine, workerEngine, registry, now, ...engineOptions } = options;
24
+ const { engine, workerEngine, registry, workflows, now, ...engineOptions } = options;
25
+ if (registry !== void 0 && workflows !== void 0) throw new TypeError("Workflow client options cannot include both registry and workflows");
24
26
  this.#now = now ?? Temporal.Now.instant;
25
27
  this.#engine = engine ?? createWorkflowEngine({
26
28
  ...engineOptions,
27
29
  now: this.#now
28
30
  });
29
31
  this.#workerEngine = workerEngine ?? workflowWorkerEngineFromCandidate(this.#engine);
30
- this.#registry = registry ?? new Registry();
32
+ this.#registry = registry ?? (workflows === void 0 ? new Registry() : createWorkflowBundleRegistry(workflows));
31
33
  this.runs = createWorkflowClientRunsApi(() => this.#engine, this.#now);
32
34
  this.admin = createWorkflowClientAdminApi(() => this.#engine, this.#now);
33
35
  this.schedules = createWorkflowClientSchedulesApi(() => this.#engine, this.#now);
@@ -120,13 +120,16 @@ function createWorkflowClientMessagesApi(getEngine) {
120
120
  function createWorkflowClientWorkersApi(getEngine, getRegistry, now) {
121
121
  return {
122
122
  create: (options) => {
123
- return new WorkflowWorker(workerOptionsFromClientOptions(requireWorkflowWorkerEngine(getEngine()), getRegistry(), now, options));
123
+ const engine = requireWorkflowWorkerEngine(getEngine());
124
+ return new WorkflowWorker(workerOptionsFromClientOptions(engine, getRegistry(), now, options));
124
125
  },
125
126
  processRun: async (runId, options) => {
126
- await new WorkflowWorker(workerOptionsFromClientOptions(requireWorkflowWorkerEngine(getEngine()), getRegistry(), now, workerOptionsFromWakeOptions(options))).processRun(runId);
127
+ const engine = requireWorkflowWorkerEngine(getEngine());
128
+ await new WorkflowWorker(workerOptionsFromClientOptions(engine, getRegistry(), now, workerOptionsFromWakeOptions(options))).processRun(runId);
127
129
  },
128
130
  wakeDueRuns: async (options) => {
129
- const worker = new WorkflowWorker(workerOptionsFromClientOptions(requireWorkflowWorkerEngine(getEngine()), getRegistry(), now, workerOptionsFromWakeOptions(options)));
131
+ const engine = requireWorkflowWorkerEngine(getEngine());
132
+ const worker = new WorkflowWorker(workerOptionsFromClientOptions(engine, getRegistry(), now, workerOptionsFromWakeOptions(options)));
130
133
  const filters = options === void 0 ? {} : options;
131
134
  const maxRuns = resolvePositiveSafeIntegerOption(options?.maxRuns, "Workflow worker maxRuns") ?? 1;
132
135
  let processedRuns = 0;
@@ -11,6 +11,7 @@ import { WorkflowRunHandleReader, WorkflowRunMaintenance, WorkflowStreamReader }
11
11
  import { WorkflowRunHandle as WorkflowRunHandle$1 } from "../types/client.mjs";
12
12
  import "../mod.mjs";
13
13
  import { StorageValue } from "@temelj/storage";
14
+ import "temporal-polyfill/global";
14
15
  //#region src/client/run-handle.d.ts
15
16
  type WorkflowRunHandleEngine = WorkflowRunHandleReader & WorkflowStreamReader & WorkflowRunMaintenance;
16
17
  declare function createWorkflowRunHandle<TOutput>(engine: WorkflowRunHandleEngine, definition: WorkflowDefinition<unknown, TOutput>, runId: RunId, now: () => Temporal.Instant): WorkflowRunHandle$1<TOutput>;
@@ -4,6 +4,7 @@ import "../errors/mod.mjs";
4
4
  import { workflowErrorFromRecord } from "../errors/records.mjs";
5
5
  import { durationBetween } from "../temporal.mjs";
6
6
  import { nonNegativeTimerDelay, sleep } from "../timer.mjs";
7
+ import "temporal-polyfill/global";
7
8
  //#region src/client/run-handle.ts
8
9
  const DEFAULT_RESULT_POLL_INTERVAL = Temporal.Duration.from({ milliseconds: 100 });
9
10
  function createWorkflowRunHandle(engine, definition, runId, now) {
@@ -59,7 +60,8 @@ var WorkflowRunHandle = class {
59
60
  if (result.kind === "failed") throw workflowErrorFromRecord(result.error);
60
61
  let sleepDelay = pollInterval;
61
62
  if (timeout !== void 0 && deadlineAt !== void 0) {
62
- const remainingDelay = durationTotal(durationBetween(this.#now(), deadlineAt));
63
+ const nowInstant = this.#now();
64
+ const remainingDelay = durationTotal(durationBetween(nowInstant, deadlineAt));
63
65
  if (remainingDelay <= 0) WorkflowResultTimeoutError.timedOut(this.runId, timeout);
64
66
  sleepDelay = Math.min(sleepDelay, remainingDelay);
65
67
  }
@@ -0,0 +1,12 @@
1
+ //#region src/cloudflare/cloudflare.d.ts
2
+ declare module "cloudflare:workers" {
3
+ export abstract class WorkflowEntrypoint<TEnv = unknown, TPayload = unknown> {
4
+ protected readonly env: TEnv;
5
+ abstract run(event: unknown, step: unknown): Promise<unknown>;
6
+ }
7
+ }
8
+ declare module "cloudflare:workflows" {
9
+ export class NonRetryableError extends Error {
10
+ constructor(message: string, name?: string);
11
+ }
12
+ }
@@ -0,0 +1,16 @@
1
+ import { z } from "zod";
2
+ //#region src/cloudflare/codec.d.ts
3
+ declare const cloudflareWorkflowEnvelopeSchema: z.ZodObject<{
4
+ kind: z.ZodLiteral<"temelj-workflow">;
5
+ version: z.ZodLiteral<1>;
6
+ workflowName: z.ZodString;
7
+ workflowVersion: z.ZodOptional<z.ZodString>;
8
+ input: z.ZodString;
9
+ }, z.core.$strip>;
10
+ /** Serialized payload dispatched through the generic Cloudflare entrypoint. */
11
+ type CloudflareWorkflowEnvelope = z.infer<typeof cloudflareWorkflowEnvelopeSchema>;
12
+ declare function encodeCloudflareWorkflowValue(value: unknown): string;
13
+ declare function decodeCloudflareWorkflowValue(value: unknown, label: string): unknown;
14
+ declare function parseCloudflareWorkflowEnvelope(value: unknown): CloudflareWorkflowEnvelope;
15
+ //#endregion
16
+ export { CloudflareWorkflowEnvelope, decodeCloudflareWorkflowValue, encodeCloudflareWorkflowValue, parseCloudflareWorkflowEnvelope };
@@ -0,0 +1,25 @@
1
+ import { createSuperJsonStorageCodec } from "@temelj/storage";
2
+ import { z } from "zod";
3
+ //#region src/cloudflare/codec.ts
4
+ const cloudflareWorkflowCodec = createSuperJsonStorageCodec({ format: "string" });
5
+ const cloudflareWorkflowEnvelopeSchema = z.object({
6
+ kind: z.literal("temelj-workflow"),
7
+ version: z.literal(1),
8
+ workflowName: z.string().min(1),
9
+ workflowVersion: z.string().min(1).optional(),
10
+ input: z.string()
11
+ });
12
+ function encodeCloudflareWorkflowValue(value) {
13
+ return cloudflareWorkflowCodec.encode(value);
14
+ }
15
+ function decodeCloudflareWorkflowValue(value, label) {
16
+ if (typeof value !== "string") throw new TypeError(`${label} must be an encoded string`);
17
+ return cloudflareWorkflowCodec.decode(value);
18
+ }
19
+ function parseCloudflareWorkflowEnvelope(value) {
20
+ const parsed = cloudflareWorkflowEnvelopeSchema.safeParse(value);
21
+ if (!parsed.success) throw new TypeError("Cloudflare Workflow payload is not a valid Temelj workflow envelope");
22
+ return parsed.data;
23
+ }
24
+ //#endregion
25
+ export { decodeCloudflareWorkflowValue, encodeCloudflareWorkflowValue, parseCloudflareWorkflowEnvelope };
@@ -0,0 +1,12 @@
1
+ import { RegistryLike } from "../types/definition.mjs";
2
+ import { Logger } from "@temelj/log";
3
+ import { WorkflowEntrypoint } from "cloudflare:workers";
4
+ //#region src/cloudflare/entrypoint.d.ts
5
+ interface CreateCloudflareWorkflowEntrypointOptions {
6
+ readonly registry: RegistryLike;
7
+ readonly logger?: Logger;
8
+ }
9
+ /** Creates a Cloudflare Workflow entrypoint class that dispatches through a Temelj registry. */
10
+ declare function createCloudflareWorkflowEntrypoint<TEnv = unknown>(options: CreateCloudflareWorkflowEntrypointOptions): typeof WorkflowEntrypoint<TEnv, unknown>;
11
+ //#endregion
12
+ export { CreateCloudflareWorkflowEntrypointOptions, createCloudflareWorkflowEntrypoint };
@@ -0,0 +1,18 @@
1
+ import { runCloudflareWorkflow } from "./execution.mjs";
2
+ import { WorkflowEntrypoint } from "cloudflare:workers";
3
+ import { NonRetryableError } from "cloudflare:workflows";
4
+ //#region src/cloudflare/entrypoint.ts
5
+ /** Creates a Cloudflare Workflow entrypoint class that dispatches through a Temelj registry. */
6
+ function createCloudflareWorkflowEntrypoint(options) {
7
+ return class TemeljCloudflareWorkflowEntrypoint extends WorkflowEntrypoint {
8
+ async run(event, step) {
9
+ return await runCloudflareWorkflow({
10
+ registry: options.registry,
11
+ ...options.logger === void 0 ? {} : { logger: options.logger },
12
+ nonRetryableError: NonRetryableError
13
+ }, event, step);
14
+ }
15
+ };
16
+ }
17
+ //#endregion
18
+ export { createCloudflareWorkflowEntrypoint };
@@ -0,0 +1,13 @@
1
+ import { RegistryLike } from "../types/definition.mjs";
2
+ import { CloudflareNonRetryableErrorConstructor, CloudflareWorkflowEvent, CloudflareWorkflowStep } from "./types.mjs";
3
+ import { Logger } from "@temelj/log";
4
+ //#region src/cloudflare/execution.d.ts
5
+ interface RunCloudflareWorkflowOptions {
6
+ readonly registry: RegistryLike;
7
+ readonly logger?: Logger;
8
+ readonly nonRetryableError?: CloudflareNonRetryableErrorConstructor;
9
+ }
10
+ /** Dispatches one Cloudflare Workflow invocation to a registered Temelj implementation. */
11
+ declare function runCloudflareWorkflow(options: RunCloudflareWorkflowOptions, event: CloudflareWorkflowEvent, step: CloudflareWorkflowStep): Promise<string>;
12
+ //#endregion
13
+ export { RunCloudflareWorkflowOptions, runCloudflareWorkflow };
@@ -0,0 +1,28 @@
1
+ import { WorkflowCapabilityError } from "../errors/capability.mjs";
2
+ import "../errors/mod.mjs";
3
+ import { parseWorkflowInput } from "../definition.mjs";
4
+ import { decodeCloudflareWorkflowValue, encodeCloudflareWorkflowValue, parseCloudflareWorkflowEnvelope } from "./codec.mjs";
5
+ import { resolveCloudflareWorkflowImplementation } from "./registry.mjs";
6
+ import { createCloudflareWorkflowContext } from "./step.mjs";
7
+ //#region src/cloudflare/execution.ts
8
+ /** Dispatches one Cloudflare Workflow invocation to a registered Temelj implementation. */
9
+ async function runCloudflareWorkflow(options, event, step) {
10
+ const envelope = parseCloudflareWorkflowEnvelope(event.payload);
11
+ const implementation = resolveCloudflareWorkflowImplementation(options.registry, envelope.workflowName, envelope.workflowVersion);
12
+ if (implementation.config.retry !== void 0) WorkflowCapabilityError.unsupported("Cloudflare workflow-level retry configuration");
13
+ const rawInput = decodeCloudflareWorkflowValue(envelope.input, "Cloudflare Workflow input");
14
+ const input = await parseWorkflowInput(implementation.definition, rawInput);
15
+ const context = createCloudflareWorkflowContext({
16
+ input,
17
+ step,
18
+ runId: event.instanceId,
19
+ workflowName: implementation.name,
20
+ ...implementation.version === void 0 ? {} : { workflowVersion: implementation.version },
21
+ createdAt: Temporal.Instant.fromEpochMilliseconds(event.timestamp.getTime()),
22
+ ...options.logger === void 0 ? {} : { logger: options.logger },
23
+ ...options.nonRetryableError === void 0 ? {} : { nonRetryableError: options.nonRetryableError }
24
+ });
25
+ return encodeCloudflareWorkflowValue(await implementation.handler(context));
26
+ }
27
+ //#endregion
28
+ export { runCloudflareWorkflow };
@@ -0,0 +1,19 @@
1
+ import { WorkflowBundle } from "../bundle.mjs";
2
+ import { createCloudflareWorkflowEntrypoint } from "./entrypoint.mjs";
3
+ import { CloudflareWorkflowBinding } from "./types.mjs";
4
+ import { CloudflareWorkflowRuntime, CreateCloudflareWorkflowRuntimeOptions } from "./runtime.mjs";
5
+ import { Logger } from "@temelj/log";
6
+ //#region src/cloudflare/host.d.ts
7
+ interface CreateCloudflareWorkflowHostOptions {
8
+ readonly workflows: WorkflowBundle;
9
+ readonly logger?: Logger;
10
+ }
11
+ type CreateCloudflareWorkflowHostRuntimeOptions = Omit<CreateCloudflareWorkflowRuntimeOptions, "binding" | "registration" | "registry">;
12
+ interface CloudflareWorkflowHost<TEnv> {
13
+ readonly Entrypoint: ReturnType<typeof createCloudflareWorkflowEntrypoint<TEnv>>;
14
+ createRuntime(binding: CloudflareWorkflowBinding, options?: CreateCloudflareWorkflowHostRuntimeOptions): CloudflareWorkflowRuntime;
15
+ }
16
+ /** Creates a Cloudflare host backed by one immutable workflow bundle. */
17
+ declare function createCloudflareWorkflowHost<TEnv = unknown>(options: CreateCloudflareWorkflowHostOptions): CloudflareWorkflowHost<TEnv>;
18
+ //#endregion
19
+ export { CloudflareWorkflowHost, CreateCloudflareWorkflowHostOptions, CreateCloudflareWorkflowHostRuntimeOptions, createCloudflareWorkflowHost };
@@ -0,0 +1,24 @@
1
+ import { createWorkflowBundleRegistry } from "../bundle.mjs";
2
+ import { createCloudflareWorkflowEntrypoint } from "./entrypoint.mjs";
3
+ import { createCloudflareWorkflowRuntime } from "./runtime.mjs";
4
+ //#region src/cloudflare/host.ts
5
+ /** Creates a Cloudflare host backed by one immutable workflow bundle. */
6
+ function createCloudflareWorkflowHost(options) {
7
+ const registry = createWorkflowBundleRegistry(options.workflows);
8
+ return {
9
+ Entrypoint: createCloudflareWorkflowEntrypoint({
10
+ registry,
11
+ ...options.logger === void 0 ? {} : { logger: options.logger }
12
+ }),
13
+ createRuntime(binding, runtimeOptions = {}) {
14
+ return createCloudflareWorkflowRuntime({
15
+ ...runtimeOptions,
16
+ binding,
17
+ registry,
18
+ registration: "static"
19
+ });
20
+ }
21
+ };
22
+ }
23
+ //#endregion
24
+ export { createCloudflareWorkflowHost };
@@ -0,0 +1,8 @@
1
+ import { CreateCloudflareWorkflowEntrypointOptions, createCloudflareWorkflowEntrypoint } from "./entrypoint.mjs";
2
+ import { CloudflareNonRetryableErrorConstructor, CloudflareWorkflowBinding, CloudflareWorkflowEvent, CloudflareWorkflowInstance, CloudflareWorkflowInstanceCreateOptions, CloudflareWorkflowInstanceStatus, CloudflareWorkflowStep, CloudflareWorkflowStepConfig, CloudflareWorkflowStepContext, CloudflareWorkflowStepEvent } from "./types.mjs";
3
+ import { RunCloudflareWorkflowOptions, runCloudflareWorkflow } from "./execution.mjs";
4
+ import { CloudflareWorkflowMessagesApi, CloudflareWorkflowRuntime, CloudflareWorkflowRuntimeRunsApi, CreateCloudflareWorkflowRuntimeOptions, createCloudflareWorkflowRuntime } from "./runtime.mjs";
5
+ import { CloudflareWorkflowHost, CreateCloudflareWorkflowHostOptions, CreateCloudflareWorkflowHostRuntimeOptions, createCloudflareWorkflowHost } from "./host.mjs";
6
+ import { createCloudflareWorkflowRegistry, resolveCloudflareWorkflowImplementation } from "./registry.mjs";
7
+ import "temporal-polyfill/global";
8
+ export { type CloudflareNonRetryableErrorConstructor, type CloudflareWorkflowBinding, type CloudflareWorkflowEvent, CloudflareWorkflowHost, type CloudflareWorkflowInstance, type CloudflareWorkflowInstanceCreateOptions, type CloudflareWorkflowInstanceStatus, CloudflareWorkflowMessagesApi, CloudflareWorkflowRuntime, CloudflareWorkflowRuntimeRunsApi, type CloudflareWorkflowStep, type CloudflareWorkflowStepConfig, type CloudflareWorkflowStepContext, type CloudflareWorkflowStepEvent, CreateCloudflareWorkflowEntrypointOptions, CreateCloudflareWorkflowHostOptions, CreateCloudflareWorkflowHostRuntimeOptions, CreateCloudflareWorkflowRuntimeOptions, RunCloudflareWorkflowOptions, createCloudflareWorkflowEntrypoint, createCloudflareWorkflowHost, createCloudflareWorkflowRegistry, createCloudflareWorkflowRuntime, resolveCloudflareWorkflowImplementation, runCloudflareWorkflow };
@@ -0,0 +1,7 @@
1
+ import { createCloudflareWorkflowRegistry, resolveCloudflareWorkflowImplementation } from "./registry.mjs";
2
+ import { runCloudflareWorkflow } from "./execution.mjs";
3
+ import { createCloudflareWorkflowEntrypoint } from "./entrypoint.mjs";
4
+ import { createCloudflareWorkflowRuntime } from "./runtime.mjs";
5
+ import { createCloudflareWorkflowHost } from "./host.mjs";
6
+ import "temporal-polyfill/global";
7
+ export { createCloudflareWorkflowEntrypoint, createCloudflareWorkflowHost, createCloudflareWorkflowRegistry, createCloudflareWorkflowRuntime, resolveCloudflareWorkflowImplementation, runCloudflareWorkflow };
@@ -0,0 +1,5 @@
1
+ //#region src/cloudflare/name.d.ts
2
+ declare function makeCloudflareWorkflowStepName(value: string): string;
3
+ declare function makeCloudflareWorkflowEventType(value: string): string;
4
+ //#endregion
5
+ export { makeCloudflareWorkflowEventType, makeCloudflareWorkflowStepName };
@@ -0,0 +1,22 @@
1
+ //#region src/cloudflare/name.ts
2
+ const CLOUDFLARE_NAME_CHARACTERS = /[^a-zA-Z0-9_-]+/g;
3
+ function makeCloudflareWorkflowStepName(value) {
4
+ return makeCloudflareName(value, 256, "step");
5
+ }
6
+ function makeCloudflareWorkflowEventType(value) {
7
+ return makeCloudflareName(value, 100, "event");
8
+ }
9
+ function makeCloudflareName(value, maximumLength, fallback) {
10
+ const normalized = value.replace(CLOUDFLARE_NAME_CHARACTERS, "-").replace(/^-+/, "");
11
+ return `${(normalized === "" ? fallback : normalized).slice(0, maximumLength - 16)}-${fnv1a(value)}`.slice(0, maximumLength);
12
+ }
13
+ function fnv1a(value) {
14
+ let hash = 14695981039346656037n;
15
+ for (let index = 0; index < value.length; index++) {
16
+ hash ^= BigInt(value.charCodeAt(index));
17
+ hash = BigInt.asUintN(64, hash * 1099511628211n);
18
+ }
19
+ return hash.toString(36).padStart(13, "0");
20
+ }
21
+ //#endregion
22
+ export { makeCloudflareWorkflowEventType, makeCloudflareWorkflowStepName };
@@ -0,0 +1,24 @@
1
+ import { RegistryLike, WorkflowDefinitionConfig, WorkflowImplementation } from "../types/definition.mjs";
2
+ import { CompiledWorkflowFunction } from "../types/client.mjs";
3
+ import { Registry } from "../registry.mjs";
4
+ import { Schema } from "@temelj/standard-schema";
5
+ //#region src/cloudflare/registry.d.ts
6
+ interface CloudflareWorkflowImplementationLike {
7
+ readonly kind: "implementation";
8
+ readonly definition: {
9
+ readonly kind: "definition";
10
+ readonly config: WorkflowDefinitionConfig<Schema | undefined>;
11
+ readonly name: string;
12
+ readonly version?: string;
13
+ };
14
+ readonly config: WorkflowDefinitionConfig<Schema | undefined>;
15
+ readonly name: string;
16
+ readonly version?: string;
17
+ readonly handler: (...args: never[]) => unknown;
18
+ }
19
+ type CloudflareWorkflowRegistryEntry = CloudflareWorkflowImplementationLike | CompiledWorkflowFunction<readonly unknown[], unknown>;
20
+ /** Creates a registry shared by the Cloudflare entrypoint and runtime facade. */
21
+ declare function createCloudflareWorkflowRegistry(entries?: readonly CloudflareWorkflowRegistryEntry[]): Registry;
22
+ declare function resolveCloudflareWorkflowImplementation(registry: RegistryLike, name: string, version?: string): WorkflowImplementation<unknown, unknown>;
23
+ //#endregion
24
+ export { createCloudflareWorkflowRegistry, resolveCloudflareWorkflowImplementation };
@@ -0,0 +1,26 @@
1
+ import { WorkflowDefinitionError } from "../errors/definition.mjs";
2
+ import "../errors/mod.mjs";
3
+ import { getCompiledWorkflowDefinition } from "../compiled-function.mjs";
4
+ import { Registry } from "../registry.mjs";
5
+ //#region src/cloudflare/registry.ts
6
+ /** Creates a registry shared by the Cloudflare entrypoint and runtime facade. */
7
+ function createCloudflareWorkflowRegistry(entries = []) {
8
+ const registry = new Registry();
9
+ for (const entry of entries) {
10
+ if (typeof entry === "function") {
11
+ const implementation = getCompiledWorkflowDefinition(entry);
12
+ if (implementation === void 0) WorkflowDefinitionError.compiledMetadataMissing();
13
+ registry.register(implementation);
14
+ continue;
15
+ }
16
+ registry.register(entry);
17
+ }
18
+ return registry;
19
+ }
20
+ function resolveCloudflareWorkflowImplementation(registry, name, version) {
21
+ const implementation = version === void 0 ? registry.latest(name) : registry.getByName(name, version);
22
+ if (implementation === void 0) throw new TypeError(`Cloudflare Workflow implementation is not registered: ${version === void 0 ? name : `${name}@${version}`}`);
23
+ return implementation;
24
+ }
25
+ //#endregion
26
+ export { createCloudflareWorkflowRegistry, resolveCloudflareWorkflowImplementation };
@@ -0,0 +1,30 @@
1
+ import { RunId } from "../types/run-id.mjs";
2
+ import { RegistryLike, WorkflowStartTarget } from "../types/definition.mjs";
3
+ import { MessageChannel, SendMessageChannelOptions, SendMessageInput } from "../types/message.mjs";
4
+ import "../types/run.mjs";
5
+ import { WorkflowRunHandle } from "../types/client.mjs";
6
+ import { WorkflowRuntime, WorkflowRuntimeRunsApi } from "../types/runtime.mjs";
7
+ import { CloudflareWorkflowBinding } from "./types.mjs";
8
+ //#region src/cloudflare/runtime.d.ts
9
+ interface CreateCloudflareWorkflowRuntimeOptions {
10
+ readonly binding: CloudflareWorkflowBinding;
11
+ readonly registry?: RegistryLike;
12
+ readonly resultPollInterval?: Temporal.Duration;
13
+ /** Controls whether workflows absent from the initial registry may be registered at runtime. */
14
+ readonly registration?: "dynamic" | "static";
15
+ }
16
+ interface CloudflareWorkflowRuntimeRunsApi extends WorkflowRuntimeRunsApi {
17
+ get<TInput, TOutput, TRawInput = TInput>(workflow: WorkflowStartTarget<TInput, TOutput, TRawInput>, runId: RunId): Promise<WorkflowRunHandle<TOutput>>;
18
+ }
19
+ interface CloudflareWorkflowMessagesApi {
20
+ send(runId: RunId, options: SendMessageInput): Promise<void>;
21
+ send<TPayload, TKey = void>(runId: RunId, channel: MessageChannel<TPayload, TKey>, options?: SendMessageChannelOptions<TPayload, TKey>): Promise<void>;
22
+ }
23
+ interface CloudflareWorkflowRuntime extends WorkflowRuntime {
24
+ readonly runs: CloudflareWorkflowRuntimeRunsApi;
25
+ readonly messages: CloudflareWorkflowMessagesApi;
26
+ }
27
+ /** Creates a runtime facade over a generic Cloudflare Workflow binding. */
28
+ declare function createCloudflareWorkflowRuntime(options: CreateCloudflareWorkflowRuntimeOptions): CloudflareWorkflowRuntime;
29
+ //#endregion
30
+ export { CloudflareWorkflowMessagesApi, CloudflareWorkflowRuntime, CloudflareWorkflowRuntimeRunsApi, CreateCloudflareWorkflowRuntimeOptions, createCloudflareWorkflowRuntime };