@evolu/common 8.10.0 → 8.11.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.
Files changed (144) hide show
  1. package/dist/src/Config.d.ts +22 -22
  2. package/dist/src/Config.d.ts.map +1 -1
  3. package/dist/src/Console.d.ts +62 -7
  4. package/dist/src/Console.d.ts.map +1 -1
  5. package/dist/src/Console.js +20 -4
  6. package/dist/src/Crypto.d.ts +76 -4
  7. package/dist/src/Crypto.d.ts.map +1 -1
  8. package/dist/src/Crypto.js +55 -4
  9. package/dist/src/Error.d.ts +45 -0
  10. package/dist/src/Error.d.ts.map +1 -1
  11. package/dist/src/Error.js +69 -0
  12. package/dist/src/Fs.d.ts +92 -18
  13. package/dist/src/Fs.d.ts.map +1 -1
  14. package/dist/src/Fs.js +2 -0
  15. package/dist/src/Identicon.d.ts +2 -2
  16. package/dist/src/Identicon.js +2 -2
  17. package/dist/src/LeakDetector.d.ts +22 -3
  18. package/dist/src/LeakDetector.d.ts.map +1 -1
  19. package/dist/src/LeakDetector.js +12 -2
  20. package/dist/src/LockManager.d.ts +8 -0
  21. package/dist/src/LockManager.d.ts.map +1 -1
  22. package/dist/src/LockManager.js +6 -0
  23. package/dist/src/Object.d.ts.map +1 -1
  24. package/dist/src/Object.js +5 -0
  25. package/dist/src/Platform.d.ts +47 -7
  26. package/dist/src/Platform.d.ts.map +1 -1
  27. package/dist/src/Platform.js +24 -5
  28. package/dist/src/Random.d.ts +25 -2
  29. package/dist/src/Random.d.ts.map +1 -1
  30. package/dist/src/Random.js +14 -2
  31. package/dist/src/Resource.d.ts +156 -1
  32. package/dist/src/Resource.d.ts.map +1 -1
  33. package/dist/src/Resource.js +201 -72
  34. package/dist/src/Schedule.d.ts +11 -10
  35. package/dist/src/Schedule.d.ts.map +1 -1
  36. package/dist/src/Schedule.js +1 -1
  37. package/dist/src/Sqlite.d.ts +132 -16
  38. package/dist/src/Sqlite.d.ts.map +1 -1
  39. package/dist/src/Sqlite.js +63 -9
  40. package/dist/src/Task.d.ts +15 -4
  41. package/dist/src/Task.d.ts.map +1 -1
  42. package/dist/src/Task.js +41 -15
  43. package/dist/src/Test.d.ts +9 -0
  44. package/dist/src/Test.d.ts.map +1 -1
  45. package/dist/src/Test.js +4 -0
  46. package/dist/src/Time.d.ts +106 -9
  47. package/dist/src/Time.d.ts.map +1 -1
  48. package/dist/src/Time.js +55 -4
  49. package/dist/src/Type.d.ts +1455 -1310
  50. package/dist/src/Type.d.ts.map +1 -1
  51. package/dist/src/Type.js +1274 -517
  52. package/dist/src/WebSocket.d.ts +164 -13
  53. package/dist/src/WebSocket.d.ts.map +1 -1
  54. package/dist/src/WebSocket.js +133 -24
  55. package/dist/src/Worker.d.ts +90 -8
  56. package/dist/src/Worker.d.ts.map +1 -1
  57. package/dist/src/Worker.js +28 -2
  58. package/dist/src/index.d.ts +6 -7
  59. package/dist/src/index.d.ts.map +1 -1
  60. package/dist/src/index.js +2 -3
  61. package/dist/src/local-first/Db.d.ts +52 -3
  62. package/dist/src/local-first/Db.d.ts.map +1 -1
  63. package/dist/src/local-first/Db.js +412 -137
  64. package/dist/src/local-first/Evolu.d.ts +336 -211
  65. package/dist/src/local-first/Evolu.d.ts.map +1 -1
  66. package/dist/src/local-first/Evolu.js +102 -15
  67. package/dist/src/local-first/Owner.d.ts +13 -30
  68. package/dist/src/local-first/Owner.d.ts.map +1 -1
  69. package/dist/src/local-first/Owner.js +13 -30
  70. package/dist/src/local-first/Protocol.d.ts +94 -16
  71. package/dist/src/local-first/Protocol.d.ts.map +1 -1
  72. package/dist/src/local-first/Protocol.js +118 -38
  73. package/dist/src/local-first/Query.d.ts +8 -15
  74. package/dist/src/local-first/Query.d.ts.map +1 -1
  75. package/dist/src/local-first/Schema.d.ts +335 -21
  76. package/dist/src/local-first/Schema.d.ts.map +1 -1
  77. package/dist/src/local-first/Schema.js +214 -17
  78. package/dist/src/local-first/Shared.d.ts +537 -22
  79. package/dist/src/local-first/Shared.d.ts.map +1 -1
  80. package/dist/src/local-first/Shared.js +1437 -234
  81. package/dist/src/local-first/Storage.d.ts +192 -14
  82. package/dist/src/local-first/Storage.d.ts.map +1 -1
  83. package/dist/src/local-first/Storage.js +81 -20
  84. package/dist/src/local-first/Timestamp.d.ts +392 -41
  85. package/dist/src/local-first/Timestamp.d.ts.map +1 -1
  86. package/dist/src/local-first/Timestamp.js +403 -81
  87. package/dist/src/local-first/index.d.ts +0 -1
  88. package/dist/src/local-first/index.d.ts.map +1 -1
  89. package/dist/src/local-first/index.js +0 -1
  90. package/package.json +1 -1
  91. package/src/Assert.test.ts +2 -5
  92. package/src/Config.test.ts +2 -6
  93. package/src/Config.ts +133 -133
  94. package/src/Console.ts +62 -7
  95. package/src/Crypto.ts +76 -4
  96. package/src/Eq.test.ts +2 -3
  97. package/src/Error.test.ts +76 -3
  98. package/src/Error.ts +71 -0
  99. package/src/Fs.ts +92 -18
  100. package/src/Identicon.ts +2 -2
  101. package/src/LeakDetector.ts +22 -3
  102. package/src/LockManager.ts +8 -0
  103. package/src/Object.test.ts +27 -12
  104. package/src/Object.ts +5 -0
  105. package/src/Platform.ts +50 -8
  106. package/src/Random.ts +25 -2
  107. package/src/Resource.test.ts +837 -0
  108. package/src/Resource.ts +235 -15
  109. package/src/Schedule.test.ts +50 -12
  110. package/src/Schedule.ts +24 -14
  111. package/src/Sqlite.ts +137 -17
  112. package/src/Task.test.ts +189 -8
  113. package/src/Task.ts +56 -17
  114. package/src/Test.ts +9 -0
  115. package/src/Time.ts +106 -9
  116. package/src/Type.test.ts +946 -1028
  117. package/src/Type.ts +4195 -3136
  118. package/src/Types.test.ts +4 -14
  119. package/src/WebSocket.ts +313 -40
  120. package/src/Worker.ts +90 -8
  121. package/src/index.ts +15 -6
  122. package/src/local-first/Db.ts +644 -339
  123. package/src/local-first/Evolu.test.ts +686 -21
  124. package/src/local-first/Evolu.ts +450 -228
  125. package/src/local-first/Owner.ts +13 -30
  126. package/src/local-first/Protocol.test.ts +617 -10
  127. package/src/local-first/Protocol.ts +196 -72
  128. package/src/local-first/Query.ts +8 -15
  129. package/src/local-first/Schema.test.ts +143 -0
  130. package/src/local-first/Schema.ts +363 -24
  131. package/src/local-first/Shared.test.ts +7731 -559
  132. package/src/local-first/Shared.ts +2036 -267
  133. package/src/local-first/Storage.ts +218 -32
  134. package/src/local-first/Timestamp.test.ts +344 -70
  135. package/src/local-first/Timestamp.ts +434 -118
  136. package/src/local-first/index.ts +0 -1
  137. package/dist/src/local-first/Error.d.ts +0 -12
  138. package/dist/src/local-first/Error.d.ts.map +0 -1
  139. package/dist/src/local-first/Error.js +0 -6
  140. package/dist/src/local-first/LocalAuth.d.ts +0 -150
  141. package/dist/src/local-first/LocalAuth.d.ts.map +0 -1
  142. package/dist/src/local-first/LocalAuth.js +0 -179
  143. package/src/local-first/Error.ts +0 -17
  144. package/src/local-first/LocalAuth.ts +0 -457
