mirror of
https://github.com/fluencelabs/aquavm
synced 2024-12-04 15:20:16 +00:00
feat(avm-client): implement pluggable formats in JS (#776)
For parsing and producing call requests and call results in AquaVM-compatible way with JSON and MessagePack. Multicodec representation is also supported, both JSON and MessagePack can be used as input. --------- Co-authored-by: Akim <59872966+akim-bow@users.noreply.github.com>
This commit is contained in:
parent
674108506b
commit
eaa40778c7
138
avm/client/package-lock.json
generated
138
avm/client/package-lock.json
generated
@ -8,10 +8,77 @@
|
||||
"name": "@fluencelabs/avm",
|
||||
"version": "0.55.0",
|
||||
"license": "Apache 2.0",
|
||||
"dependencies": {
|
||||
"msgpack-lite": "^0.1.26",
|
||||
"multicodec": "^3.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "5.2.2"
|
||||
}
|
||||
},
|
||||
"node_modules/event-lite": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/event-lite/-/event-lite-0.1.3.tgz",
|
||||
"integrity": "sha512-8qz9nOz5VeD2z96elrEKD2U433+L3DWdUdDkOINLGOJvx1GsMBbMn0aCeu28y8/e85A6mCigBiFlYMnTBEGlSw=="
|
||||
},
|
||||
"node_modules/ieee754": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
||||
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
]
|
||||
},
|
||||
"node_modules/int64-buffer": {
|
||||
"version": "0.1.10",
|
||||
"resolved": "https://registry.npmjs.org/int64-buffer/-/int64-buffer-0.1.10.tgz",
|
||||
"integrity": "sha512-v7cSY1J8ydZ0GyjUHqF+1bshJ6cnEVLo9EnjB8p+4HDRPZc9N5jjmvUV7NvEsqQOKyH0pmIBFWXVQbiS0+OBbA=="
|
||||
},
|
||||
"node_modules/isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
|
||||
},
|
||||
"node_modules/msgpack-lite": {
|
||||
"version": "0.1.26",
|
||||
"resolved": "https://registry.npmjs.org/msgpack-lite/-/msgpack-lite-0.1.26.tgz",
|
||||
"integrity": "sha512-SZ2IxeqZ1oRFGo0xFGbvBJWMp3yLIY9rlIJyxy8CGrwZn1f0ZK4r6jV/AM1r0FZMDUkWkglOk/eeKIL9g77Nxw==",
|
||||
"dependencies": {
|
||||
"event-lite": "^0.1.1",
|
||||
"ieee754": "^1.1.8",
|
||||
"int64-buffer": "^0.1.9",
|
||||
"isarray": "^1.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"msgpack": "bin/msgpack"
|
||||
}
|
||||
},
|
||||
"node_modules/multicodec": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/multicodec/-/multicodec-3.2.1.tgz",
|
||||
"integrity": "sha512-+expTPftro8VAW8kfvcuNNNBgb9gPeNYV9dn+z1kJRWF2vih+/S79f2RVeIwmrJBUJ6NT9IUPWnZDQvegEh5pw==",
|
||||
"deprecated": "This module has been superseded by the multiformats module",
|
||||
"dependencies": {
|
||||
"uint8arrays": "^3.0.0",
|
||||
"varint": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/multiformats": {
|
||||
"version": "9.9.0",
|
||||
"resolved": "https://registry.npmjs.org/multiformats/-/multiformats-9.9.0.tgz",
|
||||
"integrity": "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg=="
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "5.2.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
|
||||
@ -24,14 +91,85 @@
|
||||
"engines": {
|
||||
"node": ">=14.17"
|
||||
}
|
||||
},
|
||||
"node_modules/uint8arrays": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-3.1.1.tgz",
|
||||
"integrity": "sha512-+QJa8QRnbdXVpHYjLoTpJIdCTiw9Ir62nocClWuXIq2JIh4Uta0cQsTSpFL678p2CN8B+XSApwcU+pQEqVpKWg==",
|
||||
"dependencies": {
|
||||
"multiformats": "^9.4.2"
|
||||
}
|
||||
},
|
||||
"node_modules/varint": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/varint/-/varint-6.0.0.tgz",
|
||||
"integrity": "sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg=="
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"event-lite": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/event-lite/-/event-lite-0.1.3.tgz",
|
||||
"integrity": "sha512-8qz9nOz5VeD2z96elrEKD2U433+L3DWdUdDkOINLGOJvx1GsMBbMn0aCeu28y8/e85A6mCigBiFlYMnTBEGlSw=="
|
||||
},
|
||||
"ieee754": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
||||
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
|
||||
},
|
||||
"int64-buffer": {
|
||||
"version": "0.1.10",
|
||||
"resolved": "https://registry.npmjs.org/int64-buffer/-/int64-buffer-0.1.10.tgz",
|
||||
"integrity": "sha512-v7cSY1J8ydZ0GyjUHqF+1bshJ6cnEVLo9EnjB8p+4HDRPZc9N5jjmvUV7NvEsqQOKyH0pmIBFWXVQbiS0+OBbA=="
|
||||
},
|
||||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
|
||||
},
|
||||
"msgpack-lite": {
|
||||
"version": "0.1.26",
|
||||
"resolved": "https://registry.npmjs.org/msgpack-lite/-/msgpack-lite-0.1.26.tgz",
|
||||
"integrity": "sha512-SZ2IxeqZ1oRFGo0xFGbvBJWMp3yLIY9rlIJyxy8CGrwZn1f0ZK4r6jV/AM1r0FZMDUkWkglOk/eeKIL9g77Nxw==",
|
||||
"requires": {
|
||||
"event-lite": "^0.1.1",
|
||||
"ieee754": "^1.1.8",
|
||||
"int64-buffer": "^0.1.9",
|
||||
"isarray": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"multicodec": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/multicodec/-/multicodec-3.2.1.tgz",
|
||||
"integrity": "sha512-+expTPftro8VAW8kfvcuNNNBgb9gPeNYV9dn+z1kJRWF2vih+/S79f2RVeIwmrJBUJ6NT9IUPWnZDQvegEh5pw==",
|
||||
"requires": {
|
||||
"uint8arrays": "^3.0.0",
|
||||
"varint": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"multiformats": {
|
||||
"version": "9.9.0",
|
||||
"resolved": "https://registry.npmjs.org/multiformats/-/multiformats-9.9.0.tgz",
|
||||
"integrity": "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg=="
|
||||
},
|
||||
"typescript": {
|
||||
"version": "5.2.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
|
||||
"integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==",
|
||||
"dev": true
|
||||
},
|
||||
"uint8arrays": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-3.1.1.tgz",
|
||||
"integrity": "sha512-+QJa8QRnbdXVpHYjLoTpJIdCTiw9Ir62nocClWuXIq2JIh4Uta0cQsTSpFL678p2CN8B+XSApwcU+pQEqVpKWg==",
|
||||
"requires": {
|
||||
"multiformats": "^9.4.2"
|
||||
}
|
||||
},
|
||||
"varint": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/varint/-/varint-6.0.0.tgz",
|
||||
"integrity": "sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,10 @@
|
||||
"build": "tsc && ./build_wasm.sh"
|
||||
},
|
||||
"private": false,
|
||||
"dependencies": {},
|
||||
"dependencies": {
|
||||
"msgpack-lite": "^0.1.26",
|
||||
"multicodec": "^3.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "5.2.2"
|
||||
}
|
||||
|
@ -15,9 +15,16 @@
|
||||
*/
|
||||
|
||||
import { CallResultsArray, InterpreterResult, CallRequest, RunParameters, JSONArray, JSONObject } from './types';
|
||||
import { JsonRepr } from './formats'
|
||||
|
||||
const decoder = new TextDecoder();
|
||||
const encoder = new TextEncoder();
|
||||
// Have to match the air-interpreter-interface.
|
||||
const callRequestsRepr = new JsonRepr();
|
||||
// Have to match the air-interpreter-interface.
|
||||
const argumentRepr = new JsonRepr();
|
||||
// Have to match the air-interpreter-interface.
|
||||
const tetrapletRepr = new JsonRepr();
|
||||
// Have to match the air-interpreter-interface.
|
||||
const callResultsRepr = new JsonRepr();
|
||||
|
||||
/**
|
||||
* Encodes arguments into JSON array suitable for marine-js
|
||||
@ -44,7 +51,7 @@ export function serializeAvmArgs(
|
||||
};
|
||||
}
|
||||
|
||||
const encoded = encoder.encode(JSON.stringify(callResultsToPass));
|
||||
const encodedCallResults = callResultsRepr.toBinary(callResultsToPass)
|
||||
const runParamsSnakeCase = {
|
||||
init_peer_id: runParams.initPeerId,
|
||||
current_peer_id: runParams.currentPeerId,
|
||||
@ -55,7 +62,7 @@ export function serializeAvmArgs(
|
||||
particle_id: runParams.particleId,
|
||||
};
|
||||
|
||||
return [air, Array.from(prevData), Array.from(data), runParamsSnakeCase, Array.from(encoded)];
|
||||
return [air, Array.from(prevData), Array.from(data), runParamsSnakeCase, Array.from(encodedCallResults)];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -64,16 +71,16 @@ export function serializeAvmArgs(
|
||||
* @returns structured InterpreterResult
|
||||
*/
|
||||
export function deserializeAvmResult(result: any): InterpreterResult {
|
||||
const callRequestsStr = decoder.decode(new Uint8Array(result.call_requests));
|
||||
let parsedCallRequests;
|
||||
const callRequestsBuf = new Uint8Array(result.call_requests);
|
||||
let parsedCallRequests: object;
|
||||
try {
|
||||
if (callRequestsStr.length === 0) {
|
||||
if (callRequestsBuf.length === 0) {
|
||||
parsedCallRequests = {};
|
||||
} else {
|
||||
parsedCallRequests = JSON.parse(callRequestsStr);
|
||||
parsedCallRequests = callRequestsRepr.fromBinary(callRequestsBuf);
|
||||
}
|
||||
} catch (e) {
|
||||
throw "Couldn't parse call requests: " + e + '. Original string is: ' + callRequestsStr;
|
||||
throw "Couldn't parse call requests: " + e + '. Original data is: ' + result.call_requests;
|
||||
}
|
||||
|
||||
let resultCallRequests: Array<[key: number, callRequest: CallRequest]> = [];
|
||||
@ -83,15 +90,15 @@ export function deserializeAvmResult(result: any): InterpreterResult {
|
||||
let arguments_;
|
||||
let tetraplets;
|
||||
try {
|
||||
const argumentsStr = decoder.decode(new Uint8Array(callRequest.arguments));
|
||||
arguments_ = JSON.parse(argumentsStr);
|
||||
let argumentsBuf = new Uint8Array(callRequest.arguments);
|
||||
arguments_ = argumentRepr.fromBinary(argumentsBuf);
|
||||
} catch (e) {
|
||||
throw "Couldn't parse arguments: " + e + '. Original data is: ' + callRequest.arguments;
|
||||
}
|
||||
|
||||
try {
|
||||
const tetrapletsStr = decoder.decode(new Uint8Array(callRequest.tetraplets));
|
||||
tetraplets = JSON.parse(tetrapletsStr);
|
||||
let tetrapletBuf = new Uint8Array(callRequest.tetraplets);
|
||||
tetraplets = tetrapletRepr.fromBinary(tetrapletBuf);
|
||||
} catch (e) {
|
||||
throw "Couldn't parse tetraplets: " + e + '. Original data is: ' + callRequest.tetraplets;
|
||||
}
|
||||
|
99
avm/client/src/formats.ts
Normal file
99
avm/client/src/formats.ts
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright 2023 Fluence Labs Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import msgpack from "msgpack-lite"
|
||||
import multicodec from "multicodec"
|
||||
|
||||
const decoder = new TextDecoder();
|
||||
const encoder = new TextEncoder();
|
||||
|
||||
interface Representation {
|
||||
fromBinary(data: Uint8Array): object
|
||||
toBinary(obj: object): Uint8Array
|
||||
}
|
||||
|
||||
interface Multiformatable {
|
||||
get_code(): multicodec.CodecCode
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple JSON representation.
|
||||
*/
|
||||
export class JsonRepr implements Representation, Multiformatable {
|
||||
fromBinary(data: Uint8Array): object {
|
||||
let dataStr = decoder.decode(data)
|
||||
return JSON.parse(dataStr);
|
||||
}
|
||||
|
||||
toBinary(obj: object): Uint8Array {
|
||||
return encoder.encode(JSON.stringify(obj))
|
||||
}
|
||||
|
||||
get_code(): multicodec.CodecCode {
|
||||
return multicodec.JSON
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple MessagePack representation.
|
||||
*/
|
||||
export class MsgPackRepr implements Representation, Multiformatable {
|
||||
fromBinary(data: Uint8Array): object {
|
||||
return msgpack.decode(data)
|
||||
}
|
||||
|
||||
toBinary(obj: object): Uint8Array {
|
||||
return msgpack.encode(obj)
|
||||
}
|
||||
|
||||
get_code(): multicodec.CodecCode {
|
||||
return multicodec.MESSAGEPACK
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Multicodec representation that supports both JSON and MsgPack, but uses only specific representation for encoding.
|
||||
*/
|
||||
export class MulticodecRepr implements Representation {
|
||||
serializer: Representation & Multiformatable
|
||||
|
||||
constructor(serializer: Representation & Multiformatable) {
|
||||
this.serializer = serializer
|
||||
}
|
||||
|
||||
fromBinary(data: Uint8Array): object {
|
||||
let code = multicodec.getCodeFromData(data)
|
||||
let repr: Representation | null = null;
|
||||
|
||||
if (code == multicodec.JSON) {
|
||||
repr = new JsonRepr()
|
||||
} else if (code == multicodec.MESSAGEPACK) {
|
||||
repr = new MsgPackRepr()
|
||||
}
|
||||
|
||||
if (repr === null) {
|
||||
throw "Unknown code " + code + "in multiformat data " + data
|
||||
}
|
||||
|
||||
return repr.fromBinary(multicodec.rmPrefix(data))
|
||||
}
|
||||
|
||||
toBinary(obj: object): Uint8Array {
|
||||
let bareData = this.serializer.toBinary(obj);
|
||||
let varintCode = multicodec.getVarintFromCode(this.serializer.get_code());
|
||||
return multicodec.addPrefix(varintCode, bareData)
|
||||
}
|
||||
}
|
@ -16,3 +16,4 @@
|
||||
|
||||
export * from './types';
|
||||
export * from './avmHelpers';
|
||||
export * from './formats';
|
||||
|
Loading…
Reference in New Issue
Block a user