connector.ts 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. // Copyright (c) Jupyter Development Team.
  2. // Distributed under the terms of the Modified BSD License.
  3. import { DataConnector } from '@jupyterlab/statedb';
  4. import { KernelConnector } from './kernelconnector';
  5. import { ContextConnector } from './contextconnector';
  6. import { CompletionHandler } from './handler';
  7. /**
  8. * A context+kernel connector for completion handlers.
  9. */
  10. export class CompletionConnector extends DataConnector<
  11. CompletionHandler.IReply,
  12. void,
  13. CompletionHandler.IRequest
  14. > {
  15. /**
  16. * Create a new connector for completion requests.
  17. *
  18. * @param options - The instatiation options for the connector.
  19. */
  20. constructor(options: CompletionConnector.IOptions) {
  21. super();
  22. this._kernel = new KernelConnector(options);
  23. this._context = new ContextConnector(options);
  24. }
  25. /**
  26. * Fetch completion requests.
  27. *
  28. * @param request - The completion request text and details.
  29. */
  30. fetch(
  31. request: CompletionHandler.IRequest
  32. ): Promise<CompletionHandler.IReply> {
  33. return Promise.all([
  34. this._kernel.fetch(request),
  35. this._context.fetch(request)
  36. ]).then(([kernel, context]) => Private.mergeReplies(kernel, context));
  37. }
  38. private _kernel: KernelConnector;
  39. private _context: ContextConnector;
  40. }
  41. /**
  42. * A namespace for completion connector statics.
  43. */
  44. export namespace CompletionConnector {
  45. /**
  46. * The instantiation options for cell completion handlers.
  47. */
  48. export type IOptions = KernelConnector.IOptions & ContextConnector.IOptions;
  49. }
  50. /**
  51. * A namespace for private functionality.
  52. */
  53. namespace Private {
  54. /**
  55. * Merge results from kernel and context completions.
  56. *
  57. * @param kernel - The kernel reply being merged.
  58. *
  59. * @param context - The context reply being merged.
  60. *
  61. * @returns A reply with a superset of kernel and context matches.
  62. *
  63. * #### Notes
  64. * The kernel and context matches are merged with a preference for kernel
  65. * results. Both lists are known to contain unique, non-repeating items;
  66. * so this function returns a non-repeating superset by filtering out
  67. * duplicates from the context list that appear in the kernel list.
  68. */
  69. export function mergeReplies(
  70. kernel: CompletionHandler.IReply,
  71. context: CompletionHandler.IReply
  72. ): CompletionHandler.IReply {
  73. // If one is empty, return the other.
  74. if (kernel.matches.length === 0) {
  75. return context;
  76. } else if (context.matches.length === 0) {
  77. return kernel;
  78. }
  79. // Populate the result with a copy of the kernel matches.
  80. const matches = kernel.matches.slice();
  81. // Cache all the kernel matches in a memo.
  82. const memo = matches.reduce((acc, val) => {
  83. acc[val] = null;
  84. return acc;
  85. }, {} as { [key: string]: string | null });
  86. // Add each context match that is not in the memo to the result.
  87. context.matches.forEach(match => {
  88. if (!(match in memo)) {
  89. matches.push(match);
  90. }
  91. });
  92. return { ...kernel, matches };
  93. }
  94. }