@ckeditor/ckeditor5-dev-manual-server 61.1.0 → 61.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +0 -98
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -197,7 +197,6 @@ function manualTestsPlugin(options) {
197
197
  rewriteCatalogRequest(request, getManualCatalogPublicPath());
198
198
  next();
199
199
  });
200
- keepManualHtmlSourceFresh(server.environments.client.bundledDev?.memoryFiles, getManualPages, workspaceRoot);
201
200
  },
202
201
  resolveId(source) {
203
202
  if (source == MANUAL_ENTRIES_VIRTUAL_ID) return resolvedVirtualModuleId;
@@ -246,77 +245,6 @@ function manualTestsPlugin(options) {
246
245
  };
247
246
  }
248
247
  /**
249
- * Keeps the served manual test HTML in sync with the source file while the dev server runs.
250
- *
251
- * Under `experimental.bundledDev`, Vite serves each manual test's HTML from an in-memory bundle
252
- * produced by the rolldown dev engine. That engine emits the HTML output only during the initial
253
- * build and never regenerates it when the source `.html` changes: its bundle state reports no
254
- * stale output for HTML entries, `devEngine.invalidate()` throws on a non-JS module, and even a
255
- * forced full build leaves the HTML memory file untouched (verified against Vite 8.2.1). A `.html`
256
- * edit still triggers a full page reload, so without this the browser reloads into the same stale
257
- * HTML until the server is restarted.
258
- *
259
- * The built-in-memory HTML rewrites the entry script, injects the asset tags and manual chrome,
260
- * and copies the source `<head>` — all inside `<head>`. The markup after `</head>` is a verbatim
261
- * copy of the source. So on every request we keep the freshly built `<head>` and splice in the
262
- * current post-`</head>` markup read from disk. Splicing unconditionally (rather than only after a
263
- * detected change) also covers sources that changed between the initial build and the first request
264
- * for the page, and it is idempotent for unchanged sources. This reflects edits to the test body
265
- * without re-running Vite's HTML transform or parsing the document. Any edit that would change
266
- * what belongs in `<head>` is not picked up this way and still needs a server restart, because
267
- * reproducing it would require re-running the build pipeline the dev engine refuses to run for HTML
268
- * entries. That covers edits confined to the `<head>` (styles, meta, extra scripts) as well as
269
- * adding or removing `<ck-manual-header>` in the body: toggling it changes the injected header
270
- * chrome (`<meta>` and the component script) in `<head>`, so the chrome only updates after a
271
- * restart even though the body splice already reflects the element itself.
272
- *
273
- * When `bundledDev` is not enabled the store is absent and this is a no-op: Vite's normal dev
274
- * pipeline already serves fresh HTML on every request.
275
- */
276
- function keepManualHtmlSourceFresh(memoryFiles, getManualPages, workspaceRoot) {
277
- if (!memoryFiles) return;
278
- const getBundledFile = memoryFiles.get.bind(memoryFiles);
279
- memoryFiles.get = (filePath) => {
280
- const file = getBundledFile(filePath);
281
- if (!file || !getManualPages().has(toPublicSpecifier(filePath))) return file;
282
- try {
283
- const sourceFilePath = resolve(workspaceRoot, stripLeadingSlash(filePath));
284
- const freshHtml = composeFreshManualHtml(file.source, readFileSync(sourceFilePath, "utf8"));
285
- return freshHtml == null ? file : { source: freshHtml };
286
- } catch {
287
- return file;
288
- }
289
- };
290
- }
291
- /**
292
- * Combines the freshly built `<head>` (asset tags and injected manual chrome) with the current
293
- * post-`</head>` markup from the source file. Returns `null` when either document is missing a
294
- * `</head>`, so the caller can fall back to the built output.
295
- */
296
- function composeFreshManualHtml(builtHtml, sourceHtml) {
297
- const builtHeadEnd = findHeadCloseTagIndex(builtHtml);
298
- const sourceHeadEnd = findHeadCloseTagIndex(sourceHtml);
299
- if (builtHeadEnd == -1 || sourceHeadEnd == -1) return null;
300
- return builtHtml.slice(0, builtHeadEnd + 7) + sourceHtml.slice(sourceHeadEnd + 7);
301
- }
302
- /**
303
- * Finds the index of the `</head>` closing tag, or `-1` when the document has none. A `</head>`
304
- * literal may also appear earlier inside a `<head>` comment or an inline script string, so of all
305
- * the occurrences preceding the `<body>` tag the last one is taken. Without a `<body>` tag (or
306
- * when every occurrence follows it) the first occurrence wins, matching the pre-heuristic
307
- * behavior for such malformed documents.
308
- */
309
- function findHeadCloseTagIndex(html) {
310
- const firstHeadCloseIndex = /<\/head>/i.exec(html)?.index ?? -1;
311
- const bodyMatch = /<body[\s>]/i.exec(html);
312
- if (!bodyMatch) return firstHeadCloseIndex;
313
- const headClosePattern = /<\/head>/gi;
314
- let lastHeadCloseIndex = -1;
315
- let match;
316
- while ((match = headClosePattern.exec(html)) && match.index < bodyMatch.index) lastHeadCloseIndex = match.index;
317
- return lastHeadCloseIndex == -1 ? firstHeadCloseIndex : lastHeadCloseIndex;
318
- }
319
- /**
320
248
  * Injection contract for the `<ck-manual-header>` component, added to `<head>` only when the
321
249
  * page source contains the element:
322
250
  * - a `<meta>` carrying the package name and the base-aware catalog href the component reads;
@@ -493,7 +421,6 @@ function refreshPlugin() {
493
421
  configureServer(server) {
494
422
  const { bundledDev } = server.environments.client;
495
423
  wrapBundledDevClientSend(bundledDev);
496
- wrapBundledDevFullReloads(bundledDev, server.config.root);
497
424
  },
498
425
  hotUpdate({ file, modules }) {
499
426
  if (file.endsWith(".manual.html")) return modules;
@@ -514,31 +441,6 @@ function wrapBundledDevClientSend(bundledDev) {
514
441
  return setupIfNeeded(client, clientId);
515
442
  };
516
443
  }
517
- function wrapBundledDevFullReloads(bundledDev, workspaceRoot) {
518
- const handleHmrOutput = bundledDev.handleHmrOutput.bind(bundledDev);
519
- bundledDev.handleHmrOutput = (client, files, hmrOutput) => {
520
- if (hmrOutput.type != "FullReload") return handleHmrOutput(client, files, hmrOutput);
521
- if (!shouldShowManualRefreshPrompt(files)) {
522
- reloadClientAfterLatestBuildOutput(bundledDev, client, files, workspaceRoot);
523
- return;
524
- }
525
- ensureLatestBuildOutput(bundledDev);
526
- client.send({
527
- type: "custom",
528
- event: MANUAL_REFRESH_EVENT_NAME
529
- });
530
- };
531
- }
532
- async function reloadClientAfterLatestBuildOutput(bundledDev, client, files, workspaceRoot) {
533
- try {
534
- await bundledDev.devEngine.ensureLatestBuildOutput();
535
- } catch {}
536
- const htmlFile = files.find((file) => isHtmlFile(file));
537
- client.send({
538
- type: "full-reload",
539
- path: htmlFile ? toPublicFilePath(htmlFile, workspaceRoot) : void 0
540
- });
541
- }
542
444
  function ensureLatestBuildOutput(bundledDev) {
543
445
  try {
544
446
  bundledDev.devEngine.ensureLatestBuildOutput().catch(() => {});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ckeditor/ckeditor5-dev-manual-server",
3
- "version": "61.1.0",
3
+ "version": "61.2.0",
4
4
  "description": "Used to extend Vite to create a manual test server for CKEditor 5.",
5
5
  "keywords": [],
6
6
  "author": "CKSource (http://cksource.com/)",
@@ -25,6 +25,6 @@
25
25
  ],
26
26
  "dependencies": {
27
27
  "@ckeditor/ckeditor5-inspector": "^5.0.1",
28
- "vite": "^8.2.1"
28
+ "vite": "^8.2.2"
29
29
  }
30
30
  }