@guidelytech/react 0.0.0-stage → 0.2.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 CHANGED
@@ -1,3 +1,39 @@
1
- # Temporary Holding Version
1
+ # @guidelytech/react
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ React provider and hooks for Guidely. Wraps `@guidelytech/sdk-core`; works with React 18/19, SSR and
4
+ Strict Mode.
5
+
6
+ ```bash
7
+ pnpm add @guidelytech/react
8
+ ```
9
+
10
+ ```tsx
11
+ import { GuidelyProvider, useGuidely } from "@guidelytech/react";
12
+
13
+ export function App({ children }) {
14
+ return (
15
+ <GuidelyProvider projectId="pk_dev_…" apiUrl="http://localhost:3000" user={{ id: "u1", traits: { role: "admin" } }}>
16
+ {children}
17
+ </GuidelyProvider>
18
+ );
19
+ }
20
+
21
+ function HelpMenu() {
22
+ const guidely = useGuidely();
23
+ return <button onClick={() => guidely.startGuide("new-user-onboarding")}>Restart tour</button>;
24
+ }
25
+ ```
26
+
27
+ | Export | Description |
28
+ |---|---|
29
+ | `GuidelyProvider` | Accepts every `GuidelyOptions` field plus `user?: { id, traits?, account? }` and `children`. Creates the client inside an effect (never during SSR), destroys it on unmount; Strict Mode's double invoke yields exactly one live client. Changing `projectId`/`environment`/`apiUrl` recreates the client; changing `user` re-identifies (`undefined` resets). |
30
+ | `useGuidely()` | The client, or a no-op proxy on the server / before mount (methods return `false`, `[]`, `null` or resolved promises). |
31
+ | `useGuidelyReady()` | `true` once config is loaded. |
32
+ | `useGuidelyIdentify(userId, traits?, account?)` | Effect helper that identifies when the arguments change. |
33
+ | `useGuidelyEvent(event, handler)` | Subscribes for the component lifetime (latest handler is used). |
34
+ | `useChecklistProgress(idOrKey)` | Live `{ completedTaskIds, completedAt, dismissedAt }`. |
35
+ | `useGuideState(idOrKey)` | Live `{ active, completed, stepId, stepIndex, guide }`. |
36
+ | `noopClient` | The no-op client instance. |
37
+
38
+ Types re-exported: `GuidelyClient`, `GuidelyOptions`, `GuidelyEvents`, `GuidelyUser`,
39
+ `ChecklistProgressState`, `PublishedGuide`, `GuideState`, `GuidelyProviderProps`.
package/dist/index.cjs ADDED
@@ -0,0 +1,165 @@
1
+ "use client";
2
+ "use strict";
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+
21
+ // src/index.tsx
22
+ var index_exports = {};
23
+ __export(index_exports, {
24
+ GuidelyProvider: () => GuidelyProvider,
25
+ noopClient: () => noopClient,
26
+ useChecklistProgress: () => useChecklistProgress,
27
+ useGuideState: () => useGuideState,
28
+ useGuidely: () => useGuidely,
29
+ useGuidelyEvent: () => useGuidelyEvent,
30
+ useGuidelyIdentify: () => useGuidelyIdentify,
31
+ useGuidelyReady: () => useGuidelyReady
32
+ });
33
+ module.exports = __toCommonJS(index_exports);
34
+ var import_sdk_core = require("@guidelytech/sdk-core");
35
+ var import_react = require("react");
36
+ var import_jsx_runtime = require("react/jsx-runtime");
37
+ var GuidelyContext = (0, import_react.createContext)(null);
38
+ function GuidelyProvider({ children, user, ...options }) {
39
+ const [client, setClient] = (0, import_react.useState)(null);
40
+ const optionsRef = (0, import_react.useRef)(options);
41
+ optionsRef.current = options;
42
+ const { projectId, environment, apiUrl } = options;
43
+ (0, import_react.useEffect)(() => {
44
+ if (typeof window === "undefined" || !projectId) return;
45
+ const c = (0, import_sdk_core.createGuidely)({ ...optionsRef.current, projectId, environment, apiUrl });
46
+ setClient(c);
47
+ return () => {
48
+ c.destroy();
49
+ setClient((cur) => cur === c ? null : cur);
50
+ };
51
+ }, [projectId, environment, apiUrl]);
52
+ const userKey = user ? JSON.stringify([user.id, user.traits ?? null, user.account ?? null]) : "";
53
+ const hadUser = (0, import_react.useRef)(false);
54
+ (0, import_react.useEffect)(() => {
55
+ if (!client) return;
56
+ if (user && user.id) {
57
+ hadUser.current = true;
58
+ void client.identify(user.id, user.traits, user.account);
59
+ } else if (hadUser.current) {
60
+ hadUser.current = false;
61
+ client.reset();
62
+ }
63
+ }, [client, userKey]);
64
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(GuidelyContext.Provider, { value: client, children });
65
+ }
66
+ var NOOP_RESULTS = {
67
+ init: Promise.resolve(),
68
+ ready: Promise.resolve(),
69
+ identify: Promise.resolve(),
70
+ setAccount: Promise.resolve(),
71
+ updateTraits: Promise.resolve(),
72
+ refresh: Promise.resolve(),
73
+ startGuide: false,
74
+ getActiveGuide: null,
75
+ getGuides: [],
76
+ getChecklistProgress: { completedTaskIds: [], completedAt: null, dismissedAt: null },
77
+ isGuideCompleted: false,
78
+ on: () => {
79
+ },
80
+ getState: { ready: false, destroyed: false },
81
+ getContext: null
82
+ };
83
+ var noopClient = new Proxy({}, {
84
+ get(_target, prop) {
85
+ if (prop === "options") return { projectId: "" };
86
+ if (typeof prop !== "string") return void 0;
87
+ return () => NOOP_RESULTS[prop];
88
+ }
89
+ });
90
+ function useGuidely() {
91
+ return (0, import_react.useContext)(GuidelyContext) ?? noopClient;
92
+ }
93
+ function useGuidelyReady() {
94
+ const client = (0, import_react.useContext)(GuidelyContext);
95
+ const [ready, setReady] = (0, import_react.useState)(false);
96
+ (0, import_react.useEffect)(() => {
97
+ if (!client) {
98
+ setReady(false);
99
+ return;
100
+ }
101
+ if (client.getState().ready) setReady(true);
102
+ return client.on("ready", () => setReady(true));
103
+ }, [client]);
104
+ return ready;
105
+ }
106
+ function useGuidelyIdentify(userId, traits, account) {
107
+ const client = (0, import_react.useContext)(GuidelyContext);
108
+ const key = JSON.stringify([userId ?? null, traits ?? null, account ?? null]);
109
+ (0, import_react.useEffect)(() => {
110
+ if (!client || !userId) return;
111
+ void client.identify(userId, traits, account);
112
+ }, [client, key]);
113
+ }
114
+ function useGuidelyEvent(event, handler) {
115
+ const client = (0, import_react.useContext)(GuidelyContext);
116
+ const ref = (0, import_react.useRef)(handler);
117
+ ref.current = handler;
118
+ (0, import_react.useEffect)(() => {
119
+ if (!client) return;
120
+ const cb = ((...args) => ref.current(...args));
121
+ return client.on(event, cb);
122
+ }, [client, event]);
123
+ }
124
+ function useChecklistProgress(idOrKey) {
125
+ const client = (0, import_react.useContext)(GuidelyContext);
126
+ const [progress, setProgress] = (0, import_react.useState)({ completedTaskIds: [], completedAt: null, dismissedAt: null });
127
+ (0, import_react.useEffect)(() => {
128
+ if (!client) return;
129
+ const update = () => setProgress(client.getChecklistProgress(idOrKey));
130
+ update();
131
+ const offs = [client.on("ready", update), client.on("identify", update), client.on("checklist:task", update), client.on("checklist:complete", update)];
132
+ return () => offs.forEach((off) => off());
133
+ }, [client, idOrKey]);
134
+ return progress;
135
+ }
136
+ function useGuideState(idOrKey) {
137
+ const client = (0, import_react.useContext)(GuidelyContext);
138
+ const [state, setState] = (0, import_react.useState)({ active: false, completed: false, stepId: null, stepIndex: -1, guide: null });
139
+ (0, import_react.useEffect)(() => {
140
+ if (!client) return;
141
+ const matches = (g) => g.id === idOrKey || g.key === idOrKey;
142
+ const compute = () => {
143
+ const guide = client.getGuides().find(matches) ?? null;
144
+ const active = client.getActiveGuide();
145
+ const s = client.getState().activeGuide;
146
+ setState({ active: !!active && matches(active), completed: client.isGuideCompleted(idOrKey), stepId: active && matches(active) ? s?.stepId ?? null : null, stepIndex: active && matches(active) ? s?.stepIndex ?? -1 : -1, guide });
147
+ };
148
+ compute();
149
+ const offs = ["ready", "identify", "guide:start", "guide:step", "guide:complete", "guide:dismiss", "guide:skip"].map((e) => client.on(e, compute));
150
+ return () => offs.forEach((off) => off());
151
+ }, [client, idOrKey]);
152
+ return state;
153
+ }
154
+ // Annotate the CommonJS export names for ESM import in node:
155
+ 0 && (module.exports = {
156
+ GuidelyProvider,
157
+ noopClient,
158
+ useChecklistProgress,
159
+ useGuideState,
160
+ useGuidely,
161
+ useGuidelyEvent,
162
+ useGuidelyIdentify,
163
+ useGuidelyReady
164
+ });
165
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.tsx"],"sourcesContent":["import { createGuidely, type ChecklistProgressState, type GuidelyClient, type GuidelyEvents, type GuidelyOptions, type GuidelyUser, type PublishedGuide } from \"@guidelytech/sdk-core\";\nimport { createContext, useContext, useEffect, useRef, useState, type ReactNode } from \"react\";\n\nexport type { GuidelyClient, GuidelyOptions, GuidelyEvents, GuidelyUser, ChecklistProgressState, PublishedGuide } from \"@guidelytech/sdk-core\";\n\nconst GuidelyContext = createContext<GuidelyClient | null>(null);\n\nexport interface GuidelyProviderProps extends Omit<GuidelyOptions, \"user\"> {\n /** Identify this user as soon as the client is ready; `undefined` resets the identity. */\n user?: GuidelyUser | null;\n children?: ReactNode;\n}\n\n/**\n * Creates one Guidely client for the subtree. The client is created inside an effect (never\n * during SSR) and destroyed on unmount, so React Strict Mode's double-invoke is harmless.\n */\nexport function GuidelyProvider({ children, user, ...options }: GuidelyProviderProps) {\n const [client, setClient] = useState<GuidelyClient | null>(null);\n const optionsRef = useRef(options);\n optionsRef.current = options;\n const { projectId, environment, apiUrl } = options;\n\n useEffect(() => {\n if (typeof window === \"undefined\" || !projectId) return;\n const c = createGuidely({ ...optionsRef.current, projectId, environment, apiUrl });\n setClient(c);\n return () => {\n c.destroy();\n setClient((cur) => (cur === c ? null : cur));\n };\n }, [projectId, environment, apiUrl]);\n\n const userKey = user ? JSON.stringify([user.id, user.traits ?? null, user.account ?? null]) : \"\";\n const hadUser = useRef(false);\n useEffect(() => {\n if (!client) return;\n if (user && user.id) {\n hadUser.current = true;\n void client.identify(user.id, user.traits, user.account);\n } else if (hadUser.current) {\n hadUser.current = false;\n client.reset();\n }\n }, [client, userKey]);\n\n return <GuidelyContext.Provider value={client}>{children}</GuidelyContext.Provider>;\n}\n\nconst NOOP_RESULTS: Record<string, unknown> = {\n init: Promise.resolve(),\n ready: Promise.resolve(),\n identify: Promise.resolve(),\n setAccount: Promise.resolve(),\n updateTraits: Promise.resolve(),\n refresh: Promise.resolve(),\n startGuide: false,\n getActiveGuide: null,\n getGuides: [],\n getChecklistProgress: { completedTaskIds: [], completedAt: null, dismissedAt: null },\n isGuideCompleted: false,\n on: () => {},\n getState: { ready: false, destroyed: false },\n getContext: null,\n};\n\n/** A client that ignores every call; returned by `useGuidely()` on the server and before the provider mounts. */\nexport const noopClient: GuidelyClient = new Proxy({} as GuidelyClient, {\n get(_target, prop) {\n if (prop === \"options\") return { projectId: \"\" };\n if (typeof prop !== \"string\") return undefined;\n return () => NOOP_RESULTS[prop];\n },\n});\n\n/** The Guidely client, or a no-op client during SSR / before the provider has mounted. */\nexport function useGuidely(): GuidelyClient {\n return useContext(GuidelyContext) ?? noopClient;\n}\n\n/** True once the client has loaded its configuration. */\nexport function useGuidelyReady(): boolean {\n const client = useContext(GuidelyContext);\n const [ready, setReady] = useState(false);\n useEffect(() => {\n if (!client) {\n setReady(false);\n return;\n }\n if (client.getState().ready) setReady(true);\n return client.on(\"ready\", () => setReady(true));\n }, [client]);\n return ready;\n}\n\n/** Identifies the user whenever the arguments change. */\nexport function useGuidelyIdentify(userId: string | null | undefined, traits?: Record<string, unknown>, account?: GuidelyUser[\"account\"]): void {\n const client = useContext(GuidelyContext);\n const key = JSON.stringify([userId ?? null, traits ?? null, account ?? null]);\n useEffect(() => {\n if (!client || !userId) return;\n void client.identify(userId, traits, account);\n }, [client, key]);\n}\n\n/** Subscribes to a client event for the lifetime of the component. */\nexport function useGuidelyEvent<K extends keyof GuidelyEvents>(event: K, handler: GuidelyEvents[K]): void {\n const client = useContext(GuidelyContext);\n const ref = useRef(handler);\n ref.current = handler;\n useEffect(() => {\n if (!client) return;\n const cb = ((...args: unknown[]) => (ref.current as (...a: unknown[]) => void)(...args)) as GuidelyEvents[K];\n return client.on(event, cb);\n }, [client, event]);\n}\n\n/** Live checklist progress for a checklist guide (by id or key). */\nexport function useChecklistProgress(idOrKey: string): ChecklistProgressState {\n const client = useContext(GuidelyContext);\n const [progress, setProgress] = useState<ChecklistProgressState>({ completedTaskIds: [], completedAt: null, dismissedAt: null });\n useEffect(() => {\n if (!client) return;\n const update = () => setProgress(client.getChecklistProgress(idOrKey));\n update();\n const offs = [client.on(\"ready\", update), client.on(\"identify\", update), client.on(\"checklist:task\", update), client.on(\"checklist:complete\", update)];\n return () => offs.forEach((off) => off());\n }, [client, idOrKey]);\n return progress;\n}\n\nexport interface GuideState {\n /** The guide is currently showing. */\n active: boolean;\n completed: boolean;\n stepId: string | null;\n stepIndex: number;\n guide: PublishedGuide | null;\n}\n\n/** Live state of a guide (by id or key): active, completed, current step. */\nexport function useGuideState(idOrKey: string): GuideState {\n const client = useContext(GuidelyContext);\n const [state, setState] = useState<GuideState>({ active: false, completed: false, stepId: null, stepIndex: -1, guide: null });\n useEffect(() => {\n if (!client) return;\n const matches = (g: PublishedGuide) => g.id === idOrKey || g.key === idOrKey;\n const compute = () => {\n const guide = client.getGuides().find(matches) ?? null;\n const active = client.getActiveGuide();\n const s = client.getState().activeGuide;\n setState({ active: !!active && matches(active), completed: client.isGuideCompleted(idOrKey), stepId: active && matches(active) ? ((s as { stepId?: string | null } | null)?.stepId ?? null) : null, stepIndex: active && matches(active) ? ((s as { stepIndex?: number } | null)?.stepIndex ?? -1) : -1, guide });\n };\n compute();\n const offs = ([\"ready\", \"identify\", \"guide:start\", \"guide:step\", \"guide:complete\", \"guide:dismiss\", \"guide:skip\"] as const).map((e) => client.on(e, compute));\n return () => offs.forEach((off) => off());\n }, [client, idOrKey]);\n return state;\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,39 @@
1
+ import * as react from 'react';
2
+ import { ReactNode } from 'react';
3
+ import { PublishedGuide, GuidelyOptions, GuidelyUser, GuidelyClient, ChecklistProgressState, GuidelyEvents } from '@guidelytech/sdk-core';
4
+ export { ChecklistProgressState, GuidelyClient, GuidelyEvents, GuidelyOptions, GuidelyUser, PublishedGuide } from '@guidelytech/sdk-core';
5
+
6
+ interface GuidelyProviderProps extends Omit<GuidelyOptions, "user"> {
7
+ /** Identify this user as soon as the client is ready; `undefined` resets the identity. */
8
+ user?: GuidelyUser | null;
9
+ children?: ReactNode;
10
+ }
11
+ /**
12
+ * Creates one Guidely client for the subtree. The client is created inside an effect (never
13
+ * during SSR) and destroyed on unmount, so React Strict Mode's double-invoke is harmless.
14
+ */
15
+ declare function GuidelyProvider({ children, user, ...options }: GuidelyProviderProps): react.JSX.Element;
16
+ /** A client that ignores every call; returned by `useGuidely()` on the server and before the provider mounts. */
17
+ declare const noopClient: GuidelyClient;
18
+ /** The Guidely client, or a no-op client during SSR / before the provider has mounted. */
19
+ declare function useGuidely(): GuidelyClient;
20
+ /** True once the client has loaded its configuration. */
21
+ declare function useGuidelyReady(): boolean;
22
+ /** Identifies the user whenever the arguments change. */
23
+ declare function useGuidelyIdentify(userId: string | null | undefined, traits?: Record<string, unknown>, account?: GuidelyUser["account"]): void;
24
+ /** Subscribes to a client event for the lifetime of the component. */
25
+ declare function useGuidelyEvent<K extends keyof GuidelyEvents>(event: K, handler: GuidelyEvents[K]): void;
26
+ /** Live checklist progress for a checklist guide (by id or key). */
27
+ declare function useChecklistProgress(idOrKey: string): ChecklistProgressState;
28
+ interface GuideState {
29
+ /** The guide is currently showing. */
30
+ active: boolean;
31
+ completed: boolean;
32
+ stepId: string | null;
33
+ stepIndex: number;
34
+ guide: PublishedGuide | null;
35
+ }
36
+ /** Live state of a guide (by id or key): active, completed, current step. */
37
+ declare function useGuideState(idOrKey: string): GuideState;
38
+
39
+ export { type GuideState, GuidelyProvider, type GuidelyProviderProps, noopClient, useChecklistProgress, useGuideState, useGuidely, useGuidelyEvent, useGuidelyIdentify, useGuidelyReady };
@@ -0,0 +1,39 @@
1
+ import * as react from 'react';
2
+ import { ReactNode } from 'react';
3
+ import { PublishedGuide, GuidelyOptions, GuidelyUser, GuidelyClient, ChecklistProgressState, GuidelyEvents } from '@guidelytech/sdk-core';
4
+ export { ChecklistProgressState, GuidelyClient, GuidelyEvents, GuidelyOptions, GuidelyUser, PublishedGuide } from '@guidelytech/sdk-core';
5
+
6
+ interface GuidelyProviderProps extends Omit<GuidelyOptions, "user"> {
7
+ /** Identify this user as soon as the client is ready; `undefined` resets the identity. */
8
+ user?: GuidelyUser | null;
9
+ children?: ReactNode;
10
+ }
11
+ /**
12
+ * Creates one Guidely client for the subtree. The client is created inside an effect (never
13
+ * during SSR) and destroyed on unmount, so React Strict Mode's double-invoke is harmless.
14
+ */
15
+ declare function GuidelyProvider({ children, user, ...options }: GuidelyProviderProps): react.JSX.Element;
16
+ /** A client that ignores every call; returned by `useGuidely()` on the server and before the provider mounts. */
17
+ declare const noopClient: GuidelyClient;
18
+ /** The Guidely client, or a no-op client during SSR / before the provider has mounted. */
19
+ declare function useGuidely(): GuidelyClient;
20
+ /** True once the client has loaded its configuration. */
21
+ declare function useGuidelyReady(): boolean;
22
+ /** Identifies the user whenever the arguments change. */
23
+ declare function useGuidelyIdentify(userId: string | null | undefined, traits?: Record<string, unknown>, account?: GuidelyUser["account"]): void;
24
+ /** Subscribes to a client event for the lifetime of the component. */
25
+ declare function useGuidelyEvent<K extends keyof GuidelyEvents>(event: K, handler: GuidelyEvents[K]): void;
26
+ /** Live checklist progress for a checklist guide (by id or key). */
27
+ declare function useChecklistProgress(idOrKey: string): ChecklistProgressState;
28
+ interface GuideState {
29
+ /** The guide is currently showing. */
30
+ active: boolean;
31
+ completed: boolean;
32
+ stepId: string | null;
33
+ stepIndex: number;
34
+ guide: PublishedGuide | null;
35
+ }
36
+ /** Live state of a guide (by id or key): active, completed, current step. */
37
+ declare function useGuideState(idOrKey: string): GuideState;
38
+
39
+ export { type GuideState, GuidelyProvider, type GuidelyProviderProps, noopClient, useChecklistProgress, useGuideState, useGuidely, useGuidelyEvent, useGuidelyIdentify, useGuidelyReady };
package/dist/index.js ADDED
@@ -0,0 +1,134 @@
1
+ "use client";
2
+
3
+ // src/index.tsx
4
+ import { createGuidely } from "@guidelytech/sdk-core";
5
+ import { createContext, useContext, useEffect, useRef, useState } from "react";
6
+ import { jsx } from "react/jsx-runtime";
7
+ var GuidelyContext = createContext(null);
8
+ function GuidelyProvider({ children, user, ...options }) {
9
+ const [client, setClient] = useState(null);
10
+ const optionsRef = useRef(options);
11
+ optionsRef.current = options;
12
+ const { projectId, environment, apiUrl } = options;
13
+ useEffect(() => {
14
+ if (typeof window === "undefined" || !projectId) return;
15
+ const c = createGuidely({ ...optionsRef.current, projectId, environment, apiUrl });
16
+ setClient(c);
17
+ return () => {
18
+ c.destroy();
19
+ setClient((cur) => cur === c ? null : cur);
20
+ };
21
+ }, [projectId, environment, apiUrl]);
22
+ const userKey = user ? JSON.stringify([user.id, user.traits ?? null, user.account ?? null]) : "";
23
+ const hadUser = useRef(false);
24
+ useEffect(() => {
25
+ if (!client) return;
26
+ if (user && user.id) {
27
+ hadUser.current = true;
28
+ void client.identify(user.id, user.traits, user.account);
29
+ } else if (hadUser.current) {
30
+ hadUser.current = false;
31
+ client.reset();
32
+ }
33
+ }, [client, userKey]);
34
+ return /* @__PURE__ */ jsx(GuidelyContext.Provider, { value: client, children });
35
+ }
36
+ var NOOP_RESULTS = {
37
+ init: Promise.resolve(),
38
+ ready: Promise.resolve(),
39
+ identify: Promise.resolve(),
40
+ setAccount: Promise.resolve(),
41
+ updateTraits: Promise.resolve(),
42
+ refresh: Promise.resolve(),
43
+ startGuide: false,
44
+ getActiveGuide: null,
45
+ getGuides: [],
46
+ getChecklistProgress: { completedTaskIds: [], completedAt: null, dismissedAt: null },
47
+ isGuideCompleted: false,
48
+ on: () => {
49
+ },
50
+ getState: { ready: false, destroyed: false },
51
+ getContext: null
52
+ };
53
+ var noopClient = new Proxy({}, {
54
+ get(_target, prop) {
55
+ if (prop === "options") return { projectId: "" };
56
+ if (typeof prop !== "string") return void 0;
57
+ return () => NOOP_RESULTS[prop];
58
+ }
59
+ });
60
+ function useGuidely() {
61
+ return useContext(GuidelyContext) ?? noopClient;
62
+ }
63
+ function useGuidelyReady() {
64
+ const client = useContext(GuidelyContext);
65
+ const [ready, setReady] = useState(false);
66
+ useEffect(() => {
67
+ if (!client) {
68
+ setReady(false);
69
+ return;
70
+ }
71
+ if (client.getState().ready) setReady(true);
72
+ return client.on("ready", () => setReady(true));
73
+ }, [client]);
74
+ return ready;
75
+ }
76
+ function useGuidelyIdentify(userId, traits, account) {
77
+ const client = useContext(GuidelyContext);
78
+ const key = JSON.stringify([userId ?? null, traits ?? null, account ?? null]);
79
+ useEffect(() => {
80
+ if (!client || !userId) return;
81
+ void client.identify(userId, traits, account);
82
+ }, [client, key]);
83
+ }
84
+ function useGuidelyEvent(event, handler) {
85
+ const client = useContext(GuidelyContext);
86
+ const ref = useRef(handler);
87
+ ref.current = handler;
88
+ useEffect(() => {
89
+ if (!client) return;
90
+ const cb = ((...args) => ref.current(...args));
91
+ return client.on(event, cb);
92
+ }, [client, event]);
93
+ }
94
+ function useChecklistProgress(idOrKey) {
95
+ const client = useContext(GuidelyContext);
96
+ const [progress, setProgress] = useState({ completedTaskIds: [], completedAt: null, dismissedAt: null });
97
+ useEffect(() => {
98
+ if (!client) return;
99
+ const update = () => setProgress(client.getChecklistProgress(idOrKey));
100
+ update();
101
+ const offs = [client.on("ready", update), client.on("identify", update), client.on("checklist:task", update), client.on("checklist:complete", update)];
102
+ return () => offs.forEach((off) => off());
103
+ }, [client, idOrKey]);
104
+ return progress;
105
+ }
106
+ function useGuideState(idOrKey) {
107
+ const client = useContext(GuidelyContext);
108
+ const [state, setState] = useState({ active: false, completed: false, stepId: null, stepIndex: -1, guide: null });
109
+ useEffect(() => {
110
+ if (!client) return;
111
+ const matches = (g) => g.id === idOrKey || g.key === idOrKey;
112
+ const compute = () => {
113
+ const guide = client.getGuides().find(matches) ?? null;
114
+ const active = client.getActiveGuide();
115
+ const s = client.getState().activeGuide;
116
+ setState({ active: !!active && matches(active), completed: client.isGuideCompleted(idOrKey), stepId: active && matches(active) ? s?.stepId ?? null : null, stepIndex: active && matches(active) ? s?.stepIndex ?? -1 : -1, guide });
117
+ };
118
+ compute();
119
+ const offs = ["ready", "identify", "guide:start", "guide:step", "guide:complete", "guide:dismiss", "guide:skip"].map((e) => client.on(e, compute));
120
+ return () => offs.forEach((off) => off());
121
+ }, [client, idOrKey]);
122
+ return state;
123
+ }
124
+ export {
125
+ GuidelyProvider,
126
+ noopClient,
127
+ useChecklistProgress,
128
+ useGuideState,
129
+ useGuidely,
130
+ useGuidelyEvent,
131
+ useGuidelyIdentify,
132
+ useGuidelyReady
133
+ };
134
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.tsx"],"sourcesContent":["import { createGuidely, type ChecklistProgressState, type GuidelyClient, type GuidelyEvents, type GuidelyOptions, type GuidelyUser, type PublishedGuide } from \"@guidelytech/sdk-core\";\nimport { createContext, useContext, useEffect, useRef, useState, type ReactNode } from \"react\";\n\nexport type { GuidelyClient, GuidelyOptions, GuidelyEvents, GuidelyUser, ChecklistProgressState, PublishedGuide } from \"@guidelytech/sdk-core\";\n\nconst GuidelyContext = createContext<GuidelyClient | null>(null);\n\nexport interface GuidelyProviderProps extends Omit<GuidelyOptions, \"user\"> {\n /** Identify this user as soon as the client is ready; `undefined` resets the identity. */\n user?: GuidelyUser | null;\n children?: ReactNode;\n}\n\n/**\n * Creates one Guidely client for the subtree. The client is created inside an effect (never\n * during SSR) and destroyed on unmount, so React Strict Mode's double-invoke is harmless.\n */\nexport function GuidelyProvider({ children, user, ...options }: GuidelyProviderProps) {\n const [client, setClient] = useState<GuidelyClient | null>(null);\n const optionsRef = useRef(options);\n optionsRef.current = options;\n const { projectId, environment, apiUrl } = options;\n\n useEffect(() => {\n if (typeof window === \"undefined\" || !projectId) return;\n const c = createGuidely({ ...optionsRef.current, projectId, environment, apiUrl });\n setClient(c);\n return () => {\n c.destroy();\n setClient((cur) => (cur === c ? null : cur));\n };\n }, [projectId, environment, apiUrl]);\n\n const userKey = user ? JSON.stringify([user.id, user.traits ?? null, user.account ?? null]) : \"\";\n const hadUser = useRef(false);\n useEffect(() => {\n if (!client) return;\n if (user && user.id) {\n hadUser.current = true;\n void client.identify(user.id, user.traits, user.account);\n } else if (hadUser.current) {\n hadUser.current = false;\n client.reset();\n }\n }, [client, userKey]);\n\n return <GuidelyContext.Provider value={client}>{children}</GuidelyContext.Provider>;\n}\n\nconst NOOP_RESULTS: Record<string, unknown> = {\n init: Promise.resolve(),\n ready: Promise.resolve(),\n identify: Promise.resolve(),\n setAccount: Promise.resolve(),\n updateTraits: Promise.resolve(),\n refresh: Promise.resolve(),\n startGuide: false,\n getActiveGuide: null,\n getGuides: [],\n getChecklistProgress: { completedTaskIds: [], completedAt: null, dismissedAt: null },\n isGuideCompleted: false,\n on: () => {},\n getState: { ready: false, destroyed: false },\n getContext: null,\n};\n\n/** A client that ignores every call; returned by `useGuidely()` on the server and before the provider mounts. */\nexport const noopClient: GuidelyClient = new Proxy({} as GuidelyClient, {\n get(_target, prop) {\n if (prop === \"options\") return { projectId: \"\" };\n if (typeof prop !== \"string\") return undefined;\n return () => NOOP_RESULTS[prop];\n },\n});\n\n/** The Guidely client, or a no-op client during SSR / before the provider has mounted. */\nexport function useGuidely(): GuidelyClient {\n return useContext(GuidelyContext) ?? noopClient;\n}\n\n/** True once the client has loaded its configuration. */\nexport function useGuidelyReady(): boolean {\n const client = useContext(GuidelyContext);\n const [ready, setReady] = useState(false);\n useEffect(() => {\n if (!client) {\n setReady(false);\n return;\n }\n if (client.getState().ready) setReady(true);\n return client.on(\"ready\", () => setReady(true));\n }, [client]);\n return ready;\n}\n\n/** Identifies the user whenever the arguments change. */\nexport function useGuidelyIdentify(userId: string | null | undefined, traits?: Record<string, unknown>, account?: GuidelyUser[\"account\"]): void {\n const client = useContext(GuidelyContext);\n const key = JSON.stringify([userId ?? null, traits ?? null, account ?? null]);\n useEffect(() => {\n if (!client || !userId) return;\n void client.identify(userId, traits, account);\n }, [client, key]);\n}\n\n/** Subscribes to a client event for the lifetime of the component. */\nexport function useGuidelyEvent<K extends keyof GuidelyEvents>(event: K, handler: GuidelyEvents[K]): void {\n const client = useContext(GuidelyContext);\n const ref = useRef(handler);\n ref.current = handler;\n useEffect(() => {\n if (!client) return;\n const cb = ((...args: unknown[]) => (ref.current as (...a: unknown[]) => void)(...args)) as GuidelyEvents[K];\n return client.on(event, cb);\n }, [client, event]);\n}\n\n/** Live checklist progress for a checklist guide (by id or key). */\nexport function useChecklistProgress(idOrKey: string): ChecklistProgressState {\n const client = useContext(GuidelyContext);\n const [progress, setProgress] = useState<ChecklistProgressState>({ completedTaskIds: [], completedAt: null, dismissedAt: null });\n useEffect(() => {\n if (!client) return;\n const update = () => setProgress(client.getChecklistProgress(idOrKey));\n update();\n const offs = [client.on(\"ready\", update), client.on(\"identify\", update), client.on(\"checklist:task\", update), client.on(\"checklist:complete\", update)];\n return () => offs.forEach((off) => off());\n }, [client, idOrKey]);\n return progress;\n}\n\nexport interface GuideState {\n /** The guide is currently showing. */\n active: boolean;\n completed: boolean;\n stepId: string | null;\n stepIndex: number;\n guide: PublishedGuide | null;\n}\n\n/** Live state of a guide (by id or key): active, completed, current step. */\nexport function useGuideState(idOrKey: string): GuideState {\n const client = useContext(GuidelyContext);\n const [state, setState] = useState<GuideState>({ active: false, completed: false, stepId: null, stepIndex: -1, guide: null });\n useEffect(() => {\n if (!client) return;\n const matches = (g: PublishedGuide) => g.id === idOrKey || g.key === idOrKey;\n const compute = () => {\n const guide = client.getGuides().find(matches) ?? null;\n const active = client.getActiveGuide();\n const s = client.getState().activeGuide;\n setState({ active: !!active && matches(active), completed: client.isGuideCompleted(idOrKey), stepId: active && matches(active) ? ((s as { stepId?: string | null } | null)?.stepId ?? null) : null, stepIndex: active && matches(active) ? ((s as { stepIndex?: number } | null)?.stepIndex ?? -1) : -1, guide });\n };\n compute();\n const offs = ([\"ready\", \"identify\", \"guide:start\", \"guide:step\", \"guide:complete\", \"guide:dismiss\", \"guide:skip\"] as const).map((e) => client.on(e, compute));\n return () => offs.forEach((off) => off());\n }, [client, idOrKey]);\n return state;\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,72 @@
1
1
  {
2
2
  "name": "@guidelytech/react",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.2.0",
4
+ "description": "React provider and hooks for Guidely",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "sideEffects": false,
8
+ "main": "./dist/index.cjs",
9
+ "module": "./dist/index.js",
10
+ "types": "./dist/index.d.ts",
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.js",
15
+ "require": "./dist/index.cjs"
16
+ }
17
+ },
18
+ "files": [
19
+ "dist",
20
+ "README.md"
21
+ ],
22
+ "dependencies": {
23
+ "@guidelytech/sdk-core": "0.2.0",
24
+ "@guidelytech/shared": "0.2.0"
25
+ },
26
+ "devDependencies": {
27
+ "tsup": "^8.5.1",
28
+ "typescript": "^5.9.3",
29
+ "vitest": "^3.2.7",
30
+ "happy-dom": "^17.6.3",
31
+ "eslint": "^9.39.5",
32
+ "@eslint/js": "^9.39.5",
33
+ "typescript-eslint": "^8.46.0",
34
+ "react": "19.1.10",
35
+ "react-dom": "19.1.10",
36
+ "@types/react": "^19.1.0",
37
+ "@types/react-dom": "^19.1.0",
38
+ "@testing-library/react": "^16.3.3"
39
+ },
40
+ "peerDependencies": {
41
+ "react": ">=18.0.0",
42
+ "react-dom": ">=18.0.0"
43
+ },
44
+ "publishConfig": {
45
+ "access": "public"
46
+ },
47
+ "repository": {
48
+ "type": "git",
49
+ "url": "git+https://github.com/parmarg/Guidely.git",
50
+ "directory": "packages/react"
51
+ },
52
+ "homepage": "https://github.com/parmarg/Guidely/tree/main/packages/react#readme",
53
+ "bugs": {
54
+ "url": "https://github.com/parmarg/Guidely/issues"
55
+ },
56
+ "keywords": [
57
+ "guidely",
58
+ "product-adoption",
59
+ "onboarding",
60
+ "product-tour",
61
+ "in-app-guidance",
62
+ "react"
63
+ ],
64
+ "scripts": {
65
+ "build": "tsup",
66
+ "dev": "tsup --watch",
67
+ "typecheck": "tsc --noEmit",
68
+ "test": "vitest run",
69
+ "lint": "eslint src",
70
+ "clean": "rm -rf dist"
71
+ }
6
72
  }