From 9dfdaf574babe8abcfc13ae4e5fb8e95ad84da6e Mon Sep 17 00:00:00 2001 From: Benjamin DeMann Date: Sat, 7 Oct 2023 15:32:53 -0600 Subject: [PATCH 01/36] rename call_raw entry file to index --- examples/call_raw/dfx.json | 4 ++-- examples/call_raw/src/{call_raw.did => index.did} | 0 examples/call_raw/src/{call_raw.ts => index.ts} | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename examples/call_raw/src/{call_raw.did => index.did} (100%) rename examples/call_raw/src/{call_raw.ts => index.ts} (100%) diff --git a/examples/call_raw/dfx.json b/examples/call_raw/dfx.json index 010976366d..c9267ffd6f 100644 --- a/examples/call_raw/dfx.json +++ b/examples/call_raw/dfx.json @@ -2,9 +2,9 @@ "canisters": { "call_raw": { "type": "custom", - "main": "src/call_raw.ts", - "candid": "src/call_raw.did", + "main": "src/index.ts", "build": "npx azle call_raw", + "candid": "src/index.did", "wasm": ".azle/call_raw/call_raw.wasm", "gzip": true, "declarations": { diff --git a/examples/call_raw/src/call_raw.did b/examples/call_raw/src/index.did similarity index 100% rename from examples/call_raw/src/call_raw.did rename to examples/call_raw/src/index.did diff --git a/examples/call_raw/src/call_raw.ts b/examples/call_raw/src/index.ts similarity index 100% rename from examples/call_raw/src/call_raw.ts rename to examples/call_raw/src/index.ts From 33a30d850a406d6847e67dc9a242ce698fac9dfa Mon Sep 17 00:00:00 2001 From: Benjamin DeMann Date: Thu, 12 Oct 2023 11:15:16 -0600 Subject: [PATCH 02/36] make visitVariant more declarative --- src/lib/candid/serde/visitors/index.ts | 93 +++++++++++++++----------- 1 file changed, 55 insertions(+), 38 deletions(-) diff --git a/src/lib/candid/serde/visitors/index.ts b/src/lib/candid/serde/visitors/index.ts index 70d24469b3..d370f0ea9a 100644 --- a/src/lib/candid/serde/visitors/index.ts +++ b/src/lib/candid/serde/visitors/index.ts @@ -2,7 +2,6 @@ import { IDL } from '@dfinity/candid'; import { DecodeVisitor } from './decode_visitor'; import { EncodeVisitor } from './encode_visitor'; import { AzleResult, Result } from '../../../system_types/result'; -import { CandidType } from '../..'; export { EncodeVisitor, DecodeVisitor }; /* @@ -80,30 +79,63 @@ export function visitVariant( data: VisitorData ): VisitorResult { if (data.candidType instanceof AzleResult) { - if ('Ok' in data.js_data) { - const okField = fields[0]; - const okData = data.js_data['Ok']; - const okClass = data.candidType._azleOk; + return visitAzleResult(visitor, fields, data); + } + return visitAzleVariant(visitor, fields, data); +} - return Result.Ok( - okField[1].accept(visitor, { - js_data: okData, - candidType: okClass - }) - ); - } - if ('Err' in data.js_data) { - const errField = fields[1]; - const errData = data.js_data['Err']; - const errClass = data.candidType._azleErr; - return Result.Err( - errField[1].accept(visitor, { - js_data: errData, - candidType: errClass - }) - ); - } +export function visitRec( + visitor: DecodeVisitor | EncodeVisitor, + ty: IDL.ConstructType, + data: VisitorData +): VisitorResult { + let candidType = data.candidType(); + if (candidType._azleIsCanister) { + candidType = candidType([]); + } + return ty.accept(visitor, { + ...data, + candidType + }); +} + +function visitAzleResult( + visitor: DecodeVisitor | EncodeVisitor, + fields: [string, IDL.Type][], + data: VisitorData +) { + if ('Ok' in data.js_data) { + const OK_FIELD_INDEX = 0; + const okField = fields[OK_FIELD_INDEX]; + const okData = data.js_data['Ok']; + const okClass = data.candidType._azleOk; + + return Result.Ok( + okField[1].accept(visitor, { + js_data: okData, + candidType: okClass + }) + ); + } + if ('Err' in data.js_data) { + const ERR_FIELD_INDEX = 1; + const errField = fields[ERR_FIELD_INDEX]; + const errData = data.js_data['Err']; + const errClass = data.candidType._azleErr; + return Result.Err( + errField[1].accept(visitor, { + js_data: errData, + candidType: errClass + }) + ); } +} + +function visitAzleVariant( + visitor: DecodeVisitor | EncodeVisitor, + fields: [string, IDL.Type][], + data: VisitorData +) { const candidFields = fields.reduce((acc, [memberName, memberIdl]) => { const fieldData = data.js_data[memberName]; const fieldClass = data.candidType[memberName]; @@ -122,18 +154,3 @@ export function visitVariant( return candidFields; } - -export function visitRec( - visitor: DecodeVisitor | EncodeVisitor, - ty: IDL.ConstructType, - data: VisitorData -): VisitorResult { - let candidType = data.candidType(); - if (candidType._azleIsCanister) { - candidType = candidType([]); - } - return ty.accept(visitor, { - ...data, - candidType - }); -} From ef0905fd644ea4254695dc9f3070bf44f247aa37 Mon Sep 17 00:00:00 2001 From: Benjamin DeMann Date: Thu, 12 Oct 2023 15:33:08 -0600 Subject: [PATCH 03/36] unify encode and encodeMultiple, for decode also --- src/lib/candid/serde/index.ts | 57 +++++++++++++++++------ src/lib/candid/types/reference/service.ts | 4 +- src/lib/canister_methods/index.ts | 4 +- src/lib/ic/stable_64_read.ts | 7 +-- src/lib/ic/stable_64_write.ts | 7 +-- src/lib/ic/stable_read.ts | 7 +-- src/lib/ic/stable_write.ts | 7 +-- 7 files changed, 54 insertions(+), 39 deletions(-) diff --git a/src/lib/candid/serde/index.ts b/src/lib/candid/serde/index.ts index 3acb28def2..7d381182ea 100644 --- a/src/lib/candid/serde/index.ts +++ b/src/lib/candid/serde/index.ts @@ -18,6 +18,45 @@ import { CandidType, Parent, toIDLType } from '../../candid'; * @returns candid bytes */ export function encode( + candidType: CandidType | CandidType[], + data: any | any[], + parents: Parent[] = [] +): Uint8Array { + if (Array.isArray(candidType)) { + if (Array.isArray(data)) { + return encodeMultiple(candidType, data, parents); + } + throw new Error( + 'If multiple candid types are given then multiple data entries are expected.' + ); + } + return encodeSingle(candidType, data, parents); +} + +/** + * Decodes the provided buffer into the designated JS value. + * + * Intended to be a rich replacement for `IDL.decode` from `@dfinity/candid` + * adding support for complex Azle IDL wrappers such as {@link AzleOpt}, + * {@link AzleVec}, and {@link AzleTuple}. It recursively visits all "inner" + * values, converting them from their native shape to the shape that Azle expects. + * + * @param data the value to decode + * @param candidType either a built-in IDL data type, or an Azle-defined super-type + * @returns the Azle representation of the data + */ +export function decode( + candidType: CandidType | CandidType[], + data: ArrayBuffer, + parents: Parent[] = [] +): any | any[] { + if (Array.isArray(candidType)) { + return decodeMultiple(candidType, data, parents); + } + return decodeSingle(candidType, data, parents); +} + +function encodeSingle( candidType: CandidType, data: any, parents: Parent[] = [] @@ -38,19 +77,7 @@ export function encode( return new Uint8Array(IDL.encode([idl], [encodeReadyKey])); } -/** - * Decodes the provided buffer into the designated JS value. - * - * Intended to be a rich replacement for `IDL.decode` from `@dfinity/candid` - * adding support for complex Azle IDL wrappers such as {@link AzleOpt}, - * {@link AzleVec}, and {@link AzleTuple}. It recursively visits all "inner" - * values, converting them from their native shape to the shape that Azle expects. - * - * @param data the value to decode - * @param candidType either a built-in IDL data type, or an Azle-defined super-type - * @returns the Azle representation of the data - */ -export function decode( +function decodeSingle( candidType: CandidType, data: ArrayBuffer, parents: Parent[] = [] @@ -75,7 +102,7 @@ export function decode( }); } -export function encodeMultiple( +function encodeMultiple( candidTypes: CandidType[], data: any[], parents: Parent[] = [] @@ -104,7 +131,7 @@ export function encodeMultiple( return new Uint8Array(IDL.encode(idls, values)); } -export function decodeMultiple( +function decodeMultiple( candidTypes: CandidType[], data: ArrayBuffer, parents: Parent[] = [] diff --git a/src/lib/candid/types/reference/service.ts b/src/lib/candid/types/reference/service.ts index 0921950280..8b36d2fd2f 100644 --- a/src/lib/candid/types/reference/service.ts +++ b/src/lib/candid/types/reference/service.ts @@ -10,7 +10,7 @@ import { ic } from '../../../ic'; import { Principal } from './principal'; import { IDL } from '@dfinity/candid'; import { CanisterMethodInfo } from '../../../canister_methods'; -import { decode, encodeMultiple } from '../../serde'; +import { decode, encode } from '../../serde'; type CanisterOptions = { [key: string]: CanisterMethodInfo; @@ -302,7 +302,7 @@ function serviceCall( cycles: bigint, ...args: any[] ) { - const encodedArgs = encodeMultiple(paramCandidTypes, args); + const encodedArgs = encode(paramCandidTypes, args); if (notify) { try { diff --git a/src/lib/canister_methods/index.ts b/src/lib/canister_methods/index.ts index 8231bcf073..3066d78340 100644 --- a/src/lib/canister_methods/index.ts +++ b/src/lib/canister_methods/index.ts @@ -1,7 +1,7 @@ import { AzleVoid } from '../candid/types/primitive/void'; import { ic } from '../ic'; import { CandidType, TypeMapping } from '../candid'; -import { decodeMultiple, encode } from '../candid/serde'; +import { decode, encode } from '../candid/serde'; export * from './heartbeat'; export * from './init'; @@ -69,7 +69,7 @@ export function executeMethod( return; } - const decodedArgs = decodeMultiple(paramCandidTypes, args[0]); + const decodedArgs = decode(paramCandidTypes, args[0]); const result = callback(...decodedArgs); diff --git a/src/lib/ic/stable_64_read.ts b/src/lib/ic/stable_64_read.ts index 2417906b1f..84ec6b1529 100644 --- a/src/lib/ic/stable_64_read.ts +++ b/src/lib/ic/stable_64_read.ts @@ -1,5 +1,5 @@ import { nat64 } from '../candid/types/primitive/nats/nat64'; -import { encodeMultiple } from '../candid/serde'; +import { encode } from '../candid/serde'; /** * Reads data from the stable memory location specified by an offset. @@ -13,10 +13,7 @@ export function stable64Read(offset: nat64, length: nat64): Uint8Array { return undefined as any; } - const paramsCandidBytes = encodeMultiple( - [nat64, nat64], - [offset, length] - ).buffer; + const paramsCandidBytes = encode([nat64, nat64], [offset, length]).buffer; return new Uint8Array(globalThis._azleIc.stable64Read(paramsCandidBytes)); } diff --git a/src/lib/ic/stable_64_write.ts b/src/lib/ic/stable_64_write.ts index 015f8740af..7dc63936bb 100644 --- a/src/lib/ic/stable_64_write.ts +++ b/src/lib/ic/stable_64_write.ts @@ -1,6 +1,6 @@ import { blob } from '../candid/types/constructed/blob'; import { nat64 } from '../candid/types/primitive/nats/nat64'; -import { encodeMultiple } from '../candid/serde'; +import { encode } from '../candid/serde'; /** * Writes data to the stable memory location specified by an offset. @@ -17,10 +17,7 @@ export function stable64Write(offset: nat64, buffer: blob): void { return undefined as any; } - const paramsCandidBytes = encodeMultiple( - [nat64, blob], - [offset, buffer] - ).buffer; + const paramsCandidBytes = encode([nat64, blob], [offset, buffer]).buffer; return globalThis._azleIc.stable64Write(paramsCandidBytes); } diff --git a/src/lib/ic/stable_read.ts b/src/lib/ic/stable_read.ts index be91c18e29..0dbf401a07 100644 --- a/src/lib/ic/stable_read.ts +++ b/src/lib/ic/stable_read.ts @@ -1,5 +1,5 @@ import { nat32 } from '../candid/types/primitive/nats/nat32'; -import { encodeMultiple } from '../candid/serde'; +import { encode } from '../candid/serde'; /** * Reads data from the stable memory location specified by an offset @@ -12,10 +12,7 @@ export function stableRead(offset: nat32, length: nat32): Uint8Array { return undefined as any; } - const paramsCandidBytes = encodeMultiple( - [nat32, nat32], - [offset, length] - ).buffer; + const paramsCandidBytes = encode([nat32, nat32], [offset, length]).buffer; return new Uint8Array(globalThis._azleIc.stableRead(paramsCandidBytes)); } diff --git a/src/lib/ic/stable_write.ts b/src/lib/ic/stable_write.ts index 51b79bcff1..d43bcb329f 100644 --- a/src/lib/ic/stable_write.ts +++ b/src/lib/ic/stable_write.ts @@ -1,6 +1,6 @@ import { nat32 } from '../candid/types/primitive/nats/nat32'; import { blob } from '../candid/types/constructed/blob'; -import { encodeMultiple } from '../candid/serde'; +import { encode } from '../candid/serde'; /** * Writes data to the stable memory location specified by an offset @@ -16,10 +16,7 @@ export function stableWrite(offset: nat32, buffer: blob): void { return undefined as any; } - const paramsCandidBytes = encodeMultiple( - [nat32, blob], - [offset, buffer] - ).buffer; + const paramsCandidBytes = encode([nat32, blob], [offset, buffer]).buffer; return globalThis._azleIc.stableWrite(paramsCandidBytes); } From aa80bf0709bc91799a5ada5280acaab654f28d0b Mon Sep 17 00:00:00 2001 From: Benjamin DeMann Date: Tue, 17 Oct 2023 13:24:34 -0600 Subject: [PATCH 04/36] import clean up --- src/lib/candid/types/constructed/record.ts | 1 - src/lib/candid/types/constructed/variant.ts | 1 - 2 files changed, 2 deletions(-) diff --git a/src/lib/candid/types/constructed/record.ts b/src/lib/candid/types/constructed/record.ts index 8bcf3541dd..280a0bee2b 100644 --- a/src/lib/candid/types/constructed/record.ts +++ b/src/lib/candid/types/constructed/record.ts @@ -1,7 +1,6 @@ import { CandidType, TypeMapping, Parent } from '../../index'; import { IDL } from '@dfinity/candid'; import { processMap } from '../constructed'; -import { v4 } from 'uuid'; export function Record< T extends { diff --git a/src/lib/candid/types/constructed/variant.ts b/src/lib/candid/types/constructed/variant.ts index 7ac6cf4939..2b82e7efd6 100644 --- a/src/lib/candid/types/constructed/variant.ts +++ b/src/lib/candid/types/constructed/variant.ts @@ -1,6 +1,5 @@ import { CandidType, TypeMapping } from '../..'; import { processMap } from '.'; -import { v4 } from 'uuid'; import { IDL } from '@dfinity/candid'; export function Variant< From 723fa9c0047b130ea513f385e7a3b70d1a3db97d Mon Sep 17 00:00:00 2001 From: Benjamin DeMann Date: Tue, 17 Oct 2023 13:29:15 -0600 Subject: [PATCH 05/36] remove unecessary parent parameters --- src/lib/candid/index.ts | 2 +- src/lib/candid/serde/index.ts | 48 ++++++++++------------------------- 2 files changed, 15 insertions(+), 35 deletions(-) diff --git a/src/lib/candid/index.ts b/src/lib/candid/index.ts index 3013d0aa1b..93c997df2f 100644 --- a/src/lib/candid/index.ts +++ b/src/lib/candid/index.ts @@ -117,7 +117,7 @@ export type Parent = { export function toIDLType( candidType: CandidType, - parents: Parent[] + parents: Parent[] = [] ): IDL.Type { if ('_azleName' in candidType) { const parent = parents.find( diff --git a/src/lib/candid/serde/index.ts b/src/lib/candid/serde/index.ts index 7d381182ea..2823e6b405 100644 --- a/src/lib/candid/serde/index.ts +++ b/src/lib/candid/serde/index.ts @@ -19,18 +19,17 @@ import { CandidType, Parent, toIDLType } from '../../candid'; */ export function encode( candidType: CandidType | CandidType[], - data: any | any[], - parents: Parent[] = [] + data: any | any[] ): Uint8Array { if (Array.isArray(candidType)) { if (Array.isArray(data)) { - return encodeMultiple(candidType, data, parents); + return encodeMultiple(candidType, data); } throw new Error( 'If multiple candid types are given then multiple data entries are expected.' ); } - return encodeSingle(candidType, data, parents); + return encodeSingle(candidType, data); } /** @@ -47,21 +46,16 @@ export function encode( */ export function decode( candidType: CandidType | CandidType[], - data: ArrayBuffer, - parents: Parent[] = [] + data: ArrayBuffer ): any | any[] { if (Array.isArray(candidType)) { - return decodeMultiple(candidType, data, parents); + return decodeMultiple(candidType, data); } - return decodeSingle(candidType, data, parents); + return decodeSingle(candidType, data); } -function encodeSingle( - candidType: CandidType, - data: any, - parents: Parent[] = [] -): Uint8Array { - const idl = toIDLType(candidType, parents); +function encodeSingle(candidType: CandidType, data: any): Uint8Array { + const idl = toIDLType(candidType); const idlIsAzleVoid = Array.isArray(idl); @@ -77,16 +71,12 @@ function encodeSingle( return new Uint8Array(IDL.encode([idl], [encodeReadyKey])); } -function decodeSingle( - candidType: CandidType, - data: ArrayBuffer, - parents: Parent[] = [] -): any { +function decodeSingle(candidType: CandidType, data: ArrayBuffer): any { // TODO: there is a discrepancy between CandidType and CandidClass that // needs to be aligned so that this isn't an error. Both are representing // candid IDLs, either from the @dfinity/candid library or the // Azle-augmented ones - const idl = toIDLType(candidType, parents); + const idl = toIDLType(candidType); const idlIsAzleVoid = Array.isArray(idl); @@ -102,18 +92,14 @@ function decodeSingle( }); } -function encodeMultiple( - candidTypes: CandidType[], - data: any[], - parents: Parent[] = [] -): Uint8Array { +function encodeMultiple(candidTypes: CandidType[], data: any[]): Uint8Array { const { values, idls } = data.reduce<{ values: any[]; idls: IDL.Type[]; }>( (acc, datum, index) => { const candidType = candidTypes[index]; - const idl = toIDLType(candidType, parents); + const idl = toIDLType(candidType); const encodeReadyValue = idl.accept(new EncodeVisitor(), { candidType: candidType, @@ -131,14 +117,8 @@ function encodeMultiple( return new Uint8Array(IDL.encode(idls, values)); } -function decodeMultiple( - candidTypes: CandidType[], - data: ArrayBuffer, - parents: Parent[] = [] -): any[] { - const idls = candidTypes.map((candidType) => - toIDLType(candidType, parents) - ); +function decodeMultiple(candidTypes: CandidType[], data: ArrayBuffer): any[] { + const idls = candidTypes.map((candidType) => toIDLType(candidType)); const decoded = IDL.decode(idls, data); return idls.map((idl, index) => idl.accept(new DecodeVisitor(), { From 8adae3eb7e9e5fb642664c89eb3e25b581c778a5 Mon Sep 17 00:00:00 2001 From: Benjamin DeMann Date: Tue, 17 Oct 2023 14:20:37 -0600 Subject: [PATCH 06/36] idiot proof the default visitor data --- .../generate_candid_and_canister_methods.ts | 4 ++-- src/lib/candid/did_visitor.ts | 14 ++++++++------ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/compiler/generate_candid_and_canister_methods.ts b/src/compiler/generate_candid_and_canister_methods.ts index 07df622180..d131710925 100644 --- a/src/compiler/generate_candid_and_canister_methods.ts +++ b/src/compiler/generate_candid_and_canister_methods.ts @@ -1,6 +1,6 @@ import { CanisterMethods } from './utils/types'; import { - DEFAULT_VISITOR_DATA, + getDefaultVisitorData, didResultToCandidString, DidVisitor } from '../lib/candid/did_visitor'; @@ -37,7 +37,7 @@ export function generateCandidAndCanisterMethods(mainJs: string): { const canisterMethods = (sandbox.exports as any).canisterMethods; const candidInfo = canisterMethods.getIDL([]).accept(new DidVisitor(), { - ...DEFAULT_VISITOR_DATA, + ...getDefaultVisitorData(), isFirstService: true, systemFuncs: canisterMethods.getSystemFunctionIDLs() }); diff --git a/src/lib/candid/did_visitor.ts b/src/lib/candid/did_visitor.ts index 22f10bbe02..6f43282935 100644 --- a/src/lib/candid/did_visitor.ts +++ b/src/lib/candid/did_visitor.ts @@ -46,12 +46,14 @@ const CANDID_KEYWORDS = [ // had the same shape they got merged into one type that had one of the names. // That might not be the ideal situation, but it is the expected behavior in rust -export const DEFAULT_VISITOR_DATA: VisitorData = { - usedRecClasses: [], - isOnService: false, - isFirstService: false, - systemFuncs: [] -}; +export function getDefaultVisitorData(): VisitorData { + return { + usedRecClasses: [], + isOnService: false, + isFirstService: false, + systemFuncs: [] + }; +} export function didResultToCandidString(result: VisitorResult): string { const [candid, candidTypeDefs] = result; From 71ed079a4ce216c3e531c95324ae1b75fde1c67c Mon Sep 17 00:00:00 2001 From: Benjamin DeMann Date: Tue, 17 Oct 2023 14:23:34 -0600 Subject: [PATCH 07/36] break service into parts --- src/lib/candid/types/reference/service.ts | 425 +++++++++++----------- 1 file changed, 218 insertions(+), 207 deletions(-) diff --git a/src/lib/candid/types/reference/service.ts b/src/lib/candid/types/reference/service.ts index 8b36d2fd2f..88c0fa964a 100644 --- a/src/lib/candid/types/reference/service.ts +++ b/src/lib/candid/types/reference/service.ts @@ -50,10 +50,133 @@ type CallableObject = { (principal: Principal): CallableObject; } & CanisterReturn; +type SystemMethod = { name: string } | undefined; + +type QueryMethod = { + name: string; + composite: boolean; + guard_name: string | undefined; +}; + +type UpdateMethod = { + name: string; + guard_name: string | undefined; +}; + +type CallRawFunction = typeof ic.callRaw | typeof ic.callRaw128; +type NotifyRawFunction = typeof ic.notifyRaw; + +type FunctionInfo = { + mode: 'query' | 'update'; + paramCandidTypes: CandidType[]; + returnCandidType: CandidType; +}; + +interface ServiceFunctionInfo { + [key: string]: FunctionInfo; +} + export function Canister( canisterOptions: T ): CallableObject & { _azleCandidType?: '_azleCandidType' } { let result: _AzleCanisterReturnType = (parentOrPrincipal: any) => { + const returnFunction = createReturnFunctionObject(canisterOptions); + + if (parentOrPrincipal !== undefined && parentOrPrincipal._isPrincipal) { + return returnFunction(parentOrPrincipal); + } + + return returnFunction; + }; + result._azleIsCanister = true; + return result as any; +} + +function createCallbacks(canisterOptions: CanisterOptions) { + return Object.entries(canisterOptions).reduce((acc, entry) => { + const key = entry[0]; + const value = entry[1]; + + return { + ...acc, + [key]: { + canisterCallback: value.callback, + crossCanisterCallback: (...args: any[]) => { + return serviceCall( + this.principal as any, + key, + value.paramCandidTypes, + value.returnCandidType + )(...args); + } + } + }; + // } + }, {}); +} + +function createSystemMethod( + mode: + | 'init' + | 'postUpgrade' + | 'preUpgrade' + | 'heartbeat' + | 'inspectMessage', + canisterOptions: CanisterOptions +): SystemMethod { + const methodOption = Object.entries(canisterOptions).find( + ([key, value]) => value.mode === mode + ); + return methodOption === undefined + ? undefined + : { + name: methodOption[0] + }; +} + +function createQueryMethods(canisterOptions: CanisterOptions): QueryMethod[] { + return Object.entries(canisterOptions) + .filter((entry) => { + const key = entry[0]; + const value = entry[1]; + + return value.mode === 'query'; + }) + .map((entry) => { + const key = entry[0]; + const value = entry[1]; + + return { + name: key, + composite: value.async, + guard_name: createGlobalGuard(value.guard, key) + }; + }); +} + +function createUpdateMethods(canisterOptions: CanisterOptions): UpdateMethod[] { + return Object.entries(canisterOptions) + .filter((entry) => { + const key = entry[0]; + const value = entry[1]; + + return value.mode === 'update'; + }) + .map((entry) => { + const key = entry[0]; + const value = entry[1]; + + return { + name: key, + guard_name: createGlobalGuard(value.guard, key) + }; + }); +} + +function createReturnFunction( + canisterOptions: CanisterOptions +): _AzleFunctionReturnType { + return (principal: Principal) => { const callbacks = Object.entries(canisterOptions).reduce( (acc, entry) => { const key = entry[0]; @@ -65,7 +188,7 @@ export function Canister( canisterCallback: value.callback, crossCanisterCallback: (...args: any[]) => { return serviceCall( - this.principal as any, + principal as any, key, value.paramCandidTypes, value.returnCandidType @@ -78,213 +201,110 @@ export function Canister( {} ); - const initOption = Object.entries(canisterOptions).find( - ([key, value]) => value.mode === 'init' - ); - const init = - initOption === undefined - ? undefined - : { - name: initOption[0] - }; - - const postUpgradeOption = Object.entries(canisterOptions).find( - ([key, value]) => value.mode === 'postUpgrade' - ); - const postUpgrade = - postUpgradeOption === undefined - ? undefined - : { - name: postUpgradeOption[0] - }; - - const preUpgradeOption = Object.entries(canisterOptions).find( - ([key, value]) => value.mode === 'preUpgrade' - ); - const preUpgrade = - preUpgradeOption === undefined - ? undefined - : { - name: preUpgradeOption[0] - }; - - const heartbeatOption = Object.entries(canisterOptions).find( - ([key, value]) => value.mode === 'heartbeat' - ); - const heartbeat = - heartbeatOption === undefined - ? undefined - : { - name: heartbeatOption[0] - }; - - const inspectMessageOption = Object.entries(canisterOptions).find( - ([key, value]) => value.mode === 'inspectMessage' - ); - const inspectMessage = - inspectMessageOption === undefined - ? undefined - : { - name: inspectMessageOption[0] - }; - - const queries = Object.entries(canisterOptions) - .filter((entry) => { - const key = entry[0]; - const value = entry[1]; - - return value.mode === 'query'; - }) - .map((entry) => { - const key = entry[0]; - const value = entry[1]; + return { + ...callbacks, + principal + }; + }; +} - return { - name: key, - composite: value.async, - guard_name: createGlobalGuard(value.guard, key) - }; - }); +function createGetIdlFunction(canisterOptions: CanisterOptions) { + return (parents: Parent[]): IDL.ServiceClass => { + const serviceFunctionInfo = canisterOptions as ServiceFunctionInfo; - const updates = Object.entries(canisterOptions) - .filter((entry) => { - const key = entry[0]; - const value = entry[1]; + const record = Object.entries(serviceFunctionInfo).reduce( + (accumulator, [methodName, functionInfo]) => { + const paramIdlTypes = toParamIDLTypes( + functionInfo.paramCandidTypes, + parents + ); + const returnIdlTypes = toReturnIDLType( + functionInfo.returnCandidType, + parents + ); - return value.mode === 'update'; - }) - .map((entry) => { - const key = entry[0]; - const value = entry[1]; + const mode = functionInfo.mode; + let annotations: string[] = []; + if (mode === 'update') { + // do nothing + } else if (mode === 'query') { + annotations = ['query']; + } else { + // We don't want init, post upgrade, etc showing up in the idl + return accumulator; + } return { - name: key, - guard_name: createGlobalGuard(value.guard, key) + ...accumulator, + [methodName]: IDL.Func( + paramIdlTypes, + returnIdlTypes, + annotations + ) }; - }); - - let returnFunction: _AzleFunctionReturnType = ( - principal: Principal - ) => { - const callbacks = Object.entries(canisterOptions).reduce( - (acc, entry) => { - const key = entry[0]; - const value = entry[1]; - - return { - ...acc, - [key]: { - canisterCallback: value.callback, - crossCanisterCallback: (...args: any[]) => { - return serviceCall( - principal as any, - key, - value.paramCandidTypes, - value.returnCandidType - )(...args); - } - } - }; - // } - }, - {} - ); - - return { - ...callbacks, - principal - }; - }; - - returnFunction.init = init; - returnFunction.post_upgrade = postUpgrade; - returnFunction.pre_upgrade = preUpgrade; - returnFunction.heartbeat = heartbeat; - returnFunction.inspect_message = inspectMessage; - returnFunction.queries = queries; - returnFunction.updates = updates; - returnFunction.callbacks = callbacks; - returnFunction.getSystemFunctionIDLs = ( - parents: Parent[] - ): IDL.FuncClass[] => { - const serviceFunctionInfo = canisterOptions as ServiceFunctionInfo; - - return Object.entries(serviceFunctionInfo).reduce( - (accumulator, [_methodName, functionInfo]) => { - 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.paramCandidTypes, - parents - ); - const returnRealIdl = toReturnIDLType( - functionInfo.returnCandidType, - parents - ); - return [ - ...accumulator, - IDL.Func(paramRealIdls, returnRealIdl, [mode]) - ]; - }, - [] as IDL.FuncClass[] - ); - }; - returnFunction.getIDL = (parents: Parent[]): IDL.ServiceClass => { - const serviceFunctionInfo = canisterOptions as ServiceFunctionInfo; - - const record = Object.entries(serviceFunctionInfo).reduce( - (accumulator, [methodName, functionInfo]) => { - const paramIdlTypes = toParamIDLTypes( - functionInfo.paramCandidTypes, - parents - ); - const returnIdlTypes = toReturnIDLType( - functionInfo.returnCandidType, - parents - ); - - const mode = functionInfo.mode; - let annotations: string[] = []; - if (mode === 'update') { - // do nothing - } else if (mode === 'query') { - annotations = ['query']; - } else { - // We don't want init, post upgrade, etc showing up in the idl - return accumulator; - } - - return { - ...accumulator, - [methodName]: IDL.Func( - paramIdlTypes, - returnIdlTypes, - annotations - ) - }; - }, - {} as Record - ); - - return IDL.Service(record); - }; + }, + {} as Record + ); - if (parentOrPrincipal !== undefined && parentOrPrincipal._isPrincipal) { - return returnFunction(parentOrPrincipal); - } + return IDL.Service(record); + }; +} - return returnFunction; +function createGetSystemFunctionIdlFunction(canisterOptions: CanisterOptions) { + return (parents: Parent[]): IDL.FuncClass[] => { + const serviceFunctionInfo = canisterOptions as ServiceFunctionInfo; + + return Object.entries(serviceFunctionInfo).reduce( + (accumulator, [_methodName, functionInfo]) => { + 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.paramCandidTypes, + parents + ); + const returnRealIdl = toReturnIDLType( + functionInfo.returnCandidType, + parents + ); + return [ + ...accumulator, + IDL.Func(paramRealIdls, returnRealIdl, [mode]) + ]; + }, + [] as IDL.FuncClass[] + ); }; - result._azleIsCanister = true; - return result as any; } -type CallRawFunction = typeof ic.callRaw | typeof ic.callRaw128; -type NotifyRawFunction = typeof ic.notifyRaw; +function createReturnFunctionObject(canisterOptions: CanisterOptions) { + let returnFunction = createReturnFunction(canisterOptions); + returnFunction.init = createSystemMethod('init', canisterOptions); + returnFunction.heartbeat = createSystemMethod('heartbeat', canisterOptions); + returnFunction.post_upgrade = createSystemMethod( + 'postUpgrade', + canisterOptions + ); + returnFunction.pre_upgrade = createSystemMethod( + 'preUpgrade', + canisterOptions + ); + returnFunction.inspect_message = createSystemMethod( + 'inspectMessage', + canisterOptions + ); + returnFunction.queries = createQueryMethods(canisterOptions); + returnFunction.updates = createUpdateMethods(canisterOptions); + returnFunction.callbacks = createCallbacks(canisterOptions); + returnFunction.getIDL = createGetIdlFunction(canisterOptions); + returnFunction.getSystemFunctionIDLs = + createGetSystemFunctionIdlFunction(canisterOptions); + + return returnFunction; +} function serviceCall( canisterId: Principal, @@ -327,6 +347,7 @@ function serviceCall( } }; } + function createGlobalGuard( guard: (() => any) | undefined, functionName: string @@ -341,13 +362,3 @@ function createGlobalGuard( return guardName; } - -type FunctionInfo = { - mode: 'query' | 'update'; - paramCandidTypes: CandidType[]; - returnCandidType: CandidType; -}; - -interface ServiceFunctionInfo { - [key: string]: FunctionInfo; -} From c00ab7a722b8a0576e76a01d3ea3a1e2b029064e Mon Sep 17 00:00:00 2001 From: Benjamin DeMann Date: Tue, 17 Oct 2023 15:52:28 -0600 Subject: [PATCH 08/36] make service more declarative --- src/lib/candid/types/reference/service.ts | 364 ------------------ .../service/canister_function/index.ts | 221 +++++++++++ .../service/canister_function/query_update.ts | 73 ++++ .../canister_function/system_methods.ts | 56 +++ .../candid/types/reference/service/index.ts | 45 +++ 5 files changed, 395 insertions(+), 364 deletions(-) delete mode 100644 src/lib/candid/types/reference/service.ts create mode 100644 src/lib/candid/types/reference/service/canister_function/index.ts create mode 100644 src/lib/candid/types/reference/service/canister_function/query_update.ts create mode 100644 src/lib/candid/types/reference/service/canister_function/system_methods.ts create mode 100644 src/lib/candid/types/reference/service/index.ts diff --git a/src/lib/candid/types/reference/service.ts b/src/lib/candid/types/reference/service.ts deleted file mode 100644 index 88c0fa964a..0000000000 --- a/src/lib/candid/types/reference/service.ts +++ /dev/null @@ -1,364 +0,0 @@ -import { - TypeMapping, - Parent, - toParamIDLTypes, - toReturnIDLType, - CandidType -} from '../../index'; -import { _AzleRecursiveFunction } from '../../recursive'; -import { ic } from '../../../ic'; -import { Principal } from './principal'; -import { IDL } from '@dfinity/candid'; -import { CanisterMethodInfo } from '../../../canister_methods'; -import { decode, encode } from '../../serde'; - -type CanisterOptions = { - [key: string]: CanisterMethodInfo; -}; - -type _AzleFunctionReturnType = { - (principal: Principal): void; - init?: any; - post_upgrade?: any; - pre_upgrade?: any; - heartbeat?: any; - inspect_message?: any; - queries?: any[]; - updates?: any[]; - callbacks?: any; - getSystemFunctionIDLs?: (parents: Parent[]) => IDL.FuncClass[]; - getIDL?: (parents: Parent[]) => IDL.Type; -}; - -type _AzleCanisterReturnType = { - (parentOrPrincipal: _AzleRecursiveFunction | Principal): void; - _azleIsCanister?: boolean; -}; - -type CanisterReturn = { - [EndpointName in keyof T]: T[EndpointName] extends CanisterMethodInfo< - infer Params, - infer Return - > - ? ( - ...args: { [K in keyof Params]: TypeMapping } - ) => Promise> - : never; -}; - -type CallableObject = { - (principal: Principal): CallableObject; -} & CanisterReturn; - -type SystemMethod = { name: string } | undefined; - -type QueryMethod = { - name: string; - composite: boolean; - guard_name: string | undefined; -}; - -type UpdateMethod = { - name: string; - guard_name: string | undefined; -}; - -type CallRawFunction = typeof ic.callRaw | typeof ic.callRaw128; -type NotifyRawFunction = typeof ic.notifyRaw; - -type FunctionInfo = { - mode: 'query' | 'update'; - paramCandidTypes: CandidType[]; - returnCandidType: CandidType; -}; - -interface ServiceFunctionInfo { - [key: string]: FunctionInfo; -} - -export function Canister( - canisterOptions: T -): CallableObject & { _azleCandidType?: '_azleCandidType' } { - let result: _AzleCanisterReturnType = (parentOrPrincipal: any) => { - const returnFunction = createReturnFunctionObject(canisterOptions); - - if (parentOrPrincipal !== undefined && parentOrPrincipal._isPrincipal) { - return returnFunction(parentOrPrincipal); - } - - return returnFunction; - }; - result._azleIsCanister = true; - return result as any; -} - -function createCallbacks(canisterOptions: CanisterOptions) { - return Object.entries(canisterOptions).reduce((acc, entry) => { - const key = entry[0]; - const value = entry[1]; - - return { - ...acc, - [key]: { - canisterCallback: value.callback, - crossCanisterCallback: (...args: any[]) => { - return serviceCall( - this.principal as any, - key, - value.paramCandidTypes, - value.returnCandidType - )(...args); - } - } - }; - // } - }, {}); -} - -function createSystemMethod( - mode: - | 'init' - | 'postUpgrade' - | 'preUpgrade' - | 'heartbeat' - | 'inspectMessage', - canisterOptions: CanisterOptions -): SystemMethod { - const methodOption = Object.entries(canisterOptions).find( - ([key, value]) => value.mode === mode - ); - return methodOption === undefined - ? undefined - : { - name: methodOption[0] - }; -} - -function createQueryMethods(canisterOptions: CanisterOptions): QueryMethod[] { - return Object.entries(canisterOptions) - .filter((entry) => { - const key = entry[0]; - const value = entry[1]; - - return value.mode === 'query'; - }) - .map((entry) => { - const key = entry[0]; - const value = entry[1]; - - return { - name: key, - composite: value.async, - guard_name: createGlobalGuard(value.guard, key) - }; - }); -} - -function createUpdateMethods(canisterOptions: CanisterOptions): UpdateMethod[] { - return Object.entries(canisterOptions) - .filter((entry) => { - const key = entry[0]; - const value = entry[1]; - - return value.mode === 'update'; - }) - .map((entry) => { - const key = entry[0]; - const value = entry[1]; - - return { - name: key, - guard_name: createGlobalGuard(value.guard, key) - }; - }); -} - -function createReturnFunction( - canisterOptions: CanisterOptions -): _AzleFunctionReturnType { - return (principal: Principal) => { - const callbacks = Object.entries(canisterOptions).reduce( - (acc, entry) => { - const key = entry[0]; - const value = entry[1]; - - return { - ...acc, - [key]: { - canisterCallback: value.callback, - crossCanisterCallback: (...args: any[]) => { - return serviceCall( - principal as any, - key, - value.paramCandidTypes, - value.returnCandidType - )(...args); - } - } - }; - // } - }, - {} - ); - - return { - ...callbacks, - principal - }; - }; -} - -function createGetIdlFunction(canisterOptions: CanisterOptions) { - return (parents: Parent[]): IDL.ServiceClass => { - const serviceFunctionInfo = canisterOptions as ServiceFunctionInfo; - - const record = Object.entries(serviceFunctionInfo).reduce( - (accumulator, [methodName, functionInfo]) => { - const paramIdlTypes = toParamIDLTypes( - functionInfo.paramCandidTypes, - parents - ); - const returnIdlTypes = toReturnIDLType( - functionInfo.returnCandidType, - parents - ); - - const mode = functionInfo.mode; - let annotations: string[] = []; - if (mode === 'update') { - // do nothing - } else if (mode === 'query') { - annotations = ['query']; - } else { - // We don't want init, post upgrade, etc showing up in the idl - return accumulator; - } - - return { - ...accumulator, - [methodName]: IDL.Func( - paramIdlTypes, - returnIdlTypes, - annotations - ) - }; - }, - {} as Record - ); - - return IDL.Service(record); - }; -} - -function createGetSystemFunctionIdlFunction(canisterOptions: CanisterOptions) { - return (parents: Parent[]): IDL.FuncClass[] => { - const serviceFunctionInfo = canisterOptions as ServiceFunctionInfo; - - return Object.entries(serviceFunctionInfo).reduce( - (accumulator, [_methodName, functionInfo]) => { - 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.paramCandidTypes, - parents - ); - const returnRealIdl = toReturnIDLType( - functionInfo.returnCandidType, - parents - ); - return [ - ...accumulator, - IDL.Func(paramRealIdls, returnRealIdl, [mode]) - ]; - }, - [] as IDL.FuncClass[] - ); - }; -} - -function createReturnFunctionObject(canisterOptions: CanisterOptions) { - let returnFunction = createReturnFunction(canisterOptions); - returnFunction.init = createSystemMethod('init', canisterOptions); - returnFunction.heartbeat = createSystemMethod('heartbeat', canisterOptions); - returnFunction.post_upgrade = createSystemMethod( - 'postUpgrade', - canisterOptions - ); - returnFunction.pre_upgrade = createSystemMethod( - 'preUpgrade', - canisterOptions - ); - returnFunction.inspect_message = createSystemMethod( - 'inspectMessage', - canisterOptions - ); - returnFunction.queries = createQueryMethods(canisterOptions); - returnFunction.updates = createUpdateMethods(canisterOptions); - returnFunction.callbacks = createCallbacks(canisterOptions); - returnFunction.getIDL = createGetIdlFunction(canisterOptions); - returnFunction.getSystemFunctionIDLs = - createGetSystemFunctionIdlFunction(canisterOptions); - - return returnFunction; -} - -function serviceCall( - canisterId: Principal, - methodName: string, - paramCandidTypes: CandidType[], - returnCandidType: CandidType -) { - // This must remain a function and not an arrow function - // in order to set the context (this) correctly - return async function ( - this: any, // TODO in lib_new this was Service, I'm not sure we need this anymore - _: '_AZLE_CROSS_CANISTER_CALL', - notify: boolean, - callFunction: CallRawFunction | NotifyRawFunction, - cycles: bigint, - ...args: any[] - ) { - const encodedArgs = encode(paramCandidTypes, args); - - if (notify) { - try { - return (callFunction as NotifyRawFunction)( - canisterId, - methodName, - encodedArgs, - cycles - ); - } catch (error) { - throw error; - } - } else { - const encodedResult = await (callFunction as CallRawFunction)( - canisterId, - methodName, - encodedArgs, - cycles - ); - - return decode(returnCandidType, encodedResult); - } - }; -} - -function createGlobalGuard( - guard: (() => any) | undefined, - functionName: string -): string | undefined { - if (guard === undefined) { - return undefined; - } - - const guardName = `_azleGuard_${functionName}`; - - (globalThis as any)[guardName] = guard; - - return guardName; -} diff --git a/src/lib/candid/types/reference/service/canister_function/index.ts b/src/lib/candid/types/reference/service/canister_function/index.ts new file mode 100644 index 0000000000..b38cd185c1 --- /dev/null +++ b/src/lib/candid/types/reference/service/canister_function/index.ts @@ -0,0 +1,221 @@ +import { + Parent, + toParamIDLTypes, + toReturnIDLType, + CandidType +} from '../../../../index'; +import { _AzleRecursiveFunction } from '../../../../recursive'; +import { ic } from '../../../../../ic'; +import { Principal } from '../../principal'; +import { IDL } from '@dfinity/candid'; +import { CanisterMethodInfo, query } from '../../../../../canister_methods'; +import { decode, encode } from '../../../../serde'; +import { createQueryMethods, createUpdateMethods } from './query_update'; +import { + createGetSystemFunctionIdlFunction, + createSystemMethod +} from './system_methods'; + +export type CanisterOptions = { + [key: string]: CanisterMethodInfo; +}; + +type _AzleFunctionReturnType = { + (principal: Principal): void; + init?: any; + post_upgrade?: any; + pre_upgrade?: any; + heartbeat?: any; + inspect_message?: any; + queries?: any[]; + updates?: any[]; + callbacks?: any; + getSystemFunctionIDLs?: (parents: Parent[]) => IDL.FuncClass[]; + getIDL?: (parents: Parent[]) => IDL.Type; +}; + +type CallRawFunction = typeof ic.callRaw | typeof ic.callRaw128; +type NotifyRawFunction = typeof ic.notifyRaw; + +type FunctionInfo = { + mode: 'query' | 'update'; + paramCandidTypes: CandidType[]; + returnCandidType: CandidType; +}; + +export interface ServiceFunctionInfo { + [key: string]: FunctionInfo; +} + +export function createCanisterFunction(canisterOptions: CanisterOptions) { + let canister = createCanisterFunctionBase(canisterOptions); + canister.init = createSystemMethod('init', canisterOptions); + canister.heartbeat = createSystemMethod('heartbeat', canisterOptions); + canister.post_upgrade = createSystemMethod('postUpgrade', canisterOptions); + canister.pre_upgrade = createSystemMethod('preUpgrade', canisterOptions); + canister.inspect_message = createSystemMethod( + 'inspectMessage', + canisterOptions + ); + canister.queries = createQueryMethods(canisterOptions); + canister.updates = createUpdateMethods(canisterOptions); + canister.callbacks = createCallbacks(canisterOptions); + canister.getIDL = createGetIdlFunction(canisterOptions); + canister.getSystemFunctionIDLs = + createGetSystemFunctionIdlFunction(canisterOptions); + + return canister; +} + +function createGetIdlFunction(canisterOptions: CanisterOptions) { + return (parents: Parent[]): IDL.ServiceClass => { + const serviceFunctionInfo = canisterOptions as ServiceFunctionInfo; + + // We don't want init, post upgrade, etc showing up in the idl + const isQueryOrUpdate = (mode: string) => { + return mode === 'query' || mode === 'update'; + }; + + const record = Object.entries(serviceFunctionInfo) + .filter(([_methodName, functionInfo]) => + isQueryOrUpdate(functionInfo.mode) + ) + .reduce( + (accumulator, [methodName, functionInfo]) => { + return { + ...accumulator, + [methodName]: createUpdateOrQueryFunctionIdl( + functionInfo, + parents + ) + }; + }, + {} as Record + ); + + return IDL.Service(record); + }; +} + +function createAnnotation(mode: 'query' | 'update'): string[] { + if (mode === 'query') { + return ['query']; + } + return []; +} + +function createUpdateOrQueryFunctionIdl( + functionInfo: FunctionInfo, + parents: Parent[] +): IDL.FuncClass { + const annotations = createAnnotation(functionInfo.mode); + const paramIdlTypes = toParamIDLTypes( + functionInfo.paramCandidTypes, + parents + ); + const returnIdlTypes = toReturnIDLType( + functionInfo.returnCandidType, + parents + ); + + return IDL.Func(paramIdlTypes, returnIdlTypes, annotations); +} + +function createCallbacks(canisterOptions: CanisterOptions) { + return Object.entries(canisterOptions).reduce((acc, entry) => { + const methodName = entry[0]; + const canisterMethod = entry[1]; + + return { + ...acc, + [methodName]: { + canisterCallback: canisterMethod.callback, + crossCanisterCallback: (...args: any[]) => { + return serviceCall( + this.principal as any, + methodName, + canisterMethod.paramCandidTypes, + canisterMethod.returnCandidType + )(...args); + } + } + }; + }, {}); +} + +function createCanisterFunctionBase( + canisterOptions: CanisterOptions +): _AzleFunctionReturnType { + return (principal: Principal) => { + const callbacks = Object.entries(canisterOptions).reduce( + (acc, entry) => { + const key = entry[0]; + const value = entry[1]; + + return { + ...acc, + [key]: { + canisterCallback: value.callback, + crossCanisterCallback: (...args: any[]) => { + return serviceCall( + principal as any, + key, + value.paramCandidTypes, + value.returnCandidType + )(...args); + } + } + }; + // } + }, + {} + ); + + return { + ...callbacks, + principal + }; + }; +} + +function serviceCall( + canisterId: Principal, + methodName: string, + paramCandidTypes: CandidType[], + returnCandidType: CandidType +) { + // This must remain a function and not an arrow function + // in order to set the context (this) correctly + return async function ( + this: any, // TODO in lib_new this was Service, I'm not sure we need this anymore + _: '_AZLE_CROSS_CANISTER_CALL', + notify: boolean, + callFunction: CallRawFunction | NotifyRawFunction, + cycles: bigint, + ...args: any[] + ) { + const encodedArgs = encode(paramCandidTypes, args); + + if (notify) { + try { + return (callFunction as NotifyRawFunction)( + canisterId, + methodName, + encodedArgs, + cycles + ); + } catch (error) { + throw error; + } + } else { + const encodedResult = await (callFunction as CallRawFunction)( + canisterId, + methodName, + encodedArgs, + cycles + ); + + return decode(returnCandidType, encodedResult); + } + }; +} diff --git a/src/lib/candid/types/reference/service/canister_function/query_update.ts b/src/lib/candid/types/reference/service/canister_function/query_update.ts new file mode 100644 index 0000000000..0f8fcb0b65 --- /dev/null +++ b/src/lib/candid/types/reference/service/canister_function/query_update.ts @@ -0,0 +1,73 @@ +import { CanisterOptions } from '.'; + +type QueryMethod = { + name: string; + composite: boolean; + guard_name: string | undefined; +}; + +type UpdateMethod = { + name: string; + guard_name: string | undefined; +}; + +export function createQueryMethods( + canisterOptions: CanisterOptions +): QueryMethod[] { + return Object.entries(canisterOptions) + .filter(([_name, canisterMethod]) => canisterMethod.mode === 'query') + .map(([methodName, canisterMethod]) => + createQueryMethod( + methodName, + canisterMethod.async, + canisterMethod.guard + ) + ); +} + +export function createUpdateMethods( + canisterOptions: CanisterOptions +): UpdateMethod[] { + return Object.entries(canisterOptions) + .filter(([_name, canisterMethod]) => canisterMethod.mode === 'update') + .map(([methodName, canisterMethod]) => + createUpdateMethod(methodName, canisterMethod.guard) + ); +} + +function createQueryMethod( + methodName: string, + isComposite: boolean, + guardFunction: (() => any) | undefined +): QueryMethod { + return { + name: methodName, + composite: isComposite, + guard_name: createGlobalGuard(guardFunction, methodName) + }; +} + +function createUpdateMethod( + methodName: string, + guardFunction: (() => any) | undefined +): UpdateMethod { + return { + name: methodName, + guard_name: createGlobalGuard(guardFunction, methodName) + }; +} + +function createGlobalGuard( + guard: (() => any) | undefined, + guardedMethodName: string +): string | undefined { + if (guard === undefined) { + return undefined; + } + + const guardName = `_azleGuard_${guardedMethodName}`; + + (globalThis as any)[guardName] = guard; + + return guardName; +} diff --git a/src/lib/candid/types/reference/service/canister_function/system_methods.ts b/src/lib/candid/types/reference/service/canister_function/system_methods.ts new file mode 100644 index 0000000000..05303ccd81 --- /dev/null +++ b/src/lib/candid/types/reference/service/canister_function/system_methods.ts @@ -0,0 +1,56 @@ +import { Parent, toParamIDLTypes, toReturnIDLType } from '../../../../index'; +import { _AzleRecursiveFunction } from '../../../../recursive'; +import { IDL } from '@dfinity/candid'; +import { CanisterOptions, ServiceFunctionInfo } from '.'; + +type SystemMethod = { name: string } | 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] + }; +} + +export function createGetSystemFunctionIdlFunction( + canisterOptions: CanisterOptions +) { + return (parents: Parent[]): IDL.FuncClass[] => { + const serviceFunctionInfo = canisterOptions as ServiceFunctionInfo; + + return Object.entries(serviceFunctionInfo).reduce( + (accumulator, [_methodName, functionInfo]) => { + const mode = functionInfo.mode; + const isSystemMethod = !(mode === 'update' || mode === 'query'); + if (!isSystemMethod) { + // IDLs that are in update and query are already accounted for in the standard getIdl function + return accumulator; + } + + const paramIdls = toParamIDLTypes( + functionInfo.paramCandidTypes, + parents + ); + const returnIdl = toReturnIDLType( + functionInfo.returnCandidType, + parents + ); + return [...accumulator, IDL.Func(paramIdls, returnIdl, [mode])]; + }, + [] as IDL.FuncClass[] + ); + }; +} diff --git a/src/lib/candid/types/reference/service/index.ts b/src/lib/candid/types/reference/service/index.ts new file mode 100644 index 0000000000..0dbbe61bb2 --- /dev/null +++ b/src/lib/candid/types/reference/service/index.ts @@ -0,0 +1,45 @@ +import { TypeMapping } from '../../../index'; +import { _AzleRecursiveFunction } from '../../../recursive'; +import { Principal } from '../principal'; +import { CanisterMethodInfo } from '../../../../canister_methods'; +import { createCanisterFunction } from './canister_function'; + +type CanisterOptions = { + [key: string]: CanisterMethodInfo; +}; + +type CanisterReturn = { + [EndpointName in keyof T]: T[EndpointName] extends CanisterMethodInfo< + infer Params, + infer Return + > + ? ( + ...args: { [K in keyof Params]: TypeMapping } + ) => Promise> + : never; +}; + +type CallableObject = { + (principal: Principal): CallableObject; +} & CanisterReturn; + +type _AzleCanisterReturnType = { + (parentOrPrincipal: _AzleRecursiveFunction | Principal): void; + _azleIsCanister?: boolean; +}; + +export function Canister( + canisterOptions: T +): CallableObject & { _azleCandidType?: '_azleCandidType' } { + let result: _AzleCanisterReturnType = (parentOrPrincipal: any) => { + const canisterFunction = createCanisterFunction(canisterOptions); + + if (parentOrPrincipal !== undefined && parentOrPrincipal._isPrincipal) { + return canisterFunction(parentOrPrincipal); + } + + return canisterFunction; + }; + result._azleIsCanister = true; + return result as any; +} From 4e0c1bbe46ea9cdad6046229914f614b06b55cad Mon Sep 17 00:00:00 2001 From: Benjamin DeMann Date: Tue, 17 Oct 2023 16:07:50 -0600 Subject: [PATCH 09/36] rename toIdl --- src/lib/candid/index.ts | 44 +----------------- src/lib/candid/serde/index.ts | 10 ++--- src/lib/candid/serde/visitors/index.ts | 4 +- src/lib/candid/to_Idl.ts | 45 +++++++++++++++++++ src/lib/candid/types/constructed/index.ts | 21 +++++---- src/lib/candid/types/constructed/opt.ts | 4 +- src/lib/candid/types/constructed/record.ts | 4 +- src/lib/candid/types/constructed/tuple.ts | 8 ++-- src/lib/candid/types/constructed/variant.ts | 4 +- src/lib/candid/types/constructed/vec.ts | 5 +-- src/lib/candid/types/reference/func.ts | 6 +-- .../service/canister_function/index.ts | 16 +++---- .../canister_function/system_methods.ts | 6 +-- src/lib/system_types/result.ts | 6 +-- 14 files changed, 89 insertions(+), 94 deletions(-) create mode 100644 src/lib/candid/to_Idl.ts diff --git a/src/lib/candid/index.ts b/src/lib/candid/index.ts index 93c997df2f..9bd8b152ba 100644 --- a/src/lib/candid/index.ts +++ b/src/lib/candid/index.ts @@ -28,6 +28,7 @@ export * from './types/constructed'; export * from './types/primitive'; export * from './types/reference'; export * from './recursive'; +export * from './to_Idl'; export type TypeMapping = RecursionLevel extends 10 ? T @@ -109,46 +110,3 @@ export type TypeMapping = RecursionLevel extends 10 export type CandidType = { _azleCandidType?: '_azleCandidType'; }; - -export type Parent = { - idl: IDL.RecClass; - name: string; -}; - -export function toIDLType( - candidType: CandidType, - parents: Parent[] = [] -): IDL.Type { - if ('_azleName' in candidType) { - const parent = parents.find( - (parent) => parent.name === candidType._azleName - ); - // If the parent isn't undefined (ie we found one with the same name) - // this is a recursive type and we should return the parent rec idl - // instead of calling getIDL - if (parent !== undefined) { - return parent.idl; - } - } - if ('_azleIsCanister' in candidType && candidType._azleIsCanister) { - return toIDLType((candidType as any)(), parents); - } - // All CandidTypes ought to have a getIDL function defined for them - return (candidType as any).getIDL(parents); -} - -export function toParamIDLTypes( - paramCandidTypes: CandidType[], - parents: Parent[] = [] -): IDL.Type[] { - return paramCandidTypes.map((value) => toIDLType(value, parents)); -} - -export function toReturnIDLType( - returnCandidType: CandidType, - parents: Parent[] = [] -): IDL.Type[] { - const idlType = toIDLType(returnCandidType, parents); - - return Array.isArray(idlType) ? idlType : [idlType]; -} diff --git a/src/lib/candid/serde/index.ts b/src/lib/candid/serde/index.ts index 2823e6b405..3e4c30d4d0 100644 --- a/src/lib/candid/serde/index.ts +++ b/src/lib/candid/serde/index.ts @@ -3,7 +3,7 @@ import { IDL } from '@dfinity/candid'; import { AzleVec, AzleOpt, AzleTuple } from '../types/constructed'; import { DecodeVisitor } from './visitors/decode_visitor'; import { EncodeVisitor } from './visitors/encode_visitor'; -import { CandidType, Parent, toIDLType } from '../../candid'; +import { CandidType, toIdl } from '../../candid'; /** * Encodes the provided value as candid blob of the designated type. @@ -55,7 +55,7 @@ export function decode( } function encodeSingle(candidType: CandidType, data: any): Uint8Array { - const idl = toIDLType(candidType); + const idl = toIdl(candidType); const idlIsAzleVoid = Array.isArray(idl); @@ -76,7 +76,7 @@ function decodeSingle(candidType: CandidType, data: ArrayBuffer): any { // needs to be aligned so that this isn't an error. Both are representing // candid IDLs, either from the @dfinity/candid library or the // Azle-augmented ones - const idl = toIDLType(candidType); + const idl = toIdl(candidType); const idlIsAzleVoid = Array.isArray(idl); @@ -99,7 +99,7 @@ function encodeMultiple(candidTypes: CandidType[], data: any[]): Uint8Array { }>( (acc, datum, index) => { const candidType = candidTypes[index]; - const idl = toIDLType(candidType); + const idl = toIdl(candidType); const encodeReadyValue = idl.accept(new EncodeVisitor(), { candidType: candidType, @@ -118,7 +118,7 @@ function encodeMultiple(candidTypes: CandidType[], data: any[]): Uint8Array { } function decodeMultiple(candidTypes: CandidType[], data: ArrayBuffer): any[] { - const idls = candidTypes.map((candidType) => toIDLType(candidType)); + const idls = candidTypes.map((candidType) => toIdl(candidType)); const decoded = IDL.decode(idls, data); return idls.map((idl, index) => idl.accept(new DecodeVisitor(), { diff --git a/src/lib/candid/serde/visitors/index.ts b/src/lib/candid/serde/visitors/index.ts index d370f0ea9a..b84f56710b 100644 --- a/src/lib/candid/serde/visitors/index.ts +++ b/src/lib/candid/serde/visitors/index.ts @@ -6,8 +6,8 @@ export { EncodeVisitor, DecodeVisitor }; /* * The VisitorData gives us js_data which is the data that is about to be - * encoded or was just decoded. js_class is the CandidClass (IDLable) class that - * can be used to create the class. + * encoded or was just decoded. js_class is the CandidType that can be used to + * create the class. */ export type VisitorData = { js_data: any; candidType: any }; /** diff --git a/src/lib/candid/to_Idl.ts b/src/lib/candid/to_Idl.ts new file mode 100644 index 0000000000..6ca282239b --- /dev/null +++ b/src/lib/candid/to_Idl.ts @@ -0,0 +1,45 @@ +import { IDL } from '@dfinity/candid'; +import { CandidType } from '.'; + +export type Parent = { + idl: IDL.RecClass; + name: string; +}; + +export function toIdl( + candidType: CandidType, + parents: Parent[] = [] +): IDL.Type { + if ('_azleName' in candidType) { + const parent = parents.find( + (parent) => parent.name === candidType._azleName + ); + // If the parent isn't undefined (ie we found one with the same name) + // this is a recursive type and we should return the parent rec idl + // instead of calling getIDL + if (parent !== undefined) { + return parent.idl; + } + } + if ('_azleIsCanister' in candidType && candidType._azleIsCanister) { + return toIdl((candidType as any)(), parents); + } + // All CandidTypes ought to have a getIDL function defined for them + return (candidType as any).getIDL(parents); +} + +export function toParamIdls( + paramCandidTypes: CandidType[], + parents: Parent[] = [] +): IDL.Type[] { + return paramCandidTypes.map((value) => toIdl(value, parents)); +} + +export function toReturnIdl( + returnCandidType: CandidType, + parents: Parent[] = [] +): IDL.Type[] { + const idlType = toIdl(returnCandidType, parents); + + return Array.isArray(idlType) ? idlType : [idlType]; +} diff --git a/src/lib/candid/types/constructed/index.ts b/src/lib/candid/types/constructed/index.ts index b0cc78fac7..53e28e3ed0 100644 --- a/src/lib/candid/types/constructed/index.ts +++ b/src/lib/candid/types/constructed/index.ts @@ -1,4 +1,4 @@ -import { CandidType, Parent, toIDLType } from '../../index'; +import { CandidType, Parent, toIdl } from '../../index'; import { IDL } from '@dfinity/candid'; export * from './blob'; @@ -8,19 +8,18 @@ export * from './tuple'; export * from './variant'; export * from './vec'; -type CandidMap = { [key: string]: CandidType }; -type IdlMap = { [key: string]: IDL.Type }; +export type CandidMap = { [key: string]: CandidType }; +export type IdlMap = { [key: string]: IDL.Type }; -export function processMap(targetMap: CandidMap, parent: Parent[]): IdlMap { - const newMap: IdlMap = {}; +export function toIdlMap(candidMap: CandidMap, parent: Parent[]): IdlMap { + const idlMap: IdlMap = {}; - for (const key in targetMap) { - if (targetMap.hasOwnProperty(key)) { - const value = targetMap[key]; - const newValue = toIDLType(value, parent); - newMap[key] = newValue; + for (const key in candidMap) { + if (candidMap.hasOwnProperty(key)) { + const candidType = candidMap[key]; + idlMap[key] = toIdl(candidType, parent); } } - return newMap; + return idlMap; } diff --git a/src/lib/candid/types/constructed/opt.ts b/src/lib/candid/types/constructed/opt.ts index 1733d16fbc..74c7bf06e3 100644 --- a/src/lib/candid/types/constructed/opt.ts +++ b/src/lib/candid/types/constructed/opt.ts @@ -1,4 +1,4 @@ -import { CandidType, Parent, toIDLType } from '../../index'; +import { CandidType, Parent, toIdl } from '../../index'; import { RequireExactlyOne } from './variant'; import { IDL } from '@dfinity/candid'; @@ -36,6 +36,6 @@ export class AzleOpt { _kind: 'AzleOpt' = 'AzleOpt'; getIDL(parents: Parent[]) { - return IDL.Opt(toIDLType(this._azleType, parents)); + return IDL.Opt(toIdl(this._azleType, parents)); } } diff --git a/src/lib/candid/types/constructed/record.ts b/src/lib/candid/types/constructed/record.ts index 280a0bee2b..c6601d6f88 100644 --- a/src/lib/candid/types/constructed/record.ts +++ b/src/lib/candid/types/constructed/record.ts @@ -1,6 +1,6 @@ import { CandidType, TypeMapping, Parent } from '../../index'; import { IDL } from '@dfinity/candid'; -import { processMap } from '../constructed'; +import { toIdlMap, CandidMap } from '../constructed'; export function Record< T extends { @@ -14,7 +14,7 @@ export function Record< return { ...obj, getIDL(parents: Parent[]) { - return IDL.Record(processMap(obj as any, parents)); + return IDL.Record(toIdlMap(obj as CandidMap, parents)); } } as any; } diff --git a/src/lib/candid/types/constructed/tuple.ts b/src/lib/candid/types/constructed/tuple.ts index cb49c0ae6d..08e020c0ca 100644 --- a/src/lib/candid/types/constructed/tuple.ts +++ b/src/lib/candid/types/constructed/tuple.ts @@ -1,5 +1,5 @@ import { CandidType } from '../../index'; -import { Parent, toIDLType } from '../../index'; +import { Parent, toIdl } from '../../index'; import { IDL } from '@dfinity/candid'; export class AzleTuple { @@ -11,10 +11,10 @@ export class AzleTuple { _azleCandidType?: '_azleCandidType'; getIDL(parents: Parent[]) { - const candidTypes = this._azleTypes.map((value) => { - return toIDLType(value, parents); + const idls = this._azleTypes.map((value) => { + return toIdl(value, parents); }); - return IDL.Tuple(...candidTypes); + return IDL.Tuple(...idls); } } diff --git a/src/lib/candid/types/constructed/variant.ts b/src/lib/candid/types/constructed/variant.ts index 2b82e7efd6..9d91e7314d 100644 --- a/src/lib/candid/types/constructed/variant.ts +++ b/src/lib/candid/types/constructed/variant.ts @@ -1,5 +1,5 @@ import { CandidType, TypeMapping } from '../..'; -import { processMap } from '.'; +import { toIdlMap, CandidMap } from '.'; import { IDL } from '@dfinity/candid'; export function Variant< @@ -14,7 +14,7 @@ export function Variant< return { ...obj, getIDL(parents: any) { - return IDL.Variant(processMap(obj as any, parents)); + return IDL.Variant(toIdlMap(obj as CandidMap, parents)); } } as any; } diff --git a/src/lib/candid/types/constructed/vec.ts b/src/lib/candid/types/constructed/vec.ts index 6f9947307c..2ed97d9fa6 100644 --- a/src/lib/candid/types/constructed/vec.ts +++ b/src/lib/candid/types/constructed/vec.ts @@ -1,5 +1,5 @@ import { CandidType } from '../../index'; -import { Parent, toIDLType } from '../../index'; +import { Parent, toIdl } from '../../index'; import { IDL } from '@dfinity/candid'; export class AzleVec { @@ -11,12 +11,11 @@ export class AzleVec { _azleCandidType?: '_azleCandidType'; getIDL(parents: Parent[]) { - return IDL.Vec(toIDLType(this._azleType, parents)); + return IDL.Vec(toIdl(this._azleType, parents)); } } export type Vec = T[]; export function Vec(t: T): AzleVec { - // return IDL.Vec(toCandidClass(t)); return new AzleVec(t); } diff --git a/src/lib/candid/types/reference/func.ts b/src/lib/candid/types/reference/func.ts index aa3483a826..1a46cc0bdc 100644 --- a/src/lib/candid/types/reference/func.ts +++ b/src/lib/candid/types/reference/func.ts @@ -1,7 +1,7 @@ import { CandidType } from '../../index'; import { IDL } from '@dfinity/candid'; import { Principal } from './principal'; -import { Parent, toParamIDLTypes, toReturnIDLType } from '../../index'; +import { Parent, toParamIdls, toReturnIdl } from '../../index'; type Mode = 'query' | 'update' | 'oneway'; @@ -19,8 +19,8 @@ export function Func( return { getIDL(parents: Parent[]) { return IDL.Func( - toParamIDLTypes(paramCandidTypes, parents), - toReturnIDLType(returnCandidTypes, parents), + toParamIdls(paramCandidTypes, parents), + toReturnIdl(returnCandidTypes, parents), modeToCandid[mode] ); } diff --git a/src/lib/candid/types/reference/service/canister_function/index.ts b/src/lib/candid/types/reference/service/canister_function/index.ts index b38cd185c1..fbd3dac632 100644 --- a/src/lib/candid/types/reference/service/canister_function/index.ts +++ b/src/lib/candid/types/reference/service/canister_function/index.ts @@ -1,7 +1,7 @@ import { Parent, - toParamIDLTypes, - toReturnIDLType, + toParamIdls, + toReturnIdl, CandidType } from '../../../../index'; import { _AzleRecursiveFunction } from '../../../../recursive'; @@ -109,16 +109,10 @@ function createUpdateOrQueryFunctionIdl( parents: Parent[] ): IDL.FuncClass { const annotations = createAnnotation(functionInfo.mode); - const paramIdlTypes = toParamIDLTypes( - functionInfo.paramCandidTypes, - parents - ); - const returnIdlTypes = toReturnIDLType( - functionInfo.returnCandidType, - parents - ); + const paramIdls = toParamIdls(functionInfo.paramCandidTypes, parents); + const returnIdls = toReturnIdl(functionInfo.returnCandidType, parents); - return IDL.Func(paramIdlTypes, returnIdlTypes, annotations); + return IDL.Func(paramIdls, returnIdls, annotations); } function createCallbacks(canisterOptions: CanisterOptions) { diff --git a/src/lib/candid/types/reference/service/canister_function/system_methods.ts b/src/lib/candid/types/reference/service/canister_function/system_methods.ts index 05303ccd81..5fce6ebb95 100644 --- a/src/lib/candid/types/reference/service/canister_function/system_methods.ts +++ b/src/lib/candid/types/reference/service/canister_function/system_methods.ts @@ -1,4 +1,4 @@ -import { Parent, toParamIDLTypes, toReturnIDLType } from '../../../../index'; +import { Parent, toParamIdls, toReturnIdl } from '../../../../index'; import { _AzleRecursiveFunction } from '../../../../recursive'; import { IDL } from '@dfinity/candid'; import { CanisterOptions, ServiceFunctionInfo } from '.'; @@ -40,11 +40,11 @@ export function createGetSystemFunctionIdlFunction( return accumulator; } - const paramIdls = toParamIDLTypes( + const paramIdls = toParamIdls( functionInfo.paramCandidTypes, parents ); - const returnIdl = toReturnIDLType( + const returnIdl = toReturnIdl( functionInfo.returnCandidType, parents ); diff --git a/src/lib/system_types/result.ts b/src/lib/system_types/result.ts index d4b90978c5..2e6542157c 100644 --- a/src/lib/system_types/result.ts +++ b/src/lib/system_types/result.ts @@ -1,4 +1,4 @@ -import { Parent, toIDLType, CandidType } from '../candid'; +import { Parent, toIdl, CandidType } from '../candid'; import { RequireExactlyOne } from '../candid/types/constructed/variant'; import { IDL } from '@dfinity/candid'; @@ -15,8 +15,8 @@ export class AzleResult { getIDL(parents: Parent[]) { return IDL.Variant({ - Ok: toIDLType(this._azleOk, parents), - Err: toIDLType(this._azleErr, parents) + Ok: toIdl(this._azleOk, parents), + Err: toIdl(this._azleErr, parents) }); } } From 91ff2f69258ccbad20a6a9b8a2728d0eed615fe2 Mon Sep 17 00:00:00 2001 From: Benjamin DeMann Date: Tue, 17 Oct 2023 16:14:55 -0600 Subject: [PATCH 10/36] uniformize capitalization of IDL in function names --- src/compiler/generate_candid_and_canister_methods.ts | 4 ++-- src/lib/candid/recursive.ts | 6 +++--- src/lib/candid/to_Idl.ts | 6 +++--- src/lib/candid/types/constructed/blob.ts | 2 +- src/lib/candid/types/constructed/opt.ts | 2 +- src/lib/candid/types/constructed/record.ts | 2 +- src/lib/candid/types/constructed/tuple.ts | 2 +- src/lib/candid/types/constructed/variant.ts | 2 +- src/lib/candid/types/constructed/vec.ts | 2 +- src/lib/candid/types/primitive/bool.ts | 2 +- src/lib/candid/types/primitive/empty.ts | 2 +- src/lib/candid/types/primitive/floats/float32.ts | 2 +- src/lib/candid/types/primitive/floats/float64.ts | 2 +- src/lib/candid/types/primitive/ints/int.ts | 2 +- src/lib/candid/types/primitive/ints/int16.ts | 2 +- src/lib/candid/types/primitive/ints/int32.ts | 2 +- src/lib/candid/types/primitive/ints/int64.ts | 2 +- src/lib/candid/types/primitive/ints/int8.ts | 2 +- src/lib/candid/types/primitive/nats/nat.ts | 2 +- src/lib/candid/types/primitive/nats/nat16.ts | 2 +- src/lib/candid/types/primitive/nats/nat32.ts | 2 +- src/lib/candid/types/primitive/nats/nat64.ts | 2 +- src/lib/candid/types/primitive/nats/nat8.ts | 2 +- src/lib/candid/types/primitive/null.ts | 2 +- src/lib/candid/types/primitive/reserved.ts | 2 +- src/lib/candid/types/primitive/text.ts | 2 +- src/lib/candid/types/primitive/void.ts | 2 +- src/lib/candid/types/reference/func.ts | 2 +- src/lib/candid/types/reference/principal.ts | 2 +- .../types/reference/service/canister_function/index.ts | 8 ++++---- src/lib/system_types/result.ts | 2 +- 31 files changed, 39 insertions(+), 39 deletions(-) diff --git a/src/compiler/generate_candid_and_canister_methods.ts b/src/compiler/generate_candid_and_canister_methods.ts index d131710925..a57db95414 100644 --- a/src/compiler/generate_candid_and_canister_methods.ts +++ b/src/compiler/generate_candid_and_canister_methods.ts @@ -36,10 +36,10 @@ export function generateCandidAndCanisterMethods(mainJs: string): { const canisterMethods = (sandbox.exports as any).canisterMethods; - const candidInfo = canisterMethods.getIDL([]).accept(new DidVisitor(), { + const candidInfo = canisterMethods.getIdl([]).accept(new DidVisitor(), { ...getDefaultVisitorData(), isFirstService: true, - systemFuncs: canisterMethods.getSystemFunctionIDLs() + systemFuncs: canisterMethods.getSystemFunctionIdls() }); return { diff --git a/src/lib/candid/recursive.ts b/src/lib/candid/recursive.ts index 77dc55abbb..9eb11a3042 100644 --- a/src/lib/candid/recursive.ts +++ b/src/lib/candid/recursive.ts @@ -6,7 +6,7 @@ export type _AzleRecursiveFunction = { (...args: any[]): CandidType; _azleName?: string; _azleIsRecursive?: boolean; - getIDL?: (parents: Parent[]) => IDL.Type; + getIdl?: (parents: Parent[]) => IDL.Type; }; export function Recursive(candidTypeCallback: any): any { @@ -22,13 +22,13 @@ export function Recursive(candidTypeCallback: any): any { result._azleName = name; result._azleIsRecursive = true; - result.getIDL = (parents: Parent[]) => { + result.getIdl = (parents: Parent[]) => { const idl = IDL.Rec(); let filler = candidTypeCallback(); if (filler._azleIsCanister) { filler = filler(result); } - idl.fill(filler.getIDL([...parents, { idl: idl, name }])); + idl.fill(filler.getIdl([...parents, { idl: idl, name }])); return idl; }; diff --git a/src/lib/candid/to_Idl.ts b/src/lib/candid/to_Idl.ts index 6ca282239b..1b6ff9c6af 100644 --- a/src/lib/candid/to_Idl.ts +++ b/src/lib/candid/to_Idl.ts @@ -16,7 +16,7 @@ export function toIdl( ); // If the parent isn't undefined (ie we found one with the same name) // this is a recursive type and we should return the parent rec idl - // instead of calling getIDL + // instead of calling getIdl if (parent !== undefined) { return parent.idl; } @@ -24,8 +24,8 @@ export function toIdl( if ('_azleIsCanister' in candidType && candidType._azleIsCanister) { return toIdl((candidType as any)(), parents); } - // All CandidTypes ought to have a getIDL function defined for them - return (candidType as any).getIDL(parents); + // All CandidTypes ought to have a getIdl function defined for them + return (candidType as any).getIdl(parents); } export function toParamIdls( diff --git a/src/lib/candid/types/constructed/blob.ts b/src/lib/candid/types/constructed/blob.ts index e2d552057c..2d4e178a3c 100644 --- a/src/lib/candid/types/constructed/blob.ts +++ b/src/lib/candid/types/constructed/blob.ts @@ -4,7 +4,7 @@ export class AzleBlob { _kind: 'AzleBlob' = 'AzleBlob'; _azleCandidType?: '_azleCandidType'; - static getIDL() { + static getIdl() { return IDL.Vec(IDL.Nat8); } } diff --git a/src/lib/candid/types/constructed/opt.ts b/src/lib/candid/types/constructed/opt.ts index 74c7bf06e3..510f8981a8 100644 --- a/src/lib/candid/types/constructed/opt.ts +++ b/src/lib/candid/types/constructed/opt.ts @@ -35,7 +35,7 @@ export class AzleOpt { _azleCandidType?: '_azleCandidType'; _kind: 'AzleOpt' = 'AzleOpt'; - getIDL(parents: Parent[]) { + getIdl(parents: Parent[]) { return IDL.Opt(toIdl(this._azleType, parents)); } } diff --git a/src/lib/candid/types/constructed/record.ts b/src/lib/candid/types/constructed/record.ts index c6601d6f88..e1a3397920 100644 --- a/src/lib/candid/types/constructed/record.ts +++ b/src/lib/candid/types/constructed/record.ts @@ -13,7 +13,7 @@ export function Record< } & { _azleCandidType?: '_azleCandidType' } { return { ...obj, - getIDL(parents: Parent[]) { + getIdl(parents: Parent[]) { return IDL.Record(toIdlMap(obj as CandidMap, parents)); } } as any; diff --git a/src/lib/candid/types/constructed/tuple.ts b/src/lib/candid/types/constructed/tuple.ts index 08e020c0ca..8465379e01 100644 --- a/src/lib/candid/types/constructed/tuple.ts +++ b/src/lib/candid/types/constructed/tuple.ts @@ -10,7 +10,7 @@ export class AzleTuple { _azleTypes: CandidType[]; _azleCandidType?: '_azleCandidType'; - getIDL(parents: Parent[]) { + getIdl(parents: Parent[]) { const idls = this._azleTypes.map((value) => { return toIdl(value, parents); }); diff --git a/src/lib/candid/types/constructed/variant.ts b/src/lib/candid/types/constructed/variant.ts index 9d91e7314d..2a6f658878 100644 --- a/src/lib/candid/types/constructed/variant.ts +++ b/src/lib/candid/types/constructed/variant.ts @@ -13,7 +13,7 @@ export function Variant< }> & { _azleCandidType?: '_azleCandidType' } { return { ...obj, - getIDL(parents: any) { + getIdl(parents: any) { return IDL.Variant(toIdlMap(obj as CandidMap, parents)); } } as any; diff --git a/src/lib/candid/types/constructed/vec.ts b/src/lib/candid/types/constructed/vec.ts index 2ed97d9fa6..3901fc4c92 100644 --- a/src/lib/candid/types/constructed/vec.ts +++ b/src/lib/candid/types/constructed/vec.ts @@ -10,7 +10,7 @@ export class AzleVec { _azleType: CandidType; _azleCandidType?: '_azleCandidType'; - getIDL(parents: Parent[]) { + getIdl(parents: Parent[]) { return IDL.Vec(toIdl(this._azleType, parents)); } } diff --git a/src/lib/candid/types/primitive/bool.ts b/src/lib/candid/types/primitive/bool.ts index 8a02ef350e..5163a24beb 100644 --- a/src/lib/candid/types/primitive/bool.ts +++ b/src/lib/candid/types/primitive/bool.ts @@ -4,7 +4,7 @@ export class AzleBool { _kind: 'AzleBool' = 'AzleBool'; _azleCandidType?: '_azleCandidType'; - static getIDL() { + static getIdl() { return IDL.Bool; } } diff --git a/src/lib/candid/types/primitive/empty.ts b/src/lib/candid/types/primitive/empty.ts index 27d0609058..ac0b1954d5 100644 --- a/src/lib/candid/types/primitive/empty.ts +++ b/src/lib/candid/types/primitive/empty.ts @@ -4,7 +4,7 @@ export class AzleEmpty { _kind: 'AzleEmpty' = 'AzleEmpty'; _azleCandidType?: '_azleCandidType'; - static getIDL() { + static getIdl() { return IDL.Empty; } } diff --git a/src/lib/candid/types/primitive/floats/float32.ts b/src/lib/candid/types/primitive/floats/float32.ts index ae35a13244..8029f0bfdf 100644 --- a/src/lib/candid/types/primitive/floats/float32.ts +++ b/src/lib/candid/types/primitive/floats/float32.ts @@ -4,7 +4,7 @@ export class AzleFloat32 { _kind: 'AzleFloat32' = 'AzleFloat32'; _azleCandidType?: '_azleCandidType'; - static getIDL() { + static getIdl() { return IDL.Float32; } } diff --git a/src/lib/candid/types/primitive/floats/float64.ts b/src/lib/candid/types/primitive/floats/float64.ts index ee1f8dfac5..fe224b420f 100644 --- a/src/lib/candid/types/primitive/floats/float64.ts +++ b/src/lib/candid/types/primitive/floats/float64.ts @@ -4,7 +4,7 @@ export class AzleFloat64 { _kind: 'AzleFloat64' = 'AzleFloat64'; _azleCandidType?: '_azleCandidType'; - static getIDL() { + static getIdl() { return IDL.Float64; } } diff --git a/src/lib/candid/types/primitive/ints/int.ts b/src/lib/candid/types/primitive/ints/int.ts index 4ebde40e80..4ceaed8e4f 100644 --- a/src/lib/candid/types/primitive/ints/int.ts +++ b/src/lib/candid/types/primitive/ints/int.ts @@ -4,7 +4,7 @@ export class AzleInt { _kind: 'AzleInt' = 'AzleInt'; _azleCandidType?: '_azleCandidType'; - static getIDL() { + static getIdl() { return IDL.Int; } } diff --git a/src/lib/candid/types/primitive/ints/int16.ts b/src/lib/candid/types/primitive/ints/int16.ts index 4577fe8cce..e0640ee593 100644 --- a/src/lib/candid/types/primitive/ints/int16.ts +++ b/src/lib/candid/types/primitive/ints/int16.ts @@ -4,7 +4,7 @@ export class AzleInt16 { _kind: 'AzleInt16' = 'AzleInt16'; _azleCandidType?: '_azleCandidType'; - static getIDL() { + static getIdl() { return IDL.Int16; } } diff --git a/src/lib/candid/types/primitive/ints/int32.ts b/src/lib/candid/types/primitive/ints/int32.ts index a976e32531..80c54b16a1 100644 --- a/src/lib/candid/types/primitive/ints/int32.ts +++ b/src/lib/candid/types/primitive/ints/int32.ts @@ -4,7 +4,7 @@ export class AzleInt32 { _kind: 'AzleInt32' = 'AzleInt32'; _azleCandidType?: '_azleCandidType'; - static getIDL() { + static getIdl() { return IDL.Int32; } } diff --git a/src/lib/candid/types/primitive/ints/int64.ts b/src/lib/candid/types/primitive/ints/int64.ts index 3a21733a28..925adda269 100644 --- a/src/lib/candid/types/primitive/ints/int64.ts +++ b/src/lib/candid/types/primitive/ints/int64.ts @@ -4,7 +4,7 @@ export class AzleInt64 { _kind: 'AzleInt64' = 'AzleInt64'; _azleCandidType?: '_azleCandidType'; - static getIDL() { + static getIdl() { return IDL.Int64; } } diff --git a/src/lib/candid/types/primitive/ints/int8.ts b/src/lib/candid/types/primitive/ints/int8.ts index cb9e46ecc0..2d54a2951e 100644 --- a/src/lib/candid/types/primitive/ints/int8.ts +++ b/src/lib/candid/types/primitive/ints/int8.ts @@ -4,7 +4,7 @@ export class AzleInt8 { _kind: 'AzleInt8' = 'AzleInt8'; _azleCandidType?: '_azleCandidType'; - static getIDL() { + static getIdl() { return IDL.Int8; } } diff --git a/src/lib/candid/types/primitive/nats/nat.ts b/src/lib/candid/types/primitive/nats/nat.ts index 0cc7a539c0..c4f68059fc 100644 --- a/src/lib/candid/types/primitive/nats/nat.ts +++ b/src/lib/candid/types/primitive/nats/nat.ts @@ -4,7 +4,7 @@ export class AzleNat { _kind: 'AzleNat' = 'AzleNat'; _azleCandidType?: '_azleCandidType'; - static getIDL() { + static getIdl() { return IDL.Nat; } } diff --git a/src/lib/candid/types/primitive/nats/nat16.ts b/src/lib/candid/types/primitive/nats/nat16.ts index fbcd5cb783..fac8214301 100644 --- a/src/lib/candid/types/primitive/nats/nat16.ts +++ b/src/lib/candid/types/primitive/nats/nat16.ts @@ -4,7 +4,7 @@ export class AzleNat16 { _kind: 'AzleNat16' = 'AzleNat16'; _azleCandidType?: '_azleCandidType'; - static getIDL() { + static getIdl() { return IDL.Nat16; } } diff --git a/src/lib/candid/types/primitive/nats/nat32.ts b/src/lib/candid/types/primitive/nats/nat32.ts index f82a8c1c18..e4233c50c4 100644 --- a/src/lib/candid/types/primitive/nats/nat32.ts +++ b/src/lib/candid/types/primitive/nats/nat32.ts @@ -4,7 +4,7 @@ export class AzleNat32 { _kind: 'AzleNat32' = 'AzleNat32'; _azleCandidType?: '_azleCandidType'; - static getIDL() { + static getIdl() { return IDL.Nat32; } } diff --git a/src/lib/candid/types/primitive/nats/nat64.ts b/src/lib/candid/types/primitive/nats/nat64.ts index 0911576b38..5675605ac5 100644 --- a/src/lib/candid/types/primitive/nats/nat64.ts +++ b/src/lib/candid/types/primitive/nats/nat64.ts @@ -4,7 +4,7 @@ export class AzleNat64 { _kind: 'AzleNat64' = 'AzleNat64'; _azleCandidType?: '_azleCandidType'; - static getIDL() { + static getIdl() { return IDL.Nat64; } } diff --git a/src/lib/candid/types/primitive/nats/nat8.ts b/src/lib/candid/types/primitive/nats/nat8.ts index 3aa9c8fecb..74bc3c0564 100644 --- a/src/lib/candid/types/primitive/nats/nat8.ts +++ b/src/lib/candid/types/primitive/nats/nat8.ts @@ -4,7 +4,7 @@ export class AzleNat8 { _kind: 'AzleNat8' = 'AzleNat8'; _azleCandidType?: '_azleCandidType'; - static getIDL() { + static getIdl() { return IDL.Nat8; } } diff --git a/src/lib/candid/types/primitive/null.ts b/src/lib/candid/types/primitive/null.ts index 06cef35d3a..5a4d690759 100644 --- a/src/lib/candid/types/primitive/null.ts +++ b/src/lib/candid/types/primitive/null.ts @@ -4,7 +4,7 @@ export class AzleNull { _kind: 'AzleNull' = 'AzleNull'; _azleCandidType?: '_azleCandidType'; - static getIDL() { + static getIdl() { return IDL.Null; } } diff --git a/src/lib/candid/types/primitive/reserved.ts b/src/lib/candid/types/primitive/reserved.ts index 2c371657af..88e10f65fc 100644 --- a/src/lib/candid/types/primitive/reserved.ts +++ b/src/lib/candid/types/primitive/reserved.ts @@ -4,7 +4,7 @@ export class AzleReserved { _kind: 'AzleReserved' = 'AzleReserved'; _azleCandidType?: '_azleCandidType'; - static getIDL() { + static getIdl() { return IDL.Reserved; } } diff --git a/src/lib/candid/types/primitive/text.ts b/src/lib/candid/types/primitive/text.ts index 5b21662cfe..e8af782ef3 100644 --- a/src/lib/candid/types/primitive/text.ts +++ b/src/lib/candid/types/primitive/text.ts @@ -4,7 +4,7 @@ export class AzleText { _kind: 'AzleText' = 'AzleText'; _azleCandidType?: '_azleCandidType'; - static getIDL() { + static getIdl() { return IDL.Text; } } diff --git a/src/lib/candid/types/primitive/void.ts b/src/lib/candid/types/primitive/void.ts index 1bb3bca7e2..84de2348b1 100644 --- a/src/lib/candid/types/primitive/void.ts +++ b/src/lib/candid/types/primitive/void.ts @@ -2,7 +2,7 @@ export class AzleVoid { _kind: 'AzleVoid' = 'AzleVoid'; _azleCandidType?: '_azleCandidType'; - static getIDL() { + static getIdl() { return []; } } diff --git a/src/lib/candid/types/reference/func.ts b/src/lib/candid/types/reference/func.ts index 1a46cc0bdc..e5298f71c3 100644 --- a/src/lib/candid/types/reference/func.ts +++ b/src/lib/candid/types/reference/func.ts @@ -17,7 +17,7 @@ export function Func( mode: Mode ): [Principal, string] & { _azleCandidType?: '_azleCandidType' } { return { - getIDL(parents: Parent[]) { + getIdl(parents: Parent[]) { return IDL.Func( toParamIdls(paramCandidTypes, parents), toReturnIdl(returnCandidTypes, parents), diff --git a/src/lib/candid/types/reference/principal.ts b/src/lib/candid/types/reference/principal.ts index ec3156d6d0..f98637387f 100644 --- a/src/lib/candid/types/reference/principal.ts +++ b/src/lib/candid/types/reference/principal.ts @@ -4,7 +4,7 @@ import { Principal as DfinityPrincipal } from '@dfinity/principal'; export class Principal extends DfinityPrincipal { static _azleCandidType?: '_azleCandidType'; - static getIDL?() { + static getIdl?() { return IDL.Principal; } } diff --git a/src/lib/candid/types/reference/service/canister_function/index.ts b/src/lib/candid/types/reference/service/canister_function/index.ts index fbd3dac632..9fcde3bc0d 100644 --- a/src/lib/candid/types/reference/service/canister_function/index.ts +++ b/src/lib/candid/types/reference/service/canister_function/index.ts @@ -30,8 +30,8 @@ type _AzleFunctionReturnType = { queries?: any[]; updates?: any[]; callbacks?: any; - getSystemFunctionIDLs?: (parents: Parent[]) => IDL.FuncClass[]; - getIDL?: (parents: Parent[]) => IDL.Type; + getSystemFunctionIdls?: (parents: Parent[]) => IDL.FuncClass[]; + getIdl?: (parents: Parent[]) => IDL.Type; }; type CallRawFunction = typeof ic.callRaw | typeof ic.callRaw128; @@ -60,8 +60,8 @@ export function createCanisterFunction(canisterOptions: CanisterOptions) { canister.queries = createQueryMethods(canisterOptions); canister.updates = createUpdateMethods(canisterOptions); canister.callbacks = createCallbacks(canisterOptions); - canister.getIDL = createGetIdlFunction(canisterOptions); - canister.getSystemFunctionIDLs = + canister.getIdl = createGetIdlFunction(canisterOptions); + canister.getSystemFunctionIdls = createGetSystemFunctionIdlFunction(canisterOptions); return canister; diff --git a/src/lib/system_types/result.ts b/src/lib/system_types/result.ts index 2e6542157c..d8c860a66b 100644 --- a/src/lib/system_types/result.ts +++ b/src/lib/system_types/result.ts @@ -13,7 +13,7 @@ export class AzleResult { _azleCandidType?: '_azleCandidType'; - getIDL(parents: Parent[]) { + getIdl(parents: Parent[]) { return IDL.Variant({ Ok: toIdl(this._azleOk, parents), Err: toIdl(this._azleErr, parents) From 142ed96430d637a2171b12a150f701555d76b230 Mon Sep 17 00:00:00 2001 From: Benjamin DeMann Date: Tue, 17 Oct 2023 16:52:27 -0600 Subject: [PATCH 11/36] clean up globals --- examples/guard_functions/src/index.did | 10 ++-- src/compiler/rust/canister_methods/src/lib.rs | 3 +- .../service/canister_function/query_update.ts | 2 +- src/lib/globals.ts | 24 ++------ src/lib/ic/clear_timer.ts | 4 +- src/lib/ic/set_timer.ts | 4 +- src/lib/ic/set_timer_interval.ts | 2 +- src/lib/ic/types/azle_ic.ts | 33 ++++++++++- src/lib/stable_b_tree_map.ts | 59 +++++++++---------- 9 files changed, 74 insertions(+), 67 deletions(-) diff --git a/examples/guard_functions/src/index.did b/examples/guard_functions/src/index.did index 7a14f6a0a9..00693bd418 100644 --- a/examples/guard_functions/src/index.did +++ b/examples/guard_functions/src/index.did @@ -1,14 +1,14 @@ service: () -> { + callExpressionWithEmptyOptionsObject: () -> (bool) query; + callExpressionWithoutOptionsObject: () -> (bool) query; + customErrorGuarded: () -> (bool) query; + errorStringGuarded: () -> (bool) query; getCounter: () -> (nat32) query; identifierAnnotation: () -> (bool) query; - callExpressionWithoutOptionsObject: () -> (bool) query; - callExpressionWithEmptyOptionsObject: () -> (bool) query; looselyGuarded: () -> (bool) query; looselyGuardedManual: () -> (bool) query; looselyGuardedWithGuardOptionKeyAsString: () -> (bool) query; modifyStateGuarded: () -> (bool); - tightlyGuarded: () -> (bool) query; - errorStringGuarded: () -> (bool) query; - customErrorGuarded: () -> (bool) query; nonStringErrValueGuarded: () -> (bool) query; + tightlyGuarded: () -> (bool) query; } diff --git a/src/compiler/rust/canister_methods/src/lib.rs b/src/compiler/rust/canister_methods/src/lib.rs index df6d22b60c..a65b52ea20 100644 --- a/src/compiler/rust/canister_methods/src/lib.rs +++ b/src/compiler/rust/canister_methods/src/lib.rs @@ -249,7 +249,8 @@ fn get_guard_token_stream( let context = context.as_mut().unwrap(); let global = context.global_object().unwrap(); - let guard_function = global.get_property(#guard_name).unwrap(); + let guard_functions = global.get_property("_azleGuardFunctions").unwrap(); + let guard_function = guard_functions.get_property(#guard_name).unwrap(); // TODO I am not sure what the first parameter to call is supposed to be let result = guard_function.call(&guard_function, &[]); diff --git a/src/lib/candid/types/reference/service/canister_function/query_update.ts b/src/lib/candid/types/reference/service/canister_function/query_update.ts index 0f8fcb0b65..f06a9273b5 100644 --- a/src/lib/candid/types/reference/service/canister_function/query_update.ts +++ b/src/lib/candid/types/reference/service/canister_function/query_update.ts @@ -67,7 +67,7 @@ function createGlobalGuard( const guardName = `_azleGuard_${guardedMethodName}`; - (globalThis as any)[guardName] = guard; + globalThis._azleGuardFunctions[guardName] = guard; return guardName; } diff --git a/src/lib/globals.ts b/src/lib/globals.ts index cb89ddc31e..09867011ad 100644 --- a/src/lib/globals.ts +++ b/src/lib/globals.ts @@ -6,34 +6,18 @@ declare global { var _azleIc: AzleIc; var _azleResolveIds: { [key: string]: (buf: ArrayBuffer) => void }; var _azleRejectIds: { [key: string]: (err: any) => void }; - var icTimers: { [key: string]: string }; + var _azleIcTimers: { [key: string]: string }; var _azleTimerCallbackIds: { [key: string]: () => void }; - var Buffer: BufferConstructor; - // var console: Console; - // var crypto: Crypto; - var icTimers: { - [key: string]: string; - }; - // var TextDecoder: any; - // var TextEncoder: any; + var _azleGuardFunctions: { [key: string]: () => any }; } -// export declare var globalThis: { -// Buffer: BufferConstructor; -// console: any; -// crypto: { -// getRandomValues: () => Uint8Array; -// }; -// TextDecoder: any; -// TextEncoder: any; -// }; - globalThis.TextDecoder = require('text-encoding').TextDecoder; globalThis.TextEncoder = require('text-encoding').TextEncoder; -globalThis.icTimers ||= {}; +globalThis._azleIcTimers ||= {}; globalThis._azleResolveIds = {}; globalThis._azleRejectIds = {}; globalThis._azleTimerCallbackIds = {}; +globalThis._azleGuardFunctions = {}; globalThis.console = { ...globalThis.console, diff --git a/src/lib/ic/clear_timer.ts b/src/lib/ic/clear_timer.ts index 475abe858a..443d071e5a 100644 --- a/src/lib/ic/clear_timer.ts +++ b/src/lib/ic/clear_timer.ts @@ -14,8 +14,8 @@ export function clearTimer(timerId: TimerId): Void { globalThis._azleIc.clearTimer(encode(TimerId, timerId).buffer); - const timerCallbackId = globalThis.icTimers[timerId.toString()]; + const timerCallbackId = globalThis._azleIcTimers[timerId.toString()]; - delete globalThis.icTimers[timerId.toString()]; + delete globalThis._azleIcTimers[timerId.toString()]; delete globalThis._azleTimerCallbackIds[timerCallbackId]; } diff --git a/src/lib/ic/set_timer.ts b/src/lib/ic/set_timer.ts index 1a97519433..fe4fe2a5fe 100644 --- a/src/lib/ic/set_timer.ts +++ b/src/lib/ic/set_timer.ts @@ -33,13 +33,13 @@ export function setTimer( ) ); - globalThis.icTimers[timerId.toString()] = timerCallbackId; + globalThis._azleIcTimers[timerId.toString()] = timerCallbackId; globalThis._azleTimerCallbackIds[timerCallbackId] = () => { try { callback(); } finally { - delete globalThis.icTimers[timerId.toString()]; + delete globalThis._azleIcTimers[timerId.toString()]; delete globalThis._azleTimerCallbackIds[timerCallbackId]; } }; diff --git a/src/lib/ic/set_timer_interval.ts b/src/lib/ic/set_timer_interval.ts index f397e34c9d..f08beff91e 100644 --- a/src/lib/ic/set_timer_interval.ts +++ b/src/lib/ic/set_timer_interval.ts @@ -33,7 +33,7 @@ export function setTimerInterval( ) ); - globalThis.icTimers[timerId.toString()] = timerCallbackId; + globalThis._azleIcTimers[timerId.toString()] = timerCallbackId; // We don't delete this even if the callback throws because // it still needs to be here for the next tick diff --git a/src/lib/ic/types/azle_ic.ts b/src/lib/ic/types/azle_ic.ts index 9b4e977f31..169eb0edcf 100644 --- a/src/lib/ic/types/azle_ic.ts +++ b/src/lib/ic/types/azle_ic.ts @@ -1,6 +1,3 @@ -import { text } from '../../candid/types/primitive/text'; -import { Void } from '../../candid/types/primitive/void'; - /** * The interface for our rust methods it slightly different than the interface * we expose to the users. This is the interface for the rust functions. @@ -88,4 +85,34 @@ export type AzleIc = { call128: () => never; notify: () => never; reply: () => never; + // Stable B Tree Map Functions + stableBTreeMapInit: (candidEncodedMemoryId: ArrayBufferLike) => void; + stableBTreeMapContainsKey: ( + candidEncodedMemoryId: ArrayBufferLike, + candidEncodedKey: ArrayBufferLike + ) => boolean; + stableBTreeMapGet: ( + candidEncodedMemoryId: ArrayBufferLike, + candidEncodedKey: ArrayBufferLike + ) => ArrayBuffer | undefined; + stableBTreeMapInsert: ( + candidEncodedMemoryId: ArrayBufferLike, + candidEncodedKey: ArrayBufferLike, + candidEncodedValue: ArrayBufferLike + ) => ArrayBuffer | undefined; + stableBTreeMapIsEmpty: (candidEncodedMemoryId: ArrayBuffer) => boolean; + stableBTreeMapItems: ( + candidEncodedMemoryId: ArrayBufferLike + ) => [ArrayBuffer, ArrayBuffer][]; + stableBTreeMapKeys: ( + candidEncodedMemoryId: ArrayBufferLike + ) => ArrayBuffer[]; + stableBTreeMapLen: (candidEncodedMemoryId: ArrayBufferLike) => ArrayBuffer; + stableBTreeMapRemove( + candidEncodedMemoryId: ArrayBufferLike, + candidEncodedKey: ArrayBufferLike + ): ArrayBuffer; + stableBTreeMapValues: ( + candidEncodedMemoryId: ArrayBufferLike + ) => ArrayBuffer[]; }; diff --git a/src/lib/stable_b_tree_map.ts b/src/lib/stable_b_tree_map.ts index 5773174785..d9540f792f 100644 --- a/src/lib/stable_b_tree_map.ts +++ b/src/lib/stable_b_tree_map.ts @@ -10,8 +10,8 @@ export function StableBTreeMap< >(keyType: Key, valueType: Value, memoryId: nat8) { const candidEncodedMemoryId = encode(nat8, memoryId).buffer; - if ((globalThis as any)._azleIc !== undefined) { - (globalThis as any)._azleIc.stableBTreeMapInit(candidEncodedMemoryId); + if (globalThis._azleIc !== undefined) { + globalThis._azleIc.stableBTreeMapInit(candidEncodedMemoryId); } return { @@ -24,7 +24,7 @@ export function StableBTreeMap< const candidEncodedMemoryId = encode(nat8, memoryId).buffer; const candidEncodedKey = encode(keyType, key).buffer; - return (globalThis as any)._azleIc.stableBTreeMapContainsKey( + return globalThis._azleIc.stableBTreeMapContainsKey( candidEncodedMemoryId, candidEncodedKey ); @@ -38,9 +38,7 @@ export function StableBTreeMap< const candidEncodedMemoryId = encode(nat8, memoryId).buffer; const candidEncodedKey = encode(keyType, key).buffer; - const candidEncodedValue = ( - globalThis as any - )._azleIc.stableBTreeMapGet( + const candidEncodedValue = globalThis._azleIc.stableBTreeMapGet( candidEncodedMemoryId, candidEncodedKey ); @@ -65,13 +63,12 @@ export function StableBTreeMap< const candidEncodedKey = encode(keyType, key).buffer; const candidEncodedValue = encode(valueType, value).buffer; - const candidEncodedResultValue = ( - globalThis as any - )._azleIc.stableBTreeMapInsert( - candidEncodedMemoryId, - candidEncodedKey, - candidEncodedValue - ); + const candidEncodedResultValue = + globalThis._azleIc.stableBTreeMapInsert( + candidEncodedMemoryId, + candidEncodedKey, + candidEncodedValue + ); if (candidEncodedResultValue === undefined) { return None; @@ -86,7 +83,7 @@ export function StableBTreeMap< isEmpty(): boolean { const candidEncodedMemoryId = encode(nat8, memoryId).buffer; - return (globalThis as any)._azleIc.stableBTreeMapIsEmpty( + return globalThis._azleIc.stableBTreeMapIsEmpty( candidEncodedMemoryId ); }, @@ -97,12 +94,12 @@ export function StableBTreeMap< items(): [TypeMapping, TypeMapping][] { const candidEncodedMemoryId = encode(nat8, memoryId).buffer; - const candidEncodedItems = ( - globalThis as any - )._azleIc.stableBTreeMapItems(candidEncodedMemoryId); + const candidEncodedItems = globalThis._azleIc.stableBTreeMapItems( + candidEncodedMemoryId + ); // TODO too much copying - return candidEncodedItems.map((candidEncodedItem: any) => { + return candidEncodedItems.map((candidEncodedItem) => { return [ decode(keyType, candidEncodedItem[0]), decode(valueType, candidEncodedItem[1]) @@ -116,12 +113,12 @@ export function StableBTreeMap< keys(): TypeMapping[] { const candidEncodedMemoryId = encode(nat8, memoryId).buffer; - const candidEncodedKeys = ( - globalThis as any - )._azleIc.stableBTreeMapKeys(candidEncodedMemoryId); + const candidEncodedKeys = globalThis._azleIc.stableBTreeMapKeys( + candidEncodedMemoryId + ); // TODO too much copying - return candidEncodedKeys.map((candidEncodedKey: any) => { + return candidEncodedKeys.map((candidEncodedKey) => { return decode(keyType, candidEncodedKey); }); }, @@ -132,9 +129,9 @@ export function StableBTreeMap< len(): nat64 { const candidEncodedMemoryId = encode(nat8, memoryId).buffer; - const candidEncodedLen = ( - globalThis as any - )._azleIc.stableBTreeMapLen(candidEncodedMemoryId); + const candidEncodedLen = globalThis._azleIc.stableBTreeMapLen( + candidEncodedMemoryId + ); return decode(nat64, candidEncodedLen); }, @@ -147,9 +144,7 @@ export function StableBTreeMap< const candidEncodedMemoryId = encode(nat8, memoryId).buffer; const candidEncodedKey = encode(keyType, key).buffer; - const candidEncodedValue = ( - globalThis as any - )._azleIc.stableBTreeMapRemove( + const candidEncodedValue = globalThis._azleIc.stableBTreeMapRemove( candidEncodedMemoryId, candidEncodedKey ); @@ -167,12 +162,12 @@ export function StableBTreeMap< values(): TypeMapping[] { const candidEncodedMemoryId = encode(nat8, memoryId).buffer; - const candidEncodedValues = ( - globalThis as any - )._azleIc.stableBTreeMapValues(candidEncodedMemoryId); + const candidEncodedValues = globalThis._azleIc.stableBTreeMapValues( + candidEncodedMemoryId + ); // TODO too much copying - return candidEncodedValues.map((candidEncodedValue: any) => { + return candidEncodedValues.map((candidEncodedValue) => { return decode(valueType, candidEncodedValue); }); } From 9d5737598c288c1751e6850622679b22dccaad63 Mon Sep 17 00:00:00 2001 From: Benjamin DeMann Date: Tue, 17 Oct 2023 16:59:49 -0600 Subject: [PATCH 12/36] remove unecessary import --- src/lib/ic/index.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lib/ic/index.ts b/src/lib/ic/index.ts index 666a2672bb..65fa7e52ca 100644 --- a/src/lib/ic/index.ts +++ b/src/lib/ic/index.ts @@ -1,4 +1,3 @@ -import '@dfinity/candid/lib/esm/idl'; // This must remain or the build fails import { acceptMessage } from './accept_message'; import { argDataRaw } from './arg_data_raw'; import { argDataRawSize } from './arg_data_raw_size'; From fd84f8e60679df9a5f6905bd404d05a64efe366c Mon Sep 17 00:00:00 2001 From: Benjamin DeMann Date: Wed, 18 Oct 2023 10:20:58 -0600 Subject: [PATCH 13/36] pull out visitService to it's own file --- .../{did_visitor.ts => did_visitor/index.ts} | 99 +----------- src/lib/candid/did_visitor/visit_service.ts | 142 ++++++++++++++++++ 2 files changed, 150 insertions(+), 91 deletions(-) rename src/lib/candid/{did_visitor.ts => did_visitor/index.ts} (67%) create mode 100644 src/lib/candid/did_visitor/visit_service.ts diff --git a/src/lib/candid/did_visitor.ts b/src/lib/candid/did_visitor/index.ts similarity index 67% rename from src/lib/candid/did_visitor.ts rename to src/lib/candid/did_visitor/index.ts index 6f43282935..27917fabcc 100644 --- a/src/lib/candid/did_visitor.ts +++ b/src/lib/candid/did_visitor/index.ts @@ -1,6 +1,7 @@ import { IDL } from '@dfinity/candid'; +import { visitService } from './visit_service'; -type VisitorData = { +export type VisitorData = { usedRecClasses: IDL.RecClass[]; isOnService: boolean; isFirstService: boolean; @@ -8,9 +9,9 @@ type VisitorData = { }; type VisitorResult = [CandidDef, CandidTypesDefs]; -type TypeName = string; -type CandidDef = string; -type CandidTypesDefs = { [key: TypeName]: CandidDef }; +export type TypeName = string; +export type CandidDef = string; +export type CandidTypesDefs = { [key: TypeName]: CandidDef }; const CANDID_KEYWORDS = [ 'blob', @@ -63,91 +64,7 @@ export function didResultToCandidString(result: VisitorResult): string { export class DidVisitor extends IDL.Visitor { visitService(t: IDL.ServiceClass, data: VisitorData): VisitorResult { - const canisterMethods = extractCandid( - t._fields.map(([_name, func]) => - func.accept(this, { - ...data, - isOnService: true, - isFirstService: false - }) - ) - ); - - const isInitFunction = (func: IDL.FuncClass) => - func.annotations.includes('init'); - const isPostUpgradeFunction = (func: IDL.FuncClass) => - func.annotations.includes('postUpgrade'); - // To get the service params we need to look at the init function - const initMethod = extractCandid( - data.systemFuncs - .filter((func) => isInitFunction(func)) - .map((initFunc) => - initFunc.accept(this, { - ...data, - isOnService: true, - isFirstService: false - }) - ) - ); - const postMethod = extractCandid( - data.systemFuncs - .filter((func) => isPostUpgradeFunction(func)) - .map((initFunc) => - initFunc.accept(this, { - ...data, - isOnService: true, - isFirstService: false - }) - ) - ); - const initMethodCandidString = initMethod[0]; - const postMethodCandidString = postMethod[0]; - function getFunctionParams( - initFuncString: string[], - postFuncString: string[] - ) { - if (initFuncString.length === 0) { - if (postFuncString.length === 0) { - return '()'; - } - const parts = postFuncString[0].split('->'); - if (parts.length >= 2) { - return parts[0].trim(); - } - } - const parts = initFuncString[0].split('->'); - if (parts.length >= 2) { - return parts[0].trim(); - } - } - const canisterParamsString = getFunctionParams( - initMethodCandidString, - postMethodCandidString - ); - - const candidTypes = { - ...canisterMethods[1], - ...initMethod[1], - ...postMethod[1] - }; - - const tab = data.isFirstService ? ' ' : ''; - const func_separator = data.isFirstService ? '\n' : ' '; - - const funcStrings = canisterMethods[0] - .map((value, index) => { - return `${tab}${escapeCandidKeywords( - t._fields[index][0] - )}: ${value};`; - }) - .join(func_separator); - if (data.isFirstService) { - return [ - `service: ${canisterParamsString} -> {\n${funcStrings}\n}`, - candidTypes - ]; - } - return [`service {${funcStrings}}`, candidTypes]; + return visitService(t, this, data); } visitPrimitive( t: IDL.PrimitiveType, @@ -256,7 +173,7 @@ export class DidVisitor extends IDL.Visitor { } } -function escapeCandidKeywords(key: string): string { +export function escapeCandidKeywords(key: string): string { if (CANDID_KEYWORDS.includes(key)) { return `"${key}"`; } @@ -275,7 +192,7 @@ function newTypesToStingArr(newTypes: CandidTypesDefs): string[] { ); } -function extractCandid( +export function extractCandid( paramInfo: [CandidDef, CandidTypesDefs][] ): [CandidDef[], CandidTypesDefs] { const paramCandid = paramInfo.map(([candid, _candidTypeDefs]) => { diff --git a/src/lib/candid/did_visitor/visit_service.ts b/src/lib/candid/did_visitor/visit_service.ts new file mode 100644 index 0000000000..1044988481 --- /dev/null +++ b/src/lib/candid/did_visitor/visit_service.ts @@ -0,0 +1,142 @@ +import { IDL } from '@dfinity/candid'; +import { + CandidDef, + CandidTypesDefs, + DidVisitor, + VisitorData, + escapeCandidKeywords, + extractCandid +} from '.'; + +export function visitService( + t: IDL.ServiceClass, + didVisitor: DidVisitor, + data: VisitorData +) { + const queryAndUpdateMethods = getQueryAndUpdateMethods(t, didVisitor, data); + const initMethod = getInitMethod(didVisitor, data); + const postMethod = getPostUpgradeMethod(didVisitor, data); + + const candidTypes = { + ...queryAndUpdateMethods[1], + ...initMethod[1], + ...postMethod[1] + }; + + return serviceToCandidString( + t, + queryAndUpdateMethods[0], + initMethod[0], + postMethod[0], + candidTypes, + data.isFirstService + ); +} + +function serviceToCandidString( + t: IDL.ServiceClass, + canisterMethodCandid: string[], + initMethodCandidString: string[], + postMethodCandidString: string[], + candidTypes: CandidTypesDefs, + isFirstService: boolean +): [CandidDef, CandidTypesDefs] { + const tab = isFirstService ? ' ' : ''; + const func_separator = isFirstService ? '\n' : ' '; + + const funcStrings = canisterMethodCandid + .map((value, index) => { + return `${tab}${escapeCandidKeywords( + t._fields[index][0] + )}: ${value};`; + }) + .join(func_separator); + + const canisterParamsString = createCanisterParamsString( + initMethodCandidString, + postMethodCandidString + ); + + if (isFirstService) { + return [ + `service: ${canisterParamsString} -> {\n${funcStrings}\n}`, + candidTypes + ]; + } + return [`service {${funcStrings}}`, candidTypes]; +} + +function getInitMethod( + didVisitor: DidVisitor, + data: VisitorData +): [CandidDef[], CandidTypesDefs] { + const isInitFunction = (func: IDL.FuncClass) => + func.annotations.includes('init'); + // To get the service params we need to look at the init function + return extractCandid( + data.systemFuncs + .filter((func) => isInitFunction(func)) + .map((initFunc) => + initFunc.accept(didVisitor, { + ...data, + isOnService: true, + isFirstService: false + }) + ) + ); +} + +function getQueryAndUpdateMethods( + t: IDL.ServiceClass, + didVisitor: DidVisitor, + data: VisitorData +): [CandidDef[], CandidTypesDefs] { + return extractCandid( + t._fields.map(([_name, func]) => + func.accept(didVisitor, { + ...data, + isOnService: true, + isFirstService: false + }) + ) + ); +} + +function getPostUpgradeMethod( + didVisitor: DidVisitor, + data: VisitorData +): [CandidDef[], CandidTypesDefs] { + const isPostUpgradeFunction = (func: IDL.FuncClass) => + func.annotations.includes('postUpgrade'); + return extractCandid( + data.systemFuncs + .filter((func) => isPostUpgradeFunction(func)) + .map((initFunc) => + initFunc.accept(didVisitor, { + ...data, + isOnService: true, + isFirstService: false + }) + ) + ); +} + +function createCanisterParamsString( + initMethodCandidString: string[], + postMethodCandidString: string[] +): string { + if (initMethodCandidString.length === 0) { + if (postMethodCandidString.length === 0) { + return '()'; + } + const parts = postMethodCandidString[0].split('->'); + if (parts.length >= 2) { + return parts[0].trim(); + } + } + const parts = initMethodCandidString[0].split('->'); + if (parts.length >= 2) { + return parts[0].trim(); + } + return ''; // TODO this feels weird +} From 6aef0ddca4ee619cdefe3b678756414a0defbb4a Mon Sep 17 00:00:00 2001 From: Benjamin DeMann Date: Wed, 18 Oct 2023 10:29:24 -0600 Subject: [PATCH 14/36] clean up visit_service --- src/lib/candid/did_visitor/visit_service.ts | 55 +++++++++------------ 1 file changed, 22 insertions(+), 33 deletions(-) diff --git a/src/lib/candid/did_visitor/visit_service.ts b/src/lib/candid/did_visitor/visit_service.ts index 1044988481..8ce67ca4a2 100644 --- a/src/lib/candid/did_visitor/visit_service.ts +++ b/src/lib/candid/did_visitor/visit_service.ts @@ -14,8 +14,8 @@ export function visitService( data: VisitorData ) { const queryAndUpdateMethods = getQueryAndUpdateMethods(t, didVisitor, data); - const initMethod = getInitMethod(didVisitor, data); - const postMethod = getPostUpgradeMethod(didVisitor, data); + const initMethod = getSystemMethod('init', didVisitor, data); + const postMethod = getSystemMethod('postUpgrade', didVisitor, data); const candidTypes = { ...queryAndUpdateMethods[1], @@ -35,16 +35,16 @@ export function visitService( function serviceToCandidString( t: IDL.ServiceClass, - canisterMethodCandid: string[], - initMethodCandidString: string[], - postMethodCandidString: string[], + canisterMethodCandidStrings: string[], + initMethodCandidString: string, + postMethodCandidString: string, candidTypes: CandidTypesDefs, isFirstService: boolean ): [CandidDef, CandidTypesDefs] { const tab = isFirstService ? ' ' : ''; const func_separator = isFirstService ? '\n' : ' '; - const funcStrings = canisterMethodCandid + const funcStrings = canisterMethodCandidStrings .map((value, index) => { return `${tab}${escapeCandidKeywords( t._fields[index][0] @@ -66,14 +66,14 @@ function serviceToCandidString( return [`service {${funcStrings}}`, candidTypes]; } -function getInitMethod( +function getSystemMethod( + methodName: 'init' | 'postUpgrade', didVisitor: DidVisitor, data: VisitorData -): [CandidDef[], CandidTypesDefs] { +): [CandidDef, CandidTypesDefs] { const isInitFunction = (func: IDL.FuncClass) => - func.annotations.includes('init'); - // To get the service params we need to look at the init function - return extractCandid( + func.annotations.includes(methodName); + const result = extractCandid( data.systemFuncs .filter((func) => isInitFunction(func)) .map((initFunc) => @@ -84,6 +84,14 @@ function getInitMethod( }) ) ); + + if (result[0].length !== 1) { + console.log( + `WARNING: wrong number of ${methodName} methods detected. Expected 1 found ${result[0].length}` + ); + } + + return [result[0][0], result[1]]; } function getQueryAndUpdateMethods( @@ -102,28 +110,9 @@ function getQueryAndUpdateMethods( ); } -function getPostUpgradeMethod( - didVisitor: DidVisitor, - data: VisitorData -): [CandidDef[], CandidTypesDefs] { - const isPostUpgradeFunction = (func: IDL.FuncClass) => - func.annotations.includes('postUpgrade'); - return extractCandid( - data.systemFuncs - .filter((func) => isPostUpgradeFunction(func)) - .map((initFunc) => - initFunc.accept(didVisitor, { - ...data, - isOnService: true, - isFirstService: false - }) - ) - ); -} - function createCanisterParamsString( - initMethodCandidString: string[], - postMethodCandidString: string[] + initMethodCandidString: string, + postMethodCandidString: string ): string { if (initMethodCandidString.length === 0) { if (postMethodCandidString.length === 0) { @@ -138,5 +127,5 @@ function createCanisterParamsString( if (parts.length >= 2) { return parts[0].trim(); } - return ''; // TODO this feels weird + return '()'; // If we can't find any init or post upgrade params return empty () } From 69f9311415daaa5ab92cdb22fd08d0c85202cdad Mon Sep 17 00:00:00 2001 From: Benjamin DeMann Date: Wed, 18 Oct 2023 10:49:31 -0600 Subject: [PATCH 15/36] move each visit method to it's own file --- src/lib/candid/did_visitor/index.ts | 106 +++++------------- src/lib/candid/did_visitor/visit_func.ts | 25 +++++ src/lib/candid/did_visitor/visit_opt.ts | 11 ++ src/lib/candid/did_visitor/visit_primitive.ts | 6 + src/lib/candid/did_visitor/visit_record.ts | 24 ++++ src/lib/candid/did_visitor/visit_recursive.ts | 27 +++++ src/lib/candid/did_visitor/visit_tuple.ts | 14 +++ src/lib/candid/did_visitor/visit_variant.ts | 25 +++++ src/lib/candid/did_visitor/visit_vec.ts | 11 ++ 9 files changed, 173 insertions(+), 76 deletions(-) create mode 100644 src/lib/candid/did_visitor/visit_func.ts create mode 100644 src/lib/candid/did_visitor/visit_opt.ts create mode 100644 src/lib/candid/did_visitor/visit_primitive.ts create mode 100644 src/lib/candid/did_visitor/visit_record.ts create mode 100644 src/lib/candid/did_visitor/visit_recursive.ts create mode 100644 src/lib/candid/did_visitor/visit_tuple.ts create mode 100644 src/lib/candid/did_visitor/visit_variant.ts create mode 100644 src/lib/candid/did_visitor/visit_vec.ts diff --git a/src/lib/candid/did_visitor/index.ts b/src/lib/candid/did_visitor/index.ts index 27917fabcc..9871976e19 100644 --- a/src/lib/candid/did_visitor/index.ts +++ b/src/lib/candid/did_visitor/index.ts @@ -1,5 +1,13 @@ import { IDL } from '@dfinity/candid'; import { visitService } from './visit_service'; +import { visitVariant } from './visit_variant'; +import { visitRecord } from './visit_record'; +import { visitRecursive } from './visit_recursive'; +import { visitPrimitive } from './visit_primitive'; +import { visitTuple } from './visit_tuple'; +import { visitOpt } from './visit_opt'; +import { visitVec } from './visit_vec'; +import { visitFunc } from './visit_func'; export type VisitorData = { usedRecClasses: IDL.RecClass[]; @@ -7,7 +15,7 @@ export type VisitorData = { isFirstService: boolean; systemFuncs: IDL.FuncClass[]; }; -type VisitorResult = [CandidDef, CandidTypesDefs]; +export type VisitorResult = [CandidDef, CandidTypesDefs]; export type TypeName = string; export type CandidDef = string; @@ -40,13 +48,6 @@ const CANDID_KEYWORDS = [ 'vec' ]; -// TODO it would be nice to have names for the rec types instead of rec_1, rec_2 etc -// TODO Once types have names we should deduplicate the init and post_upgrade param types -// TODO maybe even before we have names we should deduplicate all sorts of types -// The rust to candid converter we were using did have names, but if two things -// had the same shape they got merged into one type that had one of the names. -// That might not be the ideal situation, but it is the expected behavior in rust - export function getDefaultVisitorData(): VisitorData { return { usedRecClasses: [], @@ -57,6 +58,13 @@ export function getDefaultVisitorData(): VisitorData { } export function didResultToCandidString(result: VisitorResult): string { + // TODO it would be nice to have names for the rec types instead of rec_1, rec_2 etc + // TODO Once types have names we should deduplicate the init and post_upgrade param types + // TODO maybe even before we have names we should deduplicate all sorts of types + // The rust to candid converter we were using did have names, but if two things + // had the same shape they got merged into one type that had one of the names. + // That might not be the ideal situation, but it is the expected behavior in rust + const [candid, candidTypeDefs] = result; const candidTypesString = newTypeToCandidString(candidTypeDefs); return candidTypesString + candid + '\n'; @@ -68,108 +76,54 @@ export class DidVisitor extends IDL.Visitor { } visitPrimitive( t: IDL.PrimitiveType, - data: VisitorData + _data: VisitorData ): VisitorResult { - return [t.display(), {}]; + return visitPrimitive(t); } visitTuple( - t: IDL.TupleClass, + _t: IDL.TupleClass, components: IDL.Type[], data: VisitorData ): VisitorResult { - const fields = components.map((value) => - value.accept(this, { ...data, isOnService: false }) - ); - const candid = extractCandid(fields); - return [`record {${candid[0].join('; ')}}`, candid[1]]; + return visitTuple(components, this, data); } visitOpt( - t: IDL.OptClass, + _t: IDL.OptClass, ty: IDL.Type, data: VisitorData ): VisitorResult { - const candid = ty.accept(this, { ...data, isOnService: false }); - return [`opt ${candid[0]}`, candid[1]]; + return visitOpt(ty, this, data); } visitVec( - t: IDL.VecClass, + _t: IDL.VecClass, ty: IDL.Type, data: VisitorData ): VisitorResult { - const candid = ty.accept(this, { ...data, isOnService: false }); - return [`vec ${candid[0]}`, candid[1]]; + return visitVec(ty, this, data); } visitFunc(t: IDL.FuncClass, data: VisitorData): VisitorResult { - const argsTypes = t.argTypes.map((value) => - value.accept(this, { ...data, isOnService: false }) - ); - const candidArgs = extractCandid(argsTypes); - const retsTypes = t.retTypes.map((value) => - value.accept(this, { ...data, isOnService: false }) - ); - const candidRets = extractCandid(retsTypes); - const args = candidArgs[0].join(', '); - const rets = candidRets[0].join(', '); - const annon = - t.annotations.length === 0 ? '' : ' ' + t.annotations.join(' '); - return [ - `${data.isOnService ? '' : 'func '}(${args}) -> (${rets})${annon}`, - { ...candidArgs[1], ...candidRets[1] } - ]; + return visitFunc(t, this, data); } visitRec( t: IDL.RecClass, ty: IDL.ConstructType, data: VisitorData ): VisitorResult { - // For RecClasses the definition will be the name, that name will - // reference the actual definition which will be added to the list of - // candid type defs that will get put at the top of the candid file - // Everything else will just be the normal inline candid def - const usedRecClasses = data.usedRecClasses; - if (!usedRecClasses.includes(t)) { - const candid = ty.accept(this, { - ...data, - usedRecClasses: [...usedRecClasses, t], - isOnService: false, - isFirstService: false - }); - return [t.name, { ...candid[1], [t.name]: candid[0] }]; - } - // If our list already includes this rec class then just return, we don't - // need the list because we will get it when we go through the arm above - return [t.name, {}]; + return visitRecursive(t, ty, this, data); } visitRecord( - t: IDL.RecordClass, + _t: IDL.RecordClass, fields: [string, IDL.Type][], data: VisitorData ): VisitorResult { - const candidFields = fields.map(([key, value]) => - value.accept(this, { ...data, isOnService: false }) - ); - const candid = extractCandid(candidFields); - const field_strings = fields.map( - ([key, value], index) => - escapeCandidKeywords(key) + ':' + candid[0][index] - ); - return [`record {${field_strings.join('; ')}}`, candid[1]]; + return visitRecord(fields, this, data); } visitVariant( - t: IDL.VariantClass, + _t: IDL.VariantClass, fields: [string, IDL.Type][], data: VisitorData ): VisitorResult { - const candidFields = fields.map(([key, value]) => - value.accept(this, { ...data, isOnService: false }) - ); - const candid = extractCandid(candidFields); - const fields_string = fields.map( - ([key, value], index) => - escapeCandidKeywords(key) + - (value.name === 'null' ? '' : ':' + candid[0][index]) - ); - return [`variant {${fields_string.join('; ')}}`, candid[1]]; + return visitVariant(fields, this, data); } } diff --git a/src/lib/candid/did_visitor/visit_func.ts b/src/lib/candid/did_visitor/visit_func.ts new file mode 100644 index 0000000000..1eac687f9f --- /dev/null +++ b/src/lib/candid/did_visitor/visit_func.ts @@ -0,0 +1,25 @@ +import { IDL } from '@dfinity/candid'; +import { DidVisitor, VisitorData, VisitorResult, extractCandid } from '.'; + +export function visitFunc( + t: IDL.FuncClass, + didVisitor: DidVisitor, + data: VisitorData +): VisitorResult { + const argsTypes = t.argTypes.map((value) => + value.accept(didVisitor, { ...data, isOnService: false }) + ); + const candidArgs = extractCandid(argsTypes); + const retsTypes = t.retTypes.map((value) => + value.accept(didVisitor, { ...data, isOnService: false }) + ); + const candidRets = extractCandid(retsTypes); + const args = candidArgs[0].join(', '); + const rets = candidRets[0].join(', '); + const annon = + t.annotations.length === 0 ? '' : ' ' + t.annotations.join(' '); + return [ + `${data.isOnService ? '' : 'func '}(${args}) -> (${rets})${annon}`, + { ...candidArgs[1], ...candidRets[1] } + ]; +} diff --git a/src/lib/candid/did_visitor/visit_opt.ts b/src/lib/candid/did_visitor/visit_opt.ts new file mode 100644 index 0000000000..93c838878d --- /dev/null +++ b/src/lib/candid/did_visitor/visit_opt.ts @@ -0,0 +1,11 @@ +import { IDL } from '@dfinity/candid'; +import { DidVisitor, VisitorData, VisitorResult } from '.'; + +export function visitOpt( + ty: IDL.Type, + didVisitor: DidVisitor, + data: VisitorData +): VisitorResult { + const candid = ty.accept(didVisitor, { ...data, isOnService: false }); + return [`opt ${candid[0]}`, candid[1]]; +} diff --git a/src/lib/candid/did_visitor/visit_primitive.ts b/src/lib/candid/did_visitor/visit_primitive.ts new file mode 100644 index 0000000000..cf4a128ea0 --- /dev/null +++ b/src/lib/candid/did_visitor/visit_primitive.ts @@ -0,0 +1,6 @@ +import { IDL } from '@dfinity/candid'; +import { VisitorResult } from '.'; + +export function visitPrimitive(t: IDL.PrimitiveType): VisitorResult { + return [t.display(), {}]; +} diff --git a/src/lib/candid/did_visitor/visit_record.ts b/src/lib/candid/did_visitor/visit_record.ts new file mode 100644 index 0000000000..409d80ddc4 --- /dev/null +++ b/src/lib/candid/did_visitor/visit_record.ts @@ -0,0 +1,24 @@ +import { IDL } from '@dfinity/candid'; +import { + DidVisitor, + VisitorData, + escapeCandidKeywords, + extractCandid, + VisitorResult +} from '.'; + +export function visitRecord( + fields: [string, IDL.Type][], + didVisitor: DidVisitor, + data: VisitorData +): VisitorResult { + const candidFields = fields.map(([_key, value]) => + value.accept(didVisitor, { ...data, isOnService: false }) + ); + const candid = extractCandid(candidFields); + const field_strings = fields.map( + ([key, _value], index) => + escapeCandidKeywords(key) + ':' + candid[0][index] + ); + return [`record {${field_strings.join('; ')}}`, candid[1]]; +} diff --git a/src/lib/candid/did_visitor/visit_recursive.ts b/src/lib/candid/did_visitor/visit_recursive.ts new file mode 100644 index 0000000000..ff8e8f54da --- /dev/null +++ b/src/lib/candid/did_visitor/visit_recursive.ts @@ -0,0 +1,27 @@ +import { IDL } from '@dfinity/candid'; +import { DidVisitor, VisitorData, VisitorResult } from '.'; + +export function visitRecursive( + t: IDL.RecClass, + ty: IDL.ConstructType, + didVisitor: DidVisitor, + data: VisitorData +): VisitorResult { + // For RecClasses the definition will be the name, that name will + // reference the actual definition which will be added to the list of + // candid type defs that will get put at the top of the candid file + // Everything else will just be the normal inline candid def + const usedRecClasses = data.usedRecClasses; + if (!usedRecClasses.includes(t)) { + const candid = ty.accept(didVisitor, { + ...data, + usedRecClasses: [...usedRecClasses, t], + isOnService: false, + isFirstService: false + }); + return [t.name, { ...candid[1], [t.name]: candid[0] }]; + } + // If our list already includes this rec class then just return, we don't + // need the list because we will get it when we go through the arm above + return [t.name, {}]; +} diff --git a/src/lib/candid/did_visitor/visit_tuple.ts b/src/lib/candid/did_visitor/visit_tuple.ts new file mode 100644 index 0000000000..d4cc776213 --- /dev/null +++ b/src/lib/candid/did_visitor/visit_tuple.ts @@ -0,0 +1,14 @@ +import { IDL } from '@dfinity/candid'; +import { DidVisitor, VisitorData, VisitorResult, extractCandid } from '.'; + +export function visitTuple( + components: IDL.Type[], + didVisitor: DidVisitor, + data: VisitorData +): VisitorResult { + const fields = components.map((value) => + value.accept(didVisitor, { ...data, isOnService: false }) + ); + const candid = extractCandid(fields); + return [`record {${candid[0].join('; ')}}`, candid[1]]; +} diff --git a/src/lib/candid/did_visitor/visit_variant.ts b/src/lib/candid/did_visitor/visit_variant.ts new file mode 100644 index 0000000000..35f29cd5a2 --- /dev/null +++ b/src/lib/candid/did_visitor/visit_variant.ts @@ -0,0 +1,25 @@ +import { IDL } from '@dfinity/candid'; +import { + DidVisitor, + VisitorData, + VisitorResult, + escapeCandidKeywords, + extractCandid +} from '.'; + +export function visitVariant( + fields: [string, IDL.Type][], + didVisitor: DidVisitor, + data: VisitorData +): VisitorResult { + const candidFields = fields.map(([key, value]) => + value.accept(didVisitor, { ...data, isOnService: false }) + ); + const candid = extractCandid(candidFields); + const fields_string = fields.map( + ([key, value], index) => + escapeCandidKeywords(key) + + (value.name === 'null' ? '' : ':' + candid[0][index]) + ); + return [`variant {${fields_string.join('; ')}}`, candid[1]]; +} diff --git a/src/lib/candid/did_visitor/visit_vec.ts b/src/lib/candid/did_visitor/visit_vec.ts new file mode 100644 index 0000000000..709675d1cc --- /dev/null +++ b/src/lib/candid/did_visitor/visit_vec.ts @@ -0,0 +1,11 @@ +import { IDL } from '@dfinity/candid'; +import { DidVisitor, VisitorData, VisitorResult } from '.'; + +export function visitVec( + ty: IDL.Type, + didVisitor: DidVisitor, + data: VisitorData +): VisitorResult { + const candid = ty.accept(didVisitor, { ...data, isOnService: false }); + return [`vec ${candid[0]}`, candid[1]]; +} From 53d59176f6069f2f38ca75237b44e4f2a7db620e Mon Sep 17 00:00:00 2001 From: Benjamin DeMann Date: Wed, 18 Oct 2023 11:01:38 -0600 Subject: [PATCH 16/36] clean up executeMethod --- src/lib/canister_methods/heartbeat.ts | 21 +++++++++++++++++++-- src/lib/canister_methods/index.ts | 21 --------------------- src/lib/canister_methods/pre_upgrade.ts | 2 +- 3 files changed, 20 insertions(+), 24 deletions(-) diff --git a/src/lib/canister_methods/heartbeat.ts b/src/lib/canister_methods/heartbeat.ts index ce759ca73a..5b9680d746 100644 --- a/src/lib/canister_methods/heartbeat.ts +++ b/src/lib/canister_methods/heartbeat.ts @@ -1,11 +1,12 @@ import { CanisterMethodInfo, executeMethod, isAsync } from '.'; +import { ic } from '../ic'; import { Void } from '../candid/types/primitive/void'; export function heartbeat( callback: () => void | Promise ): CanisterMethodInfo<[], Void> { - const finalCallback = (...args: any[]) => { - executeMethod('heartbeat', args, callback, [], Void, false); + const finalCallback = () => { + executeHeartbeat(callback); }; return { @@ -17,3 +18,19 @@ export function heartbeat( guard: undefined }; } + +function executeHeartbeat(callback: any) { + const result = callback(); + + if ( + result !== undefined && + result !== null && + typeof result.then === 'function' + ) { + result.catch((error: any) => { + ic.trap(error.toString()); + }); + } + + return; +} diff --git a/src/lib/canister_methods/index.ts b/src/lib/canister_methods/index.ts index 3066d78340..98c3af5a82 100644 --- a/src/lib/canister_methods/index.ts +++ b/src/lib/canister_methods/index.ts @@ -48,27 +48,6 @@ export function executeMethod( returnCandidType: CandidType, manual: boolean ) { - if (mode === 'heartbeat') { - const result = callback(); - - if ( - result !== undefined && - result !== null && - typeof result.then === 'function' - ) { - result.catch((error: any) => { - ic.trap(error.toString()); - }); - } - - return; - } - - if (mode === 'preUpgrade') { - callback(); - return; - } - const decodedArgs = decode(paramCandidTypes, args[0]); const result = callback(...decodedArgs); diff --git a/src/lib/canister_methods/pre_upgrade.ts b/src/lib/canister_methods/pre_upgrade.ts index b0669e27ce..2e75d0d3ed 100644 --- a/src/lib/canister_methods/pre_upgrade.ts +++ b/src/lib/canister_methods/pre_upgrade.ts @@ -5,7 +5,7 @@ export function preUpgrade( callback: () => void | Promise ): CanisterMethodInfo<[], Void> { const finalCallback = (...args: any[]) => { - executeMethod('preUpgrade', args, callback, [], Void, false); + callback(); }; return { From bdc8859f177acbd368eb02b43bb8459c06f67a92 Mon Sep 17 00:00:00 2001 From: Benjamin DeMann Date: Wed, 18 Oct 2023 11:19:04 -0600 Subject: [PATCH 17/36] fix error with visit_service --- src/lib/candid/did_visitor/visit_service.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/lib/candid/did_visitor/visit_service.ts b/src/lib/candid/did_visitor/visit_service.ts index 8ce67ca4a2..3b80405452 100644 --- a/src/lib/candid/did_visitor/visit_service.ts +++ b/src/lib/candid/did_visitor/visit_service.ts @@ -36,8 +36,8 @@ export function visitService( function serviceToCandidString( t: IDL.ServiceClass, canisterMethodCandidStrings: string[], - initMethodCandidString: string, - postMethodCandidString: string, + initMethodCandidString: string[], + postMethodCandidString: string[], candidTypes: CandidTypesDefs, isFirstService: boolean ): [CandidDef, CandidTypesDefs] { @@ -70,7 +70,7 @@ function getSystemMethod( methodName: 'init' | 'postUpgrade', didVisitor: DidVisitor, data: VisitorData -): [CandidDef, CandidTypesDefs] { +): [CandidDef[], CandidTypesDefs] { const isInitFunction = (func: IDL.FuncClass) => func.annotations.includes(methodName); const result = extractCandid( @@ -85,13 +85,13 @@ function getSystemMethod( ) ); - if (result[0].length !== 1) { + if (result[0].length > 1) { console.log( - `WARNING: wrong number of ${methodName} methods detected. Expected 1 found ${result[0].length}` + `WARNING: too many ${methodName} methods detected. Expected no more than 1, found ${result[0].length}` ); } - return [result[0][0], result[1]]; + return [result[0], result[1]]; } function getQueryAndUpdateMethods( @@ -111,8 +111,8 @@ function getQueryAndUpdateMethods( } function createCanisterParamsString( - initMethodCandidString: string, - postMethodCandidString: string + initMethodCandidString: string[], + postMethodCandidString: string[] ): string { if (initMethodCandidString.length === 0) { if (postMethodCandidString.length === 0) { From 5538f6d14696238d4ce08c8949cf42566d0f15cd Mon Sep 17 00:00:00 2001 From: Benjamin DeMann Date: Wed, 18 Oct 2023 12:12:04 -0600 Subject: [PATCH 18/36] update _azleIc type to be possibly undefined --- src/lib/globals.ts | 4 ++-- src/lib/ic/call_raw.ts | 4 ++++ src/lib/ic/call_raw_128.ts | 4 ++++ src/lib/stable_b_tree_map.ts | 43 +++++++++++++++++++++++++++++++++--- 4 files changed, 50 insertions(+), 5 deletions(-) diff --git a/src/lib/globals.ts b/src/lib/globals.ts index 09867011ad..1617e016a1 100644 --- a/src/lib/globals.ts +++ b/src/lib/globals.ts @@ -3,7 +3,7 @@ import { AzleIc } from './ic/types/azle_ic'; import { Buffer } from 'buffer'; declare global { - var _azleIc: AzleIc; + var _azleIc: AzleIc | undefined; var _azleResolveIds: { [key: string]: (buf: ArrayBuffer) => void }; var _azleRejectIds: { [key: string]: (err: any) => void }; var _azleIcTimers: { [key: string]: string }; @@ -13,7 +13,7 @@ declare global { globalThis.TextDecoder = require('text-encoding').TextDecoder; globalThis.TextEncoder = require('text-encoding').TextEncoder; -globalThis._azleIcTimers ||= {}; +globalThis._azleIcTimers = {}; globalThis._azleResolveIds = {}; globalThis._azleRejectIds = {}; globalThis._azleTimerCallbackIds = {}; diff --git a/src/lib/ic/call_raw.ts b/src/lib/ic/call_raw.ts index 7ae3f575e4..78555ffa6c 100644 --- a/src/lib/ic/call_raw.ts +++ b/src/lib/ic/call_raw.ts @@ -28,6 +28,10 @@ export function callRaw( // TODO this should use a Result remember return new Promise((resolve, reject) => { + if (globalThis._azleIc === undefined) { + return undefined as any; + } + const promiseId = v4(); const globalResolveId = `_resolve_${promiseId}`; const globalRejectId = `_reject_${promiseId}`; diff --git a/src/lib/ic/call_raw_128.ts b/src/lib/ic/call_raw_128.ts index b1c6ea90e3..5c4d4bc778 100644 --- a/src/lib/ic/call_raw_128.ts +++ b/src/lib/ic/call_raw_128.ts @@ -28,6 +28,10 @@ export function callRaw128( // TODO this should use a Result remember return new Promise((resolve, reject) => { + if (globalThis._azleIc === undefined) { + return undefined as any; + } + const promiseId = v4(); const globalResolveId = `_resolve_${promiseId}`; const globalRejectId = `_reject_${promiseId}`; diff --git a/src/lib/stable_b_tree_map.ts b/src/lib/stable_b_tree_map.ts index d9540f792f..bd41ff57b1 100644 --- a/src/lib/stable_b_tree_map.ts +++ b/src/lib/stable_b_tree_map.ts @@ -8,11 +8,12 @@ export function StableBTreeMap< Key extends CandidType, Value extends CandidType >(keyType: Key, valueType: Value, memoryId: nat8) { + if (globalThis._azleIc === undefined) { + return undefined as any; + } const candidEncodedMemoryId = encode(nat8, memoryId).buffer; - if (globalThis._azleIc !== undefined) { - globalThis._azleIc.stableBTreeMapInit(candidEncodedMemoryId); - } + globalThis._azleIc.stableBTreeMapInit(candidEncodedMemoryId); return { /** @@ -21,6 +22,10 @@ export function StableBTreeMap< * @returns `true` if the key exists in the map, `false` otherwise. */ containsKey(key: TypeMapping): boolean { + if (globalThis._azleIc === undefined) { + return undefined as any; + } + const candidEncodedMemoryId = encode(nat8, memoryId).buffer; const candidEncodedKey = encode(keyType, key).buffer; @@ -35,6 +40,10 @@ export function StableBTreeMap< * @returns the value associated with the given key, if it exists. */ get(key: TypeMapping): Opt> { + if (globalThis._azleIc === undefined) { + return undefined as any; + } + const candidEncodedMemoryId = encode(nat8, memoryId).buffer; const candidEncodedKey = encode(keyType, key).buffer; @@ -59,6 +68,10 @@ export function StableBTreeMap< key: TypeMapping, value: TypeMapping ): Opt> { + if (globalThis._azleIc === undefined) { + return undefined as any; + } + const candidEncodedMemoryId = encode(nat8, memoryId).buffer; const candidEncodedKey = encode(keyType, key).buffer; const candidEncodedValue = encode(valueType, value).buffer; @@ -81,6 +94,10 @@ export function StableBTreeMap< * @returns `true` if the map contains no elements, `false` otherwise. */ isEmpty(): boolean { + if (globalThis._azleIc === undefined) { + return undefined as any; + } + const candidEncodedMemoryId = encode(nat8, memoryId).buffer; return globalThis._azleIc.stableBTreeMapIsEmpty( @@ -92,6 +109,10 @@ export function StableBTreeMap< * @returns tuples representing key/value pairs. */ items(): [TypeMapping, TypeMapping][] { + if (globalThis._azleIc === undefined) { + return undefined as any; + } + const candidEncodedMemoryId = encode(nat8, memoryId).buffer; const candidEncodedItems = globalThis._azleIc.stableBTreeMapItems( @@ -111,6 +132,10 @@ export function StableBTreeMap< * @returns they keys in the map. */ keys(): TypeMapping[] { + if (globalThis._azleIc === undefined) { + return undefined as any; + } + const candidEncodedMemoryId = encode(nat8, memoryId).buffer; const candidEncodedKeys = globalThis._azleIc.stableBTreeMapKeys( @@ -127,6 +152,10 @@ export function StableBTreeMap< * @returns the number of elements in the map. */ len(): nat64 { + if (globalThis._azleIc === undefined) { + return undefined as any; + } + const candidEncodedMemoryId = encode(nat8, memoryId).buffer; const candidEncodedLen = globalThis._azleIc.stableBTreeMapLen( @@ -141,6 +170,10 @@ export function StableBTreeMap< * @returns the previous value at the key if it exists, `null` otherwise. */ remove(key: TypeMapping): Opt> { + if (globalThis._azleIc === undefined) { + return undefined as any; + } + const candidEncodedMemoryId = encode(nat8, memoryId).buffer; const candidEncodedKey = encode(keyType, key).buffer; @@ -160,6 +193,10 @@ export function StableBTreeMap< * @returns the values in the map. */ values(): TypeMapping[] { + if (globalThis._azleIc === undefined) { + return undefined as any; + } + const candidEncodedMemoryId = encode(nat8, memoryId).buffer; const candidEncodedValues = globalThis._azleIc.stableBTreeMapValues( From 189889d86d97c36b232881461d48cd8aa66085cc Mon Sep 17 00:00:00 2001 From: Benjamin DeMann Date: Wed, 18 Oct 2023 12:23:34 -0600 Subject: [PATCH 19/36] rename properties to not have _azle where possible --- src/lib/candid/recursive.ts | 12 ++++++------ src/lib/candid/serde/visitors/decode_visitor.ts | 2 +- src/lib/candid/serde/visitors/encode_visitor.ts | 2 +- src/lib/candid/serde/visitors/index.ts | 10 +++++----- src/lib/candid/to_Idl.ts | 6 +++--- src/lib/candid/types/constructed/opt.ts | 6 +++--- src/lib/candid/types/constructed/tuple.ts | 6 +++--- src/lib/candid/types/constructed/vec.ts | 6 +++--- src/lib/candid/types/reference/service/index.ts | 4 ++-- src/lib/system_types/result.ts | 16 ++++++++-------- 10 files changed, 35 insertions(+), 35 deletions(-) diff --git a/src/lib/candid/recursive.ts b/src/lib/candid/recursive.ts index 9eb11a3042..9e59bee051 100644 --- a/src/lib/candid/recursive.ts +++ b/src/lib/candid/recursive.ts @@ -4,8 +4,8 @@ import { CandidType, Parent } from './index'; export type _AzleRecursiveFunction = { (...args: any[]): CandidType; - _azleName?: string; - _azleIsRecursive?: boolean; + azleName?: string; + isRecursive?: boolean; getIdl?: (parents: Parent[]) => IDL.Type; }; @@ -14,18 +14,18 @@ export function Recursive(candidTypeCallback: any): any { let result: _AzleRecursiveFunction = (...args: any[]) => { const candidType = candidTypeCallback(); - if (candidType._azleIsCanister) { + if (candidType.isCanister) { return candidType(...args); } return candidType; }; - result._azleName = name; - result._azleIsRecursive = true; + result.azleName = name; + result.isRecursive = true; result.getIdl = (parents: Parent[]) => { const idl = IDL.Rec(); let filler = candidTypeCallback(); - if (filler._azleIsCanister) { + if (filler.isCanister) { filler = filler(result); } idl.fill(filler.getIdl([...parents, { idl: idl, name }])); diff --git a/src/lib/candid/serde/visitors/decode_visitor.ts b/src/lib/candid/serde/visitors/decode_visitor.ts index c97d94f91b..4b9f3ce790 100644 --- a/src/lib/candid/serde/visitors/decode_visitor.ts +++ b/src/lib/candid/serde/visitors/decode_visitor.ts @@ -58,7 +58,7 @@ export class DecodeVisitor extends IDL.Visitor { const candid = ty.accept(this, { js_data: data.js_data[0], - candidType: data.candidType._azleType + candidType: data.candidType.innerType }); return { diff --git a/src/lib/candid/serde/visitors/encode_visitor.ts b/src/lib/candid/serde/visitors/encode_visitor.ts index e931383364..8a4689fb77 100644 --- a/src/lib/candid/serde/visitors/encode_visitor.ts +++ b/src/lib/candid/serde/visitors/encode_visitor.ts @@ -57,7 +57,7 @@ export class EncodeVisitor extends IDL.Visitor { if ('Some' in data.js_data) { const candid = ty.accept(this, { js_data: data.js_data.Some, - candidType: data.candidType._azleType + candidType: data.candidType.innerType }); return [candid]; diff --git a/src/lib/candid/serde/visitors/index.ts b/src/lib/candid/serde/visitors/index.ts index b84f56710b..c7573cc3bc 100644 --- a/src/lib/candid/serde/visitors/index.ts +++ b/src/lib/candid/serde/visitors/index.ts @@ -30,7 +30,7 @@ export function visitTuple( const fields = components.map((value, index) => value.accept(visitor, { js_data: data.js_data[index], - candidType: data.candidType._azleTypes[index] + candidType: data.candidType.innerTypes[index] }) ); return [...fields]; @@ -47,7 +47,7 @@ export function visitVec( return data.js_data.map((array_elem: any) => { return ty.accept(visitor, { js_data: array_elem, - candidType: data.candidType._azleType + candidType: data.candidType.innerType }); }); } @@ -90,7 +90,7 @@ export function visitRec( data: VisitorData ): VisitorResult { let candidType = data.candidType(); - if (candidType._azleIsCanister) { + if (candidType.isCanister) { candidType = candidType([]); } return ty.accept(visitor, { @@ -108,7 +108,7 @@ function visitAzleResult( const OK_FIELD_INDEX = 0; const okField = fields[OK_FIELD_INDEX]; const okData = data.js_data['Ok']; - const okClass = data.candidType._azleOk; + const okClass = data.candidType.Ok; return Result.Ok( okField[1].accept(visitor, { @@ -121,7 +121,7 @@ function visitAzleResult( const ERR_FIELD_INDEX = 1; const errField = fields[ERR_FIELD_INDEX]; const errData = data.js_data['Err']; - const errClass = data.candidType._azleErr; + const errClass = data.candidType.Err; return Result.Err( errField[1].accept(visitor, { js_data: errData, diff --git a/src/lib/candid/to_Idl.ts b/src/lib/candid/to_Idl.ts index 1b6ff9c6af..7109a6e44d 100644 --- a/src/lib/candid/to_Idl.ts +++ b/src/lib/candid/to_Idl.ts @@ -10,9 +10,9 @@ export function toIdl( candidType: CandidType, parents: Parent[] = [] ): IDL.Type { - if ('_azleName' in candidType) { + if ('azleName' in candidType) { const parent = parents.find( - (parent) => parent.name === candidType._azleName + (parent) => parent.name === candidType.azleName ); // If the parent isn't undefined (ie we found one with the same name) // this is a recursive type and we should return the parent rec idl @@ -21,7 +21,7 @@ export function toIdl( return parent.idl; } } - if ('_azleIsCanister' in candidType && candidType._azleIsCanister) { + if ('isCanister' in candidType && candidType.isCanister) { return toIdl((candidType as any)(), parents); } // All CandidTypes ought to have a getIdl function defined for them diff --git a/src/lib/candid/types/constructed/opt.ts b/src/lib/candid/types/constructed/opt.ts index 510f8981a8..2ac67f194b 100644 --- a/src/lib/candid/types/constructed/opt.ts +++ b/src/lib/candid/types/constructed/opt.ts @@ -28,14 +28,14 @@ export function Opt(t: T): AzleOpt { export class AzleOpt { constructor(t: any) { - this._azleType = t; + this.innerType = t; } - _azleType: CandidType; + innerType: CandidType; _azleCandidType?: '_azleCandidType'; _kind: 'AzleOpt' = 'AzleOpt'; getIdl(parents: Parent[]) { - return IDL.Opt(toIdl(this._azleType, parents)); + return IDL.Opt(toIdl(this.innerType, parents)); } } diff --git a/src/lib/candid/types/constructed/tuple.ts b/src/lib/candid/types/constructed/tuple.ts index 8465379e01..ae1cb84584 100644 --- a/src/lib/candid/types/constructed/tuple.ts +++ b/src/lib/candid/types/constructed/tuple.ts @@ -4,14 +4,14 @@ import { IDL } from '@dfinity/candid'; export class AzleTuple { constructor(t: CandidType[]) { - this._azleTypes = t; + this.innerTypes = t; } - _azleTypes: CandidType[]; + innerTypes: CandidType[]; _azleCandidType?: '_azleCandidType'; getIdl(parents: Parent[]) { - const idls = this._azleTypes.map((value) => { + const idls = this.innerTypes.map((value) => { return toIdl(value, parents); }); return IDL.Tuple(...idls); diff --git a/src/lib/candid/types/constructed/vec.ts b/src/lib/candid/types/constructed/vec.ts index 3901fc4c92..df0adfd809 100644 --- a/src/lib/candid/types/constructed/vec.ts +++ b/src/lib/candid/types/constructed/vec.ts @@ -4,14 +4,14 @@ import { IDL } from '@dfinity/candid'; export class AzleVec { constructor(t: any) { - this._azleType = t; + this.innerType = t; } - _azleType: CandidType; + innerType: CandidType; _azleCandidType?: '_azleCandidType'; getIdl(parents: Parent[]) { - return IDL.Vec(toIdl(this._azleType, parents)); + return IDL.Vec(toIdl(this.innerType, parents)); } } diff --git a/src/lib/candid/types/reference/service/index.ts b/src/lib/candid/types/reference/service/index.ts index 0dbbe61bb2..40069b63c9 100644 --- a/src/lib/candid/types/reference/service/index.ts +++ b/src/lib/candid/types/reference/service/index.ts @@ -25,7 +25,7 @@ type CallableObject = { type _AzleCanisterReturnType = { (parentOrPrincipal: _AzleRecursiveFunction | Principal): void; - _azleIsCanister?: boolean; + isCanister?: boolean; }; export function Canister( @@ -40,6 +40,6 @@ export function Canister( return canisterFunction; }; - result._azleIsCanister = true; + result.isCanister = true; return result as any; } diff --git a/src/lib/system_types/result.ts b/src/lib/system_types/result.ts index d8c860a66b..73cf8f20cb 100644 --- a/src/lib/system_types/result.ts +++ b/src/lib/system_types/result.ts @@ -2,21 +2,21 @@ import { Parent, toIdl, CandidType } from '../candid'; import { RequireExactlyOne } from '../candid/types/constructed/variant'; import { IDL } from '@dfinity/candid'; -export class AzleResult { - constructor(ok: any, err: any) { - this._azleOk = ok; - this._azleErr = err; +export class AzleResult { + constructor(ok: T, err: K) { + this.Ok = ok; + this.Err = err; } - _azleOk: any; - _azleErr: any; + Ok: T; + Err: K; _azleCandidType?: '_azleCandidType'; getIdl(parents: Parent[]) { return IDL.Variant({ - Ok: toIdl(this._azleOk, parents), - Err: toIdl(this._azleErr, parents) + Ok: toIdl(this.Ok, parents), + Err: toIdl(this.Err, parents) }); } } From eb65851f87a3b2830ff60b67c18d527c38453678 Mon Sep 17 00:00:00 2001 From: Benjamin DeMann Date: Wed, 18 Oct 2023 12:29:19 -0600 Subject: [PATCH 20/36] rename _kind to _azleKind --- src/lib/candid/types/constructed/blob.ts | 2 +- src/lib/candid/types/constructed/opt.ts | 2 +- src/lib/candid/types/primitive/bool.ts | 2 +- src/lib/candid/types/primitive/empty.ts | 2 +- src/lib/candid/types/primitive/floats/float32.ts | 2 +- src/lib/candid/types/primitive/floats/float64.ts | 2 +- src/lib/candid/types/primitive/ints/int.ts | 2 +- src/lib/candid/types/primitive/ints/int16.ts | 2 +- src/lib/candid/types/primitive/ints/int32.ts | 2 +- src/lib/candid/types/primitive/ints/int64.ts | 2 +- src/lib/candid/types/primitive/ints/int8.ts | 2 +- src/lib/candid/types/primitive/nats/nat.ts | 2 +- src/lib/candid/types/primitive/nats/nat16.ts | 2 +- src/lib/candid/types/primitive/nats/nat32.ts | 2 +- src/lib/candid/types/primitive/nats/nat64.ts | 2 +- src/lib/candid/types/primitive/nats/nat8.ts | 2 +- src/lib/candid/types/primitive/null.ts | 2 +- src/lib/candid/types/primitive/reserved.ts | 2 +- src/lib/candid/types/primitive/text.ts | 2 +- src/lib/candid/types/primitive/void.ts | 2 +- 20 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/lib/candid/types/constructed/blob.ts b/src/lib/candid/types/constructed/blob.ts index 2d4e178a3c..2bac4860e3 100644 --- a/src/lib/candid/types/constructed/blob.ts +++ b/src/lib/candid/types/constructed/blob.ts @@ -1,7 +1,7 @@ import { IDL } from '@dfinity/candid'; export class AzleBlob { - _kind: 'AzleBlob' = 'AzleBlob'; + _azleKind: 'AzleBlob' = 'AzleBlob'; _azleCandidType?: '_azleCandidType'; static getIdl() { diff --git a/src/lib/candid/types/constructed/opt.ts b/src/lib/candid/types/constructed/opt.ts index 2ac67f194b..e398d01003 100644 --- a/src/lib/candid/types/constructed/opt.ts +++ b/src/lib/candid/types/constructed/opt.ts @@ -33,7 +33,7 @@ export class AzleOpt { innerType: CandidType; _azleCandidType?: '_azleCandidType'; - _kind: 'AzleOpt' = 'AzleOpt'; + _azleKind: 'AzleOpt' = 'AzleOpt'; getIdl(parents: Parent[]) { return IDL.Opt(toIdl(this.innerType, parents)); diff --git a/src/lib/candid/types/primitive/bool.ts b/src/lib/candid/types/primitive/bool.ts index 5163a24beb..0460f9917b 100644 --- a/src/lib/candid/types/primitive/bool.ts +++ b/src/lib/candid/types/primitive/bool.ts @@ -1,7 +1,7 @@ import { IDL } from '@dfinity/candid'; export class AzleBool { - _kind: 'AzleBool' = 'AzleBool'; + _azleKind: 'AzleBool' = 'AzleBool'; _azleCandidType?: '_azleCandidType'; static getIdl() { diff --git a/src/lib/candid/types/primitive/empty.ts b/src/lib/candid/types/primitive/empty.ts index ac0b1954d5..105c12ebcb 100644 --- a/src/lib/candid/types/primitive/empty.ts +++ b/src/lib/candid/types/primitive/empty.ts @@ -1,7 +1,7 @@ import { IDL } from '@dfinity/candid'; export class AzleEmpty { - _kind: 'AzleEmpty' = 'AzleEmpty'; + _azleKind: 'AzleEmpty' = 'AzleEmpty'; _azleCandidType?: '_azleCandidType'; static getIdl() { diff --git a/src/lib/candid/types/primitive/floats/float32.ts b/src/lib/candid/types/primitive/floats/float32.ts index 8029f0bfdf..2fd1ea7cd4 100644 --- a/src/lib/candid/types/primitive/floats/float32.ts +++ b/src/lib/candid/types/primitive/floats/float32.ts @@ -1,7 +1,7 @@ import { IDL } from '@dfinity/candid'; export class AzleFloat32 { - _kind: 'AzleFloat32' = 'AzleFloat32'; + _azleKind: 'AzleFloat32' = 'AzleFloat32'; _azleCandidType?: '_azleCandidType'; static getIdl() { diff --git a/src/lib/candid/types/primitive/floats/float64.ts b/src/lib/candid/types/primitive/floats/float64.ts index fe224b420f..a84dc16554 100644 --- a/src/lib/candid/types/primitive/floats/float64.ts +++ b/src/lib/candid/types/primitive/floats/float64.ts @@ -1,7 +1,7 @@ import { IDL } from '@dfinity/candid'; export class AzleFloat64 { - _kind: 'AzleFloat64' = 'AzleFloat64'; + _azleKind: 'AzleFloat64' = 'AzleFloat64'; _azleCandidType?: '_azleCandidType'; static getIdl() { diff --git a/src/lib/candid/types/primitive/ints/int.ts b/src/lib/candid/types/primitive/ints/int.ts index 4ceaed8e4f..6016d28b8c 100644 --- a/src/lib/candid/types/primitive/ints/int.ts +++ b/src/lib/candid/types/primitive/ints/int.ts @@ -1,7 +1,7 @@ import { IDL } from '@dfinity/candid'; export class AzleInt { - _kind: 'AzleInt' = 'AzleInt'; + _azleKind: 'AzleInt' = 'AzleInt'; _azleCandidType?: '_azleCandidType'; static getIdl() { diff --git a/src/lib/candid/types/primitive/ints/int16.ts b/src/lib/candid/types/primitive/ints/int16.ts index e0640ee593..cc73e160b3 100644 --- a/src/lib/candid/types/primitive/ints/int16.ts +++ b/src/lib/candid/types/primitive/ints/int16.ts @@ -1,7 +1,7 @@ import { IDL } from '@dfinity/candid'; export class AzleInt16 { - _kind: 'AzleInt16' = 'AzleInt16'; + _azleKind: 'AzleInt16' = 'AzleInt16'; _azleCandidType?: '_azleCandidType'; static getIdl() { diff --git a/src/lib/candid/types/primitive/ints/int32.ts b/src/lib/candid/types/primitive/ints/int32.ts index 80c54b16a1..3d2f708847 100644 --- a/src/lib/candid/types/primitive/ints/int32.ts +++ b/src/lib/candid/types/primitive/ints/int32.ts @@ -1,7 +1,7 @@ import { IDL } from '@dfinity/candid'; export class AzleInt32 { - _kind: 'AzleInt32' = 'AzleInt32'; + _azleKind: 'AzleInt32' = 'AzleInt32'; _azleCandidType?: '_azleCandidType'; static getIdl() { diff --git a/src/lib/candid/types/primitive/ints/int64.ts b/src/lib/candid/types/primitive/ints/int64.ts index 925adda269..ab5f92c88c 100644 --- a/src/lib/candid/types/primitive/ints/int64.ts +++ b/src/lib/candid/types/primitive/ints/int64.ts @@ -1,7 +1,7 @@ import { IDL } from '@dfinity/candid'; export class AzleInt64 { - _kind: 'AzleInt64' = 'AzleInt64'; + _azleKind: 'AzleInt64' = 'AzleInt64'; _azleCandidType?: '_azleCandidType'; static getIdl() { diff --git a/src/lib/candid/types/primitive/ints/int8.ts b/src/lib/candid/types/primitive/ints/int8.ts index 2d54a2951e..baba4aa495 100644 --- a/src/lib/candid/types/primitive/ints/int8.ts +++ b/src/lib/candid/types/primitive/ints/int8.ts @@ -1,7 +1,7 @@ import { IDL } from '@dfinity/candid'; export class AzleInt8 { - _kind: 'AzleInt8' = 'AzleInt8'; + _azleKind: 'AzleInt8' = 'AzleInt8'; _azleCandidType?: '_azleCandidType'; static getIdl() { diff --git a/src/lib/candid/types/primitive/nats/nat.ts b/src/lib/candid/types/primitive/nats/nat.ts index c4f68059fc..a33c9c5273 100644 --- a/src/lib/candid/types/primitive/nats/nat.ts +++ b/src/lib/candid/types/primitive/nats/nat.ts @@ -1,7 +1,7 @@ import { IDL } from '@dfinity/candid'; export class AzleNat { - _kind: 'AzleNat' = 'AzleNat'; + _azleKind: 'AzleNat' = 'AzleNat'; _azleCandidType?: '_azleCandidType'; static getIdl() { diff --git a/src/lib/candid/types/primitive/nats/nat16.ts b/src/lib/candid/types/primitive/nats/nat16.ts index fac8214301..d8108ef235 100644 --- a/src/lib/candid/types/primitive/nats/nat16.ts +++ b/src/lib/candid/types/primitive/nats/nat16.ts @@ -1,7 +1,7 @@ import { IDL } from '@dfinity/candid'; export class AzleNat16 { - _kind: 'AzleNat16' = 'AzleNat16'; + _azleKind: 'AzleNat16' = 'AzleNat16'; _azleCandidType?: '_azleCandidType'; static getIdl() { diff --git a/src/lib/candid/types/primitive/nats/nat32.ts b/src/lib/candid/types/primitive/nats/nat32.ts index e4233c50c4..735cd36d58 100644 --- a/src/lib/candid/types/primitive/nats/nat32.ts +++ b/src/lib/candid/types/primitive/nats/nat32.ts @@ -1,7 +1,7 @@ import { IDL } from '@dfinity/candid'; export class AzleNat32 { - _kind: 'AzleNat32' = 'AzleNat32'; + _azleKind: 'AzleNat32' = 'AzleNat32'; _azleCandidType?: '_azleCandidType'; static getIdl() { diff --git a/src/lib/candid/types/primitive/nats/nat64.ts b/src/lib/candid/types/primitive/nats/nat64.ts index 5675605ac5..82f36fcdce 100644 --- a/src/lib/candid/types/primitive/nats/nat64.ts +++ b/src/lib/candid/types/primitive/nats/nat64.ts @@ -1,7 +1,7 @@ import { IDL } from '@dfinity/candid'; export class AzleNat64 { - _kind: 'AzleNat64' = 'AzleNat64'; + _azleKind: 'AzleNat64' = 'AzleNat64'; _azleCandidType?: '_azleCandidType'; static getIdl() { diff --git a/src/lib/candid/types/primitive/nats/nat8.ts b/src/lib/candid/types/primitive/nats/nat8.ts index 74bc3c0564..266d45d5c1 100644 --- a/src/lib/candid/types/primitive/nats/nat8.ts +++ b/src/lib/candid/types/primitive/nats/nat8.ts @@ -1,7 +1,7 @@ import { IDL } from '@dfinity/candid'; export class AzleNat8 { - _kind: 'AzleNat8' = 'AzleNat8'; + _azleKind: 'AzleNat8' = 'AzleNat8'; _azleCandidType?: '_azleCandidType'; static getIdl() { diff --git a/src/lib/candid/types/primitive/null.ts b/src/lib/candid/types/primitive/null.ts index 5a4d690759..465c627ade 100644 --- a/src/lib/candid/types/primitive/null.ts +++ b/src/lib/candid/types/primitive/null.ts @@ -1,7 +1,7 @@ import { IDL } from '@dfinity/candid'; export class AzleNull { - _kind: 'AzleNull' = 'AzleNull'; + _azleKind: 'AzleNull' = 'AzleNull'; _azleCandidType?: '_azleCandidType'; static getIdl() { diff --git a/src/lib/candid/types/primitive/reserved.ts b/src/lib/candid/types/primitive/reserved.ts index 88e10f65fc..dedb6a3518 100644 --- a/src/lib/candid/types/primitive/reserved.ts +++ b/src/lib/candid/types/primitive/reserved.ts @@ -1,7 +1,7 @@ import { IDL } from '@dfinity/candid'; export class AzleReserved { - _kind: 'AzleReserved' = 'AzleReserved'; + _azleKind: 'AzleReserved' = 'AzleReserved'; _azleCandidType?: '_azleCandidType'; static getIdl() { diff --git a/src/lib/candid/types/primitive/text.ts b/src/lib/candid/types/primitive/text.ts index e8af782ef3..c727904699 100644 --- a/src/lib/candid/types/primitive/text.ts +++ b/src/lib/candid/types/primitive/text.ts @@ -1,7 +1,7 @@ import { IDL } from '@dfinity/candid'; export class AzleText { - _kind: 'AzleText' = 'AzleText'; + _azleKind: 'AzleText' = 'AzleText'; _azleCandidType?: '_azleCandidType'; static getIdl() { diff --git a/src/lib/candid/types/primitive/void.ts b/src/lib/candid/types/primitive/void.ts index 84de2348b1..a1c02ddf1a 100644 --- a/src/lib/candid/types/primitive/void.ts +++ b/src/lib/candid/types/primitive/void.ts @@ -1,5 +1,5 @@ export class AzleVoid { - _kind: 'AzleVoid' = 'AzleVoid'; + _azleKind: 'AzleVoid' = 'AzleVoid'; _azleCandidType?: '_azleCandidType'; static getIdl() { From 5174e75c76b0395880ca3059924b3bbaee63edfd Mon Sep 17 00:00:00 2001 From: Benjamin DeMann Date: Wed, 18 Oct 2023 12:32:34 -0600 Subject: [PATCH 21/36] rename to lowercase --- src/lib/candid/index.ts | 2 +- src/lib/candid/{to_Idl.ts => to_idl.ts} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename src/lib/candid/{to_Idl.ts => to_idl.ts} (100%) diff --git a/src/lib/candid/index.ts b/src/lib/candid/index.ts index 9bd8b152ba..b1cb7c3e53 100644 --- a/src/lib/candid/index.ts +++ b/src/lib/candid/index.ts @@ -28,7 +28,7 @@ export * from './types/constructed'; export * from './types/primitive'; export * from './types/reference'; export * from './recursive'; -export * from './to_Idl'; +export * from './to_idl'; export type TypeMapping = RecursionLevel extends 10 ? T diff --git a/src/lib/candid/to_Idl.ts b/src/lib/candid/to_idl.ts similarity index 100% rename from src/lib/candid/to_Idl.ts rename to src/lib/candid/to_idl.ts From 57dfe27b744baaf6f56bf06a4d2572b6b6a37819 Mon Sep 17 00:00:00 2001 From: Benjamin DeMann Date: Wed, 18 Oct 2023 13:36:39 -0600 Subject: [PATCH 22/36] pr fixes --- examples/robust_imports/src/index.did | 97 +++++++------------ .../rust/canister/src/ic/set_timer.rs | 3 +- .../canister/src/ic/set_timer_interval.rs | 3 +- src/lib/globals.ts | 4 +- src/lib/ic/clear_timer.ts | 2 +- src/lib/ic/reply_raw.ts | 2 +- src/lib/ic/set_timer.ts | 4 +- src/lib/ic/set_timer_interval.ts | 2 +- src/lib/index.ts | 1 - 9 files changed, 48 insertions(+), 70 deletions(-) diff --git a/examples/robust_imports/src/index.did b/examples/robust_imports/src/index.did index 87519fe4c8..d792c50a3a 100644 --- a/examples/robust_imports/src/index.did +++ b/examples/robust_imports/src/index.did @@ -1,70 +1,47 @@ -type rec_0 = variant {String:text; Thing:int8}; -type rec_1 = variant {Thing:int8}; -type rec_2 = variant {MyInt16:int16; MyInt8:int8}; -type rec_3 = variant {sixteen; eight}; -type rec_6 = record {int1:int16; int2:int16; int3:int16; int4:int8; int5:int8; int6:int8; int7:int8; int8:int8; int9:int16}; -type rec_7 = record {mytext:text}; -type rec_5 = record {type_name:text; name:text; count:int8; greeting:opt text}; -type rec_4 = record {myRecord:rec_6; myDeepTuple:record {text}; myCavernousTuple:record {text}; fathomlessRecord:rec_7; coveredRecord:rec_5; myTuple:record {text}}; -type rec_9 = variant {Seeds; Seedless}; -type rec_10 = record {int:int; starInt:int; int8:int8; int16:int16; int32:int32; int64:int64}; -type rec_11 = record {nat:nat; starNat:nat; nat8:nat8; nat16:nat16; nat32:nat32; nat64:nat64}; -type rec_12 = record {star:bool}; -type rec_13 = record {star:bool}; -type rec_14 = record {fifth:int; first:int; tenth:nat; third:float64; eighth:int; seventh:float64; second:int; sixth:float32; ninth:int8; eleventh:nat8; twelfth:float64; fourth:int}; -type rec_17 = variant {bad; good; ugly}; -type rec_16 = record {depth:nat8}; -type rec_15 = record {id:nat; list:vec nat16; name:opt text; tups:record {text; float64}; description:rec_17; depth:rec_16}; -type rec_20 = variant {bad; good; ugly}; -type rec_19 = record {depth:nat8}; -type rec_18 = record {id:nat; list:vec nat16; name:opt text; tups:record {text; float64}; description:rec_20; depth:rec_19}; -type rec_23 = variant {bad; good; ugly}; -type rec_22 = record {depth:nat8}; -type rec_21 = record {id:nat; list:vec nat16; name:opt text; tups:record {text; float64}; description:rec_23; depth:rec_22}; service: () -> { - myVariantToMyDeepVariant: (rec_0) -> (rec_1) query; - myFathomlessVariantToMyCavernousVariant: (rec_2) -> (rec_3) query; - returnVec: () -> (vec vec nat8) query; - returnFathomlessVec: () -> (vec int16) query; - returnWeird: () -> (int64) query; - returnFathomlessCanister: (service {query1:() -> (bool) query; update1:() -> (text) }) -> (service {query1:() -> (bool) query; update1:() -> (text) }) query; - makeCavernousRecord: () -> (rec_4) query; - typeCheck: (vec opt nat16) -> (int16) query; addSigFigs: (float32) -> (float64) query; - checkCanister: (service {deliver:() -> (text) ; is_delivered:() -> (bool) query}) -> (service {deliver:() -> (text) ; is_delivered:() -> (bool) query}) query; - checkWatermelonForSeeds: (bool, rec_9) -> () query; - compareApplesToOranges: (rec_10, rec_11) -> (bool) query; - handleFarkleberries: (func (text) -> () oneway, func (text) -> (text) query, func (text) -> (text) ) -> (record {func (text) -> (text) ; func (text) -> () oneway; func (text) -> (text) query}) query; - getManagementPeach: () -> (principal) query; - pitOlives: (opt bool) -> (bool) query; - peelBanana: (vec nat8) -> (nat8) query; - putTheCoconutInTheLime: (int16) -> (vec int16) query; - isMangoTrickyToEat: () -> (bool) query; - isFruitPrepared: () -> (bool) query; - removeRambutanSkins: () -> (reserved); + checkCanister: (service {deliver: () -> (text); is_delivered: () -> (bool) query;}) -> (service {deliver: () -> (text); is_delivered: () -> (bool) query;}) query; + checkCanisterAlias: (service {testQuery: () -> (text) query;}) -> (service {testQuery: () -> (text) query;}) query; + checkPrimAliases: (bool, null, text, int, float64) -> () query; + checkWatermelonForSeeds: (bool, variant {Seeds; Seedless}) -> () query; + compareApplesToOranges: (record {"int":int; starInt:int; "int8":int8; "int16":int16; "int32":int32; "int64":int64}, record {"nat":nat; starNat:nat; "nat8":nat8; "nat16":nat16; "nat32":nat32; "nat64":nat64}) -> (bool) query; + compareStars: (record {star:bool}, record {star:bool}) -> (variant {Ok:bool; Err:text}) query; + deepEmptyAlias: () -> (empty) query; dirtyIlama: () -> (); - pickElderberry: () -> (empty); - compareStars: (rec_12, rec_13) -> (variant {Ok:bool; Err:text}) query; - helloTextAlias: () -> (text) query; + getDeepBlob: (vec nat8) -> (vec nat8) query; + getManagementPeach: () -> (principal) query; + getManualAlias: () -> (float64) query; + getMyRecord: () -> (record {id:nat; list:vec nat16; name:opt text; tups:record {text; float64}; description:variant {bad; good; ugly}; depth:record {depth:nat8}}) query; + getMyRecordAlias: () -> (record {id:nat; list:vec nat16; name:opt text; tups:record {text; float64}; description:variant {bad; good; ugly}; depth:record {depth:nat8}}) query; + getNumberAliases: () -> (record {fifth:int; first:int; tenth:nat; third:float64; eighth:int; seventh:float64; second:int; sixth:float32; ninth:int8; eleventh:nat8; twelfth:float64; fourth:int}) query; + getReservedAlias: () -> (reserved) query; + getStable: (nat16) -> (opt text) query; + getSuperAlias: () -> (record {id:nat; list:vec nat16; name:opt text; tups:record {text; float64}; description:variant {bad; good; ugly}; depth:record {depth:nat8}}) query; + handleFarkleberries: (func (text) -> () oneway, func (text) -> (text) query, func (text) -> (text)) -> (record {func (text) -> (text); func (text) -> () oneway; func (text) -> (text) query}) query; helloAzleTextAlias: () -> (text) query; - helloMixedTextAlias: () -> (text) query; helloDeepTextAlias: () -> (text) query; + helloMixedTextAlias: () -> (text) query; helloStirredTextAlias: () -> (text) query; - getDeepBlob: (vec nat8) -> (vec nat8) query; - deepEmptyAlias: () -> (empty) query; - getNumberAliases: () -> (rec_14) query; + helloTextAlias: () -> (text) query; + isFruitPrepared: () -> (bool) query; + isMangoTrickyToEat: () -> (bool) query; + makeCavernousRecord: () -> (record {myRecord:record {int1:int16; int2:int16; int3:int16; int4:int8; int5:int8; int6:int8; int7:int8; "int8":int8; int9:int16}; myDeepTuple:record {text}; myCavernousTuple:record {text}; fathomlessRecord:record {mytext:text}; coveredRecord:record {type_name:text; name:text; count:int8; greeting:opt text}; myTuple:record {text}}) query; + myFathomlessVariantToMyCavernousVariant: (variant {MyInt16:int16; MyInt8:int8}) -> (variant {sixteen; eight}) query; + myVariantToMyDeepVariant: (variant {String:text; Thing:int8}) -> (variant {Thing:int8}) query; passPrincipal: (principal) -> (principal) query; - getReservedAlias: () -> (reserved) query; - simpleDeepQuery: () -> () query; - simpleAzleQuery: () -> () query; - simpleQuery: () -> () query; - checkCanisterAlias: (service {testQuery:() -> (text) query}) -> (service {testQuery:() -> (text) query}) query; - getMyRecord: () -> (rec_15) query; - getMyRecordAlias: () -> (rec_18) query; - getSuperAlias: () -> (rec_21) query; - getManualAlias: () -> (float64) query; + peelBanana: (vec nat8) -> (nat8) query; + pickElderberry: () -> (empty); + pitOlives: (opt bool) -> (bool) query; + putTheCoconutInTheLime: (int16) -> (vec int16) query; + removeRambutanSkins: () -> (reserved); + returnFathomlessCanister: (service {query1: () -> (bool) query; update1: () -> (text);}) -> (service {query1: () -> (bool) query; update1: () -> (text);}) query; + returnFathomlessVec: () -> (vec int16) query; returnFuncAlias: (func (text) -> (text) query) -> (func (text) -> (text) query) query; + returnVec: () -> (vec vec nat8) query; + returnWeird: () -> (int64) query; setStable: (nat16, text) -> (opt text); - getStable: (nat16) -> (opt text) query; - checkPrimAliases: (bool, null, text, int, float64) -> () query; + simpleAzleQuery: () -> () query; + simpleDeepQuery: () -> () query; + simpleQuery: () -> () query; + typeCheck: (vec opt nat16) -> (int16) query; } diff --git a/src/compiler/rust/canister/src/ic/set_timer.rs b/src/compiler/rust/canister/src/ic/set_timer.rs index 94858b6101..19b7212046 100644 --- a/src/compiler/rust/canister/src/ic/set_timer.rs +++ b/src/compiler/rust/canister/src/ic/set_timer.rs @@ -34,7 +34,8 @@ pub fn native_function<'a>( let global = context.global_object().unwrap(); let timer_callback = global - .get_property("_azleTimerCallbackIds").unwrap() + .get_property("_azleTimerCallbacks") + .unwrap() .get_property(callback_id.as_str()) .unwrap_or_else(|e| ic_cdk::api::trap(e.to_string().as_str())); diff --git a/src/compiler/rust/canister/src/ic/set_timer_interval.rs b/src/compiler/rust/canister/src/ic/set_timer_interval.rs index 78b8f8e399..d448972b4b 100644 --- a/src/compiler/rust/canister/src/ic/set_timer_interval.rs +++ b/src/compiler/rust/canister/src/ic/set_timer_interval.rs @@ -34,7 +34,8 @@ pub fn native_function<'a>( let global = context.global_object().unwrap(); let timer_callback = global - .get_property("_azleTimerCallbackIds").unwrap() + .get_property("_azleTimerCallbacks") + .unwrap() .get_property(callback_id.as_str()) .unwrap_or_else(|e| ic_cdk::api::trap(e.to_string().as_str())); diff --git a/src/lib/globals.ts b/src/lib/globals.ts index 1617e016a1..643e0b14d6 100644 --- a/src/lib/globals.ts +++ b/src/lib/globals.ts @@ -7,7 +7,7 @@ declare global { var _azleResolveIds: { [key: string]: (buf: ArrayBuffer) => void }; var _azleRejectIds: { [key: string]: (err: any) => void }; var _azleIcTimers: { [key: string]: string }; - var _azleTimerCallbackIds: { [key: string]: () => void }; + var _azleTimerCallbacks: { [key: string]: () => void }; var _azleGuardFunctions: { [key: string]: () => any }; } @@ -16,7 +16,7 @@ globalThis.TextEncoder = require('text-encoding').TextEncoder; globalThis._azleIcTimers = {}; globalThis._azleResolveIds = {}; globalThis._azleRejectIds = {}; -globalThis._azleTimerCallbackIds = {}; +globalThis._azleTimerCallbacks = {}; globalThis._azleGuardFunctions = {}; globalThis.console = { diff --git a/src/lib/ic/clear_timer.ts b/src/lib/ic/clear_timer.ts index 443d071e5a..ea7f7e6da5 100644 --- a/src/lib/ic/clear_timer.ts +++ b/src/lib/ic/clear_timer.ts @@ -17,5 +17,5 @@ export function clearTimer(timerId: TimerId): Void { const timerCallbackId = globalThis._azleIcTimers[timerId.toString()]; delete globalThis._azleIcTimers[timerId.toString()]; - delete globalThis._azleTimerCallbackIds[timerCallbackId]; + delete globalThis._azleTimerCallbacks[timerCallbackId]; } diff --git a/src/lib/ic/reply_raw.ts b/src/lib/ic/reply_raw.ts index c3a0955b0a..d8775ca73e 100644 --- a/src/lib/ic/reply_raw.ts +++ b/src/lib/ic/reply_raw.ts @@ -1,5 +1,5 @@ -import { Void } from '../../../examples/robust_imports/src/import_coverage/types'; import { blob } from '../candid/types/constructed/blob'; +import { Void } from '../candid/types/primitive/void'; /** * Used to manually reply to an ingress message. Intended to be used in diff --git a/src/lib/ic/set_timer.ts b/src/lib/ic/set_timer.ts index fe4fe2a5fe..e6bbd41be6 100644 --- a/src/lib/ic/set_timer.ts +++ b/src/lib/ic/set_timer.ts @@ -35,12 +35,12 @@ export function setTimer( globalThis._azleIcTimers[timerId.toString()] = timerCallbackId; - globalThis._azleTimerCallbackIds[timerCallbackId] = () => { + globalThis._azleTimerCallbacks[timerCallbackId] = () => { try { callback(); } finally { delete globalThis._azleIcTimers[timerId.toString()]; - delete globalThis._azleTimerCallbackIds[timerCallbackId]; + delete globalThis._azleTimerCallbacks[timerCallbackId]; } }; diff --git a/src/lib/ic/set_timer_interval.ts b/src/lib/ic/set_timer_interval.ts index f08beff91e..8b9eef07ec 100644 --- a/src/lib/ic/set_timer_interval.ts +++ b/src/lib/ic/set_timer_interval.ts @@ -37,7 +37,7 @@ export function setTimerInterval( // We don't delete this even if the callback throws because // it still needs to be here for the next tick - globalThis._azleTimerCallbackIds[timerCallbackId] = callback; + globalThis._azleTimerCallbacks[timerCallbackId] = callback; return timerId; } diff --git a/src/lib/index.ts b/src/lib/index.ts index 61e854fab6..8dad6d07e7 100644 --- a/src/lib/index.ts +++ b/src/lib/index.ts @@ -4,4 +4,3 @@ export * from './canister_methods'; export * from './ic'; export * from './stable_b_tree_map'; export * from './system_types'; -export { IDL } from '@dfinity/candid'; From 0da99ccdc16902917e5ea5da0d6823b17a2c1ef5 Mon Sep 17 00:00:00 2001 From: Benjamin DeMann Date: Wed, 18 Oct 2023 12:43:21 -0600 Subject: [PATCH 23/36] remove cross canister callback stuff --- src/compiler/rust/canister/src/lib.rs | 7 ++--- .../service/canister_function/index.ts | 31 +++++-------------- src/lib/ic/call.ts | 9 +----- src/lib/ic/notify.ts | 3 +- 4 files changed, 13 insertions(+), 37 deletions(-) diff --git a/src/compiler/rust/canister/src/lib.rs b/src/compiler/rust/canister/src/lib.rs index 5fa687debd..4784ec62ab 100644 --- a/src/compiler/rust/canister/src/lib.rs +++ b/src/compiler/rust/canister/src/lib.rs @@ -81,8 +81,7 @@ fn execute_js(function_name: &str, pass_arg_data: bool) { let exports = global.get_property("exports").unwrap(); let canister_methods = exports.get_property("canisterMethods").unwrap(); let callbacks = canister_methods.get_property("callbacks").unwrap(); - let method_callbacks = callbacks.get_property(function_name).unwrap(); - let canister_method_callback = method_callbacks.get_property("canisterCallback").unwrap(); + let method_callback = callbacks.get_property(function_name).unwrap(); let candid_args = if pass_arg_data { ic_cdk::api::call::arg_data_raw() @@ -94,8 +93,8 @@ fn execute_js(function_name: &str, pass_arg_data: bool) { let candid_args_js_value_ref = to_qjs_value(&context, &candid_args_js_value).unwrap(); // TODO I am not sure what the first parameter to call is supposed to be - canister_method_callback - .call(&canister_method_callback, &[candid_args_js_value_ref]) + method_callback + .call(&method_callback, &[candid_args_js_value_ref]) .unwrap(); context.execute_pending().unwrap(); diff --git a/src/lib/candid/types/reference/service/canister_function/index.ts b/src/lib/candid/types/reference/service/canister_function/index.ts index 9fcde3bc0d..28224a4a79 100644 --- a/src/lib/candid/types/reference/service/canister_function/index.ts +++ b/src/lib/candid/types/reference/service/canister_function/index.ts @@ -122,17 +122,7 @@ function createCallbacks(canisterOptions: CanisterOptions) { return { ...acc, - [methodName]: { - canisterCallback: canisterMethod.callback, - crossCanisterCallback: (...args: any[]) => { - return serviceCall( - this.principal as any, - methodName, - canisterMethod.paramCandidTypes, - canisterMethod.returnCandidType - )(...args); - } - } + [methodName]: canisterMethod.callback }; }, {}); } @@ -148,19 +138,15 @@ function createCanisterFunctionBase( return { ...acc, - [key]: { - canisterCallback: value.callback, - crossCanisterCallback: (...args: any[]) => { - return serviceCall( - principal as any, - key, - value.paramCandidTypes, - value.returnCandidType - )(...args); - } + [key]: (...args: any[]) => { + return serviceCall( + principal as any, + key, + value.paramCandidTypes, + value.returnCandidType + )(...args); } }; - // } }, {} ); @@ -182,7 +168,6 @@ function serviceCall( // in order to set the context (this) correctly return async function ( this: any, // TODO in lib_new this was Service, I'm not sure we need this anymore - _: '_AZLE_CROSS_CANISTER_CALL', notify: boolean, callFunction: CallRawFunction | NotifyRawFunction, cycles: bigint, diff --git a/src/lib/ic/call.ts b/src/lib/ic/call.ts index 229187950b..05087f0c0d 100644 --- a/src/lib/ic/call.ts +++ b/src/lib/ic/call.ts @@ -31,14 +31,7 @@ export function call any>( config?.cycles128 ); - // TODO probably get rid of .crossCanisterCallback - return (method as any).crossCanisterCallback( - '_AZLE_CROSS_CANISTER_CALL', - false, - callFunction, - cycles, - ...(config?.args ?? []) - ); + return method(false, callFunction, cycles, ...(config?.args ?? [])); } function getCallFunctionAndCycles( diff --git a/src/lib/ic/notify.ts b/src/lib/ic/notify.ts index 245939fcd7..d93cfd8216 100644 --- a/src/lib/ic/notify.ts +++ b/src/lib/ic/notify.ts @@ -43,8 +43,7 @@ export function notify any>( return undefined as any; } - return (method as any).crossCanisterCallback( - '_AZLE_CROSS_CANISTER_CALL', + return method( true, notifyRaw, config?.cycles ?? 0n, From 0d4357d06f2d958038328b6a85edee3e43da1cd3 Mon Sep 17 00:00:00 2001 From: Benjamin DeMann Date: Wed, 18 Oct 2023 13:53:19 -0600 Subject: [PATCH 24/36] rename toJSON so it doesn't conflict with standard toJSON --- examples/date/src/index.did | 6 +++--- examples/date/src/index.ts | 2 +- examples/date/test/tests.ts | 4 +++- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/examples/date/src/index.did b/examples/date/src/index.did index 5495983297..8ce2fb67c3 100644 --- a/examples/date/src/index.did +++ b/examples/date/src/index.did @@ -17,6 +17,8 @@ service: () -> { getUtcMinutes: (text) -> (nat32) query; getUtcMonth: (text) -> (nat32) query; getUtcSeconds: (text) -> (nat32) query; + now: () -> (nat64) query; + parse: (text) -> (nat64) query; setDate: (text, nat32) -> (nat32) query; setFullYear: (text, nat32) -> (nat32) query; setHours: (text, nat32) -> (nat32) query; @@ -34,11 +36,9 @@ service: () -> { setUtcSeconds: (text, nat32) -> (nat32) query; toDateString: (text) -> (text) query; toISOString: (text) -> (text) query; - toJSON: (text) -> (text) query; + toJSONString: (text) -> (text) query; toString: (text) -> (text) query; toTimeString: (text) -> (text) query; toUtcString: (text) -> (text) query; - now: () -> (nat64) query; - parse: (text) -> (nat64) query; utc: (nat32, nat32) -> (nat64) query; } diff --git a/examples/date/src/index.ts b/examples/date/src/index.ts index 8afde80654..48d4e34395 100644 --- a/examples/date/src/index.ts +++ b/examples/date/src/index.ts @@ -174,7 +174,7 @@ export default Canister({ toISOString: query([text], text, (isoString) => { return new Date(isoString).toISOString(); }), - toJSON: query([text], text, (isoString) => { + toJSONString: query([text], text, (isoString) => { return new Date(isoString).toJSON(); }), toString: query([text], text, (isoString) => { diff --git a/examples/date/test/tests.ts b/examples/date/test/tests.ts index 0313000e83..734573dd57 100644 --- a/examples/date/test/tests.ts +++ b/examples/date/test/tests.ts @@ -618,7 +618,9 @@ export function getTests(dateCanister: ActorSubclass<_SERVICE>): Test[] { test: async () => { const date = new Date(); - const result = await dateCanister.toJSON(date.toISOString()); + const result = await dateCanister.toJSONString( + date.toISOString() + ); const expected = date.toJSON(); return { From 8afb46aa8696dbd357cf7ea0240d01b2b1130d12 Mon Sep 17 00:00:00 2001 From: Benjamin DeMann Date: Wed, 18 Oct 2023 14:32:47 -0600 Subject: [PATCH 25/36] move things into their own files --- src/lib/candid/candid_type.ts | 3 + src/lib/candid/index.ts | 113 +----------------- src/lib/candid/manual.ts | 5 + src/lib/candid/type_mapping.ts | 101 ++++++++++++++++ src/lib/canister_methods/callback.ts | 8 ++ .../canister_methods/canister_method_info.ts | 15 +++ src/lib/canister_methods/execute_method.ts | 57 +++++++++ src/lib/canister_methods/index.ts | 107 +---------------- src/lib/canister_methods/is_async.ts | 11 ++ src/lib/canister_methods/method_args.ts | 1 + .../{ => methods}/heartbeat.ts | 13 +- src/lib/canister_methods/methods/index.ts | 7 ++ .../canister_methods/{ => methods}/init.ts | 8 +- .../{ => methods}/inspect_message.ts | 5 +- .../{ => methods}/post_upgrade.ts | 8 +- .../{ => methods}/pre_upgrade.ts | 11 +- .../canister_methods/{ => methods}/query.ts | 14 +-- .../canister_methods/{ => methods}/update.ts | 14 +-- src/lib/ic/types/args_type.ts | 1 + src/lib/ic/types/duration.ts | 7 ++ src/lib/ic/types/index.ts | 22 +--- src/lib/ic/types/return_type_of.ts | 1 + src/lib/ic/types/timer_id.ts | 8 ++ 23 files changed, 269 insertions(+), 271 deletions(-) create mode 100644 src/lib/candid/candid_type.ts create mode 100644 src/lib/candid/manual.ts create mode 100644 src/lib/candid/type_mapping.ts create mode 100644 src/lib/canister_methods/callback.ts create mode 100644 src/lib/canister_methods/canister_method_info.ts create mode 100644 src/lib/canister_methods/execute_method.ts create mode 100644 src/lib/canister_methods/is_async.ts create mode 100644 src/lib/canister_methods/method_args.ts rename src/lib/canister_methods/{ => methods}/heartbeat.ts (69%) create mode 100644 src/lib/canister_methods/methods/index.ts rename src/lib/canister_methods/{ => methods}/init.ts (77%) rename src/lib/canister_methods/{ => methods}/inspect_message.ts (71%) rename src/lib/canister_methods/{ => methods}/post_upgrade.ts (78%) rename src/lib/canister_methods/{ => methods}/pre_upgrade.ts (54%) rename src/lib/canister_methods/{ => methods}/query.ts (80%) rename src/lib/canister_methods/{ => methods}/update.ts (79%) create mode 100644 src/lib/ic/types/args_type.ts create mode 100644 src/lib/ic/types/duration.ts create mode 100644 src/lib/ic/types/return_type_of.ts create mode 100644 src/lib/ic/types/timer_id.ts diff --git a/src/lib/candid/candid_type.ts b/src/lib/candid/candid_type.ts new file mode 100644 index 0000000000..62e98f12a4 --- /dev/null +++ b/src/lib/candid/candid_type.ts @@ -0,0 +1,3 @@ +export type CandidType = { + _azleCandidType?: '_azleCandidType'; +}; diff --git a/src/lib/candid/index.ts b/src/lib/candid/index.ts index b1cb7c3e53..e5ce2a2ddd 100644 --- a/src/lib/candid/index.ts +++ b/src/lib/candid/index.ts @@ -1,112 +1,7 @@ -import { IDL } from '@dfinity/candid'; -import { AzleBlob, blob } from './types/constructed/blob'; -import { AzleVec } from './types/constructed/vec'; -import { AzleOpt, Opt } from './types/constructed/opt'; -import { AzleTuple } from './types/constructed/tuple'; -import { AzleNull, Null } from './types/primitive/null'; -import { AzleReserved, reserved } from './types/primitive/reserved'; -import { AzleEmpty, empty } from './types/primitive/empty'; -import { AzleBool, bool } from './types/primitive/bool'; -import { AzleText } from './types/primitive/text'; -import { AzleVoid } from './types/primitive/void'; -import { AzleFloat32, float32 } from './types/primitive/floats/float32'; -import { AzleFloat64, float64 } from './types/primitive/floats/float64'; -import { AzleInt, int } from './types/primitive/ints/int'; -import { AzleInt8, int8 } from './types/primitive/ints/int8'; -import { AzleInt16, int16 } from './types/primitive/ints/int16'; -import { AzleInt32, int32 } from './types/primitive/ints/int32'; -import { AzleInt64, int64 } from './types/primitive/ints/int64'; -import { AzleNat, nat } from './types/primitive/nats/nat'; -import { AzleNat8, nat8 } from './types/primitive/nats/nat8'; -import { AzleNat16, nat16 } from './types/primitive/nats/nat16'; -import { AzleNat32, nat32 } from './types/primitive/nats/nat32'; -import { AzleNat64, nat64 } from './types/primitive/nats/nat64'; -import { AzleResult, Result } from '../system_types'; -import { Principal } from './types/reference'; - +export * from './candid_type'; +export * from './recursive'; +export * from './to_idl'; +export * from './type_mapping'; export * from './types/constructed'; export * from './types/primitive'; export * from './types/reference'; -export * from './recursive'; -export * from './to_idl'; - -export type TypeMapping = RecursionLevel extends 10 - ? T - : T extends () => any - ? ReturnType - : T extends AzleText - ? string - : T extends AzleBool - ? bool - : T extends AzleInt - ? int - : T extends AzleInt64 - ? int64 - : T extends AzleInt32 - ? int32 - : T extends AzleInt16 - ? int16 - : T extends AzleInt8 - ? int8 - : T extends AzleNat - ? nat - : T extends AzleNat64 - ? nat64 - : T extends AzleNat32 - ? nat32 - : T extends AzleNat16 - ? nat16 - : T extends AzleNat8 - ? nat8 - : T extends AzleFloat64 - ? float64 - : T extends AzleFloat32 - ? float32 - : T extends AzleVoid - ? void - : T extends AzleTuple - ? { - [K in keyof U]: TypeMapping< - U[K], - RecursionLevel extends 0 - ? 1 - : RecursionLevel extends 1 - ? 2 - : RecursionLevel extends 2 - ? 3 - : RecursionLevel extends 3 - ? 4 - : RecursionLevel extends 4 - ? 5 - : RecursionLevel extends 5 - ? 6 - : RecursionLevel extends 6 - ? 7 - : RecursionLevel extends 8 - ? 9 - : RecursionLevel extends 9 - ? 10 - : 10 - >; - } - : T extends AzleVec - ? TypeMapping[] - : T extends AzleOpt - ? Opt> - : T extends AzleResult - ? Result, TypeMapping> - : T extends AzleBlob - ? blob - : T extends typeof Principal - ? Principal - : T extends AzleNull - ? Null - : T extends AzleReserved - ? reserved - : T extends AzleEmpty - ? empty - : T; - -export type CandidType = { - _azleCandidType?: '_azleCandidType'; -}; diff --git a/src/lib/candid/manual.ts b/src/lib/candid/manual.ts new file mode 100644 index 0000000000..9d5e51cc2e --- /dev/null +++ b/src/lib/candid/manual.ts @@ -0,0 +1,5 @@ +import { AzleVoid } from './types/primitive/void'; + +export function Manual(t: any): AzleVoid { + return t; +} diff --git a/src/lib/candid/type_mapping.ts b/src/lib/candid/type_mapping.ts new file mode 100644 index 0000000000..96cf0491a9 --- /dev/null +++ b/src/lib/candid/type_mapping.ts @@ -0,0 +1,101 @@ +import { AzleBlob, blob } from './types/constructed/blob'; +import { AzleVec } from './types/constructed/vec'; +import { AzleOpt, Opt } from './types/constructed/opt'; +import { AzleTuple } from './types/constructed/tuple'; +import { AzleNull, Null } from './types/primitive/null'; +import { AzleReserved, reserved } from './types/primitive/reserved'; +import { AzleEmpty, empty } from './types/primitive/empty'; +import { AzleBool, bool } from './types/primitive/bool'; +import { AzleText } from './types/primitive/text'; +import { AzleVoid } from './types/primitive/void'; +import { AzleFloat32, float32 } from './types/primitive/floats/float32'; +import { AzleFloat64, float64 } from './types/primitive/floats/float64'; +import { AzleInt, int } from './types/primitive/ints/int'; +import { AzleInt8, int8 } from './types/primitive/ints/int8'; +import { AzleInt16, int16 } from './types/primitive/ints/int16'; +import { AzleInt32, int32 } from './types/primitive/ints/int32'; +import { AzleInt64, int64 } from './types/primitive/ints/int64'; +import { AzleNat, nat } from './types/primitive/nats/nat'; +import { AzleNat8, nat8 } from './types/primitive/nats/nat8'; +import { AzleNat16, nat16 } from './types/primitive/nats/nat16'; +import { AzleNat32, nat32 } from './types/primitive/nats/nat32'; +import { AzleNat64, nat64 } from './types/primitive/nats/nat64'; +import { AzleResult, Result } from '../system_types'; +import { Principal } from './types/reference'; + +export type TypeMapping = RecursionLevel extends 10 + ? T + : T extends () => any + ? ReturnType + : T extends AzleText + ? string + : T extends AzleBool + ? bool + : T extends AzleInt + ? int + : T extends AzleInt64 + ? int64 + : T extends AzleInt32 + ? int32 + : T extends AzleInt16 + ? int16 + : T extends AzleInt8 + ? int8 + : T extends AzleNat + ? nat + : T extends AzleNat64 + ? nat64 + : T extends AzleNat32 + ? nat32 + : T extends AzleNat16 + ? nat16 + : T extends AzleNat8 + ? nat8 + : T extends AzleFloat64 + ? float64 + : T extends AzleFloat32 + ? float32 + : T extends AzleVoid + ? void + : T extends AzleTuple + ? { + [K in keyof U]: TypeMapping< + U[K], + RecursionLevel extends 0 + ? 1 + : RecursionLevel extends 1 + ? 2 + : RecursionLevel extends 2 + ? 3 + : RecursionLevel extends 3 + ? 4 + : RecursionLevel extends 4 + ? 5 + : RecursionLevel extends 5 + ? 6 + : RecursionLevel extends 6 + ? 7 + : RecursionLevel extends 8 + ? 9 + : RecursionLevel extends 9 + ? 10 + : 10 + >; + } + : T extends AzleVec + ? TypeMapping[] + : T extends AzleOpt + ? Opt> + : T extends AzleResult + ? Result, TypeMapping> + : T extends AzleBlob + ? blob + : T extends typeof Principal + ? Principal + : T extends AzleNull + ? Null + : T extends AzleReserved + ? reserved + : T extends AzleEmpty + ? empty + : T; diff --git a/src/lib/canister_methods/callback.ts b/src/lib/canister_methods/callback.ts new file mode 100644 index 0000000000..4e3a14d501 --- /dev/null +++ b/src/lib/canister_methods/callback.ts @@ -0,0 +1,8 @@ +import { CandidType, TypeMapping } from '../candid'; + +export type Callback< + Params extends ReadonlyArray, + Return extends CandidType +> = ( + ...args: { [K in keyof Params]: TypeMapping } +) => TypeMapping | Promise>; diff --git a/src/lib/canister_methods/canister_method_info.ts b/src/lib/canister_methods/canister_method_info.ts new file mode 100644 index 0000000000..c08cc77283 --- /dev/null +++ b/src/lib/canister_methods/canister_method_info.ts @@ -0,0 +1,15 @@ +export type CanisterMethodInfo, K> = { + mode: + | 'query' + | 'update' + | 'init' + | 'heartbeat' + | 'inspectMessage' + | 'postUpgrade' + | 'preUpgrade'; + async: boolean; + callback?: (...args: any) => any; + paramCandidTypes: any[]; + returnCandidType: any; + guard: (() => any) | undefined; +}; diff --git a/src/lib/canister_methods/execute_method.ts b/src/lib/canister_methods/execute_method.ts new file mode 100644 index 0000000000..78a04fbf86 --- /dev/null +++ b/src/lib/canister_methods/execute_method.ts @@ -0,0 +1,57 @@ +import { ic } from '../ic'; +import { CandidType, TypeMapping } from '../candid'; +import { decode, encode } from '../candid/serde'; +import { CanisterMethodInfo } from './canister_method_info'; + +export function executeMethod( + mode: CanisterMethodInfo['mode'], + args: any[], + callback: any, + paramCandidTypes: CandidType[], + returnCandidType: CandidType, + manual: boolean +) { + const decodedArgs = decode(paramCandidTypes, args[0]); + + const result = callback(...decodedArgs); + + if ( + mode === 'init' || + mode === 'postUpgrade' || + mode === 'inspectMessage' + ) { + return; + } + + if ( + result !== undefined && + result !== null && + typeof result.then === 'function' + ) { + result + .then((result: any) => { + // TODO this won't be accurate because we have most likely had + // TODO cross-canister calls + reportFinalInstructions(); + + if (!manual) { + ic.replyRaw(encode(returnCandidType, result)); + } + }) + .catch((error: any) => { + ic.trap(error.toString()); + }); + } else { + if (!manual) { + ic.replyRaw(encode(returnCandidType, result)); + } + + reportFinalInstructions(); + } +} + +function reportFinalInstructions() { + if (process.env.AZLE_INSTRUCTION_COUNT === 'true') { + console.log(`final instructions: ${ic.instructionCounter()}`); + } +} diff --git a/src/lib/canister_methods/index.ts b/src/lib/canister_methods/index.ts index 98c3af5a82..4f1821bd0e 100644 --- a/src/lib/canister_methods/index.ts +++ b/src/lib/canister_methods/index.ts @@ -1,106 +1 @@ -import { AzleVoid } from '../candid/types/primitive/void'; -import { ic } from '../ic'; -import { CandidType, TypeMapping } from '../candid'; -import { decode, encode } from '../candid/serde'; - -export * from './heartbeat'; -export * from './init'; -export * from './inspect_message'; -export * from './post_upgrade'; -export * from './pre_upgrade'; -export * from './query'; -export * from './update'; - -export function Manual(t: any): AzleVoid { - return t; -} - -export type MethodArgs = { manual?: boolean; guard?: () => void }; - -export type CanisterMethodInfo, K> = { - mode: - | 'query' - | 'update' - | 'init' - | 'heartbeat' - | 'inspectMessage' - | 'postUpgrade' - | 'preUpgrade'; - async: boolean; - callback?: (...args: any) => any; - paramCandidTypes: any[]; - returnCandidType: any; - guard: (() => any) | undefined; -}; - -export type Callback< - Params extends ReadonlyArray, - Return extends CandidType -> = ( - ...args: { [K in keyof Params]: TypeMapping } -) => TypeMapping | Promise>; - -export function executeMethod( - mode: CanisterMethodInfo['mode'], - args: any[], - callback: any, - paramCandidTypes: CandidType[], - returnCandidType: CandidType, - manual: boolean -) { - const decodedArgs = decode(paramCandidTypes, args[0]); - - const result = callback(...decodedArgs); - - if ( - mode === 'init' || - mode === 'postUpgrade' || - mode === 'inspectMessage' - ) { - return; - } - - if ( - result !== undefined && - result !== null && - typeof result.then === 'function' - ) { - result - .then((result: any) => { - // TODO this won't be accurate because we have most likely had - // TODO cross-canister calls - reportFinalInstructions(); - - if (!manual) { - ic.replyRaw(encode(returnCandidType, result)); - } - }) - .catch((error: any) => { - ic.trap(error.toString()); - }); - } else { - if (!manual) { - ic.replyRaw(encode(returnCandidType, result)); - } - - reportFinalInstructions(); - } -} - -function reportFinalInstructions() { - if (process.env.AZLE_INSTRUCTION_COUNT === 'true') { - console.log(`final instructions: ${ic.instructionCounter()}`); - } -} - -export function isAsync(originalFunction: any) { - if (originalFunction[Symbol.toStringTag] === 'AsyncFunction') { - return true; - } else if (originalFunction.constructor.name === 'AsyncFunction') { - return true; - } else if (originalFunction.toString().includes('async ')) { - return true; - } else { - return false; - } -} +export * from './methods'; diff --git a/src/lib/canister_methods/is_async.ts b/src/lib/canister_methods/is_async.ts new file mode 100644 index 0000000000..5c077e7dbe --- /dev/null +++ b/src/lib/canister_methods/is_async.ts @@ -0,0 +1,11 @@ +export function isAsync(originalFunction: any) { + if (originalFunction[Symbol.toStringTag] === 'AsyncFunction') { + return true; + } else if (originalFunction.constructor.name === 'AsyncFunction') { + return true; + } else if (originalFunction.toString().includes('async ')) { + return true; + } else { + return false; + } +} diff --git a/src/lib/canister_methods/method_args.ts b/src/lib/canister_methods/method_args.ts new file mode 100644 index 0000000000..4aeef2eeb4 --- /dev/null +++ b/src/lib/canister_methods/method_args.ts @@ -0,0 +1 @@ +export type MethodArgs = { manual?: boolean; guard?: () => void }; diff --git a/src/lib/canister_methods/heartbeat.ts b/src/lib/canister_methods/methods/heartbeat.ts similarity index 69% rename from src/lib/canister_methods/heartbeat.ts rename to src/lib/canister_methods/methods/heartbeat.ts index 5b9680d746..675b893d8d 100644 --- a/src/lib/canister_methods/heartbeat.ts +++ b/src/lib/canister_methods/methods/heartbeat.ts @@ -1,17 +1,14 @@ -import { CanisterMethodInfo, executeMethod, isAsync } from '.'; -import { ic } from '../ic'; -import { Void } from '../candid/types/primitive/void'; +import { ic } from '../../ic'; +import { Void } from '../../candid/types/primitive/void'; +import { CanisterMethodInfo } from '../canister_method_info'; +import { isAsync } from '../is_async'; export function heartbeat( callback: () => void | Promise ): CanisterMethodInfo<[], Void> { - const finalCallback = () => { - executeHeartbeat(callback); - }; - return { mode: 'heartbeat', - callback: finalCallback, + callback: executeHeartbeat, paramCandidTypes: [], returnCandidType: Void, async: isAsync(callback), diff --git a/src/lib/canister_methods/methods/index.ts b/src/lib/canister_methods/methods/index.ts new file mode 100644 index 0000000000..b07b9640eb --- /dev/null +++ b/src/lib/canister_methods/methods/index.ts @@ -0,0 +1,7 @@ +export * from './heartbeat'; +export * from './init'; +export * from './inspect_message'; +export * from './post_upgrade'; +export * from './pre_upgrade'; +export * from './query'; +export * from './update'; diff --git a/src/lib/canister_methods/init.ts b/src/lib/canister_methods/methods/init.ts similarity index 77% rename from src/lib/canister_methods/init.ts rename to src/lib/canister_methods/methods/init.ts index a7964cd3ca..1b9f2817d5 100644 --- a/src/lib/canister_methods/init.ts +++ b/src/lib/canister_methods/methods/init.ts @@ -1,6 +1,8 @@ -import { Callback, CanisterMethodInfo, executeMethod } from '.'; -import { CandidType, TypeMapping } from '../candid'; -import { Void } from '../candid/types/primitive/void'; +import { CandidType, TypeMapping } from '../../candid'; +import { Void } from '../../candid/types/primitive/void'; +import { Callback } from '../callback'; +import { CanisterMethodInfo } from '../canister_method_info'; +import { executeMethod } from '../execute_method'; export function init< const Params extends ReadonlyArray, diff --git a/src/lib/canister_methods/inspect_message.ts b/src/lib/canister_methods/methods/inspect_message.ts similarity index 71% rename from src/lib/canister_methods/inspect_message.ts rename to src/lib/canister_methods/methods/inspect_message.ts index 557f23f990..1ef07a6fec 100644 --- a/src/lib/canister_methods/inspect_message.ts +++ b/src/lib/canister_methods/methods/inspect_message.ts @@ -1,5 +1,6 @@ -import { CanisterMethodInfo, executeMethod } from '.'; -import { Void } from '../candid/types/primitive/void'; +import { Void } from '../../candid/types/primitive/void'; +import { CanisterMethodInfo } from '../canister_method_info'; +import { executeMethod } from '../execute_method'; export function inspectMessage( callback: () => void | Promise diff --git a/src/lib/canister_methods/post_upgrade.ts b/src/lib/canister_methods/methods/post_upgrade.ts similarity index 78% rename from src/lib/canister_methods/post_upgrade.ts rename to src/lib/canister_methods/methods/post_upgrade.ts index 7043b639cd..05a2c05ee5 100644 --- a/src/lib/canister_methods/post_upgrade.ts +++ b/src/lib/canister_methods/methods/post_upgrade.ts @@ -1,6 +1,8 @@ -import { Callback, CanisterMethodInfo, executeMethod } from '.'; -import { CandidType, TypeMapping } from '../candid'; -import { Void } from '../candid/types/primitive/void'; +import { CandidType, TypeMapping } from '../../candid'; +import { Void } from '../../candid/types/primitive/void'; +import { Callback } from '../callback'; +import { CanisterMethodInfo } from '../canister_method_info'; +import { executeMethod } from '../execute_method'; export function postUpgrade< const Params extends ReadonlyArray, diff --git a/src/lib/canister_methods/pre_upgrade.ts b/src/lib/canister_methods/methods/pre_upgrade.ts similarity index 54% rename from src/lib/canister_methods/pre_upgrade.ts rename to src/lib/canister_methods/methods/pre_upgrade.ts index 2e75d0d3ed..0058e78140 100644 --- a/src/lib/canister_methods/pre_upgrade.ts +++ b/src/lib/canister_methods/methods/pre_upgrade.ts @@ -1,16 +1,13 @@ -import { CanisterMethodInfo, executeMethod, isAsync } from '.'; -import { Void } from '../candid/types/primitive/void'; +import { Void } from '../../candid/types/primitive/void'; +import { CanisterMethodInfo } from '../canister_method_info'; +import { isAsync } from '../is_async'; export function preUpgrade( callback: () => void | Promise ): CanisterMethodInfo<[], Void> { - const finalCallback = (...args: any[]) => { - callback(); - }; - return { mode: 'preUpgrade', - callback: finalCallback, + callback, paramCandidTypes: [], returnCandidType: Void, async: isAsync(callback), diff --git a/src/lib/canister_methods/query.ts b/src/lib/canister_methods/methods/query.ts similarity index 80% rename from src/lib/canister_methods/query.ts rename to src/lib/canister_methods/methods/query.ts index af6a9ec684..77ce083de6 100644 --- a/src/lib/canister_methods/query.ts +++ b/src/lib/canister_methods/methods/query.ts @@ -1,11 +1,9 @@ -import { - Callback, - CanisterMethodInfo, - MethodArgs, - executeMethod, - isAsync -} from '.'; -import { CandidType, TypeMapping } from '../candid'; +import { CandidType, TypeMapping } from '../../candid'; +import { Callback } from '../callback'; +import { CanisterMethodInfo } from '../canister_method_info'; +import { executeMethod } from '../execute_method'; +import { isAsync } from '../is_async'; +import { MethodArgs } from '../method_args'; export function query< const Params extends ReadonlyArray, diff --git a/src/lib/canister_methods/update.ts b/src/lib/canister_methods/methods/update.ts similarity index 79% rename from src/lib/canister_methods/update.ts rename to src/lib/canister_methods/methods/update.ts index 3d45de9874..3322bfc6f5 100644 --- a/src/lib/canister_methods/update.ts +++ b/src/lib/canister_methods/methods/update.ts @@ -1,11 +1,9 @@ -import { - Callback, - CanisterMethodInfo, - MethodArgs, - executeMethod, - isAsync -} from '.'; -import { CandidType, TypeMapping } from '../candid'; +import { CandidType, TypeMapping } from '../../candid'; +import { Callback } from '../callback'; +import { CanisterMethodInfo } from '../canister_method_info'; +import { executeMethod } from '../execute_method'; +import { isAsync } from '../is_async'; +import { MethodArgs } from '../method_args'; export function update< const Params extends ReadonlyArray, diff --git a/src/lib/ic/types/args_type.ts b/src/lib/ic/types/args_type.ts new file mode 100644 index 0000000000..bef0f4085a --- /dev/null +++ b/src/lib/ic/types/args_type.ts @@ -0,0 +1 @@ +export type ArgsType = T extends (...args: infer U) => any ? U : any; diff --git a/src/lib/ic/types/duration.ts b/src/lib/ic/types/duration.ts new file mode 100644 index 0000000000..6bf397b6e6 --- /dev/null +++ b/src/lib/ic/types/duration.ts @@ -0,0 +1,7 @@ +import { nat64, AzleNat64 } from '../../candid/types/primitive/nats/nat64'; + +/** + * Represents a duration of time in seconds. + */ +export type Duration = nat64; // TODO: Consider modeling this after the corresponding struct in Rust +export const Duration: AzleNat64 = AzleNat64 as any; diff --git a/src/lib/ic/types/index.ts b/src/lib/ic/types/index.ts index fd3cf50ac9..9996f11bda 100644 --- a/src/lib/ic/types/index.ts +++ b/src/lib/ic/types/index.ts @@ -1,17 +1,5 @@ -import { nat64, AzleNat64 } from '../../candid/types/primitive/nats/nat64'; - -export type ArgsType = T extends (...args: infer U) => any ? U : any; -export type ReturnTypeOf = T extends (...args: any[]) => infer R ? R : any; - -/** - * Represents a duration of time in seconds. - */ -export type Duration = nat64; // TODO: Consider modeling this after the corresponding struct in Rust -export const Duration: AzleNat64 = AzleNat64 as any; - -/** - * Type returned by the {@link ic.setTimer} and {@link ic.setTimerInterval} - * functions. Pass to {@link ic.clearTimer} to remove the timer. - */ -export type TimerId = nat64; // TODO: Consider modeling this after the corresponding struct in Rust -export const TimerId: AzleNat64 = AzleNat64 as any; +export * from './azle_ic'; +export * from './args_type'; +export * from './duration'; +export * from './return_type_of'; +export * from './timer_id'; diff --git a/src/lib/ic/types/return_type_of.ts b/src/lib/ic/types/return_type_of.ts new file mode 100644 index 0000000000..6d868463ad --- /dev/null +++ b/src/lib/ic/types/return_type_of.ts @@ -0,0 +1 @@ +export type ReturnTypeOf = T extends (...args: any[]) => infer R ? R : any; diff --git a/src/lib/ic/types/timer_id.ts b/src/lib/ic/types/timer_id.ts new file mode 100644 index 0000000000..5bb9fa7ecc --- /dev/null +++ b/src/lib/ic/types/timer_id.ts @@ -0,0 +1,8 @@ +import { nat64, AzleNat64 } from '../../candid/types/primitive/nats/nat64'; + +/** + * Type returned by the {@link ic.setTimer} and {@link ic.setTimerInterval} + * functions. Pass to {@link ic.clearTimer} to remove the timer. + */ +export type TimerId = nat64; // TODO: Consider modeling this after the corresponding struct in Rust +export const TimerId: AzleNat64 = AzleNat64 as any; From a3213a4e9a164430b2c7ebcc9cdccf66c9b5e2a9 Mon Sep 17 00:00:00 2001 From: Benjamin DeMann Date: Wed, 18 Oct 2023 14:46:24 -0600 Subject: [PATCH 26/36] move everything into it's own file --- .../generate_candid_and_canister_methods.ts | 6 +- src/lib/candid/did_file/index.ts | 1 + src/lib/candid/did_file/to_did_string.ts | 26 ++++ .../visitor.ts/did_visitor.ts} | 74 ---------- .../visitor.ts/escapeCandidKeywords.ts | 33 +++++ .../did_file/visitor.ts/extract_candid.ts | 16 +++ src/lib/candid/did_file/visitor.ts/index.ts | 1 + .../visitor.ts}/visit_func.ts | 3 +- .../visitor.ts}/visit_opt.ts | 0 .../visitor.ts}/visit_primitive.ts | 0 .../visitor.ts}/visit_record.ts | 10 +- .../visitor.ts}/visit_recursive.ts | 0 .../visitor.ts}/visit_service.ts | 11 +- .../visitor.ts}/visit_tuple.ts | 3 +- .../visitor.ts}/visit_variant.ts | 10 +- .../visitor.ts}/visit_vec.ts | 0 src/lib/candid/serde/decode.ts | 59 ++++++++ src/lib/candid/serde/encode.ts | 74 ++++++++++ src/lib/candid/serde/index.ts | 131 +----------------- src/lib/candid/types/constructed/index.ts | 19 --- .../candid/types/constructed/to_idl_map.ts | 18 +++ 21 files changed, 246 insertions(+), 249 deletions(-) create mode 100644 src/lib/candid/did_file/index.ts create mode 100644 src/lib/candid/did_file/to_did_string.ts rename src/lib/candid/{did_visitor/index.ts => did_file/visitor.ts/did_visitor.ts} (55%) create mode 100644 src/lib/candid/did_file/visitor.ts/escapeCandidKeywords.ts create mode 100644 src/lib/candid/did_file/visitor.ts/extract_candid.ts create mode 100644 src/lib/candid/did_file/visitor.ts/index.ts rename src/lib/candid/{did_visitor => did_file/visitor.ts}/visit_func.ts (88%) rename src/lib/candid/{did_visitor => did_file/visitor.ts}/visit_opt.ts (100%) rename src/lib/candid/{did_visitor => did_file/visitor.ts}/visit_primitive.ts (100%) rename src/lib/candid/{did_visitor => did_file/visitor.ts}/visit_record.ts (76%) rename src/lib/candid/{did_visitor => did_file/visitor.ts}/visit_recursive.ts (100%) rename src/lib/candid/{did_visitor => did_file/visitor.ts}/visit_service.ts (94%) rename src/lib/candid/{did_visitor => did_file/visitor.ts}/visit_tuple.ts (78%) rename src/lib/candid/{did_visitor => did_file/visitor.ts}/visit_variant.ts (77%) rename src/lib/candid/{did_visitor => did_file/visitor.ts}/visit_vec.ts (100%) create mode 100644 src/lib/candid/serde/decode.ts create mode 100644 src/lib/candid/serde/encode.ts create mode 100644 src/lib/candid/types/constructed/to_idl_map.ts diff --git a/src/compiler/generate_candid_and_canister_methods.ts b/src/compiler/generate_candid_and_canister_methods.ts index a57db95414..882401242e 100644 --- a/src/compiler/generate_candid_and_canister_methods.ts +++ b/src/compiler/generate_candid_and_canister_methods.ts @@ -1,9 +1,9 @@ import { CanisterMethods } from './utils/types'; import { getDefaultVisitorData, - didResultToCandidString, DidVisitor -} from '../lib/candid/did_visitor'; +} from '../lib/candid/did_file/visitor.ts'; +import { toDidString } from '../lib/candid/did_file'; export function generateCandidAndCanisterMethods(mainJs: string): { candid: string; @@ -43,7 +43,7 @@ export function generateCandidAndCanisterMethods(mainJs: string): { }); return { - candid: didResultToCandidString(candidInfo), + candid: toDidString(candidInfo), canisterMethods: canisterMethods }; } diff --git a/src/lib/candid/did_file/index.ts b/src/lib/candid/did_file/index.ts new file mode 100644 index 0000000000..c6217109ae --- /dev/null +++ b/src/lib/candid/did_file/index.ts @@ -0,0 +1 @@ +export { toDidString } from './to_did_string'; diff --git a/src/lib/candid/did_file/to_did_string.ts b/src/lib/candid/did_file/to_did_string.ts new file mode 100644 index 0000000000..f674fe3faa --- /dev/null +++ b/src/lib/candid/did_file/to_did_string.ts @@ -0,0 +1,26 @@ +import { CandidTypesDefs, VisitorResult } from './visitor.ts/index.js'; + +export function toDidString(result: VisitorResult): string { + // TODO it would be nice to have names for the rec types instead of rec_1, rec_2 etc + // TODO Once types have names we should deduplicate the init and post_upgrade param types + // TODO maybe even before we have names we should deduplicate all sorts of types + // The rust to candid converter we were using did have names, but if two things + // had the same shape they got merged into one type that had one of the names. + // That might not be the ideal situation, but it is the expected behavior in rust + + const [candid, candidTypeDefs] = result; + const candidTypesString = newTypeToCandidString(candidTypeDefs); + return candidTypesString + candid + '\n'; +} + +function newTypeToCandidString(newTypes: CandidTypesDefs): string { + return Object.entries(newTypes).length > 0 + ? newTypesToStingArr(newTypes).join('\n') + '\n' + : ''; +} + +function newTypesToStingArr(newTypes: CandidTypesDefs): string[] { + return Object.entries(newTypes).map( + ([name, candid]) => `type ${name} = ${candid};` + ); +} diff --git a/src/lib/candid/did_visitor/index.ts b/src/lib/candid/did_file/visitor.ts/did_visitor.ts similarity index 55% rename from src/lib/candid/did_visitor/index.ts rename to src/lib/candid/did_file/visitor.ts/did_visitor.ts index 9871976e19..0f28df12f8 100644 --- a/src/lib/candid/did_visitor/index.ts +++ b/src/lib/candid/did_file/visitor.ts/did_visitor.ts @@ -21,33 +21,6 @@ export type TypeName = string; export type CandidDef = string; export type CandidTypesDefs = { [key: TypeName]: CandidDef }; -const CANDID_KEYWORDS = [ - 'blob', - 'bool', - 'float32', - 'float64', - 'func', - 'int', - 'int16', - 'int32', - 'int64', - 'int8', - 'nat', - 'nat16', - 'nat32', - 'nat64', - 'nat8', - 'null', - 'opt', - 'principal', - 'query', - 'record', - 'service', - 'text', - 'variant', - 'vec' -]; - export function getDefaultVisitorData(): VisitorData { return { usedRecClasses: [], @@ -57,19 +30,6 @@ export function getDefaultVisitorData(): VisitorData { }; } -export function didResultToCandidString(result: VisitorResult): string { - // TODO it would be nice to have names for the rec types instead of rec_1, rec_2 etc - // TODO Once types have names we should deduplicate the init and post_upgrade param types - // TODO maybe even before we have names we should deduplicate all sorts of types - // The rust to candid converter we were using did have names, but if two things - // had the same shape they got merged into one type that had one of the names. - // That might not be the ideal situation, but it is the expected behavior in rust - - const [candid, candidTypeDefs] = result; - const candidTypesString = newTypeToCandidString(candidTypeDefs); - return candidTypesString + candid + '\n'; -} - export class DidVisitor extends IDL.Visitor { visitService(t: IDL.ServiceClass, data: VisitorData): VisitorResult { return visitService(t, this, data); @@ -126,37 +86,3 @@ export class DidVisitor extends IDL.Visitor { return visitVariant(fields, this, data); } } - -export function escapeCandidKeywords(key: string): string { - if (CANDID_KEYWORDS.includes(key)) { - return `"${key}"`; - } - return key; -} - -function newTypeToCandidString(newTypes: CandidTypesDefs): string { - return Object.entries(newTypes).length > 0 - ? newTypesToStingArr(newTypes).join('\n') + '\n' - : ''; -} - -function newTypesToStingArr(newTypes: CandidTypesDefs): string[] { - return Object.entries(newTypes).map( - ([name, candid]) => `type ${name} = ${candid};` - ); -} - -export function extractCandid( - paramInfo: [CandidDef, CandidTypesDefs][] -): [CandidDef[], CandidTypesDefs] { - const paramCandid = paramInfo.map(([candid, _candidTypeDefs]) => { - return candid; - }); - const candidTypeDefs = paramInfo.reduce( - (acc, [_candid, candidTypeDefs]) => { - return { ...acc, ...candidTypeDefs }; - }, - {} - ); - return [paramCandid, candidTypeDefs]; -} diff --git a/src/lib/candid/did_file/visitor.ts/escapeCandidKeywords.ts b/src/lib/candid/did_file/visitor.ts/escapeCandidKeywords.ts new file mode 100644 index 0000000000..03d5322c43 --- /dev/null +++ b/src/lib/candid/did_file/visitor.ts/escapeCandidKeywords.ts @@ -0,0 +1,33 @@ +const CANDID_KEYWORDS = [ + 'blob', + 'bool', + 'float32', + 'float64', + 'func', + 'int', + 'int16', + 'int32', + 'int64', + 'int8', + 'nat', + 'nat16', + 'nat32', + 'nat64', + 'nat8', + 'null', + 'opt', + 'principal', + 'query', + 'record', + 'service', + 'text', + 'variant', + 'vec' +]; + +export function escapeCandidKeywords(key: string): string { + if (CANDID_KEYWORDS.includes(key)) { + return `"${key}"`; + } + return key; +} diff --git a/src/lib/candid/did_file/visitor.ts/extract_candid.ts b/src/lib/candid/did_file/visitor.ts/extract_candid.ts new file mode 100644 index 0000000000..4e8c054f99 --- /dev/null +++ b/src/lib/candid/did_file/visitor.ts/extract_candid.ts @@ -0,0 +1,16 @@ +import { CandidDef, CandidTypesDefs } from '.'; + +export function extractCandid( + paramInfo: [CandidDef, CandidTypesDefs][] +): [CandidDef[], CandidTypesDefs] { + const paramCandid = paramInfo.map(([candid, _candidTypeDefs]) => { + return candid; + }); + const candidTypeDefs = paramInfo.reduce( + (acc, [_candid, candidTypeDefs]) => { + return { ...acc, ...candidTypeDefs }; + }, + {} + ); + return [paramCandid, candidTypeDefs]; +} diff --git a/src/lib/candid/did_file/visitor.ts/index.ts b/src/lib/candid/did_file/visitor.ts/index.ts new file mode 100644 index 0000000000..6d4d61abe2 --- /dev/null +++ b/src/lib/candid/did_file/visitor.ts/index.ts @@ -0,0 +1 @@ +export * from './did_visitor'; diff --git a/src/lib/candid/did_visitor/visit_func.ts b/src/lib/candid/did_file/visitor.ts/visit_func.ts similarity index 88% rename from src/lib/candid/did_visitor/visit_func.ts rename to src/lib/candid/did_file/visitor.ts/visit_func.ts index 1eac687f9f..25f16942aa 100644 --- a/src/lib/candid/did_visitor/visit_func.ts +++ b/src/lib/candid/did_file/visitor.ts/visit_func.ts @@ -1,5 +1,6 @@ import { IDL } from '@dfinity/candid'; -import { DidVisitor, VisitorData, VisitorResult, extractCandid } from '.'; +import { DidVisitor, VisitorData, VisitorResult } from '.'; +import { extractCandid } from './extract_candid'; export function visitFunc( t: IDL.FuncClass, diff --git a/src/lib/candid/did_visitor/visit_opt.ts b/src/lib/candid/did_file/visitor.ts/visit_opt.ts similarity index 100% rename from src/lib/candid/did_visitor/visit_opt.ts rename to src/lib/candid/did_file/visitor.ts/visit_opt.ts diff --git a/src/lib/candid/did_visitor/visit_primitive.ts b/src/lib/candid/did_file/visitor.ts/visit_primitive.ts similarity index 100% rename from src/lib/candid/did_visitor/visit_primitive.ts rename to src/lib/candid/did_file/visitor.ts/visit_primitive.ts diff --git a/src/lib/candid/did_visitor/visit_record.ts b/src/lib/candid/did_file/visitor.ts/visit_record.ts similarity index 76% rename from src/lib/candid/did_visitor/visit_record.ts rename to src/lib/candid/did_file/visitor.ts/visit_record.ts index 409d80ddc4..818de64b90 100644 --- a/src/lib/candid/did_visitor/visit_record.ts +++ b/src/lib/candid/did_file/visitor.ts/visit_record.ts @@ -1,11 +1,7 @@ import { IDL } from '@dfinity/candid'; -import { - DidVisitor, - VisitorData, - escapeCandidKeywords, - extractCandid, - VisitorResult -} from '.'; +import { DidVisitor, VisitorData, VisitorResult } from '.'; +import { escapeCandidKeywords } from './escapeCandidKeywords'; +import { extractCandid } from './extract_candid'; export function visitRecord( fields: [string, IDL.Type][], diff --git a/src/lib/candid/did_visitor/visit_recursive.ts b/src/lib/candid/did_file/visitor.ts/visit_recursive.ts similarity index 100% rename from src/lib/candid/did_visitor/visit_recursive.ts rename to src/lib/candid/did_file/visitor.ts/visit_recursive.ts diff --git a/src/lib/candid/did_visitor/visit_service.ts b/src/lib/candid/did_file/visitor.ts/visit_service.ts similarity index 94% rename from src/lib/candid/did_visitor/visit_service.ts rename to src/lib/candid/did_file/visitor.ts/visit_service.ts index 3b80405452..bd75726813 100644 --- a/src/lib/candid/did_visitor/visit_service.ts +++ b/src/lib/candid/did_file/visitor.ts/visit_service.ts @@ -1,12 +1,7 @@ import { IDL } from '@dfinity/candid'; -import { - CandidDef, - CandidTypesDefs, - DidVisitor, - VisitorData, - escapeCandidKeywords, - extractCandid -} from '.'; +import { CandidDef, CandidTypesDefs, DidVisitor, VisitorData } from '.'; +import { escapeCandidKeywords } from './escapeCandidKeywords'; +import { extractCandid } from './extract_candid'; export function visitService( t: IDL.ServiceClass, diff --git a/src/lib/candid/did_visitor/visit_tuple.ts b/src/lib/candid/did_file/visitor.ts/visit_tuple.ts similarity index 78% rename from src/lib/candid/did_visitor/visit_tuple.ts rename to src/lib/candid/did_file/visitor.ts/visit_tuple.ts index d4cc776213..82292b60fc 100644 --- a/src/lib/candid/did_visitor/visit_tuple.ts +++ b/src/lib/candid/did_file/visitor.ts/visit_tuple.ts @@ -1,5 +1,6 @@ import { IDL } from '@dfinity/candid'; -import { DidVisitor, VisitorData, VisitorResult, extractCandid } from '.'; +import { DidVisitor, VisitorData, VisitorResult } from '.'; +import { extractCandid } from './extract_candid'; export function visitTuple( components: IDL.Type[], diff --git a/src/lib/candid/did_visitor/visit_variant.ts b/src/lib/candid/did_file/visitor.ts/visit_variant.ts similarity index 77% rename from src/lib/candid/did_visitor/visit_variant.ts rename to src/lib/candid/did_file/visitor.ts/visit_variant.ts index 35f29cd5a2..4ca1fb06d9 100644 --- a/src/lib/candid/did_visitor/visit_variant.ts +++ b/src/lib/candid/did_file/visitor.ts/visit_variant.ts @@ -1,11 +1,7 @@ import { IDL } from '@dfinity/candid'; -import { - DidVisitor, - VisitorData, - VisitorResult, - escapeCandidKeywords, - extractCandid -} from '.'; +import { DidVisitor, VisitorData, VisitorResult } from '.'; +import { escapeCandidKeywords } from './escapeCandidKeywords'; +import { extractCandid } from './extract_candid'; export function visitVariant( fields: [string, IDL.Type][], diff --git a/src/lib/candid/did_visitor/visit_vec.ts b/src/lib/candid/did_file/visitor.ts/visit_vec.ts similarity index 100% rename from src/lib/candid/did_visitor/visit_vec.ts rename to src/lib/candid/did_file/visitor.ts/visit_vec.ts diff --git a/src/lib/candid/serde/decode.ts b/src/lib/candid/serde/decode.ts new file mode 100644 index 0000000000..0bad964e6d --- /dev/null +++ b/src/lib/candid/serde/decode.ts @@ -0,0 +1,59 @@ +import { IDL } from '@dfinity/candid'; + +import { AzleVec, AzleOpt, AzleTuple } from '../types/constructed'; +import { DecodeVisitor } from './visitors/decode_visitor'; +import { CandidType, toIdl } from '../../candid'; + +/** + * Decodes the provided buffer into the designated JS value. + * + * Intended to be a rich replacement for `IDL.decode` from `@dfinity/candid` + * adding support for complex Azle IDL wrappers such as {@link AzleOpt}, + * {@link AzleVec}, and {@link AzleTuple}. It recursively visits all "inner" + * values, converting them from their native shape to the shape that Azle expects. + * + * @param data the value to decode + * @param candidType either a built-in IDL data type, or an Azle-defined super-type + * @returns the Azle representation of the data + */ +export function decode( + candidType: CandidType | CandidType[], + data: ArrayBuffer +): any | any[] { + if (Array.isArray(candidType)) { + return decodeMultiple(candidType, data); + } + return decodeSingle(candidType, data); +} + +function decodeSingle(candidType: CandidType, data: ArrayBuffer): any { + // TODO: there is a discrepancy between CandidType and CandidClass that + // needs to be aligned so that this isn't an error. Both are representing + // candid IDLs, either from the @dfinity/candid library or the + // Azle-augmented ones + const idl = toIdl(candidType); + + const idlIsAzleVoid = Array.isArray(idl); + + if (idlIsAzleVoid) { + return undefined; + } + + const candidDecodedValue = IDL.decode([idl], data)[0] as any; + + return idl.accept(new DecodeVisitor(), { + candidType: candidType, + js_data: candidDecodedValue + }); +} + +function decodeMultiple(candidTypes: CandidType[], data: ArrayBuffer): any[] { + const idls = candidTypes.map((candidType) => toIdl(candidType)); + const decoded = IDL.decode(idls, data); + return idls.map((idl, index) => + idl.accept(new DecodeVisitor(), { + candidType: candidTypes[index], + js_data: decoded[index] + }) + ); +} diff --git a/src/lib/candid/serde/encode.ts b/src/lib/candid/serde/encode.ts new file mode 100644 index 0000000000..f4123fe69e --- /dev/null +++ b/src/lib/candid/serde/encode.ts @@ -0,0 +1,74 @@ +import { IDL } from '@dfinity/candid'; + +import { AzleVec, AzleOpt, AzleTuple } from '../types/constructed'; +import { EncodeVisitor } from './visitors/encode_visitor'; +import { CandidType, toIdl } from '../../candid'; + +/** + * Encodes the provided value as candid blob of the designated type. + * + * Intended to be a rich replacement for `IDL.encode` from `@dfinity/candid`, + * adding support for complex Azle IDL wrappers such as {@link AzleOpt}, + * {@link AzleVec}, and {@link AzleTuple}. It recursively visits all "inner" + * values, converting any Azle values to official IDL values. + * + * @param data the value to encode + * @param candidType either a built-in IDL data type, or an Azle-defined super-type + * @returns candid bytes + */ +export function encode( + candidType: CandidType | CandidType[], + data: any | any[] +): Uint8Array { + if (Array.isArray(candidType)) { + if (Array.isArray(data)) { + return encodeMultiple(candidType, data); + } + throw new Error( + 'If multiple candid types are given then multiple data entries are expected.' + ); + } + return encodeSingle(candidType, data); +} + +function encodeSingle(candidType: CandidType, data: any): Uint8Array { + const idl = toIdl(candidType); + + const idlIsAzleVoid = Array.isArray(idl); + + if (idlIsAzleVoid) { + return new Uint8Array(IDL.encode([], [])); + } + + const encodeReadyKey = idl.accept(new EncodeVisitor(), { + candidType: candidType, + js_data: data + }); + + return new Uint8Array(IDL.encode([idl], [encodeReadyKey])); +} + +function encodeMultiple(candidTypes: CandidType[], data: any[]): Uint8Array { + const { values, idls } = data.reduce<{ + values: any[]; + idls: IDL.Type[]; + }>( + (acc, datum, index) => { + const candidType = candidTypes[index]; + const idl = toIdl(candidType); + + const encodeReadyValue = idl.accept(new EncodeVisitor(), { + candidType: candidType, + js_data: datum + }); + + return { + values: [...acc.values, encodeReadyValue], + idls: [...acc.idls, idl] + }; + }, + { values: [], idls: [] } + ); + + return new Uint8Array(IDL.encode(idls, values)); +} diff --git a/src/lib/candid/serde/index.ts b/src/lib/candid/serde/index.ts index 3e4c30d4d0..2e06b67e1c 100644 --- a/src/lib/candid/serde/index.ts +++ b/src/lib/candid/serde/index.ts @@ -1,129 +1,2 @@ -import { IDL } from '@dfinity/candid'; - -import { AzleVec, AzleOpt, AzleTuple } from '../types/constructed'; -import { DecodeVisitor } from './visitors/decode_visitor'; -import { EncodeVisitor } from './visitors/encode_visitor'; -import { CandidType, toIdl } from '../../candid'; - -/** - * Encodes the provided value as candid blob of the designated type. - * - * Intended to be a rich replacement for `IDL.encode` from `@dfinity/candid`, - * adding support for complex Azle IDL wrappers such as {@link AzleOpt}, - * {@link AzleVec}, and {@link AzleTuple}. It recursively visits all "inner" - * values, converting any Azle values to official IDL values. - * - * @param data the value to encode - * @param candidType either a built-in IDL data type, or an Azle-defined super-type - * @returns candid bytes - */ -export function encode( - candidType: CandidType | CandidType[], - data: any | any[] -): Uint8Array { - if (Array.isArray(candidType)) { - if (Array.isArray(data)) { - return encodeMultiple(candidType, data); - } - throw new Error( - 'If multiple candid types are given then multiple data entries are expected.' - ); - } - return encodeSingle(candidType, data); -} - -/** - * Decodes the provided buffer into the designated JS value. - * - * Intended to be a rich replacement for `IDL.decode` from `@dfinity/candid` - * adding support for complex Azle IDL wrappers such as {@link AzleOpt}, - * {@link AzleVec}, and {@link AzleTuple}. It recursively visits all "inner" - * values, converting them from their native shape to the shape that Azle expects. - * - * @param data the value to decode - * @param candidType either a built-in IDL data type, or an Azle-defined super-type - * @returns the Azle representation of the data - */ -export function decode( - candidType: CandidType | CandidType[], - data: ArrayBuffer -): any | any[] { - if (Array.isArray(candidType)) { - return decodeMultiple(candidType, data); - } - return decodeSingle(candidType, data); -} - -function encodeSingle(candidType: CandidType, data: any): Uint8Array { - const idl = toIdl(candidType); - - const idlIsAzleVoid = Array.isArray(idl); - - if (idlIsAzleVoid) { - return new Uint8Array(IDL.encode([], [])); - } - - const encodeReadyKey = idl.accept(new EncodeVisitor(), { - candidType: candidType, - js_data: data - }); - - return new Uint8Array(IDL.encode([idl], [encodeReadyKey])); -} - -function decodeSingle(candidType: CandidType, data: ArrayBuffer): any { - // TODO: there is a discrepancy between CandidType and CandidClass that - // needs to be aligned so that this isn't an error. Both are representing - // candid IDLs, either from the @dfinity/candid library or the - // Azle-augmented ones - const idl = toIdl(candidType); - - const idlIsAzleVoid = Array.isArray(idl); - - if (idlIsAzleVoid) { - return undefined; - } - - const candidDecodedValue = IDL.decode([idl], data)[0] as any; - - return idl.accept(new DecodeVisitor(), { - candidType: candidType, - js_data: candidDecodedValue - }); -} - -function encodeMultiple(candidTypes: CandidType[], data: any[]): Uint8Array { - const { values, idls } = data.reduce<{ - values: any[]; - idls: IDL.Type[]; - }>( - (acc, datum, index) => { - const candidType = candidTypes[index]; - const idl = toIdl(candidType); - - const encodeReadyValue = idl.accept(new EncodeVisitor(), { - candidType: candidType, - js_data: datum - }); - - return { - values: [...acc.values, encodeReadyValue], - idls: [...acc.idls, idl] - }; - }, - { values: [], idls: [] } - ); - - return new Uint8Array(IDL.encode(idls, values)); -} - -function decodeMultiple(candidTypes: CandidType[], data: ArrayBuffer): any[] { - const idls = candidTypes.map((candidType) => toIdl(candidType)); - const decoded = IDL.decode(idls, data); - return idls.map((idl, index) => - idl.accept(new DecodeVisitor(), { - candidType: candidTypes[index], - js_data: decoded[index] - }) - ); -} +export { decode } from './decode'; +export { encode } from './encode'; diff --git a/src/lib/candid/types/constructed/index.ts b/src/lib/candid/types/constructed/index.ts index 53e28e3ed0..ef999399b3 100644 --- a/src/lib/candid/types/constructed/index.ts +++ b/src/lib/candid/types/constructed/index.ts @@ -1,25 +1,6 @@ -import { CandidType, Parent, toIdl } from '../../index'; -import { IDL } from '@dfinity/candid'; - export * from './blob'; export * from './opt'; export * from './record'; export * from './tuple'; export * from './variant'; export * from './vec'; - -export type CandidMap = { [key: string]: CandidType }; -export type IdlMap = { [key: string]: IDL.Type }; - -export function toIdlMap(candidMap: CandidMap, parent: Parent[]): IdlMap { - const idlMap: IdlMap = {}; - - for (const key in candidMap) { - if (candidMap.hasOwnProperty(key)) { - const candidType = candidMap[key]; - idlMap[key] = toIdl(candidType, parent); - } - } - - return idlMap; -} diff --git a/src/lib/candid/types/constructed/to_idl_map.ts b/src/lib/candid/types/constructed/to_idl_map.ts new file mode 100644 index 0000000000..0e26e062f6 --- /dev/null +++ b/src/lib/candid/types/constructed/to_idl_map.ts @@ -0,0 +1,18 @@ +import { CandidType, Parent, toIdl } from '../../index'; +import { IDL } from '@dfinity/candid'; + +export type CandidMap = { [key: string]: CandidType }; +export type IdlMap = { [key: string]: IDL.Type }; + +export function toIdlMap(candidMap: CandidMap, parent: Parent[]): IdlMap { + const idlMap: IdlMap = {}; + + for (const key in candidMap) { + if (candidMap.hasOwnProperty(key)) { + const candidType = candidMap[key]; + idlMap[key] = toIdl(candidType, parent); + } + } + + return idlMap; +} From b3888a79667f3f7b3a2ee96e8f9ff992541c7eb0 Mon Sep 17 00:00:00 2001 From: Benjamin DeMann Date: Wed, 18 Oct 2023 15:16:38 -0600 Subject: [PATCH 27/36] fix imports --- src/lib/candid/types/constructed/record.ts | 2 +- src/lib/candid/types/constructed/variant.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/candid/types/constructed/record.ts b/src/lib/candid/types/constructed/record.ts index e1a3397920..71ed42f160 100644 --- a/src/lib/candid/types/constructed/record.ts +++ b/src/lib/candid/types/constructed/record.ts @@ -1,6 +1,6 @@ import { CandidType, TypeMapping, Parent } from '../../index'; import { IDL } from '@dfinity/candid'; -import { toIdlMap, CandidMap } from '../constructed'; +import { toIdlMap, CandidMap } from './to_idl_map'; export function Record< T extends { diff --git a/src/lib/candid/types/constructed/variant.ts b/src/lib/candid/types/constructed/variant.ts index 2a6f658878..5a7e06b84f 100644 --- a/src/lib/candid/types/constructed/variant.ts +++ b/src/lib/candid/types/constructed/variant.ts @@ -1,5 +1,5 @@ import { CandidType, TypeMapping } from '../..'; -import { toIdlMap, CandidMap } from '.'; +import { toIdlMap, CandidMap } from './to_idl_map'; import { IDL } from '@dfinity/candid'; export function Variant< From 23004e0b8af48992918fdbeeedc9cb14ac78c6c4 Mon Sep 17 00:00:00 2001 From: Benjamin DeMann Date: Wed, 18 Oct 2023 15:14:57 -0600 Subject: [PATCH 28/36] unify toParamIdl and toReturnIdl --- src/lib/candid/serde/decode.ts | 4 +-- src/lib/candid/serde/encode.ts | 27 +++++-------------- src/lib/candid/to_idl.ts | 16 +++++------ src/lib/candid/types/reference/func.ts | 7 +++-- .../service/canister_function/index.ts | 13 +++------ .../canister_function/system_methods.ts | 6 ++--- 6 files changed, 25 insertions(+), 48 deletions(-) diff --git a/src/lib/candid/serde/decode.ts b/src/lib/candid/serde/decode.ts index 0bad964e6d..d5496078d2 100644 --- a/src/lib/candid/serde/decode.ts +++ b/src/lib/candid/serde/decode.ts @@ -2,7 +2,7 @@ import { IDL } from '@dfinity/candid'; import { AzleVec, AzleOpt, AzleTuple } from '../types/constructed'; import { DecodeVisitor } from './visitors/decode_visitor'; -import { CandidType, toIdl } from '../../candid'; +import { CandidType, toIdl, toIdlArray } from '../../candid'; /** * Decodes the provided buffer into the designated JS value. @@ -48,7 +48,7 @@ function decodeSingle(candidType: CandidType, data: ArrayBuffer): any { } function decodeMultiple(candidTypes: CandidType[], data: ArrayBuffer): any[] { - const idls = candidTypes.map((candidType) => toIdl(candidType)); + const idls = toIdlArray(candidTypes); const decoded = IDL.decode(idls, data); return idls.map((idl, index) => idl.accept(new DecodeVisitor(), { diff --git a/src/lib/candid/serde/encode.ts b/src/lib/candid/serde/encode.ts index f4123fe69e..3423e5873d 100644 --- a/src/lib/candid/serde/encode.ts +++ b/src/lib/candid/serde/encode.ts @@ -2,7 +2,7 @@ import { IDL } from '@dfinity/candid'; import { AzleVec, AzleOpt, AzleTuple } from '../types/constructed'; import { EncodeVisitor } from './visitors/encode_visitor'; -import { CandidType, toIdl } from '../../candid'; +import { CandidType, toIdl, toIdlArray } from '../../candid'; /** * Encodes the provided value as candid blob of the designated type. @@ -49,25 +49,12 @@ function encodeSingle(candidType: CandidType, data: any): Uint8Array { } function encodeMultiple(candidTypes: CandidType[], data: any[]): Uint8Array { - const { values, idls } = data.reduce<{ - values: any[]; - idls: IDL.Type[]; - }>( - (acc, datum, index) => { - const candidType = candidTypes[index]; - const idl = toIdl(candidType); - - const encodeReadyValue = idl.accept(new EncodeVisitor(), { - candidType: candidType, - js_data: datum - }); - - return { - values: [...acc.values, encodeReadyValue], - idls: [...acc.idls, idl] - }; - }, - { values: [], idls: [] } + const idls = toIdlArray(candidTypes); + const values = data.map((datum, index) => + idls[index].accept(new EncodeVisitor(), { + candidType: candidTypes[index], + js_data: datum + }) ); return new Uint8Array(IDL.encode(idls, values)); diff --git a/src/lib/candid/to_idl.ts b/src/lib/candid/to_idl.ts index 7109a6e44d..a6e62e1ba6 100644 --- a/src/lib/candid/to_idl.ts +++ b/src/lib/candid/to_idl.ts @@ -28,18 +28,14 @@ export function toIdl( return (candidType as any).getIdl(parents); } -export function toParamIdls( - paramCandidTypes: CandidType[], +export function toIdlArray( + candidTypes: CandidType | CandidType[], parents: Parent[] = [] ): IDL.Type[] { - return paramCandidTypes.map((value) => toIdl(value, parents)); -} - -export function toReturnIdl( - returnCandidType: CandidType, - parents: Parent[] = [] -): IDL.Type[] { - const idlType = toIdl(returnCandidType, parents); + if (Array.isArray(candidTypes)) { + return candidTypes.map((value) => toIdl(value, parents)); + } + const idlType = toIdl(candidTypes, parents); return Array.isArray(idlType) ? idlType : [idlType]; } diff --git a/src/lib/candid/types/reference/func.ts b/src/lib/candid/types/reference/func.ts index e5298f71c3..a520a3937f 100644 --- a/src/lib/candid/types/reference/func.ts +++ b/src/lib/candid/types/reference/func.ts @@ -1,7 +1,6 @@ -import { CandidType } from '../../index'; +import { CandidType, Parent, toIdlArray } from '../../index'; import { IDL } from '@dfinity/candid'; import { Principal } from './principal'; -import { Parent, toParamIdls, toReturnIdl } from '../../index'; type Mode = 'query' | 'update' | 'oneway'; @@ -19,8 +18,8 @@ export function Func( return { getIdl(parents: Parent[]) { return IDL.Func( - toParamIdls(paramCandidTypes, parents), - toReturnIdl(returnCandidTypes, parents), + toIdlArray(paramCandidTypes, parents), + toIdlArray(returnCandidTypes, parents), modeToCandid[mode] ); } diff --git a/src/lib/candid/types/reference/service/canister_function/index.ts b/src/lib/candid/types/reference/service/canister_function/index.ts index 28224a4a79..468d60ad8d 100644 --- a/src/lib/candid/types/reference/service/canister_function/index.ts +++ b/src/lib/candid/types/reference/service/canister_function/index.ts @@ -1,14 +1,9 @@ -import { - Parent, - toParamIdls, - toReturnIdl, - CandidType -} from '../../../../index'; +import { Parent, CandidType, toIdlArray } from '../../../../index'; import { _AzleRecursiveFunction } from '../../../../recursive'; import { ic } from '../../../../../ic'; import { Principal } from '../../principal'; import { IDL } from '@dfinity/candid'; -import { CanisterMethodInfo, query } from '../../../../../canister_methods'; +import { CanisterMethodInfo } from '../../../../../canister_methods/canister_method_info'; import { decode, encode } from '../../../../serde'; import { createQueryMethods, createUpdateMethods } from './query_update'; import { @@ -109,8 +104,8 @@ function createUpdateOrQueryFunctionIdl( parents: Parent[] ): IDL.FuncClass { const annotations = createAnnotation(functionInfo.mode); - const paramIdls = toParamIdls(functionInfo.paramCandidTypes, parents); - const returnIdls = toReturnIdl(functionInfo.returnCandidType, parents); + const paramIdls = toIdlArray(functionInfo.paramCandidTypes, parents); + const returnIdls = toIdlArray(functionInfo.returnCandidType, parents); return IDL.Func(paramIdls, returnIdls, annotations); } diff --git a/src/lib/candid/types/reference/service/canister_function/system_methods.ts b/src/lib/candid/types/reference/service/canister_function/system_methods.ts index 5fce6ebb95..7fa272a6fb 100644 --- a/src/lib/candid/types/reference/service/canister_function/system_methods.ts +++ b/src/lib/candid/types/reference/service/canister_function/system_methods.ts @@ -1,4 +1,4 @@ -import { Parent, toParamIdls, toReturnIdl } from '../../../../index'; +import { Parent, toIdlArray } from '../../../../index'; import { _AzleRecursiveFunction } from '../../../../recursive'; import { IDL } from '@dfinity/candid'; import { CanisterOptions, ServiceFunctionInfo } from '.'; @@ -40,11 +40,11 @@ export function createGetSystemFunctionIdlFunction( return accumulator; } - const paramIdls = toParamIdls( + const paramIdls = toIdlArray( functionInfo.paramCandidTypes, parents ); - const returnIdl = toReturnIdl( + const returnIdl = toIdlArray( functionInfo.returnCandidType, parents ); From f67057d6580b0615e8e237223a32af28bc17199b Mon Sep 17 00:00:00 2001 From: Benjamin DeMann Date: Wed, 18 Oct 2023 15:28:19 -0600 Subject: [PATCH 29/36] fix imports --- src/lib/candid/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib/candid/index.ts b/src/lib/candid/index.ts index e5ce2a2ddd..4b9215d1d5 100644 --- a/src/lib/candid/index.ts +++ b/src/lib/candid/index.ts @@ -1,4 +1,5 @@ export * from './candid_type'; +export * from './manual'; export * from './recursive'; export * from './to_idl'; export * from './type_mapping'; From 86509a6d72931b42ce075945a444b9924c7e2b29 Mon Sep 17 00:00:00 2001 From: Benjamin DeMann Date: Wed, 18 Oct 2023 15:28:30 -0600 Subject: [PATCH 30/36] clean up bigint casting --- src/lib/ic/canister_balance.ts | 2 +- src/lib/ic/canister_balance_128.ts | 2 +- src/lib/ic/canister_version.ts | 2 +- src/lib/ic/instruction_counter.ts | 2 +- src/lib/ic/msg_cycles_accept.ts | 2 +- src/lib/ic/msg_cycles_accept_128.ts | 2 +- src/lib/ic/msg_cycles_available.ts | 2 +- src/lib/ic/msg_cycles_available_128.ts | 2 +- src/lib/ic/msg_cycles_refunded.ts | 2 +- src/lib/ic/msg_cycles_refunded_128.ts | 2 +- src/lib/ic/performance_counter.ts | 2 +- src/lib/ic/set_timer.ts | 7 ++----- src/lib/ic/set_timer_interval.ts | 9 +++------ src/lib/ic/stable_64_grow.ts | 7 +------ src/lib/ic/stable_64_size.ts | 2 +- src/lib/ic/time.ts | 2 +- 16 files changed, 19 insertions(+), 30 deletions(-) diff --git a/src/lib/ic/canister_balance.ts b/src/lib/ic/canister_balance.ts index 5e59b98868..69323f1dea 100644 --- a/src/lib/ic/canister_balance.ts +++ b/src/lib/ic/canister_balance.ts @@ -11,5 +11,5 @@ export function canisterBalance(): nat64 { } const canisterBalanceCandidBytes = globalThis._azleIc.canisterBalance(); - return BigInt(decode(nat64, canisterBalanceCandidBytes) as number); + return decode(nat64, canisterBalanceCandidBytes); } diff --git a/src/lib/ic/canister_balance_128.ts b/src/lib/ic/canister_balance_128.ts index e74483aed3..15534dd70f 100644 --- a/src/lib/ic/canister_balance_128.ts +++ b/src/lib/ic/canister_balance_128.ts @@ -12,5 +12,5 @@ export function canisterBalance128(): nat { const canisterBalance128CandidBytes = globalThis._azleIc.canisterBalance128(); - return BigInt(decode(nat, canisterBalance128CandidBytes) as number); + return decode(nat, canisterBalance128CandidBytes); } diff --git a/src/lib/ic/canister_version.ts b/src/lib/ic/canister_version.ts index fdeea1116f..8c00845ef5 100644 --- a/src/lib/ic/canister_version.ts +++ b/src/lib/ic/canister_version.ts @@ -12,5 +12,5 @@ export function canisterVersion(): nat64 { } const canisterVersionCandidBytes = globalThis._azleIc.canisterVersion(); - return BigInt(decode(nat64, canisterVersionCandidBytes) as number); + return decode(nat64, canisterVersionCandidBytes); } diff --git a/src/lib/ic/instruction_counter.ts b/src/lib/ic/instruction_counter.ts index 366774132a..c647e7ca9d 100644 --- a/src/lib/ic/instruction_counter.ts +++ b/src/lib/ic/instruction_counter.ts @@ -16,5 +16,5 @@ export function instructionCounter(): nat64 { const instructionCounterCandidBytes = globalThis._azleIc.instructionCounter(); - return BigInt(decode(nat64, instructionCounterCandidBytes) as number); + return decode(nat64, instructionCounterCandidBytes); } diff --git a/src/lib/ic/msg_cycles_accept.ts b/src/lib/ic/msg_cycles_accept.ts index 0964133d27..c65ba46dff 100644 --- a/src/lib/ic/msg_cycles_accept.ts +++ b/src/lib/ic/msg_cycles_accept.ts @@ -16,5 +16,5 @@ export function msgCyclesAccept(maxAmount: nat64): nat64 { const msgCyclesAcceptCandidBytes = globalThis._azleIc.msgCyclesAccept(maxAmountCandidBytes); - return BigInt(decode(nat64, msgCyclesAcceptCandidBytes) as number); + return decode(nat64, msgCyclesAcceptCandidBytes); } diff --git a/src/lib/ic/msg_cycles_accept_128.ts b/src/lib/ic/msg_cycles_accept_128.ts index c7365d29b4..a35a5bc4c0 100644 --- a/src/lib/ic/msg_cycles_accept_128.ts +++ b/src/lib/ic/msg_cycles_accept_128.ts @@ -16,5 +16,5 @@ export function msgCyclesAccept128(maxAmount: nat): nat { const msgCyclesAccept128CandidBytes = globalThis._azleIc.msgCyclesAccept128(maxAmountCandidBytes); - return BigInt(decode(nat, msgCyclesAccept128CandidBytes) as number); + return decode(nat, msgCyclesAccept128CandidBytes); } diff --git a/src/lib/ic/msg_cycles_available.ts b/src/lib/ic/msg_cycles_available.ts index c2e9a20275..3a941dccef 100644 --- a/src/lib/ic/msg_cycles_available.ts +++ b/src/lib/ic/msg_cycles_available.ts @@ -14,5 +14,5 @@ export function msgCyclesAvailable(): nat64 { const msgCyclesAvailableCandidBytes = globalThis._azleIc.msgCyclesAvailable(); - return BigInt(decode(nat64, msgCyclesAvailableCandidBytes) as number); + return decode(nat64, msgCyclesAvailableCandidBytes); } diff --git a/src/lib/ic/msg_cycles_available_128.ts b/src/lib/ic/msg_cycles_available_128.ts index f5e223f721..ba30d3986c 100644 --- a/src/lib/ic/msg_cycles_available_128.ts +++ b/src/lib/ic/msg_cycles_available_128.ts @@ -14,5 +14,5 @@ export function msgCyclesAvailable128(): nat { const msgCyclesAvailable128CandidBytes = globalThis._azleIc.msgCyclesAvailable128(); - return BigInt(decode(nat, msgCyclesAvailable128CandidBytes) as number); + return decode(nat, msgCyclesAvailable128CandidBytes); } diff --git a/src/lib/ic/msg_cycles_refunded.ts b/src/lib/ic/msg_cycles_refunded.ts index 65ebfcf442..85099ee685 100644 --- a/src/lib/ic/msg_cycles_refunded.ts +++ b/src/lib/ic/msg_cycles_refunded.ts @@ -13,5 +13,5 @@ export function msgCyclesRefunded(): nat64 { const msgCyclesRefundedCandidBytes = globalThis._azleIc.msgCyclesRefunded(); - return BigInt(decode(nat64, msgCyclesRefundedCandidBytes) as number); + return decode(nat64, msgCyclesRefundedCandidBytes); } diff --git a/src/lib/ic/msg_cycles_refunded_128.ts b/src/lib/ic/msg_cycles_refunded_128.ts index c8afc15865..1d541b3fc9 100644 --- a/src/lib/ic/msg_cycles_refunded_128.ts +++ b/src/lib/ic/msg_cycles_refunded_128.ts @@ -14,5 +14,5 @@ export function msgCyclesRefunded128(): nat { const msgCyclesRefunded128CandidBytes = globalThis._azleIc.msgCyclesRefunded128(); - return BigInt(decode(nat, msgCyclesRefunded128CandidBytes) as number); + return decode(nat, msgCyclesRefunded128CandidBytes); } diff --git a/src/lib/ic/performance_counter.ts b/src/lib/ic/performance_counter.ts index 9955754361..6dafb8877e 100644 --- a/src/lib/ic/performance_counter.ts +++ b/src/lib/ic/performance_counter.ts @@ -22,5 +22,5 @@ export function performanceCounter(counterType: nat32): nat64 { counterTypeCandidBytes ); - return BigInt(decode(nat64, performanceCounterCandidBytes) as number); + return decode(nat64, performanceCounterCandidBytes); } diff --git a/src/lib/ic/set_timer.ts b/src/lib/ic/set_timer.ts index e6bbd41be6..18bbcf0371 100644 --- a/src/lib/ic/set_timer.ts +++ b/src/lib/ic/set_timer.ts @@ -1,7 +1,7 @@ import { Duration, TimerId } from './types'; import { v4 } from 'uuid'; import { nat64 } from '../candid/types/primitive/nats/nat64'; -import { encode, decode as azleDecode } from '../candid/serde'; +import { encode, decode } from '../candid/serde'; /** * Sets callback to be executed later, after delay. Panics if `delay` + time() is more than 2^64 - 1. @@ -20,13 +20,10 @@ export function setTimer( return undefined as any; } - const decode = (value: ArrayBufferLike) => { - return BigInt(azleDecode(nat64, value) as number); - }; - const timerCallbackId = `_timer_${v4()}`; const timerId = decode( + nat64, globalThis._azleIc.setTimer( encode(nat64, delay).buffer, timerCallbackId diff --git a/src/lib/ic/set_timer_interval.ts b/src/lib/ic/set_timer_interval.ts index 8b9eef07ec..03e3299dc8 100644 --- a/src/lib/ic/set_timer_interval.ts +++ b/src/lib/ic/set_timer_interval.ts @@ -1,6 +1,6 @@ import { Duration, TimerId } from './types'; import { v4 } from 'uuid'; -import { encode as azleEncode, decode as azleDecode } from '../candid/serde'; +import { encode, decode } from '../candid/serde'; import { nat64 } from '../candid/types/primitive/nats/nat64'; /** @@ -20,15 +20,12 @@ export function setTimerInterval( return undefined as any; } - const decode = (value: ArrayBufferLike) => { - return BigInt(azleDecode(nat64, value) as number); - }; - const timerCallbackId = `_interval_timer_${v4()}`; const timerId = decode( + nat64, globalThis._azleIc.setTimerInterval( - azleEncode(nat64, interval).buffer, + encode(nat64, interval).buffer, timerCallbackId ) ); diff --git a/src/lib/ic/stable_64_grow.ts b/src/lib/ic/stable_64_grow.ts index e65145defa..8928536229 100644 --- a/src/lib/ic/stable_64_grow.ts +++ b/src/lib/ic/stable_64_grow.ts @@ -14,10 +14,5 @@ export function stable64Grow(newPages: nat64): nat64 { const newPagesCandidBytes = encode(nat64, newPages).buffer; - return BigInt( - decode( - nat64, - globalThis._azleIc.stable64Grow(newPagesCandidBytes) - ) as number - ); + return decode(nat64, globalThis._azleIc.stable64Grow(newPagesCandidBytes)); } diff --git a/src/lib/ic/stable_64_size.ts b/src/lib/ic/stable_64_size.ts index 9bcc7af0d8..01fd03cfa6 100644 --- a/src/lib/ic/stable_64_size.ts +++ b/src/lib/ic/stable_64_size.ts @@ -11,5 +11,5 @@ export function stable64Size(): nat64 { return undefined as any; } - return BigInt(decode(nat64, globalThis._azleIc.stable64Size()) as number); + return decode(nat64, globalThis._azleIc.stable64Size()); } diff --git a/src/lib/ic/time.ts b/src/lib/ic/time.ts index 3e068b9f6a..7ded28a8c1 100644 --- a/src/lib/ic/time.ts +++ b/src/lib/ic/time.ts @@ -11,5 +11,5 @@ export function time(): nat64 { } const timeCandidBytes = globalThis._azleIc.time(); - return BigInt(decode(nat64, timeCandidBytes) as number); + return decode(nat64, timeCandidBytes); } From 75f12f86ed62a0935a1770c610b3ae7b16216e45 Mon Sep 17 00:00:00 2001 From: Benjamin DeMann Date: Wed, 18 Oct 2023 15:39:03 -0600 Subject: [PATCH 31/36] fix heartbeat --- src/lib/canister_methods/methods/heartbeat.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/canister_methods/methods/heartbeat.ts b/src/lib/canister_methods/methods/heartbeat.ts index 675b893d8d..1c37d8d42e 100644 --- a/src/lib/canister_methods/methods/heartbeat.ts +++ b/src/lib/canister_methods/methods/heartbeat.ts @@ -8,7 +8,7 @@ export function heartbeat( ): CanisterMethodInfo<[], Void> { return { mode: 'heartbeat', - callback: executeHeartbeat, + callback: () => executeHeartbeat(callback), paramCandidTypes: [], returnCandidType: Void, async: isAsync(callback), From 08eccf4ab666f317656cb378c5b56662f25b91cc Mon Sep 17 00:00:00 2001 From: Benjamin DeMann Date: Wed, 18 Oct 2023 15:57:41 -0600 Subject: [PATCH 32/36] pr fixes --- src/compiler/generate_candid_and_canister_methods.ts | 2 +- src/lib/candid/did_file/to_did_string.ts | 10 +++++----- .../did_file/{visitor.ts => visitor}/did_visitor.ts | 0 .../{visitor.ts => visitor}/escapeCandidKeywords.ts | 0 .../did_file/{visitor.ts => visitor}/extract_candid.ts | 0 .../candid/did_file/{visitor.ts => visitor}/index.ts | 0 .../did_file/{visitor.ts => visitor}/visit_func.ts | 0 .../did_file/{visitor.ts => visitor}/visit_opt.ts | 0 .../{visitor.ts => visitor}/visit_primitive.ts | 0 .../did_file/{visitor.ts => visitor}/visit_record.ts | 0 .../{visitor.ts => visitor}/visit_recursive.ts | 0 .../did_file/{visitor.ts => visitor}/visit_service.ts | 0 .../did_file/{visitor.ts => visitor}/visit_tuple.ts | 0 .../did_file/{visitor.ts => visitor}/visit_variant.ts | 0 .../did_file/{visitor.ts => visitor}/visit_vec.ts | 0 15 files changed, 6 insertions(+), 6 deletions(-) rename src/lib/candid/did_file/{visitor.ts => visitor}/did_visitor.ts (100%) rename src/lib/candid/did_file/{visitor.ts => visitor}/escapeCandidKeywords.ts (100%) rename src/lib/candid/did_file/{visitor.ts => visitor}/extract_candid.ts (100%) rename src/lib/candid/did_file/{visitor.ts => visitor}/index.ts (100%) rename src/lib/candid/did_file/{visitor.ts => visitor}/visit_func.ts (100%) rename src/lib/candid/did_file/{visitor.ts => visitor}/visit_opt.ts (100%) rename src/lib/candid/did_file/{visitor.ts => visitor}/visit_primitive.ts (100%) rename src/lib/candid/did_file/{visitor.ts => visitor}/visit_record.ts (100%) rename src/lib/candid/did_file/{visitor.ts => visitor}/visit_recursive.ts (100%) rename src/lib/candid/did_file/{visitor.ts => visitor}/visit_service.ts (100%) rename src/lib/candid/did_file/{visitor.ts => visitor}/visit_tuple.ts (100%) rename src/lib/candid/did_file/{visitor.ts => visitor}/visit_variant.ts (100%) rename src/lib/candid/did_file/{visitor.ts => visitor}/visit_vec.ts (100%) diff --git a/src/compiler/generate_candid_and_canister_methods.ts b/src/compiler/generate_candid_and_canister_methods.ts index 882401242e..4fa06c4fb4 100644 --- a/src/compiler/generate_candid_and_canister_methods.ts +++ b/src/compiler/generate_candid_and_canister_methods.ts @@ -2,7 +2,7 @@ import { CanisterMethods } from './utils/types'; import { getDefaultVisitorData, DidVisitor -} from '../lib/candid/did_file/visitor.ts'; +} from '../lib/candid/did_file/visitor'; import { toDidString } from '../lib/candid/did_file'; export function generateCandidAndCanisterMethods(mainJs: string): { diff --git a/src/lib/candid/did_file/to_did_string.ts b/src/lib/candid/did_file/to_did_string.ts index f674fe3faa..8bb12a7e47 100644 --- a/src/lib/candid/did_file/to_did_string.ts +++ b/src/lib/candid/did_file/to_did_string.ts @@ -1,4 +1,4 @@ -import { CandidTypesDefs, VisitorResult } from './visitor.ts/index.js'; +import { CandidTypesDefs, VisitorResult } from './visitor/index.js'; export function toDidString(result: VisitorResult): string { // TODO it would be nice to have names for the rec types instead of rec_1, rec_2 etc @@ -9,17 +9,17 @@ export function toDidString(result: VisitorResult): string { // That might not be the ideal situation, but it is the expected behavior in rust const [candid, candidTypeDefs] = result; - const candidTypesString = newTypeToCandidString(candidTypeDefs); + const candidTypesString = namedTypeToCandidString(candidTypeDefs); return candidTypesString + candid + '\n'; } -function newTypeToCandidString(newTypes: CandidTypesDefs): string { +function namedTypeToCandidString(newTypes: CandidTypesDefs): string { return Object.entries(newTypes).length > 0 - ? newTypesToStingArr(newTypes).join('\n') + '\n' + ? namedTypesToStingArr(newTypes).join('\n') + '\n' : ''; } -function newTypesToStingArr(newTypes: CandidTypesDefs): string[] { +function namedTypesToStingArr(newTypes: CandidTypesDefs): string[] { return Object.entries(newTypes).map( ([name, candid]) => `type ${name} = ${candid};` ); diff --git a/src/lib/candid/did_file/visitor.ts/did_visitor.ts b/src/lib/candid/did_file/visitor/did_visitor.ts similarity index 100% rename from src/lib/candid/did_file/visitor.ts/did_visitor.ts rename to src/lib/candid/did_file/visitor/did_visitor.ts diff --git a/src/lib/candid/did_file/visitor.ts/escapeCandidKeywords.ts b/src/lib/candid/did_file/visitor/escapeCandidKeywords.ts similarity index 100% rename from src/lib/candid/did_file/visitor.ts/escapeCandidKeywords.ts rename to src/lib/candid/did_file/visitor/escapeCandidKeywords.ts diff --git a/src/lib/candid/did_file/visitor.ts/extract_candid.ts b/src/lib/candid/did_file/visitor/extract_candid.ts similarity index 100% rename from src/lib/candid/did_file/visitor.ts/extract_candid.ts rename to src/lib/candid/did_file/visitor/extract_candid.ts diff --git a/src/lib/candid/did_file/visitor.ts/index.ts b/src/lib/candid/did_file/visitor/index.ts similarity index 100% rename from src/lib/candid/did_file/visitor.ts/index.ts rename to src/lib/candid/did_file/visitor/index.ts diff --git a/src/lib/candid/did_file/visitor.ts/visit_func.ts b/src/lib/candid/did_file/visitor/visit_func.ts similarity index 100% rename from src/lib/candid/did_file/visitor.ts/visit_func.ts rename to src/lib/candid/did_file/visitor/visit_func.ts diff --git a/src/lib/candid/did_file/visitor.ts/visit_opt.ts b/src/lib/candid/did_file/visitor/visit_opt.ts similarity index 100% rename from src/lib/candid/did_file/visitor.ts/visit_opt.ts rename to src/lib/candid/did_file/visitor/visit_opt.ts diff --git a/src/lib/candid/did_file/visitor.ts/visit_primitive.ts b/src/lib/candid/did_file/visitor/visit_primitive.ts similarity index 100% rename from src/lib/candid/did_file/visitor.ts/visit_primitive.ts rename to src/lib/candid/did_file/visitor/visit_primitive.ts diff --git a/src/lib/candid/did_file/visitor.ts/visit_record.ts b/src/lib/candid/did_file/visitor/visit_record.ts similarity index 100% rename from src/lib/candid/did_file/visitor.ts/visit_record.ts rename to src/lib/candid/did_file/visitor/visit_record.ts diff --git a/src/lib/candid/did_file/visitor.ts/visit_recursive.ts b/src/lib/candid/did_file/visitor/visit_recursive.ts similarity index 100% rename from src/lib/candid/did_file/visitor.ts/visit_recursive.ts rename to src/lib/candid/did_file/visitor/visit_recursive.ts diff --git a/src/lib/candid/did_file/visitor.ts/visit_service.ts b/src/lib/candid/did_file/visitor/visit_service.ts similarity index 100% rename from src/lib/candid/did_file/visitor.ts/visit_service.ts rename to src/lib/candid/did_file/visitor/visit_service.ts diff --git a/src/lib/candid/did_file/visitor.ts/visit_tuple.ts b/src/lib/candid/did_file/visitor/visit_tuple.ts similarity index 100% rename from src/lib/candid/did_file/visitor.ts/visit_tuple.ts rename to src/lib/candid/did_file/visitor/visit_tuple.ts diff --git a/src/lib/candid/did_file/visitor.ts/visit_variant.ts b/src/lib/candid/did_file/visitor/visit_variant.ts similarity index 100% rename from src/lib/candid/did_file/visitor.ts/visit_variant.ts rename to src/lib/candid/did_file/visitor/visit_variant.ts diff --git a/src/lib/candid/did_file/visitor.ts/visit_vec.ts b/src/lib/candid/did_file/visitor/visit_vec.ts similarity index 100% rename from src/lib/candid/did_file/visitor.ts/visit_vec.ts rename to src/lib/candid/did_file/visitor/visit_vec.ts From 2b85bd39c48917b597b437e48d32cb6833c332f8 Mon Sep 17 00:00:00 2001 From: Benjamin DeMann Date: Wed, 18 Oct 2023 16:16:43 -0600 Subject: [PATCH 33/36] pr fixes --- src/lib/candid/did_file/visitor/did_visitor.ts | 18 +++++++++--------- ...idKeywords.ts => escape_candid_keywords.ts} | 0 .../candid/did_file/visitor/extract_candid.ts | 2 +- .../visitor/{visit_func.ts => visit/func.ts} | 4 ++-- .../visitor/{visit_opt.ts => visit/opt.ts} | 2 +- .../{visit_primitive.ts => visit/primitive.ts} | 2 +- .../{visit_record.ts => visit/record.ts} | 6 +++--- .../{visit_recursive.ts => visit/recursive.ts} | 2 +- .../{visit_service.ts => visit/service.ts} | 6 +++--- .../visitor/{visit_tuple.ts => visit/tuple.ts} | 4 ++-- .../{visit_variant.ts => visit/variant.ts} | 6 +++--- .../visitor/{visit_vec.ts => visit/vec.ts} | 2 +- .../service/canister_function/index.ts | 2 +- .../candid/types/reference/service/index.ts | 2 +- src/lib/canister_methods/execute_method.ts | 2 +- src/lib/canister_methods/methods/heartbeat.ts | 2 +- src/lib/canister_methods/methods/init.ts | 4 ++-- .../methods/inspect_message.ts | 2 +- .../canister_methods/methods/post_upgrade.ts | 4 ++-- .../canister_methods/methods/pre_upgrade.ts | 2 +- src/lib/canister_methods/methods/query.ts | 6 +++--- src/lib/canister_methods/methods/update.ts | 6 +++--- .../canister_methods/{ => types}/callback.ts | 2 +- .../{ => types}/canister_method_info.ts | 0 src/lib/canister_methods/types/index.ts | 3 +++ .../{ => types}/method_args.ts | 0 src/lib/ic/call_raw.ts | 1 - src/lib/ic/call_raw_128.ts | 1 - src/lib/ic/clear_timer.ts | 1 - 29 files changed, 47 insertions(+), 47 deletions(-) rename src/lib/candid/did_file/visitor/{escapeCandidKeywords.ts => escape_candid_keywords.ts} (100%) rename src/lib/candid/did_file/visitor/{visit_func.ts => visit/func.ts} (87%) rename src/lib/candid/did_file/visitor/{visit_opt.ts => visit/opt.ts} (82%) rename src/lib/candid/did_file/visitor/{visit_primitive.ts => visit/primitive.ts} (80%) rename src/lib/candid/did_file/visitor/{visit_record.ts => visit/record.ts} (75%) rename src/lib/candid/did_file/visitor/{visit_recursive.ts => visit/recursive.ts} (94%) rename src/lib/candid/did_file/visitor/{visit_service.ts => visit/service.ts} (96%) rename src/lib/candid/did_file/visitor/{visit_tuple.ts => visit/tuple.ts} (77%) rename src/lib/candid/did_file/visitor/{visit_variant.ts => visit/variant.ts} (77%) rename src/lib/candid/did_file/visitor/{visit_vec.ts => visit/vec.ts} (82%) rename src/lib/canister_methods/{ => types}/callback.ts (79%) rename src/lib/canister_methods/{ => types}/canister_method_info.ts (100%) create mode 100644 src/lib/canister_methods/types/index.ts rename src/lib/canister_methods/{ => types}/method_args.ts (100%) diff --git a/src/lib/candid/did_file/visitor/did_visitor.ts b/src/lib/candid/did_file/visitor/did_visitor.ts index 0f28df12f8..509461b95d 100644 --- a/src/lib/candid/did_file/visitor/did_visitor.ts +++ b/src/lib/candid/did_file/visitor/did_visitor.ts @@ -1,13 +1,13 @@ import { IDL } from '@dfinity/candid'; -import { visitService } from './visit_service'; -import { visitVariant } from './visit_variant'; -import { visitRecord } from './visit_record'; -import { visitRecursive } from './visit_recursive'; -import { visitPrimitive } from './visit_primitive'; -import { visitTuple } from './visit_tuple'; -import { visitOpt } from './visit_opt'; -import { visitVec } from './visit_vec'; -import { visitFunc } from './visit_func'; +import { visitService } from './visit/service'; +import { visitVariant } from './visit/variant'; +import { visitRecord } from './visit/record'; +import { visitRecursive } from './visit/recursive'; +import { visitPrimitive } from './visit/primitive'; +import { visitTuple } from './visit/tuple'; +import { visitOpt } from './visit/opt'; +import { visitVec } from './visit/vec'; +import { visitFunc } from './visit/func'; export type VisitorData = { usedRecClasses: IDL.RecClass[]; diff --git a/src/lib/candid/did_file/visitor/escapeCandidKeywords.ts b/src/lib/candid/did_file/visitor/escape_candid_keywords.ts similarity index 100% rename from src/lib/candid/did_file/visitor/escapeCandidKeywords.ts rename to src/lib/candid/did_file/visitor/escape_candid_keywords.ts diff --git a/src/lib/candid/did_file/visitor/extract_candid.ts b/src/lib/candid/did_file/visitor/extract_candid.ts index 4e8c054f99..afcd46f10c 100644 --- a/src/lib/candid/did_file/visitor/extract_candid.ts +++ b/src/lib/candid/did_file/visitor/extract_candid.ts @@ -1,4 +1,4 @@ -import { CandidDef, CandidTypesDefs } from '.'; +import { CandidDef, CandidTypesDefs } from './did_visitor'; export function extractCandid( paramInfo: [CandidDef, CandidTypesDefs][] diff --git a/src/lib/candid/did_file/visitor/visit_func.ts b/src/lib/candid/did_file/visitor/visit/func.ts similarity index 87% rename from src/lib/candid/did_file/visitor/visit_func.ts rename to src/lib/candid/did_file/visitor/visit/func.ts index 25f16942aa..404d7375ac 100644 --- a/src/lib/candid/did_file/visitor/visit_func.ts +++ b/src/lib/candid/did_file/visitor/visit/func.ts @@ -1,6 +1,6 @@ import { IDL } from '@dfinity/candid'; -import { DidVisitor, VisitorData, VisitorResult } from '.'; -import { extractCandid } from './extract_candid'; +import { DidVisitor, VisitorData, VisitorResult } from '..'; +import { extractCandid } from '../extract_candid'; export function visitFunc( t: IDL.FuncClass, diff --git a/src/lib/candid/did_file/visitor/visit_opt.ts b/src/lib/candid/did_file/visitor/visit/opt.ts similarity index 82% rename from src/lib/candid/did_file/visitor/visit_opt.ts rename to src/lib/candid/did_file/visitor/visit/opt.ts index 93c838878d..ed97ff872c 100644 --- a/src/lib/candid/did_file/visitor/visit_opt.ts +++ b/src/lib/candid/did_file/visitor/visit/opt.ts @@ -1,5 +1,5 @@ import { IDL } from '@dfinity/candid'; -import { DidVisitor, VisitorData, VisitorResult } from '.'; +import { DidVisitor, VisitorData, VisitorResult } from '..'; export function visitOpt( ty: IDL.Type, diff --git a/src/lib/candid/did_file/visitor/visit_primitive.ts b/src/lib/candid/did_file/visitor/visit/primitive.ts similarity index 80% rename from src/lib/candid/did_file/visitor/visit_primitive.ts rename to src/lib/candid/did_file/visitor/visit/primitive.ts index cf4a128ea0..9d7e92595a 100644 --- a/src/lib/candid/did_file/visitor/visit_primitive.ts +++ b/src/lib/candid/did_file/visitor/visit/primitive.ts @@ -1,5 +1,5 @@ import { IDL } from '@dfinity/candid'; -import { VisitorResult } from '.'; +import { VisitorResult } from '..'; export function visitPrimitive(t: IDL.PrimitiveType): VisitorResult { return [t.display(), {}]; diff --git a/src/lib/candid/did_file/visitor/visit_record.ts b/src/lib/candid/did_file/visitor/visit/record.ts similarity index 75% rename from src/lib/candid/did_file/visitor/visit_record.ts rename to src/lib/candid/did_file/visitor/visit/record.ts index 818de64b90..afff050dba 100644 --- a/src/lib/candid/did_file/visitor/visit_record.ts +++ b/src/lib/candid/did_file/visitor/visit/record.ts @@ -1,7 +1,7 @@ import { IDL } from '@dfinity/candid'; -import { DidVisitor, VisitorData, VisitorResult } from '.'; -import { escapeCandidKeywords } from './escapeCandidKeywords'; -import { extractCandid } from './extract_candid'; +import { DidVisitor, VisitorData, VisitorResult } from '..'; +import { escapeCandidKeywords } from '../escape_candid_keywords'; +import { extractCandid } from '../extract_candid'; export function visitRecord( fields: [string, IDL.Type][], diff --git a/src/lib/candid/did_file/visitor/visit_recursive.ts b/src/lib/candid/did_file/visitor/visit/recursive.ts similarity index 94% rename from src/lib/candid/did_file/visitor/visit_recursive.ts rename to src/lib/candid/did_file/visitor/visit/recursive.ts index ff8e8f54da..fc90b32b65 100644 --- a/src/lib/candid/did_file/visitor/visit_recursive.ts +++ b/src/lib/candid/did_file/visitor/visit/recursive.ts @@ -1,5 +1,5 @@ import { IDL } from '@dfinity/candid'; -import { DidVisitor, VisitorData, VisitorResult } from '.'; +import { DidVisitor, VisitorData, VisitorResult } from '..'; export function visitRecursive( t: IDL.RecClass, diff --git a/src/lib/candid/did_file/visitor/visit_service.ts b/src/lib/candid/did_file/visitor/visit/service.ts similarity index 96% rename from src/lib/candid/did_file/visitor/visit_service.ts rename to src/lib/candid/did_file/visitor/visit/service.ts index bd75726813..fbe1215a64 100644 --- a/src/lib/candid/did_file/visitor/visit_service.ts +++ b/src/lib/candid/did_file/visitor/visit/service.ts @@ -1,7 +1,7 @@ import { IDL } from '@dfinity/candid'; -import { CandidDef, CandidTypesDefs, DidVisitor, VisitorData } from '.'; -import { escapeCandidKeywords } from './escapeCandidKeywords'; -import { extractCandid } from './extract_candid'; +import { CandidDef, CandidTypesDefs, DidVisitor, VisitorData } from '..'; +import { escapeCandidKeywords } from '../escape_candid_keywords'; +import { extractCandid } from '../extract_candid'; export function visitService( t: IDL.ServiceClass, diff --git a/src/lib/candid/did_file/visitor/visit_tuple.ts b/src/lib/candid/did_file/visitor/visit/tuple.ts similarity index 77% rename from src/lib/candid/did_file/visitor/visit_tuple.ts rename to src/lib/candid/did_file/visitor/visit/tuple.ts index 82292b60fc..7f6b475615 100644 --- a/src/lib/candid/did_file/visitor/visit_tuple.ts +++ b/src/lib/candid/did_file/visitor/visit/tuple.ts @@ -1,6 +1,6 @@ import { IDL } from '@dfinity/candid'; -import { DidVisitor, VisitorData, VisitorResult } from '.'; -import { extractCandid } from './extract_candid'; +import { DidVisitor, VisitorData, VisitorResult } from '..'; +import { extractCandid } from '../extract_candid'; export function visitTuple( components: IDL.Type[], diff --git a/src/lib/candid/did_file/visitor/visit_variant.ts b/src/lib/candid/did_file/visitor/visit/variant.ts similarity index 77% rename from src/lib/candid/did_file/visitor/visit_variant.ts rename to src/lib/candid/did_file/visitor/visit/variant.ts index 4ca1fb06d9..e9a966396a 100644 --- a/src/lib/candid/did_file/visitor/visit_variant.ts +++ b/src/lib/candid/did_file/visitor/visit/variant.ts @@ -1,7 +1,7 @@ import { IDL } from '@dfinity/candid'; -import { DidVisitor, VisitorData, VisitorResult } from '.'; -import { escapeCandidKeywords } from './escapeCandidKeywords'; -import { extractCandid } from './extract_candid'; +import { DidVisitor, VisitorData, VisitorResult } from '..'; +import { escapeCandidKeywords } from '../escape_candid_keywords'; +import { extractCandid } from '../extract_candid'; export function visitVariant( fields: [string, IDL.Type][], diff --git a/src/lib/candid/did_file/visitor/visit_vec.ts b/src/lib/candid/did_file/visitor/visit/vec.ts similarity index 82% rename from src/lib/candid/did_file/visitor/visit_vec.ts rename to src/lib/candid/did_file/visitor/visit/vec.ts index 709675d1cc..fff1f8b01d 100644 --- a/src/lib/candid/did_file/visitor/visit_vec.ts +++ b/src/lib/candid/did_file/visitor/visit/vec.ts @@ -1,5 +1,5 @@ import { IDL } from '@dfinity/candid'; -import { DidVisitor, VisitorData, VisitorResult } from '.'; +import { DidVisitor, VisitorData, VisitorResult } from '..'; export function visitVec( ty: IDL.Type, diff --git a/src/lib/candid/types/reference/service/canister_function/index.ts b/src/lib/candid/types/reference/service/canister_function/index.ts index 468d60ad8d..93e8e76ec6 100644 --- a/src/lib/candid/types/reference/service/canister_function/index.ts +++ b/src/lib/candid/types/reference/service/canister_function/index.ts @@ -3,7 +3,7 @@ import { _AzleRecursiveFunction } from '../../../../recursive'; import { ic } from '../../../../../ic'; import { Principal } from '../../principal'; import { IDL } from '@dfinity/candid'; -import { CanisterMethodInfo } from '../../../../../canister_methods/canister_method_info'; +import { CanisterMethodInfo } from '../../../../../canister_methods/types/canister_method_info'; import { decode, encode } from '../../../../serde'; import { createQueryMethods, createUpdateMethods } from './query_update'; import { diff --git a/src/lib/candid/types/reference/service/index.ts b/src/lib/candid/types/reference/service/index.ts index 40069b63c9..a1f6a4b402 100644 --- a/src/lib/candid/types/reference/service/index.ts +++ b/src/lib/candid/types/reference/service/index.ts @@ -1,7 +1,7 @@ +import { CanisterMethodInfo } from '../../../../canister_methods/types/canister_method_info'; import { TypeMapping } from '../../../index'; import { _AzleRecursiveFunction } from '../../../recursive'; import { Principal } from '../principal'; -import { CanisterMethodInfo } from '../../../../canister_methods'; import { createCanisterFunction } from './canister_function'; type CanisterOptions = { diff --git a/src/lib/canister_methods/execute_method.ts b/src/lib/canister_methods/execute_method.ts index 78a04fbf86..a575d54a01 100644 --- a/src/lib/canister_methods/execute_method.ts +++ b/src/lib/canister_methods/execute_method.ts @@ -1,7 +1,7 @@ import { ic } from '../ic'; import { CandidType, TypeMapping } from '../candid'; import { decode, encode } from '../candid/serde'; -import { CanisterMethodInfo } from './canister_method_info'; +import { CanisterMethodInfo } from './types/canister_method_info'; export function executeMethod( mode: CanisterMethodInfo['mode'], diff --git a/src/lib/canister_methods/methods/heartbeat.ts b/src/lib/canister_methods/methods/heartbeat.ts index 1c37d8d42e..373ce8feca 100644 --- a/src/lib/canister_methods/methods/heartbeat.ts +++ b/src/lib/canister_methods/methods/heartbeat.ts @@ -1,6 +1,6 @@ import { ic } from '../../ic'; import { Void } from '../../candid/types/primitive/void'; -import { CanisterMethodInfo } from '../canister_method_info'; +import { CanisterMethodInfo } from '../types/canister_method_info'; import { isAsync } from '../is_async'; export function heartbeat( diff --git a/src/lib/canister_methods/methods/init.ts b/src/lib/canister_methods/methods/init.ts index 1b9f2817d5..aa977b1b2c 100644 --- a/src/lib/canister_methods/methods/init.ts +++ b/src/lib/canister_methods/methods/init.ts @@ -1,7 +1,7 @@ import { CandidType, TypeMapping } from '../../candid'; import { Void } from '../../candid/types/primitive/void'; -import { Callback } from '../callback'; -import { CanisterMethodInfo } from '../canister_method_info'; +import { Callback } from '../types/callback'; +import { CanisterMethodInfo } from '../types/canister_method_info'; import { executeMethod } from '../execute_method'; export function init< diff --git a/src/lib/canister_methods/methods/inspect_message.ts b/src/lib/canister_methods/methods/inspect_message.ts index 1ef07a6fec..5635e99e24 100644 --- a/src/lib/canister_methods/methods/inspect_message.ts +++ b/src/lib/canister_methods/methods/inspect_message.ts @@ -1,5 +1,5 @@ import { Void } from '../../candid/types/primitive/void'; -import { CanisterMethodInfo } from '../canister_method_info'; +import { CanisterMethodInfo } from '../types/canister_method_info'; import { executeMethod } from '../execute_method'; export function inspectMessage( diff --git a/src/lib/canister_methods/methods/post_upgrade.ts b/src/lib/canister_methods/methods/post_upgrade.ts index 05a2c05ee5..dbaebe98ce 100644 --- a/src/lib/canister_methods/methods/post_upgrade.ts +++ b/src/lib/canister_methods/methods/post_upgrade.ts @@ -1,7 +1,7 @@ import { CandidType, TypeMapping } from '../../candid'; import { Void } from '../../candid/types/primitive/void'; -import { Callback } from '../callback'; -import { CanisterMethodInfo } from '../canister_method_info'; +import { Callback } from '../types/callback'; +import { CanisterMethodInfo } from '../types/canister_method_info'; import { executeMethod } from '../execute_method'; export function postUpgrade< diff --git a/src/lib/canister_methods/methods/pre_upgrade.ts b/src/lib/canister_methods/methods/pre_upgrade.ts index 0058e78140..d94132777c 100644 --- a/src/lib/canister_methods/methods/pre_upgrade.ts +++ b/src/lib/canister_methods/methods/pre_upgrade.ts @@ -1,5 +1,5 @@ import { Void } from '../../candid/types/primitive/void'; -import { CanisterMethodInfo } from '../canister_method_info'; +import { CanisterMethodInfo } from '../types/canister_method_info'; import { isAsync } from '../is_async'; export function preUpgrade( diff --git a/src/lib/canister_methods/methods/query.ts b/src/lib/canister_methods/methods/query.ts index 77ce083de6..94e092ef91 100644 --- a/src/lib/canister_methods/methods/query.ts +++ b/src/lib/canister_methods/methods/query.ts @@ -1,9 +1,9 @@ import { CandidType, TypeMapping } from '../../candid'; -import { Callback } from '../callback'; -import { CanisterMethodInfo } from '../canister_method_info'; +import { Callback } from '../types/callback'; +import { CanisterMethodInfo } from '../types/canister_method_info'; import { executeMethod } from '../execute_method'; import { isAsync } from '../is_async'; -import { MethodArgs } from '../method_args'; +import { MethodArgs } from '../types/method_args'; export function query< const Params extends ReadonlyArray, diff --git a/src/lib/canister_methods/methods/update.ts b/src/lib/canister_methods/methods/update.ts index 3322bfc6f5..4582bd11d1 100644 --- a/src/lib/canister_methods/methods/update.ts +++ b/src/lib/canister_methods/methods/update.ts @@ -1,9 +1,9 @@ import { CandidType, TypeMapping } from '../../candid'; -import { Callback } from '../callback'; -import { CanisterMethodInfo } from '../canister_method_info'; +import { Callback } from '../types/callback'; +import { CanisterMethodInfo } from '../types/canister_method_info'; import { executeMethod } from '../execute_method'; import { isAsync } from '../is_async'; -import { MethodArgs } from '../method_args'; +import { MethodArgs } from '../types/method_args'; export function update< const Params extends ReadonlyArray, diff --git a/src/lib/canister_methods/callback.ts b/src/lib/canister_methods/types/callback.ts similarity index 79% rename from src/lib/canister_methods/callback.ts rename to src/lib/canister_methods/types/callback.ts index 4e3a14d501..4803c5fce2 100644 --- a/src/lib/canister_methods/callback.ts +++ b/src/lib/canister_methods/types/callback.ts @@ -1,4 +1,4 @@ -import { CandidType, TypeMapping } from '../candid'; +import { CandidType, TypeMapping } from '../../candid'; export type Callback< Params extends ReadonlyArray, diff --git a/src/lib/canister_methods/canister_method_info.ts b/src/lib/canister_methods/types/canister_method_info.ts similarity index 100% rename from src/lib/canister_methods/canister_method_info.ts rename to src/lib/canister_methods/types/canister_method_info.ts diff --git a/src/lib/canister_methods/types/index.ts b/src/lib/canister_methods/types/index.ts new file mode 100644 index 0000000000..9fe2b3c96f --- /dev/null +++ b/src/lib/canister_methods/types/index.ts @@ -0,0 +1,3 @@ +export * from './callback'; +export * from './canister_method_info'; +export * from './method_args'; diff --git a/src/lib/canister_methods/method_args.ts b/src/lib/canister_methods/types/method_args.ts similarity index 100% rename from src/lib/canister_methods/method_args.ts rename to src/lib/canister_methods/types/method_args.ts diff --git a/src/lib/ic/call_raw.ts b/src/lib/ic/call_raw.ts index 78555ffa6c..952f834338 100644 --- a/src/lib/ic/call_raw.ts +++ b/src/lib/ic/call_raw.ts @@ -1,4 +1,3 @@ -import { IDL } from '@dfinity/candid'; import { Principal } from '@dfinity/principal'; import { blob } from '../candid/types/constructed/blob'; import { nat64 } from '../candid/types/primitive/nats/nat64'; diff --git a/src/lib/ic/call_raw_128.ts b/src/lib/ic/call_raw_128.ts index 5c4d4bc778..3c21d0410f 100644 --- a/src/lib/ic/call_raw_128.ts +++ b/src/lib/ic/call_raw_128.ts @@ -1,4 +1,3 @@ -import { IDL } from '@dfinity/candid'; import { Principal } from '@dfinity/principal'; import { blob } from '../candid/types/constructed/blob'; import { nat } from '../candid/types/primitive/nats/nat'; diff --git a/src/lib/ic/clear_timer.ts b/src/lib/ic/clear_timer.ts index ea7f7e6da5..5862d841ba 100644 --- a/src/lib/ic/clear_timer.ts +++ b/src/lib/ic/clear_timer.ts @@ -1,4 +1,3 @@ -import { IDL } from '@dfinity/candid'; import { Void } from '../candid/types/primitive/void'; import { TimerId } from './types'; import { encode } from '../candid/serde'; From a5a9640f41363725278776d38dfcbeefa8caf5d3 Mon Sep 17 00:00:00 2001 From: Benjamin DeMann Date: Wed, 18 Oct 2023 16:20:43 -0600 Subject: [PATCH 34/36] fix type error --- src/lib/ic/trap.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/ic/trap.ts b/src/lib/ic/trap.ts index 81f76380e8..ad12df7102 100644 --- a/src/lib/ic/trap.ts +++ b/src/lib/ic/trap.ts @@ -11,5 +11,5 @@ export function trap(message: text): empty { return undefined as never; } - globalThis._azleIc.trap(message); + return globalThis._azleIc.trap(message); } From e3cc7874182faa547383761845561289bb987438 Mon Sep 17 00:00:00 2001 From: Benjamin DeMann Date: Wed, 18 Oct 2023 16:38:08 -0600 Subject: [PATCH 35/36] update imports to be direct --- src/lib/candid/did_file/visitor/visit/func.ts | 2 +- src/lib/candid/did_file/visitor/visit/opt.ts | 2 +- src/lib/candid/did_file/visitor/visit/primitive.ts | 2 +- src/lib/candid/did_file/visitor/visit/record.ts | 2 +- src/lib/candid/did_file/visitor/visit/recursive.ts | 2 +- src/lib/candid/did_file/visitor/visit/service.ts | 7 ++++++- src/lib/candid/did_file/visitor/visit/tuple.ts | 2 +- src/lib/candid/did_file/visitor/visit/variant.ts | 2 +- src/lib/candid/did_file/visitor/visit/vec.ts | 2 +- src/lib/candid/to_idl.ts | 2 +- src/lib/candid/type_mapping.ts | 2 +- src/lib/candid/types/constructed/opt.ts | 3 ++- src/lib/candid/types/constructed/record.ts | 4 +++- src/lib/candid/types/constructed/to_idl_map.ts | 3 ++- src/lib/candid/types/constructed/tuple.ts | 4 ++-- src/lib/candid/types/constructed/variant.ts | 3 ++- src/lib/candid/types/constructed/vec.ts | 4 ++-- src/lib/canister_methods/execute_method.ts | 5 +++-- src/lib/canister_methods/methods/init.ts | 3 ++- src/lib/canister_methods/methods/post_upgrade.ts | 3 ++- src/lib/canister_methods/methods/query.ts | 3 ++- src/lib/canister_methods/methods/update.ts | 3 ++- src/lib/canister_methods/types/callback.ts | 3 ++- src/lib/ic/call.ts | 3 ++- src/lib/ic/call_raw.ts | 2 +- src/lib/ic/call_raw_128.ts | 2 +- src/lib/ic/canister_balance.ts | 2 +- src/lib/ic/canister_balance_128.ts | 2 +- src/lib/ic/canister_version.ts | 2 +- src/lib/ic/clear_timer.ts | 4 ++-- src/lib/ic/instruction_counter.ts | 2 +- src/lib/ic/msg_cycles_accept.ts | 3 ++- src/lib/ic/msg_cycles_accept_128.ts | 3 ++- src/lib/ic/msg_cycles_available.ts | 2 +- src/lib/ic/msg_cycles_available_128.ts | 2 +- src/lib/ic/msg_cycles_refunded.ts | 2 +- src/lib/ic/msg_cycles_refunded_128.ts | 2 +- src/lib/ic/notify.ts | 2 +- src/lib/ic/notify_raw.ts | 5 +++-- src/lib/ic/performance_counter.ts | 3 ++- src/lib/ic/reply.ts | 4 ++-- src/lib/ic/set_certified_data.ts | 2 +- src/lib/ic/set_timer.ts | 6 ++++-- src/lib/ic/set_timer_interval.ts | 6 ++++-- src/lib/ic/stable_64_grow.ts | 3 ++- src/lib/ic/stable_64_read.ts | 2 +- src/lib/ic/stable_64_size.ts | 2 +- src/lib/ic/stable_64_write.ts | 2 +- src/lib/ic/stable_grow.ts | 3 ++- src/lib/ic/stable_read.ts | 2 +- src/lib/ic/stable_size.ts | 2 +- src/lib/ic/stable_write.ts | 2 +- src/lib/ic/time.ts | 2 +- src/lib/stable_b_tree_map.ts | 3 ++- src/lib/system_types/result.ts | 3 ++- 55 files changed, 92 insertions(+), 63 deletions(-) diff --git a/src/lib/candid/did_file/visitor/visit/func.ts b/src/lib/candid/did_file/visitor/visit/func.ts index 404d7375ac..328f9e1a5c 100644 --- a/src/lib/candid/did_file/visitor/visit/func.ts +++ b/src/lib/candid/did_file/visitor/visit/func.ts @@ -1,6 +1,6 @@ import { IDL } from '@dfinity/candid'; -import { DidVisitor, VisitorData, VisitorResult } from '..'; import { extractCandid } from '../extract_candid'; +import { DidVisitor, VisitorData, VisitorResult } from '../did_visitor'; export function visitFunc( t: IDL.FuncClass, diff --git a/src/lib/candid/did_file/visitor/visit/opt.ts b/src/lib/candid/did_file/visitor/visit/opt.ts index ed97ff872c..d00a005de8 100644 --- a/src/lib/candid/did_file/visitor/visit/opt.ts +++ b/src/lib/candid/did_file/visitor/visit/opt.ts @@ -1,5 +1,5 @@ import { IDL } from '@dfinity/candid'; -import { DidVisitor, VisitorData, VisitorResult } from '..'; +import { DidVisitor, VisitorData, VisitorResult } from '../did_visitor'; export function visitOpt( ty: IDL.Type, diff --git a/src/lib/candid/did_file/visitor/visit/primitive.ts b/src/lib/candid/did_file/visitor/visit/primitive.ts index 9d7e92595a..f257b9ced2 100644 --- a/src/lib/candid/did_file/visitor/visit/primitive.ts +++ b/src/lib/candid/did_file/visitor/visit/primitive.ts @@ -1,5 +1,5 @@ import { IDL } from '@dfinity/candid'; -import { VisitorResult } from '..'; +import { VisitorResult } from '../did_visitor'; export function visitPrimitive(t: IDL.PrimitiveType): VisitorResult { return [t.display(), {}]; diff --git a/src/lib/candid/did_file/visitor/visit/record.ts b/src/lib/candid/did_file/visitor/visit/record.ts index afff050dba..066ab942fe 100644 --- a/src/lib/candid/did_file/visitor/visit/record.ts +++ b/src/lib/candid/did_file/visitor/visit/record.ts @@ -1,5 +1,5 @@ import { IDL } from '@dfinity/candid'; -import { DidVisitor, VisitorData, VisitorResult } from '..'; +import { DidVisitor, VisitorData, VisitorResult } from '../did_visitor'; import { escapeCandidKeywords } from '../escape_candid_keywords'; import { extractCandid } from '../extract_candid'; diff --git a/src/lib/candid/did_file/visitor/visit/recursive.ts b/src/lib/candid/did_file/visitor/visit/recursive.ts index fc90b32b65..d28fc1162e 100644 --- a/src/lib/candid/did_file/visitor/visit/recursive.ts +++ b/src/lib/candid/did_file/visitor/visit/recursive.ts @@ -1,5 +1,5 @@ import { IDL } from '@dfinity/candid'; -import { DidVisitor, VisitorData, VisitorResult } from '..'; +import { DidVisitor, VisitorData, VisitorResult } from '../did_visitor'; export function visitRecursive( t: IDL.RecClass, diff --git a/src/lib/candid/did_file/visitor/visit/service.ts b/src/lib/candid/did_file/visitor/visit/service.ts index fbe1215a64..d1f9fb1a52 100644 --- a/src/lib/candid/did_file/visitor/visit/service.ts +++ b/src/lib/candid/did_file/visitor/visit/service.ts @@ -1,5 +1,10 @@ import { IDL } from '@dfinity/candid'; -import { CandidDef, CandidTypesDefs, DidVisitor, VisitorData } from '..'; +import { + CandidDef, + CandidTypesDefs, + DidVisitor, + VisitorData +} from '../did_visitor'; import { escapeCandidKeywords } from '../escape_candid_keywords'; import { extractCandid } from '../extract_candid'; diff --git a/src/lib/candid/did_file/visitor/visit/tuple.ts b/src/lib/candid/did_file/visitor/visit/tuple.ts index 7f6b475615..bcf284f291 100644 --- a/src/lib/candid/did_file/visitor/visit/tuple.ts +++ b/src/lib/candid/did_file/visitor/visit/tuple.ts @@ -1,5 +1,5 @@ import { IDL } from '@dfinity/candid'; -import { DidVisitor, VisitorData, VisitorResult } from '..'; +import { DidVisitor, VisitorData, VisitorResult } from '../did_visitor'; import { extractCandid } from '../extract_candid'; export function visitTuple( diff --git a/src/lib/candid/did_file/visitor/visit/variant.ts b/src/lib/candid/did_file/visitor/visit/variant.ts index e9a966396a..8abb824244 100644 --- a/src/lib/candid/did_file/visitor/visit/variant.ts +++ b/src/lib/candid/did_file/visitor/visit/variant.ts @@ -1,5 +1,5 @@ import { IDL } from '@dfinity/candid'; -import { DidVisitor, VisitorData, VisitorResult } from '..'; +import { DidVisitor, VisitorData, VisitorResult } from '../did_visitor'; import { escapeCandidKeywords } from '../escape_candid_keywords'; import { extractCandid } from '../extract_candid'; diff --git a/src/lib/candid/did_file/visitor/visit/vec.ts b/src/lib/candid/did_file/visitor/visit/vec.ts index fff1f8b01d..34b9ef3020 100644 --- a/src/lib/candid/did_file/visitor/visit/vec.ts +++ b/src/lib/candid/did_file/visitor/visit/vec.ts @@ -1,5 +1,5 @@ import { IDL } from '@dfinity/candid'; -import { DidVisitor, VisitorData, VisitorResult } from '..'; +import { DidVisitor, VisitorData, VisitorResult } from '../did_visitor'; export function visitVec( ty: IDL.Type, diff --git a/src/lib/candid/to_idl.ts b/src/lib/candid/to_idl.ts index a6e62e1ba6..a61e01d0dc 100644 --- a/src/lib/candid/to_idl.ts +++ b/src/lib/candid/to_idl.ts @@ -1,5 +1,5 @@ import { IDL } from '@dfinity/candid'; -import { CandidType } from '.'; +import { CandidType } from './candid_type'; export type Parent = { idl: IDL.RecClass; diff --git a/src/lib/candid/type_mapping.ts b/src/lib/candid/type_mapping.ts index 96cf0491a9..7d0eff9d08 100644 --- a/src/lib/candid/type_mapping.ts +++ b/src/lib/candid/type_mapping.ts @@ -21,7 +21,7 @@ import { AzleNat16, nat16 } from './types/primitive/nats/nat16'; import { AzleNat32, nat32 } from './types/primitive/nats/nat32'; import { AzleNat64, nat64 } from './types/primitive/nats/nat64'; import { AzleResult, Result } from '../system_types'; -import { Principal } from './types/reference'; +import { Principal } from './types/reference/principal'; export type TypeMapping = RecursionLevel extends 10 ? T diff --git a/src/lib/candid/types/constructed/opt.ts b/src/lib/candid/types/constructed/opt.ts index e398d01003..567599d642 100644 --- a/src/lib/candid/types/constructed/opt.ts +++ b/src/lib/candid/types/constructed/opt.ts @@ -1,4 +1,5 @@ -import { CandidType, Parent, toIdl } from '../../index'; +import { CandidType } from '../../candid_type'; +import { Parent, toIdl } from '../../to_idl'; import { RequireExactlyOne } from './variant'; import { IDL } from '@dfinity/candid'; diff --git a/src/lib/candid/types/constructed/record.ts b/src/lib/candid/types/constructed/record.ts index 71ed42f160..1d329fd150 100644 --- a/src/lib/candid/types/constructed/record.ts +++ b/src/lib/candid/types/constructed/record.ts @@ -1,6 +1,8 @@ -import { CandidType, TypeMapping, Parent } from '../../index'; import { IDL } from '@dfinity/candid'; import { toIdlMap, CandidMap } from './to_idl_map'; +import { CandidType } from '../../candid_type'; +import { TypeMapping } from '../../type_mapping'; +import { Parent } from '../../to_idl'; export function Record< T extends { diff --git a/src/lib/candid/types/constructed/to_idl_map.ts b/src/lib/candid/types/constructed/to_idl_map.ts index 0e26e062f6..0384ca1882 100644 --- a/src/lib/candid/types/constructed/to_idl_map.ts +++ b/src/lib/candid/types/constructed/to_idl_map.ts @@ -1,5 +1,6 @@ -import { CandidType, Parent, toIdl } from '../../index'; import { IDL } from '@dfinity/candid'; +import { CandidType } from '../../candid_type'; +import { Parent, toIdl } from '../../to_idl'; export type CandidMap = { [key: string]: CandidType }; export type IdlMap = { [key: string]: IDL.Type }; diff --git a/src/lib/candid/types/constructed/tuple.ts b/src/lib/candid/types/constructed/tuple.ts index ae1cb84584..22fae3a773 100644 --- a/src/lib/candid/types/constructed/tuple.ts +++ b/src/lib/candid/types/constructed/tuple.ts @@ -1,5 +1,5 @@ -import { CandidType } from '../../index'; -import { Parent, toIdl } from '../../index'; +import { CandidType } from '../../candid_type'; +import { Parent, toIdl } from '../../to_idl'; import { IDL } from '@dfinity/candid'; export class AzleTuple { diff --git a/src/lib/candid/types/constructed/variant.ts b/src/lib/candid/types/constructed/variant.ts index 5a7e06b84f..6fd56ddfd4 100644 --- a/src/lib/candid/types/constructed/variant.ts +++ b/src/lib/candid/types/constructed/variant.ts @@ -1,4 +1,5 @@ -import { CandidType, TypeMapping } from '../..'; +import { CandidType } from '../../candid_type'; +import { TypeMapping } from '../../type_mapping'; import { toIdlMap, CandidMap } from './to_idl_map'; import { IDL } from '@dfinity/candid'; diff --git a/src/lib/candid/types/constructed/vec.ts b/src/lib/candid/types/constructed/vec.ts index df0adfd809..c579336598 100644 --- a/src/lib/candid/types/constructed/vec.ts +++ b/src/lib/candid/types/constructed/vec.ts @@ -1,5 +1,5 @@ -import { CandidType } from '../../index'; -import { Parent, toIdl } from '../../index'; +import { CandidType } from '../../candid_type'; +import { Parent, toIdl } from '../../to_idl'; import { IDL } from '@dfinity/candid'; export class AzleVec { diff --git a/src/lib/canister_methods/execute_method.ts b/src/lib/canister_methods/execute_method.ts index a575d54a01..1fe935b234 100644 --- a/src/lib/canister_methods/execute_method.ts +++ b/src/lib/canister_methods/execute_method.ts @@ -1,6 +1,7 @@ import { ic } from '../ic'; -import { CandidType, TypeMapping } from '../candid'; -import { decode, encode } from '../candid/serde'; +import { CandidType } from '../candid/candid_type'; +import { decode } from '../candid/serde/decode'; +import { encode } from '../candid/serde/encode'; import { CanisterMethodInfo } from './types/canister_method_info'; export function executeMethod( diff --git a/src/lib/canister_methods/methods/init.ts b/src/lib/canister_methods/methods/init.ts index aa977b1b2c..eb6bdef8c8 100644 --- a/src/lib/canister_methods/methods/init.ts +++ b/src/lib/canister_methods/methods/init.ts @@ -1,4 +1,5 @@ -import { CandidType, TypeMapping } from '../../candid'; +import { CandidType } from '../../candid/candid_type'; +import { TypeMapping } from '../../candid/type_mapping'; import { Void } from '../../candid/types/primitive/void'; import { Callback } from '../types/callback'; import { CanisterMethodInfo } from '../types/canister_method_info'; diff --git a/src/lib/canister_methods/methods/post_upgrade.ts b/src/lib/canister_methods/methods/post_upgrade.ts index dbaebe98ce..a8d0bcf0be 100644 --- a/src/lib/canister_methods/methods/post_upgrade.ts +++ b/src/lib/canister_methods/methods/post_upgrade.ts @@ -1,4 +1,5 @@ -import { CandidType, TypeMapping } from '../../candid'; +import { CandidType } from '../../candid/candid_type'; +import { TypeMapping } from '../../candid/type_mapping'; import { Void } from '../../candid/types/primitive/void'; import { Callback } from '../types/callback'; import { CanisterMethodInfo } from '../types/canister_method_info'; diff --git a/src/lib/canister_methods/methods/query.ts b/src/lib/canister_methods/methods/query.ts index 94e092ef91..8b7b0ffb98 100644 --- a/src/lib/canister_methods/methods/query.ts +++ b/src/lib/canister_methods/methods/query.ts @@ -1,4 +1,5 @@ -import { CandidType, TypeMapping } from '../../candid'; +import { CandidType } from '../../candid/candid_type'; +import { TypeMapping } from '../../candid/type_mapping'; import { Callback } from '../types/callback'; import { CanisterMethodInfo } from '../types/canister_method_info'; import { executeMethod } from '../execute_method'; diff --git a/src/lib/canister_methods/methods/update.ts b/src/lib/canister_methods/methods/update.ts index 4582bd11d1..6de16af599 100644 --- a/src/lib/canister_methods/methods/update.ts +++ b/src/lib/canister_methods/methods/update.ts @@ -1,4 +1,5 @@ -import { CandidType, TypeMapping } from '../../candid'; +import { CandidType } from '../../candid/candid_type'; +import { TypeMapping } from '../../candid/type_mapping'; import { Callback } from '../types/callback'; import { CanisterMethodInfo } from '../types/canister_method_info'; import { executeMethod } from '../execute_method'; diff --git a/src/lib/canister_methods/types/callback.ts b/src/lib/canister_methods/types/callback.ts index 4803c5fce2..037a1e0918 100644 --- a/src/lib/canister_methods/types/callback.ts +++ b/src/lib/canister_methods/types/callback.ts @@ -1,4 +1,5 @@ -import { CandidType, TypeMapping } from '../../candid'; +import { CandidType } from '../../candid/candid_type'; +import { TypeMapping } from '../../candid/type_mapping'; export type Callback< Params extends ReadonlyArray, diff --git a/src/lib/ic/call.ts b/src/lib/ic/call.ts index 05087f0c0d..e097668c33 100644 --- a/src/lib/ic/call.ts +++ b/src/lib/ic/call.ts @@ -2,7 +2,8 @@ import { nat } from '../candid/types/primitive/nats/nat'; import { nat64 } from '../candid/types/primitive/nats/nat64'; import { callRaw } from './call_raw'; import { callRaw128 } from './call_raw_128'; -import { ArgsType, ReturnTypeOf } from './types'; +import { ArgsType } from './types/args_type'; +import { ReturnTypeOf } from './types/return_type_of'; /** * Performs an asynchronous call to another canister. diff --git a/src/lib/ic/call_raw.ts b/src/lib/ic/call_raw.ts index 952f834338..f9ef9b0730 100644 --- a/src/lib/ic/call_raw.ts +++ b/src/lib/ic/call_raw.ts @@ -3,7 +3,7 @@ import { blob } from '../candid/types/constructed/blob'; import { nat64 } from '../candid/types/primitive/nats/nat64'; import { v4 } from 'uuid'; import { text } from '../candid/types/primitive/text'; -import { encode } from '../candid/serde'; +import { encode } from '../candid/serde/encode'; /** * Performs an asynchronous call to another canister using the [System API]( diff --git a/src/lib/ic/call_raw_128.ts b/src/lib/ic/call_raw_128.ts index 3c21d0410f..70147fe42b 100644 --- a/src/lib/ic/call_raw_128.ts +++ b/src/lib/ic/call_raw_128.ts @@ -3,7 +3,7 @@ import { blob } from '../candid/types/constructed/blob'; import { nat } from '../candid/types/primitive/nats/nat'; import { v4 } from 'uuid'; import { text } from '../candid/types/primitive/text'; -import { encode } from '../candid/serde'; +import { encode } from '../candid/serde/encode'; /** * Performs an asynchronous call to another canister using the [System API]( diff --git a/src/lib/ic/canister_balance.ts b/src/lib/ic/canister_balance.ts index 69323f1dea..f8a6902996 100644 --- a/src/lib/ic/canister_balance.ts +++ b/src/lib/ic/canister_balance.ts @@ -1,5 +1,5 @@ import { nat64 } from '../candid/types/primitive/nats/nat64'; -import { decode } from '../candid/serde'; +import { decode } from '../candid/serde/decode'; /** * Gets the amount of funds available in the canister diff --git a/src/lib/ic/canister_balance_128.ts b/src/lib/ic/canister_balance_128.ts index 15534dd70f..cfa2f489f4 100644 --- a/src/lib/ic/canister_balance_128.ts +++ b/src/lib/ic/canister_balance_128.ts @@ -1,5 +1,5 @@ import { nat } from '../candid/types/primitive/nats/nat'; -import { decode } from '../candid/serde'; +import { decode } from '../candid/serde/decode'; /** * Gets the amount of funds available in the canister diff --git a/src/lib/ic/canister_version.ts b/src/lib/ic/canister_version.ts index 8c00845ef5..239d91485a 100644 --- a/src/lib/ic/canister_version.ts +++ b/src/lib/ic/canister_version.ts @@ -1,5 +1,5 @@ import { nat64 } from '../candid/types/primitive/nats/nat64'; -import { decode } from '../candid/serde'; +import { decode } from '../candid/serde/decode'; /** * Returns the canister version number diff --git a/src/lib/ic/clear_timer.ts b/src/lib/ic/clear_timer.ts index 5862d841ba..1423ca8a4a 100644 --- a/src/lib/ic/clear_timer.ts +++ b/src/lib/ic/clear_timer.ts @@ -1,6 +1,6 @@ import { Void } from '../candid/types/primitive/void'; -import { TimerId } from './types'; -import { encode } from '../candid/serde'; +import { TimerId } from './types/timer_id'; +import { encode } from '../candid/serde/encode'; /** * Cancels an existing timer. Does nothing if the timer has already been canceled. diff --git a/src/lib/ic/instruction_counter.ts b/src/lib/ic/instruction_counter.ts index c647e7ca9d..38ff196575 100644 --- a/src/lib/ic/instruction_counter.ts +++ b/src/lib/ic/instruction_counter.ts @@ -1,5 +1,5 @@ import { nat64 } from '../candid/types/primitive/nats/nat64'; -import { decode } from '../candid/serde'; +import { decode } from '../candid/serde/decode'; /** * Returns the number of instructions that the canister executed since the diff --git a/src/lib/ic/msg_cycles_accept.ts b/src/lib/ic/msg_cycles_accept.ts index c65ba46dff..c70bac862a 100644 --- a/src/lib/ic/msg_cycles_accept.ts +++ b/src/lib/ic/msg_cycles_accept.ts @@ -1,5 +1,6 @@ import { nat64 } from '../candid/types/primitive/nats/nat64'; -import { decode, encode } from '../candid/serde'; +import { decode } from '../candid/serde/decode'; +import { encode } from '../candid/serde/encode'; /** * Moves cycles from the call to the canister balance diff --git a/src/lib/ic/msg_cycles_accept_128.ts b/src/lib/ic/msg_cycles_accept_128.ts index a35a5bc4c0..cb4a8e51d5 100644 --- a/src/lib/ic/msg_cycles_accept_128.ts +++ b/src/lib/ic/msg_cycles_accept_128.ts @@ -1,5 +1,6 @@ import { nat } from '../candid/types/primitive/nats/nat'; -import { decode, encode } from '../candid/serde'; +import { decode } from '../candid/serde/decode'; +import { encode } from '../candid/serde/encode'; /** * Moves cycles from the call to the canister balance diff --git a/src/lib/ic/msg_cycles_available.ts b/src/lib/ic/msg_cycles_available.ts index 3a941dccef..3510d6738d 100644 --- a/src/lib/ic/msg_cycles_available.ts +++ b/src/lib/ic/msg_cycles_available.ts @@ -1,5 +1,5 @@ import { nat64 } from '../candid/types/primitive/nats/nat64'; -import { decode } from '../candid/serde'; +import { decode } from '../candid/serde/decode'; /** * Returns the amount of cycles that were transferred by the caller of the diff --git a/src/lib/ic/msg_cycles_available_128.ts b/src/lib/ic/msg_cycles_available_128.ts index ba30d3986c..403e6f37e1 100644 --- a/src/lib/ic/msg_cycles_available_128.ts +++ b/src/lib/ic/msg_cycles_available_128.ts @@ -1,5 +1,5 @@ import { nat } from '../candid/types/primitive/nats/nat'; -import { decode } from '../candid/serde'; +import { decode } from '../candid/serde/decode'; /** * Returns the amount of cycles that were transferred by the caller of the diff --git a/src/lib/ic/msg_cycles_refunded.ts b/src/lib/ic/msg_cycles_refunded.ts index 85099ee685..12eae3c241 100644 --- a/src/lib/ic/msg_cycles_refunded.ts +++ b/src/lib/ic/msg_cycles_refunded.ts @@ -1,5 +1,5 @@ import { nat64 } from '../candid/types/primitive/nats/nat64'; -import { decode } from '../candid/serde'; +import { decode } from '../candid/serde/decode'; /** * Returns the amount of cycles that came back with the response as a refund. diff --git a/src/lib/ic/msg_cycles_refunded_128.ts b/src/lib/ic/msg_cycles_refunded_128.ts index 1d541b3fc9..72bc36583b 100644 --- a/src/lib/ic/msg_cycles_refunded_128.ts +++ b/src/lib/ic/msg_cycles_refunded_128.ts @@ -1,5 +1,5 @@ import { nat } from '../candid/types/primitive/nats/nat'; -import { decode } from '../candid/serde'; +import { decode } from '../candid/serde/decode'; /** * Returns the amount of cycles that came back with the response as a refund. diff --git a/src/lib/ic/notify.ts b/src/lib/ic/notify.ts index d93cfd8216..9f37f23c29 100644 --- a/src/lib/ic/notify.ts +++ b/src/lib/ic/notify.ts @@ -1,7 +1,7 @@ import { nat } from '../candid/types/primitive/nats/nat'; import { Void } from '../candid/types/primitive/void'; import { notifyRaw } from './notify_raw'; -import { ArgsType } from './types'; +import { ArgsType } from './types/args_type'; /** * Sends a one-way message with payment cycles attached to it that invokes diff --git a/src/lib/ic/notify_raw.ts b/src/lib/ic/notify_raw.ts index 65615de609..87cba4f21d 100644 --- a/src/lib/ic/notify_raw.ts +++ b/src/lib/ic/notify_raw.ts @@ -1,8 +1,9 @@ import { Void } from '../candid/types/primitive/void'; import { nat } from '../candid/types/primitive/nats/nat'; import { blob } from '../candid/types/constructed/blob'; -import { Principal, text } from '../candid'; -import { encode } from '../candid/serde'; +import { encode } from '../candid/serde/encode'; +import { Principal } from '../candid/types/reference/principal'; +import { text } from '../candid/types/primitive/text'; /** * Like notify, but sends the argument as raw bytes, skipping Candid serialization. diff --git a/src/lib/ic/performance_counter.ts b/src/lib/ic/performance_counter.ts index 6dafb8877e..fe7edb9637 100644 --- a/src/lib/ic/performance_counter.ts +++ b/src/lib/ic/performance_counter.ts @@ -1,6 +1,7 @@ import { nat32 } from '../candid/types/primitive/nats/nat32'; import { nat64 } from '../candid/types/primitive/nats/nat64'; -import { decode, encode } from '../candid/serde'; +import { decode } from '../candid/serde/decode'; +import { encode } from '../candid/serde/encode'; /** * Gets the value of the specified performance counter diff --git a/src/lib/ic/reply.ts b/src/lib/ic/reply.ts index 2c9873d33e..8875e64bed 100644 --- a/src/lib/ic/reply.ts +++ b/src/lib/ic/reply.ts @@ -1,6 +1,6 @@ -import { CandidType } from '../candid'; +import { CandidType } from '../candid/candid_type'; import { Void } from '../candid/types/primitive/void'; -import { encode } from '../candid/serde'; +import { encode } from '../candid/serde/encode'; /** * Used to manually reply to an ingress message. Intended to be used in diff --git a/src/lib/ic/set_certified_data.ts b/src/lib/ic/set_certified_data.ts index 2472fbc66d..fa0ae50a0d 100644 --- a/src/lib/ic/set_certified_data.ts +++ b/src/lib/ic/set_certified_data.ts @@ -1,6 +1,6 @@ import { blob } from '../candid/types/constructed/blob'; import { Void } from '../candid/types/primitive/void'; -import { encode } from '../candid/serde'; +import { encode } from '../candid/serde/encode'; /** * Sets the certified data of this canister. diff --git a/src/lib/ic/set_timer.ts b/src/lib/ic/set_timer.ts index 18bbcf0371..669f0cdcb0 100644 --- a/src/lib/ic/set_timer.ts +++ b/src/lib/ic/set_timer.ts @@ -1,7 +1,9 @@ -import { Duration, TimerId } from './types'; +import { Duration } from './types/duration'; +import { TimerId } from './types/timer_id'; import { v4 } from 'uuid'; import { nat64 } from '../candid/types/primitive/nats/nat64'; -import { encode, decode } from '../candid/serde'; +import { decode } from '../candid/serde/decode'; +import { encode } from '../candid/serde/encode'; /** * Sets callback to be executed later, after delay. Panics if `delay` + time() is more than 2^64 - 1. diff --git a/src/lib/ic/set_timer_interval.ts b/src/lib/ic/set_timer_interval.ts index 03e3299dc8..809e1c5e10 100644 --- a/src/lib/ic/set_timer_interval.ts +++ b/src/lib/ic/set_timer_interval.ts @@ -1,6 +1,8 @@ -import { Duration, TimerId } from './types'; +import { Duration } from './types/duration'; +import { TimerId } from './types/timer_id'; import { v4 } from 'uuid'; -import { encode, decode } from '../candid/serde'; +import { decode } from '../candid/serde/decode'; +import { encode } from '../candid/serde/encode'; import { nat64 } from '../candid/types/primitive/nats/nat64'; /** diff --git a/src/lib/ic/stable_64_grow.ts b/src/lib/ic/stable_64_grow.ts index 8928536229..4542fa6868 100644 --- a/src/lib/ic/stable_64_grow.ts +++ b/src/lib/ic/stable_64_grow.ts @@ -1,5 +1,6 @@ import { nat64 } from '../candid/types/primitive/nats/nat64'; -import { decode, encode } from '../candid/serde'; +import { decode } from '../candid/serde/decode'; +import { encode } from '../candid/serde/encode'; /** * Attempts to grow the stable memory by `newPages`. diff --git a/src/lib/ic/stable_64_read.ts b/src/lib/ic/stable_64_read.ts index 84ec6b1529..1b38df0503 100644 --- a/src/lib/ic/stable_64_read.ts +++ b/src/lib/ic/stable_64_read.ts @@ -1,5 +1,5 @@ import { nat64 } from '../candid/types/primitive/nats/nat64'; -import { encode } from '../candid/serde'; +import { encode } from '../candid/serde/encode'; /** * Reads data from the stable memory location specified by an offset. diff --git a/src/lib/ic/stable_64_size.ts b/src/lib/ic/stable_64_size.ts index 01fd03cfa6..f12b3ac0ec 100644 --- a/src/lib/ic/stable_64_size.ts +++ b/src/lib/ic/stable_64_size.ts @@ -1,5 +1,5 @@ import { nat64 } from '../candid/types/primitive/nats/nat64'; -import { decode } from '../candid/serde'; +import { decode } from '../candid/serde/decode'; /** * Gets current size of the stable memory (in WASM pages). Supports 64-bit diff --git a/src/lib/ic/stable_64_write.ts b/src/lib/ic/stable_64_write.ts index 7dc63936bb..73eac9ef2e 100644 --- a/src/lib/ic/stable_64_write.ts +++ b/src/lib/ic/stable_64_write.ts @@ -1,6 +1,6 @@ import { blob } from '../candid/types/constructed/blob'; import { nat64 } from '../candid/types/primitive/nats/nat64'; -import { encode } from '../candid/serde'; +import { encode } from '../candid/serde/encode'; /** * Writes data to the stable memory location specified by an offset. diff --git a/src/lib/ic/stable_grow.ts b/src/lib/ic/stable_grow.ts index 6df0aeef70..553615d6dd 100644 --- a/src/lib/ic/stable_grow.ts +++ b/src/lib/ic/stable_grow.ts @@ -1,5 +1,6 @@ import { nat32 } from '../candid/types/primitive/nats/nat32'; -import { decode, encode } from '../candid/serde'; +import { decode } from '../candid/serde/decode'; +import { encode } from '../candid/serde/encode'; /** * Attempts to grow the stable memory by `newPages`. diff --git a/src/lib/ic/stable_read.ts b/src/lib/ic/stable_read.ts index 0dbf401a07..4de6a65882 100644 --- a/src/lib/ic/stable_read.ts +++ b/src/lib/ic/stable_read.ts @@ -1,5 +1,5 @@ import { nat32 } from '../candid/types/primitive/nats/nat32'; -import { encode } from '../candid/serde'; +import { encode } from '../candid/serde/encode'; /** * Reads data from the stable memory location specified by an offset diff --git a/src/lib/ic/stable_size.ts b/src/lib/ic/stable_size.ts index e44a7f4674..71cb1cae8e 100644 --- a/src/lib/ic/stable_size.ts +++ b/src/lib/ic/stable_size.ts @@ -1,5 +1,5 @@ import { nat32 } from '../candid/types/primitive/nats/nat32'; -import { decode } from '../candid/serde'; +import { decode } from '../candid/serde/decode'; /** * Gets current size of the stable memory (in WASM pages) diff --git a/src/lib/ic/stable_write.ts b/src/lib/ic/stable_write.ts index d43bcb329f..ae704011da 100644 --- a/src/lib/ic/stable_write.ts +++ b/src/lib/ic/stable_write.ts @@ -1,6 +1,6 @@ import { nat32 } from '../candid/types/primitive/nats/nat32'; import { blob } from '../candid/types/constructed/blob'; -import { encode } from '../candid/serde'; +import { encode } from '../candid/serde/encode'; /** * Writes data to the stable memory location specified by an offset diff --git a/src/lib/ic/time.ts b/src/lib/ic/time.ts index 7ded28a8c1..eca31f9252 100644 --- a/src/lib/ic/time.ts +++ b/src/lib/ic/time.ts @@ -1,5 +1,5 @@ import { nat64 } from '../candid/types/primitive/nats/nat64'; -import { decode } from '../candid/serde'; +import { decode } from '../candid/serde/decode'; /** * Gets current timestamp, in nanoseconds since the epoch (1970-01-01) diff --git a/src/lib/stable_b_tree_map.ts b/src/lib/stable_b_tree_map.ts index bd41ff57b1..a42f1227a2 100644 --- a/src/lib/stable_b_tree_map.ts +++ b/src/lib/stable_b_tree_map.ts @@ -1,4 +1,5 @@ -import { CandidType, TypeMapping } from './candid'; +import { CandidType } from './candid/candid_type'; +import { TypeMapping } from './candid/type_mapping'; import { None, Opt, Some } from './candid/types/constructed/opt'; import { nat64 } from './candid/types/primitive/nats/nat64'; import { nat8 } from './candid/types/primitive/nats/nat8'; diff --git a/src/lib/system_types/result.ts b/src/lib/system_types/result.ts index 73cf8f20cb..b6aa939631 100644 --- a/src/lib/system_types/result.ts +++ b/src/lib/system_types/result.ts @@ -1,4 +1,5 @@ -import { Parent, toIdl, CandidType } from '../candid'; +import { CandidType } from '../candid/candid_type'; +import { Parent, toIdl } from '../candid/to_idl'; import { RequireExactlyOne } from '../candid/types/constructed/variant'; import { IDL } from '@dfinity/candid'; From 27fb3e203b1ef226b21a329da9375686a2ea4189 Mon Sep 17 00:00:00 2001 From: Benjamin DeMann Date: Wed, 18 Oct 2023 16:47:55 -0600 Subject: [PATCH 36/36] organize encode/decode visitors --- .../candid/serde/visitors/decode_visitor.ts | 15 +- .../candid/serde/visitors/encode_visitor.ts | 15 +- src/lib/candid/serde/visitors/index.ts | 152 +----------------- src/lib/candid/serde/visitors/types.ts | 11 ++ src/lib/candid/serde/visitors/visit/record.ts | 25 +++ .../candid/serde/visitors/visit/recursive.ts | 19 +++ src/lib/candid/serde/visitors/visit/tuple.ts | 18 +++ .../visitors/visit/variant/azle_result.ts | 37 +++++ .../visitors/visit/variant/azle_variant.ts | 28 ++++ .../serde/visitors/visit/variant/index.ts | 18 +++ src/lib/candid/serde/visitors/visit/vec.ts | 20 +++ 11 files changed, 190 insertions(+), 168 deletions(-) create mode 100644 src/lib/candid/serde/visitors/types.ts create mode 100644 src/lib/candid/serde/visitors/visit/record.ts create mode 100644 src/lib/candid/serde/visitors/visit/recursive.ts create mode 100644 src/lib/candid/serde/visitors/visit/tuple.ts create mode 100644 src/lib/candid/serde/visitors/visit/variant/azle_result.ts create mode 100644 src/lib/candid/serde/visitors/visit/variant/azle_variant.ts create mode 100644 src/lib/candid/serde/visitors/visit/variant/index.ts create mode 100644 src/lib/candid/serde/visitors/visit/vec.ts diff --git a/src/lib/candid/serde/visitors/decode_visitor.ts b/src/lib/candid/serde/visitors/decode_visitor.ts index 4b9f3ce790..9da00466c5 100644 --- a/src/lib/candid/serde/visitors/decode_visitor.ts +++ b/src/lib/candid/serde/visitors/decode_visitor.ts @@ -1,14 +1,11 @@ import { IDL } from '@dfinity/candid'; -import { - VisitorData, - VisitorResult, - visitRec, - visitRecord, - visitTuple, - visitVariant, - visitVec -} from './index'; import { Opt } from '../../types/constructed'; +import { VisitorData, VisitorResult } from './types'; +import { visitRecord } from './visit/record'; +import { visitRec } from './visit/recursive'; +import { visitTuple } from './visit/tuple'; +import { visitVariant } from './visit/variant'; +import { visitVec } from './visit/vec'; /** * When we decode a Service we are given a principal. We need to use that diff --git a/src/lib/candid/serde/visitors/encode_visitor.ts b/src/lib/candid/serde/visitors/encode_visitor.ts index 8a4689fb77..70c38dc5a6 100644 --- a/src/lib/candid/serde/visitors/encode_visitor.ts +++ b/src/lib/candid/serde/visitors/encode_visitor.ts @@ -1,13 +1,10 @@ import { IDL } from '@dfinity/candid'; -import { - VisitorData, - VisitorResult, - visitRec, - visitRecord, - visitTuple, - visitVariant, - visitVec -} from './index'; +import { VisitorData, VisitorResult } from './types'; +import { visitTuple } from './visit/tuple'; +import { visitVec } from './visit/vec'; +import { visitRecord } from './visit/record'; +import { visitRec } from './visit/recursive'; +import { visitVariant } from './visit/variant'; /** * When we encode a Service we have a service class and we need it to be only diff --git a/src/lib/candid/serde/visitors/index.ts b/src/lib/candid/serde/visitors/index.ts index c7573cc3bc..5c8c9f712f 100644 --- a/src/lib/candid/serde/visitors/index.ts +++ b/src/lib/candid/serde/visitors/index.ts @@ -1,156 +1,8 @@ -import { IDL } from '@dfinity/candid'; -import { DecodeVisitor } from './decode_visitor'; -import { EncodeVisitor } from './encode_visitor'; -import { AzleResult, Result } from '../../../system_types/result'; -export { EncodeVisitor, DecodeVisitor }; - -/* - * The VisitorData gives us js_data which is the data that is about to be - * encoded or was just decoded. js_class is the CandidType that can be used to - * create the class. - */ -export type VisitorData = { js_data: any; candidType: any }; -/** - * The VisitorResult is the transformed version of js_data that is ready to - * be consumed by the js or ready to be encoded. - */ -export type VisitorResult = any; +export { DecodeVisitor } from './decode_visitor'; +export { EncodeVisitor } from './encode_visitor'; /* * For most of the visitors the only thing that needs to happen is to visit each * of the sub nodes. That is the same for both encoding and decoding. That logic * is extracted into these helper methods. */ - -export function visitTuple( - visitor: DecodeVisitor | EncodeVisitor, - components: IDL.Type[], - data: VisitorData -): VisitorResult { - const fields = components.map((value, index) => - value.accept(visitor, { - js_data: data.js_data[index], - candidType: data.candidType.innerTypes[index] - }) - ); - return [...fields]; -} - -export function visitVec( - visitor: DecodeVisitor | EncodeVisitor, - ty: IDL.Type, - data: VisitorData -): VisitorResult { - if (ty instanceof IDL.PrimitiveType) { - return data.js_data; - } - return data.js_data.map((array_elem: any) => { - return ty.accept(visitor, { - js_data: array_elem, - candidType: data.candidType.innerType - }); - }); -} - -export function visitRecord( - visitor: DecodeVisitor | EncodeVisitor, - fields: [string, IDL.Type][], - data: VisitorData -): VisitorResult { - const candidFields = fields.reduce((acc, [memberName, memberIdl]) => { - const fieldData = data.js_data[memberName]; - const fieldClass = data.candidType[memberName]; - - return { - ...acc, - [memberName]: memberIdl.accept(visitor, { - js_data: fieldData, - candidType: fieldClass - }) - }; - }, {}); - - return candidFields; -} - -export function visitVariant( - visitor: DecodeVisitor | EncodeVisitor, - fields: [string, IDL.Type][], - data: VisitorData -): VisitorResult { - if (data.candidType instanceof AzleResult) { - return visitAzleResult(visitor, fields, data); - } - return visitAzleVariant(visitor, fields, data); -} - -export function visitRec( - visitor: DecodeVisitor | EncodeVisitor, - ty: IDL.ConstructType, - data: VisitorData -): VisitorResult { - let candidType = data.candidType(); - if (candidType.isCanister) { - candidType = candidType([]); - } - return ty.accept(visitor, { - ...data, - candidType - }); -} - -function visitAzleResult( - visitor: DecodeVisitor | EncodeVisitor, - fields: [string, IDL.Type][], - data: VisitorData -) { - if ('Ok' in data.js_data) { - const OK_FIELD_INDEX = 0; - const okField = fields[OK_FIELD_INDEX]; - const okData = data.js_data['Ok']; - const okClass = data.candidType.Ok; - - return Result.Ok( - okField[1].accept(visitor, { - js_data: okData, - candidType: okClass - }) - ); - } - if ('Err' in data.js_data) { - const ERR_FIELD_INDEX = 1; - const errField = fields[ERR_FIELD_INDEX]; - const errData = data.js_data['Err']; - const errClass = data.candidType.Err; - return Result.Err( - errField[1].accept(visitor, { - js_data: errData, - candidType: errClass - }) - ); - } -} - -function visitAzleVariant( - visitor: DecodeVisitor | EncodeVisitor, - fields: [string, IDL.Type][], - data: VisitorData -) { - const candidFields = fields.reduce((acc, [memberName, memberIdl]) => { - const fieldData = data.js_data[memberName]; - const fieldClass = data.candidType[memberName]; - if (fieldData === undefined) { - // If the field data is undefined then it is not the variant that was used - return acc; - } - return { - ...acc, - [memberName]: memberIdl.accept(visitor, { - candidType: fieldClass, - js_data: fieldData - }) - }; - }, {}); - - return candidFields; -} diff --git a/src/lib/candid/serde/visitors/types.ts b/src/lib/candid/serde/visitors/types.ts new file mode 100644 index 0000000000..6ace27c5af --- /dev/null +++ b/src/lib/candid/serde/visitors/types.ts @@ -0,0 +1,11 @@ +/* + * The VisitorData gives us js_data which is the data that is about to be + * encoded or was just decoded. js_class is the CandidType that can be used to + * create the class. + */ +export type VisitorData = { js_data: any; candidType: any }; +/** + * The VisitorResult is the transformed version of js_data that is ready to + * be consumed by the js or ready to be encoded. + */ +export type VisitorResult = any; diff --git a/src/lib/candid/serde/visitors/visit/record.ts b/src/lib/candid/serde/visitors/visit/record.ts new file mode 100644 index 0000000000..641d29e05c --- /dev/null +++ b/src/lib/candid/serde/visitors/visit/record.ts @@ -0,0 +1,25 @@ +import { IDL } from '@dfinity/candid'; +import { EncodeVisitor } from '../encode_visitor'; +import { DecodeVisitor } from '../decode_visitor'; +import { VisitorData, VisitorResult } from '../types'; + +export function visitRecord( + visitor: DecodeVisitor | EncodeVisitor, + fields: [string, IDL.Type][], + data: VisitorData +): VisitorResult { + const candidFields = fields.reduce((acc, [memberName, memberIdl]) => { + const fieldData = data.js_data[memberName]; + const fieldClass = data.candidType[memberName]; + + return { + ...acc, + [memberName]: memberIdl.accept(visitor, { + js_data: fieldData, + candidType: fieldClass + }) + }; + }, {}); + + return candidFields; +} diff --git a/src/lib/candid/serde/visitors/visit/recursive.ts b/src/lib/candid/serde/visitors/visit/recursive.ts new file mode 100644 index 0000000000..bd15bbef7a --- /dev/null +++ b/src/lib/candid/serde/visitors/visit/recursive.ts @@ -0,0 +1,19 @@ +import { IDL } from '@dfinity/candid'; +import { EncodeVisitor } from '../encode_visitor'; +import { DecodeVisitor } from '../decode_visitor'; +import { VisitorData, VisitorResult } from '../types'; + +export function visitRec( + visitor: DecodeVisitor | EncodeVisitor, + ty: IDL.ConstructType, + data: VisitorData +): VisitorResult { + let candidType = data.candidType(); + if (candidType.isCanister) { + candidType = candidType([]); + } + return ty.accept(visitor, { + ...data, + candidType + }); +} diff --git a/src/lib/candid/serde/visitors/visit/tuple.ts b/src/lib/candid/serde/visitors/visit/tuple.ts new file mode 100644 index 0000000000..f899a89f8b --- /dev/null +++ b/src/lib/candid/serde/visitors/visit/tuple.ts @@ -0,0 +1,18 @@ +import { IDL } from '@dfinity/candid'; +import { EncodeVisitor } from '../encode_visitor'; +import { DecodeVisitor } from '../decode_visitor'; +import { VisitorData, VisitorResult } from '../types'; + +export function visitTuple( + visitor: DecodeVisitor | EncodeVisitor, + components: IDL.Type[], + data: VisitorData +): VisitorResult { + const fields = components.map((value, index) => + value.accept(visitor, { + js_data: data.js_data[index], + candidType: data.candidType.innerTypes[index] + }) + ); + return [...fields]; +} diff --git a/src/lib/candid/serde/visitors/visit/variant/azle_result.ts b/src/lib/candid/serde/visitors/visit/variant/azle_result.ts new file mode 100644 index 0000000000..186c94adca --- /dev/null +++ b/src/lib/candid/serde/visitors/visit/variant/azle_result.ts @@ -0,0 +1,37 @@ +import { IDL } from '@dfinity/candid'; +import { EncodeVisitor } from '../../encode_visitor'; +import { DecodeVisitor } from '../../decode_visitor'; +import { VisitorData } from '../../types'; +import { Result } from '../../../../../system_types/result'; + +export function visitAzleResult( + visitor: DecodeVisitor | EncodeVisitor, + fields: [string, IDL.Type][], + data: VisitorData +) { + if ('Ok' in data.js_data) { + const OK_FIELD_INDEX = 0; + const okField = fields[OK_FIELD_INDEX]; + const okData = data.js_data['Ok']; + const okClass = data.candidType.Ok; + + return Result.Ok( + okField[1].accept(visitor, { + js_data: okData, + candidType: okClass + }) + ); + } + if ('Err' in data.js_data) { + const ERR_FIELD_INDEX = 1; + const errField = fields[ERR_FIELD_INDEX]; + const errData = data.js_data['Err']; + const errClass = data.candidType.Err; + return Result.Err( + errField[1].accept(visitor, { + js_data: errData, + candidType: errClass + }) + ); + } +} diff --git a/src/lib/candid/serde/visitors/visit/variant/azle_variant.ts b/src/lib/candid/serde/visitors/visit/variant/azle_variant.ts new file mode 100644 index 0000000000..aa4ef196d1 --- /dev/null +++ b/src/lib/candid/serde/visitors/visit/variant/azle_variant.ts @@ -0,0 +1,28 @@ +import { IDL } from '@dfinity/candid'; +import { EncodeVisitor } from '../../encode_visitor'; +import { DecodeVisitor } from '../../decode_visitor'; +import { VisitorData } from '../../types'; + +export function visitAzleVariant( + visitor: DecodeVisitor | EncodeVisitor, + fields: [string, IDL.Type][], + data: VisitorData +) { + const candidFields = fields.reduce((acc, [memberName, memberIdl]) => { + const fieldData = data.js_data[memberName]; + const fieldClass = data.candidType[memberName]; + if (fieldData === undefined) { + // If the field data is undefined then it is not the variant that was used + return acc; + } + return { + ...acc, + [memberName]: memberIdl.accept(visitor, { + candidType: fieldClass, + js_data: fieldData + }) + }; + }, {}); + + return candidFields; +} diff --git a/src/lib/candid/serde/visitors/visit/variant/index.ts b/src/lib/candid/serde/visitors/visit/variant/index.ts new file mode 100644 index 0000000000..26818ae4d3 --- /dev/null +++ b/src/lib/candid/serde/visitors/visit/variant/index.ts @@ -0,0 +1,18 @@ +import { IDL } from '@dfinity/candid'; +import { EncodeVisitor } from '../../encode_visitor'; +import { AzleResult } from '../../../../../system_types'; +import { DecodeVisitor } from '../../decode_visitor'; +import { VisitorData, VisitorResult } from '../../types'; +import { visitAzleVariant } from './azle_variant'; +import { visitAzleResult } from './azle_result'; + +export function visitVariant( + visitor: DecodeVisitor | EncodeVisitor, + fields: [string, IDL.Type][], + data: VisitorData +): VisitorResult { + if (data.candidType instanceof AzleResult) { + return visitAzleResult(visitor, fields, data); + } + return visitAzleVariant(visitor, fields, data); +} diff --git a/src/lib/candid/serde/visitors/visit/vec.ts b/src/lib/candid/serde/visitors/visit/vec.ts new file mode 100644 index 0000000000..44b600ef96 --- /dev/null +++ b/src/lib/candid/serde/visitors/visit/vec.ts @@ -0,0 +1,20 @@ +import { IDL } from '@dfinity/candid'; +import { EncodeVisitor } from '../encode_visitor'; +import { DecodeVisitor } from '../decode_visitor'; +import { VisitorData, VisitorResult } from '../types'; + +export function visitVec( + visitor: DecodeVisitor | EncodeVisitor, + ty: IDL.Type, + data: VisitorData +): VisitorResult { + if (ty instanceof IDL.PrimitiveType) { + return data.js_data; + } + return data.js_data.map((array_elem: any) => { + return ty.accept(visitor, { + js_data: array_elem, + candidType: data.candidType.innerType + }); + }); +}