@workflow/world-postgres 4.0.1-beta.2 → 4.1.0-beta.10

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 (52) hide show
  1. package/LICENSE.md +201 -21
  2. package/README.md +33 -0
  3. package/bin/setup.js +12 -0
  4. package/dist/boss.d.ts +15 -0
  5. package/dist/boss.d.ts.map +1 -0
  6. package/dist/boss.js +18 -0
  7. package/dist/boss.js.map +1 -0
  8. package/dist/cli.d.ts +3 -0
  9. package/dist/cli.d.ts.map +1 -0
  10. package/dist/cli.js +44 -0
  11. package/dist/cli.js.map +1 -0
  12. package/dist/config.d.ts +6 -0
  13. package/dist/config.d.ts.map +1 -0
  14. package/dist/config.js +2 -0
  15. package/dist/config.js.map +1 -0
  16. package/dist/drizzle/index.d.ts +8 -0
  17. package/dist/drizzle/index.d.ts.map +1 -0
  18. package/dist/drizzle/index.js +7 -0
  19. package/dist/drizzle/index.js.map +1 -0
  20. package/dist/drizzle/schema.d.ts +843 -0
  21. package/dist/drizzle/schema.d.ts.map +1 -0
  22. package/dist/drizzle/schema.js +88 -0
  23. package/dist/drizzle/schema.js.map +1 -0
  24. package/dist/index.d.ts +8 -0
  25. package/dist/index.d.ts.map +1 -0
  26. package/dist/index.js +40 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/queue.d.ts +17 -0
  29. package/dist/queue.d.ts.map +1 -0
  30. package/dist/queue.js +103 -0
  31. package/dist/queue.js.map +1 -0
  32. package/dist/storage.d.ts +7 -0
  33. package/dist/storage.d.ts.map +1 -0
  34. package/dist/storage.js +585 -0
  35. package/dist/storage.js.map +1 -0
  36. package/dist/streamer.d.ts +5 -0
  37. package/dist/streamer.d.ts.map +1 -0
  38. package/dist/streamer.js +157 -0
  39. package/dist/streamer.js.map +1 -0
  40. package/dist/util.d.ts +6 -0
  41. package/dist/util.d.ts.map +1 -0
  42. package/dist/util.js +20 -0
  43. package/dist/util.js.map +1 -0
  44. package/dist/zod.d.ts +3 -0
  45. package/dist/zod.d.ts.map +1 -0
  46. package/dist/zod.js +10 -0
  47. package/dist/zod.js.map +1 -0
  48. package/package.json +32 -17
  49. package/src/drizzle/migrations/0000_cultured_the_anarchist.sql +84 -0
  50. package/src/drizzle/migrations/0001_update_error_schema.sql +7 -0
  51. package/src/drizzle/migrations/meta/0000_snapshot.json +499 -0
  52. package/src/drizzle/migrations/meta/_journal.json +13 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/drizzle/schema.ts"],"names":[],"mappings":"AA0BA,eAAO,MAAM,iBAAiB,iMAG7B,CAAC;AAEF,eAAO,MAAM,UAAU,2KAGtB,CAAC;AAYF;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,GAAG,EAAE,CAAC;AAEtC,eAAO,MAAM,MAAM,oDAAuB,CAAC;AAE3C,eAAO,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuBhB,CAAC;AAEF,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAclB,CAAC;AAEF,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwBjB,CAAC;AAEF,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgBjB,CAAC;AAQF,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAYnB,CAAC"}
