@wix/web5-core 1.56.1 → 1.57.1

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 (192) hide show
  1. package/dist/cjs/client/wixAuthFetch.js +2 -2
  2. package/dist/cjs/client/wixAuthFetch.js.map +1 -1
  3. package/dist/cjs/component/componentDefinitions/HeroEntitySectionDefinition.js +20 -15
  4. package/dist/cjs/component/componentDefinitions/HeroEntitySectionDefinition.js.map +1 -1
  5. package/dist/cjs/component/componentDefinitions/HeroSectionDefinition.js +12 -4
  6. package/dist/cjs/component/componentDefinitions/HeroSectionDefinition.js.map +1 -1
  7. package/dist/cjs/component/componentDefinitions/listItemsSectionDefinition.js +24 -29
  8. package/dist/cjs/component/componentDefinitions/listItemsSectionDefinition.js.map +1 -1
  9. package/dist/cjs/component/componentParser.js +8 -1
  10. package/dist/cjs/component/componentParser.js.map +1 -1
  11. package/dist/cjs/component/types.js.map +1 -1
  12. package/dist/cjs/components/placement/PlacementResponseRenderer.css +0 -4
  13. package/dist/cjs/components/placement/PlacementResponseRenderer.js +11 -33
  14. package/dist/cjs/components/placement/PlacementResponseRenderer.js.map +1 -1
  15. package/dist/cjs/components/placement/buildPlacementDependencies.js.map +1 -1
  16. package/dist/cjs/components/ui/OptimizedImage.js +59 -14
  17. package/dist/cjs/components/ui/OptimizedImage.js.map +1 -1
  18. package/dist/cjs/components/ui/SectionSkeleton.css +19 -0
  19. package/dist/cjs/components/ui/SectionSkeleton.js +8 -4
  20. package/dist/cjs/components/ui/SectionSkeleton.js.map +1 -1
  21. package/dist/cjs/components/ui/UserQuery.css +72 -0
  22. package/dist/cjs/components/ui/UserQuery.js +131 -37
  23. package/dist/cjs/components/ui/UserQuery.js.map +1 -1
  24. package/dist/cjs/context/UserQueryContext.js +34 -0
  25. package/dist/cjs/context/UserQueryContext.js.map +1 -0
  26. package/dist/cjs/entity/defaultExtractor.js +9 -2
  27. package/dist/cjs/entity/defaultExtractor.js.map +1 -1
  28. package/dist/cjs/entity/fetchEntityListData.js +13 -26
  29. package/dist/cjs/entity/fetchEntityListData.js.map +1 -1
  30. package/dist/cjs/entity/index.js +5 -1
  31. package/dist/cjs/entity/index.js.map +1 -1
  32. package/dist/cjs/entity/listEntityItems.js +90 -0
  33. package/dist/cjs/entity/listEntityItems.js.map +1 -0
  34. package/dist/cjs/hostScope.js +63 -0
  35. package/dist/cjs/hostScope.js.map +1 -0
  36. package/dist/cjs/index.js +38 -13
  37. package/dist/cjs/index.js.map +1 -1
  38. package/dist/cjs/patternValidator/validator.test.js +61 -61
  39. package/dist/cjs/patternValidator/validator.test.js.map +1 -1
  40. package/dist/cjs/registry/ComponentRegistry.js +22 -2
  41. package/dist/cjs/registry/ComponentRegistry.js.map +1 -1
  42. package/dist/cjs/registry/index.js +1 -3
  43. package/dist/cjs/registry/index.js.map +1 -1
  44. package/dist/cjs/registry/types.js.map +1 -1
  45. package/dist/cjs/styles/base-utilities.css +35 -0
  46. package/dist/cjs/styles/components.css +1 -0
  47. package/dist/cjs/styles/host-reset.css +100 -0
  48. package/dist/cjs/styles/tailwind-theme.css +6 -6
  49. package/dist/cjs/utils/backendEnvironment.js +78 -0
  50. package/dist/cjs/utils/backendEnvironment.js.map +1 -0
  51. package/dist/cjs/utils/entityLinkParser.js +3 -1
  52. package/dist/cjs/utils/entityLinkParser.js.map +1 -1
  53. package/dist/cjs/utils/imageBackdrop.js +269 -0
  54. package/dist/cjs/utils/imageBackdrop.js.map +1 -0
  55. package/dist/cjs/utils/intentExtractor.js +20 -9
  56. package/dist/cjs/utils/intentExtractor.js.map +1 -1
  57. package/dist/cjs/utils/productBackHandoff.js +106 -0
  58. package/dist/cjs/utils/productBackHandoff.js.map +1 -0
  59. package/dist/cjs/utils/refreshPrompts.js +72 -0
  60. package/dist/cjs/utils/refreshPrompts.js.map +1 -0
  61. package/dist/esm/client/wixAuthFetch.js +2 -2
  62. package/dist/esm/client/wixAuthFetch.js.map +1 -1
  63. package/dist/esm/component/componentDefinitions/HeroEntitySectionDefinition.js +20 -15
  64. package/dist/esm/component/componentDefinitions/HeroEntitySectionDefinition.js.map +1 -1
  65. package/dist/esm/component/componentDefinitions/HeroSectionDefinition.js +12 -4
  66. package/dist/esm/component/componentDefinitions/HeroSectionDefinition.js.map +1 -1
  67. package/dist/esm/component/componentDefinitions/listItemsSectionDefinition.js +25 -30
  68. package/dist/esm/component/componentDefinitions/listItemsSectionDefinition.js.map +1 -1
  69. package/dist/esm/component/componentParser.js +8 -1
  70. package/dist/esm/component/componentParser.js.map +1 -1
  71. package/dist/esm/component/types.js.map +1 -1
  72. package/dist/esm/components/placement/PlacementResponseRenderer.css +0 -4
  73. package/dist/esm/components/placement/PlacementResponseRenderer.js +1 -16
  74. package/dist/esm/components/placement/PlacementResponseRenderer.js.map +1 -1
  75. package/dist/esm/components/placement/buildPlacementDependencies.js.map +1 -1
  76. package/dist/esm/components/ui/OptimizedImage.js +50 -5
  77. package/dist/esm/components/ui/OptimizedImage.js.map +1 -1
  78. package/dist/esm/components/ui/SectionSkeleton.css +19 -0
  79. package/dist/esm/components/ui/SectionSkeleton.js +5 -1
  80. package/dist/esm/components/ui/SectionSkeleton.js.map +1 -1
  81. package/dist/esm/components/ui/UserQuery.css +72 -0
  82. package/dist/esm/components/ui/UserQuery.js +52 -6
  83. package/dist/esm/components/ui/UserQuery.js.map +1 -1
  84. package/dist/esm/context/UserQueryContext.js +21 -0
  85. package/dist/esm/context/UserQueryContext.js.map +1 -0
  86. package/dist/esm/entity/defaultExtractor.js +9 -2
  87. package/dist/esm/entity/defaultExtractor.js.map +1 -1
  88. package/dist/esm/entity/fetchEntityListData.js +14 -26
  89. package/dist/esm/entity/fetchEntityListData.js.map +1 -1
  90. package/dist/esm/entity/index.js +1 -0
  91. package/dist/esm/entity/index.js.map +1 -1
  92. package/dist/esm/entity/listEntityItems.js +85 -0
  93. package/dist/esm/entity/listEntityItems.js.map +1 -0
  94. package/dist/esm/hostScope.js +59 -0
  95. package/dist/esm/hostScope.js.map +1 -0
  96. package/dist/esm/index.js +13 -4
  97. package/dist/esm/index.js.map +1 -1
  98. package/dist/esm/patternValidator/validator.test.js +61 -61
  99. package/dist/esm/patternValidator/validator.test.js.map +1 -1
  100. package/dist/esm/registry/ComponentRegistry.js +22 -2
  101. package/dist/esm/registry/ComponentRegistry.js.map +1 -1
  102. package/dist/esm/registry/index.js +0 -1
  103. package/dist/esm/registry/index.js.map +1 -1
  104. package/dist/esm/registry/types.js.map +1 -1
  105. package/dist/esm/styles/base-utilities.css +35 -0
  106. package/dist/esm/styles/components.css +1 -0
  107. package/dist/esm/styles/host-reset.css +100 -0
  108. package/dist/esm/styles/tailwind-theme.css +6 -6
  109. package/dist/esm/utils/backendEnvironment.js +71 -0
  110. package/dist/esm/utils/backendEnvironment.js.map +1 -0
  111. package/dist/esm/utils/entityLinkParser.js +3 -1
  112. package/dist/esm/utils/entityLinkParser.js.map +1 -1
  113. package/dist/esm/utils/imageBackdrop.js +262 -0
  114. package/dist/esm/utils/imageBackdrop.js.map +1 -0
  115. package/dist/esm/utils/intentExtractor.js +21 -12
  116. package/dist/esm/utils/intentExtractor.js.map +1 -1
  117. package/dist/esm/utils/productBackHandoff.js +100 -0
  118. package/dist/esm/utils/productBackHandoff.js.map +1 -0
  119. package/dist/esm/utils/refreshPrompts.js +67 -0
  120. package/dist/esm/utils/refreshPrompts.js.map +1 -0
  121. package/dist/types/component/componentDefinitions/HeroEntitySectionDefinition.d.ts.map +1 -1
  122. package/dist/types/component/componentDefinitions/HeroSectionDefinition.d.ts.map +1 -1
  123. package/dist/types/component/componentDefinitions/listItemsSectionDefinition.d.ts +2 -2
  124. package/dist/types/component/componentDefinitions/listItemsSectionDefinition.d.ts.map +1 -1
  125. package/dist/types/component/componentParser.d.ts.map +1 -1
  126. package/dist/types/component/types.d.ts +1 -5
  127. package/dist/types/component/types.d.ts.map +1 -1
  128. package/dist/types/components/placement/PlacementResponseRenderer.d.ts +1 -1
  129. package/dist/types/components/placement/PlacementResponseRenderer.d.ts.map +1 -1
  130. package/dist/types/components/placement/buildPlacementDependencies.d.ts +1 -2
  131. package/dist/types/components/placement/buildPlacementDependencies.d.ts.map +1 -1
  132. package/dist/types/components/ui/OptimizedImage.d.ts +9 -0
  133. package/dist/types/components/ui/OptimizedImage.d.ts.map +1 -1
  134. package/dist/types/components/ui/SectionSkeleton.d.ts.map +1 -1
  135. package/dist/types/components/ui/UserQuery.d.ts +21 -0
  136. package/dist/types/components/ui/UserQuery.d.ts.map +1 -1
  137. package/dist/types/context/UserQueryContext.d.ts +12 -0
  138. package/dist/types/context/UserQueryContext.d.ts.map +1 -0
  139. package/dist/types/entity/defaultExtractor.d.ts.map +1 -1
  140. package/dist/types/entity/fetchEntityListData.d.ts +0 -2
  141. package/dist/types/entity/fetchEntityListData.d.ts.map +1 -1
  142. package/dist/types/entity/index.d.ts +1 -0
  143. package/dist/types/entity/index.d.ts.map +1 -1
  144. package/dist/types/entity/listEntityItems.d.ts +40 -0
  145. package/dist/types/entity/listEntityItems.d.ts.map +1 -0
  146. package/dist/types/hostScope.d.ts +83 -0
  147. package/dist/types/hostScope.d.ts.map +1 -0
  148. package/dist/types/index.d.ts +11 -7
  149. package/dist/types/index.d.ts.map +1 -1
  150. package/dist/types/registry/ComponentRegistry.d.ts +8 -0
  151. package/dist/types/registry/ComponentRegistry.d.ts.map +1 -1
  152. package/dist/types/registry/index.d.ts +0 -1
  153. package/dist/types/registry/index.d.ts.map +1 -1
  154. package/dist/types/registry/types.d.ts +5 -6
  155. package/dist/types/registry/types.d.ts.map +1 -1
  156. package/dist/types/utils/backendEnvironment.d.ts +30 -0
  157. package/dist/types/utils/backendEnvironment.d.ts.map +1 -0
  158. package/dist/types/utils/entityLinkParser.d.ts.map +1 -1
  159. package/dist/types/utils/imageBackdrop.d.ts +102 -0
  160. package/dist/types/utils/imageBackdrop.d.ts.map +1 -0
  161. package/dist/types/utils/intentExtractor.d.ts +21 -4
  162. package/dist/types/utils/intentExtractor.d.ts.map +1 -1
  163. package/dist/types/utils/productBackHandoff.d.ts +43 -0
  164. package/dist/types/utils/productBackHandoff.d.ts.map +1 -0
  165. package/dist/types/utils/refreshPrompts.d.ts +32 -0
  166. package/dist/types/utils/refreshPrompts.d.ts.map +1 -0
  167. package/package.json +2 -2
  168. package/src/components/placement/PlacementResponseRenderer.css +0 -4
  169. package/src/components/ui/SectionSkeleton.css +19 -0
  170. package/src/components/ui/UserQuery.css +72 -0
  171. package/src/styles/base-utilities.css +35 -0
  172. package/src/styles/components.css +1 -0
  173. package/src/styles/host-reset.css +100 -0
  174. package/src/styles/tailwind-theme.css +6 -6
  175. package/dist/cjs/registry/Intent.js +0 -19
  176. package/dist/cjs/registry/Intent.js.map +0 -1
  177. package/dist/cjs/utils/conversationApi.js +0 -52
  178. package/dist/cjs/utils/conversationApi.js.map +0 -1
  179. package/dist/cjs/utils/conversationMode.js +0 -23
  180. package/dist/cjs/utils/conversationMode.js.map +0 -1
  181. package/dist/esm/registry/Intent.js +0 -15
  182. package/dist/esm/registry/Intent.js.map +0 -1
  183. package/dist/esm/utils/conversationApi.js +0 -45
  184. package/dist/esm/utils/conversationApi.js.map +0 -1
  185. package/dist/esm/utils/conversationMode.js +0 -18
  186. package/dist/esm/utils/conversationMode.js.map +0 -1
  187. package/dist/types/registry/Intent.d.ts +0 -12
  188. package/dist/types/registry/Intent.d.ts.map +0 -1
  189. package/dist/types/utils/conversationApi.d.ts +0 -26
  190. package/dist/types/utils/conversationApi.d.ts.map +0 -1
  191. package/dist/types/utils/conversationMode.d.ts +0 -16
  192. package/dist/types/utils/conversationMode.d.ts.map +0 -1
