@outputai/core 0.7.1-next.ae5bab4.0 → 0.7.1-next.ba2fb0b.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 (78) hide show
  1. package/bin/worker.sh +6 -0
  2. package/package.json +1 -1
  3. package/src/consts.js +0 -4
  4. package/src/errors.js +6 -2
  5. package/src/hooks/index.d.ts +10 -0
  6. package/src/interface/evaluator.js +7 -20
  7. package/src/interface/evaluator.spec.js +117 -1
  8. package/src/interface/step.js +8 -9
  9. package/src/interface/step.spec.js +124 -0
  10. package/src/interface/validations/index.js +108 -0
  11. package/src/interface/validations/index.spec.js +182 -0
  12. package/src/interface/validations/schemas.js +113 -0
  13. package/src/interface/validations/schemas.spec.js +209 -0
  14. package/src/interface/webhook.js +1 -1
  15. package/src/interface/webhook.spec.js +1 -1
  16. package/src/interface/workflow.d.ts +10 -9
  17. package/src/interface/workflow.js +76 -164
  18. package/src/interface/workflow.spec.js +637 -521
  19. package/src/interface/workflow_activity_options.js +16 -0
  20. package/src/interface/workflow_utils.js +1 -1
  21. package/src/interface/zod_integration.spec.js +2 -2
  22. package/src/internal_utils/aggregations.js +0 -10
  23. package/src/internal_utils/aggregations.spec.js +1 -48
  24. package/src/internal_utils/errors.js +14 -8
  25. package/src/internal_utils/errors.spec.js +73 -27
  26. package/src/utils/index.d.ts +19 -0
  27. package/src/utils/utils.js +53 -0
  28. package/src/utils/utils.spec.js +105 -1
  29. package/src/worker/bundle.js +26 -0
  30. package/src/worker/bundle.spec.js +53 -0
  31. package/src/worker/bundler_options.js +1 -1
  32. package/src/worker/bundler_options.spec.js +1 -1
  33. package/src/worker/catalog_workflow/catalog_job.js +148 -0
  34. package/src/worker/catalog_workflow/catalog_job.spec.js +232 -0
  35. package/src/worker/check.js +24 -0
  36. package/src/worker/connection_monitor.js +112 -0
  37. package/src/worker/connection_monitor.spec.js +199 -0
  38. package/src/worker/index.js +146 -41
  39. package/src/worker/index.spec.js +281 -109
  40. package/src/worker/interceptors/activity.js +7 -24
  41. package/src/worker/interceptors/activity.spec.js +97 -66
  42. package/src/worker/interceptors/index.js +4 -7
  43. package/src/worker/interceptors/modules.js +15 -0
  44. package/src/worker/interceptors/workflow.js +6 -8
  45. package/src/worker/interceptors/workflow.spec.js +49 -42
  46. package/src/worker/interruption.js +33 -0
  47. package/src/worker/interruption.spec.js +98 -0
  48. package/src/worker/loader/activities.js +75 -0
  49. package/src/worker/loader/activities.spec.js +213 -0
  50. package/src/worker/loader/hooks.js +28 -0
  51. package/src/worker/loader/hooks.spec.js +64 -0
  52. package/src/worker/loader/matchers.js +46 -0
  53. package/src/worker/loader/matchers.spec.js +140 -0
  54. package/src/worker/{loader_tools.js → loader/tools.js} +19 -67
  55. package/src/worker/{loader_tools.spec.js → loader/tools.spec.js} +53 -85
  56. package/src/worker/loader/workflows.js +82 -0
  57. package/src/worker/loader/workflows.spec.js +256 -0
  58. package/src/worker/{setup_telemetry.js → telemetry.js} +9 -4
  59. package/src/worker/{setup_telemetry.spec.js → telemetry.spec.js} +3 -3
  60. package/src/worker/webpack_loaders/workflow_rewriter/collect_target_imports.js +5 -109
  61. package/src/worker/webpack_loaders/workflow_rewriter/collect_target_imports.spec.js +31 -103
  62. package/src/worker/webpack_loaders/workflow_rewriter/index.mjs +5 -6
  63. package/src/worker/webpack_loaders/workflow_rewriter/index.spec.js +11 -83
  64. package/src/worker/webpack_loaders/workflow_rewriter/rewrite_fn_bodies.js +8 -11
  65. package/src/worker/webpack_loaders/workflow_rewriter/rewrite_fn_bodies.spec.js +9 -9
  66. package/src/interface/validations/runtime.js +0 -20
  67. package/src/interface/validations/runtime.spec.js +0 -29
  68. package/src/interface/validations/schema_utils.js +0 -8
  69. package/src/interface/validations/schema_utils.spec.js +0 -67
  70. package/src/interface/validations/static.js +0 -137
  71. package/src/interface/validations/static.spec.js +0 -397
  72. package/src/interface/workflow.replay_compatibility.spec.js +0 -254
  73. package/src/worker/loader.js +0 -202
  74. package/src/worker/loader.spec.js +0 -498
  75. package/src/worker/shutdown.js +0 -26
  76. package/src/worker/shutdown.spec.js +0 -82
  77. package/src/worker/start_catalog.js +0 -96
  78. package/src/worker/start_catalog.spec.js +0 -179
