@virid/main 0.3.1 → 0.3.3
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 +57 -47
- package/README.zh.md +37 -36
- package/dist/index.cjs +2 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +18 -15
- package/dist/index.d.ts +18 -15
- package/dist/index.js +2 -3
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -15,11 +15,10 @@ Conversely, messages sent from a rendering process to the main process are abstr
|
|
|
15
15
|
## 🔌Enable plugins
|
|
16
16
|
|
|
17
17
|
```ts
|
|
18
|
-
import { createVirid } from
|
|
19
|
-
import { MainPlugin } from
|
|
20
|
-
import { app } from
|
|
21
|
-
const virid = createVirid()
|
|
22
|
-
.use(MainPlugin, { electronApp: app })
|
|
18
|
+
import { createVirid } from "@virid/core";
|
|
19
|
+
import { MainPlugin } from "@virid/main";
|
|
20
|
+
import { app } from "electron";
|
|
21
|
+
const virid = createVirid().use(MainPlugin, { electronApp: app });
|
|
23
22
|
```
|
|
24
23
|
|
|
25
24
|
## 🛠️ @virid/main Core API Overview
|
|
@@ -29,27 +28,27 @@ const virid = createVirid()
|
|
|
29
28
|
- **Function**: A specialized message base class designed for inheritance. All messages inheriting from `ToRendererMessage` will be dispatched to the rendering process.
|
|
30
29
|
- **Logic**: This message type requires two specific metadata tags:
|
|
31
30
|
- `__virid_target`: Specifies the destination (e.g., a specific `windowId`).
|
|
32
|
-
- `
|
|
31
|
+
- `__virid_message_type`: Defines the message type it should be restored to upon reaching the rendering process.
|
|
33
32
|
|
|
34
33
|
- Example:
|
|
35
34
|
|
|
36
35
|
**In the Main Process:**
|
|
37
36
|
|
|
38
37
|
```ts
|
|
39
|
-
import { ToRendererMessage } from
|
|
38
|
+
import { ToRendererMessage } from "@virid/main";
|
|
40
39
|
|
|
41
40
|
/**
|
|
42
|
-
* - __virid_target = 'renderer': Indicates the message is bound for the rendering process
|
|
41
|
+
* - __virid_target = 'renderer': Indicates the message is bound for the rendering process
|
|
43
42
|
* with the windowId 'renderer'.
|
|
44
|
-
* -
|
|
43
|
+
* - __virid_message_type = 'file-dialog': Describes the type this message will transform
|
|
45
44
|
* into once it arrives in the rendering process.
|
|
46
45
|
*/
|
|
47
46
|
export class RenderDialogMessage extends ToRendererMessage {
|
|
48
|
-
__virid_target: string =
|
|
49
|
-
|
|
50
|
-
|
|
47
|
+
__virid_target: string = "renderer";
|
|
48
|
+
__virid_message_type: string = "file-dialog";
|
|
49
|
+
|
|
51
50
|
constructor(public path: string) {
|
|
52
|
-
super()
|
|
51
|
+
super();
|
|
53
52
|
}
|
|
54
53
|
}
|
|
55
54
|
```
|
|
@@ -59,17 +58,17 @@ In the **Rendering Process**, you can use the `@FromIpc` decorator in conjunctio
|
|
|
59
58
|
**In the Rendering Process:**
|
|
60
59
|
|
|
61
60
|
```ts
|
|
62
|
-
import { FromIpc, FromMainMessage } from
|
|
61
|
+
import { FromIpc, FromMainMessage } from "@virid/renderer";
|
|
63
62
|
|
|
64
63
|
/**
|
|
65
|
-
* @FromIpc('file-dialog') indicates that when the Main Process sends a ToRendererMessage
|
|
66
|
-
* where
|
|
64
|
+
* @FromIpc('file-dialog') indicates that when the Main Process sends a ToRendererMessage
|
|
65
|
+
* where __virid_message_type is 'file-dialog', this message will be automatically
|
|
67
66
|
* delivered to the Virid dispatcher to trigger the corresponding rendering process System.
|
|
68
67
|
*/
|
|
69
|
-
@FromIpc(
|
|
68
|
+
@FromIpc("file-dialog")
|
|
70
69
|
class ChooseBgImageMessage extends FromMainMessage {
|
|
71
70
|
constructor(public path: string) {
|
|
72
|
-
super()
|
|
71
|
+
super();
|
|
73
72
|
}
|
|
74
73
|
}
|
|
75
74
|
```
|
|
@@ -77,38 +76,44 @@ class ChooseBgImageMessage extends FromMainMessage {
|
|
|
77
76
|
### FromRenderMessage / @FromRenderer()
|
|
78
77
|
|
|
79
78
|
- **Function**: A specialized message base class designed for inheritance. All messages inheriting from `FromRenderMessage` will be automatically converted and dispatched to the **Virid Dispatcher** in the Main Process when sent from a Rendering Process.
|
|
80
|
-
- **Logic**: The `@FromRenderer()` decorator accepts a string-based ID. This ID must match the `
|
|
79
|
+
- **Logic**: The `@FromRenderer()` decorator accepts a string-based ID. This ID must match the `__virid_message_type` of the `ToMainMessage` dispatched from the Rendering Process.
|
|
81
80
|
|
|
82
81
|
#### Example:
|
|
83
82
|
|
|
84
83
|
**In the Main Process:**
|
|
85
84
|
|
|
86
85
|
```ts
|
|
87
|
-
import {
|
|
86
|
+
import {
|
|
87
|
+
FromRenderer,
|
|
88
|
+
FromRenderMessage,
|
|
89
|
+
ToRendererMessage,
|
|
90
|
+
} from "@virid/main";
|
|
88
91
|
|
|
89
92
|
// Message to be sent to the Rendering Process
|
|
90
93
|
export class RenderDialogMessage extends ToRendererMessage {
|
|
91
|
-
__virid_target: string =
|
|
92
|
-
|
|
94
|
+
__virid_target: string = "renderer";
|
|
95
|
+
__virid_message_type: string = "file-dialog";
|
|
93
96
|
constructor(public path: string) {
|
|
94
|
-
super()
|
|
97
|
+
super();
|
|
95
98
|
}
|
|
96
99
|
}
|
|
97
100
|
|
|
98
101
|
/**
|
|
99
|
-
* Converts incoming messages from the Rendering Process with
|
|
100
|
-
*
|
|
102
|
+
* Converts incoming messages from the Rendering Process with
|
|
103
|
+
* __virid_message_type: 'open-dialog' into the Main Process's OpenDialogMessage.
|
|
101
104
|
*/
|
|
102
|
-
@FromRenderer(
|
|
105
|
+
@FromRenderer("open-dialog")
|
|
103
106
|
export class OpenDialogMessage extends FromRenderMessage {
|
|
104
107
|
constructor(
|
|
105
108
|
public options: {
|
|
106
|
-
title?: string
|
|
107
|
-
filters?: Array<{ name: string; extensions: string[] }
|
|
108
|
-
properties?: Array<
|
|
109
|
-
|
|
109
|
+
title?: string;
|
|
110
|
+
filters?: Array<{ name: string; extensions: string[] }>;
|
|
111
|
+
properties?: Array<
|
|
112
|
+
"openFile" | "openDirectory" | "multiSelections" | "showHiddenFiles"
|
|
113
|
+
>;
|
|
114
|
+
},
|
|
110
115
|
) {
|
|
111
|
-
super()
|
|
116
|
+
super();
|
|
112
117
|
}
|
|
113
118
|
}
|
|
114
119
|
|
|
@@ -116,14 +121,17 @@ export class WindowSystem {
|
|
|
116
121
|
@System()
|
|
117
122
|
async openDialog(@Message(OpenDialogMessage) message: OpenDialogMessage) {
|
|
118
123
|
// Invoke native Electron dialog
|
|
119
|
-
const result = await dialog.showOpenDialog(
|
|
120
|
-
|
|
124
|
+
const result = await dialog.showOpenDialog(
|
|
125
|
+
message.senderWindow,
|
|
126
|
+
message.options,
|
|
127
|
+
);
|
|
128
|
+
|
|
121
129
|
// If the user did not cancel and selected a file
|
|
122
130
|
if (!result.canceled && result.filePaths.length > 0) {
|
|
123
|
-
const selectedPath = result.filePaths[0]
|
|
124
|
-
return new RenderDialogMessage(selectedPath)
|
|
131
|
+
const selectedPath = result.filePaths[0];
|
|
132
|
+
return new RenderDialogMessage(selectedPath);
|
|
125
133
|
}
|
|
126
|
-
return
|
|
134
|
+
return;
|
|
127
135
|
}
|
|
128
136
|
}
|
|
129
137
|
```
|
|
@@ -133,28 +141,30 @@ In the **Rendering Process**, you can use `@FromIpc` in conjunction with `ToMain
|
|
|
133
141
|
**In the Rendering Process:**
|
|
134
142
|
|
|
135
143
|
```ts
|
|
136
|
-
import { ToMainMessage, FromIpc, FromMainMessage } from
|
|
144
|
+
import { ToMainMessage, FromIpc, FromMainMessage } from "@virid/renderer";
|
|
137
145
|
|
|
138
146
|
// Handles the incoming file selection result
|
|
139
|
-
@FromIpc(
|
|
147
|
+
@FromIpc("file-dialog")
|
|
140
148
|
class ChooseBgImageMessage extends FromMainMessage {
|
|
141
149
|
constructor(public path: string) {
|
|
142
|
-
super()
|
|
150
|
+
super();
|
|
143
151
|
}
|
|
144
152
|
}
|
|
145
153
|
|
|
146
154
|
// Initiates the request to open a dialog
|
|
147
155
|
class OpenDialogMessage extends ToMainMessage {
|
|
148
|
-
__virid_target: string =
|
|
149
|
-
|
|
156
|
+
__virid_target: string = "main";
|
|
157
|
+
__virid_message_type: string = "open-dialog";
|
|
150
158
|
constructor(
|
|
151
159
|
public options: {
|
|
152
|
-
title?: string
|
|
153
|
-
filters?: Array<{ name: string; extensions: string[] }
|
|
154
|
-
properties?: Array<
|
|
155
|
-
|
|
160
|
+
title?: string;
|
|
161
|
+
filters?: Array<{ name: string; extensions: string[] }>;
|
|
162
|
+
properties?: Array<
|
|
163
|
+
"openFile" | "openDirectory" | "multiSelections" | "showHiddenFiles"
|
|
164
|
+
>;
|
|
165
|
+
},
|
|
156
166
|
) {
|
|
157
|
-
super()
|
|
167
|
+
super();
|
|
158
168
|
}
|
|
159
169
|
}
|
|
160
|
-
```
|
|
170
|
+
```
|
package/README.zh.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @virid/main
|
|
2
2
|
|
|
3
3
|
`@virid/main` 是electron应用的主适配器,提供`ToRendererMessage`和`FromRendererMessage`的自动路由功能与接受渲染进程报道功能。
|
|
4
4
|
|
|
@@ -8,16 +8,15 @@
|
|
|
8
8
|
|
|
9
9
|
- **路由自动注册**:渲染进程窗口开启后,自动向主进程注册自身,以后所有的消息都将携带自身的窗口信息。
|
|
10
10
|
- **类型恢复**:消息在通过IPC通道后,恢复成真正的Message类重新进入`@virid/core`并被调度器识别并分发。实现不同进程的位置无关性。
|
|
11
|
-
- **消息定向与广播**:可以通过其他渲染进程的ID
|
|
11
|
+
- **消息定向与广播**:可以通过其他渲染进程的ID来实现定向通信,或者使用“\*”来广播消息。
|
|
12
12
|
|
|
13
13
|
## 🔌启用插件
|
|
14
14
|
|
|
15
15
|
```ts
|
|
16
|
-
import { createVirid } from
|
|
17
|
-
import { MainPlugin } from
|
|
18
|
-
import { app } from
|
|
19
|
-
const virid = createVirid()
|
|
20
|
-
.use(MainPlugin, { electronApp: app })
|
|
16
|
+
import { createVirid } from "@virid/core";
|
|
17
|
+
import { MainPlugin } from "@virid/main";
|
|
18
|
+
import { app } from "electron";
|
|
19
|
+
const virid = createVirid().use(MainPlugin, { electronApp: app });
|
|
21
20
|
```
|
|
22
21
|
|
|
23
22
|
## 🛠️ @virid/main 核心 API 概览
|
|
@@ -25,19 +24,19 @@ const virid = createVirid()
|
|
|
25
24
|
### `ToRendererMessage`
|
|
26
25
|
|
|
27
26
|
- **功能**:一个特殊的消息基类,可被继承。所有继承自`ToRendererMessage`的Message将被发往渲染进程
|
|
28
|
-
- **逻辑**:该消息类型需要两个特殊标记,`__virid_target`标记了目的地,`
|
|
27
|
+
- **逻辑**:该消息类型需要两个特殊标记,`__virid_target`标记了目的地,`__virid_message_type`标记了在目的地应该被还原为的Message类型
|
|
29
28
|
- **示例**:
|
|
30
29
|
|
|
31
30
|
```ts
|
|
32
31
|
//在主进程
|
|
33
|
-
import { ToRendererMessage } from
|
|
32
|
+
import { ToRendererMessage } from "@virid/main";
|
|
34
33
|
// __virid_target=‘renderer’,说明消息需要发往windowId为renderer的渲染进程
|
|
35
|
-
//
|
|
34
|
+
// __virid_message_type: string = 'file-dialog',描述了在渲染进程,该消息将会重新变为的类型
|
|
36
35
|
export class RenderDialogMessage extends ToRendererMessage {
|
|
37
|
-
__virid_target: string =
|
|
38
|
-
|
|
36
|
+
__virid_target: string = "renderer";
|
|
37
|
+
__virid_message_type: string = "file-dialog";
|
|
39
38
|
constructor(public path: string) {
|
|
40
|
-
super()
|
|
39
|
+
super();
|
|
41
40
|
}
|
|
42
41
|
}
|
|
43
42
|
```
|
|
@@ -46,15 +45,15 @@ export class RenderDialogMessage extends ToRendererMessage {
|
|
|
46
45
|
|
|
47
46
|
```ts
|
|
48
47
|
//在渲染进程
|
|
49
|
-
import { FromIpc, FromMainMessage } from
|
|
48
|
+
import { FromIpc, FromMainMessage } from "@virid/main";
|
|
50
49
|
//@FromIpc('file-dialog')表明当主进程发送一个ToRenderMessage,而且
|
|
51
50
|
// __virid_target: string = 'renderer'
|
|
52
|
-
//
|
|
51
|
+
// __virid_message_type: string = 'file-dialog'
|
|
53
52
|
// 时,这个消息将被自动投递到virid调度中心触发相应的渲染进程System
|
|
54
|
-
@FromIpc(
|
|
53
|
+
@FromIpc("file-dialog")
|
|
55
54
|
class ChooseBgImageMessage extends FromMainMessage {
|
|
56
55
|
constructor(public path: string) {
|
|
57
|
-
super()
|
|
56
|
+
super();
|
|
58
57
|
}
|
|
59
58
|
}
|
|
60
59
|
```
|
|
@@ -67,26 +66,28 @@ class ChooseBgImageMessage extends FromMainMessage {
|
|
|
67
66
|
|
|
68
67
|
```ts
|
|
69
68
|
//在主进程
|
|
70
|
-
import { FromRenderer, FromRenderMessage } from
|
|
69
|
+
import { FromRenderer, FromRenderMessage } from "@virid/renderer";
|
|
71
70
|
// 发往渲染进程的消息
|
|
72
71
|
export class RenderDialogMessage extends ToRendererMessage {
|
|
73
|
-
__virid_target: string =
|
|
74
|
-
|
|
72
|
+
__virid_target: string = "renderer";
|
|
73
|
+
__virid_message_type: string = "file-dialog";
|
|
75
74
|
constructor(public path: string) {
|
|
76
|
-
super()
|
|
75
|
+
super();
|
|
77
76
|
}
|
|
78
77
|
}
|
|
79
|
-
// 将来自渲染进程且
|
|
80
|
-
@FromRenderer(
|
|
78
|
+
// 将来自渲染进程且 __virid_message_type: string = 'file-dialog'的消息转换成主进程的OpenDialogMessage
|
|
79
|
+
@FromRenderer("open-dialog")
|
|
81
80
|
export class OpenDialogMessage extends FromRenderMessage {
|
|
82
81
|
constructor(
|
|
83
82
|
public options: {
|
|
84
|
-
title?: string
|
|
85
|
-
filters?: Array<{ name: string; extensions: string[] }
|
|
86
|
-
properties?: Array<
|
|
87
|
-
|
|
83
|
+
title?: string;
|
|
84
|
+
filters?: Array<{ name: string; extensions: string[] }>;
|
|
85
|
+
properties?: Array<
|
|
86
|
+
"openFile" | "openDirectory" | "multiSelections" | "showHiddenFiles"
|
|
87
|
+
>;
|
|
88
|
+
},
|
|
88
89
|
) {
|
|
89
|
-
super()
|
|
90
|
+
super();
|
|
90
91
|
}
|
|
91
92
|
}
|
|
92
93
|
|
|
@@ -94,13 +95,16 @@ export class WindowSystem {
|
|
|
94
95
|
@System()
|
|
95
96
|
async openDialog(@Message(OpenDialogMessage) message: OpenDialogMessage) {
|
|
96
97
|
// 调用原生对话框
|
|
97
|
-
const result = await dialog.showOpenDialog(
|
|
98
|
+
const result = await dialog.showOpenDialog(
|
|
99
|
+
message.senderWindow,
|
|
100
|
+
message.options,
|
|
101
|
+
);
|
|
98
102
|
// 如果用户没有取消,并且确实选择了文件
|
|
99
103
|
if (!result.canceled && result.filePaths.length > 0) {
|
|
100
|
-
const selectedPath = result.filePaths[0]
|
|
101
|
-
return new RenderDialogMessage(selectedPath)
|
|
104
|
+
const selectedPath = result.filePaths[0];
|
|
105
|
+
return new RenderDialogMessage(selectedPath);
|
|
102
106
|
}
|
|
103
|
-
return
|
|
107
|
+
return;
|
|
104
108
|
}
|
|
105
109
|
}
|
|
106
110
|
```
|
|
@@ -120,7 +124,7 @@ class ChooseBgImageMessage extends FromMainMessage {
|
|
|
120
124
|
//打开文件选择框
|
|
121
125
|
class OpenDialogMessage extends ToMainMessage {
|
|
122
126
|
__virid_target: string = 'main'
|
|
123
|
-
|
|
127
|
+
__virid_message_type: string = 'open-dialog'
|
|
124
128
|
constructor(
|
|
125
129
|
public options: {
|
|
126
130
|
title?: string
|
|
@@ -133,6 +137,3 @@ class OpenDialogMessage extends ToMainMessage {
|
|
|
133
137
|
}
|
|
134
138
|
|
|
135
139
|
```
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
package/dist/index.cjs
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @virid/main v0.3.
|
|
2
|
+
* @virid/main v0.3.3
|
|
3
3
|
* Electron main process adapter for Virid, responsible for sending, receiving, and broadcasting rendering process messages
|
|
4
4
|
*/
|
|
5
|
-
var
|
|
6
|
-
electronApp:${e?.electronApp}.`)),v.ipcMain.on(O,(i,t)=>{let{__virid_target:n,__virid_source:o,__virid_messageType:a}=t;if(!n||!o||!a){p.MessageWriter.error(new Error(`[Virid Main] Incomplete Message: The message is incomplete and requires __virid_target${n}, __virid_source${o}, __virid_messageType${a}`));return}if(a==="VIRID_INTERNAL_REGISTER"){let d=v.BrowserWindow.fromWebContents(i.sender);if(!d){p.MessageWriter.error(new Error("[Virid Main] unknown Window: Unable to find the window corresponding to event.sender"));return}if(_.has(o)){p.MessageWriter.error(new Error(`[Virid Main] Duplicate Registration: This ID has already been registered: ${o}`));return}_.set(o,d),d.once("closed",()=>{_.delete(o),p.MessageWriter.info(`[Virid Main] Window unregistered: ${o}`)}),p.MessageWriter.info(`[Virid Main] Window registered: ${o}`);return}T(t)}),r.useMiddleware(R)}s(V,"activateApp");var A=class A{constructor(){c(this,"name","@virid/main")}install(e,i){V(e,i)}};s(A,"MainPlugin");var y=A;0&&(module.exports={FromRenderer,FromRendererMessage,MainPlugin,ROUTER_MAP,ToRendererMessage,VIRID_CHANNEL,middleWare,processMessage});
|
|
5
|
+
var u=Object.defineProperty;var A=Object.getOwnPropertyDescriptor;var y=Object.getOwnPropertyNames;var V=Object.prototype.hasOwnProperty;var D=(s,e,r)=>e in s?u(s,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):s[e]=r;var p=(s,e)=>u(s,"name",{value:e,configurable:!0});var T=(s,e)=>{for(var r in e)u(s,r,{get:e[r],enumerable:!0})},W=(s,e,r,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of y(e))!V.call(s,t)&&t!==r&&u(s,t,{get:()=>e[t],enumerable:!(i=A(e,t))||i.enumerable});return s};var b=s=>W(u({},"__esModule",{value:!0}),s);var d=(s,e,r)=>D(s,typeof e!="symbol"?e+"":e,r);var N={};T(N,{FromRenderer:()=>x,FromRendererMessage:()=>M,MainPlugin:()=>E,ToRendererMessage:()=>m});module.exports=b(N);var a=require("@virid/core"),w=require("electron");var v=require("@virid/core");var h=class h extends v.EventMessage{constructor(){super(...arguments);d(this,"__virid_source","unknown");d(this,"__virid_target","unknown");d(this,"__virid_message_type","unknown");d(this,"senderWindow",null)}};p(h,"FromRendererMessage");var M=h,g=class g extends v.EventMessage{};p(g,"ToRendererMessage"),d(g,"__virid_source","main");var m=g;var I=require("@virid/core"),f={...I.VIRID_METADATA,FROMRENDERER:"virid:main:fromrenderer"};function x(s){return function(e){Reflect.defineMetadata(f.FROMRENDERER,s,e)}}p(x,"FromRenderer");var l="VIRID_INTERNAL_BUS",R=class R{constructor(){d(this,"name","@virid/main");d(this,"message_map",new Map);d(this,"route_map",new Map)}install(e,r){if(!r?.electronApp){a.MessageWriter.error(new Error(`[Virid Main] Missing Initialization Parameters: electronApp:${r?.electronApp}.`));return}w.ipcMain.on(l,(i,t)=>{let{__virid_target:_,__virid_source:n,__virid_message_type:o}=t;if(!_||!n||!o){a.MessageWriter.error(new Error(`[Virid Main] Incomplete Message: The message is incomplete and requires __virid_target${_}, __virid_source${n}, __virid_message_type${o}`));return}if(o==="VIRID_INTERNAL_REGISTER"){let c=w.BrowserWindow.fromWebContents(i.sender);if(!c){a.MessageWriter.error(new Error("[Virid Main] unknown Window: Unable to find the window corresponding to event.sender"));return}if(this.route_map.has(n)){a.MessageWriter.error(new Error(`[Virid Main] Duplicate Registration: This ID has already been registered: ${n}`));return}this.route_map.set(n,c),c.once("closed",()=>{this.route_map.delete(n),a.MessageWriter.info(`[Virid Main] Window unregistered: ${n}`)}),a.MessageWriter.info(`[Virid Main] Window registered: ${n}`);return}this.processMessage(t)}),e.useMiddleware(this.middleWare.bind(this))}bindRoute(e){let r=Reflect.getMetadata(f.FROMRENDERER,e);this.message_map.has(r)&&a.MessageWriter.error(new Error(`[Virid Main] Duplicate IpcMessage: Registration for route: ${r}, message class: ${e}`)),this.message_map.set(r,e)}middleWare(e,r){if(e instanceof m){let{__virid_target:i,__virid_message_type:t,..._}=e;if(i=="main"){a.MessageWriter.warn(`[Virid Main] Prohibit Sending To Oneself: ${i} is not allowed in ToRendererMessage.`);return}let n={__virid_source:m.__virid_source,__virid_target:i,__virid_message_type:t,payload:_},o=i==="*"||i==="all"?Array.from(this.route_map.values()):[this.route_map.get(i)].filter(Boolean);if(o.length>0)o.forEach(c=>c.webContents.send(l,n));else{a.MessageWriter.error(new Error(`[Virid Main] No Window Found: Message target ${i} cannot be found.`));return}}else r()}receiveMessages(e){let{__virid_source:r,__virid_message_type:i,__virid_target:t,payload:_}=e;if(!this.message_map.has(i)){a.MessageWriter.error(new Error(`[Virid Main] unknown Message Type: Cannot find ${i} in the main process registry.`));return}let n=this.message_map.get(i),o=new n;_&&Object.assign(o,_),o.__virid_source=r,o.__virid_target=t,o.__virid_message_type=i;let c=this.route_map.get(r);c&&(o.senderWindow=c),a.MessageWriter.write(o)}transmitMessages(e){let{__virid_source:r,__virid_message_type:i,__virid_target:t,payload:_}=e,n=this.route_map.get(t);if(!n){a.MessageWriter.error(new Error(`[Virid Main] unknown Window: Cannot find ${t} in the windows registry.`));return}n.webContents.send(l,{__virid_source:r,__virid_message_type:i,__virid_target:t,payload:_})}broadcastMessage(e){let{__virid_source:r,__virid_message_type:i,__virid_target:t,payload:_}=e;this.route_map.forEach(n=>{n.webContents.send(l,{__virid_source:r,__virid_message_type:i,__virid_target:t,payload:_})})}processMessage(e){let{__virid_target:r,__virid_source:i,__virid_message_type:t}=e;return r==="main"?this.receiveMessages(e):r==="all"||r==="*"?this.broadcastMessage(e):this.transmitMessages(e)}};p(R,"MainPlugin");var E=R;0&&(module.exports={FromRenderer,FromRendererMessage,MainPlugin,ToRendererMessage});
|
|
7
6
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/main/message.ts","../src/main/middleware.ts","../src/main/router.ts","../src/app.ts"],"sourcesContent":["/*\n * Copyright (c) 2026-present Ailrid\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * Description: Electron main process adapter for Virid, responsible for sending, receiving, and broadcasting rendering process messages.\n */\nexport * from \"./main\";\nexport * from \"./interfaces\";\nimport { ViridPlugin, type ViridApp } from \"@virid/core\";\nimport { type PluginOption } from \"./interfaces\";\nimport { activateApp } from \"./app\";\nexport class MainPlugin implements ViridPlugin<PluginOption> {\n name = \"@virid/main\";\n install(app: ViridApp, options: PluginOption) {\n activateApp(app, options);\n }\n}\n","/*\n * Copyright (c) 2026-present Ailrid.\n * Licensed under the Apache License, Version 2.0.\n * Project: Virid Main\n */\nimport { EventMessage } from \"@virid/core\";\nexport { type SystemContext } from \"@virid/core\";\n/**\n * Message from rendering process\n */\nexport abstract class FromRendererMessage extends EventMessage {\n /**\n * Where am I from?\n */\n public __virid_source: string = \"unknown\";\n /**Where is my destination?\n *'main ': Sent to the main process for processing\n *'all': Broadcast to all windows (relayed through the main process)\n *String: Specify the ID of a window (windowId)\n */\n public __virid_target: string = \"unknown\";\n\n //What message should I turn into at the destination?\n public __virid_messageType: string = \"unknown\";\n public senderWindow: Electron.BrowserWindow = null as any;\n}\n\n/**\n *Message to be sent to the rendering process\n */\nexport abstract class ToRendererMessage extends EventMessage {\n /**\n * Where am I from?\n */\n public static __virid_source = \"main\";\n /**Where is my destination?\n *'all': Broadcast to all windows (relayed through the main process)\n *String: Specify the ID of a window (windowId)\n */\n public abstract __virid_target: string;\n /**\n *What message should I turn into at the destination?\n */\n public abstract __virid_messageType: string;\n}\n","/*\n * Copyright (c) 2026-present Ailrid.\n * Licensed under the Apache License, Version 2.0.\n * Project: Virid Main\n */\nimport { type Middleware, MessageWriter } from \"@virid/core\";\nimport { ToRendererMessage } from \"./message\";\nimport { ROUTER_MAP, VIRID_CHANNEL } from \"./router\";\nexport const middleWare: Middleware = (message, next) => {\n //If the message is inherited from MainRequestMessage, intercept and send it to the corresponding rendering process\n if (message instanceof ToRendererMessage) {\n const { __virid_target, __virid_messageType, ...payload } = message;\n //Don't send it to yourself\n if (__virid_target == \"main\") {\n MessageWriter.warn(\n `[Virid Main] Prohibit Sending To Oneself: ${__virid_target} is not allowed in ToRendererMessage.`,\n );\n }\n const packet = {\n __virid_source: ToRendererMessage.__virid_source,\n __virid_target,\n __virid_messageType,\n payload,\n };\n\n const targetWindows =\n __virid_target === \"*\" || __virid_target === \"all\"\n ? Array.from(ROUTER_MAP.values())\n : [ROUTER_MAP.get(__virid_target)].filter(Boolean);\n\n if (targetWindows.length > 0) {\n targetWindows.forEach((win) =>\n win!.webContents.send(VIRID_CHANNEL, packet),\n );\n } else {\n MessageWriter.error(\n new Error(\n `[Virid Main] No Window Found: Message target ${__virid_target} cannot be found.`,\n ),\n );\n }\n } else {\n next();\n }\n};\n","/*\n * Copyright (c) 2026-present Ailrid.\n * Licensed under the Apache License, Version 2.0.\n * Project: Virid Main\n */\nimport { MessageWriter, type Newable } from \"@virid/core\";\nimport { type BrowserWindow } from \"electron\";\nimport { type FromRendererMessage } from \"./message\";\nexport const VIRID_CHANNEL = \"VIRID_INTERNAL_BUS\";\nexport const ROUTER_MAP = new Map<string, BrowserWindow>();\nconst MESSAGE_MAP = new Map<string, Newable<FromRendererMessage>>();\n\nexport function FromRenderer(type: string) {\n return function (target: Newable<FromRendererMessage>) {\n if (MESSAGE_MAP.has(type)) {\n MessageWriter.warn(\n `[Virid Main] Duplicate IpcMessage: Registration for type: ${type}`,\n );\n }\n MESSAGE_MAP.set(type, target);\n };\n}\n// The main process receives the message and sends it to its own system\nfunction ReceiveMessages(message: any): void {\n const { __virid_source, __virid_messageType, __virid_target, payload } =\n message;\n if (!MESSAGE_MAP.has(__virid_messageType)) {\n // The main process did not register this message and reported an error directly\n MessageWriter.error(\n new Error(\n `[Virid Main] unknown Message Type: Cannot find ${__virid_messageType} in the main process registry.`,\n ),\n );\n return;\n }\n // Search for message classes registered by the main process\n const MessageClass = MESSAGE_MAP.get(__virid_messageType);\n const instance = new (MessageClass as any)();\n if (payload) {\n Object.assign(instance, payload);\n }\n // Inject identity metadata\n instance.__virid_source = __virid_source;\n instance.__virid_target = __virid_target;\n instance.__virid_messageType = __virid_messageType;\n // Inject context\n const context = ROUTER_MAP.get(__virid_source);\n if (context) {\n instance.senderWindow = context;\n }\n\n // System group assigned to the main process\n MessageWriter.write(instance);\n}\n\nfunction TransmitMessages(message: any): void {\n const { __virid_source, __virid_messageType, __virid_target, payload } =\n message;\n // Search for message classes registered by the main process\n const targetWindow = ROUTER_MAP.get(__virid_target);\n if (!targetWindow) {\n // The main process did not register this message and reported an error directly\n MessageWriter.error(\n new Error(\n `[Virid Main] unknown Window: Cannot find ${__virid_target} in the windows registry.`,\n ),\n );\n return;\n }\n targetWindow.webContents.send(VIRID_CHANNEL, {\n __virid_source,\n __virid_messageType,\n __virid_target,\n payload,\n });\n}\nfunction broadcastMessage(message: any) {\n const { __virid_source, __virid_messageType, __virid_target, payload } =\n message;\n ROUTER_MAP.forEach((window) => {\n window.webContents.send(VIRID_CHANNEL, {\n __virid_source,\n __virid_messageType,\n __virid_target,\n payload,\n });\n });\n}\n\nexport function processMessage(message: any) {\n const { __virid_target, __virid_source, __virid_messageType } = message;\n if (__virid_target === \"main\") return ReceiveMessages(message);\n else if (__virid_target === \"all\" || __virid_target === \"*\")\n return broadcastMessage(message);\n else return TransmitMessages(message);\n}\n","/*\n * Copyright (c) 2026-present Ailrid.\n * Licensed under the Apache License, Version 2.0.\n * Project: Virid Main\n */\nconst VIRID_CHANNEL = \"VIRID_INTERNAL_BUS\";\nimport { type ViridApp, MessageWriter } from \"@virid/core\";\nimport { BrowserWindow, ipcMain } from \"electron\";\nimport { middleWare, processMessage, ROUTER_MAP } from \"./main\";\nimport { type PluginOption } from \"./interfaces\";\nexport function activateApp(app: ViridApp, options: PluginOption) {\n //Check parameters\n if (!options?.electronApp) {\n MessageWriter.error(\n new Error(\n `[Virid Main] Missing Initialization Parameters:\\nelectronApp:${options?.electronApp}.`,\n ),\n );\n }\n //Bind Electron main process callback\n ipcMain.on(VIRID_CHANNEL, (event, message) => {\n const { __virid_target, __virid_source, __virid_messageType } = message;\n if (!__virid_target || !__virid_source || !__virid_messageType) {\n MessageWriter.error(\n new Error(\n `[Virid Main] Incomplete Message: The message is incomplete and requires __virid_target${__virid_target}, __virid_source${__virid_source}, __virid_messageType${__virid_messageType}`,\n ),\n );\n return;\n }\n // If it is a registration message, then register this rendering process\n if (__virid_messageType === \"VIRID_INTERNAL_REGISTER\") {\n // Obtain the physical instance through event.sender and bind it with the logical ID\n const win = BrowserWindow.fromWebContents(event.sender);\n //Unable to find window, error reported\n if (!win) {\n MessageWriter.error(\n new Error(\n `[Virid Main] unknown Window: Unable to find the window corresponding to event.sender`,\n ),\n );\n return;\n }\n //If it already exists, report an error\n if (ROUTER_MAP.has(__virid_source)) {\n MessageWriter.error(\n new Error(\n `[Virid Main] Duplicate Registration: This ID has already been registered: ${__virid_source}`,\n ),\n );\n return;\n }\n // Store in routing table\n ROUTER_MAP.set(__virid_source, win);\n // Automatically delete oneself when closed\n win.once(\"closed\", () => {\n ROUTER_MAP.delete(__virid_source);\n MessageWriter.info(\n `[Virid Main] Window unregistered: ${__virid_source}`,\n );\n });\n MessageWriter.info(`[Virid Main] Window registered: ${__virid_source}`);\n return;\n }\n //Distribute messages\n processMessage(message);\n });\n //Register your own middleware function to intercept ToRenderMessage and send it to the specified rendering process\n app.useMiddleware(middleWare);\n}\n"],"mappings":";;;;ulBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,kBAAAE,EAAA,wBAAAC,EAAA,eAAAC,EAAA,eAAAC,EAAA,sBAAAC,EAAA,kBAAAC,EAAA,eAAAC,EAAA,mBAAAC,IAAA,eAAAC,EAAAV,GCKA,IAAAW,EAA6B,uBAKtB,IAAeC,EAAf,MAAeA,UAA4BC,cAAAA,CAA3C,kCAIEC,EAAAA,sBAAyB,WAMzBC,EAAAA,sBAAyB,WAGzBC,EAAAA,2BAA8B,WAC9BC,EAAAA,oBAAuC,MAChD,EAfkDJ,EAAAA,EAAAA,uBAA3C,IAAeD,EAAfM,EAoBeC,EAAf,MAAeA,UAA0BN,cAAAA,CAchD,EAdgDA,EAAAA,EAAAA,qBAI9CO,EAJoBD,EAINL,iBAAiB,QAJ1B,IAAeK,EAAfE,ECzBP,IAAAC,EAA+C,uBCA/C,IAAAC,EAA4C,uBAGrC,IAAMC,EAAgB,qBAChBC,EAAa,IAAIC,IACxBC,EAAc,IAAID,IAEjB,SAASE,EAAaC,EAAY,CACvC,OAAO,SAAUC,EAAoC,CAC/CH,EAAYI,IAAIF,CAAAA,GAClBG,gBAAcC,KACZ,6DAA6DJ,CAAAA,EAAM,EAGvEF,EAAYO,IAAIL,EAAMC,CAAAA,CACxB,CACF,CATgBF,EAAAA,EAAAA,gBAWhB,SAASO,EAAgBC,EAAY,CACnC,GAAM,CAAEC,eAAAA,EAAgBC,oBAAAA,EAAqBC,eAAAA,EAAgBC,QAAAA,CAAO,EAClEJ,EACF,GAAI,CAACT,EAAYI,IAAIO,CAAAA,EAAsB,CAEzCN,gBAAcS,MACZ,IAAIC,MACF,kDAAkDJ,CAAAA,gCAAmD,CAAA,EAGzG,MACF,CAEA,IAAMK,EAAehB,EAAYiB,IAAIN,CAAAA,EAC/BO,EAAW,IAAKF,EAClBH,GACFM,OAAOC,OAAOF,EAAUL,CAAAA,EAG1BK,EAASR,eAAiBA,EAC1BQ,EAASN,eAAiBA,EAC1BM,EAASP,oBAAsBA,EAE/B,IAAMU,EAAUvB,EAAWmB,IAAIP,CAAAA,EAC3BW,IACFH,EAASI,aAAeD,GAI1BhB,gBAAckB,MAAML,CAAAA,CACtB,CA9BSV,EAAAA,EAAAA,mBAgCT,SAASgB,EAAiBf,EAAY,CACpC,GAAM,CAAEC,eAAAA,EAAgBC,oBAAAA,EAAqBC,eAAAA,EAAgBC,QAAAA,CAAO,EAClEJ,EAEIgB,EAAe3B,EAAWmB,IAAIL,CAAAA,EACpC,GAAI,CAACa,EAAc,CAEjBpB,gBAAcS,MACZ,IAAIC,MACF,4CAA4CH,CAAAA,2BAAyC,CAAA,EAGzF,MACF,CACAa,EAAaC,YAAYC,KAAK9B,EAAe,CAC3Ca,eAAAA,EACAC,oBAAAA,EACAC,eAAAA,EACAC,QAAAA,CACF,CAAA,CACF,CApBSW,EAAAA,EAAAA,oBAqBT,SAASI,EAAiBnB,EAAY,CACpC,GAAM,CAAEC,eAAAA,EAAgBC,oBAAAA,EAAqBC,eAAAA,EAAgBC,QAAAA,CAAO,EAClEJ,EACFX,EAAW+B,QAASC,GAAAA,CAClBA,EAAOJ,YAAYC,KAAK9B,EAAe,CACrCa,eAAAA,EACAC,oBAAAA,EACAC,eAAAA,EACAC,QAAAA,CACF,CAAA,CACF,CAAA,CACF,CAXSe,EAAAA,EAAAA,oBAaF,SAASG,EAAetB,EAAY,CACzC,GAAM,CAAEG,eAAAA,EAAgBF,eAAAA,EAAgBC,oBAAAA,CAAmB,EAAKF,EAChE,OAAIG,IAAmB,OAAeJ,EAAgBC,CAAAA,EAC7CG,IAAmB,OAASA,IAAmB,IAC/CgB,EAAiBnB,CAAAA,EACde,EAAiBf,CAAAA,CAC/B,CANgBsB,EAAAA,EAAAA,kBDjFT,IAAMC,EAAyBC,EAAA,CAACC,EAASC,IAAAA,CAE9C,GAAID,aAAmBE,EAAmB,CACxC,GAAM,CAAEC,eAAAA,EAAgBC,oBAAAA,EAAqB,GAAGC,CAAAA,EAAYL,EAExDG,GAAkB,QACpBG,gBAAcC,KACZ,6CAA6CJ,CAAAA,uCAAqD,EAGtG,IAAMK,EAAS,CACbC,eAAgBP,EAAkBO,eAClCN,eAAAA,EACAC,oBAAAA,EACAC,QAAAA,CACF,EAEMK,EACJP,IAAmB,KAAOA,IAAmB,MACzCQ,MAAMC,KAAKC,EAAWC,OAAM,CAAA,EAC5B,CAACD,EAAWE,IAAIZ,CAAAA,GAAiBa,OAAOC,OAAAA,EAE1CP,EAAcQ,OAAS,EACzBR,EAAcS,QAASC,GACrBA,EAAKC,YAAYC,KAAKC,EAAef,CAAAA,CAAAA,EAGvCF,gBAAckB,MACZ,IAAIC,MACF,gDAAgDtB,CAAAA,mBAAiC,CAAA,CAIzF,MACEF,EAAAA,CAEJ,EApCsC,cEFtC,IAAAyB,EAA6C,uBAC7CC,EAAuC,oBAFvC,IAAMC,EAAgB,qBAKf,SAASC,EAAYC,EAAeC,EAAqB,CAEzDA,GAASC,aACZC,gBAAcC,MACZ,IAAIC,MACF;cAAgEJ,GAASC,WAAAA,GAAc,CAAA,EAK7FI,UAAQC,GAAGT,EAAe,CAACU,EAAOC,IAAAA,CAChC,GAAM,CAAEC,eAAAA,EAAgBC,eAAAA,EAAgBC,oBAAAA,CAAmB,EAAKH,EAChE,GAAI,CAACC,GAAkB,CAACC,GAAkB,CAACC,EAAqB,CAC9DT,gBAAcC,MACZ,IAAIC,MACF,yFAAyFK,CAAAA,mBAAiCC,CAAAA,wBAAsCC,CAAAA,EAAqB,CAAA,EAGzL,MACF,CAEA,GAAIA,IAAwB,0BAA2B,CAErD,IAAMC,EAAMC,gBAAcC,gBAAgBP,EAAMQ,MAAM,EAEtD,GAAI,CAACH,EAAK,CACRV,gBAAcC,MACZ,IAAIC,MACF,sFAAsF,CAAA,EAG1F,MACF,CAEA,GAAIY,EAAWC,IAAIP,CAAAA,EAAiB,CAClCR,gBAAcC,MACZ,IAAIC,MACF,6EAA6EM,CAAAA,EAAgB,CAAA,EAGjG,MACF,CAEAM,EAAWE,IAAIR,EAAgBE,CAAAA,EAE/BA,EAAIO,KAAK,SAAU,IAAA,CACjBH,EAAWI,OAAOV,CAAAA,EAClBR,gBAAcmB,KACZ,qCAAqCX,CAAAA,EAAgB,CAEzD,CAAA,EACAR,gBAAcmB,KAAK,mCAAmCX,CAAAA,EAAgB,EACtE,MACF,CAEAY,EAAed,CAAAA,CACjB,CAAA,EAEAT,EAAIwB,cAAcC,CAAAA,CACpB,CA3DgB1B,EAAAA,EAAAA,eJYT,IAAM2B,EAAN,MAAMA,CAAAA,CAAN,cACLC,EAAAA,YAAO,eACPC,QAAQC,EAAeC,EAAuB,CAC5CC,EAAYF,EAAKC,CAAAA,CACnB,CACF,EALaJ,EAAAA,EAAAA,cAAN,IAAMA,EAANM","names":["index_exports","__export","FromRenderer","FromRendererMessage","MainPlugin","ROUTER_MAP","ToRendererMessage","VIRID_CHANNEL","middleWare","processMessage","__toCommonJS","import_core","FromRendererMessage","EventMessage","__virid_source","__virid_target","__virid_messageType","senderWindow","_FromRendererMessage","ToRendererMessage","__publicField","_ToRendererMessage","import_core","import_core","VIRID_CHANNEL","ROUTER_MAP","Map","MESSAGE_MAP","FromRenderer","type","target","has","MessageWriter","warn","set","ReceiveMessages","message","__virid_source","__virid_messageType","__virid_target","payload","error","Error","MessageClass","get","instance","Object","assign","context","senderWindow","write","TransmitMessages","targetWindow","webContents","send","broadcastMessage","forEach","window","processMessage","middleWare","__name","message","next","ToRendererMessage","__virid_target","__virid_messageType","payload","MessageWriter","warn","packet","__virid_source","targetWindows","Array","from","ROUTER_MAP","values","get","filter","Boolean","length","forEach","win","webContents","send","VIRID_CHANNEL","error","Error","import_core","import_electron","VIRID_CHANNEL","activateApp","app","options","electronApp","MessageWriter","error","Error","ipcMain","on","event","message","__virid_target","__virid_source","__virid_messageType","win","BrowserWindow","fromWebContents","sender","ROUTER_MAP","has","set","once","delete","info","processMessage","useMiddleware","middleWare","MainPlugin","name","install","app","options","activateApp","_MainPlugin"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/main/message.ts","../src/main/constant.ts","../src/main/decorator.ts"],"sourcesContent":["/*\n * Copyright (c) 2026-present Ailrid\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * Description: Electron main process adapter for Virid, responsible for sending, receiving, and broadcasting rendering process messages.\n */\nconst VIRID_CHANNEL = \"VIRID_INTERNAL_BUS\";\nimport {\n BaseMessage,\n MessageWriter,\n Newable,\n ViridPlugin,\n type ViridApp,\n} from \"@virid/core\";\nimport { type PluginOption } from \"./interfaces\";\nimport { BrowserWindow, ipcMain } from \"electron\";\nimport { FromRendererMessage, ToRendererMessage } from \"./main\";\nimport { VIRID_MAIN_METADATA } from \"./main/constant\";\n\nexport * from \"./main\";\nexport * from \"./interfaces\";\n\nexport class MainPlugin implements ViridPlugin<PluginOption> {\n name = \"@virid/main\";\n public message_map = new Map<string, Newable<FromRendererMessage>>();\n public route_map = new Map<string, BrowserWindow>();\n install(app: ViridApp, options: PluginOption) {\n //Check parameters\n if (!options?.electronApp) {\n MessageWriter.error(\n new Error(\n `[Virid Main] Missing Initialization Parameters: electronApp:${options?.electronApp}.`,\n ),\n );\n return;\n }\n //Bind Electron main process callback\n ipcMain.on(VIRID_CHANNEL, (event, message) => {\n const { __virid_target, __virid_source, __virid_message_type } = message;\n if (!__virid_target || !__virid_source || !__virid_message_type) {\n MessageWriter.error(\n new Error(\n `[Virid Main] Incomplete Message: The message is incomplete and requires __virid_target${__virid_target}, __virid_source${__virid_source}, __virid_message_type${__virid_message_type}`,\n ),\n );\n return;\n }\n // If it is a registration message, then register this rendering process\n if (__virid_message_type === \"VIRID_INTERNAL_REGISTER\") {\n // Obtain the physical instance through event.sender and bind it with the logical ID\n const win = BrowserWindow.fromWebContents(event.sender);\n //Unable to find window, error reported\n if (!win) {\n MessageWriter.error(\n new Error(\n `[Virid Main] unknown Window: Unable to find the window corresponding to event.sender`,\n ),\n );\n return;\n }\n //If it already exists, report an error\n if (this.route_map.has(__virid_source)) {\n MessageWriter.error(\n new Error(\n `[Virid Main] Duplicate Registration: This ID has already been registered: ${__virid_source}`,\n ),\n );\n return;\n }\n // Store in routing table\n this.route_map.set(__virid_source, win);\n // Automatically delete oneself when closed\n win.once(\"closed\", () => {\n this.route_map.delete(__virid_source);\n MessageWriter.info(\n `[Virid Main] Window unregistered: ${__virid_source}`,\n );\n });\n MessageWriter.info(`[Virid Main] Window registered: ${__virid_source}`);\n return;\n }\n //Distribute messages\n this.processMessage(message);\n });\n //Register your own middleware function to intercept ToRenderMessage and send it to the specified rendering process\n app.useMiddleware(this.middleWare.bind(this));\n }\n bindRoute(target: Newable<FromRendererMessage>) {\n const route = Reflect.getMetadata(VIRID_MAIN_METADATA.FROMRENDERER, target);\n if (this.message_map.has(route)) {\n MessageWriter.error(\n new Error(\n `[Virid Main] Duplicate IpcMessage: Registration for route: ${route}, message class: ${target}`,\n ),\n );\n }\n this.message_map.set(route, target);\n }\n middleWare(message: BaseMessage, next: () => void) {\n //If the message is inherited from MainRequestMessage, intercept and send it to the corresponding rendering process\n if (message instanceof ToRendererMessage) {\n const { __virid_target, __virid_message_type, ...payload } = message;\n //Don't send it to yourself\n if (__virid_target == \"main\") {\n MessageWriter.warn(\n `[Virid Main] Prohibit Sending To Oneself: ${__virid_target} is not allowed in ToRendererMessage.`,\n );\n return;\n }\n const packet = {\n __virid_source: ToRendererMessage.__virid_source,\n __virid_target,\n __virid_message_type,\n payload,\n };\n\n const targetWindows =\n __virid_target === \"*\" || __virid_target === \"all\"\n ? Array.from(this.route_map.values())\n : [this.route_map.get(__virid_target)].filter(Boolean);\n\n if (targetWindows.length > 0) {\n targetWindows.forEach((win) =>\n win!.webContents.send(VIRID_CHANNEL, packet),\n );\n } else {\n MessageWriter.error(\n new Error(\n `[Virid Main] No Window Found: Message target ${__virid_target} cannot be found.`,\n ),\n );\n return;\n }\n } else {\n next();\n }\n }\n\n // The main process receives the message and sends it to its own system\n receiveMessages(message: any): void {\n const { __virid_source, __virid_message_type, __virid_target, payload } =\n message;\n if (!this.message_map.has(__virid_message_type)) {\n // The main process did not register this message and reported an error directly\n MessageWriter.error(\n new Error(\n `[Virid Main] unknown Message Type: Cannot find ${__virid_message_type} in the main process registry.`,\n ),\n );\n return;\n }\n // Search for message classes registered by the main process\n const MessageClass = this.message_map.get(__virid_message_type);\n const instance = new (MessageClass as any)();\n if (payload) {\n Object.assign(instance, payload);\n }\n // Inject identity metadata\n instance.__virid_source = __virid_source;\n instance.__virid_target = __virid_target;\n instance.__virid_message_type = __virid_message_type;\n // Inject context\n const context = this.route_map.get(__virid_source);\n if (context) {\n instance.senderWindow = context;\n }\n\n // System group assigned to the main process\n MessageWriter.write(instance);\n }\n\n transmitMessages(message: any): void {\n const { __virid_source, __virid_message_type, __virid_target, payload } =\n message;\n // Search for message classes registered by the main process\n const targetWindow = this.route_map.get(__virid_target);\n if (!targetWindow) {\n // The main process did not register this message and reported an error directly\n MessageWriter.error(\n new Error(\n `[Virid Main] unknown Window: Cannot find ${__virid_target} in the windows registry.`,\n ),\n );\n return;\n }\n targetWindow.webContents.send(VIRID_CHANNEL, {\n __virid_source,\n __virid_message_type,\n __virid_target,\n payload,\n });\n }\n broadcastMessage(message: any) {\n const { __virid_source, __virid_message_type, __virid_target, payload } =\n message;\n this.route_map.forEach((window: BrowserWindow) => {\n window.webContents.send(VIRID_CHANNEL, {\n __virid_source,\n __virid_message_type,\n __virid_target,\n payload,\n });\n });\n }\n\n processMessage(message: any) {\n const { __virid_target, __virid_source, __virid_message_type } = message;\n if (__virid_target === \"main\") return this.receiveMessages(message);\n else if (__virid_target === \"all\" || __virid_target === \"*\")\n return this.broadcastMessage(message);\n else return this.transmitMessages(message);\n }\n}\n","/*\n * Copyright (c) 2026-present Ailrid.\n * Licensed under the Apache License, Version 2.0.\n * Project: Virid Main\n */\nimport { EventMessage } from \"@virid/core\";\nexport { type SystemContext } from \"@virid/core\";\n/**\n * Message from rendering process\n */\nexport abstract class FromRendererMessage extends EventMessage {\n /**\n * Where am I from?\n */\n public __virid_source: string = \"unknown\";\n /**Where is my destination?\n *'main ': Sent to the main process for processing\n *'all': Broadcast to all windows (relayed through the main process)\n *String: Specify the ID of a window (windowId)\n */\n public __virid_target: string = \"unknown\";\n\n //What message should I turn into at the destination?\n public __virid_message_type: string = \"unknown\";\n public senderWindow: Electron.BrowserWindow = null as any;\n}\n\n/**\n *Message to be sent to the rendering process\n */\nexport abstract class ToRendererMessage extends EventMessage {\n /**\n * Where am I from?\n */\n public static __virid_source = \"main\";\n /**Where is my destination?\n *'all': Broadcast to all windows (relayed through the main process)\n *String: Specify the ID of a window (windowId)\n */\n public abstract __virid_target: string;\n /**\n *What message should I turn into at the destination?\n */\n public abstract __virid_message_type: string;\n}\n","/*\n * Copyright (c) 2026-present Ailrid.\n * Licensed under the Apache License, Version 2.0.\n * Project: Virid Main\n */\nimport { VIRID_METADATA } from \"@virid/core\";\n\nexport const VIRID_MAIN_METADATA = {\n ...VIRID_METADATA,\n FROMRENDERER: \"virid:main:fromrenderer\",\n} as const;\n","/*\n * Copyright (c) 2026-present Ailrid.\n * Licensed under the Apache License, Version 2.0.\n * Project: Virid Main\n */\nimport { Newable } from \"@virid/core\";\nimport { type FromRendererMessage } from \"./message\";\nimport { VIRID_MAIN_METADATA } from \"./constant\";\nexport function FromRenderer(route: string) {\n return function (target: Newable<FromRendererMessage>) {\n Reflect.defineMetadata(VIRID_MAIN_METADATA.FROMRENDERER, route, target);\n };\n}\n"],"mappings":"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","names":["index_exports","__export","FromRenderer","FromRendererMessage","MainPlugin","ToRendererMessage","__toCommonJS","import_core","import_electron","import_core","FromRendererMessage","EventMessage","__virid_source","__virid_target","__virid_message_type","senderWindow","_FromRendererMessage","ToRendererMessage","__publicField","_ToRendererMessage","import_core","VIRID_MAIN_METADATA","VIRID_METADATA","FROMRENDERER","FromRenderer","route","target","Reflect","defineMetadata","VIRID_MAIN_METADATA","FROMRENDERER","VIRID_CHANNEL","MainPlugin","name","message_map","Map","route_map","install","app","options","electronApp","MessageWriter","error","Error","ipcMain","on","event","message","__virid_target","__virid_source","__virid_message_type","win","BrowserWindow","fromWebContents","sender","has","set","once","delete","info","processMessage","useMiddleware","middleWare","bind","bindRoute","target","route","Reflect","getMetadata","VIRID_MAIN_METADATA","FROMRENDERER","next","ToRendererMessage","payload","warn","packet","targetWindows","Array","from","values","get","filter","Boolean","length","forEach","webContents","send","receiveMessages","MessageClass","instance","Object","assign","context","senderWindow","write","transmitMessages","targetWindow","broadcastMessage","window","_MainPlugin"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
import { EventMessage,
|
|
1
|
+
import { EventMessage, Newable, ViridPlugin, ViridApp, BaseMessage } from '@virid/core';
|
|
2
2
|
export { SystemContext } from '@virid/core';
|
|
3
|
-
import {
|
|
3
|
+
import { App, BrowserWindow } from 'electron';
|
|
4
|
+
|
|
5
|
+
interface PluginOption {
|
|
6
|
+
electronApp: App;
|
|
7
|
+
}
|
|
4
8
|
|
|
5
9
|
/**
|
|
6
10
|
* Message from rendering process
|
|
@@ -16,7 +20,7 @@ declare abstract class FromRendererMessage extends EventMessage {
|
|
|
16
20
|
*String: Specify the ID of a window (windowId)
|
|
17
21
|
*/
|
|
18
22
|
__virid_target: string;
|
|
19
|
-
|
|
23
|
+
__virid_message_type: string;
|
|
20
24
|
senderWindow: Electron.BrowserWindow;
|
|
21
25
|
}
|
|
22
26
|
/**
|
|
@@ -35,23 +39,22 @@ declare abstract class ToRendererMessage extends EventMessage {
|
|
|
35
39
|
/**
|
|
36
40
|
*What message should I turn into at the destination?
|
|
37
41
|
*/
|
|
38
|
-
abstract
|
|
42
|
+
abstract __virid_message_type: string;
|
|
39
43
|
}
|
|
40
44
|
|
|
41
|
-
declare
|
|
42
|
-
|
|
43
|
-
declare const VIRID_CHANNEL = "VIRID_INTERNAL_BUS";
|
|
44
|
-
declare const ROUTER_MAP: Map<string, BrowserWindow>;
|
|
45
|
-
declare function FromRenderer(type: string): (target: Newable<FromRendererMessage>) => void;
|
|
46
|
-
declare function processMessage(message: any): void;
|
|
47
|
-
|
|
48
|
-
interface PluginOption {
|
|
49
|
-
electronApp: App;
|
|
50
|
-
}
|
|
45
|
+
declare function FromRenderer(route: string): (target: Newable<FromRendererMessage>) => void;
|
|
51
46
|
|
|
52
47
|
declare class MainPlugin implements ViridPlugin<PluginOption> {
|
|
53
48
|
name: string;
|
|
49
|
+
message_map: Map<string, Newable<FromRendererMessage>>;
|
|
50
|
+
route_map: Map<string, BrowserWindow>;
|
|
54
51
|
install(app: ViridApp, options: PluginOption): void;
|
|
52
|
+
bindRoute(target: Newable<FromRendererMessage>): void;
|
|
53
|
+
middleWare(message: BaseMessage, next: () => void): void;
|
|
54
|
+
receiveMessages(message: any): void;
|
|
55
|
+
transmitMessages(message: any): void;
|
|
56
|
+
broadcastMessage(message: any): void;
|
|
57
|
+
processMessage(message: any): void;
|
|
55
58
|
}
|
|
56
59
|
|
|
57
|
-
export { FromRenderer, FromRendererMessage, MainPlugin, type PluginOption,
|
|
60
|
+
export { FromRenderer, FromRendererMessage, MainPlugin, type PluginOption, ToRendererMessage };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
import { EventMessage,
|
|
1
|
+
import { EventMessage, Newable, ViridPlugin, ViridApp, BaseMessage } from '@virid/core';
|
|
2
2
|
export { SystemContext } from '@virid/core';
|
|
3
|
-
import {
|
|
3
|
+
import { App, BrowserWindow } from 'electron';
|
|
4
|
+
|
|
5
|
+
interface PluginOption {
|
|
6
|
+
electronApp: App;
|
|
7
|
+
}
|
|
4
8
|
|
|
5
9
|
/**
|
|
6
10
|
* Message from rendering process
|
|
@@ -16,7 +20,7 @@ declare abstract class FromRendererMessage extends EventMessage {
|
|
|
16
20
|
*String: Specify the ID of a window (windowId)
|
|
17
21
|
*/
|
|
18
22
|
__virid_target: string;
|
|
19
|
-
|
|
23
|
+
__virid_message_type: string;
|
|
20
24
|
senderWindow: Electron.BrowserWindow;
|
|
21
25
|
}
|
|
22
26
|
/**
|
|
@@ -35,23 +39,22 @@ declare abstract class ToRendererMessage extends EventMessage {
|
|
|
35
39
|
/**
|
|
36
40
|
*What message should I turn into at the destination?
|
|
37
41
|
*/
|
|
38
|
-
abstract
|
|
42
|
+
abstract __virid_message_type: string;
|
|
39
43
|
}
|
|
40
44
|
|
|
41
|
-
declare
|
|
42
|
-
|
|
43
|
-
declare const VIRID_CHANNEL = "VIRID_INTERNAL_BUS";
|
|
44
|
-
declare const ROUTER_MAP: Map<string, BrowserWindow>;
|
|
45
|
-
declare function FromRenderer(type: string): (target: Newable<FromRendererMessage>) => void;
|
|
46
|
-
declare function processMessage(message: any): void;
|
|
47
|
-
|
|
48
|
-
interface PluginOption {
|
|
49
|
-
electronApp: App;
|
|
50
|
-
}
|
|
45
|
+
declare function FromRenderer(route: string): (target: Newable<FromRendererMessage>) => void;
|
|
51
46
|
|
|
52
47
|
declare class MainPlugin implements ViridPlugin<PluginOption> {
|
|
53
48
|
name: string;
|
|
49
|
+
message_map: Map<string, Newable<FromRendererMessage>>;
|
|
50
|
+
route_map: Map<string, BrowserWindow>;
|
|
54
51
|
install(app: ViridApp, options: PluginOption): void;
|
|
52
|
+
bindRoute(target: Newable<FromRendererMessage>): void;
|
|
53
|
+
middleWare(message: BaseMessage, next: () => void): void;
|
|
54
|
+
receiveMessages(message: any): void;
|
|
55
|
+
transmitMessages(message: any): void;
|
|
56
|
+
broadcastMessage(message: any): void;
|
|
57
|
+
processMessage(message: any): void;
|
|
55
58
|
}
|
|
56
59
|
|
|
57
|
-
export { FromRenderer, FromRendererMessage, MainPlugin, type PluginOption,
|
|
60
|
+
export { FromRenderer, FromRendererMessage, MainPlugin, type PluginOption, ToRendererMessage };
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @virid/main v0.3.
|
|
2
|
+
* @virid/main v0.3.3
|
|
3
3
|
* Electron main process adapter for Virid, responsible for sending, receiving, and broadcasting rendering process messages
|
|
4
4
|
*/
|
|
5
|
-
var M=Object.defineProperty;var
|
|
6
|
-
electronApp:${e?.electronApp}.`)),C.on($,(i,t)=>{let{__virid_target:a,__virid_source:n,__virid_messageType:s}=t;if(!a||!n||!s){p.error(new Error(`[Virid Main] Incomplete Message: The message is incomplete and requires __virid_target${a}, __virid_source${n}, __virid_messageType${s}`));return}if(s==="VIRID_INTERNAL_REGISTER"){let d=b.fromWebContents(i.sender);if(!d){p.error(new Error("[Virid Main] unknown Window: Unable to find the window corresponding to event.sender"));return}if(_.has(n)){p.error(new Error(`[Virid Main] Duplicate Registration: This ID has already been registered: ${n}`));return}_.set(n,d),d.once("closed",()=>{_.delete(n),p.info(`[Virid Main] Window unregistered: ${n}`)}),p.info(`[Virid Main] Window registered: ${n}`);return}T(t)}),r.useMiddleware(R)}o(y,"activateApp");var v=class v{constructor(){c(this,"name","@virid/main")}install(e,i){y(e,i)}};o(v,"MainPlugin");var A=v;export{O as FromRenderer,E as FromRendererMessage,A as MainPlugin,_ as ROUTER_MAP,f as ToRendererMessage,l as VIRID_CHANNEL,R as middleWare,T as processMessage};
|
|
5
|
+
var M=Object.defineProperty;var R=(d,e,r)=>e in d?M(d,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):d[e]=r;var p=(d,e)=>M(d,"name",{value:e,configurable:!0});var _=(d,e,r)=>R(d,typeof e!="symbol"?e+"":e,r);import{MessageWriter as o}from"@virid/core";import{BrowserWindow as A,ipcMain as y}from"electron";import{EventMessage as h}from"@virid/core";var l=class l extends h{constructor(){super(...arguments);_(this,"__virid_source","unknown");_(this,"__virid_target","unknown");_(this,"__virid_message_type","unknown");_(this,"senderWindow",null)}};p(l,"FromRendererMessage");var v=l,u=class u extends h{};p(u,"ToRendererMessage"),_(u,"__virid_source","main");var m=u;import{VIRID_METADATA as I}from"@virid/core";var g={...I,FROMRENDERER:"virid:main:fromrenderer"};function $(d){return function(e){Reflect.defineMetadata(g.FROMRENDERER,d,e)}}p($,"FromRenderer");var f="VIRID_INTERNAL_BUS",w=class w{constructor(){_(this,"name","@virid/main");_(this,"message_map",new Map);_(this,"route_map",new Map)}install(e,r){if(!r?.electronApp){o.error(new Error(`[Virid Main] Missing Initialization Parameters: electronApp:${r?.electronApp}.`));return}y.on(f,(i,s)=>{let{__virid_target:a,__virid_source:t,__virid_message_type:n}=s;if(!a||!t||!n){o.error(new Error(`[Virid Main] Incomplete Message: The message is incomplete and requires __virid_target${a}, __virid_source${t}, __virid_message_type${n}`));return}if(n==="VIRID_INTERNAL_REGISTER"){let c=A.fromWebContents(i.sender);if(!c){o.error(new Error("[Virid Main] unknown Window: Unable to find the window corresponding to event.sender"));return}if(this.route_map.has(t)){o.error(new Error(`[Virid Main] Duplicate Registration: This ID has already been registered: ${t}`));return}this.route_map.set(t,c),c.once("closed",()=>{this.route_map.delete(t),o.info(`[Virid Main] Window unregistered: ${t}`)}),o.info(`[Virid Main] Window registered: ${t}`);return}this.processMessage(s)}),e.useMiddleware(this.middleWare.bind(this))}bindRoute(e){let r=Reflect.getMetadata(g.FROMRENDERER,e);this.message_map.has(r)&&o.error(new Error(`[Virid Main] Duplicate IpcMessage: Registration for route: ${r}, message class: ${e}`)),this.message_map.set(r,e)}middleWare(e,r){if(e instanceof m){let{__virid_target:i,__virid_message_type:s,...a}=e;if(i=="main"){o.warn(`[Virid Main] Prohibit Sending To Oneself: ${i} is not allowed in ToRendererMessage.`);return}let t={__virid_source:m.__virid_source,__virid_target:i,__virid_message_type:s,payload:a},n=i==="*"||i==="all"?Array.from(this.route_map.values()):[this.route_map.get(i)].filter(Boolean);if(n.length>0)n.forEach(c=>c.webContents.send(f,t));else{o.error(new Error(`[Virid Main] No Window Found: Message target ${i} cannot be found.`));return}}else r()}receiveMessages(e){let{__virid_source:r,__virid_message_type:i,__virid_target:s,payload:a}=e;if(!this.message_map.has(i)){o.error(new Error(`[Virid Main] unknown Message Type: Cannot find ${i} in the main process registry.`));return}let t=this.message_map.get(i),n=new t;a&&Object.assign(n,a),n.__virid_source=r,n.__virid_target=s,n.__virid_message_type=i;let c=this.route_map.get(r);c&&(n.senderWindow=c),o.write(n)}transmitMessages(e){let{__virid_source:r,__virid_message_type:i,__virid_target:s,payload:a}=e,t=this.route_map.get(s);if(!t){o.error(new Error(`[Virid Main] unknown Window: Cannot find ${s} in the windows registry.`));return}t.webContents.send(f,{__virid_source:r,__virid_message_type:i,__virid_target:s,payload:a})}broadcastMessage(e){let{__virid_source:r,__virid_message_type:i,__virid_target:s,payload:a}=e;this.route_map.forEach(t=>{t.webContents.send(f,{__virid_source:r,__virid_message_type:i,__virid_target:s,payload:a})})}processMessage(e){let{__virid_target:r,__virid_source:i,__virid_message_type:s}=e;return r==="main"?this.receiveMessages(e):r==="all"||r==="*"?this.broadcastMessage(e):this.transmitMessages(e)}};p(w,"MainPlugin");var E=w;export{$ as FromRenderer,v as FromRendererMessage,E as MainPlugin,m as ToRendererMessage};
|
|
7
6
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/main/message.ts","../src/main/middleware.ts","../src/main/router.ts","../src/app.ts","../src/index.ts"],"sourcesContent":["/*\n * Copyright (c) 2026-present Ailrid.\n * Licensed under the Apache License, Version 2.0.\n * Project: Virid Main\n */\nimport { EventMessage } from \"@virid/core\";\nexport { type SystemContext } from \"@virid/core\";\n/**\n * Message from rendering process\n */\nexport abstract class FromRendererMessage extends EventMessage {\n /**\n * Where am I from?\n */\n public __virid_source: string = \"unknown\";\n /**Where is my destination?\n *'main ': Sent to the main process for processing\n *'all': Broadcast to all windows (relayed through the main process)\n *String: Specify the ID of a window (windowId)\n */\n public __virid_target: string = \"unknown\";\n\n //What message should I turn into at the destination?\n public __virid_messageType: string = \"unknown\";\n public senderWindow: Electron.BrowserWindow = null as any;\n}\n\n/**\n *Message to be sent to the rendering process\n */\nexport abstract class ToRendererMessage extends EventMessage {\n /**\n * Where am I from?\n */\n public static __virid_source = \"main\";\n /**Where is my destination?\n *'all': Broadcast to all windows (relayed through the main process)\n *String: Specify the ID of a window (windowId)\n */\n public abstract __virid_target: string;\n /**\n *What message should I turn into at the destination?\n */\n public abstract __virid_messageType: string;\n}\n","/*\n * Copyright (c) 2026-present Ailrid.\n * Licensed under the Apache License, Version 2.0.\n * Project: Virid Main\n */\nimport { type Middleware, MessageWriter } from \"@virid/core\";\nimport { ToRendererMessage } from \"./message\";\nimport { ROUTER_MAP, VIRID_CHANNEL } from \"./router\";\nexport const middleWare: Middleware = (message, next) => {\n //If the message is inherited from MainRequestMessage, intercept and send it to the corresponding rendering process\n if (message instanceof ToRendererMessage) {\n const { __virid_target, __virid_messageType, ...payload } = message;\n //Don't send it to yourself\n if (__virid_target == \"main\") {\n MessageWriter.warn(\n `[Virid Main] Prohibit Sending To Oneself: ${__virid_target} is not allowed in ToRendererMessage.`,\n );\n }\n const packet = {\n __virid_source: ToRendererMessage.__virid_source,\n __virid_target,\n __virid_messageType,\n payload,\n };\n\n const targetWindows =\n __virid_target === \"*\" || __virid_target === \"all\"\n ? Array.from(ROUTER_MAP.values())\n : [ROUTER_MAP.get(__virid_target)].filter(Boolean);\n\n if (targetWindows.length > 0) {\n targetWindows.forEach((win) =>\n win!.webContents.send(VIRID_CHANNEL, packet),\n );\n } else {\n MessageWriter.error(\n new Error(\n `[Virid Main] No Window Found: Message target ${__virid_target} cannot be found.`,\n ),\n );\n }\n } else {\n next();\n }\n};\n","/*\n * Copyright (c) 2026-present Ailrid.\n * Licensed under the Apache License, Version 2.0.\n * Project: Virid Main\n */\nimport { MessageWriter, type Newable } from \"@virid/core\";\nimport { type BrowserWindow } from \"electron\";\nimport { type FromRendererMessage } from \"./message\";\nexport const VIRID_CHANNEL = \"VIRID_INTERNAL_BUS\";\nexport const ROUTER_MAP = new Map<string, BrowserWindow>();\nconst MESSAGE_MAP = new Map<string, Newable<FromRendererMessage>>();\n\nexport function FromRenderer(type: string) {\n return function (target: Newable<FromRendererMessage>) {\n if (MESSAGE_MAP.has(type)) {\n MessageWriter.warn(\n `[Virid Main] Duplicate IpcMessage: Registration for type: ${type}`,\n );\n }\n MESSAGE_MAP.set(type, target);\n };\n}\n// The main process receives the message and sends it to its own system\nfunction ReceiveMessages(message: any): void {\n const { __virid_source, __virid_messageType, __virid_target, payload } =\n message;\n if (!MESSAGE_MAP.has(__virid_messageType)) {\n // The main process did not register this message and reported an error directly\n MessageWriter.error(\n new Error(\n `[Virid Main] unknown Message Type: Cannot find ${__virid_messageType} in the main process registry.`,\n ),\n );\n return;\n }\n // Search for message classes registered by the main process\n const MessageClass = MESSAGE_MAP.get(__virid_messageType);\n const instance = new (MessageClass as any)();\n if (payload) {\n Object.assign(instance, payload);\n }\n // Inject identity metadata\n instance.__virid_source = __virid_source;\n instance.__virid_target = __virid_target;\n instance.__virid_messageType = __virid_messageType;\n // Inject context\n const context = ROUTER_MAP.get(__virid_source);\n if (context) {\n instance.senderWindow = context;\n }\n\n // System group assigned to the main process\n MessageWriter.write(instance);\n}\n\nfunction TransmitMessages(message: any): void {\n const { __virid_source, __virid_messageType, __virid_target, payload } =\n message;\n // Search for message classes registered by the main process\n const targetWindow = ROUTER_MAP.get(__virid_target);\n if (!targetWindow) {\n // The main process did not register this message and reported an error directly\n MessageWriter.error(\n new Error(\n `[Virid Main] unknown Window: Cannot find ${__virid_target} in the windows registry.`,\n ),\n );\n return;\n }\n targetWindow.webContents.send(VIRID_CHANNEL, {\n __virid_source,\n __virid_messageType,\n __virid_target,\n payload,\n });\n}\nfunction broadcastMessage(message: any) {\n const { __virid_source, __virid_messageType, __virid_target, payload } =\n message;\n ROUTER_MAP.forEach((window) => {\n window.webContents.send(VIRID_CHANNEL, {\n __virid_source,\n __virid_messageType,\n __virid_target,\n payload,\n });\n });\n}\n\nexport function processMessage(message: any) {\n const { __virid_target, __virid_source, __virid_messageType } = message;\n if (__virid_target === \"main\") return ReceiveMessages(message);\n else if (__virid_target === \"all\" || __virid_target === \"*\")\n return broadcastMessage(message);\n else return TransmitMessages(message);\n}\n","/*\n * Copyright (c) 2026-present Ailrid.\n * Licensed under the Apache License, Version 2.0.\n * Project: Virid Main\n */\nconst VIRID_CHANNEL = \"VIRID_INTERNAL_BUS\";\nimport { type ViridApp, MessageWriter } from \"@virid/core\";\nimport { BrowserWindow, ipcMain } from \"electron\";\nimport { middleWare, processMessage, ROUTER_MAP } from \"./main\";\nimport { type PluginOption } from \"./interfaces\";\nexport function activateApp(app: ViridApp, options: PluginOption) {\n //Check parameters\n if (!options?.electronApp) {\n MessageWriter.error(\n new Error(\n `[Virid Main] Missing Initialization Parameters:\\nelectronApp:${options?.electronApp}.`,\n ),\n );\n }\n //Bind Electron main process callback\n ipcMain.on(VIRID_CHANNEL, (event, message) => {\n const { __virid_target, __virid_source, __virid_messageType } = message;\n if (!__virid_target || !__virid_source || !__virid_messageType) {\n MessageWriter.error(\n new Error(\n `[Virid Main] Incomplete Message: The message is incomplete and requires __virid_target${__virid_target}, __virid_source${__virid_source}, __virid_messageType${__virid_messageType}`,\n ),\n );\n return;\n }\n // If it is a registration message, then register this rendering process\n if (__virid_messageType === \"VIRID_INTERNAL_REGISTER\") {\n // Obtain the physical instance through event.sender and bind it with the logical ID\n const win = BrowserWindow.fromWebContents(event.sender);\n //Unable to find window, error reported\n if (!win) {\n MessageWriter.error(\n new Error(\n `[Virid Main] unknown Window: Unable to find the window corresponding to event.sender`,\n ),\n );\n return;\n }\n //If it already exists, report an error\n if (ROUTER_MAP.has(__virid_source)) {\n MessageWriter.error(\n new Error(\n `[Virid Main] Duplicate Registration: This ID has already been registered: ${__virid_source}`,\n ),\n );\n return;\n }\n // Store in routing table\n ROUTER_MAP.set(__virid_source, win);\n // Automatically delete oneself when closed\n win.once(\"closed\", () => {\n ROUTER_MAP.delete(__virid_source);\n MessageWriter.info(\n `[Virid Main] Window unregistered: ${__virid_source}`,\n );\n });\n MessageWriter.info(`[Virid Main] Window registered: ${__virid_source}`);\n return;\n }\n //Distribute messages\n processMessage(message);\n });\n //Register your own middleware function to intercept ToRenderMessage and send it to the specified rendering process\n app.useMiddleware(middleWare);\n}\n","/*\n * Copyright (c) 2026-present Ailrid\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * Description: Electron main process adapter for Virid, responsible for sending, receiving, and broadcasting rendering process messages.\n */\nexport * from \"./main\";\nexport * from \"./interfaces\";\nimport { ViridPlugin, type ViridApp } from \"@virid/core\";\nimport { type PluginOption } from \"./interfaces\";\nimport { activateApp } from \"./app\";\nexport class MainPlugin implements ViridPlugin<PluginOption> {\n name = \"@virid/main\";\n install(app: ViridApp, options: PluginOption) {\n activateApp(app, options);\n }\n}\n"],"mappings":";;;;uNAKA,OAASA,gBAAAA,MAAoB,cAKtB,IAAeC,EAAf,MAAeA,UAA4BC,CAAAA,CAA3C,kCAIEC,EAAAA,sBAAyB,WAMzBC,EAAAA,sBAAyB,WAGzBC,EAAAA,2BAA8B,WAC9BC,EAAAA,oBAAuC,MAChD,EAfkDJ,EAAAA,EAAAA,uBAA3C,IAAeD,EAAfM,EAoBeC,EAAf,MAAeA,UAA0BN,CAAAA,CAchD,EAdgDA,EAAAA,EAAAA,qBAI9CO,EAJoBD,EAINL,iBAAiB,QAJ1B,IAAeK,EAAfE,ECzBP,OAA0BC,iBAAAA,MAAqB,cCA/C,OAASC,iBAAAA,MAAmC,cAGrC,IAAMC,EAAgB,qBAChBC,EAAa,IAAIC,IACxBC,EAAc,IAAID,IAEjB,SAASE,EAAaC,EAAY,CACvC,OAAO,SAAUC,EAAoC,CAC/CH,EAAYI,IAAIF,CAAAA,GAClBG,EAAcC,KACZ,6DAA6DJ,CAAAA,EAAM,EAGvEF,EAAYO,IAAIL,EAAMC,CAAAA,CACxB,CACF,CATgBF,EAAAA,EAAAA,gBAWhB,SAASO,EAAgBC,EAAY,CACnC,GAAM,CAAEC,eAAAA,EAAgBC,oBAAAA,EAAqBC,eAAAA,EAAgBC,QAAAA,CAAO,EAClEJ,EACF,GAAI,CAACT,EAAYI,IAAIO,CAAAA,EAAsB,CAEzCN,EAAcS,MACZ,IAAIC,MACF,kDAAkDJ,CAAAA,gCAAmD,CAAA,EAGzG,MACF,CAEA,IAAMK,EAAehB,EAAYiB,IAAIN,CAAAA,EAC/BO,EAAW,IAAKF,EAClBH,GACFM,OAAOC,OAAOF,EAAUL,CAAAA,EAG1BK,EAASR,eAAiBA,EAC1BQ,EAASN,eAAiBA,EAC1BM,EAASP,oBAAsBA,EAE/B,IAAMU,EAAUvB,EAAWmB,IAAIP,CAAAA,EAC3BW,IACFH,EAASI,aAAeD,GAI1BhB,EAAckB,MAAML,CAAAA,CACtB,CA9BSV,EAAAA,EAAAA,mBAgCT,SAASgB,EAAiBf,EAAY,CACpC,GAAM,CAAEC,eAAAA,EAAgBC,oBAAAA,EAAqBC,eAAAA,EAAgBC,QAAAA,CAAO,EAClEJ,EAEIgB,EAAe3B,EAAWmB,IAAIL,CAAAA,EACpC,GAAI,CAACa,EAAc,CAEjBpB,EAAcS,MACZ,IAAIC,MACF,4CAA4CH,CAAAA,2BAAyC,CAAA,EAGzF,MACF,CACAa,EAAaC,YAAYC,KAAK9B,EAAe,CAC3Ca,eAAAA,EACAC,oBAAAA,EACAC,eAAAA,EACAC,QAAAA,CACF,CAAA,CACF,CApBSW,EAAAA,EAAAA,oBAqBT,SAASI,EAAiBnB,EAAY,CACpC,GAAM,CAAEC,eAAAA,EAAgBC,oBAAAA,EAAqBC,eAAAA,EAAgBC,QAAAA,CAAO,EAClEJ,EACFX,EAAW+B,QAASC,GAAAA,CAClBA,EAAOJ,YAAYC,KAAK9B,EAAe,CACrCa,eAAAA,EACAC,oBAAAA,EACAC,eAAAA,EACAC,QAAAA,CACF,CAAA,CACF,CAAA,CACF,CAXSe,EAAAA,EAAAA,oBAaF,SAASG,EAAetB,EAAY,CACzC,GAAM,CAAEG,eAAAA,EAAgBF,eAAAA,EAAgBC,oBAAAA,CAAmB,EAAKF,EAChE,OAAIG,IAAmB,OAAeJ,EAAgBC,CAAAA,EAC7CG,IAAmB,OAASA,IAAmB,IAC/CgB,EAAiBnB,CAAAA,EACde,EAAiBf,CAAAA,CAC/B,CANgBsB,EAAAA,EAAAA,kBDjFT,IAAMC,EAAyBC,EAAA,CAACC,EAASC,IAAAA,CAE9C,GAAID,aAAmBE,EAAmB,CACxC,GAAM,CAAEC,eAAAA,EAAgBC,oBAAAA,EAAqB,GAAGC,CAAAA,EAAYL,EAExDG,GAAkB,QACpBG,EAAcC,KACZ,6CAA6CJ,CAAAA,uCAAqD,EAGtG,IAAMK,EAAS,CACbC,eAAgBP,EAAkBO,eAClCN,eAAAA,EACAC,oBAAAA,EACAC,QAAAA,CACF,EAEMK,EACJP,IAAmB,KAAOA,IAAmB,MACzCQ,MAAMC,KAAKC,EAAWC,OAAM,CAAA,EAC5B,CAACD,EAAWE,IAAIZ,CAAAA,GAAiBa,OAAOC,OAAAA,EAE1CP,EAAcQ,OAAS,EACzBR,EAAcS,QAASC,GACrBA,EAAKC,YAAYC,KAAKC,EAAef,CAAAA,CAAAA,EAGvCF,EAAckB,MACZ,IAAIC,MACF,gDAAgDtB,CAAAA,mBAAiC,CAAA,CAIzF,MACEF,EAAAA,CAEJ,EApCsC,cEFtC,OAAwByB,iBAAAA,MAAqB,cAC7C,OAASC,iBAAAA,EAAeC,WAAAA,MAAe,WAFvC,IAAMC,EAAgB,qBAKf,SAASC,EAAYC,EAAeC,EAAqB,CAEzDA,GAASC,aACZC,EAAcC,MACZ,IAAIC,MACF;cAAgEJ,GAASC,WAAAA,GAAc,CAAA,EAK7FI,EAAQC,GAAGT,EAAe,CAACU,EAAOC,IAAAA,CAChC,GAAM,CAAEC,eAAAA,EAAgBC,eAAAA,EAAgBC,oBAAAA,CAAmB,EAAKH,EAChE,GAAI,CAACC,GAAkB,CAACC,GAAkB,CAACC,EAAqB,CAC9DT,EAAcC,MACZ,IAAIC,MACF,yFAAyFK,CAAAA,mBAAiCC,CAAAA,wBAAsCC,CAAAA,EAAqB,CAAA,EAGzL,MACF,CAEA,GAAIA,IAAwB,0BAA2B,CAErD,IAAMC,EAAMC,EAAcC,gBAAgBP,EAAMQ,MAAM,EAEtD,GAAI,CAACH,EAAK,CACRV,EAAcC,MACZ,IAAIC,MACF,sFAAsF,CAAA,EAG1F,MACF,CAEA,GAAIY,EAAWC,IAAIP,CAAAA,EAAiB,CAClCR,EAAcC,MACZ,IAAIC,MACF,6EAA6EM,CAAAA,EAAgB,CAAA,EAGjG,MACF,CAEAM,EAAWE,IAAIR,EAAgBE,CAAAA,EAE/BA,EAAIO,KAAK,SAAU,IAAA,CACjBH,EAAWI,OAAOV,CAAAA,EAClBR,EAAcmB,KACZ,qCAAqCX,CAAAA,EAAgB,CAEzD,CAAA,EACAR,EAAcmB,KAAK,mCAAmCX,CAAAA,EAAgB,EACtE,MACF,CAEAY,EAAed,CAAAA,CACjB,CAAA,EAEAT,EAAIwB,cAAcC,CAAAA,CACpB,CA3DgB1B,EAAAA,EAAAA,eCYT,IAAM2B,EAAN,MAAMA,CAAAA,CAAN,cACLC,EAAAA,YAAO,eACPC,QAAQC,EAAeC,EAAuB,CAC5CC,EAAYF,EAAKC,CAAAA,CACnB,CACF,EALaJ,EAAAA,EAAAA,cAAN,IAAMA,EAANM","names":["EventMessage","FromRendererMessage","EventMessage","__virid_source","__virid_target","__virid_messageType","senderWindow","_FromRendererMessage","ToRendererMessage","__publicField","_ToRendererMessage","MessageWriter","MessageWriter","VIRID_CHANNEL","ROUTER_MAP","Map","MESSAGE_MAP","FromRenderer","type","target","has","MessageWriter","warn","set","ReceiveMessages","message","__virid_source","__virid_messageType","__virid_target","payload","error","Error","MessageClass","get","instance","Object","assign","context","senderWindow","write","TransmitMessages","targetWindow","webContents","send","broadcastMessage","forEach","window","processMessage","middleWare","__name","message","next","ToRendererMessage","__virid_target","__virid_messageType","payload","MessageWriter","warn","packet","__virid_source","targetWindows","Array","from","ROUTER_MAP","values","get","filter","Boolean","length","forEach","win","webContents","send","VIRID_CHANNEL","error","Error","MessageWriter","BrowserWindow","ipcMain","VIRID_CHANNEL","activateApp","app","options","electronApp","MessageWriter","error","Error","ipcMain","on","event","message","__virid_target","__virid_source","__virid_messageType","win","BrowserWindow","fromWebContents","sender","ROUTER_MAP","has","set","once","delete","info","processMessage","useMiddleware","middleWare","MainPlugin","name","install","app","options","activateApp","_MainPlugin"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/main/message.ts","../src/main/constant.ts","../src/main/decorator.ts"],"sourcesContent":["/*\n * Copyright (c) 2026-present Ailrid\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * Description: Electron main process adapter for Virid, responsible for sending, receiving, and broadcasting rendering process messages.\n */\nconst VIRID_CHANNEL = \"VIRID_INTERNAL_BUS\";\nimport {\n BaseMessage,\n MessageWriter,\n Newable,\n ViridPlugin,\n type ViridApp,\n} from \"@virid/core\";\nimport { type PluginOption } from \"./interfaces\";\nimport { BrowserWindow, ipcMain } from \"electron\";\nimport { FromRendererMessage, ToRendererMessage } from \"./main\";\nimport { VIRID_MAIN_METADATA } from \"./main/constant\";\n\nexport * from \"./main\";\nexport * from \"./interfaces\";\n\nexport class MainPlugin implements ViridPlugin<PluginOption> {\n name = \"@virid/main\";\n public message_map = new Map<string, Newable<FromRendererMessage>>();\n public route_map = new Map<string, BrowserWindow>();\n install(app: ViridApp, options: PluginOption) {\n //Check parameters\n if (!options?.electronApp) {\n MessageWriter.error(\n new Error(\n `[Virid Main] Missing Initialization Parameters: electronApp:${options?.electronApp}.`,\n ),\n );\n return;\n }\n //Bind Electron main process callback\n ipcMain.on(VIRID_CHANNEL, (event, message) => {\n const { __virid_target, __virid_source, __virid_message_type } = message;\n if (!__virid_target || !__virid_source || !__virid_message_type) {\n MessageWriter.error(\n new Error(\n `[Virid Main] Incomplete Message: The message is incomplete and requires __virid_target${__virid_target}, __virid_source${__virid_source}, __virid_message_type${__virid_message_type}`,\n ),\n );\n return;\n }\n // If it is a registration message, then register this rendering process\n if (__virid_message_type === \"VIRID_INTERNAL_REGISTER\") {\n // Obtain the physical instance through event.sender and bind it with the logical ID\n const win = BrowserWindow.fromWebContents(event.sender);\n //Unable to find window, error reported\n if (!win) {\n MessageWriter.error(\n new Error(\n `[Virid Main] unknown Window: Unable to find the window corresponding to event.sender`,\n ),\n );\n return;\n }\n //If it already exists, report an error\n if (this.route_map.has(__virid_source)) {\n MessageWriter.error(\n new Error(\n `[Virid Main] Duplicate Registration: This ID has already been registered: ${__virid_source}`,\n ),\n );\n return;\n }\n // Store in routing table\n this.route_map.set(__virid_source, win);\n // Automatically delete oneself when closed\n win.once(\"closed\", () => {\n this.route_map.delete(__virid_source);\n MessageWriter.info(\n `[Virid Main] Window unregistered: ${__virid_source}`,\n );\n });\n MessageWriter.info(`[Virid Main] Window registered: ${__virid_source}`);\n return;\n }\n //Distribute messages\n this.processMessage(message);\n });\n //Register your own middleware function to intercept ToRenderMessage and send it to the specified rendering process\n app.useMiddleware(this.middleWare.bind(this));\n }\n bindRoute(target: Newable<FromRendererMessage>) {\n const route = Reflect.getMetadata(VIRID_MAIN_METADATA.FROMRENDERER, target);\n if (this.message_map.has(route)) {\n MessageWriter.error(\n new Error(\n `[Virid Main] Duplicate IpcMessage: Registration for route: ${route}, message class: ${target}`,\n ),\n );\n }\n this.message_map.set(route, target);\n }\n middleWare(message: BaseMessage, next: () => void) {\n //If the message is inherited from MainRequestMessage, intercept and send it to the corresponding rendering process\n if (message instanceof ToRendererMessage) {\n const { __virid_target, __virid_message_type, ...payload } = message;\n //Don't send it to yourself\n if (__virid_target == \"main\") {\n MessageWriter.warn(\n `[Virid Main] Prohibit Sending To Oneself: ${__virid_target} is not allowed in ToRendererMessage.`,\n );\n return;\n }\n const packet = {\n __virid_source: ToRendererMessage.__virid_source,\n __virid_target,\n __virid_message_type,\n payload,\n };\n\n const targetWindows =\n __virid_target === \"*\" || __virid_target === \"all\"\n ? Array.from(this.route_map.values())\n : [this.route_map.get(__virid_target)].filter(Boolean);\n\n if (targetWindows.length > 0) {\n targetWindows.forEach((win) =>\n win!.webContents.send(VIRID_CHANNEL, packet),\n );\n } else {\n MessageWriter.error(\n new Error(\n `[Virid Main] No Window Found: Message target ${__virid_target} cannot be found.`,\n ),\n );\n return;\n }\n } else {\n next();\n }\n }\n\n // The main process receives the message and sends it to its own system\n receiveMessages(message: any): void {\n const { __virid_source, __virid_message_type, __virid_target, payload } =\n message;\n if (!this.message_map.has(__virid_message_type)) {\n // The main process did not register this message and reported an error directly\n MessageWriter.error(\n new Error(\n `[Virid Main] unknown Message Type: Cannot find ${__virid_message_type} in the main process registry.`,\n ),\n );\n return;\n }\n // Search for message classes registered by the main process\n const MessageClass = this.message_map.get(__virid_message_type);\n const instance = new (MessageClass as any)();\n if (payload) {\n Object.assign(instance, payload);\n }\n // Inject identity metadata\n instance.__virid_source = __virid_source;\n instance.__virid_target = __virid_target;\n instance.__virid_message_type = __virid_message_type;\n // Inject context\n const context = this.route_map.get(__virid_source);\n if (context) {\n instance.senderWindow = context;\n }\n\n // System group assigned to the main process\n MessageWriter.write(instance);\n }\n\n transmitMessages(message: any): void {\n const { __virid_source, __virid_message_type, __virid_target, payload } =\n message;\n // Search for message classes registered by the main process\n const targetWindow = this.route_map.get(__virid_target);\n if (!targetWindow) {\n // The main process did not register this message and reported an error directly\n MessageWriter.error(\n new Error(\n `[Virid Main] unknown Window: Cannot find ${__virid_target} in the windows registry.`,\n ),\n );\n return;\n }\n targetWindow.webContents.send(VIRID_CHANNEL, {\n __virid_source,\n __virid_message_type,\n __virid_target,\n payload,\n });\n }\n broadcastMessage(message: any) {\n const { __virid_source, __virid_message_type, __virid_target, payload } =\n message;\n this.route_map.forEach((window: BrowserWindow) => {\n window.webContents.send(VIRID_CHANNEL, {\n __virid_source,\n __virid_message_type,\n __virid_target,\n payload,\n });\n });\n }\n\n processMessage(message: any) {\n const { __virid_target, __virid_source, __virid_message_type } = message;\n if (__virid_target === \"main\") return this.receiveMessages(message);\n else if (__virid_target === \"all\" || __virid_target === \"*\")\n return this.broadcastMessage(message);\n else return this.transmitMessages(message);\n }\n}\n","/*\n * Copyright (c) 2026-present Ailrid.\n * Licensed under the Apache License, Version 2.0.\n * Project: Virid Main\n */\nimport { EventMessage } from \"@virid/core\";\nexport { type SystemContext } from \"@virid/core\";\n/**\n * Message from rendering process\n */\nexport abstract class FromRendererMessage extends EventMessage {\n /**\n * Where am I from?\n */\n public __virid_source: string = \"unknown\";\n /**Where is my destination?\n *'main ': Sent to the main process for processing\n *'all': Broadcast to all windows (relayed through the main process)\n *String: Specify the ID of a window (windowId)\n */\n public __virid_target: string = \"unknown\";\n\n //What message should I turn into at the destination?\n public __virid_message_type: string = \"unknown\";\n public senderWindow: Electron.BrowserWindow = null as any;\n}\n\n/**\n *Message to be sent to the rendering process\n */\nexport abstract class ToRendererMessage extends EventMessage {\n /**\n * Where am I from?\n */\n public static __virid_source = \"main\";\n /**Where is my destination?\n *'all': Broadcast to all windows (relayed through the main process)\n *String: Specify the ID of a window (windowId)\n */\n public abstract __virid_target: string;\n /**\n *What message should I turn into at the destination?\n */\n public abstract __virid_message_type: string;\n}\n","/*\n * Copyright (c) 2026-present Ailrid.\n * Licensed under the Apache License, Version 2.0.\n * Project: Virid Main\n */\nimport { VIRID_METADATA } from \"@virid/core\";\n\nexport const VIRID_MAIN_METADATA = {\n ...VIRID_METADATA,\n FROMRENDERER: \"virid:main:fromrenderer\",\n} as const;\n","/*\n * Copyright (c) 2026-present Ailrid.\n * Licensed under the Apache License, Version 2.0.\n * Project: Virid Main\n */\nimport { Newable } from \"@virid/core\";\nimport { type FromRendererMessage } from \"./message\";\nimport { VIRID_MAIN_METADATA } from \"./constant\";\nexport function FromRenderer(route: string) {\n return function (target: Newable<FromRendererMessage>) {\n Reflect.defineMetadata(VIRID_MAIN_METADATA.FROMRENDERER, route, target);\n };\n}\n"],"mappings":"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","names":["MessageWriter","BrowserWindow","ipcMain","EventMessage","FromRendererMessage","EventMessage","__virid_source","__virid_target","__virid_message_type","senderWindow","_FromRendererMessage","ToRendererMessage","__publicField","_ToRendererMessage","VIRID_METADATA","VIRID_MAIN_METADATA","FROMRENDERER","FromRenderer","route","target","Reflect","defineMetadata","VIRID_MAIN_METADATA","FROMRENDERER","VIRID_CHANNEL","MainPlugin","name","message_map","Map","route_map","install","app","options","electronApp","MessageWriter","error","Error","ipcMain","on","event","message","__virid_target","__virid_source","__virid_message_type","win","BrowserWindow","fromWebContents","sender","has","set","once","delete","info","processMessage","useMiddleware","middleWare","bind","bindRoute","target","route","Reflect","getMetadata","VIRID_MAIN_METADATA","FROMRENDERER","next","ToRendererMessage","payload","warn","packet","targetWindows","Array","from","values","get","filter","Boolean","length","forEach","webContents","send","receiveMessages","MessageClass","instance","Object","assign","context","senderWindow","write","transmitMessages","targetWindow","broadcastMessage","window","_MainPlugin"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@virid/main",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.3",
|
|
5
5
|
"description": "Electron main process adapter for Virid, responsible for sending, receiving, and broadcasting rendering process messages",
|
|
6
6
|
"author": "Ailrid",
|
|
7
7
|
"license": "Apache 2.0",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"dependencies": {},
|
|
36
36
|
"peerDependencies": {
|
|
37
37
|
"electron": ">=30.0.0",
|
|
38
|
-
"@virid/core": "0.3.
|
|
38
|
+
"@virid/core": "0.3.3"
|
|
39
39
|
},
|
|
40
40
|
"scripts": {
|
|
41
41
|
"build": "tsup --config tsup.config.ts",
|