frizz 0.1.0 → 0.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.
- package/README.md +121 -63
- package/dist/dev-child.js +631 -502
- package/dist/frizz.js +191 -66
- package/package.json +1 -1
package/dist/frizz.js
CHANGED
|
@@ -1803,6 +1803,131 @@ var init_migrate_fray = __esm({
|
|
|
1803
1803
|
}
|
|
1804
1804
|
});
|
|
1805
1805
|
|
|
1806
|
+
// packages/server/src/project-root.ts
|
|
1807
|
+
import { createHash as createHash3, randomUUID as randomUUID4 } from "node:crypto";
|
|
1808
|
+
import { closeSync as closeSync3, existsSync as existsSync3, fsyncSync as fsyncSync3, mkdirSync as mkdirSync5, openSync as openSync4, readFileSync as readFileSync5, renameSync as renameSync5, rmSync as rmSync5, writeFileSync as writeFileSync5 } from "node:fs";
|
|
1809
|
+
import { homedir as homedir6 } from "node:os";
|
|
1810
|
+
import { dirname as dirname4, join as join8, parse, resolve as resolve3 } from "node:path";
|
|
1811
|
+
function projectIdPath(root) {
|
|
1812
|
+
return join8(root, FRIZZ_DIR, ID_FILE);
|
|
1813
|
+
}
|
|
1814
|
+
function readProjectIdFile(root) {
|
|
1815
|
+
let raw;
|
|
1816
|
+
try {
|
|
1817
|
+
raw = readFileSync5(projectIdPath(root), "utf8");
|
|
1818
|
+
} catch {
|
|
1819
|
+
return void 0;
|
|
1820
|
+
}
|
|
1821
|
+
try {
|
|
1822
|
+
return validateProjectId(raw.trim());
|
|
1823
|
+
} catch {
|
|
1824
|
+
throw new Error(`${projectIdPath(root)} is invalid; expected exactly one UUID`);
|
|
1825
|
+
}
|
|
1826
|
+
}
|
|
1827
|
+
function writeProjectIdFile(root, id) {
|
|
1828
|
+
const dir = join8(root, FRIZZ_DIR);
|
|
1829
|
+
mkdirSync5(dir, { recursive: true });
|
|
1830
|
+
const ignore = join8(dir, SELF_IGNORE);
|
|
1831
|
+
if (!existsSync3(ignore)) {
|
|
1832
|
+
try {
|
|
1833
|
+
writeFileSync5(ignore, "*\n", { flag: "wx" });
|
|
1834
|
+
} catch {
|
|
1835
|
+
}
|
|
1836
|
+
}
|
|
1837
|
+
const path = projectIdPath(root);
|
|
1838
|
+
const temp = join8(dir, `.${ID_FILE}.${process.pid}.${randomUUID4()}.tmp`);
|
|
1839
|
+
let fd;
|
|
1840
|
+
try {
|
|
1841
|
+
fd = openSync4(temp, "wx", 384);
|
|
1842
|
+
writeFileSync5(fd, `${id}
|
|
1843
|
+
`, "utf8");
|
|
1844
|
+
fsyncSync3(fd);
|
|
1845
|
+
closeSync3(fd);
|
|
1846
|
+
fd = void 0;
|
|
1847
|
+
renameSync5(temp, path);
|
|
1848
|
+
} catch (error) {
|
|
1849
|
+
if (fd !== void 0) {
|
|
1850
|
+
try {
|
|
1851
|
+
closeSync3(fd);
|
|
1852
|
+
} catch {
|
|
1853
|
+
}
|
|
1854
|
+
}
|
|
1855
|
+
try {
|
|
1856
|
+
rmSync5(temp, { force: true });
|
|
1857
|
+
} catch {
|
|
1858
|
+
}
|
|
1859
|
+
throw error;
|
|
1860
|
+
}
|
|
1861
|
+
return id;
|
|
1862
|
+
}
|
|
1863
|
+
function projectRootLockName(root) {
|
|
1864
|
+
return `identity-path-${createHash3("sha256").update(root).digest("hex")}.lock`;
|
|
1865
|
+
}
|
|
1866
|
+
function ensureProjectIdFile(root, home = homedir6(), seed) {
|
|
1867
|
+
const existing = readProjectIdFile(root);
|
|
1868
|
+
if (existing) return existing;
|
|
1869
|
+
const release = acquireNamedLaunchLockSync(home, projectRootLockName(root));
|
|
1870
|
+
try {
|
|
1871
|
+
const raced = readProjectIdFile(root);
|
|
1872
|
+
if (raced) return raced;
|
|
1873
|
+
return writeProjectIdFile(root, seed ? validateProjectId(seed) : randomUUID4());
|
|
1874
|
+
} finally {
|
|
1875
|
+
release();
|
|
1876
|
+
}
|
|
1877
|
+
}
|
|
1878
|
+
function isNotAGitWorktree(error) {
|
|
1879
|
+
const code = error?.code;
|
|
1880
|
+
if (code === "ENOENT" || code === "EACCES") return true;
|
|
1881
|
+
if (!error || typeof error !== "object" || !("stderr" in error)) return false;
|
|
1882
|
+
const stderr = String(error.stderr);
|
|
1883
|
+
return /not a git repository/iu.test(stderr) || /must be run in a work ?tree/iu.test(stderr);
|
|
1884
|
+
}
|
|
1885
|
+
function hasAny(dir, names) {
|
|
1886
|
+
return names.some((name) => existsSync3(join8(dir, name)));
|
|
1887
|
+
}
|
|
1888
|
+
function discoverProjectRoot(cwd = process.cwd(), home = homedir6()) {
|
|
1889
|
+
let dir;
|
|
1890
|
+
try {
|
|
1891
|
+
dir = resolve3(cwd);
|
|
1892
|
+
} catch {
|
|
1893
|
+
return resolve3(cwd);
|
|
1894
|
+
}
|
|
1895
|
+
const stop = resolve3(home);
|
|
1896
|
+
const filesystemRoot = parse(dir).root;
|
|
1897
|
+
for (let at = dir; ; at = dirname4(at)) {
|
|
1898
|
+
if (at === stop || at === filesystemRoot) break;
|
|
1899
|
+
if (existsSync3(projectIdPath(at))) return at;
|
|
1900
|
+
if (hasAny(at, REPO_MARKERS)) return at;
|
|
1901
|
+
if (hasAny(at, PROJECT_MARKERS)) return at;
|
|
1902
|
+
if (dirname4(at) === at) break;
|
|
1903
|
+
}
|
|
1904
|
+
return dir;
|
|
1905
|
+
}
|
|
1906
|
+
var FRIZZ_DIR, ID_FILE, SELF_IGNORE, REPO_MARKERS, PROJECT_MARKERS;
|
|
1907
|
+
var init_project_root = __esm({
|
|
1908
|
+
"packages/server/src/project-root.ts"() {
|
|
1909
|
+
"use strict";
|
|
1910
|
+
init_project_identity();
|
|
1911
|
+
FRIZZ_DIR = ".frizz";
|
|
1912
|
+
ID_FILE = ".id";
|
|
1913
|
+
SELF_IGNORE = ".gitignore";
|
|
1914
|
+
REPO_MARKERS = [".git", ".jj", ".hg", ".svn"];
|
|
1915
|
+
PROJECT_MARKERS = [
|
|
1916
|
+
"package.json",
|
|
1917
|
+
"pyproject.toml",
|
|
1918
|
+
"go.mod",
|
|
1919
|
+
"Cargo.toml",
|
|
1920
|
+
"deno.json",
|
|
1921
|
+
"deno.jsonc",
|
|
1922
|
+
"composer.json",
|
|
1923
|
+
"Gemfile",
|
|
1924
|
+
"pom.xml",
|
|
1925
|
+
"build.gradle",
|
|
1926
|
+
"Makefile"
|
|
1927
|
+
];
|
|
1928
|
+
}
|
|
1929
|
+
});
|
|
1930
|
+
|
|
1806
1931
|
// node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/util.js
|
|
1807
1932
|
var util, objectUtil, ZodParsedType, getParsedType;
|
|
1808
1933
|
var init_util = __esm({
|
|
@@ -7752,7 +7877,7 @@ ${DISPATCH_TASK_BANNER}
|
|
|
7752
7877
|
});
|
|
7753
7878
|
|
|
7754
7879
|
// packages/server/src/local-image.ts
|
|
7755
|
-
import { readFileSync as
|
|
7880
|
+
import { readFileSync as readFileSync7, realpathSync as realpathSync4, statSync as statSync4 } from "node:fs";
|
|
7756
7881
|
import { extname, isAbsolute as isAbsolute2 } from "node:path";
|
|
7757
7882
|
function resolveLocalImage(rawPath) {
|
|
7758
7883
|
if (!rawPath || !isAbsolute2(rawPath)) return { status: 400 };
|
|
@@ -7766,7 +7891,7 @@ function resolveLocalImage(rawPath) {
|
|
|
7766
7891
|
}
|
|
7767
7892
|
try {
|
|
7768
7893
|
if (!statSync4(real).isFile()) return { status: 404 };
|
|
7769
|
-
return { status: 200, contentType, body:
|
|
7894
|
+
return { status: 200, contentType, body: readFileSync7(real) };
|
|
7770
7895
|
} catch {
|
|
7771
7896
|
return { status: 404 };
|
|
7772
7897
|
}
|
|
@@ -7786,10 +7911,10 @@ var init_local_image = __esm({
|
|
|
7786
7911
|
});
|
|
7787
7912
|
|
|
7788
7913
|
// src/production.ts
|
|
7789
|
-
import { readFileSync as
|
|
7790
|
-
import { homedir as
|
|
7914
|
+
import { readFileSync as readFileSync9 } from "node:fs";
|
|
7915
|
+
import { homedir as homedir8 } from "node:os";
|
|
7791
7916
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
7792
|
-
import { join as
|
|
7917
|
+
import { join as join11 } from "node:path";
|
|
7793
7918
|
|
|
7794
7919
|
// src/browser.ts
|
|
7795
7920
|
import { spawn, execFile } from "node:child_process";
|
|
@@ -7951,12 +8076,12 @@ function manifestIdFor(url) {
|
|
|
7951
8076
|
return url.endsWith("/") ? url : `${url}/`;
|
|
7952
8077
|
}
|
|
7953
8078
|
function execFileP(cmd, args2) {
|
|
7954
|
-
return new Promise((
|
|
8079
|
+
return new Promise((resolve6, reject) => {
|
|
7955
8080
|
execFile(
|
|
7956
8081
|
cmd,
|
|
7957
8082
|
args2,
|
|
7958
8083
|
{ encoding: "utf8", timeout: 1e4 },
|
|
7959
|
-
(err, stdout) => err ? reject(err) :
|
|
8084
|
+
(err, stdout) => err ? reject(err) : resolve6(stdout)
|
|
7960
8085
|
);
|
|
7961
8086
|
});
|
|
7962
8087
|
}
|
|
@@ -8035,9 +8160,9 @@ function openCdpSession(browserPath, dataPath) {
|
|
|
8035
8160
|
cmdPipe.on("error", failAll);
|
|
8036
8161
|
resPipe.on("error", failAll);
|
|
8037
8162
|
child.on("exit", () => failAll(new Error("chrome exited before the CDP handshake completed")));
|
|
8038
|
-
const call = (method, params = {}, timeoutMs = 2e4) => new Promise((
|
|
8163
|
+
const call = (method, params = {}, timeoutMs = 2e4) => new Promise((resolve6, reject) => {
|
|
8039
8164
|
const id = ++seq;
|
|
8040
|
-
pending.set(id, { resolve:
|
|
8165
|
+
pending.set(id, { resolve: resolve6, reject });
|
|
8041
8166
|
cmdPipe.write(JSON.stringify({ id, method, params }) + "\0");
|
|
8042
8167
|
setTimeout(() => {
|
|
8043
8168
|
if (pending.has(id)) {
|
|
@@ -8050,15 +8175,15 @@ function openCdpSession(browserPath, dataPath) {
|
|
|
8050
8175
|
await call("Browser.close").catch(() => {
|
|
8051
8176
|
});
|
|
8052
8177
|
if (child.exitCode !== null || child.signalCode !== null) return;
|
|
8053
|
-
await new Promise((
|
|
8178
|
+
await new Promise((resolve6) => {
|
|
8054
8179
|
const t = setTimeout(() => {
|
|
8055
8180
|
child.kill();
|
|
8056
|
-
|
|
8181
|
+
resolve6();
|
|
8057
8182
|
}, 1e4);
|
|
8058
8183
|
t.unref();
|
|
8059
8184
|
child.once("exit", () => {
|
|
8060
8185
|
clearTimeout(t);
|
|
8061
|
-
|
|
8186
|
+
resolve6();
|
|
8062
8187
|
});
|
|
8063
8188
|
});
|
|
8064
8189
|
};
|
|
@@ -8537,13 +8662,14 @@ init_local_origin();
|
|
|
8537
8662
|
init_boot_progress();
|
|
8538
8663
|
init_frizz_paths();
|
|
8539
8664
|
init_migrate_fray();
|
|
8665
|
+
init_project_root();
|
|
8540
8666
|
init_logging();
|
|
8541
8667
|
init_src();
|
|
8542
8668
|
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
8543
8669
|
import { createServer } from "node:net";
|
|
8544
|
-
import { mkdirSync as
|
|
8545
|
-
import { homedir as
|
|
8546
|
-
import { basename as basename4, join as
|
|
8670
|
+
import { mkdirSync as mkdirSync6, readFileSync as readFileSync6, realpathSync as realpathSync3, writeFileSync as writeFileSync6 } from "node:fs";
|
|
8671
|
+
import { homedir as homedir7, networkInterfaces } from "node:os";
|
|
8672
|
+
import { basename as basename4, join as join9, resolve as resolve4 } from "node:path";
|
|
8547
8673
|
import { setTimeout as delay2 } from "node:timers/promises";
|
|
8548
8674
|
var PORT_SCAN_COUNT = 100;
|
|
8549
8675
|
var LAUNCH_TIMEOUT_MS = 3e4;
|
|
@@ -8711,40 +8837,41 @@ function networkUrls(port, host, interfaces = networkInterfaces) {
|
|
|
8711
8837
|
}
|
|
8712
8838
|
return urls;
|
|
8713
8839
|
}
|
|
8714
|
-
function resolveWorkspace(cwd = process.cwd(), home =
|
|
8840
|
+
function resolveWorkspace(cwd = process.cwd(), home = homedir7(), env = process.env, { migrate = false } = {}) {
|
|
8715
8841
|
let gitRoot;
|
|
8716
8842
|
try {
|
|
8717
8843
|
gitRoot = execFileSync4("git", ["rev-parse", "--show-toplevel"], {
|
|
8718
8844
|
cwd,
|
|
8719
8845
|
encoding: "utf8",
|
|
8720
|
-
|
|
8846
|
+
// stderr is CAPTURED, not ignored: it is the only thing that distinguishes "no worktree here"
|
|
8847
|
+
// from "this repository is broken", and those two must not be handled the same way.
|
|
8848
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
8721
8849
|
}).trim();
|
|
8722
|
-
} catch {
|
|
8723
|
-
throw new Error(
|
|
8724
|
-
|
|
8725
|
-
);
|
|
8850
|
+
} catch (error) {
|
|
8851
|
+
if (!isNotAGitWorktree(error)) throw new Error("unable to resolve Git repository root");
|
|
8852
|
+
gitRoot = void 0;
|
|
8726
8853
|
}
|
|
8727
8854
|
if (migrate) migrateFrayGlobalRoots({ env, home });
|
|
8728
|
-
const root0 = realpathSync3(gitRoot);
|
|
8855
|
+
const root0 = realpathSync3(gitRoot ?? discoverProjectRoot(cwd, home));
|
|
8729
8856
|
if (migrate) migrateFrayProjectId(root0, { home });
|
|
8730
|
-
const identity = resolveGitProjectIdentity(root0, home);
|
|
8731
|
-
const root = identity
|
|
8857
|
+
const identity = gitRoot ? resolveGitProjectIdentity(root0, home) : void 0;
|
|
8858
|
+
const root = identity?.root ?? root0;
|
|
8732
8859
|
if (migrate) migrateFrayProjectDir(root);
|
|
8733
|
-
const id = identity
|
|
8860
|
+
const id = ensureProjectIdFile(root, home, identity?.id);
|
|
8734
8861
|
const stateDir = projectStateDir(id, home);
|
|
8735
|
-
|
|
8862
|
+
mkdirSync6(stateDir, { recursive: true });
|
|
8736
8863
|
const target2 = {
|
|
8737
8864
|
projectId: id,
|
|
8738
8865
|
projectDir: root,
|
|
8739
8866
|
stateDir,
|
|
8740
|
-
...identity
|
|
8867
|
+
...identity?.scope === "worktree" ? { identityScope: "worktree" } : {}
|
|
8741
8868
|
};
|
|
8742
8869
|
return {
|
|
8743
8870
|
root,
|
|
8744
8871
|
id,
|
|
8745
8872
|
stateDir,
|
|
8746
8873
|
name: basename4(root),
|
|
8747
|
-
identityScope: identity
|
|
8874
|
+
identityScope: identity?.scope ?? "repository"
|
|
8748
8875
|
};
|
|
8749
8876
|
}
|
|
8750
8877
|
function workspaceLaunchTarget(workspace2) {
|
|
@@ -8775,7 +8902,7 @@ function workspaceFromLaunchTarget(target2, env = process.env) {
|
|
|
8775
8902
|
function parseStatusFile(path, authoritative, expected2, adapter = defaultProcessPlatformAdapter) {
|
|
8776
8903
|
try {
|
|
8777
8904
|
const value = JSON.parse(
|
|
8778
|
-
|
|
8905
|
+
readFileSync6(path, "utf8")
|
|
8779
8906
|
);
|
|
8780
8907
|
if (!Number.isInteger(value.pid) || value.pid <= 0 || !Number.isInteger(value.port) || value.port < 1 || value.port > 65535)
|
|
8781
8908
|
return null;
|
|
@@ -8803,12 +8930,12 @@ function liveWorkspaceOwner(stateDir, expected2, adapter = defaultProcessPlatfor
|
|
|
8803
8930
|
if (authoritative && processGenerationIsStale(authoritative, adapter))
|
|
8804
8931
|
return null;
|
|
8805
8932
|
return parseStatusFile(
|
|
8806
|
-
|
|
8933
|
+
join9(stateDir, "dev-supervisor.lock"),
|
|
8807
8934
|
authoritative,
|
|
8808
8935
|
expected2,
|
|
8809
8936
|
adapter
|
|
8810
8937
|
) ?? parseStatusFile(
|
|
8811
|
-
|
|
8938
|
+
join9(stateDir, "server.lock"),
|
|
8812
8939
|
authoritative,
|
|
8813
8940
|
expected2,
|
|
8814
8941
|
adapter
|
|
@@ -8817,7 +8944,7 @@ function liveWorkspaceOwner(stateDir, expected2, adapter = defaultProcessPlatfor
|
|
|
8817
8944
|
function readPreferredPort(stateDir) {
|
|
8818
8945
|
try {
|
|
8819
8946
|
const value = JSON.parse(
|
|
8820
|
-
|
|
8947
|
+
readFileSync6(join9(stateDir, "launcher.json"), "utf8")
|
|
8821
8948
|
);
|
|
8822
8949
|
return Number.isInteger(value.port) && value.port > 0 && value.port <= 65535 ? value.port : void 0;
|
|
8823
8950
|
} catch {
|
|
@@ -8931,10 +9058,10 @@ init_project_launch();
|
|
|
8931
9058
|
// packages/server/src/dev-supervisor.ts
|
|
8932
9059
|
init_project_launch();
|
|
8933
9060
|
import { fork } from "node:child_process";
|
|
8934
|
-
import { randomUUID as
|
|
8935
|
-
import { existsSync as
|
|
9061
|
+
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
9062
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync7, readFileSync as readFileSync8 } from "node:fs";
|
|
8936
9063
|
import { createServer as createNetServer } from "node:net";
|
|
8937
|
-
import { basename as basename5, dirname as
|
|
9064
|
+
import { basename as basename5, dirname as dirname5, extname as extname2, isAbsolute as isAbsolute3, relative, resolve as resolve5, sep as sep2 } from "node:path";
|
|
8938
9065
|
import { fileURLToPath } from "node:url";
|
|
8939
9066
|
import watcher from "@parcel/watcher";
|
|
8940
9067
|
|
|
@@ -9309,8 +9436,8 @@ function createSupervisorShutdownHandler(options2) {
|
|
|
9309
9436
|
);
|
|
9310
9437
|
};
|
|
9311
9438
|
}
|
|
9312
|
-
var packagesDir =
|
|
9313
|
-
var workspaceDir =
|
|
9439
|
+
var packagesDir = resolve5(import.meta.dirname, "..", "..");
|
|
9440
|
+
var workspaceDir = resolve5(packagesDir, "..");
|
|
9314
9441
|
var INITIAL_BOOT_REASON = "initial boot";
|
|
9315
9442
|
function defaultDevWatchRoots() {
|
|
9316
9443
|
return [workspaceDir];
|
|
@@ -9320,17 +9447,17 @@ function isWithin(path, root) {
|
|
|
9320
9447
|
return rel === "" || rel !== ".." && !rel.startsWith(`..${sep2}`) && !isAbsolute3(rel);
|
|
9321
9448
|
}
|
|
9322
9449
|
function ignoredDevPath(path) {
|
|
9323
|
-
const parts =
|
|
9450
|
+
const parts = resolve5(path).split(sep2);
|
|
9324
9451
|
const name = parts.at(-1) ?? "";
|
|
9325
9452
|
return parts.some((part) => GENERATED_DIRS.has(part) || part === "fixtures" || part.endsWith(".fixtures")) || /\.(?:test|spec)\.[^.]+$/.test(name) || name.includes(".golden.");
|
|
9326
9453
|
}
|
|
9327
9454
|
function classifyDevChange(path, roots = defaultDevWatchRoots()) {
|
|
9328
|
-
const absolute =
|
|
9329
|
-
const root = roots.find((candidate) => isWithin(absolute,
|
|
9455
|
+
const absolute = resolve5(path);
|
|
9456
|
+
const root = roots.find((candidate) => isWithin(absolute, resolve5(candidate)));
|
|
9330
9457
|
if (!root) return null;
|
|
9331
9458
|
if (ignoredDevPath(absolute)) return null;
|
|
9332
9459
|
const name = basename5(absolute);
|
|
9333
|
-
const relToWorkspace = relative(
|
|
9460
|
+
const relToWorkspace = relative(resolve5(root), absolute);
|
|
9334
9461
|
const parts = relToWorkspace.split(sep2);
|
|
9335
9462
|
const packageName = parts[0] === "packages" ? parts[1] : void 0;
|
|
9336
9463
|
if (name === "package.json" && parts.length === 3 && packageName && CHILD_PACKAGE_METADATA.has(packageName)) {
|
|
@@ -9356,7 +9483,7 @@ function devConfigSyntaxError(path) {
|
|
|
9356
9483
|
if (name !== "package.json" && !isTsconfig) return null;
|
|
9357
9484
|
let text;
|
|
9358
9485
|
try {
|
|
9359
|
-
text =
|
|
9486
|
+
text = readFileSync8(path, "utf8");
|
|
9360
9487
|
} catch (err) {
|
|
9361
9488
|
return `${name}: ${err instanceof Error ? err.message : err}`;
|
|
9362
9489
|
}
|
|
@@ -9452,7 +9579,7 @@ var Supervisor = class {
|
|
|
9452
9579
|
watchSubscribe;
|
|
9453
9580
|
reexec;
|
|
9454
9581
|
supervisorLock;
|
|
9455
|
-
statusPublisherToken =
|
|
9582
|
+
statusPublisherToken = randomUUID5();
|
|
9456
9583
|
processGeneration = currentProcessGeneration();
|
|
9457
9584
|
ownerToken;
|
|
9458
9585
|
launchTarget;
|
|
@@ -9471,10 +9598,10 @@ var Supervisor = class {
|
|
|
9471
9598
|
if (launchOwner.pid !== callerGeneration.pid || launchOwner.processStart !== callerGeneration.processStart) throw new Error("dev supervisor caller is not the exact project launch owner");
|
|
9472
9599
|
this.port = opts.port;
|
|
9473
9600
|
this.launchTarget = opts.launchTarget;
|
|
9474
|
-
this.cwd =
|
|
9601
|
+
this.cwd = resolve5(opts.cwd ?? opts.launchTarget.projectDir);
|
|
9475
9602
|
if (this.cwd !== opts.launchTarget.projectDir) throw new Error("dev supervisor cwd does not match its owned project");
|
|
9476
9603
|
this.parentEnv = projectLaunchEnvironment(opts.env ?? process.env, opts.launchTarget, opts.launchOwnerToken);
|
|
9477
|
-
this.roots = (opts.watchRoots ?? defaultDevWatchRoots()).map((root) =>
|
|
9604
|
+
this.roots = (opts.watchRoots ?? defaultDevWatchRoots()).map((root) => resolve5(root));
|
|
9478
9605
|
this.watchEnabled = opts.watch !== false;
|
|
9479
9606
|
this.childEnvironment = opts.childEnvironment ?? (() => ({}));
|
|
9480
9607
|
this.debounceMs = opts.debounceMs ?? DEV_RESTART_DEBOUNCE_MS;
|
|
@@ -9484,10 +9611,10 @@ var Supervisor = class {
|
|
|
9484
9611
|
this.childArgs = opts.childArgs ?? [];
|
|
9485
9612
|
this.watchSubscribe = opts.watchSubscribe ?? ((root, callback, options2) => watcher.subscribe(root, callback, options2));
|
|
9486
9613
|
this.reexec = opts.reexec ?? (typeof process.execve === "function" ? (request) => process.execve(request.executable, request.argv, request.env) : void 0);
|
|
9487
|
-
if (opts.stateDir &&
|
|
9614
|
+
if (opts.stateDir && resolve5(opts.stateDir) !== opts.launchTarget.stateDir) {
|
|
9488
9615
|
throw new Error("dev supervisor state directory does not match its owned project");
|
|
9489
9616
|
}
|
|
9490
|
-
this.supervisorLock =
|
|
9617
|
+
this.supervisorLock = resolve5(opts.launchTarget.stateDir, "dev-supervisor.lock");
|
|
9491
9618
|
this.ownerToken = opts.launchOwnerToken;
|
|
9492
9619
|
this.logLine = opts.log ?? ((line) => log.info("supervisor", stripPrefix(line)));
|
|
9493
9620
|
this.errorLine = opts.error ?? ((line) => log.error("supervisor", stripPrefix(line)));
|
|
@@ -9523,14 +9650,14 @@ var Supervisor = class {
|
|
|
9523
9650
|
}
|
|
9524
9651
|
async start() {
|
|
9525
9652
|
if (this.supervisorLock) {
|
|
9526
|
-
|
|
9653
|
+
mkdirSync7(dirname5(this.supervisorLock), { recursive: true });
|
|
9527
9654
|
this.writeStatus("starting", "watcher initializing");
|
|
9528
9655
|
}
|
|
9529
9656
|
try {
|
|
9530
9657
|
await this.publicProxy.listen();
|
|
9531
9658
|
if (this.watchEnabled) {
|
|
9532
9659
|
const settled = await Promise.allSettled(
|
|
9533
|
-
this.roots.filter(
|
|
9660
|
+
this.roots.filter(existsSync4).map((root) => this.watchSubscribe(root, (err, events) => this.onWatch(err, events), {
|
|
9534
9661
|
ignore: DEV_WATCH_IGNORE
|
|
9535
9662
|
}))
|
|
9536
9663
|
);
|
|
@@ -9948,13 +10075,13 @@ async function startDevSupervisor(opts) {
|
|
|
9948
10075
|
import { execFile as execFile2, spawn as spawn2 } from "node:child_process";
|
|
9949
10076
|
var PRODUCTION_REEXEC_FLAG = "--_frizz-production-reexec";
|
|
9950
10077
|
function compareReleaseVersions(a, b) {
|
|
9951
|
-
const
|
|
10078
|
+
const parse2 = (value) => {
|
|
9952
10079
|
const match = /^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/u.exec(value);
|
|
9953
10080
|
if (!match) return null;
|
|
9954
10081
|
return { numeric: [Number(match[1]), Number(match[2]), Number(match[3])], prerelease: match[4] };
|
|
9955
10082
|
};
|
|
9956
|
-
const left =
|
|
9957
|
-
const right =
|
|
10083
|
+
const left = parse2(a);
|
|
10084
|
+
const right = parse2(b);
|
|
9958
10085
|
if (!left || !right) return null;
|
|
9959
10086
|
for (let index = 0; index < left.numeric.length; index++) {
|
|
9960
10087
|
const delta = left.numeric[index] - right.numeric[index];
|
|
@@ -10019,7 +10146,7 @@ var npmRegistryReleaseAdapter = {
|
|
|
10019
10146
|
import { spawnSync } from "node:child_process";
|
|
10020
10147
|
import { chmodSync, statSync as statSync5 } from "node:fs";
|
|
10021
10148
|
import { createRequire as createRequire2 } from "node:module";
|
|
10022
|
-
import { dirname as
|
|
10149
|
+
import { dirname as dirname6, join as join10 } from "node:path";
|
|
10023
10150
|
var SUPPORTED_NODE_LINES = [
|
|
10024
10151
|
{ major: 22, minor: 13 },
|
|
10025
10152
|
{ major: 23, minor: 4 }
|
|
@@ -10037,9 +10164,7 @@ function nodeVersionIsSupported(major, minor) {
|
|
|
10037
10164
|
if (line) return minor >= line.minor;
|
|
10038
10165
|
return major > SUPPORTED_NODE_LINES[SUPPORTED_NODE_LINES.length - 1].major;
|
|
10039
10166
|
}
|
|
10040
|
-
var REQUIRED_EXECUTABLES = [
|
|
10041
|
-
{ name: "git", need: "Frizz identifies a project by its Git repository" }
|
|
10042
|
-
];
|
|
10167
|
+
var REQUIRED_EXECUTABLES = [];
|
|
10043
10168
|
function assertRequiredExecutables(command = commandIsAvailable) {
|
|
10044
10169
|
for (const { name, need } of REQUIRED_EXECUTABLES) {
|
|
10045
10170
|
if (command(name)) continue;
|
|
@@ -10072,8 +10197,8 @@ function ensureNativeHelperPermissions(options2 = {}) {
|
|
|
10072
10197
|
const chmod = options2.chmod ?? ((path, mode) => chmodSync(path, mode));
|
|
10073
10198
|
const resolvePty = options2.resolvePty ?? (() => createRequire2(import.meta.url).resolve("node-pty/package.json"));
|
|
10074
10199
|
try {
|
|
10075
|
-
const helper =
|
|
10076
|
-
|
|
10200
|
+
const helper = join10(
|
|
10201
|
+
dirname6(resolvePty()),
|
|
10077
10202
|
"prebuilds",
|
|
10078
10203
|
`${platform}-${options2.arch ?? process.arch}`,
|
|
10079
10204
|
"spawn-helper"
|
|
@@ -10089,7 +10214,7 @@ function ensureNativeHelperPermissions(options2 = {}) {
|
|
|
10089
10214
|
var PACKAGE_NAME = process.env.FRIZZ_REGISTRY_PACKAGE ?? "frizz";
|
|
10090
10215
|
function resolvePackageVersion() {
|
|
10091
10216
|
try {
|
|
10092
|
-
const manifest = JSON.parse(
|
|
10217
|
+
const manifest = JSON.parse(readFileSync9(join11(import.meta.dirname, "..", "package.json"), "utf8"));
|
|
10093
10218
|
if (typeof manifest.version === "string" && manifest.version.trim()) return manifest.version.trim();
|
|
10094
10219
|
} catch {
|
|
10095
10220
|
}
|
|
@@ -10197,7 +10322,7 @@ async function openOrPrint(port, reused) {
|
|
|
10197
10322
|
readout?.begin("browser", options.appMode ? "requesting app window" : "requesting default browser");
|
|
10198
10323
|
try {
|
|
10199
10324
|
if (options.appMode) {
|
|
10200
|
-
await launchApp(url, { dataPath:
|
|
10325
|
+
await launchApp(url, { dataPath: join11(workspace.stateDir, "browser-profile") });
|
|
10201
10326
|
browser = reused ? "focused the Frizz app window" : "opened the Frizz app window";
|
|
10202
10327
|
} else {
|
|
10203
10328
|
await launchBrowserTab(url);
|
|
@@ -10226,7 +10351,7 @@ async function openOrPrint(port, reused) {
|
|
|
10226
10351
|
for (const warning of warnings) console.log(warning);
|
|
10227
10352
|
return;
|
|
10228
10353
|
}
|
|
10229
|
-
const home =
|
|
10354
|
+
const home = homedir8();
|
|
10230
10355
|
readout.ready(
|
|
10231
10356
|
[
|
|
10232
10357
|
{ label: "Local", value: `${url}/`, accent: true },
|
|
@@ -10259,10 +10384,10 @@ async function runSupervisor(port, token) {
|
|
|
10259
10384
|
target,
|
|
10260
10385
|
owner.token
|
|
10261
10386
|
);
|
|
10262
|
-
const webDist =
|
|
10263
|
-
const runtimeDir =
|
|
10264
|
-
const scriptsDir =
|
|
10265
|
-
const workerPluginDir =
|
|
10387
|
+
const webDist = join11(import.meta.dirname, "..", "web-dist");
|
|
10388
|
+
const runtimeDir = join11(import.meta.dirname, "..", "runtime");
|
|
10389
|
+
const scriptsDir = join11(runtimeDir, "board");
|
|
10390
|
+
const workerPluginDir = join11(runtimeDir, "cc-worker");
|
|
10266
10391
|
const childEntry = fileURLToPath2(new URL("./dev-child.js", import.meta.url));
|
|
10267
10392
|
let plannedUpdate;
|
|
10268
10393
|
let updateAvailable = true;
|
|
@@ -10316,7 +10441,7 @@ async function runSupervisor(port, token) {
|
|
|
10316
10441
|
exit: (code) => {
|
|
10317
10442
|
logger.info("launcher", `stopped with code ${code}`);
|
|
10318
10443
|
const suffix = logger.file ? `
|
|
10319
|
-
log: ${tildePath(logger.file,
|
|
10444
|
+
log: ${tildePath(logger.file, homedir8())}` : "";
|
|
10320
10445
|
process.stdout.write(
|
|
10321
10446
|
code === 0 ? `
|
|
10322
10447
|
Frizz stopped. Agent sessions in tmux keep running.${suffix}
|