collect-your-stuff 1.3.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +802 -77
- package/dist/collections/arrayable/ArrayElement.d.ts +2 -0
- package/dist/collections/arrayable/ArrayElement.js +4 -2
- package/dist/collections/arrayable/ArrayElement.min.js +1 -1
- package/dist/collections/arrayable/Arrayable.d.ts +27 -13
- package/dist/collections/arrayable/Arrayable.js +47 -12
- package/dist/collections/arrayable/Arrayable.min.js +1 -1
- package/dist/collections/doubly-linked-list/DoubleLinker.d.ts +5 -1
- package/dist/collections/doubly-linked-list/DoubleLinker.js +5 -1
- package/dist/collections/doubly-linked-list/DoublyLinkedList.d.ts +25 -13
- package/dist/collections/doubly-linked-list/DoublyLinkedList.js +106 -53
- package/dist/collections/doubly-linked-list/DoublyLinkedList.min.js +1 -1
- package/dist/collections/linked-list/LinkedList.d.ts +27 -10
- package/dist/collections/linked-list/LinkedList.js +106 -43
- package/dist/collections/linked-list/LinkedList.min.js +1 -1
- package/dist/collections/linked-list/Linker.d.ts +5 -2
- package/dist/collections/linked-list/Linker.js +9 -5
- package/dist/collections/linked-list/Linker.min.js +1 -1
- package/dist/collections/linked-tree-list/LinkedTreeList.d.ts +16 -4
- package/dist/collections/linked-tree-list/LinkedTreeList.js +25 -22
- package/dist/collections/linked-tree-list/LinkedTreeList.min.js +1 -1
- package/dist/collections/linked-tree-list/TreeLinker.d.ts +7 -1
- package/dist/collections/linked-tree-list/TreeLinker.js +7 -1
- package/dist/collections/queue/Queue.d.ts +6 -3
- package/dist/collections/queue/Queue.js +23 -18
- package/dist/collections/queue/Queue.min.js +1 -1
- package/dist/collections/queue/Queueable.d.ts +10 -4
- package/dist/collections/queue/Queueable.js +11 -6
- package/dist/collections/queue/Queueable.min.js +1 -1
- package/dist/collections/stack/Stack.d.ts +4 -3
- package/dist/collections/stack/Stack.js +4 -4
- package/dist/collections/stack/Stack.min.js +1 -1
- package/dist/collections/stack/Stackable.d.ts +4 -1
- package/dist/collections/stack/Stackable.js +7 -5
- package/dist/collections/stack/Stackable.min.js +1 -1
- package/dist/main.d.ts +2 -2
- package/dist/recipes/ArrayIterator.d.ts +10 -0
- package/dist/recipes/ArrayIterator.js +10 -0
- package/dist/recipes/DoubleLinkerIterator.d.ts +9 -0
- package/dist/recipes/DoubleLinkerIterator.js +9 -0
- package/dist/recipes/LinkerIterator.d.ts +9 -0
- package/dist/recipes/LinkerIterator.js +9 -0
- package/dist/recipes/Runnable.d.ts +3 -2
- package/dist/recipes/Runnable.js +3 -2
- package/dist/recipes/TreeLinkerIterator.d.ts +9 -0
- package/dist/recipes/TreeLinkerIterator.js +9 -0
- package/package.json +2 -1
|
@@ -14,7 +14,7 @@ var _ArrayElement = require('../arrayable/ArrayElement')
|
|
|
14
14
|
class Linker {
|
|
15
15
|
/**
|
|
16
16
|
* Create the new Linker instance, provide the data and optionally give the next Linker.
|
|
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 {Linker|null} [nodeData.next=null] The reference to the next linker if any
|
|
20
20
|
*/
|
|
@@ -22,8 +22,11 @@ class Linker {
|
|
|
22
22
|
data = null,
|
|
23
23
|
next = null
|
|
24
24
|
} = {}) {
|
|
25
|
+
/** The class used to create this instance, so that it can be recognized as valid without an instanceof check. */
|
|
25
26
|
this.classType = Linker
|
|
27
|
+
/** The data stored in this linker. */
|
|
26
28
|
this.data = null
|
|
29
|
+
/** The linker after this one, or null when this is the last. */
|
|
27
30
|
this.next = null
|
|
28
31
|
this.data = data
|
|
29
32
|
this.next = next
|
|
@@ -37,8 +40,8 @@ class Linker {
|
|
|
37
40
|
*/
|
|
38
41
|
exports.Linker = Linker
|
|
39
42
|
Linker.make = (linker, classType = Linker) => {
|
|
40
|
-
if (typeof linker !== 'object') {
|
|
41
|
-
// It is not an object, so instantiate the Linker with element as the data
|
|
43
|
+
if (linker === null || typeof linker !== 'object') {
|
|
44
|
+
// It is not an object (or it is null), so instantiate the Linker with element as the data
|
|
42
45
|
return new classType({
|
|
43
46
|
data: linker
|
|
44
47
|
})
|
|
@@ -47,7 +50,8 @@ Linker.make = (linker, classType = Linker) => {
|
|
|
47
50
|
// Already valid Linker, return as-is
|
|
48
51
|
return linker
|
|
49
52
|
}
|
|
50
|
-
if (!linker
|
|
53
|
+
if (!('data' in linker)) {
|
|
54
|
+
// Not the settings for a linker (which would have data, even if it is falsy), so it is the data itself
|
|
51
55
|
linker = {
|
|
52
56
|
data: linker
|
|
53
57
|
}
|
|
@@ -61,7 +65,7 @@ Linker.make = (linker, classType = Linker) => {
|
|
|
61
65
|
* @param {IsLinker} [classType=Linker] Provide the type of IsLinker to use.
|
|
62
66
|
* @returns {{head: Linker, tail: Linker}}
|
|
63
67
|
*/
|
|
64
|
-
Linker.fromArray = (values, classType = Linker) => values.reduce((references, linker) => {
|
|
68
|
+
Linker.fromArray = (values = [], classType = Linker) => values.reduce((references, linker) => {
|
|
65
69
|
const newLinker = classType.make(linker, classType)
|
|
66
70
|
if (references.head === null) {
|
|
67
71
|
// Initialize the head and tail with the new node
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.Linker=void 0,require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.reduce.js");var _ArrayElement=require("../arrayable/ArrayElement");class Linker{constructor({data:e=null,next:r=null}={}){this.classType=Linker,this.data=null,this.next=null,this.data=e,this.next=r}}exports.Linker=Linker,Linker.make=(e,r=Linker)=>"object"!=typeof e?new r({data:e}):e.classType?e:(e
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.Linker=void 0,require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.reduce.js");var _ArrayElement=require("../arrayable/ArrayElement");class Linker{constructor({data:e=null,next:r=null}={}){this.classType=Linker,this.data=null,this.next=null,this.data=e,this.next=r}}exports.Linker=Linker,Linker.make=(e,r=Linker)=>null===e||"object"!=typeof e?new r({data:e}):e.classType?e:("data"in e||(e={data:e}),_ArrayElement.ArrayElement.make(e,r)),Linker.fromArray=(e=[],r=Linker)=>e.reduce(((e,t)=>{const a=r.make(t,r);return null===e.head?{head:a,tail:a}:(e.tail.next=a,e.tail=a,e)}),{head:null,tail:null});
|
|
@@ -13,12 +13,21 @@ import { IsTreeNode } from '../../recipes/IsTreeNode';
|
|
|
13
13
|
* @extends DoublyLinkedList
|
|
14
14
|
*/
|
|
15
15
|
export declare class LinkedTreeList implements IsTree, Iterable<TreeLinker> {
|
|
16
|
+
/** The class used to create this instance, so that it can be recognized as valid without an instanceof check. */
|
|
16
17
|
readonly classType: typeof LinkedTreeList;
|
|
18
|
+
/** A linker of the list (null when the list is empty); the head is found by walking back from it. */
|
|
17
19
|
innerList: IsTreeNode | any;
|
|
20
|
+
/** Whether the inner list has been initialized (it can only be initialized once). */
|
|
18
21
|
initialized: boolean;
|
|
22
|
+
/** The class used to wrap the data given to this list as tree linkers. */
|
|
19
23
|
linkerClass: typeof TreeLinker;
|
|
24
|
+
/** The last linker, remembered so that adding to the end does not need to walk the whole list (null when not known yet). */
|
|
25
|
+
private tailCache;
|
|
26
|
+
/** The number of linkers, kept up to date by the list's own methods so that the length does not need to walk the whole list (null when not known yet). */
|
|
27
|
+
private countCache;
|
|
20
28
|
/**
|
|
21
29
|
* Create the new LinkedTreeList instance, configure the list class.
|
|
30
|
+
* @param {TreeLinker} [linkerClass=TreeLinker] The class used to wrap given data as tree linkers.
|
|
22
31
|
*/
|
|
23
32
|
constructor(linkerClass?: typeof TreeLinker);
|
|
24
33
|
/**
|
|
@@ -28,7 +37,7 @@ export declare class LinkedTreeList implements IsTree, Iterable<TreeLinker> {
|
|
|
28
37
|
*/
|
|
29
38
|
initialize(initialList: TreeLinker): LinkedTreeList;
|
|
30
39
|
/**
|
|
31
|
-
* Retrieve
|
|
40
|
+
* Retrieve the innerList used (the list itself, not a copy).
|
|
32
41
|
* @returns {TreeLinker}
|
|
33
42
|
*/
|
|
34
43
|
get list(): TreeLinker;
|
|
@@ -38,12 +47,13 @@ export declare class LinkedTreeList implements IsTree, Iterable<TreeLinker> {
|
|
|
38
47
|
*/
|
|
39
48
|
get first(): TreeLinker;
|
|
40
49
|
/**
|
|
41
|
-
* Retrieve the last TreeLinker in the list.
|
|
50
|
+
* Retrieve the last TreeLinker in the list. The end is remembered, so this does not walk the list.
|
|
42
51
|
* @returns {TreeLinker}
|
|
43
52
|
*/
|
|
44
53
|
get last(): TreeLinker;
|
|
45
54
|
/**
|
|
46
|
-
* Return the length of the list.
|
|
55
|
+
* Return the length of the list. It is kept up to date by the list's own methods, so this does not walk the list
|
|
56
|
+
* (call reset() after linkers were changed directly).
|
|
47
57
|
* @returns {number}
|
|
48
58
|
*/
|
|
49
59
|
get length(): number;
|
|
@@ -103,7 +113,8 @@ export declare class LinkedTreeList implements IsTree, Iterable<TreeLinker> {
|
|
|
103
113
|
*/
|
|
104
114
|
remove(node: TreeLinker): TreeLinker;
|
|
105
115
|
/**
|
|
106
|
-
* Refresh all references and return head
|
|
116
|
+
* Refresh all references (the head, the end and the length) by walking the list once, and return the head. The
|
|
117
|
+
* list's own methods keep these up to date, so this is only needed after linkers were changed directly.
|
|
107
118
|
* @return {TreeLinker}
|
|
108
119
|
*/
|
|
109
120
|
reset(): TreeLinker;
|
|
@@ -117,6 +128,7 @@ export declare class LinkedTreeList implements IsTree, Iterable<TreeLinker> {
|
|
|
117
128
|
* Be able to run forEach on this LinkedTreeList to iterate over the TreeLinker Items.
|
|
118
129
|
* @param {forEachCallback} callback The function to call for-each tree node
|
|
119
130
|
* @param {LinkedTreeList} thisArg Optional, 'this' reference
|
|
131
|
+
* @return {LinkedTreeList} The list which was iterated.
|
|
120
132
|
*/
|
|
121
133
|
forEach(callback: forEachCallback, thisArg?: LinkedTreeList): LinkedTreeList;
|
|
122
134
|
/**
|
|
@@ -14,6 +14,13 @@ var _DoublyLinkedList = require('../doubly-linked-list/DoublyLinkedList')
|
|
|
14
14
|
* @memberOf module:collect-your-stuff
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
+
/**
|
|
18
|
+
* Use one of the accessors of DoublyLinkedList (which keeps track of the head, tail and length) for a LinkedTreeList.
|
|
19
|
+
* @param {string} name The accessor to use
|
|
20
|
+
* @param {LinkedTreeList} list The list to use it on
|
|
21
|
+
* @returns {*}
|
|
22
|
+
*/
|
|
23
|
+
const borrowedGetter = (name, list) => Object.getOwnPropertyDescriptor(_DoublyLinkedList.DoublyLinkedList.prototype, name).get.call(list)
|
|
17
24
|
/**
|
|
18
25
|
* LinkedTreeList represents a collection stored with a root and spreading in branching (tree) formation.
|
|
19
26
|
* @extends DoublyLinkedList
|
|
@@ -21,11 +28,19 @@ var _DoublyLinkedList = require('../doubly-linked-list/DoublyLinkedList')
|
|
|
21
28
|
class LinkedTreeList {
|
|
22
29
|
/**
|
|
23
30
|
* Create the new LinkedTreeList instance, configure the list class.
|
|
31
|
+
* @param {TreeLinker} [linkerClass=TreeLinker] The class used to wrap given data as tree linkers.
|
|
24
32
|
*/
|
|
25
33
|
constructor (linkerClass = _TreeLinker.TreeLinker) {
|
|
34
|
+
/** The class used to create this instance, so that it can be recognized as valid without an instanceof check. */
|
|
26
35
|
this.classType = LinkedTreeList
|
|
36
|
+
/** A linker of the list (null when the list is empty); the head is found by walking back from it. */
|
|
27
37
|
this.innerList = null
|
|
38
|
+
/** Whether the inner list has been initialized (it can only be initialized once). */
|
|
28
39
|
this.initialized = false
|
|
40
|
+
/** The last linker, remembered so that adding to the end does not need to walk the whole list (null when not known yet). */
|
|
41
|
+
this.tailCache = null
|
|
42
|
+
/** The number of linkers, kept up to date by the list's own methods so that the length does not need to walk the whole list (null when not known yet). */
|
|
43
|
+
this.countCache = null
|
|
29
44
|
this.linkerClass = linkerClass
|
|
30
45
|
}
|
|
31
46
|
|
|
@@ -45,7 +60,7 @@ class LinkedTreeList {
|
|
|
45
60
|
}
|
|
46
61
|
|
|
47
62
|
/**
|
|
48
|
-
* Retrieve
|
|
63
|
+
* Retrieve the innerList used (the list itself, not a copy).
|
|
49
64
|
* @returns {TreeLinker}
|
|
50
65
|
*/
|
|
51
66
|
get list () {
|
|
@@ -57,38 +72,24 @@ class LinkedTreeList {
|
|
|
57
72
|
* @returns {TreeLinker}
|
|
58
73
|
*/
|
|
59
74
|
get first () {
|
|
60
|
-
return this
|
|
75
|
+
return borrowedGetter('first', this)
|
|
61
76
|
}
|
|
62
77
|
|
|
63
78
|
/**
|
|
64
|
-
* Retrieve the last TreeLinker in the list.
|
|
79
|
+
* Retrieve the last TreeLinker in the list. The end is remembered, so this does not walk the list.
|
|
65
80
|
* @returns {TreeLinker}
|
|
66
81
|
*/
|
|
67
82
|
get last () {
|
|
68
|
-
|
|
69
|
-
if (tail === null) {
|
|
70
|
-
return null
|
|
71
|
-
}
|
|
72
|
-
let next = tail.next
|
|
73
|
-
while (next !== null) {
|
|
74
|
-
tail = next
|
|
75
|
-
next = tail.next
|
|
76
|
-
}
|
|
77
|
-
return tail
|
|
83
|
+
return borrowedGetter('last', this)
|
|
78
84
|
}
|
|
79
85
|
|
|
80
86
|
/**
|
|
81
|
-
* Return the length of the list.
|
|
87
|
+
* Return the length of the list. It is kept up to date by the list's own methods, so this does not walk the list
|
|
88
|
+
* (call reset() after linkers were changed directly).
|
|
82
89
|
* @returns {number}
|
|
83
90
|
*/
|
|
84
91
|
get length () {
|
|
85
|
-
|
|
86
|
-
let length = 0
|
|
87
|
-
while (current !== null) {
|
|
88
|
-
++length
|
|
89
|
-
current = current.next
|
|
90
|
-
}
|
|
91
|
-
return length
|
|
92
|
+
return borrowedGetter('length', this)
|
|
92
93
|
}
|
|
93
94
|
|
|
94
95
|
/**
|
|
@@ -197,7 +198,8 @@ class LinkedTreeList {
|
|
|
197
198
|
}
|
|
198
199
|
|
|
199
200
|
/**
|
|
200
|
-
* Refresh all references and return head
|
|
201
|
+
* Refresh all references (the head, the end and the length) by walking the list once, and return the head. The
|
|
202
|
+
* list's own methods keep these up to date, so this is only needed after linkers were changed directly.
|
|
201
203
|
* @return {TreeLinker}
|
|
202
204
|
*/
|
|
203
205
|
reset () {
|
|
@@ -217,6 +219,7 @@ class LinkedTreeList {
|
|
|
217
219
|
* Be able to run forEach on this LinkedTreeList to iterate over the TreeLinker Items.
|
|
218
220
|
* @param {forEachCallback} callback The function to call for-each tree node
|
|
219
221
|
* @param {LinkedTreeList} thisArg Optional, 'this' reference
|
|
222
|
+
* @return {LinkedTreeList} The list which was iterated.
|
|
220
223
|
*/
|
|
221
224
|
forEach (callback, thisArg = this) {
|
|
222
225
|
let index = 0
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.LinkedTreeList=void 0;var _TreeLinker=require("./TreeLinker"),_TreeLinkerIterator=require("../../recipes/TreeLinkerIterator"),_DoublyLinkedList=require("../doubly-linked-list/DoublyLinkedList");class LinkedTreeList{constructor(e=_TreeLinker.TreeLinker){this.classType=LinkedTreeList,this.innerList=null,this.initialized=!1,this.linkerClass=e}initialize(e){return this.initialized?(console.warn("Attempt to initialize LinkedTreeList which is not empty."),this):(this.initialized=!0,this.innerList=e,this)}get list(){return this.innerList}get first(){return this
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.LinkedTreeList=void 0;var _TreeLinker=require("./TreeLinker"),_TreeLinkerIterator=require("../../recipes/TreeLinkerIterator"),_DoublyLinkedList=require("../doubly-linked-list/DoublyLinkedList");const borrowedGetter=(e,t)=>Object.getOwnPropertyDescriptor(_DoublyLinkedList.DoublyLinkedList.prototype,e).get.call(t);class LinkedTreeList{constructor(e=_TreeLinker.TreeLinker){this.classType=LinkedTreeList,this.innerList=null,this.initialized=!1,this.tailCache=null,this.countCache=null,this.linkerClass=e}initialize(e){return this.initialized?(console.warn("Attempt to initialize LinkedTreeList which is not empty."),this):(this.initialized=!0,this.innerList=e,this)}get list(){return this.innerList}get first(){return borrowedGetter("first",this)}get last(){return borrowedGetter("last",this)}get length(){return borrowedGetter("length",this)}get parent(){return null===this.first?null:this.first.parent}set parent(e){let t=this.first;for(;null!==t;)t.parent=e,t=t.next;e&&(e.children=this)}get rootParent(){let e=this.first;if(!e)return null;let t=this.first.parent;for(;null!==t;)e=t,t=e.parent;return e}setChildren(e,t=null){Array.from(this).indexOf(e)<0&&console.error("item is not a child of this"),t.parent=e}insertAfter(e,t){return _DoublyLinkedList.DoublyLinkedList.prototype.insertAfter.call(this,e,t)}insertBefore(e,t){return _DoublyLinkedList.DoublyLinkedList.prototype.insertBefore.call(this,e,t)}append(e,t=this.last){return _DoublyLinkedList.DoublyLinkedList.prototype.append.call(this,e,t)}prepend(e,t=this.first){return _DoublyLinkedList.DoublyLinkedList.prototype.prepend.call(this,e,t)}remove(e){return _DoublyLinkedList.DoublyLinkedList.prototype.remove.call(this,e)}reset(){return _DoublyLinkedList.DoublyLinkedList.prototype.reset.call(this)}item(e){return _DoublyLinkedList.DoublyLinkedList.prototype.item.call(this,e)}forEach(e,t=this){let r=0,i=t.first;for(;null!==i;)e(i,r,t),i=i.next,++r;return t}[Symbol.iterator](){let e=this.rootParent;return new _TreeLinkerIterator.TreeLinkerIterator(e)}}exports.LinkedTreeList=LinkedTreeList,LinkedTreeList.fromArray=(e=[],t=_TreeLinker.TreeLinker,r=LinkedTreeList)=>new r(t).initialize(t.fromArray(e).head);
|
|
@@ -12,15 +12,21 @@ import { IsTree } from '../../recipes/IsTree';
|
|
|
12
12
|
* @extends DoubleLinker
|
|
13
13
|
*/
|
|
14
14
|
export declare class TreeLinker implements IsTreeNode {
|
|
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 TreeLinker;
|
|
17
|
+
/** The data stored in this tree node. */
|
|
16
18
|
data: any;
|
|
19
|
+
/** The sibling after this node, or null when this is the last child. */
|
|
17
20
|
next: IsTreeNode | null;
|
|
21
|
+
/** The sibling before this node, or null when this is the first child. */
|
|
18
22
|
prev: IsTreeNode | null;
|
|
23
|
+
/** The node this node is a child of, or null for a root node. */
|
|
19
24
|
parent: IsTreeNode;
|
|
25
|
+
/** The list of the children of this node, or null when it has none. */
|
|
20
26
|
children: IsArrayable<IsTreeNode>;
|
|
21
27
|
/**
|
|
22
28
|
* Create the new TreeLinker instance, provide the data and optionally set references for next, prev, parent, or children.
|
|
23
|
-
* @param {Object} [settings={}]
|
|
29
|
+
* @param {Object} [settings={}] The settings for the new tree node.
|
|
24
30
|
* @param {*} [settings.data=null] The data to be stored in this tree node
|
|
25
31
|
* @param {TreeLinker} [settings.next=null] The reference to the next linker if any
|
|
26
32
|
* @param {TreeLinker} [settings.prev=null] The reference to the previous linker if any
|
|
@@ -15,7 +15,7 @@ var _LinkedTreeList = require('./LinkedTreeList')
|
|
|
15
15
|
class TreeLinker {
|
|
16
16
|
/**
|
|
17
17
|
* Create the new TreeLinker instance, provide the data and optionally set references for next, prev, parent, or children.
|
|
18
|
-
* @param {Object} [settings={}]
|
|
18
|
+
* @param {Object} [settings={}] The settings for the new tree node.
|
|
19
19
|
* @param {*} [settings.data=null] The data to be stored in this tree node
|
|
20
20
|
* @param {TreeLinker} [settings.next=null] The reference to the next linker if any
|
|
21
21
|
* @param {TreeLinker} [settings.prev=null] The reference to the previous linker if any
|
|
@@ -31,11 +31,17 @@ class TreeLinker {
|
|
|
31
31
|
parent = null,
|
|
32
32
|
listClass = _LinkedTreeList.LinkedTreeList
|
|
33
33
|
} = {}) {
|
|
34
|
+
/** The class used to create this instance, so that it can be recognized as valid without an instanceof check. */
|
|
34
35
|
this.classType = TreeLinker
|
|
36
|
+
/** The data stored in this tree node. */
|
|
35
37
|
this.data = null
|
|
38
|
+
/** The sibling after this node, or null when this is the last child. */
|
|
36
39
|
this.next = null
|
|
40
|
+
/** The sibling before this node, or null when this is the first child. */
|
|
37
41
|
this.prev = null
|
|
42
|
+
/** The node this node is a child of, or null for a root node. */
|
|
38
43
|
this.parent = null
|
|
44
|
+
/** The list of the children of this node, or null when it has none. */
|
|
39
45
|
this.children = null
|
|
40
46
|
this.data = data
|
|
41
47
|
this.next = next
|
|
@@ -12,18 +12,21 @@ import { completeResponse } from '../../recipes/Runnable';
|
|
|
12
12
|
* Maintain a series of queued items.
|
|
13
13
|
*/
|
|
14
14
|
export declare class Queue {
|
|
15
|
+
/** The list which stores the queueables, the first is next to be dequeued. */
|
|
15
16
|
queuedList: IsArrayable<any>;
|
|
16
17
|
private listClass;
|
|
17
18
|
private queueableClass;
|
|
18
19
|
/**
|
|
19
20
|
* Instantiate the queue with the given queue list.
|
|
20
21
|
* @param {Iterable|LinkedList} queuedList Give the list of queueables to start in this queue.
|
|
21
|
-
* @param {IsArrayable} listClass
|
|
22
|
-
* @param {Queueable} queueableClass
|
|
22
|
+
* @param {IsArrayable} [listClass=LinkedList] The type of list to create when no queued list is given.
|
|
23
|
+
* @param {Queueable} [queueableClass=Queueable] The class used to wrap queued items.
|
|
23
24
|
*/
|
|
24
25
|
constructor(queuedList?: IsArrayable<any>, listClass?: any, queueableClass?: typeof Queueable);
|
|
25
26
|
/**
|
|
26
|
-
* Take a queued task from the front of the queue and run it if ready.
|
|
27
|
+
* Take a queued task from the front of the queue and run it if ready. A task which is not ready yet is kept in the
|
|
28
|
+
* queue (never dropped), a task which is still running is reported as blocking and left to finish on its own, and
|
|
29
|
+
* completed tasks are discarded.
|
|
27
30
|
* @return {completeResponse|*}
|
|
28
31
|
*/
|
|
29
32
|
dequeue(): completeResponse | any;
|
|
@@ -20,8 +20,8 @@ class Queue {
|
|
|
20
20
|
/**
|
|
21
21
|
* Instantiate the queue with the given queue list.
|
|
22
22
|
* @param {Iterable|LinkedList} queuedList Give the list of queueables to start in this queue.
|
|
23
|
-
* @param {IsArrayable} listClass
|
|
24
|
-
* @param {Queueable} queueableClass
|
|
23
|
+
* @param {IsArrayable} [listClass=LinkedList] The type of list to create when no queued list is given.
|
|
24
|
+
* @param {Queueable} [queueableClass=Queueable] The class used to wrap queued items.
|
|
25
25
|
*/
|
|
26
26
|
constructor (queuedList = null, listClass = _LinkedList.LinkedList, queueableClass = _Queueable.Queueable) {
|
|
27
27
|
this.listClass = listClass
|
|
@@ -33,11 +33,17 @@ class Queue {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
/**
|
|
36
|
-
* Take a queued task from the front of the queue and run it if ready.
|
|
36
|
+
* Take a queued task from the front of the queue and run it if ready. A task which is not ready yet is kept in the
|
|
37
|
+
* queue (never dropped), a task which is still running is reported as blocking and left to finish on its own, and
|
|
38
|
+
* completed tasks are discarded.
|
|
37
39
|
* @return {completeResponse|*}
|
|
38
40
|
*/
|
|
39
41
|
dequeue () {
|
|
40
|
-
|
|
42
|
+
let next = this.remove()
|
|
43
|
+
// Tasks which already completed are discarded when they reach the front of the queue
|
|
44
|
+
while (next && next.complete) {
|
|
45
|
+
next = this.remove()
|
|
46
|
+
}
|
|
41
47
|
if (!next) {
|
|
42
48
|
return {
|
|
43
49
|
success: 'No more queueable tasks in the queue',
|
|
@@ -45,31 +51,30 @@ class Queue {
|
|
|
45
51
|
context: this.queuedList
|
|
46
52
|
}
|
|
47
53
|
}
|
|
48
|
-
if (next.complete) {
|
|
49
|
-
// Previously ran queued, run next
|
|
50
|
-
return this.dequeue()
|
|
51
|
-
}
|
|
52
54
|
if (next.running) {
|
|
55
|
+
// The unfinished task reports back through its own complete callback, so it is not kept in the queue
|
|
53
56
|
return {
|
|
54
57
|
success: false,
|
|
55
58
|
error: 'The queue has been blocked by an unfinished task.',
|
|
56
59
|
context: next
|
|
57
60
|
}
|
|
58
61
|
}
|
|
62
|
+
if (!next.isReady) {
|
|
63
|
+
// Keep the task (at the back, so the next dequeue can try the other tasks) rather than losing it
|
|
64
|
+
this.enqueue(next)
|
|
65
|
+
// We could go check the next in queue here but if we end up in a state where nothing is ready it would infinite loop
|
|
66
|
+
// Also, we want the loop handled externally
|
|
67
|
+
return {
|
|
68
|
+
success: false,
|
|
69
|
+
error: 'Unable to find ready task.',
|
|
70
|
+
context: next
|
|
71
|
+
}
|
|
72
|
+
}
|
|
59
73
|
if (!this.empty()) {
|
|
60
74
|
// Place back in queue to be checked once again next time, only if the queue will not be empty
|
|
61
75
|
this.enqueue(next)
|
|
62
76
|
}
|
|
63
|
-
|
|
64
|
-
return next.run.call(next)
|
|
65
|
-
}
|
|
66
|
-
// We could go check the next in queue here but if we end up in a state where nothing is ready it would infinite loop
|
|
67
|
-
// Also, we want the loop handled externally
|
|
68
|
-
return {
|
|
69
|
-
success: false,
|
|
70
|
-
error: 'Unable to find ready task.',
|
|
71
|
-
context: next
|
|
72
|
-
}
|
|
77
|
+
return next.run.call(next)
|
|
73
78
|
}
|
|
74
79
|
|
|
75
80
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.Queue=void 0;var _Queueable=require("./Queueable"),_LinkedList=require("../linked-list/LinkedList");class Queue{constructor(e=null,u=_LinkedList.LinkedList,t=_Queueable.Queueable){this.listClass=u,this.queueableClass=t,null===e&&(e=new u(t)),this.queuedList=e}dequeue(){
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.Queue=void 0;var _Queueable=require("./Queueable"),_LinkedList=require("../linked-list/LinkedList");class Queue{constructor(e=null,u=_LinkedList.LinkedList,t=_Queueable.Queueable){this.listClass=u,this.queueableClass=t,null===e&&(e=new u(t)),this.queuedList=e}dequeue(){let e=this.remove();for(;e&&e.complete;)e=this.remove();return e?e.running?{success:!1,error:"The queue has been blocked by an unfinished task.",context:e}:e.isReady?(this.empty()||this.enqueue(e),e.run.call(e)):(this.enqueue(e),{success:!1,error:"Unable to find ready task.",context:e}):{success:"No more queueable tasks in the queue",error:!1,context:this.queuedList}}empty(){return this.size()<=0}enqueue(e){this.queuedList.append(e)}peek(){return this.queuedList.first}remove(){return this.empty()?null:this.queuedList.remove(this.queuedList.first)}size(){return this.queuedList.length}}exports.Queue=Queue,Queue.fromArray=(e=[],u=_Queueable.Queueable,t=_LinkedList.LinkedList)=>{const s=new t(u);return s.initialize(u.fromArray(e,u).head),new Queue(s,t,u)};
|
|
@@ -11,15 +11,21 @@ import { IsLinker } from '../../recipes/IsLinker';
|
|
|
11
11
|
* @extends Linker
|
|
12
12
|
*/
|
|
13
13
|
export declare class Queueable implements IsLinker, IsRunnable {
|
|
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 Queueable;
|
|
16
|
+
/** The task (or data) this queueable holds. */
|
|
15
17
|
data: any;
|
|
18
|
+
/** The queueable after this one, or null when this is the last. */
|
|
16
19
|
next: Queueable | null;
|
|
20
|
+
/** Whether this queueable has been run to completion. */
|
|
17
21
|
complete: boolean;
|
|
22
|
+
/** Whether this queueable may run, or a function which answers that when asked. */
|
|
18
23
|
ready: Function | boolean;
|
|
24
|
+
/** Whether this queueable is running right now. */
|
|
19
25
|
running: boolean;
|
|
20
26
|
/**
|
|
21
27
|
* Create a queueable item that can be used in a queue.
|
|
22
|
-
* @param {Object} [queueableData={}]
|
|
28
|
+
* @param {Object} [queueableData={}] The settings for the new queueable.
|
|
23
29
|
* @param {*} [queueableData.task=null] The data to be stored in this queueable
|
|
24
30
|
* @param {Queueable|null} [queueableData.next=null] The reference to the next queueable if any
|
|
25
31
|
* @param {boolean|Function} [queueableData.ready=false] Indicate if the queueable is ready to run
|
|
@@ -27,7 +33,7 @@ export declare class Queueable implements IsLinker, IsRunnable {
|
|
|
27
33
|
constructor({ task, next, ready }?: {
|
|
28
34
|
task?: any;
|
|
29
35
|
next?: Queueable | null;
|
|
30
|
-
ready?: boolean;
|
|
36
|
+
ready?: boolean | Function;
|
|
31
37
|
});
|
|
32
38
|
/**
|
|
33
39
|
* Check ready state.
|
|
@@ -41,7 +47,7 @@ export declare class Queueable implements IsLinker, IsRunnable {
|
|
|
41
47
|
get task(): any;
|
|
42
48
|
/**
|
|
43
49
|
* Set this queueable as completed.
|
|
44
|
-
* @param {Object} completeResponse
|
|
50
|
+
* @param {Object} [completeResponse={}] The result to report for the task.
|
|
45
51
|
* @param {*} [completeResponse.success=true] Indicate when the task failed (use false) or give a success message
|
|
46
52
|
* @param {*} [completeResponse.error=false] Indicate a task was error-free (use false) or give an error message
|
|
47
53
|
* @param {*} [completeResponse.context=null] Provide additional data in the response
|
|
@@ -70,7 +76,7 @@ export declare class Queueable implements IsLinker, IsRunnable {
|
|
|
70
76
|
* @param {IsLinker} [classType=Queueable] Provide the type of IsLinker to use.
|
|
71
77
|
* @returns {{head: Queueable, tail: Queueable}}
|
|
72
78
|
*/
|
|
73
|
-
static fromArray: (values
|
|
79
|
+
static fromArray: (values?: Array<any>, classType?: any) => {
|
|
74
80
|
head: IsLinker;
|
|
75
81
|
tail: IsLinker;
|
|
76
82
|
};
|
|
@@ -12,7 +12,7 @@ var _Linker = require('../linked-list/Linker')
|
|
|
12
12
|
class Queueable {
|
|
13
13
|
/**
|
|
14
14
|
* Create a queueable item that can be used in a queue.
|
|
15
|
-
* @param {Object} [queueableData={}]
|
|
15
|
+
* @param {Object} [queueableData={}] The settings for the new queueable.
|
|
16
16
|
* @param {*} [queueableData.task=null] The data to be stored in this queueable
|
|
17
17
|
* @param {Queueable|null} [queueableData.next=null] The reference to the next queueable if any
|
|
18
18
|
* @param {boolean|Function} [queueableData.ready=false] Indicate if the queueable is ready to run
|
|
@@ -22,10 +22,15 @@ class Queueable {
|
|
|
22
22
|
next = null,
|
|
23
23
|
ready = false
|
|
24
24
|
} = {}) {
|
|
25
|
+
/** The task (or data) this queueable holds. */
|
|
25
26
|
this.data = null
|
|
27
|
+
/** The queueable after this one, or null when this is the last. */
|
|
26
28
|
this.next = null
|
|
29
|
+
/** Whether this queueable has been run to completion. */
|
|
27
30
|
this.complete = false
|
|
31
|
+
/** Whether this queueable may run, or a function which answers that when asked. */
|
|
28
32
|
this.ready = false
|
|
33
|
+
/** Whether this queueable is running right now. */
|
|
29
34
|
this.running = false
|
|
30
35
|
this.classType = Queueable
|
|
31
36
|
this.data = task
|
|
@@ -58,7 +63,7 @@ class Queueable {
|
|
|
58
63
|
|
|
59
64
|
/**
|
|
60
65
|
* Set this queueable as completed.
|
|
61
|
-
* @param {Object} completeResponse
|
|
66
|
+
* @param {Object} [completeResponse={}] The result to report for the task.
|
|
62
67
|
* @param {*} [completeResponse.success=true] Indicate when the task failed (use false) or give a success message
|
|
63
68
|
* @param {*} [completeResponse.error=false] Indicate a task was error-free (use false) or give an error message
|
|
64
69
|
* @param {*} [completeResponse.context=null] Provide additional data in the response
|
|
@@ -112,8 +117,8 @@ class Queueable {
|
|
|
112
117
|
*/
|
|
113
118
|
exports.Queueable = Queueable
|
|
114
119
|
Queueable.make = (queueable, classType = Queueable) => {
|
|
115
|
-
if (typeof queueable !== 'object') {
|
|
116
|
-
// It is not an object, so instantiate the Queueable with an element as the data
|
|
120
|
+
if (queueable === null || typeof queueable !== 'object') {
|
|
121
|
+
// It is not an object (or it is null), so instantiate the Queueable with an element as the data
|
|
117
122
|
return new classType({
|
|
118
123
|
task: queueable,
|
|
119
124
|
ready: true
|
|
@@ -123,7 +128,7 @@ Queueable.make = (queueable, classType = Queueable) => {
|
|
|
123
128
|
// Already valid Queueable, return as-is
|
|
124
129
|
return queueable
|
|
125
130
|
}
|
|
126
|
-
if (!queueable
|
|
131
|
+
if (!('task' in queueable)) {
|
|
127
132
|
queueable = {
|
|
128
133
|
task: queueable,
|
|
129
134
|
ready: true
|
|
@@ -138,4 +143,4 @@ Queueable.make = (queueable, classType = Queueable) => {
|
|
|
138
143
|
* @param {IsLinker} [classType=Queueable] Provide the type of IsLinker to use.
|
|
139
144
|
* @returns {{head: Queueable, tail: Queueable}}
|
|
140
145
|
*/
|
|
141
|
-
Queueable.fromArray = (values, classType = Queueable) => _Linker.Linker.fromArray(values, classType)
|
|
146
|
+
Queueable.fromArray = (values = [], classType = Queueable) => _Linker.Linker.fromArray(values, classType)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.Queueable=void 0;var _Linker=require("../linked-list/Linker");class Queueable{constructor({task:e=null,next:t=null,ready:s=!1}={}){this.data=null,this.next=null,this.complete=!1,this.ready=!1,this.running=!1,this.classType=Queueable,this.data=e,this.next=t,this.complete=!1,this.ready=s,this.running=!1}get isReady(){return"function"==typeof this.ready?this.ready():this.ready}get task(){return"function"==typeof this.data?this.data:e=>"function"==typeof e?e({context:this.data}).context:this.data}markCompleted({success:e=!0,error:t=!1,context:s=null}={}){return this.complete=!0,this.running=!1,{success:e,error:t,context:s}}run(){return this.isReady?this.running?{success:!1,error:"Queued task is already running, possible missing 'complete' callback",context:this.data}:(this.running=!0,this.task(this.markCompleted.bind(this))):{success:!1,error:"Task is not ready",context:this.data}}}exports.Queueable=Queueable,Queueable.make=(e,t=Queueable)=>"object"!=typeof e?new t({task:e,ready:!0}):e.classType?e:(e
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.Queueable=void 0;var _Linker=require("../linked-list/Linker");class Queueable{constructor({task:e=null,next:t=null,ready:s=!1}={}){this.data=null,this.next=null,this.complete=!1,this.ready=!1,this.running=!1,this.classType=Queueable,this.data=e,this.next=t,this.complete=!1,this.ready=s,this.running=!1}get isReady(){return"function"==typeof this.ready?this.ready():this.ready}get task(){return"function"==typeof this.data?this.data:e=>"function"==typeof e?e({context:this.data}).context:this.data}markCompleted({success:e=!0,error:t=!1,context:s=null}={}){return this.complete=!0,this.running=!1,{success:e,error:t,context:s}}run(){return this.isReady?this.running?{success:!1,error:"Queued task is already running, possible missing 'complete' callback",context:this.data}:(this.running=!0,this.task(this.markCompleted.bind(this))):{success:!1,error:"Task is not ready",context:this.data}}}exports.Queueable=Queueable,Queueable.make=(e,t=Queueable)=>null===e||"object"!=typeof e?new t({task:e,ready:!0}):e.classType?e:("task"in e||(e={task:e,ready:!0}),new t(e)),Queueable.fromArray=(e=[],t=Queueable)=>_Linker.Linker.fromArray(e,t);
|
|
@@ -12,14 +12,15 @@ import { completeResponse } from '../../recipes/Runnable';
|
|
|
12
12
|
* Store a collection of items which can only be inserted and removed from the top.
|
|
13
13
|
*/
|
|
14
14
|
export declare class Stack {
|
|
15
|
+
/** The list which stores the stackables, the first is the top of the stack. */
|
|
15
16
|
stackedList: IsArrayable<any>;
|
|
16
17
|
private listClass;
|
|
17
18
|
private stackableClass;
|
|
18
19
|
/**
|
|
19
20
|
* Instantiate the state with the starter stacked list.
|
|
20
|
-
* @param {Iterable|LinkedList} stackedList
|
|
21
|
-
* @param {IsArrayable} listClass
|
|
22
|
-
* @param {Stackable} stackableClass
|
|
21
|
+
* @param {Iterable|LinkedList} [stackedList=null] The list of stackables to start in this stack.
|
|
22
|
+
* @param {IsArrayable} [listClass=LinkedList] The type of list to create when no stacked list is given.
|
|
23
|
+
* @param {Stackable} [stackableClass=Stackable] The class used to wrap stacked items.
|
|
23
24
|
*/
|
|
24
25
|
constructor(stackedList?: IsArrayable<any>, listClass?: any, stackableClass?: typeof Stackable);
|
|
25
26
|
/**
|
|
@@ -19,9 +19,9 @@ var _LinkedList = require('../linked-list/LinkedList')
|
|
|
19
19
|
class Stack {
|
|
20
20
|
/**
|
|
21
21
|
* Instantiate the state with the starter stacked list.
|
|
22
|
-
* @param {Iterable|LinkedList} stackedList
|
|
23
|
-
* @param {IsArrayable} listClass
|
|
24
|
-
* @param {Stackable} stackableClass
|
|
22
|
+
* @param {Iterable|LinkedList} [stackedList=null] The list of stackables to start in this stack.
|
|
23
|
+
* @param {IsArrayable} [listClass=LinkedList] The type of list to create when no stacked list is given.
|
|
24
|
+
* @param {Stackable} [stackableClass=Stackable] The class used to wrap stacked items.
|
|
25
25
|
*/
|
|
26
26
|
constructor (stackedList = null, listClass = _LinkedList.LinkedList, stackableClass = _Stackable.Stackable) {
|
|
27
27
|
this.listClass = listClass
|
|
@@ -102,5 +102,5 @@ exports.Stack = Stack
|
|
|
102
102
|
Stack.fromArray = (values = [], stackableClass = _Stackable.Stackable, listClass = _LinkedList.LinkedList) => {
|
|
103
103
|
const list = new listClass(stackableClass)
|
|
104
104
|
list.initialize(stackableClass.fromArray(values, stackableClass).head)
|
|
105
|
-
return new Stack(list)
|
|
105
|
+
return new Stack(list, listClass, stackableClass)
|
|
106
106
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.Stack=void 0;var _Stackable=require("./Stackable"),_LinkedList=require("../linked-list/LinkedList");class Stack{constructor(t=null,e=_LinkedList.LinkedList,s=_Stackable.Stackable){this.listClass=e,this.stackableClass=s,null===t&&(t=new e(s)),this.stackedList=t}empty(){return this.size()<=0}top(){return this.stackedList.first}pop(){const t=this.remove();return t?t.run():{success:"No more stackable tasks in the stack",error:!1,context:this.stackedList}}push(t){this.stackedList.prepend(t)}remove(){return this.empty()?null:this.stackedList.remove(this.stackedList.first)}size(){return this.stackedList.length}}exports.Stack=Stack,Stack.fromArray=(t=[],e=_Stackable.Stackable,s=_LinkedList.LinkedList)=>{const i=new s(e);return i.initialize(e.fromArray(t,e).head),new Stack(i)};
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.Stack=void 0;var _Stackable=require("./Stackable"),_LinkedList=require("../linked-list/LinkedList");class Stack{constructor(t=null,e=_LinkedList.LinkedList,s=_Stackable.Stackable){this.listClass=e,this.stackableClass=s,null===t&&(t=new e(s)),this.stackedList=t}empty(){return this.size()<=0}top(){return this.stackedList.first}pop(){const t=this.remove();return t?t.run():{success:"No more stackable tasks in the stack",error:!1,context:this.stackedList}}push(t){this.stackedList.prepend(t)}remove(){return this.empty()?null:this.stackedList.remove(this.stackedList.first)}size(){return this.stackedList.length}}exports.Stack=Stack,Stack.fromArray=(t=[],e=_Stackable.Stackable,s=_LinkedList.LinkedList)=>{const i=new s(e);return i.initialize(e.fromArray(t,e).head),new Stack(i,s,e)};
|
|
@@ -11,12 +11,15 @@ import { IsLinker } from '../../recipes/IsLinker';
|
|
|
11
11
|
* @extends Linker
|
|
12
12
|
*/
|
|
13
13
|
export declare class Stackable implements IsLinker, IsRunnable {
|
|
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 Stackable;
|
|
16
|
+
/** The task (or data) this stackable holds. */
|
|
15
17
|
data: any;
|
|
18
|
+
/** The stackable below this one, or null when this is the bottom. */
|
|
16
19
|
next: Stackable | null;
|
|
17
20
|
/**
|
|
18
21
|
* Create a stackable item that can be used in a stack.
|
|
19
|
-
* @param {Object} [stackData={}]
|
|
22
|
+
* @param {Object} [stackData={}] The settings for the new stackable.
|
|
20
23
|
* @param {*} [stackData.task=null] The data to be stored in this stackable
|
|
21
24
|
* @param {Stackable|null} [stackData.next=null] The reference to the next stackable if any
|
|
22
25
|
* @param {boolean|Function} [stackData.ready=false] Indicate if the stackable is ready to run
|
|
@@ -12,7 +12,7 @@ var _Linker = require('../linked-list/Linker')
|
|
|
12
12
|
class Stackable {
|
|
13
13
|
/**
|
|
14
14
|
* Create a stackable item that can be used in a stack.
|
|
15
|
-
* @param {Object} [stackData={}]
|
|
15
|
+
* @param {Object} [stackData={}] The settings for the new stackable.
|
|
16
16
|
* @param {*} [stackData.task=null] The data to be stored in this stackable
|
|
17
17
|
* @param {Stackable|null} [stackData.next=null] The reference to the next stackable if any
|
|
18
18
|
* @param {boolean|Function} [stackData.ready=false] Indicate if the stackable is ready to run
|
|
@@ -22,7 +22,9 @@ class Stackable {
|
|
|
22
22
|
next = null,
|
|
23
23
|
ready = false
|
|
24
24
|
} = {}) {
|
|
25
|
+
/** The task (or data) this stackable holds. */
|
|
25
26
|
this.data = null
|
|
27
|
+
/** The stackable below this one, or null when this is the bottom. */
|
|
26
28
|
this.next = null
|
|
27
29
|
this.classType = Stackable
|
|
28
30
|
this.data = task
|
|
@@ -56,8 +58,8 @@ class Stackable {
|
|
|
56
58
|
*/
|
|
57
59
|
exports.Stackable = Stackable
|
|
58
60
|
Stackable.make = (stackable, classType = Stackable) => {
|
|
59
|
-
if (typeof stackable !== 'object') {
|
|
60
|
-
// It is not an object, so instantiate the Stackable with stackable as the data
|
|
61
|
+
if (stackable === null || typeof stackable !== 'object') {
|
|
62
|
+
// It is not an object (or it is null), so instantiate the Stackable with stackable as the data
|
|
61
63
|
return new classType({
|
|
62
64
|
task: stackable
|
|
63
65
|
})
|
|
@@ -66,13 +68,13 @@ Stackable.make = (stackable, classType = Stackable) => {
|
|
|
66
68
|
// Already valid Stackable, return as-is
|
|
67
69
|
return stackable
|
|
68
70
|
}
|
|
69
|
-
if (!stackable
|
|
71
|
+
if (!('task' in stackable)) {
|
|
70
72
|
stackable = {
|
|
71
73
|
task: stackable
|
|
72
74
|
}
|
|
73
75
|
}
|
|
74
76
|
// Create the new node as the configured stackableClass
|
|
75
|
-
return new
|
|
77
|
+
return new classType(stackable)
|
|
76
78
|
}
|
|
77
79
|
/**
|
|
78
80
|
* Convert an array into Stackable instances, return the head and tail Stackables.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.Stackable=void 0;var _Linker=require("../linked-list/Linker");class Stackable{constructor({task:t=null,next:a=null,ready:e=!1}={}){this.data=null,this.next=null,this.classType=Stackable,this.data=t,this.next=a}get task(){return"function"==typeof this.data?this.data:()=>this.data}run(){return this.task()}}exports.Stackable=Stackable,Stackable.make=(t,a=Stackable)=>"object"!=typeof t?new a({task:t}):t.classType?t:(t
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.Stackable=void 0;var _Linker=require("../linked-list/Linker");class Stackable{constructor({task:t=null,next:a=null,ready:e=!1}={}){this.data=null,this.next=null,this.classType=Stackable,this.data=t,this.next=a}get task(){return"function"==typeof this.data?this.data:()=>this.data}run(){return this.task()}}exports.Stackable=Stackable,Stackable.make=(t,a=Stackable)=>null===t||"object"!=typeof t?new a({task:t}):t.classType?t:("task"in t||(t={task:t}),new a(t)),Stackable.fromArray=(t=[],a=Stackable)=>_Linker.Linker.fromArray(t,a);
|