11import { createAuthentication } from './authentication.js' ;
2- import { JSONADParser , parseAndApplyCommit , Store } from './index.js' ;
2+ import { JSONADParser , parseAndApplyCommit , Resource , Store } from './index.js' ;
33
44/** Opens a Websocket Connection at `/ws` for the current Drive */
55export function startWebsocket ( url : string , store : Store ) : WebSocket {
@@ -40,11 +40,7 @@ function handleMessage(ev: MessageEvent, store: Store) {
4040 } else if ( ev . data . startsWith ( 'ERROR ' ) ) {
4141 store . notifyError ( ev . data . slice ( 6 ) ) ;
4242 } else if ( ev . data . startsWith ( 'RESOURCE ' ) ) {
43- const resourceJSON : string = ev . data . slice ( 9 ) ;
44- const parsed = JSON . parse ( resourceJSON ) ;
45- const parser = new JSONADParser ( ) ;
46- const [ _ , resources ] = parser . parseObject ( parsed ) ;
47-
43+ const resources = parseResourceMessage ( ev ) ;
4844 store . addResources ( ...resources ) ;
4945 } else {
5046 console . warn ( 'Unknown websocket message:' , ev ) ;
@@ -55,6 +51,15 @@ function handleError(ev: Event) {
5551 console . error ( 'websocket error:' , ev ) ;
5652}
5753
54+ function parseResourceMessage ( ev : MessageEvent ) : Resource [ ] {
55+ const resourceJSON : string = ev . data . slice ( 9 ) ;
56+ const parsed = JSON . parse ( resourceJSON ) ;
57+ const parser = new JSONADParser ( ) ;
58+ const [ _ , resources ] = parser . parseObject ( parsed ) ;
59+
60+ return resources ;
61+ }
62+
5863/**
5964 * Authenticates current Agent over current WebSocket. Doesn't do anything if
6065 * there is no agent
@@ -79,7 +84,35 @@ export async function authenticate(client: WebSocket, store: Store) {
7984 client . send ( 'AUTHENTICATE ' + JSON . stringify ( json ) ) ;
8085}
8186
87+ const defaultTimeout = 5000 ;
88+
8289/** Sends a GET message for some resource over websockets. */
83- export async function fetchWebSocket ( client : WebSocket , subject : string ) {
84- client . send ( 'GET ' + subject ) ;
90+ export async function fetchWebSocket (
91+ client : WebSocket ,
92+ subject : string ,
93+ ) : Promise < Resource > {
94+ return new Promise ( ( resolve , reject ) => {
95+ client . addEventListener ( 'message' , function listener ( ev ) {
96+ const timeoutId = setTimeout ( ( ) => {
97+ client . removeEventListener ( 'message' , listener ) ;
98+ reject (
99+ new Error (
100+ `Request for subject "${ subject } " timed out after ${ defaultTimeout } ms.` ,
101+ ) ,
102+ ) ;
103+ } , defaultTimeout ) ;
104+
105+ if ( ev . data . startsWith ( 'RESOURCE ' ) ) {
106+ parseResourceMessage ( ev ) . forEach ( resource => {
107+ // if it is the requested subject, return the resource
108+ if ( resource . getSubject ( ) === subject ) {
109+ clearTimeout ( timeoutId ) ;
110+ client . removeEventListener ( 'message' , listener ) ;
111+ resolve ( resource ) ;
112+ }
113+ } ) ;
114+ }
115+ } ) ;
116+ client . send ( 'GET ' + subject ) ;
117+ } ) ;
85118}
0 commit comments