@wailsio/runtime 3.0.0-alpha.72 → 3.0.0-alpha.74

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/dist/calls.js CHANGED
@@ -12,8 +12,6 @@ import { newRuntimeCaller, objectNames } from "./runtime.js";
12
12
  import { nanoid } from "./nanoid.js";
13
13
  // Setup
14
14
  window._wails = window._wails || {};
15
- window._wails.callResultHandler = resultHandler;
16
- window._wails.callErrorHandler = errorHandler;
17
15
  const call = newRuntimeCaller(objectNames.Call);
18
16
  const cancelCall = newRuntimeCaller(objectNames.CancelCall);
19
17
  const callResponses = new Map();
@@ -34,90 +32,6 @@ export class RuntimeError extends Error {
34
32
  this.name = "RuntimeError";
35
33
  }
36
34
  }
37
- /**
38
- * Handles the result of a call request.
39
- *
40
- * @param id - The id of the request to handle the result for.
41
- * @param data - The result data of the request.
42
- * @param isJSON - Indicates whether the data is JSON or not.
43
- */
44
- function resultHandler(id, data, isJSON) {
45
- const resolvers = getAndDeleteResponse(id);
46
- if (!resolvers) {
47
- return;
48
- }
49
- if (!data) {
50
- resolvers.resolve(undefined);
51
- }
52
- else if (!isJSON) {
53
- resolvers.resolve(data);
54
- }
55
- else {
56
- try {
57
- resolvers.resolve(JSON.parse(data));
58
- }
59
- catch (err) {
60
- resolvers.reject(new TypeError("could not parse result: " + err.message, { cause: err }));
61
- }
62
- }
63
- }
64
- /**
65
- * Handles the error from a call request.
66
- *
67
- * @param id - The id of the promise handler.
68
- * @param data - The error data to reject the promise handler with.
69
- * @param isJSON - Indicates whether the data is JSON or not.
70
- */
71
- function errorHandler(id, data, isJSON) {
72
- const resolvers = getAndDeleteResponse(id);
73
- if (!resolvers) {
74
- return;
75
- }
76
- if (!isJSON) {
77
- resolvers.reject(new Error(data));
78
- }
79
- else {
80
- let error;
81
- try {
82
- error = JSON.parse(data);
83
- }
84
- catch (err) {
85
- resolvers.reject(new TypeError("could not parse error: " + err.message, { cause: err }));
86
- return;
87
- }
88
- let options = {};
89
- if (error.cause) {
90
- options.cause = error.cause;
91
- }
92
- let exception;
93
- switch (error.kind) {
94
- case "ReferenceError":
95
- exception = new ReferenceError(error.message, options);
96
- break;
97
- case "TypeError":
98
- exception = new TypeError(error.message, options);
99
- break;
100
- case "RuntimeError":
101
- exception = new RuntimeError(error.message, options);
102
- break;
103
- default:
104
- exception = new Error(error.message, options);
105
- break;
106
- }
107
- resolvers.reject(exception);
108
- }
109
- }
110
- /**
111
- * Retrieves and removes the response associated with the given ID from the callResponses map.
112
- *
113
- * @param id - The ID of the response to be retrieved and removed.
114
- * @returns The response object associated with the given ID, if any.
115
- */
116
- function getAndDeleteResponse(id) {
117
- const response = callResponses.get(id);
118
- callResponses.delete(id);
119
- return response;
120
- }
121
35
  /**
122
36
  * Generates a unique ID using the nanoid library.
123
37
  *
@@ -147,10 +61,13 @@ export function Call(options) {
147
61
  const result = CancellablePromise.withResolvers();
148
62
  callResponses.set(id, { resolve: result.resolve, reject: result.reject });
149
63
  const request = call(CallBinding, Object.assign({ "call-id": id }, options));
150
- let running = false;
151
- request.then(() => {
152
- running = true;
64
+ let running = true;
65
+ request.then((res) => {
66
+ running = false;
67
+ callResponses.delete(id);
68
+ result.resolve(res);
153
69
  }, (err) => {
70
+ running = false;
154
71
  callResponses.delete(id);
155
72
  result.reject(err);
156
73
  });
package/dist/create.js CHANGED
@@ -92,3 +92,8 @@ export function Struct(createField) {
92
92
  return source;
93
93
  };
94
94
  }
95
+ /**
96
+ * Maps known event names to creation functions for their data types.
97
+ * Will be monkey-patched by the binding generator.
98
+ */
99
+ export const Events = {};
package/dist/dialogs.js CHANGED
@@ -8,13 +8,9 @@ The electron alternative for Go
8
8
  (c) Lea Anthony 2019-present
