electrobun 0.1.10 → 0.1.12

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.
@@ -46,11 +46,14 @@ const menuConfigWithDefaults = (
46
46
  if (item.type === "divider" || item.type === "separator") {
47
47
  return { type: "divider" };
48
48
  } else {
49
+ // Use shared serialization method
50
+ const actionWithDataId = ffi.internal.serializeMenuAction(item.action || "", item.data);
51
+
49
52
  return {
50
53
  label: item.label || roleLabelMap[item.role] || "",
51
54
  type: item.type || "normal",
52
55
  // application menus can either have an action or a role. not both.
53
- ...(item.role ? { role: item.role } : { action: item.action || "" }),
56
+ ...(item.role ? { role: item.role } : { action: actionWithDataId }),
54
57
  // default enabled to true unless explicitly set to false
55
58
  enabled: item.enabled === false ? false : true,
56
59
  checked: Boolean(item.checked),
@@ -48,11 +48,14 @@ const menuConfigWithDefaults = (
48
48
  if (item.type === "divider" || item.type === "separator") {
49
49
  return { type: "divider" };
50
50
  } else {
51
+ // Use shared serialization method
52
+ const actionWithDataId = ffi.internal.serializeMenuAction(item.action || "", item.data);
53
+
51
54
  return {
52
55
  label: item.label || roleLabelMap[item.role] || "",
53
56
  type: item.type || "normal",
54
57
  // application menus can either have an action or a role. not both.
55
- ...(item.role ? { role: item.role } : { action: item.action || "" }),
58
+ ...(item.role ? { role: item.role } : { action: actionWithDataId }),
56
59
  // default enabled to true unless explicitly set to false
57
60
  enabled: item.enabled === false ? false : true,
58
61
  checked: Boolean(item.checked),
@@ -112,10 +112,13 @@ const menuConfigWithDefaults = (
112
112
  if (item.type === "divider" || item.type === "separator") {
113
113
  return { type: "divider" };
114
114
  } else {
115
+ // Use shared serialization method
116
+ const actionWithDataId = ffi.internal.serializeMenuAction(item.action || "", item.data);
117
+
115
118
  return {
116
119
  label: item.label || "",
117
120
  type: item.type || "normal",
118
- action: item.action || "",
121
+ action: actionWithDataId,
119
122
  // default enabled to true unless explicitly set to false
120
123
  enabled: item.enabled === false ? false : true,
121
124
  checked: Boolean(item.checked),
@@ -7,7 +7,50 @@ import { BrowserView } from "../core/BrowserView";
7
7
  import { Updater } from "../core/Updater";
8
8
  import { Tray } from "../core/Tray";
9
9
 
10
+ // Menu data reference system to avoid serialization overhead
11
+ const menuDataRegistry = new Map<string, any>();
12
+ let menuDataCounter = 0;
13
+
14
+ function storeMenuData(data: any): string {
15
+ const id = `menuData_${++menuDataCounter}`;
16
+ menuDataRegistry.set(id, data);
17
+ return id;
18
+ }
19
+
20
+ function getMenuData(id: string): any {
21
+ return menuDataRegistry.get(id);
22
+ }
10
23
 
24
+ function clearMenuData(id: string): void {
25
+ menuDataRegistry.delete(id);
26
+ }
27
+
28
+ // Shared methods for EB delimiter serialization/deserialization
29
+ const ELECTROBUN_DELIMITER = '|EB|';
30
+
31
+ function serializeMenuAction(action: string, data: any): string {
32
+ const dataId = storeMenuData(data);
33
+ return `${ELECTROBUN_DELIMITER}${dataId}|${action}`;
34
+ }
35
+
36
+ function deserializeMenuAction(encodedAction: string): { action: string; data: any } {
37
+ let actualAction = encodedAction;
38
+ let data = undefined;
39
+
40
+ if (encodedAction.startsWith(ELECTROBUN_DELIMITER)) {
41
+ const parts = encodedAction.split('|');
42
+ if (parts.length >= 4) { // ['', 'EB', 'dataId', 'actualAction', ...]
43
+ const dataId = parts[2];
44
+ actualAction = parts.slice(3).join('|'); // Rejoin in case action contains |
45
+ data = getMenuData(dataId);
46
+
47
+ // Clean up data from registry after use
48
+ clearMenuData(dataId);
49
+ }
50
+ }
51
+
52
+ return { action: actualAction, data };
53
+ }
11
54
 
12
55
  // todo: set up FFI, this is already in the webworker.
13
56
 
@@ -765,6 +808,14 @@ export const ffi = {
765
808
  // );
766
809
  // },
767
810
 
811
+ },
812
+ // Internal functions for menu data management
813
+ internal: {
814
+ storeMenuData,
815
+ getMenuData,
816
+ clearMenuData,
817
+ serializeMenuAction,
818
+ deserializeMenuAction,
768
819
  }
769
820
  }
770
821
 
@@ -1103,9 +1154,14 @@ const trayItemHandler = new JSCallback((id, action) => {
1103
1154
  // Note: Some invisible character that doesn't appear in .length
1104
1155
  // is causing issues
1105
1156
  const actionString = (new CString(action).toString() || "").trim();
1157
+
1158
+ // Use shared deserialization method
1159
+ const { action: actualAction, data } = deserializeMenuAction(actionString);
1160
+
1106
1161
  const event = electrobunEventEmitter.events.tray.trayClicked({
1107
1162
  id,
1108
- action: actionString,
1163
+ action: actualAction,
1164
+ data, // Always include data property (undefined if no data)
1109
1165
  });
1110
1166
 
1111
1167
  let result;
@@ -1120,13 +1176,19 @@ const trayItemHandler = new JSCallback((id, action) => {
1120
1176
 
1121
1177
 
1122
1178
  const applicationMenuHandler = new JSCallback((id, action) => {
1179
+ const actionString = new CString(action).toString();
1180
+
1181
+ // Use shared deserialization method
1182
+ const { action: actualAction, data } = deserializeMenuAction(actionString);
1183
+
1123
1184
  const event = electrobunEventEmitter.events.app.applicationMenuClicked({
1124
1185
  id,
1125
- action: new CString(action),
1186
+ action: actualAction,
1187
+ data, // Always include data property (undefined if no data)
1126
1188
  });
1127
1189
 
1128
1190
  // global event
1129
- electrobunEventEmitter.emitEvent(event);
1191
+ electrobunEventEmitter.emitEvent(event);
1130
1192
  }, {
1131
1193
  args: [FFIType.u32, FFIType.cstring],
1132
1194
  returns: FFIType.void,
@@ -1134,8 +1196,14 @@ const applicationMenuHandler = new JSCallback((id, action) => {
1134
1196
  })
1135
1197
 
1136
1198
  const contextMenuHandler = new JSCallback((id, action) => {
1199
+ const actionString = new CString(action).toString();
1200
+
1201
+ // Use shared deserialization method
1202
+ const { action: actualAction, data } = deserializeMenuAction(actionString);
1203
+
1137
1204
  const event = electrobunEventEmitter.events.app.contextMenuClicked({
1138
- action: new CString(action),
1205
+ action: actualAction,
1206
+ data, // Always include data property (undefined if no data)
1139
1207
  });
1140
1208
 
1141
1209
  electrobunEventEmitter.emitEvent(event);
@@ -1329,7 +1397,9 @@ export const internalRpcHandlers = {
1329
1397
  webviewEvent: (params) => {
1330
1398
  console.log('-----------------+webviewEvent', params)
1331
1399
  },
1332
- }
1400
+ },
1401
+
1402
+
1333
1403
  };
1334
1404
 
1335
1405
  // todo: consider renaming to TrayMenuItemConfig
@@ -1340,6 +1410,7 @@ export type MenuItemConfig =
1340
1410
  label: string;
1341
1411
  tooltip?: string;
1342
1412
  action?: string;
1413
+ data?: any;
1343
1414
  submenu?: Array<MenuItemConfig>;
1344
1415
  enabled?: boolean;
1345
1416
  checked?: boolean;
@@ -1353,6 +1424,7 @@ export type ApplicationMenuItemConfig =
1353
1424
  label: string;
1354
1425
  tooltip?: string;
1355
1426
  action?: string;
1427
+ data?: any;
1356
1428
  submenu?: Array<ApplicationMenuItemConfig>;
1357
1429
  enabled?: boolean;
1358
1430
  checked?: boolean;
@@ -1364,6 +1436,7 @@ export type ApplicationMenuItemConfig =
1364
1436
  label?: string;
1365
1437
  tooltip?: string;
1366
1438
  role?: string;
1439
+ data?: any;
1367
1440
  submenu?: Array<ApplicationMenuItemConfig>;
1368
1441
  enabled?: boolean;
1369
1442
  checked?: boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "electrobun",
3
- "version": "0.1.10",
3
+ "version": "0.1.12",
4
4
  "description": "Build ultra fast, tiny, and cross-platform desktop apps with Typescript.",
5
5
  "license": "MIT",
6
6
  "author": "Blackboard Technologies Inc.",