@syntrologie/runtime-sdk 2.4.0-canary.2 → 2.4.0-canary.21
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/CAPABILITIES.md +116 -1
- package/dist/SmartCanvasApp.d.ts +5 -3
- package/dist/actions/executors/index.d.ts +1 -2
- package/dist/actions/index.d.ts +2 -2
- package/dist/actions/schema.d.ts +58243 -201
- package/dist/actions/schema.js +5 -2
- package/dist/actions/types.d.ts +45 -48
- package/dist/anchor/AnchorResolver.d.ts +18 -0
- package/dist/anchor/index.d.ts +2 -0
- package/dist/api.d.ts +3 -8
- package/dist/apps/examples/gamification-app.example.d.ts +8 -8
- package/dist/chunk-2UYZ5DWI.js +126 -0
- package/dist/chunk-2UYZ5DWI.js.map +7 -0
- package/dist/{chunk-DOJR7R46.js → chunk-HF3D7YFQ.js} +49 -31
- package/dist/chunk-HF3D7YFQ.js.map +7 -0
- package/dist/{chunk-ZDZ3IYFN.js → chunk-IPU3WVPY.js} +3449 -2110
- package/dist/chunk-IPU3WVPY.js.map +7 -0
- package/dist/{chunk-BIYMC56J.js → chunk-P5G4KT2U.js} +54 -6
- package/dist/chunk-P5G4KT2U.js.map +7 -0
- package/dist/components/ShadowCanvasOverlay.d.ts +1 -20
- package/dist/config/schema.d.ts +1797 -267
- package/dist/config/schema.js +19 -62
- package/dist/config/schema.js.map +3 -3
- package/dist/context/schema.d.ts +8 -8
- package/dist/decisions/schema.d.ts +506 -1490
- package/dist/decisions/schema.js +5 -2
- package/dist/decisions/types.d.ts +22 -0
- package/dist/events/registerConfigPredicates.d.ts +7 -10
- package/dist/events/schema.d.ts +12 -12
- package/dist/experiments/adapters/growthbook.d.ts +2 -0
- package/dist/experiments/types.d.ts +7 -0
- package/dist/hooks/useShadowCanvasConfig.d.ts +4 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.js +72 -98
- package/dist/index.js.map +3 -3
- package/dist/overlays/schema.d.ts +48 -48
- package/dist/react.js +4 -3
- package/dist/react.js.map +1 -1
- package/dist/runtime.d.ts +3 -0
- package/dist/smart-canvas.esm.js +62 -66
- package/dist/smart-canvas.esm.js.map +4 -4
- package/dist/smart-canvas.js +2591 -1167
- package/dist/smart-canvas.js.map +4 -4
- package/dist/smart-canvas.min.js +62 -66
- package/dist/smart-canvas.min.js.map +4 -4
- package/dist/surfaces/types.d.ts +2 -1
- package/dist/theme/ThemeProvider.d.ts +11 -16
- package/dist/theme/defaultTheme.d.ts +6 -1
- package/dist/theme/index.d.ts +3 -4
- package/dist/theme/types.d.ts +10 -0
- package/dist/version.d.ts +1 -1
- package/package.json +7 -7
- package/schema/canvas-config.schema.json +9418 -790
- package/scripts/validate-config.mjs +78 -0
- package/dist/actions/executors/tour.d.ts +0 -18
- package/dist/chunk-BIYMC56J.js.map +0 -7
- package/dist/chunk-DOJR7R46.js.map +0 -7
- package/dist/chunk-JMHRHAEL.js +0 -18
- package/dist/chunk-JMHRHAEL.js.map +0 -7
- package/dist/chunk-ZDZ3IYFN.js.map +0 -7
- package/dist/hooks/useHostPatches.d.ts +0 -9
- package/dist/theme/extractHostTheme.d.ts +0 -14
package/dist/decisions/schema.js
CHANGED
|
@@ -3,12 +3,14 @@ import {
|
|
|
3
3
|
AnchorVisibleConditionZ,
|
|
4
4
|
ConditionZ,
|
|
5
5
|
CooldownActiveConditionZ,
|
|
6
|
+
CounterDefZ,
|
|
6
7
|
DecisionStrategyZ,
|
|
7
8
|
DismissedConditionZ,
|
|
8
9
|
EventCountConditionZ,
|
|
9
10
|
EventOccurredConditionZ,
|
|
10
11
|
ExternalStrategyZ,
|
|
11
12
|
FrequencyLimitConditionZ,
|
|
13
|
+
MatchOpZ,
|
|
12
14
|
ModelStrategyZ,
|
|
13
15
|
PageUrlConditionZ,
|
|
14
16
|
RouteConditionZ,
|
|
@@ -23,19 +25,20 @@ import {
|
|
|
23
25
|
validateActivationConfig,
|
|
24
26
|
validateCondition,
|
|
25
27
|
validateStrategy
|
|
26
|
-
} from "../chunk-
|
|
27
|
-
import "../chunk-JMHRHAEL.js";
|
|
28
|
+
} from "../chunk-P5G4KT2U.js";
|
|
28
29
|
export {
|
|
29
30
|
ActivationConfigZ,
|
|
30
31
|
AnchorVisibleConditionZ,
|
|
31
32
|
ConditionZ,
|
|
32
33
|
CooldownActiveConditionZ,
|
|
34
|
+
CounterDefZ,
|
|
33
35
|
DecisionStrategyZ,
|
|
34
36
|
DismissedConditionZ,
|
|
35
37
|
EventCountConditionZ,
|
|
36
38
|
EventOccurredConditionZ,
|
|
37
39
|
ExternalStrategyZ,
|
|
38
40
|
FrequencyLimitConditionZ,
|
|
41
|
+
MatchOpZ,
|
|
39
42
|
ModelStrategyZ,
|
|
40
43
|
PageUrlConditionZ,
|
|
41
44
|
RouteConditionZ,
|
|
@@ -110,6 +110,25 @@ export interface FrequencyLimitCondition {
|
|
|
110
110
|
/** Invert the condition (true if limit NOT reached) */
|
|
111
111
|
inverted?: boolean;
|
|
112
112
|
}
|
|
113
|
+
/**
|
|
114
|
+
* Match operator for counter filters.
|
|
115
|
+
* Exactly one of `equals` or `contains` must be specified.
|
|
116
|
+
*/
|
|
117
|
+
export interface MatchOp {
|
|
118
|
+
equals?: string | number | boolean;
|
|
119
|
+
contains?: string;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Defines what events to count for an event_count condition.
|
|
123
|
+
* Registered as an accumulator predicate at config-load time.
|
|
124
|
+
*/
|
|
125
|
+
export interface CounterDef {
|
|
126
|
+
/** Event names to listen for (e.g., ["ui.click"]). ALL other filters AND with this. */
|
|
127
|
+
events: string[];
|
|
128
|
+
/** Prop-based filters. Keys are event prop names OR element-chain fields
|
|
129
|
+
* (tag_name, $el_text, attr__*). All entries AND together. */
|
|
130
|
+
match?: Record<string, MatchOp>;
|
|
131
|
+
}
|
|
113
132
|
/**
|
|
114
133
|
* Condition that checks accumulated event counts.
|
|
115
134
|
* Used for behavior triggers like "visited /pricing 3+ times".
|
|
@@ -125,6 +144,9 @@ export interface EventCountCondition {
|
|
|
125
144
|
count: number;
|
|
126
145
|
/** Only count events within this time window (ms). Omit = session lifetime. */
|
|
127
146
|
withinMs?: number;
|
|
147
|
+
/** Inline counter definition. Defines what events to count.
|
|
148
|
+
* If omitted, predicate is pass-through (counts all events). */
|
|
149
|
+
counter?: CounterDef;
|
|
128
150
|
}
|
|
129
151
|
/**
|
|
130
152
|
* Union of all condition types.
|
|
@@ -1,19 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Register accumulator predicates from tile configs at config-load time.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* navigation, the widget never mounts, and clicks go uncounted.
|
|
4
|
+
* Scans all triggerWhen conditions (in tile actions and top-level actions)
|
|
5
|
+
* for event_count conditions with a `counter` definition. For each, builds
|
|
6
|
+
* a predicate and registers it with the accumulator.
|
|
8
7
|
*
|
|
9
|
-
*
|
|
10
|
-
* config is loaded, regardless of canvas state.
|
|
8
|
+
* Safe to call multiple times — accumulator.register() is idempotent.
|
|
11
9
|
*/
|
|
12
10
|
import type { TileConfig } from '../types';
|
|
13
11
|
import type { EventAccumulator } from './EventAccumulator';
|
|
14
12
|
/**
|
|
15
|
-
* Scan tile configs
|
|
16
|
-
* accumulator predicates
|
|
17
|
-
* is idempotent (skips if key already registered).
|
|
13
|
+
* Scan tile configs and top-level actions for event_count conditions
|
|
14
|
+
* and register accumulator predicates from their counter definitions.
|
|
18
15
|
*/
|
|
19
|
-
export declare function registerConfigPredicates(tiles: TileConfig[], accumulator: EventAccumulator): void;
|
|
16
|
+
export declare function registerConfigPredicates(tiles: TileConfig[], accumulator: EventAccumulator, actions?: unknown[]): void;
|
package/dist/events/schema.d.ts
CHANGED
|
@@ -10,15 +10,15 @@ export declare const NormalizedEventZ: z.ZodObject<{
|
|
|
10
10
|
props: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
11
11
|
schemaVersion: z.ZodString;
|
|
12
12
|
}, "strip", z.ZodTypeAny, {
|
|
13
|
-
source: "posthog" | "canvas" | "derived";
|
|
14
|
-
name: string;
|
|
15
13
|
schemaVersion: string;
|
|
14
|
+
source: "canvas" | "posthog" | "derived";
|
|
15
|
+
name: string;
|
|
16
16
|
ts: number;
|
|
17
17
|
props?: Record<string, unknown> | undefined;
|
|
18
18
|
}, {
|
|
19
|
-
source: "posthog" | "canvas" | "derived";
|
|
20
|
-
name: string;
|
|
21
19
|
schemaVersion: string;
|
|
20
|
+
source: "canvas" | "posthog" | "derived";
|
|
21
|
+
name: string;
|
|
22
22
|
ts: number;
|
|
23
23
|
props?: Record<string, unknown> | undefined;
|
|
24
24
|
}>;
|
|
@@ -29,25 +29,25 @@ export declare const EventFilterZ: z.ZodObject<{
|
|
|
29
29
|
}, "strip", z.ZodTypeAny, {
|
|
30
30
|
names?: string[] | undefined;
|
|
31
31
|
patterns?: string[] | undefined;
|
|
32
|
-
sources?: ("
|
|
32
|
+
sources?: ("canvas" | "posthog" | "derived")[] | undefined;
|
|
33
33
|
}, {
|
|
34
34
|
names?: string[] | undefined;
|
|
35
35
|
patterns?: string[] | undefined;
|
|
36
|
-
sources?: ("
|
|
36
|
+
sources?: ("canvas" | "posthog" | "derived")[] | undefined;
|
|
37
37
|
}>;
|
|
38
38
|
/**
|
|
39
39
|
* Validate a NormalizedEvent object.
|
|
40
40
|
*/
|
|
41
41
|
export declare function validateNormalizedEvent(data: unknown): z.SafeParseReturnType<{
|
|
42
|
-
source: "posthog" | "canvas" | "derived";
|
|
43
|
-
name: string;
|
|
44
42
|
schemaVersion: string;
|
|
43
|
+
source: "canvas" | "posthog" | "derived";
|
|
44
|
+
name: string;
|
|
45
45
|
ts: number;
|
|
46
46
|
props?: Record<string, unknown> | undefined;
|
|
47
47
|
}, {
|
|
48
|
-
source: "posthog" | "canvas" | "derived";
|
|
49
|
-
name: string;
|
|
50
48
|
schemaVersion: string;
|
|
49
|
+
source: "canvas" | "posthog" | "derived";
|
|
50
|
+
name: string;
|
|
51
51
|
ts: number;
|
|
52
52
|
props?: Record<string, unknown> | undefined;
|
|
53
53
|
}>;
|
|
@@ -57,11 +57,11 @@ export declare function validateNormalizedEvent(data: unknown): z.SafeParseRetur
|
|
|
57
57
|
export declare function validateEventFilter(data: unknown): z.SafeParseReturnType<{
|
|
58
58
|
names?: string[] | undefined;
|
|
59
59
|
patterns?: string[] | undefined;
|
|
60
|
-
sources?: ("
|
|
60
|
+
sources?: ("canvas" | "posthog" | "derived")[] | undefined;
|
|
61
61
|
}, {
|
|
62
62
|
names?: string[] | undefined;
|
|
63
63
|
patterns?: string[] | undefined;
|
|
64
|
-
sources?: ("
|
|
64
|
+
sources?: ("canvas" | "posthog" | "derived")[] | undefined;
|
|
65
65
|
}>;
|
|
66
66
|
/**
|
|
67
67
|
* Type inference from Zod schema.
|
|
@@ -43,6 +43,7 @@ export interface GrowthBookAdapterOptions extends GrowthBookInitOptions {
|
|
|
43
43
|
*/
|
|
44
44
|
export declare class GrowthBookAdapter implements ExperimentClient {
|
|
45
45
|
private readonly gb;
|
|
46
|
+
private readonly featureListeners;
|
|
46
47
|
constructor(options?: GrowthBookAdapterOptions);
|
|
47
48
|
/**
|
|
48
49
|
* Access to the underlying GrowthBook instance.
|
|
@@ -55,6 +56,7 @@ export declare class GrowthBookAdapter implements ExperimentClient {
|
|
|
55
56
|
getFeatureValue<T>(key: string, fallback: T): T;
|
|
56
57
|
getAllFeatures(): Record<string, unknown>;
|
|
57
58
|
shouldRenderRectangle(_tile: TileConfig): boolean;
|
|
59
|
+
onFeaturesChanged(callback: () => void): () => void;
|
|
58
60
|
}
|
|
59
61
|
/**
|
|
60
62
|
* Create an ExperimentClient backed by GrowthBook.
|
|
@@ -32,6 +32,13 @@ export interface ExperimentClient {
|
|
|
32
32
|
* Returns a map of feature key -> feature value.
|
|
33
33
|
*/
|
|
34
34
|
getAllFeatures?(): Record<string, unknown>;
|
|
35
|
+
/**
|
|
36
|
+
* Subscribe to feature flag value changes.
|
|
37
|
+
* Called when the underlying provider receives updated feature values
|
|
38
|
+
* (e.g., via streaming, webhook, or manual refresh).
|
|
39
|
+
* Returns an unsubscribe function.
|
|
40
|
+
*/
|
|
41
|
+
onFeaturesChanged?(callback: () => void): () => void;
|
|
35
42
|
}
|
|
36
43
|
/**
|
|
37
44
|
* @deprecated Use ExperimentClient instead
|
|
@@ -3,11 +3,13 @@ import type { SmartCanvasRuntime } from '../runtime';
|
|
|
3
3
|
import type { ActionStep, CanvasConfigFetcher, CanvasThemeConfig, LauncherConfig, TileConfig } from '../types';
|
|
4
4
|
export interface UseShadowCanvasConfigOptions {
|
|
5
5
|
fetcher: CanvasConfigFetcher;
|
|
6
|
-
pollIntervalMs?: number;
|
|
7
6
|
/** @deprecated Use runtime instead */
|
|
8
7
|
experiments?: ExperimentClient;
|
|
9
8
|
/** v2 Runtime for activation-based filtering */
|
|
10
9
|
runtime?: SmartCanvasRuntime;
|
|
10
|
+
/** Current page URL — triggers re-filter when URL changes (route-based activation).
|
|
11
|
+
* Full URL (not just pathname) so hash-based routing also triggers re-filter. */
|
|
12
|
+
pageUrl?: string;
|
|
11
13
|
}
|
|
12
14
|
export interface ShadowCanvasConfigState {
|
|
13
15
|
tiles: TileConfig[];
|
|
@@ -24,4 +26,4 @@ export interface ShadowCanvasConfigState {
|
|
|
24
26
|
/** Launcher button configuration */
|
|
25
27
|
launcher?: LauncherConfig;
|
|
26
28
|
}
|
|
27
|
-
export declare function useShadowCanvasConfig({ fetcher,
|
|
29
|
+
export declare function useShadowCanvasConfig({ fetcher, experiments, runtime, pageUrl, }: UseShadowCanvasConfigOptions): ShadowCanvasConfigState;
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -30,10 +30,9 @@ import {
|
|
|
30
30
|
appRegistry,
|
|
31
31
|
applyStaticSlotStyles,
|
|
32
32
|
base,
|
|
33
|
-
border,
|
|
34
|
-
brand,
|
|
35
33
|
cleanupAppContext,
|
|
36
34
|
createActionEngine,
|
|
35
|
+
createAnchorResolver,
|
|
37
36
|
createAppContext,
|
|
38
37
|
createAppLoader,
|
|
39
38
|
createCanvasConfigFetcher,
|
|
@@ -101,9 +100,10 @@ import {
|
|
|
101
100
|
validateAction,
|
|
102
101
|
validateActions,
|
|
103
102
|
widgetRegistry
|
|
104
|
-
} from "./chunk-
|
|
103
|
+
} from "./chunk-IPU3WVPY.js";
|
|
105
104
|
import {
|
|
106
105
|
AddClassZ,
|
|
106
|
+
AnchorIdZ,
|
|
107
107
|
BadgePositionZ,
|
|
108
108
|
BadgeZ,
|
|
109
109
|
CtaButtonZ,
|
|
@@ -134,18 +134,21 @@ import {
|
|
|
134
134
|
WaitZ,
|
|
135
135
|
WidgetConfigZ,
|
|
136
136
|
coreActionStepSchemas
|
|
137
|
-
} from "./chunk-
|
|
137
|
+
} from "./chunk-HF3D7YFQ.js";
|
|
138
|
+
import "./chunk-2UYZ5DWI.js";
|
|
138
139
|
import {
|
|
139
140
|
ActivationConfigZ,
|
|
140
141
|
AnchorVisibleConditionZ,
|
|
141
142
|
ConditionZ,
|
|
142
143
|
CooldownActiveConditionZ,
|
|
144
|
+
CounterDefZ,
|
|
143
145
|
DecisionStrategyZ,
|
|
144
146
|
DismissedConditionZ,
|
|
145
147
|
EventCountConditionZ,
|
|
146
148
|
EventOccurredConditionZ,
|
|
147
149
|
ExternalStrategyZ,
|
|
148
150
|
FrequencyLimitConditionZ,
|
|
151
|
+
MatchOpZ,
|
|
149
152
|
ModelStrategyZ,
|
|
150
153
|
PageUrlConditionZ,
|
|
151
154
|
RouteConditionZ,
|
|
@@ -160,8 +163,7 @@ import {
|
|
|
160
163
|
validateActivationConfig,
|
|
161
164
|
validateCondition,
|
|
162
165
|
validateStrategy
|
|
163
|
-
} from "./chunk-
|
|
164
|
-
import "./chunk-JMHRHAEL.js";
|
|
166
|
+
} from "./chunk-P5G4KT2U.js";
|
|
165
167
|
|
|
166
168
|
// src/index.ts
|
|
167
169
|
import React4 from "react";
|
|
@@ -841,14 +843,18 @@ var themeStyles = {
|
|
|
841
843
|
}
|
|
842
844
|
}
|
|
843
845
|
};
|
|
844
|
-
function FAQItem({ item, isExpanded, onToggle, theme, feedbackConfig, feedbackValue, onFeedback }) {
|
|
846
|
+
function FAQItem({ item, isExpanded, isHighlighted, onToggle, theme, feedbackConfig, feedbackValue, onFeedback }) {
|
|
845
847
|
const [isHovered, setIsHovered] = useState2(false);
|
|
846
848
|
const colors = themeStyles[theme];
|
|
847
849
|
const { question, answer } = item.config;
|
|
848
850
|
const itemStyle = {
|
|
849
851
|
...baseStyles.item,
|
|
850
852
|
...colors.item,
|
|
851
|
-
...isExpanded ? colors.itemExpanded : {}
|
|
853
|
+
...isExpanded ? colors.itemExpanded : {},
|
|
854
|
+
...isHighlighted ? {
|
|
855
|
+
boxShadow: "0 0 0 2px #6366f1, 0 0 12px rgba(99, 102, 241, 0.4)",
|
|
856
|
+
transition: "box-shadow 0.3s ease"
|
|
857
|
+
} : {}
|
|
852
858
|
};
|
|
853
859
|
const questionStyle = {
|
|
854
860
|
...baseStyles.question,
|
|
@@ -880,6 +886,7 @@ function FAQItem({ item, isExpanded, onToggle, theme, feedbackConfig, feedbackVa
|
|
|
880
886
|
function FAQWidget({ config, runtime: runtime7, instanceId }) {
|
|
881
887
|
const [renderTick, forceUpdate] = useReducer((x) => x + 1, 0);
|
|
882
888
|
const [expandedIds, setExpandedIds] = useState2(/* @__PURE__ */ new Set());
|
|
889
|
+
const [highlightId, setHighlightId] = useState2(null);
|
|
883
890
|
const [searchQuery, setSearchQuery] = useState2("");
|
|
884
891
|
const [feedbackState, setFeedbackState] = useState2(/* @__PURE__ */ new Map());
|
|
885
892
|
const feedbackConfig = useMemo(() => resolveFeedbackConfig(config.feedback), [config.feedback]);
|
|
@@ -897,43 +904,6 @@ function FAQWidget({ config, runtime: runtime7, instanceId }) {
|
|
|
897
904
|
forceUpdate();
|
|
898
905
|
});
|
|
899
906
|
}, [runtime7.accumulator]);
|
|
900
|
-
useEffect2(() => {
|
|
901
|
-
var _a, _b;
|
|
902
|
-
if (!config.scope || !((_a = runtime7.accumulator) == null ? void 0 : _a.register))
|
|
903
|
-
return;
|
|
904
|
-
const { events: eventNames, urlContains, props: propFilters } = config.scope;
|
|
905
|
-
const keys = /* @__PURE__ */ new Set();
|
|
906
|
-
for (const action of config.actions) {
|
|
907
|
-
if (((_b = action.showWhen) == null ? void 0 : _b.type) === "rules") {
|
|
908
|
-
for (const rule of action.showWhen.rules) {
|
|
909
|
-
for (const cond of rule.conditions) {
|
|
910
|
-
if (cond.type === "event_count" && cond.key) {
|
|
911
|
-
keys.add(cond.key);
|
|
912
|
-
}
|
|
913
|
-
}
|
|
914
|
-
}
|
|
915
|
-
}
|
|
916
|
-
}
|
|
917
|
-
for (const key of keys) {
|
|
918
|
-
runtime7.accumulator.register(key, (event) => {
|
|
919
|
-
var _a2, _b2, _c;
|
|
920
|
-
if (!eventNames.includes(event.name))
|
|
921
|
-
return false;
|
|
922
|
-
if (urlContains) {
|
|
923
|
-
const pathname = String((_b2 = (_a2 = event.props) == null ? void 0 : _a2.pathname) != null ? _b2 : "");
|
|
924
|
-
if (!pathname.includes(urlContains))
|
|
925
|
-
return false;
|
|
926
|
-
}
|
|
927
|
-
if (propFilters) {
|
|
928
|
-
for (const [k, v] of Object.entries(propFilters)) {
|
|
929
|
-
if (((_c = event.props) == null ? void 0 : _c[k]) !== v)
|
|
930
|
-
return false;
|
|
931
|
-
}
|
|
932
|
-
}
|
|
933
|
-
return true;
|
|
934
|
-
});
|
|
935
|
-
}
|
|
936
|
-
}, [config.scope, config.actions, runtime7.accumulator]);
|
|
937
907
|
useEffect2(() => {
|
|
938
908
|
if (!runtime7.events.subscribe)
|
|
939
909
|
return;
|
|
@@ -970,10 +940,43 @@ function FAQWidget({ config, runtime: runtime7, instanceId }) {
|
|
|
970
940
|
});
|
|
971
941
|
return unsubscribe;
|
|
972
942
|
}, [runtime7]);
|
|
943
|
+
useEffect2(() => {
|
|
944
|
+
if (!runtime7.events.subscribe)
|
|
945
|
+
return;
|
|
946
|
+
const handleDeepLink = (event) => {
|
|
947
|
+
var _a, _b;
|
|
948
|
+
const tileId = (_a = event.props) == null ? void 0 : _a.tileId;
|
|
949
|
+
const itemId = (_b = event.props) == null ? void 0 : _b.itemId;
|
|
950
|
+
if (tileId !== instanceId)
|
|
951
|
+
return;
|
|
952
|
+
if (!itemId)
|
|
953
|
+
return;
|
|
954
|
+
setExpandedIds(/* @__PURE__ */ new Set([itemId]));
|
|
955
|
+
setHighlightId(itemId);
|
|
956
|
+
setTimeout(() => setHighlightId(null), 1500);
|
|
957
|
+
requestAnimationFrame(() => {
|
|
958
|
+
const el = document.querySelector(`[data-faq-item-id="${itemId}"]`);
|
|
959
|
+
if (el)
|
|
960
|
+
el.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
961
|
+
});
|
|
962
|
+
};
|
|
963
|
+
if (runtime7.events.getRecent) {
|
|
964
|
+
const recent = runtime7.events.getRecent({ names: ["notification.deep_link"] }, 5);
|
|
965
|
+
const pending = recent.filter((e) => {
|
|
966
|
+
var _a, _b;
|
|
967
|
+
return ((_a = e.props) == null ? void 0 : _a.tileId) === instanceId && ((_b = e.props) == null ? void 0 : _b.itemId);
|
|
968
|
+
}).pop();
|
|
969
|
+
if (pending && Date.now() - pending.ts < 1e4) {
|
|
970
|
+
handleDeepLink(pending);
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
const unsubscribe = runtime7.events.subscribe({ names: ["notification.deep_link"] }, handleDeepLink);
|
|
974
|
+
return unsubscribe;
|
|
975
|
+
}, [runtime7, instanceId]);
|
|
973
976
|
const visibleQuestions = useMemo(() => config.actions.filter((q) => {
|
|
974
|
-
if (!q.
|
|
977
|
+
if (!q.triggerWhen)
|
|
975
978
|
return true;
|
|
976
|
-
const result = runtime7.evaluateSync(q.
|
|
979
|
+
const result = runtime7.evaluateSync(q.triggerWhen);
|
|
977
980
|
return result.value;
|
|
978
981
|
}), [config.actions, runtime7, renderTick]);
|
|
979
982
|
const orderedQuestions = useMemo(() => {
|
|
@@ -1067,7 +1070,7 @@ function FAQWidget({ config, runtime: runtime7, instanceId }) {
|
|
|
1067
1070
|
...baseStyles.categoryHeader,
|
|
1068
1071
|
...themeStyles[resolvedTheme].categoryHeader
|
|
1069
1072
|
};
|
|
1070
|
-
const renderItems = (items) => items.map((q) => _jsx2(FAQItem, { item: q, isExpanded: expandedIds.has(q.config.id), onToggle: () => handleToggle(q.config.id), theme: resolvedTheme, feedbackConfig, feedbackValue: feedbackState.get(q.config.id), onFeedback: handleFeedback }, q.config.id));
|
|
1073
|
+
const renderItems = (items) => items.map((q) => _jsx2(FAQItem, { item: q, isExpanded: expandedIds.has(q.config.id), isHighlighted: highlightId === q.config.id, onToggle: () => handleToggle(q.config.id), theme: resolvedTheme, feedbackConfig, feedbackValue: feedbackState.get(q.config.id), onFeedback: handleFeedback }, q.config.id));
|
|
1071
1074
|
if (visibleQuestions.length === 0) {
|
|
1072
1075
|
return _jsx2("div", { style: containerStyle, "data-adaptive-id": instanceId, "data-adaptive-type": "adaptive-faq", children: _jsx2("div", { style: emptyStateStyle, children: "No FAQ questions available." }) });
|
|
1073
1076
|
}
|
|
@@ -1136,14 +1139,14 @@ var runtime4 = {
|
|
|
1136
1139
|
/**
|
|
1137
1140
|
* Extract notify watcher entries from tile config props.
|
|
1138
1141
|
* The runtime evaluates these continuously (even with drawer closed)
|
|
1139
|
-
* and publishes faq:question_revealed when
|
|
1142
|
+
* and publishes faq:question_revealed when triggerWhen transitions false → true.
|
|
1140
1143
|
*/
|
|
1141
1144
|
notifyWatchers(props) {
|
|
1142
1145
|
var _a;
|
|
1143
1146
|
const actions = (_a = props.actions) != null ? _a : [];
|
|
1144
|
-
return actions.filter((a) => a.notify && a.
|
|
1147
|
+
return actions.filter((a) => a.notify && a.triggerWhen).map((a) => ({
|
|
1145
1148
|
id: `faq:${a.config.id}`,
|
|
1146
|
-
strategy: a.
|
|
1149
|
+
strategy: a.triggerWhen,
|
|
1147
1150
|
eventName: "faq:question_revealed",
|
|
1148
1151
|
eventProps: {
|
|
1149
1152
|
questionId: a.config.id,
|
|
@@ -1403,48 +1406,11 @@ function NavWidget({ config, runtime: runtime7, instanceId }) {
|
|
|
1403
1406
|
forceUpdate();
|
|
1404
1407
|
});
|
|
1405
1408
|
}, [runtime7.accumulator]);
|
|
1406
|
-
useEffect3(() => {
|
|
1407
|
-
var _a, _b;
|
|
1408
|
-
if (!config.scope || !((_a = runtime7.accumulator) == null ? void 0 : _a.register))
|
|
1409
|
-
return;
|
|
1410
|
-
const { events: eventNames, urlContains, props: propFilters } = config.scope;
|
|
1411
|
-
const keys = /* @__PURE__ */ new Set();
|
|
1412
|
-
for (const action of config.actions) {
|
|
1413
|
-
if (((_b = action.showWhen) == null ? void 0 : _b.type) === "rules") {
|
|
1414
|
-
for (const rule of action.showWhen.rules) {
|
|
1415
|
-
for (const cond of rule.conditions) {
|
|
1416
|
-
if (cond.type === "event_count" && cond.key) {
|
|
1417
|
-
keys.add(cond.key);
|
|
1418
|
-
}
|
|
1419
|
-
}
|
|
1420
|
-
}
|
|
1421
|
-
}
|
|
1422
|
-
}
|
|
1423
|
-
for (const key of keys) {
|
|
1424
|
-
runtime7.accumulator.register(key, (event) => {
|
|
1425
|
-
var _a2, _b2, _c;
|
|
1426
|
-
if (!eventNames.includes(event.name))
|
|
1427
|
-
return false;
|
|
1428
|
-
if (urlContains) {
|
|
1429
|
-
const pathname = String((_b2 = (_a2 = event.props) == null ? void 0 : _a2.pathname) != null ? _b2 : "");
|
|
1430
|
-
if (!pathname.includes(urlContains))
|
|
1431
|
-
return false;
|
|
1432
|
-
}
|
|
1433
|
-
if (propFilters) {
|
|
1434
|
-
for (const [k, v] of Object.entries(propFilters)) {
|
|
1435
|
-
if (((_c = event.props) == null ? void 0 : _c[k]) !== v)
|
|
1436
|
-
return false;
|
|
1437
|
-
}
|
|
1438
|
-
}
|
|
1439
|
-
return true;
|
|
1440
|
-
});
|
|
1441
|
-
}
|
|
1442
|
-
}, [config.scope, config.actions, runtime7.accumulator]);
|
|
1443
1409
|
const visibleTips = useMemo2(() => config.actions.filter((tip) => {
|
|
1444
|
-
if (!tip.
|
|
1410
|
+
if (!tip.triggerWhen)
|
|
1445
1411
|
return true;
|
|
1446
1412
|
try {
|
|
1447
|
-
const result = runtime7.evaluateSync(tip.
|
|
1413
|
+
const result = runtime7.evaluateSync(tip.triggerWhen);
|
|
1448
1414
|
return result.value;
|
|
1449
1415
|
} catch {
|
|
1450
1416
|
return false;
|
|
@@ -1518,7 +1484,9 @@ function NavWidget({ config, runtime: runtime7, instanceId }) {
|
|
|
1518
1484
|
if (external) {
|
|
1519
1485
|
window.open(href, "_blank", "noopener,noreferrer");
|
|
1520
1486
|
} else {
|
|
1521
|
-
window.location.
|
|
1487
|
+
const url = new URL(href, window.location.origin);
|
|
1488
|
+
url.search = window.location.search;
|
|
1489
|
+
window.location.href = url.toString();
|
|
1522
1490
|
}
|
|
1523
1491
|
}, [runtime7.events, instanceId]);
|
|
1524
1492
|
const containerStyle = {
|
|
@@ -1580,7 +1548,9 @@ var executeScrollTo = async (action, context) => {
|
|
|
1580
1548
|
var _a, _b, _c, _d;
|
|
1581
1549
|
const anchorEl = context.resolveAnchor(action.anchorId);
|
|
1582
1550
|
if (!anchorEl) {
|
|
1583
|
-
|
|
1551
|
+
console.error(`[adaptive-nav] Anchor not found for scrollTo, skipping: ${action.anchorId.selector}`);
|
|
1552
|
+
return { cleanup: () => {
|
|
1553
|
+
} };
|
|
1584
1554
|
}
|
|
1585
1555
|
anchorEl.scrollIntoView({
|
|
1586
1556
|
behavior: (_a = action.behavior) != null ? _a : "smooth",
|
|
@@ -1662,14 +1632,14 @@ var runtime6 = {
|
|
|
1662
1632
|
/**
|
|
1663
1633
|
* Extract notify watcher entries from tile config props.
|
|
1664
1634
|
* The runtime evaluates these continuously (even with drawer closed)
|
|
1665
|
-
* and publishes nav:tip_revealed when
|
|
1635
|
+
* and publishes nav:tip_revealed when triggerWhen transitions false → true.
|
|
1666
1636
|
*/
|
|
1667
1637
|
notifyWatchers(props) {
|
|
1668
1638
|
var _a;
|
|
1669
1639
|
const actions = (_a = props.actions) != null ? _a : [];
|
|
1670
|
-
return actions.filter((a) => a.notify && a.
|
|
1640
|
+
return actions.filter((a) => a.notify && a.triggerWhen).map((a) => ({
|
|
1671
1641
|
id: `nav:${a.config.id}`,
|
|
1672
|
-
strategy: a.
|
|
1642
|
+
strategy: a.triggerWhen,
|
|
1673
1643
|
eventName: "nav:tip_revealed",
|
|
1674
1644
|
eventProps: {
|
|
1675
1645
|
tipId: a.config.id,
|
|
@@ -1744,8 +1714,8 @@ function TileWheel({ tiles, intervalMs = 7e3, telemetry }) {
|
|
|
1744
1714
|
position: "relative",
|
|
1745
1715
|
overflow: "hidden",
|
|
1746
1716
|
borderRadius: "1.5rem",
|
|
1747
|
-
border:
|
|
1748
|
-
background:
|
|
1717
|
+
border: "var(--sc-tile-border)",
|
|
1718
|
+
background: "var(--sc-tile-background)",
|
|
1749
1719
|
padding: "1.5rem",
|
|
1750
1720
|
boxShadow: "0 25px 50px -12px rgba(0, 0, 0, 0.25)"
|
|
1751
1721
|
},
|
|
@@ -1771,7 +1741,7 @@ function TileWheel({ tiles, intervalMs = 7e3, telemetry }) {
|
|
|
1771
1741
|
height: "0.5rem",
|
|
1772
1742
|
width: "1.5rem",
|
|
1773
1743
|
borderRadius: "9999px",
|
|
1774
|
-
background: idx === index ?
|
|
1744
|
+
background: idx === index ? "var(--sc-color-primary)" : "var(--sc-tile-text-color)",
|
|
1775
1745
|
border: "none",
|
|
1776
1746
|
cursor: "pointer",
|
|
1777
1747
|
padding: 0
|
|
@@ -2086,6 +2056,7 @@ export {
|
|
|
2086
2056
|
ANIMATION_KEYFRAMES,
|
|
2087
2057
|
ActivationConfigZ,
|
|
2088
2058
|
AddClassZ,
|
|
2059
|
+
AnchorIdZ,
|
|
2089
2060
|
AnchorStateZ,
|
|
2090
2061
|
AnchorVisibleConditionZ,
|
|
2091
2062
|
AppRegistry,
|
|
@@ -2098,6 +2069,7 @@ export {
|
|
|
2098
2069
|
ConditionZ,
|
|
2099
2070
|
ContextManager,
|
|
2100
2071
|
CooldownActiveConditionZ,
|
|
2072
|
+
CounterDefZ,
|
|
2101
2073
|
CtaButtonZ,
|
|
2102
2074
|
DEFAULT_COOLDOWN,
|
|
2103
2075
|
DEFAULT_TTL,
|
|
@@ -2119,6 +2091,7 @@ export {
|
|
|
2119
2091
|
InsertHtmlZ,
|
|
2120
2092
|
InsertPositionZ,
|
|
2121
2093
|
MAX_VISIBLE_TOASTS,
|
|
2094
|
+
MatchOpZ,
|
|
2122
2095
|
ModalContentZ,
|
|
2123
2096
|
ModalZ,
|
|
2124
2097
|
ModelStrategyZ,
|
|
@@ -2187,6 +2160,7 @@ export {
|
|
|
2187
2160
|
runtime as contentRuntime,
|
|
2188
2161
|
coreActionStepSchemas,
|
|
2189
2162
|
createActionEngine,
|
|
2163
|
+
createAnchorResolver,
|
|
2190
2164
|
createAppContext,
|
|
2191
2165
|
createAppLoader,
|
|
2192
2166
|
createCanvasConfigFetcher,
|