schemaManager.js 3.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. export class SchemaManager {
  2. constructor(options) {
  3. this.onSchemaLoadOrUpdateListeners = new Set();
  4. this.isStopped = false;
  5. this.logger = options.logger;
  6. this.schemaDerivedDataProvider = options.schemaDerivedDataProvider;
  7. if ('gateway' in options) {
  8. this.modeSpecificState = {
  9. mode: 'gateway',
  10. gateway: options.gateway,
  11. apolloConfig: options.apolloConfig,
  12. };
  13. }
  14. else {
  15. this.modeSpecificState = {
  16. mode: 'schema',
  17. apiSchema: options.apiSchema,
  18. schemaDerivedData: options.schemaDerivedDataProvider(options.apiSchema),
  19. };
  20. }
  21. }
  22. async start() {
  23. if (this.modeSpecificState.mode === 'gateway') {
  24. const gateway = this.modeSpecificState.gateway;
  25. if (gateway.onSchemaLoadOrUpdate) {
  26. this.modeSpecificState.unsubscribeFromGateway =
  27. gateway.onSchemaLoadOrUpdate((schemaContext) => {
  28. this.processSchemaLoadOrUpdateEvent(schemaContext);
  29. });
  30. }
  31. else {
  32. throw new Error("Unexpectedly couldn't find onSchemaLoadOrUpdate on gateway");
  33. }
  34. const config = await this.modeSpecificState.gateway.load({
  35. apollo: this.modeSpecificState.apolloConfig,
  36. });
  37. return config.executor;
  38. }
  39. else {
  40. this.processSchemaLoadOrUpdateEvent({
  41. apiSchema: this.modeSpecificState.apiSchema,
  42. }, this.modeSpecificState.schemaDerivedData);
  43. return null;
  44. }
  45. }
  46. onSchemaLoadOrUpdate(callback) {
  47. if (!this.schemaContext) {
  48. throw new Error('You must call start() before onSchemaLoadOrUpdate()');
  49. }
  50. if (!this.isStopped) {
  51. try {
  52. callback(this.schemaContext);
  53. }
  54. catch (e) {
  55. throw new Error(`An error was thrown from an 'onSchemaLoadOrUpdate' listener: ${e.message}`);
  56. }
  57. }
  58. this.onSchemaLoadOrUpdateListeners.add(callback);
  59. return () => {
  60. this.onSchemaLoadOrUpdateListeners.delete(callback);
  61. };
  62. }
  63. getSchemaDerivedData() {
  64. if (!this.schemaDerivedData) {
  65. throw new Error('You must call start() before getSchemaDerivedData()');
  66. }
  67. return this.schemaDerivedData;
  68. }
  69. async stop() {
  70. this.isStopped = true;
  71. if (this.modeSpecificState.mode === 'gateway') {
  72. this.modeSpecificState.unsubscribeFromGateway?.();
  73. await this.modeSpecificState.gateway.stop?.();
  74. }
  75. }
  76. processSchemaLoadOrUpdateEvent(schemaContext, schemaDerivedData) {
  77. if (!this.isStopped) {
  78. this.schemaDerivedData =
  79. schemaDerivedData ??
  80. this.schemaDerivedDataProvider(schemaContext.apiSchema);
  81. this.schemaContext = schemaContext;
  82. this.onSchemaLoadOrUpdateListeners.forEach((listener) => {
  83. try {
  84. listener(schemaContext);
  85. }
  86. catch (e) {
  87. this.logger.error("An error was thrown from an 'onSchemaLoadOrUpdate' listener");
  88. this.logger.error(e);
  89. }
  90. });
  91. }
  92. }
  93. }
  94. //# sourceMappingURL=schemaManager.js.map