lens-content-processor 0.9.0 → 0.10.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/cli.d.ts CHANGED
@@ -4,6 +4,8 @@ export interface CliOptions {
4
4
  vaultPath: string | null;
5
5
  outputPath: string | null;
6
6
  stdin: boolean;
7
+ deferUrls: boolean;
8
+ checkUrlsOnly: boolean;
7
9
  }
8
10
  /**
9
11
  * The CLI's JSON output: the core ProcessResult plus a course-reachability map
package/dist/cli.js CHANGED
@@ -1,8 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  // src/cli.ts
3
3
  import { readVaultFiles } from "./fs/read-vault.js";
4
- import { processContent } from "./index.js";
5
- import { validateUrls } from "./validator/url-reachability.js";
4
+ import { processContent, } from "./index.js";
5
+ import { validateUrls, materializeUrlIssue, } from "./validator/url-reachability.js";
6
+ import { UrlCache } from "./validator/url-cache.js";
6
7
  import { buildFileToCourses } from "./reference-graph.js";
7
8
  import { dedupeErrors } from "./dedupe-errors.js";
8
9
  import { writeFile } from "fs/promises";
@@ -11,6 +12,8 @@ export function parseArgs(argv) {
11
12
  let vaultPath = null;
12
13
  let outputPath = null;
13
14
  let stdin = false;
15
+ let deferUrls = false;
16
+ let checkUrlsOnly = false;
14
17
  for (let i = 0; i < args.length; i++) {
15
18
  if (args[i] === "--output" || args[i] === "-o") {
16
19
  outputPath = args[i + 1] || null;
@@ -19,11 +22,17 @@ export function parseArgs(argv) {
19
22
  else if (args[i] === "--stdin") {
20
23
  stdin = true;
21
24
  }
25
+ else if (args[i] === "--defer-urls") {
26
+ deferUrls = true;
27
+ }
28
+ else if (args[i] === "--check-urls-only") {
29
+ checkUrlsOnly = true;
30
+ }
22
31
  else if (!args[i].startsWith("-")) {
23
32
  vaultPath = args[i];
24
33
  }
25
34
  }
26
- return { vaultPath, outputPath, stdin };
35
+ return { vaultPath, outputPath, stdin, deferUrls, checkUrlsOnly };
27
36
  }
28
37
  async function readStdin() {
29
38
  const chunks = [];
@@ -63,6 +72,22 @@ export async function run(options) {
63
72
  }
64
73
  async function main() {
65
74
  const options = parseArgs(process.argv);
75
+ if (options.deferUrls && options.checkUrlsOnly) {
76
+ console.error("--defer-urls and --check-urls-only are mutually exclusive");
77
+ process.exit(1);
78
+ }
79
+ if (options.checkUrlsOnly) {
80
+ try {
81
+ const urls = JSON.parse(await readStdin());
82
+ const issues = await validateUrls(urls, UrlCache.load());
83
+ console.log(JSON.stringify(dedupeErrors(issues), null, 2));
84
+ }
85
+ catch (error) {
86
+ console.error("Error:", error instanceof Error ? error.message : error);
87
+ process.exit(1);
88
+ }
89
+ return;
90
+ }
66
91
  if (!options.vaultPath && !options.stdin) {
67
92
  console.error("Usage: npx tsx src/cli.ts <vault-path> [--output <file>]");
68
93
  console.error(" npx tsx src/cli.ts --stdin [--output <file>]");
@@ -70,14 +95,39 @@ async function main() {
70
95
  }
71
96
  try {
72
97
  const result = await run(options);
73
- // Async URL reachability validation
74
- if (result.urlsToValidate.length > 0) {
75
- const urlWarnings = await validateUrls(result.urlsToValidate);
98
+ let output = result;
99
+ if (options.deferUrls) {
100
+ // Zero network: materialize issues from still-fresh cache entries and
101
+ // report how many unique URLs would need a live check. The consumer
102
+ // (backend) runs those later via --check-urls-only and replaces
103
+ // urlIssues wholesale — hence issues stay OUT of `errors` here.
104
+ const cache = UrlCache.load();
105
+ const cachedIssues = [];
106
+ for (const entry of result.urlsToValidate) {
107
+ const outcome = cache.getFresh(entry.url);
108
+ if (!outcome)
109
+ continue;
110
+ const issue = materializeUrlIssue(entry, outcome);
111
+ if (issue)
112
+ cachedIssues.push(issue);
113
+ }
114
+ // Dedupe against content errors exactly like the default mode's combined
115
+ // dedupe, then keep only the URL tail (errors are already deduped, so
116
+ // the slice boundary is exact).
117
+ const urlIssues = dedupeErrors([...result.errors, ...cachedIssues]).slice(result.errors.length);
118
+ output = {
119
+ ...result,
120
+ urlIssues,
121
+ staleUrlCount: cache.staleCount(result.urlsToValidate),
122
+ };
123
+ }
124
+ else if (result.urlsToValidate.length > 0) {
125
+ const urlWarnings = await validateUrls(result.urlsToValidate, UrlCache.load());
76
126
  // Re-dedupe: urlWarnings are appended after processContent already
77
127
  // deduped, and can themselves repeat (same unreachable URL twice).
78
128
  result.errors = dedupeErrors([...result.errors, ...urlWarnings]);
79
129
  }
80
- const json = JSON.stringify(result, null, 2);
130
+ const json = JSON.stringify(output, null, 2);
81
131
  if (options.outputPath) {
82
132
  await writeFile(options.outputPath, json, "utf-8");
83
133
  console.error(`Written to ${options.outputPath}`);
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ export type UrlOutcome = {
2
+ kind: "ok";
3
+ } | {
4
+ kind: "not_found";
5
+ status: number;
6
+ } | {
7
+ kind: "unconfirmed";
8
+ status: number;
9
+ } | {
10
+ kind: "timeout";
11
+ } | {
12
+ kind: "network_error";
13
+ };
14
+ export declare function defaultUrlCachePath(): string;
15
+ export declare class UrlCache {
16
+ private readonly path;
17
+ private entries;
18
+ private constructor();
19
+ /** Missing/corrupt/version-mismatched file ⇒ empty cache (degradable). */
20
+ static load(path?: string): UrlCache;
21
+ getFresh(url: string, nowMs?: number): UrlOutcome | null;
22
+ set(url: string, outcome: UrlOutcome, nowMs?: number): void;
23
+ /** Unique URLs in `urls` with no fresh cache entry. */
24
+ staleCount(urls: {
25
+ url: string;
26
+ }[], nowMs?: number): number;
27
+ /** Temp-file + rename so concurrent runs are last-writer-wins, never corrupt. */
28
+ persist(): void;
29
+ }
@@ -0,0 +1,73 @@
1
+ // src/validator/url-cache.ts
2
+ // Persistent per-URL reachability cache (24h TTL). Shared by all CLI modes.
3
+ // See docs/plans/2026-07-07-url-cache-nonblocking-design.md §1.
4
+ import { readFileSync, writeFileSync, renameSync } from "fs";
5
+ import { tmpdir } from "os";
6
+ import { join } from "path";
7
+ const CACHE_VERSION = 1;
8
+ const TTL_MS = 24 * 60 * 60 * 1000;
9
+ export function defaultUrlCachePath() {
10
+ return (process.env.LENS_URL_CACHE_PATH ??
11
+ join(tmpdir(), "lens-content-processor-url-cache.json"));
12
+ }
13
+ export class UrlCache {
14
+ path;
15
+ entries;
16
+ constructor(path, entries) {
17
+ this.path = path;
18
+ this.entries = entries;
19
+ }
20
+ /** Missing/corrupt/version-mismatched file ⇒ empty cache (degradable). */
21
+ static load(path = defaultUrlCachePath()) {
22
+ try {
23
+ const parsed = JSON.parse(readFileSync(path, "utf-8"));
24
+ if (parsed.version === CACHE_VERSION && parsed.entries) {
25
+ return new UrlCache(path, parsed.entries);
26
+ }
27
+ console.error(`url-cache: discarding ${path} (version mismatch)`);
28
+ }
29
+ catch (error) {
30
+ // A missing file is the normal cold-start case — stay quiet. Anything
31
+ // else (corrupt JSON, permission error) is worth a stderr note.
32
+ if (error.code !== "ENOENT") {
33
+ console.error(`url-cache: treating ${path} as empty:`, error instanceof Error ? error.message : error);
34
+ }
35
+ }
36
+ return new UrlCache(path, {});
37
+ }
38
+ getFresh(url, nowMs = Date.now()) {
39
+ const entry = this.entries[url];
40
+ if (!entry)
41
+ return null;
42
+ const age = nowMs - Date.parse(entry.checkedAt);
43
+ if (!(age >= 0 && age < TTL_MS))
44
+ return null;
45
+ return entry.outcome;
46
+ }
47
+ set(url, outcome, nowMs = Date.now()) {
48
+ this.entries[url] = { checkedAt: new Date(nowMs).toISOString(), outcome };
49
+ }
50
+ /** Unique URLs in `urls` with no fresh cache entry. */
51
+ staleCount(urls, nowMs = Date.now()) {
52
+ const stale = new Set();
53
+ for (const { url } of urls) {
54
+ if (this.getFresh(url, nowMs) === null)
55
+ stale.add(url);
56
+ }
57
+ return stale.size;
58
+ }
59
+ /** Temp-file + rename so concurrent runs are last-writer-wins, never corrupt. */
60
+ persist() {
61
+ const file = { version: CACHE_VERSION, entries: this.entries };
62
+ const tmpPath = `${this.path}.${process.pid}.tmp`;
63
+ try {
64
+ writeFileSync(tmpPath, JSON.stringify(file), "utf-8");
65
+ renameSync(tmpPath, this.path);
66
+ }
67
+ catch (error) {
68
+ // Degradable: an unwritable cache must never break validation.
69
+ console.error(`url-cache: failed to persist ${this.path}:`, error instanceof Error ? error.message : error);
70
+ }
71
+ }
72
+ }
73
+ //# sourceMappingURL=url-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"url-cache.js","sourceRoot":"","sources":["../../src/validator/url-cache.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import type { ContentError } from "../index.js";
2
+ import type { UrlOutcome, UrlCache } from "./url-cache.js";
2
3
  export interface UrlToValidate {
3
4
  url: string;
4
5
  file: string;
@@ -6,4 +7,16 @@ export interface UrlToValidate {
6
7
  label: string;
7
8
  allowUnreachable?: boolean;
8
9
  }
9
- export declare function validateUrls(urls: UrlToValidate[]): Promise<ContentError[]>;
10
+ /**
11
+ * Classification → warning/error for one urlsToValidate entry. Preserves the
12
+ * old checkUrl output BYTE-FOR-BYTE: the two original branches built their
13
+ * objects with different key orders, and JSON.stringify preserves insertion
14
+ * order, so each branch below must keep its exact key order.
15
+ *
16
+ * 404/410 are definitively dead: an error, never overridable. Any other
17
+ * non-ok outcome means we could not confirm reachability (a 403 bot/WAF
18
+ * block, a 5xx, a timeout, a DNS hiccup); those warnings can be vouched for
19
+ * by hand via allowUnreachable.
20
+ */
21
+ export declare function materializeUrlIssue(entry: UrlToValidate, outcome: UrlOutcome): ContentError | null;
22
+ export declare function validateUrls(urls: UrlToValidate[], cache?: UrlCache): Promise<ContentError[]>;
@@ -17,9 +17,10 @@ async function fetchWithTimeout(url, method) {
17
17
  clearTimeout(timeout);
18
18
  }
19
19
  }
