@jk2908/cxx 0.2.6 → 0.3.3
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 +18 -2
- package/dist/build.d.ts +22 -11
- package/dist/build.d.ts.map +1 -1
- package/dist/build.js +242 -73
- package/dist/build.js.map +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -7
- package/dist/index.js.map +3 -3
- package/dist/logger.d.ts +0 -2
- package/dist/logger.d.ts.map +1 -1
- package/dist/next/cxx-loader.cjs +287 -146
- package/dist/next/cxx-loader.cjs.map +7 -7
- package/dist/next/index.d.ts +34 -9
- package/dist/next/index.d.ts.map +1 -1
- package/dist/next/index.js +338 -142
- package/dist/next/index.js.map +5 -5
- package/dist/types.d.ts +5 -6
- package/dist/types.d.ts.map +1 -1
- package/dist/utils.d.ts +16 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/vite/index.d.ts +4 -3
- package/dist/vite/index.d.ts.map +1 -1
- package/dist/vite/index.js +336 -139
- package/dist/vite/index.js.map +6 -6
- package/package.json +85 -81
- package/src/build.ts +312 -108
- package/src/index.ts +26 -9
- package/src/logger.ts +5 -13
- package/src/next/cxx-loader.js +9 -6
- package/src/next/index.ts +152 -100
- package/src/types.ts +5 -8
- package/src/utils.ts +81 -8
- package/src/vite/index.ts +141 -89
package/dist/next/index.js
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
3
|
+
|
|
1
4
|
// src/build.ts
|
|
2
5
|
import { createHash } from "node:crypto";
|
|
3
6
|
import fs from "node:fs/promises";
|
|
4
7
|
import path from "node:path";
|
|
5
8
|
import { transform } from "lightningcss";
|
|
9
|
+
import MagicString from "magic-string";
|
|
6
10
|
|
|
7
11
|
// src/config.ts
|
|
8
12
|
var NAME = "cxx";
|
|
@@ -52,45 +56,93 @@ function capitalise(str) {
|
|
|
52
56
|
function pascalise(str) {
|
|
53
57
|
return str.split(/[ _-]+/).map(capitalise).join("");
|
|
54
58
|
}
|
|
55
|
-
function
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
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(() => {});
|
|
63
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
|
+
}
|
|
64
103
|
};
|
|
65
104
|
}
|
|
66
105
|
|
|
67
106
|
// src/build.ts
|
|
107
|
+
var decoder = new TextDecoder;
|
|
108
|
+
var encoder = new TextEncoder;
|
|
68
109
|
var collectCache = new LruCache;
|
|
69
|
-
var
|
|
110
|
+
var writeChain = Promise.resolve();
|
|
70
111
|
function isENOENT(err) {
|
|
71
112
|
return err instanceof Error && "code" in err && err.code === "ENOENT";
|
|
72
113
|
}
|
|
73
|
-
async function
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
114
|
+
async function writeFileAtomic(filePath, content) {
|
|
115
|
+
const tmp = `${filePath}.${process.pid}.${Math.random().toString(36).slice(2)}.tmp`;
|
|
116
|
+
await fs.writeFile(tmp, content);
|
|
117
|
+
try {
|
|
118
|
+
await fs.rename(tmp, filePath);
|
|
119
|
+
} catch (err) {
|
|
120
|
+
await fs.rm(tmp, { force: true });
|
|
121
|
+
throw err;
|
|
79
122
|
}
|
|
123
|
+
}
|
|
124
|
+
function enqueueWrite(task) {
|
|
125
|
+
const run = writeChain.then(task, task);
|
|
126
|
+
writeChain = run.then(() => {
|
|
127
|
+
return;
|
|
128
|
+
}, () => {
|
|
129
|
+
return;
|
|
130
|
+
});
|
|
131
|
+
return run;
|
|
132
|
+
}
|
|
133
|
+
async function maybeWrite(filePath, content) {
|
|
80
134
|
try {
|
|
81
|
-
if (await fs.readFile(filePath, "utf-8") === content)
|
|
82
|
-
fileCache.set(filePath, content);
|
|
135
|
+
if (await fs.readFile(filePath, "utf-8") === content)
|
|
83
136
|
return false;
|
|
84
|
-
}
|
|
85
137
|
} catch (err) {
|
|
86
138
|
if (!isENOENT(err))
|
|
87
139
|
throw err;
|
|
88
140
|
}
|
|
89
|
-
await
|
|
90
|
-
fileCache.set(filePath, content);
|
|
141
|
+
await writeFileAtomic(filePath, content);
|
|
91
142
|
return true;
|
|
92
143
|
}
|
|
93
|
-
var regex = /(?:const|var|let)\s*\[(\w
|
|
144
|
+
var regex = /((?:export\s+)?)(?:const|var|let)\s*\[(\w*)\s*,?\s*(\w*)\s*,?\s*(\w*)\s*\]\s*=\s*cxx(?:\s*`([\s\S]*?)`|\s*\.\s*tag(?:\s*<[^>]+>)?\s*\(\s*(['"])(.*?)\6\s*\)\s*`([\s\S]*?)`)/gm;
|
|
145
|
+
var IDENTIFIER = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
|
|
94
146
|
function hashCss(code) {
|
|
95
147
|
return `cxx-${createHash("sha256").update(code).digest("base64url").slice(0, 12)}`;
|
|
96
148
|
}
|
|
@@ -101,73 +153,137 @@ class DuplicateTagError extends Error {
|
|
|
101
153
|
super(`Tag ${tag} has already been seen. Tags must be unique across your application`);
|
|
102
154
|
}
|
|
103
155
|
}
|
|
156
|
+
|
|
157
|
+
class InvalidTagError extends Error {
|
|
158
|
+
name = "InvalidTagError";
|
|
159
|
+
constructor(tag) {
|
|
160
|
+
super(`Tag "${tag}" does not map to a valid TypeScript identifier. ` + `Use letters, numbers, spaces, "_" or "-"`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
104
163
|
function collect(source, id, config) {
|
|
105
|
-
const
|
|
164
|
+
const configKey = JSON.stringify(config);
|
|
106
165
|
const cached = collectCache.get(id);
|
|
107
|
-
if (cached?.source === source)
|
|
166
|
+
if (cached?.source === source && cached.config === configKey)
|
|
108
167
|
return cached;
|
|
109
|
-
const
|
|
168
|
+
const tags = new Map;
|
|
169
|
+
const magic = new MagicString(source);
|
|
170
|
+
let matched = false;
|
|
171
|
+
regex.lastIndex = 0;
|
|
172
|
+
let match;
|
|
173
|
+
while (match = regex.exec(source)) {
|
|
174
|
+
matched = true;
|
|
175
|
+
const [, exp, varOne, varTwo, varThree, plainCss, , tag, taggedCss] = match;
|
|
110
176
|
const css = plainCss ?? taggedCss;
|
|
111
|
-
const
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
177
|
+
const matchIndex = match.index;
|
|
178
|
+
const { code, exports: classExports = {} } = (() => {
|
|
179
|
+
try {
|
|
180
|
+
return transform({
|
|
181
|
+
minify: true,
|
|
182
|
+
cssModules: true,
|
|
183
|
+
filename: id,
|
|
184
|
+
code: encoder.encode(css)
|
|
185
|
+
});
|
|
186
|
+
} catch (err) {
|
|
187
|
+
const line = source.slice(0, matchIndex).split(`
|
|
188
|
+
`).length;
|
|
189
|
+
throw new Error(`Failed to compile cxx CSS at ${id}:${line}`, { cause: err });
|
|
190
|
+
}
|
|
191
|
+
})();
|
|
117
192
|
const href = hashCss(code);
|
|
118
|
-
const styles = Object.fromEntries(Object.entries(
|
|
193
|
+
const styles = Object.fromEntries(Object.entries(classExports).map(([k, v]) => [k, v.name]));
|
|
119
194
|
if (tag) {
|
|
120
195
|
const suffix = typeof config.typeSuffix === "string" ? config.typeSuffix : config.typeSuffix === false ? "" : "Classes";
|
|
121
196
|
const tagWithSuffix = pascalise(`${tag}${suffix}`);
|
|
197
|
+
if (!IDENTIFIER.test(tagWithSuffix))
|
|
198
|
+
throw new InvalidTagError(tag);
|
|
122
199
|
if (tags.has(tagWithSuffix))
|
|
123
200
|
throw new DuplicateTagError(tagWithSuffix);
|
|
124
201
|
tags.set(tagWithSuffix, Object.keys(styles));
|
|
125
202
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
203
|
+
const statements = [];
|
|
204
|
+
if (varOne) {
|
|
205
|
+
statements.push(`${exp}const ${varOne} = ${JSON.stringify(decoder.decode(code))}`);
|
|
206
|
+
}
|
|
207
|
+
if (varTwo) {
|
|
208
|
+
statements.push(`${exp}const ${varTwo} = ${JSON.stringify(styles)}`);
|
|
209
|
+
}
|
|
210
|
+
if (varThree) {
|
|
211
|
+
statements.push(`${exp}const ${varThree} = ${JSON.stringify(href)}`);
|
|
212
|
+
}
|
|
213
|
+
magic.overwrite(matchIndex, matchIndex + match[0].length, statements.join(`
|
|
214
|
+
`));
|
|
215
|
+
}
|
|
216
|
+
const template = magic.toString();
|
|
217
|
+
const map = matched ? magic.generateMap({ source: id, includeContent: true, hires: true }) : null;
|
|
218
|
+
const result = { source, config: configKey, template, tags, map };
|
|
219
|
+
collectCache.set(id, result);
|
|
220
|
+
return result;
|
|
221
|
+
}
|
|
222
|
+
function renderTypes(tags) {
|
|
223
|
+
return [
|
|
224
|
+
AUTOGEN_MSG,
|
|
225
|
+
"",
|
|
226
|
+
`import '${PKG_NAME}'`,
|
|
227
|
+
"",
|
|
228
|
+
`declare module '${PKG_NAME}' {`,
|
|
229
|
+
tagsToType(tags),
|
|
230
|
+
"}",
|
|
231
|
+
""
|
|
232
|
+
].join(`
|
|
131
233
|
`);
|
|
132
|
-
});
|
|
133
|
-
collectCache.set(id, { source, template, tags });
|
|
134
|
-
return {
|
|
135
|
-
template,
|
|
136
|
-
tags
|
|
137
|
-
};
|
|
138
234
|
}
|
|
139
|
-
async function
|
|
235
|
+
async function writeRenderedTypes(tags) {
|
|
140
236
|
const filePath = path.join(GENERATED_DIR, "index.d.ts");
|
|
141
237
|
if (!tags.size) {
|
|
142
|
-
|
|
143
|
-
await fs.rm(filePath, { force: true });
|
|
144
|
-
fileCache.delete(filePath);
|
|
145
|
-
} catch (err) {
|
|
146
|
-
if (!isENOENT(err))
|
|
147
|
-
throw err;
|
|
148
|
-
}
|
|
238
|
+
await fs.rm(filePath, { force: true });
|
|
149
239
|
return;
|
|
150
240
|
}
|
|
151
241
|
await fs.mkdir(GENERATED_DIR, { recursive: true });
|
|
152
|
-
await maybeWrite(filePath,
|
|
153
|
-
|
|
154
|
-
import '${PKG_NAME}'
|
|
155
|
-
|
|
156
|
-
declare module '${PKG_NAME}' {
|
|
157
|
-
${tagsToType(tags)}
|
|
158
|
-
}
|
|
159
|
-
`);
|
|
242
|
+
await maybeWrite(filePath, renderTypes(tags));
|
|
160
243
|
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
244
|
+
var PARTIAL_DIR = path.join(GENERATED_DIR, "tags");
|
|
245
|
+
var REBUILD_WAIT = 100;
|
|
246
|
+
var rebuildTimer = null;
|
|
247
|
+
var rebuildError = null;
|
|
248
|
+
function partialPath(filePath) {
|
|
249
|
+
return path.join(PARTIAL_DIR, `${createHash("sha1").update(filePath).digest("hex")}.json`);
|
|
250
|
+
}
|
|
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
|
+
}
|
|
166
259
|
}
|
|
167
|
-
function
|
|
260
|
+
async function readPartials() {
|
|
261
|
+
let entries;
|
|
262
|
+
try {
|
|
263
|
+
entries = await fs.readdir(PARTIAL_DIR);
|
|
264
|
+
} catch (err) {
|
|
265
|
+
if (isENOENT(err))
|
|
266
|
+
return new Map;
|
|
267
|
+
throw err;
|
|
268
|
+
}
|
|
168
269
|
const tags = new Map;
|
|
169
|
-
for (const
|
|
170
|
-
|
|
270
|
+
for (const entry of entries) {
|
|
271
|
+
if (!entry.endsWith(".json"))
|
|
272
|
+
continue;
|
|
273
|
+
const partial = path.join(PARTIAL_DIR, entry);
|
|
274
|
+
let parsed;
|
|
275
|
+
try {
|
|
276
|
+
parsed = JSON.parse(await fs.readFile(partial, "utf-8"));
|
|
277
|
+
} catch {
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
280
|
+
try {
|
|
281
|
+
await fs.access(parsed.file);
|
|
282
|
+
} catch {
|
|
283
|
+
await fs.rm(partial, { force: true });
|
|
284
|
+
continue;
|
|
285
|
+
}
|
|
286
|
+
for (const [name, classes] of Object.entries(parsed.tags)) {
|
|
171
287
|
if (tags.has(name))
|
|
172
288
|
throw new DuplicateTagError(name);
|
|
173
289
|
tags.set(name, classes);
|
|
@@ -175,111 +291,179 @@ function flattenTags(tagsByFile) {
|
|
|
175
291
|
}
|
|
176
292
|
return tags;
|
|
177
293
|
}
|
|
294
|
+
function writeTypesForFile(filePath, tags) {
|
|
295
|
+
return enqueueWrite(async () => {
|
|
296
|
+
await fs.mkdir(PARTIAL_DIR, { recursive: true });
|
|
297
|
+
const partial = partialPath(filePath);
|
|
298
|
+
if (!tags.size) {
|
|
299
|
+
await fs.rm(partial, { force: true });
|
|
300
|
+
} else {
|
|
301
|
+
await writeFileAtomic(partial, JSON.stringify({ file: filePath, tags: Object.fromEntries(tags) }));
|
|
302
|
+
}
|
|
303
|
+
}).then(() => {
|
|
304
|
+
scheduleRebuild();
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
function scheduleRebuild() {
|
|
308
|
+
if (rebuildTimer)
|
|
309
|
+
clearTimeout(rebuildTimer);
|
|
310
|
+
rebuildTimer = setTimeout(() => {
|
|
311
|
+
rebuildTimer = null;
|
|
312
|
+
flushTypes().catch((err) => {
|
|
313
|
+
rebuildError = err;
|
|
314
|
+
});
|
|
315
|
+
}, REBUILD_WAIT);
|
|
316
|
+
}
|
|
317
|
+
function flushTypes() {
|
|
318
|
+
if (rebuildTimer) {
|
|
319
|
+
clearTimeout(rebuildTimer);
|
|
320
|
+
rebuildTimer = null;
|
|
321
|
+
}
|
|
322
|
+
return enqueueWrite(async () => {
|
|
323
|
+
let before = await partialDirMtime();
|
|
324
|
+
for (let attempt = 0;attempt < 3; attempt++) {
|
|
325
|
+
await writeRenderedTypes(await readPartials());
|
|
326
|
+
const after = await partialDirMtime();
|
|
327
|
+
if (after === before)
|
|
328
|
+
return;
|
|
329
|
+
before = after;
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
function takeRebuildError() {
|
|
334
|
+
const err = rebuildError;
|
|
335
|
+
rebuildError = null;
|
|
336
|
+
return err;
|
|
337
|
+
}
|
|
338
|
+
function tagsToType(tags) {
|
|
339
|
+
return [...tags].toSorted(([a], [b]) => a.localeCompare(b)).map(([tag, classes]) => {
|
|
340
|
+
const union = classes.length > 0 ? classes.toSorted((a, b) => a.length - b.length).map((c) => `'${c}'`).join(" | ") : "never";
|
|
341
|
+
return ` export type ${tag} = ${union}`;
|
|
342
|
+
}).join(`
|
|
343
|
+
`);
|
|
344
|
+
}
|
|
178
345
|
|
|
179
346
|
// src/next/index.ts
|
|
180
347
|
import fs2 from "node:fs/promises";
|
|
181
348
|
import path2 from "node:path";
|
|
182
349
|
import { fileURLToPath } from "node:url";
|
|
183
|
-
import watcher from "@parcel/watcher";
|
|
184
350
|
var nextDir = path2.dirname(fileURLToPath(import.meta.url));
|
|
185
351
|
var loader = path2.join(nextDir, "cxx-loader.cjs");
|
|
186
|
-
var tagsByFile = new Map;
|
|
187
352
|
var watchedFiles = new Map;
|
|
188
|
-
var
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
353
|
+
var subscription = null;
|
|
354
|
+
var subscriptionPromise = null;
|
|
355
|
+
var cleanupRegistered = false;
|
|
356
|
+
var watcherLogger = null;
|
|
357
|
+
var DEFAULT_IGNORE = [
|
|
358
|
+
"**/node_modules/**",
|
|
359
|
+
"**/.next/**",
|
|
360
|
+
`**/${GENERATED_DIR}/**`,
|
|
361
|
+
"**/.git/**"
|
|
362
|
+
];
|
|
363
|
+
async function onEvent(event, filePath) {
|
|
364
|
+
const watched = watchedFiles.get(filePath);
|
|
365
|
+
if (!watched)
|
|
192
366
|
return;
|
|
193
|
-
const { pluginConfig, logger } =
|
|
194
|
-
const hadTags = tagsByFile.has(filePath);
|
|
367
|
+
const { pluginConfig, logger } = watched;
|
|
195
368
|
if (event === "delete") {
|
|
196
|
-
|
|
197
|
-
if (!hadTags)
|
|
198
|
-
return;
|
|
199
|
-
await writeTypes(flattenTags(tagsByFile));
|
|
369
|
+
await writeTypesForFile(filePath, new Map);
|
|
200
370
|
logger.info(`updated types from ${filePath}`);
|
|
201
371
|
return;
|
|
202
372
|
}
|
|
373
|
+
let source;
|
|
203
374
|
try {
|
|
204
|
-
|
|
205
|
-
const { tags } = collect(source, filePath, pluginConfig);
|
|
206
|
-
const hasTags = tags.size > 0;
|
|
207
|
-
if (hasTags) {
|
|
208
|
-
tagsByFile.set(filePath, tags);
|
|
209
|
-
} else {
|
|
210
|
-
tagsByFile.delete(filePath);
|
|
211
|
-
}
|
|
212
|
-
if (!hadTags && !hasTags)
|
|
213
|
-
return;
|
|
214
|
-
await writeTypes(flattenTags(tagsByFile));
|
|
215
|
-
logger.info(`updated types from ${filePath}`);
|
|
375
|
+
source = await fs2.readFile(filePath, "utf-8");
|
|
216
376
|
} catch (err) {
|
|
217
377
|
if (!isENOENT(err))
|
|
218
378
|
throw err;
|
|
219
|
-
|
|
220
|
-
return;
|
|
221
|
-
tagsByFile.delete(filePath);
|
|
222
|
-
await writeTypes(flattenTags(tagsByFile));
|
|
379
|
+
await writeTypesForFile(filePath, new Map);
|
|
223
380
|
logger.info(`updated types from ${filePath}`);
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
const tags = source.includes("cxx") ? collect(source, filePath, pluginConfig).tags : new Map;
|
|
384
|
+
await writeTypesForFile(filePath, tags);
|
|
385
|
+
logger.info(`updated types from ${filePath}`);
|
|
386
|
+
}
|
|
387
|
+
function ensureWatcher(pluginConfig, logger) {
|
|
388
|
+
watcherLogger = logger;
|
|
389
|
+
if (subscriptionPromise)
|
|
390
|
+
return;
|
|
391
|
+
const root = pluginConfig.watch?.root ?? process.cwd();
|
|
392
|
+
const ignore = [...DEFAULT_IGNORE, ...pluginConfig.watch?.ignore ?? []];
|
|
393
|
+
subscriptionPromise = (async () => {
|
|
394
|
+
const { subscribe } = await import("@parcel/watcher");
|
|
395
|
+
subscription = await subscribe(root, (watchErr, events) => {
|
|
396
|
+
if (watchErr) {
|
|
397
|
+
watcherLogger?.error(`failed to watch ${root}`, watchErr);
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
for (const event of events) {
|
|
401
|
+
const filePath = path2.resolve(event.path);
|
|
402
|
+
if (!watchedFiles.has(filePath))
|
|
403
|
+
continue;
|
|
404
|
+
onEvent(event.type, filePath).catch((err) => {
|
|
405
|
+
watcherLogger?.error(`failed to update types from ${filePath}`, err);
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
}, { ignore });
|
|
409
|
+
registerCleanup();
|
|
410
|
+
})().catch((err) => {
|
|
411
|
+
watcherLogger?.error("failed to start cxx watcher", err);
|
|
412
|
+
subscriptionPromise = null;
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
async function cleanup() {
|
|
416
|
+
const active = subscription;
|
|
417
|
+
subscription = null;
|
|
418
|
+
subscriptionPromise = null;
|
|
419
|
+
watchedFiles.clear();
|
|
420
|
+
if (active)
|
|
421
|
+
await active.unsubscribe();
|
|
422
|
+
}
|
|
423
|
+
async function shutdown(signal) {
|
|
424
|
+
try {
|
|
425
|
+
await cleanup();
|
|
426
|
+
} finally {
|
|
427
|
+
process.kill(process.pid, signal);
|
|
224
428
|
}
|
|
225
429
|
}
|
|
430
|
+
function registerCleanup() {
|
|
431
|
+
if (cleanupRegistered)
|
|
432
|
+
return;
|
|
433
|
+
cleanupRegistered = true;
|
|
434
|
+
process.once("SIGINT", () => void shutdown("SIGINT"));
|
|
435
|
+
process.once("SIGTERM", () => void shutdown("SIGTERM"));
|
|
436
|
+
}
|
|
226
437
|
function processFile(source, filePath, pluginConfig, logger) {
|
|
227
438
|
const resolvedFilePath = path2.resolve(filePath);
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
if (true) {
|
|
231
|
-
watchedFiles.set(resolvedFilePath, { pluginConfig, logger });
|
|
232
|
-
if (!subscription) {
|
|
233
|
-
subscription = watcher.subscribe(directoryPath, async (err, events) => {
|
|
234
|
-
if (err) {
|
|
235
|
-
logger.error(`failed to update types from ${directoryPath}`, err);
|
|
236
|
-
return;
|
|
237
|
-
}
|
|
238
|
-
for (const event of events) {
|
|
239
|
-
const eventFilePath = path2.resolve(event.path);
|
|
240
|
-
if (!watchedFiles.has(eventFilePath))
|
|
241
|
-
continue;
|
|
242
|
-
try {
|
|
243
|
-
await rebuildFile(eventFilePath, event.type);
|
|
244
|
-
} catch (watchErr) {
|
|
245
|
-
logger.error(`failed to update types from ${eventFilePath}`, watchErr);
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
});
|
|
249
|
-
subscriptionsByDir.set(directoryPath, subscription);
|
|
250
|
-
}
|
|
439
|
+
if (!source.includes("cxx") || /[\\/]node_modules[\\/]/.test(resolvedFilePath)) {
|
|
440
|
+
return { template: source, tags: new Map, map: null };
|
|
251
441
|
}
|
|
252
|
-
const
|
|
253
|
-
if (
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
442
|
+
const priorError = takeRebuildError();
|
|
443
|
+
if (priorError)
|
|
444
|
+
throw priorError;
|
|
445
|
+
if (process.env["NODE_ENV"] !== "production") {
|
|
446
|
+
watchedFiles.set(resolvedFilePath, { pluginConfig, logger });
|
|
447
|
+
ensureWatcher(pluginConfig, logger);
|
|
257
448
|
}
|
|
258
|
-
|
|
449
|
+
const result = collect(source, resolvedFilePath, pluginConfig);
|
|
450
|
+
writeTypesForFile(resolvedFilePath, result.tags);
|
|
259
451
|
return result;
|
|
260
452
|
}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
await (await subPromise).unsubscribe();
|
|
265
|
-
}));
|
|
266
|
-
subscriptionsByDir.clear();
|
|
267
|
-
}
|
|
268
|
-
process.once("SIGINT", () => {
|
|
269
|
-
cleanup().finally(() => process.exit(130));
|
|
270
|
-
});
|
|
271
|
-
process.once("SIGTERM", () => {
|
|
272
|
-
cleanup().finally(() => process.exit(143));
|
|
273
|
-
});
|
|
274
|
-
async function withCxx(nextConfig = {}, pluginConfig = {}) {
|
|
275
|
-
const TURBOPACK_GLOB = "*.{tsx,jsx,ts,js}";
|
|
453
|
+
var TURBOPACK_GLOB = "*.{tsx,jsx,ts,js}";
|
|
454
|
+
function withCxx(nextConfig = {}, pluginConfig = {}) {
|
|
455
|
+
const watchRoot = pluginConfig.watch?.root ?? nextConfig.turbopack?.root ?? process.cwd();
|
|
276
456
|
const loaderItem = {
|
|
277
457
|
loader,
|
|
278
458
|
options: {
|
|
279
|
-
pluginConfig
|
|
459
|
+
pluginConfig: {
|
|
460
|
+
...pluginConfig,
|
|
461
|
+
watch: { ...pluginConfig.watch, root: watchRoot }
|
|
462
|
+
}
|
|
280
463
|
}
|
|
281
464
|
};
|
|
282
465
|
const currentRule = nextConfig.turbopack?.rules?.[TURBOPACK_GLOB];
|
|
466
|
+
const userWebpack = nextConfig.webpack;
|
|
283
467
|
return {
|
|
284
468
|
...nextConfig,
|
|
285
469
|
turbopack: {
|
|
@@ -291,12 +475,24 @@ async function withCxx(nextConfig = {}, pluginConfig = {}) {
|
|
|
291
475
|
loaders: [...currentRule.loaders ?? [], loaderItem]
|
|
292
476
|
} : { loaders: [loaderItem] }
|
|
293
477
|
}
|
|
478
|
+
},
|
|
479
|
+
webpack(config, context) {
|
|
480
|
+
const next = userWebpack ? userWebpack(config, context) : config;
|
|
481
|
+
next.module ??= {};
|
|
482
|
+
next.module.rules ??= [];
|
|
483
|
+
next.module.rules.push({
|
|
484
|
+
test: /\.[jt]sx?$/,
|
|
485
|
+
exclude: /node_modules/,
|
|
486
|
+
enforce: "pre",
|
|
487
|
+
use: [loaderItem]
|
|
488
|
+
});
|
|
489
|
+
return next;
|
|
294
490
|
}
|
|
295
491
|
};
|
|
296
492
|
}
|
|
297
493
|
export {
|
|
298
|
-
|
|
299
|
-
|
|
494
|
+
processFile,
|
|
495
|
+
withCxx
|
|
300
496
|
};
|
|
301
497
|
|
|
302
|
-
//# debugId=
|
|
498
|
+
//# debugId=89C0BE13A5C5F77E64756E2164756E21
|