@rljson/server 0.0.4 → 0.0.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/README.architecture.md +1116 -0
- package/README.blog.md +9 -1
- package/README.contributors.md +47 -13
- package/README.md +70 -11
- package/README.public.md +204 -2
- package/README.trouble.md +50 -0
- package/dist/README.architecture.md +1116 -0
- package/dist/README.blog.md +9 -1
- package/dist/README.contributors.md +47 -13
- package/dist/README.md +70 -11
- package/dist/README.public.md +204 -2
- package/dist/README.trouble.md +50 -0
- package/dist/client.d.ts +6 -3
- package/dist/server.d.ts +7 -3
- package/dist/server.js +69 -37
- package/dist/socket-bundle.d.ts +16 -0
- package/package.json +11 -11
package/dist/server.js
CHANGED
|
@@ -743,21 +743,23 @@ class BsPeerBridge {
|
|
|
743
743
|
this._socket = _socket;
|
|
744
744
|
}
|
|
745
745
|
_eventHandlers = /* @__PURE__ */ new Map();
|
|
746
|
+
_handleConnectBound = this._handleConnect.bind(this);
|
|
747
|
+
_handleDisconnectBound = this._handleDisconnect.bind(this);
|
|
746
748
|
/**
|
|
747
749
|
* Starts the bridge by setting up connection event handlers and
|
|
748
750
|
* automatically registering all Bs methods.
|
|
749
751
|
*/
|
|
750
752
|
start() {
|
|
751
|
-
this._socket.on("connect",
|
|
752
|
-
this._socket.on("disconnect",
|
|
753
|
+
this._socket.on("connect", this._handleConnectBound);
|
|
754
|
+
this._socket.on("disconnect", this._handleDisconnectBound);
|
|
753
755
|
this._registerBsMethods();
|
|
754
756
|
}
|
|
755
757
|
/**
|
|
756
758
|
* Stops the bridge by removing all event handlers.
|
|
757
759
|
*/
|
|
758
760
|
stop() {
|
|
759
|
-
this._socket.off("connect",
|
|
760
|
-
this._socket.off("disconnect",
|
|
761
|
+
this._socket.off("connect", this._handleConnectBound);
|
|
762
|
+
this._socket.off("disconnect", this._handleDisconnectBound);
|
|
761
763
|
for (const [eventName, handler] of this._eventHandlers) {
|
|
762
764
|
this._socket.off(eventName, handler);
|
|
763
765
|
}
|
|
@@ -768,14 +770,11 @@ class BsPeerBridge {
|
|
|
768
770
|
*/
|
|
769
771
|
_registerBsMethods() {
|
|
770
772
|
const bsMethods = [
|
|
771
|
-
"setBlob",
|
|
772
773
|
"getBlob",
|
|
773
774
|
"getBlobStream",
|
|
774
|
-
"deleteBlob",
|
|
775
775
|
"blobExists",
|
|
776
776
|
"getBlobProperties",
|
|
777
|
-
"listBlobs"
|
|
778
|
-
"generateSignedUrl"
|
|
777
|
+
"listBlobs"
|
|
779
778
|
];
|
|
780
779
|
for (const methodName of bsMethods) {
|
|
781
780
|
this.registerEvent(methodName);
|
|
@@ -797,17 +796,17 @@ class BsPeerBridge {
|
|
|
797
796
|
`Method "${methodName}" not found on Bs instance`
|
|
798
797
|
);
|
|
799
798
|
if (typeof callback === "function") {
|
|
800
|
-
callback(
|
|
799
|
+
callback(error, null);
|
|
801
800
|
}
|
|
802
801
|
return;
|
|
803
802
|
}
|
|
804
803
|
bsMethod.apply(this._bs, methodArgs).then((result) => {
|
|
805
804
|
if (typeof callback === "function") {
|
|
806
|
-
callback(
|
|
805
|
+
callback(null, result);
|
|
807
806
|
}
|
|
808
807
|
}).catch((error) => {
|
|
809
808
|
if (typeof callback === "function") {
|
|
810
|
-
callback(
|
|
809
|
+
callback(error, null);
|
|
811
810
|
}
|
|
812
811
|
});
|
|
813
812
|
};
|
|
@@ -855,9 +854,9 @@ class BsPeerBridge {
|
|
|
855
854
|
throw new Error(`Method "${bsMethodName}" not found on Bs instance`);
|
|
856
855
|
}
|
|
857
856
|
const result = await bsMethod.apply(this._bs, args);
|
|
858
|
-
this._socket.emit(socketEventName,
|
|
857
|
+
this._socket.emit(socketEventName, null, result);
|
|
859
858
|
} catch (error) {
|
|
860
|
-
this._socket.emit(socketEventName,
|
|
859
|
+
this._socket.emit(socketEventName, error, null);
|
|
861
860
|
}
|
|
862
861
|
}
|
|
863
862
|
/* v8 ignore next -- @preserve */
|
|
@@ -978,11 +977,24 @@ class BaseNode {
|
|
|
978
977
|
await this._localDb.core.import(data);
|
|
979
978
|
}
|
|
980
979
|
}
|
|
980
|
+
function normalizeSocketBundle(socket) {
|
|
981
|
+
const bundle = socket;
|
|
982
|
+
if (bundle.ioUp && bundle.ioDown && bundle.bsUp && bundle.bsDown) {
|
|
983
|
+
return bundle;
|
|
984
|
+
}
|
|
985
|
+
const single = socket;
|
|
986
|
+
return {
|
|
987
|
+
ioUp: single,
|
|
988
|
+
ioDown: single,
|
|
989
|
+
bsUp: single,
|
|
990
|
+
bsDown: single
|
|
991
|
+
};
|
|
992
|
+
}
|
|
981
993
|
class Client extends BaseNode {
|
|
982
994
|
// ...........................................................................
|
|
983
995
|
/**
|
|
984
996
|
* Creates a Client instance
|
|
985
|
-
* @param _socketToServer - Socket to connect to server
|
|
997
|
+
* @param _socketToServer - Socket or namespace bundle to connect to server
|
|
986
998
|
* @param _localIo - Local Io for local storage
|
|
987
999
|
* @param _localBs - Local Bs for local blob storage
|
|
988
1000
|
*/
|
|
@@ -1043,6 +1055,7 @@ class Client extends BaseNode {
|
|
|
1043
1055
|
* Builds the Io multi with local and peer layers.
|
|
1044
1056
|
*/
|
|
1045
1057
|
async _setupIo() {
|
|
1058
|
+
const sockets = normalizeSocketBundle(this._socketToServer);
|
|
1046
1059
|
this._ioMultiIos.push({
|
|
1047
1060
|
io: this._localIo,
|
|
1048
1061
|
dump: true,
|
|
@@ -1050,9 +1063,9 @@ class Client extends BaseNode {
|
|
|
1050
1063
|
write: true,
|
|
1051
1064
|
priority: 1
|
|
1052
1065
|
});
|
|
1053
|
-
const ioPeerBridge = new IoPeerBridge(this._localIo,
|
|
1066
|
+
const ioPeerBridge = new IoPeerBridge(this._localIo, sockets.ioUp);
|
|
1054
1067
|
ioPeerBridge.start();
|
|
1055
|
-
const ioPeer = await this._createIoPeer();
|
|
1068
|
+
const ioPeer = await this._createIoPeer(sockets.ioDown);
|
|
1056
1069
|
this._ioMultiIos.push({
|
|
1057
1070
|
io: ioPeer,
|
|
1058
1071
|
dump: false,
|
|
@@ -1068,15 +1081,16 @@ class Client extends BaseNode {
|
|
|
1068
1081
|
* Builds the Bs multi with local and peer layers.
|
|
1069
1082
|
*/
|
|
1070
1083
|
async _setupBs() {
|
|
1084
|
+
const sockets = normalizeSocketBundle(this._socketToServer);
|
|
1071
1085
|
this._bsMultiBss.push({
|
|
1072
1086
|
bs: this._localBs,
|
|
1073
1087
|
read: true,
|
|
1074
1088
|
write: true,
|
|
1075
1089
|
priority: 1
|
|
1076
1090
|
});
|
|
1077
|
-
const bsPeerBridge = new BsPeerBridge(this._localBs,
|
|
1091
|
+
const bsPeerBridge = new BsPeerBridge(this._localBs, sockets.bsUp);
|
|
1078
1092
|
bsPeerBridge.start();
|
|
1079
|
-
const bsPeer = await this._createBsPeer();
|
|
1093
|
+
const bsPeer = await this._createBsPeer(sockets.bsDown);
|
|
1080
1094
|
this._bsMultiBss.push({
|
|
1081
1095
|
bs: bsPeer,
|
|
1082
1096
|
read: true,
|
|
@@ -1088,18 +1102,20 @@ class Client extends BaseNode {
|
|
|
1088
1102
|
}
|
|
1089
1103
|
/**
|
|
1090
1104
|
* Creates and initializes a downstream Io peer.
|
|
1105
|
+
* @param socket - Downstream socket to the server Io namespace.
|
|
1091
1106
|
*/
|
|
1092
|
-
async _createIoPeer() {
|
|
1093
|
-
const ioPeer = new IoPeer(
|
|
1107
|
+
async _createIoPeer(socket) {
|
|
1108
|
+
const ioPeer = new IoPeer(socket);
|
|
1094
1109
|
await ioPeer.init();
|
|
1095
1110
|
await ioPeer.isReady();
|
|
1096
1111
|
return ioPeer;
|
|
1097
1112
|
}
|
|
1098
1113
|
/**
|
|
1099
1114
|
* Creates and initializes a downstream Bs peer.
|
|
1115
|
+
* @param socket - Downstream socket to the server Bs namespace.
|
|
1100
1116
|
*/
|
|
1101
|
-
async _createBsPeer() {
|
|
1102
|
-
const bsPeer = new BsPeer(
|
|
1117
|
+
async _createBsPeer(socket) {
|
|
1118
|
+
const bsPeer = new BsPeer(socket);
|
|
1103
1119
|
await bsPeer.init();
|
|
1104
1120
|
return bsPeer;
|
|
1105
1121
|
}
|
|
@@ -1167,12 +1183,25 @@ class Server extends BaseNode {
|
|
|
1167
1183
|
* @returns The server instance.
|
|
1168
1184
|
*/
|
|
1169
1185
|
async addSocket(socket) {
|
|
1186
|
+
const sockets = normalizeSocketBundle(socket);
|
|
1170
1187
|
const clientId = `client_${this._clients.size}_${Math.random().toString(36).slice(2)}`;
|
|
1171
|
-
|
|
1172
|
-
const
|
|
1173
|
-
const
|
|
1174
|
-
|
|
1175
|
-
|
|
1188
|
+
const ioUp = sockets.ioUp;
|
|
1189
|
+
const ioDown = sockets.ioDown;
|
|
1190
|
+
const bsUp = sockets.bsUp;
|
|
1191
|
+
const bsDown = sockets.bsDown;
|
|
1192
|
+
ioUp.__clientId = clientId;
|
|
1193
|
+
ioDown.__clientId = clientId;
|
|
1194
|
+
bsUp.__clientId = clientId;
|
|
1195
|
+
bsDown.__clientId = clientId;
|
|
1196
|
+
const ioPeer = await this._createIoPeer(ioUp);
|
|
1197
|
+
const bsPeer = await this._createBsPeer(bsUp);
|
|
1198
|
+
this._registerClient(
|
|
1199
|
+
clientId,
|
|
1200
|
+
{ ioUp, ioDown, bsUp, bsDown },
|
|
1201
|
+
ioPeer,
|
|
1202
|
+
bsPeer
|
|
1203
|
+
);
|
|
1204
|
+
this._pendingSockets.push({ ioDown, bsDown });
|
|
1176
1205
|
this._queueIoPeer(ioPeer);
|
|
1177
1206
|
this._queueBsPeer(bsPeer);
|
|
1178
1207
|
await this._queueRefresh();
|
|
@@ -1185,8 +1214,8 @@ class Server extends BaseNode {
|
|
|
1185
1214
|
* Removes all listeners from all connected clients.
|
|
1186
1215
|
*/
|
|
1187
1216
|
_removeAllListeners() {
|
|
1188
|
-
for (const {
|
|
1189
|
-
|
|
1217
|
+
for (const { ioUp } of this._clients.values()) {
|
|
1218
|
+
ioUp.removeAllListeners(this._route.flat);
|
|
1190
1219
|
}
|
|
1191
1220
|
}
|
|
1192
1221
|
// ...........................................................................
|
|
@@ -1195,7 +1224,7 @@ class Server extends BaseNode {
|
|
|
1195
1224
|
* Ensures the sender is filtered out when broadcasting.
|
|
1196
1225
|
*/
|
|
1197
1226
|
_multicastRefs = () => {
|
|
1198
|
-
for (const [clientIdA, {
|
|
1227
|
+
for (const [clientIdA, { ioUp: socketA }] of this._clients.entries()) {
|
|
1199
1228
|
socketA.on(this._route.flat, (payload) => {
|
|
1200
1229
|
const ref = payload.r;
|
|
1201
1230
|
if (this._multicastedRefs.has(ref)) {
|
|
@@ -1208,7 +1237,7 @@ class Server extends BaseNode {
|
|
|
1208
1237
|
}
|
|
1209
1238
|
for (const [
|
|
1210
1239
|
clientIdB,
|
|
1211
|
-
{
|
|
1240
|
+
{ ioDown: socketB }
|
|
1212
1241
|
] of this._clients.entries()) {
|
|
1213
1242
|
if (clientIdA !== clientIdB) {
|
|
1214
1243
|
const forwarded = Object.assign({}, payload, {
|
|
@@ -1263,13 +1292,16 @@ class Server extends BaseNode {
|
|
|
1263
1292
|
/**
|
|
1264
1293
|
* Registers the client socket and peers.
|
|
1265
1294
|
* @param clientId - Stable client identifier.
|
|
1266
|
-
* @param
|
|
1295
|
+
* @param sockets - Directional sockets to register.
|
|
1267
1296
|
* @param io - Io peer associated with the client.
|
|
1268
1297
|
* @param bs - Bs peer associated with the client.
|
|
1269
1298
|
*/
|
|
1270
|
-
_registerClient(clientId,
|
|
1299
|
+
_registerClient(clientId, sockets, io, bs) {
|
|
1271
1300
|
this._clients.set(clientId, {
|
|
1272
|
-
|
|
1301
|
+
ioUp: sockets.ioUp,
|
|
1302
|
+
ioDown: sockets.ioDown,
|
|
1303
|
+
bsUp: sockets.bsUp,
|
|
1304
|
+
bsDown: sockets.bsDown,
|
|
1273
1305
|
io,
|
|
1274
1306
|
bs
|
|
1275
1307
|
});
|
|
@@ -1315,9 +1347,9 @@ class Server extends BaseNode {
|
|
|
1315
1347
|
async _refreshServers() {
|
|
1316
1348
|
this._ioServer._io = this._ioMulti;
|
|
1317
1349
|
this._bsServer._bs = this._bsMulti;
|
|
1318
|
-
for (const
|
|
1319
|
-
await this._ioServer.addSocket(
|
|
1320
|
-
await this._bsServer.addSocket(
|
|
1350
|
+
for (const pending of this._pendingSockets) {
|
|
1351
|
+
await this._ioServer.addSocket(pending.ioDown);
|
|
1352
|
+
await this._bsServer.addSocket(pending.bsDown);
|
|
1321
1353
|
}
|
|
1322
1354
|
this._pendingSockets = [];
|
|
1323
1355
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Socket } from '@rljson/io';
|
|
2
|
+
export type SocketNamespaceBundle = {
|
|
3
|
+
ioUp: Socket;
|
|
4
|
+
ioDown: Socket;
|
|
5
|
+
bsUp: Socket;
|
|
6
|
+
bsDown: Socket;
|
|
7
|
+
};
|
|
8
|
+
export type SocketLike = Socket | SocketNamespaceBundle;
|
|
9
|
+
/**
|
|
10
|
+
* Normalizes a socket input into a full namespace bundle used by the server/client constructors.
|
|
11
|
+
* - If you pass a single Socket (classic setup), it is reused for all namespaces (ioUp/ioDown/bsUp/bsDown).
|
|
12
|
+
* - If you pass an explicit bundle (namespaces already split), the bundle is returned as-is.
|
|
13
|
+
* @param socket - Single socket or pre-split namespace bundle.
|
|
14
|
+
* @returns Normalized namespace bundle for Io/Bs up/down channels.
|
|
15
|
+
*/
|
|
16
|
+
export declare function normalizeSocketBundle(socket: SocketLike): SocketNamespaceBundle;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rljson/server",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.5",
|
|
4
4
|
"description": "Rljson server description",
|
|
5
5
|
"homepage": "https://github.com/rljson/server",
|
|
6
6
|
"bugs": "https://github.com/rljson/server/issues",
|
|
@@ -20,21 +20,21 @@
|
|
|
20
20
|
],
|
|
21
21
|
"type": "module",
|
|
22
22
|
"devDependencies": {
|
|
23
|
-
"@types/node": "^25.0
|
|
24
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
25
|
-
"@typescript-eslint/parser": "^8.
|
|
23
|
+
"@types/node": "^25.1.0",
|
|
24
|
+
"@typescript-eslint/eslint-plugin": "^8.54.0",
|
|
25
|
+
"@typescript-eslint/parser": "^8.54.0",
|
|
26
26
|
"@vitest/coverage-v8": "^4.0.18",
|
|
27
27
|
"cross-env": "^10.1.0",
|
|
28
28
|
"eslint": "^9.39.2",
|
|
29
|
-
"eslint-plugin-jsdoc": "^62.
|
|
29
|
+
"eslint-plugin-jsdoc": "^62.5.0",
|
|
30
30
|
"eslint-plugin-tsdoc": "^0.5.0",
|
|
31
|
-
"globals": "^17.
|
|
31
|
+
"globals": "^17.2.0",
|
|
32
32
|
"jsdoc": "^4.0.5",
|
|
33
33
|
"read-pkg": "^10.0.0",
|
|
34
34
|
"socket.io": "^4.8.3",
|
|
35
35
|
"socket.io-client": "^4.8.3",
|
|
36
36
|
"typescript": "~5.9.3",
|
|
37
|
-
"typescript-eslint": "^8.
|
|
37
|
+
"typescript-eslint": "^8.54.0",
|
|
38
38
|
"vite": "^7.3.1",
|
|
39
39
|
"vite-node": "^5.3.0",
|
|
40
40
|
"vite-plugin-dts": "^4.5.4",
|
|
@@ -43,12 +43,12 @@
|
|
|
43
43
|
"vitest-dom": "^0.1.1"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@rljson/bs": "^0.0.
|
|
47
|
-
"@rljson/db": "^0.0.
|
|
46
|
+
"@rljson/bs": "^0.0.20",
|
|
47
|
+
"@rljson/db": "^0.0.13",
|
|
48
48
|
"@rljson/hash": "^0.0.18",
|
|
49
|
-
"@rljson/io": "^0.0.
|
|
49
|
+
"@rljson/io": "^0.0.65",
|
|
50
50
|
"@rljson/json": "^0.0.23",
|
|
51
|
-
"@rljson/rljson": "^0.0.
|
|
51
|
+
"@rljson/rljson": "^0.0.75"
|
|
52
52
|
},
|
|
53
53
|
"scripts": {
|
|
54
54
|
"build": "pnpx vite build && tsc && node scripts/copy-readme-to-dist.js",
|