@guidelytech/sdk-core 0.0.0-stage → 0.1.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/README.md +155 -2
- package/dist/index.cjs +1791 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +482 -0
- package/dist/index.d.ts +482 -0
- package/dist/index.js +1748 -0
- package/dist/index.js.map +1 -0
- package/package.json +61 -3
package/README.md
CHANGED
|
@@ -1,3 +1,156 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @guidelytech/sdk-core
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Framework-independent Guidely browser SDK: loads the published configuration for an environment,
|
|
4
|
+
identifies users, tracks events, evaluates targeting/trigger/frequency rules and renders guides
|
|
5
|
+
through `@guidelytech/guide-runtime`. Framework adapters (`@guidelytech/react`, `@guidelytech/nextjs`,
|
|
6
|
+
`@guidelytech/svelte`, `@guidelytech/sveltekit`) and the script-tag build (`@guidelytech/embed`) wrap this
|
|
7
|
+
package.
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pnpm add @guidelytech/sdk-core
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { createGuidely } from "@guidelytech/sdk-core";
|
|
15
|
+
|
|
16
|
+
const guidely = createGuidely({
|
|
17
|
+
projectId: "pk_dev_demo_react", // environment public key (not a secret)
|
|
18
|
+
apiUrl: "http://localhost:3000", // defaults to https://api.guidely.app
|
|
19
|
+
environment: "development",
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
await guidely.ready();
|
|
23
|
+
await guidely.identify("user_123", { role: "admin", plan: "pro" }, { id: "acme", traits: { seats: 12 } });
|
|
24
|
+
guidely.track("contact_created", { source: "import" });
|
|
25
|
+
guidely.on("guide:complete", (guide) => console.log("completed", guide.key));
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
The module is safe to import during SSR (nothing touches `window` at module scope).
|
|
29
|
+
`createGuidely()` throws a friendly error when called on the server.
|
|
30
|
+
|
|
31
|
+
## Options
|
|
32
|
+
|
|
33
|
+
| Option | Default | Description |
|
|
34
|
+
|---|---|---|
|
|
35
|
+
| `projectId` | — | Environment public key (`pk_dev_…`, `pk_stag_…`, `pk_prod_…`). Required. |
|
|
36
|
+
| `environment` | inferred from key prefix | `development` \| `staging` \| `production`; exposed to targeting (`environment` field). |
|
|
37
|
+
| `apiUrl` | `https://api.guidely.app` | Base URL of the Guidely API. Demos use `http://localhost:3000`. |
|
|
38
|
+
| `debug` | `false` | Log trigger decisions and requests with `console.debug("[Guidely]", …)`. |
|
|
39
|
+
| `analytics` | `true` | Send analytics events. Guides still render when `false`. |
|
|
40
|
+
| `consent` | `"granted"` | `"pending"` buffers events (persisted) until `setConsent("granted")`; `"denied"` disables analytics. |
|
|
41
|
+
| `storage` | `"local"` | `"local"` \| `"session"` \| `"memory"` for identity, cached config, state and queue. |
|
|
42
|
+
| `pollIntervalMs` | `1000` | Idle re-check interval (min 250ms): re-arms `element_visible` triggers whose target appears without navigation and drains the guide queue. |
|
|
43
|
+
| `configRefreshMs` | `300000` | Periodic config refresh (`If-None-Match` → 304 when unchanged). |
|
|
44
|
+
| `maskSelectors` | `[]` | Elements whose text is never captured in authoring picks (merged with the project setting). |
|
|
45
|
+
| `onError` | — | Receives every error the SDK swallows (network, rendering). |
|
|
46
|
+
| `theme` | — | Overrides for the project theme (`primaryColor`, `backgroundColor`, `textColor`, `borderRadius`, `fontFamily`). |
|
|
47
|
+
| `user` | — | `{ id, traits?, account? }` to identify immediately. |
|
|
48
|
+
| `fetch` | global | Custom `fetch` (tests, polyfills). |
|
|
49
|
+
| `disableAuthoring` | `false` | Ignore `?guidely_authoring=` in the URL. |
|
|
50
|
+
|
|
51
|
+
## API
|
|
52
|
+
|
|
53
|
+
All methods are safe to call at any time; failures are reported through `onError` / the `error`
|
|
54
|
+
event, never thrown into the host application.
|
|
55
|
+
|
|
56
|
+
| Method | Description |
|
|
57
|
+
|---|---|
|
|
58
|
+
| `init(): Promise<void>` / `ready(): Promise<void>` | Load config (cache first, then network), wire listeners, evaluate triggers. Idempotent. Resolves even when the API is unreachable (cached config is used; an `error` event is emitted). |
|
|
59
|
+
| `identify(userId, traits?, account?)` | POST `/sdk/identify`; merges server state (audiences, guide history, checklist progress, submitted surveys). Local state wins when both exist. Re-evaluates triggers (`segment_enter`, targeting). |
|
|
60
|
+
| `setAccount({ id, traits? })` | Sets the account for the current user and re-identifies. |
|
|
61
|
+
| `updateTraits(traits)` | Merges traits and re-identifies. |
|
|
62
|
+
| `reset()` | New anonymous id, cleared user and local state, new session; triggers re-evaluated. |
|
|
63
|
+
| `track(name, properties?)` | Custom event. Drives `event` triggers, `advanceOn: "event"` steps and checklist tasks (`completion: "event"`). Keys matching `SENSITIVE_PROPERTY_PATTERN` are stripped. |
|
|
64
|
+
| `page(url?)` | Records a `page_view` and re-evaluates triggers. Called automatically on SPA navigation (History API patch + `popstate` + `hashchange`); adapters call it explicitly too. |
|
|
65
|
+
| `setConsent("granted" \| "denied" \| "pending")` | Runtime consent changes. |
|
|
66
|
+
| `startGuide(idOrKey, { stepId? })` | Starts a guide regardless of targeting/frequency, replacing any active guide. Checklists open their panel. Returns `false` for unknown guides. |
|
|
67
|
+
| `stopGuide()` | Removes the active guide silently (no dismiss event). |
|
|
68
|
+
| `dismissGuide()` | Dismisses the active guide (records `guide_dismissed`). |
|
|
69
|
+
| `getActiveGuide(): PublishedGuide \| null` | The exclusive guide currently showing. |
|
|
70
|
+
| `getGuides(): readonly PublishedGuide[]` | Published guides for this environment. |
|
|
71
|
+
| `isGuideCompleted(idOrKey)` | From merged local + server state. |
|
|
72
|
+
| `getChecklistProgress(idOrKey)` | `{ completedTaskIds, completedAt, dismissedAt }`. |
|
|
73
|
+
| `completeChecklistTask(idOrKey, taskId)` | Manual completion; syncs to `/sdk/checklists/:id/progress`. |
|
|
74
|
+
| `openChecklist(idOrKey)` / `closeChecklist(idOrKey)` | Show/hide the checklist panel (re-renders a dismissed checklist). |
|
|
75
|
+
| `openResourceCenter()` / `closeResourceCenter()` | Toggle the resource center panel. |
|
|
76
|
+
| `refresh()` | Re-fetch config now. |
|
|
77
|
+
| `on(event, cb): () => void` / `off(event, cb)` | Subscribe to events (below). |
|
|
78
|
+
| `getContext()` | The `TargetingContext` used for rule evaluation (debugging). |
|
|
79
|
+
| `getState()` | Debug snapshot: ready flag, ids, config version, active/queued guides, widgets, state, pending events. |
|
|
80
|
+
| `destroy()` | Full cleanup: guides, widgets, listeners, timers, the `#guidely-root` host; flushes pending events via `sendBeacon`. A new client can be created afterwards. |
|
|
81
|
+
| `GuidelyClient.init(options)` / `GuidelyClient.get()` | Singleton helpers used by the embed (`window.Guidely.init/get`). |
|
|
82
|
+
|
|
83
|
+
### Events
|
|
84
|
+
|
|
85
|
+
`ready(config)`, `config(config)`, `guide:start(guide)`, `guide:step({ guide, stepId, stepIndex })`,
|
|
86
|
+
`guide:complete(guide)`, `guide:dismiss(guide)`, `guide:skip(guide)`,
|
|
87
|
+
`checklist:task({ guide, task, progress })`, `checklist:complete(guide)`,
|
|
88
|
+
`survey:submit({ guide, answers, responseId })`, `resource-center:open()`, `error(Error)`,
|
|
89
|
+
`track(sdkEvent)`, `identify({ userId, anonymousId })`, `authoring({ active })`.
|
|
90
|
+
|
|
91
|
+
## Behaviour
|
|
92
|
+
|
|
93
|
+
* **Config**: `GET /api/v1/sdk/config?key=…` with `If-None-Match`; the last good response is cached
|
|
94
|
+
in storage (`guidely:config:<key>`) and used when offline. Refreshed every `configRefreshMs` and on `refresh()`.
|
|
95
|
+
* **Events**: queued in memory + storage (max 200, oldest dropped), deduped by `eventId`, flushed in
|
|
96
|
+
batches of ≤50 every 2s, on navigation and on `visibilitychange`/`pagehide` (via `sendBeacon`,
|
|
97
|
+
falling back to `fetch`). Failed batches retry with exponential backoff (1s → 30s, 5 attempts)
|
|
98
|
+
and stay queued afterwards.
|
|
99
|
+
* **Triggers**: `page_load`, `url_match`, `event`, `element_click` (delegated capture listener),
|
|
100
|
+
`element_visible` (IntersectionObserver), `delay`, `after_guide`, `segment_enter`, `manual`.
|
|
101
|
+
Filtered by `urlPatterns`, `trigger.urlPattern`, targeting rules (`rolloutSalt = guide.id`),
|
|
102
|
+
frequency (`once`, `once_per_session`, `every_time`, `interval`, `maxImpressions`,
|
|
103
|
+
`cooldownHours`, `reshowAfterDismiss`) and survey `startAt`/`endAt`.
|
|
104
|
+
* **Exclusivity**: one flow/modal/tooltip/survey at a time, lowest `priority` first,
|
|
105
|
+
`mutuallyExclusiveWith` respected; banners, checklists, hotspot-only guides and the resource
|
|
106
|
+
center coexist. Remaining eligible guides queue and show after the active one ends (page-scoped
|
|
107
|
+
triggers are dropped if the page changed).
|
|
108
|
+
* **Multi-page flows**: `step.url` steps wait for navigation; the active step is persisted in
|
|
109
|
+
`sessionStorage` (`guidely:active`) so full page loads resume the guide.
|
|
110
|
+
* **Server sync** (fire-and-forget with retries): `POST /sdk/guide-state`,
|
|
111
|
+
`POST /sdk/checklists/:id/progress`, `POST /sdk/surveys/:id/responses`,
|
|
112
|
+
`GET /sdk/resource-center/search?q=`.
|
|
113
|
+
|
|
114
|
+
## Authoring mode
|
|
115
|
+
|
|
116
|
+
When the URL contains `?guidely_authoring=<token>` the SDK:
|
|
117
|
+
|
|
118
|
+
1. Strips the parameter (`history.replaceState`) and stores `{ token }` in
|
|
119
|
+
`sessionStorage["guidely:authoring"]` so SPA navigations keep authoring active.
|
|
120
|
+
2. Calls `GET /sdk/authoring/session?token=` and, when valid, starts the picker from
|
|
121
|
+
`@guidelytech/guide-runtime` (toolbar, hover outline, click-to-pick) and a 15s heartbeat
|
|
122
|
+
(`POST /sdk/authoring/session/heartbeat?token=`).
|
|
123
|
+
3. Sends each pick as `window.opener.postMessage({ type: "guidely:pick", sessionId, pick }, dashboardOrigin)`
|
|
124
|
+
**and** `POST /sdk/authoring/session/picks?token=`.
|
|
125
|
+
|
|
126
|
+
Messages accepted from `dashboardOrigin` (`event.origin` checked):
|
|
127
|
+
|
|
128
|
+
| `type` | Payload | Effect |
|
|
129
|
+
|---|---|---|
|
|
130
|
+
| `guidely:preview-step` | `{ step, theme?, appearance? }` | Renders the draft step live (target fallback → modal). |
|
|
131
|
+
| `guidely:preview-guide` | `{ guide: { id?, key?, name?, kind?, version?, config } }` | Runs the draft guide. |
|
|
132
|
+
| `guidely:highlight` | `{ selectors }` | Outlines matches, replies `guidely:highlight-result { counts, resolved }`. |
|
|
133
|
+
| `guidely:stop-preview` | — | Removes the preview. |
|
|
134
|
+
| `guidely:ping` | — | Replies `guidely:pong { url }`. |
|
|
135
|
+
| `guidely:exit` | — | Leaves authoring mode. |
|
|
136
|
+
|
|
137
|
+
Messages posted to the opener: `guidely:authoring-ready { sessionId, url }`, `guidely:pick`,
|
|
138
|
+
`guidely:highlight-result`, `guidely:preview-ended { reason }`, `guidely:pong`, `guidely:exit`.
|
|
139
|
+
|
|
140
|
+
## Storage keys
|
|
141
|
+
|
|
142
|
+
`guidely:anon`, `guidely:seen`, `guidely:config:<key>`, `guidely:etag:<key>`, `guidely:state:<key>`,
|
|
143
|
+
`guidely:user:<key>`, `guidely:queue:<key>` (local/session storage per `storage` option);
|
|
144
|
+
`guidely:session`, `guidely:active`, `guidely:authoring` (sessionStorage).
|
|
145
|
+
|
|
146
|
+
## Bundle size
|
|
147
|
+
|
|
148
|
+
`pnpm --filter @guidelytech/sdk-core size` builds a minified ESM bundle and prints gzip sizes:
|
|
149
|
+
|
|
150
|
+
| Bundle | minified | min+gz |
|
|
151
|
+
|---|---|---|
|
|
152
|
+
| sdk-core + guide-runtime + floating-ui + `@guidelytech/shared/runtime` (everything an app ships) | 115 kB | **35.8 kB** |
|
|
153
|
+
| script-tag build `guidely.js` (authoring schemas inlined) | 215 kB | 62 kB |
|
|
154
|
+
|
|
155
|
+
The SDK imports only the zod-free `@guidelytech/shared/runtime` entry; the Zod schemas are loaded
|
|
156
|
+
lazily and only when the page enters authoring mode. Budget: 45 kB min+gz for the npm runtime.
|