Git Product home page Git Product logo

odd-devtools's Introduction

ODD Devtools

ODD Devtools is a browser extension for debugging applications that use the ODD SDK. It logs session and file system events across domains and app namespaces. Each event includes information about the state of an application, including ODD SDK version, data root CID, username, account DID, agent DID, and capabilities.

Get started by setting debug to true in your ODD program. Open the devtools and select the ODD SDK tab. The ODD Devtools will connect to the ODD SDK and start logging events when they occur.

ODD Devtools organizes event logs by app namespace when debugging more than one app, for example, when one app requests capabilities from another. Select a namespace from the left panel to filter events, or select "All Namespaces" to view all events.

Filter events by entering a search term into the filter input. The filter checks for matches in any event payload value. For example, you could enter "private" to only view changes to the private file system.

Set up

Install the dependencies

npm install

Build

The build produces Firefox and Chrome extensions in the dist directory.

npm run build

Development

Chrome

The Chrome extension can be loaded at chrome://extensions/. Make sure the "Developer mode" toggle at the top right is enabled.

Select "Load unpacked". Find the directory with the built Chrome extension and select it.

Open a web app that is using ODD SDK with debug set to true. In the devtools, select the ODD SDK panel. The devtools will connect to ODD SDK when the panel is shown and on page reloads.

The extension will listen for messages after the extension has successfully connected with the ODD SDK.

Firefox

The Firefox extension can be loaded at about:debugging. Select "This Firefox", then "Load Temporary Add-on". Find the directory with the Firefox build and select manifest.json and "Open".

Firefox requires an extra permission step. Open about:addons and find the extension. Select it and in the permissions tab toggle "Access your data for all websites" on.

Notes to reviewer

This extension was built on macOS Ventura version 13.3.1 (a). The build used npm at version 8.15.0 and node at v18.7.0.

The extension is compiled using Vite configured by vite.chrome.config.ts and vite.firefox.config.ts. Vite emits distributions for Firefox and Chrome in dist/firefox and dist/chrome respectively.

All utilities necessary for building the extension are installed by running npm install.

odd-devtools's People

Contributors

bgins avatar jeffgca avatar

Stargazers

Ankesh Bharti avatar James Walker avatar

Watchers

 avatar

Forkers

jeffgca

odd-devtools's Issues

Add communication with Webnative

Summary

Problem

The extension does not communicate with Webnative.

Impact

The extension does not fulfill its primary purpose of debugging Webnative without this feature.

Solution

Implement a communication layer to interact with Webnative.

Detail

Communication methods

The extension can communicate with Webnative by a couple of methods:

  • Call a function added by Webnative to some global scope (e.g. window.navigator)
  • Read data added to some global scope by Webnative
  • Send a window post to Webnative

Webnative can only communicate with the extension using window post messages. We can check that the post messages are from the page where the extension's content script was injected by checking the event.source when receiving a window post message.

Side note: Chrome supports an externally_connectable API that allows a page to send messages directly using the extension runtime. Firefox does not support this feature yet so we can discard it as an option for now.

Connect

We will start the interaction between the extension and Webnative when a developer opens the Webnative devtools panel. The extension will signal to Webnative that it is ready to connect.

We could call a function put onto the global scope by Webnative or send a window post message to Webnative. I think calling a function would be preferable because it is a direct communication between the extension and Webnative. A window post message could be received elsewhere.

Webnative should send a connected window post message to the extension to confirm the connection. We can't directly target the extension with a window post message, but we can tag messages so the extension can ignore any other window post noise.

The connected message could look like:

{
  id: 'webnative-message',
  type: 'connected'
}

We could go further configure Webnative with a unique id sent by the extension when it connects. For example

{
  id: 'webnative-61728e0e-d3ee-4eea-93ff-c4d9a9ab493a',
  type: 'connected'
}

The main benefit here would be to ignore spoofed messages sent by another window poster. Not actually sure if we have a privacy or security concern, so a unique id might be overkill.

Disconnect

We should add a disconnect as well. The extension might disconnect when the developer is not viewing the Webnative devtools panel. Also, Webnative may want to signal to the extension that it has disconnected because something went wrong.

Disconnect could be implemented in roughly the same way as connect. Webnative adds a disconnect function to the global scope that the extension can call. When called, Webnative responds with a disconnect message like:

{
  id: 'webnative-message',
  type: 'disconnected'
}

Data

Data messages are sent from Webnative to the extension. See #2 for a list of data we would like to send.

We will send data messages as window post messages, and we can use a similar format to the other messages with an added data field:

