@fictjs/vite-plugin 0.16.0 → 0.17.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/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  // src/index.ts
2
2
  import { createHash } from "crypto";
3
- import { promises as fs } from "fs";
3
+ import { promises as fs, readFileSync } from "fs";
4
+ import { createRequire } from "module";
4
5
  import path from "path";
5
6
  import { fileURLToPath, pathToFileURL } from "url";
6
7
  import { transformAsync } from "@babel/core";
@@ -11,7 +12,11 @@ import * as t from "@babel/types";
11
12
  import { createFictPlugin } from "@fictjs/compiler";
12
13
  var traverse = typeof _traverse === "function" ? _traverse : _traverse.default;
13
14
  var generate = typeof _generate === "function" ? _generate : _generate.default;
14
- var CACHE_VERSION = 1;
15
+ var CACHE_VERSION = 3;
16
+ var require2 = createRequire(import.meta.url);
17
+ var TRANSFORM_CACHE_FINGERPRINT = hashString(
18
+ [getCompilerCacheFingerprint(), String(extractAndRewriteHandlers)].join("|")
19
+ );
15
20
  var MODULE_EXTENSIONS = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".mts", ".cts"];
16
21
  var VIRTUAL_HANDLER_PREFIX = "\0fict-handler:";
17
22
  var VIRTUAL_HANDLER_RESOLVE_PREFIX = "virtual:fict-handler:";
