@the-w1zard/dx 1.0.8 → 1.0.9

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/src/object.ts DELETED
@@ -1,291 +0,0 @@
1
-
2
-
3
- export class O2I {
4
- static isEmpty(value: object): B {
5
- return Reflect.ownKeys(value).length === 0;
6
- }
7
- static isNotEmpty(value: object): B {
8
- return Reflect.ownKeys(value).length !== 0;
9
- }
10
- static size(value: object): N {
11
- return Reflect.ownKeys(value).length as N;
12
- }
13
- static isPlainObject(value: unknown): B {
14
- if (value === null || typeof value !== "object") return false;
15
- const prototype = Object.getPrototypeOf(value);
16
- return prototype === Object.prototype || prototype === null;
17
- }
18
- static isObject(value: unknown): B {
19
- return value !== null && typeof value === "object";
20
- }
21
- static get<X = unknown>(
22
- value: unknown,
23
- path: string | readonly PropertyKey[],
24
- fallback?: X
25
- ): unknown | X {
26
- const parts: readonly PropertyKey[] = typeof path === "string" ? path.split(".") : path;
27
- let current = value;
28
-
29
- for (const key of parts) {
30
- if (current === null || (typeof current !== "object" && typeof current !== "function")) {
31
- return fallback;
32
- }
33
- current = (current as Record<PropertyKey, unknown>)[key];
34
- }
35
-
36
- return current === undefined ? fallback : current;
37
- }
38
- static getOr<X>(value: unknown, path: string | readonly PropertyKey[], fallback: X): X {
39
- return this.get(value, path, fallback) as X;
40
- }
41
- static set<T extends object>(value: T, path: string | readonly PropertyKey[], next: unknown): T {
42
- const parts: readonly PropertyKey[] = typeof path === "string" ? path.split(".") : path;
43
- if (!parts.length) return value;
44
-
45
- let current = value as Record<PropertyKey, unknown>;
46
-
47
- for (let i = 0; i < parts.length - 1; i++) {
48
- const key = parts[i];
49
- const child = current[key];
50
-
51
- if (child === null || (typeof child !== "object" && typeof child !== "function")) {
52
- current[key] = {};
53
- }
54
-
55
- current = current[key] as Record<PropertyKey, unknown>;
56
- }
57
-
58
- current[parts[parts.length - 1]] = next;
59
- return value;
60
- }
61
- static unset(value: object, path: string | readonly PropertyKey[]): B {
62
- const parts: readonly PropertyKey[] = typeof path === "string" ? path.split(".") : path;
63
- if (!parts.length) return false;
64
-
65
- let current = value as Record<PropertyKey, unknown>;
66
-
67
- for (let i = 0; i < parts.length - 1; i++) {
68
- const child = current[parts[i]];
69
- if (child === null || typeof child !== "object") return false;
70
- current = child as Record<PropertyKey, unknown>;
71
- }
72
-
73
- return Reflect.deleteProperty(current, parts[parts.length - 1]);
74
- }
75
- static hasPath(value: unknown, path: string | readonly PropertyKey[]): B {
76
- const parts: readonly PropertyKey[] = typeof path === "string" ? path.split(".") : path;
77
- let current = value;
78
-
79
- for (const key of parts) {
80
- if (current === null || (typeof current !== "object" && typeof current !== "function")) {
81
- return false;
82
- }
83
- if (!Object.prototype.hasOwnProperty.call(current, key)) return false;
84
- current = (current as Record<PropertyKey, unknown>)[key];
85
- }
86
-
87
- return true;
88
- }
89
- static clone<T>(value: T): T {
90
- if (value === null || typeof value !== "object") return value;
91
- if (Array.isArray(value)) return value.slice() as T;
92
- return Object.assign(Object.create(Object.getPrototypeOf(value)), value);
93
- }
94
- static deepClone<T>(value: T): T {
95
- return structuredClone(value);
96
- }
97
- static deepMerge<T extends object, U extends object>(target: T, source: U): T & U {
98
- const result = { ...target } as Record<PropertyKey, unknown>;
99
-
100
- for (const key of Reflect.ownKeys(source)) {
101
- const incoming = source[key as keyof U];
102
- const current = result[key];
103
-
104
- result[key] =
105
- this.isPlainObject(current) && this.isPlainObject(incoming)
106
- ? this.deepMerge(
107
- current as Record<PropertyKey, unknown>,
108
- incoming as Record<PropertyKey, unknown>
109
- )
110
- : incoming;
111
- }
112
-
113
- return result as T & U;
114
- }
115
- static defaults<T extends object, U extends object>(target: T, defaults: U): T & U {
116
- return Object.assign({}, defaults, target) as T & U;
117
- }
118
- static getOrCreate<T extends object, K extends PropertyKey, X>(
119
- value: T,
120
- key: K,
121
- create: () => X
122
- ): T & Record<K, X> {
123
- const object = value as T & Record<K, X>;
124
-
125
- if (!Object.prototype.hasOwnProperty.call(object, key) || object[key] === undefined) {
126
- object[key] = create() as (T & Record<K, X>)[K];
127
- }
128
-
129
- return object;
130
- }
131
- static pick<T extends object, K extends keyof T>(value: T, keys: readonly K[]): Pick<T, K> {
132
- const result = {} as Pick<T, K>;
133
-
134
- for (const key of keys) {
135
- if (Object.prototype.hasOwnProperty.call(value, key)) result[key] = value[key];
136
- }
137
-
138
- return result;
139
- }
140
- static omit<T extends object, K extends keyof T>(value: T, keys: readonly K[]): Omit<T, K> {
141
- const result = { ...value };
142
-
143
- for (const key of keys) delete result[key];
144
-
145
- return result;
146
- }
147
- static pickBy<T extends object>(
148
- value: T,
149
- predicate: (value: T[keyof T], key: keyof T) => B
150
- ): Partial<T> {
151
- const result: Partial<T> = {};
152
-
153
- for (const key of Object.keys(value) as (keyof T)[]) {
154
- if (predicate(value[key], key)) result[key] = value[key];
155
- }
156
-
157
- return result;
158
- }
159
- static omitBy<T extends object>(
160
- value: T,
161
- predicate: (value: T[keyof T], key: keyof T) => B
162
- ): Partial<T> {
163
- const result: Partial<T> = {};
164
-
165
- for (const key of Object.keys(value) as (keyof T)[]) {
166
- if (!predicate(value[key], key)) result[key] = value[key];
167
- }
168
-
169
- return result;
170
- }
171
- static mapKeys<T extends object, K extends PropertyKey>(
172
- value: T,
173
- mapper: (key: keyof T, value: T[keyof T]) => K
174
- ): Partial<Record<K, T[keyof T]>> {
175
- const result: Partial<Record<K, T[keyof T]>> = {};
176
-
177
- for (const key of Object.keys(value) as (keyof T)[]) {
178
- result[mapper(key, value[key])] = value[key];
179
- }
180
-
181
- return result;
182
- }
183
- static mapValues<T extends object, X>(
184
- value: T,
185
- mapper: (value: T[keyof T], key: keyof T) => X
186
- ): { [K in keyof T]: X } {
187
- const result = {} as { [K in keyof T]: X };
188
-
189
- for (const key of Object.keys(value) as (keyof T)[]) {
190
- result[key] = mapper(value[key], key);
191
- }
192
-
193
- return result;
194
- }
195
- static mapEntries<T extends object, K extends PropertyKey, X>(
196
- value: T,
197
- mapper: (entry: [keyof T, T[keyof T]]) => readonly [K, X]
198
- ): Partial<Record<K, X>> {
199
- const result: Partial<Record<K, X>> = {};
200
-
201
- for (const key of Object.keys(value) as (keyof T)[]) {
202
- const [nextKey, nextValue] = mapper([key, value[key]]);
203
- result[nextKey] = nextValue;
204
- }
205
-
206
- return result;
207
- }
208
- static filter<T extends object>(
209
- value: T,
210
- predicate: (value: T[keyof T], key: keyof T) => B
211
- ): Partial<T> {
212
- return this.pickBy(value, predicate);
213
- }
214
- static isEqual(first: unknown, second: unknown): B {
215
- if (Object.is(first, second)) return true;
216
-
217
- if (
218
- first === null || second === null ||
219
- typeof first !== "object" || typeof second !== "object"
220
- ) {
221
- return false;
222
- }
223
-
224
- if (first instanceof Date && second instanceof Date) {
225
- return first.getTime() === second.getTime();
226
- }
227
-
228
- if (Array.isArray(first) || Array.isArray(second)) {
229
- return Array.isArray(first) && Array.isArray(second) &&
230
- first.length === second.length &&
231
- first.every((value, index) => this.isEqual(value, second[index]));
232
- }
233
-
234
- const firstKeys = Reflect.ownKeys(first);
235
- const secondKeys = Reflect.ownKeys(second);
236
-
237
- return firstKeys.length === secondKeys.length &&
238
- firstKeys.every(key =>
239
- secondKeys.includes(key) &&
240
- this.isEqual(
241
- (first as Record<PropertyKey, unknown>)[key],
242
- (second as Record<PropertyKey, unknown>)[key]
243
- )
244
- );
245
- }
246
- static isShallowEqual(first: object, second: object): B {
247
- if (Object.is(first, second)) return true;
248
-
249
- const firstKeys = Reflect.ownKeys(first);
250
- const secondKeys = Reflect.ownKeys(second);
251
-
252
- return firstKeys.length === secondKeys.length &&
253
- firstKeys.every(key =>
254
- secondKeys.includes(key) &&
255
- Object.is(
256
- (first as Record<PropertyKey, unknown>)[key],
257
- (second as Record<PropertyKey, unknown>)[key]
258
- )
259
- );
260
- }
261
- static hasAll<T extends object>(value: T, keys: readonly PropertyKey[]): B {
262
- return keys.every(key => Object.prototype.hasOwnProperty.call(value, key));
263
- }
264
- static hasAny<T extends object>(value: T, keys: readonly PropertyKey[]): B {
265
- return keys.some(key => Object.prototype.hasOwnProperty.call(value, key));
266
- }
267
- static assertKeys<T extends object>(value: T, keys: readonly PropertyKey[]): asserts value is T {
268
- const missing = keys.filter(key => !Object.prototype.hasOwnProperty.call(value, key));
269
-
270
- if (missing.length) {
271
- throw new TypeError(`Missing required keys: ${missing.map(String).join(", ")}`);
272
- }
273
- }
274
- static with<T extends object, K extends keyof T>(value: T, key: K, next: T[K]): T {
275
- return { ...value, [key]: next };
276
- }
277
- static without<T extends object, K extends keyof T>(value: T, key: K): Omit<T, K> {
278
- const result = { ...value };
279
- delete result[key];
280
- return result;
281
- }
282
- static update<T extends object, K extends keyof T>(
283
- value: T,
284
- key: K,
285
- updater: (current: T[K]) => T[K]
286
- ): T {
287
- return { ...value, [key]: updater(value[key]) };
288
- }
289
- }
290
-
291
- globalThis.O2 = O2I;
package/src/promise.js DELETED
@@ -1,206 +0,0 @@
1
- export class P2I extends Promise {
2
- #createdAt = Date.now();
3
- #status = "pending";
4
- #val;
5
- #err;
6
- #settledAt;
7
- #label;
8
- constructor(executor) {
9
- super(executor);
10
- super.then((v) => { this.#status = "fulfilled"; this.#val = v; this.#settledAt = Date.now(); }, (e) => { this.#status = "rejected"; this.#err = e; this.#settledAt = Date.now(); });
11
- }
12
- static get [Symbol.species]() {
13
- return P2I;
14
- }
15
- then(onfulfilled, onrejected) {
16
- return super.then(onfulfilled, onrejected);
17
- }
18
- catch(onrejected) {
19
- return super.catch(onrejected);
20
- }
21
- finally(onfinally) {
22
- return super.finally(onfinally);
23
- }
24
- // [STATUS]
25
- // ══════════════════════════════════════════════════════════════════════════════════════════════════════
26
- status() { return this.#status; }
27
- isPending() { return this.#status === "pending"; }
28
- isFulfilled() { return this.#status === "fulfilled"; }
29
- isRejected() { return this.#status === "rejected"; }
30
- value() { return this.#status === "fulfilled" ? this.#val : undefined; }
31
- error() { return this.#status === "rejected" ? this.#err : undefined; }
32
- elapsed() { return this.#settledAt ? (this.#settledAt - this.#createdAt) : undefined; }
33
- static resolve(value) {
34
- return new P2I(resolve => resolve(value));
35
- }
36
- static reject(reason) {
37
- return new P2I((_, reject) => reject(reason));
38
- }
39
- static all(values) {
40
- return new P2I((resolve, reject) => {
41
- Promise.all(values).then(resolve, reject);
42
- });
43
- }
44
- static allSettled(values) {
45
- return new P2I((resolve, reject) => {
46
- Promise.allSettled(values).then(resolve, reject);
47
- });
48
- }
49
- static race(values) {
50
- return new P2I((resolve, reject) => {
51
- Promise.race(values).then(resolve, reject);
52
- });
53
- }
54
- static any(values) {
55
- return new P2I((resolve, reject) => {
56
- Promise.any(values).then(resolve, reject);
57
- });
58
- }
59
- static retry(fn, times = 3, delay = 0) {
60
- const run = (remaining) => P2I.try(fn).catch(error => {
61
- if (remaining <= 0)
62
- throw error;
63
- return new P2I(resolve => {
64
- if (delay > 0)
65
- setTimeout(resolve, delay);
66
- else
67
- resolve();
68
- }).then(() => run(remaining - 1));
69
- });
70
- return run(times);
71
- }
72
- static deferred() {
73
- let resolve;
74
- let reject;
75
- const promise = new P2I((res, rej) => {
76
- resolve = res;
77
- reject = rej;
78
- });
79
- return { promise, resolve, reject };
80
- }
81
- static try(fn) {
82
- return new P2I((resolve, reject) => {
83
- try {
84
- resolve(fn());
85
- }
86
- catch (error) {
87
- reject(error);
88
- }
89
- });
90
- }
91
- // [CONCURRENCY]
92
- // ══════════════════════════════════════════════════════════════════════════════════════════════════════
93
- static sleep(ms) {
94
- return new P2I(resolve => setTimeout(resolve, ms));
95
- }
96
- static fromCallback(fn) {
97
- return new P2I((resolve, reject) => {
98
- fn((err, value) => {
99
- if (err)
100
- reject(err);
101
- else
102
- resolve(value);
103
- });
104
- });
105
- }
106
- static mapLimit(items, limit, fn) {
107
- return new P2I((resolve, reject) => {
108
- const results = new Array(items.length);
109
- let next = 0;
110
- let active = 0;
111
- let done = 0;
112
- let failed = false;
113
- const run = () => {
114
- if (failed)
115
- return;
116
- if (done === items.length) {
117
- resolve(results);
118
- return;
119
- }
120
- while (active < limit && next < items.length) {
121
- const i = next++;
122
- active++;
123
- P2I.try(() => fn(items[i], i)).then((v) => { results[i] = v; active--; done++; run(); }, (e) => { failed = true; reject(e); });
124
- }
125
- };
126
- run();
127
- });
128
- }
129
- static series(fns) {
130
- return fns.reduce((acc, fn) => acc.then(results => P2I.resolve(fn()).then(v => [...results, v])), P2I.resolve([]));
131
- }
132
- tap(fn) {
133
- return this.then(value => P2I.resolve(fn(value)).then(() => value));
134
- }
135
- tapError(fn) {
136
- return this.catch(error => P2I.resolve(fn(error)).then(() => {
137
- throw error;
138
- }));
139
- }
140
- recover(fn) {
141
- return this.catch(fn);
142
- }
143
- fallback(value) {
144
- return this.catch(() => value);
145
- }
146
- timeout(ms, error = new Error("Promise timed out")) {
147
- return new P2I((resolve, reject) => {
148
- const timer = setTimeout(() => reject(error), ms);
149
- this.then(value => {
150
- clearTimeout(timer);
151
- resolve(value);
152
- }, reason => {
153
- clearTimeout(timer);
154
- reject(reason);
155
- });
156
- });
157
- }
158
- delay(ms) {
159
- return this.then(value => new P2I(resolve => setTimeout(() => resolve(value), ms)));
160
- }
161
- withDeadline(deadline, error = new Error("Deadline exceeded")) {
162
- return this.timeout(Math.max(0, deadline - Date.now()), error);
163
- }
164
- map(fn) {
165
- return this.then(fn);
166
- }
167
- flatMap(fn) {
168
- return this.then(fn);
169
- }
170
- or(other) {
171
- return this.catch(() => other);
172
- }
173
- and(other) {
174
- return this.then(value => P2I.resolve(other).then(result => [value, result]));
175
- }
176
- zip(other) {
177
- return this.and(other);
178
- }
179
- unwrap() {
180
- return this;
181
- }
182
- toResult() {
183
- return this.then(value => ({ ok: true, value }), error => ({ ok: false, error: error }));
184
- }
185
- onResolve(fn) {
186
- return this.tap(fn);
187
- }
188
- onReject(fn) {
189
- return this.tapError(fn);
190
- }
191
- finallyDo(fn) {
192
- return this.finally(fn);
193
- }
194
- // [DEBUG]
195
- // ══════════════════════════════════════════════════════════════════════════════════════════════════════
196
- $label(name) {
197
- this.#label = name;
198
- return this;
199
- }
200
- $debug() {
201
- const tag = this.#label ? `:${this.#label}` : "";
202
- super.then(v => console.log(`[P2${tag}] ✓ resolved`, v, `(${this.elapsed()}ms)`), e => console.log(`[P2${tag}] ✗ rejected`, e, `(${this.elapsed()}ms)`));
203
- return this;
204
- }
205
- }
206
- globalThis.P2 = P2I;