@versori/run 0.2.0-alpha.1 → 0.2.0-alpha.10

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 (81) hide show
  1. package/{script/deps/jsr.io/@std/fmt/1.0.6 → esm/deps/jsr.io/@std/fmt/1.0.7}/colors.d.ts.map +1 -1
  2. package/esm/deps/jsr.io/@std/fs/{1.0.16 → 1.0.17}/exists.d.ts.map +1 -1
  3. package/esm/deps/jsr.io/@std/log/0.224.14/console_handler.js +1 -1
  4. package/esm/deps/jsr.io/@std/log/0.224.14/rotating_file_handler.js +1 -1
  5. package/esm/src/context/Context.d.ts +2 -0
  6. package/esm/src/context/Context.d.ts.map +1 -1
  7. package/esm/src/context/Context.js +15 -0
  8. package/esm/src/dsl/http/types.d.ts +13 -2
  9. package/esm/src/dsl/http/types.d.ts.map +1 -1
  10. package/esm/src/dsl/http/versori/activation.d.ts +13 -0
  11. package/esm/src/dsl/http/versori/activation.d.ts.map +1 -0
  12. package/esm/src/dsl/http/versori/activation.js +65 -0
  13. package/esm/src/dsl/http/versori/constants.d.ts +5 -0
  14. package/esm/src/dsl/http/versori/constants.d.ts.map +1 -1
  15. package/esm/src/dsl/http/versori/constants.js +5 -0
  16. package/esm/src/dsl/http/versori/credentials/client.d.ts +1 -4
  17. package/esm/src/dsl/http/versori/credentials/client.d.ts.map +1 -1
  18. package/esm/src/dsl/http/versori/credentials/client.js +3 -16
  19. package/esm/src/dsl/http/versori/cronapi.d.ts +10 -0
  20. package/esm/src/dsl/http/versori/cronapi.d.ts.map +1 -0
  21. package/esm/src/dsl/http/versori/cronapi.js +51 -0
  22. package/esm/src/dsl/http/versori/platformapi.d.ts +4 -1
  23. package/esm/src/dsl/http/versori/platformapi.d.ts.map +1 -1
  24. package/esm/src/dsl/http/versori/platformapi.js +38 -6
  25. package/esm/src/dsl/http/versori/roundtripper.d.ts +3 -2
  26. package/esm/src/dsl/http/versori/roundtripper.d.ts.map +1 -1
  27. package/esm/src/dsl/http/versori/roundtripper.js +124 -73
  28. package/esm/src/interpreter/memory/MemoryInterpreter.d.ts +4 -2
  29. package/esm/src/interpreter/memory/MemoryInterpreter.d.ts.map +1 -1
  30. package/esm/src/interpreter/memory/MemoryInterpreter.js +47 -8
  31. package/esm/src/interpreter/memory/ObservableCompiler.d.ts +1 -0
  32. package/esm/src/interpreter/memory/ObservableCompiler.d.ts.map +1 -1
  33. package/esm/src/interpreter/memory/compilers/schedule.d.ts.map +1 -1
  34. package/esm/src/interpreter/memory/compilers/schedule.js +18 -23
  35. package/esm/src/observability/logging/ConsoleLogger.d.ts.map +1 -1
  36. package/esm/src/observability/logging/ConsoleLogger.js +55 -10
  37. package/package.json +1 -1
  38. package/{esm/deps/jsr.io/@std/fmt/1.0.6 → script/deps/jsr.io/@std/fmt/1.0.7}/colors.d.ts.map +1 -1
  39. package/script/deps/jsr.io/@std/fs/{1.0.16 → 1.0.17}/exists.d.ts.map +1 -1
  40. package/script/deps/jsr.io/@std/log/0.224.14/console_handler.js +1 -1
  41. package/script/deps/jsr.io/@std/log/0.224.14/rotating_file_handler.js +1 -1
  42. package/script/src/context/Context.d.ts +2 -0
  43. package/script/src/context/Context.d.ts.map +1 -1
  44. package/script/src/context/Context.js +15 -0
  45. package/script/src/dsl/http/types.d.ts +13 -2
  46. package/script/src/dsl/http/types.d.ts.map +1 -1
  47. package/script/src/dsl/http/versori/activation.d.ts +13 -0
  48. package/script/src/dsl/http/versori/activation.d.ts.map +1 -0
  49. package/script/src/dsl/http/versori/activation.js +69 -0
  50. package/script/src/dsl/http/versori/constants.d.ts +5 -0
  51. package/script/src/dsl/http/versori/constants.d.ts.map +1 -1
  52. package/script/src/dsl/http/versori/constants.js +6 -1
  53. package/script/src/dsl/http/versori/credentials/client.d.ts +1 -4
  54. package/script/src/dsl/http/versori/credentials/client.d.ts.map +1 -1
  55. package/script/src/dsl/http/versori/credentials/client.js +2 -15
  56. package/script/src/dsl/http/versori/cronapi.d.ts +10 -0
  57. package/script/src/dsl/http/versori/cronapi.d.ts.map +1 -0
  58. package/script/src/dsl/http/versori/cronapi.js +55 -0
  59. package/script/src/dsl/http/versori/platformapi.d.ts +4 -1
  60. package/script/src/dsl/http/versori/platformapi.d.ts.map +1 -1
  61. package/script/src/dsl/http/versori/platformapi.js +38 -6
  62. package/script/src/dsl/http/versori/roundtripper.d.ts +3 -2
  63. package/script/src/dsl/http/versori/roundtripper.d.ts.map +1 -1
  64. package/script/src/dsl/http/versori/roundtripper.js +124 -73
  65. package/script/src/interpreter/memory/MemoryInterpreter.d.ts +4 -2
  66. package/script/src/interpreter/memory/MemoryInterpreter.d.ts.map +1 -1
  67. package/script/src/interpreter/memory/MemoryInterpreter.js +47 -8
  68. package/script/src/interpreter/memory/ObservableCompiler.d.ts +1 -0
  69. package/script/src/interpreter/memory/ObservableCompiler.d.ts.map +1 -1
  70. package/script/src/interpreter/memory/compilers/schedule.d.ts.map +1 -1
  71. package/script/src/interpreter/memory/compilers/schedule.js +18 -23
  72. package/script/src/observability/logging/ConsoleLogger.d.ts.map +1 -1
  73. package/script/src/observability/logging/ConsoleLogger.js +55 -10
  74. /package/esm/deps/jsr.io/@std/fmt/{1.0.6 → 1.0.7}/colors.d.ts +0 -0
  75. /package/esm/deps/jsr.io/@std/fmt/{1.0.6 → 1.0.7}/colors.js +0 -0
  76. /package/esm/deps/jsr.io/@std/fs/{1.0.16 → 1.0.17}/exists.d.ts +0 -0
  77. /package/esm/deps/jsr.io/@std/fs/{1.0.16 → 1.0.17}/exists.js +0 -0
  78. /package/script/deps/jsr.io/@std/fmt/{1.0.6 → 1.0.7}/colors.d.ts +0 -0
  79. /package/script/deps/jsr.io/@std/fmt/{1.0.6 → 1.0.7}/colors.js +0 -0
  80. /package/script/deps/jsr.io/@std/fs/{1.0.16 → 1.0.17}/exists.d.ts +0 -0
  81. /package/script/deps/jsr.io/@std/fs/{1.0.16 → 1.0.17}/exists.js +0 -0
