mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-07-05 18:48:31 +00:00
More fixes for the Apollo update. It still has issues with ensuring queries are re-fetched properly, but it is at least modifying queries and doing what it's supposed to.
This commit is contained in:
parent
9e1ba06eef
commit
5429f4d329
3 changed files with 136 additions and 58 deletions
|
@ -1,3 +1,17 @@
|
||||||
|
<div class="list-header">4.0.0-beta1.5<span>@fe7bd1b3bbdba43c0666</span> <time datetime="2018-02-01">(2018-02-01)</time></div>
|
||||||
|
<ul class="chat-menu-content menu-side-padding">
|
||||||
|
<li>Fixed: Part two of the fixes for the new Apollo version. FFZ should now be loading data mostly correctly.</li>
|
||||||
|
<li>Bug: The directory features are not currently working unless you navigate to it from another page.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="list-header">4.0.0-beta1.5<span>@ab19f207a73078a1e97f</span> <time datetime="2018-01-19">(2018-01-19)</time></div>
|
||||||
|
<ul class="chat-menu-content menu-side-padding">
|
||||||
|
<li>Changed: Include our own version of GraphQL because we can't trust Twitch.</li>
|
||||||
|
<li>Fixed: Temporary fix for FFZ not loading at all on the build of Twitch with updated Apollo and GraphQL libraries.</li>
|
||||||
|
<li>Several features are still broken for users experiencing that build including: literally everything to do with the directory and stream uptime display.</li>
|
||||||
|
<li>We'll fix these issues as soon as the main developer can actually get access to the newer build to write compatible code.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
<div class="list-header">4.0.0-beta1.5<span>@5f6029b8672c05bfed85</span> <time datetime="2018-01-19">(2018-01-19)</time></div>
|
<div class="list-header">4.0.0-beta1.5<span>@5f6029b8672c05bfed85</span> <time datetime="2018-01-19">(2018-01-19)</time></div>
|
||||||
<ul class="chat-menu-content menu-side-padding">
|
<ul class="chat-menu-content menu-side-padding">
|
||||||
<li>Fixed: Unable to load Twitch badge data. (They moved it in memory.)</li>
|
<li>Fixed: Unable to load Twitch badge data. (They moved it in memory.)</li>
|
||||||
|
|
|
@ -92,7 +92,8 @@ Twilight.KNOWN_MODULES = {
|
||||||
simplebar: n => n.globalObserver && n.initDOMLoadedElements,
|
simplebar: n => n.globalObserver && n.initDOMLoadedElements,
|
||||||
react: n => n.Component && n.createElement,
|
react: n => n.Component && n.createElement,
|
||||||
'extension-service': n => n.extensionService,
|
'extension-service': n => n.extensionService,
|
||||||
'chat-types': n => n.a && n.a.PostWithMention
|
'chat-types': n => n.a && n.a.PostWithMention,
|
||||||
|
'gql-printer': n => n !== window && n.print
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,6 @@ export default class Apollo extends Module {
|
||||||
async onEnable() {
|
async onEnable() {
|
||||||
// TODO: Come up with a better way to await something existing.
|
// TODO: Come up with a better way to await something existing.
|
||||||
let client = this.client;
|
let client = this.client;
|
||||||
//graphql = this.graphql;
|
|
||||||
|
|
||||||
if ( ! client ) {
|
if ( ! client ) {
|
||||||
const root = this.fine.getParent(this.fine.react),
|
const root = this.fine.getParent(this.fine.react),
|
||||||
|
@ -41,53 +40,92 @@ export default class Apollo extends Module {
|
||||||
client = this.client = ctx && ctx.client;
|
client = this.client = ctx && ctx.client;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if ( ! graphql )
|
this.printer = this.web_munch.getModule('gql-printer');
|
||||||
// graphql = this.graphql = await this.web_munch.findModule('graphql', m => m.parse && m.parseValue);
|
this.gql_print = this.printer && this.printer.print;
|
||||||
|
|
||||||
if ( ! client ) // || ! graphql )
|
if ( ! client )
|
||||||
return new Promise(s => setTimeout(s,50)).then(() => this.onEnable());
|
return new Promise(s => setTimeout(s,50)).then(() => this.onEnable());
|
||||||
|
|
||||||
// Parse the queries for modifiers that were already registered.
|
|
||||||
/*for(const key in this.modifiers)
|
|
||||||
if ( has(this.modifiers, key) ) {
|
|
||||||
const modifiers = this.modifiers[key];
|
|
||||||
if ( modifiers )
|
|
||||||
for(const mod of modifiers) {
|
|
||||||
if ( typeof mod === 'function' || mod[1] === false )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
try {
|
|
||||||
mod[1] = graphql.parse(mod[0], {noLocation: true});
|
|
||||||
} catch(err) {
|
|
||||||
this.log.error(`Error parsing GraphQL statement for "${key}" modifier.`, err);
|
|
||||||
mod[1] = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// Register middleware so that we can intercept requests.
|
// Register middleware so that we can intercept requests.
|
||||||
if ( ! this.client.networkInterface ) {
|
if ( ! this.client.link || ! this.client.queryManager || ! this.client.queryManager.link ) {
|
||||||
this.log.error('Apollo does not have NetworkInterface. We are unable to manipulate queries.');
|
this.log.error('Apollo does not have a Link. We are unable to manipulate queries.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.client.networkInterface.use([{
|
this.hooked_query_init = false;
|
||||||
applyBatchMiddleware: (req, next) => {
|
|
||||||
if ( this.enabled )
|
|
||||||
this.apolloPreFlight(req);
|
|
||||||
|
|
||||||
next();
|
if ( this.client.queryManager.queryStore ) {
|
||||||
|
const old_qm_init = this.client.queryManager.queryStore.initQuery;
|
||||||
|
this.hooked_query_init = true;
|
||||||
|
this.client.queryManager.queryStore.initQuery = function(e) {
|
||||||
|
let t = this.store[e.queryId];
|
||||||
|
if ( t && t.queryString !== e.queryString )
|
||||||
|
t.queryString = e.queryString;
|
||||||
|
|
||||||
|
return old_qm_init.call(this, e);
|
||||||
}
|
}
|
||||||
}]);
|
}
|
||||||
|
|
||||||
this.client.networkInterface.useAfter([{
|
const ApolloLink = this.ApolloLink = this.client.link.constructor;
|
||||||
applyBatchAfterware: (resp, next) => {
|
|
||||||
if ( this.enabled )
|
|
||||||
this.apolloPostFlight(resp);
|
|
||||||
|
|
||||||
next();
|
this.link = new ApolloLink((operation, forward) => {
|
||||||
|
//this.log.info('Link Start', operation.operationName, operation);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// ONLY do this if we've hooked query init, thus letting us ignore certain issues
|
||||||
|
// that would cause Twitch to show lovely "Error loading data" messages everywhere.
|
||||||
|
if ( this.hooked_query_init )
|
||||||
|
this.apolloPreFlight(operation);
|
||||||
|
|
||||||
|
} catch(err) {
|
||||||
|
this.log.error('Error running Pre-Flight', err, operation);
|
||||||
|
return forward(operation);
|
||||||
}
|
}
|
||||||
}]);
|
|
||||||
|
const out = forward(operation);
|
||||||
|
|
||||||
|
if ( out.subscribe )
|
||||||
|
return new out.constructor(observer => {
|
||||||
|
try {
|
||||||
|
out.subscribe({
|
||||||
|
next: result => {
|
||||||
|
try {
|
||||||
|
this.apolloPostFlight(result);
|
||||||
|
} catch(err) {
|
||||||
|
this.log.error('Error running Post-Flight', err, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
observer.next(result);
|
||||||
|
},
|
||||||
|
|
||||||
|
error: err => {
|
||||||
|
observer.error(err);
|
||||||
|
},
|
||||||
|
|
||||||
|
complete: observer.complete.bind(observer)
|
||||||
|
});
|
||||||
|
|
||||||
|
} catch(err) {
|
||||||
|
this.log.error('Link Error', err);
|
||||||
|
observer.error(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
else {
|
||||||
|
// We didn't get the sort of output we expected.
|
||||||
|
this.log.info('Unexpected Link Result', out);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
this.old_link = this.client.link;
|
||||||
|
this.old_qm_link = this.client.queryManager.link;
|
||||||
|
this.old_qm_dedup = this.client.queryManager.deduplicator;
|
||||||
|
|
||||||
|
this.client.link = this.link.concat(this.old_link);
|
||||||
|
this.client.queryManager.link = this.link.concat(this.old_qm_link);
|
||||||
|
this.client.queryManager.deduplicator = this.link.concat(this.old_qm_dedup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -113,33 +151,58 @@ export default class Apollo extends Module {
|
||||||
|
|
||||||
|
|
||||||
apolloPreFlight(request) {
|
apolloPreFlight(request) {
|
||||||
for(const req of request.requests) {
|
const operation = request.operationName,
|
||||||
const operation = req.operationName,
|
qm = this.client.queryManager,
|
||||||
modifiers = this.modifiers[operation];
|
id_map = qm && qm.queryIdsByName,
|
||||||
|
query_map = qm && qm.queries,
|
||||||
|
raw_id = id_map && id_map[operation],
|
||||||
|
id = Array.isArray(raw_id) ? raw_id[0] : raw_id,
|
||||||
|
query = query_map && query_map.get(id),
|
||||||
|
modifiers = this.modifiers[operation];
|
||||||
|
|
||||||
if ( modifiers )
|
if ( modifiers )
|
||||||
for(const mod of modifiers) {
|
for(const mod of modifiers) {
|
||||||
if ( typeof mod === 'function' )
|
if ( typeof mod === 'function' )
|
||||||
mod(req);
|
mod(request);
|
||||||
else if ( mod[1] )
|
else if ( mod[1] )
|
||||||
this.applyModifier(req, mod[1]);
|
this.applyModifier(request, mod[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.emit(`:request.${operation}`, request.query, request.variables);
|
||||||
|
|
||||||
|
// Wipe the old query data. This is obviously not optimal, but Apollo will
|
||||||
|
// raise an exception otherwise because the query string doesn't match.
|
||||||
|
|
||||||
|
const q = this.client.queryManager.queryStore.store[id],
|
||||||
|
qs = this.gql_print && this.gql_print(request.query);
|
||||||
|
|
||||||
|
if ( q )
|
||||||
|
if ( qs ) {
|
||||||
|
q.queryString = qs;
|
||||||
|
request.query.loc.source.body = qs;
|
||||||
|
request.query.loc.end = qs.length;
|
||||||
|
|
||||||
|
if ( query ) {
|
||||||
|
query.document = request.query;
|
||||||
|
if ( query.observableQuery && query.observableQuery.options )
|
||||||
|
query.observableQuery.options.query = request.query;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.emit(`:request.${operation}`, req.query, req.variables);
|
} else {
|
||||||
}
|
this.log.info('Unable to find GQL Print. Clearing store for query:', operation);
|
||||||
|
this.client.queryManager.queryStore.store[id] = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
apolloPostFlight(response) {
|
apolloPostFlight(response) {
|
||||||
for(const resp of response.responses) {
|
const operation = response.extensions.operationName,
|
||||||
const operation = resp.extensions.operationName,
|
modifiers = this.post_modifiers[operation];
|
||||||
modifiers = this.post_modifiers[operation];
|
|
||||||
|
|
||||||
if ( modifiers )
|
if ( modifiers )
|
||||||
for(const mod of modifiers)
|
for(const mod of modifiers)
|
||||||
mod(resp);
|
mod(response);
|
||||||
|
|
||||||
this.emit(`:response.${operation}`, resp.data);
|
this.emit(`:response.${operation}`, response.data);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -196,9 +259,9 @@ export default class Apollo extends Module {
|
||||||
getQuery(operation) {
|
getQuery(operation) {
|
||||||
const qm = this.client.queryManager,
|
const qm = this.client.queryManager,
|
||||||
name_map = qm && qm.queryIdsByName,
|
name_map = qm && qm.queryIdsByName,
|
||||||
query_map = qm && qm.observableQueries,
|
query_map = qm && qm.queries,
|
||||||
query_id = name_map && name_map[operation],
|
query_id = name_map && name_map[operation],
|
||||||
query = query_map && query_map[query_id];
|
query = query_map && query_id && query_map.get(Array.isArray(query_id) ? query_id[0] : query_id);
|
||||||
|
|
||||||
if ( ! query_map && ! this.warn_qm ) {
|
if ( ! query_map && ! this.warn_qm ) {
|
||||||
this.log.error('Unable to find the Apollo query map. We cannot access data properly.');
|
this.log.error('Unable to find the Apollo query map. We cannot access data properly.');
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue