infinispan 0.12.0 → 0.14.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.
Files changed (113) hide show
  1. package/Dockerfile.server +8 -0
  2. package/README.md +5 -11
  3. package/docker-compose.yml +272 -0
  4. package/gen-asciidoc.sh +46 -0
  5. package/lib/codec.js +358 -27
  6. package/lib/functional.js +40 -7
  7. package/lib/infinispan.js +503 -52
  8. package/lib/io.js +399 -43
  9. package/lib/listeners.js +50 -3
  10. package/lib/near-cache.js +99 -0
  11. package/lib/protocols.js +560 -75
  12. package/lib/sasl/digest.js +22 -17
  13. package/lib/sasl/external.js +7 -4
  14. package/lib/sasl/factory.js +6 -5
  15. package/lib/sasl/oauthbearer.js +7 -5
  16. package/lib/sasl/plain.js +6 -4
  17. package/lib/sasl/scram.js +19 -11
  18. package/lib/utils.js +89 -24
  19. package/package.json +8 -7
  20. package/run-docker-testsuite.sh +72 -0
  21. package/types/index.d.ts +192 -1
  22. package/.eslintrc +0 -25
  23. package/.flowconfig +0 -6
  24. package/Jenkinsfile +0 -50
  25. package/Jenkinsfile-release +0 -63
  26. package/documentation/asciidoc/stories/assembly_client_usage_examples.adoc +0 -10
  27. package/documentation/asciidoc/stories/assembly_installation_configuration.adoc +0 -20
  28. package/documentation/asciidoc/titles/js_client.asciidoc +0 -28
  29. package/documentation/asciidoc/titles/stories.adoc +0 -5
  30. package/documentation/asciidoc/topics/attributes/community-attributes.adoc +0 -9
  31. package/documentation/asciidoc/topics/attributes/downstream-attributes.adoc +0 -2
  32. package/documentation/asciidoc/topics/code_examples/authentication-digest.js +0 -12
  33. package/documentation/asciidoc/topics/code_examples/authentication-external.js +0 -15
  34. package/documentation/asciidoc/topics/code_examples/authentication-oauthbearer.js +0 -10
  35. package/documentation/asciidoc/topics/code_examples/authentication-plain.js +0 -11
  36. package/documentation/asciidoc/topics/code_examples/authentication-scram.js +0 -11
  37. package/documentation/asciidoc/topics/code_examples/await-multiple-entries.js +0 -36
  38. package/documentation/asciidoc/topics/code_examples/await-single-entries.js +0 -29
  39. package/documentation/asciidoc/topics/code_examples/conditional-operations.js +0 -57
  40. package/documentation/asciidoc/topics/code_examples/connection-multiple-servers.js +0 -23
  41. package/documentation/asciidoc/topics/code_examples/connection-xsite-cluster-switch.js +0 -39
  42. package/documentation/asciidoc/topics/code_examples/connection-xsite.js +0 -13
  43. package/documentation/asciidoc/topics/code_examples/data-types.js +0 -30
  44. package/documentation/asciidoc/topics/code_examples/encryption-crypto-store.js +0 -11
  45. package/documentation/asciidoc/topics/code_examples/encryption-private-key.js +0 -13
  46. package/documentation/asciidoc/topics/code_examples/encryption-sni-hostname.js +0 -9
  47. package/documentation/asciidoc/topics/code_examples/encryption-trust-certs.js +0 -8
  48. package/documentation/asciidoc/topics/code_examples/ephemeral-data.js +0 -52
  49. package/documentation/asciidoc/topics/code_examples/hello-world.js +0 -42
  50. package/documentation/asciidoc/topics/code_examples/key-value-converter.js +0 -67
  51. package/documentation/asciidoc/topics/code_examples/logging-configuration.js +0 -2
  52. package/documentation/asciidoc/topics/code_examples/multiple-entries.js +0 -64
  53. package/documentation/asciidoc/topics/code_examples/queries.js +0 -92
  54. package/documentation/asciidoc/topics/code_examples/register-event-listener.js +0 -64
  55. package/documentation/asciidoc/topics/code_examples/sample-script-execute.js +0 -33
  56. package/documentation/asciidoc/topics/code_examples/sample-script.js +0 -3
  57. package/documentation/asciidoc/topics/code_examples/single-entries.js +0 -49
  58. package/documentation/asciidoc/topics/config_examples/logging.json +0 -14
  59. package/documentation/asciidoc/topics/proc_configuring_authentication.adoc +0 -16
  60. package/documentation/asciidoc/topics/proc_configuring_connections.adoc +0 -25
  61. package/documentation/asciidoc/topics/proc_configuring_connections_xsite.adoc +0 -18
  62. package/documentation/asciidoc/topics/proc_configuring_data_formats.adoc +0 -30
  63. package/documentation/asciidoc/topics/proc_configuring_encryption.adoc +0 -15
  64. package/documentation/asciidoc/topics/proc_configuring_logging.adoc +0 -28
  65. package/documentation/asciidoc/topics/proc_installing_clients.adoc +0 -58
  66. package/documentation/asciidoc/topics/proc_switching_clusters.adoc +0 -17
  67. package/documentation/asciidoc/topics/ref_authentication_mechanisms.adoc +0 -68
  68. package/documentation/asciidoc/topics/ref_client_usage.adoc +0 -128
  69. package/documentation/asciidoc/topics/ref_encryption.adoc +0 -71
  70. package/gen-jsdoc.sh +0 -6
  71. package/make-ssl.sh +0 -335
  72. package/memory-profiling/helper.js +0 -9
  73. package/memory-profiling/infinispan_memory_many_get.js +0 -50
  74. package/memory-profiling/infinispan_memory_one_get.js +0 -56
  75. package/release.sh +0 -19
  76. package/run-servers.sh +0 -171
  77. package/run-testsuite.sh +0 -6
  78. package/server/.keep +0 -0
  79. package/set-npm-auth-token.sh +0 -4
  80. package/smoke-tests.sh +0 -21
  81. package/spec/codec_spec.js +0 -224
  82. package/spec/configs/clean/infinispan.xml +0 -55
  83. package/spec/configs/infinispan-clustered.xml +0 -63
  84. package/spec/configs/infinispan-ssl.xml +0 -115
  85. package/spec/configs/infinispan-xsite-EARTH.xml +0 -187
  86. package/spec/configs/infinispan-xsite-MOON.xml +0 -189
  87. package/spec/configs/infinispan.xml +0 -77
  88. package/spec/functional_spec.js +0 -73
  89. package/spec/infinispan_auth_spec.js +0 -19
  90. package/spec/infinispan_cluster_spec.js +0 -176
  91. package/spec/infinispan_expiry_spec.js +0 -218
  92. package/spec/infinispan_failover_listener_spec.js +0 -52
  93. package/spec/infinispan_failover_spec.js +0 -63
  94. package/spec/infinispan_json_spec.js +0 -182
  95. package/spec/infinispan_local_spec.js +0 -354
  96. package/spec/infinispan_ssl_spec.js +0 -442
  97. package/spec/infinispan_stress_spec.js +0 -32
  98. package/spec/infinispan_xsite_spec.js +0 -99
  99. package/spec/protocols_spec.js +0 -82
  100. package/spec/protostream_spec.js +0 -237
  101. package/spec/tests.js +0 -28
  102. package/spec/utils/test-log4js.json +0 -14
  103. package/spec/utils/testing.js +0 -762
  104. package/spec/utils/typed-cachemanager-put-get.js +0 -3
  105. package/spec/utils/typed-null-return-dist.js +0 -2
  106. package/spec/utils/typed-null-return.js +0 -2
  107. package/spec/utils/typed-put-get-dist.js +0 -3
  108. package/spec/utils/typed-put-get-unicode.js +0 -3
  109. package/spec/utils/typed-put-get.js +0 -3
  110. package/spec/utils/typed-size.js +0 -2
  111. package/spec/utils_spec.js +0 -154
  112. package/spec-manual/infinispan_manual_stress_get_spec.js +0 -50
  113. package/spec-manual/infinispan_manual_stress_iterate_spec.js +0 -86
