@pikacss/integration 0.0.33 → 0.0.35

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/dist/index.cjs CHANGED
@@ -28,20 +28,19 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
28
  let node_fs = require("node:fs");
29
29
  let node_fs_promises = require("node:fs/promises");
30
30
  let __pikacss_core = require("@pikacss/core");
31
- let jiti = require("jiti");
31
+ let alien_signals = require("alien-signals");
32
+ let globby = require("globby");
32
33
  let klona = require("klona");
33
34
  let local_pkg = require("local-pkg");
34
35
  let magic_string = require("magic-string");
35
36
  magic_string = __toESM(magic_string);
36
- let micromatch = require("micromatch");
37
- micromatch = __toESM(micromatch);
38
37
  let pathe = require("pathe");
39
- let perfect_debounce = require("perfect-debounce");
40
38
 
41
39
  //#region src/eventHook.ts
42
40
  function createEventHook() {
43
41
  const listeners = /* @__PURE__ */ new Set();
44
42
  function trigger(payload) {
43
+ if (listeners.size === 0) return;
45
44
  listeners.forEach((listener) => listener(payload));
46
45
  }
47
46
  function off(listener) {
@@ -130,9 +129,11 @@ function generateVueDeclaration(ctx) {
130
129
  ];
131
130
  }
132
131
  async function generateOverloadContent(ctx) {
132
+ __pikacss_core.log.debug("Generating TypeScript overload content");
133
133
  const paramsLines = [];
134
134
  const fnsLines = [];
135
135
  const usages = [...ctx.usages.values()].flat();
136
+ __pikacss_core.log.debug(`Processing ${usages.length} style usages for overload generation`);
136
137
  for (let i = 0; i < usages.length; i++) {
137
138
  const usage = usages[i];
138
139
  try {
@@ -166,6 +167,7 @@ async function generateOverloadContent(ctx) {
166
167
  ];
167
168
  }
168
169
  async function generateTsCodegenContent(ctx) {
170
+ __pikacss_core.log.debug("Generating TypeScript code generation content");
169
171
  const lines = [
170
172
  `// Auto-generated by ${ctx.currentPackageName}`,
171
173
  `import type { CSSProperty, CSSSelectors, DefineAutocomplete, Properties, StyleDefinition, StyleItem } from \'${ctx.currentPackageName}\'`,
@@ -187,257 +189,389 @@ async function generateTsCodegenContent(ctx) {
187
189
  lines.push(...generateGlobalDeclaration(ctx));
188
190
  lines.push(...generateVueDeclaration(ctx));
189
191
  lines.push(...await generateOverloadContent(ctx));
192
+ __pikacss_core.log.debug("TypeScript code generation content completed");
190
193
  return lines.join("\n");
191
194
  }
192
195
 
193
196
  //#endregion
194
197
  //#region src/ctx.ts
195
- function findFunctionCalls(code, RE) {
196
- const result = [];
197
- let matched = RE.exec(code);
198
- while (matched != null) {
199
- const fnName = matched[1];
200
- const start = matched.index;
201
- let end = start + fnName.length;
202
- let depth = 1;
203
- let inString = false;
204
- while (depth > 0) {
205
- end++;
206
- if (inString === false && code[end] === "(") depth++;
207
- else if (inString === false && code[end] === ")") depth--;
208
- else if (inString === false && (code[end] === "'" || code[end] === "\"")) inString = code[end];
209
- else if (inString === code[end]) inString = false;
210
- }
211
- const snippet = code.slice(start, end + 1);
212
- result.push({
213
- fnName,
214
- start,
215
- end,
216
- snippet
217
- });
218
- matched = RE.exec(code);
219
- }
220
- return result;
221
- }
222
- const ESCAPE_REPLACE_RE = /[.*+?^${}()|[\]\\/]/g;
223
- function createFnUtils(fnName) {
224
- const available = {
225
- normal: new Set([fnName]),
226
- forceString: new Set([
227
- `${fnName}.str`,
228
- `${fnName}['str']`,
229
- `${fnName}["str"]`,
230
- `${fnName}[\`str\`]`
231
- ]),
232
- forceArray: new Set([
233
- `${fnName}.arr`,
234
- `${fnName}['arr']`,
235
- `${fnName}["arr"]`,
236
- `${fnName}[\`arr\`]`
237
- ]),
238
- forceInline: new Set([
239
- `${fnName}.inl`,
240
- `${fnName}['inl']`,
241
- `${fnName}["inl"]`,
242
- `${fnName}[\`inl\`]`
243
- ]),
244
- normalPreview: new Set([`${fnName}p`]),
245
- forceStringPreview: new Set([
246
- `${fnName}p.str`,
247
- `${fnName}p['str']`,
248
- `${fnName}p["str"]`,
249
- `${fnName}p[\`str\`]`
250
- ]),
251
- forceArrayPreview: new Set([
252
- `${fnName}p.arr`,
253
- `${fnName}p['arr']`,
254
- `${fnName}p["arr"]`,
255
- `${fnName}p[\`arr\`]`
256
- ]),
257
- forceInlinePreview: new Set([
258
- `${fnName}p.inl`,
259
- `${fnName}p['inl']`,
260
- `${fnName}p["inl"]`,
261
- `${fnName}p[\`inl\`]`
262
- ])
263
- };
198
+ function usePaths({ cwd: _cwd, cssCodegen, tsCodegen }) {
199
+ const cwd = (0, alien_signals.signal)(_cwd);
264
200
  return {
265
- isNormal: (fnName$1) => available.normal.has(fnName$1) || available.normalPreview.has(fnName$1),
266
- isForceString: (fnName$1) => available.forceString.has(fnName$1) || available.forceStringPreview.has(fnName$1),
267
- isForceArray: (fnName$1) => available.forceArray.has(fnName$1) || available.forceArrayPreview.has(fnName$1),
268
- isForceInline: (fnName$1) => available.forceInline.has(fnName$1) || available.forceInlinePreview.has(fnName$1),
269
- isPreview: (fnName$1) => available.normalPreview.has(fnName$1) || available.forceStringPreview.has(fnName$1) || available.forceArrayPreview.has(fnName$1) || available.forceInlinePreview.has(fnName$1),
270
- RE: new RegExp(`\\b(${Object.values(available).flatMap((s) => [...s].map((f) => `(${f.replace(ESCAPE_REPLACE_RE, "\\$&")})`)).join("|")})\\(`, "g")
201
+ cwd,
202
+ cssCodegenFilepath: (0, alien_signals.computed)(() => (0, pathe.isAbsolute)(cssCodegen) ? (0, pathe.resolve)(cssCodegen) : (0, pathe.join)(cwd(), cssCodegen)),
203
+ tsCodegenFilepath: (0, alien_signals.computed)(() => tsCodegen === false ? null : (0, pathe.isAbsolute)(tsCodegen) ? (0, pathe.resolve)(tsCodegen) : (0, pathe.join)(cwd(), tsCodegen))
271
204
  };
272
205
  }
273
- async function createCtx(options) {
274
- const { cwd, currentPackageName, target, configOrPath, fnName, transformedFormat, tsCodegen, devCss, autoCreateConfig } = options;
275
- (0, __pikacss_core.setWarnFn)((...args) => {
276
- console.warn(`[${currentPackageName}]`, ...args);
206
+ function useConfig({ cwd, tsCodegenFilepath, currentPackageName, autoCreateConfig, configOrPath, scan }) {
207
+ const RE_VALID_CONFIG_EXT = /\.(?:js|cjs|mjs|ts|cts|mts)$/;
208
+ const specificConfigPath = (0, alien_signals.computed)(() => {
209
+ if (typeof configOrPath === "string" && RE_VALID_CONFIG_EXT.test(configOrPath)) return (0, pathe.isAbsolute)(configOrPath) ? configOrPath : (0, pathe.join)(cwd(), configOrPath);
210
+ return null;
277
211
  });
278
- const devCssFilepath = (0, pathe.isAbsolute)(devCss) ? (0, pathe.resolve)(devCss) : (0, pathe.join)(cwd, devCss);
279
- const tsCodegenFilepath = tsCodegen === false ? null : (0, pathe.isAbsolute)(tsCodegen) ? (0, pathe.resolve)(tsCodegen) : (0, pathe.join)(cwd, tsCodegen);
212
+ async function findFirstExistingConfigPath() {
213
+ const _cwd = cwd();
214
+ const _specificConfigPath = specificConfigPath();
215
+ if (_specificConfigPath != null && (0, node_fs.statSync)(_specificConfigPath, { throwIfNoEntry: false })?.isFile()) return _specificConfigPath;
216
+ const stream = (0, globby.globbyStream)("**/{pika,pikacss}.config.{js,cjs,mjs,ts,cts,mts}", { ignore: scan.exclude });
217
+ for await (const entry of stream) return (0, pathe.join)(_cwd, entry);
218
+ return null;
219
+ }
280
220
  const inlineConfig = typeof configOrPath === "object" ? configOrPath : null;
281
- const specificConfigPath = typeof configOrPath === "string" ? (0, pathe.isAbsolute)(configOrPath) ? configOrPath : (0, pathe.join)(cwd, configOrPath) : null;
282
- const configSources = [...specificConfigPath == null ? [] : [specificConfigPath], ...["pika", "pikacss"].flatMap((name) => [
283
- "js",
284
- "ts",
285
- "cjs",
286
- "cts",
287
- "mjs",
288
- "mts"
289
- ].map((ext) => `${name}.config.${ext}`)).map((name) => (0, pathe.join)(cwd, name))];
290
- const targetREs = target.map((t) => micromatch.default.makeRe(t));
291
- const needToTransform = (id) => targetREs.some((re) => re.test(id));
292
- const ctx = {
293
- cwd,
294
- currentPackageName,
295
- fnName,
296
- fnUtils: createFnUtils(fnName),
297
- transformedFormat,
298
- devCssFilepath,
299
- tsCodegenFilepath,
300
- hasVue: (0, local_pkg.isPackageExists)("vue", { paths: [cwd] }),
301
- usages: /* @__PURE__ */ new Map(),
302
- hooks: {
303
- styleUpdated: createEventHook(),
304
- tsCodegenUpdated: createEventHook()
305
- },
306
- loadConfig: async () => {
307
- if (inlineConfig != null) return {
308
- config: (0, klona.klona)(inlineConfig),
309
- file: null
310
- };
311
- let resolvedConfigPath = configSources.find((path) => {
312
- const stat = (0, node_fs.statSync)(path, { throwIfNoEntry: false });
313
- return stat != null && stat.isFile();
314
- });
315
- if (resolvedConfigPath == null) {
316
- if (autoCreateConfig === false) return {
317
- config: null,
318
- file: null
221
+ async function _loadConfig() {
222
+ try {
223
+ __pikacss_core.log.debug("Loading engine config");
224
+ if (inlineConfig != null) {
225
+ __pikacss_core.log.debug("Using inline config");
226
+ return {
227
+ config: (0, klona.klona)(inlineConfig),
228
+ file: null,
229
+ content: null
319
230
  };
320
- resolvedConfigPath = configSources[0];
321
- await (0, node_fs_promises.mkdir)((0, pathe.dirname)(resolvedConfigPath), { recursive: true }).catch(() => {});
322
- const relativeTsCodegenFilepath = tsCodegenFilepath == null ? null : `./${(0, pathe.relative)((0, pathe.dirname)(resolvedConfigPath), tsCodegenFilepath)}`;
323
- await (0, node_fs_promises.writeFile)(resolvedConfigPath, [
231
+ }
232
+ let resolvedConfigPath$1 = await findFirstExistingConfigPath();
233
+ const _cwd = cwd();
234
+ if (resolvedConfigPath$1 == null) {
235
+ if (autoCreateConfig === false) {
236
+ __pikacss_core.log.warn("Config file not found and autoCreateConfig is false");
237
+ return {
238
+ config: null,
239
+ file: null,
240
+ content: null
241
+ };
242
+ }
243
+ resolvedConfigPath$1 = (0, pathe.join)(_cwd, specificConfigPath() ?? "pika.config.js");
244
+ await (0, node_fs_promises.mkdir)((0, pathe.dirname)(resolvedConfigPath$1), { recursive: true }).catch(() => {});
245
+ const _tsCodegenFilepath = tsCodegenFilepath();
246
+ const relativeTsCodegenFilepath = _tsCodegenFilepath == null ? null : `./${(0, pathe.relative)((0, pathe.dirname)(resolvedConfigPath$1), _tsCodegenFilepath)}`;
247
+ await (0, node_fs_promises.writeFile)(resolvedConfigPath$1, [
248
+ ...relativeTsCodegenFilepath == null ? [] : [`/// <reference path="${relativeTsCodegenFilepath}" />`],
324
249
  `import { defineEngineConfig } from '${currentPackageName}'`,
325
- ...relativeTsCodegenFilepath == null ? [] : [`/** @type {import('${relativeTsCodegenFilepath}')} */`],
326
250
  "",
327
251
  "export default defineEngineConfig({",
328
252
  " // Add your PikaCSS engine config here",
329
253
  "})"
330
254
  ].join("\n"));
331
255
  }
332
- const config = (await (0, jiti.createJiti)(cwd, {
333
- fsCache: false,
334
- moduleCache: false
335
- }).import(resolvedConfigPath)).default;
256
+ __pikacss_core.log.info(`Using config file: ${resolvedConfigPath$1}`);
257
+ const { createJiti } = await import("jiti");
258
+ const jiti = createJiti(require("url").pathToFileURL(__filename).href, { interopDefault: true });
259
+ const content = await (0, node_fs_promises.readFile)(resolvedConfigPath$1, "utf-8");
260
+ const config = (await jiti.evalModule(content, {
261
+ id: resolvedConfigPath$1,
262
+ forceTranspile: true
263
+ })).default;
336
264
  return {
337
265
  config: (0, klona.klona)(config),
338
- file: resolvedConfigPath
266
+ file: resolvedConfigPath$1,
267
+ content
339
268
  };
340
- },
341
- init: (0, perfect_debounce.debounce)(async () => {
342
- ctx.isReady = false;
343
- ctx.usages.clear();
344
- const { config, file } = await ctx.loadConfig().catch((error) => {
345
- (0, __pikacss_core.warn)(`Failed to load config file: ${error.message}`, error);
346
- return {
347
- config: null,
348
- file: null
349
- };
350
- });
351
- ctx.resolvedConfigPath = file;
352
- const devPlugin = (0, __pikacss_core.defineEnginePlugin)({
353
- name: "@pikacss/integration:dev",
354
- preflightUpdated: () => ctx.hooks.styleUpdated.trigger(),
355
- atomicStyleAdded: () => ctx.hooks.styleUpdated.trigger(),
356
- autocompleteConfigUpdated: () => ctx.hooks.tsCodegenUpdated.trigger()
357
- });
358
- try {
359
- const _config = config ?? {};
360
- _config.plugins = _config.plugins ?? [];
361
- _config.plugins.unshift(devPlugin);
362
- ctx.engine = await (0, __pikacss_core.createEngine)(_config);
363
- } catch (error) {
364
- (0, __pikacss_core.warn)(`Failed to create engine: ${error.message}. Maybe the config file is invalid, falling back to default config.`, error);
365
- ctx.engine = await (0, __pikacss_core.createEngine)({ plugins: [devPlugin] });
366
- }
367
- await (0, node_fs_promises.mkdir)((0, pathe.dirname)(devCssFilepath), { recursive: true }).catch(() => {});
368
- await (0, node_fs_promises.writeFile)(devCssFilepath, "");
369
- if (tsCodegenFilepath != null) {
370
- await (0, node_fs_promises.mkdir)((0, pathe.dirname)(tsCodegenFilepath), { recursive: true }).catch(() => {});
371
- await (0, node_fs_promises.writeFile)(tsCodegenFilepath, await generateTsCodegenContent(ctx));
269
+ } catch (error) {
270
+ __pikacss_core.log.error(`Failed to load config file: ${error.message}`, error);
271
+ return {
272
+ config: null,
273
+ file: null,
274
+ content: null
275
+ };
276
+ }
277
+ }
278
+ const resolvedConfig = (0, alien_signals.signal)(inlineConfig);
279
+ const resolvedConfigPath = (0, alien_signals.signal)(null);
280
+ const resolvedConfigContent = (0, alien_signals.signal)(null);
281
+ async function loadConfig() {
282
+ const result = await _loadConfig();
283
+ resolvedConfig(result.config);
284
+ resolvedConfigPath(result.file);
285
+ resolvedConfigContent(result.content);
286
+ return result;
287
+ }
288
+ return {
289
+ resolvedConfig,
290
+ resolvedConfigPath,
291
+ resolvedConfigContent,
292
+ loadConfig
293
+ };
294
+ }
295
+ function useTransform({ cwd, cssCodegenFilepath, tsCodegenFilepath, scan, fnName, usages, engine, transformedFormat, triggerStyleUpdated, triggerTsCodegenUpdated }) {
296
+ const ESCAPE_REPLACE_RE = /[.*+?^${}()|[\]\\/]/g;
297
+ function createFnUtils(fnName$1) {
298
+ const available = {
299
+ normal: new Set([fnName$1]),
300
+ forceString: new Set([
301
+ `${fnName$1}.str`,
302
+ `${fnName$1}['str']`,
303
+ `${fnName$1}["str"]`,
304
+ `${fnName$1}[\`str\`]`
305
+ ]),
306
+ forceArray: new Set([
307
+ `${fnName$1}.arr`,
308
+ `${fnName$1}['arr']`,
309
+ `${fnName$1}["arr"]`,
310
+ `${fnName$1}[\`arr\`]`
311
+ ]),
312
+ forceInline: new Set([
313
+ `${fnName$1}.inl`,
314
+ `${fnName$1}['inl']`,
315
+ `${fnName$1}["inl"]`,
316
+ `${fnName$1}[\`inl\`]`
317
+ ]),
318
+ normalPreview: new Set([`${fnName$1}p`]),
319
+ forceStringPreview: new Set([
320
+ `${fnName$1}p.str`,
321
+ `${fnName$1}p['str']`,
322
+ `${fnName$1}p["str"]`,
323
+ `${fnName$1}p[\`str\`]`
324
+ ]),
325
+ forceArrayPreview: new Set([
326
+ `${fnName$1}p.arr`,
327
+ `${fnName$1}p['arr']`,
328
+ `${fnName$1}p["arr"]`,
329
+ `${fnName$1}p[\`arr\`]`
330
+ ]),
331
+ forceInlinePreview: new Set([
332
+ `${fnName$1}p.inl`,
333
+ `${fnName$1}p['inl']`,
334
+ `${fnName$1}p["inl"]`,
335
+ `${fnName$1}p[\`inl\`]`
336
+ ])
337
+ };
338
+ return {
339
+ isNormal: (fnName$2) => available.normal.has(fnName$2) || available.normalPreview.has(fnName$2),
340
+ isForceString: (fnName$2) => available.forceString.has(fnName$2) || available.forceStringPreview.has(fnName$2),
341
+ isForceArray: (fnName$2) => available.forceArray.has(fnName$2) || available.forceArrayPreview.has(fnName$2),
342
+ isForceInline: (fnName$2) => available.forceInline.has(fnName$2) || available.forceInlinePreview.has(fnName$2),
343
+ isPreview: (fnName$2) => available.normalPreview.has(fnName$2) || available.forceStringPreview.has(fnName$2) || available.forceArrayPreview.has(fnName$2) || available.forceInlinePreview.has(fnName$2),
344
+ RE: new RegExp(`\\b(${Object.values(available).flatMap((s) => [...s].map((f) => `(${f.replace(ESCAPE_REPLACE_RE, "\\$&")})`)).join("|")})\\(`, "g")
345
+ };
346
+ }
347
+ const fnUtils = createFnUtils(fnName);
348
+ function findFunctionCalls(code) {
349
+ const RE = fnUtils.RE;
350
+ const result = [];
351
+ let matched = RE.exec(code);
352
+ while (matched != null) {
353
+ const fnName$1 = matched[1];
354
+ const start = matched.index;
355
+ let end = start + fnName$1.length;
356
+ let depth = 1;
357
+ let inString = false;
358
+ while (depth > 0) {
359
+ end++;
360
+ if (inString === false && code[end] === "(") depth++;
361
+ else if (inString === false && code[end] === ")") depth--;
362
+ else if (inString === false && (code[end] === "'" || code[end] === "\"")) inString = code[end];
363
+ else if (inString === code[end]) inString = false;
372
364
  }
373
- ctx.isReady = true;
374
- }, 300),
375
- isReady: false,
376
- configSources,
377
- resolvedConfigPath: null,
378
- engine: null,
379
- transform: async (code, id) => {
380
- try {
381
- if (ctx.isReady === false || !needToTransform(id)) return;
382
- ctx.usages.delete(id);
383
- const functionCalls = findFunctionCalls(code, ctx.fnUtils.RE);
384
- if (functionCalls.length === 0) return;
385
- const usages = [];
386
- const transformed = new magic_string.default(code);
387
- for (const fnCall of functionCalls) {
388
- const argsStr = `[${fnCall.snippet.slice(fnCall.fnName.length + 1, -1)}]`;
389
- const args = new Function(`return ${argsStr}`)();
390
- const names = await ctx.engine.use(...args);
391
- const usage = {
392
- atomicStyleIds: names,
393
- params: args
394
- };
395
- usages.push(usage);
396
- let transformedContent;
397
- if (ctx.fnUtils.isNormal(fnCall.fnName)) transformedContent = ctx.transformedFormat === "array" ? `[${names.map((n) => `'${n}'`).join(", ")}]` : ctx.transformedFormat === "string" ? `'${names.join(" ")}'` : names.join(" ");
398
- else if (ctx.fnUtils.isForceString(fnCall.fnName)) transformedContent = `'${names.join(" ")}'`;
399
- else if (ctx.fnUtils.isForceArray(fnCall.fnName)) transformedContent = `[${names.map((n) => `'${n}'`).join(", ")}]`;
400
- else if (ctx.fnUtils.isForceInline(fnCall.fnName)) transformedContent = names.join(" ");
401
- else throw new Error(`Unexpected function name: ${fnCall.fnName}`);
402
- transformed.update(fnCall.start, fnCall.end + 1, transformedContent);
403
- }
404
- ctx.usages.set(id, usages);
405
- ctx.hooks.styleUpdated.trigger();
406
- ctx.hooks.tsCodegenUpdated.trigger();
407
- return {
408
- code: transformed.toString(),
409
- map: transformed.generateMap({ hires: true })
365
+ const snippet = code.slice(start, end + 1);
366
+ result.push({
367
+ fnName: fnName$1,
368
+ start,
369
+ end,
370
+ snippet
371
+ });
372
+ matched = RE.exec(code);
373
+ }
374
+ return result;
375
+ }
376
+ async function transform(code, id) {
377
+ const _engine = engine();
378
+ if (_engine == null) return null;
379
+ try {
380
+ __pikacss_core.log.debug(`Transforming file: ${id}`);
381
+ usages.delete(id);
382
+ const functionCalls = findFunctionCalls(code);
383
+ if (functionCalls.length === 0) return;
384
+ __pikacss_core.log.debug(`Found ${functionCalls.length} style function calls in ${id}`);
385
+ const usageList = [];
386
+ const transformed = new magic_string.default(code);
387
+ for (const fnCall of functionCalls) {
388
+ const argsStr = `[${fnCall.snippet.slice(fnCall.fnName.length + 1, -1)}]`;
389
+ const args = new Function(`return ${argsStr}`)();
390
+ const names = await _engine.use(...args);
391
+ const usage = {
392
+ atomicStyleIds: names,
393
+ params: args
410
394
  };
411
- } catch (error) {
412
- (0, __pikacss_core.warn)(`Failed to transform code: ${error.message}`, error);
413
- return;
395
+ usageList.push(usage);
396
+ let transformedContent;
397
+ if (fnUtils.isNormal(fnCall.fnName)) transformedContent = transformedFormat === "array" ? `[${names.map((n) => `'${n}'`).join(", ")}]` : transformedFormat === "string" ? `'${names.join(" ")}'` : names.join(" ");
398
+ else if (fnUtils.isForceString(fnCall.fnName)) transformedContent = `'${names.join(" ")}'`;
399
+ else if (fnUtils.isForceArray(fnCall.fnName)) transformedContent = `[${names.map((n) => `'${n}'`).join(", ")}]`;
400
+ else if (fnUtils.isForceInline(fnCall.fnName)) transformedContent = names.join(" ");
401
+ else throw new Error(`Unexpected function name: ${fnCall.fnName}`);
402
+ transformed.update(fnCall.start, fnCall.end + 1, transformedContent);
414
403
  }
404
+ usages.set(id, usageList);
405
+ triggerStyleUpdated();
406
+ triggerTsCodegenUpdated();
407
+ __pikacss_core.log.debug(`Transformed ${usageList.length} style usages in ${id}`);
408
+ return {
409
+ code: transformed.toString(),
410
+ map: transformed.generateMap({ hires: true })
411
+ };
412
+ } catch (error) {
413
+ __pikacss_core.log.error(`Failed to transform code (${(0, pathe.join)(cwd(), id)}): ${error.message}`, error);
414
+ return;
415
+ }
416
+ }
417
+ return {
418
+ transformFilter: {
419
+ include: scan.include,
420
+ exclude: [
421
+ ...scan.exclude,
422
+ cssCodegenFilepath(),
423
+ ...tsCodegenFilepath() ? [tsCodegenFilepath()] : []
424
+ ]
425
+ },
426
+ transform
427
+ };
428
+ }
429
+ function createCtx(options) {
430
+ const { cwd, cssCodegenFilepath, tsCodegenFilepath } = usePaths(options);
431
+ const { resolvedConfig, resolvedConfigPath, resolvedConfigContent, loadConfig } = useConfig({
432
+ ...options,
433
+ cwd,
434
+ tsCodegenFilepath
435
+ });
436
+ const usages = /* @__PURE__ */ new Map();
437
+ const engine = (0, alien_signals.signal)(null);
438
+ const hooks = {
439
+ styleUpdated: createEventHook(),
440
+ tsCodegenUpdated: createEventHook()
441
+ };
442
+ const { transformFilter, transform } = useTransform({
443
+ ...options,
444
+ cwd,
445
+ cssCodegenFilepath,
446
+ tsCodegenFilepath,
447
+ usages,
448
+ engine,
449
+ triggerStyleUpdated: () => hooks.styleUpdated.trigger(),
450
+ triggerTsCodegenUpdated: () => hooks.tsCodegenUpdated.trigger()
451
+ });
452
+ const ctx = {
453
+ currentPackageName: options.currentPackageName,
454
+ fnName: options.fnName,
455
+ transformedFormat: options.transformedFormat,
456
+ get cwd() {
457
+ return cwd();
458
+ },
459
+ set cwd(v) {
460
+ cwd(v);
461
+ },
462
+ get cssCodegenFilepath() {
463
+ return cssCodegenFilepath();
415
464
  },
416
- getCssContent: async (isDev) => {
417
- if (ctx.isReady === false) return null;
465
+ get tsCodegenFilepath() {
466
+ return tsCodegenFilepath();
467
+ },
468
+ get hasVue() {
469
+ return (0, local_pkg.isPackageExists)("vue", { paths: [cwd()] });
470
+ },
471
+ get resolvedConfig() {
472
+ return resolvedConfig();
473
+ },
474
+ get resolvedConfigPath() {
475
+ return resolvedConfigPath();
476
+ },
477
+ get resolvedConfigContent() {
478
+ return resolvedConfigContent();
479
+ },
480
+ loadConfig,
481
+ usages,
482
+ hooks,
483
+ get engine() {
484
+ const _engine = engine();
485
+ if (_engine == null) throw new Error("Engine is not initialized yet");
486
+ return _engine;
487
+ },
488
+ transformFilter,
489
+ transform: async (code, id) => {
490
+ await ctx.setupPromise;
491
+ return transform(code, id);
492
+ },
493
+ getCssCodegenContent: async () => {
494
+ await ctx.setupPromise;
495
+ __pikacss_core.log.debug("Generating CSS code");
418
496
  const atomicStyleIds = [...new Set([...ctx.usages.values()].flatMap((i) => [...new Set(i.flatMap((i$1) => i$1.atomicStyleIds))]))];
497
+ __pikacss_core.log.debug(`Collecting ${atomicStyleIds.length} atomic style IDs`);
419
498
  return [
420
499
  `/* Auto-generated by ${ctx.currentPackageName} */`,
421
- await ctx.engine.renderPreflights(isDev),
422
- await ctx.engine.renderAtomicStyles(isDev, { atomicStyleIds })
500
+ await ctx.engine.renderPreflights(true),
501
+ await ctx.engine.renderAtomicStyles(true, { atomicStyleIds })
423
502
  ].join("\n").trim();
424
503
  },
425
504
  getTsCodegenContent: async () => {
426
- if (ctx.isReady === false || ctx.tsCodegenFilepath == null) return null;
505
+ await ctx.setupPromise;
506
+ if (ctx.tsCodegenFilepath == null) return null;
427
507
  return await generateTsCodegenContent(ctx);
428
508
  },
429
- writeDevCssFile: (0, perfect_debounce.debounce)(async () => {
430
- const content = await ctx.getCssContent(true);
509
+ writeCssCodegenFile: async () => {
510
+ await ctx.setupPromise;
511
+ const content = await ctx.getCssCodegenContent();
431
512
  if (content == null) return;
432
- await (0, node_fs_promises.writeFile)(ctx.devCssFilepath, content);
433
- }, 300),
434
- writeTsCodegenFile: (0, perfect_debounce.debounce)(async () => {
513
+ await (0, node_fs_promises.mkdir)((0, pathe.dirname)(ctx.cssCodegenFilepath), { recursive: true }).catch(() => {});
514
+ __pikacss_core.log.debug(`Writing CSS code generation file: ${ctx.cssCodegenFilepath}`);
515
+ await (0, node_fs_promises.writeFile)(ctx.cssCodegenFilepath, content);
516
+ },
517
+ writeTsCodegenFile: async () => {
518
+ await ctx.setupPromise;
519
+ if (ctx.tsCodegenFilepath == null) return;
435
520
  const content = await ctx.getTsCodegenContent();
436
- if (ctx.tsCodegenFilepath == null || content == null) return;
521
+ if (content == null) return;
522
+ await (0, node_fs_promises.mkdir)((0, pathe.dirname)(ctx.tsCodegenFilepath), { recursive: true }).catch(() => {});
523
+ __pikacss_core.log.debug(`Writing TypeScript code generation file: ${ctx.tsCodegenFilepath}`);
437
524
  await (0, node_fs_promises.writeFile)(ctx.tsCodegenFilepath, content);
438
- }, 300)
525
+ },
526
+ fullyCssCodegen: async () => {
527
+ await ctx.setupPromise;
528
+ __pikacss_core.log.debug("Starting full CSS code generation scan");
529
+ const stream = (0, globby.globbyStream)(options.scan.include, { ignore: options.scan.exclude });
530
+ let fileCount = 0;
531
+ const _cwd = cwd();
532
+ for await (const entry of stream) {
533
+ const code = await (0, node_fs_promises.readFile)((0, pathe.join)(_cwd, entry), "utf-8");
534
+ await ctx.transform(code, entry);
535
+ fileCount++;
536
+ }
537
+ __pikacss_core.log.debug(`Scanned ${fileCount} files for style collection`);
538
+ await ctx.writeCssCodegenFile();
539
+ },
540
+ setupPromise: null,
541
+ setup: () => {
542
+ ctx.setupPromise = setup().catch((error) => {
543
+ __pikacss_core.log.error(`Failed to setup integration context: ${error.message}`, error);
544
+ }).then(() => {
545
+ ctx.setupPromise = null;
546
+ });
547
+ return ctx.setupPromise;
548
+ }
439
549
  };
440
- await ctx.init();
550
+ async function setup() {
551
+ __pikacss_core.log.debug("Setting up integration context");
552
+ usages.clear();
553
+ hooks.styleUpdated.listeners.clear();
554
+ hooks.tsCodegenUpdated.listeners.clear();
555
+ engine(null);
556
+ await loadConfig();
557
+ const devPlugin = (0, __pikacss_core.defineEnginePlugin)({
558
+ name: "@pikacss/integration:dev",
559
+ preflightUpdated: () => hooks.styleUpdated.trigger(),
560
+ atomicStyleAdded: () => hooks.styleUpdated.trigger(),
561
+ autocompleteConfigUpdated: () => hooks.tsCodegenUpdated.trigger()
562
+ });
563
+ try {
564
+ const config = resolvedConfig() ?? {};
565
+ config.plugins = config.plugins ?? [];
566
+ config.plugins.unshift(devPlugin);
567
+ __pikacss_core.log.debug("Creating engine with loaded/default config");
568
+ engine(await (0, __pikacss_core.createEngine)(config));
569
+ } catch (error) {
570
+ __pikacss_core.log.error(`Failed to create engine: ${error.message}. Falling back to default config.`, error);
571
+ engine(await (0, __pikacss_core.createEngine)({ plugins: [devPlugin] }));
572
+ }
573
+ __pikacss_core.log.debug("Integration context setup successfully");
574
+ }
441
575
  return ctx;
442
576
  }
443
577