fyn 3.2.1 → 3.2.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/README.md +2 -0
- package/dist/fyn.mjs +81 -16
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -75,6 +75,7 @@ progress: normal
|
|
|
75
75
|
logLevel: info
|
|
76
76
|
production: false
|
|
77
77
|
centralStore: false
|
|
78
|
+
hardlink: true
|
|
78
79
|
```
|
|
79
80
|
|
|
80
81
|
Or as an ini:
|
|
@@ -89,6 +90,7 @@ progress=normal
|
|
|
89
90
|
logLevel=info
|
|
90
91
|
production=false
|
|
91
92
|
centralStore=false
|
|
93
|
+
hardlink=true
|
|
92
94
|
```
|
|
93
95
|
|
|
94
96
|
### Local source exports (`fyn.localExports`)
|
package/dist/fyn.mjs
CHANGED
|
@@ -92008,6 +92008,25 @@ async function unlinkDest(destFp) {
|
|
|
92008
92008
|
}
|
|
92009
92009
|
}
|
|
92010
92010
|
/**
|
|
92011
|
+
* Copy with COPYFILE_EXCL, so a new destination takes one call instead of an unlink and a copy.
|
|
92012
|
+
* An existing destination is unlinked and copied again, never written through - see
|
|
92013
|
+
* {@link unlinkDest}. replicate writes into a cleared dir, so the retry is rare.
|
|
92014
|
+
*
|
|
92015
|
+
* @param {*} srcFp
|
|
92016
|
+
* @param {*} destFp
|
|
92017
|
+
* @param {*} mode - extra copyFile flags, such as COPYFILE_FICLONE
|
|
92018
|
+
* @returns
|
|
92019
|
+
*/
|
|
92020
|
+
async function copyNew(srcFp, destFp, mode = 0) {
|
|
92021
|
+
try {
|
|
92022
|
+
return await fs.promises.copyFile(srcFp, destFp, mode | fs.constants.COPYFILE_EXCL);
|
|
92023
|
+
} catch (err) {
|
|
92024
|
+
if (err.code !== "EEXIST") throw err;
|
|
92025
|
+
}
|
|
92026
|
+
await unlinkDest(destFp);
|
|
92027
|
+
return fs.promises.copyFile(srcFp, destFp, mode | fs.constants.COPYFILE_EXCL);
|
|
92028
|
+
}
|
|
92029
|
+
/**
|
|
92011
92030
|
* Copy a file, replacing the destination rather than writing through it.
|
|
92012
92031
|
*
|
|
92013
92032
|
* @param {*} srcFp
|
|
@@ -92015,16 +92034,17 @@ async function unlinkDest(destFp) {
|
|
|
92015
92034
|
* @returns
|
|
92016
92035
|
*/
|
|
92017
92036
|
async function copyFile(srcFp, destFp) {
|
|
92018
|
-
|
|
92019
|
-
if (file_ops_default.copyFile) return file_ops_default.copyFile(srcFp, destFp);
|
|
92037
|
+
if (file_ops_default.copyFile) return copyNew(srcFp, destFp);
|
|
92020
92038
|
else {
|
|
92039
|
+
await unlinkDest(destFp);
|
|
92021
92040
|
const srcData = await file_ops_default.readFile(srcFp);
|
|
92022
92041
|
return file_ops_default.writeFile(destFp, srcData);
|
|
92023
92042
|
}
|
|
92024
92043
|
}
|
|
92025
92044
|
/**
|
|
92026
|
-
* Clone a file using copy-on-write if supported (
|
|
92027
|
-
* Falls back to regular copy if CoW is not available.
|
|
92045
|
+
* Clone a file using copy-on-write if supported (Linux btrfs/xfs).
|
|
92046
|
+
* Falls back to regular copy if CoW is not available. libuv has no clonefile on macOS, so
|
|
92047
|
+
* there it is always a full copy.
|
|
92028
92048
|
*
|
|
92029
92049
|
* Replaces the destination rather than writing through it - see {@link unlinkDest}.
|
|
92030
92050
|
*
|
|
@@ -92033,8 +92053,7 @@ async function copyFile(srcFp, destFp) {
|
|
|
92033
92053
|
* @returns
|
|
92034
92054
|
*/
|
|
92035
92055
|
async function cloneFile(srcFp, destFp) {
|
|
92036
|
-
|
|
92037
|
-
return fs.promises.copyFile(srcFp, destFp, fs.constants.COPYFILE_FICLONE);
|
|
92056
|
+
return copyNew(srcFp, destFp, fs.constants.COPYFILE_FICLONE);
|
|
92038
92057
|
}
|
|
92039
92058
|
async function prepDestDir(dest) {
|
|
92040
92059
|
const statDest = await tryCatch(() => file_ops_default.lstat(dest));
|
|
@@ -94791,12 +94810,8 @@ var PkgSrcManager = class {
|
|
|
94791
94810
|
if (hasCentral) {
|
|
94792
94811
|
if (!await central.validate(integrity)) {
|
|
94793
94812
|
const contentPath = await central.getContentPath(integrity);
|
|
94794
|
-
logger$1.
|
|
94795
|
-
|
|
94796
|
-
ID: ${verId}
|
|
94797
|
-
integrity: ${integrity}
|
|
94798
|
-
path: '${contentPath}'
|
|
94799
|
-
`);
|
|
94813
|
+
logger$1.info(`central store copy of ${dispId} has changed, likely from an edit under a project's node_modules. fyn is replacing it with a clean copy. Projects installed earlier keep their edited files.`);
|
|
94814
|
+
logger$1.debug(`replacing central store package ${verId} integrity ${integrity} at '${contentPath}'`);
|
|
94800
94815
|
await central.delete(integrity);
|
|
94801
94816
|
hasCentral = false;
|
|
94802
94817
|
}
|
|
@@ -96917,6 +96932,14 @@ const { missPipe } = fyntil;
|
|
|
96917
96932
|
function isTreeFileContent(obj) {
|
|
96918
96933
|
return typeof obj === "object" && obj !== null && "_" in obj && typeof obj._ === "number";
|
|
96919
96934
|
}
|
|
96935
|
+
/** link errors that mean the filesystem can't hardlink from the store at all */
|
|
96936
|
+
const NO_LINK_CODES = [
|
|
96937
|
+
"EXDEV",
|
|
96938
|
+
"EPERM",
|
|
96939
|
+
"ENOTSUP",
|
|
96940
|
+
"EOPNOTSUPP",
|
|
96941
|
+
"ENOSYS"
|
|
96942
|
+
];
|
|
96920
96943
|
/**
|
|
96921
96944
|
* Convert a directory tree structure to a flatten one like:
|
|
96922
96945
|
* ```
|
|
@@ -96954,9 +96977,11 @@ function flattenTree(tree, output, baseDir) {
|
|
|
96954
96977
|
var FynCentral = class {
|
|
96955
96978
|
_centralDir;
|
|
96956
96979
|
_map;
|
|
96957
|
-
|
|
96980
|
+
_hardlink;
|
|
96981
|
+
constructor({ centralDir = ".fyn/_central-storage", hardlink = true } = {}) {
|
|
96958
96982
|
this._centralDir = Path.resolve(centralDir);
|
|
96959
96983
|
this._map = /* @__PURE__ */ new Map();
|
|
96984
|
+
this._hardlink = hardlink;
|
|
96960
96985
|
}
|
|
96961
96986
|
_analyze(integrity) {
|
|
96962
96987
|
const sri = import_lib$1.default.parse(integrity, { single: true });
|
|
@@ -97129,13 +97154,32 @@ var FynCentral = class {
|
|
|
97129
97154
|
const src = Path.join(info.contentPath, "package", file);
|
|
97130
97155
|
const dest = Path.join(destDir, file);
|
|
97131
97156
|
if (file === "package.json") return copyFile(src, dest);
|
|
97132
|
-
return cloneFile(src, dest);
|
|
97157
|
+
return this._hardlink ? this._linkFile(src, dest) : cloneFile(src, dest);
|
|
97133
97158
|
}, { concurrency: 5 });
|
|
97134
97159
|
} catch (err) {
|
|
97135
97160
|
const msg = `fyn-central can't replicate package at ${destDir} for integrity ${integrity}`;
|
|
97136
97161
|
throw new AggregateError$1([err], msg);
|
|
97137
97162
|
}
|
|
97138
97163
|
}
|
|
97164
|
+
/**
|
|
97165
|
+
* Hardlink a file from the store, or clone it where the filesystem can't link it, such as a
|
|
97166
|
+
* store on another volume. That failure turns linking off for the rest of the run.
|
|
97167
|
+
*/
|
|
97168
|
+
async _linkFile(src, dest) {
|
|
97169
|
+
try {
|
|
97170
|
+
await linkFile(src, dest);
|
|
97171
|
+
return;
|
|
97172
|
+
} catch (err) {
|
|
97173
|
+
const code = err.code;
|
|
97174
|
+
if (NO_LINK_CODES.includes(code)) {
|
|
97175
|
+
if (this._hardlink) {
|
|
97176
|
+
this._hardlink = false;
|
|
97177
|
+
logger$1.info(`fyn-central: can't hardlink from ${this._centralDir} (${code}), copying instead`);
|
|
97178
|
+
}
|
|
97179
|
+
} else if (code !== "EMLINK") throw err;
|
|
97180
|
+
}
|
|
97181
|
+
await cloneFile(src, dest);
|
|
97182
|
+
}
|
|
97139
97183
|
_untarStream(tarStream, targetDir) {
|
|
97140
97184
|
const newDirObj = () => {
|
|
97141
97185
|
const n = Object.create(null);
|
|
@@ -101514,7 +101558,10 @@ var Fyn = class Fyn {
|
|
|
101514
101558
|
}
|
|
101515
101559
|
logger$1.info(`Enabling central store by fynpo monorepo using dir ${centralDir}`);
|
|
101516
101560
|
}
|
|
101517
|
-
return this._central = new FynCentral({
|
|
101561
|
+
return this._central = new FynCentral({
|
|
101562
|
+
centralDir,
|
|
101563
|
+
hardlink: this.hardlink
|
|
101564
|
+
});
|
|
101518
101565
|
}
|
|
101519
101566
|
async _initialize({ noLock = false } = {}) {
|
|
101520
101567
|
await this._initializePkg();
|
|
@@ -101841,6 +101888,7 @@ var Fyn = class Fyn {
|
|
|
101841
101888
|
fynlocal: Boolean(this.fynlocal),
|
|
101842
101889
|
layout: this._options.layout,
|
|
101843
101890
|
shortPkgDir: this._shortPkgDir,
|
|
101891
|
+
hardlink: this.hardlink,
|
|
101844
101892
|
blockedScripts: this._blockedScripts || this._installConfig.blockedScripts || [],
|
|
101845
101893
|
pendingScripts: this._pendingScripts || this._installConfig.pendingScripts || []
|
|
101846
101894
|
};
|
|
@@ -102098,6 +102146,16 @@ var Fyn = class Fyn {
|
|
|
102098
102146
|
get production() {
|
|
102099
102147
|
return this._options.production;
|
|
102100
102148
|
}
|
|
102149
|
+
/**
|
|
102150
|
+
* Whether the central store hardlinks files into node_modules. --no-hardlink or
|
|
102151
|
+
* FYN_HARDLINK=false turns it off, and .fyn.json keeps the choice for later installs.
|
|
102152
|
+
* Precedence: CLI or rc, then env, then .fyn.json, then on.
|
|
102153
|
+
*/
|
|
102154
|
+
get hardlink() {
|
|
102155
|
+
if (this._options.hardlink !== void 0) return this._options.hardlink !== false;
|
|
102156
|
+
if (process.env.FYN_HARDLINK !== void 0) return fyntil.strToBool(process.env.FYN_HARDLINK);
|
|
102157
|
+
return this._installConfig.hardlink !== false;
|
|
102158
|
+
}
|
|
102101
102159
|
get concurrency() {
|
|
102102
102160
|
return this._options.concurrency;
|
|
102103
102161
|
}
|
|
@@ -116270,7 +116328,10 @@ const pickOptions = async (cmd, checkFynpo = true) => {
|
|
|
116270
116328
|
return {
|
|
116271
116329
|
opts: allOpts,
|
|
116272
116330
|
rcData,
|
|
116273
|
-
_cliSource:
|
|
116331
|
+
_cliSource: {
|
|
116332
|
+
...cmd.rootCmd?.jsonMeta.source,
|
|
116333
|
+
...meta.source
|
|
116334
|
+
},
|
|
116274
116335
|
_fynpo: fynpo
|
|
116275
116336
|
};
|
|
116276
116337
|
};
|
|
@@ -116332,6 +116393,10 @@ const options = {
|
|
|
116332
116393
|
desc: "keep single copy of packages in central store",
|
|
116333
116394
|
argDefault: "false"
|
|
116334
116395
|
},
|
|
116396
|
+
hardlink: {
|
|
116397
|
+
args: "<flag boolean>",
|
|
116398
|
+
desc: "hardlink central store files into node_modules (default). --no-hardlink copies them, and is remembered"
|
|
116399
|
+
},
|
|
116335
116400
|
copy: {
|
|
116336
116401
|
args: "[packages string..]",
|
|
116337
116402
|
alias: "cp",
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fyn",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "3.2.
|
|
4
|
+
"version": "3.2.2",
|
|
5
5
|
"description": "fyn is a node.js package manager, and supports fynpo -- a zero setup monorepo tool",
|
|
6
6
|
"main": "./bin/index.mjs",
|
|
7
7
|
"homepage": "https://github.com/jchip/fynjs/tree/main/packages/fyn",
|