@vicinae/api 0.9.1 → 0.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/dist/api/ai.js +2 -41
  2. package/dist/api/alert.js +8 -21
  3. package/dist/api/bus.d.ts +10 -7
  4. package/dist/api/bus.js +0 -33
  5. package/dist/api/cache.d.ts +64 -73
  6. package/dist/api/cache.js +163 -14
  7. package/dist/api/clipboard.d.ts +1 -1
  8. package/dist/api/clipboard.js +3 -9
  9. package/dist/api/controls.d.ts +3 -0
  10. package/dist/api/controls.js +5 -1
  11. package/dist/api/environment.d.ts +5 -0
  12. package/dist/api/file-search.d.ts +49 -0
  13. package/dist/api/file-search.js +49 -0
  14. package/dist/api/index.d.ts +2 -1
  15. package/dist/api/index.js +2 -1
  16. package/dist/api/lib/result.d.ts +3 -1
  17. package/dist/api/lib/result.js +2 -2
  18. package/dist/api/preference.js +2 -3
  19. package/dist/api/proto/application.d.ts +14 -0
  20. package/dist/api/proto/application.js +207 -37
  21. package/dist/api/proto/clipboard.js +38 -71
  22. package/dist/api/proto/common.js +2 -6
  23. package/dist/api/proto/daemon.js +5 -15
  24. package/dist/api/proto/extension.d.ts +16 -10
  25. package/dist/api/proto/extension.js +118 -91
  26. package/dist/api/proto/file-search.d.ts +42 -0
  27. package/dist/api/proto/file-search.js +290 -0
  28. package/dist/api/proto/google/protobuf/struct.js +9 -26
  29. package/dist/api/proto/ipc.js +53 -100
  30. package/dist/api/proto/manager.d.ts +2 -0
  31. package/dist/api/proto/manager.js +54 -49
  32. package/dist/api/proto/oauth.js +15 -33
  33. package/dist/api/proto/storage.js +29 -67
  34. package/dist/api/proto/ui.d.ts +11 -2
  35. package/dist/api/proto/ui.js +267 -254
  36. package/dist/api/proto/wlr-clipboard.js +4 -12
  37. package/dist/api/proto/wm.d.ts +111 -0
  38. package/dist/api/proto/wm.js +1266 -0
  39. package/dist/api/raycast/index.d.ts +24 -0
  40. package/dist/api/raycast/index.js +40 -0
  41. package/dist/api/raycast/system.d.ts +20 -0
  42. package/dist/api/raycast/system.js +73 -0
  43. package/dist/api/raycast/window-management.d.ts +42 -0
  44. package/dist/api/raycast/window-management.js +82 -0
  45. package/dist/api/toast.js +47 -5
  46. package/dist/api/utils.d.ts +5 -11
  47. package/dist/api/utils.js +20 -31
  48. package/dist/api/window-management.d.ts +39 -0
  49. package/dist/api/window-management.js +55 -0
  50. package/package.json +1 -1
package/dist/api/ai.js CHANGED
@@ -1,9 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.AI = void 0;
4
- const stream_1 = require("stream");
5
- const crypto_1 = require("crypto");
6
- const bus_1 = require("./bus");
7
4
  var AI;
