Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Format Value Hook RFC #51

Closed
JSMonk opened this issue Sep 1, 2023 · 3 comments
Closed

Format Value Hook RFC #51

JSMonk opened this issue Sep 1, 2023 · 3 comments

Comments

@JSMonk
Copy link
Member

JSMonk commented Sep 1, 2023

Values Hook RFC

Problem

Some source languages introduce data structures that could be represented in a more DX-friendly way or just want to hide some implementation details or metadata for existing values. So, for such source languages, it's important to have the ability to customize the way how debugger shows target language values during debugging or logging.

Right now, we don't have the standardized ability to do that.
Chrome DevTools has its own solution called custom formatters

Is this a problem that source maps could solve?

Cases

For Kotlin/Wasm we have at least 3 cases for customizing values while a developer uses a debugger:

  • Strings (we use a structure like a linked list to represent the concatenated strings, but we want show to the end user a regular string during the debug process)
  • Unsigned Numbers (for unsigned numbers we use signed numbers and operations for unsigned numbers, but in the debugger tool for unsigned bytes instead of -1 we want to show 255)
  • Hiding Utility Properties (some of the struct properties are created by the compiler, so, we don't want to show them to the end-user)

The next list is taken from the custom formatters google docs

Also, there is a list of plugins that solve such cases for Chrome DevTools specifically (using custom formatters):

High-level Proposal

I believe that the API is the most discussable topic, so here I would like just to describe the high-level idea without committing to the final API.

We could define a special section called hooks, and specifically for this case, it will contain a sub-section called formatValue that will provide the path to the script that exports an array of hooks that should be invoked on each value in the duration of debugging.# Values Hook RFC

Problem

Some source languages introduce data structures that could be represented in a more DX-friendly way or just want to hide some implementation details or metadata for existing values. So, for such source languages, it's important to have the ability to customize the way how debugger shows target language values during debugging or logging.

Right now, we don't have the standardized ability to do that.
Chrome DevTools has its own solution called custom formatters

Is this a problem that source maps could solve?

Cases

For Kotlin/Wasm we have at least 3 cases for customizing values while a developer uses a debugger:

  • Strings (we use a structure like a linked list to represent the concatenated strings, but we want show to the end user a regular string)
  • Unsigned Numbers (for unsigned numbers we use signed numbers and operations for unsigned numbers, but in the debugger tool for unsigned bytes instead of -1 we want to show 255)
  • Hiding Utility Properties (some of the struct properties are created by the compiler, so, we don't want to show them to the end-user)

The next list is taken from the custom formatters google docs

Also, there is a list of plugins that solve such cases for Chrome DevTools specifically (using custom formatters):

High-level Proposal

I believe that the API is the most discussable topic, so here I would like just to describe the high-level idea without committing to the final API.

We could define a special section called hooks, and specifically for this case, it will contain a sub-section called values that will provide the path to the script that exports an array of hooks that should be invoked on each value in the duration of debugging.

Example for unsigned numbers case:

{
  ...
  "hooks": {
      "formatValues": "debug-script.js",
  }
  ...
}
// In the example, API is inspired by Chrome DevTools custom formatters, but this part should be discussed more
export default {
  hasBody: () => false, // `true` if the object can be opened to show more detail.
  : (valueToFormat/*: { value: ValueThatShouldBeFormatted, type: string } */) => { // single-line summary of the object or null. If null is returned, the default format will be used.
      const obj = valueToFormat.value
      
      if (obj instanceof UnsignedByte) { // here could be a call from WASM to make such type check
          return { 
            type: "number",
            value: obj.value < 0 ? 256 + obj.value  : obj.value
          }
      }
          
      return null
  }
}

Security

I believe that the proposal contains a lot of security issues, so, consumers could have next restriction for the Source Map Feature:

  • Script defined in the hooks should be placed at the same origin as the debugged application
  • This feature should be turned off by default and could be turned on from the DevTools specifically for a single origin
@connor4312
Copy link

connor4312 commented Sep 1, 2023

I'm dubious whether this is a problem source maps can solve. The hooks sound nice, but from a debugger's point of view, where a page has lots of scripts and lots of sourcemaps, how do we know whether any given value should be formatted using the hooks of any given sourcemap?

This is something the devtools get around by just having a global formatter. The main weak point right now of devtools is that they essentially return HTML from the formatter which makes them unusable or at least difficult to use in tooling that doesn't use the DOM to represent its output--this is why I don't support them in VS Code. However, I don't think the "hooks" defined by a single sourcemapped script should be used globally -- that's ripe for conflicts and confusion.

@mitsuhiko
Copy link
Contributor

I think this came up in a recent discussion and I also tend to believe that this is not something source maps can / should solve. If we related this to PDB, a related concept are natvis files. They are an independent format, but they can be embedded in PDBs. Maybe in some sense once there is a format defined for how such values can be expressed, then one could figure out how to link them up with source maps.

@JSMonk
Copy link
Member Author

JSMonk commented Sep 3, 2023

@connor4312 @mitsuhiko, I agree the problem is placed more outside than inside the area that the source map format solves. But I want to keep the discussion about the problem itself with this proposal (and maybe at the end of the day, if there is no nice solution for the problem, even add a few words inside the specification about the reason the format doesn't solve the problem)

About the multiple source maps with the hooks, what if it would be possible to define (inside the hooks section, for example) a list of sources? With this information, it could be possible to use a specific hook to debug only the specific code zone (that is mapped on the specific source).
Example:

{
  ...
  "sources": ["source1", "source2", "source3", "source4"],
  "hooks": {
      "formatValues": [
           {
               "script": "hook-1.js",
               "sources": [1, 2]
           },
           {
               "script": "hook-2.js",
               "sources": [3, 4]
           },
       ]
  }
  ...
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants