@lvce-editor/text-search-worker
Version:
Text Search Worker
1,920 lines (1,866 loc) • 159 kB
JavaScript
const normalizeLine = line => {
if (line.startsWith('Error: ')) {
return line.slice('Error: '.length);
}
if (line.startsWith('VError: ')) {
return line.slice('VError: '.length);
}
return line;
};
const getCombinedMessage = (error, message) => {
const stringifiedError = normalizeLine(`${error}`);
if (message) {
return `${message}: ${stringifiedError}`;
}
return stringifiedError;
};
const NewLine$2 = '\n';
const getNewLineIndex$1 = (string, startIndex = undefined) => {
return string.indexOf(NewLine$2, startIndex);
};
const mergeStacks = (parent, child) => {
if (!child) {
return parent;
}
const parentNewLineIndex = getNewLineIndex$1(parent);
const childNewLineIndex = getNewLineIndex$1(child);
if (childNewLineIndex === -1) {
return parent;
}
const parentFirstLine = parent.slice(0, parentNewLineIndex);
const childRest = child.slice(childNewLineIndex);
const childFirstLine = normalizeLine(child.slice(0, childNewLineIndex));
if (parentFirstLine.includes(childFirstLine)) {
return parentFirstLine + childRest;
}
return child;
};
class VError extends Error {
constructor(error, message) {
const combinedMessage = getCombinedMessage(error, message);
super(combinedMessage);
this.name = 'VError';
if (error instanceof Error) {
this.stack = mergeStacks(this.stack, error.stack);
}
if (error.codeFrame) {
// @ts-ignore
this.codeFrame = error.codeFrame;
}
if (error.code) {
// @ts-ignore
this.code = error.code;
}
}
}
class AssertionError extends Error {
constructor(message) {
super(message);
this.name = 'AssertionError';
}
}
const Object$1 = 1;
const Number$1 = 2;
const Array$1 = 3;
const String = 4;
const Boolean$1 = 5;
const Function = 6;
const Null = 7;
const Unknown = 8;
const getType = value => {
switch (typeof value) {
case 'number':
return Number$1;
case 'function':
return Function;
case 'string':
return String;
case 'object':
if (value === null) {
return Null;
}
if (Array.isArray(value)) {
return Array$1;
}
return Object$1;
case 'boolean':
return Boolean$1;
default:
return Unknown;
}
};
const object = value => {
const type = getType(value);
if (type !== Object$1) {
throw new AssertionError('expected value to be of type object');
}
};
const number = value => {
const type = getType(value);
if (type !== Number$1) {
throw new AssertionError('expected value to be of type number');
}
};
const array = value => {
const type = getType(value);
if (type !== Array$1) {
throw new AssertionError('expected value to be of type array');
}
};
const string = value => {
const type = getType(value);
if (type !== String) {
throw new AssertionError('expected value to be of type string');
}
};
const isMessagePort = value => {
return value && value instanceof MessagePort;
};
const isMessagePortMain = value => {
return value && value.constructor && value.constructor.name === 'MessagePortMain';
};
const isOffscreenCanvas = value => {
return typeof OffscreenCanvas !== 'undefined' && value instanceof OffscreenCanvas;
};
const isInstanceOf = (value, constructorName) => {
return value?.constructor?.name === constructorName;
};
const isSocket = value => {
return isInstanceOf(value, 'Socket');
};
const transferrables = [isMessagePort, isMessagePortMain, isOffscreenCanvas, isSocket];
const isTransferrable = value => {
for (const fn of transferrables) {
if (fn(value)) {
return true;
}
}
return false;
};
const walkValue = (value, transferrables, isTransferrable) => {
if (!value) {
return;
}
if (isTransferrable(value)) {
transferrables.push(value);
return;
}
if (Array.isArray(value)) {
for (const item of value) {
walkValue(item, transferrables, isTransferrable);
}
return;
}
if (typeof value === 'object') {
for (const property of Object.values(value)) {
walkValue(property, transferrables, isTransferrable);
}
return;
}
};
const getTransferrables = value => {
const transferrables = [];
walkValue(value, transferrables, isTransferrable);
return transferrables;
};
const attachEvents = that => {
const handleMessage = (...args) => {
const data = that.getData(...args);
that.dispatchEvent(new MessageEvent('message', {
data
}));
};
that.onMessage(handleMessage);
const handleClose = event => {
that.dispatchEvent(new Event('close'));
};
that.onClose(handleClose);
};
class Ipc extends EventTarget {
constructor(rawIpc) {
super();
this._rawIpc = rawIpc;
attachEvents(this);
}
}
const E_INCOMPATIBLE_NATIVE_MODULE = 'E_INCOMPATIBLE_NATIVE_MODULE';
const E_MODULES_NOT_SUPPORTED_IN_ELECTRON = 'E_MODULES_NOT_SUPPORTED_IN_ELECTRON';
const ERR_MODULE_NOT_FOUND = 'ERR_MODULE_NOT_FOUND';
const NewLine$1 = '\n';
const joinLines$1 = lines => {
return lines.join(NewLine$1);
};
const RE_AT = /^\s+at/;
const RE_AT_PROMISE_INDEX = /^\s*at async Promise.all \(index \d+\)$/;
const isNormalStackLine = line => {
return RE_AT.test(line) && !RE_AT_PROMISE_INDEX.test(line);
};
const getDetails = lines => {
const index = lines.findIndex(isNormalStackLine);
if (index === -1) {
return {
actualMessage: joinLines$1(lines),
rest: []
};
}
let lastIndex = index - 1;
while (++lastIndex < lines.length) {
if (!isNormalStackLine(lines[lastIndex])) {
break;
}
}
return {
actualMessage: lines[index - 1],
rest: lines.slice(index, lastIndex)
};
};
const splitLines$1 = lines => {
return lines.split(NewLine$1);
};
const RE_MESSAGE_CODE_BLOCK_START = /^Error: The module '.*'$/;
const RE_MESSAGE_CODE_BLOCK_END = /^\s* at/;
const isMessageCodeBlockStartIndex = line => {
return RE_MESSAGE_CODE_BLOCK_START.test(line);
};
const isMessageCodeBlockEndIndex = line => {
return RE_MESSAGE_CODE_BLOCK_END.test(line);
};
const getMessageCodeBlock = stderr => {
const lines = splitLines$1(stderr);
const startIndex = lines.findIndex(isMessageCodeBlockStartIndex);
const endIndex = startIndex + lines.slice(startIndex).findIndex(isMessageCodeBlockEndIndex, startIndex);
const relevantLines = lines.slice(startIndex, endIndex);
const relevantMessage = relevantLines.join(' ').slice('Error: '.length);
return relevantMessage;
};
const isModuleNotFoundMessage = line => {
return line.includes('[ERR_MODULE_NOT_FOUND]');
};
const getModuleNotFoundError = stderr => {
const lines = splitLines$1(stderr);
const messageIndex = lines.findIndex(isModuleNotFoundMessage);
const message = lines[messageIndex];
return {
code: ERR_MODULE_NOT_FOUND,
message
};
};
const isModuleNotFoundError = stderr => {
if (!stderr) {
return false;
}
return stderr.includes('ERR_MODULE_NOT_FOUND');
};
const isModulesSyntaxError = stderr => {
if (!stderr) {
return false;
}
return stderr.includes('SyntaxError: Cannot use import statement outside a module');
};
const RE_NATIVE_MODULE_ERROR = /^innerError Error: Cannot find module '.*.node'/;
const RE_NATIVE_MODULE_ERROR_2 = /was compiled against a different Node.js version/;
const isUnhelpfulNativeModuleError = stderr => {
return RE_NATIVE_MODULE_ERROR.test(stderr) && RE_NATIVE_MODULE_ERROR_2.test(stderr);
};
const getNativeModuleErrorMessage = stderr => {
const message = getMessageCodeBlock(stderr);
return {
code: E_INCOMPATIBLE_NATIVE_MODULE,
message: `Incompatible native node module: ${message}`
};
};
const getModuleSyntaxError = () => {
return {
code: E_MODULES_NOT_SUPPORTED_IN_ELECTRON,
message: `ES Modules are not supported in electron`
};
};
const getHelpfulChildProcessError = (stdout, stderr) => {
if (isUnhelpfulNativeModuleError(stderr)) {
return getNativeModuleErrorMessage(stderr);
}
if (isModulesSyntaxError(stderr)) {
return getModuleSyntaxError();
}
if (isModuleNotFoundError(stderr)) {
return getModuleNotFoundError(stderr);
}
const lines = splitLines$1(stderr);
const {
actualMessage,
rest
} = getDetails(lines);
return {
code: '',
message: actualMessage,
stack: rest
};
};
class IpcError extends VError {
// @ts-ignore
constructor(betterMessage, stdout = '', stderr = '') {
if (stdout || stderr) {
// @ts-ignore
const {
code,
message,
stack
} = getHelpfulChildProcessError(stdout, stderr);
const cause = new Error(message);
// @ts-ignore
cause.code = code;
cause.stack = stack;
super(cause, betterMessage);
} else {
super(betterMessage);
}
// @ts-ignore
this.name = 'IpcError';
// @ts-ignore
this.stdout = stdout;
// @ts-ignore
this.stderr = stderr;
}
}
const readyMessage = 'ready';
const getData$2 = event => {
return event.data;
};
const listen$7 = () => {
// @ts-ignore
if (typeof WorkerGlobalScope === 'undefined') {
throw new TypeError('module is not in web worker scope');
}
return globalThis;
};
const signal$8 = global => {
global.postMessage(readyMessage);
};
class IpcChildWithModuleWorker extends Ipc {
getData(event) {
return getData$2(event);
}
send(message) {
// @ts-ignore
this._rawIpc.postMessage(message);
}
sendAndTransfer(message) {
const transfer = getTransferrables(message);
// @ts-ignore
this._rawIpc.postMessage(message, transfer);
}
dispose() {
// ignore
}
onClose(callback) {
// ignore
}
onMessage(callback) {
this._rawIpc.addEventListener('message', callback);
}
}
const wrap$f = global => {
return new IpcChildWithModuleWorker(global);
};
const waitForFirstMessage = async port => {
const {
promise,
resolve
} = Promise.withResolvers();
port.addEventListener('message', resolve, {
once: true
});
const event = await promise;
// @ts-ignore
return event.data;
};
const listen$6 = async () => {
const parentIpcRaw = listen$7();
signal$8(parentIpcRaw);
const parentIpc = wrap$f(parentIpcRaw);
const firstMessage = await waitForFirstMessage(parentIpc);
if (firstMessage.method !== 'initialize') {
throw new IpcError('unexpected first message');
}
const type = firstMessage.params[0];
if (type === 'message-port') {
parentIpc.send({
id: firstMessage.id,
jsonrpc: '2.0',
result: null
});
parentIpc.dispose();
const port = firstMessage.params[1];
return port;
}
return globalThis;
};
class IpcChildWithModuleWorkerAndMessagePort extends Ipc {
getData(event) {
return getData$2(event);
}
send(message) {
this._rawIpc.postMessage(message);
}
sendAndTransfer(message) {
const transfer = getTransferrables(message);
this._rawIpc.postMessage(message, transfer);
}
dispose() {
if (this._rawIpc.close) {
this._rawIpc.close();
}
}
onClose(callback) {
// ignore
}
onMessage(callback) {
this._rawIpc.addEventListener('message', callback);
this._rawIpc.start();
}
}
const wrap$e = port => {
return new IpcChildWithModuleWorkerAndMessagePort(port);
};
const IpcChildWithModuleWorkerAndMessagePort$1 = {
__proto__: null,
listen: listen$6,
wrap: wrap$e
};
const Error$3 = 1;
const Open = 2;
const Close = 3;
const addListener = (emitter, type, callback) => {
if ('addEventListener' in emitter) {
emitter.addEventListener(type, callback);
} else {
emitter.on(type, callback);
}
};
const removeListener = (emitter, type, callback) => {
if ('removeEventListener' in emitter) {
emitter.removeEventListener(type, callback);
} else {
emitter.off(type, callback);
}
};
const getFirstEvent = (eventEmitter, eventMap) => {
const {
promise,
resolve
} = Promise.withResolvers();
const listenerMap = Object.create(null);
const cleanup = value => {
for (const event of Object.keys(eventMap)) {
removeListener(eventEmitter, event, listenerMap[event]);
}
resolve(value);
};
for (const [event, type] of Object.entries(eventMap)) {
const listener = event => {
cleanup({
event,
type
});
};
addListener(eventEmitter, event, listener);
listenerMap[event] = listener;
}
return promise;
};
const Message$1 = 3;
const create$5$1 = async ({
isMessagePortOpen,
messagePort
}) => {
if (!isMessagePort(messagePort)) {
throw new IpcError('port must be of type MessagePort');
}
if (isMessagePortOpen) {
return messagePort;
}
const eventPromise = getFirstEvent(messagePort, {
message: Message$1
});
messagePort.start();
const {
event,
type
} = await eventPromise;
if (type !== Message$1) {
throw new IpcError('Failed to wait for ipc message');
}
if (event.data !== readyMessage) {
throw new IpcError('unexpected first message');
}
return messagePort;
};
const signal$1 = messagePort => {
messagePort.start();
};
class IpcParentWithMessagePort extends Ipc {
getData = getData$2;
send(message) {
this._rawIpc.postMessage(message);
}
sendAndTransfer(message) {
const transfer = getTransferrables(message);
this._rawIpc.postMessage(message, transfer);
}
dispose() {
this._rawIpc.close();
}
onMessage(callback) {
this._rawIpc.addEventListener('message', callback);
}
onClose(callback) {}
}
const wrap$5 = messagePort => {
return new IpcParentWithMessagePort(messagePort);
};
const IpcParentWithMessagePort$1 = {
__proto__: null,
create: create$5$1,
signal: signal$1,
wrap: wrap$5
};
const stringifyCompact = value => {
return JSON.stringify(value);
};
const parse = content => {
if (content === 'undefined') {
return null;
}
try {
return JSON.parse(content);
} catch (error) {
throw new VError(error, 'failed to parse json');
}
};
const waitForWebSocketToBeOpen = webSocket => {
return getFirstEvent(webSocket, {
close: Close,
error: Error$3,
open: Open
});
};
const create$6 = async ({
webSocket
}) => {
const firstWebSocketEvent = await waitForWebSocketToBeOpen(webSocket);
if (firstWebSocketEvent.type === Error$3) {
throw new IpcError(`WebSocket connection error`);
}
if (firstWebSocketEvent.type === Close) {
throw new IpcError('Websocket connection was immediately closed');
}
return webSocket;
};
class IpcParentWithWebSocket extends Ipc {
getData(event) {
return parse(event.data);
}
send(message) {
this._rawIpc.send(stringifyCompact(message));
}
sendAndTransfer(message) {
throw new Error('sendAndTransfer not supported');
}
dispose() {
this._rawIpc.close();
}
onClose(callback) {
this._rawIpc.addEventListener('close', callback);
}
onMessage(callback) {
this._rawIpc.addEventListener('message', callback);
}
}
const wrap = webSocket => {
return new IpcParentWithWebSocket(webSocket);
};
const IpcParentWithWebSocket$1 = {
__proto__: null,
create: create$6,
wrap
};
const Two$1 = '2.0';
const callbacks = Object.create(null);
const get$3 = id => {
return callbacks[id];
};
const remove$3 = id => {
delete callbacks[id];
};
class JsonRpcError extends Error {
constructor(message) {
super(message);
this.name = 'JsonRpcError';
}
}
const NewLine = '\n';
const DomException = 'DOMException';
const ReferenceError$1 = 'ReferenceError';
const SyntaxError$1 = 'SyntaxError';
const TypeError$1 = 'TypeError';
const getErrorConstructor = (message, type) => {
if (type) {
switch (type) {
case DomException:
return DOMException;
case TypeError$1:
return TypeError;
case SyntaxError$1:
return SyntaxError;
case ReferenceError$1:
return ReferenceError;
default:
return Error;
}
}
if (message.startsWith('TypeError: ')) {
return TypeError;
}
if (message.startsWith('SyntaxError: ')) {
return SyntaxError;
}
if (message.startsWith('ReferenceError: ')) {
return ReferenceError;
}
return Error;
};
const constructError = (message, type, name) => {
const ErrorConstructor = getErrorConstructor(message, type);
if (ErrorConstructor === DOMException && name) {
return new ErrorConstructor(message, name);
}
if (ErrorConstructor === Error) {
const error = new Error(message);
if (name && name !== 'VError') {
error.name = name;
}
return error;
}
return new ErrorConstructor(message);
};
const joinLines = lines => {
return lines.join(NewLine);
};
const splitLines = lines => {
return lines.split(NewLine);
};
const getCurrentStack = () => {
const stackLinesToSkip = 3;
const currentStack = joinLines(splitLines(new Error().stack || '').slice(stackLinesToSkip));
return currentStack;
};
const getNewLineIndex = (string, startIndex = undefined) => {
return string.indexOf(NewLine, startIndex);
};
const getParentStack = error => {
let parentStack = error.stack || error.data || error.message || '';
if (parentStack.startsWith(' at')) {
parentStack = error.message + NewLine + parentStack;
}
return parentStack;
};
const MethodNotFound = -32601;
const Custom = -32001;
const restoreJsonRpcError = error => {
const currentStack = getCurrentStack();
if (error && error instanceof Error) {
if (typeof error.stack === 'string') {
error.stack = error.stack + NewLine + currentStack;
}
return error;
}
if (error && error.code && error.code === MethodNotFound) {
const restoredError = new JsonRpcError(error.message);
const parentStack = getParentStack(error);
restoredError.stack = parentStack + NewLine + currentStack;
return restoredError;
}
if (error && error.message) {
const restoredError = constructError(error.message, error.type, error.name);
if (error.data) {
if (error.data.stack && error.data.type && error.message) {
restoredError.stack = error.data.type + ': ' + error.message + NewLine + error.data.stack + NewLine + currentStack;
} else if (error.data.stack) {
restoredError.stack = error.data.stack;
}
if (error.data.codeFrame) {
// @ts-ignore
restoredError.codeFrame = error.data.codeFrame;
}
if (error.data.code) {
// @ts-ignore
restoredError.code = error.data.code;
}
if (error.data.type) {
// @ts-ignore
restoredError.name = error.data.type;
}
} else {
if (error.stack) {
const lowerStack = restoredError.stack || '';
// @ts-ignore
const indexNewLine = getNewLineIndex(lowerStack);
const parentStack = getParentStack(error);
// @ts-ignore
restoredError.stack = parentStack + lowerStack.slice(indexNewLine);
}
if (error.codeFrame) {
// @ts-ignore
restoredError.codeFrame = error.codeFrame;
}
}
return restoredError;
}
if (typeof error === 'string') {
return new Error(`JsonRpc Error: ${error}`);
}
return new Error(`JsonRpc Error: ${error}`);
};
const unwrapJsonRpcResult = responseMessage => {
if ('error' in responseMessage) {
const restoredError = restoreJsonRpcError(responseMessage.error);
throw restoredError;
}
if ('result' in responseMessage) {
return responseMessage.result;
}
throw new JsonRpcError('unexpected response message');
};
const warn = (...args) => {
console.warn(...args);
};
const resolve = (id, response) => {
const fn = get$3(id);
if (!fn) {
console.log(response);
warn(`callback ${id} may already be disposed`);
return;
}
fn(response);
remove$3(id);
};
const E_COMMAND_NOT_FOUND = 'E_COMMAND_NOT_FOUND';
const getErrorType = prettyError => {
if (prettyError && prettyError.type) {
return prettyError.type;
}
if (prettyError && prettyError.constructor && prettyError.constructor.name) {
return prettyError.constructor.name;
}
return undefined;
};
const isAlreadyStack = line => {
return line.trim().startsWith('at ');
};
const getStack = prettyError => {
const stackString = prettyError.stack || '';
const newLineIndex = stackString.indexOf('\n');
if (newLineIndex !== -1 && !isAlreadyStack(stackString.slice(0, newLineIndex))) {
return stackString.slice(newLineIndex + 1);
}
return stackString;
};
const getErrorProperty = (error, prettyError) => {
if (error && error.code === E_COMMAND_NOT_FOUND) {
return {
code: MethodNotFound,
message: error.message,
data: error.stack
};
}
return {
code: Custom,
message: prettyError.message,
data: {
stack: getStack(prettyError),
codeFrame: prettyError.codeFrame,
type: getErrorType(prettyError),
code: prettyError.code,
name: prettyError.name
}
};
};
const create$1$2 = (id, error) => {
return {
jsonrpc: Two$1,
id,
error
};
};
const getErrorResponse = (id, error, preparePrettyError, logError) => {
const prettyError = preparePrettyError(error);
logError(error, prettyError);
const errorProperty = getErrorProperty(error, prettyError);
return create$1$2(id, errorProperty);
};
const create$5 = (message, result) => {
return {
jsonrpc: Two$1,
id: message.id,
result: result ?? null
};
};
const getSuccessResponse = (message, result) => {
const resultProperty = result ?? null;
return create$5(message, resultProperty);
};
const getErrorResponseSimple = (id, error) => {
return {
jsonrpc: Two$1,
id,
error: {
code: Custom,
// @ts-ignore
message: error.message,
data: error
}
};
};
const getResponse = async (message, ipc, execute, preparePrettyError, logError, requiresSocket) => {
try {
const result = requiresSocket(message.method) ? await execute(message.method, ipc, ...message.params) : await execute(message.method, ...message.params);
return getSuccessResponse(message, result);
} catch (error) {
if (ipc.canUseSimpleErrorResponse) {
return getErrorResponseSimple(message.id, error);
}
return getErrorResponse(message.id, error, preparePrettyError, logError);
}
};
const defaultPreparePrettyError = error => {
return error;
};
const defaultLogError = () => {
// ignore
};
const defaultRequiresSocket = () => {
return false;
};
const defaultResolve = resolve;
// TODO maybe remove this in v6 or v7, only accept options object to simplify the code
const normalizeParams = args => {
if (args.length === 1) {
const options = args[0];
return {
ipc: options.ipc,
message: options.message,
execute: options.execute,
resolve: options.resolve || defaultResolve,
preparePrettyError: options.preparePrettyError || defaultPreparePrettyError,
logError: options.logError || defaultLogError,
requiresSocket: options.requiresSocket || defaultRequiresSocket
};
}
return {
ipc: args[0],
message: args[1],
execute: args[2],
resolve: args[3],
preparePrettyError: args[4],
logError: args[5],
requiresSocket: args[6]
};
};
const handleJsonRpcMessage = async (...args) => {
const options = normalizeParams(args);
const {
message,
ipc,
execute,
resolve,
preparePrettyError,
logError,
requiresSocket
} = options;
if ('id' in message) {
if ('method' in message) {
const response = await getResponse(message, ipc, execute, preparePrettyError, logError, requiresSocket);
try {
ipc.send(response);
} catch (error) {
const errorResponse = getErrorResponse(message.id, error, preparePrettyError, logError);
ipc.send(errorResponse);
}
return;
}
resolve(message.id, message);
return;
}
if ('method' in message) {
await getResponse(message, ipc, execute, preparePrettyError, logError, requiresSocket);
return;
}
throw new JsonRpcError('unexpected message');
};
class CommandNotFoundError extends Error {
constructor(command) {
super(`Command not found ${command}`);
this.name = 'CommandNotFoundError';
}
}
const commands = Object.create(null);
const register = commandMap => {
Object.assign(commands, commandMap);
};
const getCommand = key => {
return commands[key];
};
const execute = (command, ...args) => {
const fn = getCommand(command);
if (!fn) {
throw new CommandNotFoundError(command);
}
return fn(...args);
};
const Two = '2.0';
const create$s = (method, params) => {
return {
jsonrpc: Two,
method,
params
};
};
const create$r = (id, method, params) => {
const message = {
id,
jsonrpc: Two,
method,
params
};
return message;
};
let id = 0;
const create$q = () => {
return ++id;
};
/* eslint-disable n/no-unsupported-features/es-syntax */
const registerPromise = map => {
const id = create$q();
const {
promise,
resolve
} = Promise.withResolvers();
map[id] = resolve;
return {
id,
promise
};
};
// @ts-ignore
const invokeHelper = async (callbacks, ipc, method, params, useSendAndTransfer) => {
const {
id,
promise
} = registerPromise(callbacks);
const message = create$r(id, method, params);
if (useSendAndTransfer && ipc.sendAndTransfer) {
ipc.sendAndTransfer(message);
} else {
ipc.send(message);
}
const responseMessage = await promise;
return unwrapJsonRpcResult(responseMessage);
};
const createRpc = ipc => {
const callbacks = Object.create(null);
ipc._resolve = (id, response) => {
const fn = callbacks[id];
if (!fn) {
console.warn(`callback ${id} may already be disposed`);
return;
}
fn(response);
delete callbacks[id];
};
const rpc = {
async dispose() {
await ipc?.dispose();
},
invoke(method, ...params) {
return invokeHelper(callbacks, ipc, method, params, false);
},
invokeAndTransfer(method, ...params) {
return invokeHelper(callbacks, ipc, method, params, true);
},
// @ts-ignore
ipc,
/**
* @deprecated
*/
send(method, ...params) {
const message = create$s(method, params);
ipc.send(message);
}
};
return rpc;
};
const requiresSocket = () => {
return false;
};
const preparePrettyError = error => {
return error;
};
const logError = () => {
// handled by renderer worker
};
const handleMessage = event => {
const actualRequiresSocket = event?.target?.requiresSocket || requiresSocket;
const actualExecute = event?.target?.execute || execute;
return handleJsonRpcMessage(event.target, event.data, actualExecute, event.target._resolve, preparePrettyError, logError, actualRequiresSocket);
};
const handleIpc = ipc => {
if ('addEventListener' in ipc) {
ipc.addEventListener('message', handleMessage);
} else if ('on' in ipc) {
// deprecated
ipc.on('message', handleMessage);
}
};
const listen$1 = async (module, options) => {
const rawIpc = await module.listen(options);
if (module.signal) {
module.signal(rawIpc);
}
const ipc = module.wrap(rawIpc);
return ipc;
};
/* eslint-disable @typescript-eslint/no-misused-promises */
const createSharedLazyRpc = factory => {
let rpcPromise;
const getOrCreate = () => {
if (!rpcPromise) {
rpcPromise = factory();
}
return rpcPromise;
};
return {
async dispose() {
const rpc = await getOrCreate();
await rpc.dispose();
},
async invoke(method, ...params) {
const rpc = await getOrCreate();
return rpc.invoke(method, ...params);
},
async invokeAndTransfer(method, ...params) {
const rpc = await getOrCreate();
return rpc.invokeAndTransfer(method, ...params);
},
async send(method, ...params) {
const rpc = await getOrCreate();
rpc.send(method, ...params);
}
};
};
const create$i = async ({
commandMap,
isMessagePortOpen,
send
}) => {
return createSharedLazyRpc(() => {
return create$2$1({
commandMap,
isMessagePortOpen,
send
});
});
};
const LazyTransferMessagePortRpcParent = {
__proto__: null,
create: create$i
};
const Https = 'https:';
const Ws = 'ws:';
const Wss = 'wss:';
const getWebSocketProtocol = locationProtocol => {
return locationProtocol === Https ? Wss : Ws;
};
const getWebSocketUrl = (type, host, locationProtocol) => {
const wsProtocol = getWebSocketProtocol(locationProtocol);
return `${wsProtocol}//${host}/websocket/${type}`;
};
const getHost = () => {
return location.host;
};
const getProtocol$1 = () => {
return location.protocol;
};
const create$h = async ({
commandMap,
webSocket
}) => {
// TODO create a commandMap per rpc instance
register(commandMap);
const rawIpc = await IpcParentWithWebSocket$1.create({
webSocket
});
const ipc = IpcParentWithWebSocket$1.wrap(rawIpc);
handleIpc(ipc);
const rpc = createRpc(ipc);
return rpc;
};
const create$g = async ({
commandMap,
type
}) => {
const host = getHost();
const protocol = getProtocol$1();
const wsUrl = getWebSocketUrl(type, host, protocol);
const webSocket = new WebSocket(wsUrl);
const rpc = await create$h({
commandMap,
webSocket
});
return rpc;
};
const create$f = async ({
commandMap,
type
}) => {
return createSharedLazyRpc(() => {
return create$g({
commandMap,
type
});
});
};
const LazyWebSocketRpcParent2 = {
__proto__: null,
create: create$f
};
const create$4 = async ({
commandMap,
isMessagePortOpen = true,
messagePort
}) => {
// TODO create a commandMap per rpc instance
register(commandMap);
const rawIpc = await IpcParentWithMessagePort$1.create({
isMessagePortOpen,
messagePort
});
const ipc = IpcParentWithMessagePort$1.wrap(rawIpc);
handleIpc(ipc);
const rpc = createRpc(ipc);
messagePort.start();
return rpc;
};
const create$2$1 = async ({
commandMap,
isMessagePortOpen,
send
}) => {
const {
port1,
port2
} = new MessageChannel();
await send(port1);
return create$4({
commandMap,
isMessagePortOpen,
messagePort: port2
});
};
const TransferMessagePortRpcParent = {
__proto__: null,
create: create$2$1
};
const create$1$1 = async ({
commandMap
}) => {
// TODO create a commandMap per rpc instance
register(commandMap);
const ipc = await listen$1(IpcChildWithModuleWorkerAndMessagePort$1);
handleIpc(ipc);
const rpc = createRpc(ipc);
return rpc;
};
const WebWorkerRpcClient = {
__proto__: null,
create: create$1$1
};
const createMockRpc = ({
commandMap
}) => {
const invocations = [];
const invoke = (method, ...params) => {
invocations.push([method, ...params]);
const command = commandMap[method];
if (!command) {
throw new Error(`command ${method} not found`);
}
return command(...params);
};
const mockRpc = {
invocations,
invoke,
invokeAndTransfer: invoke
};
return mockRpc;
};
const Alert = 'alert';
const Button$3 = 'button';
const CheckBox = 'checkbox';
const None$2 = 'none';
const ScrollBar$1 = 'scrollbar';
const Status = 'status';
const ToolBar = 'toolbar';
const Tree$1 = 'tree';
const TreeItem$1 = 'treeitem';
const Actions = 'Actions';
const Badge = 'Badge';
const Chevron = 'Chevron';
const CloseMaskIcon = 'MaskIcon MaskIconClose';
const Empty$1 = '';
const FileIcon = 'FileIcon';
const FocusOutline = 'FocusOutline';
const Grow = 'Grow';
const Highlight = 'Highlight';
const HighlightDeleted = 'HighlightDeleted';
const HighlightInserted = 'HighlightInserted';
const IconButton = 'IconButton';
const IconButtonDisabled = 'IconButtonDisabled';
const Label = 'Label';
const List$1 = 'List';
const MaskIcon = 'MaskIcon';
const MaskIconBook = 'MaskIconBook';
const MaskIconCaseSensitive = 'MaskIconCaseSensitive';
const MaskIconChevronDown = 'MaskIconChevronDown';
const MaskIconChevronRight = 'MaskIconChevronRight';
const MaskIconEllipsis = 'MaskIconEllipsis';
const MaskIconExclude = 'MaskIconExclude';
const MaskIconPreserveCase = 'MaskIconPreserveCase';
const MaskIconRegex = 'MaskIconRegex';
const MaskIconReplaceAll = 'MaskIconReplaceAll';
const MaskIconWholeWord = 'MaskIconWholeWord';
const MultilineInputBox = 'MultilineInputBox';
const ScrollBar = 'ScrollBar';
const ScrollBarThumb = 'ScrollBarThumb';
const ScrollBarVertical = 'ScrollBarVertical';
const Search$2 = 'Search';
const SearchField = 'SearchField';
const SearchFieldButton = 'SearchFieldButton';
const SearchFieldButtonChecked = 'SearchFieldButtonChecked';
const SearchFieldButtonDisabled = 'SearchFieldButtonDisabled';
const SearchFieldButtons = 'SearchFieldButtons';
const SearchFieldContainer = 'SearchFieldContainer';
const SearchFieldError = 'SearchFieldError';
const SearchHeader = 'SearchHeader';
const SearchHeaderDetails = 'SearchHeaderDetails';
const SearchHeaderDetailsExpanded = 'SearchHeaderDetailsExpanded';
const SearchHeaderDetailsExpandedTop = 'SearchHeaderDetailsExpandedTop';
const SearchHeaderDetailsHeading = 'SearchHeaderDetailsHeading';
const SearchHeaderTop = 'SearchHeaderTop';
const SearchHeaderTopRight = 'SearchHeaderTopRight';
const SearchInputError = 'SearchInputError';
const SearchRemove = 'SearchRemove';
const SearchToggleButton = 'SearchToggleButton';
const SearchToggleButtonExpanded = 'SearchToggleButtonExpanded';
const SourceControlBadge = 'SourceControlBadge';
const ToggleDetails = 'ToggleDetails';
const Tree = 'Tree';
const TreeItem = 'TreeItem';
const TreeItemActive = 'TreeItemActive';
const TreeItems$1 = 'TreeItems';
const Viewlet = 'Viewlet';
const ViewletSearchMessage = 'ViewletSearchMessage';
const ViewletSearchMessageIndented = 'ViewletSearchMessageIndented';
const File$2 = 7;
const Button$2 = 1;
const Div = 4;
const Span = 8;
const Text = 12;
const Img = 17;
const Ins = 20;
const Del = 21;
const H4 = 24;
const TextArea = 62;
const Button$1 = 'event.button';
const ClientX = 'event.clientX';
const ClientY = 'event.clientY';
const DeltaMode = 'event.deltaMode';
const DeltaY = 'event.deltaY';
const TargetName = 'event.target.name';
const TargetSelectionEnd = 'event.target.selectionEnd';
const TargetSelectionStart = 'event.target.selectionStart';
const TargetValue = 'event.target.value';
const Script$1 = 2;
const Search$1 = 18;
const InputContextMenu = 91;
const Separator = 1;
const None$1 = 0;
const LeftClick = 0;
const Electron = 2;
const Remote = 3;
const IconThemeWorker = 7009;
const RendererWorker = 1;
const SearchProcess = 77;
const File$1 = 1;
const Match$1 = 2;
const FocusElementByName = 'Viewlet.focusElementByName';
const SetDom2 = 'Viewlet.setDom2';
const SetFocusContext = 'Viewlet.setFocusContext';
const SetValueByName = 'Viewlet.setValueByName';
const Empty = 0;
const FocusIgnoreFiles = 1012;
const FocusSearch = 1013;
const FocusSearchExcludeInput = 1008;
const FocusSearchIncludeInput = 1007;
const FocusSearchInput = 21;
const FocusSearchMatchCase = 32;
const FocusSearchOpenEditors = 1011;
const FocusSearchPreserveCase = 36;
const FocusSearchRegex = 33;
const FocusSearchReplaceAll = 35;
const FocusSearchReplaceInput = 31;
const FocusSearchResults = 22;
const FocusSearchWholeWord = 34;
const FocusToggleDetails = 1010;
const FocusToggleReplace = 1020;
const rpcs = Object.create(null);
const set$4 = (id, rpc) => {
rpcs[id] = rpc;
};
const get$2 = id => {
return rpcs[id];
};
const remove$2 = id => {
delete rpcs[id];
};
/* eslint-disable @typescript-eslint/explicit-function-return-type */
const create$3 = rpcId => {
return {
async dispose() {
const rpc = get$2(rpcId);
await rpc.dispose();
},
// @ts-ignore
invoke(method, ...params) {
const rpc = get$2(rpcId);
// @ts-ignore
return rpc.invoke(method, ...params);
},
// @ts-ignore
invokeAndTransfer(method, ...params) {
const rpc = get$2(rpcId);
// @ts-ignore
return rpc.invokeAndTransfer(method, ...params);
},
registerMockRpc(commandMap) {
const mockRpc = createMockRpc({
commandMap
});
set$4(rpcId, mockRpc);
// @ts-ignore
mockRpc[Symbol.dispose] = () => {
remove$2(rpcId);
};
// @ts-ignore
return mockRpc;
},
set(rpc) {
set$4(rpcId, rpc);
}
};
};
const {
invoke: invoke$2,
set: set$3
} = create$3(IconThemeWorker);
const getIcons = async iconRequests => {
// @ts-ignore
return invoke$2('IconTheme.getIcons', iconRequests);
};
const {
invoke: invoke$1,
invokeAndTransfer,
set: set$2
} = create$3(RendererWorker);
const showContextMenu2 = async (uid, menuId, x, y, args) => {
number(uid);
number(menuId);
number(x);
number(y);
// @ts-ignore
await invoke$1('ContextMenu.show2', uid, menuId, x, y, args);
};
const sendMessagePortToIconThemeWorker = async (port, rpcId) => {
const command = 'IconTheme.handleMessagePort';
// @ts-ignore
await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToIconThemeWorker', port, command, rpcId);
};
const handleWorkspaceRefresh = async () => {
return invoke$1('Layout.handleWorkspaceRefresh');
};
const sendMessagePortToSearchProcess = async port => {
await invokeAndTransfer('SendMessagePortToElectron.sendMessagePortToElectron', port, 'HandleMessagePortForSearchProcess.handleMessagePortForSearchProcess');
};
const writeClipBoardText = async text => {
await invoke$1('ClipBoard.writeText', /* text */text);
};
const openUri$1 = async (uri, focus, options) => {
await invoke$1('Main.openUri', uri, focus, options);
};
const {
invoke,
set: set$1
} = create$3(SearchProcess);
const toCommandId = key => {
const dotIndex = key.indexOf('.');
return key.slice(dotIndex + 1);
};
const create$2 = () => {
const states = Object.create(null);
const commandMapRef = {};
return {
get(uid) {
return states[uid];
},
set(uid, oldState, newState) {
states[uid] = {
oldState,
newState
};
},
dispose(uid) {
delete states[uid];
},
getKeys() {
return Object.keys(states).map(key => {
return Number.parseInt(key);
});
},
clear() {
for (const key of Object.keys(states)) {
delete states[key];
}
},
wrapCommand(fn) {
const wrapped = async (uid, ...args) => {
const {
oldState,
newState
} = states[uid];
const newerState = await fn(newState, ...args);
if (oldState === newerState || newState === newerState) {
return;
}
const latest = states[uid];
states[uid] = {
oldState: latest.oldState,
newState: newerState
};
};
return wrapped;
},
wrapGetter(fn) {
const wrapped = (uid, ...args) => {
const {
newState
} = states[uid];
return fn(newState, ...args);
};
return wrapped;
},
diff(uid, modules, numbers) {
const {
oldState,
newState
} = states[uid];
const diffResult = [];
for (let i = 0; i < modules.length; i++) {
const fn = modules[i];
if (!fn(oldState, newState)) {
diffResult.push(numbers[i]);
}
}
return diffResult;
},
getCommandIds() {
const keys = Object.keys(commandMapRef);
const ids = keys.map(toCommandId);
return ids;
},
registerCommands(commandMap) {
Object.assign(commandMapRef, commandMap);
}
};
};
const terminate = () => {
globalThis.close();
};
const mergeClassNames = (...classNames) => {
return classNames.filter(Boolean).join(' ');
};
const text = data => {
return {
childCount: 0,
text: data,
type: Text
};
};
const SetText = 1;
const Replace$1 = 2;
const SetAttribute = 3;
const RemoveAttribute = 4;
const Add = 6;
const NavigateChild = 7;
const NavigateParent = 8;
const RemoveChild = 9;
const NavigateSibling = 10;
const isKey = key => {
return key !== 'type' && key !== 'childCount';
};
const getKeys = node => {
const keys = Object.keys(node).filter(isKey);
return keys;
};
const arrayToTree = nodes => {
const result = [];
let i = 0;
while (i < nodes.length) {
const node = nodes[i];
const {
children,
nodesConsumed
} = getChildrenWithCount(nodes, i + 1, node.childCount || 0);
result.push({
node,
children
});
i += 1 + nodesConsumed;
}
return result;
};
const getChildrenWithCount = (nodes, startIndex, childCount) => {
if (childCount === 0) {
return {
children: [],
nodesConsumed: 0
};
}
const children = [];
let i = startIndex;
let remaining = childCount;
let totalConsumed = 0;
while (remaining > 0 && i < nodes.length) {
const node = nodes[i];
const nodeChildCount = node.childCount || 0;
const {
children: nodeChildren,
nodesConsumed
} = getChildrenWithCount(nodes, i + 1, nodeChildCount);
children.push({
node,
children: nodeChildren
});
const nodeSize = 1 + nodesConsumed;
i += nodeSize;
totalConsumed += nodeSize;
remaining--;
}
return {
children,
nodesConsumed: totalConsumed
};
};
const compareNodes = (oldNode, newNode) => {
const patches = [];
// Check if node type changed - return null to signal incompatible nodes
// (caller should handle this with a Replace operation)
if (oldNode.type !== newNode.type) {
return null;
}
// Handle text nodes
if (oldNode.type === Text && newNode.type === Text) {
if (oldNode.text !== newNode.text) {
patches.push({
type: SetText,
value: newNode.text
});
}
return patches;
}
// Compare attributes
const oldKeys = getKeys(oldNode);
const newKeys = getKeys(newNode);
// Check for attribute changes
for (const key of newKeys) {
if (oldNode[key] !== newNode[key]) {
patches.push({
type: SetAttribute,
key,
value: newNode[key]
});
}
}
// Check for removed attributes
for (const key of oldKeys) {
if (!(key in newNode)) {
patches.push({
type: RemoveAttribute,
key
});
}
}
return patches;
};
const treeToArray = node => {
const result = [node.node];
for (const child of node.children) {
result.push(...treeToArray(child));
}
return result;
};
const diffChildren = (oldChildren, newChildren, patches) => {
const maxLength = Math.max(oldChildren.length, newChildren.length);
// Track where we are: -1 means at parent, >= 0 means at child index
let currentChildIndex = -1;
// Collect indices of children to remove (we'll add these patches at the end in reverse order)
const indicesToRemove = [];
for (let i = 0; i < maxLength; i++) {
const oldNode = oldChildren[i];
const newNode = newChildren[i];
if (!oldNode && !newNode) {
continue;
}
if (!oldNode) {
// Add new node - we should be at the parent
if (currentChildIndex >= 0) {
// Navigate back to parent
patches.push({
type: NavigateParent
});
currentChildIndex = -1;
}
// Flatten the entire subtree so renderInternal can handle it
const flatNodes = treeToArray(newNode);
patches.push({
type: Add,
nodes: flatNodes
});
} else if (newNode) {
// Compare nodes to see if we need any patches
const nodePatches = compareNodes(oldNode.node, newNode.node);
// If nodePatches is null, the node types are incompatible - need to replace
if (nodePatches === null) {
// Navigate to this child
if (currentChildIndex === -1) {
patches.push({
type: NavigateChild,
index: i
});
currentChildIndex = i;
} else if (currentChildIndex !== i) {
patches.push({
type: NavigateSibling,
index: i
});
currentChildIndex = i;
}
// Replace the entire subtree
const flatNodes = treeToArray(newNode);
patches.push({
type: Replace$1,
nodes: flatNodes
});
// After replace, we're at the new element (same position)
continue;
}
// Check if we need to recurse into children
const hasChildrenToCompare = oldNode.children.length > 0 || newNode.children.length > 0;
// Only navigate to this element if we need to do something
if (nodePatches.length > 0 || hasChildrenToCompare) {
// Navigate to this child if not already there
if (currentChildIndex === -1) {
patches.push({
type: NavigateChild,
index: i
});
currentChildIndex = i;
} else if (currentChildIndex !== i) {
patches.push({
type: NavigateSibling,
index: i
});
currentChildIndex = i;
}
// Apply node patches (these apply to the current element, not children)
if (nodePatches.length > 0) {
patches.push(...nodePatches);
}
// Compare children recursively
if (hasChildrenToCompare) {
diffChildren(oldNode.children, newNode.children, patches);
}
}
} else {
// Remove old node - collect the index for later removal
indicesToRemove.push(i);
}
}
// Navigate back to parent if we ended at a child
if (currentChildIndex >= 0) {
patches.push({
type: NavigateParent
});
currentChildIndex = -1;
}
// Add remove patches in reverse order (highest index first)
// This ensures indices remain valid as we remove
for (let j = indicesToRemove.length - 1; j >= 0; j--) {
patches.push({
type: RemoveChild,
index: indicesToRemove[j]
});
}
};
const diffTrees = (oldTree, newTree, patches, path) => {
// At the root level (path.length === 0), we're already AT the element
// So we compare the root node directly, then compare its children
if (path.length === 0 && oldTree.length === 1 && newTree.length === 1) {
const oldNode = oldTree[0];
const newNode = newTree[0];
// Compare root nodes
const nodePatches = compareNodes(oldNode.node, newNode.node);
// If nodePatches is null, the root node types are incompatible - need to replace
if (nodePatches === null) {
const flatNodes = treeToArray(newNode);
patches.push({
type: Replace$1,
nodes: flatNodes
});
return;
}
if (nodePatches.length > 0) {
patches.push(...nodePatches);
}
// Compare children
if (oldNode.children.length > 0 || newNode.children.length > 0) {
diffChildren(oldNode.children, newNode.children, patches);
}
} else {
// Non-root level or multiple root elements - use the regular comparison
diffChildren(oldTree, newTree, patches);
}
};
const removeTrailingNavigationPatches = patches => {
// Find the last non-navigation patch
let lastNonNavigationIndex = -1;
for (let i = patches.length - 1; i >= 0; i--) {
const patch = patches[i];
if (patch.type !== NavigateChild && patch.type !== NavigateParent && patch.type !== NavigateSibling) {
lastNonNavigationIndex = i;
break;
}
}
// Return patches up to and including the last non-navigation patch
return lastNonNavigationIndex === -1 ? [] : patches.slice(0, lastNonNavigationIndex + 1);
};
const diffTree = (oldNodes, newNodes) => {
// Step 1: Convert flat arrays to tree structures
const oldTree = arrayToTree(oldNodes);
const newTree = arrayToTree(newNodes);
// Step 3: Compare the trees
const patches = [];
diffTrees(oldTree, newTree, patches, []);
// Remove trailing navigation patches since they serve no purpose
return removeTrailingNavigationPatches(patches);
};
const User = 1;
const Script = 2;
const clearSearchResults$1 = state => {
return {
...state,
focus: FocusSearchInput,
focusSource: Script,
inputSource: Script,
items: [],
limitHit: false,
limitHitWarning: '',
maxLineY: 0,
message: '',
minLineY: 0,
replacement: '',
searchInputErrorMessage: '',
value: ''
};
};
const getFilePath = text => {
// TODO make api stricter so that results always have the same shape
if (text.startsWith('./')) {
return text.slice(2);
}
return text;
};
const getIconsCached = (dirents, fileIconCache) => {
return dirents.map(dirent => {
if (dirent.type === Match$1) {
return '';
}
const path = getFilePath(dirent.text);
return fileIconCache[path];
});
};
const getFileName = path => {
const slashIndex = path.lastIndexOf('/');
if (slashIndex === -1) {
return path;
}
return path.slice(slashIndex + 1);
};
const File = 1;
const Match = 2;
const isFile = match => {
return match.type === File;
};
const getMissingDirents = (searchResults, fileIconCache) => {
const missingDirents = [];
const files = searchResults.filter(isFile);
for (const file of files) {
const uri = getFilePath(file.text);
if (!(uri in fileIconCache)) {
missingDirents.push(file);
}
}
return missingDirents;
};
const toIconRequest = item => {
const filePath = getFilePath(item.text);
const fileName = getFileName(filePath);
return {
name: fileName,
path: filePath,
type: File$2
};
};
const getMissingIconRequests = (dirents, fileIconCache) => {
const missingRequests = getMissingDirents(dirents, fileIconCache);
const iconRequests = missingRequests.map(toIconRequest);
return iconRequests;
};
const Directory = 3;
const DirectoryExpanded = 4;
const getSimpleIconRequestType = direntType => {
if (direntType === Directory || direntType === DirectoryExpanded) {
return 2;
}
return 1;
};
const toSimpleIconRequest = request => {
return {
name: request.name,
type: getSimpleIconRequestType(request.type)
};
};
const requestFileIcons = async requests => {
if (requests.length === 0) {
return [];
}
const simpleRequests = requests.map(toSimpleIconRequest);
const icons = await get