8
5
  (function (AI) {
9
6
  /**
@@ -36,42 +33,7 @@ var AI;
36
33
  * ```
37
34
  */
38
35
  function ask(prompt, options) {
39
- const handlerId = (0, crypto_1.randomUUID)();
40
- const emitter = new stream_1.EventEmitter();
41
- const promise = new Promise((resolve, reject) => {
42
- let answer = "";
43
- bus_1.bus
44
- .request("ai.create-completion", {
45
- prompt,
46
- options,
47
- callback: handlerId,
48
- })
49
- .then(({ data }) => {
50
- if (!data.started) {
51
- reject(new Error("Could not create completion"));
52
- }
53
- const { unsubscribe } = bus_1.bus.subscribe(handlerId, (...args) => {
54
- const data = args[0];
55
- answer += data.token;
56
- emitter.emit("data", data.token);
57
- if (data.done) {
58
- unsubscribe();
59
- resolve(answer);
60
- }
61
- });
62
- if (options?.signal) {
63
- options.signal.addEventListener("abort", () => {
64
- bus_1.bus.request("ai.abort-completion");
65
- unsubscribe();
66
- resolve(answer);
67
- });
68
- }
69
- })
70
- .catch((err) => reject(err));
71
- });
72
- return Object.assign(promise, {
73
- on: emitter.on.bind(emitter),
74
- });
36
+ throw new Error('not implemented');
75
37
  }
76
38
  AI.ask = ask;
77
39
  /**
@@ -115,7 +77,6 @@ var AI;
115
77
  Model["OpenAI_GPT3.5-turbo"] = "openai-gpt-3.5-turbo";
116
78
  })(Model = AI.Model || (AI.Model = {}));
117
79
  AI.getModels = async () => {
118
- const res = await bus_1.bus.request("ai.get-models");
119
- return res.data.models;
80
+ throw new Error('not implemented');
120
81
  };
121
82
  })(AI || (exports.AI = AI = {}));
package/dist/api/alert.js CHANGED
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.confirmAlert = exports.Alert = void 0;
4
- const node_crypto_1 = require("node:crypto");
5
4
  const bus_1 = require("./bus");
6
5
  const ui_1 = require("./proto/ui");
7
6
  var Alert;
@@ -20,22 +19,7 @@ const styleMap = {
20
19
  };
21
20
  const confirmAlert = async (options) => {
22
21
  return new Promise(async (resolve) => {
23
- const handle = (0, node_crypto_1.randomUUID)();
24
- let confirmCallback = () => { };
25
- let cancelCallback = () => { };
26
- const { unsubscribe } = bus_1.bus.subscribe(handle, (...args) => {
27
- callback(!!args[0]);
28
- });
29
- const callback = (value) => {
30
- if (value)
31
- confirmCallback();
32
- else
33
- cancelCallback();
34
- unsubscribe();
35
- resolve(value);
36
- };
37
22
  const req = ui_1.ConfirmAlertRequest.create({
38
- handle,
39
23
  title: options.title,
40
24
  description: options.message ?? "Are you sure?",
41
25
  rememberUserChoice: false,
@@ -48,13 +32,16 @@ const confirmAlert = async (options) => {
48
32
  style: styleMap[options.dismissAction?.style ?? Alert.ActionStyle.Cancel],
49
33
  },
50
34
  });
51
- if (options.primaryAction?.onAction) {
52
- confirmCallback = options.primaryAction.onAction;
35
+ const res = await bus_1.bus.turboRequest("ui.confirmAlert", req);
36
+ if (!res.ok)
37
+ return false;
38
+ if (res.value.confirmed) {
39
+ options.primaryAction?.onAction?.();
53
40
  }
54
- if (options.dismissAction?.onAction) {
55
- cancelCallback = options.dismissAction.onAction;
41
+ else {
42
+ options.dismissAction?.onAction?.();
56
43
  }
57
- await bus_1.bus.turboRequest("ui.confirmAlert", req);
44
+ resolve(res.value.confirmed);
58
45
  });
59
46
  };
60
47
  exports.confirmAlert = confirmAlert;
package/dist/api/bus.d.ts CHANGED
@@ -37,6 +37,7 @@ type Responses = {
37
37
  type EndpointMapping = {
38
38
  "app.list": "app.list";
39
39
  "app.open": "app.open";
40
+ "app.getDefault": "app.getDefault";
40
41
  "ui.render": "ui.render";
41
42
  "ui.showToast": "ui.showToast";
42
43
  "ui.hideToast": "ui.hideToast";
@@ -48,6 +49,14 @@ type EndpointMapping = {
48
49
  "ui.setSearchText": "ui.setSearchText";
49
50
  "ui.confirmAlert": "ui.confirmAlert";
50
51
  "ui.getSelectedText": "ui.getSelectedText";
52
+ "wm.ping": "wm.ping";
53
+ "wm.getActiveWindow": "wm.getActiveWindow";
54
+ "wm.getActiveWorkspace": "wm.getActiveWorkspace";
55
+ "wm.getWindows": "wm.getWindows";
56
+ "wm.getWorkspaces": "wm.getWorkspaces";
57
+ "wm.setWindowBounds": "wm.setWindowBounds";
58
+ "fileSearch.search": "fileSearch.search";
59
+ "ui.popToRoot": "ui.popToRoot";
51
60
  "storage.get": "storage.get";
52
61
  "storage.set": "storage.set";
53
62
  "storage.remove": "storage.remove";
@@ -88,13 +97,7 @@ declare class Bus {
88
97
  };
89
98
  replaceEventHandler(id: string, handler: EventListenerInfo['callback']): void;
90
99
  removeEventHandler(id: string): void;
91
- request2(data: extension.RequestData, options?: {
92
- timeout?: number;
93
- }): Promise<Result<extension.ResponseData, Error>>;
94
- request<T = Record<string, any>>(action: string, data?: Record<string, any>, options?: {
95
- timeout?: number;
96
- rejectOnError?: boolean;
97
- }): Promise<Message<T>>;
100
+ private request2;
98
101
  }
99
102
  /**
100
103
  * IPC bus to communicate with the extension manager.
package/dist/api/bus.js CHANGED
@@ -181,39 +181,6 @@ class Bus {
181
181
  }
182
182
  });
183
183
  }
184
- request(action, data = {}, options = {}) {
185
- const id = (0, crypto_1.randomUUID)();
186
- const { rejectOnError = true } = options;
187
- return new Promise((resolve, reject) => {
188
- let timeout;
189
- if (options.timeout) {
190
- timeout = setTimeout(() => reject(new Error(`request timed out`)), options.timeout);
191
- }
192
- const resolver = (message) => {
193
- clearTimeout(timeout);
194
- if (message.error && rejectOnError) {
195
- return reject(message.error.message ?? "Unknown error");
196
- }
197
- resolve(message);
198
- };
199
- try {
200
- this.requestMap.set(id, { resolve: resolver });
201
- const message = {
202
- envelope: {
203
- type: "request",
204
- action,
205
- id,
206
- },
207
- data,
208
- error: null,
209
- };
210
- this.port.postMessage(message);
211
- }
212
- catch (error) {
213
- reject(error);
214
- }
215
- });
216
- }
217
184
  }
218
185
  /**
219
186
  * IPC bus to communicate with the extension manager.
@@ -1,56 +1,46 @@
1
- interface AbstractCache {
2
- /**
3
- * @returns the full path to the directory where the data is stored on disk.
4
- */
5
- get storageDirectory(): string;
6
- /**
7
- * @returns the data for the given key. If there is no data for the key, `undefined` is returned.
8
- * @remarks If you want to just check for the existence of a key, use {@link has}.
9
- */
10
- get(key: string): string | undefined;
11
- /**
12
- * @returns `true` if data for the key exists, `false` otherwise.
13
- * @remarks You can use this method to check for entries without affecting the LRU access.
14
- */
15
- has(key: string): boolean;
16
- /**
17
- * @returns `true` if the cache is empty, `false` otherwise.
18
- */
19
- get isEmpty(): boolean;
20
- /**
21
- * Sets the data for the given key.
22
- * If the data exceeds the configured `capacity`, the least recently used entries are removed.
23
- * This also notifies registered subscribers (see {@link subscribe}).
24
- */
25
- set(key: string, data: string): void;
26
- /**
27
- * Removes the data for the given key.
28
- * This also notifies registered subscribers (see {@link subscribe}).
29
- * @returns `true` if data for the key was removed, `false` otherwise.
30
- */
31
- remove(key: string): boolean;
32
- /**
33
- * Clears all stored data.
34
- * This also notifies registered subscribers (see {@link subscribe}) unless the `notifySubscribers` option is set to `false`.
35
- */
36
- clear(options?: {
37
- notifySubscribers: boolean;
38
- }): void;
1
+ export declare namespace Cache {
39
2
  /**
40
- * Registers a new subscriber that gets notified when cache data is set or removed.
41
- * @returns a function that can be called to remove the subscriber.
3
+ * The options for creating a new {@link Cache}.
42
4
  */
43
- subscribe(subscriber: Cache.Subscriber): Cache.Subscription;
5
+ interface Options {
6
+ /**
7
+ * If set, the Cache will be namespaced via a subdirectory.
8
+ * This can be useful to separate the caches for individual commands of an extension.
9
+ * By default, the cache is shared between the commands of an extension.
10
+ */
11
+ namespace?: string;
12
+ /**
13
+ * The capacity in bytes. If the stored data exceeds the capacity, the least recently used data is removed.
14
+ * The default capacity is 10 MB.
15
+ */
16
+ capacity?: number;
17
+ }
18
+ type Subscriber = (key: string | undefined, data: string | undefined) => void;
19
+ type Subscription = () => void;
44
20
  }
45
- export declare class Cache implements AbstractCache {
21
+ /**
22
+ * Caching abstraction that stores data on disk and supports LRU (least recently used) access.
23
+ * Values can only be stored as plain text strings, so it is up to you to serialize your data in an appropriate way.
24
+ * For instance, you could store json using `JSON.stringify` and `JSON.parse` it back.
25
+ * If you need to store binary data, you could encode it in base64.
26
+ *
27
+ * Unlike the local storage API, this API exclusively uses the extension's support directory to store its data.
28
+ * No calls to internal Vicinae APIs are required, hence why all methods in this class are synchronous.
29
+ * Another major difference is that cache data is not encrypted, so it's not suitable to store secrets.
30
+ * (local storage currently isn't either, but that will change in the future)
31
+ */
32
+ export declare class Cache {
46
33
  constructor(options?: Cache.Options);
47
34
  /**
48
35
  * @returns the full path to the directory where the data is stored on disk.
36
+ * @remarks This is provided for informative purpose only. You should not attempt to mutate anything
37
+ * in this directory by yourself. Also note that the way cache data is serialized on disk can (will) change
38
+ * across versions.
49
39
  */
50
40
  get storageDirectory(): string;
51
41
  /**
52
- * @returns the data for the given key. If there is no data for the key, `undefined` is returned.
53
- * @remarks If you want to just check for the existence of a key, use {@link has}.
42
+ * @returns the data for the given key, or `undefined` if there is no data.
43
+ * @remarks To solely check for existence of a key, use {@link has}.
54
44
  */
55
45
  get(key: string): string | undefined;
56
46
  /**
@@ -59,13 +49,14 @@ export declare class Cache implements AbstractCache {
59
49
  */
60
50
  has(key: string): boolean;
61
51
  /**
62
- * @returns `true` if the cache is empty, `false` otherwise.
52
+ * @returns whether the cache is empty.
63
53
  */
64
54
  get isEmpty(): boolean;
65
55
  /**
66
56
  * Sets the data for the given key.
67
57
  * If the data exceeds the configured `capacity`, the least recently used entries are removed.
68
58
  * This also notifies registered subscribers (see {@link subscribe}).
59
+ * @remarks An individual cache entry cannot be bigger than the configured capacity. If this happens, an error will be thrown.
69
60
  */
70
61
  set(key: string, data: string): void;
71
62
  /**
@@ -86,32 +77,32 @@ export declare class Cache implements AbstractCache {
86
77
  * @returns a function that can be called to remove the subscriber.
87
78
  */
88
79
  subscribe(subscriber: Cache.Subscriber): Cache.Subscription;
89
- private maintainCapacity;
90
- private notifySubscribers;
91
- }
92
- export declare namespace Cache {
93
- /**
94
- * The options for creating a new {@link Cache}.
95
- */
96
- interface Options {
97
- /**
98
- * If set, the Cache will be namespaced via a subdirectory.
99
- * This can be useful to separate the caches for individual commands of an extension.
100
- * By default, the cache is shared between the commands of an extension.
101
- */
102
- namespace?: string;
103
- /**
104
- * The parent directory for the cache data.
105
- * @deprecated this parameter will be removed in the future – use the default directory.
106
- */
107
- directory?: string;
108
- /**
109
- * The capacity in bytes. If the stored data exceeds the capacity, the least recently used data is removed.
110
- * The default capacity is 10 MB.
111
- */
112
- capacity?: number;
113
- }
114
- type Subscriber = (key: string | undefined, data: string | undefined) => void;
115
- type Subscription = () => void;
80
+ private keyDataPath;
81
+ private readKeyData;
82
+ private writeKeyData;
83
+ private keyHash;
84
+ private get dataDir();
85
+ private dataPath;
86
+ private get indexPath();
87
+ private updateLRU;
88
+ private popLRU;
89
+ private removeImpl;
90
+ private initIndex;
91
+ private loadIndex;
92
+ private removeCacheDirectory;
93
+ private syncIndex;
94
+ private emptyIndex;
95
+ /**
96
+ * We store this inside the cache index file in order to know
97
+ * when a breaking change occurs.
98
+ * If we want to change the way the data is stored we just change this,
99
+ * which will force a full cache clear and use the new format.
100
+ */
101
+ private revision;
102
+ private capacity;
103
+ private subscribers;
104
+ private storageDir;
105
+ private index;
106
+ private static DEFAULT_CACHE_SIZE;
107
+ private static CACHE_DIR_NAME;
116
108
  }
117
- export {};
package/dist/api/cache.js CHANGED
@@ -1,61 +1,210 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.Cache = void 0;
7
+ const node_path_1 = __importDefault(require("node:path"));
8
+ const node_fs_1 = require("node:fs");
9
+ const node_crypto_1 = require("node:crypto");
10
+ const environment_1 = require("./environment");
11
+ /**
12
+ * Caching abstraction that stores data on disk and supports LRU (least recently used) access.
13
+ * Values can only be stored as plain text strings, so it is up to you to serialize your data in an appropriate way.
14
+ * For instance, you could store json using `JSON.stringify` and `JSON.parse` it back.
15
+ * If you need to store binary data, you could encode it in base64.
16
+ *
17
+ * Unlike the local storage API, this API exclusively uses the extension's support directory to store its data.
18
+ * No calls to internal Vicinae APIs are required, hence why all methods in this class are synchronous.
19
+ * Another major difference is that cache data is not encrypted, so it's not suitable to store secrets.
20
+ * (local storage currently isn't either, but that will change in the future)
21
+ */
4
22
  class Cache {
5
- constructor(options) { }
23
+ constructor(options) {
24
+ this.storageDir = node_path_1.default.join(environment_1.environment.supportPath, Cache.CACHE_DIR_NAME);
25
+ this.capacity = options?.capacity ?? Cache.DEFAULT_CACHE_SIZE;
26
+ if (options?.namespace) {
27
+ this.storageDir = node_path_1.default.join(this.storageDir, options.namespace);
28
+ }
29
+ (0, node_fs_1.mkdirSync)(this.dataDir, { recursive: true });
30
+ this.index = this.loadIndex() ?? this.emptyIndex();
31
+ if (this.index.revision !== this.revision) {
32
+ this.clear();
33
+ }
34
+ }
6
35
  /**
7
36
  * @returns the full path to the directory where the data is stored on disk.
37
+ * @remarks This is provided for informative purpose only. You should not attempt to mutate anything
38
+ * in this directory by yourself. Also note that the way cache data is serialized on disk can (will) change
39
+ * across versions.
8
40
  */
9
41
  get storageDirectory() {
10
- return "";
42
+ return this.storageDir;
11
43
  }
12
44
  /**
13
- * @returns the data for the given key. If there is no data for the key, `undefined` is returned.
14
- * @remarks If you want to just check for the existence of a key, use {@link has}.
45
+ * @returns the data for the given key, or `undefined` if there is no data.
46
+ * @remarks To solely check for existence of a key, use {@link has}.
15
47
  */
16
48
  get(key) {
17
- return undefined;
49
+ const info = this.index.keys[key];
50
+ if (!info)
51
+ return undefined;
52
+ this.updateLRU(key);
53
+ this.syncIndex();
54
+ return this.readKeyData(key);
18
55
  }
19
56
  /**
20
57
  * @returns `true` if data for the key exists, `false` otherwise.
21
58
  * @remarks You can use this method to check for entries without affecting the LRU access.
22
59
  */
23
60
  has(key) {
24
- return false;
61
+ return typeof this.index.keys[key] !== 'undefined';
25
62
  }
26
63
  /**
27
- * @returns `true` if the cache is empty, `false` otherwise.
64
+ * @returns whether the cache is empty.
28
65
  */
29
66
  get isEmpty() {
30
- return true;
67
+ return Object.keys(this.index.keys).length === 0;
31
68
  }
32
69
  /**
33
70
  * Sets the data for the given key.
34
71
  * If the data exceeds the configured `capacity`, the least recently used entries are removed.
35
72
  * This also notifies registered subscribers (see {@link subscribe}).
73
+ * @remarks An individual cache entry cannot be bigger than the configured capacity. If this happens, an error will be thrown.
36
74
  */
37
- set(key, data) { }
75
+ set(key, data) {
76
+ if (data.length > this.capacity) {
77
+ throw new Error(`A single cache entry cannot be bigger than the total capacity of the cache. The data for key ${key} is ${data.length} bytes long while the capacity is set to ${this.capacity}. You should either reduce the amount of data stored or increase the cache's capacity.`);
78
+ }
79
+ const info = this.index.keys[key];
80
+ let newTotalSize = this.index.size + data.length - (info?.size ?? 0);
81
+ if (newTotalSize > this.capacity) {
82
+ this.popLRU();
83
+ return this.set(key, data); // FIXME: get rid of recursion
84
+ }
85
+ this.index.size = newTotalSize;
86
+ this.index.keys[key] = { size: data.length };
87
+ this.updateLRU(key);
88
+ for (const sub of this.subscribers) {
89
+ sub(key, data);
90
+ }
91
+ this.writeKeyData(key, data);
92
+ this.syncIndex();
93
+ }
38
94
  /**
39
95
  * Removes the data for the given key.
40
96
  * This also notifies registered subscribers (see {@link subscribe}).
41
97
  * @returns `true` if data for the key was removed, `false` otherwise.
42
98
  */
43
99
  remove(key) {
44
- return false;
100
+ const removed = this.removeImpl(key);
101
+ this.syncIndex();
102
+ return removed;
45
103
  }
46
104
  /**
47
105
  * Clears all stored data.
48
106
  * This also notifies registered subscribers (see {@link subscribe}) unless the `notifySubscribers` option is set to `false`.
49
107
  */
50
- clear(options) { }
108
+ clear(options) {
109
+ const notify = options?.notifySubscribers ?? true;
110
+ this.removeCacheDirectory();
111
+ this.initIndex();
112
+ if (!notify)
113
+ return;
114
+ for (const key of Object.keys(this.index.keys)) {
115
+ for (const subscriber of this.subscribers) {
116
+ subscriber(key, undefined);
117
+ }
118
+ }
119
+ }
51
120
  /**
52
121
  * Registers a new subscriber that gets notified when cache data is set or removed.
53
122
  * @returns a function that can be called to remove the subscriber.
54
123
  */
55
124
  subscribe(subscriber) {
56
- return () => { };
125
+ this.subscribers.push(subscriber);
126
+ return () => {
127
+ this.subscribers.splice(this.subscribers.indexOf(subscriber), 1);
128
+ };
129
+ }
130
+ keyDataPath(key) {
131
+ return this.dataPath(this.keyHash(key));
132
+ }
133
+ readKeyData(key) {
134
+ return (0, node_fs_1.readFileSync)(this.keyDataPath(key), 'utf8');
135
+ }
136
+ writeKeyData(key, data) {
137
+ (0, node_fs_1.writeFileSync)(this.keyDataPath(key), data);
138
+ }
139
+ keyHash(key) {
140
+ return (0, node_crypto_1.hash)('md5', key);
141
+ }
142
+ get dataDir() {
143
+ return node_path_1.default.join(this.storageDir, 'data');
144
+ }
145
+ dataPath(id) {
146
+ return node_path_1.default.join(this.dataDir, id);
147
+ }
148
+ get indexPath() {
149
+ return node_path_1.default.join(this.storageDir, 'index.json');
57
150
  }
58
- maintainCapacity;
59
- notifySubscribers;
151
+ updateLRU(key) {
152
+ const idx = this.index.lru.findIndex((entry) => key == entry.key);
153
+ if (idx !== -1)
154
+ this.index.lru.splice(idx, 1);
155
+ this.index.lru.unshift({ key, lastUsedAt: Date.now() });
156
+ }
157
+ popLRU() {
158
+ if (this.index.lru.length === 0)
159
+ return;
160
+ this.removeImpl(this.index.lru.pop().key);
161
+ }
162
+ removeImpl(key) {
163
+ const info = this.index.keys[key];
164
+ if (!info)
165
+ return false;
166
+ (0, node_fs_1.rmSync)(this.keyDataPath(key), { force: true });
167
+ this.index.size -= info.size;
168
+ delete this.index.keys[key];
169
+ for (const sub of this.subscribers) {
170
+ sub(key, undefined);
171
+ }
172
+ return true;
173
+ }
174
+ initIndex() {
175
+ const index = { revision: this.revision, keys: {}, size: 0, lru: [] };
176
+ (0, node_fs_1.mkdirSync)(this.dataDir, { recursive: true });
177
+ const indexPath = node_path_1.default.join(this.storageDir, "index.json");
178
+ (0, node_fs_1.writeFileSync)(indexPath, JSON.stringify(index, null, 2));
179
+ return index;
180
+ }
181
+ loadIndex() {
182
+ const indexPath = node_path_1.default.join(this.storageDir, "index.json");
183
+ if (!(0, node_fs_1.existsSync)(indexPath))
184
+ return null;
185
+ return JSON.parse((0, node_fs_1.readFileSync)(indexPath, 'utf8'));
186
+ }
187
+ removeCacheDirectory() {
188
+ (0, node_fs_1.rmSync)(this.dataDir, { recursive: true, force: true });
189
+ }
190
+ syncIndex() {
191
+ (0, node_fs_1.writeFileSync)(this.indexPath, JSON.stringify(this.index, null, 2));
192
+ }
193
+ emptyIndex() {
194
+ return { revision: this.revision, keys: {}, lru: [], size: 0 };
195
+ }
196
+ /**
197
+ * We store this inside the cache index file in order to know
198
+ * when a breaking change occurs.
199
+ * If we want to change the way the data is stored we just change this,
200
+ * which will force a full cache clear and use the new format.
201
+ */
202
+ revision = '1';
203
+ capacity;
204
+ subscribers = [];
205
+ storageDir;
206
+ index;
207
+ static DEFAULT_CACHE_SIZE = 1e7;
208
+ static CACHE_DIR_NAME = ".cache";
60
209
  }
61
210
  exports.Cache = Cache;
@@ -30,5 +30,5 @@ export declare const Clipboard: {
30
30
  readText(options?: {
31
31
  offset?: number;
32
32
  }): Promise<string | undefined>;
33
- clear(text: string): Promise<void>;
33
+ clear(text: string): Promise<never>;
34
34
  };
@@ -34,18 +34,12 @@ exports.Clipboard = {
34
34
  });
35
35
  },
36
36
  async read(options) {
37
- const res = await bus_1.bus.request("clipboard.read", {
38
- options,
39
- });
40
- return res.data.content;
37
+ throw new Error('Clipboard.read not implemented');
41
38
  },
42
39
  async readText(options) {
43
- const res = await bus_1.bus.request("clipboard.read-text", {
44
- options,
45
- });
46
- return res.data.content;
40
+ throw new Error('Clipboard.readText not implemented');
47
41
  },
48
42
  async clear(text) {
49
- // TODO: implement
43
+ throw new Error('Clibpoard.clear not implemented');
50
44
  },
51
45
  };
