diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a337ac5e70..ff9bfb0527 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -87,7 +87,6 @@ # "examples/run_time_errors", # "examples/rust_type_conversions", # "examples/complex_types", -# "examples/composite_queries", # "examples/func_types", # "examples/generics", # "examples/guard_functions", @@ -148,6 +147,7 @@ jobs: "examples/candid_encoding", "examples/counter", "examples/complex_init", + "examples/composite_queries", "examples/cross_canister_calls", "examples/cycles", "examples/ethereum_json_rpc", diff --git a/examples/composite_queries/canisters/canister1/canister1.did b/examples/composite_queries/canisters/canister1/canister1.did index ba4506572b..fb3e022565 100644 --- a/examples/composite_queries/canisters/canister1/canister1.did +++ b/examples/composite_queries/canisters/canister1/canister1.did @@ -1,14 +1,11 @@ -type ManualReply = variant { Ok : text; Err : text }; -type ManualReply_1 = variant { Ok : nat; Err : text }; -service : () -> { - deepQuery : () -> (ManualReply) query; - incCanister1 : () -> (ManualReply_1) query; - incCanister2 : () -> (ManualReply_1) query; - incCounter : () -> (nat) query; - manualQuery : () -> (ManualReply) query; - simpleCompositeQuery : () -> (ManualReply) query; - simpleQuery : () -> (ManualReply) query; - simpleUpdate : () -> (ManualReply); - totallyManualQuery : () -> (ManualReply) query; - updateQuery : () -> (ManualReply) query; -} \ No newline at end of file +service: () -> { + simpleCompositeQuery: () -> (text) query; + manualQuery: () -> (text) query; + totallyManualQuery: () -> (text) query; + deepQuery: () -> (text) query; + updateQuery: () -> (text) query; + simpleQuery: () -> (text) query; + simpleUpdate: () -> (text); + incCounter: () -> (nat) query; + incCanister2: () -> (nat) query; +} diff --git a/examples/composite_queries/canisters/canister1/canister1.ts b/examples/composite_queries/canisters/canister1/canister1.ts index f267ef91b2..09614d499f 100644 --- a/examples/composite_queries/canisters/canister1/canister1.ts +++ b/examples/composite_queries/canisters/canister1/canister1.ts @@ -1,141 +1,87 @@ -import { - ic, - Manual, - match, - nat, - Principal, - $query, - Result, - $update -} from 'azle'; -import { Canister1 } from '../canister1/types'; -import { Canister2 } from '../canister2/types'; - -const canister1 = new Canister1( - Principal.fromText( - process.env.CANISTER1_PRINCIPAL ?? - ic.trap('process.env.CANISTER1_PRINCIPAL is undefined') - ) -); - -const canister2 = new Canister2( - Principal.fromText( - process.env.CANISTER2_PRINCIPAL ?? - ic.trap('process.env.CANISTER2_PRINCIPAL is undefined') - ) -); - -let counter: nat = 0n; +import { ic, Manual, nat, Principal, query, Service, text, update } from 'azle'; +import Canister2 from '../canister2/canister2'; // Composite query calling a query -$query; -export async function simpleCompositeQuery(): Promise> { - return await canister2.simpleQuery().call(); +class Canister1 extends Service { + // canister1 = new Canister1( + // Principal.fromText( + // process.env.CANISTER1_PRINCIPAL ?? + // ic.trap('process.env.CANISTER1_PRINCIPAL is undefined') + // ) + // ); + + canister2 = new Canister2( + Principal.fromText( + process.env.CANISTER2_PRINCIPAL ?? + ic.trap('process.env.CANISTER2_PRINCIPAL is undefined') + ) + ); + + counter: nat = 0n; + + @query([], text) + async simpleCompositeQuery(): Promise { + return await ic.call(this.canister2.simpleQuery); + } + + // Composite query calling a manual query + @query([], text) + async manualQuery(): Promise { + return await ic.call(this.canister2.manualQuery); + } + + // Manual composite query calling a manual query + @query([], text) + async totallyManualQuery(): Promise> { + ic.reply(await ic.call(this.canister2.manualQuery), text); + } + + // Composite query calling another composite query + @query([], text) + async deepQuery(): Promise { + return await ic.call(this.canister2.deepQuery); + } + + // Composite query calling an update method. SHOULDN'T WORK + @query([], text) + async updateQuery(): Promise { + return await ic.call(this.canister2.updateQuery); + } + + // Composite query being called by a query method. SHOULDN'T WORK + @query([], text) + async simpleQuery(): Promise { + return await ic.call(this.canister2.simpleQuery); + } + + // Composite query being called by an update method. SHOULDN'T WORK + @update([], text) + async simpleUpdate(): Promise { + return await ic.call(this.canister2.deepQuery); + } + + // Composite query that modifies the state. Should revert after the call is done + @query([], nat) + async incCounter(): Promise { + this.counter += 1n; + return this.counter; + } + + // Composite query calling queries on the same canister. SHOULDN'T WORK + // @query([], nat) + // async incCanister1(): Promise { + // this.counter += 1n; + + // return await ic.call(this.canister1.incCounter); + // } + + // Composite query calling queries that modify the state + @query([], nat) + async incCanister2(): Promise { + this.counter += 1n; + + return await ic.call(this.canister2.incCounter); + } } -// Composite query calling a manual query -$query; -export async function manualQuery(): Promise> { - return await canister2.manualQuery().call(); -} - -// Manual composite query calling a manual query -$query; -export async function totallyManualQuery(): Promise< - Manual> -> { - ic.reply(await canister2.manualQuery().call()); -} - -// Composite query calling another composite query -$query; -export async function deepQuery(): Promise> { - const callResult = await canister2.deepQuery().call(); - - return match(callResult, { - Ok: (stringQueryResult) => - match(stringQueryResult, { - Ok: (stringQuery) => ({ Ok: stringQuery }), - Err: (err) => ({ Err: err }) - }), - Err: (err) => ({ Err: err }) - }); -} - -// Composite query calling an update method. SHOULDN'T WORK -$query; -export async function updateQuery(): Promise> { - return await canister2.updateQuery().call(); -} - -// Composite query being called by a query method. SHOULDN'T WORK -$query; -export async function simpleQuery(): Promise> { - return await canister2.simpleQuery().call(); -} - -// Composite query being called by an update method. SHOULDN'T WORK -$update; -export async function simpleUpdate(): Promise> { - const callResult = await canister2.deepQuery().call(); - - return match(callResult, { - Ok: (stringQueryResult) => - match(stringQueryResult, { - Ok: (stringQuery) => ({ Ok: stringQuery }), - Err: (err) => ({ Err: err }) - }), - Err: (err) => ({ Err: err }) - }); -} - -// Composite query that modifies the state. Should revert after the call is done -$query; -export async function incCounter(): Promise { - counter += 1n; - return counter; -} - -// Composite query calling queries on the same canister. SHOULDN'T WORK -$query; -export async function incCanister1(): Promise> { - counter += 1n; - - const canister1AResult = await canister1.incCounter().call(); - - return match(canister1AResult, { - Ok: async (canister1AOk) => { - const canister1BResult = await canister1.incCounter().call(); - - return match(canister1BResult, { - Ok: (canister1BOk) => ({ - Ok: counter + canister1AOk + canister1BOk - }), - Err: (err) => ({ Err: err }) - }); - }, - Err: (err) => ({ Err: err }) - }); -} - -// Composite query calling queries that modify the state -$query; -export async function incCanister2(): Promise> { - counter += 1n; - - const canister2AResult = await canister2.incCounter().call(); - - return match(canister2AResult, { - Ok: async (canister2AOk) => { - const canister2BResult = await canister2.incCounter().call(); - - return match(canister2BResult, { - Ok: (canister2BOk) => ({ - Ok: counter + canister2AOk + canister2BOk - }), - Err: (err) => ({ Err: err }) - }); - }, - Err: (err) => ({ Err: err }) - }); -} +export default Canister1; diff --git a/examples/composite_queries/canisters/canister1/types.ts b/examples/composite_queries/canisters/canister1/types.ts deleted file mode 100644 index 55b2d5d5d7..0000000000 --- a/examples/composite_queries/canisters/canister1/types.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { CallResult, nat, Service, serviceQuery } from 'azle'; - -export class Canister1 extends Service { - @serviceQuery - incCounter: () => CallResult; -} diff --git a/examples/composite_queries/canisters/canister2/canister2.did b/examples/composite_queries/canisters/canister2/canister2.did index 7329fcc8ea..779ccf764d 100644 --- a/examples/composite_queries/canisters/canister2/canister2.did +++ b/examples/composite_queries/canisters/canister2/canister2.did @@ -1,8 +1,7 @@ -type ManualReply = variant { Ok : text; Err : text }; -service : () -> { - deepQuery : () -> (ManualReply) query; - incCounter : () -> (nat) query; - manualQuery : () -> (text) query; - simpleQuery : () -> (text) query; - updateQuery : () -> (text); -} \ No newline at end of file +service: () -> { + incCounter: () -> (nat) query; + simpleQuery: () -> (text) query; + updateQuery: () -> (text); + manualQuery: () -> (text) query; + deepQuery: () -> (text) query; +} diff --git a/examples/composite_queries/canisters/canister2/canister2.ts b/examples/composite_queries/canisters/canister2/canister2.ts index 18b320a84e..0d8d18a056 100644 --- a/examples/composite_queries/canisters/canister2/canister2.ts +++ b/examples/composite_queries/canisters/canister2/canister2.ts @@ -1,38 +1,40 @@ -import { ic, Manual, nat, Principal, $query, Result, $update } from 'azle'; -import { Canister3 } from '../canister3/types'; +import { ic, Manual, nat, Principal, query, Service, text, update } from 'azle'; +import Canister3 from '../canister3/canister3'; -const canister3 = new Canister3( - Principal.fromText( - process.env.CANISTER3_PRINCIPAL ?? - ic.trap('process.env.CANISTER3_PRINCIPAL is undefined') - ) -); +export default class extends Service { + canister3 = new Canister3( + Principal.fromText( + process.env.CANISTER3_PRINCIPAL ?? + ic.trap('process.env.CANISTER3_PRINCIPAL is undefined') + ) + ); -let counter: nat = 0n; + counter: nat = 0n; -// TODO is this supposed to be a query? -$query; -export async function incCounter(): Promise { - counter += 1n; - return counter; -} + // TODO is this supposed to be a query? + @query([], nat) + async incCounter(): Promise { + this.counter += 1n; + return this.counter; + } -$query; -export function simpleQuery(): string { - return 'Hello from Canister 2'; -} + @query([], text) + simpleQuery(): text { + return 'Hello from Canister 2'; + } -$update; -export function updateQuery(): string { - return 'Hello from a Canister 2 update'; -} + @update([], text) + updateQuery(): text { + return 'Hello from a Canister 2 update'; + } -$query; -export function manualQuery(): Manual { - ic.reply('Hello from Canister 2 manual query'); -} + @query([], text) + manualQuery(): Manual { + ic.reply('Hello from Canister 2 manual query', text); + } -$query; -export async function deepQuery(): Promise> { - return await canister3.deepQuery().call(); + @query([], text) + async deepQuery(): Promise { + return await ic.call(this.canister3.deepQuery); + } } diff --git a/examples/composite_queries/canisters/canister2/types.ts b/examples/composite_queries/canisters/canister2/types.ts deleted file mode 100644 index 38535e3296..0000000000 --- a/examples/composite_queries/canisters/canister2/types.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { - CallResult, - nat, - Result, - Service, - serviceQuery, - serviceUpdate -} from 'azle'; - -export class Canister2 extends Service { - @serviceQuery - simpleQuery: () => CallResult; - - @serviceQuery - manualQuery: () => CallResult; - - @serviceUpdate - updateQuery: () => CallResult; - - @serviceQuery - deepQuery: () => CallResult>; - - @serviceQuery - incCounter: () => CallResult; -} diff --git a/examples/composite_queries/canisters/canister3/canister3.did b/examples/composite_queries/canisters/canister3/canister3.did index 58d65d4d45..78eacc0a1e 100644 --- a/examples/composite_queries/canisters/canister3/canister3.did +++ b/examples/composite_queries/canisters/canister3/canister3.did @@ -1 +1,3 @@ -service : () -> { deepQuery : () -> (text) query } \ No newline at end of file +service: () -> { + deepQuery: () -> (text) query; +} diff --git a/examples/composite_queries/canisters/canister3/canister3.ts b/examples/composite_queries/canisters/canister3/canister3.ts index dc3bf90cbe..922996147c 100644 --- a/examples/composite_queries/canisters/canister3/canister3.ts +++ b/examples/composite_queries/canisters/canister3/canister3.ts @@ -1,6 +1,8 @@ -import { $query } from 'azle'; +import { Service, query, text } from 'azle'; -$query; -export function deepQuery(): string { - return 'Hello from Canister 3'; +export default class extends Service { + @query([], text) + deepQuery(): text { + return 'Hello from Canister 3'; + } } diff --git a/examples/composite_queries/canisters/canister3/types.ts b/examples/composite_queries/canisters/canister3/types.ts deleted file mode 100644 index 33dc67858f..0000000000 --- a/examples/composite_queries/canisters/canister3/types.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { CallResult, Service, serviceQuery } from 'azle'; - -export class Canister3 extends Service { - @serviceQuery - deepQuery: () => CallResult; -}