Skip to content

ESM support & various other compat improvements #100

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 25 commits into from
Feb 5, 2025
Merged

Conversation

toptobes
Copy link
Collaborator

@toptobes toptobes commented Feb 4, 2025

woohoo yay 100th pr yay whatever ok with that out of the way, this PR:

Allows astra-db-ts to target both CJS & ESM ❗

astra-db-ts has been updated to dual-target both CommonJS (CJS) and ECMAScript Modules (ESM).

While the package itself has been converted into pure ESM, it now transpiles in a way that should seamlessly support both module systems.

Users who were previously using astra-db-ts as CJS may continue to do so without any issues.

Types were verified using @arethetypeswrong/cli and some manual testing.

Import path conversions were done using ts2esm.

The new dist structure looks like so:

dist
|- esm/
|--- *transpiled js files*
|--- package.json containing `{"type":"module"}`
|--- index.d.ts containing `export type * from '../astra-db-ts.d.ts'`
|- cjs/
|--- *transpiled js files*
|--- package.json containing `{"type":"commonjs"}`
|--- index.d.ts containing `export type * from '../astra-db-ts.d.ts'`
|- astra-db-ts.d.ts

And the root package.json was updated to hold the new values:

"type": "module",
"main": "dist/cjs/index.js",
"exports": {
  ".": {
    "require": {
      "types": "./dist/cjs/index.d.ts",
      "default": "./dist/cjs/index.js"
    },
    "import": {
      "types": "./dist/esm/index.d.ts",
      "default": "./dist/esm/index.js"
    }
  },
  "./package.json": "./package.json"
},

ESlint configs were updated to be type-aware

consistent-type-* lints were necessary to update to ESM (requiring types to be explicitly imported/exported with import type/export type)

As a result, this surfaced a wave of new linting errors, which have been fixed—though none of these changes should introduce any functional differences.

Removes hard dependencies on fetch-h2 and events for better environment compatibility

It's simply too painful & error-prone to deal with optional deps between CJS, ESM, and different runtime environments in general

  • require() vs await import()
  • cloudflare events compat only works w/ node:events
  • top-level await not always supported
  • and we don't even speak of AMD or UMD

To simplify everything:

fetch-h2 is no longer the default HTTP client for astra-db-ts.

astra-db-ts now defaults to using the standard fetch API.

If you want to use fetch-h2, you need to install it yourself (npm i fetch-h2) and pass it as an option:

import { DataAPIClient } from '@datastax/astra-db-ts'
import * as fetchH2 from 'fetch-h2'

const client = new DataAPIClient({
   httpOptions: { client: 'fetch-h2', fetchH2 },
});

DataAPIClient is no longer a Node-compliant EventEmitter

It now uses a custom, micro EventEmitter implementation (how original, I know 🙄)

This improves compatibility across different environments while keeping things simple.

// More methods may very well come in the future
declare class MicroEmitters<Events extends Record<string, (...args: any[]) => void>> {
  on  <E extends keyof Events>(event: E, listener: Events[E]): () => void;
  off <E extends keyof Events>(event: E, listener: Events[E]): void;
  once<E extends keyof Events>(event: E, listener: Events[E]): () => void;
  emit<E extends keyof Events>(event: E, ...args: Parameters<Events[E]>): boolean;
}

As a bonus, the typed-emitter dependency was able to be removed, since MicroEmitter is natively typed

Uses tslib w/ importHelpers to save a few bytes of bundle size

yaaaaayyyyyyyy

@toptobes toptobes merged commit caf28e7 into KG-v2.0 Feb 5, 2025
@toptobes toptobes deleted the KG-support-esm branch February 5, 2025 11:45
toptobes added a commit that referenced this pull request Apr 7, 2025
* update eslint config

* run eslint --fix + fix other linting issues

* added & fixed consistent-type-* lints

* migrated source code to esm

* made tests run using tsx/esm import

* removed hard unstable dep on fetch-h2... now defaults to plain fetch by default

* removed hard unstable dep on events... now uses minimal event emitter implementaiton

* added dual support for cjs & esm

* use tslib

* update examples to work with latest version of astra-db-ts

* fixed node10 & node16:cjs type resolution issues

* update examples to reflect new compat changes

* update some http options documentation

* update readme
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.

1 participant