@agoric/time 0.3.3-upgrade-14-dev-0169c7e.0 → 0.3.3-upgrade-16-dev-8879538.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/index.js CHANGED
@@ -1,2 +1,4 @@
1
1
  export * from './src/timeMath.js';
2
2
  export * from './src/typeGuards.js';
3
+ // eslint-disable-next-line import/export -- just types
4
+ export * from './src/types.js';
package/package.json CHANGED
@@ -1,18 +1,19 @@
1
1
  {
2
2
  "name": "@agoric/time",
3
- "version": "0.3.3-upgrade-14-dev-0169c7e.0+0169c7e",
3
+ "version": "0.3.3-upgrade-16-dev-8879538.0+8879538",
4
4
  "description": "Timestamps, time math, timer service API definition",
5
5
  "type": "module",
6
6
  "main": "index.js",
7
+ "types": "index.js",
7
8
  "engines": {
8
- "node": ">=14.15.0"
9
+ "node": "^18.12 || ^20.9"
9
10
  },
10
11
  "scripts": {
11
12
  "build": "exit 0",
12
13
  "test": "ava",
13
14
  "test:xs": "exit 0",
14
15
  "lint": "run-s --continue-on-error lint:*",
15
- "lint:types": "tsc -p jsconfig.json",
16
+ "lint:types": "tsc",
16
17
  "lint:eslint": "eslint .",
17
18
  "lint-fix": "yarn lint:eslint --fix"
18
19
  },
@@ -30,14 +31,22 @@
30
31
  },
31
32
  "homepage": "https://github.com/Agoric/agoric-sdk#readme",
32
33
  "dependencies": {
33
- "@agoric/assert": "0.6.1-upgrade-14-dev-0169c7e.0+0169c7e",
34
- "@agoric/store": "0.9.3-upgrade-14-dev-0169c7e.0+0169c7e",
35
- "@endo/nat": "4.1.27"
34
+ "@agoric/assert": "0.6.1-upgrade-16-dev-8879538.0+8879538",
35
+ "@endo/nat": "^5.0.7",
36
+ "@endo/patterns": "^1.4.0"
36
37
  },
37
38
  "devDependencies": {
38
- "@endo/far": "0.2.18",
39
- "@endo/init": "0.5.56",
40
- "ava": "^5.2.0"
39
+ "@endo/far": "^1.1.2",
40
+ "@endo/init": "^1.1.2",
41
+ "ava": "^5.3.0"
42
+ },
43
+ "ava": {
44
+ "require": [
45
+ "@endo/init/debug.js"
46
+ ],
47
+ "files": [
48
+ "test/**/*.test.*"
49
+ ]
41
50
  },
42
51
  "files": [
43
52
  "*.js",
@@ -47,5 +56,8 @@
47
56
  "publishConfig": {
48
57
  "access": "public"
49
58
  },
50
- "gitHead": "0169c7e505099fdcfa8e4d1436e5d3b372f1c320"
59
+ "typeCoverage": {
60
+ "atLeast": 87.29
61
+ },
62
+ "gitHead": "8879538cd1d125a08346f02dd5701d0d70c90bb8"
51
63
  }
package/src/timeMath.js CHANGED
@@ -1,17 +1,10 @@
1
- import { mustMatch } from '@agoric/store';
2
1
  import { Nat } from '@endo/nat';
2
+ import { mustMatch } from '@endo/patterns';
3
3
  import { RelativeTimeRecordShape, TimestampRecordShape } from './typeGuards.js';
4
4
 
5
+ /** @import {RelativeTime, RelativeTimeValue, TimerBrand, TimeMathType, Timestamp, TimestampRecord, TimestampValue} from './types.js' */
6
+
5
7
  const { Fail, quote: q } = assert;
6
- /**
7
- * @typedef {import('./types').TimerBrand} TimerBrand
8
- * @typedef {import('./types').Timestamp} Timestamp
9
- * @typedef {import('./types').RelativeTime} RelativeTime
10
- * @typedef {import('./types').RelativeTimeValue} RelativeTimeValue
11
- * @typedef {import('./types').TimestampValue} TimestampValue
12
- * @typedef {import('./types').TimeMathType} TimeMathType
13
- *
14
- */
15
8
 
16
9
  /**
17
10
  * `agreedTimerBrand` is internal to this module.
@@ -200,7 +193,7 @@ const modRelRel = (rel, step) =>
200
193
  * @param {Timestamp | RelativeTime} right
201
194
  * @param {bigint} v1
202
195
  * @param {bigint} v2
203
- * @returns {RankComparison}
196
+ * @returns {import('@endo/marshal').RankComparison}
204
197
  */
