@cloudflare/ai-search-snippet 0.0.24 โ†’ 0.0.26

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudflare/ai-search-snippet",
3
- "version": "0.0.24",
3
+ "version": "0.0.26",
4
4
  "description": "A production-ready, self-contained TypeScript Web Component library for search and chat interfaces with streaming support",
5
5
  "type": "module",
6
6
  "main": "./dist/search-snippet.umd.js",
@@ -32,36 +32,24 @@
32
32
  "license": "MIT",
33
33
  "repository": {
34
34
  "type": "git",
35
- "url": "git+https://github.com/cloudflare/ai-search-snippet.git"
35
+ "url": "git+https://github.com/cloudflare/ai-search-snippet.git",
36
+ "directory": "packages/snippet"
36
37
  },
37
38
  "bugs": {
38
39
  "url": "https://github.com/cloudflare/ai-search-snippet/issues"
39
40
  },
40
41
  "homepage": "https://github.com/cloudflare/ai-search-snippet#readme",
41
- "scripts": {
42
- "dev": "vite ",
43
- "build": "npm run build:app && npm run build:lib",
44
- "build:app": "vite build -c vite.config.ts",
45
- "build:lib": "tsc && vite build -c vite.build.config.ts",
46
- "preview": "vite preview",
47
- "format": "biome format --write ./src ./index.html",
48
- "format:check": "biome format ./src ./index.html",
49
- "lint": "biome lint ./src ./index.html",
50
- "lint:fix": "biome lint --write ./src ./index.html",
51
- "check": "biome check --write ./src ./index.html",
52
- "prepublishOnly": "npm run build:lib"
53
- },
54
42
  "private": false,
55
43
  "devDependencies": {
56
- "@biomejs/biome": "2.3.3",
57
- "@cloudflare/vite-plugin": "^1.15.0",
58
- "typescript": "~5.8.3",
59
44
  "vite": "^7.3.0",
60
45
  "vite-plugin-dts": "^4.5.4",
61
- "vitest": "^3.2.4",
62
- "wrangler": "^4.58.0"
46
+ "vitest": "^3.2.4"
63
47
  },
64
48
  "engines": {
65
49
  "node": ">=16.0.0"
50
+ },
51
+ "scripts": {
52
+ "build": "tsc --noEmit && vite build",
53
+ "typecheck": "tsc --noEmit"
66
54
  }
