vscroll 1.5.2 → 1.5.3

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 (69) hide show
  1. package/dist/bundles/vscroll.esm5.js +119 -61
  2. package/dist/bundles/vscroll.esm5.js.map +1 -1
  3. package/dist/bundles/vscroll.esm5.min.js +2 -2
  4. package/dist/bundles/vscroll.esm5.min.js.map +1 -1
  5. package/dist/bundles/vscroll.esm6.js +114 -55
  6. package/dist/bundles/vscroll.esm6.js.map +1 -1
  7. package/dist/bundles/vscroll.esm6.min.js +2 -2
  8. package/dist/bundles/vscroll.esm6.min.js.map +1 -1
  9. package/dist/bundles/vscroll.umd.js +120 -62
  10. package/dist/bundles/vscroll.umd.js.map +1 -1
  11. package/dist/bundles/vscroll.umd.min.js +2 -2
  12. package/dist/bundles/vscroll.umd.min.js.map +1 -1
  13. package/dist/esm2015/classes/adapter/context.js +11 -5
  14. package/dist/esm2015/classes/adapter/context.js.map +1 -1
  15. package/dist/esm2015/classes/adapter/props.js +4 -2
  16. package/dist/esm2015/classes/adapter/props.js.map +1 -1
  17. package/dist/esm2015/classes/adapter/wanted.js +29 -0
  18. package/dist/esm2015/classes/adapter/wanted.js.map +1 -0
  19. package/dist/esm2015/classes/adapter.js +65 -29
  20. package/dist/esm2015/classes/adapter.js.map +1 -1
  21. package/dist/esm2015/classes/datasource.js +2 -0
  22. package/dist/esm2015/classes/datasource.js.map +1 -1
  23. package/dist/esm2015/classes/logger.js +1 -1
  24. package/dist/esm2015/classes/logger.js.map +1 -1
  25. package/dist/esm2015/inputs/validation.js.map +1 -1
  26. package/dist/esm2015/interfaces/adapter.js.map +1 -1
  27. package/dist/esm2015/interfaces/index.js.map +1 -1
  28. package/dist/esm2015/interfaces/process.js.map +1 -1
  29. package/dist/esm2015/interfaces/workflow.js.map +1 -1
  30. package/dist/esm2015/processes/end.js +5 -18
  31. package/dist/esm2015/processes/end.js.map +1 -1
  32. package/dist/esm2015/scroller.js +1 -1
  33. package/dist/esm2015/scroller.js.map +1 -1
  34. package/dist/esm2015/version.js +1 -1
  35. package/dist/esm2015/version.js.map +1 -1
  36. package/dist/esm2015/workflow.js.map +1 -1
  37. package/dist/esm5/classes/adapter/context.js +11 -6
  38. package/dist/esm5/classes/adapter/context.js.map +1 -1
  39. package/dist/esm5/classes/adapter/props.js +4 -2
  40. package/dist/esm5/classes/adapter/props.js.map +1 -1
  41. package/dist/esm5/classes/adapter/wanted.js +30 -0
  42. package/dist/esm5/classes/adapter/wanted.js.map +1 -0
  43. package/dist/esm5/classes/adapter.js +69 -34
  44. package/dist/esm5/classes/adapter.js.map +1 -1
  45. package/dist/esm5/classes/datasource.js +2 -0
  46. package/dist/esm5/classes/datasource.js.map +1 -1
  47. package/dist/esm5/classes/logger.js +1 -1
  48. package/dist/esm5/classes/logger.js.map +1 -1
  49. package/dist/esm5/inputs/validation.js.map +1 -1
  50. package/dist/esm5/interfaces/adapter.js.map +1 -1
  51. package/dist/esm5/interfaces/index.js.map +1 -1
  52. package/dist/esm5/interfaces/process.js.map +1 -1
  53. package/dist/esm5/interfaces/workflow.js.map +1 -1
  54. package/dist/esm5/processes/end.js +5 -18
  55. package/dist/esm5/processes/end.js.map +1 -1
  56. package/dist/esm5/scroller.js +1 -1
  57. package/dist/esm5/scroller.js.map +1 -1
  58. package/dist/esm5/version.js +1 -1
  59. package/dist/esm5/version.js.map +1 -1
  60. package/dist/esm5/workflow.js.map +1 -1
  61. package/dist/typings/classes/adapter/wanted.d.ts +14 -0
  62. package/dist/typings/classes/adapter.d.ts +7 -4
  63. package/dist/typings/classes/logger.d.ts +1 -1
  64. package/dist/typings/interfaces/adapter.d.ts +6 -0
  65. package/dist/typings/interfaces/index.d.ts +2 -2
  66. package/dist/typings/interfaces/workflow.d.ts +1 -1
  67. package/dist/typings/processes/end.d.ts +1 -2
  68. package/dist/typings/workflow.d.ts +1 -1
  69. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * vscroll (https://github.com/dhilt/vscroll) UMD
3
- * Version: 1.5.2 (2022-09-12T12:01:28.792Z)
3
+ * Version: 1.5.3 (2022-09-14T09:13:40.390Z)
4
4
  * Author: Denis Hilt
5
5
  * License: MIT
6
6
  */
@@ -94,7 +94,7 @@
94
94
 
95
95
  /**
96
96
  * vscroll (https://github.com/dhilt/vscroll) FESM5
97
- * Version: 1.5.2 (2022-09-12T12:01:24.857Z)
97
+ * Version: 1.5.3 (2022-09-14T09:13:35.350Z)
98
98
  * Author: Denis Hilt
99
99
  * License: MIT
100
100
  */
@@ -413,12 +413,14 @@
413
413
  {
414
414
  type: Type.Reactive,
415
415
  name: Name.firstVisible$,
416
- value: new Reactive(EMPTY_ITEM, { emitOnSubscribe: true })
416
+ value: new Reactive(EMPTY_ITEM, { emitOnSubscribe: true }),
417
+ wanted: true
417
418
  },
418
419
  {
419
420
  type: Type.Reactive,
420
421
  name: Name.lastVisible$,
421
- value: new Reactive(EMPTY_ITEM, { emitOnSubscribe: true })
422
+ value: new Reactive(EMPTY_ITEM, { emitOnSubscribe: true }),
423
+ wanted: true
422
424
  },
423
425
  {
424
426
  type: Type.Reactive,
@@ -435,8 +437,37 @@
435
437
 
436
438
  var core = {
437
439
  name: 'vscroll',
438
- version: '1.5.2'
440
+ version: '1.5.3'
441
+ };
442
+
443
+ var getBox = function (id) {
444
+ var _a;
445
+ return (_a = wantedStorage.get(id || -1)) === null || _a === void 0 ? void 0 : _a.box;
446
+ };
447
+ var setBox = function (_a, id) {
448
+ var name = _a.name, wanted = _a.wanted;
449
+ var Wanted = wantedStorage.get(id || -1);
450
+ if (wanted && Wanted && !Wanted.box[name] && !Wanted.block) {
451
+ var a = exports.AdapterPropName.firstVisible, a$ = exports.AdapterPropName.firstVisible$;
452
+ var b = exports.AdapterPropName.lastVisible, b$ = exports.AdapterPropName.lastVisible$;
453
+ Wanted.box[a] = Wanted.box[a$] = [a, a$].some(function (n) { return n === name; }) || Wanted.box[a];
454
+ Wanted.box[b] = Wanted.box[b$] = [b, b$].some(function (n) { return n === name; }) || Wanted.box[b];
455
+ return true;
456
+ }
457
+ return false;
458
+ };
459
+ var setBlock = function (value, id) {
460
+ var Wanted = wantedStorage.get(id || -1);
461
+ if (Wanted) {
462
+ Wanted.block = value;
463
+ }
464
+ };
465
+ var wantedUtils = {
466
+ getBox: getBox,
467
+ setBox: setBox,
468
+ setBlock: setBlock
439
469
  };
470
+ var wantedStorage = new Map();
440
471
 
441
472
  var instanceCount$1 = 0;
442
473
  var AdapterContext = /** @class */ (function () {
@@ -446,6 +477,7 @@
446
477
  var id = ++instanceCount$1;
447
478
  var conf = { configurable: true };
448
479
  var reactivePropsStore = {};
480
+ wantedStorage.set(id, { box: {}, block: false });
449
481
  // set up permanent props
450
482
  Object.defineProperty(this, exports.AdapterPropName.id, __assign({ get: function () { return id; } }, conf));
451
483
  Object.defineProperty(this, exports.AdapterPropName.mock, __assign({ get: function () { return mock; } }, conf));
@@ -457,21 +489,24 @@
457
489
  var permanent = _a.permanent;
458
490
  return !permanent;
459
491
  })
460
- .forEach(function (_a) {
461
- var name = _a.name, value = _a.value, type = _a.type;
492
+ .forEach(function (prop) {
493
+ var value = prop.value;
462
494
  // reactive props might be reconfigured by the vscroll consumer
463
- if (reactive && type === AdapterPropType.Reactive) {
464
- var react = reactive[name];
495
+ if (reactive && prop.type === AdapterPropType.Reactive) {
496
+ var react = reactive[prop.name];
465
497
  if (react) {
466
498
  // here we have a configured reactive property that came from the outer config
467
499
  // this prop must be exposed via Adapter, but at the same time we need to
468
500
  // persist the original default value as it will be used by the Adapter internally
469
- reactivePropsStore[name] = __assign(__assign({}, react), { default: value // persisting the default native Reactive prop
501
+ reactivePropsStore[prop.name] = __assign(__assign({}, react), { default: value // persisting the default native Reactive prop
470
502
  });
471
503
  value = react.source; // exposing the configured prop instead of the default one
472
504
  }
473
505
  }
474
- Object.defineProperty(_this, name, __assign({ get: function () { return value; } }, conf));
506
+ Object.defineProperty(_this, prop.name, __assign({ get: function () {
507
+ wantedUtils.setBox(prop, id);
508
+ return value;
509
+ } }, conf));
475
510
  });
476
511
  if (reactive) { // save both configured and default reactive props in the store
477
512
  reactiveConfigStorage.set(id, reactivePropsStore);
@@ -494,6 +529,7 @@
494
529
  }
495
530
  DatasourceGeneric.prototype.dispose = function () {
496
531
  reactiveConfigStorage.delete(this.adapter.id);
532
+ wantedStorage.delete(this.adapter.id);
497
533
  };
498
534
  return DatasourceGeneric;
499
535
  }());
@@ -2666,7 +2702,7 @@
2666
2702
  var workflow = scroller.workflow, interrupter = scroller.state.cycle.interrupter;
2667
2703
  if (!error && !interrupter) {
2668
2704
  // set out params accessible via Adapter
2669
- End.calculateParams(scroller, workflow);
2705
+ End.calculateParams(scroller);
2670
2706
  }
2671
2707
  // explicit interruption for we don't want to go through the inner loop finalizing
2672
2708
  if (isInterrupted(workflow)) {
@@ -2681,21 +2717,10 @@
2681
2717
  payload: __assign({}, (interrupter ? { process: interrupter } : {}))
2682
2718
  });
2683
2719
  };
2684
- End.calculateParams = function (scroller, workflow) {
2685
- var adapter = scroller.adapter, viewport = scroller.viewport, items = scroller.buffer.items;
2686
- if (adapter.wanted.firstVisible) {
2687
- var item = viewport.getEdgeVisibleItem(items, exports.Direction.backward).item;
2688
- if (!item || item.element !== adapter.firstVisible.element) {
2689
- adapter.firstVisible = item ? item.get() : EMPTY_ITEM;
2690
- }
2691
- }
2692
- // the workflow can be interrupter on firstVisible change
2693
- if (adapter.wanted.lastVisible && !isInterrupted(workflow)) {
2694
- var item = viewport.getEdgeVisibleItem(items, exports.Direction.forward).item;
2695
- if (!item || item.element !== adapter.lastVisible.element) {
2696
- adapter.lastVisible = item ? item.get() : EMPTY_ITEM;
2697
- }
2698
- }
2720
+ End.calculateParams = function (scroller) {
2721
+ var adapter = scroller.adapter, workflow = scroller.workflow;
2722
+ adapter.setFirstOrLastVisible({ first: true, workflow: workflow });
2723
+ adapter.setFirstOrLastVisible({ last: true, workflow: workflow });
2699
2724
  };
2700
2725
  End.shouldContinueRun = function (scroller, error) {
2701
2726
  var _a = scroller.state, cycle = _a.cycle, fetch = _a.fetch, render = _a.render;
@@ -3201,7 +3226,7 @@
3201
3226
  }
3202
3227
  }
3203
3228
  };
3204
- // logNow(...args: any[]) {
3229
+ // logNow(...args: unknown[]) {
3205
3230
  // const immediateLog = this.immediateLog;
3206
3231
  // const debug = this.debug;
3207
3232
  // (this as any).debug = true;
@@ -4802,14 +4827,19 @@
4802
4827
  this.source = {}; // for Reactive props
4803
4828
  this.box = {}; // for Scalars over Reactive props
4804
4829
  this.demand = {}; // for Scalars on demand
4805
- this.wanted = {};
4830
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
4831
+ this.setFirstOrLastVisible = function (_) { };
4806
4832
  this.getWorkflow = getWorkflow;
4807
4833
  this.logger = logger;
4808
4834
  this.relax$ = null;
4809
4835
  this.relaxRun = null;
4810
4836
  this.reloadCounter = 0;
4811
- // public context (if exists) should provide access Reactive props configuration by id
4837
+ var contextId = (context === null || context === void 0 ? void 0 : context.id) || -1;
4838
+ // public context (if exists) should provide access to Reactive props config by id
4812
4839
  var reactivePropsStore = context && reactiveConfigStorage.get(context.id) || {};
4840
+ // the Adapter initialization should not trigger "wanted" props setting;
4841
+ // after the initialization is completed, "wanted" functionality must be unblocked
4842
+ wantedUtils.setBlock(true, contextId);
4813
4843
  // make array of the original values from public context if present
4814
4844
  var adapterProps = context
4815
4845
  ? ADAPTER_PROPS_STUB.map(function (prop) {
@@ -4848,9 +4878,7 @@
4848
4878
  get: function () { return value; }
4849
4879
  });
4850
4880
  });
