mirror of
https://github.com/antos-rde/antosdk-apps.git
synced 2024-11-19 11:48:22 +01:00
add tunnel plugin package
This commit is contained in:
parent
0df49e387c
commit
031f78c926
7
AntunnelPlugins/README.md
Normal file
7
AntunnelPlugins/README.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# Antunnel Plugins
|
||||||
|
Aditional Plugins for Antunnel library.
|
||||||
|
This package provides also the Typescript declaration file for
|
||||||
|
application Development.
|
||||||
|
|
||||||
|
## Change logs
|
||||||
|
- v.0.1.0: Antunnel API declaration and broadcast plugin
|
526
AntunnelPlugins/broadcast.ts
Normal file
526
AntunnelPlugins/broadcast.ts
Normal file
@ -0,0 +1,526 @@
|
|||||||
|
/**
|
||||||
|
* Broadcast plugin for Antunnel to communication
|
||||||
|
* with the backend Antunnel broadcast publisher
|
||||||
|
*/
|
||||||
|
namespace Antunnel {
|
||||||
|
/**
|
||||||
|
* Broadcast control message type
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @enum {number}
|
||||||
|
*/
|
||||||
|
export enum BroadcastCTRLType {
|
||||||
|
SUBSCRIBE = 0x0A,
|
||||||
|
UNSUBSCRIBE = 0xB,
|
||||||
|
QUERY = 0xC
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Group state
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @enum {number}
|
||||||
|
*/
|
||||||
|
export enum BroadcastGroupState {
|
||||||
|
INIT,
|
||||||
|
SUBSCRIBED,
|
||||||
|
UNSUBSCRIBED
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Broadcast control message
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @interface BroadcastCTRLMsg
|
||||||
|
*/
|
||||||
|
export interface BroadcastCTRLMsg {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Message type
|
||||||
|
*
|
||||||
|
* @type {BroadcastCTRLType}
|
||||||
|
* @memberof BroadcastCTRLMsg
|
||||||
|
*/
|
||||||
|
type: BroadcastCTRLType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Group name
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof BroadcastCTRLMsg
|
||||||
|
*/
|
||||||
|
group?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User name
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof BroadcastCTRLMsg
|
||||||
|
*/
|
||||||
|
user: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* group id - allocated by backend
|
||||||
|
*
|
||||||
|
* @type {number}
|
||||||
|
* @memberof BroadcastCTRLMsg
|
||||||
|
*/
|
||||||
|
id: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Broadcast group handle
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @class BroadcastGroup
|
||||||
|
*/
|
||||||
|
export class BroadcastGroup {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Group name
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof BroadcastGroup
|
||||||
|
*/
|
||||||
|
groupname: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Group id allocated by backend
|
||||||
|
*
|
||||||
|
* @type {number}
|
||||||
|
* @memberof BroadcastGroup
|
||||||
|
*/
|
||||||
|
id: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Active users of the group
|
||||||
|
*
|
||||||
|
* @type {Set<string>}
|
||||||
|
* @memberof BroadcastGroup
|
||||||
|
*/
|
||||||
|
users: Set<string>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when grouped is opened by backend
|
||||||
|
*
|
||||||
|
* @memberof BroadcastGroup
|
||||||
|
*/
|
||||||
|
onready: () => void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called whe a message is sent to group
|
||||||
|
*
|
||||||
|
* @memberof BroadcastGroup
|
||||||
|
*/
|
||||||
|
onmessage: (data: Uint8Array) => void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when user added to the group
|
||||||
|
*
|
||||||
|
* @memberof BroadcastGroup
|
||||||
|
*/
|
||||||
|
onuseradd: (user: string) => void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when user is removed from the group
|
||||||
|
*
|
||||||
|
* @memberof BroadcastGroup
|
||||||
|
*/
|
||||||
|
onuserdel: (user: string) => void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when handle owner left the group
|
||||||
|
*
|
||||||
|
* @memberof BroadcastGroup
|
||||||
|
*/
|
||||||
|
onclose: () => void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Owner of this handle
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof BroadcastGroup
|
||||||
|
*/
|
||||||
|
user: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reference to the attached Broadcast manage
|
||||||
|
*
|
||||||
|
* @type {BroadcastManager}
|
||||||
|
* @memberof BroadcastGroup
|
||||||
|
*/
|
||||||
|
mgr: BroadcastManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current state of the handle
|
||||||
|
*
|
||||||
|
* @type {BroadcastGroupState}
|
||||||
|
* @memberof BroadcastGroup
|
||||||
|
*/
|
||||||
|
state: BroadcastGroupState;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an instance of BroadcastGroup.
|
||||||
|
* @param {string} name
|
||||||
|
* @memberof BroadcastGroup
|
||||||
|
*/
|
||||||
|
constructor(name: string) {
|
||||||
|
this.groupname = name;
|
||||||
|
this.users = new Set<string>();
|
||||||
|
this.onmessage = undefined;
|
||||||
|
this.onready = undefined;
|
||||||
|
this.onuseradd = undefined;
|
||||||
|
this.onuserdel = undefined;
|
||||||
|
this.onclose = undefined;
|
||||||
|
this.user = OS.setting.user.name;
|
||||||
|
this.mgr = undefined;
|
||||||
|
this.state = BroadcastGroupState.INIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Leave the group
|
||||||
|
*
|
||||||
|
* @return {*} {void}
|
||||||
|
* @memberof BroadcastGroup
|
||||||
|
*/
|
||||||
|
close(): void {
|
||||||
|
if (!this.mgr || !this.id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.mgr.unsubscribe(this.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query all users in the group
|
||||||
|
*
|
||||||
|
* @return {*} {void}
|
||||||
|
* @memberof BroadcastGroup
|
||||||
|
*/
|
||||||
|
refresh(): void {
|
||||||
|
if (!this.mgr || !this.id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.mgr.query(this.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a message to the group
|
||||||
|
*
|
||||||
|
* @param {Uint8Array} data
|
||||||
|
* @memberof BroadcastGroup
|
||||||
|
*/
|
||||||
|
send(data: Uint8Array): void {
|
||||||
|
this.mgr.send(this.id, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Broadcast Manager
|
||||||
|
* Managing all group handles created by the current
|
||||||
|
* user
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @class BroadcastManager
|
||||||
|
*/
|
||||||
|
export class BroadcastManager {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reference to Antunnel subscriber
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @type {SubscriberInterface}
|
||||||
|
* @memberof BroadcastManager
|
||||||
|
*/
|
||||||
|
private sub: SubscriberInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* channel name
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @type {string}
|
||||||
|
* @memberof BroadcastManager
|
||||||
|
*/
|
||||||
|
private channel: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reference to the global tunnel handle
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @type {AntunnelAPI}
|
||||||
|
* @memberof BroadcastManager
|
||||||
|
*/
|
||||||
|
private tunnel: AntunnelAPI;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* list of all registered group handles
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @type {{[prop: number]: BroadcastGroup}}
|
||||||
|
* @memberof BroadcastManager
|
||||||
|
*/
|
||||||
|
private groups: { [prop: number]: BroadcastGroup };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* temporary list of group handles that wait for
|
||||||
|
* an connection confirmation from the backend
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @type {GenericObject<BroadcastGroup>}
|
||||||
|
* @memberof BroadcastManager
|
||||||
|
*/
|
||||||
|
private pendings: GenericObject<BroadcastGroup>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an instance of BroadcastManager.
|
||||||
|
* @param {string} channel
|
||||||
|
* @memberof BroadcastManager
|
||||||
|
*/
|
||||||
|
constructor(channel: string) {
|
||||||
|
this.sub = undefined;
|
||||||
|
this.channel = channel;
|
||||||
|
this.tunnel = undefined;
|
||||||
|
this.groups = {};
|
||||||
|
this.pendings = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connect to the broadcast channel
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {(d: any)=> void} resolve
|
||||||
|
* @memberof BroadcastManager
|
||||||
|
*/
|
||||||
|
private connect(resolve: (d: any) => void): void {
|
||||||
|
this.sub = new Subscriber(this.channel);
|
||||||
|
this.sub.onopen = () => {
|
||||||
|
OS.announcer.osinfo(__("Subscriber {0}: Connected to the {1} channel", this.sub.id, this.channel));
|
||||||
|
resolve(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.sub.onerror = (e:AntunnelMSG) => {
|
||||||
|
let err: any = e;
|
||||||
|
if(e.data)
|
||||||
|
{
|
||||||
|
err = new TextDecoder("utf-8").decode(e.data);
|
||||||
|
}
|
||||||
|
OS.announcer.oserror(
|
||||||
|
__("Subscriber {0}: Error from the {1} channel: {2}",
|
||||||
|
this.sub.id, this.channel, err), undefined);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.sub.onmessage = (e: GenericObject<any>) => {
|
||||||
|
if (e.data) {
|
||||||
|
let gid = Antunnel.Msg.int_from(e.data.slice(0, 4), 0, 4);
|
||||||
|
let g_handle = this.groups[gid];
|
||||||
|
if (!g_handle)
|
||||||
|
return;
|
||||||
|
if (g_handle.onmessage) {
|
||||||
|
g_handle.onmessage(e.data.slice(4));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.sub.onctrl = (d) => {
|
||||||
|
let msg: BroadcastCTRLMsg = {
|
||||||
|
user: undefined,
|
||||||
|
group: undefined,
|
||||||
|
type: d.data[0] as BroadcastCTRLType,
|
||||||
|
id: undefined
|
||||||
|
}
|
||||||
|
switch (msg.type) {
|
||||||
|
case BroadcastCTRLType.SUBSCRIBE:
|
||||||
|
case BroadcastCTRLType.UNSUBSCRIBE:
|
||||||
|
let offset = d.data[1] + 2;
|
||||||
|
msg.user = new TextDecoder("utf-8").decode(d.data.slice(2, offset));
|
||||||
|
msg.id = Antunnel.Msg.int_from(d.data, offset, 4);
|
||||||
|
offset += 4;
|
||||||
|
msg.group = new TextDecoder("utf-8").decode(d.data.slice(offset));
|
||||||
|
if (msg.type === BroadcastCTRLType.SUBSCRIBE) {
|
||||||
|
let g_handle = this.pendings[msg.group];
|
||||||
|
if (g_handle && g_handle.user === msg.user) {
|
||||||
|
g_handle.id = msg.id;
|
||||||
|
g_handle.onready();
|
||||||
|
this.pendings[msg.group] = undefined;
|
||||||
|
delete this.pendings[msg.group];
|
||||||
|
this.groups[msg.id] = g_handle;
|
||||||
|
g_handle.state = BroadcastGroupState.SUBSCRIBED;
|
||||||
|
}
|
||||||
|
g_handle = this.groups[msg.id];
|
||||||
|
if (!g_handle) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
g_handle.users.add(msg.user);
|
||||||
|
if (g_handle.onuseradd)
|
||||||
|
g_handle.onuseradd(msg.user);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let g_handle = this.groups[msg.id];
|
||||||
|
if (!g_handle) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (g_handle.user === msg.user) {
|
||||||
|
OS.announcer.osinfo(__("Subcriber {0}: leave group {1}", this.sub.id, msg.group));
|
||||||
|
this.groups[msg.id] = undefined;
|
||||||
|
delete this.groups[msg.id];
|
||||||
|
g_handle.state = BroadcastGroupState.UNSUBSCRIBED;
|
||||||
|
if (g_handle.onclose)
|
||||||
|
g_handle.onclose();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
g_handle.users.delete(msg.user);
|
||||||
|
if (g_handle.onuserdel)
|
||||||
|
g_handle.onuserdel(msg.user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BroadcastCTRLType.QUERY:
|
||||||
|
msg.id = Antunnel.Msg.int_from(d.data, 1, 4);
|
||||||
|
msg.user = new TextDecoder("utf-8").decode(d.data.slice(5));
|
||||||
|
let g_handle = this.groups[msg.id];
|
||||||
|
if (!g_handle)
|
||||||
|
return;
|
||||||
|
if (!g_handle.users.has(msg.user)) {
|
||||||
|
g_handle.users.add(msg.user);
|
||||||
|
if (g_handle.onuseradd)
|
||||||
|
g_handle.onuseradd(msg.user);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.sub.onclose = () => {
|
||||||
|
OS.announcer.osinfo(__("Subscriber {0}: Connection to {1} closed", this.sub.id, this.channel));
|
||||||
|
this.sub = undefined;
|
||||||
|
}
|
||||||
|
this.tunnel.subscribe(this.sub);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform setup of the manager:
|
||||||
|
* - Check if Antunnel API is available
|
||||||
|
* - Connect to the tunnel if the global tunnel does not exists
|
||||||
|
* - Subscribe to th e broadcast channel if not done
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @return {*} {Promise<any>}
|
||||||
|
* @memberof BroadcastManager
|
||||||
|
*/
|
||||||
|
private setup(): Promise<any> {
|
||||||
|
return new Promise(async (resolve, reject) => {
|
||||||
|
try {
|
||||||
|
if (!Antunnel) {
|
||||||
|
throw new Error(__("Library not fould: %s", "Antunnel").__());
|
||||||
|
}
|
||||||
|
if (!Antunnel.tunnel) {
|
||||||
|
await OS.GUI.pushService("Antunnel/AntunnelService");
|
||||||
|
let uri = (OS.setting.system as any).tunnel_uri as string;
|
||||||
|
if (!uri) {
|
||||||
|
throw new Error(__("Unable to connect to: %s", "Antunnel").__());
|
||||||
|
}
|
||||||
|
await Antunnel.init(uri);
|
||||||
|
this.tunnel = Antunnel.tunnel;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.tunnel = Antunnel.tunnel;
|
||||||
|
}
|
||||||
|
if (!this.sub) {
|
||||||
|
this.connect(resolve);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
resolve(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
if (Antunnel.tunnel)
|
||||||
|
Antunnel.tunnel.close();
|
||||||
|
reject(__e(e));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a group handle from the manager
|
||||||
|
*
|
||||||
|
* @param {number} gid
|
||||||
|
* @memberof BroadcastManager
|
||||||
|
*/
|
||||||
|
unsubscribe(gid: number): void {
|
||||||
|
let arr = new Uint8Array(5);
|
||||||
|
arr[0] = BroadcastCTRLType.UNSUBSCRIBE;
|
||||||
|
arr.set(Antunnel.Msg.bytes_of(gid, 4), 1);
|
||||||
|
this.sub.send(Antunnel.Msg.CTRL, arr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query users in the specific group
|
||||||
|
*
|
||||||
|
* @param {number} gid group id
|
||||||
|
* @memberof BroadcastManager
|
||||||
|
*/
|
||||||
|
query(gid: number): void {
|
||||||
|
let arr = new Uint8Array(5);
|
||||||
|
arr[0] = BroadcastCTRLType.QUERY;
|
||||||
|
arr.set(Antunnel.Msg.bytes_of(gid, 4), 1);
|
||||||
|
this.sub.send(Antunnel.Msg.CTRL, arr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a group to the manager
|
||||||
|
*
|
||||||
|
* @param {BroadcastGroup} group
|
||||||
|
* @memberof BroadcastManager
|
||||||
|
*/
|
||||||
|
subscribe(group: BroadcastGroup): void {
|
||||||
|
this.setup()
|
||||||
|
.then((_) => {
|
||||||
|
let arr = new Uint8Array(group.groupname.length + 1);
|
||||||
|
arr[0] = BroadcastCTRLType.SUBSCRIBE;
|
||||||
|
arr.set(new TextEncoder().encode(group.groupname), 1);
|
||||||
|
this.sub.send(Antunnel.Msg.CTRL, arr);
|
||||||
|
group.mgr = this;
|
||||||
|
this.pendings[group.groupname] = group;
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
OS.announcer.oserror(__("Unable to subscribe to group {0}: {1}", group.groupname, e.toString()), e);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*CLeanup the manager
|
||||||
|
*
|
||||||
|
* @memberof BroadcastManager
|
||||||
|
*/
|
||||||
|
teardown(): void {
|
||||||
|
if (this.sub) {
|
||||||
|
this.sub.close();
|
||||||
|
}
|
||||||
|
this.groups = {};
|
||||||
|
this.pendings = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a message to a specific group
|
||||||
|
*
|
||||||
|
* @param {number} gid
|
||||||
|
* @param {Uint8Array} data
|
||||||
|
* @memberof BroadcastManager
|
||||||
|
*/
|
||||||
|
send(gid: number, data: Uint8Array): void {
|
||||||
|
let arr = new Uint8Array(data.length + 4);
|
||||||
|
arr.set(Antunnel.Msg.bytes_of(gid, 4), 0);
|
||||||
|
arr.set(data, 4);
|
||||||
|
this.sub.send(Antunnel.Msg.DATA, arr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
80
AntunnelPlugins/build.json
Normal file
80
AntunnelPlugins/build.json
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
{
|
||||||
|
"name": "AntunnelPlugins",
|
||||||
|
"targets":{
|
||||||
|
"clean": {
|
||||||
|
"jobs": [
|
||||||
|
{
|
||||||
|
"name": "vfs-rm",
|
||||||
|
"data": ["build/debug","build/release"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"build": {
|
||||||
|
"require": ["ts"],
|
||||||
|
"jobs":[
|
||||||
|
{
|
||||||
|
"name": "vfs-mkdir",
|
||||||
|
"data": ["build","build/debug","build/release"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ts-import",
|
||||||
|
"data": ["sdk://core/ts/core.d.ts", "sdk://core/ts/jquery.d.ts","sdk://core/ts/antos.d.ts"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ts-compile",
|
||||||
|
"data": {
|
||||||
|
"src": ["main.ts", "broadcast.ts"],
|
||||||
|
"dest": "build/debug/main.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ts-compile",
|
||||||
|
"data": {
|
||||||
|
"src": ["main.ts", "broadcast.ts"],
|
||||||
|
"dest": "build/debug/main.d.ts",
|
||||||
|
"options": {
|
||||||
|
"declaration": true,
|
||||||
|
"emitDeclarationOnly": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"uglify": {
|
||||||
|
"require": ["terser"],
|
||||||
|
"jobs": [
|
||||||
|
{
|
||||||
|
"name":"terser-uglify",
|
||||||
|
"data": ["build/debug/main.js"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"copy": {
|
||||||
|
"jobs": [
|
||||||
|
{
|
||||||
|
"name": "vfs-cp",
|
||||||
|
"data": {
|
||||||
|
"src": [
|
||||||
|
"package.json",
|
||||||
|
"README.md"
|
||||||
|
],
|
||||||
|
"dest":"build/debug"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"release": {
|
||||||
|
"depend": ["clean","build","uglify", "copy"],
|
||||||
|
"require": ["zip"],
|
||||||
|
"jobs": [
|
||||||
|
{
|
||||||
|
"name": "zip-mk",
|
||||||
|
"data": {
|
||||||
|
"src":"build/debug",
|
||||||
|
"dest":"build/release/AntunnelPlugins.zip"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
7
AntunnelPlugins/build/debug/README.md
Normal file
7
AntunnelPlugins/build/debug/README.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# Antunnel Plugins
|
||||||
|
Aditional Plugins for Antunnel library.
|
||||||
|
This package provides also the Typescript declaration file for
|
||||||
|
application Development.
|
||||||
|
|
||||||
|
## Change logs
|
||||||
|
- v.0.1.0: Antunnel API declaration and broadcast plugin
|
519
AntunnelPlugins/build/debug/main.d.ts
vendored
Normal file
519
AntunnelPlugins/build/debug/main.d.ts
vendored
Normal file
@ -0,0 +1,519 @@
|
|||||||
|
|
||||||
|
/**
|
||||||
|
* This namespace describe the Antunnel API
|
||||||
|
* used by o ther application
|
||||||
|
*/
|
||||||
|
declare namespace Antunnel {
|
||||||
|
/**
|
||||||
|
* Tunnel message type
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @enum {number}
|
||||||
|
*/
|
||||||
|
enum AntunnelMSGType {
|
||||||
|
OK = 0,
|
||||||
|
SUBSCRIBE = 2,
|
||||||
|
UNSUBSCRIBE = 3,
|
||||||
|
ERROR = 1,
|
||||||
|
DATA = 6,
|
||||||
|
CTRL = 7,
|
||||||
|
CLOSE = 5,
|
||||||
|
PING = 8
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Main tunnel core handle API
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @interface AntunnelAPI
|
||||||
|
*/
|
||||||
|
interface AntunnelAPI {
|
||||||
|
/**
|
||||||
|
* Close the socket connection attached to the
|
||||||
|
* current handle
|
||||||
|
*
|
||||||
|
* @memberof AntunnelAPI
|
||||||
|
*/
|
||||||
|
close(): void;
|
||||||
|
/**
|
||||||
|
* register a subscriber to the handle
|
||||||
|
*
|
||||||
|
* @param {SubscriberInterface} sub
|
||||||
|
* @memberof AntunnelAPI
|
||||||
|
*/
|
||||||
|
subscribe(sub: SubscriberInterface): void;
|
||||||
|
/**
|
||||||
|
* Remove a subscriber from the handle
|
||||||
|
*
|
||||||
|
* @param {SubscriberInterface} sub
|
||||||
|
* @param {boolean} b notify the backend ?
|
||||||
|
* @memberof AntunnelAPI
|
||||||
|
*/
|
||||||
|
unsubscribe(sub: SubscriberInterface, b: boolean): void;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Singleton instance to the current core tunnel handle
|
||||||
|
*/
|
||||||
|
var tunnel: AntunnelAPI;
|
||||||
|
/**
|
||||||
|
* A tunnel frame header
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @interface AntunnelMSGHeader
|
||||||
|
*/
|
||||||
|
interface AntunnelMSGHeader {
|
||||||
|
/**
|
||||||
|
* Client ID allocated by the backend
|
||||||
|
*
|
||||||
|
* @type {number}
|
||||||
|
* @memberof AntunnelMSGHeader
|
||||||
|
*/
|
||||||
|
cid: number;
|
||||||
|
/**
|
||||||
|
* Subscriber ID allocated by Antunnel frontend
|
||||||
|
*
|
||||||
|
* @type {number}
|
||||||
|
* @memberof AntunnelMSGHeader
|
||||||
|
*/
|
||||||
|
sid: number;
|
||||||
|
/**
|
||||||
|
* Payload size
|
||||||
|
*
|
||||||
|
* @type {number}
|
||||||
|
* @memberof AntunnelMSGHeader
|
||||||
|
*/
|
||||||
|
size: number;
|
||||||
|
/**
|
||||||
|
* Message type
|
||||||
|
*
|
||||||
|
* @type {AntunnelMSGType}
|
||||||
|
* @memberof AntunnelMSGHeader
|
||||||
|
*/
|
||||||
|
type: AntunnelMSGType;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Tunnel frame format
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @interface AntunnelMSG
|
||||||
|
*/
|
||||||
|
interface AntunnelMSG {
|
||||||
|
/**
|
||||||
|
* frame header
|
||||||
|
*
|
||||||
|
* @type {AntunnelMSGHeader}
|
||||||
|
* @memberof AntunnelMSG
|
||||||
|
*/
|
||||||
|
header: AntunnelMSGHeader;
|
||||||
|
/**
|
||||||
|
* raw data
|
||||||
|
*
|
||||||
|
* @type {Uint8Array}
|
||||||
|
* @memberof AntunnelMSG
|
||||||
|
*/
|
||||||
|
data: Uint8Array;
|
||||||
|
/**
|
||||||
|
* helper function that convert the
|
||||||
|
* entire frame to byte array
|
||||||
|
*
|
||||||
|
* @memberof AntunnelMSG
|
||||||
|
*/
|
||||||
|
as_raw(): void;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Static members of Msg class
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @interface AntunnelMSGMeta
|
||||||
|
*/
|
||||||
|
interface AntunnelMSGMeta {
|
||||||
|
/**
|
||||||
|
* constructor
|
||||||
|
*/
|
||||||
|
new (): AntunnelMSG;
|
||||||
|
/**
|
||||||
|
* convert number to array (network byte order)
|
||||||
|
*
|
||||||
|
* @param {number} x
|
||||||
|
* @param {number} [s]
|
||||||
|
* @return {*} {Uint8Array}
|
||||||
|
* @memberof AntunnelMSGMeta
|
||||||
|
*/
|
||||||
|
bytes_of(x: number, s?: number): Uint8Array;
|
||||||
|
/**
|
||||||
|
* convert network byte order array to number
|
||||||
|
*
|
||||||
|
* @param {Uint8Array} data
|
||||||
|
* @param {number} offset
|
||||||
|
* @param {number} [s]
|
||||||
|
* @return {*} {number}
|
||||||
|
* @memberof AntunnelMSGMeta
|
||||||
|
*/
|
||||||
|
int_from(data: Uint8Array, offset: number, s?: number): number;
|
||||||
|
OK: AntunnelMSGType;
|
||||||
|
ERROR: AntunnelMSGType;
|
||||||
|
DATA: AntunnelMSGType;
|
||||||
|
CLOSE: AntunnelMSGType;
|
||||||
|
SUBSCRIBE: AntunnelMSGType;
|
||||||
|
UNSUBSCRIBE: AntunnelMSGType;
|
||||||
|
CTRL: AntunnelMSGType;
|
||||||
|
PING: AntunnelMSGType;
|
||||||
|
}
|
||||||
|
var Msg: AntunnelMSGMeta;
|
||||||
|
/**
|
||||||
|
* Interface of a Subscriber class
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @interface SubscriberInterface
|
||||||
|
*/
|
||||||
|
interface SubscriberInterface {
|
||||||
|
/**
|
||||||
|
* Subscriber ID allocated by Antunnel API
|
||||||
|
*
|
||||||
|
* @type {number}
|
||||||
|
* @memberof SubscriberInterface
|
||||||
|
*/
|
||||||
|
id: number;
|
||||||
|
/**
|
||||||
|
* Channel ID/ Client ID allocated by backend
|
||||||
|
*
|
||||||
|
* @type {number}
|
||||||
|
* @memberof SubscriberInterface
|
||||||
|
*/
|
||||||
|
channel_id: number;
|
||||||
|
/**
|
||||||
|
* Called when a channel is opened for
|
||||||
|
* this subscriber
|
||||||
|
*
|
||||||
|
* @memberof SubscriberInterface
|
||||||
|
*/
|
||||||
|
onopen: () => void;
|
||||||
|
/**
|
||||||
|
* Error handle callback
|
||||||
|
*
|
||||||
|
* @memberof SubscriberInterface
|
||||||
|
*/
|
||||||
|
onerror: (d: string | AntunnelMSG) => void;
|
||||||
|
/**
|
||||||
|
* Message callback
|
||||||
|
*
|
||||||
|
* @memberof SubscriberInterface
|
||||||
|
*/
|
||||||
|
onmessage: (m: AntunnelMSG) => void;
|
||||||
|
/**
|
||||||
|
* Control messqge callback
|
||||||
|
*
|
||||||
|
* @memberof SubscriberInterface
|
||||||
|
*/
|
||||||
|
onctrl: (m: AntunnelMSG) => void;
|
||||||
|
/**
|
||||||
|
* Subscriber close callback
|
||||||
|
*
|
||||||
|
* @memberof SubscriberInterface
|
||||||
|
*/
|
||||||
|
onclose: () => void;
|
||||||
|
/**
|
||||||
|
* Send a message to backend
|
||||||
|
*
|
||||||
|
* @memberof SubscriberInterface
|
||||||
|
*/
|
||||||
|
send: (t: AntunnelMSGType, arr: Uint8Array) => void;
|
||||||
|
close: () => void;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Static member of a subscriber
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @interface SubscriberInterfaceMeta
|
||||||
|
*/
|
||||||
|
interface SubscriberInterfaceMeta {
|
||||||
|
new (channel: string): SubscriberInterface;
|
||||||
|
}
|
||||||
|
var Subscriber: SubscriberInterfaceMeta;
|
||||||
|
/**
|
||||||
|
* Core handle initialization
|
||||||
|
*/
|
||||||
|
var init: (u: string) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Broadcast plugin for Antunnel to communication
|
||||||
|
* with the backend Antunnel broadcast publisher
|
||||||
|
*/
|
||||||
|
declare namespace Antunnel {
|
||||||
|
/**
|
||||||
|
* Broadcast control message type
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @enum {number}
|
||||||
|
*/
|
||||||
|
enum BroadcastCTRLType {
|
||||||
|
SUBSCRIBE = 10,
|
||||||
|
UNSUBSCRIBE = 11,
|
||||||
|
QUERY = 12
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Group state
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @enum {number}
|
||||||
|
*/
|
||||||
|
enum BroadcastGroupState {
|
||||||
|
INIT = 0,
|
||||||
|
SUBSCRIBED = 1,
|
||||||
|
UNSUBSCRIBED = 2
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Broadcast control message
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @interface BroadcastCTRLMsg
|
||||||
|
*/
|
||||||
|
interface BroadcastCTRLMsg {
|
||||||
|
/**
|
||||||
|
* Message type
|
||||||
|
*
|
||||||
|
* @type {BroadcastCTRLType}
|
||||||
|
* @memberof BroadcastCTRLMsg
|
||||||
|
*/
|
||||||
|
type: BroadcastCTRLType;
|
||||||
|
/**
|
||||||
|
* Group name
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof BroadcastCTRLMsg
|
||||||
|
*/
|
||||||
|
group?: string;
|
||||||
|
/**
|
||||||
|
* User name
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof BroadcastCTRLMsg
|
||||||
|
*/
|
||||||
|
user: string;
|
||||||
|
/**
|
||||||
|
* group id - allocated by backend
|
||||||
|
*
|
||||||
|
* @type {number}
|
||||||
|
* @memberof BroadcastCTRLMsg
|
||||||
|
*/
|
||||||
|
id: number;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Broadcast group handle
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @class BroadcastGroup
|
||||||
|
*/
|
||||||
|
class BroadcastGroup {
|
||||||
|
/**
|
||||||
|
* Group name
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof BroadcastGroup
|
||||||
|
*/
|
||||||
|
groupname: string;
|
||||||
|
/**
|
||||||
|
* Group id allocated by backend
|
||||||
|
*
|
||||||
|
* @type {number}
|
||||||
|
* @memberof BroadcastGroup
|
||||||
|
*/
|
||||||
|
id: number;
|
||||||
|
/**
|
||||||
|
* Active users of the group
|
||||||
|
*
|
||||||
|
* @type {Set<string>}
|
||||||
|
* @memberof BroadcastGroup
|
||||||
|
*/
|
||||||
|
users: Set<string>;
|
||||||
|
/**
|
||||||
|
* Called when grouped is opened by backend
|
||||||
|
*
|
||||||
|
* @memberof BroadcastGroup
|
||||||
|
*/
|
||||||
|
onready: () => void;
|
||||||
|
/**
|
||||||
|
* Called whe a message is sent to group
|
||||||
|
*
|
||||||
|
* @memberof BroadcastGroup
|
||||||
|
*/
|
||||||
|
onmessage: (data: Uint8Array) => void;
|
||||||
|
/**
|
||||||
|
* Called when user added to the group
|
||||||
|
*
|
||||||
|
* @memberof BroadcastGroup
|
||||||
|
*/
|
||||||
|
onuseradd: (user: string) => void;
|
||||||
|
/**
|
||||||
|
* Called when user is removed from the group
|
||||||
|
*
|
||||||
|
* @memberof BroadcastGroup
|
||||||
|
*/
|
||||||
|
onuserdel: (user: string) => void;
|
||||||
|
/**
|
||||||
|
* Called when handle owner left the group
|
||||||
|
*
|
||||||
|
* @memberof BroadcastGroup
|
||||||
|
*/
|
||||||
|
onclose: () => void;
|
||||||
|
/**
|
||||||
|
* Owner of this handle
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof BroadcastGroup
|
||||||
|
*/
|
||||||
|
user: string;
|
||||||
|
/**
|
||||||
|
* reference to the attached Broadcast manage
|
||||||
|
*
|
||||||
|
* @type {BroadcastManager}
|
||||||
|
* @memberof BroadcastGroup
|
||||||
|
*/
|
||||||
|
mgr: BroadcastManager;
|
||||||
|
/**
|
||||||
|
* Current state of the handle
|
||||||
|
*
|
||||||
|
* @type {BroadcastGroupState}
|
||||||
|
* @memberof BroadcastGroup
|
||||||
|
*/
|
||||||
|
state: BroadcastGroupState;
|
||||||
|
/**
|
||||||
|
* Creates an instance of BroadcastGroup.
|
||||||
|
* @param {string} name
|
||||||
|
* @memberof BroadcastGroup
|
||||||
|
*/
|
||||||
|
constructor(name: string);
|
||||||
|
/**
|
||||||
|
* Leave the group
|
||||||
|
*
|
||||||
|
* @return {*} {void}
|
||||||
|
* @memberof BroadcastGroup
|
||||||
|
*/
|
||||||
|
close(): void;
|
||||||
|
/**
|
||||||
|
* Query all users in the group
|
||||||
|
*
|
||||||
|
* @return {*} {void}
|
||||||
|
* @memberof BroadcastGroup
|
||||||
|
*/
|
||||||
|
refresh(): void;
|
||||||
|
/**
|
||||||
|
* Send a message to the group
|
||||||
|
*
|
||||||
|
* @param {Uint8Array} data
|
||||||
|
* @memberof BroadcastGroup
|
||||||
|
*/
|
||||||
|
send(data: Uint8Array): void;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Broadcast Manager
|
||||||
|
* Managing all group handles created by the current
|
||||||
|
* user
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @class BroadcastManager
|
||||||
|
*/
|
||||||
|
class BroadcastManager {
|
||||||
|
/**
|
||||||
|
* Reference to Antunnel subscriber
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @type {SubscriberInterface}
|
||||||
|
* @memberof BroadcastManager
|
||||||
|
*/
|
||||||
|
private sub;
|
||||||
|
/**
|
||||||
|
* channel name
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @type {string}
|
||||||
|
* @memberof BroadcastManager
|
||||||
|
*/
|
||||||
|
private channel;
|
||||||
|
/**
|
||||||
|
* Reference to the global tunnel handle
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @type {AntunnelAPI}
|
||||||
|
* @memberof BroadcastManager
|
||||||
|
*/
|
||||||
|
private tunnel;
|
||||||
|
/**
|
||||||
|
* list of all registered group handles
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @type {{[prop: number]: BroadcastGroup}}
|
||||||
|
* @memberof BroadcastManager
|
||||||
|
*/
|
||||||
|
private groups;
|
||||||
|
/**
|
||||||
|
* temporary list of group handles that wait for
|
||||||
|
* an connection confirmation from the backend
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @type {GenericObject<BroadcastGroup>}
|
||||||
|
* @memberof BroadcastManager
|
||||||
|
*/
|
||||||
|
private pendings;
|
||||||
|
/**
|
||||||
|
* Creates an instance of BroadcastManager.
|
||||||
|
* @param {string} channel
|
||||||
|
* @memberof BroadcastManager
|
||||||
|
*/
|
||||||
|
constructor(channel: string);
|
||||||
|
/**
|
||||||
|
* Connect to the broadcast channel
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {(d: any)=> void} resolve
|
||||||
|
* @memberof BroadcastManager
|
||||||
|
*/
|
||||||
|
private connect;
|
||||||
|
/**
|
||||||
|
* Perform setup of the manager:
|
||||||
|
* - Check if Antunnel API is available
|
||||||
|
* - Connect to the tunnel if the global tunnel does not exists
|
||||||
|
* - Subscribe to th e broadcast channel if not done
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @return {*} {Promise<any>}
|
||||||
|
* @memberof BroadcastManager
|
||||||
|
*/
|
||||||
|
private setup;
|
||||||
|
/**
|
||||||
|
* Remove a group handle from the manager
|
||||||
|
*
|
||||||
|
* @param {number} gid
|
||||||
|
* @memberof BroadcastManager
|
||||||
|
*/
|
||||||
|
unsubscribe(gid: number): void;
|
||||||
|
/**
|
||||||
|
* Query users in the specific group
|
||||||
|
*
|
||||||
|
* @param {number} gid group id
|
||||||
|
* @memberof BroadcastManager
|
||||||
|
*/
|
||||||
|
query(gid: number): void;
|
||||||
|
/**
|
||||||
|
* Register a group to the manager
|
||||||
|
*
|
||||||
|
* @param {BroadcastGroup} group
|
||||||
|
* @memberof BroadcastManager
|
||||||
|
*/
|
||||||
|
subscribe(group: BroadcastGroup): void;
|
||||||
|
/**
|
||||||
|
*CLeanup the manager
|
||||||
|
*
|
||||||
|
* @memberof BroadcastManager
|
||||||
|
*/
|
||||||
|
teardown(): void;
|
||||||
|
/**
|
||||||
|
* Send a message to a specific group
|
||||||
|
*
|
||||||
|
* @param {number} gid
|
||||||
|
* @param {Uint8Array} data
|
||||||
|
* @memberof BroadcastManager
|
||||||
|
*/
|
||||||
|
send(gid: number, data: Uint8Array): void;
|
||||||
|
}
|
||||||
|
}
|
1
AntunnelPlugins/build/debug/main.js
Normal file
1
AntunnelPlugins/build/debug/main.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
var Antunnel;!function(e){let s;!function(e){e[e.OK=0]="OK",e[e.SUBSCRIBE=2]="SUBSCRIBE",e[e.UNSUBSCRIBE=3]="UNSUBSCRIBE",e[e.ERROR=1]="ERROR",e[e.DATA=6]="DATA",e[e.CTRL=7]="CTRL",e[e.CLOSE=5]="CLOSE",e[e.PING=8]="PING"}(s=e.AntunnelMSGType||(e.AntunnelMSGType={}))}(Antunnel||(Antunnel={})),function(e){let s,t;!function(e){e[e.SUBSCRIBE=10]="SUBSCRIBE",e[e.UNSUBSCRIBE=11]="UNSUBSCRIBE",e[e.QUERY=12]="QUERY"}(s=e.BroadcastCTRLType||(e.BroadcastCTRLType={})),function(e){e[e.INIT=0]="INIT",e[e.SUBSCRIBED=1]="SUBSCRIBED",e[e.UNSUBSCRIBED=2]="UNSUBSCRIBED"}(t=e.BroadcastGroupState||(e.BroadcastGroupState={})),e.BroadcastGroup=class{constructor(e){this.groupname=e,this.users=new Set,this.onmessage=void 0,this.onready=void 0,this.onuseradd=void 0,this.onuserdel=void 0,this.onclose=void 0,this.user=OS.setting.user.name,this.mgr=void 0,this.state=t.INIT}close(){this.mgr&&this.id&&this.mgr.unsubscribe(this.id)}refresh(){this.mgr&&this.id&&this.mgr.query(this.id)}send(e){this.mgr.send(this.id,e)}},e.BroadcastManager=class{constructor(e){this.sub=void 0,this.channel=e,this.tunnel=void 0,this.groups={},this.pendings={}}connect(n){this.sub=new e.Subscriber(this.channel),this.sub.onopen=()=>{OS.announcer.osinfo(__("Subscriber {0}: Connected to the {1} channel",this.sub.id,this.channel)),n(!0)},this.sub.onerror=e=>{let s=e;e.data&&(s=new TextDecoder("utf-8").decode(e.data)),OS.announcer.oserror(__("Subscriber {0}: Error from the {1} channel: {2}",this.sub.id,this.channel,s),void 0)},this.sub.onmessage=s=>{if(s.data){let t=e.Msg.int_from(s.data.slice(0,4),0,4),n=this.groups[t];if(!n)return;n.onmessage&&n.onmessage(s.data.slice(4))}},this.sub.onctrl=n=>{let i={user:void 0,group:void 0,type:n.data[0],id:void 0};switch(i.type){case s.SUBSCRIBE:case s.UNSUBSCRIBE:let r=n.data[1]+2;if(i.user=new TextDecoder("utf-8").decode(n.data.slice(2,r)),i.id=e.Msg.int_from(n.data,r,4),r+=4,i.group=new TextDecoder("utf-8").decode(n.data.slice(r)),i.type===s.SUBSCRIBE){let e=this.pendings[i.group];if(e&&e.user===i.user&&(e.id=i.id,e.onready(),this.pendings[i.group]=void 0,delete this.pendings[i.group],this.groups[i.id]=e,e.state=t.SUBSCRIBED),e=this.groups[i.id],!e)return;e.users.add(i.user),e.onuseradd&&e.onuseradd(i.user)}else{let e=this.groups[i.id];if(!e)return;e.user===i.user?(OS.announcer.osinfo(__("Subcriber {0}: leave group {1}",this.sub.id,i.group)),this.groups[i.id]=void 0,delete this.groups[i.id],e.state=t.UNSUBSCRIBED,e.onclose&&e.onclose()):(e.users.delete(i.user),e.onuserdel&&e.onuserdel(i.user))}break;case s.QUERY:i.id=e.Msg.int_from(n.data,1,4),i.user=new TextDecoder("utf-8").decode(n.data.slice(5));let o=this.groups[i.id];if(!o)return;o.users.has(i.user)||(o.users.add(i.user),o.onuseradd&&o.onuseradd(i.user))}},this.sub.onclose=()=>{OS.announcer.osinfo(__("Subscriber {0}: Connection to {1} closed",this.sub.id,this.channel)),this.sub=void 0},this.tunnel.subscribe(this.sub)}setup(){return new Promise(async(s,t)=>{try{if(!e)throw new Error(__("Library not fould: %s","Antunnel").__());if(e.tunnel)this.tunnel=e.tunnel;else{await OS.GUI.pushService("Antunnel/AntunnelService");let s=OS.setting.system.tunnel_uri;if(!s)throw new Error(__("Unable to connect to: %s","Antunnel").__());await e.init(s),this.tunnel=e.tunnel}this.sub?s(!0):this.connect(s)}catch(s){e.tunnel&&e.tunnel.close(),t(__e(s))}})}unsubscribe(t){let n=new Uint8Array(5);n[0]=s.UNSUBSCRIBE,n.set(e.Msg.bytes_of(t,4),1),this.sub.send(e.Msg.CTRL,n)}query(t){let n=new Uint8Array(5);n[0]=s.QUERY,n.set(e.Msg.bytes_of(t,4),1),this.sub.send(e.Msg.CTRL,n)}subscribe(t){this.setup().then(n=>{let i=new Uint8Array(t.groupname.length+1);i[0]=s.SUBSCRIBE,i.set((new TextEncoder).encode(t.groupname),1),this.sub.send(e.Msg.CTRL,i),t.mgr=this,this.pendings[t.groupname]=t}).catch(e=>{OS.announcer.oserror(__("Unable to subscribe to group {0}: {1}",t.groupname,e.toString()),e)})}teardown(){this.sub&&this.sub.close(),this.groups={},this.pendings={}}send(s,t){let n=new Uint8Array(t.length+4);n.set(e.Msg.bytes_of(s,4),0),n.set(t,4),this.sub.send(e.Msg.DATA,n)}}}(Antunnel||(Antunnel={}));
|
15
AntunnelPlugins/build/debug/package.json
Normal file
15
AntunnelPlugins/build/debug/package.json
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"pkgname": "AntunnelPlugins",
|
||||||
|
"name":"Antunnel Plugins",
|
||||||
|
"description":"Additional plugins for the Antunnel library",
|
||||||
|
"info":{
|
||||||
|
"author": "Dany LE",
|
||||||
|
"email": "mrsang@iohub.dev"
|
||||||
|
},
|
||||||
|
"version":"0.1.0-a",
|
||||||
|
"category":"Library",
|
||||||
|
"iconclass":"fa fa-cog",
|
||||||
|
"mimes":["none"],
|
||||||
|
"dependencies":["Antunnel@0.2.0-b"],
|
||||||
|
"locale": {}
|
||||||
|
}
|
BIN
AntunnelPlugins/build/release/AntunnelPlugins.zip
Normal file
BIN
AntunnelPlugins/build/release/AntunnelPlugins.zip
Normal file
Binary file not shown.
272
AntunnelPlugins/main.ts
Normal file
272
AntunnelPlugins/main.ts
Normal file
@ -0,0 +1,272 @@
|
|||||||
|
/**
|
||||||
|
* This namespace describe the Antunnel API
|
||||||
|
* used by o ther application
|
||||||
|
*/
|
||||||
|
namespace Antunnel {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tunnel message type
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @enum {number}
|
||||||
|
*/
|
||||||
|
export enum AntunnelMSGType {
|
||||||
|
OK = 0,
|
||||||
|
SUBSCRIBE = 2,
|
||||||
|
UNSUBSCRIBE = 3,
|
||||||
|
ERROR = 1,
|
||||||
|
DATA = 6,
|
||||||
|
CTRL = 7,
|
||||||
|
CLOSE = 5,
|
||||||
|
PING = 8
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main tunnel core handle API
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @interface AntunnelAPI
|
||||||
|
*/
|
||||||
|
export interface AntunnelAPI {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close the socket connection attached to the
|
||||||
|
* current handle
|
||||||
|
*
|
||||||
|
* @memberof AntunnelAPI
|
||||||
|
*/
|
||||||
|
close(): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* register a subscriber to the handle
|
||||||
|
*
|
||||||
|
* @param {SubscriberInterface} sub
|
||||||
|
* @memberof AntunnelAPI
|
||||||
|
*/
|
||||||
|
subscribe(sub: SubscriberInterface): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a subscriber from the handle
|
||||||
|
*
|
||||||
|
* @param {SubscriberInterface} sub
|
||||||
|
* @param {boolean} b notify the backend ?
|
||||||
|
* @memberof AntunnelAPI
|
||||||
|
*/
|
||||||
|
unsubscribe(sub: SubscriberInterface, b: boolean): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Singleton instance to the current core tunnel handle
|
||||||
|
*/
|
||||||
|
export var tunnel: AntunnelAPI;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A tunnel frame header
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @interface AntunnelMSGHeader
|
||||||
|
*/
|
||||||
|
export interface AntunnelMSGHeader {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Client ID allocated by the backend
|
||||||
|
*
|
||||||
|
* @type {number}
|
||||||
|
* @memberof AntunnelMSGHeader
|
||||||
|
*/
|
||||||
|
cid: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subscriber ID allocated by Antunnel frontend
|
||||||
|
*
|
||||||
|
* @type {number}
|
||||||
|
* @memberof AntunnelMSGHeader
|
||||||
|
*/
|
||||||
|
sid: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Payload size
|
||||||
|
*
|
||||||
|
* @type {number}
|
||||||
|
* @memberof AntunnelMSGHeader
|
||||||
|
*/
|
||||||
|
size: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Message type
|
||||||
|
*
|
||||||
|
* @type {AntunnelMSGType}
|
||||||
|
* @memberof AntunnelMSGHeader
|
||||||
|
*/
|
||||||
|
type: AntunnelMSGType;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tunnel frame format
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @interface AntunnelMSG
|
||||||
|
*/
|
||||||
|
export interface AntunnelMSG {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* frame header
|
||||||
|
*
|
||||||
|
* @type {AntunnelMSGHeader}
|
||||||
|
* @memberof AntunnelMSG
|
||||||
|
*/
|
||||||
|
header: AntunnelMSGHeader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* raw data
|
||||||
|
*
|
||||||
|
* @type {Uint8Array}
|
||||||
|
* @memberof AntunnelMSG
|
||||||
|
*/
|
||||||
|
data: Uint8Array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* helper function that convert the
|
||||||
|
* entire frame to byte array
|
||||||
|
*
|
||||||
|
* @memberof AntunnelMSG
|
||||||
|
*/
|
||||||
|
as_raw(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Static members of Msg class
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @interface AntunnelMSGMeta
|
||||||
|
*/
|
||||||
|
export interface AntunnelMSGMeta {
|
||||||
|
/**
|
||||||
|
* constructor
|
||||||
|
*/
|
||||||
|
new(): AntunnelMSG;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* convert number to array (network byte order)
|
||||||
|
*
|
||||||
|
* @param {number} x
|
||||||
|
* @param {number} [s]
|
||||||
|
* @return {*} {Uint8Array}
|
||||||
|
* @memberof AntunnelMSGMeta
|
||||||
|
*/
|
||||||
|
bytes_of(x: number, s?: number): Uint8Array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* convert network byte order array to number
|
||||||
|
*
|
||||||
|
* @param {Uint8Array} data
|
||||||
|
* @param {number} offset
|
||||||
|
* @param {number} [s]
|
||||||
|
* @return {*} {number}
|
||||||
|
* @memberof AntunnelMSGMeta
|
||||||
|
*/
|
||||||
|
int_from(data: Uint8Array, offset: number, s?: number): number;
|
||||||
|
|
||||||
|
OK: AntunnelMSGType;
|
||||||
|
ERROR: AntunnelMSGType;
|
||||||
|
DATA: AntunnelMSGType;
|
||||||
|
CLOSE: AntunnelMSGType;
|
||||||
|
SUBSCRIBE: AntunnelMSGType;
|
||||||
|
UNSUBSCRIBE: AntunnelMSGType;
|
||||||
|
CTRL: AntunnelMSGType;
|
||||||
|
PING: AntunnelMSGType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export var Msg: AntunnelMSGMeta;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface of a Subscriber class
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @interface SubscriberInterface
|
||||||
|
*/
|
||||||
|
export interface SubscriberInterface {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subscriber ID allocated by Antunnel API
|
||||||
|
*
|
||||||
|
* @type {number}
|
||||||
|
* @memberof SubscriberInterface
|
||||||
|
*/
|
||||||
|
id: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Channel ID/ Client ID allocated by backend
|
||||||
|
*
|
||||||
|
* @type {number}
|
||||||
|
* @memberof SubscriberInterface
|
||||||
|
*/
|
||||||
|
channel_id: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a channel is opened for
|
||||||
|
* this subscriber
|
||||||
|
*
|
||||||
|
* @memberof SubscriberInterface
|
||||||
|
*/
|
||||||
|
onopen: () => void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Error handle callback
|
||||||
|
*
|
||||||
|
* @memberof SubscriberInterface
|
||||||
|
*/
|
||||||
|
onerror: (d: string| AntunnelMSG) => void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Message callback
|
||||||
|
*
|
||||||
|
* @memberof SubscriberInterface
|
||||||
|
*/
|
||||||
|
onmessage: (m: AntunnelMSG) => void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Control messqge callback
|
||||||
|
*
|
||||||
|
* @memberof SubscriberInterface
|
||||||
|
*/
|
||||||
|
onctrl: (m: AntunnelMSG) => void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subscriber close callback
|
||||||
|
*
|
||||||
|
* @memberof SubscriberInterface
|
||||||
|
*/
|
||||||
|
onclose: () => void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a message to backend
|
||||||
|
*
|
||||||
|
* @memberof SubscriberInterface
|
||||||
|
*/
|
||||||
|
send: (t: AntunnelMSGType, arr: Uint8Array) => void;
|
||||||
|
close: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Static member of a subscriber
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @interface SubscriberInterfaceMeta
|
||||||
|
*/
|
||||||
|
export interface SubscriberInterfaceMeta {
|
||||||
|
new(channel: string): SubscriberInterface;
|
||||||
|
}
|
||||||
|
|
||||||
|
export var Subscriber: SubscriberInterfaceMeta;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Core handle initialization
|
||||||
|
*/
|
||||||
|
export var init: (u: string) => void;
|
||||||
|
}
|
15
AntunnelPlugins/package.json
Normal file
15
AntunnelPlugins/package.json
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"pkgname": "AntunnelPlugins",
|
||||||
|
"name":"Antunnel Plugins",
|
||||||
|
"description":"Additional plugins for the Antunnel library",
|
||||||
|
"info":{
|
||||||
|
"author": "Dany LE",
|
||||||
|
"email": "mrsang@iohub.dev"
|
||||||
|
},
|
||||||
|
"version":"0.1.0-a",
|
||||||
|
"category":"Library",
|
||||||
|
"iconclass":"fa fa-cog",
|
||||||
|
"mimes":["none"],
|
||||||
|
"dependencies":["Antunnel@0.2.0-b"],
|
||||||
|
"locale": {}
|
||||||
|
}
|
3
AntunnelPlugins/scheme.html
Normal file
3
AntunnelPlugins/scheme.html
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<afx-app-window apptitle="AntunnelPlugins" width="500" height="400" data-id="AntunnelPlugins">
|
||||||
|
<afx-hbox ></afx-hbox>
|
||||||
|
</afx-app-window>
|
@ -2,6 +2,7 @@
|
|||||||
AntOSDK: development API for AntOS based applications/projects
|
AntOSDK: development API for AntOS based applications/projects
|
||||||
|
|
||||||
## Change logs
|
## Change logs
|
||||||
|
- 0.0.12: TS worker now allows user specific compile options (defined un build file)
|
||||||
- 0.0.11: Update AntOS API v1.2.1
|
- 0.0.11: Update AntOS API v1.2.1
|
||||||
- 0.0.10: fix binary readfile bug
|
- 0.0.10: fix binary readfile bug
|
||||||
- 0.0.9: Fix locale gen bug
|
- 0.0.9: Fix locale gen bug
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
AntOSDK: development API for AntOS based applications/projects
|
AntOSDK: development API for AntOS based applications/projects
|
||||||
|
|
||||||
## Change logs
|
## Change logs
|
||||||
|
- 0.0.12: TS worker now allows user specific compile options (defined un build file)
|
||||||
- 0.0.11: Update AntOS API v1.2.1
|
- 0.0.11: Update AntOS API v1.2.1
|
||||||
- 0.0.10: fix binary readfile bug
|
- 0.0.10: fix binary readfile bug
|
||||||
- 0.0.9: Fix locale gen bug
|
- 0.0.9: Fix locale gen bug
|
||||||
|
@ -89,11 +89,21 @@ class TSJob extends AntOSDKBaseJob {
|
|||||||
useCaseSensitiveFileNames: () => true,
|
useCaseSensitiveFileNames: () => true,
|
||||||
writeFile: (path, data) => js_code = `${js_code}\n${data}`
|
writeFile: (path, data) => js_code = `${js_code}\n${data}`
|
||||||
};
|
};
|
||||||
const program = ts.createProgram(files, {
|
const compile_options = {
|
||||||
"target": "es6",
|
"target": "es6",
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"downlevelIteration": true
|
"downlevelIteration": true
|
||||||
}, host);
|
};
|
||||||
|
// Allow user override compile options
|
||||||
|
if(this.job.data.options)
|
||||||
|
{
|
||||||
|
for(let k in this.job.data.options)
|
||||||
|
{
|
||||||
|
compile_options[k] = this.job.data.options[k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log("TS compile options", compile_options);
|
||||||
|
const program = ts.createProgram(files,compile_options , host);
|
||||||
const result = program.emit();
|
const result = program.emit();
|
||||||
const diagnostics = result.diagnostics.concat((ts.getPreEmitDiagnostics(program)));
|
const diagnostics = result.diagnostics.concat((ts.getPreEmitDiagnostics(program)));
|
||||||
const errors = [];
|
const errors = [];
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
"author": "Xuan Sang LE",
|
"author": "Xuan Sang LE",
|
||||||
"email": "mrsang@iohub.dev"
|
"email": "mrsang@iohub.dev"
|
||||||
},
|
},
|
||||||
"version": "0.0.11-a",
|
"version": "0.0.12-a",
|
||||||
"category": "Development",
|
"category": "Development",
|
||||||
"iconclass": "fa fa-cog",
|
"iconclass": "fa fa-cog",
|
||||||
"mimes": [
|
"mimes": [
|
||||||
|
Binary file not shown.
@ -89,11 +89,21 @@ class TSJob extends AntOSDKBaseJob {
|
|||||||
useCaseSensitiveFileNames: () => true,
|
useCaseSensitiveFileNames: () => true,
|
||||||
writeFile: (path, data) => js_code = `${js_code}\n${data}`
|
writeFile: (path, data) => js_code = `${js_code}\n${data}`
|
||||||
};
|
};
|
||||||
const program = ts.createProgram(files, {
|
const compile_options = {
|
||||||
"target": "es6",
|
"target": "es6",
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"downlevelIteration": true
|
"downlevelIteration": true
|
||||||
}, host);
|
};
|
||||||
|
// Allow user override compile options
|
||||||
|
if(this.job.data.options)
|
||||||
|
{
|
||||||
|
for(let k in this.job.data.options)
|
||||||
|
{
|
||||||
|
compile_options[k] = this.job.data.options[k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log("TS compile options", compile_options);
|
||||||
|
const program = ts.createProgram(files,compile_options , host);
|
||||||
const result = program.emit();
|
const result = program.emit();
|
||||||
const diagnostics = result.diagnostics.concat((ts.getPreEmitDiagnostics(program)));
|
const diagnostics = result.diagnostics.concat((ts.getPreEmitDiagnostics(program)));
|
||||||
const errors = [];
|
const errors = [];
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
"author": "Xuan Sang LE",
|
"author": "Xuan Sang LE",
|
||||||
"email": "mrsang@iohub.dev"
|
"email": "mrsang@iohub.dev"
|
||||||
},
|
},
|
||||||
"version": "0.0.11-a",
|
"version": "0.0.12-a",
|
||||||
"category": "Development",
|
"category": "Development",
|
||||||
"iconclass": "fa fa-cog",
|
"iconclass": "fa fa-cog",
|
||||||
"mimes": [
|
"mimes": [
|
||||||
|
@ -59,6 +59,16 @@
|
|||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"download": "https://raw.githubusercontent.com/lxsang/antosdk-apps/master/Antunnel/build/release/Antunnel.zip"
|
"download": "https://raw.githubusercontent.com/lxsang/antosdk-apps/master/Antunnel/build/release/Antunnel.zip"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"pkgname": "AntunnelPlugins",
|
||||||
|
"name": "Antunnel Plugins",
|
||||||
|
"description": "https://raw.githubusercontent.com/lxsang/antosdk-apps/master/AntunnelPlugins/README.md",
|
||||||
|
"category": "Library",
|
||||||
|
"author": "Dany LE",
|
||||||
|
"version": "0.1.0-a",
|
||||||
|
"dependencies": ["Antunnel@0.2.0-b"],
|
||||||
|
"download": "https://raw.githubusercontent.com/lxsang/antosdk-apps/master/AntunnelPlugins/build/release/AntunnelPlugins.zip"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"pkgname": "Archive",
|
"pkgname": "Archive",
|
||||||
"name": "Archive",
|
"name": "Archive",
|
||||||
@ -195,7 +205,7 @@
|
|||||||
"description": "https://raw.githubusercontent.com/lxsang/antosdk-apps/master/libantosdk/README.md",
|
"description": "https://raw.githubusercontent.com/lxsang/antosdk-apps/master/libantosdk/README.md",
|
||||||
"category": "Development",
|
"category": "Development",
|
||||||
"author": "Xuan Sang LE",
|
"author": "Xuan Sang LE",
|
||||||
"version": "0.0.11-a",
|
"version": "0.0.12-a",
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"download": "https://raw.githubusercontent.com/lxsang/antosdk-apps/master/libantosdk/build/release/libantosdk.zip"
|
"download": "https://raw.githubusercontent.com/lxsang/antosdk-apps/master/libantosdk/build/release/libantosdk.zip"
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user