@wallavi/widget 1.8.0 → 1.9.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/index.js CHANGED
@@ -377,6 +377,10 @@ function useChat({
377
377
  if (proto.path.startsWith("/")) onNavigateRef.current?.(proto.path);
378
378
  return;
379
379
  }
380
+ if (proto.type === "client-action") {
381
+ executeDeclarativeSteps(proto.steps, onNavigateRef.current);
382
+ return;
383
+ }
380
384
  if (proto.type === "debug-trace") {
381
385
  setDebugTraces((prev) => [
382
386
  ...prev,
@@ -755,6 +759,82 @@ function useChat({
755
759
  voiceCall
756
760
  };
757
761
  }
762
+ function executeDeclarativeSteps(steps, onNavigate) {
763
+ if (typeof window === "undefined" || !Array.isArray(steps)) return;
764
+ for (const step of steps) {
765
+ try {
766
+ const { action, selector, value, payload } = step;
767
+ switch (action) {
768
+ case "scroll_into_view": {
769
+ if (!selector) break;
770
+ const el = document.querySelector(selector);
771
+ el?.scrollIntoView({ behavior: "smooth", block: "center" });
772
+ break;
773
+ }
774
+ case "click": {
775
+ if (!selector) break;
776
+ const el = document.querySelector(selector);
777
+ el?.click();
778
+ break;
779
+ }
780
+ case "focus": {
781
+ if (!selector) break;
782
+ const el = document.querySelector(selector);
783
+ el?.focus();
784
+ break;
785
+ }
786
+ case "add_class": {
787
+ if (!selector || !value) break;
788
+ const el = document.querySelector(selector);
789
+ if (el) el.classList.add(...value.split(/\s+/).filter(Boolean));
790
+ break;
791
+ }
792
+ case "remove_class": {
793
+ if (!selector || !value) break;
794
+ const el = document.querySelector(selector);
795
+ if (el) el.classList.remove(...value.split(/\s+/).filter(Boolean));
796
+ break;
797
+ }
798
+ case "fill_value": {
799
+ if (!selector) break;
800
+ const el = document.querySelector(selector);
801
+ if (el) {
802
+ el.value = value ?? "";
803
+ el.dispatchEvent(new Event("input", { bubbles: true }));
804
+ el.dispatchEvent(new Event("change", { bubbles: true }));
805
+ }
806
+ break;
807
+ }
808
+ case "dispatch_event": {
809
+ if (!value) break;
810
+ const detail = payload ?? {};
811
+ window.dispatchEvent(new CustomEvent(value, { detail }));
812
+ break;
813
+ }
814
+ case "navigate": {
815
+ if (value) {
816
+ if (onNavigate) {
817
+ onNavigate(value);
818
+ } else {
819
+ window.location.href = value;
820
+ }
821
+ }
822
+ break;
823
+ }
824
+ default:
825
+ console.warn(
826
+ `[Wallavi Widget] Unknown declarative action: ${action}`
827
+ );
828
+ }
829
+ } catch (err) {
830
+ console.error(
831
+ "[Wallavi Widget] Failed to execute declarative step:",
832
+ step,
833
+ err
834
+ );
835
+ }
836
+ }
837
+ }
758
838
  function getPreferredMimeType() {
759
839
  if (typeof MediaRecorder === "undefined") return "";
760
840
  const candidates = [
package/dist/index.mjs CHANGED
@@ -351,6 +351,10 @@ function useChat({
351
351
  if (proto.path.startsWith("/")) onNavigateRef.current?.(proto.path);
352
352
  return;
353
353
  }
354
+ if (proto.type === "client-action") {
355
+ executeDeclarativeSteps(proto.steps, onNavigateRef.current);
356
+ return;
357
+ }
354
358
  if (proto.type === "debug-trace") {
355
359
  setDebugTraces((prev) => [
356
360
  ...prev,
@@ -729,6 +733,82 @@ function useChat({
729
733
  voiceCall
730
734
  };
731
735
  }
736
+ function executeDeclarativeSteps(steps, onNavigate) {
737
+ if (typeof window === "undefined" || !Array.isArray(steps)) return;
738
+ for (const step of steps) {
739
+ try {
740
+ const { action, selector, value, payload } = step;
741
+ switch (action) {
742
+ case "scroll_into_view": {
743
+ if (!selector) break;
744
+ const el = document.querySelector(selector);
745
+ el?.scrollIntoView({ behavior: "smooth", block: "center" });
746
+ break;
747
+ }
748
+ case "click": {
749
+ if (!selector) break;
750
+ const el = document.querySelector(selector);
751
+ el?.click();
752
+ break;
753
+ }
754
+ case "focus": {
755
+ if (!selector) break;
756
+ const el = document.querySelector(selector);
757
+ el?.focus();
758
+ break;
759
+ }
760
+ case "add_class": {
761
+ if (!selector || !value) break;
762
+ const el = document.querySelector(selector);
763
+ if (el) el.classList.add(...value.split(/\s+/).filter(Boolean));
764
+ break;
765
+ }
766
+ case "remove_class": {
767
+ if (!selector || !value) break;
768
+ const el = document.querySelector(selector);
769
+ if (el) el.classList.remove(...value.split(/\s+/).filter(Boolean));
770
+ break;
771
+ }
772
+ case "fill_value": {
773
+ if (!selector) break;
774
+ const el = document.querySelector(selector);
775
+ if (el) {
776
+ el.value = value ?? "";
777
+ el.dispatchEvent(new Event("input", { bubbles: true }));
778
+ el.dispatchEvent(new Event("change", { bubbles: true }));
779
+ }
780
+ break;
781
+ }
782
+ case "dispatch_event": {
783
+ if (!value) break;
784
+ const detail = payload ?? {};
785
+ window.dispatchEvent(new CustomEvent(value, { detail }));
786
+ break;
787
+ }
788
+ case "navigate": {
789
+ if (value) {
790
+ if (onNavigate) {
791
+ onNavigate(value);
792
+ } else {
793
+ window.location.href = value;
794
+ }
795
+ }
796
+ break;
797
+ }
798
+ default:
799
+ console.warn(
800
+ `[Wallavi Widget] Unknown declarative action: ${action}`
801
+ );
802
+ }
803
+ } catch (err) {
804
+ console.error(
805
+ "[Wallavi Widget] Failed to execute declarative step:",
806
+ step,
807
+ err
808
+ );
809
+ }
810
+ }
811
+ }
732
812
  function getPreferredMimeType() {
733
813
  if (typeof MediaRecorder === "undefined") return "";
734
814
  const candidates = [
package/package.json CHANGED
@@ -42,7 +42,7 @@
42
42
  },
43
43
  "private": false,
44
44
  "types": "./dist/index.d.ts",
45
- "version": "1.8.0",
45
+ "version": "1.9.0",
46
46
  "scripts": {
47
47
  "build": "tsup && pnpm build:css",
48
48
  "build:css": "tailwindcss -i ./src/styles.css -o ./dist/styles.css --config tailwind.config.cjs --minify",