memcache 1.1.0 → 1.2.0

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/dist/index.cjs CHANGED
@@ -1063,16 +1063,8 @@ var Memcache = class extends import_hookified2.Hookified {
1063
1063
  const command = `cas ${key} ${flags} ${exptime} ${bytes} ${casToken}\r
1064
1064
  ${valueStr}`;
1065
1065
  const nodes = await this.getNodesByKey(key);
1066
- const promises = nodes.map(async (node) => {
1067
- try {
1068
- const result = await node.command(command);
1069
- return result === "STORED";
1070
- } catch {
1071
- return false;
1072
- }
1073
- });
1074
- const results = await Promise.all(promises);
1075
- const success = results.every((result) => result === true);
1066
+ const results = await this.execute(command, nodes);
1067
+ const success = results.every((result) => result === "STORED");
1076
1068
  await this.afterHook("cas", {
1077
1069
  key,
1078
1070
  value,
@@ -1101,16 +1093,8 @@ ${valueStr}`;
1101
1093
  const command = `set ${key} ${flags} ${exptime} ${bytes}\r
1102
1094
  ${valueStr}`;
1103
1095
  const nodes = await this.getNodesByKey(key);
1104
- const promises = nodes.map(async (node) => {
1105
- try {
1106
- const result = await node.command(command);
1107
- return result === "STORED";
1108
- } catch {
1109
- return false;
1110
- }
1111
- });
1112
- const results = await Promise.all(promises);
1113
- const success = results.every((result) => result === true);
1096
+ const results = await this.execute(command, nodes);
1097
+ const success = results.every((result) => result === "STORED");
1114
1098
  await this.afterHook("set", { key, value, exptime, flags, success });
1115
1099
  return success;
1116
1100
  }
@@ -1132,16 +1116,8 @@ ${valueStr}`;
1132
1116
  const command = `add ${key} ${flags} ${exptime} ${bytes}\r
1133
1117
  ${valueStr}`;
1134
1118
  const nodes = await this.getNodesByKey(key);
1135
- const promises = nodes.map(async (node) => {
1136
- try {
1137
- const result = await node.command(command);
1138
- return result === "STORED";
1139
- } catch {
1140
- return false;
1141
- }
1142
- });
1143
- const results = await Promise.all(promises);
1144
- const success = results.every((result) => result === true);
1119
+ const results = await this.execute(command, nodes);
1120
+ const success = results.every((result) => result === "STORED");
1145
1121
  await this.afterHook("add", { key, value, exptime, flags, success });
1146
1122
  return success;
1147
1123
  }
@@ -1163,16 +1139,8 @@ ${valueStr}`;
1163
1139
  const command = `replace ${key} ${flags} ${exptime} ${bytes}\r
1164
1140
  ${valueStr}`;
1165
1141
  const nodes = await this.getNodesByKey(key);
1166
- const promises = nodes.map(async (node) => {
1167
- try {
1168
- const result = await node.command(command);
1169
- return result === "STORED";
1170
- } catch {
1171
- return false;
1172
- }
1173
- });
1174
- const results = await Promise.all(promises);
1175
- const success = results.every((result) => result === true);
1142
+ const results = await this.execute(command, nodes);
1143
+ const success = results.every((result) => result === "STORED");
1176
1144
  await this.afterHook("replace", { key, value, exptime, flags, success });
1177
1145
  return success;
1178
1146
  }
@@ -1192,16 +1160,8 @@ ${valueStr}`;
1192
1160
  const command = `append ${key} 0 0 ${bytes}\r
1193
1161
  ${valueStr}`;
1194
1162
  const nodes = await this.getNodesByKey(key);
1195
- const promises = nodes.map(async (node) => {
1196
- try {
1197
- const result = await node.command(command);
1198
- return result === "STORED";
1199
- } catch {
1200
- return false;
1201
- }
1202
- });
1203
- const results = await Promise.all(promises);
1204
- const success = results.every((result) => result === true);
1163
+ const results = await this.execute(command, nodes);
1164
+ const success = results.every((result) => result === "STORED");
1205
1165
  await this.afterHook("append", { key, value, success });
1206
1166
  return success;
1207
1167
  }
@@ -1221,16 +1181,8 @@ ${valueStr}`;
1221
1181
  const command = `prepend ${key} 0 0 ${bytes}\r
1222
1182
  ${valueStr}`;
1223
1183
  const nodes = await this.getNodesByKey(key);
1224
- const promises = nodes.map(async (node) => {
1225
- try {
1226
- const result = await node.command(command);
1227
- return result === "STORED";
1228
- } catch {
1229
- return false;
1230
- }
1231
- });
1232
- const results = await Promise.all(promises);
1233
- const success = results.every((result) => result === true);
1184
+ const results = await this.execute(command, nodes);
1185
+ const success = results.every((result) => result === "STORED");
1234
1186
  await this.afterHook("prepend", { key, value, success });
1235
1187
  return success;
1236
1188
  }
@@ -1245,16 +1197,8 @@ ${valueStr}`;
1245
1197
  await this.beforeHook("delete", { key });
1246
1198
  this.validateKey(key);
1247
1199
  const nodes = await this.getNodesByKey(key);
1248
- const promises = nodes.map(async (node) => {
1249
- try {
1250
- const result = await node.command(`delete ${key}`);
1251
- return result === "DELETED";
1252
- } catch {
1253
- return false;
1254
- }
1255
- });
1256
- const results = await Promise.all(promises);
1257
- const success = results.every((result) => result === true);
1200
+ const results = await this.execute(`delete ${key}`, nodes);
1201
+ const success = results.every((result) => result === "DELETED");
1258
1202
  await this.afterHook("delete", { key, success });
1259
1203
  return success;
1260
1204
  }
