@rubixstudios/payload-typesense 1.0.0

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 (60) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +182 -0
  3. package/dist/components/HeadlessSearchInput.d.ts +86 -0
  4. package/dist/components/HeadlessSearchInput.d.ts.map +1 -0
  5. package/dist/components/HeadlessSearchInput.js +602 -0
  6. package/dist/components/ThemeProvider.d.ts +10 -0
  7. package/dist/components/ThemeProvider.d.ts.map +1 -0
  8. package/dist/components/ThemeProvider.js +17 -0
  9. package/dist/components/index.d.ts +6 -0
  10. package/dist/components/index.d.ts.map +1 -0
  11. package/dist/components/index.js +3 -0
  12. package/dist/components/themes/hooks.d.ts +52 -0
  13. package/dist/components/themes/hooks.d.ts.map +1 -0
  14. package/dist/components/themes/hooks.js +177 -0
  15. package/dist/components/themes/index.d.ts +5 -0
  16. package/dist/components/themes/index.d.ts.map +1 -0
  17. package/dist/components/themes/index.js +4 -0
  18. package/dist/components/themes/themes.d.ts +6 -0
  19. package/dist/components/themes/themes.d.ts.map +1 -0
  20. package/dist/components/themes/themes.js +156 -0
  21. package/dist/components/themes/types.d.ts +147 -0
  22. package/dist/components/themes/types.d.ts.map +1 -0
  23. package/dist/components/themes/types.js +1 -0
  24. package/dist/components/themes/utils.d.ts +30 -0
  25. package/dist/components/themes/utils.d.ts.map +1 -0
  26. package/dist/components/themes/utils.js +397 -0
  27. package/dist/endpoints/customEndpointHandler.d.ts +3 -0
  28. package/dist/endpoints/customEndpointHandler.d.ts.map +1 -0
  29. package/dist/endpoints/customEndpointHandler.js +5 -0
  30. package/dist/endpoints/health.d.ts +12 -0
  31. package/dist/endpoints/health.d.ts.map +1 -0
  32. package/dist/endpoints/health.js +174 -0
  33. package/dist/endpoints/search.d.ts +13 -0
  34. package/dist/endpoints/search.d.ts.map +1 -0
  35. package/dist/endpoints/search.js +375 -0
  36. package/dist/index.d.ts +39 -0
  37. package/dist/index.d.ts.map +1 -0
  38. package/dist/index.js +148 -0
  39. package/dist/lib/cache.d.ts +41 -0
  40. package/dist/lib/cache.d.ts.map +1 -0
  41. package/dist/lib/cache.js +96 -0
  42. package/dist/lib/config-validation.d.ts +75 -0
  43. package/dist/lib/config-validation.d.ts.map +1 -0
  44. package/dist/lib/config-validation.js +174 -0
  45. package/dist/lib/hooks.d.ts +4 -0
  46. package/dist/lib/hooks.d.ts.map +1 -0
  47. package/dist/lib/hooks.js +54 -0
  48. package/dist/lib/initialization.d.ts +5 -0
  49. package/dist/lib/initialization.d.ts.map +1 -0
  50. package/dist/lib/initialization.js +102 -0
  51. package/dist/lib/schema-mapper.d.ts +14 -0
  52. package/dist/lib/schema-mapper.d.ts.map +1 -0
  53. package/dist/lib/schema-mapper.js +137 -0
  54. package/dist/lib/types.d.ts +183 -0
  55. package/dist/lib/types.d.ts.map +1 -0
  56. package/dist/lib/types.js +2 -0
  57. package/dist/lib/typesense-client.d.ts +5 -0
  58. package/dist/lib/typesense-client.d.ts.map +1 -0
  59. package/dist/lib/typesense-client.js +20 -0
  60. package/package.json +92 -0
