elit 3.5.3 → 3.5.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/README.md +82 -4
- package/dist/chokidar.d.ts.map +1 -1
- package/dist/chokidar.js +306 -16
- package/dist/chokidar.js.map +1 -1
- package/dist/chokidar.mjs +306 -16
- package/dist/chokidar.mjs.map +1 -1
- package/dist/cli.d.mts +15 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +2547 -185
- package/dist/cli.mjs +81817 -0
- package/dist/config.d.mts +96 -1
- package/dist/config.d.ts +95 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js.map +1 -1
- package/dist/config.mjs.map +1 -1
- package/dist/mobile-cli.d.ts.map +1 -1
- package/dist/pm-cli.d.ts +139 -0
- package/dist/pm-cli.d.ts.map +1 -0
- package/dist/server.js +220 -197
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +221 -198
- package/dist/server.mjs.map +1 -1
- package/dist/wapk-cli.d.ts +25 -4
- package/dist/wapk-cli.d.ts.map +1 -1
- package/package.json +2 -1
- package/src/chokidar.ts +28 -2
- package/src/cli.ts +45 -5
- package/src/config.ts +101 -0
- package/src/desktop-cli.ts +2 -2
- package/src/mobile-cli.ts +52 -39
- package/src/pm-cli.ts +2369 -0
- package/src/wapk-cli.ts +717 -51
package/README.md
CHANGED
|
@@ -218,6 +218,7 @@ Main commands:
|
|
|
218
218
|
```bash
|
|
219
219
|
npx elit dev
|
|
220
220
|
npx elit build --entry ./src/main.ts --out-dir dist
|
|
221
|
+
npx elit --version
|
|
221
222
|
npx elit preview
|
|
222
223
|
npx elit test
|
|
223
224
|
npx elit desktop ./src/main.ts
|
|
@@ -226,6 +227,7 @@ npx elit desktop build ./src/main.ts --release
|
|
|
226
227
|
npx elit mobile init
|
|
227
228
|
npx elit mobile run android
|
|
228
229
|
npx elit native generate android ./src/native-screen.ts --name HomeScreen
|
|
230
|
+
npx elit pm start --script "npm start" --name my-app
|
|
229
231
|
npx elit wapk pack .
|
|
230
232
|
npx elit wapk run ./app.wapk
|
|
231
233
|
npx elit desktop wapk run ./app.wapk
|
|
@@ -233,6 +235,8 @@ npx elit desktop wapk run ./app.wapk
|
|
|
233
235
|
|
|
234
236
|
Useful flags:
|
|
235
237
|
|
|
238
|
+
- `elit --version`
|
|
239
|
+
- `elit -v`
|
|
236
240
|
- `elit dev --port 3000 --host 0.0.0.0 --no-open`
|
|
237
241
|
- `elit build --entry ./src/main.ts --out-dir dist --format esm --sourcemap`
|
|
238
242
|
- `elit preview --root dist --base-path /app`
|
|
@@ -255,6 +259,15 @@ Useful flags:
|
|
|
255
259
|
- `elit native generate android ./src/native-screen.ts --name HomeScreen --package com.example.app`
|
|
256
260
|
- `elit native generate ios ./src/native-screen.ts --out ./ios/HomeScreen.swift --no-preview`
|
|
257
261
|
- `elit native generate ir ./src/native-screen.ts --platform android --export screen`
|
|
262
|
+
- `elit pm start --script "npm start" --name my-app --runtime node`
|
|
263
|
+
- `elit pm start --script "npm start" --name my-app --watch --watch-path src --restart-policy on-failure`
|
|
264
|
+
- `elit pm start ./src/worker.ts --name worker --runtime bun`
|
|
265
|
+
- `elit pm start --wapk ./app.wapk --name packaged-app`
|
|
266
|
+
- `elit pm start --wapk gdrive://<fileId> --name packaged-app`
|
|
267
|
+
- `elit pm start --google-drive-file-id <fileId> --google-drive-token-env GOOGLE_DRIVE_ACCESS_TOKEN --name packaged-app`
|
|
268
|
+
- `elit pm save`
|
|
269
|
+
- `elit pm resurrect`
|
|
270
|
+
- `elit pm logs my-app --lines 100`
|
|
258
271
|
- `elit wapk pack . --password secret-123`
|
|
259
272
|
- `elit wapk ./app.wapk --runtime node|bun|deno`
|
|
260
273
|
- `elit wapk run ./app.wapk --password secret-123 --sync-interval 100 --watcher`
|
|
@@ -315,6 +328,19 @@ WAPK mode notes:
|
|
|
315
328
|
- WAPK stays unlocked by default unless `wapk.lock.password` or `--password` is provided.
|
|
316
329
|
- See [docs/wapk.md](docs/wapk.md) for the full archive guide and `examples/wapk-example` for an end-to-end sample.
|
|
317
330
|
|
|
331
|
+
PM mode notes:
|
|
332
|
+
|
|
333
|
+
- `elit pm start --script "npm start"`, `elit pm start --file ./app.ts`, and `elit pm start --wapk ./app.wapk` all run through the same detached process manager.
|
|
334
|
+
- WAPK PM targets can also point at `gdrive://<fileId>` or use `pm.apps[].wapkRun.googleDrive` plus forwarded WAPK run flags like `syncInterval`, `watcher`, and `watchArchive`.
|
|
335
|
+
- `elit pm start` boots every app from `pm.apps[]`, and `elit pm start <name>` starts one configured app by name.
|
|
336
|
+
- Use `elit pm list`, `elit pm stop`, `elit pm restart`, `elit pm delete`, `elit pm save`, `elit pm resurrect`, and `elit pm logs` to manage long-running processes.
|
|
337
|
+
- Use `--restart-policy always|on-failure|never` plus `--min-uptime <ms>` when you want tighter restart-loop control.
|
|
338
|
+
- Use `--watch`, `--watch-path`, `--watch-ignore`, and `--watch-debounce` when the process should restart after source changes.
|
|
339
|
+
- PM `--watch` and WAPK `--watcher` are different: the first restarts the managed process, the second changes how the inner WAPK runtime syncs files.
|
|
340
|
+
- Use `--health-url`, `--health-grace-period`, `--health-interval`, `--health-timeout`, and `--health-max-failures` when the process exposes an HTTP health endpoint.
|
|
341
|
+
- PM state and logs are stored in `./.elit/pm` by default, or in `pm.dataDir` when configured. `elit pm save` writes to `pm.dumpFile` or `./.elit/pm/dump.json`.
|
|
342
|
+
- TypeScript file targets with runtime `node` require `tsx`; use `--runtime bun` when you want zero-config TypeScript execution.
|
|
343
|
+
|
|
318
344
|
## Config File
|
|
319
345
|
|
|
320
346
|
Elit loads one of these files from the project root:
|
|
@@ -334,6 +360,37 @@ The config shape is:
|
|
|
334
360
|
build?: BuildOptions | BuildOptions[];
|
|
335
361
|
preview?: PreviewOptions;
|
|
336
362
|
test?: TestOptions;
|
|
363
|
+
pm?: {
|
|
364
|
+
dataDir?: string;
|
|
365
|
+
apps?: Array<{
|
|
366
|
+
name: string;
|
|
367
|
+
script?: string;
|
|
368
|
+
file?: string;
|
|
369
|
+
wapk?: string;
|
|
370
|
+
wapkRun?: {
|
|
371
|
+
file?: string;
|
|
372
|
+
googleDrive?: {
|
|
373
|
+
fileId?: string;
|
|
374
|
+
accessToken?: string;
|
|
375
|
+
accessTokenEnv?: string;
|
|
376
|
+
supportsAllDrives?: boolean;
|
|
377
|
+
};
|
|
378
|
+
runtime?: 'node' | 'bun' | 'deno';
|
|
379
|
+
password?: string;
|
|
380
|
+
syncInterval?: number;
|
|
381
|
+
useWatcher?: boolean;
|
|
382
|
+
watchArchive?: boolean;
|
|
383
|
+
archiveSyncInterval?: number;
|
|
384
|
+
};
|
|
385
|
+
runtime?: 'node' | 'bun' | 'deno';
|
|
386
|
+
cwd?: string;
|
|
387
|
+
env?: Record<string, string | number | boolean>;
|
|
388
|
+
autorestart?: boolean;
|
|
389
|
+
restartDelay?: number;
|
|
390
|
+
maxRestarts?: number;
|
|
391
|
+
password?: string;
|
|
392
|
+
}>;
|
|
393
|
+
};
|
|
337
394
|
mobile?: {
|
|
338
395
|
cwd?: string;
|
|
339
396
|
appId?: string;
|
|
@@ -479,6 +536,25 @@ export default {
|
|
|
479
536
|
release: true,
|
|
480
537
|
},
|
|
481
538
|
},
|
|
539
|
+
pm: {
|
|
540
|
+
apps: [
|
|
541
|
+
{
|
|
542
|
+
name: 'api',
|
|
543
|
+
script: 'npm start',
|
|
544
|
+
runtime: 'node',
|
|
545
|
+
},
|
|
546
|
+
{
|
|
547
|
+
name: 'worker',
|
|
548
|
+
file: './src/worker.ts',
|
|
549
|
+
runtime: 'bun',
|
|
550
|
+
},
|
|
551
|
+
{
|
|
552
|
+
name: 'archive-app',
|
|
553
|
+
wapk: './dist/app.wapk',
|
|
554
|
+
runtime: 'node',
|
|
555
|
+
},
|
|
556
|
+
],
|
|
557
|
+
},
|
|
482
558
|
wapk: {
|
|
483
559
|
name: 'my-app',
|
|
484
560
|
version: '1.0.0',
|
|
@@ -509,6 +585,7 @@ Important details:
|
|
|
509
585
|
- Only `VITE_` variables are exposed to client code during bundling.
|
|
510
586
|
- `desktop` config provides defaults for `elit desktop`, `elit desktop run`, `elit desktop build`, and `elit desktop wapk`. Use `desktop.entry` for hybrid defaults, `desktop.native.entry` for native defaults, and `desktop.mode` to choose which one runs by default.
|
|
511
587
|
- `mobile` config provides defaults for `elit mobile init|sync|open|run|build`.
|
|
588
|
+
- `pm` config provides defaults for `elit pm`. Use `pm.apps[]` for named processes, `pm.dataDir` for metadata/log storage, `pm.dumpFile` for `save`/`resurrect`, and per-app restart/watch/health settings.
|
|
512
589
|
- `wapk` config is loaded from `elit.config.*`, then package metadata is used as fallback.
|
|
513
590
|
- `wapk.lock.password` is the config-level default for locked archives. Use `--password` when you want to supply unlock credentials at command time instead of writing them into config.
|
|
514
591
|
- `wapk run` and `desktop wapk run` sync runtime file changes back into the same `.wapk` archive.
|
|
@@ -872,11 +949,12 @@ The package also exports `elit/test`, `elit/test-runtime`, and `elit/test-report
|
|
|
872
949
|
|
|
873
950
|
Latest release notes live in [CHANGELOG.md](CHANGELOG.md).
|
|
874
951
|
|
|
875
|
-
Highlights in `v3.5.
|
|
952
|
+
Highlights in `v3.5.5`:
|
|
876
953
|
|
|
877
|
-
-
|
|
878
|
-
- `
|
|
879
|
-
- `elit
|
|
954
|
+
- Added `elit pm` for detached background process management of shell commands, file targets, and WAPK apps.
|
|
955
|
+
- Added `pm.apps[]` and `pm.dataDir` in `elit.config.*` for config-first process manager workflows.
|
|
956
|
+
- Added `elit pm save` / `elit pm resurrect`, `pm.dumpFile`, watch mode, health checks, and restart-policy controls for the process manager.
|
|
957
|
+
- Added lifecycle commands for managed apps: `list`, `stop`, `restart`, `delete`, and `logs`.
|
|
880
958
|
|
|
881
959
|
## Good Defaults For Generated Code
|
|
882
960
|
|
package/dist/chokidar.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chokidar.d.ts","sourceRoot":"","sources":["../src/chokidar.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"chokidar.d.ts","sourceRoot":"","sources":["../src/chokidar.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AA2EtC;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;OAEG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAEjC;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC;IAExD;;OAEG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;OAEG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,GAAG;QAC3B,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,CAAC;IAEF;;OAEG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;OAEG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B;;OAEG;IACH,MAAM,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;CAC3B;AAED;;GAEG;AACH,qBAAa,SAAU,SAAQ,YAAY;IACzC,OAAO,CAAC,QAAQ,CAAM;IACtB,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,QAAQ,CAA0B;gBAE9B,OAAO,CAAC,EAAE,YAAY;IAK3B,OAAO,EAAE,YAAY,CAAC;IAE7B;;OAEG;IACH,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS;IAkBxC;;OAEG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS;IAkB5C;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAgB5B;;OAEG;IACH,UAAU,IAAI;QAAE,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;KAAE;IAkB/C;;;OAGG;IACH,WAAW,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI;CAGhC;AA6DD;;GAEG;AACH,wBAAgB,KAAK,CACnB,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,EACxB,OAAO,CAAC,EAAE,YAAY,GACrB,SAAS,CAoEX;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,MAAM,GAAG,KAAK,GAAG,MAAM,CAEpD;AAED;;GAEG;;;;;;AACH,wBAIE"}
|
package/dist/chokidar.js
CHANGED
|
@@ -34,9 +34,282 @@ var runtime = (() => {
|
|
|
34
34
|
if (typeof Bun !== "undefined") return "bun";
|
|
35
35
|
return "node";
|
|
36
36
|
})();
|
|
37
|
+
var isNode = runtime === "node";
|
|
38
|
+
var isBun = runtime === "bun";
|
|
39
|
+
var isDeno = runtime === "deno";
|
|
40
|
+
|
|
41
|
+
// src/fs.ts
|
|
42
|
+
var fs;
|
|
43
|
+
var fsPromises;
|
|
44
|
+
if (isNode || isBun) {
|
|
45
|
+
fs = require("fs");
|
|
46
|
+
fsPromises = require("fs/promises");
|
|
47
|
+
}
|
|
48
|
+
function existsSync(path) {
|
|
49
|
+
try {
|
|
50
|
+
statSync(path);
|
|
51
|
+
return true;
|
|
52
|
+
} catch {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function statSync(path) {
|
|
57
|
+
if (isNode || isBun) {
|
|
58
|
+
return fs.statSync(path);
|
|
59
|
+
} else if (isDeno) {
|
|
60
|
+
const info = Deno.statSync(path);
|
|
61
|
+
return createStatsFromDenoFileInfo(info);
|
|
62
|
+
}
|
|
63
|
+
throw new Error("Unsupported runtime");
|
|
64
|
+
}
|
|
65
|
+
function createStatsFromDenoFileInfo(info) {
|
|
66
|
+
return {
|
|
67
|
+
isFile: () => info.isFile,
|
|
68
|
+
isDirectory: () => info.isDirectory,
|
|
69
|
+
isBlockDevice: () => false,
|
|
70
|
+
isCharacterDevice: () => false,
|
|
71
|
+
isSymbolicLink: () => info.isSymlink || false,
|
|
72
|
+
isFIFO: () => false,
|
|
73
|
+
isSocket: () => false,
|
|
74
|
+
dev: info.dev || 0,
|
|
75
|
+
ino: info.ino || 0,
|
|
76
|
+
mode: info.mode || 0,
|
|
77
|
+
nlink: info.nlink || 1,
|
|
78
|
+
uid: info.uid || 0,
|
|
79
|
+
gid: info.gid || 0,
|
|
80
|
+
rdev: 0,
|
|
81
|
+
size: info.size,
|
|
82
|
+
blksize: info.blksize || 4096,
|
|
83
|
+
blocks: info.blocks || Math.ceil(info.size / 512),
|
|
84
|
+
atimeMs: info.atime?.getTime() || Date.now(),
|
|
85
|
+
mtimeMs: info.mtime?.getTime() || Date.now(),
|
|
86
|
+
ctimeMs: info.birthtime?.getTime() || Date.now(),
|
|
87
|
+
birthtimeMs: info.birthtime?.getTime() || Date.now(),
|
|
88
|
+
atime: info.atime || /* @__PURE__ */ new Date(),
|
|
89
|
+
mtime: info.mtime || /* @__PURE__ */ new Date(),
|
|
90
|
+
ctime: info.birthtime || /* @__PURE__ */ new Date(),
|
|
91
|
+
birthtime: info.birthtime || /* @__PURE__ */ new Date()
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// src/path.ts
|
|
96
|
+
function getSeparator(isWin) {
|
|
97
|
+
return isWin ? "\\" : "/";
|
|
98
|
+
}
|
|
99
|
+
function getCwd() {
|
|
100
|
+
if (isNode || isBun) {
|
|
101
|
+
return process.cwd();
|
|
102
|
+
} else if (isDeno) {
|
|
103
|
+
return Deno.cwd();
|
|
104
|
+
}
|
|
105
|
+
return "/";
|
|
106
|
+
}
|
|
107
|
+
function findLastSeparator(path) {
|
|
108
|
+
return Math.max(path.lastIndexOf("/"), path.lastIndexOf("\\"));
|
|
109
|
+
}
|
|
110
|
+
function createPathOps(isWin) {
|
|
111
|
+
return {
|
|
112
|
+
sep: getSeparator(isWin),
|
|
113
|
+
delimiter: isWin ? ";" : ":",
|
|
114
|
+
normalize: (path) => normalizePath(path, isWin),
|
|
115
|
+
join: (...paths) => joinPaths(paths, isWin),
|
|
116
|
+
resolve: (...paths) => resolvePaths(paths, isWin),
|
|
117
|
+
isAbsolute: (path) => isWin ? isAbsoluteWin(path) : isAbsolutePosix(path),
|
|
118
|
+
relative: (from, to) => relativePath(from, to, isWin),
|
|
119
|
+
dirname: (path) => getDirname(path, isWin),
|
|
120
|
+
basename: (path, ext) => getBasename(path, ext, isWin),
|
|
121
|
+
extname: (path) => getExtname(path),
|
|
122
|
+
parse: (path) => parsePath(path, isWin),
|
|
123
|
+
format: (pathObject) => formatPath(pathObject, isWin)
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
function isAbsolutePosix(path) {
|
|
127
|
+
return path.length > 0 && path[0] === "/";
|
|
128
|
+
}
|
|
129
|
+
function isAbsoluteWin(path) {
|
|
130
|
+
const len = path.length;
|
|
131
|
+
if (len === 0) return false;
|
|
132
|
+
const code = path.charCodeAt(0);
|
|
133
|
+
if (code === 47 || code === 92) {
|
|
134
|
+
return true;
|
|
135
|
+
}
|
|
136
|
+
if (code >= 65 && code <= 90 || code >= 97 && code <= 122) {
|
|
137
|
+
if (len > 2 && path.charCodeAt(1) === 58) {
|
|
138
|
+
const code2 = path.charCodeAt(2);
|
|
139
|
+
if (code2 === 47 || code2 === 92) {
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
var isWindows = (() => {
|
|
147
|
+
if (isNode) {
|
|
148
|
+
return process.platform === "win32";
|
|
149
|
+
} else if (isDeno) {
|
|
150
|
+
return Deno.build.os === "windows";
|
|
151
|
+
}
|
|
152
|
+
return typeof process !== "undefined" && process.platform === "win32";
|
|
153
|
+
})();
|
|
154
|
+
var posix = createPathOps(false);
|
|
155
|
+
var win32 = createPathOps(true);
|
|
156
|
+
function normalizePath(path, isWin) {
|
|
157
|
+
if (path.length === 0) return ".";
|
|
158
|
+
const separator = getSeparator(isWin);
|
|
159
|
+
const isAbsolute = isWin ? isAbsoluteWin(path) : isAbsolutePosix(path);
|
|
160
|
+
const trailingSeparator = path[path.length - 1] === separator || isWin && path[path.length - 1] === "/";
|
|
161
|
+
let normalized = path.replace(isWin ? /[\/\\]+/g : /\/+/g, separator);
|
|
162
|
+
const parts = normalized.split(separator);
|
|
163
|
+
const result = [];
|
|
164
|
+
for (let i = 0; i < parts.length; i++) {
|
|
165
|
+
const part = parts[i];
|
|
166
|
+
if (part === "" || part === ".") {
|
|
167
|
+
if (i === 0 && isAbsolute) result.push("");
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
if (part === "..") {
|
|
171
|
+
if (result.length > 0 && result[result.length - 1] !== "..") {
|
|
172
|
+
if (!(result.length === 1 && result[0] === "")) {
|
|
173
|
+
result.pop();
|
|
174
|
+
}
|
|
175
|
+
} else if (!isAbsolute) {
|
|
176
|
+
result.push("..");
|
|
177
|
+
}
|
|
178
|
+
} else {
|
|
179
|
+
result.push(part);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
let final = result.join(separator);
|
|
183
|
+
if (final.length === 0) {
|
|
184
|
+
return isAbsolute ? separator : ".";
|
|
185
|
+
}
|
|
186
|
+
if (trailingSeparator && final[final.length - 1] !== separator) {
|
|
187
|
+
final += separator;
|
|
188
|
+
}
|
|
189
|
+
return final;
|
|
190
|
+
}
|
|
191
|
+
function joinPaths(paths, isWin) {
|
|
192
|
+
if (paths.length === 0) return ".";
|
|
193
|
+
const separator = getSeparator(isWin);
|
|
194
|
+
let joined = "";
|
|
195
|
+
for (let i = 0; i < paths.length; i++) {
|
|
196
|
+
const path = paths[i];
|
|
197
|
+
if (path && path.length > 0) {
|
|
198
|
+
if (joined.length === 0) {
|
|
199
|
+
joined = path;
|
|
200
|
+
} else {
|
|
201
|
+
joined += separator + path;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
if (joined.length === 0) return ".";
|
|
206
|
+
return normalizePath(joined, isWin);
|
|
207
|
+
}
|
|
208
|
+
function resolvePaths(paths, isWin) {
|
|
209
|
+
const separator = getSeparator(isWin);
|
|
210
|
+
let resolved = "";
|
|
211
|
+
let isAbsolute = false;
|
|
212
|
+
for (let i = paths.length - 1; i >= 0 && !isAbsolute; i--) {
|
|
213
|
+
const path = paths[i];
|
|
214
|
+
if (path && path.length > 0) {
|
|
215
|
+
resolved = path + (resolved.length > 0 ? separator + resolved : "");
|
|
216
|
+
isAbsolute = isWin ? isAbsoluteWin(resolved) : isAbsolutePosix(resolved);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
if (!isAbsolute) {
|
|
220
|
+
const cwd = getCwd();
|
|
221
|
+
resolved = cwd + (resolved.length > 0 ? separator + resolved : "");
|
|
222
|
+
}
|
|
223
|
+
return normalizePath(resolved, isWin);
|
|
224
|
+
}
|
|
225
|
+
function relativePath(from, to, isWin) {
|
|
226
|
+
from = resolvePaths([from], isWin);
|
|
227
|
+
to = resolvePaths([to], isWin);
|
|
228
|
+
if (from === to) return "";
|
|
229
|
+
const separator = getSeparator(isWin);
|
|
230
|
+
const fromParts = from.split(separator).filter((p) => p.length > 0);
|
|
231
|
+
const toParts = to.split(separator).filter((p) => p.length > 0);
|
|
232
|
+
let commonLength = 0;
|
|
233
|
+
const minLength = Math.min(fromParts.length, toParts.length);
|
|
234
|
+
for (let i = 0; i < minLength; i++) {
|
|
235
|
+
if (fromParts[i] === toParts[i]) {
|
|
236
|
+
commonLength++;
|
|
237
|
+
} else {
|
|
238
|
+
break;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
const upCount = fromParts.length - commonLength;
|
|
242
|
+
const result = [];
|
|
243
|
+
for (let i = 0; i < upCount; i++) {
|
|
244
|
+
result.push("..");
|
|
245
|
+
}
|
|
246
|
+
for (let i = commonLength; i < toParts.length; i++) {
|
|
247
|
+
result.push(toParts[i]);
|
|
248
|
+
}
|
|
249
|
+
return result.join(separator) || ".";
|
|
250
|
+
}
|
|
251
|
+
function getDirname(path, isWin) {
|
|
252
|
+
if (path.length === 0) return ".";
|
|
253
|
+
const separator = getSeparator(isWin);
|
|
254
|
+
const normalized = normalizePath(path, isWin);
|
|
255
|
+
const lastSepIndex = normalized.lastIndexOf(separator);
|
|
256
|
+
if (lastSepIndex === -1) return ".";
|
|
257
|
+
if (lastSepIndex === 0) return separator;
|
|
258
|
+
return normalized.slice(0, lastSepIndex);
|
|
259
|
+
}
|
|
260
|
+
function getBasename(path, ext, isWin) {
|
|
261
|
+
if (path.length === 0) return "";
|
|
262
|
+
const lastSepIndex = isWin ? findLastSeparator(path) : path.lastIndexOf("/");
|
|
263
|
+
let base = lastSepIndex === -1 ? path : path.slice(lastSepIndex + 1);
|
|
264
|
+
if (ext && base.endsWith(ext)) {
|
|
265
|
+
base = base.slice(0, base.length - ext.length);
|
|
266
|
+
}
|
|
267
|
+
return base;
|
|
268
|
+
}
|
|
269
|
+
function getExtname(path) {
|
|
270
|
+
const lastDotIndex = path.lastIndexOf(".");
|
|
271
|
+
const lastSepIndex = findLastSeparator(path);
|
|
272
|
+
if (lastDotIndex === -1 || lastDotIndex < lastSepIndex || lastDotIndex === path.length - 1) {
|
|
273
|
+
return "";
|
|
274
|
+
}
|
|
275
|
+
return path.slice(lastDotIndex);
|
|
276
|
+
}
|
|
277
|
+
function parsePath(path, isWin) {
|
|
278
|
+
let root = "";
|
|
279
|
+
if (isWin) {
|
|
280
|
+
if (path.length >= 2 && path[1] === ":") {
|
|
281
|
+
root = path.slice(0, 2);
|
|
282
|
+
if (path.length > 2 && (path[2] === "\\" || path[2] === "/")) {
|
|
283
|
+
root += "\\";
|
|
284
|
+
}
|
|
285
|
+
} else if (path[0] === "\\" || path[0] === "/") {
|
|
286
|
+
root = "\\";
|
|
287
|
+
}
|
|
288
|
+
} else {
|
|
289
|
+
if (path[0] === "/") {
|
|
290
|
+
root = "/";
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
const dir = getDirname(path, isWin);
|
|
294
|
+
const base = getBasename(path, void 0, isWin);
|
|
295
|
+
const ext = getExtname(path);
|
|
296
|
+
const name = ext ? base.slice(0, base.length - ext.length) : base;
|
|
297
|
+
return { root, dir, base, ext, name };
|
|
298
|
+
}
|
|
299
|
+
function formatPath(pathObject, isWin) {
|
|
300
|
+
const separator = getSeparator(isWin);
|
|
301
|
+
const dir = pathObject.dir || pathObject.root || "";
|
|
302
|
+
const base = pathObject.base || (pathObject.name || "") + (pathObject.ext || "");
|
|
303
|
+
if (!dir) return base;
|
|
304
|
+
if (dir === pathObject.root) return dir + base;
|
|
305
|
+
return dir + separator + base;
|
|
306
|
+
}
|
|
307
|
+
function dirname(path) {
|
|
308
|
+
return getDirname(path, isWindows);
|
|
309
|
+
}
|
|
37
310
|
|
|
38
311
|
// src/chokidar.ts
|
|
39
|
-
function
|
|
312
|
+
function normalizePath2(path) {
|
|
40
313
|
return path.replace(/\\/g, "/");
|
|
41
314
|
}
|
|
42
315
|
function emitEvent(watcher, eventType, path) {
|
|
@@ -46,22 +319,22 @@ function emitEvent(watcher, eventType, path) {
|
|
|
46
319
|
function matchesAnyPattern(path, patterns) {
|
|
47
320
|
return patterns.some((pattern) => matchesPattern(path, pattern));
|
|
48
321
|
}
|
|
49
|
-
function handleRenameEvent(watcher, fullPath,
|
|
322
|
+
function handleRenameEvent(watcher, fullPath, fs2) {
|
|
50
323
|
try {
|
|
51
|
-
|
|
324
|
+
fs2.statSync(fullPath);
|
|
52
325
|
emitEvent(watcher, "add", fullPath);
|
|
53
326
|
} catch {
|
|
54
327
|
emitEvent(watcher, "unlink", fullPath);
|
|
55
328
|
}
|
|
56
329
|
}
|
|
57
|
-
function setupFsWatch(watcher, baseDir, patterns,
|
|
330
|
+
function setupFsWatch(watcher, baseDir, patterns, fs2) {
|
|
58
331
|
try {
|
|
59
|
-
const nativeWatcher =
|
|
332
|
+
const nativeWatcher = fs2.watch(baseDir, { recursive: true }, (eventType, filename) => {
|
|
60
333
|
if (!filename) return;
|
|
61
|
-
const fullPath =
|
|
334
|
+
const fullPath = normalizePath2(`${baseDir}/${filename}`);
|
|
62
335
|
if (!matchesAnyPattern(fullPath, patterns)) return;
|
|
63
336
|
if (eventType === "rename") {
|
|
64
|
-
handleRenameEvent(watcher, fullPath,
|
|
337
|
+
handleRenameEvent(watcher, fullPath, fs2);
|
|
65
338
|
} else if (eventType === "change") {
|
|
66
339
|
emitEvent(watcher, "change", fullPath);
|
|
67
340
|
}
|
|
@@ -156,20 +429,37 @@ var FSWatcher = class extends import_events.EventEmitter {
|
|
|
156
429
|
}
|
|
157
430
|
};
|
|
158
431
|
function getBaseDirectory(pattern) {
|
|
159
|
-
const
|
|
432
|
+
const normalizedPattern = normalizePath2(pattern);
|
|
433
|
+
const parts = normalizedPattern.split(/[\\\/]/);
|
|
160
434
|
let baseDir = "";
|
|
435
|
+
let sawGlob = false;
|
|
161
436
|
for (const part of parts) {
|
|
162
437
|
if (part.includes("*") || part.includes("?")) {
|
|
438
|
+
sawGlob = true;
|
|
163
439
|
break;
|
|
164
440
|
}
|
|
165
441
|
baseDir = baseDir ? `${baseDir}/${part}` : part;
|
|
166
442
|
}
|
|
167
|
-
|
|
443
|
+
if (sawGlob) {
|
|
444
|
+
return baseDir || ".";
|
|
445
|
+
}
|
|
446
|
+
if (normalizedPattern && existsSync(normalizedPattern)) {
|
|
447
|
+
try {
|
|
448
|
+
return statSync(normalizedPattern).isDirectory() ? normalizedPattern : normalizePath2(dirname(normalizedPattern)) || ".";
|
|
449
|
+
} catch {
|
|
450
|
+
return normalizePath2(dirname(normalizedPattern)) || ".";
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
const lastSegment = parts[parts.length - 1] || "";
|
|
454
|
+
if (lastSegment.includes(".") && !lastSegment.startsWith(".")) {
|
|
455
|
+
return normalizePath2(dirname(normalizedPattern)) || ".";
|
|
456
|
+
}
|
|
457
|
+
return normalizedPattern || ".";
|
|
168
458
|
}
|
|
169
459
|
function matchesPattern(filePath, pattern) {
|
|
170
|
-
const regexPattern =
|
|
460
|
+
const regexPattern = normalizePath2(pattern).replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*\*/g, ".*").replace(/\*/g, "[^/]*").replace(/\?/g, ".");
|
|
171
461
|
const regex = new RegExp(`^${regexPattern}$`);
|
|
172
|
-
const normalizedPath =
|
|
462
|
+
const normalizedPath = normalizePath2(filePath);
|
|
173
463
|
return regex.test(normalizedPath);
|
|
174
464
|
}
|
|
175
465
|
function watch(paths, options) {
|
|
@@ -184,11 +474,11 @@ function watch(paths, options) {
|
|
|
184
474
|
watchMap.get(baseDir).push(path);
|
|
185
475
|
});
|
|
186
476
|
if (runtime === "node") {
|
|
187
|
-
const
|
|
188
|
-
watchMap.forEach((patterns, baseDir) => setupFsWatch(watcher, baseDir, patterns,
|
|
477
|
+
const fs2 = require("fs");
|
|
478
|
+
watchMap.forEach((patterns, baseDir) => setupFsWatch(watcher, baseDir, patterns, fs2));
|
|
189
479
|
} else if (runtime === "bun") {
|
|
190
|
-
const
|
|
191
|
-
watchMap.forEach((patterns, baseDir) => setupFsWatch(watcher, baseDir, patterns,
|
|
480
|
+
const fs2 = require("fs");
|
|
481
|
+
watchMap.forEach((patterns, baseDir) => setupFsWatch(watcher, baseDir, patterns, fs2));
|
|
192
482
|
} else if (runtime === "deno") {
|
|
193
483
|
const baseDirs = Array.from(watchMap.keys());
|
|
194
484
|
const allPatterns = Array.from(watchMap.values()).flat();
|
|
@@ -198,7 +488,7 @@ function watch(paths, options) {
|
|
|
198
488
|
for await (const event of denoWatcher) {
|
|
199
489
|
if (watcher["_closed"]) break;
|
|
200
490
|
for (const path of event.paths) {
|
|
201
|
-
const normalizedPath =
|
|
491
|
+
const normalizedPath = normalizePath2(path);
|
|
202
492
|
if (!matchesAnyPattern(normalizedPath, allPatterns)) continue;
|
|
203
493
|
switch (event.kind) {
|
|
204
494
|
case "create":
|