You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Four correctness fixes, two of which change values you may have stored. Neo4j contract unchanged at 2.0.0. Read the first section before upgrading a pipeline that keeps span.bytes or can:// ids of merged declarations.
⚠️ Value changes (minor bump, but read this)
span.bytes are now UTF-8 byte offsets (#189, closes #179)
They were UTF-16 char offsets — ts-morph's positions — while the schema, the canonical keystone and codeanalyzer-python all mean bytes. The Neo4j projection already sliced a Buffer by them, so :TSCallable.code ran short by exactly the multibyte surplus inside the span (one em dash → the closing \n} missing). Now every node at every level — declarations, call/config_access body nodes, L3 statements and @entry/@exit, the module span, yaml ConfigKey spans — carries real byte offsets, and Buffer.from(source).subarray(lo, hi) reproduces its text, the same rule as python's source.encode()[lo:hi].
Migration: slice with bytes, not chars. Files with no non-ASCII character are byte-identical before and after; on any other file every span after the first multibyte character moves. A stored span.bytes from ≤ 1.4.0 must be recomputed.
Declaration merging mints one id per facet (#190, closes #177)
A value and a type of one name (const TableOption = () => … + interface TableOption) shared one can:// id, so the graph MERGEd them onto a node with two labels and the wrong kind; a type/type merge (class C + interface C) dropped the class from analysis.json entirely. Now the value facet keeps the bare id and the colliding type becomes …/TableOption#type; in a type/type merge the first facet keeps the bare key and id and each later one is keyed Name#<kind> (C#interface) with id …/C#interface. Signatures never move; extends/implements resolve to the type facet.
Migration: only ids that collided before change; a project without declaration merging is byte-identical (verified against main). If you stored the id of a merged type, expect the suffix.
Fixes
Large repositories no longer die in finalizeAnalysis (#188, closes #180) — the wire copy was one structuredClone of the whole envelope, which crosses Bun's serialization ceiling on a 13k-file repository (a TypeError on 1.3.0; measured on Bun 1.3.14: a ~2 GiB object aborts the process with no exception). The clone is per module now — megabytes, never gigabytes — and the rest of the root is shared by reference.
A missing input path is an error (#187, closes #181) — -i /does/not/exist used to write a schema-valid analysis.json for an empty application and exit 0. Now: one line on stderr naming the path, exit 1, nothing written; --list-programs refuses the same way. An empty but real directory still exits 0 with an empty symbol_table — that is a real answer. The reported "FATAL then exit 0" could not be reproduced on main (the FATAL path exits 1); #188 removes its only known trigger.
Also:export { type X } per-specifier type-only flags are honoured; heritage of a merged symbol resolves to its type declaration rather than its first declaration.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
codeanalyzer-typescript v1.5.0
Four correctness fixes, two of which change values you may have stored. Neo4j contract unchanged at
2.0.0. Read the first section before upgrading a pipeline that keepsspan.bytesorcan://ids of merged declarations.span.bytesare now UTF-8 byte offsets (#189, closes #179)They were UTF-16 char offsets — ts-morph's positions — while the schema, the canonical keystone and codeanalyzer-python all mean bytes. The Neo4j projection already sliced a
Bufferby them, so:TSCallable.coderan short by exactly the multibyte surplus inside the span (one em dash → the closing\n}missing). Now every node at every level — declarations,call/config_accessbody nodes, L3 statements and@entry/@exit, the module span, yamlConfigKeyspans — carries real byte offsets, andBuffer.from(source).subarray(lo, hi)reproduces its text, the same rule as python'ssource.encode()[lo:hi].Migration: slice with bytes, not chars. Files with no non-ASCII character are byte-identical before and after; on any other file every span after the first multibyte character moves. A stored
span.bytesfrom ≤ 1.4.0 must be recomputed.Declaration merging mints one id per facet (#190, closes #177)
A value and a type of one name (
const TableOption = () => …+interface TableOption) shared onecan://id, so the graphMERGEd them onto a node with two labels and the wrongkind; a type/type merge (class C+interface C) dropped the class fromanalysis.jsonentirely. Now the value facet keeps the bare id and the colliding type becomes…/TableOption#type; in a type/type merge the first facet keeps the bare key and id and each later one is keyedName#<kind>(C#interface) with id…/C#interface. Signatures never move;extends/implementsresolve to the type facet.Migration: only ids that collided before change; a project without declaration merging is byte-identical (verified against
main). If you stored the id of a merged type, expect the suffix.Fixes
Large repositories no longer die in
finalizeAnalysis(#188, closes #180) — the wire copy was onestructuredCloneof the whole envelope, which crosses Bun's serialization ceiling on a 13k-file repository (aTypeErroron 1.3.0; measured on Bun 1.3.14: a ~2 GiB object aborts the process with no exception). The clone is per module now — megabytes, never gigabytes — and the rest of the root is shared by reference.A missing input path is an error (#187, closes #181) —
-i /does/not/existused to write a schema-validanalysis.jsonfor an empty application and exit 0. Now: one line on stderr naming the path, exit 1, nothing written;--list-programsrefuses the same way. An empty but real directory still exits 0 with an emptysymbol_table— that is a real answer. The reported "FATAL then exit 0" could not be reproduced onmain(the FATAL path exits 1); #188 removes its only known trigger.Also:
export { type X }per-specifier type-only flags are honoured; heritage of a merged symbol resolves to its type declaration rather than its first declaration.Upgrade
A warm
.codeanalyzercache from 1.4.0 is invalidated automatically.Links
span.bytesare bytes, declaration merging idsAll reactions