@hotmeshio/hotmesh 0.0.28 → 0.0.29

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.
package/README.md CHANGED
@@ -17,9 +17,7 @@ npm install @hotmeshio/hotmesh
17
17
  ```
18
18
 
19
19
  ## Design
20
- The HotMesh SDK is designed to keep your code front-and-center. Write code as you normally would, then use HotMesh to make it durable.
21
-
22
- 1. Start with any ordinary class. Pay attention to unpredictable functions: those that execute slowly, cause problems at scale, or simply fail to return. *Note how the `flaky` function throws an error 50% of the time. This is exactly the type of function that can be fixed using HotMesh.*
20
+ 1. Start with any ordinary class. Pay attention to unpredictable functions: those that execute slowly, cause problems at scale, or simply fail to return now and then. *Note how the `flaky` function throws an error 50% of the time. This is exactly the type of function that can be fixed using HotMesh.*
23
21
  ```javascript
24
22
  //myworkflow.ts
25
23
 
@@ -44,7 +42,7 @@ The HotMesh SDK is designed to keep your code front-and-center. Write code as yo
44
42
  }
45
43
  }
46
44
  ```
47
- 2. Import `Redis` and `MeshOS` and configure host, port, etc. List those functions that Redis should govern as durable workflows (like `run` and `flaky`). And that's it! *Your functions don't actually change; rather, their governance does.*
45
+ 2. Import and configure `Redis` and `MeshOS` as shown. List those functions that Redis should govern as durable workflows (like `run` and `flaky`). And that's it! *Your functions don't actually change; rather, their governance does.*
48
46
  ```javascript
49
47
  //myworkflow.ts
50
48
 
@@ -53,6 +51,7 @@ The HotMesh SDK is designed to keep your code front-and-center. Write code as yo
53
51
 
