node-mac-recorder 2.22.21 → 2.22.22

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.
@@ -105,6 +105,37 @@ function transformInputFrameGlobal(ifr, d) {
105
105
  };
106
106
  }
107
107
 
108
+ // Electron: AX caret cache — deferred refresh ile crash-safe
109
+ const ELECTRON_AX_CACHE_MAX_AGE_MS = 500;
110
+
111
+ function deferredRefreshElectronAXCache(recorder, nativeBinding) {
112
+ if (recorder._axDeferredPending) return;
113
+ if (!nativeBinding || typeof nativeBinding.getTextInputSnapshot !== "function") return;
114
+
115
+ recorder._axDeferredPending = true;
116
+ setImmediate(() => {
117
+ recorder._axDeferredPending = false;
118
+ try {
119
+ const snap = nativeBinding.getTextInputSnapshot();
120
+ if (snap && Number.isFinite(snap.caretX) && Number.isFinite(snap.caretY)) {
121
+ const d = recorder.cursorDisplayInfo;
122
+ const caretT = transformGlobalToVideo(snap.caretX, snap.caretY, d);
123
+ recorder._axCaretCache = {
124
+ caretX: caretT.x,
125
+ caretY: caretT.y,
126
+ inputFrame: snap.inputFrame
127
+ ? transformInputFrameGlobal(snap.inputFrame, d)
128
+ : null,
129
+ csys: d && d.videoRelative ? "video-relative" : "global",
130
+ wallMs: Date.now(),
131
+ };
132
+ }
133
+ } catch {
134
+ // AX API hata verirse mevcut cache'i koru
135
+ }
136
+ });
137
+ }
138
+
108
139
  /** @returns {boolean} Dosyaya textInput satırı yazıldı mı */
109
140
  function tryAppendSyntheticTextInputRow(recorder, nativeBinding, filepath, cursorData, timestamp) {
110
141
  if (!IS_ELECTRON) {
@@ -122,6 +153,8 @@ function tryAppendSyntheticTextInputRow(recorder, nativeBinding, filepath, curso
122
153
  wall - (recorder._electronSynthWallMs || 0) <
123
154
  ELECTRON_SYNTH_THROTTLE_MS
124
155
  ) {
156
+ // Throttle aktif olsa bile AX cache yenilensin
157
+ deferredRefreshElectronAXCache(recorder, nativeBinding);
125
158
  return false;
126
159
  }
127
160
  const vx = cursorData.x;
@@ -130,36 +163,28 @@ function tryAppendSyntheticTextInputRow(recorder, nativeBinding, filepath, curso
130
163
  return false;
131
164
  }
132
165
 
133
- // Gerçek caret pozisyonunu accessibility API'den al
166
+ // Cached AX caret varsa gerçek caret pozisyonunu kullan
134
167
  let caretX = vx;
135
168
  let caretY = vy;
136
169
  let inputFrame = { x: vx - 1, y: vy - 9, width: 2, height: 18 };
137
- let hasRealCaret = false;
170
+ let coordinateSystem = cursorData.coordinateSystem;
138
171
 
139
- if (nativeBinding && typeof nativeBinding.getTextInputSnapshot === "function") {
140
- try {
141
- const snap = nativeBinding.getTextInputSnapshot();
142
- if (
143
- snap &&
144
- Number.isFinite(snap.caretX) &&
145
- Number.isFinite(snap.caretY)
146
- ) {
147
- // Global koordinatları video uzayına dönüştür
148
- const d = recorder.cursorDisplayInfo;
149
- const caretT = transformGlobalToVideo(snap.caretX, snap.caretY, d);
150
- caretX = caretT.x;
151
- caretY = caretT.y;
152
- hasRealCaret = true;
153
-
154
- if (snap.inputFrame) {
155
- inputFrame = transformInputFrameGlobal(snap.inputFrame, d);
156
- }
157
- }
158
- } catch {
159
- // AX API hata verirse cursor pozisyonuna fallback
160
- }
172
+ const cache = recorder._axCaretCache;
173
+ if (
174
+ cache &&
175
+ Number.isFinite(cache.caretX) &&
176
+ Number.isFinite(cache.caretY) &&
177
+ (wall - (cache.wallMs || 0)) < ELECTRON_AX_CACHE_MAX_AGE_MS
178
+ ) {
179
+ caretX = cache.caretX;
180
+ caretY = cache.caretY;
181
+ if (cache.inputFrame) inputFrame = cache.inputFrame;
182
+ coordinateSystem = cache.csys || coordinateSystem;
161
183
  }
162
184
 
185
+ // Sonraki frame için AX cache'i yenile (deferred — crash-safe)
186
+ deferredRefreshElectronAXCache(recorder, nativeBinding);
187
+
163
188
  const tiRow = {
164
189
  x: vx,
165
190
  y: vy,
@@ -170,9 +195,7 @@ function tryAppendSyntheticTextInputRow(recorder, nativeBinding, filepath, curso
170
195
  caretX,
171
196
  caretY,
172
197
  inputFrame,
173
- coordinateSystem: hasRealCaret
174
- ? (recorder.cursorDisplayInfo?.videoRelative ? "video-relative" : "global")
175
- : cursorData.coordinateSystem,
198
+ coordinateSystem,
176
199
  recordingType: cursorData.recordingType,
177
200
  videoInfo: cursorData.videoInfo || {},
178
201
  displayInfo: cursorData.displayInfo || {},
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-mac-recorder",
3
- "version": "2.22.21",
3
+ "version": "2.22.22",
4
4
  "description": "Native macOS screen recording package for Node.js applications",
5
5
  "main": "index.js",
6
6
  "keywords": [