sdocs 0.0.10 → 0.0.12

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/app-gen.js CHANGED
@@ -1,13 +1,28 @@
1
- import { mkdir, writeFile, rm, readFile, copyFile } from 'node:fs/promises';
2
- import { dirname, resolve } from 'node:path';
1
+ import { mkdir, writeFile, rm, readFile, copyFile, readdir } from 'node:fs/promises';
2
+ import { dirname, resolve, join } from 'node:path';
3
3
  import { fileURLToPath } from 'node:url';
4
4
  import { discoverDocFiles, getSdocKind } from './server/discovery.js';
5
5
  import { extractSnippets, hasDefaultSnippet } from './server/snippet-extractor.js';
6
6
  import { base64urlEncode } from './server/snippet-compiler.js';
7
7
  const __dirname = dirname(fileURLToPath(import.meta.url));
8
- /** Absolute path to the client App.svelte in the installed package */
9
- function getAppComponentPath() {
10
- return resolve(__dirname, 'client', 'App.svelte');
8
+ /** Source client directory in the installed package */
9
+ function getClientSourceDir() {
10
+ return resolve(__dirname, 'client');
11
+ }
12
+ /** Copy a directory recursively */
13
+ async function copyDir(src, dest) {
14
+ await mkdir(dest, { recursive: true });
15
+ const entries = await readdir(src, { withFileTypes: true });
16
+ for (const entry of entries) {
17
+ const srcPath = join(src, entry.name);
18
+ const destPath = join(dest, entry.name);
19
+ if (entry.isDirectory()) {
20
+ await copyDir(srcPath, destPath);
21
+ }
22
+ else {
23
+ await copyFile(srcPath, destPath);
24
+ }
25
+ }
11
26
  }
12
27
  /** Generate the main index.html */
13
28
  function generateIndexHtml(title) {
@@ -27,10 +42,9 @@ function generateIndexHtml(title) {
27
42
  }
28
43
  /** Generate the entry.js that mounts the App */
29
44
  function generateEntryJs(config) {
30
- const appPath = getAppComponentPath().replace(/\\/g, '/');
31
45
  return `import { mount } from 'svelte';
32
46
  import { docs, cssNames } from 'virtual:sdocs';
33
- import App from '${appPath}';
47
+ import App from './client/App.svelte';
34
48
 
35
49
  mount(App, {
36
50
  target: document.getElementById('app'),
@@ -44,15 +58,16 @@ mount(App, {
44
58
  }
45
59
  /** Generate a preview HTML page for an iframe snippet */
46
60
  function generatePreviewHtml(iframeVirtualId, css) {
61
+ const normHref = (href) => href.startsWith('./') ? href.slice(1) : href.startsWith('/') || href.startsWith('http') ? href : '/' + href;
47
62
  let cssLinks = '';
48
63
  if (css) {
49
64
  if (typeof css === 'string') {
50
- cssLinks = `<link rel="stylesheet" href="${css}">`;
65
+ cssLinks = `<link rel="stylesheet" href="${normHref(css)}">`;
51
66
  }
52
67
  else {
53
68
  const names = Object.keys(css);
54
69
  cssLinks = names
55
- .map((name, i) => `<link rel="stylesheet" href="${css[name]}" data-sdocs-stylesheet="${name}"${i > 0 ? ' disabled' : ''}>`)
70
+ .map((name, i) => `<link rel="stylesheet" href="${normHref(css[name])}" data-sdocs-stylesheet="${name}"${i > 0 ? ' disabled' : ''}>`)
56
71
  .join('\n\t');
57
72
  }
58
73
  }
@@ -87,11 +102,6 @@ function generatePreviewHtml(iframeVirtualId, css) {
87
102
  </body>
88
103
  </html>`;
89
104
  }
90
- /** Copy the favicon.png into the .sdocs/ directory */
91
- async function copyFavicon(sdocsDir) {
92
- const src = resolve(__dirname, 'client', 'favicon.png');
93
- await copyFile(src, resolve(sdocsDir, 'favicon.png'));
94
- }
95
105
  /** Discover doc files and extract snippet names (lightweight, no highlighting) */
96
106
  async function discoverSnippets(config, cwd) {
97
107
  const files = await discoverDocFiles(config.include, cwd);
@@ -117,18 +127,20 @@ async function discoverSnippets(config, cwd) {
117
127
  export async function generateDevFiles(config, cwd) {
118
128
  const sdocsDir = resolve(cwd, '.sdocs');
119
129
  await mkdir(sdocsDir, { recursive: true });
130
+ // Copy client components into .sdocs/client/ so they're compiled outside node_modules
131
+ await copyDir(getClientSourceDir(), resolve(sdocsDir, 'client'));
120
132
  await writeFile(resolve(sdocsDir, 'index.html'), generateIndexHtml(config.logo));
121
133
  await writeFile(resolve(sdocsDir, 'entry.js'), generateEntryJs(config));
122
- await copyFavicon(sdocsDir);
123
134
  return sdocsDir;
124
135
  }
125
136
  /** Generate .sdocs/ directory with entry + preview HTML files for build mode */
126
137
  export async function generateBuildFiles(config, cwd) {
127
138
  const sdocsDir = resolve(cwd, '.sdocs');
128
139
  await mkdir(sdocsDir, { recursive: true });
140
+ // Copy client components into .sdocs/client/
141
+ await copyDir(getClientSourceDir(), resolve(sdocsDir, 'client'));
129
142
  await writeFile(resolve(sdocsDir, 'index.html'), generateIndexHtml(config.logo));
130
143
  await writeFile(resolve(sdocsDir, 'entry.js'), generateEntryJs(config));
131
- await copyFavicon(sdocsDir);
132
144
  const inputs = {
133
145
  main: resolve(sdocsDir, 'index.html'),
134
146
  };
@@ -19,9 +19,7 @@ export async function buildCommand() {
19
19
  configFile: false,
20
20
  root: sdocsDir,
21
21
  plugins: [
22
- svelte({
23
- prebundleSvelteLibraries: false,
24
- }),
22
+ svelte(),
25
23
  sdocsPlugin({ ...config, include: absoluteIncludes, _buildMode: true }),
26
24
  ],
27
25
  build: {
@@ -31,9 +29,6 @@ export async function buildCommand() {
31
29
  input: inputs,
32
30
  },
33
31
  },
34
- optimizeDeps: {
35
- exclude: ['sdocs'],
36
- },
37
32
  });
38
33
  console.log(`[sdocs] Build complete → dist/`);
39
34
  }
@@ -16,9 +16,7 @@ export async function devCommand() {
16
16
  configFile: false,
17
17
  root: sdocsDir,
18
18
  plugins: [
19
- svelte({
20
- prebundleSvelteLibraries: false,
21
- }),
19
+ svelte(),
22
20
  sdocsPlugin({ ...config, include: absoluteIncludes }),
23
21
  ],
24
22
  server: {
@@ -28,9 +26,6 @@ export async function devCommand() {
28
26
  allow: [cwd],
29
27
  },
30
28
  },
31
- optimizeDeps: {
32
- exclude: ['sdocs'],
33
- },
34
29
  });
35
30
  await server.listen();
36
31
  server.printUrls();
@@ -63,17 +63,25 @@ export function generateIframeComponent(absoluteImports, snippetBody) {
63
63
  ${snippetBody}
64
64
  </div>`;
65
65
  }
66
+ /** Normalize a CSS path to root-relative so it works inside deeply nested virtual URLs */
67
+ function normalizeCssHref(href) {
68
+ if (href.startsWith('./'))
69
+ return href.slice(1);
70
+ if (href.startsWith('/') || href.startsWith('http'))
71
+ return href;
72
+ return '/' + href;
73
+ }
66
74
  /** Generate CSS link tags for the preview HTML */
67
75
  function generateCssLinks(css) {
68
76
  if (!css)
69
77
  return '';
70
78
  if (typeof css === 'string') {
71
- return `<link rel="stylesheet" href="${css}">`;
79
+ return `<link rel="stylesheet" href="${normalizeCssHref(css)}">`;
72
80
  }
73
81
  // Named stylesheets: first one active, rest disabled
74
82
  const names = Object.keys(css);
75
83
  return names
76
- .map((name, i) => `<link rel="stylesheet" href="${css[name]}" data-sdocs-stylesheet="${name}"${i > 0 ? ' disabled' : ''}>`)
84
+ .map((name, i) => `<link rel="stylesheet" href="${normalizeCssHref(css[name])}" data-sdocs-stylesheet="${name}"${i > 0 ? ' disabled' : ''}>`)
77
85
  .join('\n\t');
78
86
  }
79
87
  /** Generate the HTML page served inside the iframe */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sdocs",
3
- "version": "0.0.10",
3
+ "version": "0.0.12",
4
4
  "description": "A lightweight documentation tool for Svelte 5 components",
5
5
  "type": "module",
6
6
  "license": "MIT",