holochain / hdk-assemblyscript

The Holochain Developer Kit for Assemblyscript
41 stars 2 forks source link

Holochain Developer Kit for Assemblyscript

Status

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:

Working Functions

Functions Not Ready (and not ready in holochain-rust)

Using the API Functions (decorators subject to change)

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");
  ...
}

Running Tests

Dependencies

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.

Limitations of assemblyscript

It is important to note that assemblyscript is NOT typescript. There are several important features that are missing notably:

This may make writing zome in ASM difficult for developers used to javascript/typescript.

Background

To enable developers to write zomes in assemblyscript in a familiar way the HDK is responsible for 3 different things:

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.

Serializing and de-serializing strings from encoded_allocations

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.

Macros for improving the developer experience

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:

This may or may not be acceptable going forward