54
52
  export class MyWorkflow extends MeshOS {
55
53
 
54
+ //configure Redis
56
55
  redisClass = Redis;
57
56
  redisOptions = { host: 'localhost', port: 6379 };
58
57
 
@@ -62,13 +61,14 @@ The HotMesh SDK is designed to keep your code front-and-center. Write code as yo
62
61
  //list functions to retry and cache
63
62
  proxyFunctions = ['flaky'];
64
63
 
64
+ //no need to change anything else!
65
+
65
66
  async run(name: string): Promise<string> {
66
67
  const hi = await this.flaky(name);
67
68
  const hello = await this.greet(name);
68
69
  return `${hi} ${hello}`;
69
70
  }
70
71
 
71
- //this function is now durable and will be retried until it succeeds!
72
72
  async flaky(name: string): Promise<string> {
73
73
  if (Math.random() < 0.5) {
74
74
  throw new Error('Ooops!');
@@ -81,7 +81,7 @@ The HotMesh SDK is designed to keep your code front-and-center. Write code as yo
81
81
  }
82
82
  }
83
83
  ```
84
- 3. Invoke your class, providing a unique id (it's now an idempotent workflow and needs a GUID). Nothing changes from the outside, *but Redis now governs the end-to-end execution.* It's guaranteed to succeed, even if it takes a while.
84
+ 3. Invoke your class, providing a unique id (it's now an idempotent workflow and needs a GUID). Nothing changes from the outside, *but Redis now governs the end-to-end execution.* It's guaranteed to succeed, even if it breaks a few times along the way.
85
85
  ```javascript
86
86
  //mycaller.ts
87
87
 
@@ -90,11 +90,11 @@ The HotMesh SDK is designed to keep your code front-and-center. Write code as yo
90
90
  //Hi, World! Hello, World!
91
91
  ```
92
92
 
93
- Redis governance delivers more than just reliability. Externalizing state fundamentally changes the execution profile for your functions, allowing you to design long-running, durable workflows. Use the following methods to solve the most common state management challenges.
93
+ Redis governance delivers more than just reliability. Externalizing state fundamentally changes the execution profile for your functions, allowing you to design long-running, durable workflows. The `MeshOS` base class (shown in the examples above) provides additional methods for solving the most common state management challenges.
94
94
 
95
- - `waitForSignal` | Pause and wait for external event(s) before continuing. The *waitForSignal* method will collate and cache the signals and only awaken your function once they've all arrived.
95
+ - `waitForSignal` | Pause your function and wait for external event(s) before continuing. The *waitForSignal* method will collate and cache the signals and only awaken your function once they've all arrived.
96
96
  - `signal` | Send a signal (and optional payload) to any paused function.
97
- - `hook` | Redis governance supercharges your functions, transforming them into 're-entrant processes'. Optionally use the *hook* method to spawn parallel execution threads within any running function.
97
+ - `hook` | Redis governance converts your functions into 're-entrant processes'. Optionally use the *hook* method to spawn parallel execution threads to augment a running workflow.
98
98
  - `sleep` | Pause function execution for a ridiculous amount of time (months, years, etc). There's no risk of information loss, as Redis governs function state. When your function awakens, function state is efficiently (and automatically) restored.
99
99
  - `random` | Generate a deterministic random number that can be used in a reentrant process workflow (replaces `Math.random()`).
100
100
  - `executeChild` | Call another durable function and await the response. *Design sophisticated, multi-process solutions by leveraging this command.*
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hotmeshio/hotmesh",
3
- "version": "0.0.28",
3
+ "version": "0.0.29",
4
4
  "description": "Unbreakable Workflows",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -70,6 +70,9 @@ class ClientService {
70
70
  };
71
71
  this.search = async (hotMeshClient, index, query) => {
72
72
  const store = hotMeshClient.engine.store;
73
+ if (query[0]?.startsWith('FT.')) {
74
+ return await store.exec(...query);
75
+ }
73
76
  return await store.exec('FT.SEARCH', index, ...query);
74
77
  };
75
78
  this.workflow = {
@@ -91,19 +91,22 @@ export declare class MeshOSService {
91
91
  */
92
92
  static startWorkers(options?: MeshOSWorkerOptions): Promise<void>;
93
93
  /**
94
- * executes the redis FT search query
94
+ * executes the redis FT search query; optionally specify other commands
95
95
  * @example '@_quantity:[89 89]'
96
+ * @example '@_quantity:[89 89] @_name:"John"'
97
+ * @example 'FT.search my-index @_quantity:[89 89]'
98
+ * @param {FindOptions} options
96
99
  * @param {any[]} args
97
- * @returns {string}
100
+ * @returns {Promise<string[] | [number] | Array<number, string | number | string[]>>}
98
101
  */
99
- static find(options: FindOptions, ...args: string[]): Promise<string[] | [number]>;
102
+ static find(options: FindOptions, ...args: string[]): Promise<string[] | [number] | Array<string | number | string[]>>;
100
103
  /**
101
104
  * Provides a JSON abstraction for the Redis FT.search command
102
105
  * (e.g, `count`, `query`, `return`, `limit`)
103
106
  * @param {FindWhereOptions} options
104
- * @returns {Promise<string[] | [number]>}
107
+ * @returns {Promise<string[] | [number] | Array<string | number | string[]>>}
105
108
  */
106
- static findWhere(options: FindWhereOptions): Promise<string[] | [number]>;
109
+ static findWhere(options: FindWhereOptions): Promise<string[] | [number] | Array<string | number | string[]>>;
107
110
  static generateSearchQuery(query: FindWhereQuery[]): string;
108
111
  /**
109
112
  * returns the workflow handle. The handle can then be
@@ -140,10 +140,13 @@ class MeshOSService {
140
140
  }
141
141
  }
142
142
  /**
143
- * executes the redis FT search query
143
+ * executes the redis FT search query; optionally specify other commands
144
144
  * @example '@_quantity:[89 89]'
145
+ * @example '@_quantity:[89 89] @_name:"John"'
146
+ * @example 'FT.search my-index @_quantity:[89 89]'
147
+ * @param {FindOptions} options
145
148
  * @param {any[]} args
146
- * @returns {string}
149
+ * @returns {Promise<string[] | [number] | Array<number, string | number | string[]>>}
147
150
  */
148
151
  static async find(options, ...args) {
149
152
  const my = new this();
@@ -170,7 +173,7 @@ class MeshOSService {
170
173
  * Provides a JSON abstraction for the Redis FT.search command
171
174
  * (e.g, `count`, `query`, `return`, `limit`)
172
175
  * @param {FindWhereOptions} options
173
- * @returns {Promise<string[] | [number]>}
176
+ * @returns {Promise<string[] | [number] | Array<string | number | string[]>>}
174
177
  */
175
178
  static async findWhere(options) {
176
179
  const args = [this.generateSearchQuery(options.query)];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hotmeshio/hotmesh",
3
- "version": "0.0.28",
3
+ "version": "0.0.29",
4
4
  "description": "Unbreakable Workflows",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -85,6 +85,9 @@ export class ClientService {
85
85
 
86
86
  search = async (hotMeshClient: HotMesh, index: string, query: string[]): Promise<string[]> => {
87
87
  const store = hotMeshClient.engine.store;
88
+ if (query[0]?.startsWith('FT.')) {
89
+ return await store.exec(...query) as string[];
90
+ }
88
91
  return await store.exec('FT.SEARCH', index, ...query) as string[];
89
92
  }
90
93
 
@@ -236,12 +236,15 @@ export class MeshOSService {
236
236
  }
237
237
 
238
238
  /**
239
- * executes the redis FT search query
239
+ * executes the redis FT search query; optionally specify other commands
240
240
  * @example '@_quantity:[89 89]'
241
+ * @example '@_quantity:[89 89] @_name:"John"'
242
+ * @example 'FT.search my-index @_quantity:[89 89]'
243
+ * @param {FindOptions} options
241
244
  * @param {any[]} args
242
- * @returns {string}
245
+ * @returns {Promise<string[] | [number] | Array<number, string | number | string[]>>}
243
246
  */
244
- static async find(options: FindOptions, ...args: string[]): Promise<string[] | [number]> {
247
+ static async find(options: FindOptions, ...args: string[]): Promise<string[] | [number] | Array<string | number | string[]>> {
245
248
  const my = new this();
246
249
  const client = new Client({ connection: {
247
250
  class: my.redisClass,
@@ -272,9 +275,9 @@ export class MeshOSService {
272
275
  * Provides a JSON abstraction for the Redis FT.search command
273
276
  * (e.g, `count`, `query`, `return`, `limit`)
274
277
  * @param {FindWhereOptions} options
275
- * @returns {Promise<string[] | [number]>}
278
+ * @returns {Promise<string[] | [number] | Array<string | number | string[]>>}
276
279
  */
277
- static async findWhere(options: FindWhereOptions): Promise<string[] | [number]> {
280
+ static async findWhere(options: FindWhereOptions): Promise<string[] | [number] | Array<string | number | string[]>> {
278
281
  const args: string[] = [this.generateSearchQuery(options.query)];
279
282
  if (options.count) {
280
283
  args.push('LIMIT', '0', '0');