package/lib/infinispan.js CHANGED
@@ -16,24 +16,28 @@
16
16
  var protocols = require('./protocols');
17
17
  var io = require('./io');
18
18
  var listeners = require('./listeners');
19
+ var nearCacheFactory = require('./near-cache');
19
20
 
20
21
  var Client = function(addrs, clientOpts) {
21
22
  var logger = u.logger('client');
22
23
 
24
+ /**
25
+ * Resolves the protocol implementation for a given version string.
26
+ * @param {string} version Protocol version (e.g. '2.9', '3.0').
27
+ * @returns {Object} Protocol instance for the specified version.
28
+ */
23
29
  function protocolResolver(version) {
24
- logger.debugf('Using protocol version: %s', version);
25
-
26
- switch (version) {
27
- case '3.0': return protocols.version30(clientOpts);
28
- case '2.9': return protocols.version29(clientOpts);
29
- case '2.5': return protocols.version25(clientOpts);
30
- case '2.2': return protocols.version22(clientOpts);
31
- default : throw new Error('Unknown protocol version: ' + version);
30
+ if (version === 'auto') {
31
+ logger.debugf('Using protocol auto-negotiation (starting with %s)', protocols.VERSION_ORDER[0]);
32
+ return protocols.resolve(protocols.VERSION_ORDER[0], clientOpts);
32
33
  }
34
+ logger.debugf('Using protocol version: %s', version);
35
+ return protocols.resolve(version, clientOpts);
33
36
  }
34
37
 
35
38
  var p = protocolResolver(clientOpts['version']);
36
39
  var listen = listeners(p);
40
+ var nc = clientOpts.nearCache ? nearCacheFactory(clientOpts.nearCache.maxEntries) : null;
37
41
 
38
42
  var TINY = 16, SMALL = 32, MEDIUM = 64, BIG = 128;
39
43
 
@@ -41,31 +45,82 @@
41
45
  var events = ['create', 'modify', 'remove', 'expiry'];
42
46
  Object.freeze(events);
43
47
 
48
+ /**
49
+ * Sends a request with header and body, returning a promise for the decoded response.
50
+ * @param {Object} ctx Request context with buffer and id.
51
+ * @param {number} op Operation code.
52
+ * @param {Function} body Body encoder function.
53
+ * @param {Function} decoder Response decoder function.
54
+ * @param {Object} [opts] Optional operation options.
55
+ * @returns {Promise} Promise resolved with the decoded response.
56
+ */
44
57
  function future(ctx, op, body, decoder, opts) {
45
58
  f.actions(p.stepsHeaderBody(ctx, op, body, opts), codec.bytesEncoded)(ctx);
46
59
  return transport.writeCommand(ctx, decoder);
47
60
  }
48
61
 
62
+ /**
63
+ * Sends a header-only request and decodes the response.
64
+ * @param {Object} ctx Request context with buffer and id.
65
+ * @param {number} op Operation code.
66
+ * @param {Function} decoder Response decoder function.
67
+ * @param {Object} [opts] Optional operation options.
68
+ * @returns {Promise} Promise resolved with the decoded response.
69
+ */
49
70
  function futureDecodeOnly(ctx, op, decoder, opts) {
50
71
  f.actions(p.stepsHeader(ctx, op, opts), codec.bytesEncoded)(ctx);
51
72
  return transport.writeCommand(ctx, decoder);
52
73
  }
53
74
 
75
+ /**
76
+ * Sends a header-only request with no decoder.
77
+ * @param {Object} ctx Request context with buffer and id.
78
+ * @param {number} op Operation code.
79
+ * @returns {Promise} Promise resolved when the operation completes.
80
+ */
54
81
  function futureEmpty(ctx, op) {
55
82
  f.actions(p.stepsHeader(ctx, op), codec.bytesEncoded)(ctx);
56
83
  return transport.writeCommand(ctx);
57
84
  }
58
85
 
86
+ /**
87
+ * Sends a key-routed request with body, using consistent hashing for server selection.
88
+ * @param {Object} ctx Request context with buffer and id.
89
+ * @param {number} op Operation code.
90
+ * @param {string|Object} key Key used for routing.
91
+ * @param {Function} body Body encoder function.
92
+ * @param {Function} decoder Response decoder function.
93
+ * @param {Object} [opts] Optional operation options.
94
+ * @returns {Promise} Promise resolved with the decoded response.
95
+ */
59
96
  function futureKey(ctx, op, key, body, decoder, opts) {
60
97
  f.actions(p.stepsHeaderBody(ctx, op, body, opts), codec.bytesEncoded)(ctx);
61
98
  return transport.writeKeyCommand(ctx, key, decoder);
62
99
  }
63
100
 
101
+ /**
102
+ * Sends a request pinned to a specific connection.
103
+ * @param {Object} ctx Request context with buffer and id.
104
+ * @param {number} op Operation code.
105
+ * @param {Function} body Body encoder function.
106
+ * @param {Function} decoder Response decoder function.
107
+ * @param {Object} conn Connection to pin the request to.
108
+ * @returns {Promise} Promise resolved with the decoded response.
109
+ */
64
110
  function futurePinned(ctx, op, body, decoder, conn) {
65
111
  f.actions(p.stepsHeaderBody(ctx, op, body), codec.bytesEncoded)(ctx);
66
112
  return transport.writeCommandPinned(ctx, decoder, conn);
67
113
  }
68
114
 
115
+ /**
116
+ * Sends a script execution request and post-processes nulls in the response.
117
+ * @param {Object} ctx Request context with buffer and id.
118
+ * @param {number} op Operation code.
119
+ * @param {Function} body Body encoder function.
120
+ * @param {Function} decoder Response decoder function.
121
+ * @param {Object} [opts] Optional operation options.
122
+ * @returns {Promise<string>} Promise resolved with the execution result.
123
+ */
69
124
  function futureExec(ctx, op, body, decoder, opts) {
70
125
  f.actions(p.stepsHeaderBody(ctx, op, body, opts), codec.bytesEncoded)(ctx);
71
126
  var resultPromise = transport.writeCommand(ctx, decoder);
@@ -79,6 +134,11 @@
79
134
  });
80
135
  }