9
9
  */
10
10
  import { newRuntimeCaller, objectNames } from "./runtime.js";
11
- import { nanoid } from './nanoid.js';
12
11
  // setup
13
12
  window._wails = window._wails || {};
14
- window._wails.dialogErrorCallback = dialogErrorCallback;
15
- window._wails.dialogResultCallback = dialogResultCallback;
16
13
  const call = newRuntimeCaller(objectNames.Dialog);
17
- const dialogResponses = new Map();
18
14
  // Define constants from the `methods` object in Title Case
19
15
  const DialogInfo = 0;
20
16
  const DialogWarning = 1;
@@ -22,63 +18,6 @@ const DialogError = 2;
22
18
  const DialogQuestion = 3;
23
19
  const DialogOpenFile = 4;
24
20
  const DialogSaveFile = 5;
25
- /**
26
- * Handles the result of a dialog request.
27
- *
28
- * @param id - The id of the request to handle the result for.
29
- * @param data - The result data of the request.
30
- * @param isJSON - Indicates whether the data is JSON or not.
31
- */
32
- function dialogResultCallback(id, data, isJSON) {
33
- let resolvers = getAndDeleteResponse(id);
34
- if (!resolvers) {
35
- return;
36
- }
37
- if (isJSON) {
38
- try {
39
- resolvers.resolve(JSON.parse(data));
40
- }
41
- catch (err) {
42
- resolvers.reject(new TypeError("could not parse result: " + err.message, { cause: err }));
43
- }
44
- }
45
- else {
46
- resolvers.resolve(data);
47
- }
48
- }
49
- /**
50
- * Handles the error from a dialog request.
51
- *
52
- * @param id - The id of the promise handler.
53
- * @param message - An error message.
54
- */
55
- function dialogErrorCallback(id, message) {
56
- var _a;
57
- (_a = getAndDeleteResponse(id)) === null || _a === void 0 ? void 0 : _a.reject(new window.Error(message));
58
- }
59
- /**
60
- * Retrieves and removes the response associated with the given ID from the dialogResponses map.
61
- *
62
- * @param id - The ID of the response to be retrieved and removed.
63
- * @returns The response object associated with the given ID, if any.
64
- */
65
- function getAndDeleteResponse(id) {
66
- const response = dialogResponses.get(id);
67
- dialogResponses.delete(id);
68
- return response;
69
- }
70
- /**
71
- * Generates a unique ID using the nanoid library.
72
- *
73
- * @returns A unique ID that does not exist in the dialogResponses set.
74
- */
75
- function generateID() {
76
- let result;
77
- do {
78
- result = nanoid();
79
- } while (dialogResponses.has(result));
80
- return result;
81
- }
82
21
  /**
83
22
  * Presents a dialog of specified type with the given options.
84
23
  *
@@ -87,14 +26,7 @@ function generateID() {
87
26
  * @returns A promise that resolves with result of dialog.
88
27
  */
89
28
  function dialog(type, options = {}) {
90
- const id = generateID();
91
- return new Promise((resolve, reject) => {
92
- dialogResponses.set(id, { resolve, reject });
93
- call(type, Object.assign({ "dialog-id": id }, options)).catch((err) => {
94
- dialogResponses.delete(id);
95
- reject(err);
96
- });
97
- });
29
+ return call(type, options);
98
30
  }
99
31
  /**
100
32
  * Presents an info dialog.
@@ -230,3 +230,7 @@ export const Types = Object.freeze({
230
230
  WindowDropZoneFilesDropped: "common:WindowDropZoneFilesDropped",
231
231
  }),
232
232
  });
233
+ export const Windows = Types.Windows;
234
+ export const Mac = Types.Mac;
235
+ export const Linux = Types.Linux;
236
+ export const Common = Types.Common;
package/dist/events.js CHANGED
@@ -9,19 +9,21 @@ The electron alternative for Go
9
9
  */
