sdocs 0.0.26 → 0.0.29
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/CHANGELOG.md +32 -0
- package/dist/commands/build.js +6 -2
- package/dist/commands/dev.d.ts +8 -0
- package/dist/commands/dev.js +41 -5
- package/dist/server/app-gen.d.ts +4 -4
- package/dist/server/app-gen.js +42 -13
- package/dist/server/cli.js +4 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,38 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.0.29] - 2026-07-03
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- `sdocs dev`/`run` no longer floods the console with unresolved-import
|
|
15
|
+
errors on Vite 8 (its rolldown-based dependency scanner can't walk `.svelte`
|
|
16
|
+
entry graphs). The initial scan is skipped — dependencies are still
|
|
17
|
+
optimized on demand — and `svelte` is pre-bundled up front.
|
|
18
|
+
|
|
19
|
+
## [0.0.28] - 2026-07-03
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- **`sdocs dev`/`run`/`build` no longer write a `.sdocs/` directory into the
|
|
24
|
+
project.** The generated app is staged in a unique directory under
|
|
25
|
+
`node_modules/.cache/` (imports resolve exactly as before) and removed on
|
|
26
|
+
exit. This also fixes `sdocs build` breaking a concurrently running dev
|
|
27
|
+
server — they previously shared the same staging directory.
|
|
28
|
+
|
|
29
|
+
## [0.0.27] - 2026-07-03
|
|
30
|
+
|
|
31
|
+
### Added
|
|
32
|
+
|
|
33
|
+
- **`sdocs run`** — same as `dev`, built for `npx sdocs run`: works with no
|
|
34
|
+
local install. The dev server allows sdocs' own files from the npx cache,
|
|
35
|
+
and when the project has its own `svelte`, previews dedupe onto it, so
|
|
36
|
+
components and their dependencies always resolve from the project.
|
|
37
|
+
|
|
38
|
+
### Changed
|
|
39
|
+
|
|
40
|
+
- `sdocs build` applies the same svelte dedupe as the dev server.
|
|
41
|
+
|
|
10
42
|
## [0.0.26] - 2026-07-03
|
|
11
43
|
|
|
12
44
|
### Fixed
|
package/dist/commands/build.js
CHANGED
|
@@ -4,11 +4,12 @@ import { svelte } from '@sveltejs/vite-plugin-svelte';
|
|
|
4
4
|
import { loadConfig } from '../server/config.js';
|
|
5
5
|
import { sdocsPlugin } from '../vite.js';
|
|
6
6
|
import { generateBuildFiles, cleanBuildFiles } from '../server/app-gen.js';
|
|
7
|
+
import { svelteDedupe } from './dev.js';
|
|
7
8
|
export async function buildCommand() {
|
|
8
9
|
const cwd = process.cwd();
|
|
9
10
|
const config = await loadConfig(cwd);
|
|
10
11
|
console.log('[sdocs] Building static site...');
|
|
11
|
-
// Generate
|
|
12
|
+
// Generate the staging directory (in the OS temp dir) with entry + preview HTML files
|
|
12
13
|
const { sdocsDir, inputs } = await generateBuildFiles(config, cwd);
|
|
13
14
|
const inputCount = Object.keys(inputs).length;
|
|
14
15
|
console.log(`[sdocs] Generated ${inputCount} page(s) (1 main + ${inputCount - 1} previews)`);
|
|
@@ -18,6 +19,9 @@ export async function buildCommand() {
|
|
|
18
19
|
await build({
|
|
19
20
|
configFile: false,
|
|
20
21
|
root: sdocsDir,
|
|
22
|
+
resolve: {
|
|
23
|
+
dedupe: svelteDedupe(cwd),
|
|
24
|
+
},
|
|
21
25
|
plugins: [
|
|
22
26
|
svelte(),
|
|
23
27
|
sdocsPlugin({ ...config, include: absoluteIncludes, _buildMode: true }),
|
|
@@ -33,6 +37,6 @@ export async function buildCommand() {
|
|
|
33
37
|
console.log(`[sdocs] Build complete → dist/`);
|
|
34
38
|
}
|
|
35
39
|
finally {
|
|
36
|
-
await cleanBuildFiles(
|
|
40
|
+
await cleanBuildFiles(sdocsDir);
|
|
37
41
|
}
|
|
38
42
|
}
|
package/dist/commands/dev.d.ts
CHANGED
|
@@ -1 +1,9 @@
|
|
|
1
|
+
/** sdocs' own install location — under npx this is the npx cache, not the project */
|
|
2
|
+
export declare function sdocsPackageRoot(): string;
|
|
3
|
+
/**
|
|
4
|
+
* Prefer the project's own svelte over the copy next to sdocs when both exist
|
|
5
|
+
* (e.g. running via npx): previews import the project's components, and two
|
|
6
|
+
* svelte runtimes in one page don't mix.
|
|
7
|
+
*/
|
|
8
|
+
export declare function svelteDedupe(cwd: string): string[];
|
|
1
9
|
export declare function devCommand(): Promise<void>;
|
package/dist/commands/dev.js
CHANGED
|
@@ -1,20 +1,53 @@
|
|
|
1
|
-
import { resolve } from 'node:path';
|
|
1
|
+
import { dirname, resolve } from 'node:path';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
import { createRequire } from 'node:module';
|
|
2
4
|
import { createServer } from 'vite';
|
|
3
5
|
import { svelte } from '@sveltejs/vite-plugin-svelte';
|
|
4
6
|
import { loadConfig } from '../server/config.js';
|
|
5
7
|
import { sdocsPlugin } from '../vite.js';
|
|
6
8
|
import { generateDevFiles, cleanBuildFiles } from '../server/app-gen.js';
|
|
9
|
+
const require = createRequire(import.meta.url);
|
|
10
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
11
|
+
/** sdocs' own install location — under npx this is the npx cache, not the project */
|
|
12
|
+
export function sdocsPackageRoot() {
|
|
13
|
+
return resolve(__dirname, '../..');
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Prefer the project's own svelte over the copy next to sdocs when both exist
|
|
17
|
+
* (e.g. running via npx): previews import the project's components, and two
|
|
18
|
+
* svelte runtimes in one page don't mix.
|
|
19
|
+
*/
|
|
20
|
+
export function svelteDedupe(cwd) {
|
|
21
|
+
try {
|
|
22
|
+
require.resolve('svelte/package.json', { paths: [cwd] });
|
|
23
|
+
return ['svelte'];
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return [];
|
|
27
|
+
}
|
|
28
|
+
}
|
|
7
29
|
export async function devCommand() {
|
|
8
30
|
const cwd = process.cwd();
|
|
9
31
|
const config = await loadConfig(cwd);
|
|
10
32
|
console.log('[sdocs] Starting dev server...');
|
|
11
|
-
// Generate
|
|
33
|
+
// Generate the staging directory (in the OS temp dir) with entry files
|
|
12
34
|
const sdocsDir = await generateDevFiles(config, cwd);
|
|
13
|
-
// Resolve include patterns to absolute paths (relative to cwd, not
|
|
35
|
+
// Resolve include patterns to absolute paths (relative to cwd, not the staging dir)
|
|
14
36
|
const absoluteIncludes = config.include.map((p) => resolve(cwd, p));
|
|
15
37
|
const server = await createServer({
|
|
16
38
|
configFile: false,
|
|
17
39
|
root: sdocsDir,
|
|
40
|
+
resolve: {
|
|
41
|
+
dedupe: svelteDedupe(cwd),
|
|
42
|
+
},
|
|
43
|
+
optimizeDeps: {
|
|
44
|
+
// Rolldown-based Vite (8+) can't scan .svelte entry graphs and floods
|
|
45
|
+
// the console with unresolved-import errors. Skip the initial scan —
|
|
46
|
+
// runtime discovery still optimizes dependencies on demand — and
|
|
47
|
+
// pre-bundle the one dependency the client app always needs.
|
|
48
|
+
entries: [],
|
|
49
|
+
include: ['svelte'],
|
|
50
|
+
},
|
|
18
51
|
plugins: [
|
|
19
52
|
svelte(),
|
|
20
53
|
sdocsPlugin({ ...config, include: absoluteIncludes }),
|
|
@@ -23,7 +56,10 @@ export async function devCommand() {
|
|
|
23
56
|
port: config.port,
|
|
24
57
|
open: config.open,
|
|
25
58
|
fs: {
|
|
26
|
-
allow
|
|
59
|
+
// The staging dir (an explicit allow list replaces Vite's implicit
|
|
60
|
+
// root allowance), the project, and sdocs' own dependency tree
|
|
61
|
+
// (the npx cache when running without a local install).
|
|
62
|
+
allow: [sdocsDir, cwd, resolve(sdocsPackageRoot(), '..')],
|
|
27
63
|
},
|
|
28
64
|
},
|
|
29
65
|
});
|
|
@@ -32,7 +68,7 @@ export async function devCommand() {
|
|
|
32
68
|
// Cleanup on exit
|
|
33
69
|
const cleanup = async () => {
|
|
34
70
|
await server.close();
|
|
35
|
-
await cleanBuildFiles(
|
|
71
|
+
await cleanBuildFiles(sdocsDir);
|
|
36
72
|
process.exit(0);
|
|
37
73
|
};
|
|
38
74
|
process.on('SIGINT', cleanup);
|
package/dist/server/app-gen.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { ResolvedSdocsConfig } from '../types.js';
|
|
2
|
-
/** Generate
|
|
2
|
+
/** Generate the staging directory with entry files for dev mode */
|
|
3
3
|
export declare function generateDevFiles(config: ResolvedSdocsConfig, cwd: string): Promise<string>;
|
|
4
|
-
/** Generate
|
|
4
|
+
/** Generate the staging directory with entry + preview HTML files for build mode */
|
|
5
5
|
export declare function generateBuildFiles(config: ResolvedSdocsConfig, cwd: string): Promise<{
|
|
6
6
|
sdocsDir: string;
|
|
7
7
|
inputs: Record<string, string>;
|
|
8
8
|
}>;
|
|
9
|
-
/** Remove
|
|
10
|
-
export declare function cleanBuildFiles(
|
|
9
|
+
/** Remove a staging directory created by generateDevFiles/generateBuildFiles */
|
|
10
|
+
export declare function cleanBuildFiles(stagingDir: string): Promise<void>;
|
package/dist/server/app-gen.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { mkdir, writeFile, rm, readFile, copyFile, readdir } from 'node:fs/promises';
|
|
1
|
+
import { mkdir, mkdtemp, writeFile, rm, readFile, copyFile, readdir } from 'node:fs/promises';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import { tmpdir } from 'node:os';
|
|
2
4
|
import { dirname, resolve, join } from 'node:path';
|
|
3
5
|
import { fileURLToPath } from 'node:url';
|
|
4
6
|
import { discoverDocFiles, getSdocKind } from './discovery.js';
|
|
@@ -14,6 +16,36 @@ async function copyClientApp(sdocsDir) {
|
|
|
14
16
|
await copyDir(getClientSourceDir(), resolve(sdocsDir, 'client'));
|
|
15
17
|
await copyDir(resolve(__dirname, '../ui'), resolve(sdocsDir, 'ui'));
|
|
16
18
|
}
|
|
19
|
+
/** Nearest node_modules walking up from dir (mirrors Node's resolution) */
|
|
20
|
+
function findNearestNodeModules(dir) {
|
|
21
|
+
let current = resolve(dir);
|
|
22
|
+
for (;;) {
|
|
23
|
+
const candidate = join(current, 'node_modules');
|
|
24
|
+
if (existsSync(candidate))
|
|
25
|
+
return candidate;
|
|
26
|
+
const parent = dirname(current);
|
|
27
|
+
if (parent === current)
|
|
28
|
+
return null;
|
|
29
|
+
current = parent;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Create a unique staging directory for the generated app. It lives inside
|
|
34
|
+
* node_modules/.cache — never a tracked file in the user's project — and being
|
|
35
|
+
* physically inside node_modules keeps the full walk-up resolution chain for
|
|
36
|
+
* bare imports (svelte, ...) intact, including hoisted monorepo setups. When
|
|
37
|
+
* no node_modules exists anywhere (running via npx in a bare folder), sdocs'
|
|
38
|
+
* own tree provides one; the OS temp dir is the last resort.
|
|
39
|
+
*/
|
|
40
|
+
async function createStagingDir(cwd) {
|
|
41
|
+
const nodeModules = findNearestNodeModules(cwd) ?? findNearestNodeModules(resolve(__dirname, '..'));
|
|
42
|
+
if (nodeModules) {
|
|
43
|
+
const cacheDir = join(nodeModules, '.cache');
|
|
44
|
+
await mkdir(cacheDir, { recursive: true });
|
|
45
|
+
return mkdtemp(join(cacheDir, 'sdocs-'));
|
|
46
|
+
}
|
|
47
|
+
return mkdtemp(join(tmpdir(), 'sdocs-'));
|
|
48
|
+
}
|
|
17
49
|
/** Copy a directory recursively */
|
|
18
50
|
async function copyDir(src, dest) {
|
|
19
51
|
await mkdir(dest, { recursive: true });
|
|
@@ -129,21 +161,19 @@ async function discoverSnippets(config, cwd) {
|
|
|
129
161
|
}
|
|
130
162
|
return results;
|
|
131
163
|
}
|
|
132
|
-
/** Generate
|
|
164
|
+
/** Generate the staging directory with entry files for dev mode */
|
|
133
165
|
export async function generateDevFiles(config, cwd) {
|
|
134
|
-
const sdocsDir =
|
|
135
|
-
|
|
136
|
-
// Copy client components into .sdocs/client/ so they're compiled outside node_modules
|
|
166
|
+
const sdocsDir = await createStagingDir(cwd);
|
|
167
|
+
// Copy client components into the staging dir so they're compiled outside node_modules
|
|
137
168
|
await copyClientApp(sdocsDir);
|
|
138
169
|
await writeFile(resolve(sdocsDir, 'index.html'), generateIndexHtml(config.logo));
|
|
139
170
|
await writeFile(resolve(sdocsDir, 'entry.js'), generateEntryJs(config));
|
|
140
171
|
return sdocsDir;
|
|
141
172
|
}
|
|
142
|
-
/** Generate
|
|
173
|
+
/** Generate the staging directory with entry + preview HTML files for build mode */
|
|
143
174
|
export async function generateBuildFiles(config, cwd) {
|
|
144
|
-
const sdocsDir =
|
|
145
|
-
|
|
146
|
-
// Copy client components into .sdocs/client/
|
|
175
|
+
const sdocsDir = await createStagingDir(cwd);
|
|
176
|
+
// Copy client components into the staging dir
|
|
147
177
|
await copyClientApp(sdocsDir);
|
|
148
178
|
await writeFile(resolve(sdocsDir, 'index.html'), generateIndexHtml(config.logo));
|
|
149
179
|
await writeFile(resolve(sdocsDir, 'entry.js'), generateEntryJs(config));
|
|
@@ -166,8 +196,7 @@ export async function generateBuildFiles(config, cwd) {
|
|
|
166
196
|
}
|
|
167
197
|
return { sdocsDir, inputs };
|
|
168
198
|
}
|
|
169
|
-
/** Remove
|
|
170
|
-
export async function cleanBuildFiles(
|
|
171
|
-
|
|
172
|
-
await rm(sdocsDir, { recursive: true, force: true });
|
|
199
|
+
/** Remove a staging directory created by generateDevFiles/generateBuildFiles */
|
|
200
|
+
export async function cleanBuildFiles(stagingDir) {
|
|
201
|
+
await rm(stagingDir, { recursive: true, force: true });
|
|
173
202
|
}
|
package/dist/server/cli.js
CHANGED
|
@@ -18,7 +18,8 @@ Usage:
|
|
|
18
18
|
sdocs <command>
|
|
19
19
|
|
|
20
20
|
Commands:
|
|
21
|
-
dev Start development server with
|
|
21
|
+
dev Start development server with live reload
|
|
22
|
+
run Same as dev — works with npx and no local install
|
|
22
23
|
build Build static documentation site
|
|
23
24
|
preview Serve built site locally
|
|
24
25
|
init Scaffold sdocs.config.js
|
|
@@ -39,7 +40,8 @@ async function main() {
|
|
|
39
40
|
return;
|
|
40
41
|
}
|
|
41
42
|
switch (command) {
|
|
42
|
-
case 'dev':
|
|
43
|
+
case 'dev':
|
|
44
|
+
case 'run': {
|
|
43
45
|
const { devCommand } = await import('../commands/dev.js');
|
|
44
46
|
await devCommand();
|
|
45
47
|
break;
|