happy-rusty 1.8.0 → 1.9.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/CHANGELOG.md CHANGED
@@ -5,6 +5,31 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.9.1] - 2026-01-16
9
+
10
+ ### Changed
11
+ - **Performance**: `Channel` buffer replaced `Array` with `Queue` for O(1) shift operations
12
+
13
+ ### Documentation
14
+ - Added `@since` tags to all public APIs
15
+ - Improved JSDoc consistency and formatting
16
+
17
+ ### CI
18
+ - Changed JSR publish to trigger on release instead of push to main
19
+
20
+ ## [1.9.0] - 2026-01-04
21
+
22
+ ### Added
23
+ - **Try Extensions for Result**:
24
+ - `andTryAsync<U>` - Like `andThenAsync`, but auto-catches exceptions/Promise rejections and converts them to `Err`
25
+ - `orTryAsync<F>` - Like `orElseAsync`, but auto-catches exceptions in recovery logic
26
+
27
+ ### Changed
28
+ - **Performance**: `map()` and `mapErr()` now return `this` when the Result variant doesn't match, avoiding unnecessary object creation
29
+
30
+ ### Removed
31
+ - `promiseToAsyncResult()` - Use `tryAsyncResult()` instead (deprecated since v1.7.0)
32
+
8
33
  ## [1.8.0] - 2025-12-31
9
34
 
10
35
  ### Added
@@ -257,6 +282,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
257
282
  - Full TypeScript support
258
283
  - Comprehensive API matching Rust's Option and Result
259
284
 
285
+ [1.9.1]: https://github.com/JiangJie/happy-rusty/compare/v1.9.0...v1.9.1
286
+ [1.9.0]: https://github.com/JiangJie/happy-rusty/compare/v1.8.0...v1.9.0
260
287
  [1.8.0]: https://github.com/JiangJie/happy-rusty/compare/v1.7.1...v1.8.0
261
288
  [1.7.1]: https://github.com/JiangJie/happy-rusty/compare/v1.7.0...v1.7.1
262
289
  [1.7.0]: https://github.com/JiangJie/happy-rusty/compare/v1.6.2...v1.7.0
package/dist/main.cjs CHANGED
@@ -318,7 +318,7 @@ function Ok(value) {
318
318
  return Ok(fn(value));
319
319
  },
320
320
  mapErr(_fn) {
321
- return Ok(value);
321
+ return ok;
322
322
  },
323
323
  mapOr(_defaultValue, fn) {
324
324
  return fn(value);
@@ -365,6 +365,20 @@ function Ok(value) {
365
365
  },
366
366
  asErr() {
367
367
  throw new TypeError("Result::asErr() called on an `Ok` value");
368
+ },
369
+ andTryAsync(fn) {
370
+ try {
371
+ const result = fn(value);
372
+ return Promise.resolve(result).then(
373
+ Ok,
374
+ Err
375
+ );
376
+ } catch (e) {
377
+ return Promise.resolve(Err(e));
378
+ }
379
+ },
380
+ orTryAsync(_fn) {
381
+ return Promise.resolve(ok);
368
382
  }
369
383
  });
370
384
  return ok;
@@ -433,7 +447,7 @@ function Err(error) {
433
447
  return Some(err);
434
448
  },
435
449
  map(_fn) {
436
- return Err(error);
450
+ return err;
437
451
  },
438
452
  mapErr(fn) {
439
453
  return Err(fn(error));
@@ -482,6 +496,20 @@ function Err(error) {
482
496
  },
483
497
  asErr() {
484
498
  return err;
499
+ },
500
+ andTryAsync(_fn) {
501
+ return Promise.resolve(err);
502
+ },
503
+ orTryAsync(fn) {
504
+ try {
505
+ const result = fn(error);
506
+ return Promise.resolve(result).then(
507
+ Ok,
508
+ Err
509
+ );
510
+ } catch (e) {
511
+ return Promise.resolve(Err(e));
512
+ }
485
513
  }
486
514
  });
487
515
  return err;
@@ -549,9 +577,6 @@ async function tryAsyncResult(task, ...args) {
549
577
  return Err(err);
550
578
  }
551
579
  }
552
- async function promiseToAsyncResult(task) {
553
- return tryAsyncResult(task);
554
- }
555
580
 
556
581
  const ControlFlowKindSymbol = /* @__PURE__ */ Symbol("ControlFlow kind");
557
582
 
@@ -696,7 +721,7 @@ function Channel(capacity = Infinity) {
696
721
  if (capacity < 0 || !Number.isInteger(capacity) && capacity !== Infinity) {
697
722
  throw new RangeError("Channel capacity must be a non-negative integer or Infinity");
698
723
  }
699
- const buffer = [];
724
+ const buffer = new Queue();
700
725
  let closed = false;
701
726
  const sendWaitQueue = [];
702
727
  const receiveWaitQueue = [];
@@ -932,6 +957,26 @@ function Channel(capacity = Infinity) {
932
957
  close
933
958
  });
934
959
  }
960
+ class Queue {
961
+ data = [];
962
+ offset = 0;
963
+ get length() {
964
+ return this.data.length - this.offset;
965
+ }
966
+ push(item) {
967
+ this.data.push(item);
968
+ }
969
+ shift() {
970
+ const item = this.data[this.offset];
971
+ this.data[this.offset] = void 0;
972
+ this.offset++;
973
+ if (this.offset > 1024 && this.offset * 2 > this.data.length) {
974
+ this.data = this.data.slice(this.offset);
975
+ this.offset = 0;
976
+ }
977
+ return item;
978
+ }
979
+ }
935
980
 
936
981
  function Lazy(fn) {
937
982
  let value;
@@ -1500,7 +1545,6 @@ exports.Some = Some;
1500
1545
  exports.isControlFlow = isControlFlow;
1501
1546
  exports.isOption = isOption;
1502
1547
  exports.isResult = isResult;
1503
- exports.promiseToAsyncResult = promiseToAsyncResult;
1504
1548
  exports.tryAsyncOption = tryAsyncOption;
1505
1549
  exports.tryAsyncResult = tryAsyncResult;
1506
1550
  exports.tryOption = tryOption;