81
136
 
137
+ /**
138
+ * Checks whether the given event name is a supported listener event.
139
+ * @param {string} event Event name to check.
140
+ * @returns {boolean} True if the event is supported.
141
+ */
82
142
  function isEventDefined(event) {
83
143
  var exists = false;
84
144
  var eventLowerCase = event.toLowerCase();
@@ -96,6 +156,9 @@
96
156
  /**
97
157
  * Iterator instance returned by completed promise from Client.iterator() calls.
98
158
  *
159
+ * @param {String} iterId Iterator identifier.
160
+ * @param {Object} conn Connection instance.
161
+ * @returns {Object} Iterator instance with close and next methods.
99
162
  * @constructs Iterator
100
163
  * @since 0.3
101
164
  */
@@ -103,6 +166,10 @@
103
166
  var nextElems = [];
104
167
  var done = false;
105
168
 
169
+ /**
170
+ * Returns a promise fulfilled with the next cached entry.
171
+ * @returns {Promise<Object>} Promise with the next entry and done status.
172
+ */
106
173
  function nextPromise() {
107
174
  var kv = nextElems.pop();
108
175
  return new Promise(function (fulfill, reject) {
@@ -110,6 +177,10 @@
110
177
  });
111
178
  }
112
179
 
180
+ /**
181
+ * Returns a promise indicating iteration is complete.
182
+ * @returns {Promise<Object>} Promise with done set to true.
183
+ */
113
184
  function donePromise() {
114
185
  return new Promise(function (fulfill, reject) {
115
186
  fulfill({done: done});
@@ -180,7 +251,7 @@
180
251
  return futurePinned(
181
252
  ctx, 0x35, p.encodeIterId(iterId), p.complete(p.hasSuccess), conn);
182
253
  }
183
- }
254
+ };
184
255
  }
185
256
 