{
  id: 'webnative-message',
  type: 'data',
  data: { 
    // various bits of data 
  }
}

The data that we send must be JSON serializable because the message will pass through extension messaging APIs.

Add background message reception

Summary

Problem

The current implementation of the browser extension only receives messages from Webnative when a developer has the Webnative devtools panel open.

Impact

Developers will miss messages if they navigate to another panel in the devtools interface.

Solution

Move message reception to the devtools page.

Detail

The devtools page is kept alive while the developer has the devtools open. Handling messages here will let developers navigate around the devtools interface freely.

This change will require an update to when we connect and disconnect from Webnative. We have a couple of options:

Improve state information in event payloads

Summary

Problem

The state object currently displays information about the state of the app, file system, user, and ODD SDK. It's a bit overloaded, which led one user to ask "this is the state of what?"

Impact

Users are uncertain about the information they are presented, which makes the extension more difficult to use.

Solution

We can improve this by doing the following:

  • Remove ODD SDK version. We already display version information in the namespaces column.
  • Remove app namespace. We display this in the namespaces column and it should be clear which namespace is selected.
  • Display user and file system information in separate sections of the event payload

In addition, we may want to:

  • Add a timestamp to the event detail
  • Label the dataRootCID as publishedRootCID
  • In file system event details, label root as localRootCID

Store messages in extension storage

Summary

Problem

When a developer closes the devtools, messages they have observed are lost.

Impact

Developers will lose context if the close the devtools and have to start over.

Solution

Store messages in extension storage. Reload them each time the devtools are opened.

Add a clear messages button to let developers erase history if they want to.

Publish to Chrome Web Store and Firefox Add-ons

Summary

We should prepare the extension and publish it to the Chrome Web Store and to Firefox add-ons.

Tasks include:

  • Rebrand from Webnative to ODD
    • Change name in all places
    • Update icons
  • Check and update publishing related fields in manifests (version, description, author, homepage, etc.)
  • Submit to Chrome Web Store
  • Submit to Firefox Add-ons

Reconnect on page load

Summary

Problem

On reloading the page or returning from the Fission Auth Lobby, the connection with Webnative will be dropped.

Impact

Some events may be missed and developers will need to reconnect with Webnative.

Solution

Store a flag to indicate connection state in extension storage. Check the flag and reconnect as needed.

Add ODD SDK Not Connected view

Summary

Problem

The devtools display a "Not connected" indicator but do not explain what devs can do to address it.

Impact

Devs might be confused and not know how to get the devtools working.

Solution

Add a "Not connected" view that is displayed after a short delay with configuration instructions. Not that the delay is because it takes the devtools a moment to connect to the ODD SDK, and we don't want to prematurely show an error page.

Set up Vite build

Summary

Problem

Browser extensions have incompatibilities across different browsers.

Impact

Targeting multiple browsers will be challenging to maintain manually.

Solution

Set up a build using Vite that emits builds that will work in each target browser. At the moment, the main incompatibility is that Firefox does not yet support service workers for Manifest V3 extensions.

Detail

Targeting multiple browsers is the primary motivation, but adding a build will also give us:

  • Svelte support
  • TypeScript support
  • ESM support (in some of the extension scripts)

Set not connected status when Webnative not available

Summary

Problem

The devtools check for connection when opened, but not on navigating to a new domain.

Impact

The devtools will sometimes show a connected status when they are not.

Solution

Set the connected status to false on every page load. Set connected on receiving a message from Webnative.

Hide connect and disconnect messages

Summary

Problem

The devtools panel displays connect and disconnect messages.

Impact

These messages are emitted on connect and disconnect with Webnative. They don't have much value for developers and create unnecessary noise.

Solution

Don't add these messages to the event store.

Detect if the user has enabled the optional permissions

@bgins I think we've got a cold start problem if we choose to keep the needed permissions as optional. We should investigate whether we can detect if permissions have been granted from the extension at run time, and advise the user that the extension will not be functional without them enabled.

OR, is it possible to just make all the permissions we need, requested at install time? I feel like for a developer audience this will be fine.

Improve time direction indication

Summary

Problem

The direction of time in the event log is not clear to all users.

Impact

Users are not always certain in which order events occurred.

Solution

Add some indication of the ordering to the event log entries.

Add project description and privacy policy

Summary

Problem

Browser extension marketplaces request a project description and privacy policy when publishing an extension. We don't have these yet.

Impact

We can't publish without them.

Solution

Write up a project description and privacy policy. We can add the project description as the opening section of the README. We'll add the privacy policy as a separate document in the repo.

