@pluv/io 2.2.0 → 2.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/.turbo/turbo-build.log +9 -9
- package/CHANGELOG.md +7 -0
- package/dist/index.d.mts +4 -10
- package/dist/index.d.ts +4 -10
- package/dist/index.js +33 -45
- package/dist/index.mjs +33 -45
- package/package.json +5 -5
- package/src/AbstractPlatform.ts +7 -2
- package/src/PluvIO.ts +3 -1
- package/src/PluvServer.ts +44 -55
- 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.1 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.1 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
|
-
[32mCJS[39m [1mdist/index.js [22m[
|
|
16
|
-
[32mCJS[39m ⚡️ Build success in
|
|
17
|
-
[32mESM[39m [1mdist/index.mjs [22m[32m51.
|
|
18
|
-
[32mESM[39m ⚡️ Build success in
|
|
15
|
+
[32mCJS[39m [1mdist/index.js [22m[32m53.90 KB[39m
|
|
16
|
+
[32mCJS[39m ⚡️ Build success in 106ms
|
|
17
|
+
[32mESM[39m [1mdist/index.mjs [22m[32m51.72 KB[39m
|
|
18
|
+
[32mESM[39m ⚡️ Build success in 109ms
|
|
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 4113ms
|
|
21
|
+
[32mDTS[39m [1mdist/index.d.mts [22m[32m32.25 KB[39m
|
|
22
|
+
[32mDTS[39m [1mdist/index.d.ts [22m[32m32.25 KB[39m
|
package/CHANGELOG.md
CHANGED
package/dist/index.d.mts
CHANGED
|
@@ -309,7 +309,9 @@ declare abstract class AbstractPlatform<TWebSocket extends AbstractWebSocket<any
|
|
|
309
309
|
private _initialized;
|
|
310
310
|
persistence: AbstractPersistence;
|
|
311
311
|
pubSub: AbstractPubSub;
|
|
312
|
-
readonly _createToken?: (params: JWTEncodeParams<any, any>
|
|
312
|
+
readonly _createToken?: (params: JWTEncodeParams<any, any> & {
|
|
313
|
+
authorize: Maybe<ResolvedPluvIOAuthorize<any, any>>;
|
|
314
|
+
}) => Promise<string>;
|
|
313
315
|
_fetch?: (...args: any[]) => Promise<any>;
|
|
314
316
|
abstract readonly _config: TConfig;
|
|
315
317
|
abstract readonly _name: string;
|
|
@@ -452,15 +454,7 @@ type CreateRoomOptions<TPlatform extends AbstractPlatform<any, any>, TAuthorize
|
|
|
452
454
|
];
|
|
453
455
|
declare class PluvServer<TPlatform extends AbstractPlatform<any, any> = AbstractPlatform<any, any>, TAuthorize extends PluvIOAuthorize<TPlatform, any, InferInitContextType<TPlatform>> | null = any, TContext extends Record<string, any> = {}, TEvents extends PluvRouterEventConfig<TPlatform, TAuthorize, TContext> = {}> implements IOLike<TAuthorize, TEvents> {
|
|
454
456
|
readonly version: string;
|
|
455
|
-
private readonly
|
|
456
|
-
private readonly _context;
|
|
457
|
-
private readonly _crdt;
|
|
458
|
-
private readonly _debug;
|
|
459
|
-
private readonly _getInitialStorage;
|
|
460
|
-
private readonly _io;
|
|
461
|
-
private readonly _limits;
|
|
462
|
-
private readonly _platform;
|
|
463
|
-
private readonly _inputRouter;
|
|
457
|
+
private readonly _config;
|
|
464
458
|
get fetch(): (...args: any[]) => Promise<any>;
|
|
465
459
|
/**
|
|
466
460
|
* @ignore
|
package/dist/index.d.ts
CHANGED
|
@@ -309,7 +309,9 @@ declare abstract class AbstractPlatform<TWebSocket extends AbstractWebSocket<any
|
|
|
309
309
|
private _initialized;
|
|
310
310
|
persistence: AbstractPersistence;
|
|
311
311
|
pubSub: AbstractPubSub;
|
|
312
|
-
readonly _createToken?: (params: JWTEncodeParams<any, any>
|
|
312
|
+
readonly _createToken?: (params: JWTEncodeParams<any, any> & {
|
|
313
|
+
authorize: Maybe<ResolvedPluvIOAuthorize<any, any>>;
|
|
314
|
+
}) => Promise<string>;
|
|
313
315
|
_fetch?: (...args: any[]) => Promise<any>;
|
|
314
316
|
abstract readonly _config: TConfig;
|
|
315
317
|
abstract readonly _name: string;
|
|
@@ -452,15 +454,7 @@ type CreateRoomOptions<TPlatform extends AbstractPlatform<any, any>, TAuthorize
|
|
|
452
454
|
];
|
|
453
455
|
declare class PluvServer<TPlatform extends AbstractPlatform<any, any> = AbstractPlatform<any, any>, TAuthorize extends PluvIOAuthorize<TPlatform, any, InferInitContextType<TPlatform>> | null = any, TContext extends Record<string, any> = {}, TEvents extends PluvRouterEventConfig<TPlatform, TAuthorize, TContext> = {}> implements IOLike<TAuthorize, TEvents> {
|
|
454
456
|
readonly version: string;
|
|
455
|
-
private readonly
|
|
456
|
-
private readonly _context;
|
|
457
|
-
private readonly _crdt;
|
|
458
|
-
private readonly _debug;
|
|
459
|
-
private readonly _getInitialStorage;
|
|
460
|
-
private readonly _io;
|
|
461
|
-
private readonly _limits;
|
|
462
|
-
private readonly _platform;
|
|
463
|
-
private readonly _inputRouter;
|
|
457
|
+
private readonly _config;
|
|
464
458
|
get fetch(): (...args: any[]) => Promise<any>;
|
|
465
459
|
/**
|
|
466
460
|
* @ignore
|
package/dist/index.js
CHANGED
|
@@ -1162,26 +1162,17 @@ var pickBy = (obj, by) => {
|
|
|
1162
1162
|
};
|
|
1163
1163
|
|
|
1164
1164
|
// src/version.generated.ts
|
|
1165
|
-
var version = "2.2.
|
|
1165
|
+
var version = "2.2.1";
|
|
1166
1166
|
|
|
1167
1167
|
// src/PluvServer.ts
|
|
1168
1168
|
var PluvServer = class {
|
|
1169
1169
|
constructor(options) {
|
|
1170
1170
|
this.version = version;
|
|
1171
|
-
this.
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
context,
|
|
1177
|
-
crdt = import_crdt2.noop,
|
|
1178
|
-
debug = false,
|
|
1179
|
-
getInitialStorage,
|
|
1180
|
-
io,
|
|
1181
|
-
limits,
|
|
1182
|
-
platform,
|
|
1183
|
-
router = new PluvRouter({})
|
|
1184
|
-
} = options;
|
|
1171
|
+
this._config = __spreadValues({
|
|
1172
|
+
crdt: import_crdt2.noop,
|
|
1173
|
+
debug: false,
|
|
1174
|
+
router: new PluvRouter({})
|
|
1175
|
+
}, options);
|
|
1185
1176
|
const {
|
|
1186
1177
|
onRoomDeleted,
|
|
1187
1178
|
onRoomMessage,
|
|
@@ -1189,16 +1180,6 @@ var PluvServer = class {
|
|
|
1189
1180
|
onUserConnected,
|
|
1190
1181
|
onUserDisconnected
|
|
1191
1182
|
} = options;
|
|
1192
|
-
platform().validateConfig(options);
|
|
1193
|
-
this._crdt = crdt;
|
|
1194
|
-
this._debug = debug;
|
|
1195
|
-
this._inputRouter = router;
|
|
1196
|
-
this._io = io;
|
|
1197
|
-
this._limits = limits;
|
|
1198
|
-
this._platform = platform;
|
|
1199
|
-
if (authorize2) this._authorize = authorize2;
|
|
1200
|
-
if (context) this._context = context;
|
|
1201
|
-
if (getInitialStorage) this._getInitialStorage = getInitialStorage;
|
|
1202
1183
|
this._listeners = {
|
|
1203
1184
|
onRoomDeleted: (event) => onRoomDeleted == null ? void 0 : onRoomDeleted(event),
|
|
1204
1185
|
onRoomMessage: (event) => onRoomMessage == null ? void 0 : onRoomMessage(event),
|
|
@@ -1208,7 +1189,7 @@ var PluvServer = class {
|
|
|
1208
1189
|
};
|
|
1209
1190
|
}
|
|
1210
1191
|
get fetch() {
|
|
1211
|
-
const platform = this.
|
|
1192
|
+
const platform = this._config.platform();
|
|
1212
1193
|
return (...args) => {
|
|
1213
1194
|
if (!platform._fetch)
|
|
1214
1195
|
throw new Error(`\`${platform._name}\` does not support \`fetch\``);
|
|
@@ -1222,13 +1203,14 @@ var PluvServer = class {
|
|
|
1222
1203
|
*/
|
|
1223
1204
|
get _defs() {
|
|
1224
1205
|
return {
|
|
1225
|
-
authorize: this.
|
|
1226
|
-
context: this.
|
|
1206
|
+
authorize: this._config.authorize,
|
|
1207
|
+
context: this._config.context,
|
|
1227
1208
|
events: this._router._defs.events,
|
|
1228
|
-
platform: this.
|
|
1209
|
+
platform: this._config.platform()
|
|
1229
1210
|
};
|
|
1230
1211
|
}
|
|
1231
1212
|
get _baseRouter() {
|
|
1213
|
+
const listeners = this._getListeners();
|
|
1232
1214
|
return new PluvRouter({
|
|
1233
1215
|
$getOthers: this._procedure.sync((data, { room, session, sessions }) => {
|
|
1234
1216
|
const currentTime = Date.now();
|
|
@@ -1265,11 +1247,14 @@ var PluvServer = class {
|
|
|
1265
1247
|
}
|
|
1266
1248
|
};
|
|
1267
1249
|
}).self((_0, _1) => __async(this, [_0, _1], function* (data, { context, doc, platform, room, session }) {
|
|
1268
|
-
var _a;
|
|
1250
|
+
var _a, _b;
|
|
1269
1251
|
const oldState = yield platform.persistence.getStorageState(room);
|
|
1270
1252
|
const update = data == null ? void 0 : data.update;
|
|
1271
1253
|
if (!oldState) {
|
|
1272
|
-
const loadedState = yield (_a = this.
|
|
1254
|
+
const loadedState = yield (_b = (_a = this._config).getInitialStorage) == null ? void 0 : _b.call(_a, {
|
|
1255
|
+
context,
|
|
1256
|
+
room
|
|
1257
|
+
});
|
|
1273
1258
|
if (!!loadedState) {
|
|
1274
1259
|
doc.applyEncodedState({ update: loadedState }).getEncodedState();
|
|
1275
1260
|
}
|
|
@@ -1283,13 +1268,13 @@ var PluvServer = class {
|
|
|
1283
1268
|
if (!!update) {
|
|
1284
1269
|
const encodedState2 = doc.applyEncodedState({ update }).getEncodedState();
|
|
1285
1270
|
const storageSize = new TextEncoder().encode(encodedState2).length;
|
|
1286
|
-
if (!!this.
|
|
1271
|
+
if (!!this._config.limits.storageMaxSize && storageSize > this._config.limits.storageMaxSize) {
|
|
1287
1272
|
throw new Error("Storage has exceeded the size limit");
|
|
1288
1273
|
}
|
|
1289
1274
|
yield platform.persistence.setStorageState(room, encodedState2).catch((error) => {
|
|
1290
1275
|
this._logDebug(error);
|
|
1291
1276
|
});
|
|
1292
|
-
|
|
1277
|
+
listeners.onStorageUpdated({
|
|
1293
1278
|
context,
|
|
1294
1279
|
encodedState: encodedState2,
|
|
1295
1280
|
platform,
|
|
@@ -1325,7 +1310,7 @@ var PluvServer = class {
|
|
|
1325
1310
|
);
|
|
1326
1311
|
const updated = Object.assign(/* @__PURE__ */ Object.create(null), session.presence, cleanedPatch);
|
|
1327
1312
|
const bytes = new TextEncoder().encode(JSON.stringify(updated)).length;
|
|
1328
|
-
if (!!this.
|
|
1313
|
+
if (!!this._config.limits.presenceMaxSize && bytes > this._config.limits.presenceMaxSize) {
|
|
1329
1314
|
throw new Error(
|
|
1330
1315
|
`Large presence. Presence must be at most 512 bytes. Current size: ${bytes.toLocaleString()}`
|
|
1331
1316
|
);
|
|
@@ -1346,11 +1331,11 @@ var PluvServer = class {
|
|
|
1346
1331
|
const updated = update === null ? doc : doc.applyEncodedState({ update });
|
|
1347
1332
|
const encodedState = updated.getEncodedState();
|
|
1348
1333
|
const storageSize = new TextEncoder().encode(encodedState).length;
|
|
1349
|
-
if (!!this.
|
|
1334
|
+
if (!!this._config.limits.storageMaxSize && storageSize > this._config.limits.storageMaxSize) {
|
|
1350
1335
|
throw new Error("Storage has exceeded the size limit");
|
|
1351
1336
|
}
|
|
1352
1337
|
platform.persistence.setStorageState(room, encodedState).then(() => {
|
|
1353
|
-
|
|
1338
|
+
listeners.onStorageUpdated({
|
|
1354
1339
|
context,
|
|
1355
1340
|
encodedState,
|
|
1356
1341
|
platform,
|
|
@@ -1365,26 +1350,27 @@ var PluvServer = class {
|
|
|
1365
1350
|
return new PluvProcedure();
|
|
1366
1351
|
}
|
|
1367
1352
|
get _router() {
|
|
1368
|
-
return this.
|
|
1353
|
+
return this._config.router ? PluvRouter.merge(this._baseRouter, this._config.router) : this._baseRouter;
|
|
1369
1354
|
}
|
|
1370
1355
|
createRoom(room, ...options) {
|
|
1371
1356
|
var _a, _c;
|
|
1372
1357
|
const _b = (_a = options[0]) != null ? _a : {}, { _meta, debug, onDestroy, onMessage } = _b, platformRoomContext = __objRest(_b, ["_meta", "debug", "onDestroy", "onMessage"]);
|
|
1373
|
-
const platform = this.
|
|
1358
|
+
const platform = this._config.platform();
|
|
1359
|
+
platform.validateConfig(this._config);
|
|
1374
1360
|
if (platform._config.handleMode !== "io") {
|
|
1375
1361
|
throw new Error(`\`createRoom\` is unsupported for \`${platform._name}\``);
|
|
1376
1362
|
}
|
|
1377
1363
|
if (!/^[a-z0-9](?:[a-z0-9-_]*[a-z0-9])?$/i.test(room))
|
|
1378
1364
|
throw new Error("Unsupported room name");
|
|
1379
1365
|
const roomContext = platformRoomContext;
|
|
1380
|
-
const context = typeof this.
|
|
1366
|
+
const context = typeof this._config.context === "function" ? this._config.context(roomContext) : this._config.context;
|
|
1381
1367
|
const listeners = this._getListeners();
|
|
1382
1368
|
const logDebug = this._logDebug.bind(this);
|
|
1383
1369
|
const newRoom = new IORoom(room, __spreadProps(__spreadValues({}, !!_meta ? { _meta } : {}), {
|
|
1384
|
-
authorize: (_c = this.
|
|
1370
|
+
authorize: (_c = this._config.authorize) != null ? _c : void 0,
|
|
1385
1371
|
context,
|
|
1386
|
-
crdt: this.
|
|
1387
|
-
debug: debug != null ? debug : this.
|
|
1372
|
+
crdt: this._config.crdt,
|
|
1373
|
+
debug: debug != null ? debug : this._config.debug,
|
|
1388
1374
|
onDestroy(event) {
|
|
1389
1375
|
return __async(this, null, function* () {
|
|
1390
1376
|
logDebug(`${import_kleur2.default.blue("Deleting empty room:")} ${room}`);
|
|
@@ -1419,14 +1405,14 @@ var PluvServer = class {
|
|
|
1419
1405
|
}
|
|
1420
1406
|
createToken(params) {
|
|
1421
1407
|
return __async(this, null, function* () {
|
|
1422
|
-
return yield this.
|
|
1408
|
+
return yield this._config.io.createToken(params);
|
|
1423
1409
|
});
|
|
1424
1410
|
}
|
|
1425
1411
|
_getListeners() {
|
|
1426
1412
|
return this._listeners;
|
|
1427
1413
|
}
|
|
1428
1414
|
_logDebug(...data) {
|
|
1429
|
-
if (this.
|
|
1415
|
+
if (this._config.debug) console.log(...data);
|
|
1430
1416
|
}
|
|
1431
1417
|
};
|
|
1432
1418
|
|
|
@@ -1472,7 +1458,9 @@ var PluvIO = class {
|
|
|
1472
1458
|
);
|
|
1473
1459
|
}
|
|
1474
1460
|
const platform = this._platform();
|
|
1475
|
-
if (platform._createToken)
|
|
1461
|
+
if (platform._createToken) {
|
|
1462
|
+
return yield platform._createToken(__spreadProps(__spreadValues({}, params), { authorize: ioAuthorize }));
|
|
1463
|
+
}
|
|
1476
1464
|
const secret = (_a = ioAuthorize == null ? void 0 : ioAuthorize.secret) != null ? _a : null;
|
|
1477
1465
|
if (!secret) throw new Error("`authorize` was specified without a valid secret");
|
|
1478
1466
|
return yield authorize({ platform, secret }).encode(
|
package/dist/index.mjs
CHANGED
|
@@ -1120,26 +1120,17 @@ var pickBy = (obj, by) => {
|
|
|
1120
1120
|
};
|
|
1121
1121
|
|
|
1122
1122
|
// src/version.generated.ts
|
|
1123
|
-
var version = "2.2.
|
|
1123
|
+
var version = "2.2.1";
|
|
1124
1124
|
|
|
1125
1125
|
// src/PluvServer.ts
|
|
1126
1126
|
var PluvServer = class {
|
|
1127
1127
|
constructor(options) {
|
|
1128
1128
|
this.version = version;
|
|
1129
|
-
this.
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
context,
|
|
1135
|
-
crdt = noop2,
|
|
1136
|
-
debug = false,
|
|
1137
|
-
getInitialStorage,
|
|
1138
|
-
io,
|
|
1139
|
-
limits,
|
|
1140
|
-
platform,
|
|
1141
|
-
router = new PluvRouter({})
|
|
1142
|
-
} = options;
|
|
1129
|
+
this._config = __spreadValues({
|
|
1130
|
+
crdt: noop2,
|
|
1131
|
+
debug: false,
|
|
1132
|
+
router: new PluvRouter({})
|
|
1133
|
+
}, options);
|
|
1143
1134
|
const {
|
|
1144
1135
|
onRoomDeleted,
|
|
1145
1136
|
onRoomMessage,
|
|
@@ -1147,16 +1138,6 @@ var PluvServer = class {
|
|
|
1147
1138
|
onUserConnected,
|
|
1148
1139
|
onUserDisconnected
|
|
1149
1140
|
} = options;
|
|
1150
|
-
platform().validateConfig(options);
|
|
1151
|
-
this._crdt = crdt;
|
|
1152
|
-
this._debug = debug;
|
|
1153
|
-
this._inputRouter = router;
|
|
1154
|
-
this._io = io;
|
|
1155
|
-
this._limits = limits;
|
|
1156
|
-
this._platform = platform;
|
|
1157
|
-
if (authorize2) this._authorize = authorize2;
|
|
1158
|
-
if (context) this._context = context;
|
|
1159
|
-
if (getInitialStorage) this._getInitialStorage = getInitialStorage;
|
|
1160
1141
|
this._listeners = {
|
|
1161
1142
|
onRoomDeleted: (event) => onRoomDeleted == null ? void 0 : onRoomDeleted(event),
|
|
1162
1143
|
onRoomMessage: (event) => onRoomMessage == null ? void 0 : onRoomMessage(event),
|
|
@@ -1166,7 +1147,7 @@ var PluvServer = class {
|
|
|
1166
1147
|
};
|
|
1167
1148
|
}
|
|
1168
1149
|
get fetch() {
|
|
1169
|
-
const platform = this.
|
|
1150
|
+
const platform = this._config.platform();
|
|
1170
1151
|
return (...args) => {
|
|
1171
1152
|
if (!platform._fetch)
|
|
1172
1153
|
throw new Error(`\`${platform._name}\` does not support \`fetch\``);
|
|
@@ -1180,13 +1161,14 @@ var PluvServer = class {
|
|
|
1180
1161
|
*/
|
|
1181
1162
|
get _defs() {
|
|
1182
1163
|
return {
|
|
1183
|
-
authorize: this.
|
|
1184
|
-
context: this.
|
|
1164
|
+
authorize: this._config.authorize,
|
|
1165
|
+
context: this._config.context,
|
|
1185
1166
|
events: this._router._defs.events,
|
|
1186
|
-
platform: this.
|
|
1167
|
+
platform: this._config.platform()
|
|
1187
1168
|
};
|
|
1188
1169
|
}
|
|
1189
1170
|
get _baseRouter() {
|
|
1171
|
+
const listeners = this._getListeners();
|
|
1190
1172
|
return new PluvRouter({
|
|
1191
1173
|
$getOthers: this._procedure.sync((data, { room, session, sessions }) => {
|
|
1192
1174
|
const currentTime = Date.now();
|
|
@@ -1223,11 +1205,14 @@ var PluvServer = class {
|
|
|
1223
1205
|
}
|
|
1224
1206
|
};
|
|
1225
1207
|
}).self((_0, _1) => __async(this, [_0, _1], function* (data, { context, doc, platform, room, session }) {
|
|
1226
|
-
var _a;
|
|
1208
|
+
var _a, _b;
|
|
1227
1209
|
const oldState = yield platform.persistence.getStorageState(room);
|
|
1228
1210
|
const update = data == null ? void 0 : data.update;
|
|
1229
1211
|
if (!oldState) {
|
|
1230
|
-
const loadedState = yield (_a = this.
|
|
1212
|
+
const loadedState = yield (_b = (_a = this._config).getInitialStorage) == null ? void 0 : _b.call(_a, {
|
|
1213
|
+
context,
|
|
1214
|
+
room
|
|
1215
|
+
});
|
|
1231
1216
|
if (!!loadedState) {
|
|
1232
1217
|
doc.applyEncodedState({ update: loadedState }).getEncodedState();
|
|
1233
1218
|
}
|
|
@@ -1241,13 +1226,13 @@ var PluvServer = class {
|
|
|
1241
1226
|
if (!!update) {
|
|
1242
1227
|
const encodedState2 = doc.applyEncodedState({ update }).getEncodedState();
|
|
1243
1228
|
const storageSize = new TextEncoder().encode(encodedState2).length;
|
|
1244
|
-
if (!!this.
|
|
1229
|
+
if (!!this._config.limits.storageMaxSize && storageSize > this._config.limits.storageMaxSize) {
|
|
1245
1230
|
throw new Error("Storage has exceeded the size limit");
|
|
1246
1231
|
}
|
|
1247
1232
|
yield platform.persistence.setStorageState(room, encodedState2).catch((error) => {
|
|
1248
1233
|
this._logDebug(error);
|
|
1249
1234
|
});
|
|
1250
|
-
|
|
1235
|
+
listeners.onStorageUpdated({
|
|
1251
1236
|
context,
|
|
1252
1237
|
encodedState: encodedState2,
|
|
1253
1238
|
platform,
|
|
@@ -1283,7 +1268,7 @@ var PluvServer = class {
|
|
|
1283
1268
|
);
|
|
1284
1269
|
const updated = Object.assign(/* @__PURE__ */ Object.create(null), session.presence, cleanedPatch);
|
|
1285
1270
|
const bytes = new TextEncoder().encode(JSON.stringify(updated)).length;
|
|
1286
|
-
if (!!this.
|
|
1271
|
+
if (!!this._config.limits.presenceMaxSize && bytes > this._config.limits.presenceMaxSize) {
|
|
1287
1272
|
throw new Error(
|
|
1288
1273
|
`Large presence. Presence must be at most 512 bytes. Current size: ${bytes.toLocaleString()}`
|
|
1289
1274
|
);
|
|
@@ -1304,11 +1289,11 @@ var PluvServer = class {
|
|
|
1304
1289
|
const updated = update === null ? doc : doc.applyEncodedState({ update });
|
|
1305
1290
|
const encodedState = updated.getEncodedState();
|
|
1306
1291
|
const storageSize = new TextEncoder().encode(encodedState).length;
|
|
1307
|
-
if (!!this.
|
|
1292
|
+
if (!!this._config.limits.storageMaxSize && storageSize > this._config.limits.storageMaxSize) {
|
|
1308
1293
|
throw new Error("Storage has exceeded the size limit");
|
|
1309
1294
|
}
|
|
1310
1295
|
platform.persistence.setStorageState(room, encodedState).then(() => {
|
|
1311
|
-
|
|
1296
|
+
listeners.onStorageUpdated({
|
|
1312
1297
|
context,
|
|
1313
1298
|
encodedState,
|
|
1314
1299
|
platform,
|
|
@@ -1323,26 +1308,27 @@ var PluvServer = class {
|
|
|
1323
1308
|
return new PluvProcedure();
|
|
1324
1309
|
}
|
|
1325
1310
|
get _router() {
|
|
1326
|
-
return this.
|
|
1311
|
+
return this._config.router ? PluvRouter.merge(this._baseRouter, this._config.router) : this._baseRouter;
|
|
1327
1312
|
}
|
|
1328
1313
|
createRoom(room, ...options) {
|
|
1329
1314
|
var _a, _c;
|
|
1330
1315
|
const _b = (_a = options[0]) != null ? _a : {}, { _meta, debug, onDestroy, onMessage } = _b, platformRoomContext = __objRest(_b, ["_meta", "debug", "onDestroy", "onMessage"]);
|
|
1331
|
-
const platform = this.
|
|
1316
|
+
const platform = this._config.platform();
|
|
1317
|
+
platform.validateConfig(this._config);
|
|
1332
1318
|
if (platform._config.handleMode !== "io") {
|
|
1333
1319
|
throw new Error(`\`createRoom\` is unsupported for \`${platform._name}\``);
|
|
1334
1320
|
}
|
|
1335
1321
|
if (!/^[a-z0-9](?:[a-z0-9-_]*[a-z0-9])?$/i.test(room))
|
|
1336
1322
|
throw new Error("Unsupported room name");
|
|
1337
1323
|
const roomContext = platformRoomContext;
|
|
1338
|
-
const context = typeof this.
|
|
1324
|
+
const context = typeof this._config.context === "function" ? this._config.context(roomContext) : this._config.context;
|
|
1339
1325
|
const listeners = this._getListeners();
|
|
1340
1326
|
const logDebug = this._logDebug.bind(this);
|
|
1341
1327
|
const newRoom = new IORoom(room, __spreadProps(__spreadValues({}, !!_meta ? { _meta } : {}), {
|
|
1342
|
-
authorize: (_c = this.
|
|
1328
|
+
authorize: (_c = this._config.authorize) != null ? _c : void 0,
|
|
1343
1329
|
context,
|
|
1344
|
-
crdt: this.
|
|
1345
|
-
debug: debug != null ? debug : this.
|
|
1330
|
+
crdt: this._config.crdt,
|
|
1331
|
+
debug: debug != null ? debug : this._config.debug,
|
|
1346
1332
|
onDestroy(event) {
|
|
1347
1333
|
return __async(this, null, function* () {
|
|
1348
1334
|
logDebug(`${colors2.blue("Deleting empty room:")} ${room}`);
|
|
@@ -1377,14 +1363,14 @@ var PluvServer = class {
|
|
|
1377
1363
|
}
|
|
1378
1364
|
createToken(params) {
|
|
1379
1365
|
return __async(this, null, function* () {
|
|
1380
|
-
return yield this.
|
|
1366
|
+
return yield this._config.io.createToken(params);
|
|
1381
1367
|
});
|
|
1382
1368
|
}
|
|
1383
1369
|
_getListeners() {
|
|
1384
1370
|
return this._listeners;
|
|
1385
1371
|
}
|
|
1386
1372
|
_logDebug(...data) {
|
|
1387
|
-
if (this.
|
|
1373
|
+
if (this._config.debug) console.log(...data);
|
|
1388
1374
|
}
|
|
1389
1375
|
};
|
|
1390
1376
|
|
|
@@ -1430,7 +1416,9 @@ var PluvIO = class {
|
|
|
1430
1416
|
);
|
|
1431
1417
|
}
|
|
1432
1418
|
const platform = this._platform();
|
|
1433
|
-
if (platform._createToken)
|
|
1419
|
+
if (platform._createToken) {
|
|
1420
|
+
return yield platform._createToken(__spreadProps(__spreadValues({}, params), { authorize: ioAuthorize }));
|
|
1421
|
+
}
|
|
1434
1422
|
const secret = (_a = ioAuthorize == null ? void 0 : ioAuthorize.secret) != null ? _a : null;
|
|
1435
1423
|
if (!secret) throw new Error("`authorize` was specified without a valid secret");
|
|
1436
1424
|
return yield authorize({ platform, secret }).encode(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pluv/io",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.1",
|
|
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.1",
|
|
25
|
+
"@pluv/types": "^2.2.1"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"eslint": "^9.26.0",
|
|
29
29
|
"genversion": "^3.2.0",
|
|
30
30
|
"tsup": "^8.4.0",
|
|
31
31
|
"typescript": "^5.8.3",
|
|
32
|
-
"@pluv/tsconfig": "^2.2.
|
|
33
|
-
"eslint-config-pluv": "^2.2.
|
|
32
|
+
"@pluv/tsconfig": "^2.2.1",
|
|
33
|
+
"eslint-config-pluv": "^2.2.1"
|
|
34
34
|
},
|
|
35
35
|
"scripts": {
|
|
36
36
|
"build": "pnpm run version && tsup src/index.ts --format esm,cjs --dts",
|
package/src/AbstractPlatform.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import type { Maybe } from "@pluv/types";
|
|
1
2
|
import type { AbstractPersistence } from "./AbstractPersistence";
|
|
2
3
|
import type { AbstractPubSub } from "./AbstractPubSub";
|
|
3
4
|
import type { AbstractWebSocket, InferWebSocketSource } from "./AbstractWebSocket";
|
|
4
5
|
import type { JWTEncodeParams } from "./authorize";
|
|
5
6
|
import { Persistence } from "./Persistence";
|
|
6
7
|
import { PubSub } from "./PubSub";
|
|
7
|
-
import type { PlatformConfig, WebSocketSerializedState } from "./types";
|
|
8
|
+
import type { PlatformConfig, ResolvedPluvIOAuthorize, WebSocketSerializedState } from "./types";
|
|
8
9
|
|
|
9
10
|
export type InferPlatformWebSocketType<TPlatform extends AbstractPlatform> =
|
|
10
11
|
TPlatform extends AbstractPlatform<infer IAbstractWebSocket> ? IAbstractWebSocket : never;
|
|
@@ -44,7 +45,11 @@ export abstract class AbstractPlatform<
|
|
|
44
45
|
public persistence: AbstractPersistence;
|
|
45
46
|
public pubSub: AbstractPubSub;
|
|
46
47
|
|
|
47
|
-
public readonly _createToken?: (
|
|
48
|
+
public readonly _createToken?: (
|
|
49
|
+
params: JWTEncodeParams<any, any> & {
|
|
50
|
+
authorize: Maybe<ResolvedPluvIOAuthorize<any, any>>;
|
|
51
|
+
},
|
|
52
|
+
) => Promise<string>;
|
|
48
53
|
public _fetch?: (...args: any[]) => Promise<any>;
|
|
49
54
|
public abstract readonly _config: TConfig;
|
|
50
55
|
public abstract readonly _name: string;
|
package/src/PluvIO.ts
CHANGED
|
@@ -149,7 +149,9 @@ export class PluvIO<
|
|
|
149
149
|
* to support platformPluv
|
|
150
150
|
* @date December 15, 2024
|
|
151
151
|
*/
|
|
152
|
-
if (platform._createToken)
|
|
152
|
+
if (platform._createToken) {
|
|
153
|
+
return await platform._createToken({ ...params, authorize: ioAuthorize });
|
|
154
|
+
}
|
|
153
155
|
|
|
154
156
|
const secret = ioAuthorize?.secret ?? null;
|
|
155
157
|
|
package/src/PluvServer.ts
CHANGED
|
@@ -7,6 +7,7 @@ import type {
|
|
|
7
7
|
InferIOAuthorizeUser,
|
|
8
8
|
JsonObject,
|
|
9
9
|
Maybe,
|
|
10
|
+
NonNilProps,
|
|
10
11
|
} from "@pluv/types";
|
|
11
12
|
import colors from "kleur";
|
|
12
13
|
import type {
|
|
@@ -95,21 +96,12 @@ export class PluvServer<
|
|
|
95
96
|
{
|
|
96
97
|
public readonly version: string = __PLUV_VERSION as any;
|
|
97
98
|
|
|
98
|
-
private readonly
|
|
99
|
-
|
|
100
|
-
TPlatform,
|
|
101
|
-
TContext
|
|
99
|
+
private readonly _config: NonNilProps<
|
|
100
|
+
PluvServerConfig<TPlatform, TAuthorize, TContext, TEvents>
|
|
102
101
|
>;
|
|
103
|
-
private readonly _crdt: { doc: (value: any) => AbstractCrdtDocFactory<any, any> };
|
|
104
|
-
private readonly _debug: boolean;
|
|
105
|
-
private readonly _getInitialStorage: GetInitialStorageFn<TContext> | null = null;
|
|
106
|
-
private readonly _io: PluvIO<TPlatform, TAuthorize, TContext>;
|
|
107
|
-
private readonly _limits: PluvIOLimits;
|
|
108
|
-
private readonly _platform: () => TPlatform;
|
|
109
|
-
private readonly _inputRouter: PluvRouter<TPlatform, TAuthorize, TContext, TEvents>;
|
|
110
102
|
|
|
111
103
|
public get fetch(): (...args: any[]) => Promise<any> {
|
|
112
|
-
const platform = this.
|
|
104
|
+
const platform = this._config.platform();
|
|
113
105
|
|
|
114
106
|
return ((...args: any[]): Promise<any> => {
|
|
115
107
|
if (!platform._fetch)
|
|
@@ -126,10 +118,10 @@ export class PluvServer<
|
|
|
126
118
|
*/
|
|
127
119
|
public get _defs() {
|
|
128
120
|
return {
|
|
129
|
-
authorize: this.
|
|
130
|
-
context: this.
|
|
121
|
+
authorize: this._config.authorize,
|
|
122
|
+
context: this._config.context,
|
|
131
123
|
events: this._router._defs.events,
|
|
132
|
-
platform: this.
|
|
124
|
+
platform: this._config.platform(),
|
|
133
125
|
} as {
|
|
134
126
|
authorize: TAuthorize;
|
|
135
127
|
context: TContext;
|
|
@@ -139,6 +131,8 @@ export class PluvServer<
|
|
|
139
131
|
}
|
|
140
132
|
|
|
141
133
|
private get _baseRouter(): PluvRouter<TPlatform, TAuthorize, TContext, {}> {
|
|
134
|
+
const listeners = this._getListeners();
|
|
135
|
+
|
|
142
136
|
return new PluvRouter({
|
|
143
137
|
$getOthers: this._procedure.sync((data, { room, session, sessions }) => {
|
|
144
138
|
const currentTime = Date.now();
|
|
@@ -202,7 +196,10 @@ export class PluvServer<
|
|
|
202
196
|
const update = (data as any)?.update as Maybe<string>;
|
|
203
197
|
|
|
204
198
|
if (!oldState) {
|
|
205
|
-
const loadedState = await this.
|
|
199
|
+
const loadedState = await this._config.getInitialStorage?.({
|
|
200
|
+
context,
|
|
201
|
+
room,
|
|
202
|
+
});
|
|
206
203
|
|
|
207
204
|
if (!!loadedState) {
|
|
208
205
|
doc.applyEncodedState({ update: loadedState }).getEncodedState();
|
|
@@ -234,8 +231,8 @@ export class PluvServer<
|
|
|
234
231
|
const storageSize = new TextEncoder().encode(encodedState).length;
|
|
235
232
|
|
|
236
233
|
if (
|
|
237
|
-
!!this.
|
|
238
|
-
storageSize > this.
|
|
234
|
+
!!this._config.limits.storageMaxSize &&
|
|
235
|
+
storageSize > this._config.limits.storageMaxSize
|
|
239
236
|
) {
|
|
240
237
|
throw new Error("Storage has exceeded the size limit");
|
|
241
238
|
}
|
|
@@ -246,7 +243,7 @@ export class PluvServer<
|
|
|
246
243
|
this._logDebug(error);
|
|
247
244
|
});
|
|
248
245
|
|
|
249
|
-
|
|
246
|
+
listeners.onStorageUpdated({
|
|
250
247
|
context,
|
|
251
248
|
encodedState,
|
|
252
249
|
platform,
|
|
@@ -293,7 +290,10 @@ export class PluvServer<
|
|
|
293
290
|
const updated = Object.assign(Object.create(null), session.presence, cleanedPatch);
|
|
294
291
|
const bytes = new TextEncoder().encode(JSON.stringify(updated)).length;
|
|
295
292
|
|
|
296
|
-
if (
|
|
293
|
+
if (
|
|
294
|
+
!!this._config.limits.presenceMaxSize &&
|
|
295
|
+
bytes > this._config.limits.presenceMaxSize
|
|
296
|
+
) {
|
|
297
297
|
throw new Error(
|
|
298
298
|
`Large presence. Presence must be at most 512 bytes. Current size: ${bytes.toLocaleString()}`,
|
|
299
299
|
);
|
|
@@ -318,12 +318,15 @@ export class PluvServer<
|
|
|
318
318
|
const encodedState = updated.getEncodedState();
|
|
319
319
|
const storageSize = new TextEncoder().encode(encodedState).length;
|
|
320
320
|
|
|
321
|
-
if (
|
|
321
|
+
if (
|
|
322
|
+
!!this._config.limits.storageMaxSize &&
|
|
323
|
+
storageSize > this._config.limits.storageMaxSize
|
|
324
|
+
) {
|
|
322
325
|
throw new Error("Storage has exceeded the size limit");
|
|
323
326
|
}
|
|
324
327
|
|
|
325
328
|
platform.persistence.setStorageState(room, encodedState).then(() => {
|
|
326
|
-
|
|
329
|
+
listeners.onStorageUpdated({
|
|
327
330
|
context,
|
|
328
331
|
encodedState,
|
|
329
332
|
platform,
|
|
@@ -342,24 +345,19 @@ export class PluvServer<
|
|
|
342
345
|
|
|
343
346
|
private get _router(): PluvRouter<TPlatform, TAuthorize, TContext, TEvents> {
|
|
344
347
|
return (
|
|
345
|
-
this.
|
|
346
|
-
? PluvRouter.merge(this._baseRouter, this.
|
|
348
|
+
this._config.router
|
|
349
|
+
? PluvRouter.merge(this._baseRouter, this._config.router)
|
|
347
350
|
: this._baseRouter
|
|
348
351
|
) as PluvRouter<TPlatform, TAuthorize, TContext, TEvents>;
|
|
349
352
|
}
|
|
350
353
|
|
|
351
354
|
constructor(options: PluvServerConfig<TPlatform, TAuthorize, TContext, TEvents>) {
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
io,
|
|
359
|
-
limits,
|
|
360
|
-
platform,
|
|
361
|
-
router = new PluvRouter<TPlatform, TAuthorize, TContext, TEvents>({} as TEvents),
|
|
362
|
-
} = options;
|
|
355
|
+
this._config = {
|
|
356
|
+
crdt: noop,
|
|
357
|
+
debug: false,
|
|
358
|
+
router: new PluvRouter<TPlatform, TAuthorize, TContext, TEvents>({} as TEvents),
|
|
359
|
+
...options,
|
|
360
|
+
} as NonNilProps<PluvServerConfig<TPlatform, TAuthorize, TContext, TEvents>>;
|
|
363
361
|
|
|
364
362
|
const {
|
|
365
363
|
onRoomDeleted,
|
|
@@ -369,19 +367,6 @@ export class PluvServer<
|
|
|
369
367
|
onUserDisconnected,
|
|
370
368
|
} = options as Partial<BasePluvIOListeners<TPlatform, TAuthorize, TContext, TEvents>>;
|
|
371
369
|
|
|
372
|
-
platform().validateConfig(options);
|
|
373
|
-
|
|
374
|
-
this._crdt = crdt;
|
|
375
|
-
this._debug = debug;
|
|
376
|
-
this._inputRouter = router;
|
|
377
|
-
this._io = io;
|
|
378
|
-
this._limits = limits;
|
|
379
|
-
this._platform = platform;
|
|
380
|
-
|
|
381
|
-
if (authorize) this._authorize = authorize;
|
|
382
|
-
if (context) this._context = context;
|
|
383
|
-
if (getInitialStorage) this._getInitialStorage = getInitialStorage;
|
|
384
|
-
|
|
385
370
|
(this as any)._listeners = {
|
|
386
371
|
onRoomDeleted: (event) => onRoomDeleted?.(event),
|
|
387
372
|
onRoomMessage: (event) => onRoomMessage?.(event),
|
|
@@ -398,7 +383,9 @@ export class PluvServer<
|
|
|
398
383
|
const { _meta, debug, onDestroy, onMessage, ...platformRoomContext } = (options[0] ??
|
|
399
384
|
{}) as CreateRoomOptions<TPlatform, TAuthorize, TContext, TEvents>[0] & { _meta?: any };
|
|
400
385
|
|
|
401
|
-
const platform = this.
|
|
386
|
+
const platform = this._config.platform();
|
|
387
|
+
|
|
388
|
+
platform.validateConfig(this._config);
|
|
402
389
|
|
|
403
390
|
if (platform._config.handleMode !== "io") {
|
|
404
391
|
throw new Error(`\`createRoom\` is unsupported for \`${platform._name}\``);
|
|
@@ -409,16 +396,18 @@ export class PluvServer<
|
|
|
409
396
|
|
|
410
397
|
const roomContext = platformRoomContext as InferRoomContextType<TPlatform>;
|
|
411
398
|
const context: TContext =
|
|
412
|
-
typeof this.
|
|
399
|
+
typeof this._config.context === "function"
|
|
400
|
+
? this._config.context(roomContext)
|
|
401
|
+
: this._config.context;
|
|
413
402
|
const listeners = this._getListeners();
|
|
414
403
|
const logDebug = this._logDebug.bind(this);
|
|
415
404
|
|
|
416
405
|
const newRoom = new IORoom<TPlatform, TAuthorize, TContext, TEvents>(room, {
|
|
417
406
|
...(!!_meta ? { _meta } : {}),
|
|
418
|
-
authorize: this.
|
|
407
|
+
authorize: this._config.authorize ?? undefined,
|
|
419
408
|
context,
|
|
420
|
-
crdt: this.
|
|
421
|
-
debug: debug ?? this.
|
|
409
|
+
crdt: this._config.crdt,
|
|
410
|
+
debug: debug ?? this._config.debug,
|
|
422
411
|
async onDestroy(event) {
|
|
423
412
|
logDebug(`${colors.blue("Deleting empty room:")} ${room}`);
|
|
424
413
|
|
|
@@ -451,7 +440,7 @@ export class PluvServer<
|
|
|
451
440
|
public async createToken(
|
|
452
441
|
params: JWTEncodeParams<InferIOAuthorizeUser<InferIOAuthorize<this>>, TPlatform>,
|
|
453
442
|
): Promise<string> {
|
|
454
|
-
return await this.
|
|
443
|
+
return await this._config.io.createToken(params);
|
|
455
444
|
}
|
|
456
445
|
|
|
457
446
|
private _getListeners(): BasePluvIOListeners<TPlatform, TAuthorize, TContext, TEvents> {
|
|
@@ -459,6 +448,6 @@ export class PluvServer<
|
|
|
459
448
|
}
|
|
460
449
|
|
|
461
450
|
private _logDebug(...data: any[]): void {
|
|
462
|
-
if (this.
|
|
451
|
+
if (this._config.debug) console.log(...data);
|
|
463
452
|
}
|
|
464
453
|
}
|
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.1'
|