@navecss/core 0.5.0 → 0.6.0

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.
@@ -383,6 +383,171 @@ function isImportingCx(program, sources) {
383
383
  });
384
384
  }
385
385
 
386
+ // src/vite-cx-member.ts
387
+ var READ_MEMBERS = /* @__PURE__ */ new Set(["dynamic", "raw"]);
388
+ var CALL_MEMBERS = /* @__PURE__ */ new Set(["apply", "call"]);
389
+ var LEFT_TARGETS = /* @__PURE__ */ new Set([
390
+ "AssignmentExpression",
391
+ "AssignmentPattern",
392
+ "ForInStatement",
393
+ "ForOfStatement"
394
+ ]);
395
+ var WHOLE_TARGETS = /* @__PURE__ */ new Set([
396
+ "ArrayPattern",
397
+ "RestElement",
398
+ "UpdateExpression"
399
+ ]);
400
+ function unwrapped(analysis, node) {
401
+ let current = node;
402
+ for (; ; ) {
403
+ const parent = analysis.parentOf.get(current);
404
+ if (!parent || wrappedBy(parent) !== current) return current;
405
+ current = parent;
406
+ }
407
+ }
408
+ function isMemberWrite(analysis, member) {
409
+ const top = unwrapped(analysis, member);
410
+ const parent = analysis.parentOf.get(top);
411
+ if (!parent) return false;
412
+ if (LEFT_TARGETS.has(parent.type)) return nodeAt(parent, "left") === top;
413
+ if (WHOLE_TARGETS.has(parent.type)) return true;
414
+ if (parent.type === "UnaryExpression") return parent.operator === "delete";
415
+ return parent.type === "Property" && nodeAt(parent, "value") === top && analysis.parentOf.get(parent)?.type === "ObjectPattern";
416
+ }
417
+ function isCallee(analysis, member) {
418
+ const top = unwrapped(analysis, member);
419
+ const parent = analysis.parentOf.get(top);
420
+ return parent?.type === "CallExpression" && nodeAt(parent, "callee") === top;
421
+ }
422
+ function memberRoleOf(analysis, member) {
423
+ if (member.computed === true || isMemberWrite(analysis, member)) return "unknown";
424
+ const name = propertyNameOf(nodeAt(member, "property"), false);
425
+ if (name !== void 0 && READ_MEMBERS.has(name)) return "read";
426
+ if (name === void 0 || !CALL_MEMBERS.has(name)) return "unknown";
427
+ return isCallee(analysis, member) ? "call" : "read";
428
+ }
429
+
430
+ // src/vite-cx-flow.ts
431
+ var CALLED = { kind: "called" };
432
+ var SAFE = { kind: "safe" };
433
+ var UNBOUND = { kind: "unbound" };
434
+ var HARMLESS_PARENTS = /* @__PURE__ */ new Set(["ExpressionStatement", "UnaryExpression"]);
435
+ var TESTING_PARENTS = /* @__PURE__ */ new Set([
436
+ "ConditionalExpression",
437
+ "DoWhileStatement",
438
+ "ForStatement",
439
+ "IfStatement",
440
+ "WhileStatement"
441
+ ]);
442
+ function ownExportOf(analysis, declarator) {
443
+ const declaration = analysis.parentOf.get(declarator);
444
+ const statement = declaration && analysis.parentOf.get(declaration);
445
+ if (statement?.type !== "ExportNamedDeclaration") return void 0;
446
+ const id = nodeAt(declarator, "id");
447
+ return id ? exportNameOf(id) : void 0;
448
+ }
449
+ function isMemberPattern(pattern) {
450
+ if (pattern.type !== "ObjectPattern") return false;
451
+ return nodesAt(pattern, "properties").every((property) => {
452
+ if (property.type !== "Property") return false;
453
+ if (property.computed === true) return false;
454
+ const name = propertyNameOf(nodeAt(property, "key"), false);
455
+ return name !== void 0 && READ_MEMBERS.has(name);
456
+ });
457
+ }
458
+ function declaredStep(analysis, declarator) {
459
+ const id = nodeAt(declarator, "id");
460
+ if (id?.type === "Identifier") {
461
+ const exportedAs = ownExportOf(analysis, declarator);
462
+ return { kind: "aliased", id, ...exportedAs !== void 0 && { exportedAs } };
463
+ }
464
+ return id && isMemberPattern(id) ? SAFE : UNBOUND;
465
+ }
466
+ function memberStep(analysis, node) {
467
+ const role = memberRoleOf(analysis, node);
468
+ if (role === "call") return CALLED;
469
+ return role === "read" ? SAFE : UNBOUND;
470
+ }
471
+ function exportStep(parent) {
472
+ if (parent.type === "ExportDefaultDeclaration") return { kind: "exported", name: "default" };
473
+ const name = exportNameOf(nodeAt(parent, "exported"));
474
+ return name === void 0 ? UNBOUND : { kind: "exported", name };
475
+ }
476
+ function isHarmlessOperation(analysis, top, parent) {
477
+ if (parent.type === "BinaryExpression") {
478
+ return !(parent.operator === "instanceof" && nodeAt(parent, "left") === top);
479
+ }
480
+ const tag = analysis.parentOf.get(parent);
481
+ return !(tag?.type === "TaggedTemplateExpression" && nodeAt(tag, "quasi") === parent);
482
+ }
483
+ function readingStep(analysis, top, parent) {
484
+ const { type } = parent;
485
+ if (TESTING_PARENTS.has(type)) return nodeAt(parent, "test") === top ? SAFE : UNBOUND;
486
+ if (type === "BinaryExpression" || type === "TemplateLiteral") {
487
+ return isHarmlessOperation(analysis, top, parent) ? SAFE : UNBOUND;
488
+ }
489
+ if (type === "SpreadElement" || HARMLESS_PARENTS.has(type)) return SAFE;
490
+ if (type !== "SequenceExpression") return UNBOUND;
491
+ return nodesAt(parent, "expressions").at(-1) === top ? stepOf(analysis, parent) : SAFE;
492
+ }
493
+ function stepAbove(analysis, top, parent) {
494
+ switch (parent.type) {
495
+ case "CallExpression": {
496
+ return nodeAt(parent, "callee") === top ? CALLED : UNBOUND;
497
+ }
498
+ case "ExportDefaultDeclaration":
499
+ case "ExportSpecifier": {
500
+ return exportStep(parent);
501
+ }
502
+ case "MemberExpression": {
503
+ return nodeAt(parent, "object") === top ? memberStep(analysis, parent) : SAFE;
504
+ }
505
+ case "VariableDeclarator": {
506
+ return nodeAt(parent, "init") === top ? declaredStep(analysis, parent) : SAFE;
507
+ }
508
+ default: {
509
+ return readingStep(analysis, top, parent);
510
+ }
511
+ }
512
+ }
513
+ function stepOf(analysis, node) {
514
+ const top = unwrapped(analysis, node);
515
+ const parent = analysis.parentOf.get(top);
516
+ return parent ? stepAbove(analysis, top, parent) : UNBOUND;
517
+ }
518
+ function usesOfAlias(analysis, id) {
519
+ const alias = analysis.bindingDeclaredBy(id);
520
+ if (!alias) return { isWritten: true, nodes: [] };
521
+ const uses = analysis.references.filter(({ binding }) => binding === alias);
522
+ return { isWritten: alias.writes > 0, nodes: uses.map(({ node }) => node) };
523
+ }
524
+ function flowOf(analysis, start) {
525
+ const names = /* @__PURE__ */ new Set();
526
+ const state = { isCalled: false, isUnbound: false };
527
+ const seen = /* @__PURE__ */ new Set();
528
+ const stack = [start];
529
+ while (stack.length > 0 && !state.isUnbound) {
530
+ const node = stack.pop();
531
+ if (seen.has(node)) continue;
532
+ seen.add(node);
533
+ followStep(stepOf(analysis, node), { analysis, names, stack, state });
534
+ }
535
+ return { ...state, names };
536
+ }
537
+ function followStep(step, walk) {
538
+ const { analysis, names, stack, state } = walk;
539
+ if (step.kind === "aliased") {
540
+ if (step.exportedAs !== void 0) names.add(step.exportedAs);
541
+ const alias = usesOfAlias(analysis, step.id);
542
+ state.isUnbound = alias.isWritten;
543
+ pushAll(stack, alias.nodes);
544
+ return;
545
+ }
546
+ if (step.kind === "exported") names.add(step.name);
547
+ state.isCalled ||= step.kind === "called";
548
+ state.isUnbound ||= step.kind === "unbound";
549
+ }
550
+
386
551
  // src/vite-cx-refuse.ts
