feat(docx-editor): ship it in the build, updated over the first-party channel

Moving it out of the build left it with no way in. Settings can only install
from the community catalogue, so a first-party extension that isn't bundled
has a working update channel and no first copy for anyone to update — the
mechanism was all there and the front door was missing.

So it goes back beside screenshot, aegis and pdf-editor: seeded into every
profile by the build, listed under "Built into Theseus", and kept current
between releases by the operator-signed channel at
theseus.x/extensions/docx-editor/. That is the arrangement docs/ADDON-UPDATES.md
describes, and the one the signing script was written for.

About 400 KB compressed in the installer, most of it the vendored editor
libraries — next to the ~4 MB of pdf.js that pdf-editor already ships, the
weight argument for keeping it out didn't survive contact with the numbers.

The end-to-end driver goes back to checking that a fresh profile seeds it,
which is the property that actually matters now.
This commit is contained in:
Local Dev 2026-09-21 22:47:13 +02:00
parent 59593033a1
commit 56b3f2f206
25 changed files with 15 additions and 11 deletions

View file

@ -1,5 +1,5 @@
// Bundles the extension's npm dependencies into // Bundles the extension's npm dependencies into
// extensions/docx-editor/vendor/docx-vendor.js. // bundled-addons/docx-editor/vendor/docx-vendor.js.
// //
// npm run build (from addon-build/docx-editor/) // npm run build (from addon-build/docx-editor/)
// //
@ -13,7 +13,7 @@ import path from "node:path";
import { applyPatches, patches } from "./patches.mjs"; import { applyPatches, patches } from "./patches.mjs";
const here = path.dirname(fileURLToPath(import.meta.url)); const here = path.dirname(fileURLToPath(import.meta.url));
const out = path.resolve(here, "../../extensions/docx-editor/vendor"); const out = path.resolve(here, "../../bundled-addons/docx-editor/vendor");
const patchedRoot = path.join(here, ".patched"); const patchedRoot = path.join(here, ".patched");
// --- 1. patched mammoth --------------------------------------------------- // --- 1. patched mammoth ---------------------------------------------------

View file

@ -15,7 +15,7 @@ import os from "node:os";
const here = path.dirname(fileURLToPath(import.meta.url)); const here = path.dirname(fileURLToPath(import.meta.url));
const ROOT = path.resolve(here, "../.."); const ROOT = path.resolve(here, "../..");
const EXT = path.resolve(ROOT, "extensions/docx-editor"); const EXT = path.resolve(ROOT, "bundled-addons/docx-editor");
const SIZES = [16, 32, 48, 128, 256]; const SIZES = [16, 32, 48, 128, 256];
const electron = path.join(ROOT, "node_modules", "electron", "dist", const electron = path.join(ROOT, "node_modules", "electron", "dist",

View file

@ -2,7 +2,7 @@
"name": "docx-editor-vendor-build", "name": "docx-editor-vendor-build",
"private": true, "private": true,
"version": "0.0.0", "version": "0.0.0",
"description": "Build-time only: bundles mammoth + ProseMirror + docx into extensions/docx-editor/vendor/, and rasterises the icon.", "description": "Build-time only: bundles mammoth + ProseMirror + docx into bundled-addons/docx-editor/vendor/, and rasterises the icon.",
"type": "module", "type": "module",
"scripts": { "scripts": {
"build": "node build.mjs", "build": "node build.mjs",

View file

@ -14,7 +14,7 @@ import { JSDOM } from "jsdom";
const here = path.dirname(fileURLToPath(import.meta.url)); const here = path.dirname(fileURLToPath(import.meta.url));
const require = createRequire(import.meta.url); const require = createRequire(import.meta.url);
export const ADDON = path.resolve(here, "../../../extensions/docx-editor"); export const ADDON = path.resolve(here, "../../../bundled-addons/docx-editor");
export function loadAddonLibs() { export function loadAddonLibs() {
const dom = new JSDOM("<!doctype html><html><body></body></html>"); const dom = new JSDOM("<!doctype html><html><body></body></html>");

View file

@ -17,12 +17,16 @@ operator key, and updated over the channel at
It does not go through the community catalogue, which is for extensions It does not go through the community catalogue, which is for extensions
published by whoever owns a BNS name. published by whoever owns a BNS name.
It currently lives outside `bundled-addons/`, so it is not compiled into the It ships inside Theseus, so a fresh install already has it and Settings
browser and a fresh profile doesn't have it. That keeps a megabyte of lists it under **Built into Theseus**; the channel above then updates it
vendored library off everyone who only wanted a browser — but note that between releases without waiting for one. That is the same arrangement as
Settings can only *install* from the community catalogue, so until it is screenshot, aegis and pdf-editor, and it is what gives a user their first
either bundled or listed there, the update channel keeps an existing copy copy at all — Settings can only *install* from the community catalogue, so
current without giving anyone a way to get the first one. an extension that is neither bundled nor catalogued has a working update
channel and no way in.
The cost is about 400 KB compressed in the installer, most of it the
vendored editor libraries.
## The icon ## The icon

View file

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

View file

Before

Width:  |  Height:  |  Size: 695 B

After

Width:  |  Height:  |  Size: 695 B

View file

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

View file

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

Before

Width:  |  Height:  |  Size: 2 KiB

After

Width:  |  Height:  |  Size: 2 KiB