Skip to content

Commit

Permalink
Make TxMonitor's methods throw a single error & reduce boilerplate.
Browse files Browse the repository at this point in the history
  • Loading branch information
KtorZ committed May 21, 2022
1 parent 3d57630 commit 7c60bea
Show file tree
Hide file tree
Showing 7 changed files with 175 additions and 168 deletions.
52 changes: 14 additions & 38 deletions clients/TypeScript/packages/client/src/TxMonitor/TxMonitorClient.ts
@@ -1,12 +1,12 @@
import { InteractionContext } from '../Connection'
import { ensureSocketIsOpen, eventEmitterToGenerator, safeJSON } from '../util'
import { MempoolSizeAndCapacity, Null, Ogmios, TxAlonzo, TxId } from "@cardano-ogmios/schema"
import { Ogmios, MempoolSizeAndCapacity, Slot, TxAlonzo, TxId } from "@cardano-ogmios/schema"
import { baseRequest, send } from "../Request"
import { AwaitAcquired, handleAwaitAcquireResponse } from "./awaitAcquire"
import { handleHasTxResponse, isHasTxResult } from "./hasTx"
import { handleNextTxResponse, isNextTxResult } from "./nextTx"
import { handleReleaseResponse, isReleasedResult } from "./release"
import { handleSizeAndCapacityResponse, isMempoolSizeAndCapacity } from "./sizeAndCapacity"
import { handleAwaitAcquireResponse } from "./awaitAcquire"
import { handleHasTxResponse } from "./hasTx"
import { handleNextTxResponse } from "./nextTx"
import { handleReleaseResponse } from "./release"
import { handleSizeAndCapacityResponse } from "./sizeAndCapacity"

/**
* See also {@link createTxMonitorClient} for creating a client.
Expand All @@ -15,9 +15,9 @@ import { handleSizeAndCapacityResponse, isMempoolSizeAndCapacity } from "./sizeA
**/
export interface TxMonitorClient {
context: InteractionContext
awaitAcquire: (args?: {}) => Promise<AwaitAcquired>
awaitAcquire: (args?: {}) => Promise<Slot>
hasTx: (id: TxId) => Promise<boolean>
nextTx: (args?: { fields?: "all" }) => Promise<TxId | TxAlonzo | Null>
nextTx: (args?: { fields?: "all" }) => Promise<TxId | TxAlonzo | null>
sizeAndCapacity: (args?: {}) => Promise<MempoolSizeAndCapacity>
release: (args?: {}) => Promise<void>
shutdown: () => Promise<void>
Expand Down Expand Up @@ -97,7 +97,7 @@ export const createTxMonitorClient = async (
context,
awaitAcquire: (args?: {}) => {
ensureSocketIsOpen(socket)
return send<AwaitAcquired>(async (socket) => {
return send<Slot>(async (socket) => {
socket.send(safeJSON.stringify({
...baseRequest,
methodname: 'AwaitAcquire',
Expand All @@ -116,31 +116,19 @@ export const createTxMonitorClient = async (
args: { id }
} as unknown as Ogmios['HasTx']))

const response = handleHasTxResponse((await hasTxResponse.next()).value)

if (isHasTxResult(response)) {
return response
} else {
throw response
}
return handleHasTxResponse((await hasTxResponse.next()).value)
}, context)
},
nextTx: (args?: {fields?: "all"}) => {
ensureSocketIsOpen(socket)
return send<TxId | TxAlonzo | Null>(async (socket) => {
return send<TxId | TxAlonzo | null>(async (socket) => {
socket.send(safeJSON.stringify({
...baseRequest,
methodname: 'NextTx',
args: args
} as unknown as Ogmios['NextTx']))

const response = handleNextTxResponse((await nextTxResponse.next()).value)

if (isNextTxResult(response)) {
return response
} else {
throw response
}
return handleNextTxResponse((await nextTxResponse.next()).value, args)
}, context)
},
sizeAndCapacity: (args?: {}) => {
Expand All @@ -152,13 +140,7 @@ export const createTxMonitorClient = async (
args: args
} as unknown as Ogmios['SizeAndCapacity']))

const response = handleSizeAndCapacityResponse((await sizeAndCapacityResponse.next()).value)

if (isMempoolSizeAndCapacity(response)) {
return response
} else {
throw response
}
return handleSizeAndCapacityResponse((await sizeAndCapacityResponse.next()).value)
}, context)
},
release: (args?: {}) => {
Expand All @@ -170,13 +152,7 @@ export const createTxMonitorClient = async (
args: args
} as unknown as Ogmios['ReleaseMempool']))

const response = handleReleaseResponse((await releaseMempoolResponse.next()).value)

if (isReleasedResult(response)) {
return
} else {
throw response
}
return handleReleaseResponse((await releaseMempoolResponse.next()).value)
}, context)
},
shutdown: () => new Promise(resolve => {
Expand Down
34 changes: 22 additions & 12 deletions clients/TypeScript/packages/client/src/TxMonitor/awaitAcquire.ts
@@ -1,13 +1,7 @@
import { Ogmios, Slot } from "@cardano-ogmios/schema"
import { Ogmios, AwaitAcquired, Slot } from "@cardano-ogmios/schema"
import { UnknownResultError } from "../errors";
import { InteractionContext } from '../Connection'
import { Query } from '../StateQuery'
export interface AwaitAcquired {
slot: Slot;
};

export const isAwaitAcquiredResult = (result: AwaitAcquired | Error[]): result is AwaitAcquired =>
(typeof (result as AwaitAcquired) === 'object' && !Array.isArray(result))

/**
* Acquire a mempool snapshot. This is blocking until a new (i.e different) snapshot is available.
Expand All @@ -18,7 +12,7 @@ export const awaitAcquire = (context: InteractionContext, args?: {}) =>
Query<
Ogmios['AwaitAcquire'],
Ogmios['AwaitAcquireResponse'],
AwaitAcquired
Slot
>({
methodName: 'AwaitAcquire',
args: args
Expand All @@ -32,10 +26,26 @@ export const awaitAcquire = (context: InteractionContext, args?: {}) =>
}
}, context)

export const handleAwaitAcquireResponse = (response: Ogmios['AwaitAcquireResponse']): AwaitAcquired => {
/**
* @internal
*/
export const isAwaitAcquiredResult = (result: any): result is AwaitAcquired => {
if (typeof result !== 'object' || result === null) {
return false
}

return ('AwaitAcquired' in (result as AwaitAcquired) && typeof result.AwaitAcquired === 'object')
}

/**
* @internal
*/
export const handleAwaitAcquireResponse = (response: Ogmios['AwaitAcquireResponse']): Slot => {
const { result } = response

if ('AwaitAcquired' in result) {
return result.AwaitAcquired
}
return result.AwaitAcquired.slot
}

throw new UnknownResultError(response)
}
}
63 changes: 31 additions & 32 deletions clients/TypeScript/packages/client/src/TxMonitor/hasTx.ts
Expand Up @@ -3,43 +3,42 @@ import { UnknownResultError } from "../errors";
import { InteractionContext } from '../Connection'
import { Query } from '../StateQuery'

