Add remove scripts, fix builtins (#15)

This commit is contained in:
Dima 2021-02-03 21:18:27 +03:00 committed by GitHub
parent e4d3f688ed
commit 481a44b819
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 196 additions and 21 deletions

7
package-lock.json generated
View File

@ -1,6 +1,6 @@
{ {
"name": "@fluencelabs/fluence", "name": "@fluencelabs/fluence",
"version": "0.9.2", "version": "0.9.3",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
@ -29,6 +29,11 @@
"resolved": "https://registry.npmjs.org/@fluencelabs/aquamarine-stepper/-/aquamarine-stepper-0.3.4.tgz", "resolved": "https://registry.npmjs.org/@fluencelabs/aquamarine-stepper/-/aquamarine-stepper-0.3.4.tgz",
"integrity": "sha512-0NPg9dWvANtc3If8C8O8XjKwzMCq2492lA73faKJdCwUv7m+xHX9G3l6UJULTfV1T4mWVtMQZIKopNOlRYSrKA==" "integrity": "sha512-0NPg9dWvANtc3If8C8O8XjKwzMCq2492lA73faKJdCwUv7m+xHX9G3l6UJULTfV1T4mWVtMQZIKopNOlRYSrKA=="
}, },
"@fluencelabs/fluence-network-environment": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/@fluencelabs/fluence-network-environment/-/fluence-network-environment-1.0.8.tgz",
"integrity": "sha512-k1E48+r7tc5jWsnAeLrua7yRKN9lRISdJ1czkcOzUF6dZ9fI5+6ZfKKfUozJyC6n4hSjtCIcUV0G65vBvQfxBw=="
},
"@sinonjs/commons": { "@sinonjs/commons": {
"version": "1.7.2", "version": "1.7.2",
"resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.7.2.tgz", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.7.2.tgz",

View File

@ -1,6 +1,6 @@
{ {
"name": "@fluencelabs/fluence", "name": "@fluencelabs/fluence",
"version": "0.9.9", "version": "0.9.13",
"description": "JS SDK for the Fluence network", "description": "JS SDK for the Fluence network",
"main": "./dist/index.js", "main": "./dist/index.js",
"typings": "./dist/index.d.ts", "typings": "./dist/index.d.ts",
@ -15,6 +15,7 @@
"dependencies": { "dependencies": {
"@fluencelabs/aquamarine-stepper": "0.3.4", "@fluencelabs/aquamarine-stepper": "0.3.4",
"async": "3.2.0", "async": "3.2.0",
"@fluencelabs/fluence-network-environment": "1.0.8",
"base64-js": "1.3.1", "base64-js": "1.3.1",
"bs58": "4.0.1", "bs58": "4.0.1",
"cids": "0.8.1", "cids": "0.8.1",

View File

@ -7,11 +7,20 @@ import { TrustGraph } from '../internal/trust/trust_graph';
import { nodeRootCert } from '../internal/trust/misc'; import { nodeRootCert } from '../internal/trust/misc';
import { generatePeerId, peerIdToSeed, seedToPeerId } from '../internal/peerIdUtils'; import { generatePeerId, peerIdToSeed, seedToPeerId } from '../internal/peerIdUtils';
import { FluenceClientImpl } from '../internal/FluenceClientImpl'; import { FluenceClientImpl } from '../internal/FluenceClientImpl';
import { createConnectedClient, createLocalClient } from './util'; import { createConnectedClient } from './util';
import log from 'loglevel'; import log from 'loglevel';
import { createClient } from '../api'; import { createClient } from '../api';
import Multiaddr from 'multiaddr'; import Multiaddr from 'multiaddr';
import { getModules } from '../internal/builtins'; import {
addBlueprint, addProvider,
addScript,
createService,
getBlueprints, getInterfaces,
getModules, getProviders,
removeScript,
uploadModule
} from '../internal/builtins';
import {dev} from "@fluencelabs/fluence-network-environment";
const devNodeAddress = '/dns4/dev.fluence.dev/tcp/19001/wss/p2p/12D3KooWEXNUbCXooUwHrHBbrmjsrpHXoEphPwbjQXEGyzbqKnE9'; const devNodeAddress = '/dns4/dev.fluence.dev/tcp/19001/wss/p2p/12D3KooWEXNUbCXooUwHrHBbrmjsrpHXoEphPwbjQXEGyzbqKnE9';
const devNodePeerId = '12D3KooWEXNUbCXooUwHrHBbrmjsrpHXoEphPwbjQXEGyzbqKnE9'; const devNodePeerId = '12D3KooWEXNUbCXooUwHrHBbrmjsrpHXoEphPwbjQXEGyzbqKnE9';
@ -146,7 +155,7 @@ describe('Typescript usage suite', () => {
it.skip('should make a call through the network', async function () { it.skip('should make a call through the network', async function () {
this.timeout(30000); this.timeout(30000);
// arrange // arrange
const client = await createConnectedClient(devNodeAddress); const client = await createConnectedClient(dev[0].multiaddr);
client.registerCallback('test', 'test', (args, _) => { client.registerCallback('test', 'test', (args, _) => {
log.trace('should make a call through the network, called "test" "test" with args', args); log.trace('should make a call through the network, called "test" "test" with args', args);
@ -214,16 +223,111 @@ describe('Typescript usage suite', () => {
expect(res).to.deep.equal(['some d', 'some c', 'some b', 'some a']); expect(res).to.deep.equal(['some d', 'some c', 'some b', 'some a']);
}); });
it.skip('add_module', async function () { it.skip('get_modules', async function () {
this.timeout(30000); this.timeout(30000);
// arrange const client = await createConnectedClient(dev[2].multiaddr);
const client = await createConnectedClient(
'/dns4/dev.fluence.dev/tcp/19003/wss/p2p/12D3KooWBUJifCTgaxAUrcM9JysqCcS4CS8tiYH5hExbdWCAoNwb',
);
let a = await getModules(client); let modulesList = await getModules(client);
expect(a).not.to.be.undefined; expect(modulesList).not.to.be.undefined;
});
it.skip('get_interfaces', async function () {
this.timeout(30000);
const client = await createConnectedClient(dev[2].multiaddr);
let interfaces = await getInterfaces(client);
expect(interfaces).not.to.be.undefined;
});
it.skip('get_blueprints', async function () {
this.timeout(30000);
const client = await createConnectedClient(dev[2].multiaddr);
let bpList = await getBlueprints(client);
expect(bpList).not.to.be.undefined;
});
it.skip("upload_modules", async function () {
this.timeout(30000);
const client = await createConnectedClient(dev[2].multiaddr);
console.log("peerid: " + client.selfPeerId)
let base64 = "MjNy"
await uploadModule(client, "test_broken_module", base64);
});
it.skip("add_blueprint", async function () {
this.timeout(30000);
const client = await createConnectedClient(dev[2].multiaddr);
let bpId = "some"
let bpIdReturned = await addBlueprint(client, "test_broken_blueprint", ["test_broken_module"], bpId);
expect(bpIdReturned).to.be.equal(bpId);
});
it.skip("create_service", async function () {
this.timeout(30000);
const client = await createConnectedClient(dev[2].multiaddr);
let serviceId = await createService(client, "test_broken_blueprint");
// TODO there is no error on broken blueprint from a node
expect(serviceId).not.to.be.undefined;
});
it.skip("add_provider", async function () {
this.timeout(30000);
const client = await createConnectedClient(dev[2].multiaddr);
let key = Math.random().toString(36).substring(7);
let buf = Buffer.from(key)
let r = Math.random().toString(36).substring(7);
await addProvider(client, buf, dev[2].peerId, r);
let pr = await getProviders(client, buf);
console.log(pr)
console.log(r)
expect(r).to.be.equal(pr[0][0].service_id);
});
it.skip('add and remove script', async function () {
this.timeout(30000);
const client = await createConnectedClient(dev[3].multiaddr);
console.log("peerid: " + client.selfPeerId)
let script = `
(seq
(call "${client.relayPeerId}" ("op" "identity") [])
(call "${client.selfPeerId}" ("test" "test1") ["1" "2" "3"] result)
)
`;
let resMakingPromise = new Promise((resolve) => {
client.registerCallback('test', 'test1', (args, _) => {
resolve([...args]);
return {};
});
});
let scriptId = await addScript(client, script);
await resMakingPromise.then((args) => {
console.log("final!")
expect(args as string[]).to.be.deep.equal(["1", "2", "3"]);
}).finally(() => {
removeScript(client, scriptId);
})
expect(scriptId).not.to.be.undefined;
}); });
it.skip('fetch should work', async function () { it.skip('fetch should work', async function () {

View File

@ -56,7 +56,7 @@ const requestResponse = async <T>(
) )
`; `;
const res = await sendParticleAsFetch<any[]>(client, new Particle(script, data, ttl), ''); const res = await sendParticleAsFetch<any[]>(client, new Particle(script, data, ttl), name);
return handleResponse(res); return handleResponse(res);
}; };
@ -66,11 +66,12 @@ const requestResponse = async <T>(
* @returns { Array<string> } - list of available modules on the connected relay * @returns { Array<string> } - list of available modules on the connected relay
*/ */
export const getModules = async (client: FluenceClient): Promise<string[]> => { export const getModules = async (client: FluenceClient): Promise<string[]> => {
let callbackFn = "getModules"
const particle = new Particle( const particle = new Particle(
` `
(seq (seq
(call __relay ("dist" "get_modules") [] result) (call __relay ("dist" "get_modules") [] result)
(call myPeerId ("_callback" "getModules") [result]) (call myPeerId ("_callback" "${callbackFn}") [result])
) )
`, `,
{ {
@ -79,7 +80,30 @@ export const getModules = async (client: FluenceClient): Promise<string[]> => {
}, },
); );
return sendParticleAsFetch(client, particle, 'getModules'); return sendParticleAsFetch(client, particle, callbackFn);
};
/**
* Get all available modules hosted on a connected relay. @deprecated prefer using raw Particles instead
* @param { FluenceClient } client - The Fluence Client instance.
* @returns { Array<string> } - list of available modules on the connected relay
*/
export const getInterfaces = async (client: FluenceClient): Promise<string[]> => {
let callbackFn = "getInterfaces"
const particle = new Particle(
`
(seq
(call __relay ("srv" "get_interfaces") [] result)
(call myPeerId ("_callback" "${callbackFn}") [result])
)
`,
{
__relay: client.relayPeerId,
myPeerId: client.selfPeerId,
},
);
return sendParticleAsFetch(client, particle, callbackFn);
}; };
/** /**
@ -94,7 +118,7 @@ export const uploadModule = async (
name: string, name: string,
moduleBase64: string, moduleBase64: string,
config?: ModuleConfig, config?: ModuleConfig,
): Promise<string[]> => { ): Promise<void> => {
if (!config) { if (!config) {
config = { config = {
name: name, name: name,
@ -122,7 +146,7 @@ export const uploadModule = async (
) )
`; `;
return sendParticleAsFetch(client, new Particle(script, data), 'result'); return sendParticleAsFetch(client, new Particle(script, data), 'getModules', "_callback");
}; };
/** /**
@ -197,10 +221,11 @@ export const createService = async (
* Get all available blueprints hosted on a connected relay. @deprecated prefer using raw Particles instead * Get all available blueprints hosted on a connected relay. @deprecated prefer using raw Particles instead
* @param { FluenceClient } client - The Fluence Client instance. * @param { FluenceClient } client - The Fluence Client instance.
* @param {[string]} nodeId - Optional node peer id to get available blueprints from * @param {[string]} nodeId - Optional node peer id to get available blueprints from
* @param {[string]} nodeId - Optional node peer id to deploy service to
* @param {[number]} ttl - Optional ttl for the particle which does the job * @param {[number]} ttl - Optional ttl for the particle which does the job
* @returns { Array<string> } - List of available blueprints * @returns { Array<string> } - List of available blueprints
*/ */
export const getBlueprints = async (client: FluenceClient, nodeId: string, ttl?: number): Promise<string[]> => { export const getBlueprints = async (client: FluenceClient, nodeId?: string, ttl?: number): Promise<string[]> => {
let returnValue = 'blueprints'; let returnValue = 'blueprints';
let call = (nodeId: string) => `(call "${nodeId}" ("dist" "get_blueprints") [] ${returnValue})`; let call = (nodeId: string) => `(call "${nodeId}" ("dist" "get_blueprints") [] ${returnValue})`;
@ -246,6 +271,7 @@ export const addProvider = async (
/** /**
* Get a provider from DHT network from neighborhood around a key. @deprecated prefer using raw Particles instead * Get a provider from DHT network from neighborhood around a key. @deprecated prefer using raw Particles instead
* @param { FluenceClient } client - The Fluence Client instance. * @param { FluenceClient } client - The Fluence Client instance.
* @param {[buffer]} key - get provider by this key
* @param {[string]} nodeId - Optional node peer id to get providers from * @param {[string]} nodeId - Optional node peer id to get providers from
* @param {[number]} ttl - Optional ttl for the particle which does the job * @param {[number]} ttl - Optional ttl for the particle which does the job
* @returns { Array<object> } - List of providers * @returns { Array<object> } - List of providers
@ -269,12 +295,51 @@ export const getProviders = async (client: FluenceClient, key: Buffer, nodeId?:
* @param {[number]} ttl - Optional ttl for the particle which does the job * @param {[number]} ttl - Optional ttl for the particle which does the job
* @returns { Array<string> } - List of peer ids of neighbors of the node * @returns { Array<string> } - List of peer ids of neighbors of the node
*/ */
export const neighborhood = async (client: FluenceClient, node: string, ttl?: number): Promise<string[]> => { export const neighborhood = async (client: FluenceClient, nodeId?: string, ttl?: number): Promise<string[]> => {
let returnValue = 'neighborhood'; let returnValue = 'neighborhood';
let call = (nodeId: string) => `(call "${nodeId}" ("dht" "neighborhood") [node] ${returnValue})`; let call = (nodeId: string) => `(call "${nodeId}" ("dht" "neighborhood") [node] ${returnValue})`;
let data = new Map(); let data = new Map();
data.set('node', node); if (nodeId) data.set('node', nodeId);
return requestResponse(client, 'neighborhood', call, returnValue, data, (args) => args[0] as string[], node, ttl); return requestResponse(client, 'neighborhood', call, returnValue, data, (args) => args[0] as string[], nodeId, ttl);
};
/**
* Upload an AIR script, that will be runned in a loop on a node. @deprecated prefer using raw Particles instead
* @param { FluenceClient } client - The Fluence Client instance.
* @param {[string]} script - script to upload
* @param period how often start script processing, in seconds
* @param {[string]} nodeId - Optional node peer id to get neighborhood from
* @param {[number]} ttl - Optional ttl for the particle which does the job
* @returns {[string]} - script id
*/
export const addScript = async (client: FluenceClient, script: string, period?: number, nodeId?: string, ttl?: number): Promise<string> => {
let returnValue = 'id';
let periodV = ""
if (period) periodV = period.toString()
let call = (nodeId: string) => `(call "${nodeId}" ("script" "add") [script ${periodV}] ${returnValue})`;
let data = new Map();
data.set('script', script);
if (period) data.set('period', period)
return requestResponse(client, 'addScript', call, returnValue, data, (args) => args[0] as string, nodeId, ttl);
};
/**
* Remove an AIR script from a node. @deprecated prefer using raw Particles instead
* @param { FluenceClient } client - The Fluence Client instance.
* @param {[string]} id - id of a script
* @param {[string]} nodeId - Optional node peer id to get neighborhood from
* @param {[number]} ttl - Optional ttl for the particle which does the job
*/
export const removeScript = async (client: FluenceClient, id: string, nodeId?: string, ttl?: number): Promise<void> => {
let returnValue = 'empty';
let call = (nodeId: string) => `(call "${nodeId}" ("script" "remove") [script_id] ${returnValue})`;
let data = new Map();
data.set('script_id', id);
return requestResponse(client, 'removeScript', call, returnValue, data, (args) => {}, nodeId, ttl);
}; };