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