@@ -127,6 +132,9 @@ function fict(options = {}) {
127
132
  "fict",
128
133
  "fict/plus",
129
134
  "fict/advanced",
135
+ "fict/internal",
136
+ "fict/internal/list",
137
+ "fict/loader",
130
138
  "fict/slim",
131
139
  "fict/jsx-runtime",
132
140
  "fict/jsx-dev-runtime",
@@ -147,7 +155,12 @@ function fict(options = {}) {
147
155
  include2.delete(dep);
148
156
  exclude2.add(dep);
149
157
  }
150
- const dedupePackages = ["fict", "@fictjs/runtime", "@fictjs/runtime/internal"];
158
+ const dedupePackages = [
159
+ "fict",
160
+ "fict/internal",
161
+ "@fictjs/runtime",
162
+ "@fictjs/runtime/internal"
163
+ ];
151
164
  for (const dep of dedupePackages) {
152
165
  dedupe.add(dep);
153
166
  }
@@ -266,16 +279,34 @@ function fict(options = {}) {
266
279
  }
267
280
  const cacheStore = ensureCache();
268
281
  const cacheKey = cacheStore.enabled ? buildCacheKey(filename, code, fictOptions, tsProject2) : null;
282
+ const shouldSplit = options.functionSplitting ?? (config?.command === "build" && (compilerOptions.resumable || !config?.build?.ssr));
269
283
  if (cacheKey) {
270
284
  const cached = await cacheStore.get(cacheKey);
271
285
  if (cached) {
272
- return cached;
286
+ if (shouldSplit && cached.extractedHandlers?.length) {
287
+ for (const handler of cached.extractedHandlers) {
288
+ const handlerId = createHandlerId(handler.sourceModule, handler.exportName);
289
+ extractedHandlers.set(handlerId, handler);
290
+ if (config?.command === "build" && !config?.build?.ssr) {
291
+ this.emitFile({
292
+ type: "chunk",
293
+ id: `${VIRTUAL_HANDLER_RESOLVE_PREFIX}${handlerId}`,
294
+ name: `handler-${handler.exportName}`
295
+ });
296
+ }
297
+ }
298
+ }
299
+ return {
300
+ code: cached.code,
301
+ map: cached.map
302
+ };
273
303
  }
274
304
  }
275
305
  try {
276
306
  const precompiledInput = isPrecompiledFictModule(code);
277
307
  let finalCode;
278
308
  let finalMap;
309
+ let splitResult = null;
279
310
  if (precompiledInput) {
280
311
  finalCode = code;
281
312
  finalMap = null;
@@ -297,7 +328,6 @@ function fict(options = {}) {
297
328
  finalCode = result.code;
298
329
  finalMap = result.map;
299
330
  }
300
- const shouldSplit = options.functionSplitting ?? (config?.command === "build" && (compilerOptions.resumable || !config?.build?.ssr));
301
331
  debugLog("Function split decision", {
302
332
  shouldSplit,
303
333
  ssr: config?.build?.ssr,
@@ -305,7 +335,6 @@ function fict(options = {}) {
305
335
  file: filename
306
336
  });
307
337
  if (shouldSplit) {
308
- let splitResult = null;
309
338
  try {
310
339
  splitResult = extractAndRewriteHandlers(finalCode, filename, extractedHandlers);
311
340
  } catch (error) {
@@ -339,7 +368,14 @@ function fict(options = {}) {
339
368
  map: finalMap
340
369
  };
341
370
  if (cacheKey) {
342
- await cacheStore.set(cacheKey, transformed);
371
+ const cachedTransform = {
372
+ code: finalCode,
373
+ map: finalMap
374
+ };
375
+ if (shouldSplit && splitResult?.handlers.length) {
376
+ cachedTransform.extractedHandlers = splitResult.handlers.map((handlerName) => extractedHandlers.get(createHandlerId(filename, handlerName))).filter((handler) => !!handler);
377
+ }
378
+ await cacheStore.set(cacheKey, cachedTransform);
343
379
  }
344
380
  return transformed;
345
381
  } catch (error) {
@@ -504,6 +540,14 @@ function applyAlias(source, aliases) {
504
540
  function hashString(value) {
505
541
  return createHash("sha256").update(value).digest("hex");
506
542
  }
543
+ function getCompilerCacheFingerprint() {
544
+ try {
545
+ const compilerEntry = require2.resolve("@fictjs/compiler");
546
+ return hashString(readFileSync(compilerEntry, "utf8"));
547
+ } catch {
548
+ return hashString(String(createFictPlugin));
549
+ }
550
+ }
507
551
  function stableStringify(value) {
508
552
  if (value === null || typeof value !== "object") {
509
553
  return JSON.stringify(value);
@@ -535,7 +579,9 @@ function buildCacheKey(filename, code, options, tsProject) {
535
579
  const codeHash = hashString(code);
536
580
  const optionsHash = hashString(stableStringify(normalizeOptionsForCache(options)));
537
581
  const tsKey = tsProject ? `${tsProject.configHash}:${tsProject.projectVersion}` : "";
538
- return hashString([CACHE_VERSION, filename, codeHash, optionsHash, tsKey].join("|"));
582
+ return hashString(
583
+ [CACHE_VERSION, TRANSFORM_CACHE_FINGERPRINT, filename, codeHash, optionsHash, tsKey].join("|")
584
+ );
539
585
  }
540
586
  var TransformCache = class {
541
587
  constructor(options) {
@@ -684,6 +730,30 @@ async function createTypeScriptProject(ts, rootDir, configPath) {
684
730
  function createHandlerId(sourceModule, exportName) {
685
731
  return `${sourceModule}$$${exportName}`;
686
732
  }
733
+ function detectRuntimeImportFamilyFromCode(body) {
734
+ let sawFictFamily = false;
735
+ let sawStandaloneRuntimeFamily = false;
736
+ for (const stmt of body) {
737
+ const source = stmt && typeof stmt === "object" && "source" in stmt ? stmt.source?.value : void 0;
738
+ if (typeof source !== "string") continue;
739
+ if (source === "fict" || source === "fict/advanced" || source === "fict/internal" || source === "fict/internal/list" || source === "fict/jsx-runtime" || source === "fict/jsx-dev-runtime" || source === "fict/loader" || source === "fict/plus" || source === "fict/slim") {
740
+ sawFictFamily = true;
741
+ continue;
742
+ }
743
+ if (source === "@fictjs/runtime" || source === "@fictjs/runtime/advanced" || source === "@fictjs/runtime/internal" || source === "@fictjs/runtime/internal/list" || source === "@fictjs/runtime/jsx-runtime" || source === "@fictjs/runtime/jsx-dev-runtime" || source === "@fictjs/runtime/loader") {
744
+ sawStandaloneRuntimeFamily = true;
745
+ }
746
+ }
747
+ if (sawFictFamily) return "fict";
748
+ if (sawStandaloneRuntimeFamily) return "runtime";
749
+ return "fict";
750
+ }
751
+ function getRuntimeHelperModule(helperName, family) {
752
+ if (helperName === "keyedList") {
753
+ return family === "runtime" ? "@fictjs/runtime/internal/list" : "fict/internal/list";
754
+ }
755
+ return family === "runtime" ? "@fictjs/runtime/internal" : "fict/internal";
756
+ }
687
757
  function generateHandlerModule(handler) {
688
758
  if (!handler.code) {
689
759
  return `export { ${handler.exportName} as default } from '${handler.sourceModule}';
@@ -693,11 +763,12 @@ function generateHandlerModule(handler) {
693
763
  for (const helperName of handler.helpersUsed) {
694
764
  const helper = RUNTIME_HELPERS[helperName];
695
765
  if (!helper) continue;
696
- const existing = importsByModule.get(helper.from) ?? [];
766
+ const moduleSource = getRuntimeHelperModule(helperName, handler.runtimeImportFamily);
767
+ const existing = importsByModule.get(moduleSource) ?? [];
697
768
  if (!existing.includes(helper.import)) {
698
769
  existing.push(helper.import);
699
770
  }
700
- importsByModule.set(helper.from, existing);
771
+ importsByModule.set(moduleSource, existing);
701
772
  }
702
773
  const imports = [];
703
774
  for (const [module, names] of importsByModule) {
@@ -718,20 +789,21 @@ function registerExtractedHandler(sourceModule, exportName, helpersUsed, code, l
718
789
  exportName,
719
790
  helpersUsed,
720
791
  localDeps,
721
- code
792
+ code,
793
+ runtimeImportFamily: "fict"
722
794
  });
723
795
  return `${VIRTUAL_HANDLER_RESOLVE_PREFIX}${handlerId}`;
724
796
  }
725
797
  var RUNTIME_HELPERS = {
726
- __fictUseLexicalScope: { import: "__fictUseLexicalScope", from: "@fictjs/runtime/internal" },
727
- __fictGetScopeProps: { import: "__fictGetScopeProps", from: "@fictjs/runtime/internal" },
728
- __fictGetSSRScope: { import: "__fictGetSSRScope", from: "@fictjs/runtime/internal" },
729
- __fictEnsureScope: { import: "__fictEnsureScope", from: "@fictjs/runtime/internal" },
730
- __fictPrepareContext: { import: "__fictPrepareContext", from: "@fictjs/runtime/internal" },
731
- __fictPushContext: { import: "__fictPushContext", from: "@fictjs/runtime/internal" },
732
- __fictPopContext: { import: "__fictPopContext", from: "@fictjs/runtime/internal" },
733
- hydrateComponent: { import: "hydrateComponent", from: "@fictjs/runtime/internal" },
734
- __fictQrl: { import: "__fictQrl", from: "@fictjs/runtime/internal" }
798
+ __fictUseLexicalScope: { import: "__fictUseLexicalScope", from: "fict/internal" },
799
+ __fictGetScopeProps: { import: "__fictGetScopeProps", from: "fict/internal" },
800
+ __fictGetSSRScope: { import: "__fictGetSSRScope", from: "fict/internal" },
801
+ __fictEnsureScope: { import: "__fictEnsureScope", from: "fict/internal" },
802
+ __fictPrepareContext: { import: "__fictPrepareContext", from: "fict/internal" },
803
+ __fictPushContext: { import: "__fictPushContext", from: "fict/internal" },
804
+ __fictPopContext: { import: "__fictPopContext", from: "fict/internal" },
805
+ hydrateComponent: { import: "hydrateComponent", from: "fict/internal" },
806
+ __fictQrl: { import: "__fictQrl", from: "fict/internal" }
735
807
  };
736
808
  var GLOBAL_IDENTIFIERS = /* @__PURE__ */ new Set([
737
809
  // JavaScript globals
@@ -1004,6 +1076,7 @@ function extractAndRewriteHandlers(code, sourceModule, handlerRegistry) {
1004
1076
  const handlerNames = [];
1005
1077
  const nodesToRemove = /* @__PURE__ */ new Set();
1006
1078
  const allLocalDeps = /* @__PURE__ */ new Set();
1079
+ const runtimeImportFamily = detectRuntimeImportFamilyFromCode(ast.program.body);
1007
1080
  traverse(ast, {
1008
1081
  ExportNamedDeclaration(path2) {
1009
1082
  const declaration = path2.node.declaration;
@@ -1036,7 +1109,8 @@ function extractAndRewriteHandlers(code, sourceModule, handlerRegistry) {
1036
1109
  exportName: name,
1037
1110
  helpersUsed,
1038
1111
  localDeps,
1039
- code: handlerCode
1112
+ code: handlerCode,
1113
+ runtimeImportFamily
1040
1114
  });
1041
1115
  nodesToRemove.add(path2.node);
1042
1116
  }
@@ -1071,7 +1145,8 @@ function extractAndRewriteHandlers(code, sourceModule, handlerRegistry) {
1071
1145
  exportName: name,
1072
1146
  helpersUsed,
1073
1147
  localDeps,
1074
- code: handlerCode
1148
+ code: handlerCode,
1149
+ runtimeImportFamily
1075
1150
  });
1076
1151
  nodesToRemove.add(path2.node);
1077
1152
  }