@typedly/collection 3.0.0 → 5.0.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 CHANGED
@@ -27,11 +27,15 @@ A **TypeScript** type definitions package for data collections with customizable
27
27
 
28
28
  - [Installation](#installation)
29
29
  - [Api](#api)
30
- - Interface
30
+ - Constructor
31
+ - [`CollectionAdapterConstructor`](#collectionadapterconstructor)
32
+ - [`CollectionConstructor`](#collectionconstructor)
33
+ - [`ConfigurableCollectionAdapterConstructor`](#configurablecollectionadapterconstructor)
34
+ - [`ConfigurableCollectionConstructor`](#configurablecollectionconstructor)
35
+ - Main
31
36
  - [`CollectionAdapter`](#collectionadapter)
37
+ - [`CollectionSettings`](#collectionsettings)
32
38
  - [`CollectionShape`](#collectionshape)
33
- - Type
34
- - [`CollectionConstructor`](#collectionconstructor)
35
39
  - [Contributing](#contributing)
36
40
  - [Support](#support)
37
41
  - [Code of Conduct](#code-of-conduct)
@@ -50,100 +54,195 @@ npm install @typedly/collection --save-peer
50
54
 
51
55
  ```typescript
52
56
  import {
57
+ // Constructor.
58
+ CollectionAdapterConstructor,
59
+ CollectionConstructor,
60
+ ConfigurableCollectionAdapterConstructor,
53
61
  // Interface.
54
62
  CollectionAdapter,
63
+ CollectionSettings,
55
64
  CollectionShape,
56
- // Type.
57
- CollectionConstructor
58
65
  } from '@typedly/collection';
59
66
  ```
60
67
 
61
68
  ### Interface
62
69
 
63
- ### `CollectionAdapter`
70
+ ### Constructor
64
71
 
65
- The adapter interface for collections.
72
+ ### `CollectionAdapterConstructor`
66
73
 
67
- ```typescript
68
- import { CollectionAdapter } from '@typedly/collection';
69
- ```
70
-
71
- ### `CollectionShape`
74
+ The interface of adapter constructor.
72
75
 
73
76
  ```typescript
74
- import { CollectionShape, IterValue } from '@typedly/collection';
75
-
76
- export class AnyCollection<
77
+ import { CollectionAdapter, CollectionAdapterConstructor } from '@typedly/collection';
78
+ import { AsyncReturn } from '@typedly/data';
79
+ /**
80
+ * Example class with fake async returned types.
81
+ */
82
+ export class ExampleCollectionAdapter<
83
+ E,
77
84
  T,
78
- V = Set<T>
79
- > implements CollectionShape<T, V, false> {
80
- // Data shape method.
81
- get value(): V {
82
- // Implementation depends on specific requirements.
83
- return {} as V;
85
+ R extends boolean = false,
86
+ > implements CollectionAdapter<E, T, R> {
87
+ public get async(): R {
88
+ return this.#async;
84
89
  }
85
-
86
- // Example internal storage.
87
- #items: V = new Set<T>() as V;
88
-
89
- constructor(initialItems?: T[], type: new (...args: any[]) => V = Set as any) {
90
- this.#items = new type();
91
- if (initialItems) {
92
- initialItems.forEach(item => (this.#items as any).add(item));
90
+ public get size(): number {
91
+ return this.#items.length;
92
+ }
93
+ public get value(): T {
94
+ return this.#items as T;
95
+ }
96
+ version = "1.0.0";
97
+ #async: R;
98
+ #items: E[] = [];
99
+ constructor(...elements: E[]) {
100
+ this.#async = false as R;
101
+ this.#items.push(...elements);
102
+ }
103
+ public add(...element: E[]): AsyncReturn<R, this> {
104
+ this.#items.push(...element);
105
+ return this as AsyncReturn<R, this>;
106
+ }
107
+ public clear(): AsyncReturn<R, this> {
108
+ this.#items = [];
109
+ return this as AsyncReturn<R, this>;
110
+ }
111
+ public delete(...element: E[]): AsyncReturn<R, boolean> {
112
+ const index = this.#items.indexOf(element[0]);
113
+ if (index !== -1) {
114
+ this.#items.splice(index, 1);
115
+ return true as AsyncReturn<R, boolean>;
93
116
  }
117
+ return false as AsyncReturn<R, boolean>;
94
118
  }
95
-
96
- public clear(): this {
97
- // Implementation depends on specific requirements.
98
- return this;
119
+ public destroy(): AsyncReturn<R, this> {
120
+ this.#items = [];
121
+ return this as AsyncReturn<R, this>;
99
122
  }
100
- public destroy(): this {
101
- // Implementation depends on specific requirements.
102
- return this;
123
+ public forEach(callbackfn: (element: E, element2: E, collection: CollectionAdapter<E, T, R>) => void, thisArg?: any): AsyncReturn<R, this> {
124
+ this.#items.forEach((value: E) => {
125
+ callbackfn.call(thisArg, value, value, this);
126
+ });
127
+ return this as AsyncReturn<R, this>;
128
+ }
129
+ public getValue(): AsyncReturn<R, T> {
130
+ return this.#items as AsyncReturn<R, T>;
131
+ }
132
+ public has(element: E): AsyncReturn<R, boolean> {
133
+ return this.#items.includes(element) as AsyncReturn<R, boolean>;
103
134
  }
104
135
  public lock(): this {
105
- // Implementation depends on specific requirements.
106
136
  return this;
107
137
  }
108
- public set(value: V): this {
109
- // Implementation depends on specific requirements.
110
- return this;
138
+ public setValue(value: T): AsyncReturn<R, this> {
139
+ this.#items = value as unknown as E[];
140
+ return this as AsyncReturn<R, this>;
111
141
  }
112
- public unlock(): this {
113
- // Implementation depends on specific requirements.
114
- return this;
142
+ public unlock(): AsyncReturn<R, this> {
143
+ return this as AsyncReturn<R, this>;
115
144
  }
145
+ }
116
146
 
147
+ // Create factory function for creating adapter instances.
148
+ function createAdapter<
149
+ E,
150
+ T,
151
+ R extends boolean = false,
152
+ A extends CollectionAdapter<E, T, R> = CollectionAdapter<E, T, R>
153
+ >(
154
+ AdapterCtor: CollectionAdapterConstructor<E, T, R, A>,
155
+ ...elements: E[]
156
+ ): A {
157
+ return new AdapterCtor(...elements);
158
+ }
117
159
 
118
- add(element: T): this {
119
- (this.#items as any).add(element);
120
- return this;
121
- }
160
+ // ExampleCollectionAdapter<number, unknown, false>
161
+ const adapter1 = createAdapter(ExampleCollectionAdapter, 1, 2, 3);
162
+ // ExampleCollectionAdapter<string, unknown, true>
163
+ const adapter2 = createAdapter(ExampleCollectionAdapter, 'a', 'b', 'c');
164
+ ```
122
165
 
123
- delete(element: T): boolean {
124
- return (this.#items as any).delete(element);
125
- }
166
+ ### `CollectionConstructor`
126
167
 
127
- forEach(callbackfn: (element: T, element2: T, collection: CollectionShape<T, V, false>) => void, thisArg?: any): this {
128
- (this.#items as any).forEach((value: T) => {
129
- callbackfn.call(thisArg, value, value, this);
130
- });
131
- return this;
132
- }
168
+ ```typescript
169
+ import { CollectionConstructor } from '@typedly/collection';
170
+ ```
133
171
 
134
- has(element: T): boolean {
135
- return (this.#items as any).has(element);
136
- }
172
+ ### `ConfigurableCollectionAdapterConstructor`
137
173
 
138
- get size(): number {
139
- return (this.#items as any).size;
140
- }
174
+ ```typescript
175
+ import { ConfigurableCollectionAdapterConstructor } from '@typedly/collection';
176
+ ```
177
+
178
+ ### `ConfigurableCollectionConstructor`
179
+
180
+ ```typescript
181
+ import { ConfigurableCollectionConstructor } from '@typedly/collection';
182
+ ```
183
+
184
+ ### Main
185
+
186
+ ### `CollectionAdapter`
187
+
188
+ The adapter interface for collections.
189
+
190
+ ```typescript
191
+ import { CollectionAdapter } from '@typedly/collection';
192
+ ```
193
+
194
+ ### `CollectionSettings`
141
195
 
142
- get [Symbol.toStringTag](): string {
143
- return 'MyCollection';
196
+ Represents the settings for a collection.
197
+
198
+ ```typescript
199
+ import { CollectionSettings } from '@typedly/collection';
200
+ ```
201
+
202
+ ### `CollectionShape`
203
+
204
+ Represents a collection of elements.
205
+
206
+ ```typescript
207
+ import { CollectionShape, IterValue } from '@typedly/collection';
208
+
209
+ // Example class implementing CollectionShape.
210
+ export class AnyCollection<
211
+ E,
212
+ T = Set<E>
213
+ > implements CollectionShape<E, T, false> {
214
+ get size(): number { return (this.#items as any).size; }
215
+ get value(): T { return this.#items; }
216
+ get [Symbol.toStringTag](): string { return 'AnyCollection'; }
217
+
218
+ async = false as false;
219
+
220
+ #items: T;
221
+
222
+ constructor(
223
+ { async, value }: { async: false, value?: T },
224
+ type?: new (...args: any[]) => T,
225
+ ...elements: E[]
226
+ ) {
227
+ this.async = async;
228
+ this.#items = type ? new type() : value ? value : {} as T;
229
+ elements.forEach(element => (this.#items as any).add(element));
144
230
  }
145
231
 
146
- [Symbol.iterator](): IterableIterator<IterValue<V>> {
232
+ add(element: E): this { (this.#items as any).add(element); return this; }
233
+ clear(): this { return this; }
234
+ delete(element: E): boolean { return (this.#items as any).delete(element); }
235
+ destroy(): this { return this; }
236
+ forEach(callbackfn: (element: E, element2: E, collection: CollectionShape<E, T, false>) => void, thisArg?: any): this {
237
+ (this.#items as any).forEach((value: E) => callbackfn.call(thisArg, value, value, this));
238
+ return this;
239
+ }
240
+ has(element: E): boolean { return (this.#items as any).has(element); }
241
+ lock(): this { return this; }
242
+ getValue(): T { return this.#items; }
243
+ setValue(value: T): this { this.#items = value; return this; }
244
+ unlock(): this { return this; }
245
+ [Symbol.iterator](): IterableIterator<IterValue<T>> {
147
246
  return (this.#items as any).values();
148
247
  }
149
248
  }
@@ -151,18 +250,22 @@ export class AnyCollection<
151
250
  const obj1 = {age: 27};
152
251
  const obj2 = {age: 37};
153
252
  const obj3 = {age: 47};
154
- const anyCollection = new AnyCollection<{age: number}, WeakSet<{age: number}>>([], WeakSet)
253
+ const anyCollection1 = new AnyCollection<{age: number}, Set<{age: number}>>(
254
+ { async: false, value: new Set([{age: 27}, {age: 37}, {age: 47}]) }
255
+ )
155
256
  .add(obj1)
156
257
  .add(obj2)
157
258
  .add(obj3);
158
- ```
159
259
 
160
- ### Type
260
+ console.log(`anyCollection1:`, anyCollection1.value);
161
261
 
162
- ### `CollectionConstructor`
262
+ const anyCollection2 = new AnyCollection<{age: number}, Set<{age: number}>>(
263
+ { async: false }, Set)
264
+ .add(obj1)
265
+ .add(obj2)
266
+ .add(obj3);
163
267
 
164
- ```typescript
165
- import { CollectionConstructor } from '@typedly/collection';
268
+ console.log(`anyCollection2:`, anyCollection2.value);
166
269
  ```
167
270
 
168
271
  ## Contributing
@@ -176,10 +279,12 @@ If you find this package useful and would like to support its and general develo
176
279
  Support via:
177
280
 
178
281
  - [Stripe](https://donate.stripe.com/dR614hfDZcJE3wAcMM)
179
- - [Revolut](https://checkout.revolut.com/pay/048b10a3-0e10-42c8-a917-e3e9cb4c8e29)
282
+ - ~~[Revolut](https://checkout.revolut.com/pay/048b10a3-0e10-42c8-a917-e3e9cb4c8e29)~~
180
283
  - [GitHub](https://github.com/sponsors/angular-package/sponsorships?sponsor=sciborrudnicki&tier_id=83618)
181
284
  - [DonorBox](https://donorbox.org/become-a-sponsor-to-the-angular-package?default_interval=o)
182
285
  - [Patreon](https://www.patreon.com/checkout/angularpackage?rid=0&fan_landing=true&view_as=public)
286
+ - [4Fund](https://4fund.com/bruubs)
287
+ - [PayPal](https://paypal.me/sterblack)
183
288
 
184
289
  or via Trust Wallet
185
290
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@typedly/collection",
3
- "version": "3.0.0",
3
+ "version": "5.0.0",
4
4
  "author": "wwwdev.io <dev@wwwdev.io>",
5
5
  "description": "A TypeScript type definitions package for data collections with customizable storage.",
6
6
  "license": "MIT",
@@ -9,7 +9,7 @@
9
9
  "registry": "https://registry.npmjs.org"
10
10
  },
11
11
  "peerDependencies": {
12
- "@typedly/data": "^3.0.0"
12
+ "@typedly/data": "^4.0.0"
13
13
  },
14
14
  "repository": {
15
15
  "type": "git",
@@ -1,6 +1,100 @@
1
1
  import { DataShape, AsyncReturn } from '@typedly/data';
2
2
  import { ConstrainedConstructor } from '@typedly/constructor';
3
3
 
4
+ /**
5
+ * @description Represents the settings for a collection.
6
+ * @export
7
+ * @interface CollectionSettings
8
+ * @template E The type of the elements in the collection.
9
+ * @template T The type of the value in the collection.
10
+ * @template {boolean} [R=false] The `boolean` type to determine async methods.
11
+ */
12
+ interface CollectionSettings<E, T, R extends boolean = false> {
13
+ /**
14
+ * @description The asynchronous mode of the collection. If `true`, collection methods will return Promises.
15
+ * @default false
16
+ * @type {?R}
17
+ */
18
+ async?: R;
19
+ /**
20
+ * @description The initial value of the collection. The type of the value is determined by the generic type `T`. If not provided, it defaults to `undefined`.
21
+ * @type {?T}
22
+ */
23
+ value?: T;
24
+ /**
25
+ * @description The maximum number of items the collection can hold. If not provided, it defaults to `undefined`, indicating no limit.
26
+ * @default undefined
27
+ * @type {?number}
28
+ */
29
+ maxSize?: number;
30
+ /**
31
+ * @description The initial capacity of the collection. This is a hint for optimization and does not limit the number of items. If not provided, it defaults to `undefined`.
32
+ * @default undefined
33
+ * @type {?number}
34
+ */
35
+ capacity?: number;
36
+ /**
37
+ * @description Indicates whether the collection should automatically sort its elements. If `true`, the collection will maintain its elements in sorted order based on the provided `comparator` function. If not provided, it defaults to `false`.
38
+ * @default false
39
+ * @type {?boolean}
40
+ */
41
+ autoSort?: boolean;
42
+ /**
43
+ * @description A function that defines the sort order of the collection's elements. It should return a negative number if `a` should come before `b`, a positive number if `a` should come after `b`, or `0` if they are considered equal. If not provided, it defaults to `undefined`.
44
+ * @type {?(a: E, b: E) => number}
45
+ */
46
+ comparator?: (a: E, b: E) => number;
47
+ /**
48
+ * @description Indicates whether the collection should enforce uniqueness of its elements. If `true`, the collection will not allow duplicate elements. If not provided, it defaults to `false`.
49
+ * @default false
50
+ * @type {?boolean}
51
+ */
52
+ unique?: boolean;
53
+ /**
54
+ * @description Indicates whether the collection should be immutable. If `true`, the collection will not allow modifications after it has been created. If not provided, it defaults to `false`.
55
+ * @default false
56
+ * @type {?boolean}
57
+ */
58
+ immutable?: boolean;
59
+ /**
60
+ * @description Indicates whether the collection should log its actions. If `true`, the collection will log actions such as additions, removals, and updates. If not provided, it defaults to `false`.
61
+ * @default false
62
+ * @type {?boolean}
63
+ */
64
+ log?: boolean;
65
+ /**
66
+ * @description Indicates whether the collection should be lazily initialized. If `true`, the collection will delay initialization until it is first accessed. If not provided, it defaults to `false`.
67
+ * @default false
68
+ * @type {?boolean}
69
+ */
70
+ lazy?: boolean;
71
+ /**
72
+ * @description The maximum time, in milliseconds, that the collection will wait for an operation to complete before timing out. If not provided, it defaults to `undefined`, indicating no timeout.
73
+ * @type {?number}
74
+ */
75
+ timeout?: number;
76
+ /**
77
+ * @description The number of items to prefetch in the collection. If not provided, it defaults to `undefined`, indicating no prefetching.
78
+ * @type {?number}
79
+ */
80
+ prefetch?: number;
81
+ /**
82
+ * @description Indicates whether the collection should be locked. If `true`, the collection will not allow any modifications after it has been created. If not provided, it defaults to `false`.
83
+ * @default false
84
+ * @type {?boolean}
85
+ */
86
+ locked?: boolean;
87
+ /**
88
+ * @description The name of the collection. If not provided, it defaults to `undefined`.
89
+ * @type {?string}
90
+ */
91
+ name?: string;
92
+ /**
93
+ * @description Function to validate elements before adding
94
+ */
95
+ validator?: (element: E) => boolean;
96
+ }
97
+
4
98
  /**
5
99
  * @description Represents a collection of elements.
6
100
  * @export
@@ -11,6 +105,23 @@ import { ConstrainedConstructor } from '@typedly/constructor';
11
105
  * @extends {DataShape<T, R>}
12
106
  */
13
107
  interface CollectionShape<E, T = any, R extends boolean = false> extends DataShape<T, R> {
108
+ /**
109
+ * @description Indicates whether the collection operates in asynchronous mode.
110
+ * @readonly
111
+ * @type {R}
112
+ */
113
+ readonly async: R;
114
+ /**
115
+ * @description The configuration settings of the collection.
116
+ * @readonly
117
+ * @type {?CollectionSettings<E, T, R>}
118
+ */
119
+ readonly configuration?: CollectionSettings<E, T, R>;
120
+ /**
121
+ * @description The number of items in the collection.
122
+ * @returns {number}
123
+ */
124
+ readonly size: number;
14
125
  /**
15
126
  * @description Adds elements to the collection.
16
127
  * @param {...E[]} element Element of type `T` to add.
@@ -36,10 +147,22 @@ interface CollectionShape<E, T = any, R extends boolean = false> extends DataSha
36
147
  */
37
148
  has(...element: E[]): AsyncReturn<R, boolean>;
38
149
  /**
39
- * @description The number of items in the collection.
40
- * @returns {number}
150
+ * @description Sets the asynchronous mode of the collection.
151
+ * @param {R} async The boolean type to determine async methods.
152
+ * @returns {this} The collection instance `this`.
41
153
  */
42
- readonly size: number;
154
+ setAsync?(async: R): this;
155
+ /**
156
+ * @description Converts the collection to an array of elements.
157
+ * @returns {AsyncReturn<R, E[]>} The array of elements, or in `Promise` if `R` is `true`.
158
+ */
159
+ toArray?(): AsyncReturn<R, E[]>;
160
+ /**
161
+ * @description
162
+ * @param {R} async
163
+ * @returns {CollectionShape<E, T, R>}
164
+ */
165
+ with?(async: R): CollectionShape<E, T, R>;
43
166
  }
44
167
 
45
168
  /**
@@ -55,14 +178,43 @@ interface CollectionAdapter<E, T, R extends boolean = false> extends CollectionS
55
178
  version: string;
56
179
  }
57
180
 
181
+ /**
182
+ * @description The interface of adapter constructor.
183
+ * @export
184
+ * @interface CollectionAdapterConstructor
185
+ * @template E Elements type of `T`.
186
+ * @template T Value type under which the elements are stored.
187
+ * @template {boolean} [R=false] The boolean type indicates the async methods.
188
+ * @template {CollectionAdapter<E, T, R>} [A=CollectionAdapter<E, T, R>] The adapter type.
189
+ */
190
+ interface CollectionAdapterConstructor<E, T, R extends boolean = false, A extends CollectionAdapter<E, T, R> = CollectionAdapter<E, T, R>> {
191
+ new (...elements: E[]): A;
192
+ }
193
+
58
194
  /**
59
195
  * @description The constructor type for CollectionShape.
60
196
  * @export
61
197
  * @template E The type of the elements in the collection.
62
198
  * @template T The type of the value in the collection, data of elements.
63
- * @template {boolean} [R=false] The `boolean` type to determine async methods.
64
- * @template {CollectionShape<E, T, R>} [C=CollectionShape<E, T, R>]
199
+ * @template {boolean} [R=false] The boolean type indicates the async methods.
200
+ * @template {CollectionShape<E, T, R>} [S=CollectionShape<E, T, R>] The collection shape type.
201
+ */
202
+ interface CollectionConstructor<E, T, R extends boolean = false, S extends CollectionShape<E, T, R> = CollectionShape<E, T, R>> extends ConstrainedConstructor<CollectionShape<E, T, R>, S, [
203
+ ...E[]
204
+ ]> {
205
+ }
206
+
207
+ /**
208
+ * @description The interface of adapter constructor with configurable async mode.
209
+ * @export
210
+ * @interface ConfigurableCollectionAdapterConstructor
211
+ * @template E Elements type of `T`.
212
+ * @template T Value type under which the elements are stored.
213
+ * @template {CollectionSettings<E, T, any>} [C=CollectionSettings<E, T, any>]
214
+ * @template {CollectionAdapter<E, T, C['async']>} [A=CollectionAdapter<E, T, C['async']>]
65
215
  */
66
- type CollectionConstructor<E, T, R extends boolean = false, C extends CollectionShape<E, T, R> = CollectionShape<E, T, R>> = ConstrainedConstructor<CollectionShape<E, T, R>, C, E[]>;
216
+ interface ConfigurableCollectionAdapterConstructor<E, T, C extends CollectionSettings<E, T, any> = CollectionSettings<E, T, any>, A extends CollectionAdapter<E, T, C['async']> = CollectionAdapter<E, T, C['async']>> {
217
+ new (settings: C, ...elements: E[]): A;
218
+ }
67
219
 
68
- export type { CollectionAdapter, CollectionConstructor, CollectionShape };
220
+ export type { CollectionAdapter, CollectionAdapterConstructor, CollectionConstructor, CollectionSettings, CollectionShape, ConfigurableCollectionAdapterConstructor };