You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We expect $debug APIs to continuously evolve with user feedback. The high order bit for our initial release is
have the foundations built for ergonomic trampoline debugging
have some initial useful debugging APIs
Why
Current best-in-breed debugging involves adding code that is stripped for production builds (e.g. import.meta.dev or ember's @glimmer/env). The obvious problem here is that valuable debugging code isn't available when debugging production.
We want to eat our cake 🍰 and have it too -- rich debugging APIs, available in prod, without bloating application size.
Principles
We'll write (build or buy) a node-debug style library for logging + conveniently adding breakpoints. It'll be globally available via something like $debug and individual packages will create scoped instances, similar to node-debug.
All other debug APIs are accessible from a $debug property.
In production builds, $debug's contents are moved to a lazily loaded ES module. On first access, the user is told how to do the loading. Exact details TBD, but something like $debug prints a message and returns a function that does the lazy loading.
In dev and test $debug will behave the same, except that it will autoload if we detect that devtools is open.
It is important that PRs are red (i.e. unmergable) if they use $debug, but that $debug should otherwise be available even in CI. Exact details TBD, but there are a number of techniques (e.g. injecting a failing test).
Initial Guidance
Until trampoline-debug exists, write code like the following:
import$debugfrom'trampoline-debug';// node-debug style matching$debug.match='athena:*';// packages can add their own scopes, e.g. athena:debug:*, athena:info:*$debug.match=['athena:*','cache:get:*']$debug.match((debugPath): boolean);$debug.breakOn('athena:query:*');$debug.breakOn('athena:mutation:request');$debug.breakOn('cache:get:*');$debug.breakOn((debugPath,debugEvent) : boolean);// equivalent to $debug.match('athena:mutation:*');athena.$debug.match('mutation:*');// equivalent to $debug.breakOn('athena:query:*');athena.$debug.breakOn('query:*')// equivalent to $debug.match('cache:tx:commit:*');cache.$debug.match('tx:commit:*');// equivalent to $debug.breakOn('cache:get:*');cache.$debug.breakOn('get:*')athena.$debug.printSchema()athena.$debug.openGraphiQL()// open graphiql// prints a table of all operations athena has executed// include:// * queryId// * query name// * query contents// * variables (names & values)// * response body// * stack trace to execute{Query, Mutation}// * count of new entities// * count of merged entities// * timings// * path to query + open options// - in dev tools// - in graphiql// - in editor//athena.$debug.printOperations()// print detailed information for each execution of a specific operation// similar to printOperationsathena.$debug.operations.find((q)=>true).print()// with caputring enabled, on data property access, capture the render stack (ui integrations, ember, react &c.)// then highlight them similar to devtools element hoveringathena.$debug.captureRenderStacks();athena.$debug.queries.find((q)=>true).render.highlight()// print a table of revisions of the cache entry with <key>, alongside the source (e.g. operation, or manual transaction)athena.cache.$debug.history(key)// as above, but look up the cache entry by value instead of keyathena.cache.$debug.history(value)// as above, but return the data rather than printing to the consoleathena.cache.$debug.history(key,{silent: true})
Sample Library APIs
import{hasDebug,buildExtendedDebug,noDebugHelper}from'trampoline-debug';classAthena{get$debug(){if(hasDebug()){returnbuildExtendedDebug('athena',this,{printSchema(){},openGraphiQL(){},});}else{returnnoDebugHelper();}},executeQuery(){if(hasDebug()){// athena:query:requestthis.$debug.log('query:request',queryId,queryString, ...otherDebugInfo)awaitrequest();// athena:query:responsethis.$debug.log('query:response',queryId,queryString, ...otherDebugInfo)}}}import{hasDebug,buildExtendedDebug,noDebugHelper}from'trampoline-debug';classCache{get$debug(){if(hasDebug()){returnbuildExtendedDebug('cache',this,{history(){},});}else{returnnoDebugHelper();}},get(key){if(hasDebug()){// cache:get:${key}this.$debug.log(`get:${key}`, ...otherDebugInfo)}// ...}}// some class without customizationsimport{hasDebug,buildDebug,noDebugHelper}from'trampoline-debug';const$debug=buildDebug('my-class');classMyClass{method(key){if(hasDebug()){// my-class:foo$debug.log('foo', ...someDebugInfo)}// ...}}// some-other-moduleimport{hasDebug,buildDebug,noDebugHelper}from'trampoline-debug';const$debug=buildDebug('my-module');exportfunctionmoduleFn(){if(hasDebug()){$debug.log('scope', ...debugInfo)}}
The text was updated successfully, but these errors were encountered:
I understand we also need to define buildDebug interface that will be one of the key interface debug library should support?
Could you help clarify what does "// some class without customizations" mean here? Does that mean we have class Athena that customizes how breakpoints are set and the other just uses default debug setup?
Create Debugging APIs
Tasks:
We expect
$debug
APIs to continuously evolve with user feedback. The high order bit for our initial release isWhy
Current best-in-breed debugging involves adding code that is stripped for production builds (e.g.
import.meta.dev
or ember's@glimmer/env
). The obvious problem here is that valuable debugging code isn't available when debugging production.We want to eat our cake 🍰 and have it too -- rich debugging APIs, available in prod, without bloating application size.
Principles
We'll write (build or buy) a node-debug style library for logging + conveniently adding breakpoints. It'll be globally available via something like
$debug
and individual packages will create scoped instances, similar to node-debug.All other debug APIs are accessible from a
$debug
property.In production builds,
$debug
's contents are moved to a lazily loaded ES module. On first access, the user is told how to do the loading. Exact details TBD, but something like$debug
prints a message and returns a function that does the lazy loading.In dev and test
$debug
will behave the same, except that it will autoload if we detect that devtools is open.It is important that PRs are red (i.e. unmergable) if they use
$debug
, but that$debug
should otherwise be available even in CI. Exact details TBD, but there are a number of techniques (e.g. injecting a failing test).Initial Guidance
Until
trampoline-debug
exists, write code like the following:Sample Userland APIs
Sample Library APIs
The text was updated successfully, but these errors were encountered: