Created
May 7, 2025 13:18
-
-
Save zerkalica/7936c9ac3c2a7ccdfc4161a33202bc32 to your computer and use it in GitHub Desktop.
gql_ws.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace $ { | |
export class $mpk_gql_ws extends $yuf_ws_host { | |
override url() { return '/v1/graphql' } | |
override restart_delay() { return 60000 } | |
token() { return null as string | null | undefined } | |
@ $mol_mem | |
authorized(next?: boolean) { | |
// resend on token change | |
const token = this.token() | |
const ready = this.ready() | |
if (! token) return false | |
if (next === undefined && ready) { | |
this.send_object({ | |
type: 'connection_init', | |
payload: { | |
'Authorization': `Bearer ${token}`, | |
headers: { | |
'Content-Type': 'application/json', | |
} | |
} | |
}) | |
} | |
if (next) { | |
this.error(null) | |
} | |
return next ?? false | |
} | |
@ $mol_mem | |
override restarts( reset?: null ) { | |
// restart on token change | |
this.token() | |
return super.restarts(null) | |
} | |
protected subs() { return this.$.$mpk_gql_sub } | |
size() { return this.subs().size() } | |
send_authorized(payload: Object) { | |
// Resend on connection_ack change | |
if (! this.authorized()) return null | |
this.send_object(payload) | |
return null | |
} | |
pong() { this.send_object({ type: 'pong' }) } | |
override ping() { this.send_object({ type: 'ping' }) } | |
override heatbeat_enabled() { return false } | |
override enabled() { return Boolean(this.token()) && ! this.$.$yuf_browser_live.hidden() } | |
override protocols() { return [ 'graphql-ws' ] } | |
protected override on_object(obj: | |
// see https://habr.com/ru/articles/804641/ | |
// https://github.com/enisdenjo/graphql-ws/blob/master/PROTOCOL.md | |
| { type: 'connection_ack', payload?: Record<string, unknown> | null } | |
| { | |
type: 'data' | 'next' | 'error' | |
id: string | |
payload?: { | |
data?: unknown | |
errors?: readonly typeof $mpk_gql_error_dto.Value[] | |
} | |
} | |
| { type: 'complete', id: string } | |
| { type: 'ping', payload?: Record<string, unknown> | null } | |
| { type: 'pong' | 'ka', payload?: Record<string, unknown> | null } | |
) { | |
if (obj.type === 'ping') this.pong() | |
if (obj.type === 'pong' || obj.type === 'ka') this.watchdog(null) | |
if (obj.type === 'connection_ack') this.authorized(true) | |
if (obj.type === 'data' || obj.type === 'next' || obj.type === 'error') { | |
const req = this.subs().get(obj.id) | |
if (! req) return | |
const { data, errors } = obj.payload ?? {} | |
if (data) req.data(data) | |
if (errors) req.errors(errors.length ? errors : [ { message: JSON.stringify(obj.payload) } ] ) | |
} | |
if (obj.type === 'complete') { | |
const req = this.subs().get(obj.id) | |
if (req) { | |
new $mol_after_timeout(this.sub_restart_timeout(), () => req.subscribed(null)) | |
} | |
} | |
} | |
sub_restart_timeout() { return 5000 } | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment