@oh-my-pi/pi-natives 18.2.4 → 18.2.5

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.
@@ -68,6 +68,65 @@ function sourceDimensions(capture) {
68
68
  };
69
69
  }
70
70
 
71
+ function displaysEqual(a, b) {
72
+ if (a === b) return true;
73
+ if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) return false;
74
+ for (let i = 0; i < a.length; i++) {
75
+ const x = a[i];
76
+ const y = b[i];
77
+ if (
78
+ x === y ||
79
+ (x?.id === y?.id &&
80
+ x?.x === y?.x &&
81
+ x?.y === y?.y &&
82
+ x?.width === y?.width &&
83
+ x?.height === y?.height &&
84
+ x?.scale === y?.scale &&
85
+ x?.pixelX === y?.pixelX &&
86
+ x?.pixelY === y?.pixelY &&
87
+ x?.pixelWidth === y?.pixelWidth &&
88
+ x?.pixelHeight === y?.pixelHeight)
89
+ ) {
90
+ continue;
91
+ }
92
+ return false;
93
+ }
94
+ return true;
95
+ }
96
+
97
+ // Field-by-field frame comparison: the JSON.stringify signature allocated a
98
+ // full string over the display list on every capture and every input action.
99
+ // A rolling hash would risk collisions where string equality had none, so
100
+ // compare the same fields directly instead.
101
+ function sameFrame(a, b) {
102
+ if (a === b) return true;
103
+ if (!a || !b) return false;
104
+ return a.target === b.target && a.width === b.width && a.height === b.height && displaysEqual(a.displays, b.displays);
105
+ }
106
+
107
+ // Lightweight projection of the fields sameFrame reads: the stored capture
108
+ // must NOT retain the full screenshot (`data: Uint8Array`, multi-MB per
109
+ // target) after callers finish with it.
110
+ function frameIdentity(capture) {
111
+ const displays = Array.isArray(capture.displays) ? capture.displays.map(displayOf) : capture.displays;
112
+ return { target: capture.target, width: capture.width, height: capture.height, displays };
113
+ }
114
+
115
+ function displayOf(display) {
116
+ return {
117
+ id: display?.id,
118
+ x: display?.x,
119
+ y: display?.y,
120
+ width: display?.width,
121
+ height: display?.height,
122
+ scale: display?.scale,
123
+ pixelX: display?.pixelX,
124
+ pixelY: display?.pixelY,
125
+ pixelWidth: display?.pixelWidth,
126
+ pixelHeight: display?.pixelHeight,
127
+ };
128
+ }
129
+
71
130
  function frameSignature(capture) {
72
131
  return JSON.stringify({
73
132
  target: capture.target,
@@ -164,7 +223,7 @@ export function adaptDesktopSession(NativeDesktopSession) {
164
223
  try {
165
224
  const capture = await native.execute(Array.isArray(actions) ? actions : [actions], target);
166
225
  const previous = this.#capturedTargets.get(target);
167
- if (capture && previous?.native === native && frameSignature(capture) !== previous.signature) {
226
+ if (capture && previous?.native === native && !sameFrame(capture, previous.capture)) {
168
227
  this.#capturedTargets.delete(target);
169
228
  }
170
229
  } catch (error) {
@@ -201,7 +260,11 @@ export function adaptDesktopSession(NativeDesktopSession) {
201
260
  const native = this.#sessionForCapture(caps);
202
261
  const capture = await native.capture(target);
203
262
  const adapted = { ...capture, ...sourceDimensions(capture), target };
204
- this.#capturedTargets.set(target, { native, signature: frameSignature(adapted) });
263
+ // Store only the comparison fields, not the screenshot bytes:
264
+ // `adapted` carries the full PNG `data` (multi-MB per target).
265
+ // Keep the string signature for any external reader of the
266
+ // stored shape.
267
+ this.#capturedTargets.set(target, { native, capture: frameIdentity(adapted), signature: frameSignature(adapted) });
205
268
  return adapted;
206
269
  } catch (error) {
207
270
  throw normalizeError(error, "CaptureFailed");
package/native/index.d.ts CHANGED
@@ -648,7 +648,7 @@ export declare function __ompInstallTokioRuntime(): void
648
648
  * `packages/natives/native/index.js` (which derives the name from
649
649
  * `package.json#version`).
650
650
  */
651
- export declare function __piNativesV18_2_4(): void
651
+ export declare function __piNativesV18_2_5(): void
652
652
 
653
653
  /**
654
654
  * Apply ast-grep rewrite rules to matching files; honors `dryRun` and returns
package/native/index.js CHANGED
@@ -39,7 +39,7 @@ export const VcsRepo = nativeBindings.VcsRepo;
39
39
 
40
40
  // functions
41
41
  export const __ompInstallTokioRuntime = nativeBindings.__ompInstallTokioRuntime;
42
- export const __piNativesV18_2_4 = nativeBindings.__piNativesV18_2_4;
42
+ export const __piNativesV18_2_5 = nativeBindings.__piNativesV18_2_5;
43
43
  export const astEdit = nativeBindings.astEdit;
44
44
  export const astGrep = nativeBindings.astGrep;
45
45
  export const astMatch = nativeBindings.astMatch;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oh-my-pi/pi-natives",
3
- "version": "18.2.4",
3
+ "version": "18.2.5",
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",
@@ -100,11 +100,11 @@
100
100
  }
101
101
  },
102
102
  "optionalDependencies": {
103
- "@oh-my-pi/pi-natives-linux-x64": "18.2.4",
104
- "@oh-my-pi/pi-natives-linux-arm64": "18.2.4",
105
- "@oh-my-pi/pi-natives-darwin-x64": "18.2.4",
106
- "@oh-my-pi/pi-natives-darwin-arm64": "18.2.4",
107
- "@oh-my-pi/pi-natives-win32-x64": "18.2.4",
108
- "@oh-my-pi/pi-natives-win32-arm64": "18.2.4"
103
+ "@oh-my-pi/pi-natives-linux-x64": "18.2.5",
104
+ "@oh-my-pi/pi-natives-linux-arm64": "18.2.5",
105
+ "@oh-my-pi/pi-natives-darwin-x64": "18.2.5",
106
+ "@oh-my-pi/pi-natives-darwin-arm64": "18.2.5",
107
+ "@oh-my-pi/pi-natives-win32-x64": "18.2.5",
108
+ "@oh-my-pi/pi-natives-win32-arm64": "18.2.5"
109
109
  }
110
110
  }