@oh-my-pi/pi-utils 18.1.18 → 18.1.20
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/CHANGELOG.md +10 -0
- package/dist/types/dirs.d.ts +2 -0
- package/dist/types/file-lock.d.ts +6 -0
- package/package.json +2 -2
- package/src/dirs.ts +2 -1
- package/src/env.ts +1 -1
- package/src/file-lock.ts +8 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [18.1.19] - 2026-09-12
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Added public `acquireFileLock()` and `FileLockHandle` APIs for holding and explicitly releasing exclusive OS-backed file locks.
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- Child-shell environment filtering now tolerates a removed process working directory by retaining the resolved project directory ([#11828](https://github.com/can1357/oh-my-pi/issues/11828)).
|
|
14
|
+
|
|
5
15
|
## [18.1.16] - 2026-09-09
|
|
6
16
|
|
|
7
17
|
### Fixed
|
package/dist/types/dirs.d.ts
CHANGED
|
@@ -40,6 +40,8 @@ export declare function normalizeProfileName(profile: string | undefined): strin
|
|
|
40
40
|
* {@link normalizeProfileName} (which throws on a syntactically invalid value).
|
|
41
41
|
*/
|
|
42
42
|
export declare function resolveProfileEnv(omp: string | undefined, pi: string | undefined): string | undefined;
|
|
43
|
+
/** Profile-independent config root (~/.omp), shared by every omp profile. */
|
|
44
|
+
export declare function getBaseConfigRoot(): string;
|
|
43
45
|
export declare function resolveEquivalentPath(inputPath: string): string;
|
|
44
46
|
export declare function normalizePathForComparison(inputPath: string): string;
|
|
45
47
|
export declare function pathIsWithin(root: string, candidate: string): boolean;
|
|
@@ -6,8 +6,14 @@ export interface FileLockOptions {
|
|
|
6
6
|
/** Delay between acquisition attempts. */
|
|
7
7
|
retryDelayMs?: number;
|
|
8
8
|
}
|
|
9
|
+
/** An exclusive OS-backed lease. Releasing an already released handle is safe. */
|
|
10
|
+
export interface FileLockHandle {
|
|
11
|
+
release(): void;
|
|
12
|
+
}
|
|
9
13
|
declare function getLockPath(filePath: string): string;
|
|
10
14
|
declare function tryAcquireLock(lockPath: string): NativeFileLock | null;
|
|
15
|
+
/** Acquire an exclusive lease; callers must release it when their operation ends. */
|
|
16
|
+
export declare function acquireFileLock(filePath: string, options?: FileLockOptions): Promise<FileLockHandle>;
|
|
11
17
|
/** Run `fn` while holding an OS-backed exclusive lock for `filePath`. */
|
|
12
18
|
export declare function withFileLock<T>(filePath: string, fn: () => Promise<T>, options?: FileLockOptions): Promise<T>;
|
|
13
19
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oh-my-pi/pi-utils",
|
|
3
|
-
"version": "18.1.
|
|
3
|
+
"version": "18.1.20",
|
|
4
4
|
"description": "Shared utilities for pi packages",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"fmt": "oxfmt --no-error-on-unmatched-pattern 'src/**/*.{ts,tsx}' '{test,bench,examples,scripts}/**/*.ts' '*.ts'"
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
|
-
"@oh-my-pi/pi-natives": "18.1.
|
|
57
|
+
"@oh-my-pi/pi-natives": "18.1.20"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
60
|
"@types/bun": "^1.3.14"
|
package/src/dirs.ts
CHANGED
|
@@ -107,7 +107,8 @@ function readProfileFromEnvSafe(): string | undefined {
|
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
|
|
110
|
+
/** Profile-independent config root (~/.omp), shared by every omp profile. */
|
|
111
|
+
export function getBaseConfigRoot(): string {
|
|
111
112
|
return path.join(os.homedir(), getConfigDirName());
|
|
112
113
|
}
|
|
113
114
|
|
package/src/env.ts
CHANGED
|
@@ -110,7 +110,7 @@ function expandDotenvValues(values: Record<string, string>, env: Record<string,
|
|
|
110
110
|
/** Filters process env for child shells without launch-cwd dotenv values. */
|
|
111
111
|
export function filterChildShellEnv(
|
|
112
112
|
env: Record<string, string | undefined>,
|
|
113
|
-
cwd: string =
|
|
113
|
+
cwd: string = getProjectDir(),
|
|
114
114
|
): Record<string, string> {
|
|
115
115
|
const runtimeLaunchEnvValues = env === Bun.env || env === process.env ? launchEnvValues : undefined;
|
|
116
116
|
const result = filterProcessEnv(env);
|
package/src/file-lock.ts
CHANGED
|
@@ -15,6 +15,11 @@ export interface FileLockOptions {
|
|
|
15
15
|
retryDelayMs?: number;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
/** An exclusive OS-backed lease. Releasing an already released handle is safe. */
|
|
19
|
+
export interface FileLockHandle {
|
|
20
|
+
release(): void;
|
|
21
|
+
}
|
|
22
|
+
|
|
18
23
|
const DEFAULT_OPTIONS: Required<FileLockOptions> = {
|
|
19
24
|
retries: 50,
|
|
20
25
|
retryDelayMs: 100,
|
|
@@ -29,7 +34,8 @@ function tryAcquireLock(lockPath: string): NativeFileLock | null {
|
|
|
29
34
|
return lock.acquired ? lock : null;
|
|
30
35
|
}
|
|
31
36
|
|
|
32
|
-
|
|
37
|
+
/** Acquire an exclusive lease; callers must release it when their operation ends. */
|
|
38
|
+
export async function acquireFileLock(filePath: string, options: FileLockOptions = {}): Promise<FileLockHandle> {
|
|
33
39
|
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
34
40
|
const lockPath = getLockPath(filePath);
|
|
35
41
|
|
|
@@ -48,7 +54,7 @@ export async function withFileLock<T>(
|
|
|
48
54
|
fn: () => Promise<T>,
|
|
49
55
|
options: FileLockOptions = {},
|
|
50
56
|
): Promise<T> {
|
|
51
|
-
const lock = await
|
|
57
|
+
const lock = await acquireFileLock(filePath, options);
|
|
52
58
|
try {
|
|
53
59
|
return await fn();
|
|
54
60
|
} finally {
|