Skip to content

Instantly share code, notes, and snippets.

@jbaxleyiii
Last active November 8, 2017 19:07
Show Gist options
  • Select an option

  • Save jbaxleyiii/6e987685e099c98baedc68832e7edb4b to your computer and use it in GitHub Desktop.

Select an option

Save jbaxleyiii/6e987685e099c98baedc68832e7edb4b to your computer and use it in GitHub Desktop.
/*
*
* This payload happens per request result of a query. They can be kept for historical
* review and playback of requests / results, or only the last one can be shown.
*
* It includes as much details as I think we can one day support. At this point in time, I
* worry about shipping for hack week as it will take a good chunk of changes to support
* fully.
*
*/
// given an operation
const operation = {
query: gql`
query MyQuery($id: ID!) {
users(id: $id) {
firstName
lastName
fullName @client
}
}
`,
variables: {
id: 1,
},
operationName: "MyQuery",
};
// and a given context
const context = {
forceFetch: true,
};
// and a given link chain
const error = onError(console.error);
const dedup = new DedupLink();
const client = withClientState({});
const http = createHttpLink();
const ws = new WebSocketLink();
const isSub = () => true; /* detect from operation */
const link = from([error, dedup, client]).split(isSub, ws, http);
/*
* Given the above information:
* - an operation
* - a context
* - and a link chain
*
* We want to be able to create meaningful development tooling
* to understand what is happening and how to replay and debug
* the execution of this chain
*
* This will need a couple or few payload types:
* - link information
* - request information
* - result information
*
* I'm not sure about request / result being one or two payloads.
* It may make more sense to have a transaction payload
*
* These could be a single payload even
*
*/
const info = {
links: {
1: {
name: "ErrorLink",
options: {
/* could also be called config */
hanlder: "[Function]",
},
},
2: {
name: "DedupeLink",
options: {},
},
3: {
name: "ClientStateLink",
options: {},
},
4: {
name: "HttpLink",
options: {},
},
},
};
const EVENTTYPE = {
init: 1,
request: 2,
result: 3,
complete: 4,
};
const start = {
type: EVENTTYPE.init,
operation: {}, // operation at this point in time
context: {}, // context at this point in time
result: null, // no result data yet
error: null,
link: null,
timestamp: "",
};
const request = {
type: EVENTTYPE.request,
operation: {}, // operation at this point in time
context: {}, // context at this point in time
result: null, // no result data yet
error: null,
timestamp: "",
link: {
id: 1,
from: null, // starting link
to: 2,
},
};
const result = {
type: EVENTTYPE.result,
operation: {}, // operation at this point in time
context: {}, // context at this point in time
result: {
data: {},
errors: [],
},
error: null,
timestamp: "",
link: {
id: 4,
from: 3,
to: 3,
},
};
const complete = {
type: EVENTTYPE.complete,
operation: {}, // operation at this point in time
context: {}, // context at this point in time
result: {
data: {},
errors: [],
},
error: null,
link: null,
timestamp: "",
};
@stubailo
Copy link

stubailo commented Nov 8, 2017

A few comments, partially based on some design work with Peggy from yesterday (although she should also comment here!)

  1. rather than measuring duration, it might be better to just have a timestamp for each request/result - I think that will simplify both acquiring and displaying the data.
  2. I think it would be best to send information about all links up front, and give them numeric indices/IDs, and then use that for the actual events, rather than sending the link name and options attached to each event
  3. The events need to be annotated with both to and from links, since in the case of stuff like split it's not enough to know where the event came from. these can be in terms of IDs from (2)
  4. I think we should design it so that each request/response is sent as a separate message so that you can look at a panel in the dev tools and see each one show up in real time as it happens. Once a request/response has happened it shouldn't change anymore, so I think that should work

The fields on each individual event look great!

@jbaxleyiii
Copy link
Author

@stubalio thanks! Updated with changes!

@peggyrayzis
Copy link

peggyrayzis commented Nov 8, 2017

Agreed w/ all of Sashko's points. For reference, here's a rough draft of the API I'm working with for the LinkVisualizer component that reflects what we talked about yesterday.

type OperationData = { type: 'operation' };
type ResultData = { type: 'result' };
type ErrorData = { type: 'error' };

type FunctionCall = {
  from: number,
  to: number,
  timestamp: Date,
  context?: { [key: string]: any },
  data: OperationData | ResultData | ErrorData,
  direction: 'forward' | 'backward', // we could change this to request/response
};

type Props = {
  forwardCalls: Array<FunctionCall>,
  linkMap: { [key: number]: string },
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment