From 0de1429d844f09d9e274b1cd157e733f16e9fc78 Mon Sep 17 00:00:00 2001 From: amrbashir Date: Tue, 3 Oct 2023 01:47:28 +0300 Subject: [PATCH] refactor(core&api): hide internal functions and resuse them in api.js ref: https://github.com/tauri-apps/tauri/issues/7756 --- core/tauri/scripts/core.js | 120 ++++++++++++++--------------- core/tauri/scripts/init.js | 23 ++++-- core/tauri/scripts/ipc-protocol.js | 4 +- core/tauri/scripts/ipc.js | 8 +- core/tauri/scripts/pattern.js | 2 +- core/tauri/src/app.rs | 4 +- core/tauri/src/ipc/channel.rs | 2 +- core/tauri/src/manager.rs | 17 ++-- core/tauri/src/path/init.js | 14 ++-- core/tauri/src/window.rs | 2 +- examples/isolation/dist/index.html | 16 ++-- examples/isolation/dist/linked.js | 2 +- tooling/api/src/global.d.ts | 19 +++++ tooling/api/src/mocks.ts | 31 ++------ tooling/api/src/path.ts | 4 +- tooling/api/src/tauri.ts | 59 +------------- 16 files changed, 149 insertions(+), 178 deletions(-) create mode 100644 tooling/api/src/global.d.ts diff --git a/core/tauri/scripts/core.js b/core/tauri/scripts/core.js index 62ac1d1d241..5f83691889e 100644 --- a/core/tauri/scripts/core.js +++ b/core/tauri/scripts/core.js @@ -7,48 +7,46 @@ return window.crypto.getRandomValues(new Uint32Array(1))[0] } - if (!window.__TAURI__) { - Object.defineProperty(window, '__TAURI__', { - value: {} - }) - } - const osName = __TEMPLATE_os_name__ - window.__TAURI__.convertFileSrc = function convertFileSrc(filePath, protocol = 'asset') { - const path = encodeURIComponent(filePath) - return osName === 'windows' || osName === 'android' - ? `http://${protocol}.localhost/${path}` - : `${protocol}://localhost/${path}` - } + Object.defineProperties(window.__TAURI__.__INTERNALS__, 'convertFileSrc', { + value: function (filePath, protocol = 'asset') { + const path = encodeURIComponent(filePath) + return osName === 'windows' || osName === 'android' + ? `http://${protocol}.localhost/${path}` + : `${protocol}://localhost/${path}` + } + }) - window.__TAURI__.transformCallback = function transformCallback( - callback, - once - ) { - var identifier = uid() - var prop = `_${identifier}` + Object.defineProperties(window.__TAURI__.__INTERNALS__, 'transformCallback', { + value: function transformCallback( + callback, + once + ) { + var identifier = uid() + var prop = `_${identifier}` - Object.defineProperty(window, prop, { - value: (result) => { - if (once) { - Reflect.deleteProperty(window, prop) - } + Object.defineProperty(window, prop, { + value: (result) => { + if (once) { + Reflect.deleteProperty(window, prop) + } - return callback && callback(result) - }, - writable: false, - configurable: true - }) + return callback && callback(result) + }, + writable: false, + configurable: true + }) - return identifier - } + return identifier + } + }); const ipcQueue = [] let isWaitingForIpc = false function waitForIpc() { - if ('__TAURI_IPC__' in window) { + if (window.__TAURI__?.__INTERNALS__?.ipc) { for (const action of ipcQueue) { action() } @@ -57,35 +55,37 @@ } } - window.__TAURI_INVOKE__ = function invoke(cmd, payload = {}, options) { - return new Promise(function (resolve, reject) { - const callback = window.__TAURI__.transformCallback(function (r) { - resolve(r) - delete window[`_${error}`] - }, true) - const error = window.__TAURI__.transformCallback(function (e) { - reject(e) - delete window[`_${callback}`] - }, true) + Object.defineProperties(window.__TAURI__.__INTERNALS__, 'invoke', { + value: function (cmd, payload = {}, options) { + return new Promise(function (resolve, reject) { + const callback = window.__TAURI__.__INTERNALS__.transformCallback(function (r) { + resolve(r) + delete window[`_${error}`] + }, true) + const error = window.__TAURI__.__INTERNALS__.transformCallback(function (e) { + reject(e) + delete window[`_${callback}`] + }, true) - const action = () => { - window.__TAURI_IPC__({ - cmd, - callback, - error, - payload, - options - }) - } - if (window.__TAURI_IPC__) { - action() - } else { - ipcQueue.push(action) - if (!isWaitingForIpc) { - waitForIpc() - isWaitingForIpc = true + const action = () => { + window.window.__TAURI__.__INTERNALS__.ipc({ + cmd, + callback, + error, + payload, + options + }) } - } - }) - } + if (window.__TAURI__?.__INTERNALS__?.ipc) { + action() + } else { + ipcQueue.push(action) + if (!isWaitingForIpc) { + waitForIpc() + isWaitingForIpc = true + } + } + }) + } + }) })() diff --git a/core/tauri/scripts/init.js b/core/tauri/scripts/init.js index 0a242919bb8..4f08fa871c4 100644 --- a/core/tauri/scripts/init.js +++ b/core/tauri/scripts/init.js @@ -3,14 +3,23 @@ // SPDX-License-Identifier: MIT ; (function () { + if (!window.__TAURI__) { + Object.defineProperty(window, '__TAURI__', { + value: {} + }) + } + + if (!window.__TAURI__.__INTERNALS__) { + Object.defineProperty(window.__TAURI__, '__INTERNALS__', { + value: {} + }) + } + __RAW_freeze_prototype__ __RAW_pattern_script__ __RAW_ipc_script__ - ; (function () { - __RAW_bundle_script__ - })() __RAW_listen_function__ @@ -18,11 +27,15 @@ __RAW_event_initialization_script__ + ; (function () { + __RAW_bundle_script__ + })() + if (window.ipc) { - window.__TAURI_INVOKE__('__initialized', { url: window.location.href }) + window.__TAURI__.__INTERNALS__.invoke('__initialized', { url: window.location.href }) } else { window.addEventListener('DOMContentLoaded', function () { - window.__TAURI_INVOKE__('__initialized', { url: window.location.href }) + window.__TAURI__.__INTERNALS__.invoke('__initialized', { url: window.location.href }) }) } diff --git a/core/tauri/scripts/ipc-protocol.js b/core/tauri/scripts/ipc-protocol.js index f52ab5e09ad..9fe57d2cb7e 100644 --- a/core/tauri/scripts/ipc-protocol.js +++ b/core/tauri/scripts/ipc-protocol.js @@ -8,7 +8,7 @@ const fetchChannelDataCommand = __TEMPLATE_fetch_channel_data_command__ const useCustomProtocol = __TEMPLATE_use_custom_protocol__ - Object.defineProperty(window, '__TAURI_POST_MESSAGE__', { + Object.defineProperty(window.__TAURI__.__INTERNALS__, 'postMessage', { value: (message) => { const { cmd, @@ -36,7 +36,7 @@ contentType, data } = processIpcMessage(payload) - fetch(window.__TAURI__.convertFileSrc(cmd, 'ipc'), { + fetch(window.__TAURI__.__INTERNALS__.convertFileSrc(cmd, 'ipc'), { method: 'POST', body: data, headers: { diff --git a/core/tauri/scripts/ipc.js b/core/tauri/scripts/ipc.js index 1101e123b2c..30cf508e77c 100644 --- a/core/tauri/scripts/ipc.js +++ b/core/tauri/scripts/ipc.js @@ -11,7 +11,7 @@ /** * @type {string} */ - const pattern = window.__TAURI_PATTERN__.pattern + const pattern = window.__TAURI__.__INTERNALS__.__TAURI_PATTERN__.pattern /** * @type {string} @@ -90,12 +90,12 @@ ) } - Object.defineProperty(window, '__TAURI_IPC__', { + Object.defineProperty(window.__TAURI__.__INTERNALS__, 'ipc', { // todo: JSDoc this function value: Object.freeze((message) => { switch (pattern) { case 'brownfield': - window.__TAURI_POST_MESSAGE__(message) + window.__TAURI__.__INTERNALS__.postMessage(message) break case 'isolation': @@ -152,7 +152,7 @@ } if (isIsolationMessage(event)) { - window.__TAURI_POST_MESSAGE__(event.data) + window.__TAURI__.__INTERNALS__.postMessage(event.data) } }, false diff --git a/core/tauri/scripts/pattern.js b/core/tauri/scripts/pattern.js index cf22d8047cd..51c6aaa8d3d 100644 --- a/core/tauri/scripts/pattern.js +++ b/core/tauri/scripts/pattern.js @@ -15,7 +15,7 @@ return Object.freeze(object) } - Object.defineProperty(window, '__TAURI_PATTERN__', { + Object.defineProperty(window.__TAURI__.__INTERNALS__, '__TAURI_PATTERN__', { value: __tauriDeepFreeze(__TEMPLATE_pattern__) }) })() diff --git a/core/tauri/src/app.rs b/core/tauri/src/app.rs index 699dedbef1c..a6e450c6e32 100644 --- a/core/tauri/src/app.rs +++ b/core/tauri/src/app.rs @@ -974,7 +974,7 @@ pub struct Builder { /// The JS message responder. invoke_responder: Option>>, - /// The script that initializes the `window.__TAURI_POST_MESSAGE__` function. + /// The script that initializes the `window.__TAURI__.__INTERNALS__.postMessage` function. invoke_initialization_script: String, /// The setup hook. @@ -1092,7 +1092,7 @@ impl Builder { /// /// The `responder` is a function that will be called when a command has been executed and must send a response to the JS layer. /// - /// The `initialization_script` is a script that initializes `window.__TAURI_POST_MESSAGE__`. + /// The `initialization_script` is a script that initializes `window.__TAURI__.__INTERNALS__.postMessage`. /// That function must take the `(message: object, options: object)` arguments and send it to the backend. #[must_use] pub fn invoke_system(mut self, initialization_script: String, responder: F) -> Self diff --git a/core/tauri/src/ipc/channel.rs b/core/tauri/src/ipc/channel.rs index 76a9101ceba..21483ce845a 100644 --- a/core/tauri/src/ipc/channel.rs +++ b/core/tauri/src/ipc/channel.rs @@ -78,7 +78,7 @@ impl Channel { .unwrap() .insert(data_id, body); window.eval(&format!( - "__TAURI_INVOKE__('{FETCH_CHANNEL_DATA_COMMAND}', null, {{ headers: {{ '{CHANNEL_ID_HEADER_NAME}': '{data_id}' }} }}).then(window['_' + {}]).catch(console.error)", + "window.__TAURI__.__INTERNALS__.invoke('{FETCH_CHANNEL_DATA_COMMAND}', null, {{ headers: {{ '{CHANNEL_ID_HEADER_NAME}': '{data_id}' }} }}).then(window['_' + {}]).catch(console.error)", callback.0 )) }) diff --git a/core/tauri/src/manager.rs b/core/tauri/src/manager.rs index 105133870a0..73bd9478ae6 100644 --- a/core/tauri/src/manager.rs +++ b/core/tauri/src/manager.rs @@ -568,17 +568,22 @@ impl WindowManager { .initialization_script(&self.inner.invoke_initialization_script) .initialization_script(&format!( r#" - Object.defineProperty(window, '__TAURI_METADATA__', {{ + Object.defineProperty(window.__TAURI__.__INTERNALS__, 'metadata', {{ value: {{ - __windows: {window_labels_array}.map(function (label) {{ return {{ label: label }} }}), - __currentWindow: {{ label: {current_window_label} }} + windows: {window_labels_array}.map(function (label) {{ return {{ label: label }} }}), + currentWindow: {{ label: {current_window_label} }} }} }}) "#, window_labels_array = serde_json::to_string(&window_labels)?, current_window_label = serde_json::to_string(&label)?, )) - .initialization_script(&self.initialization_script(&ipc_init.into_string(),&pattern_init.into_string(),&plugin_init, is_init_global)?); + .initialization_script(&self.initialization_script( + &ipc_init.into_string(), + &pattern_init.into_string(), + &plugin_init, + is_init_global, + )?); #[cfg(feature = "isolation")] if let Pattern::Isolation { schema, .. } = self.pattern() { @@ -814,7 +819,7 @@ impl WindowManager { "eventName".into(), 0, None, - "window['_' + window.__TAURI__.transformCallback(cb) ]".into() + "window['_' + window.__TAURI__.__INTERNALS__.transformCallback(cb) ]".into() ) ), core_script: &CoreJavascript { @@ -1275,7 +1280,7 @@ fn on_window_event( let windows = windows_map.values(); for window in windows { window.eval(&format!( - r#"(function () {{ const metadata = window.__TAURI_METADATA__; if (metadata != null) {{ metadata.__windows = window.__TAURI_METADATA__.__windows.filter(w => w.label !== "{label}"); }} }})()"#, + r#"(function () {{ const metadata = window.__TAURI__.__INTERNALS__.metadata; if (metadata != null) {{ metadata.windows = window.__TAURI__.__INTERNALS__.metadata.windows.filter(w => w.label !== "{label}"); }} }})()"#, ))?; } } diff --git a/core/tauri/src/path/init.js b/core/tauri/src/path/init.js index 4de1c2d1118..6724677c03b 100644 --- a/core/tauri/src/path/init.js +++ b/core/tauri/src/path/init.js @@ -2,9 +2,11 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -if (!('path' in window.__TAURI__)) { - window.__TAURI__.path = {} -} - -window.__TAURI__.path.__sep = __TEMPLATE_sep__ -window.__TAURI__.path.__delimiter = __TEMPLATE_delimiter__ +Object.defineProperty(window.__TAURI__.__INTERNALS__, 'path', { + value: { + path: { + sep: __TEMPLATE_sep__, + delimiter: __TEMPLATE_delimiter__ + } + } +}) diff --git a/core/tauri/src/window.rs b/core/tauri/src/window.rs index 791344ad5d6..7c893d6ec69 100644 --- a/core/tauri/src/window.rs +++ b/core/tauri/src/window.rs @@ -425,7 +425,7 @@ impl<'a, R: Runtime> WindowBuilder<'a, R> { crate::vibrancy::set_window_effects(&window, Some(effects))?; } self.manager.eval_script_all(format!( - "window.__TAURI_METADATA__.__windows = {window_labels_array}.map(function (label) {{ return {{ label: label }} }})", + "window.__TAURI__.__INTERNALS__.metadata.windows = {window_labels_array}.map(function (label) {{ return {{ label: label }} }})", window_labels_array = serde_json::to_string(&self.manager.labels())?, ))?; diff --git a/examples/isolation/dist/index.html b/examples/isolation/dist/index.html index cc4311f0955..2af56ca1d64 100644 --- a/examples/isolation/dist/index.html +++ b/examples/isolation/dist/index.html @@ -3,11 +3,11 @@ Hello Tauri! @@ -36,7 +36,7 @@ align-items: center; } - +
@@ -55,15 +55,15 @@

