collect-your-stuff 1.2.9 → 1.3.2

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 (49) hide show
  1. package/README.md +802 -77
  2. package/dist/collections/arrayable/ArrayElement.d.ts +2 -0
  3. package/dist/collections/arrayable/ArrayElement.js +4 -2
  4. package/dist/collections/arrayable/ArrayElement.min.js +1 -1
  5. package/dist/collections/arrayable/Arrayable.d.ts +25 -11
  6. package/dist/collections/arrayable/Arrayable.js +37 -12
  7. package/dist/collections/arrayable/Arrayable.min.js +1 -1
  8. package/dist/collections/doubly-linked-list/DoubleLinker.d.ts +5 -1
  9. package/dist/collections/doubly-linked-list/DoubleLinker.js +5 -1
  10. package/dist/collections/doubly-linked-list/DoublyLinkedList.d.ts +11 -5
  11. package/dist/collections/doubly-linked-list/DoublyLinkedList.js +43 -25
  12. package/dist/collections/doubly-linked-list/DoublyLinkedList.min.js +1 -1
  13. package/dist/collections/linked-list/LinkedList.d.ts +13 -7
  14. package/dist/collections/linked-list/LinkedList.js +42 -23
  15. package/dist/collections/linked-list/LinkedList.min.js +1 -1
  16. package/dist/collections/linked-list/Linker.d.ts +5 -2
  17. package/dist/collections/linked-list/Linker.js +9 -5
  18. package/dist/collections/linked-list/Linker.min.js +1 -1
  19. package/dist/collections/linked-tree-list/LinkedTreeList.d.ts +7 -1
  20. package/dist/collections/linked-tree-list/LinkedTreeList.js +6 -1
  21. package/dist/collections/linked-tree-list/TreeLinker.d.ts +7 -1
  22. package/dist/collections/linked-tree-list/TreeLinker.js +7 -1
  23. package/dist/collections/queue/Queue.d.ts +6 -3
  24. package/dist/collections/queue/Queue.js +23 -18
  25. package/dist/collections/queue/Queue.min.js +1 -1
  26. package/dist/collections/queue/Queueable.d.ts +10 -4
  27. package/dist/collections/queue/Queueable.js +11 -6
  28. package/dist/collections/queue/Queueable.min.js +1 -1
  29. package/dist/collections/stack/Stack.d.ts +4 -3
  30. package/dist/collections/stack/Stack.js +4 -4
  31. package/dist/collections/stack/Stack.min.js +1 -1
  32. package/dist/collections/stack/Stackable.d.ts +4 -1
  33. package/dist/collections/stack/Stackable.js +7 -5
  34. package/dist/collections/stack/Stackable.min.js +1 -1
  35. package/dist/main.d.ts +26 -3
  36. package/dist/main.js +101 -1
  37. package/dist/main.min.js +1 -1
  38. package/dist/recipes/ArrayIterator.d.ts +10 -0
  39. package/dist/recipes/ArrayIterator.js +10 -0
  40. package/dist/recipes/DoubleLinkerIterator.d.ts +9 -0
  41. package/dist/recipes/DoubleLinkerIterator.js +9 -0
  42. package/dist/recipes/LinkerIterator.d.ts +9 -0
  43. package/dist/recipes/LinkerIterator.js +9 -0
  44. package/dist/recipes/Runnable.d.ts +3 -2
  45. package/dist/recipes/Runnable.js +3 -2
  46. package/dist/recipes/TreeLinkerIterator.d.ts +9 -0
  47. package/dist/recipes/TreeLinkerIterator.js +9 -0
  48. package/dist/services/services.d.ts +2 -2
  49. package/package.json +2 -1
@@ -9,7 +9,9 @@ import { IsElement } from '../../recipes/IsElement';
9
9
  * Element represents a node in an Arrayable.
10
10
  */
