@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.
@@ -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(/[^\w\s.-_/]/g, "")) == null ? void 0 : _b.trim();
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: "ws://voice.lupasearch.com:3001",
9038
- staging: "ws://voice.lupasearch.dev:3001"
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 || !props.isRecording) {
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.onopen = () => __async(this, null, function* () {
9150
+ socket.value.onmessage = (event) => __async(this, null, function* () {
9150
9151
  var _a;
9151
- if (((_a = mediaRecorder.value) == null ? void 0 : _a.state) !== "recording") {
9152
- yield startRecording();
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.onmessage = (event) => {
9156
- const msg = JSON.parse(event.data);
9157
- if (msg.event === "transcription") {
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 = mediaRecorder.value) == null ? void 0 : _a.state) !== "recording")
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
- mediaStream.value = yield navigator.mediaDevices.getUserMedia({
9187
- video: false,
9188
- audio: {
9189
- channelCount: 1,
9190
- echoCancellation: true,
9191
- sampleRate: 16e3
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, _c;
9320
+ var _a, _b;
9291
9321
  if (errorRef.value) {
9292
- return (_a = labels.value.serviceError) != null ? _a : errorRef.value;
9322
+ return errorRef.value;
9293
9323
  }
9294
- if (!isRecording.value) {
9295
- return (_b = labels.value.microphoneOff) != null ? _b : "Microphone is off. Try again.";
9324
+ if (!isSocketReady.value || !isRecording.value) {
9325
+ return (_a = labels.value.connecting) != null ? _a : "Connecting...";
9296
9326
  }
9297
- return (_c = labels.value.listening) != null ? _c : "Listening...";
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
- const handleRecordingButtonClick = () => {
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 typeof element.display === "function" ? element.display(item) : processDisplayCondition(element.display, item);
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 typeof element.display === "function" ? element.display(item) : processDisplayCondition(element.display, item);
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
- return typeof props.panelOptions.isInStock === "function" ? props.panelOptions.isInStock(props.item) : processDisplayCondition(props.panelOptions.isInStock, props.item);
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() : true;
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
- badgeOptions.value && ((_a = badgeOptions.value) == null ? void 0 : _a.anchorElementKey) === element.key ? {
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 ? _a : {};
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
- const element = props.element;
25381
- const item = enhancedItem.value;
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 processIsInStock = () => {
25515
- return typeof props.options.isInStock === "function" ? props.options.isInStock(props.product) : processDisplayCondition(props.options.isInStock, props.product);
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 = {
@@ -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(/[^\w\s.-_/]/g, "")) == null ? void 0 : _b.trim();
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: "ws://voice.lupasearch.com:3001",
9036
- staging: "ws://voice.lupasearch.dev:3001"
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 || !props.isRecording) {
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.onopen = () => __async(this, null, function* () {
9148
+ socket.value.onmessage = (event) => __async(this, null, function* () {
9148
9149
  var _a;
9149
- if (((_a = mediaRecorder.value) == null ? void 0 : _a.state) !== "recording") {
9150
- yield startRecording();
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.onmessage = (event) => {
9154
- const msg = JSON.parse(event.data);
9155
- if (msg.event === "transcription") {
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 = mediaRecorder.value) == null ? void 0 : _a.state) !== "recording")
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
- mediaStream.value = yield navigator.mediaDevices.getUserMedia({
9185
- video: false,
9186
- audio: {
9187
- channelCount: 1,
9188
- echoCancellation: true,
9189
- sampleRate: 16e3
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, _c;
9318
+ var _a, _b;
9289
9319
  if (errorRef.value) {
9290
- return (_a = labels.value.serviceError) != null ? _a : errorRef.value;
9320
+ return errorRef.value;
9291
9321
  }
9292
- if (!isRecording.value) {
9293
- return (_b = labels.value.microphoneOff) != null ? _b : "Microphone is off. Try again.";
9322
+ if (!isSocketReady.value || !isRecording.value) {
9323
+ return (_a = labels.value.connecting) != null ? _a : "Connecting...";
9294
9324
  }
9295
- return (_c = labels.value.listening) != null ? _c : "Listening...";
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
- const handleRecordingButtonClick = () => {
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 typeof element.display === "function" ? element.display(item) : processDisplayCondition(element.display, item);
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 typeof element.display === "function" ? element.display(item) : processDisplayCondition(element.display, item);
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
- return typeof props.panelOptions.isInStock === "function" ? props.panelOptions.isInStock(props.item) : processDisplayCondition(props.panelOptions.isInStock, props.item);
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() : true;
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
- badgeOptions.value && ((_a = badgeOptions.value) == null ? void 0 : _a.anchorElementKey) === element.key ? {
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 ? _a : {};
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
- const element = props.element;
25379
- const item = enhancedItem.value;
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 processIsInStock = () => {
25513
- return typeof props.options.isInStock === "function" ? props.options.isInStock(props.product) : processDisplayCondition(props.options.isInStock, props.product);
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?: DisplayCondition | ((document: T) => boolean);
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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getlupa/vue",
3
- "version": "0.18.4",
3
+ "version": "0.19.0",
4
4
  "main": "dist/lupaSearch.mjs",
5
5
  "module": "dist/lupaSearch.mjs",
6
6
  "types": "dist/src/index.d.ts",