@se-studio/search 1.0.55 → 1.0.58
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/CHANGELOG.md +30 -0
- package/docs/llms.md +114 -0
- package/package.json +6 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
# @se-studio/search
|
|
2
2
|
|
|
3
|
+
## 1.0.58
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Version bump: patch for changed packages
|
|
8
|
+
- Updated dependencies
|
|
9
|
+
- @se-studio/contentful-rest-api@1.0.154
|
|
10
|
+
- @se-studio/core-data-types@1.0.147
|
|
11
|
+
- @se-studio/markdown-renderer@1.0.111
|
|
12
|
+
|
|
13
|
+
## 1.0.57
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- Version bump: patch for changed packages
|
|
18
|
+
- Updated dependencies
|
|
19
|
+
- @se-studio/contentful-rest-api@1.0.153
|
|
20
|
+
- @se-studio/core-data-types@1.0.146
|
|
21
|
+
- @se-studio/markdown-renderer@1.0.110
|
|
22
|
+
|
|
23
|
+
## 1.0.56
|
|
24
|
+
|
|
25
|
+
### Patch Changes
|
|
26
|
+
|
|
27
|
+
- Version bump: patch for changed packages
|
|
28
|
+
- Updated dependencies
|
|
29
|
+
- @se-studio/contentful-rest-api@1.0.152
|
|
30
|
+
- @se-studio/core-data-types@1.0.145
|
|
31
|
+
- @se-studio/markdown-renderer@1.0.109
|
|
32
|
+
|
|
3
33
|
## 1.0.55
|
|
4
34
|
|
|
5
35
|
### Patch Changes
|
package/docs/llms.md
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# @se-studio/search — LLM Reference
|
|
2
|
+
|
|
3
|
+
AI-powered site search using Upstash Search (vector + keyword hybrid). Indexes Contentful pages, articles, persons, and custom types. Provides Next.js API route handlers for search queries and index rebuilds.
|
|
4
|
+
|
|
5
|
+
## Required Environment Variables
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
UPSTASH_SEARCH_REST_URL=https://...
|
|
9
|
+
UPSTASH_SEARCH_REST_TOKEN=...
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Key Types
|
|
13
|
+
|
|
14
|
+
```ts
|
|
15
|
+
import type {
|
|
16
|
+
SearchConfig, // { url, token } — Upstash connection
|
|
17
|
+
SearchIndexConfig, // { connection, publishedIndexName, previewIndexName }
|
|
18
|
+
SearchIndexingConfig, // full config passed to rebuildSearchIndex / webhook handler
|
|
19
|
+
SearchableContentType, // 'page' | 'article' | 'person' | 'articleType' | 'customType'
|
|
20
|
+
ContentTypeIndexConfig, // { type, enabled, includeComponents? }
|
|
21
|
+
SearchDocument, // { id, content: { title, description, body }, metadata }
|
|
22
|
+
SearchDocumentMetadata, // { type, slug, href, tags?, date?, imageUrl?, entryId, ... }
|
|
23
|
+
SearchResult, // SearchDocument + score
|
|
24
|
+
SearchResponse, // { results, query, totalCount }
|
|
25
|
+
SearchOptions, // { query, limit?, filter?, semanticWeight? }
|
|
26
|
+
RebuildResult, // { indexed, skipped, errors }
|
|
27
|
+
} from '@se-studio/search';
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Full Index Rebuild
|
|
31
|
+
|
|
32
|
+
Rebuilds the entire published (or preview) search index from Contentful:
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
import { rebuildSearchIndex } from '@se-studio/search';
|
|
36
|
+
|
|
37
|
+
const result = await rebuildSearchIndex({
|
|
38
|
+
contentfulConfig, // ContentfulConfig from @se-studio/contentful-rest-api
|
|
39
|
+
indexingConfig, // SearchIndexingConfig
|
|
40
|
+
preview: false, // true to rebuild the preview index
|
|
41
|
+
});
|
|
42
|
+
// result: { indexed: number, skipped: number, errors: string[] }
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Incremental Updates via Webhook
|
|
46
|
+
|
|
47
|
+
Creates a handler for Contentful webhooks to update the index on content changes:
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
import { createSearchWebhookHandler } from '@se-studio/search';
|
|
51
|
+
|
|
52
|
+
const handler = createSearchWebhookHandler({
|
|
53
|
+
contentfulConfig,
|
|
54
|
+
indexingConfig,
|
|
55
|
+
secret: process.env.WEBHOOK_SECRET!,
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
// In a Next.js API route:
|
|
59
|
+
export const POST = handler.handle;
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Search API Route Handlers
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
import { createSearchApiHandler, createRebuildApiHandler } from '@se-studio/search';
|
|
66
|
+
|
|
67
|
+
// Search endpoint (GET /api/search?q=...)
|
|
68
|
+
export const GET = createSearchApiHandler({
|
|
69
|
+
searchConfig: { url: process.env.UPSTASH_SEARCH_REST_URL!, token: process.env.UPSTASH_SEARCH_REST_TOKEN! },
|
|
70
|
+
publishedIndexName: 'published',
|
|
71
|
+
previewIndexName: 'preview',
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// Rebuild endpoint (POST /api/search/rebuild)
|
|
75
|
+
export const POST = createRebuildApiHandler({
|
|
76
|
+
contentfulConfig,
|
|
77
|
+
indexingConfig,
|
|
78
|
+
secret: process.env.REBUILD_SECRET!,
|
|
79
|
+
});
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## SearchIndexingConfig Shape
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
const indexingConfig: SearchIndexingConfig = {
|
|
86
|
+
searchIndex: {
|
|
87
|
+
connection: { url: '...', token: '...' },
|
|
88
|
+
publishedIndexName: 'my-site-published',
|
|
89
|
+
previewIndexName: 'my-site-preview',
|
|
90
|
+
},
|
|
91
|
+
contentTypes: [
|
|
92
|
+
{ type: 'page', enabled: true },
|
|
93
|
+
{ type: 'article', enabled: true },
|
|
94
|
+
{ type: 'person', enabled: false },
|
|
95
|
+
],
|
|
96
|
+
indexComponents: true, // extract text from nested components (default: true)
|
|
97
|
+
respectIndexedFlag: true, // skip entries with indexed === false (default: true)
|
|
98
|
+
respectHiddenFlag: true, // skip entries with hidden === true (default: true)
|
|
99
|
+
documentTransformer: (doc, contentData) => {
|
|
100
|
+
// optionally patch doc.metadata before upsert, or return null to drop
|
|
101
|
+
return doc;
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Deduplication
|
|
107
|
+
|
|
108
|
+
Search results can contain multiple chunks from the same entry. Use `deduplicateChunks` to collapse them:
|
|
109
|
+
|
|
110
|
+
```ts
|
|
111
|
+
import { deduplicateChunks } from '@se-studio/search';
|
|
112
|
+
|
|
113
|
+
const deduped = deduplicateChunks(results); // keeps highest-score chunk per entry
|
|
114
|
+
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@se-studio/search",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.58",
|
|
4
4
|
"description": "AI-powered site search with Upstash Search for Next.js marketing sites",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -39,13 +39,14 @@
|
|
|
39
39
|
},
|
|
40
40
|
"files": [
|
|
41
41
|
"dist",
|
|
42
|
-
"*.md"
|
|
42
|
+
"*.md",
|
|
43
|
+
"docs"
|
|
43
44
|
],
|
|
44
45
|
"dependencies": {
|
|
45
46
|
"@upstash/search": "^0.1.7",
|
|
46
|
-
"@se-studio/contentful-rest-api": "1.0.
|
|
47
|
-
"@se-studio/core-data-types": "1.0.
|
|
48
|
-
"@se-studio/markdown-renderer": "1.0.
|
|
47
|
+
"@se-studio/contentful-rest-api": "1.0.154",
|
|
48
|
+
"@se-studio/core-data-types": "1.0.147",
|
|
49
|
+
"@se-studio/markdown-renderer": "1.0.111"
|
|
49
50
|
},
|
|
50
51
|
"peerDependencies": {
|
|
51
52
|
"next": ">=15.5.0",
|