@hotmeshio/hotmesh 0.0.56 → 0.0.58

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 (91) hide show
  1. package/README.md +10 -10
  2. package/build/modules/enums.js +10 -1
  3. package/build/modules/key.d.ts +38 -0
  4. package/build/modules/key.js +46 -4
  5. package/build/modules/utils.d.ts +9 -0
  6. package/build/modules/utils.js +19 -1
  7. package/build/package.json +1 -1
  8. package/build/services/activities/activity.d.ts +28 -0
  9. package/build/services/activities/activity.js +46 -1
  10. package/build/services/activities/await.js +4 -0
  11. package/build/services/activities/cycle.d.ts +7 -0
  12. package/build/services/activities/cycle.js +16 -1
  13. package/build/services/activities/hook.d.ts +6 -0
  14. package/build/services/activities/hook.js +12 -2
  15. package/build/services/activities/interrupt.js +8 -0
  16. package/build/services/activities/signal.d.ts +6 -0
  17. package/build/services/activities/signal.js +15 -0
  18. package/build/services/activities/trigger.d.ts +4 -0
  19. package/build/services/activities/trigger.js +7 -1
  20. package/build/services/activities/worker.js +4 -0
  21. package/build/services/collator/index.d.ts +70 -0
  22. package/build/services/collator/index.js +91 -1
  23. package/build/services/compiler/deployer.js +38 -6
  24. package/build/services/compiler/index.d.ts +15 -0
  25. package/build/services/compiler/index.js +20 -0
  26. package/build/services/compiler/validator.d.ts +3 -0
  27. package/build/services/compiler/validator.js +25 -0
  28. package/build/services/connector/clients/ioredis.js +2 -0
  29. package/build/services/connector/clients/redis.js +2 -0
  30. package/build/services/connector/index.js +2 -0
  31. package/build/services/durable/client.d.ts +20 -0
  32. package/build/services/durable/client.js +25 -0
  33. package/build/services/durable/exporter.d.ts +22 -0
  34. package/build/services/durable/exporter.js +30 -1
  35. package/build/services/durable/handle.d.ts +36 -0
  36. package/build/services/durable/handle.js +46 -0
  37. package/build/services/durable/index.d.ts +4 -0
  38. package/build/services/durable/index.js +4 -0
  39. package/build/services/durable/schemas/factory.d.ts +29 -0
  40. package/build/services/durable/schemas/factory.js +29 -0
  41. package/build/services/durable/search.d.ts +97 -0
  42. package/build/services/durable/search.js +108 -10
  43. package/build/services/durable/worker.js +35 -6
  44. package/build/services/durable/workflow.d.ts +118 -0
  45. package/build/services/durable/workflow.js +153 -6
  46. package/build/services/engine/index.d.ts +5 -0
  47. package/build/services/engine/index.js +43 -1
  48. package/build/services/exporter/index.d.ts +27 -0
  49. package/build/services/exporter/index.js +33 -0
  50. package/build/services/hotmesh/index.js +8 -0
  51. package/build/services/logger/index.js +2 -0
  52. package/build/services/mapper/index.d.ts +14 -0
  53. package/build/services/mapper/index.js +14 -0
  54. package/build/services/pipe/functions/date.d.ts +7 -0
  55. package/build/services/pipe/functions/date.js +7 -0
  56. package/build/services/pipe/functions/math.js +2 -0
  57. package/build/services/pipe/index.d.ts +15 -0
  58. package/build/services/pipe/index.js +23 -2
  59. package/build/services/quorum/index.d.ts +7 -0
  60. package/build/services/quorum/index.js +21 -0
  61. package/build/services/reporter/index.d.ts +5 -0
  62. package/build/services/reporter/index.js +9 -0
  63. package/build/services/router/index.d.ts +9 -0
  64. package/build/services/router/index.js +30 -2
  65. package/build/services/serializer/index.js +23 -6
  66. package/build/services/store/cache.d.ts +19 -0
  67. package/build/services/store/cache.js +19 -0
  68. package/build/services/store/clients/ioredis.js +1 -0
  69. package/build/services/store/index.d.ts +55 -0
  70. package/build/services/store/index.js +81 -5
  71. package/build/services/stream/clients/ioredis.js +4 -1
  72. package/build/services/task/index.d.ts +9 -0
  73. package/build/services/task/index.js +31 -0
  74. package/build/services/telemetry/index.d.ts +7 -0
  75. package/build/services/telemetry/index.js +13 -1
  76. package/build/services/worker/index.d.ts +4 -0
  77. package/build/services/worker/index.js +6 -2
  78. package/build/types/activity.d.ts +81 -0
  79. package/build/types/durable.d.ts +256 -0
  80. package/build/types/exporter.d.ts +13 -0
  81. package/build/types/hotmesh.d.ts +10 -1
  82. package/build/types/hotmesh.js +3 -0
  83. package/build/types/index.js +1 -1
  84. package/build/types/job.d.ts +85 -0
  85. package/build/types/pipe.d.ts +65 -0
  86. package/build/types/quorum.d.ts +14 -0
  87. package/build/types/redis.d.ts +6 -0
  88. package/build/types/stream.d.ts +58 -0
  89. package/build/types/stream.js +4 -0
  90. package/package.json +1 -1
  91. package/types/durable.ts +10 -1