186
257
  return {
@@ -188,6 +259,29 @@
188
259
  // TODO: Avoid user calling connect by checking if connected
189
260
  var client = this;
190
261
  return transport.connect()
262
+ .then(function() {
263
+ if (clientOpts.version === 'auto') {
264
+ var negotiatedProtocol = transport.getProtocol();
265
+ p = negotiatedProtocol;
266
+ listen.setProtocol(negotiatedProtocol);
267
+ logger.debugf('Negotiated protocol version: %s', p.getVersionString());
268
+ }
269
+ })
270
+ .then(function() {
271
+ if (nc) {
272
+ var invalidate = function(key) { nc.remove(key); };
273
+ return client.addListener('create', invalidate)
274
+ .then(function(listenerId) {
275
+ return client.addListener('modify', invalidate, {listenerId: listenerId});
276
+ })
277
+ .then(function(listenerId) {
278
+ return client.addListener('remove', invalidate, {listenerId: listenerId});
279
+ })
280
+ .then(function(listenerId) {
281
+ return client.addListener('expiry', invalidate, {listenerId: listenerId});
282
+ });
283
+ }
284
+ })
191
285
  .then(function() {
192
286
  logger.debugf('Started Infinispan %s', client);
193
287
  return client; // return client
@@ -208,12 +302,23 @@
208
302
  * @since 0.3
209
303
  */
210
304
  disconnect: function() {
305
+ if (nc) nc.clear();
211
306
  return transport.disconnect();
212
307
  },
308
+ /**
309
+ * Returns the active protocol version string (e.g. '3.1', '4.1').
310
+ * When using auto-negotiation, this reflects the negotiated version.
311
+ *
312
+ * @returns {string} Protocol version string.
313
+ * @memberof Client#
314
+ */
315
+ getProtocolVersion: function() {
316
+ return p.getVersionString();
317
+ },
213
318
  /**
214
319
  * Get the value associated with the given key parameter.
215
320
  *
216
- * @param k {(String|Object)} Key to retrieve.
321
+ * @param {(String|Object)} k Key to retrieve.
217
322
  * @returns {Promise.<?String>}
218
323
  * A promise that will be completed with the value associated with
219
324
  * the key, or undefined if the value is not present.
@@ -221,18 +326,33 @@
221
326
  * @since 0.3
222
327
  */
223
328
  get: function(k) {
329
+ if (nc) {
330
+ var cached = nc.get(k);
331
+ if (cached !== undefined) {
332
+ return Promise.resolve(cached);
333
+ }
334
+ }
224
335
  var ctx = transport.context(SMALL);
225
336
  logger.debugf('Invoke get(msgId=%d,key=%s)', ctx.id, u.str(k));
226
337
  var decoder = p.decodeValue();
227
- return futureKey(ctx, 0x03, k, p.encodeKey(k), decoder);
338
+ var result = futureKey(ctx, 0x03, k, p.encodeKey(k), decoder);
339
+ if (nc) {
340
+ return result.then(function(value) {
341
+ if (value !== undefined) {
342
+ nc.put(k, value);
343
+ }
344
+ return value;
345
+ });
346
+ }
347
+ return result;
228
348
  },
229
349
  /**
230
350
  * Query the server with the given queryString.
231
351
  *
232
- * @param q {(Object)} query to retrieve.
233
- * @returns {Promise.<?Object[]>}
352
+ * @param {Object} q Query to retrieve.
353
+ * @returns {Promise.<Object[]>}
234
354
  * A promise that will be completed with the array of values associated with
235
- * the query, or empty array if the no values matches the query.
355
+ * the query, or empty array if no values match the query.
236
356
  * @memberof Client#
237
357
  * @since 1.3
238
358
  */
@@ -246,7 +366,7 @@
246
366
  /**
247
367
  * Check whether the given key is present.
248
368
  *
249
- * @param k {(String|Object)} Key to check for presence.
369
+ * @param {(String|Object)} k Key to check for presence.
250
370
  * @returns {Promise.<boolean>}
251
371
  * A promise that will be completed with true if there is a value
252
372
  * associated with the key, or false otherwise.
@@ -273,7 +393,7 @@
273
393
  /**
274
394
  * Get the value and metadata associated with the given key parameter.
275
395
  *
276
- * @param k {(String|Object)} Key to retrieve.
396
+ * @param {(String|Object)} k Key to retrieve.
277
397
  * @returns {Promise.<?MetadataValue>}
278
398
  * A promise that will be completed with the value and metadata
279
399
  * associated with the key, or undefined if the value is not present.
@@ -284,7 +404,16 @@
284
404
  var ctx = transport.context(SMALL);
285
405
  logger.debugf('Invoke getWithMetadata(msgId=%d,key=%s)', ctx.id, u.str(k));
286
406
  var decoder = p.decodeWithMeta();
287
- return futureKey(ctx, 0x1B, k, p.encodeKey(k), decoder);
407
+ var result = futureKey(ctx, 0x1B, k, p.encodeKey(k), decoder);
408
+ if (nc) {
409
+ return result.then(function(meta) {
410
+ if (meta !== undefined) {
411
+ nc.put(k, meta.value);
412
+ }
413
+ return meta;
414
+ });
415
+ }
416
+ return result;
288
417
  },
289
418
  /**
290
419
  * A String formatted to specify duration unit information.
@@ -314,9 +443,9 @@
314
443
  /**
315
444
  * Associates the specified value with the given key.
316
445
  *
317
- * @param k {(String|Object)} Key with which the specified value is to be associated.
318
- * @param v {(String|Object)} Value to be associated with the specified key.
319
- * @param opts {StoreOptions=} Optional store options.
446
+ * @param {(String|Object)} k Key with which the specified value is to be associated.
447
+ * @param {(String|Object)} v Value to be associated with the specified key.
448
+ * @param {StoreOptions=} opts Optional store options.
320
449
  * @returns {Promise.<?(String|Object)>}
321
450
  * A promise that will be completed with undefined unless 'previous'
322
451
  * option has been enabled and a previous value exists, in which case it
@@ -325,6 +454,7 @@
325
454
  * @since 0.3
326
455
  */
327
456
  put: function(k, v, opts) {
457
+ if (nc) nc.remove(k);
328
458
  var ctx = transport.context(MEDIUM);
329
459
  logger.debugl(function() { return ['Invoke put(msgId=%d,key=%s,value=%s,opts=%s)',
330
460
  ctx.id, u.str(k), u.str(v), u.str(opts)]; });
@@ -344,8 +474,8 @@
344
474
  /**
345
475
  * Removes the mapping for a key if it is present.
346
476
  *
347
- * @param k {(String|Object)} Key whose mapping is to be removed.
348
- * @param opts {RemoveOptions=} Optional remove options.
477
+ * @param {(String|Object)} k Key whose mapping is to be removed.
478
+ * @param {RemoveOptions=} opts Optional remove options.
349
479
  * @returns {Promise.<(Boolean|String|Object)>}
350
480
  * A promise that will be completed with true if the mapping was removed,
351
481
  * or false if the key did not exist.
@@ -355,6 +485,7 @@
355
485
  * @since 0.3
356
486
  */
357
487
  remove: function(k, opts) {
488
+ if (nc) nc.remove(k);
358
489
  var ctx = transport.context(SMALL);
359
490
  logger.debugl(function() {return ['Invoke remove(msgId=%d,key=%s,opts=%s)',
360
491
  ctx.id, u.str(k), JSON.stringify(opts)]; });
@@ -365,9 +496,9 @@
365
496
  * Conditional store operation that associates the key with the given
366
497
  * value if the specified key is not already associated with a value.
367
498
  *
368
- * @param k {(String|Object)} Key with which the specified value is to be associated.
369
- * @param v {(String|Object)} Value to be associated with the specified key.
370
- * @param opts {StoreOptions=} Optional store options.
499
+ * @param {(String|Object)} k Key with which the specified value is to be associated.
500
+ * @param {(String|Object)} v Value to be associated with the specified key.
501
+ * @param {StoreOptions=} opts Optional store options.
371
502
  * @returns {Promise.<(Boolean|String|Object)>}
372
503
  * A promise that will be completed with true if the mapping was stored,
373
504
  * or false if the key is already present.
@@ -377,6 +508,7 @@
377
508
  * @since 0.3
378
509
  */
379
510
  putIfAbsent: function(k, v, opts) {
511
+ if (nc) nc.remove(k);
380
512
  var ctx = transport.context(MEDIUM);
381
513
  logger.debugl(function() {return ['Invoke putIfAbsent(msgId=%d,key=%s,value=%s,opts=%s)',
382
514
  ctx.id, u.str(k), u.str(v), JSON.stringify(opts)]; });
@@ -387,9 +519,9 @@
387
519
  * Conditional store operation that replaces the entry for a key only
388
520
  * if currently mapped to a given value.
389
521
  *
390
- * @param k {(String|Object)} Key with which the specified value is associated.
391
- * @param v {(String|Object)} Value expected to be associated with the specified key.
392
- * @param opts {StoreOptions=} Optional store options.
522
+ * @param {(String|Object)} k Key with which the specified value is associated.
523
+ * @param {(String|Object)} v Value expected to be associated with the specified key.
524
+ * @param {StoreOptions=} opts Optional store options.
393
525
  * @returns {Promise.<(Boolean|String|Object)>}
394
526
  * A promise that will be completed with true if the mapping was replaced,
395
527
  * or false if the key does not exist.
@@ -399,6 +531,7 @@
399
531
  * @since 0.3
400
532
  */
401
533
  replace: function(k, v, opts) {
534
+ if (nc) nc.remove(k);
402
535
  var ctx = transport.context(MEDIUM);
403
536
  logger.debugl(function() { return ['Invoke replace(msgId=%d,key=%s,value=%s,opts=%s)',
404
537
  ctx.id, u.str(k), u.str(v), JSON.stringify(opts)]; });
@@ -409,12 +542,12 @@
409
542
  * Replaces the given value only if its version matches the supplied
410
543
  * version.
411
544
  *
412
- * @param k {(String|Object)} Key with which the specified value is associated.
413
- * @param v {(String|Object)} Value expected to be associated with the specified key.
414
- * @param version {Buffer} binary buffer version that should match the
545
+ * @param {(String|Object)} k Key with which the specified value is associated.
546
+ * @param {(String|Object)} v Value expected to be associated with the specified key.
547
+ * @param {Buffer} version binary buffer version that should match the
415
548
  * one in the server for the operation to succeed. Version information
416
549
  * can be retrieved with getWithMetadata method.
417
- * @param opts {StoreOptions=} Optional store options.
550
+ * @param {StoreOptions=} opts Optional store options.
418
551
  * @returns {Promise.<(Boolean|String|Object)>}
419
552
  * A promise that will be completed with true if the version matches
420
553
  * and the mapping was replaced, otherwise it returns false if not
@@ -428,6 +561,7 @@
428
561
  * @since 0.3
429
562
  */
430
563
  replaceWithVersion: function(k, v, version, opts) {
564
+ if (nc) nc.remove(k);
431
565
  var ctx = transport.context(MEDIUM);
432
566
  logger.debugl(function() { return ['Invoke replaceWithVersion(msgId=%d,key=%s,value=%s,version=0x%s,opts=%s)',
433
567
  ctx.id, u.str(k), u.str(v), version.toString('hex'), JSON.stringify(opts)]; });
@@ -438,11 +572,11 @@
438
572
  * Removes the given entry only if its version matches the
439
573
  * supplied version.
440
574
  *
441
- * @param k {(String|Object)} Key whose mapping is to be removed.
442
- * @param version {Buffer} binary buffer version that should match the
575
+ * @param {(String|Object)} k Key whose mapping is to be removed.
576
+ * @param {Buffer} version binary buffer version that should match the
443
577
  * one in the server for the operation to succeed. Version information
444
578
  * can be retrieved with getWithMetadata method.
445
- * @param opts {RemoveOptions=} Optional remove options.
579
+ * @param {RemoveOptions=} opts Optional remove options.
446
580
  * @returns {Promise.<(Boolean|String|Object)>}
447
581
  * A promise that will be completed with true if the version matches
448
582
  * and the mapping was removed, otherwise it returns false if not
@@ -456,6 +590,7 @@
456
590
  * @since 0.3
457
591
  */
458
592
  removeWithVersion: function(k, version, opts) {
593
+ if (nc) nc.remove(k);
459
594
  var ctx = transport.context(SMALL);
460
595
  logger.debugl(function() { return ['Invoke removeWithVersion(msgId=%d,key=%s,version=0x%s,opts=%s)',
461
596
  ctx.id, u.str(k), version.toString('hex'), JSON.stringify(opts)]; });
@@ -473,7 +608,7 @@
473
608
  /**
474
609
  * Retrieves all of the entries for the provided keys.
475
610
  *
476
- * @param keys {(String[]|Object[])} Keys to find values for.
611
+ * @param {(String[]|Object[])} keys Keys to find values for.
477
612
  * @returns {Promise.<Entry[]>}
478
613
  * A promise that will be completed with an array of entries for all
479
614
  * keys found. If a key does not exist, there won't be an entry for that
@@ -501,8 +636,8 @@
501
636
  /**
502
637
  * Stores all of the mappings from the specified entry array.
503
638
  *
504
- * @param pairs {Entry[]} key/value pair mappings to be stored
505
- * @param opts {MultiStoreOptions=}
639
+ * @param {Entry[]} pairs key/value pair mappings to be stored
640
+ * @param {MultiStoreOptions=} opts
506
641
  * Optional storage options to apply to all entries.
507
642
  * @returns {Promise}
508
643
  * A promise that will be completed when all entries have been stored.
@@ -510,6 +645,9 @@
510
645
  * @since 0.3
511
646
  */
512
647
  putAll: function(pairs, opts) {
648
+ if (nc) {
649
+ _.each(pairs, function(pair) { nc.remove(pair.key); });
650
+ }
513
651
  var ctx = transport.context(BIG);
514
652
  logger.debugl(function() { return ['Invoke putAll(msgId=%d,pairs=%s,opts=%s)',
515
653
  ctx.id, JSON.stringify(pairs), JSON.stringify(opts)]; });
@@ -528,9 +666,9 @@
528
666
  /**
529
667
  * Iterate over the entries stored in server(s).
530
668
  *
531
- * @param batchSize {Number}
669
+ * @param {Number} batchSize
532
670
  * The number of entries transferred from the server at a time.
533
- * @param opts {IteratorOptions=} Optional iteration settings.
671
+ * @param {IteratorOptions=} opts Optional iteration settings.
534
672
  * @return {Promise.<Iterator>}
535
673
  * A promise that will be completed with an iterator that can be used
536
674
  * to retrieve stored elements.
@@ -567,6 +705,7 @@
567
705
  * @since 0.3
568
706
  */
569
707
  clear: function() {
708
+ if (nc) nc.clear();
570
709
  var ctx = transport.context(TINY);
571
710
  logger.debugf('Invoke clear(msgId=%d)', ctx.id);
572
711
  return futureEmpty(ctx, 0x13);
@@ -632,7 +771,7 @@
632
771
  * entry version and listener id.
633
772
  * 'remove' and 'expiry' events callback the function with key
634
773
  * and listener id.
635
- * @param opts {ListenOptions=} Options for adding listener.
774
+ * @param {ListenOptions=} opts Options for adding listener.
636
775
  * @returns {Promise<String>}
637
776
  * A promise that will be completed with the identifier of the listener.
638
777
  * This identifier can be used to register multiple callbacks with the
@@ -647,7 +786,7 @@
647
786
  var conn = listen.findConnectionListener(opts.listenerId);
648
787
  if (!f.existy(conn))
649
788
  return Promise.reject(
650
- new Error('No server connection for listener (listenerId=' + opts.listenerId + ')'));
789
+ new Error(`No server connection for listener (listenerId=${ opts.listenerId })`));
651
790
 
652
791
  return listen.addLocalListener(ctx, event, listener, opts);
653
792
  } else {
@@ -655,7 +794,7 @@
655
794
  }
656
795
  } else {
657
796
  return Promise.reject(
658
- new Error('The event \'' + event + '\' is not supported'));
797
+ new Error(`The event '${ event }' is not supported`));
659
798
  }
660
799
  },
661
800
  /**
@@ -674,7 +813,7 @@
674
813
  var conn = listen.findConnectionListener(listenerId);
675
814
  if (!f.existy(conn))
676
815
  return Promise.reject(
677
- new Error('No server connection for listener (listenerId=' + listenerId + ')'));
816
+ new Error(`No server connection for listener (listenerId=${ listenerId })`));
678
817
 
679
818
  var remote = futurePinned(ctx, 0x27, p.encodeListenerId(listenerId), p.complete(p.hasSuccess), conn);
680
819
  return remote.then(function (success) {
@@ -734,6 +873,153 @@
734
873
  // TODO update jsdoc, value does not need to be String, can be JSON too
735
874
  return futureExec(ctx, 0x2B, p.encodeNameParams(scriptName, params), p.decodeValue());
736
875
  },
876
+ /**
877
+ * Counter configuration options.
878
+ *
879
+ * @typedef {Object} CounterConfig
880
+ * @property {('strong'|'weak')} type - Counter type.
881
+ * @property {('persistent'|'volatile')} [storage='volatile'] - Storage mode.
882
+ * @property {Number} [initialValue=0] - Initial counter value.
883
+ * @property {Number} [lowerBound] - Lower bound (strong bounded counters only).
884
+ * @property {Number} [upperBound] - Upper bound (strong bounded counters only).
885
+ * @property {Number} [concurrencyLevel=16] - Concurrency level (weak counters only).
886
+ * @since 0.14
887
+ */
888
+ /**
889
+ * Create a distributed counter.
890
+ *
891
+ * @param {String} name Counter name.
892
+ * @param {CounterConfig} config Counter configuration.
893
+ * @returns {Promise.<Boolean>}
894
+ * A promise that will be completed with true if the counter was created,
895
+ * or false if it already exists.
896
+ * @memberof Client#
897
+ * @since 0.14
898
+ */
899
+ counterCreate: function(name, config) {
900
+ var ctx = transport.context(MEDIUM);
901
+ logger.debugf('Invoke counterCreate(msgId=%d,name=%s)', ctx.id, name);
902
+ return future(ctx, 0x4B, p.encodeCounterCreate(name, config), p.decodeCounterStatus);
903
+ },
904
+ /**
905
+ * Get the current value of a counter.
906
+ *
907
+ * @param {String} name Counter name.
908
+ * @returns {Promise.<?Number>}
909
+ * A promise that will be completed with the counter value,
910
+ * or undefined if the counter is not defined.
911
+ * @memberof Client#
912
+ * @since 0.14
913
+ */
914
+ counterGet: function(name) {
915
+ var ctx = transport.context(SMALL);
916
+ logger.debugf('Invoke counterGet(msgId=%d,name=%s)', ctx.id, name);
917
+ return future(ctx, 0x56, p.encodeCounterName(name), p.decodeCounterValue);
918
+ },
919
+ /**
920
+ * Add a value to the counter and return the new value.
921
+ *
922
+ * @param {String} name Counter name.
923
+ * @param {Number} value Value to add (can be negative).
924
+ * @returns {Promise.<?Number>}
925
+ * A promise that will be completed with the new counter value.
926
+ * @memberof Client#
927
+ * @since 0.14
928
+ */
929
+ counterAddAndGet: function(name, value) {
930
+ var ctx = transport.context(SMALL);
931
+ logger.debugf('Invoke counterAddAndGet(msgId=%d,name=%s,value=%d)', ctx.id, name, value);
932
+ return future(ctx, 0x52, p.encodeCounterNameValue(name, value), p.decodeCounterValue);
933
+ },
934
+ /**
935
+ * Reset the counter to its initial value.
936
+ *
937
+ * @param {String} name Counter name.
938
+ * @returns {Promise.<Boolean>}
939
+ * A promise that will be completed with true if the counter was reset.
940
+ * @memberof Client#
941
+ * @since 0.14
942
+ */
943
+ counterReset: function(name) {
944
+ var ctx = transport.context(SMALL);
945
+ logger.debugf('Invoke counterReset(msgId=%d,name=%s)', ctx.id, name);
946
+ return future(ctx, 0x54, p.encodeCounterName(name), p.decodeCounterStatus);
947
+ },
948
+ /**
949
+ * Compare and swap the counter value.
950
+ *
951
+ * @param {String} name Counter name.
952
+ * @param {Number} expect Expected current value.
953
+ * @param {Number} update New value to set if current matches expected.
954
+ * @returns {Promise.<?Number>}
955
+ * A promise that will be completed with the counter value
956
+ * (the old value if successful, or current value if not).
957
+ * @memberof Client#
958
+ * @since 0.14
959
+ */
960
+ counterCompareAndSwap: function(name, expect, update) {
961
+ var ctx = transport.context(SMALL);
962
+ logger.debugf('Invoke counterCompareAndSwap(msgId=%d,name=%s,expect=%d,update=%d)', ctx.id, name, expect, update);
963
+ return future(ctx, 0x58, p.encodeCounterNameTwoLongs(name, expect, update), p.decodeCounterValue);
964
+ },
965
+ /**
966
+ * Check if a counter is defined.
967
+ *
968
+ * @param {String} name Counter name.
969
+ * @returns {Promise.<Boolean>}
970
+ * A promise that will be completed with true if the counter is defined.
971
+ * @memberof Client#
972
+ * @since 0.14
973
+ */
974
+ counterIsDefined: function(name) {
975
+ var ctx = transport.context(SMALL);
976
+ logger.debugf('Invoke counterIsDefined(msgId=%d,name=%s)', ctx.id, name);
977
+ return future(ctx, 0x4F, p.encodeCounterName(name), p.decodeCounterStatus);
978
+ },
979
+ /**
980
+ * Get the configuration of a counter.
981
+ *
982
+ * @param {String} name Counter name.
983
+ * @returns {Promise.<?CounterConfig>}
984
+ * A promise that will be completed with the counter configuration,
985
+ * or undefined if the counter is not defined.
986
+ * @memberof Client#
987
+ * @since 0.14
988
+ */
989
+ counterGetConfiguration: function(name) {
990
+ var ctx = transport.context(SMALL);
991
+ logger.debugf('Invoke counterGetConfiguration(msgId=%d,name=%s)', ctx.id, name);
992
+ return future(ctx, 0x4D, p.encodeCounterName(name), p.decodeCounterConfig);
993
+ },
994
+ /**
995
+ * Remove a counter from the cluster.
996
+ *
997
+ * @param {String} name Counter name.
998
+ * @returns {Promise.<Boolean>}
999
+ * A promise that will be completed with true if the counter was removed.
1000
+ * @memberof Client#
1001
+ * @since 0.14
1002
+ */
1003
+ counterRemove: function(name) {
1004
+ var ctx = transport.context(SMALL);
1005
+ logger.debugf('Invoke counterRemove(msgId=%d,name=%s)', ctx.id, name);
1006
+ return future(ctx, 0x5E, p.encodeCounterName(name), p.decodeCounterStatus);
1007
+ },
1008
+ /**
1009
+ * Set a value to the counter and return the previous value.
1010
+ *
1011
+ * @param {String} name Counter name.
1012
+ * @param {Number} value Value to set.
1013
+ * @returns {Promise.<?Number>}
1014
+ * A promise that will be completed with the previous counter value.
1015
+ * @memberof Client#
1016
+ * @since 0.14
1017
+ */
1018
+ counterGetAndSet: function(name, value) {
1019
+ var ctx = transport.context(SMALL);
1020
+ logger.debugf('Invoke counterGetAndSet(msgId=%d,name=%s,value=%d)', ctx.id, name, value);
1021
+ return future(ctx, 0x7F, p.encodeCounterNameValue(name, value), p.decodeCounterValue);
1022
+ },
737
1023
  /**
738
1024
  * Get server topology related information.
739
1025
  *
@@ -748,6 +1034,7 @@
748
1034
  },
749
1035
  /**
750
1036
  * Get client information represented as a string.
1037
+ * @returns {String} String representation of the client.
751
1038
  * @memberof Client#
752
1039
  * @since 0.4
753
1040
  */
@@ -761,13 +1048,175 @@
761
1048
 
762
1049
  registerProtostreamRoot: function(root){
763
1050
  return p.registerProtostreamRoot(root);
1051
+ },
1052
+ /**
1053
+ * Get the number of entries in the near cache.
1054
+ *
1055
+ * @returns {Number} Number of entries in the near cache, or 0 if near caching is not enabled.
1056
+ * @memberof Client#
1057
+ * @since 0.14
1058
+ */
1059
+ nearCacheSize: function() {
1060
+ return nc ? nc.size() : 0;
1061
+ },
1062
+
1063
+ /**
1064
+ * Admin operations for cache lifecycle, schema management, and indexing.
1065
+ * These operations use Hot Rod server tasks (exec opcode 0x2B) with
1066
+ * predefined @@-prefixed task names.
1067
+ * @memberof Client#
1068
+ * @since 0.15
1069
+ */
1070
+ admin: {
1071
+ /**
1072
+ * Create a cache with the given configuration.
1073
+ *
1074
+ * @param {String} name Cache name.
1075
+ * @param {String} config Cache configuration (XML or JSON).
1076
+ * @param {Object} [opts] Optional settings.
1077
+ * @param {String} [opts.template] Template name to use instead of config.
1078
+ * @param {String} [opts.flags] Admin flags (e.g. 'VOLATILE' for non-persistent caches).
1079
+ * @returns {Promise} A promise that completes when the cache is created.
1080
+ * @memberof Client.admin#
1081
+ * @since 0.15
1082
+ */
1083
+ createCache: function(name, config, opts) {
1084
+ var params = {name: name};
1085
+ if (f.existy(config)) params.configuration = config;
1086
+ if (f.existy(opts) && f.existy(opts.template)) params.template = opts.template;
1087
+ if (f.existy(opts) && f.existy(opts.flags)) params.flags = opts.flags;
1088
+ var ctx = transport.context(MEDIUM);
1089
+ logger.debugf('Invoke admin.createCache(msgId=%d,name=%s)', ctx.id, name);
1090
+ return future(ctx, 0x2B, p.encodeNameParams('@@cache@create', params), p.decodeValue());
1091
+ },
1092
+ /**
1093
+ * Get an existing cache or create it with the given configuration.
1094
+ *
1095
+ * @param {String} name Cache name.
1096
+ * @param {String} config Cache configuration (XML or JSON).
1097
+ * @param {Object} [opts] Optional settings.
1098
+ * @param {String} [opts.template] Template name to use instead of config.
1099
+ * @param {String} [opts.flags] Admin flags (e.g. 'VOLATILE').
1100
+ * @returns {Promise} A promise that completes when the cache is available.
1101
+ * @memberof Client.admin#
1102
+ * @since 0.15
1103
+ */
1104
+ getOrCreateCache: function(name, config, opts) {
1105
+ var params = {name: name};
1106
+ if (f.existy(config)) params.configuration = config;
1107
+ if (f.existy(opts) && f.existy(opts.template)) params.template = opts.template;
1108
+ if (f.existy(opts) && f.existy(opts.flags)) params.flags = opts.flags;
1109
+ var ctx = transport.context(MEDIUM);
1110
+ logger.debugf('Invoke admin.getOrCreateCache(msgId=%d,name=%s)', ctx.id, name);
1111
+ return future(ctx, 0x2B, p.encodeNameParams('@@cache@getorcreate', params), p.decodeValue());
1112
+ },
1113
+ /**
1114
+ * Remove a cache.
1115
+ *
1116
+ * @param {String} name Cache name.
1117
+ * @returns {Promise} A promise that completes when the cache is removed.
1118
+ * @memberof Client.admin#
1119
+ * @since 0.15
1120
+ */
1121
+ removeCache: function(name) {
1122
+ var ctx = transport.context(SMALL);
1123
+ logger.debugf('Invoke admin.removeCache(msgId=%d,name=%s)', ctx.id, name);
1124
+ return future(ctx, 0x2B, p.encodeNameParams('@@cache@remove', {name: name}), p.decodeValue());
1125
+ },
1126
+ /**
1127
+ * List all cache names.
1128
+ *
1129
+ * @returns {Promise<String[]>} A promise that completes with the list of cache names.
1130
+ * @memberof Client.admin#
1131
+ * @since 0.15
1132
+ */
1133
+ cacheNames: function() {
1134
+ var ctx = transport.context(SMALL);
1135
+ logger.debugf('Invoke admin.cacheNames(msgId=%d)', ctx.id);
1136
+ return future(ctx, 0x2B, p.encodeNameParams('@@cache@names', {}), p.decodeValue())
1137
+ .then(function(result) { return JSON.parse(result); });
1138
+ },
1139
+ /**
1140
+ * Update a mutable configuration attribute on a cache.
1141
+ *
1142
+ * @param {String} name Cache name.
1143
+ * @param {String} attribute Attribute path (e.g. 'memory.max-count').
1144
+ * @param {String} value New attribute value.
1145
+ * @returns {Promise} A promise that completes when the attribute is updated.
1146
+ * @memberof Client.admin#
1147
+ * @since 0.15
1148
+ */
1149
+ updateConfigurationAttribute: function(name, attribute, value) {
1150
+ var ctx = transport.context(SMALL);
1151
+ logger.debugf('Invoke admin.updateConfigurationAttribute(msgId=%d,name=%s,attr=%s)', ctx.id, name, attribute);
1152
+ return future(ctx, 0x2B, p.encodeNameParams('@@cache@updateConfigurationAttribute', {
1153
+ name: name, attribute: attribute, value: value
1154
+ }), p.decodeValue());
1155
+ },
1156
+ /**
1157
+ * Rebuild indexes for a cache.
1158
+ *
1159
+ * @param {String} name Cache name.
1160
+ * @returns {Promise} A promise that completes when reindexing starts.
1161
+ * @memberof Client.admin#
1162
+ * @since 0.15
1163
+ */
1164
+ reindex: function(name) {
1165
+ var ctx = transport.context(SMALL);
1166
+ logger.debugf('Invoke admin.reindex(msgId=%d,name=%s)', ctx.id, name);
1167
+ return future(ctx, 0x2B, p.encodeNameParams('@@cache@reindex', {name: name}), p.decodeValue());
1168
+ },
1169
+ /**
1170
+ * Update the index schema for a cache.
1171
+ *
1172
+ * @param {String} name Cache name.
1173
+ * @returns {Promise} A promise that completes when the index schema is updated.
1174
+ * @memberof Client.admin#
1175
+ * @since 0.15
1176
+ */
1177
+ updateIndexSchema: function(name) {
1178
+ var ctx = transport.context(SMALL);
1179
+ logger.debugf('Invoke admin.updateIndexSchema(msgId=%d,name=%s)', ctx.id, name);
1180
+ return future(ctx, 0x2B, p.encodeNameParams('@@cache@updateindexschema', {name: name}), p.decodeValue());
1181
+ },
1182
+ /**
1183
+ * Register (create or update) a Protobuf schema on the server.
1184
+ *
1185
+ * @param {String} name Schema name (e.g. 'person.proto').
1186
+ * @param {String} schema Protobuf schema content.
1187
+ * @returns {Promise} A promise that completes when the schema is registered.
1188
+ * @memberof Client.admin#
1189
+ * @since 0.15
1190
+ */
1191
+ registerSchema: function(name, schema) {
1192
+ var ctx = transport.context(MEDIUM);
1193
+ logger.debugf('Invoke admin.registerSchema(msgId=%d,name=%s)', ctx.id, name);
1194
+ return future(ctx, 0x2B, p.encodeNameParams('@@schemas@createOrUpdate', {
1195
+ name: name, content: schema, op: 's'
1196
+ }), p.decodeValue());
1197
+ },
1198
+ /**
1199
+ * Remove a registered Protobuf schema.
1200
+ *
1201
+ * @param {String} name Schema name.
1202
+ * @returns {Promise} A promise that completes when the schema is removed.
1203
+ * @memberof Client.admin#
1204
+ * @since 0.15
1205
+ */
1206
+ removeSchema: function(name) {
1207
+ var ctx = transport.context(SMALL);
1208
+ logger.debugf('Invoke admin.removeSchema(msgId=%d,name=%s)', ctx.id, name);
1209
+ return future(ctx, 0x2B, p.encodeNameParams('@@schemas@delete', {name: name}), p.decodeValue());
1210
+ }
764
1211
  }
765
- }
1212
+ };
766
1213
  };
767
1214
 
768
1215
  /**
769
1216
  * Server topology information.
770
1217
  *
1218
+ * @param {Object} transport Transport instance.
1219
+ * @returns {Object} Topology info object.
771
1220
  * @constructs Topology
772
1221
  * @since 0.3
773
1222
  */
@@ -809,7 +1258,7 @@
809
1258
  * Switch remote cache manager to a different cluster,
810
1259
  * previously declared via configuration.
811
1260
  *
812
- * @param clusterName name of the cluster to which to switch to
1261
+ * @param {String} clusterName Name of the cluster to which to switch to.
813
1262
  * @return {Promise<Boolean>}
814
1263
  * A promise encapsulating a Boolean that indicates {@code true} if the
815
1264
  * switch happened, or {@code false} otherwise.
@@ -832,7 +1281,7 @@
832
1281
  switchToDefaultCluster: function() {
833
1282
  return transport.switchToDefaultCluster();
834
1283
  }
835
- }
1284
+ };
836
1285
  };
