mirror of
https://github.com/fluencelabs/registry-demo
synced 2025-04-24 16:02:12 +00:00
Initial implementation (#1)
This commit is contained in:
parent
3a0e71f892
commit
f31ce64c9c
26
.gitignore
vendored
Normal file
26
.gitignore
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
bundle/
|
||||
/dist/
|
||||
/worker/dist/
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
.idea
|
||||
|
||||
# fluence
|
||||
|
||||
public/*.wasm
|
||||
public/runnerScript.web.js
|
||||
|
||||
src/_aqua
|
8
.prettierrc.js
Normal file
8
.prettierrc.js
Normal file
@ -0,0 +1,8 @@
|
||||
module.exports = {
|
||||
semi: true,
|
||||
trailingComma: 'all',
|
||||
singleQuote: true,
|
||||
printWidth: 120,
|
||||
tabWidth: 4,
|
||||
useTabs: false,
|
||||
};
|
3
aqua/export.aqua
Normal file
3
aqua/export.aqua
Normal file
@ -0,0 +1,3 @@
|
||||
module Export
|
||||
import createMyRoute, DiscoveryService, discoverAndNotify from "hello-registry.aqua"
|
||||
export createMyRoute, DiscoveryService, discoverAndNotify
|
32
aqua/hello-registry.aqua
Normal file
32
aqua/hello-registry.aqua
Normal file
@ -0,0 +1,32 @@
|
||||
module HelloRegistry declares createMyRoute, DiscoveryService, discoverAndNotify
|
||||
|
||||
import "@fluencelabs/registry/routing.aqua"
|
||||
import "@fluencelabs/aqua-lib/builtin.aqua"
|
||||
|
||||
alias PeerId: string
|
||||
alias RouteId: string
|
||||
|
||||
data DiscoveredUser:
|
||||
route: RouteId
|
||||
userName: string
|
||||
|
||||
service DiscoveryService("discoveryService"):
|
||||
notify_discovered(route_id: string, userName: string) -> []DiscoveredUser
|
||||
|
||||
func createMyRoute(label: string, userName: string) -> string:
|
||||
relay: ?string
|
||||
relay <<- HOST_PEER_ID
|
||||
res <- createRouteAndRegister(label, userName, relay, nil)
|
||||
DiscoveryService.notify_discovered(res, userName)
|
||||
<- res
|
||||
|
||||
func discoverAndNotify(join_route_id: string, label: string, userName: string) -> string, []DiscoveredUser:
|
||||
relay: ?string
|
||||
relay <<- HOST_PEER_ID
|
||||
our_route_id <- createRouteAndRegister(label, userName, relay, nil)
|
||||
|
||||
recs <- resolveRoute(join_route_id, 4)
|
||||
try:
|
||||
on recs[0].peer_id via recs[0].relay_id:
|
||||
peers <- DiscoveryService.notify_discovered(our_route_id, userName)
|
||||
<- our_route_id, peers
|
39
docs/_aqua/export.d.ts
vendored
Normal file
39
docs/_aqua/export.d.ts
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
/**
|
||||
*
|
||||
* This file is auto-generated. Do not edit manually: changes may be erased.
|
||||
* Generated by Aqua compiler: https://github.com/fluencelabs/aqua/.
|
||||
* If you find any bugs, please write an issue on GitHub: https://github.com/fluencelabs/aqua/issues
|
||||
* Aqua version: 0.6.1-279
|
||||
*
|
||||
*/
|
||||
import { FluencePeer } from '@fluencelabs/fluence';
|
||||
import { CallParams } from '@fluencelabs/fluence/dist/internal/compilerSupport/v2';
|
||||
export interface DiscoveryServiceDef {
|
||||
notify_discovered: (route_id: string, userName: string, callParams: CallParams<'route_id' | 'userName'>) => {
|
||||
route: string;
|
||||
userName: string;
|
||||
}[] | Promise<{
|
||||
route: string;
|
||||
userName: string;
|
||||
}[]>;
|
||||
}
|
||||
export declare function registerDiscoveryService(service: DiscoveryServiceDef): void;
|
||||
export declare function registerDiscoveryService(serviceId: string, service: DiscoveryServiceDef): void;
|
||||
export declare function registerDiscoveryService(peer: FluencePeer, service: DiscoveryServiceDef): void;
|
||||
export declare function registerDiscoveryService(peer: FluencePeer, serviceId: string, service: DiscoveryServiceDef): void;
|
||||
export declare function createMyRoute(label: string, userName: string, config?: {
|
||||
ttl?: number;
|
||||
}): Promise<string>;
|
||||
export declare function createMyRoute(peer: FluencePeer, label: string, userName: string, config?: {
|
||||
ttl?: number;
|
||||
}): Promise<string>;
|
||||
export declare type DiscoverAndNotifyResult = [string, {
|
||||
route: string;
|
||||
userName: string;
|
||||
}[]];
|
||||
export declare function discoverAndNotify(join_route_id: string, label: string, userName: string, config?: {
|
||||
ttl?: number;
|
||||
}): Promise<DiscoverAndNotifyResult>;
|
||||
export declare function discoverAndNotify(peer: FluencePeer, join_route_id: string, label: string, userName: string, config?: {
|
||||
ttl?: number;
|
||||
}): Promise<DiscoverAndNotifyResult>;
|
BIN
docs/avm.wasm
Executable file
BIN
docs/avm.wasm
Executable file
Binary file not shown.
3
docs/avmRunner.d.ts
vendored
Normal file
3
docs/avmRunner.d.ts
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
import { AvmRunnerBackground } from '@fluencelabs/avm-runner-background';
|
||||
declare const _default: AvmRunnerBackground;
|
||||
export default _default;
|
1
docs/index.d.ts
vendored
Normal file
1
docs/index.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
import './index.css';
|
1
docs/index.html
Normal file
1
docs/index.html
Normal file
@ -0,0 +1 @@
|
||||
<!doctype html><html><head><meta charset="utf-8"/><title>Registry demo</title><script defer="defer" src="main.js"></script></head><body><div id="app" class="hidden"><h1></h1><div>your peer id: <span id="peerid"></span></div><div><label>your name</label> <input id="name" value="my name"/></div><div id="ref-route-id-wrapper" class="hidden">reference route id: <span id="ref-route-id">route id here</span></div><div><button id="go">go!</button></div><div id="join-link-wrapper" class="hidden"><div>Join link: <span id="join-link"></span></div><canvas id="qrcode"/></div><div id="user-list-wrapper" class="hidden"><h1>users in room</h1><ul id="user-list"></ul></div></div><div id="loading">loading</div></body></html>
|
68
docs/index.js
Normal file
68
docs/index.js
Normal file
@ -0,0 +1,68 @@
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __generator = (this && this.__generator) || function (thisArg, body) {
|
||||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||
function step(op) {
|
||||
if (f) throw new TypeError("Generator is already executing.");
|
||||
while (_) try {
|
||||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||||
if (y = 0, t) op = [op[0] & 2, t.value];
|
||||
switch (op[0]) {
|
||||
case 0: case 1: t = op; break;
|
||||
case 4: _.label++; return { value: op[1], done: false };
|
||||
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||||
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||||
default:
|
||||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||||
if (t[2]) _.ops.pop();
|
||||
_.trys.pop(); continue;
|
||||
}
|
||||
op = body.call(thisArg, _);
|
||||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||||
}
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var avm_runner_background_1 = require("@fluencelabs/avm-runner-background");
|
||||
var js_base64_1 = require("js-base64");
|
||||
var vmPeerId = '12D3KooWNzutuy8WHXDKFqFsATvCR6j9cj2FijYbnd47geRKaQZS';
|
||||
var b = function (s) {
|
||||
return (0, js_base64_1.toUint8Array)(s);
|
||||
};
|
||||
var main = function () { return __awaiter(void 0, void 0, void 0, function () {
|
||||
var runner, s, params, res;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
runner = new avm_runner_background_1.AvmRunnerBackground();
|
||||
return [4 /*yield*/, runner.init('off')];
|
||||
case 1:
|
||||
_a.sent();
|
||||
s = "(seq\n (par \n (call \"".concat(vmPeerId, "\" (\"local_service_id\" \"local_fn_name\") [] result_1)\n (call \"remote_peer_id\" (\"service_id\" \"fn_name\") [] g)\n )\n (call \"").concat(vmPeerId, "\" (\"local_service_id\" \"local_fn_name\") [] result_2)\n )");
|
||||
params = { initPeerId: vmPeerId, currentPeerId: vmPeerId };
|
||||
return [4 /*yield*/, runner.run(s, b(''), b(''), params, [])];
|
||||
case 2:
|
||||
res = _a.sent();
|
||||
return [4 /*yield*/, runner.terminate()];
|
||||
case 3:
|
||||
_a.sent();
|
||||
return [2 /*return*/, res];
|
||||
}
|
||||
});
|
||||
}); };
|
||||
// @ts-ignore
|
||||
window.MAIN = main;
|
||||
//# sourceMappingURL=index.js.map
|
1
docs/index.js.map
Normal file
1
docs/index.js.map
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,4EAAyE;AACzE,uCAAyC;AAEzC,IAAM,QAAQ,GAAG,sDAAsD,CAAC;AAExE,IAAM,CAAC,GAAG,UAAC,CAAS;IAChB,OAAO,IAAA,wBAAY,EAAC,CAAC,CAAC,CAAC;AAC3B,CAAC,CAAC;AAEF,IAAM,IAAI,GAAG;;;;;gBACH,MAAM,GAAG,IAAI,2CAAmB,EAAE,CAAC;gBACzC,qBAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAA;;gBAAxB,SAAwB,CAAC;gBAEnB,CAAC,GAAG,2DAEW,QAAQ,uLAGZ,QAAQ,wEACnB,CAAC;gBAGD,MAAM,GAAG,EAAE,UAAU,EAAE,QAAQ,EAAE,aAAa,EAAE,QAAQ,EAAE,CAAC;gBACrD,qBAAM,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAA;;gBAAnD,GAAG,GAAG,SAA6C;gBACzD,qBAAM,MAAM,CAAC,SAAS,EAAE,EAAA;;gBAAxB,SAAwB,CAAC;gBAEzB,sBAAO,GAAG,EAAC;;;KACd,CAAC;AAEF,aAAa;AACb,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC"}
|
2
docs/main.js
Normal file
2
docs/main.js
Normal file
File diff suppressed because one or more lines are too long
36
docs/main.js.LICENSE.txt
Normal file
36
docs/main.js.LICENSE.txt
Normal file
@ -0,0 +1,36 @@
|
||||
/*!
|
||||
* Determine if an object is a Buffer
|
||||
*
|
||||
* @author Feross Aboukhadijeh <https://feross.org>
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
/*!
|
||||
* The buffer module from node.js, for the browser.
|
||||
*
|
||||
* @author Feross Aboukhadijeh <https://feross.org>
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
/*! *****************************************************************************
|
||||
Copyright (c) Microsoft Corporation.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
||||
***************************************************************************** */
|
||||
|
||||
/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh <https://feross.org/opensource> */
|
||||
|
||||
/*! noble-ed25519 - MIT License (c) Paul Miller (paulmillr.com) */
|
||||
|
||||
/*! noble-secp256k1 - MIT License (c) Paul Miller (paulmillr.com) */
|
||||
|
||||
/*! safe-buffer. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */
|
BIN
docs/marine-js.wasm
Normal file
BIN
docs/marine-js.wasm
Normal file
Binary file not shown.
871
docs/runnerScript.web.js
Normal file
871
docs/runnerScript.web.js
Normal file
File diff suppressed because one or more lines are too long
18
docs/util.d.ts
vendored
Normal file
18
docs/util.d.ts
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
import QRCode from 'qrcode';
|
||||
export declare function addClass(id: string, className: string): void;
|
||||
export declare function removeClass(id: string, className: string): void;
|
||||
export declare function hide(id: string): void;
|
||||
export declare function show(id: string): void;
|
||||
export declare function onClick(id: string, handler: (el: MouseEvent) => void): void;
|
||||
export declare function setText(id: string, text: string): void;
|
||||
export declare function getValue(id: string): any;
|
||||
export declare function createQrCode(targetId: string, link: string, opts: QRCode.QRCodeRenderersOptions): Promise<void>;
|
||||
export declare function disable(id: string): void;
|
||||
export declare function enable(id: string): void;
|
||||
export declare function link(id: string): string;
|
||||
interface DiscoveredUser {
|
||||
route: string;
|
||||
userName: string;
|
||||
}
|
||||
export declare function updateUserList(users: DiscoveredUser[]): Promise<void>;
|
||||
export {};
|
33
index.html
Normal file
33
index.html
Normal file
@ -0,0 +1,33 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Registry demo</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app" class="hidden">
|
||||
<h1></h1>
|
||||
<div>your peer id: <span id="peerid"></span></div>
|
||||
<div>
|
||||
<label>your name</label>
|
||||
<input type="text" id="name" value="my name" />
|
||||
</div>
|
||||
<div id="ref-route-id-wrapper" class="hidden">
|
||||
reference route id: <span id="ref-route-id">route id here</span>
|
||||
</div>
|
||||
<div>
|
||||
<button id="go">go!</button>
|
||||
</div>
|
||||
<div id="join-link-wrapper" class="hidden">
|
||||
<div>Join link: <span id="join-link"></span></div>
|
||||
<canvas id="qrcode" />
|
||||
</div>
|
||||
|
||||
<div id="user-list-wrapper" class="hidden">
|
||||
<h1>users in room</h1>
|
||||
<ul id="user-list"></ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="loading">loading</div>
|
||||
</body>
|
||||
</html>
|
23808
package-lock.json
generated
Normal file
23808
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
47
package.json
Normal file
47
package.json
Normal file
@ -0,0 +1,47 @@
|
||||
{
|
||||
"name": "registry-demo",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"postinstall": "copy-avm-public public",
|
||||
"start": "webpack serve",
|
||||
"prestart": "npm run compile-aqua",
|
||||
"prebuild": "npm run compile-aqua",
|
||||
"copy-public": "copy-avm public && copy-avm-runner public",
|
||||
"build": "webpack --mode=production --node-env=production",
|
||||
"build:dev": "webpack --mode=development",
|
||||
"build:prod": "webpack --mode=production --node-env=production",
|
||||
"watch": "webpack --watch",
|
||||
"serve": "webpack serve",
|
||||
"compile-aqua": "aqua -i ./aqua/ -o ./src/_aqua",
|
||||
"watch-aqua": "chokidar \"**/*.aqua\" -c \"npm run compile-aqua\"",
|
||||
"pages": "npm run build && cp -r ./dist/* ./docs && cp -r ./public/* ./docs"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@fluencelabs/avm-runner-background": "^0.2.0",
|
||||
"@fluencelabs/fluence": "^0.20.1",
|
||||
"@fluencelabs/fluence-network-environment": "^1.0.13",
|
||||
"process": "^0.11.10",
|
||||
"qrcode": "^1.5.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@fluencelabs/aqua": "^0.6.1-279",
|
||||
"@fluencelabs/registry": "^0.3.1",
|
||||
"@fluencelabs/aqua-lib": "^0.4.0",
|
||||
"@fluencelabs/marine-js": "^0.1.0",
|
||||
"@types/qrcode": "^1.4.2",
|
||||
"@webpack-cli/generators": "^2.4.1",
|
||||
"css-loader": "^6.5.1",
|
||||
"html-webpack-plugin": "^5.5.0",
|
||||
"style-loader": "^3.3.1",
|
||||
"ts-loader": "^8.3.0",
|
||||
"typescript": "^4.5.4",
|
||||
"util": "^0.12.4",
|
||||
"webpack": "^5.65.0",
|
||||
"webpack-cli": "^4.9.1",
|
||||
"webpack-dev-server": "^4.6.0"
|
||||
}
|
||||
}
|
10
src/avmRunner.ts
Normal file
10
src/avmRunner.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import { AvmRunnerBackground } from '@fluencelabs/avm-runner-background';
|
||||
|
||||
export default new AvmRunnerBackground({
|
||||
method: 'fetch-from-url',
|
||||
baseUrl: 'https://fluence.one/registry-demo/',
|
||||
filePaths: {
|
||||
avm: 'avm.wasm',
|
||||
marine: 'marine-js.wasm',
|
||||
},
|
||||
});
|
3
src/index.css
Normal file
3
src/index.css
Normal file
@ -0,0 +1,3 @@
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
97
src/index.ts
Normal file
97
src/index.ts
Normal file
@ -0,0 +1,97 @@
|
||||
import './index.css';
|
||||
|
||||
import { CallParams, Fluence } from '@fluencelabs/fluence';
|
||||
import { krasnodar } from '@fluencelabs/fluence-network-environment';
|
||||
import avmRunner from './avmRunner';
|
||||
import { createQrCode, disable, getValue, hide, link, onClick, setText, show, updateUserList } from './util';
|
||||
|
||||
import { createMyRoute, discoverAndNotify, registerDiscoveryService, DiscoveryServiceDef } from './_aqua/export';
|
||||
|
||||
const label = 'registry-demo';
|
||||
|
||||
let selfDiscoveryRouteId: string;
|
||||
let joinRouteId: string | null;
|
||||
|
||||
interface DiscoveredUser {
|
||||
route: string;
|
||||
userName: string;
|
||||
}
|
||||
|
||||
class DiscoveryService implements DiscoveryServiceDef {
|
||||
private _discoveredUsers: DiscoveredUser[] = [];
|
||||
|
||||
notify_discovered(route_id: string, userName: string): DiscoveredUser[] {
|
||||
if (this._discoveredUsers.every((x) => x.route !== route_id)) {
|
||||
this._discoveredUsers.push({
|
||||
userName: userName,
|
||||
route: route_id,
|
||||
});
|
||||
|
||||
if (this.onUpdated) {
|
||||
this.onUpdated(this._discoveredUsers);
|
||||
}
|
||||
}
|
||||
|
||||
return this._discoveredUsers;
|
||||
}
|
||||
|
||||
setInitialList(userList: DiscoveredUser[]) {
|
||||
this._discoveredUsers = userList;
|
||||
|
||||
if (this.onUpdated) {
|
||||
this.onUpdated(this._discoveredUsers);
|
||||
}
|
||||
}
|
||||
|
||||
onUpdated: ((users: DiscoveredUser[]) => void) | null = null;
|
||||
}
|
||||
|
||||
const discoveryServiceInstance = new DiscoveryService();
|
||||
|
||||
discoveryServiceInstance.onUpdated = updateUserList;
|
||||
|
||||
async function main() {
|
||||
await Fluence.start({
|
||||
avmRunner: avmRunner,
|
||||
connectTo: krasnodar[4],
|
||||
});
|
||||
|
||||
registerDiscoveryService(discoveryServiceInstance);
|
||||
|
||||
const selfPeerId = Fluence.getStatus().peerId!;
|
||||
setText('peerid', selfPeerId);
|
||||
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
joinRouteId = params.get('join');
|
||||
|
||||
if (joinRouteId) {
|
||||
setText('ref-route-id', joinRouteId);
|
||||
show('ref-route-id-wrapper');
|
||||
}
|
||||
|
||||
hide('loading');
|
||||
show('app');
|
||||
}
|
||||
|
||||
onClick('go', async () => {
|
||||
disable('go');
|
||||
|
||||
const myName = getValue('name');
|
||||
|
||||
if (joinRouteId) {
|
||||
const [routeId, knownUsers] = await discoverAndNotify(joinRouteId, label, myName);
|
||||
discoveryServiceInstance.setInitialList(knownUsers);
|
||||
selfDiscoveryRouteId = routeId;
|
||||
} else {
|
||||
selfDiscoveryRouteId = await createMyRoute(label, myName);
|
||||
}
|
||||
|
||||
setText('join-link', link(selfDiscoveryRouteId));
|
||||
await createQrCode('qrcode', link(selfDiscoveryRouteId), { width: 480 });
|
||||
|
||||
hide('ref-route-id-wrapper');
|
||||
show('join-link-wrapper');
|
||||
show('user-list-wrapper');
|
||||
});
|
||||
|
||||
main();
|
81
src/util.ts
Normal file
81
src/util.ts
Normal file
@ -0,0 +1,81 @@
|
||||
import QRCode from 'qrcode';
|
||||
|
||||
export function addClass(id: string, className: string) {
|
||||
const el = document.getElementById(id)!;
|
||||
el.classList.add(className);
|
||||
}
|
||||
|
||||
export function removeClass(id: string, className: string) {
|
||||
const el = document.getElementById(id)!;
|
||||
el.classList.remove(className);
|
||||
}
|
||||
|
||||
export function hide(id: string) {
|
||||
addClass(id, 'hidden');
|
||||
}
|
||||
|
||||
export function show(id: string) {
|
||||
removeClass(id, 'hidden');
|
||||
}
|
||||
|
||||
export function onClick(id: string, handler: (el: MouseEvent) => void) {
|
||||
const el = document.getElementById(id)!;
|
||||
el.onclick = handler;
|
||||
}
|
||||
|
||||
export function setText(id: string, text: string) {
|
||||
const el = document.getElementById(id)!;
|
||||
el.textContent = text;
|
||||
}
|
||||
|
||||
export function getValue(id: string) {
|
||||
const el: any = document.getElementById(id)!;
|
||||
return el.value;
|
||||
}
|
||||
|
||||
export async function createQrCode(targetId: string, link: string, opts: QRCode.QRCodeRenderersOptions) {
|
||||
const el = document.getElementById(targetId)!;
|
||||
await QRCode.toCanvas(el, link, opts);
|
||||
}
|
||||
|
||||
export function disable(id: string) {
|
||||
const el = document.getElementById(id)!;
|
||||
el.setAttribute('disabled', 'true');
|
||||
}
|
||||
|
||||
export function enable(id: string) {
|
||||
const el = document.getElementById(id)!;
|
||||
el.removeAttribute('disabled');
|
||||
}
|
||||
|
||||
export function link(id: string): string {
|
||||
return 'https://fluence.one/registry-demo/?join=' + id;
|
||||
}
|
||||
|
||||
interface DiscoveredUser {
|
||||
route: string;
|
||||
userName: string;
|
||||
}
|
||||
|
||||
export async function updateUserList(users: DiscoveredUser[]) {
|
||||
const promises = users.map(async (x) => {
|
||||
const html =
|
||||
// force new line
|
||||
`<div class="user">
|
||||
<div class="user__name">${x.userName}</div>
|
||||
<canvas class="user__canvas" id="${x.route}" />
|
||||
</div>`;
|
||||
const li = document.createElement('li');
|
||||
li.innerHTML = html;
|
||||
return li;
|
||||
});
|
||||
|
||||
const lis = await Promise.all(promises);
|
||||
|
||||
const ul = document.getElementById('user-list')!;
|
||||
ul?.replaceChildren(...lis);
|
||||
|
||||
for (let x of users) {
|
||||
createQrCode(x.route, link(x.route), {});
|
||||
}
|
||||
}
|
26
tsconfig.json
Normal file
26
tsconfig.json
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"lib": [
|
||||
"es2015",
|
||||
"dom"
|
||||
],
|
||||
"outDir": "./dist/",
|
||||
"target": "es5",
|
||||
"module": "commonjs",
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"declaration": true,
|
||||
"declarationMap": false,
|
||||
"sourceMap": true,
|
||||
"noImplicitAny": false
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"dist"
|
||||
],
|
||||
"include": [
|
||||
"src"
|
||||
]
|
||||
}
|
67
webpack.config.js
Normal file
67
webpack.config.js
Normal file
@ -0,0 +1,67 @@
|
||||
// Generated using webpack-cli https://github.com/webpack/webpack-cli
|
||||
|
||||
const webpack = require('webpack');
|
||||
const path = require('path');
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
|
||||
// const isProduction = process.env.NODE_ENV == 'production';
|
||||
const isProduction = false;
|
||||
|
||||
const stylesHandler = 'style-loader';
|
||||
|
||||
const config = {
|
||||
entry: './src/index.ts',
|
||||
output: {
|
||||
path: path.resolve(__dirname, 'dist'),
|
||||
},
|
||||
devServer: {
|
||||
open: true,
|
||||
host: 'localhost',
|
||||
static: {
|
||||
directory: path.join(__dirname, 'public'),
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
new HtmlWebpackPlugin({
|
||||
template: 'index.html',
|
||||
}),
|
||||
new webpack.ProvidePlugin({
|
||||
process: 'process/browser',
|
||||
}),
|
||||
|
||||
// Add your plugins here
|
||||
// Learn more about plugins from https://webpack.js.org/configuration/plugins/
|
||||
],
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.(ts|tsx)$/i,
|
||||
loader: 'ts-loader',
|
||||
exclude: ['/node_modules/'],
|
||||
},
|
||||
{
|
||||
test: /\.css$/i,
|
||||
use: [stylesHandler, 'css-loader'],
|
||||
},
|
||||
{
|
||||
test: /\.(eot|svg|ttf|woff|woff2|png|jpg|gif)$/i,
|
||||
type: 'asset',
|
||||
},
|
||||
|
||||
// Add your rules for custom modules here
|
||||
// Learn more about loaders from https://webpack.js.org/loaders/
|
||||
],
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.ts', '.js', 'css'],
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = () => {
|
||||
if (isProduction) {
|
||||
config.mode = 'production';
|
||||
} else {
|
||||
config.mode = 'development';
|
||||
}
|
||||
return config;
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user