package/src/Task.ts CHANGED
@@ -686,6 +686,7 @@ import {
686
686
  type RandomBytesDep,
687
687
  } from "./Crypto.ts";
688
688
  import { eqArraySameValue } from "./Eq.ts";
689
+ import type { defectToError } from "./Error.ts";
689
690
  import { constTrue, constVoid, identity } from "./Function.ts";
690
691
  import type { fetch, NativeFetch, NativeFetchDep } from "./Http.ts";
691
692
  import {
@@ -1462,10 +1463,20 @@ export interface Run<D = unknown> {
1462
1463
  callback: (abortError: AbortError) => void,
1463
1464
  ) => Disposable | null;
1464
1465
 
1465
- /** Returns the current {@link RunState} of this {@link Run}. */
1466
+ /**
1467
+ * Returns the current {@link RunState} of this {@link Run}.
1468
+ *
1469
+ * Abort requests are recorded before propagating to descendants. Observed
1470
+ * aborts are recorded before this Run's abort callbacks execute.
1471
+ */
1466
1472
  readonly getState: () => RunState;
1467
1473
 
1468
- /** Creates a memoized recursive {@link RunSnapshot} of the current Run tree. */
1474
+ /**
1475
+ * Creates a memoized recursive {@link RunSnapshot} of the current Run tree.
1476
+ *
1477
+ * Reflects abort requests and observations with the same timing as
1478
+ * {@link Run.getState}.
1479
+ */
1469
1480
  readonly snapshot: () => RunSnapshot;
1470
1481
 
1471
1482
  /**
@@ -2085,8 +2096,9 @@ export interface ReportDefectDep {
2085
2096
  * platforms without native global error reporting. Browser adapters use the
2086
2097
  * native
2087
2098
  * {@link https://developer.mozilla.org/en-US/docs/Web/API/Window/reportError | reportError}
2088
- * API; other platform adapters can use platform-specific reporting and preserve
2089
- * nested panic defects as cause or detail data.
2099
+ * API, and other platform adapters can use platform-specific reporting.
2100
+ * Adapters report an `Error` from {@link defectToError}, which such reporting
2101
+ * shows readably.
2090
2102
  *
2091
2103
  * @group Run
2092
2104
  */
@@ -2481,6 +2493,7 @@ const createRunInternal = <D extends object>(
2481
2493
  : abortBehavior.abortMask;
2482
2494
 
2483
2495
  let state: RunState = runningRunState;
2496
+ let publishedState: RunState = state;
2484
2497
  let exit: RunExit | undefined;
2485
2498
  let snapshot: RunSnapshot | undefined;
2486
2499
 
@@ -2533,6 +2546,13 @@ const createRunInternal = <D extends object>(
2533
2546
  }
2534
2547
  };
2535
2548
 
2549
+ const publishState = (): void => {
2550
+ // A nested disposal may have published this state before the outer abort.
2551
+ if (publishedState === state) return;
2552
+ publishedState = state;
2553
+ emitEvent({ type: "StateChanged", state });
2554
+ };
2555
+
2536
2556
  // Reads abort reasons from the Run-owned controllers, which are only
2537
2557
  // aborted with AbortError.
2538
2558
  const currentAbort = (): RunAbortState["abort"] => ({
@@ -2542,17 +2562,10 @@ const createRunInternal = <D extends object>(
2542
2562
  : null,
2543
2563
  });
2544
2564
 
2545
- const commitState = (nextState: RunState): void => {
2546
- state = nextState;
2547
- emitEvent({ type: "StateChanged", state });
2548
- };
2549
-
2550
2565
  const requestAbort = (reason: AbortReason = explicitAbortReason): void => {
2551
2566
  if (requestController.signal.aborted) return;
2552
- const abortError = createAbortError(reason);
2553
- requestController.abort(abortError);
2554
- if (abortMask === abortableMask) signalController.abort(abortError);
2555
- commitState({ type: "Aborted", abort: currentAbort() });
2567
+ abortControllers(createAbortError(reason), abortMask === abortableMask);
2568
+ publishState();
2556
2569
  };
2557
2570
 
2558
2571
  // The first provided exit claims the Run exit; later exits are ignored. A
@@ -2569,7 +2582,8 @@ const createRunInternal = <D extends object>(
2569
2582
 
2570
2583
  const settle = (): RunExit => {
2571
2584
  exit ??= ok(ok());
2572
- commitState({ type: "Settled", abort: currentAbort(), exit });
2585
+ state = { type: "Settled", abort: currentAbort(), exit };
2586
+ publishState();
2573
2587
  return exit;
2574
2588
  };
2575
2589
 
@@ -2590,14 +2604,39 @@ const createRunInternal = <D extends object>(
2590
2604
 
2591
2605
  const abortError = exit?.ok === false ? exit.error : runDisposedAbortError;
2592
2606
 
2607
+ // If called from a local abort callback, let its abort operation finish
2608
+ // dispatching callbacks before publishing the state.
2593
2609
  const { aborted } = signalController.signal;
2594
- requestController.abort(abortError);
2595
- signalController.abort(abortError);
2596
- if (!aborted) commitState({ type: "Aborted", abort: currentAbort() });
2610
+ abortControllers(abortError, true);
2611
+ if (!aborted) publishState();
2597
2612
 
2598
2613
  return disposePromise;
2599
2614
  };
2600
2615
 
2616
+ const abortControllers = (abortError: AbortError, observe: boolean): void => {
2617
+ // Record the request before propagation invokes descendant callbacks.
2618
+ if (!requestController.signal.aborted) {
2619
+ state = {
2620
+ type: "Aborted",
2621
+ abort: { request: abortError.reason, observed: null },
2622
+ };
2623
+ requestController.abort(abortError);
2624
+ }
2625
+
2626
+ // A descendant callback may have disposed this Run reentrantly. Preserve
2627
+ // the first observed reason; otherwise record it before local callbacks.
2628
+ if (observe && !signalController.signal.aborted) {
2629
+ state = {
2630
+ type: "Aborted",
2631
+ abort: {
2632
+ request: (requestController.signal.reason as AbortError).reason,
2633
+ observed: abortError.reason,
2634
+ },
2635
+ };
2636
+ signalController.abort(abortError);
2637
+ }
2638
+ };
2639
+
2601
2640
  // Custom deps replace parent custom deps, so defaults must be picked from
2602
2641
  // the merged deps by key. `satisfies RunDefaultDeps` fails to compile when
2603
2642
  // a newly added required default dep is missing here; optional ones like
package/src/Test.ts CHANGED
@@ -38,6 +38,8 @@ import { createId, type Id } from "./Type.ts";
38
38
  * }
39
39
  * assertFalse(Reflect.has(globalThis, key));
40
40
  * ```
41
+ *
42
+ * @group Testing
41
43
  */
42
44
  export const testStubGlobal = (
43
45
  key: PropertyKey,
@@ -58,6 +60,11 @@ export const testStubGlobal = (
58
60
  return disposer;
59
61
  };
60
62
 
63
+ /**
64
+ * Deterministic id factory returned by {@link testCreateId}.
65
+ *
66
+ * @group Testing
67
+ */
61
68
  export type TestCreateId = <B extends string = never>() => [B] extends [never]
62
69
  ? Id
63
70
  : Id & Brand<B>;
@@ -96,6 +103,8 @@ export type TestCreateId = <B extends string = never>() => [B] extends [never]
96
103
  * assertEqual(replayCreateId(), callbackId);
97
104
  * assertType<typeof todoId, Id & Brand<"Todo">>();
98
105
  * ```
106
+ *
107
+ * @group Testing
99
108
  */
100
109
  export const testCreateId = (): TestCreateId => {
101
110
  const randomBytes = testCreateRandomBytes({
package/src/Time.ts CHANGED
@@ -42,7 +42,11 @@ import {
42
42
  union,
43
43
  } from "./Type.ts";
44
44
 
45
- /** Time and timer operations. */
45
+ /**
46
+ * Time and timer operations.
47
+ *
48
+ * @group Core
49
+ */
46
50
  export interface Time {
47
51
  readonly now: {
48
52
  /** Returns current time as Unix epoch milliseconds. */
@@ -80,6 +84,11 @@ export interface Time {
80
84
  readonly clearTimeout: (id: TimeoutId) => void;
81
85
  }
82
86
 
87
+ /**
88
+ * Dependency wrapper for {@link Time}.
89
+ *
90
+ * @group Core
91
+ */
83
92
  export interface TimeDep {
84
93
  readonly time: Time;
85
94
  }
@@ -88,6 +97,8 @@ export interface TimeDep {
88
97
  * Opaque type for timeout handles.
89
98
  *
90
99
  * Use with {@link Time.clearTimeout} to cancel a pending timeout.
100
+ *
101
+ * @group Core
91
102
  */
92
103
  export type TimeoutId = Brand<"TimeoutId">;
93
104
 
@@ -107,6 +118,8 @@ interface TimeoutIdInternal {
107
118
  *
108
119
  * Throws if the system clock returns an out-of-range value. This is intentional
109
120
  * — there's no reasonable fallback for a misconfigured clock.
121
+ *
122
+ * @group Core
110
123
  */
111
124
  export const createTime = (): Time => {
112
125
  const timeoutOwner = Symbol("Time");
@@ -204,6 +217,8 @@ const clearTimeoutId = (owner: symbol, id: TimeoutId): void => {
204
217
  * Test {@link Time} with controllable timers.
205
218
  *
206
219
  * Call `advance(ms)` to move time forward and trigger any pending timeouts.
220
+ *
221
+ * @group Testing
207
222
  */
208
223
  export interface TestTime extends Time {
209
224
  /**
@@ -215,6 +230,11 @@ export interface TestTime extends Time {
215
230
  readonly advance: (duration: Duration) => void;
216
231
  }
217
232
 
233
+ /**
234
+ * Dependency wrapper for {@link TestTime}.
235
+ *
236
+ * @group Testing
237
+ */
218
238
  export interface TestTimeDep {
219
239
  readonly time: TestTime;
220
240
  }
@@ -230,6 +250,8 @@ export interface TestTimeDep {
230
250
  * wall-clock or performance `now()` call. `"microtask"` increments after the
231
251
  * current turn, while `"sync"` increments immediately after each read. Omit it
232
252
  * to keep time fixed until `advance()` is called.
253
+ *
254
+ * @group Testing
233
255
  */
234
256
  export const testCreateTime = (options?: {
235
257
  readonly startAt?: Millis;
@@ -341,6 +363,8 @@ const maxMillisWithInfinity = 281474976710655;
341
363
  *
342
364
  * If a system clock exceeds this range, operations will throw. This is
343
365
  * intentional — there's no reasonable fallback for a misconfigured clock.
366
+ *
367
+ * @group Millis
344
368
  */
345
369
  export const Millis = /*#__PURE__*/ brand(
346
370
  "Millis",
@@ -348,19 +372,33 @@ export const Millis = /*#__PURE__*/ brand(
348
372
  );
349
373
  export type Millis = typeof Millis.Output;
350
374
 
351
- /** Positive {@link Millis} value. */
375
+ /**
376
+ * Positive {@link Millis} value.
377
+ *
378
+ * @group Millis
379
+ */
352
380
  export const PositiveMillis = /*#__PURE__*/ positive(Millis);
353
381
  export type PositiveMillis = typeof PositiveMillis.Output;
354
382
 
355
- /** Minimum {@link Millis} value. */
383
+ /**
384
+ * Minimum {@link Millis} value.
385
+ *
386
+ * @group Millis
387
+ */
356
388
  export const minMillis = 0 as Millis;
357
389
 
358
- /** Maximum {@link Millis} value. */
390
+ /**
391
+ * Maximum {@link Millis} value.
392
+ *
393
+ * @group Millis
394
+ */
359
395
  export const maxMillis = (maxMillisWithInfinity - 1) as Millis;
360
396
 
361
397
  /**
362
398
  * Converts a number to {@link Millis}, rounding to the nearest millisecond and
363
399
  * saturating overflow at {@link maxMillis}.
400
+ *
401
+ * @group Millis
364
402
  */
365
403
  export const saturateMillis = (value: NonNaNNumber): Millis =>
366
404
  Millis.orNull(Math.max(0, Math.round(value))) ?? maxMillis;
@@ -370,23 +408,39 @@ export const saturateMillis = (value: NonNaNNumber): Millis =>
370
408
  *
371
409
  * This is a safe cast because {@link Millis} guarantees a valid timestamp range
372
410
  * that always produces a valid ISO string.
411
+ *
412
+ * @group Millis
373
413
  */
374
414
  export const millisToDateIso = (value: Millis): DateIso =>
375
415
  new Date(value).toISOString() as DateIso;
376
416
 
377
- /** Unix epoch milliseconds used as the origin for {@link PerformanceTime}. */
417
+ /**
418
+ * Unix epoch milliseconds used as the origin for {@link PerformanceTime}.
419
+ *
420
+ * @group Performance
421
+ */
378
422
  export type PerformanceTimeOrigin = number & Brand<"PerformanceTimeOrigin">;
379
423
 
380
- /** High-resolution milliseconds elapsed since {@link PerformanceTimeOrigin}. */
424
+ /**
425
+ * High-resolution milliseconds elapsed since {@link PerformanceTimeOrigin}.
426
+ *
427
+ * @group Performance
428
+ */
381
429
  export type PerformanceTime = number & Brand<"PerformanceTime">;
382
430
 
383
- /** Elapsed fractional milliseconds measured using {@link PerformanceTime}. */
431
+ /**
432
+ * Elapsed fractional milliseconds measured using {@link PerformanceTime}.
433
+ *
434
+ * @group Performance
435
+ */
384
436
  export type PerformanceDuration = number & Brand<"PerformanceDuration">;
385
437
 
386
438
  /**
387
439
  * Returns the elapsed fractional milliseconds between two performance times.
388
440
  *
389
441
  * Throws if `end` precedes `start`.
442
+ *
443
+ * @group Performance
390
444
  */
391
445
  export const performanceDurationBetween = (
392
446
  start: PerformanceTime,
@@ -412,6 +466,8 @@ export const performanceDurationBetween = (
412
466
  *
413
467
  * assertType<typeof readableSchedule, typeof validatedSchedule>();
414
468
  * ```
469
+ *
470
+ * @group Durations
415
471
  */
416
472
  export type Duration = DurationLiteral | Millis;
417
473
 
@@ -431,12 +487,18 @@ export type Duration = DurationLiteral | Millis;
431
487
  *
432
488
  * assertType<typeof readableSleep, typeof validatedSleep>();
433
489
  * ```
490
+ *
491
+ * @group Durations
434
492
  */
435
493
  export type PositiveDuration = DurationLiteral | PositiveMillis;
436
494
 
437
495
  // Keep these annotations concrete. Generic unit wrappers add thousands of
438
496
  // compiler instantiations to pnpm bench:type.
439
- /** Milliseconds duration: `"1ms"` to `"999ms"`. See {@link DurationLiteral}. */
497
+ /**
498
+ * Milliseconds duration: `"1ms"` to `"999ms"`. See {@link DurationLiteral}.
499
+ *
500
+ * @group Durations
501
+ */
440
502
  export const DurationLiteralMilliseconds: UnionType<
441
503
  readonly [
442
504
  TemplateLiteralType<readonly [typeof Digit1To9, "ms"]>,
@@ -456,6 +518,8 @@ export type DurationLiteralMilliseconds =
456
518
  /**
457
519
  * Seconds duration: `"1s"` to `"59s"` or `"1.1s"` to `"59.9s"`. See
458
520
  * {@link DurationLiteral}.
521
+ *
522
+ * @group Durations
459
523
  */
460
524
  export const DurationLiteralSeconds: UnionType<
461
525
  readonly [
@@ -473,6 +537,8 @@ export type DurationLiteralSeconds = typeof DurationLiteralSeconds.Output;
473
537
  /**
474
538
  * Minutes duration: `"1m"` to `"59m"` or `"1.1m"` to `"59.9m"`. See
475
539
  * {@link DurationLiteral}.
540
+ *
541
+ * @group Durations
476
542
  */
477
543
  export const DurationLiteralMinutes: UnionType<
478
544
  readonly [
@@ -490,6 +556,8 @@ export type DurationLiteralMinutes = typeof DurationLiteralMinutes.Output;
490
556
  /**
491
557
  * Hours duration: `"1h"` to `"23h"` or `"1.1h"` to `"23.9h"`. See
492
558
  * {@link DurationLiteral}.
559
+ *
560
+ * @group Durations
493
561
  */
494
562
  export const DurationLiteralHours: UnionType<
495
563
  readonly [
@@ -507,6 +575,8 @@ export type DurationLiteralHours = typeof DurationLiteralHours.Output;
507
575
  /**
508
576
  * Days duration: `"1d"` to `"6d"` or `"1.1d"` to `"6.9d"`. See
509
577
  * {@link DurationLiteral}.
578
+ *
579
+ * @group Durations
510
580
  */
511
581
  export const DurationLiteralDays: UnionType<
512
582
  readonly [
@@ -524,6 +594,8 @@ export type DurationLiteralDays = typeof DurationLiteralDays.Output;
524
594
  /**
525
595
  * Weeks duration: `"1w"` to `"51w"` or `"1.1w"` to `"51.9w"`. See
526
596
  * {@link DurationLiteral}.
597
+ *
598
+ * @group Durations
527
599
  */
528
600
  export const DurationLiteralWeeks: UnionType<
529
601
  readonly [
@@ -541,6 +613,8 @@ export type DurationLiteralWeeks = typeof DurationLiteralWeeks.Output;
541
613
  /**
542
614
  * Years duration: `"1y"` to `"99y"` or `"1.1y"` to `"99.9y"`. See
543
615
  * {@link DurationLiteral}.
616
+ *
617
+ * @group Durations
544
618
  */
545
619
  export const DurationLiteralYears: UnionType<
546
620
  readonly [
@@ -555,6 +629,12 @@ export const DurationLiteralYears: UnionType<
555
629
  );
556
630
  export type DurationLiteralYears = typeof DurationLiteralYears.Output;
557
631
 
632
+ /**
633
+ * Duration literal string, from {@link DurationLiteralMilliseconds} to
634
+ * {@link DurationLiteralYears}.
635
+ *
636
+ * @group Durations
637
+ */
558
638
  export type DurationLiteral =
559
639
  | DurationLiteralMilliseconds
560
640
  | DurationLiteralSeconds
@@ -622,6 +702,8 @@ const durationLiteralSyntax = /*#__PURE__*/ union(
622
702
  * assertOk(DurationLiteral.fromUnknown(literal), "1.5s");
623
703
  * assertFalse(DurationLiteral.is("1000ms"));
624
704
  * ```
705
+ *
706
+ * @group Durations
625
707
  */
626
708
  export const DurationLiteral: Type<
627
709
  "DurationLiteral",
@@ -640,7 +722,11 @@ export const DurationLiteral: Type<
640
722
  `The value ${safelyStringifyUnknownValue(error.value)} is not a duration literal. Use a value such as "500ms" or "1.5s".`,
641
723
  );
642
724
 
643
- /** Error returned when {@link DurationLiteral} rejects a value. */
725
+ /**
726
+ * Error returned when {@link DurationLiteral} rejects a value.
727
+ *
728
+ * @group Durations
729
+ */
644
730
  export interface DurationLiteralError extends TypeError<"DurationLiteral"> {
645
731
  readonly value: unknown;
646
732
  /**
@@ -668,6 +754,8 @@ export interface DurationLiteralError extends TypeError<"DurationLiteral"> {
668
754
  * assertEqual(durationToMillis("1w"), 604800000);
669
755
  * assertEqual(durationToMillis(Millis.orThrow(5000)), 5000);
670
756
  * ```
757
+ *
758
+ * @group Durations
671
759
  */
672
760
  export function durationToMillis(
673
761
  duration: DurationLiteral | PositiveMillis,
@@ -704,6 +792,8 @@ const durationUnits = {
704
792
  * Frame budget at 60fps (16ms).
705
793
  *
706
794
  * Work exceeding this blocks a frame, causing visible jank in animations.
795
+ *
796
+ * @group Millis
707
797
  */
708
798
  export const ms60fps = 16 as Millis;
709
799
 
@@ -711,6 +801,8 @@ export const ms60fps = 16 as Millis;
711
801
  * Frame budget at 120fps (8ms).
712
802
  *
713
803
  * For high refresh rate displays. Work exceeding this blocks a frame.
804
+ *
805
+ * @group Millis
714
806
  */
715
807
  export const ms120fps = 8 as Millis;
716
808
 
@@ -720,6 +812,7 @@ export const ms120fps = 8 as Millis;
720
812
  * Tasks exceeding this are "long tasks" per web standards. Use with
721
813
  * {@link yieldNow} to yield periodically and keep UI responsive.
722
814
  *
815
+ * @group Millis
723
816
  * @see https://web.dev/articles/optimize-long-tasks
724
817
  */
725
818
  export const msLongTask = 50 as Millis;
@@ -752,6 +845,8 @@ export const msLongTask = 50 as Millis;
752
845
  * "1d1h1m1.000s",
753
846
  * );
754
847
  * ```
848
+ *
849
+ * @group Millis
755
850
  */
756
851
  export const formatMillisAsDuration = (millis: Millis): string => {
757
852
  const seconds = ((millis % durationUnits.m) / durationUnits.s).toFixed(3);
@@ -796,6 +891,8 @@ export const formatMillisAsDuration = (millis: Millis): string => {
796
891
  * "14:32:15.234",
797
892
  * );
798
893
  * ```
894
+ *
895
+ * @group Millis
799
896
  */
800
897
  export const formatMillisAsClockTime = (millis: Millis): string => {
801
898
  const date = new Date(millis);