837
1286
 
838
1287
  /**
@@ -861,13 +1310,13 @@
861
1310
  * client([{port: 11522, host: 'myhost'}, {port: 11622, host: 'myhost'}],
862
1311
  * {version: '2.2', cacheName: 'myCache'})
863
1312
  *
864
- * @param args {(ServerAddress|ServerAddress[])}
1313
+ * @param {(ServerAddress|ServerAddress[])} args
865
1314
  * Optional single or multiple addresses to which to connect. If none
866
1315
  * provided, the client will connect to localhost:11222 address by default.
867
- * @param [options] {ClientOptions}
1316
+ * @param {ClientOptions=} options
868
1317
  * Optional configuration settings.
869
1318
  * @constructs Client
870
- * @returns {Promise<ReturnType<Client>>}
1319
+ * @returns {Promise<ReturnType<Client>>} A promise that resolves to a connected client.
871
1320
  * @since 0.3
872
1321
  */
873
1322
  exports.client = function client(args, options) {
@@ -891,7 +1340,7 @@
891
1340
  *
892
1341
  * @static
893
1342
  * @typedef {Object} ClientOptions
894
- * @property {?(2.9|2.5|2.2)} [version=2.9] - Version of client/server protocol.
1343
+ * @property {?('auto'|'4.1'|'4.0'|'3.1'|'3.0'|'2.9'|'2.5'|'2.2')} [version='auto'] - Version of client/server protocol. Use 'auto' to negotiate the highest supported version.
895
1344
  * @property {?String} [cacheName] - Optional cache name.
896
1345
  * @property {?Number} [maxRetries=3] - Optional number of retries for operation.
897
1346
  * @property {?Object} [ssl] - TLS/SSL properties.
@@ -918,10 +1367,12 @@
918
1367
  * @property {?boolean} [topologyUpdates=true] - Optional flag to controls whether the client deals with topology updates or not.
919
1368
  * @property {?("text/plain"|"application/json")} [mediaType="text/plain"] - Media type of the cache contents.
920
1369
  * @property {?Cluster[]} [clusters] - Optional additional clusters for cross-site failovers.
1370
+ * @property {?Object} [nearCache] - Near cache configuration. When set, enables client-side caching with server-side invalidation.
1371
+ * @property {?Number} [nearCache.maxEntries] - Maximum number of entries to store in the near cache.
921
1372
  * @since 0.3
922
1373
  */
923
1374
  Client.config = {
924
- version: '2.9', // Hot Rod protocol version
1375
+ version: 'auto', // Hot Rod protocol version (auto-negotiate)
925
1376
  cacheName: undefined, // Cache name
926
1377
  maxRetries: 3, // Maximum number of retries
927
1378
  authentication: {