UNPKG

@valtown/codemirror-codeium

Version:

codemirror integration for codeium

95 lines 3.48 kB
import { createPromiseClient } from "@connectrpc/connect"; import { LanguageServerService } from "./api/proto/exa/language_server_pb/language_server_connect.js"; import { createConnectTransport } from "@connectrpc/connect-web"; // This is the same as the monaco editor example const transport = createConnectTransport({ baseUrl: "https://web-backend.codeium.com", useBinaryFormat: true, }); const client = createPromiseClient(LanguageServerService, transport); let sessionId; try { /** * Note that this won't be available in 'insecure contexts', * websites served under HTTP not HTTPS, but those are rare. * And it'll work in localhost for development. */ sessionId = crypto.randomUUID(); } catch { // When not in a secure context // https://stackoverflow.com/questions/105034/how-do-i-create-a-guid-uuid function uuidv4() { return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, c => (+c ^ (crypto.getRandomValues(new Uint8Array(1))[0] ?? 0) & 15 >> +c / 4).toString(16)); } sessionId = uuidv4(); } export async function getCodeiumCompletions({ text, cursorOffset, config, otherDocuments, }) { return (await client.getCompletions({ metadata: { ideName: "web", ideVersion: "0.0.5", extensionName: "@valtown/codemirror-codeium", extensionVersion: "1.0.0", apiKey: config.apiKey, sessionId: sessionId, authSource: config.authSource, }, document: { text: text, cursorOffset: BigInt(cursorOffset), language: config.language, // TODO: not sure why we have both language and // editorlanguage // The types don't like this here, but it works. editorLanguage: "typescript", lineEnding: "\n", }, editorOptions: { tabSize: 2n, insertSpaces: true, }, otherDocuments: otherDocuments, multilineConfig: undefined, }, { // signal, headers: { Authorization: `Basic ${config.apiKey}-${sessionId}`, }, })); } /** * Make the body of the response a bit easier to work with: * turn a BigInt into an int in the response so that it can * be used with CodeMirror directly, and avoid using some * complex kinds of completions. */ export function completionsToChangeSpec(completions) { return completions.completionItems.map((item) => { /** * Add absolute offsets for the suggestion text insertions * so that we can add matching decorations. */ let combinedOffset = 0; return item.completionParts .filter((part) => { // Type 3 overwrites existing text. Maybe we need this eventually, // but not right now and it usually is duplicative. return part.type !== 3; }) .map((part) => { const offset = Number(part.offset); const text = part.type === 2 ? `\n${part.text}` : part.text; const res = { absoluteStartPos: combinedOffset + offset, absoluteEndPos: combinedOffset + offset + text.length, from: offset, to: offset, insert: text, }; combinedOffset += text.length; return res; }); }); } //# sourceMappingURL=codeium.js.map