Skip to content

Commit 3ff5dcc

Browse files
authored
chore(repository): improve repository structure and naming (#11)
1 parent bfb8af2 commit 3ff5dcc

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

82 files changed

+812
-240
lines changed

.gitignore

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,7 @@ yarn-error.log
1010
!.yarn/releases
1111
!.yarn/plugins
1212

13-
*/.openapi-generator
14-
*/node_modules
15-
*/dist
16-
*/.openapi-generator-ignore
17-
18-
output/complement
13+
**/.openapi-generator
14+
**/node_modules
15+
**/dist
16+
**/.openapi-generator-ignore

README.md

Lines changed: 18 additions & 4 deletions

clients/README.md

Lines changed: 11 additions & 0 deletions
File renamed without changes.

output/client-search/searchApi.ts renamed to clients/algoliasearch-client-javascript/client-search/searchApi.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import http from 'http';
2-
import { shuffle } from '../complement/helpers';
3-
import { Transporter } from '../complement/Transporter';
4-
import { Headers, Host, Request, RequestOptions } from '../complement/types';
2+
import { shuffle } from '../utils/helpers';
3+
import { Transporter } from '../utils/Transporter';
4+
import { Headers, Host, Request, RequestOptions } from '../utils/types';
55

66
import { BatchObject } from '../model/batchObject';
77
import { BatchResponse } from '../model/batchResponse';

output/model/models.ts renamed to clients/algoliasearch-client-javascript/model/models.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { RequestOptions } from '../complement/types';
1+
import type { RequestOptions } from '../utils/types';
22

33
export * from './batchObject';
44
export * from './batchResponse';

output/package.json renamed to clients/algoliasearch-client-javascript/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@
1414
"test": "yarn build && node dist/client.js"
1515
},
1616
"engines": {
17-
"node": ">= 16.0.0",
18-
"yarn": ">= 3.0.0"
17+
"node": "^16.0.0",
18+
"yarn": "^3.0.0"
1919
},
2020
"devDependencies": {
2121
"@types/node": "^16.11.6",
22-
"typescript": "^4.4.4"
22+
"typescript": "4.5.2"
2323
}
2424
}

clients/utils/javascript/Cache.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
export interface Cache {
2+
/**
3+
* Gets the value of the given `key`.
4+
*/
5+
get: <TValue>(key: object | string, defaultValue: () => Promise<TValue>) => Promise<TValue>;
6+
7+
/**
8+
* Sets the given value with the given `key`.
9+
*/
10+
set: <TValue>(key: object | string, value: TValue) => Promise<TValue>;
11+
12+
/**
13+
* Deletes the given `key`.
14+
*/
15+
delete: (key: object | string) => Promise<void>;
16+
17+
/**
18+
* Clears the cache.
19+
*/
20+
clear: () => Promise<void>;
21+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import type { Cache } from './Cache';
2+
3+
export class MemoryCache implements Cache {
4+
private cache: Record<string, any> = {};
5+
6+
async get<TValue>(key: object | string, defaultValue: () => Promise<TValue>): Promise<TValue> {
7+
const keyAsString = JSON.stringify(key);
8+
9+
if (keyAsString in this.cache) {
10+
return Promise.resolve(this.cache[keyAsString]);
11+
}
12+
return await defaultValue();
13+
}
14+
15+
async set<TValue>(key: object | string, value: TValue): Promise<TValue> {
16+
this.cache[JSON.stringify(key)] = value;
17+
return value;
18+
}
19+
20+
async delete(key: object | string): Promise<void> {
21+
delete this.cache[JSON.stringify(key)];
22+
}
23+
24+
async clear(): Promise<void> {
25+
this.cache = {};
26+
}
27+
}

clients/utils/javascript/Requester.ts

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import { EndRequest, Response } from './types';
2+
import * as http from 'http';
3+
import * as https from 'https';
4+
5+
export class Requester {
6+
private httpAgent: http.Agent;
7+
private httpsAgent: https.Agent;
8+
9+
constructor() {
10+
this.httpAgent = new http.Agent({ keepAlive: true });
11+
this.httpsAgent = new https.Agent({ keepAlive: true });
12+
}
13+
14+
async send(request: EndRequest): Promise<Response> {
15+
return new Promise((resolve) => {
16+
const url = new URL(request.url);
17+
18+
const path = url.search === null ? url.pathname : `${url.pathname}?${url.search}`;
19+
20+
const options: https.RequestOptions = {
21+
agent: url.protocol === 'https:' ? this.httpsAgent : this.httpAgent,
22+
hostname: url.hostname,
23+
path,
24+
method: request.method,
25+
headers: request.headers,
26+
...(url.port !== undefined ? { port: url.port || '' } : {}),
27+
};
28+
29+
const req = (url.protocol === 'https:' ? https : http).request(options, (response) => {
30+
let contentBuffers: Buffer[] = [];
31+
32+
response.on('data', (chunk) => {
33+
contentBuffers = contentBuffers.concat(chunk);
34+
});
35+
36+
response.on('end', () => {
37+
clearTimeout(connectTimeout);
38+
clearTimeout(responseTimeout as NodeJS.Timeout);
39+
40+
resolve({
41+
status: response.statusCode || 0,
42+
content: Buffer.concat(contentBuffers).toString(),
43+
isTimedOut: false,
44+
});
45+
});
46+
});
47+
48+
const createTimeout = (timeout: number, content: string): NodeJS.Timeout => {
49+
return setTimeout(() => {
50+
req.destroy();
51+
52+
resolve({
53+
status: 0,
54+
content,
55+
isTimedOut: true,
56+
});
57+
}, timeout * 1000);
58+
};
59+
60+
const connectTimeout = createTimeout(request.connectTimeout, 'Connection timeout');
61+
62+
let responseTimeout: NodeJS.Timeout | undefined;
63+
64+
req.on('error', (error) => {
65+
clearTimeout(connectTimeout);
66+
clearTimeout(responseTimeout as NodeJS.Timeout);
67+
resolve({ status: 0, content: error.message, isTimedOut: false });
68+
});
69+
70+
req.once('response', () => {
71+
clearTimeout(connectTimeout);
72+
responseTimeout = createTimeout(request.responseTimeout, 'Socket timeout');
73+
});
74+
75+
if (request.data !== undefined) {
76+
req.write(request.data);
77+
}
78+
79+
req.end();
80+
});
81+
}
82+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import type { Host } from './types';
2+
3+
const EXPIRATION_DELAY = 2 * 60 * 1000;
4+
5+
export class StatefulHost implements Host {
6+
url: string;
7+
accept: 'read' | 'write' | 'readWrite';
8+
protocol: 'http' | 'https';
9+
10+
private lastUpdate: number;
11+
private status: 'up' | 'down' | 'timedout';
12+
13+
constructor(host: Host, status: StatefulHost['status'] = 'up') {
14+
this.url = host.url;
15+
this.accept = host.accept;
16+
this.protocol = host.protocol;
17+
18+
this.status = status;
19+
this.lastUpdate = Date.now();
20+
}
21+
22+
isUp(): boolean {
23+
return this.status === 'up' || Date.now() - this.lastUpdate > EXPIRATION_DELAY;
24+
}
25+
26+
isTimedout(): boolean {
27+
return this.status === 'timedout' && Date.now() - this.lastUpdate <= EXPIRATION_DELAY;
28+
}
29+
}

0 commit comments

Comments
 (0)