@hotmeshio/hotmesh 0.10.2 → 0.12.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 +1 -1
- package/build/modules/enums.d.ts +1 -0
- package/build/modules/enums.js +3 -1
- package/build/modules/errors.d.ts +2 -0
- package/build/modules/errors.js +2 -0
- package/build/modules/key.js +3 -2
- package/build/package.json +2 -2
- package/build/services/activities/worker.js +10 -0
- package/build/services/dba/index.d.ts +2 -1
- package/build/services/dba/index.js +11 -2
- package/build/services/durable/client.js +6 -1
- package/build/services/durable/exporter.d.ts +15 -0
- package/build/services/durable/exporter.js +384 -5
- package/build/services/durable/schemas/factory.d.ts +1 -1
- package/build/services/durable/schemas/factory.js +27 -4
- package/build/services/durable/worker.d.ts +2 -2
- package/build/services/durable/worker.js +15 -9
- package/build/services/durable/workflow/context.js +2 -0
- package/build/services/durable/workflow/execChild.js +5 -2
- package/build/services/durable/workflow/hook.js +6 -0
- package/build/services/durable/workflow/proxyActivities.js +3 -4
- package/build/services/engine/index.d.ts +2 -2
- package/build/services/engine/index.js +10 -5
- package/build/services/exporter/index.d.ts +16 -2
- package/build/services/exporter/index.js +76 -0
- package/build/services/hotmesh/index.d.ts +2 -2
- package/build/services/hotmesh/index.js +2 -2
- package/build/services/router/config/index.d.ts +2 -2
- package/build/services/router/config/index.js +2 -1
- package/build/services/router/consumption/index.js +80 -5
- package/build/services/store/index.d.ts +52 -0
- package/build/services/store/providers/postgres/exporter-sql.d.ts +40 -0
- package/build/services/store/providers/postgres/exporter-sql.js +92 -0
- package/build/services/store/providers/postgres/kvtables.js +6 -0
- package/build/services/store/providers/postgres/postgres.d.ts +42 -0
- package/build/services/store/providers/postgres/postgres.js +151 -0
- package/build/services/stream/index.d.ts +1 -0
- package/build/services/stream/providers/postgres/kvtables.d.ts +1 -1
- package/build/services/stream/providers/postgres/kvtables.js +235 -82
- package/build/services/stream/providers/postgres/lifecycle.d.ts +4 -3
- package/build/services/stream/providers/postgres/lifecycle.js +6 -5
- package/build/services/stream/providers/postgres/messages.d.ts +14 -6
- package/build/services/stream/providers/postgres/messages.js +153 -76
- package/build/services/stream/providers/postgres/notifications.d.ts +5 -2
- package/build/services/stream/providers/postgres/notifications.js +39 -35
- package/build/services/stream/providers/postgres/postgres.d.ts +21 -118
- package/build/services/stream/providers/postgres/postgres.js +87 -140
- package/build/services/stream/providers/postgres/scout.js +2 -2
- package/build/services/stream/providers/postgres/stats.js +3 -2
- package/build/services/stream/registry.d.ts +62 -0
- package/build/services/stream/registry.js +198 -0
- package/build/services/worker/index.js +20 -6
- package/build/types/durable.d.ts +6 -1
- package/build/types/error.d.ts +2 -0
- package/build/types/exporter.d.ts +84 -0
- package/build/types/hotmesh.d.ts +7 -1
- package/build/types/index.d.ts +1 -1
- package/build/types/stream.d.ts +2 -0
- package/package.json +2 -2
|
@@ -91,5 +91,57 @@ declare abstract class StoreService<Provider extends ProviderClient, Transaction
|
|
|
91
91
|
abstract setThrottleRate(options: ThrottleOptions): Promise<void>;
|
|
92
92
|
abstract getThrottleRates(): Promise<StringStringType>;
|
|
93
93
|
abstract getThrottleRate(topic: string): Promise<number>;
|
|
94
|
+
/**
|
|
95
|
+
* Fetch activity inputs for a workflow. Used by the exporter to enrich
|
|
96
|
+
* timeline events with activity arguments.
|
|
97
|
+
*
|
|
98
|
+
* @param workflowId - The workflow ID
|
|
99
|
+
* @param symbolField - The compressed symbol field for activity arguments
|
|
100
|
+
* @returns Map of job_id -> parsed input arguments and activityName:index -> parsed inputs
|
|
101
|
+
*/
|
|
102
|
+
getActivityInputs?(workflowId: string, symbolField: string): Promise<{
|
|
103
|
+
byJobId: Map<string, any>;
|
|
104
|
+
byNameIndex: Map<string, any>;
|
|
105
|
+
}>;
|
|
106
|
+
/**
|
|
107
|
+
* Fetch child workflow inputs in batch. Used by the exporter to enrich
|
|
108
|
+
* child workflow events with their arguments.
|
|
109
|
+
*
|
|
110
|
+
* @param childJobKeys - Array of child job keys to fetch
|
|
111
|
+
* @param symbolField - The compressed symbol field for workflow arguments
|
|
112
|
+
* @returns Map of child_workflow_id -> parsed input arguments
|
|
113
|
+
*/
|
|
114
|
+
getChildWorkflowInputs?(childJobKeys: string[], symbolField: string): Promise<Map<string, any>>;
|
|
115
|
+
/**
|
|
116
|
+
* Fetch stream message history for a job from worker_streams.
|
|
117
|
+
* Returns raw activity input/output data from soft-deleted messages.
|
|
118
|
+
*
|
|
119
|
+
* @param jobId - The job ID (metadata.jid in stream messages)
|
|
120
|
+
* @param options - Optional filters for activity or message types
|
|
121
|
+
* @returns Array of stream history entries ordered by creation time
|
|
122
|
+
*/
|
|
123
|
+
getStreamHistory?(jobId: string, options?: {
|
|
124
|
+
activity?: string;
|
|
125
|
+
types?: string[];
|
|
126
|
+
}): Promise<import('../../types/exporter').StreamHistoryEntry[]>;
|
|
127
|
+
/**
|
|
128
|
+
* Fetch job record and attributes by key. Used by the exporter to
|
|
129
|
+
* reconstruct execution history for expired jobs.
|
|
130
|
+
*
|
|
131
|
+
* @param jobKey - The job key (e.g., "hmsh:durable:j:workflowId")
|
|
132
|
+
* @returns Job row and all attributes
|
|
133
|
+
*/
|
|
134
|
+
getJobByKeyDirect?(jobKey: string): Promise<{
|
|
135
|
+
job: {
|
|
136
|
+
id: string;
|
|
137
|
+
key: string;
|
|
138
|
+
status: number;
|
|
139
|
+
created_at: Date;
|
|
140
|
+
updated_at: Date;
|
|
141
|
+
expired_at?: Date;
|
|
142
|
+
is_live: boolean;
|
|
143
|
+
};
|
|
144
|
+
attributes: Record<string, string>;
|
|
145
|
+
}>;
|
|
94
146
|
}
|
|
95
147
|
export { StoreService };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQL queries for exporter enrichment (Postgres provider).
|
|
3
|
+
* These queries support the exporter's input enrichment and direct query features.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Fetch job record by key.
|
|
7
|
+
*/
|
|
8
|
+
export declare const GET_JOB_BY_KEY = "\n SELECT id, key, status, created_at, updated_at, expired_at, is_live\n FROM {schema}.jobs\n WHERE key = $1\n LIMIT 1\n";
|
|
9
|
+
/**
|
|
10
|
+
* Fetch all attributes for a job.
|
|
11
|
+
*/
|
|
12
|
+
export declare const GET_JOB_ATTRIBUTES = "\n SELECT field, value\n FROM {schema}.jobs_attributes\n WHERE job_id = $1\n ORDER BY field\n";
|
|
13
|
+
/**
|
|
14
|
+
* Fetch activity inputs for a workflow.
|
|
15
|
+
* Matches all activity jobs for the given workflow and extracts their input arguments.
|
|
16
|
+
*/
|
|
17
|
+
export declare const GET_ACTIVITY_INPUTS = "\n SELECT j.key, ja.value\n FROM {schema}.jobs j\n JOIN {schema}.jobs_attributes ja ON ja.job_id = j.id\n WHERE j.key LIKE $1\n AND ja.field = $2\n";
|
|
18
|
+
/**
|
|
19
|
+
* Fetch all worker stream messages for a job AND its child activities.
|
|
20
|
+
* Child activity jobs use the pattern: -{parentJobId}-$activityName-N
|
|
21
|
+
* Uses the partial index on (jid, created_at) WHERE jid != '' for efficiency.
|
|
22
|
+
* Includes both active and expired messages for full execution history.
|
|
23
|
+
*/
|
|
24
|
+
export declare const GET_STREAM_HISTORY_BY_JID = "\n SELECT\n id, jid, aid, dad, msg_type, topic, workflow_name,\n message, created_at, expired_at\n FROM {schema}.worker_streams\n WHERE jid = $1 OR jid LIKE '-' || $1 || '-%'\n ORDER BY created_at, id\n";
|
|
25
|
+
/**
|
|
26
|
+
* Fetch worker stream messages for a job filtered by message type.
|
|
27
|
+
* Includes child activity messages.
|
|
28
|
+
*/
|
|
29
|
+
export declare const GET_STREAM_HISTORY_BY_JID_AND_TYPE = "\n SELECT\n id, jid, aid, dad, msg_type, topic, workflow_name,\n message, created_at, expired_at\n FROM {schema}.worker_streams\n WHERE (jid = $1 OR jid LIKE '-' || $1 || '-%')\n AND msg_type = ANY($2::text[])\n ORDER BY created_at, id\n";
|
|
30
|
+
/**
|
|
31
|
+
* Fetch worker stream messages for a job filtered by activity ID.
|
|
32
|
+
* Includes child activity messages.
|
|
33
|
+
*/
|
|
34
|
+
export declare const GET_STREAM_HISTORY_BY_JID_AND_AID = "\n SELECT\n id, jid, aid, dad, msg_type, topic, workflow_name,\n message, created_at, expired_at\n FROM {schema}.worker_streams\n WHERE (jid = $1 OR jid LIKE '-' || $1 || '-%')\n AND aid = $2\n ORDER BY created_at, id\n";
|
|
35
|
+
/**
|
|
36
|
+
* Fetch child workflow inputs in batch.
|
|
37
|
+
* Uses parameterized IN clause for exact-match efficiency.
|
|
38
|
+
* Note: This query template must be built dynamically with the correct number of placeholders.
|
|
39
|
+
*/
|
|
40
|
+
export declare function buildChildWorkflowInputsQuery(childCount: number, schema: string): string;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* SQL queries for exporter enrichment (Postgres provider).
|
|
4
|
+
* These queries support the exporter's input enrichment and direct query features.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.buildChildWorkflowInputsQuery = exports.GET_STREAM_HISTORY_BY_JID_AND_AID = exports.GET_STREAM_HISTORY_BY_JID_AND_TYPE = exports.GET_STREAM_HISTORY_BY_JID = exports.GET_ACTIVITY_INPUTS = exports.GET_JOB_ATTRIBUTES = exports.GET_JOB_BY_KEY = void 0;
|
|
8
|
+
/**
|
|
9
|
+
* Fetch job record by key.
|
|
10
|
+
*/
|
|
11
|
+
exports.GET_JOB_BY_KEY = `
|
|
12
|
+
SELECT id, key, status, created_at, updated_at, expired_at, is_live
|
|
13
|
+
FROM {schema}.jobs
|
|
14
|
+
WHERE key = $1
|
|
15
|
+
LIMIT 1
|
|
16
|
+
`;
|
|
17
|
+
/**
|
|
18
|
+
* Fetch all attributes for a job.
|
|
19
|
+
*/
|
|
20
|
+
exports.GET_JOB_ATTRIBUTES = `
|
|
21
|
+
SELECT field, value
|
|
22
|
+
FROM {schema}.jobs_attributes
|
|
23
|
+
WHERE job_id = $1
|
|
24
|
+
ORDER BY field
|
|
25
|
+
`;
|
|
26
|
+
/**
|
|
27
|
+
* Fetch activity inputs for a workflow.
|
|
28
|
+
* Matches all activity jobs for the given workflow and extracts their input arguments.
|
|
29
|
+
*/
|
|
30
|
+
exports.GET_ACTIVITY_INPUTS = `
|
|
31
|
+
SELECT j.key, ja.value
|
|
32
|
+
FROM {schema}.jobs j
|
|
33
|
+
JOIN {schema}.jobs_attributes ja ON ja.job_id = j.id
|
|
34
|
+
WHERE j.key LIKE $1
|
|
35
|
+
AND ja.field = $2
|
|
36
|
+
`;
|
|
37
|
+
/**
|
|
38
|
+
* Fetch all worker stream messages for a job AND its child activities.
|
|
39
|
+
* Child activity jobs use the pattern: -{parentJobId}-$activityName-N
|
|
40
|
+
* Uses the partial index on (jid, created_at) WHERE jid != '' for efficiency.
|
|
41
|
+
* Includes both active and expired messages for full execution history.
|
|
42
|
+
*/
|
|
43
|
+
exports.GET_STREAM_HISTORY_BY_JID = `
|
|
44
|
+
SELECT
|
|
45
|
+
id, jid, aid, dad, msg_type, topic, workflow_name,
|
|
46
|
+
message, created_at, expired_at
|
|
47
|
+
FROM {schema}.worker_streams
|
|
48
|
+
WHERE jid = $1 OR jid LIKE '-' || $1 || '-%'
|
|
49
|
+
ORDER BY created_at, id
|
|
50
|
+
`;
|
|
51
|
+
/**
|
|
52
|
+
* Fetch worker stream messages for a job filtered by message type.
|
|
53
|
+
* Includes child activity messages.
|
|
54
|
+
*/
|
|
55
|
+
exports.GET_STREAM_HISTORY_BY_JID_AND_TYPE = `
|
|
56
|
+
SELECT
|
|
57
|
+
id, jid, aid, dad, msg_type, topic, workflow_name,
|
|
58
|
+
message, created_at, expired_at
|
|
59
|
+
FROM {schema}.worker_streams
|
|
60
|
+
WHERE (jid = $1 OR jid LIKE '-' || $1 || '-%')
|
|
61
|
+
AND msg_type = ANY($2::text[])
|
|
62
|
+
ORDER BY created_at, id
|
|
63
|
+
`;
|
|
64
|
+
/**
|
|
65
|
+
* Fetch worker stream messages for a job filtered by activity ID.
|
|
66
|
+
* Includes child activity messages.
|
|
67
|
+
*/
|
|
68
|
+
exports.GET_STREAM_HISTORY_BY_JID_AND_AID = `
|
|
69
|
+
SELECT
|
|
70
|
+
id, jid, aid, dad, msg_type, topic, workflow_name,
|
|
71
|
+
message, created_at, expired_at
|
|
72
|
+
FROM {schema}.worker_streams
|
|
73
|
+
WHERE (jid = $1 OR jid LIKE '-' || $1 || '-%')
|
|
74
|
+
AND aid = $2
|
|
75
|
+
ORDER BY created_at, id
|
|
76
|
+
`;
|
|
77
|
+
/**
|
|
78
|
+
* Fetch child workflow inputs in batch.
|
|
79
|
+
* Uses parameterized IN clause for exact-match efficiency.
|
|
80
|
+
* Note: This query template must be built dynamically with the correct number of placeholders.
|
|
81
|
+
*/
|
|
82
|
+
function buildChildWorkflowInputsQuery(childCount, schema) {
|
|
83
|
+
const placeholders = Array.from({ length: childCount }, (_, i) => `$${i + 1}`).join(',');
|
|
84
|
+
return `
|
|
85
|
+
SELECT j.key, ja.value
|
|
86
|
+
FROM ${schema}.jobs j
|
|
87
|
+
JOIN ${schema}.jobs_attributes ja ON ja.job_id = j.id
|
|
88
|
+
WHERE j.key IN (${placeholders})
|
|
89
|
+
AND ja.field = $${childCount + 1}
|
|
90
|
+
`;
|
|
91
|
+
}
|
|
92
|
+
exports.buildChildWorkflowInputsQuery = buildChildWorkflowInputsQuery;
|
|
@@ -221,6 +221,12 @@ const KVTables = (context) => ({
|
|
|
221
221
|
await client.query(`
|
|
222
222
|
CREATE INDEX IF NOT EXISTS idx_${tableDef.name}_pruned_at
|
|
223
223
|
ON ${fullTableName} (pruned_at) WHERE pruned_at IS NULL;
|
|
224
|
+
`);
|
|
225
|
+
// Index for paginated entity listing with sort (dashboard entity queries)
|
|
226
|
+
await client.query(`
|
|
227
|
+
CREATE INDEX IF NOT EXISTS idx_${tableDef.name}_entity_created
|
|
228
|
+
ON ${fullTableName} (entity, created_at DESC)
|
|
229
|
+
WHERE entity IS NOT NULL;
|
|
224
230
|
`);
|
|
225
231
|
// Create function to update is_live flag in the schema
|
|
226
232
|
await client.query(`
|
|
@@ -194,5 +194,47 @@ declare class PostgresStoreService extends StoreService<ProviderClient, Provider
|
|
|
194
194
|
* Enhanced shouldScout that can handle notifications
|
|
195
195
|
*/
|
|
196
196
|
shouldScout(): Promise<boolean>;
|
|
197
|
+
/**
|
|
198
|
+
* Fetch activity inputs for a workflow. Used by the exporter to enrich
|
|
199
|
+
* timeline events with activity arguments.
|
|
200
|
+
*/
|
|
201
|
+
getActivityInputs(workflowId: string, symbolField: string): Promise<{
|
|
202
|
+
byJobId: Map<string, any>;
|
|
203
|
+
byNameIndex: Map<string, any>;
|
|
204
|
+
}>;
|
|
205
|
+
/**
|
|
206
|
+
* Fetch child workflow inputs in batch. Used by the exporter to enrich
|
|
207
|
+
* child workflow events with their arguments.
|
|
208
|
+
*/
|
|
209
|
+
getChildWorkflowInputs(childJobKeys: string[], symbolField: string): Promise<Map<string, any>>;
|
|
210
|
+
/**
|
|
211
|
+
* Fetch job record and attributes by key. Used by the exporter to
|
|
212
|
+
* reconstruct execution history for expired jobs.
|
|
213
|
+
*/
|
|
214
|
+
getJobByKeyDirect(jobKey: string): Promise<{
|
|
215
|
+
job: {
|
|
216
|
+
id: string;
|
|
217
|
+
key: string;
|
|
218
|
+
status: number;
|
|
219
|
+
created_at: Date;
|
|
220
|
+
updated_at: Date;
|
|
221
|
+
expired_at?: Date;
|
|
222
|
+
is_live: boolean;
|
|
223
|
+
};
|
|
224
|
+
attributes: Record<string, string>;
|
|
225
|
+
}>;
|
|
226
|
+
/**
|
|
227
|
+
* Fetch stream message history for a job from worker_streams.
|
|
228
|
+
* Returns raw activity input/output data from soft-deleted messages.
|
|
229
|
+
*/
|
|
230
|
+
getStreamHistory(jobId: string, options?: {
|
|
231
|
+
activity?: string;
|
|
232
|
+
types?: string[];
|
|
233
|
+
}): Promise<import('../../../../types/exporter').StreamHistoryEntry[]>;
|
|
234
|
+
/**
|
|
235
|
+
* Parse a HotMesh-encoded value string.
|
|
236
|
+
* Values may be prefixed with `/s` (JSON), `/d` (number), `/t` or `/f` (boolean), `/n` (null).
|
|
237
|
+
*/
|
|
238
|
+
private parseHmshValue;
|
|
197
239
|
}
|
|
198
240
|
export { PostgresStoreService };
|
|
@@ -1284,5 +1284,156 @@ class PostgresStoreService extends __1.StoreService {
|
|
|
1284
1284
|
}
|
|
1285
1285
|
return false;
|
|
1286
1286
|
}
|
|
1287
|
+
// ── Exporter queries ───────────────────────────────────────────────────────
|
|
1288
|
+
/**
|
|
1289
|
+
* Fetch activity inputs for a workflow. Used by the exporter to enrich
|
|
1290
|
+
* timeline events with activity arguments.
|
|
1291
|
+
*/
|
|
1292
|
+
async getActivityInputs(workflowId, symbolField) {
|
|
1293
|
+
const { GET_ACTIVITY_INPUTS } = await Promise.resolve().then(() => __importStar(require('./exporter-sql')));
|
|
1294
|
+
const schemaName = this.kvsql().safeName(this.appId);
|
|
1295
|
+
const sql = GET_ACTIVITY_INPUTS.replace(/{schema}/g, schemaName);
|
|
1296
|
+
const jobKeyPattern = `hmsh:${this.appId}:j:-${workflowId}-%`;
|
|
1297
|
+
const result = await this.pgClient.query(sql, [jobKeyPattern, symbolField]);
|
|
1298
|
+
const byJobId = new Map();
|
|
1299
|
+
const byNameIndex = new Map();
|
|
1300
|
+
for (const row of result.rows) {
|
|
1301
|
+
const jobKey = row.key;
|
|
1302
|
+
const jobId = jobKey.replace(`hmsh:${this.appId}:j:`, '');
|
|
1303
|
+
try {
|
|
1304
|
+
const parsed = this.parseHmshValue(row.value);
|
|
1305
|
+
byJobId.set(jobId, parsed);
|
|
1306
|
+
// Extract activityName and executionIndex from job_id
|
|
1307
|
+
// Format: -workflowId-$activityName-executionIndex
|
|
1308
|
+
const match = jobId.match(/\$([^-]+)-(\d+)$/);
|
|
1309
|
+
if (match) {
|
|
1310
|
+
const activityName = match[1];
|
|
1311
|
+
const executionIndex = match[2];
|
|
1312
|
+
byNameIndex.set(`${activityName}:${executionIndex}`, parsed);
|
|
1313
|
+
}
|
|
1314
|
+
}
|
|
1315
|
+
catch {
|
|
1316
|
+
// Skip unparseable values
|
|
1317
|
+
}
|
|
1318
|
+
}
|
|
1319
|
+
return { byJobId, byNameIndex };
|
|
1320
|
+
}
|
|
1321
|
+
/**
|
|
1322
|
+
* Fetch child workflow inputs in batch. Used by the exporter to enrich
|
|
1323
|
+
* child workflow events with their arguments.
|
|
1324
|
+
*/
|
|
1325
|
+
async getChildWorkflowInputs(childJobKeys, symbolField) {
|
|
1326
|
+
if (childJobKeys.length === 0) {
|
|
1327
|
+
return new Map();
|
|
1328
|
+
}
|
|
1329
|
+
const { buildChildWorkflowInputsQuery } = await Promise.resolve().then(() => __importStar(require('./exporter-sql')));
|
|
1330
|
+
const schemaName = this.kvsql().safeName(this.appId);
|
|
1331
|
+
const sql = buildChildWorkflowInputsQuery(childJobKeys.length, schemaName);
|
|
1332
|
+
const result = await this.pgClient.query(sql, [...childJobKeys, symbolField]);
|
|
1333
|
+
const childInputMap = new Map();
|
|
1334
|
+
for (const row of result.rows) {
|
|
1335
|
+
const jobKey = row.key;
|
|
1336
|
+
const childId = jobKey.replace(`hmsh:${this.appId}:j:`, '');
|
|
1337
|
+
try {
|
|
1338
|
+
const parsed = this.parseHmshValue(row.value);
|
|
1339
|
+
childInputMap.set(childId, parsed);
|
|
1340
|
+
}
|
|
1341
|
+
catch {
|
|
1342
|
+
// Skip unparseable values
|
|
1343
|
+
}
|
|
1344
|
+
}
|
|
1345
|
+
return childInputMap;
|
|
1346
|
+
}
|
|
1347
|
+
/**
|
|
1348
|
+
* Fetch job record and attributes by key. Used by the exporter to
|
|
1349
|
+
* reconstruct execution history for expired jobs.
|
|
1350
|
+
*/
|
|
1351
|
+
async getJobByKeyDirect(jobKey) {
|
|
1352
|
+
const { GET_JOB_BY_KEY, GET_JOB_ATTRIBUTES } = await Promise.resolve().then(() => __importStar(require('./exporter-sql')));
|
|
1353
|
+
const schemaName = this.kvsql().safeName(this.appId);
|
|
1354
|
+
const jobSql = GET_JOB_BY_KEY.replace(/{schema}/g, schemaName);
|
|
1355
|
+
const jobResult = await this.pgClient.query(jobSql, [jobKey]);
|
|
1356
|
+
if (jobResult.rows.length === 0) {
|
|
1357
|
+
throw new Error(`No job found for key "${jobKey}"`);
|
|
1358
|
+
}
|
|
1359
|
+
const job = jobResult.rows[0];
|
|
1360
|
+
const attrSql = GET_JOB_ATTRIBUTES.replace(/{schema}/g, schemaName);
|
|
1361
|
+
const attrResult = await this.pgClient.query(attrSql, [job.id]);
|
|
1362
|
+
const attributes = {};
|
|
1363
|
+
for (const row of attrResult.rows) {
|
|
1364
|
+
attributes[row.field] = row.value;
|
|
1365
|
+
}
|
|
1366
|
+
return { job, attributes };
|
|
1367
|
+
}
|
|
1368
|
+
/**
|
|
1369
|
+
* Fetch stream message history for a job from worker_streams.
|
|
1370
|
+
* Returns raw activity input/output data from soft-deleted messages.
|
|
1371
|
+
*/
|
|
1372
|
+
async getStreamHistory(jobId, options) {
|
|
1373
|
+
const { GET_STREAM_HISTORY_BY_JID, GET_STREAM_HISTORY_BY_JID_AND_TYPE, GET_STREAM_HISTORY_BY_JID_AND_AID, } = await Promise.resolve().then(() => __importStar(require('./exporter-sql')));
|
|
1374
|
+
const schemaName = this.kvsql().safeName(this.appId);
|
|
1375
|
+
let sql;
|
|
1376
|
+
let params;
|
|
1377
|
+
if (options?.activity) {
|
|
1378
|
+
sql = GET_STREAM_HISTORY_BY_JID_AND_AID.replace(/{schema}/g, schemaName);
|
|
1379
|
+
params = [jobId, options.activity];
|
|
1380
|
+
}
|
|
1381
|
+
else if (options?.types?.length) {
|
|
1382
|
+
sql = GET_STREAM_HISTORY_BY_JID_AND_TYPE.replace(/{schema}/g, schemaName);
|
|
1383
|
+
params = [jobId, options.types];
|
|
1384
|
+
}
|
|
1385
|
+
else {
|
|
1386
|
+
sql = GET_STREAM_HISTORY_BY_JID.replace(/{schema}/g, schemaName);
|
|
1387
|
+
params = [jobId];
|
|
1388
|
+
}
|
|
1389
|
+
const result = await this.pgClient.query(sql, params);
|
|
1390
|
+
return result.rows.map((row) => {
|
|
1391
|
+
let parsed = {};
|
|
1392
|
+
try {
|
|
1393
|
+
parsed = JSON.parse(row.message);
|
|
1394
|
+
}
|
|
1395
|
+
catch {
|
|
1396
|
+
// message may not be valid JSON
|
|
1397
|
+
}
|
|
1398
|
+
return {
|
|
1399
|
+
id: parseInt(row.id),
|
|
1400
|
+
jid: row.jid,
|
|
1401
|
+
aid: row.aid,
|
|
1402
|
+
dad: row.dad,
|
|
1403
|
+
msg_type: row.msg_type,
|
|
1404
|
+
topic: row.topic,
|
|
1405
|
+
workflow_name: row.workflow_name,
|
|
1406
|
+
data: parsed.data || {},
|
|
1407
|
+
status: parsed.status,
|
|
1408
|
+
code: parsed.code,
|
|
1409
|
+
created_at: row.created_at instanceof Date
|
|
1410
|
+
? row.created_at.toISOString()
|
|
1411
|
+
: String(row.created_at),
|
|
1412
|
+
expired_at: row.expired_at
|
|
1413
|
+
? (row.expired_at instanceof Date
|
|
1414
|
+
? row.expired_at.toISOString()
|
|
1415
|
+
: String(row.expired_at))
|
|
1416
|
+
: undefined,
|
|
1417
|
+
};
|
|
1418
|
+
});
|
|
1419
|
+
}
|
|
1420
|
+
/**
|
|
1421
|
+
* Parse a HotMesh-encoded value string.
|
|
1422
|
+
* Values may be prefixed with `/s` (JSON), `/d` (number), `/t` or `/f` (boolean), `/n` (null).
|
|
1423
|
+
*/
|
|
1424
|
+
parseHmshValue(raw) {
|
|
1425
|
+
if (typeof raw !== 'string')
|
|
1426
|
+
return undefined;
|
|
1427
|
+
const prefix = raw.slice(0, 2);
|
|
1428
|
+
const rest = raw.slice(2);
|
|
1429
|
+
switch (prefix) {
|
|
1430
|
+
case '/t': return true;
|
|
1431
|
+
case '/f': return false;
|
|
1432
|
+
case '/d': return Number(rest);
|
|
1433
|
+
case '/n': return null;
|
|
1434
|
+
case '/s': return JSON.parse(rest);
|
|
1435
|
+
default: return raw;
|
|
1436
|
+
}
|
|
1437
|
+
}
|
|
1287
1438
|
}
|
|
1288
1439
|
exports.PostgresStoreService = PostgresStoreService;
|
|
@@ -64,6 +64,7 @@ export declare abstract class StreamService<ClientProvider extends ProviderClien
|
|
|
64
64
|
maxMessageSize: number;
|
|
65
65
|
maxBatchSize: number;
|
|
66
66
|
};
|
|
67
|
+
deadLetterMessages?(streamName: string, groupName: string, messageIds: string[]): Promise<number>;
|
|
67
68
|
stopNotificationConsumer?(streamName: string, groupName: string): Promise<void>;
|
|
68
69
|
cleanup?(): Promise<void>;
|
|
69
70
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { ILogger } from '../../../logger';
|
|
2
2
|
export declare function deploySchema(streamClient: any, appId: string, logger: ILogger): Promise<void>;
|
|
3
|
-
export declare function getNotificationChannelName(streamName: string,
|
|
3
|
+
export declare function getNotificationChannelName(streamName: string, isEngine: boolean): string;
|