Skip to content

Commit

Permalink
fix(config): generate artifacts by respecting the order of transforms…
Browse files Browse the repository at this point in the history
… & sources
  • Loading branch information
ardatan committed Jun 10, 2022
1 parent e8973be commit ed9ba7f
Show file tree
Hide file tree
Showing 15 changed files with 76 additions and 75 deletions.
6 changes: 6 additions & 0 deletions .changeset/khaki-berries-love.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@graphql-mesh/types": patch
"@graphql-mesh/utils": patch
---

Small improvements for relaxing event loop
5 changes: 5 additions & 0 deletions .changeset/proud-terms-peel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@graphql-mesh/config": patch
---

fix(config): generate artifacts by respecting the order of transforms & sources
13 changes: 4 additions & 9 deletions packages/cache/redis/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,10 @@ export default class RedisCache<V = string> implements KeyValueCache<V> {
return new LocalforageCache(options as any) as any;
}
}
const id$ = options.pubsub
.subscribe('destroy', () => {
this.client.disconnect(false);
id$.then(id => options.pubsub.unsubscribe(id)).catch(err => console.error(err));
})
.catch(err => {
console.error(err);
return 0;
});
const id = options.pubsub.subscribe('destroy', () => {
this.client.disconnect(false);
options.pubsub.unsubscribe(id);
});
}

async set(key: string, value: V, options?: KeyValueCacheSetOptions): Promise<void> {
Expand Down
28 changes: 14 additions & 14 deletions packages/config/src/process.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,16 +218,14 @@ export async function processConfig(
if (options.generateCode) {
const transformImportName = pascalCase(transformName + '_Transform');
importCodes.push(`import ${transformImportName} from ${JSON.stringify(moduleName)};`);
codes.push(`${transformsVariableName}.push(
new ${transformImportName}({
codes.push(`${transformsVariableName}[${transformIndex}] = new ${transformImportName}({
apiName: ${JSON.stringify(source.name)},
config: ${JSON.stringify(transformConfig)},
baseDir,
cache,
pubsub,
importFn
})
);`);
});`);
}

return new TransformCtor({
Expand All @@ -243,11 +241,11 @@ export async function processConfig(
]);

if (options.generateCode) {
codes.push(`sources.push({
codes.push(`sources[${sourceIndex}] = {
name: '${source.name}',
handler: ${handlerVariableName},
transforms: ${transformsVariableName}
})`);
}`);
}

return {
Expand All @@ -273,16 +271,14 @@ export async function processConfig(
const transformImportName = pascalCase(transformName + '_Transform');
importCodes.push(`import ${transformImportName} from ${JSON.stringify(moduleName)};`);

codes.push(`transforms.push(
new (${transformImportName} as any)({
codes.push(`transforms[${transformIndex}] = new (${transformImportName} as any)({
apiName: '',
config: ${JSON.stringify(transformConfig)},
baseDir,
cache,
pubsub,
importFn
})
)`);
})`);
}
return new TransformLibrary({
apiName: '',
Expand All @@ -302,7 +298,9 @@ export async function processConfig(
const { importName, moduleName, pluginFactory } = ENVELOP_CORE_PLUGINS_MAP[pluginName];
if (options.generateCode) {
importCodes.push(`import { ${importName} } from ${JSON.stringify(moduleName)};`);
codes.push(`additionalEnvelopPlugins.push(${importName}(${JSON.stringify(pluginConfig, null, 2)}))`);
codes.push(
`additionalEnvelopPlugins[${pluginIndex}] = ${importName}(${JSON.stringify(pluginConfig, null, 2)}))`
);
}
return pluginFactory(pluginConfig);
}
Expand All @@ -320,18 +318,20 @@ export async function processConfig(
if (options.generateCode) {
importName = pascalCase('use_' + pluginName);
importCodes.push(`import ${importName} from ${JSON.stringify(moduleName)};`);
codes.push(`additionalEnvelopPlugins.push(${importName}({
codes.push(`additionalEnvelopPlugins[${pluginIndex}] = ${importName}({
...(${JSON.stringify(pluginConfig, null, 2)}),
logger: logger.child(${JSON.stringify(pluginName)}),
}))`);
})`);
}
} else {
Object.keys(possiblePluginFactory).forEach(key => {
if (key.toString().startsWith('use') && typeof possiblePluginFactory[key] === 'function') {
pluginFactory = possiblePluginFactory[key];
if (options.generateCode) {
importCodes.push(`import { ${importName} } from ${JSON.stringify(moduleName)};`);
codes.push(`additionalEnvelopPlugins.push(${importName}(${JSON.stringify(pluginConfig, null, 2)}])`);
codes.push(
`additionalEnvelopPlugins[${pluginIndex}] = ${importName}(${JSON.stringify(pluginConfig, null, 2)}]`
);
}
}
});
Expand Down
4 changes: 2 additions & 2 deletions packages/handlers/mysql/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -542,9 +542,9 @@ export default class MySQLHandler implements MeshHandler {
);
introspectionConnection.release();

const id$ = this.pubsub.subscribe('destroy', () => {
const id = this.pubsub.subscribe('destroy', () => {
pool.end();
id$.then(id => this.pubsub.unsubscribe(id)).catch(err => console.error(err));
this.pubsub.unsubscribe(id);
});

// graphql-compose doesn't add @defer and @stream to the schema
Expand Down
33 changes: 11 additions & 22 deletions packages/handlers/neo4j/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,19 @@ import { process } from '@graphql-mesh/cross-helpers';
function getEventEmitterFromPubSub(pubsub: MeshPubSub): any {
return {
on(event: string | symbol, listener: (...args: any[]) => void) {
pubsub.subscribe(event.toString(), listener).catch(e => console.error(e));
pubsub.subscribe(event.toString(), listener);
return this;
},
once(event: string | symbol, listener: (...args: any[]) => void) {
let id: number;
pubsub
.subscribe(event.toString(), data => {
listener(data);
pubsub.unsubscribe(id);
})
.then(subId => {
id = subId;
})
.catch(e => console.error(e));
const id = pubsub.subscribe(event.toString(), data => {
listener(data);
pubsub.unsubscribe(id);
});

return this;
},
emit(event: string | symbol, ...args: any[]) {
pubsub.publish(event.toString(), args[0]).catch(e => console.error(e));
pubsub.publish(event.toString(), args[0]);
return true;
},
addListener(event: string | symbol, listener: (...args: any[]) => void) {
Expand Down Expand Up @@ -75,17 +70,11 @@ export default class Neo4JHandler implements MeshHandler {
},
});

const id$ = this.pubsub.subscribe('destroy', () => {
const id = this.pubsub.subscribe('destroy', async () => {
this.pubsub.unsubscribe(id);
this.logger.debug('Closing Neo4j');
driver
.close()
.then(() => {
this.logger.debug('Neo4j has been closed');
})
.catch(error => {
this.logger.debug(`Neo4j couldn't be closed: `, error);
});
id$.then(id => this.pubsub.unsubscribe(id)).catch(err => console.error(err));
await driver.close();
this.logger.debug('Neo4j closed');
});

const typeDefs = await this.getCachedTypeDefs(driver);
Expand Down
4 changes: 2 additions & 2 deletions packages/handlers/postgraphile/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,10 @@ export default class PostGraphileHandler implements MeshHandler {
});
}

const id$ = this.pubsub.subscribe('destroy', () => {
const id = this.pubsub.subscribe('destroy', () => {
this.pubsub.unsubscribe(id);
this.logger.debug('Destroying PostgreSQL pool');
pgPool.end();
id$.then(id => this.pubsub.unsubscribe(id)).catch(err => console.error(err));
});

const cacheKey = this.name + '_introspection.json';
Expand Down
6 changes: 3 additions & 3 deletions packages/mergers/federation/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,9 @@ export default class FederationMerger implements MeshMerger {
},
batch: true,
});
const id$ = this.pubsub.subscribe('destroy', () => {
gateway.stop().catch(err => this.logger.error(err));
id$.then(id => this.pubsub.unsubscribe(id)).catch(err => console.error(err));
const id = this.pubsub.subscribe('destroy', async () => {
this.pubsub.unsubscribe(id);
await gateway.stop();
});
this.logger.debug(`Applying additionalTypeDefs`);
typeDefs?.forEach(typeDef => {
Expand Down
4 changes: 2 additions & 2 deletions packages/testing/getTestMesh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ export async function getTestMesh() {
validate: false,
});
await yoga.start();
const subId$ = pubsub.subscribe('destroy', async () => {
const subId = pubsub.subscribe('destroy', async () => {
pubsub.unsubscribe(subId);
await yoga.stop();
subId$.then(subId => pubsub.unsubscribe(subId)).catch(err => console.error(err));
});
const mesh = await getMesh({
sources: [
Expand Down
4 changes: 2 additions & 2 deletions packages/transforms/cache/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,8 @@ export default class CacheTransform implements MeshTransform {

private waitAndReturn(pubsubTopic: string) {
return new Promise((resolve, reject) => {
const subId$ = this.options.pubsub.subscribe(pubsubTopic, async ({ result, error }) => {
subId$.then(subId => this.options.pubsub.unsubscribe(subId));
const subId = this.options.pubsub.subscribe(pubsubTopic, ({ result, error }) => {
this.options.pubsub.unsubscribe(subId);

if (error) {
reject(error);
Expand Down
4 changes: 2 additions & 2 deletions packages/transforms/rate-limit/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ export default class RateLimitTransform implements MeshTransform {
});
}
if (options.pubsub) {
const id$ = options.pubsub.subscribe('destroy', () => {
const id = options.pubsub.subscribe('destroy', () => {
options.pubsub.unsubscribe(id);
this.timeouts.forEach(timeout => clearTimeout(timeout));
id$.then(id => options.pubsub.unsubscribe(id)).catch(err => console.error(err));
});
}
}
Expand Down
4 changes: 1 addition & 3 deletions packages/transforms/rate-limit/tests/rate-limit.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@ describe('Rate Limit Transform', () => {
});

afterEach(() => {
pubsub
.publish('destroy', {} as any)
.catch(e => console.warn(`Error on emitting destroy: ${e.stack || e.message || e}`));
pubsub.publish('destroy', {} as any);
});

const baseDir = process.cwd();
Expand Down
2 changes: 1 addition & 1 deletion packages/types/src/config-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,7 @@
"description": "Handler for gRPC and Protobuf schemas"
},
"jsonSchema": {
"description": "Handler for JSON Schema specification. Source could be a local json file, or a url to it. (Any of: JsonSchemaHandler, JsonSchemaHandlerBundle)",
"description": "Handler for JSON Schema specification.\nSource could be a local json file, or a url to it. (Any of: JsonSchemaHandler, JsonSchemaHandlerBundle)",
"anyOf": [
{
"$ref": "#/definitions/JsonSchemaHandler"
Expand Down
3 changes: 2 additions & 1 deletion packages/types/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,8 @@ export interface Handler {
| GraphQLHandlerMultipleHTTPConfiguration;
grpc?: GrpcHandler;
/**
* Handler for JSON Schema specification. Source could be a local json file, or a url to it. (Any of: JsonSchemaHandler, JsonSchemaHandlerBundle)
* Handler for JSON Schema specification.
* Source could be a local json file, or a url to it. (Any of: JsonSchemaHandler, JsonSchemaHandlerBundle)
*/
jsonSchema?: JsonSchemaHandler | JsonSchemaHandlerBundle;
mongoose?: MongooseHandler;
Expand Down
31 changes: 19 additions & 12 deletions website/docs/generated-markdown/JsonSchemaHandler.generated.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,21 @@
* `schemaHeaders` (type: `JSON`)
* `operations` - (required) Array of:
* `object`:
* `field` (type: `String`, required)
* `description` (type: `String`)
* `type` (type: `String (Query | Mutation | Subscription)`, required)
* `requestSchema` (type: `Any`)
* `requestSample` (type: `Any`)
* `requestTypeName` (type: `String`)
* `requestBaseBody` (type: `Any`) - This body will be merged with the request body sent with the underlying HTTP request
* `responseSchema` (type: `Any`)
* `responseSample` (type: `Any`)
* `responseTypeName` (type: `String`)
* `field` (type: `String`, required) - This Field based on the field name of the URL path.
Example: "https://MyAPIURL.com/FieldNameHere/",
so we will set the "field: FieldNameHere".
* `description` (type: `String`) - Your chance to describe the operation!
Make sure the description is clear and concise.
* `type` (type: `String (Query | Mutation | Subscription)`, required) - Type field is set the opertion type: Query, Mutation or Subscription.
* `requestSchema` (type: `Any`) - Your chance to provide request schema name.
* `requestSample` (type: `Any`) - The path definition of the JSON Schema sample.
Example: "./jsons/questions.response.json".
* `requestTypeName` (type: `String`) - Inset any name for the type of the request body.
* `requestBaseBody` (type: `Any`) - This body will be merged with the request body sent with
the underlying HTTP request
* `responseSchema` (type: `Any`) - Yay! Now you can provide the response schema name.
* `responseSample` (type: `Any`) - Did you use Sample? Provide the respone sample path.
* `responseTypeName` (type: `String`) - Inset any name for the type of the response body.
* `responseByStatusCode` (type: `Any`) - You can define your response schemas by status codes;

responseByStatusCode:
Expand All @@ -22,7 +27,8 @@ responseByStatusCode:
404:
responseSample: ./error-sample.json
responseTypeName: MyError
* `argTypeMap` (type: `JSON`)
* `argTypeMap` (type: `JSON`) - Mapping the JSON Schema and define the arguments of the operation.
Example: 'argTypeMap: ID: String'
* `path` (type: `String`, required)
* `method` (type: `String (GET | HEAD | POST | PUT | DELETE | CONNECT | OPTIONS | TRACE | PATCH)`)
* `headers` (type: `JSON`)
Expand All @@ -36,7 +42,8 @@ unless you define an explicit Content-Type header
* `requestSchema` (type: `Any`)
* `requestSample` (type: `Any`)
* `requestTypeName` (type: `String`)
* `requestBaseBody` (type: `Any`) - This body will be merged with the request body sent with the underlying HTTP request
* `requestBaseBody` (type: `Any`) - This body will be merged with the request body sent with
the underlying HTTP request
* `responseSchema` (type: `Any`)
* `responseSample` (type: `Any`)
* `responseTypeName` (type: `String`)
Expand Down

0 comments on commit ed9ba7f

Please sign in to comment.