package/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Front Tribe (https://fronttribe.com)
4
+ Copyright (c) 2025 Rubix Studios Pty. Ltd. <hello@rubixstudios.com.au>
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,182 @@
1
+ # Typesense Plugin for Payload CMS
2
+
3
+ This plugin is a fork of FrontTribe's Typesense Search Plugin for Payload CMS…
4
+
5
+ A production-ready search plugin that integrates Typesense with Payload CMS, offering fast, typo-tolerant search with real-time synchronization. This fork by Rubix Studios reduces bloat and introduces targeted changes for improved performance, maintainability, and flexibility.
6
+
7
+ ## Installation
8
+
9
+ ```sh
10
+ pnpm add @rubixstudios/typesense
11
+ ```
12
+
13
+ ```typescript
14
+ // payload.config.ts
15
+ import { buildConfig } from 'payload/config'
16
+ import { typesenseSearch } from '@rubixstudios/typesense'
17
+
18
+ export default buildConfig({
19
+ plugins: [
20
+ typesenseSearch({
21
+ typesense: {
22
+ apiKey: 'xyz',
23
+ nodes: [{ host: 'localhost', port: 8108, protocol: 'http' }],
24
+ },
25
+ collections: {
26
+ posts: {
27
+ enabled: true,
28
+ searchFields: ['title', 'content'],
29
+ facetFields: ['category', 'status'],
30
+ displayName: 'Blog Posts',
31
+ icon: '📝',
32
+ },
33
+ },
34
+ }),
35
+ ],
36
+ })
37
+ ```
38
+
39
+ ```tsx
40
+ // 4. Use the search component
41
+ import { HeadlessSearchInput } from '@rubixstudios/typesense'
42
+
43
+ function SearchPage() {
44
+ return (
45
+ <HeadlessSearchInput
46
+ baseUrl="http://localhost:3000"
47
+ theme="modern" // Choose from: modern, dark
48
+ placeholder="Search everything..."
49
+ onResultClick={(result) => {
50
+ console.log('Selected:', result.document)
51
+ }}
52
+ />
53
+ )
54
+ }
55
+
56
+ // Multi-collection search
57
+ function MultiCollectionSearch() {
58
+ return (
59
+ <HeadlessSearchInput
60
+ baseUrl="http://localhost:3000"
61
+ collections={['posts', 'products']}
62
+ placeholder="Search posts & products..."
63
+ onResultClick={(result) => {
64
+ console.log('Selected:', result.document)
65
+ }}
66
+ />
67
+ )
68
+ }
69
+
70
+ // Single collection search
71
+ function PostSearch() {
72
+ return (
73
+ <HeadlessSearchInput
74
+ baseUrl="http://localhost:3000"
75
+ collection="posts"
76
+ placeholder="Search posts..."
77
+ onResultClick={(result) => {
78
+ console.log('Selected:', result.document)
79
+ }}
80
+ />
81
+ )
82
+ }
83
+ ```
84
+
85
+ ## Features
86
+
87
+ - **Performance**: Sub-millisecond response times for search queries
88
+ - **Flexible Search**: Single, multiple, or universal collection search with one component
89
+ - **Modern Interface**: Responsive design implemented with Tailwind CSS
90
+ - **Optimized API**: Automatically routes requests to the most efficient endpoint
91
+ - **Real-Time Sync**: Continuous data sync with Payload CMS
92
+ - **Built-in Caching**: In-memory cache with configurable time-to-live settings
93
+ - **Production Ready**: Robust error handling and performance optimization
94
+ - **Responsive**: Mobile-first architecture ensuring compatibility across devices
95
+
96
+ ## API Endpoints
97
+
98
+ - `GET /api/search` - Universal search across all collections
99
+ - `GET /api/search/{collection}` - Search specific collection
100
+ - `POST /api/search/{collection}` - Advanced search with filters
101
+ - `GET /api/search/{collection}/suggest` - Search suggestions
102
+ - `GET /api/search/collections` - Collection metadata
103
+ - `GET /api/search/health` - Health check
104
+
105
+ ## Components
106
+
107
+ - **HeadlessSearchInput** - Single component supporting all search patterns:
108
+ - **Single Collection**: `collection="posts"` - Direct API calls for optimal performance
109
+ - **Multiple Collections**: `collections={['posts', 'products']}` - Smart filtering with universal search
110
+ - **Universal Search**: No collection props - Search across all collections
111
+ - **Complete UI Control**: Customizable rendering with comprehensive theme system
112
+
113
+ ## Theme System
114
+
115
+ The plugin includes a powerful theme system with 5 pre-built themes and unlimited customization:
116
+
117
+ ### Pre-built Themes
118
+
119
+ ```tsx
120
+ // Modern theme (default) - Clean and professional
121
+ <HeadlessSearchInput theme="modern" />
122
+
123
+ // Minimal theme - Flat design with minimal styling
124
+ <HeadlessSearchInput theme="minimal" />
125
+
126
+ // Elegant theme - Sophisticated with gradients
127
+ <HeadlessSearchInput theme="elegant" />
128
+
129
+ // Dark theme - Perfect for dark mode
130
+ <HeadlessSearchInput theme="dark" />
131
+
132
+ // Colorful theme - Vibrant and modern
133
+ <HeadlessSearchInput theme="colorful" />
134
+ ```
135
+
136
+ ### Custom Themes
137
+
138
+ ```tsx
139
+ const customTheme = {
140
+ theme: 'modern',
141
+ colors: {
142
+ inputBorderFocus: '#10b981',
143
+ inputBackground: '#f0fdf4',
144
+ resultsBackground: '#f0fdf4',
145
+ },
146
+ spacing: {
147
+ inputPadding: '1rem 1.25rem',
148
+ inputBorderRadius: '1.5rem',
149
+ },
150
+ enableAnimations: true,
151
+ enableShadows: true,
152
+ }
153
+
154
+ <HeadlessSearchInput theme={customTheme} />
155
+ ```
156
+
157
+ ### Theme Features
158
+
159
+ - **2 Pre-built Themes**: Modern, Dark
160
+ - **Unlimited Customization**: Override any color, spacing, typography, or animation
161
+ - **Performance Options**: Disable animations/shadows for better performance
162
+ - **Responsive Design**: Automatic mobile optimization
163
+ - **CSS Variables**: Advanced styling with CSS custom properties
164
+ - **TypeScript Support**: Full type safety for all theme configurations
165
+
166
+ ## Contributing
167
+
168
+ 1. Fork the repository
169
+ 2. Create a feature branch
170
+ 3. Make your changes
171
+ 4. Add tests
172
+ 5. Submit a pull request
173
+
174
+ ## License
175
+
176
+ MIT License - see [LICENSE](LICENSE) file for details.
177
+
178
+ ## Acknowledgments
179
+
180
+ - [FrontTribe](https://github.com/FrontTribe/typesense-search)
181
+ - [Typesense](https://typesense.org/)
182
+ - [Payload CMS](https://payloadcms.com/)
@@ -0,0 +1,86 @@
1
+ import React from 'react';
2
+ import type { BaseSearchInputProps, SearchResult } from '../lib/types.js';
3
+ import type { ThemeConfig } from './themes/types.js';
4
+ export interface HeadlessSearchInputProps<T = Record<string, unknown>> extends BaseSearchInputProps<T> {
5
+ /**
6
+ * Collection to search in (for single collection search)
7
+ */
8
+ collection?: string;
9
+ /**
10
+ * Collections to search in (for multi-collection search)
11
+ */
12
+ collections?: string[];
13
+ /**
14
+ * Enable suggestions
15
+ */
16
+ enableSuggestions?: boolean;
17
+ /**
18
+ * Number of results to show per page
19
+ */
20
+ perPage?: number;
21
+ /**
22
+ * Custom render function for error state
23
+ */
24
+ renderError?: (error: string) => React.ReactNode;
25
+ /**
26
+ * Custom input element (for complete control)
27
+ */
28
+ renderInput?: (props: {
29
+ className: string;
30
+ onBlur: (e: React.FocusEvent) => void;
31
+ onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
32
+ onFocus: () => void;
33
+ onKeyDown: (e: React.KeyboardEvent) => void;
34
+ placeholder: string;
35
+ ref: React.RefObject<HTMLInputElement | null>;
36
+ value: string;
37
+ }) => React.ReactNode;
38
+ /**
39
+ * Custom render function for loading state
40
+ */
41
+ renderLoading?: () => React.ReactNode;
42
+ /**
43
+ * Custom render function for no results
44
+ */
45
+ renderNoResults?: (query: string) => React.ReactNode;
46
+ /**
47
+ * Custom render function for results
48
+ */
49
+ renderResult?: (result: SearchResult<T>, index: number) => React.ReactNode;
50
+ /**
51
+ * Custom render function for results header
52
+ */
53
+ renderResultsHeader?: (found: number, searchTime: number) => React.ReactNode;
54
+ /**
55
+ * Custom CSS class for individual result items
56
+ */
57
+ resultItemClassName?: string;
58
+ /**
59
+ * Custom CSS class for the results container
60
+ */
61
+ resultsClassName?: string;
62
+ /**
63
+ * Custom CSS class for results container
64
+ */
65
+ resultsContainerClassName?: string;
66
+ /**
67
+ * Show loading state
68
+ */
69
+ showLoading?: boolean;
70
+ /**
71
+ * Show result count
72
+ */
73
+ showResultCount?: boolean;
74
+ /**
75
+ * Show search time
76
+ */
77
+ showSearchTime?: boolean;
78
+ /**
79
+ * Theme configuration
80
+ */
81
+ theme?: string | ThemeConfig;
82
+ }
83
+ declare const HeadlessSearchInput: <T = Record<string, unknown>>({ baseUrl, className, collection, collections, debounceMs, enableSuggestions: _enableSuggestions, errorClassName, inputClassName, inputWrapperClassName, minQueryLength, noResultsClassName, onResultClick, onResults, onSearch, perPage, placeholder, renderError, renderInput, renderNoResults, renderResult, renderResultsHeader, resultItemClassName, resultsClassName, resultsContainerClassName, resultsHeaderClassName, resultsListClassName, showLoading, showResultCount, showSearchTime, theme, }: HeadlessSearchInputProps<T>) => React.ReactElement;
84
+ export default HeadlessSearchInput;
85
+ export { HeadlessSearchInput };
86
+ //# sourceMappingURL=HeadlessSearchInput.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HeadlessSearchInput.d.ts","sourceRoot":"","sources":["../../src/components/HeadlessSearchInput.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAmD,MAAM,OAAO,CAAA;AAEvE,OAAO,KAAK,EAAE,oBAAoB,EAAkB,YAAY,EAAE,MAAM,iBAAiB,CAAA;AACzF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAIpD,MAAM,WAAW,wBAAwB,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CACnE,SAAQ,oBAAoB,CAAC,CAAC,CAAC;IAC/B;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;IACtB;;OAEG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;OAEG;IACH,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,KAAK,CAAC,SAAS,CAAA;IAChD;;OAEG;IACH,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE;QACpB,SAAS,EAAE,MAAM,CAAA;QACjB,MAAM,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAA;QACrC,QAAQ,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAA;QAC1D,OAAO,EAAE,MAAM,IAAI,CAAA;QACnB,SAAS,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,aAAa,KAAK,IAAI,CAAA;QAC3C,WAAW,EAAE,MAAM,CAAA;QACnB,GAAG,EAAE,KAAK,CAAC,SAAS,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAA;QAC7C,KAAK,EAAE,MAAM,CAAA;KACd,KAAK,KAAK,CAAC,SAAS,CAAA;IACrB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,KAAK,CAAC,SAAS,CAAA;IACrC;;OAEG;IACH,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,KAAK,CAAC,SAAS,CAAA;IACpD;;OAEG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,KAAK,CAAC,SAAS,CAAA;IAC1E;;OAEG;IACH,mBAAmB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,KAAK,CAAC,SAAS,CAAA;IAC5E;;OAEG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB;;OAEG;IACH,yBAAyB,CAAC,EAAE,MAAM,CAAA;IAClC;;OAEG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB;;OAEG;IACH,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB;;OAEG;IACH,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,WAAW,CAAA;CAC7B;AAED,QAAA,MAAM,mBAAmB,GAAI,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAG,6eA+BxD,wBAAwB,CAAC,CAAC,CAAC,KAAG,KAAK,CAAC,YAotBtC,CAAA;AAED,eAAe,mBAAmB,CAAA;AAClC,OAAO,EAAE,mBAAmB,EAAE,CAAA"}