@@ -14,6 +14,14 @@ var _jsxFileName = "/home/builduser/work/c2b6ca0b3fa984ee/packages/web5-core/dis
14
14
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
15
15
  const DEFAULT_LOADING_MESSAGES = ['Thinking…', 'Recognizing intent…', 'Connecting the dots…', 'Synthesizing insights…', 'Formulating a response…'];
16
16
  const headerClassName = 'web5-user-query sticky top-0 z-10 flex items-center justify-between bg-white/60 backdrop-blur-sm pl-5 pr-[10px] py-[7px] sm:px-[30px] sm:py-[17px]';
17
+
18
+ /**
19
+ * Product the visitor was redirected from (DL #114). Rendered as a back badge
20
+ * above the query: back arrow + thumbnail + product name. All fields are
21
+ * resolved and validated app-side (allowed-domain `backUrl`, `https:`
22
+ * `imageUrl`) before reaching this presentational component.
23
+ */
24
+
17
25
  const UserQuery = ({
18
26
  query,
19
27
  onNewConversation,
@@ -27,7 +35,9 @@ const UserQuery = ({
27
35
  loading,
28
36
  newConversationLabel = 'New conversation',
29
37
  copiedLabel = 'Link Copied',
30
- copiedDurationMs = 2000
38
+ copiedDurationMs = 2000,
39
+ productBackContext,
40
+ onBackToProduct
31
41
  }) => {
32
42
  const forwardStack = (0, _react.useMemo)(() => (0, _navigationStack.getForwardStack)(), [currentTriggerId]);
33
43
  const canGoForward = forwardStack.length > 0;
@@ -55,6 +65,10 @@ const UserQuery = ({
55
65
  onNewConversation == null || onNewConversation();
56
66
  }, [onNewConversation]);
57
67
  const [shareState, setShareState] = (0, _react.useState)('idle');
68
+ const [productImageError, setProductImageError] = (0, _react.useState)(false);
69
+ (0, _react.useEffect)(() => {
70
+ setProductImageError(false);
71
+ }, [productBackContext == null ? void 0 : productBackContext.imageUrl]);
58
72
  const handleShare = (0, _react.useCallback)(async () => {
59
73
  if (shareState !== 'idle') {
60
74
  return;
@@ -94,6 +108,70 @@ const UserQuery = ({
94
108
  }
95
109
  const isCopied = shareState === 'copied';
96
110
  const isLoading = shareState === 'loading';
111
+ const productBadge = productBackContext ? (() => {
112
+ const {
113
+ title,
114
+ imageUrl,
115
+ backUrl,
116
+ label
117
+ } = productBackContext;
118
+ const canNavigateBack = !!backUrl && !!onBackToProduct;
119
+ const content = /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_UndoIcon.UndoIcon, {
120
+ className: "web5-user-query__product-back-icon",
121
+ __self: void 0,
122
+ __source: {
123
+ fileName: _jsxFileName,
124
+ lineNumber: 193,
125
+ columnNumber: 13
126
+ }
127
+ }), imageUrl && !productImageError && /*#__PURE__*/_react.default.createElement("span", {
128
+ className: "web5-user-query__product-back-thumb",
129
+ __self: void 0,
130
+ __source: {
131
+ fileName: _jsxFileName,
132
+ lineNumber: 195,
133
+ columnNumber: 15
134
+ }
135
+ }, /*#__PURE__*/_react.default.createElement("img", {
136
+ src: imageUrl,
137
+ alt: "",
138
+ onError: () => setProductImageError(true),
139
+ __self: void 0,
140
+ __source: {
141
+ fileName: _jsxFileName,
142
+ lineNumber: 196,
143
+ columnNumber: 17
144
+ }
145
+ })), /*#__PURE__*/_react.default.createElement("span", {
146
+ className: "web5-user-query__product-back-title",
147
+ __self: void 0,
148
+ __source: {
149
+ fileName: _jsxFileName,
150
+ lineNumber: 203,
151
+ columnNumber: 13
152
+ }
153
+ }, title));
154
+ return canNavigateBack ? /*#__PURE__*/_react.default.createElement("button", {
155
+ type: "button",
156
+ onClick: () => onBackToProduct == null ? void 0 : onBackToProduct(backUrl),
157
+ "aria-label": label ?? `Back to ${title}`,
158
+ className: "web5-user-query__product-back",
159
+ __self: void 0,
160
+ __source: {
161
+ fileName: _jsxFileName,
162
+ lineNumber: 207,
163
+ columnNumber: 11
164
+ }
165
+ }, content) : /*#__PURE__*/_react.default.createElement("div", {
166
+ className: "web5-user-query__product-back web5-user-query__product-back--static",
167
+ __self: void 0,
168
+ __source: {
169
+ fileName: _jsxFileName,
170
+ lineNumber: 216,
171
+ columnNumber: 11
172
+ }
173
+ }, content);
174
+ })() : null;
97
175
  if (loading) {
98
176
  const progressText = loading.progressMessage ?? cycledMessage;
99
177
  return /*#__PURE__*/_react.default.createElement("div", {
@@ -104,32 +182,40 @@ const UserQuery = ({
104
182
  __self: void 0,
105
183
  __source: {
106
184
  fileName: _jsxFileName,
107
- lineNumber: 161,
185
+ lineNumber: 226,
108
186
  columnNumber: 7
109
187
  }
110
- }, /*#__PURE__*/_react.default.createElement("p", {
111
- className: "text-[14px] leading-5 text-text-body truncate min-w-0 max-w-[700px] flex-1",
112
- title: `Asking: ${loading.pendingQuery}`,
188
+ }, /*#__PURE__*/_react.default.createElement("div", {
189
+ className: "web5-user-query__left flex-1",
113
190
  __self: void 0,
114
191
  __source: {
115
192
  fileName: _jsxFileName,
116
- lineNumber: 167,
193
+ lineNumber: 232,
117
194
  columnNumber: 9
118
195
  }
196
+ }, productBadge, /*#__PURE__*/_react.default.createElement("p", {
197
+ className: "text-[14px] leading-5 text-text-body truncate min-w-0 max-w-[700px]",
198
+ title: `Asking: ${loading.pendingQuery}`,
199
+ __self: void 0,
200
+ __source: {
201
+ fileName: _jsxFileName,
202
+ lineNumber: 234,
203
+ columnNumber: 11
204
+ }
119
205
  }, /*#__PURE__*/_react.default.createElement("span", {
120
206
  className: "text-text-body/70",
121
207
  __self: void 0,
122
208
  __source: {
123
209
  fileName: _jsxFileName,
124
- lineNumber: 171,
125
- columnNumber: 11
210
+ lineNumber: 238,
211
+ columnNumber: 13
126
212
  }
127
- }, "Asking: "), loading.pendingQuery), progressText && /*#__PURE__*/_react.default.createElement("div", {
213
+ }, "Asking: "), loading.pendingQuery)), progressText && /*#__PURE__*/_react.default.createElement("div", {
128
214
  className: "hidden sm:flex items-center gap-2 ml-[10px] shrink-0 min-w-0",
129
215
  __self: void 0,
130
216
  __source: {
131
217
  fileName: _jsxFileName,
132
- lineNumber: 175,
218
+ lineNumber: 243,
133
219
  columnNumber: 11
134
220
  }
135
221
  }, /*#__PURE__*/_react.default.createElement("div", {
@@ -138,7 +224,7 @@ const UserQuery = ({
138
224
  __self: void 0,
139
225
  __source: {
140
226
  fileName: _jsxFileName,
141
- lineNumber: 176,
227
+ lineNumber: 244,
142
228
  columnNumber: 13
143
229
  }
144
230
  }), /*#__PURE__*/_react.default.createElement("p", {
@@ -146,7 +232,7 @@ const UserQuery = ({
146
232
  __self: void 0,
147
233
  __source: {
148
234
  fileName: _jsxFileName,
149
- lineNumber: 180,
235
+ lineNumber: 248,
150
236
  columnNumber: 13
151
237
  }
152
238
  }, progressText)));
@@ -156,7 +242,7 @@ const UserQuery = ({
156
242
  __self: void 0,
157
243
  __source: {
158
244
  fileName: _jsxFileName,
159
- lineNumber: 190,
245
+ lineNumber: 258,
160
246
  columnNumber: 5
161
247
  }
162
248
  }, /*#__PURE__*/_react.default.createElement("div", {
@@ -164,24 +250,32 @@ const UserQuery = ({
164
250
  __self: void 0,
165
251
  __source: {
166
252
  fileName: _jsxFileName,
167
- lineNumber: 191,
253
+ lineNumber: 259,
168
254
  columnNumber: 7
169
255
  }
170
- }, /*#__PURE__*/_react.default.createElement("p", {
256
+ }, /*#__PURE__*/_react.default.createElement("div", {
257
+ className: "web5-user-query__left",
258
+ __self: void 0,
259
+ __source: {
260
+ fileName: _jsxFileName,
261
+ lineNumber: 260,
262
+ columnNumber: 9
263
+ }
264
+ }, productBadge, /*#__PURE__*/_react.default.createElement("p", {
171
265
  className: "web5-user-query__title text-[14px] leading-5 text-text-body truncate min-w-0 max-w-[700px]",
172
266
  title: query,
173
267
  __self: void 0,
174
268
  __source: {
175
269
  fileName: _jsxFileName,
176
- lineNumber: 192,
177
- columnNumber: 9
270
+ lineNumber: 262,
271
+ columnNumber: 11
178
272
  }
179
- }, query), hasNavigation && /*#__PURE__*/_react.default.createElement("div", {
273
+ }, query)), hasNavigation && /*#__PURE__*/_react.default.createElement("div", {
180
274
  className: "flex items-center gap-[9px]",
181
275
  __self: void 0,
182
276
  __source: {
183
277
  fileName: _jsxFileName,
184
- lineNumber: 199,
278
+ lineNumber: 270,
185
279
  columnNumber: 11
186
280
  }
187
281
  }, /*#__PURE__*/_react.default.createElement("button", {
@@ -194,14 +288,14 @@ const UserQuery = ({
194
288
  __self: void 0,
195
289
  __source: {
196
290
  fileName: _jsxFileName,
197
- lineNumber: 200,
291
+ lineNumber: 271,
198
292
  columnNumber: 13
199
293
  }
200
294
  }, /*#__PURE__*/_react.default.createElement(_UndoIcon.UndoIcon, {
201
295
  __self: void 0,
202
296
  __source: {
203
297
  fileName: _jsxFileName,
204
- lineNumber: 208,
298
+ lineNumber: 279,
205
299
  columnNumber: 15
206
300
  }
207
301
  })), /*#__PURE__*/_react.default.createElement("button", {
@@ -214,14 +308,14 @@ const UserQuery = ({
214
308
  __self: void 0,
215
309
  __source: {
216
310
  fileName: _jsxFileName,
217
- lineNumber: 210,
311
+ lineNumber: 281,
218
312
  columnNumber: 13
219
313
  }
220
314
  }, /*#__PURE__*/_react.default.createElement(_RedoIcon.RedoIcon, {
221
315
  __self: void 0,
222
316
  __source: {
223
317
  fileName: _jsxFileName,
224
- lineNumber: 218,
318
+ lineNumber: 289,
225
319
  columnNumber: 15
226
320
  }
227
321
  })))), /*#__PURE__*/_react.default.createElement("div", {
@@ -229,7 +323,7 @@ const UserQuery = ({
229
323
  __self: void 0,
230
324
  __source: {
231
325
  fileName: _jsxFileName,
232
- lineNumber: 223,
326
+ lineNumber: 294,
233
327
  columnNumber: 7
234
328
  }
235
329
  }, /*#__PURE__*/_react.default.createElement("div", {
@@ -237,7 +331,7 @@ const UserQuery = ({
237
331
  __self: void 0,
238
332
  __source: {
239
333
  fileName: _jsxFileName,
240
- lineNumber: 225,
334
+ lineNumber: 296,
241
335
  columnNumber: 9
242
336
  }
243
337
  }, /*#__PURE__*/_react.default.createElement("button", {
@@ -249,21 +343,21 @@ const UserQuery = ({
249
343
  __self: void 0,
250
344
  __source: {
251
345
  fileName: _jsxFileName,
252
- lineNumber: 226,
346
+ lineNumber: 297,
253
347
  columnNumber: 11
254
348
  }
255
349
  }, isCopied ? /*#__PURE__*/_react.default.createElement(_CheckIcon.CheckIcon, {
256
350
  __self: void 0,
257
351
  __source: {
258
352
  fileName: _jsxFileName,
259
- lineNumber: 237,
353
+ lineNumber: 308,
260
354
  columnNumber: 25
261
355
  }
262
356
  }) : /*#__PURE__*/_react.default.createElement(_ShareIcon.ShareIcon, {
263
357
  __self: void 0,
264
358
  __source: {
265
359
  fileName: _jsxFileName,
266
- lineNumber: 237,
360
+ lineNumber: 308,
267
361
  columnNumber: 41
268
362
  }
269
363
  }), /*#__PURE__*/_react.default.createElement("span", {
@@ -271,7 +365,7 @@ const UserQuery = ({
271
365
  __self: void 0,
272
366
  __source: {
273
367
  fileName: _jsxFileName,
274
- lineNumber: 238,
368
+ lineNumber: 309,
275
369
  columnNumber: 13
276
370
  }
277
371
  }, isLoading ? 'Sharing…' : isCopied ? copiedLabel : 'Share')), isCopied && /*#__PURE__*/_react.default.createElement("div", {
@@ -279,14 +373,14 @@ const UserQuery = ({
279
373
  __self: void 0,
280
374
  __source: {
281
375
  fileName: _jsxFileName,
282
- lineNumber: 244,
376
+ lineNumber: 315,
283
377
  columnNumber: 13
284
378
  }
285
379
  }, /*#__PURE__*/_react.default.createElement(_CheckIcon.CheckIcon, {
286
380
  __self: void 0,
287
381
  __source: {
288
382
  fileName: _jsxFileName,
289
- lineNumber: 245,
383
+ lineNumber: 316,
290
384
  columnNumber: 15
291
385
  }
292
386
  }), copiedLabel)), onNewConversation && /*#__PURE__*/_react.default.createElement("button", {
@@ -296,14 +390,14 @@ const UserQuery = ({
296
390
  __self: void 0,
297
391
  __source: {
298
392
  fileName: _jsxFileName,
299
- lineNumber: 251,
393
+ lineNumber: 322,
300
394
  columnNumber: 11
301
395
  }
302
396
  }, /*#__PURE__*/_react.default.createElement(_PlusIcon.PlusIcon, {
303
397
  __self: void 0,
304
398
  __source: {
305
399
  fileName: _jsxFileName,
306
- lineNumber: 256,
400
+ lineNumber: 327,
307
401
  columnNumber: 13
308
402
  }
309
403
  }), /*#__PURE__*/_react.default.createElement("span", {
@@ -311,7 +405,7 @@ const UserQuery = ({
311
405
  __self: void 0,
312
406
  __source: {
313
407
  fileName: _jsxFileName,
314
- lineNumber: 257,
408
+ lineNumber: 328,
315
409
  columnNumber: 13
316
410
  }
317
411
  }, newConversationLabel)), onToggleCommentMode && /*#__PURE__*/_react.default.createElement("button", {
@@ -324,14 +418,14 @@ const UserQuery = ({
324
418
  __self: void 0,
325
419
  __source: {
326
420
  fileName: _jsxFileName,
327
- lineNumber: 261,
421
+ lineNumber: 332,
328
422
  columnNumber: 11
329
423
  }
330
424
  }, /*#__PURE__*/_react.default.createElement(_CommentIcon.CommentIcon, {
331
425
  __self: void 0,
332
426
  __source: {
333
427
  fileName: _jsxFileName,
334
- lineNumber: 273,
428
+ lineNumber: 344,
335
429
  columnNumber: 13
336
430
  }
337
431
  }), commentCount > 0 && /*#__PURE__*/_react.default.createElement("span", {
@@ -339,7 +433,7 @@ const UserQuery = ({
339
433
  __self: void 0,
340
434
  __source: {
341
435
  fileName: _jsxFileName,
342
- lineNumber: 275,
436
+ lineNumber: 346,
343
437
  columnNumber: 15
344
438
  }
345
439
  }, commentCount))));
@@ -1 +1 @@
1
- {"version":3,"names":["_react","_interopRequireWildcard","require","_ShareIcon","_CheckIcon","_PlusIcon","_UndoIcon","_RedoIcon","_CommentIcon","_navigationStack","_jsxFileName","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","DEFAULT_LOADING_MESSAGES","headerClassName","UserQuery","query","onNewConversation","onNavigateToTriggerId","predecessorTriggerId","currentTriggerId","onShare","onToggleCommentMode","commentMode","commentCount","loading","newConversationLabel","copiedLabel","copiedDurationMs","forwardStack","useMemo","getForwardStack","canGoForward","length","canGoBack","hasNavigation","handleBack","useCallback","pushToForwardStack","handleForward","nextTid","popFromForwardStack","handleNewConversation","clearForwardStack","shareState","setShareState","useState","handleShare","urlToCopy","window","location","href","err","console","warn","navigator","clipboard","writeText","catch","setTimeout","cyclingMessages","messages","cycledMessage","setCycledMessage","useEffect","progressMessage","index","interval","setInterval","clearInterval","isCopied","isLoading","progressText","createElement","className","role","__self","__source","fileName","lineNumber","columnNumber","title","pendingQuery","type","onClick","disabled","UndoIcon","RedoIcon","CheckIcon","ShareIcon","PlusIcon","CommentIcon","exports"],"sources":["../../../../src/components/ui/UserQuery.tsx"],"sourcesContent":["import React, { FC, useCallback, useEffect, useMemo, useState } from 'react';\nimport { ShareIcon } from './icons/ShareIcon';\nimport { CheckIcon } from './icons/CheckIcon';\nimport { PlusIcon } from './icons/PlusIcon';\nimport { UndoIcon } from './icons/UndoIcon';\nimport { RedoIcon } from './icons/RedoIcon';\nimport { CommentIcon } from './icons/CommentIcon';\nimport {\n getForwardStack,\n pushToForwardStack,\n popFromForwardStack,\n clearForwardStack,\n} from '../../utils/navigationStack';\n\ntype ShareState = 'idle' | 'loading' | 'copied';\n\nconst DEFAULT_LOADING_MESSAGES = [\n 'Thinking…',\n 'Recognizing intent…',\n 'Connecting the dots…',\n 'Synthesizing insights…',\n 'Formulating a response…',\n];\n\nconst headerClassName =\n 'web5-user-query sticky top-0 z-10 flex items-center justify-between bg-white/60 backdrop-blur-sm pl-5 pr-[10px] py-[7px] sm:px-[30px] sm:py-[17px]';\n\nexport interface UserQueryLoadingState {\n pendingQuery: string;\n /** Static progress message. If omitted, falls back to cycling through `messages`. */\n progressMessage?: string;\n /** Messages cycled while loading when `progressMessage` is not set. */\n messages?: string[];\n}\n\nexport interface UserQueryProps {\n query: string;\n onNewConversation?: () => void;\n onNavigateToTriggerId?: (triggerId: string) => void;\n predecessorTriggerId?: string;\n currentTriggerId?: string;\n onShare?: (triggerId: string) => Promise<string>;\n /** Optional comment-mode toggle. When provided, render the chat-bubble\n * toggle button next to Share. The button reflects `commentMode` via\n * `is-on` styling and `aria-pressed`. */\n onToggleCommentMode?: () => void;\n commentMode?: boolean;\n /** Total number of comments on this response — shown as a badge next to the\n * toggle when > 0. */\n commentCount?: number;\n loading?: UserQueryLoadingState;\n /** Label for the \"new conversation\" action. Defaults to \"New conversation\". */\n newConversationLabel?: string;\n /** Label shown after the share link is copied. Defaults to \"Link Copied\". */\n copiedLabel?: string;\n /** How long the copied state stays visible, in ms. Defaults to 2000. */\n copiedDurationMs?: number;\n}\n\nexport const UserQuery: FC<UserQueryProps> = ({\n query,\n onNewConversation,\n onNavigateToTriggerId,\n predecessorTriggerId,\n currentTriggerId,\n onShare,\n onToggleCommentMode,\n commentMode = false,\n commentCount = 0,\n loading,\n newConversationLabel = 'New conversation',\n copiedLabel = 'Link Copied',\n copiedDurationMs = 2000,\n}) => {\n const forwardStack = useMemo(() => getForwardStack(), [currentTriggerId]);\n const canGoForward = forwardStack.length > 0;\n const canGoBack = !!predecessorTriggerId;\n const hasNavigation = canGoBack || canGoForward;\n\n const handleBack = useCallback(() => {\n if (!predecessorTriggerId || !currentTriggerId || !onNavigateToTriggerId) {\n return;\n }\n pushToForwardStack(currentTriggerId);\n onNavigateToTriggerId(predecessorTriggerId);\n }, [predecessorTriggerId, currentTriggerId, onNavigateToTriggerId]);\n\n const handleForward = useCallback(() => {\n if (!onNavigateToTriggerId) {\n return;\n }\n const nextTid = popFromForwardStack();\n if (!nextTid) {\n return;\n }\n onNavigateToTriggerId(nextTid);\n }, [onNavigateToTriggerId]);\n\n const handleNewConversation = useCallback(() => {\n clearForwardStack();\n onNewConversation?.();\n }, [onNewConversation]);\n\n const [shareState, setShareState] = useState<ShareState>('idle');\n\n const handleShare = useCallback(async () => {\n if (shareState !== 'idle') {\n return;\n }\n setShareState('loading');\n let urlToCopy = window.location.href;\n try {\n if (onShare && currentTriggerId) {\n urlToCopy = await onShare(currentTriggerId);\n }\n } catch (err) {\n console.warn('[share] failed, falling back to current URL:', err);\n }\n navigator.clipboard\n .writeText(urlToCopy)\n .catch((err) => console.warn('[share] clipboard write failed:', err));\n setShareState('copied');\n setTimeout(() => setShareState('idle'), copiedDurationMs);\n }, [shareState, onShare, currentTriggerId, copiedDurationMs]);\n\n const cyclingMessages = useMemo(\n () =>\n loading?.messages && loading.messages.length > 0\n ? loading.messages\n : DEFAULT_LOADING_MESSAGES,\n [loading?.messages],\n );\n const [cycledMessage, setCycledMessage] = useState(cyclingMessages[0]);\n\n useEffect(() => {\n if (!loading || loading.progressMessage) {\n return;\n }\n setCycledMessage(cyclingMessages[0]);\n if (cyclingMessages.length <= 1) {\n return;\n }\n let index = 0;\n const interval = setInterval(() => {\n index = (index + 1) % cyclingMessages.length;\n setCycledMessage(cyclingMessages[index]);\n }, 4000);\n return () => clearInterval(interval);\n }, [loading, cyclingMessages]);\n\n if (!query && !loading) {\n return null;\n }\n\n const isCopied = shareState === 'copied';\n const isLoading = shareState === 'loading';\n\n if (loading) {\n const progressText = loading.progressMessage ?? cycledMessage;\n return (\n <div\n className={headerClassName}\n role=\"status\"\n aria-busy=\"true\"\n aria-live=\"polite\"\n >\n <p\n className=\"text-[14px] leading-5 text-text-body truncate min-w-0 max-w-[700px] flex-1\"\n title={`Asking: ${loading.pendingQuery}`}\n >\n <span className=\"text-text-body/70\">Asking: </span>\n {loading.pendingQuery}\n </p>\n {progressText && (\n <div className=\"hidden sm:flex items-center gap-2 ml-[10px] shrink-0 min-w-0\">\n <div\n className=\"w-4 h-4 shrink-0 animate-spin inline-block border-[2px] border-current border-t-transparent text-blue-600 dark:text-blue-500 rounded-full\"\n aria-hidden=\"true\"\n />\n <p className=\"text-[13px] leading-5 text-text-body/70 truncate max-w-[240px]\">\n {progressText}\n </p>\n </div>\n )}\n </div>\n );\n }\n\n return (\n <div className={headerClassName}>\n <div className=\"flex items-center gap-[30px] flex-1 min-w-0\">\n <p\n className=\"web5-user-query__title text-[14px] leading-5 text-text-body truncate min-w-0 max-w-[700px]\"\n title={query}\n >\n {query}\n </p>\n {hasNavigation && (\n <div className=\"flex items-center gap-[9px]\">\n <button\n type=\"button\"\n onClick={handleBack}\n disabled={!canGoBack}\n title=\"Go to previous conversation\"\n aria-label=\"Go to previous conversation\"\n className=\"w-6 h-6 flex items-center justify-center text-text-body hover:text-black transition-colors bg-transparent border-0 cursor-pointer disabled:opacity-30 disabled:cursor-default\"\n >\n <UndoIcon />\n </button>\n <button\n type=\"button\"\n onClick={handleForward}\n disabled={!canGoForward}\n title=\"Go to next conversation\"\n aria-label=\"Go to next conversation\"\n className=\"w-6 h-6 flex items-center justify-center text-text-body hover:text-black transition-colors bg-transparent border-0 cursor-pointer disabled:opacity-30 disabled:cursor-default\"\n >\n <RedoIcon />\n </button>\n </div>\n )}\n </div>\n <div className=\"flex items-center gap-[10px] ml-[10px] sm:ml-0 shrink-0\">\n {/* Share button — wraps button + mobile tooltip in a relative container */}\n <div className=\"relative\">\n <button\n type=\"button\"\n onClick={handleShare}\n disabled={isLoading || isCopied}\n className={`web5-user-query__share flex items-center gap-2 p-[6px] sm:px-[13px] sm:py-[5px] rounded-[30px] text-[13px] leading-5 border-0 cursor-pointer transition-colors disabled:cursor-default\n ${\n isCopied\n ? 'is-copied bg-[#2b2b2b] text-white'\n : 'text-text-body bg-white hover:bg-gray-50'\n }`}\n >\n {isCopied ? <CheckIcon /> : <ShareIcon />}\n <span className=\"hidden sm:inline\">\n {isLoading ? 'Sharing…' : isCopied ? copiedLabel : 'Share'}\n </span>\n </button>\n {/* Mobile-only tooltip: drops below the button when link is copied */}\n {isCopied && (\n <div className=\"web5-user-query__copied-toast sm:hidden absolute top-full right-0 mt-1 flex items-center gap-2 bg-[#2b2b2b] text-white text-[12px] leading-none px-3 py-2 rounded-[8px] whitespace-nowrap\">\n <CheckIcon />\n {copiedLabel}\n </div>\n )}\n </div>\n {onNewConversation && (\n <button\n type=\"button\"\n onClick={handleNewConversation}\n className=\"web5-user-query__new-conversation flex items-center gap-2 p-[6px] sm:px-[13px] sm:py-[5px] rounded-[30px] text-[13px] leading-5 text-text-body bg-white border-0 cursor-pointer hover:bg-gray-50 transition-colors\"\n >\n <PlusIcon />\n <span className=\"hidden sm:inline\">{newConversationLabel}</span>\n </button>\n )}\n {onToggleCommentMode && (\n <button\n type=\"button\"\n onClick={onToggleCommentMode}\n aria-pressed={commentMode}\n title=\"Add a comment\"\n aria-label=\"Add a comment\"\n className={`relative flex items-center gap-2 p-[6px] sm:px-[13px] sm:py-[5px] rounded-[30px] text-[13px] leading-5 border-0 cursor-pointer transition-colors ${\n commentMode\n ? 'bg-[#2b2b2b] text-white'\n : 'text-text-body bg-white hover:bg-gray-50'\n }`}\n >\n <CommentIcon />\n {commentCount > 0 && (\n <span\n className={`absolute -top-1 -right-1 min-w-[18px] h-[18px] px-1 rounded-full text-[10px] leading-[18px] text-center font-semibold ${\n commentMode ? 'bg-white text-[#2b2b2b]' : 'bg-[#2b2b2b] text-white'\n }`}\n >\n {commentCount}\n </span>\n )}\n </button>\n )}\n </div>\n </div>\n );\n};\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_react","_interopRequireWildcard","require","_ShareIcon","_CheckIcon","_PlusIcon","_UndoIcon","_RedoIcon","_CommentIcon","_navigationStack","_jsxFileName","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","DEFAULT_LOADING_MESSAGES","headerClassName","UserQuery","query","onNewConversation","onNavigateToTriggerId","predecessorTriggerId","currentTriggerId","onShare","onToggleCommentMode","commentMode","commentCount","loading","newConversationLabel","copiedLabel","copiedDurationMs","productBackContext","onBackToProduct","forwardStack","useMemo","getForwardStack","canGoForward","length","canGoBack","hasNavigation","handleBack","useCallback","pushToForwardStack","handleForward","nextTid","popFromForwardStack","handleNewConversation","clearForwardStack","shareState","setShareState","useState","productImageError","setProductImageError","useEffect","imageUrl","handleShare","urlToCopy","window","location","href","err","console","warn","navigator","clipboard","writeText","catch","setTimeout","cyclingMessages","messages","cycledMessage","setCycledMessage","progressMessage","index","interval","setInterval","clearInterval","isCopied","isLoading","productBadge","title","backUrl","label","canNavigateBack","content","createElement","Fragment","UndoIcon","className","__self","__source","fileName","lineNumber","columnNumber","src","alt","onError","type","onClick","progressText","role","pendingQuery","disabled","RedoIcon","CheckIcon","ShareIcon","PlusIcon","CommentIcon","exports"],"sources":["../../../../src/components/ui/UserQuery.tsx"],"sourcesContent":["import React, { FC, useCallback, useEffect, useMemo, useState } from 'react';\nimport { ShareIcon } from './icons/ShareIcon';\nimport { CheckIcon } from './icons/CheckIcon';\nimport { PlusIcon } from './icons/PlusIcon';\nimport { UndoIcon } from './icons/UndoIcon';\nimport { RedoIcon } from './icons/RedoIcon';\nimport { CommentIcon } from './icons/CommentIcon';\nimport {\n getForwardStack,\n pushToForwardStack,\n popFromForwardStack,\n clearForwardStack,\n} from '../../utils/navigationStack';\n\ntype ShareState = 'idle' | 'loading' | 'copied';\n\nconst DEFAULT_LOADING_MESSAGES = [\n 'Thinking…',\n 'Recognizing intent…',\n 'Connecting the dots…',\n 'Synthesizing insights…',\n 'Formulating a response…',\n];\n\nconst headerClassName =\n 'web5-user-query sticky top-0 z-10 flex items-center justify-between bg-white/60 backdrop-blur-sm pl-5 pr-[10px] py-[7px] sm:px-[30px] sm:py-[17px]';\n\nexport interface UserQueryLoadingState {\n pendingQuery: string;\n /** Static progress message. If omitted, falls back to cycling through `messages`. */\n progressMessage?: string;\n /** Messages cycled while loading when `progressMessage` is not set. */\n messages?: string[];\n}\n\n/**\n * Product the visitor was redirected from (DL #114). Rendered as a back badge\n * above the query: back arrow + thumbnail + product name. All fields are\n * resolved and validated app-side (allowed-domain `backUrl`, `https:`\n * `imageUrl`) before reaching this presentational component.\n */\nexport interface ProductBackContext {\n /** Product display name. Required — without it the badge does not render. */\n title: string;\n /** Validated product thumbnail URL. Omitted/failed to load → arrow + title only. */\n imageUrl?: string;\n /** Validated product-page URL to return to. Omitted → badge is non-clickable. */\n backUrl?: string;\n /** Accessible label override. Defaults to `Back to ${title}`. */\n label?: string;\n}\n\nexport interface UserQueryProps {\n query: string;\n onNewConversation?: () => void;\n onNavigateToTriggerId?: (triggerId: string) => void;\n predecessorTriggerId?: string;\n currentTriggerId?: string;\n onShare?: (triggerId: string) => Promise<string>;\n /** Optional comment-mode toggle. When provided, render the chat-bubble\n * toggle button next to Share. The button reflects `commentMode` via\n * `is-on` styling and `aria-pressed`. */\n onToggleCommentMode?: () => void;\n commentMode?: boolean;\n /** Total number of comments on this response — shown as a badge next to the\n * toggle when > 0. */\n commentCount?: number;\n loading?: UserQueryLoadingState;\n /** Label for the \"new conversation\" action. Defaults to \"New conversation\". */\n newConversationLabel?: string;\n /** Label shown after the share link is copied. Defaults to \"Link Copied\". */\n copiedLabel?: string;\n /** How long the copied state stays visible, in ms. Defaults to 2000. */\n copiedDurationMs?: number;\n /** When set (visitor arrived from a product page), render a back-to-product\n * badge above the query (DL #114). */\n productBackContext?: ProductBackContext;\n /** Invoked with the validated `backUrl` when the badge is activated. */\n onBackToProduct?: (backUrl: string) => void;\n}\n\nexport const UserQuery: FC<UserQueryProps> = ({\n query,\n onNewConversation,\n onNavigateToTriggerId,\n predecessorTriggerId,\n currentTriggerId,\n onShare,\n onToggleCommentMode,\n commentMode = false,\n commentCount = 0,\n loading,\n newConversationLabel = 'New conversation',\n copiedLabel = 'Link Copied',\n copiedDurationMs = 2000,\n productBackContext,\n onBackToProduct,\n}) => {\n const forwardStack = useMemo(() => getForwardStack(), [currentTriggerId]);\n const canGoForward = forwardStack.length > 0;\n const canGoBack = !!predecessorTriggerId;\n const hasNavigation = canGoBack || canGoForward;\n\n const handleBack = useCallback(() => {\n if (!predecessorTriggerId || !currentTriggerId || !onNavigateToTriggerId) {\n return;\n }\n pushToForwardStack(currentTriggerId);\n onNavigateToTriggerId(predecessorTriggerId);\n }, [predecessorTriggerId, currentTriggerId, onNavigateToTriggerId]);\n\n const handleForward = useCallback(() => {\n if (!onNavigateToTriggerId) {\n return;\n }\n const nextTid = popFromForwardStack();\n if (!nextTid) {\n return;\n }\n onNavigateToTriggerId(nextTid);\n }, [onNavigateToTriggerId]);\n\n const handleNewConversation = useCallback(() => {\n clearForwardStack();\n onNewConversation?.();\n }, [onNewConversation]);\n\n const [shareState, setShareState] = useState<ShareState>('idle');\n\n const [productImageError, setProductImageError] = useState(false);\n useEffect(() => {\n setProductImageError(false);\n }, [productBackContext?.imageUrl]);\n\n const handleShare = useCallback(async () => {\n if (shareState !== 'idle') {\n return;\n }\n setShareState('loading');\n let urlToCopy = window.location.href;\n try {\n if (onShare && currentTriggerId) {\n urlToCopy = await onShare(currentTriggerId);\n }\n } catch (err) {\n console.warn('[share] failed, falling back to current URL:', err);\n }\n navigator.clipboard\n .writeText(urlToCopy)\n .catch((err) => console.warn('[share] clipboard write failed:', err));\n setShareState('copied');\n setTimeout(() => setShareState('idle'), copiedDurationMs);\n }, [shareState, onShare, currentTriggerId, copiedDurationMs]);\n\n const cyclingMessages = useMemo(\n () =>\n loading?.messages && loading.messages.length > 0\n ? loading.messages\n : DEFAULT_LOADING_MESSAGES,\n [loading?.messages],\n );\n const [cycledMessage, setCycledMessage] = useState(cyclingMessages[0]);\n\n useEffect(() => {\n if (!loading || loading.progressMessage) {\n return;\n }\n setCycledMessage(cyclingMessages[0]);\n if (cyclingMessages.length <= 1) {\n return;\n }\n let index = 0;\n const interval = setInterval(() => {\n index = (index + 1) % cyclingMessages.length;\n setCycledMessage(cyclingMessages[index]);\n }, 4000);\n return () => clearInterval(interval);\n }, [loading, cyclingMessages]);\n\n if (!query && !loading) {\n return null;\n }\n\n const isCopied = shareState === 'copied';\n const isLoading = shareState === 'loading';\n\n const productBadge = productBackContext\n ? (() => {\n const { title, imageUrl, backUrl, label } = productBackContext;\n const canNavigateBack = !!backUrl && !!onBackToProduct;\n const content = (\n <>\n <UndoIcon className=\"web5-user-query__product-back-icon\" />\n {imageUrl && !productImageError && (\n <span className=\"web5-user-query__product-back-thumb\">\n <img\n src={imageUrl}\n alt=\"\"\n onError={() => setProductImageError(true)}\n />\n </span>\n )}\n <span className=\"web5-user-query__product-back-title\">{title}</span>\n </>\n );\n return canNavigateBack ? (\n <button\n type=\"button\"\n onClick={() => onBackToProduct?.(backUrl!)}\n aria-label={label ?? `Back to ${title}`}\n className=\"web5-user-query__product-back\"\n >\n {content}\n </button>\n ) : (\n <div className=\"web5-user-query__product-back web5-user-query__product-back--static\">\n {content}\n </div>\n );\n })()\n : null;\n\n if (loading) {\n const progressText = loading.progressMessage ?? cycledMessage;\n return (\n <div\n className={headerClassName}\n role=\"status\"\n aria-busy=\"true\"\n aria-live=\"polite\"\n >\n <div className=\"web5-user-query__left flex-1\">\n {productBadge}\n <p\n className=\"text-[14px] leading-5 text-text-body truncate min-w-0 max-w-[700px]\"\n title={`Asking: ${loading.pendingQuery}`}\n >\n <span className=\"text-text-body/70\">Asking: </span>\n {loading.pendingQuery}\n </p>\n </div>\n {progressText && (\n <div className=\"hidden sm:flex items-center gap-2 ml-[10px] shrink-0 min-w-0\">\n <div\n className=\"w-4 h-4 shrink-0 animate-spin inline-block border-[2px] border-current border-t-transparent text-blue-600 dark:text-blue-500 rounded-full\"\n aria-hidden=\"true\"\n />\n <p className=\"text-[13px] leading-5 text-text-body/70 truncate max-w-[240px]\">\n {progressText}\n </p>\n </div>\n )}\n </div>\n );\n }\n\n return (\n <div className={headerClassName}>\n <div className=\"flex items-center gap-[30px] flex-1 min-w-0\">\n <div className=\"web5-user-query__left\">\n {productBadge}\n <p\n className=\"web5-user-query__title text-[14px] leading-5 text-text-body truncate min-w-0 max-w-[700px]\"\n title={query}\n >\n {query}\n </p>\n </div>\n {hasNavigation && (\n <div className=\"flex items-center gap-[9px]\">\n <button\n type=\"button\"\n onClick={handleBack}\n disabled={!canGoBack}\n title=\"Go to previous conversation\"\n aria-label=\"Go to previous conversation\"\n className=\"w-6 h-6 flex items-center justify-center text-text-body hover:text-black transition-colors bg-transparent border-0 cursor-pointer disabled:opacity-30 disabled:cursor-default\"\n >\n <UndoIcon />\n </button>\n <button\n type=\"button\"\n onClick={handleForward}\n disabled={!canGoForward}\n title=\"Go to next conversation\"\n aria-label=\"Go to next conversation\"\n className=\"w-6 h-6 flex items-center justify-center text-text-body hover:text-black transition-colors bg-transparent border-0 cursor-pointer disabled:opacity-30 disabled:cursor-default\"\n >\n <RedoIcon />\n </button>\n </div>\n )}\n </div>\n <div className=\"flex items-center gap-[10px] ml-[10px] sm:ml-0 shrink-0\">\n {/* Share button — wraps button + mobile tooltip in a relative container */}\n <div className=\"relative\">\n <button\n type=\"button\"\n onClick={handleShare}\n disabled={isLoading || isCopied}\n className={`web5-user-query__share flex items-center gap-2 p-[6px] sm:px-[13px] sm:py-[5px] rounded-[30px] text-[13px] leading-5 border-0 cursor-pointer transition-colors disabled:cursor-default\n ${\n isCopied\n ? 'is-copied bg-[#2b2b2b] text-white'\n : 'text-text-body bg-white hover:bg-gray-50'\n }`}\n >\n {isCopied ? <CheckIcon /> : <ShareIcon />}\n <span className=\"hidden sm:inline\">\n {isLoading ? 'Sharing…' : isCopied ? copiedLabel : 'Share'}\n </span>\n </button>\n {/* Mobile-only tooltip: drops below the button when link is copied */}\n {isCopied && (\n <div className=\"web5-user-query__copied-toast sm:hidden absolute top-full right-0 mt-1 flex items-center gap-2 bg-[#2b2b2b] text-white text-[12px] leading-none px-3 py-2 rounded-[8px] whitespace-nowrap\">\n <CheckIcon />\n {copiedLabel}\n </div>\n )}\n </div>\n {onNewConversation && (\n <button\n type=\"button\"\n onClick={handleNewConversation}\n className=\"web5-user-query__new-conversation flex items-center gap-2 p-[6px] sm:px-[13px] sm:py-[5px] rounded-[30px] text-[13px] leading-5 text-text-body bg-white border-0 cursor-pointer hover:bg-gray-50 transition-colors\"\n >\n <PlusIcon />\n <span className=\"hidden sm:inline\">{newConversationLabel}</span>\n </button>\n )}\n {onToggleCommentMode && (\n <button\n type=\"button\"\n onClick={onToggleCommentMode}\n aria-pressed={commentMode}\n title=\"Add a comment\"\n aria-label=\"Add a comment\"\n className={`relative flex items-center gap-2 p-[6px] sm:px-[13px] sm:py-[5px] rounded-[30px] text-[13px] leading-5 border-0 cursor-pointer transition-colors ${\n commentMode\n ? 'bg-[#2b2b2b] text-white'\n : 'text-text-body bg-white hover:bg-gray-50'\n }`}\n >\n <CommentIcon />\n {commentCount > 0 && (\n <span\n className={`absolute -top-1 -right-1 min-w-[18px] h-[18px] px-1 rounded-full text-[10px] leading-[18px] text-center font-semibold ${\n commentMode ? 'bg-white text-[#2b2b2b]' : 'bg-[#2b2b2b] text-white'\n }`}\n >\n {commentCount}\n </span>\n )}\n </button>\n )}\n </div>\n </div>\n );\n};\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.UserQueryProvider = void 0;
5
+ exports.useUserQuery = useUserQuery;
6
+ var _react = _interopRequireWildcard(require("react"));
7
+ var _jsxFileName = "/home/builduser/work/c2b6ca0b3fa984ee/packages/web5-core/dist/cjs/context/UserQueryContext.tsx";
8
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
9
+ const UserQueryContext = /*#__PURE__*/(0, _react.createContext)('');
10
+
11
+ /**
12
+ * Returns the raw user query that produced the current response page.
13
+ * Defaults to an empty string when no provider is present (e.g. storybook,
14
+ * tests), so callers can use it without guarding.
15
+ */
16
+ function useUserQuery() {
17
+ return (0, _react.useContext)(UserQueryContext);
18
+ }
19
+ const UserQueryProvider = ({
20
+ query,
21
+ children
22
+ }) => {
23
+ return /*#__PURE__*/_react.default.createElement(UserQueryContext.Provider, {
24
+ value: query,
25
+ __self: void 0,
26
+ __source: {
27
+ fileName: _jsxFileName,
28
+ lineNumber: 28,
29
+ columnNumber: 5
30
+ }
31
+ }, children);
32
+ };
33
+ exports.UserQueryProvider = UserQueryProvider;
34
+ //# sourceMappingURL=UserQueryContext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_react","_interopRequireWildcard","require","_jsxFileName","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","UserQueryContext","createContext","useUserQuery","useContext","UserQueryProvider","query","children","createElement","Provider","value","__self","__source","fileName","lineNumber","columnNumber","exports"],"sources":["../../../src/context/UserQueryContext.tsx"],"sourcesContent":["import React, {\n createContext,\n useContext,\n type FC,\n type PropsWithChildren,\n} from 'react';\n\nconst UserQueryContext = createContext<string>('');\n\n/**\n * Returns the raw user query that produced the current response page.\n * Defaults to an empty string when no provider is present (e.g. storybook,\n * tests), so callers can use it without guarding.\n */\nexport function useUserQuery(): string {\n return useContext(UserQueryContext);\n}\n\nexport interface UserQueryProviderProps extends PropsWithChildren {\n query: string;\n}\n\nexport const UserQueryProvider: FC<UserQueryProviderProps> = ({\n query,\n children,\n}) => {\n return (\n <UserQueryContext.Provider value={query}>\n {children}\n </UserQueryContext.Provider>\n );\n};\n"],"mappings":";;;;;AAAA,IAAAA,MAAA,GAAAC,uBAAA,CAAAC,OAAA;AAKe,IAAAC,YAAA;AAAA,SAAAF,wBAAAG,CAAA,EAAAC,CAAA,6BAAAC,OAAA,MAAAC,CAAA,OAAAD,OAAA,IAAAE,CAAA,OAAAF,OAAA,YAAAL,uBAAA,YAAAA,CAAAG,CAAA,EAAAC,CAAA,SAAAA,CAAA,IAAAD,CAAA,IAAAA,CAAA,CAAAK,UAAA,SAAAL,CAAA,MAAAM,CAAA,EAAAC,CAAA,EAAAC,CAAA,KAAAC,SAAA,QAAAC,OAAA,EAAAV,CAAA,iBAAAA,CAAA,uBAAAA,CAAA,yBAAAA,CAAA,SAAAQ,CAAA,MAAAF,CAAA,GAAAL,CAAA,GAAAG,CAAA,GAAAD,CAAA,QAAAG,CAAA,CAAAK,GAAA,CAAAX,CAAA,UAAAM,CAAA,CAAAM,GAAA,CAAAZ,CAAA,GAAAM,CAAA,CAAAO,GAAA,CAAAb,CAAA,EAAAQ,CAAA,gBAAAP,CAAA,IAAAD,CAAA,gBAAAC,CAAA,OAAAa,cAAA,CAAAC,IAAA,CAAAf,CAAA,EAAAC,CAAA,OAAAM,CAAA,IAAAD,CAAA,GAAAU,MAAA,CAAAC,cAAA,KAAAD,MAAA,CAAAE,wBAAA,CAAAlB,CAAA,EAAAC,CAAA,OAAAM,CAAA,CAAAK,GAAA,IAAAL,CAAA,CAAAM,GAAA,IAAAP,CAAA,CAAAE,CAAA,EAAAP,CAAA,EAAAM,CAAA,IAAAC,CAAA,CAAAP,CAAA,IAAAD,CAAA,CAAAC,CAAA,WAAAO,CAAA,KAAAR,CAAA,EAAAC,CAAA;AAEf,MAAMkB,gBAAgB,gBAAG,IAAAC,oBAAa,EAAS,EAAE,CAAC;;AAElD;AACA;AACA;AACA;AACA;AACO,SAASC,YAAYA,CAAA,EAAW;EACrC,OAAO,IAAAC,iBAAU,EAACH,gBAAgB,CAAC;AACrC;AAMO,MAAMI,iBAA6C,GAAGA,CAAC;EAC5DC,KAAK;EACLC;AACF,CAAC,KAAK;EACJ,oBACE7B,MAAA,CAAAc,OAAA,CAAAgB,aAAA,CAACP,gBAAgB,CAACQ,QAAQ;IAACC,KAAK,EAAEJ,KAAM;IAAAK,MAAA;IAAAC,QAAA;MAAAC,QAAA,EAAAhC,YAAA;MAAAiC,UAAA;MAAAC,YAAA;IAAA;EAAA,GACrCR,QACwB,CAAC;AAEhC,CAAC;AAACS,OAAA,CAAAX,iBAAA,GAAAA,iBAAA","ignoreList":[]}
@@ -26,6 +26,11 @@ function extractEntityIdFromUrl(entityUrl) {
26
26
  };
27
27
  }
28
28
  function matchesUrl(payloadItem, entityId, config) {
29
+ // Entities resolve by `entityId` (the `<id>` in `web5://entity/<type>/<id>`).
30
+ // Accept a direct `id` match, then fall back to the configured url strategy.
31
+ if (payloadItem.id === entityId) {
32
+ return true;
33
+ }
29
34
  const urlValue = payloadItem[config.urlMatchProperty];
30
35
  if (typeof urlValue !== 'string') {
31
36
  return false;
@@ -47,8 +52,10 @@ function findEntityInPayload(entityType, entityId, payload, entityConfig) {
47
52
  if (!typeConfig) {
48
53
  return null;
49
54
  }
50
- const matchingTypeItems = payload.filter(item => item.type === typeConfig.payloadType);
51
- const matchedItem = matchingTypeItems.find(item => matchesUrl(item, entityId, typeConfig));
55
+
56
+ // Resolution keys off `entityId` (not the type): find the payload item whose
57
+ // id/url matches, using the type's configured url strategy.
58
+ const matchedItem = payload.find(item => matchesUrl(item, entityId, typeConfig));
52
59
  return matchedItem || null;
53
60
  }
54
61
 
@@ -1 +1 @@
1
- {"version":3,"names":["_linkTypes","require","_entityLinkParser","extractEntityIdFromUrl","entityUrl","trimmedUrl","trim","isWeb5EntityUrl","parsed","parseWeb5Url","type","Web5UrlType","ENTITY","entityType","entityId","matchesUrl","payloadItem","config","urlValue","urlMatchProperty","pattern","urlMatchPattern","endsWith","includes","findEntityInPayload","payload","entityConfig","typeConfig","entityTypes","matchingTypeItems","filter","item","payloadType","matchedItem","find","transformToSolutionEntityData","transformToGenericEntityData","formatEntityDate","timestamp","_parts$find","_parts$find2","_parts$find3","date","Date","isNaN","getTime","undefined","formatter","Intl","DateTimeFormat","day","month","timeZone","year","parts","formatToParts","part","value","transformToBlogPostEntityData","_payloadItem$labels","_payloadItem$tags","imageUrl","publishTimestamp","publishDate","published_at","img","imgAlreadyAbsolute","startsWith","imageBaseUrl","url","title","description","excerpt","update_ts","author","authorName","cmsItemId","cms_item_id","usage","tags","labels","length","defaultExtractor","exports"],"sources":["../../../src/entity/defaultExtractor.ts"],"sourcesContent":["import type { SolutionEntityData, BlogEntityData, EntityItemData } from '../component/types';\nimport type {\n ApiPayloadItem,\n EntityConfig,\n EntityTypeConfig,\n} from '../types/entity';\nimport type { EntityExtractor } from './types';\nimport { Web5UrlType, isWeb5EntityUrl } from '../types/link-types';\nimport { parseWeb5Url } from '../utils/entityLinkParser';\n\n/**\n * Extract entity type and ID from a web5://entity/ URL.\n * Delegates to the central `parseWeb5Url` parser.\n */\nfunction extractEntityIdFromUrl(\n entityUrl: string,\n): { entityType: string; entityId: string } | null {\n const trimmedUrl = entityUrl?.trim();\n if (!trimmedUrl || !isWeb5EntityUrl(trimmedUrl)) {\n return null;\n }\n const parsed = parseWeb5Url(trimmedUrl);\n if (parsed?.type !== Web5UrlType.ENTITY || !parsed.entityType || !parsed.entityId) {\n return null;\n }\n return { entityType: parsed.entityType, entityId: parsed.entityId };\n}\n\nfunction matchesUrl(\n payloadItem: ApiPayloadItem,\n entityId: string,\n config: EntityTypeConfig,\n): boolean {\n const urlValue = payloadItem[config.urlMatchProperty as keyof ApiPayloadItem];\n\n if (typeof urlValue !== 'string') {\n return false;\n }\n\n const pattern = config.urlMatchPattern || 'endsWith';\n\n switch (pattern) {\n case 'endsWith':\n return urlValue.endsWith(`/${entityId}`);\n case 'contains':\n return urlValue.includes(entityId);\n case 'equals':\n return urlValue === entityId;\n default:\n return urlValue.endsWith(`/${entityId}`);\n }\n}\n\nfunction findEntityInPayload(\n entityType: string,\n entityId: string,\n payload: ApiPayloadItem[],\n entityConfig: EntityConfig,\n): ApiPayloadItem | null {\n const typeConfig = entityConfig.entityTypes[entityType];\n\n if (!typeConfig) {\n return null;\n }\n\n const matchingTypeItems = payload.filter(\n (item) => item.type === typeConfig.payloadType,\n );\n\n const matchedItem = matchingTypeItems.find((item) =>\n matchesUrl(item, entityId, typeConfig),\n );\n\n return matchedItem || null;\n}\n\n/** @deprecated Use transformToGenericEntityData */\nexport function transformToSolutionEntityData(\n payloadItem: ApiPayloadItem,\n config: EntityTypeConfig,\n): SolutionEntityData {\n return transformToGenericEntityData(payloadItem, config);\n}\n\nfunction formatEntityDate(timestamp: string): string | undefined {\n const date = new Date(timestamp);\n if (isNaN(date.getTime())) {\n return undefined;\n }\n const formatter = new Intl.DateTimeFormat('en-US', {\n day: 'numeric',\n month: 'short',\n timeZone: 'Europe/Kiev',\n year: 'numeric',\n });\n const parts = formatter.formatToParts(date);\n const day = parts.find((part) => part.type === 'day')?.value;\n const month = parts.find((part) => part.type === 'month')?.value;\n const year = parts.find((part) => part.type === 'year')?.value;\n\n if (!day || !month || !year) {\n return undefined;\n }\n\n return `${day} ${month} ${year}`;\n}\n\n/** @deprecated Use transformToGenericEntityData */\nexport function transformToBlogPostEntityData(\n payloadItem: ApiPayloadItem,\n config: EntityTypeConfig,\n): BlogEntityData {\n return transformToGenericEntityData(payloadItem, config);\n}\n\nexport function transformToGenericEntityData(\n payloadItem: ApiPayloadItem,\n config: EntityTypeConfig,\n): EntityItemData {\n let imageUrl: string | undefined;\n const publishTimestamp = payloadItem.publishDate || payloadItem.published_at;\n\n if (payloadItem.img) {\n const imgAlreadyAbsolute = payloadItem.img.startsWith('http');\n imageUrl = config.imageBaseUrl && !imgAlreadyAbsolute\n ? `${config.imageBaseUrl}${payloadItem.img}`\n : payloadItem.img;\n }\n\n return {\n url: payloadItem.url,\n title: payloadItem.title,\n type: payloadItem.type,\n description: payloadItem.description,\n excerpt: payloadItem.excerpt,\n imageUrl,\n date: payloadItem.update_ts\n ? formatEntityDate(payloadItem.update_ts)\n : undefined,\n publishDate: publishTimestamp\n ? formatEntityDate(publishTimestamp)\n : undefined,\n author: payloadItem.author || payloadItem.authorName,\n cmsItemId: payloadItem.cms_item_id,\n usage: payloadItem.usage,\n tags: payloadItem.labels?.length\n ? payloadItem.labels\n : payloadItem.tags?.length\n ? payloadItem.tags\n : undefined,\n };\n}\n\n/**\n * Default entity extractor - config-driven extraction for any client.\n * Uses entityConfig from client JSON to resolve web5://entity/ URLs against API payload.\n */\nexport const defaultExtractor: EntityExtractor = {\n extractEntityIdFromUrl,\n findEntityInPayload,\n};\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_linkTypes","require","_entityLinkParser","extractEntityIdFromUrl","entityUrl","trimmedUrl","trim","isWeb5EntityUrl","parsed","parseWeb5Url","type","Web5UrlType","ENTITY","entityType","entityId","matchesUrl","payloadItem","config","id","urlValue","urlMatchProperty","pattern","urlMatchPattern","endsWith","includes","findEntityInPayload","payload","entityConfig","typeConfig","entityTypes","matchedItem","find","item","transformToSolutionEntityData","transformToGenericEntityData","formatEntityDate","timestamp","_parts$find","_parts$find2","_parts$find3","date","Date","isNaN","getTime","undefined","formatter","Intl","DateTimeFormat","day","month","timeZone","year","parts","formatToParts","part","value","transformToBlogPostEntityData","_payloadItem$labels","_payloadItem$tags","imageUrl","publishTimestamp","publishDate","published_at","img","imgAlreadyAbsolute","startsWith","imageBaseUrl","url","title","description","excerpt","update_ts","author","authorName","cmsItemId","cms_item_id","usage","tags","labels","length","defaultExtractor","exports"],"sources":["../../../src/entity/defaultExtractor.ts"],"sourcesContent":["import type { SolutionEntityData, BlogEntityData, EntityItemData } from '../component/types';\nimport type {\n ApiPayloadItem,\n EntityConfig,\n EntityTypeConfig,\n} from '../types/entity';\nimport type { EntityExtractor } from './types';\nimport { Web5UrlType, isWeb5EntityUrl } from '../types/link-types';\nimport { parseWeb5Url } from '../utils/entityLinkParser';\n\n/**\n * Extract entity type and ID from a web5://entity/ URL.\n * Delegates to the central `parseWeb5Url` parser.\n */\nfunction extractEntityIdFromUrl(\n entityUrl: string,\n): { entityType: string; entityId: string } | null {\n const trimmedUrl = entityUrl?.trim();\n if (!trimmedUrl || !isWeb5EntityUrl(trimmedUrl)) {\n return null;\n }\n const parsed = parseWeb5Url(trimmedUrl);\n if (parsed?.type !== Web5UrlType.ENTITY || !parsed.entityType || !parsed.entityId) {\n return null;\n }\n return { entityType: parsed.entityType, entityId: parsed.entityId };\n}\n\nfunction matchesUrl(\n payloadItem: ApiPayloadItem,\n entityId: string,\n config: EntityTypeConfig,\n): boolean {\n // Entities resolve by `entityId` (the `<id>` in `web5://entity/<type>/<id>`).\n // Accept a direct `id` match, then fall back to the configured url strategy.\n if (payloadItem.id === entityId) {\n return true;\n }\n\n const urlValue = payloadItem[config.urlMatchProperty as keyof ApiPayloadItem];\n\n if (typeof urlValue !== 'string') {\n return false;\n }\n\n const pattern = config.urlMatchPattern || 'endsWith';\n\n switch (pattern) {\n case 'endsWith':\n return urlValue.endsWith(`/${entityId}`);\n case 'contains':\n return urlValue.includes(entityId);\n case 'equals':\n return urlValue === entityId;\n default:\n return urlValue.endsWith(`/${entityId}`);\n }\n}\n\nfunction findEntityInPayload(\n entityType: string,\n entityId: string,\n payload: ApiPayloadItem[],\n entityConfig: EntityConfig,\n): ApiPayloadItem | null {\n const typeConfig = entityConfig.entityTypes[entityType];\n\n if (!typeConfig) {\n return null;\n }\n\n // Resolution keys off `entityId` (not the type): find the payload item whose\n // id/url matches, using the type's configured url strategy.\n const matchedItem = payload.find((item) =>\n matchesUrl(item, entityId, typeConfig),\n );\n\n return matchedItem || null;\n}\n\n/** @deprecated Use transformToGenericEntityData */\nexport function transformToSolutionEntityData(\n payloadItem: ApiPayloadItem,\n config: EntityTypeConfig,\n): SolutionEntityData {\n return transformToGenericEntityData(payloadItem, config);\n}\n\nfunction formatEntityDate(timestamp: string): string | undefined {\n const date = new Date(timestamp);\n if (isNaN(date.getTime())) {\n return undefined;\n }\n const formatter = new Intl.DateTimeFormat('en-US', {\n day: 'numeric',\n month: 'short',\n timeZone: 'Europe/Kiev',\n year: 'numeric',\n });\n const parts = formatter.formatToParts(date);\n const day = parts.find((part) => part.type === 'day')?.value;\n const month = parts.find((part) => part.type === 'month')?.value;\n const year = parts.find((part) => part.type === 'year')?.value;\n\n if (!day || !month || !year) {\n return undefined;\n }\n\n return `${day} ${month} ${year}`;\n}\n\n/** @deprecated Use transformToGenericEntityData */\nexport function transformToBlogPostEntityData(\n payloadItem: ApiPayloadItem,\n config: EntityTypeConfig,\n): BlogEntityData {\n return transformToGenericEntityData(payloadItem, config);\n}\n\nexport function transformToGenericEntityData(\n payloadItem: ApiPayloadItem,\n config: EntityTypeConfig,\n): EntityItemData {\n let imageUrl: string | undefined;\n const publishTimestamp = payloadItem.publishDate || payloadItem.published_at;\n\n if (payloadItem.img) {\n const imgAlreadyAbsolute = payloadItem.img.startsWith('http');\n imageUrl = config.imageBaseUrl && !imgAlreadyAbsolute\n ? `${config.imageBaseUrl}${payloadItem.img}`\n : payloadItem.img;\n }\n\n return {\n url: payloadItem.url,\n title: payloadItem.title,\n type: payloadItem.type,\n description: payloadItem.description,\n excerpt: payloadItem.excerpt,\n imageUrl,\n date: payloadItem.update_ts\n ? formatEntityDate(payloadItem.update_ts)\n : undefined,\n publishDate: publishTimestamp\n ? formatEntityDate(publishTimestamp)\n : undefined,\n author: payloadItem.author || payloadItem.authorName,\n cmsItemId: payloadItem.cms_item_id,\n usage: payloadItem.usage,\n tags: payloadItem.labels?.length\n ? payloadItem.labels\n : payloadItem.tags?.length\n ? payloadItem.tags\n : undefined,\n };\n}\n\n/**\n * Default entity extractor - config-driven extraction for any client.\n * Uses entityConfig from client JSON to resolve web5://entity/ URLs against API payload.\n */\nexport const defaultExtractor: EntityExtractor = {\n extractEntityIdFromUrl,\n findEntityInPayload,\n};\n"],"mappings":"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","ignoreList":[]}