diff --git a/src/locutus.ts b/src/locutus.ts index 58a5cc1..f92f8dd 100644 --- a/src/locutus.ts +++ b/src/locutus.ts @@ -100,7 +100,8 @@ export class App { this.defaultLocation = "/"; this.setHash("/"); } else { - throw Error(response.message); + console.error(response.error); + throw Error(response.error.message || response.error.code); } } @@ -237,14 +238,14 @@ export class App { this.addMessage(input.value); const val = input.value; input.value = ""; - await this.session.sendEvent("60nc0XXDIYUh6QzX4p0rMpCdzDmxghZLZk8dLuQh628", { + await this.session.newEvent("60nc0XXDIYUh6QzX4p0rMpCdzDmxghZLZk8dLuQh628", { message: val, }); } }); this.session.subscribe(response => { - this.addMessage(response.data.event.data.message); + this.addMessage(response.data.data.message); }); } } diff --git a/src/usimp.ts b/src/usimp.ts index e25b5e6..d2105f7 100644 --- a/src/usimp.ts +++ b/src/usimp.ts @@ -19,12 +19,15 @@ interface DomainServerJson { } } -interface EventJson { - data: { - event: { - data: any - } - } +interface OutputEnvelopeJson { + status: string, + request_nr: number, + data: any, + error: { + code: string, + message: string | null, + description: string | null, + } | null, } interface WellKnownJson { @@ -145,6 +148,7 @@ export class Session { httpBaseUrl: string | null; websocket: WebSocket | null; numRequests: number; + subscriptions: string[]; constructor(domain: Domain) { this.domain = domain; @@ -153,6 +157,7 @@ export class Session { this.token = null; this.httpBaseUrl = null; this.websocket = null; + this.subscriptions = []; } async chooseDomainServer(): Promise<{ http: number | null, ws: number | null } | undefined> { @@ -238,28 +243,43 @@ export class Session { }); } - async send(endpoint: string, data: object, timeout: number = 2000, forceHttp: boolean = false) { + async send(endpoint: string, data: any, timeout: number = 2000, forceHttp: boolean = false, cb: ((a: OutputEnvelopeJson) => void) | null = null) { this.numRequests++; - while (true) { try { - if (!forceHttp && this.websocket) { + if (!forceHttp && this.websocket !== null) { const req_nr = this.numRequests; - const response = this.waitForWebSocketResponse(req_nr, timeout); - const startTime = performance.now(); + + let response; + if (cb === null) { + response = this.waitForWebSocketResponse(req_nr, timeout); + } else { + this.websocket.addEventListener("message", (msg) => { + const data = JSON.parse(msg.data); + if (data['request_nr'] === req_nr) { + cb(data); + } + }); + } + await this.waitForWebSocket(); await this.websocket.send(JSON.stringify({ 'request_nr': req_nr, 'endpoint': endpoint, 'to_domain': this.domain.id, + 'token': this.token, 'data': data })); - const responseData = await response; - const endTime = performance.now(); - responseData.duration = endTime - startTime; - return responseData; + if (cb === null) { + const responseData = await response; + const endTime = performance.now(); + responseData.duration = endTime - startTime; + return responseData; + } else { + return null; // TODO subscription id + } } else { const controller = new AbortController(); const timer = setTimeout(() => controller.abort(), timeout); @@ -322,46 +342,37 @@ export class Session { return response; } - async sendEvent(roomId: string, data: object) { - return this.send("send_event", { + async newEvent(roomId: string, data: any) { + return this.send("new_event", { room_id: roomId, - data: data, + events: [{ + data: data + }], }); } - subscribe(func: (a: EventJson) => void) { + async subscribe(cb: (a: OutputEnvelopeJson) => void) { this.numRequests++; - if (this.websocket) { - // TODO + if (this.websocket !== null) { + let subscription = await this.send('subscribe', {}, 60_000, false, cb); + this.subscriptions.push(subscription); + return subscription; } else { - let headers: Record = { - 'Content-Type': 'application/json', - 'To-Domain': this.domain.id, - }; - if (this.token) { - headers['Authorization'] = `usimp ${this.token}`; - } - - fetch(`${this.httpBaseUrl}/subscribe`, { - method: "POST", - headers: headers, - body: JSON.stringify({}), - }).then(response => { - return response.json(); - }).then(response => { - if (response.status === "success") { - this.subscribe(func); - func(response); + this.send('subscribe', {}, 60_000).then((res) => { + if (res.status === "success") { + this.subscribe(cb); + cb(res); } else { setTimeout(() => { - this.subscribe(func); + this.subscribe(cb); }, 1000); } }).catch(() => { setTimeout(() => { - this.subscribe(func); + this.subscribe(cb); }, 1000); }); + return null; // TODO subscription id } } }