@pluv/io 2.2.4 → 2.2.5
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/.turbo/turbo-build.log +9 -9
- package/CHANGELOG.md +7 -0
- package/dist/index.d.mts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +32 -20
- package/dist/index.mjs +32 -20
- package/package.json +5 -5
- package/src/AbstractPersistence.ts +1 -1
- package/src/AbstractPlatform.ts +2 -1
- package/src/IORoom.ts +5 -3
- package/src/PluvServer.ts +11 -5
- package/src/utils/index.ts +1 -0
- package/src/utils/oneLine.ts +7 -0
- package/src/version.generated.ts +1 -1
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
|
|
2
|
-
> @pluv/io@2.2.
|
|
2
|
+
> @pluv/io@2.2.5 build /home/runner/work/pluv/pluv/packages/io
|
|
3
3
|
> pnpm run version && tsup src/index.ts --format esm,cjs --dts
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
> @pluv/io@2.2.
|
|
6
|
+
> @pluv/io@2.2.5 version /home/runner/work/pluv/pluv/packages/io
|
|
7
7
|
> genversion ./src/version.generated.ts --esm
|
|
8
8
|
|
|
9
9
|
[34mCLI[39m Building entry: src/index.ts
|
|
@@ -12,11 +12,11 @@
|
|
|
12
12
|
[34mCLI[39m Target: es6
|
|
13
13
|
[34mESM[39m Build start
|
|
14
14
|
[34mCJS[39m Build start
|
|
15
|
-
[
|
|
16
|
-
[
|
|
17
|
-
[
|
|
18
|
-
[
|
|
15
|
+
[32mESM[39m [1mdist/index.mjs [22m[32m52.32 KB[39m
|
|
16
|
+
[32mESM[39m ⚡️ Build success in 127ms
|
|
17
|
+
[32mCJS[39m [1mdist/index.js [22m[32m54.50 KB[39m
|
|
18
|
+
[32mCJS[39m ⚡️ Build success in 127ms
|
|
19
19
|
[34mDTS[39m Build start
|
|
20
|
-
[32mDTS[39m ⚡️ Build success in
|
|
21
|
-
[32mDTS[39m [1mdist/index.d.mts [22m[32m32.
|
|
22
|
-
[32mDTS[39m [1mdist/index.d.ts [22m[32m32.
|
|
20
|
+
[32mDTS[39m ⚡️ Build success in 4196ms
|
|
21
|
+
[32mDTS[39m [1mdist/index.d.mts [22m[32m32.28 KB[39m
|
|
22
|
+
[32mDTS[39m [1mdist/index.d.ts [22m[32m32.28 KB[39m
|
package/CHANGELOG.md
CHANGED
package/dist/index.d.mts
CHANGED
|
@@ -11,7 +11,7 @@ declare abstract class AbstractPersistence {
|
|
|
11
11
|
abstract getUser(room: string, connectionId: string): Promise<JsonObject | null>;
|
|
12
12
|
abstract getUsers(room: string): Promise<Map<[connectionId: string][0], JsonObject | null>>;
|
|
13
13
|
abstract getUsersSize(room: string): Promise<number>;
|
|
14
|
-
abstract initialize(roomContext: any):
|
|
14
|
+
abstract initialize(roomContext: any): typeof this;
|
|
15
15
|
abstract setStorageState(room: string, state: string): Promise<void>;
|
|
16
16
|
}
|
|
17
17
|
|
|
@@ -309,6 +309,7 @@ declare abstract class AbstractPlatform<TWebSocket extends AbstractWebSocket<any
|
|
|
309
309
|
private _initialized;
|
|
310
310
|
persistence: AbstractPersistence;
|
|
311
311
|
pubSub: AbstractPubSub;
|
|
312
|
+
abstract readonly id: string;
|
|
312
313
|
readonly _createToken?: (params: JWTEncodeParams<any, any> & {
|
|
313
314
|
authorize: Maybe<ResolvedPluvIOAuthorize<any, any>>;
|
|
314
315
|
}) => Promise<string>;
|
|
@@ -327,7 +328,7 @@ declare abstract class AbstractPlatform<TWebSocket extends AbstractWebSocket<any
|
|
|
327
328
|
abstract randomUUID(): string;
|
|
328
329
|
abstract setSerializedState(webSocket: AbstractWebSocket, state: WebSocketSerializedState): WebSocketSerializedState;
|
|
329
330
|
validateConfig(config: any): void;
|
|
330
|
-
protected _initialize(): this;
|
|
331
|
+
protected _initialize(): typeof this;
|
|
331
332
|
}
|
|
332
333
|
|
|
333
334
|
interface IORoomListeners<TPlatform extends AbstractPlatform<any>, TAuthorize extends PluvIOAuthorize<TPlatform, any, InferInitContextType<TPlatform>> | null, TContext extends Record<string, any>, TEvents extends PluvRouterEventConfig<TPlatform, TAuthorize, TContext>> {
|
package/dist/index.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ declare abstract class AbstractPersistence {
|
|
|
11
11
|
abstract getUser(room: string, connectionId: string): Promise<JsonObject | null>;
|
|
12
12
|
abstract getUsers(room: string): Promise<Map<[connectionId: string][0], JsonObject | null>>;
|
|
13
13
|
abstract getUsersSize(room: string): Promise<number>;
|
|
14
|
-
abstract initialize(roomContext: any):
|
|
14
|
+
abstract initialize(roomContext: any): typeof this;
|
|
15
15
|
abstract setStorageState(room: string, state: string): Promise<void>;
|
|
16
16
|
}
|
|
17
17
|
|
|
@@ -309,6 +309,7 @@ declare abstract class AbstractPlatform<TWebSocket extends AbstractWebSocket<any
|
|
|
309
309
|
private _initialized;
|
|
310
310
|
persistence: AbstractPersistence;
|
|
311
311
|
pubSub: AbstractPubSub;
|
|
312
|
+
abstract readonly id: string;
|
|
312
313
|
readonly _createToken?: (params: JWTEncodeParams<any, any> & {
|
|
313
314
|
authorize: Maybe<ResolvedPluvIOAuthorize<any, any>>;
|
|
314
315
|
}) => Promise<string>;
|
|
@@ -327,7 +328,7 @@ declare abstract class AbstractPlatform<TWebSocket extends AbstractWebSocket<any
|
|
|
327
328
|
abstract randomUUID(): string;
|
|
328
329
|
abstract setSerializedState(webSocket: AbstractWebSocket, state: WebSocketSerializedState): WebSocketSerializedState;
|
|
329
330
|
validateConfig(config: any): void;
|
|
330
|
-
protected _initialize(): this;
|
|
331
|
+
protected _initialize(): typeof this;
|
|
331
332
|
}
|
|
332
333
|
|
|
333
334
|
interface IORoomListeners<TPlatform extends AbstractPlatform<any>, TAuthorize extends PluvIOAuthorize<TPlatform, any, InferInitContextType<TPlatform>> | null, TContext extends Record<string, any>, TEvents extends PluvRouterEventConfig<TPlatform, TAuthorize, TContext>> {
|
package/dist/index.js
CHANGED
|
@@ -409,6 +409,23 @@ var MAX_USER_ID_LENGTH = 128;
|
|
|
409
409
|
var MAX_USER_SIZE_BYTES = 512;
|
|
410
410
|
var PING_TIMEOUT_MS = 3e4;
|
|
411
411
|
|
|
412
|
+
// src/utils/oneLine.ts
|
|
413
|
+
var oneLine = (strings, ...values) => {
|
|
414
|
+
return strings.map((str) => str.replace(/\s+/g, " ")).reduce((acc, str, i) => acc + str + (i < values.length ? values[i] : ""), "").replace(/\s+/g, " ").trim();
|
|
415
|
+
};
|
|
416
|
+
|
|
417
|
+
// src/utils/pickBy.ts
|
|
418
|
+
var pickBy = (obj, by) => {
|
|
419
|
+
const result = {};
|
|
420
|
+
const keys = Object.keys(obj);
|
|
421
|
+
for (let i = 0; i < keys.length; ++i) {
|
|
422
|
+
const key = keys[i];
|
|
423
|
+
const value = obj[key];
|
|
424
|
+
if (by(value)) result[key] = value;
|
|
425
|
+
}
|
|
426
|
+
return result;
|
|
427
|
+
};
|
|
428
|
+
|
|
412
429
|
// src/IORoom.ts
|
|
413
430
|
var IORoom = class {
|
|
414
431
|
constructor(id, config) {
|
|
@@ -603,9 +620,10 @@ var IORoom = class {
|
|
|
603
620
|
}
|
|
604
621
|
yield this._emitRegistered(pluvWs);
|
|
605
622
|
const size = this.getSize();
|
|
606
|
-
this._logDebug(
|
|
607
|
-
|
|
608
|
-
|
|
623
|
+
this._logDebug(oneLine`
|
|
624
|
+
${import_kleur.default.blue(`Registered connection for room ${this.id}:`)}
|
|
625
|
+
${pluvWs.sessionId}
|
|
626
|
+
`);
|
|
609
627
|
this._logDebug(`${import_kleur.default.blue(`Room ${this.id} size:`)} ${size}`);
|
|
610
628
|
});
|
|
611
629
|
}
|
|
@@ -1149,20 +1167,8 @@ var IORoom = class {
|
|
|
1149
1167
|
}
|
|
1150
1168
|
};
|
|
1151
1169
|
|
|
1152
|
-
// src/utils/pickBy.ts
|
|
1153
|
-
var pickBy = (obj, by) => {
|
|
1154
|
-
const result = {};
|
|
1155
|
-
const keys = Object.keys(obj);
|
|
1156
|
-
for (let i = 0; i < keys.length; ++i) {
|
|
1157
|
-
const key = keys[i];
|
|
1158
|
-
const value = obj[key];
|
|
1159
|
-
if (by(value)) result[key] = value;
|
|
1160
|
-
}
|
|
1161
|
-
return result;
|
|
1162
|
-
};
|
|
1163
|
-
|
|
1164
1170
|
// src/version.generated.ts
|
|
1165
|
-
var version = "2.2.
|
|
1171
|
+
var version = "2.2.5";
|
|
1166
1172
|
|
|
1167
1173
|
// src/PluvServer.ts
|
|
1168
1174
|
var PluvServer = class {
|
|
@@ -1311,9 +1317,11 @@ var PluvServer = class {
|
|
|
1311
1317
|
const updated = Object.assign(/* @__PURE__ */ Object.create(null), session.presence, cleanedPatch);
|
|
1312
1318
|
const bytes = new TextEncoder().encode(JSON.stringify(updated)).length;
|
|
1313
1319
|
if (!!this._config.limits.presenceMaxSize && bytes > this._config.limits.presenceMaxSize) {
|
|
1314
|
-
throw new Error(
|
|
1315
|
-
|
|
1316
|
-
|
|
1320
|
+
throw new Error(oneLine`
|
|
1321
|
+
Large presence. Presence must be at most
|
|
1322
|
+
${this._config.limits.presenceMaxSize.toLocaleString()} bytes.
|
|
1323
|
+
Current size: ${bytes.toLocaleString()} bytes
|
|
1324
|
+
`);
|
|
1317
1325
|
}
|
|
1318
1326
|
context.presence = updated;
|
|
1319
1327
|
return {
|
|
@@ -1332,7 +1340,11 @@ var PluvServer = class {
|
|
|
1332
1340
|
const encodedState = updated.getEncodedState();
|
|
1333
1341
|
const storageSize = new TextEncoder().encode(encodedState).length;
|
|
1334
1342
|
if (!!this._config.limits.storageMaxSize && storageSize > this._config.limits.storageMaxSize) {
|
|
1335
|
-
throw new Error(
|
|
1343
|
+
throw new Error(oneLine`
|
|
1344
|
+
Large Storage. Storage must be at most
|
|
1345
|
+
${this._config.limits.storageMaxSize.toLocaleString()} bytes.
|
|
1346
|
+
Current size: ${storageSize.toLocaleString()} bytes
|
|
1347
|
+
`);
|
|
1336
1348
|
}
|
|
1337
1349
|
platform.persistence.setStorageState(room, encodedState).then(() => {
|
|
1338
1350
|
listeners.onStorageUpdated({
|
package/dist/index.mjs
CHANGED
|
@@ -367,6 +367,23 @@ var MAX_USER_ID_LENGTH = 128;
|
|
|
367
367
|
var MAX_USER_SIZE_BYTES = 512;
|
|
368
368
|
var PING_TIMEOUT_MS = 3e4;
|
|
369
369
|
|
|
370
|
+
// src/utils/oneLine.ts
|
|
371
|
+
var oneLine = (strings, ...values) => {
|
|
372
|
+
return strings.map((str) => str.replace(/\s+/g, " ")).reduce((acc, str, i) => acc + str + (i < values.length ? values[i] : ""), "").replace(/\s+/g, " ").trim();
|
|
373
|
+
};
|
|
374
|
+
|
|
375
|
+
// src/utils/pickBy.ts
|
|
376
|
+
var pickBy = (obj, by) => {
|
|
377
|
+
const result = {};
|
|
378
|
+
const keys = Object.keys(obj);
|
|
379
|
+
for (let i = 0; i < keys.length; ++i) {
|
|
380
|
+
const key = keys[i];
|
|
381
|
+
const value = obj[key];
|
|
382
|
+
if (by(value)) result[key] = value;
|
|
383
|
+
}
|
|
384
|
+
return result;
|
|
385
|
+
};
|
|
386
|
+
|
|
370
387
|
// src/IORoom.ts
|
|
371
388
|
var IORoom = class {
|
|
372
389
|
constructor(id, config) {
|
|
@@ -561,9 +578,10 @@ var IORoom = class {
|
|
|
561
578
|
}
|
|
562
579
|
yield this._emitRegistered(pluvWs);
|
|
563
580
|
const size = this.getSize();
|
|
564
|
-
this._logDebug(
|
|
565
|
-
|
|
566
|
-
|
|
581
|
+
this._logDebug(oneLine`
|
|
582
|
+
${colors.blue(`Registered connection for room ${this.id}:`)}
|
|
583
|
+
${pluvWs.sessionId}
|
|
584
|
+
`);
|
|
567
585
|
this._logDebug(`${colors.blue(`Room ${this.id} size:`)} ${size}`);
|
|
568
586
|
});
|
|
569
587
|
}
|
|
@@ -1107,20 +1125,8 @@ var IORoom = class {
|
|
|
1107
1125
|
}
|
|
1108
1126
|
};
|
|
1109
1127
|
|
|
1110
|
-
// src/utils/pickBy.ts
|
|
1111
|
-
var pickBy = (obj, by) => {
|
|
1112
|
-
const result = {};
|
|
1113
|
-
const keys = Object.keys(obj);
|
|
1114
|
-
for (let i = 0; i < keys.length; ++i) {
|
|
1115
|
-
const key = keys[i];
|
|
1116
|
-
const value = obj[key];
|
|
1117
|
-
if (by(value)) result[key] = value;
|
|
1118
|
-
}
|
|
1119
|
-
return result;
|
|
1120
|
-
};
|
|
1121
|
-
|
|
1122
1128
|
// src/version.generated.ts
|
|
1123
|
-
var version = "2.2.
|
|
1129
|
+
var version = "2.2.5";
|
|
1124
1130
|
|
|
1125
1131
|
// src/PluvServer.ts
|
|
1126
1132
|
var PluvServer = class {
|
|
@@ -1269,9 +1275,11 @@ var PluvServer = class {
|
|
|
1269
1275
|
const updated = Object.assign(/* @__PURE__ */ Object.create(null), session.presence, cleanedPatch);
|
|
1270
1276
|
const bytes = new TextEncoder().encode(JSON.stringify(updated)).length;
|
|
1271
1277
|
if (!!this._config.limits.presenceMaxSize && bytes > this._config.limits.presenceMaxSize) {
|
|
1272
|
-
throw new Error(
|
|
1273
|
-
|
|
1274
|
-
|
|
1278
|
+
throw new Error(oneLine`
|
|
1279
|
+
Large presence. Presence must be at most
|
|
1280
|
+
${this._config.limits.presenceMaxSize.toLocaleString()} bytes.
|
|
1281
|
+
Current size: ${bytes.toLocaleString()} bytes
|
|
1282
|
+
`);
|
|
1275
1283
|
}
|
|
1276
1284
|
context.presence = updated;
|
|
1277
1285
|
return {
|
|
@@ -1290,7 +1298,11 @@ var PluvServer = class {
|
|
|
1290
1298
|
const encodedState = updated.getEncodedState();
|
|
1291
1299
|
const storageSize = new TextEncoder().encode(encodedState).length;
|
|
1292
1300
|
if (!!this._config.limits.storageMaxSize && storageSize > this._config.limits.storageMaxSize) {
|
|
1293
|
-
throw new Error(
|
|
1301
|
+
throw new Error(oneLine`
|
|
1302
|
+
Large Storage. Storage must be at most
|
|
1303
|
+
${this._config.limits.storageMaxSize.toLocaleString()} bytes.
|
|
1304
|
+
Current size: ${storageSize.toLocaleString()} bytes
|
|
1305
|
+
`);
|
|
1294
1306
|
}
|
|
1295
1307
|
platform.persistence.setStorageState(room, encodedState).then(() => {
|
|
1296
1308
|
listeners.onStorageUpdated({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pluv/io",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.5",
|
|
4
4
|
"description": "@pluv/io server-side websocket manager",
|
|
5
5
|
"author": "leedavidcs",
|
|
6
6
|
"license": "MIT",
|
|
@@ -21,16 +21,16 @@
|
|
|
21
21
|
"jose": "^5.10.0",
|
|
22
22
|
"kleur": "^4.1.5",
|
|
23
23
|
"wonka": "^6.3.5",
|
|
24
|
-
"@pluv/crdt": "^2.2.
|
|
25
|
-
"@pluv/types": "^2.2.
|
|
24
|
+
"@pluv/crdt": "^2.2.5",
|
|
25
|
+
"@pluv/types": "^2.2.5"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"eslint": "^9.27.0",
|
|
29
29
|
"genversion": "^3.2.0",
|
|
30
30
|
"tsup": "^8.5.0",
|
|
31
31
|
"typescript": "^5.8.3",
|
|
32
|
-
"@pluv/tsconfig": "^2.2.
|
|
33
|
-
"eslint-config-pluv": "^2.2.
|
|
32
|
+
"@pluv/tsconfig": "^2.2.5",
|
|
33
|
+
"eslint-config-pluv": "^2.2.5"
|
|
34
34
|
},
|
|
35
35
|
"scripts": {
|
|
36
36
|
"build": "pnpm run version && tsup src/index.ts --format esm,cjs --dts",
|
|
@@ -23,7 +23,7 @@ export abstract class AbstractPersistence {
|
|
|
23
23
|
|
|
24
24
|
public abstract getUsersSize(room: string): Promise<number>;
|
|
25
25
|
|
|
26
|
-
public abstract initialize(roomContext: any):
|
|
26
|
+
public abstract initialize(roomContext: any): typeof this;
|
|
27
27
|
|
|
28
28
|
public abstract setStorageState(room: string, state: string): Promise<void>;
|
|
29
29
|
}
|
package/src/AbstractPlatform.ts
CHANGED
|
@@ -45,6 +45,7 @@ export abstract class AbstractPlatform<
|
|
|
45
45
|
public persistence: AbstractPersistence;
|
|
46
46
|
public pubSub: AbstractPubSub;
|
|
47
47
|
|
|
48
|
+
public abstract readonly id: string;
|
|
48
49
|
public readonly _createToken?: (
|
|
49
50
|
params: JWTEncodeParams<any, any> & {
|
|
50
51
|
authorize: Maybe<ResolvedPluvIOAuthorize<any, any>>;
|
|
@@ -94,7 +95,7 @@ export abstract class AbstractPlatform<
|
|
|
94
95
|
|
|
95
96
|
public validateConfig(config: any): void {}
|
|
96
97
|
|
|
97
|
-
protected _initialize(): this {
|
|
98
|
+
protected _initialize(): typeof this {
|
|
98
99
|
if (this._initialized) throw new Error("Platform is already initialized");
|
|
99
100
|
|
|
100
101
|
this._initialized = true;
|
package/src/IORoom.ts
CHANGED
|
@@ -44,6 +44,7 @@ import type {
|
|
|
44
44
|
WebSocketSession,
|
|
45
45
|
WebSocketType,
|
|
46
46
|
} from "./types";
|
|
47
|
+
import { oneLine } from "./utils";
|
|
47
48
|
|
|
48
49
|
type BroadcastMessage<TIO extends IORoom<any, any, any, any>> =
|
|
49
50
|
| InferEventMessage<InferIOInput<TIO>>
|
|
@@ -406,9 +407,10 @@ export class IORoom<
|
|
|
406
407
|
|
|
407
408
|
const size = this.getSize();
|
|
408
409
|
|
|
409
|
-
this._logDebug(
|
|
410
|
-
|
|
411
|
-
|
|
410
|
+
this._logDebug(oneLine`
|
|
411
|
+
${colors.blue(`Registered connection for room ${this.id}:`)}
|
|
412
|
+
${pluvWs.sessionId}
|
|
413
|
+
`);
|
|
412
414
|
this._logDebug(`${colors.blue(`Room ${this.id} size:`)} ${size}`);
|
|
413
415
|
}
|
|
414
416
|
|
package/src/PluvServer.ts
CHANGED
|
@@ -31,7 +31,7 @@ import type {
|
|
|
31
31
|
PluvIOLimits,
|
|
32
32
|
PluvIOListeners,
|
|
33
33
|
} from "./types";
|
|
34
|
-
import { pickBy } from "./utils";
|
|
34
|
+
import { oneLine, pickBy } from "./utils";
|
|
35
35
|
import { __PLUV_VERSION } from "./version";
|
|
36
36
|
|
|
37
37
|
export type InferIORoom<TServer extends PluvServer<any, any, any, any>> =
|
|
@@ -294,9 +294,11 @@ export class PluvServer<
|
|
|
294
294
|
!!this._config.limits.presenceMaxSize &&
|
|
295
295
|
bytes > this._config.limits.presenceMaxSize
|
|
296
296
|
) {
|
|
297
|
-
throw new Error(
|
|
298
|
-
|
|
299
|
-
|
|
297
|
+
throw new Error(oneLine`
|
|
298
|
+
Large presence. Presence must be at most
|
|
299
|
+
${this._config.limits.presenceMaxSize.toLocaleString()} bytes.
|
|
300
|
+
Current size: ${bytes.toLocaleString()} bytes
|
|
301
|
+
`);
|
|
300
302
|
}
|
|
301
303
|
|
|
302
304
|
context.presence = updated;
|
|
@@ -322,7 +324,11 @@ export class PluvServer<
|
|
|
322
324
|
!!this._config.limits.storageMaxSize &&
|
|
323
325
|
storageSize > this._config.limits.storageMaxSize
|
|
324
326
|
) {
|
|
325
|
-
throw new Error(
|
|
327
|
+
throw new Error(oneLine`
|
|
328
|
+
Large Storage. Storage must be at most
|
|
329
|
+
${this._config.limits.storageMaxSize.toLocaleString()} bytes.
|
|
330
|
+
Current size: ${storageSize.toLocaleString()} bytes
|
|
331
|
+
`);
|
|
326
332
|
}
|
|
327
333
|
|
|
328
334
|
platform.persistence.setStorageState(room, encodedState).then(() => {
|
package/src/utils/index.ts
CHANGED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export const oneLine = (strings: TemplateStringsArray, ...values: unknown[]): string => {
|
|
2
|
+
return strings
|
|
3
|
+
.map((str) => str.replace(/\s+/g, " "))
|
|
4
|
+
.reduce((acc, str, i) => acc + str + (i < values.length ? values[i] : ""), "")
|
|
5
|
+
.replace(/\s+/g, " ")
|
|
6
|
+
.trim();
|
|
7
|
+
};
|
package/src/version.generated.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Generated by genversion.
|
|
2
|
-
export const version = '2.2.
|
|
2
|
+
export const version = '2.2.5'
|