@rohal12/twee-ts 1.17.0 → 1.17.1

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.
@@ -10,6 +10,13 @@ interface LocatedError extends Error {
10
10
  };
11
11
  }
12
12
  //#endregion
13
+ //#region src/plugins/paths.d.ts
14
+ /** The output settings that say where a bundle is written, as Rollup and Vite pass them to generateBundle. */
15
+ interface OutputLocation {
16
+ readonly dir?: string | undefined;
17
+ readonly file?: string | undefined;
18
+ }
19
+ //#endregion
13
20
  //#region src/plugins/rollup.d.ts
14
21
  export interface TweeTsRollupPluginOptions {
15
22
  /** Source directories/files to compile. */
@@ -37,6 +44,9 @@ export declare function tweeTsPlugin(options: TweeTsRollupPluginOptions): {
37
44
  }) => void;
38
45
  error: (error: LocatedError) => never;
39
46
  warn: (message: string) => void;
40
- }): Promise<void>;
47
+ meta: {
48
+ watchMode: boolean;
49
+ };
50
+ }, outputOptions: OutputLocation, bundle: Readonly<Record<string, unknown>>): Promise<void>;
41
51
  };
42
52
  //#endregion
@@ -1,33 +1,59 @@
1
- import { i as compile, n as formatDiagnostic, r as splitDiagnostics, t as fatalError } from "../diagnostics-DZNS7W41.js";
2
- import { resolve } from "node:path";
1
+ import { a as fatalError, c as compileForOutputFile, o as formatDiagnostic, s as splitDiagnostics, t as emittedFilePath } from "../paths-w4ulhCFb.js";
2
+ import { readdirSync } from "node:fs";
3
+ import { join, resolve, sep } from "node:path";
3
4
  //#region src/plugins/rollup.ts
4
5
  /**
5
6
  * Ready-made Rollup plugin for twee-ts.
6
7
  * Compiles .tw files and emits HTML as an asset. Compile errors fail the build
7
8
  * and emit nothing; warnings go through Rollup's warnings.
8
9
  */
10
+ /**
11
+ * What `rollup --watch` watches for the input at the absolute `path`: the path
12
+ * itself, which Rollup watches recursively when it is a folder, unless it holds
13
+ * one of the files the build wrote (`written`). Such a folder is replaced by what
14
+ * it contains, and the written files are left out, so writing them starts no
15
+ * build. A file added straight to that folder later is found at the next build.
16
+ */
17
+ function watchTargets(path, written) {
18
+ if (written.includes(path)) return [];
19
+ if (!written.some((file) => file.startsWith(path + sep))) return [path];
20
+ let entries;
21
+ try {
22
+ entries = readdirSync(path);
23
+ } catch {
24
+ return [path];
25
+ }
26
+ return entries.flatMap((entry) => watchTargets(join(path, entry), written));
27
+ }
9
28
  function tweeTsPlugin(options) {
10
29
  const outputFilename = options.outputFilename ?? "index.html";
30
+ let written = [];
31
+ let writing = [];
11
32
  return {
12
33
  name: "twee-ts",
13
34
  buildStart() {
14
35
  if (!this.meta.watchMode) return;
36
+ if (writing.length > 0) {
37
+ written = writing;
38
+ writing = [];
39
+ }
15
40
  const extra = options.compileOptions;
16
41
  const inputs = [
17
42
  ...options.sources,
18
43
  ...extra?.headFile ? [extra.headFile] : [],
19
44
  ...extra?.modules ?? []
20
45
  ];
21
- for (const input of inputs) this.addWatchFile(resolve(input));
46
+ for (const input of inputs) for (const target of watchTargets(resolve(input), written)) this.addWatchFile(target);
22
47
  },
23
- async generateBundle() {
48
+ async generateBundle(outputOptions, bundle) {
49
+ const outFile = emittedFilePath(outputOptions, outputFilename);
24
50
  let result;
25
51
  try {
26
- result = await compile({
52
+ result = await compileForOutputFile({
27
53
  sources: options.sources,
28
54
  formatId: options.format,
29
55
  ...options.compileOptions
30
- });
56
+ }, outFile);
31
57
  } catch (e) {
32
58
  return this.error(fatalError(e));
33
59
  }
@@ -43,6 +69,10 @@ function tweeTsPlugin(options) {
43
69
  fileName: outputFilename,
44
70
  source: result.output
45
71
  });
72
+ if (this.meta.watchMode) for (const fileName of /* @__PURE__ */ new Set([...Object.keys(bundle), outputFilename])) {
73
+ const path = emittedFilePath(outputOptions, fileName);
74
+ if (path !== void 0) writing.push(path);
75
+ }
46
76
  }
47
77
  };
48
78
  }
