Skip to content

Commit 481a44b

Browse files
authored
Add remove scripts, fix builtins (#15)
1 parent e4d3f68 commit 481a44b

File tree

4 files changed

+196
-21
lines changed

4 files changed

+196
-21
lines changed

package-lock.json

Lines changed: 6 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@fluencelabs/fluence",
3-
"version": "0.9.9",
3+
"version": "0.9.13",
44
"description": "JS SDK for the Fluence network",
55
"main": "./dist/index.js",
66
"typings": "./dist/index.d.ts",
@@ -15,6 +15,7 @@
1515
"dependencies": {
1616
"@fluencelabs/aquamarine-stepper": "0.3.4",
1717
"async": "3.2.0",
18+
"@fluencelabs/fluence-network-environment": "1.0.8",
1819
"base64-js": "1.3.1",
1920
"bs58": "4.0.1",
2021
"cids": "0.8.1",

src/__test__/client.spec.ts

Lines changed: 114 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,20 @@ import { TrustGraph } from '../internal/trust/trust_graph';
77
import { nodeRootCert } from '../internal/trust/misc';
88
import { generatePeerId, peerIdToSeed, seedToPeerId } from '../internal/peerIdUtils';
99
import { FluenceClientImpl } from '../internal/FluenceClientImpl';
10-
import { createConnectedClient, createLocalClient } from './util';
10+
import { createConnectedClient } from './util';
1111
import log from 'loglevel';
1212
import { createClient } from '../api';
1313
import Multiaddr from 'multiaddr';
14-
import { getModules } from '../internal/builtins';
14+
import {
15+
addBlueprint, addProvider,
16+
addScript,
17+
createService,
18+
getBlueprints, getInterfaces,
19+
getModules, getProviders,
20+
removeScript,
21+
uploadModule
22+
} from '../internal/builtins';
23+
import {dev} from "@fluencelabs/fluence-network-environment";
1524

1625
const devNodeAddress = '/dns4/dev.fluence.dev/tcp/19001/wss/p2p/12D3KooWEXNUbCXooUwHrHBbrmjsrpHXoEphPwbjQXEGyzbqKnE9';
1726
const devNodePeerId = '12D3KooWEXNUbCXooUwHrHBbrmjsrpHXoEphPwbjQXEGyzbqKnE9';
@@ -146,7 +155,7 @@ describe('Typescript usage suite', () => {
146155
it.skip('should make a call through the network', async function () {
147156
this.timeout(30000);
148157
// arrange
149-
const client = await createConnectedClient(devNodeAddress);
158+
const client = await createConnectedClient(dev[0].multiaddr);
150159

151160
client.registerCallback('test', 'test', (args, _) => {
152161
log.trace('should make a call through the network, called "test" "test" with args', args);
@@ -214,16 +223,111 @@ describe('Typescript usage suite', () => {
214223
expect(res).to.deep.equal(['some d', 'some c', 'some b', 'some a']);
215224
});
216225

217-
it.skip('add_module', async function () {
226+
it.skip('get_modules', async function () {
218227
this.timeout(30000);
219-
// arrange
220-
const client = await createConnectedClient(
221-
'/dns4/dev.fluence.dev/tcp/19003/wss/p2p/12D3KooWBUJifCTgaxAUrcM9JysqCcS4CS8tiYH5hExbdWCAoNwb',
222-
);
228+
const client = await createConnectedClient(dev[2].multiaddr);
229+
230+
let modulesList = await getModules(client);
231+
232+
expect(modulesList).not.to.be.undefined;
233+
});
234+
235+
it.skip('get_interfaces', async function () {
236+
this.timeout(30000);
237+
const client = await createConnectedClient(dev[2].multiaddr);
238+
239+
let interfaces = await getInterfaces(client);
240+
241+
expect(interfaces).not.to.be.undefined;
242+
});
243+
244+
it.skip('get_blueprints', async function () {
245+
this.timeout(30000);
246+
const client = await createConnectedClient(dev[2].multiaddr);
247+
248+
let bpList = await getBlueprints(client);
249+
250+
expect(bpList).not.to.be.undefined;
251+
});
252+
253+
it.skip("upload_modules", async function () {
254+
this.timeout(30000);
255+
const client = await createConnectedClient(dev[2].multiaddr);
256+
257+
console.log("peerid: " + client.selfPeerId)
258+
259+
let base64 = "MjNy"
260+
261+
await uploadModule(client, "test_broken_module", base64);
262+
});
263+
264+
it.skip("add_blueprint", async function () {
265+
this.timeout(30000);
266+
const client = await createConnectedClient(dev[2].multiaddr);
267+
268+
let bpId = "some"
269+
270+
let bpIdReturned = await addBlueprint(client, "test_broken_blueprint", ["test_broken_module"], bpId);
271+
272+
expect(bpIdReturned).to.be.equal(bpId);
273+
});
274+
275+
it.skip("create_service", async function () {
276+
this.timeout(30000);
277+
const client = await createConnectedClient(dev[2].multiaddr);
278+
279+
let serviceId = await createService(client, "test_broken_blueprint");
280+
281+
// TODO there is no error on broken blueprint from a node
282+
expect(serviceId).not.to.be.undefined;
283+
});
284+
285+
it.skip("add_provider", async function () {
286+
this.timeout(30000);
287+
const client = await createConnectedClient(dev[2].multiaddr);
288+
289+
let key = Math.random().toString(36).substring(7);
290+
let buf = Buffer.from(key)
291+
292+
let r = Math.random().toString(36).substring(7);
293+
await addProvider(client, buf, dev[2].peerId, r);
294+
295+
let pr = await getProviders(client, buf);
296+
console.log(pr)
297+
console.log(r)
298+
expect(r).to.be.equal(pr[0][0].service_id);
299+
});
300+
301+
it.skip('add and remove script', async function () {
302+
this.timeout(30000);
303+
const client = await createConnectedClient(dev[3].multiaddr);
304+
305+
console.log("peerid: " + client.selfPeerId)
306+
307+
let script = `
308+
(seq
309+
(call "${client.relayPeerId}" ("op" "identity") [])
310+
(call "${client.selfPeerId}" ("test" "test1") ["1" "2" "3"] result)
311+
)
312+
`;
313+
314+
let resMakingPromise = new Promise((resolve) => {
315+
client.registerCallback('test', 'test1', (args, _) => {
316+
resolve([...args]);
317+
return {};
318+
});
319+
});
320+
321+
let scriptId = await addScript(client, script);
223322

224-
let a = await getModules(client);
323+
await resMakingPromise.then((args) => {
324+
console.log("final!")
325+
expect(args as string[]).to.be.deep.equal(["1", "2", "3"]);
326+
}).finally(() => {
327+
removeScript(client, scriptId);
328+
})
225329

226-
expect(a).not.to.be.undefined;
330+
expect(scriptId).not.to.be.undefined;
227331
});
228332

229333
it.skip('fetch should work', async function () {

src/internal/builtins.ts

Lines changed: 74 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ const requestResponse = async <T>(
5656
)
5757
`;
5858

59-
const res = await sendParticleAsFetch<any[]>(client, new Particle(script, data, ttl), '');
59+
const res = await sendParticleAsFetch<any[]>(client, new Particle(script, data, ttl), name);
6060
return handleResponse(res);
6161
};
6262

@@ -66,11 +66,12 @@ const requestResponse = async <T>(
6666
* @returns { Array<string> } - list of available modules on the connected relay
6767
*/
6868
export const getModules = async (client: FluenceClient): Promise<string[]> => {
69+
let callbackFn = "getModules"
6970
const particle = new Particle(
7071
`
7172
(seq
7273
(call __relay ("dist" "get_modules") [] result)
73-
(call myPeerId ("_callback" "getModules") [result])
74+
(call myPeerId ("_callback" "${callbackFn}") [result])
7475
)
7576
`,
7677
{
@@ -79,7 +80,30 @@ export const getModules = async (client: FluenceClient): Promise<string[]> => {
7980
},
8081
);
8182

82-
return sendParticleAsFetch(client, particle, 'getModules');
83+
return sendParticleAsFetch(client, particle, callbackFn);
84+
};
85+
86+
/**
87+
* Get all available modules hosted on a connected relay. @deprecated prefer using raw Particles instead
88+
* @param { FluenceClient } client - The Fluence Client instance.
89+
* @returns { Array<string> } - list of available modules on the connected relay
90+
*/
91+
export const getInterfaces = async (client: FluenceClient): Promise<string[]> => {
92+
let callbackFn = "getInterfaces"
93+
const particle = new Particle(
94+
`
95+
(seq
96+
(call __relay ("srv" "get_interfaces") [] result)
97+
(call myPeerId ("_callback" "${callbackFn}") [result])
98+
)
99+
`,
100+
{
101+
__relay: client.relayPeerId,
102+
myPeerId: client.selfPeerId,
103+
},
104+
);
105+
106+
return sendParticleAsFetch(client, particle, callbackFn);
83107
};
84108

85109
/**
@@ -94,7 +118,7 @@ export const uploadModule = async (
94118
name: string,
95119
moduleBase64: string,
96120
config?: ModuleConfig,
97-
): Promise<string[]> => {
121+
): Promise<void> => {
98122
if (!config) {
99123
config = {
100124
name: name,
@@ -122,7 +146,7 @@ export const uploadModule = async (
122146
)
123147
`;
124148

125-
return sendParticleAsFetch(client, new Particle(script, data), 'result');
149+
return sendParticleAsFetch(client, new Particle(script, data), 'getModules', "_callback");
126150
};
127151

128152
/**
@@ -197,10 +221,11 @@ export const createService = async (
197221
* Get all available blueprints hosted on a connected relay. @deprecated prefer using raw Particles instead
198222
* @param { FluenceClient } client - The Fluence Client instance.
199223
* @param {[string]} nodeId - Optional node peer id to get available blueprints from
224+
* @param {[string]} nodeId - Optional node peer id to deploy service to
200225
* @param {[number]} ttl - Optional ttl for the particle which does the job
201226
* @returns { Array<string> } - List of available blueprints
202227
*/
203-
export const getBlueprints = async (client: FluenceClient, nodeId: string, ttl?: number): Promise<string[]> => {
228+
export const getBlueprints = async (client: FluenceClient, nodeId?: string, ttl?: number): Promise<string[]> => {
204229
let returnValue = 'blueprints';
205230
let call = (nodeId: string) => `(call "${nodeId}" ("dist" "get_blueprints") [] ${returnValue})`;
206231

@@ -246,6 +271,7 @@ export const addProvider = async (
246271
/**
247272
* Get a provider from DHT network from neighborhood around a key. @deprecated prefer using raw Particles instead
248273
* @param { FluenceClient } client - The Fluence Client instance.
274+
* @param {[buffer]} key - get provider by this key
249275
* @param {[string]} nodeId - Optional node peer id to get providers from
250276
* @param {[number]} ttl - Optional ttl for the particle which does the job
251277
* @returns { Array<object> } - List of providers
@@ -269,12 +295,51 @@ export const getProviders = async (client: FluenceClient, key: Buffer, nodeId?:
269295
* @param {[number]} ttl - Optional ttl for the particle which does the job
270296
* @returns { Array<string> } - List of peer ids of neighbors of the node
271297
*/
272-
export const neighborhood = async (client: FluenceClient, node: string, ttl?: number): Promise<string[]> => {
298+
export const neighborhood = async (client: FluenceClient, nodeId?: string, ttl?: number): Promise<string[]> => {
273299
let returnValue = 'neighborhood';
274300
let call = (nodeId: string) => `(call "${nodeId}" ("dht" "neighborhood") [node] ${returnValue})`;
275301

276302
let data = new Map();
277-
data.set('node', node);
303+
if (nodeId) data.set('node', nodeId);
304+
305+
return requestResponse(client, 'neighborhood', call, returnValue, data, (args) => args[0] as string[], nodeId, ttl);
306+
};
307+
308+
/**
309+
* Upload an AIR script, that will be runned in a loop on a node. @deprecated prefer using raw Particles instead
310+
* @param { FluenceClient } client - The Fluence Client instance.
311+
* @param {[string]} script - script to upload
312+
* @param period how often start script processing, in seconds
313+
* @param {[string]} nodeId - Optional node peer id to get neighborhood from
314+
* @param {[number]} ttl - Optional ttl for the particle which does the job
315+
* @returns {[string]} - script id
316+
*/
317+
export const addScript = async (client: FluenceClient, script: string, period?: number, nodeId?: string, ttl?: number): Promise<string> => {
318+
let returnValue = 'id';
319+
let periodV = ""
320+
if (period) periodV = period.toString()
321+
let call = (nodeId: string) => `(call "${nodeId}" ("script" "add") [script ${periodV}] ${returnValue})`;
322+
323+
let data = new Map();
324+
data.set('script', script);
325+
if (period) data.set('period', period)
326+
327+
return requestResponse(client, 'addScript', call, returnValue, data, (args) => args[0] as string, nodeId, ttl);
328+
};
329+
330+
/**
331+
* Remove an AIR script from a node. @deprecated prefer using raw Particles instead
332+
* @param { FluenceClient } client - The Fluence Client instance.
333+
* @param {[string]} id - id of a script
334+
* @param {[string]} nodeId - Optional node peer id to get neighborhood from
335+
* @param {[number]} ttl - Optional ttl for the particle which does the job
336+
*/
337+
export const removeScript = async (client: FluenceClient, id: string, nodeId?: string, ttl?: number): Promise<void> => {
338+
let returnValue = 'empty';
339+
let call = (nodeId: string) => `(call "${nodeId}" ("script" "remove") [script_id] ${returnValue})`;
340+
341+
let data = new Map();
342+
data.set('script_id', id);
278343

279-
return requestResponse(client, 'neighborhood', call, returnValue, data, (args) => args[0] as string[], node, ttl);
344+
return requestResponse(client, 'removeScript', call, returnValue, data, (args) => {}, nodeId, ttl);
280345
};

0 commit comments

Comments
 (0)