@void/solid 0.7.12 → 0.8.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.
- package/dist/plugin.d.mts +1 -1
- package/dist/plugin.mjs +78 -65
- package/package.json +3 -3
package/dist/plugin.d.mts
CHANGED
|
@@ -11,6 +11,6 @@ type VoidSolidOptions = Readonly<{
|
|
|
11
11
|
viewTransitions?: boolean;
|
|
12
12
|
prefetch?: PrefetchConfig;
|
|
13
13
|
}>;
|
|
14
|
-
declare function voidSolid(options?: VoidSolidOptions):
|
|
14
|
+
declare function voidSolid(options?: VoidSolidOptions): Array<Plugin>;
|
|
15
15
|
//#endregion
|
|
16
16
|
export { VoidSolidOptions, voidSolid };
|
package/dist/plugin.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import solid from "vite-plugin-solid";
|
|
2
|
+
import { generateComponentManifest, resolveEffectiveLayoutChain, resolvePagesDir, resolveStaticPageDataBuildOptions, scanPages } from "void/pages";
|
|
2
3
|
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
3
4
|
import { normalizePath } from "vite";
|
|
4
|
-
import { generateComponentManifest, resolveEffectiveLayoutChain, resolveStaticPageDataBuildOptions, scanPages } from "void/pages";
|
|
5
5
|
import { ISLANDS_CLIENT_ENTRY_ID, ISLANDS_RENDERER_ID, computePagesNeedingClientJS, extractCssImports, needsIslandClientBundle, resolveSpecifier, rewriteCssImportForVirtualModule, watchPagesForRescan } from "void/pages-islands-plugin";
|
|
6
6
|
//#region ../../node_modules/.pnpm/pathe@2.0.3/node_modules/pathe/dist/shared/pathe.M-eThtNZ.mjs
|
|
7
7
|
const _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//;
|
|
@@ -9,42 +9,9 @@ function normalizeWindowsPath(input = "") {
|
|
|
9
9
|
if (!input) return input;
|
|
10
10
|
return input.replace(/\\/g, "/").replace(_DRIVE_LETTER_START_RE, (r) => r.toUpperCase());
|
|
11
11
|
}
|
|
12
|
-
const _UNC_REGEX = /^[/\\]{2}/;
|
|
13
12
|
const _IS_ABSOLUTE_RE = /^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Za-z]:[/\\]/;
|
|
14
13
|
const _DRIVE_LETTER_RE = /^[A-Za-z]:$/;
|
|
15
14
|
const _ROOT_FOLDER_RE = /^\/([A-Za-z]:)?$/;
|
|
16
|
-
const normalize = function(path) {
|
|
17
|
-
if (path.length === 0) return ".";
|
|
18
|
-
path = normalizeWindowsPath(path);
|
|
19
|
-
const isUNCPath = path.match(_UNC_REGEX);
|
|
20
|
-
const isPathAbsolute = isAbsolute(path);
|
|
21
|
-
const trailingSeparator = path[path.length - 1] === "/";
|
|
22
|
-
path = normalizeString(path, !isPathAbsolute);
|
|
23
|
-
if (path.length === 0) {
|
|
24
|
-
if (isPathAbsolute) return "/";
|
|
25
|
-
return trailingSeparator ? "./" : ".";
|
|
26
|
-
}
|
|
27
|
-
if (trailingSeparator) path += "/";
|
|
28
|
-
if (_DRIVE_LETTER_RE.test(path)) path += "/";
|
|
29
|
-
if (isUNCPath) {
|
|
30
|
-
if (!isPathAbsolute) return `//./${path}`;
|
|
31
|
-
return `//${path}`;
|
|
32
|
-
}
|
|
33
|
-
return isPathAbsolute && !isAbsolute(path) ? `/${path}` : path;
|
|
34
|
-
};
|
|
35
|
-
const join = function(...segments) {
|
|
36
|
-
let path = "";
|
|
37
|
-
for (const seg of segments) {
|
|
38
|
-
if (!seg) continue;
|
|
39
|
-
if (path.length > 0) {
|
|
40
|
-
const pathTrailing = path[path.length - 1] === "/";
|
|
41
|
-
const segLeading = seg[0] === "/";
|
|
42
|
-
if (pathTrailing && segLeading) path += seg.slice(1);
|
|
43
|
-
else path += pathTrailing || segLeading ? seg : `/${seg}`;
|
|
44
|
-
} else path += seg;
|
|
45
|
-
}
|
|
46
|
-
return normalize(path);
|
|
47
|
-
};
|
|
48
15
|
function cwd() {
|
|
49
16
|
if (typeof process !== "undefined" && typeof process.cwd === "function") return process.cwd().replace(/\\/g, "/");
|
|
50
17
|
return "/";
|
|
@@ -141,6 +108,22 @@ const COMPONENT_EXTENSIONS = [
|
|
|
141
108
|
".ts",
|
|
142
109
|
".js"
|
|
143
110
|
];
|
|
111
|
+
const ISLAND_IMPORT_RE = /import\s+([$_A-Za-z][$_\w]*)\s+from\s+("[^"]+"|'[^']+')\s+with\s*\{\s*island\s*:\s*("[^"]+"|'[^']+')\s*,?\s*\}/g;
|
|
112
|
+
function findIslandImports(code) {
|
|
113
|
+
const imports = [];
|
|
114
|
+
let match;
|
|
115
|
+
ISLAND_IMPORT_RE.lastIndex = 0;
|
|
116
|
+
while ((match = ISLAND_IMPORT_RE.exec(code)) !== null) {
|
|
117
|
+
const specifierRaw = match[2];
|
|
118
|
+
imports.push({
|
|
119
|
+
statement: match[0],
|
|
120
|
+
importName: match[1],
|
|
121
|
+
specifier: specifierRaw.slice(1, -1),
|
|
122
|
+
hydrate: match[3].slice(1, -1)
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
return imports;
|
|
126
|
+
}
|
|
144
127
|
/**
|
|
145
128
|
* Prefix for virtual island wrapper modules. Must NOT use the `\0` prefix
|
|
146
129
|
* because `vite-plugin-solid` skips `\0`-prefixed modules in its transform
|
|
@@ -148,10 +131,10 @@ const COMPONENT_EXTENSIONS = [
|
|
|
148
131
|
* detect the language.
|
|
149
132
|
*/
|
|
150
133
|
const WRAPPER_PREFIX = "/@void-island-wrap/";
|
|
151
|
-
function islandsPlugin(pagesDir) {
|
|
134
|
+
function islandsPlugin(pagesDir, options) {
|
|
152
135
|
let pageScan = null;
|
|
153
136
|
let isDev = false;
|
|
154
|
-
const root = dirname(pagesDir);
|
|
137
|
+
const root = options?.root ?? dirname(pagesDir);
|
|
155
138
|
const islandManifest = /* @__PURE__ */ new Map();
|
|
156
139
|
const islandCssFiles = /* @__PURE__ */ new Set();
|
|
157
140
|
const wrapperMeta = /* @__PURE__ */ new Map();
|
|
@@ -177,8 +160,7 @@ function islandsPlugin(pagesDir) {
|
|
|
177
160
|
},
|
|
178
161
|
async buildStart() {
|
|
179
162
|
if (existsSync(pagesDir)) {
|
|
180
|
-
pageScan = await scanPages(root);
|
|
181
|
-
const importAttrRe = /import\s+\w+\s+from\s+("[^"]+"|'[^']+')\s+with\s*\{\s*island\s*:\s*("[^"]+"|'[^']+')\s*\}/g;
|
|
163
|
+
pageScan = await scanPages(root, { pagesDir });
|
|
182
164
|
const filesToScan = [
|
|
183
165
|
...pageScan.pages.map((page) => ({
|
|
184
166
|
filePath: page.componentPath,
|
|
@@ -198,11 +180,9 @@ function islandsPlugin(pagesDir) {
|
|
|
198
180
|
const filePath = resolve(pagesDir, entry.filePath);
|
|
199
181
|
const code = readFileSync(filePath, "utf-8");
|
|
200
182
|
const importerDir = dirname(filePath);
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
const spec = importMatch[1].slice(1, -1);
|
|
205
|
-
const strategy = importMatch[2].slice(1, -1);
|
|
183
|
+
for (const islandImport of findIslandImports(code)) {
|
|
184
|
+
const spec = islandImport.specifier;
|
|
185
|
+
const strategy = islandImport.hydrate;
|
|
206
186
|
const absPath = resolveSpecifier(spec, importerDir, COMPONENT_EXTENSIONS);
|
|
207
187
|
if (absPath) {
|
|
208
188
|
const islandId = normalizePath(relative(root, absPath)).replace(/\.[^.]+$/, "");
|
|
@@ -265,16 +245,12 @@ function islandsPlugin(pagesDir) {
|
|
|
265
245
|
filter: { id: /\.island\.(tsx|jsx)$/ },
|
|
266
246
|
handler(code, id) {
|
|
267
247
|
if (/import\s+\{[^}]*\buseForm\b/.test(code)) this.warn(`islands: useForm cannot be imported in island page '${id}'. Use useIslandForm instead.`);
|
|
268
|
-
const importAttrRe = /import\s+(\w+)\s+from\s+("[^"]+"|'[^']+')\s+with\s*\{\s*island\s*:\s*("[^"]+"|'[^']+')\s*\}/g;
|
|
269
248
|
const importerDir = dirname(id);
|
|
270
249
|
let transformed = code;
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
const
|
|
274
|
-
const
|
|
275
|
-
const strategyRaw = match[3];
|
|
276
|
-
const spec = specRaw.slice(1, -1);
|
|
277
|
-
const strategy = strategyRaw.slice(1, -1);
|
|
250
|
+
for (const islandImport of findIslandImports(code)) {
|
|
251
|
+
const name = islandImport.importName;
|
|
252
|
+
const spec = islandImport.specifier;
|
|
253
|
+
const strategy = islandImport.hydrate;
|
|
278
254
|
const absPath = resolveSpecifier(spec, importerDir, COMPONENT_EXTENSIONS);
|
|
279
255
|
if (absPath) {
|
|
280
256
|
const islandId = normalizePath(relative(root, absPath)).replace(/\.[^.]+$/, "");
|
|
@@ -292,7 +268,7 @@ function islandsPlugin(pagesDir) {
|
|
|
292
268
|
hydrate: strategy
|
|
293
269
|
});
|
|
294
270
|
const replacement = `import ${name} from ${JSON.stringify(wrapperUrl)}`;
|
|
295
|
-
transformed = transformed.replace(
|
|
271
|
+
transformed = transformed.replace(islandImport.statement, replacement);
|
|
296
272
|
}
|
|
297
273
|
if (transformed !== code) return {
|
|
298
274
|
code: transformed,
|
|
@@ -442,12 +418,30 @@ function hasNonIslandPages(dir) {
|
|
|
442
418
|
}
|
|
443
419
|
function pagesPlugin(pagesDir, options) {
|
|
444
420
|
let pageScan = null;
|
|
421
|
+
let isDev = false;
|
|
445
422
|
let viteConfig;
|
|
446
|
-
const root = dirname(pagesDir);
|
|
423
|
+
const root = options?.root ?? dirname(pagesDir);
|
|
424
|
+
const normalizedPagesDir = normalizePath(pagesDir);
|
|
425
|
+
let pendingRescan = null;
|
|
426
|
+
const rescanPages = async () => {
|
|
427
|
+
pageScan = existsSync(pagesDir) ? await scanPages(root, { pagesDir }) : null;
|
|
428
|
+
};
|
|
429
|
+
const runRescan = () => {
|
|
430
|
+
pendingRescan ??= rescanPages().finally(() => {
|
|
431
|
+
pendingRescan = null;
|
|
432
|
+
});
|
|
433
|
+
return pendingRescan;
|
|
434
|
+
};
|
|
435
|
+
const invalidatePageModules = (server) => {
|
|
436
|
+
for (const env of Object.values(server.environments)) for (const id of ["\0" + RENDERER_ID, "\0" + CLIENT_ENTRY_ID]) {
|
|
437
|
+
const mod = env.moduleGraph.getModuleById(id);
|
|
438
|
+
if (mod) env.moduleGraph.invalidateModule(mod);
|
|
439
|
+
}
|
|
440
|
+
};
|
|
447
441
|
return {
|
|
448
442
|
name: "void-solid:pages",
|
|
449
443
|
async buildStart() {
|
|
450
|
-
|
|
444
|
+
await runRescan();
|
|
451
445
|
},
|
|
452
446
|
resolveId: {
|
|
453
447
|
filter: { id: /^virtual:void-pages-(renderer|client)$/ },
|
|
@@ -457,7 +451,9 @@ function pagesPlugin(pagesDir, options) {
|
|
|
457
451
|
},
|
|
458
452
|
load: {
|
|
459
453
|
filter: { id: /^\0virtual:void-pages-(renderer|client)$/ },
|
|
460
|
-
handler(id) {
|
|
454
|
+
async handler(id) {
|
|
455
|
+
if (isDev && pendingRescan) await pendingRescan;
|
|
456
|
+
if (!pageScan && existsSync(pagesDir)) await runRescan();
|
|
461
457
|
if (id === "\0" + RENDERER_ID) {
|
|
462
458
|
if (!pageScan) return "export function renderPage() { throw new Error('No pages found'); }";
|
|
463
459
|
return generateRendererModule(pageScan, pagesDir);
|
|
@@ -468,19 +464,34 @@ function pagesPlugin(pagesDir, options) {
|
|
|
468
464
|
}
|
|
469
465
|
}
|
|
470
466
|
},
|
|
467
|
+
configureServer(server) {
|
|
468
|
+
const handlePagesChange = async (path, event) => {
|
|
469
|
+
const normalizedPath = normalizePath(path);
|
|
470
|
+
if (normalizedPath !== normalizedPagesDir && !normalizedPath.startsWith(normalizedPagesDir + "/")) return;
|
|
471
|
+
if (event === "change" && !normalizedPath.endsWith(".md")) return;
|
|
472
|
+
await runRescan();
|
|
473
|
+
invalidatePageModules(server);
|
|
474
|
+
};
|
|
475
|
+
server.watcher.on("add", (path) => handlePagesChange(path, "add"));
|
|
476
|
+
server.watcher.on("change", (path) => handlePagesChange(path, "change"));
|
|
477
|
+
server.watcher.on("unlink", (path) => handlePagesChange(path, "unlink"));
|
|
478
|
+
},
|
|
471
479
|
configResolved(config) {
|
|
472
480
|
viteConfig = config;
|
|
473
481
|
},
|
|
474
482
|
config(_, env) {
|
|
475
483
|
if (!existsSync(pagesDir)) return;
|
|
476
|
-
if (env.command === "serve")
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
"solid
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
+
if (env.command === "serve") {
|
|
485
|
+
isDev = true;
|
|
486
|
+
return { optimizeDeps: {
|
|
487
|
+
exclude: ["@void/solid"],
|
|
488
|
+
include: [
|
|
489
|
+
"solid-js",
|
|
490
|
+
"solid-js/web",
|
|
491
|
+
"solid-js/store"
|
|
492
|
+
]
|
|
493
|
+
} };
|
|
494
|
+
}
|
|
484
495
|
if (!hasNonIslandPages(pagesDir)) return;
|
|
485
496
|
return { build: {
|
|
486
497
|
manifest: true,
|
|
@@ -699,7 +710,8 @@ function configPlugin() {
|
|
|
699
710
|
};
|
|
700
711
|
}
|
|
701
712
|
function voidSolid(options) {
|
|
702
|
-
const
|
|
713
|
+
const root = process.cwd();
|
|
714
|
+
const pagesDir = resolvePagesDir(root);
|
|
703
715
|
return [
|
|
704
716
|
configPlugin(),
|
|
705
717
|
solid({
|
|
@@ -707,10 +719,11 @@ function voidSolid(options) {
|
|
|
707
719
|
...options?.solid
|
|
708
720
|
}),
|
|
709
721
|
pagesPlugin(pagesDir, {
|
|
722
|
+
root,
|
|
710
723
|
viewTransitions: options?.viewTransitions,
|
|
711
724
|
prefetch: options?.prefetch
|
|
712
725
|
}),
|
|
713
|
-
...islandsPlugin(pagesDir)
|
|
726
|
+
...islandsPlugin(pagesDir, { root })
|
|
714
727
|
];
|
|
715
728
|
}
|
|
716
729
|
//#endregion
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@void/solid",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/voidzero-dev/void.git",
|
|
@@ -43,12 +43,12 @@
|
|
|
43
43
|
"solid-js": "^1.9.12",
|
|
44
44
|
"vite": "npm:@voidzero-dev/vite-plus-core@0.1.20",
|
|
45
45
|
"vite-plus": "^0.1.20",
|
|
46
|
-
"void": "0.
|
|
46
|
+
"void": "0.8.0"
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
49
49
|
"solid-js": "^1.9.0",
|
|
50
50
|
"vite": "^8.0.0",
|
|
51
|
-
"void": "0.
|
|
51
|
+
"void": "0.8.0"
|
|
52
52
|
},
|
|
53
53
|
"scripts": {
|
|
54
54
|
"build": "vp pack",
|