@napolab/texture-bridge-renderer 0.4.1 → 0.5.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 +114 -1
- package/dist/index.d.cts +47 -1
- package/dist/index.d.mts +47 -1
- package/dist/index.mjs +113 -2
- package/package.json +3 -2
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++;
|
|
@@ -238,4 +243,112 @@ async function createTextureBridge(options) {
|
|
|
238
243
|
}
|
|
239
244
|
|
|
240
245
|
//#endregion
|
|
241
|
-
|
|
246
|
+
//#region src/receiver.ts
|
|
247
|
+
var TextureReceiverBridgeImpl = class extends events.EventEmitter {
|
|
248
|
+
constructor(receiver, pollIntervalMs) {
|
|
249
|
+
super();
|
|
250
|
+
this.fpsCounter = new FpsCounter();
|
|
251
|
+
this._disposed = false;
|
|
252
|
+
this._timer = null;
|
|
253
|
+
this.receiver = receiver;
|
|
254
|
+
this.pollIntervalMs = pollIntervalMs;
|
|
255
|
+
}
|
|
256
|
+
get isDisposed() {
|
|
257
|
+
return this._disposed;
|
|
258
|
+
}
|
|
259
|
+
start() {
|
|
260
|
+
if (this._disposed || this._timer) return;
|
|
261
|
+
this.fpsCounter.reset();
|
|
262
|
+
this._timer = setInterval(() => this._poll(), this.pollIntervalMs);
|
|
263
|
+
}
|
|
264
|
+
stop() {
|
|
265
|
+
if (this._timer) {
|
|
266
|
+
clearInterval(this._timer);
|
|
267
|
+
this._timer = null;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
dispose() {
|
|
271
|
+
if (this._disposed) return;
|
|
272
|
+
this._disposed = true;
|
|
273
|
+
this.stop();
|
|
274
|
+
this.receiver.stop();
|
|
275
|
+
this.emit("disposed");
|
|
276
|
+
this.removeAllListeners();
|
|
277
|
+
}
|
|
278
|
+
_poll() {
|
|
279
|
+
if (this._disposed) return;
|
|
280
|
+
try {
|
|
281
|
+
if (!this.receiver.hasNewFrame()) return;
|
|
282
|
+
const frame = this.receiver.receiveFrame();
|
|
283
|
+
if (!frame) return;
|
|
284
|
+
this.emit("frame", frame);
|
|
285
|
+
const fps = this.fpsCounter.tick();
|
|
286
|
+
if (fps !== null) this.emit("fps", fps);
|
|
287
|
+
} catch (err) {
|
|
288
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
289
|
+
this.emit("error", error);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
};
|
|
293
|
+
function createTextureReceiver(options) {
|
|
294
|
+
const { senderName, appName, serverUuid, pollIntervalMs = 16 } = options;
|
|
295
|
+
return new TextureReceiverBridgeImpl(new _napolab_texture_bridge_core.TextureReceiver(senderName, appName, serverUuid), pollIntervalMs);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
//#endregion
|
|
299
|
+
//#region src/discovery.ts
|
|
300
|
+
var SenderDiscovery = class extends events.EventEmitter {
|
|
301
|
+
constructor(..._args) {
|
|
302
|
+
super(..._args);
|
|
303
|
+
this._senders = [];
|
|
304
|
+
this._timer = null;
|
|
305
|
+
this._disposed = false;
|
|
306
|
+
}
|
|
307
|
+
get isDisposed() {
|
|
308
|
+
return this._disposed;
|
|
309
|
+
}
|
|
310
|
+
start(intervalMs = 1e3) {
|
|
311
|
+
if (this._disposed || this._timer) return;
|
|
312
|
+
this._timer = setInterval(() => this._refresh(), intervalMs);
|
|
313
|
+
}
|
|
314
|
+
stop() {
|
|
315
|
+
if (this._timer) {
|
|
316
|
+
clearInterval(this._timer);
|
|
317
|
+
this._timer = null;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
getSenders() {
|
|
321
|
+
return [...this._senders];
|
|
322
|
+
}
|
|
323
|
+
dispose() {
|
|
324
|
+
if (this._disposed) return;
|
|
325
|
+
this._disposed = true;
|
|
326
|
+
this.stop();
|
|
327
|
+
this.removeAllListeners();
|
|
328
|
+
}
|
|
329
|
+
_refresh() {
|
|
330
|
+
if (this._disposed) return;
|
|
331
|
+
try {
|
|
332
|
+
const current = (0, _napolab_texture_bridge_core.listSenders)();
|
|
333
|
+
const prev = this._senders;
|
|
334
|
+
const added = current.filter((c) => !prev.some((p) => this._isSame(c, p)));
|
|
335
|
+
const removed = prev.filter((p) => !current.some((c) => this._isSame(c, p)));
|
|
336
|
+
this._senders = current;
|
|
337
|
+
if (added.length > 0) this.emit("added", added);
|
|
338
|
+
if (removed.length > 0) this.emit("removed", removed);
|
|
339
|
+
if (added.length > 0 || removed.length > 0) this.emit("updated", current);
|
|
340
|
+
} catch (err) {
|
|
341
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
342
|
+
this.emit("error", error);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
_isSame(a, b) {
|
|
346
|
+
if (a.uuid && b.uuid) return a.uuid === b.uuid;
|
|
347
|
+
return a.name === b.name && a.appName === b.appName;
|
|
348
|
+
}
|
|
349
|
+
};
|
|
350
|
+
|
|
351
|
+
//#endregion
|
|
352
|
+
exports.SenderDiscovery = SenderDiscovery;
|
|
353
|
+
exports.createTextureBridge = createTextureBridge;
|
|
354
|
+
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 */
|
|
@@ -63,4 +65,48 @@ interface TextureBridge {
|
|
|
63
65
|
*/
|
|
64
66
|
declare function createTextureBridge(options: TextureBridgeOptions): Promise<TextureBridge>;
|
|
65
67
|
//#endregion
|
|
66
|
-
|
|
68
|
+
//#region src/receiver.d.ts
|
|
69
|
+
interface TextureReceiverBridgeOptions {
|
|
70
|
+
senderName: string;
|
|
71
|
+
appName?: string;
|
|
72
|
+
serverUuid?: string;
|
|
73
|
+
pollIntervalMs?: number;
|
|
74
|
+
}
|
|
75
|
+
interface ReceiverBridgeEvents {
|
|
76
|
+
frame: [frame: ReceivedFrame];
|
|
77
|
+
fps: [fps: number];
|
|
78
|
+
error: [error: Error];
|
|
79
|
+
disposed: [];
|
|
80
|
+
}
|
|
81
|
+
interface TextureReceiverBridge {
|
|
82
|
+
on<K extends keyof ReceiverBridgeEvents>(event: K, listener: (...args: ReceiverBridgeEvents[K]) => void): this;
|
|
83
|
+
off<K extends keyof ReceiverBridgeEvents>(event: K, listener: (...args: ReceiverBridgeEvents[K]) => void): this;
|
|
84
|
+
once<K extends keyof ReceiverBridgeEvents>(event: K, listener: (...args: ReceiverBridgeEvents[K]) => void): this;
|
|
85
|
+
start(): void;
|
|
86
|
+
stop(): void;
|
|
87
|
+
dispose(): void;
|
|
88
|
+
readonly isDisposed: boolean;
|
|
89
|
+
}
|
|
90
|
+
declare function createTextureReceiver(options: TextureReceiverBridgeOptions): TextureReceiverBridge;
|
|
91
|
+
//#endregion
|
|
92
|
+
//#region src/discovery.d.ts
|
|
93
|
+
interface SenderDiscoveryEvents {
|
|
94
|
+
updated: [senders: SenderInfo[]];
|
|
95
|
+
added: [senders: SenderInfo[]];
|
|
96
|
+
removed: [senders: SenderInfo[]];
|
|
97
|
+
error: [error: Error];
|
|
98
|
+
}
|
|
99
|
+
declare class SenderDiscovery extends EventEmitter {
|
|
100
|
+
private _senders;
|
|
101
|
+
private _timer;
|
|
102
|
+
private _disposed;
|
|
103
|
+
get isDisposed(): boolean;
|
|
104
|
+
start(intervalMs?: number): void;
|
|
105
|
+
stop(): void;
|
|
106
|
+
getSenders(): SenderInfo[];
|
|
107
|
+
dispose(): void;
|
|
108
|
+
private _refresh;
|
|
109
|
+
private _isSame;
|
|
110
|
+
}
|
|
111
|
+
//#endregion
|
|
112
|
+
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 */
|
|
@@ -63,4 +65,48 @@ interface TextureBridge {
|
|
|
63
65
|
*/
|
|
64
66
|
declare function createTextureBridge(options: TextureBridgeOptions): Promise<TextureBridge>;
|
|
65
67
|
//#endregion
|
|
66
|
-
|
|
68
|
+
//#region src/receiver.d.ts
|
|
69
|
+
interface TextureReceiverBridgeOptions {
|
|
70
|
+
senderName: string;
|
|
71
|
+
appName?: string;
|
|
72
|
+
serverUuid?: string;
|
|
73
|
+
pollIntervalMs?: number;
|
|
74
|
+
}
|
|
75
|
+
interface ReceiverBridgeEvents {
|
|
76
|
+
frame: [frame: ReceivedFrame];
|
|
77
|
+
fps: [fps: number];
|
|
78
|
+
error: [error: Error];
|
|
79
|
+
disposed: [];
|
|
80
|
+
}
|
|
81
|
+
interface TextureReceiverBridge {
|
|
82
|
+
on<K extends keyof ReceiverBridgeEvents>(event: K, listener: (...args: ReceiverBridgeEvents[K]) => void): this;
|
|
83
|
+
off<K extends keyof ReceiverBridgeEvents>(event: K, listener: (...args: ReceiverBridgeEvents[K]) => void): this;
|
|
84
|
+
once<K extends keyof ReceiverBridgeEvents>(event: K, listener: (...args: ReceiverBridgeEvents[K]) => void): this;
|
|
85
|
+
start(): void;
|
|
86
|
+
stop(): void;
|
|
87
|
+
dispose(): void;
|
|
88
|
+
readonly isDisposed: boolean;
|
|
89
|
+
}
|
|
90
|
+
declare function createTextureReceiver(options: TextureReceiverBridgeOptions): TextureReceiverBridge;
|
|
91
|
+
//#endregion
|
|
92
|
+
//#region src/discovery.d.ts
|
|
93
|
+
interface SenderDiscoveryEvents {
|
|
94
|
+
updated: [senders: SenderInfo[]];
|
|
95
|
+
added: [senders: SenderInfo[]];
|
|
96
|
+
removed: [senders: SenderInfo[]];
|
|
97
|
+
error: [error: Error];
|
|
98
|
+
}
|
|
99
|
+
declare class SenderDiscovery extends EventEmitter {
|
|
100
|
+
private _senders;
|
|
101
|
+
private _timer;
|
|
102
|
+
private _disposed;
|
|
103
|
+
get isDisposed(): boolean;
|
|
104
|
+
start(intervalMs?: number): void;
|
|
105
|
+
stop(): void;
|
|
106
|
+
getSenders(): SenderInfo[];
|
|
107
|
+
dispose(): void;
|
|
108
|
+
private _refresh;
|
|
109
|
+
private _isSame;
|
|
110
|
+
}
|
|
111
|
+
//#endregion
|
|
112
|
+
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++;
|
|
@@ -209,4 +214,110 @@ async function createTextureBridge(options) {
|
|
|
209
214
|
}
|
|
210
215
|
|
|
211
216
|
//#endregion
|
|
212
|
-
|
|
217
|
+
//#region src/receiver.ts
|
|
218
|
+
var TextureReceiverBridgeImpl = class extends EventEmitter {
|
|
219
|
+
constructor(receiver, pollIntervalMs) {
|
|
220
|
+
super();
|
|
221
|
+
this.fpsCounter = new FpsCounter();
|
|
222
|
+
this._disposed = false;
|
|
223
|
+
this._timer = null;
|
|
224
|
+
this.receiver = receiver;
|
|
225
|
+
this.pollIntervalMs = pollIntervalMs;
|
|
226
|
+
}
|
|
227
|
+
get isDisposed() {
|
|
228
|
+
return this._disposed;
|
|
229
|
+
}
|
|
230
|
+
start() {
|
|
231
|
+
if (this._disposed || this._timer) return;
|
|
232
|
+
this.fpsCounter.reset();
|
|
233
|
+
this._timer = setInterval(() => this._poll(), this.pollIntervalMs);
|
|
234
|
+
}
|
|
235
|
+
stop() {
|
|
236
|
+
if (this._timer) {
|
|
237
|
+
clearInterval(this._timer);
|
|
238
|
+
this._timer = null;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
dispose() {
|
|
242
|
+
if (this._disposed) return;
|
|
243
|
+
this._disposed = true;
|
|
244
|
+
this.stop();
|
|
245
|
+
this.receiver.stop();
|
|
246
|
+
this.emit("disposed");
|
|
247
|
+
this.removeAllListeners();
|
|
248
|
+
}
|
|
249
|
+
_poll() {
|
|
250
|
+
if (this._disposed) return;
|
|
251
|
+
try {
|
|
252
|
+
if (!this.receiver.hasNewFrame()) return;
|
|
253
|
+
const frame = this.receiver.receiveFrame();
|
|
254
|
+
if (!frame) return;
|
|
255
|
+
this.emit("frame", frame);
|
|
256
|
+
const fps = this.fpsCounter.tick();
|
|
257
|
+
if (fps !== null) this.emit("fps", fps);
|
|
258
|
+
} catch (err) {
|
|
259
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
260
|
+
this.emit("error", error);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
};
|
|
264
|
+
function createTextureReceiver(options) {
|
|
265
|
+
const { senderName, appName, serverUuid, pollIntervalMs = 16 } = options;
|
|
266
|
+
return new TextureReceiverBridgeImpl(new TextureReceiver(senderName, appName, serverUuid), pollIntervalMs);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
//#endregion
|
|
270
|
+
//#region src/discovery.ts
|
|
271
|
+
var SenderDiscovery = class extends EventEmitter {
|
|
272
|
+
constructor(..._args) {
|
|
273
|
+
super(..._args);
|
|
274
|
+
this._senders = [];
|
|
275
|
+
this._timer = null;
|
|
276
|
+
this._disposed = false;
|
|
277
|
+
}
|
|
278
|
+
get isDisposed() {
|
|
279
|
+
return this._disposed;
|
|
280
|
+
}
|
|
281
|
+
start(intervalMs = 1e3) {
|
|
282
|
+
if (this._disposed || this._timer) return;
|
|
283
|
+
this._timer = setInterval(() => this._refresh(), intervalMs);
|
|
284
|
+
}
|
|
285
|
+
stop() {
|
|
286
|
+
if (this._timer) {
|
|
287
|
+
clearInterval(this._timer);
|
|
288
|
+
this._timer = null;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
getSenders() {
|
|
292
|
+
return [...this._senders];
|
|
293
|
+
}
|
|
294
|
+
dispose() {
|
|
295
|
+
if (this._disposed) return;
|
|
296
|
+
this._disposed = true;
|
|
297
|
+
this.stop();
|
|
298
|
+
this.removeAllListeners();
|
|
299
|
+
}
|
|
300
|
+
_refresh() {
|
|
301
|
+
if (this._disposed) return;
|
|
302
|
+
try {
|
|
303
|
+
const current = listSenders();
|
|
304
|
+
const prev = this._senders;
|
|
305
|
+
const added = current.filter((c) => !prev.some((p) => this._isSame(c, p)));
|
|
306
|
+
const removed = prev.filter((p) => !current.some((c) => this._isSame(c, p)));
|
|
307
|
+
this._senders = current;
|
|
308
|
+
if (added.length > 0) this.emit("added", added);
|
|
309
|
+
if (removed.length > 0) this.emit("removed", removed);
|
|
310
|
+
if (added.length > 0 || removed.length > 0) this.emit("updated", current);
|
|
311
|
+
} catch (err) {
|
|
312
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
313
|
+
this.emit("error", error);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
_isSame(a, b) {
|
|
317
|
+
if (a.uuid && b.uuid) return a.uuid === b.uuid;
|
|
318
|
+
return a.name === b.name && a.appName === b.appName;
|
|
319
|
+
}
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
//#endregion
|
|
323
|
+
export { SenderDiscovery, createTextureBridge, createTextureReceiver };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@napolab/texture-bridge-renderer",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.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.
|
|
28
|
+
"@napolab/texture-bridge-core": "0.5.1"
|
|
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
|
}
|