spice-couchbase 2.0.44 → 2.0.45

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 (3) hide show
  1. package/build/index.js +116 -51
  2. package/package.json +1 -1
  3. package/src/index.js +98 -53
package/build/index.js CHANGED
@@ -36,8 +36,10 @@ if (!Promise.allSettled) {
36
36
  status: "rejected",
37
37
  reason
38
38
  }))));
39
- }
39
+ } // Couchbase lookupIn has a limit of 16 operations per call
40
40
 
41
+
42
+ var LOOKUP_IN_MAX_SPECS = 16;
41
43
  module.exports = class Database {
42
44
  constructor(connection) {
43
45
  var {
@@ -305,24 +307,40 @@ module.exports = class Database {
305
307
  return _asyncToGenerator(function* () {
306
308
  try {
307
309
  var useLookupIn = columns.length > 0;
308
- var response = yield useLookupIn ? (_this8.use_bucket_name ? _this8.connection : _this8.collection).lookupIn(doc_id, columns.map(col => couchbase.LookupInSpec.get(col))) : (_this8.use_bucket_name ? _this8.connection : _this8.collection).get(doc_id);
310
+ var collection = _this8.use_bucket_name ? _this8.connection : _this8.collection;
309
311
 
310
- if (useLookupIn) {
311
- // lookupIn returns content array with each spec result
312
- var value = {
313
- id: doc_id
314
- };
315
- columns.forEach((col, colIndex) => {
316
- if (response.content && response.content[colIndex]) {
317
- value[col] = response.content[colIndex].value;
318
- }
319
- });
320
- return value;
321
- } else {
312
+ if (!useLookupIn) {
313
+ var response = yield collection.get(doc_id);
322
314
  return _objectSpread({
323
315
  id: doc_id
324
316
  }, response.content);
325
- }
317
+ } // Batch columns into chunks of LOOKUP_IN_MAX_SPECS (16)
318
+
319
+
320
+ var value = {
321
+ id: doc_id
322
+ };
323
+
324
+ var columnBatches = _.chunk(columns, LOOKUP_IN_MAX_SPECS); // Execute all batch requests in parallel
325
+
326
+
327
+ var batchPromises = columnBatches.map(batch => {
328
+ var specs = batch.map(col => couchbase.LookupInSpec.get(col));
329
+ return collection.lookupIn(doc_id, specs);
330
+ });
331
+ var batchResults = yield Promise.allSettled(batchPromises); // Merge results from all batches
332
+
333
+ batchResults.forEach((result, batchIndex) => {
334
+ if (result.status === "fulfilled" && result.value) {
335
+ var batch = columnBatches[batchIndex];
336
+ batch.forEach((col, colIndex) => {
337
+ if (result.value.content && result.value.content[colIndex]) {
338
+ value[col] = result.value.content[colIndex].value;
339
+ }
340
+ });
341
+ }
342
+ });
343
+ return value;
326
344
  } catch (e) {
327
345
  console.error(e);
328
346
  }
@@ -400,42 +418,89 @@ module.exports = class Database {
400
418
 
401
419
  if (_.isArray(keys) && keys.length > 0) {
402
420
  var useLookupIn = columns.length > 0;
421
+ var collection = _this14.use_bucket_name ? _this14.connection : _this14.collection;
403
422
 
404
- var functions = _.map(keys, key => useLookupIn ? (_this14.use_bucket_name ? _this14.connection : _this14.collection).lookupIn(key, columns.map(col => couchbase.LookupInSpec.get(col))) : (_this14.use_bucket_name ? _this14.connection : _this14.collection).get(key));
423
+ if (!useLookupIn) {
424
+ // Regular get - no batching needed
425
+ var functions = _.map(keys, key => collection.get(key));
405
426
 
406
- var returned_all = yield Promise.allSettled(functions);
427
+ var returned_all = yield Promise.allSettled(functions);
407
428
 
408
- var responses = _.flatten(_.map(returned_all, returned_obj => {
409
- return returned_obj === null || returned_obj === void 0 ? void 0 : returned_obj.value;
410
- }));
429
+ var responses = _.flatten(_.map(returned_all, returned_obj => returned_obj === null || returned_obj === void 0 ? void 0 : returned_obj.value));
411
430
 
412
- var final_responses = _.compact(_.map(responses, (res, index) => {
413
- if (res) {
414
- var value;
431
+ var _final_responses = _.compact(_.map(responses, (res, index) => {
432
+ if (res) {
433
+ var value = res.value;
415
434
 
416
- if (useLookupIn) {
417
- // lookupIn returns content array with each spec result
418
- value = {};
419
- columns.forEach((col, colIndex) => {
420
- if (res.content && res.content[colIndex]) {
421
- value[col] = res.content[colIndex].value;
435
+ if (!keep_type && value) {
436
+ delete value.type;
437
+ }
438
+
439
+ if (value) {
440
+ value.id = keys[index];
441
+ }
442
+
443
+ return value;
444
+ }
445
+ }));
446
+
447
+ return _final_responses;
448
+ } // lookupIn with batching for columns > 16
449
+
450
+
451
+ var columnBatches = _.chunk(columns, LOOKUP_IN_MAX_SPECS); // For each key, we need to fetch all column batches and merge the results
452
+
453
+
454
+ var keyPromises = _.map(keys,
455
+ /*#__PURE__*/
456
+ function () {
457
+ var _ref = _asyncToGenerator(function* (key) {
458
+ try {
459
+ var value = {
460
+ id: key
461
+ }; // Execute all batch requests for this key in parallel
462
+
463
+ var batchPromises = columnBatches.map(batch => {
464
+ var specs = batch.map(col => couchbase.LookupInSpec.get(col));
465
+ return collection.lookupIn(key, specs);
466
+ });
467
+ var batchResults = yield Promise.allSettled(batchPromises); // Merge results from all batches
468
+
469
+ batchResults.forEach((result, batchIndex) => {
470
+ if (result.status === "fulfilled" && result.value) {
471
+ var batch = columnBatches[batchIndex];
472
+ batch.forEach((col, colIndex) => {
473
+ if (result.value.content && result.value.content[colIndex]) {
474
+ value[col] = result.value.content[colIndex].value;
475
+ }
476
+ });
422
477
  }
423
478
  });
424
- } else {
425
- // regular get returns the full document in value
426
- value = res.value;
427
- }
428
479
 
429
- if (!keep_type && value) {
430
- delete value.type;
431
- }
480
+ if (!keep_type && value) {
481
+ delete value.type;
482
+ }
432
483
 
433
- if (value) {
434
- value.id = keys[index];
484
+ return value;
485
+ } catch (e) {
486
+ return null;
435
487
  }
488
+ });
436
489
 
437
- return value;
490
+ return function (_x) {
491
+ return _ref.apply(this, arguments);
492
+ };
493
+ }());
494
+
495
+ var results = yield Promise.allSettled(keyPromises);
496
+
497
+ var final_responses = _.compact(_.map(results, result => {
498
+ if (result.status === "fulfilled" && result.value) {
499
+ // Only return if we got at least some data beyond just the id
500
+ return Object.keys(result.value).length > 1 ? result.value : null;
438
501
  }
502
+
503
+ return null;
439
504
  }));
440
505
 
441
506
  return final_responses;
@@ -450,7 +515,7 @@ module.exports = class Database {
450
515
  return new Promise(
451
516
  /*#__PURE__*/
452
517
  function () {
453
- var _ref = _asyncToGenerator(function* (resolve, reject) {
518
+ var _ref2 = _asyncToGenerator(function* (resolve, reject) {
454
519
  var ViewQuery = couchbase.ViewQuery;
455
520
  var query = ViewQuery.from(design_doc, view);
456
521
 
@@ -477,7 +542,7 @@ module.exports = class Database {
477
542
  that.connection.query(query,
478
543
  /*#__PURE__*/
479
544
  function () {
480
- var _ref2 = _asyncToGenerator(function* (err, results, matrix) {
545
+ var _ref3 = _asyncToGenerator(function* (err, results, matrix) {
481
546
  var return_value = [];
482
547
 
483
548
  if (err) {
@@ -500,14 +565,14 @@ module.exports = class Database {
500
565
  }
501
566
  });
502
567
 
503
- return function (_x3, _x4, _x5) {
504
- return _ref2.apply(this, arguments);
568
+ return function (_x4, _x5, _x6) {
569
+ return _ref3.apply(this, arguments);
505
570
  };
506
571
  }());
507
572
  });
508
573
 
509
- return function (_x, _x2) {
510
- return _ref.apply(this, arguments);
574
+ return function (_x2, _x3) {
575
+ return _ref2.apply(this, arguments);
511
576
  };
512
577
  }());
513
578
  }
@@ -611,7 +676,7 @@ module.exports = class Database {
611
676
  return new Promise(
612
677
  /*#__PURE__*/
613
678
  function () {
614
- var _ref3 = _asyncToGenerator(function* (resolve, reject) {
679
+ var _ref4 = _asyncToGenerator(function* (resolve, reject) {
615
680
  try {
616
681
  var full_query = search_query + " AND type:" + type;
617
682
  var query = that.SearchQuery.new(that.full_text_index || full_text_index, that.SearchQuery.queryString(full_query));
@@ -632,7 +697,7 @@ module.exports = class Database {
632
697
  that.cluster.query(query,
633
698
  /*#__PURE__*/
634
699
  function () {
635
- var _ref4 = _asyncToGenerator(function* (err, results, matrix) {
700
+ var _ref5 = _asyncToGenerator(function* (err, results, matrix) {
636
701
  var return_value = [];
637
702
 
638
703
  if (err) {
@@ -658,8 +723,8 @@ module.exports = class Database {
658
723
  }
659
724
  });
660
725
 
661
- return function (_x8, _x9, _x10) {
662
- return _ref4.apply(this, arguments);
726
+ return function (_x9, _x10, _x11) {
727
+ return _ref5.apply(this, arguments);
663
728
  };
664
729
  }());
665
730
  } catch (e) {
@@ -667,8 +732,8 @@ module.exports = class Database {
667
732
  }
668
733
  });
669
734
 
670
- return function (_x6, _x7) {
671
- return _ref3.apply(this, arguments);
735
+ return function (_x7, _x8) {
736
+ return _ref4.apply(this, arguments);
672
737
  };
673
738
  }());
674
739
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spice-couchbase",
3
- "version": "2.0.44",
3
+ "version": "2.0.45",
4
4
  "description": "",
5
5
  "main": "build/index.js",
6
6
  "scripts": {
package/src/index.js CHANGED
@@ -24,6 +24,9 @@ if (!Promise.allSettled) {
24
24
  );
25
25
  }
26
26
 
27
+ // Couchbase lookupIn has a limit of 16 operations per call
28
+ const LOOKUP_IN_MAX_SPECS = 16;
29
+
27
30
  module.exports = class Database {
28
31
  constructor(
29
32
  connection,
@@ -268,27 +271,38 @@ module.exports = class Database {
268
271
  async get(doc_id, { columns = [] } = {}) {
269
272
  try {
270
273
  const useLookupIn = columns.length > 0;
271
- let response = await (
272
- useLookupIn ?
273
- (this.use_bucket_name ? this.connection : this.collection).lookupIn(
274
- doc_id,
275
- columns.map((col) => couchbase.LookupInSpec.get(col))
276
- )
277
- : (this.use_bucket_name ? this.connection : this.collection).get(doc_id)
278
- );
274
+ const collection = this.use_bucket_name ? this.connection : this.collection;
279
275
 
280
- if (useLookupIn) {
281
- // lookupIn returns content array with each spec result
282
- let value = { id: doc_id };
283
- columns.forEach((col, colIndex) => {
284
- if (response.content && response.content[colIndex]) {
285
- value[col] = response.content[colIndex].value;
286
- }
287
- });
288
- return value;
289
- } else {
276
+ if (!useLookupIn) {
277
+ let response = await collection.get(doc_id);
290
278
  return { id: doc_id, ...response.content };
291
279
  }
280
+
281
+ // Batch columns into chunks of LOOKUP_IN_MAX_SPECS (16)
282
+ let value = { id: doc_id };
283
+ const columnBatches = _.chunk(columns, LOOKUP_IN_MAX_SPECS);
284
+
285
+ // Execute all batch requests in parallel
286
+ const batchPromises = columnBatches.map((batch) => {
287
+ const specs = batch.map((col) => couchbase.LookupInSpec.get(col));
288
+ return collection.lookupIn(doc_id, specs);
289
+ });
290
+
291
+ const batchResults = await Promise.allSettled(batchPromises);
292
+
293
+ // Merge results from all batches
294
+ batchResults.forEach((result, batchIndex) => {
295
+ if (result.status === "fulfilled" && result.value) {
296
+ const batch = columnBatches[batchIndex];
297
+ batch.forEach((col, colIndex) => {
298
+ if (result.value.content && result.value.content[colIndex]) {
299
+ value[col] = result.value.content[colIndex].value;
300
+ }
301
+ });
302
+ }
303
+ });
304
+
305
+ return value;
292
306
  } catch (e) {
293
307
  console.error(e);
294
308
  }
@@ -351,50 +365,81 @@ module.exports = class Database {
351
365
  }
352
366
  if (_.isArray(keys) && keys.length > 0) {
353
367
  const useLookupIn = columns.length > 0;
354
- let functions = _.map(keys, (key) =>
355
- useLookupIn ?
356
- (this.use_bucket_name ? this.connection : this.collection).lookupIn(
357
- key,
358
- columns.map((col) => couchbase.LookupInSpec.get(col))
359
- )
360
- : (this.use_bucket_name ? this.connection : this.collection).get(key)
361
- );
362
- let returned_all = await Promise.allSettled(functions);
368
+ const collection = this.use_bucket_name ? this.connection : this.collection;
363
369
 
364
-
370
+ if (!useLookupIn) {
371
+ // Regular get - no batching needed
372
+ let functions = _.map(keys, (key) => collection.get(key));
373
+ let returned_all = await Promise.allSettled(functions);
365
374
 
366
- let responses = _.flatten(
367
- _.map(returned_all, (returned_obj) => {
368
- return returned_obj?.value;
369
- })
370
- );
375
+ let responses = _.flatten(
376
+ _.map(returned_all, (returned_obj) => returned_obj?.value)
377
+ );
371
378
 
379
+ let final_responses = _.compact(
380
+ _.map(responses, (res, index) => {
381
+ if (res) {
382
+ let value = res.value;
383
+ if (!keep_type && value) {
384
+ delete value.type;
385
+ }
386
+ if (value) {
387
+ value.id = keys[index];
388
+ }
389
+ return value;
390
+ }
391
+ })
392
+ );
372
393
 
373
- let final_responses = _.compact(
374
- _.map(responses, (res, index) => {
375
- if (res) {
376
- let value;
377
- if (useLookupIn) {
378
- // lookupIn returns content array with each spec result
379
- value = {};
380
- columns.forEach((col, colIndex) => {
381
- if (res.content && res.content[colIndex]) {
382
- value[col] = res.content[colIndex].value;
394
+ return final_responses;
395
+ }
396
+
397
+ // lookupIn with batching for columns > 16
398
+ const columnBatches = _.chunk(columns, LOOKUP_IN_MAX_SPECS);
399
+
400
+ // For each key, we need to fetch all column batches and merge the results
401
+ const keyPromises = _.map(keys, async (key) => {
402
+ try {
403
+ let value = { id: key };
404
+
405
+ // Execute all batch requests for this key in parallel
406
+ const batchPromises = columnBatches.map((batch) => {
407
+ const specs = batch.map((col) => couchbase.LookupInSpec.get(col));
408
+ return collection.lookupIn(key, specs);
409
+ });
410
+
411
+ const batchResults = await Promise.allSettled(batchPromises);
412
+
413
+ // Merge results from all batches
414
+ batchResults.forEach((result, batchIndex) => {
415
+ if (result.status === "fulfilled" && result.value) {
416
+ const batch = columnBatches[batchIndex];
417
+ batch.forEach((col, colIndex) => {
418
+ if (result.value.content && result.value.content[colIndex]) {
419
+ value[col] = result.value.content[colIndex].value;
383
420
  }
384
421
  });
385
- } else {
386
- // regular get returns the full document in value
387
- value = res.value;
388
422
  }
423
+ });
389
424
 
390
- if (!keep_type && value) {
391
- delete value.type;
392
- }
393
- if (value) {
394
- value.id = keys[index];
395
- }
396
- return value;
425
+ if (!keep_type && value) {
426
+ delete value.type;
427
+ }
428
+
429
+ return value;
430
+ } catch (e) {
431
+ return null;
432
+ }
433
+ });
434
+
435
+ let results = await Promise.allSettled(keyPromises);
436
+ let final_responses = _.compact(
437
+ _.map(results, (result) => {
438
+ if (result.status === "fulfilled" && result.value) {
439
+ // Only return if we got at least some data beyond just the id
440
+ return Object.keys(result.value).length > 1 ? result.value : null;
397
441
  }
442
+ return null;
398
443
  })
399
444
  );
400
445