@cloudflare/ai-search-snippet 0.0.26 → 0.0.27

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/main.d.ts CHANGED
@@ -1,4 +1,7 @@
1
- export declare class AISearchClient extends Client {
1
+ export declare class AISearchClient {
2
+ activeRequests: Map<string, RequestState>;
3
+ baseUrl: string;
4
+ constructor(baseUrl: string);
2
5
  private request;
3
6
  /**
4
7
  * Performs a search query with optional streaming
@@ -159,17 +162,6 @@ declare type ChatTextResponse = {
159
162
 
160
163
  declare type ChatTypes = ChatResult | ChatTextResponse | ChatError;
161
164
 
162
- declare class Client {
163
- activeRequests: Map<string, RequestState>;
164
- baseUrl: string;
165
- constructor(baseUrl: string);
166
- search(_query: string, _options?: SearchOptions): Promise<SearchResult[]>;
167
- searchStream(_query: string, _options?: SearchOptions): AsyncGenerator<SearchResult | SearchError, void, undefined>;
168
- chat(_message: string, _options?: SearchOptions): AsyncGenerator<ChatTypes, void, undefined>;
169
- cancelRequest(_requestId: string): void;
170
- cancelAllRequests(): void;
171
- }
172
-
173
165
  declare interface Message {
174
166
  id: string;
175
167
  role: 'user' | 'assistant' | 'system';
@@ -206,7 +198,7 @@ declare class SearchBarSnippet extends HTMLElement {
206
198
  private handleInputKeydownEnter;
207
199
  private handleInputKeydownEscape;
208
200
  private handleSearchButtonClick;
209
- static get observedAttributes(): readonly ["api-url", "placeholder", "max-results", "debounce-ms", "theme", "hide-branding", "show-url", "hide-thumbnails", "see-more"];
201
+ static get observedAttributes(): readonly ["api-url", "placeholder", "max-results", "debounce-ms", "theme", "hide-branding", "show-url", "show-date", "hide-thumbnails", "see-more"];
210
202
  constructor();
211
203
  connectedCallback(): void;
212
204
  disconnectedCallback(): void;
@@ -262,7 +254,7 @@ export declare class SearchModalSnippet extends HTMLElement {
262
254
  private handleBackdropClick;
263
255
  private savedBodyStyles;
264
256
  private savedHtmlOverflow;
265
- static get observedAttributes(): readonly ["api-url", "placeholder", "max-results", "theme", "shortcut", "use-meta-key", "debounce-ms", "hide-branding", "show-url", "hide-thumbnails", "see-more"];
257
+ static get observedAttributes(): readonly ["api-url", "placeholder", "max-results", "theme", "shortcut", "use-meta-key", "debounce-ms", "hide-branding", "show-url", "show-date", "hide-thumbnails", "see-more"];
266
258
  constructor();
267
259
  connectedCallback(): void;
268
260
  disconnectedCallback(): void;
@@ -334,6 +326,7 @@ export declare interface SearchResult {
334
326
  id: string;
335
327
  title: string;
336
328
  description: string;
329
+ timestamp?: number;
337
330
  url?: string;
338
331
  image?: string;
339
332
  metadata?: Record<string, unknown>;
@@ -358,6 +351,8 @@ export declare interface SearchSnippetProps {
358
351
  hideBranding?: boolean;
359
352
  /** Show URL in search results (default: false) */
360
353
  showUrl?: boolean;
354
+ /** Show date in search results when timestamp is present (default: false) */
355
+ showDate?: boolean;
361
356
  /** Hide thumbnails in search results (default: false) */
362
357
  hideThumbnails?: boolean;
363
358
  /** URL template for "See more" link. The search query is appended URL-encoded. Example: "https://example.com/search?q=" */
@@ -1,6 +1,6 @@
1
- var R = Object.defineProperty;
2
- var H = (o, i, e) => i in o ? R(o, i, { enumerable: !0, configurable: !0, writable: !0, value: e }) : o[i] = e;
3
- var a = (o, i, e) => H(o, typeof i != "symbol" ? i + "" : i, e);
1
+ var H = Object.defineProperty;
2
+ var N = (o, i, e) => i in o ? H(o, i, { enumerable: !0, configurable: !0, writable: !0, value: e }) : o[i] = e;
3
+ var a = (o, i, e) => N(o, typeof i != "symbol" ? i + "" : i, e);
4
4
  const p = [
5
5
  "Searching...",
6
6
  "Digging through results...",
@@ -13,7 +13,7 @@ const p = [
13
13
  "Rummaging through pages...",
14
14
  "Hunting down answers..."
15
15
  ];
16
- function A(o, i) {
16
+ function $(o, i) {
17
17
  let e;
18
18
  return function(...s) {
19
19
  const r = () => {
@@ -29,7 +29,7 @@ function h(o) {
29
29
  function S(o) {
30
30
  return new DOMParser().parseFromString(o, "text/html").documentElement.textContent || "";
31
31
  }
32
- function N(o) {
32
+ function D(o) {
33
33
  const i = new Date(o), t = (/* @__PURE__ */ new Date()).getTime() - i.getTime();
34
34
  if (t < 6e4)
35
35
  return "Just now";
@@ -48,13 +48,19 @@ function N(o) {
48
48
  minute: "2-digit"
49
49
  });
50
50
  }
51
- function E(o = "id") {
51
+ function A(o) {
52
+ return new Date(o).toLocaleDateString(void 0, {
53
+ month: "short",
54
+ day: "numeric"
55
+ });
56
+ }
57
+ function M(o = "id") {
52
58
  return `${o}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
53
59
  }
54
60
  function d(o, i) {
55
61
  return o !== null ? o : i;
56
62
  }
57
- function m(o, i) {
63
+ function g(o, i) {
58
64
  return o === null ? i : o === "true" || o === "";
59
65
  }
60
66
  function f(o, i) {
@@ -62,7 +68,7 @@ function f(o, i) {
62
68
  const e = Number.parseInt(o, 10);
63
69
  return Number.isNaN(e) ? i : e;
64
70
  }
65
- function g(o, i) {
71
+ function m(o, i) {
66
72
  return new CustomEvent(o, {
67
73
  detail: i,
68
74
  bubbles: !0,
@@ -73,7 +79,7 @@ function g(o, i) {
73
79
  function w(o) {
74
80
  if (!o)
75
81
  throw new Error("API URL is required");
76
- return new P(o);
82
+ return new _(o);
77
83
  }
78
84
  class _ {
79
85
  constructor(i) {
@@ -81,23 +87,6 @@ class _ {
81
87
  a(this, "baseUrl");
82
88
  this.baseUrl = i.replace(/\/$/, "");
83
89
  }
84
- search(i, e) {
85
- throw new Error("Not implemented");
86
- }
87
- searchStream(i, e) {
88
- throw new Error("Not implemented");
89
- }
90
- chat(i, e) {
91
- throw new Error("Not implemented");
92
- }
93
- cancelRequest(i) {
94
- throw new Error("Not implemented");
95
- }
96
- cancelAllRequests() {
97
- throw new Error("Not implemented");
98
- }
99
- }
100
- class P extends _ {
101
90
  request(i = {}, e, t) {
102
91
  const s = e === "search" ? "snippet-search" : "snippet-chat-completions";
103
92
  return fetch(`${this.baseUrl}/${e}`, {
@@ -128,7 +117,7 @@ class P extends _ {
128
117
  {
129
118
  query: i,
130
119
  streaming: !1,
131
- maxResults: 30
120
+ maxResults: e.maxResults || 30
132
121
  },
133
122
  "search",
134
123
  r
@@ -145,6 +134,7 @@ class P extends _ {
145
134
  id: l.id,
146
135
  title: S(l.item.metadata?.title),
147
136
  description: l.item.metadata?.description ? S(l.item.metadata?.description) : "",
137
+ timestamp: l.item.timestamp ?? void 0,
148
138
  url: l.item.key,
149
139
  image: l.item.metadata?.image || void 0,
150
140
  metadata: l.item.metadata
@@ -176,8 +166,8 @@ class P extends _ {
176
166
  const { done: u, value: C } = await l.read();
177
167
  if (u)
178
168
  break;
179
- const B = b.decode(C, { stream: !0 });
180
- c += B;
169
+ const R = b.decode(C, { stream: !0 });
170
+ c += R;
181
171
  }
182
172
  yield {
183
173
  type: "result",
@@ -245,10 +235,10 @@ class P extends _ {
245
235
  return `req-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
246
236
  }
247
237
  }
248
- const V = `<svg width="32" height="10" viewBox="0 0 412 186" xmlns="http://www.w3.org/2000/svg" aria-label="Cloudflare" role="img">
238
+ const P = `<svg width="32" height="10" viewBox="0 0 412 186" xmlns="http://www.w3.org/2000/svg" aria-label="Cloudflare" role="img">
249
239
  <path fill="#f38020" d="m280.8395,183.31456c11,-26 -4,-38 -19,-38l-148,-2c-4,0 -4,-6 1,-7l150,-2c17,-1 37,-15 43,-33c0,0 10,-21 9,-24a97,97 0 0 0 -187,-11c-38,-25 -78,9 -69,46c-48,3 -65,46 -60,72c0,1 1,2 3,2l274,0c1,0 3,-1 3,-3z"/>
250
240
  <path fill="#faae40" d="m330.8395,81.31456c-4,0 -6,-1 -7,1l-5,21c-5,16 3,30 20,31l32,2c4,0 4,6 -1,7l-33,1c-36,4 -46,39 -46,39c0,2 0,3 2,3l113,0l3,-2a81,81 0 0 0 -78,-103"/>
251
- </svg>`, j = "https://search.ai.cloudflare.com", y = `Powered by <a href="${j}" target="_blank" rel="noopener noreferrer">Cloudflare AI Search ${V}</a>`, $ = `
241
+ </svg>`, V = "https://workers.cloudflare.com/product/ai-search", x = `Powered by <a href="${V}" target="_blank" rel="noopener noreferrer">Cloudflare AI Search ${P}</a>`, B = `
252
242
  /* Chat container */
253
243
  .chat-container {
254
244
  display: flex;
@@ -565,7 +555,7 @@ const V = `<svg width="32" height="10" viewBox="0 0 412 186" xmlns="http://www.w
565
555
  .chat-message-bubble a:hover {
566
556
  text-decoration: none;
567
557
  }
568
- `, x = `
558
+ `, y = `
569
559
  :host {
570
560
  /* Colors - Light Mode */
571
561
  --search-snippet-primary-color: #2563eb;
@@ -1000,7 +990,7 @@ const V = `<svg width="32" height="10" viewBox="0 0 412 186" xmlns="http://www.w
1000
990
  text-align: center;
1001
991
  }
1002
992
  `;
1003
- function D(o) {
993
+ function j(o) {
1004
994
  let i = o;
1005
995
  i = O(i), i = i.replace(/```([\s\S]*?)```/g, (n, c) => `<pre><code>${c.trim()}</code></pre>`);
1006
996
  const e = i.split(`
@@ -1137,13 +1127,13 @@ class q {
1137
1127
  */
1138
1128
  async sendMessage(i) {
1139
1129
  const e = {
1140
- id: E("msg"),
1130
+ id: M("msg"),
1141
1131
  role: "user",
1142
1132
  content: i,
1143
1133
  timestamp: Date.now()
1144
1134
  };
1145
1135
  this.addMessage(e), this.renderMessages(!0), this.setStreamingState(!0);
1146
- const t = E("msg"), s = {
1136
+ const t = M("msg"), s = {
1147
1137
  id: t,
1148
1138
  role: "assistant",
1149
1139
  content: "",
@@ -1161,10 +1151,10 @@ class q {
1161
1151
  break;
1162
1152
  }
1163
1153
  const c = this.messages.findIndex((l) => l.id === t);
1164
- c !== -1 && (this.messages[c].content = n), this.container.dispatchEvent(g("message", { message: s }));
1154
+ c !== -1 && (this.messages[c].content = n), this.container.dispatchEvent(m("message", { message: s }));
1165
1155
  } catch (r) {
1166
1156
  this.showErrorInMessage(t, r.message), this.container.dispatchEvent(
1167
- g("error", {
1157
+ m("error", {
1168
1158
  error: {
1169
1159
  message: r.message,
1170
1160
  code: "CHAT_ERROR"
@@ -1229,11 +1219,11 @@ class q {
1229
1219
  <div class="chat-message-avatar">${s}</div>
1230
1220
  <div class="chat-message-content">
1231
1221
  <div class="chat-message-bubble">
1232
- ${i.content ? `<div class="chat-message-text">${D(i.content)}</div>` : ""}
1222
+ ${i.content ? `<div class="chat-message-text">${j(i.content)}</div>` : ""}
1233
1223
  ${e ? `<div class="chat-streaming"><span class="chat-streaming-dot"></span><span class="chat-streaming-dot"></span><span class="chat-streaming-dot"></span><span class="loading-text">${p[this.loadingMessageIndex]}</span></div>` : ""}
1234
1224
  </div>
1235
1225
  <div class="chat-message-metadata">
1236
- <span class="chat-message-time">${N(i.timestamp)}</span>
1226
+ <span class="chat-message-time">${D(i.timestamp)}</span>
1237
1227
  </div>
1238
1228
  </div>
1239
1229
  </div>
@@ -1286,7 +1276,7 @@ class q {
1286
1276
  this.clearLoadingMessages(), this.isStreaming && this.client.cancelAllRequests(), this.inputElement && (this.handleInputResize && this.inputElement.removeEventListener("input", this.handleInputResize), this.handleInputKeydown && this.inputElement.removeEventListener("keydown", this.handleInputKeydown)), this.sendButton && this.handleSendClick && this.sendButton.removeEventListener("click", this.handleSendClick), this.handleInputResize = null, this.handleInputKeydown = null, this.handleSendClick = null;
1287
1277
  }
1288
1278
  }
1289
- const M = "chat-bubble-snippet";
1279
+ const E = "chat-bubble-snippet";
1290
1280
  class K extends HTMLElement {
1291
1281
  constructor() {
1292
1282
  super();
@@ -1307,7 +1297,7 @@ class K extends HTMLElement {
1307
1297
  return ["api-url", "placeholder", "theme", "hide-branding"];
1308
1298
  }
1309
1299
  connectedCallback() {
1310
- this.render(), this.initializeClient(), this.dispatchEvent(g("ready", void 0));
1300
+ this.render(), this.initializeClient(), this.dispatchEvent(m("ready", void 0));
1311
1301
  }
1312
1302
  disconnectedCallback() {
1313
1303
  this.cleanup();
@@ -1320,7 +1310,7 @@ class K extends HTMLElement {
1320
1310
  apiUrl: d(this.getAttribute("api-url"), "http://localhost:3000"),
1321
1311
  placeholder: d(this.getAttribute("placeholder"), "Type a message..."),
1322
1312
  theme: d(this.getAttribute("theme"), "auto"),
1323
- hideBranding: m(this.getAttribute("hide-branding"), !1)
1313
+ hideBranding: g(this.getAttribute("hide-branding"), !1)
1324
1314
  };
1325
1315
  }
1326
1316
  initializeClient() {
@@ -1337,8 +1327,8 @@ class K extends HTMLElement {
1337
1327
  }
1338
1328
  render() {
1339
1329
  const e = document.createElement("style");
1340
- e.textContent = `${x}
1341
- ${$}
1330
+ e.textContent = `${y}
1331
+ ${B}
1342
1332
  ${this.getBubbleStyles()}`, this.container = document.createElement("div"), this.container.className = "chat-bubble-widget", this.container.innerHTML = this.getBaseHTML(), this.shadow.innerHTML = "", this.shadow.appendChild(e), this.shadow.appendChild(this.container), this.attachEventListeners();
1343
1333
  }
1344
1334
  getBubbleStyles() {
@@ -1518,7 +1508,7 @@ ${this.getBubbleStyles()}`, this.container = document.createElement("div"), this
1518
1508
  </div>
1519
1509
  </div>
1520
1510
  <div class="chat-content"></div>
1521
- ${this.getProps().hideBranding ? "" : `<div class="powered-by">${y}</div>`}
1511
+ ${this.getProps().hideBranding ? "" : `<div class="powered-by">${x}</div>`}
1522
1512
  </div>
1523
1513
  `;
1524
1514
  }
@@ -1569,7 +1559,7 @@ ${this.getBubbleStyles()}`, this.container = document.createElement("div"), this
1569
1559
  return this.chatView?.getMessages() || [];
1570
1560
  }
1571
1561
  }
1572
- customElements.get(M) || customElements.define(M, K);
1562
+ customElements.get(E) || customElements.define(E, K);
1573
1563
  const L = "chat-page-snippet", I = "chat-page-sessions";
1574
1564
  class U extends HTMLElement {
1575
1565
  constructor() {
@@ -1593,7 +1583,7 @@ class U extends HTMLElement {
1593
1583
  return ["api-url", "placeholder", "theme", "hide-branding"];
1594
1584
  }
1595
1585
  connectedCallback() {
1596
- this.render(), this.initializeClient(), this.setupView(), this.dispatchEvent(g("ready", void 0));
1586
+ this.render(), this.initializeClient(), this.setupView(), this.dispatchEvent(m("ready", void 0));
1597
1587
  }
1598
1588
  disconnectedCallback() {
1599
1589
  this.saveCurrentSession(), this.cleanup();
@@ -1606,7 +1596,7 @@ class U extends HTMLElement {
1606
1596
  apiUrl: d(this.getAttribute("api-url"), "http://localhost:3000"),
1607
1597
  placeholder: d(this.getAttribute("placeholder"), "Type a message..."),
1608
1598
  theme: d(this.getAttribute("theme"), "auto"),
1609
- hideBranding: m(this.getAttribute("hide-branding"), !1)
1599
+ hideBranding: g(this.getAttribute("hide-branding"), !1)
1610
1600
  };
1611
1601
  }
1612
1602
  initializeClient() {
@@ -1623,8 +1613,8 @@ class U extends HTMLElement {
1623
1613
  }
1624
1614
  render() {
1625
1615
  const e = document.createElement("style");
1626
- e.textContent = `${x}
1627
- ${$}
1616
+ e.textContent = `${y}
1617
+ ${B}
1628
1618
  ${this.getPageStyles()}`, this.container = document.createElement("div"), this.container.className = "chat-page-container", this.container.innerHTML = this.getBaseHTML(), this.shadow.innerHTML = "", this.shadow.appendChild(e), this.shadow.appendChild(this.container), this.attachEventListeners();
1629
1619
  }
1630
1620
  getPageStyles() {
@@ -1916,7 +1906,7 @@ ${this.getPageStyles()}`, this.container = document.createElement("div"), this.c
1916
1906
  New Chat
1917
1907
  </button>
1918
1908
  <div class="chat-list"></div>
1919
- ${this.getProps().hideBranding ? "" : `<div class="powered-by">${y}</div>`}
1909
+ ${this.getProps().hideBranding ? "" : `<div class="powered-by">${x}</div>`}
1920
1910
  </div>
1921
1911
  <div class="chat-main">
1922
1912
  <div class="chat-page-header">
@@ -2349,12 +2339,36 @@ a.search-result-item:focus-visible {
2349
2339
  overflow: hidden;
2350
2340
  }
2351
2341
 
2342
+ .search-result-metadata {
2343
+ display: flex;
2344
+ align-items: center;
2345
+ gap: var(--search-snippet-spacing-sm);
2346
+ margin-top: var(--search-snippet-spacing-xs);
2347
+ min-width: 0;
2348
+ }
2349
+
2352
2350
  .search-result-url {
2353
2351
  font-size: var(--search-snippet-font-size-sm);
2354
2352
  color: var(--search-snippet-primary-color);
2355
- margin-top: var(--search-snippet-spacing-xs);
2356
2353
  text-decoration: none;
2357
- display: inline-block;
2354
+ display: block;
2355
+ flex: 1;
2356
+ min-width: 0;
2357
+ overflow: hidden;
2358
+ text-overflow: ellipsis;
2359
+ white-space: nowrap;
2360
+ }
2361
+
2362
+ .search-result-url-empty {
2363
+ visibility: hidden;
2364
+ }
2365
+
2366
+ .search-result-date {
2367
+ font-size: 12px;
2368
+ font-weight: var(--search-snippet-font-weight-medium);
2369
+ color: var(--search-snippet-text-secondary);
2370
+ text-align: right;
2371
+ flex-shrink: 0;
2358
2372
  }
2359
2373
 
2360
2374
  .search-result-url:hover {
@@ -2479,12 +2493,13 @@ class F extends HTMLElement {
2479
2493
  "theme",
2480
2494
  "hide-branding",
2481
2495
  "show-url",
2496
+ "show-date",
2482
2497
  "hide-thumbnails",
2483
2498
  "see-more"
2484
2499
  ];
2485
2500
  }
2486
2501
  connectedCallback() {
2487
- this.initializeClient(), this.render(), this.dispatchEvent(g("ready", void 0));
2502
+ this.initializeClient(), this.render(), this.dispatchEvent(m("ready", void 0));
2488
2503
  }
2489
2504
  disconnectedCallback() {
2490
2505
  this.cleanup();
@@ -2499,9 +2514,10 @@ class F extends HTMLElement {
2499
2514
  maxResults: f(this.getAttribute("max-results"), 10),
2500
2515
  debounceMs: f(this.getAttribute("debounce-ms"), 300),
2501
2516
  theme: d(this.getAttribute("theme"), "auto"),
2502
- hideBranding: m(this.getAttribute("hide-branding"), !1),
2503
- showUrl: m(this.getAttribute("show-url"), !1),
2504
- hideThumbnails: m(this.getAttribute("hide-thumbnails"), !1),
2517
+ hideBranding: g(this.getAttribute("hide-branding"), !1),
2518
+ showUrl: g(this.getAttribute("show-url"), !1),
2519
+ showDate: g(this.getAttribute("show-date"), !1),
2520
+ hideThumbnails: g(this.getAttribute("hide-thumbnails"), !1),
2505
2521
  seeMore: d(this.getAttribute("see-more"), "")
2506
2522
  };
2507
2523
  }
@@ -2519,12 +2535,12 @@ class F extends HTMLElement {
2519
2535
  }
2520
2536
  render() {
2521
2537
  const e = this.getProps(), t = (r) => this.performSearch(r);
2522
- this.debouncedSearch = A(
2538
+ this.debouncedSearch = $(
2523
2539
  t,
2524
2540
  e.debounceMs || 400
2525
2541
  );
2526
2542
  const s = document.createElement("style");
2527
- s.textContent = `${x}
2543
+ s.textContent = `${y}
2528
2544
  ${G}`, this.container = document.createElement("div"), this.container.className = "container", this.container.innerHTML = `
2529
2545
  <div class="search-view">
2530
2546
  <div class="search-input-wrapper">
@@ -2589,7 +2605,7 @@ ${G}`, this.container = document.createElement("div"), this.container.className
2589
2605
  this.showNoResultsState(t);
2590
2606
  return;
2591
2607
  }
2592
- const s = this.getProps(), r = s.hideBranding ? "" : `<div class="powered-by-inline">${y}</div>`, n = s.seeMore ? `<div class="search-footer">
2608
+ const s = this.getProps(), r = s.hideBranding ? "" : `<div class="powered-by-inline">${x}</div>`, n = s.seeMore ? `<div class="search-footer">
2593
2609
  <a href="${h(s.seeMore + encodeURIComponent(t))}" class="search-see-more">
2594
2610
  <span>See more results</span>
2595
2611
  <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14"/><path d="m12 5 7 7-7 7"/></svg>
@@ -2609,14 +2625,17 @@ ${G}`, this.container = document.createElement("div"), this.container.className
2609
2625
  this.resultsContainer.innerHTML = c, this.attachResultHandlers();
2610
2626
  }
2611
2627
  renderResult(e) {
2612
- const t = this.getProps(), s = t.hideThumbnails ? "" : this.renderResultImage(e.image, e.title);
2628
+ const t = this.getProps(), s = t.hideThumbnails ? "" : this.renderResultImage(e.image, e.title), r = e.url ? h(e.url) : "#", n = t.showDate && e.timestamp !== void 0 ? `<div class="search-result-date">${h(A(e.timestamp))}</div>` : "", c = t.showUrl && e.url || n ? `<div class="search-result-metadata">
2629
+ ${t.showUrl && e.url ? `<span class="search-result-url">${h(e.url)}</span>` : '<span class="search-result-url search-result-url-empty"></span>'}
2630
+ ${n}
2631
+ </div>` : "";
2613
2632
  return `
2614
- <a href="${e.url ? h(e.url) : "#"}" class="search-result-item" data-result-id="${h(e.url || "")}">
2633
+ <a href="${r}" class="search-result-item" data-result-id="${h(e.url || "")}">
2615
2634
  ${s}
2616
2635
  <div class="search-result-content">
2617
2636
  <div class="search-result-title">${h(e.title || "")}</div>
2618
2637
  <div class="search-result-snippet">${h(e.description || "")}</div>
2619
- ${t.showUrl && e.url ? `<span class="search-result-url">${h(e.url)}</span>` : ""}
2638
+ ${c}
2620
2639
  </div>
2621
2640
  </a>
2622
2641
  `;
@@ -2978,17 +2997,37 @@ a.modal-result-item:focus-visible {
2978
2997
  overflow: hidden;
2979
2998
  }
2980
2999
 
3000
+ .modal-result-metadata {
3001
+ display: flex;
3002
+ align-items: center;
3003
+ gap: var(--search-snippet-spacing-sm);
3004
+ min-width: 0;
3005
+ }
3006
+
2981
3007
  .modal-result-url {
2982
3008
  font-size: var(--search-snippet-font-size-sm);
2983
3009
  color: var(--search-snippet-primary-color);
2984
3010
  text-decoration: none;
2985
- display: inline-block;
2986
- max-width: 100%;
3011
+ display: block;
3012
+ flex: 1;
3013
+ min-width: 0;
2987
3014
  overflow: hidden;
2988
3015
  text-overflow: ellipsis;
2989
3016
  white-space: nowrap;
2990
3017
  }
2991
3018
 
3019
+ .modal-result-url-empty {
3020
+ visibility: hidden;
3021
+ }
3022
+
3023
+ .modal-result-date {
3024
+ font-size: 12px;
3025
+ font-weight: var(--search-snippet-font-weight-medium);
3026
+ color: var(--search-snippet-text-secondary);
3027
+ text-align: right;
3028
+ flex-shrink: 0;
3029
+ }
3030
+
2992
3031
  .modal-result-url:hover {
2993
3032
  text-decoration: underline;
2994
3033
  }
@@ -3182,12 +3221,13 @@ class W extends HTMLElement {
3182
3221
  "debounce-ms",
3183
3222
  "hide-branding",
3184
3223
  "show-url",
3224
+ "show-date",
3185
3225
  "hide-thumbnails",
3186
3226
  "see-more"
3187
3227
  ];
3188
3228
  }
3189
3229
  connectedCallback() {
3190
- this.initializeClient(), this.render(), this.attachGlobalKeyboardShortcut(), this.dispatchEvent(g("ready", void 0));
3230
+ this.initializeClient(), this.render(), this.attachGlobalKeyboardShortcut(), this.dispatchEvent(m("ready", void 0));
3191
3231
  }
3192
3232
  disconnectedCallback() {
3193
3233
  this.cleanup();
@@ -3204,9 +3244,10 @@ class W extends HTMLElement {
3204
3244
  theme: d(this.getAttribute("theme"), "auto"),
3205
3245
  shortcut: d(this.getAttribute("shortcut"), "k"),
3206
3246
  useMetaKey: this.getAttribute("use-meta-key") !== "false",
3207
- hideBranding: m(this.getAttribute("hide-branding"), !1),
3208
- showUrl: m(this.getAttribute("show-url"), !1),
3209
- hideThumbnails: m(this.getAttribute("hide-thumbnails"), !1),
3247
+ hideBranding: g(this.getAttribute("hide-branding"), !1),
3248
+ showUrl: g(this.getAttribute("show-url"), !1),
3249
+ showDate: g(this.getAttribute("show-date"), !1),
3250
+ hideThumbnails: g(this.getAttribute("hide-thumbnails"), !1),
3210
3251
  seeMore: d(this.getAttribute("see-more"), "")
3211
3252
  };
3212
3253
  }
@@ -3224,14 +3265,14 @@ class W extends HTMLElement {
3224
3265
  }
3225
3266
  render() {
3226
3267
  const e = this.getProps(), t = (c) => this.performSearch(c);
3227
- this.debouncedSearch = A(
3268
+ this.debouncedSearch = $(
3228
3269
  t,
3229
3270
  e.debounceMs || 300
3230
3271
  );
3231
3272
  const s = document.createElement("style");
3232
- s.textContent = `${x}
3273
+ s.textContent = `${y}
3233
3274
  ${Y}`;
3234
- const r = e.hideBranding ? "" : `<div class="powered-by-inline">${y}</div>`, n = document.createElement("div");
3275
+ const r = e.hideBranding ? "" : `<div class="powered-by-inline">${x}</div>`, n = document.createElement("div");
3235
3276
  n.innerHTML = `
3236
3277
  <div class="modal-backdrop" role="presentation"></div>
3237
3278
  <div class="modal-container" role="dialog" aria-modal="true" aria-labelledby="modal-title">
@@ -3325,7 +3366,7 @@ ${Y}`;
3325
3366
  }
3326
3367
  const e = this.results[this.activeIndex];
3327
3368
  this.dispatchEvent(
3328
- g("result-select", {
3369
+ m("result-select", {
3329
3370
  result: e,
3330
3371
  index: this.activeIndex
3331
3372
  })
@@ -3366,10 +3407,13 @@ ${Y}`;
3366
3407
  this.resultsContainer.innerHTML = r + n, this.footerCount && (this.footerCount.textContent = `${e.length} result${e.length === 1 ? "" : "s"}`), this.inputElement && this.inputElement.setAttribute("aria-expanded", "true"), this.attachResultHandlers(), this.updateActiveResult();
3367
3408
  }
3368
3409
  renderResult(e, t) {
3369
- const s = this.getProps(), r = s.hideThumbnails ? "" : this.renderResultImage(e.image, e.title);
3410
+ const s = this.getProps(), r = s.hideThumbnails ? "" : this.renderResultImage(e.image, e.title), n = e.url ? h(e.url) : "#", c = s.showDate && e.timestamp !== void 0 ? `<div class="modal-result-date">${h(A(e.timestamp))}</div>` : "", l = s.showUrl && e.url || c ? `<div class="modal-result-metadata">
3411
+ ${s.showUrl && e.url ? `<span class="modal-result-url">${h(e.url)}</span>` : '<span class="modal-result-url modal-result-url-empty"></span>'}
3412
+ ${c}
3413
+ </div>` : "";
3370
3414
  return `
3371
3415
  <a
3372
- href="${e.url ? h(e.url) : "#"}"
3416
+ href="${n}"
3373
3417
  class="modal-result-item${t === this.activeIndex ? " active" : ""}"
3374
3418
  role="option"
3375
3419
  id="result-${t}"
@@ -3382,7 +3426,7 @@ ${Y}`;
3382
3426
  <div class="modal-result-content">
3383
3427
  <div class="modal-result-title">${h(e.title || "")}</div>
3384
3428
  ${e.description ? `<div class="modal-result-description">${h(e.description)}</div>` : ""}
3385
- ${s.showUrl && e.url ? `<span class="modal-result-url">${h(e.url)}</span>` : ""}
3429
+ ${l}
3386
3430
  </div>
3387
3431
  </a>
3388
3432
  `;
@@ -3509,13 +3553,13 @@ ${Y}`;
3509
3553
  requestAnimationFrame(() => {
3510
3554
  this.inputElement?.focus();
3511
3555
  });
3512
- }), this.lockBodyScroll(), this.dispatchEvent(g("open", void 0)));
3556
+ }), this.lockBodyScroll(), this.dispatchEvent(m("open", void 0)));
3513
3557
  }
3514
3558
  /**
3515
3559
  * Close the search modal
3516
3560
  */
3517
3561
  close() {
3518
- this.isOpen && (this.isOpen = !1, this.backdrop?.classList.remove("open"), this.modal?.classList.remove("open"), this.inputElement && (this.inputElement.value = ""), this.results = [], this.activeIndex = -1, this.showEmptyState(), this.unlockBodyScroll(), this.dispatchEvent(g("close", void 0)));
3562
+ this.isOpen && (this.isOpen = !1, this.backdrop?.classList.remove("open"), this.modal?.classList.remove("open"), this.inputElement && (this.inputElement.value = ""), this.results = [], this.activeIndex = -1, this.showEmptyState(), this.unlockBodyScroll(), this.dispatchEvent(m("close", void 0)));
3519
3563
  }
3520
3564
  /**
3521
3565
  * Toggle the search modal open/closed
@@ -3544,7 +3588,7 @@ ${Y}`;
3544
3588
  }
3545
3589
  customElements.get(T) || customElements.define(T, W);
3546
3590
  export {
3547
- P as AISearchClient,
3591
+ _ as AISearchClient,
3548
3592
  K as ChatBubbleSnippet,
3549
3593
  U as ChatPageSnippet,
3550
3594
  F as SearchBarSnippet,