@ng-doc/builder 22.0.0 → 22.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 (98) hide show
  1. package/LICENSE +21 -0
  2. package/engine/builders/helpers/get-playground-metadata.js +7 -1
  3. package/engine/builders/helpers/get-playground-metadata.js.map +1 -1
  4. package/engine/builders/page/demo-assets.builder.js +2 -0
  5. package/engine/builders/page/demo-assets.builder.js.map +1 -1
  6. package/engine/builders/shared/content.builder.js +2 -0
  7. package/engine/builders/shared/content.builder.js.map +1 -1
  8. package/engine/builders/shared/page-wrapper.builder.js +2 -0
  9. package/engine/builders/shared/page-wrapper.builder.js.map +1 -1
  10. package/generator/bootstrap/bin.js +174 -107
  11. package/generator/bootstrap/cli.js +174 -107
  12. package/generator/bootstrap/index.js +139 -99
  13. package/generator/bootstrap/process-tree.d.ts +5 -4
  14. package/generator/build-metafile.json +647 -240
  15. package/generator/build-provenance.json +6 -4
  16. package/generator/compiler/index.d.ts +20 -0
  17. package/generator/compiler/index.js +2400 -945
  18. package/generator/compiler/plan.d.ts +24 -0
  19. package/generator/content/code-snippet.d.ts +20 -0
  20. package/generator/content/content-compiler.d.ts +5 -1
  21. package/generator/content/format-cache.d.ts +108 -0
  22. package/generator/content/highlight-cache.d.ts +12 -36
  23. package/generator/content/html-pipeline.d.ts +10 -1
  24. package/generator/content/html-pool.d.ts +8 -2
  25. package/generator/content/html-worker.js +630 -39
  26. package/generator/contracts.d.ts +57 -0
  27. package/generator/discovery/index.d.ts +2 -0
  28. package/generator/kernel/flags.d.ts +5 -0
  29. package/generator/outputs/index.d.ts +29 -0
  30. package/generator/semantic/angular.d.ts +21 -1
  31. package/generator/semantic/formatting.d.ts +27 -0
  32. package/generator/semantic/fragments.d.ts +11 -2
  33. package/generator/templates/api/class-declaration.html.nunj +5 -3
  34. package/generator/templates/demo-app.ts.nunj +37 -0
  35. package/generator/templates/demo-routes.ts.nunj +43 -0
  36. package/generator/templates/index.ts.nunj +5 -0
  37. package/generator/templates/page-wrapper.ts.nunj +6 -1
  38. package/generator/templates/page.ts.nunj +13 -2
  39. package/generator/templates/routes.ts.nunj +7 -3
  40. package/generator/templates/symbol/members.html.nunj +6 -4
  41. package/generator/templates/symbol/page.html.nunj +1 -1
  42. package/generator/vite/angular/analog-provenance.json +1 -1
  43. package/generator/vite/angular-composition.d.ts +25 -1
  44. package/generator/vite/application-builder.js +6 -1
  45. package/generator/vite/application.d.ts +14 -0
  46. package/generator/vite/content-updates.d.ts +62 -0
  47. package/generator/vite/demo-application.d.ts +34 -0
  48. package/generator/vite/dev-server-builder.js +6 -1
  49. package/generator/vite/host-updates.d.ts +153 -6
  50. package/generator/vite/index.js +985 -247
  51. package/generator/vite/lifecycle.d.ts +40 -2
  52. package/generator/vite/prerender-entry.js +72 -2
  53. package/generator/vite/prerender-runtime.d.ts +13 -0
  54. package/generator/vite/prerender.d.ts +2 -0
  55. package/helpers/format-cache.d.ts +34 -0
  56. package/helpers/format-cache.js +26 -0
  57. package/helpers/format-cache.js.map +1 -0
  58. package/helpers/format-code.js +9 -2
  59. package/helpers/format-code.js.map +1 -1
  60. package/helpers/playground/get-playground-inputs.js +6 -3
  61. package/helpers/playground/get-playground-inputs.js.map +1 -1
  62. package/helpers/playground/playground-options.d.ts +28 -0
  63. package/helpers/playground/playground-options.js +122 -0
  64. package/helpers/playground/playground-options.js.map +1 -0
  65. package/helpers/playground/written-union-order.d.ts +33 -0
  66. package/helpers/playground/written-union-order.js +106 -0
  67. package/helpers/playground/written-union-order.js.map +1 -0
  68. package/helpers/to-template-string.d.ts +5 -1
  69. package/helpers/to-template-string.js +7 -2
  70. package/helpers/to-template-string.js.map +1 -1
  71. package/interfaces/code-block-options.d.ts +5 -0
  72. package/interfaces/configuration.d.ts +92 -1
  73. package/package.json +6 -5
  74. package/parsers/parse-code-block-params.d.ts +10 -1
  75. package/parsers/parse-code-block-params.js +29 -3
  76. package/parsers/parse-code-block-params.js.map +1 -1
  77. package/schematics/collection.json +1 -1
  78. package/schematics/migrate-to-vite/analyze.js +46 -3
  79. package/schematics/migrate-to-vite/analyze.js.map +1 -1
  80. package/schematics/migrate-to-vite/setup/workspace.d.ts +5 -0
  81. package/schematics/migrate-to-vite/setup/workspace.js +20 -0
  82. package/schematics/migrate-to-vite/setup/workspace.js.map +1 -1
  83. package/schematics/migrate-to-vite/testing/fixtures.d.ts +12 -0
  84. package/schematics/migrate-to-vite/testing/fixtures.js +27 -0
  85. package/schematics/migrate-to-vite/testing/fixtures.js.map +1 -1
  86. package/schematics/vite-setup/index.d.ts +9 -5
  87. package/schematics/vite-setup/index.js +11 -5
  88. package/schematics/vite-setup/index.js.map +1 -1
  89. package/schematics/vite-setup/schema.json +1 -1
  90. package/templates/api/class-declaration.html.nunj +5 -3
  91. package/templates/demo-app.ts.nunj +37 -0
  92. package/templates/demo-routes.ts.nunj +43 -0
  93. package/templates/index.ts.nunj +5 -0
  94. package/templates/page-wrapper.ts.nunj +6 -1
  95. package/templates/page.ts.nunj +13 -2
  96. package/templates/routes.ts.nunj +7 -3
  97. package/templates/symbol/members.html.nunj +6 -4
  98. package/templates/symbol/page.html.nunj +1 -1