4851
- // Reactive props
4852
- // 1) store original values in "source" container, to avoid extra .get() calls on scalar twins set
4853
- // 2) "wanted" container is bound with scalars; get() updates it
4881
+ // Reactive props: store original values in "source" container, to avoid extra .get() calls on scalar twins set
4854
4882
  adapterProps
4855
4883
  .filter(function (prop) { return prop.type === AdapterPropType.Reactive; })
4856
4884
  .forEach(function (_a) {
@@ -4858,29 +4886,30 @@
4858
4886
  _this.source[name] = value;
4859
4887
  Object.defineProperty(_this, name, {
4860
4888
  configurable: true,
4861
- get: function () {
4862
- var scalarWanted = ADAPTER_PROPS_STUB.find(function (_a) {
4863
- var wanted = _a.wanted, reactive = _a.reactive;
4864
- return wanted && reactive === name;
4865
- });
4866
- if (scalarWanted && _this.externalContext) {
4867
- _this.wanted[scalarWanted.name] = true;
4868
- }
4869
- return _this.source[name];
4870
- }
4889
+ get: function () { return _this.source[name]; }
4871
4890
  });
4872
4891
  });
4892
+ // for "wanted" props that can be explicitly requested for the first time after the Adapter initialization,
4893
+ // an implicit calculation of the initial value is required;
4894
+ // so this method should be called when accessing the "wanted" props through one of the following getters
4895
+ var processWanted = function (prop) {
4896
+ if (wantedUtils.setBox(prop, contextId)) {
4897
+ if ([exports.AdapterPropName.firstVisible, exports.AdapterPropName.firstVisible$].some(function (n) { return n === prop.name; })) {
4898
+ _this.setFirstOrLastVisible({ first: true });
4899
+ }
4900
+ else if ([exports.AdapterPropName.lastVisible, exports.AdapterPropName.lastVisible$].some(function (n) { return n === prop.name; })) {
4901
+ _this.setFirstOrLastVisible({ last: true });
4902
+ }
4903
+ }
4904
+ };
4873
4905
  // Scalar props that have Reactive twins