@@ -0,0 +1,88 @@
1
+ import { StepStatusSchema, WorkflowRunStatusSchema, } from '@workflow/world';
2
+ import { boolean, customType, index, integer, jsonb, pgEnum, pgSchema, primaryKey, text, timestamp, varchar, } from 'drizzle-orm/pg-core';
3
+ function mustBeMoreThanOne(t) {
4
+ return t;
5
+ }
6
+ export const workflowRunStatus = pgEnum('status', mustBeMoreThanOne(WorkflowRunStatusSchema.options));
7
+ export const stepStatus = pgEnum('step_status', mustBeMoreThanOne(StepStatusSchema.options));
8
+ export const schema = pgSchema('workflow');
9
+ export const runs = schema.table('workflow_runs', {
10
+ runId: varchar('id').primaryKey(),
11
+ output: jsonb('output').$type(),
12
+ deploymentId: varchar('deployment_id').notNull(),
13
+ status: workflowRunStatus('status').notNull(),
14
+ workflowName: varchar('name').notNull(),
15
+ executionContext: jsonb('execution_context').$type(),
16
+ input: jsonb('input').$type().notNull(),
17
+ error: text('error'),
18
+ createdAt: timestamp('created_at').defaultNow().notNull(),
19
+ updatedAt: timestamp('updated_at')
20
+ .defaultNow()
21
+ .$onUpdateFn(() => new Date())
22
+ .notNull(),
23
+ completedAt: timestamp('completed_at'),
24
+ startedAt: timestamp('started_at'),
25
+ }, (tb) => ({
26
+ workflowNameIdx: index().on(tb.workflowName),
27
+ statusIdx: index().on(tb.status),
28
+ }));
29
+ export const events = schema.table('workflow_events', {
30
+ eventId: varchar('id').primaryKey(),
31
+ eventType: varchar('type').$type().notNull(),
32
+ correlationId: varchar('correlation_id'),
33
+ createdAt: timestamp('created_at').defaultNow().notNull(),
34
+ runId: varchar('run_id').notNull(),
35
+ eventData: jsonb('payload'),
36
+ }, (tb) => ({
37
+ runFk: index().on(tb.runId),
38
+ correlationIdFk: index().on(tb.correlationId),
39
+ }));
40
+ export const steps = schema.table('workflow_steps', {
41
+ runId: varchar('run_id').notNull(),
42
+ stepId: varchar('step_id').primaryKey(),
43
+ stepName: varchar('step_name').notNull(),
44
+ status: stepStatus('status').notNull(),
45
+ input: jsonb('input').$type().notNull(),
46
+ output: jsonb('output').$type(),
47
+ error: text('error'),
48
+ attempt: integer('attempt').notNull(),
49
+ startedAt: timestamp('started_at'),
50
+ completedAt: timestamp('completed_at'),
51
+ createdAt: timestamp('created_at').defaultNow().notNull(),
52
+ updatedAt: timestamp('updated_at')
53
+ .defaultNow()
54
+ .$onUpdateFn(() => new Date())
55
+ .notNull(),
56
+ retryAfter: timestamp('retry_after'),
57
+ }, (tb) => ({
58
+ runFk: index().on(tb.runId),
59
+ statusIdx: index().on(tb.status),
60
+ }));
61
+ export const hooks = schema.table('workflow_hooks', {
62
+ runId: varchar('run_id').notNull(),
63
+ hookId: varchar('hook_id').primaryKey(),
64
+ token: varchar('token').notNull(),
65
+ ownerId: varchar('owner_id').notNull(),
66
+ projectId: varchar('project_id').notNull(),
67
+ environment: varchar('environment').notNull(),
68
+ createdAt: timestamp('created_at').defaultNow().notNull(),
69
+ metadata: jsonb('metadata').$type(),
70
+ }, (tb) => ({
71
+ runFk: index().on(tb.runId),
72
+ tokenIdx: index().on(tb.token),
73
+ }));
74
+ const bytea = customType({
75
+ dataType() {
76
+ return 'bytea';
77
+ },
78
+ });
79
+ export const streams = schema.table('workflow_stream_chunks', {
80
+ chunkId: varchar('id').$type().notNull(),
81
+ streamId: varchar('stream_id').notNull(),
82
+ chunkData: bytea('data').notNull(),
83
+ createdAt: timestamp('created_at').defaultNow().notNull(),
84
+ eof: boolean('eof').notNull(),
85
+ }, (tb) => ({
86
+ primaryKey: primaryKey({ columns: [tb.streamId, tb.chunkId] }),
87
+ }));
88
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/drizzle/schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { World } from '@workflow/world';
2
+ import type { PostgresWorldConfig } from './config.js';
3
+ export declare function createWorld(config?: PostgresWorldConfig): World & {
4
+ start(): Promise<void>;
5
+ };
6
+ export type { PostgresWorldConfig } from './config.js';
7
+ export * from './drizzle/schema.js';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAGtD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAoBvD,wBAAgB,WAAW,CACzB,MAAM,GAAE,mBAQP,GACA,KAAK,GAAG;IAAE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAkBpC;AAGD,YAAY,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACvD,cAAc,qBAAqB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,40 @@
1
+ import PgBoss from 'pg-boss';
2
+ import createPostgres from 'postgres';
3
+ import { createClient } from './drizzle/index.js';
4
+ import { createQueue } from './queue.js';
5
+ import { createEventsStorage, createHooksStorage, createRunsStorage, createStepsStorage, } from './storage.js';
6
+ import { createStreamer } from './streamer.js';
7
+ function createStorage(drizzle) {
8
+ return {
9
+ runs: createRunsStorage(drizzle),
10
+ events: createEventsStorage(drizzle),
11
+ hooks: createHooksStorage(drizzle),
12
+ steps: createStepsStorage(drizzle),
13
+ };
14
+ }
15
+ export function createWorld(config = {
16
+ connectionString: process.env.WORKFLOW_POSTGRES_URL ||
17
+ 'postgres://world:world@localhost:5432/world',
18
+ jobPrefix: process.env.WORKFLOW_POSTGRES_JOB_PREFIX,
19
+ queueConcurrency: parseInt(process.env.WORKFLOW_POSTGRES_WORKER_CONCURRENCY || '10', 10) ||
20
+ 10,
21
+ }) {
22
+ const boss = new PgBoss({
23
+ connectionString: config.connectionString,
24
+ });
25
+ const postgres = createPostgres(config.connectionString);
26
+ const drizzle = createClient(postgres);
27
+ const queue = createQueue(boss, config);
28
+ const storage = createStorage(drizzle);
29
+ const streamer = createStreamer(postgres, drizzle);
30
+ return {
31
+ ...storage,
32
+ ...streamer,
33
+ ...queue,
34
+ async start() {
35
+ await queue.start();
36
+ },
37
+ };
38
+ }
39
+ export * from './drizzle/schema.js';
40
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,MAAM,MAAM,SAAS,CAAC;AAC7B,OAAO,cAAc,MAAM,UAAU,CAAC;AAEtC,OAAO,EAAE,YAAY,EAAgB,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/C,SAAS,aAAa,CAAC,OAAgB;IACrC,OAAO;QACL,IAAI,EAAE,iBAAiB,CAAC,OAAO,CAAC;QAChC,MAAM,EAAE,mBAAmB,CAAC,OAAO,CAAC;QACpC,KAAK,EAAE,kBAAkB,CAAC,OAAO,CAAC;QAClC,KAAK,EAAE,kBAAkB,CAAC,OAAO,CAAC;KACnC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,WAAW,CACzB,SAA8B;IAC5B,gBAAgB,EACd,OAAO,CAAC,GAAG,CAAC,qBAAqB;QACjC,6CAA6C;IAC/C,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,4BAA4B;IACnD,gBAAgB,EACd,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,oCAAoC,IAAI,IAAI,EAAE,EAAE,CAAC;QACtE,EAAE;CACL;IAED,MAAM,IAAI,GAAG,IAAI,MAAM,CAAC;QACtB,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;KAC1C,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG,cAAc,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;IACzD,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IACvC,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACxC,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IACvC,MAAM,QAAQ,GAAG,cAAc,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAEnD,OAAO;QACL,GAAG,OAAO;QACV,GAAG,QAAQ;QACX,GAAG,KAAK;QACR,KAAK,CAAC,KAAK;YACT,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC;QACtB,CAAC;KACF,CAAC;AACJ,CAAC;AAID,cAAc,qBAAqB,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { type Queue } from '@workflow/world';
2
+ import type PgBoss from 'pg-boss';
3
+ import type { PostgresWorldConfig } from './config.js';
4
+ /**
5
+ * The Postgres queue works by creating two job types in pg-boss:
6
+ * - `workflow` for workflow jobs
7
+ * - `step` for step jobs
8
+ *
9
+ * When a message is queued, it is sent to pg-boss with the appropriate job type.
10
+ * When a job is processed, it is deserialized and then re-queued into the _embedded world_, showing that
11
+ * we can reuse the embedded world, mix and match worlds to build
12
+ * hybrid architectures, and even migrate between worlds.
13
+ */
14
+ export declare function createQueue(boss: PgBoss, config: PostgresWorldConfig): Queue & {
15
+ start(): Promise<void>;
16
+ };
17
+ //# sourceMappingURL=queue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../src/queue.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,KAAK,EAIX,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,MAAM,MAAM,SAAS,CAAC;AAGlC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEvD;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,mBAAmB,GAC1B,KAAK,GAAG;IAAE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAgGpC"}
package/dist/queue.js ADDED
@@ -0,0 +1,103 @@
1
+ import * as Stream from 'node:stream';
2
+ import { JsonTransport } from '@vercel/queue';
3
+ import { MessageId, QueuePayloadSchema, } from '@workflow/world';
4
+ import { createEmbeddedWorld } from '@workflow/world-local';
5
+ import { monotonicFactory } from 'ulid';
6
+ import { MessageData } from './boss.js';
7
+ /**
8
+ * The Postgres queue works by creating two job types in pg-boss:
9
+ * - `workflow` for workflow jobs
10
+ * - `step` for step jobs
11
+ *
12
+ * When a message is queued, it is sent to pg-boss with the appropriate job type.
13
+ * When a job is processed, it is deserialized and then re-queued into the _embedded world_, showing that
14
+ * we can reuse the embedded world, mix and match worlds to build
15
+ * hybrid architectures, and even migrate between worlds.
16
+ */
17
+ export function createQueue(boss, config) {
18
+ const port = process.env.PORT ? Number(process.env.PORT) : undefined;
19
+ const embeddedWorld = createEmbeddedWorld({ dataDir: undefined, port });
20
+ const transport = new JsonTransport();
21
+ const generateMessageId = monotonicFactory();
22
+ const prefix = config.jobPrefix || 'workflow_';
23
+ const Queues = {
24
+ __wkf_workflow_: `${prefix}flows`,
25
+ __wkf_step_: `${prefix}steps`,
26
+ };
27
+ const createQueueHandler = embeddedWorld.createQueueHandler;
28
+ const getDeploymentId = async () => {
29
+ return 'postgres';
30
+ };
31
+ const createdQueues = new Map();
32
+ function createQueue(name) {
33
+ let createdQueue = createdQueues.get(name);
34
+ if (!createdQueue) {
35
+ createdQueue = boss.createQueue(name);
36
+ createdQueues.set(name, createdQueue);
37
+ }
38
+ return createdQueue;
39
+ }
40
+ const queue = async (queue, message, opts) => {
41
+ await boss.start();
42
+ const [prefix, queueId] = parseQueueName(queue);
43
+ const jobName = Queues[prefix];
44
+ await createQueue(jobName);
45
+ const body = transport.serialize(message);
46
+ const messageId = MessageId.parse(`msg_${generateMessageId()}`);
47
+ await boss.send({
48
+ name: jobName,
49
+ options: {
50
+ singletonKey: opts?.idempotencyKey ?? messageId,
51
+ retryLimit: 3,
52
+ },
53
+ data: MessageData.encode({
54
+ id: queueId,
55
+ data: body,
56
+ attempt: 1,
57
+ messageId,
58
+ idempotencyKey: opts?.idempotencyKey,
59
+ }),
60
+ });
61
+ return { messageId };
62
+ };
63
+ async function setupListener(queue, jobName) {
64
+ await createQueue(jobName);
65
+ await Promise.all(Array.from({ length: config.queueConcurrency || 10 }, async () => {
66
+ await boss.work(jobName, work);
67
+ }));
68
+ async function work([job]) {
69
+ const messageData = MessageData.parse(job.data);
70
+ const bodyStream = Stream.Readable.toWeb(Stream.Readable.from([messageData.data]));
71
+ const body = await transport.deserialize(bodyStream);
72
+ const message = QueuePayloadSchema.parse(body);
73
+ const queueName = `${queue}${messageData.id}`;
74
+ await embeddedWorld.queue(queueName, message, {
75
+ idempotencyKey: messageData.idempotencyKey,
76
+ });
77
+ }
78
+ }
79
+ async function setupListeners() {
80
+ for (const [prefix, jobName] of Object.entries(Queues)) {
81
+ await setupListener(prefix, jobName);
82
+ }
83
+ }
84
+ return {
85
+ createQueueHandler,
86
+ getDeploymentId,
87
+ queue,
88
+ async start() {
89
+ boss = await boss.start();
90
+ await setupListeners();
91
+ },
92
+ };
93
+ }
94
+ const parseQueueName = (name) => {
95
+ const prefixes = ['__wkf_step_', '__wkf_workflow_'];
96
+ for (const prefix of prefixes) {
97
+ if (name.startsWith(prefix)) {
98
+ return [prefix, name.slice(prefix.length)];
99
+ }
100
+ }
101
+ throw new Error(`Invalid queue name: ${name}`);
102
+ };
103
+ //# sourceMappingURL=queue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue.js","sourceRoot":"","sources":["../src/queue.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { Storage } from '@workflow/world';
2
+ import { type Drizzle } from './drizzle/index.js';
3
+ export declare function createRunsStorage(drizzle: Drizzle): Storage['runs'];
4
+ export declare function createEventsStorage(drizzle: Drizzle): Storage['events'];
5
+ export declare function createHooksStorage(drizzle: Drizzle): Storage['hooks'];
6
+ export declare function createStepsStorage(drizzle: Drizzle): Storage['steps'];
7
+ //# sourceMappingURL=storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAQV,OAAO,EAIR,MAAM,iBAAiB,CAAC;AASzB,OAAO,EAAE,KAAK,OAAO,EAAU,MAAM,oBAAoB,CAAC;AA4H1D,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAoMnE;AAMD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CA8FvE;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CA+FrE;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAuHrE"}