@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/dist/editorLoader.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { debug, warn } from "./logger";
|
|
1
2
|
export const DEFAULT_EDITOR_URL = "https://cdn.syntrologie.com/editor-sdk/latest/editor-sdk.js";
|
|
2
3
|
/**
|
|
3
4
|
* Allowed hosts for loading the editor SDK.
|
|
@@ -17,18 +18,18 @@ const ALLOWED_EDITOR_HOSTS = [
|
|
|
17
18
|
* Requires HTTPS for non-localhost URLs.
|
|
18
19
|
*/
|
|
19
20
|
function validateEditorUrl(url) {
|
|
20
|
-
|
|
21
|
+
debug('Syntro Runtime', 'Validating editor URL:', url);
|
|
21
22
|
try {
|
|
22
23
|
const parsed = new URL(url);
|
|
23
24
|
const isLocalhost = /^(localhost|127\.0\.0\.1)$/.test(parsed.hostname);
|
|
24
|
-
|
|
25
|
+
debug('Syntro Runtime', 'Parsed URL:', {
|
|
25
26
|
hostname: parsed.hostname,
|
|
26
27
|
protocol: parsed.protocol,
|
|
27
28
|
isLocalhost,
|
|
28
29
|
});
|
|
29
30
|
// Require HTTPS for non-localhost
|
|
30
31
|
if (parsed.protocol !== 'https:' && !isLocalhost) {
|
|
31
|
-
|
|
32
|
+
warn('Syntro Runtime', '❌ Editor URL must use HTTPS:', url);
|
|
32
33
|
return false;
|
|
33
34
|
}
|
|
34
35
|
// Check against allowlist - handle both exact match and suffix match
|
|
@@ -39,20 +40,20 @@ function validateEditorUrl(url) {
|
|
|
39
40
|
}
|
|
40
41
|
return parsed.hostname === host;
|
|
41
42
|
});
|
|
42
|
-
|
|
43
|
+
debug('Syntro Runtime', 'Host allowlist check:', {
|
|
43
44
|
hostname: parsed.hostname,
|
|
44
45
|
allowedHosts: ALLOWED_EDITOR_HOSTS,
|
|
45
46
|
isAllowed,
|
|
46
47
|
});
|
|
47
48
|
if (!isAllowed) {
|
|
48
|
-
|
|
49
|
+
warn('Syntro Runtime', '❌ Editor URL host not in allowlist:', parsed.hostname);
|
|
49
50
|
return false;
|
|
50
51
|
}
|
|
51
|
-
|
|
52
|
+
debug('Syntro Runtime', '✓ Editor URL validated');
|
|
52
53
|
return true;
|
|
53
54
|
}
|
|
54
55
|
catch (e) {
|
|
55
|
-
|
|
56
|
+
warn('Syntro Runtime', '❌ Invalid editor URL: ' + url, e);
|
|
56
57
|
return false;
|
|
57
58
|
}
|
|
58
59
|
}
|
|
@@ -62,18 +63,18 @@ function validateEditorUrl(url) {
|
|
|
62
63
|
*/
|
|
63
64
|
export const shouldLoadEditor = () => {
|
|
64
65
|
var _a;
|
|
65
|
-
|
|
66
|
+
debug('Syntro Runtime', '====== EDITOR LOAD CHECK ======');
|
|
66
67
|
if (typeof window === "undefined") {
|
|
67
|
-
|
|
68
|
+
debug('Syntro Runtime', 'Not in browser - skipping editor');
|
|
68
69
|
return false;
|
|
69
70
|
}
|
|
70
71
|
const params = new URLSearchParams(window.location.search);
|
|
71
|
-
|
|
72
|
-
|
|
72
|
+
debug('Syntro Runtime', 'URL:', window.location.href);
|
|
73
|
+
debug('Syntro Runtime', 'Search params:', window.location.search);
|
|
73
74
|
// Require editor_token for security - prevents arbitrary editor activation
|
|
74
75
|
const hasEditorFlag = params.has("syntro_editor") || params.has("syntro-editor");
|
|
75
76
|
const hasEditorToken = params.has("editor_token");
|
|
76
|
-
|
|
77
|
+
debug('Syntro Runtime', 'Editor flags:', {
|
|
77
78
|
hasEditorFlag,
|
|
78
79
|
hasEditorToken,
|
|
79
80
|
syntro_editor: params.get("syntro_editor"),
|
|
@@ -81,28 +82,66 @@ export const shouldLoadEditor = () => {
|
|
|
81
82
|
editor_token: hasEditorToken ? `${(_a = params.get("editor_token")) === null || _a === void 0 ? void 0 : _a.slice(0, 10)}...` : 'none',
|
|
82
83
|
});
|
|
83
84
|
if (hasEditorFlag && !hasEditorToken) {
|
|
84
|
-
|
|
85
|
-
|
|
85
|
+
warn('Syntro Runtime', '❌ Editor activation requires editor_token parameter');
|
|
86
|
+
debug('Syntro Runtime', '================================');
|
|
86
87
|
return false;
|
|
87
88
|
}
|
|
88
89
|
const shouldLoad = hasEditorFlag && hasEditorToken;
|
|
89
|
-
|
|
90
|
-
|
|
90
|
+
debug('Syntro Runtime', 'Should load editor:', shouldLoad);
|
|
91
|
+
debug('Syntro Runtime', '================================');
|
|
91
92
|
return shouldLoad;
|
|
92
93
|
};
|
|
94
|
+
/**
|
|
95
|
+
* Checks if audit mode should be activated based on URL query parameters.
|
|
96
|
+
* Audit mode enables element marking for product touring.
|
|
97
|
+
*/
|
|
98
|
+
export const isAuditMode = () => {
|
|
99
|
+
debug('Syntro Runtime', '====== AUDIT MODE CHECK ======');
|
|
100
|
+
if (typeof window === "undefined") {
|
|
101
|
+
debug('Syntro Runtime', 'Not in browser - skipping audit');
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
const params = new URLSearchParams(window.location.search);
|
|
105
|
+
const hasAuditFlag = params.has("syntro_audit");
|
|
106
|
+
const auditSessionId = params.get("audit_session_id");
|
|
107
|
+
debug('Syntro Runtime', 'Audit flags:', {
|
|
108
|
+
hasAuditFlag,
|
|
109
|
+
auditSessionId: auditSessionId ? `${auditSessionId.slice(0, 8)}...` : 'none',
|
|
110
|
+
});
|
|
111
|
+
// Require syntro_audit flag to activate audit mode
|
|
112
|
+
if (!hasAuditFlag) {
|
|
113
|
+
debug('Syntro Runtime', 'No syntro_audit param - not in audit mode');
|
|
114
|
+
debug('Syntro Runtime', '================================');
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
debug('Syntro Runtime', '✓ Audit mode active');
|
|
118
|
+
debug('Syntro Runtime', '================================');
|
|
119
|
+
return true;
|
|
120
|
+
};
|
|
121
|
+
/**
|
|
122
|
+
* Checks if any SDK mode (editor or audit) should be loaded.
|
|
123
|
+
* Returns the mode type if active, or null if neither.
|
|
124
|
+
*/
|
|
125
|
+
export const getActiveSdkMode = () => {
|
|
126
|
+
if (shouldLoadEditor())
|
|
127
|
+
return 'editor';
|
|
128
|
+
if (isAuditMode())
|
|
129
|
+
return 'audit';
|
|
130
|
+
return null;
|
|
131
|
+
};
|
|
93
132
|
/**
|
|
94
133
|
* Dynamically loads the Editor SDK script.
|
|
95
134
|
* Validates URL against allowlist and supports SRI integrity checking.
|
|
96
135
|
*/
|
|
97
136
|
export const loadEditorSdk = async (editorUrlOrOptions) => {
|
|
98
137
|
var _a;
|
|
99
|
-
|
|
138
|
+
debug('Syntro Runtime', '====== LOAD EDITOR SDK ======');
|
|
100
139
|
if (typeof window === "undefined") {
|
|
101
|
-
|
|
140
|
+
debug('Syntro Runtime', 'Not in browser - skipping editor SDK load');
|
|
102
141
|
return;
|
|
103
142
|
}
|
|
104
143
|
if (window.SyntroEditor) {
|
|
105
|
-
|
|
144
|
+
debug('Syntro Runtime', 'Editor SDK already loaded (window.SyntroEditor exists)');
|
|
106
145
|
return;
|
|
107
146
|
}
|
|
108
147
|
// Handle both legacy string arg and new options object
|
|
@@ -110,18 +149,18 @@ export const loadEditorSdk = async (editorUrlOrOptions) => {
|
|
|
110
149
|
? { editorUrl: editorUrlOrOptions }
|
|
111
150
|
: editorUrlOrOptions !== null && editorUrlOrOptions !== void 0 ? editorUrlOrOptions : {};
|
|
112
151
|
const editorUrl = (_a = options.editorUrl) !== null && _a !== void 0 ? _a : DEFAULT_EDITOR_URL;
|
|
113
|
-
|
|
114
|
-
|
|
152
|
+
debug('Syntro Runtime', 'Editor URL:', editorUrl);
|
|
153
|
+
debug('Syntro Runtime', 'Options:', {
|
|
115
154
|
hasIntegrity: !!options.integrity,
|
|
116
155
|
isDefault: editorUrl === DEFAULT_EDITOR_URL,
|
|
117
156
|
});
|
|
118
157
|
// Security: Validate URL against allowlist
|
|
119
158
|
if (!validateEditorUrl(editorUrl)) {
|
|
120
159
|
console.error('[Syntro Runtime] ❌ BLOCKED: Editor from untrusted URL:', editorUrl);
|
|
121
|
-
|
|
160
|
+
debug('Syntro Runtime', '================================');
|
|
122
161
|
return;
|
|
123
162
|
}
|
|
124
|
-
|
|
163
|
+
debug('Syntro Runtime', '✓ URL validated, injecting script tag...');
|
|
125
164
|
return new Promise((resolve, reject) => {
|
|
126
165
|
const script = document.createElement("script");
|
|
127
166
|
script.src = editorUrl;
|
|
@@ -130,23 +169,23 @@ export const loadEditorSdk = async (editorUrlOrOptions) => {
|
|
|
130
169
|
if (options.integrity) {
|
|
131
170
|
script.integrity = options.integrity;
|
|
132
171
|
script.crossOrigin = "anonymous";
|
|
133
|
-
|
|
172
|
+
debug('Syntro Runtime', 'SRI integrity check enabled');
|
|
134
173
|
}
|
|
135
174
|
script.onload = () => {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
175
|
+
debug('Syntro Runtime', '✓ Editor SDK script loaded successfully');
|
|
176
|
+
debug('Syntro Runtime', 'window.SyntroEditor:', !!window.SyntroEditor);
|
|
177
|
+
debug('Syntro Runtime', '================================');
|
|
139
178
|
resolve();
|
|
140
179
|
};
|
|
141
180
|
script.onerror = (err) => {
|
|
142
181
|
console.error('[Syntro Runtime] ❌ Failed to load Editor SDK:', err);
|
|
143
182
|
console.error('[Syntro Runtime] URL attempted:', editorUrl);
|
|
144
183
|
console.error('[Syntro Runtime] Check: Is the URL accessible? CORS? Network?');
|
|
145
|
-
|
|
184
|
+
debug('Syntro Runtime', '================================');
|
|
146
185
|
reject(err);
|
|
147
186
|
};
|
|
148
187
|
document.head.appendChild(script);
|
|
149
|
-
|
|
188
|
+
debug('Syntro Runtime', 'Script tag appended to <head>');
|
|
150
189
|
});
|
|
151
190
|
};
|
|
152
191
|
//# sourceMappingURL=editorLoader.js.map
|
package/dist/editorLoader.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editorLoader.js","sourceRoot":"","sources":["../src/editorLoader.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"editorLoader.js","sourceRoot":"","sources":["../src/editorLoader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EventBus - Normalized event stream for the runtime.
|
|
3
|
+
*
|
|
4
|
+
* The EventBus provides:
|
|
5
|
+
* - Publish/subscribe for normalized events
|
|
6
|
+
* - Event history for recent event lookups
|
|
7
|
+
* - Filtering by name, pattern, or source
|
|
8
|
+
*/
|
|
9
|
+
import type { NormalizedEvent, EventFilter, EventCallback, EventUnsubscribe } from "./types";
|
|
10
|
+
export interface EventBusOptions {
|
|
11
|
+
/** Maximum number of events to keep in history */
|
|
12
|
+
maxHistorySize?: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* EventBus class for managing normalized events.
|
|
16
|
+
*/
|
|
17
|
+
export declare class EventBus {
|
|
18
|
+
private subscriptions;
|
|
19
|
+
private history;
|
|
20
|
+
private maxHistorySize;
|
|
21
|
+
constructor(options?: EventBusOptions);
|
|
22
|
+
/**
|
|
23
|
+
* Subscribe to events matching an optional filter.
|
|
24
|
+
* Returns an unsubscribe function.
|
|
25
|
+
*/
|
|
26
|
+
subscribe(filterOrCallback: EventFilter | EventCallback, maybeCallback?: EventCallback): EventUnsubscribe;
|
|
27
|
+
/**
|
|
28
|
+
* Publish an event to all matching subscribers.
|
|
29
|
+
*/
|
|
30
|
+
publish(name: string, props?: Record<string, unknown>, source?: NormalizedEvent["source"]): void;
|
|
31
|
+
/**
|
|
32
|
+
* Publish a pre-constructed NormalizedEvent.
|
|
33
|
+
*/
|
|
34
|
+
publishEvent(event: NormalizedEvent): void;
|
|
35
|
+
/**
|
|
36
|
+
* Get recent events matching an optional filter.
|
|
37
|
+
*/
|
|
38
|
+
getRecent(filter?: EventFilter, limit?: number): NormalizedEvent[];
|
|
39
|
+
/**
|
|
40
|
+
* Check if an event with a specific name occurred within a time window.
|
|
41
|
+
*/
|
|
42
|
+
hasRecentEvent(eventName: string, withinMs: number, source?: NormalizedEvent["source"]): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Count events matching a filter within a time window.
|
|
45
|
+
*/
|
|
46
|
+
countRecentEvents(filter: EventFilter, withinMs?: number): number;
|
|
47
|
+
/**
|
|
48
|
+
* Clear all event history.
|
|
49
|
+
*/
|
|
50
|
+
clearHistory(): void;
|
|
51
|
+
/**
|
|
52
|
+
* Get the number of current subscribers.
|
|
53
|
+
*/
|
|
54
|
+
getSubscriberCount(): number;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Create an EventBus instance.
|
|
58
|
+
*/
|
|
59
|
+
export declare function createEventBus(options?: EventBusOptions): EventBus;
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { EVENT_SCHEMA_VERSION } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Check if an event matches a filter.
|
|
4
|
+
*/
|
|
5
|
+
function matchesFilter(event, filter) {
|
|
6
|
+
if (!filter)
|
|
7
|
+
return true;
|
|
8
|
+
// Check name filter
|
|
9
|
+
if (filter.names && filter.names.length > 0) {
|
|
10
|
+
if (!filter.names.includes(event.name)) {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
// Check pattern filter
|
|
15
|
+
if (filter.patterns && filter.patterns.length > 0) {
|
|
16
|
+
const matched = filter.patterns.some((pattern) => {
|
|
17
|
+
try {
|
|
18
|
+
const regex = new RegExp(pattern);
|
|
19
|
+
return regex.test(event.name);
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
if (!matched)
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
// Check source filter
|
|
29
|
+
if (filter.sources && filter.sources.length > 0) {
|
|
30
|
+
if (!filter.sources.includes(event.source)) {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* EventBus class for managing normalized events.
|
|
38
|
+
*/
|
|
39
|
+
export class EventBus {
|
|
40
|
+
constructor(options = {}) {
|
|
41
|
+
var _a;
|
|
42
|
+
this.subscriptions = new Set();
|
|
43
|
+
this.history = [];
|
|
44
|
+
this.maxHistorySize = (_a = options.maxHistorySize) !== null && _a !== void 0 ? _a : 100;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Subscribe to events matching an optional filter.
|
|
48
|
+
* Returns an unsubscribe function.
|
|
49
|
+
*/
|
|
50
|
+
subscribe(filterOrCallback, maybeCallback) {
|
|
51
|
+
let filter;
|
|
52
|
+
let callback;
|
|
53
|
+
// Handle overloaded signatures
|
|
54
|
+
if (typeof filterOrCallback === "function") {
|
|
55
|
+
filter = undefined;
|
|
56
|
+
callback = filterOrCallback;
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
filter = filterOrCallback;
|
|
60
|
+
callback = maybeCallback;
|
|
61
|
+
}
|
|
62
|
+
const subscription = { filter, callback };
|
|
63
|
+
this.subscriptions.add(subscription);
|
|
64
|
+
return () => {
|
|
65
|
+
this.subscriptions.delete(subscription);
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Publish an event to all matching subscribers.
|
|
70
|
+
*/
|
|
71
|
+
publish(name, props, source = "canvas") {
|
|
72
|
+
const event = {
|
|
73
|
+
ts: Date.now(),
|
|
74
|
+
name,
|
|
75
|
+
source,
|
|
76
|
+
props,
|
|
77
|
+
schemaVersion: EVENT_SCHEMA_VERSION,
|
|
78
|
+
};
|
|
79
|
+
this.publishEvent(event);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Publish a pre-constructed NormalizedEvent.
|
|
83
|
+
*/
|
|
84
|
+
publishEvent(event) {
|
|
85
|
+
// Add to history
|
|
86
|
+
this.history.push(event);
|
|
87
|
+
if (this.history.length > this.maxHistorySize) {
|
|
88
|
+
this.history.shift();
|
|
89
|
+
}
|
|
90
|
+
// Notify matching subscribers
|
|
91
|
+
for (const subscription of this.subscriptions) {
|
|
92
|
+
if (matchesFilter(event, subscription.filter)) {
|
|
93
|
+
try {
|
|
94
|
+
subscription.callback(event);
|
|
95
|
+
}
|
|
96
|
+
catch (err) {
|
|
97
|
+
console.error("[EventBus] Subscriber error:", err);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Get recent events matching an optional filter.
|
|
104
|
+
*/
|
|
105
|
+
getRecent(filter, limit) {
|
|
106
|
+
let events = this.history;
|
|
107
|
+
if (filter) {
|
|
108
|
+
events = events.filter((e) => matchesFilter(e, filter));
|
|
109
|
+
}
|
|
110
|
+
if (limit && limit > 0) {
|
|
111
|
+
events = events.slice(-limit);
|
|
112
|
+
}
|
|
113
|
+
return events;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Check if an event with a specific name occurred within a time window.
|
|
117
|
+
*/
|
|
118
|
+
hasRecentEvent(eventName, withinMs, source) {
|
|
119
|
+
const cutoff = Date.now() - withinMs;
|
|
120
|
+
return this.history.some((e) => e.name === eventName &&
|
|
121
|
+
e.ts >= cutoff &&
|
|
122
|
+
(source === undefined || e.source === source));
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Count events matching a filter within a time window.
|
|
126
|
+
*/
|
|
127
|
+
countRecentEvents(filter, withinMs) {
|
|
128
|
+
let events = this.history.filter((e) => matchesFilter(e, filter));
|
|
129
|
+
if (withinMs !== undefined) {
|
|
130
|
+
const cutoff = Date.now() - withinMs;
|
|
131
|
+
events = events.filter((e) => e.ts >= cutoff);
|
|
132
|
+
}
|
|
133
|
+
return events.length;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Clear all event history.
|
|
137
|
+
*/
|
|
138
|
+
clearHistory() {
|
|
139
|
+
this.history = [];
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Get the number of current subscribers.
|
|
143
|
+
*/
|
|
144
|
+
getSubscriberCount() {
|
|
145
|
+
return this.subscriptions.size;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Create an EventBus instance.
|
|
150
|
+
*/
|
|
151
|
+
export function createEventBus(options = {}) {
|
|
152
|
+
return new EventBus(options);
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=EventBus.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EventBus.js","sourceRoot":"","sources":["../../src/events/EventBus.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Events module exports.
|
|
3
|
+
*/
|
|
4
|
+
export * from "./types";
|
|
5
|
+
export * from "./schema";
|
|
6
|
+
export { EventBus, createEventBus } from "./EventBus";
|
|
7
|
+
export type { EventBusOptions } from "./EventBus";
|
|
8
|
+
export { normalizePostHogEvent, shouldNormalizeEvent, createPostHogNormalizer, } from "./normalizers/posthog";
|
|
9
|
+
export { CanvasEvents } from "./normalizers/canvas";
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Events module exports.
|
|
3
|
+
*/
|
|
4
|
+
export * from "./types";
|
|
5
|
+
export * from "./schema";
|
|
6
|
+
export { EventBus, createEventBus } from "./EventBus";
|
|
7
|
+
// Normalizers
|
|
8
|
+
export { normalizePostHogEvent, shouldNormalizeEvent, createPostHogNormalizer, } from "./normalizers/posthog";
|
|
9
|
+
export { CanvasEvents } from "./normalizers/canvas";
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/events/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAGtD,cAAc;AACd,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canvas Event Normalizer
|
|
3
|
+
*
|
|
4
|
+
* Transforms Smart Canvas events into normalized events for the EventBus.
|
|
5
|
+
*/
|
|
6
|
+
import type { NormalizedEvent } from "../types";
|
|
7
|
+
import type { CanvasSurface } from "../../telemetry/types";
|
|
8
|
+
/**
|
|
9
|
+
* Canvas opened event.
|
|
10
|
+
*/
|
|
11
|
+
export declare function canvasOpened(surface: CanvasSurface): NormalizedEvent;
|
|
12
|
+
/**
|
|
13
|
+
* Canvas closed event.
|
|
14
|
+
*/
|
|
15
|
+
export declare function canvasClosed(surface: CanvasSurface): NormalizedEvent;
|
|
16
|
+
/**
|
|
17
|
+
* Tile viewed event.
|
|
18
|
+
*/
|
|
19
|
+
export declare function tileViewed(tileId: string, surface: CanvasSurface): NormalizedEvent;
|
|
20
|
+
/**
|
|
21
|
+
* Tile expanded event.
|
|
22
|
+
*/
|
|
23
|
+
export declare function tileExpanded(tileId: string, surface: CanvasSurface): NormalizedEvent;
|
|
24
|
+
/**
|
|
25
|
+
* Tile collapsed event.
|
|
26
|
+
*/
|
|
27
|
+
export declare function tileCollapsed(tileId: string, surface: CanvasSurface): NormalizedEvent;
|
|
28
|
+
/**
|
|
29
|
+
* Tile action event.
|
|
30
|
+
*/
|
|
31
|
+
export declare function tileAction(tileId: string, actionId: string, surface: CanvasSurface): NormalizedEvent;
|
|
32
|
+
/**
|
|
33
|
+
* Overlay/tour started event.
|
|
34
|
+
*/
|
|
35
|
+
export declare function overlayStarted(recipeId: string, recipeName?: string): NormalizedEvent;
|
|
36
|
+
/**
|
|
37
|
+
* Overlay/tour completed event.
|
|
38
|
+
*/
|
|
39
|
+
export declare function overlayCompleted(recipeId: string, recipeName?: string): NormalizedEvent;
|
|
40
|
+
/**
|
|
41
|
+
* Overlay/tour dismissed event.
|
|
42
|
+
*/
|
|
43
|
+
export declare function overlayDismissed(recipeId: string, recipeName?: string, stepIndex?: number): NormalizedEvent;
|
|
44
|
+
/**
|
|
45
|
+
* Overlay step viewed event.
|
|
46
|
+
*/
|
|
47
|
+
export declare function overlayStepViewed(recipeId: string, stepIndex: number, stepTitle?: string): NormalizedEvent;
|
|
48
|
+
/**
|
|
49
|
+
* Create a custom canvas event.
|
|
50
|
+
*/
|
|
51
|
+
export declare function customCanvasEvent(name: string, props?: Record<string, unknown>): NormalizedEvent;
|
|
52
|
+
/**
|
|
53
|
+
* Canvas event factory for easy event creation.
|
|
54
|
+
*/
|
|
55
|
+
export declare const CanvasEvents: {
|
|
56
|
+
canvasOpened: typeof canvasOpened;
|
|
57
|
+
canvasClosed: typeof canvasClosed;
|
|
58
|
+
tileViewed: typeof tileViewed;
|
|
59
|
+
tileExpanded: typeof tileExpanded;
|
|
60
|
+
tileCollapsed: typeof tileCollapsed;
|
|
61
|
+
tileAction: typeof tileAction;
|
|
62
|
+
overlayStarted: typeof overlayStarted;
|
|
63
|
+
overlayCompleted: typeof overlayCompleted;
|
|
64
|
+
overlayDismissed: typeof overlayDismissed;
|
|
65
|
+
overlayStepViewed: typeof overlayStepViewed;
|
|
66
|
+
custom: typeof customCanvasEvent;
|
|
67
|
+
};
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { StandardEvents, EVENT_SCHEMA_VERSION } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* Create a canvas event with standard metadata.
|
|
4
|
+
*/
|
|
5
|
+
function createCanvasEvent(name, props) {
|
|
6
|
+
return {
|
|
7
|
+
ts: Date.now(),
|
|
8
|
+
name,
|
|
9
|
+
source: "canvas",
|
|
10
|
+
props,
|
|
11
|
+
schemaVersion: EVENT_SCHEMA_VERSION,
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Canvas opened event.
|
|
16
|
+
*/
|
|
17
|
+
export function canvasOpened(surface) {
|
|
18
|
+
return createCanvasEvent(StandardEvents.CANVAS_OPENED, { surface });
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Canvas closed event.
|
|
22
|
+
*/
|
|
23
|
+
export function canvasClosed(surface) {
|
|
24
|
+
return createCanvasEvent(StandardEvents.CANVAS_CLOSED, { surface });
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Tile viewed event.
|
|
28
|
+
*/
|
|
29
|
+
export function tileViewed(tileId, surface) {
|
|
30
|
+
return createCanvasEvent(StandardEvents.TILE_VIEWED, { tileId, surface });
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Tile expanded event.
|
|
34
|
+
*/
|
|
35
|
+
export function tileExpanded(tileId, surface) {
|
|
36
|
+
return createCanvasEvent(StandardEvents.TILE_EXPANDED, { tileId, surface });
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Tile collapsed event.
|
|
40
|
+
*/
|
|
41
|
+
export function tileCollapsed(tileId, surface) {
|
|
42
|
+
return createCanvasEvent(StandardEvents.TILE_COLLAPSED, { tileId, surface });
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Tile action event.
|
|
46
|
+
*/
|
|
47
|
+
export function tileAction(tileId, actionId, surface) {
|
|
48
|
+
return createCanvasEvent(StandardEvents.TILE_ACTION, {
|
|
49
|
+
tileId,
|
|
50
|
+
actionId,
|
|
51
|
+
surface,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Overlay/tour started event.
|
|
56
|
+
*/
|
|
57
|
+
export function overlayStarted(recipeId, recipeName) {
|
|
58
|
+
return createCanvasEvent(StandardEvents.OVERLAY_STARTED, {
|
|
59
|
+
recipeId,
|
|
60
|
+
recipeName,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Overlay/tour completed event.
|
|
65
|
+
*/
|
|
66
|
+
export function overlayCompleted(recipeId, recipeName) {
|
|
67
|
+
return createCanvasEvent(StandardEvents.OVERLAY_COMPLETED, {
|
|
68
|
+
recipeId,
|
|
69
|
+
recipeName,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Overlay/tour dismissed event.
|
|
74
|
+
*/
|
|
75
|
+
export function overlayDismissed(recipeId, recipeName, stepIndex) {
|
|
76
|
+
return createCanvasEvent(StandardEvents.OVERLAY_DISMISSED, {
|
|
77
|
+
recipeId,
|
|
78
|
+
recipeName,
|
|
79
|
+
stepIndex,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Overlay step viewed event.
|
|
84
|
+
*/
|
|
85
|
+
export function overlayStepViewed(recipeId, stepIndex, stepTitle) {
|
|
86
|
+
return createCanvasEvent(StandardEvents.OVERLAY_STEP_VIEWED, {
|
|
87
|
+
recipeId,
|
|
88
|
+
stepIndex,
|
|
89
|
+
stepTitle,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Create a custom canvas event.
|
|
94
|
+
*/
|
|
95
|
+
export function customCanvasEvent(name, props) {
|
|
96
|
+
// Prefix custom events with "canvas." if not already prefixed
|
|
97
|
+
const eventName = name.startsWith("canvas.") ? name : `canvas.${name}`;
|
|
98
|
+
return createCanvasEvent(eventName, props);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Canvas event factory for easy event creation.
|
|
102
|
+
*/
|
|
103
|
+
export const CanvasEvents = {
|
|
104
|
+
canvasOpened,
|
|
105
|
+
canvasClosed,
|
|
106
|
+
tileViewed,
|
|
107
|
+
tileExpanded,
|
|
108
|
+
tileCollapsed,
|
|
109
|
+
tileAction,
|
|
110
|
+
overlayStarted,
|
|
111
|
+
overlayCompleted,
|
|
112
|
+
overlayDismissed,
|
|
113
|
+
overlayStepViewed,
|
|
114
|
+
custom: customCanvasEvent,
|
|
115
|
+
};
|
|
116
|
+
//# sourceMappingURL=canvas.js.map
|