spark-html-bun 0.1.3 → 0.1.4
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/package.json +3 -3
- package/src/index.js +37 -12
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spark-html-bun",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "Dev server, build, and preview for spark-html apps — built entirely on Bun. Scoped component HMR over a plain WebSocket, import-map dev serving (no bundling in dev), Bun.build for the app shell, and an explicit post-build pipeline (prerender, image, font, manifest, offline, sri). Zero dependencies.",
|
|
5
|
-
"homepage": "https://wilkinnovo.github.io/spark",
|
|
5
|
+
"homepage": "https://wilkinnovo.github.io/spark-html",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "./src/index.js",
|
|
8
8
|
"types": "./src/index.d.ts",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
},
|
|
25
25
|
"repository": {
|
|
26
26
|
"type": "git",
|
|
27
|
-
"url": "git+https://github.com/wilkinnovo/spark.git"
|
|
27
|
+
"url": "git+https://github.com/wilkinnovo/spark-html.git"
|
|
28
28
|
},
|
|
29
29
|
"keywords": [
|
|
30
30
|
"bun",
|
package/src/index.js
CHANGED
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
* devRoutes?({ config }) → { '/path': { type, body() } }, // dev serving
|
|
47
47
|
* transformHtml?(html, { dev }) } // dev page injection
|
|
48
48
|
*/
|
|
49
|
-
import { join, resolve, extname, basename, sep } from 'node:path';
|
|
49
|
+
import { join, resolve, dirname, extname, basename, sep } from 'node:path';
|
|
50
50
|
import { existsSync, watch, readdirSync, statSync, readFileSync } from 'node:fs';
|
|
51
51
|
import { rm, mkdir, cp, readFile } from 'node:fs/promises';
|
|
52
52
|
|
|
@@ -200,16 +200,34 @@ function connect() {
|
|
|
200
200
|
connect();
|
|
201
201
|
`;
|
|
202
202
|
|
|
203
|
+
// Resolve a bare package to the { dir, entry } of its module entry file, so we
|
|
204
|
+
// can serve the entry AND its sibling files under one /@modules/<pkg>/ prefix.
|
|
205
|
+
// Cached — the resolution doesn't change while the server is up.
|
|
206
|
+
const moduleInfoCache = new Map();
|
|
207
|
+
function moduleEntry(pkg, projectRoot) {
|
|
208
|
+
const key = projectRoot + '\0' + pkg;
|
|
209
|
+
if (moduleInfoCache.has(key)) return moduleInfoCache.get(key);
|
|
210
|
+
let info = null;
|
|
211
|
+
try {
|
|
212
|
+
const file = Bun.resolveSync(pkg, projectRoot);
|
|
213
|
+
info = { dir: dirname(file), entry: file.slice(file.lastIndexOf('/') + 1) };
|
|
214
|
+
} catch { /* unresolvable — leave null */ }
|
|
215
|
+
moduleInfoCache.set(key, info);
|
|
216
|
+
return info;
|
|
217
|
+
}
|
|
218
|
+
|
|
203
219
|
// Import map for the app's bare specifiers: every dependency in package.json
|
|
204
|
-
// maps to /@modules/<name
|
|
205
|
-
//
|
|
206
|
-
//
|
|
220
|
+
// maps to /@modules/<name>/<entry-file>. The trailing entry filename matters —
|
|
221
|
+
// a package's own relative imports (e.g. spark-html-theme's `./init.js`) resolve
|
|
222
|
+
// against that URL, so they land at /@modules/<name>/init.js and stay inside the
|
|
223
|
+
// package instead of collapsing to /@modules/init.js (a 404 that blanks the app).
|
|
207
224
|
function buildImportMap(projectRoot) {
|
|
208
225
|
const imports = {};
|
|
209
226
|
try {
|
|
210
227
|
const pkg = JSON.parse(readFileSync(join(projectRoot, 'package.json'), 'utf8'));
|
|
211
228
|
for (const dep of Object.keys({ ...pkg.dependencies, ...pkg.devDependencies })) {
|
|
212
|
-
|
|
229
|
+
const info = moduleEntry(dep, projectRoot);
|
|
230
|
+
if (info) imports[dep] = `/@modules/${dep}/${info.entry}`;
|
|
213
231
|
}
|
|
214
232
|
} catch { /* no package.json — no bare imports to map */ }
|
|
215
233
|
return imports;
|
|
@@ -285,15 +303,22 @@ export async function dev(overrides = {}) {
|
|
|
285
303
|
return new Response(await route.body(), { headers: { 'Content-Type': route.type } });
|
|
286
304
|
}
|
|
287
305
|
|
|
288
|
-
// Bare-specifier modules: /@modules/<name> →
|
|
306
|
+
// Bare-specifier modules: /@modules/<name>/<file> → the package's entry
|
|
307
|
+
// (or a sibling file it imports relatively), served from the entry's dir.
|
|
289
308
|
if (path.startsWith('/@modules/')) {
|
|
290
|
-
const
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
309
|
+
const rest = path.slice('/@modules/'.length);
|
|
310
|
+
const slash = rest.indexOf('/');
|
|
311
|
+
const pkg = slash === -1 ? rest : rest.slice(0, slash);
|
|
312
|
+
const subpath = slash === -1 ? '' : rest.slice(slash + 1);
|
|
313
|
+
const info = moduleEntry(pkg, projectRoot);
|
|
314
|
+
if (info) {
|
|
315
|
+
const file = resolve(info.dir, subpath || info.entry);
|
|
316
|
+
// Guard against escaping the package dir via a crafted subpath.
|
|
317
|
+
if (file.startsWith(info.dir + sep) && isFile(file)) {
|
|
318
|
+
return new Response(Bun.file(file), { headers: { 'Content-Type': 'text/javascript' } });
|
|
319
|
+
}
|
|
296
320
|
}
|
|
321
|
+
return new Response(`/* cannot resolve "${rest}" */`, { status: 404, headers: { 'Content-Type': 'text/javascript' } });
|
|
297
322
|
}
|
|
298
323
|
|
|
299
324
|
// Static lookup: project root first (index.html, src/…), then publicDir.
|