recombee-api-client 4.1.2 → 4.1.4

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
@@ -9,196 +9,253 @@ For client side (browser, mobile apps ...) .js library please see [this reposito
9
9
 
10
10
  ## Installation
11
11
 
12
- ```
13
- npm i recombee-api-client --save
14
- ```
15
-
16
- ## Promises / callbacks
17
-
18
- The SDK supports both Promises and callbacks, so you can choose the way which suits your coding style and conventions of your project:
19
-
20
- ```javascript
21
- //Using Promise
22
- client.send(new AddDetailView)
23
- .then((response) => {
24
- //handle response
25
- })
26
- .catch((error) => {
27
- //handle error
28
- });
29
-
30
- //Using callback
31
- client.send(new AddDetailView,
32
- (error, response) => {
33
- //handle result
34
- }
35
- );
12
+ ```sh
13
+ npm install recombee-api-client
14
+ # or
15
+ yarn add recombee-api-client
16
+ # or
17
+ pnpm add recombee-api-client
18
+ # or
19
+ bun add recombee-api-client
36
20
  ```
37
21
 
22
+ The library ships with types, so you should get autocomplete in your IDE out of the box.
23
+ If you're using TypeScript, it should recognize these correctly and warn you about any type errors.
38
24
 
39
25
  ## Examples
40
26
 
41
- ### Basic example
27
+ ### Basic examples
42
28
 
43
29
  ```javascript
44
- var recombee = require('recombee-api-client');
45
- var rqs = recombee.requests;
46
-
47
- var client = new recombee.ApiClient('--my-database-id--', '--db-private-token--', {region: 'us-west'});
30
+ import { ApiClient, requests } from "recombee-api-client";
48
31
 
49
- // Prepare some userIDs and itemIDs
50
- const NUM = 100;
51
- var userIds = Array.apply(0, Array(NUM)).map((_, i) => {
52
- return `user-${i}`;
53
- });
54
-
55
- var itemIds = Array.apply(0, Array(NUM)).map((_, i) => {
56
- return `item-${i}`;
57
- });
32
+ const client = new ApiClient(
33
+ "[RECOMBEE_DATABASE_ID]",
34
+ "[RECOMBEE_DATABASE_PRIVATE_TOKEN]",
35
+ { region: "us-west" }
36
+ );
58
37
 
38
+ const request = new requests.ListUsers({ count: 10 });
59
39
 
60
- // Generate some random purchases of items by users
61
- const PROBABILITY_PURCHASED = 0.1;
62
- var purchases = [];
63
- userIds.forEach((userId) => {
64
- var purchased = itemIds.filter(() => Math.random() < PROBABILITY_PURCHASED);
65
- purchased.forEach((itemId) => {
40
+ client
41
+ .send(request)
42
+ .then((result) => {
43
+ console.log(result);
44
+ })
45
+ .catch((error) => {
46
+ console.error(error);
47
+ });
48
+ ```
66
49
 
67
- purchases.push(new rqs.AddPurchase(userId, itemId, {'cascadeCreate': true}))
50
+ ```javascript
51
+ import { ApiClient, requests } from "recombee-api-client";
68
52
 
69
- });
70
- });
53
+ const client = new ApiClient(
54
+ "[RECOMBEE_DATABASE_ID]",
55
+ "[RECOMBEE_DATABASE_PRIVATE_TOKEN]",
56
+ { region: "us-west" }
57
+ );
71
58
 
72
- // Send the data to Recombee, use Batch for faster processing of larger data
73
- client.send(new rqs.Batch(purchases))
74
- .then(() => {
75
- //Get 5 recommended items for user 'user-25'
76
- return client.send(new rqs.RecommendItemsToUser('user-25', 5));
77
- })
78
- .then((response) => {
79
- console.log("Recommended items for user-25: %j", response.recomms);
80
-
81
- // User scrolled down - get next 3 recommended items
82
- return client.send(new rqs.RecommendNextItems(response.recommId, 3));
83
- })
84
- .then((response) => {
85
- console.log("Next recommended items for user-25: %j", response.recomms);
86
- })
87
- .catch((error) => {
88
- console.error(error);
89
- // Use fallback
90
- });
59
+ async function example() {
60
+ // Prepare some userIDs and itemIDs
61
+ const NUM = 100;
62
+ const userIds = Array.from({ length: NUM }).map((_, i) => {
63
+ return `user-${i}`;
64
+ });
65
+ const itemIds = Array.from({ length: NUM }).map((_, i) => {
66
+ return `item-${i}`;
67
+ });
68
+
69
+ // Generate some random purchases of items by users
70
+ const PROBABILITY_PURCHASED = 0.1;
71
+ const purchases = [];
72
+ userIds.forEach((userId) => {
73
+ const purchased = itemIds.filter(
74
+ () => Math.random() < PROBABILITY_PURCHASED
75
+ );
76
+ purchased.forEach((itemId) => {
77
+ purchases.push(
78
+ new requests.AddPurchase(userId, itemId, {
79
+ cascadeCreate: true,
80
+ })
81
+ );
82
+ });
83
+ });
84
+
85
+ // Send the data to Recombee, use Batch for faster processing of larger data
86
+ await client.send(new requests.Batch(purchases));
87
+
88
+ //Get 5 recommended items for user 'user-25'
89
+ const response = await client.send(
90
+ new requests.RecommendItemsToUser("user-25", 5)
91
+ );
92
+ console.log("Recommended items for user-25: %j", response.recomms);
93
+ // User scrolled down - get next 3 recommended items
94
+ const response2 = await client.send(
95
+ new requests.RecommendNextItems(response.recommId, 3)
96
+ );
97
+ console.log("Next recommended items for user-25: %j", response2.recomms);
98
+ }
99
+
100
+ example();
91
101
  ```
92
102
 
93
103
  ### Using property values
94
104
 
95
105
  ```javascript
96
- var recombee = require('recombee-api-client');
97
- var rqs = recombee.requests;
106
+ const recombee = require("recombee-api-client");
107
+ const rqs = recombee.requests;
98
108
 
99
- var client = new recombee.ApiClient('--my-database-id--', '--db-private-token--', {region: 'ap-se'});
109
+ const client = new recombee.ApiClient(
110
+ "--my-database-id--",
111
+ "--db-private-token--",
112
+ { region: "ap-se" }
113
+ );
100
114
  const NUM = 100;
101
115
 
102
116
  // We will use computers as items in this example
103
- // Computers have four properties
117
+ // Computers have four properties
104
118
  // - price (floating point number)
105
119
  // - number of processor cores (integer number)
106
120
  // - description (string)
107
121
  // - image (url of computer's photo)
108
122
 
109
123
  // Add properties of items
110
- client.send(new rqs.Batch([
111
- new rqs.AddItemProperty('price', 'double'),
112
- new rqs.AddItemProperty('num-cores', 'int'),
113
- new rqs.AddItemProperty('description', 'string'),
114
- new rqs.AddItemProperty('time', 'timestamp'),
115
- new rqs.AddItemProperty('image', 'image')
116
- ]))
117
- .then((responses) => {
118
- //Prepare requests for setting a catalog of computers
119
-
120
- var requests = Array.apply(0, Array(NUM)).map((_, i) => {
121
- return new rqs.SetItemValues(
122
- `computer-${i}`, //itemId
123
- //values:
124
- {
125
- 'price': 600 + 400 * Math.random(),
126
- 'num-cores': Math.floor(Math.random() * 8) + 1,
127
- 'description': 'Great computer',
128
- 'time': new Date().toISOString(),
129
- 'image': `http://examplesite.com/products/computer-${i}.jpg`
130
- },
131
- //optional parameters:
132
- {
133
- 'cascadeCreate': true // Use cascadeCreate for creating item
134
- // with given itemId, if it doesn't exist
135
- }
136
- );
137
- });
138
- //Send catalog to the recommender system
139
- return client.send(new rqs.Batch(requests));
140
- })
141
- .then((responses) => {
142
- // Generate some random purchases of items by users
143
- var userIds = Array.apply(0, Array(NUM)).map((_, i) => {
144
- return `user-${i}`;
145
- });
146
- var itemIds = Array.apply(0, Array(NUM)).map((_, i) => {
147
- return `computer-${i}`;
148
- });
149
-
150
- // Generate some random purchases of items by users
151
- const PROBABILITY_PURCHASED = 0.1;
152
- var purchases = [];
153
- userIds.forEach((userId) => {
154
- var purchased = itemIds.filter(() => Math.random() < PROBABILITY_PURCHASED);
155
- purchased.forEach((itemId) => {
156
- purchases.push(new rqs.AddPurchase(userId, itemId, {'cascadeCreate': true}))
157
- });
158
- });
159
- // Send purchases to the recommender system
160
- return client.send(new rqs.Batch(purchases));
161
- })
162
- .then((responses) => {
163
- // Get 5 recommendations for user-42, who is currently viewing computer-6
164
- // Recommend only computers that have at least 3 cores
165
- return client.send(new rqs.RecommendItemsToItem('computer-6', 'user-42', 5,
166
- {'filter': "'num-cores' >= 3"}
167
- ));
168
- })
169
- .then((recommended) => {
170
- console.log("Recommended items with at least 3 processor cores: %j", recommended);
171
-
172
- // Recommend only items that are more expensive then currently viewed item (up-sell)
173
- return client.send(new rqs.RecommendItemsToItem('computer-6', 'user-42', 5,
174
- {'filter': " 'price' > context_item[\"price\"] ",
175
- 'returnProperties': true}
176
- ));
177
- })
178
- .then((recommended) => {
179
- console.log("Recommended up-sell items: %j", recommended)
180
-
181
- // Filters, boosters and other settings can be set also in the Admin UI (admin.recombee.com)
182
- // when scenario is specified
183
- return client.send(new rqs.RecommendItemsToItem('computer-6', 'user-42', 5,
184
- {'scenario': "product_detail"}
185
- ));
186
- })
187
- .then((recommended) => {
188
- // Perform personalized full-text search with a user's search query (e.g. "computers")
189
- return client.send(new rqs.SearchItems('user-42', 'computers', 5, {'scenario': "search_top"}));
190
- })
191
- .then((matched) => {
192
- console.log("Matched items: %j", matched)
193
- })
194
- .catch((error) => {
195
- console.error(error);
196
- // Use fallback
197
- });
124
+ client
125
+ .send(
126
+ new rqs.Batch([
127
+ new rqs.AddItemProperty("price", "double"),
128
+ new rqs.AddItemProperty("num-cores", "int"),
129
+ new rqs.AddItemProperty("description", "string"),
130
+ new rqs.AddItemProperty("time", "timestamp"),
131
+ new rqs.AddItemProperty("image", "image"),
132
+ ])
133
+ )
134
+ .then((responses) => {
135
+ //Prepare requests for setting a catalog of computers
136
+
137
+ var requests = Array.apply(0, Array(NUM)).map((_, i) => {
138
+ return new rqs.SetItemValues(
139
+ `computer-${i}`, //itemId
140
+ //values:
141
+ {
142
+ price: 600 + 400 * Math.random(),
143
+ "num-cores": Math.floor(Math.random() * 8) + 1,
144
+ description: "Great computer",
145
+ time: new Date().toISOString(),
146
+ image: `http://examplesite.com/products/computer-${i}.jpg`,
147
+ },
148
+ //optional parameters:
149
+ {
150
+ cascadeCreate: true, // Use cascadeCreate for creating item
151
+ // with given itemId, if it doesn't exist
152
+ }
153
+ );
154
+ });
155
+ //Send catalog to the recommender system
156
+ return client.send(new rqs.Batch(requests));
157
+ })
158
+ .then((responses) => {
159
+ // Generate some random purchases of items by users
160
+ const userIds = Array.apply(0, Array(NUM)).map((_, i) => {
161
+ return `user-${i}`;
162
+ });
163
+ const itemIds = Array.apply(0, Array(NUM)).map((_, i) => {
164
+ return `computer-${i}`;
165
+ });
166
+
167
+ // Generate some random purchases of items by users
168
+ const PROBABILITY_PURCHASED = 0.1;
169
+ const purchases = [];
170
+ userIds.forEach((userId) => {
171
+ const purchased = itemIds.filter(
172
+ () => Math.random() < PROBABILITY_PURCHASED
173
+ );
174
+ purchased.forEach((itemId) => {
175
+ purchases.push(
176
+ new rqs.AddPurchase(userId, itemId, { cascadeCreate: true })
177
+ );
178
+ });
179
+ });
180
+ // Send purchases to the recommender system
181
+ return client.send(new rqs.Batch(purchases));
182
+ })
183
+ .then((responses) => {
184
+ // Get 5 recommendations for user-42, who is currently viewing computer-6
185
+ // Recommend only computers that have at least 3 cores
186
+ return client.send(
187
+ new rqs.RecommendItemsToItem("computer-6", "user-42", 5, {
188
+ filter: "'num-cores' >= 3",
189
+ })
190
+ );
191
+ })
192
+ .then((recommended) => {
193
+ console.log(
194
+ "Recommended items with at least 3 processor cores: %j",
195
+ recommended
196
+ );
197
+
198
+ // Recommend only items that are more expensive then currently viewed item (up-sell)
199
+ return client.send(
200
+ new rqs.RecommendItemsToItem("computer-6", "user-42", 5, {
201
+ filter: " 'price' > context_item[\"price\"] ",
202
+ returnProperties: true,
203
+ })
204
+ );
205
+ })
206
+ .then((recommended) => {
207
+ console.log("Recommended up-sell items: %j", recommended);
208
+
209
+ // Filters, boosters and other settings can be set also in the Admin UI (admin.recombee.com)
210
+ // when scenario is specified
211
+ return client.send(
212
+ new rqs.RecommendItemsToItem("computer-6", "user-42", 5, {
213
+ scenario: "product_detail",
214
+ })
215
+ );
216
+ })
217
+ .then((recommended) => {
218
+ // Perform personalized full-text search with a user's search query (e.g. "computers")
219
+ return client.send(
220
+ new rqs.SearchItems("user-42", "computers", 5, {
221
+ scenario: "search_top",
222
+ })
223
+ );
224
+ })
225
+ .then((matched) => {
226
+ console.log("Matched items: %j", matched);
227
+ })
228
+ .catch((error) => {
229
+ console.error(error);
230
+ // Use fallback
231
+ });
232
+ ```
233
+
234
+ ## Promises / callbacks
235
+
236
+ The SDK supports both Promises and callbacks, so you can choose the way which suits your coding style and conventions of your project:
237
+
238
+ ```javascript
239
+ // Using Promises
240
+ await client.send(new ListUsers());
241
+ // or
242
+ client
243
+ .send(new ListUsers())
244
+ .then((response) => {
245
+ // handle response
246
+ })
247
+ .catch((error) => {
248
+ // handle error
249
+ });
250
+
251
+ // Using callbacks
252
+ client.send(new ListUsers(), (error, response) => {
253
+ // handle result
254
+ });
198
255
  ```
199
256
 
200
257
  ## Errors handling
201
258
 
202
- Various errors can occur while processing request, for example because of adding an already existing item or submitting interaction of nonexistent user without *cascadeCreate* set to true. These errors lead to the *ResponseError*, which is thrown or put to callback function by the *send* method of the client (depending on using Promises or callbacks). Another reason for errorneous request is a timeout. *ApiError* is the base class of both *ResponseError* and *TimeoutError*.
259
+ Various errors can occur while processing request, for example because of adding an already existing item or submitting interaction of nonexistent user without _cascadeCreate_ set to true. These errors lead to the _ResponseError_, which is thrown or put to callback function by the _send_ method of the client (depending on using Promises or callbacks). Another reason for errorneous request is a timeout. _ApiError_ is the base class of both _ResponseError_ and _TimeoutError_.
203
260
 
204
- We are doing our best to provide the fastest and most reliable service, but production-level applications must implement a fallback solution since problems can always happen. The fallback might be, for example, showing the most popular items from the current category, or not displaying recommendations at all.
261
+ We are doing our best to provide the fastest and most reliable service, but production-level applications must implement a fallback solution since problems can always happen. The fallback might be, for example, showing the most popular items from the current category, or not displaying recommendations at all.
package/lib/api-client.js CHANGED
@@ -15,8 +15,8 @@ class ApiClient {
15
15
  /**
16
16
  * Construct the client
17
17
  * @param {string} databaseId - ID of your database
18
- * @param {string} secretToken - Corresponding secret token
19
- * @param {Object} options - Other custom options
18
+ * @param {string} token - Corresponding secret token
19
+ * @param {Object} [options] - Other custom options
20
20
  */
21
21
  constructor (databaseId, token, options) {
22
22
  this.databaseId = databaseId;
@@ -45,7 +45,7 @@ class ApiClient {
45
45
  url: url,
46
46
  headers: {'Accept': 'application/json',
47
47
  'Content-Type': 'application/json',
48
- 'User-Agent': 'recombee-node-api-client/4.1.2'},
48
+ 'User-Agent': 'recombee-node-api-client/4.1.3'},
49
49
  timeout: request.timeout,
50
50
  agent: this.options.agent
51
51
  };
package/lib/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- declare module "recombee-api-client" {
1
+ export module "recombee-api-client" {
2
2
  namespace requests {
3
3
  /**
4
4
  * Base class for all the requests
@@ -17,6 +17,11 @@ declare module "recombee-api-client" {
17
17
  ensureHttps: boolean
18
18
  );
19
19
 
20
+ method: "GET" | "PUT" | "POST" | "DELETE";
21
+ path: string;
22
+ timeout: number;
23
+ ensureHttps: boolean;
24
+
20
25
  protected __response_type: any;
21
26
  }
22
27
 
@@ -194,9 +199,9 @@ declare module "recombee-api-client" {
194
199
  }
195
200
 
196
201
  export type BatchResponse = {
197
- statusCode: number;
198
- response: Response[];
199
- }
202
+ code: number;
203
+ json: any;
204
+ }[]
200
205
 
201
206
  /**
202
207
  * Client for sending requests to Recombee and getting replies
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "recombee-api-client",
3
- "version": "4.1.2",
3
+ "version": "4.1.4",
4
4
  "description": "Node.js client (SDK) for easy use of the Recombee recommendation API",
5
5
  "main": "index.js",
6
6
  "types": "lib/index.d.ts",
@@ -31,6 +31,8 @@
31
31
  "jssha": "^2.3.0"
32
32
  },
33
33
  "devDependencies": {
34
- "chai": "^3.5.0"
34
+ "chai": "^3.5.0",
35
+ "mocha": "~10.2.0",
36
+ "typescript": "~5.3.3"
35
37
  }
36
38
  }
package/tsconfig.json ADDED
@@ -0,0 +1,9 @@
1
+ {
2
+ "compilerOptions": {
3
+ "module": "NodeNext",
4
+ "noEmit": true,
5
+ "strict": true,
6
+ "noUncheckedIndexedAccess": true
7
+ },
8
+ "include": ["lib/index.d.ts"]
9
+ }