Create a new RRStack.
Constructor options. timeUnit defaults to 'ms'.
Get the current IANA timezone id (unbranded string).
Move a rule to the bottom (last index).
Describe a rule by index as human-readable text. Leverages rrule.toText() plus effect and duration phrasing. *
Zero-based index into rules.
Move a rule down by one (toward the end). No-op if already at the bottom.
Format an instant using this stack's configured timezone and time unit.
t is interpreted as milliseconds since epoch.t is interpreted as integer seconds since epoch.Instant in the configured unit.
Optionalopts: { format?: string; locale?: string }Optional formatting:
A string representation (ISO by default).
Compute effective active bounds across all rules.
{ start?: number; end?: number; empty: boolean }
start and/or end are omitted for open-sided coverage.empty indicates no active coverage.const stack = new RRStack({
timezone: 'UTC',
rules: [{
effect: 'active',
duration: { hours: 1 },
options: { freq: 'daily', byhour: [5], byminute: [0], bysecond: [0], starts: Date.UTC(2024, 0, 10, 0, 0, 0) },
}],
});
const b = stack.getEffectiveBounds();
// b.start is 2024-01-10T05:00:00Z (number); b.end is undefined (open end)
Enumerate event instants within [from, to) that survive the coverage
cascade (i.e., are not suppressed by a blackout).
Start of the window (inclusive), in the configured unit.
End of the window (exclusive), in the configured unit.
An iterable of { at: number; label?: string } entries,
ordered chronologically.
Stream contiguous status segments over [from, to). *
Start of the window (inclusive), in the configured unit.
End of the window (exclusive), in the configured unit.
Optionalopts: { limit?: number }Optional settings:
An iterable of { start, end, status } entries. Memory-bounded
and stable for long windows.
for (const seg of stack.getSegments(from, to)) {
// { start: number; end: number; status: 'active' | 'blackout' }
}
const segs: Array<{ start: number; end: number; status: 'active' | 'blackout' }> = [];
try {
for (const seg of stack.getSegments(from, to, { limit: 1000 })) {
segs.push(seg);
}
} catch (err) {
// If more than 1000 segments would be produced, an Error is thrown.
// Consider reducing the window or processing in chunks (e.g., day/week).
}
Note: The iterator is streaming and memory-bounded, but the number of
segments can be large when many rules overlap across long windows.
Use the limit option to make this explicit, or query in smaller chunks
for real-time UIs.
Determine whether the stack is active at t.
Timestamp in the configured unit.
true when active; false when blackout.
Get the next event instant at or after t that survives the coverage cascade.
Optionalt: numberTimestamp in the configured unit (defaults to now).
OptionallookAhead: numberMaximum look-ahead window in the configured unit. Defaults to 366 days.
The next event instant, or undefined if none found in the window.
Return the current time in the configured unit.
Remove the rule at the specified index. Delegates to the rules setter (single recompile).
Zero-based index of the rule to remove.
Subscribe to post‑mutation notifications. The listener is invoked exactly once after a successful state change (after recompile). The constructor initialization does not trigger notifications.
Unsubscribe function.
Swap two rules by index (no-op if indices are equal).
Serialize the stack to JSON.
A RRStackOptions including version injected at build time * (fallback '0.0.0' in dev/test).
Move a rule to the top (index 0).
Move a rule up by one (toward index 0). No-op if already at the top.
Ingest a partial RRStackOptions JSON with version/unit handling, replacements, and notices.
StaticasValidate and brand a timezone id.
Candidate IANA timezone string.
The branded TimeZoneId.
StaticisValidate an IANA timezone id.
Candidate IANA timezone string.
True if recognized by the host ICU/Intl data.
Library entry point.