Skip to content

Commit

Permalink
add support for Funcs
Browse files Browse the repository at this point in the history
  • Loading branch information
bdemann committed Sep 22, 2023
1 parent d47cb8b commit 044246e
Show file tree
Hide file tree
Showing 11 changed files with 151 additions and 136 deletions.
5 changes: 3 additions & 2 deletions canisters/ledger/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ import {
Variant,
Vec,
candid,
principal
principal,
Func
} from '../../src/lib_new';
import {
ICRC1Account,
Expand Down Expand Up @@ -279,7 +280,7 @@ export class QueryArchiveResult extends Variant {

// A function that is used for fetching archived ledger blocks.
@func([GetBlocksArgs], QueryArchiveResult, 'query')
class QueryArchiveFn {}
class QueryArchiveFn extends Func {}

class ArchivedBlock extends Record {
// The index of the first archived block that can be fetched using the callback.
Expand Down
5 changes: 3 additions & 2 deletions canisters/management/http_request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import {
Null,
nat64,
nat,
func
func,
Func
} from '../../src/lib_new';

export class HttpHeader extends Record {
Expand Down Expand Up @@ -63,7 +64,7 @@ export class HttpTransformArgs extends Record {
}

@func([HttpTransformArgs], HttpResponse, 'query')
export class HttpTransformFunc {}
export class HttpTransformFunc extends Func {}

export class HttpTransform extends Record {
/**
Expand Down
206 changes: 105 additions & 101 deletions examples/func_types/canisters/func_types/func_types.ts
Original file line number Diff line number Diff line change
@@ -1,123 +1,127 @@
import {
Func,
Query,
Update,
$init,
init,
ic,
match,
nat64,
Opt,
Principal,
$query,
query,
Record,
Result,
Service,
StableBTreeMap,
$update,
update,
Variant,
Vec
Vec,
candid,
text,
func,
Void,
Null
} from 'azle';
import { Notifier, NotifierFunc } from '../notifiers/types';
import Notifier, { NotifierFunc } from '../notifiers/notifiers';

let stableStorage = new StableBTreeMap<string, StableFunc>(0, 25, 1_000);
@func([text], text, 'query')
class BasicFunc extends Func {}

type User = Record<{
id: string;
@func([User, Reaction], nat64, 'update')
class ComplexFunc extends Func {}

class User extends Record {
@candid(text)
id: text;

@candid(BasicFunc)
basicFunc: BasicFunc;

@candid(ComplexFunc)
complexFunc: ComplexFunc;
}>;
}

type Reaction = Variant<{
class Reaction extends Variant {
Good: null;
Bad: null;
BasicFunc: BasicFunc;
ComplexFunc: ComplexFunc;
}>;

type BasicFunc = Func<Query<(param1: string) => string>>;
type ComplexFunc = Func<Update<(user: User, reaction: Reaction) => nat64>>;
type StableFunc = Func<Query<(param1: nat64, param2: string) => void>>;
type NullFunc = Func<
Query<
(
param1: Opt<null>,
param2: Vec<null>,
param3: null,
param4: Vec<Vec<null>>,
param5: Vec<Opt<null>>
) => null
>
>;

$init;
export function init(): void {
stableStorage.insert('stableFunc', [
Principal.from('aaaaa-aa'),
'start_canister'
]);
}

$query;
export function getStableFunc(): StableFunc {
return match(stableStorage.get('stableFunc'), {
Some: (func) => func,
None: () => [Principal.from('aaaaa-aa'), 'raw_rand'] as StableFunc
});
}

$query;
export function basicFuncParam(basicFunc: BasicFunc): BasicFunc {
return basicFunc;
}

$query;
export function nullFuncParam(nullFunc: NullFunc): NullFunc {
return nullFunc;
}

$query;
export function basicFuncParamArray(basicFunc: Vec<BasicFunc>): Vec<BasicFunc> {
return basicFunc;
}

$query;
export function basicFuncReturnType(): BasicFunc {
return [Principal.fromText('aaaaa-aa'), 'create_canister'];
}

$query;
export function basicFuncReturnTypeArray(): Vec<BasicFunc> {
return [
[Principal.fromText('aaaaa-aa'), 'create_canister'],
[Principal.fromText('aaaaa-aa'), 'update_settings'],
[Principal.fromText('aaaaa-aa'), 'install_code']
];
}

$query;
export function complexFuncParam(complexFunc: ComplexFunc): ComplexFunc {
return complexFunc;
}

$query;
export function complexFuncReturnType(): ComplexFunc {
return [Principal.fromText('aaaaa-aa'), 'stop_canister'];
}

$update;
export async function getNotifierFromNotifiersCanister(): Promise<
Result<NotifierFunc, string>
> {
const notifiersCanister: Notifier = new Notifier(
Principal.fromText(
process.env.NOTIFIERS_PRINCIPAL ??
ic.trap('process.env.NOTIFIERS_PRINCIPAL is undefined')
)
);

const result = await notifiersCanister.getNotifier().call();

return match(result, {
Ok: (ok) => ({ Ok: ok }),
Err: (err) => ({ Err: err })
});
@func([nat64, text], Void, 'query')
class StableFunc extends Func {}

@func(
[Opt(Null), Vec(Null), Null, Vec(Vec(Null)), Vec(Opt(Null))],
Null,
'query'
)
class NullFunc extends Func {}

export default class extends Service {
stableStorage = new StableBTreeMap<text, StableFunc>(text, StableFunc, 0);

@init([])
init() {
this.stableStorage.insert(
'stableFunc',
new StableFunc(Principal.from('aaaaa-aa'), 'start_canister')
);
}

@query([], StableFunc)
getStableFunc(): StableFunc {
const stableFuncOpt = this.stableStorage.get('stableFunc');
if (stableFuncOpt.length === 1) {
return stableFuncOpt[0];
}
return new StableFunc(Principal.from('aaaaa-aa'), 'raw_rand');
}

@query([BasicFunc], BasicFunc)
basicFuncParam(basicFunc: BasicFunc): BasicFunc {
return basicFunc;
}

@query([NullFunc], NullFunc)
nullFuncParam(nullFunc: NullFunc): NullFunc {
return nullFunc;
}

@query([Vec(BasicFunc)], Vec(BasicFunc))
basicFuncParamArray(basicFunc: Vec<BasicFunc>): Vec<BasicFunc> {
return basicFunc;
}

@query([], BasicFunc)
basicFuncReturnType(): BasicFunc {
return new BasicFunc(Principal.fromText('aaaaa-aa'), 'create_canister');
}

@query([], Vec(BasicFunc))
basicFuncReturnTypeArray(): Vec<BasicFunc> {
return [
new BasicFunc(Principal.fromText('aaaaa-aa'), 'create_canister'),
new BasicFunc(Principal.fromText('aaaaa-aa'), 'update_settings'),
new BasicFunc(Principal.fromText('aaaaa-aa'), 'install_code')
];
}

@query([ComplexFunc], ComplexFunc)
complexFuncParam(complexFunc: ComplexFunc): ComplexFunc {
return complexFunc;
}

@query([], ComplexFunc)
complexFuncReturnType(): ComplexFunc {
return [Principal.fromText('aaaaa-aa'), 'stop_canister'];
}

@update([], NotifierFunc)
async getNotifierFromNotifiersCanister(): Promise<NotifierFunc> {
const notifiersCanister: Notifier = new Notifier(
Principal.fromText(
process.env.NOTIFIERS_PRINCIPAL ??
ic.trap('process.env.NOTIFIERS_PRINCIPAL is undefined')
)
);

return await ic.call(notifiersCanister.getNotifier);
}
}
4 changes: 3 additions & 1 deletion examples/func_types/canisters/notifiers/notifiers.did
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
service : () -> { getNotifier : () -> (func (vec nat8) -> () oneway) query }
service: () -> {
getNotifier: () -> (func (vec nat8) -> () oneway) query;
}
26 changes: 15 additions & 11 deletions examples/func_types/canisters/notifiers/notifiers.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import { ic, Principal, $query } from 'azle';
import { NotifierFunc } from './types';
import { ic, Principal, query, blob, Func, Service, Void, func } from 'azle';

$query;
export function getNotifier(): NotifierFunc {
return [
Principal.fromText(
process.env.NOTIFIERS_PRINCIPAL ??
ic.trap('process.env.NOTIFIERS_PRINCIPAL is undefined')
),
'notify'
];
@func([blob], Void, 'oneway')
export class NotifierFunc extends Func {}

export default class extends Service {
@query([], NotifierFunc)
getNotifier(): NotifierFunc {
return new NotifierFunc(
Principal.fromText(
process.env.NOTIFIERS_PRINCIPAL ??
ic.trap('process.env.NOTIFIERS_PRINCIPAL is undefined')
),
'notify'
);
}
}
8 changes: 0 additions & 8 deletions examples/func_types/canisters/notifiers/types.ts

This file was deleted.

7 changes: 3 additions & 4 deletions examples/func_types/test/tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,14 +127,13 @@ export function getTests(funcTypesCanister: ActorSubclass<_SERVICE>): Test[] {
name: 'getNotifierFromNotifiersCanister',
test: async () => {
// TODO agent-js seems to be creating incorrect types here: https://github.com/dfinity/agent-js/issues/583
const result: any =
const result =
await funcTypesCanister.getNotifierFromNotifiersCanister();

return {
Ok:
'Ok' in result &&
result.Ok[0].toText() === getCanisterId('notifiers') &&
result.Ok[1] === 'notify'
result[0].toText() === getCanisterId('notifiers') &&
result[1] === 'notify'
};
}
}
Expand Down
3 changes: 2 additions & 1 deletion examples/list_of_lists/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
empty,
float32,
float64,
Func,
func,
int,
int16,
Expand Down Expand Up @@ -49,7 +50,7 @@ class State extends Variant {
}

@func([text], text, 'query')
class BasicFunc {}
class BasicFunc extends Func {}

export default class extends Service {
@query([Vec(text)], Vec(text))
Expand Down
5 changes: 3 additions & 2 deletions examples/motoko_examples/http_counter/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ import {
Some,
None,
bool,
Service
Service,
Func
} from 'azle';

class Token extends Record {
Expand All @@ -36,7 +37,7 @@ class StreamingCallbackHttpResponse extends Record {
}

@func([text], StreamingCallbackHttpResponse, 'query')
class Callback {}
class Callback extends Func {}

class CallbackStrategy extends Record {
@candid(Callback)
Expand Down
13 changes: 11 additions & 2 deletions src/lib_new/func.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { IDL, Principal } from './index';
import { CandidClass, toReturnIDLType, toParamIDLTypes } from './utils';
import {
CandidClass,
toReturnIDLType,
toParamIDLTypes,
ReturnCandidClass
} from './utils';

type Mode = 'query' | 'update' | 'oneway';

Expand All @@ -9,9 +14,13 @@ const modeToCandid = {
update: [] // TODO what is the proper way to do updates
};

export class Func {
constructor(principal: Principal, name: string) {}
}

export function func(
paramsIdls: CandidClass[],
returnIdl: CandidClass,
returnIdl: ReturnCandidClass,
mode: Mode
) {
return (target: any) => {
Expand Down
Loading

0 comments on commit 044246e

Please sign in to comment.