@@ -6,6 +6,7 @@ const mod_js_1 = require("./credentials/mod.js");
6
6
  const platformapi_js_1 = require("./platformapi.js");
7
7
  const mod_js_2 = require("../../../observability/mod.js");
8
8
  const constants_js_1 = require("./constants.js");
9
+ const connect_1 = require("@connectrpc/connect");
9
10
  /**
10
11
  * VersoriRoundTripper is an implementation of the RoundTripperFactory interface for Versori connections.
11
12
  * This is the intended implementation for when projects/services are hosted on Versori infrastructure.
@@ -19,13 +20,19 @@ const constants_js_1 = require("./constants.js");
19
20
  * ```
20
21
  */
21
22
  class VersoriRoundTripperFactory {
22
- constructor(credsClient, platformAPIClient, logger) {
23
+ constructor(credsClient, credsBaseURL, platformAPIClient, logger) {
23
24
  Object.defineProperty(this, "tokenClient", {
24
25
  enumerable: true,
25
26
  configurable: true,
26
27
  writable: true,
27
28
  value: void 0
28
29
  });
30
+ Object.defineProperty(this, "credsBaseURL", {
31
+ enumerable: true,
32
+ configurable: true,
33
+ writable: true,
34
+ value: void 0
35
+ });
29
36
  Object.defineProperty(this, "platformAPIClient", {
30
37
  enumerable: true,
31
38
  configurable: true,
@@ -56,6 +63,7 @@ class VersoriRoundTripperFactory {
56
63
  }
57
64
  });
58
65
  this.tokenClient = credsClient;
66
+ this.credsBaseURL = credsBaseURL;
59
67
  this.platformAPIClient = platformAPIClient;
60
68
  this.versoriCfg = (0, configloader_js_1.LoadConfigFromFile)();
61
69
  this.log = logger;
@@ -77,20 +85,23 @@ class VersoriRoundTripperFactory {
77
85
  missingVars.push(constants_js_1.envVarCredsBaseURL);
78
86
  throw new Error(`Missing environment variables: ${missingVars.join(', ')}`);
79
87
  }
80
- const pAPIClient = new platformapi_js_1.PlatformAPIClient(platformApiBaseURL, orgId, envId);
81
- const tokenClient = new mod_js_1.VersoriCredentialClient(credsBaseURL);
82
88
  const log = logger || new mod_js_2.ConsoleLogger('debug');
83
- return new VersoriRoundTripperFactory(tokenClient, pAPIClient, log);
89
+ const pAPIClient = new platformapi_js_1.PlatformAPIClient(platformApiBaseURL, orgId, envId, log);
90
+ const tokenClient = new mod_js_1.VersoriCredentialClient(credsBaseURL);
91
+ return new VersoriRoundTripperFactory(tokenClient, credsBaseURL, pAPIClient, log);
84
92
  }
85
93
  // takes the info and modifies the url using changeBaseUrl if necessary
94
+ // if a full valid URL is passed as a string, it will be returned as is
95
+ // if a valid URL object is passed, it will be returned as is
86
96
  changeRequestInit(info, conn) {
87
97
  if (typeof info === 'string') {
88
- // should be this most of the time assuming we're using pathnames
98
+ if (isValidURL(info)) {
99
+ return info;
100
+ }
89
101
  return this.changeBaseUrl(info, conn);
90
102
  }
91
103
  else if (info instanceof URL) {
92
- const newUrl = new URL(this.changeBaseUrl(info.toString(), conn));
93
- return newUrl;
104
+ return info;
94
105
  }
95
106
  else if (info instanceof Request) {
96
107
  const url = this.changeBaseUrl(info.url, conn);
@@ -102,6 +113,7 @@ class VersoriRoundTripperFactory {
102
113
  const connBaseURL = conn.baseUrl;
103
114
  // if the connection has no baseUrl set, but the pathname is a valid URL, return it as is
104
115
  if (!connBaseURL && isValidURL(pathname)) {
116
+ this.log.debug('Using given URL as is', { url: pathname });
105
117
  return pathname;
106
118
  }
107
119
  const connBaseURLObj = new URL(connBaseURL);
@@ -111,36 +123,45 @@ class VersoriRoundTripperFactory {
111
123
  _pathname = pathnameObj.pathname;
112
124
  }
113
125
  const newURL = new URL(_pathname, connBaseURLObj.origin);
126
+ this.log.debug('Using baseURL from connection', { url: newURL.toString() });
114
127
  return newURL.toString();
115
128
  }
116
- // TODO: Currently if the connection is edited, then the fetcher will not be updated.
117
- async create(connName, fn = globalThis.fetch) {
129
+ create(connName, fn = globalThis.fetch) {
118
130
  const cnxId = this.getConnectionID(connName);
119
- const conn = await this.platformAPIClient.getStaticConnection(cnxId);
120
- if (!conn) {
131
+ if (!cnxId) {
132
+ this.log.debug('Connection not found in config, could be a dynamic connection', {
133
+ connectionName: connName,
134
+ });
121
135
  return undefined;
122
136
  }
123
- const _fn = (input, init) => {
137
+ const _fn = async (input, init) => {
138
+ const conn = await this.platformAPIClient.getStaticConnection(cnxId);
139
+ if (!conn) {
140
+ this.log.error('Connection not found for user, using default fetch', {
141
+ connectionName: connName,
142
+ });
143
+ return globalThis.fetch(input, init);
144
+ }
124
145
  const _input = this.changeRequestInit(input, conn);
125
- return fn(_input, init);
146
+ switch (conn.credentials[0].authSchemeConfig.type) {
147
+ case 'api-key':
148
+ return (await this.apiKeyFetcher(conn, fn))(_input, init);
149
+ case 'basic-auth':
150
+ return (await this.basicAuthFetcher(conn, fn))(_input, init);
151
+ case 'jwt-bearer':
152
+ return (await this.bearerTokenFetcher(conn, fn))(_input, init);
153
+ case 'oauth2':
154
+ return (await this.oauth2Fetcher(conn, fn))(_input, init);
155
+ default:
156
+ return fn(_input, init);
157
+ }
126
158
  };
127
- switch (conn.credentials[0].authSchemeConfig.type) {
128
- case 'api-key':
129
- return this.apiKeyFetcher(conn, _fn);
130
- case 'basic-auth':
131
- return this.basicAuthFetcher(conn, _fn);
132
- case 'jwt-bearer':
133
- return this.bearerTokenFetcher(conn, _fn);
134
- case 'oauth2':
135
- return this.oauth2Fetcher(conn, _fn);
136
- default:
137
- return fn;
138
- }
159
+ return _fn;
139
160
  }
140
- async createDynamic(templateName, fn = globalThis.fetch) {
161
+ createDynamic(templateName, fn = globalThis.fetch) {
141
162
  const template = this.getTemplateID(templateName);
142
163
  if (!template) {
143
- this.log.info('Template not found in config, could be a static connection', {
164
+ this.log.debug('Template not found in config, could be a static connection', {
144
165
  templateName: templateName,
145
166
  });
146
167
  return undefined;
@@ -171,7 +192,8 @@ class VersoriRoundTripperFactory {
171
192
  return _fn;
172
193
  }
173
194
  getConnectionID(connName) {
174
- const conn = this.versoriCfg.mappings.find((c) => (c.dynamic === undefined || c.dynamic === false) && c.name.toLowerCase() === connName.toLowerCase());
195
+ const conn = this.versoriCfg.mappings.find((c) => (c.dynamic === undefined || c.dynamic === false) &&
196
+ c.name.toLowerCase() === connName.toLowerCase());
175
197
  if (!conn || !conn.connId) {
176
198
  return '';
177
199
  }
@@ -184,17 +206,17 @@ class VersoriRoundTripperFactory {
184
206
  }
185
207
  return template.templateId;
186
208
  }
187
- async apiKeyFetcher(conn, fn) {
188
- const tokenResponse = await this.tokenClient.getToken(conn.credentials[0].credential.id);
189
- const token = tokenResponse.token?.accessToken;
190
- const asc = conn.credentials[0].authSchemeConfig.apiKey;
191
- if (!token) {
192
- throw new Error('Token not found');
193
- }
194
- if (!asc) {
195
- throw new Error('API Key configuration not found');
196
- }
197
- const _fn = (input, init) => {
209
+ apiKeyFetcher(conn, fn) {
210
+ const _fn = async (input, init) => {
211
+ const tokenResponse = await this.getToken(conn.credentials[0].credential.id);
212
+ const token = tokenResponse.token?.accessToken;
213
+ const asc = conn.credentials[0].authSchemeConfig.apiKey;
214
+ if (!token) {
215
+ throw new Error('Token not found');
216
+ }
217
+ if (!asc) {
218
+ throw new Error('API Key configuration not found');
219
+ }
198
220
  if (!init) {
199
221
  init = {};
200
222
  }
@@ -232,13 +254,13 @@ class VersoriRoundTripperFactory {
232
254
  };
233
255
  return _fn;
234
256
  }
235
- async basicAuthFetcher(conn, fn) {
236
- const tokenResponse = await this.tokenClient.getToken(conn.credentials[0].credential.id);
237
- const token = tokenResponse.token?.accessToken;
238
- if (!token) {
239
- throw new Error('Token not found');
240
- }
241
- const _fn = (input, init) => {
257
+ basicAuthFetcher(conn, fn) {
258
+ const _fn = async (input, init) => {
259
+ const tokenResponse = await this.getToken(conn.credentials[0].credential.id);
260
+ const token = tokenResponse.token?.accessToken;
261
+ if (!token) {
262
+ throw new Error('Token not found');
263
+ }
242
264
  if (!init) {
243
265
  init = {};
244
266
  }
@@ -262,13 +284,13 @@ class VersoriRoundTripperFactory {
262
284
  return _fn;
263
285
  }
264
286
  // TODO: need to make the prefix and header name configurable from authschemeconfig
265
- async bearerTokenFetcher(conn, fn) {
266
- const tokenResponse = await this.tokenClient.getToken(conn.credentials[0].credential.id);
267
- const token = tokenResponse.token?.accessToken;
268
- if (!token) {
269
- throw new Error('Token not found');
270
- }
271
- const _fn = (input, init) => {
287
+ bearerTokenFetcher(conn, fn) {
288
+ const _fn = async (input, init) => {
289
+ const tokenResponse = await this.getToken(conn.credentials[0].credential.id);
290
+ const token = tokenResponse.token?.accessToken;
291
+ if (!token) {
292
+ throw new Error('Token not found');
293
+ }
272
294
  if (!init) {
273
295
  init = {};
274
296
  }
@@ -291,27 +313,27 @@ class VersoriRoundTripperFactory {
291
313
  };
292
314
  return _fn;
293
315
  }
294
- async oauth2Fetcher(conn, fn) {
295
- const tokenResponse = await this.tokenClient.getOAuth2Token(conn.credentials[0].credential.id);
296
- const token = tokenResponse.token?.accessToken;
297
- const tokenType = tokenResponse.token?.tokenType;
298
- if (!token) {
299
- throw new Error('Token not found');
300
- }
301
- const _tokenType = () => {
302
- const _tt = tokenType?.toLowerCase();
303
- switch (_tt) {
304
- case 'bearer':
305
- return 'Bearer';
306
- case 'mac':
307
- return 'MAC';
308
- case 'basic':
309
- return 'Basic';
310
- default:
311
- return 'Bearer';
316
+ oauth2Fetcher(conn, fn) {
317
+ const refreshFn = async (input, init, forceRefresh = false) => {
318
+ const tokenResponse = await this.getToken(conn.credentials[0].credential.id, forceRefresh);
319
+ const token = tokenResponse.token?.accessToken;
320
+ const tokenType = tokenResponse.token?.tokenType;
321
+ if (!token) {
322
+ throw new Error('Token not found');
312
323
  }
313
- };
314
- const _fn = (input, init) => {
324
+ const _tokenType = () => {
325
+ const _tt = tokenType?.toLowerCase();
326
+ switch (_tt) {
327
+ case 'bearer':
328
+ return 'Bearer';
329
+ case 'mac':
330
+ return 'MAC';
331
+ case 'basic':
332
+ return 'Basic';
333
+ default:
334
+ return 'Bearer';
335
+ }
336
+ };
315
337
  if (!init) {
316
338
  init = {};
317
339
  }
@@ -332,8 +354,37 @@ class VersoriRoundTripperFactory {
332
354
  }
333
355
  return fn(input, init);
334
356
  };
357
+ const _fn = async (input, init) => {
358
+ const resp = await refreshFn(input, init, false);
359
+ if (resp.status === 401) {
360
+ this.log.debug('Received 401 Unauthorized response, attempting refresh', {
361
+ url: input,
362
+ status: resp.status,
363
+ });
364
+ // TODO: attempt refresh until precondition failed??
365
+ return refreshFn(input, init, true);
366
+ }
367
+ return Promise.resolve(resp);
368
+ };
335
369
  return _fn;
336
370
  }
371
+ async getToken(id) {
372
+ try {
373
+ return await this.tokenClient.getToken(id);
374
+ }
375
+ catch (error) {
376
+ this.log.error('unable to get credential', { error });
377
+ if (error instanceof connect_1.ConnectError) {
378
+ if (error.rawMessage.includes("connection error received: not a result of an error") && error.code === connect_1.Code.Internal) {
379
+ this.log.info('Connection error received, attempting to reconnect');
380
+ this.tokenClient = new mod_js_1.VersoriCredentialClient(this.credsBaseURL);
381
+ return await this.tokenClient.getToken(id);
382
+ }
383
+ throw error;
384
+ }
385
+ throw error;
386
+ }
387
+ }
337
388
  }
338
389
  exports.VersoriRoundTripperFactory = VersoriRoundTripperFactory;
339
390
  function isValidURL(url) {
@@ -1,7 +1,7 @@
1
1
  import { Router } from 'express';
2
2
  import { Observable, Subscription } from 'rxjs';
3
3
  import { ContextProvider } from '../../context/ContextProvider.js';
4
- import { ConnectionProvider, RoundTripperFactory } from '../../dsl/http/types.js';
4
+ import { ConnectionProvider, CronProvider, RoundTripperFactory } from '../../dsl/http/types.js';
5
5
  import { Workflow } from '../../dsl/Workflow.js';
6
6
  import { Logger } from '../../observability/logging/Logger.js';
7
7
  import { ObservableCompiler } from './ObservableCompiler.js';
@@ -26,12 +26,14 @@ export declare class MemoryInterpreter {
26
26
  private readonly contextProvider;
27
27
  private readonly roundTripperFactory;
28
28
  private readonly router;
29
+ private cronRegistry;
29
30
  private readonly connectionProvider;
31
+ private readonly cronProvider;
30
32
  private registeredWorkflows;
31
33
  private server?;
32
34
  private shutdownServer?;
33
35
  private isShuttingDown;
34
- constructor(log: Logger, compiler: ObservableCompiler, contextProvider: ContextProvider, roundTripperFactory: RoundTripperFactory, router: Router, connectionProvider: ConnectionProvider);
36
+ constructor(log: Logger, compiler: ObservableCompiler, contextProvider: ContextProvider, roundTripperFactory: RoundTripperFactory, router: Router, cronRegistry: Map<string, string>, connectionProvider: ConnectionProvider, cronProvider: CronProvider);
35
37
  static newInstance(options?: MemoryInterpreterOptions): Promise<MemoryInterpreter>;
36
38
  register<O>(workflow: Workflow<O>, options?: MemoryInterpreterOptions): Registration;
37
39
  start(): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"MemoryInterpreter.d.ts","sourceRoot":"","sources":["../../../../src/src/interpreter/memory/MemoryInterpreter.ts"],"names":[],"mappings":"AAAA,OAAgB,EAAqB,MAAM,EAAE,MAAM,SAAS,CAAC;AAC7D,OAAO,EAA+B,UAAU,EAAW,YAAY,EAAE,MAAM,MAAM,CAAC;AACtF,OAAO,EAAE,eAAe,EAAuB,MAAM,kCAAkC,CAAC;AAExF,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAGlF,OAAO,EAAE,QAAQ,EAAgB,MAAM,uBAAuB,CAAC;AAI/D,OAAO,EAAE,MAAM,EAAE,MAAM,uCAAuC,CAAC;AAC/D,OAAO,EAAmB,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC9E,OAAO,EAAE,WAAW,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAIpE,MAAM,MAAM,wBAAwB,GAAG;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,kBAAkB,CAAC;IAC9B,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,sBAAsB,CAAC,EAAE,OAAO,CAAC;CACpC,CAAC;AAEF,KAAK,YAAY,GAAG;IAChB,QAAQ,EAAE,UAAU,CAAC,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;IAC7C,KAAK,EAAE,uBAAuB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IAC9C,oBAAoB,EAAE,eAAe,CAAC;IACtC,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,YAAY,CAAC,EAAE,YAAY,CAAC;CAC/B,CAAA;AAED,qBAAa,iBAAiB;IAOtB,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,mBAAmB;IACpC,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IAXvC,OAAO,CAAC,mBAAmB,CAA2B;IACtD,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,cAAc,CAAC,CAAa;IACpC,OAAO,CAAC,cAAc,CAAS;gBAGV,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,kBAAkB,EAC5B,eAAe,EAAE,eAAe,EAChC,mBAAmB,EAAE,mBAAmB,EACxC,MAAM,EAAE,MAAM,EACd,kBAAkB,EAAE,kBAAkB;WAS9C,WAAW,CAAC,OAAO,GAAE,wBAA6B,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAoC5F,QAAQ,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,wBAAwB;IA6C/D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAiHtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAK9B"}
1
+ {"version":3,"file":"MemoryInterpreter.d.ts","sourceRoot":"","sources":["../../../../src/src/interpreter/memory/MemoryInterpreter.ts"],"names":[],"mappings":"AAAA,OAAgB,EAAqB,MAAM,EAAE,MAAM,SAAS,CAAC;AAC7D,OAAO,EAA+B,UAAU,EAAW,YAAY,EAAE,MAAM,MAAM,CAAC;AACtF,OAAO,EAAE,eAAe,EAAuB,MAAM,kCAAkC,CAAC;AAExF,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAGhG,OAAO,EAAE,QAAQ,EAAgB,MAAM,uBAAuB,CAAC;AAI/D,OAAO,EAAE,MAAM,EAAE,MAAM,uCAAuC,CAAC;AAC/D,OAAO,EAAmB,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC9E,OAAO,EAAE,WAAW,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAIpE,MAAM,MAAM,wBAAwB,GAAG;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,kBAAkB,CAAC;IAC9B,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,sBAAsB,CAAC,EAAE,OAAO,CAAC;CACpC,CAAC;AAEF,KAAK,YAAY,GAAG;IAChB,QAAQ,EAAE,UAAU,CAAC,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;IAC7C,KAAK,EAAE,uBAAuB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IAC9C,oBAAoB,EAAE,eAAe,CAAC;IACtC,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,YAAY,CAAC,EAAE,YAAY,CAAC;CAC/B,CAAA;AAED,qBAAa,iBAAiB;IAOtB,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,mBAAmB;IACpC,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IACnC,OAAO,CAAC,QAAQ,CAAC,YAAY;IAbjC,OAAO,CAAC,mBAAmB,CAA2B;IACtD,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,cAAc,CAAC,CAAa;IACpC,OAAO,CAAC,cAAc,CAAS;gBAGV,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,kBAAkB,EAC5B,eAAe,EAAE,eAAe,EAChC,mBAAmB,EAAE,mBAAmB,EACxC,MAAM,EAAE,MAAM,EACvB,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EACxB,kBAAkB,EAAE,kBAAkB,EACtC,YAAY,EAAE,YAAY;WASlC,WAAW,CAAC,OAAO,GAAE,wBAA6B,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAwC5F,QAAQ,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,wBAAwB;IA8C/D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA2ItB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAK9B"}
@@ -15,8 +15,9 @@ const MemoryKeyValueProvider_js_1 = require("../../kv/memory/MemoryKeyValueProvi
15
15
  const NatsKeyValueProvider_js_1 = require("../../kv/nats/NatsKeyValueProvider.js");
16
16
  const ConsoleLogger_js_1 = require("../../observability/logging/ConsoleLogger.js");
17
17
  const ObservableCompiler_js_1 = require("./ObservableCompiler.js");
18
+ const cronapi_js_1 = require("../../dsl/http/versori/cronapi.js");
18
19
  class MemoryInterpreter {
19
- constructor(log, compiler, contextProvider, roundTripperFactory, router, connectionProvider) {
20
+ constructor(log, compiler, contextProvider, roundTripperFactory, router, cronRegistry, connectionProvider, cronProvider) {
20
21
  Object.defineProperty(this, "log", {
21
22
  enumerable: true,
22
23
  configurable: true,
@@ -47,12 +48,24 @@ class MemoryInterpreter {
47
48
  writable: true,
48
49
  value: router
49
50
  });
51
+ Object.defineProperty(this, "cronRegistry", {
52
+ enumerable: true,
53
+ configurable: true,
54
+ writable: true,
55
+ value: cronRegistry
56
+ });
50
57
  Object.defineProperty(this, "connectionProvider", {
51
58
  enumerable: true,
52
59
  configurable: true,
53
60
  writable: true,
54
61
  value: connectionProvider
55
62
  });
63
+ Object.defineProperty(this, "cronProvider", {
64
+ enumerable: true,
65
+ configurable: true,
66
+ writable: true,
67
+ value: cronProvider
68
+ });
56
69
  Object.defineProperty(this, "registeredWorkflows", {
57
70
  enumerable: true,
58
71
  configurable: true,
@@ -92,12 +105,12 @@ class MemoryInterpreter {
92
105
  if (options.contextProvider) {
93
106
  // no need to set up a key-value provider if options.contextProvider is already
94
107
  // initialised.
95
- return new MemoryInterpreter(log, compiler, options.contextProvider, roundTripperFactory, express_1.default.Router(), platformapi_js_1.PlatformAPIClient.fromEnv());
108
+ return new MemoryInterpreter(log, compiler, options.contextProvider, roundTripperFactory, express_1.default.Router(), new Map(), platformapi_js_1.PlatformAPIClient.fromEnv(), cronapi_js_1.CronAPIClient.fromEnv());
96
109
  }
97
110
  const kvp = await (options.skipVersoriCredentials
98
111
  ? new MemoryKeyValueProvider_js_1.MemoryKeyValueProvider()
99
112
  : NatsKeyValueProvider_js_1.NatsKeyValueProvider.fromEnv());
100
- return new MemoryInterpreter(log, compiler, new ContextProvider_js_1.ContextProviderImpl(log, kvp), roundTripperFactory, express_1.default.Router(), platformapi_js_1.PlatformAPIClient.fromEnv());
113
+ return new MemoryInterpreter(log, compiler, new ContextProvider_js_1.ContextProviderImpl(log, kvp), roundTripperFactory, express_1.default.Router(), new Map(), platformapi_js_1.PlatformAPIClient.fromEnv(), cronapi_js_1.CronAPIClient.fromEnv());
101
114
  }
102
115
  register(workflow, options) {
103
116
  const localAbortController = new AbortController();
@@ -114,6 +127,7 @@ class MemoryInterpreter {
114
127
  contextProvider: this.contextProvider,
115
128
  roundTripperFactory: this.roundTripperFactory,
116
129
  router: this.router,
130
+ cronRegistry: this.cronRegistry,
117
131
  connectionProvider: this.connectionProvider
118
132
  };
119
133
  const trigger$ = this.compiler.compileTrigger(compilerContext, workflow.trigger, combinedSignal);
@@ -146,9 +160,18 @@ class MemoryInterpreter {
146
160
  registration.subscription = registration.trigger$
147
161
  .pipe((0, rxjs_1.tap)((ctx) => {
148
162
  ctx.log.info('MemoryInterpreter.executionStarted', { data: ctx.data });
149
- }), (0, rxjs_1.mergeMap)((ctx) => (0, rxjs_1.of)(ctx).pipe(registration.task$, (0, rxjs_1.catchError)((error) => {
150
- ctx.log.error('MemoryInterpreter.executionError', { error });
151
- ctx.options.onError?.(ctx.withData(error));
163
+ }), (0, rxjs_1.mergeMap)((ctx) => (0, rxjs_1.of)(ctx).pipe(registration.task$, (0, rxjs_1.catchError)((err) => {
164
+ ctx.log.error('MemoryInterpreter.executionError', { error: err instanceof Error ? err.toString() : err });
165
+ try {
166
+ ctx.options.onError?.(ctx.withData(err));
167
+ }
168
+ catch (err) {
169
+ ctx.log.error('MemoryInterpreter.onErrorError: failed to call onError handler', { error: err instanceof Error ? err.toString() : err });
170
+ ctx.options.onError?.(ctx.withData({
171
+ message: 'Internal server error',
172
+ error: err instanceof Error ? err.toString() : err,
173
+ }));
174
+ }
152
175
  return rxjs_1.EMPTY;
153
176
  }))))
154
177
  .subscribe({
@@ -158,11 +181,20 @@ class MemoryInterpreter {
158
181
  durationMs,
159
182
  data: ctx.data,
160
183
  });
161
- ctx.options.onSuccess?.(ctx);
184
+ try {
185
+ ctx.options.onSuccess?.(ctx);
186
+ }
187
+ catch (err) {
188
+ ctx.log.error('MemoryInterpreter.onSuccessError: failed to call onSuccess handler', { error: err instanceof Error ? err.toString() : err });
189
+ ctx.options.onSuccess?.(ctx.withData({
190
+ message: 'Internal server error',
191
+ error: err instanceof Error ? err.toString() : err,
192
+ }));
193
+ }
162
194
  this.contextProvider.destroy(ctx);
163
195
  },
164
196
  error: (err) => {
165
- this.log.error('MemoryInterpreter.error', { error: err });
197
+ this.log.error('MemoryInterpreter.error', { error: err instanceof Error ? err.toString() : err });
166
198
  Deno.removeSignalListener('SIGINT', registration.sigintListener);
167
199
  },
168
200
  complete: () => {
@@ -174,6 +206,13 @@ class MemoryInterpreter {
174
206
  registration.subscription = undefined;
175
207
  });
176
208
  }
209
+ try {
210
+ this.cronProvider.updateCrons(this.cronRegistry);
211
+ }
212
+ catch (err) {
213
+ this.log.error('MemoryInterpreter.updateCronsError', { error: err instanceof Error ? err.toString() : err });
214
+ throw new Error('Unable to register scheduler tasks with central cron provider');
215
+ }
177
216
  this.server = app.listen(port, () => {
178
217
  this.log.info(`Express server listening on http://localhost:${port}`);
179
218
  });
@@ -14,6 +14,7 @@ export type CompilerContext = {
14
14
  roundTripperFactory: RoundTripperFactory;
15
15
  connectionProvider: ConnectionProvider;
16
16
  router: Router;
17
+ cronRegistry: Map<string, string>;
17
18
  };
18
19
  export type CompilerFunc<In = any, Out = any, T extends Task<In, Out> = Task<In, Out>> = (ctx: CompilerContext, task: T) => OperatorFunction<In, Out>;
19
20
  export declare class ObservableCompiler {
@@ -1 +1 @@
1
- {"version":3,"file":"ObservableCompiler.d.ts","sourceRoot":"","sources":["../../../../src/src/interpreter/memory/ObservableCompiler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,MAAM,CAAC;AACpD,OAAO,EAAE,IAAI,EAAY,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,uCAAuC,CAAC;AAO/D,OAAO,EAAE,uBAAuB,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE9F,OAAO,EAAE,OAAO,EAAe,MAAM,sBAAsB,CAAC;AAG5D,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAEvD,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAClF,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEjC,MAAM,MAAM,eAAe,GAAG;IAC1B,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,eAAe,EAAE,eAAe,CAAC;IACjC,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,MAAM,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,YAAY,CAAC,EAAE,GAAG,GAAG,EAAE,GAAG,GAAG,GAAG,EAAE,CAAC,SAAS,IAAI,CAAC,EAAE,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE,EAAE,GAAG,CAAC,IAAI,CACrF,GAAG,EAAE,eAAe,EACpB,IAAI,EAAE,CAAC,KACN,gBAAgB,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;AAE/B,qBAAa,kBAAkB;IAC3B,OAAO,CAAC,aAAa,CAAkD;IACvE,OAAO,CAAC,gBAAgB,CAAgD;;IAgBxE,WAAW,CAAC,EAAE,GAAG,GAAG,EAAE,GAAG,GAAG,GAAG,EAAE,KAAK,GAAG,IAAI,EACzC,GAAG,EAAE,eAAe,EACpB,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,GAAG,CAAC,GACpB,uBAAuB,CAAC,EAAE,EAAE,GAAG,EAAE,KAAK,CAAC;IAe1C,cAAc,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC,SAAS,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,EAC3D,GAAG,EAAE,eAAe,EACpB,OAAO,EAAE,CAAC,EACV,MAAM,EAAE,WAAW,GACpB,UAAU,CAAC,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAerC,YAAY,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,SAAS,IAAI,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,QAAQ,EAAE,YAAY,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;IAKjF,eAAe,CAAC,GAAG,EAAE,CAAC,SAAS,OAAO,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,eAAe,CAAC,GAAG,EAAE,CAAC,CAAC;CAIjF"}
1
+ {"version":3,"file":"ObservableCompiler.d.ts","sourceRoot":"","sources":["../../../../src/src/interpreter/memory/ObservableCompiler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,MAAM,CAAC;AACpD,OAAO,EAAE,IAAI,EAAY,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,uCAAuC,CAAC;AAO/D,OAAO,EAAE,uBAAuB,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE9F,OAAO,EAAE,OAAO,EAAe,MAAM,sBAAsB,CAAC;AAG5D,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAEvD,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAClF,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEjC,MAAM,MAAM,eAAe,GAAG;IAC1B,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,eAAe,EAAE,eAAe,CAAC;IACjC,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC,CAAC;AAEF,MAAM,MAAM,YAAY,CAAC,EAAE,GAAG,GAAG,EAAE,GAAG,GAAG,GAAG,EAAE,CAAC,SAAS,IAAI,CAAC,EAAE,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE,EAAE,GAAG,CAAC,IAAI,CACrF,GAAG,EAAE,eAAe,EACpB,IAAI,EAAE,CAAC,KACN,gBAAgB,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;AAE/B,qBAAa,kBAAkB;IAC3B,OAAO,CAAC,aAAa,CAAkD;IACvE,OAAO,CAAC,gBAAgB,CAAgD;;IAgBxE,WAAW,CAAC,EAAE,GAAG,GAAG,EAAE,GAAG,GAAG,GAAG,EAAE,KAAK,GAAG,IAAI,EACzC,GAAG,EAAE,eAAe,EACpB,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,GAAG,CAAC,GACpB,uBAAuB,CAAC,EAAE,EAAE,GAAG,EAAE,KAAK,CAAC;IAe1C,cAAc,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC,SAAS,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,EAC3D,GAAG,EAAE,eAAe,EACpB,OAAO,EAAE,CAAC,EACV,MAAM,EAAE,WAAW,GACpB,UAAU,CAAC,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAerC,YAAY,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,SAAS,IAAI,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,QAAQ,EAAE,YAAY,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;IAKjF,eAAe,CAAC,GAAG,EAAE,CAAC,SAAS,OAAO,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,eAAe,CAAC,GAAG,EAAE,CAAC,CAAC;CAIjF"}
@@ -1 +1 @@
1
- {"version":3,"file":"schedule.d.ts","sourceRoot":"","sources":["../../../../../src/src/interpreter/memory/compilers/schedule.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,0CAA0C,CAAC;AAEzF,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AA6F7C,eAAO,MAAM,gBAAgB,EAAE,eAAe,CAAC,YAAY,EAAE,eAAe,CAG3E,CAAC"}
1
+ {"version":3,"file":"schedule.d.ts","sourceRoot":"","sources":["../../../../../src/src/interpreter/memory/compilers/schedule.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,0CAA0C,CAAC;AAEzF,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAuF7C,eAAO,MAAM,gBAAgB,EAAE,eAAe,CAAC,YAAY,EAAE,eAAe,CAG3E,CAAC"}
@@ -1,15 +1,18 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.scheduleCompiler = void 0;
4
- const cron_1 = require("cron");
5
4
  const rxjs_1 = require("rxjs");
6
5
  const ScheduleTrigger_js_1 = require("../../../dsl/triggers/ScheduleTrigger.js");
7
6
  function compileSchedule(ctx, trigger, signal) {
8
7
  return new rxjs_1.Observable((subscriber) => {
8
+ // Add HTTP endpoint for manual triggering
9
+ if (!ctx.router) {
10
+ throw new Error('Router not available in compiler context');
11
+ }
9
12
  const client = ctx.connectionProvider;
10
- const job = cron_1.CronJob.from({
11
- cronTime: trigger.schedule,
12
- onTick: async () => {
13
+ ctx.cronRegistry.set(trigger.id, trigger.schedule);
14
+ ctx.router.post(`/cron/${trigger.id}`, async (req, res) => {
15
+ try {
13
16
  if (trigger.activationPredicate === undefined) {
14
17
  const executionCtx = ctx.contextProvider.create({}, undefined);
15
18
  try {
@@ -18,6 +21,7 @@ function compileSchedule(ctx, trigger, signal) {
18
21
  catch (error) {
19
22
  executionCtx.log.error('execution error inside schedule', { error });
20
23
  }
24
+ res.status(200).json({ status: 'triggered', executionId: executionCtx.executionId });
21
25
  return;
22
26
  }
23
27
  const activations = await client.listActivations();
@@ -30,6 +34,7 @@ function compileSchedule(ctx, trigger, signal) {
30
34
  catch (error) {
31
35
  executionCtx.log.error('execution error inside schedule', { error });
32
36
  }
37
+ res.status(200).json({ status: 'triggered', executionId: executionCtx.executionId });
33
38
  return;
34
39
  }
35
40
  activations.forEach((activation) => {
@@ -42,31 +47,21 @@ function compileSchedule(ctx, trigger, signal) {
42
47
  executionCtx.log.error('execution error inside schedule', { error });
43
48
  }
44
49
  });
45
- },
46
- onComplete: () => {
47
- if (subscriber.closed) {
48
- return;
49
- }
50
- ctx.log.debug('schedule execution completed');
51
- subscriber.complete();
52
- },
53
- errorHandler: (error) => {
54
- ctx.log.error('schedule execution error', { error });
55
- subscriber.error(error);
56
- },
57
- start: true,
50
+ res.status(200).json({ status: 'triggered' });
51
+ }
52
+ catch (error) {
53
+ executionCtx.log.error('execution error inside schedule', { error });
54
+ res.status(500).json({ error: 'Failed to trigger schedule' });
55
+ }
58
56
  });
59
57
  function cleanup() {
60
- ctx.log.debug('schedule execution stopped');
61
- job.stop();
58
+ ctx.log.debug('scheduler trigger stopped');
59
+ subscriber.complete();
62
60
  }
63
61
  signal.addEventListener('abort', cleanup, { once: true });
64
62
  return () => {
65
63
  signal.removeEventListener('abort', cleanup);
66
- ctx.log.debug('schedule execution unsubscribed');
67
- // call job.stop() directly rather than using cleanup since cleanup is called when the
68
- // signal is aborted and we don't want duplicate logs when the unsubscription happens.
69
- job.stop();
64
+ ctx.log.debug('scheduler execution unsubscribed');
70
65
  };
71
66
  });
72
67
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ConsoleLogger.d.ts","sourceRoot":"","sources":["../../../../src/src/observability/logging/ConsoleLogger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,+CAA+C,CAAC;AACrE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AA+B/C;;GAEG;AACH,qBAAa,aAAc,YAAW,MAAM;IACxC,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC;IAEhB,KAAK,EAAE,QAAQ,CAAC;IAEhB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAEpB,KAAK,EAAE,QAAQ,EAAE,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM;IAOjE,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAO9D,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAO7D,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAO9D,KAAK,CAAC,MAAM,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,GAAG,aAAa;IAOvD,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI;CAGlC"}
1
+ {"version":3,"file":"ConsoleLogger.d.ts","sourceRoot":"","sources":["../../../../src/src/observability/logging/ConsoleLogger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,+CAA+C,CAAC;AACrE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAmF/C;;GAEG;AACH,qBAAa,aAAc,YAAW,MAAM;IACxC,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC;IAEhB,KAAK,EAAE,QAAQ,CAAC;IAEhB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAEpB,KAAK,EAAE,QAAQ,EAAE,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM;IAOjE,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAO9D,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAO7D,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAO9D,KAAK,CAAC,MAAM,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,GAAG,aAAa;IAOvD,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI;CAGlC"}
@@ -25,6 +25,38 @@ var __importStar = (this && this.__importStar) || function (mod) {
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
26
  exports.ConsoleLogger = void 0;
27
27
  const log = __importStar(require("../../../deps/jsr.io/@std/log/0.224.14/mod.js"));
28
+ function valueOfUnknown(obj, idx) {
29
+ switch (typeof obj) {
30
+ case 'object':
31
+ if (obj instanceof Object) {
32
+ const valueOf = obj.valueOf();
33
+ if (typeof valueOf === 'object' && !Array.isArray(valueOf)) {
34
+ return valueOf;
35
+ }
36
+ return {
37
+ [`arg${idx}`]: obj,
38
+ };
39
+ }
40
+ if (obj === null) {
41
+ return {
42
+ [`arg${idx}`]: null,
43
+ };
44
+ }
45
+ return obj;
46
+ case 'undefined':
47
+ return {
48
+ [`arg${idx}`]: undefined,
49
+ };
50
+ case 'function':
51
+ return {
52
+ [`arg${idx}`]: obj.valueOf(),
53
+ };
54
+ default:
55
+ return {
56
+ [`arg${idx}`]: obj,
57
+ };
58
+ }
59
+ }
28
60
  log.setup({
29
61
  handlers: {
30
62
  default: new log.ConsoleHandler('DEBUG', {
@@ -34,16 +66,29 @@ log.setup({
34
66
  // - args are rendered as a nested object named `args`.
35
67
  //
36
68
  // This implementation uses ISO 8601 time and flattens the args object.
37
- return JSON.stringify({
38
- level: record.levelName,
39
- time: record.datetime.toISOString(),
40
- ...(record.loggerName ? { name: record.loggerName } : {}),
41
- msg: record.msg,
42
- ...(Array.isArray(record.args) ? record.args.reduce((acc, next) => ({
43
- ...acc,
44
- ...(typeof next === 'object' ? next : {}),
45
- }), {}) : {})
46
- });
69
+ try {
70
+ return JSON.stringify({
71
+ level: record.levelName,
72
+ time: record.datetime.toISOString(),
73
+ ...(record.loggerName ? { name: record.loggerName } : {}),
74
+ msg: record.msg,
75
+ ...(Array.isArray(record.args)
76
+ ? (record.args.reduce((acc, next, idx) => ({
77
+ ...acc,
78
+ ...(valueOfUnknown(next, idx)),
79
+ }), {}))
80
+ : {}),
81
+ });
82
+ }
83
+ catch (err) {
84
+ return JSON.stringify({
85
+ level: record.levelName,
86
+ time: record.datetime.toISOString(),
87
+ ...(record.loggerName ? { name: record.loggerName } : {}),
88
+ msg: record.msg,
89
+ LOG_ERROR: `Failed to render args: ${err instanceof Error ? err.message : err}`,
90
+ });
91
+ }
47
92
  },
48
93
  }),
49
94
  },