The hdk-assemblyscript
is not currently ready for use, and has an "experimental" status.
The hdk-assemblyscript development is currently partially blocked by the lack of JSON parsing in assemblyscript. There is an open issue for this in the Assemblyscript repository. There are some who've said it is being worked on.
Until these issues are resolved, hdk-rust will be the most functional HDK for app development.
There are several pieces required to complete an HDK, here are their status:
- Declaring capabilities and their functions: A prototype using
@zome_function
decorator is complete, but being reworked, issue here - Declaring entry types: Not implemented, but a proposal is in this issue
- Stringification of class instances to string: Implemented using the
@can_stringify
decorator for classes - Entry Validation: Not implemented, but a proposal is in this issue
- Link Validation: Not implemented
- Genesis wrapper: Not implemented, issue here
- debug
- commit_entry
- get_entry
- init_globals
- call
- get_links
- link_entries
- hash_entry
- sign
- verify_signature
- update_entry
- update_agent
- remove_entry
- query
- send
- start_bundle
- close_bundle
To use a function, just import it...
import {
debug
} from 'hdk-assemblyscript'
Then, in some zome function that you are writing, you can just call that function...
@zome_function
function createPost(...) {
...
debug("hello");
...
}
- Nodejs
- Nodejs must be installed, as the assemblyscript build system relies on node/npm
- hc
hc
is the command line tools for Holochain app development
- hcshell
hcshell
is the underlying container that runs Holochain DNA tests
To run the tests of this repo, run the following commands within this repository in the command line, having cloned or downloaded it to your computer.
npm install
cd examples/appSpec
hc test | test/node_modules/faucet/bin/cmd.js
The use of | test/node_modules/faucet/bin/cmd.js
ensures a nicer visual output. To read more about options for test running, visit the holochain-cmd repository.
It is important to note that assemblyscript is NOT typescript. There are several important features that are missing notably:
- interfaces
- use of untyped variables or the any type
- JSON.parse/JSON.stringify
- virtual methods (the method of the compile time type will always be called)
- Closures
This may make writing zome in ASM difficult for developers used to javascript/typescript.
To enable developers to write zomes in assemblyscript in a familiar way the HDK is responsible for 3 different things:
- Wrapping Holochain API calls from assemblyscript so that they can be called with familiar parameters
- Wrapping exported functions from assemblyscript so that the holochain runtime can call them
- Wrapping callbacks (e.g. validate_commit etc)
The medium of communication between holochain core and wasm zomes is strings which use json to encode objects. More speficically all wasm calls must accept a single u32 (encoded_allocation) where the high 16 bits are the memory offset and the low 32 bits are the size of the string. Similarly this is what a wasm call must return.
Rust passes and expects UTF-8 null terminated strings. Assemblyscript deals in UTF-16LE encoded non-null terminated strings with a 32 bit header specifying the length. It is important to deal with the conversion between these two types in the serialize and deserialize functions.
Assemblyscript supports transforming the typescript source as part of the build pipeline. It is also able to recognise decorators e.g @zome_function
. This mean that the boilerplate of deserializing/serializing arguments can be abstracted from the developer.
The proposed tranform is as follows: Developer writes:
@zome_function
function writePost(title: string): string {
... commit entries etc
}
compiler sees:
function _writePost(title: string, body: string, timestamp: i32): string {
... commit entries etc
}
export function writePost(e: u32): u32 {
let jsonString: string = deserialize(e);
// `{"title": "wasm for beginners", "body": "...", "timestamp": 1234}``
// parameters defined as variables
let title: string;
let body: string;
let timestamp: i32;
// call the original function
let result: string = _writePost(title, body, timestamp);
// return the serialized result string
return serialize(result);
}
The above still has some limitations such as:
- only string values allowed for public zome function returns
- only primitive types and strings permitted as function parameters
This may or may not be acceptable going forward