@syntrologie/runtime-sdk 2.4.0-canary.24 → 2.4.0-canary.25
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/dist/actions/schema.js +2 -2
- package/dist/{chunk-LD22WJ44.js → chunk-2WDY7YGN.js} +78 -40
- package/dist/chunk-2WDY7YGN.js.map +7 -0
- package/dist/{chunk-WILWIL6L.js → chunk-7OZFA3CQ.js} +5 -2
- package/dist/chunk-7OZFA3CQ.js.map +7 -0
- package/dist/{chunk-NM5Y27GX.js → chunk-YZ27S3HX.js} +2 -2
- package/dist/config/schema.d.ts +81 -0
- package/dist/config/schema.js +1 -1
- package/dist/index.js +5 -5
- package/dist/index.js.map +2 -2
- package/dist/react.js +3 -3
- package/dist/smart-canvas.esm.js +31 -31
- package/dist/smart-canvas.esm.js.map +3 -3
- package/dist/smart-canvas.js +68 -30
- package/dist/smart-canvas.js.map +2 -2
- package/dist/smart-canvas.min.js +31 -31
- package/dist/smart-canvas.min.js.map +3 -3
- package/dist/version.d.ts +1 -1
- package/package.json +7 -7
- package/schema/canvas-config.schema.json +9 -0
- package/scripts/validate-config.mjs +71 -0
- package/dist/chunk-LD22WJ44.js.map +0 -7
- package/dist/chunk-WILWIL6L.js.map +0 -7
- /package/dist/{chunk-NM5Y27GX.js.map → chunk-YZ27S3HX.js.map} +0 -0
package/dist/version.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@syntrologie/runtime-sdk",
|
|
3
|
-
"version": "2.4.0-canary.
|
|
3
|
+
"version": "2.4.0-canary.25",
|
|
4
4
|
"description": "Syntrologie Runtime SDK for web experimentation and analytics",
|
|
5
5
|
"license": "Proprietary",
|
|
6
6
|
"private": false,
|
|
@@ -67,12 +67,12 @@
|
|
|
67
67
|
"@floating-ui/dom": "^1.7.5",
|
|
68
68
|
"@growthbook/growthbook": "~1.6.2",
|
|
69
69
|
"@growthbook/growthbook-react": "^1.6.4",
|
|
70
|
-
"@syntrologie/adapt-chatbot": "2.4.0-canary.
|
|
71
|
-
"@syntrologie/adapt-content": "2.4.0-canary.
|
|
72
|
-
"@syntrologie/adapt-faq": "2.4.0-canary.
|
|
73
|
-
"@syntrologie/adapt-gamification": "2.4.0-canary.
|
|
74
|
-
"@syntrologie/adapt-nav": "2.4.0-canary.
|
|
75
|
-
"@syntrologie/adapt-overlays": "2.4.0-canary.
|
|
70
|
+
"@syntrologie/adapt-chatbot": "2.4.0-canary.25",
|
|
71
|
+
"@syntrologie/adapt-content": "2.4.0-canary.25",
|
|
72
|
+
"@syntrologie/adapt-faq": "2.4.0-canary.25",
|
|
73
|
+
"@syntrologie/adapt-gamification": "2.4.0-canary.25",
|
|
74
|
+
"@syntrologie/adapt-nav": "2.4.0-canary.25",
|
|
75
|
+
"@syntrologie/adapt-overlays": "2.4.0-canary.25",
|
|
76
76
|
"lucide-react": "^0.576.0",
|
|
77
77
|
"posthog-js": "~1.302.2",
|
|
78
78
|
"zod": "^3.25.76"
|
|
@@ -271,6 +271,15 @@
|
|
|
271
271
|
},
|
|
272
272
|
"width": {
|
|
273
273
|
"type": "string"
|
|
274
|
+
},
|
|
275
|
+
"transitionDuration": {
|
|
276
|
+
"type": "string"
|
|
277
|
+
},
|
|
278
|
+
"transitionEasing": {
|
|
279
|
+
"type": "string"
|
|
280
|
+
},
|
|
281
|
+
"transitionFade": {
|
|
282
|
+
"type": "string"
|
|
274
283
|
}
|
|
275
284
|
},
|
|
276
285
|
"additionalProperties": false
|
|
@@ -159,3 +159,74 @@ if (routeErrors.length > 0) {
|
|
|
159
159
|
for (const e of routeErrors) console.error(` - ${e}`);
|
|
160
160
|
process.exit(1);
|
|
161
161
|
}
|
|
162
|
+
|
|
163
|
+
// --- Semantic warnings (non-blocking, design-quality hints) ---
|
|
164
|
+
const warnings = [];
|
|
165
|
+
|
|
166
|
+
// Tile-level route restrictions should be rare. They hide the entire tile
|
|
167
|
+
// (and all its actions) on non-matching pages. The preferred pattern is:
|
|
168
|
+
// - Tile: routes ["/**"] (or omitted) + onlyIfPopulated: true
|
|
169
|
+
// - Actions: triggerWhen with route conditions to self-target specific pages
|
|
170
|
+
// This way the tile is always available and actions decide when to appear.
|
|
171
|
+
for (const tile of config.tiles ?? []) {
|
|
172
|
+
const routes = tile.activation?.routes;
|
|
173
|
+
if (!routes) continue;
|
|
174
|
+
|
|
175
|
+
const includePatterns = routes.include ?? [];
|
|
176
|
+
const hasCatchAll = includePatterns.some((r) => WILDCARD_PATTERNS.includes(r) || r === '/**');
|
|
177
|
+
if (hasCatchAll) continue;
|
|
178
|
+
|
|
179
|
+
const routeList = includePatterns.join('", "');
|
|
180
|
+
const actions = tile.props?.actions ?? [];
|
|
181
|
+
const actionsWithoutTrigger = actions.filter((a) => !a.triggerWhen).length;
|
|
182
|
+
|
|
183
|
+
let detail = '';
|
|
184
|
+
if (actionsWithoutTrigger > 0) {
|
|
185
|
+
detail =
|
|
186
|
+
`\n ${actionsWithoutTrigger} of ${actions.length} action(s) have no triggerWhen — ` +
|
|
187
|
+
`they'll never appear outside ["${routeList}"].`;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
warnings.push(
|
|
191
|
+
`Tile "${tile.id}": activation.routes restricts to ["${routeList}"].${detail}\n` +
|
|
192
|
+
` Prefer: set routes to ["/**"], add onlyIfPopulated: true, and use ` +
|
|
193
|
+
`triggerWhen with a "route" condition on each action to target specific pages.`
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// page_url conditions should use ** prefix to match any host, not absolute paths.
|
|
198
|
+
// "/dashboard/state" won't match "http://localhost:8088/dashboard/state" because
|
|
199
|
+
// page_url evaluates against the full URL. Use "**/dashboard/state" instead.
|
|
200
|
+
function collectPageUrlConditions(obj, path, results) {
|
|
201
|
+
if (!obj || typeof obj !== 'object') return;
|
|
202
|
+
if (Array.isArray(obj)) {
|
|
203
|
+
for (const [i, item] of obj.entries()) {
|
|
204
|
+
collectPageUrlConditions(item, `${path}[${i}]`, results);
|
|
205
|
+
}
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
if (obj.type === 'page_url' && typeof obj.url === 'string') {
|
|
209
|
+
results.push({ path, url: obj.url });
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
for (const [key, val] of Object.entries(obj)) {
|
|
213
|
+
collectPageUrlConditions(val, `${path}.${key}`, results);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
const pageUrlHits = [];
|
|
218
|
+
collectPageUrlConditions(config, 'config', pageUrlHits);
|
|
219
|
+
for (const { path, url } of pageUrlHits) {
|
|
220
|
+
if (url.startsWith('/')) {
|
|
221
|
+
warnings.push(
|
|
222
|
+
`${path}: page_url "${url}" uses an absolute path.\n` +
|
|
223
|
+
` page_url matches against the full URL (e.g., "http://localhost:8088${url}"),\n` +
|
|
224
|
+
` so "${url}" will never match. Use "**${url}" instead.`
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if (warnings.length > 0) {
|
|
230
|
+
console.warn(`\n\u26A0\uFE0F ${warnings.length} design warning(s):`);
|
|
231
|
+
for (const w of warnings) console.warn(` - ${w}`);
|
|
232
|
+
}
|