leonelsearchapi 1.0.0-beta.1
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/index.js +148 -0
- package/package.json +20 -0
- package/readme.md +412 -0
package/index.js
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
export class LeonelSearchAPI {
|
|
2
|
+
/**
|
|
3
|
+
* @param {Object} options
|
|
4
|
+
* @param {string} options.apiKey Your LeonelSearch API key
|
|
5
|
+
* @param {string} [options.apiVersion='v1'] API version
|
|
6
|
+
* @param {boolean} [options.debug=false] Enable debug logs
|
|
7
|
+
*/
|
|
8
|
+
constructor({ apiKey, apiVersion = 'v1', debug = false }) {
|
|
9
|
+
if (!apiKey) throw new Error('apiKey is required');
|
|
10
|
+
|
|
11
|
+
this.apiKey = apiKey;
|
|
12
|
+
this.baseURL = `http://leonelsearch.qzz.io:30213/api/${apiVersion}`;
|
|
13
|
+
this.debug = debug;
|
|
14
|
+
|
|
15
|
+
if (this.debug) {
|
|
16
|
+
console.log('[LeonelSearchAPI] Initialized');
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Performs a search request
|
|
22
|
+
* @param {Object} params
|
|
23
|
+
* @param {string} params.query Search query
|
|
24
|
+
* @param {'web'|'image'|'video'|'news'} params.type Search type
|
|
25
|
+
* @param {number} [params.limit=10] Results per page (1-50)
|
|
26
|
+
* @param {number} [params.page=1] Page number (>=1)
|
|
27
|
+
* @returns {Promise<Object>} API response
|
|
28
|
+
*/
|
|
29
|
+
async search({ query, type, limit = 10, page = 1 }) {
|
|
30
|
+
if (!query) throw new Error('Param "query" is required');
|
|
31
|
+
if (!type) throw new Error('Param "type" is required');
|
|
32
|
+
|
|
33
|
+
const validTypes = ['web', 'image', 'video', 'news'];
|
|
34
|
+
if (!validTypes.includes(type)) {
|
|
35
|
+
throw new Error(
|
|
36
|
+
`Invalid type "${type}". Must be one of: ${validTypes.join(', ')}`
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (limit < 1 || limit > 50) {
|
|
41
|
+
throw new Error('Param "limit" must be between 1 and 50');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (page < 1) {
|
|
45
|
+
throw new Error('Param "page" must be 1 or greater');
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const payload = { query, type, limit, page };
|
|
49
|
+
|
|
50
|
+
if (this.debug) {
|
|
51
|
+
console.log('[LeonelSearchAPI] → Request');
|
|
52
|
+
console.log(' Endpoint: /search');
|
|
53
|
+
console.log(' Payload:', payload);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
try {
|
|
57
|
+
const res = await fetch(`${this.baseURL}/search`, {
|
|
58
|
+
method: 'POST',
|
|
59
|
+
headers: {
|
|
60
|
+
'Content-Type': 'application/json',
|
|
61
|
+
'x-api-key': this.apiKey
|
|
62
|
+
},
|
|
63
|
+
body: JSON.stringify(payload)
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// ==============================
|
|
67
|
+
// ERROR RESPONSE
|
|
68
|
+
// ==============================
|
|
69
|
+
if (!res.ok) {
|
|
70
|
+
let message = `${res.status} ${res.statusText}`;
|
|
71
|
+
let data = null;
|
|
72
|
+
|
|
73
|
+
const raw = await res.text();
|
|
74
|
+
|
|
75
|
+
if (raw) {
|
|
76
|
+
try {
|
|
77
|
+
data = JSON.parse(raw);
|
|
78
|
+
if (data?.message) message = data.message;
|
|
79
|
+
} catch {
|
|
80
|
+
message = raw;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const error = new Error(message);
|
|
85
|
+
error.status = res.status;
|
|
86
|
+
error.data = data;
|
|
87
|
+
|
|
88
|
+
if (this.debug) {
|
|
89
|
+
console.error('[LeonelSearchAPI] ✖ API Error');
|
|
90
|
+
console.error(' Status:', res.status);
|
|
91
|
+
console.error(' Message:', message);
|
|
92
|
+
if (data) console.error(' Data:', data);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
throw error;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// ==============================
|
|
99
|
+
// SUCCESS RESPONSE
|
|
100
|
+
// ==============================
|
|
101
|
+
const json = await res.json();
|
|
102
|
+
|
|
103
|
+
if (this.debug) {
|
|
104
|
+
console.log('[LeonelSearchAPI] ← Response');
|
|
105
|
+
console.log(' Query:', json.query);
|
|
106
|
+
console.log(
|
|
107
|
+
' Results:',
|
|
108
|
+
json.meta?.resultCount ??
|
|
109
|
+
json.results?.length ??
|
|
110
|
+
0
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return json;
|
|
115
|
+
} catch (err) {
|
|
116
|
+
if (this.debug) {
|
|
117
|
+
console.error('[LeonelSearchAPI] ✖ Request Failed');
|
|
118
|
+
console.error(err);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
throw err;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// ============================================================
|
|
126
|
+
// Shortcuts
|
|
127
|
+
// ============================================================
|
|
128
|
+
|
|
129
|
+
/** Web search */
|
|
130
|
+
searchWeb(query, limit = 10, page = 1) {
|
|
131
|
+
return this.search({ query, type: 'web', limit, page });
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/** Image search */
|
|
135
|
+
searchImages(query, limit = 10, page = 1) {
|
|
136
|
+
return this.search({ query, type: 'image', limit, page });
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/** Video search */
|
|
140
|
+
searchVideos(query, limit = 10, page = 1) {
|
|
141
|
+
return this.search({ query, type: 'video', limit, page });
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/** News search */
|
|
145
|
+
searchNews(query, limit = 10, page = 1) {
|
|
146
|
+
return this.search({ query, type: 'news', limit, page });
|
|
147
|
+
}
|
|
148
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "leonelsearchapi",
|
|
3
|
+
"version": "1.0.0-beta.1",
|
|
4
|
+
"description": "Official JavaScript client for LeonelSearchAPI. Perform searches easily with your API key.",
|
|
5
|
+
"homepage": "https://github.com/LeonelDevStudios/LeonelSearchAPI#readme",
|
|
6
|
+
"bugs": {
|
|
7
|
+
"url": "https://github.com/LeonelDevStudios/LeonelSearchAPI/issues"
|
|
8
|
+
},
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/LeonelDevStudios/LeonelSearchAPI.git"
|
|
12
|
+
},
|
|
13
|
+
"license": "MIT",
|
|
14
|
+
"author": "LeonelDev",
|
|
15
|
+
"type": "module",
|
|
16
|
+
"main": "index.js",
|
|
17
|
+
"scripts": {
|
|
18
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
19
|
+
}
|
|
20
|
+
}
|
package/readme.md
ADDED
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
# LeonelSearchAPI
|
|
2
|
+
|
|
3
|
+
Official JavaScript client for the **LeonelSearch API**.
|
|
4
|
+
Easily perform web searches and retrieve structured results using your API key.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- 🔍 **Multi-type search support**: `web`, `image`, `video`, and `news`
|
|
11
|
+
- ⚡ **Lightweight**: No dependencies, fast and efficient
|
|
12
|
+
- 📦 **Modern ES Modules**: Built with `import/export` syntax
|
|
13
|
+
- 📑 **Structured results**: Consistent data format across all search types
|
|
14
|
+
- 🔐 **Secure authentication**: API key protected requests
|
|
15
|
+
- 🌐 **Simple integration**: Easy to use in any JavaScript project
|
|
16
|
+
- 🎯 **Convenience methods**: Dedicated methods for each search type
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install leonelsearchapi
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Quick Start
|
|
29
|
+
|
|
30
|
+
```javascript
|
|
31
|
+
import { LeonelSearchAPI } from 'leonelsearchapi';
|
|
32
|
+
|
|
33
|
+
// Initialize the client
|
|
34
|
+
const client = new LeonelSearchAPI({
|
|
35
|
+
apiKey: 'YOUR_API_KEY', // Get your key from leonelsearch.com
|
|
36
|
+
debug: false // Set true to enable debug logs
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// Perform a web search
|
|
40
|
+
async function searchExample() {
|
|
41
|
+
try {
|
|
42
|
+
const results = await client.search({
|
|
43
|
+
query: 'latest space news',
|
|
44
|
+
type: 'web', // Search type: 'web', 'image', 'video', or 'news'
|
|
45
|
+
limit: 5,
|
|
46
|
+
page: 1
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
console.log(results);
|
|
50
|
+
} catch (err) {
|
|
51
|
+
console.error('Error:', err.message);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
searchExample();
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## API Reference
|
|
61
|
+
|
|
62
|
+
### `new LeonelSearchAPI({ apiKey })`
|
|
63
|
+
|
|
64
|
+
* **apiKey** *(string, required)*: Your personal LeonelSearch API key
|
|
65
|
+
|
|
66
|
+
### `client.search({ query, type, limit, page })`
|
|
67
|
+
|
|
68
|
+
The main search method supporting all search types.
|
|
69
|
+
|
|
70
|
+
| Parameter | Type | Required | Default | Description | Valid Values |
|
|
71
|
+
|-----------|--------|----------|---------|----------------------------|-------------------------------|
|
|
72
|
+
| query | string | ✅ | — | The search term | Any string |
|
|
73
|
+
| type | string | ✅ | — | Type of search to perform | `'web'`, `'image'`, `'video'`, `'news'` |
|
|
74
|
+
| limit | number | ❌ | 10 | Number of results per page | 1-50 |
|
|
75
|
+
| page | number | ❌ | 1 | Page number | ≥1 |
|
|
76
|
+
|
|
77
|
+
**Returns:** A Promise resolving to a structured response object:
|
|
78
|
+
|
|
79
|
+
```json
|
|
80
|
+
{
|
|
81
|
+
"query": "search query",
|
|
82
|
+
"results": [
|
|
83
|
+
{
|
|
84
|
+
"type": "result type",
|
|
85
|
+
"url": "source URL",
|
|
86
|
+
"title": "result title",
|
|
87
|
+
"text": "description or excerpt",
|
|
88
|
+
"score": 0
|
|
89
|
+
}
|
|
90
|
+
]
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Convenience Methods
|
|
95
|
+
|
|
96
|
+
For easier use, the client provides dedicated methods for each search type:
|
|
97
|
+
|
|
98
|
+
#### `client.searchWeb(query, limit = 10, page = 1)`
|
|
99
|
+
Performs a web search.
|
|
100
|
+
|
|
101
|
+
#### `client.searchImages(query, limit = 10, page = 1)`
|
|
102
|
+
Performs an image search.
|
|
103
|
+
|
|
104
|
+
#### `client.searchVideos(query, limit = 10, page = 1)`
|
|
105
|
+
Performs a video search.
|
|
106
|
+
|
|
107
|
+
#### `client.searchNews(query, limit = 10, page = 1)`
|
|
108
|
+
Performs a news search.
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Examples
|
|
113
|
+
|
|
114
|
+
### Using the Main Search Method
|
|
115
|
+
|
|
116
|
+
```javascript
|
|
117
|
+
// Web search
|
|
118
|
+
const webResults = await client.search({
|
|
119
|
+
query: 'latest space exploration',
|
|
120
|
+
type: 'web',
|
|
121
|
+
limit: 5
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
// Image search
|
|
125
|
+
const imageResults = await client.search({
|
|
126
|
+
query: 'mars rover photos',
|
|
127
|
+
type: 'image',
|
|
128
|
+
limit: 10
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
// Video search
|
|
132
|
+
const videoResults = await client.search({
|
|
133
|
+
query: 'quantum computing explained',
|
|
134
|
+
type: 'video',
|
|
135
|
+
limit: 3
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
// News search
|
|
139
|
+
const newsResults = await client.search({
|
|
140
|
+
query: 'artificial intelligence breakthroughs',
|
|
141
|
+
type: 'news',
|
|
142
|
+
limit: 5,
|
|
143
|
+
page: 2
|
|
144
|
+
});
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Using Convenience Methods
|
|
148
|
+
|
|
149
|
+
```javascript
|
|
150
|
+
// More concise syntax for common use cases
|
|
151
|
+
const webResults = await client.searchWeb('space exploration', 10, 1);
|
|
152
|
+
const imageResults = await client.searchImages('natural landscapes', 15, 1);
|
|
153
|
+
const videoResults = await client.searchVideos('cooking tutorials', 5, 1);
|
|
154
|
+
const newsResults = await client.searchNews('technology trends', 8, 1);
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Complete Example with Error Handling
|
|
158
|
+
|
|
159
|
+
```javascript
|
|
160
|
+
import { LeonelSearchAPI } from 'leonelsearchapi';
|
|
161
|
+
|
|
162
|
+
const client = new LeonelSearchAPI({
|
|
163
|
+
apiKey: 'your-api-key-here'
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
async function performComprehensiveSearch() {
|
|
167
|
+
try {
|
|
168
|
+
console.log('=== Performing Multiple Search Types ===\n');
|
|
169
|
+
|
|
170
|
+
// Search for web results
|
|
171
|
+
const webSearch = await client.searchWeb('renewable energy innovations', 3);
|
|
172
|
+
console.log('Web Results:', webSearch.results.length, 'items found');
|
|
173
|
+
|
|
174
|
+
// Search for images
|
|
175
|
+
const imageSearch = await client.searchImages('solar panels installation', 4);
|
|
176
|
+
console.log('Image Results:', imageSearch.results.length, 'items found');
|
|
177
|
+
|
|
178
|
+
// Search for news
|
|
179
|
+
const newsSearch = await client.searchNews('climate policy updates', 5);
|
|
180
|
+
console.log('News Results:', newsSearch.results.length, 'items found\n');
|
|
181
|
+
|
|
182
|
+
// Display sample results
|
|
183
|
+
console.log('Sample News Headlines:');
|
|
184
|
+
newsSearch.results.slice(0, 3).forEach((result, index) => {
|
|
185
|
+
console.log(`${index + 1}. ${result.title}`);
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
return { webSearch, imageSearch, newsSearch };
|
|
189
|
+
} catch (error) {
|
|
190
|
+
console.error('Search failed:', error.message);
|
|
191
|
+
throw error;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
performComprehensiveSearch();
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Pagination Example
|
|
199
|
+
|
|
200
|
+
```javascript
|
|
201
|
+
async function fetchPaginatedResults() {
|
|
202
|
+
const allResults = [];
|
|
203
|
+
let currentPage = 1;
|
|
204
|
+
const resultsPerPage = 10;
|
|
205
|
+
|
|
206
|
+
try {
|
|
207
|
+
// Fetch first page
|
|
208
|
+
let response = await client.searchNews('economic indicators', resultsPerPage, currentPage);
|
|
209
|
+
allResults.push(...response.results);
|
|
210
|
+
|
|
211
|
+
// Continue fetching while there are results
|
|
212
|
+
while (response.results.length === resultsPerPage) {
|
|
213
|
+
currentPage++;
|
|
214
|
+
response = await client.searchNews('economic indicators', resultsPerPage, currentPage);
|
|
215
|
+
allResults.push(...response.results);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
console.log(`Total results fetched: ${allResults.length}`);
|
|
219
|
+
return allResults;
|
|
220
|
+
} catch (error) {
|
|
221
|
+
console.error('Pagination error:', error.message);
|
|
222
|
+
return allResults;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## Response Structure
|
|
230
|
+
|
|
231
|
+
All search methods return results in a consistent format:
|
|
232
|
+
|
|
233
|
+
```javascript
|
|
234
|
+
{
|
|
235
|
+
query: "original search query",
|
|
236
|
+
results: [
|
|
237
|
+
{
|
|
238
|
+
type: "web", // or "image", "video", "news"
|
|
239
|
+
url: "https://example.com/article",
|
|
240
|
+
title: "Article Title",
|
|
241
|
+
text: "Article excerpt or description...",
|
|
242
|
+
score: 0 // Relevance score
|
|
243
|
+
},
|
|
244
|
+
// ... more results
|
|
245
|
+
]
|
|
246
|
+
}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## Error Handling
|
|
252
|
+
|
|
253
|
+
```javascript
|
|
254
|
+
import { LeonelSearchAPI } from 'leonelsearchapi';
|
|
255
|
+
|
|
256
|
+
const client = new LeonelSearchAPI({ apiKey: 'your-key' });
|
|
257
|
+
|
|
258
|
+
async function safeSearch(query, type = 'web') {
|
|
259
|
+
try {
|
|
260
|
+
const results = await client.search({ query, type });
|
|
261
|
+
return results;
|
|
262
|
+
} catch (error) {
|
|
263
|
+
// Handle specific error types
|
|
264
|
+
const errorMessage = error.message.toLowerCase();
|
|
265
|
+
|
|
266
|
+
if (errorMessage.includes('401') || errorMessage.includes('invalid api')) {
|
|
267
|
+
console.error('❌ Authentication failed. Please check your API key.');
|
|
268
|
+
} else if (errorMessage.includes('429') || errorMessage.includes('rate limit')) {
|
|
269
|
+
console.error('⏳ Rate limit exceeded. Please wait before making more requests.');
|
|
270
|
+
} else if (errorMessage.includes('400') || errorMessage.includes('bad request')) {
|
|
271
|
+
console.error('⚠️ Invalid request. Please check your search parameters.');
|
|
272
|
+
} else if (errorMessage.includes('network') || errorMessage.includes('connection')) {
|
|
273
|
+
console.error('🔌 Network error. Please check your internet connection.');
|
|
274
|
+
} else {
|
|
275
|
+
console.error('💥 An unexpected error occurred:', error.message);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// Return empty results for graceful degradation
|
|
279
|
+
return { query, results: [] };
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// Usage
|
|
284
|
+
const results = await safeSearch('test query', 'news');
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
---
|
|
288
|
+
|
|
289
|
+
## TypeScript Support
|
|
290
|
+
|
|
291
|
+
The package includes full TypeScript definitions:
|
|
292
|
+
|
|
293
|
+
```typescript
|
|
294
|
+
import { LeonelSearchAPI, SearchResult, SearchParams } from 'leonelsearchapi';
|
|
295
|
+
|
|
296
|
+
const client = new LeonelSearchAPI({ apiKey: 'your-key' });
|
|
297
|
+
|
|
298
|
+
// Type-safe search with main method
|
|
299
|
+
async function searchWithTypes(params: SearchParams) {
|
|
300
|
+
const response = await client.search(params);
|
|
301
|
+
return response.results;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// Using convenience methods with type inference
|
|
305
|
+
async function convenienceExamples() {
|
|
306
|
+
// These methods are fully typed
|
|
307
|
+
const webResults = await client.searchWeb('typescript tutorial', 5);
|
|
308
|
+
const imageResults = await client.searchImages('typescript logo', 10);
|
|
309
|
+
const newsResults = await client.searchNews('typescript updates', 8);
|
|
310
|
+
|
|
311
|
+
return { webResults, imageResults, newsResults };
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// Type-safe parameter object
|
|
315
|
+
const searchParams: SearchParams = {
|
|
316
|
+
query: 'typescript vs javascript',
|
|
317
|
+
type: 'web', // TypeScript will validate this value
|
|
318
|
+
limit: 5,
|
|
319
|
+
page: 1
|
|
320
|
+
};
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
---
|
|
324
|
+
|
|
325
|
+
## Best Practices
|
|
326
|
+
|
|
327
|
+
### 1. **API Key Security**
|
|
328
|
+
```javascript
|
|
329
|
+
// Store API key in environment variables, not in code
|
|
330
|
+
const client = new LeonelSearchAPI({
|
|
331
|
+
apiKey: process.env.LEONELSEARCH_API_KEY
|
|
332
|
+
});
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
### 2. **Request Optimization**
|
|
336
|
+
```javascript
|
|
337
|
+
// Request only what you need
|
|
338
|
+
const optimalSearch = await client.search({
|
|
339
|
+
query: 'specific topic',
|
|
340
|
+
type: 'web',
|
|
341
|
+
limit: 5 // Smaller limits for faster responses
|
|
342
|
+
});
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
### 3. **Implement Caching**
|
|
346
|
+
```javascript
|
|
347
|
+
// Simple caching strategy
|
|
348
|
+
const searchCache = new Map();
|
|
349
|
+
|
|
350
|
+
async function cachedSearch(query, type = 'web') {
|
|
351
|
+
const cacheKey = `${type}:${query}`;
|
|
352
|
+
|
|
353
|
+
if (searchCache.has(cacheKey)) {
|
|
354
|
+
return searchCache.get(cacheKey);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
const results = await client.search({ query, type });
|
|
358
|
+
searchCache.set(cacheKey, results);
|
|
359
|
+
|
|
360
|
+
// Optional: Clear cache after some time
|
|
361
|
+
setTimeout(() => searchCache.delete(cacheKey), 300000); // 5 minutes
|
|
362
|
+
|
|
363
|
+
return results;
|
|
364
|
+
}
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
### 4. **Rate Limiting**
|
|
368
|
+
```javascript
|
|
369
|
+
// Implement request spacing
|
|
370
|
+
async function rateLimitedSearch(query, type) {
|
|
371
|
+
await new Promise(resolve => setTimeout(resolve, 1000)); // 1 second delay
|
|
372
|
+
return client.search({ query, type });
|
|
373
|
+
}
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
### 5. **Batch Processing**
|
|
377
|
+
```javascript
|
|
378
|
+
// Process multiple searches efficiently
|
|
379
|
+
async function batchSearch(queries, type = 'web') {
|
|
380
|
+
const results = [];
|
|
381
|
+
|
|
382
|
+
for (const query of queries) {
|
|
383
|
+
try {
|
|
384
|
+
const result = await client.search({ query, type, limit: 3 });
|
|
385
|
+
results.push({ query, success: true, data: result });
|
|
386
|
+
} catch (error) {
|
|
387
|
+
results.push({ query, success: false, error: error.message });
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
// Delay between requests to respect rate limits
|
|
391
|
+
await new Promise(resolve => setTimeout(resolve, 500));
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
return results;
|
|
395
|
+
}
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
---
|
|
399
|
+
|
|
400
|
+
## License
|
|
401
|
+
|
|
402
|
+
MIT © 2026 LeonelDev
|
|
403
|
+
|
|
404
|
+
---
|
|
405
|
+
|
|
406
|
+
## Support
|
|
407
|
+
|
|
408
|
+
For API key registration, documentation, and support, visit [leonelsearchapi.com](https://leonelsearchapi.com)
|
|
409
|
+
|
|
410
|
+
---
|
|
411
|
+
|
|
412
|
+
*Note: This is a beta release. API responses and features may change during development.*
|