@opencxh/domain 1.151.0 → 1.153.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.
@@ -72,14 +72,20 @@ export interface ToolSource {
72
72
  /** A second line: a snippet, a date, an author. */
73
73
  detail?: string;
74
74
  /**
75
- * Shell-absolute in-product route, including the `/apps/<app>` prefix — the
76
- * source may well belong to a different app than the one showing it.
75
+ * Where to open this source. Two forms, told apart by their first character:
77
76
  *
78
- * Follow it with the **kernel** router (`sdk` from `@opencxh/app-sdk`), not an
79
- * app's own: `createApp().router.navigate` prefixes the calling app's id, which
80
- * would turn `/apps/kb/…` into `/apps/ai/apps/kb/…`.
77
+ * - **`/…`** — a shell-absolute in-product route, including the `/apps/<app>`
78
+ * prefix, since the source may well belong to a different app than the one
79
+ * showing it. Follow it with the **kernel** router (`sdk` from
80
+ * `@opencxh/app-sdk`), not an app's own: `createApp().router.navigate`
81
+ * prefixes the calling app's id, which would turn `/apps/kb/…` into
82
+ * `/apps/ai/apps/kb/…`.
83
+ * - **`http(s)://…`** — somewhere outside the platform, opened in a new tab.
84
+ * A Shopify order lives in Shopify's admin and nowhere here; pretending
85
+ * otherwise would mean either a dead in-product link or dropping the only
86
+ * address the thing has.
81
87
  *
82
- * Absent when the thing has no page of its own — a memory item, for instance —
88
+ * Absent when the thing has no page at all — a memory item, for instance —
83
89
  * which is a reason to show it without a link, not a reason to hide it.
84
90
  */
85
91
  url?: string;
@@ -9,7 +9,8 @@
9
9
  export declare const PRESENCE_ONLINE_WINDOW_MS = 90000;
10
10
  /**
11
11
  * Effective presence status. `offline` is derived from connectivity (stale
12
- * `lastSeenAt`) and always wins; the rest are set by the user or a provider.
12
+ * `lastSeenAt`) and wins over anything you set — except the statuses in
13
+ * {@link PRESENCE_SURVIVES_OFFLINE}; the rest are set by the user or a provider.
13
14
  */
14
15
  export type PresenceStatus = "available" | "away" | "busy" | "dnd" | "out_of_office" | "offline";
15
16
  /** Statuses a user (or provider) can set — `offline` is derived, not settable. */
@@ -43,3 +44,56 @@ export interface PresenceStatusInput {
43
44
  /** Unix ms after which the status auto-clears (falls back to derived). */
44
45
  expiresAt?: number;
45
46
  }
47
+ /**
48
+ * A user's stored availability, as the server persists it. Connectivity is not
49
+ * in here — that stays derived from `lastSeenAt` on an installation.
50
+ */
51
+ export interface StoredPresenceStatus {
52
+ status?: string;
53
+ message?: string;
54
+ /** Unix ms after which the status no longer applies. */
55
+ expiresAt?: number;
56
+ /** `"manual"` or a providerId (e.g. `"microsoft"`). */
57
+ source?: string;
58
+ }
59
+ /**
60
+ * Statuses that mean "I am not at my desk" rather than "I am here, in this
61
+ * state". Those two behave differently when connectivity goes stale: `busy`
62
+ * describes right now, so a closed laptop makes it meaningless and `offline` is
63
+ * the more honest answer. `out_of_office` is a statement about a period, and it
64
+ * is at its most useful precisely when the person is *not* reachable — so it
65
+ * outlives the connection instead of being overwritten by it.
66
+ */
67
+ export declare const PRESENCE_SURVIVES_OFFLINE: readonly PresenceStatus[];
68
+ /**
69
+ * The one place that turns "when was this user last seen" plus "what did they
70
+ * set" into an effective presence. Every read (the tenant list, your own row)
71
+ * and every broadcast goes through it, so the dot never depends on which route
72
+ * answered.
73
+ *
74
+ * `online` is connectivity and nothing else — call routing leans on it. The
75
+ * status layers on top: an expired one falls back, and a stale connection turns
76
+ * the rest into `offline` unless it survives (see
77
+ * {@link PRESENCE_SURVIVES_OFFLINE}). The message travels with the status it
78
+ * belongs to, so it disappears together with it.
79
+ */
80
+ export declare function derivePresence(lastSeenAt: number, stored: StoredPresenceStatus | undefined, now: number): {
81
+ online: boolean;
82
+ status: PresenceStatus;
83
+ message?: string;
84
+ };
85
+ /** The shape a client holds per user; the stored status is already folded in. */
86
+ export interface AgeablePresence {
87
+ lastSeenAt: number;
88
+ online: boolean;
89
+ status: PresenceStatus;
90
+ }
91
+ /**
92
+ * Age a client-held entry: peers who go silent expire without a round-trip.
93
+ *
94
+ * Clients only have the *effective* status, not the stored row, so this is the
95
+ * connectivity half of {@link derivePresence} — same rule about what survives.
96
+ * Returns the entry unchanged when nothing moved, so a re-render only happens
97
+ * on a real transition.
98
+ */
99
+ export declare function agePresenceEntry<T extends AgeablePresence>(entry: T, now: number): T;
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opencxh/domain",
3
- "version": "1.151.0",
3
+ "version": "1.153.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",