@guidelytech/sdk-core 0.8.0 → 0.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.d.cts CHANGED
@@ -4,14 +4,14 @@ export { AppSnapshot, AutocaptureSettings, ExceptionProperties, GuideConfig, Gui
4
4
  import { FlagsClient, JsonValue, FlagValue, FlagDetails } from '@guidelytech/flags';
5
5
  export { Attributes, EvaluationResult, FlagDetails, FlagsBootstrap, FlagsClient, FlagsClientOptions, FlagsPayload, JsonValue } from '@guidelytech/flags';
6
6
  import { MessengerTab } from '@guidelytech/guide-runtime/messenger';
7
- import { j as GuidelyOptions, c as GuidelyAccount, a as ConsentState, C as ChecklistProgressState, k as GuidelyEvents, e as GuidelyUser, G as GuideLocalState, S as SessionState } from './types-DbKQPvFt.cjs';
8
- export { E as EventQueue, b as EventQueueOptions, l as GuideStepInfo, d as GuidelyEnvironment, m as GuidelyEventName, P as PersistedState, f as areMutuallyExclusive, i as isExclusiveGuide, g as isFrequencyEligible, h as isWithinSchedule } from './types-DbKQPvFt.cjs';
7
+ import { k as GuidelyOptions, c as GuidelyAccount, a as ConsentState, C as ChecklistProgressState, l as GuidelyEvents, e as GuidelyUser, G as GuideLocalState, S as SessionState } from './types-zM5e3loY.cjs';
8
+ export { E as EventQueue, b as EventQueueOptions, m as GuideStepInfo, d as GuidelyEnvironment, n as GuidelyEventName, P as PersistedState, f as areMutuallyExclusive, i as isExclusiveGuide, h as isFrequencyEligible, j as isWithinSchedule } from './types-zM5e3loY.cjs';
9
9
  export { K as KEYS, b as KeyValueStore, S as StorageKind, d as createStorage } from './http-47tiAlOM.cjs';
10
10
  export { C as CaptureMarker, a as CaptureOutgoingMessage } from './capture-C3faAYb7.cjs';
11
11
  export { CAPTURE_PARAM } from '@guidelytech/shared/runtime';
12
12
 
13
13
  declare const SDK_NAME = "@guidelytech/sdk-core";
14
- declare const SDK_VERSION = "0.8.0";
14
+ declare const SDK_VERSION = "0.9.0";
15
15
  declare const DEFAULT_API_URL = "https://api.guidely.app";
16
16
  /**
17
17
  * Framework-independent Guidely client. Create one per page with {@link createGuidely} or
@@ -214,6 +214,11 @@ declare class GuidelyClient {
214
214
  /** Opens the Scout messenger (when enabled for the project), optionally on a tab. */
215
215
  openMessenger(tab?: MessengerTab): void;
216
216
  closeMessenger(): void;
217
+ /**
218
+ * Opens the complaint form in the messenger, optionally with a category picked (its id from
219
+ * Complaints → Categories). Does nothing when the project doesn't take complaints.
220
+ */
221
+ openComplaint(categoryId?: string): void;
217
222
  /** Opens a new messenger conversation, optionally pre-filling the message. */
218
223
  showNewMessage(text?: string): void;
219
224
  /** Boolean flag value for the current user; `fallback` (default `false`) until loaded or when missing. */
package/dist/index.d.ts CHANGED
@@ -4,14 +4,14 @@ export { AppSnapshot, AutocaptureSettings, ExceptionProperties, GuideConfig, Gui
4
4
  import { FlagsClient, JsonValue, FlagValue, FlagDetails } from '@guidelytech/flags';
5
5
  export { Attributes, EvaluationResult, FlagDetails, FlagsBootstrap, FlagsClient, FlagsClientOptions, FlagsPayload, JsonValue } from '@guidelytech/flags';
6
6
  import { MessengerTab } from '@guidelytech/guide-runtime/messenger';
7
- import { j as GuidelyOptions, c as GuidelyAccount, a as ConsentState, C as ChecklistProgressState, k as GuidelyEvents, e as GuidelyUser, G as GuideLocalState, S as SessionState } from './types-DqhNl5Am.js';
8
- export { E as EventQueue, b as EventQueueOptions, l as GuideStepInfo, d as GuidelyEnvironment, m as GuidelyEventName, P as PersistedState, f as areMutuallyExclusive, i as isExclusiveGuide, g as isFrequencyEligible, h as isWithinSchedule } from './types-DqhNl5Am.js';
7
+ import { k as GuidelyOptions, c as GuidelyAccount, a as ConsentState, C as ChecklistProgressState, l as GuidelyEvents, e as GuidelyUser, G as GuideLocalState, S as SessionState } from './types-DnJW_4ck.js';
8
+ export { E as EventQueue, b as EventQueueOptions, m as GuideStepInfo, d as GuidelyEnvironment, n as GuidelyEventName, P as PersistedState, f as areMutuallyExclusive, i as isExclusiveGuide, h as isFrequencyEligible, j as isWithinSchedule } from './types-DnJW_4ck.js';
9
9
  export { K as KEYS, b as KeyValueStore, S as StorageKind, d as createStorage } from './http-47tiAlOM.js';
10
10
  export { C as CaptureMarker, a as CaptureOutgoingMessage } from './capture-Dqd7up2n.js';
11
11
  export { CAPTURE_PARAM } from '@guidelytech/shared/runtime';
12
12
 
13
13
  declare const SDK_NAME = "@guidelytech/sdk-core";
14
- declare const SDK_VERSION = "0.8.0";
14
+ declare const SDK_VERSION = "0.9.0";
15
15
  declare const DEFAULT_API_URL = "https://api.guidely.app";
16
16
  /**
17
17
  * Framework-independent Guidely client. Create one per page with {@link createGuidely} or
@@ -214,6 +214,11 @@ declare class GuidelyClient {
214
214
  /** Opens the Scout messenger (when enabled for the project), optionally on a tab. */
215
215
  openMessenger(tab?: MessengerTab): void;
216
216
  closeMessenger(): void;
217
+ /**
218
+ * Opens the complaint form in the messenger, optionally with a category picked (its id from
219
+ * Complaints → Categories). Does nothing when the project doesn't take complaints.
220
+ */
221
+ openComplaint(categoryId?: string): void;
217
222
  /** Opens a new messenger conversation, optionally pre-filling the message. */
218
223
  showNewMessage(text?: string): void;
219
224
  /** Boolean flag value for the current user; `fallback` (default `false`) until loaded or when missing. */
package/dist/index.js CHANGED
@@ -2,10 +2,11 @@ import {
2
2
  Emitter,
3
3
  EventQueue,
4
4
  areMutuallyExclusive,
5
+ dismissedAfterMerge,
5
6
  isExclusiveGuide,
6
7
  isFrequencyEligible,
7
8
  isWithinSchedule
8
- } from "./chunk-GDF6RCHQ.js";
9
+ } from "./chunk-544KSOC3.js";
9
10
  import {
10
11
  KEYS,
11
12
  createStorage,
@@ -730,11 +731,15 @@ function forgetConversations(store, projectId) {
730
731
  store.remove(KEYS.conversations(projectId));
731
732
  }
732
733
  var HttpError = class extends Error {
733
- constructor(status) {
734
- super(`Request failed (${status})`);
734
+ constructor(status, message) {
735
+ super(message || `Request failed (${status})`);
735
736
  __publicField(this, "status", status);
736
737
  }
737
738
  };
739
+ function serverMessage(data) {
740
+ const m = data?.error?.message;
741
+ return typeof m === "string" && m !== "Request validation failed" ? m : void 0;
742
+ }
738
743
  function createMessengerTransport(opts) {
739
744
  const { api, store, projectId } = opts;
740
745
  const tokenFor = (id) => storedConversations(store, projectId).find((c) => c.id === id)?.token ?? "";
@@ -816,6 +821,16 @@ function createMessengerTransport(opts) {
816
821
  const res = await api.get(`/articles/${encodeURIComponent(id)}`);
817
822
  return res.ok && res.data ? res.data.article : null;
818
823
  },
824
+ async fileComplaint(input) {
825
+ const headers = input.conversationId ? { [TOKEN_HEADER]: tokenFor(input.conversationId) } : {};
826
+ const res = await api.post("/complaints", { ...input, anonymousId: opts.anonymousId(), userId: opts.userId(), pageUrl: opts.pageUrl() }, { headers });
827
+ if (!res.ok || !res.data || !("complaint" in res.data)) {
828
+ if (res.status === 429) throw new HttpError(429, "You've filed several complaints just now. Please try again later.");
829
+ throw new HttpError(res.status, serverMessage(res.data) ?? "Your complaint couldn't be sent. Please try again.");
830
+ }
831
+ if (res.data.token) remember(res.data.conversation.id, res.data.token);
832
+ return res.data;
833
+ },
819
834
  async pageContent(path) {
820
835
  const res = await api.post("/messenger/page", { anonymousId: opts.anonymousId(), userId: opts.userId(), path: path.split(/[?#]/)[0] || "/" });
821
836
  if (!res.ok || !res.data) throw new HttpError(res.status);
@@ -1013,7 +1028,7 @@ var loadRecorder = async () => (await import("./recorder.js")).recorder;
1013
1028
 
1014
1029
  // src/client.ts
1015
1030
  var SDK_NAME = "@guidelytech/sdk-core";
1016
- var SDK_VERSION = "0.8.0";
1031
+ var SDK_VERSION = "0.9.0";
1017
1032
  var DEFAULT_API_URL = "https://api.guidely.app";
1018
1033
  var PAGE_SCOPED = /* @__PURE__ */ new Set(["page_load", "url_match", "element_click", "element_visible", "delay"]);
1019
1034
  var DAY_MS = 24 * 60 * 60 * 1e3;
@@ -1421,7 +1436,8 @@ var GuidelyClient = class _GuidelyClient {
1421
1436
  checklists[id] = {
1422
1437
  completedTaskIds: Array.from(/* @__PURE__ */ new Set([...local?.completedTaskIds ?? [], ...p.completedTaskIds ?? []])),
1423
1438
  completedAt: local?.completedAt ?? p.completedAt ?? null,
1424
- dismissedAt: local?.dismissedAt ?? p.dismissedAt ?? null
1439
+ dismissedAt: dismissedAfterMerge(local, p),
1440
+ dismissResetAt: p.dismissResetAt ?? local?.dismissResetAt ?? null
1425
1441
  };
1426
1442
  }
1427
1443
  this.state = {
@@ -2060,6 +2076,12 @@ var GuidelyClient = class _GuidelyClient {
2060
2076
  ctx: () => this.getContext(),
2061
2077
  startAtStep: stepId,
2062
2078
  eventBus: this.eventBus,
2079
+ // Started from Help, Scout or startGuide(): steps on other pages offer to take the user there.
2080
+ promptForUrl: manual,
2081
+ // Also while a step waits for its page, so a link that loads that page resumes on it.
2082
+ onPosition: (id) => {
2083
+ if (exclusive) writeJson(this.sessionStore, KEYS.active, { guideId: guide.id, stepId: id, manual });
2084
+ },
2063
2085
  onError: (err) => this.reportError(err),
2064
2086
  onEvent: (e) => {
2065
2087
  const step = e.stepId ? guide.config.steps.find((s) => s.id === e.stepId) : void 0;
@@ -2283,7 +2305,7 @@ var GuidelyClient = class _GuidelyClient {
2283
2305
  const ctx = this.getContext();
2284
2306
  const url = location.href;
2285
2307
  const seen = readJson(this.store, KEYS.newsSeen(this.options.projectId), []);
2286
- return buildMessengerVisitor({
2308
+ const visitor = buildMessengerVisitor({
2287
2309
  guides: this.config?.guides ?? [],
2288
2310
  state: this.state,
2289
2311
  traits: this.user?.traits,
@@ -2296,6 +2318,7 @@ var GuidelyClient = class _GuidelyClient {
2296
2318
  },
2297
2319
  newsSeen: Array.isArray(seen) ? seen : []
2298
2320
  });
2321
+ return { ...visitor, identified: !!this.user?.id };
2299
2322
  }
2300
2323
  destroyMessenger() {
2301
2324
  this.messenger?.destroy();
@@ -2481,6 +2504,14 @@ var GuidelyClient = class _GuidelyClient {
2481
2504
  closeMessenger() {
2482
2505
  this.messenger?.close();
2483
2506
  }
2507
+ /**
2508
+ * Opens the complaint form in the messenger, optionally with a category picked (its id from
2509
+ * Complaints → Categories). Does nothing when the project doesn't take complaints.
2510
+ */
2511
+ openComplaint(categoryId) {
2512
+ if (!this.config?.messenger?.enabled || !this.config.messenger.complaints?.categories.length) return;
2513
+ void this.loadMessenger().then((m) => m?.openComplaint(categoryId));
2514
+ }
2484
2515
  /** Opens a new messenger conversation, optionally pre-filling the message. */
2485
2516
  showNewMessage(text) {
2486
2517
  if (!this.config?.messenger?.enabled) return;