diff --git a/packages/time/src/types.d.ts b/packages/time/src/types.d.ts index c5ae0e2803a..f2efe31c124 100644 --- a/packages/time/src/types.d.ts +++ b/packages/time/src/types.d.ts @@ -8,14 +8,14 @@ import type { RankComparison } from '@endo/marshal'; // meant to be globally accessible as a side-effect of importing this module. /** * The TimerBrand is a unique object that represents the kind of Time - * used in Timestamp/RelativeTime records. Time from different sources - * is not comparable. + * used in Timestamp/RelativeTime records. Times from different sources + * are not comparable. * * Do not call `isMyTimerService(myTimerService)` on an untrusted * brand, because that will leak your closely-held timer authority. If * the goal is to check the suitability of a client-provided * Timestamp, use coerceTimestampRecord() or add/subtract it to a - * known-good Timestamp, or extact its brand and === against + * known-good Timestamp, or extract its brand and === against * `timerService.getTimerBrand()`. * * TODO Not all Timestamps are labeled with the TimerBrand (in much @@ -52,11 +52,21 @@ export type TimestampValue = bigint; */ export type RelativeTimeValue = bigint; +/** + * The canonical representation of a typed absolute time. It bundles the brand + * with the time, as represented by a TimerService, which might represent time + * since the epoch, or blockheight on a particular chain. + */ export type TimestampRecord = { timerBrand: TimerBrand; absValue: bigint; }; +/** + * The canonical representation of a typed relative time. It bundles the brand + * with an elapsed time, as represented by a TimerService, which might represent + * time since the epoch, or blockheight on a particular chain. + */ export type RelativeTimeRecord = { timerBrand: TimerBrand; relValue: bigint; @@ -87,7 +97,8 @@ export type RelativeTime = RelativeTimeRecord | RelativeTimeValue; /** * A CancelToken is an arbitrary marker object, passed in with * each API call that creates a wakeup or repeater, and passed to - * cancel() to cancel them all. + * cancel() to cancel them all. Multiple wakeups can rely on the same + * CancelToken so they can be cancelled collectively. */ export type CancelToken = object; @@ -171,6 +182,11 @@ export interface TimerService { getTimerBrand: () => TimerBrand; } +/** + * Read-only access to a TimeService's current time. This allows reading the + * current time (e.g. to see if a deadline has passed) without the ability to + * schedule events. + */ export interface Clock { /** * Retrieve the latest timestamp @@ -182,6 +198,11 @@ export interface Clock { getTimerBrand: () => TimerBrand; } +/** + * The interface that must be implemented by objects which are to be invoked at + * scheduled times. Used by `TimerService.repeatAfter()`, + * `TimerService.setWakeup()`, and `TimerRepeater.schedule()`. + */ export interface TimerWaker { /** * The timestamp passed to `wake()` is the time that the call was scheduled @@ -190,6 +211,12 @@ export interface TimerWaker { wake: (timestamp: TimestampRecord) => void; } +/** + * Provides the ability to schedule wake() calls repeatedly at a regular + * interval, or to disable all future use of this TimerRepeater. Created by the + * deprecated makeRepeater(), new code should use repeatAfter(), which doesn't + * have a control object and doesn't require a second schedule step + */ export interface TimerRepeater { /** * Returns the time scheduled for @@ -205,6 +232,26 @@ export interface TimerRepeater { disable: () => void; } +/** + * TimeMath supports simple arithmetic on typed Time values, enforcing that + * values are combined in type-compatible ways. You can add 3 minutes to 3pm, + * or 5 minutes to a half hour, but it makes no sense to add 3pm and 5pm. + * Subtracting two Timestamps does produce a useful difference. + * + * The brands prevent you from accidentally combining time values from different + * TimerServices. Some chains track time in blocks, others follow wall clock + * time, some do both. Every local computer has its own unique notion of wall + * clock time. Even when these clocks are talking about the same thing (UTC), + * they can all drift in different ways. Using the correct brands lets you be + * precise about which particular source of time you mean, preventing confusion + * or attacks when the clocks diverge. Thus it is an error to e.g. use a time + * you got from chain A to schedule an event on chain B. + * + * The basic types are `RelativeTimeRecord` (durations) and `TimestampRecord`. The numeric + * values can be extracted from the typed values, but it's usually better to + * maintain values as their canonical typed form so these operations can be + * applied. + */ export type TimeMathType = { /** * Validates that the operand represents a `Timestamp` and returns the bigint