@hotmeshio/hotmesh 0.5.4 → 0.5.6

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 (27) hide show
  1. package/README.md +185 -161
  2. package/build/package.json +3 -2
  3. package/build/services/activities/trigger.js +1 -1
  4. package/build/services/connector/factory.js +2 -1
  5. package/build/services/connector/providers/postgres.js +11 -6
  6. package/build/services/memflow/client.js +4 -2
  7. package/build/services/memflow/index.d.ts +154 -34
  8. package/build/services/memflow/index.js +165 -33
  9. package/build/services/memflow/interceptor.d.ts +241 -0
  10. package/build/services/memflow/interceptor.js +256 -0
  11. package/build/services/memflow/worker.js +10 -1
  12. package/build/services/memflow/workflow/execChild.js +3 -1
  13. package/build/services/memflow/workflow/execHook.js +1 -1
  14. package/build/services/memflow/workflow/hook.js +4 -2
  15. package/build/services/memflow/workflow/proxyActivities.js +2 -1
  16. package/build/services/router/consumption/index.js +23 -9
  17. package/build/services/router/error-handling/index.js +3 -3
  18. package/build/services/search/providers/postgres/postgres.js +47 -19
  19. package/build/services/store/providers/postgres/kvtypes/hash/basic.js +1 -1
  20. package/build/services/store/providers/postgres/kvtypes/hash/index.js +2 -2
  21. package/build/services/store/providers/postgres/kvtypes/hash/jsonb.js +11 -11
  22. package/build/services/store/providers/postgres/postgres.js +8 -8
  23. package/build/services/stream/providers/postgres/postgres.js +23 -20
  24. package/build/services/sub/providers/postgres/postgres.js +11 -3
  25. package/build/services/task/index.js +4 -4
  26. package/build/types/memflow.d.ts +78 -0
  27. package/package.json +3 -2
@@ -18,7 +18,7 @@ function createJsonbOperations(context) {
18
18
  };
