dsteem Modernization Plan -Final Phase -7

in Steem Dev2 hours ago

Day 7: the short, satisfying one. typedoc 0.13 → 0.28 (an absurd 15-minor-version jump), drop the ugly sed post-processing the old Makefile needed to fix absolute paths in the generated HTML, and replace it all with a four-line typedoc.json. The API documentation regenerates cleanly with the modern layout. With this done, the modernization is feature-complete — every architectural change from the Phase 0 plan is in. All that's left is the release ceremony next week.

dsteem-phase-7-typedoc.png



Where typedoc Was Stuck

[email protected] was the version pinned in v0.11.3 from 2018. The current version is 0.28.19. Some of the things that changed between those two:

Eratypedoc behavior
0.13 (2018)--mode file, baked absolute filesystem paths into output HTML, required CLI flags for everything
0.20 (2021)Added typedoc.json config file support
0.22 (2021)Removed --mode, switched to "entry point" model
0.24 (2023)Switched to TypeScript's own type-resolution machinery
0.25 (2023)Auto-detects tsconfig.json instead of needing --target ES6 --mode file
0.28 (2025)Modern responsive theme, proper search index, no absolute-path leakage

The old Makefile invocation looked like this:

docs: $(SRC_FILES) node_modules
    typedoc --gitRevision master --target ES6 --mode file --out docs src
    find docs -name "*.html" | xargs sed -i '' 's~$(shell pwd)~.~g'
    echo "Served at <https://jnordberg.github.io/dsteem/>" > docs/README.md
    touch docs

That sed -i '' is BSD syntax (macOS-only) — GNU sed (Linux/Windows) accepts it as a filename argument and writes the substitution-result to a file literally named ''. So the old make docs target only worked on macOS, and the only reason it existed at all was to scrub the absolute path /Users/jnordberg/dsteem out of the generated HTML.


he New Setup

typedoc.json:

{
  "$schema": "https://typedoc.org/schema.json",
  "entryPoints": ["src/index.ts"],
  "out": "docs",
  "readme": "README.md",
  "tsconfig": "tsconfig.json",
  "excludePrivate": true,
  "excludeInternal": true,
  "gitRevision": "master"
}

package.json script:

+ "build:docs": "typedoc",

That's it. Modern typedoc:

  • Auto-discovers the entry point and resolves the full export graph from src/index.ts
  • Uses the project's existing tsconfig.json for type resolution (no duplicate config)
  • Doesn't bake absolute paths into the output (the sed post-processing is gone)
  • Generates a search index, a sidebar, and a responsive theme by default
  • Hides private and @internal-tagged members from public docs automatically

The whole docs build is now npm run build:docs. No Makefile. No sed. Works on every platform.


The Phase 7 Result

$ rm -rf docs && npm run build:docs

[warning] BroadcastAPI, defined in dsteem/src/helpers/broadcast.ts, is referenced
          by Client.broadcast but not included in the documentation
[warning] Manabar, defined in dsteem/src/steem/rc.ts, is referenced by
          RCAPI.calculateRCMana but not included in the documentation
[info]    html generated at ./docs
[warning] Found 0 errors and 10 warnings