@@ -1,3 +1,6 @@
1
1
  export declare const closeMainWindow: () => Promise<void>;
2
2
  export declare const clearSearchBar: () => Promise<void>;
3
3
  export declare const getSelectedText: () => Promise<string>;
4
+ export declare const popToRoot: (options?: {
5
+ clearSearchBar?: boolean;
6
+ }) => Promise<void>;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getSelectedText = exports.clearSearchBar = exports.closeMainWindow = void 0;
3
+ exports.popToRoot = exports.getSelectedText = exports.clearSearchBar = exports.closeMainWindow = void 0;
4
4
  const bus_1 = require("./bus");
5
5
  const closeMainWindow = async () => {
6
6
  await bus_1.bus.turboRequest("ui.closeMainWindow", {});
@@ -18,3 +18,7 @@ const getSelectedText = async () => {
18
18
  return response.value.text;
19
19
  };
20
20
  exports.getSelectedText = getSelectedText;
21
+ const popToRoot = async (options) => {
22
+ await bus_1.bus.turboRequest('ui.popToRoot', { clearSearchBar: options?.clearSearchBar ?? false });
23
+ };
24
+ exports.popToRoot = popToRoot;
@@ -121,5 +121,10 @@ export interface Environment {
121
121
  tag: string;
122
122
  commit: string;
123
123
  };
124
+ /**
125
+ * Whether we run an actual Raycast extension in compatibility mode.
126
+ * This is used internally to provide Raycast-compatible interfaces.
127
+ */
128
+ isRaycast: boolean;
124
129
  }
125
130
  export declare const environment: Environment;