Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions src/core/backend/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# @hookplane/backend

## 0.2.0

### Minor Changes

- Refactor backend interface to use plain states

### Patch Changes

- Updated dependencies
- @hookplane/core@0.1.1

## 0.1.0

### Minor Changes
Expand Down
2 changes: 1 addition & 1 deletion src/core/backend/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@hookplane/backend",
"type": "module",
"version": "0.1.0",
"version": "0.2.0",
"license": "Apache-2.0",
"description": "Uniform backend interface for hookplane",
"repository": "github:interlandi-io/hookplane",
Expand Down
81 changes: 55 additions & 26 deletions src/core/backend/src/backend.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
import { ProviderSet, Statefile } from '@hookplane/core'
import { ResultAsync } from 'neverthrow'

export type StatefileData = Statefile<ProviderSet>['data']
import type { ProviderSet, State } from '@hookplane/core'
import type { ResultAsync } from 'neverthrow'

export interface Backend {
/** Name of the backend */
readonly name: string

statefile: {
/** Reads the raw statefile data from storage */
read(): ResultAsync<StatefileData, BackendError>
state: {
/** Reads state data */
read<P extends ProviderSet>(
providers: P,
): ResultAsync<State<P>, BackendError>

/** Writes a validated statefile to storage */
/** Writes a state to storage */
write<P extends ProviderSet>(
data: Statefile<P>,
data: State<P>,
): ResultAsync<void, BackendError>

/** Deletes the statefile from storage */
/** Deletes the state from storage */
delete(): ResultAsync<void, BackendError>
}

Expand All @@ -32,64 +32,83 @@ export interface Backend {
}
}

export type StatefileOperation = 'read' | 'write' | 'delete'
export type BackendOperation = 'read' | 'write' | 'delete'

export type BackendError =
| NotFoundError
| PermissionDeniedError
| WriteRejectedError
| ServerError
| InternalError
| ProviderNotFoundError
| UnknownError

export interface NotFoundError {
kind: 'BackendError'
name: 'NotFoundError'
message: string
while: StatefileOperation
while: BackendOperation
}

export interface PermissionDeniedError {
kind: 'BackendError'
name: 'PermissionDeniedError'
message: string
while: StatefileOperation
while: BackendOperation
}

export interface WriteRejectedError {
kind: 'BackendError'
name: 'WriteRejectedError'
message: string
while: StatefileOperation
while: BackendOperation
}

export interface ServerError {
kind: 'BackendError'
name: 'ServerError'
message: string
statusCode?: number
while: StatefileOperation
while: BackendOperation
}

export interface InternalError {
kind: 'BackendError'
name: 'InternalError'
message: string
while: BackendOperation
cause?: unknown
}

export interface ProviderNotFoundError {
kind: 'BackendError'
name: 'ProviderNotFoundError'
message: string
while: BackendOperation
provider: string
}

export interface UnknownError {
kind: 'BackendError'
name: 'UnknownError'
message: string
while: StatefileOperation
while: BackendOperation
cause?: unknown
}

export interface BackendDescriptor<TConfig, TState> {
readonly name: string
init?: (config: TConfig) => Promise<TState>
statefile: {
read(params: {
state: {
read<P extends ProviderSet>(params: {
config: TConfig
state: TState
}): ResultAsync<StatefileData, BackendError>
providers: P
}): ResultAsync<State<P>, BackendError>
write<P extends ProviderSet>(params: {
config: TConfig
state: TState
data: Statefile<P>
data: State<P>
}): ResultAsync<void, BackendError>
delete(params: {
config: TConfig
Expand Down Expand Up @@ -118,18 +137,28 @@ export interface BackendDescriptor<TConfig, TState> {

export function describeBackend<TConfig, TState>(
desc: BackendDescriptor<TConfig, TState>,
): (config: TConfig) => Promise<Backend> {
return async (config: TConfig) => {
): (config: TConfig) => () => Promise<Backend> {
return (config: TConfig) => async () => {
let state = {} as TState
if (desc.init) {
state = await desc.init(config)
}
return {
name: desc.name,
statefile: {
read: () => desc.statefile.read({ config, state }),
write: (data) => desc.statefile.write({ config, state, data }),
delete: () => desc.statefile.delete({ config, state }),
state: {
read: <P extends ProviderSet>(providers: P) =>
desc.state.read<P>({
config,
state,
providers: providers,
}),
Comment thread
coderabbitai[bot] marked this conversation as resolved.
write: <P extends ProviderSet>(data: State<P>) =>
desc.state.write<P>({
config,
state,
data,
}),
delete: () => desc.state.delete({ config, state }),
},
signingSecret: {
read: (id) => desc.signingSecret.read({ config, state, id }),
Expand Down
5 changes: 3 additions & 2 deletions src/core/backend/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
export { createLocalBackend, type LocalBackendConfig } from './local.js'
export { createTempBackend } from './temp.js'
export type {
StatefileData,
Backend,
BackendDescriptor,
BackendError,
StatefileOperation,
BackendOperation,
} from './backend.js'
export { describeBackend } from './backend.js'
export type {
NotFoundError,
PermissionDeniedError,
WriteRejectedError,
ServerError,
InternalError,
ProviderNotFoundError,
UnknownError,
} from './backend.js'
Loading
Loading