@napolab/texture-bridge-renderer 0.5.1 → 0.6.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/dist/index.cjs CHANGED
@@ -160,6 +160,24 @@ var TextureBridgeImpl = class extends events.EventEmitter {
160
160
  get isDisposed() {
161
161
  return this._disposed;
162
162
  }
163
+ /** Handle a paint event from the offscreen BrowserWindow. */
164
+ handlePaint(event) {
165
+ const texture = event.texture;
166
+ if (!texture?.textureInfo) return;
167
+ try {
168
+ if (this._disposed) return;
169
+ (0, _napolab_texture_bridge_core.sendTextureFromPaintEvent)(this.sender, texture.textureInfo);
170
+ this.previewManager?.sendFrame(texture);
171
+ } catch (err) {
172
+ const error = err instanceof Error ? err : new Error(String(err));
173
+ this.emit("error", error);
174
+ } finally {
175
+ texture.release?.();
176
+ }
177
+ if (this._disposed) return;
178
+ const fps = this.fpsCounter.tick();
179
+ if (fps !== null) this.emit("fps", fps);
180
+ }
163
181
  openPreview() {
164
182
  if (this._disposed) return;
165
183
  if (!this.previewManager) this.previewManager = new PreviewManager(this.options.width, this.options.height, this.options.preview);
@@ -170,6 +188,7 @@ var TextureBridgeImpl = class extends events.EventEmitter {
170
188
  }
171
189
  resize(width, height) {
172
190
  if (this._disposed) return;
191
+ const prevOpts = this.options;
173
192
  this.options = {
174
193
  ...this.options,
175
194
  width,
@@ -177,7 +196,14 @@ var TextureBridgeImpl = class extends events.EventEmitter {
177
196
  };
178
197
  this._renderWindow.setSize(width, height);
179
198
  this.sender.stop();
180
- this.sender = new _napolab_texture_bridge_core.TextureSender(this.options.name, width, height);
199
+ try {
200
+ this.sender = new _napolab_texture_bridge_core.TextureSender(this.options.name, width, height);
201
+ } catch (err) {
202
+ this.options = prevOpts;
203
+ this._renderWindow.setSize(prevOpts.width, prevOpts.height);
204
+ this.sender = new _napolab_texture_bridge_core.TextureSender(prevOpts.name, prevOpts.width, prevOpts.height);
205
+ throw err;
206
+ }
181
207
  this.previewManager?.updateSize(width, height);
182
208
  this.emit("resize", width, height);
183
209
  }
@@ -191,6 +217,9 @@ var TextureBridgeImpl = class extends events.EventEmitter {
191
217
  this.emit("disposed");
192
218
  this.removeAllListeners();
193
219
  }
220
+ [Symbol.dispose]() {
221
+ this.dispose();
222
+ }
194
223
  };
195
224
  /**
196
225
  * Create a fully-wired texture bridge: offscreen window, native sender,
@@ -220,19 +249,7 @@ async function createTextureBridge(options) {
220
249
  }
221
250
  const bridge = new TextureBridgeImpl(renderWindow, sender, previewManager, options);
222
251
  renderWindow.webContents.on("paint", (event) => {
223
- const texture = event.texture;
224
- if (!texture?.textureInfo) return;
225
- try {
226
- (0, _napolab_texture_bridge_core.sendTextureFromPaintEvent)(bridge.sender, texture.textureInfo);
227
- bridge.previewManager?.sendFrame(texture);
228
- } catch (err) {
229
- const error = err instanceof Error ? err : new Error(String(err));
230
- bridge.emit("error", error);
231
- } finally {
232
- texture.release?.();
233
- }
234
- const fps = bridge.fpsCounter.tick();
235
- if (fps !== null) bridge.emit("fps", fps);
252
+ bridge.handlePaint(event);
236
253
  });
237
254
  renderWindow.webContents.setFrameRate(frameRate);
238
255
  if (rendererUrl.startsWith("http://") || rendererUrl.startsWith("https://")) await renderWindow.loadURL(rendererUrl);
@@ -275,10 +292,12 @@ var TextureReceiverBridgeImpl = class extends events.EventEmitter {
275
292
  this.emit("disposed");
276
293
  this.removeAllListeners();
277
294
  }
295
+ [Symbol.dispose]() {
296
+ this.dispose();
297
+ }
278
298
  _poll() {
279
299
  if (this._disposed) return;
280
300
  try {
281
- if (!this.receiver.hasNewFrame()) return;
282
301
  const frame = this.receiver.receiveFrame();
283
302
  if (!frame) return;
284
303
  this.emit("frame", frame);
package/dist/index.d.cts CHANGED
@@ -52,8 +52,10 @@ interface TextureBridge {
52
52
  readonly previewWindow: BrowserWindow | null;
53
53
  /** Whether the bridge has been disposed */
54
54
  readonly isDisposed: boolean;
55
- /** Tear down all resources */
55
+ /** Tear down all resources. Terminal operation — the bridge cannot be reused afterward. */
56
56
  dispose(): void;
57
+ /** Alias for dispose(), enabling `using bridge = await createTextureBridge(...)` */
58
+ [Symbol.dispose](): void;
57
59
  }
58
60
  //#endregion
59
61
  //#region src/bridge.d.ts
@@ -84,7 +86,10 @@ interface TextureReceiverBridge {
84
86
  once<K extends keyof ReceiverBridgeEvents>(event: K, listener: (...args: ReceiverBridgeEvents[K]) => void): this;
85
87
  start(): void;
86
88
  stop(): void;
89
+ /** Tear down all resources. Terminal operation — the bridge cannot be reused afterward. */
87
90
  dispose(): void;
91
+ /** Alias for dispose(), enabling `using receiver = createTextureReceiver(...)` */
92
+ [Symbol.dispose](): void;
88
93
  readonly isDisposed: boolean;
89
94
  }
90
95
  declare function createTextureReceiver(options: TextureReceiverBridgeOptions): TextureReceiverBridge;
package/dist/index.d.mts CHANGED
@@ -52,8 +52,10 @@ interface TextureBridge {
52
52
  readonly previewWindow: BrowserWindow | null;
53
53
  /** Whether the bridge has been disposed */
54
54
  readonly isDisposed: boolean;
55
- /** Tear down all resources */
55
+ /** Tear down all resources. Terminal operation — the bridge cannot be reused afterward. */
56
56
  dispose(): void;
57
+ /** Alias for dispose(), enabling `using bridge = await createTextureBridge(...)` */
58
+ [Symbol.dispose](): void;
57
59
  }
58
60
  //#endregion
59
61
  //#region src/bridge.d.ts
@@ -84,7 +86,10 @@ interface TextureReceiverBridge {
84
86
  once<K extends keyof ReceiverBridgeEvents>(event: K, listener: (...args: ReceiverBridgeEvents[K]) => void): this;
85
87
  start(): void;
86
88
  stop(): void;
89
+ /** Tear down all resources. Terminal operation — the bridge cannot be reused afterward. */
87
90
  dispose(): void;
91
+ /** Alias for dispose(), enabling `using receiver = createTextureReceiver(...)` */
92
+ [Symbol.dispose](): void;
88
93
  readonly isDisposed: boolean;
89
94
  }
90
95
  declare function createTextureReceiver(options: TextureReceiverBridgeOptions): TextureReceiverBridge;
package/dist/index.mjs CHANGED
@@ -131,6 +131,24 @@ var TextureBridgeImpl = class extends EventEmitter {
131
131
  get isDisposed() {
132
132
  return this._disposed;
133
133
  }
134
+ /** Handle a paint event from the offscreen BrowserWindow. */
135
+ handlePaint(event) {
136
+ const texture = event.texture;
137
+ if (!texture?.textureInfo) return;
138
+ try {
139
+ if (this._disposed) return;
140
+ sendTextureFromPaintEvent(this.sender, texture.textureInfo);
141
+ this.previewManager?.sendFrame(texture);
142
+ } catch (err) {
143
+ const error = err instanceof Error ? err : new Error(String(err));
144
+ this.emit("error", error);
145
+ } finally {
146
+ texture.release?.();
147
+ }
148
+ if (this._disposed) return;
149
+ const fps = this.fpsCounter.tick();
150
+ if (fps !== null) this.emit("fps", fps);
151
+ }
134
152
  openPreview() {
135
153
  if (this._disposed) return;
136
154
  if (!this.previewManager) this.previewManager = new PreviewManager(this.options.width, this.options.height, this.options.preview);
@@ -141,6 +159,7 @@ var TextureBridgeImpl = class extends EventEmitter {
141
159
  }
142
160
  resize(width, height) {
143
161
  if (this._disposed) return;
162
+ const prevOpts = this.options;
144
163
  this.options = {
145
164
  ...this.options,
146
165
  width,
@@ -148,7 +167,14 @@ var TextureBridgeImpl = class extends EventEmitter {
148
167
  };
149
168
  this._renderWindow.setSize(width, height);
150
169
  this.sender.stop();
151
- this.sender = new TextureSender(this.options.name, width, height);
170
+ try {
171
+ this.sender = new TextureSender(this.options.name, width, height);
172
+ } catch (err) {
173
+ this.options = prevOpts;
174
+ this._renderWindow.setSize(prevOpts.width, prevOpts.height);
175
+ this.sender = new TextureSender(prevOpts.name, prevOpts.width, prevOpts.height);
176
+ throw err;
177
+ }
152
178
  this.previewManager?.updateSize(width, height);
153
179
  this.emit("resize", width, height);
154
180
  }
@@ -162,6 +188,9 @@ var TextureBridgeImpl = class extends EventEmitter {
162
188
  this.emit("disposed");
163
189
  this.removeAllListeners();
164
190
  }
191
+ [Symbol.dispose]() {
192
+ this.dispose();
193
+ }
165
194
  };
166
195
  /**
167
196
  * Create a fully-wired texture bridge: offscreen window, native sender,
@@ -191,19 +220,7 @@ async function createTextureBridge(options) {
191
220
  }
192
221
  const bridge = new TextureBridgeImpl(renderWindow, sender, previewManager, options);
193
222
  renderWindow.webContents.on("paint", (event) => {
194
- const texture = event.texture;
195
- if (!texture?.textureInfo) return;
196
- try {
197
- sendTextureFromPaintEvent(bridge.sender, texture.textureInfo);
198
- bridge.previewManager?.sendFrame(texture);
199
- } catch (err) {
200
- const error = err instanceof Error ? err : new Error(String(err));
201
- bridge.emit("error", error);
202
- } finally {
203
- texture.release?.();
204
- }
205
- const fps = bridge.fpsCounter.tick();
206
- if (fps !== null) bridge.emit("fps", fps);
223
+ bridge.handlePaint(event);
207
224
  });
208
225
  renderWindow.webContents.setFrameRate(frameRate);
209
226
  if (rendererUrl.startsWith("http://") || rendererUrl.startsWith("https://")) await renderWindow.loadURL(rendererUrl);
@@ -246,10 +263,12 @@ var TextureReceiverBridgeImpl = class extends EventEmitter {
246
263
  this.emit("disposed");
247
264
  this.removeAllListeners();
248
265
  }
266
+ [Symbol.dispose]() {
267
+ this.dispose();
268
+ }
249
269
  _poll() {
250
270
  if (this._disposed) return;
251
271
  try {
252
- if (!this.receiver.hasNewFrame()) return;
253
272
  const frame = this.receiver.receiveFrame();
254
273
  if (!frame) return;
255
274
  this.emit("frame", frame);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@napolab/texture-bridge-renderer",
3
- "version": "0.5.1",
3
+ "version": "0.6.1",
4
4
  "description": "High-level factory API for GPU texture bridge (BrowserWindow + Preview + Sender)",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",
@@ -25,7 +25,7 @@
25
25
  "./package.json": "./package.json"
26
26
  },
27
27
  "dependencies": {
28
- "@napolab/texture-bridge-core": "0.5.1"
28
+ "@napolab/texture-bridge-core": "0.6.1"
29
29
  },
30
30
  "peerDependencies": {
31
31
  "electron": ">=40.0.0"