mirror of
https://github.com/fluencelabs/fluence-js.git
synced 2025-03-30 22:11:03 +00:00
Fix host imports in fluence-js (#997)
This commit is contained in:
parent
84f0b3ba18
commit
8a10957efe
8
package-lock.json
generated
8
package-lock.json
generated
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "fluence",
|
"name": "fluence",
|
||||||
"version": "0.7.96",
|
"version": "0.7.99",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -25,9 +25,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@fluencelabs/aquamarine-stepper": {
|
"@fluencelabs/aquamarine-stepper": {
|
||||||
"version": "0.0.15",
|
"version": "0.0.16",
|
||||||
"resolved": "https://registry.npmjs.org/@fluencelabs/aquamarine-stepper/-/aquamarine-stepper-0.0.15.tgz",
|
"resolved": "https://registry.npmjs.org/@fluencelabs/aquamarine-stepper/-/aquamarine-stepper-0.0.16.tgz",
|
||||||
"integrity": "sha512-dCzBlqiR0/EiYzCseIlpE8wbi/jRMLvMsFkTIm0tmhvSfWtBskXLniM9CE4JqyUATAVuBdKJ5HKsufACugGf4A=="
|
"integrity": "sha512-yrRMH2ysrxkhOGUe599urPopx6bon44qHppyvE6RKdrE1qVgxYKONWU+BNM+ouzIZ3UW5hoT0gQZ7lmI3HS30g=="
|
||||||
},
|
},
|
||||||
"@sinonjs/commons": {
|
"@sinonjs/commons": {
|
||||||
"version": "1.7.2",
|
"version": "1.7.2",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "fluence",
|
"name": "fluence",
|
||||||
"version": "0.7.97",
|
"version": "0.7.100",
|
||||||
"description": "the browser js-libp2p client for the Fluence network",
|
"description": "the browser js-libp2p client for the Fluence network",
|
||||||
"main": "./dist/fluence.js",
|
"main": "./dist/fluence.js",
|
||||||
"typings": "./dist/fluence.d.ts",
|
"typings": "./dist/fluence.d.ts",
|
||||||
@ -10,12 +10,13 @@
|
|||||||
"package:build": "NODE_ENV=production webpack && npm run package",
|
"package:build": "NODE_ENV=production webpack && npm run package",
|
||||||
"package": "tsc && rsync -r src/aqua/*.js dist/aqua",
|
"package": "tsc && rsync -r src/aqua/*.js dist/aqua",
|
||||||
"start": "webpack-dev-server -p",
|
"start": "webpack-dev-server -p",
|
||||||
"build": "webpack"
|
"build": "webpack --mode production"
|
||||||
},
|
},
|
||||||
|
"repository": "https://github.com/fluencelabs/fluence",
|
||||||
"author": "Fluence Labs",
|
"author": "Fluence Labs",
|
||||||
"license": "Apache 2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fluencelabs/aquamarine-stepper": "0.0.15",
|
"@fluencelabs/aquamarine-stepper": "0.0.16",
|
||||||
"async": "3.2.0",
|
"async": "3.2.0",
|
||||||
"base64-js": "1.3.1",
|
"base64-js": "1.3.1",
|
||||||
"bs58": "4.0.1",
|
"bs58": "4.0.1",
|
||||||
|
3
src/aqua/index.d.ts
vendored
3
src/aqua/index.d.ts
vendored
@ -6,9 +6,10 @@
|
|||||||
* @param {string} aqua
|
* @param {string} aqua
|
||||||
* @param {string} prev_data
|
* @param {string} prev_data
|
||||||
* @param {string} data
|
* @param {string} data
|
||||||
|
* @param {string} log_level
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
export function invoke(wasm: any, init_user_id: string, aqua: string, prev_data: string, data: string): string;
|
export function invoke(wasm: any, init_user_id: string, aqua: string, prev_data: string, data: string, log_level: string): string;
|
||||||
export function ast(wasm: any, script: string): string;
|
export function ast(wasm: any, script: string): string;
|
||||||
export function getStringFromWasm0(wasm: any, arg1: any, arg2: any): string
|
export function getStringFromWasm0(wasm: any, arg1: any, arg2: any): string
|
||||||
export function getInt32Memory0(wasm: any): number[]
|
export function getInt32Memory0(wasm: any): number[]
|
||||||
|
@ -96,9 +96,10 @@ export function getStringFromWasm0(wasm, ptr, len) {
|
|||||||
* @param {string} aqua
|
* @param {string} aqua
|
||||||
* @param {string} prev_data
|
* @param {string} prev_data
|
||||||
* @param {string} data
|
* @param {string} data
|
||||||
|
* @param {string} log_level
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
export function invoke(wasm, init_user_id, aqua, prev_data, data) {
|
export function invoke(wasm, init_user_id, aqua, prev_data, data, log_level) {
|
||||||
try {
|
try {
|
||||||
var ptr0 = passStringToWasm0(wasm, init_user_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
var ptr0 = passStringToWasm0(wasm, init_user_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||||
var len0 = WASM_VECTOR_LEN;
|
var len0 = WASM_VECTOR_LEN;
|
||||||
@ -108,7 +109,9 @@ export function invoke(wasm, init_user_id, aqua, prev_data, data) {
|
|||||||
var len2 = WASM_VECTOR_LEN;
|
var len2 = WASM_VECTOR_LEN;
|
||||||
var ptr3 = passStringToWasm0(wasm, data, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
var ptr3 = passStringToWasm0(wasm, data, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||||
var len3 = WASM_VECTOR_LEN;
|
var len3 = WASM_VECTOR_LEN;
|
||||||
wasm.invoke(8, ptr0, len0, ptr1, len1, ptr2, len2, ptr3, len3);
|
var ptr4 = passStringToWasm0(wasm, log_level, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||||
|
var len4 = WASM_VECTOR_LEN;
|
||||||
|
wasm.invoke(8, ptr0, len0, ptr1, len1, ptr2, len2, ptr3, len3, ptr4, len4);
|
||||||
var r0 = getInt32Memory0(wasm)[8 / 4 + 0];
|
var r0 = getInt32Memory0(wasm)[8 / 4 + 0];
|
||||||
var r1 = getInt32Memory0(wasm)[8 / 4 + 1];
|
var r1 = getInt32Memory0(wasm)[8 / 4 + 1];
|
||||||
return getStringFromWasm0(wasm, r0, r1);
|
return getStringFromWasm0(wasm, r0, r1);
|
||||||
|
@ -19,10 +19,7 @@ import Multiaddr from "multiaddr"
|
|||||||
import {FluenceClient} from "./fluenceClient";
|
import {FluenceClient} from "./fluenceClient";
|
||||||
import * as log from "loglevel";
|
import * as log from "loglevel";
|
||||||
import {LogLevelDesc} from "loglevel";
|
import {LogLevelDesc} from "loglevel";
|
||||||
import {ServiceMultiple} from "./service";
|
import {parseAstClosure} from "./stepper";
|
||||||
import {registerService} from "./globalState";
|
|
||||||
import {build} from "./particle";
|
|
||||||
import {instantiateInterpreter, parseAstClosure} from "./stepper";
|
|
||||||
|
|
||||||
log.setLevel('info')
|
log.setLevel('info')
|
||||||
|
|
||||||
@ -39,6 +36,22 @@ export default class Fluence {
|
|||||||
return await PeerId.create({keyType: "Ed25519"});
|
return await PeerId.create({keyType: "Ed25519"});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create FluenceClient without connecting it to a relay
|
||||||
|
*
|
||||||
|
* @param peerId – client's peer id. Must contain a private key. See `generatePeerId()`
|
||||||
|
*/
|
||||||
|
static async local(peerId?: PeerId): Promise<FluenceClient> {
|
||||||
|
if (!peerId) {
|
||||||
|
peerId = await Fluence.generatePeerId()
|
||||||
|
}
|
||||||
|
|
||||||
|
let client = new FluenceClient(peerId);
|
||||||
|
await client.instantiateInterpreter();
|
||||||
|
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Connect to Fluence node.
|
* Connect to Fluence node.
|
||||||
*
|
*
|
||||||
@ -46,15 +59,9 @@ export default class Fluence {
|
|||||||
* @param peerId your peer id. Should be with a private key. Could be generated by `generatePeerId()` function
|
* @param peerId your peer id. Should be with a private key. Could be generated by `generatePeerId()` function
|
||||||
*/
|
*/
|
||||||
static async connect(multiaddr: string | Multiaddr, peerId?: PeerId): Promise<FluenceClient> {
|
static async connect(multiaddr: string | Multiaddr, peerId?: PeerId): Promise<FluenceClient> {
|
||||||
|
let client = await Fluence.local(peerId);
|
||||||
if (!peerId) {
|
|
||||||
peerId = await Fluence.generatePeerId()
|
|
||||||
}
|
|
||||||
|
|
||||||
let client = new FluenceClient(peerId);
|
|
||||||
|
|
||||||
await client.connect(multiaddr);
|
await client.connect(multiaddr);
|
||||||
|
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ export class FluenceClient {
|
|||||||
enqueueParticle(particle);
|
enqueueParticle(particle);
|
||||||
} else {
|
} else {
|
||||||
if (this.interpreter === undefined) {
|
if (this.interpreter === undefined) {
|
||||||
throw new Error("Undefined. Interpreter is not initialized. User 'Fluence.connect' to create a client.")
|
throw new Error("Undefined. Interpreter is not initialized. Use 'Fluence.connect' to create a client.")
|
||||||
}
|
}
|
||||||
// start particle processing if queue is empty
|
// start particle processing if queue is empty
|
||||||
try {
|
try {
|
||||||
@ -87,8 +87,8 @@ export class FluenceClient {
|
|||||||
log.info("inner interpreter outcome:");
|
log.info("inner interpreter outcome:");
|
||||||
log.info(stepperOutcome);
|
log.info(stepperOutcome);
|
||||||
|
|
||||||
// do nothing if there is no `next_peer_pks`
|
// do nothing if there is no `next_peer_pks` or if client isn't connected to the network
|
||||||
if (stepperOutcome.next_peer_pks.length > 0) {
|
if (stepperOutcome.next_peer_pks.length > 0 && this.connection) {
|
||||||
let newParticle: Particle = {...particle};
|
let newParticle: Particle = {...particle};
|
||||||
newParticle.data = JSON.parse(stepperOutcome.call_path);
|
newParticle.data = JSON.parse(stepperOutcome.call_path);
|
||||||
|
|
||||||
@ -138,18 +138,27 @@ export class FluenceClient {
|
|||||||
return this.connection.disconnect();
|
return this.connection.disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiate WebAssembly with AIR interpreter to execute AIR scripts
|
||||||
|
*/
|
||||||
|
async instantiateInterpreter() {
|
||||||
|
this.interpreter = await instantiateInterpreter(this.selfPeerId);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Establish a connection to the node. If the connection is already established, disconnect and reregister all services in a new connection.
|
* Establish a connection to the node. If the connection is already established, disconnect and reregister all services in a new connection.
|
||||||
*
|
*
|
||||||
* @param multiaddr
|
* @param multiaddr
|
||||||
*/
|
*/
|
||||||
async connect(multiaddr: string | Multiaddr): Promise<void> {
|
async connect(multiaddr: string | Multiaddr) {
|
||||||
|
|
||||||
multiaddr = Multiaddr(multiaddr);
|
multiaddr = Multiaddr(multiaddr);
|
||||||
|
|
||||||
|
if (!this.interpreter) {
|
||||||
|
throw Error("you must call 'instantiateInterpreter' before 'connect'")
|
||||||
|
}
|
||||||
|
|
||||||
let nodePeerId = multiaddr.getPeerId();
|
let nodePeerId = multiaddr.getPeerId();
|
||||||
this.nodePeerIdStr = nodePeerId;
|
this.nodePeerIdStr = nodePeerId;
|
||||||
|
|
||||||
if (!nodePeerId) {
|
if (!nodePeerId) {
|
||||||
throw Error("'multiaddr' did not contain a valid peer id")
|
throw Error("'multiaddr' did not contain a valid peer id")
|
||||||
}
|
}
|
||||||
@ -160,12 +169,8 @@ export class FluenceClient {
|
|||||||
await this.connection.disconnect();
|
await this.connection.disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
let peerId = PeerId.createFromB58String(nodePeerId);
|
let node = PeerId.createFromB58String(nodePeerId);
|
||||||
|
let connection = new FluenceConnection(multiaddr, node, this.selfPeerId, this.handleExternalParticle());
|
||||||
this.interpreter = await instantiateInterpreter(this.selfPeerId);
|
|
||||||
|
|
||||||
let connection = new FluenceConnection(multiaddr, peerId, this.selfPeerId, this.handleExternalParticle());
|
|
||||||
|
|
||||||
await connection.connect();
|
await connection.connect();
|
||||||
|
|
||||||
this.connection = connection;
|
this.connection = connection;
|
||||||
@ -176,6 +181,10 @@ export class FluenceClient {
|
|||||||
return particle.id
|
return particle.id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async executeParticle(particle: Particle) {
|
||||||
|
await this.handleParticle(particle);
|
||||||
|
}
|
||||||
|
|
||||||
nodeIdentityCall(): string {
|
nodeIdentityCall(): string {
|
||||||
return `(call "${this.nodePeerIdStr}" ("op" "identity") [] void[])`
|
return `(call "${this.nodePeerIdStr}" ("op" "identity") [] void[])`
|
||||||
}
|
}
|
||||||
|
@ -40,24 +40,36 @@ type LogImport = {
|
|||||||
log_utf8_string: (level: any, target: any, offset: any, size: any) => void
|
log_utf8_string: (level: any, target: any, offset: any, size: any) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class HostImportsConfig {
|
||||||
|
exports: Exports | undefined;
|
||||||
|
newImportObject: () => ImportObject;
|
||||||
|
|
||||||
|
constructor(create: (cfg: HostImportsConfig) => ImportObject) {
|
||||||
|
this.exports = undefined;
|
||||||
|
this.newImportObject = () => create(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
setExports(exports: Exports) {
|
||||||
|
this.exports = exports;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const interpreter_wasm = toByteArray(wasmBs64)
|
const interpreter_wasm = toByteArray(wasmBs64)
|
||||||
|
|
||||||
/// Instantiates WebAssembly runtime with AIR interpreter module
|
/// Instantiates WebAssembly runtime with AIR interpreter module
|
||||||
async function interpreterInstance(hostImports: (wasm: Exports) => Imports): Promise<Instance> {
|
async function interpreterInstance(cfg: HostImportsConfig): Promise<Instance> {
|
||||||
// Uninitialized exports reference that must be initialized after WebAssembly is instantiated
|
|
||||||
let exports: Exports = undefined;
|
|
||||||
/// Create host imports that use module exports internally
|
/// Create host imports that use module exports internally
|
||||||
let imports = hostImports(exports);
|
let imports = cfg.newImportObject();
|
||||||
|
|
||||||
/// Instantiate interpreter
|
/// Instantiate interpreter
|
||||||
let interpreter_module = await WebAssembly.compile(interpreter_wasm);
|
let interpreter_module = await WebAssembly.compile(interpreter_wasm);
|
||||||
let instance: Instance = await WebAssembly.instantiate(interpreter_module, imports);
|
let instance: Instance = await WebAssembly.instantiate(interpreter_module, imports);
|
||||||
|
|
||||||
/// Finally initialize exports, so host imports can use them
|
/// Set exports, so host imports can use them
|
||||||
exports = instance.exports;
|
cfg.setExports(instance.exports);
|
||||||
|
|
||||||
/// Trigger interpreter initialization (i.e., call main function)
|
/// Trigger interpreter initialization (i.e., call main function)
|
||||||
call_export(exports.main);
|
call_export(instance.exports.main);
|
||||||
|
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
@ -72,9 +84,10 @@ function call_export(f: ExportValue, ...argArray: any[]): any {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function log_import(wasm: Exports): LogImport {
|
function log_import(cfg: HostImportsConfig): LogImport {
|
||||||
return {
|
return {
|
||||||
log_utf8_string: (level: any, target: any, offset: any, size: any) => {
|
log_utf8_string: (level: any, target: any, offset: any, size: any) => {
|
||||||
|
let wasm = cfg.exports;
|
||||||
try {
|
try {
|
||||||
let str = getStringFromWasm0(wasm, offset, size)
|
let str = getStringFromWasm0(wasm, offset, size)
|
||||||
|
|
||||||
@ -103,12 +116,13 @@ function log_import(wasm: Exports): LogImport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns import object that describes host functions called by AIR interpreter
|
/// Returns import object that describes host functions called by AIR interpreter
|
||||||
function newImportObject(wasm: Exports, peerId: PeerId): ImportObject {
|
function newImportObject(cfg: HostImportsConfig, peerId: PeerId): ImportObject {
|
||||||
return {
|
return {
|
||||||
// __wbg_callserviceimpl_c0ca292e3c8c0c97 this is a function generated by bindgen. Could be changed.
|
// __wbg_callserviceimpl_c0ca292e3c8c0c97 this is a function generated by bindgen. Could be changed.
|
||||||
// If so, an error with a new name will be occurred after wasm initialization.
|
// If so, an error with a new name will be occurred after wasm initialization.
|
||||||
"./aquamarine_client_bg.js": {
|
"./aquamarine_client_bg.js": {
|
||||||
__wbg_callserviceimpl_7d3cf77a2722659e: (arg0: any, arg1: any, arg2: any, arg3: any, arg4: any, arg5: any, arg6: any) => {
|
__wbg_callserviceimpl_7d3cf77a2722659e: (arg0: any, arg1: any, arg2: any, arg3: any, arg4: any, arg5: any, arg6: any) => {
|
||||||
|
let wasm = cfg.exports;
|
||||||
try {
|
try {
|
||||||
let serviceId = getStringFromWasm0(wasm, arg1, arg2)
|
let serviceId = getStringFromWasm0(wasm, arg1, arg2)
|
||||||
let fnName = getStringFromWasm0(wasm, arg3, arg4)
|
let fnName = getStringFromWasm0(wasm, arg3, arg4)
|
||||||
@ -126,6 +140,7 @@ function newImportObject(wasm: Exports, peerId: PeerId): ImportObject {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
__wbg_getcurrentpeeridimpl_154ce1848a306ff5: (arg0: any) => {
|
__wbg_getcurrentpeeridimpl_154ce1848a306ff5: (arg0: any) => {
|
||||||
|
let wasm = cfg.exports;
|
||||||
var ret = peerId.toB58String();
|
var ret = peerId.toB58String();
|
||||||
var ptr0 = passStringToWasm0(wasm, ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
var ptr0 = passStringToWasm0(wasm, ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||||
var len0 = WASM_VECTOR_LEN;
|
var len0 = WASM_VECTOR_LEN;
|
||||||
@ -133,13 +148,13 @@ function newImportObject(wasm: Exports, peerId: PeerId): ImportObject {
|
|||||||
getInt32Memory0(wasm)[arg0 / 4 + 0] = ptr0;
|
getInt32Memory0(wasm)[arg0 / 4 + 0] = ptr0;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
host: log_import(wasm)
|
host: log_import(cfg)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function newLogImport(wasm: Exports): ImportObject {
|
function newLogImport(cfg: HostImportsConfig): ImportObject {
|
||||||
return {
|
return {
|
||||||
host: log_import(wasm),
|
host: log_import(cfg),
|
||||||
"./aquamarine_client_bg.js": {
|
"./aquamarine_client_bg.js": {
|
||||||
__wbg_callserviceimpl_7d3cf77a2722659e: _ => {},
|
__wbg_callserviceimpl_7d3cf77a2722659e: _ => {},
|
||||||
__wbg_getcurrentpeeridimpl_154ce1848a306ff5: _ => {}
|
__wbg_getcurrentpeeridimpl_154ce1848a306ff5: _ => {}
|
||||||
@ -150,17 +165,36 @@ function newLogImport(wasm: Exports): ImportObject {
|
|||||||
/// Instantiates AIR interpreter, and returns its `invoke` function as closure
|
/// Instantiates AIR interpreter, and returns its `invoke` function as closure
|
||||||
/// NOTE: an interpreter is also called a stepper from time to time
|
/// NOTE: an interpreter is also called a stepper from time to time
|
||||||
export async function instantiateInterpreter(peerId: PeerId): Promise<InterpreterInvoke> {
|
export async function instantiateInterpreter(peerId: PeerId): Promise<InterpreterInvoke> {
|
||||||
let instance = await interpreterInstance(wasm => newImportObject(wasm, peerId));
|
let cfg = new HostImportsConfig((cfg) => newImportObject(cfg, peerId))
|
||||||
|
let instance = await interpreterInstance(cfg);
|
||||||
|
|
||||||
return (init_user_id: string, script: string, prev_data: string, data: string) => {
|
return (init_user_id: string, script: string, prev_data: string, data: string) => {
|
||||||
return aqua.invoke(instance.exports, init_user_id, script, prev_data, data)
|
|
||||||
|
let logLevel = log.getLevel()
|
||||||
|
let logLevelStr = "info"
|
||||||
|
if (logLevel === 0) {
|
||||||
|
logLevelStr = "trace"
|
||||||
|
} else if (logLevel === 1) {
|
||||||
|
logLevelStr = "debug"
|
||||||
|
} else if (logLevel === 2) {
|
||||||
|
logLevelStr = "info"
|
||||||
|
} else if (logLevel === 3) {
|
||||||
|
logLevelStr = "warn"
|
||||||
|
} else if (logLevel === 4) {
|
||||||
|
logLevelStr = "error"
|
||||||
|
} else if (logLevel === 5) {
|
||||||
|
logLevelStr = "off"
|
||||||
|
}
|
||||||
|
|
||||||
|
return aqua.invoke(instance.exports, init_user_id, script, prev_data, data, logLevelStr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Instantiate AIR interpreter with host imports containing only logger, but not call_service
|
/// Instantiate AIR interpreter with host imports containing only logger, but not call_service
|
||||||
/// peerId isn't actually required for AST parsing, but host imports require it, and I don't see any workaround
|
/// peerId isn't actually required for AST parsing, but host imports require it, and I don't see any workaround
|
||||||
export async function parseAstClosure(): Promise<(script: string) => string> {
|
export async function parseAstClosure(): Promise<(script: string) => string> {
|
||||||
let instance = await interpreterInstance(wasm => newLogImport(wasm));
|
let cfg = new HostImportsConfig((cfg) => newLogImport(cfg));
|
||||||
|
let instance = await interpreterInstance(cfg);
|
||||||
|
|
||||||
return (script: string) => {
|
return (script: string) => {
|
||||||
return aqua.ast(instance.exports, script)
|
return aqua.ast(instance.exports, script)
|
||||||
|
27
src/test/air.spec.ts
Normal file
27
src/test/air.spec.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import 'mocha';
|
||||||
|
import Fluence from "../fluence";
|
||||||
|
import {build} from "../particle";
|
||||||
|
import { ServiceMultiple } from "../service";
|
||||||
|
import { registerService } from "../globalState";
|
||||||
|
|
||||||
|
describe("AIR", () => {
|
||||||
|
it("call local function", async function () {
|
||||||
|
let service = new ServiceMultiple("console");
|
||||||
|
registerService(service);
|
||||||
|
service.registerFunction('log', (args: any[]) => {
|
||||||
|
console.log(`log: ${args}`);
|
||||||
|
|
||||||
|
return {}
|
||||||
|
})
|
||||||
|
|
||||||
|
let client = await Fluence.local();
|
||||||
|
|
||||||
|
let script = `(call %init_peer_id% ("console" "log") ["hello"])`
|
||||||
|
|
||||||
|
// Wrap script into particle, so it can be executed by local WASM runtime
|
||||||
|
let particle = await build(client.selfPeerId, script, new Map())
|
||||||
|
|
||||||
|
await client.executeParticle(particle);
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
@ -3,7 +3,7 @@ import Fluence from "../fluence";
|
|||||||
|
|
||||||
describe("AIR AST parsing suite", () => {
|
describe("AIR AST parsing suite", () => {
|
||||||
it("parse simple script and return ast", async function () {
|
it("parse simple script and return ast", async function () {
|
||||||
let ast = Fluence.parseAIR(`
|
let ast = await Fluence.parseAIR(`
|
||||||
(call node ("service" "function") [1 2 3 arg] output)
|
(call node ("service" "function") [1 2 3 arg] output)
|
||||||
`);
|
`);
|
||||||
|
|
||||||
|
@ -6,9 +6,9 @@
|
|||||||
"./types"
|
"./types"
|
||||||
],
|
],
|
||||||
"outDir": "./dist/",
|
"outDir": "./dist/",
|
||||||
|
"baseUrl": ".",
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"inlineSources": true,
|
"inlineSources": true,
|
||||||
"noImplicitAny": true,
|
|
||||||
"strictFunctionTypes": true,
|
"strictFunctionTypes": true,
|
||||||
"allowSyntheticDefaultImports": true,
|
"allowSyntheticDefaultImports": true,
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
@ -17,11 +17,13 @@
|
|||||||
"module": "commonjs",
|
"module": "commonjs",
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"declaration": true,
|
"declaration": true,
|
||||||
"strict": true,
|
|
||||||
"strictNullChecks": false,
|
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"declarationMap": true,
|
"declarationMap": true,
|
||||||
"baseUrl": "."
|
"strict": true,
|
||||||
|
"noImplicitAny": true,
|
||||||
|
"alwaysStrict": true,
|
||||||
|
"noImplicitThis": true,
|
||||||
|
"strictNullChecks": false,
|
||||||
},
|
},
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"node_modules",
|
"node_modules",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user