happy-rusty 1.9.2 → 1.10.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/dist/main.mjs CHANGED
@@ -21,7 +21,7 @@
21
21
  *
22
22
  * @internal
23
23
  */
24
- const OptionKindSymbol = /* @__PURE__ */ Symbol("Option kind");
24
+ const OptionKindSymbol = /*#__PURE__*/ Symbol("Option kind");
25
25
  //#endregion
26
26
  //#region src/core/option/guards.ts
27
27
  /**
@@ -66,7 +66,7 @@ function isOption(o) {
66
66
  *
67
67
  * @internal
68
68
  */
69
- const ResultKindSymbol = /* @__PURE__ */ Symbol("Result kind");
69
+ const ResultKindSymbol = /*#__PURE__*/ Symbol("Result kind");
70
70
  //#endregion
71
71
  //#region src/core/result/guards.ts
72
72
  /**
@@ -101,8 +101,8 @@ function isResult(r) {
101
101
  * - `Err<T, E>(error)` - Creates a failed Result
102
102
  * - `None` interface - Type overrides for better type inference
103
103
  */
104
- const ASYNC_TRUE$1 = /* @__PURE__ */ Promise.resolve(true);
105
- const ASYNC_FALSE$1 = /* @__PURE__ */ Promise.resolve(false);
104
+ const ASYNC_TRUE$1 = /*#__PURE__*/ Promise.resolve(true);
105
+ const ASYNC_FALSE$1 = /*#__PURE__*/ Promise.resolve(false);
106
106
  /**
107
107
  * Creates an `Option<T>` representing the presence of a value.
108
108
  * This function is typically used to construct an `Option` that contains a value, indicating that the operation yielding the value was successful.
@@ -263,7 +263,7 @@ function Some(value) {
263
263
  * const name = None.unwrapOr('Anonymous'); // 'Anonymous'
264
264
  * ```
265
265
  */
