mirror of
https://github.com/fluencelabs/fluent-pad
synced 2025-04-26 09:12:15 +00:00
fluence js sdk api demos
This commit is contained in:
parent
09c34a1774
commit
b45caed0a1
78
src/demo/1_asyncCall.tsx
Normal file
78
src/demo/1_asyncCall.tsx
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
// import fluence from 'fluence';
|
||||||
|
|
||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
|
||||||
|
const fluence: any = {
|
||||||
|
call: (script, args, timeout) => {
|
||||||
|
// register particle id,
|
||||||
|
// build particle
|
||||||
|
// listen on "ack" service
|
||||||
|
|
||||||
|
return new Promise((resolve, rejects) => {
|
||||||
|
// if received "ack" "particle_id"
|
||||||
|
// resolve with the result
|
||||||
|
// if "particle_id" timed out reject
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
interface Product {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
sku: string;
|
||||||
|
description: string;
|
||||||
|
reviews: Review[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Review {
|
||||||
|
id: string;
|
||||||
|
productId: string;
|
||||||
|
author: string;
|
||||||
|
text: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const getProductInfo = async (): Promise<Product[]> => {
|
||||||
|
const timeout = 1000;
|
||||||
|
const script = `
|
||||||
|
(seq
|
||||||
|
(call %init_peer_relay% ("op" "identity") [])
|
||||||
|
(seq
|
||||||
|
(call productsNode (productsService "get_products") [] products)
|
||||||
|
(seq
|
||||||
|
(call reviewsNode (reviewsService "get_reviews") [] reviews)
|
||||||
|
(call %init_peer_id% ("ack" %particle_id%) [products reviews])
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)`;
|
||||||
|
|
||||||
|
const params = {
|
||||||
|
productsNode: '123', // probably discovered
|
||||||
|
productsService: 'org.acme/products@v1', // probably discovered
|
||||||
|
|
||||||
|
reviewsNode: '123', // probably discovered
|
||||||
|
reviewsService: 'org.acme/revires@v1', // probably discovered
|
||||||
|
};
|
||||||
|
|
||||||
|
const [products, reviews] = await fluence.call(script, params, timeout);
|
||||||
|
return products.join().with(reviews);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const DemoComponent = () => {
|
||||||
|
const [products, setProducts] = useState<Product[]>([]);
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
useEffect(() => {
|
||||||
|
setIsLoading(true);
|
||||||
|
getProductInfo()
|
||||||
|
.then((data) => {
|
||||||
|
setProducts(data);
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
// catch timeout here
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
setIsLoading(false);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return <div>{isLoading && <div>.. render products here {products.length}</div>}</div>;
|
||||||
|
};
|
106
src/demo/2_eventStream.tsx
Normal file
106
src/demo/2_eventStream.tsx
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
// import fluence from 'fluence';
|
||||||
|
|
||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
|
||||||
|
const fluence: any = {
|
||||||
|
on: (channel: string, handler) => {
|
||||||
|
// add subscription
|
||||||
|
},
|
||||||
|
|
||||||
|
registerEvent: (channel: string, eventName: string, validate?: (args: any[], tetraplets: any[][]) => boolean) => {
|
||||||
|
const registry: any = null;
|
||||||
|
const pushEvent: any = null;
|
||||||
|
|
||||||
|
const s = registry.getService(channel);
|
||||||
|
s.registerFunction(eventName, (args: any[], tetraplets: any[][]) => {
|
||||||
|
if (validate && validate(args, tetraplets)) {
|
||||||
|
// don't block
|
||||||
|
setImmediate(() => {
|
||||||
|
pushEvent(channel, {
|
||||||
|
type: eventName,
|
||||||
|
args: args,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
error: 'something',
|
||||||
|
};
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
fluence.registerEvent('users', 'join', (args: any[], tetraplets) => {
|
||||||
|
return args.length === 1 && args[0].is().guid() && args[1].is().string();
|
||||||
|
});
|
||||||
|
|
||||||
|
fluence.registerEvent('users', 'leave', (args: any[], tetraplets) => {
|
||||||
|
return args.length === 1 && args[0].is().guid();
|
||||||
|
});
|
||||||
|
|
||||||
|
interface User {
|
||||||
|
id: string; // guid,
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DemoComponent = () => {
|
||||||
|
const [users, setUsers] = useState<User[]>([]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fluence.on('users', (msg) => {
|
||||||
|
if (msg.type === 'join') {
|
||||||
|
setUsers((prev) => [
|
||||||
|
...prev,
|
||||||
|
{
|
||||||
|
id: msg.args[0],
|
||||||
|
name: msg.args[1],
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg.type === 'leave') {
|
||||||
|
setUsers((prev) => prev.filter((x) => x.id !== msg.args[0]));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<ul>
|
||||||
|
{users.map((x) => (
|
||||||
|
<li key={x.id}>
|
||||||
|
<div>{x.id}</div>
|
||||||
|
<div>{x.name}</div>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
// RxJS
|
||||||
|
|
||||||
|
const Observable: any = null;
|
||||||
|
|
||||||
|
const users = Observable.create((observer) => {
|
||||||
|
fluence.on('users', (msg) => {
|
||||||
|
observer.next(msg);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// ELM
|
||||||
|
|
||||||
|
const app: any = null;
|
||||||
|
|
||||||
|
fluence.on('users', (msg) => {
|
||||||
|
app.ports.eventReceiver.send(msg.type, msg.args);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Redux
|
||||||
|
|
||||||
|
const store: any = null;
|
||||||
|
|
||||||
|
fluence.on('users', (msg) => {
|
||||||
|
store.dispatch(msg);
|
||||||
|
});
|
59
src/demo/3_service.tsx
Normal file
59
src/demo/3_service.tsx
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
// import fluence, { Service, Function } from 'fluence';
|
||||||
|
|
||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
|
||||||
|
abstract class FluenceService {
|
||||||
|
abstract create();
|
||||||
|
abstract destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
const registry: any = null;
|
||||||
|
|
||||||
|
const Service: any = (serviceId) => (constructor) => {
|
||||||
|
constructor.serviceId = serviceId;
|
||||||
|
|
||||||
|
constructor.create = () => {
|
||||||
|
registry.registerService(serviceId, this);
|
||||||
|
};
|
||||||
|
|
||||||
|
constructor.destroy = () => {
|
||||||
|
registry.deleteService(serviceId);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const Function: any = (fnName) => (obj, fn) => {
|
||||||
|
const s = registry.getService(obj.serviceId);
|
||||||
|
s.registerFunction(fnName, fn);
|
||||||
|
};
|
||||||
|
|
||||||
|
@Service('calc_service')
|
||||||
|
export class CalcService {
|
||||||
|
@Function('add')
|
||||||
|
add(a: number, b: number) {
|
||||||
|
return {
|
||||||
|
result: a + b,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Function('mul')
|
||||||
|
mul(a: number, b: number) {
|
||||||
|
return {
|
||||||
|
result: a * b,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const useFluenceService = <T extends FluenceService>() => {
|
||||||
|
const [service, setService] = useState<T>();
|
||||||
|
useEffect(() => {
|
||||||
|
const service: T = undefined as any;
|
||||||
|
setService(service);
|
||||||
|
service.create();
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
service.destroy();
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return service;
|
||||||
|
};
|
76
src/demo/4_grapgql_adapter.tsx
Normal file
76
src/demo/4_grapgql_adapter.tsx
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
// import fluence from 'fluence';
|
||||||
|
|
||||||
|
const useQuery: any = null;
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
graphql
|
||||||
|
|
||||||
|
type Product {
|
||||||
|
id: String!
|
||||||
|
name: String!
|
||||||
|
sku: String!
|
||||||
|
description: String!
|
||||||
|
}
|
||||||
|
|
||||||
|
type Review {
|
||||||
|
id: String!
|
||||||
|
productId: String!
|
||||||
|
author: String!
|
||||||
|
text: String!
|
||||||
|
appearsIn: [Product!]!
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
adapter
|
||||||
|
|
||||||
|
type(Product)
|
||||||
|
.resolvedByService('products_service')
|
||||||
|
.onNode('123')
|
||||||
|
.hasMane(Review)
|
||||||
|
.on('reviews')
|
||||||
|
.equalTo('id');
|
||||||
|
|
||||||
|
type(Review)
|
||||||
|
.resolvedByService('reviews_service')
|
||||||
|
.onNode('987');
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
interface Product {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
sku: string;
|
||||||
|
description: string;
|
||||||
|
reviews: Review[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Review {
|
||||||
|
id: string;
|
||||||
|
productId: string;
|
||||||
|
author: string;
|
||||||
|
text: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DemoComponent = () => {
|
||||||
|
const { isLoading, error, data } = useQuery(`
|
||||||
|
{
|
||||||
|
Product {
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
sku,
|
||||||
|
description
|
||||||
|
reviews: {
|
||||||
|
id,
|
||||||
|
author,
|
||||||
|
text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
|
||||||
|
return <div>{isLoading && <div>.. render products here {data.products.length}</div>}</div>;
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user