-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(reindex): init base internal client implementatipn
- Loading branch information
Showing
25 changed files
with
809 additions
and
548 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
export * from './tap-task-either-error'; | ||
export * from './tap-task-either'; | ||
export * from './try-tagged-error-task'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import * as TE from 'fp-ts/TaskEither'; | ||
|
||
import type * as T from 'fp-ts/Task'; | ||
import type { TaggedError } from '../../types'; | ||
|
||
export const tryTaggedErrorTask = | ||
<TC extends TaggedError>(TagClass: new (originalStack?: string) => TC) => | ||
<R>(task: T.Task<R>): TE.TaskEither<TC, R> => | ||
TE.tryCatch(task, (exception: any) => new TagClass(exception.stack)); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,3 @@ | ||
export * from './fp-ts'; | ||
export * from './nop'; | ||
export * from './reject-falsy-values'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export const nop = () => {}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
type FalsyValues = false | undefined | null; | ||
|
||
type FalsyItem<O> = O | FalsyValues; | ||
|
||
export const rejectFalsyItems = <O>(items: Array<FalsyItem<O>>) => | ||
items.filter(Boolean) as Array<Exclude<O, FalsyValues>>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,11 @@ | ||
export type TaggedError = Error & { | ||
tag: string; | ||
}; | ||
export abstract class TaggedError extends Error { | ||
abstract readonly tag: string; | ||
|
||
constructor(readonly originalStack?: string) { | ||
super(); | ||
Error.captureStackTrace(this, TaggedError); | ||
} | ||
} | ||
|
||
export const isTaggedError = (error: Error): error is TaggedError => | ||
'tag' in error; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,56 @@ | ||
import { pipe, flow } from 'fp-ts/function'; | ||
import * as TE from 'fp-ts/TaskEither'; | ||
|
||
import type { AbstractLogger } from './abstract-logger.types'; | ||
import { nop, rejectFalsyItems, tapTaskEither } from '@searchpunch/core'; | ||
|
||
type UnsafeErrorMessage = string | Error; | ||
|
||
type TaskEitherLoggerAttrs<E, A> = { | ||
onBefore?: () => string; | ||
onRight?: (data: A) => string; | ||
onLeft: (error: E) => UnsafeErrorMessage; | ||
}; | ||
|
||
export class AbstractFpTsLogger { | ||
constructor(private readonly logger: AbstractLogger) {} | ||
|
||
logTaskEitherError = | ||
<E, A>(onLeft: (error: E) => UnsafeErrorMessage) => | ||
(task: TE.TaskEither<E, A>): TE.TaskEither<E, A> => | ||
pipe( | ||
task, | ||
this.logTaskEither({ | ||
onLeft, | ||
}), | ||
); | ||
|
||
logTaskEither = | ||
<E, A>({ onBefore, onRight, onLeft }: TaskEitherLoggerAttrs<E, A>) => | ||
(task: TE.TaskEither<E, A>): TE.TaskEither<E, A> => | ||
pipe( | ||
TE.fromIO(onBefore ?? nop), | ||
TE.chain(() => task), | ||
tapTaskEither( | ||
onRight ? flow(onRight, this.logger.info) : nop, | ||
error => { | ||
this.tryLogErrorWithStack(onLeft(error))(error); | ||
}, | ||
), | ||
); | ||
|
||
private readonly tryLogErrorWithStack = | ||
(message: UnsafeErrorMessage) => (error: any) => { | ||
const mappedMessage = pipe( | ||
[ | ||
message, | ||
error && 'originalStack' in error && error.originalStack, | ||
error && 'stack' in error && error.stack, | ||
], | ||
rejectFalsyItems, | ||
array => array.join('\n'), | ||
); | ||
|
||
this.logger.error(mappedMessage); | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
23 changes: 23 additions & 0 deletions
23
packages/reindex/src/+internal/client/es-monadic-client.error.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { TaggedError } from '@searchpunch/core'; | ||
|
||
export class EsUnableSetAliasError extends TaggedError { | ||
readonly tag = 'EsUnableSetAliasError'; | ||
} | ||
|
||
export class EsNotFoundError extends TaggedError { | ||
readonly tag = 'EsNotFoundError'; | ||
} | ||
|
||
export class EsConnectionRefused extends TaggedError { | ||
readonly tag = 'EsConnectionRefused'; | ||
} | ||
|
||
export class EsInternalError extends TaggedError { | ||
readonly tag = 'EsInternalError'; | ||
} | ||
|
||
export type EsTaggedError = | ||
| EsConnectionRefused | ||
| EsUnableSetAliasError | ||
| EsNotFoundError | ||
| EsInternalError; |
9 changes: 9 additions & 0 deletions
9
packages/reindex/src/+internal/client/es-monadic-client.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { EsMonadicClient } from './es-monadic-client'; | ||
|
||
test('test', async () => { | ||
const client = EsMonadicClient.ofConnection({ | ||
node: 'http://localhost:9001', | ||
}); | ||
|
||
await client.alias.getAllIndicesByAlias('dupa')(); | ||
}); |
111 changes: 111 additions & 0 deletions
111
packages/reindex/src/+internal/client/es-monadic-client.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
import { pipe } from 'fp-ts/function'; | ||
import * as es from '@elastic/elasticsearch'; | ||
import { PinoLogger, type AbstractLogger } from '@searchpunch/logger'; | ||
|
||
import type { EsDocId } from './es-monadic-client.types'; | ||
|
||
import { tryEsTask } from './try-es-task'; | ||
import { | ||
EsNotFoundError, | ||
EsUnableSetAliasError, | ||
} from './es-monadic-client.error'; | ||
|
||
type AttrWithEsIndex<F = unknown> = F & { | ||
index: string; | ||
}; | ||
|
||
export type EsMonadicClientOptions = { | ||
client: es.Client; | ||
logger?: AbstractLogger; | ||
}; | ||
|
||
export class EsMonadicClient { | ||
readonly rawClient: es.Client; | ||
|
||
private readonly logger: AbstractLogger; | ||
|
||
constructor(options: EsMonadicClientOptions) { | ||
this.rawClient = options.client; | ||
this.logger = options.logger ?? new PinoLogger('EsMonadicDecorator'); | ||
} | ||
|
||
static ofConnection = ( | ||
esConnectionOptions: es.ClientOptions, | ||
options?: Omit<EsMonadicClientOptions, 'client'>, | ||
) => | ||
new EsMonadicClient({ | ||
...options, | ||
client: new es.Client(esConnectionOptions), | ||
}); | ||
|
||
readonly record = { | ||
get: ({ id, index }: AttrWithEsIndex<{ id: EsDocId }>) => | ||
pipe( | ||
async () => { | ||
const response = await this.rawClient.get({ | ||
id: id.toString(), | ||
index, | ||
}); | ||
|
||
return response._source; | ||
}, | ||
tryEsTask(EsNotFoundError), | ||
this.logger.fp.logTaskEitherError(() => `Record with ${id} not found!`), | ||
), | ||
|
||
delete: ({ id, index }: AttrWithEsIndex<{ id: EsDocId }>) => | ||
pipe( | ||
async () => | ||
this.rawClient.delete({ | ||
id: id.toString(), | ||
index, | ||
}), | ||
tryEsTask(), | ||
this.logger.fp.logTaskEitherError(() => `Record with ${id} not found!`), | ||
), | ||
}; | ||
|
||
readonly alias = { | ||
getAllIndicesByAlias: (aliasName: string) => | ||
pipe( | ||
async () => { | ||
const response = await this.rawClient.indices.getAlias({ | ||
index: aliasName, | ||
}); | ||
|
||
return Object.keys(response.body); | ||
}, | ||
tryEsTask(), | ||
this.logger.fp.logTaskEitherError( | ||
() => `Unable to list "${aliasName}" alias indices!`, | ||
), | ||
), | ||
|
||
put: (attrs: { aliasName: string; destinationIndex: string }) => | ||
pipe( | ||
async () => | ||
this.rawClient.indices.putAlias({ | ||
index: attrs.destinationIndex, | ||
name: attrs.aliasName, | ||
}), | ||
tryEsTask(EsUnableSetAliasError), | ||
this.logger.fp.logTaskEither({ | ||
onLeft: () => 'Unable to put alias!', | ||
onBefore: () => | ||
`Trying to put alias "${attrs.aliasName}" for "${attrs.destinationIndex}" index!`, | ||
}), | ||
), | ||
|
||
existsOrFail: (name: string) => | ||
pipe( | ||
async () => | ||
this.rawClient.indices.existsAlias({ | ||
name, | ||
}), | ||
tryEsTask(), | ||
this.logger.fp.logTaskEitherError( | ||
() => `Cannot check if "${name}" index exists!"`, | ||
), | ||
), | ||
}; | ||
} |
1 change: 1 addition & 0 deletions
1
packages/reindex/src/+internal/client/es-monadic-client.types.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export type EsDocId = string | number; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './es-monadic-client'; |
Oops, something went wrong.