Skip to content

Commit a1f2c54

Browse files
authored
Merge pull request #8009 from plotly/cam/8004/add-entry-point-types
feat: Add entry point types
2 parents acddada + 95c2ade commit a1f2c54

145 files changed

Lines changed: 3184 additions & 44 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,9 @@ jobs:
596596
- name: Verify generated types are in sync with schema
597597
run: npm run schema-typegen-diff-check
598598

599+
- name: Verify entry point declarations are in sync
600+
run: npm run entry-point-types-check
601+
599602
package-resolution:
600603
needs: install-and-cibuild
601604
runs-on: ubuntu-latest
@@ -646,6 +649,21 @@ jobs:
646649
647650
console.log('Loaded ' + modules.length + ' compiled modules and src/lib/index.js');
648651
652+
- name: Type-check type imports from the entry points
653+
working-directory: ${{ runner.temp }}/consumer
654+
run: |
655+
cat > entry-point-types.ts <<'EOF'
656+
import type * as Root from 'plotly.js';
657+
import type { Config, Data, Layout } from 'plotly.js/lib/core';
658+
import type * as calendars from 'plotly.js/lib/calendars';
659+
import type * as indexBasic from 'plotly.js/lib/index-basic';
660+
import type * as scatter from 'plotly.js/lib/scatter';
661+
import type * as de from 'plotly.js/lib/locales/de';
662+
EOF
663+
"$GITHUB_WORKSPACE"/node_modules/.bin/tsc entry-point-types.ts \
664+
--noEmit --strict --skipLibCheck \
665+
--target es2022 --module esnext --moduleResolution bundler
666+
649667
# ============================================================
650668
# Standalone jobs (no dependencies on install-and-cibuild)
651669
# ============================================================

