@syntrologie/runtime-sdk 2.8.0-canary.63 → 2.8.0-canary.65

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.
@@ -20679,7 +20679,7 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
20679
20679
  }
20680
20680
 
20681
20681
  // src/version.ts
20682
- var SDK_VERSION = "2.8.0-canary.63";
20682
+ var SDK_VERSION = "2.8.0-canary.65";
20683
20683
 
20684
20684
  // src/types.ts
20685
20685
  var SDK_SCHEMA_VERSION = "2.0";
@@ -37037,32 +37037,7 @@ ${cssRules}
37037
37037
  // Capture performance metrics
37038
37038
  capture_performance: true,
37039
37039
  // Enable web vitals
37040
- enable_recording_console_log: true,
37041
- // Bootstrap callback for when flags are loaded
37042
- loaded: (ph) => {
37043
- if (enableFeatureFlags && this.featureFlagsCallback) {
37044
- ph.onFeatureFlags(() => {
37045
- const allFlags = this.getAllFeatureFlags();
37046
- if (allFlags && this.featureFlagsCallback) {
37047
- this.featureFlagsCallback(allFlags);
37048
- }
37049
- });
37050
- const existingFlags = this.getAllFeatureFlags();
37051
- if (existingFlags && Object.keys(existingFlags).length > 0) {
37052
- this.featureFlagsCallback(existingFlags);
37053
- }
37054
- }
37055
- if (this.captureCallback) {
37056
- ph.on("eventCaptured", (...args) => {
37057
- const data = args[0];
37058
- const eventName = typeof data === "string" ? data : data?.event;
37059
- const properties = typeof data === "string" ? void 0 : data?.properties;
37060
- if (typeof eventName === "string") {
37061
- this.captureCallback?.(eventName, properties);
37062
- }
37063
- });
37064
- }
37065
- }
37040
+ enable_recording_console_log: true
37066
37041
  };
37067
37042
  const result = Jo.init(
37068
37043
  options.apiKey,
@@ -37072,6 +37047,28 @@ ${cssRules}
37072
37047
  if (result) {
37073
37048
  this.client = result;
37074
37049
  }
37050
+ if (this.captureCallback && this.client) {
37051
+ this.client.on("eventCaptured", (...args) => {
37052
+ const data = args[0];
37053
+ const eventName = typeof data === "string" ? data : data?.event;
37054
+ const properties = typeof data === "string" ? void 0 : data?.properties;
37055
+ if (typeof eventName === "string") {
37056
+ this.captureCallback?.(eventName, properties);
37057
+ }
37058
+ });
37059
+ }
37060
+ if (enableFeatureFlags && this.featureFlagsCallback && this.client) {
37061
+ this.client.onFeatureFlags(() => {
37062
+ const allFlags = this.getAllFeatureFlags();
37063
+ if (allFlags && this.featureFlagsCallback) {
37064
+ this.featureFlagsCallback(allFlags);
37065
+ }
37066
+ });
37067
+ const existingFlags = this.getAllFeatureFlags();
37068
+ if (existingFlags && Object.keys(existingFlags).length > 0) {
37069
+ this.featureFlagsCallback(existingFlags);
37070
+ }
37071
+ }
37075
37072
  if (this.rrwebCallback && this.client) {
37076
37073
  this.setupRRWebIntercept();
37077
37074
  }
@@ -38477,74 +38474,97 @@ ${cssRules}
38477
38474
  selector: external_exports.string(),
38478
38475
  route: external_exports.union([external_exports.string(), external_exports.array(external_exports.string())])
38479
38476
  }).strict();
