@syntrologie/runtime-sdk 2.11.0 → 2.12.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.
Files changed (55) hide show
  1. package/CAPABILITIES.md +176 -117
  2. package/README.md +2 -0
  3. package/dist/actions/schema.d.ts +7 -7
  4. package/dist/actions/schema.js +3 -4
  5. package/dist/actions/types.d.ts +1 -1
  6. package/dist/actions/validation-core.d.ts +24 -0
  7. package/dist/actions/validation-rules.d.ts +74 -0
  8. package/dist/actions/validation.d.ts +5 -11
  9. package/dist/bootstrap-init.d.ts +33 -0
  10. package/dist/bootstrap-runtime.d.ts +7 -0
  11. package/dist/bootstrap-types.d.ts +90 -0
  12. package/dist/bootstrap.d.ts +17 -83
  13. package/dist/{chunk-Q77NT67W.js → chunk-BU4Z6PD7.js} +16 -1
  14. package/dist/{chunk-Q77NT67W.js.map → chunk-BU4Z6PD7.js.map} +1 -1
  15. package/dist/{chunk-H3FAYTUV.js → chunk-J2LGX2PV.js} +1216 -394
  16. package/dist/chunk-J2LGX2PV.js.map +7 -0
  17. package/dist/{chunk-NBFQGKSV.js → chunk-L6RJMBR2.js} +4 -4
  18. package/dist/{chunk-NBFQGKSV.js.map → chunk-L6RJMBR2.js.map} +2 -2
  19. package/dist/{chunk-37TTQRH5.js → chunk-XDYJ64IN.js} +2 -2
  20. package/dist/config/schema.js +2 -3
  21. package/dist/decisions/schema.js +1 -2
  22. package/dist/events/EventBus.d.ts +27 -1
  23. package/dist/events/history.d.ts +9 -0
  24. package/dist/events/index.d.ts +3 -0
  25. package/dist/events/types.d.ts +24 -0
  26. package/dist/events/validation.d.ts +7 -0
  27. package/dist/index.d.ts +0 -2
  28. package/dist/index.js +1131 -2039
  29. package/dist/index.js.map +4 -4
  30. package/dist/overlays/runtime/overlay/overlay-runner.d.ts +4 -0
  31. package/dist/overlays/runtime/overlay/overlay-state.d.ts +21 -0
  32. package/dist/overlays/types.d.ts +3 -1
  33. package/dist/react.js +6 -5
  34. package/dist/react.js.map +2 -2
  35. package/dist/smart-canvas.esm.js +92 -108
  36. package/dist/smart-canvas.esm.js.map +4 -4
  37. package/dist/smart-canvas.js +4649 -4957
  38. package/dist/smart-canvas.js.map +4 -4
  39. package/dist/smart-canvas.min.js +92 -108
  40. package/dist/smart-canvas.min.js.map +4 -4
  41. package/dist/telemetry/adapters/posthog.d.ts +5 -10
  42. package/dist/test/setup.d.ts +1 -0
  43. package/dist/token.d.ts +2 -0
  44. package/dist/version.d.ts +1 -1
  45. package/package.json +23 -29
  46. package/schema/canvas-config.schema.json +1 -1
  47. package/scripts/syntroReactPlugin.mjs +3 -0
  48. package/scripts/validate-config.mjs +42 -0
  49. package/dist/chunk-H3FAYTUV.js.map +0 -7
  50. package/dist/chunk-JMHRHAEL.js +0 -18
  51. package/dist/chunk-JMHRHAEL.js.map +0 -7
  52. package/dist/replayMirror-QZ3GQ527.js +0 -32
  53. package/dist/replayMirror-QZ3GQ527.js.map +0 -7
  54. package/dist/telemetry/replayMirror.d.ts +0 -7
  55. /package/dist/{chunk-37TTQRH5.js.map → chunk-XDYJ64IN.js.map} +0 -0
