Blog
Dioc library in Hoppscotch codebase.

Dioc library in Hoppscotch codebase.

In this article, we review Dioc lbrary in Hoppscotch codebase. We will look at:

  1. What is Hoppscotch?

  2. What is Dioc library?

  3. Dioc usage in Hoppscotch

I study patterns used in an open source project found on Github Trending. For this week, I reviewed some parts of Hoppscotch codebase and wrote this article.

What is Hoppscotch?

Hoppscotch is an open source API development ecosystem —  https://hoppscotch.io. It is an alternative to Postman, Insomnia.

Check out the Hoppscotch documentation to learn more.

What is Dioc library?

dioc is a really simple DI/IOC system where you write services (which are singletons per container) that can depend on each other and emit events that can be listened upon.

Example

import { Service, Container } from "dioc"

// Here is a simple service, which you can define by extending the Service class
// and providing an ID static field (of type string)
export class PersistenceService extends Service {
  // This should be unique for each container
  public static ID = "PERSISTENCE_SERVICE"

  public read(key: string): string | undefined {
    // ...
  }

  public write(key: string, value: string) {
    // ...
  }
}

type TodoServiceEvent =
  | { type: "TODO_CREATED"; index: number }
  | { type: "TODO_DELETED"; index: number }

// Services have a built in event system
// Define the generic argument to say what are the possible emitted values
export class TodoService extends Service<TodoServiceEvent> {
  public static ID = "TODO_SERVICE"

  // Inject persistence service into this service
  private readonly persistence = this.bind(PersistenceService)

  public todos = []

  // Services cannot(*) have constructors, but init logic can be mentioned here
  override onServiceInit() {
    this.todos = JSON.parse(this.persistence.read("todos") ?? "[]")
  }

  public addTodo(text: string) {
    // ...

    // You can access services via the bound fields
    this.persistence.write("todos", JSON.stringify(this.todos))

    // This is how you emit an event
    this.emit({
      type: "TODO_CREATED",
      index,
    })
  }

  public removeTodo(index: number) {
    // ...

    this.emit({
      type: "TODO_DELETED",
      index,
    })
  }
}

// Services need a container to run in
const container = new Container()

// You can initialize and get services using Container#bind
// It will automatically initialize the service (and its dependencies)
const todoService = container.bind(TodoService) // Returns an instance of TodoService

Check out Dioc npm package.

Dioc usage in Hoppscotch

In headerDownloadableLinks.service.ts, you will find the below code:

/**
 * Service to manage the downloadable links in the app header.
 */
export class HeaderDownloadableLinksService
  extends Service
  implements AdditionalLinkSet
{
  public static readonly ID = "HEADER_DOWNLOADABLE_LINKS_SERVICE"
  public readonly linkSetID = "HEADER_DOWNLOADABLE_LINKS"

  private readonly additionalLinkSet = this.bind(AdditionalLinksService)

  /**
   * List of downloadable links to be shown in the header
   * This includes showing the link to the desktop app, PWA, CLI.
   */
  private headerDownloadableLinks = ref<Link[]>([
    macOS,
    windows,
    linux,
    pwa,
    cli,
  ])

  override onServiceInit() {
    this.additionalLinkSet.registerAdditionalSet(this)
  }

  getLinks(): Ref<Link[]> {
    // @ts-expect-error show type not recognizing ComputedRef
    return this.headerDownloadableLinks
  }
}

onServiceInit function calls registerAdditionalSet function and this additionalLinkSet is imported as shown below, at the top:

import {
  AdditionalLinkSet,
  AdditionalLinksService,
  Link,
} from "@hoppscotch/common/services/additionalLinks.service"

About me:

Hey, my name is Ramu Narasinga. I study codebase architecture in large open-source projects.

Email: ramu.narasinga@gmail.com

I spent 200+ hours analyzing Supabase, shadcn/ui, LobeChat. Found the patterns that separate AI slop from production code. Stop refactoring AI slop. Start with proven patterns. Check out production-grade projects at thinkthroo.com

References:

  1. packages/hoppscotch-selfhost-web/src/services/headerDownloadableLinks.service.ts#L1

  2. https://www.npmjs.com/package/dioc

  3. packages/hoppscotch-selfhost-web/package.json#L41

We use cookies
We use cookies to ensure you get the best experience on our website. For more information on how we use cookies, please see our cookie policy.

By clicking "Accept", you agree to our use of cookies.

Learn more