@pyreon/vite-plugin 0.25.1 → 0.26.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/analysis/index.js.html +1 -1
- package/lib/index.js +219 -21
- package/lib/index.js.map +1 -1
- package/lib/{rocketstyle-collapse-DGnwgDhC.js → rocketstyle-collapse-XIiHU85Y.js} +57 -38
- package/lib/rocketstyle-collapse-XIiHU85Y.js.map +1 -0
- package/lib/types/index.d.ts +123 -2
- package/lib/types/index.d.ts.map +1 -1
- package/package.json +6 -4
- package/lib/rocketstyle-collapse-DGnwgDhC.js.map +0 -1
|
@@ -5386,7 +5386,7 @@ var drawChart = (function (exports) {
|
|
|
5386
5386
|
</script>
|
|
5387
5387
|
<script>
|
|
5388
5388
|
/*<!--*/
|
|
5389
|
-
const data = {"version":2,"tree":{"name":"root","children":[{"name":"index.js","children":[{"name":"src/index.ts","uid":"
|
|
5389
|
+
const data = {"version":2,"tree":{"name":"root","children":[{"name":"index.js","children":[{"name":"src/index.ts","uid":"f90e1d82-1"}]},{"name":"rocketstyle-collapse-XIiHU85Y.js","children":[{"name":"src/rocketstyle-collapse.ts","uid":"f90e1d82-3"}]}],"isRoot":true},"nodeParts":{"f90e1d82-1":{"renderedLength":56169,"gzipLength":18271,"brotliLength":0,"metaUid":"f90e1d82-0"},"f90e1d82-3":{"renderedLength":5493,"gzipLength":2490,"brotliLength":0,"metaUid":"f90e1d82-2"}},"nodeMetas":{"f90e1d82-0":{"id":"/src/index.ts","moduleParts":{"index.js":"f90e1d82-1"},"imported":[{"uid":"f90e1d82-4"},{"uid":"f90e1d82-5"},{"uid":"f90e1d82-6"},{"uid":"f90e1d82-2","dynamic":true},{"uid":"f90e1d82-7","dynamic":true}],"importedBy":[],"isEntry":true},"f90e1d82-2":{"id":"/src/rocketstyle-collapse.ts","moduleParts":{"rocketstyle-collapse-XIiHU85Y.js":"f90e1d82-3"},"imported":[{"uid":"f90e1d82-8"},{"uid":"f90e1d82-9","dynamic":true}],"importedBy":[{"uid":"f90e1d82-0"}]},"f90e1d82-4":{"id":"node:fs","moduleParts":{},"imported":[],"importedBy":[{"uid":"f90e1d82-0"}]},"f90e1d82-5":{"id":"node:path","moduleParts":{},"imported":[],"importedBy":[{"uid":"f90e1d82-0"}]},"f90e1d82-6":{"id":"@pyreon/compiler","moduleParts":{},"imported":[],"importedBy":[{"uid":"f90e1d82-0"}]},"f90e1d82-7":{"id":"node:fs/promises","moduleParts":{},"imported":[],"importedBy":[{"uid":"f90e1d82-0"}]},"f90e1d82-8":{"id":"@pyreon/reactivity","moduleParts":{},"imported":[],"importedBy":[{"uid":"f90e1d82-2"}]},"f90e1d82-9":{"id":"vite","moduleParts":{},"imported":[],"importedBy":[{"uid":"f90e1d82-2"}]}},"env":{"rollup":"4.23.0"},"options":{"gzip":true,"brotli":false,"sourcemap":false}};
|
|
5390
5390
|
|
|
5391
5391
|
const run = () => {
|
|
5392
5392
|
const width = window.innerWidth;
|
package/lib/index.js
CHANGED
|
@@ -40,7 +40,7 @@ const __DEV__ = typeof process !== "undefined" && process.env.NODE_ENV !== "prod
|
|
|
40
40
|
const _countSink = globalThis;
|
|
41
41
|
let _createCollapseResolver = null;
|
|
42
42
|
async function loadCreateCollapseResolver() {
|
|
43
|
-
if (!_createCollapseResolver) _createCollapseResolver = (await import("./rocketstyle-collapse-
|
|
43
|
+
if (!_createCollapseResolver) _createCollapseResolver = (await import("./rocketstyle-collapse-XIiHU85Y.js")).createCollapseResolver;
|
|
44
44
|
return _createCollapseResolver;
|
|
45
45
|
}
|
|
46
46
|
const HMR_RUNTIME_ID = "\0pyreon/hmr-runtime";
|
|
@@ -108,7 +108,7 @@ const COMPAT_ALIASES = {
|
|
|
108
108
|
* structural property of the monorepo (workspace layout), not the package
|
|
109
109
|
* name — so it's robust against renames.
|
|
110
110
|
*/
|
|
111
|
-
function
|
|
111
|
+
function _isPyreonWorkspaceFile(id, cache) {
|
|
112
112
|
const queryIdx = id.indexOf("?");
|
|
113
113
|
const filePath = queryIdx === -1 ? id : id.slice(0, queryIdx);
|
|
114
114
|
if (!filePath || filePath[0] === "\0") return false;
|
|
@@ -137,7 +137,7 @@ function isPyreonWorkspaceFile(id, cache) {
|
|
|
137
137
|
* Return the Pyreon compat target for an import specifier, or undefined if
|
|
138
138
|
* the import should not be redirected.
|
|
139
139
|
*/
|
|
140
|
-
function
|
|
140
|
+
function _getCompatTarget(compat, id) {
|
|
141
141
|
if (!compat) return void 0;
|
|
142
142
|
const aliased = COMPAT_ALIASES[compat][id];
|
|
143
143
|
if (aliased) return aliased;
|
|
@@ -249,6 +249,27 @@ function pyreonPlugin(options) {
|
|
|
249
249
|
source: "@pyreon/ui-core"
|
|
250
250
|
};
|
|
251
251
|
const collapseSources = new Set(collapseUserCfg.sources ?? ["@pyreon/ui-components"]);
|
|
252
|
+
const jsxAutoImportOpt = options?.jsxAutoImport;
|
|
253
|
+
const jsxAutoImportEnabled = jsxAutoImportOpt !== false;
|
|
254
|
+
const jsxAutoImportUserCfg = jsxAutoImportOpt && jsxAutoImportOpt !== true ? jsxAutoImportOpt : {};
|
|
255
|
+
const jsxAutoImportMappings = jsxAutoImportUserCfg.mappings ?? (jsxAutoImportUserCfg.source && jsxAutoImportUserCfg.names ? [{
|
|
256
|
+
source: jsxAutoImportUserCfg.source,
|
|
257
|
+
names: jsxAutoImportUserCfg.names
|
|
258
|
+
}] : [{
|
|
259
|
+
source: "@pyreon/primitives",
|
|
260
|
+
names: [
|
|
261
|
+
"Stack",
|
|
262
|
+
"Inline",
|
|
263
|
+
"Text",
|
|
264
|
+
"Button",
|
|
265
|
+
"Press",
|
|
266
|
+
"Field",
|
|
267
|
+
"Toggle"
|
|
268
|
+
]
|
|
269
|
+
}, {
|
|
270
|
+
source: "@pyreon/core",
|
|
271
|
+
names: ["For", "Show"]
|
|
272
|
+
}]);
|
|
252
273
|
const collapseComponentFilter = collapseUserCfg.components ? (n) => collapseUserCfg.components.includes(n) : null;
|
|
253
274
|
let collapseResolver = null;
|
|
254
275
|
let collapseResolverInit = null;
|
|
@@ -276,6 +297,7 @@ function pyreonPlugin(options) {
|
|
|
276
297
|
const resolveCache = /* @__PURE__ */ new Map();
|
|
277
298
|
const pyreonWorkspaceDirCache = /* @__PURE__ */ new Map();
|
|
278
299
|
const islandRegistry = /* @__PURE__ */ new Map();
|
|
300
|
+
let _devServer;
|
|
279
301
|
return {
|
|
280
302
|
name: "pyreon",
|
|
281
303
|
enforce: "pre",
|
|
@@ -334,8 +356,8 @@ function pyreonPlugin(options) {
|
|
|
334
356
|
async resolveId(id, importer) {
|
|
335
357
|
if (id === HMR_RUNTIME_IMPORT) return HMR_RUNTIME_ID;
|
|
336
358
|
if (id === ISLANDS_REGISTRY_IMPORT) return ISLANDS_REGISTRY_ID;
|
|
337
|
-
if (compat && (id === "@pyreon/core/jsx-runtime" || id === "@pyreon/core/jsx-dev-runtime") && importer &&
|
|
338
|
-
const target =
|
|
359
|
+
if (compat && (id === "@pyreon/core/jsx-runtime" || id === "@pyreon/core/jsx-dev-runtime") && importer && _isPyreonWorkspaceFile(importer, pyreonWorkspaceDirCache)) return;
|
|
360
|
+
const target = _getCompatTarget(compat, id);
|
|
339
361
|
if (!target) return;
|
|
340
362
|
return (await this.resolve(target, importer, { skipSelf: true }))?.id;
|
|
341
363
|
},
|
|
@@ -357,9 +379,15 @@ function pyreonPlugin(options) {
|
|
|
357
379
|
return;
|
|
358
380
|
}
|
|
359
381
|
scanSignalExports(code, normalizeModuleId(id), signalExportRegistry);
|
|
360
|
-
if (islandsEnabled)
|
|
361
|
-
|
|
362
|
-
|
|
382
|
+
if (islandsEnabled) {
|
|
383
|
+
if (scanIslandDeclarations(code, id, islandRegistry) && _devServer) {
|
|
384
|
+
const mod = _devServer.moduleGraph.getModuleById(ISLANDS_REGISTRY_ID);
|
|
385
|
+
if (mod) _devServer.moduleGraph.invalidateModule(mod);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
const codeAfterAutoImport = jsxAutoImportEnabled ? autoImportCanonicalPrimitives(code, jsxAutoImportMappings) : code;
|
|
389
|
+
const deferResult = transformDeferInline(codeAfterAutoImport, id);
|
|
390
|
+
const sourceForJsx = deferResult.changed ? deferResult.code : codeAfterAutoImport;
|
|
363
391
|
for (const w of deferResult.warnings) this.warn(`${w.message} (${id}:${w.line}:${w.column})`);
|
|
364
392
|
const knownSignals = await resolveImportedSignals(sourceForJsx, id, signalExportRegistry, this, resolveCache);
|
|
365
393
|
const isSsr = transformOptions?.ssr === true;
|
|
@@ -383,6 +411,7 @@ function pyreonPlugin(options) {
|
|
|
383
411
|
},
|
|
384
412
|
props: s.props,
|
|
385
413
|
childrenText: s.childrenText,
|
|
414
|
+
...s.childTree ? { childTree: s.childTree } : {},
|
|
386
415
|
config: {
|
|
387
416
|
provider: collapseProvider,
|
|
388
417
|
theme: collapseTheme,
|
|
@@ -424,6 +453,7 @@ function pyreonPlugin(options) {
|
|
|
424
453
|
};
|
|
425
454
|
},
|
|
426
455
|
configureServer(server) {
|
|
456
|
+
_devServer = server;
|
|
427
457
|
generateProjectContext(projectRoot);
|
|
428
458
|
let contextTimer = null;
|
|
429
459
|
server.watcher.on("change", (file) => {
|
|
@@ -440,7 +470,7 @@ function pyreonPlugin(options) {
|
|
|
440
470
|
const url = req.url ?? "/";
|
|
441
471
|
if (isAssetRequest(url)) return next();
|
|
442
472
|
try {
|
|
443
|
-
await
|
|
473
|
+
await _handleSsrRequest(server, ssrConfig.entry, url, req, res, next);
|
|
444
474
|
} catch (err) {
|
|
445
475
|
server.ssrFixStacktrace(err);
|
|
446
476
|
next(err);
|
|
@@ -455,7 +485,7 @@ function pyreonPlugin(options) {
|
|
|
455
485
|
}
|
|
456
486
|
};
|
|
457
487
|
}
|
|
458
|
-
async function
|
|
488
|
+
async function _handleSsrRequest(server, entry, url, req, res, next) {
|
|
459
489
|
const mod = await server.ssrLoadModule(entry);
|
|
460
490
|
const handler = mod.handler ?? mod.default;
|
|
461
491
|
if (typeof handler !== "function") {
|
|
@@ -637,7 +667,7 @@ const SIGNAL_PREFIX_RE = /^((?:export\s+)?(?:const|let)\s+(\w+)\s*=\s*)signal(?:
|
|
|
637
667
|
* (uppercase first letter — standard convention for JSX components).
|
|
638
668
|
*/
|
|
639
669
|
const EXPORT_COMPONENT_RE = /export\s+(?:default\s+)?(?:function\s+([A-Z]\w*)|const\s+([A-Z]\w*)\s*[=:])/;
|
|
640
|
-
function
|
|
670
|
+
function _skipStringLiteral(code, start, quote) {
|
|
641
671
|
let j = start + 1;
|
|
642
672
|
while (j < code.length) {
|
|
643
673
|
if (code[j] === "\\") {
|
|
@@ -649,7 +679,7 @@ function skipStringLiteral(code, start, quote) {
|
|
|
649
679
|
}
|
|
650
680
|
return j;
|
|
651
681
|
}
|
|
652
|
-
function
|
|
682
|
+
function _extractBalancedArgs(code, start) {
|
|
653
683
|
let depth = 1;
|
|
654
684
|
for (let i = start; i < code.length; i++) {
|
|
655
685
|
const ch = code[i];
|
|
@@ -657,7 +687,7 @@ function extractBalancedArgs(code, start) {
|
|
|
657
687
|
else if (ch === ")") {
|
|
658
688
|
depth--;
|
|
659
689
|
if (depth === 0) return code.slice(start, i);
|
|
660
|
-
} else if (ch === "\"" || ch === "'" || ch === "`") i =
|
|
690
|
+
} else if (ch === "\"" || ch === "'" || ch === "`") i = _skipStringLiteral(code, i, ch);
|
|
661
691
|
}
|
|
662
692
|
return null;
|
|
663
693
|
}
|
|
@@ -671,7 +701,7 @@ function braceDepthAt(code, pos) {
|
|
|
671
701
|
const ch = code[i];
|
|
672
702
|
if (ch === "{") depth++;
|
|
673
703
|
else if (ch === "}") depth--;
|
|
674
|
-
else if (ch === "\"" || ch === "'" || ch === "`") i =
|
|
704
|
+
else if (ch === "\"" || ch === "'" || ch === "`") i = _skipStringLiteral(code, i, ch);
|
|
675
705
|
}
|
|
676
706
|
return depth;
|
|
677
707
|
}
|
|
@@ -682,7 +712,7 @@ function rewriteSignals(code, moduleId) {
|
|
|
682
712
|
let m = SIGNAL_PREFIX_RE.exec(code);
|
|
683
713
|
while (m !== null) {
|
|
684
714
|
const argsStart = m.index + m[0].length;
|
|
685
|
-
const args =
|
|
715
|
+
const args = _extractBalancedArgs(code, argsStart);
|
|
686
716
|
if (args === null) {
|
|
687
717
|
m = SIGNAL_PREFIX_RE.exec(code);
|
|
688
718
|
continue;
|
|
@@ -760,7 +790,7 @@ function injectSignalNames(code, moduleId) {
|
|
|
760
790
|
let m = reBound.exec(masked);
|
|
761
791
|
while (m !== null) {
|
|
762
792
|
const argsStart = m.index + m[0].length;
|
|
763
|
-
const args =
|
|
793
|
+
const args = _extractBalancedArgs(code, argsStart);
|
|
764
794
|
if (args !== null && !hasMultipleArgs(args)) {
|
|
765
795
|
matches.push({
|
|
766
796
|
start: argsStart,
|
|
@@ -779,7 +809,7 @@ function injectSignalNames(code, moduleId) {
|
|
|
779
809
|
while (m !== null) {
|
|
780
810
|
if (!covered.has(m.index)) {
|
|
781
811
|
const argsStart = m.index + m[0].length;
|
|
782
|
-
const args =
|
|
812
|
+
const args = _extractBalancedArgs(code, argsStart);
|
|
783
813
|
if (args !== null && !hasMultipleArgs(args)) matches.push({
|
|
784
814
|
start: argsStart,
|
|
785
815
|
end: argsStart + args.length,
|
|
@@ -992,6 +1022,159 @@ function injectHmr(code, moduleId) {
|
|
|
992
1022
|
function transformCompatAttributes(code) {
|
|
993
1023
|
return code.replace(/(\s)className(\s*=)/g, "$1class$2").replace(/(\s)htmlFor(\s*=)/g, "$1for$2");
|
|
994
1024
|
}
|
|
1025
|
+
/**
|
|
1026
|
+
* Auto-inject `import { ... } from '<source>'` for bare JSX references
|
|
1027
|
+
* to canonical primitives. Closes the Phase D2 "literally same .tsx
|
|
1028
|
+
* file across web + native" gap — the native PMTC compiler resolves
|
|
1029
|
+
* bare tags via its canonical-primitives table (no import needed); the
|
|
1030
|
+
* web build needs the imports for symbol resolution.
|
|
1031
|
+
*
|
|
1032
|
+
* Pass shape:
|
|
1033
|
+
* 1. Regex-scan `<Name` JSX opening tags + `<Name/>` self-closing
|
|
1034
|
+
* shapes against the configured names set.
|
|
1035
|
+
* 2. Parse existing imports from the source to find what's already
|
|
1036
|
+
* imported as a value (we don't auto-add a name that's already in
|
|
1037
|
+
* scope, regardless of source — a user-defined `<Button>` from a
|
|
1038
|
+
* local file takes precedence).
|
|
1039
|
+
* 3. Inject the auto-import ONLY for names that are used but not
|
|
1040
|
+
* already imported. Skips entirely if the diff is empty.
|
|
1041
|
+
*
|
|
1042
|
+
* Conservative by construction: regex matches only at JSX opening-tag
|
|
1043
|
+
* positions (`<Name` followed by `[\s/>]`). String/comment scans aren't
|
|
1044
|
+
* needed because the regex requires the `<` boundary. Names in regular
|
|
1045
|
+
* code positions (function calls, type references) don't trigger the
|
|
1046
|
+
* import.
|
|
1047
|
+
*
|
|
1048
|
+
* Same module's own export shape is detected — if the source exports
|
|
1049
|
+
* a `Stack` symbol via `export function Stack(...)` or `export const
|
|
1050
|
+
* Stack = ...`, the auto-import is suppressed for that name (it's
|
|
1051
|
+
* already a top-level identifier in scope, and importing from the
|
|
1052
|
+
* primitives package would shadow it).
|
|
1053
|
+
*/
|
|
1054
|
+
function autoImportCanonicalPrimitives(code, mappings) {
|
|
1055
|
+
if (mappings.length === 0) return code;
|
|
1056
|
+
const nameToSource = /* @__PURE__ */ new Map();
|
|
1057
|
+
for (const { source, names } of mappings) for (const n of names) if (!nameToSource.has(n)) nameToSource.set(n, source);
|
|
1058
|
+
if (nameToSource.size === 0) return code;
|
|
1059
|
+
const masked = _maskCommentsAndStrings(code);
|
|
1060
|
+
const allNames = Array.from(nameToSource.keys());
|
|
1061
|
+
const nameAlt = allNames.join("|");
|
|
1062
|
+
const jsxTagRe = new RegExp(`<(${nameAlt})(?=[\\s/>])`, "g");
|
|
1063
|
+
const used = /* @__PURE__ */ new Set();
|
|
1064
|
+
let m;
|
|
1065
|
+
while ((m = jsxTagRe.exec(masked)) !== null) used.add(m[1]);
|
|
1066
|
+
if (used.size === 0) return code;
|
|
1067
|
+
const alreadyInScope = _collectImportedNames(masked);
|
|
1068
|
+
for (const name of allNames) if (new RegExp(`(?:^|\\n)\\s*(?:export\\s+)?(?:function\\s+${name}\\b|const\\s+${name}\\b|let\\s+${name}\\b|var\\s+${name}\\b|class\\s+${name}\\b)`).test(code)) alreadyInScope.add(name);
|
|
1069
|
+
const bySource = /* @__PURE__ */ new Map();
|
|
1070
|
+
for (const name of used) {
|
|
1071
|
+
if (alreadyInScope.has(name)) continue;
|
|
1072
|
+
const src = nameToSource.get(name);
|
|
1073
|
+
if (!bySource.has(src)) bySource.set(src, []);
|
|
1074
|
+
bySource.get(src).push(name);
|
|
1075
|
+
}
|
|
1076
|
+
if (bySource.size === 0) return code;
|
|
1077
|
+
let result = code;
|
|
1078
|
+
let workMask = masked;
|
|
1079
|
+
const orderedSources = mappings.map((m) => m.source).filter((s, i, a) => a.indexOf(s) === i);
|
|
1080
|
+
for (const source of orderedSources) {
|
|
1081
|
+
const toInject = bySource.get(source);
|
|
1082
|
+
if (!toInject || toInject.length === 0) continue;
|
|
1083
|
+
toInject.sort();
|
|
1084
|
+
const existing = new RegExp(`import\\s*\\{([^}]*)\\}\\s*from\\s*['"]${escapeRegex(source)}['"]`).exec(workMask);
|
|
1085
|
+
if (existing) {
|
|
1086
|
+
const realMatch = result.slice(existing.index, existing.index + existing[0].length);
|
|
1087
|
+
const existingSpecifiers = (/\{([^}]*)\}/.exec(realMatch)?.[1] ?? "").split(",").map((s) => s.trim()).filter(Boolean);
|
|
1088
|
+
const existingLocalNames = new Set(existingSpecifiers.map((s) => {
|
|
1089
|
+
const asIdx = s.indexOf(" as ");
|
|
1090
|
+
return asIdx >= 0 ? s.slice(asIdx + 4).trim() : s;
|
|
1091
|
+
}));
|
|
1092
|
+
const merged = [...existingSpecifiers];
|
|
1093
|
+
for (const n of toInject) if (!existingLocalNames.has(n)) merged.push(n);
|
|
1094
|
+
merged.sort();
|
|
1095
|
+
const newImport = `import { ${merged.join(", ")} } from '${source}'`;
|
|
1096
|
+
const before = result.slice(0, existing.index);
|
|
1097
|
+
const after = result.slice(existing.index + existing[0].length);
|
|
1098
|
+
result = before + newImport + after;
|
|
1099
|
+
const beforeM = workMask.slice(0, existing.index);
|
|
1100
|
+
const afterM = workMask.slice(existing.index + existing[0].length);
|
|
1101
|
+
workMask = beforeM + " ".repeat(newImport.length) + afterM;
|
|
1102
|
+
} else {
|
|
1103
|
+
const importLine = `import { ${toInject.join(", ")} } from '${source}'\n`;
|
|
1104
|
+
result = importLine + result;
|
|
1105
|
+
workMask = " ".repeat(importLine.length) + workMask;
|
|
1106
|
+
}
|
|
1107
|
+
}
|
|
1108
|
+
return result;
|
|
1109
|
+
}
|
|
1110
|
+
/**
|
|
1111
|
+
* Replace JS comments with spaces while preserving line/column
|
|
1112
|
+
* positions. Used by the auto-import scanner so `<Stack>` text inside
|
|
1113
|
+
* JSDoc doesn't false-positive as a JSX usage. Position preservation
|
|
1114
|
+
* lets the caller use the masked code for regex SEARCH and the
|
|
1115
|
+
* original code for SPLICE.
|
|
1116
|
+
*
|
|
1117
|
+
* String literals are deliberately LEFT VISIBLE — they often carry
|
|
1118
|
+
* the package name we need to match (`from '@pyreon/primitives'`).
|
|
1119
|
+
* The trade-off: a literal `'<Stack/>'` inside a string would
|
|
1120
|
+
* false-positive, but that's vanishingly rare compared to JSDoc
|
|
1121
|
+
* examples + the cost of either making string-aware AST parsing OR
|
|
1122
|
+
* masking only the LITERAL TEXT (not the quotes) is not worth it
|
|
1123
|
+
* for the marginal correctness gain.
|
|
1124
|
+
*
|
|
1125
|
+
* Handles:
|
|
1126
|
+
* - line comments `// ... newline`
|
|
1127
|
+
* - block comments `/* ... */`
|
|
1128
|
+
*/
|
|
1129
|
+
function _maskCommentsAndStrings(code) {
|
|
1130
|
+
const out = new Array(code.length);
|
|
1131
|
+
let i = 0;
|
|
1132
|
+
const n = code.length;
|
|
1133
|
+
while (i < n) {
|
|
1134
|
+
const c = code[i] ?? "";
|
|
1135
|
+
const c2 = code[i + 1] ?? "";
|
|
1136
|
+
if (c === "/" && c2 === "*") {
|
|
1137
|
+
const end = code.indexOf("*/", i + 2);
|
|
1138
|
+
const stop = end < 0 ? n : end + 2;
|
|
1139
|
+
for (let j = i; j < stop; j++) out[j] = code[j] === "\n" ? "\n" : " ";
|
|
1140
|
+
i = stop;
|
|
1141
|
+
continue;
|
|
1142
|
+
}
|
|
1143
|
+
if (c === "/" && c2 === "/") {
|
|
1144
|
+
let j = i;
|
|
1145
|
+
while (j < n && code[j] !== "\n") {
|
|
1146
|
+
out[j] = " ";
|
|
1147
|
+
j++;
|
|
1148
|
+
}
|
|
1149
|
+
i = j;
|
|
1150
|
+
continue;
|
|
1151
|
+
}
|
|
1152
|
+
out[i] = c;
|
|
1153
|
+
i++;
|
|
1154
|
+
}
|
|
1155
|
+
return out.join("");
|
|
1156
|
+
}
|
|
1157
|
+
/** Collect every name imported via `import { ... }` / `import X` / `import * as X`. */
|
|
1158
|
+
function _collectImportedNames(code) {
|
|
1159
|
+
const out = /* @__PURE__ */ new Set();
|
|
1160
|
+
const namedRe = /import\s*(?:type\s+)?\{([^}]+)\}\s*from\s*['"][^'"]+['"]/g;
|
|
1161
|
+
let m;
|
|
1162
|
+
while ((m = namedRe.exec(code)) !== null) for (const spec of m[1].split(",")) {
|
|
1163
|
+
const trimmed = spec.trim();
|
|
1164
|
+
if (!trimmed) continue;
|
|
1165
|
+
const asIdx = trimmed.indexOf(" as ");
|
|
1166
|
+
out.add(asIdx >= 0 ? trimmed.slice(asIdx + 4).trim() : trimmed);
|
|
1167
|
+
}
|
|
1168
|
+
const defaultRe = /import\s+(\w+)(?:\s*,\s*\{[^}]*\})?\s+from\s*['"][^'"]+['"]/g;
|
|
1169
|
+
while ((m = defaultRe.exec(code)) !== null) out.add(m[1]);
|
|
1170
|
+
const nsRe = /import\s+\*\s+as\s+(\w+)\s+from\s*['"][^'"]+['"]/g;
|
|
1171
|
+
while ((m = nsRe.exec(code)) !== null) out.add(m[1]);
|
|
1172
|
+
return out;
|
|
1173
|
+
}
|
|
1174
|
+
/** Escape a string for safe use inside a RegExp. */
|
|
1175
|
+
function escapeRegex(s) {
|
|
1176
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1177
|
+
}
|
|
995
1178
|
function getExt(id) {
|
|
996
1179
|
const clean = id.split("?")[0] ?? id;
|
|
997
1180
|
const dot = clean.lastIndexOf(".");
|
|
@@ -1068,15 +1251,30 @@ function scanIslandDeclarations(code, filePath, registry) {
|
|
|
1068
1251
|
if (!nameMatch) continue;
|
|
1069
1252
|
const hydrateMatch = /(?:^|[\s,{])hydrate\s*:\s*['"]([^'"]+)['"]/.exec(optsBlock);
|
|
1070
1253
|
const hydrate = hydrateMatch ? hydrateMatch[1] : "load";
|
|
1071
|
-
const loaderAbsPath = importPath.startsWith(".") ? resolveRelative(filePath, importPath) : importPath;
|
|
1254
|
+
const loaderAbsPath = normalizeModuleId(importPath.startsWith(".") ? resolveRelative(filePath, importPath) : importPath);
|
|
1072
1255
|
decls.push({
|
|
1073
1256
|
name: nameMatch[1],
|
|
1074
1257
|
hydrate,
|
|
1075
1258
|
loaderAbsPath
|
|
1076
1259
|
});
|
|
1077
1260
|
}
|
|
1078
|
-
|
|
1079
|
-
|
|
1261
|
+
const key = normalizeModuleId(filePath);
|
|
1262
|
+
const changed = !islandDeclsEqual(registry.get(key), decls.length > 0 ? decls : void 0);
|
|
1263
|
+
if (decls.length > 0) registry.set(key, decls);
|
|
1264
|
+
else registry.delete(key);
|
|
1265
|
+
return changed;
|
|
1266
|
+
}
|
|
1267
|
+
/** PR-S12: structural equality check for IslandDecl arrays. */
|
|
1268
|
+
function islandDeclsEqual(a, b) {
|
|
1269
|
+
if (a === b) return true;
|
|
1270
|
+
if (!a || !b) return false;
|
|
1271
|
+
if (a.length !== b.length) return false;
|
|
1272
|
+
for (let i = 0; i < a.length; i++) {
|
|
1273
|
+
const ai = a[i];
|
|
1274
|
+
const bi = b[i];
|
|
1275
|
+
if (ai.name !== bi.name || ai.hydrate !== bi.hydrate || ai.loaderAbsPath !== bi.loaderAbsPath) return false;
|
|
1276
|
+
}
|
|
1277
|
+
return true;
|
|
1080
1278
|
}
|
|
1081
1279
|
/**
|
|
1082
1280
|
* Resolve a dynamic-import specifier to an absolute path, mirroring how Node
|
|
@@ -1299,5 +1497,5 @@ export function __hmr_dispose(moduleId) {
|
|
|
1299
1497
|
`;
|
|
1300
1498
|
|
|
1301
1499
|
//#endregion
|
|
1302
|
-
export { _computeLineStarts, _isTruthyEnv, _maskStringsAndComments, _offsetToLineCol, buildLpihClientScript, pyreonPlugin as default, registerLpihMiddleware, resolveLpihCachePath, writeLpihCacheFile };
|
|
1500
|
+
export { _collectImportedNames, _computeLineStarts, _extractBalancedArgs, _getCompatTarget, _handleSsrRequest, _isPyreonWorkspaceFile, _isTruthyEnv, _maskCommentsAndStrings, _maskStringsAndComments, _offsetToLineCol, _skipStringLiteral, buildLpihClientScript, pyreonPlugin as default, registerLpihMiddleware, resolveLpihCachePath, writeLpihCacheFile };
|
|
1303
1501
|
//# sourceMappingURL=index.js.map
|