@@ -10,11 +10,47 @@ export declare class WorkflowHandleService {
10
10
  workflowId: string;
11
11
  constructor(hotMesh: HotMesh, workflowTopic: string, workflowId: string);
12
12
  export(options?: ExportOptions): Promise<DurableJobExport>;
13
+ /**
14
+ * Sends a signal to the workflow. This is a way to send
15
+ * a message to a workflow that is paused due to having
16
+ * executed `Durable.workflow.waitFor`. The workflow
17
+ * will awaken if no other signals are pending.
18
+ */
13
19
  signal(signalId: string, data: Record<any, any>): Promise<void>;
20
+ /**
21
+ * Returns the job state of the workflow. If the workflow has completed
22
+ * this is also the job output. If the workflow is still running, this
23
+ * is the current state of the job, but it may change depending upon
24
+ * the activities that remain.
25
+ */
14
26
  state(metadata?: boolean): Promise<Record<string, any>>;
27
+ /**
28
+ * Returns the current search state of the workflow. This is
29
+ * different than the job state or individual activity state.
30
+ * Search state represents name/value pairs that were added
31
+ * to the workflow. As the workflow is stored in a Redis hash,
32
+ * this is a way to store additional data that is indexed
33
+ * and searchable using the RediSearch module.
34
+ */
15
35
  queryState(fields: string[]): Promise<Record<string, any>>;
36
+ /**
37
+ * Returns the current status of the workflow. This is a semaphore
38
+ * value that represents the current state of the workflow, where
39
+ * 0 is complete and a negative value represents that the flow was
40
+ * interrupted.
41
+ */
16
42
  status(): Promise<number>;
43
+ /**
44
+ * Interrupts a running workflow. Standard Job Completion tasks will
45
+ * run. Subscribers will be notified and the job hash will be expired.
46
+ */
17
47
  interrupt(options?: JobInterruptOptions): Promise<string>;
48
+ /**
49
+ * Waits for the workflow to complete and returns the result. If
50
+ * the workflow response includes an error, this method will rethrow
51
+ * the error, including the stack trace if available.
52
+ * Wrap calls in a try/catch as necessary to avoid unhandled exceptions.
53
+ */
18
54
  result<T>(config?: {
19
55
  state?: boolean;
20
56
  throwOnError?: boolean;
@@ -12,9 +12,21 @@ class WorkflowHandleService {
12
12
  async export(options) {
13
13
  return this.exporter.export(this.workflowId, options);
14
14
  }
15
+ /**
16
+ * Sends a signal to the workflow. This is a way to send
17
+ * a message to a workflow that is paused due to having
18
+ * executed `Durable.workflow.waitFor`. The workflow
19
+ * will awaken if no other signals are pending.
20
+ */
15
21
  async signal(signalId, data) {
16
22
  await this.hotMesh.hook(`${this.hotMesh.appId}.wfs.signal`, { id: signalId, data });
17
23
  }
24
+ /**
25
+ * Returns the job state of the workflow. If the workflow has completed
26
+ * this is also the job output. If the workflow is still running, this
27
+ * is the current state of the job, but it may change depending upon
28
+ * the activities that remain.
29
+ */
18
30
  async state(metadata = false) {
19
31
  const state = await this.hotMesh.getState(`${this.hotMesh.appId}.execute`, this.workflowId);
20
32
  if (!state.data && state.metadata.err) {
@@ -22,25 +34,56 @@ class WorkflowHandleService {
22
34
  }
23
35
  return metadata ? state : state.data;
24
36
  }
37
+ /**
38
+ * Returns the current search state of the workflow. This is
39
+ * different than the job state or individual activity state.
40
+ * Search state represents name/value pairs that were added
41
+ * to the workflow. As the workflow is stored in a Redis hash,
42
+ * this is a way to store additional data that is indexed
43
+ * and searchable using the RediSearch module.
44
+ */
25
45
  async queryState(fields) {
26
46
  return await this.hotMesh.getQueryState(this.workflowId, fields);
27
47
  }
48
+ /**
49
+ * Returns the current status of the workflow. This is a semaphore
50
+ * value that represents the current state of the workflow, where
51
+ * 0 is complete and a negative value represents that the flow was
52
+ * interrupted.
53
+ */
28
54
  async status() {
29
55
  return await this.hotMesh.getStatus(this.workflowId);
30
56
  }
57
+ /**
58
+ * Interrupts a running workflow. Standard Job Completion tasks will
59
+ * run. Subscribers will be notified and the job hash will be expired.
60
+ */
31
61
  async interrupt(options) {
32
62
  return await this.hotMesh.interrupt(`${this.hotMesh.appId}.execute`, this.workflowId, options);
33
63
  }
64
+ /**
65
+ * Waits for the workflow to complete and returns the result. If
66
+ * the workflow response includes an error, this method will rethrow
67
+ * the error, including the stack trace if available.
68
+ * Wrap calls in a try/catch as necessary to avoid unhandled exceptions.
69
+ */
34
70
  async result(config) {
35
71
  const topic = `${this.hotMesh.appId}.executed.${this.workflowId}`;
36
72
  let isResolved = false;
37
73
  return new Promise(async (resolve, reject) => {
74
+ /**
75
+ * rejects/resolves the promise based on the `throwOnError`
76
+ * default behavior is to throw if error
77
+ */
38
78
  const safeReject = (err) => {
39
79
  if (config?.throwOnError === false) {
40
80
  return resolve(err);
41
81
  }
42
82
  reject(err);
43
83
  };
84
+ /**
85
+ * Common completion function that unsubscribes from the topic/returns
86
+ */
44
87
  const complete = async (response, err) => {
45
88
  if (isResolved)
46
89
  return;
@@ -63,6 +106,7 @@ class WorkflowHandleService {
63
106
  }
64
107
  resolve(response);
65
108
  };
109
+ //more expensive; fetches the entire job, not just the `status`
66
110
  if (config?.state) {
67
111
  const state = await this.hotMesh.getState(`${this.hotMesh.appId}.execute`, this.workflowId);
68
112
  if (state?.data?.done && !state.data?.$error) {
@@ -75,6 +119,7 @@ class WorkflowHandleService {
75
119
  return complete(null, JSON.parse(state.metadata.err));
76
120
  }
77
121
  }
122
+ //subscribe to 'done' topic
78
123
  this.hotMesh.sub(topic, async (_topic, state) => {
79
124
  this.hotMesh.unsub(topic);
80
125
  if (state.data.done && !state.data?.$error) {
@@ -88,6 +133,7 @@ class WorkflowHandleService {
88
133
  return await complete(null, error);
89
134
  }
90
135
  });
136
+ //check state in case completed during wiring
91
137
  const status = await this.hotMesh.getStatus(this.workflowId);
92
138
  if (status <= 0) {
93
139
  await complete();
@@ -10,6 +10,10 @@ export declare const Durable: {
10
10
  Search: typeof Search;
11
11
  Worker: typeof WorkerService;
12
12
  workflow: typeof WorkflowService;
13
+ /**
14
+ * Shutdown everything. All connections, workers, and clients will be closed.
15
+ * Include in your signal handlers to ensure a clean shutdown.
16
+ */
13
17
  shutdown(): Promise<void>;
14
18
  };
15
19
  export type { ContextType };
@@ -13,6 +13,10 @@ exports.Durable = {
13
13
  Search: search_1.Search,
14
14
  Worker: worker_1.WorkerService,
15
15
  workflow: workflow_1.WorkflowService,
16
+ /**
17
+ * Shutdown everything. All connections, workers, and clients will be closed.
18
+ * Include in your signal handlers to ensure a clean shutdown.
19
+ */
16
20
  async shutdown() {
17
21
  await client_1.ClientService.shutdown();
18
22
  await worker_1.WorkerService.shutdown();
@@ -1,4 +1,33 @@
1
+ /**
2
+ *********** HOTMESH 'DURABLE' MODULE APPLICATION GRAPH **********
3
+ *
4
+ * This HotMesh application spec uses 50 activities and 25 transitions
5
+ * to model and emulate the Temporal Application & Query servers using
6
+ * Redis as the backend.
7
+ *
8
+ * It's particularly useful for organizations with high-speed, high-volume
9
+ * use cases as it uses in-memory Redis Streams for transactional,
10
+ * workflow processing, while adhering to Temporal's developer-friendly syntax.
11
+ *
12
+ * This YAML file can also serve as a useful starting point for building
13
+ * Integration/BPM/Workflow servers in general (MuleSoft, etc) without the need
14
+ * for a physical application server.
15
+ *
16
+ * Possible use cases include:
17
+ * * Orchestration servers
18
+ * * Integration servers
19
+ * * BPMN engines
20
+ * * Reentrant process servers
21
+ * * Service Meshes
22
+ * * Master Data Management systems
23
+ */
1
24
  declare const APP_VERSION = "1";
2
25
  declare const APP_ID = "durable";
26
+ /**
27
+ * returns a new durable workflow schema
28
+ * @param {string} app - app name (e.g., 'durable')
29
+ * @param {string} version - number as string (e.g., '1')
30
+ * @returns {string} HotMesh App YAML
31
+ */
3
32
  declare const getWorkflowYAML: (app: string, version: string) => string;
4
33
  export { getWorkflowYAML, APP_VERSION, APP_ID, };
@@ -1,10 +1,39 @@
1
1
  "use strict";
2
+ /**
3
+ *********** HOTMESH 'DURABLE' MODULE APPLICATION GRAPH **********
4
+ *
5
+ * This HotMesh application spec uses 50 activities and 25 transitions
6
+ * to model and emulate the Temporal Application & Query servers using
7
+ * Redis as the backend.
8
+ *
9
+ * It's particularly useful for organizations with high-speed, high-volume
10
+ * use cases as it uses in-memory Redis Streams for transactional,
11
+ * workflow processing, while adhering to Temporal's developer-friendly syntax.
12
+ *
13
+ * This YAML file can also serve as a useful starting point for building
14
+ * Integration/BPM/Workflow servers in general (MuleSoft, etc) without the need
15
+ * for a physical application server.
16
+ *
17
+ * Possible use cases include:
18
+ * * Orchestration servers
19
+ * * Integration servers
20
+ * * BPMN engines
21
+ * * Reentrant process servers
22
+ * * Service Meshes
23
+ * * Master Data Management systems
24
+ */
2
25
  Object.defineProperty(exports, "__esModule", { value: true });
3
26
  exports.APP_ID = exports.APP_VERSION = exports.getWorkflowYAML = void 0;
4
27
  const APP_VERSION = '1';
5
28
  exports.APP_VERSION = APP_VERSION;
6
29
  const APP_ID = 'durable';
7
30
  exports.APP_ID = APP_ID;
31
+ /**
32
+ * returns a new durable workflow schema
33
+ * @param {string} app - app name (e.g., 'durable')
34
+ * @param {string} version - number as string (e.g., '1')
35
+ * @returns {string} HotMesh App YAML
36
+ */
8
37
  const getWorkflowYAML = (app, version) => {
9
38
  return `app:
10
39
  id: ${app}
@@ -10,14 +10,111 @@ export declare class Search {
10
10
  store: StoreService<RedisClient, RedisMulti> | null;
11
11
  cachedFields: Record<string, string>;
12
12
  constructor(workflowId: string, hotMeshClient: HotMesh, searchSessionId: string);
13
+ /**
14
+ * Prefixes the key with an underscore to keep separate from the
15
+ * activity and job history (and searchable via HKEYS)
16
+ * @param {string} key - the key to be sanitized. Wrap in quotes to avoid sanitization.
17
+ * @returns {string} - the sanitized key
18
+ * @private
19
+ */
13
20
  safeKey(key: string): string;
21
+ /**
22
+ * For those deployments with a redis stack backend (with the FT module),
23
+ * this method will configure the search index for the workflow. For all
24
+ * others, this method will exit/fail gracefully and not index
25
+ * the fields in the HASH. All values are searchable via HKEYS/HSC/HGET
26
+ * @param {HotMesh} hotMeshClient - the hotmesh client
27
+ * @param {WorkflowSearchOptions} search - the search options
28
+ * @returns {Promise<void>}
29
+ * @example
30
+ * const search = {
31
+ * index: 'my_search_index',
32
+ * prefix: ['my_workflow_prefix'],
33
+ * schema: {
34
+ * field1: { type: 'TEXT', sortable: true },
35
+ * field2: { type: 'NUMERIC', sortable: true }
36
+ * }
37
+ * }
38
+ * await Search.configureSearchIndex(hotMeshClient, search);
39
+ */
14
40
  static configureSearchIndex(hotMeshClient: HotMesh, search?: WorkflowSearchOptions): Promise<void>;
41
+ /**
42
+ * For those deployments with a redis stack backend (with the FT module),
43
+ * this method will list all search indexes.
44
+ *
45
+ * @param {HotMesh} hotMeshClient - the hotmesh client
46
+ * @returns {Promise<string[]>} - the list of search indexes
47
+ * @example
48
+ * const searchIndexes = await Search.listSearchIndexes(hotMeshClient);
49
+ */
15
50
  static listSearchIndexes(hotMeshClient: HotMesh): Promise<string[]>;
51
+ /**
52
+ * increments the index to return a unique search session guid when
53
+ * calling any method that produces side effects (changes the value)
54
+ * @private
55
+ */
16
56
  getSearchSessionGuid(): string;
57
+ /**
58
+ * Sets the fields listed in args. Returns the
59
+ * count of new fields that were set (does not
60
+ * count fields that were updated)
61
+ * @param args
62
+ * @returns {number}
63
+ * @example
64
+ * const search = new Search();
65
+ * const count = await search.set('field1', 'value1', 'field2', 'value2');
66
+ */
17
67
  set(...args: string[]): Promise<number>;
68
+ /**
69
+ * Returns the value of the field in the HASH stored at key.
70
+ * @param key
71
+ * @returns {string}
72
+ * @example
73
+ * const search = new Search();
74
+ * const value = await search.get('field1');
75
+ */
18
76
  get(key: string): Promise<string>;
77
+ /**
78
+ * Returns the values of all specified fields in the HASH stored at key.
79
+ * @param args
80
+ * @returns
81
+ */
19
82
  mget(...args: string[]): Promise<string[]>;
83
+ /**
84
+ * Deletes the fields provided as args. Returns the
85
+ * count of fields that were deleted.
86
+ *
87
+ * @param args
88
+ * @returns {number}
89
+ * @example
90
+ * sont search = new Search();
91
+ * const count = await search.del('field1', 'field2', 'field3');
92
+ */
20
93
  del(...args: string[]): Promise<number | void>;
94
+ /**
95
+ * Increments the value of a float field by the given amount. Returns the
96
+ * new value of the field after the increment. Pass a negative
97
+ * number to decrement the value.
98
+ *
99
+ * @param key - the key to increment
100
+ * @param val - the value to increment by
101
+ * @returns {number} - the new value
102
+ * @example
103
+ * const search = new Search();
104
+ * const count = await search.incr('field1', 1.5);
105
+ */
21
106
  incr(key: string, val: number): Promise<number>;
107
+ /**
108
+ * Multiplies the value of a field by the given amount. Returns the
109
+ * new value of the field after the multiplication. NOTE:
110
+ * this is exponential multiplication.
111
+ *
112
+ * @param key - the key to multiply
113
+ * @param val - the value to multiply by
114
+ * @returns {number} - the new product of the multiplication
115
+ * @example
116
+ * const search = new Search();
117
+ * const product = await search.mult('field1', 1.5);
118
+ */
22
119
  mult(key: string, val: number): Promise<number>;
23
120
  }
@@ -16,31 +16,56 @@ class Search {
16
16
  this.hotMeshClient = hotMeshClient;
17
17
  this.store = hotMeshClient.engine.store;
18
18
  }
19
+ /**
20
+ * Prefixes the key with an underscore to keep separate from the
21
+ * activity and job history (and searchable via HKEYS)
22
+ * @param {string} key - the key to be sanitized. Wrap in quotes to avoid sanitization.
23
+ * @returns {string} - the sanitized key
24
+ * @private
25
+ */
19
26
  safeKey(key) {
20
27
  if (key.startsWith('"')) {
21
28
  return key.slice(1, -1);
22
29
  }
23
30
  return `_${key}`;
24
31
  }
32
+ /**
33
+ * For those deployments with a redis stack backend (with the FT module),
34
+ * this method will configure the search index for the workflow. For all
35
+ * others, this method will exit/fail gracefully and not index
36
+ * the fields in the HASH. All values are searchable via HKEYS/HSC/HGET
37
+ * @param {HotMesh} hotMeshClient - the hotmesh client
38
+ * @param {WorkflowSearchOptions} search - the search options
39
+ * @returns {Promise<void>}
40
+ * @example
41
+ * const search = {
42
+ * index: 'my_search_index',
43
+ * prefix: ['my_workflow_prefix'],
44
+ * schema: {
45
+ * field1: { type: 'TEXT', sortable: true },
46
+ * field2: { type: 'NUMERIC', sortable: true }
47
+ * }
48
+ * }
49
+ * await Search.configureSearchIndex(hotMeshClient, search);
50
+ */
25
51
  static async configureSearchIndex(hotMeshClient, search) {
26
52
  if (search?.schema) {
27
53
  const store = hotMeshClient.engine.store;
28
54
  const schema = [];
29
55
  for (const [key, value] of Object.entries(search.schema)) {
30
56
  if (value.indexed !== false) {
31
- schema.push(`_${key}`);
32
- schema.push(value.type);
33
- if (value.sortable) {
34
- schema.push('SORTABLE');
35
- }
36
- if (value.sortable) {
37
- schema.push('SORTABLE');
38
- }
57
+ schema.push(value.fieldName ? `${value.fieldName.toString()}` : `_${key}`);
58
+ schema.push(value.type ? value.type : 'TEXT');
39
59
  if (value.noindex) {
40
60
  schema.push('NOINDEX');
41
61
  }
42
- if (value.nostem && value.type === 'TEXT') {
43
- schema.push('NOSTEM');
62
+ else {
63
+ if (value.nostem && value.type === 'TEXT') {
64
+ schema.push('NOSTEM');
65
+ }
66
+ if (value.sortable) {
67
+ schema.push('SORTABLE');
68
+ }
44
69
  }
45
70
  }
46
71
  }
@@ -58,6 +83,15 @@ class Search {
58
83
  }
59
84
  }
60
85
  }
86
+ /**
87
+ * For those deployments with a redis stack backend (with the FT module),
88
+ * this method will list all search indexes.
89
+ *
90
+ * @param {HotMesh} hotMeshClient - the hotmesh client
91
+ * @returns {Promise<string[]>} - the list of search indexes
92
+ * @example
93
+ * const searchIndexes = await Search.listSearchIndexes(hotMeshClient);
94
+ */
61
95
  static async listSearchIndexes(hotMeshClient) {
62
96
  try {
63
97
  const store = hotMeshClient.engine.store;
@@ -69,9 +103,25 @@ class Search {
69
103
  return [];
70
104
  }
71
105
  }
106
+ /**
107
+ * increments the index to return a unique search session guid when
108
+ * calling any method that produces side effects (changes the value)
109
+ * @private
110
+ */
72
111
  getSearchSessionGuid() {
112
+ //return the search session as it would exist in the search session index
73
113
  return `${this.searchSessionId}-${this.searchSessionIndex++}-`;
74
114
  }
115
+ /**
116
+ * Sets the fields listed in args. Returns the
117
+ * count of new fields that were set (does not
118
+ * count fields that were updated)
119
+ * @param args
120
+ * @returns {number}
121
+ * @example
122
+ * const search = new Search();
123
+ * const count = await search.set('field1', 'value1', 'field2', 'value2');
124
+ */
75
125
  async set(...args) {
76
126
  const ssGuid = this.getSearchSessionGuid();
77
127
  const store = storage_1.asyncLocalStorage.getStore();
@@ -88,9 +138,18 @@ class Search {
88
138
  return Number(replay[ssGuid]);
89
139
  }
90
140
  const fieldCount = await this.store.exec('HSET', this.jobId, ...safeArgs);
141
+ //no need to wait; set this interim value in the replay
91
142
  this.store.exec('HSET', this.jobId, ssGuid, fieldCount.toString());
92
143
  return Number(fieldCount);
93
144
  }
145
+ /**
146
+ * Returns the value of the field in the HASH stored at key.
147
+ * @param key
148
+ * @returns {string}
149
+ * @example
150
+ * const search = new Search();
151
+ * const value = await search.get('field1');
152
+ */
94
153
  async get(key) {
95
154
  try {
96
155
  if (key in this.cachedFields) {
@@ -105,6 +164,11 @@ class Search {
105
164
  return '';
106
165
  }
107
166
  }
167
+ /**
168
+ * Returns the values of all specified fields in the HASH stored at key.
169
+ * @param args
170
+ * @returns
171
+ */
108
172
  async mget(...args) {
109
173
  let isCached = true;
110
174
  const values = [];
@@ -135,6 +199,16 @@ class Search {
135
199
  return [];
136
200
  }
137
201
  }
202
+ /**
203
+ * Deletes the fields provided as args. Returns the
204
+ * count of fields that were deleted.
205
+ *
206
+ * @param args
207
+ * @returns {number}
208
+ * @example
209
+ * sont search = new Search();
210
+ * const count = await search.del('field1', 'field2', 'field3');
211
+ */
138
212
  async del(...args) {
139
213
  const ssGuid = this.getSearchSessionGuid();
140
214
  const store = storage_1.asyncLocalStorage.getStore();
@@ -153,6 +227,18 @@ class Search {
153
227
  this.store.exec('HSET', this.jobId, ssGuid, formattedResponse.toString());
154
228
  return formattedResponse;
155
229
  }
230
+ /**
231
+ * Increments the value of a float field by the given amount. Returns the
232
+ * new value of the field after the increment. Pass a negative
233
+ * number to decrement the value.
234
+ *
235
+ * @param key - the key to increment
236
+ * @param val - the value to increment by
237
+ * @returns {number} - the new value
238
+ * @example
239
+ * const search = new Search();
240
+ * const count = await search.incr('field1', 1.5);
241
+ */
156
242
  async incr(key, val) {
157
243
  delete this.cachedFields[key];
158
244
  const ssGuid = this.getSearchSessionGuid();
@@ -165,6 +251,18 @@ class Search {
165
251
  this.store.exec('HSET', this.jobId, ssGuid, num.toString());
166
252
  return Number(num);
167
253
  }
254
+ /**
255
+ * Multiplies the value of a field by the given amount. Returns the
256
+ * new value of the field after the multiplication. NOTE:
257
+ * this is exponential multiplication.
258
+ *
259
+ * @param key - the key to multiply
260
+ * @param val - the value to multiply by
261
+ * @returns {number} - the new product of the multiplication
262
+ * @example
263
+ * const search = new Search();
264
+ * const product = await search.mult('field1', 1.5);
265
+ */
168
266
  async mult(key, val) {
169
267
  delete this.cachedFields[key];
170
268
  const ssGuid = this.getSearchSessionGuid();