Version 3.10.0 · All versions

All pages

These are the docs as released with Solid Memo 3.10.0. Read the latest docs.

Boundaries

Import rules between packages. These are the load-bearing walls of the codebase; a change that violates them is wrong even if it works.

Enforcement

npm run check:boundaries (checkBoundaries.ts, run by npm run check and in CI) reads every import of every workspace package and fails on:

Test files follow the same rules as their subject; they and the vitest configs may also use the shared test tooling of the root package.json.

An example

A screen in ui may use what the use cases give it, since ui may import application (the table below):

// packages/ui/src/ui/DeckListContainer.tsx
import type { UseCases } from "@solid-memo/application/useCases";

It may not reach for an adapter, such as the guest's pod in solid:

// packages/ui/src/ui/SomeScreen.tsx
import { createLocalPod } from "@solid-memo/solid/localPod";

The check names the file and the rule, once for each problem, and fails:

packages/ui/src/ui/SomeScreen.tsx: @solid-memo/ui may not import @solid-memo/solid.
packages/ui/src/ui/SomeScreen.tsx: imports @solid-memo/solid, which package.json does not declare.
2 boundary problem(s).

The fix is a use case: the screen calls one on UseCases, and composition wires the adapter behind its port. A package that may import another only from some files says which. Importing the composition root anywhere in apps/web but its entry point gives:

apps/web/src/App.tsx: only files matching /^src\/main\.tsx$/ may import @solid-memo/composition.

When every import keeps to the rules, the check prints "Every package keeps to its boundaries."

Layers

PackageMay importOnly from
turtle—
markdownturtleturtle: tooling/ only, to read the docs' index (markdown.md)
vocabturtleturtle: tooling/ only
domainvocab
applicationdomain, vocab
shacldomain, vocab, turtle, markdownturtle, markdown: node/ only
solidapplication, domain, vocab, shacl
browserapplication, domain
uiapplication, domain, vocab, markdownmarkdown: src/ui/ only
compositionapplication, domain, vocab, solid, browser
webapplication, domain, vocab, ui, composition, studio, markdowncomposition: src/main.tsx only; studio: src/main.tsx only, with a dynamic import(); markdown: vite.config.ts and src/build.test.ts only, its node tooling, which renders the docs (markdown.md)
studioapplication, domain, vocab, ui
e2e-podapplication, domain, vocab, solid
e2e-journeysuiui: harness/strings.ts only, for the app's messages

Browser code: src/ of markdown, vocab, domain, application, shacl, solid, browser, composition, ui, web and studio; vocab's and markdown's tooling/ are node-only.

Vendor libraries

Each is a dependency of only the packages listed (and so, by the check, used nowhere else):

LibraryPackageNotes
@inrupt/solid-client, @inrupt/solid-client-authn-browsersolidshacl also uses @inrupt/solid-client to parse shape documents; deck files are written and read with it too (below); its access control (universal access, ACP, the ACL functions) only in src/solidReleasePublisher.ts (below)
@tanstack/react-query, preactui, web, studiothe components; in web, main.tsx to render the page and App.tsx, the page; in studio, its screens
@fontsource/*, @fontsource-variable/*ui, markdownin ui, src/style.css only; in markdown, @fontsource-variable/fredoka in tooling/drawDiagrams.ts only, to embed Fredoka in the docs' diagrams (markdown.md)
rdf-validate-shaclshaclsrc/engine.ts only, loaded lazily
mdast-util-from-markdown, micromark-extension-gfm-table, mdast-util-gfm-table, micromark-extension-cjk-friendlymarkdownsrc/parse.ts only; the package's API is its own types, never mdast's (markdown.md)
n3turtle, the node tooling of shacl, and e2e-podnever in the browser; in e2e-pod, the server contract and the tests
fake-indexeddbbrowser, compositiontests only: IndexedDB in node, for the guest's pod's store
@playwright/teste2e-journeysdrives the built app in Chromium; the harness also talks to the Solid server with its request API
mermaid, playwrightmarkdowntooling/drawDiagrams.ts only, never in the browser (the check holds both node-only): Mermaid draws the docs' diagrams in Chromium, which playwright starts (markdown.md); development tools, so Mermaid's packages before 1.0.0 are not shipped (vendor-code.md)

Files without a vendor library

A deck saved as a file, or read from one (studio.md), needs no library of its own:

Access control

The app changes who may read something in one place only: a release it publishes is made readable by everyone (studio.md). That write is confined to the ReleasePublisher port's adapter, solidReleasePublisher.ts, which calls @inrupt/solid-client's universalAccess.setPublicAccess for the release's document alone, asking read and nothing else. The library writes that document's own ACL (Web Access Control) or ACR (Access Control Policies). No other module imports universalAccess, or writes an ACL or an ACR; no folder's access control is changed. npm run check:boundaries enforces the imports (checkBoundaries.ts, VENDOR_ONLY_FROM): outside tests, only that file may import @inrupt/solid-client's access control (universalAccess, the acp_* modules, the ACL functions), or all of the library at once (import * as). That no module writes an ACL or an ACR with a plain request is for review: the check sees imports alone.

Further rules

Adding a dependency

  1. Decide which single package it belongs to, and add it to that package's package.json (npm install <lib> -w @solid-memo/<package>).
  2. If it performs I/O, wrap it behind a port in packages/application/src/ports.ts and implement the port in an adapter package.
  3. Add it to the vendor table above.