@danxbot/ui 7.9.3 → 7.9.6

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.
@@ -119,7 +119,7 @@ export { applyCalendarDelta, calendarDragResult, createdEvent, describeTarget, r
119
119
  export { EVENT_PALETTE, DEFAULT_PALETTE_KEY, isPaletteKey, paletteFor, } from "./components/calendar/palette";
120
120
  export { cellLabel, eventLabel, formatDateRange, longDate, monthTitle, timeOfDay, weekdayName, zoneLabel, } from "./components/calendar/format";
121
121
  export { initialFocusDay, isInMonth, nextDayForKey, useGridNavigation, type GridNavigation, type GridNavigationOptions, } from "./components/calendar/use-grid-navigation";
122
- export { AmbiguousTimeError, addDays, addDuration, addMonths, atMidnight, atTime, comparePlainDate, dayFraction, dayLengthMs, dayOfWeek, daysBetween, daysInMonth, endOfMonth, hoursInDay, instantAtFraction, instantToPlainDate, instantToPlainDateTime, isSameDate, isoDateString, isoDateTimeString, monthGridDays, nextDay, offsetAt, parsePlainDate, plainDateTimeToInstant, startOfDay, startOfMonth, startOfWeek, weekDays, type CalendarDuration, type Disambiguation, type Instant, type PlainDate, type PlainDateTime, type TimeZone, } from "./lib/time";
122
+ export { AmbiguousTimeError, addDays, addDuration, addMonths, atMidnight, atTime, comparePlainDate, dayFraction, dayLengthMs, dayOfWeek, daysBetween, daysInMonth, endOfMonth, hoursInDay, instantAtFraction, instantToPlainDate, instantToPlainDateTime, isSameDate, isoDateString, isoDateTimeString, monthGridDays, nextDay, offsetAt, parsePlainDate, plainDateTimeToInstant, relativeAge, startOfDay, startOfMonth, startOfWeek, weekDays, type CalendarDuration, type Disambiguation, type Instant, type PlainDate, type PlainDateTime, type TimeZone, } from "./lib/time";
123
123
  export { allDayBandSegment, dayKey, daySlots, isAllDay, packBand, packLanes, snapFractionToInstant, timeSegments, timedBandSegment, type AllDayEvent, type BandInput, type BandOptions, type BandPlacement, type BandResult, type BandSegment, type CalendarEvent, type CalendarEventId, type CalendarView, type DaySlot, type DragKind, type EventDraft, type EventPalette, type LaneInput, type LaneOptions, type LanePlacement, type PaletteEntry, type TimeSegment, type TimedEvent, type VisibleRange, } from "./lib/calendar";
124
124
  export { RBACProvider, useRBAC, AccountMenu, DevToolsPopover, RolePermissionMatrix, ProfilePage, RolesPermissionsPage, type RBACProviderProps, type RBACHookResult, type AccountMenuProps, type DevToolsPopoverProps, type RolePermissionMatrixProps, type Permission, type Role, type User, type Team, type TeamMembership, } from "./components/rbac";
125
125
  export { UseCaseCard, RoadmapItemCard, RoadmapSwimlaneBoard, UseCaseLedgerPage, RoadmapPage, PhaseManager, TrackManager, deriveRoadmapItemStatus, isFullyBuilt, isUnbuilt, trackIds, trackProgress, toneForIndex, CATEGORY_TONES, type Domain, type Phase, type Track, type RoadmapItem, type RoadmapItemStatus, type UseCase, type UseCaseStatus, type UseCaseDecision, type UseCaseCardProps, type RoadmapItemCardProps, type RoadmapSwimlaneBoardProps, type UseCaseLedgerPageProps, type RoadmapPageProps, type PhaseManagerProps, type TrackManagerProps, } from "./components/roadmap";
@@ -82,6 +82,38 @@ export declare class SubscriptionRegistry {
82
82
  * never touch realtime at all.
83
83
  */
84
84
  start(): void;
85
+ /**
86
+ * The document became visible again, or the page was restored from the
87
+ * back/forward cache — either way, a gap of UNKNOWN length just ended.
88
+ *
89
+ * `pusher:subscription_succeeded`/`state_change` (what `onConnectionState`
90
+ * listens for) is the transport TELLING us the socket dropped and came
91
+ * back. It is not the only way a gap happens: the OS suspending the
92
+ * machine, or the browser freezing a backgrounded tab under memory
93
+ * pressure, pauses this process's OWN timers along with everything else —
94
+ * including whatever ping/pong loop the transport uses to notice its own
95
+ * connection died. A transport that never got to run its detection code
96
+ * has nothing to report, so `connectionState()` can read "connected"
97
+ * throughout a gap the socket did not actually survive, and `tick()`'s own
98
+ * `isDead()` check — which trusts that string — has nothing to catch.
99
+ *
100
+ * Pusher has no event replay. Broadcasting is also gated server-side on a
101
+ * short-TTL registration (`PusherSubscriptionService`, 300s) that a long
102
+ * enough gap can outlive on its own. Either way, "did we actually miss
103
+ * anything" has no answer worth computing — the same reasoning
104
+ * `onConnectionState`'s reconnect branch already acts on — so becoming
105
+ * visible again is treated exactly like a reconnect: every entry is
106
+ * resubscribed (which the SubscriptionRegistry itself dedupes against
107
+ * one that is still genuinely healthy — a resubscribe is bounded, cheap,
108
+ * and correctness-preserving even when it turns out to have been
109
+ * unnecessary), and the epoch bumps on each success, which is what
110
+ * drives every mounted read (`reads/refetch.ts`'s `onEpoch`) to reissue
111
+ * the request it already made.
112
+ */
113
+ private onResume;
114
+ private handleVisibilityChange;
115
+ /** `event.persisted` is a bfcache restore — a full page resume with no `visibilitychange` of its own. */
116
+ private handlePageShow;
85
117
  /**
86
118
  * Stop the timers. REVERSIBLE, and it keeps every entry and every channel.
87
119
  *
@@ -1,3 +1,4 @@
1
1
  export { AmbiguousTimeError, isoDateString, isoDateTimeString, type CalendarDuration, type Disambiguation, type Instant, type PlainDate, type PlainDateTime, type TimeZone, } from "./types";
2
2
  export { addDuration, dayFraction, dayLengthMs, hoursInDay, instantAtFraction, instantToPlainDate, instantToPlainDateTime, nextDay, offsetAt, plainDateTimeToInstant, startOfDay, } from "./zone";
3
3
  export { addDays, addMonths, atMidnight, atTime, comparePlainDate, dayOfWeek, daysBetween, daysInMonth, endOfMonth, isSameDate, monthGridDays, parsePlainDate, startOfMonth, startOfWeek, weekDays, } from "./plain";
4
+ export { relativeAge } from "./relativeAge";
@@ -0,0 +1,14 @@
1
+ /**
2
+ * A moment's age in words: "just now", "4m ago", "4h ago", "1d 6h ago",
3
+ * "2w ago".
4
+ *
5
+ * Stays two-unit only in the day range (a message from earlier today reads
6
+ * as "6h ago", not "0d 6h ago") — days-plus-hours is the one range where a
7
+ * single unit throws away information a reader of a chat transcript actually
8
+ * wants ("this morning" vs "yesterday afternoon" are different facts, and
9
+ * "1d ago" collapses both). Beyond a week it drops to whole weeks, same as
10
+ * every sibling formatter in this codebase — nobody needs "9d ago" instead
11
+ * of "1w 2d ago", and nobody needs either instead of a calendar date, but a
12
+ * chat message's hover row has no room for a calendar date, so weeks it is.
13
+ */
14
+ export declare function relativeAge(when: string | number | Date): string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danxbot/ui",
3
- "version": "7.9.3",
3
+ "version": "7.9.6",
4
4
  "type": "module",
5
5
  "description": "Danxbot — a domain-agnostic React design system with motion as a first-class primitive.",
6
6
  "license": "MIT",