@@ -1270,16 +1214,8 @@ ${valueStr}`;
1270
1214
  await this.beforeHook("incr", { key, value });
1271
1215
  this.validateKey(key);
1272
1216
  const nodes = await this.getNodesByKey(key);
1273
- const promises = nodes.map(async (node) => {
1274
- try {
1275
- const result = await node.command(`incr ${key} ${value}`);
1276
- return typeof result === "number" ? result : void 0;
1277
- } catch {
1278
- return void 0;
1279
- }
1280
- });
1281
- const results = await Promise.all(promises);
1282
- const newValue = results.find((v) => v !== void 0);
1217
+ const results = await this.execute(`incr ${key} ${value}`, nodes);
1218
+ const newValue = results.find((v) => typeof v === "number");
1283
1219
  await this.afterHook("incr", { key, value, newValue });
1284
1220
  return newValue;
1285
1221
  }
@@ -1295,16 +1231,8 @@ ${valueStr}`;
1295
1231
  await this.beforeHook("decr", { key, value });
1296
1232
  this.validateKey(key);
1297
1233
  const nodes = await this.getNodesByKey(key);
1298
- const promises = nodes.map(async (node) => {
1299
- try {
1300
- const result = await node.command(`decr ${key} ${value}`);
1301
- return typeof result === "number" ? result : void 0;
1302
- } catch {
1303
- return void 0;
1304
- }
1305
- });
1306
- const results = await Promise.all(promises);
1307
- const newValue = results.find((v) => v !== void 0);
1234
+ const results = await this.execute(`decr ${key} ${value}`, nodes);
1235
+ const newValue = results.find((v) => typeof v === "number");
1308
1236
  await this.afterHook("decr", { key, value, newValue });
1309
1237
  return newValue;
1310
1238
  }
