@getlupa/client 1.18.5 → 1.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.
@@ -12590,7 +12590,7 @@ var __async = (__this, __arguments, generator) => {
12590
12590
  return "";
12591
12591
  }
12592
12592
  const transformedStr = typeof str === "string" ? str : str.toString();
12593
- 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();
12593
+ 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();
12594
12594
  };
12595
12595
  const getTransformedString = (str) => {
12596
12596
  var _a, _b;
@@ -14330,8 +14330,8 @@ var __async = (__this, __arguments, generator) => {
14330
14330
  staging: "https://api.staging.lupasearch.com/v1/"
14331
14331
  };
14332
14332
  const VoiceServiceEnv = {
14333
- production: "ws://voice.lupasearch.com:3001",
14334
- staging: "ws://voice.lupasearch.dev:3001"
14333
+ production: "wss://voice.lupasearch.com",
14334
+ staging: "wss://voice.lupasearch.dev"
14335
14335
  };
14336
14336
  const DEFAULT_REQUEST_CONFIG = {
14337
14337
  method: "POST",
@@ -14372,7 +14372,7 @@ var __async = (__this, __arguments, generator) => {
14372
14372
  }
14373
14373
  };
14374
14374
  const startProgressBar = () => {
14375
- if (!progressBar.value || !props.isRecording) {
14375
+ if (!progressBar.value) {
14376
14376
  return;
14377
14377
  }
14378
14378
  const duration = props.timesliceLimit * props.timeSliceLength;
@@ -14430,6 +14430,7 @@ var __async = (__this, __arguments, generator) => {
14430
14430
  const mediaStream = ref(null);
14431
14431
  const mediaRecorder = ref(null);
14432
14432
  const isRecording = ref(false);
14433
+ const isSocketReady = ref(false);
14433
14434
  const errorRef = ref(null);
14434
14435
  const transcription = ref("");
14435
14436
  const timeSliceLength = computed(() => {
@@ -14442,35 +14443,51 @@ var __async = (__this, __arguments, generator) => {
14442
14443
  });
14443
14444
  const initSocket = (url, onMessage) => {
14444
14445
  socket.value = new WebSocket(url);
14445
- socket.value.onopen = () => __async2(this, null, function* () {
14446
+ socket.value.onmessage = (event) => __async2(this, null, function* () {
14446
14447
  var _a;
14447
- if (((_a = mediaRecorder.value) == null ? void 0 : _a.state) !== "recording") {
14448
- yield startRecording();
14448
+ try {
14449
+ const msg = JSON.parse(event.data);
14450
+ if (msg.event === "ready") {
14451
+ if (((_a = mediaRecorder.value) == null ? void 0 : _a.state) !== "recording") {
14452
+ try {
14453
+ isSocketReady.value = true;
14454
+ yield startRecording();
14455
+ } catch (error) {
14456
+ console.error("Recording failed to start:", error);
14457
+ closeSocket();
14458
+ }
14459
+ }
14460
+ } else if (msg.event === "transcription") {
14461
+ transcription.value = msg.transcription;
14462
+ onMessage == null ? void 0 : onMessage(msg.transcription);
14463
+ stopSocketConnection();
14464
+ } else if (msg.event === "error") {
14465
+ errorRef.value = msg.message || "An error occurred during transcription";
14466
+ isSocketReady.value = false;
14467
+ stopRecording();
14468
+ closeSocket();
14469
+ }
14470
+ } catch (error) {
14471
+ console.error("Error processing WebSocket message:", error);
14449
14472
  }
14450
14473
  });
14451
- socket.value.onmessage = (event) => {
14452
- const msg = JSON.parse(event.data);
14453
- if (msg.event === "transcription") {
14454
- transcription.value = msg.transcription;
14455
- onMessage == null ? void 0 : onMessage(msg.transcription);
14456
- stopSocketConnection();
14457
- } else if (msg.event === "error") {
14458
- errorRef.value = "Server error during transcription";
14459
- stopRecording();
14474
+ socket.value.onclose = (event) => {
14475
+ if (event.code === 4001) {
14476
+ errorRef.value = event.reason || "Connection closed by server";
14460
14477
  }
14461
- };
14462
- socket.value.onclose = () => {
14463
14478
  stopRecording();
14464
14479
  };
14465
14480
  socket.value.onerror = () => {
14466
- stopRecording();
14467
14481
  errorRef.value = "Service connection error";
14482
+ stopRecording();
14468
14483
  };
14469
14484
  };
14470
14485
  const onMediaRecorderDataAvailable = (event) => __async2(this, null, function* () {
14471
14486
  var _a, _b;
14472
- if (((_a = mediaRecorder.value) == null ? void 0 : _a.state) !== "recording")
14487
+ if (!isSocketReady.value || ((_a = socket.value) == null ? void 0 : _a.readyState) !== WebSocket.OPEN) {
14488
+ console.warn("Skipping audio chunk: socket not ready.");
14473
14489
  return;
14490
+ }
14474
14491
  const audioBuffer = yield event.data.arrayBuffer();
14475
14492
  const header = buildSocketMessageFrameHeader("audio-chunk", audioBuffer.byteLength);
14476
14493
  const buffer = new Uint8Array(header.length + audioBuffer.byteLength);
@@ -14479,20 +14496,29 @@ var __async = (__this, __arguments, generator) => {
14479
14496
  (_b = socket.value) == null ? void 0 : _b.send(buffer);
14480
14497
  });
14481
14498
  const startRecording = () => __async2(this, null, function* () {
14482
- mediaStream.value = yield navigator.mediaDevices.getUserMedia({
14483
- video: false,
14484
- audio: {
14485
- channelCount: 1,
14486
- echoCancellation: true,
14487
- sampleRate: 16e3
14499
+ var _a, _b;
14500
+ try {
14501
+ mediaStream.value = yield navigator.mediaDevices.getUserMedia({
14502
+ video: false,
14503
+ audio: {
14504
+ channelCount: 1,
14505
+ echoCancellation: true,
14506
+ sampleRate: options.sampleRate || 16e3
14507
+ }
14508
+ });
14509
+ mediaRecorder.value = new MediaRecorder(mediaStream.value, {
14510
+ mimeType: "audio/webm; codecs=opus"
14511
+ });
14512
+ mediaRecorder.value.ondataavailable = onMediaRecorderDataAvailable;
14513
+ mediaRecorder.value.start(timeSliceLength.value);
14514
+ isRecording.value = true;
14515
+ } catch (error) {
14516
+ if (error.name === "NotAllowedError") {
14517
+ errorRef.value = ((_a = options.labels) == null ? void 0 : _a.microphoneNotAllowed) || "Microphone access denied. Please allow microphone access in your browser settings.";
14518
+ } else if (error.name === "NotFoundError") {
14519
+ errorRef.value = ((_b = options.labels) == null ? void 0 : _b.microphoneNotFound) || "No microphone found. Please connect a microphone and try again.";
14488
14520
  }
14489
- });
14490
- mediaRecorder.value = new MediaRecorder(mediaStream.value, {
14491
- mimeType: "audio/webm; codecs=opus"
14492
- });
14493
- mediaRecorder.value.ondataavailable = onMediaRecorderDataAvailable;
14494
- mediaRecorder.value.start(timeSliceLength.value);
14495
- isRecording.value = true;
14521
+ }
14496
14522
  });
14497
14523
  const stopRecording = () => {
14498
14524
  var _a, _b;
@@ -14515,6 +14541,7 @@ var __async = (__this, __arguments, generator) => {
14515
14541
  var _a;
14516
14542
  (_a = socket.value) == null ? void 0 : _a.close();
14517
14543
  socket.value = null;
14544
+ isSocketReady.value = false;
14518
14545
  };
14519
14546
  const reset = () => {
14520
14547
  stopRecording();
@@ -14522,9 +14549,11 @@ var __async = (__this, __arguments, generator) => {
14522
14549
  transcription.value = "";
14523
14550
  errorRef.value = null;
14524
14551
  isRecording.value = false;
14552
+ isSocketReady.value = false;
14525
14553
  };
14526
14554
  return {
14527
14555
  isRecording,
14556
+ isSocketReady,
14528
14557
  transcription,
14529
14558
  errorRef,
14530
14559
  initSocket,
@@ -14558,6 +14587,7 @@ var __async = (__this, __arguments, generator) => {
14558
14587
  const optionsStore = useOptionsStore();
14559
14588
  const {
14560
14589
  isRecording,
14590
+ isSocketReady,
14561
14591
  transcription,
14562
14592
  errorRef,
14563
14593
  initSocket,
@@ -14583,20 +14613,28 @@ var __async = (__this, __arguments, generator) => {
14583
14613
  return (_a = props.options.labels) != null ? _a : {};
14584
14614
  });
14585
14615
  const description = computed(() => {
14586
- var _a, _b, _c;
14616
+ var _a, _b;
14587
14617
  if (errorRef.value) {
14588
- return (_a = labels.value.serviceError) != null ? _a : errorRef.value;
14618
+ return errorRef.value;
14589
14619
  }
14590
- if (!isRecording.value) {
14591
- return (_b = labels.value.microphoneOff) != null ? _b : "Microphone is off. Try again.";
14620
+ if (!isSocketReady.value || !isRecording.value) {
14621
+ return (_a = labels.value.connecting) != null ? _a : "Connecting...";
14592
14622
  }
14593
- return (_c = labels.value.listening) != null ? _c : "Listening...";
14623
+ return (_b = labels.value.listening) != null ? _b : "Listening...";
14594
14624
  });
14595
14625
  watch(transcription, (newValue) => {
14596
14626
  emit2("transcript-update", newValue);
14597
14627
  });
14598
- const handleRecordingButtonClick = () => {
14628
+ watch(isRecording, (newVal) => {
14599
14629
  var _a, _b;
14630
+ if (newVal === true) {
14631
+ (_a = voiceSearchProgressBar.value) == null ? void 0 : _a.startProgressBar();
14632
+ } else {
14633
+ (_b = voiceSearchProgressBar.value) == null ? void 0 : _b.stopProgressBar();
14634
+ }
14635
+ });
14636
+ const handleRecordingButtonClick = () => {
14637
+ var _a;
14600
14638
  if (isRecording.value) {
14601
14639
  setTimeout(() => {
14602
14640
  stopSocketConnection();
@@ -14610,7 +14648,6 @@ var __async = (__this, __arguments, generator) => {
14610
14648
  );
14611
14649
  const socketUrl = `${voiceServiceUrl}?clientId=${clientId.value}&queryKey=${props.options.queryKey}&languageCode=${(_a = props.options.language) != null ? _a : "en-US"}&connectionType=write-first`;
14612
14650
  initSocket(socketUrl);
14613
- (_b = voiceSearchProgressBar.value) == null ? void 0 : _b.startProgressBar();
14614
14651
  setTimeout(() => {
14615
14652
  stopSocketConnection();
14616
14653
  handleOnStopEvent();
@@ -24293,6 +24330,15 @@ and ensure you are accounting for this risk.
24293
24330
  return false;
24294
24331
  }
24295
24332
  };
24333
+ function shouldDisplay(displayOpt, doc2) {
24334
+ if (!displayOpt)
24335
+ return true;
24336
+ if (typeof displayOpt === "function") {
24337
+ return displayOpt(doc2);
24338
+ }
24339
+ const rules = Array.isArray(displayOpt) ? displayOpt : [displayOpt];
24340
+ return rules.every((rule2) => processDisplayCondition(rule2, doc2));
24341
+ }
24296
24342
  const checkHasFullImageUrl = (imageUrl) => typeof imageUrl === "string" && (imageUrl.indexOf("http://") === 0 || imageUrl.indexOf("https://") === 0);
24297
24343
  const computeImageUrl = (imageUrl, rootImageUrl) => {
24298
24344
  const mainUrl = Array.isArray(imageUrl) ? imageUrl[0] : imageUrl;
@@ -25109,7 +25155,7 @@ and ensure you are accounting for this risk.
25109
25155
  if (!element.display) {
25110
25156
  return true;
25111
25157
  }
25112
- return typeof element.display === "function" ? element.display(item) : processDisplayCondition(element.display, item);
25158
+ return shouldDisplay(element.display, item);
25113
25159
  });
25114
25160
  const enhancedItem = computed(() => {
25115
25161
  var _a, _b, _c, _d;
@@ -25432,7 +25478,7 @@ and ensure you are accounting for this risk.
25432
25478
  if (!element.display) {
25433
25479
  return true;
25434
25480
  }
25435
- return typeof element.display === "function" ? element.display(item) : processDisplayCondition(element.display, item);
25481
+ return shouldDisplay(element.display, item);
25436
25482
  };
25437
25483
  const badges = computed(() => {
25438
25484
  if (!props.options.elements) {
@@ -25510,10 +25556,6 @@ and ensure you are accounting for this risk.
25510
25556
  const badgeOptions = computed(() => {
25511
25557
  return __spreadProps2(__spreadValues2({}, props.panelOptions.badges), { product: props.item });
25512
25558
  });
25513
- const imageElements = computed(() => {
25514
- var _a, _b;
25515
- return (_b = (_a = props.panelOptions.elements) == null ? void 0 : _a.filter((e2) => e2.type === DocumentElementType.IMAGE)) != null ? _b : [];
25516
- });
25517
25559
  const mainImageElement = computed(() => {
25518
25560
  return imageElements.value[0];
25519
25561
  });
@@ -25533,12 +25575,6 @@ and ensure you are accounting for this risk.
25533
25575
  minWidth: widthOverride.value ? `${widthOverride.value + 10}px` : void 0
25534
25576
  } : {};
25535
25577
  });
25536
- const detailElements = computed(() => {
25537
- var _a, _b;
25538
- return (_b = (_a = props.panelOptions.elements) == null ? void 0 : _a.filter(
25539
- (e2) => e2.type !== DocumentElementType.IMAGE && e2.type !== DocumentElementType.ADDTOCART
25540
- )) != null ? _b : [];
25541
- });
25542
25578
  const addToCartElement = computed(() => {
25543
25579
  var _a;
25544
25580
  return (_a = props.panelOptions.elements) == null ? void 0 : _a.find((e2) => e2.type === DocumentElementType.ADDTOCART);
@@ -25557,12 +25593,42 @@ and ensure you are accounting for this risk.
25557
25593
  onMounted(() => {
25558
25594
  checkIfIsInStock();
25559
25595
  });
25560
- const processIsInStock = () => {
25561
- return typeof props.panelOptions.isInStock === "function" ? props.panelOptions.isInStock(props.item) : processDisplayCondition(props.panelOptions.isInStock, props.item);
25562
- };
25596
+ const processIsInStock = computed(() => {
25597
+ const raw = props.panelOptions.isInStock;
25598
+ if (!raw)
25599
+ return true;
25600
+ const rules = Array.isArray(raw) ? raw : [raw];
25601
+ return rules.every((rule2) => shouldDisplay(rule2, props.item));
25602
+ });
25563
25603
  const checkIfIsInStock = () => __async2(this, null, function* () {
25564
- isInStock.value = props.panelOptions.isInStock ? processIsInStock() : true;
25604
+ isInStock.value = props.panelOptions.isInStock ? processIsInStock.value : true;
25565
25605
  });
25606
+ const imageElements = computed(
25607
+ () => {
25608
+ var _a, _b;
25609
+ return (_b = (_a = props.panelOptions.elements) == null ? void 0 : _a.filter((e2) => e2.type === DocumentElementType.IMAGE && !e2.group)) != null ? _b : [];
25610
+ }
25611
+ );
25612
+ const detailElements = computed(
25613
+ () => {
25614
+ var _a, _b;
25615
+ return (_b = (_a = props.panelOptions.elements) == null ? void 0 : _a.filter(
25616
+ (e2) => e2.type !== DocumentElementType.IMAGE && e2.type !== DocumentElementType.ADDTOCART && !e2.group
25617
+ )) != null ? _b : [];
25618
+ }
25619
+ );
25620
+ const elementGroups = computed(
25621
+ () => {
25622
+ var _a;
25623
+ return Array.from(
25624
+ new Set((_a = props.panelOptions.elements) == null ? void 0 : _a.map((e2) => e2.group).filter((g) => Boolean(g)))
25625
+ );
25626
+ }
25627
+ );
25628
+ function getGroupElements(group) {
25629
+ var _a, _b;
25630
+ return (_b = (_a = props.panelOptions.elements) == null ? void 0 : _a.filter((e2) => e2.group === group)) != null ? _b : [];
25631
+ }
25566
25632
  return (_ctx, _cache) => {
25567
25633
  return openBlock(), createElementBlock("a", mergeProps({
25568
25634
  class: ["lupa-search-box-product", { "lupa-search-box-product-highlighted": _ctx.highlighted }],
@@ -25578,9 +25644,9 @@ and ensure you are accounting for this risk.
25578
25644
  (openBlock(true), createElementBlock(Fragment, null, renderList(imageElements.value, (element) => {
25579
25645
  return openBlock(), createBlock(_sfc_main$1g, {
25580
25646
  class: "lupa-search-box-product-element",
25647
+ key: element.key,
25581
25648
  item: _ctx.item,
25582
25649
  element,
25583
- key: element.key,
25584
25650
  labels: _ctx.labels,
25585
25651
  link: link.value
25586
25652
  }, null, 8, ["item", "element", "labels", "link"]);
@@ -25590,14 +25656,14 @@ and ensure you are accounting for this risk.
25590
25656
  (openBlock(true), createElementBlock(Fragment, null, renderList(detailElements.value, (element) => {
25591
25657
  var _a;
25592
25658
  return openBlock(), createBlock(_sfc_main$1g, {
25593
- key: element.key,
25594
25659
  class: "lupa-search-box-product-element",
25660
+ key: element.key,
25595
25661
  item: _ctx.item,
25596
25662
  element,
25597
25663
  labels: _ctx.labels,
25598
25664
  link: link.value
25599
25665
  }, createSlots({ _: 2 }, [
25600
- badgeOptions.value && ((_a = badgeOptions.value) == null ? void 0 : _a.anchorElementKey) === element.key ? {
25666
+ ((_a = badgeOptions.value) == null ? void 0 : _a.anchorElementKey) === element.key ? {
25601
25667
  name: "badges",
25602
25668
  fn: withCtx(() => [
25603
25669
  createVNode(_sfc_main$19, {
@@ -25610,6 +25676,24 @@ and ensure you are accounting for this risk.
25610
25676
  ]), 1032, ["item", "element", "labels", "link"]);
25611
25677
  }), 128))
25612
25678
  ]),
25679
+ (openBlock(true), createElementBlock(Fragment, null, renderList(elementGroups.value, (group) => {
25680
+ return openBlock(), createElementBlock("div", {
25681
+ key: group,
25682
+ class: normalizeClass(`lupa-search-box-group-${group}`)
25683
+ }, [
25684
+ (openBlock(true), createElementBlock(Fragment, null, renderList(getGroupElements(group), (element) => {
25685
+ return openBlock(), createBlock(_sfc_main$1g, {
25686
+ class: "lupa-search-box-product-element",
25687
+ key: element.key,
25688
+ item: _ctx.item,
25689
+ element,
25690
+ labels: _ctx.labels,
25691
+ link: link.value,
25692
+ isInStock: isInStock.value
25693
+ }, null, 8, ["item", "element", "labels", "link", "isInStock"]);
25694
+ }), 128))
25695
+ ], 2);
25696
+ }), 128)),
25613
25697
  addToCartElement.value ? (openBlock(), createElementBlock("div", _hoisted_3$z, [
25614
25698
  createVNode(_sfc_main$1g, {
25615
25699
  class: "lupa-search-box-product-element",
@@ -30606,14 +30690,9 @@ and ensure you are accounting for this risk.
30606
30690
  const enhancementData = (_d = (_c = dynamicDataIdMap.value) == null ? void 0 : _c[(_b = props.item) == null ? void 0 : _b.id]) != null ? _d : {};
30607
30691
  return __spreadValues2(__spreadValues2({}, props.item), enhancementData);
30608
30692
  });
30609
- const displayElement = computed(() => {
30610
- const element = props.element;
30611
- const item = enhancedItem.value;
30612
- if (!element.display) {
30613
- return true;
30614
- }
30615
- return typeof element.display === "function" ? element.display(item) : processDisplayCondition(element.display, item);
30616
- });
30693
+ const displayElement = computed(
30694
+ () => shouldDisplay(props.element.display, enhancedItem.value)
30695
+ );
30617
30696
  const dynamicAttributes = computed(() => {
30618
30697
  return getDynamicAttributes(props.element.dynamicAttributes, enhancedItem.value);
30619
30698
  });
@@ -30741,15 +30820,21 @@ and ensure you are accounting for this risk.
30741
30820
  var _a, _b;
30742
30821
  return (_b = (_a = props.options.elements) == null ? void 0 : _a.filter((e2) => e2.group === group)) != null ? _b : [];
30743
30822
  };
30744
- const processIsInStock = () => {
30745
- return typeof props.options.isInStock === "function" ? props.options.isInStock(props.product) : processDisplayCondition(props.options.isInStock, props.product);
30823
+ const shouldShowInStock = () => {
30824
+ const raw = props.options.isInStock;
30825
+ if (!raw)
30826
+ return true;
30827
+ const rules = Array.isArray(raw) ? raw : [raw];
30828
+ return rules.every(
30829
+ (rule2) => typeof rule2 === "function" ? rule2(props.product) : processDisplayCondition(rule2, props.product)
30830
+ );
30831
+ };
30832
+ const checkIfIsInStock = () => {
30833
+ isInStock.value = shouldShowInStock();
30746
30834
  };
30747
30835
  onMounted(() => {
30748
30836
  checkIfIsInStock();
30749
30837
  });
30750
- const checkIfIsInStock = () => __async2(this, null, function* () {
30751
- isInStock.value = props.options.isInStock ? yield processIsInStock() : true;
30752
- });
30753
30838
  const handleClick = () => {
30754
30839
  var _a, _b, _c, _d;
30755
30840
  const event = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getlupa/client",
3
- "version": "1.18.5",
3
+ "version": "1.19.0",
4
4
  "main": "dist/lupaSearch.js",
5
5
  "module": "dist/index.mjs",
6
6
  "types": "dist/src/index.d.ts",
@@ -20,7 +20,7 @@
20
20
  },
21
21
  "devDependencies": {
22
22
  "@getlupa/client-sdk": "^1.3.4",
23
- "@getlupa/vue": "0.18.5",
23
+ "@getlupa/vue": "0.19.0",
24
24
  "@rushstack/eslint-patch": "^1.3.2",
25
25
  "@tsconfig/node18": "^2.0.1",
26
26
  "@types/jsdom": "^21.1.1",