@oh-my-pi/pi-natives 18.9.1 → 18.10.0

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 CHANGED
@@ -10,6 +10,7 @@ Native Rust functionality via N-API.
10
10
  - **Audio**: Cross-platform low-latency microphone capture and gapless speaker playback
11
11
  - **WebRTC**: Native Opus media, SDP offer/answer negotiation, and data-channel events for live sessions
12
12
  - **File locking**: Process-owned cross-process locks with in-memory kernel names on Linux/Windows and `flock(2)` sidecars on other Unix platforms
13
+ - **Local IPC**: `IpcServer`/`IpcConnection` over Unix sockets and Windows named pipes — owner-only access, single-instance binding with stale-endpoint takeover, newline or raw framing; `ipcEndpoint(dir, name)` names endpoints per platform
13
14
  - **PDF**: In-memory PDF-to-Markdown extraction with OCR-page classification via `pdf-inspector`
14
15
  - **Binary patches**: `applyBinaryPatch(oldPath, patchPath, outPath)` applies an HDiffPatch single-stream patch (HDIFFSF20, zstd or uncompressed), streaming from files; callers verify digests
15
16
 
package/native/index.d.ts CHANGED
@@ -235,6 +235,85 @@ export declare class HighlightStream {
235
235
  push(chunk: string): string
236
236
  }
237
237
 
238
+ /** One accepted or dialed IPC connection. */
239
+ export declare class IpcConnection {
240
+ /**
241
+ * Dial `endpoint`. Rejects with code ENOENT (no endpoint), ECONNREFUSED
242
+ * (stale socket / no listener), ETIMEDOUT, EACCES (peer owned by another
243
+ * user, or permission), or the OS errno name.
244
+ */
245
+ static connect(endpoint: string, options: IpcConnectOptions): Promise<IpcConnection>
246
+ /**
247
+ * Begin delivery on a `lines` connection (throws `TypeError` on a `raw`
248
+ * one). Call `start`/`startRaw` exactly once. Frames received before
249
+ * start are buffered, never dropped. `onLine` gets each non-empty line
250
+ * (one trailing CR stripped, invalid UTF-8 replaced lossily). `onClose`
251
+ * fires exactly once, after the last frame — including after local
252
+ * `end()`/`destroy()`: `null` for an orderly close, otherwise
253
+ * `"<CODE>: <message>"`.
254
+ */
255
+ start(onLine: (line: string) => void, onClose: (reason: string | null) => void): void
256
+ /**
257
+ * Same as `start()` for a `raw` connection (throws `TypeError` on a
258
+ * `lines` one): `onChunk` gets each received chunk.
259
+ */
260
+ startRaw(onChunk: (chunk: Uint8Array) => void, onClose: (reason: string | null) => void): void
261
+ /**
262
+ * Send one frame. lines: a string without LF (`TypeError` otherwise);
263
+ * LF is appended. raw: string (UTF-8) or `Uint8Array` written as-is.
264
+ * Frames sent during one JS task are written together when it ends (a
265
+ * microtask), in order; `end()` writes them first. Returns false once
266
+ * unwritten bytes exceed 1 MiB (await `drained()` before sending more).
267
+ * After close: returns false and drops the frame.
268
+ */
269
+ send(frame: string | Uint8Array): boolean
270
+ /** Resolves when the write queue is empty, or the connection closed. */
271
+ drained(): Promise<void>
272
+ /**
273
+ * Graceful: write everything queued, then shut the write half (Unix) /
274
+ * close the pipe (Windows); onClose follows when the read side ends.
275
+ */
276
+ end(): void
277
+ /**
278
+ * Immediate close; queued writes are dropped; onClose(null) follows.
279
+ * Idempotent.
280
+ */
281
+ destroy(): void
282
+ /** Keep the event loop alive while delivering (default). */
283
+ ref(): void
284
+ /** Let the event loop exit while this connection is open. */
285
+ unref(): void
286
+ /** Whether the connection is closed (or `destroy()` was called). */
287
+ get closed(): boolean
288
+ }
289
+
290
+ /** Listening IPC endpoint. */
291
+ export declare class IpcServer {
292
+ /**
293
+ * Bind and listen.
294
+ *
295
+ * Unix: creates the parent dir (0700) if missing; under an exclusive flock
296
+ * on `<path>.bind.lock`, rejects EADDRINUSE when a live server answers,
297
+ * otherwise replaces the stale socket file; the socket is chmod 0600 before
298
+ * `listen()`. Windows: first pipe instance (exists → EADDRINUSE), remote
299
+ * clients rejected, DACL granting only the current user.
300
+ * `onConnection` receives each accepted, peer-verified connection (not yet
301
+ * started).
302
+ */
303
+ static listen(endpoint: string, options: IpcListenOptions, onConnection: (connection: IpcConnection) => void): Promise<IpcServer>
304
+ /** The endpoint this server listens on. */
305
+ get endpoint(): string
306
+ /**
307
+ * Stop accepting. Unix: unlink the socket file if it is still the inode
308
+ * this server bound. Accepted connections are untouched. Idempotent.
309
+ */
310
+ close(): Promise<void>
311
+ /** Keep the event loop alive while listening (default). */
312
+ ref(): void
313
+ /** Let the event loop exit while listening. */
314
+ unref(): void
315
+ }
316
+
238
317
  /** WebRTC peer that accepts 16 kHz mono PCM and renders remote Opus audio. */
