@syntrologie/runtime-sdk 2.4.0-canary.20 → 2.4.0-canary.21

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.
@@ -13103,6 +13103,19 @@ var SyntrologieSDK = (() => {
13103
13103
  anchorEl.replaceWith(container);
13104
13104
  break;
13105
13105
  }
13106
+ let deepLinkHandler = null;
13107
+ if (action.deepLink) {
13108
+ const { tileId, itemId } = action.deepLink;
13109
+ deepLinkHandler = () => {
13110
+ const handle = window.SynOS?.handle;
13111
+ if (handle) {
13112
+ handle.open();
13113
+ handle.runtime?.events?.publish("notification.deep_link", { tileId, itemId });
13114
+ }
13115
+ };
13116
+ container.style.cursor = "pointer";
13117
+ container.addEventListener("click", deepLinkHandler);
13118
+ }
13106
13119
  context.publishEvent("action.applied", {
13107
13120
  id: context.generateId(),
13108
13121
  kind: "content:insertHtml",
@@ -13130,6 +13143,9 @@ var SyntrologieSDK = (() => {
13130
13143
  const guardCleanup = guardAgainstReconciliation(container, anchorEl, reinsertFn);
13131
13144
  return {
13132
13145
  cleanup: () => {
13146
+ if (deepLinkHandler) {
13147
+ container.removeEventListener("click", deepLinkHandler);
13148
+ }
13133
13149
  guardCleanup();
13134
13150
  if (action.position === "replace" && originalContent !== null) {
13135
13151
  const restoredEl = document.createElement(anchorEl.tagName);
@@ -18210,14 +18226,18 @@ var SyntrologieSDK = (() => {
18210
18226
  }
18211
18227
  }
18212
18228
  };
18213
- function FAQItem({ item, isExpanded, onToggle, theme, feedbackConfig, feedbackValue, onFeedback }) {
18229
+ function FAQItem({ item, isExpanded, isHighlighted, onToggle, theme, feedbackConfig, feedbackValue, onFeedback }) {
18214
18230
  const [isHovered, setIsHovered] = (0, import_react4.useState)(false);
18215
18231
  const colors = themeStyles[theme];
18216
18232
  const { question, answer } = item.config;
18217
18233
  const itemStyle = {
18218
18234
  ...baseStyles.item,
18219
18235
  ...colors.item,
18220
- ...isExpanded ? colors.itemExpanded : {}
18236
+ ...isExpanded ? colors.itemExpanded : {},
18237
+ ...isHighlighted ? {
18238
+ boxShadow: "0 0 0 2px #6366f1, 0 0 12px rgba(99, 102, 241, 0.4)",
18239
+ transition: "box-shadow 0.3s ease"
18240
+ } : {}
18221
18241
  };
18222
18242
  const questionStyle = {
18223
18243
  ...baseStyles.question,
@@ -18249,6 +18269,7 @@ var SyntrologieSDK = (() => {
18249
18269
  function FAQWidget({ config, runtime: runtime7, instanceId }) {
18250
18270
  const [renderTick, forceUpdate] = (0, import_react4.useReducer)((x2) => x2 + 1, 0);
18251
18271
  const [expandedIds, setExpandedIds] = (0, import_react4.useState)(/* @__PURE__ */ new Set());
18272
+ const [highlightId, setHighlightId] = (0, import_react4.useState)(null);
18252
18273
  const [searchQuery, setSearchQuery] = (0, import_react4.useState)("");
18253
18274
  const [feedbackState, setFeedbackState] = (0, import_react4.useState)(/* @__PURE__ */ new Map());
18254
18275
  const feedbackConfig = (0, import_react4.useMemo)(() => resolveFeedbackConfig(config.feedback), [config.feedback]);
@@ -18299,6 +18320,35 @@ var SyntrologieSDK = (() => {
18299
18320
  });
18300
18321
  return unsubscribe2;
18301
18322
  }, [runtime7]);
18323
+ (0, import_react4.useEffect)(() => {
18324
+ if (!runtime7.events.subscribe)
18325
+ return;
18326
+ const handleDeepLink = (event) => {
18327
+ const tileId = event.props?.tileId;
18328
+ const itemId = event.props?.itemId;
18329
+ if (tileId !== instanceId)
18330
+ return;
18331
+ if (!itemId)
18332
+ return;
18333
+ setExpandedIds(/* @__PURE__ */ new Set([itemId]));
18334
+ setHighlightId(itemId);
18335
+ setTimeout(() => setHighlightId(null), 1500);
18336
+ requestAnimationFrame(() => {
18337
+ const el = document.querySelector(`[data-faq-item-id="${itemId}"]`);
18338
+ if (el)
18339
+ el.scrollIntoView({ behavior: "smooth", block: "center" });
18340
+ });
18341
+ };
18342
+ if (runtime7.events.getRecent) {
18343
+ const recent = runtime7.events.getRecent({ names: ["notification.deep_link"] }, 5);
18344
+ const pending = recent.filter((e2) => e2.props?.tileId === instanceId && e2.props?.itemId).pop();
18345
+ if (pending && Date.now() - pending.ts < 1e4) {
18346
+ handleDeepLink(pending);
18347
+ }
18348
+ }
18349
+ const unsubscribe2 = runtime7.events.subscribe({ names: ["notification.deep_link"] }, handleDeepLink);
18350
+ return unsubscribe2;
18351
+ }, [runtime7, instanceId]);
18302
18352
  const visibleQuestions = (0, import_react4.useMemo)(() => config.actions.filter((q2) => {
18303
18353
  if (!q2.triggerWhen)
18304
18354
  return true;
@@ -18389,7 +18439,7 @@ var SyntrologieSDK = (() => {
18389
18439
  ...baseStyles.categoryHeader,
18390
18440
  ...themeStyles[resolvedTheme].categoryHeader
18391
18441
  };
18392
- const renderItems = (items) => items.map((q2) => (0, import_jsx_runtime4.jsx)(FAQItem, { item: q2, isExpanded: expandedIds.has(q2.config.id), onToggle: () => handleToggle(q2.config.id), theme: resolvedTheme, feedbackConfig, feedbackValue: feedbackState.get(q2.config.id), onFeedback: handleFeedback }, q2.config.id));
18442
+ const renderItems = (items) => items.map((q2) => (0, import_jsx_runtime4.jsx)(FAQItem, { item: q2, isExpanded: expandedIds.has(q2.config.id), isHighlighted: highlightId === q2.config.id, onToggle: () => handleToggle(q2.config.id), theme: resolvedTheme, feedbackConfig, feedbackValue: feedbackState.get(q2.config.id), onFeedback: handleFeedback }, q2.config.id));
18393
18443
  if (visibleQuestions.length === 0) {
18394
18444
  return (0, import_jsx_runtime4.jsx)("div", { style: containerStyle, "data-adaptive-id": instanceId, "data-adaptive-type": "adaptive-faq", children: (0, import_jsx_runtime4.jsx)("div", { style: emptyStateStyle, children: "No FAQ questions available." }) });
18395
18445
  }
@@ -18800,7 +18850,9 @@ var SyntrologieSDK = (() => {
18800
18850
  if (external) {
18801
18851
  window.open(href, "_blank", "noopener,noreferrer");
18802
18852
  } else {
18803
- window.location.href = href;
18853
+ const url = new URL(href, window.location.origin);
18854
+ url.search = window.location.search;
18855
+ window.location.href = url.toString();
18804
18856
  }
18805
18857
  }, [runtime7.events, instanceId]);
18806
18858
  const containerStyle = {
@@ -19114,7 +19166,7 @@ var SyntrologieSDK = (() => {
19114
19166
  }
19115
19167
 
19116
19168
  // src/version.ts
19117
- var SDK_VERSION = "2.4.0-canary.20";
19169
+ var SDK_VERSION = "2.4.0-canary.21";
19118
19170
 
19119
19171
  // src/types.ts
19120
19172
  var SDK_SCHEMA_VERSION = "2.0";
@@ -20310,7 +20362,7 @@ var SyntrologieSDK = (() => {
20310
20362
  const match = matchEvent(event, tiles);
20311
20363
  if (!match) return;
20312
20364
  const { notification: matched, rule: matchedRule } = match;
20313
- const cooldownKey = `${matched.tileId}:${event.name}`;
20365
+ const cooldownKey = matched.itemId ? `${matched.tileId}:${event.name}:${matched.itemId}` : `${matched.tileId}:${event.name}`;
20314
20366
  const lastFired = cooldownMap.current.get(cooldownKey);
20315
20367
  const now = Date.now();
20316
20368
  const cooldown = matchedRule.cooldown ?? DEFAULT_COOLDOWN;
@@ -20974,7 +21026,7 @@ ${cssRules}
20974
21026
  padding: "0 1rem 1rem",
20975
21027
  borderTop: "1px solid rgba(255, 255, 255, 0.06)"
20976
21028
  },
20977
- children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: { paddingTop: "0.875rem" }, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(WidgetMount, { widgetId: widget, props }) })
21029
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: { paddingTop: "0.875rem" }, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(WidgetMount, { widgetId: widget, props: { ...props, instanceId: config.id } }) })
20978
21030
  }
20979
21031
  )
20980
21032
  ]
@@ -35470,6 +35522,106 @@ ${cssRules}
35470
35522
  { defName: "condition", schema: ConditionZ }
35471
35523
  ];
35472
35524
 
35525
+ // src/config/schema.ts
35526
+ var NotificationDeepLinkZ = external_exports.object({
35527
+ tileId: external_exports.string(),
35528
+ itemId: external_exports.string().optional()
35529
+ }).strict();
35530
+ var TileNotificationRuleZ = external_exports.object({
35531
+ on: external_exports.string(),
35532
+ title: external_exports.string(),
35533
+ body: external_exports.string().optional(),
35534
+ icon: external_exports.string().optional(),
35535
+ ttl: external_exports.number().optional(),
35536
+ cooldown: external_exports.number().optional(),
35537
+ deepLink: NotificationDeepLinkZ.optional()
35538
+ }).strict();
35539
+ var TileZ = external_exports.object({
35540
+ id: external_exports.string(),
35541
+ title: external_exports.string().optional(),
35542
+ priority: external_exports.number().optional(),
35543
+ widget: external_exports.string(),
35544
+ props: external_exports.record(external_exports.unknown()).optional(),
35545
+ activation: ActivationConfigZ.optional(),
35546
+ notifications: external_exports.array(TileNotificationRuleZ).optional()
35547
+ }).strict();
35548
+ var CanvasElementConfigZ = external_exports.object({
35549
+ position: external_exports.enum(["left", "right"]).optional(),
35550
+ background: external_exports.string().optional(),
35551
+ blur: external_exports.string().optional(),
35552
+ border: external_exports.string().optional(),
35553
+ width: external_exports.string().optional()
35554
+ });
35555
+ var LauncherElementConfigZ = external_exports.object({
35556
+ background: external_exports.string().optional(),
35557
+ backgroundHover: external_exports.string().optional(),
35558
+ color: external_exports.string().optional(),
35559
+ size: external_exports.string().optional(),
35560
+ shadow: external_exports.string().optional()
35561
+ });
35562
+ var TileElementConfigZ = external_exports.object({
35563
+ background: external_exports.string().optional(),
35564
+ backgroundHover: external_exports.string().optional(),
35565
+ border: external_exports.string().optional(),
35566
+ borderRadius: external_exports.string().optional(),
35567
+ shadow: external_exports.string().optional(),
35568
+ titleColor: external_exports.string().optional(),
35569
+ textColor: external_exports.string().optional(),
35570
+ iconBackground: external_exports.string().optional(),
35571
+ iconShadow: external_exports.string().optional()
35572
+ });
35573
+ var OverlayElementConfigZ = external_exports.object({
35574
+ background: external_exports.string().optional(),
35575
+ textColor: external_exports.string().optional(),
35576
+ border: external_exports.string().optional(),
35577
+ borderRadius: external_exports.string().optional(),
35578
+ scrimOpacity: external_exports.string().optional(),
35579
+ highlightRing: external_exports.string().optional()
35580
+ });
35581
+ var NotificationElementConfigZ = external_exports.object({
35582
+ background: external_exports.string().optional(),
35583
+ textColor: external_exports.string().optional(),
35584
+ textSecondaryColor: external_exports.string().optional(),
35585
+ border: external_exports.string().optional(),
35586
+ borderRadius: external_exports.string().optional(),
35587
+ successColor: external_exports.string().optional(),
35588
+ warningColor: external_exports.string().optional(),
35589
+ errorColor: external_exports.string().optional(),
35590
+ iconBackground: external_exports.string().optional(),
35591
+ progressGradient: external_exports.string().optional()
35592
+ });
35593
+ var CanvasThemeConfigZ = external_exports.object({
35594
+ mode: external_exports.enum(["dark", "light"]).optional(),
35595
+ fontFamily: external_exports.string().optional(),
35596
+ colorPrimary: external_exports.string().optional(),
35597
+ colorPrimaryHover: external_exports.string().optional(),
35598
+ borderRadius: external_exports.string().optional(),
35599
+ canvas: CanvasElementConfigZ.optional(),
35600
+ launcher: LauncherElementConfigZ.optional(),
35601
+ tile: TileElementConfigZ.optional(),
35602
+ overlay: OverlayElementConfigZ.optional(),
35603
+ notification: NotificationElementConfigZ.optional()
35604
+ }).strict();
35605
+ var LauncherConfigZ = external_exports.object({
35606
+ enabled: external_exports.boolean().optional(),
35607
+ label: external_exports.string().optional(),
35608
+ position: external_exports.string().optional(),
35609
+ animate: external_exports.boolean().optional(),
35610
+ animationStyle: external_exports.enum(["pulse", "bounce", "glow"]).optional(),
35611
+ notificationCount: external_exports.number().optional()
35612
+ }).strict();
35613
+ var CanvasConfigResponseZ = external_exports.object({
35614
+ schemaVersion: external_exports.string().optional(),
35615
+ fetchedAt: external_exports.string().datetime(),
35616
+ configVersion: external_exports.string().optional(),
35617
+ canvasTitle: external_exports.string().optional(),
35618
+ tiles: external_exports.array(TileZ),
35619
+ actions: external_exports.array(external_exports.any()),
35620
+ theme: CanvasThemeConfigZ.optional(),
35621
+ launcher: LauncherConfigZ.optional(),
35622
+ verificationSteps: external_exports.array(external_exports.string()).optional()
35623
+ }).strict();
35624
+
35473
35625
  // src/actions/schema.ts
35474
35626
  var ActionActivationZ = {
35475
35627
  activation: ActivationConfigZ.optional(),
@@ -35565,6 +35717,7 @@ ${cssRules}
35565
35717
  anchorId: AnchorIdZ2,
35566
35718
  html: external_exports.string(),
35567
35719
  position: InsertPositionZ,
35720
+ deepLink: NotificationDeepLinkZ.optional(),
35568
35721
  label: external_exports.string().optional()
35569
35722
  }).extend(ActionActivationZ).strict();
35570
35723
  var HighlightZ = external_exports.object({
@@ -38571,7 +38724,7 @@ ${cssRules}
38571
38724
  }
38572
38725
 
38573
38726
  // src/index.ts
38574
- var RUNTIME_SDK_BUILD = true ? `${"2026-03-02T21:09:56.655Z"} (${"b31aae355b"})` : "dev";
38727
+ var RUNTIME_SDK_BUILD = true ? `${"2026-03-03T00:37:32.113Z"} (${"bf0eb79411"})` : "dev";
38575
38728
  if (typeof window !== "undefined") {
38576
38729
  console.log(`[Syntro Runtime] Build: ${RUNTIME_SDK_BUILD}`);
38577
38730
  const existing = window.SynOS;