@bobfrankston/msgapidefs 0.1.23 → 0.1.25

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.
Files changed (3) hide show
  1. package/UDP-PLAN.md +499 -0
  2. package/msgapi-plan.md +209 -0
  3. package/package.json +1 -1
package/UDP-PLAN.md ADDED
@@ -0,0 +1,499 @@
1
+ # UDP Support Plan for msgapi
2
+
3
+ ## Overview
4
+
5
+ Add UDP networking capabilities to msgapi, enabling lightweight, connectionless communication for:
6
+ - Local device control and discovery
7
+ - IoT messaging
8
+ - Low-latency event broadcasting
9
+ - Inter-process communication
10
+ - Home automation integration
11
+
12
+ **Target Use Case**: Trusted, friendly applications controlled by the user. This is for power users running their own apps, not for sandboxed web content.
13
+
14
+ **Reference Implementation**: `y:\dev\homecontrol\utils\netsupport`
15
+
16
+ ---
17
+
18
+ ## API Design
19
+
20
+ ### msgapi.udp Object
21
+
22
+ ```typescript
23
+ interface UdpSocket {
24
+ /** Local port this socket is bound to */
25
+ readonly port: number;
26
+
27
+ /** Local address this socket is bound to */
28
+ readonly address: string;
29
+
30
+ /** Send a UDP message */
31
+ send(message: string | Uint8Array, port: number, address?: string): Promise<void>;
32
+
33
+ /** Register a message handler (non-exclusive, multiple handlers allowed) */
34
+ onMessage(handler: (message: UdpMessage) => void): void;
35
+
36
+ /** Remove a message handler */
37
+ offMessage(handler: (message: UdpMessage) => void): void;
38
+
39
+ /** Close the socket */
40
+ close(): Promise<void>;
41
+ }
42
+
43
+ interface UdpMessage {
44
+ /** Message content as string */
45
+ data: string;
46
+
47
+ /** Raw message content as Uint8Array */
48
+ buffer: Uint8Array;
49
+
50
+ /** Sender's address */
51
+ remoteAddress: string;
52
+
53
+ /** Sender's port */
54
+ remotePort: number;
55
+
56
+ /** Size of message in bytes */
57
+ size: number;
58
+ }
59
+
60
+ interface UdpOptions {
61
+ /** Port to bind to (0 = random available port) */
62
+ port?: number;
63
+
64
+ /** Address to bind to (default: '0.0.0.0' for all interfaces) */
65
+ address?: string;
66
+
67
+ /** Enable SO_REUSEADDR (allows multiple sockets on same port) */
68
+ reuseAddress?: boolean;
69
+
70
+ /** Enable SO_BROADCAST for broadcast messages */
71
+ broadcast?: boolean;
72
+
73
+ /** Join multicast group(s) */
74
+ multicast?: string | string[];
75
+ }
76
+
77
+ interface MsgAPI {
78
+ // ... existing properties ...
79
+
80
+ /**
81
+ * UDP networking operations namespace
82
+ * Requires -allowUdp flag when launching msgview/msger
83
+ */
84
+ udp?: {
85
+ /**
86
+ * Create a UDP socket
87
+ * @param options - Socket configuration options
88
+ * @returns UDP socket instance
89
+ * @example
90
+ * // Simple receiver on port 8080
91
+ * const socket = await msgapi.udp.create({ port: 8080 });
92
+ * socket.onMessage(msg => {
93
+ * console.log(`Received from ${msg.remoteAddress}:${msg.remotePort}: ${msg.data}`);
94
+ * });
95
+ *
96
+ * @example
97
+ * // Broadcast sender with reuse address
98
+ * const socket = await msgapi.udp.create({
99
+ * port: 0, // Random port
100
+ * broadcast: true,
101
+ * reuseAddress: true
102
+ * });
103
+ * await socket.send('Hello Network!', 8080, '255.255.255.255');
104
+ */
105
+ create(options?: UdpOptions): Promise<UdpSocket>;
106
+
107
+ /**
108
+ * Create a multicast receiver
109
+ * Convenience method for multicast scenarios
110
+ * @param multicastGroup - Multicast group address (e.g., '239.255.255.250')
111
+ * @param port - Port to listen on
112
+ * @returns UDP socket joined to multicast group
113
+ * @example
114
+ * const socket = await msgapi.udp.createMulticast('239.255.0.1', 5353);
115
+ * socket.onMessage(msg => console.log('Multicast:', msg.data));
116
+ */
117
+ createMulticast(multicastGroup: string, port: number): Promise<UdpSocket>;
118
+
119
+ /**
120
+ * Send a one-off UDP message without creating a persistent socket
121
+ * @param message - Message to send
122
+ * @param port - Destination port
123
+ * @param address - Destination address (default: 'localhost')
124
+ * @example
125
+ * await msgapi.udp.send('Quick message', 8080, '192.168.1.100');
126
+ */
127
+ send(message: string | Uint8Array, port: number, address?: string): Promise<void>;
128
+ };
129
+ }
130
+ ```
131
+
132
+ ---
133
+
134
+ ## Implementation Requirements
135
+
136
+ ### Permission/Security Model
137
+
138
+ UDP requires explicit permission, similar to `allowFs`:
139
+
140
+ **Command-line flag:**
141
+ - **msgview**: `-allowUdp`
142
+ - **msger**: `-allowUdp`
143
+
144
+ **Config file (recommended for friendly apps):**
145
+ ```json
146
+ {
147
+ "url": "http://localhost:8080/myapp",
148
+ "flags": {
149
+ "allowFs": true,
150
+ "allowUdp": true
151
+ }
152
+ }
153
+ ```
154
+
155
+ **Rationale**: This is for trusted applications the user controls. Like `allowFs`, `allowUdp` gives power to friendly apps that need it. The user explicitly enables it in their config file.
156
+
157
+ **Philosophy**: We're not sandboxing untrusted web content - we're empowering user-controlled applications with full system capabilities when requested.
158
+
159
+ ### Non-Exclusive Listening
160
+
161
+ Multiple handlers can listen to the same port:
162
+ - `reuseAddress: true` enables SO_REUSEADDR socket option
163
+ - Multiple `onMessage()` handlers can be registered on same socket
164
+ - Useful for multiple windows/instances receiving same broadcasts
165
+
166
+ ### Platform-Specific Notes
167
+
168
+ #### Node.js/msgview (Electron)
169
+ - Use Node.js `dgram` module
170
+ - Full UDP support including multicast
171
+ - Works on Windows, Linux, macOS
172
+
173
+ #### Rust/msger (wry)
174
+ - Use Rust `tokio::net::UdpSocket`
175
+ - Full platform support
176
+ - Async message handling via Tokio runtime
177
+
178
+ #### C#/msga (.NET MAUI)
179
+ - Use `System.Net.Sockets.UdpClient`
180
+ - Platform: Windows, Android (iOS restrictions may apply)
181
+ - iOS: UDP requires special entitlements, may be restricted
182
+
183
+ ---
184
+
185
+ ## Usage Examples
186
+
187
+ ### Example 1: Simple Sender/Receiver
188
+
189
+ **Sender:**
190
+ ```javascript
191
+ const socket = await msgapi.udp.create({ port: 0 }); // Random port
192
+ await socket.send('Hello!', 8080, '192.168.1.100');
193
+ await socket.close();
194
+ ```
195
+
196
+ **Receiver:**
197
+ ```javascript
198
+ const socket = await msgapi.udp.create({
199
+ port: 8080,
200
+ reuseAddress: true // Allow multiple receivers
201
+ });
202
+
203
+ socket.onMessage(msg => {
204
+ console.log(`From ${msg.remoteAddress}: ${msg.data}`);
205
+ // Echo back
206
+ socket.send(`Echo: ${msg.data}`, msg.remotePort, msg.remoteAddress);
207
+ });
208
+ ```
209
+
210
+ ### Example 2: Broadcast Discovery
211
+
212
+ **Service Announcer:**
213
+ ```javascript
214
+ const socket = await msgapi.udp.create({
215
+ broadcast: true
216
+ });
217
+
218
+ setInterval(async () => {
219
+ await socket.send(
220
+ JSON.stringify({ service: 'MyApp', port: 9000 }),
221
+ 8888,
222
+ '255.255.255.255'
223
+ );
224
+ }, 5000);
225
+ ```
226
+
227
+ **Service Discovery:**
228
+ ```javascript
229
+ const socket = await msgapi.udp.create({
230
+ port: 8888,
231
+ reuseAddress: true
232
+ });
233
+
234
+ socket.onMessage(msg => {
235
+ const service = JSON.parse(msg.data);
236
+ console.log(`Found: ${service.service} at ${msg.remoteAddress}:${service.port}`);
237
+ });
238
+ ```
239
+
240
+ ### Example 3: Multicast Communication
241
+
242
+ **Multicast Sender:**
243
+ ```javascript
244
+ const socket = await msgapi.udp.create({ broadcast: true });
245
+ await socket.send('Event occurred!', 5353, '239.255.0.1');
246
+ ```
247
+
248
+ **Multicast Receiver:**
249
+ ```javascript
250
+ const socket = await msgapi.udp.createMulticast('239.255.0.1', 5353);
251
+ socket.onMessage(msg => {
252
+ console.log('Multicast event:', msg.data);
253
+ });
254
+ ```
255
+
256
+ ### Example 4: Home Automation Control
257
+
258
+ ```javascript
259
+ // Config file enables UDP:
260
+ // { "flags": { "allowUdp": true }, ... }
261
+
262
+ // Listen for button press events
263
+ const listener = await msgapi.udp.create({
264
+ port: 7777,
265
+ reuseAddress: true
266
+ });
267
+
268
+ listener.onMessage(async msg => {
269
+ const event = JSON.parse(msg.data);
270
+
271
+ if (event.type === 'button_press') {
272
+ console.log(`Button ${event.button} pressed`);
273
+
274
+ // Send command to light controller
275
+ const controller = await msgapi.udp.create();
276
+ await controller.send(
277
+ JSON.stringify({ command: 'toggle', device: 'light1' }),
278
+ 8888,
279
+ 'light-controller.local' // DNS resolution supported
280
+ );
281
+ await controller.close();
282
+ }
283
+ });
284
+ ```
285
+
286
+ ### Example 5: Multiple Listeners (Non-Exclusive)
287
+
288
+ ```javascript
289
+ // Window 1: Logger
290
+ const socket1 = await msgapi.udp.create({
291
+ port: 9000,
292
+ reuseAddress: true
293
+ });
294
+ socket1.onMessage(msg => console.log('[LOG]', msg.data));
295
+
296
+ // Window 2: Processor
297
+ const socket2 = await msgapi.udp.create({
298
+ port: 9000,
299
+ reuseAddress: true
300
+ });
301
+ socket2.onMessage(msg => processMessage(msg.data));
302
+
303
+ // Both receive the same messages!
304
+ ```
305
+
306
+ ---
307
+
308
+ ## Implementation Checklist
309
+
310
+ ### Phase 1: Core Implementation
311
+
312
+ #### msgapidefs (TypeScript definitions)
313
+ - [ ] Add `UdpSocket` interface
314
+ - [ ] Add `UdpMessage` interface
315
+ - [ ] Add `UdpOptions` interface
316
+ - [ ] Add `msgapi.udp` namespace to `MsgAPI` interface
317
+ - [ ] Update README.md with UDP examples
318
+ - [ ] Add to msgapi-plan.md status table
319
+
320
+ #### msgview (Electron/Node.js)
321
+ - [ ] Implement `dgram`-based UDP socket wrapper
322
+ - [ ] Add `-allowUdp` flag to CLI parser
323
+ - [ ] Wire up IPC handlers for UDP operations
324
+ - [ ] Handle socket cleanup on window close
325
+ - [ ] Implement message handler registration/removal
326
+ - [ ] Add error handling for network errors
327
+ - [ ] Test on Windows, Linux, macOS
328
+
329
+ #### msger (Rust/wry)
330
+ - [ ] Add `tokio::net::UdpSocket` wrapper
331
+ - [ ] Add `--allow-udp` CLI flag
332
+ - [ ] Implement message handler callback system
333
+ - [ ] Handle async message reception in Tokio runtime
334
+ - [ ] Wire up webview invoke handlers
335
+ - [ ] Implement socket cleanup on window close
336
+ - [ ] Test on Windows (primary target)
337
+
338
+ #### msga (C#/.NET MAUI)
339
+ - [ ] Implement `UdpClient` wrapper in Services/
340
+ - [ ] Add allowUdp config option
341
+ - [ ] Wire up JavaScript-to-C# bridge for UDP
342
+ - [ ] Handle message callbacks via WebView
343
+ - [ ] Test on Windows, Android
344
+ - [ ] Document iOS limitations
345
+
346
+ ### Phase 2: Advanced Features
347
+ - [ ] Multicast support testing
348
+ - [ ] Broadcast support testing
349
+ - [ ] IPv6 support
350
+ - [ ] Socket options (TTL, buffer sizes)
351
+ - [ ] Rate limiting/throttling options
352
+ - [ ] Connection statistics/monitoring
353
+
354
+ ### Phase 3: Documentation & Examples
355
+ - [ ] Add UDP section to main README
356
+ - [ ] Create UDP examples repository
357
+ - [ ] Document common patterns (discovery, control, etc.)
358
+ - [ ] Add troubleshooting guide
359
+ - [ ] Document firewall configuration needs
360
+
361
+ ---
362
+
363
+ ## Security Considerations
364
+
365
+ ### Trust Model
366
+
367
+ **This is for friendly applications, not adversarial content.**
368
+
369
+ The user:
370
+ - Writes or controls the HTML/JS being loaded
371
+ - Explicitly enables `allowUdp` in their config file
372
+ - Understands they're giving the app network access
373
+ - Similar trust level to `allowFs` (full file system access)
374
+
375
+ ### Design Principles
376
+ 1. **Explicit opt-in**: Require `allowUdp` in config or CLI flag
377
+ 2. **Full power when enabled**: No artificial restrictions for trusted apps
378
+ 3. **Clear documentation**: User understands what they're enabling
379
+ 4. **Useful error messages**: If UDP fails, explain clearly why
380
+
381
+ ### Reasonable Safeguards
382
+ 1. **Message size limits**: Respect UDP's 64KB datagram limit (natural constraint)
383
+ 2. **Socket cleanup**: Auto-close sockets when window closes (resource management)
384
+ 3. **Error handling**: Clear errors for invalid addresses/ports
385
+
386
+ ### NOT Implemented (Trust-Based)
387
+ - ❌ Rate limiting (user's app, user's choice)
388
+ - ❌ IP restrictions (user may need any destination)
389
+ - ❌ Port restrictions (user may need privileged ports with sudo)
390
+ - ❌ DNS blocking (user should be able to resolve hostnames)
391
+ - ❌ Audit logging (adds overhead, user controls the app)
392
+
393
+ **Rationale**: If we trust the user with `allowFs` (full filesystem), we can trust them with UDP. Both are powerful, both require explicit enablement.
394
+
395
+ ---
396
+
397
+ ## Testing Strategy
398
+
399
+ ### Unit Tests
400
+ - Socket creation with various options
401
+ - Message sending/receiving
402
+ - Handler registration/removal
403
+ - Socket cleanup
404
+ - Error conditions
405
+
406
+ ### Integration Tests
407
+ - msgview ↔ msgview communication
408
+ - msger ↔ msger communication
409
+ - Cross-implementation (msgview ↔ msger)
410
+ - Broadcast reception by multiple instances
411
+ - Multicast group joining
412
+
413
+ ### Platform Tests
414
+ - Windows (primary target)
415
+ - Linux (msgview, msger)
416
+ - macOS (msgview)
417
+ - Android (msga)
418
+
419
+ ---
420
+
421
+ ## Reference: netsupport Comparison
422
+
423
+ Based on `y:\dev\homecontrol\utils\netsupport`:
424
+
425
+ ### Key Concepts to Adopt
426
+ - Simple socket creation API
427
+ - Non-exclusive listening (SO_REUSEADDR)
428
+ - Clean message handler pattern
429
+ - Automatic cleanup on close
430
+
431
+ ### Differences from netsupport
432
+ - **msgapi**: Integrated into window API (security via flag)
433
+ - **netsupport**: Standalone utility (assumed trusted)
434
+ - **msgapi**: Promise-based async API
435
+ - **netsupport**: May use callback patterns
436
+ - **msgapi**: Cross-platform (Electron, Rust, C#)
437
+ - **netsupport**: Node.js focused
438
+
439
+ ---
440
+
441
+ ## Future Enhancements
442
+
443
+ ### Potential Additions
444
+ - **TCP support**: For reliable, connection-oriented communication
445
+ - **WebSocket support**: For browser-like bidirectional communication
446
+ - **HTTP client**: Simple fetch-like API for web requests
447
+ - **MQTT support**: For IoT messaging patterns
448
+ - **Serial port**: For hardware device communication
449
+
450
+ ### Not Planned (Use Native APIs Instead)
451
+ - File transfers over network (use fs API + HTTP)
452
+ - Complex protocol implementations (use dedicated libraries)
453
+ - VPN/tunnel features (system-level concern)
454
+
455
+ ---
456
+
457
+ ## Open Questions
458
+
459
+ 1. **DNS resolution**: Allow hostnames in send()?
460
+ - **Recommendation**: YES - trust the user's app, support `socket.send('msg', 8080, 'myserver.local')`
461
+
462
+ 2. **Socket lifetime**: Auto-close on window close, or persist?
463
+ - **Recommendation**: Auto-close for resource management
464
+
465
+ 3. **Error handling**: Silent fail or throw/reject?
466
+ - **Recommendation**: Reject promises with descriptive errors
467
+
468
+ 4. **Buffer encoding**: String (UTF-8) vs raw bytes?
469
+ - **Recommendation**: Support both (string + Uint8Array) ✅ Already in API
470
+
471
+ 5. **Privileged ports**: Allow binding to ports < 1024?
472
+ - **Recommendation**: YES - if user runs msgview with appropriate permissions, allow it
473
+
474
+ ---
475
+
476
+ ## Timeline Estimate
477
+
478
+ - **Phase 1 (Core)**: 2-3 weeks per implementation
479
+ - msgview: 1 week (Node.js dgram is straightforward)
480
+ - msger: 2 weeks (Tokio async + webview bridge)
481
+ - msga: 2 weeks (C# + bridge wiring)
482
+
483
+ - **Phase 2 (Advanced)**: 1 week per implementation
484
+
485
+ - **Phase 3 (Docs)**: 1 week overall
486
+
487
+ **Total**: 8-10 weeks for full implementation across all platforms
488
+
489
+ ---
490
+
491
+ ## Status
492
+
493
+ - [x] Planning document created
494
+ - [ ] msgapidefs types added
495
+ - [ ] msgview implementation
496
+ - [ ] msger implementation
497
+ - [ ] msga implementation
498
+ - [ ] Documentation complete
499
+ - [ ] Testing complete
package/msgapi-plan.md ADDED
@@ -0,0 +1,209 @@
1
+ # msgapi Implementation Plan
2
+
3
+ Shared planning document for msgapi across implementations:
4
+ - **TypeScript**: msgapidefs (this repo) - types/definitions
5
+ - **TypeScript/Electron**: msgview
6
+ - **Rust/wry**: msger
7
+ - **C#/.NET MAUI**: msga (y:\dev\utils\msga)
8
+
9
+ ## Current Status
10
+
11
+ ### Implemented APIs
12
+
13
+ | API | msgview | msger | msga | Notes |
14
+ |-----|---------|-------|------|-------|
15
+ | **Window Control** |
16
+ | toggleFullscreen() | ✅ | ✅ | ⚠️ | msga: C# exists, not wired |
17
+ | setFullscreen(bool) | ✅ | ✅ | ⚠️ | msga: C# exists, not wired |
18
+ | minimize() | ✅ | ✅ | ⚠️ | msga: Windows only in C# |
19
+ | maximize() | ✅ | ✅ | ⚠️ | msga: Windows only in C# |
20
+ | setSize(w,h) | ✅ | ✅ | ⚠️ | msga: Windows only in C# |
21
+ | setPosition(x,y) | ✅ | ✅ | ⚠️ | msga: Windows only in C# |
22
+ | setAlwaysOnTop(bool) | ✅ | ✅ | ❌ | |
23
+ | close(result?) | ✅ | ✅ | ⚠️ | msga: basic close only |
24
+ | **File System** |
25
+ | fs.selectFile() | ✅ | ✅ | ⚠️ | msga: C# exists, not wired |
26
+ | fs.selectFiles() | ✅ | ✅ | ⚠️ | msga: C# exists, not wired |
27
+ | fs.saveFileAs() | ✅ | ✅ | ❌ | |
28
+ | fs.selectFolder() | ✅ | ✅ | ❌ | |
29
+ | fs.read(path) | ✅ | ✅ | ❌ | Requires allowFs flag |
30
+ | fs.write(path) | ✅ | ✅ | ❌ | Requires allowFs flag |
31
+ | fs.list(path) | ✅ | ✅ | ❌ | Requires allowFs flag |
32
+ | fs.exists(path) | ✅ | ✅ | ❌ | Requires allowFs flag |
33
+ | fs.delete(path) | ✅ | ✅ | ❌ | Requires allowFs flag |
34
+
35
+ Legend: ✅ Implemented | ⚠️ Partial/Not wired | ❌ Not implemented
36
+
37
+ ### msga Wiring Status
38
+
39
+ The MsgApiBridge.cs file in msga has C# implementations but the JavaScript bridge is not connected:
40
+ - JavaScript injection exists in MainPage.xaml.cs
41
+ - C# handler methods exist in Services/MsgApiBridge.cs
42
+ - Missing: WebView JavaScript-to-C# message handler wiring
43
+
44
+ ---
45
+
46
+ ## Planned Features
47
+
48
+ ### 1. UDP Communication
49
+
50
+ **Use case**: Local device control, IoT messaging, low-latency communication
51
+
52
+ ```typescript
53
+ interface MsgAPI {
54
+ udp: {
55
+ // Send UDP datagram
56
+ send(host: string, port: number, data: string | Uint8Array): Promise<void>;
57
+
58
+ // Listen for UDP datagrams on a port
59
+ listen(port: number, callback: (data: Uint8Array, sender: {host: string, port: number}) => void): Promise<{close: () => void}>;
60
+
61
+ // Send and wait for response (with timeout)
62
+ sendReceive(host: string, port: number, data: string | Uint8Array, timeoutMs?: number): Promise<Uint8Array>;
63
+
64
+ // Broadcast to subnet
65
+ broadcast(port: number, data: string | Uint8Array): Promise<void>;
66
+ }
67
+ }
68
+ ```
69
+
70
+ **Implementation notes**:
71
+ - TypeScript: Define types only (browser cannot do UDP)
72
+ - Electron (msgview): Use dgram module
73
+ - Rust (msger): Use std::net::UdpSocket or tokio UDP
74
+ - C#/MAUI (msga): Use System.Net.Sockets.UdpClient
75
+
76
+ **Security considerations**:
77
+ - Require explicit allowUdp flag or permission prompt
78
+ - Consider port restrictions (no well-known ports < 1024?)
79
+ - Localhost-only mode option
80
+
81
+ ### 2. Enhanced File System
82
+
83
+ **Use case**: Full file system access for local apps, document management
84
+
85
+ ```typescript
86
+ interface FsExtended {
87
+ // Already planned in msgapidefs
88
+ read(path: string): Promise<Uint8Array>;
89
+ write(path: string, content: string | Uint8Array): Promise<void>;
90
+ list(path: string): Promise<FsEntry[]>;
91
+ exists(path: string): Promise<boolean>;
92
+ delete(path: string): Promise<void>;
93
+
94
+ // New additions
95
+ mkdir(path: string, recursive?: boolean): Promise<void>;
96
+ rename(oldPath: string, newPath: string): Promise<void>;
97
+ copy(src: string, dest: string): Promise<void>;
98
+ stat(path: string): Promise<FsStat>;
99
+ watch(path: string, callback: (event: FsWatchEvent) => void): Promise<{close: () => void}>;
100
+ }
101
+
102
+ interface FsEntry {
103
+ name: string;
104
+ path: string;
105
+ isDirectory: boolean;
106
+ size: number;
107
+ modified: Date;
108
+ }
109
+
110
+ interface FsStat {
111
+ size: number;
112
+ created: Date;
113
+ modified: Date;
114
+ accessed: Date;
115
+ isDirectory: boolean;
116
+ isFile: boolean;
117
+ isSymlink: boolean;
118
+ }
119
+
120
+ interface FsWatchEvent {
121
+ type: 'create' | 'modify' | 'delete' | 'rename';
122
+ path: string;
123
+ newPath?: string; // For rename
124
+ }
125
+ ```
126
+
127
+ **Security considerations**:
128
+ - Require allowFs flag
129
+ - Consider sandboxed paths (app data directory only by default)
130
+ - Full access requires explicit user consent
131
+
132
+ ### 3. System Integration (Lower Priority)
133
+
134
+ ```typescript
135
+ interface MsgAPI {
136
+ system?: {
137
+ // Clipboard
138
+ clipboard: {
139
+ read(): Promise<string>;
140
+ write(text: string): Promise<void>;
141
+ readImage?(): Promise<Uint8Array>;
142
+ writeImage?(data: Uint8Array): Promise<void>;
143
+ };
144
+
145
+ // Notifications
146
+ notify(title: string, body: string, options?: NotifyOptions): Promise<void>;
147
+
148
+ // Shell/external commands (very restricted)
149
+ openExternal(url: string): Promise<void>; // Open in default browser/app
150
+
151
+ // Environment info
152
+ platform: 'windows' | 'macos' | 'linux' | 'android' | 'ios';
153
+ arch: string;
154
+ version: string;
155
+ }
156
+ }
157
+ ```
158
+
159
+ ---
160
+
161
+ ## Implementation Priorities
162
+
163
+ ### Phase 1: Wire Up msga (Current)
164
+ 1. Connect JavaScript bridge to C# handlers in msga
165
+ 2. Test existing window control APIs on Android/Windows
166
+ 3. Ensure parity with msgview/msger for basic features
167
+
168
+ ### Phase 2: UDP Support
169
+ 1. Add UDP types to msgapidefs
170
+ 2. Implement in msger (Rust) - fastest iteration
171
+ 3. Port to msgview (Electron)
172
+ 4. Port to msga (C#/MAUI)
173
+
174
+ ### Phase 3: Enhanced File System
175
+ 1. Add new fs types to msgapidefs
176
+ 2. Implement mkdir, rename, copy, stat
177
+ 3. Add file watching (platform-specific)
178
+
179
+ ### Phase 4: System Integration
180
+ 1. Clipboard support
181
+ 2. Notifications
182
+ 3. Platform detection
183
+
184
+ ---
185
+
186
+ ## Cross-Implementation Testing
187
+
188
+ All implementations should pass the same test suite. Use samples.html as base:
189
+
190
+ ```
191
+ msgapidefs/samples.html - Interactive test page
192
+ msgapidefs/tests/ - Automated tests (TODO)
193
+ ```
194
+
195
+ Test categories:
196
+ - [ ] Window control (fullscreen, minimize, maximize, resize, position)
197
+ - [ ] File dialogs (select file, select files, save as, select folder)
198
+ - [ ] File system read/write (when allowFs enabled)
199
+ - [ ] UDP send/receive (when implemented)
200
+
201
+ ---
202
+
203
+ ## Notes
204
+
205
+ - msgapi is injected as `window.msgapi` global
206
+ - All async methods return Promises
207
+ - Errors thrown as standard JavaScript errors
208
+ - Platform-specific features return undefined/null if unavailable
209
+ - Version property indicates implementation: `msgapi.version` = "msga/1.0" etc.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bobfrankston/msgapidefs",
3
- "version": "0.1.23",
3
+ "version": "0.1.25",
4
4
  "description": "TypeScript definitions for msgapi JavaScript API (msgview/msger)",
5
5
  "type": "module",
6
6
  "main": "./msgapidefs.js",