20
- async function checkUrl(entry) {
20
+ /** Network → classification. Must match the old checkUrl decision tree exactly. */
21
+ async function classifyUrl(url) {
21
22
  try {
22
- let response = await fetchWithTimeout(entry.url, "HEAD");
23
+ let response = await fetchWithTimeout(url, "HEAD");
23
24
  // A HEAD that isn't a definitive answer (not OK, not a known 404/410 or
24
25
  // rate-limit) may just mean the server rejects the HEAD method: some do so
25
26
  // with 405, others unconventionally with 403. Retry with GET to get the true
@@ -27,56 +28,102 @@ async function checkUrl(entry) {
27
28
  if (!response.ok &&
28
29
  !NOT_FOUND_STATUSES.has(response.status) &&
29
30
  !REACHABLE_STATUSES.has(response.status)) {
30
- response = await fetchWithTimeout(entry.url, "GET");
31
+ response = await fetchWithTimeout(url, "GET");
31
32
  }
32
- if (!response.ok && !REACHABLE_STATUSES.has(response.status)) {
33
- // 404/410 are definitively dead: an error, never overridable. Any other
34
- // status means we could not confirm reachability (a 403 bot/WAF block, a
35
- // 5xx, etc.); that warning can be vouched for by hand via allowUnreachable.
36
- const isNotFound = NOT_FOUND_STATUSES.has(response.status);
37
- if (!isNotFound && entry.allowUnreachable)
33
+ if (response.ok || REACHABLE_STATUSES.has(response.status)) {
34
+ return { kind: "ok" };
35
+ }
36
+ if (NOT_FOUND_STATUSES.has(response.status)) {
37
+ return { kind: "not_found", status: response.status };
38
+ }
39
+ return { kind: "unconfirmed", status: response.status };
40
+ }
41
+ catch (error) {
42
+ const aborted = error instanceof DOMException && error.name === "AbortError";
43
+ return aborted ? { kind: "timeout" } : { kind: "network_error" };
44
+ }
45
+ }
46
+ /**
47
+ * Classification → warning/error for one urlsToValidate entry. Preserves the
48
+ * old checkUrl output BYTE-FOR-BYTE: the two original branches built their
49
+ * objects with different key orders, and JSON.stringify preserves insertion
50
+ * order, so each branch below must keep its exact key order.
51
+ *
52
+ * 404/410 are definitively dead: an error, never overridable. Any other
53
+ * non-ok outcome means we could not confirm reachability (a 403 bot/WAF
54
+ * block, a 5xx, a timeout, a DNS hiccup); those warnings can be vouched for
55
+ * by hand via allowUnreachable.
56
+ */
57
+ export function materializeUrlIssue(entry, outcome) {
58
+ switch (outcome.kind) {
59
+ case "ok":
60
+ return null;
61
+ case "not_found":
62
+ return {
63
+ file: entry.file,
64
+ line: entry.line,
65
+ message: `${entry.label} returned HTTP ${outcome.status}: ${entry.url}`,
66
+ severity: "error",
67
+ };
68
+ case "unconfirmed":
69
+ if (entry.allowUnreachable)
38
70
  return null;
39
71
  return {
40
72
  file: entry.file,
41
73
  line: entry.line,
42
- message: `${entry.label} returned HTTP ${response.status}: ${entry.url}`,
43
- severity: isNotFound ? "error" : "warning",
44
- ...(isNotFound ? {} : { suggestion: OVERRIDE_HINT }),
74
+ message: `${entry.label} returned HTTP ${outcome.status}: ${entry.url}`,
75
+ severity: "warning",
76
+ suggestion: OVERRIDE_HINT,
77
+ };
78
+ case "timeout":
79
+ case "network_error":
80
+ if (entry.allowUnreachable)
81
+ return null;
82
+ return {
83
+ file: entry.file,
84
+ line: entry.line,
85
+ message: outcome.kind === "timeout"
86
+ ? `${entry.label} timed out: ${entry.url}`
87
+ : `${entry.label} unreachable: ${entry.url}`,
88
+ suggestion: OVERRIDE_HINT,
89
+ severity: "warning",
45
90
  };
46
- }
47
- return null;
48
- }
49
- catch (error) {
50
- // A timeout or network failure is "could not confirm" too (our own network, a
51
- // transient DNS hiccup, or a flaky host), not a definitive 404/410, so it is
52
- // overridable as well.
53
- if (entry.allowUnreachable)
54
- return null;
55
- const aborted = error instanceof DOMException && error.name === "AbortError";
56
- return {
57
- file: entry.file,
58
- line: entry.line,
59
- message: aborted
60
- ? `${entry.label} timed out: ${entry.url}`
61
- : `${entry.label} unreachable: ${entry.url}`,
62
- suggestion: OVERRIDE_HINT,
63
- severity: "warning",
64
- };
65
91
  }
66
92
  }
67
- export async function validateUrls(urls) {
93
+ export async function validateUrls(urls, cache) {
68
94
  if (urls.length === 0)
69
95
  return [];
70
- const warnings = [];
71
- // Process in batches to avoid overwhelming servers/network
72
- for (let i = 0; i < urls.length; i += CONCURRENCY) {
73
- const batch = urls.slice(i, i + CONCURRENCY);
74
- const results = await Promise.all(batch.map(checkUrl));
75
- for (const result of results) {
76
- if (result)
77
- warnings.push(result);
78
- }
96
+ // Resolve one outcome per unique URL: from fresh cache where possible,
97
+ // otherwise over the network (batched, then written back to the cache).
98
+ const outcomes = new Map();
99
+ const toCheck = [];
100
+ for (const { url } of urls) {
101
+ if (outcomes.has(url) || toCheck.includes(url))
102
+ continue;
103
+ const cached = cache?.getFresh(url) ?? null;
104
+ if (cached)
105
+ outcomes.set(url, cached);
106
+ else
107
+ toCheck.push(url);
108
+ }
109
+ // Process in batches to avoid overwhelming servers/network. Persist after
110
+ // each batch so an interrupted sweep still makes durable progress.
111
+ for (let i = 0; i < toCheck.length; i += CONCURRENCY) {
112
+ const batch = toCheck.slice(i, i + CONCURRENCY);
113
+ const results = await Promise.all(batch.map(classifyUrl));
114
+ batch.forEach((url, j) => {
115
+ outcomes.set(url, results[j]);
116
+ cache?.set(url, results[j]);
117
+ });
118
+ cache?.persist();
119
+ }
120
+ // One issue per entry, in urlsToValidate entry order (output parity).
121
+ const issues = [];
122
+ for (const entry of urls) {
123
+ const issue = materializeUrlIssue(entry, outcomes.get(entry.url));
124
+ if (issue)
125
+ issues.push(issue);
79
126
  }
80
- return warnings;
127
+ return issues;
81
128
  }
82
129
  //# sourceMappingURL=url-reachability.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"url-reachability.js","sourceRoot":"","sources":["../../src/validator/url-reachability.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"url-reachability.js","sourceRoot":"","sources":["../../src/validator/url-reachability.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lens-content-processor",
3
- "version": "0.9.0",
3
+ "version": "0.10.0",
4
4
  "description": "Parser and validator for Lens educational content (Markdown modules, lenses, learning outcomes)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",