mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			126 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			126 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 'use strict';
 | |
| 
 | |
| const { EventEmitter } = require('events');
 | |
| 
 | |
| class Node {
 | |
|     constructor(value) {
 | |
|         this.value = value;
 | |
|         this.next = null;
 | |
|     }
 | |
| 
 | |
|     link(next) {
 | |
|         this.next = next;
 | |
|         next.prev = this;
 | |
|         return this;
 | |
|     }
 | |
| }
 | |
| 
 | |
| module.exports = class List extends EventEmitter {
 | |
|     constructor() {
 | |
|         super();
 | |
|         this.start = null;
 | |
|         this.tail = null;
 | |
|     }
 | |
| 
 | |
|     add(obj) {
 | |
|         const node = new Node(obj);
 | |
|         if (this.start) {
 | |
|             this.start = node.link(this.start);
 | |
|         } else {
 | |
|             this.start = node;
 | |
|             this.tail = node;
 | |
|         }
 | |
|         return node;
 | |
|     }
 | |
| 
 | |
|     iterate(fn) {
 | |
|         if (!this.start) {
 | |
|             return;
 | |
|         }
 | |
|         let cursor = this.start;
 | |
|         while (cursor) {
 | |
|             const result = fn(cursor);
 | |
|             if (result === false) {
 | |
|                 cursor = null;
 | |
|             } else {
 | |
|                 cursor = cursor.next;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     iterateReverse(fn) {
 | |
|         if (!this.tail) {
 | |
|             return;
 | |
|         }
 | |
|         let cursor = this.tail;
 | |
|         while (cursor) {
 | |
|             const result = fn(cursor);
 | |
|             if (result === false) {
 | |
|                 cursor = null;
 | |
|             } else {
 | |
|                 cursor = cursor.prev;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     reverseRemoveUntilTrue(fn) {
 | |
|         if (!this.tail) {
 | |
|             return;
 | |
|         }
 | |
| 
 | |
|         let cursor = this.tail;
 | |
|         while (cursor) {
 | |
|             const result = fn(cursor);
 | |
|             if (result === false && cursor === this.start) {
 | |
|                 // whole list is removed
 | |
|                 this.emit('evicted', cursor.value);
 | |
|                 this.start = null;
 | |
|                 this.tail = null;
 | |
|                 // stop iteration
 | |
|                 cursor = null;
 | |
|             } else if (result === true) {
 | |
|                 // when TRUE, set match as new tail
 | |
|                 if (cursor !== this.tail) {
 | |
|                     this.tail = cursor;
 | |
|                     cursor.next = null;
 | |
|                 }
 | |
|                 // stop iteration
 | |
|                 cursor = null;
 | |
|             } else {
 | |
|                 // evicted
 | |
|                 this.emit('evicted', cursor.value);
 | |
|                 // iterate to next
 | |
|                 cursor = cursor.prev;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     toArray() {
 | |
|         const result = [];
 | |
| 
 | |
|         if (this.start) {
 | |
|             let cursor = this.start;
 | |
|             while (cursor) {
 | |
|                 result.push(cursor.value);
 | |
|                 cursor = cursor.next;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         return result;
 | |
|     }
 | |
| 
 | |
|     // toArrayReverse () {
 | |
|     //     const result = [];
 | |
| 
 | |
|     //     if (this.tail) {
 | |
|     //         let cursor = this.tail;
 | |
|     //         while (cursor) {
 | |
|     //             result.push(cursor.value);
 | |
|     //             cursor = cursor.prev;
 | |
|     //         }
 | |
|     //     }
 | |
| 
 | |
|     //     return result;
 | |
|     // }
 | |
| };
 |