$ ls docs/*.html | head -5
docs/hierarchy.html
docs/index.html
docs/modules.html
  • 0 errors
  • 10 warnings — all about transitively-referenced types that aren't directly exported from src/index.ts. They're internal-shape types (BroadcastAPI, Manabar, RCAccount) accessed via Client.broadcast / Client.rc. Adding them to the entry-point export list would fix the warnings; deferring for now since they're warnings, not blockers.
  • Generated HTML in docs/ with the new theme — works directly on GitHub Pages.

🧠 The Meta-Lesson

Doc-gen tools age in a peculiar way: they often work just well enough that nobody notices they're broken until a fresh person tries to regenerate the site on a clean machine and discovers sed writes a file literally called ''. The cost of keeping them current is low (an annual npm install --save-dev typedoc@latest and a rerun); the cost of skipping it is the slow accumulation of platform-specific hacks like that find ... | xargs sed -i '' workaround.

The pattern generalizes. Every dev tool that ships HTML/markdown output deserves the same yearly check: does it still work on Linux + Mac + Windows? Does its config format still match the docs? Is its default theme still readable?

If you can't say yes to all three, swap it out before the workaround crust gets any thicker.


The Modernization Is Feature-Complete

Phases 0 through 7 have shipped. Here's the full end-state of the project today:

Production dependency tree (5 packages)

@noble/curves    ← secp256k1 ECDSA (audited, pure-JS)
@noble/hashes    ← SHA256, RIPEMD160 (audited, pure-JS)
bs58             ← Base58 encoding (for WIF)
bytebuffer       ← binary serialization
verror           ← error wrapping

Test + build pipeline (npm scripts only)

npm run lint          ← ESLint 9 flat config (0 errors)
npm run build         ← tsup → dist/index.{cjs,mjs,d.ts} + dsteem.browser.global.js
npm test              ← mocha 11, 50 passing, 438ms
npm run coverage      ← c8 with 70% line-coverage gate (currently 73.22%)
npm run test:browser  ← Playwright headless smoke against the bundled artifact
npm run build:docs    ← typedoc 0.28
npm run prepublishOnly← lint + build + test in one

Final checklist (all green)

CheckResult
npm run lint0 errors, 43 warnings (unused-vars only)
npm run builddist/index.{cjs,mjs,d.ts} + dist/dsteem.browser.global.js
npm test50 passing
npm run coverage73.22% line coverage — passes 70% gate
npm run test:browserPlaywright chromium: smoke passes
npm run build:docsdocs/index.html regenerated
Live api.steemit.comhead block 106461966 ✓
Live api.moecki.onlinehead block 106461967 ✓
npm audit --omit=dev0 vulnerabilities in production deps
npm pack --dry-run11 files, 792.7 KB tarball
Browser bundle size351 KB (down from 782 KB — -55%)
Public API surfacebyte-compatible with v0.11.x (golden vectors confirm)
Node version supported>=22.0.0

What's Left for Phase 8 (Next Week)

Phase 8 is the release ceremony, not an engineering phase. The work left:

  • Update README.md with the new install instructions, CDN URLs, Node 22 minimum, and the dual-RPC documentation
  • Update CLAUDE.md to replace Makefile references with the new npm run * scripts (done in passing as part of the Phase 5/6 work — needs a final review)
  • Bump package.json to "version": "0.12.0" (done in passing — Phase 8 will verify)
  • Run npm publish --dry-run and visually inspect the file list
  • Tag v0.12.0, push, let CI build, confirm green
  • npm publish

Plus the things I deliberately deferred for the release post:

  • Final security retrospective: what the threat model looked like at v0.11.3 vs. v0.12.0
  • Migration guide for anyone with [email protected] in package.json (spoiler: it's npm install dsteem@^0.12)
  • A "thanks" section to the upstream maintainers, the @noble crypto ecosystem, and everyone who pinged me with questions during the week

The Phase 8 post lands next week, after the npm publish. Until then, the work is on the blazeapps007/dsteem fork — pull it, try it, file issues.


🧠 The Whole-Week Meta-Lesson

Modernizing a multi-year-stale library is not glamorous. There's no exciting new feature to announce, no benchmark to brag about, no architecture diagram that makes everyone nod sagely. It's a week of replacing one tool with another and then making sure nothing broke.

But that week of work matters for everyone who builds on Steem. Every developer who picks up [email protected] will:

  • Skip the node-gyp rabbit hole that bit them at [email protected]
  • Get TypeScript IntelliSense that actually works (proper .d.ts instead of one giant declaration file)
  • Use the package in modern bundlers (Vite, esbuild, webpack 5) without browser field hacks
  • Avoid the high-severity CVE that's sitting in their node_modules right now
  • Run the package on Node 22 / Node 24 / Bun / Deno without compatibility shims

That's the value. Not novelty — removed friction. And friction removed is friction that won't keep nudging some future developer toward abandoning Steem dev because "the SDK is annoying."

Boring modernization work is the unsexy half of OSS sustainability. I hope this week of posts makes the why of that work visible to people who use the result without ever seeing the code.


🙏 Halfway Thank-You

This is post 7 of 8. The release post is next week. Thank you to everyone who's been reading the series, vote-boosting the posts, and following along on GitHub. The witness votes since the series started have been genuinely motivating — if you're enjoying the technical depth, please keep them coming for next week's release post too.


🤝 How You Can Help

  • 🔍 Watch the repo: blazeapps007/dsteem
  • 🧪 Test the pre-release: clone the repo, npm install, npm test, try npm pack and npm install ./dsteem-0.12.0.tgz in one of your existing projects. The whole point of API compatibility is that nothing should break.
  • 🐛 File issues: anything that misbehaves between v0.11.3 and the upcoming v0.12.0 is a P0. API compatibility is non-negotiable.
  • 💬 Comment: questions about specific phase choices help shape the rest of the series — and the release post next week is a great place to ask "but why didn't you do X?"

This work was developed with Claude AI assistance. All technical decisions reflect Steem ecosystem needs and the hard requirement of zero breaking .


Support Secure Steem Development

If you value proactive engineering, UX polish, and performance optimizations for the STEEM ecosystem, please consider supporting my witness: blaze.apps

🗳️ Vote Here:
Vote for blaze.apps Witness

Disclaimer: This post describes work in progress on the blazeapps007/dsteem fork. The release will be tagged v0.12.0 after Phase 8 ships next week.