export const isHasTxResult = (result: boolean | Error[]): result is boolean =>
(typeof result === 'boolean')


/**
* Ask whether a given transaction is present in the acquired mempool snapshot.
*
* @category TxMonitor
*/
export const hasTx = (context: InteractionContext, id: TxId) =>
Query<
Ogmios['HasTx'],
Ogmios['HasTxResponse'],
Boolean
>({
methodName: 'HasTx',
args: { id }
}, {
handler: (response, resolve, reject) => {
const result = handleHasTxResponse(response)
if (isHasTxResult(result)) {
return resolve(result as Boolean)
} else {
return reject(result as Error[])
Query<
Ogmios['HasTx'],
Ogmios['HasTxResponse'],
boolean
>({
methodName: 'HasTx',
args: { id }
}, {
handler: (response, resolve, reject) => {
try {
resolve(handleHasTxResponse(response))
} catch (e) {
reject(e)
}
}
}
}, context)
}, context)

export const handleHasTxResponse = (response: Ogmios['HasTxResponse']): (boolean | Error[]) => {
try {
const { result } = response
if (result !== undefined) {
return result;
} else {
return [new UnknownResultError(response)]
}
} catch (e) {
return [new UnknownResultError(response)]
}
}
/**
* @internal
*/
export const isHasTxResult = (result: any): result is boolean =>
(typeof result === 'boolean')

/**
* @internal
*/
export const handleHasTxResponse = (response: Ogmios['HasTxResponse']): boolean => {
const { result } = response
if (isHasTxResult(result)) {
return result
}
throw new UnknownResultError(response)
}
85 changes: 52 additions & 33 deletions clients/TypeScript/packages/client/src/TxMonitor/nextTx.ts
@@ -1,44 +1,63 @@
import { Null, Ogmios, TxAlonzo, TxId } from "@cardano-ogmios/schema"
import { UnknownResultError } from "../errors";
import { Ogmios, TxAlonzo, TxId } from "@cardano-ogmios/schema"
import { UnknownResultError } from "../errors"
import { InteractionContext } from '../Connection'
import { Query } from '../StateQuery'

export const isNextTxResult = (result: TxId | TxAlonzo | Null | Error[]): result is TxId | TxAlonzo | Null =>
((typeof (result as TxId) === 'string' || typeof (result as TxAlonzo) === 'object' || typeof (result as Null) === 'object') && !Array.isArray(result))

/**
* Request the next mempool transaction from an acquired snapshot.
*
* @category TxMonitor
*/
export const nextTx = (context: InteractionContext, args?: { fields?: "all"}) =>
Query<
Ogmios['NextTx'],
Ogmios['NextTxResponse'],
TxId | TxAlonzo | Null
>({
methodName: 'NextTx',
args: args
}, {
handler: (response, resolve, reject) => {
const result = handleNextTxResponse(response)
if (isNextTxResult(result)) {
return resolve(result as TxId | TxAlonzo | Null)
} else {
return reject(result as Error[])
export function nextTx (context: InteractionContext, args?: { fields: "all" }) : Promise<TxAlonzo|null>
export function nextTx (context: InteractionContext, args?: {}) : Promise<TxId|null>
export function nextTx (context: InteractionContext, args?: { fields: "all" }) : Promise<TxId|TxAlonzo|null> {
return Query<
Ogmios['NextTx'],
Ogmios['NextTxResponse'],
TxAlonzo | null
>({
methodName: 'NextTx',
args: args
}, {
handler: (response, resolve, reject) => {
try {
resolve(handleNextTxResponse(response, args))
} catch (e) {
reject(e)
}
}
}
}, context)
}, context)
}

/**
* @internal
*/
export const isNextTxResultId = (result: any): result is TxId | null =>
((result as null) === null) || (typeof (result as TxId) === 'string')

export const handleNextTxResponse = (response: Ogmios['NextTxResponse']): (TxId | TxAlonzo | Null | Error[]) => {
try {
const { result } = response
if (result !== undefined) {
return result;
} else {
return [new UnknownResultError(response)]
}
} catch (e) {
return [new UnknownResultError(response)]
/**
* @internal
*/
export const isNextTxResultAll = (result: any): result is TxAlonzo | null =>
((result as null) === null) || (typeof (result as TxAlonzo) === 'object')

/**
* @internal
*/
export function handleNextTxResponse (response: Ogmios['NextTxResponse'], args?: { fields: "all" }): (TxAlonzo | null)
export function handleNextTxResponse (response: Ogmios['NextTxResponse'], args?: {}): (TxId | null)
export function handleNextTxResponse (response: Ogmios['NextTxResponse'], args?: { fields: "all" }): (TxId | TxAlonzo | null) {
const { result } = response

if (args.fields === "all") {
if (isNextTxResultAll(result)) {
return result
}
} else {
if (isNextTxResultId(result)) {
return result
}
}
}

throw new UnknownResultError(response)
}
38 changes: 19 additions & 19 deletions clients/TypeScript/packages/client/src/TxMonitor/release.ts
Expand Up @@ -3,9 +3,6 @@ import { UnknownResultError } from "../errors";
import { InteractionContext } from '../Connection'
import { Query } from '../StateQuery'

export const isReleasedResult = (result: string | Error[]): result is string =>
(result === "Released")

/**
* Release a previously acquired mempool snapshot.
*
Expand All @@ -21,24 +18,27 @@ export const release = (context: InteractionContext, args?: {}) =>
args: args
}, {
handler: (response, resolve, reject) => {
const result = handleReleaseResponse(response)
if (isReleasedResult(result)) {
return resolve()
} else {
return reject(result as Error[])
try {
resolve(handleReleaseResponse(response))
} catch (e) {
reject(e)
}
}
}, context)

export const handleReleaseResponse = (response: Ogmios['ReleaseMempoolResponse']): (string | Error[]) => {
try {
const { result } = response
if (result !== undefined) {
return result;
} else {
return [new UnknownResultError(response)]
}
} catch (e) {
return [new UnknownResultError(response)]
/**
* @internal
*/
export const isReleaseResult = (result: any): result is string =>
(result === "Released")

/**
* @internal
*/
export const handleReleaseResponse = (response: Ogmios['ReleaseMempoolResponse']): void => {
const { result } = response
if (isReleaseResult(result)) {
return
}
}
throw new UnknownResultError(response)
}

0 comments on commit 7c60bea

Please sign in to comment.