Repository navigation
refactor!: Continued public surface minimization #4060
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
ec033b5
Handle members that can be marked private/internal without additional…
janbuchar a1c8b84
refactor!: Collapse the context pipeline seam into `contextPipelineBu…
janbuchar 1a37307
refactor!: Make BasicCrawler.requestManager read-only
janbuchar 4ae206a
Add a guide about the public API export and our BC guarantees
janbuchar 79a7185
Do not ignore symbols that are in fact part of the public API, remove…
janbuchar 5d25c27
docs: Fix stale references left by the extractor move, and two broken…
janbuchar a1f8405
Merge remote-tracking branch 'origin/master' into continued-public-su…
janbuchar 2f1ab9a
Merge remote-tracking branch 'origin/master' into continued-public-su…
janbuchar 7dec8f1
Simplify public-api/README.md
janbuchar 00e3eff
Address review feedback
janbuchar 48aa200
Merge remote-tracking branch 'origin/master' into continued-public-su…
janbuchar d195467
Merge remote-tracking branch 'origin/master' into continued-public-su…
janbuchar 4148e93
Revert inlined RequestListSource
janbuchar 8e90da9
Fix test
janbuchar 5e7d331
Do not expose internal utils
janbuchar 51b0101
Remove docs that suggested you should extend context in FileDownload
janbuchar ac1baa5
Do not accept contextPipelineBuilder in concrete crawler classes
janbuchar d36dffe
docs: fix nits in the upgrading guide and JSDoc
B4nan 4973c49
Merge remote-tracking branch 'origin/master' into continued-public-su…
B4nan 88a1290
docs: drop v4-only changes from the v3 upgrading guide
B4nan 5552c0e
Merge branch 'master' of github.com:apify/crawlee into continued-publ…
B4nan 2c26e61
refactor: run subclass buildContextPipeline overrides in browser craw…
B4nan File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| --- | ||
| id: public-api | ||
| title: Public API | ||
| description: What Crawlee promises not to break, and what it doesn't | ||
| --- | ||
|
|
||
| Crawlee ships its type definitions, and those definitions contain more than its supported API. | ||
| Some of what you can import is a deliberate promise; some of it is machinery that happens to be | ||
| reachable. This page explains how to tell, so you can decide what to depend on. | ||
|
|
||
| ## Supported by default | ||
|
|
||
| Anything Crawlee exports is supported unless it says otherwise. If you can import it and its | ||
| documentation does not mark it as internal, it is covered by backwards compatibility: it will | ||
| not change shape or disappear outside a major release, and if it ever does, the change is | ||
| recorded in the upgrading guide. | ||
|
|
||
| ## Marked internal | ||
|
|
||
| Some members carry an `@internal` tag in their documentation comment. Your editor shows it when | ||
| you hover the symbol, and it means exactly one thing: **we do not promise anything about it.** | ||
| It can change signature, behaviour or disappear entirely in any release, including a patch, and | ||
| it will not appear in the upgrading guide when it does. | ||
|
|
||
| It is still exported, still typed, and auto-completion still works. That is on purpose. We | ||
| would rather leave you a way to unblock yourself — knowingly — than take it away and have you | ||
| patch the package or give up. So the tag is a statement about support, not about access: | ||
|
|
||
| ```ts | ||
| // Fine. Supported, and it will keep working. | ||
| import { CheerioCrawler, Dataset } from 'crawlee'; | ||
|
|
||
| // Allowed, but you are on your own. Pin your Crawlee version | ||
| // and expect to revisit this on every upgrade. | ||
| import { someInternalHelper } from 'crawlee'; | ||
| ``` | ||
|
|
||
| If you find yourself reaching for an internal member to get something done, that is worth | ||
| telling us about, so you should [open an issue](https://github.com/apify/crawlee/issues). Those reports are | ||
| what we use to decide which extension points deserve a real, supported API. | ||
|
|
||
| ## Things that are not types | ||
|
|
||
| Not every promise is expressible in TypeScript, and a few things are contracts even though | ||
| nothing checks them: | ||
|
|
||
| - **Persisted state.** The layout of what Crawlee writes into a key-value store or request | ||
| queue is an implementation detail. Read it for debugging, do not build on it. | ||
| - **Log message text.** Messages change freely; never match on them. | ||
| - **Subclass hook ordering.** When you override a documented extension point, call `super` | ||
| where the base class expects it. Skipping it usually compiles and then misbehaves at runtime. | ||
|
|
||
| ## Where to check | ||
|
|
||
| For anything beyond the obvious, the per-package surface maps under | ||
| [`docs/public-api/`](https://github.com/apify/crawlee/tree/master/docs/public-api) in the | ||
| repository are the authoritative inventory of what we promise. If a symbol is in there, it is | ||
| supported; if not, it is not. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,83 +1,15 @@ | ||
| # Public API surface maps | ||
|
|
||
| Each `*.api.md` file in this folder is a generated **map of the public, type-level | ||
| interface** of one publishable `@crawlee/*` package — every exported class, method, | ||
| property, function, and type, with full signatures. These reports define **where we | ||
| promise backwards compatibility**. | ||
| Each `*.api.md` file here is a generated map of the public, type-level interface of one `@crawlee/*` package. Being in a report is the backwards-compatibility promise; being absent means no promise, not that the symbol is unreachable. See the [Public API guide](../guides/public_api.mdx) for what that means for users. | ||
|
|
||
| They are produced by [API Extractor](https://api-extractor.com/) from the built | ||
| `dist/index.d.ts` of each package. | ||
| - **Untagged** members are promised. The codebase does not use explicit `@public` tags. | ||
| - **`@internal`** (and the legacy `@ignore`) members are trimmed from the report but stay exported and present in the `.d.ts`. Use `#private` / `private` when something should be unreachable, `@internal` when it should be reachable but unsupported. | ||
| - **`@private` is inert**: it does not remove anything from the report. | ||
|
|
||
| ## Workflow | ||
| The reports are generated by [`apify/api-extractor-report`](https://github.com/apify/api-extractor-report); its [README](https://github.com/apify/api-extractor-report#readme) explains how they are produced and what it fixes up in API Extractor's output. Regenerating and CI checks are covered in [CONTRIBUTING.md](https://github.com/apify/crawlee/blob/master/CONTRIBUTING.md#public-api-reports). | ||
|
|
||
| - After changing any package's public surface, regenerate the reports and commit them: | ||
| ## Reading a report | ||
|
|
||
| ```sh | ||
| pnpm build # the reports are generated from dist/ | ||
| pnpm api:extract | ||
| ``` | ||
|
|
||
| - CI runs `pnpm api:check`, which fails if a committed report is out of date. A failing | ||
| check means you changed the public API: either that change is intentional (commit the | ||
| updated report — reviewers will see the surface diff) or it was accidental (fix it). | ||
|
|
||
| - `api:check` also fails if a report ends up referencing a symbol it never declares, which | ||
| leaves the committed map describing a type nothing in it defines. Regenerating cannot fix | ||
| that; it has to be fixed in the source. In practice it means a `@public` symbol's signature | ||
| references an `@internal`/`@ignore`-d one, so the referenced type is trimmed out from under | ||
| it. Either drop the referenced type's tag (it is reachable from the public API, so users can | ||
| already depend on it) or keep it out of the public signature. An untagged symbol is | ||
| implicitly public, which is the convention here — the codebase does not use explicit | ||
| `@public` tags. | ||
|
|
||
| A symbol that is merely missing from the package's exports does **not** need fixing: see the | ||
| note on forgotten exports below. | ||
|
|
||
| ## Notes | ||
|
|
||
| - The reports are generated as API Extractor's **`public`** variant, so symbols tagged | ||
| `@internal` (`@alpha`/`@beta` too) are excluded — only `@public` surface is tracked. | ||
| The legacy `@ignore` tag counts as `@internal` here; the generator rewrites it before | ||
| extraction, so an `@ignore`-d symbol is excluded too and cannot be referenced from a | ||
| `@public` signature. | ||
| The generator stages the variant as `<name>.public.api.md` under `temp/` and promotes it | ||
| onto the committed `<name>.api.md`, so the tracked filenames stay stable. | ||
| - API Extractor builds the import list before it trims the non-`@public` declarations and | ||
| never revisits it, so a type reachable only from an `@internal` member would linger as a | ||
| bare import and read as public surface. There is no config option for this, so the | ||
| generator post-processes each report: it parses the fenced TypeScript and drops imports | ||
| whose binding is referenced by no declaration that survived the trim. | ||
| - **Forgotten exports** — types the public API references but the entry point never exports — | ||
| are included in the report via `includeForgottenExports` and carry an explicit banner: | ||
|
|
||
| ```ts | ||
| // Not exported by the entry point; reachable only as a referenced type. | ||
| // @public (undocumented) | ||
| interface SitemapUrlData { | ||
| ``` | ||
| Their *shape* is part of the surface we promise not to break, but their *name* is not | ||
| importable, so they are emitted without `export`. API Extractor labels them `@public | ||
| (undocumented)` like anything else, which is indistinguishable from a real export at a | ||
| glance, hence the added banner. The alternative was exporting every such type from its | ||
| package — ~38 new public exports, committing us to names we never meant to publish. If you | ||
| *want* one importable, export it deliberately and the report will show it with `export`. | ||
| - Because API Extractor decides both of the above before the `@public` trim, it also offers | ||
| declarations for symbols reachable only from members that never reach the report. The | ||
| generator drops those the same way it drops dead imports, so the report carries nothing it | ||
| does not refer to. Only symbols flagged `ae-forgotten-export` are eligible, which is what | ||
| keeps genuinely reachable declarations (e.g. the `social` namespace in `@crawlee/utils`, | ||
| whose members are exposed through a `declare namespace` block) from being pruned. | ||
| - `docs/public-api/temp/` holds intermediate reports (including the staged `.public.api.md` | ||
| files) and is git-ignored. | ||
| - `@crawlee/cli` and `@crawlee/templates` are deliberately excluded — they are tooling | ||
| (a CLI binary and project scaffolding), not an importable API where we promise BC. The | ||
| exclude list lives in `scripts/api-extractor/run.ts`. | ||
| - The generator lives in `scripts/api-extractor/`. It temporarily strips the build's | ||
| injected `// @ts-ignore` comment lines from the `.d.ts` files (restoring them | ||
| afterwards) because API Extractor's AST walker trips over some of them; a small number | ||
| of packages additionally need a sanitized-mirror fallback. See the comments in | ||
| `scripts/api-extractor/run.ts` for details. | ||
| - These reports now cover only the `@public` surface. Further shrinking them — genuinely | ||
| hiding class internals (untagged `protected`/`_`-prefixed members) rather than merely | ||
| tagging them — is the goal tracked in issue #3109. | ||
| - **Forgotten exports** are types the public API references but the entry point does not export. They appear without `export` under a `// Not exported by the entry point` banner: their shape is promised, their name is not importable. Export one deliberately if it should be. | ||
| - **`crawlee.api.md` is nearly empty on purpose.** The meta-package only has `export *` lines, and everything they re-export is inventoried in the constituent package's report. | ||
| - `@crawlee/cli` and `@crawlee/templates` are excluded: they are tooling, not an importable API. |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we maybe log an event in the json object? Maybe a json logger similar to pino?