Skip to content

Commit

Permalink
use toIPC mechanism for channels, fix bug checking null
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasfernog committed Oct 17, 2024
1 parent 6e79d48 commit 744f4bc
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 62 deletions.
2 changes: 1 addition & 1 deletion crates/tauri/scripts/bundle.global.js

Large diffs are not rendered by default.

8 changes: 7 additions & 1 deletion crates/tauri/scripts/ipc.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,18 +100,24 @@

if (
typeof data === 'object' &&
data !== null &&
'constructor' in data &&
data.constructor === Array
) {
return data.map((v) => serializeIpcPayload(v))
}

if (typeof data === 'object' && SERIALIZE_TO_IPC_FN in data) {
if (
typeof data === 'object' &&
data !== null &&
SERIALIZE_TO_IPC_FN in data
) {
return data[SERIALIZE_TO_IPC_FN]()
}

if (
typeof data === 'object' &&
data !== null &&
'constructor' in data &&
data.constructor === Object
) {
Expand Down
8 changes: 1 addition & 7 deletions crates/tauri/scripts/process-ipc-message-fn.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,7 @@
return Array.from(val)
} else if (val instanceof ArrayBuffer) {
return Array.from(new Uint8Array(val))
} else if (
typeof val === "object" &&
'__TAURI_CHANNEL_MARKER__' in val &&
typeof val.id === 'number'
) {
return `__CHANNEL__:${val.id}`
} else if (typeof val === "object" && SERIALIZE_TO_IPC_FN in val) {
} else if (typeof val === "object" && val !== null && SERIALIZE_TO_IPC_FN in val) {
return val[SERIALIZE_TO_IPC_FN]()
} else {
return val
Expand Down
109 changes: 56 additions & 53 deletions packages/api/src/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,56 @@
* @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
export const SERIALIZE_TO_IPC_FN = '__TAURI_TO_IPC_KEY__'

/**
* Transforms a callback function to a string identifier that can be passed to the backend.
* The backend uses the identifier to `eval()` the callback.
Expand All @@ -26,8 +76,6 @@ function transformCallback<T = unknown>(

class Channel<T = unknown> {
id: number
// @ts-expect-error field used by the IPC serializer
private readonly __TAURI_CHANNEL_MARKER__ = true
#onmessage: (response: T) => void = () => {
// no-op
}
Expand Down Expand Up @@ -80,9 +128,14 @@ class Channel<T = unknown> {
return this.#onmessage
}

toJSON(): string {
[SERIALIZE_TO_IPC_FN]() {
return `__CHANNEL__:${this.id}`
}

toJSON(): string {
// eslint-disable-next-line security/detect-object-injection
return this[SERIALIZE_TO_IPC_FN]()
}
}

class PluginListener {
Expand Down Expand Up @@ -258,56 +311,6 @@ export class Resource {
}
}

/**
* 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
export const SERIALIZE_TO_IPC_FN = '__TAURI_TO_IPC_KEY__'

function isTauri(): boolean {
return 'isTauri' in window && !!window.isTauri
}
Expand Down
3 changes: 3 additions & 0 deletions packages/api/src/dpi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ class LogicalSize {
* @since 2.0.0
*/
toJSON() {
// eslint-disable-next-line security/detect-object-injection
return this[SERIALIZE_TO_IPC_FN]()
}
}
Expand Down Expand Up @@ -184,6 +185,7 @@ class PhysicalSize {
* @since 2.0.0
*/
toJSON() {
// eslint-disable-next-line security/detect-object-injection
return this[SERIALIZE_TO_IPC_FN]()
}
}
Expand Down Expand Up @@ -278,6 +280,7 @@ class LogicalPosition {
* @since 2.0.0
*/
toJSON() {
// eslint-disable-next-line security/detect-object-injection
return this[SERIALIZE_TO_IPC_FN]()
}
}
Expand Down

0 comments on commit 744f4bc

Please sign in to comment.