@getlupa/vue 0.18.4 → 0.19.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/lupaSearch.js +159 -74
- package/dist/lupaSearch.mjs +159 -74
- package/dist/src/composables/useVoiceRecorder.d.ts +1 -0
- package/dist/src/types/DocumentElement.d.ts +2 -1
- package/dist/src/types/search-box/SearchBoxOptions.d.ts +4 -1
- package/dist/src/utils/render.utils.d.ts +2 -1
- package/package.json +1 -1
package/dist/lupaSearch.js
CHANGED
|
@@ -7294,7 +7294,7 @@ const getNormalizedString = (str) => {
|
|
|
7294
7294
|
return "";
|
|
7295
7295
|
}
|
|
7296
7296
|
const transformedStr = typeof str === "string" ? str : str.toString();
|
|
7297
|
-
return transformedStr.normalize === void 0 ? (_a = transformedStr.toLocaleLowerCase()) == null ? void 0 : _a.trim() : (_b = transformedStr.toLocaleLowerCase().normalize("NFKD").replace(/[^\
|
|
7297
|
+
return transformedStr.normalize === void 0 ? (_a = transformedStr.toLocaleLowerCase()) == null ? void 0 : _a.trim() : (_b = transformedStr.toLocaleLowerCase().normalize("NFKD").replace(/[^\p{L}\p{N}\s]/gu, "")) == null ? void 0 : _b.trim();
|
|
7298
7298
|
};
|
|
7299
7299
|
const getTransformedString = (str) => {
|
|
7300
7300
|
var _a, _b;
|
|
@@ -9034,8 +9034,8 @@ const Env = {
|
|
|
9034
9034
|
staging: "https://api.staging.lupasearch.com/v1/"
|
|
9035
9035
|
};
|
|
9036
9036
|
const VoiceServiceEnv = {
|
|
9037
|
-
production: "
|
|
9038
|
-
staging: "
|
|
9037
|
+
production: "wss://voice.lupasearch.com",
|
|
9038
|
+
staging: "wss://voice.lupasearch.dev"
|
|
9039
9039
|
};
|
|
9040
9040
|
const DEFAULT_REQUEST_CONFIG = {
|
|
9041
9041
|
method: "POST",
|
|
@@ -9076,7 +9076,7 @@ const _sfc_main$1z = /* @__PURE__ */ vue.defineComponent({
|
|
|
9076
9076
|
}
|
|
9077
9077
|
};
|
|
9078
9078
|
const startProgressBar = () => {
|
|
9079
|
-
if (!progressBar.value
|
|
9079
|
+
if (!progressBar.value) {
|
|
9080
9080
|
return;
|
|
9081
9081
|
}
|
|
9082
9082
|
const duration = props.timesliceLimit * props.timeSliceLength;
|
|
@@ -9134,6 +9134,7 @@ function useVoiceRecorder(options) {
|
|
|
9134
9134
|
const mediaStream = vue.ref(null);
|
|
9135
9135
|
const mediaRecorder = vue.ref(null);
|
|
9136
9136
|
const isRecording = vue.ref(false);
|
|
9137
|
+
const isSocketReady = vue.ref(false);
|
|
9137
9138
|
const errorRef = vue.ref(null);
|
|
9138
9139
|
const transcription = vue.ref("");
|
|
9139
9140
|
const timeSliceLength = vue.computed(() => {
|
|
@@ -9146,35 +9147,51 @@ function useVoiceRecorder(options) {
|
|
|
9146
9147
|
});
|
|
9147
9148
|
const initSocket = (url, onMessage) => {
|
|
9148
9149
|
socket.value = new WebSocket(url);
|
|
9149
|
-
socket.value.
|
|
9150
|
+
socket.value.onmessage = (event) => __async(this, null, function* () {
|
|
9150
9151
|
var _a;
|
|
9151
|
-
|
|
9152
|
-
|
|
9152
|
+
try {
|
|
9153
|
+
const msg = JSON.parse(event.data);
|
|
9154
|
+
if (msg.event === "ready") {
|
|
9155
|
+
if (((_a = mediaRecorder.value) == null ? void 0 : _a.state) !== "recording") {
|
|
9156
|
+
try {
|
|
9157
|
+
isSocketReady.value = true;
|
|
9158
|
+
yield startRecording();
|
|
9159
|
+
} catch (error) {
|
|
9160
|
+
console.error("Recording failed to start:", error);
|
|
9161
|
+
closeSocket();
|
|
9162
|
+
}
|
|
9163
|
+
}
|
|
9164
|
+
} else if (msg.event === "transcription") {
|
|
9165
|
+
transcription.value = msg.transcription;
|
|
9166
|
+
onMessage == null ? void 0 : onMessage(msg.transcription);
|
|
9167
|
+
stopSocketConnection();
|
|
9168
|
+
} else if (msg.event === "error") {
|
|
9169
|
+
errorRef.value = msg.message || "An error occurred during transcription";
|
|
9170
|
+
isSocketReady.value = false;
|
|
9171
|
+
stopRecording();
|
|
9172
|
+
closeSocket();
|
|
9173
|
+
}
|
|
9174
|
+
} catch (error) {
|
|
9175
|
+
console.error("Error processing WebSocket message:", error);
|
|
9153
9176
|
}
|
|
9154
9177
|
});
|
|
9155
|
-
socket.value.
|
|
9156
|
-
|
|
9157
|
-
|
|
9158
|
-
transcription.value = msg.transcription;
|
|
9159
|
-
onMessage == null ? void 0 : onMessage(msg.transcription);
|
|
9160
|
-
stopSocketConnection();
|
|
9161
|
-
} else if (msg.event === "error") {
|
|
9162
|
-
errorRef.value = "Server error during transcription";
|
|
9163
|
-
stopRecording();
|
|
9178
|
+
socket.value.onclose = (event) => {
|
|
9179
|
+
if (event.code === 4001) {
|
|
9180
|
+
errorRef.value = event.reason || "Connection closed by server";
|
|
9164
9181
|
}
|
|
9165
|
-
};
|
|
9166
|
-
socket.value.onclose = () => {
|
|
9167
9182
|
stopRecording();
|
|
9168
9183
|
};
|
|
9169
9184
|
socket.value.onerror = () => {
|
|
9170
|
-
stopRecording();
|
|
9171
9185
|
errorRef.value = "Service connection error";
|
|
9186
|
+
stopRecording();
|
|
9172
9187
|
};
|
|
9173
9188
|
};
|
|
9174
9189
|
const onMediaRecorderDataAvailable = (event) => __async(this, null, function* () {
|
|
9175
9190
|
var _a, _b;
|
|
9176
|
-
if (((_a =
|
|
9191
|
+
if (!isSocketReady.value || ((_a = socket.value) == null ? void 0 : _a.readyState) !== WebSocket.OPEN) {
|
|
9192
|
+
console.warn("Skipping audio chunk: socket not ready.");
|
|
9177
9193
|
return;
|
|
9194
|
+
}
|
|
9178
9195
|
const audioBuffer = yield event.data.arrayBuffer();
|
|
9179
9196
|
const header = buildSocketMessageFrameHeader("audio-chunk", audioBuffer.byteLength);
|
|
9180
9197
|
const buffer = new Uint8Array(header.length + audioBuffer.byteLength);
|
|
@@ -9183,20 +9200,29 @@ function useVoiceRecorder(options) {
|
|
|
9183
9200
|
(_b = socket.value) == null ? void 0 : _b.send(buffer);
|
|
9184
9201
|
});
|
|
9185
9202
|
const startRecording = () => __async(this, null, function* () {
|
|
9186
|
-
|
|
9187
|
-
|
|
9188
|
-
|
|
9189
|
-
|
|
9190
|
-
|
|
9191
|
-
|
|
9203
|
+
var _a, _b;
|
|
9204
|
+
try {
|
|
9205
|
+
mediaStream.value = yield navigator.mediaDevices.getUserMedia({
|
|
9206
|
+
video: false,
|
|
9207
|
+
audio: {
|
|
9208
|
+
channelCount: 1,
|
|
9209
|
+
echoCancellation: true,
|
|
9210
|
+
sampleRate: options.sampleRate || 16e3
|
|
9211
|
+
}
|
|
9212
|
+
});
|
|
9213
|
+
mediaRecorder.value = new MediaRecorder(mediaStream.value, {
|
|
9214
|
+
mimeType: "audio/webm; codecs=opus"
|
|
9215
|
+
});
|
|
9216
|
+
mediaRecorder.value.ondataavailable = onMediaRecorderDataAvailable;
|
|
9217
|
+
mediaRecorder.value.start(timeSliceLength.value);
|
|
9218
|
+
isRecording.value = true;
|
|
9219
|
+
} catch (error) {
|
|
9220
|
+
if (error.name === "NotAllowedError") {
|
|
9221
|
+
errorRef.value = ((_a = options.labels) == null ? void 0 : _a.microphoneNotAllowed) || "Microphone access denied. Please allow microphone access in your browser settings.";
|
|
9222
|
+
} else if (error.name === "NotFoundError") {
|
|
9223
|
+
errorRef.value = ((_b = options.labels) == null ? void 0 : _b.microphoneNotFound) || "No microphone found. Please connect a microphone and try again.";
|
|
9192
9224
|
}
|
|
9193
|
-
}
|
|
9194
|
-
mediaRecorder.value = new MediaRecorder(mediaStream.value, {
|
|
9195
|
-
mimeType: "audio/webm; codecs=opus"
|
|
9196
|
-
});
|
|
9197
|
-
mediaRecorder.value.ondataavailable = onMediaRecorderDataAvailable;
|
|
9198
|
-
mediaRecorder.value.start(timeSliceLength.value);
|
|
9199
|
-
isRecording.value = true;
|
|
9225
|
+
}
|
|
9200
9226
|
});
|
|
9201
9227
|
const stopRecording = () => {
|
|
9202
9228
|
var _a, _b;
|
|
@@ -9219,6 +9245,7 @@ function useVoiceRecorder(options) {
|
|
|
9219
9245
|
var _a;
|
|
9220
9246
|
(_a = socket.value) == null ? void 0 : _a.close();
|
|
9221
9247
|
socket.value = null;
|
|
9248
|
+
isSocketReady.value = false;
|
|
9222
9249
|
};
|
|
9223
9250
|
const reset = () => {
|
|
9224
9251
|
stopRecording();
|
|
@@ -9226,9 +9253,11 @@ function useVoiceRecorder(options) {
|
|
|
9226
9253
|
transcription.value = "";
|
|
9227
9254
|
errorRef.value = null;
|
|
9228
9255
|
isRecording.value = false;
|
|
9256
|
+
isSocketReady.value = false;
|
|
9229
9257
|
};
|
|
9230
9258
|
return {
|
|
9231
9259
|
isRecording,
|
|
9260
|
+
isSocketReady,
|
|
9232
9261
|
transcription,
|
|
9233
9262
|
errorRef,
|
|
9234
9263
|
initSocket,
|
|
@@ -9262,6 +9291,7 @@ const _sfc_main$1y = /* @__PURE__ */ vue.defineComponent({
|
|
|
9262
9291
|
const optionsStore = useOptionsStore();
|
|
9263
9292
|
const {
|
|
9264
9293
|
isRecording,
|
|
9294
|
+
isSocketReady,
|
|
9265
9295
|
transcription,
|
|
9266
9296
|
errorRef,
|
|
9267
9297
|
initSocket,
|
|
@@ -9287,20 +9317,28 @@ const _sfc_main$1y = /* @__PURE__ */ vue.defineComponent({
|
|
|
9287
9317
|
return (_a = props.options.labels) != null ? _a : {};
|
|
9288
9318
|
});
|
|
9289
9319
|
const description = vue.computed(() => {
|
|
9290
|
-
var _a, _b
|
|
9320
|
+
var _a, _b;
|
|
9291
9321
|
if (errorRef.value) {
|
|
9292
|
-
return
|
|
9322
|
+
return errorRef.value;
|
|
9293
9323
|
}
|
|
9294
|
-
if (!isRecording.value) {
|
|
9295
|
-
return (
|
|
9324
|
+
if (!isSocketReady.value || !isRecording.value) {
|
|
9325
|
+
return (_a = labels.value.connecting) != null ? _a : "Connecting...";
|
|
9296
9326
|
}
|
|
9297
|
-
return (
|
|
9327
|
+
return (_b = labels.value.listening) != null ? _b : "Listening...";
|
|
9298
9328
|
});
|
|
9299
9329
|
vue.watch(transcription, (newValue) => {
|
|
9300
9330
|
emit("transcript-update", newValue);
|
|
9301
9331
|
});
|
|
9302
|
-
|
|
9332
|
+
vue.watch(isRecording, (newVal) => {
|
|
9303
9333
|
var _a, _b;
|
|
9334
|
+
if (newVal === true) {
|
|
9335
|
+
(_a = voiceSearchProgressBar.value) == null ? void 0 : _a.startProgressBar();
|
|
9336
|
+
} else {
|
|
9337
|
+
(_b = voiceSearchProgressBar.value) == null ? void 0 : _b.stopProgressBar();
|
|
9338
|
+
}
|
|
9339
|
+
});
|
|
9340
|
+
const handleRecordingButtonClick = () => {
|
|
9341
|
+
var _a;
|
|
9304
9342
|
if (isRecording.value) {
|
|
9305
9343
|
setTimeout(() => {
|
|
9306
9344
|
stopSocketConnection();
|
|
@@ -9314,7 +9352,6 @@ const _sfc_main$1y = /* @__PURE__ */ vue.defineComponent({
|
|
|
9314
9352
|
);
|
|
9315
9353
|
const socketUrl = `${voiceServiceUrl}?clientId=${clientId.value}&queryKey=${props.options.queryKey}&languageCode=${(_a = props.options.language) != null ? _a : "en-US"}&connectionType=write-first`;
|
|
9316
9354
|
initSocket(socketUrl);
|
|
9317
|
-
(_b = voiceSearchProgressBar.value) == null ? void 0 : _b.startProgressBar();
|
|
9318
9355
|
setTimeout(() => {
|
|
9319
9356
|
stopSocketConnection();
|
|
9320
9357
|
handleOnStopEvent();
|
|
@@ -19047,6 +19084,15 @@ const processDisplayCondition = (displayCondition, doc = {}) => {
|
|
|
19047
19084
|
return false;
|
|
19048
19085
|
}
|
|
19049
19086
|
};
|
|
19087
|
+
function shouldDisplay(displayOpt, doc) {
|
|
19088
|
+
if (!displayOpt)
|
|
19089
|
+
return true;
|
|
19090
|
+
if (typeof displayOpt === "function") {
|
|
19091
|
+
return displayOpt(doc);
|
|
19092
|
+
}
|
|
19093
|
+
const rules = Array.isArray(displayOpt) ? displayOpt : [displayOpt];
|
|
19094
|
+
return rules.every((rule2) => processDisplayCondition(rule2, doc));
|
|
19095
|
+
}
|
|
19050
19096
|
const checkHasFullImageUrl = (imageUrl) => typeof imageUrl === "string" && (imageUrl.indexOf("http://") === 0 || imageUrl.indexOf("https://") === 0);
|
|
19051
19097
|
const computeImageUrl = (imageUrl, rootImageUrl) => {
|
|
19052
19098
|
const mainUrl = Array.isArray(imageUrl) ? imageUrl[0] : imageUrl;
|
|
@@ -19863,7 +19909,7 @@ const _sfc_main$1g = /* @__PURE__ */ vue.defineComponent(__spreadProps(__spreadV
|
|
|
19863
19909
|
if (!element.display) {
|
|
19864
19910
|
return true;
|
|
19865
19911
|
}
|
|
19866
|
-
return
|
|
19912
|
+
return shouldDisplay(element.display, item);
|
|
19867
19913
|
});
|
|
19868
19914
|
const enhancedItem = vue.computed(() => {
|
|
19869
19915
|
var _a, _b, _c, _d;
|
|
@@ -20186,7 +20232,7 @@ const _sfc_main$19 = /* @__PURE__ */ vue.defineComponent(__spreadProps(__spreadV
|
|
|
20186
20232
|
if (!element.display) {
|
|
20187
20233
|
return true;
|
|
20188
20234
|
}
|
|
20189
|
-
return
|
|
20235
|
+
return shouldDisplay(element.display, item);
|
|
20190
20236
|
};
|
|
20191
20237
|
const badges = vue.computed(() => {
|
|
20192
20238
|
if (!props.options.elements) {
|
|
@@ -20264,10 +20310,6 @@ const _sfc_main$18 = /* @__PURE__ */ vue.defineComponent({
|
|
|
20264
20310
|
const badgeOptions = vue.computed(() => {
|
|
20265
20311
|
return __spreadProps(__spreadValues({}, props.panelOptions.badges), { product: props.item });
|
|
20266
20312
|
});
|
|
20267
|
-
const imageElements = vue.computed(() => {
|
|
20268
|
-
var _a, _b;
|
|
20269
|
-
return (_b = (_a = props.panelOptions.elements) == null ? void 0 : _a.filter((e2) => e2.type === DocumentElementType.IMAGE)) != null ? _b : [];
|
|
20270
|
-
});
|
|
20271
20313
|
const mainImageElement = vue.computed(() => {
|
|
20272
20314
|
return imageElements.value[0];
|
|
20273
20315
|
});
|
|
@@ -20287,12 +20329,6 @@ const _sfc_main$18 = /* @__PURE__ */ vue.defineComponent({
|
|
|
20287
20329
|
minWidth: widthOverride.value ? `${widthOverride.value + 10}px` : void 0
|
|
20288
20330
|
} : {};
|
|
20289
20331
|
});
|
|
20290
|
-
const detailElements = vue.computed(() => {
|
|
20291
|
-
var _a, _b;
|
|
20292
|
-
return (_b = (_a = props.panelOptions.elements) == null ? void 0 : _a.filter(
|
|
20293
|
-
(e2) => e2.type !== DocumentElementType.IMAGE && e2.type !== DocumentElementType.ADDTOCART
|
|
20294
|
-
)) != null ? _b : [];
|
|
20295
|
-
});
|
|
20296
20332
|
const addToCartElement = vue.computed(() => {
|
|
20297
20333
|
var _a;
|
|
20298
20334
|
return (_a = props.panelOptions.elements) == null ? void 0 : _a.find((e2) => e2.type === DocumentElementType.ADDTOCART);
|
|
@@ -20311,12 +20347,42 @@ const _sfc_main$18 = /* @__PURE__ */ vue.defineComponent({
|
|
|
20311
20347
|
vue.onMounted(() => {
|
|
20312
20348
|
checkIfIsInStock();
|
|
20313
20349
|
});
|
|
20314
|
-
const processIsInStock = () => {
|
|
20315
|
-
|
|
20316
|
-
|
|
20350
|
+
const processIsInStock = vue.computed(() => {
|
|
20351
|
+
const raw = props.panelOptions.isInStock;
|
|
20352
|
+
if (!raw)
|
|
20353
|
+
return true;
|
|
20354
|
+
const rules = Array.isArray(raw) ? raw : [raw];
|
|
20355
|
+
return rules.every((rule2) => shouldDisplay(rule2, props.item));
|
|
20356
|
+
});
|
|
20317
20357
|
const checkIfIsInStock = () => __async(this, null, function* () {
|
|
20318
|
-
isInStock.value = props.panelOptions.isInStock ? processIsInStock
|
|
20358
|
+
isInStock.value = props.panelOptions.isInStock ? processIsInStock.value : true;
|
|
20319
20359
|
});
|
|
20360
|
+
const imageElements = vue.computed(
|
|
20361
|
+
() => {
|
|
20362
|
+
var _a, _b;
|
|
20363
|
+
return (_b = (_a = props.panelOptions.elements) == null ? void 0 : _a.filter((e2) => e2.type === DocumentElementType.IMAGE && !e2.group)) != null ? _b : [];
|
|
20364
|
+
}
|
|
20365
|
+
);
|
|
20366
|
+
const detailElements = vue.computed(
|
|
20367
|
+
() => {
|
|
20368
|
+
var _a, _b;
|
|
20369
|
+
return (_b = (_a = props.panelOptions.elements) == null ? void 0 : _a.filter(
|
|
20370
|
+
(e2) => e2.type !== DocumentElementType.IMAGE && e2.type !== DocumentElementType.ADDTOCART && !e2.group
|
|
20371
|
+
)) != null ? _b : [];
|
|
20372
|
+
}
|
|
20373
|
+
);
|
|
20374
|
+
const elementGroups = vue.computed(
|
|
20375
|
+
() => {
|
|
20376
|
+
var _a;
|
|
20377
|
+
return Array.from(
|
|
20378
|
+
new Set((_a = props.panelOptions.elements) == null ? void 0 : _a.map((e2) => e2.group).filter((g) => Boolean(g)))
|
|
20379
|
+
);
|
|
20380
|
+
}
|
|
20381
|
+
);
|
|
20382
|
+
function getGroupElements(group) {
|
|
20383
|
+
var _a, _b;
|
|
20384
|
+
return (_b = (_a = props.panelOptions.elements) == null ? void 0 : _a.filter((e2) => e2.group === group)) != null ? _b : [];
|
|
20385
|
+
}
|
|
20320
20386
|
return (_ctx, _cache) => {
|
|
20321
20387
|
return vue.openBlock(), vue.createElementBlock("a", vue.mergeProps({
|
|
20322
20388
|
class: ["lupa-search-box-product", { "lupa-search-box-product-highlighted": _ctx.highlighted }],
|
|
@@ -20332,9 +20398,9 @@ const _sfc_main$18 = /* @__PURE__ */ vue.defineComponent({
|
|
|
20332
20398
|
(vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(imageElements.value, (element) => {
|
|
20333
20399
|
return vue.openBlock(), vue.createBlock(_sfc_main$1g, {
|
|
20334
20400
|
class: "lupa-search-box-product-element",
|
|
20401
|
+
key: element.key,
|
|
20335
20402
|
item: _ctx.item,
|
|
20336
20403
|
element,
|
|
20337
|
-
key: element.key,
|
|
20338
20404
|
labels: _ctx.labels,
|
|
20339
20405
|
link: link.value
|
|
20340
20406
|
}, null, 8, ["item", "element", "labels", "link"]);
|
|
@@ -20344,14 +20410,14 @@ const _sfc_main$18 = /* @__PURE__ */ vue.defineComponent({
|
|
|
20344
20410
|
(vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(detailElements.value, (element) => {
|
|
20345
20411
|
var _a;
|
|
20346
20412
|
return vue.openBlock(), vue.createBlock(_sfc_main$1g, {
|
|
20347
|
-
key: element.key,
|
|
20348
20413
|
class: "lupa-search-box-product-element",
|
|
20414
|
+
key: element.key,
|
|
20349
20415
|
item: _ctx.item,
|
|
20350
20416
|
element,
|
|
20351
20417
|
labels: _ctx.labels,
|
|
20352
20418
|
link: link.value
|
|
20353
20419
|
}, vue.createSlots({ _: 2 }, [
|
|
20354
|
-
|
|
20420
|
+
((_a = badgeOptions.value) == null ? void 0 : _a.anchorElementKey) === element.key ? {
|
|
20355
20421
|
name: "badges",
|
|
20356
20422
|
fn: vue.withCtx(() => [
|
|
20357
20423
|
vue.createVNode(_sfc_main$19, {
|
|
@@ -20364,6 +20430,24 @@ const _sfc_main$18 = /* @__PURE__ */ vue.defineComponent({
|
|
|
20364
20430
|
]), 1032, ["item", "element", "labels", "link"]);
|
|
20365
20431
|
}), 128))
|
|
20366
20432
|
]),
|
|
20433
|
+
(vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(elementGroups.value, (group) => {
|
|
20434
|
+
return vue.openBlock(), vue.createElementBlock("div", {
|
|
20435
|
+
key: group,
|
|
20436
|
+
class: vue.normalizeClass(`lupa-search-box-group-${group}`)
|
|
20437
|
+
}, [
|
|
20438
|
+
(vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(getGroupElements(group), (element) => {
|
|
20439
|
+
return vue.openBlock(), vue.createBlock(_sfc_main$1g, {
|
|
20440
|
+
class: "lupa-search-box-product-element",
|
|
20441
|
+
key: element.key,
|
|
20442
|
+
item: _ctx.item,
|
|
20443
|
+
element,
|
|
20444
|
+
labels: _ctx.labels,
|
|
20445
|
+
link: link.value,
|
|
20446
|
+
isInStock: isInStock.value
|
|
20447
|
+
}, null, 8, ["item", "element", "labels", "link", "isInStock"]);
|
|
20448
|
+
}), 128))
|
|
20449
|
+
], 2);
|
|
20450
|
+
}), 128)),
|
|
20367
20451
|
addToCartElement.value ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_3$z, [
|
|
20368
20452
|
vue.createVNode(_sfc_main$1g, {
|
|
20369
20453
|
class: "lupa-search-box-product-element",
|
|
@@ -21764,8 +21848,8 @@ const _sfc_main$_ = /* @__PURE__ */ vue.defineComponent({
|
|
|
21764
21848
|
const facetKeyClass = vue.computed(() => `lupa-facet-active-filter-${props.filter.key}`);
|
|
21765
21849
|
const { searchResultOptions } = storeToRefs(useOptionsStore());
|
|
21766
21850
|
const units = vue.computed(() => {
|
|
21767
|
-
var _a;
|
|
21768
|
-
return (_a = searchResultOptions.value.filters.facets.stats.units) != null ?
|
|
21851
|
+
var _a, _b, _c, _d, _e;
|
|
21852
|
+
return (_e = (_d = (_c = (_b = (_a = searchResultOptions.value) == null ? void 0 : _a.filters) == null ? void 0 : _b.facets) == null ? void 0 : _c.stats) == null ? void 0 : _d.units) != null ? _e : {};
|
|
21769
21853
|
});
|
|
21770
21854
|
function handleClick() {
|
|
21771
21855
|
emit("remove", { filter: props.filter });
|
|
@@ -25376,14 +25460,9 @@ const _sfc_main$t = /* @__PURE__ */ vue.defineComponent(__spreadProps(__spreadVa
|
|
|
25376
25460
|
const enhancementData = (_d = (_c = dynamicDataIdMap.value) == null ? void 0 : _c[(_b = props.item) == null ? void 0 : _b.id]) != null ? _d : {};
|
|
25377
25461
|
return __spreadValues(__spreadValues({}, props.item), enhancementData);
|
|
25378
25462
|
});
|
|
25379
|
-
const displayElement = vue.computed(
|
|
25380
|
-
|
|
25381
|
-
|
|
25382
|
-
if (!element.display) {
|
|
25383
|
-
return true;
|
|
25384
|
-
}
|
|
25385
|
-
return typeof element.display === "function" ? element.display(item) : processDisplayCondition(element.display, item);
|
|
25386
|
-
});
|
|
25463
|
+
const displayElement = vue.computed(
|
|
25464
|
+
() => shouldDisplay(props.element.display, enhancedItem.value)
|
|
25465
|
+
);
|
|
25387
25466
|
const dynamicAttributes = vue.computed(() => {
|
|
25388
25467
|
return getDynamicAttributes(props.element.dynamicAttributes, enhancedItem.value);
|
|
25389
25468
|
});
|
|
@@ -25511,15 +25590,21 @@ const _sfc_main$s = /* @__PURE__ */ vue.defineComponent({
|
|
|
25511
25590
|
var _a, _b;
|
|
25512
25591
|
return (_b = (_a = props.options.elements) == null ? void 0 : _a.filter((e2) => e2.group === group)) != null ? _b : [];
|
|
25513
25592
|
};
|
|
25514
|
-
const
|
|
25515
|
-
|
|
25593
|
+
const shouldShowInStock = () => {
|
|
25594
|
+
const raw = props.options.isInStock;
|
|
25595
|
+
if (!raw)
|
|
25596
|
+
return true;
|
|
25597
|
+
const rules = Array.isArray(raw) ? raw : [raw];
|
|
25598
|
+
return rules.every(
|
|
25599
|
+
(rule2) => typeof rule2 === "function" ? rule2(props.product) : processDisplayCondition(rule2, props.product)
|
|
25600
|
+
);
|
|
25601
|
+
};
|
|
25602
|
+
const checkIfIsInStock = () => {
|
|
25603
|
+
isInStock.value = shouldShowInStock();
|
|
25516
25604
|
};
|
|
25517
25605
|
vue.onMounted(() => {
|
|
25518
25606
|
checkIfIsInStock();
|
|
25519
25607
|
});
|
|
25520
|
-
const checkIfIsInStock = () => __async(this, null, function* () {
|
|
25521
|
-
isInStock.value = props.options.isInStock ? yield processIsInStock() : true;
|
|
25522
|
-
});
|
|
25523
25608
|
const handleClick = () => {
|
|
25524
25609
|
var _a, _b, _c, _d;
|
|
25525
25610
|
const event = {
|
package/dist/lupaSearch.mjs
CHANGED
|
@@ -7292,7 +7292,7 @@ const getNormalizedString = (str) => {
|
|
|
7292
7292
|
return "";
|
|
7293
7293
|
}
|
|
7294
7294
|
const transformedStr = typeof str === "string" ? str : str.toString();
|
|
7295
|
-
return transformedStr.normalize === void 0 ? (_a = transformedStr.toLocaleLowerCase()) == null ? void 0 : _a.trim() : (_b = transformedStr.toLocaleLowerCase().normalize("NFKD").replace(/[^\
|
|
7295
|
+
return transformedStr.normalize === void 0 ? (_a = transformedStr.toLocaleLowerCase()) == null ? void 0 : _a.trim() : (_b = transformedStr.toLocaleLowerCase().normalize("NFKD").replace(/[^\p{L}\p{N}\s]/gu, "")) == null ? void 0 : _b.trim();
|
|
7296
7296
|
};
|
|
7297
7297
|
const getTransformedString = (str) => {
|
|
7298
7298
|
var _a, _b;
|
|
@@ -9032,8 +9032,8 @@ const Env = {
|
|
|
9032
9032
|
staging: "https://api.staging.lupasearch.com/v1/"
|
|
9033
9033
|
};
|
|
9034
9034
|
const VoiceServiceEnv = {
|
|
9035
|
-
production: "
|
|
9036
|
-
staging: "
|
|
9035
|
+
production: "wss://voice.lupasearch.com",
|
|
9036
|
+
staging: "wss://voice.lupasearch.dev"
|
|
9037
9037
|
};
|
|
9038
9038
|
const DEFAULT_REQUEST_CONFIG = {
|
|
9039
9039
|
method: "POST",
|
|
@@ -9074,7 +9074,7 @@ const _sfc_main$1z = /* @__PURE__ */ defineComponent({
|
|
|
9074
9074
|
}
|
|
9075
9075
|
};
|
|
9076
9076
|
const startProgressBar = () => {
|
|
9077
|
-
if (!progressBar.value
|
|
9077
|
+
if (!progressBar.value) {
|
|
9078
9078
|
return;
|
|
9079
9079
|
}
|
|
9080
9080
|
const duration = props.timesliceLimit * props.timeSliceLength;
|
|
@@ -9132,6 +9132,7 @@ function useVoiceRecorder(options) {
|
|
|
9132
9132
|
const mediaStream = ref(null);
|
|
9133
9133
|
const mediaRecorder = ref(null);
|
|
9134
9134
|
const isRecording = ref(false);
|
|
9135
|
+
const isSocketReady = ref(false);
|
|
9135
9136
|
const errorRef = ref(null);
|
|
9136
9137
|
const transcription = ref("");
|
|
9137
9138
|
const timeSliceLength = computed(() => {
|
|
@@ -9144,35 +9145,51 @@ function useVoiceRecorder(options) {
|
|
|
9144
9145
|
});
|
|
9145
9146
|
const initSocket = (url, onMessage) => {
|
|
9146
9147
|
socket.value = new WebSocket(url);
|
|
9147
|
-
socket.value.
|
|
9148
|
+
socket.value.onmessage = (event) => __async(this, null, function* () {
|
|
9148
9149
|
var _a;
|
|
9149
|
-
|
|
9150
|
-
|
|
9150
|
+
try {
|
|
9151
|
+
const msg = JSON.parse(event.data);
|
|
9152
|
+
if (msg.event === "ready") {
|
|
9153
|
+
if (((_a = mediaRecorder.value) == null ? void 0 : _a.state) !== "recording") {
|
|
9154
|
+
try {
|
|
9155
|
+
isSocketReady.value = true;
|
|
9156
|
+
yield startRecording();
|
|
9157
|
+
} catch (error) {
|
|
9158
|
+
console.error("Recording failed to start:", error);
|
|
9159
|
+
closeSocket();
|
|
9160
|
+
}
|
|
9161
|
+
}
|
|
9162
|
+
} else if (msg.event === "transcription") {
|
|
9163
|
+
transcription.value = msg.transcription;
|
|
9164
|
+
onMessage == null ? void 0 : onMessage(msg.transcription);
|
|
9165
|
+
stopSocketConnection();
|
|
9166
|
+
} else if (msg.event === "error") {
|
|
9167
|
+
errorRef.value = msg.message || "An error occurred during transcription";
|
|
9168
|
+
isSocketReady.value = false;
|
|
9169
|
+
stopRecording();
|
|
9170
|
+
closeSocket();
|
|
9171
|
+
}
|
|
9172
|
+
} catch (error) {
|
|
9173
|
+
console.error("Error processing WebSocket message:", error);
|
|
9151
9174
|
}
|
|
9152
9175
|
});
|
|
9153
|
-
socket.value.
|
|
9154
|
-
|
|
9155
|
-
|
|
9156
|
-
transcription.value = msg.transcription;
|
|
9157
|
-
onMessage == null ? void 0 : onMessage(msg.transcription);
|
|
9158
|
-
stopSocketConnection();
|
|
9159
|
-
} else if (msg.event === "error") {
|
|
9160
|
-
errorRef.value = "Server error during transcription";
|
|
9161
|
-
stopRecording();
|
|
9176
|
+
socket.value.onclose = (event) => {
|
|
9177
|
+
if (event.code === 4001) {
|
|
9178
|
+
errorRef.value = event.reason || "Connection closed by server";
|
|
9162
9179
|
}
|
|
9163
|
-
};
|
|
9164
|
-
socket.value.onclose = () => {
|
|
9165
9180
|
stopRecording();
|
|
9166
9181
|
};
|
|
9167
9182
|
socket.value.onerror = () => {
|
|
9168
|
-
stopRecording();
|
|
9169
9183
|
errorRef.value = "Service connection error";
|
|
9184
|
+
stopRecording();
|
|
9170
9185
|
};
|
|
9171
9186
|
};
|
|
9172
9187
|
const onMediaRecorderDataAvailable = (event) => __async(this, null, function* () {
|
|
9173
9188
|
var _a, _b;
|
|
9174
|
-
if (((_a =
|
|
9189
|
+
if (!isSocketReady.value || ((_a = socket.value) == null ? void 0 : _a.readyState) !== WebSocket.OPEN) {
|
|
9190
|
+
console.warn("Skipping audio chunk: socket not ready.");
|
|
9175
9191
|
return;
|
|
9192
|
+
}
|
|
9176
9193
|
const audioBuffer = yield event.data.arrayBuffer();
|
|
9177
9194
|
const header = buildSocketMessageFrameHeader("audio-chunk", audioBuffer.byteLength);
|
|
9178
9195
|
const buffer = new Uint8Array(header.length + audioBuffer.byteLength);
|
|
@@ -9181,20 +9198,29 @@ function useVoiceRecorder(options) {
|
|
|
9181
9198
|
(_b = socket.value) == null ? void 0 : _b.send(buffer);
|
|
9182
9199
|
});
|
|
9183
9200
|
const startRecording = () => __async(this, null, function* () {
|
|
9184
|
-
|
|
9185
|
-
|
|
9186
|
-
|
|
9187
|
-
|
|
9188
|
-
|
|
9189
|
-
|
|
9201
|
+
var _a, _b;
|
|
9202
|
+
try {
|
|
9203
|
+
mediaStream.value = yield navigator.mediaDevices.getUserMedia({
|
|
9204
|
+
video: false,
|
|
9205
|
+
audio: {
|
|
9206
|
+
channelCount: 1,
|
|
9207
|
+
echoCancellation: true,
|
|
9208
|
+
sampleRate: options.sampleRate || 16e3
|
|
9209
|
+
}
|
|
9210
|
+
});
|
|
9211
|
+
mediaRecorder.value = new MediaRecorder(mediaStream.value, {
|
|
9212
|
+
mimeType: "audio/webm; codecs=opus"
|
|
9213
|
+
});
|
|
9214
|
+
mediaRecorder.value.ondataavailable = onMediaRecorderDataAvailable;
|
|
9215
|
+
mediaRecorder.value.start(timeSliceLength.value);
|
|
9216
|
+
isRecording.value = true;
|
|
9217
|
+
} catch (error) {
|
|
9218
|
+
if (error.name === "NotAllowedError") {
|
|
9219
|
+
errorRef.value = ((_a = options.labels) == null ? void 0 : _a.microphoneNotAllowed) || "Microphone access denied. Please allow microphone access in your browser settings.";
|
|
9220
|
+
} else if (error.name === "NotFoundError") {
|
|
9221
|
+
errorRef.value = ((_b = options.labels) == null ? void 0 : _b.microphoneNotFound) || "No microphone found. Please connect a microphone and try again.";
|
|
9190
9222
|
}
|
|
9191
|
-
}
|
|
9192
|
-
mediaRecorder.value = new MediaRecorder(mediaStream.value, {
|
|
9193
|
-
mimeType: "audio/webm; codecs=opus"
|
|
9194
|
-
});
|
|
9195
|
-
mediaRecorder.value.ondataavailable = onMediaRecorderDataAvailable;
|
|
9196
|
-
mediaRecorder.value.start(timeSliceLength.value);
|
|
9197
|
-
isRecording.value = true;
|
|
9223
|
+
}
|
|
9198
9224
|
});
|
|
9199
9225
|
const stopRecording = () => {
|
|
9200
9226
|
var _a, _b;
|
|
@@ -9217,6 +9243,7 @@ function useVoiceRecorder(options) {
|
|
|
9217
9243
|
var _a;
|
|
9218
9244
|
(_a = socket.value) == null ? void 0 : _a.close();
|
|
9219
9245
|
socket.value = null;
|
|
9246
|
+
isSocketReady.value = false;
|
|
9220
9247
|
};
|
|
9221
9248
|
const reset = () => {
|
|
9222
9249
|
stopRecording();
|
|
@@ -9224,9 +9251,11 @@ function useVoiceRecorder(options) {
|
|
|
9224
9251
|
transcription.value = "";
|
|
9225
9252
|
errorRef.value = null;
|
|
9226
9253
|
isRecording.value = false;
|
|
9254
|
+
isSocketReady.value = false;
|
|
9227
9255
|
};
|
|
9228
9256
|
return {
|
|
9229
9257
|
isRecording,
|
|
9258
|
+
isSocketReady,
|
|
9230
9259
|
transcription,
|
|
9231
9260
|
errorRef,
|
|
9232
9261
|
initSocket,
|
|
@@ -9260,6 +9289,7 @@ const _sfc_main$1y = /* @__PURE__ */ defineComponent({
|
|
|
9260
9289
|
const optionsStore = useOptionsStore();
|
|
9261
9290
|
const {
|
|
9262
9291
|
isRecording,
|
|
9292
|
+
isSocketReady,
|
|
9263
9293
|
transcription,
|
|
9264
9294
|
errorRef,
|
|
9265
9295
|
initSocket,
|
|
@@ -9285,20 +9315,28 @@ const _sfc_main$1y = /* @__PURE__ */ defineComponent({
|
|
|
9285
9315
|
return (_a = props.options.labels) != null ? _a : {};
|
|
9286
9316
|
});
|
|
9287
9317
|
const description = computed(() => {
|
|
9288
|
-
var _a, _b
|
|
9318
|
+
var _a, _b;
|
|
9289
9319
|
if (errorRef.value) {
|
|
9290
|
-
return
|
|
9320
|
+
return errorRef.value;
|
|
9291
9321
|
}
|
|
9292
|
-
if (!isRecording.value) {
|
|
9293
|
-
return (
|
|
9322
|
+
if (!isSocketReady.value || !isRecording.value) {
|
|
9323
|
+
return (_a = labels.value.connecting) != null ? _a : "Connecting...";
|
|
9294
9324
|
}
|
|
9295
|
-
return (
|
|
9325
|
+
return (_b = labels.value.listening) != null ? _b : "Listening...";
|
|
9296
9326
|
});
|
|
9297
9327
|
watch(transcription, (newValue) => {
|
|
9298
9328
|
emit("transcript-update", newValue);
|
|
9299
9329
|
});
|
|
9300
|
-
|
|
9330
|
+
watch(isRecording, (newVal) => {
|
|
9301
9331
|
var _a, _b;
|
|
9332
|
+
if (newVal === true) {
|
|
9333
|
+
(_a = voiceSearchProgressBar.value) == null ? void 0 : _a.startProgressBar();
|
|
9334
|
+
} else {
|
|
9335
|
+
(_b = voiceSearchProgressBar.value) == null ? void 0 : _b.stopProgressBar();
|
|
9336
|
+
}
|
|
9337
|
+
});
|
|
9338
|
+
const handleRecordingButtonClick = () => {
|
|
9339
|
+
var _a;
|
|
9302
9340
|
if (isRecording.value) {
|
|
9303
9341
|
setTimeout(() => {
|
|
9304
9342
|
stopSocketConnection();
|
|
@@ -9312,7 +9350,6 @@ const _sfc_main$1y = /* @__PURE__ */ defineComponent({
|
|
|
9312
9350
|
);
|
|
9313
9351
|
const socketUrl = `${voiceServiceUrl}?clientId=${clientId.value}&queryKey=${props.options.queryKey}&languageCode=${(_a = props.options.language) != null ? _a : "en-US"}&connectionType=write-first`;
|
|
9314
9352
|
initSocket(socketUrl);
|
|
9315
|
-
(_b = voiceSearchProgressBar.value) == null ? void 0 : _b.startProgressBar();
|
|
9316
9353
|
setTimeout(() => {
|
|
9317
9354
|
stopSocketConnection();
|
|
9318
9355
|
handleOnStopEvent();
|
|
@@ -19045,6 +19082,15 @@ const processDisplayCondition = (displayCondition, doc = {}) => {
|
|
|
19045
19082
|
return false;
|
|
19046
19083
|
}
|
|
19047
19084
|
};
|
|
19085
|
+
function shouldDisplay(displayOpt, doc) {
|
|
19086
|
+
if (!displayOpt)
|
|
19087
|
+
return true;
|
|
19088
|
+
if (typeof displayOpt === "function") {
|
|
19089
|
+
return displayOpt(doc);
|
|
19090
|
+
}
|
|
19091
|
+
const rules = Array.isArray(displayOpt) ? displayOpt : [displayOpt];
|
|
19092
|
+
return rules.every((rule2) => processDisplayCondition(rule2, doc));
|
|
19093
|
+
}
|
|
19048
19094
|
const checkHasFullImageUrl = (imageUrl) => typeof imageUrl === "string" && (imageUrl.indexOf("http://") === 0 || imageUrl.indexOf("https://") === 0);
|
|
19049
19095
|
const computeImageUrl = (imageUrl, rootImageUrl) => {
|
|
19050
19096
|
const mainUrl = Array.isArray(imageUrl) ? imageUrl[0] : imageUrl;
|
|
@@ -19861,7 +19907,7 @@ const _sfc_main$1g = /* @__PURE__ */ defineComponent(__spreadProps(__spreadValue
|
|
|
19861
19907
|
if (!element.display) {
|
|
19862
19908
|
return true;
|
|
19863
19909
|
}
|
|
19864
|
-
return
|
|
19910
|
+
return shouldDisplay(element.display, item);
|
|
19865
19911
|
});
|
|
19866
19912
|
const enhancedItem = computed(() => {
|
|
19867
19913
|
var _a, _b, _c, _d;
|
|
@@ -20184,7 +20230,7 @@ const _sfc_main$19 = /* @__PURE__ */ defineComponent(__spreadProps(__spreadValue
|
|
|
20184
20230
|
if (!element.display) {
|
|
20185
20231
|
return true;
|
|
20186
20232
|
}
|
|
20187
|
-
return
|
|
20233
|
+
return shouldDisplay(element.display, item);
|
|
20188
20234
|
};
|
|
20189
20235
|
const badges = computed(() => {
|
|
20190
20236
|
if (!props.options.elements) {
|
|
@@ -20262,10 +20308,6 @@ const _sfc_main$18 = /* @__PURE__ */ defineComponent({
|
|
|
20262
20308
|
const badgeOptions = computed(() => {
|
|
20263
20309
|
return __spreadProps(__spreadValues({}, props.panelOptions.badges), { product: props.item });
|
|
20264
20310
|
});
|
|
20265
|
-
const imageElements = computed(() => {
|
|
20266
|
-
var _a, _b;
|
|
20267
|
-
return (_b = (_a = props.panelOptions.elements) == null ? void 0 : _a.filter((e2) => e2.type === DocumentElementType.IMAGE)) != null ? _b : [];
|
|
20268
|
-
});
|
|
20269
20311
|
const mainImageElement = computed(() => {
|
|
20270
20312
|
return imageElements.value[0];
|
|
20271
20313
|
});
|
|
@@ -20285,12 +20327,6 @@ const _sfc_main$18 = /* @__PURE__ */ defineComponent({
|
|
|
20285
20327
|
minWidth: widthOverride.value ? `${widthOverride.value + 10}px` : void 0
|
|
20286
20328
|
} : {};
|
|
20287
20329
|
});
|
|
20288
|
-
const detailElements = computed(() => {
|
|
20289
|
-
var _a, _b;
|
|
20290
|
-
return (_b = (_a = props.panelOptions.elements) == null ? void 0 : _a.filter(
|
|
20291
|
-
(e2) => e2.type !== DocumentElementType.IMAGE && e2.type !== DocumentElementType.ADDTOCART
|
|
20292
|
-
)) != null ? _b : [];
|
|
20293
|
-
});
|
|
20294
20330
|
const addToCartElement = computed(() => {
|
|
20295
20331
|
var _a;
|
|
20296
20332
|
return (_a = props.panelOptions.elements) == null ? void 0 : _a.find((e2) => e2.type === DocumentElementType.ADDTOCART);
|
|
@@ -20309,12 +20345,42 @@ const _sfc_main$18 = /* @__PURE__ */ defineComponent({
|
|
|
20309
20345
|
onMounted(() => {
|
|
20310
20346
|
checkIfIsInStock();
|
|
20311
20347
|
});
|
|
20312
|
-
const processIsInStock = () => {
|
|
20313
|
-
|
|
20314
|
-
|
|
20348
|
+
const processIsInStock = computed(() => {
|
|
20349
|
+
const raw = props.panelOptions.isInStock;
|
|
20350
|
+
if (!raw)
|
|
20351
|
+
return true;
|
|
20352
|
+
const rules = Array.isArray(raw) ? raw : [raw];
|
|
20353
|
+
return rules.every((rule2) => shouldDisplay(rule2, props.item));
|
|
20354
|
+
});
|
|
20315
20355
|
const checkIfIsInStock = () => __async(this, null, function* () {
|
|
20316
|
-
isInStock.value = props.panelOptions.isInStock ? processIsInStock
|
|
20356
|
+
isInStock.value = props.panelOptions.isInStock ? processIsInStock.value : true;
|
|
20317
20357
|
});
|
|
20358
|
+
const imageElements = computed(
|
|
20359
|
+
() => {
|
|
20360
|
+
var _a, _b;
|
|
20361
|
+
return (_b = (_a = props.panelOptions.elements) == null ? void 0 : _a.filter((e2) => e2.type === DocumentElementType.IMAGE && !e2.group)) != null ? _b : [];
|
|
20362
|
+
}
|
|
20363
|
+
);
|
|
20364
|
+
const detailElements = computed(
|
|
20365
|
+
() => {
|
|
20366
|
+
var _a, _b;
|
|
20367
|
+
return (_b = (_a = props.panelOptions.elements) == null ? void 0 : _a.filter(
|
|
20368
|
+
(e2) => e2.type !== DocumentElementType.IMAGE && e2.type !== DocumentElementType.ADDTOCART && !e2.group
|
|
20369
|
+
)) != null ? _b : [];
|
|
20370
|
+
}
|
|
20371
|
+
);
|
|
20372
|
+
const elementGroups = computed(
|
|
20373
|
+
() => {
|
|
20374
|
+
var _a;
|
|
20375
|
+
return Array.from(
|
|
20376
|
+
new Set((_a = props.panelOptions.elements) == null ? void 0 : _a.map((e2) => e2.group).filter((g) => Boolean(g)))
|
|
20377
|
+
);
|
|
20378
|
+
}
|
|
20379
|
+
);
|
|
20380
|
+
function getGroupElements(group) {
|
|
20381
|
+
var _a, _b;
|
|
20382
|
+
return (_b = (_a = props.panelOptions.elements) == null ? void 0 : _a.filter((e2) => e2.group === group)) != null ? _b : [];
|
|
20383
|
+
}
|
|
20318
20384
|
return (_ctx, _cache) => {
|
|
20319
20385
|
return openBlock(), createElementBlock("a", mergeProps({
|
|
20320
20386
|
class: ["lupa-search-box-product", { "lupa-search-box-product-highlighted": _ctx.highlighted }],
|
|
@@ -20330,9 +20396,9 @@ const _sfc_main$18 = /* @__PURE__ */ defineComponent({
|
|
|
20330
20396
|
(openBlock(true), createElementBlock(Fragment, null, renderList(imageElements.value, (element) => {
|
|
20331
20397
|
return openBlock(), createBlock(_sfc_main$1g, {
|
|
20332
20398
|
class: "lupa-search-box-product-element",
|
|
20399
|
+
key: element.key,
|
|
20333
20400
|
item: _ctx.item,
|
|
20334
20401
|
element,
|
|
20335
|
-
key: element.key,
|
|
20336
20402
|
labels: _ctx.labels,
|
|
20337
20403
|
link: link.value
|
|
20338
20404
|
}, null, 8, ["item", "element", "labels", "link"]);
|
|
@@ -20342,14 +20408,14 @@ const _sfc_main$18 = /* @__PURE__ */ defineComponent({
|
|
|
20342
20408
|
(openBlock(true), createElementBlock(Fragment, null, renderList(detailElements.value, (element) => {
|
|
20343
20409
|
var _a;
|
|
20344
20410
|
return openBlock(), createBlock(_sfc_main$1g, {
|
|
20345
|
-
key: element.key,
|
|
20346
20411
|
class: "lupa-search-box-product-element",
|
|
20412
|
+
key: element.key,
|
|
20347
20413
|
item: _ctx.item,
|
|
20348
20414
|
element,
|
|
20349
20415
|
labels: _ctx.labels,
|
|
20350
20416
|
link: link.value
|
|
20351
20417
|
}, createSlots({ _: 2 }, [
|
|
20352
|
-
|
|
20418
|
+
((_a = badgeOptions.value) == null ? void 0 : _a.anchorElementKey) === element.key ? {
|
|
20353
20419
|
name: "badges",
|
|
20354
20420
|
fn: withCtx(() => [
|
|
20355
20421
|
createVNode(_sfc_main$19, {
|
|
@@ -20362,6 +20428,24 @@ const _sfc_main$18 = /* @__PURE__ */ defineComponent({
|
|
|
20362
20428
|
]), 1032, ["item", "element", "labels", "link"]);
|
|
20363
20429
|
}), 128))
|
|
20364
20430
|
]),
|
|
20431
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(elementGroups.value, (group) => {
|
|
20432
|
+
return openBlock(), createElementBlock("div", {
|
|
20433
|
+
key: group,
|
|
20434
|
+
class: normalizeClass(`lupa-search-box-group-${group}`)
|
|
20435
|
+
}, [
|
|
20436
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(getGroupElements(group), (element) => {
|
|
20437
|
+
return openBlock(), createBlock(_sfc_main$1g, {
|
|
20438
|
+
class: "lupa-search-box-product-element",
|
|
20439
|
+
key: element.key,
|
|
20440
|
+
item: _ctx.item,
|
|
20441
|
+
element,
|
|
20442
|
+
labels: _ctx.labels,
|
|
20443
|
+
link: link.value,
|
|
20444
|
+
isInStock: isInStock.value
|
|
20445
|
+
}, null, 8, ["item", "element", "labels", "link", "isInStock"]);
|
|
20446
|
+
}), 128))
|
|
20447
|
+
], 2);
|
|
20448
|
+
}), 128)),
|
|
20365
20449
|
addToCartElement.value ? (openBlock(), createElementBlock("div", _hoisted_3$z, [
|
|
20366
20450
|
createVNode(_sfc_main$1g, {
|
|
20367
20451
|
class: "lupa-search-box-product-element",
|
|
@@ -21762,8 +21846,8 @@ const _sfc_main$_ = /* @__PURE__ */ defineComponent({
|
|
|
21762
21846
|
const facetKeyClass = computed(() => `lupa-facet-active-filter-${props.filter.key}`);
|
|
21763
21847
|
const { searchResultOptions } = storeToRefs(useOptionsStore());
|
|
21764
21848
|
const units = computed(() => {
|
|
21765
|
-
var _a;
|
|
21766
|
-
return (_a = searchResultOptions.value.filters.facets.stats.units) != null ?
|
|
21849
|
+
var _a, _b, _c, _d, _e;
|
|
21850
|
+
return (_e = (_d = (_c = (_b = (_a = searchResultOptions.value) == null ? void 0 : _a.filters) == null ? void 0 : _b.facets) == null ? void 0 : _c.stats) == null ? void 0 : _d.units) != null ? _e : {};
|
|
21767
21851
|
});
|
|
21768
21852
|
function handleClick() {
|
|
21769
21853
|
emit("remove", { filter: props.filter });
|
|
@@ -25374,14 +25458,9 @@ const _sfc_main$t = /* @__PURE__ */ defineComponent(__spreadProps(__spreadValues
|
|
|
25374
25458
|
const enhancementData = (_d = (_c = dynamicDataIdMap.value) == null ? void 0 : _c[(_b = props.item) == null ? void 0 : _b.id]) != null ? _d : {};
|
|
25375
25459
|
return __spreadValues(__spreadValues({}, props.item), enhancementData);
|
|
25376
25460
|
});
|
|
25377
|
-
const displayElement = computed(
|
|
25378
|
-
|
|
25379
|
-
|
|
25380
|
-
if (!element.display) {
|
|
25381
|
-
return true;
|
|
25382
|
-
}
|
|
25383
|
-
return typeof element.display === "function" ? element.display(item) : processDisplayCondition(element.display, item);
|
|
25384
|
-
});
|
|
25461
|
+
const displayElement = computed(
|
|
25462
|
+
() => shouldDisplay(props.element.display, enhancedItem.value)
|
|
25463
|
+
);
|
|
25385
25464
|
const dynamicAttributes = computed(() => {
|
|
25386
25465
|
return getDynamicAttributes(props.element.dynamicAttributes, enhancedItem.value);
|
|
25387
25466
|
});
|
|
@@ -25509,15 +25588,21 @@ const _sfc_main$s = /* @__PURE__ */ defineComponent({
|
|
|
25509
25588
|
var _a, _b;
|
|
25510
25589
|
return (_b = (_a = props.options.elements) == null ? void 0 : _a.filter((e2) => e2.group === group)) != null ? _b : [];
|
|
25511
25590
|
};
|
|
25512
|
-
const
|
|
25513
|
-
|
|
25591
|
+
const shouldShowInStock = () => {
|
|
25592
|
+
const raw = props.options.isInStock;
|
|
25593
|
+
if (!raw)
|
|
25594
|
+
return true;
|
|
25595
|
+
const rules = Array.isArray(raw) ? raw : [raw];
|
|
25596
|
+
return rules.every(
|
|
25597
|
+
(rule2) => typeof rule2 === "function" ? rule2(props.product) : processDisplayCondition(rule2, props.product)
|
|
25598
|
+
);
|
|
25599
|
+
};
|
|
25600
|
+
const checkIfIsInStock = () => {
|
|
25601
|
+
isInStock.value = shouldShowInStock();
|
|
25514
25602
|
};
|
|
25515
25603
|
onMounted(() => {
|
|
25516
25604
|
checkIfIsInStock();
|
|
25517
25605
|
});
|
|
25518
|
-
const checkIfIsInStock = () => __async(this, null, function* () {
|
|
25519
|
-
isInStock.value = props.options.isInStock ? yield processIsInStock() : true;
|
|
25520
|
-
});
|
|
25521
25606
|
const handleClick = () => {
|
|
25522
25607
|
var _a, _b, _c, _d;
|
|
25523
25608
|
const event = {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { VoiceSearchOptions } from '../types/search-box/SearchBoxOptions';
|
|
2
2
|
export declare function useVoiceRecorder(options: VoiceSearchOptions): {
|
|
3
3
|
isRecording: import("vue").Ref<boolean>;
|
|
4
|
+
isSocketReady: import("vue").Ref<boolean>;
|
|
4
5
|
transcription: import("vue").Ref<string>;
|
|
5
6
|
errorRef: import("vue").Ref<string>;
|
|
6
7
|
initSocket: (url: string, onMessage?: (transcription: string) => void) => void;
|
|
@@ -10,6 +10,7 @@ export declare enum DocumentElementType {
|
|
|
10
10
|
ADDTOCART = "addToCart",
|
|
11
11
|
CUSTOM_HTML = "customHtml"
|
|
12
12
|
}
|
|
13
|
+
export type DisplayOption<T = any> = DisplayCondition | DisplayCondition[] | ((document: T) => boolean);
|
|
13
14
|
export type DisplayCondition = {
|
|
14
15
|
condition: 'exists' | 'notExists' | 'equals' | 'notEquals' | 'greaterThan' | 'lessThan' | 'greaterThanOrEquals' | 'lessThanOrEquals';
|
|
15
16
|
fields: (string | number)[];
|
|
@@ -21,7 +22,7 @@ export type DynamicAttribute = {
|
|
|
21
22
|
export type DocumentElementBase<T = any> = {
|
|
22
23
|
type: DocumentElementType;
|
|
23
24
|
key?: string;
|
|
24
|
-
display?:
|
|
25
|
+
display?: DisplayOption<T>;
|
|
25
26
|
isHtml?: boolean;
|
|
26
27
|
group?: string;
|
|
27
28
|
dynamic?: boolean;
|
|
@@ -36,8 +36,10 @@ export type SearchBoxOptionLinks = {
|
|
|
36
36
|
};
|
|
37
37
|
export type VoiceSearchLabels = {
|
|
38
38
|
listening?: string;
|
|
39
|
-
microphoneOff?: string;
|
|
40
39
|
serviceError?: string;
|
|
40
|
+
connecting?: string;
|
|
41
|
+
microphoneNotFound?: string;
|
|
42
|
+
microphoneNotAllowed?: string;
|
|
41
43
|
};
|
|
42
44
|
export type VoiceSearchOptions = {
|
|
43
45
|
enabled: boolean;
|
|
@@ -45,6 +47,7 @@ export type VoiceSearchOptions = {
|
|
|
45
47
|
stopDelay?: number;
|
|
46
48
|
timesliceLimit?: number;
|
|
47
49
|
timesliceLength?: number;
|
|
50
|
+
sampleRate?: number;
|
|
48
51
|
labels?: VoiceSearchLabels;
|
|
49
52
|
language?: string;
|
|
50
53
|
customVoiceServiceUrl?: string;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { DisplayCondition, DynamicAttribute } from '../types/DocumentElement';
|
|
1
|
+
import { DisplayCondition, DynamicAttribute, DisplayOption } from '../types/DocumentElement';
|
|
2
2
|
export declare const renderHtmlTemplate: (template: string, document?: Record<string, unknown>) => string;
|
|
3
3
|
export declare const getDynamicAttributes: (dynamicAttributes?: DynamicAttribute[], document?: Record<string, unknown>) => {};
|
|
4
4
|
export declare const processDisplayCondition: (displayCondition: DisplayCondition, doc?: Record<string, unknown>) => boolean;
|
|
5
|
+
export declare function shouldDisplay<T = any>(displayOpt: DisplayOption<T> | undefined, doc: Record<string, unknown>): boolean;
|