@meeovi/layer-search 1.1.6 → 1.1.7
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/README.md +17 -19
- package/app/composables/bridges/instantsearch.ts +1 -1
- package/app/composables/bridges/searchkit-server.ts +0 -1
- package/app/composables/bridges/searchkit.ts +0 -1
- package/app/composables/bridges/vue.ts +0 -1
- package/app/composables/module.ts +0 -1
- package/app/utils/search/client.ts +18 -20
- package/package.json +1 -1
- /package/app/{plugin → plugins}/searchClient.ts +0 -0
package/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<!-- packages/search/README.md -->
|
|
2
|
-
# @meeovi/search
|
|
2
|
+
# @meeovi/layer-search
|
|
3
3
|
|
|
4
4
|
A modular, provider-agnostic search layer for the Alternate Framework. It provides a unified, typed search API with pluggable adapters (Meilisearch, OpenSearch, mock adapters), lightweight bridges for UI integrations (InstantSearch / Searchkit), a small CLI for indexing/warmup, and event hooks.
|
|
5
5
|
|
|
@@ -16,13 +16,13 @@ A modular, provider-agnostic search layer for the Alternate Framework. It provid
|
|
|
16
16
|
Using npm:
|
|
17
17
|
|
|
18
18
|
```bash
|
|
19
|
-
npm install @meeovi/search
|
|
19
|
+
npm install @meeovi/layer-search
|
|
20
20
|
```
|
|
21
21
|
|
|
22
22
|
Using pnpm:
|
|
23
23
|
|
|
24
24
|
```bash
|
|
25
|
-
pnpm add @meeovi/search
|
|
25
|
+
pnpm add @meeovi/layer-search
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
## Quick Usage
|
|
@@ -31,14 +31,14 @@ Register the module with an Alternate app:
|
|
|
31
31
|
|
|
32
32
|
```ts
|
|
33
33
|
import { createAlternateApp } from '@meeovi/core'
|
|
34
|
-
import searchModule from '@meeovi/search'
|
|
34
|
+
import searchModule from '@meeovi/layer-search'
|
|
35
35
|
|
|
36
36
|
const app = createAlternateApp({
|
|
37
37
|
config: {
|
|
38
38
|
search: {
|
|
39
|
-
defaultProvider: '
|
|
39
|
+
defaultProvider: 'opensearch',
|
|
40
40
|
providers: {
|
|
41
|
-
|
|
41
|
+
opensearch: {
|
|
42
42
|
host: 'http://localhost:7700',
|
|
43
43
|
index: 'products',
|
|
44
44
|
apiKey: 'masterKey'
|
|
@@ -62,14 +62,14 @@ if (searchAdapter) {
|
|
|
62
62
|
## Adapters
|
|
63
63
|
|
|
64
64
|
Adapters are intentionally provider-agnostic and may be supplied by external packages or by your application.
|
|
65
|
-
The core `@meeovi/search` layer does not bundle provider implementations; instead provide an adapter instance at startup
|
|
65
|
+
The core `@meeovi/layer-search` layer does not bundle provider implementations; instead provide an adapter instance at startup
|
|
66
66
|
or register one at runtime so the search manager can be created.
|
|
67
67
|
|
|
68
68
|
Example (external adapter package or custom implementation):
|
|
69
69
|
|
|
70
70
|
```ts
|
|
71
71
|
// import from an external adapter package or your own implementation
|
|
72
|
-
import { createMySearchAdapter } from 'my-search-adapter-package'
|
|
72
|
+
import { createMySearchAdapter } from 'my-search-adapter-package' /* @meeovi/adapter-opensearch */
|
|
73
73
|
|
|
74
74
|
const adapter = createMySearchAdapter({ /* provider config */ })
|
|
75
75
|
```
|
|
@@ -105,7 +105,7 @@ This layer includes bridges that let UI code use Algolia InstantSearch or Search
|
|
|
105
105
|
Example (client):
|
|
106
106
|
|
|
107
107
|
```ts
|
|
108
|
-
import { createInstantSearchBridge } from '@meeovi/search'
|
|
108
|
+
import { createInstantSearchBridge } from '@meeovi/layer-search'
|
|
109
109
|
// `manager` is the `SearchManager` instance available on the app context
|
|
110
110
|
const bridge = createInstantSearchBridge(manager)
|
|
111
111
|
|
|
@@ -120,7 +120,7 @@ Example (server - Express):
|
|
|
120
120
|
|
|
121
121
|
```ts
|
|
122
122
|
import express from 'express'
|
|
123
|
-
import { createSearchkitGraphQLHandler } from '@meeovi/search'
|
|
123
|
+
import { createSearchkitGraphQLHandler } from '@meeovi/layer-search'
|
|
124
124
|
|
|
125
125
|
const app = express()
|
|
126
126
|
app.use(express.json())
|
|
@@ -151,8 +151,8 @@ There are two common ways to register a search adapter so the search layer can u
|
|
|
151
151
|
|
|
152
152
|
```ts
|
|
153
153
|
import { createAlternateApp } from '@meeovi/core'
|
|
154
|
-
import searchModule from '@meeovi/search'
|
|
155
|
-
import { createMySearchAdapter } from 'my-search-adapter-package'
|
|
154
|
+
import searchModule from '@meeovi/layer-search'
|
|
155
|
+
import { createMySearchAdapter } from 'my-search-adapter-package' /* @meeovi/adapter-opensearch */
|
|
156
156
|
|
|
157
157
|
const myProviderModule = {
|
|
158
158
|
id: 'search-provider-my',
|
|
@@ -173,8 +173,8 @@ await app.start()
|
|
|
173
173
|
|
|
174
174
|
```ts
|
|
175
175
|
import { createAlternateApp } from '@meeovi/core'
|
|
176
|
-
import searchModule from '@meeovi/search'
|
|
177
|
-
import { createMySearchAdapter } from 'my-search-adapter-package'
|
|
176
|
+
import searchModule from '@meeovi/layer-search'
|
|
177
|
+
import { createMySearchAdapter } from 'my-search-adapter-package' /* @meeovi/adapter-opensearch */
|
|
178
178
|
|
|
179
179
|
const app = createAlternateApp({ modules: [searchModule] })
|
|
180
180
|
|
|
@@ -199,7 +199,7 @@ Included CLI commands:
|
|
|
199
199
|
|
|
200
200
|
Environment variables supported (example for Meilisearch):
|
|
201
201
|
|
|
202
|
-
- `SEARCH_PROVIDER=
|
|
202
|
+
- `SEARCH_PROVIDER=opensearch`
|
|
203
203
|
- `MEILI_HOST=http://localhost:7700`
|
|
204
204
|
- `MEILI_INDEX=products`
|
|
205
205
|
- `MEILI_KEY=masterKey`
|
|
@@ -238,7 +238,7 @@ Because every layer follows this `KEY` / `NUXT_PUBLIC_KEY` pattern, you can plac
|
|
|
238
238
|
Use the mock adapter in tests to avoid external dependencies:
|
|
239
239
|
|
|
240
240
|
```ts
|
|
241
|
-
import { createMockSearchAdapter } from '@meeovi/search'
|
|
241
|
+
import { createMockSearchAdapter } from '@meeovi/layer-search'
|
|
242
242
|
|
|
243
243
|
const mock = createMockSearchAdapter([{ id: '1', title: 'Test Product' }])
|
|
244
244
|
const results = await mock.search({ term: 'test' })
|
|
@@ -249,13 +249,11 @@ const results = await mock.search({ term: 'test' })
|
|
|
249
249
|
Typical layout:
|
|
250
250
|
|
|
251
251
|
```
|
|
252
|
-
@meeovi/search
|
|
252
|
+
@meeovi/layer-search
|
|
253
253
|
├─ src/
|
|
254
254
|
│ ├─ index.ts
|
|
255
255
|
│ ├─ module.ts
|
|
256
256
|
│ ├─ adapter/
|
|
257
|
-
│ │ ├─ opensearch.ts
|
|
258
|
-
│ │ ├─ meilisearch.ts
|
|
259
257
|
│ │ ├─ mock.ts
|
|
260
258
|
│ │ └─ types.ts
|
|
261
259
|
│ ├─ config/schema.ts
|
|
@@ -3,7 +3,7 @@ import type { MeeoviSearchItem } from '../adapter/types'
|
|
|
3
3
|
|
|
4
4
|
export function createInstantSearchBridge(manager: SearchManager) {
|
|
5
5
|
return {
|
|
6
|
-
searchFunction(helper: any) {
|
|
6
|
+
async searchFunction(helper: any) {
|
|
7
7
|
manager.context.setQuery(helper.state.query || '')
|
|
8
8
|
manager.context.setPage(helper.state.page || 1)
|
|
9
9
|
// map filters if needed from helper.state
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { graphql, buildSchema } from 'graphql'
|
|
2
2
|
import type { SearchManager } from '../core/SearchManager'
|
|
3
|
-
import type { MeeoviSearchItem } from '../adapter/types'
|
|
4
3
|
|
|
5
4
|
const schema = buildSchema(`
|
|
6
5
|
type Hit { id: ID, title: String, description: String, price: Float }
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { ref, computed } from 'vue'
|
|
2
2
|
import { useAlternateContext } from '@meeovi/core'
|
|
3
3
|
import type { SearchManager } from '../core/SearchManager'
|
|
4
|
-
import type { MeeoviSearchItem } from '../adapter/types'
|
|
5
4
|
|
|
6
5
|
export function useSearch() {
|
|
7
6
|
const ctx = useAlternateContext() as any
|
|
@@ -7,7 +7,6 @@ import {
|
|
|
7
7
|
import { validateSearchConfig, type SearchModuleConfig } from './config/schema'
|
|
8
8
|
import type { SearchAdapter } from '@meeovi/core'
|
|
9
9
|
import { SearchManager } from './core/SearchManager'
|
|
10
|
-
import type { MeeoviSearchItem } from './adapter/types'
|
|
11
10
|
|
|
12
11
|
declare module '@meeovi/core' {
|
|
13
12
|
interface AlternateConfig {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Lightweight helper to obtain a search client and index name for InstantSearch
|
|
2
|
-
// This
|
|
3
|
-
|
|
2
|
+
// This version NEVER throws — it returns null when search is not configured.
|
|
3
|
+
|
|
4
4
|
import type { SearchClient } from 'instantsearch.js'
|
|
5
5
|
import { getEnv } from '../env'
|
|
6
6
|
|
|
@@ -16,40 +16,38 @@ function buildHostFromParts(): string | null {
|
|
|
16
16
|
const explicit = getEnv('SEARCHKIT_HOST')
|
|
17
17
|
if (explicit) return explicit
|
|
18
18
|
|
|
19
|
-
// Allow composing host from protocol/hostname/port path
|
|
20
19
|
const protocol = (getEnv('SEARCHKIT_PROTOCOL') || 'http').replace(/:\/\//, '')
|
|
21
20
|
const hostname = getEnv('SEARCHKIT_HOSTNAME')
|
|
22
21
|
const port = getEnv('SEARCHKIT_PORT')
|
|
22
|
+
|
|
23
23
|
if (!hostname) return null
|
|
24
|
+
|
|
24
25
|
return `${protocol}://${hostname}${port ? `:${port}` : ''}`
|
|
25
26
|
}
|
|
26
27
|
|
|
27
|
-
export function getSearchClient(): SearchClient {
|
|
28
|
+
export function getSearchClient(): SearchClient | null {
|
|
28
29
|
const host = buildHostFromParts()
|
|
29
30
|
if (!host) {
|
|
30
|
-
|
|
31
|
+
console.warn('[search] Searchkit host not configured — search disabled')
|
|
32
|
+
return null
|
|
31
33
|
}
|
|
32
34
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
// If not present, let the import fail so the plugin can fallback.
|
|
40
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
41
|
-
const createClient = require('@searchkit/instantsearch-client')
|
|
42
|
-
if (!createClient) {
|
|
43
|
-
throw new Error('@searchkit/instantsearch-client is not installed')
|
|
35
|
+
let createClient: any
|
|
36
|
+
try {
|
|
37
|
+
createClient = require('@searchkit/instantsearch-client')
|
|
38
|
+
} catch {
|
|
39
|
+
console.warn('[search] @searchkit/instantsearch-client not installed — search disabled')
|
|
40
|
+
return null
|
|
44
41
|
}
|
|
45
42
|
|
|
46
|
-
// Create a minimal client. The factory API may vary; adapt to your Searchkit config.
|
|
47
43
|
try {
|
|
48
44
|
const opts: any = { host }
|
|
45
|
+
const apiKey = getEnv('SEARCHKIT_API_KEY')
|
|
49
46
|
if (apiKey) opts.apiKey = apiKey
|
|
47
|
+
|
|
50
48
|
return createClient(opts)
|
|
51
49
|
} catch (e: any) {
|
|
52
|
-
|
|
53
|
-
|
|
50
|
+
console.warn('[search] Failed to create Searchkit client:', e?.message || e)
|
|
51
|
+
return null
|
|
54
52
|
}
|
|
55
|
-
}
|
|
53
|
+
}
|
package/package.json
CHANGED
|
File without changes
|