@@ -32,10 +32,12 @@ export interface PostHogAdapterOptions {
32
32
  */
33
33
  sessionRecording?: boolean;
34
34
  /**
35
- * Enable pageview capture.
36
- * @default true
35
+ * Pageview capture mode.
36
+ * - true: capture only on initial page load
37
+ * - 'history_change': auto-capture on SPA navigation (pushState/replaceState)
38
+ * @default "history_change"
37
39
  */
38
- capturePageview?: boolean;
40
+ capturePageview?: boolean | 'history_change';
39
41
  /**
40
42
  * Enable page leave capture.
41
43
  * @default true
@@ -77,12 +79,6 @@ export interface PostHogAdapterOptions {
77
79
  * @default false
78
80
  */
79
81
  behavioralSignals?: boolean | Record<string, number>;
80
- /**
81
- * Endpoint URL to mirror session recording payloads.
82
- * When set, recording requests to PostHog's /s/ endpoint are also
83
- * sent (fire-and-forget) to this URL.
84
- */
85
- replayMirrorEndpoint?: string;
86
82
  /**
87
83
  * Callback for raw rrweb events from session recording.
88
84
  * Called with each rrweb eventWithTime before PostHog processes it.
@@ -103,7 +99,6 @@ export declare class PostHogAdapter implements TelemetryClient {
103
99
  private featureFlagsCallback?;
104
100
  private captureCallback?;
105
101
  private rrwebCallback?;
106
- private consentUnsub?;
107
102
  constructor(options?: PostHogAdapterOptions);
108
103
  /**
109
104
  * Initialize the PostHog client. Called immediately (no consent gate)
@@ -0,0 +1 @@
1
+ import '@testing-library/jest-dom/vitest';
package/dist/token.d.ts CHANGED
@@ -20,6 +20,8 @@ export interface SyntroTokenPayload {
20
20
  f?: string;
21
21
  /** Fetcher-specific options (e.g., configId for cdn fetcher) */
22
22
  o?: Record<string, string>;
23
+ /** Geo worker URL (e.g., "https://dev-geo.syntrologie.com" for dev) */
24
+ g?: string;
23
25
  /** Debug mode - enables console logging (default: false) */
24
26
  d?: boolean;
25
27
  }
package/dist/version.d.ts CHANGED
@@ -10,4 +10,4 @@
10
10
  *
11
11
  * @since 2.0.0
12
12
  */
13
- export declare const SDK_VERSION = "2.11.0";
13
+ export declare const SDK_VERSION = "2.12.0";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@syntrologie/runtime-sdk",
3
- "version": "2.11.0",
3
+ "version": "2.12.0",
4
4
  "description": "Syntrologie Runtime SDK for web experimentation and analytics",
5
5
  "license": "Proprietary",
6
6
  "private": false,
@@ -61,22 +61,16 @@
61
61
  "validate-config": "node ./scripts/validate-config.mjs",
62
62
  "typecheck": "tsc --noEmit -p tsconfig.build.json",
63
63
  "test": "vitest run",
64
- "prepublishOnly": "npm run clean && npm run build"
64
+ "strip-internal-deps": "node ./scripts/strip-internal-deps.mjs",
65
+ "prepublishOnly": "npm run clean && npm run build && npm run strip-internal-deps"
65
66
  },
66
67
  "dependencies": {
67
- "@floating-ui/dom": "^1.7.5",
68
+ "@floating-ui/dom": "1.7.5",
68
69
  "@growthbook/growthbook": "~1.6.2",
69
- "@growthbook/growthbook-react": "^1.6.4",
70
- "@syntrologie/adapt-chatbot": "2.11.0",
71
- "@syntrologie/adapt-content": "2.11.0",
72
- "@syntrologie/adapt-faq": "2.11.0",
73
- "@syntrologie/adapt-gamification": "2.11.0",
74
- "@syntrologie/adapt-nav": "2.11.0",
75
- "@syntrologie/adapt-overlays": "2.11.0",
76
- "@syntrologie/event-processor": "*",
77
- "lucide-react": "^0.576.0",
78
- "posthog-js": "~1.302.2",
79
- "zod": "^3.25.76"
70
+ "@growthbook/growthbook-react": "1.6.4",
71
+ "lucide-react": "0.576.0",
72
+ "posthog-js": "1.341.0",
73
+ "zod": "3.25.76"
80
74
  },
81
75
  "peerDependencies": {
82
76
  "react": ">=18.0.0",
@@ -87,21 +81,21 @@
87
81
  "@semantic-release/github": "~12.0.3",
88
82
  "@semantic-release/npm": "~13.1.3",
89
83
  "@syntro/design-system": "*",
90
- "@testing-library/dom": "^10.4.1",
91
- "@testing-library/jest-dom": "^6.9.1",
92
- "@testing-library/react": "^16.3.2",
93
- "@types/node": "^22.19.7",
94
- "@types/react": "^19.2.0",
95
- "@types/react-dom": "^19.2.0",
96
- "ajv": "^8.18.0",
97
- "ajv-formats": "^3.0.1",
98
- "esbuild": "^0.27.2",
99
- "jsdom": "^26.1.0",
100
- "react": "^19.2.0",
101
- "react-dom": "^19.2.0",
84
+ "@testing-library/dom": "10.4.1",
85
+ "@testing-library/jest-dom": "6.9.1",
86
+ "@testing-library/react": "16.3.2",
87
+ "@types/node": "22.19.7",
88
+ "@types/react": "19.2.14",
89
+ "@types/react-dom": "19.2.3",
90
+ "ajv": "8.18.0",
91
+ "ajv-formats": "3.0.1",
92
+ "esbuild": "0.27.2",
93
+ "jsdom": "26.1.0",
94
+ "react": "19.2.1",
95
+ "react-dom": "19.2.1",
102
96
  "semantic-release": "~25.0.3",
103
- "typescript": "^5.9.3",
104
- "vitest": "^4.0.18",
105
- "zod-to-json-schema": "^3.25.1"
97
+ "typescript": "5.9.3",
98
+ "vitest": "4.0.18",
99
+ "zod-to-json-schema": "3.25.1"
106
100
  }
