coakka-v2-connector-electron 2.5.3 → 3.1.1
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/CONSUMING.md +48 -5
- package/PACKAGE-LICENSE.md +1 -1
- package/README.md +89 -50
- package/dist/index.d.ts +27 -23
- package/dist/index.js +1 -191
- package/dist/preload.cjs +1 -16
- package/dist/preload.d.ts +3 -1
- package/dist/preload.js +1 -8
- package/package.json +8 -16
package/CONSUMING.md
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
# Consuming CoAkka Runtime Connector For Electron
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
## Version `3.1.1`
|
|
4
|
+
|
|
5
|
+
Electron `3.1.1` is the first Electron connector release on Core generation
|
|
6
|
+
`3.1`. It installs `coakka-v2-connector-node@3.1.2` as an exact dependency.
|
|
7
|
+
The Node connector includes Core 3.1 r2, build
|
|
8
|
+
`6789dd16210fc01f17cca4d2b66a592d1ac79121`, ABI 1, for macOS ARM64,
|
|
9
|
+
Linux ARM64/x64 and Windows ARM64/x64.
|
|
8
10
|
|
|
9
11
|
Use the package only from the Electron main process and preload boundary:
|
|
10
12
|
|
|
@@ -13,3 +15,44 @@ Use the package only from the Electron main process and preload boundary:
|
|
|
13
15
|
- renderer: call `window.coakka.intent(...)`
|
|
14
16
|
|
|
15
17
|
Do not import the runtime connector directly from renderer code.
|
|
18
|
+
|
|
19
|
+
Use Electron 42 or later and let npm install the declared Node dependency
|
|
20
|
+
when you install the Electron connector.
|
|
21
|
+
|
|
22
|
+
Keep `contextIsolation: true`, `nodeIntegration: false` and `sandbox: true` on
|
|
23
|
+
the application window. Compile your preload source into one CommonJS file
|
|
24
|
+
with a JavaScript bundler: include `coakka-v2-connector-electron/preload` in the
|
|
25
|
+
bundle and leave only `electron` external. Neither a runtime owner nor native
|
|
26
|
+
library loading belongs in the preload. The renderer receives only the
|
|
27
|
+
intent methods exposed by the context bridge, not general-purpose IPC access.
|
|
28
|
+
|
|
29
|
+
Supply `authorize` when registering main-process IPC handlers. Check the
|
|
30
|
+
window, main frame and trusted document URL using Electron's main-process
|
|
31
|
+
event; return literal `true` only for an accepted sender. Do not trust an
|
|
32
|
+
intent's `source` string as sender identity. Reject untrusted navigation and
|
|
33
|
+
window creation according to the application's policy.
|
|
34
|
+
|
|
35
|
+
Remove registered IPC handlers and await runtime close on every exit path.
|
|
36
|
+
A close does not cancel or join an application handler already executing; cancel
|
|
37
|
+
and join business tasks separately before releasing their application resources.
|
|
38
|
+
Late handler results cannot reply through the closing native owner.
|
|
39
|
+
A failed duplicate handler registration preserves the existing handler.
|
|
40
|
+
Startup snapshots report the runtime's accepted values; omitted CPU and
|
|
41
|
+
connection preferences use `AUTO` and `MULTIPLEXED`. Renderer intent deadlines
|
|
42
|
+
remain bounded (2 seconds when omitted, at most 30 seconds), and each IPC
|
|
43
|
+
batch defaults to the accepted runtime queue capacity capped at 64 values.
|
|
44
|
+
The inherited ask path requires no host worker-pool tuning; one lazy bounded
|
|
45
|
+
main-process scheduler advances Core-owned tickets without allocating one
|
|
46
|
+
worker for every ask.
|
|
47
|
+
An explicit batch maximum may not exceed that capacity or 256. Batches run in
|
|
48
|
+
input order and are not atomic: completed items are not rolled back on failure.
|
|
49
|
+
These intent limits belong to the Electron application boundary; they are
|
|
50
|
+
not a second native capability or configuration table.
|
|
51
|
+
|
|
52
|
+
## Shutdown timing
|
|
53
|
+
|
|
54
|
+
Closing retires native work before releasing its resources. Host scheduling
|
|
55
|
+
and storage affect that latency: macOS qualification observed occasional
|
|
56
|
+
Runtime/File shutdowns taking about 2.4 seconds. That observation is not a
|
|
57
|
+
hard maximum. Release application resources only after close has returned
|
|
58
|
+
or its Promise has settled.
|
package/PACKAGE-LICENSE.md
CHANGED
|
@@ -28,4 +28,4 @@ substantially equivalent infrastructure service.
|
|
|
28
28
|
It does not replace either license.
|
|
29
29
|
|
|
30
30
|
Public guidance and stable links are available in the
|
|
31
|
-
[CoAkka package licensing guide](https://github.com/phuong-tran/coakka-samples/blob/
|
|
31
|
+
[CoAkka package licensing guide](https://github.com/phuong-tran/coakka-samples/blob/83c4dd7de7290df064e79fcbbca1f470458142a0/docs/common/package-licensing.md).
|
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# CoAkka Runtime Connector For Electron
|
|
2
2
|
|
|
3
3
|
<p align="center">
|
|
4
|
-
<img src="https://raw.githubusercontent.com/phuong-tran/coakka-samples/main/docs/assets/brand/coakka-logo.png" alt="CoAkka" width="480">
|
|
4
|
+
<img src="https://raw.githubusercontent.com/phuong-tran/coakka-samples/main/docs/common/assets/brand/coakka-logo.png" alt="CoAkka" width="480">
|
|
5
5
|
</p>
|
|
6
6
|
|
|
7
7
|
**This is the Electron connector in the polyglot, multi-language,
|
|
@@ -12,15 +12,22 @@ contract used by Node.js, the JVM, Python, Go, C#, Rust, Swift, and other
|
|
|
12
12
|
connector lanes.
|
|
13
13
|
|
|
14
14
|
Kubernetes is supported but not required. Use the public
|
|
15
|
-
[Ecosystem Overview](https://github.com/phuong-tran/coakka-samples/blob/main/docs/ecosystem-overview.md)
|
|
16
|
-
and [Compatibility Matrix](https://github.com/phuong-tran/coakka-publish/blob/main/docs/compatibility-matrix.md)
|
|
15
|
+
[Ecosystem Overview](https://github.com/phuong-tran/coakka-samples/blob/main/docs/common/ecosystem-overview.md)
|
|
16
|
+
and [Compatibility Matrix](https://github.com/phuong-tran/coakka-publish/blob/main/docs/coakka-runtime/reference/compatibility-matrix.md)
|
|
17
17
|
to select an exact package and native platform tuple.
|
|
18
18
|
Start with the [CoAkka Documentation](https://github.com/phuong-tran/coakka-samples/blob/main/docs/README.md)
|
|
19
19
|
for concepts, integration paths, operations, and runnable samples.
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
Use Electron 42 or later. The Electron main process owns the runtime. Preload
|
|
22
|
+
and renderer code use a small intent API over IPC.
|
|
23
|
+
|
|
24
|
+
## Version `3.1.1`
|
|
25
|
+
|
|
26
|
+
Electron `3.1.1` is the first Electron connector release on Core generation
|
|
27
|
+
`3.1`. Its exact dependency `coakka-v2-connector-node@3.1.2` includes Core
|
|
28
|
+
3.1 r2, build `6789dd16210fc01f17cca4d2b66a592d1ac79121`, ABI 1. npm installs
|
|
29
|
+
the Node dependency automatically. Its native images cover macOS ARM64,
|
|
30
|
+
Linux ARM64/x64 and Windows ARM64/x64.
|
|
24
31
|
|
|
25
32
|
## New To CoAkka
|
|
26
33
|
|
|
@@ -36,25 +43,14 @@ Use these public repositories to orient first:
|
|
|
36
43
|
| `coakka-samples` | Runnable examples and code you can inspect first. | https://github.com/phuong-tran/coakka-samples |
|
|
37
44
|
| `coakka-publish` | Released packages, native archives, manifests, checksums, compatibility matrix, and release notes. | https://github.com/phuong-tran/coakka-publish |
|
|
38
45
|
|
|
39
|
-
|
|
46
|
+
Install the connector with npm.
|
|
40
47
|
|
|
41
48
|
```sh
|
|
42
|
-
|
|
43
|
-
cd coakka-samples
|
|
44
|
-
bash run.sh runtime electron basic
|
|
49
|
+
npm install coakka-v2-connector-electron@3.1.1
|
|
45
50
|
```
|
|
46
51
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
Samples docs directory:
|
|
51
|
-
https://github.com/phuong-tran/coakka-samples/tree/main/docs
|
|
52
|
-
|
|
53
|
-
That smoke explains the runtime mental model first: keep real HTTP or IPC at
|
|
54
|
-
the app edge, but replace fake backend HTTP used only for work owned by the
|
|
55
|
-
same app or team with a CoAkka target and explicit reply/deadletter behavior.
|
|
56
|
-
|
|
57
|
-
The boundary is intentionally strict:
|
|
52
|
+
The following example routes an intent from a sandboxed window to a named
|
|
53
|
+
handler in the main process and returns the handler's reply to the renderer.
|
|
58
54
|
|
|
59
55
|
- renderer JavaScript sends an intent through `ipcRenderer.invoke`
|
|
60
56
|
- preload exposes only a small `coakka.intent(...)` API
|
|
@@ -69,16 +65,18 @@ The main-process options can forward the shared `connectionStrategy` and
|
|
|
69
65
|
`security` startup specs. Capability/config/security getters and atomic apply
|
|
70
66
|
results are exposed on `ElectronRuntimeIntentBridge`; renderer/preload code
|
|
71
67
|
still never receives credential material. See
|
|
72
|
-
[Connection Strategies](https://github.com/phuong-tran/coakka-samples/blob/main/docs/connection-strategies.md),
|
|
73
|
-
[TLS and mTLS](https://github.com/phuong-tran/coakka-samples/blob/main/docs/tls-and-mtls.md),
|
|
74
|
-
and [Troubleshooting](https://github.com/phuong-tran/coakka-samples/blob/main/docs/troubleshooting.md).
|
|
68
|
+
[Connection Strategies](https://github.com/phuong-tran/coakka-samples/blob/main/docs/coakka-runtime/reference/connection-strategies.md),
|
|
69
|
+
[TLS and mTLS](https://github.com/phuong-tran/coakka-samples/blob/main/docs/coakka-runtime/reference/tls-and-mtls.md),
|
|
70
|
+
and [Troubleshooting](https://github.com/phuong-tran/coakka-samples/blob/main/docs/coakka-runtime/operations/troubleshooting.md).
|
|
75
71
|
|
|
76
72
|
## Main Process
|
|
77
73
|
|
|
78
74
|
```js
|
|
79
|
-
import { ipcMain } from "electron";
|
|
75
|
+
import { BrowserWindow, ipcMain } from "electron";
|
|
76
|
+
import { pathToFileURL } from "node:url";
|
|
80
77
|
import {
|
|
81
78
|
ElectronRuntimeIntentBridge,
|
|
79
|
+
localRoute,
|
|
82
80
|
registerElectronIntentIpcHandler,
|
|
83
81
|
} from "coakka-v2-connector-electron";
|
|
84
82
|
|
|
@@ -86,7 +84,7 @@ const target = "samples.electron.intent.echo";
|
|
|
86
84
|
const bridge = ElectronRuntimeIntentBridge.start({
|
|
87
85
|
systemName: "electron-app",
|
|
88
86
|
nodeId: "electron-app-main",
|
|
89
|
-
|
|
87
|
+
routes: [localRoute(target)],
|
|
90
88
|
});
|
|
91
89
|
|
|
92
90
|
bridge.registerJsonIntentHandler(target, async (intent) => ({
|
|
@@ -94,11 +92,32 @@ bridge.registerJsonIntentHandler(target, async (intent) => ({
|
|
|
94
92
|
echo: intent.payload,
|
|
95
93
|
}));
|
|
96
94
|
|
|
97
|
-
|
|
95
|
+
// app.whenReady() has resolved. These are your application's absolute paths.
|
|
96
|
+
const window = new BrowserWindow({
|
|
97
|
+
webPreferences: {
|
|
98
|
+
preload: bundledPreloadPath,
|
|
99
|
+
contextIsolation: true,
|
|
100
|
+
nodeIntegration: false,
|
|
101
|
+
sandbox: true,
|
|
102
|
+
},
|
|
103
|
+
});
|
|
104
|
+
const trustedUrl = pathToFileURL(rendererHtmlPath).href;
|
|
105
|
+
const unregister = registerElectronIntentIpcHandler(ipcMain, bridge, {
|
|
106
|
+
authorize: (event) => event.sender === window.webContents &&
|
|
107
|
+
event.senderFrame === window.webContents.mainFrame &&
|
|
108
|
+
event.senderFrame.url === trustedUrl,
|
|
109
|
+
});
|
|
110
|
+
await window.loadFile(rendererHtmlPath);
|
|
111
|
+
// At application shutdown: unregister(), then await bridge.close().
|
|
98
112
|
```
|
|
99
113
|
|
|
100
114
|
## Preload
|
|
101
115
|
|
|
116
|
+
Bundle this application-owned source into one CommonJS preload file, leaving
|
|
117
|
+
only `electron` external. A sandboxed preload cannot load arbitrary package
|
|
118
|
+
files with `require`; do not disable the sandbox to make package imports work.
|
|
119
|
+
Use that bundled file as `bundledPreloadPath` above.
|
|
120
|
+
|
|
102
121
|
```js
|
|
103
122
|
const { contextBridge, ipcRenderer } = require("electron");
|
|
104
123
|
const { createCoAkkaPreloadApi } = require("coakka-v2-connector-electron/preload");
|
|
@@ -124,42 +143,62 @@ const result = await window.coakka.intent({
|
|
|
124
143
|
});
|
|
125
144
|
```
|
|
126
145
|
|
|
127
|
-
##
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
146
|
+
## Lifecycle And Admission
|
|
147
|
+
|
|
148
|
+
For sustained renderer traffic, `intentBatch([...])` amortizes a structured-clone
|
|
149
|
+
IPC round trip. Items execute sequentially through the same runtime ask path
|
|
150
|
+
and preserve order. The default maximum is the accepted queue capacity capped
|
|
151
|
+
at 64 intents; an explicit maximum cannot exceed that capacity or 256. A batch
|
|
152
|
+
is not atomic: earlier items remain completed if a later item fails, and later
|
|
153
|
+
items are not started. Prefer single intents for individual completion latency.
|
|
154
|
+
|
|
155
|
+
The application must authorize every single and batch IPC invocation. Only an
|
|
156
|
+
explicit `true` permits delivery; exceptions and every other value reject the
|
|
157
|
+
invocation. Match the expected window, main frame and trusted document, not
|
|
158
|
+
just a renderer-supplied source name. Remove IPC handlers when their owner
|
|
159
|
+
closes. Do not expose `ipcRenderer` itself through the context bridge.
|
|
160
|
+
|
|
161
|
+
Startup options are submitted to the native runtime; use
|
|
162
|
+
`runtimeStartupConfig()` for accepted configuration rather than reconstructing
|
|
163
|
+
it from input. Omitted policy uses `AUTO` and `MULTIPLEXED`. Main owns handlers
|
|
164
|
+
and runtime lifetime; a refused duplicate registration leaves the accepted
|
|
165
|
+
handler intact. Await `close()` to retire native ownership and registered
|
|
166
|
+
callbacks; a reader waiting for handler capacity is also awakened. Close does
|
|
167
|
+
not cancel or join already-running application handlers. Their late results
|
|
168
|
+
cannot submit native replies after close begins. Cancel/join application tasks
|
|
169
|
+
separately before releasing resources those tasks still use.
|
|
170
|
+
File and Stream Lane owners must also be explicitly closed by their owners.
|
|
171
|
+
|
|
172
|
+
Electron inherits the Node package's lazy bounded ask scheduler in the main
|
|
173
|
+
process. It requires no host worker-pool tuning and does not allocate one worker
|
|
174
|
+
per ask. The Electron wrapper adds no second scheduler or response matcher;
|
|
175
|
+
Core still owns ticket matching, timeout/cancellation and completion notifications.
|
|
176
|
+
|
|
177
|
+
Read the bundled `CONSUMING.md` for preload and renderer setup. The
|
|
178
|
+
[current package ledger](https://github.com/phuong-tran/coakka-samples/blob/main/docs/common/current-packages.md)
|
|
179
|
+
records registry availability.
|
|
141
180
|
|
|
142
181
|
## File Lane
|
|
143
182
|
|
|
144
183
|
The Node dependency exposes `FileLane` to trusted Electron main-process code.
|
|
145
184
|
Do not forward raw file paths, authorization tokens, or lane methods through
|
|
146
|
-
preload/renderer IPC. See the shared [file-lane contract](https://github.com/phuong-tran/coakka-samples/blob/main/docs/runtime-file-transfer.md).
|
|
185
|
+
preload/renderer IPC. See the shared [file-lane contract](https://github.com/phuong-tran/coakka-samples/blob/main/docs/coakka-runtime/guides/runtime-file-transfer.md).
|
|
147
186
|
|
|
148
187
|
## Stream Lane
|
|
149
188
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
[streaming contract](https://github.com/phuong-tran/coakka-samples/blob/main/docs/runtime-streaming.md).
|
|
189
|
+
The matching Node dependency provides owner-aware File and Stream Lane surfaces
|
|
190
|
+
for trusted Electron main-process code. Keep runtime ownership in the main
|
|
191
|
+
process and follow the public
|
|
192
|
+
[streaming contract](https://github.com/phuong-tran/coakka-samples/blob/main/docs/coakka-runtime/guides/runtime-streaming.md).
|
|
154
193
|
Electron re-exports Node's `FileReceiveGrant`, `StreamPublishGrant`, and
|
|
155
194
|
`openOwned`/`prepare*Grant` methods only to main-process code. Follow the
|
|
156
|
-
[owner-grant ONE/ALL sample](https://github.com/phuong-tran/coakka-samples/blob/main/docs/runtime-lane-owner-grants.md)
|
|
195
|
+
[owner-grant ONE/ALL sample](https://github.com/phuong-tran/coakka-samples/blob/main/docs/coakka-runtime/reference/runtime-lane-owner-grants.md)
|
|
157
196
|
and keep serialized grants out of preload and renderer IPC.
|
|
158
197
|
|
|
159
198
|
## AI-Assisted Integration
|
|
160
199
|
|
|
161
200
|
Before generating Electron integration code, read the public
|
|
162
|
-
[AI-assisted integration guide](https://github.com/phuong-tran/coakka-samples/blob/main/docs/ai-assisted-integration.md)
|
|
201
|
+
[AI-assisted integration guide](https://github.com/phuong-tran/coakka-samples/blob/main/docs/coakka-runtime/guides/ai-assisted-integration.md)
|
|
163
202
|
and the runnable Electron sample. Connection policy and native lane ownership
|
|
164
203
|
belong to Electron main; renderer code sends validated intent only.
|
|
165
204
|
|
|
@@ -170,11 +209,11 @@ belong to Electron main; renderer code sends validated intent only.
|
|
|
170
209
|
|
|
171
210
|
Connector source, generated bindings, type declarations, examples, and package
|
|
172
211
|
documentation use the [Apache License, Version 2.0](https://github.com/phuong-tran/coakka-samples/blob/main/LICENSE).
|
|
173
|
-
|
|
212
|
+
Native Core files in the Node dependency use the [CoAkka Native Artifact License 1.2](https://github.com/phuong-tran/coakka-samples/blob/main/NATIVE-LICENSE.md).
|
|
174
213
|
Those native terms permit ordinary application and SaaS use but require a
|
|
175
214
|
separate agreement to sell or offer CoAkka itself as managed runtime or
|
|
176
215
|
infrastructure.
|
|
177
216
|
|
|
178
|
-
See [CoAkka Package Licensing](https://github.com/phuong-tran/coakka-samples/blob/main/docs/package-licensing.md)
|
|
217
|
+
See [CoAkka Package Licensing](https://github.com/phuong-tran/coakka-samples/blob/main/docs/common/package-licensing.md)
|
|
179
218
|
for the file-scope map. The package also carries offline `LICENSE`,
|
|
180
219
|
`NATIVE-LICENSE.md`, `PACKAGE-LICENSE.md`, and `NOTICE` copies.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { type RuntimeCapabilitiesSnapshot, type RuntimeTcpConnectionApplyResult, type RuntimeTcpConnectionConfigSnapshot, type RuntimeTcpConnectionStrategySpec, type RuntimeTcpSecurityApplyResult, type RuntimeTcpSecurityInfoSnapshot, type RuntimeTcpSecuritySpec } from "coakka-v2-connector-node";
|
|
2
|
-
export { RuntimeCapability, RuntimeTcpConnectionMode, RuntimeTcpSecurityMode, RuntimeTlsReloadMode, supportsRuntimeCapabilities, } from "coakka-v2-connector-node";
|
|
1
|
+
import { type ConnectorStartSpec, type RuntimeClientStats, type RuntimeCapabilitiesSnapshot, type RuntimeDeliverySnapshot, type RuntimeInfoSnapshot, type RuntimeStartupSnapshot, type RuntimeTcpConnectionApplyResult, type RuntimeTcpConnectionConfigSnapshot, type RuntimeTcpConnectionStrategySpec, type RuntimeTcpSecurityApplyResult, type RuntimeTcpSecurityInfoSnapshot, type RuntimeTcpSecuritySpec } from "coakka-v2-connector-node";
|
|
2
|
+
export { EndpointFlag, RuntimeCapability, RuntimeNetworkMode, RuntimeTcpConnectionMode, RuntimeTcpSecurityMode, RuntimeTlsReloadMode, RouteStrategy, embeddedNetwork, localRoute, networkNode, outboundOnlyNetwork, supportsRuntimeCapabilities, type EndpointSpec, type RouteSpec, type RuntimeNetworkConfig, } from "coakka-v2-connector-node";
|
|
3
3
|
/**
|
|
4
4
|
* File and Stream Lanes are available only to trusted Electron main-process
|
|
5
5
|
* code. They are intentionally absent from preload and renderer intents so
|
|
6
6
|
* file paths and bearer grants never cross that boundary implicitly.
|
|
7
7
|
*/
|
|
8
8
|
export { FILE_LANE_DETAIL_MAX_BYTES, FILE_LANE_SHA256_BYTES, LANE_OWNER_GRANTS_FEATURE, FileLane, FileLaneError, FileLaneFlag, FileLaneSecurityMode, FileReceiveGrant, FileTransferDirection, FileTransferResult, FileTransferState, LaneOwnerGrantUnavailableError, STREAM_LANE_DETAIL_MAX_BYTES, STREAM_LANE_MAX_FRAME_BYTES, STREAM_LANE_MAX_WINDOW_BYTES, StreamConsumerDecision, StreamDirection, StreamFrameFlag, StreamLane, StreamLaneError, StreamLaneFlag, StreamLaneSecurityMode, StreamPublishGrant, StreamPressureReason, StreamPressureState, StreamResult, StreamSourceSignal, StreamState, type FileDigest, type FileLaneConfig, type FileLaneSecurityConfig, type FileLaneStats, type FileReceiveSpec, type FileSendSpec, type FileTransferSnapshot, type LaneOwnerConfig, type LaneOwnerEndpoint, type StreamConsumer, type StreamFrameMetadata, type StreamLaneConfig, type StreamLaneSecurityConfig, type StreamLaneStats, type StreamPressureSnapshot, type StreamPublishSpec, type StreamSessionSnapshot, type StreamSource, type StreamSourceFrame, type StreamSubscribeSpec, } from "coakka-v2-connector-node";
|
|
9
|
-
export declare const COAKKA_ELECTRON_CONNECTOR_VERSION = "
|
|
9
|
+
export declare const COAKKA_ELECTRON_CONNECTOR_VERSION = "3.1.1";
|
|
10
10
|
export declare const COAKKA_ELECTRON_INTENT_CHANNEL = "coakka:intent";
|
|
11
|
+
export declare const COAKKA_ELECTRON_INTENT_BATCH_CHANNEL = "coakka:intent-batch";
|
|
11
12
|
export interface ElectronIntentPayloadIdentity {
|
|
12
13
|
messageType: string;
|
|
13
14
|
payloadSchemaVersion?: number;
|
|
@@ -29,47 +30,50 @@ export interface ElectronIntentResult {
|
|
|
29
30
|
target: string;
|
|
30
31
|
operation: string;
|
|
31
32
|
payload: Record<string, unknown>;
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
matchedDeadletters: number;
|
|
33
|
+
payloadIdentity: {
|
|
34
|
+
messageType: string;
|
|
35
|
+
payloadSchemaVersion: number;
|
|
36
|
+
payloadFormat: "json";
|
|
37
37
|
};
|
|
38
38
|
}
|
|
39
|
-
export interface ElectronRuntimeIntentBridgeOptions {
|
|
40
|
-
systemName: string;
|
|
41
|
-
nodeId: string;
|
|
42
|
-
defaultTarget: string;
|
|
43
|
-
routePort?: number;
|
|
44
|
-
queueCapacity?: number;
|
|
45
|
-
strictNoDrop?: boolean;
|
|
39
|
+
export interface ElectronRuntimeIntentBridgeOptions extends ConnectorStartSpec {
|
|
46
40
|
runtimeLibPath?: string;
|
|
47
|
-
connectionStrategy?: RuntimeTcpConnectionStrategySpec;
|
|
48
|
-
security?: RuntimeTcpSecuritySpec;
|
|
49
41
|
}
|
|
50
42
|
export type ElectronJsonIntentHandler = (intent: ElectronIntentEnvelope) => Record<string, unknown> | Promise<Record<string, unknown>>;
|
|
51
43
|
export interface IpcMainLike {
|
|
52
|
-
handle(channel: string, listener: (event: unknown,
|
|
44
|
+
handle(channel: string, listener: (event: unknown, payload: unknown) => Promise<unknown>): void;
|
|
53
45
|
removeHandler(channel: string): void;
|
|
54
46
|
}
|
|
47
|
+
export interface ElectronIntentIpcRegistrationOptions {
|
|
48
|
+
channel?: string;
|
|
49
|
+
batchChannel?: string;
|
|
50
|
+
/** Defaults to Core's accepted queue capacity, capped at 64 IPC values. */
|
|
51
|
+
maximumBatchSize?: number;
|
|
52
|
+
/** App-owned sender/frame trust decision; only literal true permits dispatch. */
|
|
53
|
+
authorize(event: unknown): boolean | Promise<boolean>;
|
|
54
|
+
}
|
|
55
55
|
export declare class ElectronRuntimeIntentBridge {
|
|
56
56
|
private readonly runtimeHost;
|
|
57
|
-
readonly defaultTarget: string;
|
|
58
57
|
static start(options: ElectronRuntimeIntentBridgeOptions): ElectronRuntimeIntentBridge;
|
|
59
58
|
private readonly handlers;
|
|
60
59
|
private closed;
|
|
60
|
+
private closePromise;
|
|
61
61
|
private constructor();
|
|
62
62
|
registerJsonIntentHandler(target: string, handler: ElectronJsonIntentHandler): void;
|
|
63
63
|
handleIntent(intent: ElectronIntentEnvelope): Promise<ElectronIntentResult>;
|
|
64
|
+
runtimeInfo(): RuntimeInfoSnapshot;
|
|
65
|
+
/** Connector-owned counters for trusted main-process diagnostics only. */
|
|
66
|
+
connectorStats(): RuntimeClientStats;
|
|
67
|
+
runtimeStartupConfig(): RuntimeStartupSnapshot & {
|
|
68
|
+
delivery: RuntimeDeliverySnapshot;
|
|
69
|
+
};
|
|
64
70
|
runtimeCapabilities(): RuntimeCapabilitiesSnapshot;
|
|
65
71
|
tcpConnectionConfig(): RuntimeTcpConnectionConfigSnapshot;
|
|
66
72
|
tcpSecurityInfo(): RuntimeTcpSecurityInfoSnapshot;
|
|
67
|
-
startupConnectionResult(): RuntimeTcpConnectionApplyResult | null;
|
|
68
|
-
startupSecurityResult(): RuntimeTcpSecurityApplyResult | null;
|
|
69
73
|
applyTcpConnectionStrategy(spec: RuntimeTcpConnectionStrategySpec): RuntimeTcpConnectionApplyResult;
|
|
70
74
|
applyTcpSecurity(spec: RuntimeTcpSecuritySpec): RuntimeTcpSecurityApplyResult;
|
|
71
|
-
close(): void
|
|
75
|
+
close(): Promise<void>;
|
|
72
76
|
private createRuntimeHandler;
|
|
73
77
|
private requireOpen;
|
|
74
78
|
}
|
|
75
|
-
export declare function registerElectronIntentIpcHandler(ipcMain: IpcMainLike, bridge: ElectronRuntimeIntentBridge,
|
|
79
|
+
export declare function registerElectronIntentIpcHandler(ipcMain: IpcMainLike, bridge: ElectronRuntimeIntentBridge, options: ElectronIntentIpcRegistrationOptions): () => void;
|
package/dist/index.js
CHANGED
|
@@ -1,191 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export { RuntimeCapability, RuntimeTcpConnectionMode, RuntimeTcpSecurityMode, RuntimeTlsReloadMode, supportsRuntimeCapabilities, } from "coakka-v2-connector-node";
|
|
3
|
-
/**
|
|
4
|
-
* File and Stream Lanes are available only to trusted Electron main-process
|
|
5
|
-
* code. They are intentionally absent from preload and renderer intents so
|
|
6
|
-
* file paths and bearer grants never cross that boundary implicitly.
|
|
7
|
-
*/
|
|
8
|
-
export { FILE_LANE_DETAIL_MAX_BYTES, FILE_LANE_SHA256_BYTES, LANE_OWNER_GRANTS_FEATURE, FileLane, FileLaneError, FileLaneFlag, FileLaneSecurityMode, FileReceiveGrant, FileTransferDirection, FileTransferResult, FileTransferState, LaneOwnerGrantUnavailableError, STREAM_LANE_DETAIL_MAX_BYTES, STREAM_LANE_MAX_FRAME_BYTES, STREAM_LANE_MAX_WINDOW_BYTES, StreamConsumerDecision, StreamDirection, StreamFrameFlag, StreamLane, StreamLaneError, StreamLaneFlag, StreamLaneSecurityMode, StreamPublishGrant, StreamPressureReason, StreamPressureState, StreamResult, StreamSourceSignal, StreamState, } from "coakka-v2-connector-node";
|
|
9
|
-
export const COAKKA_ELECTRON_CONNECTOR_VERSION = "2.5.3";
|
|
10
|
-
export const COAKKA_ELECTRON_INTENT_CHANNEL = "coakka:intent";
|
|
11
|
-
const DEFAULT_ROUTE_PORT = 19481;
|
|
12
|
-
export class ElectronRuntimeIntentBridge {
|
|
13
|
-
runtimeHost;
|
|
14
|
-
defaultTarget;
|
|
15
|
-
static start(options) {
|
|
16
|
-
const target = requireNonBlank(options.defaultTarget, "defaultTarget");
|
|
17
|
-
const startSpec = {
|
|
18
|
-
systemName: requireNonBlank(options.systemName, "systemName"),
|
|
19
|
-
nodeId: requireNonBlank(options.nodeId, "nodeId"),
|
|
20
|
-
queueCapacity: options.queueCapacity ?? 64,
|
|
21
|
-
strictNoDrop: options.strictNoDrop ?? true,
|
|
22
|
-
generation: 1,
|
|
23
|
-
connectionStrategy: options.connectionStrategy,
|
|
24
|
-
security: options.security,
|
|
25
|
-
routes: [
|
|
26
|
-
{
|
|
27
|
-
target,
|
|
28
|
-
endpoints: [
|
|
29
|
-
{
|
|
30
|
-
host: "127.0.0.1",
|
|
31
|
-
port: options.routePort ?? DEFAULT_ROUTE_PORT,
|
|
32
|
-
flags: EndpointFlag.LOCAL,
|
|
33
|
-
},
|
|
34
|
-
],
|
|
35
|
-
},
|
|
36
|
-
],
|
|
37
|
-
};
|
|
38
|
-
return new ElectronRuntimeIntentBridge(RuntimeHost.start(startSpec, options.runtimeLibPath), target);
|
|
39
|
-
}
|
|
40
|
-
handlers = new Map();
|
|
41
|
-
closed = false;
|
|
42
|
-
constructor(runtimeHost, defaultTarget) {
|
|
43
|
-
this.runtimeHost = runtimeHost;
|
|
44
|
-
this.defaultTarget = defaultTarget;
|
|
45
|
-
}
|
|
46
|
-
registerJsonIntentHandler(target, handler) {
|
|
47
|
-
const normalizedTarget = requireNonBlank(target, "target");
|
|
48
|
-
this.handlers.set(normalizedTarget, handler);
|
|
49
|
-
this.runtimeHost.registerHandler(normalizedTarget, this.createRuntimeHandler(normalizedTarget), true);
|
|
50
|
-
}
|
|
51
|
-
async handleIntent(intent) {
|
|
52
|
-
this.requireOpen();
|
|
53
|
-
const normalized = normalizeIntent(intent);
|
|
54
|
-
const identity = toPayloadIdentity(normalized.payloadIdentity);
|
|
55
|
-
const response = await this.runtimeHost.askJson(normalized.source, normalized.target, normalized.payload, identity, normalized.timeoutMs ?? 2_000, normalized.operation, DeliveryHint.ROUTER_DEFAULT, normalized.headers ?? {});
|
|
56
|
-
const clientStats = this.runtimeHost.clientStats();
|
|
57
|
-
const runtimeStats = this.runtimeHost.stats();
|
|
58
|
-
return {
|
|
59
|
-
intentId: normalized.intentId,
|
|
60
|
-
source: normalized.source,
|
|
61
|
-
target: normalized.target,
|
|
62
|
-
operation: normalized.operation,
|
|
63
|
-
payload: response,
|
|
64
|
-
runtime: {
|
|
65
|
-
generation: runtimeStats.appliedGeneration,
|
|
66
|
-
delivered: clientStats.deliveredRequests,
|
|
67
|
-
matchedResponses: clientStats.matchedResponses,
|
|
68
|
-
matchedDeadletters: clientStats.matchedDeadletters,
|
|
69
|
-
},
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
runtimeCapabilities() {
|
|
73
|
-
return this.runtimeHost.runtimeCapabilities();
|
|
74
|
-
}
|
|
75
|
-
tcpConnectionConfig() {
|
|
76
|
-
return this.runtimeHost.tcpConnectionConfig();
|
|
77
|
-
}
|
|
78
|
-
tcpSecurityInfo() {
|
|
79
|
-
return this.runtimeHost.tcpSecurityInfo();
|
|
80
|
-
}
|
|
81
|
-
startupConnectionResult() {
|
|
82
|
-
return this.runtimeHost.startupConnectionResult();
|
|
83
|
-
}
|
|
84
|
-
startupSecurityResult() {
|
|
85
|
-
return this.runtimeHost.startupSecurityResult();
|
|
86
|
-
}
|
|
87
|
-
applyTcpConnectionStrategy(spec) {
|
|
88
|
-
return this.runtimeHost.applyTcpConnectionStrategy(spec);
|
|
89
|
-
}
|
|
90
|
-
applyTcpSecurity(spec) {
|
|
91
|
-
return this.runtimeHost.applyTcpSecurity(spec);
|
|
92
|
-
}
|
|
93
|
-
close() {
|
|
94
|
-
if (this.closed) {
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
this.closed = true;
|
|
98
|
-
this.runtimeHost.close();
|
|
99
|
-
}
|
|
100
|
-
createRuntimeHandler(target) {
|
|
101
|
-
return async (request) => {
|
|
102
|
-
const handler = this.handlers.get(target);
|
|
103
|
-
if (handler == null) {
|
|
104
|
-
throw new Error(`no Electron intent handler registered for target=${target}`);
|
|
105
|
-
}
|
|
106
|
-
const payload = JSON.parse(Buffer.from(request.payload).toString("utf8"));
|
|
107
|
-
const resultPayload = await handler({
|
|
108
|
-
intentId: request.message_id,
|
|
109
|
-
source: request.source,
|
|
110
|
-
target,
|
|
111
|
-
operation: "intent",
|
|
112
|
-
payload,
|
|
113
|
-
payloadIdentity: {
|
|
114
|
-
messageType: request.message_type,
|
|
115
|
-
payloadSchemaVersion: request.payload_schema_version,
|
|
116
|
-
payloadFormat: "json",
|
|
117
|
-
},
|
|
118
|
-
headers: request.headers,
|
|
119
|
-
});
|
|
120
|
-
return NodeRuntimeClient.makeJsonReplyFromRequestIdentity(request, target, resultPayload);
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
requireOpen() {
|
|
124
|
-
if (this.closed) {
|
|
125
|
-
throw new Error("Electron runtime intent bridge is closed");
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
export function registerElectronIntentIpcHandler(ipcMain, bridge, channel = COAKKA_ELECTRON_INTENT_CHANNEL) {
|
|
130
|
-
ipcMain.handle(channel, async (_event, intent) => bridge.handleIntent(intent));
|
|
131
|
-
return () => ipcMain.removeHandler(channel);
|
|
132
|
-
}
|
|
133
|
-
function normalizeIntent(intent) {
|
|
134
|
-
if (intent == null || typeof intent !== "object") {
|
|
135
|
-
throw new Error("intent envelope is required");
|
|
136
|
-
}
|
|
137
|
-
return {
|
|
138
|
-
intentId: requireNonBlank(intent.intentId, "intentId"),
|
|
139
|
-
source: requireNonBlank(intent.source, "source"),
|
|
140
|
-
target: requireNonBlank(intent.target, "target"),
|
|
141
|
-
operation: requireNonBlank(intent.operation, "operation"),
|
|
142
|
-
payload: requireJsonObject(intent.payload, "payload"),
|
|
143
|
-
payloadIdentity: requirePayloadIdentity(intent.payloadIdentity),
|
|
144
|
-
timeoutMs: normalizeTimeout(intent.timeoutMs),
|
|
145
|
-
headers: normalizeHeaders(intent.headers),
|
|
146
|
-
};
|
|
147
|
-
}
|
|
148
|
-
function toPayloadIdentity(identity) {
|
|
149
|
-
return new PayloadIdentity(identity.messageType, identity.payloadSchemaVersion ?? 1, PayloadFormat.JSON).requireTyped("Electron intent payloadIdentity");
|
|
150
|
-
}
|
|
151
|
-
function requirePayloadIdentity(identity) {
|
|
152
|
-
if (identity == null || typeof identity !== "object") {
|
|
153
|
-
throw new Error("payloadIdentity is required");
|
|
154
|
-
}
|
|
155
|
-
return {
|
|
156
|
-
messageType: requireNonBlank(identity.messageType, "payloadIdentity.messageType"),
|
|
157
|
-
payloadSchemaVersion: identity.payloadSchemaVersion ?? 1,
|
|
158
|
-
payloadFormat: "json",
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
function requireJsonObject(value, what) {
|
|
162
|
-
if (value == null || typeof value !== "object" || Array.isArray(value)) {
|
|
163
|
-
throw new Error(`${what} must be a JSON object`);
|
|
164
|
-
}
|
|
165
|
-
return value;
|
|
166
|
-
}
|
|
167
|
-
function normalizeHeaders(headers) {
|
|
168
|
-
if (headers == null) {
|
|
169
|
-
return {};
|
|
170
|
-
}
|
|
171
|
-
const normalized = {};
|
|
172
|
-
for (const [key, value] of Object.entries(headers)) {
|
|
173
|
-
normalized[requireNonBlank(key, "header key")] = String(value);
|
|
174
|
-
}
|
|
175
|
-
return normalized;
|
|
176
|
-
}
|
|
177
|
-
function normalizeTimeout(timeoutMs) {
|
|
178
|
-
if (timeoutMs == null) {
|
|
179
|
-
return undefined;
|
|
180
|
-
}
|
|
181
|
-
if (!Number.isInteger(timeoutMs) || timeoutMs < 1) {
|
|
182
|
-
throw new Error("timeoutMs must be a positive integer");
|
|
183
|
-
}
|
|
184
|
-
return timeoutMs;
|
|
185
|
-
}
|
|
186
|
-
function requireNonBlank(value, what) {
|
|
187
|
-
if (typeof value !== "string" || value.trim() === "") {
|
|
188
|
-
throw new Error(`${what} is required`);
|
|
189
|
-
}
|
|
190
|
-
return value;
|
|
191
|
-
}
|
|
1
|
+
var S=Object.defineProperty;var a=(e,t)=>S(e,"name",{value:t,configurable:!0});import{DeliveryHint as w,NodeRuntimeClient as T,PayloadFormat as y,PayloadIdentity as f,RuntimeHost as I}from"coakka-v2-connector-node";import{EndpointFlag as z,RuntimeCapability as j,RuntimeNetworkMode as k,RuntimeTcpConnectionMode as B,RuntimeTcpSecurityMode as x,RuntimeTlsReloadMode as D,RouteStrategy as J,embeddedNetwork as V,localRoute as $,networkNode as v,outboundOnlyNetwork as K,supportsRuntimeCapabilities as U}from"coakka-v2-connector-node";import{FILE_LANE_DETAIL_MAX_BYTES as Y,FILE_LANE_SHA256_BYTES as G,LANE_OWNER_GRANTS_FEATURE as W,FileLane as Q,FileLaneError as Z,FileLaneFlag as ee,FileLaneSecurityMode as te,FileReceiveGrant as re,FileTransferDirection as ne,FileTransferResult as oe,FileTransferState as ae,LaneOwnerGrantUnavailableError as ie,STREAM_LANE_DETAIL_MAX_BYTES as se,STREAM_LANE_MAX_FRAME_BYTES as ue,STREAM_LANE_MAX_WINDOW_BYTES as le,StreamConsumerDecision as ce,StreamDirection as me,StreamFrameFlag as de,StreamLane as pe,StreamLaneError as he,StreamLaneFlag as ye,StreamLaneSecurityMode as fe,StreamPublishGrant as Ee,StreamPressureReason as Se,StreamPressureState as we,StreamResult as Te,StreamSourceSignal as Ie,StreamState as ge}from"coakka-v2-connector-node";var L="3.1.1",g="coakka:intent",_="coakka:intent-batch",C=2e3,p=3e4,h=class e{static{a(this,"ElectronRuntimeIntentBridge")}runtimeHost;static start(t){let{runtimeLibPath:r,...n}=t;return new e(I.start(n,r))}handlers=new Map;closed=!1;closePromise=null;constructor(t){this.runtimeHost=t}registerJsonIntentHandler(t,r){this.requireOpen();let n=i(t,"target");if(typeof r!="function")throw new TypeError("Electron intent handler must be a function");this.runtimeHost.registerHandler(n,this.createRuntimeHandler(n),!0),this.handlers.set(n,r)}async handleIntent(t){this.requireOpen();let r=N(t),n=O(r.payloadIdentity),o=await this.runtimeHost.askTyped(r.source,r.target,Buffer.from(JSON.stringify(r.payload)),n,r.timeoutMs??C,r.operation,w.ROUTER_DEFAULT,r.headers??{}),s=new f(o.message_type,o.payload_schema_version,o.payload_format).requireTyped("Electron intent response");if(s.payloadFormat!==y.JSON)throw new Error("Electron intent response payloadFormat must be json");let u=m(JSON.parse(Buffer.from(o.payload).toString("utf8")),"response payload");return{intentId:r.intentId,source:r.source,target:r.target,operation:r.operation,payload:u,payloadIdentity:{messageType:s.messageType,payloadSchemaVersion:s.payloadSchemaVersion,payloadFormat:"json"}}}runtimeInfo(){return this.requireOpen(),this.runtimeHost.runtimeInfo()}connectorStats(){return this.requireOpen(),this.runtimeHost.clientStats()}runtimeStartupConfig(){return this.requireOpen(),this.runtimeHost.runtimeStartupConfig()}runtimeCapabilities(){return this.requireOpen(),this.runtimeHost.runtimeCapabilities()}tcpConnectionConfig(){return this.requireOpen(),this.runtimeHost.tcpConnectionConfig()}tcpSecurityInfo(){return this.requireOpen(),this.runtimeHost.tcpSecurityInfo()}applyTcpConnectionStrategy(t){return this.requireOpen(),this.runtimeHost.applyTcpConnectionStrategy(t)}applyTcpSecurity(t){return this.requireOpen(),this.runtimeHost.applyTcpSecurity(t)}close(){return this.closePromise!=null?this.closePromise:(this.closed=!0,this.handlers.clear(),this.closePromise=this.runtimeHost.close(),this.closePromise)}createRuntimeHandler(t){return async r=>{let n=this.handlers.get(t);if(n==null)throw new Error(`no Electron intent handler registered for target=${t}`);let o=m(JSON.parse(Buffer.from(r.payload).toString("utf8")),"request payload"),s=await n({intentId:r.message_id,source:r.source,target:t,operation:i(r.headers.operation,"request operation"),payload:o,payloadIdentity:{messageType:r.message_type,payloadSchemaVersion:r.payload_schema_version,payloadFormat:"json"},headers:r.headers});return T.makeJsonReplyFromRequestIdentity(r,t,m(s,"handler response payload"))}}requireOpen(){if(this.closed)throw new Error("Electron runtime intent bridge is closed")}};function P(e,t,r){let n=i(r.channel??g,"IPC channel"),o=i(r.batchChannel??_,"IPC batch channel");if(n===o)throw new Error("Electron intent and batch IPC channels must be distinct");if(typeof r.authorize!="function")throw new Error("Electron intent IPC registration requires an authorize policy");let s=t.runtimeStartupConfig().queueCapacity,u=r.maximumBatchSize??Math.min(s,64);if(!Number.isInteger(u)||u<1||u>s||u>256)throw new Error(`maximumBatchSize must be an integer in 1..${Math.min(s,256)}`);e.handle(n,async(c,l)=>{if(await r.authorize(c)!==!0)throw new Error("Electron intent IPC sender is not authorized");return t.handleIntent(l)});try{e.handle(o,async(c,l)=>{if(await r.authorize(c)!==!0)throw new Error("Electron intent IPC sender is not authorized");if(!Array.isArray(l)||l.length<1||l.length>u)throw new Error(`Electron intent batch must contain 1..${u} intents`);let d=[];for(let E of l)d.push(await t.handleIntent(E));return d})}catch(c){throw e.removeHandler(n),c}return()=>{e.removeHandler(n),e.removeHandler(o)}}a(P,"registerElectronIntentIpcHandler");function N(e){if(e==null||typeof e!="object")throw new Error("intent envelope is required");return{intentId:i(e.intentId,"intentId"),source:i(e.source,"source"),target:i(e.target,"target"),operation:i(e.operation,"operation"),payload:m(e.payload,"payload"),payloadIdentity:A(e.payloadIdentity),timeoutMs:R(e.timeoutMs),headers:b(e.headers)}}a(N,"normalizeIntent");function O(e){return new f(e.messageType,e.payloadSchemaVersion??1,y.JSON).requireTyped("Electron intent payloadIdentity")}a(O,"toPayloadIdentity");function A(e){if(e==null||typeof e!="object")throw new Error("payloadIdentity is required");if(e.payloadFormat!=null&&e.payloadFormat!=="json")throw new Error("payloadIdentity.payloadFormat must be json");let t=e.payloadSchemaVersion??1;if(!Number.isInteger(t)||t<1||t>4294967295)throw new Error("payloadIdentity.payloadSchemaVersion must be an integer in 1..4294967295");return{messageType:i(e.messageType,"payloadIdentity.messageType"),payloadSchemaVersion:t,payloadFormat:"json"}}a(A,"requirePayloadIdentity");function m(e,t){if(e==null||typeof e!="object"||Array.isArray(e))throw new Error(`${t} must be a JSON object`);return e}a(m,"requireJsonObject");function b(e){if(e==null)return{};let t=Object.create(null);for(let[r,n]of Object.entries(e)){let o=i(r,"header key");if(["method","operation"].includes(o.toLowerCase()))throw new Error(`headers.${o} is reserved by the intent envelope`);if(typeof n!="string")throw new Error(`headers.${o} must be a string`);t[o]=n}return t}a(b,"normalizeHeaders");function R(e){if(e!=null){if(!Number.isInteger(e)||e<1||e>p)throw new Error(`timeoutMs must be an integer in 1..${p}`);return e}}a(R,"normalizeTimeout");function i(e,t){if(typeof e!="string"||e.trim()==="")throw new Error(`${t} is required`);return e}a(i,"requireNonBlank");export{L as COAKKA_ELECTRON_CONNECTOR_VERSION,_ as COAKKA_ELECTRON_INTENT_BATCH_CHANNEL,g as COAKKA_ELECTRON_INTENT_CHANNEL,h as ElectronRuntimeIntentBridge,z as EndpointFlag,Y as FILE_LANE_DETAIL_MAX_BYTES,G as FILE_LANE_SHA256_BYTES,Q as FileLane,Z as FileLaneError,ee as FileLaneFlag,te as FileLaneSecurityMode,re as FileReceiveGrant,ne as FileTransferDirection,oe as FileTransferResult,ae as FileTransferState,W as LANE_OWNER_GRANTS_FEATURE,ie as LaneOwnerGrantUnavailableError,J as RouteStrategy,j as RuntimeCapability,k as RuntimeNetworkMode,B as RuntimeTcpConnectionMode,x as RuntimeTcpSecurityMode,D as RuntimeTlsReloadMode,se as STREAM_LANE_DETAIL_MAX_BYTES,ue as STREAM_LANE_MAX_FRAME_BYTES,le as STREAM_LANE_MAX_WINDOW_BYTES,ce as StreamConsumerDecision,me as StreamDirection,de as StreamFrameFlag,pe as StreamLane,he as StreamLaneError,ye as StreamLaneFlag,fe as StreamLaneSecurityMode,Se as StreamPressureReason,we as StreamPressureState,Ee as StreamPublishGrant,Te as StreamResult,Ie as StreamSourceSignal,ge as StreamState,V as embeddedNetwork,$ as localRoute,v as networkNode,K as outboundOnlyNetwork,P as registerElectronIntentIpcHandler,U as supportsRuntimeCapabilities};
|
package/dist/preload.cjs
CHANGED
|
@@ -1,16 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
const COAKKA_ELECTRON_INTENT_CHANNEL = "coakka:intent";
|
|
4
|
-
|
|
5
|
-
function createCoAkkaPreloadApi(ipcRenderer, channel = COAKKA_ELECTRON_INTENT_CHANNEL) {
|
|
6
|
-
return {
|
|
7
|
-
intent(intent) {
|
|
8
|
-
return ipcRenderer.invoke(channel, intent);
|
|
9
|
-
},
|
|
10
|
-
};
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
module.exports = {
|
|
14
|
-
COAKKA_ELECTRON_INTENT_CHANNEL,
|
|
15
|
-
createCoAkkaPreloadApi,
|
|
16
|
-
};
|
|
1
|
+
"use strict";var o=Object.defineProperty;var s=Object.getOwnPropertyDescriptor;var A=Object.getOwnPropertyNames;var k=Object.prototype.hasOwnProperty;var E=(r,t)=>o(r,"name",{value:t,configurable:!0});var C=(r,t)=>{for(var n in t)o(r,n,{get:t[n],enumerable:!0})},u=(r,t,n,e)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of A(t))!k.call(r,i)&&i!==n&&o(r,i,{get:()=>t[i],enumerable:!(e=s(t,i))||e.enumerable});return r};var T=r=>u(o({},"__esModule",{value:!0}),r);var a={};C(a,{COAKKA_ELECTRON_INTENT_BATCH_CHANNEL:()=>N,COAKKA_ELECTRON_INTENT_CHANNEL:()=>c,createCoAkkaPreloadApi:()=>_});module.exports=T(a);var c="coakka:intent",N="coakka:intent-batch";function _(r,t=c,n=N){if(typeof t!="string"||t.trim()==="")throw new Error("Electron intent IPC channel is required");if(typeof n!="string"||n.trim()==="")throw new Error("Electron intent batch IPC channel is required");if(t===n)throw new Error("Electron intent and batch IPC channels must be distinct");return{intent(e){return r.invoke(t,e)},intentBatch(e){return r.invoke(n,e)}}}E(_,"createCoAkkaPreloadApi");0&&(module.exports={COAKKA_ELECTRON_INTENT_BATCH_CHANNEL,COAKKA_ELECTRON_INTENT_CHANNEL,createCoAkkaPreloadApi});
|
package/dist/preload.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
export declare const COAKKA_ELECTRON_INTENT_CHANNEL = "coakka:intent";
|
|
2
|
+
export declare const COAKKA_ELECTRON_INTENT_BATCH_CHANNEL = "coakka:intent-batch";
|
|
2
3
|
export interface IpcRendererLike {
|
|
3
4
|
invoke(channel: string, payload: unknown): Promise<unknown>;
|
|
4
5
|
}
|
|
5
6
|
export interface CoAkkaElectronPreloadApi {
|
|
6
7
|
intent(intent: unknown): Promise<unknown>;
|
|
8
|
+
intentBatch(intents: readonly unknown[]): Promise<unknown>;
|
|
7
9
|
}
|
|
8
|
-
export declare function createCoAkkaPreloadApi(ipcRenderer: IpcRendererLike, channel?: string): CoAkkaElectronPreloadApi;
|
|
10
|
+
export declare function createCoAkkaPreloadApi(ipcRenderer: IpcRendererLike, channel?: string, batchChannel?: string): CoAkkaElectronPreloadApi;
|
package/dist/preload.js
CHANGED
|
@@ -1,8 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export function createCoAkkaPreloadApi(ipcRenderer, channel = COAKKA_ELECTRON_INTENT_CHANNEL) {
|
|
3
|
-
return {
|
|
4
|
-
intent(intent) {
|
|
5
|
-
return ipcRenderer.invoke(channel, intent);
|
|
6
|
-
},
|
|
7
|
-
};
|
|
8
|
-
}
|
|
1
|
+
var o=Object.defineProperty;var i=(r,t)=>o(r,"name",{value:t,configurable:!0});var E="coakka:intent",c="coakka:intent-batch";function s(r,t=E,n=c){if(typeof t!="string"||t.trim()==="")throw new Error("Electron intent IPC channel is required");if(typeof n!="string"||n.trim()==="")throw new Error("Electron intent batch IPC channel is required");if(t===n)throw new Error("Electron intent and batch IPC channels must be distinct");return{intent(e){return r.invoke(t,e)},intentBatch(e){return r.invoke(n,e)}}}i(s,"createCoAkkaPreloadApi");export{c as COAKKA_ELECTRON_INTENT_BATCH_CHANNEL,E as COAKKA_ELECTRON_INTENT_CHANNEL,s as createCoAkkaPreloadApi};
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "coakka-v2-connector-electron",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "Electron connector for
|
|
3
|
+
"version": "3.1.1",
|
|
4
|
+
"description": "Electron connector for CoAkka Runtime, a native-backed polyglot distributed runtime for application-owned work",
|
|
5
5
|
"license": "SEE LICENSE IN PACKAGE-LICENSE.md",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "git+https://github.com/phuong-tran/coakka-publish.git"
|
|
9
9
|
},
|
|
10
|
-
"homepage": "https://github.com/phuong-tran/coakka-samples/tree/main/runtime
|
|
10
|
+
"homepage": "https://github.com/phuong-tran/coakka-samples/tree/main/docs/coakka-runtime",
|
|
11
11
|
"bugs": {
|
|
12
12
|
"url": "https://github.com/phuong-tran/coakka-samples/issues"
|
|
13
13
|
},
|
|
@@ -20,11 +20,13 @@
|
|
|
20
20
|
"polyglot",
|
|
21
21
|
"multi-language",
|
|
22
22
|
"multi-platform",
|
|
23
|
-
"ipc"
|
|
23
|
+
"ipc",
|
|
24
|
+
"distributed-runtime",
|
|
25
|
+
"application-owned-work"
|
|
24
26
|
],
|
|
25
27
|
"type": "module",
|
|
26
28
|
"engines": {
|
|
27
|
-
"node": ">=22"
|
|
29
|
+
"node": ">=22.0.0"
|
|
28
30
|
},
|
|
29
31
|
"main": "./dist/index.js",
|
|
30
32
|
"types": "./dist/index.d.ts",
|
|
@@ -48,20 +50,10 @@
|
|
|
48
50
|
"NOTICE",
|
|
49
51
|
"README.md"
|
|
50
52
|
],
|
|
51
|
-
"scripts": {
|
|
52
|
-
"build": "node scripts/build-package.mjs",
|
|
53
|
-
"verify": "npm run build",
|
|
54
|
-
"pack:release": "npm run build && node scripts/pack-release.mjs",
|
|
55
|
-
"smoke:packaged": "bash scripts/smoke-packaged-package.sh"
|
|
56
|
-
},
|
|
57
53
|
"dependencies": {
|
|
58
|
-
"coakka-v2-connector-node": "
|
|
54
|
+
"coakka-v2-connector-node": "3.1.2"
|
|
59
55
|
},
|
|
60
56
|
"peerDependencies": {
|
|
61
57
|
"electron": ">=42"
|
|
62
|
-
},
|
|
63
|
-
"devDependencies": {
|
|
64
|
-
"@types/node": "^22.0.0",
|
|
65
|
-
"typescript": "^5.8.3"
|
|
66
58
|
}
|
|
67
59
|
}
|