Apollo Client currently uses the Observable implementation provided by the
zen-observable npm package, since it is small and works well for our
needs. Although zen-observable itself is not written in TypeScript, we
use the companion package @types/zen-observable to provide types.
We are actively considering switching from zen-observable to RxJS (#5749),
though it remains to be seen how much of a breaking change that will be
(and thus whether it makes sense for a minor or major version update).
In the meantime, several issues (most recently #5961) have been opened
pointing out that zen-observable effectively does not support importing
its code as ECMAScript modules, even though it has a separate entry point
(zen-observable/esm.js) that uses ESM syntax.
This is a problem the zen-observable package could easily fix by adding a
"module" field to its package.json, but @abdonrd tried to propose that
change in a PR (as I requested), and has not heard back since June 2020:
zenparsing/zen-observable#74
Fortunately, Apollo maintains an npm package called zen-observable-ts,
which was originally created to provide TypeScript types, before
@types/zen-observable was introduced. This commit revives that wrapper
package, so we can make sure both CommonJS and ESM exports are supported,
with full TypeScript types, until the zen-observable maintainer gets
around to merging that PR.
I considered forking zen-observable, but I'm happy with this wrapping
strategy, since reusing zen-observable makes it easier to take advantage
of any future updates to the zen-observable package.
I also considered using https://www.npmjs.com/package/patch-package to
apply changes to node_modules/zen-observable/package.json upon
installation, but that doesn't really work unless @apollo/client bundles
the zen-observable implementation into itself, since otherwise the
original (unpatched) zen-observable package will continue to be installed
when developers npm install @apollo/client. The patch-package tool is
great, but I don't think it's meant for libraries to use.
Thankfully, this time around we do not need to hand-write the TypeScript
types, since they can be re-exported from @types/zen-observable.
I bumped the major version of zen-observable-ts, since the older versions
(used by apollo-link) still get more than two million downloads per week.
The source code for the zen-observable-ts package can now be found at
https://github.com/apollographql/zen-observable-ts, rather than the old
https://github.com/apollographql/apollo-link monorepo.