205
198
  const compareValues = (left, right, v1, v2) => {
206
199
  sharedTimerBrand(left, right);
@@ -253,7 +246,9 @@ export const TimeMath = harden({
253
246
  relValue,
254
247
  coerceTimestampRecord,
255
248
  coerceRelativeTimeRecord,
249
+ // @ts-expect-error xxx dynamic typing
256
250
  addAbsRel,
251
+ // @ts-expect-error xxx dynamic typing
257
252
  addRelRel,
258
253
  subtractAbsAbs,
259
254
  clampedSubtractAbsAbs,
package/src/typeGuards.js CHANGED
@@ -1,4 +1,4 @@
1
- import { M } from '@agoric/store';
1
+ import { M } from '@endo/patterns';
2
2
 
3
3
  export const TimerBrandShape = M.remotable('TimerBrand');
4
4
  export const TimestampValueShape = M.nat();
package/src/types.d.ts CHANGED
@@ -1,22 +1,21 @@
1
- /* eslint-disable no-use-before-define, no-undef */
2
- import type { ERef } from '@endo/eventual-send';
1
+ import type { ERef, RemotableBrand } from '@endo/eventual-send';
3
2
 
4
- import type { RankComparison } from '@agoric/store';
3
+ import type { RankComparison, RemotableObject } from '@endo/marshal';
5
4
 
6
- /// <reference types="@agoric/notifier/src/types.js"/>
5
+ /// <reference types="@agoric/notifier/src/types.js" />
7
6
 
8
7
  // These aren't in the global runtime environment. They are just types that are
9
8
  // meant to be globally accessible as a side-effect of importing this module.
10
9
  /**
11
10
  * The TimerBrand is a unique object that represents the kind of Time
12
- * used in Timestamp/RelativeTime records. Time from different sources
13
- * is not comparable.
11
+ * used in Timestamp/RelativeTime records. Times from different sources
12
+ * are not comparable.
14
13
  *
15
14
  * Do not call `isMyTimerService(myTimerService)` on an untrusted
16
15
  * brand, because that will leak your closely-held timer authority. If
17
16
  * the goal is to check the suitability of a client-provided
18
17
  * Timestamp, use coerceTimestampRecord() or add/subtract it to a
19
- * known-good Timestamp, or extact its brand and === against
18
+ * known-good Timestamp, or extract its brand and === against
20
19
  * `timerService.getTimerBrand()`.
21
20
  *
22
21
  * TODO Not all Timestamps are labeled with the TimerBrand (in much
@@ -29,7 +28,7 @@ import type { RankComparison } from '@agoric/store';
29
28
  * See https://github.com/Agoric/agoric-sdk/issues/5798
30
29
  * and https://github.com/Agoric/agoric-sdk/pull/5821
31
30
  */
32
- export type TimerBrand = {
31
+ export type TimerBrand = RemotableObject & {
33
32
  isMyTimerService: (timer: TimerService) => ERef<boolean>;
34
33
  isMyClock: (clock: Clock) => ERef<boolean>;
35
34
  };
@@ -53,11 +52,21 @@ export type TimestampValue = bigint;
53
52
  */
54
53
  export type RelativeTimeValue = bigint;
55
54
 
55
+ /**
56
+ * The canonical representation of a typed absolute time. It bundles the brand
57
+ * with the time, as represented by a TimerService, which might represent time
58
+ * since the epoch, or blockheight on a particular chain.
59
+ */
56
60
  export type TimestampRecord = {
57
61
  timerBrand: TimerBrand;
58
62
  absValue: bigint;
59
63
  };
60
64
 
65
+ /**
66
+ * The canonical representation of a typed relative time. It bundles the brand
67
+ * with an elapsed time, as represented by a TimerService, which might represent
68
+ * time since the epoch, or blockheight on a particular chain.
69
+ */
61
70
  export type RelativeTimeRecord = {
62
71
  timerBrand: TimerBrand;
63
72
  relValue: bigint;
@@ -88,7 +97,8 @@ export type RelativeTime = RelativeTimeRecord | RelativeTimeValue;
88
97
  /**
89
98
  * A CancelToken is an arbitrary marker object, passed in with
90
99
  * each API call that creates a wakeup or repeater, and passed to
91
- * cancel() to cancel them all.
100
+ * cancel() to cancel them all. Multiple wakeups can rely on the same
101
+ * CancelToken so they can be cancelled collectively.
92
102
  */
93
103
  export type CancelToken = object;
94
104
 
@@ -97,7 +107,7 @@ export type CancelToken = object;
97
107
  * schedule a single wake() call, create a repeater that will allow scheduling
98
108
  * of events at regular intervals, or remove scheduled calls.
99
109
  */
100
- export interface TimerService {
110
+ export interface TimerServiceI {
101
111
  /**
102
112
  * Retrieve the latest timestamp
103
113
  */
@@ -111,7 +121,7 @@ export interface TimerService {
111
121
  cancelToken?: CancelToken,
112
122
  ) => TimestampRecord;
113
123
  /**
114
- * Create and return a promise that will resolve after the absolte
124
+ * Create and return a promise that will resolve after the absolute
115
125
  * time has passed.
116
126
  */
117
127
  wakeAt: (
@@ -157,7 +167,7 @@ export interface TimerService {
157
167
  delay: RelativeTime,
158
168
  interval: RelativeTime,
159
169
  cancelToken?: CancelToken,
160
- ) => Notifier<TimestampRecord>;
170
+ ) => import('@agoric/notifier').Notifier<TimestampRecord>;
161
171
  /**
162
172
  * Cancel a previously-established wakeup or repeater.
163
173
  */
@@ -171,7 +181,16 @@ export interface TimerService {
171
181
  */
172
182
  getTimerBrand: () => TimerBrand;
173
183
  }
184
+ // XXX copied from Remotable helper return type
185
+ export type TimerService = TimerServiceI &
186
+ RemotableObject<'TimerService'> &
187
+ RemotableBrand<{}, TimerServiceI>;
174
188
 
189
+ /**
190
+ * Read-only access to a TimeService's current time. This allows reading the
191
+ * current time (e.g. to see if a deadline has passed) without the ability to
192
+ * schedule events.
193
+ */
175
194
  export interface Clock {
176
195
  /**
177
196
  * Retrieve the latest timestamp
@@ -183,6 +202,11 @@ export interface Clock {
183
202
  getTimerBrand: () => TimerBrand;
184
203
  }
185
204
 
205
+ /**
206
+ * The interface that must be implemented by objects which are to be invoked at
207
+ * scheduled times. Used by `TimerService.repeatAfter()`,
208
+ * `TimerService.setWakeup()`, and `TimerRepeater.schedule()`.
209
+ */
186
210
  export interface TimerWaker {
187
211
  /**
188
212
  * The timestamp passed to `wake()` is the time that the call was scheduled
@@ -191,6 +215,12 @@ export interface TimerWaker {
191
215
  wake: (timestamp: TimestampRecord) => void;
192
216
  }
193
217
 
218
+ /**
219
+ * Provides the ability to schedule wake() calls repeatedly at a regular
220
+ * interval, or to disable all future use of this TimerRepeater. Created by the
221
+ * deprecated makeRepeater(), new code should use repeatAfter(), which doesn't
222
+ * have a control object and doesn't require a second schedule step
223
+ */
194
224
  export interface TimerRepeater {
195
225
  /**
196
226
  * Returns the time scheduled for
@@ -206,6 +236,26 @@ export interface TimerRepeater {
206
236
  disable: () => void;
207
237
  }
208
238
 
239
+ /**
240
+ * TimeMath supports simple arithmetic on typed Time values, enforcing that
241
+ * values are combined in type-compatible ways. You can add 3 minutes to 3pm,
242
+ * or 5 minutes to a half hour, but it makes no sense to add 3pm and 5pm.
243
+ * Subtracting two Timestamps does produce a useful difference.
244
+ *
245
+ * The brands prevent you from accidentally combining time values from different
246
+ * TimerServices. Some chains track time in blocks, others follow wall clock
247
+ * time, some do both. Every local computer has its own unique notion of wall
248
+ * clock time. Even when these clocks are talking about the same thing (UTC),
249
+ * they can all drift in different ways. Using the correct brands lets you be
250
+ * precise about which particular source of time you mean, preventing confusion
251
+ * or attacks when the clocks diverge. Thus it is an error to e.g. use a time
252
+ * you got from chain A to schedule an event on chain B.
253
+ *
254
+ * The basic types are `RelativeTimeRecord` (durations) and `TimestampRecord`. The numeric
255
+ * values can be extracted from the typed values, but it's usually better to
256
+ * maintain values as their canonical typed form so these operations can be
257
+ * applied.
258
+ */
209
259
  export type TimeMathType = {
210
260
  /**
211
261
  * Validates that the operand represents a `Timestamp` and returns the bigint
@@ -240,17 +290,19 @@ export type TimeMathType = {
240
290
  ) => RelativeTimeRecord;
241
291
  /**
242
292
  * An absolute time + a relative time gives a new absolute time.
243
- *
244
- * @template {Timestamp} T
245
293
  */
246
- addAbsRel: (abs: T, rel: RelativeTime) => T;
294
+ addAbsRel: <T extends Timestamp>(
295
+ abs: T,
296
+ rel: RelativeTime,
297
+ ) => T extends TimestampRecord ? TimestampRecord : TimestampValue;
247
298
  /**
248
299
  * A relative time (i.e., a duration) + another relative time
249
300
  * gives a new relative time.
250
- *
251
- * @template {RelativeTime} T
252
301
  */
253
- addRelRel: (rel1: T, rel2: T) => T;
302
+ addRelRel: <T extends RelativeTime>(
303
+ rel1: T,
304
+ rel2: T,
305
+ ) => T extends RelativeTimeRecord ? RelativeTimeRecord : RelativeTimeValue;
254
306
  /**
255
307
  * The difference between two absolute times is a relative time. If abs1 > abs2
256
308
  * the difference would be negative, so this method throws instead.
package/src/types.js ADDED
@@ -0,0 +1,2 @@
1
+ // Empty JS file to correspond with types.d.ts
2
+ export {};
package/CHANGELOG.md DELETED
@@ -1,69 +0,0 @@
1
- # Change Log
2
-
3
- All notable changes to this project will be documented in this file.
4
- See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
-
6
- ### [0.3.3-u13.0](https://github.com/Agoric/agoric-sdk/compare/@agoric/time@0.3.3-u12.0...@agoric/time@0.3.3-u13.0) (2023-12-07)
7
-
8
- **Note:** Version bump only for package @agoric/time
9
-
10
-
11
-
12
-
13
-
14
- ### [0.3.3-u12.0](https://github.com/Agoric/agoric-sdk/compare/@agoric/time@0.3.3-u11wf.0...@agoric/time@0.3.3-u12.0) (2023-11-10)
15
-
16
- **Note:** Version bump only for package @agoric/time
17
-
18
-
19
-
20
-
21
-
22
- ### [0.3.3-u11wf.0](https://github.com/Agoric/agoric-sdk/compare/@agoric/time@0.3.3-u11.0...@agoric/time@0.3.3-u11wf.0) (2023-09-23)
23
-
24
- **Note:** Version bump only for package @agoric/time
25
-
26
-
27
-
28
-
29
-
30
- ### [0.3.3-u11.0](https://github.com/Agoric/agoric-sdk/compare/@agoric/time@0.3.2...@agoric/time@0.3.3-u11.0) (2023-08-24)
31
-
32
- **Note:** Version bump only for package @agoric/time
33
-
34
-
35
-
36
-
37
-
38
- ### [0.3.2](https://github.com/Agoric/agoric-sdk/compare/@agoric/time@0.3.1...@agoric/time@0.3.2) (2023-06-02)
39
-
40
- **Note:** Version bump only for package @agoric/time
41
-
42
-
43
-
44
-
45
-
46
- ### [0.3.1](https://github.com/Agoric/agoric-sdk/compare/@agoric/time@0.3.0...@agoric/time@0.3.1) (2023-05-24)
47
-
48
- **Note:** Version bump only for package @agoric/time
49
-
50
-
51
-
52
-
53
-
54
- ## 0.3.0 (2023-05-19)
55
-
56
-
57
- ### Features
58
-
59
- * **auction:** add an auctioneer to manage vault liquidation ([#7000](https://github.com/Agoric/agoric-sdk/issues/7000)) ([398b70f](https://github.com/Agoric/agoric-sdk/commit/398b70f7e028f957afc1582f0ee31eb2574c94d0)), closes [#6992](https://github.com/Agoric/agoric-sdk/issues/6992) [#7047](https://github.com/Agoric/agoric-sdk/issues/7047) [#7074](https://github.com/Agoric/agoric-sdk/issues/7074)
60
- * create new @agoric/time package ([a61a3fb](https://github.com/Agoric/agoric-sdk/commit/a61a3fbb7a5ccfe07c715a310baa88ada8e572b2)), closes [#6003](https://github.com/Agoric/agoric-sdk/issues/6003)
61
-
62
-
63
- ### Bug Fixes
64
-
65
- * **time:** TimerService now returns branded TimestampRecord ([9137e9c](https://github.com/Agoric/agoric-sdk/commit/9137e9cab6f459c876b1a2ad8e681be7224749ce)), closes [#6003](https://github.com/Agoric/agoric-sdk/issues/6003)
66
- * clean up types ([6f53f19](https://github.com/Agoric/agoric-sdk/commit/6f53f1915ce21e65fefc2fff900b7d4b947be6b1))
67
- * move timer files to new package ([c105bde](https://github.com/Agoric/agoric-sdk/commit/c105bdefff2527a90b3c6b9d80d0462944dd51c3))
68
- * TimerBrand has isMyTimerService(), not isMyTimer() ([9f4e867](https://github.com/Agoric/agoric-sdk/commit/9f4e8670694504ebbd451c8840f900a1a24b902f))
69
- * **time:** fix the code/test to work in its new home ([504d333](https://github.com/Agoric/agoric-sdk/commit/504d3335cf632cc50e079fb27a82db604318bd4a))