19
19
  function handleContextSet(key, fields, options) {
20
20
  const tableName = context.tableForKey(key, 'hash');
21
- const replayId = Object.keys(fields).find(k => k.includes('-') && k !== '@context');
21
+ const replayId = Object.keys(fields).find((k) => k.includes('-') && k !== '@context');
22
22
  const params = [];
23
23
  let sql = '';
24
24
  if (options?.nx) {
@@ -93,7 +93,7 @@ function createJsonbOperations(context) {
93
93
  }
94
94
  function handleContextMerge(key, fields, options) {
95
95
  const tableName = context.tableForKey(key, 'hash');
96
- const replayId = Object.keys(fields).find(k => k.includes('-') && k !== '@context:merge');
96
+ const replayId = Object.keys(fields).find((k) => k.includes('-') && k !== '@context:merge');
97
97
  const params = [];
98
98
  let sql = '';
99
99
  if (options?.nx) {
@@ -227,7 +227,7 @@ function createJsonbOperations(context) {
227
227
  const tableName = context.tableForKey(key, 'hash');
228
228
  const path = fields['@context:delete'];
229
229
  const pathParts = path.split('.');
230
- const replayId = Object.keys(fields).find(k => k.includes('-') && k !== '@context:delete');
230
+ const replayId = Object.keys(fields).find((k) => k.includes('-') && k !== '@context:delete');
231
231
  const params = [];
232
232
  let sql = '';
233
233
  if (pathParts.length === 1) {
@@ -300,7 +300,7 @@ function createJsonbOperations(context) {
300
300
  const tableName = context.tableForKey(key, 'hash');
301
301
  const { path, value } = JSON.parse(fields['@context:append']);
302
302
  const pathParts = path.split('.');
303
- const replayId = Object.keys(fields).find(k => k.includes('-') && k !== '@context:append');
303
+ const replayId = Object.keys(fields).find((k) => k.includes('-') && k !== '@context:append');
304
304
  const params = [];
305
305
  let sql = '';
306
306
  if (replayId) {
@@ -348,7 +348,7 @@ function createJsonbOperations(context) {
348
348
  const tableName = context.tableForKey(key, 'hash');
349
349
  const { path, value } = JSON.parse(fields['@context:prepend']);
350
350
  const pathParts = path.split('.');
351
- const replayId = Object.keys(fields).find(k => k.includes('-') && k !== '@context:prepend');
351
+ const replayId = Object.keys(fields).find((k) => k.includes('-') && k !== '@context:prepend');
352
352
  const params = [];
353
353
  let sql = '';
354
354
  if (replayId) {
@@ -396,7 +396,7 @@ function createJsonbOperations(context) {
396
396
  const tableName = context.tableForKey(key, 'hash');
397
397
  const { path, index } = JSON.parse(fields['@context:remove']);
398
398
  const pathParts = path.split('.');
399
- const replayId = Object.keys(fields).find(k => k.includes('-') && k !== '@context:remove');
399
+ const replayId = Object.keys(fields).find((k) => k.includes('-') && k !== '@context:remove');
400
400
  const params = [];
401
401
  let sql = '';
402
402
  if (replayId) {
@@ -458,7 +458,7 @@ function createJsonbOperations(context) {
458
458
  const tableName = context.tableForKey(key, 'hash');
459
459
  const { path, value } = JSON.parse(fields['@context:increment']);
460
460
  const pathParts = path.split('.');
461
- const replayId = Object.keys(fields).find(k => k.includes('-') && k !== '@context:increment');
461
+ const replayId = Object.keys(fields).find((k) => k.includes('-') && k !== '@context:increment');
462
462
  const params = [];
463
463
  let sql = '';
464
464
  if (replayId) {
@@ -506,7 +506,7 @@ function createJsonbOperations(context) {
506
506
  const tableName = context.tableForKey(key, 'hash');
507
507
  const path = fields['@context:toggle'];
508
508
  const pathParts = path.split('.');
509
- const replayId = Object.keys(fields).find(k => k.includes('-') && k !== '@context:toggle');
509
+ const replayId = Object.keys(fields).find((k) => k.includes('-') && k !== '@context:toggle');
510
510
  const params = [];
511
511
  let sql = '';
512
512
  if (replayId) {
@@ -554,7 +554,7 @@ function createJsonbOperations(context) {
554
554
  const tableName = context.tableForKey(key, 'hash');
555
555
  const { path, value } = JSON.parse(fields['@context:setIfNotExists']);
556
556
  const pathParts = path.split('.');
557
- const replayId = Object.keys(fields).find(k => k.includes('-') && k !== '@context:setIfNotExists');
557
+ const replayId = Object.keys(fields).find((k) => k.includes('-') && k !== '@context:setIfNotExists');
558
558
  const params = [];
559
559
  let sql = '';
560
560
  if (replayId) {
@@ -598,7 +598,7 @@ function createJsonbOperations(context) {
598
598
  }
599
599
  function handleContextGetPath(key, fields, options) {
600
600
  const tableName = context.tableForKey(key, 'hash');
601
- const getField = Object.keys(fields).find(k => k.startsWith('@context:get:'));
601
+ const getField = Object.keys(fields).find((k) => k.startsWith('@context:get:'));
602
602
  const pathKey = getField.replace('@context:get:', '');
603
603
  const pathParts = JSON.parse(fields[getField]);
604
604
  const params = [];
@@ -627,7 +627,7 @@ function createJsonbOperations(context) {
627
627
  function handleContextGet(key, fields, options) {
628
628
  const tableName = context.tableForKey(key, 'hash');
629
629
  const path = fields['@context:get'];
630
- const replayId = Object.keys(fields).find(k => k.includes('-') && k !== '@context:get');
630
+ const replayId = Object.keys(fields).find((k) => k.includes('-') && k !== '@context:get');
631
631
  const params = [];
632
632
  let sql = '';
633
633
  if (path === '') {
@@ -1053,14 +1053,14 @@ class PostgresStoreService extends __1.StoreService {
1053
1053
  this.logger.info('postgres-time-notifications-deployed', {
1054
1054
  appId,
1055
1055
  schemaName,
1056
- message: 'Time-aware notifications ENABLED - using LISTEN/NOTIFY instead of polling'
1056
+ message: 'Time-aware notifications ENABLED - using LISTEN/NOTIFY instead of polling',
1057
1057
  });
1058
1058
  }
1059
1059
  catch (error) {
1060
1060
  this.logger.error('postgres-time-notifications-deploy-error', {
1061
1061
  appId,
1062
1062
  schemaName,
1063
- error: error.message
1063
+ error: error.message,
1064
1064
  });
1065
1065
  // Don't throw - fall back to polling mode
1066
1066
  }
@@ -1084,13 +1084,13 @@ class PostgresStoreService extends __1.StoreService {
1084
1084
  // This is likely a notification from sub or stream provider, ignore it
1085
1085
  this.logger.debug('postgres-store-ignoring-non-time-notification', {
1086
1086
  channel: notification.channel,
1087
- payloadPreview: notification.payload.substring(0, 100)
1087
+ payloadPreview: notification.payload.substring(0, 100),
1088
1088
  });
1089
1089
  }
1090
1090
  });
1091
1091
  this.logger.debug('postgres-time-scout-notifications-started', {
1092
1092
  appId: this.appId,
1093
- channelName
1093
+ channelName,
1094
1094
  });
1095
1095
  // Start the enhanced time scout loop
1096
1096
  await this.processTimeHooksWithNotifications(timeEventCallback);
@@ -1098,7 +1098,7 @@ class PostgresStoreService extends __1.StoreService {
1098
1098
  catch (error) {
1099
1099
  this.logger.error('postgres-time-scout-notifications-error', {
1100
1100
  appId: this.appId,
1101
- error
1101
+ error,
1102
1102
  });
1103
1103
  // Fall back to regular polling mode
1104
1104
  throw error;
@@ -1118,7 +1118,7 @@ class PostgresStoreService extends __1.StoreService {
1118
1118
  type,
1119
1119
  appId: app_id,
1120
1120
  nextAwakening: next_awakening,
1121
- readyAt: ready_at
1121
+ readyAt: ready_at,
1122
1122
  });
1123
1123
  if (type === 'time_hooks_ready') {
1124
1124
  // Process any ready time hooks immediately
@@ -1132,7 +1132,7 @@ class PostgresStoreService extends __1.StoreService {
1132
1132
  catch (error) {
1133
1133
  this.logger.error('postgres-time-notification-handle-error', {
1134
1134
  notification,
1135
- error
1135
+ error,
1136
1136
  });
1137
1137
  }
1138
1138
  }
@@ -1233,7 +1233,7 @@ class PostgresStoreService extends __1.StoreService {
1233
1233
  // For now, just log the schedule update
1234
1234
  this.logger.debug('postgres-time-schedule-updated', {
1235
1235
  nextAwakening,
1236
- currentTime: Date.now()
1236
+ currentTime: Date.now(),
1237
1237
  });
1238
1238
  }
1239
1239
  /**
@@ -62,16 +62,17 @@ class PostgresStreamService extends index_1.StreamService {
62
62
  if (!clientNotificationConsumers) {
63
63
  return;
64
64
  }
65
- for (const [consumerKey, instanceMap] of clientNotificationConsumers.entries()) {
65
+ for (const [consumerKey, instanceMap,] of clientNotificationConsumers.entries()) {
66
66
  for (const [instance, consumer] of instanceMap.entries()) {
67
- if (consumer.isListening && now - consumer.lastFallbackCheck > this.getFallbackInterval()) {
67
+ if (consumer.isListening &&
68
+ now - consumer.lastFallbackCheck > this.getFallbackInterval()) {
68
69
  try {
69
70
  const messages = await instance.fetchMessages(consumer.streamName, consumer.groupName, consumer.consumerName, { batchSize: 10, enableBackoff: false, maxRetries: 1 });
70
71
  if (messages.length > 0) {
71
72
  instance.logger.debug('postgres-stream-fallback-messages', {
72
73
  streamName: consumer.streamName,
73
74
  groupName: consumer.groupName,
74
- messageCount: messages.length
75
+ messageCount: messages.length,
75
76
  });
76
77
  consumer.callback(messages);
77
78
  }
@@ -81,7 +82,7 @@ class PostgresStreamService extends index_1.StreamService {
81
82
  instance.logger.error('postgres-stream-fallback-error', {
82
83
  streamName: consumer.streamName,
83
84
  groupName: consumer.groupName,
84
- error
85
+ error,
85
86
  });
86
87
  }
87
88
  }
@@ -96,17 +97,19 @@ class PostgresStreamService extends index_1.StreamService {
96
97
  // This is likely a pub/sub notification from the sub provider, ignore it
97
98
  this.logger.debug('postgres-stream-ignoring-sub-notification', {
98
99
  channel: notification.channel,
99
- payloadPreview: notification.payload.substring(0, 100)
100
+ payloadPreview: notification.payload.substring(0, 100),
100
101
  });
101
102
  return;
102
103
  }
103
104
  this.logger.debug('postgres-stream-processing-notification', {
104
- channel: notification.channel
105
+ channel: notification.channel,
105
106
  });
106
107
  const payload = JSON.parse(notification.payload);
107
108
  const { stream_name, group_name } = payload;
108
109
  if (!stream_name || !group_name) {
109
- this.logger.warn('postgres-stream-invalid-notification', { notification });
110
+ this.logger.warn('postgres-stream-invalid-notification', {
111
+ notification,
112
+ });
110
113
  return;
111
114
  }
112
115
  const consumerKey = this.getConsumerKey(stream_name, group_name);
@@ -128,7 +131,7 @@ class PostgresStreamService extends index_1.StreamService {
128
131
  catch (error) {
129
132
  this.logger.error('postgres-stream-notification-parse-error', {
130
133
  notification,
131
- error
134
+ error,
132
135
  });
133
136
  }
134
137
  }
@@ -143,7 +146,7 @@ class PostgresStreamService extends index_1.StreamService {
143
146
  this.logger.error('postgres-stream-fetch-deliver-error', {
144
147
  streamName: consumer.streamName,
145
148
  groupName: consumer.groupName,
146
- error
149
+ error,
147
150
  });
148
151
  }
149
152
  }
@@ -298,7 +301,7 @@ class PostgresStreamService extends index_1.StreamService {
298
301
  streamName,
299
302
  groupName,
300
303
  channelName,
301
- listenDuration: Date.now() - listenStart
304
+ listenDuration: Date.now() - listenStart,
302
305
  });
303
306
  }
304
307
  catch (error) {
@@ -306,7 +309,7 @@ class PostgresStreamService extends index_1.StreamService {
306
309
  streamName,
307
310
  groupName,
308
311
  channelName,
309
- error
312
+ error,
310
313
  });
311
314
  // Fall back to polling if LISTEN fails
312
315
  return this.fetchMessages(streamName, groupName, consumerName, options);
@@ -319,7 +322,7 @@ class PostgresStreamService extends index_1.StreamService {
319
322
  consumerName,
320
323
  callback,
321
324
  isListening: true,
322
- lastFallbackCheck: Date.now()
325
+ lastFallbackCheck: Date.now(),
323
326
  };
324
327
  instanceMap.set(this, consumer);
325
328
  // Track this consumer for cleanup
@@ -328,7 +331,7 @@ class PostgresStreamService extends index_1.StreamService {
328
331
  streamName,
329
332
  groupName,
330
333
  instanceCount: instanceMap.size,
331
- setupDuration: Date.now() - startTime
334
+ setupDuration: Date.now() - startTime,
332
335
  });
333
336
  // Do an initial fetch asynchronously to avoid blocking setup
334
337
  // This ensures we don't miss any messages that were already in the queue
@@ -338,13 +341,13 @@ class PostgresStreamService extends index_1.StreamService {
338
341
  const initialMessages = await this.fetchMessages(streamName, groupName, consumerName, {
339
342
  ...options,
340
343
  enableBackoff: false,
341
- maxRetries: 1
344
+ maxRetries: 1,
342
345
  });
343
346
  this.logger.debug('postgres-stream-initial-fetch-complete', {
344
347
  streamName,
345
348
  groupName,
346
349
  messageCount: initialMessages.length,
347
- fetchDuration: Date.now() - fetchStart
350
+ fetchDuration: Date.now() - fetchStart,
348
351
  });
349
352
  // If we got messages, call the callback
350
353
  if (initialMessages.length > 0) {
@@ -355,7 +358,7 @@ class PostgresStreamService extends index_1.StreamService {
355
358
  this.logger.error('postgres-stream-initial-fetch-error', {
356
359
  streamName,
357
360
  groupName,
358
- error
361
+ error,
359
362
  });
360
363
  }
361
364
  });
@@ -387,7 +390,7 @@ class PostgresStreamService extends index_1.StreamService {
387
390
  this.logger.debug('postgres-stream-unlisten', {
388
391
  streamName,
389
392
  groupName,
390
- channelName
393
+ channelName,
391
394
  });
392
395
  }
393
396
  catch (error) {
@@ -395,7 +398,7 @@ class PostgresStreamService extends index_1.StreamService {
395
398
  streamName,
396
399
  groupName,
397
400
  channelName,
398
- error
401
+ error,
399
402
  });
400
403
  }
401
404
  }
@@ -583,7 +586,7 @@ class PostgresStreamService extends index_1.StreamService {
583
586
  this.logger.debug('postgres-stream-cleanup-unlisten', {
584
587
  streamName: consumer.streamName,
585
588
  groupName: consumer.groupName,
586
- channelName
589
+ channelName,
587
590
  });
588
591
  }
589
592
  catch (error) {
@@ -591,7 +594,7 @@ class PostgresStreamService extends index_1.StreamService {
591
594
  streamName: consumer.streamName,
592
595
  groupName: consumer.groupName,
593
596
  channelName,
594
- error
597
+ error,
595
598
  });
596
599
  }
597
600
  }
@@ -37,7 +37,7 @@ class PostgresSubService extends index_1.SubService {
37
37
  try {
38
38
  const payload = JSON.parse(msg.payload || '{}');
39
39
  // Call all callbacks registered for this channel across all SubService instances
40
- callbacks.forEach(callback => {
40
+ callbacks.forEach((callback) => {
41
41
  try {
42
42
  callback(msg.channel, payload);
43
43
  }
@@ -101,7 +101,11 @@ class PostgresSubService extends index_1.SubService {
101
101
  callbacks.set(this, callback);
102
102
  // Track this subscription for cleanup
103
103
  this.instanceSubscriptions.add(safeKey);
104
- this.logger.debug(`postgres-subscribe`, { originalKey, safeKey, totalCallbacks: callbacks.size });
104
+ this.logger.debug(`postgres-subscribe`, {
105
+ originalKey,
106
+ safeKey,
107
+ totalCallbacks: callbacks.size,
108
+ });
105
109
  }
106
110
  async unsubscribe(keyType, appId, topic) {
107
111
  const [originalKey, safeKey] = this.mintSafeKey(keyType, {
@@ -125,7 +129,11 @@ class PostgresSubService extends index_1.SubService {
125
129
  clientSubscriptions.delete(safeKey);
126
130
  await this.eventClient.query(`UNLISTEN "${safeKey}"`);
127
131
  }
128
- this.logger.debug(`postgres-unsubscribe`, { originalKey, safeKey, remainingCallbacks: callbacks.size });
132
+ this.logger.debug(`postgres-unsubscribe`, {
133
+ originalKey,
134
+ safeKey,
135
+ remainingCallbacks: callbacks.size,
136
+ });
129
137
  }
130
138
  /**
131
139
  * Cleanup method to remove all subscriptions for this instance.
@@ -211,7 +211,7 @@ class TaskService {
211
211
  try {
212
212
  this.logger.info('task-using-notification-mode', {
213
213
  appId: this.store.appId,
214
- message: 'Time scout using PostgreSQL LISTEN/NOTIFY mode for efficient task processing'
214
+ message: 'Time scout using PostgreSQL LISTEN/NOTIFY mode for efficient task processing',
215
215
  });
216
216
  // Use the PostgreSQL store's notification-based approach
217
217
  await this.store.startTimeScoutWithNotifications(timeEventCallback);
@@ -221,7 +221,7 @@ class TaskService {
221
221
  appId: this.store.appId,
222
222
  error: error.message,
223
223
  fallbackTo: 'polling',
224
- message: 'Notification mode failed - falling back to traditional polling'
224
+ message: 'Notification mode failed - falling back to traditional polling',
225
225
  });
226
226
  // Fall back to regular polling
227
227
  await this.processTimeHooks(timeEventCallback);
@@ -231,7 +231,7 @@ class TaskService {
231
231
  this.logger.info('task-using-polling-mode', {
232
232
  appId: this.store.appId,
233
233
  storeType: this.store.constructor.name,
234
- message: 'Time scout using traditional polling mode (notifications not available)'
234
+ message: 'Time scout using traditional polling mode (notifications not available)',
235
235
  });
236
236
  // Use regular polling for non-PostgreSQL stores
237
237
  await this.processTimeHooks(timeEventCallback);
@@ -247,7 +247,7 @@ class TaskService {
247
247
  * Check if the store supports notifications
248
248
  */
249
249
  supportsNotifications() {
250
- return typeof this.store.startTimeScoutWithNotifications === 'function';
250
+ return (typeof this.store.startTimeScoutWithNotifications === 'function');
251
251
  }
252
252
  }
253
253
  exports.TaskService = TaskService;
@@ -495,4 +495,82 @@ interface ClientWorkflow {
495
495
  getHandle(taskQueue: string, workflowName: string, workflowId: string, namespace?: string): Promise<WorkflowHandleService>;
496
496
  search(taskQueue: string, workflowName: string, namespace: string | null, index: string, ...query: string[]): Promise<string[]>;
497
497
  }
498
+ /**
499
+ * Workflow interceptor that can wrap workflow execution in an onion-like pattern.
500
+ * Each interceptor wraps the next one, with the actual workflow execution at the center.
501
+ *
502
+ * Interceptors are executed in the order they are registered. Each interceptor can:
503
+ * - Perform actions before workflow execution
504
+ * - Modify or enhance the workflow context
505
+ * - Handle or transform workflow results
506
+ * - Catch and handle errors
507
+ * - Add cross-cutting concerns like logging, metrics, or tracing
508
+ *
509
+ * @example
510
+ * ```typescript
511
+ * // Simple logging interceptor
512
+ * const loggingInterceptor: WorkflowInterceptor = {
513
+ * async execute(ctx, next) {
514
+ * console.log('Before workflow');
515
+ * try {
516
+ * const result = await next();
517
+ * console.log('After workflow');
518
+ * return result;
519
+ * } catch (err) {
520
+ * console.error('Workflow error:', err);
521
+ * throw err;
522
+ * }
523
+ * }
524
+ * };
525
+ *
526
+ * // Register the interceptor
527
+ * MemFlow.registerInterceptor(loggingInterceptor);
528
+ * ```
529
+ */
530
+ export interface WorkflowInterceptor {
531
+ /**
532
+ * Called before workflow execution to wrap the workflow in custom logic
533
+ *
534
+ * @param ctx - The workflow context map containing workflow metadata and state
535
+ * @param next - Function to call the next interceptor or the workflow itself
536
+ * @returns The result of the workflow execution
537
+ *
538
+ * @example
539
+ * ```typescript
540
+ * // Metrics interceptor implementation
541
+ * {
542
+ * async execute(ctx, next) {
543
+ * const workflowName = ctx.get('workflowName');
544
+ * const metrics = getMetricsClient();
545
+ *
546
+ * metrics.increment(`workflow.start.${workflowName}`);
547
+ * const timer = metrics.startTimer();
548
+ *
549
+ * try {
550
+ * const result = await next();
551
+ * metrics.increment(`workflow.success.${workflowName}`);
552
+ * return result;
553
+ * } catch (err) {
554
+ * metrics.increment(`workflow.error.${workflowName}`);
555
+ * throw err;
556
+ * } finally {
557
+ * timer.end();
558
+ * }
559
+ * }
560
+ * }
561
+ * ```
562
+ */
563
+ execute(ctx: Map<string, any>, next: () => Promise<any>): Promise<any>;
564
+ }
565
+ /**
566
+ * Registry for workflow interceptors that are executed in order
567
+ * for each workflow execution
568
+ */
569
+ export interface InterceptorRegistry {
570
+ /**
571
+ * Array of registered interceptors that will wrap workflow execution
572
+ * in the order they were registered (first registered = outermost wrapper)
573
+ */
574
+ interceptors: WorkflowInterceptor[];
575
+ }
498
576
  export { ActivityConfig, ActivityWorkflowDataType, ChildResponseType, ClientConfig, ClientWorkflow, ContextType, Connection, ProxyResponseType, ProxyType, Registry, SignalOptions, FindJobsOptions, FindOptions, FindWhereOptions, FindWhereQuery, HookOptions, SearchResults, WorkerConfig, WorkflowConfig, WorkerOptions, WorkflowSearchOptions, WorkflowDataType, WorkflowOptions, WorkflowContext, };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hotmeshio/hotmesh",
3
- "version": "0.5.4",
3
+ "version": "0.5.6",
4
4
  "description": "Permanent-Memory Workflows & AI Agents",
5
5
  "main": "./build/index.js",
6
6
  "types": "./build/index.d.ts",
@@ -31,7 +31,8 @@
31
31
  "test:memflow:basic": "HMSH_LOGLEVEL=info NODE_ENV=test jest ./tests/memflow/basic/postgres.test.ts --detectOpenHandles --forceExit --verbose",
32
32
  "test:memflow:collision": "NODE_ENV=test jest ./tests/memflow/collision/*.test.ts --detectOpenHandles --forceExit --verbose",
33
33
  "test:memflow:fatal": "NODE_ENV=test jest ./tests/memflow/fatal/*.test.ts --detectOpenHandles --forceExit --verbose",
34
- "test:memflow:goodbye": "NODE_ENV=test jest ./tests/memflow/goodbye/*.test.ts --detectOpenHandles --forceExit --verbose",
34
+ "test:memflow:goodbye": "NODE_ENV=test HMSH_LOGLEVEL=debug jest ./tests/memflow/goodbye/postgres.test.ts --detectOpenHandles --forceExit --verbose",
35
+ "test:memflow:interceptor": "NODE_ENV=test HMSH_LOGLEVEL=debug jest ./tests/memflow/interceptor/postgres.test.ts --detectOpenHandles --forceExit --verbose",
35
36
  "test:memflow:entity": "NODE_ENV=test HMSH_LOGLEVEL=debug jest ./tests/memflow/entity/postgres.test.ts --detectOpenHandles --forceExit --verbose",
36
37
  "test:memflow:agent": "NODE_ENV=test HMSH_LOGLEVEL=debug jest ./tests/memflow/agent/postgres.test.ts --detectOpenHandles --forceExit --verbose",
37
38
  "test:memflow:hello": "HMSH_TELEMETRY=debug HMSH_LOGLEVEL=debug HMSH_IS_CLUSTER=true NODE_ENV=test jest ./tests/memflow/helloworld/postgres.test.ts --detectOpenHandles --forceExit --verbose",