@appport/transport-tauri 1.0.0

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.
package/README.md ADDED
@@ -0,0 +1,45 @@
1
+ # @appport/transport-tauri
2
+
3
+ The Tauri IPC transport.
4
+
5
+ ```ts
6
+ import { invoke } from "@tauri-apps/api/core";
7
+ import { listen } from "@tauri-apps/api/event";
8
+ import { createTauriTransport } from "@appport/transport-tauri";
9
+
10
+ const transport = createTauriTransport({ invoke, listen });
11
+ ```
12
+
13
+ Tauri already models IPC as serialized request/response commands plus one-way
14
+ events, which is the same split AppPort makes between capabilities and events.
15
+ One command carries every capability; the envelope names it.
16
+
17
+ ## The Rust side
18
+
19
+ ```rust
20
+ #[tauri::command]
21
+ pub async fn appport_request(
22
+ app: AppHandle,
23
+ state: State<'_, AppPort>,
24
+ envelope: Value,
25
+ ) -> Result<Option<Value>, String> {
26
+ match envelope.get("type").and_then(Value::as_str) {
27
+ // Request envelopes are answered by the command's return value.
28
+ Some("request") => Ok(Some(state.runtime.handle_request(envelope).await)),
29
+ // Everything else replies asynchronously on one event channel.
30
+ _ => {
31
+ let handle = app.clone();
32
+ state
33
+ .runtime
34
+ .handle_duplex(envelope, move |outgoing| {
35
+ let _ = handle.emit("appport://message", outgoing);
36
+ })
37
+ .await;
38
+ Ok(None)
39
+ }
40
+ }
41
+ }
42
+ ```
43
+
44
+ Without `listen`, the transport is request/response only — conformance level 1.
45
+ With it, events and streams work exactly as they do over WebSocket.
@@ -0,0 +1,23 @@
1
+ import { type AppTransport } from "@appport/client";
2
+ /** `@tauri-apps/api`'s `invoke`, structurally. */
3
+ export type TauriInvoke = (command: string, args?: Record<string, unknown>) => Promise<unknown>;
4
+ /** `@tauri-apps/api`'s `listen`, structurally. */
5
+ export type TauriListen = (event: string, handler: (event: {
6
+ payload: unknown;
7
+ }) => void) => Promise<() => void>;
8
+ export declare const APPPORT_COMMAND = "appport_request";
9
+ export declare const APPPORT_EVENT = "appport://message";
10
+ export interface TauriTransportOptions {
11
+ invoke: TauriInvoke;
12
+ /**
13
+ * Event listener used for server-pushed envelopes (events, stream chunks).
14
+ * Without it the transport is request/response only — conformance level 1.
15
+ */
16
+ listen?: TauriListen;
17
+ /** Command name. Defaults to `appport_request`. */
18
+ command?: string;
19
+ /** Event name the Rust side emits envelopes on. */
20
+ eventName?: string;
21
+ }
22
+ export declare function createTauriTransport(options: TauriTransportOptions): AppTransport;
23
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,OAAO,EAAyB,KAAK,YAAY,EAAuB,MAAM,iBAAiB,CAAC;AAEhG,kDAAkD;AAClD,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAEhG,kDAAkD;AAClD,MAAM,MAAM,WAAW,GAAG,CACxB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,CAAC,KAAK,EAAE;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,KAAK,IAAI,KAC3C,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;AAEzB,eAAO,MAAM,eAAe,oBAAoB,CAAC;AACjD,eAAO,MAAM,aAAa,sBAAsB,CAAC;AAEjD,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,WAAW,CAAC;IACpB;;;OAGG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,mDAAmD;IACnD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mDAAmD;IACnD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,qBAAqB,GAAG,YAAY,CAiCjF"}
package/dist/index.js ADDED
@@ -0,0 +1,44 @@
1
+ /**
2
+ * `@appport/transport-tauri` — the Tauri IPC transport (§23, §29).
3
+ *
4
+ * Tauri already models IPC as serialized request/response commands plus
5
+ * one-way events, which is the same split AppPort makes between capabilities
6
+ * and events. One command, `appport_request`, carries every capability; the
7
+ * envelope names the capability.
8
+ */
9
+ import { errors } from "@appport/protocol";
10
+ import { createDuplexTransport } from "@appport/client";
11
+ export const APPPORT_COMMAND = "appport_request";
12
+ export const APPPORT_EVENT = "appport://message";
13
+ export function createTauriTransport(options) {
14
+ const command = options.command ?? APPPORT_COMMAND;
15
+ const eventName = options.eventName ?? APPPORT_EVENT;
16
+ let unlisten;
17
+ let deliver;
18
+ return createDuplexTransport({
19
+ kind: "ipc",
20
+ features: { events: Boolean(options.listen), streams: Boolean(options.listen), persistent: true },
21
+ async open(handlers) {
22
+ deliver = handlers.onEnvelope;
23
+ if (options.listen) {
24
+ unlisten = await options.listen(eventName, (event) => handlers.onEnvelope(event.payload));
25
+ }
26
+ },
27
+ async send(envelope) {
28
+ const result = await options.invoke(command, { envelope });
29
+ // The command answers synchronously for request/response capabilities and
30
+ // returns null when the reply arrives as an event instead.
31
+ if (result !== null && result !== undefined) {
32
+ if (!deliver)
33
+ throw errors.internal("The Tauri transport received a reply before it was opened");
34
+ deliver(result);
35
+ }
36
+ },
37
+ async close() {
38
+ unlisten?.();
39
+ unlisten = undefined;
40
+ deliver = undefined;
41
+ }
42
+ });
43
+ }
44
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,MAAM,EAAuB,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAA0C,MAAM,iBAAiB,CAAC;AAWhG,MAAM,CAAC,MAAM,eAAe,GAAG,iBAAiB,CAAC;AACjD,MAAM,CAAC,MAAM,aAAa,GAAG,mBAAmB,CAAC;AAejD,MAAM,UAAU,oBAAoB,CAAC,OAA8B;IACjE,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,eAAe,CAAC;IACnD,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,aAAa,CAAC;IACrD,IAAI,QAAkC,CAAC;IACvC,IAAI,OAA+C,CAAC;IAEpD,OAAO,qBAAqB,CAAC;QAC3B,IAAI,EAAE,KAAK;QACX,QAAQ,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE;QAEjG,KAAK,CAAC,IAAI,CAAC,QAAwB;YACjC,OAAO,GAAG,QAAQ,CAAC,UAAU,CAAC;YAC9B,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;gBACnB,QAAQ,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;YAC5F,CAAC;QACH,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,QAAwB;YACjC,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;YAC3D,0EAA0E;YAC1E,2DAA2D;YAC3D,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBAC5C,IAAI,CAAC,OAAO;oBAAE,MAAM,MAAM,CAAC,QAAQ,CAAC,2DAA2D,CAAC,CAAC;gBACjG,OAAO,CAAC,MAAM,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;QAED,KAAK,CAAC,KAAK;YACT,QAAQ,EAAE,EAAE,CAAC;YACb,QAAQ,GAAG,SAAS,CAAC;YACrB,OAAO,GAAG,SAAS,CAAC;QACtB,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "@appport/transport-tauri",
3
+ "version": "1.0.0",
4
+ "description": "Tauri IPC AppPort transport.",
5
+ "license": "Apache-2.0",
6
+ "repository": { "type": "git", "url": "git+https://github.com/rkendel1/appport.git", "directory": "packages/transports/tauri" },
7
+ "type": "module",
8
+ "main": "./dist/index.js",
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.js"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist",
18
+ "README.md"
19
+ ],
20
+ "scripts": {
21
+ "build": "tsc -b",
22
+ "clean": "tsc -b --clean"
23
+ },
24
+ "dependencies": {
25
+ "@appport/protocol": "1.0.0",
26
+ "@appport/client": "1.0.0"
27
+ },
28
+ "publishConfig": { "access": "public" }
29
+ }