@rljson/server 0.0.3

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Rljson
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,9 @@
1
+ <!--
2
+ @license
3
+ Copyright (c) 2025 Rljson
4
+
5
+ Use of this source code is governed by terms that can be
6
+ found in the LICENSE file in the root of this package.
7
+ -->
8
+
9
+ # Architecture
package/README.blog.md ADDED
@@ -0,0 +1,11 @@
1
+ <!--
2
+ @license
3
+ Copyright (c) 2025 Rljson
4
+
5
+ Use of this source code is governed by terms that can be
6
+ found in the LICENSE file in the root of this package.
7
+ -->
8
+
9
+ # Blog
10
+
11
+ Add latest posts at the end.
@@ -0,0 +1,32 @@
1
+ <!--
2
+ @license
3
+ Copyright (c) 2025 Rljson
4
+
5
+ Use of this source code is governed by terms that can be
6
+ found in the LICENSE file in the root of this package.
7
+ -->
8
+
9
+ # Contributors Guide
10
+
11
+ - [Prepare](#prepare)
12
+ - [Develop](#develop)
13
+ - [Administrate](#administrate)
14
+ - [Fast Coding](#fast-coding)
15
+
16
+ ## Prepare
17
+
18
+ Read [prepare.md](doc/prepare.md)
19
+
20
+ <!-- ........................................................................-->
21
+
22
+ ## Develop
23
+
24
+ Read [develop.md](doc/develop.md)
25
+
26
+ ## Administrate
27
+
28
+ Read [create-new-repo.md](doc/create-new-repo.md)
29
+
30
+ ## Fast Coding
31
+
32
+ Read [fast-coding-guide.md](doc/fast-coding-guide.md)
package/README.md ADDED
@@ -0,0 +1,24 @@
1
+ <!--
2
+ @license
3
+ Copyright (c) 2025 Rljson
4
+
5
+ Use of this source code is governed by terms that can be
6
+ found in the LICENSE file in the root of this package.
7
+ -->
8
+
9
+ # @rljson/server
10
+
11
+ ## Users
12
+
13
+ | File | Purpose |
14
+ | ------------------------------------ | --------------------------- |
15
+ | [README.public.md](README.public.md) | Install and use the package |
16
+
17
+ ## Contributors
18
+
19
+ | File | Purpose |
20
+ | ------------------------------------------------ | ----------------------------- |
21
+ | [README.contributors.md](README.contributors.md) | Run, debug, build and publish |
22
+ | [README.architecture.md](README.architecture.md) | Software architecture guide |
23
+ | [README.trouble.md](README.trouble.md) | Errors & solutions |
24
+ | [README.blog.md](README.blog.md) | Blog |
@@ -0,0 +1,129 @@
1
+ <!--
2
+ @license
3
+ Copyright (c) 2025 Rljson
4
+
5
+ Use of this source code is governed by terms that can be
6
+ found in the LICENSE file in the root of this package.
7
+ -->
8
+
9
+ # @rljson/server
10
+
11
+ @rljson/server provides a lightweight client/server layer for Rljson storage. It wires Io (row/table data) and Bs (blob storage) over sockets so clients can read from server storage while still keeping their own local storage.
12
+
13
+ ## What it does (quick overview)
14
+
15
+ - **Server** hosts Io + Bs and exposes them over sockets.
16
+ - **Client** combines local Io/Bs with server Io/Bs into unified interfaces.
17
+ - **Sockets** are provided by your runtime (e.g., Socket.IO) and wrapped by `SocketIoBridge`.
18
+
19
+ ## Install
20
+
21
+ ```sh
22
+ pnpm add @rljson/server
23
+ ```
24
+
25
+ ## Basic usage
26
+
27
+ ### Server
28
+
29
+ ```ts
30
+ import { BsMem } from '@rljson/bs';
31
+ import { IoMem } from '@rljson/io';
32
+ import { Route } from '@rljson/rljson';
33
+
34
+ import { Server } from '@rljson/server';
35
+
36
+ const route = Route.fromFlat('my.app.route');
37
+ const serverIo = new IoMem();
38
+ await serverIo.init();
39
+ await serverIo.isReady();
40
+
41
+ const serverBs = new BsMem();
42
+ const server = new Server(route, serverIo, serverBs);
43
+ await server.init();
44
+
45
+ // When a socket connects:
46
+ // await server.addSocket(new SocketIoBridge(serverSocket));
47
+ ```
48
+
49
+ ### Client
50
+
51
+ ```ts
52
+ import { BsMem } from '@rljson/bs';
53
+ import { IoMem } from '@rljson/io';
54
+
55
+ import { Client } from '@rljson/server';
56
+
57
+ const localIo = new IoMem();
58
+ await localIo.init();
59
+ await localIo.isReady();
60
+
61
+ const localBs = new BsMem();
62
+
63
+ const client = new Client(new SocketIoBridge(clientSocket), localIo, localBs);
64
+ await client.init();
65
+
66
+ // Unified interfaces
67
+ const io = client.io;
68
+ const bs = client.bs;
69
+ ```
70
+
71
+ ## How the layering works
72
+
73
+ Both client and server use a **multi-layer** approach:
74
+
75
+ - **Local layer** (priority 1): always read/write to local Io/Bs
76
+ - **Peer layer** (priority 2): read-only from server Io/Bs
77
+
78
+ This is implemented with `IoMulti` and `BsMulti` internally, but the public API exposes them as `Io` and `Bs`.
79
+
80
+ ## API highlights
81
+
82
+ ### Client
83
+
84
+ - `init()` – builds Io/Bs multis and starts peer bridges
85
+ - `ready()` – resolves once Io is ready
86
+ - `tearDown()` – closes and clears local state
87
+ - `io` – Io interface (multi-layer)
88
+ - `bs` – Bs interface (multi-layer)
89
+
90
+ ### Server
91
+
92
+ - `init()` – initializes server multis
93
+ - `ready()` – resolves when Io is ready
94
+ - `addSocket(socket)` – registers a client socket and refreshes multis
95
+ - `io` – Io interface used by server
96
+ - `bs` – Bs interface used by server
97
+
98
+ ## Example
99
+
100
+ [src/example.ts](src/example.ts)
101
+
102
+ ## Deeper dive
103
+
104
+ ### Networking flow
105
+
106
+ 1. **Client connects** using your socket runtime.
107
+ 2. **Server registers** the socket with `addSocket()`.
108
+ 3. **IoPeerBridge** allows the server to pull from client local Io (upstream).
109
+ 4. **IoPeer** allows the client to pull from server Io (downstream).
110
+ 5. `IoMulti` merges these layers into a single Io interface.
111
+
112
+ The same pattern is used for Bs (blob storage).
113
+
114
+ ### Consistency model
115
+
116
+ - Local writes are immediate.
117
+ - Server data is read-only from the client perspective.
118
+ - Multi-layer priority ensures local data always wins.
119
+
120
+ ### When to use this package
121
+
122
+ - You want **local-first** data access with server-backed reads.
123
+ - You want **Io and Bs** to share a consistent socket layer.
124
+ - You want a single abstraction for both **in-memory** and **networked** access.
125
+
126
+ ## Notes
127
+
128
+ - `Client.io` and `Client.bs` are already merged interfaces. No need to access multis directly.
129
+ - `Server.addSocket()` batches refreshes to reduce rebuild overhead when multiple sockets connect.
@@ -0,0 +1,23 @@
1
+ <!--
2
+ @license
3
+ Copyright (c) 2025 Rljson
4
+
5
+ Use of this source code is governed by terms that can be
6
+ found in the LICENSE file in the root of this package.
7
+ -->
8
+
9
+ # Trouble shooting
10
+
11
+ ## Table of contents <!-- omit in toc -->
12
+
13
+ - [Vscode Windows: Debugging is not working](#vscode-windows-debugging-is-not-working)
14
+
15
+ ## Vscode Windows: Debugging is not working
16
+
17
+ Date: 2025-03-08
18
+
19
+ ⚠️ IMPORTANT: On Windows, please check out the repo on drive C. There is a bug
20
+ in the VS Code Vitest extension (v1.14.4), which prevents test debugging from
21
+ working: <https://github.com/vitest-dev/vscode/issues/548> Please check from
22
+ time to time if the issue has been fixed and remove this note once it is
23
+ resolved.
@@ -0,0 +1,9 @@
1
+ <!--
2
+ @license
3
+ Copyright (c) 2025 Rljson
4
+
5
+ Use of this source code is governed by terms that can be
6
+ found in the LICENSE file in the root of this package.
7
+ -->
8
+
9
+ # Architecture
@@ -0,0 +1,11 @@
1
+ <!--
2
+ @license
3
+ Copyright (c) 2025 Rljson
4
+
5
+ Use of this source code is governed by terms that can be
6
+ found in the LICENSE file in the root of this package.
7
+ -->
8
+
9
+ # Blog
10
+
11
+ Add latest posts at the end.
@@ -0,0 +1,32 @@
1
+ <!--
2
+ @license
3
+ Copyright (c) 2025 Rljson
4
+
5
+ Use of this source code is governed by terms that can be
6
+ found in the LICENSE file in the root of this package.
7
+ -->
8
+
9
+ # Contributors Guide
10
+
11
+ - [Prepare](#prepare)
12
+ - [Develop](#develop)
13
+ - [Administrate](#administrate)
14
+ - [Fast Coding](#fast-coding)
15
+
16
+ ## Prepare
17
+
18
+ Read [prepare.md](doc/prepare.md)
19
+
20
+ <!-- ........................................................................-->
21
+
22
+ ## Develop
23
+
24
+ Read [develop.md](doc/develop.md)
25
+
26
+ ## Administrate
27
+
28
+ Read [create-new-repo.md](doc/create-new-repo.md)
29
+
30
+ ## Fast Coding
31
+
32
+ Read [fast-coding-guide.md](doc/fast-coding-guide.md)
package/dist/README.md ADDED
@@ -0,0 +1,24 @@
1
+ <!--
2
+ @license
3
+ Copyright (c) 2025 Rljson
4
+
5
+ Use of this source code is governed by terms that can be
6
+ found in the LICENSE file in the root of this package.
7
+ -->
8
+
9
+ # @rljson/server
10
+
11
+ ## Users
12
+
13
+ | File | Purpose |
14
+ | ------------------------------------ | --------------------------- |
15
+ | [README.public.md](README.public.md) | Install and use the package |
16
+
17
+ ## Contributors
18
+
19
+ | File | Purpose |
20
+ | ------------------------------------------------ | ----------------------------- |
21
+ | [README.contributors.md](README.contributors.md) | Run, debug, build and publish |
22
+ | [README.architecture.md](README.architecture.md) | Software architecture guide |
23
+ | [README.trouble.md](README.trouble.md) | Errors & solutions |
24
+ | [README.blog.md](README.blog.md) | Blog |
@@ -0,0 +1,129 @@
1
+ <!--
2
+ @license
3
+ Copyright (c) 2025 Rljson
4
+
5
+ Use of this source code is governed by terms that can be
6
+ found in the LICENSE file in the root of this package.
7
+ -->
8
+
9
+ # @rljson/server
10
+
11
+ @rljson/server provides a lightweight client/server layer for Rljson storage. It wires Io (row/table data) and Bs (blob storage) over sockets so clients can read from server storage while still keeping their own local storage.
12
+
13
+ ## What it does (quick overview)
14
+
15
+ - **Server** hosts Io + Bs and exposes them over sockets.
16
+ - **Client** combines local Io/Bs with server Io/Bs into unified interfaces.
17
+ - **Sockets** are provided by your runtime (e.g., Socket.IO) and wrapped by `SocketIoBridge`.
18
+
19
+ ## Install
20
+
21
+ ```sh
22
+ pnpm add @rljson/server
23
+ ```
24
+
25
+ ## Basic usage
26
+
27
+ ### Server
28
+
29
+ ```ts
30
+ import { BsMem } from '@rljson/bs';
31
+ import { IoMem } from '@rljson/io';
32
+ import { Route } from '@rljson/rljson';
33
+
34
+ import { Server } from '@rljson/server';
35
+
36
+ const route = Route.fromFlat('my.app.route');
37
+ const serverIo = new IoMem();
38
+ await serverIo.init();
39
+ await serverIo.isReady();
40
+
41
+ const serverBs = new BsMem();
42
+ const server = new Server(route, serverIo, serverBs);
43
+ await server.init();
44
+
45
+ // When a socket connects:
46
+ // await server.addSocket(new SocketIoBridge(serverSocket));
47
+ ```
48
+
49
+ ### Client
50
+
51
+ ```ts
52
+ import { BsMem } from '@rljson/bs';
53
+ import { IoMem } from '@rljson/io';
54
+
55
+ import { Client } from '@rljson/server';
56
+
57
+ const localIo = new IoMem();
58
+ await localIo.init();
59
+ await localIo.isReady();
60
+
61
+ const localBs = new BsMem();
62
+
63
+ const client = new Client(new SocketIoBridge(clientSocket), localIo, localBs);
64
+ await client.init();
65
+
66
+ // Unified interfaces
67
+ const io = client.io;
68
+ const bs = client.bs;
69
+ ```
70
+
71
+ ## How the layering works
72
+
73
+ Both client and server use a **multi-layer** approach:
74
+
75
+ - **Local layer** (priority 1): always read/write to local Io/Bs
76
+ - **Peer layer** (priority 2): read-only from server Io/Bs
77
+
78
+ This is implemented with `IoMulti` and `BsMulti` internally, but the public API exposes them as `Io` and `Bs`.
79
+
80
+ ## API highlights
81
+
82
+ ### Client
83
+
84
+ - `init()` – builds Io/Bs multis and starts peer bridges
85
+ - `ready()` – resolves once Io is ready
86
+ - `tearDown()` – closes and clears local state
87
+ - `io` – Io interface (multi-layer)
88
+ - `bs` – Bs interface (multi-layer)
89
+
90
+ ### Server
91
+
92
+ - `init()` – initializes server multis
93
+ - `ready()` – resolves when Io is ready
94
+ - `addSocket(socket)` – registers a client socket and refreshes multis
95
+ - `io` – Io interface used by server
96
+ - `bs` – Bs interface used by server
97
+
98
+ ## Example
99
+
100
+ [src/example.ts](src/example.ts)
101
+
102
+ ## Deeper dive
103
+
104
+ ### Networking flow
105
+
106
+ 1. **Client connects** using your socket runtime.
107
+ 2. **Server registers** the socket with `addSocket()`.
108
+ 3. **IoPeerBridge** allows the server to pull from client local Io (upstream).
109
+ 4. **IoPeer** allows the client to pull from server Io (downstream).
110
+ 5. `IoMulti` merges these layers into a single Io interface.
111
+
112
+ The same pattern is used for Bs (blob storage).
113
+
114
+ ### Consistency model
115
+
116
+ - Local writes are immediate.
117
+ - Server data is read-only from the client perspective.
118
+ - Multi-layer priority ensures local data always wins.
119
+
120
+ ### When to use this package
121
+
122
+ - You want **local-first** data access with server-backed reads.
123
+ - You want **Io and Bs** to share a consistent socket layer.
124
+ - You want a single abstraction for both **in-memory** and **networked** access.
125
+
126
+ ## Notes
127
+
128
+ - `Client.io` and `Client.bs` are already merged interfaces. No need to access multis directly.
129
+ - `Server.addSocket()` batches refreshes to reduce rebuild overhead when multiple sockets connect.
@@ -0,0 +1,23 @@
1
+ <!--
2
+ @license
3
+ Copyright (c) 2025 Rljson
4
+
5
+ Use of this source code is governed by terms that can be
6
+ found in the LICENSE file in the root of this package.
7
+ -->
8
+
9
+ # Trouble shooting
10
+
11
+ ## Table of contents <!-- omit in toc -->
12
+
13
+ - [Vscode Windows: Debugging is not working](#vscode-windows-debugging-is-not-working)
14
+
15
+ ## Vscode Windows: Debugging is not working
16
+
17
+ Date: 2025-03-08
18
+
19
+ ⚠️ IMPORTANT: On Windows, please check out the repo on drive C. There is a bug
20
+ in the VS Code Vitest extension (v1.14.4), which prevents test debugging from
21
+ working: <https://github.com/vitest-dev/vscode/issues/548> Please check from
22
+ time to time if the issue has been fixed and remove this note once it is
23
+ resolved.
@@ -0,0 +1,22 @@
1
+ import { Io } from '@rljson/io';
2
+ import { Rljson, TableCfg } from '@rljson/rljson';
3
+ export declare abstract class BaseNode {
4
+ protected _localIo: Io;
5
+ private _localDb;
6
+ constructor(_localIo: Io);
7
+ /**
8
+ * Creates tables in the local Db.
9
+ * @param cfgs - Table configurations
10
+ * @param cfgs.withInsertHistory - TableCfgs for tables with InsertHistory
11
+ * @param cfgs.withoutInsertHistory - TableCfgs for tables without InsertHistory
12
+ */
13
+ createTables(cfgs: {
14
+ withInsertHistory?: TableCfg[];
15
+ withoutInsertHistory?: TableCfg[];
16
+ }): Promise<void>;
17
+ /**
18
+ * Imports Rljson data into the local Db.
19
+ * @param data - Rljson data to import
20
+ */
21
+ import(data: Rljson): Promise<void>;
22
+ }
@@ -0,0 +1,56 @@
1
+ import { Bs } from '@rljson/bs';
2
+ import { Io, IoMulti, Socket } from '@rljson/io';
3
+ import { BaseNode } from './base-node.ts';
4
+ export declare class Client extends BaseNode {
5
+ private _socketToServer;
6
+ protected _localIo: Io;
7
+ protected _localBs: Bs;
8
+ private _ioMultiIos;
9
+ private _ioMulti?;
10
+ private _bsMultiBss;
11
+ private _bsMulti?;
12
+ /**
13
+ * Creates a Client instance
14
+ * @param _socketToServer - Socket to connect to server
15
+ * @param _localIo - Local Io for local storage
16
+ * @param _localBs - Local Bs for local blob storage
17
+ */
18
+ constructor(_socketToServer: Socket, _localIo: Io, _localBs: Bs);
19
+ /**
20
+ * Initializes Io and Bs multis and their peer bridges.
21
+ * @returns The initialized Io implementation.
22
+ */
23
+ init(): Promise<IoMulti | undefined>;
24
+ /**
25
+ * Resolves once the Io implementation is ready.
26
+ */
27
+ ready(): Promise<void>;
28
+ /**
29
+ * Closes client resources and clears internal state.
30
+ */
31
+ tearDown(): Promise<void>;
32
+ /**
33
+ * Returns the Io implementation.
34
+ */
35
+ get io(): Io | undefined;
36
+ /**
37
+ * Returns the Bs implementation.
38
+ */
39
+ get bs(): Bs | undefined;
40
+ /**
41
+ * Builds the Io multi with local and peer layers.
42
+ */
43
+ private _setupIo;
44
+ /**
45
+ * Builds the Bs multi with local and peer layers.
46
+ */
47
+ private _setupBs;
48
+ /**
49
+ * Creates and initializes a downstream Io peer.
50
+ */
51
+ private _createIoPeer;
52
+ /**
53
+ * Creates and initializes a downstream Bs peer.
54
+ */
55
+ private _createBsPeer;
56
+ }
@@ -0,0 +1 @@
1
+ export declare const example: () => Promise<void>;
@@ -0,0 +1,3 @@
1
+ export { Client } from './client.ts';
2
+ export { Server } from './server.ts';
3
+ export { SocketIoBridge } from './socket-io-bridge.ts';
@@ -0,0 +1,104 @@
1
+ import { Bs, BsPeer } from '@rljson/bs';
2
+ import { Io, IoPeer, Socket } from '@rljson/io';
3
+ import { Route } from '@rljson/rljson';
4
+ import { BaseNode } from './base-node.ts';
5
+ export type SocketWithClientId = Socket & {
6
+ __clientId?: string;
7
+ };
8
+ export declare class Server extends BaseNode {
9
+ private _route;
10
+ protected _localIo: Io;
11
+ protected _localBs: Bs;
12
+ private _clients;
13
+ private _ios;
14
+ private _ioMulti;
15
+ private _ioServer;
16
+ private _bss;
17
+ private _bsMulti;
18
+ private _bsServer;
19
+ private _multicastedRefs;
20
+ private _refreshPromise?;
21
+ private _pendingSockets;
22
+ constructor(_route: Route, _localIo: Io, _localBs: Bs);
23
+ /**
24
+ * Initializes Io and Bs multis on the server.
25
+ */
26
+ init(): Promise<void>;
27
+ /**
28
+ * Resolves once the Io implementation is ready.
29
+ */
30
+ ready(): Promise<void>;
31
+ /**
32
+ * Adds a client socket, rebuilds multis, and refreshes servers.
33
+ * @param socket - Client socket to register.
34
+ * @returns The server instance.
35
+ */
36
+ addSocket(socket: Socket): Promise<this>;
37
+ /**
38
+ * Removes all listeners from all connected clients.
39
+ */
40
+ private _removeAllListeners;
41
+ /**
42
+ * Broadcasts incoming payloads from any client to all other connected clients.
43
+ */
44
+ private _multicastRefs;
45
+ get route(): Route;
46
+ /**
47
+ * Returns the Io implementation.
48
+ */
49
+ get io(): Io;
50
+ /**
51
+ * Returns the Bs implementation.
52
+ */
53
+ get bs(): Bs;
54
+ /**
55
+ * Returns the connected clients map.
56
+ */
57
+ get clients(): Map<string, {
58
+ socket: SocketWithClientId;
59
+ io: IoPeer;
60
+ bs: BsPeer;
61
+ }>;
62
+ /**
63
+ * Creates and initializes a downstream Io peer for a socket.
64
+ * @param socket - Client socket to bind the peer to.
65
+ */
66
+ private _createIoPeer;
67
+ /**
68
+ * Creates and initializes a downstream Bs peer for a socket.
69
+ * @param socket - Client socket to bind the peer to.
70
+ */
71
+ private _createBsPeer;
72
+ /**
73
+ * Registers the client socket and peers.
74
+ * @param clientId - Stable client identifier.
75
+ * @param socket - Client socket to register.
76
+ * @param io - Io peer associated with the client.
77
+ * @param bs - Bs peer associated with the client.
78
+ */
79
+ private _registerClient;
80
+ /**
81
+ * Queues an Io peer for inclusion in the Io multi.
82
+ * @param ioPeer - Io peer to add.
83
+ */
84
+ private _queueIoPeer;
85
+ /**
86
+ * Queues a Bs peer for inclusion in the Bs multi.
87
+ * @param bsPeer - Bs peer to add.
88
+ */
89
+ private _queueBsPeer;
90
+ /**
91
+ * Rebuilds Io and Bs multis from queued peers.
92
+ */
93
+ private _rebuildMultis;
94
+ /**
95
+ * Recreates servers and reattaches sockets.
96
+ */
97
+ private _refreshServers;
98
+ /**
99
+ * Batches multi/server refreshes into a single queued task.
100
+ */
101
+ private _queueRefresh;
102
+ /** Example instance for test purposes */
103
+ static example(): Promise<Server>;
104
+ }