draftlogs/8009_fix.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Add TypeScript declarations for the modular `lib/` entry points [[#8009](https://github.com/plotly/plotly.js/pull/8009)]

package.json

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,19 @@
55
"license": "MIT",
66
"main": "./lib/index.js",
77
"types": "./lib/index.d.ts",
8+
"typesVersions": {
9+
"*": {
10+
"lib/index.d.ts": [
11+
"./lib/index.d.ts"
12+
],
13+
"lib/index": [
14+
"./lib/index.d.ts"
15+
],
16+
"lib/*": [
17+
"./src/types/generated/entry_points/*.d.ts"
18+
]
19+
}
20+
},
821
"webpack": "./dist/plotly.js",
922
"repository": {
1023
"type": "git",
@@ -30,14 +43,16 @@
3043
"extra-bundles": "node tasks/extra_bundles.mjs",
3144
"locales": "node tasks/locales.mjs",
3245
"schema": "node tasks/schema.mjs",
33-
"schema-typegen-diff-check": "npm run schema && git diff --exit-code src/types/generated/ test/plot-schema.json",
46+
"schema-typegen-diff-check": "npm run schema && git diff --exit-code src/types/generated/schema.d.ts test/plot-schema.json",
47+
"entry-point-types": "node tasks/entry_point_types.mjs",
48+
"entry-point-types-check": "node tasks/entry_point_types.mjs --check",
3449
"stats": "node tasks/stats.mjs",
3550
"find-strings": "node tasks/find_locale_strings.js",
3651
"preprocess": "node tasks/preprocess.js",
3752
"use-draftlogs": "node tasks/use_draftlogs.js",
3853
"empty-draftlogs": "node tasks/empty_draftlogs.js",
3954
"empty-dist": "node tasks/empty_dist.js",
40-
"build": "npm run empty-dist && npm run preprocess && npm run find-strings && npm run bundle && npm run extra-bundles && npm run locales && npm run schema dist && npm run stats",
55+
"build": "npm run empty-dist && npm run preprocess && npm run entry-point-types && npm run find-strings && npm run bundle && npm run extra-bundles && npm run locales && npm run schema dist && npm run stats",
4156
"regl-codegen": "node devtools/regl_codegen/server.mjs",
4257
"cibuild": "npm run empty-dist && npm run preprocess && node tasks/cibundle.mjs",
4358
"lint": "npx @biomejs/biome lint",

src/types/ARCHITECTURE.md

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ How TypeScript types are organized in plotly.js.
2727
│ │ │ schema.d.ts — common enums, │
2828
│ │ │ traces, layout, animation, │
2929
│ │ │ config, _internal namespace │
30+
│ │ │ │
31+
│ │ │ entry_points/ — one │
32+
│ │ │ declaration per lib/ path │
3033
└──────────────────────────┘ └────────────────────────────────┘
3134
```
3235

@@ -119,9 +122,33 @@ src/types/
119122
│ └── attributes.d.ts # AttributeMap, AttrInfo (compile-time validation)
120123
121124
└── generated/ # machine-generated types
122-
└── schema.d.ts # all traces + layout + shared types (from plot-schema.json)
125+
├── schema.d.ts # all traces + layout + shared types (from plot-schema.json)
126+
└── entry_points/ # one declaration per lib/ entry point
127+
├── core.d.ts # plotly.js/lib/core
128+
├── scatter.d.ts # plotly.js/lib/scatter, and one per trace
129+
└── locales/ # plotly.js/lib/locales/<id>, one per locale
123130
```
124131

132+
### The `generated/entry_points/` directory
133+
134+
`lib/` holds one entry point per trace, component, bundle, and locale, so a
135+
consumer can import `plotly.js/lib/scatter` instead of the whole library. Each
136+
entry point needs its own declaration. Those declarations live here rather than
137+
beside the entry points so `lib/` stays readable.
138+
139+
`typesVersions` in package.json maps `plotly.js/lib/<entry>` onto this directory.
140+
Two things follow from that:
141+
142+
- The `lib/index.d.ts` key in that table is necessary. TypeScript 5 runs the
143+
resolved `types` field back through the table, and without the key the `lib/*`
144+
pattern captures it and breaks the plain `plotly.js` import.
145+
- WARNING: TypeScript ignores `typesVersions` once a package has an `exports`
146+
field. Adding `exports` to package.json breaks every subpath declaration here.
147+
148+
Run `npm run entry-point-types` to regenerate. Run
149+
`npm run entry-point-types-check` to fail when the committed output is stale. CI
150+
runs the check, so a new entry point cannot ship without its declaration.
151+
125152
### The `.internal.d.ts` convention
126153

127154
Files with the `.internal.d.ts` suffix contain types that are **not** part of the

src/types/CONVERTING_ATTRIBUTES.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ should be added to the corresponding `Full*` interface instead.
103103
```bash
104104
npm run typecheck # zero errors
105105
npm run schema-typegen-diff-check # regen + check test/plot-schema.json
106-
# and src/types/generated/ are unchanged
106+
# and generated/schema.d.ts are unchanged
107107
```
108108

109109
The `schema-typegen-diff-check` script regenerates both the runtime schema

src/types/GENERATOR.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -330,10 +330,14 @@ wildcard) but their bare names are not.
330330
## CI integration
331331

332332
`npm run schema-typegen-diff-check` runs the generator and then verifies that
333-
both `test/plot-schema.json` and `src/types/generated/` are unchanged via
334-
`git diff --exit-code`. If either differs, the command fails with exit code 1
333+
both `test/plot-schema.json` and `src/types/generated/schema.d.ts` are unchanged
334+
via `git diff --exit-code`. If either differs, the command fails with exit code 1
335335
and outputs the diff to the console.
336336

337+
The path names `schema.d.ts` rather than the whole `generated/` directory, so an
338+
uncommitted change to the entry point declarations cannot fail this check.
339+
`npm run entry-point-types-check` covers those.
340+
337341
This is what makes the JS-to-TS conversion workflow safe: a correct
338342
conversion produces a byte-identical schema, so the check passes; an
339343
incorrect conversion (typo in a `values` array, missed default, wrong

src/types/README.md

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ This directory documents the TypeScript conversion in progress.
77
| [SETUP.md](SETUP.md) | First-time contributor — toolchain overview, npm scripts |
88
| [ARCHITECTURE.md](ARCHITECTURE.md) | Anyone working with types — directory layout, public/private split |
99
| [CONVERTING_ATTRIBUTES.md](CONVERTING_ATTRIBUTES.md) | **Contributor doing conversion work** — step-by-step recipe |
10-
| [GENERATOR.md](GENERATOR.md) | Maintainer extending or debugging the type generator |
10+
| [GENERATOR.md](GENERATOR.md) | Maintainer extending or debugging the schema type generator |
1111

1212
## Status
1313

@@ -16,7 +16,8 @@ This directory documents the TypeScript conversion in progress.
1616
- `AttributeMap` validation machinery: ✅ done
1717
- **Schema-based type generator**: ✅ done — all trace types + layout + shared interfaces
1818
- Consumer entry point (`lib/index.d.ts`, wired via `package.json#types`): ✅ done
19-
- CI gates (`typecheck` + `schema-typegen-diff-check`): ✅ done
19+
- Modular entry points (`plotly.js/lib/<entry>`, wired via `package.json#typesVersions`): ✅ done
20+
- CI gates (`typecheck` + `schema-typegen-diff-check` + `entry-point-types-check`): ✅ done
2021
- First attribute file converted (modebar): ✅ done
2122
- Conversion of remaining files: 🚧 in progress
2223

@@ -36,12 +37,24 @@ This directory documents the TypeScript conversion in progress.
3637
`Datum[] | Datum[][] | TypedArray` for *every* `data_array` so 2D/3D usage
3738
typechecks, but the trade-off is that 1D-only fields also accept 2D arrays.
3839

39-
The published consumer surface lives at [`lib/index.d.ts`](../../lib/index.d.ts).
40+
The published consumer surface has two parts. [`lib/index.d.ts`](../../lib/index.d.ts)
41+
declares the full library for `import ... from 'plotly.js'`. The generated
42+
declarations in [`generated/entry_points/`](generated/entry_points/) cover the
43+
modular entry points, one file each: `plotly.js/lib/core`, every trace and
44+
component, the partial bundles, and every locale under
45+
`plotly.js/lib/locales/`.
46+
4047
This `src/types/` directory is the authoring location — internal types live
4148
here, public types are re-exported through `lib/index.d.ts` to consumers.
4249

4350
## Generated types
4451

52+
Two tasks generate types. This section covers the schema generator. For the
53+
entry point declarations under
54+
[`generated/entry_points/`](generated/entry_points/), see
55+
[ARCHITECTURE.md](ARCHITECTURE.md#the-generatedentry_points-directory) and run
56+
`npm run entry-point-types`.
57+
4558
The following are **auto-generated from `plot-schema.json`** by
4659
`tasks/generate_schema_types.mjs`:
4760

src/types/SETUP.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ npm run typecheck-watch # incremental rechecking on change
2929

3030
npm run schema # rebuild test/plot-schema.json + regenerate types under src/types/generated/
3131
npm run schema-typegen-diff-check # regenerate + verify no changes to test/plot-schema.json or src/types/generated/schema.d.ts
32+
33+
npm run entry-point-types # regenerate the entry point declarations under src/types/generated/entry_points/
34+
npm run entry-point-types-check # verify the committed entry point declarations are current
35+
3236
npm run build # full production build (regenerate all files under `dist/`)
3337
```
3438

@@ -48,14 +52,16 @@ npm start
4852

4953
```bash
5054
npm run typecheck
51-
npm run schema # if attribute files changed
55+
npm run schema # if attribute files changed
56+
npm run entry-point-types # if you added or removed a lib/ entry point
5257
```
5358

54-
**CI** runs both checks as separate jobs (see `.github/workflows/ci.yml`):
59+
**CI** runs these checks (see `.github/workflows/ci.yml`):
5560

5661
```bash
5762
npm run typecheck # validates the type system is internally consistent
5863
npm run schema-typegen-diff-check # verifies generated types match the schema
64+
npm run entry-point-types-check # verifies every lib/ entry point has a current declaration
5965
```
6066

6167
## How esbuild handles `.ts`
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/**
2+
* Generated from lib/bar.js by tasks/generate_entry_point_types.mjs.
3+
* Do not edit by hand — run `npm run entry-point-types` to regenerate.
4+
*/
5+
6+
import type { RegisterTraceModule } from '../../core/api';
7+
8+
/**
9+
* The `bar` trace module, for `Plotly.register`.
10+
*
11+
* @example
12+
* import * as Plotly from 'plotly.js/lib/core';
13+
* import * as bar from 'plotly.js/lib/bar';
14+
*
15+
* Plotly.register([bar]);
16+
*/
17+
declare const bar: RegisterTraceModule & { name: 'bar' };
18+
19+
export = bar;
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/**
2+
* Generated from lib/barpolar.js by tasks/generate_entry_point_types.mjs.
3+
* Do not edit by hand — run `npm run entry-point-types` to regenerate.
4+
*/
5+
6+
import type { RegisterTraceModule } from '../../core/api';
7+
8+
/**
9+
* The `barpolar` trace module, for `Plotly.register`.
10+
*
11+
* @example
12+
* import * as Plotly from 'plotly.js/lib/core';
13+
* import * as barpolar from 'plotly.js/lib/barpolar';
14+
*
15+
* Plotly.register([barpolar]);
16+
*/
17+
declare const barpolar: RegisterTraceModule & { name: 'barpolar' };
18+
19+
export = barpolar;

0 commit comments

Comments
 (0)