@output.ai/core 0.4.6 → 0.4.8
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/package.json +1 -1
- package/src/consts.js +10 -0
- package/src/index.js +1 -1
- package/src/interface/workflow.js +2 -2
- package/src/internal_activities/index.spec.js +10 -7
- package/src/logger.js +19 -2
- package/src/utils/index.d.ts +17 -0
- package/src/utils/utils.js +28 -0
- package/src/utils/utils.spec.js +49 -1
- package/src/worker/interceptors/activity.js +11 -2
- package/src/worker/interceptors/activity.spec.js +9 -6
- package/src/worker/sinks.js +29 -42
- package/src/logger.d.ts +0 -4
package/package.json
CHANGED
package/src/consts.js
CHANGED
|
@@ -10,3 +10,13 @@ export const ComponentType = {
|
|
|
10
10
|
INTERNAL_STEP: 'internal_step',
|
|
11
11
|
STEP: 'step'
|
|
12
12
|
};
|
|
13
|
+
export const LifecycleEvent = {
|
|
14
|
+
START: 'start',
|
|
15
|
+
END: 'end',
|
|
16
|
+
ERROR: 'error'
|
|
17
|
+
};
|
|
18
|
+
export const LifecycleEventLogMessage = {
|
|
19
|
+
[LifecycleEvent.START]: 'Start',
|
|
20
|
+
[LifecycleEvent.END]: 'End',
|
|
21
|
+
[LifecycleEvent.ERROR]: 'Error'
|
|
22
|
+
};
|
package/src/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import { proxyActivities, inWorkflowContext, executeChild, workflowInfo, uuid4,
|
|
|
3
3
|
import { validateWorkflow } from './validations/static.js';
|
|
4
4
|
import { validateWithSchema } from './validations/runtime.js';
|
|
5
5
|
import { SHARED_STEP_PREFIX, ACTIVITY_GET_TRACE_DESTINATIONS, METADATA_ACCESS_SYMBOL } from '#consts';
|
|
6
|
-
import { deepMerge, mergeActivityOptions, setMetadata } from '#utils';
|
|
6
|
+
import { deepMerge, mergeActivityOptions, setMetadata, toUrlSafeBase64 } from '#utils';
|
|
7
7
|
import { FatalError, ValidationError } from '#errors';
|
|
8
8
|
|
|
9
9
|
/**
|
|
@@ -121,7 +121,7 @@ export function workflow( { name, description, inputSchema, outputSchema, fn, op
|
|
|
121
121
|
startWorkflow: async ( childName, input, extra = {} ) =>
|
|
122
122
|
executeChild( childName, {
|
|
123
123
|
args: input ? [ input ] : [],
|
|
124
|
-
workflowId: `${workflowId}-${
|
|
124
|
+
workflowId: `${workflowId}-${toUrlSafeBase64( uuid4() )}`,
|
|
125
125
|
parentClosePolicy: ParentClosePolicy[extra?.detached ? 'ABANDON' : 'TERMINATE'],
|
|
126
126
|
memo: {
|
|
127
127
|
executionContext,
|
|
@@ -4,15 +4,18 @@ import { FatalError } from '#errors';
|
|
|
4
4
|
import { serializeBodyAndInferContentType, serializeFetchResponse } from '#utils';
|
|
5
5
|
import { sendHttpRequest } from './index.js';
|
|
6
6
|
|
|
7
|
-
vi.mock( '#
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
isStringboolTrue: vi.fn( () => false ),
|
|
11
|
-
serializeBodyAndInferContentType: vi.fn(),
|
|
12
|
-
serializeFetchResponse: vi.fn()
|
|
13
|
-
};
|
|
7
|
+
vi.mock( '#logger', () => {
|
|
8
|
+
const log = { info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() };
|
|
9
|
+
return { createChildLogger: vi.fn( () => log ) };
|
|
14
10
|
} );
|
|
15
11
|
|
|
12
|
+
vi.mock( '#utils', () => ( {
|
|
13
|
+
setMetadata: vi.fn(),
|
|
14
|
+
isStringboolTrue: vi.fn( () => false ),
|
|
15
|
+
serializeBodyAndInferContentType: vi.fn(),
|
|
16
|
+
serializeFetchResponse: vi.fn()
|
|
17
|
+
} ) );
|
|
18
|
+
|
|
16
19
|
const mockAgent = new MockAgent();
|
|
17
20
|
mockAgent.disableNetConnect();
|
|
18
21
|
|
package/src/logger.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import winston from 'winston';
|
|
2
|
+
import { shuffleArray } from '#utils';
|
|
2
3
|
|
|
3
4
|
const isProduction = process.env.NODE_ENV === 'production';
|
|
4
5
|
|
|
@@ -10,6 +11,16 @@ const levels = {
|
|
|
10
11
|
debug: 4
|
|
11
12
|
};
|
|
12
13
|
|
|
14
|
+
const colors = shuffleArray( [
|
|
15
|
+
'033', // blue
|
|
16
|
+
'030', // green
|
|
17
|
+
'208', // orange
|
|
18
|
+
'045', // turquoise
|
|
19
|
+
'129', // purple
|
|
20
|
+
'184' // yellow
|
|
21
|
+
] );
|
|
22
|
+
const assignedColors = new Map();
|
|
23
|
+
|
|
13
24
|
// Format metadata as friendly JSON: "{ name: "foo", count: 5 }"
|
|
14
25
|
const formatMeta = obj => {
|
|
15
26
|
const entries = Object.entries( obj );
|
|
@@ -18,14 +29,20 @@ const formatMeta = obj => {
|
|
|
18
29
|
}
|
|
19
30
|
return ' { ' + entries.map( ( [ k, v ] ) => `${k}: ${JSON.stringify( v )}` ).join( ', ' ) + ' }';
|
|
20
31
|
};
|
|
32
|
+
// Distribute the namespace in a map and assign it the next available color
|
|
33
|
+
const getColor = v =>
|
|
34
|
+
assignedColors.has( v ) ? assignedColors.get( v ) : assignedColors.set( v, colors[assignedColors.size % colors.length] ).get( v );
|
|
35
|
+
|
|
36
|
+
// Colorize a text using the namespace string
|
|
37
|
+
const colorizeByNamespace = ( namespace, text ) => `\x1b[38;5;${getColor( namespace )}m${text}\x1b[0m`;
|
|
21
38
|
|
|
22
39
|
// Development format: colorized with namespace prefix
|
|
23
40
|
const devFormat = winston.format.combine(
|
|
24
41
|
winston.format.colorize(),
|
|
25
42
|
winston.format.printf( ( { level, message, namespace, service: _, environment: __, ...rest } ) => {
|
|
26
|
-
const ns = namespace ?
|
|
43
|
+
const ns = 'Core' + ( namespace ? `.${namespace}` : '' );
|
|
27
44
|
const meta = formatMeta( rest );
|
|
28
|
-
return `[${level}] ${ns} ${message}${meta}`;
|
|
45
|
+
return `[${level}] ${colorizeByNamespace( ns, `${namespace}: ${message}` )}${meta}`;
|
|
29
46
|
} )
|
|
30
47
|
);
|
|
31
48
|
|
package/src/utils/index.d.ts
CHANGED
|
@@ -96,6 +96,14 @@ export function serializeBodyAndInferContentType( body: unknown ): SerializedBod
|
|
|
96
96
|
*/
|
|
97
97
|
export function isPlainObject( object: unknown ): boolean;
|
|
98
98
|
|
|
99
|
+
/**
|
|
100
|
+
* Returns a copy of an array with its content shuffled.
|
|
101
|
+
*
|
|
102
|
+
* @param arr - The array to shuffle
|
|
103
|
+
* @returns A shuffled array copy
|
|
104
|
+
*/
|
|
105
|
+
export function shuffleArray( arr: array ): array;
|
|
106
|
+
|
|
99
107
|
/**
|
|
100
108
|
* Creates a new object by merging object `b` onto object `a`, biased toward `b`:
|
|
101
109
|
* - Fields in `b` overwrite fields in `a`.
|
|
@@ -108,3 +116,12 @@ export function isPlainObject( object: unknown ): boolean;
|
|
|
108
116
|
* @returns A new merged object.
|
|
109
117
|
*/
|
|
110
118
|
export function deepMerge( a: object, b: object ): object;
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Shortens a UUID to a url-safe base64-like string (custom 64-char alphabet).
|
|
122
|
+
* Temporal-friendly: no Buffer or crypto; safe to use inside workflows.
|
|
123
|
+
*
|
|
124
|
+
* @param uuid - Standard UUID (e.g. `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`).
|
|
125
|
+
* @returns Short string using A–Z, a–z, 0–9, `_`, `-` (typically 21–22 chars).
|
|
126
|
+
*/
|
|
127
|
+
export function toUrlSafeBase64( uuid: string ): string;
|
package/src/utils/utils.js
CHANGED
|
@@ -162,6 +162,17 @@ export const serializeBodyAndInferContentType = payload => {
|
|
|
162
162
|
return { body: String( payload ), contentType: 'text/plain; charset=UTF-8' };
|
|
163
163
|
};
|
|
164
164
|
|
|
165
|
+
/**
|
|
166
|
+
* Receives an array and returns a copy of it with the elements shuffled
|
|
167
|
+
*
|
|
168
|
+
* @param {array} arr
|
|
169
|
+
* @returns {array}
|
|
170
|
+
*/
|
|
171
|
+
export const shuffleArray = arr => arr
|
|
172
|
+
.map( v => ( { v, sort: Math.random() } ) )
|
|
173
|
+
.sort( ( a, b ) => a.sort - b.sort )
|
|
174
|
+
.map( ( { v } ) => v );
|
|
175
|
+
|
|
165
176
|
/**
|
|
166
177
|
* Creates a new object merging object "b" onto object "a" biased to "b":
|
|
167
178
|
* - Object "b" will overwrite fields on object "a";
|
|
@@ -184,3 +195,20 @@ export const deepMerge = ( a, b ) => {
|
|
|
184
195
|
Object.assign( obj, { [k]: isPlainObject( v ) && isPlainObject( a[k] ) ? deepMerge( a[k], v ) : v } )
|
|
185
196
|
, clone( a ) );
|
|
186
197
|
};
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Shortens a UUID by re-encoding it to base62.
|
|
201
|
+
*
|
|
202
|
+
* This is a Temporal friendly, without crypto or Buffer.
|
|
203
|
+
* @param {string} uuid
|
|
204
|
+
* @returns {string}
|
|
205
|
+
*/
|
|
206
|
+
export const toUrlSafeBase64 = uuid => {
|
|
207
|
+
const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-';
|
|
208
|
+
const alphabetLen = alphabet.length;
|
|
209
|
+
const base = BigInt( alphabetLen );
|
|
210
|
+
const hex = uuid.replace( /-/g, '' );
|
|
211
|
+
|
|
212
|
+
const toDigits = n => n <= 0n ? [] : toDigits( n / base ).concat( alphabet[Number( n % base )] );
|
|
213
|
+
return toDigits( BigInt( '0x' + hex ) ).join( '' );
|
|
214
|
+
};
|
package/src/utils/utils.spec.js
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import { describe, it, expect } from 'vitest';
|
|
2
2
|
import { Readable } from 'node:stream';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
clone,
|
|
5
|
+
mergeActivityOptions,
|
|
6
|
+
serializeBodyAndInferContentType,
|
|
7
|
+
serializeFetchResponse,
|
|
8
|
+
deepMerge,
|
|
9
|
+
isPlainObject,
|
|
10
|
+
toUrlSafeBase64
|
|
11
|
+
} from './utils.js';
|
|
4
12
|
|
|
5
13
|
describe( 'clone', () => {
|
|
6
14
|
it( 'produces a deep copy without shared references', () => {
|
|
@@ -411,3 +419,43 @@ describe( 'isPlainObject', () => {
|
|
|
411
419
|
expect( isPlainObject( zum ) ).toBe( false );
|
|
412
420
|
} );
|
|
413
421
|
} );
|
|
422
|
+
|
|
423
|
+
describe( 'toUrlSafeBase64', () => {
|
|
424
|
+
const urlSafeAlphabet = /^[A-Za-z0-9_-]+$/;
|
|
425
|
+
|
|
426
|
+
it( 'returns a string for a valid UUID', () => {
|
|
427
|
+
const uuid = '550e8400-e29b-41d4-a716-446655440000';
|
|
428
|
+
expect( typeof toUrlSafeBase64( uuid ) ).toBe( 'string' );
|
|
429
|
+
expect( toUrlSafeBase64( uuid ).length ).toBeGreaterThan( 0 );
|
|
430
|
+
} );
|
|
431
|
+
|
|
432
|
+
it( 'output length is 21 or 22 for a standard UUID', () => {
|
|
433
|
+
const uuid = '550e8400-e29b-41d4-a716-446655440000';
|
|
434
|
+
const out = toUrlSafeBase64( uuid );
|
|
435
|
+
expect( out.length ).toBeGreaterThanOrEqual( 21 );
|
|
436
|
+
expect( out.length ).toBeLessThanOrEqual( 22 );
|
|
437
|
+
} );
|
|
438
|
+
|
|
439
|
+
it( 'output contains only url-safe alphabet characters', () => {
|
|
440
|
+
const uuid = '550e8400-e29b-41d4-a716-446655440000';
|
|
441
|
+
const out = toUrlSafeBase64( uuid );
|
|
442
|
+
expect( out ).toMatch( urlSafeAlphabet );
|
|
443
|
+
} );
|
|
444
|
+
|
|
445
|
+
it( 'is deterministic for the same UUID', () => {
|
|
446
|
+
const uuid = '6ba7b810-9dad-11d1-80b4-00c04fd430c8';
|
|
447
|
+
expect( toUrlSafeBase64( uuid ) ).toBe( toUrlSafeBase64( uuid ) );
|
|
448
|
+
} );
|
|
449
|
+
|
|
450
|
+
it( 'different UUIDs produce different strings', () => {
|
|
451
|
+
const a = toUrlSafeBase64( '550e8400-e29b-41d4-a716-446655440000' );
|
|
452
|
+
const b = toUrlSafeBase64( '6ba7b810-9dad-11d1-80b4-00c04fd430c8' );
|
|
453
|
+
expect( a ).not.toBe( b );
|
|
454
|
+
} );
|
|
455
|
+
|
|
456
|
+
it( 'strips hyphens and encodes hex (same as 32-char hex)', () => {
|
|
457
|
+
const withHyphens = '550e8400-e29b-41d4-a716-446655440000';
|
|
458
|
+
const hexOnly = '550e8400e29b41d4a716446655440000';
|
|
459
|
+
expect( toUrlSafeBase64( withHyphens ) ).toBe( toUrlSafeBase64( hexOnly ) );
|
|
460
|
+
} );
|
|
461
|
+
} );
|
|
@@ -2,9 +2,11 @@ import { Context } from '@temporalio/activity';
|
|
|
2
2
|
import { Storage } from '#async_storage';
|
|
3
3
|
import { addEventStart, addEventEnd, addEventError } from '#tracing';
|
|
4
4
|
import { headersToObject } from '../sandboxed_utils.js';
|
|
5
|
-
import { METADATA_ACCESS_SYMBOL } from '#consts';
|
|
5
|
+
import { LifecycleEventLogMessage, LifecycleEvent, METADATA_ACCESS_SYMBOL } from '#consts';
|
|
6
6
|
import { activityHeartbeatEnabled, activityHeartbeatIntervalMs } from '../configs.js';
|
|
7
|
+
import { createChildLogger } from '#logger';
|
|
7
8
|
|
|
9
|
+
const log = createChildLogger( 'Activity' );
|
|
8
10
|
/*
|
|
9
11
|
This interceptor wraps every activity execution with cross-cutting concerns:
|
|
10
12
|
|
|
@@ -27,11 +29,15 @@ export class ActivityExecutionInterceptor {
|
|
|
27
29
|
};
|
|
28
30
|
|
|
29
31
|
async execute( input, next ) {
|
|
30
|
-
const { workflowExecution: { workflowId }, activityId, activityType } = Context.current().info;
|
|
32
|
+
const { workflowExecution: { workflowId }, activityId, activityType, workflowType: workflowName } = Context.current().info;
|
|
31
33
|
const { executionContext } = headersToObject( input.headers );
|
|
32
34
|
const { type: kind } = this.activities?.[activityType]?.[METADATA_ACCESS_SYMBOL];
|
|
33
35
|
|
|
36
|
+
const startDate = Date.now();
|
|
37
|
+
const logContext = { workflowName, workflowId, stepId: activityId, stepName: activityType };
|
|
34
38
|
const traceArguments = { kind, id: activityId, parentId: workflowId, name: activityType, executionContext };
|
|
39
|
+
|
|
40
|
+
log.info( LifecycleEventLogMessage[LifecycleEvent.START], logContext );
|
|
35
41
|
addEventStart( { details: input.args[0], ...traceArguments } );
|
|
36
42
|
|
|
37
43
|
const intervals = { heartbeat: null };
|
|
@@ -40,10 +46,13 @@ export class ActivityExecutionInterceptor {
|
|
|
40
46
|
intervals.heartbeat = activityHeartbeatEnabled && setInterval( () => Context.current().heartbeat(), activityHeartbeatIntervalMs );
|
|
41
47
|
|
|
42
48
|
const output = await Storage.runWithContext( async _ => next( input ), { parentId: activityId, executionContext } );
|
|
49
|
+
|
|
50
|
+
log.info( LifecycleEventLogMessage[LifecycleEvent.END], { ...logContext, durationMs: Date.now() - startDate } );
|
|
43
51
|
addEventEnd( { details: output, ...traceArguments } );
|
|
44
52
|
return output;
|
|
45
53
|
|
|
46
54
|
} catch ( error ) {
|
|
55
|
+
log.error( LifecycleEventLogMessage[LifecycleEvent.ERROR], { ...logContext, durationMs: Date.now() - startDate, error: error.message } );
|
|
47
56
|
addEventError( { details: error, ...traceArguments } );
|
|
48
57
|
throw error;
|
|
49
58
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
2
2
|
|
|
3
|
-
const METADATA_ACCESS_SYMBOL = Symbol( '__metadata' );
|
|
3
|
+
const METADATA_ACCESS_SYMBOL = vi.hoisted( () => Symbol( '__metadata' ) );
|
|
4
4
|
|
|
5
5
|
const heartbeatMock = vi.fn();
|
|
6
6
|
const contextInfoMock = {
|
|
@@ -37,11 +37,14 @@ vi.mock( '../sandboxed_utils.js', () => ( {
|
|
|
37
37
|
headersToObject: () => ( { executionContext: { workflowId: 'wf-1' } } )
|
|
38
38
|
} ) );
|
|
39
39
|
|
|
40
|
-
vi.mock( '#consts',
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
40
|
+
vi.mock( '#consts', async importOriginal => {
|
|
41
|
+
const actual = await importOriginal();
|
|
42
|
+
return {
|
|
43
|
+
...actual, get METADATA_ACCESS_SYMBOL() {
|
|
44
|
+
return METADATA_ACCESS_SYMBOL;
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
} );
|
|
45
48
|
|
|
46
49
|
vi.mock( '../configs.js', () => ( {
|
|
47
50
|
get activityHeartbeatEnabled() {
|
package/src/worker/sinks.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { WORKFLOW_CATALOG } from '#consts';
|
|
1
|
+
import { LifecycleEvent, LifecycleEventLogMessage, WORKFLOW_CATALOG } from '#consts';
|
|
2
2
|
import { addEventStart, addEventEnd, addEventError } from '#tracing';
|
|
3
3
|
import { createChildLogger } from '#logger';
|
|
4
4
|
|
|
5
|
-
const log = createChildLogger( '
|
|
5
|
+
const log = createChildLogger( 'Workflow' );
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
8
|
+
* Adds a workflow trace event
|
|
9
9
|
*
|
|
10
10
|
* @param {function} method - Trace function to call
|
|
11
11
|
* @param {object} workflowInfo - Temporal workflowInfo object
|
|
@@ -20,44 +20,31 @@ const addWorkflowEvent = ( method, workflowInfo, details ) => {
|
|
|
20
20
|
};
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
23
|
+
* Logs the internal workflow event
|
|
24
24
|
*
|
|
25
|
-
* @param {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
const { workflowId, workflowType: workflowName } = workflowInfo;
|
|
29
|
-
if ( workflowName === WORKFLOW_CATALOG ) {
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
log.info( 'Workflow started', { workflowName, workflowId } );
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Log workflow completion with duration
|
|
37
|
-
*
|
|
38
|
-
* @param {object} workflowInfo - Temporal workflowInfo object
|
|
25
|
+
* @param {LifecycleEvent} event
|
|
26
|
+
* @param {Object} workflowInfo
|
|
27
|
+
* @returns {void}
|
|
39
28
|
*/
|
|
40
|
-
const
|
|
29
|
+
const logWorkflowEvent = ( event, workflowInfo, error ) => {
|
|
41
30
|
const { workflowId, workflowType: workflowName, startTime } = workflowInfo;
|
|
31
|
+
// exclude internal catalog
|
|
42
32
|
if ( workflowName === WORKFLOW_CATALOG ) {
|
|
43
33
|
return;
|
|
44
34
|
}
|
|
45
|
-
const durationMs = Date.now() - startTime.getTime();
|
|
46
|
-
log.info( 'Workflow completed', { workflowName, workflowId, durationMs } );
|
|
47
|
-
};
|
|
48
35
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
36
|
+
if ( event === LifecycleEvent.START ) {
|
|
37
|
+
log.info( LifecycleEventLogMessage[event], { workflowName, workflowId } );
|
|
38
|
+
} else if ( event === LifecycleEvent.END ) {
|
|
39
|
+
log.info( LifecycleEventLogMessage[event], { workflowName, workflowId, durationMs: Date.now() - startTime.getTime() } );
|
|
40
|
+
} else if ( event === LifecycleEvent.ERROR ) {
|
|
41
|
+
log.info( LifecycleEventLogMessage[event], {
|
|
42
|
+
workflowName,
|
|
43
|
+
workflowId,
|
|
44
|
+
durationMs: Date.now() - startTime.getTime(),
|
|
45
|
+
error: error.message
|
|
46
|
+
} );
|
|
58
47
|
}
|
|
59
|
-
const durationMs = Date.now() - startTime.getTime();
|
|
60
|
-
log.error( 'Workflow failed', { workflowName, workflowId, durationMs } );
|
|
61
48
|
};
|
|
62
49
|
|
|
63
50
|
/**
|
|
@@ -77,25 +64,25 @@ const addEvent = ( method, workflowInfo, options ) => {
|
|
|
77
64
|
export const sinks = {
|
|
78
65
|
trace: {
|
|
79
66
|
addWorkflowEventStart: {
|
|
80
|
-
fn: ( workflowInfo,
|
|
81
|
-
|
|
82
|
-
addWorkflowEvent( addEventStart, workflowInfo,
|
|
67
|
+
fn: ( workflowInfo, details ) => {
|
|
68
|
+
logWorkflowEvent( LifecycleEvent.START, workflowInfo );
|
|
69
|
+
addWorkflowEvent( addEventStart, workflowInfo, details );
|
|
83
70
|
},
|
|
84
71
|
callDuringReplay: false
|
|
85
72
|
},
|
|
86
73
|
|
|
87
74
|
addWorkflowEventEnd: {
|
|
88
|
-
fn: ( workflowInfo,
|
|
89
|
-
|
|
90
|
-
addWorkflowEvent( addEventEnd, workflowInfo,
|
|
75
|
+
fn: ( workflowInfo, details ) => {
|
|
76
|
+
logWorkflowEvent( LifecycleEvent.END, workflowInfo );
|
|
77
|
+
addWorkflowEvent( addEventEnd, workflowInfo, details );
|
|
91
78
|
},
|
|
92
79
|
callDuringReplay: false
|
|
93
80
|
},
|
|
94
81
|
|
|
95
82
|
addWorkflowEventError: {
|
|
96
|
-
fn: ( workflowInfo,
|
|
97
|
-
|
|
98
|
-
addWorkflowEvent( addEventError, workflowInfo,
|
|
83
|
+
fn: ( workflowInfo, details ) => {
|
|
84
|
+
logWorkflowEvent( LifecycleEvent.ERROR, workflowInfo, details );
|
|
85
|
+
addWorkflowEvent( addEventError, workflowInfo, details );
|
|
99
86
|
},
|
|
100
87
|
callDuringReplay: false
|
|
101
88
|
},
|
package/src/logger.d.ts
DELETED