@@ -1,202 +0,0 @@
1
- import { dirname, join } from 'node:path';
2
- import { existsSync, mkdirSync, writeFileSync } from 'node:fs';
3
- import { EOL } from 'node:os';
4
- import { fileURLToPath } from 'url';
5
- import { getTraceDestinations, sendHttpRequest } from '#internal_activities';
6
- import {
7
- activityMatchersBuilder,
8
- findSharedActivitiesFromWorkflows,
9
- findWorkflowsInNodeModules,
10
- importComponents,
11
- matchFiles,
12
- staticMatchers
13
- } from './loader_tools.js';
14
- import {
15
- ACTIVITY_SEND_HTTP_REQUEST,
16
- ACTIVITY_OPTIONS_FILENAME,
17
- SHARED_STEP_PREFIX,
18
- WORKFLOWS_INDEX_FILENAME,
19
- WORKFLOW_CATALOG,
20
- ACTIVITY_GET_TRACE_DESTINATIONS
21
- } from '#consts';
22
- import { createChildLogger } from '#logger';
23
- import { ValidationError } from '#errors';
24
-
25
- const log = createChildLogger( 'Scanner' );
26
-
27
- const __dirname = dirname( fileURLToPath( import.meta.url ) );
28
-
29
- /**
30
- * Writes to file the activity options
31
- *
32
- * @param {object} optionsMap
33
- */
34
- const writeActivityOptionsFile = map => {
35
- const path = join( __dirname, 'temp', ACTIVITY_OPTIONS_FILENAME );
36
- mkdirSync( dirname( path ), { recursive: true } );
37
- writeFileSync( path, `export default ${JSON.stringify( map, undefined, 2 )};`, 'utf-8' );
38
- };
39
-
40
- /**
41
- * Creates the activity key that will identify it on Temporal.
42
- *
43
- * It composes it using a namespace and the name of the activity.
44
- *
45
- * No two activities with the same name can exist on the same namespace.
46
- *
47
- * @param {object} options
48
- * @param {string} namespace
49
- * @param {string} activityName
50
- * @returns {string} key
51
- */
52
- const generateActivityKey = ( { namespace, activityName } ) => `${namespace}#${activityName}`;
53
-
54
- /**
55
- * Load activities:
56
- *
57
- * - Scans activities based on workflows, using each workflow folder as a point to lookup for steps, evaluators files;
58
- * - Scans shared activities in the rootDir;
59
- * - Loads internal activities as well;
60
- *
61
- * Builds a map of activities, where they is generated according to the type of activity and the value is the function itself and return it.
62
- * - Shared activity keys have a common prefix followed by the activity name;
63
- * - Internal activities are registered with a fixed key;
64
- * - Workflow activities keys are composed using the workflow name and the activity name;
65
- *
66
- * @param {string} rootDir
67
- * @param {object[]} workflows
68
- * @returns {object}
69
- */
70
- export async function loadActivities( rootDir, workflows ) {
71
- const activities = {};
72
- const activityOptionsMap = {};
73
-
74
- // Load workflow based activities
75
- for ( const { path: workflowPath, name: workflowName, external } of workflows ) {
76
- const dir = dirname( workflowPath );
77
- for await ( const { fn, metadata, path } of importComponents( matchFiles( dir, Object.values( activityMatchersBuilder( dir ) ) ) ) ) {
78
- log.info( 'Component loaded', { type: metadata.type, name: metadata.name, path, workflow: workflowName, ...( external && { external } ) } );
79
- // Activities loaded from a workflow path will use the workflow name as a namespace, which is unique across the platform, avoiding collision
80
- const activityKey = generateActivityKey( { namespace: workflowName, activityName: metadata.name } );
81
- if ( activities[activityKey] ) {
82
- throw new ValidationError( `Activity "${metadata.name}" in workflow "${workflowName}" conflicts with another \
83
- activity in the same workflow. Activity names must be unique within a workflow.` );
84
- }
85
- activities[activityKey] = fn;
86
- // propagate the custom options set on the step()/evaluator() constructor
87
- activityOptionsMap[activityKey] = metadata.options?.activityOptions ?? undefined;
88
- }
89
- }
90
-
91
- // Load shared activities/evaluators from local and external npm modules
92
- const localSharedActivities = matchFiles( rootDir, [ staticMatchers.sharedStepsDir, staticMatchers.sharedEvaluatorsDir ] );
93
- const externalSharedActivities = findSharedActivitiesFromWorkflows( workflows.filter( w => w.external ) );
94
- for await ( const { fn, metadata, path } of importComponents( [ ...localSharedActivities, ...externalSharedActivities ] ) ) {
95
- const external = externalSharedActivities.some( a => a.path === path );
96
- log.info( 'Shared component loaded', { type: metadata.type, name: metadata.name, path, ...( external && { external } ) } );
97
- // Reuses the same global namespace for shared activities
98
- const activityKey = generateActivityKey( { namespace: SHARED_STEP_PREFIX, activityName: metadata.name } );
99
- if ( activities[activityKey] ) {
100
- throw new ValidationError( `Shared activity "${metadata.name}" conflicts with another shared activity. \
101
- Shared activity names must be unique.` );
102
- }
103
- activities[activityKey] = fn;
104
- activityOptionsMap[activityKey] = metadata.options?.activityOptions ?? undefined;
105
- }
106
-
107
- // writes down the activity option overrides
108
- writeActivityOptionsFile( activityOptionsMap );
109
-
110
- // system activities
111
- activities[ACTIVITY_SEND_HTTP_REQUEST] = sendHttpRequest;
112
- activities[ACTIVITY_GET_TRACE_DESTINATIONS] = getTraceDestinations;
113
- return activities;
114
- };
115
-
116
- /**
117
- * Scan and find workflow.js files and import them.
118
- *
119
- * Creates an array containing their metadata and path and return it.
120
- *
121
- * @param {string} rootDir
122
- * @returns {object[]}
123
- */
124
- export async function loadWorkflows( rootDir ) {
125
- const workflowNames = new Set();
126
- const workflows = [];
127
- const localWorkflows = matchFiles( rootDir, [ staticMatchers.workflowFile ] );
128
- const externalWorkflows = findWorkflowsInNodeModules( rootDir );
129
- for await ( const { metadata, path } of importComponents( [ ...localWorkflows, ...externalWorkflows ] ) ) {
130
- const external = externalWorkflows.some( a => a.path === path );
131
- if ( staticMatchers.workflowPathHasShared( path ) ) {
132
- throw new ValidationError( 'Workflow directory can\'t be named "shared"' );
133
- }
134
- const { name, aliases } = metadata;
135
- if ( workflowNames.has( name ) ) {
136
- throw new ValidationError( `Workflow name "${name}" conflicts with another workflow or alias. \
137
- Workflow names and aliases must be unique.` );
138
- }
139
- if ( WORKFLOW_CATALOG === name ) {
140
- throw new ValidationError( `Workflow name "${name}" is reserved for the internal catalog workflow.` );
141
- }
142
- workflowNames.add( name );
143
- for ( const alias of aliases ?? [] ) {
144
- if ( workflowNames.has( alias ) ) {
145
- throw new ValidationError( `Workflow "${name}" alias "${alias}" conflicts with another workflow or alias. \
146
- Workflow names and aliases must be unique.` );
147
- }
148
- if ( WORKFLOW_CATALOG === alias ) {
149
- throw new ValidationError( `Workflow "${name}" alias "${alias}" is reserved for the internal catalog workflow.` );
150
- }
151
- workflowNames.add( alias );
152
- }
153
-
154
- log.info( 'Workflow loaded', { name, path, aliases, ...( external && { external } ) } );
155
- workflows.push( { ...metadata, path, external } );
156
- }
157
- return workflows;
158
- };
159
-
160
- /**
161
- * Loads the hook files from package.json's "outputai" section.
162
- *
163
- * @param {string} rootDir
164
- * @returns {void}
165
- */
166
- export async function loadHooks( rootDir ) {
167
- const packageFile = join( rootDir, 'package.json' );
168
- if ( existsSync( packageFile ) ) {
169
- const pkg = await import( packageFile, { with: { type: 'json' } } );
170
- const content = pkg.default;
171
- const hooks = [];
172
- // @DEPRECATED: "output" is the legacy namespace for configs, can be removed after couple version (this is being added in 0.3.x)
173
- hooks.push( ...( content['output']?.hookFiles ?? [] ) );
174
- hooks.push( ...( content['outputai']?.hookFiles ?? [] ) );
175
- for ( const path of hooks ) {
176
- const hookFile = join( rootDir, path );
177
- await import( hookFile );
178
- log.info( 'Hook file loaded', { path } );
179
- }
180
- }
181
- };
182
-
183
- /**
184
- * Creates a temporary index file importing all workflows for Temporal.
185
- *
186
- * @param {object[]} workflows
187
- * @returns
188
- */
189
- export function createWorkflowsEntryPoint( workflows ) {
190
- const path = join( __dirname, 'temp', WORKFLOWS_INDEX_FILENAME );
191
-
192
- // default system catalog workflow
193
- const catalog = { name: WORKFLOW_CATALOG, path: join( __dirname, './catalog_workflow/workflow.js' ) };
194
- const aliasExports = workflows.flatMap( ( { aliases = [], path } ) =>
195
- aliases.map( alias => ( { name: alias, path } ) )
196
- );
197
- const content = [ ...workflows, ...aliasExports, catalog ].map( ( { name, path } ) => `export { default as ${name} } from '${path}';` ).join( EOL );
198
-
199
- mkdirSync( dirname( path ), { recursive: true } );
200
- writeFileSync( path, content, 'utf-8' );
201
- return path;
202
- };