239
318
  export declare class LiveWebRtcPeer {
240
319
  /**
@@ -2193,6 +2272,44 @@ export interface InlineSloppyRegion {
2193
2272
  */
2194
2273
  export declare function invalidateFsScanCache(path?: string | undefined | null): void
2195
2274
 
2275
+ /** Options for `IpcConnection.connect`. */
2276
+ export interface IpcConnectOptions {
2277
+ /**
2278
+ * `lines`: UTF-8 text frames delimited by LF; `raw`: byte chunks as
2279
+ * received.
2280
+ */
2281
+ framing: "lines" | "raw"
2282
+ /** Connect deadline. Default 3000 ms. Expiry rejects with code ETIMEDOUT. */
2283
+ timeoutMs?: number
2284
+ /** Max bytes of one received line (lines framing). Default 64 MiB. */
2285
+ maxFrameBytes?: number
2286
+ }
2287
+
2288
+ /**
2289
+ * Platform endpoint for `name` scoped to directory `dir`.
2290
+ *
2291
+ * Unix: `<dir>/<stem>.sock`; when that path does not fit `sun_path` (104 bytes
2292
+ * on macOS/BSD, 108 on Linux, including NUL), `/tmp/omp-<euid>/<hash16>.sock`.
2293
+ * Windows: `\\.\pipe\omp-<stem>-<hash16(lowercase(resolve(dir)))>`.
2294
+ * `stem` is `name` with every char outside `[A-Za-z0-9._-]` replaced by "_".
2295
+ * Pure and deterministic: every process computes the same endpoint.
2296
+ */
2297
+ export declare function ipcEndpoint(dir: string, name: string): string
2298
+
2299
+ /** Options for `IpcServer.listen`. */
2300
+ export interface IpcListenOptions {
2301
+ /**
2302
+ * `lines`: UTF-8 text frames delimited by LF; `raw`: byte chunks as
2303
+ * received.
2304
+ */
2305
+ framing: "lines" | "raw"
2306
+ /**
2307
+ * Max bytes of one received line (lines framing). Default 64 MiB.
2308
+ * Exceeding closes that connection with reason "EMSGSIZE: …".
2309
+ */
2310
+ maxFrameBytes?: number
2311
+ }
2312
+
2196
2313
  /** Kind enum of the backend selected by default for this build target. */
2197
2314
  export declare function isoBackend(): IsoBackendKind
2198
2315
 
package/native/index.js CHANGED
@@ -31,6 +31,8 @@ export const EditSession = nativeBindings.EditSession;
31
31
  export const EditStore = nativeBindings.EditStore;
32
32
  export const FileLock = nativeBindings.FileLock;
33
33
  export const HighlightStream = nativeBindings.HighlightStream;
34
+ export const IpcConnection = nativeBindings.IpcConnection;
35
+ export const IpcServer = nativeBindings.IpcServer;
34
36
  export const LiveWebRtcPeer = nativeBindings.LiveWebRtcPeer;
35
37
  export const MacAppearanceObserver = nativeBindings.MacAppearanceObserver;
36
38
  export const NativeOAuthCallback = nativeBindings.NativeOAuthCallback;
@@ -95,6 +97,7 @@ export const hasMatch = nativeBindings.hasMatch ?? missingNativeExport("hasMatch
95
97
  export const highlightCode = nativeBindings.highlightCode ?? missingNativeExport("highlightCode");
96
98
  export const htmlToMarkdown = nativeBindings.htmlToMarkdown ?? missingNativeExport("htmlToMarkdown");
97
99
  export const invalidateFsScanCache = nativeBindings.invalidateFsScanCache ?? missingNativeExport("invalidateFsScanCache");
100
+ export const ipcEndpoint = nativeBindings.ipcEndpoint ?? missingNativeExport("ipcEndpoint");
98
101
  export const isoBackend = nativeBindings.isoBackend ?? missingNativeExport("isoBackend");
99
102
  export const isoDiff = nativeBindings.isoDiff ?? missingNativeExport("isoDiff");
100
103
  export const isoIsUnavailableError = nativeBindings.isoIsUnavailableError ?? missingNativeExport("isoIsUnavailableError");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oh-my-pi/pi-natives",
3
- "version": "18.9.1",
3
+ "version": "18.10.0",
4
4
  "description": "Native Rust bindings for PDF conversion, audio, WebRTC, grep, clipboard, image processing, syntax highlighting, PTY, and shell operations via N-API",
5
5
  "type": "module",
6
6
  "homepage": "https://omp.sh",
@@ -42,7 +42,8 @@
42
42
  "fmt": "oxfmt --no-error-on-unmatched-pattern 'src/**/*.{ts,tsx}' '{test,bench,examples,scripts}/**/*.ts' '*.ts'",
43
43
  "gen:npm": "bun scripts/gen-npm-packages.ts",
44
44
  "bench": "bun bench/grep.ts",
45
- "bench:text": "bun bench/text.ts"
45
+ "bench:text": "bun bench/text.ts",
46
+ "bench:ipc": "bun bench/ipc.ts"
46
47
  },
47
48
  "devDependencies": {
48
49
  "@napi-rs/cli": "3.7.2",
@@ -112,11 +113,11 @@
112
113
  }
113
114
  },
114
115
  "optionalDependencies": {
115
- "@oh-my-pi/pi-natives-linux-x64": "18.9.1",
116
- "@oh-my-pi/pi-natives-linux-arm64": "18.9.1",
117
- "@oh-my-pi/pi-natives-darwin-x64": "18.9.1",
118
- "@oh-my-pi/pi-natives-darwin-arm64": "18.9.1",
119
- "@oh-my-pi/pi-natives-win32-x64": "18.9.1",
120
- "@oh-my-pi/pi-natives-win32-arm64": "18.9.1"
116
+ "@oh-my-pi/pi-natives-linux-x64": "18.10.0",
117
+ "@oh-my-pi/pi-natives-linux-arm64": "18.10.0",
118
+ "@oh-my-pi/pi-natives-darwin-x64": "18.10.0",
119
+ "@oh-my-pi/pi-natives-darwin-arm64": "18.10.0",
120
+ "@oh-my-pi/pi-natives-win32-x64": "18.10.0",
121
+ "@oh-my-pi/pi-natives-win32-arm64": "18.10.0"
121
122
  }
122
123
  }