Add panel UI

Summary

Problem

The devtools panel does not display Webnative debugging information.

Impact

Developers can't get useful information from the extension if we don't display it.

Solution

Implement a panel UI.

Detail

The panel UI should display information from Webnative across a few different categories.

General

  • Webnative version
  • App namespace

The app namespace is configured by developers and isolates the app in browser storage. For example, a developer might declare their app namespace as:

const program = await wn.program({
  namespace: { creator: "Nullsoft", name: "Winamp" }
})

It is also possible for a developer to declare an app namespace as a single string:

const program = await wn.program({
  namespace: "MySuperApp"
})

Webnative version and app namespace are always available regardless of whether a user has authed or not.

Account / User / Auth

(Leaving the category name intentionally open ended.)

  • Username
  • Account DID
  • Agent DID

Each of these should be displayed only after a user has authed.

The account DID is the user's root agent DID. The agent DID is the DID associated with the key pair of the current device. This could be the same as the account DID if it is the device where the user registered.

File system (WNFS)

  • Filesystem skeleton
  • Data root CID
  • Bitswap activity and connection details
  • Capabilities

The Filesystem skeleton will likely be the most complex interface in the extension. The file system is a tree with "private" and "public" root branches. Inside each root branch, there may be arbitrarily nested subdirectories and files. It may be possible to draw inspiration from the way the DOM is displayed by the Chrome devtools:

CleanShot 2023-01-25 at 14 04 13@2x

Bitswap activity and connection details are TBD because we will eventually be moving away from Bitswap. Will update with more details on that soon.

Capabilities is also TBD, but it would be a list of directories or files in WNFS that the app has access to. This only applies to apps that have requested capability from the Auth Lobby.

Each of these items are only relevant after a user has authed.

Connected/Disconnected states

The browser extension connects to Webnative in a web app. We hope that the connection will be solid, but there may be times when we have lost the connection with Webnative and the developer needs to re-establish the connection.

We should display the connection state and provide a way to reconnect. We may also want to provide the developer with a way to explicitly disconnect (not sure about this one).

Our canvas

The devtools panel is displayed inside the devtools in a dedicated panel like this:

CleanShot 2023-01-25 at 13 51 58@2x

(Ignore the placeholder mouse tracking UI. We'll replace that ๐Ÿ˜„.)

The panel can be resized by draggging it up and down. The panel can also be displayed on the left or right sides of the browser window:

CleanShot 2023-01-25 at 13 55 04@2x

The side version can be resized by dragging left or right.

Finally, the devtools panel can be popped out into it's own dedicated window.

TRACKING: ODD Devtools browser extension

The ODD Devtools extension provides developers a devtools panel with information for debugging their ODD applications.

It should display the following information:

  • ODD SDK version
  • App namespace
  • Username
  • Account DID
  • Agent DID
  • Event log (shows filesystem events for v1, more events in a future version)
  • Data root CID
  • Capabilities (what parts of WNFS does the app have access to)

The information should only be exposed when the developer has set debug to true when initializing an ODD program.

Milestone 0.1

Tasks

Dependencies

Milestone 0.2

No milestone

Implement text-based filtering

Summary

Problem

The devtools logs many messages, which can get a bit noisy. Text-based filtering can help developers focus on a specific message type, directory, or file.

Impact

Without filtering, a developer will need to look through unrelated events to find the events they want.

Solution

Add text-based filtering on message types and values in event payloads.

Messages are not displayed when multiple tabs are open

Summary

Problem

When more than one tab is open, the devtools will stop working in all but the last opened tab.

Impact

Developers can only use the devtools in one tab at a time.

Solution

Keep a map of ports from the background script to each devtools instance.

Filter messages in each devtools instance include only messages from its associated tab.

The UI scales naively

Currently as you widen the browser window the Namespace and Event columns scale their width out - this is probably unnecessary, the columns can probably be fixed width even?

Duplicate devtools panels created in Firefox

Summary

Problem

When selecting the devtools panel in Firefox, a duplicate panel is created.

Impact

Many unnecessary panels are created.

Solution

The panels are created when importing the devtools script in the panel to access stores. Remove the import and keep a separate copy of stores in the panel script.

Firefox displays not connected view incorrectly

Summary

Problem

Firefox sometimes displays the not connected view when it appears to have actually connected.

Impact

The not connected view blocks the event log, which makes the extension unusable in some cases. The bug is intermittent, so sometimes refreshing the web page helps.

Solution

Increase the timeout before we assume the connection failed. The timeout is currently one second. We can probably increase this to two seconds.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.