@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.
- package/LICENSE.md +201 -21
- package/README.md +33 -0
- package/bin/setup.js +12 -0
- package/dist/boss.d.ts +15 -0
- package/dist/boss.d.ts.map +1 -0
- package/dist/boss.js +18 -0
- package/dist/boss.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +44 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +6 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +2 -0
- package/dist/config.js.map +1 -0
- package/dist/drizzle/index.d.ts +8 -0
- package/dist/drizzle/index.d.ts.map +1 -0
- package/dist/drizzle/index.js +7 -0
- package/dist/drizzle/index.js.map +1 -0
- package/dist/drizzle/schema.d.ts +843 -0
- package/dist/drizzle/schema.d.ts.map +1 -0
- package/dist/drizzle/schema.js +88 -0
- package/dist/drizzle/schema.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +40 -0
- package/dist/index.js.map +1 -0
- package/dist/queue.d.ts +17 -0
- package/dist/queue.d.ts.map +1 -0
- package/dist/queue.js +103 -0
- package/dist/queue.js.map +1 -0
- package/dist/storage.d.ts +7 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +585 -0
- package/dist/storage.js.map +1 -0
- package/dist/streamer.d.ts +5 -0
- package/dist/streamer.d.ts.map +1 -0
- package/dist/streamer.js +157 -0
- package/dist/streamer.js.map +1 -0
- package/dist/util.d.ts +6 -0
- package/dist/util.d.ts.map +1 -0
- package/dist/util.js +20 -0
- package/dist/util.js.map +1 -0
- package/dist/zod.d.ts +3 -0
- package/dist/zod.d.ts.map +1 -0
- package/dist/zod.js +10 -0
- package/dist/zod.js.map +1 -0
- package/package.json +32 -17
- package/src/drizzle/migrations/0000_cultured_the_anarchist.sql +84 -0
- package/src/drizzle/migrations/0001_update_error_schema.sql +7 -0
- package/src/drizzle/migrations/meta/0000_snapshot.json +499 -0
- 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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"}
|
package/dist/index.d.ts
ADDED
|
@@ -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"}
|
package/dist/queue.d.ts
ADDED
|
@@ -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"}
|