@weasel-js/forge 1.14.1 → 1.14.2
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/dist/vite/index.d.ts +18 -1
- package/dist/vite/index.js +138 -6
- package/dist/vite/index.js.map +1 -1
- package/package.json +11 -11
package/dist/vite/index.d.ts
CHANGED
|
@@ -61,4 +61,21 @@ interface WatchProbeOptions {
|
|
|
61
61
|
/** A plugin giving any dev server the warning forge's own gives when the OS reports no file changes. */
|
|
62
62
|
declare function watchProbe({ probe }?: WatchProbeOptions): Plugin;
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
/** Options for the `watchRecovery` vite plugin. */
|
|
65
|
+
interface WatchRecoveryOptions {
|
|
66
|
+
/**
|
|
67
|
+
* How long the watcher must have reported nothing before the served files are checked for changes it missed,
|
|
68
|
+
* and how often they are checked while it stays quiet, in milliseconds. Default 2000.
|
|
69
|
+
*/
|
|
70
|
+
quietMs?: number;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* A plugin that serves an edit the OS never reported. Each module vite serves from a file is stamped with the file's
|
|
74
|
+
* modification time when vite reads it. A request for a module whose file has changed since, and a check of every
|
|
75
|
+
* served file once the watcher has been quiet for `quietMs`, replays the missed change through vite's watcher: the
|
|
76
|
+
* module is transformed again and the open page gets the update, or a reload, as it would have from the event.
|
|
77
|
+
* Each recovery logs one line naming the file.
|
|
78
|
+
*/
|
|
79
|
+
declare function watchRecovery({ quietMs }?: WatchRecoveryOptions): Plugin;
|
|
80
|
+
|
|
81
|
+
export { type ForgeOptions, type ForgeTestOptions, type PropControlsOptions, type WatchProbeOptions, type WatchRecoveryOptions, forge, forgeTest, watchProbe, watchRecovery };
|
package/dist/vite/index.js
CHANGED
|
@@ -3,13 +3,14 @@ import { byComponent } from '../chunk-RVJHUY7W.js';
|
|
|
3
3
|
import { isGallery } from '../chunk-VUPN73JP.js';
|
|
4
4
|
import { PROP_ARG_TYPES_EXPORT, storyNameFromExport, storyId } from '../chunk-5WS67HMU.js';
|
|
5
5
|
import { readFileSync, mkdtempSync, existsSync, mkdirSync, writeFileSync, globSync, statSync, watch, rmSync } from 'fs';
|
|
6
|
-
import { resolve, relative, sep, join, dirname, basename, matchesGlob, posix } from 'path';
|
|
6
|
+
import { resolve, relative, sep, isAbsolute, join, dirname, basename, matchesGlob, posix } from 'path';
|
|
7
7
|
import { parse } from '@babel/parser';
|
|
8
8
|
import { execFile } from 'child_process';
|
|
9
9
|
import { fileURLToPath } from 'url';
|
|
10
10
|
import { createHash } from 'crypto';
|
|
11
11
|
import { stableStringify } from '@weasel-js/core/json';
|
|
12
12
|
import { tmpdir } from 'os';
|
|
13
|
+
import { normalizePath } from 'vite';
|
|
13
14
|
|
|
14
15
|
// src/vite/html.ts
|
|
15
16
|
var escaped = (text) => text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
@@ -1783,6 +1784,125 @@ ${lines.join("\n")}
|
|
|
1783
1784
|
"capture-frame-entry.js": () => captureFrameEntry(frameStyles())
|
|
1784
1785
|
};
|
|
1785
1786
|
}
|
|
1787
|
+
var WATCH_RECOVERY = "weasel-watch-recovery";
|
|
1788
|
+
var QUIET_MS = 2e3;
|
|
1789
|
+
var mtimeOf = (file) => {
|
|
1790
|
+
try {
|
|
1791
|
+
return statSync(file).mtimeMs;
|
|
1792
|
+
} catch {
|
|
1793
|
+
return void 0;
|
|
1794
|
+
}
|
|
1795
|
+
};
|
|
1796
|
+
var withoutQuery = (url) => url.replace(/[?#].*$/s, "");
|
|
1797
|
+
function watchRecovery({ quietMs = QUIET_MS } = {}) {
|
|
1798
|
+
const stamps = /* @__PURE__ */ new Map();
|
|
1799
|
+
const read = /* @__PURE__ */ new Map();
|
|
1800
|
+
const fileOfUrl = /* @__PURE__ */ new Map();
|
|
1801
|
+
let server;
|
|
1802
|
+
let active = false;
|
|
1803
|
+
let skipped = () => true;
|
|
1804
|
+
let lastEvent = 0;
|
|
1805
|
+
let replaying = false;
|
|
1806
|
+
let timer;
|
|
1807
|
+
const restamp = (file) => {
|
|
1808
|
+
const modules = stamps.get(file);
|
|
1809
|
+
const now = mtimeOf(file);
|
|
1810
|
+
if (!modules || now === void 0) return;
|
|
1811
|
+
for (const id of modules.keys()) modules.set(id, now);
|
|
1812
|
+
};
|
|
1813
|
+
const missed = (file) => {
|
|
1814
|
+
const modules = stamps.get(file);
|
|
1815
|
+
const now = mtimeOf(file);
|
|
1816
|
+
if (!modules || now === void 0) return false;
|
|
1817
|
+
for (const stamp of modules.values()) if (stamp !== now) return true;
|
|
1818
|
+
return false;
|
|
1819
|
+
};
|
|
1820
|
+
const recover = (file, outcome) => {
|
|
1821
|
+
if (!server) return;
|
|
1822
|
+
restamp(file);
|
|
1823
|
+
for (const environment of Object.values(server.environments)) environment.moduleGraph.onFileChange(file);
|
|
1824
|
+
server.config.logger.warn(`[watch] ${relative(server.config.root, file)} changed with no file event; ${outcome}`, {
|
|
1825
|
+
timestamp: true
|
|
1826
|
+
});
|
|
1827
|
+
replaying = true;
|
|
1828
|
+
try {
|
|
1829
|
+
server.watcher.emit("change", file);
|
|
1830
|
+
} finally {
|
|
1831
|
+
replaying = false;
|
|
1832
|
+
}
|
|
1833
|
+
};
|
|
1834
|
+
const sweep = () => {
|
|
1835
|
+
if (Date.now() - lastEvent < quietMs) return;
|
|
1836
|
+
for (const file of stamps.keys()) if (missed(file)) recover(file, "pushing it to the page");
|
|
1837
|
+
};
|
|
1838
|
+
const self = {
|
|
1839
|
+
name: WATCH_RECOVERY,
|
|
1840
|
+
apply: "serve",
|
|
1841
|
+
configResolved(config) {
|
|
1842
|
+
active = config.server.watch !== null && config.plugins.find((p) => p.name === WATCH_RECOVERY) === self;
|
|
1843
|
+
const cacheDir = normalizePath(config.cacheDir) + "/";
|
|
1844
|
+
skipped = (file) => !isAbsolute(file) || file.includes("/node_modules/") || file.startsWith(cacheDir);
|
|
1845
|
+
},
|
|
1846
|
+
configureServer(s) {
|
|
1847
|
+
if (!active) return;
|
|
1848
|
+
server = s;
|
|
1849
|
+
for (const event of ["add", "change", "unlink"]) {
|
|
1850
|
+
s.watcher.on(event, (path) => {
|
|
1851
|
+
if (replaying) return;
|
|
1852
|
+
lastEvent = Date.now();
|
|
1853
|
+
const file = normalizePath(path);
|
|
1854
|
+
if (event === "unlink") stamps.delete(file);
|
|
1855
|
+
else restamp(file);
|
|
1856
|
+
});
|
|
1857
|
+
}
|
|
1858
|
+
const base = s.config.base;
|
|
1859
|
+
s.middlewares.use(function weaselWatchRecovery(req, _res, next) {
|
|
1860
|
+
let url = withoutQuery(req.url ?? "");
|
|
1861
|
+
if (base !== "/" && url.startsWith(base)) url = url.slice(base.length - 1);
|
|
1862
|
+
let file;
|
|
1863
|
+
try {
|
|
1864
|
+
file = fileOfUrl.get(decodeURI(url));
|
|
1865
|
+
} catch {
|
|
1866
|
+
}
|
|
1867
|
+
if (file && missed(file)) recover(file, "serving the new text");
|
|
1868
|
+
next();
|
|
1869
|
+
});
|
|
1870
|
+
timer = setInterval(sweep, quietMs);
|
|
1871
|
+
timer.unref();
|
|
1872
|
+
},
|
|
1873
|
+
load: {
|
|
1874
|
+
order: "pre",
|
|
1875
|
+
handler(id) {
|
|
1876
|
+
if (!active || this.environment.name !== "client") return;
|
|
1877
|
+
const file = withoutQuery(id);
|
|
1878
|
+
if (skipped(file)) return;
|
|
1879
|
+
const mtime = mtimeOf(file);
|
|
1880
|
+
if (mtime !== void 0) read.set(id, mtime);
|
|
1881
|
+
}
|
|
1882
|
+
},
|
|
1883
|
+
transform: {
|
|
1884
|
+
order: "pre",
|
|
1885
|
+
handler(_code, id) {
|
|
1886
|
+
const mtime = read.get(id);
|
|
1887
|
+
if (mtime === void 0) return;
|
|
1888
|
+
read.delete(id);
|
|
1889
|
+
if (this.environment.mode !== "dev") return;
|
|
1890
|
+
const mod = this.environment.moduleGraph.getModuleById(id);
|
|
1891
|
+
if (!mod?.file) return;
|
|
1892
|
+
let modules = stamps.get(mod.file);
|
|
1893
|
+
if (!modules) stamps.set(mod.file, modules = /* @__PURE__ */ new Map());
|
|
1894
|
+
modules.set(id, mtime);
|
|
1895
|
+
fileOfUrl.set(withoutQuery(mod.url), mod.file);
|
|
1896
|
+
}
|
|
1897
|
+
},
|
|
1898
|
+
buildEnd() {
|
|
1899
|
+
clearInterval(timer);
|
|
1900
|
+
}
|
|
1901
|
+
};
|
|
1902
|
+
return self;
|
|
1903
|
+
}
|
|
1904
|
+
|
|
1905
|
+
// src/vite/watchProbe.ts
|
|
1786
1906
|
var WAIT_MS = 5e3;
|
|
1787
1907
|
var REWRITE_MS = 250;
|
|
1788
1908
|
var watchDir = (dir, onEvent) => {
|
|
@@ -1823,11 +1943,16 @@ function fileEventsArrive({ waitMs = WAIT_MS, watch = watchDir } = {}) {
|
|
|
1823
1943
|
deadline.unref();
|
|
1824
1944
|
});
|
|
1825
1945
|
}
|
|
1826
|
-
var
|
|
1946
|
+
var UNREPORTED = `[watch] a file written ${WAIT_MS / 1e3} s ago has not been reported by the OS file watcher, `;
|
|
1947
|
+
var FSEVENTSD = "On macOS, look for `fseventsd` held at 100% CPU.";
|
|
1948
|
+
var SILENT = UNREPORTED + "so an edit will not reach the page until file events arrive again. `server.watch: { usePolling: true }` serves edits without them, and so does the `watchRecovery()` plugin beside `watchProbe()`. " + FSEVENTSD;
|
|
1949
|
+
var RECOVERING = UNREPORTED + "so edits are found by their modification times instead: on the next request for the module, or within seconds once the watcher is quiet, each logged as it is served. " + FSEVENTSD;
|
|
1827
1950
|
async function warnWhenWatchIsSilent(server, probe = fileEventsArrive) {
|
|
1828
1951
|
const { watch } = server.config.server;
|
|
1829
1952
|
if (watch === null || watch?.usePolling) return;
|
|
1830
|
-
if (
|
|
1953
|
+
if (await probe()) return;
|
|
1954
|
+
const recovering = server.config.plugins.some((p) => p.name === WATCH_RECOVERY);
|
|
1955
|
+
server.config.logger.warn(recovering ? RECOVERING : SILENT);
|
|
1831
1956
|
}
|
|
1832
1957
|
function watchProbe({ probe } = {}) {
|
|
1833
1958
|
return {
|
|
@@ -1856,6 +1981,14 @@ function watchSources(server, { files, depGraph, reindex, redeps, logError }) {
|
|
|
1856
1981
|
});
|
|
1857
1982
|
}
|
|
1858
1983
|
}
|
|
1984
|
+
function companions(options, storyFiles) {
|
|
1985
|
+
const { storybookShims: shims, propControls: controls } = options;
|
|
1986
|
+
return [
|
|
1987
|
+
watchRecovery(),
|
|
1988
|
+
...shims === false ? [] : [storybookShims()],
|
|
1989
|
+
...controls === false ? [] : [propControls(storyFiles, controls === true ? void 0 : controls)]
|
|
1990
|
+
];
|
|
1991
|
+
}
|
|
1859
1992
|
function forge(options) {
|
|
1860
1993
|
let root = process.cwd();
|
|
1861
1994
|
let base = "/";
|
|
@@ -1994,8 +2127,7 @@ function forge(options) {
|
|
|
1994
2127
|
return true;
|
|
1995
2128
|
}
|
|
1996
2129
|
return [
|
|
1997
|
-
...options
|
|
1998
|
-
...options.propControls === false ? [] : [propControls(() => [...files().keys()], options.propControls === true ? void 0 : options.propControls)],
|
|
2130
|
+
...companions(options, () => [...files().keys()]),
|
|
1999
2131
|
{
|
|
2000
2132
|
name: "weaselforge",
|
|
2001
2133
|
config(config, { command }) {
|
|
@@ -2121,6 +2253,6 @@ ${lines.join("\n")}
|
|
|
2121
2253
|
];
|
|
2122
2254
|
}
|
|
2123
2255
|
|
|
2124
|
-
export { forge, forgeTest, watchProbe };
|
|
2256
|
+
export { forge, forgeTest, watchProbe, watchRecovery };
|
|
2125
2257
|
//# sourceMappingURL=index.js.map
|
|
2126
2258
|
//# sourceMappingURL=index.js.map
|