@jk2908/cxx 0.3.3 → 0.3.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 +1 -4
- package/dist/build.d.ts +10 -4
- package/dist/build.d.ts.map +1 -1
- package/dist/build.js +157 -81
- package/dist/build.js.map +6 -5
- package/dist/index.js +1 -4
- package/dist/index.js.map +2 -2
- package/dist/logger.d.ts +1 -1
- package/dist/logger.d.ts.map +1 -1
- package/dist/next/cxx-loader.cjs +50 -152
- package/dist/next/cxx-loader.cjs.map +8 -8
- package/dist/next/index.d.ts +5 -17
- package/dist/next/index.d.ts.map +1 -1
- package/dist/next/index.js +160 -178
- package/dist/next/index.js.map +7 -6
- package/dist/types.d.ts +0 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/utils.d.ts +0 -16
- package/dist/utils.d.ts.map +1 -1
- package/dist/vite/index.d.ts +1 -0
- package/dist/vite/index.d.ts.map +1 -1
- package/dist/vite/index.js +193 -242
- package/dist/vite/index.js.map +7 -7
- package/package.json +1 -4
- package/src/build.ts +130 -40
- package/src/logger.ts +2 -7
- package/src/next/cxx-loader.js +1 -10
- package/src/next/index.ts +16 -150
- package/src/types.ts +0 -2
- package/src/utils.ts +0 -87
- package/src/vite/index.ts +49 -110
package/dist/utils.d.ts
CHANGED
|
@@ -1,19 +1,3 @@
|
|
|
1
1
|
export declare function capitalise(str: string): string;
|
|
2
2
|
export declare function pascalise(str: string): string;
|
|
3
|
-
export type Batcher<K, V> = {
|
|
4
|
-
/**
|
|
5
|
-
* Queue a value for a key. Queueing the same key again replaces the previous value.
|
|
6
|
-
*/
|
|
7
|
-
add: (key: K, value: V) => void;
|
|
8
|
-
/**
|
|
9
|
-
* Run any waiting work now and resolve once it has finished.
|
|
10
|
-
*/
|
|
11
|
-
flush: () => Promise<void>;
|
|
12
|
-
};
|
|
13
|
-
/**
|
|
14
|
-
* Group bursts of work and run them together. Every key queued within `wait` is
|
|
15
|
-
* included once, and a key queued while a batch is running is handled in the next
|
|
16
|
-
* batch instead of replacing the one in progress.
|
|
17
|
-
*/
|
|
18
|
-
export declare function createBatcher<K, V>(wait: number, flush: (batch: Map<K, V>) => void | Promise<void>): Batcher<K, V>;
|
|
19
3
|
//# sourceMappingURL=utils.d.ts.map
|
package/dist/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,UAErC;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,UAKpC
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,UAErC;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,UAKpC"}
|
package/dist/vite/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export default function cxx(pluginConfig?: PluginConfig): {
|
|
|
4
4
|
name: string;
|
|
5
5
|
enforce: "pre";
|
|
6
6
|
configResolved(this: import("vite").MinimalPluginContextWithoutEnvironment, config: ResolvedConfig): void;
|
|
7
|
+
buildStart(this: import("rolldown").PluginContext): Promise<void>;
|
|
7
8
|
transform(this: import("rolldown").TransformPluginContext, code: string, id: string): {
|
|
8
9
|
code: string;
|
|
9
10
|
map: import("magic-string").SourceMap | null;
|
package/dist/vite/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/vite/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/vite/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAe,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,MAAM,MAAM,CAAA;AAE3E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAkB/C,MAAM,CAAC,OAAO,UAAU,GAAG,CAAC,YAAY,GAAE,YAAiB;;;wFA6ElC,cAAc;;;;;;yFAkCb,aAAa;;EAYtC"}
|
package/dist/vite/index.js
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import { createRequire } from "node:module";
|
|
2
|
-
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
3
|
-
|
|
4
1
|
// src/build.ts
|
|
5
2
|
import { createHash } from "node:crypto";
|
|
6
3
|
import fs from "node:fs/promises";
|
|
@@ -14,6 +11,86 @@ var PKG_NAME = `@jk2908/${NAME}`;
|
|
|
14
11
|
var GENERATED_DIR = `.${NAME}`;
|
|
15
12
|
var AUTOGEN_MSG = `// auto-generated by ${NAME}`;
|
|
16
13
|
|
|
14
|
+
// src/logger.ts
|
|
15
|
+
var LEVELS = {
|
|
16
|
+
debug: 0,
|
|
17
|
+
info: 1,
|
|
18
|
+
warn: 2,
|
|
19
|
+
error: 3,
|
|
20
|
+
fatal: 4
|
|
21
|
+
};
|
|
22
|
+
var defaultLevel = process.env["NODE_ENV"] === "production" ? "error" : "info";
|
|
23
|
+
|
|
24
|
+
class Logger {
|
|
25
|
+
name;
|
|
26
|
+
#level = defaultLevel;
|
|
27
|
+
constructor(name) {
|
|
28
|
+
this.name = name;
|
|
29
|
+
}
|
|
30
|
+
static toError(err) {
|
|
31
|
+
return err instanceof Error ? err : new Error(String(err), { cause: err });
|
|
32
|
+
}
|
|
33
|
+
static print(err) {
|
|
34
|
+
if (err instanceof Error) {
|
|
35
|
+
return err.message + (err.stack ? `
|
|
36
|
+
${err.stack}` : "");
|
|
37
|
+
}
|
|
38
|
+
if (typeof err === "object" && err !== null) {
|
|
39
|
+
try {
|
|
40
|
+
return JSON.stringify(err, null, 2);
|
|
41
|
+
} catch {
|
|
42
|
+
return String(err);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return String(err);
|
|
46
|
+
}
|
|
47
|
+
set level(level) {
|
|
48
|
+
this.#level = level;
|
|
49
|
+
}
|
|
50
|
+
get level() {
|
|
51
|
+
return this.#level;
|
|
52
|
+
}
|
|
53
|
+
log(level, message, error) {
|
|
54
|
+
if (LEVELS[level] < LEVELS[this.level])
|
|
55
|
+
return;
|
|
56
|
+
const entry = {
|
|
57
|
+
ts: Date.now(),
|
|
58
|
+
level,
|
|
59
|
+
message
|
|
60
|
+
};
|
|
61
|
+
if (level === "error" || level === "fatal") {
|
|
62
|
+
entry.error = error ? Logger.toError(error) : new Error(message);
|
|
63
|
+
}
|
|
64
|
+
const line = `${this.name ? `[${this.name}]` : ""} [${entry.ts}] [${level.toUpperCase()}] ${message}`;
|
|
65
|
+
const extra = entry.error ? `
|
|
66
|
+
${Logger.print(entry.error)}` : "";
|
|
67
|
+
if (level === "warn") {
|
|
68
|
+
console.warn(line, extra);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
if (level === "error" || level === "fatal") {
|
|
72
|
+
console.error(line, extra);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
console.log(line, extra);
|
|
76
|
+
}
|
|
77
|
+
debug(...messages) {
|
|
78
|
+
this.log("debug", messages.join(" "));
|
|
79
|
+
}
|
|
80
|
+
info(...messages) {
|
|
81
|
+
this.log("info", messages.join(" "));
|
|
82
|
+
}
|
|
83
|
+
warn(...messages) {
|
|
84
|
+
this.log("warn", messages.join(" "));
|
|
85
|
+
}
|
|
86
|
+
error(message, error) {
|
|
87
|
+
this.log("error", message, error === undefined ? undefined : Logger.toError(error));
|
|
88
|
+
}
|
|
89
|
+
fatal(message, error) {
|
|
90
|
+
this.log("fatal", message, error === undefined ? undefined : Logger.toError(error));
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
17
94
|
// src/lru.ts
|
|
18
95
|
var CACHE_MAX_SIZE = 100;
|
|
19
96
|
|
|
@@ -56,54 +133,9 @@ function capitalise(str) {
|
|
|
56
133
|
function pascalise(str) {
|
|
57
134
|
return str.split(/[ _-]+/).map(capitalise).join("");
|
|
58
135
|
}
|
|
59
|
-
function createBatcher(wait, flush) {
|
|
60
|
-
const pending = new Map;
|
|
61
|
-
let timer = null;
|
|
62
|
-
let current = null;
|
|
63
|
-
function drain() {
|
|
64
|
-
if (current)
|
|
65
|
-
return current;
|
|
66
|
-
const run = (async () => {
|
|
67
|
-
while (pending.size > 0) {
|
|
68
|
-
const batch = new Map(pending);
|
|
69
|
-
pending.clear();
|
|
70
|
-
await flush(batch);
|
|
71
|
-
}
|
|
72
|
-
})();
|
|
73
|
-
current = run;
|
|
74
|
-
run.then(() => {
|
|
75
|
-
if (current === run)
|
|
76
|
-
current = null;
|
|
77
|
-
}, () => {
|
|
78
|
-
if (current === run)
|
|
79
|
-
current = null;
|
|
80
|
-
});
|
|
81
|
-
return run;
|
|
82
|
-
}
|
|
83
|
-
function schedule() {
|
|
84
|
-
if (timer)
|
|
85
|
-
clearTimeout(timer);
|
|
86
|
-
timer = setTimeout(() => {
|
|
87
|
-
timer = null;
|
|
88
|
-
drain().catch(() => {});
|
|
89
|
-
}, wait);
|
|
90
|
-
}
|
|
91
|
-
return {
|
|
92
|
-
add(key, value) {
|
|
93
|
-
pending.set(key, value);
|
|
94
|
-
schedule();
|
|
95
|
-
},
|
|
96
|
-
flush() {
|
|
97
|
-
if (timer) {
|
|
98
|
-
clearTimeout(timer);
|
|
99
|
-
timer = null;
|
|
100
|
-
}
|
|
101
|
-
return drain();
|
|
102
|
-
}
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
136
|
|
|
106
137
|
// src/build.ts
|
|
138
|
+
var logger = new Logger(NAME);
|
|
107
139
|
var decoder = new TextDecoder;
|
|
108
140
|
var encoder = new TextEncoder;
|
|
109
141
|
var collectCache = new LruCache;
|
|
@@ -244,29 +276,21 @@ async function writeRenderedTypes(tags) {
|
|
|
244
276
|
var PARTIAL_DIR = path.join(GENERATED_DIR, "tags");
|
|
245
277
|
var REBUILD_WAIT = 100;
|
|
246
278
|
var rebuildTimer = null;
|
|
247
|
-
var rebuildError = null;
|
|
248
279
|
function partialPath(filePath) {
|
|
249
280
|
return path.join(PARTIAL_DIR, `${createHash("sha1").update(filePath).digest("hex")}.json`);
|
|
250
281
|
}
|
|
251
|
-
async function partialDirMtime() {
|
|
252
|
-
try {
|
|
253
|
-
return (await fs.stat(PARTIAL_DIR)).mtimeMs;
|
|
254
|
-
} catch (err) {
|
|
255
|
-
if (isENOENT(err))
|
|
256
|
-
return 0;
|
|
257
|
-
throw err;
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
282
|
async function readPartials() {
|
|
261
283
|
let entries;
|
|
262
284
|
try {
|
|
263
285
|
entries = await fs.readdir(PARTIAL_DIR);
|
|
264
286
|
} catch (err) {
|
|
265
287
|
if (isENOENT(err))
|
|
266
|
-
return new Map;
|
|
288
|
+
return { tags: new Map, duplicates: [] };
|
|
267
289
|
throw err;
|
|
268
290
|
}
|
|
269
291
|
const tags = new Map;
|
|
292
|
+
const fileByTag = new Map;
|
|
293
|
+
const duplicates = [];
|
|
270
294
|
for (const entry of entries) {
|
|
271
295
|
if (!entry.endsWith(".json"))
|
|
272
296
|
continue;
|
|
@@ -277,19 +301,28 @@ async function readPartials() {
|
|
|
277
301
|
} catch {
|
|
278
302
|
continue;
|
|
279
303
|
}
|
|
304
|
+
let source;
|
|
280
305
|
try {
|
|
281
|
-
await fs.
|
|
306
|
+
source = await fs.readFile(parsed.file, "utf-8");
|
|
282
307
|
} catch {
|
|
283
308
|
await fs.rm(partial, { force: true });
|
|
284
309
|
continue;
|
|
285
310
|
}
|
|
311
|
+
if (!source.includes("cxx")) {
|
|
312
|
+
await fs.rm(partial, { force: true });
|
|
313
|
+
continue;
|
|
314
|
+
}
|
|
286
315
|
for (const [name, classes] of Object.entries(parsed.tags)) {
|
|
287
|
-
|
|
288
|
-
|
|
316
|
+
const existing = fileByTag.get(name);
|
|
317
|
+
if (existing) {
|
|
318
|
+
duplicates.push({ tag: name, files: [existing, parsed.file] });
|
|
319
|
+
continue;
|
|
320
|
+
}
|
|
321
|
+
fileByTag.set(name, parsed.file);
|
|
289
322
|
tags.set(name, classes);
|
|
290
323
|
}
|
|
291
324
|
}
|
|
292
|
-
return tags;
|
|
325
|
+
return { tags, duplicates };
|
|
293
326
|
}
|
|
294
327
|
function writeTypesForFile(filePath, tags) {
|
|
295
328
|
return enqueueWrite(async () => {
|
|
@@ -300,8 +333,8 @@ function writeTypesForFile(filePath, tags) {
|
|
|
300
333
|
} else {
|
|
301
334
|
await writeFileAtomic(partial, JSON.stringify({ file: filePath, tags: Object.fromEntries(tags) }));
|
|
302
335
|
}
|
|
303
|
-
}).then(() => {
|
|
304
|
-
|
|
336
|
+
}).then(() => scheduleRebuild()).catch((err) => {
|
|
337
|
+
logger.error(`failed to write types for ${filePath}`, err);
|
|
305
338
|
});
|
|
306
339
|
}
|
|
307
340
|
function scheduleRebuild() {
|
|
@@ -310,7 +343,7 @@ function scheduleRebuild() {
|
|
|
310
343
|
rebuildTimer = setTimeout(() => {
|
|
311
344
|
rebuildTimer = null;
|
|
312
345
|
flushTypes().catch((err) => {
|
|
313
|
-
|
|
346
|
+
logger.error("failed to generate types", err);
|
|
314
347
|
});
|
|
315
348
|
}, REBUILD_WAIT);
|
|
316
349
|
}
|
|
@@ -320,23 +353,64 @@ function flushTypes() {
|
|
|
320
353
|
rebuildTimer = null;
|
|
321
354
|
}
|
|
322
355
|
return enqueueWrite(async () => {
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
356
|
+
const { tags, duplicates } = await readPartials();
|
|
357
|
+
await writeRenderedTypes(tags);
|
|
358
|
+
for (const duplicate of duplicates) {
|
|
359
|
+
logger.error(`Tag "${duplicate.tag}" is defined in multiple files: ${duplicate.files.join(", ")}`);
|
|
360
|
+
}
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
var SOURCE_EXTENSIONS = new Set([".js", ".jsx", ".ts", ".tsx"]);
|
|
364
|
+
var SKIP_DIRS = new Set(["node_modules", "dist", "build", "coverage", "out"]);
|
|
365
|
+
async function runWithConcurrency(items, concurrency, fn) {
|
|
366
|
+
let cursor = 0;
|
|
367
|
+
const workers = Array.from({ length: Math.min(concurrency, items.length) }, async () => {
|
|
368
|
+
while (cursor < items.length) {
|
|
369
|
+
const index = cursor++;
|
|
370
|
+
await fn(items[index]);
|
|
330
371
|
}
|
|
331
372
|
});
|
|
373
|
+
await Promise.all(workers);
|
|
332
374
|
}
|
|
333
|
-
function
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
375
|
+
async function refreshFile(file, config) {
|
|
376
|
+
let source;
|
|
377
|
+
try {
|
|
378
|
+
source = await fs.readFile(file, "utf-8");
|
|
379
|
+
} catch (err) {
|
|
380
|
+
if (!isENOENT(err))
|
|
381
|
+
throw err;
|
|
382
|
+
await writeTypesForFile(file, new Map);
|
|
383
|
+
return;
|
|
384
|
+
}
|
|
385
|
+
const tags = source.includes("cxx") ? collect(source, file, config).tags : new Map;
|
|
386
|
+
await writeTypesForFile(file, tags);
|
|
387
|
+
}
|
|
388
|
+
async function seedTypes(root, config) {
|
|
389
|
+
async function scan(dir) {
|
|
390
|
+
let entries;
|
|
391
|
+
try {
|
|
392
|
+
entries = await fs.readdir(dir, { withFileTypes: true });
|
|
393
|
+
} catch {
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
await runWithConcurrency(entries, 8, async (entry) => {
|
|
397
|
+
if (entry.name.startsWith(".") || SKIP_DIRS.has(entry.name))
|
|
398
|
+
return;
|
|
399
|
+
const full = path.join(dir, entry.name);
|
|
400
|
+
if (entry.isDirectory()) {
|
|
401
|
+
await scan(full);
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
404
|
+
if (!SOURCE_EXTENSIONS.has(path.extname(entry.name)))
|
|
405
|
+
return;
|
|
406
|
+
await refreshFile(full, config);
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
await scan(root);
|
|
410
|
+
await flushTypes();
|
|
337
411
|
}
|
|
338
412
|
function tagsToType(tags) {
|
|
339
|
-
return [...tags].toSorted(([a], [b]) => a
|
|
413
|
+
return [...tags].toSorted(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([tag, classes]) => {
|
|
340
414
|
const union = classes.length > 0 ? classes.toSorted((a, b) => a.length - b.length).map((c) => `'${c}'`).join(" | ") : "never";
|
|
341
415
|
return ` export type ${tag} = ${union}`;
|
|
342
416
|
}).join(`
|
|
@@ -345,170 +419,60 @@ function tagsToType(tags) {
|
|
|
345
419
|
|
|
346
420
|
// src/vite/index.ts
|
|
347
421
|
import { realpathSync } from "node:fs";
|
|
348
|
-
import fs2 from "node:fs/promises";
|
|
349
422
|
import path2 from "node:path";
|
|
350
|
-
|
|
351
|
-
// src/logger.ts
|
|
352
|
-
var LEVELS = {
|
|
353
|
-
debug: 0,
|
|
354
|
-
info: 1,
|
|
355
|
-
warn: 2,
|
|
356
|
-
error: 3,
|
|
357
|
-
fatal: 4
|
|
358
|
-
};
|
|
359
|
-
var defaultLevel = process.env["NODE_ENV"] === "production" ? "error" : "info";
|
|
360
|
-
|
|
361
|
-
class Logger {
|
|
362
|
-
name;
|
|
363
|
-
#level;
|
|
364
|
-
constructor(level, name) {
|
|
365
|
-
this.name = name;
|
|
366
|
-
this.#level = level ?? defaultLevel;
|
|
367
|
-
}
|
|
368
|
-
static toError(err) {
|
|
369
|
-
return err instanceof Error ? err : new Error(String(err), { cause: err });
|
|
370
|
-
}
|
|
371
|
-
static print(err) {
|
|
372
|
-
if (err instanceof Error) {
|
|
373
|
-
return err.message + (err.stack ? `
|
|
374
|
-
${err.stack}` : "");
|
|
375
|
-
}
|
|
376
|
-
if (typeof err === "object" && err !== null) {
|
|
377
|
-
try {
|
|
378
|
-
return JSON.stringify(err, null, 2);
|
|
379
|
-
} catch {
|
|
380
|
-
return String(err);
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
return String(err);
|
|
384
|
-
}
|
|
385
|
-
set level(level) {
|
|
386
|
-
this.#level = level;
|
|
387
|
-
}
|
|
388
|
-
get level() {
|
|
389
|
-
return this.#level;
|
|
390
|
-
}
|
|
391
|
-
log(level, message, error) {
|
|
392
|
-
if (LEVELS[level] < LEVELS[this.level])
|
|
393
|
-
return;
|
|
394
|
-
const entry = {
|
|
395
|
-
ts: Date.now(),
|
|
396
|
-
level,
|
|
397
|
-
message
|
|
398
|
-
};
|
|
399
|
-
if (level === "error" || level === "fatal") {
|
|
400
|
-
entry.error = error ? Logger.toError(error) : new Error(message);
|
|
401
|
-
}
|
|
402
|
-
const line = `${this.name ? `[${this.name}]` : ""} [${entry.ts}] [${level.toUpperCase()}] ${message}`;
|
|
403
|
-
const extra = entry.error ? `
|
|
404
|
-
${Logger.print(entry.error)}` : "";
|
|
405
|
-
if (level === "warn") {
|
|
406
|
-
console.warn(line, extra);
|
|
407
|
-
return;
|
|
408
|
-
}
|
|
409
|
-
if (level === "error" || level === "fatal") {
|
|
410
|
-
console.error(line, extra);
|
|
411
|
-
return;
|
|
412
|
-
}
|
|
413
|
-
console.log(line, extra);
|
|
414
|
-
}
|
|
415
|
-
debug(...messages) {
|
|
416
|
-
this.log("debug", messages.join(" "));
|
|
417
|
-
}
|
|
418
|
-
info(...messages) {
|
|
419
|
-
this.log("info", messages.join(" "));
|
|
420
|
-
}
|
|
421
|
-
warn(...messages) {
|
|
422
|
-
this.log("warn", messages.join(" "));
|
|
423
|
-
}
|
|
424
|
-
error(message, error) {
|
|
425
|
-
this.log("error", message, error === undefined ? undefined : Logger.toError(error));
|
|
426
|
-
}
|
|
427
|
-
fatal(message, error) {
|
|
428
|
-
this.log("fatal", message, error === undefined ? undefined : Logger.toError(error));
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
// src/vite/index.ts
|
|
433
|
-
var ACCEPTED_EXTENSIONS = new Set([".js", ".jsx", ".ts", ".tsx"]);
|
|
434
423
|
function normaliseWatchPath(p) {
|
|
435
424
|
return p.replace(/\\/g, "/");
|
|
436
425
|
}
|
|
437
|
-
function globToRegExp(glob) {
|
|
438
|
-
const pattern = glob.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*\*(\/|$)/g, ".*$1").replace(/\*/g, "[^/]*").replace(/\?/g, "[^/]");
|
|
439
|
-
return new RegExp(`^${pattern}$`);
|
|
440
|
-
}
|
|
441
426
|
function cxx(pluginConfig = {}) {
|
|
442
|
-
const
|
|
427
|
+
const logger2 = new Logger;
|
|
443
428
|
let watchRoot = normaliseWatchPath(process.cwd());
|
|
444
|
-
|
|
429
|
+
let seeded = false;
|
|
430
|
+
const realpaths = new Map;
|
|
445
431
|
function resolveWatchFile(filePath) {
|
|
446
432
|
const absolutePath = path2.resolve(watchRoot, filePath);
|
|
447
433
|
const parentPath = path2.dirname(absolutePath);
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
434
|
+
let resolvedParentPath = realpaths.get(parentPath);
|
|
435
|
+
if (resolvedParentPath === undefined) {
|
|
436
|
+
try {
|
|
437
|
+
resolvedParentPath = normaliseWatchPath(realpathSync.native(parentPath));
|
|
438
|
+
} catch {
|
|
439
|
+
resolvedParentPath = normaliseWatchPath(parentPath);
|
|
440
|
+
}
|
|
441
|
+
realpaths.set(parentPath, resolvedParentPath);
|
|
453
442
|
}
|
|
443
|
+
return normaliseWatchPath(path2.join(resolvedParentPath, path2.basename(absolutePath)));
|
|
454
444
|
}
|
|
455
445
|
function watchedFile(filePath) {
|
|
456
446
|
const resolvedPath = resolveWatchFile(filePath);
|
|
457
|
-
if (resolvedPath.startsWith(`${watchRoot}/`) && !resolvedPath.includes(`/${GENERATED_DIR}/`) &&
|
|
447
|
+
if (resolvedPath.startsWith(`${watchRoot}/`) && !resolvedPath.includes(`/${GENERATED_DIR}/`) && SOURCE_EXTENSIONS.has(path2.extname(resolvedPath))) {
|
|
458
448
|
return resolvedPath;
|
|
459
449
|
}
|
|
460
450
|
return null;
|
|
461
451
|
}
|
|
462
|
-
async function
|
|
463
|
-
|
|
464
|
-
try {
|
|
465
|
-
source = await fs2.readFile(file, "utf-8");
|
|
466
|
-
} catch (err) {
|
|
467
|
-
if (!isENOENT(err))
|
|
468
|
-
throw err;
|
|
452
|
+
async function handleEvent(event, file) {
|
|
453
|
+
if (event === "unlink") {
|
|
469
454
|
await writeTypesForFile(file, new Map);
|
|
470
|
-
|
|
455
|
+
} else {
|
|
456
|
+
await refreshFile(file, pluginConfig);
|
|
471
457
|
}
|
|
472
|
-
|
|
473
|
-
await writeTypesForFile(file, tags);
|
|
458
|
+
logger2.info(`updated types from ${file}`);
|
|
474
459
|
}
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
} catch {
|
|
480
|
-
return;
|
|
481
|
-
}
|
|
482
|
-
await Promise.all(entries.map(async (entry) => {
|
|
483
|
-
if (entry.name.startsWith(".") || entry.name === "node_modules")
|
|
484
|
-
return;
|
|
485
|
-
const full = path2.join(dir, entry.name);
|
|
486
|
-
if (entry.isDirectory()) {
|
|
487
|
-
await scan(full);
|
|
460
|
+
function onWatch(event) {
|
|
461
|
+
return (p) => {
|
|
462
|
+
const file = watchedFile(p);
|
|
463
|
+
if (!file)
|
|
488
464
|
return;
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
465
|
+
handleEvent(event, file).catch((err) => {
|
|
466
|
+
logger2.error(`failed to update types from ${file}`, err);
|
|
467
|
+
});
|
|
468
|
+
};
|
|
469
|
+
}
|
|
470
|
+
async function seed() {
|
|
471
|
+
if (seeded)
|
|
472
|
+
return;
|
|
473
|
+
seeded = true;
|
|
474
|
+
await seedTypes(watchRoot, pluginConfig);
|
|
497
475
|
}
|
|
498
|
-
const queue = createBatcher(75, async (batch) => {
|
|
499
|
-
for (const [file, event] of batch) {
|
|
500
|
-
try {
|
|
501
|
-
if (event === "unlink") {
|
|
502
|
-
await writeTypesForFile(file, new Map);
|
|
503
|
-
} else {
|
|
504
|
-
await recordFile(file);
|
|
505
|
-
}
|
|
506
|
-
logger.info(`updated types from ${file}`);
|
|
507
|
-
} catch (err) {
|
|
508
|
-
logger.error(`failed to update types from ${file}`, err);
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
});
|
|
512
476
|
return {
|
|
513
477
|
name: "cxx",
|
|
514
478
|
enforce: "pre",
|
|
@@ -519,6 +483,10 @@ function cxx(pluginConfig = {}) {
|
|
|
519
483
|
} catch {
|
|
520
484
|
watchRoot = normaliseWatchPath(root);
|
|
521
485
|
}
|
|
486
|
+
realpaths.clear();
|
|
487
|
+
},
|
|
488
|
+
async buildStart() {
|
|
489
|
+
await seed();
|
|
522
490
|
},
|
|
523
491
|
transform(code, id) {
|
|
524
492
|
if (id.startsWith("\x00") || id.includes("/node_modules/"))
|
|
@@ -526,7 +494,7 @@ function cxx(pluginConfig = {}) {
|
|
|
526
494
|
if (!code.includes("cxx"))
|
|
527
495
|
return null;
|
|
528
496
|
const cleanId = id.split("?")[0];
|
|
529
|
-
if (!
|
|
497
|
+
if (!SOURCE_EXTENSIONS.has(path2.extname(cleanId)))
|
|
530
498
|
return null;
|
|
531
499
|
const { template, tags, map } = collect(code, cleanId, pluginConfig);
|
|
532
500
|
if (template === code)
|
|
@@ -538,25 +506,8 @@ function cxx(pluginConfig = {}) {
|
|
|
538
506
|
};
|
|
539
507
|
},
|
|
540
508
|
configureServer(server) {
|
|
541
|
-
|
|
542
|
-
server.watcher.on("add", (
|
|
543
|
-
const file = watchedFile(p);
|
|
544
|
-
if (file)
|
|
545
|
-
queue.add(file, "add");
|
|
546
|
-
}).on("change", (p) => {
|
|
547
|
-
const file = watchedFile(p);
|
|
548
|
-
if (file)
|
|
549
|
-
queue.add(file, "change");
|
|
550
|
-
}).on("unlink", (p) => {
|
|
551
|
-
const file = watchedFile(p);
|
|
552
|
-
if (file)
|
|
553
|
-
queue.add(file, "unlink");
|
|
554
|
-
});
|
|
555
|
-
scan(watchRoot).then(() => flushTypes()).then(() => {
|
|
556
|
-
const err = takeRebuildError();
|
|
557
|
-
if (err)
|
|
558
|
-
logger.error("failed to generate types", err);
|
|
559
|
-
}).catch((err) => logger.error("failed to scan for cxx templates", err));
|
|
509
|
+
logger2.info("Watching for changes...");
|
|
510
|
+
server.watcher.on("add", onWatch("add")).on("change", onWatch("change")).on("unlink", onWatch("unlink"));
|
|
560
511
|
},
|
|
561
512
|
async writeBundle() {
|
|
562
513
|
await flushTypes();
|
|
@@ -567,4 +518,4 @@ export {
|
|
|
567
518
|
cxx as default
|
|
568
519
|
};
|
|
569
520
|
|
|
570
|
-
//# debugId=
|
|
521
|
+
//# debugId=9AC49C0FC7DBDEB864756E2164756E21
|