@dokebi/template-inertia 0.4.2 → 0.4.5
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.
- package/AI.md +136 -23
- package/README.md +23 -7
- package/dist/boot-fallback.d.ts +61 -0
- package/dist/boot-fallback.js +134 -0
- package/dist/built-files.d.ts +9 -0
- package/dist/built-files.js +44 -0
- package/dist/errors.d.ts +2 -2
- package/dist/errors.js +3 -1
- package/dist/i18n-store.d.ts +64 -0
- package/dist/i18n-store.js +368 -0
- package/dist/i18n.d.ts +216 -0
- package/dist/i18n.js +901 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +426 -63
- package/dist/options.d.ts +28 -0
- package/dist/options.js +97 -1
- package/dist/prune.d.ts +30 -0
- package/dist/prune.js +159 -0
- package/dist/responder.d.ts +14 -4
- package/dist/responder.js +70 -11
- package/dist/vite-deps.d.ts +76 -0
- package/dist/vite-deps.js +249 -0
- package/dist/vite-dev.d.ts +42 -4
- package/dist/vite-dev.js +162 -16
- package/dist/vite-files.d.ts +129 -0
- package/dist/vite-files.js +633 -0
- package/dist/vite-host.js +67 -10
- package/dist/vite-plugin.d.ts +69 -0
- package/dist/vite-plugin.js +173 -0
- package/dist/vite-watch.d.ts +44 -0
- package/dist/vite-watch.js +176 -0
- package/options.schema.json +127 -1
- package/package.json +38 -11
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { Logger } from '@dokebi/core';
|
|
2
|
+
/** One optimized dependency or chunk as Vite's optimizer holds it (absolute `file`). */
|
|
3
|
+
interface DepInfoShape {
|
|
4
|
+
readonly file: string;
|
|
5
|
+
readonly fileHash?: string;
|
|
6
|
+
}
|
|
7
|
+
/** The part of Vite's dependency optimizer read here. */
|
|
8
|
+
interface DepsOptimizerShape {
|
|
9
|
+
readonly metadata: {
|
|
10
|
+
readonly hash: string;
|
|
11
|
+
readonly optimized: Readonly<Record<string, DepInfoShape>>;
|
|
12
|
+
readonly chunks: Readonly<Record<string, DepInfoShape>>;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
/** The part of Vite's dev server the cache check uses. */
|
|
16
|
+
export interface DepsServerShape {
|
|
17
|
+
readonly config: {
|
|
18
|
+
readonly cacheDir: string;
|
|
19
|
+
};
|
|
20
|
+
readonly environments?: {
|
|
21
|
+
readonly client?: {
|
|
22
|
+
readonly depsOptimizer?: DepsOptimizerShape;
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
restart(forceOptimize?: boolean): Promise<void>;
|
|
26
|
+
}
|
|
27
|
+
/** Why the folder no longer holds what the optimizer serves. */
|
|
28
|
+
export type DepsDrift = 'missing' | 'rewritten';
|
|
29
|
+
export interface DepsState {
|
|
30
|
+
/** Undefined when the folder holds every file the optimizer serves, as it wrote them. */
|
|
31
|
+
readonly drift: DepsDrift | undefined;
|
|
32
|
+
/** Files the optimizer serves (optimized dependencies and their chunks). */
|
|
33
|
+
readonly files: number;
|
|
34
|
+
/** Served files that are not on disk (absolute paths). */
|
|
35
|
+
readonly missing: readonly string[];
|
|
36
|
+
/** The optimizer metadata that was compared (Vite replaces the object on every commit). */
|
|
37
|
+
readonly metadata?: object;
|
|
38
|
+
}
|
|
39
|
+
/** What asked for the check (logged). */
|
|
40
|
+
export type DepsTrigger = 'start' | 'client' | 'outdated';
|
|
41
|
+
export interface DependencyCacheOptions {
|
|
42
|
+
/** Least time between two repairs in ms (`devDepsRepairIntervalMs`). */
|
|
43
|
+
readonly repairIntervalMs: number;
|
|
44
|
+
/** The clock (tests). */
|
|
45
|
+
readonly now?: () => number;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* The host's check of its dependency cache. `ensure` re-optimizes when the folder no longer holds
|
|
49
|
+
* what the optimizer serves; one check or repair runs at a time (callers share it).
|
|
50
|
+
*/
|
|
51
|
+
export declare class DependencyCache {
|
|
52
|
+
#private;
|
|
53
|
+
constructor(logger: Logger, server: DepsServerShape, options: DependencyCacheOptions);
|
|
54
|
+
/** Repairs so far. */
|
|
55
|
+
get repairs(): number;
|
|
56
|
+
/** The deps folder of the browser environment (`<cacheDir>/deps`, Vite's default name). */
|
|
57
|
+
get folder(): string;
|
|
58
|
+
/**
|
|
59
|
+
* Compares the optimizer's state with the folder: every served file is there, and the
|
|
60
|
+
* metadata on disk is the one this optimizer wrote or loaded (same hash and file hashes).
|
|
61
|
+
*/
|
|
62
|
+
inspect(): Promise<DepsState>;
|
|
63
|
+
/**
|
|
64
|
+
* Checks the cache and re-optimizes when it drifted; resolves true after a repair. A check or
|
|
65
|
+
* repair already running is shared. Failures reject (the caller logs them).
|
|
66
|
+
*/
|
|
67
|
+
ensure(trigger: DepsTrigger): Promise<boolean>;
|
|
68
|
+
/**
|
|
69
|
+
* Records this host in the cache folder and warns when another live host of `dokebi dev`
|
|
70
|
+
* recorded itself there: two optimizers on one folder can break each other's files.
|
|
71
|
+
*/
|
|
72
|
+
claim(pid?: number): Promise<void>;
|
|
73
|
+
/** Removes the marker when it is still this host's. */
|
|
74
|
+
release(pid?: number): Promise<void>;
|
|
75
|
+
}
|
|
76
|
+
export {};
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
// The pre-bundled dependencies of the Vite dev host (D-0128). Vite keeps what its dependency
|
|
2
|
+
// optimizer produced in memory (each dependency's file under node_modules/.vite/deps and the
|
|
3
|
+
// `?v=` hash the browser is given) and trusts node_modules/.vite/deps/_metadata.json at start when
|
|
4
|
+
// its lockfile and config hashes match; it never looks at the files again. A cache changed under
|
|
5
|
+
// it (another Vite or `dokebi dev` on the same folder re-optimizing at the same time, a reinstall)
|
|
6
|
+
// leaves metadata that names files that are gone. Vite answers a gone file requested with `?v=` as
|
|
7
|
+
// 504 "Outdated Optimize Dep", and nothing ever heals that: the host outlives app restarts (D-0045
|
|
8
|
+
// addendum 3) and the next host trusts the same metadata.
|
|
9
|
+
//
|
|
10
|
+
// So the host compares its optimizer's state with the folder when it starts, whenever an app
|
|
11
|
+
// process connects (every app or worker restart) and after a 504, and re-optimizes when they
|
|
12
|
+
// differ: it removes the deps folder and restarts its Vite (a new optimizer, a new module graph;
|
|
13
|
+
// open pages reconnect HMR and reload, a new page load gets the new hashes). A repair at most once
|
|
14
|
+
// per `devDepsRepairIntervalMs`; a cache that keeps changing faster is reported instead.
|
|
15
|
+
import { constants } from 'node:fs';
|
|
16
|
+
import { access, mkdir, readFile, rm, writeFile } from 'node:fs/promises';
|
|
17
|
+
import { dirname, join } from 'node:path';
|
|
18
|
+
import { diagnostics } from '@dokebi/core/libraries';
|
|
19
|
+
const { describeError } = diagnostics;
|
|
20
|
+
/** Vite's metadata file in the deps folder. */
|
|
21
|
+
const METADATA_FILE = '_metadata.json';
|
|
22
|
+
/**
|
|
23
|
+
* The marker of the host that uses a cache folder (its pid), in Vite's cacheDir: under `.dokebi/`,
|
|
24
|
+
* which the dev server never serves (the `.dokebi` rule of DEV_FILES_DENY, D-0129).
|
|
25
|
+
*/
|
|
26
|
+
const HOST_MARKER = join('.dokebi', 'vite-host.json');
|
|
27
|
+
/** Missing files named in a log record at most. */
|
|
28
|
+
const SAMPLE = 5;
|
|
29
|
+
async function present(file) {
|
|
30
|
+
try {
|
|
31
|
+
await access(file, constants.F_OK);
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
if (error.code === 'ENOENT')
|
|
36
|
+
return false;
|
|
37
|
+
throw error;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/** `process.kill(pid, 0)`: whether the process exists (EPERM: it exists, owned by another user). */
|
|
41
|
+
function alive(pid) {
|
|
42
|
+
try {
|
|
43
|
+
process.kill(pid, 0);
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
return error.code === 'EPERM';
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* The host's check of its dependency cache. `ensure` re-optimizes when the folder no longer holds
|
|
52
|
+
* what the optimizer serves; one check or repair runs at a time (callers share it).
|
|
53
|
+
*/
|
|
54
|
+
export class DependencyCache {
|
|
55
|
+
#logger;
|
|
56
|
+
#server;
|
|
57
|
+
#intervalMs;
|
|
58
|
+
#now;
|
|
59
|
+
#running;
|
|
60
|
+
#repairedAt = Number.NEGATIVE_INFINITY;
|
|
61
|
+
#repairs = 0;
|
|
62
|
+
#skippedWarnedAt = Number.NEGATIVE_INFINITY;
|
|
63
|
+
#skipped = 0;
|
|
64
|
+
constructor(logger, server, options) {
|
|
65
|
+
this.#logger = logger;
|
|
66
|
+
this.#server = server;
|
|
67
|
+
this.#intervalMs = options.repairIntervalMs;
|
|
68
|
+
this.#now = options.now ?? Date.now;
|
|
69
|
+
}
|
|
70
|
+
/** Repairs so far. */
|
|
71
|
+
get repairs() {
|
|
72
|
+
return this.#repairs;
|
|
73
|
+
}
|
|
74
|
+
/** The deps folder of the browser environment (`<cacheDir>/deps`, Vite's default name). */
|
|
75
|
+
get folder() {
|
|
76
|
+
return join(this.#server.config.cacheDir, 'deps');
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Compares the optimizer's state with the folder: every served file is there, and the
|
|
80
|
+
* metadata on disk is the one this optimizer wrote or loaded (same hash and file hashes).
|
|
81
|
+
*/
|
|
82
|
+
async inspect() {
|
|
83
|
+
const optimizer = this.#server.environments?.client?.depsOptimizer;
|
|
84
|
+
if (!optimizer)
|
|
85
|
+
return { drift: undefined, files: 0, missing: [] };
|
|
86
|
+
const { metadata } = optimizer;
|
|
87
|
+
const served = [...Object.values(metadata.optimized), ...Object.values(metadata.chunks)];
|
|
88
|
+
// Nothing served from the folder yet (a first optimization still running): nothing to lose.
|
|
89
|
+
if (served.length === 0)
|
|
90
|
+
return { drift: undefined, files: 0, missing: [], metadata };
|
|
91
|
+
const found = await Promise.all(served.map((info) => present(info.file)));
|
|
92
|
+
const missing = served.filter((_, index) => !found[index]).map((info) => info.file);
|
|
93
|
+
if (missing.length)
|
|
94
|
+
return { drift: 'missing', files: served.length, missing, metadata };
|
|
95
|
+
const folder = dirname(served[0]?.file ?? join(this.folder, METADATA_FILE));
|
|
96
|
+
let text;
|
|
97
|
+
try {
|
|
98
|
+
text = await readFile(join(folder, METADATA_FILE), 'utf8');
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
// The files are there and Vite never reads the metadata again while it runs; the next
|
|
102
|
+
// host start finds no metadata and optimizes afresh.
|
|
103
|
+
if (error.code === 'ENOENT')
|
|
104
|
+
return { drift: undefined, files: served.length, missing, metadata };
|
|
105
|
+
throw error;
|
|
106
|
+
}
|
|
107
|
+
let disk;
|
|
108
|
+
try {
|
|
109
|
+
disk = JSON.parse(text);
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
if (this.#logger.isEnabled('debug'))
|
|
113
|
+
this.#logger.log('debug', 'Vite dev host found unreadable dependency metadata', {
|
|
114
|
+
folder,
|
|
115
|
+
error: describeError(error),
|
|
116
|
+
});
|
|
117
|
+
return { drift: 'rewritten', files: served.length, missing, metadata };
|
|
118
|
+
}
|
|
119
|
+
const same = disk.hash === metadata.hash &&
|
|
120
|
+
Object.entries(metadata.optimized).every(([id, info]) => disk.optimized?.[id]?.fileHash === info.fileHash);
|
|
121
|
+
return { drift: same ? undefined : 'rewritten', files: served.length, missing, metadata };
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Checks the cache and re-optimizes when it drifted; resolves true after a repair. A check or
|
|
125
|
+
* repair already running is shared. Failures reject (the caller logs them).
|
|
126
|
+
*/
|
|
127
|
+
ensure(trigger) {
|
|
128
|
+
this.#running ??= this.#ensure(trigger).finally(() => {
|
|
129
|
+
this.#running = undefined;
|
|
130
|
+
});
|
|
131
|
+
return this.#running;
|
|
132
|
+
}
|
|
133
|
+
async #ensure(trigger) {
|
|
134
|
+
let state = await this.inspect();
|
|
135
|
+
// Vite commits a new optimization by renaming folders and then replacing its metadata; a
|
|
136
|
+
// check between the two saw the old metadata against the new files. Compare again.
|
|
137
|
+
if (state.drift !== undefined &&
|
|
138
|
+
state.metadata !== this.#server.environments?.client?.depsOptimizer?.metadata) {
|
|
139
|
+
if (this.#logger.isEnabled('debug'))
|
|
140
|
+
this.#logger.log('debug', 'Vite dev host compares its dependency cache again', {
|
|
141
|
+
trigger,
|
|
142
|
+
drift: state.drift,
|
|
143
|
+
});
|
|
144
|
+
state = await this.inspect();
|
|
145
|
+
}
|
|
146
|
+
if (state.drift === undefined) {
|
|
147
|
+
if (this.#logger.isEnabled('debug'))
|
|
148
|
+
this.#logger.log('debug', 'Vite dev host dependency cache matches', {
|
|
149
|
+
trigger,
|
|
150
|
+
files: state.files,
|
|
151
|
+
});
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
const now = this.#now();
|
|
155
|
+
if (now - this.#repairedAt < this.#intervalMs) {
|
|
156
|
+
// Something rewrites the folder faster than the host repairs it: say so, once a window.
|
|
157
|
+
this.#skipped++;
|
|
158
|
+
if (now - this.#skippedWarnedAt >= this.#intervalMs) {
|
|
159
|
+
this.#logger.log('warn', 'Vite dev host dependency cache keeps changing; is another dokebi dev or Vite using this project?', {
|
|
160
|
+
code: 'INERTIA_VITE_DEPS_CHANGING',
|
|
161
|
+
trigger,
|
|
162
|
+
drift: state.drift,
|
|
163
|
+
folder: this.folder,
|
|
164
|
+
repairIntervalMs: this.#intervalMs,
|
|
165
|
+
repeated: this.#skipped,
|
|
166
|
+
});
|
|
167
|
+
this.#skippedWarnedAt = now;
|
|
168
|
+
this.#skipped = 0;
|
|
169
|
+
}
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
this.#repairedAt = now;
|
|
173
|
+
this.#repairs++;
|
|
174
|
+
this.#logger.log('warn', 'Vite dev host found its pre-bundled dependencies changed on disk; re-optimizing', {
|
|
175
|
+
code: 'INERTIA_VITE_DEPS_STALE',
|
|
176
|
+
trigger,
|
|
177
|
+
drift: state.drift,
|
|
178
|
+
folder: this.folder,
|
|
179
|
+
files: state.files,
|
|
180
|
+
missing: state.missing.length,
|
|
181
|
+
sample: state.missing.slice(0, SAMPLE),
|
|
182
|
+
});
|
|
183
|
+
const begin = performance.now();
|
|
184
|
+
// Vite reads no metadata from a folder that is not there: the restarted optimizer starts
|
|
185
|
+
// afresh (the folder is rewritten, the browser gets new `?v=` hashes). restart(true) would
|
|
186
|
+
// do the same but keep forcing a re-optimization on every later restart of this Vite.
|
|
187
|
+
await rm(this.folder, { recursive: true, force: true });
|
|
188
|
+
await this.#server.restart();
|
|
189
|
+
this.#logger.log('debug', 'Vite dev host re-optimized its dependencies', {
|
|
190
|
+
trigger,
|
|
191
|
+
ms: Math.round(performance.now() - begin),
|
|
192
|
+
repairs: this.#repairs,
|
|
193
|
+
});
|
|
194
|
+
return true;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Records this host in the cache folder and warns when another live host of `dokebi dev`
|
|
198
|
+
* recorded itself there: two optimizers on one folder can break each other's files.
|
|
199
|
+
*/
|
|
200
|
+
async claim(pid = process.pid) {
|
|
201
|
+
const marker = join(this.#server.config.cacheDir, HOST_MARKER);
|
|
202
|
+
let other;
|
|
203
|
+
try {
|
|
204
|
+
const recorded = JSON.parse(await readFile(marker, 'utf8')).pid;
|
|
205
|
+
if (typeof recorded === 'number' && recorded !== pid && alive(recorded))
|
|
206
|
+
other = recorded;
|
|
207
|
+
}
|
|
208
|
+
catch (error) {
|
|
209
|
+
const code = error.code;
|
|
210
|
+
if (code !== 'ENOENT' && !(error instanceof SyntaxError))
|
|
211
|
+
throw error;
|
|
212
|
+
if (this.#logger.isEnabled('debug'))
|
|
213
|
+
this.#logger.log('debug', 'Vite dev host found no live host marker', {
|
|
214
|
+
marker,
|
|
215
|
+
reason: code ?? 'unreadable',
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
if (other !== undefined)
|
|
219
|
+
this.#logger.log('warn', 'Another dokebi dev Vite host uses this project; stop one, or their pre-bundled dependencies can break each other', { code: 'INERTIA_VITE_HOST_SHARED', pid: other, folder: this.#server.config.cacheDir });
|
|
220
|
+
await mkdir(dirname(marker), { recursive: true });
|
|
221
|
+
await writeFile(marker, `${JSON.stringify({ pid })}\n`);
|
|
222
|
+
this.#logger.log('debug', 'Vite dev host recorded itself in the cache folder', {
|
|
223
|
+
marker,
|
|
224
|
+
shared: other !== undefined,
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
/** Removes the marker when it is still this host's. */
|
|
228
|
+
async release(pid = process.pid) {
|
|
229
|
+
const marker = join(this.#server.config.cacheDir, HOST_MARKER);
|
|
230
|
+
let recorded;
|
|
231
|
+
try {
|
|
232
|
+
recorded = JSON.parse(await readFile(marker, 'utf8')).pid;
|
|
233
|
+
}
|
|
234
|
+
catch (error) {
|
|
235
|
+
const code = error.code;
|
|
236
|
+
if (code !== 'ENOENT' && !(error instanceof SyntaxError))
|
|
237
|
+
throw error;
|
|
238
|
+
// Gone or not a marker this host wrote: nothing of this host's to remove.
|
|
239
|
+
if (this.#logger.isEnabled('debug'))
|
|
240
|
+
this.#logger.log('debug', 'Vite dev host has no marker to remove', {
|
|
241
|
+
marker,
|
|
242
|
+
reason: code ?? 'unreadable',
|
|
243
|
+
});
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
if (recorded === pid)
|
|
247
|
+
await rm(marker, { force: true });
|
|
248
|
+
}
|
|
249
|
+
}
|
package/dist/vite-dev.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { type IncomingMessage, type ServerResponse } from 'node:http';
|
|
1
|
+
import { type ClientRequest, type IncomingMessage, type ServerResponse } from 'node:http';
|
|
2
|
+
import type { Duplex } from 'node:stream';
|
|
2
3
|
import type { Logger } from '@dokebi/core';
|
|
3
4
|
export declare const viteDevRequested: () => boolean;
|
|
4
5
|
/** The part of a Node response the dev route finishes. */
|
|
@@ -14,6 +15,15 @@ export interface DevResponse {
|
|
|
14
15
|
export declare function viteFallthrough(response: DevResponse, error: unknown, report: (error: unknown) => void): void;
|
|
15
16
|
/** Header that carries the host key; the host answers no HTTP request without it. */
|
|
16
17
|
export declare const VITE_HOST_KEY_HEADER = "x-dokebi-vite-key";
|
|
18
|
+
/** Whether an upgrade request is Vite's client (its HMR or ping socket), by its subprotocol. */
|
|
19
|
+
export declare function isViteUpgrade(request: Pick<IncomingMessage, 'headers'>): boolean;
|
|
20
|
+
/** Default of `devDepsRepairIntervalMs` (D-0128). */
|
|
21
|
+
export declare const DEFAULT_DEPS_REPAIR_INTERVAL_MS = 10000;
|
|
22
|
+
/** Settings of the host from dokebi.yaml (`options.dokebi-template-inertia`). */
|
|
23
|
+
export interface ViteHostSettings {
|
|
24
|
+
/** Least time between two repairs of the pre-bundled dependencies in ms (D-0128). */
|
|
25
|
+
readonly depsRepairIntervalMs?: number;
|
|
26
|
+
}
|
|
17
27
|
/** The one Vite of a development session and the loopback port it answers on. */
|
|
18
28
|
export interface ViteHost {
|
|
19
29
|
/** Where clients reach the host: `http://127.0.0.1:<port>`. */
|
|
@@ -31,8 +41,19 @@ export interface ViteHost {
|
|
|
31
41
|
export interface ViteDev {
|
|
32
42
|
/** Answers a dev route request from the host (status, headers and body as Vite sent them). */
|
|
33
43
|
forward(request: IncomingMessage, response: ServerResponse, report: (error: unknown) => void): void;
|
|
34
|
-
/**
|
|
35
|
-
|
|
44
|
+
/**
|
|
45
|
+
* Loads `entry` (relative to the project root) through Vite and calls its `render(page)`. With
|
|
46
|
+
* `timeoutMs` (the scope's `ssr.timeoutMs`) the request to the host is cut at that deadline
|
|
47
|
+
* (`SSR_TIMEOUT`), so a render that never finishes does not keep a connection to the host.
|
|
48
|
+
*/
|
|
49
|
+
render(entry: string, page: unknown, timeoutMs?: number): Promise<unknown>;
|
|
50
|
+
/**
|
|
51
|
+
* Joins an HMR WebSocket upgrade that reached the app's port (`<base>` with subprotocol
|
|
52
|
+
* `vite-hmr`) to the host: the browser's handshake goes on as it came, Vite checks its token
|
|
53
|
+
* and answers, then bytes flow both ways until either side closes. So the browser needs only
|
|
54
|
+
* the page's own origin (a tunnel, a proxy), never the host's loopback port.
|
|
55
|
+
*/
|
|
56
|
+
upgrade(request: IncomingMessage, socket: Duplex, head: Buffer, report: (error: unknown) => void): void;
|
|
36
57
|
/** Releases this process's connections (and its own host, when it started one). */
|
|
37
58
|
close(): Promise<void>;
|
|
38
59
|
}
|
|
@@ -47,8 +68,25 @@ export interface ViteDev {
|
|
|
47
68
|
* - WebSocket upgrades of Vite's client (HMR): Vite answers them and keeps its token check
|
|
48
69
|
* (cross-site WebSocket hijacking). @dokebi/websocket answers every upgrade on the app's port,
|
|
49
70
|
* so HMR cannot share that one.
|
|
71
|
+
*
|
|
72
|
+
* Watcher events for files whose state did not change since Vite read them (FSEvents delivering
|
|
73
|
+
* writes from before the start, late) are dropped before Vite sees them (`vite-watch.ts`).
|
|
74
|
+
*
|
|
75
|
+
* The pre-bundled dependencies (node_modules/.vite/deps) are compared with what Vite serves at
|
|
76
|
+
* the start, whenever an app process connects (every app restart) and after a 504; when the
|
|
77
|
+
* folder changed under Vite, the host re-optimizes (`vite-deps.ts`, D-0128).
|
|
78
|
+
*/
|
|
79
|
+
export declare function startViteHost(logger: Logger, root?: string, settings?: ViteHostSettings): Promise<ViteHost>;
|
|
80
|
+
/**
|
|
81
|
+
* Destroys a request to the host without leaving a listener on a pooled connection. Node 24.15
|
|
82
|
+
* (`_http_client` onSocket, onSocketNT) adds the connection's 'error' listener when the agent
|
|
83
|
+
* hands it to a request and, when that request was destroyed while it waited in the agent's
|
|
84
|
+
* queue, puts the connection back in the pool with the listener still on it: one more per such
|
|
85
|
+
* request for as long as the keep-alive connection lives (audit r6: MaxListenersExceededWarning
|
|
86
|
+
* after renders cut at their deadline). A request without its connection yet is destroyed once
|
|
87
|
+
* it has one, which closes that connection instead.
|
|
50
88
|
*/
|
|
51
|
-
export declare function
|
|
89
|
+
export declare function destroyRequest(outgoing: ClientRequest, error?: Error): void;
|
|
52
90
|
/**
|
|
53
91
|
* Connects this process to a Vite host and checks that it answers with the key. Requests share
|
|
54
92
|
* keep-alive connections; `close` ends them (the host keeps running).
|