10
10
  import { newRuntimeCaller, objectNames } from "./runtime.js";
11
11
  import { eventListeners, Listener, listenerOff } from "./listener.js";
12
+ import { Events as Create } from "./create.js";
13
+ import { Types } from "./event_types.js";
12
14
  // Setup
13
15
  window._wails = window._wails || {};
14
16
  window._wails.dispatchWailsEvent = dispatchWailsEvent;
15
17
  const call = newRuntimeCaller(objectNames.Events);
16
18
  const EmitMethod = 0;
17
- export { Types } from "./event_types.js";
19
+ export * from "./event_types.js";
18
20
  /**
19
21
  * Represents a system event or a custom event emitted through wails-provided facilities.
20
22
  */
21
23
  export class WailsEvent {
22
- constructor(name, data = null) {
24
+ constructor(name, data) {
23
25
  this.name = name;
24
- this.data = data;
26
+ this.data = data !== null && data !== void 0 ? data : null;
25
27
  }
26
28
  }
27
29
  function dispatchWailsEvent(event) {
@@ -29,7 +31,7 @@ function dispatchWailsEvent(event) {
29
31
  if (!listeners) {
30
32
  return;
31
33
  }
32
- let wailsEvent = new WailsEvent(event.name, event.data);
34
+ let wailsEvent = new WailsEvent(event.name, (event.name in Create) ? Create[event.name](event.data) : event.data);
33
35
  if ('sender' in event) {
34
36
  wailsEvent.sender = event.sender;
35
37
  }
@@ -90,25 +92,6 @@ export function Off(...eventNames) {
90
92
  export function OffAll() {
91
93
  eventListeners.clear();
92
94
  }
93
- /**
94
- * Emits an event using the name and data.
95
- *
96
- * @returns A promise that will be fulfilled once the event has been emitted.
97
- * @param name - the name of the event to emit.
98
- * @param data - the data to be sent with the event.
99
- */
100
95
  export function Emit(name, data) {
101
- let eventName;
102
- let eventData;
103
- if (typeof name === 'object' && name !== null && 'name' in name && 'data' in name) {
104
- // If name is an object with a name property, use it directly
105
- eventName = name['name'];
106
- eventData = name['data'];
107
- }
108
- else {
109
- // Otherwise use the standard parameters
110
- eventName = name;
111
- eventData = data;
112
- }
113
- return call(EmitMethod, { name: eventName, data: eventData });
96
+ return call(EmitMethod, new WailsEvent(name, data));
114
97
  }
package/dist/index.js CHANGED
@@ -29,10 +29,11 @@ export { Application, Browser, Call, Clipboard, Dialogs, Events, Flags, Screens,
29
29
  * An internal utility consumed by the binding generator.
30
30
  *
31
31
  * @ignore
32
- * @internal
33
32
  */
34
33
  export { Create };
35
34
  export * from "./cancellable.js";
35
+ // Export transport interfaces and utilities
36
+ export { setTransport, getTransport, objectNames, clientId, } from "./runtime.js";
36
37
  // Notify backend
37
38
  window._wails.invoke = System.invoke;
38
39
  // Register platform handlers (internal API)
@@ -0,0 +1,64 @@
1
+ /*
2
+ _ __ _ __
3
+ | | / /___ _(_) /____
4
+ | | /| / / __ `/ / / ___/
5
+ | |/ |/ / /_/ / / (__ )
6
+ |__/|__/\__,_/_/_/____/
7
+ The electron alternative for Go
8
+ (c) Lea Anthony 2019-present
9
+ */
10
+ const TYPED_EVENTS_MODULE = "\0wailsio_runtime_events_typed";
11
+ /**
12
+ * A plugin that extends the wails runtime with locally generated code
13
+ * to provide support for typed custom events.
14
+ * With the plugin installed, vite will fail to build the project
15
+ * unless wails bindings have been generated first.
16
+ *
17
+ * @param {string} [bindingsRoot] - The root import path for generated bindings
18
+ */
19
+ export default function WailsTypedEvents(bindingsRoot) {
20
+ let bindingsId, runtimeId, eventsId;
21
+ return {
22
+ name: "wails-typed-events",
23
+ async buildStart() {
24
+ const bindingsPath = `${bindingsRoot}/github.com/wailsapp/wails/v3/internal/eventcreate`;
25
+ let resolution = await this.resolve(bindingsPath);
26
+ if (!resolution || resolution.external) {
27
+ this.error(`Event bindings module not found at import specifier '${bindingsPath}'. Please verify that the wails tool is up to date and the binding generator runs successfully. If you moved the bindings to a custom location, ensure you supplied the correct root path as the first argument to \`wailsTypedEventsPlugin\``);
28
+ return;
29
+ }
30
+ bindingsId = resolution.id;
31
+ resolution = await this.resolve("@wailsio/runtime");
32
+ if (!resolution || resolution.external) {
33
+ return;
34
+ }
35
+ runtimeId = resolution.id;
36
+ resolution = await this.resolve("./events.js", runtimeId);
37
+ if (!resolution || resolution.external) {
38
+ this.error("Could not resolve events module within @wailsio/runtime package. Please verify that the module is correctly installed and up to date.");
39
+ return;
40
+ }
41
+ eventsId = resolution.id;
42
+ },
43
+ resolveId: {
44
+ order: 'pre',
45
+ handler(id, importer) {
46
+ if (bindingsId !== null
47
+ && runtimeId !== null
48
+ && eventsId !== null
49
+ && importer === runtimeId
50
+ && id === "./events.js") {
51
+ return TYPED_EVENTS_MODULE;
52
+ }
53
+ return undefined;
54
+ }
55
+ },
56
+ load(id) {
57
+ if (id === TYPED_EVENTS_MODULE) {
58
+ return (`import ${JSON.stringify(bindingsId)};\n`
59
+ + `export * from ${JSON.stringify(eventsId)};`);
60
+ }
61
+ return undefined;
62
+ }
63
+ };
64
+ }
package/dist/runtime.js CHANGED
@@ -7,8 +7,10 @@
7
7
  The electron alternative for Go
8
8
  (c) Lea Anthony 2019-present
9
9
  */
10
- import { nanoid } from './nanoid.js';
10
+ import { nanoid } from "./nanoid.js";
11
11
  const runtimeURL = window.location.origin + "/wails/runtime";
12
+ // Re-export nanoid for custom transport implementations
13
+ export { nanoid };
12
14
  // Object Names
13
15
  export const objectNames = Object.freeze({
14
16
  Call: 0,
@@ -24,6 +26,39 @@ export const objectNames = Object.freeze({
24
26
  CancelCall: 10,
25
27
  });
26
28
  export let clientId = nanoid();
29
+ /**
30
+ * Custom transport implementation (can be set by user)
31
+ */
32
+ let customTransport = null;
33
+ /**
34
+ * Set a custom transport for all Wails runtime calls.
35
+ * This allows you to replace the default HTTP fetch transport with
36
+ * WebSockets, custom protocols, or any other mechanism.
37
+ *
38
+ * @param transport - Your custom transport implementation
39
+ *
40
+ * @example
41
+ * ```typescript
42
+ * import { setTransport } from '/wails/runtime.js';
43
+ *
44
+ * const wsTransport = {
45
+ * call: async (objectID, method, windowName, args) => {
46
+ * // Your WebSocket implementation
47
+ * }
48
+ * };
49
+ *
50
+ * setTransport(wsTransport);
51
+ * ```
52
+ */
53
+ export function setTransport(transport) {
54
+ customTransport = transport;
55
+ }
56
+ /**
57
+ * Get the current transport (useful for extending/wrapping)
58
+ */
59
+ export function getTransport() {
60
+ return customTransport;
61
+ }
27
62
  /**
28
63
  * Creates a new runtime caller with specified ID.
29
64
  *
@@ -38,19 +73,31 @@ export function newRuntimeCaller(object, windowName = '') {
38
73
  }
39
74
  async function runtimeCallWithID(objectID, method, windowName, args) {
40
75
  var _a, _b;
76
+ // Use custom transport if available
77
+ if (customTransport) {
78
+ return customTransport.call(objectID, method, windowName, args);
79
+ }
80
+ // Default HTTP fetch transport
41
81
  let url = new URL(runtimeURL);
42
- url.searchParams.append("object", objectID.toString());
43
- url.searchParams.append("method", method.toString());
44
- if (args) {
45
- url.searchParams.append("args", JSON.stringify(args));
82
+ let body = {
83
+ object: objectID,
84
+ method
85
+ };
86
+ if (args !== null && args !== undefined) {
87
+ body.args = args;
46
88
  }
47
89
  let headers = {
48
- ["x-wails-client-id"]: clientId
90
+ ["x-wails-client-id"]: clientId,
91
+ ["Content-Type"]: "application/json"
49
92
  };
50
93
  if (windowName) {
51
94
  headers["x-wails-window-name"] = windowName;
52
95
  }
53
- let response = await fetch(url, { headers });
96
+ let response = await fetch(url, {
97
+ method: 'POST',
98
+ headers,
99
+ body: JSON.stringify(body)
100
+ });
54
101
  if (!response.ok) {
55
102
  throw new Error(await response.text());
56
103
  }
package/dist/system.js CHANGED
@@ -11,6 +11,7 @@ import { newRuntimeCaller, objectNames } from "./runtime.js";
11
11
  const call = newRuntimeCaller(objectNames.System);
12
12
  const SystemIsDarkMode = 0;
13
13
  const SystemEnvironment = 1;
14
+ const SystemCapabilities = 2;
14
15
  const ApplicationFilesDroppedWithContext = 100; // New method ID for enriched drop event
15
16
  const _invoke = (function () {
16
17
  var _a, _b, _c, _d, _e;
@@ -43,13 +44,7 @@ export function IsDarkMode() {
43
44
  * @returns A promise that resolves to an object containing the capabilities.
44
45
  */
45
46
  export async function Capabilities() {
46
- let response = await fetch("/wails/capabilities");
47
- if (response.ok) {
48
- return response.json();
49
- }
50
- else {
51
- throw new Error("could not fetch capabilities: " + response.statusText);
52
- }
47
+ return call(SystemCapabilities);
53
48
  }
54
49
  /**
55
50
  * Retrieves environment details.
package/package.json CHANGED
@@ -1,12 +1,18 @@
1
1
  {
2
2
  "name": "@wailsio/runtime",
3
3
  "type": "module",
4
- "version": "3.0.0-alpha.72",
4
+ "version": "3.0.0-alpha.74",
5
5
  "description": "Wails Runtime",
6
6
  "types": "types/index.d.ts",
7
7
  "exports": {
8
- "types": "./types/index.d.ts",
9
- "import": "./dist/index.js"
8
+ ".": {
9
+ "types": "./types/index.d.ts",
10
+ "default": "./dist/index.js"
11
+ },
12
+ "./plugins/*": {
13
+ "types": "./types/plugins/*.d.ts",
14
+ "default": "./dist/plugins/*.js"
15
+ }
10
16
  },
11
17
  "repository": {
12
18
  "type": "git",
@@ -50,6 +56,7 @@
50
56
  "typedoc-plugin-mdn-links": "^4.0.13",
51
57
  "typedoc-plugin-missing-exports": "^3.1.0",
52
58
  "typescript": "^5.7.3",
59
+ "vite": "^5.2.0",
53
60
  "vitest": "^3.0.6"
54
61
  },
55
62
  "overrides": {
@@ -108,7 +108,6 @@ export interface CancellablePromiseWithResolvers<T> {
108
108
  * if so is the underlying implementation.
109
109
  */
110
110
  export declare class CancellablePromise<T> extends Promise<T> implements PromiseLike<T>, CancellablePromiseLike<T> {
111
- static [x: symbol]: PromiseConstructor;
112
111
  /**
113
112
  * Creates a new `CancellablePromise`.
114
113
  *
package/types/create.d.ts CHANGED
@@ -29,3 +29,8 @@ export declare function Nullable<T = any>(element: (source: any) => T): (source:
29
29
  * and returns an in-place creation function for a struct.
30
30
  */
31
31
  export declare function Struct(createField: Record<string, (source: any) => any>): <U extends Record<string, any> = any>(source: any) => U;
32
+ /**
33
+ * Maps known event names to creation functions for their data types.
34
+ * Will be monkey-patched by the binding generator.
35
+ */
36
+ export declare const Events: Record<string, (source: any) => any>;