1
1
import { createAuthentication } from './authentication.js' ;
2
- import { JSONADParser , parseAndApplyCommit , Store } from './index.js' ;
2
+ import { JSONADParser , parseAndApplyCommit , Resource , Store } from './index.js' ;
3
3
4
4
/** Opens a Websocket Connection at `/ws` for the current Drive */
5
5
export function startWebsocket ( url : string , store : Store ) : WebSocket {
@@ -40,11 +40,7 @@ function handleMessage(ev: MessageEvent, store: Store) {
40
40
} else if ( ev . data . startsWith ( 'ERROR ' ) ) {
41
41
store . notifyError ( ev . data . slice ( 6 ) ) ;
42
42
} 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 ) ;
48
44
store . addResources ( ...resources ) ;
49
45
} else {
50
46
console . warn ( 'Unknown websocket message:' , ev ) ;
@@ -55,6 +51,15 @@ function handleError(ev: Event) {
55
51
console . error ( 'websocket error:' , ev ) ;
56
52
}
57
53
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
+
58
63
/**
59
64
* Authenticates current Agent over current WebSocket. Doesn't do anything if
60
65
* there is no agent
@@ -79,7 +84,35 @@ export async function authenticate(client: WebSocket, store: Store) {
79
84
client . send ( 'AUTHENTICATE ' + JSON . stringify ( json ) ) ;
80
85
}
81
86
87
+ const defaultTimeout = 5000 ;
88
+
82
89
/** 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
+ } ) ;
85
118
}
0 commit comments