@@ -0,0 +1,34 @@
1
+ /** The generated module of the demo application, in the output root (`demo-app.ts.nunj`). */
2
+ export declare const DEMO_APPLICATION_MODULE = "demo-app.ts";
3
+ /**
4
+ * The demo application of a generation: its generated module and the URL path of its pages.
5
+ * The NgDoc plugin publishes it to the application plugin (`NgDocDemoApplicationApi`).
6
+ */
7
+ export interface NgDocDemoApplication {
8
+ /** The generated module (absolute), which exports the routes and the providers import. */
9
+ readonly module: string;
10
+ /** The URL path of the demo pages, relative to the base href, without slashes around it. */
11
+ readonly path: string;
12
+ /** Every demo page, relative to the base href (`<path>/<page route>/<demo name>`). */
13
+ readonly pages: readonly string[];
14
+ }
15
+ /**
16
+ * What the NgDoc plugin offers the application plugin through `api.ngDocDemoApplication`.
17
+ * @internal
18
+ */
19
+ export interface NgDocDemoApplicationApi {
20
+ readonly schemaVersion: 1;
21
+ /**
22
+ * The demo application of the build's generation, generating first if the build has not yet: a
23
+ * build adds the demo page's input before it starts, when there is one.
24
+ */
25
+ resolve(): Promise<NgDocDemoApplication | undefined>;
26
+ /** The demo application of the current generation of the development server, if any. */
27
+ current(): Promise<NgDocDemoApplication | undefined>;
28
+ }
29
+ /**
30
+ * Reads the demo application from a committed output root: a generation writes `demo-app.ts`
31
+ * only when a guide has demo pages, and that module names the URL path of the pages.
32
+ * @param outputRoot - The output root of the published generation.
33
+ */
34
+ export declare function readDemoApplication(outputRoot: string): Promise<NgDocDemoApplication | undefined>;
@@ -7,6 +7,7 @@ import { Observable } from "rxjs";
7
7
  import { createServer as viteCreateServer } from "vite";
