@athoscommerce/snap-store-mobx 1.2.3-beta.1 → 1.3.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/dist/cjs/Autocomplete/AutocompleteStore.js +2 -2
- 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 +1 -2
- package/dist/cjs/index.d.ts +0 -4
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +1 -5
- package/dist/cjs/types.d.ts +2 -13
- package/dist/cjs/types.d.ts.map +1 -1
- package/dist/esm/Autocomplete/AutocompleteStore.js +1 -1
- 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 +0 -4
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +0 -2
- package/dist/esm/types.d.ts +2 -13
- package/dist/esm/types.d.ts.map +1 -1
- package/package.json +5 -5
- package/dist/cjs/Chat/ChatStore.d.ts +0 -55
- package/dist/cjs/Chat/ChatStore.d.ts.map +0 -1
- package/dist/cjs/Chat/ChatStore.js +0 -368
- package/dist/cjs/Chat/Stores/ChatAttachmentStore.d.ts +0 -98
- package/dist/cjs/Chat/Stores/ChatAttachmentStore.d.ts.map +0 -1
- package/dist/cjs/Chat/Stores/ChatAttachmentStore.js +0 -312
- package/dist/cjs/Chat/Stores/ChatCompareStore.d.ts +0 -14
- package/dist/cjs/Chat/Stores/ChatCompareStore.d.ts.map +0 -1
- package/dist/cjs/Chat/Stores/ChatCompareStore.js +0 -63
- package/dist/cjs/Chat/Stores/ChatSessionStore.d.ts +0 -103
- package/dist/cjs/Chat/Stores/ChatSessionStore.d.ts.map +0 -1
- package/dist/cjs/Chat/Stores/ChatSessionStore.js +0 -612
- package/dist/esm/Chat/ChatStore.d.ts +0 -55
- package/dist/esm/Chat/ChatStore.d.ts.map +0 -1
- package/dist/esm/Chat/ChatStore.js +0 -309
- package/dist/esm/Chat/Stores/ChatAttachmentStore.d.ts +0 -98
- package/dist/esm/Chat/Stores/ChatAttachmentStore.d.ts.map +0 -1
- package/dist/esm/Chat/Stores/ChatAttachmentStore.js +0 -220
- package/dist/esm/Chat/Stores/ChatCompareStore.d.ts +0 -14
- package/dist/esm/Chat/Stores/ChatCompareStore.d.ts.map +0 -1
- package/dist/esm/Chat/Stores/ChatCompareStore.js +0 -49
- package/dist/esm/Chat/Stores/ChatSessionStore.d.ts +0 -103
- package/dist/esm/Chat/Stores/ChatSessionStore.d.ts.map +0 -1
- package/dist/esm/Chat/Stores/ChatSessionStore.js +0 -581
|
@@ -1,309 +0,0 @@
|
|
|
1
|
-
import { makeObservable, observable, computed } from 'mobx';
|
|
2
|
-
import { MetaStore } from '../Meta/MetaStore';
|
|
3
|
-
import { AbstractStore } from '../Abstract/AbstractStore';
|
|
4
|
-
import { StorageStore } from '../Storage/StorageStore';
|
|
5
|
-
import { ChatSessionStore } from './Stores/ChatSessionStore';
|
|
6
|
-
import { Variants } from '../Search/Stores/SearchResultStore';
|
|
7
|
-
const CHAT_STATUS_EXPIRATION_TIME = 1000 * 60 * 60 * 12; // 12 hours
|
|
8
|
-
export class ChatStore extends AbstractStore {
|
|
9
|
-
constructor(config) {
|
|
10
|
-
super(config);
|
|
11
|
-
this.meta = undefined;
|
|
12
|
-
this.inputValue = '';
|
|
13
|
-
this.open = false;
|
|
14
|
-
this.chats = [];
|
|
15
|
-
this.chatEnabled = null;
|
|
16
|
-
this.initChatLoading = false;
|
|
17
|
-
this.suggestedQuestions = [];
|
|
18
|
-
this.welcomeMessage = '';
|
|
19
|
-
this.features = { imageSearch: { enabled: false }, similarProducts: { enabled: false } };
|
|
20
|
-
this.productQuickview = null;
|
|
21
|
-
this.productQuickviewError = null;
|
|
22
|
-
/** Raw meta kept for lazy hydration of inactive chat sessions. */
|
|
23
|
-
this.storedMetaData = null;
|
|
24
|
-
const legacyKey = `ss-${this.config.id}`;
|
|
25
|
-
const storageKey = this.config.siteId ? `ss-${this.config.siteId}-${this.config.id}` : legacyKey;
|
|
26
|
-
this.storage = new StorageStore({
|
|
27
|
-
type: 'local',
|
|
28
|
-
key: storageKey,
|
|
29
|
-
});
|
|
30
|
-
const storedChatStatusResponse = this.storage.get('chatStatusResponse');
|
|
31
|
-
if (storedChatStatusResponse) {
|
|
32
|
-
try {
|
|
33
|
-
const storedChatStatus = JSON.parse(storedChatStatusResponse);
|
|
34
|
-
if (storedChatStatus.checkTime && Date.now() - storedChatStatus.checkTime > CHAT_STATUS_EXPIRATION_TIME) {
|
|
35
|
-
// chat status is expired, remove from storage to trigger a new check
|
|
36
|
-
this.storage.set('chatStatusResponse', null);
|
|
37
|
-
}
|
|
38
|
-
else {
|
|
39
|
-
this.handleChatStatusResponse(storedChatStatus.response);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
catch {
|
|
43
|
-
this.storage.set('chatStatusResponse', null);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
// check for entries in storage
|
|
47
|
-
let latestChatId = '';
|
|
48
|
-
const storedChats = this.storage.get('chats');
|
|
49
|
-
storedChats &&
|
|
50
|
-
Object.keys(storedChats || {}).forEach((chatId) => {
|
|
51
|
-
const chatData = storedChats[chatId];
|
|
52
|
-
if (chatData) {
|
|
53
|
-
const restoredChat = new ChatSessionStore({
|
|
54
|
-
data: {
|
|
55
|
-
...chatData,
|
|
56
|
-
id: chatId,
|
|
57
|
-
},
|
|
58
|
-
stores: {
|
|
59
|
-
storage: this.storage,
|
|
60
|
-
},
|
|
61
|
-
});
|
|
62
|
-
// Mark as unhydrated — results are still raw JSON from storage.
|
|
63
|
-
// Only the active session will be hydrated below.
|
|
64
|
-
restoredChat.hydrated = false;
|
|
65
|
-
this.chats.push(restoredChat);
|
|
66
|
-
latestChatId = chatId;
|
|
67
|
-
}
|
|
68
|
-
});
|
|
69
|
-
const storedMeta = this.storage.get('meta');
|
|
70
|
-
if (storedMeta) {
|
|
71
|
-
try {
|
|
72
|
-
const metaData = JSON.parse(storedMeta);
|
|
73
|
-
this.meta = new MetaStore({
|
|
74
|
-
data: {
|
|
75
|
-
meta: metaData,
|
|
76
|
-
},
|
|
77
|
-
});
|
|
78
|
-
// Keep raw meta for lazy hydration of inactive sessions
|
|
79
|
-
this.storedMetaData = metaData;
|
|
80
|
-
// Only hydrate the active chat session — inactive sessions will be
|
|
81
|
-
// hydrated lazily when switched to via switchChat()
|
|
82
|
-
const activeChat = this.chats.find((chat) => chat.id === latestChatId);
|
|
83
|
-
if (activeChat) {
|
|
84
|
-
activeChat.hydrateResults(metaData);
|
|
85
|
-
activeChat.hydrated = true;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
catch {
|
|
89
|
-
this.storage.set('meta', null);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
this.currentChatId = latestChatId;
|
|
93
|
-
makeObservable(this, {
|
|
94
|
-
meta: observable,
|
|
95
|
-
inputValue: observable,
|
|
96
|
-
open: observable,
|
|
97
|
-
chats: observable,
|
|
98
|
-
currentChatId: observable,
|
|
99
|
-
chatEnabled: observable,
|
|
100
|
-
initChatLoading: observable,
|
|
101
|
-
blocked: computed,
|
|
102
|
-
currentChat: computed,
|
|
103
|
-
chatsIds: computed,
|
|
104
|
-
features: observable,
|
|
105
|
-
suggestedQuestions: observable,
|
|
106
|
-
welcomeMessage: observable,
|
|
107
|
-
productQuickview: observable,
|
|
108
|
-
productQuickviewError: observable,
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
get currentChat() {
|
|
112
|
-
return this.chats.find((chat) => chat.id === this.currentChatId);
|
|
113
|
-
}
|
|
114
|
-
get chatsIds() {
|
|
115
|
-
return this.chats.map((chat) => chat.id);
|
|
116
|
-
}
|
|
117
|
-
get blocked() {
|
|
118
|
-
let isBlocked = false;
|
|
119
|
-
const blockedAttachments = this.currentChat?.attachments.items.some((item) => item.type === 'image' && item.state === 'loading');
|
|
120
|
-
if (this.loading || blockedAttachments) {
|
|
121
|
-
isBlocked = true;
|
|
122
|
-
}
|
|
123
|
-
return isBlocked;
|
|
124
|
-
}
|
|
125
|
-
handleChatStatusResponse(response) {
|
|
126
|
-
const { chatbot, features } = response;
|
|
127
|
-
const { status, suggestedQuestions, welcomeMessage } = chatbot;
|
|
128
|
-
this.chatEnabled = status.enabled === true;
|
|
129
|
-
this.features = features;
|
|
130
|
-
this.suggestedQuestions = suggestedQuestions || [];
|
|
131
|
-
this.welcomeMessage = welcomeMessage || '';
|
|
132
|
-
this.storage.set('chatStatusResponse', JSON.stringify({ response, checkTime: Date.now() }));
|
|
133
|
-
return this.chatEnabled;
|
|
134
|
-
}
|
|
135
|
-
reset() {
|
|
136
|
-
this.chats = [];
|
|
137
|
-
this.clearProductQuickview();
|
|
138
|
-
this.storage.clear();
|
|
139
|
-
this.createChat();
|
|
140
|
-
}
|
|
141
|
-
setProductQuickview(product) {
|
|
142
|
-
this.productQuickview = product;
|
|
143
|
-
this.productQuickviewError = null;
|
|
144
|
-
}
|
|
145
|
-
updateProductQuickview(response) {
|
|
146
|
-
if (!this.productQuickview) {
|
|
147
|
-
return;
|
|
148
|
-
}
|
|
149
|
-
// merge parent-level mappings from the API response into the Product
|
|
150
|
-
this.productQuickview.mappings = {
|
|
151
|
-
...this.productQuickview.mappings,
|
|
152
|
-
core: { ...this.productQuickview.mappings.core, ...response.mappings.core },
|
|
153
|
-
};
|
|
154
|
-
const meta = this.meta?.data || {};
|
|
155
|
-
if (this.productQuickview.variants) {
|
|
156
|
-
// update existing Variants with new data from the Products API
|
|
157
|
-
this.productQuickview.variants.optionConfig = response.variants.optionConfig;
|
|
158
|
-
this.productQuickview.variants.update(response.variants.data);
|
|
159
|
-
}
|
|
160
|
-
else {
|
|
161
|
-
// create Variants for the first time using the Products API data
|
|
162
|
-
this.productQuickview.variants = new Variants({
|
|
163
|
-
data: {
|
|
164
|
-
mask: this.productQuickview.mask,
|
|
165
|
-
variants: response.variants.data,
|
|
166
|
-
optionConfig: response.variants.optionConfig,
|
|
167
|
-
meta,
|
|
168
|
-
},
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
setProductQuickviewError(message) {
|
|
173
|
-
this.productQuickviewError = message;
|
|
174
|
-
}
|
|
175
|
-
clearProductQuickview() {
|
|
176
|
-
this.productQuickview = null;
|
|
177
|
-
this.productQuickviewError = null;
|
|
178
|
-
}
|
|
179
|
-
clearHistory() {
|
|
180
|
-
// drop previous chats while keeping the conversation the user is currently in;
|
|
181
|
-
// if there is no current chat, fall back to a full reset
|
|
182
|
-
const currentChat = this.currentChat;
|
|
183
|
-
if (!currentChat) {
|
|
184
|
-
this.reset();
|
|
185
|
-
return;
|
|
186
|
-
}
|
|
187
|
-
const storedChats = this.storage.get('chats') || {};
|
|
188
|
-
const filtered = {};
|
|
189
|
-
if (storedChats[currentChat.id]) {
|
|
190
|
-
filtered[currentChat.id] = storedChats[currentChat.id];
|
|
191
|
-
}
|
|
192
|
-
this.storage.set('chats', filtered);
|
|
193
|
-
this.chats = [currentChat];
|
|
194
|
-
}
|
|
195
|
-
createChat(data) {
|
|
196
|
-
// Prune old sessions before creating a new one to keep storage bounded
|
|
197
|
-
ChatSessionStore.pruneStoredSessions(this.storage);
|
|
198
|
-
const newChat = new ChatSessionStore({
|
|
199
|
-
data: {
|
|
200
|
-
sessionId: data?.sessionId,
|
|
201
|
-
},
|
|
202
|
-
stores: {
|
|
203
|
-
storage: this.storage,
|
|
204
|
-
},
|
|
205
|
-
});
|
|
206
|
-
this.currentChatId = newChat.id;
|
|
207
|
-
this.chats.push(newChat);
|
|
208
|
-
return newChat;
|
|
209
|
-
}
|
|
210
|
-
switchChat(id) {
|
|
211
|
-
const chatExists = this.chats.find((chat) => chat.id === id);
|
|
212
|
-
if (chatExists) {
|
|
213
|
-
// Lazily hydrate results when switching to a session for the first time
|
|
214
|
-
if (!chatExists.hydrated && this.storedMetaData) {
|
|
215
|
-
chatExists.hydrateResults(this.storedMetaData);
|
|
216
|
-
chatExists.hydrated = true;
|
|
217
|
-
}
|
|
218
|
-
this.currentChatId = id;
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
sendProductQuery(result, options) {
|
|
222
|
-
const display = result?.display || result;
|
|
223
|
-
this.currentChat?.attachments.add({
|
|
224
|
-
type: 'product',
|
|
225
|
-
requestType: options.requestType,
|
|
226
|
-
productId: result.id,
|
|
227
|
-
name: display.mappings?.core?.name,
|
|
228
|
-
thumbnailUrl: display.mappings?.core?.thumbnailImageUrl || display.mappings?.core?.imageUrl,
|
|
229
|
-
});
|
|
230
|
-
// for the productQuery flow we want the secondary chat to immediately
|
|
231
|
-
// show the product details panel — push a productQuery message so it
|
|
232
|
-
// becomes the active side-chat message until a productAnswer arrives
|
|
233
|
-
if (options.requestType === 'productQuery' && this.currentChat) {
|
|
234
|
-
this.currentChat.pushProductQueryMessage(result);
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
compareProduct(result) {
|
|
238
|
-
this.currentChat?.comparisons.add({
|
|
239
|
-
result,
|
|
240
|
-
});
|
|
241
|
-
}
|
|
242
|
-
addFacet(facet) {
|
|
243
|
-
this.currentChat?.attachments.add({
|
|
244
|
-
type: 'facet',
|
|
245
|
-
key: facet.key,
|
|
246
|
-
facetLabel: facet.facetLabel,
|
|
247
|
-
value: facet.value,
|
|
248
|
-
label: facet.label,
|
|
249
|
-
count: facet.count,
|
|
250
|
-
});
|
|
251
|
-
}
|
|
252
|
-
removeFacet(key, value) {
|
|
253
|
-
const facetAttachment = this.currentChat?.attachments.items.find((item) => item.type === 'facet' &&
|
|
254
|
-
item.key === key &&
|
|
255
|
-
item.value === value &&
|
|
256
|
-
(item.state === 'active' || item.state === 'attached'));
|
|
257
|
-
if (facetAttachment) {
|
|
258
|
-
const index = this.currentChat?.attachments.items.indexOf(facetAttachment);
|
|
259
|
-
if (index !== undefined && index !== -1) {
|
|
260
|
-
this.currentChat?.attachments.items.splice(index, 1);
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
clearPendingFacets() {
|
|
265
|
-
const facetAttachments = this.currentChat?.attachments.items.filter((item) => item.type === 'facet' && (item.state === 'active' || item.state === 'attached')) || [];
|
|
266
|
-
facetAttachments.forEach((item) => {
|
|
267
|
-
const index = this.currentChat?.attachments.items.indexOf(item);
|
|
268
|
-
if (index !== undefined && index !== -1) {
|
|
269
|
-
this.currentChat?.attachments.items.splice(index, 1);
|
|
270
|
-
}
|
|
271
|
-
});
|
|
272
|
-
}
|
|
273
|
-
isFacetSelected(key, value) {
|
|
274
|
-
return (this.currentChat?.attachments.items.some((item) => item.type === 'facet' &&
|
|
275
|
-
item.key === key &&
|
|
276
|
-
item.value === value &&
|
|
277
|
-
(item.state === 'active' || item.state === 'attached')) || false);
|
|
278
|
-
}
|
|
279
|
-
request(request) {
|
|
280
|
-
this.currentChat?.request(request);
|
|
281
|
-
// remove any facet attachments after request
|
|
282
|
-
const facetAttachments = this.currentChat?.attachments.attached.filter((item) => item.type === 'facet') || [];
|
|
283
|
-
facetAttachments.forEach((item) => {
|
|
284
|
-
this.currentChat?.attachments.remove(item.id);
|
|
285
|
-
});
|
|
286
|
-
// remove any productSimilar attachments after request
|
|
287
|
-
const productSimilarAttachments = this.currentChat?.attachments.attached.filter((item) => item.type === 'product' && item.requestType === 'productSimilar') || [];
|
|
288
|
-
productSimilarAttachments.forEach((item) => {
|
|
289
|
-
this.currentChat?.attachments.remove(item.id);
|
|
290
|
-
});
|
|
291
|
-
}
|
|
292
|
-
update(data) {
|
|
293
|
-
// TODO: handle error
|
|
294
|
-
// if(err?.responseBody?.errorMessage || err?.responseBody?.errorCode) {
|
|
295
|
-
// const errorMessage = err?.responseBody?.errorMessage || 'An unknown error has occurred.';
|
|
296
|
-
// }
|
|
297
|
-
this.currentChat?.update(data);
|
|
298
|
-
if (!this.meta) {
|
|
299
|
-
this.storage.set('meta', JSON.stringify(data.meta));
|
|
300
|
-
}
|
|
301
|
-
this.meta = new MetaStore({
|
|
302
|
-
data: {
|
|
303
|
-
meta: data.meta,
|
|
304
|
-
},
|
|
305
|
-
});
|
|
306
|
-
// Keep raw meta in sync for lazy hydration of inactive sessions
|
|
307
|
-
this.storedMetaData = data.meta;
|
|
308
|
-
}
|
|
309
|
-
}
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
type AttachmentState = 'loading' | 'error' | 'attached' | 'active' | 'saved';
|
|
2
|
-
type AttachmentError = {
|
|
3
|
-
message: string;
|
|
4
|
-
};
|
|
5
|
-
export type ChatAttachmentAddAttachment = ChatAttachmentImageConfig | ChatAttachmentProductConfig | ChatAttachmentFacetConfig;
|
|
6
|
-
export declare class ChatAttachmentStore {
|
|
7
|
-
items: ChatAttachments[];
|
|
8
|
-
constructor();
|
|
9
|
-
get attached(): ChatAttachments[];
|
|
10
|
-
get compared(): ChatAttachmentProduct[];
|
|
11
|
-
add<T extends ChatAttachments>(attachment: ChatAttachmentAddAttachment): T;
|
|
12
|
-
remove(id: string): void;
|
|
13
|
-
get(id: string): ChatAttachments | undefined;
|
|
14
|
-
reset(): void;
|
|
15
|
-
hydrate(attachments: ChatAttachmentAddAttachment[]): void;
|
|
16
|
-
}
|
|
17
|
-
type ChatAttachments = ChatAttachmentImage | ChatAttachmentProduct | ChatAttachmentFacet;
|
|
18
|
-
declare abstract class ChatAttachment {
|
|
19
|
-
abstract type: string;
|
|
20
|
-
id: string;
|
|
21
|
-
state: AttachmentState;
|
|
22
|
-
error?: AttachmentError;
|
|
23
|
-
constructor(params?: {
|
|
24
|
-
data?: {
|
|
25
|
-
id?: string;
|
|
26
|
-
state?: AttachmentState;
|
|
27
|
-
error?: AttachmentError;
|
|
28
|
-
};
|
|
29
|
-
});
|
|
30
|
-
save(): void;
|
|
31
|
-
activate(): void;
|
|
32
|
-
}
|
|
33
|
-
type ChatAttachmentImageConfig = {
|
|
34
|
-
type: 'image';
|
|
35
|
-
id?: string;
|
|
36
|
-
base64?: string;
|
|
37
|
-
fileName?: string;
|
|
38
|
-
imageId?: string;
|
|
39
|
-
imageUrl?: string;
|
|
40
|
-
thumbnailUrl?: string;
|
|
41
|
-
state?: AttachmentState;
|
|
42
|
-
error?: AttachmentError;
|
|
43
|
-
};
|
|
44
|
-
type ChatAttachmentProductConfig = {
|
|
45
|
-
type: 'product';
|
|
46
|
-
id?: string;
|
|
47
|
-
productId: string;
|
|
48
|
-
thumbnailUrl: string;
|
|
49
|
-
name: string;
|
|
50
|
-
requestType: 'productQuery' | 'productSimilar' | 'productComparison';
|
|
51
|
-
state?: AttachmentState;
|
|
52
|
-
error?: AttachmentError;
|
|
53
|
-
};
|
|
54
|
-
type ChatAttachmentFacetConfig = {
|
|
55
|
-
type: 'facet';
|
|
56
|
-
id?: string;
|
|
57
|
-
key: string;
|
|
58
|
-
facetLabel: string;
|
|
59
|
-
value: string;
|
|
60
|
-
label: string;
|
|
61
|
-
count: number;
|
|
62
|
-
state?: AttachmentState;
|
|
63
|
-
error?: AttachmentError;
|
|
64
|
-
};
|
|
65
|
-
export declare class ChatAttachmentProduct extends ChatAttachment {
|
|
66
|
-
type: 'product' | never;
|
|
67
|
-
productId: string;
|
|
68
|
-
thumbnailUrl: string;
|
|
69
|
-
name: string;
|
|
70
|
-
requestType: 'productQuery' | 'productSimilar' | 'productComparison';
|
|
71
|
-
constructor({ id, productId, thumbnailUrl, name, requestType, state, error }: ChatAttachmentProductConfig);
|
|
72
|
-
}
|
|
73
|
-
export declare class ChatAttachmentFacet extends ChatAttachment {
|
|
74
|
-
type: 'facet' | never;
|
|
75
|
-
key: string;
|
|
76
|
-
facetLabel: string;
|
|
77
|
-
value: string;
|
|
78
|
-
label: string;
|
|
79
|
-
count: number;
|
|
80
|
-
constructor({ id, key, facetLabel, value, label, count, state, error }: ChatAttachmentFacetConfig);
|
|
81
|
-
}
|
|
82
|
-
export declare class ChatAttachmentImage extends ChatAttachment {
|
|
83
|
-
type: 'image' | never;
|
|
84
|
-
fileName?: string;
|
|
85
|
-
imageId?: string;
|
|
86
|
-
imageUrl?: string;
|
|
87
|
-
thumbnailUrl?: string;
|
|
88
|
-
base64?: string;
|
|
89
|
-
constructor({ id, base64, fileName, imageId, imageUrl, thumbnailUrl, state, error }: ChatAttachmentImageConfig);
|
|
90
|
-
update: ({ imageId, imageUrl, thumbnailUrl, error, }: {
|
|
91
|
-
imageId?: string;
|
|
92
|
-
imageUrl?: string;
|
|
93
|
-
thumbnailUrl?: string;
|
|
94
|
-
error?: AttachmentError;
|
|
95
|
-
}) => Promise<void>;
|
|
96
|
-
}
|
|
97
|
-
export {};
|
|
98
|
-
//# sourceMappingURL=ChatAttachmentStore.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ChatAttachmentStore.d.ts","sourceRoot":"","sources":["../../../../src/Chat/Stores/ChatAttachmentStore.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,220 +0,0 @@
|
|
|
1
|
-
// TODO: implement
|
|
2
|
-
// how should localStorage be handled for attachments?
|
|
3
|
-
import { v4 as uuidv4 } from 'uuid';
|
|
4
|
-
import { makeObservable, observable, computed } from 'mobx';
|
|
5
|
-
export class ChatAttachmentStore {
|
|
6
|
-
constructor() {
|
|
7
|
-
this.items = [];
|
|
8
|
-
makeObservable(this, {
|
|
9
|
-
items: observable,
|
|
10
|
-
attached: computed,
|
|
11
|
-
compared: computed,
|
|
12
|
-
});
|
|
13
|
-
}
|
|
14
|
-
get attached() {
|
|
15
|
-
return this.items.filter((item) => item.state !== 'saved');
|
|
16
|
-
}
|
|
17
|
-
get compared() {
|
|
18
|
-
return this.items
|
|
19
|
-
.filter((item) => item.state !== 'saved')
|
|
20
|
-
.filter((item) => item.type === 'product')
|
|
21
|
-
.filter((item) => item.requestType === 'productComparison');
|
|
22
|
-
}
|
|
23
|
-
add(attachment) {
|
|
24
|
-
// TODO: check if attachment already exists
|
|
25
|
-
switch (attachment.type) {
|
|
26
|
-
case 'image': {
|
|
27
|
-
// if there are currently any other attachments remove them
|
|
28
|
-
this.items.forEach((item) => {
|
|
29
|
-
this.remove(item.id);
|
|
30
|
-
});
|
|
31
|
-
const newAttachment = new ChatAttachmentImage(attachment);
|
|
32
|
-
this.items.push(newAttachment);
|
|
33
|
-
return newAttachment;
|
|
34
|
-
}
|
|
35
|
-
case 'product': {
|
|
36
|
-
// 'productSimilar' and 'productQuery' are single-product flows — replace any
|
|
37
|
-
// existing attachments so the conversation only targets the latest product
|
|
38
|
-
if (attachment.requestType === 'productSimilar' || attachment.requestType === 'productQuery') {
|
|
39
|
-
this.items.forEach((item) => {
|
|
40
|
-
this.remove(item.id);
|
|
41
|
-
});
|
|
42
|
-
const newAttachment = new ChatAttachmentProduct(attachment);
|
|
43
|
-
this.items.unshift(newAttachment);
|
|
44
|
-
return newAttachment;
|
|
45
|
-
}
|
|
46
|
-
// For 'productQuery' or 'productComparison', continue with existing logic
|
|
47
|
-
// if there are currently any other attachments remove them
|
|
48
|
-
this.items.forEach((item) => {
|
|
49
|
-
if (item.type !== 'product') {
|
|
50
|
-
this.remove(item.id);
|
|
51
|
-
}
|
|
52
|
-
});
|
|
53
|
-
// check if product is already attached
|
|
54
|
-
const existingProductAttachment = this.items.find((item) => item.type === 'product' &&
|
|
55
|
-
(item.state === 'active' || item.state === 'attached') &&
|
|
56
|
-
item.productId === attachment.productId);
|
|
57
|
-
if (existingProductAttachment) {
|
|
58
|
-
existingProductAttachment.requestType = attachment.requestType; // changes existing attachments to the incoming requestType
|
|
59
|
-
return existingProductAttachment;
|
|
60
|
-
}
|
|
61
|
-
// if there are already two product attachments, remove until only one remains
|
|
62
|
-
const productAttachments = this.items.filter((item) => item.type === 'product' && (item.state === 'active' || item.state === 'attached'));
|
|
63
|
-
while (productAttachments.length >= 2) {
|
|
64
|
-
const toRemove = productAttachments.pop();
|
|
65
|
-
if (toRemove) {
|
|
66
|
-
this.remove(toRemove.id);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
this.items.forEach((item) => {
|
|
70
|
-
item.requestType = attachment.requestType; // changes existing attachments to the incoming requestType
|
|
71
|
-
});
|
|
72
|
-
const newAttachment = new ChatAttachmentProduct(attachment);
|
|
73
|
-
this.items.unshift(newAttachment);
|
|
74
|
-
return newAttachment;
|
|
75
|
-
}
|
|
76
|
-
case 'facet': {
|
|
77
|
-
// if there are currently any non-facet attachments remove them
|
|
78
|
-
this.items.forEach((item) => {
|
|
79
|
-
if (item.type !== 'facet') {
|
|
80
|
-
this.remove(item.id);
|
|
81
|
-
}
|
|
82
|
-
});
|
|
83
|
-
// check if this exact facet value is already attached
|
|
84
|
-
const existingFacet = this.items.find((item) => item.type === 'facet' &&
|
|
85
|
-
item.key === attachment.key &&
|
|
86
|
-
item.value === attachment.value &&
|
|
87
|
-
(item.state === 'active' || item.state === 'attached'));
|
|
88
|
-
if (existingFacet) {
|
|
89
|
-
return existingFacet;
|
|
90
|
-
}
|
|
91
|
-
const newAttachment = new ChatAttachmentFacet(attachment);
|
|
92
|
-
this.items.push(newAttachment);
|
|
93
|
-
return newAttachment;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
remove(id) {
|
|
98
|
-
const index = this.items.findIndex((item) => item.id === id);
|
|
99
|
-
const attachment = this.items[index];
|
|
100
|
-
if (attachment.state === 'active' || attachment.state === 'saved') {
|
|
101
|
-
attachment.save();
|
|
102
|
-
}
|
|
103
|
-
else {
|
|
104
|
-
if (index !== -1) {
|
|
105
|
-
this.items.splice(index, 1);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
get(id) {
|
|
110
|
-
return this.items.find((item) => item.id === id);
|
|
111
|
-
}
|
|
112
|
-
reset() {
|
|
113
|
-
this.items = [];
|
|
114
|
-
}
|
|
115
|
-
// Restore serialized attachments from storage without running the add() dedup logic,
|
|
116
|
-
// which would otherwise drop earlier images when multiple attachments are loaded.
|
|
117
|
-
hydrate(attachments) {
|
|
118
|
-
attachments.forEach((attachment) => {
|
|
119
|
-
switch (attachment.type) {
|
|
120
|
-
case 'image':
|
|
121
|
-
this.items.push(new ChatAttachmentImage(attachment));
|
|
122
|
-
break;
|
|
123
|
-
case 'product':
|
|
124
|
-
this.items.push(new ChatAttachmentProduct(attachment));
|
|
125
|
-
break;
|
|
126
|
-
case 'facet':
|
|
127
|
-
this.items.push(new ChatAttachmentFacet(attachment));
|
|
128
|
-
break;
|
|
129
|
-
}
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
class ChatAttachment {
|
|
134
|
-
constructor(params = {}) {
|
|
135
|
-
this.state = 'loading';
|
|
136
|
-
this.error = undefined;
|
|
137
|
-
this.id = params.data?.id ?? uuidv4();
|
|
138
|
-
this.state = params.data?.state ?? 'loading';
|
|
139
|
-
makeObservable(this, {
|
|
140
|
-
id: observable,
|
|
141
|
-
state: observable,
|
|
142
|
-
error: observable,
|
|
143
|
-
});
|
|
144
|
-
}
|
|
145
|
-
save() {
|
|
146
|
-
this.state = 'saved';
|
|
147
|
-
}
|
|
148
|
-
activate() {
|
|
149
|
-
this.state = 'active';
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
export class ChatAttachmentProduct extends ChatAttachment {
|
|
153
|
-
constructor({ id, productId, thumbnailUrl, name, requestType, state, error }) {
|
|
154
|
-
super({ data: { id, state, error } });
|
|
155
|
-
this.type = 'product';
|
|
156
|
-
this.state = state ?? 'attached';
|
|
157
|
-
this.productId = productId;
|
|
158
|
-
this.thumbnailUrl = thumbnailUrl;
|
|
159
|
-
this.name = name;
|
|
160
|
-
this.requestType = requestType;
|
|
161
|
-
makeObservable(this, {
|
|
162
|
-
type: observable,
|
|
163
|
-
productId: observable,
|
|
164
|
-
thumbnailUrl: observable,
|
|
165
|
-
name: observable,
|
|
166
|
-
requestType: observable,
|
|
167
|
-
});
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
export class ChatAttachmentFacet extends ChatAttachment {
|
|
171
|
-
constructor({ id, key, facetLabel, value, label, count, state, error }) {
|
|
172
|
-
super({ data: { id, state, error } });
|
|
173
|
-
this.type = 'facet';
|
|
174
|
-
this.state = state ?? 'attached';
|
|
175
|
-
this.key = key;
|
|
176
|
-
this.facetLabel = facetLabel;
|
|
177
|
-
this.value = value;
|
|
178
|
-
this.label = label;
|
|
179
|
-
this.count = count;
|
|
180
|
-
makeObservable(this, {
|
|
181
|
-
type: observable,
|
|
182
|
-
key: observable,
|
|
183
|
-
facetLabel: observable,
|
|
184
|
-
value: observable,
|
|
185
|
-
label: observable,
|
|
186
|
-
});
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
export class ChatAttachmentImage extends ChatAttachment {
|
|
190
|
-
constructor({ id, base64, fileName, imageId, imageUrl, thumbnailUrl, state, error }) {
|
|
191
|
-
super({ data: { id, state, error } });
|
|
192
|
-
this.type = 'image';
|
|
193
|
-
// used to update attachment after upload or from
|
|
194
|
-
this.update = async ({ imageId, imageUrl, thumbnailUrl, error, }) => {
|
|
195
|
-
if (imageId && imageUrl && thumbnailUrl) {
|
|
196
|
-
this.state = 'attached';
|
|
197
|
-
this.imageId = imageId;
|
|
198
|
-
this.imageUrl = imageUrl;
|
|
199
|
-
this.thumbnailUrl = thumbnailUrl;
|
|
200
|
-
}
|
|
201
|
-
else if (error) {
|
|
202
|
-
this.state = 'error';
|
|
203
|
-
this.error = error;
|
|
204
|
-
}
|
|
205
|
-
};
|
|
206
|
-
this.base64 = base64;
|
|
207
|
-
this.fileName = fileName;
|
|
208
|
-
this.imageId = imageId;
|
|
209
|
-
this.imageUrl = imageUrl;
|
|
210
|
-
this.thumbnailUrl = thumbnailUrl;
|
|
211
|
-
makeObservable(this, {
|
|
212
|
-
type: observable,
|
|
213
|
-
imageId: observable,
|
|
214
|
-
imageUrl: observable,
|
|
215
|
-
thumbnailUrl: observable,
|
|
216
|
-
base64: observable,
|
|
217
|
-
fileName: observable,
|
|
218
|
-
});
|
|
219
|
-
}
|
|
220
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
export declare class ChatCompareStore {
|
|
2
|
-
items: any[];
|
|
3
|
-
committedItems: any[];
|
|
4
|
-
maxItems: number;
|
|
5
|
-
constructor();
|
|
6
|
-
add(item: any): void;
|
|
7
|
-
remove(itemId: string): void;
|
|
8
|
-
reset(): void;
|
|
9
|
-
resetCommitted(): void;
|
|
10
|
-
commit(): void;
|
|
11
|
-
get compared(): any[];
|
|
12
|
-
get committed(): any[];
|
|
13
|
-
}
|
|
14
|
-
//# sourceMappingURL=ChatCompareStore.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ChatCompareStore.d.ts","sourceRoot":"","sources":["../../../../src/Chat/Stores/ChatCompareStore.ts"],"names":[],"mappings":"AAEA,qBAAa,gBAAgB;IACrB,KAAK,EAAE,GAAG,EAAE,CAAM;IAClB,cAAc,EAAE,GAAG,EAAE,CAAM;IAC3B,QAAQ,EAAE,MAAM,CAAK;;IAa5B,GAAG,CAAC,IAAI,EAAE,GAAG;IAYb,MAAM,CAAC,MAAM,EAAE,MAAM;IAIrB,KAAK;IAIL,cAAc;IAKd,MAAM;IAON,IAAI,QAAQ,UAEX;IAED,IAAI,SAAS,UAEZ;CACD"}
|