@outputai/core 0.8.2-next.e1cd79b.0 → 0.8.2-next.e658cc2.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/package.json +11 -11
- package/src/bus.js +1 -1
- package/src/consts.js +5 -2
- package/src/helpers/component.js +12 -0
- package/src/helpers/component.spec.js +54 -0
- package/src/helpers/fetch.js +105 -0
- package/src/helpers/fetch.spec.js +203 -0
- package/src/helpers/function.js +15 -0
- package/src/helpers/function.spec.js +48 -0
- package/src/helpers/object.js +98 -0
- package/src/helpers/object.spec.js +377 -0
- package/src/helpers/promise.js +29 -0
- package/src/helpers/promise.spec.js +35 -0
- package/src/helpers/string.js +30 -0
- package/src/helpers/string.spec.js +64 -0
- package/src/hooks/index.d.ts +102 -30
- package/src/hooks/index.js +16 -1
- package/src/hooks/index.spec.js +55 -1
- package/src/index.d.ts +2 -2
- package/src/interface/evaluator.d.ts +2 -2
- package/src/interface/evaluator.js +14 -12
- package/src/interface/evaluator.spec.js +10 -6
- package/src/interface/index.d.ts +7 -6
- package/src/interface/index.js +2 -0
- package/src/interface/logger.d.ts +61 -0
- package/src/interface/logger.js +73 -0
- package/src/interface/logger.spec.js +172 -0
- package/src/interface/step.d.ts +1 -1
- package/src/interface/step.js +15 -12
- package/src/interface/step.spec.js +10 -6
- package/src/interface/webhook.d.ts +21 -2
- package/src/interface/workflow.d.ts +2 -2
- package/src/interface/workflow.js +85 -78
- package/src/interface/workflow.spec.js +11 -4
- package/src/internal_activities/index.js +38 -35
- package/src/internal_activities/index.spec.js +27 -4
- package/src/logger/development.js +2 -2
- package/src/logger/development.spec.js +19 -2
- package/src/logger/production.js +1 -1
- package/src/logger/production.spec.js +24 -5
- package/src/sdk/README.md +47 -0
- package/src/sdk/helpers/component_metadata.d.ts +17 -0
- package/src/sdk/helpers/component_metadata.js +6 -0
- package/src/sdk/helpers/component_metadata.spec.js +30 -0
- package/src/sdk/helpers/index.d.ts +12 -0
- package/src/sdk/helpers/index.js +3 -0
- package/src/sdk/helpers/objects.d.ts +51 -0
- package/src/sdk/helpers/objects.js +8 -0
- package/src/sdk/helpers/objects.spec.js +16 -0
- package/src/sdk/helpers/path.d.ts +11 -0
- package/src/sdk/helpers/path.js +32 -0
- package/src/{utils/resolve_invocation_dir.spec.js → sdk/helpers/path.spec.js} +9 -9
- package/src/sdk/runtime/context.d.ts +30 -0
- package/src/sdk/runtime/context.js +15 -0
- package/src/{activity_integration → sdk/runtime}/context.spec.js +5 -5
- package/src/sdk/runtime/events.d.ts +15 -0
- package/src/sdk/runtime/events.js +18 -0
- package/src/{activity_integration → sdk/runtime}/events.spec.js +8 -9
- package/src/sdk/runtime/index.d.ts +12 -0
- package/src/sdk/runtime/index.js +3 -0
- package/src/sdk/runtime/tracing.d.ts +46 -0
- package/src/sdk/runtime/tracing.js +11 -0
- package/src/tracing/processors/s3/redis_client.spec.js +0 -6
- package/src/tracing/processors/s3/s3_client.spec.js +0 -6
- package/src/tracing/trace_engine.js +1 -1
- package/src/worker/catalog_workflow/catalog_job.js +1 -1
- package/src/worker/catalog_workflow/index.spec.js +8 -11
- package/src/worker/configs.js +1 -1
- package/src/worker/connection_monitor.js +1 -1
- package/src/worker/global_functions.js +14 -0
- package/src/worker/global_functions.spec.js +55 -0
- package/src/worker/index.js +4 -1
- package/src/worker/index.spec.js +7 -0
- package/src/worker/interceptors/activity.js +8 -11
- package/src/worker/interceptors/activity.spec.js +25 -26
- package/src/worker/interceptors/workflow.js +3 -3
- package/src/worker/interceptors/workflow.spec.js +1 -1
- package/src/worker/loader/matchers.js +1 -1
- package/src/worker/loader/tools.js +1 -1
- package/src/worker/loader/tools.spec.js +1 -1
- package/src/worker/log_hooks.js +14 -0
- package/src/worker/log_hooks.spec.js +83 -2
- package/src/worker/sinks.js +7 -1
- package/src/worker/sinks.spec.js +203 -0
- package/src/activity_integration/context.d.ts +0 -23
- package/src/activity_integration/context.js +0 -18
- package/src/activity_integration/event_id_integration.spec.js +0 -52
- package/src/activity_integration/events.d.ts +0 -10
- package/src/activity_integration/events.js +0 -15
- package/src/activity_integration/index.d.ts +0 -9
- package/src/activity_integration/index.js +0 -3
- package/src/activity_integration/tracing.d.ts +0 -40
- package/src/activity_integration/tracing.js +0 -48
- package/src/utils/index.d.ts +0 -180
- package/src/utils/index.js +0 -2
- package/src/utils/resolve_invocation_dir.js +0 -34
- package/src/utils/utils.js +0 -334
- package/src/utils/utils.spec.js +0 -723
- /package/src/{internal_utils → helpers}/aggregations.js +0 -0
- /package/src/{internal_utils → helpers}/aggregations.spec.js +0 -0
- /package/src/{internal_utils → helpers}/errors.js +0 -0
- /package/src/{internal_utils → helpers}/errors.spec.js +0 -0
- /package/src/{internal_utils → helpers}/temporal_context.js +0 -0
- /package/src/{internal_utils → helpers}/temporal_context.spec.ts +0 -0
- /package/src/{internal_utils → helpers}/trace_info.js +0 -0
- /package/src/{internal_utils → helpers}/trace_info.spec.js +0 -0
- /package/src/{internal_utils → helpers}/workflow_context.js +0 -0
- /package/src/{internal_utils → helpers}/workflow_context.spec.js +0 -0
package/src/utils/utils.js
DELETED
|
@@ -1,334 +0,0 @@
|
|
|
1
|
-
import { METADATA_ACCESS_SYMBOL } from '#consts';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Node safe clone implementation that doesn't use global structuredClone()
|
|
5
|
-
* @param {object} v
|
|
6
|
-
* @returns {object}
|
|
7
|
-
*/
|
|
8
|
-
export const clone = v => {
|
|
9
|
-
try {
|
|
10
|
-
return JSON.parse( JSON.stringify( v ) );
|
|
11
|
-
} catch {
|
|
12
|
-
return v;
|
|
13
|
-
}
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Detect a JS plain object.
|
|
18
|
-
*
|
|
19
|
-
* @param {unknown} v
|
|
20
|
-
* @returns {boolean}
|
|
21
|
-
*/
|
|
22
|
-
export const isPlainObject = v =>
|
|
23
|
-
typeof v === 'object' &&
|
|
24
|
-
!Array.isArray( v ) &&
|
|
25
|
-
v !== null &&
|
|
26
|
-
[ Object.prototype, null ].includes( Object.getPrototypeOf( v ) );
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Throw given error
|
|
30
|
-
* @param {Error} e
|
|
31
|
-
* @throws {e}
|
|
32
|
-
*/
|
|
33
|
-
export const throws = e => {
|
|
34
|
-
throw e;
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Add metadata "values" property to a given object
|
|
39
|
-
* @param {object} target
|
|
40
|
-
* @param {object} values
|
|
41
|
-
* @returns
|
|
42
|
-
*/
|
|
43
|
-
export const setMetadata = ( target, values ) =>
|
|
44
|
-
Object.defineProperty( target, METADATA_ACCESS_SYMBOL, { value: values, writable: false, enumerable: false, configurable: false } );
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Read metadata previously attached via setMetadata
|
|
48
|
-
* @param {Function} target
|
|
49
|
-
* @returns {object|null}
|
|
50
|
-
*/
|
|
51
|
-
export const getMetadata = target => target[METADATA_ACCESS_SYMBOL] ?? null;
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Returns true if string value is stringbool and true
|
|
55
|
-
* @param {string} v
|
|
56
|
-
* @returns
|
|
57
|
-
*/
|
|
58
|
-
export const isStringboolTrue = v => [ '1', 'true', 'on' ].includes( v );
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Consume Fetch's HTTP Response and return a serialized version of it;
|
|
62
|
-
*
|
|
63
|
-
* @param {Response} response
|
|
64
|
-
* @returns {object} Serialized response
|
|
65
|
-
*/
|
|
66
|
-
export const serializeFetchResponse = async response => {
|
|
67
|
-
const headers = Object.fromEntries( response.headers );
|
|
68
|
-
const contentType = headers['content-type'] || '';
|
|
69
|
-
|
|
70
|
-
const body = await ( async () => {
|
|
71
|
-
if ( contentType.includes( 'application/json' ) ) {
|
|
72
|
-
return response.json();
|
|
73
|
-
}
|
|
74
|
-
if ( contentType.startsWith( 'text/' ) ) {
|
|
75
|
-
return response.text();
|
|
76
|
-
}
|
|
77
|
-
return response.arrayBuffer().then( buf => Buffer.from( buf ).toString( 'base64' ) );
|
|
78
|
-
} )();
|
|
79
|
-
|
|
80
|
-
return {
|
|
81
|
-
url: response.url,
|
|
82
|
-
status: response.status,
|
|
83
|
-
statusText: response.statusText,
|
|
84
|
-
ok: response.ok,
|
|
85
|
-
headers,
|
|
86
|
-
body
|
|
87
|
-
};
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Duck-typing to detect a Node Readable (Stream) without importing anything
|
|
92
|
-
*
|
|
93
|
-
* @param {unknown} v
|
|
94
|
-
* @returns {boolean}
|
|
95
|
-
*/
|
|
96
|
-
const isReadable = v =>
|
|
97
|
-
typeof v === 'object' &&
|
|
98
|
-
typeof v?.read === 'function' &&
|
|
99
|
-
typeof v?.on === 'function' &&
|
|
100
|
-
typeof v?.pipe === 'function' &&
|
|
101
|
-
v?.readable !== false;
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Based on the type of a payload, serialized it to be send as the body of a fetch POST request and also infer its Content Type.
|
|
105
|
-
*
|
|
106
|
-
* Non serializable types versus Content-Type reference (for Node)
|
|
107
|
-
*
|
|
108
|
-
* |Type|Is self-describing)|Inferred type by fetch|Defined mime type|
|
|
109
|
-
* |-|-|-|-}
|
|
110
|
-
* |Blob|yes|`blob.type`||
|
|
111
|
-
* |File|yes|`file.type`||
|
|
112
|
-
* |FormData|yes|"multipart/form-data; boundary=..."||
|
|
113
|
-
* |URLSearchParams|yes|"application/x-www-form-urlencoded;charset=UTF-8"||
|
|
114
|
-
* |ArrayBuffer|no||"application/octet-stream"|
|
|
115
|
-
* |TypedArray (Uint8Array,Uint16Array)||"application/octet-stream"||
|
|
116
|
-
* |DataView|no||"application/octet-stream"|
|
|
117
|
-
* |ReadableStream, Readable, AsyncIterator|no||Can't, because stream must be read|
|
|
118
|
-
*
|
|
119
|
-
* If payload is none of the above types, test it:
|
|
120
|
-
* If the it is an object, serialize using JSON.stringify and set content-type to `application/json`;
|
|
121
|
-
* Else, it is a JS primitive, serialize using JSON.stringify and set content-type to `text/plain`;
|
|
122
|
-
*
|
|
123
|
-
* This implementation is overkill for temporal workflows since the only types available there will be:
|
|
124
|
-
* - URLSearchParams
|
|
125
|
-
* - ArrayBuffer
|
|
126
|
-
* - TypedArrays
|
|
127
|
-
* - DataView
|
|
128
|
-
* - asyncGenerator
|
|
129
|
-
* The others are non deterministic and are not available at runtime, but this function was build to be flexible
|
|
130
|
-
*
|
|
131
|
-
* @see {@link https://fetch.spec.whatwg.org/#bodyinit}
|
|
132
|
-
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch}
|
|
133
|
-
*
|
|
134
|
-
* @param {unknown} payload
|
|
135
|
-
* @returns {object} An object with the serialized body and inferred content-type
|
|
136
|
-
*/
|
|
137
|
-
export const serializeBodyAndInferContentType = payload => {
|
|
138
|
-
const dataTypes = [ Blob, File, URLSearchParams, FormData ];
|
|
139
|
-
|
|
140
|
-
// empty body
|
|
141
|
-
if ( [ null, undefined ].includes( payload ) ) {
|
|
142
|
-
return { body: undefined, contentType: undefined };
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
// Buffer types, covers ArrayBuffer, TypedArrays and DataView
|
|
146
|
-
if ( payload instanceof ArrayBuffer || ArrayBuffer.isView( payload ) ) {
|
|
147
|
-
return { body: payload, contentType: 'application/octet-stream' };
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// These data types auto assigned mime types
|
|
151
|
-
if ( dataTypes.some( t => payload instanceof t ) ) {
|
|
152
|
-
return { body: payload, contentType: undefined };
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
// ReadableStream, Readable and Async Iterator mimes cant be determined without reading it
|
|
156
|
-
if ( payload instanceof ReadableStream || typeof payload[Symbol.asyncIterator] === 'function' || isReadable( payload ) ) {
|
|
157
|
-
return { body: payload, contentType: undefined };
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
if ( typeof payload === 'object' ) {
|
|
161
|
-
return { body: JSON.stringify( payload ), contentType: 'application/json; charset=UTF-8' };
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
return { body: String( payload ), contentType: 'text/plain; charset=UTF-8' };
|
|
165
|
-
};
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* Receives an array and returns a copy of it with the elements shuffled
|
|
169
|
-
*
|
|
170
|
-
* @param {array} arr
|
|
171
|
-
* @returns {array}
|
|
172
|
-
*/
|
|
173
|
-
export const shuffleArray = arr => arr
|
|
174
|
-
.map( v => ( { v, sort: Math.random() } ) )
|
|
175
|
-
.sort( ( a, b ) => a.sort - b.sort )
|
|
176
|
-
.map( ( { v } ) => v );
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* Creates a new object merging object "b" onto object "a", using a resolver function to define the value to keep.
|
|
180
|
-
* - Object "b" fields that also exists on "a" will have their value defined by the "resolver" function
|
|
181
|
-
* - Object "b" fields that don't exist on object "a" will be added;
|
|
182
|
-
* - Object "a" fields that don't exist on object "b" will be preserved;
|
|
183
|
-
*
|
|
184
|
-
* If "b" isn't an object, a new object equal to "a" is returned
|
|
185
|
-
*
|
|
186
|
-
* @param {object} a - The base object
|
|
187
|
-
* @param {object} b - The target object
|
|
188
|
-
* @param {function} resolver - A function that return the value to be kept. First argument is value a, second is value b
|
|
189
|
-
* @returns {object} A new object
|
|
190
|
-
*/
|
|
191
|
-
export const deepMergeWithResolver = ( a, b, resolver ) => {
|
|
192
|
-
if ( !isPlainObject( a ) ) {
|
|
193
|
-
throw new Error( 'Parameter "a" is not an object.' );
|
|
194
|
-
}
|
|
195
|
-
if ( !isPlainObject( b ) ) {
|
|
196
|
-
return clone( a );
|
|
197
|
-
}
|
|
198
|
-
return Object.entries( b ).reduce( ( obj, [ k, v ] ) =>
|
|
199
|
-
Object.assign( obj, {
|
|
200
|
-
[k]: ( () => {
|
|
201
|
-
if ( isPlainObject( v ) && isPlainObject( a[k] ) ) {
|
|
202
|
-
return deepMergeWithResolver( a[k], v, resolver );
|
|
203
|
-
}
|
|
204
|
-
if ( Object.hasOwn( a, k ) ) {
|
|
205
|
-
return resolver( a[k], v );
|
|
206
|
-
}
|
|
207
|
-
return v;
|
|
208
|
-
} )()
|
|
209
|
-
} )
|
|
210
|
-
, clone( a ) );
|
|
211
|
-
};
|
|
212
|
-
|
|
213
|
-
/**
|
|
214
|
-
* Creates a new object merging object "b" onto object "a" biased to "b":
|
|
215
|
-
* - Object "b" will overwrite fields on object "a";
|
|
216
|
-
* - Object "b" fields that don't exist on object "a" will be added;
|
|
217
|
-
* - Object "a" fields that don't exist on object "b" will be preserved;
|
|
218
|
-
*
|
|
219
|
-
* If "b" isn't an object, a new object equal to "a" is returned
|
|
220
|
-
*
|
|
221
|
-
* @param {object} a - The base object
|
|
222
|
-
* @param {object} b - The target object
|
|
223
|
-
* @returns {object} A new object
|
|
224
|
-
*/
|
|
225
|
-
export const deepMerge = ( a, b ) => deepMergeWithResolver( a, b, ( _, b ) => b );
|
|
226
|
-
|
|
227
|
-
/**
|
|
228
|
-
* Shortens a UUID by re-encoding it to base62.
|
|
229
|
-
*
|
|
230
|
-
* This is a Temporal friendly, without crypto or Buffer.
|
|
231
|
-
* @param {string} uuid
|
|
232
|
-
* @returns {string}
|
|
233
|
-
*/
|
|
234
|
-
export const toUrlSafeBase64 = uuid => {
|
|
235
|
-
const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-';
|
|
236
|
-
const alphabetLen = alphabet.length;
|
|
237
|
-
const base = BigInt( alphabetLen );
|
|
238
|
-
const hex = uuid.replace( /-/g, '' );
|
|
239
|
-
|
|
240
|
-
const toDigits = n => n <= 0n ? [] : toDigits( n / base ).concat( alphabet[Number( n % base )] );
|
|
241
|
-
return toDigits( BigInt( '0x' + hex ) ).join( '' );
|
|
242
|
-
};
|
|
243
|
-
|
|
244
|
-
/**
|
|
245
|
-
* Similar to native Promise.allSettled but throws an Error if the execution exceeds a given time.
|
|
246
|
-
*
|
|
247
|
-
* The error thrown will have attribute `.isTimeout` as `true`.
|
|
248
|
-
*
|
|
249
|
-
* @template T
|
|
250
|
-
* @param {Array<T | PromiseLike<T>>} promises
|
|
251
|
-
* @param {number} timeoutMs
|
|
252
|
-
* @returns {Promise<PromiseSettledResult<Awaited<T>>[]>}
|
|
253
|
-
* @throws {Error & { isTimeout: true }}
|
|
254
|
-
*/
|
|
255
|
-
export const allSettledWithTimeout = ( () => {
|
|
256
|
-
class TimeoutError extends Error {
|
|
257
|
-
isTimeout = true;
|
|
258
|
-
constructor() {
|
|
259
|
-
super( 'Timed out before completing all promises' );
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
return async ( promises, timeoutMs ) => {
|
|
264
|
-
if ( promises.length === 0 ) {
|
|
265
|
-
return [];
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
const state = { timeoutMonitor: null };
|
|
269
|
-
|
|
270
|
-
try {
|
|
271
|
-
return await Promise.race( [
|
|
272
|
-
Promise.allSettled( promises ),
|
|
273
|
-
new Promise( ( _, reject ) => {
|
|
274
|
-
state.timeoutMonitor = setTimeout( () => reject( new TimeoutError() ), timeoutMs );
|
|
275
|
-
} )
|
|
276
|
-
] );
|
|
277
|
-
} finally {
|
|
278
|
-
clearTimeout( state.timeoutMonitor );
|
|
279
|
-
}
|
|
280
|
-
};
|
|
281
|
-
} )();
|
|
282
|
-
|
|
283
|
-
/**
|
|
284
|
-
* Builds a promise that can be resolved from the outside.
|
|
285
|
-
*/
|
|
286
|
-
export class CancellablePromise {
|
|
287
|
-
#promise = null;
|
|
288
|
-
#complete = null;
|
|
289
|
-
#completed = false;
|
|
290
|
-
|
|
291
|
-
constructor() {
|
|
292
|
-
this.#promise = new Promise( resolve => {
|
|
293
|
-
this.#complete = () => {
|
|
294
|
-
resolve();
|
|
295
|
-
this.#completed = true;
|
|
296
|
-
};
|
|
297
|
-
} );
|
|
298
|
-
}
|
|
299
|
-
/** Retrieves the promise */
|
|
300
|
-
get promise() {
|
|
301
|
-
return this.#promise;
|
|
302
|
-
}
|
|
303
|
-
/** Returns whether the promise is resolved or not */
|
|
304
|
-
get completed() {
|
|
305
|
-
return this.#completed;
|
|
306
|
-
}
|
|
307
|
-
/** Resolves the promise */
|
|
308
|
-
complete() {
|
|
309
|
-
this.#complete();
|
|
310
|
-
}
|
|
311
|
-
};
|
|
312
|
-
|
|
313
|
-
/**
|
|
314
|
-
* Returns a function that invokes the fn argument when called once, further calls do nothing.
|
|
315
|
-
* @param {Function} fn
|
|
316
|
-
* @returns {Function}
|
|
317
|
-
*/
|
|
318
|
-
export const runOnce = fn => {
|
|
319
|
-
const state = { executed: false, result: undefined };
|
|
320
|
-
return ( ...args ) => {
|
|
321
|
-
if ( !state.executed ) {
|
|
322
|
-
state.executed = true;
|
|
323
|
-
return state.result = fn( ...args );
|
|
324
|
-
}
|
|
325
|
-
return state.result;
|
|
326
|
-
};
|
|
327
|
-
};
|
|
328
|
-
|
|
329
|
-
/**
|
|
330
|
-
* Escape regexp characters in a string
|
|
331
|
-
* @param {*} value
|
|
332
|
-
* @returns
|
|
333
|
-
*/
|
|
334
|
-
export const rxEscape = v => v.replace( /[.*+?^${}()|[\]\\]/g, '\\$&' );
|