@signe/room 2.9.4 → 3.0.0
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/CHANGELOG.md +13 -0
- package/dist/chunk-EUXUH3YW.js +15 -0
- package/dist/chunk-EUXUH3YW.js.map +1 -0
- package/dist/cloudflare/index.d.ts +71 -0
- package/dist/cloudflare/index.js +320 -0
- package/dist/cloudflare/index.js.map +1 -0
- package/dist/index.d.ts +65 -188
- package/dist/index.js +742 -146
- package/dist/index.js.map +1 -1
- package/dist/node/index.d.ts +164 -0
- package/dist/node/index.js +786 -0
- package/dist/node/index.js.map +1 -0
- package/dist/party-dNs-hqkq.d.ts +175 -0
- package/examples/cloudflare/README.md +62 -0
- package/examples/cloudflare/node_modules/.bin/tsc +17 -0
- package/examples/cloudflare/node_modules/.bin/tsserver +17 -0
- package/examples/cloudflare/node_modules/.bin/wrangler +17 -0
- package/examples/cloudflare/node_modules/.bin/wrangler2 +17 -0
- package/examples/cloudflare/package.json +24 -0
- package/examples/cloudflare/public/index.html +443 -0
- package/examples/cloudflare/src/index.ts +28 -0
- package/examples/cloudflare/src/room.ts +44 -0
- package/examples/cloudflare/tsconfig.json +10 -0
- package/examples/cloudflare/wrangler.jsonc +25 -0
- package/examples/node/README.md +57 -0
- package/examples/node/node_modules/.bin/tsc +17 -0
- package/examples/node/node_modules/.bin/tsserver +17 -0
- package/examples/node/node_modules/.bin/tsx +17 -0
- package/examples/node/package.json +23 -0
- package/examples/node/public/index.html +443 -0
- package/examples/node/room.ts +44 -0
- package/examples/node/server.sqlite.ts +52 -0
- package/examples/node/server.ts +51 -0
- package/examples/node/tsconfig.json +10 -0
- package/examples/node-game/README.md +66 -0
- package/examples/node-game/package.json +23 -0
- package/examples/node-game/public/index.html +705 -0
- package/examples/node-game/room.ts +145 -0
- package/examples/node-game/server.sqlite.ts +54 -0
- package/examples/node-game/server.ts +53 -0
- package/examples/node-game/tsconfig.json +10 -0
- package/examples/node-shard/README.md +32 -0
- package/examples/node-shard/dev.ts +39 -0
- package/examples/node-shard/package.json +24 -0
- package/examples/node-shard/public/index.html +777 -0
- package/examples/node-shard/room-server.ts +68 -0
- package/examples/node-shard/room.ts +105 -0
- package/examples/node-shard/shared.ts +6 -0
- package/examples/node-shard/tsconfig.json +14 -0
- package/examples/node-shard/world-server.ts +169 -0
- package/package.json +14 -5
- package/readme.md +377 -11
- package/src/cloudflare/index.ts +474 -0
- package/src/mock.ts +29 -7
- package/src/node/index.ts +1112 -0
- package/src/server.ts +626 -90
- package/src/session.guard.ts +6 -2
- package/src/shard.ts +91 -23
- package/src/storage.ts +29 -5
- package/src/testing.ts +4 -3
- package/src/types/party.ts +4 -1
- package/src/world.guard.ts +23 -4
- package/src/world.ts +170 -79
- package/examples/game/.vscode/launch.json +0 -11
- package/examples/game/.vscode/settings.json +0 -11
- package/examples/game/README.md +0 -40
- package/examples/game/app/client.tsx +0 -15
- package/examples/game/app/components/Admin.tsx +0 -1089
- package/examples/game/app/components/Room.tsx +0 -162
- package/examples/game/app/styles.css +0 -31
- package/examples/game/package-lock.json +0 -225
- package/examples/game/package.json +0 -20
- package/examples/game/party/game.room.ts +0 -32
- package/examples/game/party/server.ts +0 -10
- package/examples/game/party/shard.ts +0 -5
- package/examples/game/partykit.json +0 -14
- package/examples/game/public/favicon.ico +0 -0
- package/examples/game/public/index.html +0 -27
- package/examples/game/public/normalize.css +0 -351
- package/examples/game/shared/room.schema.ts +0 -14
- package/examples/game/tsconfig.json +0 -109
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { createServer } from "node:http";
|
|
2
|
+
import { WebSocketServer } from "ws";
|
|
3
|
+
import { createMemoryNodeRoomStorage, createNodeRoomTransport } from "@signe/room/node";
|
|
4
|
+
import { MainServer, ShardServer } from "./room";
|
|
5
|
+
import { AUTH_JWT_SECRET, ROOM_ORIGIN, ROOM_PORT, SHARD_SECRET, WORLD_ORIGIN } from "./shared";
|
|
6
|
+
|
|
7
|
+
const storage = createMemoryNodeRoomStorage();
|
|
8
|
+
|
|
9
|
+
const transport = createNodeRoomTransport(MainServer, {
|
|
10
|
+
partiesPath: "/parties/main",
|
|
11
|
+
storage,
|
|
12
|
+
env: {
|
|
13
|
+
AUTH_JWT_SECRET,
|
|
14
|
+
SHARD_SECRET,
|
|
15
|
+
},
|
|
16
|
+
rooms: {
|
|
17
|
+
main: MainServer,
|
|
18
|
+
shard: ShardServer,
|
|
19
|
+
},
|
|
20
|
+
externalParties: {
|
|
21
|
+
world: {
|
|
22
|
+
get(worldId: string) {
|
|
23
|
+
return {
|
|
24
|
+
fetch(pathOrInit?: string | RequestInit | Request, init?: RequestInit) {
|
|
25
|
+
const path = typeof pathOrInit === "string" ? pathOrInit : "/";
|
|
26
|
+
const requestInit = typeof pathOrInit === "string" ? init : pathOrInit;
|
|
27
|
+
return fetch(`${WORLD_ORIGIN}/parties/world/${encodeURIComponent(worldId)}${normalizeStubPath(path)}`, requestInit as RequestInit);
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
const server = createServer(async (req, res) => {
|
|
36
|
+
if (req.url?.startsWith("/parties/")) {
|
|
37
|
+
await transport.handleNodeRequest(req, res);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
res.writeHead(404, { "Content-Type": "text/plain; charset=utf-8" });
|
|
42
|
+
res.end("Not Found");
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
const wsServer = new WebSocketServer({ noServer: true });
|
|
46
|
+
|
|
47
|
+
server.on("upgrade", (request, socket, head) => {
|
|
48
|
+
if (request.url?.startsWith("/parties/")) {
|
|
49
|
+
transport.handleUpgrade(wsServer, request, socket, head);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
socket.destroy();
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
server.listen(ROOM_PORT, () => {
|
|
57
|
+
console.log(`Room process: ${ROOM_ORIGIN}`);
|
|
58
|
+
console.log(`Main rooms: ${ROOM_ORIGIN}/parties/main/demo/state`);
|
|
59
|
+
console.log(`Shard rooms: ws://localhost:${ROOM_PORT}/parties/shard/{shardId}`);
|
|
60
|
+
console.log(`World origin: ${WORLD_ORIGIN}`);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
function normalizeStubPath(path: string) {
|
|
64
|
+
if (!path || path === "/") {
|
|
65
|
+
return "";
|
|
66
|
+
}
|
|
67
|
+
return path.startsWith("/") ? path : `/${path}`;
|
|
68
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { signal } from "@signe/reactive";
|
|
2
|
+
import { Action, Request, Room, Server, Shard, WorldRoom } from "@signe/room";
|
|
3
|
+
import { connected, sync, users } from "@signe/sync";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import type * as Party from "../../src/types/party";
|
|
6
|
+
|
|
7
|
+
class DemoUser {
|
|
8
|
+
@sync() name = signal("Anonymous");
|
|
9
|
+
@connected() connected = signal(false);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
@Room({ path: "{roomId}", sessionExpiryTime: 5000 })
|
|
13
|
+
class DemoRoom {
|
|
14
|
+
@sync() count = signal(0);
|
|
15
|
+
@users(DemoUser) users = signal<Record<string, DemoUser>>({});
|
|
16
|
+
|
|
17
|
+
onJoin(user: DemoUser, _conn: unknown, ctx: { request?: Request }) {
|
|
18
|
+
const url = new URL(ctx.request?.url ?? "http://localhost");
|
|
19
|
+
const name = url.searchParams.get("name")?.trim();
|
|
20
|
+
|
|
21
|
+
if (name) {
|
|
22
|
+
user.name.set(name.slice(0, 40));
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
@Action("increment", z.object({ amount: z.number().optional() }))
|
|
27
|
+
increment(_user: DemoUser, value: { amount?: number }) {
|
|
28
|
+
this.count.update((count) => count + (value.amount ?? 1));
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@Request({ path: "/state" })
|
|
32
|
+
getState() {
|
|
33
|
+
return this.snapshot();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@Request({ path: "/reset", method: "POST" })
|
|
37
|
+
reset() {
|
|
38
|
+
this.count.set(0);
|
|
39
|
+
return this.snapshot();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
private snapshot() {
|
|
43
|
+
return {
|
|
44
|
+
count: this.count(),
|
|
45
|
+
users: Object.fromEntries(
|
|
46
|
+
Object.entries(this.users()).map(([id, user]) => [
|
|
47
|
+
id,
|
|
48
|
+
{
|
|
49
|
+
name: user.name(),
|
|
50
|
+
connected: user.connected(),
|
|
51
|
+
},
|
|
52
|
+
])
|
|
53
|
+
),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
@Room({
|
|
59
|
+
path: "world-{worldId}",
|
|
60
|
+
maxUsers: 100,
|
|
61
|
+
throttleStorage: 2000,
|
|
62
|
+
throttleSync: 500,
|
|
63
|
+
})
|
|
64
|
+
class DashboardWorldRoom extends WorldRoom {
|
|
65
|
+
constructor(private readonly dashboardRoom: Party.Room) {
|
|
66
|
+
super(dashboardRoom);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
@Request({ path: "/dashboard" })
|
|
70
|
+
dashboard() {
|
|
71
|
+
return {
|
|
72
|
+
worldId: this.dashboardRoom.id,
|
|
73
|
+
rooms: Object.values(this.rooms()).map((room) => ({
|
|
74
|
+
id: room.id,
|
|
75
|
+
name: room.name(),
|
|
76
|
+
balancingStrategy: room.balancingStrategy(),
|
|
77
|
+
public: room.public(),
|
|
78
|
+
maxPlayersPerShard: room.maxPlayersPerShard(),
|
|
79
|
+
minShards: room.minShards(),
|
|
80
|
+
maxShards: room.maxShards(),
|
|
81
|
+
})),
|
|
82
|
+
shards: Object.values(this.shards()).map((shard: any) => ({
|
|
83
|
+
id: shard.id,
|
|
84
|
+
roomId: shard.roomId(),
|
|
85
|
+
worldId: shard.worldId(),
|
|
86
|
+
url: shard.url(),
|
|
87
|
+
currentConnections: shard.currentConnections(),
|
|
88
|
+
maxConnections: shard.maxConnections(),
|
|
89
|
+
status: shard.status(),
|
|
90
|
+
lastHeartbeat: shard.lastHeartbeat(),
|
|
91
|
+
})),
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export class MainServer extends Server {
|
|
97
|
+
rooms = [DashboardWorldRoom, DemoRoom];
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export class ShardServer extends Shard {
|
|
101
|
+
constructor(room: Party.Room) {
|
|
102
|
+
super(room);
|
|
103
|
+
this.statsInterval = 5000;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export const AUTH_JWT_SECRET = process.env.AUTH_JWT_SECRET ?? "node-shard-auth-secret-at-least-256-bits";
|
|
2
|
+
export const SHARD_SECRET = process.env.SHARD_SECRET ?? "node-shard-local-secret";
|
|
3
|
+
export const WORLD_PORT = Number(process.env.WORLD_PORT ?? 3002);
|
|
4
|
+
export const ROOM_PORT = Number(process.env.ROOM_PORT ?? 3003);
|
|
5
|
+
export const WORLD_ORIGIN = process.env.WORLD_ORIGIN ?? `http://localhost:${WORLD_PORT}`;
|
|
6
|
+
export const ROOM_ORIGIN = process.env.ROOM_ORIGIN ?? `http://localhost:${ROOM_PORT}`;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "Bundler",
|
|
6
|
+
"strict": true,
|
|
7
|
+
"experimentalDecorators": true,
|
|
8
|
+
"emitDecoratorMetadata": false,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"skipLibCheck": true,
|
|
11
|
+
"noEmit": true
|
|
12
|
+
},
|
|
13
|
+
"include": ["*.ts", "public/**/*.html"]
|
|
14
|
+
}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { createServer, type IncomingMessage, type ServerResponse } from "node:http";
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { createMemoryNodeRoomStorage, createNodeRoomTransport } from "@signe/room/node";
|
|
6
|
+
import { MainServer } from "./room";
|
|
7
|
+
import { AUTH_JWT_SECRET, ROOM_ORIGIN, SHARD_SECRET, WORLD_ORIGIN, WORLD_PORT } from "./shared";
|
|
8
|
+
|
|
9
|
+
const root = fileURLToPath(new URL(".", import.meta.url));
|
|
10
|
+
const storage = createMemoryNodeRoomStorage();
|
|
11
|
+
|
|
12
|
+
const transport = createNodeRoomTransport(MainServer, {
|
|
13
|
+
partiesPath: "/parties/main",
|
|
14
|
+
storage,
|
|
15
|
+
env: {
|
|
16
|
+
AUTH_JWT_SECRET,
|
|
17
|
+
SHARD_SECRET,
|
|
18
|
+
},
|
|
19
|
+
rooms: {
|
|
20
|
+
world: MainServer,
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
const server = createServer(async (req, res) => {
|
|
25
|
+
try {
|
|
26
|
+
if (req.url?.startsWith("/parties/world/")) {
|
|
27
|
+
await transport.handleNodeRequest(req, res);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (req.url?.startsWith("/api/world/")) {
|
|
32
|
+
await handleWorldApi(req, res);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (req.url?.startsWith("/api/room/")) {
|
|
37
|
+
await handleRoomApi(req, res);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (req.url === "/" || req.url === "/index.html" || req.url?.startsWith("/rooms/")) {
|
|
42
|
+
const html = await readFile(join(root, "public/index.html"), "utf8");
|
|
43
|
+
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
44
|
+
res.end(html);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
res.writeHead(404, { "Content-Type": "text/plain; charset=utf-8" });
|
|
49
|
+
res.end("Not Found");
|
|
50
|
+
} catch (error) {
|
|
51
|
+
console.error(error);
|
|
52
|
+
writeJson(res, 500, { error: "Internal Server Error" });
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
server.listen(WORLD_PORT, () => {
|
|
57
|
+
console.log(`World process: ${WORLD_ORIGIN}`);
|
|
58
|
+
console.log(`Dashboard: ${WORLD_ORIGIN}`);
|
|
59
|
+
console.log(`Room process: ${ROOM_ORIGIN}`);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
async function handleWorldApi(req: IncomingMessage, res: ServerResponse) {
|
|
63
|
+
const url = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
|
|
64
|
+
const match = url.pathname.match(/^\/api\/world\/([^/]+)\/([^/]+)$/);
|
|
65
|
+
|
|
66
|
+
if (!match) {
|
|
67
|
+
writeJson(res, 404, { error: "Not Found" });
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const worldId = decodeURIComponent(match[1]);
|
|
72
|
+
const action = match[2];
|
|
73
|
+
|
|
74
|
+
if (req.method === "GET" && action === "dashboard") {
|
|
75
|
+
await proxyWorld(res, worldId, "/dashboard", { method: "GET" });
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (req.method === "POST" && action === "connect") {
|
|
80
|
+
const body = await readJson(req);
|
|
81
|
+
await proxyWorld(res, worldId, "/connect", {
|
|
82
|
+
method: "POST",
|
|
83
|
+
headers: {
|
|
84
|
+
"Content-Type": "application/json",
|
|
85
|
+
},
|
|
86
|
+
body: JSON.stringify(body),
|
|
87
|
+
});
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (req.method === "POST" && action === "scale") {
|
|
92
|
+
const body = await readJson(req);
|
|
93
|
+
await proxyWorld(res, worldId, "/scale-room", {
|
|
94
|
+
method: "POST",
|
|
95
|
+
body: JSON.stringify(body),
|
|
96
|
+
});
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (req.method === "POST" && action === "shard-status") {
|
|
101
|
+
const body = await readJson(req);
|
|
102
|
+
await proxyWorld(res, worldId, "/update-shard", {
|
|
103
|
+
method: "POST",
|
|
104
|
+
body: JSON.stringify(body),
|
|
105
|
+
});
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
writeJson(res, 404, { error: "Not Found" });
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
async function handleRoomApi(req: IncomingMessage, res: ServerResponse) {
|
|
113
|
+
const url = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
|
|
114
|
+
const match = url.pathname.match(/^\/api\/room\/([^/]+)\/([^/]+)$/);
|
|
115
|
+
|
|
116
|
+
if (!match) {
|
|
117
|
+
writeJson(res, 404, { error: "Not Found" });
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const roomId = decodeURIComponent(match[1]);
|
|
122
|
+
const action = match[2];
|
|
123
|
+
|
|
124
|
+
if (req.method === "POST" && action === "reset") {
|
|
125
|
+
const response = await fetch(`${ROOM_ORIGIN}/parties/main/${encodeURIComponent(roomId)}/reset`, {
|
|
126
|
+
method: "POST",
|
|
127
|
+
});
|
|
128
|
+
res.writeHead(response.status, Object.fromEntries(response.headers.entries()));
|
|
129
|
+
res.end(Buffer.from(await response.arrayBuffer()));
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
writeJson(res, 404, { error: "Not Found" });
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
async function proxyWorld(
|
|
137
|
+
res: ServerResponse,
|
|
138
|
+
worldId: string,
|
|
139
|
+
path: string,
|
|
140
|
+
init: RequestInit
|
|
141
|
+
) {
|
|
142
|
+
const headers = new Headers(init.headers);
|
|
143
|
+
headers.set("Content-Type", "application/json");
|
|
144
|
+
headers.set("x-access-shard", SHARD_SECRET);
|
|
145
|
+
|
|
146
|
+
const response = await transport.fetch(`/parties/world/${encodeURIComponent(worldId)}${path}`, {
|
|
147
|
+
...init,
|
|
148
|
+
headers,
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
res.writeHead(response.status, Object.fromEntries(response.headers.entries()));
|
|
152
|
+
res.end(Buffer.from(await response.arrayBuffer()));
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
async function readJson(req: IncomingMessage) {
|
|
156
|
+
const chunks: Buffer[] = [];
|
|
157
|
+
|
|
158
|
+
for await (const chunk of req) {
|
|
159
|
+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const body = Buffer.concat(chunks).toString("utf8");
|
|
163
|
+
return body ? JSON.parse(body) : {};
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function writeJson(res: ServerResponse, status: number, body: unknown) {
|
|
167
|
+
res.writeHead(status, { "Content-Type": "application/json; charset=utf-8" });
|
|
168
|
+
res.end(JSON.stringify(body));
|
|
169
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@signe/room",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "PartyKit room primitives with synchronized state, sessions, guards, and HTTP handlers.",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"keywords": [
|
|
@@ -16,6 +16,14 @@
|
|
|
16
16
|
".": {
|
|
17
17
|
"import": "./dist/index.js",
|
|
18
18
|
"types": "./dist/index.d.ts"
|
|
19
|
+
},
|
|
20
|
+
"./node": {
|
|
21
|
+
"import": "./dist/node/index.js",
|
|
22
|
+
"types": "./dist/node/index.d.ts"
|
|
23
|
+
},
|
|
24
|
+
"./cloudflare": {
|
|
25
|
+
"import": "./dist/cloudflare/index.js",
|
|
26
|
+
"types": "./dist/cloudflare/index.d.ts"
|
|
19
27
|
}
|
|
20
28
|
},
|
|
21
29
|
"license": "MIT",
|
|
@@ -23,16 +31,17 @@
|
|
|
23
31
|
"dset": "^3.1.3",
|
|
24
32
|
"partysocket": "^1.0.1",
|
|
25
33
|
"zod": "^3.23.8",
|
|
26
|
-
"@signe/sync": "
|
|
34
|
+
"@signe/sync": "3.0.0"
|
|
27
35
|
},
|
|
28
36
|
"publishConfig": {
|
|
29
37
|
"access": "public"
|
|
30
38
|
},
|
|
31
39
|
"devDependencies": {
|
|
32
|
-
"@cloudflare/workers-types": "^4.
|
|
40
|
+
"@cloudflare/workers-types": "^4.20241218.0",
|
|
41
|
+
"@types/node": "^22.13.9"
|
|
33
42
|
},
|
|
34
43
|
"scripts": {
|
|
35
|
-
"build": "tsup src/index.ts",
|
|
36
|
-
"dev": "tsup src/index.ts --watch"
|
|
44
|
+
"build": "tsup src/index.ts src/node/index.ts src/cloudflare/index.ts",
|
|
45
|
+
"dev": "tsup src/index.ts src/node/index.ts src/cloudflare/index.ts --watch"
|
|
37
46
|
}
|
|
38
47
|
}
|