mirror of
https://github.com/ByteAtATime/raycast-linux.git
synced 2025-08-28 18:04:07 +00:00
style: formatting
This commit is contained in:
parent
85c9595d15
commit
fc7c835c66
38 changed files with 4202 additions and 2343 deletions
|
@ -1 +1,8 @@
|
|||
sidecar/plugin-host.js
|
||||
sidecar/dist
|
||||
src-tauri
|
||||
package-lock.json
|
||||
pnpm-lock.yaml
|
||||
yarn.lock
|
||||
bun.lock
|
||||
bun.lockb
|
6
.vscode/extensions.json
vendored
6
.vscode/extensions.json
vendored
|
@ -1,7 +1,3 @@
|
|||
{
|
||||
"recommendations": [
|
||||
"svelte.svelte-vscode",
|
||||
"tauri-apps.tauri-vscode",
|
||||
"rust-lang.rust-analyzer"
|
||||
]
|
||||
"recommendations": ["svelte.svelte-vscode", "tauri-apps.tauri-vscode", "rust-lang.rust-analyzer"]
|
||||
}
|
||||
|
|
3116
pnpm-lock.yaml
generated
3116
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load diff
938
sidecar/pnpm-lock.yaml
generated
938
sidecar/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load diff
2
sidecar/src/global.d.ts
vendored
2
sidecar/src/global.d.ts
vendored
|
@ -1,4 +1,4 @@
|
|||
declare module "*.txt" {
|
||||
declare module '*.txt' {
|
||||
const content: string;
|
||||
export default content;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { HostConfig } from "react-reconciler";
|
||||
import type { HostConfig } from 'react-reconciler';
|
||||
import type {
|
||||
ComponentType,
|
||||
ComponentProps,
|
||||
|
@ -7,18 +7,18 @@ import type {
|
|||
TextInstance,
|
||||
UpdatePayload,
|
||||
ParentInstance,
|
||||
AnyInstance,
|
||||
} from "./types";
|
||||
AnyInstance
|
||||
} from './types';
|
||||
import {
|
||||
instances,
|
||||
getNextInstanceId,
|
||||
commitBuffer,
|
||||
addToCommitBuffer,
|
||||
clearCommitBuffer,
|
||||
} from "./state";
|
||||
import { writeOutput } from "./io";
|
||||
import { serializeProps, optimizeCommitBuffer } from "./utils";
|
||||
import React from "react";
|
||||
clearCommitBuffer
|
||||
} from './state';
|
||||
import { writeOutput } from './io';
|
||||
import { serializeProps, optimizeCommitBuffer } from './utils';
|
||||
import React from 'react';
|
||||
|
||||
const appendChildToParent = (parent: ParentInstance, child: AnyInstance) => {
|
||||
const existingIndex = parent.children.findIndex(({ id }) => id === child.id);
|
||||
|
@ -27,8 +27,8 @@ const appendChildToParent = (parent: ParentInstance, child: AnyInstance) => {
|
|||
}
|
||||
parent.children.push(child);
|
||||
addToCommitBuffer({
|
||||
type: "APPEND_CHILD",
|
||||
payload: { parentId: parent.id, childId: child.id },
|
||||
type: 'APPEND_CHILD',
|
||||
payload: { parentId: parent.id, childId: child.id }
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -42,18 +42,16 @@ const insertChildBefore = (
|
|||
parent.children.splice(existingIndex, 1);
|
||||
}
|
||||
|
||||
const beforeIndex = parent.children.findIndex(
|
||||
({ id }) => id === beforeChild.id
|
||||
);
|
||||
const beforeIndex = parent.children.findIndex(({ id }) => id === beforeChild.id);
|
||||
if (beforeIndex !== -1) {
|
||||
parent.children.splice(beforeIndex, 0, child);
|
||||
addToCommitBuffer({
|
||||
type: "INSERT_BEFORE",
|
||||
type: 'INSERT_BEFORE',
|
||||
payload: {
|
||||
parentId: parent.id,
|
||||
childId: child.id,
|
||||
beforeId: beforeChild.id,
|
||||
},
|
||||
beforeId: beforeChild.id
|
||||
}
|
||||
});
|
||||
} else {
|
||||
appendChildToParent(parent, child);
|
||||
|
@ -63,8 +61,8 @@ const insertChildBefore = (
|
|||
const removeChildFromParent = (parent: ParentInstance, child: AnyInstance) => {
|
||||
parent.children = parent.children.filter(({ id }) => id !== child.id);
|
||||
addToCommitBuffer({
|
||||
type: "REMOVE_CHILD",
|
||||
payload: { parentId: parent.id, childId: child.id },
|
||||
type: 'REMOVE_CHILD',
|
||||
payload: { parentId: parent.id, childId: child.id }
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -99,8 +97,8 @@ export const hostConfig: HostConfig<
|
|||
if (commitBuffer.length > 0) {
|
||||
const optimizedPayload = optimizeCommitBuffer(commitBuffer);
|
||||
writeOutput({
|
||||
type: "BATCH_UPDATE",
|
||||
payload: optimizedPayload,
|
||||
type: 'BATCH_UPDATE',
|
||||
payload: optimizedPayload
|
||||
});
|
||||
clearCommitBuffer();
|
||||
}
|
||||
|
@ -108,32 +106,30 @@ export const hostConfig: HostConfig<
|
|||
|
||||
createInstance(type, props, root, hostContext, internalInstanceHandle) {
|
||||
const componentType =
|
||||
typeof type === "string"
|
||||
? type
|
||||
: type.displayName || type.name || "Anonymous";
|
||||
typeof type === 'string' ? type : type.displayName || type.name || 'Anonymous';
|
||||
const id = getNextInstanceId();
|
||||
const instance: RaycastInstance = {
|
||||
id,
|
||||
type: componentType,
|
||||
children: [],
|
||||
props: serializeProps(props),
|
||||
_internalFiber: internalInstanceHandle,
|
||||
_internalFiber: internalInstanceHandle
|
||||
};
|
||||
(internalInstanceHandle as any).stateNode = instance;
|
||||
instances.set(id, instance);
|
||||
|
||||
addToCommitBuffer({
|
||||
type: "CREATE_INSTANCE",
|
||||
payload: { id, type: componentType, props: instance.props },
|
||||
type: 'CREATE_INSTANCE',
|
||||
payload: { id, type: componentType, props: instance.props }
|
||||
});
|
||||
return instance;
|
||||
},
|
||||
|
||||
createTextInstance(text) {
|
||||
const id = getNextInstanceId();
|
||||
const instance: TextInstance = { id, type: "TEXT", text };
|
||||
const instance: TextInstance = { id, type: 'TEXT', text };
|
||||
instances.set(id, instance);
|
||||
addToCommitBuffer({ type: "CREATE_TEXT_INSTANCE", payload: instance });
|
||||
addToCommitBuffer({ type: 'CREATE_TEXT_INSTANCE', payload: instance });
|
||||
return instance;
|
||||
},
|
||||
|
||||
|
@ -148,16 +144,16 @@ export const hostConfig: HostConfig<
|
|||
commitUpdate(instance, type, oldProps, newProps, internalHandle) {
|
||||
instance.props = serializeProps(newProps);
|
||||
addToCommitBuffer({
|
||||
type: "UPDATE_PROPS",
|
||||
payload: { id: instance.id, props: instance.props },
|
||||
type: 'UPDATE_PROPS',
|
||||
payload: { id: instance.id, props: instance.props }
|
||||
});
|
||||
},
|
||||
|
||||
commitTextUpdate(textInstance, oldText, newText) {
|
||||
textInstance.text = newText;
|
||||
addToCommitBuffer({
|
||||
type: "UPDATE_TEXT",
|
||||
payload: { id: textInstance.id, text: newText },
|
||||
type: 'UPDATE_TEXT',
|
||||
payload: { id: textInstance.id, text: newText }
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -167,8 +163,8 @@ export const hostConfig: HostConfig<
|
|||
clearContainer: (container) => {
|
||||
container.children = [];
|
||||
addToCommitBuffer({
|
||||
type: "CLEAR_CONTAINER",
|
||||
payload: { containerId: container.id },
|
||||
type: 'CLEAR_CONTAINER',
|
||||
payload: { containerId: container.id }
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -202,33 +198,33 @@ export const hostConfig: HostConfig<
|
|||
HostTransitionContext: React.createContext(0),
|
||||
|
||||
resetFormInstance: function (): void {
|
||||
throw new Error("Function not implemented.");
|
||||
throw new Error('Function not implemented.');
|
||||
},
|
||||
requestPostPaintCallback: function (): void {
|
||||
throw new Error("Function not implemented.");
|
||||
throw new Error('Function not implemented.');
|
||||
},
|
||||
shouldAttemptEagerTransition: function (): boolean {
|
||||
throw new Error("Function not implemented.");
|
||||
throw new Error('Function not implemented.');
|
||||
},
|
||||
trackSchedulerEvent: function (): void {
|
||||
throw new Error("Function not implemented.");
|
||||
throw new Error('Function not implemented.');
|
||||
},
|
||||
resolveEventType: function (): null | string {
|
||||
throw new Error("Function not implemented.");
|
||||
throw new Error('Function not implemented.');
|
||||
},
|
||||
resolveEventTimeStamp: function (): number {
|
||||
throw new Error("Function not implemented.");
|
||||
throw new Error('Function not implemented.');
|
||||
},
|
||||
preloadInstance: function (): boolean {
|
||||
throw new Error("Function not implemented.");
|
||||
throw new Error('Function not implemented.');
|
||||
},
|
||||
startSuspendingCommit: function (): void {
|
||||
throw new Error("Function not implemented.");
|
||||
throw new Error('Function not implemented.');
|
||||
},
|
||||
suspendInstance: function (): void {
|
||||
throw new Error("Function not implemented.");
|
||||
throw new Error('Function not implemented.');
|
||||
},
|
||||
waitForCommitToBeReady: function () {
|
||||
throw new Error("Function not implemented.");
|
||||
},
|
||||
throw new Error('Function not implemented.');
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,30 +1,27 @@
|
|||
import { createInterface } from "readline";
|
||||
import { writeLog, writeOutput } from "./io";
|
||||
import { runPlugin } from "./plugin";
|
||||
import { instances } from "./state";
|
||||
import { batchedUpdates } from "./reconciler";
|
||||
import { createInterface } from 'readline';
|
||||
import { writeLog, writeOutput } from './io';
|
||||
import { runPlugin } from './plugin';
|
||||
import { instances } from './state';
|
||||
import { batchedUpdates } from './reconciler';
|
||||
|
||||
process.on("unhandledRejection", (reason: unknown) => {
|
||||
process.on('unhandledRejection', (reason: unknown) => {
|
||||
writeLog(`--- UNHANDLED PROMISE REJECTION ---`);
|
||||
const stack =
|
||||
reason && typeof reason === "object" && "stack" in reason
|
||||
? reason.stack
|
||||
: reason;
|
||||
const stack = reason && typeof reason === 'object' && 'stack' in reason ? reason.stack : reason;
|
||||
writeLog(stack);
|
||||
});
|
||||
|
||||
const rl = createInterface({ input: process.stdin });
|
||||
|
||||
rl.on("line", (line) => {
|
||||
rl.on('line', (line) => {
|
||||
batchedUpdates(() => {
|
||||
try {
|
||||
const command: { action: string; payload: unknown } = JSON.parse(line);
|
||||
|
||||
switch (command.action) {
|
||||
case "run-plugin":
|
||||
case 'run-plugin':
|
||||
runPlugin();
|
||||
break;
|
||||
case "dispatch-event": {
|
||||
case 'dispatch-event': {
|
||||
const { instanceId, handlerName, args } = command.payload as {
|
||||
instanceId: number;
|
||||
handlerName: string;
|
||||
|
@ -39,12 +36,10 @@ rl.on("line", (line) => {
|
|||
|
||||
const handler = instance._internalFiber?.memoizedProps?.[handlerName];
|
||||
|
||||
if (typeof handler === "function") {
|
||||
if (typeof handler === 'function') {
|
||||
handler(...args);
|
||||
} else {
|
||||
writeLog(
|
||||
`Handler ${handlerName} not found on instance ${instanceId}`
|
||||
);
|
||||
writeLog(`Handler ${handlerName} not found on instance ${instanceId}`);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -56,10 +51,10 @@ rl.on("line", (line) => {
|
|||
err instanceof Error
|
||||
? { message: err.message, stack: err.stack }
|
||||
: { message: String(err) };
|
||||
writeLog(`ERROR: ${error.message} \n ${error.stack ?? ""}`);
|
||||
writeOutput({ type: "error", payload: error.message });
|
||||
writeLog(`ERROR: ${error.message} \n ${error.stack ?? ''}`);
|
||||
writeOutput({ type: 'error', payload: error.message });
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
writeLog("Node.js Sidecar started successfully with React Reconciler.");
|
||||
writeLog('Node.js Sidecar started successfully with React Reconciler.');
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Packr } from "msgpackr";
|
||||
import { Packr } from 'msgpackr';
|
||||
|
||||
const packr = new Packr();
|
||||
|
||||
|
@ -12,7 +12,7 @@ export const writeOutput = (data: object): void => {
|
|||
process.stdout.write(payload);
|
||||
} catch (e: unknown) {
|
||||
const errorString = e instanceof Error ? e.toString() : String(e);
|
||||
const errorPayload = packr.pack({ type: "log", payload: errorString });
|
||||
const errorPayload = packr.pack({ type: 'log', payload: errorString });
|
||||
const errorHeader = Buffer.alloc(4);
|
||||
errorHeader.writeUInt32BE(errorPayload.length);
|
||||
process.stdout.write(errorHeader);
|
||||
|
@ -21,5 +21,5 @@ export const writeOutput = (data: object): void => {
|
|||
};
|
||||
|
||||
export const writeLog = (message: unknown): void => {
|
||||
writeOutput({ type: "log", payload: message });
|
||||
writeOutput({ type: 'log', payload: message });
|
||||
};
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
import React from "react";
|
||||
import { jsx } from "react/jsx-runtime";
|
||||
import plugin from "../dist/plugin/emoji.txt";
|
||||
import { updateContainer } from "./reconciler";
|
||||
import { writeLog } from "./io";
|
||||
import React from 'react';
|
||||
import { jsx } from 'react/jsx-runtime';
|
||||
import plugin from '../dist/plugin/emoji.txt';
|
||||
import { updateContainer } from './reconciler';
|
||||
import { writeLog } from './io';
|
||||
|
||||
const createPluginRequire =
|
||||
() =>
|
||||
(moduleName: string): unknown => {
|
||||
if (moduleName === "react") {
|
||||
if (moduleName === 'react') {
|
||||
return React;
|
||||
}
|
||||
|
||||
if (moduleName.startsWith("@raycast/api")) {
|
||||
if (moduleName.startsWith('@raycast/api')) {
|
||||
const storage = new Map<string, string>();
|
||||
const LocalStorage = {
|
||||
getItem: async (key: string) => storage.get(key),
|
||||
setItem: async (key: string, value: string) => storage.set(key, value),
|
||||
removeItem: async (key: string) => storage.delete(key),
|
||||
clear: async () => storage.clear(),
|
||||
clear: async () => storage.clear()
|
||||
};
|
||||
|
||||
const createWrapperComponent =
|
||||
|
@ -25,33 +25,31 @@ const createPluginRequire =
|
|||
({ children, ...rest }: { children?: React.ReactNode }) =>
|
||||
jsx(name, { ...rest, children });
|
||||
|
||||
const ListComponent = createWrapperComponent("List");
|
||||
const ListSectionComponent = createWrapperComponent("ListSection");
|
||||
const ListDropdownComponent = createWrapperComponent("ListDropdown");
|
||||
const ActionPanelComponent = createWrapperComponent("ActionPanel");
|
||||
const ActionPanelSectionComponent =
|
||||
createWrapperComponent("ActionPanelSection");
|
||||
const ListComponent = createWrapperComponent('List');
|
||||
const ListSectionComponent = createWrapperComponent('ListSection');
|
||||
const ListDropdownComponent = createWrapperComponent('ListDropdown');
|
||||
const ActionPanelComponent = createWrapperComponent('ActionPanel');
|
||||
const ActionPanelSectionComponent = createWrapperComponent('ActionPanelSection');
|
||||
|
||||
Object.assign(ListComponent, {
|
||||
Item: "ListItem",
|
||||
Item: 'ListItem',
|
||||
Section: ListSectionComponent,
|
||||
Dropdown: ListDropdownComponent,
|
||||
Dropdown: ListDropdownComponent
|
||||
});
|
||||
Object.assign(ListDropdownComponent, { Item: "ListDropdownItem" });
|
||||
Object.assign(ListDropdownComponent, { Item: 'ListDropdownItem' });
|
||||
Object.assign(ActionPanelComponent, {
|
||||
Section: ActionPanelSectionComponent,
|
||||
Section: ActionPanelSectionComponent
|
||||
});
|
||||
|
||||
return {
|
||||
LocalStorage,
|
||||
environment: {
|
||||
assetsPath:
|
||||
"/home/byte/code/raycast-linux/sidecar/dist/plugin/assets/",
|
||||
assetsPath: '/home/byte/code/raycast-linux/sidecar/dist/plugin/assets/'
|
||||
},
|
||||
getPreferenceValues: () => ({
|
||||
primaryAction: "paste",
|
||||
unicodeVersion: "14.0",
|
||||
shortCodes: true,
|
||||
primaryAction: 'paste',
|
||||
unicodeVersion: '14.0',
|
||||
shortCodes: true
|
||||
}),
|
||||
usePersistentState: <T>(
|
||||
key: string,
|
||||
|
@ -63,10 +61,10 @@ const createPluginRequire =
|
|||
List: ListComponent,
|
||||
ActionPanel: ActionPanelComponent,
|
||||
Action: {
|
||||
Paste: "Action.Paste",
|
||||
CopyToClipboard: "Action.CopyToClipboard",
|
||||
OpenInBrowser: "Action.OpenInBrowser",
|
||||
},
|
||||
Paste: 'Action.Paste',
|
||||
CopyToClipboard: 'Action.CopyToClipboard',
|
||||
OpenInBrowser: 'Action.OpenInBrowser'
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -76,32 +74,21 @@ const createPluginRequire =
|
|||
export const runPlugin = (): void => {
|
||||
const scriptText = plugin;
|
||||
const pluginModule = {
|
||||
exports: {} as { default: React.ComponentType | null },
|
||||
exports: {} as { default: React.ComponentType | null }
|
||||
};
|
||||
const scriptFunction = new Function(
|
||||
"require",
|
||||
"module",
|
||||
"exports",
|
||||
"React",
|
||||
scriptText
|
||||
);
|
||||
const scriptFunction = new Function('require', 'module', 'exports', 'React', scriptText);
|
||||
|
||||
scriptFunction(
|
||||
createPluginRequire(),
|
||||
pluginModule,
|
||||
pluginModule.exports,
|
||||
React
|
||||
);
|
||||
scriptFunction(createPluginRequire(), pluginModule, pluginModule.exports, React);
|
||||
|
||||
const PluginRootComponent = pluginModule.exports.default;
|
||||
|
||||
if (!PluginRootComponent) {
|
||||
throw new Error("Plugin did not export a default component.");
|
||||
throw new Error('Plugin did not export a default component.');
|
||||
}
|
||||
|
||||
writeLog("Plugin loaded. Initializing React render...");
|
||||
writeLog('Plugin loaded. Initializing React render...');
|
||||
const AppElement = React.createElement(PluginRootComponent);
|
||||
updateContainer(AppElement, () => {
|
||||
writeLog("Initial render complete");
|
||||
writeLog('Initial render complete');
|
||||
});
|
||||
};
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import Reconciler, { type RootTag } from "react-reconciler";
|
||||
import type React from "react";
|
||||
import { root } from "./state";
|
||||
import { hostConfig } from "./hostConfig";
|
||||
import { writeLog } from "./io";
|
||||
import Reconciler, { type RootTag } from 'react-reconciler';
|
||||
import type React from 'react';
|
||||
import { root } from './state';
|
||||
import { hostConfig } from './hostConfig';
|
||||
import { writeLog } from './io';
|
||||
|
||||
const reconciler = Reconciler(hostConfig);
|
||||
|
||||
|
@ -17,15 +17,12 @@ export const container = reconciler.createContainer(
|
|||
null,
|
||||
false,
|
||||
null,
|
||||
"",
|
||||
'',
|
||||
onRecoverableError,
|
||||
null
|
||||
);
|
||||
|
||||
export const updateContainer = (
|
||||
element: React.ReactElement,
|
||||
callback?: () => void
|
||||
) => {
|
||||
export const updateContainer = (element: React.ReactElement, callback?: () => void) => {
|
||||
reconciler.updateContainer(element, container, null, callback);
|
||||
};
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import type { AnyInstance, Commit, Container } from "./types";
|
||||
import type { AnyInstance, Commit, Container } from './types';
|
||||
|
||||
export const instances = new Map<number, AnyInstance>();
|
||||
export const root: Container = { id: "root", children: [] };
|
||||
export const root: Container = { id: 'root', children: [] };
|
||||
|
||||
let instanceCounter = 0;
|
||||
export const getNextInstanceId = (): number => ++instanceCounter;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import type React from "react";
|
||||
import type Reconciler from "react-reconciler";
|
||||
import type React from 'react';
|
||||
import type Reconciler from 'react-reconciler';
|
||||
|
||||
export type ComponentType = string | React.ComponentType<any>;
|
||||
export type ComponentProps = Record<string, unknown>;
|
||||
|
@ -16,12 +16,12 @@ export interface RaycastInstance extends BaseInstance {
|
|||
}
|
||||
|
||||
export interface TextInstance extends BaseInstance {
|
||||
type: "TEXT";
|
||||
type: 'TEXT';
|
||||
text: string;
|
||||
}
|
||||
|
||||
export interface Container {
|
||||
id: "root";
|
||||
id: 'root';
|
||||
children: (RaycastInstance | TextInstance)[];
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@ export interface Commit {
|
|||
}
|
||||
|
||||
export interface SerializedReactElement {
|
||||
$$typeof: "react.element.serialized";
|
||||
$$typeof: 'react.element.serialized';
|
||||
type: string;
|
||||
props: Record<string, unknown>;
|
||||
}
|
||||
|
|
|
@ -1,41 +1,29 @@
|
|||
import React from "react";
|
||||
import type {
|
||||
ComponentType,
|
||||
Commit,
|
||||
SerializedReactElement,
|
||||
ParentInstance,
|
||||
} from "./types";
|
||||
import { root, instances } from "./state";
|
||||
import React from 'react';
|
||||
import type { ComponentType, Commit, SerializedReactElement, ParentInstance } from './types';
|
||||
import { root, instances } from './state';
|
||||
|
||||
export const getComponentDisplayName = (type: ComponentType): string => {
|
||||
if (typeof type === "string") {
|
||||
if (typeof type === 'string') {
|
||||
return type;
|
||||
}
|
||||
return type.displayName ?? type.name ?? "Anonymous";
|
||||
return type.displayName ?? type.name ?? 'Anonymous';
|
||||
};
|
||||
|
||||
const isSerializableReactElement = (
|
||||
value: unknown
|
||||
): value is React.ReactElement => React.isValidElement(value);
|
||||
const isSerializableReactElement = (value: unknown): value is React.ReactElement =>
|
||||
React.isValidElement(value);
|
||||
|
||||
function serializeReactElement(
|
||||
element: React.ReactElement
|
||||
): SerializedReactElement {
|
||||
function serializeReactElement(element: React.ReactElement): SerializedReactElement {
|
||||
return {
|
||||
$$typeof: "react.element.serialized",
|
||||
$$typeof: 'react.element.serialized',
|
||||
type: getComponentDisplayName(element.type as ComponentType),
|
||||
props: serializeProps(element.props as Record<string, unknown>),
|
||||
props: serializeProps(element.props as Record<string, unknown>)
|
||||
};
|
||||
}
|
||||
|
||||
export function serializeProps(
|
||||
props: Record<string, unknown>
|
||||
): Record<string, unknown> {
|
||||
export function serializeProps(props: Record<string, unknown>): Record<string, unknown> {
|
||||
return Object.fromEntries(
|
||||
Object.entries(props)
|
||||
.filter(
|
||||
([key, value]) => key !== "children" && typeof value !== "function"
|
||||
)
|
||||
.filter(([key, value]) => key !== 'children' && typeof value !== 'function')
|
||||
.map(([key, value]) => {
|
||||
if (isSerializableReactElement(value)) {
|
||||
return [key, serializeReactElement(value)];
|
||||
|
@ -44,10 +32,8 @@ export function serializeProps(
|
|||
return [
|
||||
key,
|
||||
value.map((item) =>
|
||||
isSerializableReactElement(item)
|
||||
? serializeReactElement(item)
|
||||
: item
|
||||
),
|
||||
isSerializableReactElement(item) ? serializeReactElement(item) : item
|
||||
)
|
||||
];
|
||||
}
|
||||
return [key, value];
|
||||
|
@ -57,23 +43,18 @@ export function serializeProps(
|
|||
|
||||
export function optimizeCommitBuffer(buffer: Commit[]): Commit[] {
|
||||
const OPTIMIZATION_THRESHOLD = 10;
|
||||
const childOpsByParent = new Map<ParentInstance["id"], Commit[]>();
|
||||
const childOpsByParent = new Map<ParentInstance['id'], Commit[]>();
|
||||
const otherOps: Commit[] = [];
|
||||
|
||||
for (const op of buffer) {
|
||||
const { type, payload } = op;
|
||||
const parentId = (payload as { parentId?: ParentInstance["id"] })?.parentId;
|
||||
const parentId = (payload as { parentId?: ParentInstance['id'] })?.parentId;
|
||||
|
||||
const isChildOp =
|
||||
type === "APPEND_CHILD" ||
|
||||
type === "REMOVE_CHILD" ||
|
||||
type === "INSERT_BEFORE";
|
||||
type === 'APPEND_CHILD' || type === 'REMOVE_CHILD' || type === 'INSERT_BEFORE';
|
||||
|
||||
if (isChildOp && parentId) {
|
||||
childOpsByParent.set(
|
||||
parentId,
|
||||
(childOpsByParent.get(parentId) ?? []).concat(op)
|
||||
);
|
||||
childOpsByParent.set(parentId, (childOpsByParent.get(parentId) ?? []).concat(op));
|
||||
} else {
|
||||
otherOps.push(op);
|
||||
}
|
||||
|
@ -91,14 +72,13 @@ export function optimizeCommitBuffer(buffer: Commit[]): Commit[] {
|
|||
continue;
|
||||
}
|
||||
|
||||
const parentInstance =
|
||||
parentId === "root" ? root : instances.get(parentId as number);
|
||||
const parentInstance = parentId === 'root' ? root : instances.get(parentId as number);
|
||||
|
||||
if (parentInstance && "children" in parentInstance) {
|
||||
if (parentInstance && 'children' in parentInstance) {
|
||||
const childrenIds = parentInstance.children.map(({ id }) => id);
|
||||
finalOps.push({
|
||||
type: "REPLACE_CHILDREN",
|
||||
payload: { parentId, childrenIds },
|
||||
type: 'REPLACE_CHILDREN',
|
||||
payload: { parentId, childrenIds }
|
||||
});
|
||||
} else {
|
||||
finalOps.push(...ops);
|
||||
|
|
|
@ -1,22 +1,18 @@
|
|||
import { setResults } from "../results.svelte";
|
||||
import type * as api from "@raycast/api";
|
||||
import { Toast } from "./toast";
|
||||
import {
|
||||
writeText,
|
||||
writeHtml,
|
||||
writeImage,
|
||||
} from "@tauri-apps/plugin-clipboard-manager";
|
||||
import { setResults } from '../results.svelte';
|
||||
import type * as api from '@raycast/api';
|
||||
import { Toast } from './toast';
|
||||
import { writeText, writeHtml, writeImage } from '@tauri-apps/plugin-clipboard-manager';
|
||||
|
||||
export const mockRaycastApi = {
|
||||
updateCommandMetadata: async (metadata: { subtitle?: string | null }) => {
|
||||
setResults([{ subtitle: metadata.subtitle }]);
|
||||
},
|
||||
environment: {
|
||||
launchType: "userInitiated",
|
||||
launchType: 'userInitiated'
|
||||
},
|
||||
LaunchType: {
|
||||
UserInitiated: "userInitiated",
|
||||
Background: "background",
|
||||
UserInitiated: 'userInitiated',
|
||||
Background: 'background'
|
||||
},
|
||||
Toast: Toast as typeof api.Toast,
|
||||
Clipboard: {
|
||||
|
@ -24,17 +20,17 @@ export const mockRaycastApi = {
|
|||
content: string | number | api.Clipboard.Content,
|
||||
options?: api.Clipboard.CopyOptions
|
||||
) => {
|
||||
if (typeof content === "string" || typeof content === "number") {
|
||||
if (typeof content === 'string' || typeof content === 'number') {
|
||||
await writeText(content.toString());
|
||||
} else {
|
||||
if ("html" in content) {
|
||||
if ('html' in content) {
|
||||
await writeHtml(content.html);
|
||||
} else if ("file" in content) {
|
||||
} else if ('file' in content) {
|
||||
await writeImage(content.file);
|
||||
} else {
|
||||
await writeText(content.text);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
} satisfies typeof api;
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
import { setToast } from "$lib/results.svelte";
|
||||
import type * as api from "@raycast/api";
|
||||
import { setToast } from '$lib/results.svelte';
|
||||
import type * as api from '@raycast/api';
|
||||
|
||||
export class Toast {
|
||||
public static readonly Style = {
|
||||
Success: "SUCCESS",
|
||||
Failure: "FAILURE",
|
||||
Animated: "ANIMATED",
|
||||
Success: 'SUCCESS',
|
||||
Failure: 'FAILURE',
|
||||
Animated: 'ANIMATED'
|
||||
};
|
||||
|
||||
public style: "SUCCESS" | "FAILURE" | "ANIMATED";
|
||||
public style: 'SUCCESS' | 'FAILURE' | 'ANIMATED';
|
||||
public title: string;
|
||||
public message: string | undefined;
|
||||
public primaryAction: api.Toast.ActionOptions | undefined;
|
||||
public secondaryAction: api.Toast.ActionOptions | undefined;
|
||||
|
||||
constructor(props: api.Toast.Options) {
|
||||
this.style = props.style ?? "SUCCESS"; // TODO: is this default value correct?
|
||||
this.style = props.style ?? 'SUCCESS'; // TODO: is this default value correct?
|
||||
this.title = props.title;
|
||||
this.message = props.message;
|
||||
this.primaryAction = props.primaryAction;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<!-- src/ResultsList.svelte -->
|
||||
<script lang="ts">
|
||||
import { getResults } from "$lib/results.svelte";
|
||||
import { getResults } from '$lib/results.svelte';
|
||||
|
||||
const pluginResults = $derived(getResults());
|
||||
</script>
|
||||
|
@ -8,10 +8,8 @@
|
|||
<div class="flex-grow overflow-y-auto">
|
||||
<ul>
|
||||
{#each pluginResults as result}
|
||||
<li
|
||||
class="flex items-center p-2 rounded-lg hover:bg-blue-500/20 cursor-pointer"
|
||||
>
|
||||
<div class="flex flex-col ml-2">
|
||||
<li class="flex cursor-pointer items-center rounded-lg p-2 hover:bg-blue-500/20">
|
||||
<div class="ml-2 flex flex-col">
|
||||
<span class="text-xs text-gray-400">{result.subtitle}</span>
|
||||
</div>
|
||||
</li>
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
<script lang="ts">
|
||||
import { Separator } from "./ui/separator";
|
||||
import { getToast } from "../results.svelte";
|
||||
import { Toast } from "$lib/api/toast";
|
||||
import { Button } from "./ui/button";
|
||||
import type * as api from "@raycast/api";
|
||||
import { Kbd } from "./ui/kbd";
|
||||
import { shortcutToText } from "$lib/renderKey";
|
||||
import { Separator } from './ui/separator';
|
||||
import { getToast } from '../results.svelte';
|
||||
import { Toast } from '$lib/api/toast';
|
||||
import { Button } from './ui/button';
|
||||
import type * as api from '@raycast/api';
|
||||
import { Kbd } from './ui/kbd';
|
||||
import { shortcutToText } from '$lib/renderKey';
|
||||
|
||||
const toast = getToast();
|
||||
|
||||
const styles = $derived.by(() => {
|
||||
switch (toast?.style) {
|
||||
case Toast.Style.Success:
|
||||
return "bg-green-500/20";
|
||||
return 'bg-green-500/20';
|
||||
case Toast.Style.Failure:
|
||||
return "bg-red-500/20";
|
||||
return 'bg-red-500/20';
|
||||
default:
|
||||
return "bg-gray-500/20";
|
||||
return 'bg-gray-500/20';
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
@ -26,13 +26,13 @@
|
|||
{#if toast}
|
||||
{@const actualToast = toast as Toast}
|
||||
|
||||
<div class="py-2 px-4 flex items-center gap-4 {styles}">
|
||||
{#if actualToast.style === "SUCCESS"}
|
||||
<div class="w-2.5 h-2.5 bg-green-500 rounded-full"></div>
|
||||
{:else if actualToast.style === "FAILURE"}
|
||||
<div class="w-2.5 h-2.5 bg-red-500 rounded-full"></div>
|
||||
{:else if actualToast.style === "ANIMATED"}
|
||||
<div class="w-2.5 h-2.5 bg-gray-500 rounded-full"></div>
|
||||
<div class="flex items-center gap-4 px-4 py-2 {styles}">
|
||||
{#if actualToast.style === 'SUCCESS'}
|
||||
<div class="h-2.5 w-2.5 rounded-full bg-green-500"></div>
|
||||
{:else if actualToast.style === 'FAILURE'}
|
||||
<div class="h-2.5 w-2.5 rounded-full bg-red-500"></div>
|
||||
{:else if actualToast.style === 'ANIMATED'}
|
||||
<div class="h-2.5 w-2.5 rounded-full bg-gray-500"></div>
|
||||
{/if}
|
||||
|
||||
{actualToast.title}
|
||||
|
@ -42,8 +42,7 @@
|
|||
{#if actualToast.primaryAction}
|
||||
<Button
|
||||
variant="ghost"
|
||||
onclick={() =>
|
||||
actualToast.primaryAction!.onAction(actualToast as api.Toast)}
|
||||
onclick={() => actualToast.primaryAction!.onAction(actualToast as api.Toast)}
|
||||
>
|
||||
{actualToast.primaryAction.title}
|
||||
|
||||
|
|
|
@ -1,36 +1,36 @@
|
|||
<script lang="ts" module>
|
||||
import { cn, type WithElementRef } from "$lib/utils.js";
|
||||
import type { HTMLAnchorAttributes, HTMLButtonAttributes } from "svelte/elements";
|
||||
import { type VariantProps, tv } from "tailwind-variants";
|
||||
import { cn, type WithElementRef } from '$lib/utils.js';
|
||||
import type { HTMLAnchorAttributes, HTMLButtonAttributes } from 'svelte/elements';
|
||||
import { type VariantProps, tv } from 'tailwind-variants';
|
||||
|
||||
export const buttonVariants = tv({
|
||||
base: "focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive inline-flex shrink-0 items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium outline-none transition-all focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
||||
variants: {
|
||||
variant: {
|
||||
default: "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
|
||||
default: 'bg-primary text-primary-foreground shadow-xs hover:bg-primary/90',
|
||||
destructive:
|
||||
"bg-destructive shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60 text-white",
|
||||
'bg-destructive shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60 text-white',
|
||||
outline:
|
||||
"bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50 border",
|
||||
secondary: "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
|
||||
ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
|
||||
link: "text-primary underline-offset-4 hover:underline",
|
||||
'bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50 border',
|
||||
secondary: 'bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80',
|
||||
ghost: 'hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50',
|
||||
link: 'text-primary underline-offset-4 hover:underline'
|
||||
},
|
||||
size: {
|
||||
default: "h-9 px-4 py-2 has-[>svg]:px-3",
|
||||
sm: "h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5",
|
||||
lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
|
||||
icon: "size-9",
|
||||
},
|
||||
default: 'h-9 px-4 py-2 has-[>svg]:px-3',
|
||||
sm: 'h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5',
|
||||
lg: 'h-10 rounded-md px-6 has-[>svg]:px-4',
|
||||
icon: 'size-9'
|
||||
}
|
||||
},
|
||||
defaultVariants: {
|
||||
variant: "default",
|
||||
size: "default",
|
||||
},
|
||||
variant: 'default',
|
||||
size: 'default'
|
||||
}
|
||||
});
|
||||
|
||||
export type ButtonVariant = VariantProps<typeof buttonVariants>["variant"];
|
||||
export type ButtonSize = VariantProps<typeof buttonVariants>["size"];
|
||||
export type ButtonVariant = VariantProps<typeof buttonVariants>['variant'];
|
||||
export type ButtonSize = VariantProps<typeof buttonVariants>['size'];
|
||||
|
||||
export type ButtonProps = WithElementRef<HTMLButtonAttributes> &
|
||||
WithElementRef<HTMLAnchorAttributes> & {
|
||||
|
@ -42,11 +42,11 @@
|
|||
<script lang="ts">
|
||||
let {
|
||||
class: className,
|
||||
variant = "default",
|
||||
size = "default",
|
||||
variant = 'default',
|
||||
size = 'default',
|
||||
ref = $bindable(null),
|
||||
href = undefined,
|
||||
type = "button",
|
||||
type = 'button',
|
||||
disabled,
|
||||
children,
|
||||
...restProps
|
||||
|
@ -60,7 +60,7 @@
|
|||
class={cn(buttonVariants({ variant, size }), className)}
|
||||
href={disabled ? undefined : href}
|
||||
aria-disabled={disabled}
|
||||
role={disabled ? "link" : undefined}
|
||||
role={disabled ? 'link' : undefined}
|
||||
tabindex={disabled ? -1 : undefined}
|
||||
{...restProps}
|
||||
>
|
||||
|
|
|
@ -2,8 +2,8 @@ import Root, {
|
|||
type ButtonProps,
|
||||
type ButtonSize,
|
||||
type ButtonVariant,
|
||||
buttonVariants,
|
||||
} from "./button.svelte";
|
||||
buttonVariants
|
||||
} from './button.svelte';
|
||||
|
||||
export {
|
||||
Root,
|
||||
|
@ -13,5 +13,5 @@ export {
|
|||
buttonVariants,
|
||||
type ButtonProps,
|
||||
type ButtonSize,
|
||||
type ButtonVariant,
|
||||
type ButtonVariant
|
||||
};
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import Root from "./input.svelte";
|
||||
import Root from './input.svelte';
|
||||
|
||||
export {
|
||||
Root,
|
||||
//
|
||||
Root as Input,
|
||||
Root as Input
|
||||
};
|
||||
|
|
|
@ -1,18 +1,12 @@
|
|||
<script lang="ts">
|
||||
import type {
|
||||
HTMLInputAttributes,
|
||||
HTMLInputTypeAttribute,
|
||||
} from "svelte/elements";
|
||||
import { cn, type WithElementRef } from "$lib/utils.js";
|
||||
import type { HTMLInputAttributes, HTMLInputTypeAttribute } from 'svelte/elements';
|
||||
import { cn, type WithElementRef } from '$lib/utils.js';
|
||||
|
||||
type InputType = Exclude<HTMLInputTypeAttribute, "file">;
|
||||
type InputType = Exclude<HTMLInputTypeAttribute, 'file'>;
|
||||
|
||||
type Props = WithElementRef<
|
||||
Omit<HTMLInputAttributes, "type"> &
|
||||
(
|
||||
| { type: "file"; files?: FileList }
|
||||
| { type?: InputType; files?: undefined }
|
||||
)
|
||||
Omit<HTMLInputAttributes, 'type'> &
|
||||
({ type: 'file'; files?: FileList } | { type?: InputType; files?: undefined })
|
||||
>;
|
||||
|
||||
let {
|
||||
|
@ -25,14 +19,14 @@
|
|||
}: Props = $props();
|
||||
</script>
|
||||
|
||||
{#if type === "file"}
|
||||
{#if type === 'file'}
|
||||
<input
|
||||
bind:this={ref}
|
||||
data-slot="input"
|
||||
class={cn(
|
||||
"selection:bg-primary dark:bg-input/30 selection:text-primary-foreground border-input ring-offset-background placeholder:text-muted-foreground shadow-xs flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 pt-1.5 text-sm font-medium outline-none transition-[color,box-shadow] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
||||
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
|
||||
"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
|
||||
'selection:bg-primary dark:bg-input/30 selection:text-primary-foreground border-input ring-offset-background placeholder:text-muted-foreground flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 pt-1.5 text-sm font-medium shadow-xs transition-[color,box-shadow] outline-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',
|
||||
'focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]',
|
||||
'aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive',
|
||||
className
|
||||
)}
|
||||
type="file"
|
||||
|
@ -45,8 +39,8 @@
|
|||
bind:this={ref}
|
||||
data-slot="input"
|
||||
class={cn(
|
||||
"border-input bg-background selection:bg-primary dark:bg-input/30 selection:text-primary-foreground ring-offset-background placeholder:text-muted-foreground shadow-xs flex h-9 w-full min-w-0 rounded-md border px-3 py-1 text-base outline-none transition-[color,box-shadow] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
||||
"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
|
||||
'border-input bg-background selection:bg-primary dark:bg-input/30 selection:text-primary-foreground ring-offset-background placeholder:text-muted-foreground flex h-9 w-full min-w-0 rounded-md border px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',
|
||||
'aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive',
|
||||
className
|
||||
)}
|
||||
{type}
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
import Kbd from "./kbd.svelte";
|
||||
import Kbd from './kbd.svelte';
|
||||
|
||||
export { Kbd };
|
||||
|
|
|
@ -1,25 +1,25 @@
|
|||
<script lang="ts" module>
|
||||
import { tv, type VariantProps } from "tailwind-variants";
|
||||
import type { WithChildren } from "bits-ui";
|
||||
import { tv, type VariantProps } from 'tailwind-variants';
|
||||
import type { WithChildren } from 'bits-ui';
|
||||
|
||||
const style = tv({
|
||||
base: "inline-flex place-items-center justify-center gap-1 rounded-md p-0.5",
|
||||
base: 'inline-flex place-items-center justify-center gap-1 rounded-md p-0.5',
|
||||
variants: {
|
||||
variant: {
|
||||
outline: "border-border bg-background text-muted-foreground border",
|
||||
secondary: "bg-secondary text-muted-foreground",
|
||||
primary: "bg-primary text-primary-foreground",
|
||||
outline: 'border-border bg-background text-muted-foreground border',
|
||||
secondary: 'bg-secondary text-muted-foreground',
|
||||
primary: 'bg-primary text-primary-foreground'
|
||||
},
|
||||
size: {
|
||||
sm: "min-w-6 gap-1.5 p-0.5 px-1 text-sm",
|
||||
default: "min-w-8 gap-1.5 p-1 px-2",
|
||||
lg: "min-w-9 gap-2 p-1 px-3 text-lg",
|
||||
},
|
||||
},
|
||||
sm: 'min-w-6 gap-1.5 p-0.5 px-1 text-sm',
|
||||
default: 'min-w-8 gap-1.5 p-1 px-2',
|
||||
lg: 'min-w-9 gap-2 p-1 px-3 text-lg'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
type Size = VariantProps<typeof style>["size"];
|
||||
type Variant = VariantProps<typeof style>["variant"];
|
||||
type Size = VariantProps<typeof style>['size'];
|
||||
type Variant = VariantProps<typeof style>['variant'];
|
||||
|
||||
export type KbdPropsWithoutHTML = WithChildren<{
|
||||
ref?: HTMLElement | null;
|
||||
|
@ -32,14 +32,14 @@
|
|||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { cn } from "$lib/utils";
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
let {
|
||||
ref = $bindable(null),
|
||||
class: className,
|
||||
size = "default",
|
||||
variant = "outline",
|
||||
children,
|
||||
size = 'default',
|
||||
variant = 'outline',
|
||||
children
|
||||
}: KbdProps = $props();
|
||||
</script>
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import Root from "./separator.svelte";
|
||||
import Root from './separator.svelte';
|
||||
|
||||
export {
|
||||
Root,
|
||||
//
|
||||
Root as Separator,
|
||||
Root as Separator
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<script lang="ts">
|
||||
import { Separator as SeparatorPrimitive } from "bits-ui";
|
||||
import { cn } from "$lib/utils.js";
|
||||
import { Separator as SeparatorPrimitive } from 'bits-ui';
|
||||
import { cn } from '$lib/utils.js';
|
||||
|
||||
let {
|
||||
ref = $bindable(null),
|
||||
|
@ -13,7 +13,7 @@
|
|||
bind:ref
|
||||
data-slot="separator"
|
||||
class={cn(
|
||||
"bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=vertical]:h-full data-[orientation=horizontal]:w-full data-[orientation=vertical]:w-px",
|
||||
'bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px',
|
||||
className
|
||||
)}
|
||||
{...restProps}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { mockRaycastApi } from "./api";
|
||||
import plugin from "./plugin.js?raw";
|
||||
import { mockRaycastApi } from './api';
|
||||
import plugin from './plugin.js?raw';
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
|
@ -10,42 +10,36 @@ declare global {
|
|||
|
||||
window.require = function (moduleName) {
|
||||
console.log(`Plugin is requesting module: ${moduleName}`);
|
||||
if (moduleName === "@raycast/api") {
|
||||
if (moduleName === '@raycast/api') {
|
||||
return mockRaycastApi;
|
||||
}
|
||||
throw new Error(
|
||||
`Module not found: ${moduleName}. Our fake 'require' is very limited!`
|
||||
);
|
||||
throw new Error(`Module not found: ${moduleName}. Our fake 'require' is very limited!`);
|
||||
};
|
||||
|
||||
window.module = {
|
||||
exports: {},
|
||||
exports: {}
|
||||
};
|
||||
|
||||
export async function runPlugin() {
|
||||
console.log("Requesting plugin script from Rust backend...");
|
||||
console.log('Requesting plugin script from Rust backend...');
|
||||
const scriptText = plugin;
|
||||
|
||||
console.log("Executing plugin script in a try/catch block...");
|
||||
console.log('Executing plugin script in a try/catch block...');
|
||||
try {
|
||||
// TOOD: don't use eval
|
||||
eval(scriptText);
|
||||
} catch (e) {
|
||||
console.error("Error evaluating plugin script:", e);
|
||||
console.error('Error evaluating plugin script:', e);
|
||||
return;
|
||||
}
|
||||
|
||||
const pluginMainFunction = window.module.exports.default;
|
||||
|
||||
if (pluginMainFunction && typeof pluginMainFunction === "function") {
|
||||
console.log(
|
||||
"Plugin script loaded successfully. Running its main command..."
|
||||
);
|
||||
if (pluginMainFunction && typeof pluginMainFunction === 'function') {
|
||||
console.log('Plugin script loaded successfully. Running its main command...');
|
||||
await pluginMainFunction();
|
||||
console.log("Plugin main command finished.");
|
||||
console.log('Plugin main command finished.');
|
||||
} else {
|
||||
console.error(
|
||||
"Could not find a default export function in the plugin script."
|
||||
);
|
||||
console.error('Could not find a default export function in the plugin script.');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,65 +1,61 @@
|
|||
"use strict";
|
||||
'use strict';
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
for (var name in all) __defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if ((from && typeof from === "object") || typeof from === "function") {
|
||||
if ((from && typeof from === 'object') || typeof from === 'function') {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, {
|
||||
get: () => from[key],
|
||||
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable,
|
||||
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
||||
});
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) =>
|
||||
__copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, '__esModule', { value: true }), mod);
|
||||
|
||||
// src/index.ts
|
||||
var src_exports = {};
|
||||
__export(src_exports, {
|
||||
default: () => src_default,
|
||||
default: () => src_default
|
||||
});
|
||||
module.exports = __toCommonJS(src_exports);
|
||||
var import_api = require("@raycast/api");
|
||||
var import_api = require('@raycast/api');
|
||||
var command = async () => {
|
||||
const now = new Date();
|
||||
const london = now.toLocaleString(void 0, {
|
||||
timeZone: "Europe/London",
|
||||
timeStyle: "short",
|
||||
timeZone: 'Europe/London',
|
||||
timeStyle: 'short'
|
||||
});
|
||||
const berlin = now.toLocaleString(void 0, {
|
||||
timeZone: "Europe/Berlin",
|
||||
timeStyle: "short",
|
||||
timeZone: 'Europe/Berlin',
|
||||
timeStyle: 'short'
|
||||
});
|
||||
const moscow = now.toLocaleString(void 0, {
|
||||
timeZone: "Europe/Moscow",
|
||||
timeStyle: "short",
|
||||
timeZone: 'Europe/Moscow',
|
||||
timeStyle: 'short'
|
||||
});
|
||||
const india = now.toLocaleString(void 0, {
|
||||
timeZone: "Asia/Kolkata",
|
||||
timeStyle: "short",
|
||||
timeZone: 'Asia/Kolkata',
|
||||
timeStyle: 'short'
|
||||
});
|
||||
const subtitle = `\u{1F1EC}\u{1F1E7} ${london} \u{1F1F3}\u{1F1F1}\u{1F1E9}\u{1F1EA}\u{1F1F3}\u{1F1F4}\u{1F1E9}\u{1F1F0}\u{1F1F5}\u{1F1F1} ${berlin} \u{1F1F7}\u{1F1FA} ${moscow} \u{1F1EE}\u{1F1F3} ${india}`;
|
||||
await (0, import_api.updateCommandMetadata)({ subtitle });
|
||||
if (
|
||||
import_api.environment.launchType === import_api.LaunchType.UserInitiated
|
||||
) {
|
||||
if (import_api.environment.launchType === import_api.LaunchType.UserInitiated) {
|
||||
const toast = new import_api.Toast({
|
||||
style: import_api.Toast.Style.Success,
|
||||
title: "Refreshed!",
|
||||
message: subtitle,
|
||||
title: 'Refreshed!',
|
||||
message: subtitle
|
||||
});
|
||||
toast.primaryAction = {
|
||||
title: "Copy to Clipboard",
|
||||
shortcut: { modifiers: ["cmd", "shift"], key: "c" },
|
||||
onAction: () => import_api.Clipboard.copy(subtitle),
|
||||
title: 'Copy to Clipboard',
|
||||
shortcut: { modifiers: ['cmd', 'shift'], key: 'c' },
|
||||
onAction: () => import_api.Clipboard.copy(subtitle)
|
||||
};
|
||||
await toast.show();
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { Keyboard } from "@raycast/api";
|
||||
import type { Keyboard } from '@raycast/api';
|
||||
|
||||
type ShortcutParts = {
|
||||
modifiers: Keyboard.KeyModifier[];
|
||||
|
@ -8,32 +8,32 @@ type ShortcutParts = {
|
|||
function formatShortcutParts(parts: ShortcutParts, isMac: boolean): string {
|
||||
const modifierMap = {
|
||||
mac: {
|
||||
cmd: "⌘",
|
||||
ctrl: "⌃",
|
||||
opt: "⌥",
|
||||
shift: "⇧",
|
||||
cmd: '⌘',
|
||||
ctrl: '⌃',
|
||||
opt: '⌥',
|
||||
shift: '⇧'
|
||||
},
|
||||
other: {
|
||||
cmd: "Win",
|
||||
ctrl: "Ctrl",
|
||||
opt: "Alt",
|
||||
shift: "Shift",
|
||||
},
|
||||
cmd: 'Win',
|
||||
ctrl: 'Ctrl',
|
||||
opt: 'Alt',
|
||||
shift: 'Shift'
|
||||
}
|
||||
};
|
||||
|
||||
const keyMap: Partial<Record<Keyboard.KeyEquivalent, string>> = {
|
||||
return: "⏎",
|
||||
enter: "⏎",
|
||||
delete: "⌫",
|
||||
backspace: "⌫",
|
||||
deleteForward: "⌦",
|
||||
arrowUp: "↑",
|
||||
arrowDown: "↓",
|
||||
arrowLeft: "←",
|
||||
arrowRight: "→",
|
||||
tab: "⇥",
|
||||
escape: "⎋",
|
||||
space: "␣",
|
||||
return: '⏎',
|
||||
enter: '⏎',
|
||||
delete: '⌫',
|
||||
backspace: '⌫',
|
||||
deleteForward: '⌦',
|
||||
arrowUp: '↑',
|
||||
arrowDown: '↓',
|
||||
arrowLeft: '←',
|
||||
arrowRight: '→',
|
||||
tab: '⇥',
|
||||
escape: '⎋',
|
||||
space: '␣'
|
||||
};
|
||||
|
||||
const currentModifiers = isMac ? modifierMap.mac : modifierMap.other;
|
||||
|
@ -44,18 +44,15 @@ function formatShortcutParts(parts: ShortcutParts, isMac: boolean): string {
|
|||
|
||||
const allParts = [...modifierStrings, keyString];
|
||||
|
||||
return allParts.join(" + ");
|
||||
return allParts.join(' + ');
|
||||
}
|
||||
|
||||
export function shortcutToText(
|
||||
shortcut: Keyboard.Shortcut,
|
||||
forceOS?: "macOS" | "windows"
|
||||
): string {
|
||||
export function shortcutToText(shortcut: Keyboard.Shortcut, forceOS?: 'macOS' | 'windows'): string {
|
||||
const isMac = forceOS
|
||||
? forceOS === "macOS"
|
||||
: typeof navigator !== "undefined" && /Mac/i.test(navigator.platform);
|
||||
? forceOS === 'macOS'
|
||||
: typeof navigator !== 'undefined' && /Mac/i.test(navigator.platform);
|
||||
|
||||
if ("modifiers" in shortcut) {
|
||||
if ('modifiers' in shortcut) {
|
||||
return formatShortcutParts(shortcut, isMac);
|
||||
} else {
|
||||
if (isMac) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { Toast } from "./api/toast";
|
||||
import type { Toast } from './api/toast';
|
||||
|
||||
type Result = {
|
||||
subtitle?: string | null;
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import { clsx, type ClassValue } from "clsx";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
import { clsx, type ClassValue } from 'clsx';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
return twMerge(clsx(inputs));
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export type WithoutChild<T> = T extends { child?: any } ? Omit<T, "child"> : T;
|
||||
export type WithoutChild<T> = T extends { child?: any } ? Omit<T, 'child'> : T;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export type WithoutChildren<T> = T extends { children?: any } ? Omit<T, "children"> : T;
|
||||
export type WithoutChildren<T> = T extends { children?: any } ? Omit<T, 'children'> : T;
|
||||
export type WithoutChildrenOrChild<T> = WithoutChildren<WithoutChild<T>>;
|
||||
export type WithElementRef<T, U extends HTMLElement = HTMLElement> = T & { ref?: U | null };
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<script lang="ts">
|
||||
import { Command, type Child } from "@tauri-apps/plugin-shell";
|
||||
import { SvelteMap } from "svelte/reactivity";
|
||||
import { Unpackr } from "msgpackr";
|
||||
import { tick } from "svelte";
|
||||
import { VList } from "virtua/svelte";
|
||||
import { Command, type Child } from '@tauri-apps/plugin-shell';
|
||||
import { SvelteMap } from 'svelte/reactivity';
|
||||
import { Unpackr } from 'msgpackr';
|
||||
import { tick } from 'svelte';
|
||||
import { VList } from 'virtua/svelte';
|
||||
|
||||
interface UINode {
|
||||
id: number;
|
||||
|
@ -21,7 +21,7 @@
|
|||
|
||||
type ListItem = {
|
||||
id: number;
|
||||
type: "header" | "item";
|
||||
type: 'header' | 'item';
|
||||
props: Record<string, any>;
|
||||
height: number;
|
||||
};
|
||||
|
@ -41,21 +41,21 @@
|
|||
|
||||
for (const childId of root.children) {
|
||||
const sectionNode = uiTree.get(childId);
|
||||
if (sectionNode && sectionNode.type === "ListSection") {
|
||||
if (sectionNode && sectionNode.type === 'ListSection') {
|
||||
newFlatList.push({
|
||||
id: sectionNode.id,
|
||||
type: "header",
|
||||
type: 'header',
|
||||
props: sectionNode.props,
|
||||
height: HEADER_HEIGHT,
|
||||
height: HEADER_HEIGHT
|
||||
});
|
||||
for (const itemId of sectionNode.children) {
|
||||
const itemNode = uiTree.get(itemId);
|
||||
if (itemNode) {
|
||||
newFlatList.push({
|
||||
id: itemNode.id,
|
||||
type: "item",
|
||||
type: 'item',
|
||||
props: itemNode.props,
|
||||
height: ITEM_HEIGHT,
|
||||
height: ITEM_HEIGHT
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -80,7 +80,7 @@
|
|||
const message = unpackr.unpack(messagePayload);
|
||||
handleSidecarMessage(message);
|
||||
} catch (e) {
|
||||
console.error("Failed to unpack sidecar message:", e);
|
||||
console.error('Failed to unpack sidecar message:', e);
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
|
@ -89,39 +89,36 @@
|
|||
}
|
||||
|
||||
async function connectAndRun() {
|
||||
const command = Command.sidecar("binaries/app", undefined, {
|
||||
encoding: "raw",
|
||||
const command = Command.sidecar('binaries/app', undefined, {
|
||||
encoding: 'raw'
|
||||
});
|
||||
command.stdout.on("data", (chunk) => {
|
||||
command.stdout.on('data', (chunk) => {
|
||||
try {
|
||||
receiveBuffer = Buffer.concat([receiveBuffer, Buffer.from(chunk)]);
|
||||
processReceiveBuffer();
|
||||
} catch (e) {
|
||||
console.error("Failed to parse sidecar message:", chunk, e);
|
||||
console.error('Failed to parse sidecar message:', chunk, e);
|
||||
}
|
||||
});
|
||||
command.stderr.on("data", (line) => {
|
||||
command.stderr.on('data', (line) => {
|
||||
sidecarLogs = [...sidecarLogs, `STDERR: ${line}`];
|
||||
});
|
||||
sidecarChild = await command.spawn();
|
||||
sidecarLogs = [
|
||||
...sidecarLogs,
|
||||
`Sidecar spawned with PID: ${sidecarChild.pid}`,
|
||||
];
|
||||
sidecarLogs = [...sidecarLogs, `Sidecar spawned with PID: ${sidecarChild.pid}`];
|
||||
if (sidecarChild) {
|
||||
sidecarChild.write(JSON.stringify({ action: "run-plugin" }) + "\n");
|
||||
sidecarChild.write(JSON.stringify({ action: 'run-plugin' }) + '\n');
|
||||
}
|
||||
}
|
||||
connectAndRun();
|
||||
return () => {
|
||||
console.log("Component unmounting, killing sidecar...");
|
||||
console.log('Component unmounting, killing sidecar...');
|
||||
sidecarChild?.kill();
|
||||
};
|
||||
});
|
||||
|
||||
function sendToSidecar(message: object) {
|
||||
if (sidecarChild) {
|
||||
sidecarChild.write(JSON.stringify(message) + "\n");
|
||||
sidecarChild.write(JSON.stringify(message) + '\n');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -132,7 +129,7 @@
|
|||
getMutableNode: (id: number) => UINode | undefined
|
||||
) {
|
||||
switch (command.type) {
|
||||
case "REPLACE_CHILDREN": {
|
||||
case 'REPLACE_CHILDREN': {
|
||||
const { parentId, childrenIds } = command.payload;
|
||||
const parentNode = getMutableNode(parentId);
|
||||
if (parentNode) {
|
||||
|
@ -140,17 +137,17 @@
|
|||
}
|
||||
break;
|
||||
}
|
||||
case "log":
|
||||
console.log("SIDECAR:", command.payload);
|
||||
case 'log':
|
||||
console.log('SIDECAR:', command.payload);
|
||||
sidecarLogs = [...sidecarLogs, command.payload];
|
||||
break;
|
||||
case "CREATE_TEXT_INSTANCE":
|
||||
case "CREATE_INSTANCE": {
|
||||
case 'CREATE_TEXT_INSTANCE':
|
||||
case 'CREATE_INSTANCE': {
|
||||
const { id, type, props } = command.payload;
|
||||
tempTree.set(id, { id, type, props, children: [] });
|
||||
break;
|
||||
}
|
||||
case "UPDATE_PROPS": {
|
||||
case 'UPDATE_PROPS': {
|
||||
const { id, props } = command.payload;
|
||||
const node = getMutableNode(id);
|
||||
if (node) {
|
||||
|
@ -158,9 +155,9 @@
|
|||
}
|
||||
break;
|
||||
}
|
||||
case "APPEND_CHILD": {
|
||||
case 'APPEND_CHILD': {
|
||||
const { parentId, childId } = command.payload;
|
||||
if (parentId === "root") {
|
||||
if (parentId === 'root') {
|
||||
tempState.rootNodeId = childId;
|
||||
} else {
|
||||
const parentNode = getMutableNode(parentId);
|
||||
|
@ -172,7 +169,7 @@
|
|||
}
|
||||
break;
|
||||
}
|
||||
case "REMOVE_CHILD": {
|
||||
case 'REMOVE_CHILD': {
|
||||
const { parentId, childId } = command.payload;
|
||||
const parentNode = getMutableNode(parentId);
|
||||
if (parentNode) {
|
||||
|
@ -181,7 +178,7 @@
|
|||
}
|
||||
break;
|
||||
}
|
||||
case "INSERT_BEFORE": {
|
||||
case 'INSERT_BEFORE': {
|
||||
const { parentId, childId, beforeId } = command.payload;
|
||||
const parentNode = getMutableNode(parentId);
|
||||
if (parentNode) {
|
||||
|
@ -200,8 +197,7 @@
|
|||
}
|
||||
|
||||
function handleSidecarMessage(message: any) {
|
||||
const commands =
|
||||
message.type === "BATCH_UPDATE" ? message.payload : [message];
|
||||
const commands = message.type === 'BATCH_UPDATE' ? message.payload : [message];
|
||||
if (commands.length === 0) {
|
||||
updateCounter++;
|
||||
return;
|
||||
|
@ -216,7 +212,7 @@
|
|||
const clonedNode = {
|
||||
...originalNode,
|
||||
props: { ...originalNode.props },
|
||||
children: [...originalNode.children],
|
||||
children: [...originalNode.children]
|
||||
};
|
||||
tempTree.set(id, clonedNode);
|
||||
mutatedIds.add(id);
|
||||
|
@ -236,41 +232,34 @@
|
|||
}
|
||||
|
||||
function dispatchEvent(instanceId: number, handlerName: string, args: any[]) {
|
||||
console.log(
|
||||
`[EVENT] Dispatching '${handlerName}' to instance ${instanceId}`
|
||||
);
|
||||
console.log(`[EVENT] Dispatching '${handlerName}' to instance ${instanceId}`);
|
||||
sendToSidecar({
|
||||
action: "dispatch-event",
|
||||
payload: { instanceId, handlerName, args },
|
||||
action: 'dispatch-event',
|
||||
payload: { instanceId, handlerName, args }
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<main class="flex grow flex-col h-screen">
|
||||
<main class="flex h-screen grow flex-col">
|
||||
{#if rootNodeId}
|
||||
{@const rootNode = uiTree.get(rootNodeId)}
|
||||
{#if rootNode?.type === "List"}
|
||||
{#if rootNode?.type === 'List'}
|
||||
<div class="flex h-full flex-col">
|
||||
<input
|
||||
type="text"
|
||||
class="w-full border-b border-gray-300 px-4 py-3 text-lg focus:border-blue-500 focus:outline-none"
|
||||
placeholder="Search Emojis..."
|
||||
oninput={(e) =>
|
||||
dispatchEvent(rootNode.id, "onSearchTextChange", [
|
||||
e.currentTarget.value,
|
||||
])}
|
||||
oninput={(e) => dispatchEvent(rootNode.id, 'onSearchTextChange', [e.currentTarget.value])}
|
||||
/>
|
||||
|
||||
<div class="flex-grow">
|
||||
<VList data={flatList} getKey={(item) => item.id} class="h-full">
|
||||
{#snippet children(item)}
|
||||
{#if item.type === "header"}
|
||||
<h3
|
||||
class="px-4 pb-1 pt-2.5 text-xs font-semibold uppercase text-gray-500"
|
||||
>
|
||||
{#if item.type === 'header'}
|
||||
<h3 class="px-4 pt-2.5 pb-1 text-xs font-semibold text-gray-500 uppercase">
|
||||
{item.props.title}
|
||||
</h3>
|
||||
{:else if item.type === "item"}
|
||||
{:else if item.type === 'item'}
|
||||
<div class="flex items-center gap-3 px-4 py-2">
|
||||
<span class="text-lg">{item.props.icon}</span>
|
||||
<span>{item.props.title}</span>
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
// Tauri doesn't have a Node.js server to do proper SSR
|
||||
// so we will use adapter-static to prerender the app (SSG)
|
||||
// See: https://v2.tauri.app/start/frontend/sveltekit/ for more info
|
||||
import adapter from "@sveltejs/adapter-static";
|
||||
import { vitePreprocess } from "@sveltejs/vite-plugin-svelte";
|
||||
import adapter from '@sveltejs/adapter-static';
|
||||
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
|
||||
|
||||
/** @type {import('@sveltejs/kit').Config} */
|
||||
const config = {
|
||||
preprocess: vitePreprocess(),
|
||||
kit: {
|
||||
adapter: adapter(),
|
||||
},
|
||||
adapter: adapter()
|
||||
}
|
||||
};
|
||||
|
||||
export default config;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { defineConfig } from "vite";
|
||||
import tailwindcss from "@tailwindcss/vite";
|
||||
import { sveltekit } from "@sveltejs/kit/vite";
|
||||
import { nodePolyfills } from "vite-plugin-node-polyfills";
|
||||
import { defineConfig } from 'vite';
|
||||
import tailwindcss from '@tailwindcss/vite';
|
||||
import { sveltekit } from '@sveltejs/kit/vite';
|
||||
import { nodePolyfills } from 'vite-plugin-node-polyfills';
|
||||
|
||||
const host = process.env.TAURI_DEV_HOST;
|
||||
|
||||
|
@ -20,14 +20,14 @@ export default defineConfig(async () => ({
|
|||
host: host || false,
|
||||
hmr: host
|
||||
? {
|
||||
protocol: "ws",
|
||||
protocol: 'ws',
|
||||
host,
|
||||
port: 1421,
|
||||
port: 1421
|
||||
}
|
||||
: undefined,
|
||||
watch: {
|
||||
// 3. tell vite to ignore watching `src-tauri`
|
||||
ignored: ["**/src-tauri/**"],
|
||||
},
|
||||
},
|
||||
ignored: ['**/src-tauri/**']
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue