diff --git a/.changeset/gold-ears-knock.md b/.changeset/gold-ears-knock.md new file mode 100644 index 0000000000..7b2fb021fa --- /dev/null +++ b/.changeset/gold-ears-knock.md @@ -0,0 +1,7 @@ +--- +'@graphiql/toolkit': minor +--- + +do not include `require` statements in ESM build, include `import` in esm and `require` in cjs builds + +make `getWsFetcher`, `createWebsocketsFetcherFromUrl` async diff --git a/packages/graphiql-toolkit/src/create-fetcher/__tests__/lib.spec.ts b/packages/graphiql-toolkit/src/create-fetcher/__tests__/lib.spec.ts index 11a261e8ac..921ffcaebf 100644 --- a/packages/graphiql-toolkit/src/create-fetcher/__tests__/lib.spec.ts +++ b/packages/graphiql-toolkit/src/create-fetcher/__tests__/lib.spec.ts @@ -15,7 +15,7 @@ import { createClient } from 'graphql-ws'; import { SubscriptionClient } from 'subscriptions-transport-ws'; -const exampleWithSubscription = /* GraphQL */ parse(` +const exampleWithSubscription = parse(/* GraphQL */ ` subscription Example { example } @@ -47,9 +47,9 @@ describe('createWebsocketsFetcherFromUrl', () => { jest.resetAllMocks(); }); - it('creates a websockets client using provided url', () => { + it('creates a websockets client using provided url', async () => { createClient.mockReturnValue(true); - createWebsocketsFetcherFromUrl('wss://example.com'); + await createWebsocketsFetcherFromUrl('wss://example.com'); // @ts-ignore expect(createClient.mock.calls[0][0]).toEqual({ url: 'wss://example.com' }); }); @@ -66,23 +66,23 @@ describe('getWsFetcher', () => { afterEach(() => { jest.resetAllMocks(); }); - it('provides an observable wsClient when custom wsClient option is provided', () => { + it('provides an observable wsClient when custom wsClient option is provided', async () => { createClient.mockReturnValue(true); - getWsFetcher({ url: '', wsClient: true }); + await getWsFetcher({ url: '', wsClient: true }); // @ts-ignore expect(createClient.mock.calls).toHaveLength(0); }); - it('creates a subscriptions-transports-ws observable when custom legacyClient option is provided', () => { + it('creates a subscriptions-transports-ws observable when custom legacyClient option is provided', async () => { createClient.mockReturnValue(true); - getWsFetcher({ url: '', legacyClient: true }); + await getWsFetcher({ url: '', legacyClient: true }); // @ts-ignore expect(createClient.mock.calls).toHaveLength(0); expect(SubscriptionClient.mock.calls).toHaveLength(0); }); - it('if subscriptionsUrl is provided, create a client on the fly', () => { + it('if subscriptionsUrl is provided, create a client on the fly', async () => { createClient.mockReturnValue(true); - getWsFetcher({ url: '', subscriptionUrl: 'wss://example' }); + await getWsFetcher({ url: '', subscriptionUrl: 'wss://example' }); expect(createClient.mock.calls[0]).toEqual([ { connectionParams: {}, url: 'wss://example' }, ]); @@ -90,15 +90,17 @@ describe('getWsFetcher', () => { }); }); -describe('missing graphql-ws dependency', () => { - it('should throw a nice error', () => { +describe('missing `graphql-ws` dependency', () => { + it('should throw a nice error', async () => { jest.resetModules(); jest.doMock('graphql-ws', () => { // eslint-disable-next-line no-throw-literal throw { code: 'MODULE_NOT_FOUND' }; }); - expect(() => createWebsocketsFetcherFromUrl('wss://example.com')).toThrow( + await expect( + createWebsocketsFetcherFromUrl('wss://example.com'), + ).rejects.toThrow( /You need to install the 'graphql-ws' package to use websockets when passing a 'subscriptionUrl'/, ); }); diff --git a/packages/graphiql-toolkit/src/create-fetcher/createFetcher.ts b/packages/graphiql-toolkit/src/create-fetcher/createFetcher.ts index 0ddcdf99df..b90c65ee83 100644 --- a/packages/graphiql-toolkit/src/create-fetcher/createFetcher.ts +++ b/packages/graphiql-toolkit/src/create-fetcher/createFetcher.ts @@ -27,7 +27,7 @@ export function createGraphiQLFetcher(options: CreateFetcherOptions): Fetcher { ? createMultipartFetcher(options, httpFetch) : simpleFetcher; - return (graphQLParams, fetcherOpts) => { + return async (graphQLParams, fetcherOpts) => { if (graphQLParams.operationName === 'IntrospectionQuery') { return (options.schemaFetcher || simpleFetcher)( graphQLParams, @@ -41,7 +41,7 @@ export function createGraphiQLFetcher(options: CreateFetcherOptions): Fetcher { ) : false; if (isSubscription) { - const wsFetcher = getWsFetcher(options, fetcherOpts); + const wsFetcher = await getWsFetcher(options, fetcherOpts); if (!wsFetcher) { throw new Error( diff --git a/packages/graphiql-toolkit/src/create-fetcher/lib.ts b/packages/graphiql-toolkit/src/create-fetcher/lib.ts index 60dd880c1d..f0f1f20867 100644 --- a/packages/graphiql-toolkit/src/create-fetcher/lib.ts +++ b/packages/graphiql-toolkit/src/create-fetcher/lib.ts @@ -68,15 +68,16 @@ export const createSimpleFetcher = return data.json(); }; -export const createWebsocketsFetcherFromUrl = ( +export async function createWebsocketsFetcherFromUrl( url: string, connectionParams?: ClientOptions['connectionParams'], -) => { +): Promise { let wsClient; try { - const { createClient } = require('graphql-ws') as { - createClient: typeof createClientType; - }; + const { createClient } = + process.env.USE_IMPORT === 'false' + ? (require('graphql-ws') as { createClient: typeof createClientType }) + : await import('graphql-ws'); // TODO: defaults? wsClient = createClient({ url, connectionParams }); @@ -90,7 +91,7 @@ export const createWebsocketsFetcherFromUrl = ( // eslint-disable-next-line no-console console.error(`Error creating websocket client for ${url}`, err); } -}; +} /** * Create ws/s fetcher using provided wsClient implementation @@ -177,10 +178,10 @@ export const createMultipartFetcher = ( /** * If `wsClient` or `legacyClient` are provided, then `subscriptionUrl` is overridden. */ -export const getWsFetcher = ( +export async function getWsFetcher( options: CreateFetcherOptions, fetcherOpts?: FetcherOpts, -): Fetcher | void => { +): Promise { if (options.wsClient) { return createWebsocketsFetcherFromClient(options.wsClient); } @@ -194,4 +195,4 @@ export const getWsFetcher = ( if (legacyWebsocketsClient) { return createLegacyWebsocketsFetcher(legacyWebsocketsClient); } -}; +} diff --git a/packages/graphiql-toolkit/tsconfig.json b/packages/graphiql-toolkit/tsconfig.json index c0d02ccc11..9209de32b2 100644 --- a/packages/graphiql-toolkit/tsconfig.json +++ b/packages/graphiql-toolkit/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "target": "es2016", + "target": "es2017", "module": "ESNext", "declaration": true, "noEmit": true, diff --git a/packages/graphiql-toolkit/tsup.config.ts b/packages/graphiql-toolkit/tsup.config.ts index c40cc74c1b..a4d1c15b46 100644 --- a/packages/graphiql-toolkit/tsup.config.ts +++ b/packages/graphiql-toolkit/tsup.config.ts @@ -5,6 +5,7 @@ const opts: Options = { bundle: false, clean: true, dts: true, + minifySyntax: true, }; export default defineConfig([ @@ -13,10 +14,16 @@ export default defineConfig([ format: 'esm', outDir: 'dist/esm', outExtension: () => ({ js: '.js' }), + env: { + USE_IMPORT: 'true', + }, }, { ...opts, format: 'cjs', outDir: 'dist/cjs', + env: { + USE_IMPORT: 'false', + }, }, ]); diff --git a/packages/monaco-graphql/test/monaco-editor.test.ts b/packages/monaco-graphql/test/monaco-editor.test.ts index 88151941ec..b9fc918b87 100644 --- a/packages/monaco-graphql/test/monaco-editor.test.ts +++ b/packages/monaco-graphql/test/monaco-editor.test.ts @@ -15,7 +15,7 @@ describe('monaco-editor', () => { // expect(lines[1]).toMatch(' building for production...'); // expect(lines[2]).toBe('transforming...'); expect(lines[3]).toMatch( - `✓ ${parseInt(version, 10) > 16 ? 857 : 843} modules transformed.`, + `✓ ${parseInt(version, 10) > 16 ? 862 : 843} modules transformed.`, ); // expect(lines[4]).toBe('rendering chunks...'); // expect(lines[5]).toBe('computing gzip size...');