kenobi-js 0.1.36 → 0.1.38

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/browser/dist.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Kenobi SDK v0.1.35
2
+ * Kenobi SDK v0.1.37
3
3
  * (c) 2025 Kenobi.ai
4
4
  */
5
5
  "use strict";
@@ -2398,6 +2398,11 @@ var KenobiLib = (() => {
2398
2398
  };
2399
2399
  __name(_TransitionOrchestrator, "TransitionOrchestrator");
2400
2400
  var TransitionOrchestrator = _TransitionOrchestrator;
2401
+ var isCueCardConfigResponse = /* @__PURE__ */ __name((value) => {
2402
+ if (typeof value !== "object" || value === null) return false;
2403
+ const candidate = value;
2404
+ return typeof candidate.enabled === "boolean";
2405
+ }, "isCueCardConfigResponse");
2401
2406
  var TRANSFORMATION_ACTIONS = /* @__PURE__ */ new Set(["Replace", "InsertBefore", "InsertAfter", "Delete", "SetFormField"]);
2402
2407
  var isString = /* @__PURE__ */ __name((value) => typeof value === "string", "isString");
2403
2408
  var isStringArray = /* @__PURE__ */ __name((value) => Array.isArray(value) && value.every((item) => isString(item)), "isStringArray");
@@ -2434,6 +2439,7 @@ var KenobiLib = (() => {
2434
2439
  __publicField(this, "currentUrl");
2435
2440
  __publicField(this, "navTicking", false);
2436
2441
  __publicField(this, "transitionDefaults");
2442
+ __publicField(this, "cueCardPaths");
2437
2443
  __publicField(this, "startAutoTransform", /* @__PURE__ */ __name(async () => {
2438
2444
  try {
2439
2445
  this.syncChangeStack();
@@ -2566,6 +2572,23 @@ var KenobiLib = (() => {
2566
2572
  __publicField(this, "getDurationInMilliseconds", /* @__PURE__ */ __name((start, end) => +end - +start, "getDurationInMilliseconds"));
2567
2573
  __publicField(this, "formatThousands", /* @__PURE__ */ __name((number) => new Intl.NumberFormat("en-US").format(number), "formatThousands"));
2568
2574
  __publicField(this, "setDebug", /* @__PURE__ */ __name((value) => this.config.debug = value, "setDebug"));
2575
+ /**
2576
+ * Checks if a path matches a pattern.
2577
+ * Supports exact matches ("/pricing") and wildcard suffixes ("/blog/*").
2578
+ */
2579
+ __publicField(this, "matchesPathPattern", /* @__PURE__ */ __name((path, pattern) => {
2580
+ const normalizedPath = path === "/" ? "/" : path.replace(/\/$/, "");
2581
+ const normalizedPattern = pattern === "/" ? "/" : pattern.replace(/\/$/, "");
2582
+ if (normalizedPattern.endsWith("/*")) {
2583
+ const base = normalizedPattern.slice(0, -2);
2584
+ return normalizedPath === base || normalizedPath.startsWith(base + "/");
2585
+ }
2586
+ return normalizedPath === normalizedPattern;
2587
+ }, "matchesPathPattern"));
2588
+ /**
2589
+ * Checks if the given path matches any of the configured cueCardPaths.
2590
+ */
2591
+ __publicField(this, "isPathAllowedForCueCard", /* @__PURE__ */ __name((path) => this.cueCardPaths.some((pattern) => this.matchesPathPattern(path, pattern)), "isPathAllowedForCueCard"));
2569
2592
  __publicField(this, "isInputElement", /* @__PURE__ */ __name((el) => {
2570
2593
  if (!(el instanceof HTMLInputElement) && !(el instanceof HTMLTextAreaElement) && !(el instanceof HTMLSelectElement))
2571
2594
  return false;
@@ -2675,6 +2698,7 @@ var KenobiLib = (() => {
2675
2698
  this.undoAll();
2676
2699
  void this.startAutoTransform();
2677
2700
  }
2701
+ this.syncCueCardVisibility();
2678
2702
  }
2679
2703
  });
2680
2704
  }, "schedule");
@@ -3037,21 +3061,74 @@ var KenobiLib = (() => {
3037
3061
  ----
3038
3062
  */
3039
3063
  /**
3040
- * Initializes and mounts a CueCard with default configuration.
3064
+ * Fetches the CueCard configuration from the API to check if an active
3065
+ * template exists for the given path.
3066
+ *
3067
+ * @param pagePath - The page path to check for active template
3068
+ * @returns The config response, or null if the request failed
3069
+ */
3070
+ __publicField(this, "fetchCueCardConfig", /* @__PURE__ */ __name(async (pagePath) => {
3071
+ if (!this.config.publicKey) return null;
3072
+ try {
3073
+ const searchParams = new URLSearchParams({
3074
+ publicKey: this.config.publicKey,
3075
+ pagePath
3076
+ });
3077
+ const response = await fetch(
3078
+ `${this.config.apiHost}/v1/cue-card-config?${searchParams.toString()}`
3079
+ );
3080
+ if (!response.ok) {
3081
+ this.log(
3082
+ "warn",
3083
+ `CueCard config request failed with status ${response.status}`
3084
+ );
3085
+ return null;
3086
+ }
3087
+ const data = await response.json();
3088
+ if (!isCueCardConfigResponse(data)) {
3089
+ this.log("warn", "Invalid CueCard config response format");
3090
+ return null;
3091
+ }
3092
+ return data;
3093
+ } catch (error) {
3094
+ this.log("error", "Failed to fetch CueCard config:", error);
3095
+ return null;
3096
+ }
3097
+ }, "fetchCueCardConfig"));
3098
+ /**
3099
+ * Initializes and mounts a CueCard with configuration from the API.
3041
3100
  * Called automatically when publicKey is provided.
3042
3101
  *
3043
- * Default config matches the template editor settings.
3044
- * Future: This config will be fetched per-org from the database.
3102
+ * The CueCard will only be mounted if an active template exists for
3103
+ * the current path on the server.
3045
3104
  */
3046
- __publicField(this, "initCueCard", /* @__PURE__ */ __name(() => {
3105
+ __publicField(this, "initCueCard", /* @__PURE__ */ __name(async () => {
3047
3106
  if (this.cueCardInstance) {
3048
3107
  this.log("warn", "CueCard already initialized, skipping...");
3049
3108
  return;
3050
3109
  }
3110
+ if (!this.isPathAllowedForCueCard(this.currentPath)) {
3111
+ this.log(
3112
+ "debug",
3113
+ `CueCard not mounted: path "${this.currentPath}" not in allowed paths`
3114
+ );
3115
+ return;
3116
+ }
3117
+ const configResponse = await this.fetchCueCardConfig(this.currentPath);
3118
+ if (!configResponse || !configResponse.enabled) {
3119
+ this.log(
3120
+ "debug",
3121
+ `CueCard not mounted: no active template for path "${this.currentPath}"`
3122
+ );
3123
+ return;
3124
+ }
3125
+ this.log("debug", "Active template found, mounting CueCard...");
3126
+ const serverConfig = configResponse.config;
3051
3127
  this.cueCardInstance = new CueCard({
3052
- theme: "light",
3053
- position: "top-center",
3054
- fields: [
3128
+ theme: serverConfig?.theme ?? "light",
3129
+ position: serverConfig?.position ?? "top-center",
3130
+ direction: serverConfig?.direction ?? "top-to-bottom",
3131
+ fields: serverConfig?.fields ?? [
3055
3132
  {
3056
3133
  name: "companyDomain",
3057
3134
  label: "Company Name or Domain",
@@ -3062,10 +3139,12 @@ var KenobiLib = (() => {
3062
3139
  }
3063
3140
  ],
3064
3141
  isVisible: true,
3065
- enableFocusMode: false,
3066
- showWatermark: false,
3067
- showKeyboardHints: true,
3068
- enableLauncher: true,
3142
+ enableFocusMode: serverConfig?.enableFocusMode ?? false,
3143
+ showWatermark: serverConfig?.showWatermark ?? false,
3144
+ showKeyboardHints: serverConfig?.showKeyboardHints ?? true,
3145
+ enableLauncher: serverConfig?.enableLauncher ?? true,
3146
+ customTheme: serverConfig?.customTheme,
3147
+ textOverrides: serverConfig?.textOverrides,
3069
3148
  onDismiss: /* @__PURE__ */ __name(() => {
3070
3149
  this.log("debug", "CueCard dismissed by user");
3071
3150
  }, "onDismiss"),
@@ -3080,6 +3159,29 @@ var KenobiLib = (() => {
3080
3159
  this.cueCardInstance.mount();
3081
3160
  this.log("debug", "CueCard mounted successfully");
3082
3161
  }, "initCueCard"));
3162
+ /**
3163
+ * Syncs CueCard visibility based on the current path.
3164
+ * Mounts CueCard if on an allowed path and active template exists, unmounts if not.
3165
+ * Called after navigation changes.
3166
+ */
3167
+ __publicField(this, "syncCueCardVisibility", /* @__PURE__ */ __name(() => {
3168
+ if (!this.config.publicKey) return;
3169
+ const isAllowed = this.isPathAllowedForCueCard(this.currentPath);
3170
+ if (isAllowed && !this.cueCardInstance) {
3171
+ this.log(
3172
+ "debug",
3173
+ `Navigated to allowed path "${this.currentPath}", checking for active template...`
3174
+ );
3175
+ void this.initCueCard();
3176
+ } else if (!isAllowed && this.cueCardInstance) {
3177
+ this.log(
3178
+ "debug",
3179
+ `Navigated away from allowed paths to "${this.currentPath}", unmounting CueCard`
3180
+ );
3181
+ this.cueCardInstance.unmount();
3182
+ this.cueCardInstance = null;
3183
+ }
3184
+ }, "syncCueCardVisibility"));
3083
3185
  /**
3084
3186
  * Triggers personalization by calling the API with the provided input.
3085
3187
  * Updates CueCard status during the flow and applies transformations.
@@ -3158,6 +3260,7 @@ var KenobiLib = (() => {
3158
3260
  this.config.transitionDefaults
3159
3261
  );
3160
3262
  this.orchestrator = new TransitionOrchestrator();
3263
+ this.cueCardPaths = this.config.cueCardPaths ?? ["/"];
3161
3264
  this.syncVisitorKey();
3162
3265
  this.currentPath = this.getCurrentPath();
3163
3266
  this.currentUrl = this.getCurrentUrl();
@@ -3176,8 +3279,8 @@ var KenobiLib = (() => {
3176
3279
  void this.startAutoTransform();
3177
3280
  }
3178
3281
  if (this.config.publicKey) {
3179
- this.log("debug", "Public key provided, auto-mounting CueCard...");
3180
- this.initCueCard();
3282
+ this.log("debug", "Public key provided, checking for active template...");
3283
+ void this.initCueCard();
3181
3284
  }
3182
3285
  }
3183
3286
  };