@guidelytech/svelte 0.10.0 → 0.11.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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/client-store.ts","../src/flags.ts"],"sourcesContent":["import { createGuidely as createCore, type ChecklistProgressState, type GuidelyClient, type GuidelyOptions, type GuidelyUser, type PublishedGuide } from \"@guidelytech/sdk-core\";\nimport { getContext, setContext } from \"svelte\";\nimport { derived, get, readable, type Readable } from \"svelte/store\";\nimport { guidely } from \"./client-store\";\n\nexport type { GuidelyClient, GuidelyOptions, GuidelyEvents, GuidelyUser, ChecklistProgressState, PublishedGuide } from \"@guidelytech/sdk-core\";\nexport { guidely };\nexport { flag, featureValue, flagDetails, allFlags, flagsReady, createFlags, setFlagsContext } from \"./flags\";\nexport type { FlagsSource } from \"./flags\";\nexport { createStaticFlags } from \"@guidelytech/flags\";\nexport type { FlagsClient, FlagsClientOptions, FlagDetails, FlagsBootstrap, FlagsPayload, FlagsReader, Attributes, JsonValue, EvaluationResult } from \"@guidelytech/flags\";\n\n/**\n * Creates the client and stores it in the `guidely` store. Browser-only: throws a helpful error\n * when called during SSR (call it from `onMount` or use `@guidelytech/sveltekit`'s `initGuidely`).\n */\nexport function createGuidely(options: GuidelyOptions): GuidelyClient {\n if (typeof window === \"undefined\") throw new Error(\"[Guidely] createGuidely() can only run in the browser. Call it inside onMount(), or use initGuidely() from @guidelytech/sveltekit.\");\n const existing = get(guidely);\n if (existing && !existing.getState().destroyed && existing.options.projectId === options.projectId) return existing;\n existing?.destroy();\n const client = createCore(options);\n guidely.set(client);\n if (pendingUser !== undefined) applyUser(client, pendingUser);\n pendingUser = undefined;\n return client;\n}\n\nconst appliedUser = new WeakMap<GuidelyClient, string | null>();\nlet pendingUser: GuidelyUser | null | undefined;\n\n/**\n * Keeps the Guidely user in step with your app's signed-in user. Idempotent: call it whenever your\n * user data may have changed (a `$effect` / `$:` on layout data). A user identifies (again only when\n * id, traits or account change); `null` resets a previously identified user, including one restored\n * from storage; `undefined` means \"not known yet\" and changes nothing. No-op on the server; called\n * before `createGuidely`, it is applied when the client is created.\n */\nexport function syncGuidelyUser(user: GuidelyUser | null | undefined): void {\n if (typeof window === \"undefined\") return;\n const client = get(guidely);\n if (client) applyUser(client, user);\n else pendingUser = user;\n}\n\nfunction applyUser(client: GuidelyClient, user: GuidelyUser | null | undefined): void {\n if (user === undefined) return;\n const key = user ? JSON.stringify([String(user.id), user.traits ?? null, user.account ?? null]) : null;\n if (appliedUser.has(client) && appliedUser.get(client) === key) return;\n appliedUser.set(client, key);\n if (user) void client.identify(user.id, user.traits, user.account);\n else if (client.getState().user?.id) client.reset();\n}\n\n/** Destroys the current client and clears the store. */\nexport function destroyGuidely(): void {\n get(guidely)?.destroy();\n guidely.set(null);\n}\n\nconst CONTEXT_KEY = Symbol.for(\"guidely\");\n\nexport function setGuidelyContext(client: GuidelyClient | null): void {\n setContext(CONTEXT_KEY, client);\n}\n\nexport function getGuidelyContext(): GuidelyClient | null {\n return (getContext(CONTEXT_KEY) as GuidelyClient | null | undefined) ?? get(guidely);\n}\n\nfunction fromClient<T>(initial: T, compute: (client: GuidelyClient) => T, events: Array<Parameters<GuidelyClient[\"on\"]>[0]>): Readable<T> {\n return readable<T>(initial, (set) => {\n let offs: Array<() => void> = [];\n const unsub = guidely.subscribe((client) => {\n offs.forEach((off) => off());\n offs = [];\n if (!client) return set(initial);\n const update = () => set(compute(client));\n update();\n offs = events.map((e) => client.on(e, update as never));\n });\n return () => {\n offs.forEach((off) => off());\n unsub();\n };\n });\n}\n\n/** True once the configuration has loaded. */\nexport const guidelyReady: Readable<boolean> = fromClient(false, (c) => c.getState().ready, [\"ready\"]);\n\n/** The guide currently showing (flows, modals, surveys), or null. */\nexport const activeGuide: Readable<PublishedGuide | null> = fromClient<PublishedGuide | null>(null, (c) => c.getActiveGuide(), [\"ready\", \"guide:start\", \"guide:complete\", \"guide:dismiss\", \"guide:skip\", \"identify\"]);\n\n/** Live checklist progress for a checklist guide (by id or key). */\nexport function checklistProgress(idOrKey: string): Readable<ChecklistProgressState> {\n return fromClient<ChecklistProgressState>({ completedTaskIds: [], completedAt: null, dismissedAt: null }, (c) => c.getChecklistProgress(idOrKey), [\"ready\", \"identify\", \"checklist:task\", \"checklist:complete\"]);\n}\n\n/** Is the given guide completed for the current user? */\nexport function guideCompleted(idOrKey: string): Readable<boolean> {\n return derived(fromClient<boolean>(false, (c) => c.isGuideCompleted(idOrKey), [\"ready\", \"identify\", \"guide:complete\"]), (v) => v);\n}\n\n/** `use:guideTrigger={\"guide-key\"}` — clicking the element starts the guide. */\nexport function guideTrigger(node: HTMLElement, key: string): { update(key: string): void; destroy(): void } {\n let current = key;\n const onClick = (e: Event) => {\n e.preventDefault();\n get(guidely)?.startGuide(current);\n };\n node.addEventListener(\"click\", onClick);\n node.setAttribute(\"data-guidely-trigger\", current);\n return {\n update(next: string) {\n current = next;\n node.setAttribute(\"data-guidely-trigger\", next);\n },\n destroy() {\n node.removeEventListener(\"click\", onClick);\n },\n };\n}\n\n/** `use:guidelyTarget={\"id\"}` — marks an element as a guide target (`data-tour`). No runtime behaviour. */\nexport function guidelyTarget(node: HTMLElement, id?: string): { update(id?: string): void; destroy(): void } {\n const apply = (v?: string) => {\n if (v) node.setAttribute(\"data-tour\", v);\n };\n apply(id);\n return { update: apply, destroy() {} };\n}\n","import type { GuidelyClient } from \"@guidelytech/sdk-core\";\nimport { writable } from \"svelte/store\";\n\n/** The current client (null on the server and before `createGuidely`). */\nexport const guidely = writable<GuidelyClient | null>(null);\n","import { createFlagsClient, jsonEquals, type FlagDetails, type FlagValue, type FlagsClient, type FlagsClientOptions, type FlagsReader, type JsonValue } from \"@guidelytech/flags\";\nimport type { GuidelyClient } from \"@guidelytech/sdk-core\";\nimport { getContext, setContext } from \"svelte\";\nimport { derived, readable, type Readable } from \"svelte/store\";\nimport { guidely } from \"./client-store\";\n\n/** Where flag stores read from: a Guidely client, a flags client, or a static snapshot. */\nexport type FlagsSource = GuidelyClient | FlagsReader;\n\nconst FLAGS_KEY = Symbol.for(\"guidely.flags\");\n\nfunction readerOf(source: FlagsSource | null | undefined): FlagsReader | null {\n if (!source) return null;\n return \"isFeatureEnabled\" in source && \"flags\" in source ? (source as GuidelyClient).flags : (source as FlagsReader);\n}\n\n/**\n * Makes `source` the flags for this component and its children (call during component\n * initialisation). Accepts a client, a flags client, a static snapshot or a store of one.\n */\nexport function setFlagsContext(source: FlagsSource | Readable<FlagsSource | null> | null): void {\n const store = source && \"subscribe\" in source && !(\"isEnabled\" in source) && !(\"isFeatureEnabled\" in source) ? derived(source as Readable<FlagsSource | null>, readerOf) : readable(readerOf(source as FlagsSource | null));\n setContext(FLAGS_KEY, store);\n}\n\n/** An explicit source, else the component context (`setFlagsContext` / `initGuidely`), else the global `guidely` client. */\nfunction sourceStore(source?: FlagsSource | null): Readable<FlagsReader | null> {\n if (source) return readable(readerOf(source));\n try {\n const ctx = getContext<Readable<FlagsReader | null> | undefined>(FLAGS_KEY);\n if (ctx) return ctx;\n } catch {\n /* not during component initialisation */\n }\n return derived(guidely, (c) => c?.flags ?? null);\n}\n\nfunction flagStore<T>(source: FlagsSource | null | undefined, initial: T, select: (r: FlagsReader) => T): Readable<T> {\n const src = sourceStore(source);\n return readable<T>(initial, (set) => {\n let off = () => {};\n let last: { value: T } | null = null;\n const unsub = src.subscribe((reader) => {\n off();\n off = () => {};\n if (!reader) {\n last = { value: initial };\n return set(initial);\n }\n const update = () => {\n const value = select(reader);\n if (last && jsonEquals(last.value, value)) return; // object flags keep their identity\n last = { value };\n set(value);\n };\n update();\n off = reader.subscribe(update);\n });\n return () => {\n off();\n unsub();\n };\n });\n}\n\n/** `$flag` is true when the boolean flag is on; `fallback` (default `false`) until flags load, or when missing. */\nexport function flag(key: string, fallback = false, source?: FlagsSource | null): Readable<boolean> {\n return flagStore(source, fallback, (r) => r.isEnabled(key, fallback));\n}\n\n/** A flag's value (string, number, JSON…); `fallback` when missing or of a different type. */\nexport function featureValue<T extends JsonValue>(key: string, fallback: T, source?: FlagsSource | null): Readable<FlagValue<T>> {\n return flagStore(source, fallback as FlagValue<T>, (r) => r.getValue(key, fallback));\n}\n\n/** A flag's value plus why it was served (reason, rule, variation, experiment). */\nexport function flagDetails<T extends JsonValue>(key: string, fallback: T, source?: FlagsSource | null): Readable<FlagDetails<FlagValue<T>>> {\n return flagStore<FlagDetails<FlagValue<T>>>(source, { key, value: fallback as FlagValue<T>, reason: \"FLAG_NOT_FOUND\", inExperiment: false, usedFallback: true }, (r) => r.getDetails(key, fallback));\n}\n\n/** Every flag's value (records no exposures). */\nexport function allFlags(source?: FlagsSource | null): Readable<Record<string, JsonValue>> {\n return flagStore<Record<string, JsonValue>>(source, {}, (r) => r.getAll());\n}\n\n/** True once flags have loaded (or failed to and serve fallbacks); true from the start with a bootstrap payload. */\nexport function flagsReady(source?: FlagsSource | null): Readable<boolean> {\n return flagStore(source, false, (r) => r.isReady());\n}\n\n/**\n * Feature flags only (no guides or analytics): a flags client to pass to the stores\n * (`flag(\"x\", false, flags)`) or to `setFlagsContext(flags)`. Runs in the browser and on servers.\n */\nexport function createFlags(options: FlagsClientOptions): FlagsClient {\n return createFlagsClient(options);\n}\n"],"mappings":"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","names":["import_svelte","import_store","import_store","import_flags","createCore"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/client-store.ts","../src/flags.ts"],"sourcesContent":["import { createGuidely as createCore, type ChecklistProgressState, type GuidelyClient, type GuidelyOptions, type GuidelyUser, type PublishedGuide } from \"@guidelytech/sdk-core\";\nimport { getContext, setContext } from \"svelte\";\nimport { derived, get, readable, type Readable } from \"svelte/store\";\nimport { guidely } from \"./client-store\";\n\nexport type { GuidelyClient, GuidelyOptions, GuidelyEvents, GuidelyUser, ChecklistProgressState, PublishedGuide, AgentTurnInput, AgentTurnRedactor } from \"@guidelytech/sdk-core\";\nexport { guidely };\nexport { flag, featureValue, flagDetails, allFlags, flagsReady, createFlags, setFlagsContext } from \"./flags\";\nexport type { FlagsSource } from \"./flags\";\nexport { createStaticFlags } from \"@guidelytech/flags\";\nexport type { FlagsClient, FlagsClientOptions, FlagDetails, FlagsBootstrap, FlagsPayload, FlagsReader, Attributes, JsonValue, EvaluationResult } from \"@guidelytech/flags\";\n\n/**\n * Creates the client and stores it in the `guidely` store. Browser-only: throws a helpful error\n * when called during SSR (call it from `onMount` or use `@guidelytech/sveltekit`'s `initGuidely`).\n */\nexport function createGuidely(options: GuidelyOptions): GuidelyClient {\n if (typeof window === \"undefined\") throw new Error(\"[Guidely] createGuidely() can only run in the browser. Call it inside onMount(), or use initGuidely() from @guidelytech/sveltekit.\");\n const existing = get(guidely);\n if (existing && !existing.getState().destroyed && existing.options.projectId === options.projectId) return existing;\n existing?.destroy();\n const client = createCore(options);\n guidely.set(client);\n if (pendingUser !== undefined) applyUser(client, pendingUser);\n pendingUser = undefined;\n return client;\n}\n\nconst appliedUser = new WeakMap<GuidelyClient, string | null>();\nlet pendingUser: GuidelyUser | null | undefined;\n\n/**\n * Keeps the Guidely user in step with your app's signed-in user. Idempotent: call it whenever your\n * user data may have changed (a `$effect` / `$:` on layout data). A user identifies (again only when\n * id, traits or account change); `null` resets a previously identified user, including one restored\n * from storage; `undefined` means \"not known yet\" and changes nothing. No-op on the server; called\n * before `createGuidely`, it is applied when the client is created.\n */\nexport function syncGuidelyUser(user: GuidelyUser | null | undefined): void {\n if (typeof window === \"undefined\") return;\n const client = get(guidely);\n if (client) applyUser(client, user);\n else pendingUser = user;\n}\n\nfunction applyUser(client: GuidelyClient, user: GuidelyUser | null | undefined): void {\n if (user === undefined) return;\n const key = user ? JSON.stringify([String(user.id), user.traits ?? null, user.account ?? null]) : null;\n if (appliedUser.has(client) && appliedUser.get(client) === key) return;\n appliedUser.set(client, key);\n if (user) void client.identify(user.id, user.traits, user.account);\n else if (client.getState().user?.id) client.reset();\n}\n\n/** Destroys the current client and clears the store. */\nexport function destroyGuidely(): void {\n get(guidely)?.destroy();\n guidely.set(null);\n}\n\nconst CONTEXT_KEY = Symbol.for(\"guidely\");\n\nexport function setGuidelyContext(client: GuidelyClient | null): void {\n setContext(CONTEXT_KEY, client);\n}\n\nexport function getGuidelyContext(): GuidelyClient | null {\n return (getContext(CONTEXT_KEY) as GuidelyClient | null | undefined) ?? get(guidely);\n}\n\nfunction fromClient<T>(initial: T, compute: (client: GuidelyClient) => T, events: Array<Parameters<GuidelyClient[\"on\"]>[0]>): Readable<T> {\n return readable<T>(initial, (set) => {\n let offs: Array<() => void> = [];\n const unsub = guidely.subscribe((client) => {\n offs.forEach((off) => off());\n offs = [];\n if (!client) return set(initial);\n const update = () => set(compute(client));\n update();\n offs = events.map((e) => client.on(e, update as never));\n });\n return () => {\n offs.forEach((off) => off());\n unsub();\n };\n });\n}\n\n/** True once the configuration has loaded. */\nexport const guidelyReady: Readable<boolean> = fromClient(false, (c) => c.getState().ready, [\"ready\"]);\n\n/** The guide currently showing (flows, modals, surveys), or null. */\nexport const activeGuide: Readable<PublishedGuide | null> = fromClient<PublishedGuide | null>(null, (c) => c.getActiveGuide(), [\"ready\", \"guide:start\", \"guide:complete\", \"guide:dismiss\", \"guide:skip\", \"identify\"]);\n\n/** Live checklist progress for a checklist guide (by id or key). */\nexport function checklistProgress(idOrKey: string): Readable<ChecklistProgressState> {\n return fromClient<ChecklistProgressState>({ completedTaskIds: [], completedAt: null, dismissedAt: null }, (c) => c.getChecklistProgress(idOrKey), [\"ready\", \"identify\", \"checklist:task\", \"checklist:complete\"]);\n}\n\n/** Is the given guide completed for the current user? */\nexport function guideCompleted(idOrKey: string): Readable<boolean> {\n return derived(fromClient<boolean>(false, (c) => c.isGuideCompleted(idOrKey), [\"ready\", \"identify\", \"guide:complete\"]), (v) => v);\n}\n\n/** `use:guideTrigger={\"guide-key\"}` — clicking the element starts the guide. */\nexport function guideTrigger(node: HTMLElement, key: string): { update(key: string): void; destroy(): void } {\n let current = key;\n const onClick = (e: Event) => {\n e.preventDefault();\n get(guidely)?.startGuide(current);\n };\n node.addEventListener(\"click\", onClick);\n node.setAttribute(\"data-guidely-trigger\", current);\n return {\n update(next: string) {\n current = next;\n node.setAttribute(\"data-guidely-trigger\", next);\n },\n destroy() {\n node.removeEventListener(\"click\", onClick);\n },\n };\n}\n\n/** `use:guidelyTarget={\"id\"}` — marks an element as a guide target (`data-tour`). No runtime behaviour. */\nexport function guidelyTarget(node: HTMLElement, id?: string): { update(id?: string): void; destroy(): void } {\n const apply = (v?: string) => {\n if (v) node.setAttribute(\"data-tour\", v);\n };\n apply(id);\n return { update: apply, destroy() {} };\n}\n","import type { GuidelyClient } from \"@guidelytech/sdk-core\";\nimport { writable } from \"svelte/store\";\n\n/** The current client (null on the server and before `createGuidely`). */\nexport const guidely = writable<GuidelyClient | null>(null);\n","import { createFlagsClient, jsonEquals, type FlagDetails, type FlagValue, type FlagsClient, type FlagsClientOptions, type FlagsReader, type JsonValue } from \"@guidelytech/flags\";\nimport type { GuidelyClient } from \"@guidelytech/sdk-core\";\nimport { getContext, setContext } from \"svelte\";\nimport { derived, readable, type Readable } from \"svelte/store\";\nimport { guidely } from \"./client-store\";\n\n/** Where flag stores read from: a Guidely client, a flags client, or a static snapshot. */\nexport type FlagsSource = GuidelyClient | FlagsReader;\n\nconst FLAGS_KEY = Symbol.for(\"guidely.flags\");\n\nfunction readerOf(source: FlagsSource | null | undefined): FlagsReader | null {\n if (!source) return null;\n return \"isFeatureEnabled\" in source && \"flags\" in source ? (source as GuidelyClient).flags : (source as FlagsReader);\n}\n\n/**\n * Makes `source` the flags for this component and its children (call during component\n * initialisation). Accepts a client, a flags client, a static snapshot or a store of one.\n */\nexport function setFlagsContext(source: FlagsSource | Readable<FlagsSource | null> | null): void {\n const store = source && \"subscribe\" in source && !(\"isEnabled\" in source) && !(\"isFeatureEnabled\" in source) ? derived(source as Readable<FlagsSource | null>, readerOf) : readable(readerOf(source as FlagsSource | null));\n setContext(FLAGS_KEY, store);\n}\n\n/** An explicit source, else the component context (`setFlagsContext` / `initGuidely`), else the global `guidely` client. */\nfunction sourceStore(source?: FlagsSource | null): Readable<FlagsReader | null> {\n if (source) return readable(readerOf(source));\n try {\n const ctx = getContext<Readable<FlagsReader | null> | undefined>(FLAGS_KEY);\n if (ctx) return ctx;\n } catch {\n /* not during component initialisation */\n }\n return derived(guidely, (c) => c?.flags ?? null);\n}\n\nfunction flagStore<T>(source: FlagsSource | null | undefined, initial: T, select: (r: FlagsReader) => T): Readable<T> {\n const src = sourceStore(source);\n return readable<T>(initial, (set) => {\n let off = () => {};\n let last: { value: T } | null = null;\n const unsub = src.subscribe((reader) => {\n off();\n off = () => {};\n if (!reader) {\n last = { value: initial };\n return set(initial);\n }\n const update = () => {\n const value = select(reader);\n if (last && jsonEquals(last.value, value)) return; // object flags keep their identity\n last = { value };\n set(value);\n };\n update();\n off = reader.subscribe(update);\n });\n return () => {\n off();\n unsub();\n };\n });\n}\n\n/** `$flag` is true when the boolean flag is on; `fallback` (default `false`) until flags load, or when missing. */\nexport function flag(key: string, fallback = false, source?: FlagsSource | null): Readable<boolean> {\n return flagStore(source, fallback, (r) => r.isEnabled(key, fallback));\n}\n\n/** A flag's value (string, number, JSON…); `fallback` when missing or of a different type. */\nexport function featureValue<T extends JsonValue>(key: string, fallback: T, source?: FlagsSource | null): Readable<FlagValue<T>> {\n return flagStore(source, fallback as FlagValue<T>, (r) => r.getValue(key, fallback));\n}\n\n/** A flag's value plus why it was served (reason, rule, variation, experiment). */\nexport function flagDetails<T extends JsonValue>(key: string, fallback: T, source?: FlagsSource | null): Readable<FlagDetails<FlagValue<T>>> {\n return flagStore<FlagDetails<FlagValue<T>>>(source, { key, value: fallback as FlagValue<T>, reason: \"FLAG_NOT_FOUND\", inExperiment: false, usedFallback: true }, (r) => r.getDetails(key, fallback));\n}\n\n/** Every flag's value (records no exposures). */\nexport function allFlags(source?: FlagsSource | null): Readable<Record<string, JsonValue>> {\n return flagStore<Record<string, JsonValue>>(source, {}, (r) => r.getAll());\n}\n\n/** True once flags have loaded (or failed to and serve fallbacks); true from the start with a bootstrap payload. */\nexport function flagsReady(source?: FlagsSource | null): Readable<boolean> {\n return flagStore(source, false, (r) => r.isReady());\n}\n\n/**\n * Feature flags only (no guides or analytics): a flags client to pass to the stores\n * (`flag(\"x\", false, flags)`) or to `setFlagsContext(flags)`. Runs in the browser and on servers.\n */\nexport function createFlags(options: FlagsClientOptions): FlagsClient {\n return createFlagsClient(options);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sBAAyJ;AACzJ,IAAAA,iBAAuC;AACvC,IAAAC,gBAAsD;;;ACDtD,mBAAyB;AAGlB,IAAM,cAAU,uBAA+B,IAAI;;;ACJ1D,mBAA6J;AAE7J,oBAAuC;AACvC,IAAAC,gBAAiD;AAMjD,IAAM,YAAY,uBAAO,IAAI,eAAe;AAE5C,SAAS,SAAS,QAA4D;AAC5E,MAAI,CAAC,OAAQ,QAAO;AACpB,SAAO,sBAAsB,UAAU,WAAW,SAAU,OAAyB,QAAS;AAChG;AAMO,SAAS,gBAAgB,QAAiE;AAC/F,QAAM,QAAQ,UAAU,eAAe,UAAU,EAAE,eAAe,WAAW,EAAE,sBAAsB,cAAU,uBAAQ,QAAwC,QAAQ,QAAI,wBAAS,SAAS,MAA4B,CAAC;AAC1N,gCAAW,WAAW,KAAK;AAC7B;AAGA,SAAS,YAAY,QAA2D;AAC9E,MAAI,OAAQ,YAAO,wBAAS,SAAS,MAAM,CAAC;AAC5C,MAAI;AACF,UAAM,UAAM,0BAAqD,SAAS;AAC1E,QAAI,IAAK,QAAO;AAAA,EAClB,QAAQ;AAAA,EAER;AACA,aAAO,uBAAQ,SAAS,CAAC,MAAM,GAAG,SAAS,IAAI;AACjD;AAEA,SAAS,UAAa,QAAwC,SAAY,QAA4C;AACpH,QAAM,MAAM,YAAY,MAAM;AAC9B,aAAO,wBAAY,SAAS,CAAC,QAAQ;AACnC,QAAI,MAAM,MAAM;AAAA,IAAC;AACjB,QAAI,OAA4B;AAChC,UAAM,QAAQ,IAAI,UAAU,CAAC,WAAW;AACtC,UAAI;AACJ,YAAM,MAAM;AAAA,MAAC;AACb,UAAI,CAAC,QAAQ;AACX,eAAO,EAAE,OAAO,QAAQ;AACxB,eAAO,IAAI,OAAO;AAAA,MACpB;AACA,YAAM,SAAS,MAAM;AACnB,cAAM,QAAQ,OAAO,MAAM;AAC3B,YAAI,YAAQ,yBAAW,KAAK,OAAO,KAAK,EAAG;AAC3C,eAAO,EAAE,MAAM;AACf,YAAI,KAAK;AAAA,MACX;AACA,aAAO;AACP,YAAM,OAAO,UAAU,MAAM;AAAA,IAC/B,CAAC;AACD,WAAO,MAAM;AACX,UAAI;AACJ,YAAM;AAAA,IACR;AAAA,EACF,CAAC;AACH;AAGO,SAAS,KAAK,KAAa,WAAW,OAAO,QAAgD;AAClG,SAAO,UAAU,QAAQ,UAAU,CAAC,MAAM,EAAE,UAAU,KAAK,QAAQ,CAAC;AACtE;AAGO,SAAS,aAAkC,KAAa,UAAa,QAAqD;AAC/H,SAAO,UAAU,QAAQ,UAA0B,CAAC,MAAM,EAAE,SAAS,KAAK,QAAQ,CAAC;AACrF;AAGO,SAAS,YAAiC,KAAa,UAAa,QAAkE;AAC3I,SAAO,UAAqC,QAAQ,EAAE,KAAK,OAAO,UAA0B,QAAQ,kBAAkB,cAAc,OAAO,cAAc,KAAK,GAAG,CAAC,MAAM,EAAE,WAAW,KAAK,QAAQ,CAAC;AACrM;AAGO,SAAS,SAAS,QAAkE;AACzF,SAAO,UAAqC,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC;AAC3E;AAGO,SAAS,WAAW,QAAgD;AACzE,SAAO,UAAU,QAAQ,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC;AACpD;AAMO,SAAS,YAAY,SAA0C;AACpE,aAAO,gCAAkB,OAAO;AAClC;;;AFvFA,IAAAC,gBAAkC;AAO3B,SAAS,cAAc,SAAwC;AACpE,MAAI,OAAO,WAAW,YAAa,OAAM,IAAI,MAAM,oIAAoI;AACvL,QAAM,eAAW,mBAAI,OAAO;AAC5B,MAAI,YAAY,CAAC,SAAS,SAAS,EAAE,aAAa,SAAS,QAAQ,cAAc,QAAQ,UAAW,QAAO;AAC3G,YAAU,QAAQ;AAClB,QAAM,aAAS,gBAAAC,eAAW,OAAO;AACjC,UAAQ,IAAI,MAAM;AAClB,MAAI,gBAAgB,OAAW,WAAU,QAAQ,WAAW;AAC5D,gBAAc;AACd,SAAO;AACT;AAEA,IAAM,cAAc,oBAAI,QAAsC;AAC9D,IAAI;AASG,SAAS,gBAAgB,MAA4C;AAC1E,MAAI,OAAO,WAAW,YAAa;AACnC,QAAM,aAAS,mBAAI,OAAO;AAC1B,MAAI,OAAQ,WAAU,QAAQ,IAAI;AAAA,MAC7B,eAAc;AACrB;AAEA,SAAS,UAAU,QAAuB,MAA4C;AACpF,MAAI,SAAS,OAAW;AACxB,QAAM,MAAM,OAAO,KAAK,UAAU,CAAC,OAAO,KAAK,EAAE,GAAG,KAAK,UAAU,MAAM,KAAK,WAAW,IAAI,CAAC,IAAI;AAClG,MAAI,YAAY,IAAI,MAAM,KAAK,YAAY,IAAI,MAAM,MAAM,IAAK;AAChE,cAAY,IAAI,QAAQ,GAAG;AAC3B,MAAI,KAAM,MAAK,OAAO,SAAS,KAAK,IAAI,KAAK,QAAQ,KAAK,OAAO;AAAA,WACxD,OAAO,SAAS,EAAE,MAAM,GAAI,QAAO,MAAM;AACpD;AAGO,SAAS,iBAAuB;AACrC,yBAAI,OAAO,GAAG,QAAQ;AACtB,UAAQ,IAAI,IAAI;AAClB;AAEA,IAAM,cAAc,uBAAO,IAAI,SAAS;AAEjC,SAAS,kBAAkB,QAAoC;AACpE,iCAAW,aAAa,MAAM;AAChC;AAEO,SAAS,oBAA0C;AACxD,aAAQ,2BAAW,WAAW,SAA0C,mBAAI,OAAO;AACrF;AAEA,SAAS,WAAc,SAAY,SAAuC,QAAgE;AACxI,aAAO,wBAAY,SAAS,CAAC,QAAQ;AACnC,QAAI,OAA0B,CAAC;AAC/B,UAAM,QAAQ,QAAQ,UAAU,CAAC,WAAW;AAC1C,WAAK,QAAQ,CAAC,QAAQ,IAAI,CAAC;AAC3B,aAAO,CAAC;AACR,UAAI,CAAC,OAAQ,QAAO,IAAI,OAAO;AAC/B,YAAM,SAAS,MAAM,IAAI,QAAQ,MAAM,CAAC;AACxC,aAAO;AACP,aAAO,OAAO,IAAI,CAAC,MAAM,OAAO,GAAG,GAAG,MAAe,CAAC;AAAA,IACxD,CAAC;AACD,WAAO,MAAM;AACX,WAAK,QAAQ,CAAC,QAAQ,IAAI,CAAC;AAC3B,YAAM;AAAA,IACR;AAAA,EACF,CAAC;AACH;AAGO,IAAM,eAAkC,WAAW,OAAO,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC;AAG9F,IAAM,cAA+C,WAAkC,MAAM,CAAC,MAAM,EAAE,eAAe,GAAG,CAAC,SAAS,eAAe,kBAAkB,iBAAiB,cAAc,UAAU,CAAC;AAG7M,SAAS,kBAAkB,SAAmD;AACnF,SAAO,WAAmC,EAAE,kBAAkB,CAAC,GAAG,aAAa,MAAM,aAAa,KAAK,GAAG,CAAC,MAAM,EAAE,qBAAqB,OAAO,GAAG,CAAC,SAAS,YAAY,kBAAkB,oBAAoB,CAAC;AACjN;AAGO,SAAS,eAAe,SAAoC;AACjE,aAAO,uBAAQ,WAAoB,OAAO,CAAC,MAAM,EAAE,iBAAiB,OAAO,GAAG,CAAC,SAAS,YAAY,gBAAgB,CAAC,GAAG,CAAC,MAAM,CAAC;AAClI;AAGO,SAAS,aAAa,MAAmB,KAA6D;AAC3G,MAAI,UAAU;AACd,QAAM,UAAU,CAAC,MAAa;AAC5B,MAAE,eAAe;AACjB,2BAAI,OAAO,GAAG,WAAW,OAAO;AAAA,EAClC;AACA,OAAK,iBAAiB,SAAS,OAAO;AACtC,OAAK,aAAa,wBAAwB,OAAO;AACjD,SAAO;AAAA,IACL,OAAO,MAAc;AACnB,gBAAU;AACV,WAAK,aAAa,wBAAwB,IAAI;AAAA,IAChD;AAAA,IACA,UAAU;AACR,WAAK,oBAAoB,SAAS,OAAO;AAAA,IAC3C;AAAA,EACF;AACF;AAGO,SAAS,cAAc,MAAmB,IAA6D;AAC5G,QAAM,QAAQ,CAAC,MAAe;AAC5B,QAAI,EAAG,MAAK,aAAa,aAAa,CAAC;AAAA,EACzC;AACA,QAAM,EAAE;AACR,SAAO,EAAE,QAAQ,OAAO,UAAU;AAAA,EAAC,EAAE;AACvC;","names":["import_svelte","import_store","import_store","import_flags","createCore"]}
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { GuidelyClient, PublishedGuide, ChecklistProgressState, GuidelyOptions, GuidelyUser } from '@guidelytech/sdk-core';
2
- export { ChecklistProgressState, GuidelyClient, GuidelyEvents, GuidelyOptions, GuidelyUser, PublishedGuide } from '@guidelytech/sdk-core';
2
+ export { AgentTurnInput, AgentTurnRedactor, ChecklistProgressState, GuidelyClient, GuidelyEvents, GuidelyOptions, GuidelyUser, PublishedGuide } from '@guidelytech/sdk-core';
3
3
  import * as svelte_store from 'svelte/store';
