nalloc 0.0.1
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 +282 -0
- package/build/devtools.cjs +79 -0
- package/build/devtools.cjs.map +1 -0
- package/build/devtools.d.ts +82 -0
- package/build/devtools.js +43 -0
- package/build/devtools.js.map +1 -0
- package/build/index.cjs +76 -0
- package/build/index.cjs.map +1 -0
- package/build/index.d.ts +4 -0
- package/build/index.js +5 -0
- package/build/index.js.map +1 -0
- package/build/option.cjs +279 -0
- package/build/option.cjs.map +1 -0
- package/build/option.d.ts +356 -0
- package/build/option.js +157 -0
- package/build/option.js.map +1 -0
- package/build/result.cjs +381 -0
- package/build/result.cjs.map +1 -0
- package/build/result.d.ts +442 -0
- package/build/result.js +229 -0
- package/build/result.js.map +1 -0
- package/build/safe.cjs +88 -0
- package/build/safe.cjs.map +1 -0
- package/build/safe.d.ts +29 -0
- package/build/safe.js +18 -0
- package/build/safe.js.map +1 -0
- package/build/testing.cjs +111 -0
- package/build/testing.cjs.map +1 -0
- package/build/testing.d.ts +85 -0
- package/build/testing.js +81 -0
- package/build/testing.js.map +1 -0
- package/build/types.cjs +78 -0
- package/build/types.cjs.map +1 -0
- package/build/types.d.ts +137 -0
- package/build/types.js +36 -0
- package/build/types.js.map +1 -0
- package/build/unsafe.cjs +82 -0
- package/build/unsafe.cjs.map +1 -0
- package/build/unsafe.d.ts +27 -0
- package/build/unsafe.js +11 -0
- package/build/unsafe.js.map +1 -0
- package/package.json +93 -0
- package/src/__tests__/index.ts +13 -0
- package/src/__tests__/option.ts +610 -0
- package/src/__tests__/option.types.ts +120 -0
- package/src/__tests__/result.ts +721 -0
- package/src/__tests__/result.types.ts +249 -0
- package/src/__tests__/safe.ts +24 -0
- package/src/__tests__/tooling.ts +86 -0
- package/src/__tests__/unsafe.ts +24 -0
- package/src/devtools.ts +97 -0
- package/src/index.ts +18 -0
- package/src/option.ts +510 -0
- package/src/result.ts +676 -0
- package/src/safe.ts +58 -0
- package/src/testing.ts +159 -0
- package/src/types.ts +201 -0
- package/src/unsafe.ts +47 -0
package/README.md
ADDED
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
# nalloc
|
|
2
|
+
|
|
3
|
+
**Rust-like safety at JavaScript speed.**
|
|
4
|
+
|
|
5
|
+
Type-safe `Option` and `Result` for TypeScript with near-zero allocations for extreme performance.
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/nalloc)
|
|
8
|
+
[](https://www.npmjs.com/package/nalloc)
|
|
9
|
+
|
|
10
|
+
## Why nalloc?
|
|
11
|
+
|
|
12
|
+
Most Option/Result libraries wrap every value in an object. nalloc doesn't.
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
Other libraries: Some(42) --> { _tag: 'Some', value: 42 } // allocates
|
|
16
|
+
nalloc: Some(42) --> 42 // zero allocation
|
|
17
|
+
|
|
18
|
+
Other libraries: Ok(data) --> { _tag: 'Ok', value: data } // allocates
|
|
19
|
+
nalloc: Ok(data) --> data // zero allocation
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
- **Rust-like types** - `Option<T>` and `Result<T, E>` with full pattern matching and combinators
|
|
23
|
+
- **Near-zero allocations** - `Some` and `Ok` are the values themselves. Only `Err` allocates.
|
|
24
|
+
- **Extreme performance** - Up to 2x faster than alternatives on the happy path
|
|
25
|
+
|
|
26
|
+
## Benchmarks
|
|
27
|
+
|
|
28
|
+
| Operation | nalloc | neverthrow | ts-results | oxide.ts |
|
|
29
|
+
|-----------|---------|------------|------------|----------|
|
|
30
|
+
| `ok()` | **91M ops/s** | 75M ops/s | 56M ops/s | 40M ops/s |
|
|
31
|
+
| `err()` | **55M ops/s** | 52M ops/s | 0.1M ops/s | 47M ops/s |
|
|
32
|
+
| `some()` | **85M ops/s** | - | 40M ops/s | 50M ops/s |
|
|
33
|
+
| `Result.map` | **74M ops/s** | 53M ops/s | 47M ops/s | 64M ops/s |
|
|
34
|
+
| `Option.map` | **71M ops/s** | - | 52M ops/s | 41M ops/s |
|
|
35
|
+
|
|
36
|
+
Run `pnpm bench` to reproduce.
|
|
37
|
+
|
|
38
|
+
## Install
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npm install nalloc
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Quick start
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
import { Option, Result, ok, err, none } from 'nalloc';
|
|
48
|
+
|
|
49
|
+
// Option: the value IS the Option
|
|
50
|
+
const port = Option.fromNullable(process.env.PORT);
|
|
51
|
+
const portNum = Option.unwrapOr(port, '3000');
|
|
52
|
+
|
|
53
|
+
// Result: Ok is the value itself, Err wraps the error
|
|
54
|
+
const config = Result.tryCatch(() => JSON.parse(raw), () => 'invalid json');
|
|
55
|
+
const data = Result.match(
|
|
56
|
+
config,
|
|
57
|
+
cfg => cfg,
|
|
58
|
+
error => ({ fallback: true })
|
|
59
|
+
);
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## How it works
|
|
63
|
+
|
|
64
|
+
| Type | Representation | Allocation |
|
|
65
|
+
|------|----------------|------------|
|
|
66
|
+
| `Option<T>` | `T \| null \| undefined` | Zero |
|
|
67
|
+
| `Some<T>` | The value itself | Zero |
|
|
68
|
+
| `None` | `null` or `undefined` | Zero |
|
|
69
|
+
| `Ok<T>` | The value itself (branded) | Zero |
|
|
70
|
+
| `Err<E>` | Minimal wrapper `{ error: E }` | One object |
|
|
71
|
+
|
|
72
|
+
This means zero GC pressure on the happy path - your success values stay as plain values.
|
|
73
|
+
|
|
74
|
+
## Coming from other libraries?
|
|
75
|
+
|
|
76
|
+
### From neverthrow
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
// neverthrow
|
|
80
|
+
import { ok, err, Result } from 'neverthrow';
|
|
81
|
+
const result: Result<number, string> = ok(42);
|
|
82
|
+
result.map(x => x * 2);
|
|
83
|
+
|
|
84
|
+
// nalloc - same concepts, faster execution
|
|
85
|
+
import { Result, ok, err } from 'nalloc';
|
|
86
|
+
const result = ok(42); // zero allocation
|
|
87
|
+
Result.map(result, x => x * 2); // function-based API
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### From fp-ts
|
|
91
|
+
|
|
92
|
+
```ts
|
|
93
|
+
// fp-ts
|
|
94
|
+
import { pipe } from 'fp-ts/function';
|
|
95
|
+
import * as O from 'fp-ts/Option';
|
|
96
|
+
pipe(O.some(42), O.map(x => x * 2));
|
|
97
|
+
|
|
98
|
+
// nalloc - simpler, faster
|
|
99
|
+
import { Option } from 'nalloc';
|
|
100
|
+
Option.map(42, x => x * 2); // value IS the Option
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### From Rust
|
|
104
|
+
|
|
105
|
+
The API mirrors Rust's `Option` and `Result`:
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
import { Option, Result, ok, err, none } from 'nalloc';
|
|
109
|
+
|
|
110
|
+
// Rust: Some(42).map(|x| x * 2)
|
|
111
|
+
Option.map(42, x => x * 2);
|
|
112
|
+
|
|
113
|
+
// Rust: Ok(42).and_then(|x| if x > 0 { Ok(x) } else { Err("negative") })
|
|
114
|
+
Result.andThen(ok(42), x => x > 0 ? ok(x) : err('negative'));
|
|
115
|
+
|
|
116
|
+
// Rust: result.unwrap_or(0)
|
|
117
|
+
Result.unwrapOr(result, 0);
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Option
|
|
121
|
+
|
|
122
|
+
An `Option<T>` is `T | null | undefined`. The value itself is the Option.
|
|
123
|
+
|
|
124
|
+
```ts
|
|
125
|
+
import { Option, none } from 'nalloc';
|
|
126
|
+
|
|
127
|
+
// Create from nullable
|
|
128
|
+
const maybePort = Option.fromNullable(process.env.PORT);
|
|
129
|
+
|
|
130
|
+
// Transform
|
|
131
|
+
const doubled = Option.map(maybePort, p => parseInt(p) * 2);
|
|
132
|
+
const validated = Option.filter(doubled, n => n > 0);
|
|
133
|
+
|
|
134
|
+
// Extract
|
|
135
|
+
const port = Option.unwrapOr(maybePort, '3000');
|
|
136
|
+
|
|
137
|
+
// Pattern match
|
|
138
|
+
const label = Option.match(
|
|
139
|
+
maybePort,
|
|
140
|
+
value => `Port: ${value}`,
|
|
141
|
+
() => 'Port: default'
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
// Assert and narrow
|
|
145
|
+
Option.assertSome(maybePort, 'PORT is required');
|
|
146
|
+
|
|
147
|
+
// Filter collections
|
|
148
|
+
const activeIds = Option.filterMap(users, user =>
|
|
149
|
+
user.isActive ? user.id : none
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
// Async
|
|
153
|
+
const maybeUser = await Option.fromPromise(fetchUserById(id));
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Result
|
|
157
|
+
|
|
158
|
+
A `Result<T, E>` is either `Ok<T>` (the value itself) or `Err<E>` (a wrapper).
|
|
159
|
+
|
|
160
|
+
```ts
|
|
161
|
+
import { Result, ok, err } from 'nalloc';
|
|
162
|
+
|
|
163
|
+
// Wrap throwing functions
|
|
164
|
+
const parsed = Result.tryCatch(
|
|
165
|
+
() => JSON.parse(raw),
|
|
166
|
+
e => 'invalid json'
|
|
167
|
+
);
|
|
168
|
+
|
|
169
|
+
// Async operations
|
|
170
|
+
const data = await Result.fromPromise(fetch('/api'));
|
|
171
|
+
const processed = await Result.tryAsync(async () => {
|
|
172
|
+
const res = await fetch('/api');
|
|
173
|
+
return res.json();
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
// Transform
|
|
177
|
+
const userId = Result.map(parsed, data => data.userId);
|
|
178
|
+
const validated = Result.flatMap(userId, id =>
|
|
179
|
+
id > 0 ? ok(id) : err('invalid id')
|
|
180
|
+
);
|
|
181
|
+
|
|
182
|
+
// Pattern match
|
|
183
|
+
const user = Result.match(
|
|
184
|
+
parsed,
|
|
185
|
+
data => data.user,
|
|
186
|
+
error => null
|
|
187
|
+
);
|
|
188
|
+
|
|
189
|
+
// Assert and narrow
|
|
190
|
+
Result.assertOk(loaded, 'Config required');
|
|
191
|
+
|
|
192
|
+
// Collections
|
|
193
|
+
const combined = Result.all([ok(1), ok(2), ok(3)]); // Ok([1, 2, 3])
|
|
194
|
+
const first = Result.any([err('a'), ok(42), err('b')]); // Ok(42)
|
|
195
|
+
const [oks, errs] = Result.partition(results);
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## API Reference
|
|
199
|
+
|
|
200
|
+
### Option
|
|
201
|
+
|
|
202
|
+
| Function | Description |
|
|
203
|
+
|----------|-------------|
|
|
204
|
+
| `fromNullable(value)` | Convert nullable to Option |
|
|
205
|
+
| `fromPromise(promise)` | Promise to Option (rejection = None) |
|
|
206
|
+
| `map(opt, fn)` | Transform Some value |
|
|
207
|
+
| `flatMap(opt, fn)` | Chain Option-returning functions |
|
|
208
|
+
| `filter(opt, predicate)` | Keep Some if predicate passes |
|
|
209
|
+
| `match(opt, onSome, onNone)` | Pattern match |
|
|
210
|
+
| `unwrap(opt)` | Extract or throw |
|
|
211
|
+
| `unwrapOr(opt, default)` | Extract or default |
|
|
212
|
+
| `unwrapOrElse(opt, fn)` | Extract or compute default |
|
|
213
|
+
| `assertSome(opt, msg?)` | Assert and narrow to Some |
|
|
214
|
+
| `isSome(opt)` / `isNone(opt)` | Type guards |
|
|
215
|
+
| `filterMap(items, fn)` | Map and filter in one pass |
|
|
216
|
+
|
|
217
|
+
### Result
|
|
218
|
+
|
|
219
|
+
| Function | Description |
|
|
220
|
+
|----------|-------------|
|
|
221
|
+
| `tryCatch(fn, onError?)` | Wrap throwing function |
|
|
222
|
+
| `tryAsync(fn, onError?)` | Wrap async function |
|
|
223
|
+
| `fromPromise(promise)` | Promise to Result |
|
|
224
|
+
| `map(result, fn)` | Transform Ok value |
|
|
225
|
+
| `mapErr(result, fn)` | Transform Err value |
|
|
226
|
+
| `flatMap(result, fn)` | Chain Result-returning functions |
|
|
227
|
+
| `match(result, onOk, onErr)` | Pattern match |
|
|
228
|
+
| `unwrap(result)` | Extract Ok or throw |
|
|
229
|
+
| `unwrapOr(result, default)` | Extract Ok or default |
|
|
230
|
+
| `assertOk(result, msg?)` | Assert and narrow to Ok |
|
|
231
|
+
| `isOk(result)` / `isErr(result)` | Type guards |
|
|
232
|
+
| `all(results)` | Collect all Ok or first Err |
|
|
233
|
+
| `any(results)` | First Ok or all Errs |
|
|
234
|
+
| `partition(results)` | Split into [oks, errs] |
|
|
235
|
+
| `partitionAsync(promises)` | Async partition |
|
|
236
|
+
|
|
237
|
+
## Testing
|
|
238
|
+
|
|
239
|
+
```ts
|
|
240
|
+
import { expectOk, expectErr, expectSome, expectNone, extendExpect } from 'nalloc/testing';
|
|
241
|
+
import { expect } from 'vitest';
|
|
242
|
+
|
|
243
|
+
extendExpect(expect);
|
|
244
|
+
|
|
245
|
+
expect(result).toBeOk();
|
|
246
|
+
expect(result).toBeErr();
|
|
247
|
+
expect(option).toBeSome();
|
|
248
|
+
expect(option).toBeNone();
|
|
249
|
+
|
|
250
|
+
const value = expectOk(result); // returns value or throws
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
## Devtools
|
|
254
|
+
|
|
255
|
+
```ts
|
|
256
|
+
import { formatResult, formatOption, inspectResult, inspectOption } from 'nalloc/devtools';
|
|
257
|
+
|
|
258
|
+
formatResult(ok(42)); // "Ok(42)"
|
|
259
|
+
formatOption(null); // "None"
|
|
260
|
+
|
|
261
|
+
inspectResult(ok(42)); // { status: 'ok', value: 42 }
|
|
262
|
+
inspectOption(42); // { kind: 'some', value: 42 }
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
## Comparison
|
|
266
|
+
|
|
267
|
+
| Feature | nalloc | neverthrow | fp-ts | oxide.ts |
|
|
268
|
+
|---------|---------|------------|-------|----------|
|
|
269
|
+
| Zero-alloc Option | Yes | No | No | No |
|
|
270
|
+
| Zero-alloc Ok | Yes | No | No | No |
|
|
271
|
+
| Bundle size | Tiny | Small | Large | Small |
|
|
272
|
+
| Learning curve | Low | Low | High | Low |
|
|
273
|
+
| Async support | Yes | Yes | Yes | Limited |
|
|
274
|
+
| Tree-shakeable | Yes | Yes | Yes | Yes |
|
|
275
|
+
|
|
276
|
+
## License
|
|
277
|
+
|
|
278
|
+
MIT
|
|
279
|
+
|
|
280
|
+
## Contributing
|
|
281
|
+
|
|
282
|
+
Contributions welcome! Open an issue or PR for ideas, bug fixes, or docs.
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
_export(exports, {
|
|
12
|
+
get formatOption () {
|
|
13
|
+
return formatOption;
|
|
14
|
+
},
|
|
15
|
+
get formatResult () {
|
|
16
|
+
return formatResult;
|
|
17
|
+
},
|
|
18
|
+
get inspectOption () {
|
|
19
|
+
return inspectOption;
|
|
20
|
+
},
|
|
21
|
+
get inspectResult () {
|
|
22
|
+
return inspectResult;
|
|
23
|
+
},
|
|
24
|
+
get logOption () {
|
|
25
|
+
return logOption;
|
|
26
|
+
},
|
|
27
|
+
get logResult () {
|
|
28
|
+
return logResult;
|
|
29
|
+
},
|
|
30
|
+
get toJSONOption () {
|
|
31
|
+
return toJSONOption;
|
|
32
|
+
},
|
|
33
|
+
get toJSONResult () {
|
|
34
|
+
return toJSONResult;
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
const _typescjs = require("./types.cjs");
|
|
38
|
+
function formatOption(opt) {
|
|
39
|
+
return (0, _typescjs.isSome)(opt) ? `Some(${String(opt)})` : 'None';
|
|
40
|
+
}
|
|
41
|
+
function formatResult(result) {
|
|
42
|
+
if ((0, _typescjs.isOk)(result)) {
|
|
43
|
+
return `Ok(${String(result)})`;
|
|
44
|
+
}
|
|
45
|
+
const error = result.error;
|
|
46
|
+
return `Err(${error instanceof Error ? error.message : String(error)})`;
|
|
47
|
+
}
|
|
48
|
+
function inspectOption(opt) {
|
|
49
|
+
return (0, _typescjs.isSome)(opt) ? {
|
|
50
|
+
kind: 'some',
|
|
51
|
+
value: opt
|
|
52
|
+
} : {
|
|
53
|
+
kind: 'none'
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function inspectResult(result) {
|
|
57
|
+
return (0, _typescjs.isOk)(result) ? {
|
|
58
|
+
status: 'ok',
|
|
59
|
+
value: result
|
|
60
|
+
} : {
|
|
61
|
+
status: 'err',
|
|
62
|
+
error: result.error
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function logOption(opt, logger = console.log) {
|
|
66
|
+
logger(formatOption(opt));
|
|
67
|
+
}
|
|
68
|
+
function logResult(result, logger = console.log) {
|
|
69
|
+
const tagged = inspectResult(result);
|
|
70
|
+
if (tagged.status === 'ok') {
|
|
71
|
+
logger(`Ok`, tagged.value);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
logger(`Err`, tagged.error);
|
|
75
|
+
}
|
|
76
|
+
const toJSONOption = inspectOption;
|
|
77
|
+
const toJSONResult = inspectResult;
|
|
78
|
+
|
|
79
|
+
//# sourceMappingURL=devtools.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/devtools.ts"],"sourcesContent":["import { Option, Result, isSome, isOk } from './types.js';\n\n/** Logger function signature for custom logging. */\ntype Logger = (message: string, ...args: unknown[]) => void;\n\n/**\n * Formats an Option as a human-readable string.\n * @param opt - The Option to format\n * @returns \"Some(value)\" or \"None\"\n * @example\n * formatOption(42) // \"Some(42)\"\n * formatOption(null) // \"None\"\n * formatOption(undefined) // \"None\"\n */\nexport function formatOption<T>(opt: Option<T>): string {\n return isSome(opt) ? `Some(${String(opt)})` : 'None';\n}\n\n/**\n * Formats a Result as a human-readable string.\n * For Err containing an Error, displays the error message.\n * @param result - The Result to format\n * @returns \"Ok(value)\" or \"Err(error)\"\n * @example\n * formatResult(42) // \"Ok(42)\"\n * formatResult(err('fail')) // \"Err(fail)\"\n * formatResult(err(new Error('oops'))) // \"Err(oops)\"\n */\nexport function formatResult<T, E>(result: Result<T, E>): string {\n if (isOk(result)) {\n return `Ok(${String(result)})`;\n }\n const error = (result as { error: E }).error;\n return `Err(${error instanceof Error ? error.message : String(error)})`;\n}\n\n/**\n * Inspects an Option, returning a tagged object for debugging or serialization.\n * @param opt - The Option to inspect\n * @returns `{ kind: 'some', value: T }` or `{ kind: 'none' }`\n * @example\n * inspectOption(42) // { kind: 'some', value: 42 }\n * inspectOption(null) // { kind: 'none' }\n */\nexport function inspectOption<T>(opt: Option<T>) {\n return isSome(opt) ? { kind: 'some' as const, value: opt } : { kind: 'none' as const };\n}\n\n/**\n * Inspects a Result, returning a tagged object for debugging or serialization.\n * @param result - The Result to inspect\n * @returns `{ status: 'ok', value: T }` or `{ status: 'err', error: E }`\n * @example\n * inspectResult(42) // { status: 'ok', value: 42 }\n * inspectResult(err('fail')) // { status: 'err', error: 'fail' }\n */\nexport function inspectResult<T, E>(result: Result<T, E>) {\n return isOk(result) ? { status: 'ok' as const, value: result } : { status: 'err' as const, error: (result as { error: E }).error };\n}\n\n/**\n * Logs an Option using the provided logger (defaults to console.log).\n * @param opt - The Option to log\n * @param logger - The logging function to use\n * @example\n * logOption(42) // logs \"Some(42)\"\n * logOption(null) // logs \"None\"\n * logOption(42, console.warn) // logs \"Some(42)\" as warning\n */\nexport function logOption<T>(opt: Option<T>, logger: Logger = console.log): void {\n logger(formatOption(opt));\n}\n\n/**\n * Logs a Result using the provided logger (defaults to console.log).\n * Logs \"Ok\" with the value or \"Err\" with the error.\n * @param result - The Result to log\n * @param logger - The logging function to use\n * @example\n * logResult(42) // logs \"Ok\", 42\n * logResult(err('fail')) // logs \"Err\", \"fail\"\n * logResult(42, console.warn) // logs \"Ok\", 42 as warning\n */\nexport function logResult<T, E>(result: Result<T, E>, logger: Logger = console.log): void {\n const tagged = inspectResult(result);\n if (tagged.status === 'ok') {\n logger(`Ok`, tagged.value);\n return;\n }\n logger(`Err`, tagged.error);\n}\n\n/** Alias for inspectOption. Returns a JSON-serializable representation. */\nexport const toJSONOption = inspectOption;\n\n/** Alias for inspectResult. Returns a JSON-serializable representation. */\nexport const toJSONResult = inspectResult;\n"],"names":["formatOption","formatResult","inspectOption","inspectResult","logOption","logResult","toJSONOption","toJSONResult","opt","isSome","String","result","isOk","error","Error","message","kind","value","status","logger","console","log","tagged"],"mappings":";;;;;;;;;;;QAcgBA;eAAAA;;QAcAC;eAAAA;;QAgBAC;eAAAA;;QAYAC;eAAAA;;QAaAC;eAAAA;;QAcAC;eAAAA;;QAUHC;eAAAA;;QAGAC;eAAAA;;;0BAhGgC;AActC,SAASP,aAAgBQ,GAAc;IAC5C,OAAOC,IAAAA,gBAAM,EAACD,OAAO,CAAC,KAAK,EAAEE,OAAOF,KAAK,CAAC,CAAC,GAAG;AAChD;AAYO,SAASP,aAAmBU,MAAoB;IACrD,IAAIC,IAAAA,cAAI,EAACD,SAAS;QAChB,OAAO,CAAC,GAAG,EAAED,OAAOC,QAAQ,CAAC,CAAC;IAChC;IACA,MAAME,QAAQ,AAACF,OAAwBE,KAAK;IAC5C,OAAO,CAAC,IAAI,EAAEA,iBAAiBC,QAAQD,MAAME,OAAO,GAAGL,OAAOG,OAAO,CAAC,CAAC;AACzE;AAUO,SAASX,cAAiBM,GAAc;IAC7C,OAAOC,IAAAA,gBAAM,EAACD,OAAO;QAAEQ,MAAM;QAAiBC,OAAOT;IAAI,IAAI;QAAEQ,MAAM;IAAgB;AACvF;AAUO,SAASb,cAAoBQ,MAAoB;IACtD,OAAOC,IAAAA,cAAI,EAACD,UAAU;QAAEO,QAAQ;QAAeD,OAAON;IAAO,IAAI;QAAEO,QAAQ;QAAgBL,OAAO,AAACF,OAAwBE,KAAK;IAAC;AACnI;AAWO,SAAST,UAAaI,GAAc,EAAEW,SAAiBC,QAAQC,GAAG;IACvEF,OAAOnB,aAAaQ;AACtB;AAYO,SAASH,UAAgBM,MAAoB,EAAEQ,SAAiBC,QAAQC,GAAG;IAChF,MAAMC,SAASnB,cAAcQ;IAC7B,IAAIW,OAAOJ,MAAM,KAAK,MAAM;QAC1BC,OAAO,CAAC,EAAE,CAAC,EAAEG,OAAOL,KAAK;QACzB;IACF;IACAE,OAAO,CAAC,GAAG,CAAC,EAAEG,OAAOT,KAAK;AAC5B;AAGO,MAAMP,eAAeJ;AAGrB,MAAMK,eAAeJ"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { Option, Result } from './types.js';
|
|
2
|
+
/** Logger function signature for custom logging. */
|
|
3
|
+
type Logger = (message: string, ...args: unknown[]) => void;
|
|
4
|
+
/**
|
|
5
|
+
* Formats an Option as a human-readable string.
|
|
6
|
+
* @param opt - The Option to format
|
|
7
|
+
* @returns "Some(value)" or "None"
|
|
8
|
+
* @example
|
|
9
|
+
* formatOption(42) // "Some(42)"
|
|
10
|
+
* formatOption(null) // "None"
|
|
11
|
+
* formatOption(undefined) // "None"
|
|
12
|
+
*/
|
|
13
|
+
export declare function formatOption<T>(opt: Option<T>): string;
|
|
14
|
+
/**
|
|
15
|
+
* Formats a Result as a human-readable string.
|
|
16
|
+
* For Err containing an Error, displays the error message.
|
|
17
|
+
* @param result - The Result to format
|
|
18
|
+
* @returns "Ok(value)" or "Err(error)"
|
|
19
|
+
* @example
|
|
20
|
+
* formatResult(42) // "Ok(42)"
|
|
21
|
+
* formatResult(err('fail')) // "Err(fail)"
|
|
22
|
+
* formatResult(err(new Error('oops'))) // "Err(oops)"
|
|
23
|
+
*/
|
|
24
|
+
export declare function formatResult<T, E>(result: Result<T, E>): string;
|
|
25
|
+
/**
|
|
26
|
+
* Inspects an Option, returning a tagged object for debugging or serialization.
|
|
27
|
+
* @param opt - The Option to inspect
|
|
28
|
+
* @returns `{ kind: 'some', value: T }` or `{ kind: 'none' }`
|
|
29
|
+
* @example
|
|
30
|
+
* inspectOption(42) // { kind: 'some', value: 42 }
|
|
31
|
+
* inspectOption(null) // { kind: 'none' }
|
|
32
|
+
*/
|
|
33
|
+
export declare function inspectOption<T>(opt: Option<T>): {
|
|
34
|
+
kind: "some";
|
|
35
|
+
value: import("./types.js").Some<Exclude<T, import("./types.js").NoneValueType>>;
|
|
36
|
+
} | {
|
|
37
|
+
kind: "none";
|
|
38
|
+
value?: undefined;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Inspects a Result, returning a tagged object for debugging or serialization.
|
|
42
|
+
* @param result - The Result to inspect
|
|
43
|
+
* @returns `{ status: 'ok', value: T }` or `{ status: 'err', error: E }`
|
|
44
|
+
* @example
|
|
45
|
+
* inspectResult(42) // { status: 'ok', value: 42 }
|
|
46
|
+
* inspectResult(err('fail')) // { status: 'err', error: 'fail' }
|
|
47
|
+
*/
|
|
48
|
+
export declare function inspectResult<T, E>(result: Result<T, E>): {
|
|
49
|
+
status: "ok";
|
|
50
|
+
value: import("./types.js").Ok<T>;
|
|
51
|
+
error?: undefined;
|
|
52
|
+
} | {
|
|
53
|
+
status: "err";
|
|
54
|
+
error: E;
|
|
55
|
+
value?: undefined;
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Logs an Option using the provided logger (defaults to console.log).
|
|
59
|
+
* @param opt - The Option to log
|
|
60
|
+
* @param logger - The logging function to use
|
|
61
|
+
* @example
|
|
62
|
+
* logOption(42) // logs "Some(42)"
|
|
63
|
+
* logOption(null) // logs "None"
|
|
64
|
+
* logOption(42, console.warn) // logs "Some(42)" as warning
|
|
65
|
+
*/
|
|
66
|
+
export declare function logOption<T>(opt: Option<T>, logger?: Logger): void;
|
|
67
|
+
/**
|
|
68
|
+
* Logs a Result using the provided logger (defaults to console.log).
|
|
69
|
+
* Logs "Ok" with the value or "Err" with the error.
|
|
70
|
+
* @param result - The Result to log
|
|
71
|
+
* @param logger - The logging function to use
|
|
72
|
+
* @example
|
|
73
|
+
* logResult(42) // logs "Ok", 42
|
|
74
|
+
* logResult(err('fail')) // logs "Err", "fail"
|
|
75
|
+
* logResult(42, console.warn) // logs "Ok", 42 as warning
|
|
76
|
+
*/
|
|
77
|
+
export declare function logResult<T, E>(result: Result<T, E>, logger?: Logger): void;
|
|
78
|
+
/** Alias for inspectOption. Returns a JSON-serializable representation. */
|
|
79
|
+
export declare const toJSONOption: typeof inspectOption;
|
|
80
|
+
/** Alias for inspectResult. Returns a JSON-serializable representation. */
|
|
81
|
+
export declare const toJSONResult: typeof inspectResult;
|
|
82
|
+
export {};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { isSome, isOk } from "./types.js";
|
|
2
|
+
export function formatOption(opt) {
|
|
3
|
+
return isSome(opt) ? `Some(${String(opt)})` : 'None';
|
|
4
|
+
}
|
|
5
|
+
export function formatResult(result) {
|
|
6
|
+
if (isOk(result)) {
|
|
7
|
+
return `Ok(${String(result)})`;
|
|
8
|
+
}
|
|
9
|
+
const error = result.error;
|
|
10
|
+
return `Err(${error instanceof Error ? error.message : String(error)})`;
|
|
11
|
+
}
|
|
12
|
+
export function inspectOption(opt) {
|
|
13
|
+
return isSome(opt) ? {
|
|
14
|
+
kind: 'some',
|
|
15
|
+
value: opt
|
|
16
|
+
} : {
|
|
17
|
+
kind: 'none'
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export function inspectResult(result) {
|
|
21
|
+
return isOk(result) ? {
|
|
22
|
+
status: 'ok',
|
|
23
|
+
value: result
|
|
24
|
+
} : {
|
|
25
|
+
status: 'err',
|
|
26
|
+
error: result.error
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export function logOption(opt, logger = console.log) {
|
|
30
|
+
logger(formatOption(opt));
|
|
31
|
+
}
|
|
32
|
+
export function logResult(result, logger = console.log) {
|
|
33
|
+
const tagged = inspectResult(result);
|
|
34
|
+
if (tagged.status === 'ok') {
|
|
35
|
+
logger(`Ok`, tagged.value);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
logger(`Err`, tagged.error);
|
|
39
|
+
}
|
|
40
|
+
export const toJSONOption = inspectOption;
|
|
41
|
+
export const toJSONResult = inspectResult;
|
|
42
|
+
|
|
43
|
+
//# sourceMappingURL=devtools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/devtools.ts"],"sourcesContent":["import { Option, Result, isSome, isOk } from './types.js';\n\n/** Logger function signature for custom logging. */\ntype Logger = (message: string, ...args: unknown[]) => void;\n\n/**\n * Formats an Option as a human-readable string.\n * @param opt - The Option to format\n * @returns \"Some(value)\" or \"None\"\n * @example\n * formatOption(42) // \"Some(42)\"\n * formatOption(null) // \"None\"\n * formatOption(undefined) // \"None\"\n */\nexport function formatOption<T>(opt: Option<T>): string {\n return isSome(opt) ? `Some(${String(opt)})` : 'None';\n}\n\n/**\n * Formats a Result as a human-readable string.\n * For Err containing an Error, displays the error message.\n * @param result - The Result to format\n * @returns \"Ok(value)\" or \"Err(error)\"\n * @example\n * formatResult(42) // \"Ok(42)\"\n * formatResult(err('fail')) // \"Err(fail)\"\n * formatResult(err(new Error('oops'))) // \"Err(oops)\"\n */\nexport function formatResult<T, E>(result: Result<T, E>): string {\n if (isOk(result)) {\n return `Ok(${String(result)})`;\n }\n const error = (result as { error: E }).error;\n return `Err(${error instanceof Error ? error.message : String(error)})`;\n}\n\n/**\n * Inspects an Option, returning a tagged object for debugging or serialization.\n * @param opt - The Option to inspect\n * @returns `{ kind: 'some', value: T }` or `{ kind: 'none' }`\n * @example\n * inspectOption(42) // { kind: 'some', value: 42 }\n * inspectOption(null) // { kind: 'none' }\n */\nexport function inspectOption<T>(opt: Option<T>) {\n return isSome(opt) ? { kind: 'some' as const, value: opt } : { kind: 'none' as const };\n}\n\n/**\n * Inspects a Result, returning a tagged object for debugging or serialization.\n * @param result - The Result to inspect\n * @returns `{ status: 'ok', value: T }` or `{ status: 'err', error: E }`\n * @example\n * inspectResult(42) // { status: 'ok', value: 42 }\n * inspectResult(err('fail')) // { status: 'err', error: 'fail' }\n */\nexport function inspectResult<T, E>(result: Result<T, E>) {\n return isOk(result) ? { status: 'ok' as const, value: result } : { status: 'err' as const, error: (result as { error: E }).error };\n}\n\n/**\n * Logs an Option using the provided logger (defaults to console.log).\n * @param opt - The Option to log\n * @param logger - The logging function to use\n * @example\n * logOption(42) // logs \"Some(42)\"\n * logOption(null) // logs \"None\"\n * logOption(42, console.warn) // logs \"Some(42)\" as warning\n */\nexport function logOption<T>(opt: Option<T>, logger: Logger = console.log): void {\n logger(formatOption(opt));\n}\n\n/**\n * Logs a Result using the provided logger (defaults to console.log).\n * Logs \"Ok\" with the value or \"Err\" with the error.\n * @param result - The Result to log\n * @param logger - The logging function to use\n * @example\n * logResult(42) // logs \"Ok\", 42\n * logResult(err('fail')) // logs \"Err\", \"fail\"\n * logResult(42, console.warn) // logs \"Ok\", 42 as warning\n */\nexport function logResult<T, E>(result: Result<T, E>, logger: Logger = console.log): void {\n const tagged = inspectResult(result);\n if (tagged.status === 'ok') {\n logger(`Ok`, tagged.value);\n return;\n }\n logger(`Err`, tagged.error);\n}\n\n/** Alias for inspectOption. Returns a JSON-serializable representation. */\nexport const toJSONOption = inspectOption;\n\n/** Alias for inspectResult. Returns a JSON-serializable representation. */\nexport const toJSONResult = inspectResult;\n"],"names":["isSome","isOk","formatOption","opt","String","formatResult","result","error","Error","message","inspectOption","kind","value","inspectResult","status","logOption","logger","console","log","logResult","tagged","toJSONOption","toJSONResult"],"mappings":"AAAA,SAAyBA,MAAM,EAAEC,IAAI,QAAQ,aAAa;AAc1D,OAAO,SAASC,aAAgBC,GAAc;IAC5C,OAAOH,OAAOG,OAAO,CAAC,KAAK,EAAEC,OAAOD,KAAK,CAAC,CAAC,GAAG;AAChD;AAYA,OAAO,SAASE,aAAmBC,MAAoB;IACrD,IAAIL,KAAKK,SAAS;QAChB,OAAO,CAAC,GAAG,EAAEF,OAAOE,QAAQ,CAAC,CAAC;IAChC;IACA,MAAMC,QAAQ,AAACD,OAAwBC,KAAK;IAC5C,OAAO,CAAC,IAAI,EAAEA,iBAAiBC,QAAQD,MAAME,OAAO,GAAGL,OAAOG,OAAO,CAAC,CAAC;AACzE;AAUA,OAAO,SAASG,cAAiBP,GAAc;IAC7C,OAAOH,OAAOG,OAAO;QAAEQ,MAAM;QAAiBC,OAAOT;IAAI,IAAI;QAAEQ,MAAM;IAAgB;AACvF;AAUA,OAAO,SAASE,cAAoBP,MAAoB;IACtD,OAAOL,KAAKK,UAAU;QAAEQ,QAAQ;QAAeF,OAAON;IAAO,IAAI;QAAEQ,QAAQ;QAAgBP,OAAO,AAACD,OAAwBC,KAAK;IAAC;AACnI;AAWA,OAAO,SAASQ,UAAaZ,GAAc,EAAEa,SAAiBC,QAAQC,GAAG;IACvEF,OAAOd,aAAaC;AACtB;AAYA,OAAO,SAASgB,UAAgBb,MAAoB,EAAEU,SAAiBC,QAAQC,GAAG;IAChF,MAAME,SAASP,cAAcP;IAC7B,IAAIc,OAAON,MAAM,KAAK,MAAM;QAC1BE,OAAO,CAAC,EAAE,CAAC,EAAEI,OAAOR,KAAK;QACzB;IACF;IACAI,OAAO,CAAC,GAAG,CAAC,EAAEI,OAAOb,KAAK;AAC5B;AAGA,OAAO,MAAMc,eAAeX,cAAc;AAG1C,OAAO,MAAMY,eAAeT,cAAc"}
|
package/build/index.cjs
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
_export(exports, {
|
|
12
|
+
get Option () {
|
|
13
|
+
return _optioncjs;
|
|
14
|
+
},
|
|
15
|
+
get Result () {
|
|
16
|
+
return _resultcjs;
|
|
17
|
+
},
|
|
18
|
+
get err () {
|
|
19
|
+
return _typescjs.err;
|
|
20
|
+
},
|
|
21
|
+
get none () {
|
|
22
|
+
return _typescjs.none;
|
|
23
|
+
},
|
|
24
|
+
get ok () {
|
|
25
|
+
return _typescjs.ok;
|
|
26
|
+
},
|
|
27
|
+
get some () {
|
|
28
|
+
return _typescjs.some;
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
const _typescjs = require("./types.cjs");
|
|
32
|
+
const _optioncjs = /*#__PURE__*/ _interop_require_wildcard(require("./option.cjs"));
|
|
33
|
+
const _resultcjs = /*#__PURE__*/ _interop_require_wildcard(require("./result.cjs"));
|
|
34
|
+
function _getRequireWildcardCache(nodeInterop) {
|
|
35
|
+
if (typeof WeakMap !== "function") return null;
|
|
36
|
+
var cacheBabelInterop = new WeakMap();
|
|
37
|
+
var cacheNodeInterop = new WeakMap();
|
|
38
|
+
return (_getRequireWildcardCache = function(nodeInterop) {
|
|
39
|
+
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
|
|
40
|
+
})(nodeInterop);
|
|
41
|
+
}
|
|
42
|
+
function _interop_require_wildcard(obj, nodeInterop) {
|
|
43
|
+
if (!nodeInterop && obj && obj.__esModule) {
|
|
44
|
+
return obj;
|
|
45
|
+
}
|
|
46
|
+
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
|
|
47
|
+
return {
|
|
48
|
+
default: obj
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
var cache = _getRequireWildcardCache(nodeInterop);
|
|
52
|
+
if (cache && cache.has(obj)) {
|
|
53
|
+
return cache.get(obj);
|
|
54
|
+
}
|
|
55
|
+
var newObj = {
|
|
56
|
+
__proto__: null
|
|
57
|
+
};
|
|
58
|
+
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
|
|
59
|
+
for(var key in obj){
|
|
60
|
+
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
61
|
+
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
|
|
62
|
+
if (desc && (desc.get || desc.set)) {
|
|
63
|
+
Object.defineProperty(newObj, key, desc);
|
|
64
|
+
} else {
|
|
65
|
+
newObj[key] = obj[key];
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
newObj.default = obj;
|
|
70
|
+
if (cache) {
|
|
71
|
+
cache.set(obj, newObj);
|
|
72
|
+
}
|
|
73
|
+
return newObj;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export { some, none, ok, err } from './types.js';\nexport type {\n Some,\n None,\n Ok,\n Err,\n Option as OptionType,\n OptionValue,\n IsOption,\n InferSome,\n Result as ResultType,\n ResultValue,\n ResultErrorType,\n IsResult,\n InferErr,\n} from './types.js';\nexport * as Option from './option.js';\nexport * as Result from './result.js';\n"],"names":["Option","Result","err","none","ok","some"],"mappings":";;;;;;;;;;;QAgBYA;;;QACAC;;;QAjBaC;eAAAA,aAAG;;QAAbC;eAAAA,cAAI;;QAAEC;eAAAA,YAAE;;QAAdC;eAAAA,cAAI;;;0BAAuB;mEAgBZ;mEACA"}
|
package/build/index.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { some, none, ok, err } from './types.js';
|
|
2
|
+
export type { Some, None, Ok, Err, Option as OptionType, OptionValue, IsOption, InferSome, Result as ResultType, ResultValue, ResultErrorType, IsResult, InferErr, } from './types.js';
|
|
3
|
+
export * as Option from './option.js';
|
|
4
|
+
export * as Result from './result.js';
|
package/build/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export { some, none, ok, err } from './types.js';\nexport type {\n Some,\n None,\n Ok,\n Err,\n Option as OptionType,\n OptionValue,\n IsOption,\n InferSome,\n Result as ResultType,\n ResultValue,\n ResultErrorType,\n IsResult,\n InferErr,\n} from './types.js';\nexport * as Option from './option.js';\nexport * as Result from './result.js';\n"],"names":["some","none","ok","err","Option","Result"],"mappings":"AAAA,SAASA,IAAI,EAAEC,IAAI,EAAEC,EAAE,EAAEC,GAAG,QAAQ,aAAa;AAgBjD,OAAO,KAAKC,MAAM,MAAM,cAAc;AACtC,OAAO,KAAKC,MAAM,MAAM,cAAc"}
|