dreaction-client-core 1.1.11 → 1.2.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/lib/index.d.ts +17 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +54 -2
- package/lib/utils/fps.d.ts +2 -0
- package/lib/utils/fps.d.ts.map +1 -0
- package/lib/utils/fps.js +30 -0
- package/package.json +2 -2
- package/src/index.ts +67 -2
- package/src/utils/fps.ts +33 -0
package/lib/index.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export { assertHasLoggerPlugin } from './plugins/logger';
|
|
|
6
6
|
export type { LoggerPlugin } from './plugins/logger';
|
|
7
7
|
export { assertHasStateResponsePlugin, hasStateResponsePlugin, } from './plugins/state-responses';
|
|
8
8
|
export type { StateResponsePlugin } from './plugins/state-responses';
|
|
9
|
+
export { runFPSMeter } from './utils/fps';
|
|
9
10
|
export interface LifeCycleMethods {
|
|
10
11
|
onCommand?: (command: Command) => void;
|
|
11
12
|
onConnect?: () => void;
|
|
@@ -62,6 +63,10 @@ export interface DReactionCore {
|
|
|
62
63
|
configure: (options?: ClientOptions<this>) => ClientOptions<this>['plugins'] extends PluginCreator<this>[] ? this & InferFeaturesFromPlugins<this, ClientOptions<this>['plugins']> : this;
|
|
63
64
|
use: <P extends PluginCreator<this>>(pluginCreator: P) => this & InferFeaturesFromPlugin<this, P>;
|
|
64
65
|
connect: () => this;
|
|
66
|
+
/**
|
|
67
|
+
* Wait for connection to be established
|
|
68
|
+
*/
|
|
69
|
+
waitForConnect: () => Promise<void>;
|
|
65
70
|
}
|
|
66
71
|
export type InferFeatures<Client = DReactionCore, PC extends PluginCreator<Client> = PluginCreator<Client>> = PC extends (client: Client) => {
|
|
67
72
|
features: infer U;
|
|
@@ -148,6 +153,12 @@ export declare class DReactionImpl implements Omit<DReactionCore, 'options' | 'p
|
|
|
148
153
|
* The current ID for custom commands
|
|
149
154
|
*/
|
|
150
155
|
customCommandLatestId: number;
|
|
156
|
+
/**
|
|
157
|
+
* Promise resolvers for connection wait
|
|
158
|
+
*/
|
|
159
|
+
private connectPromiseResolve;
|
|
160
|
+
private connectPromiseReject;
|
|
161
|
+
private connectPromise;
|
|
151
162
|
/**
|
|
152
163
|
* Starts a timer and returns a function you can call to stop it and return the elapsed time.
|
|
153
164
|
*/
|
|
@@ -160,7 +171,7 @@ export declare class DReactionImpl implements Omit<DReactionCore, 'options' | 'p
|
|
|
160
171
|
/**
|
|
161
172
|
* Connect to the DReaction server.
|
|
162
173
|
*/
|
|
163
|
-
connect(): this
|
|
174
|
+
connect(): this;
|
|
164
175
|
/**
|
|
165
176
|
* Sends a command to the server
|
|
166
177
|
*/
|
|
@@ -178,6 +189,11 @@ export declare class DReactionImpl implements Omit<DReactionCore, 'options' | 'p
|
|
|
178
189
|
*/
|
|
179
190
|
use(pluginCreator: PluginCreator<this>): this & PluginFeatures<this, typeof pluginCreator>;
|
|
180
191
|
registerCustomCommand(config: CustomCommand, optHandler?: () => void): () => void;
|
|
192
|
+
/**
|
|
193
|
+
* Wait for connection to be established.
|
|
194
|
+
* Returns a promise that resolves when the connection is ready.
|
|
195
|
+
*/
|
|
196
|
+
waitForConnect(): Promise<void>;
|
|
181
197
|
}
|
|
182
198
|
export declare function createClient<Client extends DReactionCore = DReactionCore>(options?: ClientOptions<Client>): Client;
|
|
183
199
|
//# sourceMappingURL=index.d.ts.map
|
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,IAAI,CAAC;AAC3B,OAAO,KAAK,EACV,OAAO,EACP,UAAU,EACV,cAAc,EACd,gBAAgB,EAChB,4BAA4B,EAC7B,MAAM,oBAAoB,CAAC;AAW5B,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,YAAY,EAAE,aAAa,EAAE,CAAC;AAC9B,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AACzD,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EACL,4BAA4B,EAC5B,sBAAsB,GACvB,MAAM,2BAA2B,CAAC;AACnC,YAAY,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/lib/index.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.DReactionImpl = exports.corePlugins = exports.hasStateResponsePlugin = exports.assertHasStateResponsePlugin = exports.assertHasLoggerPlugin = void 0;
|
|
6
|
+
exports.DReactionImpl = exports.corePlugins = exports.runFPSMeter = exports.hasStateResponsePlugin = exports.assertHasStateResponsePlugin = exports.assertHasLoggerPlugin = void 0;
|
|
7
7
|
exports.createClient = createClient;
|
|
8
8
|
const validate_1 = __importDefault(require("./validate"));
|
|
9
9
|
const logger_1 = __importDefault(require("./plugins/logger"));
|
|
@@ -20,6 +20,8 @@ Object.defineProperty(exports, "assertHasLoggerPlugin", { enumerable: true, get:
|
|
|
20
20
|
var state_responses_2 = require("./plugins/state-responses");
|
|
21
21
|
Object.defineProperty(exports, "assertHasStateResponsePlugin", { enumerable: true, get: function () { return state_responses_2.assertHasStateResponsePlugin; } });
|
|
22
22
|
Object.defineProperty(exports, "hasStateResponsePlugin", { enumerable: true, get: function () { return state_responses_2.hasStateResponsePlugin; } });
|
|
23
|
+
var fps_1 = require("./utils/fps");
|
|
24
|
+
Object.defineProperty(exports, "runFPSMeter", { enumerable: true, get: function () { return fps_1.runFPSMeter; } });
|
|
23
25
|
exports.corePlugins = [
|
|
24
26
|
(0, image_1.default)(),
|
|
25
27
|
(0, logger_1.default)(),
|
|
@@ -80,6 +82,12 @@ class DReactionImpl {
|
|
|
80
82
|
* The current ID for custom commands
|
|
81
83
|
*/
|
|
82
84
|
customCommandLatestId = 1;
|
|
85
|
+
/**
|
|
86
|
+
* Promise resolvers for connection wait
|
|
87
|
+
*/
|
|
88
|
+
connectPromiseResolve = null;
|
|
89
|
+
connectPromiseReject = null;
|
|
90
|
+
connectPromise = null;
|
|
83
91
|
/**
|
|
84
92
|
* Starts a timer and returns a function you can call to stop it and return the elapsed time.
|
|
85
93
|
*/
|
|
@@ -114,6 +122,12 @@ class DReactionImpl {
|
|
|
114
122
|
close() {
|
|
115
123
|
this.connected = false;
|
|
116
124
|
this.socket && this.socket.close && this.socket.close();
|
|
125
|
+
// Reject any pending connection promise
|
|
126
|
+
if (this.connectPromiseReject) {
|
|
127
|
+
this.connectPromiseReject(new Error('Connection closed'));
|
|
128
|
+
this.connectPromiseResolve = null;
|
|
129
|
+
this.connectPromiseReject = null;
|
|
130
|
+
}
|
|
117
131
|
return this;
|
|
118
132
|
}
|
|
119
133
|
/**
|
|
@@ -121,11 +135,21 @@ class DReactionImpl {
|
|
|
121
135
|
*/
|
|
122
136
|
connect() {
|
|
123
137
|
this.connected = true;
|
|
138
|
+
// Create a new promise for this connection attempt
|
|
139
|
+
this.connectPromise = new Promise((resolve, reject) => {
|
|
140
|
+
this.connectPromiseResolve = resolve;
|
|
141
|
+
this.connectPromiseReject = reject;
|
|
142
|
+
});
|
|
124
143
|
const { createSocket, secure, host, environment, port, name, client = {}, info = {}, getClientId, } = this.options;
|
|
125
144
|
const { onCommand, onConnect, onDisconnect } = this.options;
|
|
126
145
|
if (!host) {
|
|
127
146
|
console.log('host is not config, skip connect.');
|
|
128
|
-
|
|
147
|
+
if (this.connectPromiseReject) {
|
|
148
|
+
this.connectPromiseReject(new Error('Host is not configured'));
|
|
149
|
+
this.connectPromiseResolve = null;
|
|
150
|
+
this.connectPromiseReject = null;
|
|
151
|
+
}
|
|
152
|
+
return this;
|
|
129
153
|
}
|
|
130
154
|
// establish a connection to the server
|
|
131
155
|
const protocol = secure ? 'wss' : 'ws';
|
|
@@ -136,6 +160,12 @@ class DReactionImpl {
|
|
|
136
160
|
onConnect && onConnect();
|
|
137
161
|
// trigger our plugins onConnect
|
|
138
162
|
this.plugins.forEach((p) => p.onConnect && p.onConnect());
|
|
163
|
+
// Resolve the connection promise
|
|
164
|
+
if (this.connectPromiseResolve) {
|
|
165
|
+
this.connectPromiseResolve();
|
|
166
|
+
this.connectPromiseResolve = null;
|
|
167
|
+
this.connectPromiseReject = null;
|
|
168
|
+
}
|
|
139
169
|
const getClientIdPromise = getClientId || emptyPromise;
|
|
140
170
|
getClientIdPromise(name).then((clientId) => {
|
|
141
171
|
this.isReady = true;
|
|
@@ -159,6 +189,12 @@ class DReactionImpl {
|
|
|
159
189
|
// fires when we disconnect
|
|
160
190
|
const onClose = () => {
|
|
161
191
|
this.isReady = false;
|
|
192
|
+
// Reject connection promise if still pending
|
|
193
|
+
if (this.connectPromiseReject) {
|
|
194
|
+
this.connectPromiseReject(new Error('Connection failed or closed'));
|
|
195
|
+
this.connectPromiseResolve = null;
|
|
196
|
+
this.connectPromiseReject = null;
|
|
197
|
+
}
|
|
162
198
|
// trigger our disconnect handler
|
|
163
199
|
onDisconnect && onDisconnect();
|
|
164
200
|
// as well as the plugin's onDisconnect
|
|
@@ -404,6 +440,22 @@ class DReactionImpl {
|
|
|
404
440
|
});
|
|
405
441
|
};
|
|
406
442
|
}
|
|
443
|
+
/**
|
|
444
|
+
* Wait for connection to be established.
|
|
445
|
+
* Returns a promise that resolves when the connection is ready.
|
|
446
|
+
*/
|
|
447
|
+
waitForConnect() {
|
|
448
|
+
if (this.isReady) {
|
|
449
|
+
// Already connected, resolve immediately
|
|
450
|
+
return Promise.resolve();
|
|
451
|
+
}
|
|
452
|
+
if (this.connectPromise) {
|
|
453
|
+
// Return existing promise
|
|
454
|
+
return this.connectPromise;
|
|
455
|
+
}
|
|
456
|
+
// No connection attempt in progress
|
|
457
|
+
return Promise.reject(new Error('Not connected. Call connect() first.'));
|
|
458
|
+
}
|
|
407
459
|
}
|
|
408
460
|
exports.DReactionImpl = DReactionImpl;
|
|
409
461
|
// convenience factory function
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fps.d.ts","sourceRoot":"","sources":["../../src/utils/fps.ts"],"names":[],"mappings":"AAAA,wBAAgB,WAAW,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,cAgC1D"}
|
package/lib/utils/fps.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runFPSMeter = runFPSMeter;
|
|
4
|
+
function runFPSMeter(onUpdate) {
|
|
5
|
+
let fps = 0;
|
|
6
|
+
let lastTime = performance.now();
|
|
7
|
+
let frameCount = 0;
|
|
8
|
+
let running = true;
|
|
9
|
+
let timer;
|
|
10
|
+
const updateFPS = () => {
|
|
11
|
+
if (!running) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
frameCount++;
|
|
15
|
+
const now = performance.now();
|
|
16
|
+
if (now - lastTime >= 1000) {
|
|
17
|
+
fps = frameCount;
|
|
18
|
+
frameCount = 0;
|
|
19
|
+
lastTime = now;
|
|
20
|
+
onUpdate(fps);
|
|
21
|
+
}
|
|
22
|
+
timer = requestAnimationFrame(updateFPS);
|
|
23
|
+
};
|
|
24
|
+
updateFPS();
|
|
25
|
+
// return stop function
|
|
26
|
+
return () => {
|
|
27
|
+
running = false;
|
|
28
|
+
cancelAnimationFrame(timer);
|
|
29
|
+
};
|
|
30
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dreaction-client-core",
|
|
3
|
-
"version": "1.1
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"@types/ws": "^8.5.13",
|
|
18
18
|
"eventemitter-strict": "^1.0.1",
|
|
19
19
|
"ws": "^8.18.0",
|
|
20
|
-
"dreaction-protocol": "1.0.
|
|
20
|
+
"dreaction-protocol": "1.0.8"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
23
|
"typescript": "^5.4.5"
|
package/src/index.ts
CHANGED
|
@@ -26,6 +26,7 @@ export {
|
|
|
26
26
|
hasStateResponsePlugin,
|
|
27
27
|
} from './plugins/state-responses';
|
|
28
28
|
export type { StateResponsePlugin } from './plugins/state-responses';
|
|
29
|
+
export { runFPSMeter } from './utils/fps';
|
|
29
30
|
|
|
30
31
|
// #region Plugin Types
|
|
31
32
|
export interface LifeCycleMethods {
|
|
@@ -126,6 +127,11 @@ export interface DReactionCore {
|
|
|
126
127
|
) => this & InferFeaturesFromPlugin<this, P>;
|
|
127
128
|
|
|
128
129
|
connect: () => this;
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Wait for connection to be established
|
|
133
|
+
*/
|
|
134
|
+
waitForConnect: () => Promise<void>;
|
|
129
135
|
}
|
|
130
136
|
|
|
131
137
|
export type InferFeatures<
|
|
@@ -228,6 +234,13 @@ export class DReactionImpl
|
|
|
228
234
|
*/
|
|
229
235
|
customCommandLatestId = 1;
|
|
230
236
|
|
|
237
|
+
/**
|
|
238
|
+
* Promise resolvers for connection wait
|
|
239
|
+
*/
|
|
240
|
+
private connectPromiseResolve: (() => void) | null = null;
|
|
241
|
+
private connectPromiseReject: ((error: Error) => void) | null = null;
|
|
242
|
+
private connectPromise: Promise<void> | null = null;
|
|
243
|
+
|
|
231
244
|
/**
|
|
232
245
|
* Starts a timer and returns a function you can call to stop it and return the elapsed time.
|
|
233
246
|
*/
|
|
@@ -277,6 +290,13 @@ export class DReactionImpl
|
|
|
277
290
|
this.connected = false;
|
|
278
291
|
this.socket && this.socket.close && this.socket.close();
|
|
279
292
|
|
|
293
|
+
// Reject any pending connection promise
|
|
294
|
+
if (this.connectPromiseReject) {
|
|
295
|
+
this.connectPromiseReject(new Error('Connection closed'));
|
|
296
|
+
this.connectPromiseResolve = null;
|
|
297
|
+
this.connectPromiseReject = null;
|
|
298
|
+
}
|
|
299
|
+
|
|
280
300
|
return this;
|
|
281
301
|
}
|
|
282
302
|
|
|
@@ -285,6 +305,13 @@ export class DReactionImpl
|
|
|
285
305
|
*/
|
|
286
306
|
connect() {
|
|
287
307
|
this.connected = true;
|
|
308
|
+
|
|
309
|
+
// Create a new promise for this connection attempt
|
|
310
|
+
this.connectPromise = new Promise<void>((resolve, reject) => {
|
|
311
|
+
this.connectPromiseResolve = resolve;
|
|
312
|
+
this.connectPromiseReject = reject;
|
|
313
|
+
});
|
|
314
|
+
|
|
288
315
|
const {
|
|
289
316
|
createSocket,
|
|
290
317
|
secure,
|
|
@@ -300,7 +327,12 @@ export class DReactionImpl
|
|
|
300
327
|
|
|
301
328
|
if (!host) {
|
|
302
329
|
console.log('host is not config, skip connect.');
|
|
303
|
-
|
|
330
|
+
if (this.connectPromiseReject) {
|
|
331
|
+
this.connectPromiseReject(new Error('Host is not configured'));
|
|
332
|
+
this.connectPromiseResolve = null;
|
|
333
|
+
this.connectPromiseReject = null;
|
|
334
|
+
}
|
|
335
|
+
return this;
|
|
304
336
|
}
|
|
305
337
|
|
|
306
338
|
// establish a connection to the server
|
|
@@ -315,8 +347,14 @@ export class DReactionImpl
|
|
|
315
347
|
// trigger our plugins onConnect
|
|
316
348
|
this.plugins.forEach((p) => p.onConnect && p.onConnect());
|
|
317
349
|
|
|
318
|
-
|
|
350
|
+
// Resolve the connection promise
|
|
351
|
+
if (this.connectPromiseResolve) {
|
|
352
|
+
this.connectPromiseResolve();
|
|
353
|
+
this.connectPromiseResolve = null;
|
|
354
|
+
this.connectPromiseReject = null;
|
|
355
|
+
}
|
|
319
356
|
|
|
357
|
+
const getClientIdPromise = getClientId || emptyPromise;
|
|
320
358
|
getClientIdPromise(name!).then((clientId) => {
|
|
321
359
|
this.isReady = true;
|
|
322
360
|
// introduce ourselves
|
|
@@ -341,6 +379,14 @@ export class DReactionImpl
|
|
|
341
379
|
// fires when we disconnect
|
|
342
380
|
const onClose = () => {
|
|
343
381
|
this.isReady = false;
|
|
382
|
+
|
|
383
|
+
// Reject connection promise if still pending
|
|
384
|
+
if (this.connectPromiseReject) {
|
|
385
|
+
this.connectPromiseReject(new Error('Connection failed or closed'));
|
|
386
|
+
this.connectPromiseResolve = null;
|
|
387
|
+
this.connectPromiseReject = null;
|
|
388
|
+
}
|
|
389
|
+
|
|
344
390
|
// trigger our disconnect handler
|
|
345
391
|
onDisconnect && onDisconnect();
|
|
346
392
|
|
|
@@ -652,6 +698,25 @@ export class DReactionImpl
|
|
|
652
698
|
});
|
|
653
699
|
};
|
|
654
700
|
}
|
|
701
|
+
|
|
702
|
+
/**
|
|
703
|
+
* Wait for connection to be established.
|
|
704
|
+
* Returns a promise that resolves when the connection is ready.
|
|
705
|
+
*/
|
|
706
|
+
waitForConnect(): Promise<void> {
|
|
707
|
+
if (this.isReady) {
|
|
708
|
+
// Already connected, resolve immediately
|
|
709
|
+
return Promise.resolve();
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
if (this.connectPromise) {
|
|
713
|
+
// Return existing promise
|
|
714
|
+
return this.connectPromise;
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
// No connection attempt in progress
|
|
718
|
+
return Promise.reject(new Error('Not connected. Call connect() first.'));
|
|
719
|
+
}
|
|
655
720
|
}
|
|
656
721
|
|
|
657
722
|
// convenience factory function
|
package/src/utils/fps.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export function runFPSMeter(onUpdate: (fps: number) => void) {
|
|
2
|
+
let fps = 0;
|
|
3
|
+
let lastTime = performance.now();
|
|
4
|
+
let frameCount = 0;
|
|
5
|
+
let running = true;
|
|
6
|
+
let timer: number;
|
|
7
|
+
|
|
8
|
+
const updateFPS = () => {
|
|
9
|
+
if (!running) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
frameCount++;
|
|
14
|
+
const now = performance.now();
|
|
15
|
+
if (now - lastTime >= 1000) {
|
|
16
|
+
fps = frameCount;
|
|
17
|
+
frameCount = 0;
|
|
18
|
+
lastTime = now;
|
|
19
|
+
|
|
20
|
+
onUpdate(fps);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
timer = requestAnimationFrame(updateFPS);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
updateFPS();
|
|
27
|
+
|
|
28
|
+
// return stop function
|
|
29
|
+
return () => {
|
|
30
|
+
running = false;
|
|
31
|
+
cancelAnimationFrame(timer);
|
|
32
|
+
};
|
|
33
|
+
}
|