@napolab/texture-bridge-renderer 0.4.1 → 0.6.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/dist/index.cjs CHANGED
@@ -121,6 +121,11 @@ var FpsCounter = class {
121
121
  this.count = 0;
122
122
  this.lastTime = Date.now();
123
123
  }
124
+ /** Reset the counter, discarding any accumulated frames and time. */
125
+ reset() {
126
+ this.count = 0;
127
+ this.lastTime = Date.now();
128
+ }
124
129
  /** Call on every frame. Returns FPS when 1 second has elapsed, otherwise null. */
125
130
  tick() {
126
131
  this.count++;
@@ -155,6 +160,24 @@ var TextureBridgeImpl = class extends events.EventEmitter {
155
160
  get isDisposed() {
156
161
  return this._disposed;
157
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
+ }
158
181
  openPreview() {
159
182
  if (this._disposed) return;
160
183
  if (!this.previewManager) this.previewManager = new PreviewManager(this.options.width, this.options.height, this.options.preview);
@@ -165,6 +188,7 @@ var TextureBridgeImpl = class extends events.EventEmitter {
165
188
  }
166
189
  resize(width, height) {
167
190
  if (this._disposed) return;
191
+ const prevOpts = this.options;
168
192
  this.options = {
169
193
  ...this.options,
170
194
  width,
@@ -172,7 +196,14 @@ var TextureBridgeImpl = class extends events.EventEmitter {
172
196
  };
173
197
  this._renderWindow.setSize(width, height);
174
198
  this.sender.stop();
175
- 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
+ }
176
207
  this.previewManager?.updateSize(width, height);
177
208
  this.emit("resize", width, height);
178
209
  }
@@ -186,6 +217,9 @@ var TextureBridgeImpl = class extends events.EventEmitter {
186
217
  this.emit("disposed");
187
218
  this.removeAllListeners();
188
219
  }
220
+ [Symbol.dispose]() {
221
+ this.dispose();
222
+ }
189
223
  };
190
224
  /**
191
225
  * Create a fully-wired texture bridge: offscreen window, native sender,
@@ -215,19 +249,7 @@ async function createTextureBridge(options) {
215
249
  }
216
250
  const bridge = new TextureBridgeImpl(renderWindow, sender, previewManager, options);
217
251
  renderWindow.webContents.on("paint", (event) => {
218
- const texture = event.texture;
219
- if (!texture?.textureInfo) return;
220
- try {
221
- (0, _napolab_texture_bridge_core.sendTextureFromPaintEvent)(bridge.sender, texture.textureInfo);
222
- bridge.previewManager?.sendFrame(texture);
223
- } catch (err) {
224
- const error = err instanceof Error ? err : new Error(String(err));
225
- bridge.emit("error", error);
226
- } finally {
227
- texture.release?.();
228
- }
229
- const fps = bridge.fpsCounter.tick();
230
- if (fps !== null) bridge.emit("fps", fps);
252
+ bridge.handlePaint(event);
231
253
  });
232
254
  renderWindow.webContents.setFrameRate(frameRate);
233
255
  if (rendererUrl.startsWith("http://") || rendererUrl.startsWith("https://")) await renderWindow.loadURL(rendererUrl);
@@ -238,4 +260,115 @@ async function createTextureBridge(options) {
238
260
  }
239
261
 
240
262
  //#endregion
241
- exports.createTextureBridge = createTextureBridge;
263
+ //#region src/receiver.ts
264
+ var TextureReceiverBridgeImpl = class extends events.EventEmitter {
265
+ constructor(receiver, pollIntervalMs) {
266
+ super();
267
+ this.fpsCounter = new FpsCounter();
268
+ this._disposed = false;
269
+ this._timer = null;
270
+ this.receiver = receiver;
271
+ this.pollIntervalMs = pollIntervalMs;
272
+ }
273
+ get isDisposed() {
274
+ return this._disposed;
275
+ }
276
+ start() {
277
+ if (this._disposed || this._timer) return;
278
+ this.fpsCounter.reset();
279
+ this._timer = setInterval(() => this._poll(), this.pollIntervalMs);
280
+ }
281
+ stop() {
282
+ if (this._timer) {
283
+ clearInterval(this._timer);
284
+ this._timer = null;
285
+ }
286
+ }
287
+ dispose() {
288
+ if (this._disposed) return;
289
+ this._disposed = true;
290
+ this.stop();
291
+ this.receiver.stop();
292
+ this.emit("disposed");
293
+ this.removeAllListeners();
294
+ }
295
+ [Symbol.dispose]() {
296
+ this.dispose();
297
+ }
298
+ _poll() {
299
+ if (this._disposed) return;
300
+ try {
301
+ if (!this.receiver.hasNewFrame()) return;
302
+ const frame = this.receiver.receiveFrame();
303
+ if (!frame) return;
304
+ this.emit("frame", frame);
305
+ const fps = this.fpsCounter.tick();
306
+ if (fps !== null) this.emit("fps", fps);
307
+ } catch (err) {
308
+ const error = err instanceof Error ? err : new Error(String(err));
309
+ this.emit("error", error);
310
+ }
311
+ }
312
+ };
313
+ function createTextureReceiver(options) {
314
+ const { senderName, appName, serverUuid, pollIntervalMs = 16 } = options;
315
+ return new TextureReceiverBridgeImpl(new _napolab_texture_bridge_core.TextureReceiver(senderName, appName, serverUuid), pollIntervalMs);
316
+ }
317
+
318
+ //#endregion
319
+ //#region src/discovery.ts
320
+ var SenderDiscovery = class extends events.EventEmitter {
321
+ constructor(..._args) {
322
+ super(..._args);
323
+ this._senders = [];
324
+ this._timer = null;
325
+ this._disposed = false;
326
+ }
327
+ get isDisposed() {
328
+ return this._disposed;
329
+ }
330
+ start(intervalMs = 1e3) {
331
+ if (this._disposed || this._timer) return;
332
+ this._timer = setInterval(() => this._refresh(), intervalMs);
333
+ }
334
+ stop() {
335
+ if (this._timer) {
336
+ clearInterval(this._timer);
337
+ this._timer = null;
338
+ }
339
+ }
340
+ getSenders() {
341
+ return [...this._senders];
342
+ }
343
+ dispose() {
344
+ if (this._disposed) return;
345
+ this._disposed = true;
346
+ this.stop();
347
+ this.removeAllListeners();
348
+ }
349
+ _refresh() {
350
+ if (this._disposed) return;
351
+ try {
352
+ const current = (0, _napolab_texture_bridge_core.listSenders)();
353
+ const prev = this._senders;
354
+ const added = current.filter((c) => !prev.some((p) => this._isSame(c, p)));
355
+ const removed = prev.filter((p) => !current.some((c) => this._isSame(c, p)));
356
+ this._senders = current;
357
+ if (added.length > 0) this.emit("added", added);
358
+ if (removed.length > 0) this.emit("removed", removed);
359
+ if (added.length > 0 || removed.length > 0) this.emit("updated", current);
360
+ } catch (err) {
361
+ const error = err instanceof Error ? err : new Error(String(err));
362
+ this.emit("error", error);
363
+ }
364
+ }
365
+ _isSame(a, b) {
366
+ if (a.uuid && b.uuid) return a.uuid === b.uuid;
367
+ return a.name === b.name && a.appName === b.appName;
368
+ }
369
+ };
370
+
371
+ //#endregion
372
+ exports.SenderDiscovery = SenderDiscovery;
373
+ exports.createTextureBridge = createTextureBridge;
374
+ exports.createTextureReceiver = createTextureReceiver;
package/dist/index.d.cts CHANGED
@@ -1,4 +1,6 @@
1
1
  import { BrowserWindow } from "electron";
2
+ import { ReceivedFrame, SenderInfo } from "@napolab/texture-bridge-core";
3
+ import { EventEmitter } from "events";
2
4
 
3
5
  //#region src/types.d.ts
4
6
  /** Options for the preview window */
@@ -50,8 +52,10 @@ interface TextureBridge {
50
52
  readonly previewWindow: BrowserWindow | null;
51
53
  /** Whether the bridge has been disposed */
52
54
  readonly isDisposed: boolean;
53
- /** Tear down all resources */
55
+ /** Tear down all resources. Terminal operation — the bridge cannot be reused afterward. */
54
56
  dispose(): void;
57
+ /** Alias for dispose(), enabling `using bridge = await createTextureBridge(...)` */
58
+ [Symbol.dispose](): void;
55
59
  }
56
60
  //#endregion
57
61
  //#region src/bridge.d.ts
@@ -63,4 +67,51 @@ interface TextureBridge {
63
67
  */
64
68
  declare function createTextureBridge(options: TextureBridgeOptions): Promise<TextureBridge>;
65
69
  //#endregion
66
- export { type BridgeEvents, type PreviewOptions, type TextureBridge, type TextureBridgeOptions, createTextureBridge };
70
+ //#region src/receiver.d.ts
71
+ interface TextureReceiverBridgeOptions {
72
+ senderName: string;
73
+ appName?: string;
74
+ serverUuid?: string;
75
+ pollIntervalMs?: number;
76
+ }
77
+ interface ReceiverBridgeEvents {
78
+ frame: [frame: ReceivedFrame];
79
+ fps: [fps: number];
80
+ error: [error: Error];
81
+ disposed: [];
82
+ }
83
+ interface TextureReceiverBridge {
84
+ on<K extends keyof ReceiverBridgeEvents>(event: K, listener: (...args: ReceiverBridgeEvents[K]) => void): this;
85
+ off<K extends keyof ReceiverBridgeEvents>(event: K, listener: (...args: ReceiverBridgeEvents[K]) => void): this;
86
+ once<K extends keyof ReceiverBridgeEvents>(event: K, listener: (...args: ReceiverBridgeEvents[K]) => void): this;
87
+ start(): void;
88
+ stop(): void;
89
+ /** Tear down all resources. Terminal operation — the bridge cannot be reused afterward. */
90
+ dispose(): void;
91
+ /** Alias for dispose(), enabling `using receiver = createTextureReceiver(...)` */
92
+ [Symbol.dispose](): void;
93
+ readonly isDisposed: boolean;
94
+ }
95
+ declare function createTextureReceiver(options: TextureReceiverBridgeOptions): TextureReceiverBridge;
96
+ //#endregion
97
+ //#region src/discovery.d.ts
98
+ interface SenderDiscoveryEvents {
99
+ updated: [senders: SenderInfo[]];
100
+ added: [senders: SenderInfo[]];
101
+ removed: [senders: SenderInfo[]];
102
+ error: [error: Error];
103
+ }
104
+ declare class SenderDiscovery extends EventEmitter {
105
+ private _senders;
106
+ private _timer;
107
+ private _disposed;
108
+ get isDisposed(): boolean;
109
+ start(intervalMs?: number): void;
110
+ stop(): void;
111
+ getSenders(): SenderInfo[];
112
+ dispose(): void;
113
+ private _refresh;
114
+ private _isSame;
115
+ }
116
+ //#endregion
117
+ export { type BridgeEvents, type PreviewOptions, type ReceiverBridgeEvents, SenderDiscovery, type SenderDiscoveryEvents, type TextureBridge, type TextureBridgeOptions, type TextureReceiverBridge, type TextureReceiverBridgeOptions, createTextureBridge, createTextureReceiver };
package/dist/index.d.mts CHANGED
@@ -1,4 +1,6 @@
1
+ import { EventEmitter } from "events";
1
2
  import { BrowserWindow } from "electron";
3
+ import { ReceivedFrame, SenderInfo } from "@napolab/texture-bridge-core";
2
4
 
3
5
  //#region src/types.d.ts
4
6
  /** Options for the preview window */
@@ -50,8 +52,10 @@ interface TextureBridge {
50
52
  readonly previewWindow: BrowserWindow | null;
51
53
  /** Whether the bridge has been disposed */
52
54
  readonly isDisposed: boolean;
53
- /** Tear down all resources */
55
+ /** Tear down all resources. Terminal operation — the bridge cannot be reused afterward. */
54
56
  dispose(): void;
57
+ /** Alias for dispose(), enabling `using bridge = await createTextureBridge(...)` */
58
+ [Symbol.dispose](): void;
55
59
  }
56
60
  //#endregion
57
61
  //#region src/bridge.d.ts
@@ -63,4 +67,51 @@ interface TextureBridge {
63
67
  */
64
68
  declare function createTextureBridge(options: TextureBridgeOptions): Promise<TextureBridge>;
65
69
  //#endregion
66
- export { type BridgeEvents, type PreviewOptions, type TextureBridge, type TextureBridgeOptions, createTextureBridge };
70
+ //#region src/receiver.d.ts
71
+ interface TextureReceiverBridgeOptions {
72
+ senderName: string;
73
+ appName?: string;
74
+ serverUuid?: string;
75
+ pollIntervalMs?: number;
76
+ }
77
+ interface ReceiverBridgeEvents {
78
+ frame: [frame: ReceivedFrame];
79
+ fps: [fps: number];
80
+ error: [error: Error];
81
+ disposed: [];
82
+ }
83
+ interface TextureReceiverBridge {
84
+ on<K extends keyof ReceiverBridgeEvents>(event: K, listener: (...args: ReceiverBridgeEvents[K]) => void): this;
85
+ off<K extends keyof ReceiverBridgeEvents>(event: K, listener: (...args: ReceiverBridgeEvents[K]) => void): this;
86
+ once<K extends keyof ReceiverBridgeEvents>(event: K, listener: (...args: ReceiverBridgeEvents[K]) => void): this;
87
+ start(): void;
88
+ stop(): void;
89
+ /** Tear down all resources. Terminal operation — the bridge cannot be reused afterward. */
90
+ dispose(): void;
91
+ /** Alias for dispose(), enabling `using receiver = createTextureReceiver(...)` */
92
+ [Symbol.dispose](): void;
93
+ readonly isDisposed: boolean;
94
+ }
95
+ declare function createTextureReceiver(options: TextureReceiverBridgeOptions): TextureReceiverBridge;
96
+ //#endregion
97
+ //#region src/discovery.d.ts
98
+ interface SenderDiscoveryEvents {
99
+ updated: [senders: SenderInfo[]];
100
+ added: [senders: SenderInfo[]];
101
+ removed: [senders: SenderInfo[]];
102
+ error: [error: Error];
103
+ }
104
+ declare class SenderDiscovery extends EventEmitter {
105
+ private _senders;
106
+ private _timer;
107
+ private _disposed;
108
+ get isDisposed(): boolean;
109
+ start(intervalMs?: number): void;
110
+ stop(): void;
111
+ getSenders(): SenderInfo[];
112
+ dispose(): void;
113
+ private _refresh;
114
+ private _isSame;
115
+ }
116
+ //#endregion
117
+ export { type BridgeEvents, type PreviewOptions, type ReceiverBridgeEvents, SenderDiscovery, type SenderDiscoveryEvents, type TextureBridge, type TextureBridgeOptions, type TextureReceiverBridge, type TextureReceiverBridgeOptions, createTextureBridge, createTextureReceiver };
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { EventEmitter } from "events";
2
2
  import { BrowserWindow, app, ipcMain, sharedTexture } from "electron";
3
- import { TextureSender, sendTextureFromPaintEvent } from "@napolab/texture-bridge-core";
3
+ import { TextureReceiver, TextureSender, listSenders, sendTextureFromPaintEvent } from "@napolab/texture-bridge-core";
4
4
  import path from "path";
5
5
 
6
6
  //#region src/preview-manager.ts
@@ -92,6 +92,11 @@ var FpsCounter = class {
92
92
  this.count = 0;
93
93
  this.lastTime = Date.now();
94
94
  }
95
+ /** Reset the counter, discarding any accumulated frames and time. */
96
+ reset() {
97
+ this.count = 0;
98
+ this.lastTime = Date.now();
99
+ }
95
100
  /** Call on every frame. Returns FPS when 1 second has elapsed, otherwise null. */
96
101
  tick() {
97
102
  this.count++;
@@ -126,6 +131,24 @@ var TextureBridgeImpl = class extends EventEmitter {
126
131
  get isDisposed() {
127
132
  return this._disposed;
128
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
+ }
129
152
  openPreview() {
130
153
  if (this._disposed) return;
131
154
  if (!this.previewManager) this.previewManager = new PreviewManager(this.options.width, this.options.height, this.options.preview);
@@ -136,6 +159,7 @@ var TextureBridgeImpl = class extends EventEmitter {
136
159
  }
137
160
  resize(width, height) {
138
161
  if (this._disposed) return;
162
+ const prevOpts = this.options;
139
163
  this.options = {
140
164
  ...this.options,
141
165
  width,
@@ -143,7 +167,14 @@ var TextureBridgeImpl = class extends EventEmitter {
143
167
  };
144
168
  this._renderWindow.setSize(width, height);
145
169
  this.sender.stop();
146
- 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
+ }
147
178
  this.previewManager?.updateSize(width, height);
148
179
  this.emit("resize", width, height);
149
180
  }
@@ -157,6 +188,9 @@ var TextureBridgeImpl = class extends EventEmitter {
157
188
  this.emit("disposed");
158
189
  this.removeAllListeners();
159
190
  }
191
+ [Symbol.dispose]() {
192
+ this.dispose();
193
+ }
160
194
  };
161
195
  /**
162
196
  * Create a fully-wired texture bridge: offscreen window, native sender,
@@ -186,19 +220,7 @@ async function createTextureBridge(options) {
186
220
  }
187
221
  const bridge = new TextureBridgeImpl(renderWindow, sender, previewManager, options);
188
222
  renderWindow.webContents.on("paint", (event) => {
189
- const texture = event.texture;
190
- if (!texture?.textureInfo) return;
191
- try {
192
- sendTextureFromPaintEvent(bridge.sender, texture.textureInfo);
193
- bridge.previewManager?.sendFrame(texture);
194
- } catch (err) {
195
- const error = err instanceof Error ? err : new Error(String(err));
196
- bridge.emit("error", error);
197
- } finally {
198
- texture.release?.();
199
- }
200
- const fps = bridge.fpsCounter.tick();
201
- if (fps !== null) bridge.emit("fps", fps);
223
+ bridge.handlePaint(event);
202
224
  });
203
225
  renderWindow.webContents.setFrameRate(frameRate);
204
226
  if (rendererUrl.startsWith("http://") || rendererUrl.startsWith("https://")) await renderWindow.loadURL(rendererUrl);
@@ -209,4 +231,113 @@ async function createTextureBridge(options) {
209
231
  }
210
232
 
211
233
  //#endregion
212
- export { createTextureBridge };
234
+ //#region src/receiver.ts
235
+ var TextureReceiverBridgeImpl = class extends EventEmitter {
236
+ constructor(receiver, pollIntervalMs) {
237
+ super();
238
+ this.fpsCounter = new FpsCounter();
239
+ this._disposed = false;
240
+ this._timer = null;
241
+ this.receiver = receiver;
242
+ this.pollIntervalMs = pollIntervalMs;
243
+ }
244
+ get isDisposed() {
245
+ return this._disposed;
246
+ }
247
+ start() {
248
+ if (this._disposed || this._timer) return;
249
+ this.fpsCounter.reset();
250
+ this._timer = setInterval(() => this._poll(), this.pollIntervalMs);
251
+ }
252
+ stop() {
253
+ if (this._timer) {
254
+ clearInterval(this._timer);
255
+ this._timer = null;
256
+ }
257
+ }
258
+ dispose() {
259
+ if (this._disposed) return;
260
+ this._disposed = true;
261
+ this.stop();
262
+ this.receiver.stop();
263
+ this.emit("disposed");
264
+ this.removeAllListeners();
265
+ }
266
+ [Symbol.dispose]() {
267
+ this.dispose();
268
+ }
269
+ _poll() {
270
+ if (this._disposed) return;
271
+ try {
272
+ if (!this.receiver.hasNewFrame()) return;
273
+ const frame = this.receiver.receiveFrame();
274
+ if (!frame) return;
275
+ this.emit("frame", frame);
276
+ const fps = this.fpsCounter.tick();
277
+ if (fps !== null) this.emit("fps", fps);
278
+ } catch (err) {
279
+ const error = err instanceof Error ? err : new Error(String(err));
280
+ this.emit("error", error);
281
+ }
282
+ }
283
+ };
284
+ function createTextureReceiver(options) {
285
+ const { senderName, appName, serverUuid, pollIntervalMs = 16 } = options;
286
+ return new TextureReceiverBridgeImpl(new TextureReceiver(senderName, appName, serverUuid), pollIntervalMs);
287
+ }
288
+
289
+ //#endregion
290
+ //#region src/discovery.ts
291
+ var SenderDiscovery = class extends EventEmitter {
292
+ constructor(..._args) {
293
+ super(..._args);
294
+ this._senders = [];
295
+ this._timer = null;
296
+ this._disposed = false;
297
+ }
298
+ get isDisposed() {
299
+ return this._disposed;
300
+ }
301
+ start(intervalMs = 1e3) {
302
+ if (this._disposed || this._timer) return;
303
+ this._timer = setInterval(() => this._refresh(), intervalMs);
304
+ }
305
+ stop() {
306
+ if (this._timer) {
307
+ clearInterval(this._timer);
308
+ this._timer = null;
309
+ }
310
+ }
311
+ getSenders() {
312
+ return [...this._senders];
313
+ }
314
+ dispose() {
315
+ if (this._disposed) return;
316
+ this._disposed = true;
317
+ this.stop();
318
+ this.removeAllListeners();
319
+ }
320
+ _refresh() {
321
+ if (this._disposed) return;
322
+ try {
323
+ const current = listSenders();
324
+ const prev = this._senders;
325
+ const added = current.filter((c) => !prev.some((p) => this._isSame(c, p)));
326
+ const removed = prev.filter((p) => !current.some((c) => this._isSame(c, p)));
327
+ this._senders = current;
328
+ if (added.length > 0) this.emit("added", added);
329
+ if (removed.length > 0) this.emit("removed", removed);
330
+ if (added.length > 0 || removed.length > 0) this.emit("updated", current);
331
+ } catch (err) {
332
+ const error = err instanceof Error ? err : new Error(String(err));
333
+ this.emit("error", error);
334
+ }
335
+ }
336
+ _isSame(a, b) {
337
+ if (a.uuid && b.uuid) return a.uuid === b.uuid;
338
+ return a.name === b.name && a.appName === b.appName;
339
+ }
340
+ };
341
+
342
+ //#endregion
343
+ export { SenderDiscovery, createTextureBridge, createTextureReceiver };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@napolab/texture-bridge-renderer",
3
- "version": "0.4.1",
3
+ "version": "0.6.0",
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.4.1"
28
+ "@napolab/texture-bridge-core": "0.6.0"
29
29
  },
30
30
  "peerDependencies": {
31
31
  "electron": ">=40.0.0"
@@ -53,6 +53,7 @@
53
53
  ],
54
54
  "scripts": {
55
55
  "build": "tsdown src/index.ts src/client/index.ts src/client/worker-protocol.ts --format cjs,esm --dts && cp -r src/assets dist/assets",
56
+ "test": "vitest run",
56
57
  "typecheck": "tsgo --noEmit"
57
58
  }
58
59
  }