@nlozgachev/pipelined 0.20.0 → 0.21.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 +46 -34
- package/dist/{Task-JOnNAaPq.d.mts → Task-CT8iwwuB.d.mts} +76 -2
- package/dist/{Task-BAT6Z6b9.d.ts → Task-GSGtQO1m.d.ts} +76 -2
- package/dist/{chunk-RUDOUVQR.mjs → chunk-2DPG2RDB.mjs} +5 -7
- package/dist/{chunk-AC7RQXWC.mjs → chunk-C3Z56PCR.mjs} +30 -11
- package/dist/chunk-SSZXZTIX.mjs +1398 -0
- package/dist/core.d.mts +597 -105
- package/dist/core.d.ts +597 -105
- package/dist/core.js +882 -88
- package/dist/core.mjs +4 -2
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +911 -98
- package/dist/index.mjs +5 -3
- package/dist/utils.d.mts +1 -1
- package/dist/utils.d.ts +1 -1
- package/dist/utils.js +34 -17
- package/dist/utils.mjs +2 -2
- package/package.json +2 -1
- package/dist/chunk-7COGDULU.mjs +0 -603
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# pipelined
|
|
2
2
|
|
|
3
|
-
[](https://www.npmjs.com/package/@nlozgachev/pipelined)[](https://github.com/nlozgachev/pipelined/actions/workflows/publish.yml)[](https://app.codecov.io/github/nlozgachev/pipelined)[](https://www.typescriptlang.org)
|
|
3
|
+
[](https://www.npmjs.com/package/@nlozgachev/pipelined) [](https://github.com/nlozgachev/pipelined/actions/workflows/publish.yml) [](https://app.codecov.io/github/nlozgachev/pipelined) [](https://www.typescriptlang.org)
|
|
4
4
|
|
|
5
5
|
Opinionated functional abstractions for TypeScript.
|
|
6
6
|
|
|
@@ -23,45 +23,61 @@ Full guides and API reference at **[pipelined.lozgachev.dev](https://pipelined.l
|
|
|
23
23
|
|
|
24
24
|
## Example
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
A careful, production-minded attempt at "fetch with retry, timeout, and cancellation":
|
|
27
27
|
|
|
28
28
|
```ts
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
29
|
+
type UserResult =
|
|
30
|
+
| { ok: true; user: User; }
|
|
31
|
+
| { ok: false; error: "Timeout" | "NetworkError"; };
|
|
32
|
+
|
|
33
|
+
async function fetchUser(
|
|
34
|
+
id: string,
|
|
35
|
+
signal?: AbortSignal,
|
|
36
|
+
): Promise<UserResult> {
|
|
37
|
+
async function attempt(n: number): Promise<UserResult> {
|
|
38
|
+
const controller = new AbortController();
|
|
39
|
+
const timerId = setTimeout(() => controller.abort(), 5000);
|
|
40
|
+
signal?.addEventListener("abort", () => controller.abort(), { once: true });
|
|
41
|
+
|
|
42
|
+
try {
|
|
43
|
+
const res = await fetch(`/users/${id}`, { signal: controller.signal });
|
|
44
|
+
clearTimeout(timerId);
|
|
45
|
+
return { ok: true, user: await res.json() };
|
|
46
|
+
} catch (e) {
|
|
47
|
+
clearTimeout(timerId);
|
|
48
|
+
if ((e as Error).name === "AbortError" && !signal?.aborted) {
|
|
49
|
+
return { ok: false, error: "Timeout" };
|
|
50
|
+
}
|
|
51
|
+
if (n < 3) {
|
|
52
|
+
await new Promise((r) => setTimeout(r, n * 1000));
|
|
53
|
+
return attempt(n + 1);
|
|
54
|
+
}
|
|
55
|
+
return { ok: false, error: "NetworkError" };
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return attempt(1);
|
|
43
59
|
}
|
|
44
60
|
```
|
|
45
61
|
|
|
46
|
-
The
|
|
47
|
-
|
|
48
|
-
|
|
62
|
+
The signal is forwarded by hand. The timeout needs its own controller. Timed-out aborts are
|
|
63
|
+
distinguished from external cancellation by checking `signal?.aborted`. The retry is recursive
|
|
64
|
+
to thread the attempt count.
|
|
49
65
|
|
|
50
66
|
With **pipelined**:
|
|
51
67
|
|
|
52
68
|
```ts
|
|
53
|
-
import { TaskResult } from "@nlozgachev/pipelined/core";
|
|
54
69
|
import { pipe } from "@nlozgachev/pipelined/composition";
|
|
70
|
+
import { Result, TaskResult } from "@nlozgachev/pipelined/core";
|
|
55
71
|
|
|
56
72
|
const fetchUser = (id: string): TaskResult<ApiError, User> =>
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
73
|
+
pipe(
|
|
74
|
+
TaskResult.tryCatch(
|
|
75
|
+
(signal) => fetch(`/users/${id}`, { signal }).then((r) => r.json()),
|
|
76
|
+
(e) => new ApiError(e),
|
|
77
|
+
),
|
|
78
|
+
TaskResult.timeout(5000, () => new ApiError("request timed out")),
|
|
79
|
+
TaskResult.retry({ attempts: 3, backoff: (n) => n * 1000 }),
|
|
80
|
+
);
|
|
65
81
|
```
|
|
66
82
|
|
|
67
83
|
`TaskResult<ApiError, User>` is a lazy function — nothing runs until called. The `AbortSignal`
|
|
@@ -73,9 +89,9 @@ const controller = new AbortController();
|
|
|
73
89
|
const result = await fetchUser("42")(controller.signal);
|
|
74
90
|
|
|
75
91
|
if (Result.isOk(result)) {
|
|
76
|
-
|
|
92
|
+
render(result.value); // User
|
|
77
93
|
} else {
|
|
78
|
-
|
|
94
|
+
showError(result.error); // ApiError, not unknown
|
|
79
95
|
}
|
|
80
96
|
```
|
|
81
97
|
|
|
@@ -106,7 +122,6 @@ share a common environment. Every type follows the same conventions — `map`, `
|
|
|
106
122
|
- **`Reader<R, A>`** — a computation that depends on an environment `R`, supplied once at the
|
|
107
123
|
boundary.
|
|
108
124
|
|
|
109
|
-
|
|
110
125
|
### pipelined/utils
|
|
111
126
|
|
|
112
127
|
Everyday utilities for built-in JS types.
|
|
@@ -133,9 +148,6 @@ have custom implementations that in several cases run faster than the native met
|
|
|
133
148
|
- **`pipe`**, **`flow`**, **`compose`** — function composition.
|
|
134
149
|
- **`curry`** / **`uncurry`**, **`tap`**, **`memoize`**, and other function utilities.
|
|
135
150
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
151
|
## License
|
|
140
152
|
|
|
141
153
|
BSD-3-Clause
|
|
@@ -22,13 +22,17 @@ declare const _deferred: unique symbol;
|
|
|
22
22
|
*/
|
|
23
23
|
type Deferred<A> = {
|
|
24
24
|
readonly [_deferred]: A;
|
|
25
|
-
readonly then: (onfulfilled: (value: A) =>
|
|
25
|
+
readonly then: (onfulfilled: (value: A) => unknown) => void;
|
|
26
26
|
};
|
|
27
27
|
declare namespace Deferred {
|
|
28
28
|
/**
|
|
29
29
|
* Wraps a `Promise` into a `Deferred`, structurally excluding rejection handlers,
|
|
30
30
|
* `.catch()`, `.finally()`, and chainable `.then()`.
|
|
31
31
|
*
|
|
32
|
+
* **Precondition**: `p` must never reject. If `p` rejects, the returned `Deferred` will
|
|
33
|
+
* never resolve — `await`-ing it will hang indefinitely. Use `TaskResult.tryCatch` to
|
|
34
|
+
* handle operations that may fail before converting to a `Deferred`.
|
|
35
|
+
*
|
|
32
36
|
* @example
|
|
33
37
|
* ```ts
|
|
34
38
|
* const d = Deferred.fromPromise(Promise.resolve("hello"));
|
|
@@ -69,6 +73,76 @@ type WithSecond<T> = {
|
|
|
69
73
|
type WithLog<T> = {
|
|
70
74
|
readonly log: ReadonlyArray<T>;
|
|
71
75
|
};
|
|
76
|
+
/** Retry policy for `Op.interpret`. */
|
|
77
|
+
type RetryOptions<E> = {
|
|
78
|
+
readonly attempts: number;
|
|
79
|
+
readonly backoff?: number | ((attempt: number) => number);
|
|
80
|
+
readonly when?: (error: E) => boolean;
|
|
81
|
+
};
|
|
82
|
+
/** Timeout policy for `Op.interpret`. Wraps the entire retry sequence. */
|
|
83
|
+
type TimeoutOptions<E> = {
|
|
84
|
+
readonly ms: number;
|
|
85
|
+
readonly onTimeout: () => E;
|
|
86
|
+
};
|
|
87
|
+
type WithRetry<E> = {
|
|
88
|
+
readonly retry: RetryOptions<E>;
|
|
89
|
+
};
|
|
90
|
+
type WithTimeout<E> = {
|
|
91
|
+
readonly timeout?: TimeoutOptions<E>;
|
|
92
|
+
};
|
|
93
|
+
type WithMs = {
|
|
94
|
+
readonly ms: number;
|
|
95
|
+
};
|
|
96
|
+
/** For `throttled`: also fire on the trailing edge after the cooldown. */
|
|
97
|
+
type WithTrailing = {
|
|
98
|
+
readonly trailing: true;
|
|
99
|
+
};
|
|
100
|
+
/** For `debounced`: also fire on the leading edge (first call). */
|
|
101
|
+
type WithLeading = {
|
|
102
|
+
readonly leading: true;
|
|
103
|
+
};
|
|
104
|
+
/** For `debounced`: maximum ms before the trailing call fires regardless of continued activity. */
|
|
105
|
+
type WithMaxWait = {
|
|
106
|
+
readonly maxWait: number;
|
|
107
|
+
};
|
|
108
|
+
type WithN = {
|
|
109
|
+
readonly n: number;
|
|
110
|
+
};
|
|
111
|
+
/**
|
|
112
|
+
* `O` is a string literal (or union of literals) representing the overflow value.
|
|
113
|
+
* The generic lets overload signatures discriminate on the specific value:
|
|
114
|
+
* `WithOverflow<"drop">` → `{ overflow: "drop" }`
|
|
115
|
+
* `WithOverflow<"replace-last">` → `{ overflow: "replace-last" }`
|
|
116
|
+
* Used by both `concurrent` (`"drop" | "queue"`) and `queue` (`"drop" | "replace-last"`).
|
|
117
|
+
* `extends string` prevents `WithOverflow<42>` from being valid.
|
|
118
|
+
*/
|
|
119
|
+
type WithOverflow<O extends string> = {
|
|
120
|
+
readonly overflow: O;
|
|
121
|
+
};
|
|
122
|
+
type WithMaxSize = {
|
|
123
|
+
readonly maxSize: number;
|
|
124
|
+
};
|
|
125
|
+
type WithConcurrency = {
|
|
126
|
+
readonly concurrency?: number;
|
|
127
|
+
};
|
|
128
|
+
type WithDedupe<I> = {
|
|
129
|
+
readonly dedupe: (a: I, b: I) => boolean;
|
|
130
|
+
};
|
|
131
|
+
type WithSize = {
|
|
132
|
+
readonly size?: number;
|
|
133
|
+
};
|
|
134
|
+
type WithCooldown = {
|
|
135
|
+
readonly cooldown?: number;
|
|
136
|
+
};
|
|
137
|
+
type WithMinInterval = {
|
|
138
|
+
readonly minInterval?: number;
|
|
139
|
+
};
|
|
140
|
+
type WithKey<I, K> = {
|
|
141
|
+
readonly key: (input: I) => K;
|
|
142
|
+
};
|
|
143
|
+
type WithPerKey<S extends string> = {
|
|
144
|
+
readonly perKey: S;
|
|
145
|
+
};
|
|
72
146
|
|
|
73
147
|
type Ok<A> = WithKind<"Ok"> & WithValue<A>;
|
|
74
148
|
type Err<E> = WithKind<"Error"> & WithError<E>;
|
|
@@ -703,4 +777,4 @@ declare namespace Task {
|
|
|
703
777
|
};
|
|
704
778
|
}
|
|
705
779
|
|
|
706
|
-
export { Deferred as D, type Err as E, Maybe as M, type None as N, type Ok as O, Result as R, type Some as S, Task as T, type WithValue as W, type WithLog as a, type WithKind as b, type WithError as c, type
|
|
780
|
+
export { Deferred as D, type Err as E, Maybe as M, type None as N, type Ok as O, Result as R, type Some as S, Task as T, type WithValue as W, type WithLog as a, type WithKind as b, type WithError as c, type RetryOptions as d, type TimeoutOptions as e, type WithMs as f, type WithTrailing as g, type WithRetry as h, type WithTimeout as i, type WithLeading as j, type WithMaxWait as k, type WithN as l, type WithOverflow as m, type WithKey as n, type WithPerKey as o, type WithMinInterval as p, type WithCooldown as q, type WithMaxSize as r, type WithDedupe as s, type WithConcurrency as t, type WithSize as u, type WithErrors as v, type WithFirst as w, type WithSecond as x };
|
|
@@ -22,13 +22,17 @@ declare const _deferred: unique symbol;
|
|
|
22
22
|
*/
|
|
23
23
|
type Deferred<A> = {
|
|
24
24
|
readonly [_deferred]: A;
|
|
25
|
-
readonly then: (onfulfilled: (value: A) =>
|
|
25
|
+
readonly then: (onfulfilled: (value: A) => unknown) => void;
|
|
26
26
|
};
|
|
27
27
|
declare namespace Deferred {
|
|
28
28
|
/**
|
|
29
29
|
* Wraps a `Promise` into a `Deferred`, structurally excluding rejection handlers,
|
|
30
30
|
* `.catch()`, `.finally()`, and chainable `.then()`.
|
|
31
31
|
*
|
|
32
|
+
* **Precondition**: `p` must never reject. If `p` rejects, the returned `Deferred` will
|
|
33
|
+
* never resolve — `await`-ing it will hang indefinitely. Use `TaskResult.tryCatch` to
|
|
34
|
+
* handle operations that may fail before converting to a `Deferred`.
|
|
35
|
+
*
|
|
32
36
|
* @example
|
|
33
37
|
* ```ts
|
|
34
38
|
* const d = Deferred.fromPromise(Promise.resolve("hello"));
|
|
@@ -69,6 +73,76 @@ type WithSecond<T> = {
|
|
|
69
73
|
type WithLog<T> = {
|
|
70
74
|
readonly log: ReadonlyArray<T>;
|
|
71
75
|
};
|
|
76
|
+
/** Retry policy for `Op.interpret`. */
|
|
77
|
+
type RetryOptions<E> = {
|
|
78
|
+
readonly attempts: number;
|
|
79
|
+
readonly backoff?: number | ((attempt: number) => number);
|
|
80
|
+
readonly when?: (error: E) => boolean;
|
|
81
|
+
};
|
|
82
|
+
/** Timeout policy for `Op.interpret`. Wraps the entire retry sequence. */
|
|
83
|
+
type TimeoutOptions<E> = {
|
|
84
|
+
readonly ms: number;
|
|
85
|
+
readonly onTimeout: () => E;
|
|
86
|
+
};
|
|
87
|
+
type WithRetry<E> = {
|
|
88
|
+
readonly retry: RetryOptions<E>;
|
|
89
|
+
};
|
|
90
|
+
type WithTimeout<E> = {
|
|
91
|
+
readonly timeout?: TimeoutOptions<E>;
|
|
92
|
+
};
|
|
93
|
+
type WithMs = {
|
|
94
|
+
readonly ms: number;
|
|
95
|
+
};
|
|
96
|
+
/** For `throttled`: also fire on the trailing edge after the cooldown. */
|
|
97
|
+
type WithTrailing = {
|
|
98
|
+
readonly trailing: true;
|
|
99
|
+
};
|
|
100
|
+
/** For `debounced`: also fire on the leading edge (first call). */
|
|
101
|
+
type WithLeading = {
|
|
102
|
+
readonly leading: true;
|
|
103
|
+
};
|
|
104
|
+
/** For `debounced`: maximum ms before the trailing call fires regardless of continued activity. */
|
|
105
|
+
type WithMaxWait = {
|
|
106
|
+
readonly maxWait: number;
|
|
107
|
+
};
|
|
108
|
+
type WithN = {
|
|
109
|
+
readonly n: number;
|
|
110
|
+
};
|
|
111
|
+
/**
|
|
112
|
+
* `O` is a string literal (or union of literals) representing the overflow value.
|
|
113
|
+
* The generic lets overload signatures discriminate on the specific value:
|
|
114
|
+
* `WithOverflow<"drop">` → `{ overflow: "drop" }`
|
|
115
|
+
* `WithOverflow<"replace-last">` → `{ overflow: "replace-last" }`
|
|
116
|
+
* Used by both `concurrent` (`"drop" | "queue"`) and `queue` (`"drop" | "replace-last"`).
|
|
117
|
+
* `extends string` prevents `WithOverflow<42>` from being valid.
|
|
118
|
+
*/
|
|
119
|
+
type WithOverflow<O extends string> = {
|
|
120
|
+
readonly overflow: O;
|
|
121
|
+
};
|
|
122
|
+
type WithMaxSize = {
|
|
123
|
+
readonly maxSize: number;
|
|
124
|
+
};
|
|
125
|
+
type WithConcurrency = {
|
|
126
|
+
readonly concurrency?: number;
|
|
127
|
+
};
|
|
128
|
+
type WithDedupe<I> = {
|
|
129
|
+
readonly dedupe: (a: I, b: I) => boolean;
|
|
130
|
+
};
|
|
131
|
+
type WithSize = {
|
|
132
|
+
readonly size?: number;
|
|
133
|
+
};
|
|
134
|
+
type WithCooldown = {
|
|
135
|
+
readonly cooldown?: number;
|
|
136
|
+
};
|
|
137
|
+
type WithMinInterval = {
|
|
138
|
+
readonly minInterval?: number;
|
|
139
|
+
};
|
|
140
|
+
type WithKey<I, K> = {
|
|
141
|
+
readonly key: (input: I) => K;
|
|
142
|
+
};
|
|
143
|
+
type WithPerKey<S extends string> = {
|
|
144
|
+
readonly perKey: S;
|
|
145
|
+
};
|
|
72
146
|
|
|
73
147
|
type Ok<A> = WithKind<"Ok"> & WithValue<A>;
|
|
74
148
|
type Err<E> = WithKind<"Error"> & WithError<E>;
|
|
@@ -703,4 +777,4 @@ declare namespace Task {
|
|
|
703
777
|
};
|
|
704
778
|
}
|
|
705
779
|
|
|
706
|
-
export { Deferred as D, type Err as E, Maybe as M, type None as N, type Ok as O, Result as R, type Some as S, Task as T, type WithValue as W, type WithLog as a, type WithKind as b, type WithError as c, type
|
|
780
|
+
export { Deferred as D, type Err as E, Maybe as M, type None as N, type Ok as O, Result as R, type Some as S, Task as T, type WithValue as W, type WithLog as a, type WithKind as b, type WithError as c, type RetryOptions as d, type TimeoutOptions as e, type WithMs as f, type WithTrailing as g, type WithRetry as h, type WithTimeout as i, type WithLeading as j, type WithMaxWait as k, type WithN as l, type WithOverflow as m, type WithKey as n, type WithPerKey as o, type WithMinInterval as p, type WithCooldown as q, type WithMaxSize as r, type WithDedupe as s, type WithConcurrency as t, type WithSize as u, type WithErrors as v, type WithFirst as w, type WithSecond as x };
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
// src/Core/Deferred.ts
|
|
2
|
-
var _store = /* @__PURE__ */ new WeakMap();
|
|
3
2
|
var Deferred;
|
|
4
3
|
((Deferred2) => {
|
|
5
|
-
Deferred2.fromPromise = (p) =>
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
Deferred2.toPromise = (d) => _store.get(d) ?? new Promise((resolve) => d.then(resolve));
|
|
4
|
+
Deferred2.fromPromise = (p) => (
|
|
5
|
+
// eslint-disable-next-line unicorn/no-thenable -- Deferred is intentionally thenable; it is the mechanism that makes Task awaitable
|
|
6
|
+
{ then: ((f) => p.then(f)) }
|
|
7
|
+
);
|
|
8
|
+
Deferred2.toPromise = (d) => new Promise((resolve) => d.then(resolve));
|
|
11
9
|
})(Deferred || (Deferred = {}));
|
|
12
10
|
|
|
13
11
|
// src/Core/Maybe.ts
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
Maybe,
|
|
4
4
|
Result,
|
|
5
5
|
Task
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-2DPG2RDB.mjs";
|
|
7
7
|
import {
|
|
8
8
|
isNonEmptyList
|
|
9
9
|
} from "./chunk-DBIC62UV.mjs";
|
|
@@ -364,7 +364,7 @@ var Rec;
|
|
|
364
364
|
const vals = Object.values(data);
|
|
365
365
|
const result = {};
|
|
366
366
|
for (let i = 0; i < keys2.length; i++) {
|
|
367
|
-
result
|
|
367
|
+
Object.defineProperty(result, keys2[i], { value: f(vals[i]), writable: true, enumerable: true, configurable: true });
|
|
368
368
|
}
|
|
369
369
|
return result;
|
|
370
370
|
};
|
|
@@ -373,21 +373,30 @@ var Rec;
|
|
|
373
373
|
const vals = Object.values(data);
|
|
374
374
|
const result = {};
|
|
375
375
|
for (let i = 0; i < keys2.length; i++) {
|
|
376
|
-
result
|
|
376
|
+
Object.defineProperty(result, keys2[i], {
|
|
377
|
+
value: f(keys2[i], vals[i]),
|
|
378
|
+
writable: true,
|
|
379
|
+
enumerable: true,
|
|
380
|
+
configurable: true
|
|
381
|
+
});
|
|
377
382
|
}
|
|
378
383
|
return result;
|
|
379
384
|
};
|
|
380
385
|
Rec2.filter = (predicate) => (data) => {
|
|
381
386
|
const result = {};
|
|
382
387
|
for (const [k, v] of Object.entries(data)) {
|
|
383
|
-
if (predicate(v))
|
|
388
|
+
if (predicate(v)) {
|
|
389
|
+
Object.defineProperty(result, k, { value: v, writable: true, enumerable: true, configurable: true });
|
|
390
|
+
}
|
|
384
391
|
}
|
|
385
392
|
return result;
|
|
386
393
|
};
|
|
387
394
|
Rec2.filterWithKey = (predicate) => (data) => {
|
|
388
395
|
const result = {};
|
|
389
396
|
for (const [k, v] of Object.entries(data)) {
|
|
390
|
-
if (predicate(k, v))
|
|
397
|
+
if (predicate(k, v)) {
|
|
398
|
+
Object.defineProperty(result, k, { value: v, writable: true, enumerable: true, configurable: true });
|
|
399
|
+
}
|
|
391
400
|
}
|
|
392
401
|
return result;
|
|
393
402
|
};
|
|
@@ -400,8 +409,11 @@ var Rec;
|
|
|
400
409
|
const result = {};
|
|
401
410
|
for (const item of items) {
|
|
402
411
|
const key = keyFn(item);
|
|
403
|
-
if (
|
|
404
|
-
|
|
412
|
+
if (Object.hasOwn(result, key)) {
|
|
413
|
+
result[key].push(item);
|
|
414
|
+
} else {
|
|
415
|
+
Object.defineProperty(result, key, { value: [item], writable: true, enumerable: true, configurable: true });
|
|
416
|
+
}
|
|
405
417
|
}
|
|
406
418
|
return result;
|
|
407
419
|
};
|
|
@@ -409,7 +421,7 @@ var Rec;
|
|
|
409
421
|
const result = {};
|
|
410
422
|
for (const key of pickedKeys) {
|
|
411
423
|
if (Object.hasOwn(data, key)) {
|
|
412
|
-
result
|
|
424
|
+
Object.defineProperty(result, key, { value: data[key], writable: true, enumerable: true, configurable: true });
|
|
413
425
|
}
|
|
414
426
|
}
|
|
415
427
|
return result;
|
|
@@ -419,7 +431,12 @@ var Rec;
|
|
|
419
431
|
const result = {};
|
|
420
432
|
for (const key of Object.keys(data)) {
|
|
421
433
|
if (!omitSet.has(key)) {
|
|
422
|
-
result
|
|
434
|
+
Object.defineProperty(result, key, {
|
|
435
|
+
value: data[key],
|
|
436
|
+
writable: true,
|
|
437
|
+
enumerable: true,
|
|
438
|
+
configurable: true
|
|
439
|
+
});
|
|
423
440
|
}
|
|
424
441
|
}
|
|
425
442
|
return result;
|
|
@@ -433,14 +450,16 @@ var Rec;
|
|
|
433
450
|
Rec2.mapKeys = (f) => (data) => {
|
|
434
451
|
const result = {};
|
|
435
452
|
for (const [k, v] of Object.entries(data)) {
|
|
436
|
-
result
|
|
453
|
+
Object.defineProperty(result, f(k), { value: v, writable: true, enumerable: true, configurable: true });
|
|
437
454
|
}
|
|
438
455
|
return result;
|
|
439
456
|
};
|
|
440
457
|
Rec2.compact = (data) => {
|
|
441
458
|
const result = {};
|
|
442
459
|
for (const [k, v] of Object.entries(data)) {
|
|
443
|
-
if (v.kind === "Some")
|
|
460
|
+
if (v.kind === "Some") {
|
|
461
|
+
Object.defineProperty(result, k, { value: v.value, writable: true, enumerable: true, configurable: true });
|
|
462
|
+
}
|
|
444
463
|
}
|
|
445
464
|
return result;
|
|
446
465
|
};
|