@suwatte/toolchain
v1.0.0
Published
Build, validate, and test Source plugins for Suwatte
Maintainers
Readme
@suwatte/toolchain
The official, standalone toolkit for building Source plugins for Suwatte. It includes the public TypeScript types, runtime helpers, compiler, command-line interface, emulator, and validation schemas in one package. It does not depend on another Suwatte-scoped package.
Requirements
- Node.js 22 or newer
sharp0.34 when emulator tests need native image processing
Installation
npm install --save-dev @suwatte/toolchainThe package installs the suwatte command in the project.
Project layout
Put each Source in its own directory under src/sources. Every Source needs an
index.ts file with a default export.
my-catalog/
├── package.json
├── tsconfig.json
└── src/
└── sources/
├── example-en/
│ └── index.ts
└── example-ja/
└── index.tsThe default export must be a delegate class with a static info property.
Source metadata includes id, name, version, website, languages, and a
numeric ContentRating value. Optional static variants generate additional
artifacts from the same delegate class.
Command line
Build the catalog:
npx suwatte buildThe build writes installable .stt bundles and the source-list webpage to
dist/:
dist/
├── sources/
│ └── example-en.stt
├── sources.json
├── index.html
├── main.css
└── catalog.jsServe the same catalog on the local network for device testing:
npx suwatte serveBoth commands accept -f, --folder <folder> to change the output directory and
--timings to print build diagnostics. serve also accepts
-p, --port <port>; the default port is 8080.
See The command line for the device-testing workflow.
Package exports
| Export | Purpose |
| --- | --- |
| @suwatte/toolchain | Public Source types and runtime helpers |
| @suwatte/toolchain/types | Source, content, chapter, page, and networking types |
| @suwatte/toolchain/runtime | Source-class and variant runtime helpers |
| @suwatte/toolchain/emulator | Node.js shims for stores, networking, crypto, and native images |
| @suwatte/toolchain/validate | Zod schemas and delegate validation helpers |
Emulator
Use the emulator to run a Source without the app:
import emulate from "@suwatte/toolchain/emulator";
import Target from "./src/sources/example-en";
const source = emulate(Target);
const results = await source.getSearchResults({ query: "example" }, 1);The emulator provides the same Source-facing globals used by the app, including
ObjectStore, SecureStore, NetworkClient, HttpClient, NetworkError, and
CloudflareError. See The emulator
for reset controls and test patterns.
Validation
The validation export checks delegate results during development without
changing the .stt runtime contract:
import {
ContentSchema,
wrapDelegateWithValidation,
} from "@suwatte/toolchain/validate";
ContentSchema.parse(contentPayload);
const validatedDelegate = wrapDelegateWithValidation(delegate, "example-en");Networking compatibility
Legacy NetworkClient requests cross the app's JavaScriptCore-to-Swift bridge.
Their body must be a plain JSON-compatible dictionary. Keep
application/x-www-form-urlencoded bodies as dictionaries because the native
client performs the encoding:
await client.request({
url: `${baseUrl}/wp-admin/admin-ajax.php`,
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: { action: "manga_get_chapters", manga: mangaId },
});Use HttpClient when a request intentionally needs a raw string or
Uint8Array body. The emulator rejects pre-serialized legacy form bodies so
that local tests match the native bridge.
See Networking for the two network stacks and their directives.
Identifier convention
- Language variants:
LANG.DOMAIN - Non-language service variants:
LANG.DOMAIN.VARIANT - Normalize
LANGidentifiers to lowercase, hyphenated tokens. Keep canonical BCP 47 casing in the metadatalanguagesfield.
Changing a Source identifier creates a different Source and disconnects saved library entries from it. See Versions before changing identifiers or compatibility requirements.
Development
npm ci
npm test
npm pack --dry-runThe test command performs a clean TypeScript build before running the Node.js test suite. The package is licensed under the MIT License.
