-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinvoke-system-initialization-script.js
More file actions
132 lines (121 loc) · 4.31 KB
/
Copy pathinvoke-system-initialization-script.js
File metadata and controls
132 lines (121 loc) · 4.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
// Invoke system for the Servo runtime, derived from tauri's ipc-protocol.js.
//
// Servo does not expose custom protocol request bodies to embedders, so the
// custom protocol IPC path used by the default invoke system cannot carry
// invoke payloads. This script always routes invokes through the
// `window.ipc.postMessage` bridge provided by tauri-runtime-servo, except for
// the channel data fetch command which carries its arguments in request
// headers (no body needed) and requires a response.
;(function () {
/**
* A runtime generated key to ensure an IPC call comes from an initialized frame.
*
* This is declared outside the `window.__TAURI_INVOKE__` definition to prevent
* the key from being leaked by `window.__TAURI_INVOKE__.toString()`.
*/
const __TAURI_INVOKE_KEY__ = __INVOKE_KEY__
const processIpcMessage = function (message) {
if (
message instanceof ArrayBuffer
|| ArrayBuffer.isView(message)
|| Array.isArray(message)
) {
return {
contentType: 'application/octet-stream',
data: message
}
} else {
const data = JSON.stringify(message, (_k, val) => {
// if this value changes, make sure to update it in:
// 1. ipc.js
// 2. core.ts
const SERIALIZE_TO_IPC_FN = '__TAURI_TO_IPC_KEY__'
if (val instanceof Map) {
return Object.fromEntries(val.entries())
} else if (val instanceof Uint8Array) {
return Array.from(val)
} else if (val instanceof ArrayBuffer) {
return Array.from(new Uint8Array(val))
} else if (
typeof val === 'object'
&& val !== null
&& SERIALIZE_TO_IPC_FN in val
) {
return val[SERIALIZE_TO_IPC_FN]()
} else {
return val
}
})
return {
contentType: 'application/json',
data
}
}
}
const fetchChannelDataCommand = 'plugin:__TAURI_CHANNEL__|fetch'
let customProtocolIpcFailed = false
function sendIpcMessage(message) {
const { cmd, callback, error, payload, options } = message
if (!customProtocolIpcFailed && cmd === fetchChannelDataCommand) {
// the channel data fetch passes its arguments via headers and needs the
// response body, so it is the one command that keeps using the custom
// protocol
const { contentType, data } = processIpcMessage(payload)
const headers = new Headers((options && options.headers) || {})
headers.set('Content-Type', contentType)
headers.set('Tauri-Callback', callback)
headers.set('Tauri-Error', error)
headers.set('Tauri-Invoke-Key', __TAURI_INVOKE_KEY__)
fetch(window.__TAURI_INTERNALS__.convertFileSrc(cmd, 'ipc'), {
method: 'POST',
body: data,
headers
})
.then((response) => {
const callbackId =
response.headers.get('Tauri-Response') === 'ok' ? callback : error
switch ((response.headers.get('content-type') || '').split(',')[0]) {
case 'application/json':
return response.json().then((r) => [callbackId, r])
case 'text/plain':
return response.text().then((r) => [callbackId, r])
default:
return response.arrayBuffer().then((r) => [callbackId, r])
}
})
.then(
([callbackId, data]) => {
window.__TAURI_INTERNALS__.runCallback(callbackId, data)
},
(e) => {
console.warn(
'IPC custom protocol failed, Tauri will now use the postMessage interface instead',
e
)
customProtocolIpcFailed = true
sendIpcMessage(message)
}
)
} else {
// `window.ipc.postMessage` is provided by tauri-runtime-servo's IPC bridge
const { data } = processIpcMessage({
cmd,
callback,
error,
options: {
...options,
customProtocolIpcBlocked: customProtocolIpcFailed
},
payload,
__TAURI_INVOKE_KEY__
})
window.ipc.postMessage(data)
}
}
Object.defineProperty(window.__TAURI_INTERNALS__, 'postMessage', {
value: sendIpcMessage
})
})()