4874
- // 1) scalars should use "box" container
4875
- // 2) "wanted" should be updated on get
4876
- // 3) reactive props (from "source") are triggered on set
4906
+ // 1) reactive props (from "source") should be triggered on set
4907
+ // 2) scalars should use "box" container on get
4908
+ // 3) "wanted" scalars should also run wanted-related logic on get
4877
4909
  adapterProps
4878
4910
  .filter(function (prop) { return prop.type === AdapterPropType.Scalar && !!prop.reactive; })
4879
- .forEach(function (_a) {
4880
- var name = _a.name, value = _a.value, reactive = _a.reactive, wanted = _a.wanted;
4881
- if (wanted) {
4882
- _this.wanted[name] = false;
4883
- }
4911
+ .forEach(function (prop) {
4912
+ var name = prop.name, value = prop.value, reactive = prop.reactive;
4884
4913
  _this.box[name] = value;
4885
4914
  Object.defineProperty(_this, name, {
4886
4915
  configurable: true,
@@ -4896,9 +4925,7 @@
4896
4925
  }
4897
4926
  },
4898
4927
  get: function () {
4899
- if (wanted && _this.externalContext) {
4900
- _this.wanted[name] = true;
4901
- }
4928
+ processWanted(prop);
4902
4929
  return _this.box[name];
4903
4930
  }
4904
4931
  });
@@ -4921,8 +4948,8 @@
4921
4948
  }
4922
4949
  // Adapter public context augmentation
4923
4950
  adapterProps
4924
- .forEach(function (_a) {
4925
- var name = _a.name, type = _a.type, defaultValue = _a.value, permanent = _a.permanent;
4951
+ .forEach(function (prop) {
4952
+ var name = prop.name, type = prop.type, defaultValue = prop.value, permanent = prop.permanent;
4926
4953
  var value = _this[name];
4927
4954
  if (type === AdapterPropType.Function) {
4928
4955
  value = value.bind(_this);
@@ -4936,14 +4963,20 @@
4936
4963
  else if (name === exports.AdapterPropName.augmented) {
4937
4964
  value = true;
4938
4965
  }
4966
+ var nonPermanentScalar = !permanent && type === AdapterPropType.Scalar;
4939
4967
  Object.defineProperty(context, name, {
4940
4968
  configurable: true,
4941
- get: function () { return !permanent && type === AdapterPropType.Scalar
4942
- ? _this[name] // non-permanent Scalars should be taken in runtime
4943
- : value; } // Reactive props and methods (Functions/WorkflowRunners) can be defined once
4969
+ get: function () {
4970
+ processWanted(prop); // consider accessing "wanted" Reactive props
4971
+ if (nonPermanentScalar) {
4972
+ return _this[name]; // non-permanent Scalars should be taken in runtime
4973
+ }
4974
+ return value; // other props (Reactive/Functions/WorkflowRunners) can be defined once
4975
+ }
4944
4976
  });
4945
4977
  });
4946
4978
  this.externalContext = context;
4979
+ wantedUtils.setBlock(false, contextId);
4947
4980
  }
4948
4981
  Object.defineProperty(Adapter.prototype, "workflow", {
4949
4982
  get: function () {
@@ -4983,7 +5016,7 @@
4983
5016
  : defaultMethod.apply(_this, args);
4984
5017
  };
4985
5018
  };
4986
- Adapter.prototype.initialize = function (buffer, state, logger, adapterRun$) {
5019
+ Adapter.prototype.initialize = function (buffer, state, viewport, logger, adapterRun$) {
4987
5020
  var _this = this;
4988
5021
  // buffer
4989
5022
  Object.defineProperty(this.demand, exports.AdapterPropName.itemsCount, {
@@ -5012,6 +5045,30 @@
5012
5045
  state.cycle.innerLoop.busy.on(function (busy) { return _this.loopPending = busy; });
5013
5046
  this.isLoading = state.cycle.busy.get();
5014
5047
  state.cycle.busy.on(function (busy) { return _this.isLoading = busy; });
5048
+ //viewport
5049
+ this.setFirstOrLastVisible = function (_a) {
5050
+ var _b, _c, _d;
5051
+ var first = _a.first, last = _a.last, workflow = _a.workflow;
5052
+ if ((!first && !last) || ((_b = workflow === null || workflow === void 0 ? void 0 : workflow.call) === null || _b === void 0 ? void 0 : _b.interrupted)) {
5053
+ return;
5054
+ }
5055
+ var token = first ? exports.AdapterPropName.firstVisible : exports.AdapterPropName.lastVisible;
5056
+ if (!((_d = wantedUtils.getBox((_c = _this.externalContext) === null || _c === void 0 ? void 0 : _c.id)) === null || _d === void 0 ? void 0 : _d[token])) {
5057
+ return;
5058
+ }
5059
+ if (buffer.items.some(function (_a) {
5060
+ var element = _a.element;
5061
+ return !element;
5062
+ })) {
5063
+ logger.log('skipping first/lastVisible set because not all buffered items are rendered at this moment');
5064
+ return;
5065
+ }
5066
+ var direction = first ? exports.Direction.backward : exports.Direction.forward;
5067
+ var item = viewport.getEdgeVisibleItem(buffer.items, direction).item;
5068
+ if (!item || item.element !== _this[token].element) {
5069
+ _this[token] = (item ? item.get() : EMPTY_ITEM);
5070
+ }
5071
+ };
5015
5072
  // logger
5016
5073
  this.logger = logger;
5017
5074
  // self-pending subscription; set up only on the very first init
@@ -5058,7 +5115,8 @@
5058
5115
  };
5059
5116
  Adapter.prototype.resetContext = function () {
5060
5117
  var _this = this;
5061
- var reactiveStore = reactiveConfigStorage.get(this.externalContext.id);
5118
+ var _a;
5119
+ var reactiveStore = reactiveConfigStorage.get((_a = this.externalContext) === null || _a === void 0 ? void 0 : _a.id);
5062
5120
  ADAPTER_PROPS_STUB
5063
5121
  .forEach(function (_a) {
5064
5122
  var type = _a.type, permanent = _a.permanent, name = _a.name, value = _a.value;
@@ -5277,7 +5335,7 @@
5277
5335
  Scroller.prototype.init = function (adapterRun$) {
5278
5336
  this.viewport.reset(this.buffer.startIndex);
5279
5337
  this.logger.stat('initialization');
5280
- this.adapter.initialize(this.buffer, this.state, this.logger, adapterRun$);
5338
+ this.adapter.initialize(this.buffer, this.state, this.viewport, this.logger, adapterRun$);
5281
5339
  };
5282
5340
  Scroller.prototype.dispose = function (forever) {
5283
5341
  if (forever) { // Adapter is not re-instantiated on reset