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