67
- }
55
+ }
package/README.md DELETED
@@ -1,574 +0,0 @@
1
- # ๐Ÿ” Search Snippet Library
2
-
3
- A production-ready, self-contained TypeScript Web Component library providing both search and chat interfaces with streaming support. Zero dependencies, fully customizable, and framework-agnostic.
4
-
5
- ## โœจ Features
6
-
7
- - **๐ŸŽจ Fully Customizable** - 20+ CSS variables for complete theme control
8
- - **โšก Zero Dependencies** - Self-contained with everything bundled
9
- - **๐Ÿ“ฑ Responsive Design** - Works seamlessly on all devices
10
- - **๐ŸŽญ Framework Agnostic** - Native Web Components work everywhere
11
- - **โ™ฟ Accessible** - WCAG 2.1 AA compliant with ARIA support
12
- - **๐Ÿš€ Streaming Support** - Real-time streaming responses with low latency
13
- - **๐ŸŒ“ Dark Mode** - Automatic theme switching based on system preferences
14
- - **๐Ÿ“ฆ Tiny Bundle** - Optimized for minimal size (< 50KB gzipped)
15
- - **๐Ÿ”’ Secure** - XSS protection with HTML sanitization
16
- - **โš™๏ธ TypeScript** - Full type definitions included
17
-
18
- ## ๐Ÿš€ Quick Start
19
-
20
- > **Note:** This library requires an active AI Search endpoint in your Cloudflare Dashboard. Make sure to enable and configure your AI Search service before using these components.
21
-
22
- ### Installation
23
-
24
- ```bash
25
- npm install @cloudflare/ai-search-snippet
26
- # or
27
- yarn add @cloudflare/ai-search-snippet
28
- ```
29
-
30
- ### Basic Usage
31
-
32
- > **Note:** Replace `<hash>` with your Cloudflare AI Search endpoint hash (you can find it in the Cloudflare Dashboard).
33
-
34
- ```html
35
- <!-- Import the library -->
36
- <script
37
- type="module"
38
- src="https:/<hash>/search.ai.cloudflare.com/search-snippet.es.js"
39
- ></script>
40
-
41
- <!-- Search bar with results -->
42
- <search-bar-snippet
43
- api-url="https:/<hash>/search.ai.cloudflare.com/"
44
- placeholder="Search..."
45
- max-results="10"
46
- >
47
- </search-bar-snippet>
48
-
49
- <!-- Modal search (opens with Cmd/Ctrl+K) -->
50
- <search-modal-snippet
51
- api-url="https:/<hash>/search.ai.cloudflare.com/"
52
- placeholder="Search documentation..."
53
- max-results="10"
54
- >
55
- </search-modal-snippet>
56
-
57
- <!-- Floating chat bubble -->
58
- <chat-bubble-snippet
59
- api-url="https:/<hash>/search.ai.cloudflare.com/"
60
- placeholder="Type a message..."
61
- >
62
- </chat-bubble-snippet>
63
-
64
- <!-- Full-page chat with history -->
65
- <chat-page-snippet
66
- api-url="https:/<hash>/search.ai.cloudflare.com/"
67
- placeholder="Type a message..."
68
- >
69
- </chat-page-snippet>
70
- ```
71
-
72
- ## ๐Ÿ“– API Reference
73
-
74
- ### Components
75
-
76
- The library provides four Web Components:
77
-
78
- | Component | Tag | Description |
79
- | -------------------- | ------------------------ | ------------------------------------- |
80
- | `SearchBarSnippet` | `<search-bar-snippet>` | Search input with results dropdown |
81
- | `SearchModalSnippet` | `<search-modal-snippet>` | Modal search with Cmd/Ctrl+K shortcut |
82
- | `ChatBubbleSnippet` | `<chat-bubble-snippet>` | Floating chat bubble overlay |
83
- | `ChatPageSnippet` | `<chat-page-snippet>` | Full-page chat with session history |
84
-
85
- ### Common Attributes
86
-
87
- These attributes are available on all components:
88
-
89
- | Attribute | Type | Default | Description |
90
- | --------------- | ----------------------------- | ----------------------- | ------------------------------ |
91
- | `api-url` | string | `http://localhost:3000` | API endpoint URL |
92
- | `placeholder` | string | Component-specific | Input placeholder text |
93
- | `theme` | `'light' \| 'dark' \| 'auto'` | `'auto'` | Color scheme |
94
- | `hide-branding` | boolean | `false` | Hide the "Powered by" branding |
95
-
96
- ### Search Components Attributes
97
-
98
- Additional attributes for `<search-bar-snippet>` and `<search-modal-snippet>`:
99
-
100
- | Attribute | Type | Default | Description |
101
- | ------------- | ------- | ------- | ------------------------------------ |
102
- | `max-results` | number | `10` | Maximum search results to display |
103
- | `debounce-ms` | number | `300` | Input debounce delay in milliseconds |
104
- | `show-url` | boolean | `false` | Show URL in search results |
105
-
106
- ### Modal-Specific Attributes
107
-
108
- Additional attributes for `<search-modal-snippet>`:
109
-
110
- | Attribute | Type | Default | Description |
111
- | -------------- | ------- | ------- | ------------------------------------------ |
112
- | `shortcut` | string | `'k'` | Keyboard shortcut key (with Cmd/Ctrl) |
113
- | `use-meta-key` | boolean | `true` | Use meta key (Cmd on Mac, Ctrl on Windows) |
114
-
115
- ### JavaScript API
116
-
117
- #### Search Bar (`<search-bar-snippet>`)
118
-
119
- ```typescript
120
- const searchBar = document.querySelector("search-bar-snippet");
121
-
122
- // Perform a search programmatically
123
- searchBar.search("query");
124
- ```
125
-
126
- #### Search Modal (`<search-modal-snippet>`)
127
-
128
- ```typescript
129
- const modal = document.querySelector("search-modal-snippet");
130
-
131
- modal.open(); // Open the modal
132
- modal.close(); // Close the modal
133
- modal.toggle(); // Toggle open/closed
134
- modal.search("query"); // Open and search
135
- const results = modal.getResults(); // Get current results
136
- const isOpen = modal.isModalOpen(); // Check if open
137
- ```
138
-
139
- #### Chat Bubble (`<chat-bubble-snippet>`)
140
-
141
- ```typescript
142
- const chatBubble = document.querySelector("chat-bubble-snippet");
143
-
144
- await chatBubble.sendMessage("Hello!"); // Send a message
145
- const messages = chatBubble.getMessages(); // Get message history
146
- chatBubble.clearChat(); // Clear chat history
147
- ```
148
-
149
- #### Chat Page (`<chat-page-snippet>`)
150
-
151
- ```typescript
152
- const chatPage = document.querySelector("chat-page-snippet");
153
-
154
- await chatPage.sendMessage("Hello!"); // Send a message
155
- const messages = chatPage.getMessages(); // Get message history
156
- chatPage.clearChat(); // Clear current chat
157
- const sessions = chatPage.getSessions(); // Get all chat sessions
158
- const current = chatPage.getCurrentSession(); // Get current session
159
- ```
160
-
161
- ### Events
162
-
163
- #### Common Events (all components)
164
-
165
- ```javascript
166
- const component = document.querySelector("search-bar-snippet");
167
-
168
- component.addEventListener("ready", () => {
169
- console.log("Component ready");
170
- });
171
-
172
- component.addEventListener("error", (e) => {
173
- console.error("Error:", e.detail.error);
174
- });
175
- ```
176
-
177
- #### Modal-Specific Events
178
-
179
- ```javascript
180
- const modal = document.querySelector("search-modal-snippet");
181
-
182
- modal.addEventListener("open", () => {
183
- console.log("Modal opened");
184
- });
185
-
186
- modal.addEventListener("close", () => {
187
- console.log("Modal closed");
188
- });
189
-
190
- modal.addEventListener("result-select", (e) => {
191
- console.log("Selected result:", e.detail.result);
192
- });
193
- ```
194
-
195
- #### Chat Events
196
-
197
- ```javascript
198
- const chat = document.querySelector("chat-bubble-snippet");
199
-
200
- chat.addEventListener("message", (e) => {
201
- console.log("New message:", e.detail.message);
202
- });
203
- ```
204
-
205
- ## ๐ŸŽจ Customization
206
-
207
- ### CSS Variables
208
-
209
- Customize the appearance using CSS variables:
210
-
211
- ```css
212
- search-bar-snippet,
213
- search-modal-snippet,
214
- chat-bubble-snippet,
215
- chat-page-snippet {
216
- /* ========== COLORS ========== */
217
- /* Primary */
218
- --search-snippet-primary-color: #2563eb;
219
- --search-snippet-primary-hover: #0f51dfff;
220
-
221
- /* Background & Surface */
222
- --search-snippet-background: #ffffff;
223
- --search-snippet-surface: #f8f9fa;
224
- --search-snippet-hover-background: #f1f3f5;
225
-
226
- /* Text */
227
- --search-snippet-text-color: #212529;
228
- --search-snippet-text-secondary: #6c757d;
229
-
230
- /* Border & Focus */
231
- --search-snippet-border-color: #dee2e6;
232
- --search-snippet-focus-ring: #0066cc40;
233
-
234
- /* Status Colors */
235
- --search-snippet-error-color: #dc3545;
236
- --search-snippet-error-background: #f8d7da;
237
- --search-snippet-success-color: #28a745;
238
- --search-snippet-success-background: #d4edda;
239
- --search-snippet-warning-color: #ffc107;
240
- --search-snippet-warning-background: #fff3cd;
241
-
242
- /* Message Colors */
243
- --search-snippet-user-message-bg: #0066cc;
244
- --search-snippet-user-message-text: #ffffff;
245
- --search-snippet-assistant-message-bg: #f1f3f5;
246
- --search-snippet-assistant-message-text: #212529;
247
- --search-snippet-system-message-bg: #fff3cd;
248
- --search-snippet-system-message-text: #856404;
249
-
250
- /* ========== TYPOGRAPHY ========== */
251
- --search-snippet-font-family:
252
- -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Helvetica Neue",
253
- Arial, sans-serif;
254
- --search-snippet-font-family-mono:
255
- "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
256
- --search-snippet-font-size-base: 14px;
257
- --search-snippet-font-size-sm: 12px;
258
- --search-snippet-font-size-lg: 16px;
259
- --search-snippet-font-size-xl: 18px;
260
- --search-snippet-line-height: 1.5;
261
- --search-snippet-font-weight-normal: 400;
262
- --search-snippet-font-weight-medium: 500;
263
- --search-snippet-font-weight-bold: 600;
264
-
265
- /* ========== SPACING ========== */
266
- --search-snippet-spacing-xs: 4px;
267
- --search-snippet-spacing-sm: 8px;
268
- --search-snippet-spacing-md: 12px;
269
- --search-snippet-spacing-lg: 16px;
270
- --search-snippet-spacing-xl: 24px;
271
- --search-snippet-spacing-xxl: 32px;
272
-
273
- /* ========== SIZING ========== */
274
- --search-snippet-width: 100%;
275
- --search-snippet-max-width: 100%;
276
- --search-snippet-min-width: 320px;
277
- --search-snippet-max-height: 600px;
278
- --search-snippet-input-height: 44px;
279
- --search-snippet-button-height: 36px;
280
- --search-snippet-icon-size: 20px;
281
- --search-snippet-icon-margin-left: 6px;
282
-
283
- /* ========== BORDER ========== */
284
- --search-snippet-border-width: 1px;
285
- --search-snippet-border-radius: 18px;
286
-
287
- /* ========== SHADOWS ========== */
288
- --search-snippet-shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
289
- --search-snippet-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
290
- --search-snippet-shadow-md: 0 4px 12px rgba(0, 0, 0, 0.15);
291
- --search-snippet-shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.2);
292
- --search-snippet-shadow-inner: inset 0 2px 4px 0 rgba(0, 0, 0, 0.06);
293
- --search-snippet-result-item-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
294
-
295
- /* ========== ANIMATION ========== */
296
- --search-snippet-transition-fast: 150ms ease;
297
- --search-snippet-transition: 200ms ease;
298
- --search-snippet-transition-slow: 300ms ease;
299
- --search-snippet-animation-duration: 0.2s;
300
-
301
- /* ========== Z-INDEX ========== */
302
- --search-snippet-z-dropdown: 1000;
303
- --search-snippet-z-modal: 1050;
304
- --search-snippet-z-popover: 1060;
305
- --search-snippet-z-tooltip: 1070;
306
-
307
- /* ========== CHAT BUBBLE SPECIFIC ========== */
308
- --chat-bubble-button-shadow: 0 8px 24px rgba(0, 0, 0, 0.2);
309
- --chat-bubble-window-shadow: 0 8px 24px rgba(0, 0, 0, 0.2);
310
- --chat-bubble-button-size: 60px;
311
- --chat-bubble-button-radius: 50%;
312
- --chat-bubble-button-icon-size: 28px;
313
- --chat-bubble-button-icon-color: white;
314
- --chat-bubble-button-bottom: 20px;
315
- --chat-bubble-button-right: 20px;
316
- --chat-bubble-button-z-index: 9999;
317
- --chat-bubble-position: fixed;
318
- }
319
- ```
320
-
321
- ### Theme Examples
322
-
323
- **Dark Theme:**
324
-
325
- ```css
326
- search-bar-snippet {
327
- --search-snippet-primary-color: #4dabf7;
328
- --search-snippet-background: #1a1b1e;
329
- --search-snippet-text-color: #c1c2c5;
330
- --search-snippet-border-color: #373a40;
331
- }
332
- ```
333
-
334
- **Custom Brand:**
335
-
336
- ```css
337
- chat-bubble-snippet {
338
- --search-snippet-primary-color: #667eea;
339
- --search-snippet-primary-hover: #5568d3;
340
- --search-snippet-border-radius: 12px;
341
- --search-snippet-shadow: 0 4px 12px rgba(102, 126, 234, 0.2);
342
- }
343
- ```
344
-
345
- ## ๐Ÿ”ง Advanced Usage
346
-
347
- ### TypeScript
348
-
349
- ```typescript
350
- import {
351
- SearchBarSnippet,
352
- SearchModalSnippet,
353
- ChatBubbleSnippet,
354
- ChatPageSnippet,
355
- type SearchSnippetProps,
356
- } from "@cloudflare/ai-search-snippet";
357
-
358
- // Type-safe usage
359
- const searchBar = document.createElement(
360
- "search-bar-snippet",
361
- ) as SearchBarSnippet;
362
- searchBar.setAttribute("api-url", "https://api.example.com");
363
- searchBar.setAttribute("max-results", "10");
364
-
365
- const chatBubble = document.createElement(
366
- "chat-bubble-snippet",
367
- ) as ChatBubbleSnippet;
368
- chatBubble.setAttribute("api-url", "https://api.example.com");
369
- await chatBubble.sendMessage("Hello, world!");
370
- ```
371
-
372
- ### React Integration
373
-
374
- ```tsx
375
- import { useEffect, useRef } from "react";
376
- import "@cloudflare/ai-search-snippet";
377
-
378
- function ChatWidget() {
379
- const ref = useRef<HTMLElement>(null);
380
-
381
- useEffect(() => {
382
- const chat = ref.current;
383
-
384
- const handleMessage = (e: CustomEvent) => {
385
- console.log("Message:", e.detail);
386
- };
387
-
388
- chat?.addEventListener("message", handleMessage as EventListener);
389
-
390
- return () => {
391
- chat?.removeEventListener("message", handleMessage as EventListener);
392
- };
393
- }, []);
394
-
395
- return (
396
- <chat-bubble-snippet
397
- ref={ref}
398
- api-url="https://api.example.com"
399
- placeholder="Ask a question..."
400
- />
401
- );
402
- }
403
- ```
404
-
405
- ### Vue Integration
406
-
407
- ```vue
408
- <template>
409
- <chat-bubble-snippet
410
- :api-url="apiUrl"
411
- placeholder="Ask a question..."
412
- @message="handleMessage"
413
- @error="handleError"
414
- />
415
- </template>
416
-
417
- <script setup>
418
- import { ref } from "vue";
419
- import "@cloudflare/ai-search-snippet";
420
-
421
- const apiUrl = ref("https://api.example.com");
422
-
423
- const handleMessage = (event) => {
424
- console.log("Message:", event.detail.message);
425
- };
426
-
427
- const handleError = (event) => {
428
- console.error("Error:", event.detail.error);
429
- };
430
- </script>
431
- ```
432
-
433
- ## ๐Ÿ—๏ธ Development
434
-
435
- ### Build from Source
436
-
437
- ```bash
438
- # Install dependencies
439
- npm install
440
-
441
- # Development mode with hot reload
442
- npm run dev
443
-
444
- # Build for production
445
- npm run build
446
-
447
- # Preview production build
448
- npm run preview
449
-
450
- # Lint and format
451
- npm run lint
452
- npm run format
453
- ```
454
-
455
- ### Project Structure
456
-
457
- ```
458
- nlweb-cl-snippet/
459
- โ”œโ”€โ”€ src/
460
- โ”‚ โ”œโ”€โ”€ api/
461
- โ”‚ โ”‚ โ”œโ”€โ”€ index.ts # Base Client abstract class
462
- โ”‚ โ”‚ โ””โ”€โ”€ ai-search.ts # AISearchClient with streaming
463
- โ”‚ โ”œโ”€โ”€ components/
464
- โ”‚ โ”‚ โ”œโ”€โ”€ search-bar-snippet.ts # Search input with results
465
- โ”‚ โ”‚ โ”œโ”€โ”€ search-modal-snippet.ts # Modal search with Cmd/Ctrl+K
466
- โ”‚ โ”‚ โ”œโ”€โ”€ chat-bubble-snippet.ts # Floating chat bubble
467
- โ”‚ โ”‚ โ”œโ”€โ”€ chat-page-snippet.ts # Full-page chat with history
468
- โ”‚ โ”‚ โ””โ”€โ”€ chat-view.ts # Shared chat interface
469
- โ”‚ โ”œโ”€โ”€ styles/
470
- โ”‚ โ”‚ โ”œโ”€โ”€ theme.ts # Base styles & CSS variables
471
- โ”‚ โ”‚ โ”œโ”€โ”€ search.ts # Search-specific styles
472
- โ”‚ โ”‚ โ””โ”€โ”€ chat.ts # Chat-specific styles
473
- โ”‚ โ”œโ”€โ”€ types/
474
- โ”‚ โ”‚ โ””โ”€โ”€ index.ts # TypeScript definitions
475
- โ”‚ โ”œโ”€โ”€ utils/
476
- โ”‚ โ”‚ โ””โ”€โ”€ index.ts # Utility functions
477
- โ”‚ โ””โ”€โ”€ main.ts # Entry point
478
- โ”œโ”€โ”€ dist/ # Build output
479
- โ”œโ”€โ”€ index.html # Demo page
480
- โ”œโ”€โ”€ package.json
481
- โ”œโ”€โ”€ tsconfig.json
482
- โ”œโ”€โ”€ vite.config.ts
483
- โ””โ”€โ”€ README.md
484
- ```
485
-
486
- ## ๐Ÿ“ API Server Requirements
487
-
488
- The component expects the API server to implement the following endpoints:
489
-
490
- ### Search Endpoint
491
-
492
- **POST** `/search`
493
-
494
- Request:
495
-
496
- ```json
497
- {
498
- "query": "search query",
499
- "max_results": 10,
500
- "filters": {}
501
- }
502
- ```
503
-
504
- Response:
505
-
506
- ```json
507
- {
508
- "results": [
509
- {
510
- "id": "result-1",
511
- "title": "Result Title",
512
- "snippet": "Result description...",
513
- "url": "https://example.com",
514
- "metadata": {}
515
- }
516
- ],
517
- "total": 42
518
- }
519
- ```
520
-
521
- ### Chat Endpoint (Streaming)
522
-
523
- **POST** `/ask`
524
-
525
- Request:
526
-
527
- ```json
528
- {
529
- "query": "user message",
530
- "generate_mode": "summarize",
531
- "prev": [
532
- {
533
- "role": "user",
534
- "content": "previous message",
535
- "timestamp": 1234567890
536
- }
537
- ]
538
- }
539
- ```
540
-
541
- Response: Streaming text chunks via ReadableStream
542
-
543
- ## ๐Ÿงช Browser Support
544
-
545
- - Chrome 90+
546
- - Firefox 88+
547
- - Safari 14+
548
- - Edge 90+
549
-
550
- ## ๐Ÿ“„ License
551
-
552
- MIT License - see LICENSE file for details
553
-
554
- ## ๐Ÿค Contributing
555
-
556
- Contributions are welcome! Please feel free to submit a Pull Request.
557
-
558
- ## ๐Ÿ› Bug Reports
559
-
560
- If you discover any bugs, please create an issue on GitHub with:
561
-
562
- - Description of the bug
563
- - Steps to reproduce
564
- - Expected behavior
565
- - Actual behavior
566
- - Browser and version
567
-
568
- ## ๐Ÿ“ฎ Support
569
-
570
- For questions and support, please open a GitHub issue.
571
-
572
- ---
573
-
574
- Built with TypeScript, Web Components, and โค๏ธ