Skip to content

Commit

Permalink
feat: quickjs plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
ppedziwiatr committed Mar 29, 2024
1 parent 31f02a9 commit e4f6a70
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 3 deletions.
3 changes: 2 additions & 1 deletion src/core/WarpPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ export const knownWarpPlugins = [
'deploy',
'contract-blacklist',
'vm2',
'vrf'
'vrf',
'quickjs'
] as const;
type WarpPluginPartialType = `smartweave-extension-${string}`;
export type WarpKnownPluginType = (typeof knownWarpPlugins)[number];
Expand Down
69 changes: 67 additions & 2 deletions src/core/modules/impl/HandlerExecutorFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { isBrowser } from '../../../utils/utils';
import { Buffer } from 'warp-isomorphic';
import { InteractionState } from '../../../contract/states/InteractionState';
import { WarpLogger } from '../../../logging/WarpLogger';
import { XOR } from 'utils/types/mutually-exclusive';

// 'require' to fix esbuild adding same lib in both cjs and esm format
// https://github.com/evanw/esbuild/issues/1950
Expand Down Expand Up @@ -208,6 +209,15 @@ export class HandlerExecutorFactory implements ExecutorFactory<HandlerApi<unknow
swGlobal: swGlobal,
contractDefinition
});
} else if (warp.hasPlugin('quickjs')) {
const quickJsPlugin = warp.loadPlugin<QuickJsPluginInput, HandlerApi<State>>('quickjs');
return quickJsPlugin.process({
contractSource: contractDefinition.src,
evaluationOptions,
swGlobal: swGlobal,
contractDefinition,
binaryType: 'release_sync'
});
} else {
const contractFunction = new Function(normalizedSource);
const handler = isBrowser()
Expand Down Expand Up @@ -286,18 +296,37 @@ export interface HandlerApi<State> {
export type HandlerResult<State, Result> = {
result: Result;
state: State;
event: InteractionCompleteEvent;
event?: InteractionCompleteEvent;
gasUsed?: number;
};

export type InteractionResult<State, Result> = HandlerResult<State, Result> & {
type WarpInteractionResult<State, Result> = HandlerResult<State, Result> & {
type: InteractionResultType;
errorMessage?: string;
error?: unknown;
originalValidity?: Record<string, boolean>;
originalErrorMessages?: Record<string, string>;
};

export type AoInteractionResult<Result> = {
Memory: string;
Error: string;
Messages: {
target: string;
data: string;
anchor: string;
tags: { name: string; value: string }[];
}[];
Spawns: {
data: string;
anchor: string;
tags: { name: string; value: string }[];
}[];
Output: Result;
};

export type InteractionResult<State, Result> = XOR<WarpInteractionResult<State, Result>, AoInteractionResult<Result>>;

export type InteractionType = 'view' | 'write';

export type ContractInteraction<Input> = {
Expand Down Expand Up @@ -330,3 +359,39 @@ export interface VM2PluginInput {
logger: WarpLogger;
contractDefinition: ContractDefinition<unknown>;
}

export type QuickJsBinaryType = 'release_sync' | 'release_async' | 'debug_sync' | 'debug_async';

export interface QuickJsPluginInput {
contractSource: string;
evaluationOptions: EvaluationOptions;
swGlobal: SmartWeaveGlobal;
contractDefinition: ContractDefinition<unknown>;
binaryType: QuickJsBinaryType;
}

export interface QuickJsOptions {
memoryLimit?: number;
maxStackSize?: number;
interruptCycles?: number;
timeout?: number;
}

export interface QuickJsPluginMessage {
Cron: boolean;
Data: string | Buffer;
Epoch: number;
From: string;
Id: string | undefined;
Nonce: number;
Owner: string;
Signature: string | undefined;
Tags: {
[key: string]: string | undefined;
};
Target: string;
Timestamp: string;
['Block-Height']: string;
['Forwarded-By']: string;
['Hash-Chain']: string;
}
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ export * from './contract/Signature';
export * from './contract/EvaluationOptionsEvaluator';
export * from './contract/deploy/Source';
export * from './contract/deploy/CreateContract';
export * from './contract/states/ContractInteractionState';
export * from './contract/states/InteractionState';

export * from './legacy/gqlResult';
export * from './legacy/smartweave-global';
Expand Down
2 changes: 2 additions & 0 deletions src/utils/types/mutually-exclusive.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
type Without<T, U> = { [P in Exclude<keyof T, keyof U>]?: never };
export type XOR<T, U> = T | U extends object ? (Without<T, U> & U) | (Without<U, T> & T) : T | U;

0 comments on commit e4f6a70

Please sign in to comment.