38477
+ var COUNTABLE_EVENTS = [
38478
+ // User interactions (from PostHog autocapture normalization)
38479
+ "ui.click",
38480
+ "ui.scroll",
38481
+ "ui.input",
38482
+ "ui.change",
38483
+ "ui.submit",
38484
+ // Behavioral detectors (from event-processor)
38485
+ "ui.hover",
38486
+ "ui.idle",
38487
+ "ui.scroll_thrash",
38488
+ "ui.focus_bounce",
38489
+ // Navigation
38490
+ "nav.page_view",
38491
+ "nav.page_leave",
38492
+ // Derived behavioral signals
38493
+ "behavior.rage_click",
38494
+ "behavior.hesitation",
38495
+ "behavior.confusion"
38496
+ ];
38497
+ var CountableEventZ = external_exports.enum(COUNTABLE_EVENTS).describe("Event name to count. ui.* = user interactions and behavioral detectors, nav.* = page navigation, behavior.* = derived behavioral signals.");
38498
+ var SESSION_METRIC_KEYS = ["time_on_page", "page_views", "scroll_depth"];
38499
+ var SessionMetricKeyZ = external_exports.enum(SESSION_METRIC_KEYS).describe("Session metric key. time_on_page = seconds on current page, page_views = pages visited this session, scroll_depth = 0-100 percentage.");
38480
38500
  var PageUrlConditionZ = external_exports.object({
38481
38501
  type: external_exports.literal("page_url"),
38482
- url: external_exports.string()
38483
- });
38502
+ url: external_exports.string().describe('URL path to match (e.g. "/pricing", "/dashboard")')
38503
+ }).describe('Fires when the current page URL matches. Use for page-specific actions. Example: {"type": "page_url", "url": "/pricing"}');
38484
38504
  var RouteConditionZ = external_exports.object({
38485
38505
  type: external_exports.literal("route"),
38486
- routeId: external_exports.string()
38487
- });
38506
+ routeId: external_exports.string().describe("Named route ID from the route filter")
38507
+ }).describe("Fires when the current route matches a named route ID.");
38488
38508
  var AnchorVisibleConditionZ = external_exports.object({
38489
38509
  type: external_exports.literal("anchor_visible"),
38490
- anchorId: external_exports.string(),
38491
- state: external_exports.enum(["visible", "present", "absent"])
38492
- });
38510
+ anchorId: external_exports.string().describe("CSS selector of the anchor element"),
38511
+ state: external_exports.enum(["visible", "present", "absent"]).describe('"visible" = in viewport, "present" = in DOM, "absent" = not in DOM')
38512
+ }).describe(`Fires based on a DOM element's visibility state. Example: {"type": "anchor_visible", "anchorId": "#cta-button", "state": "visible"}`);
38493
38513
  var EventOccurredConditionZ = external_exports.object({
38494
38514
  type: external_exports.literal("event_occurred"),
38495
- eventName: external_exports.string(),
38496
- withinMs: external_exports.number().optional()
38497
- });
38515
+ eventName: external_exports.string().describe('Event name (e.g. "ui.click", "$pageview")'),
38516
+ withinMs: external_exports.number().optional().describe("Time window in ms. Omit = any time this session.")
38517
+ }).describe('Fires when a specific event has occurred during this session. Example: {"type": "event_occurred", "eventName": "ui.click", "withinMs": 5000}');
38498
38518
  var StateEqualsConditionZ = external_exports.object({
38499
38519
  type: external_exports.literal("state_equals"),
38500
- key: external_exports.string(),
38501
- value: external_exports.unknown()
38502
- });
38520
+ key: external_exports.string().describe("Key in the SDK persistent state store (localStorage). Only valid for keys the host app explicitly sets via syntro.state.set()."),
38521
+ value: external_exports.unknown().describe("Expected value to match against")
38522
+ }).describe("Checks the SDK persistent state store (localStorage). ONLY for host-app state set via syntro.state.set() \u2014 NOT for user attributes like region, device, or UTM params (those are handled by segment targeting). Do NOT use this for targeting. If you do not know the valid state keys, do not use this condition type.");
38503
38523
  var ViewportConditionZ = external_exports.object({
38504
38524
  type: external_exports.literal("viewport"),
38505
- minWidth: external_exports.number().optional(),
38506
- maxWidth: external_exports.number().optional(),
38507
- minHeight: external_exports.number().optional(),
38508
- maxHeight: external_exports.number().optional()
38509
- });
38525
+ minWidth: external_exports.number().optional().describe("Minimum viewport width in pixels"),
38526
+ maxWidth: external_exports.number().optional().describe("Maximum viewport width in pixels"),
38527
+ minHeight: external_exports.number().optional().describe("Minimum viewport height in pixels"),
38528
+ maxHeight: external_exports.number().optional().describe("Maximum viewport height in pixels")
38529
+ }).describe('Fires based on viewport (screen) size. Use for responsive behavior. Example: {"type": "viewport", "minWidth": 768} \u2014 fires on tablet and larger.');
38510
38530
  var SessionMetricConditionZ = external_exports.object({
38511
38531
  type: external_exports.literal("session_metric"),
38512
- key: external_exports.string(),
38532
+ key: SessionMetricKeyZ,
38513
38533
  operator: external_exports.enum(["gte", "lte", "eq", "gt", "lt"]),
38514
- threshold: external_exports.number()
38515
- });
38534
+ threshold: external_exports.number().describe("Numeric threshold to compare against")
38535
+ }).describe('Fires when a session metric crosses a threshold. Valid keys: "time_on_page" (seconds), "page_views" (count), "scroll_depth" (0-100). Example: {"type": "session_metric", "key": "time_on_page", "operator": "gte", "threshold": 30}');
38516
38536
  var DismissedConditionZ = external_exports.object({
38517
38537
  type: external_exports.literal("dismissed"),
38518
- key: external_exports.string(),
38519
- inverted: external_exports.boolean().optional()
38520
- });
38538
+ key: external_exports.string().describe("Dismissal key (usually a tile or action ID)"),
38539
+ inverted: external_exports.boolean().optional().describe("When true, fires if NOT dismissed (default behavior)")
38540
+ }).describe("Checks if an item has been dismissed by the user. Use with inverted: true to show only if not dismissed.");
38521
38541
  var CooldownActiveConditionZ = external_exports.object({
38522
38542
  type: external_exports.literal("cooldown_active"),
38523
- key: external_exports.string(),
38524
- inverted: external_exports.boolean().optional()
38525
- });
38543
+ key: external_exports.string().describe("Cooldown key"),
38544
+ inverted: external_exports.boolean().optional().describe("When true, fires if cooldown is NOT active")
38545
+ }).describe("Checks if a cooldown timer is currently active. Use to prevent showing the same intervention too frequently.");
38526
38546
  var FrequencyLimitConditionZ = external_exports.object({
38527
38547
  type: external_exports.literal("frequency_limit"),
38528
- key: external_exports.string(),
38529
- limit: external_exports.number(),
38530
- inverted: external_exports.boolean().optional()
38531
- });
38548
+ key: external_exports.string().describe("Frequency counter key"),
38549
+ limit: external_exports.number().describe("Maximum allowed count"),
38550
+ inverted: external_exports.boolean().optional().describe("When true, fires if limit NOT reached")
38551
+ }).describe("Checks if a frequency limit has been reached. Use to cap how many times an action fires per session.");
38532
38552
  var MatchOpZ = external_exports.object({
38533
38553
  equals: external_exports.union([external_exports.string(), external_exports.number(), external_exports.boolean()]).optional(),
38534
38554
  contains: external_exports.string().optional()
38535
- });
38555
+ }).describe("Match operator for counter filters. Exactly one of equals or contains must be specified.");
38536
38556
  var CounterDefZ = external_exports.object({
38537
- events: external_exports.array(external_exports.string()).min(1),
38538
- match: external_exports.record(external_exports.string(), MatchOpZ).optional()
38539
- });
38557
+ events: external_exports.array(CountableEventZ).min(1).describe("Event names to count. Use values from the countable events enum."),
38558
+ match: external_exports.record(external_exports.string(), MatchOpZ).optional().describe("Property filters. Keys are event prop names or element-chain fields (tag_name, $el_text, attr__*). All entries AND together.")
38559
+ }).describe("Defines what events to count. Registered as an accumulator predicate at config-load time.");
38540
38560
  var EventCountConditionZ = external_exports.object({
38541
38561
  type: external_exports.literal("event_count"),
38542
- key: external_exports.string(),
38562
+ key: external_exports.string().describe("Unique key for this counter (used for accumulator registration)"),
38543
38563
  operator: external_exports.enum(["gte", "lte", "eq", "gt", "lt"]),
38544
- count: external_exports.number().int().min(0),
38545
- withinMs: external_exports.number().positive().optional(),
38546
- counter: CounterDefZ.optional()
38547
- });
38564
+ count: external_exports.number().int().min(0).describe("Target count threshold"),
38565
+ withinMs: external_exports.number().positive().optional().describe("Time window in ms. Omit = count across entire session."),
38566
+ counter: CounterDefZ.optional().describe("Inline counter definition. Defines what events to count.")
38567
+ }).describe('Fires when accumulated event count crosses a threshold. Most powerful trigger type. Example: {"type": "event_count", "key": "pricing-clicks", "operator": "gte", "count": 3, "counter": {"events": ["ui.click"], "match": {"attr__data-cta": {"contains": "pricing"}}}}');
38548
38568
  var ConditionZ = external_exports.discriminatedUnion("type", [
38549
38569
  PageUrlConditionZ,
38550
38570
  RouteConditionZ,
@@ -38559,35 +38579,35 @@ ${cssRules}
38559
38579
  EventCountConditionZ
38560
38580
  ]);
