@songmu/mdhq 0.0.3 → 0.0.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/README.md +7 -4
- package/dist/cli.js +15 -7
- package/docs/specification.md +18 -20
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -30,10 +30,13 @@ mdhq root
|
|
|
30
30
|
|
|
31
31
|
`mdhq get` accepts multiple URLs as arguments or one URL per line on standard
|
|
32
32
|
input; both sources are merged. It prints one absolute Markdown path per URL
|
|
33
|
-
to stdout by default. Warnings are written to stderr. `--json`
|
|
34
|
-
result object
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
to stdout by default. Warnings are written to stderr. `--json` writes one
|
|
34
|
+
compact JSON result object per URL as JSON Lines. Results are written as soon
|
|
35
|
+
as each URL finishes, so parallel requests can produce output in completion
|
|
36
|
+
order rather than input order. If a later request fails, results already
|
|
37
|
+
written to stdout remain available.
|
|
38
|
+
Requests are limited to eight in parallel, with requests to the same host
|
|
39
|
+
serialized and spaced one second apart; image downloads use the same limits.
|
|
37
40
|
|
|
38
41
|
`mdhq list` recursively lists `.md` files below the storage root, one per
|
|
39
42
|
line, in sorted root-relative form. Use `-p` or `--full-path` to print absolute
|
package/dist/cli.js
CHANGED
|
@@ -69,7 +69,7 @@ export function createProgram(io = process) {
|
|
|
69
69
|
.option("--update", "update an existing page")
|
|
70
70
|
.option("--user-agent <value>", "HTTP User-Agent")
|
|
71
71
|
.option("--header <header>", "additional HTTP header", collect, [])
|
|
72
|
-
.addOption(new Option("--json", "print
|
|
72
|
+
.addOption(new Option("--json", "print results as JSON Lines"))
|
|
73
73
|
.action(async (urls, options) => {
|
|
74
74
|
const inputUrls = await readStdinUrls(io.stdin);
|
|
75
75
|
const requestedUrls = [...(urls ?? []), ...inputUrls]
|
|
@@ -79,7 +79,6 @@ export function createProgram(io = process) {
|
|
|
79
79
|
throw new MdhqError("INVALID_URL", "At least one URL is required");
|
|
80
80
|
}
|
|
81
81
|
const scheduler = new RequestScheduler();
|
|
82
|
-
const results = [];
|
|
83
82
|
let nextIndex = 0;
|
|
84
83
|
const worker = async () => {
|
|
85
84
|
while (nextIndex < requestedUrls.length) {
|
|
@@ -89,7 +88,7 @@ export function createProgram(io = process) {
|
|
|
89
88
|
if (url === undefined) {
|
|
90
89
|
continue;
|
|
91
90
|
}
|
|
92
|
-
|
|
91
|
+
const result = await getPage({
|
|
93
92
|
url,
|
|
94
93
|
...(options.root ? { root: options.root } : {}),
|
|
95
94
|
...(options.assets === false ? { assets: false } : {}),
|
|
@@ -99,12 +98,21 @@ export function createProgram(io = process) {
|
|
|
99
98
|
scheduler,
|
|
100
99
|
onWarning: (warning) => io.stderr.write(`warning: ${warning.message}\n`)
|
|
101
100
|
});
|
|
101
|
+
io.stdout.write(`${options.json ? JSON.stringify(result) : result.path}\n`);
|
|
102
102
|
}
|
|
103
103
|
};
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
104
|
+
const failures = [];
|
|
105
|
+
await Promise.all(Array.from({ length: Math.min(8, requestedUrls.length) }, async () => {
|
|
106
|
+
try {
|
|
107
|
+
await worker();
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
failures.push(error);
|
|
111
|
+
}
|
|
112
|
+
}));
|
|
113
|
+
if (failures.length > 0) {
|
|
114
|
+
throw failures[0];
|
|
115
|
+
}
|
|
108
116
|
});
|
|
109
117
|
program
|
|
110
118
|
.command("list")
|
package/docs/specification.md
CHANGED
|
@@ -21,13 +21,13 @@ Runtime requirements:
|
|
|
21
21
|
The executable provides three subcommands:
|
|
22
22
|
|
|
23
23
|
```text
|
|
24
|
-
mdhq get [options]
|
|
24
|
+
mdhq get [options] [urls...]
|
|
25
25
|
mdhq list [options]
|
|
26
26
|
mdhq root [options]
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
-
`mdhq get` accepts
|
|
30
|
-
|
|
29
|
+
`mdhq get` accepts multiple URL arguments and one URL per line from standard
|
|
30
|
+
input. Both sources are merged, and up to eight URLs are processed in parallel.
|
|
31
31
|
|
|
32
32
|
### `get` options
|
|
33
33
|
|
|
@@ -37,22 +37,19 @@ processing is delegated to external tools such as `xargs`.
|
|
|
37
37
|
| `--update` | Fetch and replace an existing document with the same URL identity. |
|
|
38
38
|
| `--user-agent <value>` | Override the default HTTP User-Agent. |
|
|
39
39
|
| `--header <header>` | Add an HTTP header. The option is repeatable and uses `Name: value` syntax. |
|
|
40
|
-
| `--json` | Write
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
path followed by a newline.
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
"assets": [],
|
|
54
|
-
"warnings": []
|
|
55
|
-
}
|
|
40
|
+
| `--json` | Write one result per line as JSON Lines instead of only the Markdown path. |
|
|
41
|
+
|
|
42
|
+
Without `--json`, stdout receives one absolute Markdown path per requested URL,
|
|
43
|
+
with each path followed by a newline. Each result is written as soon as that
|
|
44
|
+
URL finishes, so parallel requests can produce output in completion order
|
|
45
|
+
rather than input order.
|
|
46
|
+
Warnings are written to stderr.
|
|
47
|
+
|
|
48
|
+
With `--json`, stdout contains one compact JSON object per requested URL,
|
|
49
|
+
also written as soon as the URL finishes. Each line has this shape:
|
|
50
|
+
|
|
51
|
+
```jsonl
|
|
52
|
+
{"requestedUrl":"https://example.com/start","sourceUrl":"https://example.com/article","path":"/data/mdhq/example.com/article.md","status":"saved","assets":[],"warnings":[]}
|
|
56
53
|
```
|
|
57
54
|
|
|
58
55
|
`status` is one of:
|
|
@@ -63,7 +60,8 @@ With `--json`, stdout contains an object with this shape:
|
|
|
63
60
|
body, including an HTTP 304 response.
|
|
64
61
|
- `skipped`: an existing same-identity file was kept.
|
|
65
62
|
|
|
66
|
-
An error is written to stderr and causes exit status `1`.
|
|
63
|
+
An error is written to stderr and causes exit status `1`. Results written to
|
|
64
|
+
stdout before the error remain available to downstream consumers.
|
|
67
65
|
|
|
68
66
|
### `list`
|
|
69
67
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@songmu/mdhq",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"description": "Save web pages as Markdown in a ghq-inspired filesystem layout.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -69,6 +69,6 @@
|
|
|
69
69
|
"@types/node": "^26.4.0",
|
|
70
70
|
"@types/proper-lockfile": "4.1.4",
|
|
71
71
|
"typescript": "^7.0.2",
|
|
72
|
-
"vitest": "^
|
|
72
|
+
"vitest": "^5.0.0"
|
|
73
73
|
}
|
|
74
74
|
}
|