387
552
  function textOf(reading, node) {
388
553
  return reading.code.slice(node.start, node.end);
@@ -431,8 +596,41 @@ function isRenamedReexportOf(reading, expression) {
431
596
  return parent?.type === "ExportSpecifier" && exportNameOf(nodeAt(parent, "exported")) !== "cx";
432
597
  }
433
598
 
599
+ // src/vite-cx-hand-out.ts
600
+ function reexportedAs(reading, expression) {
601
+ const name = reexportNameOf(reading, expression);
602
+ return name === void 0 ? void 0 : { exportedAs: [name] };
603
+ }
604
+ function unboundIn(reading, use) {
605
+ return reading.isDependency === true ? { ...use, isUnboundHandOut: true } : use;
606
+ }
607
+ function handOutOf(reading, expression) {
608
+ if (reading.isDependency !== true) return {};
609
+ const flow = flowOf(reading.analysis, expression);
610
+ if (flow.isUnbound) return { isUnboundHandOut: true };
611
+ if (flow.names.size === 0) return {};
612
+ return { exportedAs: [...flow.names], isRenamed: true };
613
+ }
614
+
615
+ // src/vite-cx-unref.ts
616
+ function isVueUnref(reading, callee) {
617
+ if (callee?.type !== "Identifier") return false;
618
+ const binding = reading.analysis.referenceOf(callee)?.binding;
619
+ return binding?.kind === "import" && binding.source === "vue" && binding.imported === "unref";
620
+ }
621
+ function throughUnref(reading, expression) {
622
+ let current = expression;
623
+ for (; ; ) {
624
+ const call = reading.analysis.parentOf.get(current);
625
+ const args = call ? nodesAt(call, "arguments") : [];
626
+ const isUnref = call?.type === "CallExpression" && args.length === 1 && args[0] === current && isVueUnref(reading, nodeAt(call, "callee"));
627
+ if (!isUnref) return current;
628
+ current = call;
629
+ }
630
+ }
631
+
434
632
  // src/vite-cx-reference.ts
435
- function isCallee(parent, node) {
633
+ function isCallee2(parent, node) {
436
634
  return parent?.type === "CallExpression" && nodeAt(parent, "callee") === node;
437
635
  }
438
636
  function isOnlyRaw(pattern) {
@@ -447,38 +645,37 @@ function refused(node, local, phrase) {
447
645
  }
448
646
  function rawMemberUse(parent, member, local) {
449
647
  const isAlias = parent?.type === "VariableDeclarator" && nodeAt(parent, "init") === member && nodeAt(parent, "id")?.type === "Identifier";
450
- if (isAlias || isCallee(parent, member)) return { kind: "raw", node: member, local };
648
+ if (isAlias || isCallee2(parent, member)) return { kind: "raw", node: member, local };
451
649
  return refused(member, local, `${local}.raw is used other than by calling it`);
452
650
  }
453
651
  function memberUse(reading, member, local) {
652
+ const use = namedMemberUse(reading, member, local);
653
+ const isUnbound = member.computed === true || isMemberWrite(reading.analysis, member);
654
+ if (!isUnbound || reading.isDependency !== true) return use;
655
+ return unboundIn(
656
+ reading,
657
+ use.kind === "refused" ? use : refused(member, local, `${local} is read with a computed member`)
658
+ );
659
+ }
660
+ function namedMemberUse(reading, member, local) {
454
661
  const parent = reading.analysis.parentOf.get(member);
455
662
  const isComputed = member.computed === true;
456
663
  const name = propertyNameOf(nodeAt(member, "property"), isComputed);
457
664
  if (name === "raw") return rawMemberUse(parent, member, local);
458
665
  if (name === "dynamic" && !isComputed) {
459
- if (parent && isCallee(parent, member)) return { kind: "dynamic", node: parent, local };
666
+ if (parent && isCallee2(parent, member)) return { kind: "dynamic", node: parent, local };
460
667
  return refused(member, local, `${local}.dynamic is referenced other than by a direct call`);
461
668
  }
462
669
  if (name === "call" || name === "apply") {
463
670
  return refused(member, local, `${local} is called through .${name}()`);
464
671
  }
465
- if (isComputed) return refused(member, local, `${local} is read with a computed member`);
466
- return refused(member, local, `${local}.${name ?? "?"} is not a member the build reads`);
467
- }
468
- function isVueUnref(reading, callee) {
469
- if (callee?.type !== "Identifier") return false;
470
- const binding = reading.analysis.referenceOf(callee)?.binding;
471
- return binding?.kind === "import" && binding.source === "vue" && binding.imported === "unref";
672
+ return otherMemberUse(reading, member, { local, name, isComputed });
472
673
  }
473
- function throughUnref(reading, expression) {
474
- let current = expression;
475
- for (; ; ) {
476
- const call = reading.analysis.parentOf.get(current);
477
- const args = call ? nodesAt(call, "arguments") : [];
478
- const isUnref = call?.type === "CallExpression" && args.length === 1 && args[0] === current && isVueUnref(reading, nodeAt(call, "callee"));
479
- if (!isUnref) return current;
480
- current = call;
481
- }
674
+ function otherMemberUse(reading, member, read) {
675
+ const { isComputed, local, name } = read;
676
+ const phrase = isComputed ? `${local} is read with a computed member` : `${local}.${name ?? "?"} is not a member the build reads`;
677
+ const use = refused(member, local, phrase);
678
+ return unboundIn(reading, use);
482
679
  }
483
680
  function ancestor(reading, node, levels) {
484
681
  let current = node;
@@ -506,7 +703,7 @@ function rawDestructuring(parent, expression, local) {
506
703
  function readableUse(reading, expression, local) {
507
704
  const parent = reading.analysis.parentOf.get(expression);
508
705
  if (!parent) return void 0;
509
- if (isCallee(parent, expression)) return { kind: "call", node: parent, local };
706
+ if (isCallee2(parent, expression)) return { kind: "call", node: parent, local };
510
707
  if (parent.type === "MemberExpression" && nodeAt(parent, "object") === expression) {
511
708
  return memberUse(reading, parent, local);
512
709
  }
@@ -518,21 +715,16 @@ function useOfExpression(reading, start, local) {
518
715
  if (readable) return readable;
519
716
  const exposedAs = exposureName(reading, expression);
520
717
  if (exposedAs !== void 0) return { kind: "exposure", node: expression, local, exposedAs };
521
- const phrase = phraseFor(reading, expression, local);
522
718
  const isReexport = isReexportOf(reading, expression);
523
719
  const isRenamed = isReexport && isRenamedReexportOf(reading, expression);
524
- const exportedAs = reexportedAs(reading, expression);
525
720
  return {
526
- ...refused(expression, local, phrase),
721
+ ...refused(expression, local, phraseFor(reading, expression, local)),
527
722
  isReexport,
528
723
  ...isRenamed && { isRenamed },
529
- ...exportedAs
724
+ ...reexportedAs(reading, expression),
725
+ ...!isReexport && handOutOf(reading, expression)
530
726
  };
531
727
  }
532
- function reexportedAs(reading, expression) {
533
- const name = reexportNameOf(reading, expression);
534
- return name === void 0 ? void 0 : { exportedAs: [name] };
535
- }
536
728
  function isOtherKey(property) {
537
729
  if (property.type !== "Property") return false;
538
730
  const name = propertyNameOf(nodeAt(property, "key"), property.computed === true);
@@ -569,7 +761,9 @@ function namespaceUse(reading, expression, cx) {
569
761
  if (isListed && isOtherExport) return void 0;
570
762
  const use = refused(expression, local, `${local} is used other than as ${local}.cx`);
571
763
  const exportedAs = reexportedAs(reading, expression);
572
- return exportedAs ? { ...use, ...exportedAs, isRenamed: true } : use;
764
+ if (exportedAs) return { ...use, ...exportedAs, isRenamed: true };
765
+ if (patternDestructuring(reading, expression)) return unboundIn(reading, use);
766
+ return { ...use, ...handOutOf(reading, expression) };
573
767
  }
574
768
  function useOf(reading, reference2, cx) {
575
769
  if (cx.isNamespace) return namespaceUse(reading, reference2.node, cx);
@@ -580,6 +774,407 @@ function useOf(reading, reference2, cx) {
580
774
  return { ...use, isListable: !isDeclaredSource };
581
775
  }
582
776
 
777
+ // src/vite-cx-take-keys.ts
778
+ var CX_ONLY = /* @__PURE__ */ new Set(["cx"]);
779
+ function isCxName(names, name) {
780
+ return names === void 0 || names.has(name);
781
+ }
782
+ function patternKeys(pattern, names) {
783
+ const taken = [];
784
+ for (const property of nodesAt(pattern, "properties")) {
785
+ const key = property.type === "Property" ? propertyNameOf(nodeAt(property, "key"), property.computed === true) : void 0;
786
+ if (key === void 0) return void 0;
787
+ if (isCxName(names, key)) taken.push(key);
788
+ }
789
+ return taken;
790
+ }
791
+ function referenceTakes(analysis, node, names) {
792
+ const read = memberReadOf({ analysis }, node);
793
+ if (read) {
794
+ if (read.key === void 0) return void 0;
795
+ return isCxName(names, read.key) ? [read.key] : [];
796
+ }
797
+ const pattern = patternDestructuring({ analysis }, node);
798
+ return pattern?.type === "ObjectPattern" ? patternKeys(pattern, names) : void 0;
799
+ }
800
+ function outermost(analysis, node) {
801
+ let current = node;
802
+ let parent = analysis.parentOf.get(current);
803
+ while (parent?.type === "ParenthesizedExpression") {
804
+ current = parent;
805
+ parent = analysis.parentOf.get(current);
806
+ }
807
+ return current;
808
+ }
809
+ function thenCall(analysis, node) {
810
+ const member = analysis.parentOf.get(node);
811
+ if (member?.type !== "MemberExpression" || nodeAt(member, "object") !== node) return void 0;
812
+ const key = propertyNameOf(nodeAt(member, "property"), member.computed === true);
813
+ const call = analysis.parentOf.get(member);
814
+ return key === "then" && call?.type === "CallExpression" && nodeAt(call, "callee") === member ? call : void 0;
815
+ }
816
+ function thenCallback(analysis, node) {
817
+ const call = thenCall(analysis, node);
818
+ const callback = call && nodesAt(call, "arguments")[0];
819
+ const isInline = callback?.type === "ArrowFunctionExpression" || callback?.type === "FunctionExpression";
820
+ return isInline ? callback : void 0;
821
+ }
822
+ function referencesToParameter(analysis, owner, name) {
823
+ return analysis.references.filter(
824
+ ({ binding }) => binding?.kind === "param" && binding.owner === owner && binding.name === name
825
+ );
826
+ }
827
+ function parameterTakes(analysis, callback, names) {
828
+ const parameter = nodesAt(callback, "params")[0];
829
+ if (parameter === void 0) return [];
830
+ if (parameter.type === "ObjectPattern") return patternKeys(parameter, names);
831
+ const name = parameter.type === "Identifier" ? stringAt(parameter, "name") : void 0;
832
+ if (name === void 0) return void 0;
833
+ const found = [];
834
+ for (const { binding, node } of referencesToParameter(analysis, callback, name)) {
835
+ const taken = binding?.writes === 0 ? referenceTakes(analysis, node, names) : void 0;
836
+ if (taken === void 0) return void 0;
837
+ pushAll(found, taken);
838
+ }
839
+ return found;
840
+ }
841
+ function variableTakes(analysis, init, names) {
842
+ const declarator = analysis.parentOf.get(init);
843
+ const declaration = declarator && analysis.parentOf.get(declarator);
844
+ if (declaration && analysis.parentOf.get(declaration)?.type === "ExportNamedDeclaration") {
845
+ return void 0;
846
+ }
847
+ const found = [];
848
+ for (const { binding, node } of analysis.references) {
849
+ if (binding?.init !== init) continue;
850
+ const taken = binding.writes === 0 ? referenceTakes(analysis, node, names) : void 0;
851
+ if (taken === void 0) return void 0;
852
+ pushAll(found, taken);
853
+ }
854
+ return found;
855
+ }
856
+ function awaitedKeys(analysis, awaited, names) {
857
+ const declarator = analysis.parentOf.get(awaited);
858
+ const isVariable = declarator?.type === "VariableDeclarator" && nodeAt(declarator, "init") === awaited && nodeAt(declarator, "id")?.type === "Identifier";
859
+ return isVariable ? variableTakes(analysis, awaited, names) : referenceTakes(analysis, awaited, names);
860
+ }
861
+ function dynamicKeys(analysis, node, names) {
862
+ const awaited = analysis.parentOf.get(node);
863
+ if (awaited?.type === "AwaitExpression") {
864
+ return awaitedKeys(analysis, outermost(analysis, awaited), names);
865
+ }
866
+ const callback = thenCallback(analysis, node);
867
+ return callback && parameterTakes(analysis, callback, names);
868
+ }
869
+
870
+ // src/vite-commonjs-exports.ts
871
+ function isName(node, name) {
872
+ return node?.type === "Identifier" && node.name === name;
873
+ }
874
+ function isModuleExports(node) {
875
+ if (node?.type !== "MemberExpression" || node.computed === true) return false;
876
+ return isName(nodeAt(node, "object"), "module") && isName(nodeAt(node, "property"), "exports");
877
+ }
878
+ function isExportsObject(node) {
879
+ return isName(node, "exports") || isModuleExports(node);
880
+ }
881
+ function memberOf(node) {
882
+ if (node?.type !== "MemberExpression" || node.computed === true) return void 0;
883
+ const object = nodeAt(node, "object");
884
+ const name = exportNameOf(nodeAt(node, "property"));
885
+ return object === void 0 || name === void 0 ? void 0 : { name, object };
886
+ }
887
+ function exportsMemberOf(node) {
888
+ const member = memberOf(node);
889
+ if (!member) return void 0;
890
+ return isExportsObject(member.object) ? member.name : void 0;
891
+ }
892
+ function statementCallOf(statement) {
893
+ if (statement.type !== "ExpressionStatement") return void 0;
894
+ const expression = nodeAt(statement, "expression");
895
+ return expression?.type === "CallExpression" ? expression : void 0;
896
+ }
897
+ function definePropertyOf(statement) {
898
+ const call = statementCallOf(statement);
899
+ const callee = call && memberOf(nodeAt(call, "callee"));
900
+ if (!call || callee?.name !== "defineProperty" || !isName(callee.object, "Object")) {
901
+ return void 0;
902
+ }
903
+ const [target, key, descriptor] = nodesAt(call, "arguments");
904
+ return { as: staticStringOf(key), descriptor, target };
905
+ }
906
+
907
+ // src/vite-commonjs-emits.ts
908
+ function initOf(analysis, name) {
909
+ const binding = analysis.referenceOf(name)?.binding;
910
+ return binding?.writes === 0 ? binding.init : void 0;
911
+ }
912
+ function isOwnHelperRead(node) {
913
+ const member = memberOf(node);
914
+ return member?.name === "__exportStar" && member.object.type === "ThisExpression";
915
+ }
916
+ function isThisGuard(node) {
917
+ if (node?.type !== "LogicalExpression" || node.operator !== "&&") return false;
918
+ return nodeAt(node, "left")?.type === "ThisExpression" && isOwnHelperRead(nodeAt(node, "right"));
919
+ }
920
+ function isOwnHelper(node) {
921
+ if (node?.type !== "LogicalExpression" || node.operator !== "||") return false;
922
+ return isThisGuard(nodeAt(node, "left")) && nodeAt(node, "right")?.type === "FunctionExpression";
923
+ }
924
+ function isTslibRequire(node) {
925
+ if (node?.type !== "CallExpression" || !isName(nodeAt(node, "callee"), "require")) return false;
926
+ const args = nodesAt(node, "arguments");
927
+ return args.length === 1 && staticStringOf(args[0]) === "tslib";
928
+ }
929
+ function isTslibMember(callee, analysis) {
930
+ const member = memberOf(callee);
931
+ if (member?.object.type !== "Identifier") return false;
932
+ return isTslibRequire(initOf(analysis, member.object));
933
+ }
934
+ function isExportStarCallee(callee, analysis) {
935
+ if (isName(callee, "__exportStar")) return isOwnHelper(initOf(analysis, callee));
936
+ return memberOf(callee)?.name === "__exportStar" && isTslibMember(callee, analysis);
937
+ }
938
+ function exportStarOf(statement, input) {
939
+ const call = statementCallOf(statement);
940
+ if (!call) return void 0;
941
+ const [required, target] = nodesAt(call, "arguments");
942
+ if (required === void 0 || !input.requires.has(required) || !isExportsObject(target)) {
943
+ return void 0;
944
+ }
945
+ const analysis = input.analysis();
946
+ const isHelper = !analysis.hasDirectEval && isExportStarCallee(nodeAt(call, "callee"), analysis);
947
+ return isHelper ? required : void 0;
948
+ }
949
+ function starForwardOf(statement, input) {
950
+ const required = exportStarOf(statement, input);
951
+ if (required === void 0) return void 0;
952
+ const named = input.names?.values().filter((name) => name !== "default").toArray();
953
+ const takes = named?.length === 0 ? [] : [{ shape: "star", names: [], isForward: true }];
954
+ return { given: named ?? [], require: required, takes };
955
+ }
956
+ function returnOf(block) {
957
+ const statements = nodesAt(block, "body");
958
+ const only = statements.length === 1 ? statements[0] : void 0;
959
+ return only?.type === "ReturnStatement" ? nodeAt(only, "argument") : void 0;
960
+ }
961
+ function returnedBy(getter) {
962
+ const isArrow = getter?.type === "ArrowFunctionExpression";
963
+ if (!getter || !isArrow && getter.type !== "FunctionExpression") return void 0;
964
+ const body = nodeAt(getter, "body");
965
+ if (body?.type === "BlockStatement") return returnOf(body);
966
+ return isArrow ? body : void 0;
967
+ }
968
+ function getterOf(descriptor) {
969
+ if (descriptor?.type !== "ObjectExpression") return void 0;
970
+ const property = nodesAt(descriptor, "properties").find((node) => {
971
+ const isGet = propertyNameOf(nodeAt(node, "key"), node.computed === true) === "get";
972
+ return node.type === "Property" && isGet;
973
+ });
974
+ return property && nodeAt(property, "value");
975
+ }
976
+ function getterReadOf(statement) {
977
+ const define = definePropertyOf(statement);
978
+ if (define?.as === void 0 || !isExportsObject(define.target)) return void 0;
979
+ const member = memberOf(returnedBy(getterOf(define.descriptor)));
980
+ if (member?.object.type !== "Identifier") return void 0;
981
+ return { as: define.as, name: member.name, object: member.object };
982
+ }
983
+ function boundForwardOf(require2, reads, context) {
984
+ const uses = context.analysis.references.filter(({ binding: binding2 }) => binding2?.init === require2);
985
+ const binding = uses[0]?.binding;
986
+ if (!binding || binding.writes > 0) return void 0;
987
+ const read = uses.map(({ node }) => reads.get(node));
988
+ if (read.includes(void 0)) return void 0;
989
+ const cx = read.filter((getter) => getter !== void 0 && isCxName(context.names, getter.name));
990
+ const names = [...new Set(cx.map((getter) => getter.name))];
991
+ const takes = names.length === 0 ? [] : [{ shape: "names", names, isPassedOn: true, isForward: true }];
992
+ return { given: cx.map((getter) => getter.as), require: require2, takes };
993
+ }
994
+ function boundForwardsOf(program, input) {
995
+ const reads = /* @__PURE__ */ new Map();
996
+ for (const statement of nodesAt(program, "body")) {
997
+ const read = getterReadOf(statement);
998
+ if (read) reads.set(read.object, read);
999
+ }
1000
+ if (reads.size === 0) return [];
1001
+ const analysis = input.analysis();
1002
+ if (analysis.hasDirectEval) return [];
1003
+ const context = { analysis, names: input.names };
1004
+ return [...input.requires].flatMap((require2) => {
1005
+ const forward = boundForwardOf(require2, reads, context);
1006
+ return forward ? [forward] : [];
1007
+ });
1008
+ }
1009
+
1010
+ // src/vite-require-interop.ts
1011
+ var INTEROP_HELPERS = /* @__PURE__ */ new Set([
1012
+ "__importDefault",
1013
+ "__importStar",
1014
+ "__toESM",
1015
+ "_interop_require_default",
1016
+ "_interop_require_wildcard",
1017
+ "_interopRequireDefault",
1018
+ "_interopRequireWildcard"
1019
+ ]);
1020
+ function isInteropCallee(analysis, callee) {
1021
+ if (callee?.type === "Identifier") {
1022
+ const binding = analysis.referenceOf(callee)?.binding;
1023
+ const isDeclared = binding !== void 0 && binding.kind !== "import" && binding.kind !== "param";
1024
+ return INTEROP_HELPERS.has(callee.name) && isDeclared;
1025
+ }
1026
+ const member = memberOf(callee);
1027
+ return member !== void 0 && INTEROP_HELPERS.has(member.name) && isTslibMember(callee, analysis);
1028
+ }
1029
+ function unwrappedFromInterop(analysis, node) {
1030
+ let current = node;
1031
+ for (; ; ) {
1032
+ const parent = analysis.parentOf.get(current);
1033
+ if (parent?.type === "AwaitExpression") {
1034
+ current = parent;
1035
+ continue;
1036
+ }
1037
+ const args = parent ? nodesAt(parent, "arguments") : [];
1038
+ const isFirstArgument = parent?.type === "CallExpression" && args[0] === current;
1039
+ if (!parent || !isFirstArgument || !isInteropCallee(analysis, nodeAt(parent, "callee"))) {
1040
+ return current;
1041
+ }
1042
+ current = parent;
1043
+ }
1044
+ }
1045
+
1046
+ // src/vite-require-uses.ts
1047
+ var INHERITED_NAMES = /* @__PURE__ */ new Set([
1048
+ ...Object.getOwnPropertyNames(Object.prototype),
1049
+ ...Object.getOwnPropertyNames(Function.prototype)
1050
+ ]);
1051
+ function isExportKey(key) {
1052
+ return key !== void 0 && !INHERITED_NAMES.has(key);
1053
+ }
1054
+ function isCalled(analysis, node) {
1055
+ const parent = analysis.parentOf.get(node);
1056
+ if (parent?.type === "CallExpression") return nodeAt(parent, "callee") === node;
1057
+ if (parent?.type !== "SequenceExpression") return false;
1058
+ return nodesAt(parent, "expressions").at(-1) === node && isCalled(analysis, parent);
1059
+ }
1060
+ function isCalledWithReceiver(analysis, member) {
1061
+ return analysis.parentOf.get(member)?.type === "CallExpression";
1062
+ }
1063
+ function isMemberCall(analysis, node, cxNames) {
1064
+ const member = analysis.parentOf.get(node);
1065
+ if (member?.type !== "MemberExpression" || nodeAt(member, "object") !== node) return false;
1066
+ const key = propertyNameOf(nodeAt(member, "property"), member.computed === true);
1067
+ if (!isExportKey(key) || !isCalled(analysis, member)) return false;
1068
+ return isCxName(cxNames, key) || !isCalledWithReceiver(analysis, member);
1069
+ }
1070
+ function destructuredNames(pattern) {
1071
+ if (pattern.type !== "ObjectPattern") return void 0;
1072
+ const names = [];
1073
+ for (const property of nodesAt(pattern, "properties")) {
1074
+ const value = nodeAt(property, "value");
1075
+ const key = propertyNameOf(nodeAt(property, "key"), property.computed === true);
1076
+ if (!isExportKey(key) || property.type !== "Property" || value?.type !== "Identifier") {
1077
+ return void 0;
1078
+ }
1079
+ names.push(value.name);
1080
+ }
1081
+ return names;
1082
+ }
1083
+ function isOnlyUsedAs(analysis, names, isUse) {
1084
+ const matching = analysis.references.filter(
1085
+ ({ binding }) => binding !== void 0 && binding.kind !== "param" && names.includes(binding.name)
1086
+ );
1087
+ return matching.every(({ binding, node }) => binding.writes === 0 && isUse(node));
1088
+ }
1089
+ function isBoundAndCalled(analysis, input, isUsedAs) {
1090
+ const { cxNames, pattern } = input;
1091
+ if (pattern?.type === "Identifier") {
1092
+ return isUsedAs([pattern.name], (node) => isMemberCall(analysis, node, cxNames));
1093
+ }
1094
+ const names = pattern && destructuredNames(pattern);
1095
+ return names !== void 0 && isUsedAs(names, (node) => isCalled(analysis, node));
1096
+ }
1097
+ function isExportedDeclarator(analysis, declarator) {
1098
+ const declaration = analysis.parentOf.get(declarator);
1099
+ return declaration !== void 0 && analysis.parentOf.get(declaration)?.type === "ExportNamedDeclaration";
1100
+ }
1101
+ function isDeclaredAndCalled(analysis, declarator, input) {
1102
+ if (nodeAt(declarator, "init") !== input.top || isExportedDeclarator(analysis, declarator)) {
1103
+ return false;
1104
+ }
1105
+ return isBoundAndCalled(
1106
+ analysis,
1107
+ { cxNames: input.cxNames, pattern: nodeAt(declarator, "id") },
1108
+ (names, isUse) => isOnlyUsedAs(analysis, names, isUse)
1109
+ );
1110
+ }
1111
+ function isMemberDeclaredAndCalled(analysis, member) {
1112
+ const name = propertyNameOf(nodeAt(member, "property"), member.computed === true);
1113
+ const declarator = analysis.parentOf.get(member);
1114
+ if (!isExportKey(name) || declarator?.type !== "VariableDeclarator") return false;
1115
+ if (isExportedDeclarator(analysis, declarator)) return false;
1116
+ const id = nodeAt(declarator, "id");
1117
+ if (nodeAt(declarator, "init") !== member || id?.type !== "Identifier") return false;
1118
+ return isOnlyUsedAs(analysis, [id.name], (node) => isCalled(analysis, node));
1119
+ }
1120
+ function isCallbackCalledOnly(analysis, callback, cxNames) {
1121
+ if (callback?.type !== "ArrowFunctionExpression") return false;
1122
+ const parameter = nodesAt(callback, "params")[0];
1123
+ if (!parameter) return true;
1124
+ const isInside = (node) => node.start >= callback.start && node.end <= callback.end;
1125
+ return isBoundAndCalled(
1126
+ analysis,
1127
+ { cxNames, pattern: parameter },
1128
+ (names, isUse) => analysis.references.filter(({ node }) => isInside(node) && names.includes(node.name)).every(({ node }) => isUse(node))
1129
+ );
1130
+ }
1131
+ function isPromiseUsedAsCallsOnly(analysis, promise, cxNames) {
1132
+ const member = analysis.parentOf.get(promise);
1133
+ if (member?.type === "ExpressionStatement") return true;
1134
+ if (member?.type !== "MemberExpression" || nodeAt(member, "object") !== promise) return false;
1135
+ const name = propertyNameOf(nodeAt(member, "property"), member.computed === true);
1136
+ const call = analysis.parentOf.get(member);
1137
+ if (name !== "then" || call?.type !== "CallExpression" || nodeAt(call, "callee") !== member) {
1138
+ return false;
1139
+ }
1140
+ return isCallbackCalledOnly(analysis, nodesAt(call, "arguments")[0], cxNames);
1141
+ }
1142
+ function isAwaitedUpTo(analysis, node, top) {
1143
+ let current = node;
1144
+ while (current && current !== top) {
1145
+ current = analysis.parentOf.get(current);
1146
+ if (current?.type === "AwaitExpression") return true;
1147
+ }
1148
+ return false;
1149
+ }
1150
+ function isResultUsedAsCallsOnly(analysis, top, cxNames) {
1151
+ const parent = analysis.parentOf.get(top);
1152
+ if (parent?.type === "ExpressionStatement") return true;
1153
+ if (parent?.type === "MemberExpression") {
1154
+ return isMemberCall(analysis, top, cxNames) || isMemberDeclaredAndCalled(analysis, parent);
1155
+ }
1156
+ return parent?.type === "VariableDeclarator" && isDeclaredAndCalled(analysis, parent, { cxNames, top });
1157
+ }
1158
+ function isEqualsDeclaredAndCalled(analysis, declaration, cxNames) {
1159
+ if (analysis.parentOf.get(declaration)?.type === "ExportNamedDeclaration") return false;
1160
+ return isBoundAndCalled(
1161
+ analysis,
1162
+ { cxNames, pattern: nodeAt(declaration, "id") },
1163
+ (names, isUse) => isOnlyUsedAs(analysis, names, isUse)
1164
+ );
1165
+ }
1166
+ function isUsedAsCallsOnly(analysis, require2, cxNames) {
1167
+ if (analysis.hasDirectEval) return false;
1168
+ if (require2.type === "TSImportEqualsDeclaration") {
1169
+ return isEqualsDeclaredAndCalled(analysis, require2, cxNames);
1170
+ }
1171
+ const top = unwrappedFromInterop(analysis, require2);
1172
+ if (require2.type === "ImportExpression" && !isAwaitedUpTo(analysis, require2, top)) {
1173
+ return isPromiseUsedAsCallsOnly(analysis, top, cxNames);
1174
+ }
1175
+ return isResultUsedAsCallsOnly(analysis, top, cxNames);
1176
+ }
1177
+
583
1178
  // src/vite-cx-source-forms.ts
584
1179
  var REEXPORT_TEXT = "a re-export of cx, which the build follows only from a module listed in cxModules.";
585
1180
  var SECOND_HOP_TEXT = "a re-export of the cx of a module listed in cxModules, which the build follows one step only.";
@@ -615,23 +1210,31 @@ function reexportProblem(code, node, isListed) {
615
1210
  exportedAs: exportedNamesOf(node)
616
1211
  };
617
1212
  }
618
- function sourceFormProblem(code, node, options) {
1213
+ function dynamicImportProblem(code, node, options, analysis) {
1214
+ const isHandedOut2 = options.isDependency === true && !isUsedAsCallsOnly(analysis, node, CX_ONLY);
1215
+ return {
1216
+ kind: "reference",
1217
+ offset: node.start,
1218
+ construct: code.slice(node.start, node.end),
1219
+ text: DYNAMIC_IMPORT_TEXT,
1220
+ ...isHandedOut2 && { isUnboundHandOut: true }
1221
+ };
1222
+ }
1223
+ function sourceFormProblem(code, node, options, analysis) {
619
1224
  const source = staticStringOf(nodeAt(node, "source"));
620
1225
  if (source === void 0 || !options.cxSources.has(source)) return void 0;
621
1226
  if (node.type === "ExportNamedDeclaration" || node.type === "ExportAllDeclaration") {
622
1227
  if (isTypeOnly(node) || options.isDeclared === true) return void 0;
623
1228
  return reexportProblem(code, node, options.declaredSources?.has(source) === true);
624
1229
  }
625
- if (node.type !== "ImportExpression") return void 0;
626
- const construct = code.slice(node.start, node.end);
627
- return { kind: "reference", offset: node.start, construct, text: DYNAMIC_IMPORT_TEXT };
1230
+ return node.type === "ImportExpression" ? dynamicImportProblem(code, node, options, analysis) : void 0;
628
1231
  }
629
- function sourceFormProblems(code, program, options) {
1232
+ function sourceFormProblems(code, program, options, analysis) {
630
1233
  const problems = [];
631
1234
  const stack = [program];
632
1235
  while (stack.length > 0) {
633
1236
  const node = stack.pop();
634
- const problem2 = sourceFormProblem(code, node, options);
1237
+ const problem2 = sourceFormProblem(code, node, options, analysis);
635
1238
  if (problem2) problems.push(problem2);
636
1239
  pushAll(stack, childrenOf(node));
637
1240
  }
@@ -1525,6 +2128,7 @@ function declarePattern(pattern, spec, scope, walker) {
1525
2128
  if (spec.owner) binding.owner = spec.owner;
1526
2129
  const declared = declare(into, binding, isAssigning);
1527
2130
  if (spec.init) declared.init = spec.init;
2131
+ walker.declarations.set(pattern, declared);
1528
2132
  return;
1529
2133
  }
1530
2134
  DECLARE[pattern.type]?.(pattern, spec, scope, walker);
@@ -1758,6 +2362,10 @@ var HANDLERS = {
1758
2362
  ImportDeclaration: (node, scope) => {
1759
2363
  declareImport(node, scope);
1760
2364
  },
2365
+ TSImportEqualsDeclaration: (node, scope, walker) => {
2366
+ if (!isTypeOnly(node)) declarePattern(nodeAt(node, "id"), { kind: "const" }, scope, walker);
2367
+ visitKeys(node, ["moduleReference"], scope, walker);
2368
+ },
1761
2369
  ExportNamedDeclaration: visitExport,
1762
2370
  VariableDeclaration: visitDeclaration,
1763
2371
  FunctionDeclaration: (node, scope, walker) => {
@@ -1833,6 +2441,7 @@ function analyze(program) {
1833
2441
  const walker = {
1834
2442
  references: [],
1835
2443
  parentOf: /* @__PURE__ */ new Map(),
2444
+ declarations: /* @__PURE__ */ new Map(),
1836
2445
  evalScopes: [],
1837
2446
  visit: (node, scope) => {
1838
2447
  visit(node, scope, walker);
@@ -1854,7 +2463,8 @@ function analyze(program) {
1854
2463
  hasDirectEval: evalScopes.length > 0,
1855
2464
  references: walker.references,
1856
2465
  parentOf: walker.parentOf,
1857
- referenceOf: (node) => byNode.get(node)
2466
+ referenceOf: (node) => byNode.get(node),
2467
+ bindingDeclaredBy: (node) => walker.declarations.get(node)
1858
2468
  };
1859
2469
  }
1860
2470
 
@@ -1977,7 +2587,8 @@ function refusedProblem(reading, use) {
1977
2587
  text: `${use.phrase ?? ""}.`,
1978
2588
  ...use.isReexport && { isListable: use.isListable },
1979
2589
  ...use.isRenamed === true && { isRenamed: true },
1980
- ...use.exportedAs && { exportedAs: use.exportedAs }
2590
+ ...use.exportedAs && { exportedAs: use.exportedAs },
2591
+ ...use.isUnboundHandOut === true && { isUnboundHandOut: true }
1981
2592
  };
1982
2593
  }
1983
2594
  function readUse(reading, use, analysis) {
@@ -2018,7 +2629,8 @@ function readUses(reading, program) {
2018
2629
  analysis,
2019
2630
  code,
2020
2631
  allowsExposure: options.isVueScript === true,
2021
- declaredSources: options.declaredSources
2632
+ declaredSources: options.declaredSources,
2633
+ isDependency: options.isDependency
2022
2634
  };
2023
2635
  for (const reference2 of analysis.references) {
2024
2636
  const cx = reference2.binding && bindings.get(reference2.binding);
@@ -2060,7 +2672,7 @@ function readModule(code, program, options) {
2060
2672
  cxSources: options.cxSources,
2061
2673
  declaredSources: options.declaredSources ?? /* @__PURE__ */ new Set()
2062
2674
  }) : [];
2063
- for (const problem2 of [...sourceFormProblems(code, program, options), ...listed]) {
2675
+ for (const problem2 of [...sourceFormProblems(code, program, options, analysis), ...listed]) {
2064
2676
  report(reading, problem2);
2065
2677
  }
2066
2678
  for (const atom of atomsWrittenIn(code)) result.classes.add(atom);
@@ -2437,10 +3049,198 @@ function unprunedAtoms(css, emitted) {
2437
3049
  return [...atoms].toSorted((a, b) => a.localeCompare(b));
2438
3050
  }
2439
3051
 
2440
- // src/vite-restorers.ts
2441
- function withRestorers(atoms) {
2442
- if (atoms.has("srOnly")) atoms.add("srOnlyFocusable");
2443
- return atoms;
3052
+ // src/vite-css-id.ts
3053
+ var STYLESHEET = /\.(?:css|less|sass|scss|styl|stylus|pcss|postcss|sss)(?:$|\?)/;
3054
+ var SPECIAL_QUERY = /[?&](?:worker|sharedworker|raw|url)\b/;
3055
+ var CSS_MODULE = /\.module\.(?:css|less|sass|scss|styl|stylus|pcss|postcss|sss)(?:$|\?)/;
3056
+ var TEXT_QUERY = /[?&](?:inline|direct|transform-only)\b/;
3057
+ function isStylesheetPath(id) {
3058
+ return STYLESHEET.test(id);
3059
+ }
3060
+ function isStylesheetId(id) {
3061
+ return STYLESHEET.test(id) && !SPECIAL_QUERY.test(id);
3062
+ }
3063
+ function isCssModuleId(id) {
3064
+ return isStylesheetId(id) && CSS_MODULE.test(id) && !TEXT_QUERY.test(id);
3065
+ }
3066
+ function isUnreadStylesheet(id) {
3067
+ return isStylesheetId(id) && !isCssModuleId(id);
3068
+ }
3069
+ function canHoldDirective(code) {
3070
+ return /@[n\\]/i.test(code);
3071
+ }
3072
+ function filePathOf(id) {
3073
+ const query = id.indexOf("?");
3074
+ return query === -1 ? id : id.slice(0, query);
3075
+ }
3076
+
3077
+ // src/vite-cx-text-test.ts
3078
+ function literalPattern(text) {
3079
+ return text.replaceAll(/[$()*+.?[\\\]^{|}]/g, String.raw`\$&`);
3080
+ }
3081
+ var INSIDE = String.raw`[^\n'"\x60\\]{0,512}`;
3082
+ var EXTENSION = String.raw`\.[^\n'"\x60\\/?#.]*`;
3083
+ var QUOTE = String.raw`['"\x60]`;
3084
+ function textTestOf(names) {
3085
+ if (names.size === 0) return void 0;
3086
+ const listed = [...names].map((name) => literalPattern(name)).join("|");
3087
+ const named = `${QUOTE}(?:${INSIDE}/)?(?:${listed})(?:${EXTENSION})?/*(?:[?#]${INSIDE})?${QUOTE}`;
3088
+ const directory = String.raw`(?:\bfrom|\bimport)\s*(?:\(\s*)?${QUOTE}\.{1,2}(?:/\.{1,2})*/?${QUOTE}`;
3089
+ return new RegExp(names.has("index") ? `${named}|${directory}` : named);
3090
+ }
3091
+
3092
+ // src/vite-path-text.ts
3093
+ function baseNameOf(file) {
3094
+ let end = file.length;
3095
+ while (end > 1 && file[end - 1] === "/") end -= 1;
3096
+ const start = file.lastIndexOf("/", end - 1) + 1;
3097
+ return file.slice(start, end);
3098
+ }
3099
+ function extensionOf(file) {
3100
+ const segment = baseNameOf(file);
3101
+ const dot = segment.lastIndexOf(".");
3102
+ return segment === ".." || dot <= 0 ? "" : segment.slice(dot);
3103
+ }
3104
+ function stemOf(file) {
3105
+ const segment = baseNameOf(file);
3106
+ const extension = extensionOf(file);
3107
+ return extension === "" || extension === segment ? segment : segment.slice(0, -extension.length);
3108
+ }
3109
+ function directoryOf(file) {
3110
+ let end = file.length;
3111
+ while (end > 1 && file[end - 1] === "/") end -= 1;
3112
+ const slash = file.lastIndexOf("/", end - 1);
3113
+ if (slash === -1) return ".";
3114
+ let cut2 = slash;
3115
+ while (cut2 > 1 && file[cut2 - 1] === "/") cut2 -= 1;
3116
+ return file.slice(0, cut2 === 0 ? 1 : cut2);
3117
+ }
3118
+ function rootEntryOf(root) {
3119
+ let end = root.length;
3120
+ while (end > 0 && (root[end - 1] === "/" || root[end - 1] === "\\")) end -= 1;
3121
+ return `${root.slice(0, end)}/index.html`;
3122
+ }
3123
+
3124
+ // src/vite-cx-modules.ts
3125
+ function isRelative(text) {
3126
+ const cut2 = text.search(/[#?]/);
3127
+ const path = cut2 === -1 ? text : text.slice(0, cut2);
3128
+ return path === "." || path === ".." || path.startsWith("./") || path.startsWith("../");
3129
+ }
3130
+ function fileOf(id) {
3131
+ return filePathOf(id).replaceAll("\\", "/");
3132
+ }
3133
+ function namesOf(file) {
3134
+ const name = stemOf(file);
3135
+ return name === "index" ? [name, baseNameOf(directoryOf(file))] : [name];
3136
+ }
3137
+ function entriesNaming(declared, id) {
3138
+ const file = fileOf(id);
3139
+ return declared.ids.entries().filter(([, resolved]) => fileOf(resolved) === file).map(([entry]) => entry).toArray();
3140
+ }
3141
+ async function declaredModulesFor(context, resolver, environment) {
3142
+ const { cxModules } = context.options;
3143
+ if (cxModules.length === 0) return void 0;
3144
+ const known = context.state.declared.get(environment);
3145
+ if (known) return known;
3146
+ const made = resolveEntries(context, resolver);
3147
+ context.state.declared.set(environment, made);
3148
+ return made;
3149
+ }
3150
+ async function resolveOrNull(resolver, source, importer) {
3151
+ try {
3152
+ return await resolver.resolve?.(source, importer) ?? void 0;
3153
+ } catch {
3154
+ return void 0;
3155
+ }
3156
+ }
3157
+ async function resolveEntries(context, resolver) {
3158
+ const from = rootEntryOf(context.root);
3159
+ const nave = await resolveOrNull(resolver, CX_SOURCE, from);
3160
+ const naveFile = nave === void 0 ? void 0 : fileOf(nave.id);
3161
+ const resolved = await Promise.all(
3162
+ context.options.cxModules.map(async (entry) => {
3163
+ const found = await resolveOrNull(resolver, entry, from);
3164
+ return [entry, found?.id];
3165
+ })
3166
+ );
3167
+ const kept = resolved.filter(
3168
+ ([entry, id]) => entry !== CX_SOURCE && (id === void 0 || fileOf(id) !== naveFile)
3169
+ );
3170
+ const ids = new Map(kept.filter((pair) => pair[1] !== void 0));
3171
+ const files = new Set(ids.values().map((id) => fileOf(id)));
3172
+ const names = new Set(files.values().flatMap((file) => namesOf(file)));
3173
+ return {
3174
+ entries: new Set(kept.map(([entry]) => entry).filter((entry) => !isRelative(entry))),
3175
+ ids,
3176
+ files,
3177
+ names,
3178
+ textTest: textTestOf(names)
3179
+ };
3180
+ }
3181
+ function forgetDeclared(state, environment) {
3182
+ state.declared.delete(environment);
3183
+ const prefix = `${environment}\0`;
3184
+ for (const key of state.recognised.keys())
3185
+ if (key.startsWith(prefix)) state.recognised.delete(key);
3186
+ }
3187
+ function withoutTrailingSlashes(text) {
3188
+ let end = text.length;
3189
+ while (end > 0 && text[end - 1] === "/") end -= 1;
3190
+ return text.slice(0, end);
3191
+ }
3192
+ function lastSegmentOf(specifier) {
3193
+ const cut2 = specifier.slice(1).search(/[#?]/);
3194
+ const bare = withoutTrailingSlashes(cut2 === -1 ? specifier : specifier.slice(0, cut2 + 1));
3195
+ const segment = bare.slice(bare.lastIndexOf("/") + 1);
3196
+ return segment === "." || segment === ".." ? "index" : segment;
3197
+ }
3198
+ function isNamingListed(specifier, declared) {
3199
+ const segment = lastSegmentOf(specifier);
3200
+ if (declared.names.has(segment)) return true;
3201
+ const extension = extensionOf(segment);
3202
+ return extension !== "" && declared.names.has(segment.slice(0, -extension.length));
3203
+ }
3204
+ function isAboutListed(input, declared) {
3205
+ if (!declared) return false;
3206
+ return isListedFile(declared, input.id) || isMentioningDeclared(input.code, declared);
3207
+ }
3208
+ function isListedFile(declared, id) {
3209
+ return declared.files.has(fileOf(id));
3210
+ }
3211
+ function isMentioningDeclared(code, declared) {
3212
+ for (const entry of declared.entries) if (code.includes(entry)) return true;
3213
+ return declared.textTest?.test(code) ?? false;
3214
+ }
3215
+ function recognisedKey(environment, file, importer) {
3216
+ return `${environment}\0${file}\0${importer}`;
3217
+ }
3218
+
3219
+ // src/vite-declared-echoes.ts
3220
+ var ECHO_KINDS = /* @__PURE__ */ new Set([
3221
+ "argument",
3222
+ "dynamic",
3223
+ "own",
3224
+ "reference",
3225
+ "unknown"
3226
+ ]);
3227
+ function withoutEchoes(modules) {
3228
+ const broken = new Set(
3229
+ modules.flatMap(
3230
+ (module) => module.problems.flatMap(
3231
+ (problem2) => problem2.kind === "declared" && problem2.moduleId !== void 0 && !problem2.hasNaveCx ? [fileOf(problem2.moduleId)] : []
3232
+ )
3233
+ )
3234
+ );
3235
+ const isEcho = (module) => module.onlyVia !== void 0 && [...module.onlyVia].every((file) => broken.has(file));
3236
+ return modules.flatMap(
3237
+ (module) => isEcho(module) ? module.problems.filter((problem2) => !ECHO_KINDS.has(problem2.kind)) : module.problems
3238
+ );
3239
+ }
3240
+
3241
+ // src/vite-module-id.ts
3242
+ function isDependencyId(id) {
3243
+ return filePathOf(id).replaceAll("\\", "/").includes("/node_modules/");
2444
3244
  }
2445
3245
 
2446
3246
  // src/vite-problems.ts
@@ -2469,6 +3269,43 @@ function cut(text, limit = 40) {
2469
3269
  return oneLine.length > limit ? `${oneLine.slice(0, limit)}...` : oneLine;
2470
3270
  }
2471
3271
 
3272
+ // src/vite-takes-host.ts
3273
+ function parseOf(host, code, id) {
3274
+ return host.parseModule ? host.parseModule(code, id) : host.parse?.(code);
3275
+ }
3276
+ async function resolvedIds(host, source, importer) {
3277
+ if (host.resolveAll) return await host.resolveAll(source, importer);
3278
+ const resolved = await host.resolve?.(source, importer);
3279
+ return resolved ? [resolved.id] : [];
3280
+ }
3281
+
3282
+ // src/vite-specifiers.ts
3283
+ function isTypeOnlyDeclaration(node) {
3284
+ if (isTypeOnly(node)) return true;
3285
+ return nodesAt(node, "specifiers").length > 0 && valueSpecifiersOf(node).length === 0;
3286
+ }
3287
+ function specifiersIn(program) {
3288
+ const found = /* @__PURE__ */ new Map();
3289
+ const stack = [program];
3290
+ while (stack.length > 0) {
3291
+ const node = stack.pop();
3292
+ const where = isTypeOnlyDeclaration(node) ? void 0 : nodeAt(node, "source");
3293
+ const source = staticStringOf(where);
3294
+ if (where !== void 0 && source !== void 0) {
3295
+ found.set(source, Math.min(found.get(source) ?? Infinity, where.start));
3296
+ }
3297
+ pushAll(stack, childrenOf(node));
3298
+ }
3299
+ return [...found].toSorted(([, a], [, b]) => a - b).map(([source]) => source);
3300
+ }
3301
+ function specifiersOf(host, importer) {
3302
+ try {
3303
+ return specifiersIn(parseOf(host, importer.code, importer.id));
3304
+ } catch {
3305
+ return void 0;
3306
+ }
3307
+ }
3308
+
2472
3309
  // src/vite-class-map-message.ts
2473
3310
  var CLASS_MAP_NOT_PARSED = "the module could not be read, so the atoms it names would not ship: it is a CSS Module, and the JavaScript Vite wrote for its class map did not parse. A plugin that runs after Vite's CSS step has changed that JavaScript: have that plugin leave a CSS Module's JavaScript valid.";
2474
3311
 
@@ -2513,10 +3350,11 @@ function clausesOf(takes) {
2513
3350
  const passedOn = takes.some((take) => take.isPassedOn === true) ? "; where a file re-exports what it takes, import cx from @navecss/core/cx in the files that call it, call cx there in its place, and drop the re-export" : "";
2514
3351
  return { files, listed, whole: `${wholeClause}${passedOn}` };
2515
3352
  }
2516
- function takenLine(pkg, takes, hasPackageFix) {
3353
+ function takenLine(pkg, takes, input) {
2517
3354
  const { files, listed, whole } = clausesOf(takes);
3355
+ const { hasPackageFix, rootName } = input;
2518
3356
  const fix = hasPackageFix ? FIX : "";
2519
- return `${pkg} re-exports cx, and your code takes that cx, from the package or through another package that re-exports it, in ${listed}. The build does not read calls made through what your code takes there, and the keepFor entry stands in only for the package's own calls: ${files}, import cx from @navecss/core/cx instead and call cx in its place${whole}. The build prints no cxModules entry for this, since it found none of these takes made, by an import it can read and a specifier that resolves from Vite's root, from a module that re-exports cx from @navecss/core/cx itself and only under the name cx. Once your code makes none of these takes, the keepFor entry clears this.${fix}`;
3357
+ return `${pkg} re-exports cx, and your code takes that cx, from the package or through another package that re-exports it, in ${listed}. The build does not read calls made through what your code takes there, and the keepFor entry stands in only for the package's own calls: ${files}, import cx from @navecss/core/cx instead and call cx in its place${whole}. The build prints no cxModules entry for this, since it found none of these takes made, by an import it can read and a specifier that resolves from ${rootName}, from a module that re-exports cx from @navecss/core/cx itself and only under the name cx. Once your code makes none of these takes, the keepFor entry clears this.${fix}`;
2520
3358
  }
2521
3359
  function forwardLine(pkg, takes) {
2522
3360
  const { files, listed, whole } = clausesOf(takes);
@@ -2537,6 +3375,12 @@ function isRenamedOrReached(problem2) {
2537
3375
  function isSecondHop(problem2) {
2538
3376
  return problem2.kind === "reexport" && problem2.isListable === false && problem2.pkg !== void 0;
2539
3377
  }
3378
+ function isHandedOut(problem2) {
3379
+ return problem2.kind === "reference" && problem2.isRenamed === true && problem2.exportedAs !== void 0;
3380
+ }
3381
+ function handedOutClause(pkg) {
3382
+ return ` ${pkg} also gives cx out under another name, and the build does not read calls made through it: where your code imports it from ${pkg} or one of its subpaths, import cx from @navecss/core/cx instead and call cx in its place.`;
3383
+ }
2540
3384
  function callsLine(pkg, problems, entry) {
2541
3385
  if (problems.every((problem2) => problem2.kind === "own")) {
2542
3386
  return `${pkg} names atoms of your own, which have no class, so a keepFor entry cannot make its calls produce a Nave class. The fix is the package's: it must name atoms Nave ships.`;
@@ -2547,8 +3391,20 @@ function callsLine(pkg, problems, entry) {
2547
3391
  const places = count === 1 ? "1 place" : `${count} places`;
2548
3392
  return `${pkg} calls cx.dynamic() in ${places}, and keepFor lists no atoms for it, so none of them applies a class. List the atoms those calls can take, from its documentation, under its name in ${entry}.`;
2549
3393
  }
2550
- return `${pkg} is a dependency, so its code is not yours to change. List the atoms its calls can produce, from its documentation, under its name in ${entry}. The lasting fix is the package's: names chosen at run time go through cx.dynamic().`;
3394
+ const handedOut = problems.some((problem2) => isHandedOut(problem2)) ? handedOutClause(pkg) : "";
3395
+ return `${pkg} is a dependency, so its code is not yours to change. List the atoms its calls can produce, from its documentation, under its name in ${entry}. The lasting fix is the package's: names chosen at run time go through cx.dynamic().${handedOut}`;
3396
+ }
3397
+ function heldLine(pkg, held2, everyAtom) {
3398
+ const formOf = (problem2) => {
3399
+ const sentence = problem2.text.replace(/\.(\s.*)?$/su, "");
3400
+ return problem2.construct === "" ? sentence : `${cut(problem2.construct)}: ${sentence}`;
3401
+ };
3402
+ const places = [
3403
+ ...new Set(held2.map((problem2) => `${problem2.file} (${formOf(problem2)})`))
3404
+ ].toSorted(compareText);
3405
+ return `${pkg} uses cx in ${places.join(", ")}. From there the build cannot tell whether a call of your code goes through it, and the keepFor entry does not stand in for that, so the build fails whenever these files are part of it, whatever your code takes from ${pkg}. The fix is the package's, in a release of it or a patched copy: export it by name from an ES module, as in export { cx as cn } from '@navecss/core/cx', which the build then checks wherever your code takes it. Until then, ship every atom: ${everyAtom}`;
2551
3406
  }
3407
+ var EVERY_ATOM = 'see "Which atoms the build ships" in node_modules/@navecss/core/README.md.';
2552
3408
  var LASTING_FIX = "The lasting fix is the package's: import cx from @navecss/core/cx where it is called, or re-export it from the package's entry.";
2553
3409
  function listedLine(pkg, specifiers, configured, home) {
2554
3410
  const array = cxModulesArray(configured, specifiers);
@@ -2596,7 +3452,8 @@ function takeLines(pkg, all, home) {
2596
3452
  const lines = [];
2597
3453
  if (takes.length > 0) {
2598
3454
  const hasPackageFix = plain.some((problem2) => isRenamedOrReached(problem2)) || takes.some((take) => take.isReached);
2599
- lines.push(takenLine(pkg, takes, hasPackageFix));
3455
+ const rootName = plain.find((problem2) => problem2.rootName !== void 0)?.rootName;
3456
+ lines.push(takenLine(pkg, takes, { hasPackageFix, rootName: rootName ?? "the project root" }));
2600
3457
  }
2601
3458
  if (hops.length > 0)
2602
3459
  lines.push(
@@ -2610,9 +3467,12 @@ function takeLines(pkg, all, home) {
2610
3467
  lines.push(callsThroughLine(pkg, [...new Set(callers)].toSorted(compareText), home));
2611
3468
  return lines;
2612
3469
  }
2613
- function packageLines(pkg, all, configured, home) {
3470
+ function packageLines(pkg, all, configured, places) {
3471
+ const { home, everyAtom } = places;
2614
3472
  const isTaken = (problem2) => (problem2.takes?.length ?? 0) > 0;
2615
- const problems = all.filter((problem2) => !isTaken(problem2) && problem2.callers === void 0);
3473
+ const kept = all.filter((problem2) => !isTaken(problem2) && problem2.callers === void 0);
3474
+ const held2 = kept.filter((problem2) => problem2.isHeld === true);
3475
+ const problems = kept.filter((problem2) => problem2.isHeld !== true);
2616
3476
  const entry = `${home}: keepFor: { '${pkg}': ['<atom>'] }`;
2617
3477
  const reexports = problems.filter((problem2) => isListableReexport(problem2));
2618
3478
  const internal = reexports.filter(
@@ -2632,6 +3492,7 @@ function packageLines(pkg, all, configured, home) {
2632
3492
  lines.push(declaredLine(pkg, entries.toSorted(compareText), internal.length > 0, home));
2633
3493
  }
2634
3494
  if (rest.length > 0) lines.push(callsLine(pkg, rest, entry));
3495
+ if (held2.length > 0) lines.push(heldLine(pkg, held2, everyAtom));
2635
3496
  const listed = named.length > 0 ? listedLine(pkg, named, configured, home) : void 0;
2636
3497
  if (listed !== void 0) lines.push(listed);
2637
3498
  if (internal.length > 0) {
@@ -2647,6 +3508,951 @@ function packageLines(pkg, all, configured, home) {
2647
3508
  return lines;
2648
3509
  }
2649
3510
 
3511
+ // src/vite-dependency-reexports.ts
3512
+ async function isResolvingTo(ctx, input) {
3513
+ try {
3514
+ const resolved = await resolvedIds(ctx, input.specifier, input.from);
3515
+ return resolved.some((id) => fileOf(id) === input.file);
3516
+ } catch {
3517
+ return false;
3518
+ }
3519
+ }
3520
+ function importersOf(ctx, id) {
3521
+ const info = ctx.getModuleInfo?.(id);
3522
+ return [.../* @__PURE__ */ new Set([...info?.importers ?? [], ...info?.dynamicImporters ?? []])];
3523
+ }
3524
+ async function specifiersWritten(ctx, input) {
3525
+ const { file, importer } = input;
3526
+ const code = ctx.getModuleInfo?.(importer)?.code;
3527
+ if (code === null || code === void 0) return [];
3528
+ const written = specifiersOf(ctx, { id: importer, code }) ?? [];
3529
+ const found = [];
3530
+ for (const specifier of written) {
3531
+ if (await isResolvingTo(ctx, { file, from: importer, specifier })) found.push(specifier);
3532
+ }
3533
+ return found;
3534
+ }
3535
+ async function specifiersInto(ctx, context, input) {
3536
+ const found = /* @__PURE__ */ new Set();
3537
+ for (const importer of importersOf(ctx, input.id)) {
3538
+ const owner = isDependencyId(importer) ? await context.packageOf(importer) : void 0;
3539
+ if (owner === input.pkg) continue;
3540
+ const written = await specifiersWritten(ctx, { file: fileOf(input.id), importer });
3541
+ for (const specifier of written) found.add(specifier);
3542
+ }
3543
+ return found.values().toArray().toSorted(compareText);
3544
+ }
3545
+ async function clearingSpecifier(ctx, context, input) {
3546
+ const from = rootEntryOf(context.root);
3547
+ const file = fileOf(input.id);
3548
+ if (await isResolvingTo(ctx, { file, from, specifier: input.pkg })) return input.pkg;
3549
+ const specifiers = await specifiersInto(ctx, context, input);
3550
+ for (const specifier of specifiers) {
3551
+ if (await isResolvingTo(ctx, { file, from, specifier })) return specifier;
3552
+ }
3553
+ return void 0;
3554
+ }
3555
+ async function withClearingSpecifiers(ctx, context, problems) {
3556
+ const asked = /* @__PURE__ */ new Map();
3557
+ const clearing = (pkg, id) => {
3558
+ const known = asked.get(id);
3559
+ if (known) return known;
3560
+ const answer = clearingSpecifier(ctx, context, { id, pkg });
3561
+ asked.set(id, answer);
3562
+ return answer;
3563
+ };
3564
+ const entriesOf = async (id) => {
3565
+ const declared = await declaredModulesFor(context, ctx, ctx.environment.name);
3566
+ return declared ? entriesNaming(declared, id) : [];
3567
+ };
3568
+ const renamed = new Set(
3569
+ problems.flatMap(
3570
+ (problem2) => problem2.isRenamed === true && problem2.moduleId !== void 0 ? [problem2.moduleId] : []
3571
+ )
3572
+ );
3573
+ return await Promise.all(
3574
+ problems.map(async (problem2) => {
3575
+ const { moduleId, pkg } = problem2;
3576
+ if (pkg === void 0 || moduleId === void 0) return problem2;
3577
+ if (problem2.kind === "declared") return { ...problem2, entries: await entriesOf(moduleId) };
3578
+ if (!isListableReexport(problem2)) return problem2;
3579
+ if (renamed.has(moduleId)) return { ...problem2, isRenamed: true };
3580
+ const specifier = await clearing(pkg, moduleId);
3581
+ return specifier === void 0 ? problem2 : { ...problem2, specifier };
3582
+ })
3583
+ );
3584
+ }
3585
+
3586
+ // src/vite-cx-reexported.ts
3587
+ function declaredNames2(pattern) {
3588
+ const found = [];
3589
+ const stack = pattern ? [pattern] : [];
3590
+ while (stack.length > 0) {
3591
+ const node = stack.pop();
3592
+ if (node.type === "Identifier") {
3593
+ found.push(stringAt(node, "name") ?? "");
3594
+ } else if (node.type === "AssignmentPattern") {
3595
+ pushAll(
3596
+ stack,
3597
+ [nodeAt(node, "left")].filter((part) => part !== void 0)
3598
+ );
3599
+ } else {
3600
+ const single = ["argument", "value"].map((key) => nodeAt(node, key));
3601
+ const lists = ["properties", "elements"].flatMap((key) => nodesAt(node, key));
3602
+ pushAll(
3603
+ stack,
3604
+ single.filter((part) => part !== void 0)
3605
+ );
3606
+ pushAll(stack, lists);
3607
+ }
3608
+ }
3609
+ return found;
3610
+ }
3611
+ function ownExports(program) {
3612
+ const found = /* @__PURE__ */ new Set();
3613
+ for (const statement of nodesAt(program, "body")) {
3614
+ const namespace = statement.type === "ExportAllDeclaration" ? exportNameOf(nodeAt(statement, "exported")) : void 0;
3615
+ if (namespace !== void 0) found.add(namespace);
3616
+ if (statement.type !== "ExportNamedDeclaration") continue;
3617
+ const declaration = nodeAt(statement, "declaration");
3618
+ const declared = nodesAt(declaration ?? statement, "declarations").flatMap(
3619
+ (declarator) => declaredNames2(nodeAt(declarator, "id"))
3620
+ );
3621
+ for (const name of [...declared, ...declaredNames2(declaration && nodeAt(declaration, "id"))]) {
3622
+ found.add(name);
3623
+ }
3624
+ for (const specifier of nodesAt(statement, "specifiers")) {
3625
+ const name = exportNameOf(nodeAt(specifier, "exported"));
3626
+ if (name !== void 0) found.add(name);
3627
+ }
3628
+ }
3629
+ return found;
3630
+ }
3631
+ function exportedBy(node, source, own) {
3632
+ const from = staticStringOf(nodeAt(node, "source"));
3633
+ if (from === void 0 || !source.reaches.has(from)) return [];
3634
+ if (node.type === "ExportAllDeclaration") {
3635
+ const namespace = exportNameOf(nodeAt(node, "exported"));
3636
+ if (namespace !== void 0) return [namespace];
3637
+ return source.names.values().filter((name) => name !== "default" && !own.has(name) && !source.rivals.has(name)).toArray();
3638
+ }
3639
+ return nodesAt(node, "specifiers").flatMap((specifier) => {
3640
+ const local = exportNameOf(nodeAt(specifier, "local"));
3641
+ const exported = exportNameOf(nodeAt(specifier, "exported"));
3642
+ return local !== void 0 && exported !== void 0 && source.names.has(local) ? [exported] : [];
3643
+ });
3644
+ }
3645
+ function isImportedFrom(binding, source) {
3646
+ if (binding?.kind !== "import" || binding.source === void 0) return false;
3647
+ if (!source.reaches.has(binding.source)) return false;
3648
+ return binding.imported === "*" || source.names.has(binding.imported ?? "");
3649
+ }
3650
+ function starSources(program) {
3651
+ return nodesAt(program, "body").flatMap((statement) => {
3652
+ const source = staticStringOf(nodeAt(statement, "source"));
3653
+ const isStar = statement.type === "ExportAllDeclaration" && !nodeAt(statement, "exported");
3654
+ return isStar && source !== void 0 ? [source] : [];
3655
+ });
3656
+ }
3657
+ function reexportedNames(program, source) {
3658
+ const found = /* @__PURE__ */ new Set();
3659
+ const own = ownExports(program);
3660
+ const stack = [program];
3661
+ while (stack.length > 0) {
3662
+ const node = stack.pop();
3663
+ if (node.type === "ExportNamedDeclaration" || node.type === "ExportAllDeclaration") {
3664
+ for (const name of exportedBy(node, source, own)) found.add(name);
3665
+ }
3666
+ pushAll(stack, childrenOf(node));
3667
+ }
3668
+ const analysis = analyze(program);
3669
+ for (const reference2 of analysis.references) {
3670
+ if (!isImportedFrom(reference2.binding, source)) continue;
3671
+ for (const name of flowOf(analysis, reference2.node).names) found.add(name);
3672
+ }
3673
+ return [...found];
3674
+ }
3675
+
3676
+ // src/vite-cx-star-exports.ts
3677
+ function resolvedFiles(ctx, resolutions, input) {
3678
+ const key = `${input.id}\0${input.specifier}`;
3679
+ const known = resolutions.get(key);
3680
+ if (known) return known;
3681
+ const asked = (async () => {
3682
+ try {
3683
+ const ids = await resolvedIds(ctx, input.specifier, input.id);
3684
+ return ids.map((id) => fileOf(id));
3685
+ } catch {
3686
+ return [];
3687
+ }
3688
+ })();
3689
+ resolutions.set(key, asked);
3690
+ return asked;
3691
+ }
3692
+ function ownNamesOf(program, file, cxExports) {
3693
+ const found = { names: ownExports(program), cx: /* @__PURE__ */ new Set() };
3694
+ for (const name of found.names) {
3695
+ if (cxExports.get(file)?.has(name)) found.cx.add(name);
3696
+ }
3697
+ return found;
3698
+ }
3699
+ function unreadProgram(ctx, input) {
3700
+ const { file, seen } = input;
3701
+ const code = ctx.getModuleInfo?.(file)?.code;
3702
+ const isUnread = !seen.has(file) && typeof code === "string";
3703
+ seen.add(file);
3704
+ return isUnread ? parseOf(ctx, code, file) : void 0;
3705
+ }
3706
+ function addBelow(found, belows) {
3707
+ for (const below of belows) {
3708
+ for (const name of below.cx) {
3709
+ found.names.add(name);
3710
+ found.cx.add(name);
3711
+ }
3712
+ }
3713
+ const first2 = belows.at(0)?.names ?? /* @__PURE__ */ new Set();
3714
+ for (const name of first2) {
3715
+ if (belows.every((below) => below.names.has(name))) found.names.add(name);
3716
+ }
3717
+ }
3718
+ function rivalsIn(exported) {
3719
+ return new Set([...exported.names].filter((name) => !exported.cx.has(name)));
3720
+ }
3721
+ async function addStars(ctx, input) {
3722
+ const { found, file, program, walk } = input;
3723
+ for (const specifier of starSources(program)) {
3724
+ const stars = await resolvedFiles(ctx, walk.resolutions, { id: file, specifier });
3725
+ const belows = [];
3726
+ for (const star of stars) {
3727
+ const branch = stars.length > 1 ? { ...walk, seen: new Set(walk.seen) } : walk;
3728
+ belows.push(await exportsOf(ctx, { file: star, walk: branch }));
3729
+ }
3730
+ addBelow(found, belows);
3731
+ }
3732
+ }
3733
+ async function exportsOf(ctx, input) {
3734
+ const { file, walk } = input;
3735
+ const program = unreadProgram(ctx, { file, seen: walk.seen });
3736
+ if (!program) return { names: /* @__PURE__ */ new Set(), cx: /* @__PURE__ */ new Set() };
3737
+ const found = ownNamesOf(program, file, walk.cxExports);
3738
+ await addStars(ctx, { found, file, program, walk });
3739
+ return found;
3740
+ }
3741
+ async function rivalsOf(ctx, input) {
3742
+ const { cxExports, id, program, reaches, resolutions } = input;
3743
+ const rivals = /* @__PURE__ */ new Set();
3744
+ const others = starSources(program).filter((text) => !reaches.has(text));
3745
+ for (const specifier of others) {
3746
+ const files = await resolvedFiles(ctx, resolutions, { id, specifier });
3747
+ const rivalsPerFile = [];
3748
+ for (const file of files) {
3749
+ const walk = { cxExports, resolutions, seen: /* @__PURE__ */ new Set() };
3750
+ rivalsPerFile.push(rivalsIn(await exportsOf(ctx, { file, walk })));
3751
+ }
3752
+ const [first2 = /* @__PURE__ */ new Set()] = rivalsPerFile;
3753
+ for (const name of first2) {
3754
+ if (rivalsPerFile.every((found) => found.has(name))) rivals.add(name);
3755
+ }
3756
+ }
3757
+ return rivals;
3758
+ }
3759
+
3760
+ // src/vite-require-takes.ts
3761
+ var WHOLE = { shape: "unreadable", names: [] };
3762
+ function held(specifier) {
3763
+ return {
3764
+ ...WHOLE,
3765
+ isHeld: true,
3766
+ form: `requires ${specifier} and uses what it returns where the build cannot follow it`
3767
+ };
3768
+ }
3769
+ function isCreateRequireCall(node) {
3770
+ if (node?.type !== "CallExpression") return false;
3771
+ const callee = nodeAt(node, "callee");
3772
+ if (isName(callee, "createRequire")) return true;
3773
+ return callee?.type === "MemberExpression" && isName(nodeAt(callee, "property"), "createRequire");
3774
+ }
3775
+ function nodesIn(program) {
3776
+ const found = [];
3777
+ const stack = [program];
3778
+ while (stack.length > 0) {
3779
+ const node = stack.pop();
3780
+ found.push(node);
3781
+ pushAll(stack, childrenOf(node));
3782
+ }
3783
+ return found;
3784
+ }
3785
+ function requireNamesIn(nodes) {
3786
+ const names = /* @__PURE__ */ new Set(["require"]);
3787
+ for (const node of nodes) {
3788
+ const id = nodeAt(node, "id");
3789
+ if (node.type !== "VariableDeclarator" || id?.type !== "Identifier") continue;
3790
+ if (isCreateRequireCall(nodeAt(node, "init"))) names.add(id.name);
3791
+ }
3792
+ return names;
3793
+ }
3794
+ function equalsSpecifierOf(node) {
3795
+ const reference2 = nodeAt(node, "moduleReference");
3796
+ if (node.importKind === "type" || reference2?.type !== "TSExternalModuleReference") {
3797
+ return void 0;
3798
+ }
3799
+ return staticStringOf(nodeAt(reference2, "expression"));
3800
+ }
3801
+ function isRequireCallee(callee, requireNames) {
3802
+ if (callee?.type === "Identifier") return requireNames.has(callee.name);
3803
+ return isCreateRequireCall(callee);
3804
+ }
3805
+ function requiredBy(node, requireNames) {
3806
+ if (node.type === "TSImportEqualsDeclaration") return equalsSpecifierOf(node);
3807
+ if (node.type !== "CallExpression") return void 0;
3808
+ const args = nodesAt(node, "arguments");
3809
+ const isRequire = isRequireCallee(nodeAt(node, "callee"), requireNames);
3810
+ return isRequire && args.length === 1 ? staticStringOf(args[0]) : void 0;
3811
+ }
3812
+ function requireCallsOf(program) {
3813
+ const nodes = nodesIn(program);
3814
+ const requireNames = requireNamesIn(nodes);
3815
+ return nodes.flatMap((node) => {
3816
+ const specifier = requiredBy(node, requireNames);
3817
+ return specifier === void 0 ? [] : [{ node, specifier }];
3818
+ });
3819
+ }
3820
+ function requireSpecifiersIn(program) {
3821
+ return [...new Set(requireCallsOf(program).map(({ specifier }) => specifier))];
3822
+ }
3823
+ function assignmentOf(statement) {
3824
+ if (statement.type !== "ExpressionStatement") return void 0;
3825
+ const expression = nodeAt(statement, "expression");
3826
+ if (expression?.type !== "AssignmentExpression" || expression.operator !== "=") return void 0;
3827
+ return { left: nodeAt(expression, "left"), right: nodeAt(expression, "right") };
3828
+ }
3829
+ function wholeForwardOf(left, right, input) {
3830
+ if (right === void 0 || !input.requires.has(right) || !isModuleExports(left)) return void 0;
3831
+ const given = input.names === void 0 ? [] : input.names.values().toArray();
3832
+ return { given, require: right, takes: [{ shape: "star", names: [], isForward: true }] };
3833
+ }
3834
+ function memberForwardOf(left, right, input) {
3835
+ const as = exportsMemberOf(left);
3836
+ const member = memberOf(right);
3837
+ if (as === void 0 || !member || !input.requires.has(member.object)) return void 0;
3838
+ if (!isCxName(input.names, member.name)) return void 0;
3839
+ const taken = { shape: "names", names: [member.name], isPassedOn: true, isForward: true };
3840
+ return { given: [as], require: member.object, takes: [taken] };
3841
+ }
3842
+ function forwardOf(statement, input) {
3843
+ const assignment = assignmentOf(statement);
3844
+ if (!assignment) return starForwardOf(statement, input);
3845
+ const { left, right } = assignment;
3846
+ return wholeForwardOf(left, right, input) ?? memberForwardOf(left, right, input);
3847
+ }
3848
+ function isMarkerWrite(statement) {
3849
+ const assignment = assignmentOf(statement);
3850
+ if (assignment) return exportsMemberOf(assignment.left) === "__esModule";
3851
+ const define = definePropertyOf(statement);
3852
+ return define !== void 0 && isExportsObject(define.target) && define.as === "__esModule";
3853
+ }
3854
+ function isMarkedEsModule(program) {
3855
+ return nodesAt(program, "body").some((statement) => isMarkerWrite(statement));
3856
+ }
3857
+ function forwardsIn(program, input) {
3858
+ const written = nodesAt(program, "body").flatMap((statement) => {
3859
+ const forward = forwardOf(statement, input);
3860
+ return forward ? [forward] : [];
3861
+ });
3862
+ return [...written, ...boundForwardsOf(program, input)];
3863
+ }
3864
+ function requireTakesIn(program, input) {
3865
+ const requires = requireCallsOf(program).filter(({ specifier }) => input.reaches.has(specifier));
3866
+ if (requires.length === 0) return { given: [], takes: [] };
3867
+ let analysis;
3868
+ const forwardInput = {
3869
+ analysis: () => analysis ??= analyze(program),
3870
+ names: input.names,
3871
+ requires: new Set(requires.map(({ node }) => node))
3872
+ };
3873
+ const forwards = input.readsForwards ? forwardsIn(program, forwardInput) : [];
3874
+ const forwarded = new Set(forwards.map((forward) => forward.require));
3875
+ const takes = forwards.flatMap((forward) => forward.takes);
3876
+ const others = requires.filter(({ node }) => !forwarded.has(node));
3877
+ if (input.readsForwards) {
3878
+ const analysisOf = forwardInput.analysis();
3879
+ for (const { node, specifier } of others) {
3880
+ takes.push(isUsedAsCallsOnly(analysisOf, node, input.names) ? WHOLE : held(specifier));
3881
+ }
3882
+ } else if (others.length > 0) takes.push(WHOLE);
3883
+ const given = new Set(forwards.flatMap((forward) => forward.given));
3884
+ if (given.size > 0 && !isMarkedEsModule(program)) given.add("default");
3885
+ return { given: [...given], takes };
3886
+ }
3887
+
3888
+ // src/vite-listed-holders.ts
3889
+ async function reachingSpecifiers(ctx, input) {
3890
+ const { code, file, id, resolutions } = input;
3891
+ const program = parseOf(ctx, code, id);
3892
+ if (!program) return void 0;
3893
+ const reachingOf = async (specifiers) => {
3894
+ const reaching = /* @__PURE__ */ new Set();
3895
+ for (const specifier of specifiers) {
3896
+ const files = await resolvedFiles(ctx, resolutions, { id, specifier });
3897
+ if (files.includes(file)) reaching.add(specifier);
3898
+ }
3899
+ return reaching;
3900
+ };
3901
+ const reaches = await reachingOf(specifiersIn(program));
3902
+ const requires = await reachingOf(requireSpecifiersIn(program));
3903
+ return { program, reaches, requires };
3904
+ }
3905
+ async function reexportedBy(ctx, input) {
3906
+ const code = ctx.getModuleInfo?.(input.id)?.code;
3907
+ if (code === null || code === void 0) return [];
3908
+ try {
3909
+ const read = await reachingSpecifiers(ctx, { ...input, code });
3910
+ if (!read) return [];
3911
+ const { program, reaches, requires } = read;
3912
+ const forwarded = requires.size === 0 ? [] : requireTakesIn(program, { names: input.names, reaches: requires, readsForwards: true }).given;
3913
+ if (reaches.size === 0) return forwarded;
3914
+ const rivals = await rivalsOf(ctx, { ...input, program, reaches });
3915
+ const reexported2 = reexportedNames(program, { names: input.names, reaches, rivals });
3916
+ return [.../* @__PURE__ */ new Set([...reexported2, ...forwarded])];
3917
+ } catch {
3918
+ return [];
3919
+ }
3920
+ }
3921
+ async function reexportsOf(ctx, input) {
3922
+ const importers = importersOf(ctx, input.id).filter((importer) => isDependencyId(importer));
3923
+ const found = /* @__PURE__ */ new Map();
3924
+ for (const importer of importers) {
3925
+ const added = await reexportedBy(ctx, { ...input, file: fileOf(input.id), id: importer });
3926
+ if (added.length > 0) found.set(importer, added);
3927
+ }
3928
+ return found;
3929
+ }
3930
+ async function holdersOf(ctx, origin) {
3931
+ const held2 = /* @__PURE__ */ new Map([[origin.id, origin.names]]);
3932
+ const queue = [origin.id];
3933
+ while (queue.length > 0) {
3934
+ const id = queue.shift();
3935
+ const reexports = await reexportsOf(ctx, {
3936
+ cxExports: origin.cxExports,
3937
+ id,
3938
+ names: held2.get(id),
3939
+ resolutions: origin.resolutions
3940
+ });
3941
+ for (const [importer, added] of reexports) {
3942
+ const known = held2.get(importer) ?? /* @__PURE__ */ new Set();
3943
+ const isNew = importer !== origin.id && added.some((name) => !known.has(name));
3944
+ if (isNew) {
3945
+ held2.set(importer, /* @__PURE__ */ new Set([...known, ...added]));
3946
+ queue.push(importer);
3947
+ }
3948
+ }
3949
+ }
3950
+ return held2.entries().map(([id, names]) => ({ id, names, isReached: id !== origin.id })).toArray();
3951
+ }
3952
+
3953
+ // src/vite-cx-reference-names.ts
3954
+ function leftmostName(node) {
3955
+ let current = node;
3956
+ while (current?.type === "TSQualifiedName") current = nodeAt(current, "left");
3957
+ return current?.type === "Identifier" ? current.name : void 0;
3958
+ }
3959
+ function typeNameOf(node) {
3960
+ if (node.type === "TSTypeQuery") return leftmostName(nodeAt(node, "exprName"));
3961
+ return node.type === "TSTypeReference" ? leftmostName(nodeAt(node, "typeName")) : void 0;
3962
+ }
3963
+ function jsxNameOf(node) {
3964
+ if (node.type !== "JSXOpeningElement") return void 0;
3965
+ let current = nodeAt(node, "name");
3966
+ while (current?.type === "JSXMemberExpression") current = nodeAt(current, "object");
3967
+ return current?.type === "JSXIdentifier" ? current.name : void 0;
3968
+ }
3969
+ function jsxMemberOf(node) {
3970
+ if (node.type !== "JSXOpeningElement") return void 0;
3971
+ let current = nodeAt(node, "name");
3972
+ while (current?.type === "JSXMemberExpression") {
3973
+ const object = nodeAt(current, "object");
3974
+ if (object?.type === "JSXIdentifier") {
3975
+ const member = nodeAt(current, "property")?.name;
3976
+ return typeof member === "string" ? { member, name: object.name } : void 0;
3977
+ }
3978
+ current = object;
3979
+ }
3980
+ return void 0;
3981
+ }
3982
+ function jsxMembersIn(program) {
3983
+ const found = /* @__PURE__ */ new Map();
3984
+ const stack = [program];
3985
+ while (stack.length > 0) {
3986
+ const node = stack.pop();
3987
+ const read = jsxMemberOf(node);
3988
+ if (read) found.set(read.name, (found.get(read.name) ?? /* @__PURE__ */ new Set()).add(read.member));
3989
+ pushAll(stack, childrenOf(node));
3990
+ }
3991
+ return found;
3992
+ }
3993
+ function namesIn(program, nameOf) {
3994
+ const found = /* @__PURE__ */ new Set();
3995
+ const stack = [program];
3996
+ while (stack.length > 0) {
3997
+ const node = stack.pop();
3998
+ const name = nameOf(node);
3999
+ if (name !== void 0) found.add(name);
4000
+ pushAll(stack, childrenOf(node));
4001
+ }
4002
+ return found;
4003
+ }
4004
+
4005
+ // src/vite-cx-take-passing.ts
4006
+ function usesOf(analysis, source, specifier) {
4007
+ const local = exportNameOf(nodeAt(specifier, "local"));
4008
+ return analysis.references.filter(
4009
+ ({ binding }) => binding?.kind === "import" && binding.source === source && binding.name === local
4010
+ );
4011
+ }
4012
+ function isPure(flow) {
4013
+ return flow.names.size > 0 && !flow.isCalled && !flow.isUnbound;
4014
+ }
4015
+ function passingOf(analysis, source, specifier) {
4016
+ const flows = usesOf(analysis, source, specifier).map((use) => flowOf(analysis, use.node));
4017
+ if (flows.every((flow) => flow.names.size === 0)) return {};
4018
+ return flows.every((flow) => isPure(flow)) ? { isForward: true, isPassedOn: true } : { isPassedOn: true };
4019
+ }
4020
+ function isCarriedOn(analysis, source, specifier) {
4021
+ return usesOf(analysis, source, specifier).some((use) => flowOf(analysis, use.node).isUnbound);
4022
+ }
4023
+ function isValueCarried(analysis, node) {
4024
+ const flow = flowOf(analysis, node);
4025
+ return flow.isUnbound || flow.names.size > 0;
4026
+ }
4027
+ function isExportedDeclarator2(analysis, declarator) {
4028
+ const declaration = analysis.parentOf.get(declarator);
4029
+ const statement = declaration && analysis.parentOf.get(declaration);
4030
+ return statement?.type === "ExportNamedDeclaration";
4031
+ }
4032
+ function isBoundNameCarried(analysis, property) {
4033
+ const value = nodeAt(property, "value");
4034
+ const declarator = analysis.parentOf.get(analysis.parentOf.get(property) ?? property);
4035
+ const alias = value?.type === "Identifier" ? analysis.bindingDeclaredBy(value) : void 0;
4036
+ if (!alias || declarator?.type !== "VariableDeclarator" || isExportedDeclarator2(analysis, declarator)) {
4037
+ return true;
4038
+ }
4039
+ return analysis.references.some(
4040
+ (use) => use.binding === alias && isValueCarried(analysis, use.node)
4041
+ );
4042
+ }
4043
+ function isPatternCarried(analysis, pattern, names) {
4044
+ return nodesAt(pattern, "properties").some((property) => {
4045
+ const key = propertyNameOf(nodeAt(property, "key"), property.computed === true);
4046
+ if (key === void 0) return false;
4047
+ if (INHERITED_NAMES.has(key)) return true;
4048
+ return isCxName(names, key) && isBoundNameCarried(analysis, property);
4049
+ });
4050
+ }
4051
+ function isCalledWithReceiver2(analysis, member) {
4052
+ let top = unwrapped(analysis, member);
4053
+ let parent = analysis.parentOf.get(top);
4054
+ while (parent?.type === "ChainExpression") {
4055
+ top = unwrapped(analysis, parent);
4056
+ parent = analysis.parentOf.get(top);
4057
+ }
4058
+ if (parent?.type === "CallExpression") return nodeAt(parent, "callee") === top;
4059
+ return parent?.type === "TaggedTemplateExpression" && nodeAt(parent, "tag") === top;
4060
+ }
4061
+ function isUseCarried(analysis, node, names) {
4062
+ const read = memberReadOf({ analysis }, node);
4063
+ if (read) {
4064
+ if (read.key === void 0) return isCalledWithReceiver2(analysis, read.member);
4065
+ if (INHERITED_NAMES.has(read.key)) return true;
4066
+ if (!isCxName(names, read.key)) return isCalledWithReceiver2(analysis, read.member);
4067
+ return isValueCarried(analysis, read.member);
4068
+ }
4069
+ const pattern = patternDestructuring({ analysis }, node);
4070
+ return pattern?.type === "ObjectPattern" && isPatternCarried(analysis, pattern, names);
4071
+ }
4072
+ function heldNamespace(analysis, references, names, source) {
4073
+ const isCarried = references.some(({ node }) => isUseCarried(analysis, node, names));
4074
+ return isCarried ? withHeld({ shape: "namespace", names: [] }, source) : void 0;
4075
+ }
4076
+ function withHeld(taken, source) {
4077
+ const isWhole = taken.names.length === 0 && taken.isForward !== true;
4078
+ if (!isWhole || taken.shape === "names" || taken.shape === "star") return taken;
4079
+ const form = taken.shape === "namespace" ? `uses the namespace of ${source} where the build cannot follow it` : `imports ${source} and uses it where the build cannot follow it`;
4080
+ return { ...taken, isHeld: true, form };
4081
+ }
4082
+
4083
+ // src/vite-cx-takes.ts
4084
+ var UNREADABLE = { shape: "unreadable", names: [] };
4085
+ function namespaceTakes(analysis, references, names) {
4086
+ const found = /* @__PURE__ */ new Set();
4087
+ for (const reference2 of references) {
4088
+ const taken = referenceTakes(analysis, reference2.node, names);
4089
+ if (taken === void 0) return { shape: "namespace", names: [] };
4090
+ for (const name of taken) found.add(name);
4091
+ }
4092
+ return found.size === 0 ? void 0 : { shape: "namespace", names: [...found] };
4093
+ }
4094
+ function referencesTo(analysis, source, specifier) {
4095
+ const local = exportNameOf(nodeAt(specifier, "local"));
4096
+ return analysis.references.filter(({ binding }) => {
4097
+ return binding?.kind === "import" && binding.imported === "*" && binding.source === source && binding.name === local;
4098
+ });
4099
+ }
4100
+ function isTypeUseOnly(scan, source, specifier) {
4101
+ const local = exportNameOf(nodeAt(specifier, "local"));
4102
+ if (local === void 0 || !scan.typeNames().has(local) || scan.jsxNames().has(local)) {
4103
+ return false;
4104
+ }
4105
+ return usesOf(scan.analysis(), source, specifier).length === 0;
4106
+ }
4107
+ function namespaceTakesOf(scan, source, specifier) {
4108
+ const references = referencesTo(scan.analysis(), source, specifier);
4109
+ const taken = namespaceTakes(scan.analysis(), references, scan.names);
4110
+ if (taken?.names.length === 0) return taken;
4111
+ const local = exportNameOf(nodeAt(specifier, "local"));
4112
+ const tags = local === void 0 ? [] : [...scan.jsxMembers(local)];
4113
+ const names = /* @__PURE__ */ new Set([
4114
+ ...taken?.names ?? [],
4115
+ ...tags.filter((name) => isCxName(scan.names, name))
4116
+ ]);
4117
+ return names.size === 0 ? void 0 : { shape: "namespace", names: [...names] };
4118
+ }
4119
+ function namespaceTake(scan, source, specifier) {
4120
+ const references = referencesTo(scan.analysis(), source, specifier);
4121
+ const held2 = scan.isDependency && heldNamespace(scan.analysis(), references, scan.names, source);
4122
+ if (held2) return held2;
4123
+ const taken = namespaceTakesOf(scan, source, specifier);
4124
+ const isForward = passingOf(scan.analysis(), source, specifier).isForward;
4125
+ const forwarded = taken && { ...taken, ...isForward && { isForward } };
4126
+ return forwarded && scan.isDependency ? withHeld(forwarded, source) : forwarded;
4127
+ }
4128
+ function namedTake(scan, source, specifier) {
4129
+ const imported = specifier.type === "ImportDefaultSpecifier" ? "default" : exportNameOf(nodeAt(specifier, "imported"));
4130
+ if (imported === void 0 || !isCxName(scan.names, imported)) return void 0;
4131
+ if (isTypeUseOnly(scan, source, specifier)) return void 0;
4132
+ const isHeld = scan.isDependency && isCarriedOn(scan.analysis(), source, specifier);
4133
+ const form = `uses ${imported} from ${source} where the build cannot follow it`;
4134
+ return {
4135
+ shape: "names",
4136
+ names: [imported],
4137
+ ...passingOf(scan.analysis(), source, specifier),
4138
+ ...isHeld && { isHeld: true, form }
4139
+ };
4140
+ }
4141
+ function importTakes(node, source, scan) {
4142
+ return valueSpecifiersOf(node).flatMap((specifier) => {
4143
+ const taken = specifier.type === "ImportNamespaceSpecifier" ? namespaceTake(scan, source, specifier) : namedTake(scan, source, specifier);
4144
+ return taken ? [taken] : [];
4145
+ });
4146
+ }
4147
+ function exportTakes(node, scan) {
4148
+ if (node.type === "ExportAllDeclaration") {
4149
+ if (nodeAt(node, "exported") !== void 0) {
4150
+ return [{ shape: "namespace", names: [], isForward: true }];
4151
+ }
4152
+ const hasNamed = scan.names === void 0 || scan.names.keys().some((name) => name !== "default");
4153
+ return hasNamed ? [{ shape: "star", names: [], isForward: true }] : [];
4154
+ }
4155
+ const re = valueSpecifiersOf(node).map((specifier) => exportNameOf(nodeAt(specifier, "local"))).filter((name) => name !== void 0 && isCxName(scan.names, name));
4156
+ return re.length === 0 ? [] : [{ shape: "names", names: re, isPassedOn: true, isForward: true }];
4157
+ }
4158
+ function dynamicTakes(node, scan) {
4159
+ const keys = dynamicKeys(scan.analysis(), node, scan.names);
4160
+ if (keys === void 0) return [{ shape: "dynamic-import", names: [] }];
4161
+ return keys.length === 0 ? [] : [{ shape: "dynamic-import", names: keys }];
4162
+ }
4163
+ function takesOf(node, scan) {
4164
+ const source = staticStringOf(nodeAt(node, "source"));
4165
+ if (source === void 0 || !scan.reaches.has(source)) return [];
4166
+ if (isTypeOnly(node)) return [];
4167
+ if (node.type === "ImportDeclaration") return importTakes(node, source, scan);
4168
+ if (node.type === "ImportExpression") {
4169
+ if (!scan.isDependency) return dynamicTakes(node, scan);
4170
+ const taken = isUsedAsCallsOnly(scan.analysis(), node, scan.names) ? dynamicTakes(node, scan) : [{ shape: "dynamic-import", names: [] }];
4171
+ return taken.map((one) => withHeld(one, source));
4172
+ }
4173
+ return exportTakes(node, scan);
4174
+ }
4175
+ function takesIn(program, input) {
4176
+ let analysis;
4177
+ let typeNames;
4178
+ let jsxNames;
4179
+ let jsxMembers;
4180
+ const scan = {
4181
+ ...input,
4182
+ isDependency: input.isDependency === true,
4183
+ analysis: () => analysis ??= analyze(program),
4184
+ typeNames: () => typeNames ??= namesIn(program, typeNameOf),
4185
+ jsxNames: () => jsxNames ??= namesIn(program, jsxNameOf),
4186
+ jsxMembers: (local) => (jsxMembers ??= jsxMembersIn(program)).get(local) ?? /* @__PURE__ */ new Set()
4187
+ };
4188
+ const found = [];
4189
+ const stack = [program];
4190
+ while (stack.length > 0) {
4191
+ const node = stack.pop();
4192
+ pushAll(found, takesOf(node, scan));
4193
+ pushAll(stack, childrenOf(node));
4194
+ }
4195
+ return found;
4196
+ }
4197
+
4198
+ // src/vite-listed-routes.ts
4199
+ function importTakesOf(program, input) {
4200
+ return input.reaches.size === 0 ? [] : takesIn(program, input);
4201
+ }
4202
+ function unreadableFor(id, module) {
4203
+ return isDependencyId(id) ? { ...UNREADABLE, isHeld: true, form: `takes ${module} in a way the build cannot read` } : UNREADABLE;
4204
+ }
4205
+ function requireTakesOf(program, input) {
4206
+ if (input.requires.size === 0) return [];
4207
+ return requireTakesIn(program, {
4208
+ names: input.names,
4209
+ reaches: input.requires,
4210
+ readsForwards: isDependencyId(input.id)
4211
+ }).takes;
4212
+ }
4213
+ async function takenBy(ctx, input) {
4214
+ const { file, id, label, names, resolutions } = input;
4215
+ const unreadable = () => unreadableFor(id, label);
4216
+ const code = ctx.getModuleInfo?.(id)?.code;
4217
+ try {
4218
+ const read = code === null || code === void 0 ? void 0 : await reachingSpecifiers(ctx, { code, file, id, resolutions });
4219
+ if (!read) return [unreadable()];
4220
+ const { program, reaches, requires } = read;
4221
+ if (reaches.size === 0 && requires.size === 0) return [unreadable()];
4222
+ return [
4223
+ ...importTakesOf(program, { isDependency: isDependencyId(id), names, reaches }),
4224
+ ...requireTakesOf(program, { id, names, requires })
4225
+ ];
4226
+ } catch {
4227
+ return [unreadable()];
4228
+ }
4229
+ }
4230
+ function merged(takes) {
4231
+ const byKey = /* @__PURE__ */ new Map();
4232
+ for (const take of takes) {
4233
+ const key = `${take.taker}\0${take.shape}`;
4234
+ const known = byKey.get(key);
4235
+ const names = /* @__PURE__ */ new Set([...known?.names ?? [], ...take.names]);
4236
+ const isReached = take.isReached || known?.isReached === true;
4237
+ const isPassedOn = take.isPassedOn === true || known?.isPassedOn === true;
4238
+ byKey.set(key, { ...take, isPassedOn, isReached, names: [...names].toSorted(compareText) });
4239
+ }
4240
+ return byKey.values().toArray();
4241
+ }
4242
+ async function isCounted(context, input) {
4243
+ const { importer, isEntry, pkg, wantCalls } = input;
4244
+ if (wantCalls || !isDependencyId(importer)) return true;
4245
+ if (!isEntry) return false;
4246
+ return await context.packageOf(importer) !== pkg;
4247
+ }
4248
+ async function routesOf(ctx, context, input) {
4249
+ const { holder, importer, isEntry, resolutions, wantCalls } = input;
4250
+ const isDependency = isDependencyId(importer);
4251
+ const taker = context.labelOf(importer);
4252
+ const taken = await takenBy(ctx, {
4253
+ file: fileOf(holder.id),
4254
+ id: importer,
4255
+ label: context.labelOf(fileOf(holder.id)),
4256
+ names: holder.names,
4257
+ resolutions
4258
+ });
4259
+ const takes = taken.map((take) => ({ ...take, taker, isReached: holder.isReached }));
4260
+ if (isDependency) {
4261
+ const pkg = await context.packageOf(importer) ?? taker;
4262
+ const held2 = takes.filter((take) => take.isHeld === true).map((take) => ({ form: take.form ?? "", importer, pkg, taker }));
4263
+ const calls = takes.filter((take) => take.isForward !== true && take.isHeld !== true);
4264
+ return { entry: isEntry ? calls : [], told: [], calls: wantCalls ? calls : [], held: held2 };
4265
+ }
4266
+ const isCleared = (take) => isEntry && take.shape !== "unreadable";
4267
+ return {
4268
+ entry: takes.filter((take) => isCleared(take)),
4269
+ told: takes.filter((take) => !isCleared(take)),
4270
+ calls: [],
4271
+ held: []
4272
+ };
4273
+ }
4274
+ function serverTakesOf(found, holder) {
4275
+ const takes = [];
4276
+ for (const taken of found.takes) {
4277
+ const names = taken.names.filter((name) => holder.names.has(name));
4278
+ const isWhole = taken.names.length === 0;
4279
+ const hasNamed = holder.names.keys().some((name) => name !== "default");
4280
+ const isTaken = taken.shape === "star" ? hasNamed : isWhole || names.length > 0;
4281
+ if (isTaken) {
4282
+ const kept = isWhole ? taken.names : names;
4283
+ takes.push({
4284
+ ...taken,
4285
+ names: kept,
4286
+ taker: found.taker,
4287
+ isReached: holder.isReached,
4288
+ ...found.isRecorded === true && { isRecorded: true }
4289
+ });
4290
+ }
4291
+ }
4292
+ return takes;
4293
+ }
4294
+ async function takesFrom(ctx, context, input) {
4295
+ const { holder, isEntry, pkg, resolutions, wantCalls } = input;
4296
+ const importers = importersOf(ctx, holder.id);
4297
+ const entry = [];
4298
+ const told = [];
4299
+ const calls = [];
4300
+ const held2 = [];
4301
+ for (const importer of importers) {
4302
+ const routes = await routesOf(ctx, context, {
4303
+ holder,
4304
+ importer,
4305
+ isEntry,
4306
+ resolutions,
4307
+ wantCalls
4308
+ });
4309
+ pushAll(held2, routes.held);
4310
+ if (!await isCounted(context, { importer, isEntry, pkg, wantCalls })) continue;
4311
+ pushAll(entry, routes.entry);
4312
+ pushAll(told, routes.told);
4313
+ pushAll(calls, routes.calls);
4314
+ }
4315
+ return { entry: merged(entry), told: merged(told), calls: merged(calls), held: held2 };
4316
+ }
4317
+ function serverRoutes(holder, input) {
4318
+ const file = fileOf(holder.id);
4319
+ const fromServer = input.serverImports.filter((one) => one.file === file);
4320
+ const takes = fromServer.flatMap((found) => serverTakesOf(found, holder));
4321
+ const isCleared = (take) => input.isEntry && take.shape !== "unreadable";
4322
+ return {
4323
+ entry: takes.filter((take) => isCleared(take)),
4324
+ told: takes.filter((take) => !isCleared(take))
4325
+ };
4326
+ }
4327
+
4328
+ // src/vite-listed-takes.ts
4329
+ async function prepareOne(ctx, context, input) {
4330
+ const { isHop, problems, walk } = input;
4331
+ const first2 = problems[0];
4332
+ const pkg = first2.pkg;
4333
+ const names = new Set(problems.flatMap((problem2) => problem2.exportedAs ?? []));
4334
+ const hasEntry = !isHop && problems.some((problem2) => problem2.specifier !== void 0);
4335
+ const holders = await holdersOf(ctx, { ...walk, id: first2.moduleId, names });
4336
+ const routed = await Promise.all(
4337
+ holders.map(
4338
+ (holder) => takesFrom(ctx, context, {
4339
+ holder,
4340
+ isEntry: hasEntry && !holder.isReached,
4341
+ pkg,
4342
+ resolutions: walk.resolutions,
4343
+ wantCalls: isHop
4344
+ })
4345
+ )
4346
+ );
4347
+ const isListed = Object.hasOwn(context.options.keepFor, pkg);
4348
+ return { hasEntry, holders, isHop, isListed, problems, rootName: context.rootName, routed };
4349
+ }
4350
+ function heldProblemsOf(routed) {
4351
+ const byKey = /* @__PURE__ */ new Map();
4352
+ const all = routed.flatMap((route) => route.held);
4353
+ for (const held2 of all) byKey.set(`${held2.importer}\0${held2.form}`, held2);
4354
+ return byKey.values().map((held2) => ({
4355
+ kind: "reference",
4356
+ offset: 0,
4357
+ construct: "",
4358
+ text: `${held2.form}.`,
4359
+ file: held2.taker,
4360
+ line: 0,
4361
+ column: 0,
4362
+ unknownLine: "",
4363
+ pkg: held2.pkg,
4364
+ moduleId: held2.importer,
4365
+ isHeld: true
4366
+ })).toArray();
4367
+ }
4368
+ function decideOne(prepared, serverImports) {
4369
+ return [...heldProblemsOf(prepared.routed), ...decidedByTakes(prepared, serverImports)];
4370
+ }
4371
+ function decidedByTakes(prepared, serverImports) {
4372
+ const { hasEntry, holders, isHop, isListed, problems, rootName, routed } = prepared;
4373
+ const fromServer = holders.map(
4374
+ (holder) => serverRoutes(holder, { isEntry: hasEntry && !holder.isReached, serverImports })
4375
+ );
4376
+ const entry = [...routed.flatMap((route) => route.entry), ...fromServer.flatMap((r) => r.entry)];
4377
+ if (entry.length > 0) return problems.filter((problem2) => problem2.specifier !== void 0);
4378
+ const told = merged([
4379
+ ...routed.flatMap((route) => route.told),
4380
+ ...fromServer.flatMap((route) => route.told)
4381
+ ]);
4382
+ const callers = isHop && !isListed ? callersOf(routed) : [];
4383
+ if (told.length === 0 && callers.length === 0) return [];
4384
+ return problems.map((problem2) => ({
4385
+ ...problem2,
4386
+ ...told.length > 0 && { takes: told, rootName },
4387
+ ...callers.length > 0 && { callers }
4388
+ }));
4389
+ }
4390
+ function callersOf(routed) {
4391
+ const callers = new Set(routed.flatMap((route) => route.calls.map((call) => call.taker)));
4392
+ return [...callers].toSorted(compareText);
4393
+ }
4394
+ async function prepareReexports(ctx, context, standingIn) {
4395
+ const exporting = standingIn.filter((problem2) => problem2.exportedAs !== void 0);
4396
+ const located = await withClearingSpecifiers(ctx, context, exporting);
4397
+ const byModule = /* @__PURE__ */ new Map();
4398
+ const hops = /* @__PURE__ */ new Map();
4399
+ for (const problem2 of located) {
4400
+ if (problem2.moduleId === void 0 || problem2.pkg === void 0) continue;
4401
+ const group = isSecondHop(problem2) ? hops : byModule;
4402
+ group.set(problem2.moduleId, [...group.get(problem2.moduleId) ?? [], problem2]);
4403
+ }
4404
+ const cxExports = new Map(
4405
+ [...byModule.values(), ...hops.values()].map((problems) => [
4406
+ fileOf(problems[0].moduleId),
4407
+ new Set(problems.flatMap((problem2) => problem2.exportedAs ?? []))
4408
+ ])
4409
+ );
4410
+ const walk = { cxExports, resolutions: /* @__PURE__ */ new Map() };
4411
+ return await Promise.all([
4412
+ ...byModule.values().map((problems) => prepareOne(ctx, context, { isHop: false, problems, walk })),
4413
+ ...hops.values().map((problems) => prepareOne(ctx, context, { isHop: true, problems, walk }))
4414
+ ]);
4415
+ }
4416
+ function decideReexports(prepared, serverImports) {
4417
+ const decided = prepared.flatMap((one) => decideOne(one, serverImports));
4418
+ const isFirst = (problem2, index) => problem2.isHeld !== true || decided.findIndex(
4419
+ (other) => other.isHeld === true && other.moduleId === problem2.moduleId && other.text === problem2.text
4420
+ ) === index;
4421
+ return decided.filter((problem2, index) => isFirst(problem2, index));
4422
+ }
4423
+
4424
+ // src/vite-reexport-judge.ts
4425
+ async function judgeReexports(host, context, modules, serverImports = []) {
4426
+ const kept = await withClearingSpecifiers(
4427
+ host,
4428
+ context,
4429
+ withoutEchoes(
4430
+ modules.map((module) => ({
4431
+ onlyVia: module.onlyVia,
4432
+ problems: [
4433
+ ...module.problems,
4434
+ ...module.suppressed.filter((problem2) => problem2.kind === "declared")
4435
+ ]
4436
+ }))
4437
+ )
4438
+ );
4439
+ const suppressed = modules.flatMap((module) => module.suppressed);
4440
+ const held2 = suppressed.filter((problem2) => problem2.isUnboundHandOut === true).map((problem2) => ({ ...problem2, isHeld: true }));
4441
+ const standingIn = [
4442
+ ...suppressed.filter((problem2) => problem2.isUnboundHandOut !== true),
4443
+ ...kept.filter((problem2) => isSecondHop(problem2))
4444
+ ];
4445
+ const rest = kept.filter((problem2) => !isSecondHop(problem2));
4446
+ const prepared = await prepareReexports(host, context, standingIn);
4447
+ return { problems: [...rest, ...held2, ...decideReexports(prepared, serverImports)], prepared };
4448
+ }
4449
+
4450
+ // src/vite-restorers.ts
4451
+ function withRestorers(atoms) {
4452
+ if (atoms.has("srOnly")) atoms.add("srOnlyFocusable");
4453
+ return atoms;
4454
+ }
4455
+
2650
4456
  // src/vite-used-report.ts
2651
4457
  var LINE_UNKNOWN_WITHOUT_MAP = " (line unknown: this file's compiled code has no source map in this build; with build.sourcemap set in the Vite config, the report gives the line if the source maps then lead back to it)";
2652
4458
  var LINE_UNKNOWN_UNMAPPED = " (line unknown: no source map leads from the compiled code to this file)";
@@ -2704,11 +4510,11 @@ function applicationLines(application, configured, home) {
2704
4510
  }
2705
4511
  return lines;
2706
4512
  }
2707
- function remedyBlock(problems, listed, home, hostRemedies) {
4513
+ function remedyBlock(problems, listed, places, hostRemedies) {
2708
4514
  const configured = withoutRemoved(problems, listed);
2709
4515
  const application = problems.filter((problem2) => problem2.pkg === void 0);
2710
4516
  const lines = [
2711
- ...applicationLines(application, configured, home),
4517
+ ...applicationLines(application, configured, places.home),
2712
4518
  ...hostRemedies?.(application) ?? []
2713
4519
  ];
2714
4520
  const byPackage = /* @__PURE__ */ new Map();
@@ -2717,7 +4523,7 @@ function remedyBlock(problems, listed, home, hostRemedies) {
2717
4523
  byPackage.set(problem2.pkg, [...byPackage.get(problem2.pkg) ?? [], problem2]);
2718
4524
  }
2719
4525
  for (const pkg of byPackage.keys().toArray().toSorted(compareText)) {
2720
- lines.push(...packageLines(pkg, byPackage.get(pkg), configured, home));
4526
+ lines.push(...packageLines(pkg, byPackage.get(pkg), configured, places));
2721
4527
  }
2722
4528
  if (application.some((problem2) => problem2.needsAvailable)) lines.push(availableLine());
2723
4529
  return lines;
@@ -2749,17 +4555,21 @@ function problemLines(problems) {
2749
4555
  function noun(count, word) {
2750
4556
  return `${count} ${word}${count === 1 ? "" : "s"}`;
2751
4557
  }
2752
- function buildReport(problems, configured, home, hostRemedies) {
4558
+ function buildReport(problems, configured, home, host) {
4559
+ const { remedies: hostRemedies, everyAtom = EVERY_ATOM } = typeof host === "function" ? { remedies: host } : host ?? {};
2753
4560
  const files = new Set(problems.map((problem2) => problem2.file)).size;
2754
4561
  const first2 = `${noun(problems.length, "problem")} in ${noun(files, "file")}: ${REPORT_CAUSE}`;
2755
4562
  return [
2756
4563
  first2,
2757
4564
  ...problemLines(problems),
2758
- ...remedyBlock(problems, configured, home, hostRemedies)
4565
+ ...remedyBlock(problems, configured, { home, everyAtom }, hostRemedies)
2759
4566
  ].join("\n");
2760
4567
  }
2761
4568
  function moduleReport(problems, configured, home) {
2762
- return [...problemLines(problems), ...remedyBlock(problems, configured, home)].join("\n");
4569
+ return [
4570
+ ...problemLines(problems),
4571
+ ...remedyBlock(problems, configured, { home, everyAtom: EVERY_ATOM })
4572
+ ].join("\n");
2763
4573
  }
2764
4574
 
2765
- export { CLASS_MAP_NOT_PARSED, CX_SOURCE, LINE_UNKNOWN_UNMAPPED, LINE_UNKNOWN_WITHOUT_MAP, REPORT_CAUSE, analyze, applyEdits, assertOptions, atomOfClass, atomsWrittenIn, buildReport, childrenOf, combinedMapOf, compareText, cxModulesArray, exportNameOf, inspectAtomicLayer, isListableReexport, isNode, isSecondHop, keptAtoms, memberReadOf, moduleReport, nodeAt, nodesAt, patternDestructuring, placerFor, propertyNameOf, pruneAtomicLayer, pushAll, readModule, resolveUsedOptions, staticStringOf, stringAt, toSourceMap, unprunedAtoms, withRestorers, withoutRemoved };
4575
+ export { CLASS_MAP_NOT_PARSED, CX_ONLY, CX_SOURCE, LINE_UNKNOWN_UNMAPPED, LINE_UNKNOWN_WITHOUT_MAP, REPORT_CAUSE, UNREADABLE, analyze, applyEdits, assertOptions, atomOfClass, atomsWrittenIn, buildReport, canHoldDirective, childrenOf, combinedMapOf, compareText, cxModulesArray, decideReexports, declaredModulesFor, fileOf, filePathOf, flowOf, forgetDeclared, inspectAtomicLayer, isAboutListed, isCssModuleId, isDependencyId, isListedFile, isNamingListed, isNode, isRelative, isResolvingTo, isStylesheetId, isStylesheetPath, isUnreadStylesheet, isUsedAsCallsOnly, judgeReexports, keptAtoms, moduleReport, nodeAt, nodesAt, placerFor, pruneAtomicLayer, pushAll, readModule, recognisedKey, resolveOrNull, resolveUsedOptions, specifiersIn, specifiersOf, staticStringOf, takesIn, toSourceMap, unprunedAtoms, withRestorers, withoutRemoved };