Skip to content

Commit

Permalink
clean up canister methods
Browse files Browse the repository at this point in the history
  • Loading branch information
bdemann committed Oct 4, 2023
1 parent a80eb9b commit 43fad0d
Show file tree
Hide file tree
Showing 9 changed files with 160 additions and 210 deletions.
87 changes: 36 additions & 51 deletions src/lib/candid/types/reference/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,6 @@ type CanisterOptions = {
[key: string]: CanisterMethodInfo<any, any>;
};

type _AzleCanisterOptions = {
[key: string]: (
parentOrUndefined: _AzleRecursiveFunction | undefined
) => CanisterMethodInfo<any, any>;
};

type _AzleFunctionReturnType = {
(principal: Principal): void;
init?: any;
Expand Down Expand Up @@ -57,20 +51,13 @@ type CallableObject<T extends CanisterOptions> = {
} & CanisterReturn<T>;

export function Canister<T extends CanisterOptions>(
serviceOptions: T
canisterOptions: T
): CallableObject<T> & { _azleCandidType?: '_azleCandidType' } {
const _azleCanisterOptions =
serviceOptions as unknown as _AzleCanisterOptions;
let result: _AzleCanisterReturnType = (parentOrPrincipal: any) => {
const originalPrincipal = parentOrPrincipal;
const parentOrUndefined =
parentOrPrincipal !== undefined && parentOrPrincipal._isPrincipal
? undefined
: parentOrPrincipal;
const callbacks = Object.entries(_azleCanisterOptions).reduce(
const callbacks = Object.entries(canisterOptions).reduce(
(acc, entry) => {
const key = entry[0];
const value = entry[1](parentOrUndefined);
const value = entry[1];

return {
...acc,
Expand All @@ -91,8 +78,8 @@ export function Canister<T extends CanisterOptions>(
{}
);

const initOption = Object.entries(_azleCanisterOptions).find(
([key, value]) => value(parentOrUndefined).mode === 'init'
const initOption = Object.entries(canisterOptions).find(
([key, value]) => value.mode === 'init'
);
const init =
initOption === undefined
Expand All @@ -101,8 +88,8 @@ export function Canister<T extends CanisterOptions>(
name: initOption[0]
};

const postUpgradeOption = Object.entries(_azleCanisterOptions).find(
([key, value]) => value(parentOrUndefined).mode === 'postUpgrade'
const postUpgradeOption = Object.entries(canisterOptions).find(
([key, value]) => value.mode === 'postUpgrade'
);
const postUpgrade =
postUpgradeOption === undefined
Expand All @@ -111,8 +98,8 @@ export function Canister<T extends CanisterOptions>(
name: postUpgradeOption[0]
};

const preUpgradeOption = Object.entries(_azleCanisterOptions).find(
([key, value]) => value(parentOrUndefined).mode === 'preUpgrade'
const preUpgradeOption = Object.entries(canisterOptions).find(
([key, value]) => value.mode === 'preUpgrade'
);
const preUpgrade =
preUpgradeOption === undefined
Expand All @@ -121,8 +108,8 @@ export function Canister<T extends CanisterOptions>(
name: preUpgradeOption[0]
};

const heartbeatOption = Object.entries(_azleCanisterOptions).find(
([key, value]) => value(parentOrUndefined).mode === 'heartbeat'
const heartbeatOption = Object.entries(canisterOptions).find(
([key, value]) => value.mode === 'heartbeat'
);
const heartbeat =
heartbeatOption === undefined
Expand All @@ -131,8 +118,8 @@ export function Canister<T extends CanisterOptions>(
name: heartbeatOption[0]
};

const inspectMessageOption = Object.entries(_azleCanisterOptions).find(
([key, value]) => value(parentOrUndefined).mode === 'inspectMessage'
const inspectMessageOption = Object.entries(canisterOptions).find(
([key, value]) => value.mode === 'inspectMessage'
);
const inspectMessage =
inspectMessageOption === undefined
Expand All @@ -141,16 +128,16 @@ export function Canister<T extends CanisterOptions>(
name: inspectMessageOption[0]
};

const queries = Object.entries(_azleCanisterOptions)
const queries = Object.entries(canisterOptions)
.filter((entry) => {
const key = entry[0];
const value = entry[1](parentOrUndefined);
const value = entry[1];

return value.mode === 'query';
})
.map((entry) => {
const key = entry[0];
const value = entry[1](parentOrUndefined);
const value = entry[1];

return {
name: key,
Expand All @@ -159,16 +146,16 @@ export function Canister<T extends CanisterOptions>(
};
});

const updates = Object.entries(_azleCanisterOptions)
const updates = Object.entries(canisterOptions)
.filter((entry) => {
const key = entry[0];
const value = entry[1](parentOrUndefined);
const value = entry[1];

return value.mode === 'update';
})
.map((entry) => {
const key = entry[0];
const value = entry[1](parentOrUndefined);
const value = entry[1];

return {
name: key,
Expand All @@ -179,10 +166,10 @@ export function Canister<T extends CanisterOptions>(
let returnFunction: _AzleFunctionReturnType = (
principal: Principal
) => {
const callbacks = Object.entries(_azleCanisterOptions).reduce(
const callbacks = Object.entries(canisterOptions).reduce(
(acc, entry) => {
const key = entry[0];
const value = entry[1](parentOrUndefined);
const value = entry[1];

return {
...acc,
Expand Down Expand Up @@ -220,23 +207,22 @@ export function Canister<T extends CanisterOptions>(
returnFunction.getSystemFunctionIDLs = (
parents: Parent[]
): IDL.FuncClass[] => {
const serviceFunctionInfo =
_azleCanisterOptions as unknown as ServiceFunctionInfo;
const serviceFunctionInfo = canisterOptions as ServiceFunctionInfo;

return Object.entries(serviceFunctionInfo).reduce(
(accumulator, [_methodName, functionInfo]) => {
const mode = functionInfo(parentOrUndefined).mode;
const mode = functionInfo.mode;
if (mode === 'update' || mode === 'query') {
// We don't want init, post upgrade, etc showing up in the idl
return accumulator;
}

const paramRealIdls = toParamIDLTypes(
functionInfo(parentOrUndefined).paramCandidTypes,
functionInfo.paramCandidTypes,
parents
);
const returnRealIdl = toReturnIDLType(
functionInfo(parentOrUndefined).returnCandidType,
functionInfo.returnCandidType,
parents
);
return [
Expand All @@ -248,21 +234,20 @@ export function Canister<T extends CanisterOptions>(
);
};
returnFunction.getIDL = (parents: Parent[]): IDL.ServiceClass => {
const serviceFunctionInfo =
_azleCanisterOptions as unknown as ServiceFunctionInfo;
const serviceFunctionInfo = canisterOptions as ServiceFunctionInfo;

const record = Object.entries(serviceFunctionInfo).reduce(
(accumulator, [methodName, functionInfo]) => {
const paramRealIdls = toParamIDLTypes(
functionInfo(parentOrUndefined).paramCandidTypes,
const paramIdlTypes = toParamIDLTypes(
functionInfo.paramCandidTypes,
parents
);
const returnRealIdl = toReturnIDLType(
functionInfo(parentOrUndefined).returnCandidType,
const returnIdlTypes = toReturnIDLType(
functionInfo.returnCandidType,
parents
);

const mode = functionInfo(parentOrUndefined).mode;
const mode = functionInfo.mode;
let annotations: string[] = [];
if (mode === 'update') {
// do nothing
Expand All @@ -276,8 +261,8 @@ export function Canister<T extends CanisterOptions>(
return {
...accumulator,
[methodName]: IDL.Func(
paramRealIdls,
returnRealIdl,
paramIdlTypes,
returnIdlTypes,
annotations
)
};
Expand All @@ -288,8 +273,8 @@ export function Canister<T extends CanisterOptions>(
return IDL.Service(record);
};

if (originalPrincipal !== undefined && originalPrincipal._isPrincipal) {
return returnFunction(originalPrincipal);
if (parentOrPrincipal !== undefined && parentOrPrincipal._isPrincipal) {
return returnFunction(parentOrPrincipal);
}

return returnFunction;
Expand Down Expand Up @@ -364,5 +349,5 @@ type FunctionInfo = {
};

interface ServiceFunctionInfo {
[key: string]: (parent: _AzleRecursiveFunction | undefined) => FunctionInfo;
[key: string]: FunctionInfo;
}
24 changes: 11 additions & 13 deletions src/lib/canister_methods/heartbeat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,16 @@ import { Void } from '../candid/types/primitive/void';
export function heartbeat(
callback: () => void | Promise<void>
): CanisterMethodInfo<[], Void> {
return (() => {
const finalCallback = (...args: any[]) => {
executeMethod('heartbeat', args, callback, [], Void, false, []);
};
const finalCallback = (...args: any[]) => {
executeMethod('heartbeat', args, callback, [], Void, false);
};

return {
mode: 'heartbeat',
callback: finalCallback,
paramCandidTypes: [],
returnCandidType: Void,
async: isAsync(callback),
guard: undefined
} as CanisterMethodInfo<[], Void>;
}) as any;
return {
mode: 'heartbeat',
callback: finalCallback,
paramCandidTypes: [],
returnCandidType: Void,
async: isAsync(callback),
guard: undefined
};
}
15 changes: 4 additions & 11 deletions src/lib/canister_methods/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { AzleVoid } from '../candid/types/primitive/void';
import { ic } from '../ic';
import { CandidType, TypeMapping, Parent } from '../candid';
import { CandidType, TypeMapping } from '../candid';
import { decodeMultiple, encode } from '../candid/serde';

export * from './heartbeat';
Expand Down Expand Up @@ -46,8 +46,7 @@ export function executeMethod(
callback: any,
paramCandidTypes: CandidType[],
returnCandidType: CandidType,
manual: boolean,
parents: Parent[]
manual: boolean
) {
if (mode === 'heartbeat') {
const result = callback();
Expand All @@ -70,7 +69,7 @@ export function executeMethod(
return;
}

const decodedArgs = decodeMultiple(paramCandidTypes, args[0], parents);
const decodedArgs = decodeMultiple(paramCandidTypes, args[0]);

const result = callback(...decodedArgs);

Expand All @@ -94,7 +93,7 @@ export function executeMethod(
console.log(`final instructions: ${ic.instructionCounter()}`);

if (!manual) {
ic.replyRaw(encode(returnCandidType, result, parents));
ic.replyRaw(encode(returnCandidType, result));
}
})
.catch((error: any) => {
Expand All @@ -109,12 +108,6 @@ export function executeMethod(
}
}

export function createParents(parent: any): Parent[] {
return parent === undefined
? []
: [{ idl: parent, name: parent._azleName }];
}

export function isAsync(originalFunction: any) {
if (originalFunction[Symbol.toStringTag] === 'AsyncFunction') {
return true;
Expand Down
47 changes: 22 additions & 25 deletions src/lib/canister_methods/init.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Callback, CanisterMethodInfo, createParents, executeMethod } from '.';
import { Callback, CanisterMethodInfo, executeMethod } from '.';
import { CandidType, TypeMapping } from '../candid';
import { Void } from '../candid/types/primitive/void';

Expand All @@ -11,29 +11,26 @@ export function init<
? GenericCallback
: never
): CanisterMethodInfo<Params, Void> {
return ((parent: any) => {
const finalCallback =
callback === undefined
? undefined
: (...args: any[]) => {
executeMethod(
'init',
args,
callback,
paramCandidTypes as unknown as CandidType[],
Void,
false,
createParents(parent)
);
};
const finalCallback =
callback === undefined
? undefined
: (...args: any[]) => {
executeMethod(
'init',
args,
callback,
paramCandidTypes as unknown as CandidType[],
Void,
false
);
};

return {
mode: 'init',
callback: finalCallback,
paramCandidTypes: paramCandidTypes as any,
returnCandidType: Void,
async: false,
guard: undefined
} as CanisterMethodInfo<Params, Void>;
}) as any;
return {
mode: 'init',
callback: finalCallback,
paramCandidTypes: paramCandidTypes as any,
returnCandidType: Void,
async: false,
guard: undefined
};
}
Loading

0 comments on commit 43fad0d

Please sign in to comment.