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.
Files changed (58) hide show
  1. package/README.md +282 -0
  2. package/build/devtools.cjs +79 -0
  3. package/build/devtools.cjs.map +1 -0
  4. package/build/devtools.d.ts +82 -0
  5. package/build/devtools.js +43 -0
  6. package/build/devtools.js.map +1 -0
  7. package/build/index.cjs +76 -0
  8. package/build/index.cjs.map +1 -0
  9. package/build/index.d.ts +4 -0
  10. package/build/index.js +5 -0
  11. package/build/index.js.map +1 -0
  12. package/build/option.cjs +279 -0
  13. package/build/option.cjs.map +1 -0
  14. package/build/option.d.ts +356 -0
  15. package/build/option.js +157 -0
  16. package/build/option.js.map +1 -0
  17. package/build/result.cjs +381 -0
  18. package/build/result.cjs.map +1 -0
  19. package/build/result.d.ts +442 -0
  20. package/build/result.js +229 -0
  21. package/build/result.js.map +1 -0
  22. package/build/safe.cjs +88 -0
  23. package/build/safe.cjs.map +1 -0
  24. package/build/safe.d.ts +29 -0
  25. package/build/safe.js +18 -0
  26. package/build/safe.js.map +1 -0
  27. package/build/testing.cjs +111 -0
  28. package/build/testing.cjs.map +1 -0
  29. package/build/testing.d.ts +85 -0
  30. package/build/testing.js +81 -0
  31. package/build/testing.js.map +1 -0
  32. package/build/types.cjs +78 -0
  33. package/build/types.cjs.map +1 -0
  34. package/build/types.d.ts +137 -0
  35. package/build/types.js +36 -0
  36. package/build/types.js.map +1 -0
  37. package/build/unsafe.cjs +82 -0
  38. package/build/unsafe.cjs.map +1 -0
  39. package/build/unsafe.d.ts +27 -0
  40. package/build/unsafe.js +11 -0
  41. package/build/unsafe.js.map +1 -0
  42. package/package.json +93 -0
  43. package/src/__tests__/index.ts +13 -0
  44. package/src/__tests__/option.ts +610 -0
  45. package/src/__tests__/option.types.ts +120 -0
  46. package/src/__tests__/result.ts +721 -0
  47. package/src/__tests__/result.types.ts +249 -0
  48. package/src/__tests__/safe.ts +24 -0
  49. package/src/__tests__/tooling.ts +86 -0
  50. package/src/__tests__/unsafe.ts +24 -0
  51. package/src/devtools.ts +97 -0
  52. package/src/index.ts +18 -0
  53. package/src/option.ts +510 -0
  54. package/src/result.ts +676 -0
  55. package/src/safe.ts +58 -0
  56. package/src/testing.ts +159 -0
  57. package/src/types.ts +201 -0
  58. 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
+ [![npm version](https://img.shields.io/npm/v/nalloc.svg)](https://www.npmjs.com/package/nalloc)
8
+ [![npm downloads](https://img.shields.io/npm/dw/nalloc.svg)](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"}
@@ -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"}
@@ -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,5 @@
1
+ export { some, none, ok, err } from "./types.js";
2
+ export * as Option from "./option.js";
3
+ export * as Result from "./result.js";
4
+
5
+ //# sourceMappingURL=index.js.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":["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"}