steppler 0.0.1 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,15 @@
1
+ # steppler
2
+
3
+ To install dependencies:
4
+
5
+ ```bash
6
+ bun install
7
+ ```
8
+
9
+ To run:
10
+
11
+ ```bash
12
+ bun run index.ts
13
+ ```
14
+
15
+ This project was created using `bun init` in bun v1.3.10. [Bun](https://bun.com) is a fast all-in-one JavaScript runtime.
@@ -0,0 +1,3 @@
1
+ import type { Steppler } from "../client.js";
2
+ export declare function createHandler(client: Steppler): (req: Request) => Promise<Response>;
3
+ //# sourceMappingURL=generic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generic.d.ts","sourceRoot":"","sources":["../../src/adapters/generic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAE7C,wBAAgB,aAAa,CAAC,MAAM,EAAE,QAAQ,uCAE7C"}
@@ -0,0 +1,4 @@
1
+ export function createHandler(client) {
2
+ return client._createHandler();
3
+ }
4
+ //# sourceMappingURL=generic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generic.js","sourceRoot":"","sources":["../../src/adapters/generic.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,aAAa,CAAC,MAAgB;IAC7C,OAAO,MAAM,CAAC,cAAc,EAAE,CAAC;AAChC,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { Steppler } from "../client.js";
2
+ export declare function createNextHandler(client: Steppler): {
3
+ POST: (req: Request) => Promise<Response>;
4
+ };
5
+ //# sourceMappingURL=next.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"next.d.ts","sourceRoot":"","sources":["../../src/adapters/next.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAE7C,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,QAAQ;gBAGpC,OAAO;EAEpB"}
@@ -0,0 +1,7 @@
1
+ export function createNextHandler(client) {
2
+ const handle = client._createHandler();
3
+ return {
4
+ POST: (req) => handle(req),
5
+ };
6
+ }
7
+ //# sourceMappingURL=next.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"next.js","sourceRoot":"","sources":["../../src/adapters/next.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,iBAAiB,CAAC,MAAgB;IACjD,MAAM,MAAM,GAAG,MAAM,CAAC,cAAc,EAAE,CAAC;IACvC,OAAO;QACN,IAAI,EAAE,CAAC,GAAY,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC;KACnC,CAAC;AACH,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { Steppler as StepplerClient } from "@steppler/api";
2
+ import type { Task, TaskConfig } from "./types.js";
3
+ export declare class Steppler {
4
+ _registry: Map<string, Task<unknown, unknown>>;
5
+ _client: StepplerClient;
6
+ _signingSecret?: string;
7
+ constructor(config?: {
8
+ apiKey?: string;
9
+ apiUrl?: string;
10
+ signingSecret?: string;
11
+ });
12
+ task<TPayload = unknown, TResult = unknown>(config: TaskConfig<TPayload, TResult>): Task<TPayload, TResult>;
13
+ _createHandler(): (req: Request) => Promise<Response>;
14
+ }
15
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,cAAc,EAAE,MAAM,eAAe,CAAC;AAG3D,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEnD,qBAAa,QAAQ;IACpB,SAAS,sCAA6C;IACtD,OAAO,EAAE,cAAc,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;gBAEZ,MAAM,CAAC,EAAE;QACpB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,aAAa,CAAC,EAAE,MAAM,CAAC;KACvB;IAcD,IAAI,CAAC,QAAQ,GAAG,OAAO,EAAE,OAAO,GAAG,OAAO,EACzC,MAAM,EAAE,UAAU,CAAC,QAAQ,EAAE,OAAO,CAAC,GACnC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC;IAM1B,cAAc;CAGd"}
package/dist/client.js ADDED
@@ -0,0 +1,27 @@
1
+ import { Steppler as StepplerClient } from "@steppler/api";
2
+ import { createHandler } from "./handler.js";
3
+ import { createTask } from "./task.js";
4
+ export class Steppler {
5
+ _registry = new Map();
6
+ _client;
7
+ _signingSecret;
8
+ constructor(config) {
9
+ const apiKey = config?.apiKey ?? process.env.STEPPLER_API_KEY ?? "";
10
+ const apiUrl = config?.apiUrl ?? process.env.STEPPLER_API_URL;
11
+ const signingSecret = config?.signingSecret ?? process.env.STEPPLER_SIGNING_SECRET;
12
+ this._signingSecret = signingSecret;
13
+ this._client = new StepplerClient({
14
+ bearerAuth: apiKey,
15
+ ...(apiUrl ? { serverURL: apiUrl } : {}),
16
+ });
17
+ }
18
+ task(config) {
19
+ const t = createTask(config, this._client);
20
+ this._registry.set(config.id, t);
21
+ return t;
22
+ }
23
+ _createHandler() {
24
+ return createHandler(this._registry, this._signingSecret);
25
+ }
26
+ }
27
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,cAAc,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAGvC,MAAM,OAAO,QAAQ;IACpB,SAAS,GAAG,IAAI,GAAG,EAAkC,CAAC;IACtD,OAAO,CAAiB;IACxB,cAAc,CAAU;IAExB,YAAY,MAIX;QACA,MAAM,MAAM,GAAG,MAAM,EAAE,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,EAAE,CAAC;QACpE,MAAM,MAAM,GAAG,MAAM,EAAE,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;QAC9D,MAAM,aAAa,GAClB,MAAM,EAAE,aAAa,IAAI,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC;QAE9D,IAAI,CAAC,cAAc,GAAG,aAAa,CAAC;QAEpC,IAAI,CAAC,OAAO,GAAG,IAAI,cAAc,CAAC;YACjC,UAAU,EAAE,MAAM;YAClB,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACxC,CAAC,CAAC;IACJ,CAAC;IAED,IAAI,CACH,MAAqC;QAErC,MAAM,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QAC3C,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,CAA2B,CAAC,CAAC;QAC3D,OAAO,CAAC,CAAC;IACV,CAAC;IAED,cAAc;QACb,OAAO,aAAa,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;IAC3D,CAAC;CACD"}
@@ -0,0 +1,7 @@
1
+ export declare class FatalError extends Error {
2
+ constructor(message: string);
3
+ }
4
+ export declare class StepplerError extends Error {
5
+ constructor(message: string);
6
+ }
7
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,UAAW,SAAQ,KAAK;gBACxB,OAAO,EAAE,MAAM;CAI3B;AAED,qBAAa,aAAc,SAAQ,KAAK;gBAC3B,OAAO,EAAE,MAAM;CAI3B"}
package/dist/errors.js ADDED
@@ -0,0 +1,13 @@
1
+ export class FatalError extends Error {
2
+ constructor(message) {
3
+ super(message);
4
+ this.name = "FatalError";
5
+ }
6
+ }
7
+ export class StepplerError extends Error {
8
+ constructor(message) {
9
+ super(message);
10
+ this.name = "StepplerError";
11
+ }
12
+ }
13
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,UAAW,SAAQ,KAAK;IACpC,YAAY,OAAe;QAC1B,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;IAC1B,CAAC;CACD;AAED,MAAM,OAAO,aAAc,SAAQ,KAAK;IACvC,YAAY,OAAe;QAC1B,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC7B,CAAC;CACD"}
@@ -0,0 +1,3 @@
1
+ import type { Task } from "./types.js";
2
+ export declare function createHandler(registry: Map<string, Task<unknown, unknown>>, signingSecret?: string): (req: Request) => Promise<Response>;
3
+ //# sourceMappingURL=handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../src/handler.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,wBAAgB,aAAa,CAC5B,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,EAC7C,aAAa,CAAC,EAAE,MAAM,IAEO,KAAK,OAAO,KAAG,OAAO,CAAC,QAAQ,CAAC,CA4F7D"}
@@ -0,0 +1,75 @@
1
+ import { createHmac } from "crypto";
2
+ import { FatalError } from "./errors.js";
3
+ import { createStepHelpers } from "./step.js";
4
+ export function createHandler(registry, signingSecret) {
5
+ return async function handle(req) {
6
+ // Verify signature
7
+ const body = await req.text();
8
+ if (signingSecret) {
9
+ const signature = req.headers.get("X-Steppler-Signature");
10
+ const expected = `sha256=${sign(body, signingSecret)}`;
11
+ if (signature !== expected) {
12
+ return new Response("Unauthorized", { status: 401 });
13
+ }
14
+ }
15
+ let parsed;
16
+ try {
17
+ parsed = JSON.parse(body);
18
+ }
19
+ catch {
20
+ return new Response("Invalid JSON body", { status: 400 });
21
+ }
22
+ const { runId, handler, payload, attempt = 1, state = {} } = parsed;
23
+ // Find task in registry
24
+ const task = registry.get(handler);
25
+ if (!task) {
26
+ return new Response(`No handler registered for "${handler}"`, {
27
+ status: 404,
28
+ });
29
+ }
30
+ // Validate payload with zod schema if present
31
+ if (task._config.schema) {
32
+ const result = task._config.schema.safeParse(payload);
33
+ if (!result.success) {
34
+ return new Response(JSON.stringify({
35
+ error: "Payload validation failed",
36
+ issues: result.error.issues,
37
+ }), { status: 400, headers: { "Content-Type": "application/json" } });
38
+ }
39
+ }
40
+ // Build step helpers
41
+ const pendingEvents = [];
42
+ const step = createStepHelpers(state, pendingEvents);
43
+ try {
44
+ const result = await task._config.run({ payload, runId, attempt, step });
45
+ return Response.json({
46
+ result,
47
+ events: pendingEvents,
48
+ }, { status: 200 });
49
+ }
50
+ catch (err) {
51
+ // Suspension signal from step.sleep()
52
+ if (typeof err === "object" &&
53
+ err !== null &&
54
+ "__steppler_suspend" in err) {
55
+ const suspension = err;
56
+ return Response.json({
57
+ suspend: true,
58
+ resumeAt: suspension.resumeAt,
59
+ events: pendingEvents,
60
+ }, { status: 202 });
61
+ }
62
+ // Fatal error — 4xx, no retry
63
+ if (err instanceof FatalError) {
64
+ return new Response(err.message, { status: 400 });
65
+ }
66
+ // Everything else — 5xx, DEW will retry
67
+ const message = err instanceof Error ? err.message : String(err);
68
+ return new Response(message, { status: 500 });
69
+ }
70
+ };
71
+ }
72
+ function sign(body, secret) {
73
+ return createHmac("sha256", secret).update(body).digest("hex");
74
+ }
75
+ //# sourceMappingURL=handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handler.js","sourceRoot":"","sources":["../src/handler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export { createHandler } from "./adapters/generic.js";
2
+ export { createNextHandler } from "./adapters/next.js";
3
+ export { Steppler } from "./client.js";
4
+ export { FatalError } from "./errors.js";
5
+ export type { Run, RunContext, RunResult, StepHelpers, Task, TaskConfig, TriggerOptions, } from "./types.js";
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,YAAY,EACX,GAAG,EACH,UAAU,EACV,SAAS,EACT,WAAW,EACX,IAAI,EACJ,UAAU,EACV,cAAc,GACd,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ export { createHandler } from "./adapters/generic.js";
2
+ export { createNextHandler } from "./adapters/next.js";
3
+ export { Steppler } from "./client.js";
4
+ export { FatalError } from "./errors.js";
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC"}
package/dist/step.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ import type { StepHelpers } from "./types.js";
2
+ export type PendingEvent = {
3
+ type: string;
4
+ metadata: Record<string, unknown>;
5
+ };
6
+ export declare function createStepHelpers(state: Record<string, unknown>, pendingEvents: PendingEvent[]): StepHelpers;
7
+ //# sourceMappingURL=step.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"step.d.ts","sourceRoot":"","sources":["../src/step.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,MAAM,MAAM,YAAY,GAAG;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC,CAAC;AAEF,wBAAgB,iBAAiB,CAChC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,aAAa,EAAE,YAAY,EAAE,GAC3B,WAAW,CA0Bb"}
package/dist/step.js ADDED
@@ -0,0 +1,39 @@
1
+ export function createStepHelpers(state, pendingEvents) {
2
+ return {
3
+ async run(id, fn) {
4
+ if (id in state) {
5
+ return state[id];
6
+ }
7
+ pendingEvents.push({ type: "step_started", metadata: { step: id } });
8
+ const output = await fn();
9
+ pendingEvents.push({
10
+ type: "step_completed",
11
+ metadata: { step: id, output },
12
+ });
13
+ return output;
14
+ },
15
+ async sleep(id, duration) {
16
+ if (id in state)
17
+ return;
18
+ const ms = parseDuration(duration);
19
+ const resumeAt = new Date(Date.now() + ms).toISOString();
20
+ throw { __steppler_suspend: true, resumeAt, step: id };
21
+ },
22
+ };
23
+ }
24
+ function parseDuration(duration) {
25
+ const units = {
26
+ ms: 1,
27
+ s: 1000,
28
+ m: 60_000,
29
+ h: 3_600_000,
30
+ d: 86_400_000,
31
+ };
32
+ const match = duration.match(/^(\d+)(ms|s|m|h|d)$/);
33
+ if (!match)
34
+ throw new Error(`Invalid duration format: "${duration}". Use e.g. "30s", "5m", "2h"`);
35
+ const value = parseInt(match[1], 10);
36
+ const unit = match[2];
37
+ return value * units[unit];
38
+ }
39
+ //# sourceMappingURL=step.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"step.js","sourceRoot":"","sources":["../src/step.ts"],"names":[],"mappings":"AAOA,MAAM,UAAU,iBAAiB,CAChC,KAA8B,EAC9B,aAA6B;IAE7B,OAAO;QACN,KAAK,CAAC,GAAG,CAAI,EAAU,EAAE,EAAoB;YAC5C,IAAI,EAAE,IAAI,KAAK,EAAE,CAAC;gBACjB,OAAO,KAAK,CAAC,EAAE,CAAM,CAAC;YACvB,CAAC;YAED,aAAa,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;YACrE,MAAM,MAAM,GAAG,MAAM,EAAE,EAAE,CAAC;YAC1B,aAAa,CAAC,IAAI,CAAC;gBAClB,IAAI,EAAE,gBAAgB;gBACtB,QAAQ,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE;aAC9B,CAAC,CAAC;YAEH,OAAO,MAAM,CAAC;QACf,CAAC;QAED,KAAK,CAAC,KAAK,CAAC,EAAU,EAAE,QAAgB;YACvC,IAAI,EAAE,IAAI,KAAK;gBAAE,OAAO;YAExB,MAAM,EAAE,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;YACnC,MAAM,QAAQ,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;YAEzD,MAAM,EAAE,kBAAkB,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;QACxD,CAAC;KACD,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,QAAgB;IACtC,MAAM,KAAK,GAA2B;QACrC,EAAE,EAAE,CAAC;QACL,CAAC,EAAE,IAAI;QACP,CAAC,EAAE,MAAM;QACT,CAAC,EAAE,SAAS;QACZ,CAAC,EAAE,UAAU;KACb,CAAC;IAEF,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;IACpD,IAAI,CAAC,KAAK;QACT,MAAM,IAAI,KAAK,CACd,6BAA6B,QAAQ,+BAA+B,CACpE,CAAC;IAEH,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACrC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAuB,CAAC;IAE5C,OAAO,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;AAC5B,CAAC"}
package/dist/task.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ import type { Steppler as StepplerClient } from "@steppler/api";
2
+ import type { Task, TaskConfig } from "./types.js";
3
+ export declare function createTask<TPayload, TResult>(config: TaskConfig<TPayload, TResult>, client: StepplerClient): Task<TPayload, TResult>;
4
+ //# sourceMappingURL=task.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task.d.ts","sourceRoot":"","sources":["../src/task.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,IAAI,cAAc,EAAE,MAAM,eAAe,CAAC;AAChE,OAAO,KAAK,EAGX,IAAI,EACJ,UAAU,EAEV,MAAM,YAAY,CAAC;AAMpB,wBAAgB,UAAU,CAAC,QAAQ,EAAE,OAAO,EAC3C,MAAM,EAAE,UAAU,CAAC,QAAQ,EAAE,OAAO,CAAC,EACrC,MAAM,EAAE,cAAc,GACpB,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAsDzB"}
package/dist/task.js ADDED
@@ -0,0 +1,46 @@
1
+ function sleep(ms) {
2
+ return new Promise((res) => setTimeout(res, ms));
3
+ }
4
+ export function createTask(config, client) {
5
+ return {
6
+ id: config.id,
7
+ _config: config,
8
+ async trigger(payload, options = {}) {
9
+ const validated = config.schema ? config.schema.parse(payload) : payload;
10
+ const run = await client.runs.create({
11
+ triggerId: config.id,
12
+ payload: validated,
13
+ idempotencyKey: options.idempotencyKey,
14
+ webhook: options.webhook,
15
+ tags: options.tags,
16
+ priority: options.priority,
17
+ scheduledAt: options.scheduledAt
18
+ ? new Date(options.scheduledAt)
19
+ : undefined,
20
+ });
21
+ return {
22
+ id: run.id,
23
+ status: run.status,
24
+ triggerId: run.triggerId,
25
+ createdAt: run.createdAt,
26
+ };
27
+ },
28
+ async triggerAndWait(payload, options = {}) {
29
+ const run = await this.trigger(payload, options);
30
+ while (true) {
31
+ const status = await client.runs.status({ id: run.id });
32
+ if (status.status === "success" || status.status === "failed") {
33
+ return {
34
+ id: status.id,
35
+ status: status.status,
36
+ result: status.result,
37
+ error: status.error,
38
+ finishedAt: status.finishedAt ?? null,
39
+ };
40
+ }
41
+ await sleep(1000);
42
+ }
43
+ },
44
+ };
45
+ }
46
+ //# sourceMappingURL=task.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task.js","sourceRoot":"","sources":["../src/task.ts"],"names":[],"mappings":"AASA,SAAS,KAAK,CAAC,EAAU;IACxB,OAAO,IAAI,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,UAAU,CACzB,MAAqC,EACrC,MAAsB;IAEtB,OAAO;QACN,EAAE,EAAE,MAAM,CAAC,EAAE;QACb,OAAO,EAAE,MAAM;QAEf,KAAK,CAAC,OAAO,CACZ,OAAiB,EACjB,UAA0B,EAAE;YAE5B,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;YAEzE,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;gBACpC,SAAS,EAAE,MAAM,CAAC,EAAE;gBACpB,OAAO,EAAE,SAAS;gBAClB,cAAc,EAAE,OAAO,CAAC,cAAc;gBACtC,OAAO,EAAE,OAAO,CAAC,OAAO;gBACxB,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,WAAW,EAAE,OAAO,CAAC,WAAW;oBAC/B,CAAC,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC;oBAC/B,CAAC,CAAC,SAAS;aACZ,CAAC,CAAC;YAEH,OAAO;gBACN,EAAE,EAAE,GAAG,CAAC,EAAE;gBACV,MAAM,EAAE,GAAG,CAAC,MAAuB;gBACnC,SAAS,EAAE,GAAG,CAAC,SAAS;gBACxB,SAAS,EAAE,GAAG,CAAC,SAAS;aACxB,CAAC;QACH,CAAC;QAED,KAAK,CAAC,cAAc,CACnB,OAAiB,EACjB,UAA0B,EAAE;YAE5B,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAEjD,OAAO,IAAI,EAAE,CAAC;gBACb,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;gBAExD,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;oBAC/D,OAAO;wBACN,EAAE,EAAE,MAAM,CAAC,EAAE;wBACb,MAAM,EAAE,MAAM,CAAC,MAA6B;wBAC5C,MAAM,EAAE,MAAM,CAAC,MAAM;wBACrB,KAAK,EAAE,MAAM,CAAC,KAAK;wBACnB,UAAU,EAAE,MAAM,CAAC,UAAU,IAAI,IAAI;qBACrC,CAAC;gBACH,CAAC;gBAED,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC;YACnB,CAAC;QACF,CAAC;KACD,CAAC;AACH,CAAC"}
@@ -0,0 +1,63 @@
1
+ import type { ZodSchema } from "zod";
2
+ export type RunStatus = "pending" | "running" | "success" | "failed";
3
+ export type Run = {
4
+ id: string;
5
+ status: RunStatus;
6
+ triggerId: string;
7
+ createdAt: string;
8
+ };
9
+ export type RunResult = {
10
+ id: string;
11
+ status: RunStatus;
12
+ result: unknown;
13
+ error: unknown;
14
+ finishedAt: string | null;
15
+ };
16
+ export type TriggerOptions = {
17
+ idempotencyKey?: string;
18
+ webhook?: string;
19
+ tags?: string[];
20
+ priority?: number;
21
+ scheduledAt?: string;
22
+ };
23
+ export type StepHelpers = {
24
+ run: <T>(id: string, fn: () => Promise<T>) => Promise<T>;
25
+ sleep: (id: string, duration: string) => Promise<void>;
26
+ };
27
+ export type RunContext<TPayload = unknown> = {
28
+ payload: TPayload;
29
+ runId: string;
30
+ attempt: number;
31
+ step: StepHelpers;
32
+ };
33
+ export type TaskConfig<TPayload = unknown, TResult = unknown> = {
34
+ id: string;
35
+ schema?: ZodSchema<TPayload>;
36
+ cron?: string | {
37
+ pattern: string;
38
+ timezone?: string;
39
+ };
40
+ queue?: {
41
+ name: string;
42
+ concurrencyLimit?: number;
43
+ rateLimit?: {
44
+ max: number;
45
+ duration: string;
46
+ };
47
+ };
48
+ retry?: {
49
+ maxAttempts: number;
50
+ backoff?: "exponential" | "linear" | "fixed";
51
+ minTimeoutInMs?: number;
52
+ maxTimeoutInMs?: number;
53
+ };
54
+ timeout?: number;
55
+ run: (context: RunContext<TPayload>) => Promise<TResult>;
56
+ };
57
+ export type Task<TPayload = unknown, TResult = unknown> = {
58
+ id: string;
59
+ _config: TaskConfig<TPayload, TResult>;
60
+ trigger: (payload: TPayload, options?: TriggerOptions) => Promise<Run>;
61
+ triggerAndWait: (payload: TPayload, options?: TriggerOptions) => Promise<RunResult>;
62
+ };
63
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json CHANGED
@@ -1,12 +1,35 @@
1
1
  {
2
- "name": "steppler",
3
- "version": "0.0.1",
4
- "description": "Reserved package name",
5
- "main": "index.js",
6
- "keywords": [
7
- "placeholder",
8
- "reserved"
9
- ],
10
- "author": "tminusdev",
11
- "license": "MIT"
12
- }
2
+ "name": "steppler",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "import": "./dist/index.js",
10
+ "types": "./dist/index.d.ts"
11
+ },
12
+ "./next": {
13
+ "import": "./dist/adapters/next.js",
14
+ "types": "./dist/adapters/next.d.ts"
15
+ },
16
+ "./handler": {
17
+ "import": "./dist/adapters/generic.js",
18
+ "types": "./dist/adapters/generic.d.ts"
19
+ }
20
+ },
21
+ "files": [
22
+ "dist"
23
+ ],
24
+ "scripts": {
25
+ "build": "tsc",
26
+ "dev": "tsc --watch"
27
+ },
28
+ "dependencies": {
29
+ "@steppler/api": "latest"
30
+ },
31
+ "devDependencies": {
32
+ "typescript": "^5.0.0",
33
+ "@types/node": "^22.0.0"
34
+ }
35
+ }
package/index.js DELETED
@@ -1,3 +0,0 @@
1
- export default function() {
2
- console.log('This package is reserved');
3
- }