4
4
  import { Readable } from 'svelte/store';
5
5
  import { FlagsReader, JsonValue, FlagsClientOptions, FlagsClient, FlagValue, FlagDetails } from '@guidelytech/flags';
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { GuidelyClient, PublishedGuide, ChecklistProgressState, GuidelyOptions, GuidelyUser } from '@guidelytech/sdk-core';
2
- export { ChecklistProgressState, GuidelyClient, GuidelyEvents, GuidelyOptions, GuidelyUser, PublishedGuide } from '@guidelytech/sdk-core';
2
+ export { AgentTurnInput, AgentTurnRedactor, ChecklistProgressState, GuidelyClient, GuidelyEvents, GuidelyOptions, GuidelyUser, PublishedGuide } from '@guidelytech/sdk-core';
3
3
  import * as svelte_store from 'svelte/store';
4
4
  import { Readable } from 'svelte/store';
5
5
  import { FlagsReader, JsonValue, FlagsClientOptions, FlagsClient, FlagValue, FlagDetails } from '@guidelytech/flags';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/client-store.ts","../src/flags.ts"],"sourcesContent":["import { createGuidely as createCore, type ChecklistProgressState, type GuidelyClient, type GuidelyOptions, type GuidelyUser, type PublishedGuide } from \"@guidelytech/sdk-core\";\nimport { getContext, setContext } from \"svelte\";\nimport { derived, get, readable, type Readable } from \"svelte/store\";\nimport { guidely } from \"./client-store\";\n\nexport type { GuidelyClient, GuidelyOptions, GuidelyEvents, GuidelyUser, ChecklistProgressState, PublishedGuide } from \"@guidelytech/sdk-core\";\nexport { guidely };\nexport { flag, featureValue, flagDetails, allFlags, flagsReady, createFlags, setFlagsContext } from \"./flags\";\nexport type { FlagsSource } from \"./flags\";\nexport { createStaticFlags } from \"@guidelytech/flags\";\nexport type { FlagsClient, FlagsClientOptions, FlagDetails, FlagsBootstrap, FlagsPayload, FlagsReader, Attributes, JsonValue, EvaluationResult } from \"@guidelytech/flags\";\n\n/**\n * Creates the client and stores it in the `guidely` store. Browser-only: throws a helpful error\n * when called during SSR (call it from `onMount` or use `@guidelytech/sveltekit`'s `initGuidely`).\n */\nexport function createGuidely(options: GuidelyOptions): GuidelyClient {\n if (typeof window === \"undefined\") throw new Error(\"[Guidely] createGuidely() can only run in the browser. Call it inside onMount(), or use initGuidely() from @guidelytech/sveltekit.\");\n const existing = get(guidely);\n if (existing && !existing.getState().destroyed && existing.options.projectId === options.projectId) return existing;\n existing?.destroy();\n const client = createCore(options);\n guidely.set(client);\n if (pendingUser !== undefined) applyUser(client, pendingUser);\n pendingUser = undefined;\n return client;\n}\n\nconst appliedUser = new WeakMap<GuidelyClient, string | null>();\nlet pendingUser: GuidelyUser | null | undefined;\n\n/**\n * Keeps the Guidely user in step with your app's signed-in user. Idempotent: call it whenever your\n * user data may have changed (a `$effect` / `$:` on layout data). A user identifies (again only when\n * id, traits or account change); `null` resets a previously identified user, including one restored\n * from storage; `undefined` means \"not known yet\" and changes nothing. No-op on the server; called\n * before `createGuidely`, it is applied when the client is created.\n */\nexport function syncGuidelyUser(user: GuidelyUser | null | undefined): void {\n if (typeof window === \"undefined\") return;\n const client = get(guidely);\n if (client) applyUser(client, user);\n else pendingUser = user;\n}\n\nfunction applyUser(client: GuidelyClient, user: GuidelyUser | null | undefined): void {\n if (user === undefined) return;\n const key = user ? JSON.stringify([String(user.id), user.traits ?? null, user.account ?? null]) : null;\n if (appliedUser.has(client) && appliedUser.get(client) === key) return;\n appliedUser.set(client, key);\n if (user) void client.identify(user.id, user.traits, user.account);\n else if (client.getState().user?.id) client.reset();\n}\n\n/** Destroys the current client and clears the store. */\nexport function destroyGuidely(): void {\n get(guidely)?.destroy();\n guidely.set(null);\n}\n\nconst CONTEXT_KEY = Symbol.for(\"guidely\");\n\nexport function setGuidelyContext(client: GuidelyClient | null): void {\n setContext(CONTEXT_KEY, client);\n}\n\nexport function getGuidelyContext(): GuidelyClient | null {\n return (getContext(CONTEXT_KEY) as GuidelyClient | null | undefined) ?? get(guidely);\n}\n\nfunction fromClient<T>(initial: T, compute: (client: GuidelyClient) => T, events: Array<Parameters<GuidelyClient[\"on\"]>[0]>): Readable<T> {\n return readable<T>(initial, (set) => {\n let offs: Array<() => void> = [];\n const unsub = guidely.subscribe((client) => {\n offs.forEach((off) => off());\n offs = [];\n if (!client) return set(initial);\n const update = () => set(compute(client));\n update();\n offs = events.map((e) => client.on(e, update as never));\n });\n return () => {\n offs.forEach((off) => off());\n unsub();\n };\n });\n}\n\n/** True once the configuration has loaded. */\nexport const guidelyReady: Readable<boolean> = fromClient(false, (c) => c.getState().ready, [\"ready\"]);\n\n/** The guide currently showing (flows, modals, surveys), or null. */\nexport const activeGuide: Readable<PublishedGuide | null> = fromClient<PublishedGuide | null>(null, (c) => c.getActiveGuide(), [\"ready\", \"guide:start\", \"guide:complete\", \"guide:dismiss\", \"guide:skip\", \"identify\"]);\n\n/** Live checklist progress for a checklist guide (by id or key). */\nexport function checklistProgress(idOrKey: string): Readable<ChecklistProgressState> {\n return fromClient<ChecklistProgressState>({ completedTaskIds: [], completedAt: null, dismissedAt: null }, (c) => c.getChecklistProgress(idOrKey), [\"ready\", \"identify\", \"checklist:task\", \"checklist:complete\"]);\n}\n\n/** Is the given guide completed for the current user? */\nexport function guideCompleted(idOrKey: string): Readable<boolean> {\n return derived(fromClient<boolean>(false, (c) => c.isGuideCompleted(idOrKey), [\"ready\", \"identify\", \"guide:complete\"]), (v) => v);\n}\n\n/** `use:guideTrigger={\"guide-key\"}` — clicking the element starts the guide. */\nexport function guideTrigger(node: HTMLElement, key: string): { update(key: string): void; destroy(): void } {\n let current = key;\n const onClick = (e: Event) => {\n e.preventDefault();\n get(guidely)?.startGuide(current);\n };\n node.addEventListener(\"click\", onClick);\n node.setAttribute(\"data-guidely-trigger\", current);\n return {\n update(next: string) {\n current = next;\n node.setAttribute(\"data-guidely-trigger\", next);\n },\n destroy() {\n node.removeEventListener(\"click\", onClick);\n },\n };\n}\n\n/** `use:guidelyTarget={\"id\"}` — marks an element as a guide target (`data-tour`). No runtime behaviour. */\nexport function guidelyTarget(node: HTMLElement, id?: string): { update(id?: string): void; destroy(): void } {\n const apply = (v?: string) => {\n if (v) node.setAttribute(\"data-tour\", v);\n };\n apply(id);\n return { update: apply, destroy() {} };\n}\n","import type { GuidelyClient } from \"@guidelytech/sdk-core\";\nimport { writable } from \"svelte/store\";\n\n/** The current client (null on the server and before `createGuidely`). */\nexport const guidely = writable<GuidelyClient | null>(null);\n","import { createFlagsClient, jsonEquals, type FlagDetails, type FlagValue, type FlagsClient, type FlagsClientOptions, type FlagsReader, type JsonValue } from \"@guidelytech/flags\";\nimport type { GuidelyClient } from \"@guidelytech/sdk-core\";\nimport { getContext, setContext } from \"svelte\";\nimport { derived, readable, type Readable } from \"svelte/store\";\nimport { guidely } from \"./client-store\";\n\n/** Where flag stores read from: a Guidely client, a flags client, or a static snapshot. */\nexport type FlagsSource = GuidelyClient | FlagsReader;\n\nconst FLAGS_KEY = Symbol.for(\"guidely.flags\");\n\nfunction readerOf(source: FlagsSource | null | undefined): FlagsReader | null {\n if (!source) return null;\n return \"isFeatureEnabled\" in source && \"flags\" in source ? (source as GuidelyClient).flags : (source as FlagsReader);\n}\n\n/**\n * Makes `source` the flags for this component and its children (call during component\n * initialisation). Accepts a client, a flags client, a static snapshot or a store of one.\n */\nexport function setFlagsContext(source: FlagsSource | Readable<FlagsSource | null> | null): void {\n const store = source && \"subscribe\" in source && !(\"isEnabled\" in source) && !(\"isFeatureEnabled\" in source) ? derived(source as Readable<FlagsSource | null>, readerOf) : readable(readerOf(source as FlagsSource | null));\n setContext(FLAGS_KEY, store);\n}\n\n/** An explicit source, else the component context (`setFlagsContext` / `initGuidely`), else the global `guidely` client. */\nfunction sourceStore(source?: FlagsSource | null): Readable<FlagsReader | null> {\n if (source) return readable(readerOf(source));\n try {\n const ctx = getContext<Readable<FlagsReader | null> | undefined>(FLAGS_KEY);\n if (ctx) return ctx;\n } catch {\n /* not during component initialisation */\n }\n return derived(guidely, (c) => c?.flags ?? null);\n}\n\nfunction flagStore<T>(source: FlagsSource | null | undefined, initial: T, select: (r: FlagsReader) => T): Readable<T> {\n const src = sourceStore(source);\n return readable<T>(initial, (set) => {\n let off = () => {};\n let last: { value: T } | null = null;\n const unsub = src.subscribe((reader) => {\n off();\n off = () => {};\n if (!reader) {\n last = { value: initial };\n return set(initial);\n }\n const update = () => {\n const value = select(reader);\n if (last && jsonEquals(last.value, value)) return; // object flags keep their identity\n last = { value };\n set(value);\n };\n update();\n off = reader.subscribe(update);\n });\n return () => {\n off();\n unsub();\n };\n });\n}\n\n/** `$flag` is true when the boolean flag is on; `fallback` (default `false`) until flags load, or when missing. */\nexport function flag(key: string, fallback = false, source?: FlagsSource | null): Readable<boolean> {\n return flagStore(source, fallback, (r) => r.isEnabled(key, fallback));\n}\n\n/** A flag's value (string, number, JSON…); `fallback` when missing or of a different type. */\nexport function featureValue<T extends JsonValue>(key: string, fallback: T, source?: FlagsSource | null): Readable<FlagValue<T>> {\n return flagStore(source, fallback as FlagValue<T>, (r) => r.getValue(key, fallback));\n}\n\n/** A flag's value plus why it was served (reason, rule, variation, experiment). */\nexport function flagDetails<T extends JsonValue>(key: string, fallback: T, source?: FlagsSource | null): Readable<FlagDetails<FlagValue<T>>> {\n return flagStore<FlagDetails<FlagValue<T>>>(source, { key, value: fallback as FlagValue<T>, reason: \"FLAG_NOT_FOUND\", inExperiment: false, usedFallback: true }, (r) => r.getDetails(key, fallback));\n}\n\n/** Every flag's value (records no exposures). */\nexport function allFlags(source?: FlagsSource | null): Readable<Record<string, JsonValue>> {\n return flagStore<Record<string, JsonValue>>(source, {}, (r) => r.getAll());\n}\n\n/** True once flags have loaded (or failed to and serve fallbacks); true from the start with a bootstrap payload. */\nexport function flagsReady(source?: FlagsSource | null): Readable<boolean> {\n return flagStore(source, false, (r) => r.isReady());\n}\n\n/**\n * Feature flags only (no guides or analytics): a flags client to pass to the stores\n * (`flag(\"x\", false, flags)`) or to `setFlagsContext(flags)`. Runs in the browser and on servers.\n */\nexport function createFlags(options: FlagsClientOptions): FlagsClient {\n return createFlagsClient(options);\n}\n"],"mappings":"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","names":["getContext","setContext","derived","readable","setContext","getContext","readable","derived"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/client-store.ts","../src/flags.ts"],"sourcesContent":["import { createGuidely as createCore, type ChecklistProgressState, type GuidelyClient, type GuidelyOptions, type GuidelyUser, type PublishedGuide } from \"@guidelytech/sdk-core\";\nimport { getContext, setContext } from \"svelte\";\nimport { derived, get, readable, type Readable } from \"svelte/store\";\nimport { guidely } from \"./client-store\";\n\nexport type { GuidelyClient, GuidelyOptions, GuidelyEvents, GuidelyUser, ChecklistProgressState, PublishedGuide, AgentTurnInput, AgentTurnRedactor } from \"@guidelytech/sdk-core\";\nexport { guidely };\nexport { flag, featureValue, flagDetails, allFlags, flagsReady, createFlags, setFlagsContext } from \"./flags\";\nexport type { FlagsSource } from \"./flags\";\nexport { createStaticFlags } from \"@guidelytech/flags\";\nexport type { FlagsClient, FlagsClientOptions, FlagDetails, FlagsBootstrap, FlagsPayload, FlagsReader, Attributes, JsonValue, EvaluationResult } from \"@guidelytech/flags\";\n\n/**\n * Creates the client and stores it in the `guidely` store. Browser-only: throws a helpful error\n * when called during SSR (call it from `onMount` or use `@guidelytech/sveltekit`'s `initGuidely`).\n */\nexport function createGuidely(options: GuidelyOptions): GuidelyClient {\n if (typeof window === \"undefined\") throw new Error(\"[Guidely] createGuidely() can only run in the browser. Call it inside onMount(), or use initGuidely() from @guidelytech/sveltekit.\");\n const existing = get(guidely);\n if (existing && !existing.getState().destroyed && existing.options.projectId === options.projectId) return existing;\n existing?.destroy();\n const client = createCore(options);\n guidely.set(client);\n if (pendingUser !== undefined) applyUser(client, pendingUser);\n pendingUser = undefined;\n return client;\n}\n\nconst appliedUser = new WeakMap<GuidelyClient, string | null>();\nlet pendingUser: GuidelyUser | null | undefined;\n\n/**\n * Keeps the Guidely user in step with your app's signed-in user. Idempotent: call it whenever your\n * user data may have changed (a `$effect` / `$:` on layout data). A user identifies (again only when\n * id, traits or account change); `null` resets a previously identified user, including one restored\n * from storage; `undefined` means \"not known yet\" and changes nothing. No-op on the server; called\n * before `createGuidely`, it is applied when the client is created.\n */\nexport function syncGuidelyUser(user: GuidelyUser | null | undefined): void {\n if (typeof window === \"undefined\") return;\n const client = get(guidely);\n if (client) applyUser(client, user);\n else pendingUser = user;\n}\n\nfunction applyUser(client: GuidelyClient, user: GuidelyUser | null | undefined): void {\n if (user === undefined) return;\n const key = user ? JSON.stringify([String(user.id), user.traits ?? null, user.account ?? null]) : null;\n if (appliedUser.has(client) && appliedUser.get(client) === key) return;\n appliedUser.set(client, key);\n if (user) void client.identify(user.id, user.traits, user.account);\n else if (client.getState().user?.id) client.reset();\n}\n\n/** Destroys the current client and clears the store. */\nexport function destroyGuidely(): void {\n get(guidely)?.destroy();\n guidely.set(null);\n}\n\nconst CONTEXT_KEY = Symbol.for(\"guidely\");\n\nexport function setGuidelyContext(client: GuidelyClient | null): void {\n setContext(CONTEXT_KEY, client);\n}\n\nexport function getGuidelyContext(): GuidelyClient | null {\n return (getContext(CONTEXT_KEY) as GuidelyClient | null | undefined) ?? get(guidely);\n}\n\nfunction fromClient<T>(initial: T, compute: (client: GuidelyClient) => T, events: Array<Parameters<GuidelyClient[\"on\"]>[0]>): Readable<T> {\n return readable<T>(initial, (set) => {\n let offs: Array<() => void> = [];\n const unsub = guidely.subscribe((client) => {\n offs.forEach((off) => off());\n offs = [];\n if (!client) return set(initial);\n const update = () => set(compute(client));\n update();\n offs = events.map((e) => client.on(e, update as never));\n });\n return () => {\n offs.forEach((off) => off());\n unsub();\n };\n });\n}\n\n/** True once the configuration has loaded. */\nexport const guidelyReady: Readable<boolean> = fromClient(false, (c) => c.getState().ready, [\"ready\"]);\n\n/** The guide currently showing (flows, modals, surveys), or null. */\nexport const activeGuide: Readable<PublishedGuide | null> = fromClient<PublishedGuide | null>(null, (c) => c.getActiveGuide(), [\"ready\", \"guide:start\", \"guide:complete\", \"guide:dismiss\", \"guide:skip\", \"identify\"]);\n\n/** Live checklist progress for a checklist guide (by id or key). */\nexport function checklistProgress(idOrKey: string): Readable<ChecklistProgressState> {\n return fromClient<ChecklistProgressState>({ completedTaskIds: [], completedAt: null, dismissedAt: null }, (c) => c.getChecklistProgress(idOrKey), [\"ready\", \"identify\", \"checklist:task\", \"checklist:complete\"]);\n}\n\n/** Is the given guide completed for the current user? */\nexport function guideCompleted(idOrKey: string): Readable<boolean> {\n return derived(fromClient<boolean>(false, (c) => c.isGuideCompleted(idOrKey), [\"ready\", \"identify\", \"guide:complete\"]), (v) => v);\n}\n\n/** `use:guideTrigger={\"guide-key\"}` — clicking the element starts the guide. */\nexport function guideTrigger(node: HTMLElement, key: string): { update(key: string): void; destroy(): void } {\n let current = key;\n const onClick = (e: Event) => {\n e.preventDefault();\n get(guidely)?.startGuide(current);\n };\n node.addEventListener(\"click\", onClick);\n node.setAttribute(\"data-guidely-trigger\", current);\n return {\n update(next: string) {\n current = next;\n node.setAttribute(\"data-guidely-trigger\", next);\n },\n destroy() {\n node.removeEventListener(\"click\", onClick);\n },\n };\n}\n\n/** `use:guidelyTarget={\"id\"}` — marks an element as a guide target (`data-tour`). No runtime behaviour. */\nexport function guidelyTarget(node: HTMLElement, id?: string): { update(id?: string): void; destroy(): void } {\n const apply = (v?: string) => {\n if (v) node.setAttribute(\"data-tour\", v);\n };\n apply(id);\n return { update: apply, destroy() {} };\n}\n","import type { GuidelyClient } from \"@guidelytech/sdk-core\";\nimport { writable } from \"svelte/store\";\n\n/** The current client (null on the server and before `createGuidely`). */\nexport const guidely = writable<GuidelyClient | null>(null);\n","import { createFlagsClient, jsonEquals, type FlagDetails, type FlagValue, type FlagsClient, type FlagsClientOptions, type FlagsReader, type JsonValue } from \"@guidelytech/flags\";\nimport type { GuidelyClient } from \"@guidelytech/sdk-core\";\nimport { getContext, setContext } from \"svelte\";\nimport { derived, readable, type Readable } from \"svelte/store\";\nimport { guidely } from \"./client-store\";\n\n/** Where flag stores read from: a Guidely client, a flags client, or a static snapshot. */\nexport type FlagsSource = GuidelyClient | FlagsReader;\n\nconst FLAGS_KEY = Symbol.for(\"guidely.flags\");\n\nfunction readerOf(source: FlagsSource | null | undefined): FlagsReader | null {\n if (!source) return null;\n return \"isFeatureEnabled\" in source && \"flags\" in source ? (source as GuidelyClient).flags : (source as FlagsReader);\n}\n\n/**\n * Makes `source` the flags for this component and its children (call during component\n * initialisation). Accepts a client, a flags client, a static snapshot or a store of one.\n */\nexport function setFlagsContext(source: FlagsSource | Readable<FlagsSource | null> | null): void {\n const store = source && \"subscribe\" in source && !(\"isEnabled\" in source) && !(\"isFeatureEnabled\" in source) ? derived(source as Readable<FlagsSource | null>, readerOf) : readable(readerOf(source as FlagsSource | null));\n setContext(FLAGS_KEY, store);\n}\n\n/** An explicit source, else the component context (`setFlagsContext` / `initGuidely`), else the global `guidely` client. */\nfunction sourceStore(source?: FlagsSource | null): Readable<FlagsReader | null> {\n if (source) return readable(readerOf(source));\n try {\n const ctx = getContext<Readable<FlagsReader | null> | undefined>(FLAGS_KEY);\n if (ctx) return ctx;\n } catch {\n /* not during component initialisation */\n }\n return derived(guidely, (c) => c?.flags ?? null);\n}\n\nfunction flagStore<T>(source: FlagsSource | null | undefined, initial: T, select: (r: FlagsReader) => T): Readable<T> {\n const src = sourceStore(source);\n return readable<T>(initial, (set) => {\n let off = () => {};\n let last: { value: T } | null = null;\n const unsub = src.subscribe((reader) => {\n off();\n off = () => {};\n if (!reader) {\n last = { value: initial };\n return set(initial);\n }\n const update = () => {\n const value = select(reader);\n if (last && jsonEquals(last.value, value)) return; // object flags keep their identity\n last = { value };\n set(value);\n };\n update();\n off = reader.subscribe(update);\n });\n return () => {\n off();\n unsub();\n };\n });\n}\n\n/** `$flag` is true when the boolean flag is on; `fallback` (default `false`) until flags load, or when missing. */\nexport function flag(key: string, fallback = false, source?: FlagsSource | null): Readable<boolean> {\n return flagStore(source, fallback, (r) => r.isEnabled(key, fallback));\n}\n\n/** A flag's value (string, number, JSON…); `fallback` when missing or of a different type. */\nexport function featureValue<T extends JsonValue>(key: string, fallback: T, source?: FlagsSource | null): Readable<FlagValue<T>> {\n return flagStore(source, fallback as FlagValue<T>, (r) => r.getValue(key, fallback));\n}\n\n/** A flag's value plus why it was served (reason, rule, variation, experiment). */\nexport function flagDetails<T extends JsonValue>(key: string, fallback: T, source?: FlagsSource | null): Readable<FlagDetails<FlagValue<T>>> {\n return flagStore<FlagDetails<FlagValue<T>>>(source, { key, value: fallback as FlagValue<T>, reason: \"FLAG_NOT_FOUND\", inExperiment: false, usedFallback: true }, (r) => r.getDetails(key, fallback));\n}\n\n/** Every flag's value (records no exposures). */\nexport function allFlags(source?: FlagsSource | null): Readable<Record<string, JsonValue>> {\n return flagStore<Record<string, JsonValue>>(source, {}, (r) => r.getAll());\n}\n\n/** True once flags have loaded (or failed to and serve fallbacks); true from the start with a bootstrap payload. */\nexport function flagsReady(source?: FlagsSource | null): Readable<boolean> {\n return flagStore(source, false, (r) => r.isReady());\n}\n\n/**\n * Feature flags only (no guides or analytics): a flags client to pass to the stores\n * (`flag(\"x\", false, flags)`) or to `setFlagsContext(flags)`. Runs in the browser and on servers.\n */\nexport function createFlags(options: FlagsClientOptions): FlagsClient {\n return createFlagsClient(options);\n}\n"],"mappings":"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","names":["getContext","setContext","derived","readable","setContext","getContext","readable","derived"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@guidelytech/svelte",
3
- "version": "0.10.0",
3
+ "version": "0.11.0",
4
4
  "description": "Svelte stores, actions and client for Guidely",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -20,9 +20,9 @@
20
20
  "README.md"
21
21
  ],
22
22
  "dependencies": {
23
- "@guidelytech/flags": "0.10.0",
24
- "@guidelytech/sdk-core": "0.10.0",
25
- "@guidelytech/shared": "0.10.0"
23
+ "@guidelytech/flags": "0.11.0",
24
+ "@guidelytech/sdk-core": "0.11.0",
25
+ "@guidelytech/shared": "0.11.0"
26
26
  },
27
27
  "devDependencies": {
28
28
  "tsup": "^8.5.1",