Skip to content

Mallok 0.1.0-rc.10

Pre-release
Pre-release

Choose a tag to compare

@JasonYv JasonYv released this 05 Oct 16:49
· 15 commits to main since this release

Plugin API 2 — what a plugin that ships inside a site needs to render its own data, serve its own pages and be edited in the admin — and three admin defects. Read the upgrade notes: several things existing sites, themes and plugins relied on have changed.

Fixed

  • The admin no longer goes blank when a second content item is opened in one session. Any part of the admin that loads on demand crashed the second time it was shown; a reload was the only way back.
  • Opening an item no longer marks it "Unsaved". The Markdown pane reported the document being loaded into it as an edit. For a document with Windows line endings, publishing it untouched rewrote every line ending.
  • A plugin secret that has been removed is shown as not set without a reload.
  • A theme that declares clientScripts is checked like any other. Declaring one script used to switch the script check off for the whole theme. See the upgrade notes.

Added

  • Settings → Email. The Resend key and the sender address are site settings, used by every plugin that sends email. PUT /_mallok/api/settings/email, POST /_mallok/api/settings/email/check.
  • Plugin API 2 (docs/PLUGIN_API.md §13). A plugin declares "pluginApi": 2 to use it; a plugin declaring 1 keeps the behaviour it had, except where the upgrade notes say otherwise.
    • renderData: a hook that reads the plugin's own tables while a page is rendered, so a theme prints plugins.<plugin_id> in the cached HTML. One database call per hook, read-only, at most two plugins per page; a failing hook costs the page that data and its place in the cache, never the page.
    • renderData may add offers to the page's Product structured data, and declare cache tags of its own (p:<plugin-id>:<tag>).
    • Routes with several segments and :parameters, a locale segment after the plugin id, and JSON bodies passed whole as input.json.
    • Rate-limit tiers: "rateLimit": "strict" | "relaxed", each a binding in wrangler.jsonc, counted per route.
    • Pages: a route with "render": "page" returns a view and a theme layout declared in pluginLayouts renders it, private and unindexed.
    • onContentDelete, and editable records panels with money and rows fields, sorting and search, optionally attached to the editor of one content kind.
  • Themes may declare pluginLayouts, and read plugins on every page.

Upgrade notes

Every site

  • The Resend key and sender move from Plugins → Inquiry to Settings → Email on the first request after deploying. Nothing needs re-entering. A script that wrote the key with PUT /plugins/inquiry/secrets {"resend_api_key": …} gets 400; use PUT /settings/email. Rolling back to an earlier release after the move leaves the inquiry plugin without its key: re-enter it there.
  • Add the second rate-limit binding. mallok upgrade does not edit wrangler.jsonc. Add RATE_LIMITER_RELAXED to ratelimits with a namespace_id of its own and deploy (docs/CLOUDFLARE_RESOURCES.md §4). Until then a route asking for the relaxed tier is held to the strict one.
  • A POST to a plugin route from another site is refused (403). An inquiry form embedded on a different domain stops working; a form on the site itself is unaffected.
  • Rate-limited plugin routes are counted per route, no longer per plugin.

Sites with their own theme

  • A theme that declares clientScripts may contain only <script src="{{ theme.asset_base }}/…"> tags naming a declared file. Inline script, a JSON-LD block included, on…= attributes and scripts from anywhere else fail the build, naming the template.

Sites with their own plugins

  • onContentSave is now called. It was documented and never run. A plugin that declares it starts rewriting or refusing saves; it must give the same answer for the same input, or every mallok publish becomes a change.
  • ctx.purgeTags purges only the calling plugin's own tags, and site. A plugin that purged a core tag such as c:<id> declares its own tag from renderData and purges that.
  • A plugin that omits pluginApi is now taken as version 2, and a version 2 route may not start with a segment shaped like a locale code (de, go, my-cart). Declare "pluginApi": 1 or rename the route.
  • The inquiry plugin's from_address is optional; empty uses the site sender.

Upgrade with npx mallok upgrade --to 0.1.0-rc.10, then follow the upgrade notes above.

Candidate provenance

  • Source: 476eb32b6042f5ae9d2045a7179fb1c32ff1a152
  • Artifact: mallok-0.1.0-rc.10.tgz
  • SHA-256: 899d942af9a76ca07a90e6ebce620c8555a08bcd85731478712ddc991dec234f
  • Local release gate: lint, typecheck, unit and integration tests, real-upgrade tests, build and bundle budgets, static build, coverage floor, browser and accessibility checks and a whole-history secret scan passed; the exact-artifact consumer checks passed against this tarball with the build directory moved away.
  • GitHub CI and the complete release gate passed. The Linux CI tarball is byte-for-byte identical to the local one, a clean-clone rebuild reproduced it exactly, and the tarball npm serves is the same file.
  • The isolated test site was upgraded from rc.9 with mallok upgrade, given the second rate-limit binding as the upgrade notes say, and deployed. Checked on the deployed site without signing in: pages in both languages, the SEO endpoints, cache MISS/HIT/HEAD behaviour, the credential bypass, the admin boundary, one JSON-LD node on a product page, a cross-site POST to the inquiry form answered 403 and a same-site one accepted. The maintainer, signed in to the deployed admin after the upgrade, reported Settings → Email already showing the sender and the Resend key — the move from the inquiry plugin ran — and a second content item opening normally in one session, with nothing marked unsaved.

Known limitations

This is not stable 0.1.

  • Plugin API 2 has been exercised by test plugins, not by a real one on a deployed site. renderData, plugin pages, records panels and the content hooks are covered by Worker and browser tests; no deployed site has run them yet.
  • Not verified on a deployed site: email delivery with the moved Resend key, a purge by plugin cache tag, and that the two rate-limit bindings count separately. Whether Cloudflare's Free plan includes rate-limit bindings is still not stated in its documentation.
  • No new CPU sample was taken; the rc.5 measurements remain historical. renderData and the save hooks add work to requests that already exceeded the 10 ms target there.
  • Real inquiry email delivery, the seven-day media cleanup check, full second-site restore and production upgrade/rollback acceptance remain open. See docs/RELEASE_STATUS.md.

npm is published: mallok@0.1.0-rc.10; next and latest point to it.