pond-ts 0.68.0 → 0.70.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/README.md CHANGED
@@ -1,21 +1,44 @@
1
1
  # pond-ts
2
2
 
3
+ [![npm](https://img.shields.io/npm/v/pond-ts?label=pond-ts)](https://www.npmjs.com/package/pond-ts)
4
+ [![CI](https://github.com/pond-ts/pond/actions/workflows/ci.yml/badge.svg)](https://github.com/pond-ts/pond/actions/workflows/ci.yml)
5
+ [![license: MIT](https://img.shields.io/npm/l/pond-ts)](https://github.com/pond-ts/pond/blob/main/LICENSE)
6
+ [![docs](https://img.shields.io/badge/docs-pond--ts.org-1f6feb)](https://pond-ts.org)
7
+
3
8
  **Highly optimised, fully typed Timeseries library for TypeScript**
4
9
 
5
10
  Schema-driven events, composable batch transforms, push-based streaming
6
- ingest, multi-entity partitioning, and an optional React integration —
7
- all strict TypeScript end to end, all immutable.
11
+ ingest, multi-entity partitioning — and, optionally, React hooks and
12
+ canvas charts that read the series directly. All strict TypeScript end to
13
+ end, all immutable.
8
14
 
9
15
  **pond-ts** is the TypeScript-first successor to
10
16
  [pondjs](https://github.com/esnet/pond), rewritten from scratch with a
11
17
  focus on type safety, composability, and the live-streaming patterns
12
18
  that pondjs never grew.
13
19
 
20
+ ## The packages
21
+
22
+ Three packages carry most projects. The core has no dependency on the other
23
+ two; add them only if you render.
24
+
25
+ | Package | What it is | Needs |
26
+ | --------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- |
27
+ | **[`pond-ts`](https://www.npmjs.com/package/pond-ts)** — core | `TimeSeries` (batch) and `LiveSeries` (streaming) with one operator vocabulary: aggregate, rolling, align, fill, partition, join, typed columns. Node or browser, no React. | nothing |
28
+ | **[`@pond-ts/charts`](https://www.npmjs.com/package/@pond-ts/charts)** — optional | Declarative React charts on a canvas data plane that consume a pond series with no adapter: line, area, band, bar, scatter, box, candlestick, heat map; cursors, selection, pan/zoom, annotations. | `pond-ts`, `@pond-ts/react`, React 18/19 |
29
+ | **[`@pond-ts/react`](https://www.npmjs.com/package/@pond-ts/react)** — optional | Hooks to own a series in a component and read live views on a throttled snapshot cadence (`useLiveSeries`, `useSnapshot`, …). | `pond-ts`, React 18/19 |
30
+
14
31
  ```sh
15
- npm install pond-ts # core
16
- npm install @pond-ts/react # React hooks (optional)
32
+ npm install pond-ts # core — enough for Node pipelines and non-React apps
33
+ npm install @pond-ts/charts @pond-ts/react pond-ts # add the React chart stack
17
34
  ```
18
35
 
36
+ Two domain packages ([`@pond-ts/financial`](#domain-packages) for markets,
37
+ [`@pond-ts/fit`](#domain-packages) for activity data) and one experimental
38
+ runtime ([`@pond-ts/process`](#domain-packages)) sit on top — see
39
+ [Domain packages](#domain-packages) below. All six release together under
40
+ one version; keep them in step.
41
+
19
42
  - **Typed schemas** — declare once, every transform downstream narrows
20
43
  off it. `event.get('cpu')` returns `number | undefined` straight from
21
44
  the schema; no `as` casts.
@@ -108,6 +131,43 @@ The full live surface (`filter`, `map`, `select`, `window`, `aggregate`,
108
131
  `sample`) is incremental — events flow, views emit, retention bounds
109
132
  memory.
110
133
 
134
+ ## Quick start: charts (React)
135
+
136
+ `@pond-ts/charts` reads a `TimeSeries` or `LiveSeries` directly — do the maths
137
+ in pond, hand the result to a layer. Rows share one x scale, so they pan,
138
+ zoom and track the cursor together.
139
+
140
+ ```tsx
141
+ import {
142
+ BandChart,
143
+ ChartContainer,
144
+ ChartRow,
145
+ Layers,
146
+ LineChart,
147
+ YAxis,
148
+ } from '@pond-ts/charts';
149
+
150
+ // `bands` is the baseline() result from the batch quick start:
151
+ // cpu + avg / sd / upper / lower columns.
152
+ export function CpuChart({ width }: { width: number }) {
153
+ return (
154
+ <ChartContainer width={width} cursor="crosshair" panZoom>
155
+ <ChartRow height={240}>
156
+ <YAxis id="cpu" format=".0%" />
157
+ <Layers>
158
+ <BandChart series={bands} lower="lower" upper="upper" axis="cpu" />
159
+ <LineChart series={bands} column="cpu" axis="cpu" />
160
+ </Layers>
161
+ </ChartRow>
162
+ </ChartContainer>
163
+ );
164
+ }
165
+ ```
166
+
167
+ Pass `width="auto"` to measure the parent instead. Live data renders through
168
+ the same layers: own the series with `useLiveSeries` from `@pond-ts/react`
169
+ and pass its snapshot as `series`.
170
+
111
171
  ## Quick start: multi-entity
112
172
 
113
173
  `partitionBy` routes events into per-key buffers. Every stateful
@@ -182,6 +242,26 @@ it is behind. Run locally:
182
242
  npm run build && node packages/core/bench/vs-pondjs.cjs
183
243
  ```
184
244
 
245
+ ## Domain packages
246
+
247
+ Optional, domain-specific, all on plain pond series:
248
+
249
+ - **[`@pond-ts/financial`](https://www.npmjs.com/package/@pond-ts/financial)**
250
+ — sixty-plus oracle-verified technical studies (SMA, EMA, RSI, MACD,
251
+ Bollinger, ATR, VWAP, …) that append columns to a bar series, a fluent
252
+ `bars.sma({ period: 20 }).rsi({ period: 14 })` form, and a
253
+ `TradingCalendar` so session-aligned bars, rolling windows and chart axes
254
+ stop at the close.
255
+ - **[`@pond-ts/fit`](https://www.npmjs.com/package/@pond-ts/fit)** — fitness
256
+ and activity analytics: typed quantities with units, canonical activity
257
+ series, geo (distance, elevation, best efforts), power (NP / IF / TSS,
258
+ curves), heart-rate zones, splits.
259
+ - **[`@pond-ts/process`](https://www.npmjs.com/package/@pond-ts/process)** —
260
+ **experimental.** Computations as data: processing graphs authored fluently
261
+ or composed as JSON, resolved against a declared op vocabulary with
262
+ content-addressed caching, provenance and per-node timings. The API is
263
+ expected to move.
264
+
185
265
  ## Documentation
186
266
 
187
267
  The full guide is at **<https://pond-ts.org/>**.
@@ -233,20 +313,22 @@ the loop:
233
313
 
234
314
  ## Develop
235
315
 
236
- The repo is an npm-workspaces monorepo with two published packages
237
- (`pond-ts`, `@pond-ts/react`). Node 18+ for runtime; Node 20+ for the
316
+ The repo is an npm-workspaces monorepo with six published packages
317
+ (`pond-ts`, `@pond-ts/react`, `@pond-ts/charts`, `@pond-ts/financial`,
318
+ `@pond-ts/fit`, `@pond-ts/process`). Node 18+ for runtime; Node 20+ for the
238
319
  docs site (Docusaurus).
239
320
 
240
321
  ```sh
241
- npm install # one-time, hoists deps for both packages
322
+ npm install # one-time, hoists deps for all packages
242
323
  npm run build # build both packages
243
324
  npm test # runtime + type-level tests on both packages
244
325
  npm run format # prettier write across the repo
245
326
  npm run verify # format check + build + test (CI parity)
246
327
  ```
247
328
 
248
- `packages/core/` is the `pond-ts` package; `packages/react/` is
249
- `@pond-ts/react`. Docs live in `website/`.
329
+ Each package lives under `packages/<name>/` (`core` is `pond-ts`, the rest
330
+ match their scoped names). Docs live in `website/` — its own npm root, not a
331
+ workspace.
250
332
 
251
333
  ## License
252
334
 
@@ -4,7 +4,7 @@ import { Sequence } from '../sequence/sequence.js';
4
4
  import type { DurationInput } from '../core/duration.js';
5
5
  import type { TemporalLike } from '../core/temporal.js';
6
6
  import type { BatchSampleStrategy } from '../sequence/sample.js';
7
- import type { AggregateSchema, AlignSchema, AppendColumn, BaselineSchema, DedupeKeep, DiffSchema, EventDataForSchema, FillMapping, FillStrategy, MaterializeSchema, NumericColumnNameForSchema, RollingAlignment, RollingSchema, SeriesSchema, SmoothAppendSchema, SmoothMethod, SmoothSchema, ValidatedAggregateMap } from '../schema/index.js';
7
+ import type { AggregateSchema, AlignSchema, AppendColumn, BaselineSchema, DedupeKeep, DiffSchema, EventDataForSchema, ValueColumnsForSchema, FillMapping, FillStrategy, MaterializeSchema, NumericColumnNameForSchema, RollingAlignment, RollingSchema, SeriesSchema, SmoothAppendSchema, SmoothMethod, SmoothSchema, ValidatedAggregateMap } from '../schema/index.js';
8
8
  import type { ScanStep } from './operators/scan.js';
9
9
  type SequenceLike = Sequence | BoundedSequence;
10
10
  type AlignMethod = 'hold' | 'linear';
@@ -24,7 +24,7 @@ type AlignSample = 'begin' | 'center' | 'end';
24
24
  * the one actually passed — harmless because injected columns are already
25
25
  * optional.
26
26
  */
27
- export type WithPartitionColumns<Mapping, By extends string> = string extends By ? Mapping : Mapping & {
27
+ export type WithPartitionColumns<S extends SeriesSchema, Mapping, By extends string> = string extends By ? Mapping : string extends ValueColumnsForSchema<S>[number]['name'] ? Mapping : Mapping & {
28
28
  readonly [C in Exclude<By, keyof Mapping>]: 'first';
29
29
  };
30
30
  /**
@@ -74,6 +74,22 @@ export declare class PartitionedTimeSeries<S extends SeriesSchema, K extends str
74
74
  #private;
75
75
  readonly source: TimeSeries<S>;
76
76
  readonly by: ReadonlyArray<keyof EventDataForSchema<S> & string>;
77
+ /**
78
+ * Phantom, erased at runtime. Pins `By` **contravariantly** so a view
79
+ * partitioned by one column cannot be assigned where a view partitioned
80
+ * by another is claimed (`PartitionedTimeSeries<S, K, 'host'>` ←
81
+ * `partitionBy('region')` is an error), while a specialised view still
82
+ * assigns to the legacy `PartitionedTimeSeries<S>` / `<S, K>` shape.
83
+ * Without it `By` only appears inside a conditional in return positions
84
+ * and TypeScript treats it as freely convertible (Codex finding on #724).
85
+ *
86
+ * Spelling note: **`never` (the default) is the "any / unknown column"
87
+ * view**, and it is the top of this pin — every specialised view assigns
88
+ * to it. `string` is the *bottom* (a `string`-typed `By` assigns to any
89
+ * literal), so do not write `PartitionedTimeSeries<S, K, string>` to mean
90
+ * "any column"; the `partitionBy` overloads never produce it.
91
+ */
92
+ readonly __partitionColumns?: (by: By) => void;
77
93
  /**
78
94
  * Declared partition values when `partitionBy(col, { groups })` was
79
95
  * used. When set, `toMap` iterates in declared order (not insertion
@@ -266,13 +282,13 @@ export declare class PartitionedTimeSeries<S extends SeriesSchema, K extends str
266
282
  rolling<const Mapping extends ValidatedAggregateMap<S, Mapping>>(window: DurationInput, mapping: Mapping, options?: {
267
283
  alignment?: RollingAlignment;
268
284
  minSamples?: number;
269
- }): PartitionedTimeSeries<RollingSchema<S, WithPartitionColumns<Mapping, By>>, K, By>;
285
+ }): PartitionedTimeSeries<RollingSchema<S, WithPartitionColumns<S, Mapping, By>>, K, By>;
270
286
  rolling<const Mapping extends ValidatedAggregateMap<S, Mapping>>(sequence: SequenceLike, window: DurationInput, mapping: Mapping, options?: {
271
287
  alignment?: RollingAlignment;
272
288
  sample?: AlignSample;
273
289
  range?: TemporalLike;
274
290
  minSamples?: number;
275
- }): PartitionedTimeSeries<AggregateSchema<S, WithPartitionColumns<Mapping, By>>, K, By>;
291
+ }): PartitionedTimeSeries<AggregateSchema<S, WithPartitionColumns<S, Mapping, By>>, K, By>;
276
292
  /** Per-partition `smooth`. See {@link TimeSeries.smooth}. */
277
293
  smooth<const Target extends NumericColumnNameForSchema<S>, const Output extends string | undefined = undefined>(column: Target, method: SmoothMethod, options: {
278
294
  alpha: number;
@@ -332,7 +348,7 @@ export declare class PartitionedTimeSeries<S extends SeriesSchema, K extends str
332
348
  /** Per-partition `aggregate`. See {@link TimeSeries.aggregate}. */
333
349
  aggregate<const Mapping extends ValidatedAggregateMap<S, Mapping>>(sequence: SequenceLike, mapping: Mapping, options?: {
334
350
  range?: TemporalLike;
335
- }): PartitionedTimeSeries<AggregateSchema<S, WithPartitionColumns<Mapping, By>>, K, By>;
351
+ }): PartitionedTimeSeries<AggregateSchema<S, WithPartitionColumns<S, Mapping, By>>, K, By>;
336
352
  }
337
353
  export {};
338
354
  //# sourceMappingURL=partitioned-time-series.d.ts.map
@@ -1,5 +1,5 @@
1
- import { Temporal } from '@js-temporal/polyfill';
2
- export type CalendarUnit = 'day' | 'week' | 'month';
1
+ /** A calendar bucket unit. Boundaries are wall-clock in an IANA zone, so a `'day'` is 23, 24 or 25 hours across DST. */
2
+ export type CalendarUnit = 'day' | 'week' | 'month' | 'quarter' | 'year';
3
3
  export type WeekStartsOn = 1 | 2 | 3 | 4 | 5 | 6 | 7;
4
4
  export type TimeZoneOptions = {
5
5
  timeZone?: string;
@@ -10,9 +10,6 @@ export type CalendarOptions = TimeZoneOptions & {
10
10
  export declare function resolveTimeZone(options?: TimeZoneOptions): string;
11
11
  export declare function normalizeWeekStartsOn(value: number | undefined): WeekStartsOn;
12
12
  export declare function parseTimestampString(value: string, options?: TimeZoneOptions): number;
13
- export declare function toPlainDateStart(instantMs: number, timeZone: string, unit: CalendarUnit, weekStartsOn: WeekStartsOn): Temporal.PlainDate;
14
- export declare function plainDateToStart(date: Temporal.PlainDate, timeZone: string): Temporal.ZonedDateTime;
15
- export declare function nextCalendarStart(current: Temporal.PlainDate, unit: CalendarUnit): Temporal.PlainDate;
16
13
  export declare function dayRangeForDate(reference: string, options?: TimeZoneOptions): {
17
14
  start: number;
18
15
  end: number;
@@ -1,4 +1,5 @@
1
1
  import { Temporal } from '@js-temporal/polyfill';
2
+ import { TimeZone } from './time-zone.js';
2
3
  const DATE_ONLY_RE = /^\d{4}-\d{2}-\d{2}$/;
3
4
  const YEAR_MONTH_RE = /^\d{4}-\d{2}$/;
4
5
  const DATE_TIME_LOCAL_RE = /^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(?::\d{2}(?:\.\d{1,9})?)?$/;
@@ -42,51 +43,6 @@ export function parseTimestampString(value, options = {}) {
42
43
  }
43
44
  return Temporal.Instant.from(value).epochMilliseconds;
44
45
  }
45
- export function toPlainDateStart(instantMs, timeZone, unit, weekStartsOn) {
46
- // **Floor to the containing millisecond.** `Temporal.Instant` refuses a
47
- // fractional epoch ms outright — `fromEpochMilliseconds(1577836800000.37)`
48
- // throws `epoch milliseconds must be an integer` — and a fraction is not a
49
- // caller error here. A chart's wheel-zoom derives its view range from pixel
50
- // positions through `xScale.invert()`, so a perfectly ordinary gesture hands
51
- // us `1.7e12 + 0.37`; realizing a calendar sequence over that range then
52
- // crashed the page outright.
53
- //
54
- // Flooring is the only sane reading rather than a papering-over: the epoch
55
- // millisecond *is* the atomic unit of this model, so an over-precise input
56
- // can only mean the millisecond containing it, and calendar boundaries are
57
- // themselves whole milliseconds — so the bucket containing `t` and the one
58
- // containing `t + 0.37` are necessarily the same. Integer inputs are
59
- // untouched.
60
- //
61
- // `Math.floor`, not `Math.trunc`: before 1970 they disagree, and `-5.5` lies
62
- // inside the millisecond spanning `[-6, -5)`, which is `-6`.
63
- const zoned = Temporal.Instant.fromEpochMilliseconds(Math.floor(instantMs)).toZonedDateTimeISO(timeZone);
64
- const date = zoned.toPlainDate();
65
- if (unit === 'day') {
66
- return date;
67
- }
68
- if (unit === 'month') {
69
- return Temporal.PlainDate.from({
70
- year: date.year,
71
- month: date.month,
72
- day: 1,
73
- });
74
- }
75
- const offset = (date.dayOfWeek - weekStartsOn + 7) % 7;
76
- return date.subtract({ days: offset });
77
- }
78
- export function plainDateToStart(date, timeZone) {
79
- return date.toZonedDateTime({ timeZone }).startOfDay();
80
- }
81
- export function nextCalendarStart(current, unit) {
82
- if (unit === 'day') {
83
- return current.add({ days: 1 });
84
- }
85
- if (unit === 'week') {
86
- return current.add({ weeks: 1 });
87
- }
88
- return current.add({ months: 1 });
89
- }
90
46
  export function dayRangeForDate(reference, options = {}) {
91
47
  const timeZone = resolveTimeZone(options);
92
48
  const start = Temporal.PlainDate.from(reference)
@@ -102,12 +58,10 @@ export function calendarRangeForReference(unit, reference, options = {}) {
102
58
  const timeZone = resolveTimeZone(options);
103
59
  const weekStartsOn = normalizeWeekStartsOn(options.weekStartsOn);
104
60
  const referenceMs = parseTimestampString(reference, { timeZone });
105
- const startDate = toPlainDateStart(referenceMs, timeZone, unit, weekStartsOn);
106
- const start = plainDateToStart(startDate, timeZone);
107
- const end = plainDateToStart(nextCalendarStart(startDate, unit), timeZone);
61
+ const zone = TimeZone.of(timeZone);
108
62
  return {
109
- start: start.epochMilliseconds,
110
- end: end.epochMilliseconds,
63
+ start: zone.startOf(unit, referenceMs, { weekStartsOn }),
64
+ end: zone.next(unit, referenceMs, { weekStartsOn }),
111
65
  };
112
66
  }
113
67
  //# sourceMappingURL=calendar.js.map
@@ -6,4 +6,6 @@ export type { DurationInput, DurationUnit } from './duration.js';
6
6
  export { ValidationError } from './errors.js';
7
7
  export type { EventKey, IntervalInput, IntervalValue, TemporalLike, TimeRangeInput, TimestampInput, } from './temporal.js';
8
8
  export type { CalendarOptions, CalendarUnit, TimeZoneOptions, } from './calendar.js';
9
+ export { TimeZone } from './time-zone.js';
10
+ export type { Disambiguation, StartOfOptions, ZonedParts, ZonedPartsInput, } from './time-zone.js';
9
11
  //# sourceMappingURL=index.d.ts.map
@@ -3,4 +3,5 @@ export { Interval } from './interval.js';
3
3
  export { Time } from './time.js';
4
4
  export { TimeRange, toTimeRange } from './time-range.js';
5
5
  export { ValidationError } from './errors.js';
6
+ export { TimeZone } from './time-zone.js';
6
7
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,122 @@
1
+ import type { CalendarUnit, WeekStartsOn } from './calendar.js';
2
+ /**
3
+ * How `TimeZone.instant()` resolves a wall-clock time that a transition
4
+ * makes ambiguous (a fall-back repeats an hour) or skips (a spring-forward
5
+ * drops one). Same vocabulary and same defaults as Temporal:
6
+ *
7
+ * - `'compatible'` (default) — the earlier instant when the time repeats,
8
+ * the instant *after* the gap when it is skipped (02:30 on a spring-forward
9
+ * night becomes 03:30). This is also what `startOf('day')` needs on the
10
+ * rare days that have no midnight.
11
+ * - `'earlier'` / `'later'` — always the earlier / later of the two readings.
12
+ * - `'reject'` — throw a `RangeError` for either case.
13
+ */
14
+ export type Disambiguation = 'compatible' | 'earlier' | 'later' | 'reject';
15
+ /** The wall-clock reading of an instant in a zone. `weekday` is ISO: 1 = Monday … 7 = Sunday. */
16
+ export type ZonedParts = {
17
+ year: number;
18
+ month: number;
19
+ day: number;
20
+ hour: number;
21
+ minute: number;
22
+ second: number;
23
+ millisecond: number;
24
+ weekday: 1 | 2 | 3 | 4 | 5 | 6 | 7;
25
+ };
26
+ /** The date-and-time fields `TimeZone.instant()` accepts. Time fields default to zero. */
27
+ export type ZonedPartsInput = {
28
+ year: number;
29
+ month: number;
30
+ day: number;
31
+ hour?: number;
32
+ minute?: number;
33
+ second?: number;
34
+ millisecond?: number;
35
+ };
36
+ export type StartOfOptions = {
37
+ /** First day of the week for `'week'`, ISO numbering (1 = Monday, default) … 7 = Sunday. */
38
+ weekStartsOn?: WeekStartsOn;
39
+ };
40
+ declare function assertCalendarUnit(unit: string): asserts unit is CalendarUnit;
41
+ /**
42
+ * An IANA time zone as a calendar: the one place in pond that turns instants
43
+ * (UTC epoch milliseconds) into wall-clock readings and calendar boundaries,
44
+ * and back.
45
+ *
46
+ * Instances are interned — `TimeZone.of('Europe/Berlin')` returns the same
47
+ * object every time — and cache the zone's offset transitions as they are
48
+ * discovered, so after the first query in a stretch of history every call
49
+ * is integer arithmetic. `Sequence.calendar` buckets with it; the charts'
50
+ * time axis places and labels ticks with it; the two therefore agree on
51
+ * every boundary by construction.
52
+ *
53
+ * A `TimeZone` holds no instant. Values (`Time`, `TimeRange`, `Interval`)
54
+ * stay plain UTC milliseconds; the zone is a parameter to the code that
55
+ * interprets them.
56
+ */
57
+ export declare class TimeZone {
58
+ #private;
59
+ /** The canonical IANA identifier, e.g. `'America/New_York'` or `'UTC'`. */
60
+ readonly id: string;
61
+ private constructor();
62
+ /**
63
+ * Example: `TimeZone.of('Australia/Sydney')`. Looks up a zone by IANA
64
+ * identifier. Throws `RangeError` for an identifier the runtime does not
65
+ * know. Case-insensitive on input; `id` reports the canonical spelling.
66
+ * A fixed-offset identifier such as `'+05:30'` is accepted too, as
67
+ * Temporal accepts it, and behaves as a zone with a single segment.
68
+ */
69
+ static of(id: string): TimeZone;
70
+ /** Example: `TimeZone.UTC.startOf('month', t)`. The UTC zone. */
71
+ static get UTC(): TimeZone;
72
+ /**
73
+ * Example: `TimeZone.local()`. The runtime's own zone, as the environment
74
+ * reports it. Resolved on every call, so a test that changes `TZ` between
75
+ * calls sees the change.
76
+ */
77
+ static local(): TimeZone;
78
+ /** Example: `zone.offsetAt(t)`. The zone's UTC offset at an instant, in milliseconds east of UTC. */
79
+ offsetAt(ms: number): number;
80
+ /**
81
+ * Example: `zone.parts(t).hour`. The wall-clock reading of an instant in
82
+ * this zone.
83
+ */
84
+ parts(ms: number): ZonedParts;
85
+ /**
86
+ * Example: `zone.instant({ year: 2026, month: 3, day: 29, hour: 2, minute: 30 })`.
87
+ * The instant at which this zone's clocks read the given wall time. When
88
+ * a transition makes the reading ambiguous or nonexistent,
89
+ * `disambiguation` decides (default `'compatible'`, as Temporal).
90
+ */
91
+ instant(parts: ZonedPartsInput, options?: {
92
+ disambiguation?: Disambiguation;
93
+ }): number;
94
+ /**
95
+ * Example: `zone.startOf('week', t, { weekStartsOn: 7 })`. The first
96
+ * instant of the calendar unit containing `ms`, in this zone. On a day
97
+ * with no midnight (a spring-forward at 00:00) this is the first instant
98
+ * that exists, as `Temporal.ZonedDateTime.startOfDay` does.
99
+ */
100
+ startOf(unit: CalendarUnit, ms: number, options?: StartOfOptions): number;
101
+ /**
102
+ * Example: `zone.next('month', t)`. The first instant of the calendar unit
103
+ * *after* the one containing `ms` — i.e. the exclusive end of `startOf`'s
104
+ * bucket.
105
+ */
106
+ next(unit: CalendarUnit, ms: number, options?: StartOfOptions): number;
107
+ /**
108
+ * Example: `zone.abbreviation(t)` → `'EDT'`. The zone's short name at an
109
+ * instant, as `Intl` reports it for `locale` (default: the runtime's
110
+ * locale). Which zones have a conventional abbreviation is a locale
111
+ * question — `en-US` knows `EST`, `en-AU` knows `AEDT`, and neither knows
112
+ * the other's; the fallback is a `GMT±h[:mm]` offset string. Pass the
113
+ * viewer's locale when rendering.
114
+ */
115
+ abbreviation(ms: number, options?: {
116
+ locale?: string;
117
+ }): string;
118
+ toString(): string;
119
+ toJSON(): string;
120
+ }
121
+ export { assertCalendarUnit };
122
+ //# sourceMappingURL=time-zone.d.ts.map