@@ -1 +1 @@
1
- {"version":3,"file":"rollup.js","names":[],"sources":["../../src/plugins/rollup.ts"],"sourcesContent":["/**\n * Ready-made Rollup plugin for twee-ts.\n * Compiles .tw files and emits HTML as an asset. Compile errors fail the build\n * and emit nothing; warnings go through Rollup's warnings.\n */\nimport { resolve } from 'node:path';\nimport type { CompileOptions, CompileResult, Diagnostic } from '../types.js';\nimport { compile } from '../compiler.js';\nimport { fatalError, formatDiagnostic, splitDiagnostics } from './diagnostics.js';\nimport type { LocatedError } from './diagnostics.js';\n\nexport interface TweeTsRollupPluginOptions {\n /** Source directories/files to compile. */\n sources: string[];\n /** Story format ID. */\n format?: string;\n /** Output filename. Default: 'index.html'. */\n outputFilename?: string;\n /** Additional compile options. */\n compileOptions?: Partial<CompileOptions>;\n}\n\nexport function tweeTsPlugin(options: TweeTsRollupPluginOptions) {\n const outputFilename = options.outputFilename ?? 'index.html';\n\n return {\n name: 'twee-ts',\n\n // `rollup --watch` rebuilds for the files the build registers. The story's\n // inputs are read in generateBundle, outside the module graph, so they are\n // registered here. Rollup's watcher watches a folder recursively, files added\n // to it included.\n buildStart(this: { addWatchFile: (id: string) => void; meta: { watchMode: boolean } }) {\n if (!this.meta.watchMode) return;\n const extra = options.compileOptions;\n const inputs = [...options.sources, ...(extra?.headFile ? [extra.headFile] : []), ...(extra?.modules ?? [])];\n for (const input of inputs) this.addWatchFile(resolve(input));\n },\n\n async generateBundle(this: {\n emitFile: (opts: { type: 'asset'; fileName: string; source: string }) => void;\n error: (error: LocatedError) => never;\n warn: (message: string) => void;\n }): Promise<void> {\n let result: CompileResult;\n try {\n result = await compile({\n sources: options.sources,\n formatId: options.format,\n ...options.compileOptions,\n });\n } catch (e) {\n return this.error(fatalError(e));\n }\n let warnings: Diagnostic[];\n try {\n warnings = splitDiagnostics(result);\n } catch (e) {\n return this.error(e as LocatedError);\n }\n for (const w of warnings) this.warn(formatDiagnostic(w));\n this.emitFile({ type: 'asset', fileName: outputFilename, source: result.output });\n },\n };\n}\n"],"mappings":";;;;;;;;AAsBA,SAAgB,aAAa,SAAoC;CAC/D,MAAM,iBAAiB,QAAQ,kBAAkB;CAEjD,OAAO;EACL,MAAM;EAMN,aAAuF;GACrF,IAAI,CAAC,KAAK,KAAK,WAAW;GAC1B,MAAM,QAAQ,QAAQ;GACtB,MAAM,SAAS;IAAC,GAAG,QAAQ;IAAS,GAAI,OAAO,WAAW,CAAC,MAAM,QAAQ,IAAI,CAAC;IAAI,GAAI,OAAO,WAAW,CAAC;GAAE;GAC3G,KAAK,MAAM,SAAS,QAAQ,KAAK,aAAa,QAAQ,KAAK,CAAC;EAC9D;EAEA,MAAM,iBAIY;GAChB,IAAI;GACJ,IAAI;IACF,SAAS,MAAM,QAAQ;KACrB,SAAS,QAAQ;KACjB,UAAU,QAAQ;KAClB,GAAG,QAAQ;IACb,CAAC;GACH,SAAS,GAAG;IACV,OAAO,KAAK,MAAM,WAAW,CAAC,CAAC;GACjC;GACA,IAAI;GACJ,IAAI;IACF,WAAW,iBAAiB,MAAM;GACpC,SAAS,GAAG;IACV,OAAO,KAAK,MAAM,CAAiB;GACrC;GACA,KAAK,MAAM,KAAK,UAAU,KAAK,KAAK,iBAAiB,CAAC,CAAC;GACvD,KAAK,SAAS;IAAE,MAAM;IAAS,UAAU;IAAgB,QAAQ,OAAO;GAAO,CAAC;EAClF;CACF;AACF"}
1
+ {"version":3,"file":"rollup.js","names":[],"sources":["../../src/plugins/rollup.ts"],"sourcesContent":["/**\n * Ready-made Rollup plugin for twee-ts.\n * Compiles .tw files and emits HTML as an asset. Compile errors fail the build\n * and emit nothing; warnings go through Rollup's warnings.\n */\nimport { readdirSync } from 'node:fs';\nimport { join, resolve, sep } from 'node:path';\nimport type { CompileOptions, CompileResult, Diagnostic } from '../types.js';\nimport { compileForOutputFile } from '../compiler.js';\nimport { fatalError, formatDiagnostic, splitDiagnostics } from './diagnostics.js';\nimport type { LocatedError } from './diagnostics.js';\nimport { emittedFilePath } from './paths.js';\nimport type { OutputLocation } from './paths.js';\n\nexport interface TweeTsRollupPluginOptions {\n /** Source directories/files to compile. */\n sources: string[];\n /** Story format ID. */\n format?: string;\n /** Output filename. Default: 'index.html'. */\n outputFilename?: string;\n /** Additional compile options. */\n compileOptions?: Partial<CompileOptions>;\n}\n\n/**\n * What `rollup --watch` watches for the input at the absolute `path`: the path\n * itself, which Rollup watches recursively when it is a folder, unless it holds\n * one of the files the build wrote (`written`). Such a folder is replaced by what\n * it contains, and the written files are left out, so writing them starts no\n * build. A file added straight to that folder later is found at the next build.\n */\nfunction watchTargets(path: string, written: readonly string[]): string[] {\n if (written.includes(path)) return [];\n if (!written.some((file) => file.startsWith(path + sep))) return [path];\n let entries: string[];\n try {\n entries = readdirSync(path);\n } catch {\n return [path]; // Unreadable: Rollup's watcher reports it.\n }\n return entries.flatMap((entry) => watchTargets(join(path, entry), written));\n}\n\nexport function tweeTsPlugin(options: TweeTsRollupPluginOptions) {\n const outputFilename = options.outputFilename ?? 'index.html';\n // In watch mode, the files the last build wrote and those the current one writes\n // (absolute paths). They may sit inside a source folder, which must not rebuild for them.\n let written: readonly string[] = [];\n let writing: string[] = [];\n\n return {\n name: 'twee-ts',\n\n // `rollup --watch` rebuilds for the files the build registers. The story's\n // inputs are read in generateBundle, outside the module graph, so they are\n // registered here. Rollup's watcher watches a folder recursively, files added\n // to it included.\n buildStart(this: { addWatchFile: (id: string) => void; meta: { watchMode: boolean } }) {\n if (!this.meta.watchMode) return;\n // A build that failed before writing leaves the last build's files as they were.\n if (writing.length > 0) {\n written = writing;\n writing = [];\n }\n const extra = options.compileOptions;\n const inputs = [...options.sources, ...(extra?.headFile ? [extra.headFile] : []), ...(extra?.modules ?? [])];\n for (const input of inputs) {\n for (const target of watchTargets(resolve(input), written)) this.addWatchFile(target);\n }\n },\n\n async generateBundle(\n this: {\n emitFile: (opts: { type: 'asset'; fileName: string; source: string }) => void;\n error: (error: LocatedError) => never;\n warn: (message: string) => void;\n meta: { watchMode: boolean };\n },\n outputOptions: OutputLocation,\n bundle: Readonly<Record<string, unknown>>,\n ): Promise<void> {\n // Where the story is written: a source folder may hold it, and its last\n // build must not be loaded back as a source.\n const outFile = emittedFilePath(outputOptions, outputFilename);\n let result: CompileResult;\n try {\n result = await compileForOutputFile(\n { sources: options.sources, formatId: options.format, ...options.compileOptions },\n outFile,\n );\n } catch (e) {\n return this.error(fatalError(e));\n }\n let warnings: Diagnostic[];\n try {\n warnings = splitDiagnostics(result);\n } catch (e) {\n return this.error(e as LocatedError);\n }\n for (const w of warnings) this.warn(formatDiagnostic(w));\n this.emitFile({ type: 'asset', fileName: outputFilename, source: result.output });\n if (this.meta.watchMode) {\n for (const fileName of new Set([...Object.keys(bundle), outputFilename])) {\n const path = emittedFilePath(outputOptions, fileName);\n if (path !== undefined) writing.push(path);\n }\n }\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAgCA,SAAS,aAAa,MAAc,SAAsC;CACxE,IAAI,QAAQ,SAAS,IAAI,GAAG,OAAO,CAAC;CACpC,IAAI,CAAC,QAAQ,MAAM,SAAS,KAAK,WAAW,OAAO,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI;CACtE,IAAI;CACJ,IAAI;EACF,UAAU,YAAY,IAAI;CAC5B,QAAQ;EACN,OAAO,CAAC,IAAI;CACd;CACA,OAAO,QAAQ,SAAS,UAAU,aAAa,KAAK,MAAM,KAAK,GAAG,OAAO,CAAC;AAC5E;AAEA,SAAgB,aAAa,SAAoC;CAC/D,MAAM,iBAAiB,QAAQ,kBAAkB;CAGjD,IAAI,UAA6B,CAAC;CAClC,IAAI,UAAoB,CAAC;CAEzB,OAAO;EACL,MAAM;EAMN,aAAuF;GACrF,IAAI,CAAC,KAAK,KAAK,WAAW;GAE1B,IAAI,QAAQ,SAAS,GAAG;IACtB,UAAU;IACV,UAAU,CAAC;GACb;GACA,MAAM,QAAQ,QAAQ;GACtB,MAAM,SAAS;IAAC,GAAG,QAAQ;IAAS,GAAI,OAAO,WAAW,CAAC,MAAM,QAAQ,IAAI,CAAC;IAAI,GAAI,OAAO,WAAW,CAAC;GAAE;GAC3G,KAAK,MAAM,SAAS,QAClB,KAAK,MAAM,UAAU,aAAa,QAAQ,KAAK,GAAG,OAAO,GAAG,KAAK,aAAa,MAAM;EAExF;EAEA,MAAM,eAOJ,eACA,QACe;GAGf,MAAM,UAAU,gBAAgB,eAAe,cAAc;GAC7D,IAAI;GACJ,IAAI;IACF,SAAS,MAAM,qBACb;KAAE,SAAS,QAAQ;KAAS,UAAU,QAAQ;KAAQ,GAAG,QAAQ;IAAe,GAChF,OACF;GACF,SAAS,GAAG;IACV,OAAO,KAAK,MAAM,WAAW,CAAC,CAAC;GACjC;GACA,IAAI;GACJ,IAAI;IACF,WAAW,iBAAiB,MAAM;GACpC,SAAS,GAAG;IACV,OAAO,KAAK,MAAM,CAAiB;GACrC;GACA,KAAK,MAAM,KAAK,UAAU,KAAK,KAAK,iBAAiB,CAAC,CAAC;GACvD,KAAK,SAAS;IAAE,MAAM;IAAS,UAAU;IAAgB,QAAQ,OAAO;GAAO,CAAC;GAChF,IAAI,KAAK,KAAK,WACZ,KAAK,MAAM,4BAAY,IAAI,IAAI,CAAC,GAAG,OAAO,KAAK,MAAM,GAAG,cAAc,CAAC,GAAG;IACxE,MAAM,OAAO,gBAAgB,eAAe,QAAQ;IACpD,IAAI,SAAS,KAAA,GAAW,QAAQ,KAAK,IAAI;GAC3C;EAEJ;CACF;AACF"}
@@ -1,31 +1,8 @@
1
- import { a as compileIncremental, c as mediaTypeFromFilename, n as formatDiagnostic, o as getFilenames, r as splitDiagnostics, s as isExcluded, t as fatalError } from "../diagnostics-DZNS7W41.js";
1
+ import { a as fatalError, c as compileForOutputFile, d as mediaTypeFromFilename, i as toPosix, l as getFilenames, n as isInside, o as formatDiagnostic, r as isViteConfigTemp, s as splitDiagnostics, t as emittedFilePath, u as isExcluded } from "../paths-w4ulhCFb.js";
2
2
  import { readdirSync, statSync } from "node:fs";
3
3
  import { resolve } from "node:path";
4
4
  import { stripVTControlCharacters } from "node:util";
5
5
  import { build, version } from "vite";
6
- //#region src/plugins/paths.ts
7
- /**
8
- * Path helpers for the Vite plugin. Vite reports module ids with forward
9
- * slashes on every platform, while node:path gives backslashes on Windows, so
10
- * the plugin compares paths in forward-slash form only.
11
- */
12
- /** The path with Windows separators turned into forward slashes. */
13
- function toPosix(path) {
14
- return path.replace(/\\/g, "/");
15
- }
16
- /** Whether `file` is one of `dirs` or inside one of them. All paths in forward-slash form. */
17
- function isInside(file, dirs) {
18
- return dirs.some((dir) => file === dir || file.startsWith(dir.endsWith("/") ? dir : `${dir}/`));
19
- }
20
- /**
21
- * Whether `file` is a temporary copy of a Vite config file. Vite writes one next
22
- * to the config file each time it loads it (when no node_modules folder is
23
- * above the config, and always under Deno), then deletes it.
24
- */
25
- function isViteConfigTemp(file) {
26
- return /\.timestamp-\d+-[0-9a-f]*\.mjs$/.test(file);
27
- }
28
- //#endregion
29
6
  //#region src/plugins/vite.ts
30
7
  /**
31
8
  * Ready-made Vite plugin for twee-ts.
@@ -141,11 +118,24 @@ function headInputs(options) {
141
118
  const extra = options.compileOptions;
142
119
  return [...extra?.headFile ? [extra.headFile] : [], ...extra?.modules ?? []].map((p) => toPosix(resolve(p)));
143
120
  }
144
- /** Whether a file (forward-slash path) is a source the compile leaves out; the head file and modules never are. */
145
- function excludedInput(options) {
121
+ /**
122
+ * Whether a file (forward-slash path) is an input the compile leaves out: the
123
+ * story HTML a build writes (`builtStory`, an absolute path), and the sources
124
+ * `exclude` matches. `exclude` never applies to the head file and modules.
125
+ */
126
+ function excludedInput(options, builtStory) {
146
127
  const exclude = options.compileOptions?.exclude ?? [];
147
128
  const notExcludable = headInputs(options);
148
- return (file) => isExcluded(file, exclude) && !isInside(file, notExcludable);
129
+ const output = builtStory === void 0 ? void 0 : toPosix(builtStory);
130
+ return (file) => file === output || isExcluded(file, exclude) && !isInside(file, notExcludable);
131
+ }
132
+ /**
133
+ * Where a build writes the story HTML with this config: `build.outDir`, against
134
+ * the root. It may sit inside a source folder, where neither a compile nor the
135
+ * watchers may take it for a source.
136
+ */
137
+ function builtStoryPath(config, outputFilename) {
138
+ return resolve(config.root, config.build.outDir, outputFilename);
149
139
  }
150
140
  /** Absolute forward-slash paths whose changes recompile the story: sources, head file, modules. */
151
141
  function watchedInputs(options) {
@@ -156,8 +146,14 @@ function watchedInputs(options) {
156
146
  * (forward-slash paths) but those `skip` returns true for, and every folder
157
147
  * under them. The bundler watches each path on its own, not recursively, so a
158
148
  * folder is listed for the files added to it or deleted from it.
149
+ *
150
+ * A watched folder may still report changes in its subfolders (Rolldown's
151
+ * watcher on Linux does), so no folder that holds the story the build writes
152
+ * (`story`, a forward-slash path) is listed: writing the story would start the
153
+ * next build. A file added straight to such a folder is found when another
154
+ * change starts a build.
159
155
  */
160
- function buildWatchTargets(inputs, skip) {
156
+ function buildWatchTargets(inputs, skip, story) {
161
157
  const targets = [];
162
158
  const walk = (path) => {
163
159
  let entries;
@@ -170,7 +166,7 @@ function buildWatchTargets(inputs, skip) {
170
166
  } catch {
171
167
  return;
172
168
  }
173
- targets.push(path);
169
+ if (story === void 0 || !story.startsWith(`${path}/`)) targets.push(path);
174
170
  for (const entry of entries) walk(`${path}/${entry}`);
175
171
  };
176
172
  for (const input of inputs) walk(input);
@@ -377,6 +373,7 @@ function tweeTsPlugin(options) {
377
373
  const cache = /* @__PURE__ */ new Map();
378
374
  let innerBuild = false;
379
375
  let building = false;
376
+ let builtStory;
380
377
  let stopDev;
381
378
  if (options.entry && viteMajor < 8) throw new Error(`twee-ts: the entry option needs Vite 8 or newer (found ${version}).`);
382
379
  return {
@@ -390,13 +387,16 @@ function tweeTsPlugin(options) {
390
387
  return { build: inputOnly(EMPTY_INPUT) };
391
388
  },
392
389
  configResolved(config) {
393
- if (innerBuild || !options.entry) return;
390
+ if (innerBuild) return;
391
+ builtStory = builtStoryPath(config, outputFilename);
392
+ if (!options.entry) return;
394
393
  const sources = options.sources.map((p) => toPosix(resolve(p)));
395
394
  if (isInside(toPosix(resolve(options.entry)), sources)) config.logger.warn(`[twee-ts] The entry ${options.entry} is inside the story sources (${options.sources.join(", ")}). twee-ts also loads the .js and .css files it finds in source folders, unbundled, as Story JavaScript and Story Stylesheet; keep the entry's folder out of \`sources\`.`);
396
395
  },
397
396
  buildStart() {
398
397
  if (innerBuild || !building || !this.meta.watchMode) return;
399
- for (const target of buildWatchTargets(watchedInputs(options), excludedInput(options))) this.addWatchFile(target);
398
+ const story = builtStory === void 0 ? void 0 : toPosix(builtStory);
399
+ for (const target of buildWatchTargets(watchedInputs(options), excludedInput(options, builtStory), story)) this.addWatchFile(target);
400
400
  },
401
401
  watchChange(id) {
402
402
  if (innerBuild) return;
@@ -411,13 +411,14 @@ function tweeTsPlugin(options) {
411
411
  },
412
412
  generateBundle: {
413
413
  order: "post",
414
- async handler(_outputOptions, bundle) {
414
+ async handler(outputOptions, bundle) {
415
415
  if (innerBuild) return;
416
416
  for (const [fileName, item] of Object.entries(bundle)) if (item.type === "chunk" && item.facadeModuleId === RESOLVED_EMPTY_INPUT) delete bundle[fileName];
417
417
  const entry = options.entry ? takeEntryFromBundle(bundle) : void 0;
418
+ const outFile = emittedFilePath(outputOptions, outputFilename) ?? builtStory;
418
419
  let result;
419
420
  try {
420
- result = await compileIncremental(buildCompileOptions(options, entry), cache);
421
+ result = await compileForOutputFile(buildCompileOptions(options, entry), outFile, cache);
421
422
  } catch (e) {
422
423
  return this.error(fatalError(e));
423
424
  }
@@ -440,7 +441,8 @@ function tweeTsPlugin(options) {
440
441
  const base = server.config.base;
441
442
  const servePaths = outputFilename === "index.html" ? [base, `${base}index.html`] : [`${base}${outputFilename}`];
442
443
  const inputs = watchedInputs(options);
443
- const excluded = excludedInput(options);
444
+ const buildOutput = builtStoryPath(server.config, outputFilename);
445
+ const excluded = excludedInput(options, buildOutput);
444
446
  const entryPath = options.entry ? resolve(options.entry) : void 0;
445
447
  const root = toPosix(server.config.root);
446
448
  server.watcher.add(inputs);
@@ -470,7 +472,7 @@ function tweeTsPlugin(options) {
470
472
  entry = await bundleEntryForDev(server.config, entryPath);
471
473
  entryStale = false;
472
474
  }
473
- const result = await compileIncremental(buildCompileOptions(options, entry), cache);
475
+ const result = await compileForOutputFile(buildCompileOptions(options, entry), buildOutput, cache);
474
476
  for (const w of splitDiagnostics(result)) server.config.logger.warn(`[twee-ts] ${formatDiagnostic(w)}`);
475
477
  html = injectViteClient(result.output, base);
476
478
  lastError = void 0;
@@ -1 +1 @@
1
- {"version":3,"file":"vite.js","names":["viteVersion"],"sources":["../../src/plugins/paths.ts","../../src/plugins/vite.ts"],"sourcesContent":["/**\n * Path helpers for the Vite plugin. Vite reports module ids with forward\n * slashes on every platform, while node:path gives backslashes on Windows, so\n * the plugin compares paths in forward-slash form only.\n */\n\n/** The path with Windows separators turned into forward slashes. */\nexport function toPosix(path: string): string {\n return path.replace(/\\\\/g, '/');\n}\n\n/** Whether `file` is one of `dirs` or inside one of them. All paths in forward-slash form. */\nexport function isInside(file: string, dirs: readonly string[]): boolean {\n return dirs.some((dir) => file === dir || file.startsWith(dir.endsWith('/') ? dir : `${dir}/`));\n}\n\n/**\n * Whether `file` is a temporary copy of a Vite config file. Vite writes one next\n * to the config file each time it loads it (when no node_modules folder is\n * above the config, and always under Deno), then deletes it.\n */\nexport function isViteConfigTemp(file: string): boolean {\n return /\\.timestamp-\\d+-[0-9a-f]*\\.mjs$/.test(file);\n}\n","/**\n * Ready-made Vite plugin for twee-ts.\n *\n * Compiles Twee sources into the story HTML. With `entry`, Vite also bundles a\n * script, and the CSS it imports, into the story as its Story JavaScript and\n * Story Stylesheet.\n *\n * In dev the compiled HTML is served at the base URL with Vite's client added.\n * Every change to a source, the head file, a module or a file the entry imports\n * recompiles it and reloads the page, and errors appear in Vite's overlay. A\n * request for the story also recompiles it first if a source, the head file or\n * a module changed without the watcher reporting it.\n */\nimport { readdirSync, statSync } from 'node:fs';\nimport { resolve } from 'node:path';\nimport { stripVTControlCharacters } from 'node:util';\nimport { build, version as viteVersion } from 'vite';\nimport type { ErrorPayload, InlineConfig, Logger, Plugin, ResolvedConfig, UserConfig } from 'vite';\nimport type { CompileOptions, CompileResult, Diagnostic, FileCacheEntry, InlineSource } from '../types.js';\nimport { compileIncremental } from '../compiler.js';\nimport { fatalError, formatDiagnostic, splitDiagnostics } from './diagnostics.js';\nimport type { LocatedError } from './diagnostics.js';\nimport { getFilenames, isExcluded } from '../filesystem.js';\nimport { mediaTypeFromFilename } from '../media-types.js';\nimport { isInside, isViteConfigTemp, toPosix } from './paths.js';\n\nexport interface TweeTsVitePluginOptions {\n /** Source directories/files to compile, relative to the working directory. */\n sources: string[];\n /** Story format ID. */\n format?: string;\n /** Output filename in build output. Default: 'index.html'. */\n outputFilename?: string;\n /** Additional compile options. `sources` and `formatId` come from the options above. */\n compileOptions?: Partial<CompileOptions>;\n /**\n * A JS or TS file, relative to the working directory. Vite bundles it and\n * everything it imports into one self-contained script that becomes the\n * story's Story JavaScript; CSS it imports becomes the Story Stylesheet.\n * Requires Vite 8.\n */\n entry?: string;\n}\n\n/** Passage names the bundled entry takes inside the story. */\nconst ENTRY_SCRIPT_NAME = 'twee-ts-entry.js';\nconst ENTRY_STYLE_NAME = 'twee-ts-entry.css';\n\n/**\n * Set on the inline config of the build this plugin starts itself to bundle the\n * entry in dev. The plugin instance that build loads from the user's config file\n * sees it and stands aside.\n */\nconst INNER_BUILD_FLAG = '__tweeTsEntryBuild';\n\n/**\n * A build input that stands in when there is no entry, so Vite does not look\n * for an index.html (whose page would replace the story). Its empty chunk is\n * dropped from the output.\n */\nconst EMPTY_INPUT = 'virtual:twee-ts-empty-input';\nconst RESOLVED_EMPTY_INPUT = '\\0' + EMPTY_INPUT;\n\nconst viteMajor = Number.parseInt(viteVersion, 10);\n\n/**\n * The bundled entry: its script, its stylesheet, the files it was built from\n * (forward-slash paths), and any files the bundler still emits separately\n * (by output file name).\n */\ninterface EntryBundle {\n script: string;\n style: string;\n files: Set<string>;\n assets: Map<string, string | Uint8Array>;\n}\n\n/** The parts of a Vite output bundle this plugin reads. */\ntype BundleItem =\n | { type: 'chunk'; code: string; isEntry: boolean; moduleIds: readonly string[] }\n | { type: 'asset'; source: string | Uint8Array };\n\nfunction buildCompileOptions(options: TweeTsVitePluginOptions, entry: EntryBundle | undefined): CompileOptions {\n const inline: InlineSource[] = [];\n if (entry) {\n inline.push({ filename: ENTRY_SCRIPT_NAME, content: entry.script });\n if (entry.style !== '') inline.push({ filename: ENTRY_STYLE_NAME, content: entry.style });\n }\n return {\n ...options.compileOptions,\n sources: [...options.sources, ...inline],\n formatId: options.format ?? options.compileOptions?.formatId,\n };\n}\n\n/** Whether the user's config names build inputs of its own. */\nfunction hasUserInput(userConfig: UserConfig): boolean {\n const build = userConfig.build as Record<string, { input?: unknown } | undefined> | undefined;\n return build?.['rolldownOptions']?.input !== undefined || build?.['rollupOptions']?.input !== undefined;\n}\n\n/** Build settings naming one input, under the option name this Vite version reads. */\nfunction inputOnly(input: string): NonNullable<InlineConfig['build']> {\n return (viteMajor >= 8 ? { rolldownOptions: { input } } : { rollupOptions: { input } }) as NonNullable<\n InlineConfig['build']\n >;\n}\n\n/**\n * Build settings that turn the entry into one IIFE script and one stylesheet.\n * Fonts and images the entry uses are inlined as data URLs, so the story stays\n * one file; only an import marked `?no-inline` is still emitted separately.\n */\nfunction entryBuildOptions(entryPath: string): NonNullable<InlineConfig['build']> {\n return {\n cssCodeSplit: false,\n assetsInlineLimit: () => true,\n rolldownOptions: {\n input: entryPath,\n output: { format: 'iife', entryFileNames: ENTRY_SCRIPT_NAME, assetFileNames: '[name][extname]' },\n },\n };\n}\n\n/** Removes a trailing source-map comment that points at a file (a data: URL map stays). */\nfunction dropFileSourceMapComment(code: string): string {\n return code\n .replace(/\\n?\\/\\/# sourceMappingURL=(?!data:)\\S*\\s*$/, '')\n .replace(/\\n?\\/\\*# sourceMappingURL=(?!data:)[^*]*\\*\\/\\s*$/, '');\n}\n\n/**\n * Takes the entry's script and stylesheet out of the bundle, together with\n * their map files, which the story cannot ship. Anything else the bundler\n * emitted stays in the bundle, so a build writes it next to the HTML, and is\n * also returned, so the dev server can serve it.\n */\nfunction takeEntryFromBundle(bundle: Record<string, BundleItem>): EntryBundle {\n const entry: EntryBundle = { script: '', style: '', files: new Set(), assets: new Map() };\n const styles: string[] = [];\n for (const [fileName, item] of Object.entries(bundle)) {\n if (item.type === 'chunk') {\n if (item.isEntry) {\n entry.script = dropFileSourceMapComment(item.code);\n for (const id of item.moduleIds) if (!id.startsWith('\\0')) entry.files.add(fileOfId(id));\n }\n delete bundle[fileName];\n } else if (fileName.endsWith('.css')) {\n const css = typeof item.source === 'string' ? item.source : new TextDecoder().decode(item.source);\n styles.push(dropFileSourceMapComment(css));\n delete bundle[fileName];\n } else if (fileName.endsWith('.map')) {\n delete bundle[fileName];\n } else {\n entry.assets.set(fileName, item.source);\n }\n }\n entry.style = styles.join('\\n');\n return entry;\n}\n\n/** Absolute forward-slash paths of the head file and the modules, which `exclude` doesn't apply to. */\nfunction headInputs(options: TweeTsVitePluginOptions): string[] {\n const extra = options.compileOptions;\n return [...(extra?.headFile ? [extra.headFile] : []), ...(extra?.modules ?? [])].map((p) => toPosix(resolve(p)));\n}\n\n/** Whether a file (forward-slash path) is a source the compile leaves out; the head file and modules never are. */\nfunction excludedInput(options: TweeTsVitePluginOptions): (file: string) => boolean {\n const exclude = options.compileOptions?.exclude ?? [];\n const notExcludable = headInputs(options);\n return (file) => isExcluded(file, exclude) && !isInside(file, notExcludable);\n}\n\n/** Absolute forward-slash paths whose changes recompile the story: sources, head file, modules. */\nfunction watchedInputs(options: TweeTsVitePluginOptions): string[] {\n return [...options.sources.map((p) => toPosix(resolve(p))), ...headInputs(options)];\n}\n\n/**\n * What `vite build --watch` watches for the story: every file under `inputs`\n * (forward-slash paths) but those `skip` returns true for, and every folder\n * under them. The bundler watches each path on its own, not recursively, so a\n * folder is listed for the files added to it or deleted from it.\n */\nfunction buildWatchTargets(inputs: readonly string[], skip: (file: string) => boolean): string[] {\n const targets: string[] = [];\n const walk = (path: string): void => {\n let entries;\n try {\n if (!statSync(path).isDirectory()) {\n if (!skip(path)) targets.push(path);\n return;\n }\n entries = readdirSync(path);\n } catch {\n return; // Missing or unreadable: the compile reports it.\n }\n targets.push(path);\n for (const entry of entries) walk(`${path}/${entry}`);\n };\n for (const input of inputs) walk(input);\n return targets;\n}\n\n/**\n * Every file under `inputs` (forward-slash paths) but those `skip` returns true\n * for, with what a change to it alters: modification time, size and inode (a\n * file replaced by a new one).\n */\nfunction inputFiles(inputs: readonly string[], skip: (file: string) => boolean): Map<string, string> {\n const files = new Map<string, string>();\n for (const filename of getFilenames([...inputs]).filenames) {\n const file = toPosix(resolve(filename));\n if (skip(file)) continue;\n try {\n const stat = statSync(filename);\n files.set(file, `${stat.mtimeMs}:${stat.size}:${stat.ino}`);\n } catch {\n // Deleted since the walk found it; it counts as gone.\n }\n }\n return files;\n}\n\n/** The files added, removed or changed between two `inputFiles` results. */\nfunction filesChanged(before: ReadonlyMap<string, string>, after: ReadonlyMap<string, string>): Set<string> {\n const changed = new Set<string>();\n for (const [file, state] of after) if (before.get(file) !== state) changed.add(file);\n for (const file of before.keys()) if (!after.has(file)) changed.add(file);\n return changed;\n}\n\n/** Adds Vite's client to the page so reloads and the error overlay reach it. */\nfunction injectViteClient(html: string, base: string): string {\n const tag = `<script type=\"module\" src=\"${base}@vite/client\"></script>`;\n const head = /<head[^>]*>/i.exec(html);\n if (!head) return tag + html;\n const at = head.index + head[0].length;\n return html.slice(0, at) + tag + html.slice(at);\n}\n\n/** Served until the first successful compile, so the overlay has a page to appear on. */\nfunction waitingPage(base: string): string {\n return (\n '<!doctype html><html><head><meta charset=\"utf-8\">' +\n `<script type=\"module\" src=\"${base}@vite/client\"></script>` +\n '<title>twee-ts</title></head><body><p>The story has not compiled yet.</p></body></html>'\n );\n}\n\nfunction toOverlayError(e: unknown): ErrorPayload['err'] {\n const error = fatalError(e);\n return {\n // Bundler messages carry terminal colour codes; the overlay would show them raw.\n message: stripVTControlCharacters(error.message),\n stack: '',\n plugin: 'twee-ts',\n ...(error.id ? { id: error.id } : {}),\n ...(error.loc ? { loc: error.loc } : {}),\n };\n}\n\n/** Bundles the entry for dev with the user's own Vite config, unminified, with an inline source map. */\n/**\n * The entry build's logger: its warnings go to the dev server's logger; its\n * progress lines and its own \"build failed\" line are dropped, because the plugin\n * reports a failed bundle itself.\n */\nfunction entryBuildLogger(outer: Logger): Logger {\n return {\n info: () => {},\n warn: (message, options) => outer.warn(message, options),\n warnOnce: (message, options) => outer.warnOnce(message, options),\n error: () => {},\n clearScreen: () => {},\n hasErrorLogged: () => false,\n get hasWarned() {\n return outer.hasWarned;\n },\n };\n}\n\n/**\n * Keeps the entry build a one-off even when the user's config sets build.watch:\n * Vite's config merge skips a null, so the inline `watch: null` alone can't.\n */\nconst oneOffEntryBuild: Plugin = {\n name: 'twee-ts:one-off-entry-build',\n enforce: 'post',\n config(userConfig) {\n if (userConfig.build) userConfig.build.watch = null;\n },\n};\n\n/** Build-phase plugin hooks that may call `this.addWatchFile`. */\nconst WATCH_FILE_HOOKS = [\n 'buildStart',\n 'resolveId',\n 'resolveDynamicImport',\n 'load',\n 'transform',\n 'moduleParsed',\n 'buildEnd',\n];\n\n/** A module id or watched file as a forward-slash file path, without a query or hash (like Vite's cleanUrl). */\nfunction fileOfId(id: string): string {\n return toPosix(id.replace(/[?#].*$/s, ''));\n}\n\n/** A plugin context whose `addWatchFile` also records the file in `files`. */\nfunction recordingContext(context: object, files: Set<string>): object {\n return new Proxy(context, {\n get(target, key) {\n const value: unknown = Reflect.get(target, key, target);\n if (typeof value !== 'function') return value;\n if (key !== 'addWatchFile') return value.bind(target);\n return (id: string) => {\n if (!id.startsWith('\\0')) files.add(fileOfId(resolve(id)));\n return value.call(target, id);\n };\n },\n });\n}\n\n/**\n * A copy of `plugin` whose hooks record `addWatchFile` calls in `files`. The\n * original stays untouched, so a plugin object shared across entry builds never\n * collects wrappers. The copy keeps the prototype, so class-based plugins keep\n * their methods, and object-form hooks keep `order`, `filter` and the rest. A\n * plugin with no such hooks (a built-in one, for instance) is returned as is.\n */\nfunction recordingPlugin(plugin: unknown, files: Set<string>): unknown {\n if (typeof plugin !== 'object' || plugin === null) return plugin;\n const hooks = plugin as Readonly<Record<string, unknown>>;\n const hookHandler = (hook: unknown): unknown =>\n typeof hook === 'object' && hook !== null ? (hook as { handler?: unknown }).handler : hook;\n if (!WATCH_FILE_HOOKS.some((name) => typeof hookHandler(hooks[name]) === 'function')) return plugin;\n const copy = Object.create(\n Object.getPrototypeOf(plugin) as object | null,\n Object.getOwnPropertyDescriptors(plugin),\n ) as Record<string, unknown>;\n for (const name of WATCH_FILE_HOOKS) {\n const hook = hooks[name];\n const handler = hookHandler(hook);\n if (typeof handler !== 'function') continue;\n const wrapped = function (this: object, ...args: unknown[]): unknown {\n return handler.apply(recordingContext(this, files), args);\n };\n copy[name] = typeof hook === 'function' ? wrapped : { ...(hook as object), handler: wrapped };\n }\n return copy;\n}\n\n/**\n * Collects the files the entry build's plugins add with `addWatchFile`. These\n * are not modules of the bundle: Vite's CSS plugin adds the stylesheets pulled\n * in by `@import` and the files `url()` points at this way. The build runs on\n * recording copies of its plugins. They are made in the bundler's `options`\n * hook, which sees the final plugin list, including the plugins Vite resolves\n * per environment (`applyToEnvironment`) after `configResolved`.\n */\nfunction recordWatchFiles(files: Set<string>): Plugin {\n return {\n name: 'twee-ts:record-watch-files',\n options: {\n order: 'post',\n async handler(inputOptions) {\n const plugins = (await flattenPlugins(inputOptions.plugins)).map((p) => recordingPlugin(p, files));\n return { ...inputOptions, plugins: plugins as typeof inputOptions.plugins };\n },\n },\n };\n}\n\n/** A plugin option (nested arrays, promises, falsy entries) as one flat list. */\nasync function flattenPlugins(option: unknown): Promise<unknown[]> {\n const value: unknown = await option;\n if (Array.isArray(value)) return (await Promise.all(value.map(flattenPlugins))).flat();\n return value ? [value] : [];\n}\n\n/** Bundles the entry for dev with the user's own Vite config, unminified, with an inline source map. */\nasync function bundleEntryForDev(config: ResolvedConfig, entryPath: string): Promise<EntryBundle> {\n const watchFiles = new Set<string>();\n const inline: InlineConfig & Record<string, unknown> = {\n configFile: config.configFile ?? false,\n root: config.root,\n mode: config.mode,\n customLogger: entryBuildLogger(config.logger),\n publicDir: false,\n // With a config file the entry build reads it again, plugins and all. Without\n // one, the settings that change how code bundles come across from the server.\n ...(config.configFile ? {} : { define: config.define, resolve: { alias: config.resolve.alias } }),\n build: {\n ...entryBuildOptions(entryPath),\n write: false,\n minify: false,\n sourcemap: 'inline',\n emptyOutDir: false,\n copyPublicDir: false,\n watch: null,\n },\n plugins: [oneOffEntryBuild, recordWatchFiles(watchFiles)],\n [INNER_BUILD_FLAG]: true,\n };\n const out = await build(inline);\n const bundle: Record<string, BundleItem> = {};\n for (const result of Array.isArray(out) ? out : [out]) {\n if (!('output' in result)) {\n await result.close();\n throw new Error('twee-ts: the entry build returned a watcher instead of a bundle.');\n }\n for (const item of result.output) bundle[item.fileName] = item;\n }\n const entry = takeEntryFromBundle(bundle);\n for (const file of watchFiles) entry.files.add(file);\n return entry;\n}\n\nexport function tweeTsPlugin(options: TweeTsVitePluginOptions): Plugin {\n const outputFilename = options.outputFilename ?? 'index.html';\n const cache = new Map<string, FileCacheEntry>();\n let innerBuild = false;\n let building = false;\n let stopDev: (() => void) | undefined;\n\n if (options.entry && viteMajor < 8) {\n throw new Error(`twee-ts: the entry option needs Vite 8 or newer (found ${viteVersion}).`);\n }\n\n return {\n name: 'twee-ts',\n\n config(userConfig, env) {\n innerBuild = (userConfig as Record<string, unknown>)[INNER_BUILD_FLAG] === true;\n building = env.command === 'build';\n if (innerBuild || !building) return undefined;\n if (options.entry) return { build: entryBuildOptions(resolve(options.entry)) };\n if (hasUserInput(userConfig)) return undefined;\n return { build: inputOnly(EMPTY_INPUT) };\n },\n\n configResolved(config) {\n if (innerBuild || !options.entry) return;\n const sources = options.sources.map((p) => toPosix(resolve(p)));\n if (isInside(toPosix(resolve(options.entry)), sources)) {\n config.logger.warn(\n `[twee-ts] The entry ${options.entry} is inside the story sources (${options.sources.join(', ')}). ` +\n 'twee-ts also loads the .js and .css files it finds in source folders, unbundled, as Story JavaScript ' +\n \"and Story Stylesheet; keep the entry's folder out of `sources`.\",\n );\n }\n },\n\n // `vite build --watch` rebuilds for the files the build registers. The story's\n // inputs are read in generateBundle, outside the module graph, so they are\n // registered here; the dev server watches them itself (configureServer).\n buildStart() {\n if (innerBuild || !building || !this.meta.watchMode) return;\n for (const target of buildWatchTargets(watchedInputs(options), excludedInput(options))) {\n this.addWatchFile(target);\n }\n },\n\n // The compile cache trusts modification times, which a quick save may leave\n // unchanged (coarse file-system timestamps); forget a file that changed.\n watchChange(id) {\n if (innerBuild) return;\n const changed = toPosix(resolve(id));\n for (const key of [...cache.keys()]) if (toPosix(resolve(key)) === changed) cache.delete(key);\n },\n\n resolveId(id) {\n return id === EMPTY_INPUT ? RESOLVED_EMPTY_INPUT : undefined;\n },\n\n load(id) {\n // A statement app builds keep (they drop unused exports), so Rollup in Vite 5\n // doesn't warn about an empty chunk. The chunk is removed from the output.\n return id === RESOLVED_EMPTY_INPUT ? 'globalThis.tweeTsEmptyInput = true;' : undefined;\n },\n\n generateBundle: {\n order: 'post',\n async handler(_outputOptions, bundle) {\n if (innerBuild) return;\n for (const [fileName, item] of Object.entries(bundle)) {\n if (item.type === 'chunk' && item.facadeModuleId === RESOLVED_EMPTY_INPUT) delete bundle[fileName];\n }\n const entry = options.entry ? takeEntryFromBundle(bundle) : undefined;\n let result: CompileResult;\n try {\n result = await compileIncremental(buildCompileOptions(options, entry), cache);\n } catch (e) {\n return this.error(fatalError(e));\n }\n let warnings: Diagnostic[];\n try {\n warnings = splitDiagnostics(result);\n } catch (e) {\n return this.error(e as LocatedError);\n }\n for (const w of warnings) this.warn(formatDiagnostic(w));\n this.emitFile({ type: 'asset', fileName: outputFilename, source: result.output });\n },\n },\n\n async configureServer(server) {\n if (innerBuild) return;\n const base = server.config.base;\n const servePaths = outputFilename === 'index.html' ? [base, `${base}index.html`] : [`${base}${outputFilename}`];\n const inputs = watchedInputs(options);\n const excluded = excludedInput(options);\n const entryPath = options.entry ? resolve(options.entry) : undefined;\n const root = toPosix(server.config.root);\n server.watcher.add(inputs);\n\n let html = '';\n let lastError: ErrorPayload['err'] | undefined;\n let entry: EntryBundle | undefined; // last good bundle\n let entryStale = true; // bundle again on the next rebuild\n let queue: Promise<void> = Promise.resolve();\n let pending = new Set<string>();\n let timer: ReturnType<typeof setTimeout> | undefined;\n let closed = false;\n // The input files as the last compile found them, to tell whether the\n // watcher missed a change (see catchUp).\n let compiledInputs = new Map<string, string>();\n let catchingUp: Promise<void> | undefined;\n stopDev = () => {\n closed = true;\n clearTimeout(timer);\n pending.clear();\n };\n\n // The files that belong to the entry: after a good bundle, the modules it was\n // built from and the files its plugins watch (such as CSS @imports and url()\n // targets); while there is none, or the last one failed, anything in\n // the project, so that creating a missing import brings it back.\n const touchesEntry = (file: string): boolean =>\n entryPath !== undefined && (entryStale ? isInside(file, [root]) : (entry?.files.has(file) ?? false));\n\n // `initial`: the compile at server start. No page is open yet, and Vite would\n // hold a full-reload for the first page that connects and reload it once.\n const rebuild = async (changed: ReadonlySet<string>, initial = false): Promise<void> => {\n if (closed) return;\n // Taken before the compile reads anything, so a file written during it\n // still counts as changed afterwards.\n compiledInputs = inputFiles(inputs, excluded);\n // The compile cache trusts modification times, which a quick save may leave\n // unchanged (coarse file-system timestamps); forget the files that changed.\n for (const key of [...cache.keys()]) if (changed.has(toPosix(resolve(key)))) cache.delete(key);\n try {\n if (entryPath && (entryStale || [...changed].some(touchesEntry))) {\n entryStale = true;\n entry = await bundleEntryForDev(server.config, entryPath);\n entryStale = false;\n }\n const result = await compileIncremental(buildCompileOptions(options, entry), cache);\n for (const w of splitDiagnostics(result)) server.config.logger.warn(`[twee-ts] ${formatDiagnostic(w)}`);\n html = injectViteClient(result.output, base);\n lastError = undefined;\n if (!initial) server.ws.send({ type: 'full-reload' });\n } catch (e) {\n lastError = toOverlayError(e);\n server.config.logger.error(`[twee-ts] ${lastError.message}`);\n server.ws.send({ type: 'error', err: lastError });\n }\n };\n\n // rebuild() reports its own errors; this catches a failure while reporting,\n // so one bad report doesn't stop every later rebuild.\n const keepQueueAlive = (e: unknown): void => {\n try {\n server.config.logger.error(`[twee-ts] ${fatalError(e).message}`);\n } catch {\n // Nothing left to report with.\n }\n };\n\n await rebuild(new Set(), true);\n\n server.watcher.on('all', (event, file) => {\n if (event !== 'add' && event !== 'change' && event !== 'unlink') return;\n const changed = toPosix(resolve(file));\n // Loading the config for the entry build writes and deletes one of these;\n // reacting to it would bundle again, and again.\n if (isViteConfigTemp(changed)) return;\n if ((!isInside(changed, inputs) || excluded(changed)) && !touchesEntry(changed)) return;\n pending.add(changed);\n clearTimeout(timer);\n timer = setTimeout(() => {\n const files = pending;\n pending = new Set();\n queue = queue.then(() => rebuild(files)).catch(keepQueueAlive);\n }, 50);\n });\n\n // The watcher can miss changes. When a folder is deleted and created again\n // in quick succession (as `git rebase` does), chokidar stops watching the\n // folder, so a file added to it later raises no event; under Deno it also\n // loses the files created with it, so their later edits raise none\n // either. Before the story is served, this\n // waits for any compile under way, compares the input files with what the\n // last compile found, and compiles again first if they differ.\n const catchUp = (): Promise<void> => {\n catchingUp ??= (async () => {\n await queue;\n const changed = filesChanged(compiledInputs, inputFiles(inputs, excluded));\n if (changed.size === 0) return;\n // Changes the watcher did report, still waiting out the debounce, go into the same compile.\n for (const file of pending) changed.add(file);\n pending = new Set();\n clearTimeout(timer);\n queue = queue.then(() => rebuild(changed)).catch(keepQueueAlive);\n await queue;\n })().finally(() => {\n catchingUp = undefined;\n });\n return catchingUp;\n };\n\n server.ws.on('connection', () => {\n if (lastError) server.ws.send({ type: 'error', err: lastError });\n });\n\n server.middlewares.use((req, res, next) => {\n const path = (req.url ?? '').split('?')[0] ?? '';\n if (servePaths.includes(path)) {\n catchUp().then(() => {\n res.statusCode = 200;\n res.setHeader('Content-Type', 'text/html; charset=utf-8');\n res.end(html || waitingPage(base));\n }, next);\n return;\n }\n // Files the entry's bundle still emits separately, where the build writes them.\n const asset = path.startsWith(base) ? entry?.assets.get(path.slice(base.length)) : undefined;\n if (asset !== undefined) {\n res.statusCode = 200;\n res.setHeader('Content-Type', mediaTypeFromFilename(path));\n res.end(asset);\n return;\n }\n next();\n });\n },\n\n // Vite runs this when the dev server closes (and after a build); no rebuild may\n // start after it, including one whose timer is still pending in middleware mode.\n closeBundle() {\n stopDev?.();\n },\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"vite.js","names":["viteVersion"],"sources":["../../src/plugins/vite.ts"],"sourcesContent":["/**\n * Ready-made Vite plugin for twee-ts.\n *\n * Compiles Twee sources into the story HTML. With `entry`, Vite also bundles a\n * script, and the CSS it imports, into the story as its Story JavaScript and\n * Story Stylesheet.\n *\n * In dev the compiled HTML is served at the base URL with Vite's client added.\n * Every change to a source, the head file, a module or a file the entry imports\n * recompiles it and reloads the page, and errors appear in Vite's overlay. A\n * request for the story also recompiles it first if a source, the head file or\n * a module changed without the watcher reporting it.\n */\nimport { readdirSync, statSync } from 'node:fs';\nimport { resolve } from 'node:path';\nimport { stripVTControlCharacters } from 'node:util';\nimport { build, version as viteVersion } from 'vite';\nimport type { ErrorPayload, InlineConfig, Logger, Plugin, ResolvedConfig, UserConfig } from 'vite';\nimport type { CompileOptions, CompileResult, Diagnostic, FileCacheEntry, InlineSource } from '../types.js';\nimport { compileForOutputFile } from '../compiler.js';\nimport { fatalError, formatDiagnostic, splitDiagnostics } from './diagnostics.js';\nimport type { LocatedError } from './diagnostics.js';\nimport { getFilenames, isExcluded } from '../filesystem.js';\nimport { mediaTypeFromFilename } from '../media-types.js';\nimport { emittedFilePath, isInside, isViteConfigTemp, toPosix } from './paths.js';\n\nexport interface TweeTsVitePluginOptions {\n /** Source directories/files to compile, relative to the working directory. */\n sources: string[];\n /** Story format ID. */\n format?: string;\n /** Output filename in build output. Default: 'index.html'. */\n outputFilename?: string;\n /** Additional compile options. `sources` and `formatId` come from the options above. */\n compileOptions?: Partial<CompileOptions>;\n /**\n * A JS or TS file, relative to the working directory. Vite bundles it and\n * everything it imports into one self-contained script that becomes the\n * story's Story JavaScript; CSS it imports becomes the Story Stylesheet.\n * Requires Vite 8.\n */\n entry?: string;\n}\n\n/** Passage names the bundled entry takes inside the story. */\nconst ENTRY_SCRIPT_NAME = 'twee-ts-entry.js';\nconst ENTRY_STYLE_NAME = 'twee-ts-entry.css';\n\n/**\n * Set on the inline config of the build this plugin starts itself to bundle the\n * entry in dev. The plugin instance that build loads from the user's config file\n * sees it and stands aside.\n */\nconst INNER_BUILD_FLAG = '__tweeTsEntryBuild';\n\n/**\n * A build input that stands in when there is no entry, so Vite does not look\n * for an index.html (whose page would replace the story). Its empty chunk is\n * dropped from the output.\n */\nconst EMPTY_INPUT = 'virtual:twee-ts-empty-input';\nconst RESOLVED_EMPTY_INPUT = '\\0' + EMPTY_INPUT;\n\nconst viteMajor = Number.parseInt(viteVersion, 10);\n\n/**\n * The bundled entry: its script, its stylesheet, the files it was built from\n * (forward-slash paths), and any files the bundler still emits separately\n * (by output file name).\n */\ninterface EntryBundle {\n script: string;\n style: string;\n files: Set<string>;\n assets: Map<string, string | Uint8Array>;\n}\n\n/** The parts of a Vite output bundle this plugin reads. */\ntype BundleItem =\n | { type: 'chunk'; code: string; isEntry: boolean; moduleIds: readonly string[] }\n | { type: 'asset'; source: string | Uint8Array };\n\nfunction buildCompileOptions(options: TweeTsVitePluginOptions, entry: EntryBundle | undefined): CompileOptions {\n const inline: InlineSource[] = [];\n if (entry) {\n inline.push({ filename: ENTRY_SCRIPT_NAME, content: entry.script });\n if (entry.style !== '') inline.push({ filename: ENTRY_STYLE_NAME, content: entry.style });\n }\n return {\n ...options.compileOptions,\n sources: [...options.sources, ...inline],\n formatId: options.format ?? options.compileOptions?.formatId,\n };\n}\n\n/** Whether the user's config names build inputs of its own. */\nfunction hasUserInput(userConfig: UserConfig): boolean {\n const build = userConfig.build as Record<string, { input?: unknown } | undefined> | undefined;\n return build?.['rolldownOptions']?.input !== undefined || build?.['rollupOptions']?.input !== undefined;\n}\n\n/** Build settings naming one input, under the option name this Vite version reads. */\nfunction inputOnly(input: string): NonNullable<InlineConfig['build']> {\n return (viteMajor >= 8 ? { rolldownOptions: { input } } : { rollupOptions: { input } }) as NonNullable<\n InlineConfig['build']\n >;\n}\n\n/**\n * Build settings that turn the entry into one IIFE script and one stylesheet.\n * Fonts and images the entry uses are inlined as data URLs, so the story stays\n * one file; only an import marked `?no-inline` is still emitted separately.\n */\nfunction entryBuildOptions(entryPath: string): NonNullable<InlineConfig['build']> {\n return {\n cssCodeSplit: false,\n assetsInlineLimit: () => true,\n rolldownOptions: {\n input: entryPath,\n output: { format: 'iife', entryFileNames: ENTRY_SCRIPT_NAME, assetFileNames: '[name][extname]' },\n },\n };\n}\n\n/** Removes a trailing source-map comment that points at a file (a data: URL map stays). */\nfunction dropFileSourceMapComment(code: string): string {\n return code\n .replace(/\\n?\\/\\/# sourceMappingURL=(?!data:)\\S*\\s*$/, '')\n .replace(/\\n?\\/\\*# sourceMappingURL=(?!data:)[^*]*\\*\\/\\s*$/, '');\n}\n\n/**\n * Takes the entry's script and stylesheet out of the bundle, together with\n * their map files, which the story cannot ship. Anything else the bundler\n * emitted stays in the bundle, so a build writes it next to the HTML, and is\n * also returned, so the dev server can serve it.\n */\nfunction takeEntryFromBundle(bundle: Record<string, BundleItem>): EntryBundle {\n const entry: EntryBundle = { script: '', style: '', files: new Set(), assets: new Map() };\n const styles: string[] = [];\n for (const [fileName, item] of Object.entries(bundle)) {\n if (item.type === 'chunk') {\n if (item.isEntry) {\n entry.script = dropFileSourceMapComment(item.code);\n for (const id of item.moduleIds) if (!id.startsWith('\\0')) entry.files.add(fileOfId(id));\n }\n delete bundle[fileName];\n } else if (fileName.endsWith('.css')) {\n const css = typeof item.source === 'string' ? item.source : new TextDecoder().decode(item.source);\n styles.push(dropFileSourceMapComment(css));\n delete bundle[fileName];\n } else if (fileName.endsWith('.map')) {\n delete bundle[fileName];\n } else {\n entry.assets.set(fileName, item.source);\n }\n }\n entry.style = styles.join('\\n');\n return entry;\n}\n\n/** Absolute forward-slash paths of the head file and the modules, which `exclude` doesn't apply to. */\nfunction headInputs(options: TweeTsVitePluginOptions): string[] {\n const extra = options.compileOptions;\n return [...(extra?.headFile ? [extra.headFile] : []), ...(extra?.modules ?? [])].map((p) => toPosix(resolve(p)));\n}\n\n/**\n * Whether a file (forward-slash path) is an input the compile leaves out: the\n * story HTML a build writes (`builtStory`, an absolute path), and the sources\n * `exclude` matches. `exclude` never applies to the head file and modules.\n */\nfunction excludedInput(options: TweeTsVitePluginOptions, builtStory: string | undefined): (file: string) => boolean {\n const exclude = options.compileOptions?.exclude ?? [];\n const notExcludable = headInputs(options);\n const output = builtStory === undefined ? undefined : toPosix(builtStory);\n return (file) => file === output || (isExcluded(file, exclude) && !isInside(file, notExcludable));\n}\n\n/**\n * Where a build writes the story HTML with this config: `build.outDir`, against\n * the root. It may sit inside a source folder, where neither a compile nor the\n * watchers may take it for a source.\n */\nfunction builtStoryPath(config: ResolvedConfig, outputFilename: string): string {\n return resolve(config.root, config.build.outDir, outputFilename);\n}\n\n/** Absolute forward-slash paths whose changes recompile the story: sources, head file, modules. */\nfunction watchedInputs(options: TweeTsVitePluginOptions): string[] {\n return [...options.sources.map((p) => toPosix(resolve(p))), ...headInputs(options)];\n}\n\n/**\n * What `vite build --watch` watches for the story: every file under `inputs`\n * (forward-slash paths) but those `skip` returns true for, and every folder\n * under them. The bundler watches each path on its own, not recursively, so a\n * folder is listed for the files added to it or deleted from it.\n *\n * A watched folder may still report changes in its subfolders (Rolldown's\n * watcher on Linux does), so no folder that holds the story the build writes\n * (`story`, a forward-slash path) is listed: writing the story would start the\n * next build. A file added straight to such a folder is found when another\n * change starts a build.\n */\nfunction buildWatchTargets(\n inputs: readonly string[],\n skip: (file: string) => boolean,\n story: string | undefined,\n): string[] {\n const targets: string[] = [];\n const walk = (path: string): void => {\n let entries;\n try {\n if (!statSync(path).isDirectory()) {\n if (!skip(path)) targets.push(path);\n return;\n }\n entries = readdirSync(path);\n } catch {\n return; // Missing or unreadable: the compile reports it.\n }\n if (story === undefined || !story.startsWith(`${path}/`)) targets.push(path);\n for (const entry of entries) walk(`${path}/${entry}`);\n };\n for (const input of inputs) walk(input);\n return targets;\n}\n\n/**\n * Every file under `inputs` (forward-slash paths) but those `skip` returns true\n * for, with what a change to it alters: modification time, size and inode (a\n * file replaced by a new one).\n */\nfunction inputFiles(inputs: readonly string[], skip: (file: string) => boolean): Map<string, string> {\n const files = new Map<string, string>();\n for (const filename of getFilenames([...inputs]).filenames) {\n const file = toPosix(resolve(filename));\n if (skip(file)) continue;\n try {\n const stat = statSync(filename);\n files.set(file, `${stat.mtimeMs}:${stat.size}:${stat.ino}`);\n } catch {\n // Deleted since the walk found it; it counts as gone.\n }\n }\n return files;\n}\n\n/** The files added, removed or changed between two `inputFiles` results. */\nfunction filesChanged(before: ReadonlyMap<string, string>, after: ReadonlyMap<string, string>): Set<string> {\n const changed = new Set<string>();\n for (const [file, state] of after) if (before.get(file) !== state) changed.add(file);\n for (const file of before.keys()) if (!after.has(file)) changed.add(file);\n return changed;\n}\n\n/** Adds Vite's client to the page so reloads and the error overlay reach it. */\nfunction injectViteClient(html: string, base: string): string {\n const tag = `<script type=\"module\" src=\"${base}@vite/client\"></script>`;\n const head = /<head[^>]*>/i.exec(html);\n if (!head) return tag + html;\n const at = head.index + head[0].length;\n return html.slice(0, at) + tag + html.slice(at);\n}\n\n/** Served until the first successful compile, so the overlay has a page to appear on. */\nfunction waitingPage(base: string): string {\n return (\n '<!doctype html><html><head><meta charset=\"utf-8\">' +\n `<script type=\"module\" src=\"${base}@vite/client\"></script>` +\n '<title>twee-ts</title></head><body><p>The story has not compiled yet.</p></body></html>'\n );\n}\n\nfunction toOverlayError(e: unknown): ErrorPayload['err'] {\n const error = fatalError(e);\n return {\n // Bundler messages carry terminal colour codes; the overlay would show them raw.\n message: stripVTControlCharacters(error.message),\n stack: '',\n plugin: 'twee-ts',\n ...(error.id ? { id: error.id } : {}),\n ...(error.loc ? { loc: error.loc } : {}),\n };\n}\n\n/** Bundles the entry for dev with the user's own Vite config, unminified, with an inline source map. */\n/**\n * The entry build's logger: its warnings go to the dev server's logger; its\n * progress lines and its own \"build failed\" line are dropped, because the plugin\n * reports a failed bundle itself.\n */\nfunction entryBuildLogger(outer: Logger): Logger {\n return {\n info: () => {},\n warn: (message, options) => outer.warn(message, options),\n warnOnce: (message, options) => outer.warnOnce(message, options),\n error: () => {},\n clearScreen: () => {},\n hasErrorLogged: () => false,\n get hasWarned() {\n return outer.hasWarned;\n },\n };\n}\n\n/**\n * Keeps the entry build a one-off even when the user's config sets build.watch:\n * Vite's config merge skips a null, so the inline `watch: null` alone can't.\n */\nconst oneOffEntryBuild: Plugin = {\n name: 'twee-ts:one-off-entry-build',\n enforce: 'post',\n config(userConfig) {\n if (userConfig.build) userConfig.build.watch = null;\n },\n};\n\n/** Build-phase plugin hooks that may call `this.addWatchFile`. */\nconst WATCH_FILE_HOOKS = [\n 'buildStart',\n 'resolveId',\n 'resolveDynamicImport',\n 'load',\n 'transform',\n 'moduleParsed',\n 'buildEnd',\n];\n\n/** A module id or watched file as a forward-slash file path, without a query or hash (like Vite's cleanUrl). */\nfunction fileOfId(id: string): string {\n return toPosix(id.replace(/[?#].*$/s, ''));\n}\n\n/** A plugin context whose `addWatchFile` also records the file in `files`. */\nfunction recordingContext(context: object, files: Set<string>): object {\n return new Proxy(context, {\n get(target, key) {\n const value: unknown = Reflect.get(target, key, target);\n if (typeof value !== 'function') return value;\n if (key !== 'addWatchFile') return value.bind(target);\n return (id: string) => {\n if (!id.startsWith('\\0')) files.add(fileOfId(resolve(id)));\n return value.call(target, id);\n };\n },\n });\n}\n\n/**\n * A copy of `plugin` whose hooks record `addWatchFile` calls in `files`. The\n * original stays untouched, so a plugin object shared across entry builds never\n * collects wrappers. The copy keeps the prototype, so class-based plugins keep\n * their methods, and object-form hooks keep `order`, `filter` and the rest. A\n * plugin with no such hooks (a built-in one, for instance) is returned as is.\n */\nfunction recordingPlugin(plugin: unknown, files: Set<string>): unknown {\n if (typeof plugin !== 'object' || plugin === null) return plugin;\n const hooks = plugin as Readonly<Record<string, unknown>>;\n const hookHandler = (hook: unknown): unknown =>\n typeof hook === 'object' && hook !== null ? (hook as { handler?: unknown }).handler : hook;\n if (!WATCH_FILE_HOOKS.some((name) => typeof hookHandler(hooks[name]) === 'function')) return plugin;\n const copy = Object.create(\n Object.getPrototypeOf(plugin) as object | null,\n Object.getOwnPropertyDescriptors(plugin),\n ) as Record<string, unknown>;\n for (const name of WATCH_FILE_HOOKS) {\n const hook = hooks[name];\n const handler = hookHandler(hook);\n if (typeof handler !== 'function') continue;\n const wrapped = function (this: object, ...args: unknown[]): unknown {\n return handler.apply(recordingContext(this, files), args);\n };\n copy[name] = typeof hook === 'function' ? wrapped : { ...(hook as object), handler: wrapped };\n }\n return copy;\n}\n\n/**\n * Collects the files the entry build's plugins add with `addWatchFile`. These\n * are not modules of the bundle: Vite's CSS plugin adds the stylesheets pulled\n * in by `@import` and the files `url()` points at this way. The build runs on\n * recording copies of its plugins. They are made in the bundler's `options`\n * hook, which sees the final plugin list, including the plugins Vite resolves\n * per environment (`applyToEnvironment`) after `configResolved`.\n */\nfunction recordWatchFiles(files: Set<string>): Plugin {\n return {\n name: 'twee-ts:record-watch-files',\n options: {\n order: 'post',\n async handler(inputOptions) {\n const plugins = (await flattenPlugins(inputOptions.plugins)).map((p) => recordingPlugin(p, files));\n return { ...inputOptions, plugins: plugins as typeof inputOptions.plugins };\n },\n },\n };\n}\n\n/** A plugin option (nested arrays, promises, falsy entries) as one flat list. */\nasync function flattenPlugins(option: unknown): Promise<unknown[]> {\n const value: unknown = await option;\n if (Array.isArray(value)) return (await Promise.all(value.map(flattenPlugins))).flat();\n return value ? [value] : [];\n}\n\n/** Bundles the entry for dev with the user's own Vite config, unminified, with an inline source map. */\nasync function bundleEntryForDev(config: ResolvedConfig, entryPath: string): Promise<EntryBundle> {\n const watchFiles = new Set<string>();\n const inline: InlineConfig & Record<string, unknown> = {\n configFile: config.configFile ?? false,\n root: config.root,\n mode: config.mode,\n customLogger: entryBuildLogger(config.logger),\n publicDir: false,\n // With a config file the entry build reads it again, plugins and all. Without\n // one, the settings that change how code bundles come across from the server.\n ...(config.configFile ? {} : { define: config.define, resolve: { alias: config.resolve.alias } }),\n build: {\n ...entryBuildOptions(entryPath),\n write: false,\n minify: false,\n sourcemap: 'inline',\n emptyOutDir: false,\n copyPublicDir: false,\n watch: null,\n },\n plugins: [oneOffEntryBuild, recordWatchFiles(watchFiles)],\n [INNER_BUILD_FLAG]: true,\n };\n const out = await build(inline);\n const bundle: Record<string, BundleItem> = {};\n for (const result of Array.isArray(out) ? out : [out]) {\n if (!('output' in result)) {\n await result.close();\n throw new Error('twee-ts: the entry build returned a watcher instead of a bundle.');\n }\n for (const item of result.output) bundle[item.fileName] = item;\n }\n const entry = takeEntryFromBundle(bundle);\n for (const file of watchFiles) entry.files.add(file);\n return entry;\n}\n\nexport function tweeTsPlugin(options: TweeTsVitePluginOptions): Plugin {\n const outputFilename = options.outputFilename ?? 'index.html';\n const cache = new Map<string, FileCacheEntry>();\n let innerBuild = false;\n let building = false;\n let builtStory: string | undefined; // where a build writes the story, once the config is resolved\n let stopDev: (() => void) | undefined;\n\n if (options.entry && viteMajor < 8) {\n throw new Error(`twee-ts: the entry option needs Vite 8 or newer (found ${viteVersion}).`);\n }\n\n return {\n name: 'twee-ts',\n\n config(userConfig, env) {\n innerBuild = (userConfig as Record<string, unknown>)[INNER_BUILD_FLAG] === true;\n building = env.command === 'build';\n if (innerBuild || !building) return undefined;\n if (options.entry) return { build: entryBuildOptions(resolve(options.entry)) };\n if (hasUserInput(userConfig)) return undefined;\n return { build: inputOnly(EMPTY_INPUT) };\n },\n\n configResolved(config) {\n if (innerBuild) return;\n builtStory = builtStoryPath(config, outputFilename);\n if (!options.entry) return;\n const sources = options.sources.map((p) => toPosix(resolve(p)));\n if (isInside(toPosix(resolve(options.entry)), sources)) {\n config.logger.warn(\n `[twee-ts] The entry ${options.entry} is inside the story sources (${options.sources.join(', ')}). ` +\n 'twee-ts also loads the .js and .css files it finds in source folders, unbundled, as Story JavaScript ' +\n \"and Story Stylesheet; keep the entry's folder out of `sources`.\",\n );\n }\n },\n\n // `vite build --watch` rebuilds for the files the build registers. The story's\n // inputs are read in generateBundle, outside the module graph, so they are\n // registered here; the dev server watches them itself (configureServer).\n buildStart() {\n if (innerBuild || !building || !this.meta.watchMode) return;\n const story = builtStory === undefined ? undefined : toPosix(builtStory);\n for (const target of buildWatchTargets(watchedInputs(options), excludedInput(options, builtStory), story)) {\n this.addWatchFile(target);\n }\n },\n\n // The compile cache trusts modification times, which a quick save may leave\n // unchanged (coarse file-system timestamps); forget a file that changed.\n watchChange(id) {\n if (innerBuild) return;\n const changed = toPosix(resolve(id));\n for (const key of [...cache.keys()]) if (toPosix(resolve(key)) === changed) cache.delete(key);\n },\n\n resolveId(id) {\n return id === EMPTY_INPUT ? RESOLVED_EMPTY_INPUT : undefined;\n },\n\n load(id) {\n // A statement app builds keep (they drop unused exports), so Rollup in Vite 5\n // doesn't warn about an empty chunk. The chunk is removed from the output.\n return id === RESOLVED_EMPTY_INPUT ? 'globalThis.tweeTsEmptyInput = true;' : undefined;\n },\n\n generateBundle: {\n order: 'post',\n async handler(outputOptions, bundle) {\n if (innerBuild) return;\n for (const [fileName, item] of Object.entries(bundle)) {\n if (item.type === 'chunk' && item.facadeModuleId === RESOLVED_EMPTY_INPUT) delete bundle[fileName];\n }\n const entry = options.entry ? takeEntryFromBundle(bundle) : undefined;\n // The bundler's own output settings say where the story goes, should they\n // differ from build.outDir; its last build there is no source.\n const outFile = emittedFilePath(outputOptions, outputFilename) ?? builtStory;\n let result: CompileResult;\n try {\n result = await compileForOutputFile(buildCompileOptions(options, entry), outFile, cache);\n } catch (e) {\n return this.error(fatalError(e));\n }\n let warnings: Diagnostic[];\n try {\n warnings = splitDiagnostics(result);\n } catch (e) {\n return this.error(e as LocatedError);\n }\n for (const w of warnings) this.warn(formatDiagnostic(w));\n this.emitFile({ type: 'asset', fileName: outputFilename, source: result.output });\n },\n },\n\n async configureServer(server) {\n if (innerBuild) return;\n const base = server.config.base;\n const servePaths = outputFilename === 'index.html' ? [base, `${base}index.html`] : [`${base}${outputFilename}`];\n const inputs = watchedInputs(options);\n // A build's story HTML, which `vite build` may have left inside a source folder.\n const buildOutput = builtStoryPath(server.config, outputFilename);\n const excluded = excludedInput(options, buildOutput);\n const entryPath = options.entry ? resolve(options.entry) : undefined;\n const root = toPosix(server.config.root);\n server.watcher.add(inputs);\n\n let html = '';\n let lastError: ErrorPayload['err'] | undefined;\n let entry: EntryBundle | undefined; // last good bundle\n let entryStale = true; // bundle again on the next rebuild\n let queue: Promise<void> = Promise.resolve();\n let pending = new Set<string>();\n let timer: ReturnType<typeof setTimeout> | undefined;\n let closed = false;\n // The input files as the last compile found them, to tell whether the\n // watcher missed a change (see catchUp).\n let compiledInputs = new Map<string, string>();\n let catchingUp: Promise<void> | undefined;\n stopDev = () => {\n closed = true;\n clearTimeout(timer);\n pending.clear();\n };\n\n // The files that belong to the entry: after a good bundle, the modules it was\n // built from and the files its plugins watch (such as CSS @imports and url()\n // targets); while there is none, or the last one failed, anything in\n // the project, so that creating a missing import brings it back.\n const touchesEntry = (file: string): boolean =>\n entryPath !== undefined && (entryStale ? isInside(file, [root]) : (entry?.files.has(file) ?? false));\n\n // `initial`: the compile at server start. No page is open yet, and Vite would\n // hold a full-reload for the first page that connects and reload it once.\n const rebuild = async (changed: ReadonlySet<string>, initial = false): Promise<void> => {\n if (closed) return;\n // Taken before the compile reads anything, so a file written during it\n // still counts as changed afterwards.\n compiledInputs = inputFiles(inputs, excluded);\n // The compile cache trusts modification times, which a quick save may leave\n // unchanged (coarse file-system timestamps); forget the files that changed.\n for (const key of [...cache.keys()]) if (changed.has(toPosix(resolve(key)))) cache.delete(key);\n try {\n if (entryPath && (entryStale || [...changed].some(touchesEntry))) {\n entryStale = true;\n entry = await bundleEntryForDev(server.config, entryPath);\n entryStale = false;\n }\n const result = await compileForOutputFile(buildCompileOptions(options, entry), buildOutput, cache);\n for (const w of splitDiagnostics(result)) server.config.logger.warn(`[twee-ts] ${formatDiagnostic(w)}`);\n html = injectViteClient(result.output, base);\n lastError = undefined;\n if (!initial) server.ws.send({ type: 'full-reload' });\n } catch (e) {\n lastError = toOverlayError(e);\n server.config.logger.error(`[twee-ts] ${lastError.message}`);\n server.ws.send({ type: 'error', err: lastError });\n }\n };\n\n // rebuild() reports its own errors; this catches a failure while reporting,\n // so one bad report doesn't stop every later rebuild.\n const keepQueueAlive = (e: unknown): void => {\n try {\n server.config.logger.error(`[twee-ts] ${fatalError(e).message}`);\n } catch {\n // Nothing left to report with.\n }\n };\n\n await rebuild(new Set(), true);\n\n server.watcher.on('all', (event, file) => {\n if (event !== 'add' && event !== 'change' && event !== 'unlink') return;\n const changed = toPosix(resolve(file));\n // Loading the config for the entry build writes and deletes one of these;\n // reacting to it would bundle again, and again.\n if (isViteConfigTemp(changed)) return;\n if ((!isInside(changed, inputs) || excluded(changed)) && !touchesEntry(changed)) return;\n pending.add(changed);\n clearTimeout(timer);\n timer = setTimeout(() => {\n const files = pending;\n pending = new Set();\n queue = queue.then(() => rebuild(files)).catch(keepQueueAlive);\n }, 50);\n });\n\n // The watcher can miss changes. When a folder is deleted and created again\n // in quick succession (as `git rebase` does), chokidar stops watching the\n // folder, so a file added to it later raises no event; under Deno it also\n // loses the files created with it, so their later edits raise none\n // either. Before the story is served, this\n // waits for any compile under way, compares the input files with what the\n // last compile found, and compiles again first if they differ.\n const catchUp = (): Promise<void> => {\n catchingUp ??= (async () => {\n await queue;\n const changed = filesChanged(compiledInputs, inputFiles(inputs, excluded));\n if (changed.size === 0) return;\n // Changes the watcher did report, still waiting out the debounce, go into the same compile.\n for (const file of pending) changed.add(file);\n pending = new Set();\n clearTimeout(timer);\n queue = queue.then(() => rebuild(changed)).catch(keepQueueAlive);\n await queue;\n })().finally(() => {\n catchingUp = undefined;\n });\n return catchingUp;\n };\n\n server.ws.on('connection', () => {\n if (lastError) server.ws.send({ type: 'error', err: lastError });\n });\n\n server.middlewares.use((req, res, next) => {\n const path = (req.url ?? '').split('?')[0] ?? '';\n if (servePaths.includes(path)) {\n catchUp().then(() => {\n res.statusCode = 200;\n res.setHeader('Content-Type', 'text/html; charset=utf-8');\n res.end(html || waitingPage(base));\n }, next);\n return;\n }\n // Files the entry's bundle still emits separately, where the build writes them.\n const asset = path.startsWith(base) ? entry?.assets.get(path.slice(base.length)) : undefined;\n if (asset !== undefined) {\n res.statusCode = 200;\n res.setHeader('Content-Type', mediaTypeFromFilename(path));\n res.end(asset);\n return;\n }\n next();\n });\n },\n\n // Vite runs this when the dev server closes (and after a build); no rebuild may\n // start after it, including one whose timer is still pending in middleware mode.\n closeBundle() {\n stopDev?.();\n },\n };\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rohal12/twee-ts",
3
- "version": "1.17.0",
3
+ "version": "1.17.1",
4
4
  "description": "TypeScript Twee-to-HTML compiler — a complete reimplementation of Tweego",
5
5
  "type": "module",
6
6
  "license": "Unlicense",