| ; | |
| var tslib_es6 = require('./external/tslib/tslib.es6.cjs'); | |
| // Copyright 2019-2024 Tauri Programme within The Commons Conservancy | |
| // SPDX-License-Identifier: Apache-2.0 | |
| // SPDX-License-Identifier: MIT | |
| var _Channel_onmessage, _Channel_nextMessageIndex, _Channel_pendingMessages, _Channel_messageEndIndex, _Resource_rid; | |
| /** | |
| * Invoke your custom commands. | |
| * | |
| * This package is also accessible with `window.__TAURI__.core` when [`app.withGlobalTauri`](https://v2.tauri.app/reference/config/#withglobaltauri) in `tauri.conf.json` is set to `true`. | |
| * @module | |
| */ | |
| /** | |
| * A key to be used to implement a special function | |
| * on your types that define how your type should be serialized | |
| * when passing across the IPC. | |
| * @example | |
| * Given a type in Rust that looks like this | |
| * ```rs | |
| * #[derive(serde::Serialize, serde::Deserialize) | |
| * enum UserId { | |
| * String(String), | |
| * Number(u32), | |
| * } | |
| * ``` | |
| * `UserId::String("id")` would be serialized into `{ String: "id" }` | |
| * and so we need to pass the same structure back to Rust | |
| * ```ts | |
| * import { SERIALIZE_TO_IPC_FN } from "@tauri-apps/api/core" | |
| * | |
| * class UserIdString { | |
| * id | |
| * constructor(id) { | |
| * this.id = id | |
| * } | |
| * | |
| * [SERIALIZE_TO_IPC_FN]() { | |
| * return { String: this.id } | |
| * } | |
| * } | |
| * | |
| * class UserIdNumber { | |
| * id | |
| * constructor(id) { | |
| * this.id = id | |
| * } | |
| * | |
| * [SERIALIZE_TO_IPC_FN]() { | |
| * return { Number: this.id } | |
| * } | |
| * } | |
| * | |
| * type UserId = UserIdString | UserIdNumber | |
| * ``` | |
| * | |
| */ | |
| // if this value changes, make sure to update it in: | |
| // 1. ipc.js | |
| // 2. process-ipc-message-fn.js | |
| const SERIALIZE_TO_IPC_FN = '__TAURI_TO_IPC_KEY__'; | |
| /** | |
| * Stores the callback in a known location, and returns an identifier that can be passed to the backend. | |
| * The backend uses the identifier to `eval()` the callback. | |
| * | |
| * @return An unique identifier associated with the callback function. | |
| * | |
| * @since 1.0.0 | |
| */ | |
| function transformCallback( | |
| // TODO: Make this not optional in v3 | |
| callback, once = false) { | |
| return window.__TAURI_INTERNALS__.transformCallback(callback, once); | |
| } | |
| class Channel { | |
| constructor(onmessage) { | |
| _Channel_onmessage.set(this, void 0); | |
| // the index is used as a mechanism to preserve message order | |
| _Channel_nextMessageIndex.set(this, 0); | |
| _Channel_pendingMessages.set(this, []); | |
| _Channel_messageEndIndex.set(this, void 0); | |
| tslib_es6.__classPrivateFieldSet(this, _Channel_onmessage, onmessage || (() => { }), "f"); | |
| this.id = transformCallback((rawMessage) => { | |
| const index = rawMessage.index; | |
| if ('end' in rawMessage) { | |
| if (index == tslib_es6.__classPrivateFieldGet(this, _Channel_nextMessageIndex, "f")) { | |
| this.cleanupCallback(); | |
| } | |
| else { | |
| tslib_es6.__classPrivateFieldSet(this, _Channel_messageEndIndex, index, "f"); | |
| } | |
| return; | |
| } | |
| const message = rawMessage.message; | |
| // Process the message if we're at the right order | |
| if (index == tslib_es6.__classPrivateFieldGet(this, _Channel_nextMessageIndex, "f")) { | |
| tslib_es6.__classPrivateFieldGet(this, _Channel_onmessage, "f").call(this, message); | |
| tslib_es6.__classPrivateFieldSet(this, _Channel_nextMessageIndex, tslib_es6.__classPrivateFieldGet(this, _Channel_nextMessageIndex, "f") + 1, "f"); | |
| // process pending messages | |
| while (tslib_es6.__classPrivateFieldGet(this, _Channel_nextMessageIndex, "f") in tslib_es6.__classPrivateFieldGet(this, _Channel_pendingMessages, "f")) { | |
| const message = tslib_es6.__classPrivateFieldGet(this, _Channel_pendingMessages, "f")[tslib_es6.__classPrivateFieldGet(this, _Channel_nextMessageIndex, "f")]; | |
| tslib_es6.__classPrivateFieldGet(this, _Channel_onmessage, "f").call(this, message); | |
| // eslint-disable-next-line @typescript-eslint/no-array-delete | |
| delete tslib_es6.__classPrivateFieldGet(this, _Channel_pendingMessages, "f")[tslib_es6.__classPrivateFieldGet(this, _Channel_nextMessageIndex, "f")]; | |
| tslib_es6.__classPrivateFieldSet(this, _Channel_nextMessageIndex, tslib_es6.__classPrivateFieldGet(this, _Channel_nextMessageIndex, "f") + 1, "f"); | |
| } | |
| if (tslib_es6.__classPrivateFieldGet(this, _Channel_nextMessageIndex, "f") === tslib_es6.__classPrivateFieldGet(this, _Channel_messageEndIndex, "f")) { | |
| this.cleanupCallback(); | |
| } | |
| } | |
| // Queue the message if we're not | |
| else { | |
| // eslint-disable-next-line security/detect-object-injection | |
| tslib_es6.__classPrivateFieldGet(this, _Channel_pendingMessages, "f")[index] = message; | |
| } | |
| }); | |
| } | |
| cleanupCallback() { | |
| window.__TAURI_INTERNALS__.unregisterCallback(this.id); | |
| } | |
| set onmessage(handler) { | |
| tslib_es6.__classPrivateFieldSet(this, _Channel_onmessage, handler, "f"); | |
| } | |
| get onmessage() { | |
| return tslib_es6.__classPrivateFieldGet(this, _Channel_onmessage, "f"); | |
| } | |
| [(_Channel_onmessage = new WeakMap(), _Channel_nextMessageIndex = new WeakMap(), _Channel_pendingMessages = new WeakMap(), _Channel_messageEndIndex = new WeakMap(), SERIALIZE_TO_IPC_FN)]() { | |
| return `__CHANNEL__:${this.id}`; | |
| } | |
| toJSON() { | |
| // eslint-disable-next-line security/detect-object-injection | |
| return this[SERIALIZE_TO_IPC_FN](); | |
| } | |
| } | |
| class PluginListener { | |
| constructor(plugin, event, channelId) { | |
| this.plugin = plugin; | |
| this.event = event; | |
| this.channelId = channelId; | |
| } | |
| async unregister() { | |
| return invoke(`plugin:${this.plugin}|remove_listener`, { | |
| event: this.event, | |
| channelId: this.channelId | |
| }); | |
| } | |
| } | |
| /** | |
| * Adds a listener to a plugin event. | |
| * | |
| * @returns The listener object to stop listening to the events. | |
| * | |
| * @since 2.0.0 | |
| */ | |
| async function addPluginListener(plugin, event, cb) { | |
| const handler = new Channel(cb); | |
| try { | |
| await invoke(`plugin:${plugin}|register_listener`, { | |
| event, | |
| handler | |
| }); | |
| return new PluginListener(plugin, event, handler.id); | |
| } | |
| catch { | |
| // TODO(v3): remove this fallback | |
| // note: we must try with camelCase here for backwards compatibility | |
| await invoke(`plugin:${plugin}|registerListener`, { event, handler }); | |
| return new PluginListener(plugin, event, handler.id); | |
| } | |
| } | |
| /** | |
| * Get permission state for a plugin. | |
| * | |
| * This should be used by plugin authors to wrap their actual implementation. | |
| */ | |
| async function checkPermissions(plugin) { | |
| return invoke(`plugin:${plugin}|check_permissions`); | |
| } | |
| /** | |
| * Request permissions. | |
| * | |
| * This should be used by plugin authors to wrap their actual implementation. | |
| */ | |
| async function requestPermissions(plugin) { | |
| return invoke(`plugin:${plugin}|request_permissions`); | |
| } | |
| /** | |
| * Sends a message to the backend. | |
| * @example | |
| * ```typescript | |
| * import { invoke } from '@tauri-apps/api/core'; | |
| * await invoke('login', { user: 'tauri', password: 'poiwe3h4r5ip3yrhtew9ty' }); | |
| * ``` | |
| * | |
| * @param cmd The command name. | |
| * @param args The optional arguments to pass to the command. | |
| * @param options The request options. | |
| * @return A promise resolving or rejecting to the backend response. | |
| * | |
| * @since 1.0.0 | |
| */ | |
| async function invoke(cmd, args = {}, options) { | |
| return window.__TAURI_INTERNALS__.invoke(cmd, args, options); | |
| } | |
| /** | |
| * Convert a device file path to an URL that can be loaded by the webview. | |
| * Note that `asset:` and `http://asset.localhost` must be added to [`app.security.csp`](https://v2.tauri.app/reference/config/#csp-1) in `tauri.conf.json`. | |
| * Example CSP value: `"csp": "default-src 'self' ipc: http://ipc.localhost; img-src 'self' asset: http://asset.localhost"` to use the asset protocol on image sources. | |
| * | |
| * Additionally, `"enable" : "true"` must be added to [`app.security.assetProtocol`](https://v2.tauri.app/reference/config/#assetprotocolconfig) | |
| * in `tauri.conf.json` and its access scope must be defined on the `scope` array on the same `assetProtocol` object. | |
| * | |
| * @param filePath The file path. | |
| * @param protocol The protocol to use. Defaults to `asset`. You only need to set this when using a custom protocol. | |
| * @example | |
| * ```typescript | |
| * import { appDataDir, join } from '@tauri-apps/api/path'; | |
| * import { convertFileSrc } from '@tauri-apps/api/core'; | |
| * const appDataDirPath = await appDataDir(); | |
| * const filePath = await join(appDataDirPath, 'assets/video.mp4'); | |
| * const assetUrl = convertFileSrc(filePath); | |
| * | |
| * const video = document.getElementById('my-video'); | |
| * const source = document.createElement('source'); | |
| * source.type = 'video/mp4'; | |
| * source.src = assetUrl; | |
| * video.appendChild(source); | |
| * video.load(); | |
| * ``` | |
| * | |
| * @return the URL that can be used as source on the webview. | |
| * | |
| * @since 1.0.0 | |
| */ | |
| function convertFileSrc(filePath, protocol = 'asset') { | |
| return window.__TAURI_INTERNALS__.convertFileSrc(filePath, protocol); | |
| } | |
| /** | |
| * A rust-backed resource stored through `tauri::Manager::resources_table` API. | |
| * | |
| * The resource lives in the main process and does not exist | |
| * in the Javascript world, and thus will not be cleaned up automatically | |
| * except on application exit. If you want to clean it up early, call {@linkcode Resource.close} | |
| * | |
| * @example | |
| * ```typescript | |
| * import { Resource, invoke } from '@tauri-apps/api/core'; | |
| * export class DatabaseHandle extends Resource { | |
| * static async open(path: string): Promise<DatabaseHandle> { | |
| * const rid: number = await invoke('open_db', { path }); | |
| * return new DatabaseHandle(rid); | |
| * } | |
| * | |
| * async execute(sql: string): Promise<void> { | |
| * await invoke('execute_sql', { rid: this.rid, sql }); | |
| * } | |
| * } | |
| * ``` | |
| */ | |
| class Resource { | |
| get rid() { | |
| return tslib_es6.__classPrivateFieldGet(this, _Resource_rid, "f"); | |
| } | |
| constructor(rid) { | |
| _Resource_rid.set(this, void 0); | |
| tslib_es6.__classPrivateFieldSet(this, _Resource_rid, rid, "f"); | |
| } | |
| /** | |
| * Destroys and cleans up this resource from memory. | |
| * **You should not call any method on this object anymore and should drop any reference to it.** | |
| */ | |
| async close() { | |
| return invoke('plugin:resources|close', { | |
| rid: this.rid | |
| }); | |
| } | |
| } | |
| _Resource_rid = new WeakMap(); | |
| function isTauri() { | |
| // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access | |
| return !!(globalThis || window).isTauri; | |
| } | |
| exports.Channel = Channel; | |
| exports.PluginListener = PluginListener; | |
| exports.Resource = Resource; | |
| exports.SERIALIZE_TO_IPC_FN = SERIALIZE_TO_IPC_FN; | |
| exports.addPluginListener = addPluginListener; | |
| exports.checkPermissions = checkPermissions; | |
| exports.convertFileSrc = convertFileSrc; | |
| exports.invoke = invoke; | |
| exports.isTauri = isTauri; | |
| exports.requestPermissions = requestPermissions; | |
| exports.transformCallback = transformCallback; | |