Hello, Tauri!

code.innerText = JSON.stringify(obj, null, 2); } - const cb = window.__TAURI__.transformCallback(v => updateCode('response', v)); - const error = window.__TAURI__.transformCallback(e => updateCode('response', e)); + const cb = window.__TAURI__.tauri.transformCallback(v => updateCode('response', v)); + const error = window.__TAURI__.tauri.transformCallback(e => updateCode('response', e)); window.ipc.postMessage(JSON.stringify({ cmd: "ping", callback: cb, error, })); - - updateCode('__TAURI_PATTERN__', window.__TAURI_PATTERN__); + + updateCode('__TAURI__.__INTERNALS__.__TAURI_PATTERN__', window.__TAURI__.__INTERNALS__.__TAURI_PATTERN__); @@ -71,7 +71,7 @@

Hello, Tauri!

const ping = document.querySelector("#ping") const pong = document.querySelector('#pong') ping.addEventListener("click", () => { - window.__TAURI_INVOKE__("ping") + window.__TAURI__.tauri.invoke("ping") .then(() => { pong.innerText = `ok: ${Date.now()}` }) diff --git a/examples/isolation/dist/linked.js b/examples/isolation/dist/linked.js index 7f65231311a..5fafe6b80a8 100644 --- a/examples/isolation/dist/linked.js +++ b/examples/isolation/dist/linked.js @@ -1 +1 @@ -console.log("linked", window.__TAURI_PATTERN__); +console.log("linked", window.__TAURI__.__INTERNALS__.__TAURI_PATTERN__); diff --git a/tooling/api/src/global.d.ts b/tooling/api/src/global.d.ts new file mode 100644 index 00000000000..dbb5133de2d --- /dev/null +++ b/tooling/api/src/global.d.ts @@ -0,0 +1,19 @@ +/** @ignore */ +interface Window { + __TAURI__: { + __INTERNALS__: { + invoke: typeof invoke + transformCallback: typeof transformCallback + convertFileSrc: typeof convertFileSrc + ipc: (message: any) => void + metadata: { + windows: WindowDef[] + currentWindow: WindowDef + } + path: { + sep: string + delimiter: string + } + } + } +} diff --git a/tooling/api/src/mocks.ts b/tooling/api/src/mocks.ts index ce5a93f9bb8..1a9ac761cba 100644 --- a/tooling/api/src/mocks.ts +++ b/tooling/api/src/mocks.ts @@ -2,21 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -/** @ignore */ -declare global { - interface Window { - __TAURI_METADATA__: { - __windows: WindowDef[] - __currentWindow: WindowDef - } - } -} - -/** @ignore */ -interface WindowDef { - label: string -} - interface IPCMessage { cmd: string callback: number @@ -81,7 +66,7 @@ export function mockIPC( cb: (cmd: string, payload: Record) => any | Promise ): void { // eslint-disable-next-line @typescript-eslint/no-misused-promises - window.__TAURI_IPC__ = async ({ + window.__TAURI__.__INTERNALS__.ipc = async ({ cmd, callback, error, @@ -143,9 +128,9 @@ export function mockWindows( current: string, ...additionalWindows: string[] ): void { - window.__TAURI_METADATA__ = { - __windows: [current, ...additionalWindows].map((label) => ({ label })), - __currentWindow: { label: current } + window.__TAURI__.__INTERNALS__.metadata = { + windows: [current, ...additionalWindows].map((label) => ({ label })), + currentWindow: { label: current } } } @@ -165,11 +150,11 @@ export function mockWindows( * test("mocked windows", () => { * mockWindows("main", "second", "third"); * - * expect(window).toHaveProperty("__TAURI_METADATA__") + * expect(window.__TAURI__.__INTERNALS__.metadata).toHaveProperty("__TAURI__.__INTERNALS__.metadata") * }) * * test("no mocked windows", () => { - * expect(window).not.toHaveProperty("__TAURI_METADATA__") + * expect(window.__TAURI__.__INTERNALS__.metadata).not.toHaveProperty("__TAURI__.__INTERNALS__.metadata") * }) * ``` * @@ -177,7 +162,7 @@ export function mockWindows( */ export function clearMocks(): void { // @ts-expect-error "The operand of a 'delete' operator must be optional' does not matter in this case - delete window.__TAURI_IPC__ + delete window.__TAURI__.__INTERNALS__.ipc // @ts-expect-error "The operand of a 'delete' operator must be optional' does not matter in this case - delete window.__TAURI_METADATA__ + delete window.__TAURI__.__INTERNALS__.metadata } diff --git a/tooling/api/src/path.ts b/tooling/api/src/path.ts index e87f0480188..d21b14dbec1 100644 --- a/tooling/api/src/path.ts +++ b/tooling/api/src/path.ts @@ -547,7 +547,7 @@ async function tempDir(path: string): Promise { * @since 2.0.0 */ function sep(): string { - return window.__TAURI__.path.__sep + return window.__TAURI__.__INTERNALS__.path.sep } /** @@ -558,7 +558,7 @@ function sep(): string { * @since 2.0.0 */ function delimiter(): string { - return window.__TAURI__.path.__delimiter + return window.__TAURI__.__INTERNALS__.path.delimiter } /** * Resolves a sequence of `paths` or `path` segments into an absolute path. diff --git a/tooling/api/src/tauri.ts b/tooling/api/src/tauri.ts index 8d76c0d3242..335d58b3f1b 100644 --- a/tooling/api/src/tauri.ts +++ b/tooling/api/src/tauri.ts @@ -9,27 +9,6 @@ * @module */ -/** @ignore */ -declare global { - interface Window { - __TAURI__: { - path: { - __sep: string - __delimiter: string - } - - convertFileSrc: (src: string, protocol: string) => string - } - - __TAURI_IPC__: (message: any) => void - } -} - -/** @ignore */ -function uid(): number { - return window.crypto.getRandomValues(new Uint32Array(1))[0] -} - /** * Transforms a callback function to a string identifier that can be passed to the backend. * The backend uses the identifier to `eval()` the callback. @@ -42,22 +21,7 @@ function transformCallback( callback?: (response: any) => void, once = false ): number { - const identifier = uid() - const prop = `_${identifier}` - - Object.defineProperty(window, prop, { - value: (result: any) => { - if (once) { - Reflect.deleteProperty(window, prop) - } - - return callback?.(result) - }, - writable: false, - configurable: true - }) - - return identifier + return window.__TAURI__.__INTERNALS__.transformCallback(callback, once) } class Channel { @@ -159,24 +123,7 @@ async function invoke( args: InvokeArgs = {}, options?: InvokeOptions ): Promise { - return new Promise((resolve, reject) => { - const callback = transformCallback((e: T) => { - resolve(e) - Reflect.deleteProperty(window, `_${error}`) - }, true) - const error = transformCallback((e) => { - reject(e) - Reflect.deleteProperty(window, `_${callback}`) - }, true) - - window.__TAURI_IPC__({ - cmd, - callback, - error, - payload: args, - options - }) - }) + return window.__TAURI__.__INTERNALS__.invoke(cmd, args, options) } /** @@ -210,7 +157,7 @@ async function invoke( * @since 1.0.0 */ function convertFileSrc(filePath: string, protocol = 'asset'): string { - return window.__TAURI__.convertFileSrc(filePath, protocol) + return window.__TAURI__.__INTERNALS__.convertFileSrc(filePath, protocol) } export type { InvokeArgs, InvokeOptions }