1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-10 13:40:06 +00:00
Files
browser/libs/tools/generator/conventions.md

3.8 KiB

Conventions

This file outlines the code conventions that we're applying to code within the generator modules. These conventions supplement the conventions in the contributing documentation.

Important

If you are using a programming assistant, please include this file in the prompt's context when generating code.

Modules

Every source folder is treated as a module, and must have a barrel file. It may import from its ancestors and its children. Modules should not import from their cousins or grandchildren. Do not import barrel files from parent scopes.

Do:

import foo from "../../foo";
import bar from "../bar";
import baz from "../baz.ts";

import biz from "./biz";

Do not:

import foo from "../";
import bar from "../../foo/bar";
import baz from "../bar/baz.ts";

import buz from "./baz/biz/buz";

Barrel files (ADR-0002)

The root barrel file contains all public exports of the module. All other barrel files are internal to the module. This is presently enforced with a lint.

Common files

The following files may be used to consolidate low-level module items.

  • data.ts <- constants; may only depend on external modules.
  • index.ts <- exports; may define aggregates and apply type assertions to improve module DevEx.
  • type.ts <- type definitions; may only depend on data.ts and external modules.
  • util.ts <- utility functions; may only depend on data.ts, type.ts, and external modules.

Example

Tip

Implementing the const object pattern (ADR-0025):

  1. Write the const object into data.ts
  2. Derive type definitions from the const object in type.ts
  3. Import types and data into index.ts, perform type assertions, and re-export the data.

Rx (ADR-0015)

Reactive code should be written functionally, with liberal use of observable injection. Core rx code should not depend on services. It should depend solely on reactive objects and functions.

Services and other long-lived components compose the rx logic for injection into other contexts. They read observables from their dependencies and inject them into the Core rx code.

Example

Logging

The generator's reactivity model is time-sensitive, which makes identifying and diagnosing runtime behaviors difficult. Consider, for example, interactively debugging an observable subject to timeout(). Because the computer's clock keeps running when the debugger is paused, stopping a program subject to this operation can exhaust the timeout, resulting in heisenbugs. The generator's permanent runtime logging facilities decrease this complexity of debugging by writing structured logs using the SemanticLogger.

When a generator creates a logger, it sets the log's type parameter. This can be filtered by editing XYZ.

Caution

The SemanticLogger writes arbitrary runtime information into the console. It is automatically disabled outside of development environments to mitigate data leaks.

Navigation