@olegkuibar/plunk 0.2.0-canary.04ff96f
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/LICENSE +21 -0
- package/README.md +95 -0
- package/dist/add-5ZRFUL6Z.mjs +258 -0
- package/dist/chokidar-XGAEDN45.mjs +1746 -0
- package/dist/chunk-34UXZ622.mjs +98 -0
- package/dist/chunk-4O2QOKVO.mjs +1958 -0
- package/dist/chunk-CSMZ6DZA.mjs +367 -0
- package/dist/chunk-CZM4TNAI.mjs +292 -0
- package/dist/chunk-EDUXIQ5W.mjs +1729 -0
- package/dist/chunk-GAAB2TLH.mjs +160 -0
- package/dist/chunk-HKNM3UWU.mjs +496 -0
- package/dist/chunk-I6SN7BBN.mjs +1131 -0
- package/dist/chunk-KYDBD2KQ.mjs +39 -0
- package/dist/chunk-LKQINKH4.mjs +130 -0
- package/dist/chunk-PUSXMPOF.mjs +82 -0
- package/dist/chunk-S4HJSJ32.mjs +69 -0
- package/dist/chunk-W3C72UKC.mjs +113 -0
- package/dist/chunk-WSECI6M7.mjs +85 -0
- package/dist/chunk-XMIZ7OUZ.mjs +26 -0
- package/dist/chunk-XZK5T4GK.mjs +23 -0
- package/dist/chunk-ZOYNYK5Y.mjs +23 -0
- package/dist/chunk-ZQCGJUBJ.mjs +92 -0
- package/dist/clean-LTR5MZTY.mjs +84 -0
- package/dist/cli.mjs +57 -0
- package/dist/dev-LFXQP6SA.mjs +194 -0
- package/dist/dist-DUFCZSIL.mjs +813 -0
- package/dist/doctor-R7ZVR7PY.mjs +230 -0
- package/dist/hash-worker.mjs +65 -0
- package/dist/index.d.ts +194 -0
- package/dist/index.mjs +9486 -0
- package/dist/init-SWCNRISY.mjs +310 -0
- package/dist/list-B77L2F34.mjs +119 -0
- package/dist/migrate-X5TIC5SS.mjs +124 -0
- package/dist/prompt-HTPH6HQ7.mjs +756 -0
- package/dist/publish-UXCLPNM6.mjs +63 -0
- package/dist/push-JI6HGCFG.mjs +197 -0
- package/dist/remove-DCR7KKD5.mjs +149 -0
- package/dist/restore-SUN3WGSW.mjs +124 -0
- package/dist/status-MESRBH54.mjs +103 -0
- package/dist/tailwind-source-JBBEIXIJ.mjs +89 -0
- package/dist/update-SKDSA673.mjs +100 -0
- package/dist/vite-config-BAK67JHB.mjs +128 -0
- package/dist/vite-plugin.d.ts +5 -0
- package/dist/vite-plugin.mjs +42 -0
- package/dist/workspace-76HJPAK2.mjs +97 -0
- package/package.json +96 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import{createRequire as __cr}from"node:module";globalThis.require=__cr(import.meta.url);
|
|
3
|
+
import {
|
|
4
|
+
getConsumerPlunkDir,
|
|
5
|
+
getConsumerStatePath,
|
|
6
|
+
getConsumersPath,
|
|
7
|
+
isConsumerState,
|
|
8
|
+
isConsumersRegistry,
|
|
9
|
+
withFileLock
|
|
10
|
+
} from "./chunk-EDUXIQ5W.mjs";
|
|
11
|
+
import {
|
|
12
|
+
atomicWriteFile,
|
|
13
|
+
ensureDir,
|
|
14
|
+
ensurePrivateDir,
|
|
15
|
+
exists,
|
|
16
|
+
isNodeError
|
|
17
|
+
} from "./chunk-HKNM3UWU.mjs";
|
|
18
|
+
import {
|
|
19
|
+
consola
|
|
20
|
+
} from "./chunk-I6SN7BBN.mjs";
|
|
21
|
+
|
|
22
|
+
// src/core/tracker.ts
|
|
23
|
+
import { readFile } from "fs/promises";
|
|
24
|
+
import { dirname } from "path";
|
|
25
|
+
async function readConsumerState(consumerPath) {
|
|
26
|
+
const statePath = getConsumerStatePath(consumerPath);
|
|
27
|
+
try {
|
|
28
|
+
const content = await readFile(statePath, "utf-8");
|
|
29
|
+
const parsed = JSON.parse(content);
|
|
30
|
+
if (!isConsumerState(parsed)) {
|
|
31
|
+
consola.warn(`Invalid consumer state in ${statePath}, using defaults`);
|
|
32
|
+
return { version: "1", links: {} };
|
|
33
|
+
}
|
|
34
|
+
return parsed;
|
|
35
|
+
} catch (err) {
|
|
36
|
+
if (isNodeError(err) && err.code !== "ENOENT") {
|
|
37
|
+
consola.warn(`Failed to read consumer state: ${err}`);
|
|
38
|
+
}
|
|
39
|
+
return { version: "1", links: {} };
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
async function writeConsumerState(consumerPath, state) {
|
|
43
|
+
await ensureDir(getConsumerPlunkDir(consumerPath));
|
|
44
|
+
const statePath = getConsumerStatePath(consumerPath);
|
|
45
|
+
await atomicWriteFile(statePath, JSON.stringify(state, null, 2));
|
|
46
|
+
}
|
|
47
|
+
async function addLink(consumerPath, packageName, entry) {
|
|
48
|
+
const statePath = getConsumerStatePath(consumerPath);
|
|
49
|
+
await withFileLock(statePath, async () => {
|
|
50
|
+
const state = await readConsumerState(consumerPath);
|
|
51
|
+
state.links[packageName] = entry;
|
|
52
|
+
await writeConsumerState(consumerPath, state);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
async function removeLink(consumerPath, packageName) {
|
|
56
|
+
const statePath = getConsumerStatePath(consumerPath);
|
|
57
|
+
await withFileLock(statePath, async () => {
|
|
58
|
+
const state = await readConsumerState(consumerPath);
|
|
59
|
+
delete state.links[packageName];
|
|
60
|
+
await writeConsumerState(consumerPath, state);
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
async function getLink(consumerPath, packageName) {
|
|
64
|
+
const state = await readConsumerState(consumerPath);
|
|
65
|
+
return state.links[packageName] ?? null;
|
|
66
|
+
}
|
|
67
|
+
async function readConsumersRegistry() {
|
|
68
|
+
const regPath = getConsumersPath();
|
|
69
|
+
try {
|
|
70
|
+
const content = await readFile(regPath, "utf-8");
|
|
71
|
+
const parsed = JSON.parse(content);
|
|
72
|
+
if (!isConsumersRegistry(parsed)) {
|
|
73
|
+
consola.warn(`Invalid consumers registry, using empty registry`);
|
|
74
|
+
return {};
|
|
75
|
+
}
|
|
76
|
+
return parsed;
|
|
77
|
+
} catch (err) {
|
|
78
|
+
if (isNodeError(err) && err.code !== "ENOENT") {
|
|
79
|
+
consola.warn(`Failed to read consumers registry: ${err}`);
|
|
80
|
+
}
|
|
81
|
+
return {};
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
async function writeConsumersRegistry(registry) {
|
|
85
|
+
const regPath = getConsumersPath();
|
|
86
|
+
await ensurePrivateDir(dirname(getConsumersPath()));
|
|
87
|
+
await atomicWriteFile(regPath, JSON.stringify(registry, null, 2));
|
|
88
|
+
}
|
|
89
|
+
async function registerConsumer(packageName, consumerPath) {
|
|
90
|
+
const regPath = getConsumersPath();
|
|
91
|
+
await withFileLock(regPath, async () => {
|
|
92
|
+
const registry = await readConsumersRegistry();
|
|
93
|
+
if (!registry[packageName]) {
|
|
94
|
+
registry[packageName] = [];
|
|
95
|
+
}
|
|
96
|
+
const normalized = consumerPath.replace(/\\/g, "/");
|
|
97
|
+
if (!registry[packageName].includes(normalized)) {
|
|
98
|
+
registry[packageName].push(normalized);
|
|
99
|
+
}
|
|
100
|
+
await writeConsumersRegistry(registry);
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
async function unregisterConsumer(packageName, consumerPath) {
|
|
104
|
+
const regPath = getConsumersPath();
|
|
105
|
+
await withFileLock(regPath, async () => {
|
|
106
|
+
const registry = await readConsumersRegistry();
|
|
107
|
+
if (!registry[packageName]) return;
|
|
108
|
+
const normalized = consumerPath.replace(/\\/g, "/");
|
|
109
|
+
registry[packageName] = registry[packageName].filter(
|
|
110
|
+
(p) => p !== normalized
|
|
111
|
+
);
|
|
112
|
+
if (registry[packageName].length === 0) {
|
|
113
|
+
delete registry[packageName];
|
|
114
|
+
}
|
|
115
|
+
await writeConsumersRegistry(registry);
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
async function getConsumers(packageName) {
|
|
119
|
+
const registry = await readConsumersRegistry();
|
|
120
|
+
return registry[packageName] ?? [];
|
|
121
|
+
}
|
|
122
|
+
async function cleanStaleConsumers() {
|
|
123
|
+
const regPath = getConsumersPath();
|
|
124
|
+
let removedConsumers = 0;
|
|
125
|
+
let removedPackages = 0;
|
|
126
|
+
await withFileLock(regPath, async () => {
|
|
127
|
+
const registry = await readConsumersRegistry();
|
|
128
|
+
const updated = {};
|
|
129
|
+
for (const [pkgName, consumers] of Object.entries(registry)) {
|
|
130
|
+
const validConsumers = [];
|
|
131
|
+
for (const consumerPath of consumers) {
|
|
132
|
+
if (await exists(consumerPath)) {
|
|
133
|
+
validConsumers.push(consumerPath);
|
|
134
|
+
} else {
|
|
135
|
+
removedConsumers++;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
if (validConsumers.length > 0) {
|
|
139
|
+
updated[pkgName] = validConsumers;
|
|
140
|
+
} else {
|
|
141
|
+
removedPackages++;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
await writeConsumersRegistry(updated);
|
|
145
|
+
});
|
|
146
|
+
return { removedConsumers, removedPackages };
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export {
|
|
150
|
+
readConsumerState,
|
|
151
|
+
writeConsumerState,
|
|
152
|
+
addLink,
|
|
153
|
+
removeLink,
|
|
154
|
+
getLink,
|
|
155
|
+
readConsumersRegistry,
|
|
156
|
+
registerConsumer,
|
|
157
|
+
unregisterConsumer,
|
|
158
|
+
getConsumers,
|
|
159
|
+
cleanStaleConsumers
|
|
160
|
+
};
|
|
@@ -0,0 +1,496 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import{createRequire as __cr}from"node:module";globalThis.require=__cr(import.meta.url);
|
|
3
|
+
import {
|
|
4
|
+
isDryRun,
|
|
5
|
+
verbose
|
|
6
|
+
} from "./chunk-I6SN7BBN.mjs";
|
|
7
|
+
|
|
8
|
+
// node_modules/.pnpm/yocto-queue@1.2.2/node_modules/yocto-queue/index.js
|
|
9
|
+
var Node = class {
|
|
10
|
+
value;
|
|
11
|
+
next;
|
|
12
|
+
constructor(value) {
|
|
13
|
+
this.value = value;
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
var Queue = class {
|
|
17
|
+
#head;
|
|
18
|
+
#tail;
|
|
19
|
+
#size;
|
|
20
|
+
constructor() {
|
|
21
|
+
this.clear();
|
|
22
|
+
}
|
|
23
|
+
enqueue(value) {
|
|
24
|
+
const node = new Node(value);
|
|
25
|
+
if (this.#head) {
|
|
26
|
+
this.#tail.next = node;
|
|
27
|
+
this.#tail = node;
|
|
28
|
+
} else {
|
|
29
|
+
this.#head = node;
|
|
30
|
+
this.#tail = node;
|
|
31
|
+
}
|
|
32
|
+
this.#size++;
|
|
33
|
+
}
|
|
34
|
+
dequeue() {
|
|
35
|
+
const current = this.#head;
|
|
36
|
+
if (!current) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
this.#head = this.#head.next;
|
|
40
|
+
this.#size--;
|
|
41
|
+
if (!this.#head) {
|
|
42
|
+
this.#tail = void 0;
|
|
43
|
+
}
|
|
44
|
+
return current.value;
|
|
45
|
+
}
|
|
46
|
+
peek() {
|
|
47
|
+
if (!this.#head) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
return this.#head.value;
|
|
51
|
+
}
|
|
52
|
+
clear() {
|
|
53
|
+
this.#head = void 0;
|
|
54
|
+
this.#tail = void 0;
|
|
55
|
+
this.#size = 0;
|
|
56
|
+
}
|
|
57
|
+
get size() {
|
|
58
|
+
return this.#size;
|
|
59
|
+
}
|
|
60
|
+
*[Symbol.iterator]() {
|
|
61
|
+
let current = this.#head;
|
|
62
|
+
while (current) {
|
|
63
|
+
yield current.value;
|
|
64
|
+
current = current.next;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
*drain() {
|
|
68
|
+
while (this.#head) {
|
|
69
|
+
yield this.dequeue();
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
// node_modules/.pnpm/p-limit@7.3.0/node_modules/p-limit/index.js
|
|
75
|
+
function pLimit(concurrency) {
|
|
76
|
+
let rejectOnClear = false;
|
|
77
|
+
if (typeof concurrency === "object") {
|
|
78
|
+
({ concurrency, rejectOnClear = false } = concurrency);
|
|
79
|
+
}
|
|
80
|
+
validateConcurrency(concurrency);
|
|
81
|
+
if (typeof rejectOnClear !== "boolean") {
|
|
82
|
+
throw new TypeError("Expected `rejectOnClear` to be a boolean");
|
|
83
|
+
}
|
|
84
|
+
const queue = new Queue();
|
|
85
|
+
let activeCount = 0;
|
|
86
|
+
const resumeNext = () => {
|
|
87
|
+
if (activeCount < concurrency && queue.size > 0) {
|
|
88
|
+
activeCount++;
|
|
89
|
+
queue.dequeue().run();
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
const next = () => {
|
|
93
|
+
activeCount--;
|
|
94
|
+
resumeNext();
|
|
95
|
+
};
|
|
96
|
+
const run = async (function_, resolve, arguments_) => {
|
|
97
|
+
const result = (async () => function_(...arguments_))();
|
|
98
|
+
resolve(result);
|
|
99
|
+
try {
|
|
100
|
+
await result;
|
|
101
|
+
} catch {
|
|
102
|
+
}
|
|
103
|
+
next();
|
|
104
|
+
};
|
|
105
|
+
const enqueue = (function_, resolve, reject, arguments_) => {
|
|
106
|
+
const queueItem = { reject };
|
|
107
|
+
new Promise((internalResolve) => {
|
|
108
|
+
queueItem.run = internalResolve;
|
|
109
|
+
queue.enqueue(queueItem);
|
|
110
|
+
}).then(run.bind(void 0, function_, resolve, arguments_));
|
|
111
|
+
if (activeCount < concurrency) {
|
|
112
|
+
resumeNext();
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
const generator = (function_, ...arguments_) => new Promise((resolve, reject) => {
|
|
116
|
+
enqueue(function_, resolve, reject, arguments_);
|
|
117
|
+
});
|
|
118
|
+
Object.defineProperties(generator, {
|
|
119
|
+
activeCount: {
|
|
120
|
+
get: () => activeCount
|
|
121
|
+
},
|
|
122
|
+
pendingCount: {
|
|
123
|
+
get: () => queue.size
|
|
124
|
+
},
|
|
125
|
+
clearQueue: {
|
|
126
|
+
value() {
|
|
127
|
+
if (!rejectOnClear) {
|
|
128
|
+
queue.clear();
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
const abortError = AbortSignal.abort().reason;
|
|
132
|
+
while (queue.size > 0) {
|
|
133
|
+
queue.dequeue().reject(abortError);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
concurrency: {
|
|
138
|
+
get: () => concurrency,
|
|
139
|
+
set(newConcurrency) {
|
|
140
|
+
validateConcurrency(newConcurrency);
|
|
141
|
+
concurrency = newConcurrency;
|
|
142
|
+
queueMicrotask(() => {
|
|
143
|
+
while (activeCount < concurrency && queue.size > 0) {
|
|
144
|
+
resumeNext();
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
map: {
|
|
150
|
+
async value(iterable, function_) {
|
|
151
|
+
const promises = Array.from(iterable, (value, index) => this(function_, value, index));
|
|
152
|
+
return Promise.all(promises);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
return generator;
|
|
157
|
+
}
|
|
158
|
+
function validateConcurrency(concurrency) {
|
|
159
|
+
if (!((Number.isInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency > 0)) {
|
|
160
|
+
throw new TypeError("Expected `concurrency` to be a number from 1 and up");
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// src/utils/fs.ts
|
|
165
|
+
import {
|
|
166
|
+
copyFile,
|
|
167
|
+
cp,
|
|
168
|
+
mkdir,
|
|
169
|
+
readdir,
|
|
170
|
+
rename,
|
|
171
|
+
rm,
|
|
172
|
+
stat as stat2,
|
|
173
|
+
writeFile,
|
|
174
|
+
constants
|
|
175
|
+
} from "fs/promises";
|
|
176
|
+
import { join, dirname, relative as relative2, parse as parsePath } from "path";
|
|
177
|
+
import { availableParallelism as availableParallelism2 } from "os";
|
|
178
|
+
|
|
179
|
+
// src/utils/hash.ts
|
|
180
|
+
import { createHash } from "crypto";
|
|
181
|
+
import { createReadStream } from "fs";
|
|
182
|
+
import { readFile, stat } from "fs/promises";
|
|
183
|
+
import { relative } from "path";
|
|
184
|
+
import { availableParallelism } from "os";
|
|
185
|
+
|
|
186
|
+
// node_modules/.pnpm/xxhash-wasm@1.1.0/node_modules/xxhash-wasm/esm/xxhash-wasm.js
|
|
187
|
+
var t = new Uint8Array([0, 97, 115, 109, 1, 0, 0, 0, 1, 48, 8, 96, 3, 127, 127, 127, 1, 127, 96, 3, 127, 127, 127, 0, 96, 2, 127, 127, 0, 96, 1, 127, 1, 127, 96, 3, 127, 127, 126, 1, 126, 96, 3, 126, 127, 127, 1, 126, 96, 2, 127, 126, 0, 96, 1, 127, 1, 126, 3, 11, 10, 0, 0, 2, 1, 3, 4, 5, 6, 1, 7, 5, 3, 1, 0, 1, 7, 85, 9, 3, 109, 101, 109, 2, 0, 5, 120, 120, 104, 51, 50, 0, 0, 6, 105, 110, 105, 116, 51, 50, 0, 2, 8, 117, 112, 100, 97, 116, 101, 51, 50, 0, 3, 8, 100, 105, 103, 101, 115, 116, 51, 50, 0, 4, 5, 120, 120, 104, 54, 52, 0, 5, 6, 105, 110, 105, 116, 54, 52, 0, 7, 8, 117, 112, 100, 97, 116, 101, 54, 52, 0, 8, 8, 100, 105, 103, 101, 115, 116, 54, 52, 0, 9, 10, 251, 22, 10, 242, 1, 1, 4, 127, 32, 0, 32, 1, 106, 33, 3, 32, 1, 65, 16, 79, 4, 127, 32, 3, 65, 16, 107, 33, 6, 32, 2, 65, 168, 136, 141, 161, 2, 106, 33, 3, 32, 2, 65, 137, 235, 208, 208, 7, 107, 33, 4, 32, 2, 65, 207, 140, 162, 142, 6, 106, 33, 5, 3, 64, 32, 3, 32, 0, 40, 2, 0, 65, 247, 148, 175, 175, 120, 108, 106, 65, 13, 119, 65, 177, 243, 221, 241, 121, 108, 33, 3, 32, 4, 32, 0, 65, 4, 106, 34, 0, 40, 2, 0, 65, 247, 148, 175, 175, 120, 108, 106, 65, 13, 119, 65, 177, 243, 221, 241, 121, 108, 33, 4, 32, 2, 32, 0, 65, 4, 106, 34, 0, 40, 2, 0, 65, 247, 148, 175, 175, 120, 108, 106, 65, 13, 119, 65, 177, 243, 221, 241, 121, 108, 33, 2, 32, 5, 32, 0, 65, 4, 106, 34, 0, 40, 2, 0, 65, 247, 148, 175, 175, 120, 108, 106, 65, 13, 119, 65, 177, 243, 221, 241, 121, 108, 33, 5, 32, 6, 32, 0, 65, 4, 106, 34, 0, 79, 13, 0, 11, 32, 2, 65, 12, 119, 32, 5, 65, 18, 119, 106, 32, 4, 65, 7, 119, 106, 32, 3, 65, 1, 119, 106, 5, 32, 2, 65, 177, 207, 217, 178, 1, 106, 11, 32, 1, 106, 32, 0, 32, 1, 65, 15, 113, 16, 1, 11, 146, 1, 0, 32, 1, 32, 2, 106, 33, 2, 3, 64, 32, 1, 65, 4, 106, 32, 2, 75, 69, 4, 64, 32, 0, 32, 1, 40, 2, 0, 65, 189, 220, 202, 149, 124, 108, 106, 65, 17, 119, 65, 175, 214, 211, 190, 2, 108, 33, 0, 32, 1, 65, 4, 106, 33, 1, 12, 1, 11, 11, 3, 64, 32, 1, 32, 2, 79, 69, 4, 64, 32, 0, 32, 1, 45, 0, 0, 65, 177, 207, 217, 178, 1, 108, 106, 65, 11, 119, 65, 177, 243, 221, 241, 121, 108, 33, 0, 32, 1, 65, 1, 106, 33, 1, 12, 1, 11, 11, 32, 0, 32, 0, 65, 15, 118, 115, 65, 247, 148, 175, 175, 120, 108, 34, 0, 65, 13, 118, 32, 0, 115, 65, 189, 220, 202, 149, 124, 108, 34, 0, 65, 16, 118, 32, 0, 115, 11, 63, 0, 32, 0, 65, 8, 106, 32, 1, 65, 168, 136, 141, 161, 2, 106, 54, 2, 0, 32, 0, 65, 12, 106, 32, 1, 65, 137, 235, 208, 208, 7, 107, 54, 2, 0, 32, 0, 65, 16, 106, 32, 1, 54, 2, 0, 32, 0, 65, 20, 106, 32, 1, 65, 207, 140, 162, 142, 6, 106, 54, 2, 0, 11, 195, 4, 1, 6, 127, 32, 1, 32, 2, 106, 33, 6, 32, 0, 65, 24, 106, 33, 4, 32, 0, 65, 40, 106, 40, 2, 0, 33, 3, 32, 0, 32, 0, 40, 2, 0, 32, 2, 106, 54, 2, 0, 32, 0, 65, 4, 106, 34, 5, 32, 5, 40, 2, 0, 32, 2, 65, 16, 79, 32, 0, 40, 2, 0, 65, 16, 79, 114, 114, 54, 2, 0, 32, 2, 32, 3, 106, 65, 16, 73, 4, 64, 32, 3, 32, 4, 106, 32, 1, 32, 2, 252, 10, 0, 0, 32, 0, 65, 40, 106, 32, 2, 32, 3, 106, 54, 2, 0, 15, 11, 32, 3, 4, 64, 32, 3, 32, 4, 106, 32, 1, 65, 16, 32, 3, 107, 34, 2, 252, 10, 0, 0, 32, 0, 65, 8, 106, 34, 3, 32, 3, 40, 2, 0, 32, 4, 40, 2, 0, 65, 247, 148, 175, 175, 120, 108, 106, 65, 13, 119, 65, 177, 243, 221, 241, 121, 108, 54, 2, 0, 32, 0, 65, 12, 106, 34, 3, 32, 3, 40, 2, 0, 32, 4, 65, 4, 106, 40, 2, 0, 65, 247, 148, 175, 175, 120, 108, 106, 65, 13, 119, 65, 177, 243, 221, 241, 121, 108, 54, 2, 0, 32, 0, 65, 16, 106, 34, 3, 32, 3, 40, 2, 0, 32, 4, 65, 8, 106, 40, 2, 0, 65, 247, 148, 175, 175, 120, 108, 106, 65, 13, 119, 65, 177, 243, 221, 241, 121, 108, 54, 2, 0, 32, 0, 65, 20, 106, 34, 3, 32, 3, 40, 2, 0, 32, 4, 65, 12, 106, 40, 2, 0, 65, 247, 148, 175, 175, 120, 108, 106, 65, 13, 119, 65, 177, 243, 221, 241, 121, 108, 54, 2, 0, 32, 0, 65, 40, 106, 65, 0, 54, 2, 0, 32, 1, 32, 2, 106, 33, 1, 11, 32, 1, 32, 6, 65, 16, 107, 77, 4, 64, 32, 6, 65, 16, 107, 33, 8, 32, 0, 65, 8, 106, 40, 2, 0, 33, 2, 32, 0, 65, 12, 106, 40, 2, 0, 33, 3, 32, 0, 65, 16, 106, 40, 2, 0, 33, 5, 32, 0, 65, 20, 106, 40, 2, 0, 33, 7, 3, 64, 32, 2, 32, 1, 40, 2, 0, 65, 247, 148, 175, 175, 120, 108, 106, 65, 13, 119, 65, 177, 243, 221, 241, 121, 108, 33, 2, 32, 3, 32, 1, 65, 4, 106, 34, 1, 40, 2, 0, 65, 247, 148, 175, 175, 120, 108, 106, 65, 13, 119, 65, 177, 243, 221, 241, 121, 108, 33, 3, 32, 5, 32, 1, 65, 4, 106, 34, 1, 40, 2, 0, 65, 247, 148, 175, 175, 120, 108, 106, 65, 13, 119, 65, 177, 243, 221, 241, 121, 108, 33, 5, 32, 7, 32, 1, 65, 4, 106, 34, 1, 40, 2, 0, 65, 247, 148, 175, 175, 120, 108, 106, 65, 13, 119, 65, 177, 243, 221, 241, 121, 108, 33, 7, 32, 8, 32, 1, 65, 4, 106, 34, 1, 79, 13, 0, 11, 32, 0, 65, 8, 106, 32, 2, 54, 2, 0, 32, 0, 65, 12, 106, 32, 3, 54, 2, 0, 32, 0, 65, 16, 106, 32, 5, 54, 2, 0, 32, 0, 65, 20, 106, 32, 7, 54, 2, 0, 11, 32, 1, 32, 6, 73, 4, 64, 32, 4, 32, 1, 32, 6, 32, 1, 107, 34, 1, 252, 10, 0, 0, 32, 0, 65, 40, 106, 32, 1, 54, 2, 0, 11, 11, 97, 1, 1, 127, 32, 0, 65, 16, 106, 40, 2, 0, 33, 1, 32, 0, 65, 4, 106, 40, 2, 0, 4, 127, 32, 1, 65, 12, 119, 32, 0, 65, 20, 106, 40, 2, 0, 65, 18, 119, 106, 32, 0, 65, 12, 106, 40, 2, 0, 65, 7, 119, 106, 32, 0, 65, 8, 106, 40, 2, 0, 65, 1, 119, 106, 5, 32, 1, 65, 177, 207, 217, 178, 1, 106, 11, 32, 0, 40, 2, 0, 106, 32, 0, 65, 24, 106, 32, 0, 65, 40, 106, 40, 2, 0, 16, 1, 11, 255, 3, 2, 3, 126, 1, 127, 32, 0, 32, 1, 106, 33, 6, 32, 1, 65, 32, 79, 4, 126, 32, 6, 65, 32, 107, 33, 6, 32, 2, 66, 214, 235, 130, 238, 234, 253, 137, 245, 224, 0, 124, 33, 3, 32, 2, 66, 177, 169, 172, 193, 173, 184, 212, 166, 61, 125, 33, 4, 32, 2, 66, 249, 234, 208, 208, 231, 201, 161, 228, 225, 0, 124, 33, 5, 3, 64, 32, 3, 32, 0, 41, 3, 0, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 124, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 33, 3, 32, 4, 32, 0, 65, 8, 106, 34, 0, 41, 3, 0, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 124, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 33, 4, 32, 2, 32, 0, 65, 8, 106, 34, 0, 41, 3, 0, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 124, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 33, 2, 32, 5, 32, 0, 65, 8, 106, 34, 0, 41, 3, 0, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 124, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 33, 5, 32, 6, 32, 0, 65, 8, 106, 34, 0, 79, 13, 0, 11, 32, 2, 66, 12, 137, 32, 5, 66, 18, 137, 124, 32, 4, 66, 7, 137, 124, 32, 3, 66, 1, 137, 124, 32, 3, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 133, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 66, 157, 163, 181, 234, 131, 177, 141, 138, 250, 0, 125, 32, 4, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 133, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 66, 157, 163, 181, 234, 131, 177, 141, 138, 250, 0, 125, 32, 2, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 133, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 66, 157, 163, 181, 234, 131, 177, 141, 138, 250, 0, 125, 32, 5, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 133, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 66, 157, 163, 181, 234, 131, 177, 141, 138, 250, 0, 125, 5, 32, 2, 66, 197, 207, 217, 178, 241, 229, 186, 234, 39, 124, 11, 32, 1, 173, 124, 32, 0, 32, 1, 65, 31, 113, 16, 6, 11, 134, 2, 0, 32, 1, 32, 2, 106, 33, 2, 3, 64, 32, 2, 32, 1, 65, 8, 106, 79, 4, 64, 32, 1, 41, 3, 0, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 32, 0, 133, 66, 27, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 66, 157, 163, 181, 234, 131, 177, 141, 138, 250, 0, 125, 33, 0, 32, 1, 65, 8, 106, 33, 1, 12, 1, 11, 11, 32, 1, 65, 4, 106, 32, 2, 77, 4, 64, 32, 0, 32, 1, 53, 2, 0, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 133, 66, 23, 137, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 66, 249, 243, 221, 241, 153, 246, 153, 171, 22, 124, 33, 0, 32, 1, 65, 4, 106, 33, 1, 11, 3, 64, 32, 1, 32, 2, 73, 4, 64, 32, 0, 32, 1, 49, 0, 0, 66, 197, 207, 217, 178, 241, 229, 186, 234, 39, 126, 133, 66, 11, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 33, 0, 32, 1, 65, 1, 106, 33, 1, 12, 1, 11, 11, 32, 0, 32, 0, 66, 33, 136, 133, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 34, 0, 32, 0, 66, 29, 136, 133, 66, 249, 243, 221, 241, 153, 246, 153, 171, 22, 126, 34, 0, 32, 0, 66, 32, 136, 133, 11, 77, 0, 32, 0, 65, 8, 106, 32, 1, 66, 214, 235, 130, 238, 234, 253, 137, 245, 224, 0, 124, 55, 3, 0, 32, 0, 65, 16, 106, 32, 1, 66, 177, 169, 172, 193, 173, 184, 212, 166, 61, 125, 55, 3, 0, 32, 0, 65, 24, 106, 32, 1, 55, 3, 0, 32, 0, 65, 32, 106, 32, 1, 66, 249, 234, 208, 208, 231, 201, 161, 228, 225, 0, 124, 55, 3, 0, 11, 244, 4, 2, 3, 127, 4, 126, 32, 1, 32, 2, 106, 33, 5, 32, 0, 65, 40, 106, 33, 4, 32, 0, 65, 200, 0, 106, 40, 2, 0, 33, 3, 32, 0, 32, 0, 41, 3, 0, 32, 2, 173, 124, 55, 3, 0, 32, 2, 32, 3, 106, 65, 32, 73, 4, 64, 32, 3, 32, 4, 106, 32, 1, 32, 2, 252, 10, 0, 0, 32, 0, 65, 200, 0, 106, 32, 2, 32, 3, 106, 54, 2, 0, 15, 11, 32, 3, 4, 64, 32, 3, 32, 4, 106, 32, 1, 65, 32, 32, 3, 107, 34, 2, 252, 10, 0, 0, 32, 0, 65, 8, 106, 34, 3, 32, 3, 41, 3, 0, 32, 4, 41, 3, 0, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 124, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 55, 3, 0, 32, 0, 65, 16, 106, 34, 3, 32, 3, 41, 3, 0, 32, 4, 65, 8, 106, 41, 3, 0, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 124, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 55, 3, 0, 32, 0, 65, 24, 106, 34, 3, 32, 3, 41, 3, 0, 32, 4, 65, 16, 106, 41, 3, 0, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 124, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 55, 3, 0, 32, 0, 65, 32, 106, 34, 3, 32, 3, 41, 3, 0, 32, 4, 65, 24, 106, 41, 3, 0, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 124, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 55, 3, 0, 32, 0, 65, 200, 0, 106, 65, 0, 54, 2, 0, 32, 1, 32, 2, 106, 33, 1, 11, 32, 1, 65, 32, 106, 32, 5, 77, 4, 64, 32, 5, 65, 32, 107, 33, 2, 32, 0, 65, 8, 106, 41, 3, 0, 33, 6, 32, 0, 65, 16, 106, 41, 3, 0, 33, 7, 32, 0, 65, 24, 106, 41, 3, 0, 33, 8, 32, 0, 65, 32, 106, 41, 3, 0, 33, 9, 3, 64, 32, 6, 32, 1, 41, 3, 0, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 124, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 33, 6, 32, 7, 32, 1, 65, 8, 106, 34, 1, 41, 3, 0, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 124, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 33, 7, 32, 8, 32, 1, 65, 8, 106, 34, 1, 41, 3, 0, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 124, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 33, 8, 32, 9, 32, 1, 65, 8, 106, 34, 1, 41, 3, 0, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 124, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 33, 9, 32, 2, 32, 1, 65, 8, 106, 34, 1, 79, 13, 0, 11, 32, 0, 65, 8, 106, 32, 6, 55, 3, 0, 32, 0, 65, 16, 106, 32, 7, 55, 3, 0, 32, 0, 65, 24, 106, 32, 8, 55, 3, 0, 32, 0, 65, 32, 106, 32, 9, 55, 3, 0, 11, 32, 1, 32, 5, 73, 4, 64, 32, 4, 32, 1, 32, 5, 32, 1, 107, 34, 1, 252, 10, 0, 0, 32, 0, 65, 200, 0, 106, 32, 1, 54, 2, 0, 11, 11, 188, 2, 1, 5, 126, 32, 0, 65, 24, 106, 41, 3, 0, 33, 1, 32, 0, 41, 3, 0, 34, 2, 66, 32, 90, 4, 126, 32, 0, 65, 8, 106, 41, 3, 0, 34, 3, 66, 1, 137, 32, 0, 65, 16, 106, 41, 3, 0, 34, 4, 66, 7, 137, 124, 32, 1, 66, 12, 137, 32, 0, 65, 32, 106, 41, 3, 0, 34, 5, 66, 18, 137, 124, 124, 32, 3, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 133, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 66, 157, 163, 181, 234, 131, 177, 141, 138, 250, 0, 125, 32, 4, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 133, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 66, 157, 163, 181, 234, 131, 177, 141, 138, 250, 0, 125, 32, 1, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 133, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 66, 157, 163, 181, 234, 131, 177, 141, 138, 250, 0, 125, 32, 5, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 133, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 66, 157, 163, 181, 234, 131, 177, 141, 138, 250, 0, 125, 5, 32, 1, 66, 197, 207, 217, 178, 241, 229, 186, 234, 39, 124, 11, 32, 2, 124, 32, 0, 65, 40, 106, 32, 2, 66, 31, 131, 167, 16, 6, 11]);
|
|
188
|
+
async function e() {
|
|
189
|
+
return (function(t2) {
|
|
190
|
+
const { exports: { mem: e2, xxh32: n, xxh64: r, init32: i, update32: a, digest32: o, init64: s, update64: u, digest64: c } } = t2;
|
|
191
|
+
let h = new Uint8Array(e2.buffer);
|
|
192
|
+
function g(t3, n2) {
|
|
193
|
+
if (e2.buffer.byteLength < t3 + n2) {
|
|
194
|
+
const r2 = Math.ceil((t3 + n2 - e2.buffer.byteLength) / 65536);
|
|
195
|
+
e2.grow(r2), h = new Uint8Array(e2.buffer);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
function f(t3, e3, n2, r2, i2, a2) {
|
|
199
|
+
g(t3);
|
|
200
|
+
const o2 = new Uint8Array(t3);
|
|
201
|
+
return h.set(o2), n2(0, e3), o2.set(h.subarray(0, t3)), { update(e4) {
|
|
202
|
+
let n3;
|
|
203
|
+
return h.set(o2), "string" == typeof e4 ? (g(3 * e4.length, t3), n3 = w.encodeInto(e4, h.subarray(t3)).written) : (g(e4.byteLength, t3), h.set(e4, t3), n3 = e4.byteLength), r2(0, t3, n3), o2.set(h.subarray(0, t3)), this;
|
|
204
|
+
}, digest: () => (h.set(o2), a2(i2(0))) };
|
|
205
|
+
}
|
|
206
|
+
function y(t3) {
|
|
207
|
+
return t3 >>> 0;
|
|
208
|
+
}
|
|
209
|
+
const b = 2n ** 64n - 1n;
|
|
210
|
+
function d(t3) {
|
|
211
|
+
return t3 & b;
|
|
212
|
+
}
|
|
213
|
+
const w = new TextEncoder(), l = 0, p = 0n;
|
|
214
|
+
function x(t3, e3 = l) {
|
|
215
|
+
return g(3 * t3.length, 0), y(n(0, w.encodeInto(t3, h).written, e3));
|
|
216
|
+
}
|
|
217
|
+
function L(t3, e3 = p) {
|
|
218
|
+
return g(3 * t3.length, 0), d(r(0, w.encodeInto(t3, h).written, e3));
|
|
219
|
+
}
|
|
220
|
+
return { h32: x, h32ToString: (t3, e3 = l) => x(t3, e3).toString(16).padStart(8, "0"), h32Raw: (t3, e3 = l) => (g(t3.byteLength, 0), h.set(t3), y(n(0, t3.byteLength, e3))), create32: (t3 = l) => f(48, t3, i, a, o, y), h64: L, h64ToString: (t3, e3 = p) => L(t3, e3).toString(16).padStart(16, "0"), h64Raw: (t3, e3 = p) => (g(t3.byteLength, 0), h.set(t3), d(r(0, t3.byteLength, e3))), create64: (t3 = p) => f(88, t3, s, u, c, d) };
|
|
221
|
+
})((await WebAssembly.instantiate(t)).instance);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// src/utils/hash.ts
|
|
225
|
+
var STREAM_THRESHOLD = 1024 * 1024;
|
|
226
|
+
var WORKER_THRESHOLD = 64 * 1024;
|
|
227
|
+
var limit = pLimit(Math.max(availableParallelism(), 8));
|
|
228
|
+
var xxh = null;
|
|
229
|
+
async function getXxhash() {
|
|
230
|
+
if (!xxh) xxh = await e();
|
|
231
|
+
return xxh;
|
|
232
|
+
}
|
|
233
|
+
var pool = null;
|
|
234
|
+
var poolFailed = false;
|
|
235
|
+
async function getPool() {
|
|
236
|
+
if (poolFailed) return null;
|
|
237
|
+
if (pool) return pool;
|
|
238
|
+
try {
|
|
239
|
+
const { default: Tinypool } = await import("./dist-DUFCZSIL.mjs");
|
|
240
|
+
const poolSize = Math.min(Math.max(availableParallelism(), 2), 8);
|
|
241
|
+
const workerUrl = new URL("./hash-worker.mjs", import.meta.url);
|
|
242
|
+
pool = new Tinypool({
|
|
243
|
+
filename: workerUrl.href,
|
|
244
|
+
minThreads: 0,
|
|
245
|
+
maxThreads: poolSize
|
|
246
|
+
});
|
|
247
|
+
verbose(`[hash] Worker pool initialized (max ${poolSize} threads)`);
|
|
248
|
+
return pool;
|
|
249
|
+
} catch {
|
|
250
|
+
poolFailed = true;
|
|
251
|
+
verbose("[hash] Worker pool unavailable, using main-thread hashing");
|
|
252
|
+
return null;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
process.on("exit", () => {
|
|
256
|
+
pool?.destroy();
|
|
257
|
+
});
|
|
258
|
+
async function computeContentHash(files, baseDir) {
|
|
259
|
+
const sorted = [...files].sort((a, b) => {
|
|
260
|
+
const relA = relative(baseDir, a).replace(/\\/g, "/");
|
|
261
|
+
const relB = relative(baseDir, b).replace(/\\/g, "/");
|
|
262
|
+
return relA.localeCompare(relB);
|
|
263
|
+
});
|
|
264
|
+
const contents = await Promise.all(
|
|
265
|
+
sorted.map(
|
|
266
|
+
(file) => limit(async () => ({
|
|
267
|
+
rel: relative(baseDir, file).replace(/\\/g, "/"),
|
|
268
|
+
content: await readFile(file)
|
|
269
|
+
}))
|
|
270
|
+
)
|
|
271
|
+
);
|
|
272
|
+
verbose(`[hash] Computing content hash for ${files.length} files`);
|
|
273
|
+
const hash = createHash("sha256");
|
|
274
|
+
for (const { rel, content } of contents) {
|
|
275
|
+
hash.update(rel);
|
|
276
|
+
hash.update("\0");
|
|
277
|
+
hash.update(content);
|
|
278
|
+
}
|
|
279
|
+
const result = "sha256:" + hash.digest("hex");
|
|
280
|
+
verbose(`[hash] Result: ${result.slice(0, 20)}...`);
|
|
281
|
+
return result;
|
|
282
|
+
}
|
|
283
|
+
async function hashFile(filePath, knownSize) {
|
|
284
|
+
const size = knownSize ?? (await stat(filePath)).size;
|
|
285
|
+
if (size <= WORKER_THRESHOLD) {
|
|
286
|
+
return hashFileMainThread(filePath, size);
|
|
287
|
+
}
|
|
288
|
+
const p = await getPool();
|
|
289
|
+
if (p) {
|
|
290
|
+
try {
|
|
291
|
+
return await p.run([filePath, size]);
|
|
292
|
+
} catch {
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
return hashFileMainThread(filePath, size);
|
|
296
|
+
}
|
|
297
|
+
async function hashFileMainThread(filePath, size) {
|
|
298
|
+
if (size > STREAM_THRESHOLD) {
|
|
299
|
+
return hashFileStream(filePath);
|
|
300
|
+
}
|
|
301
|
+
const { h64Raw } = await getXxhash();
|
|
302
|
+
const content = await readFile(filePath);
|
|
303
|
+
return h64Raw(content).toString(16);
|
|
304
|
+
}
|
|
305
|
+
function hashFileStream(filePath) {
|
|
306
|
+
return new Promise((resolve, reject) => {
|
|
307
|
+
const hash = createHash("sha256");
|
|
308
|
+
const stream = createReadStream(filePath);
|
|
309
|
+
stream.on("data", (chunk) => hash.update(chunk));
|
|
310
|
+
stream.on("end", () => resolve(hash.digest("hex")));
|
|
311
|
+
stream.on("error", reject);
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// src/utils/fs.ts
|
|
316
|
+
var ioLimit = pLimit(Math.max(availableParallelism2(), 8));
|
|
317
|
+
function isNodeError(err) {
|
|
318
|
+
return err instanceof Error && "code" in err;
|
|
319
|
+
}
|
|
320
|
+
var reflinkSupported = /* @__PURE__ */ new Map();
|
|
321
|
+
function volumeRoot(filePath) {
|
|
322
|
+
const { root } = parsePath(filePath);
|
|
323
|
+
return root || "/";
|
|
324
|
+
}
|
|
325
|
+
async function copyWithCoW(src, dest) {
|
|
326
|
+
if (isDryRun()) {
|
|
327
|
+
verbose(`[dry-run] would copy ${src} \u2192 ${dest}`);
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
await mkdir(dirname(dest), { recursive: true });
|
|
331
|
+
const root = volumeRoot(dest);
|
|
332
|
+
const supportsReflink = reflinkSupported.get(root);
|
|
333
|
+
if (supportsReflink === false) {
|
|
334
|
+
await copyFile(src, dest);
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
if (supportsReflink === true) {
|
|
338
|
+
await copyFile(src, dest, constants.COPYFILE_FICLONE);
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
try {
|
|
342
|
+
await copyFile(src, dest, constants.COPYFILE_FICLONE_FORCE);
|
|
343
|
+
reflinkSupported.set(root, true);
|
|
344
|
+
} catch {
|
|
345
|
+
reflinkSupported.set(root, false);
|
|
346
|
+
verbose(`[copy] reflink not supported on ${root}, using plain copy`);
|
|
347
|
+
await copyFile(src, dest);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
async function collectFiles(dir) {
|
|
351
|
+
const entries = await readdir(dir, { recursive: true });
|
|
352
|
+
const results = await Promise.all(
|
|
353
|
+
entries.map(
|
|
354
|
+
(entry) => ioLimit(async () => {
|
|
355
|
+
const full = join(dir, entry);
|
|
356
|
+
try {
|
|
357
|
+
const s = await stat2(full);
|
|
358
|
+
return s.isFile() ? full : null;
|
|
359
|
+
} catch {
|
|
360
|
+
return null;
|
|
361
|
+
}
|
|
362
|
+
})
|
|
363
|
+
)
|
|
364
|
+
);
|
|
365
|
+
return results.filter((f) => f !== null);
|
|
366
|
+
}
|
|
367
|
+
async function incrementalCopy(srcDir, destDir) {
|
|
368
|
+
const srcFiles = await collectFiles(srcDir);
|
|
369
|
+
let copied = 0;
|
|
370
|
+
let removed = 0;
|
|
371
|
+
let skipped = 0;
|
|
372
|
+
const results = await Promise.all(
|
|
373
|
+
srcFiles.map(
|
|
374
|
+
(srcFile) => ioLimit(async () => {
|
|
375
|
+
const rel = relative2(srcDir, srcFile);
|
|
376
|
+
const destFile = join(destDir, rel);
|
|
377
|
+
let needsCopy = true;
|
|
378
|
+
try {
|
|
379
|
+
const [srcStat, destStat] = await Promise.all([
|
|
380
|
+
stat2(srcFile),
|
|
381
|
+
stat2(destFile)
|
|
382
|
+
]);
|
|
383
|
+
if (srcStat.size !== destStat.size) {
|
|
384
|
+
verbose(`[copy] ${rel} (size differs: ${srcStat.size} vs ${destStat.size})`);
|
|
385
|
+
} else {
|
|
386
|
+
const [srcHash, destHash] = await Promise.all([
|
|
387
|
+
hashFile(srcFile, srcStat.size),
|
|
388
|
+
hashFile(destFile, destStat.size)
|
|
389
|
+
]);
|
|
390
|
+
if (srcHash === destHash) {
|
|
391
|
+
needsCopy = false;
|
|
392
|
+
verbose(`[skip] ${rel} (unchanged)`);
|
|
393
|
+
} else {
|
|
394
|
+
verbose(`[copy] ${rel} (hash differs)`);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
} catch (err) {
|
|
398
|
+
if (isNodeError(err) && err.code === "ENOENT") {
|
|
399
|
+
verbose(`[copy] ${rel} (new file)`);
|
|
400
|
+
} else {
|
|
401
|
+
throw err;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
if (needsCopy) {
|
|
405
|
+
await copyWithCoW(srcFile, destFile);
|
|
406
|
+
return "copied";
|
|
407
|
+
}
|
|
408
|
+
return "skipped";
|
|
409
|
+
})
|
|
410
|
+
)
|
|
411
|
+
);
|
|
412
|
+
for (const r of results) {
|
|
413
|
+
if (r === "copied") copied++;
|
|
414
|
+
else skipped++;
|
|
415
|
+
}
|
|
416
|
+
try {
|
|
417
|
+
const destFiles = await collectFiles(destDir);
|
|
418
|
+
const srcRelPaths = new Set(srcFiles.map((f) => relative2(srcDir, f)));
|
|
419
|
+
for (const destFile of destFiles) {
|
|
420
|
+
const rel = relative2(destDir, destFile);
|
|
421
|
+
if (!srcRelPaths.has(rel)) {
|
|
422
|
+
verbose(`[remove] ${rel} (no longer in source)`);
|
|
423
|
+
if (!isDryRun()) {
|
|
424
|
+
await rm(destFile);
|
|
425
|
+
}
|
|
426
|
+
removed++;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
} catch (err) {
|
|
430
|
+
if (isNodeError(err) && err.code === "ENOENT") {
|
|
431
|
+
} else {
|
|
432
|
+
throw err;
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
return { copied, removed, skipped };
|
|
436
|
+
}
|
|
437
|
+
async function moveDir(src, dest) {
|
|
438
|
+
try {
|
|
439
|
+
await rename(src, dest);
|
|
440
|
+
} catch (err) {
|
|
441
|
+
if (isNodeError(err) && err.code === "EXDEV") {
|
|
442
|
+
await cp(src, dest, { recursive: true });
|
|
443
|
+
await rm(src, { recursive: true, force: true });
|
|
444
|
+
} else {
|
|
445
|
+
throw err;
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
async function removeDir(dir) {
|
|
450
|
+
if (isDryRun()) {
|
|
451
|
+
verbose(`[dry-run] would remove ${dir}`);
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
await rm(dir, { recursive: true, force: true });
|
|
455
|
+
}
|
|
456
|
+
async function ensureDir(dir) {
|
|
457
|
+
await mkdir(dir, { recursive: true });
|
|
458
|
+
}
|
|
459
|
+
async function ensurePrivateDir(dir) {
|
|
460
|
+
await mkdir(dir, { recursive: true, mode: 448 });
|
|
461
|
+
}
|
|
462
|
+
async function exists(path) {
|
|
463
|
+
try {
|
|
464
|
+
await stat2(path);
|
|
465
|
+
return true;
|
|
466
|
+
} catch {
|
|
467
|
+
return false;
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
async function atomicWriteFile(filePath, data) {
|
|
471
|
+
if (isDryRun()) {
|
|
472
|
+
verbose(`[dry-run] would write ${filePath}`);
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
475
|
+
const tmpPath = filePath + ".tmp";
|
|
476
|
+
await writeFile(tmpPath, data);
|
|
477
|
+
await rename(tmpPath, filePath);
|
|
478
|
+
}
|
|
479
|
+
async function copyDir(src, dest) {
|
|
480
|
+
await cp(src, dest, { recursive: true });
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
export {
|
|
484
|
+
pLimit,
|
|
485
|
+
computeContentHash,
|
|
486
|
+
isNodeError,
|
|
487
|
+
copyWithCoW,
|
|
488
|
+
incrementalCopy,
|
|
489
|
+
moveDir,
|
|
490
|
+
removeDir,
|
|
491
|
+
ensureDir,
|
|
492
|
+
ensurePrivateDir,
|
|
493
|
+
exists,
|
|
494
|
+
atomicWriteFile,
|
|
495
|
+
copyDir
|
|
496
|
+
};
|