analyze-core.ts

Pure two-phase analysis orchestrator.

Extracted from analyze.ts to break what would otherwise be a circular import: session.tsanalyze.ts (for the orchestrator) → session.ts (for the wrappers). With the orchestrator here, both session.ts and analyze.ts import downward into this module without depending on each other.

Public surface:

@internal — module split is implementation detail; consumers go through analyze.ts / session.ts for the stable surface.

view source

Declarations
#

9 declarations

analyzeCore
#

analyze-core.ts view source

(inputs: AnalyzeCoreInputs): { modules: { path: string; declarations: ({ kind: "function"; parameters: { name: string; type: string; optional: boolean; rest: boolean; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 17 more ...; sourceLine?: number | undefined; } | ... 7 more ... | { ...; })[]; ... 7 more ...; moduleComment?: string | undefined; }[]; diagnostics: ({ ...; } | ... 12 more ... | { ...; })[]; } import {analyzeCore} from 'svelte-docinfo/analyze-core.js';

Run the two-phase analysis loop on pre-prepared inputs.

inputs

returns

{ modules: { path: string; declarations: ({ kind: "function"; parameters: { name: string; type: string; optional: boolean; rest: boolean; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 17 more ...; sourceLine?: number | undefined; } | ......

AnalyzeCoreInputs
#

analyze-core.ts view source

AnalyzeCoreInputs import type {AnalyzeCoreInputs} from 'svelte-docinfo/analyze-core.js';

Inputs to analyzeCore. The caller (one-shot wrapper or session.query) is responsible for normalizing sourceOptions, obtaining the program, and pre-transforming Svelte files into svelteVirtualFiles.

transformFailedIds carries the IDs of .svelte files whose svelte2tsx transform threw at ingest. The dispatch synthesizes a placeholder ModuleJson (partial: true, empty declarations) for each so consumers see the file's existence in modules even though analysis couldn't run. Identifying these via a sibling Set keeps svelteVirtualFiles a clean "files we can analyze" map; the failure side-channel doesn't pollute it.

sourceFiles

type ReadonlyArray<SourceFileInfo>

sourceOptions

type ModuleSourceOptions

program

type ts.Program

svelteVirtualFiles

type ReadonlyMap<string, SvelteVirtualFile>

transformFailedIds?

Svelte file IDs whose svelte2tsx transform failed at ingest.

type ReadonlySet<string>

onDuplicates?

type OnDuplicates

log?

type AnalysisLog

analyzeModule
#

analyze-core.ts view source

(sourceFile: SourceFileInfo & { dependents?: readonly string[] | undefined; }, program: Program, options: ModuleSourceOptions, diagnostics: ({ symbolName: string; ... 5 more ...; column?: number | undefined; } | ... 12 more ... | { ...; })[], log?: AnalysisLog | undefined): { ...; } | undefined import {analyzeModule} from 'svelte-docinfo/analyze-core.js';

Analyze a single non-Svelte source file and extract module metadata.

sourceFile

type SourceFileInfo & { dependents?: readonly string[] | undefined; }

program

type Program

options

diagnostics

type ({ symbolName: string; file: string; message: string; severity: "error" | "warning"; kind: "type_extraction_failed"; line?: number | undefined; column?: number | undefined; } | { functionName: string; ... 5 more ...; column?: number | undefined; } | ... 11 more ... | { ...; })[]

log?

type AnalysisLog | undefined
optional

returns

{ path: string; declarations: ({ kind: "function"; parameters: { name: string; type: string; optional: boolean; rest: boolean; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 17 more ...; sourceLine?: number | undefined; } | ... 7 more ......

AnalyzeResultJson
#

analyze-core.ts view source

also exported from index.ts

ZodObject<{ modules: ZodDefault<ZodArray<ZodObject<{ path: ZodString; declarations: ZodDefault<ZodArray<ZodDiscriminatedUnion<[ZodObject<{ kind: ZodLiteral<"function">; returnType: ZodOptional<ZodString>; returnDescription: ZodOptional<...>; ... 16 more ...; genericParams: ZodDefault<...>; }, $strict>, ... 7 more ..... import type {AnalyzeResultJson} from 'svelte-docinfo/analyze-core.js';

Result of analyze, analyzeFromFiles, and AnalysisSession.query.

Modules sorted alphabetically by path. Diagnostics are query-time (analysis-pass) diagnostics only when produced by session.query; one-shot wrappers concatenate ingest + query diagnostics into this same array.

Schema-validated round-trip

The envelope is a Zod schema (AnalyzeResultJson) — both fields default to [], so JSON.stringify(result, compactReplacer) strips empty arrays on the wire and AnalyzeResultJson.parse(JSON.parse(json)) restores them. Consumers programmatically ingesting analysis JSON should parse through the schema to get defaults restored; raw-JSON consumers (e.g., jq) treat missing keys as null-equivalent (jq '.diagnostics | length' returns 0 on {}) and don't need the parse step.

Construction sites (one-shot wrappers, session.query) hand back hand-built objects without re-running .parse() — the inner modules and diagnostics arrays are already Zod-validated upstream, and the envelope schema is the type contract, not a validation gate.

See AnalyzeResultJsonWire for the serialized input-side shape published on virtual:svelte-docinfo.

AnalyzeResultJsonWire
#

analyze-core.ts view source

also exported from index.ts

AnalyzeResultJsonWire import type {AnalyzeResultJsonWire} from 'svelte-docinfo/analyze-core.js';

Serialized wire shape of an analysis result, as published by the Vite plugin on virtual:svelte-docinfo — the input-side counterpart to AnalyzeResultJson (the validated output of .parse()).

The two fields are deliberately asymmetric:

  • modules is ModuleJsonInput (the z.input of ModuleJson) because the plugin runs it through compactReplacer, which strips .default([]) arrays and .default(false) booleans. Default-bearing fields therefore arrive undefined.
  • diagnostics is the output Diagnostic — the plugin serializes it without the replacer, and Diagnostic has no defaults to strip, so the array is always present and the shape matches runtime exactly.

Consumers restore defaults by parsing through AnalyzeResultJson.

Note this describes the Vite virtual module specifically. The CLI runs the whole envelope through compactReplacer, so its JSON may additionally omit an empty diagnostics array — CLI consumers should parse through AnalyzeResultJson rather than assume this shape.

modules

type Array<ModuleJsonInput>

diagnostics

type Array<Diagnostic>

normalizeDiagnosticPaths
#

analyze-core.ts view source

(diagnostics: ({ symbolName: string; file: string; message: string; severity: "error" | "warning"; kind: "type_extraction_failed"; line?: number | undefined; column?: number | undefined; } | { functionName: string; ... 5 more ...; column?: number | undefined; } | ... 11 more ... | { ...; })[], projectRoot: string): void import {normalizeDiagnosticPaths} from 'svelte-docinfo/analyze-core.js';

Normalize Diagnostic.file to project-root-relative form, in place.

Producers inside the analysis pipeline can write absolute paths or virtual paths (svelte2tsx output like Foo.svelte.__svelte2tsx__.ts). This pass collapses both to the public contract: a path relative to projectRoot with no leading slash and no ./ prefix.

Exposed for build-tool integrations that bypass the session and collect their own discovery/dep diagnostics — they need the same normalization to match the public contract.

diagnostics

type ({ symbolName: string; file: string; message: string; severity: "error" | "warning"; kind: "type_extraction_failed"; line?: number | undefined; column?: number | undefined; } | { functionName: string; ... 5 more ...; column?: number | undefined; } | ... 11 more ... | { ...; })[]

projectRoot

type string

returns

void

mutates

  • diagnostics — — rewrites each diagnostic's `file` field

OnDuplicates
#

analyze-core.ts view source

also exported from index.ts

OnDuplicates import type {OnDuplicates} from 'svelte-docinfo/analyze-core.js';

Behavior selector for duplicate declaration names across modules.

  • 'throw' — throw an Error listing every duplicate (strict flat-namespace enforcement)
  • 'warn' — log to log.error and continue
  • OnDuplicatesCallback — custom handler

Omitted entirely: no dispatch runs, but a duplicate_declaration diagnostic is still emitted into the diagnostics array for every collision (the diagnostic is the data; this option is the action).

'throw' trade-off: the throw fires after diagnostics are emitted but before the result is returned, so 'throw' callers never reach the diagnostics array. Callers that want fail-fast *and* diagnostic access should omit onDuplicates and inspect themselves:

const result = await analyze({...}); if (hasErrors(result.diagnostics)) throw new Error('analysis errors');

Or use an OnDuplicatesCallback and stash the data before throwing.

OnDuplicatesCallback
#

analyze-core.ts view source

also exported from index.ts

OnDuplicatesCallback import type {OnDuplicatesCallback} from 'svelte-docinfo/analyze-core.js';

Custom callback for handling duplicate declaration names.

Use the 'throw' or 'warn' shortcuts on onDuplicates for the common cases. Pass a function to fully control reporting.

(call)

type (duplicates: Map<string, DuplicateDeclaration[]>, log: Pick<AnalysisLog, "error">): void

duplicates

type Map<string, DuplicateDeclaration[]>

log

type Pick<AnalysisLog, "error">
returns void

throwOnDuplicates
#

analyze-core.ts view source

also exported from index.ts

(duplicates: Map<string, DuplicateDeclaration[]>, log: Pick<AnalysisLog, "error">): void import {throwOnDuplicates} from 'svelte-docinfo/analyze-core.js';

Convenience OnDuplicatesCallback that throws on any duplicate.

duplicates

type Map<string, DuplicateDeclaration[]>

log

type Pick<AnalysisLog, "error">

returns

void

throws

  • Error - listing every duplicate name and module location

Depends on
#

Imported by
#