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) FESM5
3
- * Version: 1.5.2 (2022-09-12T12:01:24.857Z)
3
+ * Version: 1.5.3 (2022-09-14T09:13:35.350Z)
4
4
  * Author: Denis Hilt
5
5
  * License: MIT
6
6
  */
@@ -321,12 +321,14 @@ var getDefaultAdapterProps = function () { return [
321
321
  {
322
322
  type: Type.Reactive,
323
323
  name: Name.firstVisible$,
324
- value: new Reactive(EMPTY_ITEM, { emitOnSubscribe: true })
324
+ value: new Reactive(EMPTY_ITEM, { emitOnSubscribe: true }),
325
+ wanted: true
325
326
  },
326
327
  {
327
328
  type: Type.Reactive,
328
329
  name: Name.lastVisible$,
329
- value: new Reactive(EMPTY_ITEM, { emitOnSubscribe: true })
330
+ value: new Reactive(EMPTY_ITEM, { emitOnSubscribe: true }),
331
+ wanted: true
330
332
  },
331
333
  {
332
334
  type: Type.Reactive,
@@ -343,8 +345,37 @@ var reactiveConfigStorage = new Map();
343
345
 
344
346
  var core = {
345
347
  name: 'vscroll',
346
- version: '1.5.2'
348
+ version: '1.5.3'
349
+ };
350
+
351
+ var getBox = function (id) {
352
+ var _a;
353
+ return (_a = wantedStorage.get(id || -1)) === null || _a === void 0 ? void 0 : _a.box;
354
+ };
355
+ var setBox = function (_a, id) {
356
+ var name = _a.name, wanted = _a.wanted;
357
+ var Wanted = wantedStorage.get(id || -1);
358
+ if (wanted && Wanted && !Wanted.box[name] && !Wanted.block) {
359
+ var a = AdapterPropName.firstVisible, a$ = AdapterPropName.firstVisible$;
360
+ var b = AdapterPropName.lastVisible, b$ = AdapterPropName.lastVisible$;
361
+ Wanted.box[a] = Wanted.box[a$] = [a, a$].some(function (n) { return n === name; }) || Wanted.box[a];
362
+ Wanted.box[b] = Wanted.box[b$] = [b, b$].some(function (n) { return n === name; }) || Wanted.box[b];
363
+ return true;
364
+ }
365
+ return false;
366
+ };
367
+ var setBlock = function (value, id) {
368
+ var Wanted = wantedStorage.get(id || -1);
369
+ if (Wanted) {
370
+ Wanted.block = value;
371
+ }
372
+ };
373
+ var wantedUtils = {
374
+ getBox: getBox,
375
+ setBox: setBox,
376
+ setBlock: setBlock
347
377
  };
378
+ var wantedStorage = new Map();
348
379
 
349
380
  var instanceCount$1 = 0;
350
381
  var AdapterContext = /** @class */ (function () {
@@ -354,6 +385,7 @@ var AdapterContext = /** @class */ (function () {
354
385
  var id = ++instanceCount$1;
355
386
  var conf = { configurable: true };
356
387
  var reactivePropsStore = {};
388
+ wantedStorage.set(id, { box: {}, block: false });
357
389
  // set up permanent props
358
390
  Object.defineProperty(this, AdapterPropName.id, __assign({ get: function () { return id; } }, conf));
359
391
  Object.defineProperty(this, AdapterPropName.mock, __assign({ get: function () { return mock; } }, conf));
@@ -365,21 +397,24 @@ var AdapterContext = /** @class */ (function () {
365
397
  var permanent = _a.permanent;
366
398
  return !permanent;
367
399
  })
368
- .forEach(function (_a) {
369
- var name = _a.name, value = _a.value, type = _a.type;
400
+ .forEach(function (prop) {
401
+ var value = prop.value;
370
402
  // reactive props might be reconfigured by the vscroll consumer
371
- if (reactive && type === AdapterPropType.Reactive) {
372
- var react = reactive[name];
403
+ if (reactive && prop.type === AdapterPropType.Reactive) {
404
+ var react = reactive[prop.name];
373
405
  if (react) {
374
406
  // here we have a configured reactive property that came from the outer config
375
407
  // this prop must be exposed via Adapter, but at the same time we need to
376
408
  // persist the original default value as it will be used by the Adapter internally
377
- reactivePropsStore[name] = __assign(__assign({}, react), { default: value // persisting the default native Reactive prop
409
+ reactivePropsStore[prop.name] = __assign(__assign({}, react), { default: value // persisting the default native Reactive prop
378
410
  });
379
411
  value = react.source; // exposing the configured prop instead of the default one
380
412
  }
381
413
  }
382
- Object.defineProperty(_this, name, __assign({ get: function () { return value; } }, conf));
414
+ Object.defineProperty(_this, prop.name, __assign({ get: function () {
415
+ wantedUtils.setBox(prop, id);
416
+ return value;
417
+ } }, conf));
383
418
  });
384
419
  if (reactive) { // save both configured and default reactive props in the store
385
420
  reactiveConfigStorage.set(id, reactivePropsStore);
@@ -402,6 +437,7 @@ var DatasourceGeneric = /** @class */ (function () {
402
437
  }
403
438
  DatasourceGeneric.prototype.dispose = function () {
404
439
  reactiveConfigStorage.delete(this.adapter.id);
440
+ wantedStorage.delete(this.adapter.id);
405
441
  };
406
442
  return DatasourceGeneric;
407
443
  }());
@@ -2574,7 +2610,7 @@ var End = /** @class */ (function (_super) {
2574
2610
  var workflow = scroller.workflow, interrupter = scroller.state.cycle.interrupter;
2575
2611
  if (!error && !interrupter) {
2576
2612
  // set out params accessible via Adapter
2577
- End.calculateParams(scroller, workflow);
2613
+ End.calculateParams(scroller);
2578
2614
  }
2579
2615
  // explicit interruption for we don't want to go through the inner loop finalizing
2580
2616
  if (isInterrupted(workflow)) {
@@ -2589,21 +2625,10 @@ var End = /** @class */ (function (_super) {
2589
2625
  payload: __assign({}, (interrupter ? { process: interrupter } : {}))
2590
2626
  });
2591
2627
  };
2592
- End.calculateParams = function (scroller, workflow) {
2593
- var adapter = scroller.adapter, viewport = scroller.viewport, items = scroller.buffer.items;
2594
- if (adapter.wanted.firstVisible) {
2595
- var item = viewport.getEdgeVisibleItem(items, Direction.backward).item;
2596
- if (!item || item.element !== adapter.firstVisible.element) {
2597
- adapter.firstVisible = item ? item.get() : EMPTY_ITEM;
2598
- }
2599
- }
2600
- // the workflow can be interrupter on firstVisible change
2601
- if (adapter.wanted.lastVisible && !isInterrupted(workflow)) {
2602
- var item = viewport.getEdgeVisibleItem(items, Direction.forward).item;
2603
- if (!item || item.element !== adapter.lastVisible.element) {
2604
- adapter.lastVisible = item ? item.get() : EMPTY_ITEM;
2605
- }
2606
- }
2628
+ End.calculateParams = function (scroller) {
2629
+ var adapter = scroller.adapter, workflow = scroller.workflow;
2630
+ adapter.setFirstOrLastVisible({ first: true, workflow: workflow });
2631
+ adapter.setFirstOrLastVisible({ last: true, workflow: workflow });
2607
2632
  };
2608
2633
  End.shouldContinueRun = function (scroller, error) {
2609
2634
  var _a = scroller.state, cycle = _a.cycle, fetch = _a.fetch, render = _a.render;
@@ -3109,7 +3134,7 @@ var Logger = /** @class */ (function () {
3109
3134
  }
3110
3135
  }
3111
3136
  };
3112
- // logNow(...args: any[]) {
3137
+ // logNow(...args: unknown[]) {
3113
3138
  // const immediateLog = this.immediateLog;
3114
3139
  // const debug = this.debug;
3115
3140
  // (this as any).debug = true;
@@ -4710,14 +4735,19 @@ var Adapter = /** @class */ (function () {
4710
4735
  this.source = {}; // for Reactive props
4711
4736
  this.box = {}; // for Scalars over Reactive props
4712
4737
  this.demand = {}; // for Scalars on demand
4713
- this.wanted = {};
4738
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
4739
+ this.setFirstOrLastVisible = function (_) { };
4714
4740
  this.getWorkflow = getWorkflow;
4715
4741
  this.logger = logger;
4716
4742
  this.relax$ = null;
4717
4743
  this.relaxRun = null;
4718
4744
  this.reloadCounter = 0;
4719
- // public context (if exists) should provide access Reactive props configuration by id
4745
+ var contextId = (context === null || context === void 0 ? void 0 : context.id) || -1;
4746
+ // public context (if exists) should provide access to Reactive props config by id
4720
4747
  var reactivePropsStore = context && reactiveConfigStorage.get(context.id) || {};
4748
+ // the Adapter initialization should not trigger "wanted" props setting;
4749
+ // after the initialization is completed, "wanted" functionality must be unblocked
4750
+ wantedUtils.setBlock(true, contextId);
4721
4751
  // make array of the original values from public context if present
4722
4752
  var adapterProps = context
4723
4753
  ? ADAPTER_PROPS_STUB.map(function (prop) {
@@ -4756,9 +4786,7 @@ var Adapter = /** @class */ (function () {
4756
4786
  get: function () { return value; }
4757
4787
  });
4758
4788
  });
4759
- // Reactive props
4760
- // 1) store original values in "source" container, to avoid extra .get() calls on scalar twins set
4761
- // 2) "wanted" container is bound with scalars; get() updates it
4789
+ // Reactive props: store original values in "source" container, to avoid extra .get() calls on scalar twins set
4762
4790
  adapterProps
4763
4791
  .filter(function (prop) { return prop.type === AdapterPropType.Reactive; })
4764
4792
  .forEach(function (_a) {
@@ -4766,29 +4794,30 @@ var Adapter = /** @class */ (function () {
4766
4794
  _this.source[name] = value;
4767
4795
  Object.defineProperty(_this, name, {
4768
4796
  configurable: true,
4769
- get: function () {
4770
- var scalarWanted = ADAPTER_PROPS_STUB.find(function (_a) {
4771
- var wanted = _a.wanted, reactive = _a.reactive;
4772
- return wanted && reactive === name;
4773
- });
4774
- if (scalarWanted && _this.externalContext) {
4775
- _this.wanted[scalarWanted.name] = true;
4776
- }
4777
- return _this.source[name];
4778
- }
4797
+ get: function () { return _this.source[name]; }
4779
4798
  });
4780
4799
  });
4800
+ // for "wanted" props that can be explicitly requested for the first time after the Adapter initialization,
4801
+ // an implicit calculation of the initial value is required;
4802
+ // so this method should be called when accessing the "wanted" props through one of the following getters
4803
+ var processWanted = function (prop) {
4804
+ if (wantedUtils.setBox(prop, contextId)) {
4805
+ if ([AdapterPropName.firstVisible, AdapterPropName.firstVisible$].some(function (n) { return n === prop.name; })) {
4806
+ _this.setFirstOrLastVisible({ first: true });
4807
+ }
4808
+ else if ([AdapterPropName.lastVisible, AdapterPropName.lastVisible$].some(function (n) { return n === prop.name; })) {
4809
+ _this.setFirstOrLastVisible({ last: true });
4810
+ }
4811
+ }
4812
+ };
4781
4813
  // Scalar props that have Reactive twins
4782
- // 1) scalars should use "box" container
4783
- // 2) "wanted" should be updated on get
4784
- // 3) reactive props (from "source") are triggered on set
4814
+ // 1) reactive props (from "source") should be triggered on set
4815
+ // 2) scalars should use "box" container on get
4816
+ // 3) "wanted" scalars should also run wanted-related logic on get
4785
4817
  adapterProps
4786
4818
  .filter(function (prop) { return prop.type === AdapterPropType.Scalar && !!prop.reactive; })
4787
- .forEach(function (_a) {
4788
- var name = _a.name, value = _a.value, reactive = _a.reactive, wanted = _a.wanted;
4789
- if (wanted) {
4790
- _this.wanted[name] = false;
4791
- }
4819
+ .forEach(function (prop) {
4820
+ var name = prop.name, value = prop.value, reactive = prop.reactive;
4792
4821
  _this.box[name] = value;
4793
4822
  Object.defineProperty(_this, name, {
4794
4823
  configurable: true,
@@ -4804,9 +4833,7 @@ var Adapter = /** @class */ (function () {
4804
4833
  }
4805
4834
  },
4806
4835
  get: function () {
4807
- if (wanted && _this.externalContext) {
4808
- _this.wanted[name] = true;
4809
- }
4836
+ processWanted(prop);
4810
4837
  return _this.box[name];
4811
4838
  }
4812
4839
  });
@@ -4829,8 +4856,8 @@ var Adapter = /** @class */ (function () {
4829
4856
  }
4830
4857
  // Adapter public context augmentation
4831
4858
  adapterProps
4832
- .forEach(function (_a) {
4833
- var name = _a.name, type = _a.type, defaultValue = _a.value, permanent = _a.permanent;
4859
+ .forEach(function (prop) {
4860
+ var name = prop.name, type = prop.type, defaultValue = prop.value, permanent = prop.permanent;
4834
4861
  var value = _this[name];
4835
4862
  if (type === AdapterPropType.Function) {
4836
4863
  value = value.bind(_this);
@@ -4844,14 +4871,20 @@ var Adapter = /** @class */ (function () {
4844
4871
  else if (name === AdapterPropName.augmented) {
4845
4872
  value = true;
4846
4873
  }
4874
+ var nonPermanentScalar = !permanent && type === AdapterPropType.Scalar;
4847
4875
  Object.defineProperty(context, name, {
4848
4876
  configurable: true,
4849
- get: function () { return !permanent && type === AdapterPropType.Scalar
4850
- ? _this[name] // non-permanent Scalars should be taken in runtime
4851
- : value; } // Reactive props and methods (Functions/WorkflowRunners) can be defined once
4877
+ get: function () {
4878
+ processWanted(prop); // consider accessing "wanted" Reactive props
4879
+ if (nonPermanentScalar) {
4880
+ return _this[name]; // non-permanent Scalars should be taken in runtime
4881
+ }
4882
+ return value; // other props (Reactive/Functions/WorkflowRunners) can be defined once
4883
+ }
4852
4884
  });
4853
4885
  });
4854
4886
  this.externalContext = context;
4887
+ wantedUtils.setBlock(false, contextId);
4855
4888
  }
4856
4889
  Object.defineProperty(Adapter.prototype, "workflow", {
4857
4890
  get: function () {
@@ -4891,7 +4924,7 @@ var Adapter = /** @class */ (function () {
4891
4924
  : defaultMethod.apply(_this, args);
4892
4925
  };
4893
4926
  };
4894
- Adapter.prototype.initialize = function (buffer, state, logger, adapterRun$) {
4927
+ Adapter.prototype.initialize = function (buffer, state, viewport, logger, adapterRun$) {
4895
4928
  var _this = this;
4896
4929
  // buffer
4897
4930
  Object.defineProperty(this.demand, AdapterPropName.itemsCount, {
@@ -4920,6 +4953,30 @@ var Adapter = /** @class */ (function () {
4920
4953
  state.cycle.innerLoop.busy.on(function (busy) { return _this.loopPending = busy; });
4921
4954
  this.isLoading = state.cycle.busy.get();
4922
4955
  state.cycle.busy.on(function (busy) { return _this.isLoading = busy; });
4956
+ //viewport
4957
+ this.setFirstOrLastVisible = function (_a) {
4958
+ var _b, _c, _d;
4959
+ var first = _a.first, last = _a.last, workflow = _a.workflow;
4960
+ if ((!first && !last) || ((_b = workflow === null || workflow === void 0 ? void 0 : workflow.call) === null || _b === void 0 ? void 0 : _b.interrupted)) {
4961
+ return;
4962
+ }
4963
+ var token = first ? AdapterPropName.firstVisible : AdapterPropName.lastVisible;
4964
+ if (!((_d = wantedUtils.getBox((_c = _this.externalContext) === null || _c === void 0 ? void 0 : _c.id)) === null || _d === void 0 ? void 0 : _d[token])) {
4965
+ return;
4966
+ }
4967
+ if (buffer.items.some(function (_a) {
4968
+ var element = _a.element;
4969
+ return !element;
4970
+ })) {
4971
+ logger.log('skipping first/lastVisible set because not all buffered items are rendered at this moment');
4972
+ return;
4973
+ }
4974
+ var direction = first ? Direction.backward : Direction.forward;
4975
+ var item = viewport.getEdgeVisibleItem(buffer.items, direction).item;
4976
+ if (!item || item.element !== _this[token].element) {
4977
+ _this[token] = (item ? item.get() : EMPTY_ITEM);
4978
+ }
4979
+ };
4923
4980
  // logger
4924
4981
  this.logger = logger;
4925
4982
  // self-pending subscription; set up only on the very first init
@@ -4966,7 +5023,8 @@ var Adapter = /** @class */ (function () {
4966
5023
  };
4967
5024
  Adapter.prototype.resetContext = function () {
4968
5025
  var _this = this;
4969
- var reactiveStore = reactiveConfigStorage.get(this.externalContext.id);
5026
+ var _a;
5027
+ var reactiveStore = reactiveConfigStorage.get((_a = this.externalContext) === null || _a === void 0 ? void 0 : _a.id);
4970
5028
  ADAPTER_PROPS_STUB
4971
5029
  .forEach(function (_a) {
4972
5030
  var type = _a.type, permanent = _a.permanent, name = _a.name, value = _a.value;
@@ -5185,7 +5243,7 @@ var Scroller = /** @class */ (function () {
5185
5243
  Scroller.prototype.init = function (adapterRun$) {
5186
5244
  this.viewport.reset(this.buffer.startIndex);
5187
5245
  this.logger.stat('initialization');
5188
- this.adapter.initialize(this.buffer, this.state, this.logger, adapterRun$);
5246
+ this.adapter.initialize(this.buffer, this.state, this.viewport, this.logger, adapterRun$);
5189
5247
  };
5190
5248
  Scroller.prototype.dispose = function (forever) {
5191
5249
  if (forever) { // Adapter is not re-instantiated on reset