diff --git a/canister_templates/experimental.wasm b/canister_templates/experimental.wasm index af4b4df531..36dd5567c4 100644 Binary files a/canister_templates/experimental.wasm and b/canister_templates/experimental.wasm differ diff --git a/src/build/experimental/commands/compile/candid_and_method_meta.ts b/src/build/experimental/commands/compile/candid_and_method_meta.ts index ed3421e8d8..e0dce1bd6e 100644 --- a/src/build/experimental/commands/compile/candid_and_method_meta.ts +++ b/src/build/experimental/commands/compile/candid_and_method_meta.ts @@ -66,21 +66,21 @@ async function handleHttp(): Promise { ).toString(); const methodMeta: MethodMeta = { + init: { name: 'init', index: 0 }, + post_upgrade: { name: 'postUpgrade', index: 1 }, queries: [ { name: 'http_request', - index: 0, + index: 2, composite: true } ], updates: [ { name: 'http_request_update', - index: 1 + index: 3 } - ], - init: { name: 'init', index: 2 }, - post_upgrade: { name: 'postUpgrade', index: 3 } + ] }; return { diff --git a/src/build/experimental/commands/compile/wasm_binary/rust/experimental_canister_template/src/candid.rs b/src/build/experimental/commands/compile/wasm_binary/rust/experimental_canister_template/src/candid.rs index a0c78ae82e..323eae214f 100644 --- a/src/build/experimental/commands/compile/wasm_binary/rust/experimental_canister_template/src/candid.rs +++ b/src/build/experimental/commands/compile/wasm_binary/rust/experimental_canister_template/src/candid.rs @@ -58,11 +58,6 @@ pub fn get_candid_and_method_meta_pointer() -> *mut std::os::raw::c_char { .get_global() .set("_azleCallbacks", context.new_object().into()); - context.get_global().set( - "_azleCanisterMethodsIndex", - wasmedge_quickjs::JsValue::Int(0), - ); - context.get_global().set("_azleMethodMeta", { let mut method_meta = context.new_object(); method_meta.set("queries", context.new_array().into()); diff --git a/src/build/experimental/commands/compile/wasm_binary/rust/experimental_canister_template/src/init_and_post_upgrade.rs b/src/build/experimental/commands/compile/wasm_binary/rust/experimental_canister_template/src/init_and_post_upgrade.rs index bf7c40eb9b..0c6ec781f8 100644 --- a/src/build/experimental/commands/compile/wasm_binary/rust/experimental_canister_template/src/init_and_post_upgrade.rs +++ b/src/build/experimental/commands/compile/wasm_binary/rust/experimental_canister_template/src/init_and_post_upgrade.rs @@ -140,11 +140,6 @@ pub fn initialize_js( .get_global() .set("_azleCallbacks", context.new_object().into()); - context.get_global().set( - "_azleCanisterMethodsIndex", - wasmedge_quickjs::JsValue::Int(0), - ); - context.get_global().set("_azleMethodMeta", { let mut method_meta = context.new_object(); method_meta.set("queries", context.new_array().into()); diff --git a/src/lib/experimental/candid/types/reference/service/canister_function/index.ts b/src/lib/experimental/candid/types/reference/service/canister_function/index.ts index 563691efea..fd0e1fead6 100644 --- a/src/lib/experimental/candid/types/reference/service/canister_function/index.ts +++ b/src/lib/experimental/candid/types/reference/service/canister_function/index.ts @@ -2,18 +2,18 @@ import '../../../../../experimental'; import { IDL } from '@dfinity/candid'; -import { MethodMeta } from '../../../../../../../build/stable/utils/types'; +import { + Method, + MethodMeta +} from '../../../../../../../build/stable/utils/types'; import { CanisterMethodInfo } from '../../../../../canister_methods/types/canister_method_info'; +import { Callbacks } from '../../../../../globals'; import { ic } from '../../../../../ic'; import { CandidType, Parent, toIdlTypeArray } from '../../../../index'; import { _AzleRecursiveFunction } from '../../../../recursive'; import { decode, encode } from '../../../../serde'; import { Principal } from '../../principal'; -import { createQueryMethods, createUpdateMethods } from './query_update'; -import { - createGetSystemFunctionIdlTypeFunction, - createSystemMethod -} from './system_methods'; +import { createGetSystemFunctionIdlTypeFunction } from './system_methods'; export type CanisterOptions = { [key: string]: CanisterMethodInfo; @@ -52,28 +52,11 @@ export function createCanisterFunction( ): _AzleFunctionReturnType { let canister = createCanisterFunctionBase(canisterOptions); - canister.methodMeta = {}; - canister.methodMeta.init = createSystemMethod('init', canisterOptions); - canister.methodMeta.heartbeat = createSystemMethod( - 'heartbeat', - canisterOptions - ); - canister.methodMeta.post_upgrade = createSystemMethod( - 'postUpgrade', - canisterOptions - ); - canister.methodMeta.pre_upgrade = createSystemMethod( - 'preUpgrade', - canisterOptions - ); - canister.methodMeta.inspect_message = createSystemMethod( - 'inspectMessage', - canisterOptions - ); - canister.methodMeta.queries = createQueryMethods(canisterOptions); - canister.methodMeta.updates = createUpdateMethods(canisterOptions); + const { callbacks, methodMeta } = + createCallbacksAndMethodMeta(canisterOptions); - canister.callbacks = createCallbacks(canisterOptions); + canister.callbacks = callbacks; + canister.methodMeta = methodMeta; canister.getIdlType = createGetIdlTypeFunction(canisterOptions); canister.getSystemFunctionIdlTypes = @@ -138,17 +121,107 @@ function createUpdateOrQueryFunctionIdlType( return IDL.Func(paramIdlTypes, returnIdlType, annotations); } -function createCallbacks( - canisterOptions: CanisterOptions -): Record any) | undefined> { - return Object.entries(canisterOptions).reduce((acc, entry) => { - const canisterMethod = entry[1]; +function createCallbacksAndMethodMeta(canisterOptions: CanisterOptions): { + callbacks: Callbacks; + methodMeta: MethodMeta; +} { + return Object.entries(canisterOptions).reduce( + (acc, [canisterMethodName, canisterMethodInfo], index) => { + const methodMeta = getMethodMeta( + canisterMethodName, + index, + canisterMethodInfo + ); + + const queries = [ + ...(acc.methodMeta.queries ?? []), + ...(methodMeta.queries ?? []) + ]; + + const updates = [ + ...(acc.methodMeta.updates ?? []), + ...(methodMeta.updates ?? []) + ]; + + return { + callbacks: { + ...acc.callbacks, + [index.toString()]: canisterMethodInfo.callback! + }, + methodMeta: { + ...acc.methodMeta, + ...methodMeta, + queries, + updates + } + }; + }, + { + callbacks: {} as Callbacks, + methodMeta: {} as MethodMeta + } + ); +} + +function getMethodMeta( + canisterMethodName: string, + index: number, + canisterMethodInfo: CanisterMethodInfo +): MethodMeta { + const method: Method = { + name: canisterMethodName, + index, + composite: + canisterMethodInfo.mode === 'query' + ? canisterMethodInfo.async + : undefined + }; + + if (canisterMethodInfo.mode === 'init') { + return { + init: method + }; + } + + if (canisterMethodInfo.mode === 'postUpgrade') { + return { + post_upgrade: method + }; + } + + if (canisterMethodInfo.mode === 'preUpgrade') { + return { + pre_upgrade: method + }; + } + + if (canisterMethodInfo.mode === 'inspectMessage') { + return { + inspect_message: method + }; + } + if (canisterMethodInfo.mode === 'heartbeat') { return { - ...acc, - [canisterMethod.index.toString()]: canisterMethod.callback + heartbeat: method }; - }, {}); + } + + if (canisterMethodInfo.mode === 'query') { + return { + queries: [method] + }; + } + + if (canisterMethodInfo.mode === 'update') { + return { + updates: [method] + }; + } + + throw new Error( + `Invalid method mode: ${canisterMethodInfo.mode} for method: ${canisterMethodName}` + ); } function createCanisterFunctionBase( diff --git a/src/lib/experimental/candid/types/reference/service/canister_function/query_update.ts b/src/lib/experimental/candid/types/reference/service/canister_function/query_update.ts deleted file mode 100644 index 2ab0853336..0000000000 --- a/src/lib/experimental/candid/types/reference/service/canister_function/query_update.ts +++ /dev/null @@ -1,57 +0,0 @@ -import '../../../../../experimental'; - -import { CanisterOptions } from '.'; - -type QueryMethod = { - name: string; - composite: boolean; - index: number; -}; - -type UpdateMethod = { - name: string; - index: number; -}; - -export function createQueryMethods( - canisterOptions: CanisterOptions -): QueryMethod[] { - return Object.entries(canisterOptions) - .filter(([_name, canisterMethod]) => canisterMethod.mode === 'query') - .map(([methodName, canisterMethod]) => - createQueryMethod( - methodName, - canisterMethod.async, - canisterMethod.index - ) - ); -} - -export function createUpdateMethods( - canisterOptions: CanisterOptions -): UpdateMethod[] { - return Object.entries(canisterOptions) - .filter(([_name, canisterMethod]) => canisterMethod.mode === 'update') - .map(([methodName, canisterMethod]) => - createUpdateMethod(methodName, canisterMethod.index) - ); -} - -function createQueryMethod( - methodName: string, - isComposite: boolean, - index: number -): QueryMethod { - return { - name: methodName, - composite: isComposite, - index - }; -} - -function createUpdateMethod(methodName: string, index: number): UpdateMethod { - return { - name: methodName, - index - }; -} diff --git a/src/lib/experimental/candid/types/reference/service/canister_function/system_methods.ts b/src/lib/experimental/candid/types/reference/service/canister_function/system_methods.ts index 099cbad56e..944e30e16b 100644 --- a/src/lib/experimental/candid/types/reference/service/canister_function/system_methods.ts +++ b/src/lib/experimental/candid/types/reference/service/canister_function/system_methods.ts @@ -6,29 +6,6 @@ import { Parent, toIdlTypeArray } from '../../../../index'; import { _AzleRecursiveFunction } from '../../../../recursive'; import { CanisterOptions, ServiceFunctionInfo } from '.'; -type SystemMethod = { name: string; index: number } | undefined; - -export function createSystemMethod( - mode: - | 'init' - | 'postUpgrade' - | 'preUpgrade' - | 'heartbeat' - | 'inspectMessage', - canisterOptions: CanisterOptions -): SystemMethod { - const methodOption = Object.entries(canisterOptions).find( - ([_methodName, canisterMethod]) => canisterMethod.mode === mode - ); - if (methodOption === undefined) { - return undefined; - } - return { - name: methodOption[0], - index: methodOption[1].index - }; -} - export function createGetSystemFunctionIdlTypeFunction( canisterOptions: CanisterOptions ) { diff --git a/src/lib/experimental/canister_methods/methods/heartbeat.ts b/src/lib/experimental/canister_methods/methods/heartbeat.ts index 1f20d4ebf9..81b2f67b26 100644 --- a/src/lib/experimental/canister_methods/methods/heartbeat.ts +++ b/src/lib/experimental/canister_methods/methods/heartbeat.ts @@ -13,8 +13,7 @@ export function heartbeat( callback: () => executeHeartbeat(callback), paramCandidTypes: [], returnCandidType: Void, - async: isAsync(callback), - index: globalThis._azleCanisterMethodsIndex++ + async: isAsync(callback) }; } diff --git a/src/lib/experimental/canister_methods/methods/init.ts b/src/lib/experimental/canister_methods/methods/init.ts index 4bcfe20fa7..b7641d9abb 100644 --- a/src/lib/experimental/canister_methods/methods/init.ts +++ b/src/lib/experimental/canister_methods/methods/init.ts @@ -14,8 +14,7 @@ export function init< paramCandidTypes: Params, callback?: Awaited> extends TypeMapping ? GenericCallback - : never, - noop?: boolean + : never ): CanisterMethodInfo { const finalCallback = callback === undefined @@ -36,7 +35,6 @@ export function init< callback: finalCallback, paramCandidTypes: paramCandidTypes as any, returnCandidType: Void, - async: false, - index: noop === true ? 0 : globalThis._azleCanisterMethodsIndex++ + async: false }; } diff --git a/src/lib/experimental/canister_methods/methods/inspect_message.ts b/src/lib/experimental/canister_methods/methods/inspect_message.ts index 526061f9ba..d8622a0123 100644 --- a/src/lib/experimental/canister_methods/methods/inspect_message.ts +++ b/src/lib/experimental/canister_methods/methods/inspect_message.ts @@ -16,7 +16,6 @@ export function inspectMessage( callback: finalCallback, paramCandidTypes: [], returnCandidType: Void, - async: false, - index: globalThis._azleCanisterMethodsIndex++ + async: false }; } diff --git a/src/lib/experimental/canister_methods/methods/post_upgrade.ts b/src/lib/experimental/canister_methods/methods/post_upgrade.ts index 5e96ff6c9b..56edafaf4b 100644 --- a/src/lib/experimental/canister_methods/methods/post_upgrade.ts +++ b/src/lib/experimental/canister_methods/methods/post_upgrade.ts @@ -14,8 +14,7 @@ export function postUpgrade< paramCandidTypes: Params, callback?: Awaited> extends TypeMapping ? GenericCallback - : never, - noop?: boolean + : never ): CanisterMethodInfo { const finalCallback = callback === undefined @@ -36,7 +35,6 @@ export function postUpgrade< callback: finalCallback, paramCandidTypes: paramCandidTypes as unknown as CandidType[], returnCandidType: Void, - async: false, - index: noop === true ? 0 : globalThis._azleCanisterMethodsIndex++ + async: false }; } diff --git a/src/lib/experimental/canister_methods/methods/pre_upgrade.ts b/src/lib/experimental/canister_methods/methods/pre_upgrade.ts index 58acf554f8..9a0c673877 100644 --- a/src/lib/experimental/canister_methods/methods/pre_upgrade.ts +++ b/src/lib/experimental/canister_methods/methods/pre_upgrade.ts @@ -12,7 +12,6 @@ export function preUpgrade( callback, paramCandidTypes: [], returnCandidType: Void, - async: isAsync(callback), - index: globalThis._azleCanisterMethodsIndex++ + async: isAsync(callback) }; } diff --git a/src/lib/experimental/canister_methods/methods/query.ts b/src/lib/experimental/canister_methods/methods/query.ts index 1bb7525bc8..da7fa61419 100644 --- a/src/lib/experimental/canister_methods/methods/query.ts +++ b/src/lib/experimental/canister_methods/methods/query.ts @@ -18,8 +18,7 @@ export function query< callback?: Awaited> extends TypeMapping ? GenericCallback : never, - methodArgs?: MethodArgs, - noop?: boolean + methodArgs?: MethodArgs ): CanisterMethodInfo { // TODO maybe the cross canister callback should be made here? const finalCallback = @@ -41,7 +40,6 @@ export function query< callback: finalCallback, paramCandidTypes: paramCandidTypes as unknown as CandidType[], returnCandidType, - async: callback === undefined ? false : isAsync(callback), - index: noop === true ? 0 : globalThis._azleCanisterMethodsIndex++ + async: callback === undefined ? false : isAsync(callback) }; } diff --git a/src/lib/experimental/canister_methods/methods/update.ts b/src/lib/experimental/canister_methods/methods/update.ts index a9c66e976d..a3452ad7ce 100644 --- a/src/lib/experimental/canister_methods/methods/update.ts +++ b/src/lib/experimental/canister_methods/methods/update.ts @@ -18,8 +18,7 @@ export function update< callback?: Awaited> extends TypeMapping ? GenericCallback : never, - methodArgs?: MethodArgs, - noop?: boolean + methodArgs?: MethodArgs ): CanisterMethodInfo { const finalCallback = callback === undefined @@ -40,7 +39,6 @@ export function update< callback: finalCallback, paramCandidTypes: paramCandidTypes as unknown as CandidType[], returnCandidType, - async: callback === undefined ? false : isAsync(callback), - index: noop === true ? 0 : globalThis._azleCanisterMethodsIndex++ + async: callback === undefined ? false : isAsync(callback) }; } diff --git a/src/lib/experimental/canister_methods/types/canister_method_info.ts b/src/lib/experimental/canister_methods/types/canister_method_info.ts index 7edb34c88a..3b31f2753d 100644 --- a/src/lib/experimental/canister_methods/types/canister_method_info.ts +++ b/src/lib/experimental/canister_methods/types/canister_method_info.ts @@ -17,5 +17,4 @@ export type CanisterMethodInfo, K> = { callback?: (...args: any) => any; paramCandidTypes: any[]; returnCandidType: any; - index: number; }; diff --git a/src/lib/experimental/globals.ts b/src/lib/experimental/globals.ts index 26bebf2f07..bcbd86290e 100644 --- a/src/lib/experimental/globals.ts +++ b/src/lib/experimental/globals.ts @@ -11,7 +11,7 @@ import { v4 } from 'uuid'; import { MethodMeta } from '../../build/stable/utils/types'; import { azleFetch } from './fetch'; -type Callbacks = { +export type Callbacks = { [key: string]: (...args: any) => any; }; @@ -19,8 +19,6 @@ declare global { // eslint-disable-next-line no-var var _azleCallbacks: Callbacks; // eslint-disable-next-line no-var - var _azleCanisterMethodsIndex: number; - // eslint-disable-next-line no-var var _azleMethodMeta: MethodMeta; // eslint-disable-next-line no-var var _azleOutgoingHttpOptionsSubnetSize: number | undefined; diff --git a/type_tests/canister_methods/init.ts b/type_tests/canister_methods/init.ts index 8ea82088c2..4b5b4f3408 100644 --- a/type_tests/canister_methods/init.ts +++ b/type_tests/canister_methods/init.ts @@ -42,6 +42,5 @@ init( }> > >; - }, - true + } ); diff --git a/type_tests/canister_methods/post_upgrade.ts b/type_tests/canister_methods/post_upgrade.ts index 44b283d78a..f8017f0f60 100644 --- a/type_tests/canister_methods/post_upgrade.ts +++ b/type_tests/canister_methods/post_upgrade.ts @@ -42,6 +42,5 @@ postUpgrade( }> > >; - }, - true + } ); diff --git a/type_tests/canister_methods/query.ts b/type_tests/canister_methods/query.ts index 3079726347..490977a324 100644 --- a/type_tests/canister_methods/query.ts +++ b/type_tests/canister_methods/query.ts @@ -49,6 +49,5 @@ query( return param2; }, - undefined, - true + undefined ); diff --git a/type_tests/canister_methods/update.ts b/type_tests/canister_methods/update.ts index df474a88db..9667b75139 100644 --- a/type_tests/canister_methods/update.ts +++ b/type_tests/canister_methods/update.ts @@ -49,6 +49,5 @@ update( return param2; }, - undefined, - true + undefined );