@hotmeshio/hotmesh 0.1.15 → 0.1.16
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 +623 -209
- package/build/index.d.ts +14 -3
- package/build/index.js +17 -4
- package/build/modules/enums.d.ts +12 -12
- package/build/modules/enums.js +15 -25
- package/build/modules/errors.d.ts +16 -16
- package/build/modules/errors.js +28 -28
- package/build/modules/key.d.ts +0 -37
- package/build/modules/key.js +4 -45
- package/build/modules/utils.d.ts +7 -15
- package/build/modules/utils.js +21 -44
- package/build/package.json +18 -15
- package/build/services/activities/activity.d.ts +0 -31
- package/build/services/activities/activity.js +1 -50
- package/build/services/activities/await.js +0 -4
- package/build/services/activities/cycle.d.ts +0 -7
- package/build/services/activities/cycle.js +1 -16
- package/build/services/activities/hook.d.ts +0 -6
- package/build/services/activities/hook.js +2 -12
- package/build/services/activities/interrupt.js +0 -8
- package/build/services/activities/signal.d.ts +0 -6
- package/build/services/activities/signal.js +0 -15
- package/build/services/activities/trigger.d.ts +4 -5
- package/build/services/activities/trigger.js +22 -16
- package/build/services/activities/worker.js +0 -4
- package/build/services/collator/index.d.ts +0 -70
- package/build/services/collator/index.js +1 -91
- package/build/services/compiler/deployer.js +6 -38
- package/build/services/compiler/index.d.ts +0 -15
- package/build/services/compiler/index.js +0 -20
- package/build/services/compiler/validator.d.ts +0 -3
- package/build/services/compiler/validator.js +0 -25
- package/build/services/connector/clients/ioredis.js +0 -2
- package/build/services/connector/clients/redis.js +0 -2
- package/build/services/connector/index.js +0 -2
- package/build/services/engine/index.d.ts +1 -10
- package/build/services/engine/index.js +1 -48
- package/build/services/exporter/index.d.ts +0 -27
- package/build/services/exporter/index.js +0 -33
- package/build/services/hotmesh/index.d.ts +8 -4
- package/build/services/hotmesh/index.js +20 -19
- package/build/services/logger/index.js +0 -2
- package/build/services/mapper/index.d.ts +0 -14
- package/build/services/mapper/index.js +0 -14
- package/build/services/meshcall/index.d.ts +21 -0
- package/build/services/meshcall/index.js +202 -0
- package/build/services/meshcall/schemas/factory.d.ts +2 -0
- package/build/services/meshcall/schemas/factory.js +179 -0
- package/build/services/meshdata/index.d.ts +75 -0
- package/build/services/meshdata/index.js +541 -0
- package/build/services/meshflow/client.d.ts +18 -0
- package/build/services/{durable → meshflow}/client.js +9 -40
- package/build/services/{durable → meshflow}/connection.d.ts +2 -1
- package/build/services/{durable → meshflow}/connection.js +1 -0
- package/build/services/meshflow/exporter.d.ts +29 -0
- package/build/services/{durable → meshflow}/exporter.js +0 -29
- package/build/services/meshflow/handle.d.ts +22 -0
- package/build/services/{durable → meshflow}/handle.js +0 -46
- package/build/services/meshflow/index.d.ts +17 -0
- package/build/services/meshflow/index.js +23 -0
- package/build/services/meshflow/schemas/factory.d.ts +4 -0
- package/build/services/{durable → meshflow}/schemas/factory.js +2 -30
- package/build/services/meshflow/search.d.ts +23 -0
- package/build/services/{durable → meshflow}/search.js +0 -99
- package/build/services/{durable → meshflow}/worker.d.ts +3 -2
- package/build/services/{durable → meshflow}/worker.js +23 -39
- package/build/services/meshflow/workflow.d.ts +27 -0
- package/build/services/{durable → meshflow}/workflow.js +27 -169
- package/build/services/pipe/functions/date.d.ts +0 -7
- package/build/services/pipe/functions/date.js +0 -7
- package/build/services/pipe/functions/math.js +0 -2
- package/build/services/pipe/index.d.ts +0 -15
- package/build/services/pipe/index.js +2 -23
- package/build/services/quorum/index.d.ts +1 -7
- package/build/services/quorum/index.js +0 -21
- package/build/services/reporter/index.d.ts +0 -5
- package/build/services/reporter/index.js +0 -9
- package/build/services/router/index.d.ts +0 -9
- package/build/services/router/index.js +2 -30
- package/build/services/serializer/index.js +6 -23
- package/build/services/store/cache.d.ts +0 -19
- package/build/services/store/cache.js +0 -19
- package/build/services/store/clients/ioredis.d.ts +0 -6
- package/build/services/store/clients/ioredis.js +0 -7
- package/build/services/store/clients/redis.d.ts +0 -6
- package/build/services/store/clients/redis.js +0 -6
- package/build/services/store/index.d.ts +0 -55
- package/build/services/store/index.js +14 -87
- package/build/services/stream/clients/ioredis.js +1 -4
- package/build/services/task/index.d.ts +0 -9
- package/build/services/task/index.js +0 -31
- package/build/services/telemetry/index.d.ts +0 -7
- package/build/services/telemetry/index.js +1 -13
- package/build/services/worker/index.d.ts +1 -4
- package/build/services/worker/index.js +0 -6
- package/build/types/activity.d.ts +0 -81
- package/build/types/error.d.ts +5 -5
- package/build/types/exporter.d.ts +1 -14
- package/build/types/hotmesh.d.ts +4 -12
- package/build/types/hotmesh.js +0 -3
- package/build/types/index.d.ts +5 -3
- package/build/types/index.js +1 -1
- package/build/types/job.d.ts +1 -95
- package/build/types/meshcall.d.ts +54 -0
- package/build/types/meshdata.d.ts +59 -0
- package/build/types/meshdata.js +2 -0
- package/build/types/meshflow.d.ts +202 -0
- package/build/types/meshflow.js +2 -0
- package/build/types/pipe.d.ts +0 -65
- package/build/types/quorum.d.ts +0 -12
- package/build/types/redis.d.ts +0 -6
- package/build/types/stream.d.ts +0 -59
- package/build/types/stream.js +0 -4
- package/index.ts +22 -3
- package/package.json +18 -15
- package/typedoc.json +38 -0
- package/types/error.ts +5 -5
- package/types/exporter.ts +1 -1
- package/types/hotmesh.ts +3 -2
- package/types/index.ts +25 -7
- package/types/job.ts +19 -1
- package/types/meshcall.ts +123 -0
- package/types/meshdata.ts +273 -0
- package/types/{durable.ts → meshflow.ts} +33 -9
- package/build/services/durable/client.d.ts +0 -49
- package/build/services/durable/exporter.d.ts +0 -51
- package/build/services/durable/handle.d.ts +0 -58
- package/build/services/durable/index.d.ts +0 -19
- package/build/services/durable/index.js +0 -25
- package/build/services/durable/schemas/factory.d.ts +0 -33
- package/build/services/durable/search.d.ts +0 -120
- package/build/services/durable/workflow.d.ts +0 -143
- package/build/types/durable.d.ts +0 -467
- /package/build/types/{durable.js → meshcall.js} +0 -0
|
@@ -3,42 +3,15 @@ import { StoreService } from '../store';
|
|
|
3
3
|
import { DependencyExport, ExportOptions, JobActionExport, JobExport } from '../../types/exporter';
|
|
4
4
|
import { RedisClient, RedisMulti } from '../../types/redis';
|
|
5
5
|
import { StringStringType, Symbols } from '../../types/serializer';
|
|
6
|
-
/**
|
|
7
|
-
* Downloads job data from Redis (hscan, hmget, hgetall)
|
|
8
|
-
* Expands process data and includes dependency list
|
|
9
|
-
*/
|
|
10
6
|
declare class ExporterService {
|
|
11
7
|
appId: string;
|
|
12
8
|
logger: ILogger;
|
|
13
9
|
store: StoreService<RedisClient, RedisMulti>;
|
|
14
10
|
symbols: Promise<Symbols> | Symbols;
|
|
15
11
|
constructor(appId: string, store: StoreService<RedisClient, RedisMulti>, logger: ILogger);
|
|
16
|
-
/**
|
|
17
|
-
* Convert the job hash and dependency list into a JobExport object.
|
|
18
|
-
* This object contains various facets that describe the interaction
|
|
19
|
-
* in terms relevant to narrative storytelling.
|
|
20
|
-
*/
|
|
21
12
|
export(jobId: string, options?: ExportOptions): Promise<JobExport>;
|
|
22
|
-
/**
|
|
23
|
-
* Inflates the key from Redis, 3-character symbol
|
|
24
|
-
* into a human-readable JSON path, reflecting the
|
|
25
|
-
* tree-like structure of the unidimensional Hash
|
|
26
|
-
*/
|
|
27
13
|
inflateKey(key: string): string;
|
|
28
|
-
/**
|
|
29
|
-
* Inflates the job data from Redis into a JobExport object
|
|
30
|
-
* @param jobHash - the job data from Redis
|
|
31
|
-
* @param dependencyList - the list of dependencies for the job
|
|
32
|
-
* @returns - the inflated job data
|
|
33
|
-
*/
|
|
34
14
|
inflate(jobHash: StringStringType, dependencyList: string[]): JobExport;
|
|
35
|
-
/**
|
|
36
|
-
* Inflates the dependency data from Redis into a JobExport object by
|
|
37
|
-
* organizing the dimensional isolate in sch a way asto interleave
|
|
38
|
-
* into a story
|
|
39
|
-
* @param data - the dependency data from Redis
|
|
40
|
-
* @returns - the organized dependency data
|
|
41
|
-
*/
|
|
42
15
|
inflateDependencyData(data: string[], actions: JobActionExport): DependencyExport[];
|
|
43
16
|
}
|
|
44
17
|
export { ExporterService };
|
|
@@ -4,21 +4,12 @@ exports.ExporterService = void 0;
|
|
|
4
4
|
const key_1 = require("../../modules/key");
|
|
5
5
|
const utils_1 = require("../../modules/utils");
|
|
6
6
|
const serializer_1 = require("../serializer");
|
|
7
|
-
/**
|
|
8
|
-
* Downloads job data from Redis (hscan, hmget, hgetall)
|
|
9
|
-
* Expands process data and includes dependency list
|
|
10
|
-
*/
|
|
11
7
|
class ExporterService {
|
|
12
8
|
constructor(appId, store, logger) {
|
|
13
9
|
this.appId = appId;
|
|
14
10
|
this.logger = logger;
|
|
15
11
|
this.store = store;
|
|
16
12
|
}
|
|
17
|
-
/**
|
|
18
|
-
* Convert the job hash and dependency list into a JobExport object.
|
|
19
|
-
* This object contains various facets that describe the interaction
|
|
20
|
-
* in terms relevant to narrative storytelling.
|
|
21
|
-
*/
|
|
22
13
|
async export(jobId, options = {}) {
|
|
23
14
|
if (!this.symbols) {
|
|
24
15
|
this.symbols = this.store.getAllSymbols();
|
|
@@ -29,22 +20,10 @@ class ExporterService {
|
|
|
29
20
|
const jobExport = this.inflate(jobData, depData);
|
|
30
21
|
return jobExport;
|
|
31
22
|
}
|
|
32
|
-
/**
|
|
33
|
-
* Inflates the key from Redis, 3-character symbol
|
|
34
|
-
* into a human-readable JSON path, reflecting the
|
|
35
|
-
* tree-like structure of the unidimensional Hash
|
|
36
|
-
*/
|
|
37
23
|
inflateKey(key) {
|
|
38
24
|
return key in this.symbols ? this.symbols[key] : key;
|
|
39
25
|
}
|
|
40
|
-
/**
|
|
41
|
-
* Inflates the job data from Redis into a JobExport object
|
|
42
|
-
* @param jobHash - the job data from Redis
|
|
43
|
-
* @param dependencyList - the list of dependencies for the job
|
|
44
|
-
* @returns - the inflated job data
|
|
45
|
-
*/
|
|
46
26
|
inflate(jobHash, dependencyList) {
|
|
47
|
-
//the list of actions taken in the workflow and hook functions
|
|
48
27
|
const actions = {
|
|
49
28
|
hooks: {},
|
|
50
29
|
main: {
|
|
@@ -58,7 +37,6 @@ class ExporterService {
|
|
|
58
37
|
Object.entries(jobHash).forEach(([key, value]) => {
|
|
59
38
|
const match = key.match(regex);
|
|
60
39
|
if (match) {
|
|
61
|
-
//activity process state
|
|
62
40
|
const [_, letters, numbers] = match;
|
|
63
41
|
const path = this.inflateKey(letters);
|
|
64
42
|
const dimensions = `${numbers.replace(/,/g, '/')}`;
|
|
@@ -66,7 +44,6 @@ class ExporterService {
|
|
|
66
44
|
process[`${dimensions}/${path}`] = resolved;
|
|
67
45
|
}
|
|
68
46
|
else if (key.length === 3) {
|
|
69
|
-
//job state
|
|
70
47
|
process[this.inflateKey(key)] = serializer_1.SerializerService.fromString(value);
|
|
71
48
|
}
|
|
72
49
|
});
|
|
@@ -76,13 +53,6 @@ class ExporterService {
|
|
|
76
53
|
status: jobHash[':'],
|
|
77
54
|
};
|
|
78
55
|
}
|
|
79
|
-
/**
|
|
80
|
-
* Inflates the dependency data from Redis into a JobExport object by
|
|
81
|
-
* organizing the dimensional isolate in sch a way asto interleave
|
|
82
|
-
* into a story
|
|
83
|
-
* @param data - the dependency data from Redis
|
|
84
|
-
* @returns - the organized dependency data
|
|
85
|
-
*/
|
|
86
56
|
inflateDependencyData(data, actions) {
|
|
87
57
|
const hookReg = /([0-9,]+)-(\d+)$/;
|
|
88
58
|
const flowReg = /-(\d+)$/;
|
|
@@ -94,7 +64,6 @@ class ExporterService {
|
|
|
94
64
|
let type;
|
|
95
65
|
let dimensionKey = '';
|
|
96
66
|
if (match) {
|
|
97
|
-
//hook-originating dependency
|
|
98
67
|
const [_, dimension, counter] = match;
|
|
99
68
|
dimensionKey = dimension.split(',').join('/');
|
|
100
69
|
prefix = `${dimensionKey}[${counter}]`;
|
|
@@ -103,13 +72,11 @@ class ExporterService {
|
|
|
103
72
|
else {
|
|
104
73
|
const match = jobId.match(flowReg);
|
|
105
74
|
if (match) {
|
|
106
|
-
//main workflow-originating dependency
|
|
107
75
|
const [_, counter] = match;
|
|
108
76
|
prefix = `[${counter}]`;
|
|
109
77
|
type = 'flow';
|
|
110
78
|
}
|
|
111
79
|
else {
|
|
112
|
-
//'other' types like signal cleanup
|
|
113
80
|
prefix = '/';
|
|
114
81
|
type = 'other';
|
|
115
82
|
}
|
|
@@ -5,11 +5,11 @@ import { WorkerService } from '../worker';
|
|
|
5
5
|
import { JobState, JobData, JobOutput, JobStatus, JobInterruptOptions, ExtensionType } from '../../types/job';
|
|
6
6
|
import { HotMeshConfig, HotMeshManifest } from '../../types/hotmesh';
|
|
7
7
|
import { JobExport } from '../../types/exporter';
|
|
8
|
-
import { JobMessageCallback, QuorumProfile, ThrottleOptions } from '../../types/quorum';
|
|
8
|
+
import { JobMessageCallback, QuorumMessage, QuorumMessageCallback, QuorumProfile, ThrottleOptions } from '../../types/quorum';
|
|
9
9
|
import { StringAnyType, StringStringType } from '../../types/serializer';
|
|
10
10
|
import { JobStatsInput, GetStatsOptions, IdsResponse, StatsResponse } from '../../types/stats';
|
|
11
11
|
import { StreamCode, StreamData, StreamDataResponse, StreamStatus } from '../../types/stream';
|
|
12
|
-
declare class
|
|
12
|
+
declare class HotMesh {
|
|
13
13
|
namespace: string;
|
|
14
14
|
appId: string;
|
|
15
15
|
guid: string;
|
|
@@ -20,10 +20,11 @@ declare class HotMeshService {
|
|
|
20
20
|
static disconnecting: boolean;
|
|
21
21
|
verifyAndSetNamespace(namespace?: string): void;
|
|
22
22
|
verifyAndSetAppId(appId: string): void;
|
|
23
|
-
static init(config: HotMeshConfig): Promise<
|
|
23
|
+
static init(config: HotMeshConfig): Promise<HotMesh>;
|
|
24
24
|
static guid(): string;
|
|
25
25
|
initEngine(config: HotMeshConfig, logger: ILogger): Promise<void>;
|
|
26
26
|
initQuorum(config: HotMeshConfig, engine: EngineService, logger: ILogger): Promise<void>;
|
|
27
|
+
constructor();
|
|
27
28
|
doWork(config: HotMeshConfig, logger: ILogger): Promise<void>;
|
|
28
29
|
pub(topic: string, data?: JobData, context?: JobState, extended?: ExtensionType): Promise<string>;
|
|
29
30
|
sub(topic: string, callback: JobMessageCallback): Promise<void>;
|
|
@@ -34,6 +35,9 @@ declare class HotMeshService {
|
|
|
34
35
|
add(streamData: StreamData | StreamDataResponse): Promise<string>;
|
|
35
36
|
rollCall(delay?: number): Promise<QuorumProfile[]>;
|
|
36
37
|
throttle(options: ThrottleOptions): Promise<boolean>;
|
|
38
|
+
pubQuorum(quorumMessage: QuorumMessage): Promise<boolean>;
|
|
39
|
+
subQuorum(callback: QuorumMessageCallback): Promise<void>;
|
|
40
|
+
unsubQuorum(callback: QuorumMessageCallback): Promise<void>;
|
|
37
41
|
plan(path: string): Promise<HotMeshManifest>;
|
|
38
42
|
deploy(pathOrYAML: string): Promise<HotMeshManifest>;
|
|
39
43
|
activate(version: string, delay?: number): Promise<boolean>;
|
|
@@ -53,4 +57,4 @@ declare class HotMeshService {
|
|
|
53
57
|
stop(): void;
|
|
54
58
|
compress(terms: string[]): Promise<boolean>;
|
|
55
59
|
}
|
|
56
|
-
export {
|
|
60
|
+
export { HotMesh };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.HotMesh = void 0;
|
|
4
4
|
const key_1 = require("../../modules/key");
|
|
5
5
|
const utils_1 = require("../../modules/utils");
|
|
6
6
|
const redis_1 = require("../connector/clients/redis");
|
|
@@ -12,12 +12,7 @@ const quorum_1 = require("../quorum");
|
|
|
12
12
|
const router_1 = require("../router");
|
|
13
13
|
const worker_1 = require("../worker");
|
|
14
14
|
const enums_1 = require("../../modules/enums");
|
|
15
|
-
class
|
|
16
|
-
constructor() {
|
|
17
|
-
this.engine = null;
|
|
18
|
-
this.quorum = null;
|
|
19
|
-
this.workers = [];
|
|
20
|
-
}
|
|
15
|
+
class HotMesh {
|
|
21
16
|
verifyAndSetNamespace(namespace) {
|
|
22
17
|
if (!namespace) {
|
|
23
18
|
this.namespace = key_1.HMNS;
|
|
@@ -41,8 +36,8 @@ class HotMeshService {
|
|
|
41
36
|
}
|
|
42
37
|
}
|
|
43
38
|
static async init(config) {
|
|
44
|
-
const instance = new
|
|
45
|
-
instance.guid = (0, utils_1.guid)();
|
|
39
|
+
const instance = new HotMesh();
|
|
40
|
+
instance.guid = config.guid ?? (0, utils_1.guid)();
|
|
46
41
|
instance.verifyAndSetNamespace(config.namespace);
|
|
47
42
|
instance.verifyAndSetAppId(config.appId);
|
|
48
43
|
instance.logger = new logger_1.LoggerService(config.appId, instance.guid, config.name || '', config.logLevel);
|
|
@@ -65,10 +60,14 @@ class HotMeshService {
|
|
|
65
60
|
this.quorum = await quorum_1.QuorumService.init(this.namespace, this.appId, this.guid, config, engine, logger);
|
|
66
61
|
}
|
|
67
62
|
}
|
|
63
|
+
constructor() {
|
|
64
|
+
this.engine = null;
|
|
65
|
+
this.quorum = null;
|
|
66
|
+
this.workers = [];
|
|
67
|
+
}
|
|
68
68
|
async doWork(config, logger) {
|
|
69
69
|
this.workers = await worker_1.WorkerService.init(this.namespace, this.appId, this.guid, config, logger);
|
|
70
70
|
}
|
|
71
|
-
// ************* PUB/SUB METHODS *************
|
|
72
71
|
async pub(topic, data = {}, context, extended) {
|
|
73
72
|
return await this.engine?.pub(topic, data, context, extended);
|
|
74
73
|
}
|
|
@@ -90,7 +89,6 @@ class HotMeshService {
|
|
|
90
89
|
async add(streamData) {
|
|
91
90
|
return (await this.engine.add(streamData));
|
|
92
91
|
}
|
|
93
|
-
// ************* QUORUM METHODS *************
|
|
94
92
|
async rollCall(delay) {
|
|
95
93
|
return await this.quorum?.rollCall(delay);
|
|
96
94
|
}
|
|
@@ -118,7 +116,15 @@ class HotMeshService {
|
|
|
118
116
|
await this.engine.store.setThrottleRate(throttleMessage);
|
|
119
117
|
return await this.quorum?.pub(throttleMessage);
|
|
120
118
|
}
|
|
121
|
-
|
|
119
|
+
async pubQuorum(quorumMessage) {
|
|
120
|
+
return await this.quorum?.pub(quorumMessage);
|
|
121
|
+
}
|
|
122
|
+
async subQuorum(callback) {
|
|
123
|
+
return await this.quorum?.sub(callback);
|
|
124
|
+
}
|
|
125
|
+
async unsubQuorum(callback) {
|
|
126
|
+
return await this.quorum?.unsub(callback);
|
|
127
|
+
}
|
|
122
128
|
async plan(path) {
|
|
123
129
|
return await this.engine?.plan(path);
|
|
124
130
|
}
|
|
@@ -126,10 +132,8 @@ class HotMeshService {
|
|
|
126
132
|
return await this.engine?.deploy(pathOrYAML);
|
|
127
133
|
}
|
|
128
134
|
async activate(version, delay) {
|
|
129
|
-
//activation is a quorum operation
|
|
130
135
|
return await this.quorum?.activate(version, delay);
|
|
131
136
|
}
|
|
132
|
-
// ************* REPORTER METHODS *************
|
|
133
137
|
async export(jobId) {
|
|
134
138
|
return await this.engine?.export(jobId);
|
|
135
139
|
}
|
|
@@ -154,15 +158,12 @@ class HotMeshService {
|
|
|
154
158
|
async resolveQuery(topic, query) {
|
|
155
159
|
return await this.engine?.resolveQuery(topic, query);
|
|
156
160
|
}
|
|
157
|
-
// ****************** `INTERRUPT` ACTIVE JOBS *****************
|
|
158
161
|
async interrupt(topic, jobId, options = {}) {
|
|
159
162
|
return await this.engine?.interrupt(topic, jobId, options);
|
|
160
163
|
}
|
|
161
|
-
// ****************** `SCRUB` CLEAN COMPLETED JOBS *****************
|
|
162
164
|
async scrub(jobId) {
|
|
163
165
|
await this.engine?.scrub(jobId);
|
|
164
166
|
}
|
|
165
|
-
// ****** `HOOK` ACTIVITY RE-ENTRY POINT ******
|
|
166
167
|
async hook(topic, data, status, code) {
|
|
167
168
|
return await this.engine?.hook(topic, data, status, code);
|
|
168
169
|
}
|
|
@@ -188,5 +189,5 @@ class HotMeshService {
|
|
|
188
189
|
return await this.engine?.compress(terms);
|
|
189
190
|
}
|
|
190
191
|
}
|
|
191
|
-
exports.
|
|
192
|
-
|
|
192
|
+
exports.HotMesh = HotMesh;
|
|
193
|
+
HotMesh.disconnecting = false;
|
|
@@ -15,14 +15,12 @@ class LoggerService {
|
|
|
15
15
|
level: this.logLevel,
|
|
16
16
|
format: winston_1.format.combine(winston_1.format.colorize(), winston_1.format.timestamp(), winston_1.format.printf((info) => {
|
|
17
17
|
const { timestamp, level, message } = info;
|
|
18
|
-
// Extract the object from the `info` object's `Symbol(splat)` field
|
|
19
18
|
const symbols = Object.getOwnPropertySymbols(info);
|
|
20
19
|
const splatSymbol = symbols.find((symbol) => symbol.toString() === 'Symbol(splat)');
|
|
21
20
|
let splatData = {};
|
|
22
21
|
if (splatSymbol) {
|
|
23
22
|
splatData = info[splatSymbol][0] || {};
|
|
24
23
|
}
|
|
25
|
-
// Pass it to the `tagify` method
|
|
26
24
|
const tags = this.tagify(splatData);
|
|
27
25
|
return `${timestamp} [${level}] [${this.name || this.appId}:${this.instanceId}] ${message} ${tags}`;
|
|
28
26
|
})),
|
|
@@ -7,22 +7,8 @@ declare class MapperService {
|
|
|
7
7
|
constructor(rules: Record<string, unknown>, data: JobState);
|
|
8
8
|
mapRules(): Record<string, unknown>;
|
|
9
9
|
private traverseRules;
|
|
10
|
-
/**
|
|
11
|
-
* resolves a pipe expression of the form: { @pipe: [["{data.foo.bar}", 2, false, "hello world"]] }
|
|
12
|
-
* @param value
|
|
13
|
-
* @returns
|
|
14
|
-
*/
|
|
15
10
|
private pipe;
|
|
16
|
-
/**
|
|
17
|
-
* resolves a mapping expression in the form: "{data.foo.bar}" or 2 or false or "hello world"
|
|
18
|
-
* @param value
|
|
19
|
-
* @returns
|
|
20
|
-
*/
|
|
21
11
|
private resolve;
|
|
22
|
-
/**
|
|
23
|
-
* Evaluates a transition rule against the current job state and incoming Stream message
|
|
24
|
-
* to determine which (if any) transition should be taken.
|
|
25
|
-
*/
|
|
26
12
|
static evaluate(transitionRule: TransitionRule | boolean, context: JobState, code: StreamCode): boolean;
|
|
27
13
|
}
|
|
28
14
|
export { MapperService };
|
|
@@ -27,28 +27,14 @@ class MapperService {
|
|
|
27
27
|
return this.resolve(rules);
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
|
-
/**
|
|
31
|
-
* resolves a pipe expression of the form: { @pipe: [["{data.foo.bar}", 2, false, "hello world"]] }
|
|
32
|
-
* @param value
|
|
33
|
-
* @returns
|
|
34
|
-
*/
|
|
35
30
|
pipe(value) {
|
|
36
31
|
const pipe = new pipe_1.Pipe(value, this.data);
|
|
37
32
|
return pipe.process();
|
|
38
33
|
}
|
|
39
|
-
/**
|
|
40
|
-
* resolves a mapping expression in the form: "{data.foo.bar}" or 2 or false or "hello world"
|
|
41
|
-
* @param value
|
|
42
|
-
* @returns
|
|
43
|
-
*/
|
|
44
34
|
resolve(value) {
|
|
45
35
|
const pipe = new pipe_1.Pipe([[value]], this.data);
|
|
46
36
|
return pipe.process();
|
|
47
37
|
}
|
|
48
|
-
/**
|
|
49
|
-
* Evaluates a transition rule against the current job state and incoming Stream message
|
|
50
|
-
* to determine which (if any) transition should be taken.
|
|
51
|
-
*/
|
|
52
38
|
static evaluate(transitionRule, context, code) {
|
|
53
39
|
if (typeof transitionRule === 'boolean') {
|
|
54
40
|
return transitionRule;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { HotMesh } from "../hotmesh";
|
|
2
|
+
import { MeshCallConnectParams, MeshCallCronParams, MeshCallExecParams, MeshCallFlushParams, MeshCallInterruptParams } from "../../types/meshcall";
|
|
3
|
+
import { RedisConfig } from "../../types";
|
|
4
|
+
declare class MeshCall {
|
|
5
|
+
static workers: Map<string, HotMesh | Promise<HotMesh>>;
|
|
6
|
+
static engines: Map<string, HotMesh | Promise<HotMesh>>;
|
|
7
|
+
static connections: Map<string, any>;
|
|
8
|
+
constructor();
|
|
9
|
+
static findFirstMatching(workers: Map<string, (HotMesh | Promise<HotMesh>)>, namespace: string, config: RedisConfig): Promise<HotMesh | void>;
|
|
10
|
+
static getHotMeshClient: (namespace: string, connection: RedisConfig) => Promise<HotMesh>;
|
|
11
|
+
static verifyWorkflowActive(hotMesh: HotMesh, appId?: string, count?: number): Promise<boolean>;
|
|
12
|
+
static activateWorkflow(hotMesh: HotMesh, appId?: string, version?: string): Promise<void>;
|
|
13
|
+
static getInstance(namespace: string, redis: RedisConfig): Promise<HotMesh>;
|
|
14
|
+
static connect(params: MeshCallConnectParams): Promise<HotMesh>;
|
|
15
|
+
static exec<U>(params: MeshCallExecParams): Promise<U>;
|
|
16
|
+
static flush(params: MeshCallFlushParams): Promise<void>;
|
|
17
|
+
static cron(params: MeshCallCronParams): Promise<boolean>;
|
|
18
|
+
static interrupt(params: MeshCallInterruptParams): Promise<void>;
|
|
19
|
+
static shutdown(): Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
export { MeshCall };
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
var _a;
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.MeshCall = void 0;
|
|
8
|
+
const ms_1 = __importDefault(require("ms"));
|
|
9
|
+
const hotmesh_1 = require("../hotmesh");
|
|
10
|
+
const enums_1 = require("../../modules/enums");
|
|
11
|
+
const utils_1 = require("../../modules/utils");
|
|
12
|
+
const key_1 = require("../../modules/key");
|
|
13
|
+
const factory_1 = require("./schemas/factory");
|
|
14
|
+
class MeshCall {
|
|
15
|
+
constructor() { }
|
|
16
|
+
static async findFirstMatching(workers, namespace = key_1.HMNS, config) {
|
|
17
|
+
for (const [id, hotMeshInstance] of workers) {
|
|
18
|
+
if ((await hotMeshInstance).namespace === namespace) {
|
|
19
|
+
if (id.startsWith((0, utils_1.hashOptions)(config.options))) {
|
|
20
|
+
return hotMeshInstance;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
static async verifyWorkflowActive(hotMesh, appId = key_1.HMNS, count = 0) {
|
|
26
|
+
const app = await hotMesh.engine.store.getApp(appId);
|
|
27
|
+
const appVersion = app?.version;
|
|
28
|
+
if (isNaN(appVersion)) {
|
|
29
|
+
if (count > 10) {
|
|
30
|
+
throw new Error('Workflow failed to activate');
|
|
31
|
+
}
|
|
32
|
+
await (0, utils_1.sleepFor)(enums_1.HMSH_QUORUM_DELAY_MS * 2);
|
|
33
|
+
return await MeshCall.verifyWorkflowActive(hotMesh, appId, count + 1);
|
|
34
|
+
}
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
static async activateWorkflow(hotMesh, appId = key_1.HMNS, version = '1') {
|
|
38
|
+
const app = await hotMesh.engine.store.getApp(appId);
|
|
39
|
+
const appVersion = app?.version;
|
|
40
|
+
if (appVersion === version && !app.active) {
|
|
41
|
+
try {
|
|
42
|
+
await hotMesh.activate(version);
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
hotMesh.engine.logger.error('durable-client-activate-err', { error });
|
|
46
|
+
throw error;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
else if (isNaN(Number(appVersion)) || appVersion < version) {
|
|
50
|
+
try {
|
|
51
|
+
await hotMesh.deploy((0, factory_1.getWorkflowYAML)(appId));
|
|
52
|
+
await hotMesh.activate(version);
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
hotMesh.engine.logger.error('durable-client-deploy-activate-err', {
|
|
56
|
+
...error,
|
|
57
|
+
});
|
|
58
|
+
throw error;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
static async getInstance(namespace, redis) {
|
|
63
|
+
let hotMeshInstance = await MeshCall.findFirstMatching(MeshCall.workers, namespace, redis);
|
|
64
|
+
if (!hotMeshInstance) {
|
|
65
|
+
hotMeshInstance = await MeshCall.findFirstMatching(MeshCall.engines, namespace, redis);
|
|
66
|
+
if (!hotMeshInstance) {
|
|
67
|
+
hotMeshInstance = await MeshCall.getHotMeshClient(namespace, redis);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return hotMeshInstance;
|
|
71
|
+
}
|
|
72
|
+
static async connect(params) {
|
|
73
|
+
const targetNamespace = params.namespace ?? key_1.HMNS;
|
|
74
|
+
const optionsHash = (0, utils_1.hashOptions)(params.redis?.options);
|
|
75
|
+
const targetTopic = `${optionsHash}.${targetNamespace}.${params.topic}`;
|
|
76
|
+
const hotMeshWorker = await hotmesh_1.HotMesh.init({
|
|
77
|
+
guid: params.guid,
|
|
78
|
+
logLevel: params.logLevel ?? enums_1.HMSH_LOGLEVEL,
|
|
79
|
+
appId: params.namespace ?? key_1.HMNS,
|
|
80
|
+
engine: { redis: params.redis },
|
|
81
|
+
workers: [
|
|
82
|
+
{
|
|
83
|
+
topic: params.topic,
|
|
84
|
+
redis: params.redis,
|
|
85
|
+
callback: async function (input) {
|
|
86
|
+
const response = await params.callback.apply(this, input.data.args);
|
|
87
|
+
return {
|
|
88
|
+
metadata: { ...input.metadata },
|
|
89
|
+
data: { response },
|
|
90
|
+
};
|
|
91
|
+
},
|
|
92
|
+
}
|
|
93
|
+
],
|
|
94
|
+
});
|
|
95
|
+
MeshCall.workers.set(targetTopic, hotMeshWorker);
|
|
96
|
+
await MeshCall.activateWorkflow(hotMeshWorker, targetNamespace);
|
|
97
|
+
return hotMeshWorker;
|
|
98
|
+
}
|
|
99
|
+
static async exec(params) {
|
|
100
|
+
const TOPIC = `${params.namespace ?? key_1.HMNS}.call`;
|
|
101
|
+
const hotMeshInstance = await MeshCall.getInstance(params.namespace, params.redis);
|
|
102
|
+
let id = params.options?.id;
|
|
103
|
+
if (id) {
|
|
104
|
+
if (params.options?.flush) {
|
|
105
|
+
await hotMeshInstance.scrub(id);
|
|
106
|
+
}
|
|
107
|
+
else if (params.options?.ttl) {
|
|
108
|
+
try {
|
|
109
|
+
const cached = await hotMeshInstance.getState(TOPIC, id);
|
|
110
|
+
if (cached) {
|
|
111
|
+
return cached.data.response;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
id = hotmesh_1.HotMesh.guid();
|
|
120
|
+
}
|
|
121
|
+
let expire = 1;
|
|
122
|
+
if (params.options?.ttl) {
|
|
123
|
+
expire = (0, ms_1.default)(params.options.ttl) / 1000;
|
|
124
|
+
}
|
|
125
|
+
const jobOutput = await hotMeshInstance.pubsub(TOPIC, { id, expire, topic: params.topic, args: params.args }, null, 30000);
|
|
126
|
+
return jobOutput?.data?.response;
|
|
127
|
+
}
|
|
128
|
+
static async flush(params) {
|
|
129
|
+
const hotMeshInstance = await MeshCall.getInstance(params.namespace, params.redis);
|
|
130
|
+
await hotMeshInstance.scrub(params.id);
|
|
131
|
+
}
|
|
132
|
+
static async cron(params) {
|
|
133
|
+
try {
|
|
134
|
+
await MeshCall.connect({
|
|
135
|
+
logLevel: params.logLevel,
|
|
136
|
+
guid: params.guid,
|
|
137
|
+
topic: params.topic,
|
|
138
|
+
redis: params.redis,
|
|
139
|
+
callback: params.callback,
|
|
140
|
+
namespace: params.namespace,
|
|
141
|
+
});
|
|
142
|
+
const TOPIC = `${params.namespace ?? key_1.HMNS}.cron`;
|
|
143
|
+
const hotMeshInstance = await MeshCall.getInstance(params.namespace, params.redis);
|
|
144
|
+
await hotMeshInstance.pub(TOPIC, {
|
|
145
|
+
id: params.options.id,
|
|
146
|
+
topic: params.topic,
|
|
147
|
+
args: params.args,
|
|
148
|
+
interval: params.options.interval,
|
|
149
|
+
maxCycles: params.options.maxCycles ?? 1000000000,
|
|
150
|
+
maxDuration: params.options.maxDuration,
|
|
151
|
+
});
|
|
152
|
+
return true;
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
if (error.message.includes(`Duplicate job: ${params.options.id}`)) {
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
throw error;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
static async interrupt(params) {
|
|
162
|
+
const hotMeshInstance = await MeshCall.getInstance(params.namespace, params.redis);
|
|
163
|
+
await hotMeshInstance.interrupt(`${params.namespace ?? key_1.HMNS}.cron`, params.options.id, { 'throw': false, expire: 60 });
|
|
164
|
+
}
|
|
165
|
+
static async shutdown() {
|
|
166
|
+
for (const [_, hotMeshInstance] of MeshCall.workers) {
|
|
167
|
+
(await hotMeshInstance).stop();
|
|
168
|
+
}
|
|
169
|
+
for (const [_, hotMeshInstance] of MeshCall.engines) {
|
|
170
|
+
(await hotMeshInstance).stop();
|
|
171
|
+
}
|
|
172
|
+
await hotmesh_1.HotMesh.stop();
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
exports.MeshCall = MeshCall;
|
|
176
|
+
_a = MeshCall;
|
|
177
|
+
MeshCall.workers = new Map();
|
|
178
|
+
MeshCall.engines = new Map();
|
|
179
|
+
MeshCall.connections = new Map();
|
|
180
|
+
MeshCall.getHotMeshClient = async (namespace, connection) => {
|
|
181
|
+
const optionsHash = (0, utils_1.hashOptions)(connection.options);
|
|
182
|
+
const targetNS = namespace ?? key_1.HMNS;
|
|
183
|
+
const connectionNS = `${optionsHash}.${targetNS}`;
|
|
184
|
+
if (MeshCall.engines.has(connectionNS)) {
|
|
185
|
+
const hotMeshClient = await MeshCall.engines.get(connectionNS);
|
|
186
|
+
await _a.verifyWorkflowActive(hotMeshClient, targetNS);
|
|
187
|
+
return hotMeshClient;
|
|
188
|
+
}
|
|
189
|
+
const hotMeshClient = hotmesh_1.HotMesh.init({
|
|
190
|
+
appId: targetNS,
|
|
191
|
+
logLevel: enums_1.HMSH_LOGLEVEL,
|
|
192
|
+
engine: {
|
|
193
|
+
redis: {
|
|
194
|
+
class: connection.class,
|
|
195
|
+
options: connection.options,
|
|
196
|
+
},
|
|
197
|
+
},
|
|
198
|
+
});
|
|
199
|
+
MeshCall.engines.set(connectionNS, hotMeshClient);
|
|
200
|
+
await _a.activateWorkflow(await hotMeshClient, targetNS);
|
|
201
|
+
return hotMeshClient;
|
|
202
|
+
};
|