107
101
  }
@@ -9337,7 +9337,7 @@
9337
9337
  "properties": {
9338
9338
  "kind": {
9339
9339
  "type": "string",
9340
- "const": "core:tour"
9340
+ "const": "overlays:tour"
9341
9341
  },
9342
9342
  "tourId": {
9343
9343
  "type": "string"
@@ -71,6 +71,9 @@ export const syntroReactPlugin = {
71
71
  export function useReducer() { return _R().useReducer.apply(null, arguments); }
72
72
  export function useLayoutEffect() { return _R().useLayoutEffect.apply(null, arguments); }
73
73
  export function useId() { return _R().useId.apply(null, arguments); }
74
+ export function useSyncExternalStore() { return _R().useSyncExternalStore.apply(null, arguments); }
75
+ export function useDebugValue() { return _R().useDebugValue.apply(null, arguments); }
76
+ export function useInsertionEffect() { return _R().useInsertionEffect.apply(null, arguments); }
74
77
 
75
78
  // Creation APIs — lazy function wrappers
76
79
  export function createElement() { return _R().createElement.apply(null, arguments); }
@@ -119,6 +119,29 @@ if (semanticErrors.length > 0) {
119
119
  process.exit(1);
120
120
  }
121
121
 
122
+ // --- Semantic check: tiles with notifications must have actions ---
123
+ // Notifications reference content (FAQ items, nav tips) that lives in
124
+ // tile.props.actions. Without actions, notifications have nothing to show.
125
+ for (const tile of config.tiles ?? []) {
126
+ const notifications = tile.notifications ?? [];
127
+ if (notifications.length === 0) continue;
128
+
129
+ const actions = tile.props?.actions ?? [];
130
+ if (actions.length === 0) {
131
+ semanticErrors.push(
132
+ `Tile "${tile.id}": has ${notifications.length} notification(s) but no actions.\n` +
133
+ ` Notifications reference tile content (FAQ items, nav tips) defined in tile.props.actions.\n` +
134
+ ` Add actions to the tile, or remove the notifications.`
135
+ );
136
+ }
137
+ }
138
+
139
+ if (semanticErrors.length > 0) {
140
+ console.error(`\n\u274C ${semanticErrors.length} semantic error(s):`);
141
+ for (const e of semanticErrors) console.error(` - ${e}`);
142
+ process.exit(1);
143
+ }
144
+
122
145
  // --- Semantic check: anchorId.route must include at least one concrete route ---
123
146
  // Wildcards allowed by canvas-config.schema.json anchorId.route;
124
147
  // update here if the schema adds new glob patterns.
@@ -241,6 +264,25 @@ for (const { path, url } of pageUrlHits) {
241
264
  }
242
265
  }
243
266
 
267
+ // Hidden insertHtml without a triggerWhen is dead HTML — the SDK has no way to show it.
268
+ // The LLM sometimes generates `display:none` elements expecting a trigger type (e.g.,
269
+ // exit-intent) that doesn't exist in the SDK. Without triggerWhen, the element is
270
+ // injected hidden and stays hidden forever.
271
+ for (const [i, action] of (config.actions ?? []).entries()) {
272
+ if (action.kind !== 'content:insertHtml') continue;
273
+ if (action.triggerWhen) continue;
274
+ const html = action.html ?? '';
275
+ if (!/display\s*:\s*none/i.test(html)) continue;
276
+
277
+ const label = action.label ? ` (label: "${action.label}")` : '';
278
+ warnings.push(
279
+ `actions[${i}]${label}: content:insertHtml injects hidden HTML (display:none) with no triggerWhen.\n` +
280
+ ` This element will be inserted into the DOM but never shown — the SDK has no mechanism to reveal it.\n` +
281
+ ` Either add a triggerWhen with a valid condition (e.g., event_count, session_metric) to control visibility,\n` +
282
+ ` or remove display:none to show it immediately.`
283
+ );
284
+ }
285
+
244
286
  if (warnings.length > 0) {
245
287
  console.warn(`\n\u26A0\uFE0F ${warnings.length} design warning(s):`);
246
288
  for (const w of warnings) console.warn(` - ${w}`);