Skip to content

Latest commit

 

History

History
128 lines (99 loc) · 3.15 KB

File metadata and controls

128 lines (99 loc) · 3.15 KB

A few notes on coding conventions used in this project.

Tooling

Run these commands to perform type and style checks and automatically reformat code based on conventions:

make check           # Type check + lint frontend and backend
make fmt             # Format all code

Code Style Guidelines

TypeScript (client and plugs)

Import Organization

// Use relative imports by default (include .ts extension)
import { Space } from "./space.ts";
// Use `type` for type-only imports (part of the lint rules)
import type { Command } from "./types/command.ts";

// Use package-prefixed absolute when available (defined in deno.json)
import { sleep } from "@silverbulletmd/silverbullet/lib/async";

TypeScript Conventions

  • Use type over interface for object shapes
  • Use type for unions and complex types
  • Always type function parameters explicitly
  • Type return values for public APIs
  • Let TypeScript infer obvious variable types
  • Use any for error objects in catch blocks

Naming Conventions

  • Variables & functions: camelCase
  • Classes: PascalCase
  • Files: snake_case.ts (e.g., http_space_primitives.ts)
  • Test files: *.test.ts alongside source files
  • Types: PascalCase (e.g., PageMeta, SpacePrimitives)
  • Constants: camelCase

Testing Patterns

TypeScript tests run with Deno.

Test structure:

Deno.test("Test description in plain English", async () => {
  // Setup
  const kv = new MemoryKvPrimitives();
  const space = new Space(new DataStoreSpacePrimitives(kv), eventHook);
  
  // Execute
  await space.writePage("test", testPage);
  
  // Assert
  assertEquals(await space.readPage("test"), testPage);
});

Assertions:

import { assertEquals, assertNotEquals } from "@std/assert";

assertEquals(actual, expected);
assertNotEquals(actual, notExpected);

Test configuration:

Deno.test("Test with options", {
  sanitizeResources: false,
  sanitizeOps: false,
}, async () => {
  // test code
});

Comments & Documentation

Use JSDoc for public APIs:

/**
 * Lists all pages (files ending in .md) in the space.
 * @param unfiltered - Whether to include filtered pages
 * @returns A list of all pages represented as PageMeta objects
 */
export function listPages(unfiltered?: boolean): Promise<PageMeta[]> {
  return syscall("space.listPages", unfiltered);
}

Inline comments:

  • In case of doubt: add comments around the why of the code (not what)
  • Add TODO comments for known issues
// Note: these events are dispatched asynchronously (not waiting for results)
this.eventHook.dispatchEvent(...);

// TODO: Clean this up, this has become a god class
export class Client {

Code Patterns

Definite assignment for late initialization:

class Client {
  space!: Space;        // Initialized in init()
  editorView!: EditorView;
}

Destructuring:

const { name, def } = command;
const { text, meta } = await this.space.readPage(name);

Go (server)

Follow common Go conventions. make fmt also reformats Go code.

Lua (libraries)

See website/Space Lua/Conventions