Skip to content

Commit dbfd805

Browse files
Merge pull request #4 from typescript-package/develop
v2.1.0
2 parents 17d2ad5 + c301465 commit dbfd805

File tree

8 files changed

+498
-4
lines changed

8 files changed

+498
-4
lines changed

README.md

Lines changed: 113 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,16 @@ A lightweight **TypeScript** library for basic data management.
1919

2020
- [Installation](#installation)
2121
- [Api](#api)
22-
- `abstract`
22+
- Abstract
2323
- [`Immutability`](#immutability)
2424
- [`DataCore`](#datacore)
25-
- **Base**
25+
- Base
2626
- [`Data`](#data)
2727
- [`Value`](#value)
28-
- **`WeakData`**
28+
- Map
29+
- [`DataMap`](#datamap)
30+
- [`WeakDataMap`](#weakdatamap)
31+
- WeakData
2932
- [`IndexedWeakData`](#indexedweakdata)
3033
- [`WeakData`](#weakdata)
3134
- [Immutability](#immutability)
@@ -59,6 +62,10 @@ import {
5962
Data,
6063
Value,
6164

65+
// `Map`.
66+
DataMap,
67+
WeakDataMap,
68+
6269
// `WeakData`.
6370
NamedWeakData,
6471
// Indexed.
@@ -108,6 +115,109 @@ The class to manage the value of generic type variable `Type`.
108115
import { Value } from '@typescript-package/data';
109116
```
110117

118+
### `DataMap`
119+
120+
The `DataMap` is a concrete class that extends `Map` and encapsulates its data within a `DataCore` store, providing additional data management capabilities.
121+
122+
```typescript
123+
import { DataMap } from '@typescript-package/data';
124+
125+
// Define a `DataCore` implementation for holding a data in `DataMap`.
126+
export class CustomMapData<Key, Value> extends Data<Map<Key, Value>> {
127+
constructor(initialValue?: Map<Key, Value>) {
128+
super(initialValue ?? new Map());
129+
}
130+
}
131+
132+
// Create a new `DataMap` instance with predefined entries and customized data holder.
133+
export const dataMap = new DataMap<string, number, CustomMapData<string, number>>(
134+
[
135+
["one", 1],
136+
["two", 2],
137+
["three", 3],
138+
],
139+
new CustomMapData()
140+
);
141+
142+
// Check the `CustomMapData`.
143+
console.log(`Data holder of \`CustomMapData\`:`, dataMap.data); // Output: CustomMapData {#locked: false, #value: Value}
144+
145+
// Get the `CustomMapData` value.
146+
console.log(`Data holder of \`CustomMapData\` value:`, dataMap.data.value); // Output: Map(3) {'one' => 1, 'two' => 2, 'three' => 3}
147+
148+
// Log the size of the map
149+
console.log("Size:", dataMap.size); // Output: Size: 3
150+
151+
// Get a value from the map
152+
console.log("Value for 'two':", dataMap.get("two")); // Output: Value for 'two': 2
153+
154+
// Check if a key exists
155+
console.log("Has 'three'?", dataMap.has("three")); // Output: Has 'three'? true
156+
157+
// Set a new key-value pair
158+
dataMap.set("four", 4);
159+
console.log("Size after set:", dataMap.size); // Output: Size after set: 4
160+
161+
// Iterate over entries
162+
dataMap.forEach((value, key) => console.log(`${key}: ${value}`));
163+
// Output:
164+
// one: 1
165+
// two: 2
166+
// three: 3
167+
// four: 4
168+
169+
// Delete an entry
170+
dataMap.delete("one");
171+
console.log("Size after delete:", dataMap.size); // Output: Size after delete: 3
172+
173+
// Clear the map
174+
dataMap.clear();
175+
console.log("Size after clear:", dataMap.size); // Output: Size after clear: 0
176+
177+
```
178+
179+
### `WeakDataMap`
180+
181+
The `WeakDataMap` class is a concrete class that stores data in a static `WeakMap`.
182+
183+
```typescript
184+
import { WeakDataMap } from '@typescript-package/data';
185+
186+
// Create an instance of `WeakDataMap`.
187+
const weakDataMap = new WeakDataMap<string, number>([
188+
['one', 1],
189+
['two', 2],
190+
['three', 3],
191+
]);
192+
193+
194+
// Get the value from `WeakData` static.
195+
console.log(`data: `, WeakData.get(weakDataMap.data)); // Output: Map(3) {'one' => 1, 'two' => 2, 'three' => 3}
196+
197+
// Get a value by key
198+
console.log(weakDataMap.get('two')); // Output: 2
199+
200+
// Add a new key-value pair
201+
weakDataMap.set('four', 4);
202+
203+
// Check if a key exists
204+
console.log(weakDataMap.has('four')); // Output: true
205+
206+
// Delete a key
207+
weakDataMap.delete('one');
208+
209+
// Iterate over entries
210+
for (const [key, value] of weakDataMap.entries()) {
211+
console.log(key, value);
212+
}
213+
214+
// Output:
215+
// two 2
216+
// three 3
217+
// four 4
218+
219+
```
220+
111221
### `Immutability`
112222

113223
Manages the immutability states of `this` current instance.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@typescript-package/data",
3-
"version": "2.0.0",
3+
"version": "2.1.0",
44
"author": "wwwdev.io <dev@wwwdev.io>",
55
"description": "A lightweight TypeScript library for basic data management.",
66
"license": "MIT",

src/map/data-map.class.ts

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
// Class.
2+
import { Data } from '../lib/data.class';
3+
// Abstract.
4+
import { DataCore } from '../lib/data-core.abstract';
5+
/**
6+
* @description The `DataMap` is a concrete class that extends `Map` and encapsulates its data within a `DataCore` store, providing additional data management capabilities.
7+
* @export
8+
* @class DataMap
9+
* @template Key
10+
* @template Value
11+
* @template {DataCore<Map<Key, Value>>} [DataType=Data<Map<Key, Value>>]
12+
* @extends {Map<Key, Value>}
13+
*/
14+
export class DataMap<
15+
Key,
16+
Value,
17+
DataType extends DataCore<Map<Key, Value>> = Data<Map<Key, Value>>
18+
> {
19+
/**
20+
* @description Returns the `string` tag representation of the `DataMap` class when used in `Object.prototype.toString.call(instance)`.
21+
* @public
22+
* @readonly
23+
*/
24+
public get [Symbol.toStringTag](): string {
25+
return DataMap.name;
26+
}
27+
28+
/**
29+
* @description Returns the privately stored data class.
30+
* @public
31+
* @readonly
32+
* @type {DataType}
33+
*/
34+
public get data() {
35+
return this.#data;
36+
}
37+
38+
/**
39+
* @inheritdoc
40+
* @public
41+
* @readonly
42+
* @type {number}
43+
*/
44+
public get size() {
45+
return this.#data.value.size;
46+
}
47+
48+
/**
49+
* @description A privately stored data holder of generic type variable `DataType` for the `Map`.
50+
* @type {DataType}
51+
*/
52+
#data: DataType;
53+
54+
/**
55+
* Creates an instance of `DataMap`.
56+
* @constructor
57+
* @param {?[Key, Value][]} [entries] Initial value for `Map`.
58+
* @param {?DataType} [data] The data store of generic type variable `DataType` for `Map` value.
59+
*/
60+
constructor(
61+
entries?: [Key, Value][],
62+
data?: DataType
63+
) {
64+
if (data) {
65+
this.#data = data;
66+
(Array.isArray(entries) && this.#data.value.size === 0) && entries.forEach(([key, value]) => this.#data.value.set(key, value));
67+
} else {
68+
this.#data = new Data(new Map(entries)) as unknown as DataType;
69+
}
70+
}
71+
72+
/**
73+
* Clears all entries.
74+
* @inheritdoc
75+
* @public
76+
* @returns {this}
77+
*/
78+
public clear(): this {
79+
this.onClear?.(this.#data);
80+
this.#data.value.clear();
81+
return this;
82+
}
83+
84+
/**
85+
* Deletes a value from the `key`.
86+
* @inheritdoc
87+
* @public
88+
* @param {Key} key The key to delete.
89+
* @returns {boolean}
90+
*/
91+
public delete(key: Key): boolean {
92+
return this.#data.value.delete(key);
93+
}
94+
95+
/**
96+
* @inheritdoc
97+
*/
98+
public entries(): IterableIterator<[Key, Value]> {
99+
return this.#data.value.entries();
100+
}
101+
102+
/**
103+
* @inheritdoc
104+
* @public
105+
* @param {(value: Value, key: Key, map: Map<Key, Value>) => void} callbackfn
106+
* @param {?*} [thisArg]
107+
* @returns {this}
108+
*/
109+
public forEach(callbackfn: (value: Value, key: Key, map: Map<Key, Value>) => void, thisArg?: any): this {
110+
this.#data.value.forEach(callbackfn, thisArg);
111+
return this;
112+
}
113+
114+
/**
115+
* @inheritdoc
116+
* @public
117+
* @param {Key} key The key to get the value.
118+
*/
119+
public get(key: Key): Value | undefined {
120+
return this.onGet?.(key, this.#data), this.#data.value.get(key);
121+
}
122+
123+
/**
124+
* @inheritdoc
125+
* @public
126+
* @param {Key} key The key to check.
127+
* @returns {boolean}
128+
*/
129+
public has(key: Key): boolean {
130+
return this.onGet?.(key, this.#data), this.#data.value.has(key);
131+
}
132+
133+
/**
134+
* @inheritdoc
135+
*/
136+
public keys(): MapIterator<Key> {
137+
return this.#data.value.keys();
138+
}
139+
140+
/**
141+
* @inheritdoc
142+
* @public
143+
* @param {Key} key The key under which the `value` set.
144+
* @param {Value} value The value of `Value` type.
145+
* @returns {this} The `this` current instance for chaining.
146+
*/
147+
public set(key: Key, value: Value): this {
148+
this.onSet?.(key, value, this.get(key)!, this.#data);
149+
this.#data.value.set(key, value);
150+
return this;
151+
}
152+
153+
/**
154+
* @inheritdoc
155+
*/
156+
public values(): MapIterator<Value> {
157+
return this.#data.value.values();
158+
}
159+
160+
/**
161+
* @description Hook called when the `Map` is cleared.
162+
* @protected
163+
* @param {DataType} data The data holder.
164+
*/
165+
protected onClear(data: DataType): void {}
166+
167+
/**
168+
* @description Hook called when a value is deleted.
169+
* @protected
170+
* @param {DataType} data The data holder.
171+
*/
172+
protected onDelete(key: Key, data: DataType): void {}
173+
174+
/**
175+
* @description Hook called before the `get` being invoked.
176+
* @protected
177+
* @param {Key} key The key to get the value.
178+
* @param {DataType} data The data holder.
179+
*/
180+
protected onGet(key: Key, data: DataType): void {}
181+
182+
/**
183+
* @description Hook called when a value is added.
184+
* @protected
185+
* @param {key} key The key under which set the `value`.
186+
* @param {Type} value The value to set.
187+
* @param {Type} previousValue The previous value.
188+
* @param {DataType} data The data holder.
189+
*/
190+
protected onSet(key: Key, value: Value, previousValue: Value, data: DataType): void {}
191+
}

src/map/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export { DataMap } from './data-map.class';
2+
export { WeakDataMap } from './weak-data-map.class';

src/map/weak-data-map.class.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Class.
2+
import { DataMap } from './data-map.class';
3+
import { WeakData } from '../lib';
4+
/**
5+
* @description The `WeakDataMap` class is a concrete class that stores data in a static `WeakMap`.
6+
* @export
7+
* @class WeakDataMap
8+
* @template Key
9+
* @template Value
10+
* @extends {DataMap<Key, Value, WeakData<Map<Key, Value>>>}
11+
*/
12+
export class WeakDataMap<Key, Value> extends DataMap<Key, Value, WeakData<Map<Key, Value>>> {
13+
/**
14+
* @description Returns the `string` tag representation of the `WeakDataMap` class when used in `Object.prototype.toString.call(instance)`.
15+
* @public
16+
* @readonly
17+
* @type {string}
18+
*/
19+
public override get [Symbol.toStringTag](): string {
20+
return WeakDataMap.name;
21+
}
22+
23+
/**
24+
* Creates an instance of `WeakDataMap`.
25+
* @constructor
26+
* @param {?[Key, Value][]} [entries]
27+
*/
28+
constructor(entries?: [Key, Value][]) {
29+
super(entries, new WeakData(new Map(entries)));
30+
}
31+
}

src/public-api.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,8 @@ export {
1818
// Basic.
1919
WeakData,
2020
} from './lib';
21+
// Map related.
22+
export {
23+
DataMap,
24+
WeakDataMap,
25+
} from './map';

0 commit comments

Comments
 (0)