266
- const None = /* @__PURE__ */ Object.freeze({
266
+ const None = /*#__PURE__*/ Object.freeze({
267
267
  [Symbol.toStringTag]: "Option",
268
268
  [OptionKindSymbol]: "None",
269
269
  *[Symbol.iterator]() {},
@@ -402,7 +402,7 @@ const None = /* @__PURE__ */ Object.freeze({
402
402
  * }
403
403
  * ```
404
404
  */
405
- const ASYNC_NONE = /* @__PURE__ */ Promise.resolve(None);
405
+ const ASYNC_NONE = /*#__PURE__*/ Promise.resolve(None);
406
406
  function Ok(value) {
407
407
  const ok = Object.freeze({
408
408
  [Symbol.toStringTag]: "Result",
@@ -802,7 +802,7 @@ async function tryAsyncOption(task, ...args) {
802
802
  * const value: boolean = RESULT_TRUE.intoOk(); // Safe extraction
803
803
  * ```
804
804
  */
805
- const RESULT_TRUE = /* @__PURE__ */ Ok(true);
805
+ const RESULT_TRUE = /*#__PURE__*/ Ok(true);
806
806
  /**
807
807
  * Result constant for `false`.
808
808
  * Can be used anywhere due to immutability.
@@ -817,7 +817,7 @@ const RESULT_TRUE = /* @__PURE__ */ Ok(true);
817
817
  * const value: boolean = RESULT_FALSE.intoOk(); // Safe extraction
818
818
  * ```
819
819
  */
820
- const RESULT_FALSE = /* @__PURE__ */ Ok(false);
820
+ const RESULT_FALSE = /*#__PURE__*/ Ok(false);
821
821
  /**
822
822
  * Result constant for `0`.
823
823
  * Can be used anywhere due to immutability.
@@ -832,7 +832,7 @@ const RESULT_FALSE = /* @__PURE__ */ Ok(false);
832
832
  * const value: number = RESULT_ZERO.intoOk(); // Safe extraction
833
833
  * ```
834
834
  */
835
- const RESULT_ZERO = /* @__PURE__ */ Ok(0);
835
+ const RESULT_ZERO = /*#__PURE__*/ Ok(0);
836
836
  /**
837
837
  * Result constant for `void` or `()`.
838
838
  * Can be used anywhere due to immutability.
@@ -847,7 +847,7 @@ const RESULT_ZERO = /* @__PURE__ */ Ok(0);
847
847
  * RESULT_VOID.intoOk(); // Safe extraction (returns undefined)
848
848
  * ```
849
849
  */
850
- const RESULT_VOID = /* @__PURE__ */ Ok();
850
+ const RESULT_VOID = /*#__PURE__*/ Ok();
851
851
  //#endregion
852
852
  //#region src/core/result/extensions.ts
853
853
  /**
@@ -934,7 +934,7 @@ async function tryAsyncResult(task, ...args) {
934
934
  *
935
935
  * @internal
936
936
  */
937
- const ControlFlowKindSymbol = /* @__PURE__ */ Symbol("ControlFlow kind");
937
+ const ControlFlowKindSymbol = /*#__PURE__*/ Symbol("ControlFlow kind");
938
938
  //#endregion
939
939
  //#region src/std/ops/control_flow.ts
940
940
  /**
@@ -1147,8 +1147,8 @@ function isControlFlow(cf) {
1147
1147
  * Supports rendezvous (capacity=0) for synchronous handoff between sender and receiver.
1148
1148
  *
1149
1149
  */
1150
- const ASYNC_TRUE = /* @__PURE__ */ Promise.resolve(true);
1151
- const ASYNC_FALSE = /* @__PURE__ */ Promise.resolve(false);
1150
+ const ASYNC_TRUE = /*#__PURE__*/ Promise.resolve(true);
1151
+ const ASYNC_FALSE = /*#__PURE__*/ Promise.resolve(false);
1152
1152
  /**
1153
1153
  * Creates a new MPMC channel with the specified capacity.
1154
1154
  *
@@ -2214,6 +2214,17 @@ function RwLock(value) {
2214
2214
  if (released) return;
2215
2215
  released = true;
2216
2216
  releaseWrite();
2217
+ },
2218
+ downgrade() {
2219
+ if (released) throw new Error("RwLockWriteGuard has been released");
2220
+ released = true;
2221
+ writer = false;
2222
+ readers = 1;
2223
+ while (readWaitQueue.length > 0) {
2224
+ readers++;
2225
+ readWaitQueue.shift()();
2226
+ }
2227
+ return createReadGuard();
2217
2228
  }
2218
2229
  });
2219
2230
  }
@@ -2302,6 +2313,119 @@ function RwLock(value) {
2302
2313
  });
2303
2314
  }
2304
2315
  //#endregion
2305
- export { ASYNC_NONE, Break, Channel, Continue, Err, FnOnce, FnOnceAsync, Lazy, LazyAsync, Mutex, None, Ok, Once, OnceAsync, RESULT_FALSE, RESULT_TRUE, RESULT_VOID, RESULT_ZERO, RwLock, Some, isControlFlow, isOption, isResult, tryAsyncOption, tryAsyncResult, tryOption, tryResult };
2316
+ //#region src/std/sync/semaphore.ts
2317
+ /**
2318
+ * @module
2319
+ * Counting semaphore for limiting async concurrency.
2320
+ *
2321
+ * Inspired by [tokio's `Semaphore`](https://docs.rs/tokio/latest/tokio/sync/struct.Semaphore.html)
2322
+ * (Rust std does not include one). Unlike `Mutex<T>` which binds to a value,
2323
+ * `Semaphore` is a pure concurrency counter: it limits how many async
2324
+ * operations can run concurrently without protecting any data.
2325
+ *
2326
+ * **When to use `Semaphore` vs `Mutex<T>`:**
2327
+ * - Use `Mutex<T>` for exclusive access to a value (n=1, with data)
2328
+ * - Use `Semaphore` to limit concurrency to N (e.g. fetch rate limiting,
2329
+ * connection pools, task queues)
2330
+ *
2331
+ * `Semaphore(1)` behaves like a `Mutex` without a value (a binary semaphore),
2332
+ * but `Mutex<T>` is preferred when you need to protect a value since the
2333
+ * guard provides typed access via `value`.
2334
+ */
2335
+ /**
2336
+ * Creates a new `Semaphore` with the given capacity.
2337
+ *
2338
+ * @param permits - The maximum number of concurrent operations allowed.
2339
+ * Must be a non-negative integer. Use `0` to disallow any
2340
+ * concurrent acquire (acquire will wait forever).
2341
+ * @returns A new `Semaphore` instance.
2342
+ * @throws {RangeError} If `permits` is negative or not an integer.
2343
+ * @example
2344
+ * ```ts
2345
+ * // Limit to 5 concurrent operations
2346
+ * const sem = Semaphore(5);
2347
+ *
2348
+ * // Binary semaphore (equivalent to a value-less Mutex)
2349
+ * const binary = Semaphore(1);
2350
+ * ```
2351
+ *
2352
+ * @example
2353
+ * ```ts
2354
+ * // Task queue: process 2 jobs at a time
2355
+ * const sem = Semaphore(2);
2356
+ *
2357
+ * async function processJob(job: Job) {
2358
+ * return sem.withPermit(async () => {
2359
+ * return await runJob(job);
2360
+ * });
2361
+ * }
2362
+ *
2363
+ * await Promise.all(jobs.map(processJob));
2364
+ * ```
2365
+ */
2366
+ function Semaphore(permits) {
2367
+ if (!Number.isInteger(permits) || permits < 0) throw new RangeError(`Semaphore capacity must be a non-negative integer, got ${permits}`);
2368
+ const capacity = permits;
2369
+ let available = permits;
2370
+ const waitQueue = [];
2371
+ function releasePermit() {
2372
+ if (waitQueue.length > 0) waitQueue.shift()();
2373
+ else available++;
2374
+ }
2375
+ function createPermit() {
2376
+ let released = false;
2377
+ return Object.freeze({
2378
+ [Symbol.toStringTag]: "SemaphorePermit",
2379
+ toString() {
2380
+ return released ? "SemaphorePermit(<released>)" : "SemaphorePermit";
2381
+ },
2382
+ release() {
2383
+ if (released) return;
2384
+ released = true;
2385
+ releasePermit();
2386
+ }
2387
+ });
2388
+ }
2389
+ function acquire() {
2390
+ if (available > 0) {
2391
+ available--;
2392
+ return Promise.resolve(createPermit());
2393
+ }
2394
+ return new Promise((resolve) => {
2395
+ waitQueue.push(() => {
2396
+ resolve(createPermit());
2397
+ });
2398
+ });
2399
+ }
2400
+ function tryAcquire() {
2401
+ if (available > 0) {
2402
+ available--;
2403
+ return Some(createPermit());
2404
+ }
2405
+ return None;
2406
+ }
2407
+ return Object.freeze({
2408
+ [Symbol.toStringTag]: "Semaphore",
2409
+ toString() {
2410
+ return `Semaphore(${available}/${capacity})`;
2411
+ },
2412
+ capacity,
2413
+ async withPermit(fn) {
2414
+ const permit = await acquire();
2415
+ try {
2416
+ return await fn();
2417
+ } finally {
2418
+ permit.release();
2419
+ }
2420
+ },
2421
+ acquire,
2422
+ tryAcquire,
2423
+ availablePermits() {
2424
+ return available;
2425
+ }
2426
+ });
2427
+ }
2428
+ //#endregion
2429
+ export { ASYNC_NONE, Break, Channel, Continue, Err, FnOnce, FnOnceAsync, Lazy, LazyAsync, Mutex, None, Ok, Once, OnceAsync, RESULT_FALSE, RESULT_TRUE, RESULT_VOID, RESULT_ZERO, RwLock, Semaphore, Some, isControlFlow, isOption, isResult, tryAsyncOption, tryAsyncResult, tryOption, tryResult };
2306
2430
 
2307
2431
  //# sourceMappingURL=main.mjs.map