38561
38581
  var RuleZ = external_exports.object({
38562
- conditions: external_exports.array(ConditionZ),
38563
- value: external_exports.unknown()
38564
- });
38582
+ conditions: external_exports.array(ConditionZ).describe("Array of conditions \u2014 ALL must match (AND logic) for this rule to fire."),
38583
+ value: external_exports.unknown().describe("Value returned when all conditions match. For triggerWhen: true = fire the action.")
38584
+ }).describe("A single rule. ALL conditions must match (AND logic). Rules in a strategy are evaluated top-to-bottom \u2014 first rule where all conditions match wins and returns its value.");
38565
38585
  var RuleStrategyZ = external_exports.object({
38566
38586
  type: external_exports.literal("rules"),
38567
- rules: external_exports.array(RuleZ),
38568
- default: external_exports.unknown()
38569
- });
38587
+ rules: external_exports.array(RuleZ).describe("Ordered list of rules. Evaluated top-to-bottom \u2014 first match wins."),
38588
+ default: external_exports.unknown().describe("Fallback value when no rule matches. For triggerWhen: false = do not fire by default.")
38589
+ }).describe("Rule-based strategy. Evaluates rules top-to-bottom. First rule where ALL conditions match returns its value. If no rule matches, returns default. For triggerWhen: set value=true on matching rules, default=false.");
38570
38590
  var ScoreStrategyZ = external_exports.object({
38571
38591
  type: external_exports.literal("score"),
38572
38592
  field: external_exports.string(),
38573
38593
  threshold: external_exports.number(),
38574
38594
  above: external_exports.unknown(),
38575
38595
  below: external_exports.unknown()
38576
- });
38596
+ }).describe("Score-based strategy. Compares a field value against a threshold.");
38577
38597
  var ModelStrategyZ = external_exports.object({
38578
38598
  type: external_exports.literal("model"),
38579
38599
  modelId: external_exports.string(),
38580
38600
  inputs: external_exports.array(external_exports.string()),
38581
38601
  outputMapping: external_exports.record(external_exports.string(), external_exports.unknown()),
38582
38602
  default: external_exports.unknown()
38583
- });
38603
+ }).describe("ML model strategy. Sends inputs to a model and maps outputs.");
38584
38604
  var ExternalStrategyZ = external_exports.object({
38585
38605
  type: external_exports.literal("external"),
38586
38606
  endpoint: external_exports.string(),
38587
38607
  method: external_exports.enum(["GET", "POST"]).optional(),
38588
38608
  default: external_exports.unknown(),
38589
38609
  timeoutMs: external_exports.number().optional()
38590
- });
38610
+ }).describe("External API strategy. Calls an endpoint to determine the value.");
38591
38611
  var DecisionStrategyZ = external_exports.discriminatedUnion("type", [
38592
38612
  RuleStrategyZ,
38593
38613
  ScoreStrategyZ,
@@ -42120,7 +42140,7 @@ ${cssRules}
42120
42140
  }
42121
42141
 
42122
42142
  // src/index.ts
42123
- var RUNTIME_SDK_BUILD = true ? `${"2026-04-13T03:02:09.724Z"} (${"709fe972866"})` : "dev";
42143
+ var RUNTIME_SDK_BUILD = true ? `${"2026-04-13T17:37:13.929Z"} (${"e3f2c1dda1d"})` : "dev";
42124
42144
  if (typeof window !== "undefined") {
42125
42145
  console.log(`[Syntro Runtime] Build: ${RUNTIME_SDK_BUILD}`);
42126
42146
  const existing = window.SynOS;