@@ -1320,16 +1248,8 @@ ${valueStr}`;
1320
1248
  await this.beforeHook("touch", { key, exptime });
1321
1249
  this.validateKey(key);
1322
1250
  const nodes = await this.getNodesByKey(key);
1323
- const promises = nodes.map(async (node) => {
1324
- try {
1325
- const result = await node.command(`touch ${key} ${exptime}`);
1326
- return result === "TOUCHED";
1327
- } catch {
1328
- return false;
1329
- }
1330
- });
1331
- const results = await Promise.all(promises);
1332
- const success = results.every((result) => result === true);
1251
+ const results = await this.execute(`touch ${key} ${exptime}`, nodes);
1252
+ const success = results.every((result) => result === "TOUCHED");
1333
1253
  await this.afterHook("touch", { key, exptime, success });
1334
1254
  return success;
1335
1255
  }
@@ -1445,6 +1365,23 @@ ${valueStr}`;
1445
1365
  }
1446
1366
  return nodes;
1447
1367
  }
1368
+ /**
1369
+ * Execute a command on the specified nodes.
1370
+ * @param {string} command - The memcache command string to execute
1371
+ * @param {MemcacheNode[]} nodes - Array of MemcacheNode instances to execute on
1372
+ * @param {ExecuteOptions} options - Optional execution options
1373
+ * @returns {Promise<unknown[]>} Promise resolving to array of results from each node
1374
+ */
1375
+ async execute(command, nodes, options) {
1376
+ const promises = nodes.map(async (node) => {
1377
+ try {
1378
+ return await node.command(command, options?.commandOptions);
1379
+ } catch {
1380
+ return void 0;
1381
+ }
1382
+ });
1383
+ return Promise.all(promises);
1384
+ }
1448
1385
  /**
1449
1386
  * Validates a Memcache key according to protocol requirements.
1450
1387
  * @param {string} key - The key to validate
package/dist/index.d.cts CHANGED
@@ -187,6 +187,10 @@ interface MemcacheOptions {
187
187
  interface MemcacheStats {
188
188
  [key: string]: string;
189
189
  }
190
+ interface ExecuteOptions {
191
+ /** Command options passed to node.command() */
192
+ commandOptions?: CommandOptions;
193
+ }
190
194
  declare class Memcache extends Hookified {
191
195
  private _nodes;
192
196
  private _timeout;
@@ -474,6 +478,14 @@ declare class Memcache extends Hookified {
474
478
  * @throws {Error} If no nodes are available for the key
475
479
  */
476
480
  getNodesByKey(key: string): Promise<Array<MemcacheNode>>;
481
+ /**
482
+ * Execute a command on the specified nodes.
483
+ * @param {string} command - The memcache command string to execute
484
+ * @param {MemcacheNode[]} nodes - Array of MemcacheNode instances to execute on
485
+ * @param {ExecuteOptions} options - Optional execution options
486
+ * @returns {Promise<unknown[]>} Promise resolving to array of results from each node
487
+ */
488
+ execute(command: string, nodes: MemcacheNode[], options?: ExecuteOptions): Promise<unknown[]>;
477
489
  /**
478
490
  * Validates a Memcache key according to protocol requirements.
479
491
  * @param {string} key - The key to validate
@@ -498,4 +510,4 @@ declare class Memcache extends Hookified {
498
510
  private forwardNodeEvents;
499
511
  }
500
512
 
501
- export { type HashProvider, Memcache, MemcacheEvents, type MemcacheOptions, type MemcacheStats, createNode, Memcache as default };
513
+ export { type ExecuteOptions, type HashProvider, Memcache, MemcacheEvents, type MemcacheOptions, type MemcacheStats, createNode, Memcache as default };
package/dist/index.d.ts CHANGED
@@ -187,6 +187,10 @@ interface MemcacheOptions {
187
187
  interface MemcacheStats {
188
188
  [key: string]: string;
189
189
  }
190
+ interface ExecuteOptions {
191
+ /** Command options passed to node.command() */
192
+ commandOptions?: CommandOptions;
193
+ }
190
194
  declare class Memcache extends Hookified {
191
195
  private _nodes;
192
196
  private _timeout;
@@ -474,6 +478,14 @@ declare class Memcache extends Hookified {
474
478
  * @throws {Error} If no nodes are available for the key
475
479
  */
476
480
  getNodesByKey(key: string): Promise<Array<MemcacheNode>>;
481
+ /**
482
+ * Execute a command on the specified nodes.
483
+ * @param {string} command - The memcache command string to execute
484
+ * @param {MemcacheNode[]} nodes - Array of MemcacheNode instances to execute on
485
+ * @param {ExecuteOptions} options - Optional execution options
486
+ * @returns {Promise<unknown[]>} Promise resolving to array of results from each node
487
+ */
488
+ execute(command: string, nodes: MemcacheNode[], options?: ExecuteOptions): Promise<unknown[]>;
477
489
  /**
478
490
  * Validates a Memcache key according to protocol requirements.
479
491
  * @param {string} key - The key to validate
@@ -498,4 +510,4 @@ declare class Memcache extends Hookified {
498
510
  private forwardNodeEvents;
499
511
  }
500
512
 
501
- export { type HashProvider, Memcache, MemcacheEvents, type MemcacheOptions, type MemcacheStats, createNode, Memcache as default };
513
+ export { type ExecuteOptions, type HashProvider, Memcache, MemcacheEvents, type MemcacheOptions, type MemcacheStats, createNode, Memcache as default };
package/dist/index.js CHANGED
@@ -1036,16 +1036,8 @@ var Memcache = class extends Hookified2 {
1036
1036
  const command = `cas ${key} ${flags} ${exptime} ${bytes} ${casToken}\r
1037
1037
  ${valueStr}`;
1038
1038
  const nodes = await this.getNodesByKey(key);
1039
- const promises = nodes.map(async (node) => {
1040
- try {
1041
- const result = await node.command(command);
1042
- return result === "STORED";
1043
- } catch {
1044
- return false;
1045
- }
1046
- });
1047
- const results = await Promise.all(promises);
1048
- const success = results.every((result) => result === true);
1039
+ const results = await this.execute(command, nodes);
1040
+ const success = results.every((result) => result === "STORED");
1049
1041
  await this.afterHook("cas", {
1050
1042
  key,
1051
1043
  value,
@@ -1074,16 +1066,8 @@ ${valueStr}`;
1074
1066
  const command = `set ${key} ${flags} ${exptime} ${bytes}\r
1075
1067
  ${valueStr}`;
1076
1068
  const nodes = await this.getNodesByKey(key);
1077
- const promises = nodes.map(async (node) => {
1078
- try {
1079
- const result = await node.command(command);
1080
- return result === "STORED";
1081
- } catch {
1082
- return false;
1083
- }
1084
- });
1085
- const results = await Promise.all(promises);
1086
- const success = results.every((result) => result === true);
1069
+ const results = await this.execute(command, nodes);
1070
+ const success = results.every((result) => result === "STORED");
1087
1071
  await this.afterHook("set", { key, value, exptime, flags, success });
1088
1072
  return success;
1089
1073
  }
@@ -1105,16 +1089,8 @@ ${valueStr}`;
1105
1089
  const command = `add ${key} ${flags} ${exptime} ${bytes}\r
1106
1090
  ${valueStr}`;
1107
1091
  const nodes = await this.getNodesByKey(key);
1108
- const promises = nodes.map(async (node) => {
1109
- try {
1110
- const result = await node.command(command);
1111
- return result === "STORED";
1112
- } catch {
1113
- return false;
1114
- }
1115
- });
1116
- const results = await Promise.all(promises);
1117
- const success = results.every((result) => result === true);
1092
+ const results = await this.execute(command, nodes);
1093
+ const success = results.every((result) => result === "STORED");
1118
1094
  await this.afterHook("add", { key, value, exptime, flags, success });
1119
1095
  return success;
1120
1096
  }
@@ -1136,16 +1112,8 @@ ${valueStr}`;
1136
1112
  const command = `replace ${key} ${flags} ${exptime} ${bytes}\r
1137
1113
  ${valueStr}`;
1138
1114
  const nodes = await this.getNodesByKey(key);
1139
- const promises = nodes.map(async (node) => {
1140
- try {
1141
- const result = await node.command(command);
1142
- return result === "STORED";
1143
- } catch {
1144
- return false;
1145
- }
1146
- });
1147
- const results = await Promise.all(promises);
1148
- const success = results.every((result) => result === true);
1115
+ const results = await this.execute(command, nodes);
1116
+ const success = results.every((result) => result === "STORED");
1149
1117
  await this.afterHook("replace", { key, value, exptime, flags, success });
1150
1118
  return success;
1151
1119
  }
@@ -1165,16 +1133,8 @@ ${valueStr}`;
1165
1133
  const command = `append ${key} 0 0 ${bytes}\r
1166
1134
  ${valueStr}`;
1167
1135
  const nodes = await this.getNodesByKey(key);
1168
- const promises = nodes.map(async (node) => {
1169
- try {
1170
- const result = await node.command(command);
1171
- return result === "STORED";
1172
- } catch {
1173
- return false;
1174
- }
1175
- });
1176
- const results = await Promise.all(promises);
1177
- const success = results.every((result) => result === true);
1136
+ const results = await this.execute(command, nodes);
1137
+ const success = results.every((result) => result === "STORED");
1178
1138
  await this.afterHook("append", { key, value, success });
1179
1139
  return success;
1180
1140
  }
@@ -1194,16 +1154,8 @@ ${valueStr}`;
1194
1154
  const command = `prepend ${key} 0 0 ${bytes}\r
1195
1155
  ${valueStr}`;
1196
1156
  const nodes = await this.getNodesByKey(key);
1197
- const promises = nodes.map(async (node) => {
1198
- try {
1199
- const result = await node.command(command);
1200
- return result === "STORED";
1201
- } catch {
1202
- return false;
1203
- }
1204
- });
1205
- const results = await Promise.all(promises);
1206
- const success = results.every((result) => result === true);
1157
+ const results = await this.execute(command, nodes);
1158
+ const success = results.every((result) => result === "STORED");
1207
1159
  await this.afterHook("prepend", { key, value, success });
1208
1160
  return success;
1209
1161
  }
@@ -1218,16 +1170,8 @@ ${valueStr}`;
1218
1170
  await this.beforeHook("delete", { key });
1219
1171
  this.validateKey(key);
1220
1172
  const nodes = await this.getNodesByKey(key);
1221
- const promises = nodes.map(async (node) => {
1222
- try {
1223
- const result = await node.command(`delete ${key}`);
1224
- return result === "DELETED";
1225
- } catch {
1226
- return false;
1227
- }
1228
- });
1229
- const results = await Promise.all(promises);
1230
- const success = results.every((result) => result === true);
1173
+ const results = await this.execute(`delete ${key}`, nodes);
1174
+ const success = results.every((result) => result === "DELETED");
1231
1175
  await this.afterHook("delete", { key, success });
1232
1176
  return success;
1233
1177
  }
@@ -1243,16 +1187,8 @@ ${valueStr}`;
1243
1187
  await this.beforeHook("incr", { key, value });
1244
1188
  this.validateKey(key);
1245
1189
  const nodes = await this.getNodesByKey(key);
1246
- const promises = nodes.map(async (node) => {
1247
- try {
1248
- const result = await node.command(`incr ${key} ${value}`);
1249
- return typeof result === "number" ? result : void 0;
1250
- } catch {
1251
- return void 0;
1252
- }
1253
- });
1254
- const results = await Promise.all(promises);
1255
- const newValue = results.find((v) => v !== void 0);
1190
+ const results = await this.execute(`incr ${key} ${value}`, nodes);
1191
+ const newValue = results.find((v) => typeof v === "number");
1256
1192
  await this.afterHook("incr", { key, value, newValue });
1257
1193
  return newValue;
1258
1194
  }
@@ -1268,16 +1204,8 @@ ${valueStr}`;
1268
1204
  await this.beforeHook("decr", { key, value });
1269
1205
  this.validateKey(key);
1270
1206
  const nodes = await this.getNodesByKey(key);
1271
- const promises = nodes.map(async (node) => {
1272
- try {
1273
- const result = await node.command(`decr ${key} ${value}`);
1274
- return typeof result === "number" ? result : void 0;
1275
- } catch {
1276
- return void 0;
1277
- }
1278
- });
1279
- const results = await Promise.all(promises);
1280
- const newValue = results.find((v) => v !== void 0);
1207
+ const results = await this.execute(`decr ${key} ${value}`, nodes);
1208
+ const newValue = results.find((v) => typeof v === "number");
1281
1209
  await this.afterHook("decr", { key, value, newValue });
1282
1210
  return newValue;
1283
1211
  }
@@ -1293,16 +1221,8 @@ ${valueStr}`;
1293
1221
  await this.beforeHook("touch", { key, exptime });
1294
1222
  this.validateKey(key);
1295
1223
  const nodes = await this.getNodesByKey(key);
1296
- const promises = nodes.map(async (node) => {
1297
- try {
1298
- const result = await node.command(`touch ${key} ${exptime}`);
1299
- return result === "TOUCHED";
1300
- } catch {
1301
- return false;
1302
- }
1303
- });
1304
- const results = await Promise.all(promises);
1305
- const success = results.every((result) => result === true);
1224
+ const results = await this.execute(`touch ${key} ${exptime}`, nodes);
1225
+ const success = results.every((result) => result === "TOUCHED");
1306
1226
  await this.afterHook("touch", { key, exptime, success });
1307
1227
  return success;
1308
1228
  }
@@ -1418,6 +1338,23 @@ ${valueStr}`;
1418
1338
  }
1419
1339
  return nodes;
1420
1340
  }
1341
+ /**
1342
+ * Execute a command on the specified nodes.
1343
+ * @param {string} command - The memcache command string to execute
1344
+ * @param {MemcacheNode[]} nodes - Array of MemcacheNode instances to execute on
1345
+ * @param {ExecuteOptions} options - Optional execution options
1346
+ * @returns {Promise<unknown[]>} Promise resolving to array of results from each node
1347
+ */
1348
+ async execute(command, nodes, options) {
1349
+ const promises = nodes.map(async (node) => {
1350
+ try {
1351
+ return await node.command(command, options?.commandOptions);
1352
+ } catch {
1353
+ return void 0;
1354
+ }
1355
+ });
1356
+ return Promise.all(promises);
1357
+ }
1421
1358
  /**
1422
1359
  * Validates a Memcache key according to protocol requirements.
1423
1360
  * @param {string} key - The key to validate
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "memcache",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "Nodejs Memcache Client",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -27,16 +27,16 @@
27
27
  "author": "Jared Wray <me@jaredwray.com>",
28
28
  "license": "MIT",
29
29
  "devDependencies": {
30
- "@biomejs/biome": "^2.3.7",
31
- "@types/node": "^24.10.1",
32
- "@vitest/coverage-v8": "^4.0.13",
30
+ "@biomejs/biome": "^2.3.10",
31
+ "@types/node": "^25.0.3",
32
+ "@vitest/coverage-v8": "^4.0.16",
33
33
  "tsc": "^2.0.4",
34
34
  "tsup": "^8.5.1",
35
35
  "typescript": "^5.9.3",
36
- "vitest": "^4.0.13"
36
+ "vitest": "^4.0.16"
37
37
  },
38
38
  "dependencies": {
39
- "hookified": "^1.13.0",
39
+ "hookified": "^1.14.0",
40
40
  "rimraf": "^6.1.2"
41
41
  },
42
42
  "files": [