11
11
  export declare class ArrayElement implements IsElement {
12
+ /** The class used to create this instance, so that it can be recognized as valid without an instanceof check. */
12
13
  readonly classType: typeof ArrayElement;
14
+ /** The data stored in this element. */
13
15
  data: any;
14
16
  /**
15
17
  * Create the new Element instance, provide the data and optionally configure the type of Element.
@@ -15,7 +15,9 @@ class ArrayElement {
15
15
  * @param {*} [data=null] The data to be stored in this element.
16
16
  */
17
17
  constructor (data = null) {
18
+ /** The class used to create this instance, so that it can be recognized as valid without an instanceof check. */
18
19
  this.classType = ArrayElement
20
+ /** The data stored in this element. */
19
21
  this.data = null
20
22
  this.data = data
21
23
  }
@@ -28,8 +30,8 @@ class ArrayElement {
28
30
  */
29
31
  exports.ArrayElement = ArrayElement
30
32
  ArrayElement.make = (element, classType = ArrayElement) => {
31
- if (typeof element !== 'object') {
32
- // It is not an object, so instantiate the Element with element as the data
33
+ if (element === null || typeof element !== 'object') {
34
+ // It is not an object (or it is null), so instantiate the Element with element as the data
33
35
  return new classType(element)
34
36
  }
35
37
  if (element.classType) {
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ArrayElement=void 0,require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.reduce.js");class ArrayElement{constructor(e=null){this.classType=ArrayElement,this.data=null,this.data=e}}exports.ArrayElement=ArrayElement,ArrayElement.make=(e,r=ArrayElement)=>"object"!=typeof e?new r(e):e.classType?e:new r(e),ArrayElement.fromArray=(e=[],r=ArrayElement)=>e.reduce(((e,t)=>{const a=r.make(t,r);return e.head.length?(e.head.push(a),e.tail=a,e):{head:[a],tail:a}}),{head:[],tail:null});
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ArrayElement=void 0,require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.reduce.js");class ArrayElement{constructor(e=null){this.classType=ArrayElement,this.data=null,this.data=e}}exports.ArrayElement=ArrayElement,ArrayElement.make=(e,r=ArrayElement)=>null===e||"object"!=typeof e?new r(e):e.classType?e:new r(e),ArrayElement.fromArray=(e=[],r=ArrayElement)=>e.reduce(((e,t)=>{const a=r.make(t,r);return e.head.length?(e.head.push(a),e.tail=a,e):{head:[a],tail:a}}),{head:[],tail:null});
@@ -11,14 +11,26 @@ import { IsElement } from '../../recipes/IsElement';
11
11
  * Arrayable represents a collection stored as an array.
12
12
  */
13
13
  export declare class Arrayable implements IsArrayable<ArrayElement>, Iterable<ArrayElement> {
14
+ /** The class used to create this instance, so that it can be recognized as valid without an instanceof check. */
14
15
  readonly classType: typeof Arrayable;
16
+ /** The array which stores the elements of this Arrayable. */
15
17
  innerList: Array<ArrayElement>;
18
+ /** Whether the inner list has been initialized (it can only be initialized once). */
16
19
  initialized: boolean;
20
+ /** The class used to wrap the data given to this Arrayable as elements. */
17
21
  elementClass: typeof ArrayElement;
18
22
  /**
19
23
  * Create the new Arrayable instance, configure the Arrayable class.
24
+ * @param {ArrayElement} [elementClass=ArrayElement] The class used to wrap given data as elements.
20
25
  */
21
26
  constructor(elementClass?: typeof ArrayElement);
27
+ /**
28
+ * Find the position of an element which must be in this list.
29
+ * @param {ArrayElement} node The element to find
30
+ * @returns {number}
31
+ * @throws {Error} When the element is not in this list
32
+ */
33
+ private indexOfElement;
22
34
  /**
23
35
  * Initialize the inner list, should only run once.
24
36
  * @param {Array<ArrayElement>} initialList Give the array of elements to start in this Arrayable.
@@ -26,20 +38,20 @@ export declare class Arrayable implements IsArrayable<ArrayElement>, Iterable<Ar
26
38
  */
27
39
  initialize(initialList: Array<ArrayElement>): Arrayable;
28
40
  /**
29
- * Retrieve a copy of the innerList used.
41
+ * Retrieve the innerList used (the list itself, not a copy).
30
42
  * @returns {Array<ArrayElement>}
31
43
  */
32
44
  get list(): Array<ArrayElement>;
33
45
  /**
34
46
  * Retrieve the first Element from the Arrayable
35
- * @returns {ArrayElement}
47
+ * @returns {ArrayElement|null} The first element, or null when the Arrayable is empty
36
48
  */
37
- get first(): ArrayElement;
49
+ get first(): ArrayElement | null;
38
50
  /**
39
51
  * Retrieve the last Element from the Arrayable
40
- * @returns {ArrayElement}
52
+ * @returns {ArrayElement|null} The last element, or null when the Arrayable is empty
41
53
  */
42
- get last(): ArrayElement;
54
+ get last(): ArrayElement | null;
43
55
  /**
44
56
  * Return the length of the list.
45
57
  * @returns {number}
@@ -47,18 +59,20 @@ export declare class Arrayable implements IsArrayable<ArrayElement>, Iterable<Ar
47
59
  get length(): number;
48
60
  /**
49
61
  * Insert a new node (or data) after a node.
50
- * @param {ArrayElement|*} node The existing node as reference
62
+ * @param {ArrayElement|null} node The existing node as reference, or null to insert at the start of the list
51
63
  * @param {ArrayElement|*} newNode The new node to go after the existing node
52
64
  * @returns {Arrayable}
65
+ * @throws {Error} When the reference node is not in this list
53
66
  */
54
- insertAfter(node: ArrayElement, newNode: ArrayElement | any): Arrayable;
67
+ insertAfter(node: ArrayElement | null, newNode: ArrayElement | any): Arrayable;
55
68
  /**
56
69
  * Insert a new node (or data) before a node.
57
- * @param {ArrayElement|*} node The existing node as reference
70
+ * @param {ArrayElement|null} node The existing node as reference, or null to insert at the end of the list
58
71
  * @param {ArrayElement|*} newNode The new node to go before the existing node
59
72
  * @returns {Arrayable}
73
+ * @throws {Error} When the reference node is not in this list
60
74
  */
61
- insertBefore(node: ArrayElement, newNode: ArrayElement | any): Arrayable;
75
+ insertBefore(node: ArrayElement | null, newNode: ArrayElement | any): Arrayable;
62
76
  /**
63
77
  * Add a node (or data) after the given (or last) node in the list.
64
78
  * @param {ArrayElement|*} node The new node to add to the end of the list
@@ -76,9 +90,9 @@ export declare class Arrayable implements IsArrayable<ArrayElement>, Iterable<Ar
76
90
  /**
77
91
  * Remove an element from this arrayable.
78
92
  * @param {ArrayElement} node The node we wish to remove (and it will be returned after removal)
79
- * @return {ArrayElement}
93
+ * @return {ArrayElement|null} The removed node, or null when it was not in this list (nothing is removed)
80
94
  */
81
- remove(node: ArrayElement): ArrayElement;
95
+ remove(node: ArrayElement): ArrayElement | null;
82
96
  /**
83
97
  * Retrieve an ArrayElement item from this list by numeric index, otherwise return null.
84
98
  * @param {number} index The integer number for retrieving a node by position.
@@ -19,14 +19,32 @@ var _ArrayIterator = require('../../recipes/ArrayIterator')
19
19
  class Arrayable {
20
20
  /**
21
21
  * Create the new Arrayable instance, configure the Arrayable class.
22
+ * @param {ArrayElement} [elementClass=ArrayElement] The class used to wrap given data as elements.
22
23
  */
23
24
  constructor (elementClass = _ArrayElement.ArrayElement) {
25
+ /** The class used to create this instance, so that it can be recognized as valid without an instanceof check. */
24
26
  this.classType = Arrayable
27
+ /** The array which stores the elements of this Arrayable. */
25
28
  this.innerList = []
29
+ /** Whether the inner list has been initialized (it can only be initialized once). */
26
30
  this.initialized = false
27
31
  this.elementClass = elementClass
28
32
  }
29
33
 
34
+ /**
35
+ * Find the position of an element which must be in this list.
36
+ * @param {ArrayElement} node The element to find
37
+ * @returns {number}
38
+ * @throws {Error} When the element is not in this list
39
+ */
40
+ indexOfElement (node) {
41
+ const index = this.innerList.indexOf(node)
42
+ if (index < 0) {
43
+ throw new Error('The reference element is not in this list.')
44
+ }
45
+ return index
46
+ }
47
+
30
48
  /**
31
49
  * Initialize the inner list, should only run once.
32
50
  * @param {Array<ArrayElement>} initialList Give the array of elements to start in this Arrayable.
@@ -43,7 +61,7 @@ class Arrayable {
43
61
  }
44
62
 
45
63
  /**
46
- * Retrieve a copy of the innerList used.
64
+ * Retrieve the innerList used (the list itself, not a copy).
47
65
  * @returns {Array<ArrayElement>}
48
66
  */
49
67
  get list () {
@@ -52,18 +70,18 @@ class Arrayable {
52
70
 
53
71
  /**
54
72
  * Retrieve the first Element from the Arrayable
55
- * @returns {ArrayElement}
73
+ * @returns {ArrayElement|null} The first element, or null when the Arrayable is empty
56
74
  */
57
75
  get first () {
58
- return this.innerList[0]
76
+ return this.length ? this.innerList[0] : null
59
77
  }
60
78
 
61
79
  /**
62
80
  * Retrieve the last Element from the Arrayable
63
- * @returns {ArrayElement}
81
+ * @returns {ArrayElement|null} The last element, or null when the Arrayable is empty
64
82
  */
65
83
  get last () {
66
- return this.innerList[this.length - 1]
84
+ return this.length ? this.innerList[this.length - 1] : null
67
85
  }
68
86
 
69
87
  /**
@@ -76,25 +94,29 @@ class Arrayable {
76
94
 
77
95
  /**
78
96
  * Insert a new node (or data) after a node.
79
- * @param {ArrayElement|*} node The existing node as reference
97
+ * @param {ArrayElement|null} node The existing node as reference, or null to insert at the start of the list
80
98
  * @param {ArrayElement|*} newNode The new node to go after the existing node
81
99
  * @returns {Arrayable}
100
+ * @throws {Error} When the reference node is not in this list
82
101
  */
83
102
  insertAfter (node, newNode) {
84
- const insertAt = this.innerList.indexOf(node)
85
- this.innerList.splice(insertAt + 1, 0, this.elementClass.make(newNode))
103
+ // With no reference element, the new one goes after nothing: at the start of the list
104
+ const insertAt = node === null || typeof node === 'undefined' ? -1 : this.indexOfElement(node)
105
+ this.innerList.splice(insertAt + 1, 0, this.elementClass.make(newNode, this.elementClass))
86
106
  return this
87
107
  }
88
108
 
89
109
  /**
90
110
  * Insert a new node (or data) before a node.
91
- * @param {ArrayElement|*} node The existing node as reference
111
+ * @param {ArrayElement|null} node The existing node as reference, or null to insert at the end of the list
92
112
  * @param {ArrayElement|*} newNode The new node to go before the existing node
93
113
  * @returns {Arrayable}
114
+ * @throws {Error} When the reference node is not in this list
94
115
  */
95
116
  insertBefore (node, newNode) {
96
- const insertAt = this.innerList.indexOf(node)
97
- this.innerList.splice(insertAt, 0, this.elementClass.make(newNode))
117
+ // With no reference element, the new one goes before nothing: at the end of the list
118
+ const insertAt = node === null || typeof node === 'undefined' ? this.length : this.indexOfElement(node)
119
+ this.innerList.splice(insertAt, 0, this.elementClass.make(newNode, this.elementClass))
98
120
  return this
99
121
  }
100
122
 
@@ -121,10 +143,13 @@ class Arrayable {
121
143
  /**
122
144
  * Remove an element from this arrayable.
123
145
  * @param {ArrayElement} node The node we wish to remove (and it will be returned after removal)
124
- * @return {ArrayElement}
146
+ * @return {ArrayElement|null} The removed node, or null when it was not in this list (nothing is removed)
125
147
  */
126
148
  remove (node) {
127
149
  const deleteAt = this.innerList.indexOf(node)
150
+ if (deleteAt < 0) {
151
+ return null
152
+ }
128
153
  this.innerList.splice(deleteAt, 1)
129
154
  return node
130
155
  }
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.Arrayable=void 0;var _ArrayElement=require("./ArrayElement"),_ArrayIterator=require("../../recipes/ArrayIterator");class Arrayable{constructor(t=_ArrayElement.ArrayElement){this.classType=Arrayable,this.innerList=[],this.initialized=!1,this.elementClass=t}initialize(t){return this.initialized?(console.warn("Attempt to initialize non-empty list."),this):(this.initialized=!0,this.innerList=t,this)}get list(){return this.innerList}get first(){return this.innerList[0]}get last(){return this.innerList[this.length-1]}get length(){return this.innerList.length}insertAfter(t,e){const r=this.innerList.indexOf(t);return this.innerList.splice(r+1,0,this.elementClass.make(e)),this}insertBefore(t,e){const r=this.innerList.indexOf(t);return this.innerList.splice(r,0,this.elementClass.make(e)),this}append(t,e=this.last){return this.insertAfter(e,t)}prepend(t,e=this.first){return this.insertBefore(e,t)}remove(t){const e=this.innerList.indexOf(t);return this.innerList.splice(e,1),t}item(t){if(t>=this.length)return null;if(t>=0)return this.innerList[t];const e=this.length+t;return e<0?null:this.innerList[e]}forEach(t,e=this){for(let r=0;r<e.length;++r)t(e.item(r),r,e);return e}[Symbol.iterator](){return new _ArrayIterator.ArrayIterator(this.innerList,0)}}exports.Arrayable=Arrayable,Arrayable.fromArray=(t=[],e=_ArrayElement.ArrayElement,r=Arrayable)=>new r(e).initialize(e.fromArray(t).head);
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.Arrayable=void 0;var _ArrayElement=require("./ArrayElement"),_ArrayIterator=require("../../recipes/ArrayIterator");class Arrayable{constructor(e=_ArrayElement.ArrayElement){this.classType=Arrayable,this.innerList=[],this.initialized=!1,this.elementClass=e}indexOfElement(e){const t=this.innerList.indexOf(e);if(t<0)throw new Error("The reference element is not in this list.");return t}initialize(e){return this.initialized?(console.warn("Attempt to initialize non-empty list."),this):(this.initialized=!0,this.innerList=e,this)}get list(){return this.innerList}get first(){return this.length?this.innerList[0]:null}get last(){return this.length?this.innerList[this.length-1]:null}get length(){return this.innerList.length}insertAfter(e,t){const r=null==e?-1:this.indexOfElement(e);return this.innerList.splice(r+1,0,this.elementClass.make(t,this.elementClass)),this}insertBefore(e,t){const r=null==e?this.length:this.indexOfElement(e);return this.innerList.splice(r,0,this.elementClass.make(t,this.elementClass)),this}append(e,t=this.last){return this.insertAfter(t,e)}prepend(e,t=this.first){return this.insertBefore(t,e)}remove(e){const t=this.innerList.indexOf(e);return t<0?null:(this.innerList.splice(t,1),e)}item(e){if(e>=this.length)return null;if(e>=0)return this.innerList[e];const t=this.length+e;return t<0?null:this.innerList[t]}forEach(e,t=this){for(let r=0;r<t.length;++r)e(t.item(r),r,t);return t}[Symbol.iterator](){return new _ArrayIterator.ArrayIterator(this.innerList,0)}}exports.Arrayable=Arrayable,Arrayable.fromArray=(e=[],t=_ArrayElement.ArrayElement,r=Arrayable)=>new r(t).initialize(t.fromArray(e).head);
@@ -10,13 +10,17 @@ import { IsDoubleLinker } from '../../recipes/IsDoubleLinker';
10
10
  * @extends Linker
11
11
  */
12
12
  export declare class DoubleLinker implements IsDoubleLinker {
13
+ /** The class used to create this instance, so that it can be recognized as valid without an instanceof check. */
13
14
  readonly classType: typeof DoubleLinker;
15
+ /** The data stored in this linker. */
14
16
  data: any;
17
+ /** The linker after this one, or null when this is the last. */
15
18
  next: DoubleLinker | null;
19
+ /** The linker before this one, or null when this is the first. */
16
20
  prev: DoubleLinker | null;
17
21
  /**
18
22
  * Create the new DoubleLinker instance, provide the data and optionally the next and prev references.
19
- * @param {Object} [nodeData={}]
23
+ * @param {Object} [nodeData={}] The settings for the new linker.
20
24
  * @param {*} [nodeData.data=null] The data to be stored in this linker
21
25
  * @param {DoubleLinker|null} [nodeData.next=null] The reference to the next linker if any
22
26
  * @param {DoubleLinker|null} [nodeData.prev=null] The reference to the previous linker if any
@@ -14,7 +14,7 @@ var _Linker = require('../linked-list/Linker')
14
14
  class DoubleLinker {
15
15
  /**
16
16
  * Create the new DoubleLinker instance, provide the data and optionally the next and prev references.
17
- * @param {Object} [nodeData={}]
17
+ * @param {Object} [nodeData={}] The settings for the new linker.
18
18
  * @param {*} [nodeData.data=null] The data to be stored in this linker
19
19
  * @param {DoubleLinker|null} [nodeData.next=null] The reference to the next linker if any
20
20
  * @param {DoubleLinker|null} [nodeData.prev=null] The reference to the previous linker if any
@@ -24,9 +24,13 @@ class DoubleLinker {
24
24
  next = null,
25
25
  prev = null
26
26
  } = {}) {
27
+ /** The class used to create this instance, so that it can be recognized as valid without an instanceof check. */
27
28
  this.classType = DoubleLinker
29
+ /** The data stored in this linker. */
28
30
  this.data = null
31
+ /** The linker after this one, or null when this is the last. */
29
32
  this.next = null
33
+ /** The linker before this one, or null when this is the first. */
30
34
  this.prev = null
31
35
  this.data = data
32
36
  this.next = next
@@ -12,12 +12,17 @@ import { IsDoubleLinker } from '../../recipes/IsDoubleLinker';
12
12
  * @extends LinkedList
13
13
  */
14
14
  export declare class DoublyLinkedList implements IsArrayable<DoubleLinker>, Iterable<DoubleLinker> {
15
+ /** The class used to create this instance, so that it can be recognized as valid without an instanceof check. */
15
16
  readonly classType: typeof DoublyLinkedList;
17
+ /** A linker of the list (null when the list is empty); the head is found by walking back from it. */
16
18
  innerList: DoubleLinker;
19
+ /** Whether the inner list has been initialized (it can only be initialized once). */
17
20
  initialized: boolean;
21
+ /** The class used to wrap the data given to this list as linkers. */
18
22
  linkerClass: typeof DoubleLinker;
19
23
  /**
20
24
  * Create the new DoublyLinkedList instance.
25
+ * @param {DoubleLinker} [linkerClass=DoubleLinker] The class used to wrap given data as linkers.
21
26
  */
22
27
  constructor(linkerClass?: typeof DoubleLinker);
23
28
  /**
@@ -27,7 +32,7 @@ export declare class DoublyLinkedList implements IsArrayable<DoubleLinker>, Iter
27
32
  */
28
33
  initialize(initialList: DoubleLinker): DoublyLinkedList;
29
34
  /**
30
- * Retrieve a copy of the innerList used.
35
+ * Retrieve the innerList used (the list itself, not a copy).
31
36
  * @returns {DoubleLinker}
32
37
  */
33
38
  get list(): DoubleLinker;
@@ -48,18 +53,18 @@ export declare class DoublyLinkedList implements IsArrayable<DoubleLinker>, Iter
48
53
  get length(): number;
49
54
  /**
50
55
  * Insert a new node (or data) after a node.
51
- * @param {DoubleLinker|*} node The existing node as reference
56
+ * @param {DoubleLinker|*} node The existing node as reference (which must be in this list, this is not checked), or null to insert at the start of the list
52
57
  * @param {DoubleLinker|*} newNode The new node to go after the existing node
53
58
  * @returns {DoublyLinkedList}
54
59
  */
55
- insertAfter(node: DoubleLinker, newNode: DoubleLinker | any): DoublyLinkedList;
60
+ insertAfter(node: DoubleLinker | null, newNode: DoubleLinker | any): DoublyLinkedList;
56
61
  /**
57
62
  * Insert a new node (or data) before a node.
58
- * @param {DoubleLinker|*} node The existing node as reference
63
+ * @param {DoubleLinker|*} node The existing node as reference (which must be in this list, this is not checked), or null to insert at the end of the list
59
64
  * @param {DoubleLinker|*} newNode The new node to go before the existing node
60
65
  * @returns {DoublyLinkedList}
61
66
  */
62
- insertBefore(node: DoubleLinker, newNode: DoubleLinker | any): DoublyLinkedList;
67
+ insertBefore(node: DoubleLinker | null, newNode: DoubleLinker | any): DoublyLinkedList;
63
68
  /**
64
69
  * Add a node (or data) after the given (or last) node in the list.
65
70
  * @param {DoubleLinker|*} node The new node to add to the end of the list
@@ -95,6 +100,7 @@ export declare class DoublyLinkedList implements IsArrayable<DoubleLinker>, Iter
95
100
  * Be able to run forEach on this DoublyLinkedList to iterate over the DoubleLinker Items.
96
101
  * @param {forEachCallback} callback The function to call for-each double linker
97
102
  * @param {DoublyLinkedList} thisArg Optional, 'this' reference
103
+ * @return {DoublyLinkedList} The list which was iterated.
98
104
  */
99
105
  forEach(callback: forEachCallback, thisArg?: DoublyLinkedList): DoublyLinkedList;
100
106
  /**
@@ -23,10 +23,14 @@ var _LinkedList = require('../linked-list/LinkedList')
23
23
  class DoublyLinkedList {
24
24
  /**
25
25
  * Create the new DoublyLinkedList instance.
26
+ * @param {DoubleLinker} [linkerClass=DoubleLinker] The class used to wrap given data as linkers.
26
27
  */
27
28
  constructor (linkerClass = _DoubleLinker.DoubleLinker) {
29
+ /** The class used to create this instance, so that it can be recognized as valid without an instanceof check. */
28
30
  this.classType = DoublyLinkedList
31
+ /** A linker of the list (null when the list is empty); the head is found by walking back from it. */
29
32
  this.innerList = null
33
+ /** Whether the inner list has been initialized (it can only be initialized once). */
30
34
  this.initialized = false
31
35
  this.linkerClass = linkerClass
32
36
  }
@@ -37,11 +41,12 @@ class DoublyLinkedList {
37
41
  * @return {DoublyLinkedList}
38
42
  */
39
43
  initialize (initialList) {
44
+ // Borrowed from LinkedList, which types its return as a LinkedList although it returns whatever list called it
40
45
  return _LinkedList.LinkedList.prototype.initialize.call(this, initialList)
41
46
  }
42
47
 
43
48
  /**
44
- * Retrieve a copy of the innerList used.
49
+ * Retrieve the innerList used (the list itself, not a copy).
45
50
  * @returns {DoubleLinker}
46
51
  */
47
52
  get list () {
@@ -89,54 +94,66 @@ class DoublyLinkedList {
89
94
 
90
95
  /**
91
96
  * Insert a new node (or data) after a node.
92
- * @param {DoubleLinker|*} node The existing node as reference
97
+ * @param {DoubleLinker|*} node The existing node as reference (which must be in this list, this is not checked), or null to insert at the start of the list
93
98
  * @param {DoubleLinker|*} newNode The new node to go after the existing node
94
99
  * @returns {DoublyLinkedList}
95
100
  */
96
101
  insertAfter (node, newNode) {
97
- newNode = this.linkerClass.make(newNode)
98
- if (node !== null) {
99
- // Ensure the next reference of this node is assigned to the new node
100
- newNode.next = node.next
101
- // Ensure this node is assigned as the prev reference of the new node
102
- newNode.prev = node
103
- // Then set this node's next reference to the new node
104
- node.next = newNode
102
+ newNode = this.linkerClass.make(newNode, this.linkerClass)
103
+ if (node === null || typeof node === 'undefined') {
104
+ // After nothing means at the start of the list
105
+ const head = this.first
106
+ newNode.next = head
107
+ if (head) {
108
+ head.prev = newNode
109
+ }
110
+ this.innerList = newNode
111
+ return this
105
112
  }
113
+ // Ensure the next reference of this node is assigned to the new node
114
+ newNode.next = node.next
115
+ // Ensure this node is assigned as the prev reference of the new node
116
+ newNode.prev = node
117
+ // Then set this node's next reference to the new node
118
+ node.next = newNode
106
119
  if (newNode.next) {
107
120
  // Update the next reference to ensure circular reference for prev points to the new node
108
121
  newNode.next.prev = newNode
109
122
  }
110
- if (!this.length) {
111
- this.innerList = newNode
112
- }
113
123
  this.reset()
114
124
  return this
115
125
  }
116
126
 
117
127
  /**
118
128
  * Insert a new node (or data) before a node.
119
- * @param {DoubleLinker|*} node The existing node as reference
129
+ * @param {DoubleLinker|*} node The existing node as reference (which must be in this list, this is not checked), or null to insert at the end of the list
120
130
  * @param {DoubleLinker|*} newNode The new node to go before the existing node
121
131
  * @returns {DoublyLinkedList}
122
132
  */
123
133
  insertBefore (node, newNode) {
124
- newNode = this.linkerClass.make(newNode)
125
- if (node !== null) {
126
- // The new node will reference this prev node as prev
127
- newNode.prev = node.prev
128
- // The new node will reference this node as next
129
- newNode.next = node
130
- // This prev will reference the new node
131
- node.prev = newNode
134
+ newNode = this.linkerClass.make(newNode, this.linkerClass)
135
+ if (node === null || typeof node === 'undefined') {
136
+ // Before nothing means at the end of the list
137
+ const tail = this.last
138
+ if (tail === null) {
139
+ this.innerList = newNode
140
+ } else {
141
+ tail.next = newNode
142
+ newNode.prev = tail
143
+ }
144
+ this.reset()
145
+ return this
132
146
  }
147
+ // The new node will reference this prev node as prev
148
+ newNode.prev = node.prev
149
+ // The new node will reference this node as next
150
+ newNode.next = node
151
+ // This prev will reference the new node
152
+ node.prev = newNode
133
153
  if (newNode.prev) {
134
154
  // Update the prev reference to ensure circular reference for next points to the new node
135
155
  newNode.prev.next = newNode
136
156
  }
137
- if (!this.length) {
138
- this.innerList = newNode
139
- }
140
157
  this.reset()
141
158
  return this
142
159
  }
@@ -247,6 +264,7 @@ class DoublyLinkedList {
247
264
  * Be able to run forEach on this DoublyLinkedList to iterate over the DoubleLinker Items.
248
265
  * @param {forEachCallback} callback The function to call for-each double linker
249
266
  * @param {DoublyLinkedList} thisArg Optional, 'this' reference
267
+ * @return {DoublyLinkedList} The list which was iterated.
250
268
  */
251
269
  forEach (callback, thisArg = this) {
252
270
  return _LinkedList.LinkedList.prototype.forEach.call(this, callback, thisArg)
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.DoublyLinkedList=void 0,require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.for-each.js");var _DoubleLinker=require("./DoubleLinker"),_DoubleLinkerIterator=require("../../recipes/DoubleLinkerIterator"),_LinkedList=require("../linked-list/LinkedList");class DoublyLinkedList{constructor(e=_DoubleLinker.DoubleLinker){this.classType=DoublyLinkedList,this.innerList=null,this.initialized=!1,this.linkerClass=e}initialize(e){return _LinkedList.LinkedList.prototype.initialize.call(this,e)}get list(){return this.innerList}get first(){return this.reset()}get last(){let e=this.innerList;if(null===e)return null;let t=e.next;for(;null!==t;)e=t,t=e.next;return e}get length(){let e=this.first,t=0;for(;null!==e;)++t,e=e.next;return t}insertAfter(e,t){return t=this.linkerClass.make(t),null!==e&&(t.next=e.next,t.prev=e,e.next=t),t.next&&(t.next.prev=t),this.length||(this.innerList=t),this.reset(),this}insertBefore(e,t){return t=this.linkerClass.make(t),null!==e&&(t.prev=e.prev,t.next=e,e.prev=t),t.prev&&(t.prev.next=t),this.length||(this.innerList=t),this.reset(),this}append(e,t=this.last){return this.insertAfter(t,e)}prepend(e,t=this.first){return this.insertBefore(t,e)}remove(e){return null===e?null:(e.prev&&(e.prev.next=e.next),e.next&&(e.next.prev=e.prev),this.innerList===e&&(this.innerList=e.next||e.prev||null),this.reset(),e)}reset(){let e=this.innerList;if(null===e)return null;let t=e.next;for(;null!==t;)e=t,t=e.next;let r=e.prev;for(;null!==r;)e=r,r=e.prev;return this.innerList=e,e}item(e){if(e>=0){let t=this.first,r=-1;for(;++r<e&&null!==t;)t=t.next;return r===e?t:null}let t=this.last,r=this.length;const i=this.length+e;if(i<0)return null;for(;--r>i&&null!==t;)t=t.prev;return r===i?t:null}forEach(e,t=this){return _LinkedList.LinkedList.prototype.forEach.call(this,e,t)}[Symbol.iterator](){let e=this.first;return new _DoubleLinkerIterator.DoubleLinkerIterator(e)}}exports.DoublyLinkedList=DoublyLinkedList,DoublyLinkedList.fromArray=(e=[],t=_DoubleLinker.DoubleLinker,r=DoublyLinkedList)=>_LinkedList.LinkedList.fromArray(e,t,r);
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.DoublyLinkedList=void 0,require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.for-each.js");var _DoubleLinker=require("./DoubleLinker"),_DoubleLinkerIterator=require("../../recipes/DoubleLinkerIterator"),_LinkedList=require("../linked-list/LinkedList");class DoublyLinkedList{constructor(e=_DoubleLinker.DoubleLinker){this.classType=DoublyLinkedList,this.innerList=null,this.initialized=!1,this.linkerClass=e}initialize(e){return _LinkedList.LinkedList.prototype.initialize.call(this,e)}get list(){return this.innerList}get first(){return this.reset()}get last(){let e=this.innerList;if(null===e)return null;let t=e.next;for(;null!==t;)e=t,t=e.next;return e}get length(){let e=this.first,t=0;for(;null!==e;)++t,e=e.next;return t}insertAfter(e,t){if(t=this.linkerClass.make(t,this.linkerClass),null==e){const e=this.first;return t.next=e,e&&(e.prev=t),this.innerList=t,this}return t.next=e.next,t.prev=e,e.next=t,t.next&&(t.next.prev=t),this.reset(),this}insertBefore(e,t){if(t=this.linkerClass.make(t,this.linkerClass),null==e){const e=this.last;return null===e?this.innerList=t:(e.next=t,t.prev=e),this.reset(),this}return t.prev=e.prev,t.next=e,e.prev=t,t.prev&&(t.prev.next=t),this.reset(),this}append(e,t=this.last){return this.insertAfter(t,e)}prepend(e,t=this.first){return this.insertBefore(t,e)}remove(e){return null===e?null:(e.prev&&(e.prev.next=e.next),e.next&&(e.next.prev=e.prev),this.innerList===e&&(this.innerList=e.next||e.prev||null),this.reset(),e)}reset(){let e=this.innerList;if(null===e)return null;let t=e.next;for(;null!==t;)e=t,t=e.next;let r=e.prev;for(;null!==r;)e=r,r=e.prev;return this.innerList=e,e}item(e){if(e>=0){let t=this.first,r=-1;for(;++r<e&&null!==t;)t=t.next;return r===e?t:null}let t=this.last,r=this.length;const i=this.length+e;if(i<0)return null;for(;--r>i&&null!==t;)t=t.prev;return r===i?t:null}forEach(e,t=this){return _LinkedList.LinkedList.prototype.forEach.call(this,e,t)}[Symbol.iterator](){let e=this.first;return new _DoubleLinkerIterator.DoubleLinkerIterator(e)}}exports.DoublyLinkedList=DoublyLinkedList,DoublyLinkedList.fromArray=(e=[],t=_DoubleLinker.DoubleLinker,r=DoublyLinkedList)=>_LinkedList.LinkedList.fromArray(e,t,r);
@@ -12,12 +12,17 @@ import { Linker } from './Linker';
12
12
  * @extends Arrayable
13
13
  */
14
14
  export declare class LinkedList implements IsArrayable<Linker>, Iterable<Linker> {
15
+ /** The class used to create this instance, so that it can be recognized as valid without an instanceof check. */
15
16
  readonly classType: typeof LinkedList;
17
+ /** The first linker of the list (null when the list is empty), from which the whole list is reached. */
16
18
  innerList: Linker;
19
+ /** Whether the inner list has been initialized (it can only be initialized once). */
17
20
  initialized: boolean;
21
+ /** The class used to wrap the data given to this list as linkers. */
18
22
  linkerClass: typeof Linker;
19
23
  /**
20
24
  * Create the new LinkedList instance.
25
+ * @param {Linker} [linkerClass=Linker] The class used to wrap given data as linkers.
21
26
  */
22
27
  constructor(linkerClass?: typeof Linker);
23
28
  /**
@@ -27,7 +32,7 @@ export declare class LinkedList implements IsArrayable<Linker>, Iterable<Linker>
27
32
  */
28
33
  initialize(initialList: Linker): LinkedList;
29
34
  /**
30
- * Retrieve a copy of the innerList used.
35
+ * Retrieve the innerList used (the list itself, not a copy).
31
36
  * @returns {Linker}
32
37
  */
33
38
  get list(): IsLinker;
@@ -48,18 +53,19 @@ export declare class LinkedList implements IsArrayable<Linker>, Iterable<Linker>
48
53
  get length(): number;
49
54
  /**
50
55
  * Insert a new node (or data) after a node.
51
- * @param {Linker|*} node The existing node as reference
56
+ * @param {Linker|*} node The existing node as reference, or null to insert at the start of the list
52
57
  * @param {Linker|*} newNode The new node to go after the existing node
53
58
  * @returns {LinkedList}
54
59
  */
55
- insertAfter(node: IsLinker, newNode: Linker | any): LinkedList;
60
+ insertAfter(node: IsLinker | null, newNode: Linker | any): LinkedList;
56
61
  /**
57
62
  * Insert a new node (or data) before a node.
58
- * @param {Linker|*} node The existing node as reference
63
+ * @param {Linker|*} node The existing node as reference, or null to insert at the end of the list
59
64
  * @param {Linker|*} newNode The new node to go before the existing node
60
65
  * @returns {LinkedList}
66
+ * @throws {Error} When the reference node is not in this list
61
67
  */
62
- insertBefore(node: IsLinker, newNode: Linker | any): LinkedList;
68
+ insertBefore(node: IsLinker | null, newNode: Linker | any): LinkedList;
63
69
  /**
64
70
  * Add a node (or data) after the given (or last) node in the list.
65
71
  * @param {Linker|*} node The new node to add to the end of the list
@@ -77,9 +83,9 @@ export declare class LinkedList implements IsArrayable<Linker>, Iterable<Linker>
77
83
  /**
78
84
  * Remove a linker from this linked list.
79
85
  * @param {Linker} node The node we wish to remove (and it will be returned after removal)
80
- * @return {Linker}
86
+ * @return {Linker|null} The removed node, or null when it was not in this list (nothing is removed)
81
87
  */
82
- remove(node: Linker): Linker;
88
+ remove(node: Linker | null): Linker | null;
83
89
  /**
84
90
  * Retrieve a Linker item from this list by numeric index, otherwise return null.
85
91
  * @param {number} index The integer number for retrieving a node by position.