diff --git a/packages/cwait/package.json b/packages/cwait/package.json index 9314871..4f819f8 100644 --- a/packages/cwait/package.json +++ b/packages/cwait/package.json @@ -3,7 +3,8 @@ "version": "0.0.1", "type": "module", "scripts": { - "build": "yarn g:tsc -p tsconfig.build.json", + "clean": "rm -rf dist", + "build": "yarn clean && yarn g:tsc -p tsconfig.build.json", "dev": "yarn g:tsc -p tsconfig.build.json --watch", "lint": "yarn g:lint .", "publish:lib": "node scripts/publish.js" diff --git a/packages/cwait/src/onchain/context/context.ts b/packages/cwait/src/onchain/context/context.ts index 41513b2..d140bc0 100644 --- a/packages/cwait/src/onchain/context/context.ts +++ b/packages/cwait/src/onchain/context/context.ts @@ -11,7 +11,7 @@ import { CwebTake } from '@coinweb/contract-kit/dist/types/operations/take'; import { getCallParameters, getContractIssuer } from 'lib/onchain'; import { ExecutorMethodArgs, ResolvedOp } from '../../types'; -import { pushAwaitedTask } from '../promisifiedFeatures'; +import { pushAwaitedTask } from '../runtime'; import { extractOps } from './extractOps'; diff --git a/packages/cwait/src/onchain/executor.ts b/packages/cwait/src/onchain/executor.ts deleted file mode 100644 index 1595498..0000000 --- a/packages/cwait/src/onchain/executor.ts +++ /dev/null @@ -1,69 +0,0 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ -import { Context, NewTx, getMethodArguments, isSelfCall } from '@coinweb/contract-kit'; - -import { Task } from '../types'; - -import { context, getRawContext, handleContext } from './context'; -import { getAwaitedTasks } from './promisifiedFeatures'; -import { pushResolvedOp } from './promisifiedFeatures/runtime/resolvedOps'; -import { constructTx } from './utils'; - -let abortExecution: ((result: { isFullyExecuted: boolean; awaitedTasks: Task[] }) => void) | null = null; - -export const executor = (method: (...args: any[]) => Promise) => { - return async (ctx: Context): Promise => { - console.log('executor-start >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>'); - const shouldRestart = handleContext(ctx); - pushResolvedOp(context.ops); - - if (getMethodArguments(getRawContext()).length > 2 && !isSelfCall(ctx)) { - throw new Error('Wrong contract call, check the call arguments'); - } - - if (shouldRestart) { - const awaitedTasks = getAwaitedTasks(); - - return constructTx(awaitedTasks, false); - } - - const execution = new Promise<{ isFullyExecuted: boolean; awaitedTasks: Task[] }>((resolve, reject) => { - abortExecution = resolve; - - method(...context.initialArgs).then( - () => { - console.log('<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< executor-resolved'); - const awaitedTasks = getAwaitedTasks(); - resolve({ isFullyExecuted: true, awaitedTasks }); - }, - (error) => { - console.log(' <<<<<<<<<<<<<<<<<<<<<<<<<<<<<< { - const awaitedTasks = getAwaitedTasks(); - abortExecution?.({ isFullyExecuted: false, awaitedTasks }); - }, 0); - - try { - const { isFullyExecuted, awaitedTasks } = await execution; - - return constructTx(awaitedTasks, isFullyExecuted); - } catch (error) { - console.log('<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< executor-error'); - console.log((error as Error).message); - throw error; - } - }; -}; - -export const stopExecution = () => { - console.log('stopExecution'); - const awaitedTasks = getAwaitedTasks(); - abortExecution?.({ isFullyExecuted: false, awaitedTasks }); -}; diff --git a/packages/cwait/src/onchain/utils/constructTx/constructTx.ts b/packages/cwait/src/onchain/executor/constructTx/constructTx.ts similarity index 61% rename from packages/cwait/src/onchain/utils/constructTx/constructTx.ts rename to packages/cwait/src/onchain/executor/constructTx/constructTx.ts index c91adef..08ee09f 100644 --- a/packages/cwait/src/onchain/utils/constructTx/constructTx.ts +++ b/packages/cwait/src/onchain/executor/constructTx/constructTx.ts @@ -1,8 +1,10 @@ -import { Task } from '../../../types'; +import { getAwaitedTasks } from '../../runtime'; import { prepareTx } from './prepareTxs'; -export const constructTx = (awaitedTasks: Task[], isFullyExecuted: boolean) => { +export const constructTx = (isFullyExecuted: boolean) => { + const awaitedTasks = getAwaitedTasks(); + const { calls, txFee } = prepareTx({ awaitedTasks, isFullyExecuted, txFee: 0n }); const { txs } = prepareTx({ awaitedTasks, isFullyExecuted, txFee, callsCount: calls }); diff --git a/packages/cwait/src/onchain/utils/constructTx/index.ts b/packages/cwait/src/onchain/executor/constructTx/index.ts similarity index 100% rename from packages/cwait/src/onchain/utils/constructTx/index.ts rename to packages/cwait/src/onchain/executor/constructTx/index.ts diff --git a/packages/cwait/src/onchain/utils/constructTx/prepareInThreadTxs.ts b/packages/cwait/src/onchain/executor/constructTx/prepareInThreadTxs.ts similarity index 99% rename from packages/cwait/src/onchain/utils/constructTx/prepareInThreadTxs.ts rename to packages/cwait/src/onchain/executor/constructTx/prepareInThreadTxs.ts index 496580f..5f6c179 100644 --- a/packages/cwait/src/onchain/utils/constructTx/prepareInThreadTxs.ts +++ b/packages/cwait/src/onchain/executor/constructTx/prepareInThreadTxs.ts @@ -22,8 +22,8 @@ import { isPreparedStoreOp, isPreparedTakeOp, isPreparedUnlockOp, -} from '../typeGuards'; -import { uuid } from '../uuid'; +} from '../../utils/opTypeGuards'; +import { uuid } from '../../utils/uuid'; export const prepareInThreadTxs = ({ cwebPerCall, diff --git a/packages/cwait/src/onchain/utils/constructTx/prepareOutThreadTxs.ts b/packages/cwait/src/onchain/executor/constructTx/prepareOutThreadTxs.ts similarity index 98% rename from packages/cwait/src/onchain/utils/constructTx/prepareOutThreadTxs.ts rename to packages/cwait/src/onchain/executor/constructTx/prepareOutThreadTxs.ts index ff9c2bb..d3096f3 100644 --- a/packages/cwait/src/onchain/utils/constructTx/prepareOutThreadTxs.ts +++ b/packages/cwait/src/onchain/executor/constructTx/prepareOutThreadTxs.ts @@ -18,7 +18,7 @@ import { isPreparedStoreOp, isPreparedTakeOp, isPreparedUnlockOp, -} from '../typeGuards'; +} from '../../utils/opTypeGuards'; export const prepareOutThreadTxs = ({ ops, diff --git a/packages/cwait/src/onchain/utils/constructTx/prepareTxs.ts b/packages/cwait/src/onchain/executor/constructTx/prepareTxs.ts similarity index 100% rename from packages/cwait/src/onchain/utils/constructTx/prepareTxs.ts rename to packages/cwait/src/onchain/executor/constructTx/prepareTxs.ts diff --git a/packages/cwait/src/onchain/utils/constructTx/splitTasks.ts b/packages/cwait/src/onchain/executor/constructTx/splitTasks.ts similarity index 100% rename from packages/cwait/src/onchain/utils/constructTx/splitTasks.ts rename to packages/cwait/src/onchain/executor/constructTx/splitTasks.ts diff --git a/packages/cwait/src/onchain/executor/executor.ts b/packages/cwait/src/onchain/executor/executor.ts new file mode 100644 index 0000000..6a31392 --- /dev/null +++ b/packages/cwait/src/onchain/executor/executor.ts @@ -0,0 +1,42 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import { Context, NewTx, getMethodArguments, isSelfCall } from '@coinweb/contract-kit'; + +import { context, getRawContext, handleContext } from '../context'; +import { execLoop, setNextExec, stopExecution } from '../runtime'; +import { pushResolvedOp } from '../runtime/resolvedOps'; + +import { constructTx } from './constructTx'; + +export const executor = (method: (...args: any[]) => Promise) => { + return async (ctx: Context): Promise => { + console.log('executor-start >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>'); + const shouldRestart = handleContext(ctx); + pushResolvedOp(context.ops); + + if (getMethodArguments(getRawContext()).length > 2 && !isSelfCall(ctx)) { + throw new Error('Wrong contract call, check the call arguments'); + } + + if (shouldRestart) { + console.log('<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< executor-finish'); + return constructTx(false); + } + + //@ts-expect-error + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + os.setTimeout(() => { + stopExecution(); + }, 0); + + try { + setNextExec(() => method(...context.initialArgs)); + const isFullyExecuted = await execLoop(); + console.log('<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< executor-finish'); + return constructTx(isFullyExecuted); + } catch (error) { + console.log((error as Error).message); + console.log('<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< executor-error'); + throw error; + } + }; +}; diff --git a/packages/cwait/src/onchain/executor/index.ts b/packages/cwait/src/onchain/executor/index.ts new file mode 100644 index 0000000..78dc04d --- /dev/null +++ b/packages/cwait/src/onchain/executor/index.ts @@ -0,0 +1 @@ +export * from './executor'; diff --git a/packages/cwait/src/onchain/constructCwebMain.ts b/packages/cwait/src/onchain/features/constructCwebMain/constructCwebMain.ts similarity index 90% rename from packages/cwait/src/onchain/constructCwebMain.ts rename to packages/cwait/src/onchain/features/constructCwebMain/constructCwebMain.ts index 3ac7eaa..c47b55a 100644 --- a/packages/cwait/src/onchain/constructCwebMain.ts +++ b/packages/cwait/src/onchain/features/constructCwebMain/constructCwebMain.ts @@ -2,10 +2,9 @@ import { ContractHandlers as ContractHandlersOrig, SELF_REGISTER_HANDLER_NAME } import { selfRegisterHandler } from '@coinweb/self-register'; import { queue } from 'lib/onchain'; -import { addMethodHandler, ContractHandlers, executeHandler } from '../contract-kit'; - -import { executor } from './executor'; -import { mutexMethods } from './mutex'; +import { addMethodHandler, ContractHandlers, executeHandler } from '../../../contract-kit'; +import { executor } from '../../executor'; +import { mutexMethods } from '../../mutex'; // eslint-disable-next-line @typescript-eslint/no-explicit-any export const constructCwebMain = (methods: Record Promise>) => async () => { diff --git a/packages/cwait/src/onchain/features/constructCwebMain/index.ts b/packages/cwait/src/onchain/features/constructCwebMain/index.ts new file mode 100644 index 0000000..1ee0946 --- /dev/null +++ b/packages/cwait/src/onchain/features/constructCwebMain/index.ts @@ -0,0 +1 @@ +export * from './constructCwebMain'; diff --git a/packages/cwait/src/onchain/promisifiedFeatures/features/cwait/cwait.ts b/packages/cwait/src/onchain/features/cwait/cwait.ts similarity index 59% rename from packages/cwait/src/onchain/promisifiedFeatures/features/cwait/cwait.ts rename to packages/cwait/src/onchain/features/cwait/cwait.ts index 633001b..93ee765 100644 --- a/packages/cwait/src/onchain/promisifiedFeatures/features/cwait/cwait.ts +++ b/packages/cwait/src/onchain/features/cwait/cwait.ts @@ -1,12 +1,23 @@ import { constructStore } from '@coinweb/contract-kit/dist/esm/operations/store'; -import { constructResultClaim } from '../../../claims/result'; -import { stopExecution } from '../../../executor'; -import { opMarker } from '../../../global'; -import { isResolvedChildOp, isResolvedExecOp, isResolvedSlotOp } from '../../../utils'; -import { uuid } from '../../../utils'; -import { getAwaitedTasksCount, pushAwaitedTask } from '../../runtime/awaitedTasks'; -import { getUsedOps, saveUsedOps, shiftResolvedOp } from '../../runtime/resolvedOps'; +import { constructResultClaim } from '../../claims/result'; +import { opMarker } from '../../globals/promise'; +import { setNextExec, stopExecution } from '../../runtime'; +import { + freezeAwaitedTasks, + getAwaitedTasksCount, + pushAwaitedTask, + unfreezeAwaitedTasks, +} from '../../runtime/awaitedTasks'; +import { + freezeResolvedOps, + getUsedOps, + saveUsedOps, + shiftResolvedOp, + unfreezeResolvedOps, +} from '../../runtime/resolvedOps'; +import { isResolvedChildOp, isResolvedExecOp, isResolvedSlotOp } from '../../utils'; +import { uuid } from '../../utils'; let isRootDetected = false; @@ -44,13 +55,21 @@ export const cwait = Promise { + unfreezeAwaitedTasks(); + unfreezeResolvedOps(); - if (!getAwaitedTasksCount()) { - pushAwaitedTask(constructStore(constructResultClaim(op.ExecOp.id, getUsedOps()))); - } + saveUsedOps(); + + await asyncCallback(...args); + + if (!getAwaitedTasksCount()) { + pushAwaitedTask(constructStore(constructResultClaim(op.ExecOp.id, getUsedOps()))); + } + }); stopExecution(); diff --git a/packages/cwait/src/onchain/promisifiedFeatures/features/cwait/index.ts b/packages/cwait/src/onchain/features/cwait/index.ts similarity index 100% rename from packages/cwait/src/onchain/promisifiedFeatures/features/cwait/index.ts rename to packages/cwait/src/onchain/features/cwait/index.ts diff --git a/packages/cwait/src/onchain/promisifiedFeatures/features/index.ts b/packages/cwait/src/onchain/features/index.ts similarity index 66% rename from packages/cwait/src/onchain/promisifiedFeatures/features/index.ts rename to packages/cwait/src/onchain/features/index.ts index e13c3d1..330a6d0 100644 --- a/packages/cwait/src/onchain/promisifiedFeatures/features/index.ts +++ b/packages/cwait/src/onchain/features/index.ts @@ -1,3 +1,4 @@ export * from './cwait'; export * from './mutex'; export * from './ops'; +export * from './constructCwebMain'; diff --git a/packages/cwait/src/onchain/promisifiedFeatures/features/mutex/index.ts b/packages/cwait/src/onchain/features/mutex/index.ts similarity index 100% rename from packages/cwait/src/onchain/promisifiedFeatures/features/mutex/index.ts rename to packages/cwait/src/onchain/features/mutex/index.ts diff --git a/packages/cwait/src/onchain/promisifiedFeatures/features/mutex/lock.ts b/packages/cwait/src/onchain/features/mutex/lock.ts similarity index 94% rename from packages/cwait/src/onchain/promisifiedFeatures/features/mutex/lock.ts rename to packages/cwait/src/onchain/features/mutex/lock.ts index 60c8b33..fccbe2a 100644 --- a/packages/cwait/src/onchain/promisifiedFeatures/features/mutex/lock.ts +++ b/packages/cwait/src/onchain/features/mutex/lock.ts @@ -1,8 +1,8 @@ import { getTime } from 'lib/onchain'; -import { opMarker } from '../../../global'; -import { LockedKey } from '../../../mutex'; -import { isResolvedLockOp, isResolvedSlotOp, isResolvedUnlockOp, uuid } from '../../../utils'; +import { opMarker } from '../../globals/promise'; +import { LockedKey } from '../../mutex'; +import { isResolvedLockOp, isResolvedSlotOp, isResolvedUnlockOp, uuid } from '../../utils'; import { pushAwaitedTask, shiftResolvedOp } from '../../runtime'; const unlock = (lockId: string, timestamp: number) => { diff --git a/packages/cwait/src/onchain/promisifiedFeatures/features/ops/block.ts b/packages/cwait/src/onchain/features/ops/block.ts similarity index 88% rename from packages/cwait/src/onchain/promisifiedFeatures/features/ops/block.ts rename to packages/cwait/src/onchain/features/ops/block.ts index 5b0faf5..a2b0048 100644 --- a/packages/cwait/src/onchain/promisifiedFeatures/features/ops/block.ts +++ b/packages/cwait/src/onchain/features/ops/block.ts @@ -1,7 +1,7 @@ import { BlockFilter, constructBlock, extractBlock } from '@coinweb/contract-kit'; -import { opMarker } from '../../../global'; -import { isResolvedBlockOp, isResolvedSlotOp } from '../../../utils'; +import { opMarker } from '../../globals/promise'; +import { isResolvedBlockOp, isResolvedSlotOp } from '../../utils'; import { pushAwaitedTask, shiftResolvedOp } from '../../runtime'; export const blockOp = (filters: BlockFilter[]) => { diff --git a/packages/cwait/src/onchain/promisifiedFeatures/features/ops/index.ts b/packages/cwait/src/onchain/features/ops/index.ts similarity index 100% rename from packages/cwait/src/onchain/promisifiedFeatures/features/ops/index.ts rename to packages/cwait/src/onchain/features/ops/index.ts diff --git a/packages/cwait/src/onchain/promisifiedFeatures/features/ops/rangeRead.ts b/packages/cwait/src/onchain/features/ops/rangeRead.ts similarity index 85% rename from packages/cwait/src/onchain/promisifiedFeatures/features/ops/rangeRead.ts rename to packages/cwait/src/onchain/features/ops/rangeRead.ts index bd2162a..df7fd81 100644 --- a/packages/cwait/src/onchain/promisifiedFeatures/features/ops/rangeRead.ts +++ b/packages/cwait/src/onchain/features/ops/rangeRead.ts @@ -1,10 +1,10 @@ import { Claim, ClaimKey, constructRangeRead, extractRead } from '@coinweb/contract-kit'; import { ClaimRange } from '@coinweb/contract-kit/dist/types/operations/read'; -import { TypedClaim } from '../../../../types'; -import { context } from '../../../context'; -import { opMarker } from '../../../global'; -import { isResolvedReadOp, isResolvedSlotOp } from '../../../utils'; +import { TypedClaim } from '../../../types'; +import { context } from '../../context'; +import { opMarker } from '../../globals/promise'; +import { isResolvedReadOp, isResolvedSlotOp } from '../../utils'; import { pushAwaitedTask, shiftResolvedOp } from '../../runtime'; export const rangeReadOp = ( diff --git a/packages/cwait/src/onchain/promisifiedFeatures/features/ops/read.ts b/packages/cwait/src/onchain/features/ops/read.ts similarity index 82% rename from packages/cwait/src/onchain/promisifiedFeatures/features/ops/read.ts rename to packages/cwait/src/onchain/features/ops/read.ts index 312cd15..d5477b8 100644 --- a/packages/cwait/src/onchain/promisifiedFeatures/features/ops/read.ts +++ b/packages/cwait/src/onchain/features/ops/read.ts @@ -1,9 +1,9 @@ import { Claim, ClaimKey, constructRead, extractRead } from '@coinweb/contract-kit'; -import { TypedClaim } from '../../../../types'; -import { context } from '../../../context'; -import { opMarker } from '../../../global'; -import { isResolvedReadOp, isResolvedSlotOp } from '../../../utils'; +import { TypedClaim } from '../../../types'; +import { context } from '../../context'; +import { opMarker } from '../../globals/promise'; +import { isResolvedReadOp, isResolvedSlotOp } from '../../utils'; import { pushAwaitedTask, shiftResolvedOp } from '../../runtime'; export const readOp = (key: ClaimKey) => { diff --git a/packages/cwait/src/onchain/promisifiedFeatures/features/ops/store.ts b/packages/cwait/src/onchain/features/ops/store.ts similarity index 89% rename from packages/cwait/src/onchain/promisifiedFeatures/features/ops/store.ts rename to packages/cwait/src/onchain/features/ops/store.ts index 432e145..481762e 100644 --- a/packages/cwait/src/onchain/promisifiedFeatures/features/ops/store.ts +++ b/packages/cwait/src/onchain/features/ops/store.ts @@ -1,8 +1,8 @@ import { Claim, constructStore } from '@coinweb/contract-kit'; import { extractStore } from '@coinweb/contract-kit/dist/esm/operations/store'; -import { opMarker } from '../../../global'; -import { isResolvedSlotOp, isResolvedStoreOp } from '../../../utils'; +import { opMarker } from '../../globals/promise'; +import { isResolvedSlotOp, isResolvedStoreOp } from '../../utils'; import { pushAwaitedTask, shiftResolvedOp } from '../../runtime'; export const storeOp = (claim: Claim, storeCweb?: bigint) => { diff --git a/packages/cwait/src/onchain/promisifiedFeatures/features/ops/take.ts b/packages/cwait/src/onchain/features/ops/take.ts similarity index 85% rename from packages/cwait/src/onchain/promisifiedFeatures/features/ops/take.ts rename to packages/cwait/src/onchain/features/ops/take.ts index 05c8dee..56b79ab 100644 --- a/packages/cwait/src/onchain/promisifiedFeatures/features/ops/take.ts +++ b/packages/cwait/src/onchain/features/ops/take.ts @@ -1,8 +1,8 @@ import { Claim, ClaimKey, constructTake, extractTake } from '@coinweb/contract-kit'; -import { TypedClaim } from '../../../../types'; -import { opMarker } from '../../../global'; -import { isResolvedSlotOp, isResolvedTakeOp } from '../../../utils'; +import { TypedClaim } from '../../../types'; +import { opMarker } from '../../globals/promise'; +import { isResolvedSlotOp, isResolvedTakeOp } from '../../utils'; import { pushAwaitedTask, shiftResolvedOp } from '../../runtime'; export const takeOp = (key: ClaimKey) => { diff --git a/packages/cwait/src/onchain/globals/index.ts b/packages/cwait/src/onchain/globals/index.ts new file mode 100644 index 0000000..b0a9756 --- /dev/null +++ b/packages/cwait/src/onchain/globals/index.ts @@ -0,0 +1 @@ +export * from './promise'; diff --git a/packages/cwait/src/onchain/global.ts b/packages/cwait/src/onchain/globals/promise.ts similarity index 91% rename from packages/cwait/src/onchain/global.ts rename to packages/cwait/src/onchain/globals/promise.ts index b2c8c6a..c4f8ba2 100644 --- a/packages/cwait/src/onchain/global.ts +++ b/packages/cwait/src/onchain/globals/promise.ts @@ -1,5 +1,8 @@ -import { markTaskBatch } from './promisifiedFeatures/runtime/awaitedTasks'; -import { getBatchId } from './utils'; +import { markTaskBatch } from '../runtime/awaitedTasks'; + +let batchId = 0; + +const getBatchId = () => batchId++; export const opMarker = Symbol('opMarker'); diff --git a/packages/cwait/src/onchain/index.ts b/packages/cwait/src/onchain/index.ts index b31def1..512d267 100644 --- a/packages/cwait/src/onchain/index.ts +++ b/packages/cwait/src/onchain/index.ts @@ -1,3 +1,3 @@ -export * from './context'; -export * from './promisifiedFeatures/features'; -export * from './constructCwebMain'; +import './globals'; + +export * from './features'; diff --git a/packages/cwait/src/onchain/promisifiedFeatures/index.ts b/packages/cwait/src/onchain/promisifiedFeatures/index.ts deleted file mode 100644 index a66d282..0000000 --- a/packages/cwait/src/onchain/promisifiedFeatures/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './runtime'; -export * from './features'; diff --git a/packages/cwait/src/onchain/promisifiedFeatures/runtime/awaitedTasks.ts b/packages/cwait/src/onchain/runtime/awaitedTasks.ts similarity index 63% rename from packages/cwait/src/onchain/promisifiedFeatures/runtime/awaitedTasks.ts rename to packages/cwait/src/onchain/runtime/awaitedTasks.ts index f1f4ddc..d848ccc 100644 --- a/packages/cwait/src/onchain/promisifiedFeatures/runtime/awaitedTasks.ts +++ b/packages/cwait/src/onchain/runtime/awaitedTasks.ts @@ -1,8 +1,13 @@ -import { PreparedOp, Task } from '../../../types'; +import { PreparedOp, Task } from '../../types'; const awaitedTasks: Task[] = []; +let isFreezed = false; export const pushAwaitedTask = (op: PreparedOp) => { + if (isFreezed) { + return; + } + awaitedTasks.push({ op, batchId: -1 }); }; @@ -15,3 +20,11 @@ export const markTaskBatch = (count: number, batchId: number) => { }; export const getAwaitedTasksCount = () => awaitedTasks.length; + +export const freezeAwaitedTasks = () => { + isFreezed = true; +}; + +export const unfreezeAwaitedTasks = () => { + isFreezed = false; +}; diff --git a/packages/cwait/src/onchain/runtime/execLoop.ts b/packages/cwait/src/onchain/runtime/execLoop.ts new file mode 100644 index 0000000..da06ae4 --- /dev/null +++ b/packages/cwait/src/onchain/runtime/execLoop.ts @@ -0,0 +1,41 @@ +let abortExecution: ((isFullyExecuted: boolean) => void) | null = null; + +export const stopExecution = (isFullyExecuted = false) => { + console.log('stopExecution'); + abortExecution?.(isFullyExecuted); +}; + +type ExecTask = () => Promise; + +let execQueue: ExecTask[] = []; +export const setNextExec = (task: ExecTask) => (execQueue = [task]); + +export const execLoop = async (): Promise => { + const nextExec = execQueue.pop(); + + if (nextExec) { + const execution = new Promise((resolve, reject) => { + abortExecution = resolve; + + nextExec().then( + () => { + resolve(true); + }, + (error) => { + console.log(error); + reject(error); + } + ); + }); + + const isFullyExecuted = await execution; + + if (isFullyExecuted) { + return true; + } + + return execLoop(); + } + + return false; +}; diff --git a/packages/cwait/src/onchain/promisifiedFeatures/runtime/index.ts b/packages/cwait/src/onchain/runtime/index.ts similarity index 69% rename from packages/cwait/src/onchain/promisifiedFeatures/runtime/index.ts rename to packages/cwait/src/onchain/runtime/index.ts index 7478a6d..bf12790 100644 --- a/packages/cwait/src/onchain/promisifiedFeatures/runtime/index.ts +++ b/packages/cwait/src/onchain/runtime/index.ts @@ -1,2 +1,3 @@ export * from './awaitedTasks'; +export * from './execLoop'; export * from './resolvedOps'; diff --git a/packages/cwait/src/onchain/promisifiedFeatures/runtime/resolvedOps.ts b/packages/cwait/src/onchain/runtime/resolvedOps.ts similarity index 66% rename from packages/cwait/src/onchain/promisifiedFeatures/runtime/resolvedOps.ts rename to packages/cwait/src/onchain/runtime/resolvedOps.ts index 8c7f236..1cb6a4f 100644 --- a/packages/cwait/src/onchain/promisifiedFeatures/runtime/resolvedOps.ts +++ b/packages/cwait/src/onchain/runtime/resolvedOps.ts @@ -1,11 +1,16 @@ -import { ResolvedOp } from '../../../types'; +import { ResolvedOp } from '../../types'; const resolvedOps: ResolvedOp[] = []; let usedOps: ResolvedOp[] = []; let isSavingUsed = false; +let isFreezed = false; export const pushResolvedOp = (op: ResolvedOp | ResolvedOp[]) => { + if (isFreezed) { + return; + } + if (Array.isArray(op)) { resolvedOps.push(...op); } else { @@ -15,8 +20,8 @@ export const pushResolvedOp = (op: ResolvedOp | ResolvedOp[]) => { export const shiftResolvedOp = () => { const result = { - isOp: resolvedOps.length > 0, - op: resolvedOps.shift(), + isOp: resolvedOps.length > 0 && !isFreezed, + op: isFreezed ? undefined : resolvedOps.shift(), } as | { isOp: true; @@ -40,3 +45,11 @@ export const saveUsedOps = () => { usedOps = []; isSavingUsed = true; }; + +export const freezeResolvedOps = () => { + isFreezed = true; +}; + +export const unfreezeResolvedOps = () => { + isFreezed = false; +}; diff --git a/packages/cwait/src/onchain/utils/batchId.ts b/packages/cwait/src/onchain/utils/batchId.ts deleted file mode 100644 index 3880b73..0000000 --- a/packages/cwait/src/onchain/utils/batchId.ts +++ /dev/null @@ -1,3 +0,0 @@ -let batchId = 0; - -export const getBatchId = () => batchId++; diff --git a/packages/cwait/src/onchain/utils/callstack.ts b/packages/cwait/src/onchain/utils/callstack.ts deleted file mode 100644 index ea22049..0000000 --- a/packages/cwait/src/onchain/utils/callstack.ts +++ /dev/null @@ -1,10 +0,0 @@ -export const getStack = ({ skip = 0 }: { skip?: number } = {}) => - new Error().stack - ?.split('\n') - .slice(2 + skip) - .map((line) => { - const match = line.match(/at\s+([^\s(]+)/); - return match ? match[1] : ''; - }) - .filter((name) => name && name !== 'Promise') - .join('@') || ''; diff --git a/packages/cwait/src/onchain/utils/index.ts b/packages/cwait/src/onchain/utils/index.ts index d9e397c..b72ca62 100644 --- a/packages/cwait/src/onchain/utils/index.ts +++ b/packages/cwait/src/onchain/utils/index.ts @@ -1,5 +1,2 @@ -export * from './batchId'; -export * from './callstack'; -export * from './constructTx'; -export * from './typeGuards'; +export * from './opTypeGuards'; export * from './uuid'; diff --git a/packages/cwait/src/onchain/utils/typeGuards.ts b/packages/cwait/src/onchain/utils/opTypeGuards.ts similarity index 100% rename from packages/cwait/src/onchain/utils/typeGuards.ts rename to packages/cwait/src/onchain/utils/opTypeGuards.ts diff --git a/packages/cwait/tsconfig.json b/packages/cwait/tsconfig.json index 5611da8..e84c22c 100644 --- a/packages/cwait/tsconfig.json +++ b/packages/cwait/tsconfig.json @@ -9,5 +9,5 @@ "esModuleInterop": true, "types": ["vitest/globals"] }, - "include": ["**/*.ts", "vitest.*.ts", "__tests__", "scripts/publish.js", "src/onchain/utils"] + "include": ["**/*.ts", "vitest.*.ts", "__tests__", "scripts/publish.js", "src/onchain/utils", "src/onchain/executor/constructTx"] }