@spscommerce/max 0.4.0 → 0.6.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/lib/MaxPanel.d.ts +2 -1
- package/lib/api-service.d.ts +2 -1
- package/lib/components/ChatLoadingStatus.d.ts +7 -0
- package/lib/components/MaxPanelHeaderActions.d.ts +14 -0
- package/lib/components/index.d.ts +2 -0
- package/lib/hooks/scrollStateMachine.d.ts +128 -0
- package/lib/hooks/useMaxChat.d.ts +2 -2
- package/lib/hooks/useMaxPanelScrollController.d.ts +30 -0
- package/lib/index.d.ts +3 -0
- package/lib/index.js +14408 -13929
- package/lib/index.umd.cjs +166 -166
- package/lib/logger.d.ts +6 -0
- package/lib/models/AdditionalContext.d.ts +2 -0
- package/lib/style.css +1 -1
- package/package.json +3 -1
- package/vitest.config.ts +20 -0
package/lib/MaxPanel.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import * as React from "react";
|
|
|
2
2
|
import { FeatureFlagsTitles } from "./models/FeatureFlagsTitles";
|
|
3
3
|
import { CurrentApp } from "./models/CurrentApp";
|
|
4
4
|
import { CurrentUser } from "./models/CurrentUser";
|
|
5
|
+
import type { AdditionalContextProvider } from "./models/AdditionalContext";
|
|
5
6
|
export declare function MaxPanel({ token, currentUser, hideAgentPanel, isAgentPanelOpen, isInCustomerView, flags, env, currentApp, context, currentConversationId, locale, }: {
|
|
6
7
|
token: string | null;
|
|
7
8
|
currentUser: CurrentUser | undefined;
|
|
@@ -11,7 +12,7 @@ export declare function MaxPanel({ token, currentUser, hideAgentPanel, isAgentPa
|
|
|
11
12
|
flags: FeatureFlagsTitles;
|
|
12
13
|
env: string;
|
|
13
14
|
currentApp: CurrentApp;
|
|
14
|
-
context:
|
|
15
|
+
context: AdditionalContextProvider;
|
|
15
16
|
currentConversationId?: string | null;
|
|
16
17
|
locale?: string;
|
|
17
18
|
}): React.ReactNode;
|
package/lib/api-service.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ConversationList, ConversationMessages } from "./models/Conversation";
|
|
2
|
+
import type { AdditionalContext } from "./models/AdditionalContext";
|
|
2
3
|
import type { UsageStatus } from "./models/UsageStatus";
|
|
3
4
|
export declare class AgentApiService {
|
|
4
5
|
private readonly url;
|
|
@@ -19,5 +20,5 @@ export declare class AgentApiService {
|
|
|
19
20
|
deleteConversation: (conversationId: string) => Promise<void>;
|
|
20
21
|
postFeedback: (messageId: string, score: string, comment: string) => Promise<void>;
|
|
21
22
|
fetchUsageStatus: (userId: string) => Promise<UsageStatus>;
|
|
22
|
-
postChat(message: string, currentAppName: string, currentConversationId: string | null, agentContext:
|
|
23
|
+
postChat(message: string, currentAppName: string, currentConversationId: string | null, agentContext: AdditionalContext, currentUrl: string, appInitiated: boolean, userTimezone: string | null): Promise<unknown>;
|
|
23
24
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
type LoadingStatusProps = {
|
|
3
|
+
label: string;
|
|
4
|
+
};
|
|
5
|
+
export declare function OlderMessagesLoadingStatus({ label }: LoadingStatusProps): React.ReactNode;
|
|
6
|
+
export declare function ConversationSwitchLoadingStatus({ label }: LoadingStatusProps): React.ReactNode;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
type MaxPanelHeaderActionsProps = {
|
|
3
|
+
isCompact: boolean;
|
|
4
|
+
showConversationList: boolean;
|
|
5
|
+
conversationToggleLabel: string;
|
|
6
|
+
newConversationLabel: string;
|
|
7
|
+
newConversationCompactTitle: string;
|
|
8
|
+
closePanelLabel: string;
|
|
9
|
+
onToggleConversationList: () => void;
|
|
10
|
+
onStartNewConversation: () => void;
|
|
11
|
+
onClosePanel: () => void;
|
|
12
|
+
};
|
|
13
|
+
export declare function MaxPanelHeaderActions({ isCompact, showConversationList, conversationToggleLabel, newConversationLabel, newConversationCompactTitle, closePanelLabel, onToggleConversationList, onStartNewConversation, onClosePanel, }: MaxPanelHeaderActionsProps): React.ReactNode;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Primary phase. Mutually exclusive — exactly one is active at any time.
|
|
3
|
+
*
|
|
4
|
+
* - `idle` — No active conversation; landing surface.
|
|
5
|
+
* - `switch-pending` — A conversation switch (or initial load with an
|
|
6
|
+
* existing conversation id) was requested. Waiting
|
|
7
|
+
* for the messages fetch to resolve.
|
|
8
|
+
* - `switch-settling` — Fetch resolved. Layout is settling; the controller
|
|
9
|
+
* is actively snapping the viewport to the bottom and
|
|
10
|
+
* waiting for late-arriving content (images, async
|
|
11
|
+
* markdown rendering, feedback widgets) to commit.
|
|
12
|
+
* - `ready` — Steady state: pin, streaming follow, scroll-to-
|
|
13
|
+
* bottom button, and pagination all behave per their
|
|
14
|
+
* own side-channel state.
|
|
15
|
+
*/
|
|
16
|
+
export type ScrollPhase = "idle" | "switch-pending" | "switch-settling" | "ready";
|
|
17
|
+
/**
|
|
18
|
+
* Active user-message anchor. Set when the user sends a message, cleared
|
|
19
|
+
* when a conversation switch begins or the message is replaced. The
|
|
20
|
+
* controller pins the referenced message near the top of the viewport.
|
|
21
|
+
*
|
|
22
|
+
* `expansionTargetTop` is the synthetic min-height target applied to
|
|
23
|
+
* `.conversation-section` when natural content does not provide enough
|
|
24
|
+
* scroll room to honor the pin. `null` means no expansion is active.
|
|
25
|
+
*/
|
|
26
|
+
export type UserPinAnchor = {
|
|
27
|
+
messageId: string;
|
|
28
|
+
expansionTargetTop: number | null;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Scroll position captured at the start of an older-messages load. Used
|
|
32
|
+
* after the prepend lands to restore the user's viewport so the visible
|
|
33
|
+
* messages do not appear to jump.
|
|
34
|
+
*/
|
|
35
|
+
export type OlderLoadCapture = {
|
|
36
|
+
savedScrollTop: number;
|
|
37
|
+
savedScrollHeight: number;
|
|
38
|
+
};
|
|
39
|
+
export type ScrollState = {
|
|
40
|
+
readonly phase: ScrollPhase;
|
|
41
|
+
readonly streamingFollowEngaged: boolean;
|
|
42
|
+
readonly userPin: UserPinAnchor | null;
|
|
43
|
+
readonly userPinApplied: boolean;
|
|
44
|
+
readonly olderLoad: OlderLoadCapture | null;
|
|
45
|
+
readonly programmaticLockActive: boolean;
|
|
46
|
+
};
|
|
47
|
+
export declare const initialScrollState: ScrollState;
|
|
48
|
+
export type ScrollAction = {
|
|
49
|
+
type: "CONVERSATION_SWITCH_REQUESTED";
|
|
50
|
+
} | {
|
|
51
|
+
type: "CONVERSATION_LOAD_RESOLVED";
|
|
52
|
+
} | {
|
|
53
|
+
type: "SWITCH_SETTLE_COMPLETE";
|
|
54
|
+
} | {
|
|
55
|
+
type: "USER_MESSAGE_ANCHORED";
|
|
56
|
+
messageId: string;
|
|
57
|
+
} | {
|
|
58
|
+
type: "USER_PIN_APPLIED";
|
|
59
|
+
expansionTargetTop: number | null;
|
|
60
|
+
} | {
|
|
61
|
+
type: "USER_PIN_EXPANSION_CLEARED";
|
|
62
|
+
} | {
|
|
63
|
+
type: "USER_PIN_CLEARED";
|
|
64
|
+
} | {
|
|
65
|
+
type: "STREAMING_FOLLOW_ENGAGED";
|
|
66
|
+
} | {
|
|
67
|
+
type: "STREAMING_FOLLOW_DISENGAGED";
|
|
68
|
+
} | {
|
|
69
|
+
type: "STREAMING_ENDED";
|
|
70
|
+
} | {
|
|
71
|
+
type: "PROGRAMMATIC_LOCK_ENGAGED";
|
|
72
|
+
} | {
|
|
73
|
+
type: "PROGRAMMATIC_LOCK_RELEASED";
|
|
74
|
+
} | {
|
|
75
|
+
type: "OLDER_LOAD_STARTED";
|
|
76
|
+
savedScrollTop: number;
|
|
77
|
+
savedScrollHeight: number;
|
|
78
|
+
} | {
|
|
79
|
+
type: "OLDER_LOAD_RESOLVED";
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* Apply an action to the state. Pure function — no I/O. Every transition is
|
|
83
|
+
* named; unreachable transitions return state unchanged.
|
|
84
|
+
*
|
|
85
|
+
* INVARIANT: `userPinApplied` only becomes true via `USER_PIN_APPLIED`, and
|
|
86
|
+
* is reset to false on every `USER_MESSAGE_ANCHORED` and switch lifecycle
|
|
87
|
+
* action. The controller relies on this for the "pin only once per
|
|
88
|
+
* message" guarantee.
|
|
89
|
+
*/
|
|
90
|
+
export declare function scrollReducer(state: ScrollState, action: ScrollAction): ScrollState;
|
|
91
|
+
export type ChatSurfaceState = "initial-loading" | "switch-loading" | "ready";
|
|
92
|
+
/**
|
|
93
|
+
* Externally observable scroll state value, emitted as `data-scroll-state`
|
|
94
|
+
* on the scroll wrapper. Order of precedence: switch lifecycle > interaction
|
|
95
|
+
* mode > steady. Stable string set documented for downstream consumers
|
|
96
|
+
* (tests, Playwright selectors, Clarity recordings).
|
|
97
|
+
*/
|
|
98
|
+
export type ScrollStateAttribute = "idle" | "switch-pending" | "switch-settling" | "streaming-follow" | "user-pin-active" | "ready";
|
|
99
|
+
export declare function selectScrollStateAttribute(state: ScrollState): ScrollStateAttribute;
|
|
100
|
+
export declare function selectChatSurfaceState(args: {
|
|
101
|
+
state: ScrollState;
|
|
102
|
+
loading: boolean;
|
|
103
|
+
isActiveChat: boolean;
|
|
104
|
+
showConversationList: boolean;
|
|
105
|
+
}): ChatSurfaceState;
|
|
106
|
+
/**
|
|
107
|
+
* Whether the scroll-to-bottom button should be visible. Pure: caller
|
|
108
|
+
* measures the DOM and passes the values in.
|
|
109
|
+
*
|
|
110
|
+
* Hidden during switch lifecycle (the user is transitioning conversations,
|
|
111
|
+
* showing the button would flash). Hidden while the only "distance to
|
|
112
|
+
* bottom" comes from synthetic pin expansion (not real new content).
|
|
113
|
+
* Otherwise visible iff `distanceToBottom > threshold`.
|
|
114
|
+
*/
|
|
115
|
+
export declare function selectShowScrollToBottom(args: {
|
|
116
|
+
state: ScrollState;
|
|
117
|
+
scrollHeight: number;
|
|
118
|
+
clientHeight: number;
|
|
119
|
+
scrollTop: number;
|
|
120
|
+
isStreaming: boolean;
|
|
121
|
+
threshold: number;
|
|
122
|
+
}): boolean;
|
|
123
|
+
/**
|
|
124
|
+
* Whether the controller is in the user-visible "transitioning" window
|
|
125
|
+
* (switch-pending or switch-settling). Used by the loading UI and to
|
|
126
|
+
* gate IntersectionObserver pagination triggers.
|
|
127
|
+
*/
|
|
128
|
+
export declare function selectIsTransitioning(state: ScrollState): boolean;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { Chat } from "../models/Chat";
|
|
2
2
|
import { Conversation, Message } from "../models/Conversation";
|
|
3
3
|
import { AgentApiService } from "../api-service";
|
|
4
|
-
|
|
4
|
+
import type { AdditionalContextProvider } from "../models/AdditionalContext";
|
|
5
|
+
export declare function useMaxChat(agentApi: AgentApiService, context: AdditionalContextProvider): {
|
|
5
6
|
error: boolean;
|
|
6
7
|
loading: boolean;
|
|
7
8
|
isAgentThinking: boolean;
|
|
8
9
|
messages: Chat[];
|
|
9
|
-
displayedMessages: Chat[];
|
|
10
10
|
hasMoreMessages: boolean;
|
|
11
11
|
loadOlderMessages: () => Promise<void>;
|
|
12
12
|
isLoadingOlderMessages: boolean;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { Chat } from "../models/Chat";
|
|
3
|
+
import { ChatSurfaceState, ScrollAction, ScrollStateAttribute } from "./scrollStateMachine";
|
|
4
|
+
type UseMaxPanelScrollControllerArgs = {
|
|
5
|
+
isAgentPanelOpen?: boolean;
|
|
6
|
+
currentConversationId: string | null | undefined;
|
|
7
|
+
showConversationList: boolean;
|
|
8
|
+
loading: boolean;
|
|
9
|
+
messages: Chat[];
|
|
10
|
+
messageHasBeenSent: boolean;
|
|
11
|
+
isAgentThinking: boolean;
|
|
12
|
+
streamingResponse?: string;
|
|
13
|
+
hasMoreMessages: boolean;
|
|
14
|
+
isLoadingOlderMessages: boolean;
|
|
15
|
+
loadOlderMessages: () => Promise<void>;
|
|
16
|
+
};
|
|
17
|
+
type UseMaxPanelScrollControllerResult = {
|
|
18
|
+
scrollWrapperRef: React.MutableRefObject<HTMLDivElement | null>;
|
|
19
|
+
sentinelRef: React.MutableRefObject<HTMLDivElement | null>;
|
|
20
|
+
showScrollToBottom: boolean;
|
|
21
|
+
isConversationTransitioning: boolean;
|
|
22
|
+
isStreaming: boolean;
|
|
23
|
+
isActiveChat: boolean;
|
|
24
|
+
chatSurfaceState: ChatSurfaceState;
|
|
25
|
+
scrollStateAttribute: ScrollStateAttribute;
|
|
26
|
+
prepareConversationSwitchSnap: () => void;
|
|
27
|
+
scrollToLatest: () => void;
|
|
28
|
+
};
|
|
29
|
+
export declare function useMaxPanelScrollController(args: UseMaxPanelScrollControllerArgs): UseMaxPanelScrollControllerResult;
|
|
30
|
+
export type { ScrollAction };
|
package/lib/index.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
import "./max.scss";
|
|
2
2
|
export * from "./icons";
|
|
3
3
|
export * from "./MaxPanel";
|
|
4
|
+
export type { AdditionalContext, AdditionalContextProvider } from "./models/AdditionalContext";
|
|
5
|
+
export type { CurrentApp } from "./models/CurrentApp";
|
|
6
|
+
export type { FeatureFlagsTitles } from "./models/FeatureFlagsTitles";
|