@athoscommerce/snap-store-mobx 1.5.0 → 1.5.1-beta.112
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/dist/cjs/Autocomplete/Stores/AutocompleteFacetStore.js +2 -1
- package/dist/cjs/Chat/ChatStore.d.ts +87 -0
- package/dist/cjs/Chat/ChatStore.d.ts.map +1 -0
- package/dist/cjs/Chat/ChatStore.js +545 -0
- package/dist/cjs/Chat/Stores/ChatAttachmentStore.d.ts +98 -0
- package/dist/cjs/Chat/Stores/ChatAttachmentStore.d.ts.map +1 -0
- package/dist/cjs/Chat/Stores/ChatAttachmentStore.js +314 -0
- package/dist/cjs/Chat/Stores/ChatCompareStore.d.ts +16 -0
- package/dist/cjs/Chat/Stores/ChatCompareStore.d.ts.map +1 -0
- package/dist/cjs/Chat/Stores/ChatCompareStore.js +65 -0
- package/dist/cjs/Chat/Stores/ChatSessionStore.d.ts +107 -0
- package/dist/cjs/Chat/Stores/ChatSessionStore.d.ts.map +1 -0
- package/dist/cjs/Chat/Stores/ChatSessionStore.js +635 -0
- package/dist/cjs/Search/Stores/SearchFacetStore.d.ts.map +1 -1
- package/dist/cjs/Search/Stores/SearchFacetStore.js +13 -10
- package/dist/cjs/Search/Stores/index.d.ts +1 -1
- package/dist/cjs/Search/Stores/index.d.ts.map +1 -1
- package/dist/cjs/Search/Stores/index.js +2 -1
- package/dist/cjs/index.d.ts +4 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +5 -1
- package/dist/cjs/types.d.ts +21 -2
- package/dist/cjs/types.d.ts.map +1 -1
- package/dist/esm/Autocomplete/Stores/AutocompleteFacetStore.js +1 -1
- package/dist/esm/Chat/ChatStore.d.ts +87 -0
- package/dist/esm/Chat/ChatStore.d.ts.map +1 -0
- package/dist/esm/Chat/ChatStore.js +484 -0
- package/dist/esm/Chat/Stores/ChatAttachmentStore.d.ts +98 -0
- package/dist/esm/Chat/Stores/ChatAttachmentStore.d.ts.map +1 -0
- package/dist/esm/Chat/Stores/ChatAttachmentStore.js +222 -0
- package/dist/esm/Chat/Stores/ChatCompareStore.d.ts +16 -0
- package/dist/esm/Chat/Stores/ChatCompareStore.d.ts.map +1 -0
- package/dist/esm/Chat/Stores/ChatCompareStore.js +51 -0
- package/dist/esm/Chat/Stores/ChatSessionStore.d.ts +107 -0
- package/dist/esm/Chat/Stores/ChatSessionStore.d.ts.map +1 -0
- package/dist/esm/Chat/Stores/ChatSessionStore.js +601 -0
- package/dist/esm/Search/Stores/SearchFacetStore.d.ts.map +1 -1
- package/dist/esm/Search/Stores/SearchFacetStore.js +13 -10
- package/dist/esm/Search/Stores/index.d.ts +1 -1
- package/dist/esm/Search/Stores/index.d.ts.map +1 -1
- package/dist/esm/Search/Stores/index.js +1 -1
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +2 -0
- package/dist/esm/types.d.ts +21 -2
- package/dist/esm/types.d.ts.map +1 -1
- package/package.json +5 -5
|
@@ -0,0 +1,601 @@
|
|
|
1
|
+
import { makeObservable, observable, computed } from 'mobx';
|
|
2
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
3
|
+
import { ChatAttachmentStore, } from '../Stores/ChatAttachmentStore';
|
|
4
|
+
import { ChatCompareStore } from './ChatCompareStore';
|
|
5
|
+
import { SearchResultStore, Product } from '../../Search/Stores/SearchResultStore';
|
|
6
|
+
function createChatResultStore(results, meta) {
|
|
7
|
+
return new SearchResultStore({
|
|
8
|
+
config: {},
|
|
9
|
+
state: { loaded: true },
|
|
10
|
+
data: {
|
|
11
|
+
search: { results },
|
|
12
|
+
meta,
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
function createChatProduct(result, meta) {
|
|
17
|
+
return new Product({
|
|
18
|
+
config: {},
|
|
19
|
+
data: { result, meta },
|
|
20
|
+
position: 0,
|
|
21
|
+
responseId: '',
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
/** Extract raw serializable data from a Product instance for storage. */
|
|
25
|
+
function serializeProduct(product) {
|
|
26
|
+
if (!(product instanceof Product))
|
|
27
|
+
return product;
|
|
28
|
+
const raw = {
|
|
29
|
+
id: product.id,
|
|
30
|
+
responseId: product.responseId,
|
|
31
|
+
mappings: product.mappings,
|
|
32
|
+
attributes: product.attributes,
|
|
33
|
+
badges: product.badges?.all?.map((b) => ({ tag: b.tag })) || [],
|
|
34
|
+
};
|
|
35
|
+
if (product.variants) {
|
|
36
|
+
raw.variants = {
|
|
37
|
+
data: product.variants.data.map((v) => ({
|
|
38
|
+
mappings: v.mappings,
|
|
39
|
+
attributes: v.attributes,
|
|
40
|
+
options: v.options,
|
|
41
|
+
badges: v.badges,
|
|
42
|
+
})),
|
|
43
|
+
optionConfig: product.variants.optionConfig,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
return raw;
|
|
47
|
+
}
|
|
48
|
+
/** Serialize attachments for localStorage. Strips base64 from images (kept only at runtime). */
|
|
49
|
+
function serializeAttachmentsForStorage(items) {
|
|
50
|
+
return items.map((item) => {
|
|
51
|
+
if (item.type === 'image') {
|
|
52
|
+
return {
|
|
53
|
+
type: 'image',
|
|
54
|
+
id: item.id,
|
|
55
|
+
fileName: item.fileName,
|
|
56
|
+
imageId: item.imageId,
|
|
57
|
+
imageUrl: item.imageUrl,
|
|
58
|
+
thumbnailUrl: item.thumbnailUrl,
|
|
59
|
+
state: item.state,
|
|
60
|
+
error: item.error,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
if (item.type === 'product') {
|
|
64
|
+
return {
|
|
65
|
+
type: 'product',
|
|
66
|
+
id: item.id,
|
|
67
|
+
productId: item.productId,
|
|
68
|
+
thumbnailUrl: item.thumbnailUrl,
|
|
69
|
+
name: item.name,
|
|
70
|
+
requestType: item.requestType,
|
|
71
|
+
state: item.state,
|
|
72
|
+
error: item.error,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
type: 'facet',
|
|
77
|
+
id: item.id,
|
|
78
|
+
key: item.key,
|
|
79
|
+
facetLabel: item.facetLabel,
|
|
80
|
+
value: item.value,
|
|
81
|
+
label: item.label,
|
|
82
|
+
count: item.count,
|
|
83
|
+
state: item.state,
|
|
84
|
+
error: item.error,
|
|
85
|
+
};
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
/** Convert a chat message array to a plain serializable form for localStorage. */
|
|
89
|
+
function serializeChatForStorage(chat) {
|
|
90
|
+
return chat.map((message) => {
|
|
91
|
+
switch (message.messageType) {
|
|
92
|
+
case 'productSearchResult': {
|
|
93
|
+
const msg = message;
|
|
94
|
+
return { ...msg, results: Array.from(msg.results || []).map(serializeProduct) };
|
|
95
|
+
}
|
|
96
|
+
case 'inspirationResult': {
|
|
97
|
+
const msg = message;
|
|
98
|
+
return {
|
|
99
|
+
...msg,
|
|
100
|
+
inspirationSections: msg.inspirationSections?.map((section) => ({
|
|
101
|
+
...section,
|
|
102
|
+
products: Array.from(section.products || []).map(serializeProduct),
|
|
103
|
+
})),
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
case 'productAnswer': {
|
|
107
|
+
const msg = message;
|
|
108
|
+
return { ...msg, sourceProduct: serializeProduct(msg.sourceProduct) };
|
|
109
|
+
}
|
|
110
|
+
case 'productComparison': {
|
|
111
|
+
const msg = message;
|
|
112
|
+
return { ...msg, searchResults: Array.from(msg.searchResults || []).map(serializeProduct) };
|
|
113
|
+
}
|
|
114
|
+
case 'productRecommendation': {
|
|
115
|
+
const msg = message;
|
|
116
|
+
return {
|
|
117
|
+
...msg,
|
|
118
|
+
recommendationResult: msg.recommendationResult?.map((rec) => ({
|
|
119
|
+
...rec,
|
|
120
|
+
results: Array.from(rec.results || []).map(serializeProduct),
|
|
121
|
+
})),
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
case 'productQuery': {
|
|
125
|
+
const msg = message;
|
|
126
|
+
return { ...msg, sourceProduct: serializeProduct(msg.sourceProduct) };
|
|
127
|
+
}
|
|
128
|
+
default:
|
|
129
|
+
return message;
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
export class ChatSessionStore {
|
|
134
|
+
constructor(params) {
|
|
135
|
+
this.chat = [];
|
|
136
|
+
this.actions = [];
|
|
137
|
+
this.attachments = new ChatAttachmentStore();
|
|
138
|
+
this.comparisons = new ChatCompareStore();
|
|
139
|
+
this.feedbacks = [];
|
|
140
|
+
this.sessionFeedback = null;
|
|
141
|
+
this.feedbackDismissed = false;
|
|
142
|
+
this.feedbackJustGiven = false;
|
|
143
|
+
this.createdAt = new Date();
|
|
144
|
+
this.requestType = '';
|
|
145
|
+
this.dismissedSideChatMessageId = null;
|
|
146
|
+
this.activeMessageId = null;
|
|
147
|
+
this.sessionLimitReached = false;
|
|
148
|
+
/** Whether raw stored results have been hydrated into Product/SearchResultStore instances. */
|
|
149
|
+
this.hydrated = true;
|
|
150
|
+
this.saveTimerId = null;
|
|
151
|
+
const { id, sessionId, chat, attachments, actions, feedbacks, sessionFeedback, feedbackDismissed, createdAt, sessionEndTime, committedComparisons, } = params.data || {};
|
|
152
|
+
const { stores } = params;
|
|
153
|
+
this.id = id || uuidv4();
|
|
154
|
+
this.sessionId = sessionId;
|
|
155
|
+
this.storage = stores.storage;
|
|
156
|
+
this.actions = actions || [];
|
|
157
|
+
this.createdAt = createdAt ? new Date(createdAt) : new Date();
|
|
158
|
+
this.sessionEndTime = sessionEndTime ? new Date(sessionEndTime) : undefined;
|
|
159
|
+
this.feedbacks = feedbacks || [];
|
|
160
|
+
this.sessionFeedback = sessionFeedback || null;
|
|
161
|
+
this.feedbackDismissed = feedbackDismissed || false;
|
|
162
|
+
// if chat and attachments are passed, load them
|
|
163
|
+
if (chat && chat.length > 0) {
|
|
164
|
+
// productQuery messages only exist to drive the side-chat panel for an
|
|
165
|
+
// in-flight productQuery click; they must not be rehydrated on reload
|
|
166
|
+
// or the side chat would re-open without the matching primary-chat state
|
|
167
|
+
this.chat = chat.filter((message) => message.messageType !== 'productQuery');
|
|
168
|
+
}
|
|
169
|
+
if (attachments && attachments.length > 0) {
|
|
170
|
+
this.attachments.hydrate(attachments);
|
|
171
|
+
// Any attachment already referenced by a sent user message is no longer
|
|
172
|
+
// pending — transition it from 'active' to 'saved' so it stops appearing
|
|
173
|
+
// in the attachment context bar while remaining available via get(id) for
|
|
174
|
+
// rendering inside historical user messages.
|
|
175
|
+
const usedAttachmentIds = new Set();
|
|
176
|
+
this.chat.forEach((msg) => {
|
|
177
|
+
if (msg.messageType === 'user' && msg.attachments) {
|
|
178
|
+
msg.attachments.forEach((id) => usedAttachmentIds.add(id));
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
this.attachments.items.forEach((item) => {
|
|
182
|
+
if ((item.state === 'active' || item.state === 'attached') && usedAttachmentIds.has(item.id)) {
|
|
183
|
+
item.save();
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
// restore committed comparisons only if the thread is still anchored
|
|
188
|
+
// to a product comparison — either the last response was a
|
|
189
|
+
// productComparison or the user sent a follow-up before a response
|
|
190
|
+
// arrived (pending state)
|
|
191
|
+
if (committedComparisons && committedComparisons.length > 0) {
|
|
192
|
+
const EXCLUDED_MESSAGE_TYPES = ['topicDrift'];
|
|
193
|
+
const visibleMessages = this.chat.filter((message) => !EXCLUDED_MESSAGE_TYPES.includes(message.messageType));
|
|
194
|
+
const lastMessage = visibleMessages[visibleMessages.length - 1];
|
|
195
|
+
if (lastMessage?.messageType === 'productComparison' || lastMessage?.messageType === 'user') {
|
|
196
|
+
this.comparisons.committedItems = committedComparisons;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
makeObservable(this, {
|
|
200
|
+
chat: observable,
|
|
201
|
+
requestType: observable,
|
|
202
|
+
actions: observable,
|
|
203
|
+
attachments: observable,
|
|
204
|
+
feedbacks: observable,
|
|
205
|
+
sessionFeedback: observable,
|
|
206
|
+
feedbackDismissed: observable,
|
|
207
|
+
feedbackJustGiven: observable,
|
|
208
|
+
dismissedSideChatMessageId: observable,
|
|
209
|
+
activeMessageId: observable,
|
|
210
|
+
sessionLimitReached: observable,
|
|
211
|
+
activeMessage: computed,
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
dismissSideChat() {
|
|
215
|
+
// clear the override first so the fallback (last eligible message) is what we
|
|
216
|
+
// dismiss — otherwise closing while viewing an older message would leave the
|
|
217
|
+
// last message undismissed and the side chat would auto-reopen on it
|
|
218
|
+
this.activeMessageId = null;
|
|
219
|
+
const fallback = this.activeMessage;
|
|
220
|
+
if (fallback) {
|
|
221
|
+
this.dismissedSideChatMessageId = fallback.id;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
setActiveMessage(id) {
|
|
225
|
+
this.activeMessageId = id;
|
|
226
|
+
this.dismissedSideChatMessageId = null;
|
|
227
|
+
}
|
|
228
|
+
pushProductQueryMessage(result) {
|
|
229
|
+
// capture the side-chat message that was active at click time so a back action
|
|
230
|
+
// can restore it even when it's not the last message in the chat
|
|
231
|
+
const sourceMessageId = this.activeMessage?.id;
|
|
232
|
+
// drop any trailing productQuery so a fresh productQuery click replaces
|
|
233
|
+
// the side-chat target rather than stacking up
|
|
234
|
+
while (this.chat.length > 0 && this.chat[this.chat.length - 1]?.messageType === 'productQuery') {
|
|
235
|
+
this.chat.pop();
|
|
236
|
+
}
|
|
237
|
+
this.chat.push({
|
|
238
|
+
id: uuidv4(),
|
|
239
|
+
messageType: 'productQuery',
|
|
240
|
+
sourceProduct: result,
|
|
241
|
+
sourceMessageId,
|
|
242
|
+
});
|
|
243
|
+
// re-show the side chat in case the user previously dismissed it
|
|
244
|
+
this.dismissedSideChatMessageId = null;
|
|
245
|
+
this.activeMessageId = null;
|
|
246
|
+
this.save();
|
|
247
|
+
}
|
|
248
|
+
popProductQueryMessage(restoreActiveMessageId) {
|
|
249
|
+
while (this.chat.length > 0 && this.chat[this.chat.length - 1]?.messageType === 'productQuery') {
|
|
250
|
+
this.chat.pop();
|
|
251
|
+
}
|
|
252
|
+
this.activeMessageId = restoreActiveMessageId || null;
|
|
253
|
+
this.save();
|
|
254
|
+
}
|
|
255
|
+
get isExpired() {
|
|
256
|
+
// Prefer the server-provided end time (returned by chatInit); fall back to a
|
|
257
|
+
// 24-hour window from createdAt for sessions persisted before that field existed.
|
|
258
|
+
if (this.sessionEndTime) {
|
|
259
|
+
return Date.now() > this.sessionEndTime.getTime();
|
|
260
|
+
}
|
|
261
|
+
const ONE_DAY = 24 * 60 * 60 * 1000;
|
|
262
|
+
return Date.now() - this.createdAt.getTime() > ONE_DAY;
|
|
263
|
+
}
|
|
264
|
+
get topicDrift() {
|
|
265
|
+
const lastMessage = this.chat[this.chat.length - 1];
|
|
266
|
+
return lastMessage?.messageType === 'topicDrift' ? lastMessage : null;
|
|
267
|
+
}
|
|
268
|
+
get activeMessage() {
|
|
269
|
+
const EXCLUDED_MESSAGE_TYPES = ['topicDrift', 'productAnswer'];
|
|
270
|
+
if (this.activeMessageId) {
|
|
271
|
+
// Walk backward — the override is usually near the end
|
|
272
|
+
for (let i = this.chat.length - 1; i >= 0; i--) {
|
|
273
|
+
const m = this.chat[i];
|
|
274
|
+
if (m.id === this.activeMessageId && !EXCLUDED_MESSAGE_TYPES.includes(m.messageType)) {
|
|
275
|
+
return m;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
// Find the last eligible message by iterating backwards
|
|
280
|
+
let lastMessage = null;
|
|
281
|
+
for (let i = this.chat.length - 1; i >= 0; i--) {
|
|
282
|
+
if (!EXCLUDED_MESSAGE_TYPES.includes(this.chat[i].messageType)) {
|
|
283
|
+
lastMessage = this.chat[i];
|
|
284
|
+
break;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
// When the user sends a follow-up while in a productQuery flow (e.g. "discuss product"),
|
|
288
|
+
// the last visible message becomes a 'user' message which would close the secondary panel.
|
|
289
|
+
// Instead, keep the productQuery message as the active side-chat target so the product
|
|
290
|
+
// information panel stays open during and after the request.
|
|
291
|
+
if (lastMessage?.messageType === 'user' && this.requestType === 'productQuery') {
|
|
292
|
+
for (let i = this.chat.length - 1; i >= 0; i--) {
|
|
293
|
+
const m = this.chat[i];
|
|
294
|
+
if (m.messageType === 'productQuery' && !EXCLUDED_MESSAGE_TYPES.includes(m.messageType)) {
|
|
295
|
+
return m;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
return lastMessage || null;
|
|
300
|
+
}
|
|
301
|
+
dismissTopicDrift() {
|
|
302
|
+
this.chat = this.chat.filter((m) => m.messageType !== 'topicDrift');
|
|
303
|
+
this.save();
|
|
304
|
+
}
|
|
305
|
+
handleTopicDrift() {
|
|
306
|
+
let lastUserMessage;
|
|
307
|
+
for (let i = this.chat.length - 1; i >= 0; i--) {
|
|
308
|
+
if (this.chat[i].messageType === 'user') {
|
|
309
|
+
lastUserMessage = this.chat[i];
|
|
310
|
+
break;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
const messageText = lastUserMessage?.text;
|
|
314
|
+
// remove all topicDrift messages and the last user message that triggered the drift
|
|
315
|
+
if (lastUserMessage) {
|
|
316
|
+
const lastUserIndex = this.chat.lastIndexOf(lastUserMessage);
|
|
317
|
+
this.chat = this.chat.slice(0, lastUserIndex);
|
|
318
|
+
}
|
|
319
|
+
else {
|
|
320
|
+
this.chat = this.chat.filter((m) => m.messageType !== 'topicDrift');
|
|
321
|
+
}
|
|
322
|
+
this.save();
|
|
323
|
+
return messageText;
|
|
324
|
+
}
|
|
325
|
+
reset() {
|
|
326
|
+
this.attachments.reset();
|
|
327
|
+
this.chat = [];
|
|
328
|
+
this.actions = [];
|
|
329
|
+
this.feedbacks = [];
|
|
330
|
+
this.sessionFeedback = null;
|
|
331
|
+
}
|
|
332
|
+
/** Persist the session to storage immediately (synchronous). */
|
|
333
|
+
saveImmediate() {
|
|
334
|
+
if (this.saveTimerId !== null) {
|
|
335
|
+
clearTimeout(this.saveTimerId);
|
|
336
|
+
this.saveTimerId = null;
|
|
337
|
+
}
|
|
338
|
+
this.storage.set(`chats.${this.id}`, {
|
|
339
|
+
sessionId: this.sessionId,
|
|
340
|
+
chat: serializeChatForStorage(this.chat),
|
|
341
|
+
attachments: serializeAttachmentsForStorage(this.attachments.items),
|
|
342
|
+
actions: this.actions,
|
|
343
|
+
feedbacks: this.feedbacks,
|
|
344
|
+
sessionFeedback: this.sessionFeedback,
|
|
345
|
+
feedbackDismissed: this.feedbackDismissed,
|
|
346
|
+
createdAt: this.createdAt,
|
|
347
|
+
sessionEndTime: this.sessionEndTime,
|
|
348
|
+
committedComparisons: this.comparisons.committedItems,
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Schedule a save — multiple calls within the debounce window are coalesced
|
|
353
|
+
* into a single localStorage write.
|
|
354
|
+
*/
|
|
355
|
+
save() {
|
|
356
|
+
if (this.saveTimerId !== null) {
|
|
357
|
+
clearTimeout(this.saveTimerId);
|
|
358
|
+
}
|
|
359
|
+
this.saveTimerId = setTimeout(() => {
|
|
360
|
+
this.saveTimerId = null;
|
|
361
|
+
this.saveImmediate();
|
|
362
|
+
}, 0);
|
|
363
|
+
}
|
|
364
|
+
/** Remove oldest stored sessions when exceeding the limit. */
|
|
365
|
+
static pruneStoredSessions(storage, maxSessions = 10) {
|
|
366
|
+
const storedChats = storage.get('chats');
|
|
367
|
+
if (storedChats) {
|
|
368
|
+
const chatIds = Object.keys(storedChats);
|
|
369
|
+
if (chatIds.length > maxSessions) {
|
|
370
|
+
chatIds
|
|
371
|
+
.sort((a, b) => {
|
|
372
|
+
const aTime = new Date(storedChats[a]?.createdAt || 0).getTime();
|
|
373
|
+
const bTime = new Date(storedChats[b]?.createdAt || 0).getTime();
|
|
374
|
+
return aTime - bTime;
|
|
375
|
+
})
|
|
376
|
+
.slice(0, chatIds.length - maxSessions)
|
|
377
|
+
.forEach((id) => {
|
|
378
|
+
storage.set(`chats.${id}`, null);
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
/** Re-wrap raw stored results as Product / SearchResultStore instances. */
|
|
384
|
+
hydrateResults(meta) {
|
|
385
|
+
this.chat.forEach((message) => {
|
|
386
|
+
if (message.messageType === 'productSearchResult') {
|
|
387
|
+
const msg = message;
|
|
388
|
+
if (msg.results?.length && !(msg.results[0] instanceof Product)) {
|
|
389
|
+
msg.results = createChatResultStore(msg.results, meta);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
else if (message.messageType === 'inspirationResult') {
|
|
393
|
+
const msg = message;
|
|
394
|
+
msg.inspirationSections?.forEach((section) => {
|
|
395
|
+
if (section.products?.length && !(section.products[0] instanceof Product)) {
|
|
396
|
+
section.products = createChatResultStore(section.products, meta);
|
|
397
|
+
}
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
else if (message.messageType === 'productAnswer') {
|
|
401
|
+
const msg = message;
|
|
402
|
+
if (msg.sourceProduct && !(msg.sourceProduct instanceof Product)) {
|
|
403
|
+
msg.sourceProduct = createChatProduct(msg.sourceProduct, meta);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
else if (message.messageType === 'productComparison') {
|
|
407
|
+
const msg = message;
|
|
408
|
+
if (msg.searchResults?.length && !(msg.searchResults[0] instanceof Product)) {
|
|
409
|
+
msg.searchResults = createChatResultStore(msg.searchResults, meta);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
else if (message.messageType === 'productRecommendation') {
|
|
413
|
+
const msg = message;
|
|
414
|
+
msg.recommendationResult?.forEach((rec) => {
|
|
415
|
+
if (rec.results?.length && !(rec.results[0] instanceof Product)) {
|
|
416
|
+
rec.results = createChatResultStore(rec.results, meta);
|
|
417
|
+
}
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
request(request, filterLabels) {
|
|
423
|
+
// clear the questions on new request
|
|
424
|
+
this.actions = [];
|
|
425
|
+
this.requestType = request.data.requestType;
|
|
426
|
+
this.activeMessageId = null;
|
|
427
|
+
// remove any attachments that failed to upload
|
|
428
|
+
const errorAttachments = this.attachments.items.filter((item) => item.state === 'error');
|
|
429
|
+
errorAttachments.forEach((item) => this.attachments.items.splice(this.attachments.items.indexOf(item), 1));
|
|
430
|
+
const attachments = [];
|
|
431
|
+
if (request.data.requestType === 'productSearch') {
|
|
432
|
+
const searchFilters = request.data.searchFilters;
|
|
433
|
+
if (searchFilters && searchFilters.length > 0) {
|
|
434
|
+
const filterTextArray = [];
|
|
435
|
+
searchFilters.forEach((filter) => {
|
|
436
|
+
const labelEntry = filterLabels?.[filter.key];
|
|
437
|
+
filter.options?.forEach((option) => {
|
|
438
|
+
const facetLabel = labelEntry?.facetLabel || filter.key;
|
|
439
|
+
if ('low' in option || 'high' in option) {
|
|
440
|
+
const low = option.low ?? '*';
|
|
441
|
+
const high = option.high ?? '*';
|
|
442
|
+
filterTextArray.push(`${facetLabel} ${low}-${high}`);
|
|
443
|
+
}
|
|
444
|
+
else {
|
|
445
|
+
const key = option.key;
|
|
446
|
+
const optionLabel = labelEntry?.values[key] || key;
|
|
447
|
+
filterTextArray.push(`${facetLabel} ${optionLabel}`);
|
|
448
|
+
}
|
|
449
|
+
});
|
|
450
|
+
});
|
|
451
|
+
this.chat.push({
|
|
452
|
+
id: uuidv4(),
|
|
453
|
+
messageType: 'user',
|
|
454
|
+
attachments: attachments.length > 0 ? attachments : undefined,
|
|
455
|
+
text: `Filter by ${filterTextArray.join(' and ')}`,
|
|
456
|
+
requestType: request.data.requestType,
|
|
457
|
+
request: request.data, // request is added here to conditionally display different text in MessageUser
|
|
458
|
+
});
|
|
459
|
+
}
|
|
460
|
+
else if (request.data.searchTerm) {
|
|
461
|
+
// for when a query is clicked from ChatInspirationResultMessage
|
|
462
|
+
this.chat.push({
|
|
463
|
+
id: uuidv4(),
|
|
464
|
+
messageType: 'user',
|
|
465
|
+
text: request.data.searchTerm,
|
|
466
|
+
requestType: request.data.requestType,
|
|
467
|
+
request: request.data, // request is added here to conditionally display different text in MessageUser
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
else if ('message' in request.data && request.data.message) {
|
|
472
|
+
if (request.data.requestType === 'imageSearch') {
|
|
473
|
+
const imageId = request.data.attachedImageId;
|
|
474
|
+
const attachedImage = this.attachments.attached.find((item) => item.type == 'image' && item.imageId == imageId);
|
|
475
|
+
if (attachedImage) {
|
|
476
|
+
attachments.push(attachedImage.id);
|
|
477
|
+
attachedImage.activate();
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
else if (request.data.requestType === 'productQuery') {
|
|
481
|
+
const productId = request.data.productId;
|
|
482
|
+
const attachedProduct = this.attachments.attached.find((item) => item.type == 'product' && item.productId == productId);
|
|
483
|
+
if (attachedProduct) {
|
|
484
|
+
attachments.push(attachedProduct.id);
|
|
485
|
+
attachedProduct.activate();
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
else if (request.data.requestType === 'productComparison') {
|
|
489
|
+
this.comparisons.compared.forEach((item) => {
|
|
490
|
+
const d = item.result?.display || item.result;
|
|
491
|
+
const attachment = this.attachments.add({
|
|
492
|
+
type: 'product',
|
|
493
|
+
requestType: 'productComparison',
|
|
494
|
+
productId: item.result.id,
|
|
495
|
+
name: d.mappings?.core?.name,
|
|
496
|
+
thumbnailUrl: d.mappings?.core?.thumbnailImageUrl || d.mappings?.core?.imageUrl || d.mappings?.core?.parentImageUrl,
|
|
497
|
+
});
|
|
498
|
+
if (attachment) {
|
|
499
|
+
attachments.push(attachment.id);
|
|
500
|
+
attachment.activate();
|
|
501
|
+
}
|
|
502
|
+
});
|
|
503
|
+
}
|
|
504
|
+
this.chat.push({
|
|
505
|
+
id: uuidv4(),
|
|
506
|
+
messageType: 'user',
|
|
507
|
+
attachments: attachments.length > 0 ? attachments : undefined,
|
|
508
|
+
text: request.data.message,
|
|
509
|
+
requestType: request.data.requestType,
|
|
510
|
+
});
|
|
511
|
+
}
|
|
512
|
+
else if (request.data?.requestType === 'productSimilar') {
|
|
513
|
+
const attachedSimilarProduct = this.attachments.attached.find((item) => item.type == 'product' && item.requestType == 'productSimilar');
|
|
514
|
+
if (attachedSimilarProduct) {
|
|
515
|
+
attachments.push(attachedSimilarProduct.id);
|
|
516
|
+
attachedSimilarProduct.activate();
|
|
517
|
+
this.chat.push({
|
|
518
|
+
id: uuidv4(),
|
|
519
|
+
messageType: 'user',
|
|
520
|
+
attachments: attachments.length > 0 ? attachments : undefined,
|
|
521
|
+
text: `Show similar products to "${attachedSimilarProduct.name || attachedSimilarProduct.productId}"`,
|
|
522
|
+
requestType: request.data.requestType,
|
|
523
|
+
});
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
else if (request.data?.requestType === 'productComparison') {
|
|
527
|
+
const productNames = [];
|
|
528
|
+
this.comparisons.compared.forEach((item) => {
|
|
529
|
+
const d = item.result?.display || item.result;
|
|
530
|
+
const attachment = this.attachments.add({
|
|
531
|
+
type: 'product',
|
|
532
|
+
requestType: 'productComparison',
|
|
533
|
+
productId: item.result.id,
|
|
534
|
+
name: d.mappings?.core?.name,
|
|
535
|
+
thumbnailUrl: d.mappings?.core?.thumbnailImageUrl || d.mappings?.core?.imageUrl || d.mappings?.core?.parentImageUrl,
|
|
536
|
+
});
|
|
537
|
+
if (attachment) {
|
|
538
|
+
attachments.push(attachment.id);
|
|
539
|
+
attachment.activate();
|
|
540
|
+
productNames.push(attachment.name || attachment.productId);
|
|
541
|
+
}
|
|
542
|
+
});
|
|
543
|
+
if (attachments.length > 0) {
|
|
544
|
+
this.chat.push({
|
|
545
|
+
id: uuidv4(),
|
|
546
|
+
messageType: 'user',
|
|
547
|
+
attachments: attachments,
|
|
548
|
+
text: `Compare ${productNames.map((name) => `"${name}"`).join(' and ')}`,
|
|
549
|
+
requestType: request.data.requestType,
|
|
550
|
+
});
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
// snapshot the comparison list into the committed list so the
|
|
554
|
+
// header section can clear and the footer can display them
|
|
555
|
+
if (request.data.requestType === 'productComparison') {
|
|
556
|
+
this.comparisons.commit();
|
|
557
|
+
}
|
|
558
|
+
this.save();
|
|
559
|
+
}
|
|
560
|
+
update(data) {
|
|
561
|
+
this.sessionId = data.chat.context.sessionId;
|
|
562
|
+
const meta = data.meta;
|
|
563
|
+
data.chat.data.forEach((messageData) => {
|
|
564
|
+
// check if the data has questions?
|
|
565
|
+
if (messageData.messageType === 'actions') {
|
|
566
|
+
this.actions.push({
|
|
567
|
+
type: 'actions',
|
|
568
|
+
data: messageData.actions,
|
|
569
|
+
});
|
|
570
|
+
return;
|
|
571
|
+
}
|
|
572
|
+
// convert raw results to Product instances (via SearchResultStore) so
|
|
573
|
+
// display components can use result.display for mask-aware rendering
|
|
574
|
+
if (messageData.messageType === 'productSearchResult' && messageData.results?.length) {
|
|
575
|
+
messageData.results = createChatResultStore(messageData.results, meta);
|
|
576
|
+
}
|
|
577
|
+
else if (messageData.messageType === 'inspirationResult' && messageData.inspirationSections?.length) {
|
|
578
|
+
messageData.inspirationSections = messageData.inspirationSections.map((section) => ({
|
|
579
|
+
...section,
|
|
580
|
+
products: section.products?.length
|
|
581
|
+
? createChatResultStore(section.products, meta)
|
|
582
|
+
: section.products,
|
|
583
|
+
}));
|
|
584
|
+
}
|
|
585
|
+
else if (messageData.messageType === 'productAnswer' && messageData.sourceProduct) {
|
|
586
|
+
messageData.sourceProduct = createChatProduct(messageData.sourceProduct, meta);
|
|
587
|
+
}
|
|
588
|
+
else if (messageData.messageType === 'productComparison' && messageData.searchResults?.length) {
|
|
589
|
+
messageData.searchResults = createChatResultStore(messageData.searchResults, meta);
|
|
590
|
+
}
|
|
591
|
+
else if (messageData.messageType === 'productRecommendation' && messageData.recommendationResult?.length) {
|
|
592
|
+
messageData.recommendationResult = messageData.recommendationResult.map((rec) => ({
|
|
593
|
+
...rec,
|
|
594
|
+
results: rec.results?.length ? createChatResultStore(rec.results, meta) : rec.results,
|
|
595
|
+
}));
|
|
596
|
+
}
|
|
597
|
+
this.chat.push(messageData);
|
|
598
|
+
});
|
|
599
|
+
this.save();
|
|
600
|
+
}
|
|
601
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SearchFacetStore.d.ts","sourceRoot":"","sources":["../../../../src/Search/Stores/SearchFacetStore.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"SearchFacetStore.d.ts","sourceRoot":"","sources":["../../../../src/Search/Stores/SearchFacetStore.ts"],"names":[],"mappings":"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"}
|
|
@@ -238,15 +238,16 @@ export class ValueFacet extends Facet {
|
|
|
238
238
|
export class FacetValue {
|
|
239
239
|
constructor(services, facet, value) {
|
|
240
240
|
Object.assign(this, value);
|
|
241
|
+
const urlManager = services.urlManager;
|
|
241
242
|
if (this.filtered) {
|
|
242
|
-
this.url =
|
|
243
|
+
this.url = urlManager.remove('page').remove(`filter.${facet.field}`, value.value);
|
|
243
244
|
}
|
|
244
245
|
else {
|
|
245
|
-
let valueUrl =
|
|
246
|
+
let valueUrl = urlManager.remove('page');
|
|
246
247
|
if (facet.multiple == 'single') {
|
|
247
|
-
valueUrl = valueUrl
|
|
248
|
+
valueUrl = valueUrl.remove(`filter.${facet.field}`);
|
|
248
249
|
}
|
|
249
|
-
this.url = valueUrl
|
|
250
|
+
this.url = valueUrl.merge(`filter.${facet.field}`, value.value);
|
|
250
251
|
}
|
|
251
252
|
}
|
|
252
253
|
}
|
|
@@ -264,26 +265,28 @@ export class FacetHierarchyValue extends FacetValue {
|
|
|
264
265
|
this.history = true;
|
|
265
266
|
}
|
|
266
267
|
}
|
|
268
|
+
const urlManager = services.urlManager;
|
|
267
269
|
if (value.value) {
|
|
268
|
-
this.url =
|
|
270
|
+
this.url = urlManager.remove('page').set(`filter.${facet.field}`, value.value);
|
|
269
271
|
}
|
|
270
272
|
else {
|
|
271
|
-
this.url =
|
|
273
|
+
this.url = urlManager.remove('page').remove(`filter.${facet.field}`);
|
|
272
274
|
}
|
|
273
275
|
}
|
|
274
276
|
}
|
|
275
277
|
export class FacetRangeValue {
|
|
276
278
|
constructor(services, facet, value) {
|
|
277
279
|
Object.assign(this, value);
|
|
280
|
+
const urlManager = services.urlManager;
|
|
278
281
|
if (this.filtered) {
|
|
279
|
-
this.url =
|
|
282
|
+
this.url = urlManager.remove('page').remove(`filter.${facet.field}`, [{ low: this.low, high: this.high }]);
|
|
280
283
|
}
|
|
281
284
|
else {
|
|
282
|
-
let valueUrl =
|
|
285
|
+
let valueUrl = urlManager.remove('page');
|
|
283
286
|
if (facet.multiple == 'single') {
|
|
284
|
-
valueUrl = valueUrl
|
|
287
|
+
valueUrl = valueUrl.remove(`filter.${facet.field}`);
|
|
285
288
|
}
|
|
286
|
-
this.url = valueUrl
|
|
289
|
+
this.url = valueUrl.merge(`filter.${facet.field}`, [{ low: this.low, high: this.high }]);
|
|
287
290
|
}
|
|
288
291
|
}
|
|
289
292
|
}
|
|
@@ -2,7 +2,7 @@ export { SearchMerchandisingStore, BannerContent, ContentType, MerchandisingCont
|
|
|
2
2
|
export { SearchFacetStore, ValueFacet, RangeFacet, FacetValue, FacetHierarchyValue, FacetRangeValue } from './SearchFacetStore';
|
|
3
3
|
export { SearchFilterStore, Filter } from './SearchFilterStore';
|
|
4
4
|
export { SearchPaginationStore, Page } from './SearchPaginationStore';
|
|
5
|
-
export { SearchResultStore, Product, Banner, VariantSelection, VariantSelectionValue } from './SearchResultStore';
|
|
5
|
+
export { SearchResultStore, Product, Banner, Variants, VariantSelection, VariantSelectionValue } from './SearchResultStore';
|
|
6
6
|
export { SearchSortingStore } from './SearchSortingStore';
|
|
7
7
|
export { SearchQueryStore } from './SearchQueryStore';
|
|
8
8
|
export { SearchHistoryStore } from './SearchHistoryStore';
|