Skip to content

Clean up .js files in various TypeScript-first packages#2992

Merged
mfedderly merged 7 commits intomasterfrom
mf/clean-up-lib-js
Jan 1, 2026
Merged

Clean up .js files in various TypeScript-first packages#2992
mfedderly merged 7 commits intomasterfrom
mf/clean-up-lib-js

Conversation

@mfedderly
Copy link
Collaborator

Turns out the migration steps to TypeScript in certain packages just added typings to the .js files and moved on. This converts the rest of the supporting .js files, so we don't have to rely on the tsup build behavior of copying these into the dist directory for us.

I'll add a few inline notes of things I noticed along the way.

import { getCoords, collectionOf } from "@turf/invariant";
import { featureEach } from "@turf/meta";
import { isObject } from "@turf/helpers";
import { Feature, FeatureCollection, Point } from "geojson";
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isobands and isolines share these two matrix transform files, they're identical copies.

var first = rhumbDestination(origin, cellSize * r, 0, { units: units });
if (first.properties == null) {
first.properties = {};
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To satisfy the type strictness.

@@ -1,56 +1,68 @@
// Find self-intersections in geojson polygon (possibly with interior rings)
import { Feature, Polygon, Position } from "geojson";
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file and simplepolygon felt really rough to migrate 😩

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @mfedderly . I'm the author of simplepolygon and migrate the code to typescript around the same time (two weeks earlier actually) of your commit. Just found out about your work too. There's some useful feedback here I'll try to incorporate in the near future, thanks!

I'm curious if the vendoring of simplepolygon and geojson-polygon-self-intersections is a strategic choice, or if you'd consider to add them as dependencies?

Manuel

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mclaeysb in this PR I just blindly migrated the remaining .js files to .ts since we're trying to get off of the split js/ts build system that we've got going on right now. These few files definitely felt like I was more likely to make a mistake in the translation compared to the other ones.

I'm not actually sure why this file was originally vendoered (edit: see below about circular dependencies onto Turf packages). I'd be open to transitioning this to a dependency on your original NPM package though. Using the original package would be good for overall bundle sizes, on the off chance that someone pulls in simplepolygon and @turf/unkink-polygon at the same time.

One thing that's been on my mind is that Turf does tend to generate ~500k downloads a week, and so I feel some responsibility to guard against supply-chain attacks. Turf just published its first release with NPM's Trusted Publishing, as we already were publishing through GitHub actions.

I'm still thinking about the exact details but I would prefer our dependencies to meet the following standards:

  • Have a npm/pnpm/yarn lockfile checked in
  • Have relatively few entries in dependencies
  • Have a relatively low number of issues flagged by Dependabot in your package and its transitive dependencies (ignoring anything coming from devDependencies, because it doesn't impact Turf and its consumers). Basically: do you increase OUR Dependabot list if we take a dependency on your package.
  • Use trusted publishing (I know this is new and lots of our existing packages don't satisfy this, I think it's probably valuable but understand that its annoying to set up)

In simplepolygon's case, there's another complication. Turf cannot safely take dependencies on a package that itself has dependencies on @turf/*. The reason being is that our published packages depend on all of the other Turf packages at at least the same version. For example your package currently depends on "@turf/area": "7.3.1", which will already pull in a second version of @turf/area with the current Turf 7.3.3. Sneakily, even if you depended on "@turf/area": "^7", it would give us these same issues when we release v8.

Separately, I suspect you don't need the dependency on geojson, and just want the @types/geojson devDependencies.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh another thing, even for single-maintainer packages, it makes me more comfortable if there are pull requests that publicly run some amount of testing before being merged.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the reply (and the work on Turf!). I understand the risk management perspective. I just wanted to offer help if a dependency solution was preferred, but for me it all ok.

Going forward I'll try to find some time to include your suggestions on the geojson dependencies and other remarks in this PR (like those on speed and efficiency) in the latest version of simplepolygon. I don't see myself setting up a more complicated publishing or CI though.

You can then consider to update the vendored version to the latest simplepolygon (with TS and improvements) just once (or add a dependency, but reading your requirement, maybe that won't happen).

I'll keep you updated
Cheers!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mclaeysb sounds good. Thanks to you also also for simplepolygon in the first place! Its been working well for Turf since before my time on the project, and as far as I know nobody has complained about performance. It was just something I noticed along the way as I migrated the code.

Happy to lend another set of eyes on the simplepolygon side if you'd like, otherwise feel free to ping me and I can re-vendor the updated code. We appreciate the continued maintenance here, always nice to have some confidence that things haven't been abandoned.

output = {
type: "Feature",
geometry: { type: "MultiPoint", coordinates: output },
};
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

filterFn is always defined in our usage, so I removed this.

}
>;
determineParents(output);
setNetWinding(output);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

var output was declared twice and the types disagreed, and then the determineParents and setNetWinding calls were referencing it quasi-implicitly because of the closure. Gnarly stuff.

for (var j = 0; j < pseudoVtxListByRingAndEdge[i].length; j++) {
for (var k = 0; k < pseudoVtxListByRingAndEdge[i][j].length; k++) {
var coordToFind = pseudoVtxListByRingAndEdge[i][j][k].coord;
let coordToFind = pseudoVtxListByRingAndEdge[i][j][k].coord;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^ multiple var defs bypassed by turning them into lets

var pushing = { isect: nxtIsect };
var pushing: { isect: number; parent: number; winding: number } = {
isect: nxtIsect,
} as any; // as any because parent and winding are filled in below
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leaving the code as-is, but I'd write this differently if we were TypeScript first. The isect/parent/winding tuple type is also defined in several places instead of giving it a name.

break;
}
u[array[i]] = 1;
u[array[i].toString()] = 1;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is probably horrible for perf [number, number].toString() gets used as the key into u


var key = isect;
var unique = !seen[key];
var unique = !seen[key.toString()];
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is [number, number].toString() being used as a key. This has to be bad for perf.

@mfedderly mfedderly merged commit 42bd068 into master Jan 1, 2026
4 checks passed
@mfedderly mfedderly deleted the mf/clean-up-lib-js branch January 1, 2026 19:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants