utilium 0.4.1 → 0.4.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.
- package/dist/list.d.ts +26 -0
- package/dist/list.js +99 -0
- package/dist/objects.d.ts +1 -1
- package/dist/types.d.ts +8 -1
- package/package.json +4 -1
- package/src/list.ts +127 -0
- package/src/objects.ts +1 -1
- package/src/types.ts +8 -1
package/dist/list.d.ts
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
/// <reference types="node" resolution-mode="require"/>
|
2
|
+
import { EventEmitter } from 'eventemitter3';
|
3
|
+
export declare class List<T> extends EventEmitter<'update'> implements Set<T>, RelativeIndexable<T> {
|
4
|
+
readonly [Symbol.toStringTag] = "List";
|
5
|
+
protected data: Set<T>;
|
6
|
+
array(): T[];
|
7
|
+
json(): string;
|
8
|
+
toString(): string;
|
9
|
+
set(index: number, value: T): void;
|
10
|
+
deleteAt(index: number): void;
|
11
|
+
at(index: number): T;
|
12
|
+
pop(): T | undefined;
|
13
|
+
push(...items: T[]): number;
|
14
|
+
join(separator?: string): string;
|
15
|
+
splice(start: number, deleteCount: number, ...items: T[]): T[];
|
16
|
+
add(value: T): this;
|
17
|
+
clear(): void;
|
18
|
+
delete(value: T): boolean;
|
19
|
+
forEach(callbackfn: (value: T, value2: T, list: List<T>) => void, thisArg?: any): void;
|
20
|
+
has(value: T): boolean;
|
21
|
+
get size(): number;
|
22
|
+
entries(): IterableIterator<[T, T]>;
|
23
|
+
keys(): IterableIterator<T>;
|
24
|
+
values(): IterableIterator<T>;
|
25
|
+
[Symbol.iterator](): IterableIterator<T>;
|
26
|
+
}
|
package/dist/list.js
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
import { EventEmitter } from 'eventemitter3';
|
2
|
+
export class List extends EventEmitter {
|
3
|
+
[Symbol.toStringTag] = 'List';
|
4
|
+
data = new Set();
|
5
|
+
array() {
|
6
|
+
return [...this.data];
|
7
|
+
}
|
8
|
+
json() {
|
9
|
+
return JSON.stringify([...this.data]);
|
10
|
+
}
|
11
|
+
toString() {
|
12
|
+
return this.join(',');
|
13
|
+
}
|
14
|
+
set(index, value) {
|
15
|
+
if (Math.abs(index) > this.data.size) {
|
16
|
+
throw new ReferenceError('Can not set an element outside the bounds of the list');
|
17
|
+
}
|
18
|
+
const data = [...this.data];
|
19
|
+
data.splice(index, 1, value);
|
20
|
+
this.data = new Set(data);
|
21
|
+
this.emit('update');
|
22
|
+
}
|
23
|
+
deleteAt(index) {
|
24
|
+
if (Math.abs(index) > this.data.size) {
|
25
|
+
throw new ReferenceError('Can not delete an element outside the bounds of the list');
|
26
|
+
}
|
27
|
+
this.delete([...this.data].at(index));
|
28
|
+
}
|
29
|
+
// Array methods
|
30
|
+
at(index) {
|
31
|
+
if (Math.abs(index) > this.data.size) {
|
32
|
+
throw new ReferenceError('Can not access an element outside the bounds of the list');
|
33
|
+
}
|
34
|
+
return [...this.data].at(index);
|
35
|
+
}
|
36
|
+
pop() {
|
37
|
+
const item = [...this.data].pop();
|
38
|
+
if (item !== undefined) {
|
39
|
+
this.delete(item);
|
40
|
+
}
|
41
|
+
return item;
|
42
|
+
}
|
43
|
+
push(...items) {
|
44
|
+
for (const item of items) {
|
45
|
+
this.add(item);
|
46
|
+
}
|
47
|
+
return this.data.size;
|
48
|
+
}
|
49
|
+
join(separator) {
|
50
|
+
return [...this.data].join(separator);
|
51
|
+
}
|
52
|
+
splice(start, deleteCount, ...items) {
|
53
|
+
if (Math.abs(start) > this.data.size) {
|
54
|
+
throw new ReferenceError('Can not splice elements outside the bounds of the list');
|
55
|
+
}
|
56
|
+
const data = [...this.data];
|
57
|
+
const deleted = data.splice(start, deleteCount, ...items);
|
58
|
+
this.data = new Set(data);
|
59
|
+
this.emit('update');
|
60
|
+
return deleted;
|
61
|
+
}
|
62
|
+
// Set methods
|
63
|
+
add(value) {
|
64
|
+
this.data.add(value);
|
65
|
+
this.emit('update');
|
66
|
+
return this;
|
67
|
+
}
|
68
|
+
clear() {
|
69
|
+
this.data.clear();
|
70
|
+
this.emit('update');
|
71
|
+
}
|
72
|
+
delete(value) {
|
73
|
+
const success = this.data.delete(value);
|
74
|
+
this.emit('update');
|
75
|
+
return success;
|
76
|
+
}
|
77
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
78
|
+
forEach(callbackfn, thisArg) {
|
79
|
+
this.data.forEach((v1, v2) => callbackfn.call(thisArg, v1, v2, this));
|
80
|
+
}
|
81
|
+
has(value) {
|
82
|
+
return this.data.has(value);
|
83
|
+
}
|
84
|
+
get size() {
|
85
|
+
return this.data.size;
|
86
|
+
}
|
87
|
+
entries() {
|
88
|
+
return this.data.entries();
|
89
|
+
}
|
90
|
+
keys() {
|
91
|
+
return this.data.keys();
|
92
|
+
}
|
93
|
+
values() {
|
94
|
+
return this.data.values();
|
95
|
+
}
|
96
|
+
[Symbol.iterator]() {
|
97
|
+
return this.data[Symbol.iterator]();
|
98
|
+
}
|
99
|
+
}
|
package/dist/objects.d.ts
CHANGED
package/dist/types.d.ts
CHANGED
@@ -143,7 +143,7 @@ export type FlattenArray<A extends unknown[], D = null> = A extends (infer U)[]
|
|
143
143
|
/**
|
144
144
|
* Whether T is a tuple
|
145
145
|
*/
|
146
|
-
export type IsTuple<T> = T extends [] ? false : T extends [infer
|
146
|
+
export type IsTuple<T> = T extends [] ? false : T extends [infer _Head, ...infer _Rest] ? true : false;
|
147
147
|
/**
|
148
148
|
* Flattens a tuple
|
149
149
|
*/
|
@@ -181,4 +181,11 @@ export type LastOfUnion<T> = UnionToIntersection<T extends any ? () => T : never
|
|
181
181
|
* @see https://stackoverflow.com/a/55128956/17637456
|
182
182
|
*/
|
183
183
|
export type UnionToTuple<T, L = LastOfUnion<T>, N = [T] extends [never] ? true : false> = true extends N ? [] : Push<UnionToTuple<Exclude<T, L>>, L>;
|
184
|
+
/**
|
185
|
+
* Makes properties with keys assignable to K in T required
|
186
|
+
* @see https://stackoverflow.com/a/69328045/17637456
|
187
|
+
*/
|
188
|
+
export type WithRequired<T, K extends keyof T> = T & {
|
189
|
+
[P in K]-?: T[P];
|
190
|
+
};
|
184
191
|
export {};
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "utilium",
|
3
|
-
"version": "0.4.
|
3
|
+
"version": "0.4.3",
|
4
4
|
"description": "Typescript utilies",
|
5
5
|
"main": "dist/index.js",
|
6
6
|
"types": "dist/index.d.ts",
|
@@ -31,5 +31,8 @@
|
|
31
31
|
"prettier": "^3.2.5",
|
32
32
|
"typedoc": "^0.24.8",
|
33
33
|
"typescript": "^5.1.6"
|
34
|
+
},
|
35
|
+
"dependencies": {
|
36
|
+
"eventemitter3": "^5.0.1"
|
34
37
|
}
|
35
38
|
}
|
package/src/list.ts
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
import { EventEmitter } from 'eventemitter3';
|
2
|
+
|
3
|
+
export class List<T> extends EventEmitter<'update'> implements Set<T>, RelativeIndexable<T> {
|
4
|
+
public readonly [Symbol.toStringTag] = 'List';
|
5
|
+
|
6
|
+
protected data = new Set<T>();
|
7
|
+
|
8
|
+
public array(): T[] {
|
9
|
+
return [...this.data];
|
10
|
+
}
|
11
|
+
|
12
|
+
public json() {
|
13
|
+
return JSON.stringify([...this.data]);
|
14
|
+
}
|
15
|
+
|
16
|
+
public toString() {
|
17
|
+
return this.join(',');
|
18
|
+
}
|
19
|
+
|
20
|
+
public set(index: number, value: T): void {
|
21
|
+
if (Math.abs(index) > this.data.size) {
|
22
|
+
throw new ReferenceError('Can not set an element outside the bounds of the list');
|
23
|
+
}
|
24
|
+
|
25
|
+
const data = [...this.data];
|
26
|
+
data.splice(index, 1, value);
|
27
|
+
this.data = new Set<T>(data);
|
28
|
+
this.emit('update');
|
29
|
+
}
|
30
|
+
|
31
|
+
public deleteAt(index: number): void {
|
32
|
+
if (Math.abs(index) > this.data.size) {
|
33
|
+
throw new ReferenceError('Can not delete an element outside the bounds of the list');
|
34
|
+
}
|
35
|
+
|
36
|
+
this.delete([...this.data].at(index)!);
|
37
|
+
}
|
38
|
+
|
39
|
+
// Array methods
|
40
|
+
|
41
|
+
public at(index: number): T {
|
42
|
+
if (Math.abs(index) > this.data.size) {
|
43
|
+
throw new ReferenceError('Can not access an element outside the bounds of the list');
|
44
|
+
}
|
45
|
+
|
46
|
+
return [...this.data].at(index)!;
|
47
|
+
}
|
48
|
+
|
49
|
+
public pop(): T | undefined {
|
50
|
+
const item = [...this.data].pop();
|
51
|
+
if (item !== undefined) {
|
52
|
+
this.delete(item);
|
53
|
+
}
|
54
|
+
return item;
|
55
|
+
}
|
56
|
+
|
57
|
+
public push(...items: T[]): number {
|
58
|
+
for (const item of items) {
|
59
|
+
this.add(item);
|
60
|
+
}
|
61
|
+
return this.data.size;
|
62
|
+
}
|
63
|
+
|
64
|
+
public join(separator?: string): string {
|
65
|
+
return [...this.data].join(separator);
|
66
|
+
}
|
67
|
+
|
68
|
+
public splice(start: number, deleteCount: number, ...items: T[]): T[] {
|
69
|
+
if (Math.abs(start) > this.data.size) {
|
70
|
+
throw new ReferenceError('Can not splice elements outside the bounds of the list');
|
71
|
+
}
|
72
|
+
|
73
|
+
const data = [...this.data];
|
74
|
+
const deleted = data.splice(start, deleteCount, ...items);
|
75
|
+
this.data = new Set<T>(data);
|
76
|
+
this.emit('update');
|
77
|
+
return deleted;
|
78
|
+
}
|
79
|
+
|
80
|
+
// Set methods
|
81
|
+
|
82
|
+
public add(value: T): this {
|
83
|
+
this.data.add(value);
|
84
|
+
this.emit('update');
|
85
|
+
return this;
|
86
|
+
}
|
87
|
+
|
88
|
+
public clear(): void {
|
89
|
+
this.data.clear();
|
90
|
+
this.emit('update');
|
91
|
+
}
|
92
|
+
|
93
|
+
public delete(value: T): boolean {
|
94
|
+
const success = this.data.delete(value);
|
95
|
+
this.emit('update');
|
96
|
+
return success;
|
97
|
+
}
|
98
|
+
|
99
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
100
|
+
public forEach(callbackfn: (value: T, value2: T, list: List<T>) => void, thisArg?: any): void {
|
101
|
+
this.data.forEach((v1, v2) => callbackfn.call(thisArg, v1, v2, this));
|
102
|
+
}
|
103
|
+
|
104
|
+
public has(value: T): boolean {
|
105
|
+
return this.data.has(value);
|
106
|
+
}
|
107
|
+
|
108
|
+
public get size(): number {
|
109
|
+
return this.data.size;
|
110
|
+
}
|
111
|
+
|
112
|
+
public entries(): IterableIterator<[T, T]> {
|
113
|
+
return this.data.entries();
|
114
|
+
}
|
115
|
+
|
116
|
+
public keys(): IterableIterator<T> {
|
117
|
+
return this.data.keys();
|
118
|
+
}
|
119
|
+
|
120
|
+
public values(): IterableIterator<T> {
|
121
|
+
return this.data.values();
|
122
|
+
}
|
123
|
+
|
124
|
+
public [Symbol.iterator](): IterableIterator<T> {
|
125
|
+
return this.data[Symbol.iterator]();
|
126
|
+
}
|
127
|
+
}
|
package/src/objects.ts
CHANGED
package/src/types.ts
CHANGED
@@ -172,7 +172,8 @@ export type FlattenArray<A extends unknown[], D = null> = A extends (infer U)[]
|
|
172
172
|
/**
|
173
173
|
* Whether T is a tuple
|
174
174
|
*/
|
175
|
-
|
175
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
176
|
+
export type IsTuple<T> = T extends [] ? false : T extends [infer _Head, ...infer _Rest] ? true : false;
|
176
177
|
|
177
178
|
/**
|
178
179
|
* Flattens a tuple
|
@@ -220,3 +221,9 @@ export type LastOfUnion<T> = UnionToIntersection<T extends any ? () => T : never
|
|
220
221
|
* @see https://stackoverflow.com/a/55128956/17637456
|
221
222
|
*/
|
222
223
|
export type UnionToTuple<T, L = LastOfUnion<T>, N = [T] extends [never] ? true : false> = true extends N ? [] : Push<UnionToTuple<Exclude<T, L>>, L>;
|
224
|
+
|
225
|
+
/**
|
226
|
+
* Makes properties with keys assignable to K in T required
|
227
|
+
* @see https://stackoverflow.com/a/69328045/17637456
|
228
|
+
*/
|
229
|
+
export type WithRequired<T, K extends keyof T> = T & { [P in K]-?: T[P] };
|