@syntrologie/runtime-sdk 0.2.20 → 1.0.1-canary.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CAPABILITIES.md +211 -0
- package/dist/SmartCanvasElement.js +11 -1
- package/dist/SmartCanvasElement.js.map +1 -1
- package/dist/api.js +26 -12
- package/dist/api.js.map +1 -1
- package/dist/bootstrap.d.ts +16 -2
- package/dist/bootstrap.js +84 -30
- package/dist/bootstrap.js.map +1 -1
- package/dist/configFetcher.js +2 -1
- package/dist/configFetcher.js.map +1 -1
- package/dist/context/ContextManager.d.ts +66 -0
- package/dist/context/ContextManager.js +268 -0
- package/dist/context/ContextManager.js.map +1 -0
- package/dist/context/index.d.ts +7 -0
- package/dist/context/index.js +7 -0
- package/dist/context/index.js.map +1 -0
- package/dist/context/schema.d.ts +360 -0
- package/dist/context/schema.js +50 -0
- package/dist/context/schema.js.map +1 -0
- package/dist/context/types.d.ts +101 -0
- package/dist/context/types.js +8 -0
- package/dist/context/types.js.map +1 -0
- package/dist/decisions/engine.d.ts +43 -0
- package/dist/decisions/engine.js +112 -0
- package/dist/decisions/engine.js.map +1 -0
- package/dist/decisions/index.d.ts +9 -0
- package/dist/decisions/index.js +10 -0
- package/dist/decisions/index.js.map +1 -0
- package/dist/decisions/schema.d.ts +2166 -0
- package/dist/decisions/schema.js +143 -0
- package/dist/decisions/schema.js.map +1 -0
- package/dist/decisions/strategies/rules.d.ts +24 -0
- package/dist/decisions/strategies/rules.js +152 -0
- package/dist/decisions/strategies/rules.js.map +1 -0
- package/dist/decisions/strategies/score.d.ts +10 -0
- package/dist/decisions/strategies/score.js +29 -0
- package/dist/decisions/strategies/score.js.map +1 -0
- package/dist/decisions/types.d.ts +242 -0
- package/dist/decisions/types.js +2 -0
- package/dist/decisions/types.js.map +1 -0
- package/dist/editorLoader.d.ts +10 -0
- package/dist/editorLoader.js +68 -29
- package/dist/editorLoader.js.map +1 -1
- package/dist/events/EventBus.d.ts +59 -0
- package/dist/events/EventBus.js +154 -0
- package/dist/events/EventBus.js.map +1 -0
- package/dist/events/index.d.ts +9 -0
- package/dist/events/index.js +10 -0
- package/dist/events/index.js.map +1 -0
- package/dist/events/normalizers/canvas.d.ts +67 -0
- package/dist/events/normalizers/canvas.js +116 -0
- package/dist/events/normalizers/canvas.js.map +1 -0
- package/dist/events/normalizers/posthog.d.ts +29 -0
- package/dist/events/normalizers/posthog.js +155 -0
- package/dist/events/normalizers/posthog.js.map +1 -0
- package/dist/events/schema.d.ts +70 -0
- package/dist/events/schema.js +30 -0
- package/dist/events/schema.js.map +1 -0
- package/dist/events/types.d.ts +73 -0
- package/dist/events/types.js +41 -0
- package/dist/events/types.js.map +1 -0
- package/dist/hooks/useShadowCanvasConfig.d.ts +5 -1
- package/dist/hooks/useShadowCanvasConfig.js +17 -3
- package/dist/hooks/useShadowCanvasConfig.js.map +1 -1
- package/dist/index.d.ts +6 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -1
- package/dist/logger.d.ts +29 -0
- package/dist/logger.js +81 -0
- package/dist/logger.js.map +1 -0
- package/dist/overlays/schema.d.ts +55 -55
- package/dist/runtime.d.ts +86 -0
- package/dist/runtime.js +132 -0
- package/dist/runtime.js.map +1 -0
- package/dist/smart-canvas.esm.js +11 -11
- package/dist/smart-canvas.esm.js.map +4 -4
- package/dist/smart-canvas.js +1801 -249
- package/dist/smart-canvas.js.map +4 -4
- package/dist/smart-canvas.min.js +12 -11
- package/dist/smart-canvas.min.js.map +4 -4
- package/dist/state/StateStore.d.ts +41 -0
- package/dist/state/StateStore.js +170 -0
- package/dist/state/StateStore.js.map +1 -0
- package/dist/state/helpers/cooldowns.d.ts +7 -0
- package/dist/state/helpers/cooldowns.js +31 -0
- package/dist/state/helpers/cooldowns.js.map +1 -0
- package/dist/state/helpers/dismissals.d.ts +7 -0
- package/dist/state/helpers/dismissals.js +34 -0
- package/dist/state/helpers/dismissals.js.map +1 -0
- package/dist/state/helpers/frequency.d.ts +8 -0
- package/dist/state/helpers/frequency.js +43 -0
- package/dist/state/helpers/frequency.js.map +1 -0
- package/dist/state/index.d.ts +7 -0
- package/dist/state/index.js +7 -0
- package/dist/state/index.js.map +1 -0
- package/dist/state/schema.d.ts +49 -0
- package/dist/state/schema.js +25 -0
- package/dist/state/schema.js.map +1 -0
- package/dist/state/types.d.ts +137 -0
- package/dist/state/types.js +9 -0
- package/dist/state/types.js.map +1 -0
- package/dist/telemetry/adapters/posthog.d.ts +1 -1
- package/dist/telemetry/adapters/posthog.js +1 -1
- package/dist/telemetry/adapters/posthog.js.map +1 -1
- package/dist/token.d.ts +2 -0
- package/dist/token.js.map +1 -1
- package/dist/types.d.ts +8 -0
- package/package.json +7 -4
- package/schema/canvas-config.schema.json +205 -0
- package/schema/runtime-context.schema.json +131 -0
package/CAPABILITIES.md
CHANGED
|
@@ -8,6 +8,7 @@ This document describes all available operations and capabilities of the SmartCa
|
|
|
8
8
|
- [Anchor Selectors](#anchor-selectors)
|
|
9
9
|
- [Operations](#operations)
|
|
10
10
|
- [Overlays](#overlays)
|
|
11
|
+
- [Runtime v2 Providers](#runtime-v2-providers)
|
|
11
12
|
- [Best Practices](#best-practices)
|
|
12
13
|
|
|
13
14
|
## Overview
|
|
@@ -319,6 +320,216 @@ Overlays are defined in `overlayRecipe`:
|
|
|
319
320
|
- `routes`: URL paths where this recipe applies (optional)
|
|
320
321
|
- `steps`: Array of tooltip and highlight steps
|
|
321
322
|
|
|
323
|
+
## Runtime v2 Providers
|
|
324
|
+
|
|
325
|
+
The v2 runtime provides adaptives with a unified interface for context, events, state, and decisions.
|
|
326
|
+
|
|
327
|
+
### SmartCanvasRuntime
|
|
328
|
+
|
|
329
|
+
Every adaptive receives a `runtime` object:
|
|
330
|
+
|
|
331
|
+
```typescript
|
|
332
|
+
type SmartCanvasRuntime = {
|
|
333
|
+
telemetry: TelemetryClient; // Emit events to PostHog
|
|
334
|
+
context: ContextManager; // Subscribe to page/session state
|
|
335
|
+
events: EventBus; // Subscribe to normalized events
|
|
336
|
+
state: StateStore; // Persist dismissals, cooldowns
|
|
337
|
+
version: string;
|
|
338
|
+
mode: "production" | "development";
|
|
339
|
+
};
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
### Usage
|
|
343
|
+
|
|
344
|
+
```typescript
|
|
345
|
+
const { canvas, runtime } = await Syntro.init({
|
|
346
|
+
token: "syn_..."
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
// Access runtime providers
|
|
350
|
+
runtime.telemetry?.trackAction(...);
|
|
351
|
+
runtime.context.subscribe((ctx, prev) => { ... });
|
|
352
|
+
runtime.events.subscribe({ names: ['ui.click'] }, (event) => { ... });
|
|
353
|
+
runtime.state.dismissals.mark('my-tile');
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
### Context Manager
|
|
357
|
+
|
|
358
|
+
Subscribe to runtime context changes:
|
|
359
|
+
|
|
360
|
+
```typescript
|
|
361
|
+
const unsubscribe = runtime.context.subscribe((ctx, prev) => {
|
|
362
|
+
if (ctx.page.url !== prev.page.url) {
|
|
363
|
+
// Handle route change
|
|
364
|
+
}
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
const ctx = runtime.context.get();
|
|
368
|
+
console.log(ctx.page.url, ctx.session.sessionId);
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
**Available Context:**
|
|
372
|
+
| Field | Type | Description |
|
|
373
|
+
|-------|------|-------------|
|
|
374
|
+
| `page.url` | string | Current page URL |
|
|
375
|
+
| `page.routeId` | string? | Matched route pattern |
|
|
376
|
+
| `page.title` | string? | Document title |
|
|
377
|
+
| `session.sessionId` | string | PostHog session ID |
|
|
378
|
+
| `session.startTs` | number | Session start timestamp |
|
|
379
|
+
| `viewport.width` | number | Viewport width in pixels |
|
|
380
|
+
| `viewport.height` | number | Viewport height in pixels |
|
|
381
|
+
| `anchors` | AnchorState[]? | Tracked anchor visibility |
|
|
382
|
+
|
|
383
|
+
### Event Bus
|
|
384
|
+
|
|
385
|
+
Subscribe to normalized events:
|
|
386
|
+
|
|
387
|
+
```typescript
|
|
388
|
+
const unsubscribe = runtime.events.subscribe(
|
|
389
|
+
{ names: ["ui.click", "nav.page_view"] },
|
|
390
|
+
(event) => {
|
|
391
|
+
console.log(event.name, event.props);
|
|
392
|
+
}
|
|
393
|
+
);
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
**Event Schema:**
|
|
397
|
+
```typescript
|
|
398
|
+
type NormalizedEvent = {
|
|
399
|
+
ts: number; // Timestamp
|
|
400
|
+
name: string; // e.g., "ui.click", "canvas.opened"
|
|
401
|
+
source: "posthog" | "canvas" | "derived";
|
|
402
|
+
props?: Record<string, any>;
|
|
403
|
+
schemaVersion: string;
|
|
404
|
+
};
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
**Standard Events:**
|
|
408
|
+
| Event | Source | Description |
|
|
409
|
+
|-------|--------|-------------|
|
|
410
|
+
| `ui.click` | posthog | User clicked element |
|
|
411
|
+
| `ui.scroll` | posthog | User scrolled |
|
|
412
|
+
| `nav.page_view` | posthog | Page navigation |
|
|
413
|
+
| `canvas.opened` | canvas | Smart Canvas opened |
|
|
414
|
+
| `canvas.closed` | canvas | Smart Canvas closed |
|
|
415
|
+
| `tile.viewed` | canvas | Tile became visible |
|
|
416
|
+
| `tile.action` | canvas | User clicked tile action |
|
|
417
|
+
|
|
418
|
+
### State Store
|
|
419
|
+
|
|
420
|
+
Persist state across sessions:
|
|
421
|
+
|
|
422
|
+
```typescript
|
|
423
|
+
// Session storage (cleared on close)
|
|
424
|
+
runtime.state.session.set("lastTileViewed", "tile-123");
|
|
425
|
+
const last = runtime.state.session.get<string>("lastTileViewed");
|
|
426
|
+
|
|
427
|
+
// User storage (persists across sessions)
|
|
428
|
+
runtime.state.user.set("onboardingComplete", true);
|
|
429
|
+
|
|
430
|
+
// Namespace by adaptive
|
|
431
|
+
const ns = runtime.state.ns("my-adaptive");
|
|
432
|
+
ns.session.set("step", 3);
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
**Built-in Helpers:**
|
|
436
|
+
```typescript
|
|
437
|
+
// Track dismissals
|
|
438
|
+
runtime.state.dismissals.mark("tooltip-1");
|
|
439
|
+
if (runtime.state.dismissals.isDismissed("tooltip-1")) { ... }
|
|
440
|
+
|
|
441
|
+
// Cooldowns (don't show again for X ms)
|
|
442
|
+
runtime.state.cooldowns.set("promo-banner", 86400000); // 24h
|
|
443
|
+
if (runtime.state.cooldowns.isActive("promo-banner")) { ... }
|
|
444
|
+
|
|
445
|
+
// Frequency caps
|
|
446
|
+
runtime.state.frequency.increment("upsell-shown");
|
|
447
|
+
if (runtime.state.frequency.count("upsell-shown") >= 3) { ... }
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
### Decision Strategies
|
|
451
|
+
|
|
452
|
+
Tile activation uses `DecisionStrategy` for conditional rendering:
|
|
453
|
+
|
|
454
|
+
```json
|
|
455
|
+
{
|
|
456
|
+
"id": "promo-tile",
|
|
457
|
+
"title": "Limited Offer",
|
|
458
|
+
"activation": {
|
|
459
|
+
"routes": { "include": ["/pricing", "/upgrade"] },
|
|
460
|
+
"strategy": {
|
|
461
|
+
"type": "rules",
|
|
462
|
+
"rules": [
|
|
463
|
+
{
|
|
464
|
+
"conditions": [
|
|
465
|
+
{ "type": "viewport", "minWidth": 768 },
|
|
466
|
+
{ "type": "dismissed", "key": "promo-tile", "inverted": true }
|
|
467
|
+
],
|
|
468
|
+
"value": true
|
|
469
|
+
}
|
|
470
|
+
],
|
|
471
|
+
"default": false
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
**Strategy Types:**
|
|
478
|
+
| Type | Description |
|
|
479
|
+
|------|-------------|
|
|
480
|
+
| `rules` | Condition-based matching (if/then) |
|
|
481
|
+
| `score` | Threshold on augmented field |
|
|
482
|
+
| `model` | ML model prediction (future) |
|
|
483
|
+
| `external` | Remote decision endpoint (future) |
|
|
484
|
+
|
|
485
|
+
**Condition Types:**
|
|
486
|
+
| Condition | Parameters | Description |
|
|
487
|
+
|-----------|------------|-------------|
|
|
488
|
+
| `page_url` | `url` (pattern) | URL matches pattern |
|
|
489
|
+
| `route` | `routeId` | Route ID matches |
|
|
490
|
+
| `anchor_visible` | `anchorId`, `state` | Anchor visibility state |
|
|
491
|
+
| `event_occurred` | `eventName`, `withinMs?` | Event happened recently |
|
|
492
|
+
| `state_equals` | `key`, `value` | State value matches |
|
|
493
|
+
| `viewport` | `minWidth?`, `maxWidth?` | Viewport size range |
|
|
494
|
+
| `session_metric` | `key`, `operator`, `threshold` | Session metric comparison |
|
|
495
|
+
| `dismissed` | `key`, `inverted?` | Item has been dismissed |
|
|
496
|
+
| `cooldown_active` | `key`, `inverted?` | Cooldown is active |
|
|
497
|
+
| `frequency_limit` | `key`, `limit`, `inverted?` | Frequency cap reached |
|
|
498
|
+
|
|
499
|
+
### Migration from v1
|
|
500
|
+
|
|
501
|
+
The new `activation` field replaces the deprecated `experiment` field:
|
|
502
|
+
|
|
503
|
+
**Before (v1):**
|
|
504
|
+
```json
|
|
505
|
+
{
|
|
506
|
+
"experiment": {
|
|
507
|
+
"featureKey": "my-feature",
|
|
508
|
+
"variationId": 1
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
**After (v2):**
|
|
514
|
+
```json
|
|
515
|
+
{
|
|
516
|
+
"activation": {
|
|
517
|
+
"strategy": {
|
|
518
|
+
"type": "rules",
|
|
519
|
+
"rules": [
|
|
520
|
+
{
|
|
521
|
+
"conditions": [
|
|
522
|
+
{ "type": "route", "routeId": "/dashboard" }
|
|
523
|
+
],
|
|
524
|
+
"value": true
|
|
525
|
+
}
|
|
526
|
+
],
|
|
527
|
+
"default": false
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
```
|
|
532
|
+
|
|
322
533
|
## Best Practices
|
|
323
534
|
|
|
324
535
|
### 1. Element Selection
|
|
@@ -36,7 +36,17 @@ const ensureOverlayRoot = () => {
|
|
|
36
36
|
root = document.createElement("div");
|
|
37
37
|
root.id = id;
|
|
38
38
|
root.setAttribute("data-smart-canvas-overlay", "true");
|
|
39
|
-
|
|
39
|
+
// Guard against body not existing yet (script in <head>)
|
|
40
|
+
if (document.body) {
|
|
41
|
+
document.body.appendChild(root);
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
45
|
+
if (!root.parentNode) {
|
|
46
|
+
document.body.appendChild(root);
|
|
47
|
+
}
|
|
48
|
+
}, { once: true });
|
|
49
|
+
}
|
|
40
50
|
}
|
|
41
51
|
return root;
|
|
42
52
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SmartCanvasElement.js","sourceRoot":"","sources":["../src/SmartCanvasElement.tsx"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,OAAO,EAAE,UAAU,EAAQ,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,cAAc,EAA4B,MAAM,kBAAkB,CAAC;AAC5E,OAAO,EAAE,2BAA2B,EAAyB,MAAM,cAAc,CAAC;AAGlF,MAAM,QAAQ,GAAG,cAAc,CAAC;AAChC,MAAM,QAAQ,GAAG;;;;;;;;;;;;;CAahB,CAAC;AAEF,MAAM,iBAAiB,GAAG,GAAG,EAAE;IAC7B,MAAM,EAAE,GAAG,sBAAsB,CAAC;IAClC,IAAI,IAAI,GAAG,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;IACvC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QACrC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,YAAY,CAAC,2BAA2B,EAAE,MAAM,CAAC,CAAC;QACvD,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"SmartCanvasElement.js","sourceRoot":"","sources":["../src/SmartCanvasElement.tsx"],"names":[],"mappings":"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"}
|
package/dist/api.js
CHANGED
|
@@ -2,9 +2,9 @@ import { registerSmartCanvasElement } from "./SmartCanvasElement";
|
|
|
2
2
|
import { createCanvasConfigFetcher } from "./configFetcher";
|
|
3
3
|
import { initAntiFlicker } from "./antiFlicker";
|
|
4
4
|
import { applyPatchesEarly, extractPatchesFromConfig, revertAllPatches } from "./earlyPatcher";
|
|
5
|
-
import { loadEditorSdk,
|
|
5
|
+
import { loadEditorSdk, getActiveSdkMode } from "./editorLoader";
|
|
6
6
|
export const createSmartCanvas = async (config = {}) => {
|
|
7
|
-
var _a, _b, _c
|
|
7
|
+
var _a, _b, _c;
|
|
8
8
|
if (typeof window === "undefined" || typeof document === "undefined") {
|
|
9
9
|
throw new Error("SmartCanvas can only be created in a browser-like environment");
|
|
10
10
|
}
|
|
@@ -45,8 +45,10 @@ export const createSmartCanvas = async (config = {}) => {
|
|
|
45
45
|
if (removeAntiFlicker) {
|
|
46
46
|
removeAntiFlicker();
|
|
47
47
|
}
|
|
48
|
-
// Check if we should load the editor
|
|
49
|
-
|
|
48
|
+
// Check if we should load the editor (for editor mode or audit mode)
|
|
49
|
+
const sdkMode = getActiveSdkMode();
|
|
50
|
+
if (sdkMode) {
|
|
51
|
+
console.log(`[SmartCanvas] Loading editor SDK for ${sdkMode} mode`);
|
|
50
52
|
// We don't await this so the runtime SDK can continue initializing
|
|
51
53
|
loadEditorSdk(config.editorUrl).catch(console.error);
|
|
52
54
|
}
|
|
@@ -57,11 +59,24 @@ export const createSmartCanvas = async (config = {}) => {
|
|
|
57
59
|
host.style.setProperty(key, value);
|
|
58
60
|
}
|
|
59
61
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
// Wait for body to exist if running in <head>
|
|
63
|
+
const appendToTarget = () => {
|
|
64
|
+
var _a;
|
|
65
|
+
const target = (_a = config.target) !== null && _a !== void 0 ? _a : document.body;
|
|
66
|
+
if (target) {
|
|
67
|
+
target.appendChild(host);
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
if (document.body) {
|
|
71
|
+
appendToTarget();
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
// Script running before body exists - wait for DOMContentLoaded
|
|
75
|
+
document.addEventListener('DOMContentLoaded', appendToTarget, { once: true });
|
|
76
|
+
}
|
|
77
|
+
const experiments = (_a = config.integrations) === null || _a === void 0 ? void 0 : _a.experiments;
|
|
78
|
+
const telemetry = (_b = config.integrations) === null || _b === void 0 ? void 0 : _b.telemetry;
|
|
79
|
+
const fetcher = (_c = config.fetcher) !== null && _c !== void 0 ? _c : createCanvasConfigFetcher({
|
|
65
80
|
configUri: config.configUri,
|
|
66
81
|
experiments,
|
|
67
82
|
featureKey: config.configUriFeatureKey,
|
|
@@ -153,13 +168,12 @@ export const createSmartCanvas = async (config = {}) => {
|
|
|
153
168
|
},
|
|
154
169
|
};
|
|
155
170
|
// Expose handle for editor SDK access
|
|
156
|
-
// In editor mode: always expose (editor needs it to inject tiles and save config)
|
|
171
|
+
// In editor/audit mode: always expose (editor needs it to inject tiles and save config)
|
|
157
172
|
// In dev mode: always expose (for debugging)
|
|
158
173
|
// In production: never expose (security)
|
|
159
174
|
if (typeof window !== "undefined") {
|
|
160
|
-
const isEditorMode = new URLSearchParams(window.location.search).has('editor_token');
|
|
161
175
|
const isDev = process.env.NODE_ENV === 'development';
|
|
162
|
-
if (
|
|
176
|
+
if (sdkMode || isDev) {
|
|
163
177
|
window.__smartCanvasHandle = handle;
|
|
164
178
|
}
|
|
165
179
|
}
|
package/dist/api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAsB,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAKtF,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAE5D,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAC/F,OAAO,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAsB,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAKtF,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAE5D,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAC/F,OAAO,EAAE,aAAa,EAAiC,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAiFhG,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,EACpC,SAA4B,EAAE,EACF,EAAE;;IAC9B,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE,CAAC;QACrE,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;IACnF,CAAC;IAED,qCAAqC;IACrC,IAAI,iBAAiB,GAAwB,IAAI,CAAC;IAClD,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;QACvB,MAAM,iBAAiB,GAAG,OAAO,MAAM,CAAC,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3F,iBAAiB,GAAG,eAAe,CAAC,iBAAiB,CAAC,CAAC;IACzD,CAAC;IAED,uDAAuD;IACvD,IAAI,aAAa,GAAQ,IAAI,CAAC;IAC9B,IAAI,cAAc,GAA+B,IAAI,CAAC;IAEtD,uDAAuD;IACvD,IAAI,MAAM,CAAC,aAAa,KAAK,KAAK,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACrD,IAAI,CAAC;YACH,cAAc,GAAG,MAAM,CAAC,OAAO,CAAC;YAChC,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;YAC5C,aAAa,GAAG,YAAY,CAAC,CAAC,kBAAkB;YAChD,MAAM,OAAO,GAAG,wBAAwB,CAAC,YAAY,CAAC,CAAC;YACvD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACvB,iBAAiB,CAAC;oBAChB,OAAO;oBACP,UAAU,EAAE,GAAG,EAAE;wBACf,gDAAgD;wBAChD,IAAI,iBAAiB,EAAE,CAAC;4BACtB,iBAAiB,EAAE,CAAC;4BACpB,iBAAiB,GAAG,IAAI,CAAC;wBAC3B,CAAC;oBACH,CAAC;iBACF,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,6CAA6C,EAAE,KAAK,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;IAED,6CAA6C;IAC7C,IAAI,iBAAiB,EAAE,CAAC;QACtB,iBAAiB,EAAE,CAAC;IACtB,CAAC;IAED,qEAAqE;IACrE,MAAM,OAAO,GAAG,gBAAgB,EAAE,CAAC;IACnC,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,CAAC,GAAG,CAAC,wCAAwC,OAAO,OAAO,CAAC,CAAC;QACpE,mEAAmE;QACnE,aAAa,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACvD,CAAC;IAED,0BAA0B,EAAE,CAAC;IAE7B,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,cAAc,CAAuB,CAAC;IAC1E,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;YACzD,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IAED,8CAA8C;IAC9C,MAAM,cAAc,GAAG,GAAG,EAAE;;QAC1B,MAAM,MAAM,GAAG,MAAA,MAAM,CAAC,MAAM,mCAAI,QAAQ,CAAC,IAAI,CAAC;QAC9C,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC,CAAC;IAEF,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC;QAClB,cAAc,EAAE,CAAC;IACnB,CAAC;SAAM,CAAC;QACN,gEAAgE;QAChE,QAAQ,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,cAAc,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAChF,CAAC;IAED,MAAM,WAAW,GAAG,MAAA,MAAM,CAAC,YAAY,0CAAE,WAAW,CAAC;IACrD,MAAM,SAAS,GAAG,MAAA,MAAM,CAAC,YAAY,0CAAE,SAAS,CAAC;IAEjD,MAAM,OAAO,GACX,MAAA,MAAM,CAAC,OAAO,mCACd,yBAAyB,CAAC;QACxB,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,WAAW;QACX,UAAU,EAAE,MAAM,CAAC,mBAAmB;QACtC,WAAW,EAAE,MAAM,CAAC,gBAAgB;KACrC,CAAC,CAAC;IAEL,+CAA+C;IAC/C,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,cAAc,GAAG,OAAO,CAAC;IAC3B,CAAC;IAED,MAAM,QAAQ,GAA4C;QACxD,OAAO;QACP,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,WAAW;QACX,SAAS;QACT,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;QACzC,uBAAuB,EAAE,MAAM,CAAC,uBAAuB;QACvD,uBAAuB,EAAE,MAAM,CAAC,uBAAuB;QACvD,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,mBAAmB,EAAE,MAAM,CAAC,mBAAmB;QAC/C,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;QACzC,KAAK,EAAE,MAAM,CAAC,KAAK;KACpB,CAAC;IAEF,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IAC7B,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;QACvB,IAAI,CAAC,IAAI,EAAE,CAAC;IACd,CAAC;IAED,MAAM,MAAM,GAAsB;QAChC,EAAE,EAAE,IAAI;QACR,IAAI,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE;QACvB,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE;QACzB,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE;QAC5B,SAAS,EAAE,CAAC,MAAM,EAAE,EAAE;YACpB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gBAClD,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACrC,CAAC;QACH,CAAC;QACD,SAAS,EAAE,KAAK,IAAI,EAAE;YAClB,0CAA0C;YAC1C,IAAI,cAAc,EAAE,CAAC;gBACjB,IAAI,CAAC;oBACD,MAAM,WAAW,GAAG,MAAM,cAAc,EAAE,CAAC;oBAC3C,aAAa,GAAG,WAAW,CAAC;oBAC5B,OAAO,WAAW,CAAC;gBACvB,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACb,OAAO,CAAC,KAAK,CAAC,sCAAsC,EAAE,KAAK,CAAC,CAAC;gBACjE,CAAC;YACL,CAAC;YACD,OAAO,aAAa,CAAC;QACzB,CAAC;QACD,YAAY,EAAE,CAAC,SAAS,EAAE,EAAE;YACxB,aAAa,GAAG,SAAS,CAAC;YAC1B,mBAAmB;YACnB,MAAM,OAAO,GAAG,wBAAwB,CAAC,SAAS,CAAC,CAAC;YACpD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACrB,iBAAiB,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;YACnC,CAAC;QACL,CAAC;QACD,UAAU,EAAE,CAAC,OAAO,EAAE,EAAE;YACpB,IAAI,OAAO,EAAE,CAAC;gBACV,IAAI,aAAa,EAAE,CAAC;oBAChB,MAAM,OAAO,GAAG,wBAAwB,CAAC,aAAa,CAAC,CAAC;oBACxD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBACrB,iBAAiB,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;oBACnC,CAAC;gBACL,CAAC;YACL,CAAC;iBAAM,CAAC;gBACJ,gBAAgB,EAAE,CAAC;YACvB,CAAC;QACL,CAAC;QACD,iBAAiB,EAAE,CAAC,GAAG,EAAE,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE,SAAS,CAAC;QAC7E,kBAAkB,EAAE,CAAC,UAAU,EAAE,EAAE;YAC/B,cAAc,GAAG,UAAU,CAAC;YAC5B,IAAI,CAAC,kBAAkB,CAAC,UAAU,CAAC,CAAC;QACxC,CAAC;QACD,2BAA2B,EAAE,CAAC,UAAU,EAAE,EAAE;;YACxC,MAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,QAAQ,0DAAG,UAAU,CAAC,CAAC;QACtC,CAAC;QACD,YAAY,EAAE,GAAG,EAAE;;YACf,OAAO,MAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,YAAY,yDAAI,CAAC;QACvC,CAAC;QACD,qBAAqB,EAAE,GAAG,EAAE;;YACxB,MAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,qBAAqB,yDAAI,CAAC;QACzC,CAAC;KACF,CAAC;IAEF,sCAAsC;IACtC,wFAAwF;IACxF,6CAA6C;IAC7C,yCAAyC;IACzC,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;QAClC,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa,CAAC;QACrD,IAAI,OAAO,IAAI,KAAK,EAAE,CAAC;YACpB,MAAc,CAAC,mBAAmB,GAAG,MAAM,CAAC;QAC/C,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAUF,+CAA+C;AAC/C,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAEtD,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;IAClC,MAAM,CAAC,WAAW,GAAG;QACnB,KAAK,CAAC,MAAM,CAAC,MAA0B;YACrC,OAAO,iBAAiB,CAAC,MAAM,CAAC,CAAC;QACnC,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/dist/bootstrap.d.ts
CHANGED
|
@@ -5,14 +5,21 @@
|
|
|
5
5
|
* ```typescript
|
|
6
6
|
* import { Syntro } from '@syntrologie/runtime-sdk';
|
|
7
7
|
*
|
|
8
|
-
* const { canvas,
|
|
8
|
+
* const { canvas, runtime } = await Syntro.init({
|
|
9
9
|
* token: "syn_eyJ2IjoxLCJleHAiOnsiayI6InNkay14eHgiLCJwIjoiZ3Jvd3RoYm9vayJ9fQ"
|
|
10
10
|
* });
|
|
11
|
+
*
|
|
12
|
+
* // Access runtime providers
|
|
13
|
+
* runtime.telemetry?.trackAction(...);
|
|
14
|
+
* runtime.context.subscribe((ctx, prev) => { ... });
|
|
15
|
+
* runtime.events.subscribe({ names: ['ui.click'] }, (event) => { ... });
|
|
16
|
+
* runtime.state.dismissals.mark('my-tile');
|
|
11
17
|
* ```
|
|
12
18
|
*/
|
|
13
19
|
import { decodeToken, encodeToken } from "./token";
|
|
14
20
|
import { SmartCanvasConfig, SmartCanvasHandle } from "./api";
|
|
15
21
|
import { SessionMetricTracker } from "./metrics";
|
|
22
|
+
import { SmartCanvasRuntime } from "./runtime";
|
|
16
23
|
import type { ExperimentClient } from "./experiments/types";
|
|
17
24
|
import type { TelemetryClient } from "./telemetry/types";
|
|
18
25
|
import type { CanvasConfigFetcher } from "./types";
|
|
@@ -50,17 +57,24 @@ export interface SyntroInitResult {
|
|
|
50
57
|
* The SmartCanvas handle for controlling the canvas.
|
|
51
58
|
*/
|
|
52
59
|
canvas: SmartCanvasHandle;
|
|
60
|
+
/**
|
|
61
|
+
* The unified v2 runtime with all providers.
|
|
62
|
+
* Use this to access telemetry, context, events, and state.
|
|
63
|
+
*/
|
|
64
|
+
runtime: SmartCanvasRuntime;
|
|
53
65
|
/**
|
|
54
66
|
* The experiment client, if experiments are configured in the token.
|
|
67
|
+
* @deprecated Access via runtime.telemetry or use DecisionStrategy instead
|
|
55
68
|
*/
|
|
56
69
|
experiments?: ExperimentClient;
|
|
57
70
|
/**
|
|
58
71
|
* The telemetry client, if telemetry is configured in the token.
|
|
72
|
+
* @deprecated Access via runtime.telemetry instead
|
|
59
73
|
*/
|
|
60
74
|
telemetry?: TelemetryClient;
|
|
61
75
|
/**
|
|
62
76
|
* The session metric tracker, if enableSessionMetrics is true.
|
|
63
|
-
*
|
|
77
|
+
* @deprecated Access via runtime.sessionMetrics instead
|
|
64
78
|
*/
|
|
65
79
|
sessionMetrics?: SessionMetricTracker;
|
|
66
80
|
}
|
package/dist/bootstrap.js
CHANGED
|
@@ -5,9 +5,15 @@
|
|
|
5
5
|
* ```typescript
|
|
6
6
|
* import { Syntro } from '@syntrologie/runtime-sdk';
|
|
7
7
|
*
|
|
8
|
-
* const { canvas,
|
|
8
|
+
* const { canvas, runtime } = await Syntro.init({
|
|
9
9
|
* token: "syn_eyJ2IjoxLCJleHAiOnsiayI6InNkay14eHgiLCJwIjoiZ3Jvd3RoYm9vayJ9fQ"
|
|
10
10
|
* });
|
|
11
|
+
*
|
|
12
|
+
* // Access runtime providers
|
|
13
|
+
* runtime.telemetry?.trackAction(...);
|
|
14
|
+
* runtime.context.subscribe((ctx, prev) => { ... });
|
|
15
|
+
* runtime.events.subscribe({ names: ['ui.click'] }, (event) => { ... });
|
|
16
|
+
* runtime.state.dismissals.mark('my-tile');
|
|
11
17
|
* ```
|
|
12
18
|
*/
|
|
13
19
|
import { decodeToken, encodeToken } from "./token";
|
|
@@ -17,6 +23,8 @@ import { createConfigFetcher } from "./fetchers/registry";
|
|
|
17
23
|
import { createCanvasConfigFetcher } from "./configFetcher";
|
|
18
24
|
import { createSmartCanvas } from "./api";
|
|
19
25
|
import { createSessionMetricTracker } from "./metrics";
|
|
26
|
+
import { createSmartCanvasRuntime } from "./runtime";
|
|
27
|
+
import { initLogger, debug, warn, error as logError } from "./logger";
|
|
20
28
|
/**
|
|
21
29
|
* Get environment variable, supporting both Vite and Next.js patterns.
|
|
22
30
|
*/
|
|
@@ -42,12 +50,12 @@ function getEnvVar(name) {
|
|
|
42
50
|
*/
|
|
43
51
|
function isEditorMode() {
|
|
44
52
|
if (typeof window === "undefined") {
|
|
45
|
-
|
|
53
|
+
debug('Syntro Bootstrap', 'isEditorMode: not in browser');
|
|
46
54
|
return false;
|
|
47
55
|
}
|
|
48
56
|
const params = new URLSearchParams(window.location.search);
|
|
49
57
|
const hasToken = params.has("editor_token");
|
|
50
|
-
|
|
58
|
+
debug('Syntro Bootstrap', 'isEditorMode check:', {
|
|
51
59
|
url: window.location.href,
|
|
52
60
|
search: window.location.search,
|
|
53
61
|
hasEditorToken: hasToken,
|
|
@@ -55,6 +63,25 @@ function isEditorMode() {
|
|
|
55
63
|
});
|
|
56
64
|
return hasToken;
|
|
57
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* Check if we're in audit mode (syntro_audit in URL params).
|
|
68
|
+
* Audit mode enables element marking for product touring.
|
|
69
|
+
*/
|
|
70
|
+
function isAuditMode() {
|
|
71
|
+
var _a;
|
|
72
|
+
if (typeof window === "undefined") {
|
|
73
|
+
debug('Syntro Bootstrap', 'isAuditMode: not in browser');
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
const params = new URLSearchParams(window.location.search);
|
|
77
|
+
const hasAuditFlag = params.has("syntro_audit");
|
|
78
|
+
debug('Syntro Bootstrap', 'isAuditMode check:', {
|
|
79
|
+
url: window.location.href,
|
|
80
|
+
hasAuditFlag,
|
|
81
|
+
auditSessionId: (_a = params.get("audit_session_id")) !== null && _a !== void 0 ? _a : 'none',
|
|
82
|
+
});
|
|
83
|
+
return hasAuditFlag;
|
|
84
|
+
}
|
|
58
85
|
// ============================================================================
|
|
59
86
|
// Segment Attribute Caching (localStorage)
|
|
60
87
|
// ============================================================================
|
|
@@ -70,12 +97,12 @@ function loadCachedSegmentAttributes() {
|
|
|
70
97
|
const cached = localStorage.getItem(SEGMENT_CACHE_KEY);
|
|
71
98
|
if (cached) {
|
|
72
99
|
const attrs = JSON.parse(cached);
|
|
73
|
-
|
|
100
|
+
debug('Syntro Bootstrap', 'Loaded cached segment attributes:', attrs);
|
|
74
101
|
return attrs;
|
|
75
102
|
}
|
|
76
103
|
}
|
|
77
104
|
catch (err) {
|
|
78
|
-
|
|
105
|
+
warn('Syntro Bootstrap', 'Failed to load cached segment attributes:', err);
|
|
79
106
|
}
|
|
80
107
|
return {};
|
|
81
108
|
}
|
|
@@ -87,10 +114,10 @@ function cacheSegmentAttributes(attrs) {
|
|
|
87
114
|
return;
|
|
88
115
|
try {
|
|
89
116
|
localStorage.setItem(SEGMENT_CACHE_KEY, JSON.stringify(attrs));
|
|
90
|
-
|
|
117
|
+
debug('Syntro Bootstrap', 'Cached segment attributes:', attrs);
|
|
91
118
|
}
|
|
92
119
|
catch (err) {
|
|
93
|
-
|
|
120
|
+
warn('Syntro Bootstrap', 'Failed to cache segment attributes:', err);
|
|
94
121
|
}
|
|
95
122
|
}
|
|
96
123
|
/**
|
|
@@ -122,40 +149,46 @@ function extractSegmentFlags(allFlags) {
|
|
|
122
149
|
*/
|
|
123
150
|
async function init(options) {
|
|
124
151
|
var _a, _b, _c;
|
|
125
|
-
|
|
126
|
-
|
|
152
|
+
// Initialize logger early (URL param works without token)
|
|
153
|
+
initLogger();
|
|
154
|
+
debug('Syntro Bootstrap', '====== INIT ======');
|
|
155
|
+
debug('Syntro Bootstrap', 'Options:', {
|
|
127
156
|
hasToken: !!options.token,
|
|
128
157
|
tokenPrefix: ((_a = options.token) === null || _a === void 0 ? void 0 : _a.slice(0, 15)) + '...',
|
|
129
158
|
hasCanvasOptions: !!options.canvas,
|
|
130
159
|
});
|
|
131
|
-
// In editor mode, token is optional -
|
|
160
|
+
// In editor or audit mode, token is optional - SDK handles auth differently
|
|
132
161
|
const editorMode = isEditorMode();
|
|
133
|
-
|
|
162
|
+
const auditMode = isAuditMode();
|
|
163
|
+
const sdkMode = editorMode ? 'editor' : auditMode ? 'audit' : null;
|
|
164
|
+
debug('Syntro Bootstrap', 'SDK mode:', sdkMode !== null && sdkMode !== void 0 ? sdkMode : 'normal');
|
|
134
165
|
let payload;
|
|
135
166
|
if (options.token) {
|
|
136
167
|
// If token is provided and starts with syn_, decode it
|
|
137
168
|
if (options.token.startsWith("syn_")) {
|
|
138
|
-
|
|
169
|
+
debug('Syntro Bootstrap', 'Token starts with syn_, decoding...');
|
|
139
170
|
payload = decodeToken(options.token);
|
|
171
|
+
// Re-init logger with token's debug flag
|
|
172
|
+
initLogger(payload.d);
|
|
140
173
|
}
|
|
141
|
-
else if (!
|
|
142
|
-
// Not a syn_ token and not in
|
|
143
|
-
|
|
144
|
-
|
|
174
|
+
else if (!sdkMode) {
|
|
175
|
+
// Not a syn_ token and not in special mode - error
|
|
176
|
+
logError('Syntro Bootstrap', '❌ Token does not start with syn_ and NOT in editor/audit mode!');
|
|
177
|
+
logError('Syntro Bootstrap', 'Token received:', options.token);
|
|
145
178
|
throw new Error("Invalid Syntro token: must start with 'syn_'");
|
|
146
179
|
}
|
|
147
180
|
else {
|
|
148
|
-
|
|
181
|
+
debug('Syntro Bootstrap', `✓ Non-syn_ token allowed (${sdkMode} mode)`);
|
|
149
182
|
}
|
|
150
|
-
// If in editor mode with non-syn_ token, skip token decoding
|
|
183
|
+
// If in editor/audit mode with non-syn_ token, skip token decoding
|
|
151
184
|
}
|
|
152
|
-
else if (!
|
|
153
|
-
// No token and not in
|
|
154
|
-
|
|
155
|
-
throw new Error("Syntro token is required (unless in editor mode)");
|
|
185
|
+
else if (!sdkMode) {
|
|
186
|
+
// No token and not in special mode - error
|
|
187
|
+
logError('Syntro Bootstrap', '❌ No token provided and NOT in editor/audit mode!');
|
|
188
|
+
throw new Error("Syntro token is required (unless in editor or audit mode)");
|
|
156
189
|
}
|
|
157
190
|
else {
|
|
158
|
-
|
|
191
|
+
debug('Syntro Bootstrap', `✓ No token, but ${sdkMode} mode - proceeding`);
|
|
159
192
|
}
|
|
160
193
|
// Host resolution priority: env var > token > default
|
|
161
194
|
// Env vars are checked at build time by bundlers (Next.js/Vite)
|
|
@@ -173,16 +206,16 @@ async function init(options) {
|
|
|
173
206
|
// PHASE 1: Load cached segment attributes for instant evaluation
|
|
174
207
|
// ============================================================================
|
|
175
208
|
const cachedSegmentAttrs = loadCachedSegmentAttributes();
|
|
176
|
-
|
|
209
|
+
debug('Syntro Bootstrap', 'Phase 1: Using cached segment attributes:', cachedSegmentAttrs);
|
|
177
210
|
// Will be set when experiments client is created
|
|
178
211
|
let experiments;
|
|
179
212
|
// Callback for when PostHog feature flags are loaded (Phase 2)
|
|
180
213
|
const onFeatureFlagsLoaded = (allFlags) => {
|
|
181
214
|
var _a, _b, _c;
|
|
182
|
-
|
|
215
|
+
debug('Syntro Bootstrap', 'Phase 2: PostHog feature flags loaded');
|
|
183
216
|
// Extract segment flags (in_segment_*)
|
|
184
217
|
const segmentFlags = extractSegmentFlags(allFlags);
|
|
185
|
-
|
|
218
|
+
debug('Syntro Bootstrap', 'Segment flags from PostHog:', segmentFlags);
|
|
186
219
|
// Cache for next page load
|
|
187
220
|
cacheSegmentAttributes(segmentFlags);
|
|
188
221
|
// Update GrowthBook with fresh segment attributes
|
|
@@ -191,7 +224,7 @@ async function init(options) {
|
|
|
191
224
|
const sessionAttrs = (_b = (_a = sessionMetrics === null || sessionMetrics === void 0 ? void 0 : sessionMetrics.getAll) === null || _a === void 0 ? void 0 : _a.call(sessionMetrics)) !== null && _b !== void 0 ? _b : {};
|
|
192
225
|
// Merge session metrics + segment flags and update GrowthBook
|
|
193
226
|
const updatedAttrs = { ...sessionAttrs, ...segmentFlags };
|
|
194
|
-
|
|
227
|
+
debug('Syntro Bootstrap', 'Updating GrowthBook with attributes:', updatedAttrs);
|
|
195
228
|
(_c = experiments.setAttributes) === null || _c === void 0 ? void 0 : _c.call(experiments, updatedAttrs);
|
|
196
229
|
}
|
|
197
230
|
};
|
|
@@ -254,10 +287,10 @@ async function init(options) {
|
|
|
254
287
|
sessionMetrics = createSessionMetricTracker({
|
|
255
288
|
experiments,
|
|
256
289
|
onMetricChange: (key, value) => {
|
|
257
|
-
|
|
290
|
+
debug('Syntro Bootstrap', `Session metric changed: ${key} = ${value}`);
|
|
258
291
|
},
|
|
259
292
|
});
|
|
260
|
-
|
|
293
|
+
debug('Syntro Bootstrap', 'SessionMetricTracker created');
|
|
261
294
|
}
|
|
262
295
|
// Create canvas with integrations
|
|
263
296
|
const canvas = await createSmartCanvas({
|
|
@@ -266,7 +299,28 @@ async function init(options) {
|
|
|
266
299
|
integrations: { experiments, telemetry },
|
|
267
300
|
editorUrl,
|
|
268
301
|
});
|
|
269
|
-
|
|
302
|
+
// Determine runtime mode
|
|
303
|
+
let runtimeMode = 'production';
|
|
304
|
+
if (editorMode)
|
|
305
|
+
runtimeMode = 'editor';
|
|
306
|
+
else if (auditMode)
|
|
307
|
+
runtimeMode = 'audit';
|
|
308
|
+
else if (getEnvVar('NODE_ENV') === 'development')
|
|
309
|
+
runtimeMode = 'development';
|
|
310
|
+
// Create the unified v2 runtime
|
|
311
|
+
const runtime = createSmartCanvasRuntime({
|
|
312
|
+
telemetry,
|
|
313
|
+
sessionMetrics,
|
|
314
|
+
mode: runtimeMode,
|
|
315
|
+
});
|
|
316
|
+
debug('Syntro Bootstrap', 'Runtime created:', {
|
|
317
|
+
version: runtime.version,
|
|
318
|
+
mode: runtime.mode,
|
|
319
|
+
hasContext: !!runtime.context,
|
|
320
|
+
hasEvents: !!runtime.events,
|
|
321
|
+
hasState: !!runtime.state,
|
|
322
|
+
});
|
|
323
|
+
return { canvas, runtime, experiments, telemetry, sessionMetrics };
|
|
270
324
|
}
|
|
271
325
|
/**
|
|
272
326
|
* The Syntro namespace for single-token initialization.
|