@utsp/runtime-server 0.1.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/LICENSE +21 -0
- package/README.md +36 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.ts +143 -0
- package/dist/index.mjs +1 -0
- package/package.json +65 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Thomas Piquet
|
|
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.
|
package/README.md
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# @utsp/runtime-server
|
|
2
|
+
|
|
3
|
+
> ⚠️ **PROTOTYPE - NOT READY FOR PRODUCTION**
|
|
4
|
+
>
|
|
5
|
+
> This package is currently in early development and should **NOT** be used in production.
|
|
6
|
+
> The API is unstable and subject to breaking changes without notice.
|
|
7
|
+
|
|
8
|
+
Server-side runtime for UTSP (Universal Text Stream Protocol) multi-user applications.
|
|
9
|
+
|
|
10
|
+
[](https://opensource.org/licenses/MIT)
|
|
11
|
+
|
|
12
|
+
## ⚠️ Development Status
|
|
13
|
+
|
|
14
|
+
**This is a prototype package under active development.**
|
|
15
|
+
|
|
16
|
+
- ❌ No stable API
|
|
17
|
+
- ❌ No documentation available yet
|
|
18
|
+
- ❌ Breaking changes expected
|
|
19
|
+
- ❌ Not recommended for production use
|
|
20
|
+
|
|
21
|
+
**Please check back later for updates or watch the repository for release announcements.**
|
|
22
|
+
|
|
23
|
+
## Installation
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install @utsp/runtime-server
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Repository
|
|
30
|
+
|
|
31
|
+
- [GitHub](https://github.com/thp-software/utsp)
|
|
32
|
+
- [Issues](https://github.com/thp-software/utsp/issues)
|
|
33
|
+
|
|
34
|
+
## License
|
|
35
|
+
|
|
36
|
+
MIT © 2025 Thomas Piquet
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var h=Object.defineProperty;var v=Object.getOwnPropertyDescriptor;var d=Object.getOwnPropertyNames;var k=Object.prototype.hasOwnProperty;var f=(n,t,e)=>t in n?h(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e;var l=(n,t)=>h(n,"name",{value:t,configurable:!0});var w=(n,t)=>{for(var e in t)h(n,e,{get:t[e],enumerable:!0})},T=(n,t,e,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of d(t))!k.call(n,s)&&s!==e&&h(n,s,{get:()=>t[s],enumerable:!(i=v(t,s))||i.enumerable});return n};var S=n=>T(h({},"__esModule",{value:!0}),n);var r=(n,t,e)=>(f(n,typeof t!="symbol"?t+"":t,e),e);var y={};w(y,{ServerRuntime:()=>p});module.exports=S(y);var u=require("@utsp/core"),g=require("@utsp/network-server");var c=class c{constructor(t){r(this,"core");r(this,"network");r(this,"options");r(this,"running",!1);r(this,"startTime",0);r(this,"lastTimestamp",0);r(this,"tickCount",0);r(this,"tps",0);r(this,"tpsUpdateTime",0);r(this,"tickInterval",null);this.options={application:t.application,port:t.port,host:t.host??"0.0.0.0",tickRate:t.tickRate??20,maxConnections:t.maxConnections??100,debug:t.debug??!1,width:t.width??80,height:t.height??25,cors:t.cors??{origin:"*"}},this.log("Initializing ServerRuntime..."),this.core=new u.Core({mode:"server",maxUsers:this.options.maxConnections}),this.network=new g.SocketIOServer({port:this.options.port,host:this.options.host,cors:this.options.cors,maxConnections:this.options.maxConnections,debug:this.options.debug}),this.log("ServerRuntime initialized")}getMode(){return"server"}isRunning(){return this.running}setTickRate(t){if(t<=0||t>1e3)throw new Error(`Invalid tick rate: ${t}. Must be between 1 and 1000.`);if(this.options.tickRate=t,this.log(`Tick rate changed to ${t} TPS`),this.running&&this.tickInterval){clearInterval(this.tickInterval);let e=1e3/t;this.log(`Restarting tick loop at ${t} TPS (${e}ms)...`),this.tickInterval=setInterval(()=>{this.tick()},e)}}getTickRate(){return this.options.tickRate}async start(){if(this.running){this.log("Already running");return}this.log("Starting ServerRuntime..."),await this.network.start(),this.log(`Server listening on ${this.options.host}:${this.options.port}`),this.setupNetworkHandlers(),this.log("Calling application.init()..."),this.options.application.init(this.core,this),this.running=!0,this.startTime=Date.now(),this.lastTimestamp=this.startTime,this.tpsUpdateTime=this.startTime;let t=1e3/this.options.tickRate;this.log(`Starting tick loop at ${this.options.tickRate} TPS (${t}ms)...`),this.tickInterval=setInterval(()=>{this.tick()},t)}async stop(){if(!this.running)return;this.log("Stopping ServerRuntime..."),this.running=!1,this.tickInterval&&(clearInterval(this.tickInterval),this.tickInterval=null),this.network.getClients().forEach(e=>{this.network.disconnectClient(e,"Server stopped")}),await this.network.stop(),this.log("ServerRuntime stopped")}getStats(){return{mode:"server",running:this.running,userCount:this.core.getUsers().length,tps:this.tps,uptime:this.running?Date.now()-this.startTime:0,totalTicks:this.tickCount}}async destroy(){await this.stop(),this.log("Destroying ServerRuntime..."),this.options.application.destroy&&this.options.application.destroy(),await this.network.destroy(),this.log("ServerRuntime destroyed")}setupNetworkHandlers(){this.network.onConnect(t=>{this.log(`Client connected: ${t}`)}),this.network.onDisconnect((t,e)=>{this.log(`Client disconnected: ${t} (${e})`);let i=this.core.getUser(t);i&&(this.options.application.destroyUser&&this.options.application.destroyUser(this.core,i,e),this.core.removeUser(t))}),this.network.on("join",(t,e)=>{this.log(`Join request from ${t}: ${e.username}`);try{let i=e.username||`Player${t.substring(0,4)}`,s=this.core.createUser(t,i);this.options.application.initUser(this.core,s,{username:i,token:e.token}),this.network.sendToClient(t,"join_response",{success:!0,userId:t,roomId:"main"});let o=this.core.generateAllLoadPackets();this.log(`Sending ${o.length} load packets to ${t}...`),o.forEach(m=>{this.network.sendToClient(t,"load",m)});let a=s.getInputBindingsLoadPacket();a&&(this.network.sendToClient(t,"input-bindings",a),this.log(`Sent input bindings to ${t}`)),this.log(`User ${i} (${t}) joined`)}catch(i){this.log(`Failed to join: ${i}`),this.network.sendToClient(t,"join_response",{success:!1,error:"Failed to join game"})}}),this.network.on("leave",t=>{this.log(`Leave request from ${t}`),this.network.disconnectClient(t,"User left")}),this.network.on("input",(t,e)=>{let i=this.core.getUser(t);if(!i){this.log(`Input from unknown user: ${t}`);return}if(e.axes&&Object.entries(e.axes).forEach(([s,o])=>{i.setAxis(s,o)}),e.buttons&&Object.entries(e.buttons).forEach(([s,o])=>{i.setButton(s,o)}),e.mousePosition){let{x:s,y:o}=e.mousePosition;i.setMousePosition(s,o,!0)}e.textInputs&&Array.isArray(e.textInputs)&&i.setTextInputs(e.textInputs)})}tick(){if(!this.running)return;let t=Date.now(),e=(t-this.lastTimestamp)/1e3;this.lastTimestamp=t,this.tickCount++,t-this.tpsUpdateTime>=1e3&&(this.tps=Math.round(this.tickCount*1e3/(t-this.tpsUpdateTime)),this.tickCount=0,this.tpsUpdateTime=t),this.options.application.update&&this.options.application.update(this.core,e),this.core.getUsers().forEach(s=>{this.options.application.updateUser(this.core,s,e),s.clearTextInputs()}),this.core.endTick(),this.broadcastUpdates()}broadcastUpdates(){let t=this.core.endTickSplit(),e=this.core.getCurrentTick();t.forEach(({static:i,dynamic:s},o)=>{if(i&&(this.network.sendToClient(o,"update-static",i),console.warn(`[SERVER] update-static: ${i.length}B (tick ${e})`)),s){let a=this.network;a.sendToClientVolatile?a.sendToClientVolatile(o,"update-dynamic",s):this.network.sendToClient(o,"update-dynamic",s),console.warn(`[SERVER] update-dynamic: ${s.length}B (tick ${e})`)}})}log(t){this.options.debug&&console.warn(`[ServerRuntime] ${t}`)}};l(c,"ServerRuntime");var p=c;0&&(module.exports={ServerRuntime});
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
export { IApplication } from '@utsp/types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Server Runtime Options
|
|
5
|
+
*/
|
|
6
|
+
interface ServerRuntimeOptions {
|
|
7
|
+
/**
|
|
8
|
+
* The application implementation
|
|
9
|
+
*/
|
|
10
|
+
application: any;
|
|
11
|
+
/**
|
|
12
|
+
* Server port
|
|
13
|
+
*/
|
|
14
|
+
port: number;
|
|
15
|
+
/**
|
|
16
|
+
* Server host
|
|
17
|
+
* @default '0.0.0.0'
|
|
18
|
+
*/
|
|
19
|
+
host?: string;
|
|
20
|
+
/**
|
|
21
|
+
* Server tick rate (updates per second)
|
|
22
|
+
* @default 60
|
|
23
|
+
*/
|
|
24
|
+
tickRate?: number;
|
|
25
|
+
/**
|
|
26
|
+
* Maximum concurrent connections
|
|
27
|
+
* @default 100
|
|
28
|
+
*/
|
|
29
|
+
maxConnections?: number;
|
|
30
|
+
/**
|
|
31
|
+
* Terminal width (columns)
|
|
32
|
+
* @default 80
|
|
33
|
+
*/
|
|
34
|
+
width?: number;
|
|
35
|
+
/**
|
|
36
|
+
* Terminal height (rows)
|
|
37
|
+
* @default 25
|
|
38
|
+
*/
|
|
39
|
+
height?: number;
|
|
40
|
+
/**
|
|
41
|
+
* CORS configuration
|
|
42
|
+
* @default { origin: '*' }
|
|
43
|
+
*/
|
|
44
|
+
cors?: {
|
|
45
|
+
origin: string | string[];
|
|
46
|
+
credentials?: boolean;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Enable debug logging
|
|
50
|
+
* @default false
|
|
51
|
+
*/
|
|
52
|
+
debug?: boolean;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Server Runtime Statistics
|
|
56
|
+
*/
|
|
57
|
+
interface ServerRuntimeStats {
|
|
58
|
+
/** Runtime mode */
|
|
59
|
+
mode: 'server';
|
|
60
|
+
/** Whether the runtime is running */
|
|
61
|
+
running: boolean;
|
|
62
|
+
/** Number of connected users */
|
|
63
|
+
userCount: number;
|
|
64
|
+
/** Current tick rate (TPS) */
|
|
65
|
+
tps: number;
|
|
66
|
+
/** Uptime in milliseconds */
|
|
67
|
+
uptime: number;
|
|
68
|
+
/** Total ticks processed */
|
|
69
|
+
totalTicks: number;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Server Runtime
|
|
74
|
+
*
|
|
75
|
+
* Headless mode - runs server without rendering.
|
|
76
|
+
* Uses: Core + Network (SocketIOServer)
|
|
77
|
+
* No Render, no Input (receives input from clients)
|
|
78
|
+
*
|
|
79
|
+
* Perfect for:
|
|
80
|
+
* - Multiplayer game servers
|
|
81
|
+
* - Authoritative game logic
|
|
82
|
+
* - Scalable backend
|
|
83
|
+
*/
|
|
84
|
+
|
|
85
|
+
declare class ServerRuntime {
|
|
86
|
+
private core;
|
|
87
|
+
private network;
|
|
88
|
+
private options;
|
|
89
|
+
private running;
|
|
90
|
+
private startTime;
|
|
91
|
+
private lastTimestamp;
|
|
92
|
+
private tickCount;
|
|
93
|
+
private tps;
|
|
94
|
+
private tpsUpdateTime;
|
|
95
|
+
private tickInterval;
|
|
96
|
+
constructor(options: ServerRuntimeOptions);
|
|
97
|
+
getMode(): 'server';
|
|
98
|
+
isRunning(): boolean;
|
|
99
|
+
/**
|
|
100
|
+
* Change le tick rate du serveur (peut être appelé à tout moment)
|
|
101
|
+
* Redémarre l'interval avec la nouvelle fréquence
|
|
102
|
+
*
|
|
103
|
+
* @param tickRate - Nouveau tick rate en TPS (ticks per second)
|
|
104
|
+
* @example
|
|
105
|
+
* ```typescript
|
|
106
|
+
* // Dans init() de votre application :
|
|
107
|
+
* init(core: UTSPCore, runtime: ServerRuntime): void {
|
|
108
|
+
* runtime.setTickRate(60); // Passer à 60 TPS
|
|
109
|
+
* }
|
|
110
|
+
* ```
|
|
111
|
+
*/
|
|
112
|
+
setTickRate(tickRate: number): void;
|
|
113
|
+
/**
|
|
114
|
+
* Récupère le tick rate actuel
|
|
115
|
+
*/
|
|
116
|
+
getTickRate(): number;
|
|
117
|
+
start(): Promise<void>;
|
|
118
|
+
stop(): Promise<void>;
|
|
119
|
+
getStats(): ServerRuntimeStats;
|
|
120
|
+
destroy(): Promise<void>;
|
|
121
|
+
/**
|
|
122
|
+
* Setup network event handlers
|
|
123
|
+
*/
|
|
124
|
+
private setupNetworkHandlers;
|
|
125
|
+
/**
|
|
126
|
+
* Main tick loop
|
|
127
|
+
*/
|
|
128
|
+
private tick;
|
|
129
|
+
/**
|
|
130
|
+
* Broadcast updates to all connected clients
|
|
131
|
+
* Uses split packets:
|
|
132
|
+
* - Static layers → Reliable channel (guaranteed delivery)
|
|
133
|
+
* - Dynamic layers → Volatile channel (can drop packets for performance)
|
|
134
|
+
*/
|
|
135
|
+
private broadcastUpdates;
|
|
136
|
+
/**
|
|
137
|
+
* Debug logging
|
|
138
|
+
*/
|
|
139
|
+
private log;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export { ServerRuntime };
|
|
143
|
+
export type { ServerRuntimeOptions, ServerRuntimeStats };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var c=Object.defineProperty;var g=(r,t,e)=>t in r?c(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e;var l=(r,t)=>c(r,"name",{value:t,configurable:!0});var o=(r,t,e)=>(g(r,typeof t!="symbol"?t+"":t,e),e);import{Core as m}from"@utsp/core";import{SocketIOServer as v}from"@utsp/network-server";var p=class p{constructor(t){o(this,"core");o(this,"network");o(this,"options");o(this,"running",!1);o(this,"startTime",0);o(this,"lastTimestamp",0);o(this,"tickCount",0);o(this,"tps",0);o(this,"tpsUpdateTime",0);o(this,"tickInterval",null);this.options={application:t.application,port:t.port,host:t.host??"0.0.0.0",tickRate:t.tickRate??20,maxConnections:t.maxConnections??100,debug:t.debug??!1,width:t.width??80,height:t.height??25,cors:t.cors??{origin:"*"}},this.log("Initializing ServerRuntime..."),this.core=new m({mode:"server",maxUsers:this.options.maxConnections}),this.network=new v({port:this.options.port,host:this.options.host,cors:this.options.cors,maxConnections:this.options.maxConnections,debug:this.options.debug}),this.log("ServerRuntime initialized")}getMode(){return"server"}isRunning(){return this.running}setTickRate(t){if(t<=0||t>1e3)throw new Error(`Invalid tick rate: ${t}. Must be between 1 and 1000.`);if(this.options.tickRate=t,this.log(`Tick rate changed to ${t} TPS`),this.running&&this.tickInterval){clearInterval(this.tickInterval);let e=1e3/t;this.log(`Restarting tick loop at ${t} TPS (${e}ms)...`),this.tickInterval=setInterval(()=>{this.tick()},e)}}getTickRate(){return this.options.tickRate}async start(){if(this.running){this.log("Already running");return}this.log("Starting ServerRuntime..."),await this.network.start(),this.log(`Server listening on ${this.options.host}:${this.options.port}`),this.setupNetworkHandlers(),this.log("Calling application.init()..."),this.options.application.init(this.core,this),this.running=!0,this.startTime=Date.now(),this.lastTimestamp=this.startTime,this.tpsUpdateTime=this.startTime;let t=1e3/this.options.tickRate;this.log(`Starting tick loop at ${this.options.tickRate} TPS (${t}ms)...`),this.tickInterval=setInterval(()=>{this.tick()},t)}async stop(){if(!this.running)return;this.log("Stopping ServerRuntime..."),this.running=!1,this.tickInterval&&(clearInterval(this.tickInterval),this.tickInterval=null),this.network.getClients().forEach(e=>{this.network.disconnectClient(e,"Server stopped")}),await this.network.stop(),this.log("ServerRuntime stopped")}getStats(){return{mode:"server",running:this.running,userCount:this.core.getUsers().length,tps:this.tps,uptime:this.running?Date.now()-this.startTime:0,totalTicks:this.tickCount}}async destroy(){await this.stop(),this.log("Destroying ServerRuntime..."),this.options.application.destroy&&this.options.application.destroy(),await this.network.destroy(),this.log("ServerRuntime destroyed")}setupNetworkHandlers(){this.network.onConnect(t=>{this.log(`Client connected: ${t}`)}),this.network.onDisconnect((t,e)=>{this.log(`Client disconnected: ${t} (${e})`);let i=this.core.getUser(t);i&&(this.options.application.destroyUser&&this.options.application.destroyUser(this.core,i,e),this.core.removeUser(t))}),this.network.on("join",(t,e)=>{this.log(`Join request from ${t}: ${e.username}`);try{let i=e.username||`Player${t.substring(0,4)}`,s=this.core.createUser(t,i);this.options.application.initUser(this.core,s,{username:i,token:e.token}),this.network.sendToClient(t,"join_response",{success:!0,userId:t,roomId:"main"});let n=this.core.generateAllLoadPackets();this.log(`Sending ${n.length} load packets to ${t}...`),n.forEach(u=>{this.network.sendToClient(t,"load",u)});let a=s.getInputBindingsLoadPacket();a&&(this.network.sendToClient(t,"input-bindings",a),this.log(`Sent input bindings to ${t}`)),this.log(`User ${i} (${t}) joined`)}catch(i){this.log(`Failed to join: ${i}`),this.network.sendToClient(t,"join_response",{success:!1,error:"Failed to join game"})}}),this.network.on("leave",t=>{this.log(`Leave request from ${t}`),this.network.disconnectClient(t,"User left")}),this.network.on("input",(t,e)=>{let i=this.core.getUser(t);if(!i){this.log(`Input from unknown user: ${t}`);return}if(e.axes&&Object.entries(e.axes).forEach(([s,n])=>{i.setAxis(s,n)}),e.buttons&&Object.entries(e.buttons).forEach(([s,n])=>{i.setButton(s,n)}),e.mousePosition){let{x:s,y:n}=e.mousePosition;i.setMousePosition(s,n,!0)}e.textInputs&&Array.isArray(e.textInputs)&&i.setTextInputs(e.textInputs)})}tick(){if(!this.running)return;let t=Date.now(),e=(t-this.lastTimestamp)/1e3;this.lastTimestamp=t,this.tickCount++,t-this.tpsUpdateTime>=1e3&&(this.tps=Math.round(this.tickCount*1e3/(t-this.tpsUpdateTime)),this.tickCount=0,this.tpsUpdateTime=t),this.options.application.update&&this.options.application.update(this.core,e),this.core.getUsers().forEach(s=>{this.options.application.updateUser(this.core,s,e),s.clearTextInputs()}),this.core.endTick(),this.broadcastUpdates()}broadcastUpdates(){let t=this.core.endTickSplit(),e=this.core.getCurrentTick();t.forEach(({static:i,dynamic:s},n)=>{if(i&&(this.network.sendToClient(n,"update-static",i),console.warn(`[SERVER] update-static: ${i.length}B (tick ${e})`)),s){let a=this.network;a.sendToClientVolatile?a.sendToClientVolatile(n,"update-dynamic",s):this.network.sendToClient(n,"update-dynamic",s),console.warn(`[SERVER] update-dynamic: ${s.length}B (tick ${e})`)}})}log(t){this.options.debug&&console.warn(`[ServerRuntime] ${t}`)}};l(p,"ServerRuntime");var h=p;export{h as ServerRuntime};
|
package/package.json
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@utsp/runtime-server",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Server-side runtime for UTSP applications (Node.js, headless)",
|
|
5
|
+
"author": "Thomas Piquet",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"main": "./dist/index.cjs",
|
|
9
|
+
"module": "./dist/index.mjs",
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"import": "./dist/index.mjs",
|
|
15
|
+
"require": "./dist/index.cjs"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "https://github.com/thp-software/utsp.git",
|
|
21
|
+
"directory": "packages/runtime-server"
|
|
22
|
+
},
|
|
23
|
+
"bugs": {
|
|
24
|
+
"url": "https://github.com/thp-software/utsp/issues"
|
|
25
|
+
},
|
|
26
|
+
"homepage": "https://github.com/thp-software/utsp/tree/master/packages/runtime-server#readme",
|
|
27
|
+
"keywords": [
|
|
28
|
+
"utsp",
|
|
29
|
+
"runtime",
|
|
30
|
+
"server",
|
|
31
|
+
"multi-user",
|
|
32
|
+
"terminal",
|
|
33
|
+
"nodejs",
|
|
34
|
+
"headless"
|
|
35
|
+
],
|
|
36
|
+
"engines": {
|
|
37
|
+
"node": ">=18.0.0"
|
|
38
|
+
},
|
|
39
|
+
"sideEffects": false,
|
|
40
|
+
"files": [
|
|
41
|
+
"dist",
|
|
42
|
+
"README.md",
|
|
43
|
+
"LICENSE"
|
|
44
|
+
],
|
|
45
|
+
"publishConfig": {
|
|
46
|
+
"access": "public"
|
|
47
|
+
},
|
|
48
|
+
"dependencies": {
|
|
49
|
+
"@utsp/core": "0.1.1",
|
|
50
|
+
"@utsp/network-server": "0.1.1",
|
|
51
|
+
"@utsp/types": "0.1.1"
|
|
52
|
+
},
|
|
53
|
+
"devDependencies": {
|
|
54
|
+
"@types/node": "^20.0.0",
|
|
55
|
+
"typescript": "^5.3.3"
|
|
56
|
+
},
|
|
57
|
+
"scripts": {
|
|
58
|
+
"build": "node ../../scripts/build-package.mjs packages/runtime-server",
|
|
59
|
+
"dev": "tsc --watch",
|
|
60
|
+
"clean": "rimraf dist",
|
|
61
|
+
"lint": "eslint \"src/**/*.ts\" --max-warnings 0",
|
|
62
|
+
"lint:fix": "eslint \"src/**/*.ts\" --fix",
|
|
63
|
+
"typecheck": "tsc --noEmit"
|
|
64
|
+
}
|
|
65
|
+
}
|