8
8
 
9
9
  // libs/builder/generator/vite/production.ts
10
+ import { existsSync } from "node:fs";
10
11
  import { rm, writeFile } from "node:fs/promises";
11
12
  import path from "node:path";
12
13
  import { build as viteBuild } from "vite";
@@ -75,7 +76,8 @@ function prerenderNgDoc(options) {
75
76
  serverEntry: options.serverEntry,
76
77
  routes: [...options.routes ?? []],
77
78
  discoverRoutes: options.discoverRoutes ?? true,
78
- ...options.routeTimeoutMs === void 0 ? {} : { routeTimeoutMs: options.routeTimeoutMs }
79
+ ...options.routeTimeoutMs === void 0 ? {} : { routeTimeoutMs: options.routeTimeoutMs },
80
+ ...options.demoServerEntry ? { demoServerEntry: options.demoServerEntry } : {}
79
81
  };
80
82
  if (request.routeTimeoutMs !== void 0 && (!Number.isSafeInteger(request.routeTimeoutMs) || request.routeTimeoutMs < 1)) {
81
83
  return Promise.reject(
@@ -256,11 +258,13 @@ async function buildNgDocViteApplication(options, dependencies = defaultDependen
256
258
  }
257
259
  const prerender = options.prerender ?? (options.skipBuild ? true : ssr === true);
258
260
  if (!prerender) return { browser, ...ssr ? { server: serverEntry } : {} };
261
+ const demoServerEntry = path.join(serverDirectory, "demo-server.mjs");
259
262
  const report = await timed(
260
263
  "Prerendered the routes",
261
264
  () => dependencies.prerender({
262
265
  browserDir: browser,
263
266
  serverEntry,
267
+ ...existsSync(demoServerEntry) && existsSync(path.join(browser, "ng-doc-demo.html")) ? { demoServerEntry } : {},
264
268
  routes: options.routes ?? [],
265
269
  discoverRoutes: options.discoverRoutes ?? true,
266
270
  ...options.routeTimeoutMs === void 0 ? {} : { routeTimeoutMs: options.routeTimeoutMs },
@@ -273,6 +277,7 @@ async function buildNgDocViteApplication(options, dependencies = defaultDependen
273
277
  `
274
278
  );
275
279
  log(`Prerendered ${report.routes.length} route(s) into ${browser}`);
280
+ for (const { route, message: message2 } of report.warnings ?? []) log(`Warning: ${route}: ${message2}`);
276
281
  if (report.errors.length) {
277
282
  log(`The application logged ${report.errors.length} error(s) while prerendering:`);
278
283
  for (const { route, message: message2 } of report.errors.slice(0, 10)) log(` ${route}: ${message2}`);
@@ -4,6 +4,24 @@ export interface PhysicalState {
4
4
  digest?: string;
5
5
  version: string;
6
6
  }
7
+ export interface ManifestFile {
8
+ digest: string;
9
+ role: OutputManifest['files'][number]['role'];
10
+ }
11
+ /**
12
+ * One generated file whose bytes or role differ between the outputs the browser was last told
13
+ * about and the outputs a reload announces now.
14
+ */
15
+ export interface AnnouncedChange {
16
+ /** Relative to the output root, with forward slashes, as the manifest lists it. */
17
+ readonly path: string;
18
+ /** The absolute path. */
19
+ readonly file: string;
20
+ /** Absent for a created file. */
21
+ readonly before?: Readonly<ManifestFile>;
22
+ /** Absent for a deleted file. */
23
+ readonly after?: Readonly<ManifestFile>;
24
+ }
7
25
  export interface HostUpdateTicket {
8
26
  readonly ready: Promise<void>;
9
27
  readonly token: object;
@@ -15,13 +33,60 @@ export interface InitialCompilationInventory {
15
33
  }>;
16
34
  isCurrent(): boolean;
17
35
  }
36
+ /**
37
+ * What the host does for the coordinator when a burst ends (see {@link HostUpdateCoordinator}).
38
+ */
39
+ export interface HostUpdateRecovery {
40
+ /** Logs a warning: the summary of the host update timeouts a burst held back. */
41
+ warn(message: string): void;
42
+ /**
43
+ * Reports `file` again as its watcher would have: a generated output whose report never
44
+ * completed its generation's expectation (lost, or its hook timed out and threw).
45
+ */
46
+ replay(file: string, type: 'create' | 'update' | 'delete'): void;
47
+ /** Re-observes every recorded input before the next generation (`BuildSession.rescan`). */
48
+ rescan(): void;
49
+ }
50
+ /** How long a host update waits for the publication's host obligations to drain. */
51
+ export declare const HOST_COMPLETION_TIMEOUT_MS = 30000;
52
+ /** Hot updates within {@link HOST_BURST_WINDOW_MS} that open a burst of file events. */
53
+ export declare const HOST_BURST_EVENTS = 1000;
54
+ /** The window in which {@link HOST_BURST_EVENTS} hot updates open a burst. */
55
+ export declare const HOST_BURST_WINDOW_MS = 1000;
56
+ /** A burst ends after this long without a hot update or a host update timeout. */
57
+ export declare const HOST_BURST_QUIET_MS = 2000;
18
58
  export declare function observePhysicalState(file: string, read?: () => string | Promise<string>): Promise<PhysicalState>;
19
59
  /** A synchronous metadata-only stamp preserves the event-time identity without starting I/O queues. */
20
60
  export declare function observePhysicalVersion(file: string): string | undefined;
21
- /** Coordinates committed generator versions with Vite's client hot-update pipeline. */
61
+ /**
62
+ * Coordinates committed generator versions with Vite's client hot-update pipeline.
63
+ *
64
+ * Bursts: thousands of file events at once (a script or a checkout writing many files) flood
65
+ * Vite's hot-update pipeline and the watcher. Host updates then wait longer than
66
+ * {@link HOST_COMPLETION_TIMEOUT_MS}, a hook that timed out leaves its generation's obligation
67
+ * open (nothing reports that output again, so no reload is ever sent), and chokidar may lose
68
+ * events without any signal. So a burst is tracked: it opens with {@link HOST_BURST_EVENTS} hot
69
+ * updates of files outside the output root (once the first generation is published) within
70
+ * {@link HOST_BURST_WINDOW_MS}, or with a host update timeout, and ends after
71
+ * {@link HOST_BURST_QUIET_MS} without either. Only its first timeout is reported as it happens;
72
+ * the others are summed up in one warning when it ends. Then it takes one more pass: every
73
+ * generated output whose report never completed its expectation, and whose file is still what
74
+ * its generation wrote, is reported again (`HostUpdateRecovery.replay`), and every recorded
75
+ * input is re-observed (`HostUpdateRecovery.rescan`), so the newest edit is published even if
76
+ * its event was lost or its generation failed under the load. A replayed report is matched like
77
+ * any other: one that arrives twice is a repeat, so an edit still reloads once.
78
+ *
79
+ * Churn: under a sustained stream of edits a new generation starts before the previous one is
80
+ * published, again and again. A host update that waits for the current publication follows each
81
+ * newer generation, so it settles only once the stream stops. That is required of one whose hook
82
+ * hands Vite modules: Vite updates them when the hook returns, which must not happen before the
83
+ * newest publication. A module-less one hands Vite nothing, so it settles once it is acknowledged
84
+ * (see {@link settle}; `NGDOC_VITE_MODULELESS_SETTLE=0` makes it wait as well).
85
+ */
22
86
  export declare class HostUpdateCoordinator {
23
87
  private readonly notify;
24
88
  private readonly fail;
89
+ private readonly recovery?;
25
90
  private outputRoot?;
26
91
  private manifest?;
27
92
  private announcedManifest?;
@@ -43,7 +108,24 @@ export declare class HostUpdateCoordinator {
43
108
  private pendingGeneration?;
44
109
  private sequence;
45
110
  private disposed;
46
- constructor(notify: () => void, fail: (error: Error) => void);
111
+ private burst?;
112
+ /** The start and the hot updates of the current burst-detection window. */
113
+ private window;
114
+ /** Whether a module-less host update settles without waiting for the current publication. */
115
+ private readonly modulelessSettle;
116
+ /**
117
+ * Whether the pending reload must reload the page whatever its outputs: an Angular source was
118
+ * compiled for it, or it repairs an earlier failure (the browser shows the error overlay).
119
+ */
120
+ private pendingFull;
121
+ /**
122
+ * @param notify Announces the newest settled publication to the browser. `changes` lists the
123
+ * generated files that differ from the last announcement, when nothing else asks for a full
124
+ * reload; without it, or when the host cannot apply the changes in place, the page reloads.
125
+ * @param fail Reports a host error.
126
+ * @param recovery What the host does after a burst.
127
+ */
128
+ constructor(notify: (changes?: readonly AnnouncedChange[]) => void, fail: (error: Error) => void, recovery?: HostUpdateRecovery | undefined);
47
129
  seed(outputRoot: string, manifest: OutputManifest): void;
48
130
  initialCompilationInventory(): InitialCompilationInventory;
49
131
  started(generation: number, changes: FileChange[]): void;
@@ -70,7 +152,8 @@ export declare class HostUpdateCoordinator {
70
152
  * generated output that a generation claimed. Its host hooks settle only once the newest
71
153
  * generation is published and every host obligation is drained, and by then `flush()` has sent
72
154
  * that generation's reload (or its outputs equal the last announced ones). A native reload for
73
- * the same output would be a second one.
155
+ * the same output would be a second one. A module-less one settles earlier (see
156
+ * {@link settle}), but Vite has nothing of it to reload either way.
74
157
  */
75
158
  announces(read: object): boolean;
76
159
  /**
@@ -81,6 +164,16 @@ export declare class HostUpdateCoordinator {
81
164
  * `ticket.ready`, which binds the generation.
82
165
  */
83
166
  compilerCompanions(ticket: HostUpdateTicket): string[];
167
+ /**
168
+ * Whether the generation that claimed this TypeScript source update committed and still has a
169
+ * generated TypeScript module update whose Angular pass has not completed: that pass is still to
170
+ * come, and the source can join it (`ngDocCompanionFiles`) instead of taking a pass of its own.
171
+ * False for anything else: a generated output, a source no generation claimed, a generation
172
+ * that failed, was cancelled or rewrote no TypeScript module, or whose passes all completed.
173
+ * Call it after `committed(ticket)`, which waits for the generation's result.
174
+ * @param ticket The source's hot update ticket.
175
+ */
176
+ generationPass(ticket: HostUpdateTicket): boolean;
84
177
  /**
85
178
  * Whether `file` is a generated output: a path below the output root of the published
86
179
  * generation. Nothing is generated before the first publication or after disposal.
@@ -93,11 +186,30 @@ export declare class HostUpdateCoordinator {
93
186
  /** The diagnostics recorded so far; a pass that starts now can repair exactly these. */
94
187
  diagnosticMark(): number;
95
188
  private recoverDiagnostics;
96
- /** Waits for the current accepted publication and all peer host acknowledgments. */
97
- settle(ticket: HostUpdateTicket): Promise<void>;
189
+ /**
190
+ * Waits for the current accepted publication and all peer host acknowledgments.
191
+ *
192
+ * A module-less hot update does not wait: once its hooks return, Vite has no module to update
193
+ * and sends nothing, and its acknowledgment has already settled what it obliged (the reload,
194
+ * sent by `flush()` once every obligation is settled, is this coordinator's own). Waiting made
195
+ * it follow every generation that started meanwhile, so under sustained churn it settled only
196
+ * when the churn stopped, and each wait for the host obligations to drain could time out
197
+ * (`NGDOC_VITE_HOST_TIMEOUT`) while every single obligation was completed in time. Nothing
198
+ * else changes: obligations, the reload and what is published are the same, so the switch off
199
+ * (`NGDOC_VITE_MODULELESS_SETTLE=0`) only makes it wait as before.
200
+ * @param ticket The hot update's ticket, after its acknowledgment.
201
+ * @param modules Whether its hooks hand Vite any module to update (or a page reload Vite sends
202
+ * itself, for an HTML file without modules). Only the caller, which sees Vite's context, knows.
203
+ */
204
+ settle(ticket: HostUpdateTicket, modules?: boolean): Promise<void>;
98
205
  /** Waits for the candidate's atomic commit boundary, including a failure that kept last-good. */
99
206
  committed(ticket: HostUpdateTicket): Promise<void>;
100
- complete(ticket: HostUpdateTicket): Promise<void>;
207
+ /**
208
+ * Acknowledges a hot update that takes no compiler pass, then settles it.
209
+ * @param ticket The hot update's ticket.
210
+ * @param modules See {@link settle}.
211
+ */
212
+ complete(ticket: HostUpdateTicket, modules?: boolean): Promise<void>;
101
213
  published(result: Extract<BuildResult, {
102
214
  status: 'success';
103
215
  }>, recovered: boolean): void;
@@ -136,10 +248,45 @@ export declare class HostUpdateCoordinator {
136
248
  private hasOutputBlockers;
137
249
  private flush;
138
250
  private queueCurrentReload;
251
+ /**
252
+ * Settles a module-less hot update without waiting (see {@link settle}).
253
+ * @param token The acknowledged hot update.
254
+ */
255
+ private settleModuleless;
139
256
  private awaitCurrentPublication;
140
257
  private awaitWithoutDiagnostic;
141
258
  private delta;
259
+ /**
260
+ * The generated files that differ between two manifests, in path order.
261
+ * @param previousManifest The outputs the browser was last told about.
262
+ * @param nextManifest The outputs announced now.
263
+ */
264
+ private changes;
142
265
  private prune;
143
266
  private withTimeout;
267
+ /** Counts a hot update towards a burst of file events (see the class description). */
268
+ private hotUpdate;
269
+ /**
270
+ * A host update did not settle in time. The first of a burst is reported as it happens (as
271
+ * every timeout was before); the others only count towards the burst's summary, so a flood of
272
+ * file events logs two lines instead of one per event.
273
+ * @param failure The timeout, thrown to its waiter as well.
274
+ */
275
+ private timedOut;
276
+ private openBurst;
277
+ /**
278
+ * One timer per burst, re-armed for the rest of the quiet period when activity moved `last`.
279
+ * @param burst The open burst.
280
+ * @param delay When to check it next.
281
+ */
282
+ private armBurst;
283
+ /**
284
+ * The pass after a burst: the summary of its held-back timeouts, then every open output
285
+ * obligation whose file is still what its generation wrote is reported again, in path order,
286
+ * and every recorded input is re-observed once no generation is in flight. An output a newer generation rewrote since is left
287
+ * to that generation's own report, which supersedes the older expectation.
288
+ * @param burst The burst that ended.
289
+ */
290
+ private recover;
144
291
  }
145
292
  export {};