Skip to content

Application Architecture

Chris Amico edited this page Aug 29, 2023 · 2 revisions

The DocumentCloud frontend application code primarily lives in two directories:

  • src/: all the JavaScript, Svelte, and Scss to define the entire application
  • public/: a few static files, including the index.html file that imports the compiled JavaScript bundles, a global.css file, the Favicon, and the main DocumentCloud logo

This document deep dives into the layout of the application architecture in the src/ directory.

Svue

The codebase makes extensive use of Svue, a reactive way to store data with computed properties in Svelte.

src/

There are a few top-level files in this directory, which all play an important role.

  • main.js: the entry-point for the whole application. This file imports the top-level Svelte component (see below), injecting it into the main page
  • Main.svelte: the top-level Svelte component. This file uses the router (described later on) to determine what components to display. It also defines several global styles
  • emit.js: an event emitter. This file simplifies Svelte's event dispatch mechanism, and is widely used in the app code to dispatch events
  • routes.js: this top-level file defines all the routes (URLs) the frontend supports. It also leverages a lazy component loader, which only imports the application code as needed for a particular route. This lazy loading mechanism causes Webpack to break the frontend bundle into smaller JavaScript bundles called chunks that are imported as needed. This keeps the overall frontend from having to load everything at once and makes things more performant.

We'll tour some second-level directories in the src/ directory now, starting with the more self-contained ones.

Self-contained subdirectories

style

This directory stores shared SCSS and CSS styles. Right now, variables.scss is defined, a file which supplies global SCSS constants, like colors, sizes, and even some shared style mixins. A vanilla CSS version, variables.css is included. New variables should be added in vanilla CSS and used going forward.

assets

This directory stores SVG assets. These files, when imported from other Svelte components, are inlined into the JavaScript source code. Any SVG files placed in this directory should first be minified as much as possible (SVGOMG is useful) to ensure they don't bloat the JavaScript bundle too much. Inlining is useful because it means imagery and icons in the app don't need to be loaded asynchronously, making the behavior smoother and preventing any flickering.

util

Common utility JavaScript code. There are many files here that provide useful functionality that can be shared across the app. Some notable files include:

  • array.js: provides array functions, like uniquify and chunk
  • barchDelay.js: provides a function to run asynchronous code on a large collection of items in chunks, with a delay between invocations (mainly used to avoid spamming the DocumentCloud API with too many requests at once when dispatching multiple requests at once)
  • cache.js: provides a wrapper function to memoize function calls, useful for computationally or network-intensive calls that we don't expect to change between invocations
  • callEvery.js: provides a wrapper function to call a specified function every n invocations
  • closure.js: provides many wrapper functions, including timeoutify which ensures a function can only be called so many times per some time period. This is mostly useful with low latency events, like resizing a window and updating something expensive (e.g. layout) as a result that you don't want running too often.
  • string.js: string utility functions, like formatBytes which formats a size into a human-readable representation
  • url.js: URL utility functions, including ones to join URLs from parts and extract or modify query parameters

langs

This directory includes:

  • i18n.js: the script that provides and initializes internationalization
  • langs.json: the listing of available languages to the frontend
  • json/: JSON files for each language translation

router

This directory provides router.js, which is the main router for the application, along with the link component, Link.svelte.

Code sub-directories

The rest of the application code is more binned by functionality. At a glance, some more of the src/ subdirectories include:

  • api/: has JavaScript code to interact with the DocumentCloud API, including session.js which exports session management and auth.js which manages authentication state
  • common/: provides Svelte components that are common to multiple parts of the application. common/dialog provides the dialog components
  • pages/: provides route-specific Svelte components, such as those for the homepage, manager, and view. In the top-level of this subdirectory are FlatPage.svelte, which renders a flat page from Django (useful for help and documentation) and NotFound.svelte, which is shown for 404s
  • structure/: provides Svue objects that wrap API-returned data structures and give them more rich functionality. For instance, document.js wraps a document JSON object and provides utility methods like .pageUrl(pageNumber)
  • embed/: the main embed loader scripts for linking with legacy DocumentCloud
  • ticker/: provides `ticker.js, which is a global events dispatch system (allows things like the progress bar to update exactly every 5 seconds)

The rest of the sub-directories more explicitly deal with supporting JavaScript code to manage shared state for specific routes:

  • manager/: provides the following notable files for the manager
    • documents.js: handles state around the set of documents currently visible and progress
    • layout.js: handles state around the manager layout, e.g. which dialogs are shown, if the sidebar is expanded, etc.
    • manager.js: provides functionality to edit or modify selected documents
  • viewer/: provides the following notable files for the document viewer
    • viewer.js: stores the currently shown document and its notes and sections
    • document.js: stores state for the document renderer, including whether the sidebar is expanded, which viewer mode is selected, etc.
  • search/: provides files to manage the set of documents returned for a search and highlight search queries
  • entities/: provides entities.js to manage the set of entities currently shown for a document
Clone this wiki locally