@pluv/platform-node 0.0.0-canary-20261027022227

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) 2022 Shoubhit Dash
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,18 @@
1
+ ## `@pluv/platform-node`
2
+
3
+ > Enables [@pluv/io](https://www.npmjs.com/package/@pluv/io) to run on [Node.js](https://nodejs.org/).
4
+
5
+ **👉 See full documentation on [docs.pluv.io](https://docs.pluv.io/docs). 👈**
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ # npm
11
+ npm install @pluv/platform-node ws @types/ws
12
+
13
+ # yarn
14
+ yarn add @pluv/platform-node ws @types/ws
15
+
16
+ # pnpm
17
+ pnpm add @pluv/platform-node ws @types/ws
18
+ ```
@@ -0,0 +1,71 @@
1
+ import { AbstractEventMap, AbstractListener, AbstractPersistence, AbstractPlatform, AbstractPlatformConfig, AbstractWebSocket, AbstractWebSocketConfig, ConvertWebSocketConfig, WebSocketSerializedState, WebSocketSession } from "@pluv/io";
2
+ import { WebSocket, WebSocket as WebSocket$1 } from "ws";
3
+ import { BaseUser, Id, Json, JsonObject } from "@pluv/types";
4
+ import { IncomingMessage } from "node:http";
5
+ declare const identity: <T extends unknown>(x: T) => T;
6
+ type ToRequestOptions = {
7
+ origin?: string;
8
+ };
9
+ export declare const toRequest: (request: Request | IncomingMessage, options?: ToRequestOptions) => Request;
10
+ type InferCallback<TMeta extends Record<string, Json> = {}> = (i: typeof identity) => {
11
+ meta?: (io: TMeta) => TMeta;
12
+ };
13
+ export declare const infer: <TMeta extends Record<string, Json> = {}>(callback: InferCallback<TMeta>) => InferCallback<TMeta>;
14
+ type NodeWebSocketConfig = AbstractWebSocketConfig;
15
+ declare class NodeWebSocket extends AbstractWebSocket<WebSocket$1> {
16
+ private _sessionId;
17
+ private _state;
18
+ private _user;
19
+ set presence(presence: JsonObject | null);
20
+ get readyState(): 0 | 1 | 2 | 3;
21
+ get session(): WebSocketSession<any>;
22
+ get sessionId(): string;
23
+ get state(): WebSocketSerializedState;
24
+ set state(state: WebSocketSerializedState);
25
+ get user(): BaseUser | null;
26
+ set user(user: BaseUser);
27
+ constructor(webSocket: WebSocket$1, config: NodeWebSocketConfig);
28
+ addEventListener<TType extends keyof AbstractEventMap>(type: TType, handler: AbstractListener<TType>): void;
29
+ close(code?: number, reason?: string): void;
30
+ send(message: string | ArrayBuffer | ArrayBufferView): void;
31
+ terminate(): void;
32
+ }
33
+ type NodeRegisterInput = {
34
+ request: Request | IncomingMessage;
35
+ };
36
+ type NodeAuthorizeContext = {
37
+ request: Request;
38
+ };
39
+ type NodePlatformRoomContext<TMeta extends Record<string, Json>> = keyof TMeta extends never ? {
40
+ meta?: undefined;
41
+ } : {
42
+ meta: TMeta;
43
+ };
44
+ type NodePlatformConfig<TMeta extends Record<string, Json>> = {
45
+ origin?: string;
46
+ persistence?: AbstractPersistence;
47
+ roomContext?: NodePlatformRoomContext<TMeta>;
48
+ };
49
+ declare class NodePlatform<TMeta extends Record<string, Json> = {}> extends AbstractPlatform<NodeWebSocket, NodeRegisterInput, NodePlatformRoomContext<TMeta>> {
50
+ readonly id: `${string}-${string}-${string}-${string}-${string}`;
51
+ readonly _name = "platformNode";
52
+ readonly origin: string | undefined;
53
+ constructor(config?: NodePlatformConfig<TMeta>);
54
+ acceptWebSocket(webSocket: NodeWebSocket): Promise<void>;
55
+ convertWebSocket(webSocket: WebSocket$1, config: ConvertWebSocketConfig): NodeWebSocket;
56
+ getLastPing(webSocket: NodeWebSocket): number | null;
57
+ getSerializedState(webSocket: WebSocket$1): WebSocketSerializedState | null;
58
+ getSessionId(webSocket: WebSocket$1): string | null;
59
+ getWebSockets(): readonly WebSocket$1[];
60
+ initialize(config: AbstractPlatformConfig<NodePlatformRoomContext<TMeta>>): this;
61
+ normalizeInitContext(initContext: NodeRegisterInput): NodeRegisterInput;
62
+ parseData(data: string | ArrayBuffer): Record<string, any>;
63
+ randomUUID(): string;
64
+ setSerializedState(webSocket: NodeWebSocket, state: WebSocketSerializedState): WebSocketSerializedState;
65
+ }
66
+ type PlatformNodeParams<TMeta extends Record<string, Json> = {}> = Id<NodePlatformConfig<TMeta> & {
67
+ types?: InferCallback<TMeta>;
68
+ }>;
69
+ export declare const platformNode: <TMeta extends Record<string, Json> = {}>(config?: PlatformNodeParams<TMeta>) => (() => NodePlatform<TMeta>);
70
+ export type { InferCallback, NodeAuthorizeContext, NodePlatform, NodePlatformConfig, NodeRegisterInput, PlatformNodeParams, ToRequestOptions, WebSocket };
71
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":["WebSocket","WebSocket"],"sources":["../src/utils/identity.ts","../src/utils/toRequest.ts","../src/infer.ts","../src/NodeWebSocket.ts","../src/types.ts","../src/NodePlatform.ts","../src/platformNode.ts"],"mappings":";;;;cAAa,WAAY,mBAAiB,GAAK,MAAI;KCwCvC;EACR;;qBAGS,YAAS,SACT,UAAU,iBAAe,UACzB,qBACV;KC5CS,cAAc,cAAc,eAAe,eAAe,UAAU;EAC5E,QAAQ,IAAI,UAAU;;qBAGb,QAAS,cAAc,eAAe,YAAU,UAAY,cAAc,WAAM,cAAA;KCcjF,sBAAsB;cAErB,sBAAsB,kBAAkBA;UACzC;UACA;UACA;MAEG,SAAS,UAAU;MAInB;MAIA,WAAW;MAeX;MAUA,SAAS;MAIT,MAAM,OAAO;MAIb,QAAQ;MAIR,KAAK,MAAM;EAItB,YAAY,WAAWA,aAAW,QAAQ;EAkBnC,iBAAiB,oBAAoB,kBACxC,MAAM,OACN,SAAS,iBAAiB;EA+BvB,MAAM,eAAe;EAUrB,KAAK,kBAAkB,cAAc;EAQrC;;KChJC;EAAsB,SAAS,UAAU;;KAEzC;EAAyB,SAAS;;KCWlC,wBAAwB,cAAc,eAAe,eAAe;EACxE;;EACA,MAAM;;KAEF,mBAAmB,cAAc,eAAe;EACxD;EACA,cAAc;EACd,cAAc,wBAAwB;;cAG7B,aAAa,cAAc,eAAe,oBAAoB,iBACvE,eACA,mBACA,wBAAwB;WAER;WACA;WACA;EAEhB,YAAY,SAAQ,mBAAmB;EAWhC,gBAAgB,WAAW,gBAAgB;EAI3C,iBAAiB,WAAWC,aAAW,QAAQ,yBAAyB;EAUxE,YAAY,WAAW;EAIvB,mBAAmB,WAAWA,cAAY;EAI1C,aAAa,WAAWA;EAIxB,0BAA0BA;EAI1B,WAAW,QAAQ,uBAAuB,wBAAwB;EAQlE,qBAAqB,aAAa,oBAAoB;EAMtD,UAAU,eAAe,cAAc;EAQvC;EAIA,mBACH,WAAW,eACX,OAAO,2BACR;;KCnGK,mBAAmB,cAAc,eAAe,cAAc,GACtE,mBAAmB;EACf,QAAQ,cAAc;;qBAIjB,eAAgB,cAAc,eAAe,YAAU,SACxD,mBAAmB,kBACrB,aAAa"}
package/dist/index.mjs ADDED
@@ -0,0 +1,204 @@
1
+ import { AbstractPlatform, AbstractWebSocket } from "@pluv/io";
2
+ import crypto from "node:crypto";
3
+ import { TextDecoder } from "node:util";
4
+ import { Readable } from "node:stream";
5
+ // src/infer.ts
6
+ const infer = (callback) => callback;
7
+ // src/NodeWebSocket.ts
8
+ var NodeWebSocket = class extends AbstractWebSocket {
9
+ _sessionId = null;
10
+ _state;
11
+ _user = null;
12
+ set presence(presence) {
13
+ this._state.presence = presence;
14
+ }
15
+ get readyState() {
16
+ return this.webSocket.readyState;
17
+ }
18
+ get session() {
19
+ const user = this._user;
20
+ if (!user) throw new Error("WebSocket is not authorized");
21
+ return {
22
+ ...this._state,
23
+ id: this.sessionId,
24
+ user,
25
+ webSocket: this
26
+ };
27
+ }
28
+ get sessionId() {
29
+ if (this._sessionId) return this._sessionId;
30
+ const sessionId = this._sessionId ?? `p_${crypto.randomUUID()}`;
31
+ this._sessionId = sessionId;
32
+ return sessionId;
33
+ }
34
+ get state() {
35
+ return this._state;
36
+ }
37
+ set state(state) {
38
+ this._state = state;
39
+ }
40
+ get user() {
41
+ return this._user;
42
+ }
43
+ set user(user) {
44
+ this._user = user;
45
+ }
46
+ constructor(webSocket, config) {
47
+ const { room } = config;
48
+ super(webSocket, config);
49
+ this._state = {
50
+ kind: "user",
51
+ operator: null,
52
+ presence: null,
53
+ quit: false,
54
+ room,
55
+ seq: { presence: null },
56
+ timers: { ping: (/* @__PURE__ */ new Date()).getTime() }
57
+ };
58
+ }
59
+ addEventListener(type, handler) {
60
+ switch (type) {
61
+ case "close":
62
+ this.webSocket.on("close", async (code, buffer) => {
63
+ const reason = buffer.toString("utf-8");
64
+ await Promise.resolve(handler({
65
+ code,
66
+ reason
67
+ }));
68
+ });
69
+ return;
70
+ case "error":
71
+ this.webSocket.on("error", async (error) => {
72
+ const message = error.message;
73
+ await Promise.resolve(handler({
74
+ error,
75
+ message
76
+ }));
77
+ });
78
+ return;
79
+ case "message":
80
+ this.webSocket.on("message", async (data) => {
81
+ await Promise.resolve(handler({ data }));
82
+ });
83
+ return;
84
+ }
85
+ }
86
+ close(code, reason) {
87
+ if (![this.CONNECTING, this.OPEN].some((readyState) => readyState === this.readyState)) return;
88
+ this.webSocket.close(code, reason);
89
+ }
90
+ send(message) {
91
+ if (this.readyState !== this.OPEN) return;
92
+ this.webSocket.send(message, (error) => {
93
+ if (error) throw error;
94
+ });
95
+ }
96
+ terminate() {
97
+ this.webSocket.terminate();
98
+ }
99
+ };
100
+ // src/utils/toRequest.ts
101
+ const getHeader = (incoming, name) => {
102
+ const value = incoming.headers[name];
103
+ if (Array.isArray(value)) return value[0];
104
+ return value;
105
+ };
106
+ const inferOrigin = (incoming) => {
107
+ const host = getHeader(incoming, "x-forwarded-host") ?? getHeader(incoming, "host") ?? "localhost";
108
+ return `${getHeader(incoming, "x-forwarded-proto") ?? (incoming.socket.encrypted ? "https" : "http")}://${host}`;
109
+ };
110
+ const toHeaders = (incoming) => {
111
+ const headers = new Headers();
112
+ for (const [key, value] of Object.entries(incoming.headers)) {
113
+ if (value == null) continue;
114
+ if (Array.isArray(value)) {
115
+ for (const item of value) headers.append(key, item);
116
+ continue;
117
+ }
118
+ headers.append(key, value);
119
+ }
120
+ return headers;
121
+ };
122
+ const toRequest = (request, options = {}) => {
123
+ if (request instanceof Request) return request;
124
+ const origin = options.origin ?? inferOrigin(request);
125
+ const url = new URL(request.url ?? "/", origin);
126
+ const method = request.method ?? "GET";
127
+ const headers = toHeaders(request);
128
+ if (method === "GET" || method === "HEAD") return new Request(url, {
129
+ headers,
130
+ method
131
+ });
132
+ return new Request(url, {
133
+ body: Readable.toWeb(request),
134
+ duplex: "half",
135
+ headers,
136
+ method
137
+ });
138
+ };
139
+ // src/NodePlatform.ts
140
+ var NodePlatform = class NodePlatform extends AbstractPlatform {
141
+ id = crypto.randomUUID();
142
+ _name = "platformNode";
143
+ origin;
144
+ constructor(config = {}) {
145
+ const { origin, roomContext, persistence } = config;
146
+ super({
147
+ roomContext,
148
+ ...persistence ? { persistence } : {}
149
+ });
150
+ this.origin = origin;
151
+ }
152
+ acceptWebSocket(webSocket) {
153
+ return Promise.resolve(void 0);
154
+ }
155
+ convertWebSocket(webSocket, config) {
156
+ const { room } = config;
157
+ return new NodeWebSocket(webSocket, {
158
+ persistence: this.persistence,
159
+ platform: this,
160
+ room
161
+ });
162
+ }
163
+ getLastPing(webSocket) {
164
+ return null;
165
+ }
166
+ getSerializedState(webSocket) {
167
+ return null;
168
+ }
169
+ getSessionId(webSocket) {
170
+ return null;
171
+ }
172
+ getWebSockets() {
173
+ return [];
174
+ }
175
+ initialize(config) {
176
+ return new NodePlatform({
177
+ origin: this.origin,
178
+ persistence: this.persistence.initialize(config.roomContext),
179
+ roomContext: config.roomContext
180
+ })._initialize();
181
+ }
182
+ normalizeInitContext(initContext) {
183
+ return { request: toRequest(initContext.request, { origin: this.origin }) };
184
+ }
185
+ parseData(data) {
186
+ if (typeof data === "string") return JSON.parse(data);
187
+ const decoder = new TextDecoder("utf8");
188
+ return JSON.parse(decoder.decode(data));
189
+ }
190
+ randomUUID() {
191
+ return crypto.randomUUID();
192
+ }
193
+ setSerializedState(webSocket, state) {
194
+ webSocket.state = state;
195
+ return webSocket.state;
196
+ }
197
+ };
198
+ // src/platformNode.ts
199
+ const platformNode = (config = {}) => {
200
+ return () => new NodePlatform(config);
201
+ };
202
+ export { infer, platformNode, toRequest };
203
+
204
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/infer.ts","../src/NodeWebSocket.ts","../src/utils/toRequest.ts","../src/NodePlatform.ts","../src/platformNode.ts"],"sourcesContent":["import type { Json } from \"@pluv/types\";\nimport type { identity } from \"./utils\";\n\nexport type InferCallback<TMeta extends Record<string, Json> = {}> = (i: typeof identity) => {\n meta?: (io: TMeta) => TMeta;\n};\n\nexport const infer = <TMeta extends Record<string, Json> = {}>(callback: InferCallback<TMeta>) =>\n callback;\n","import type {\n AbstractCloseEvent,\n AbstractErrorEvent,\n AbstractEventMap,\n AbstractListener,\n AbstractMessageEvent,\n AbstractWebSocketConfig,\n WebSocketSerializedState,\n WebSocketSession,\n} from \"@pluv/io\";\nimport { AbstractWebSocket } from \"@pluv/io\";\nimport type { BaseUser, JsonObject } from \"@pluv/types\";\nimport crypto from \"node:crypto\";\nimport type { WebSocket } from \"ws\";\n\nexport interface NodeWebSocketEventMap {\n close: AbstractCloseEvent;\n message: AbstractMessageEvent;\n error: AbstractErrorEvent;\n}\n\nexport type NodeWebSocketConfig = AbstractWebSocketConfig;\n\nexport class NodeWebSocket extends AbstractWebSocket<WebSocket> {\n private _sessionId: string | null = null;\n private _state: WebSocketSerializedState;\n private _user: BaseUser | null = null;\n\n public set presence(presence: JsonObject | null) {\n this._state.presence = presence;\n }\n\n public get readyState(): 0 | 1 | 2 | 3 {\n return this.webSocket.readyState;\n }\n\n public get session(): WebSocketSession<any> {\n const user = this._user;\n\n if (!user) {\n throw new Error(\"WebSocket is not authorized\");\n }\n\n return {\n ...this._state,\n id: this.sessionId,\n user,\n webSocket: this,\n };\n }\n\n public get sessionId(): string {\n if (this._sessionId) return this._sessionId;\n\n const sessionId = this._sessionId ?? `p_${crypto.randomUUID()}`;\n\n this._sessionId = sessionId;\n\n return sessionId;\n }\n\n public get state(): WebSocketSerializedState {\n return this._state;\n }\n\n public set state(state: WebSocketSerializedState) {\n this._state = state;\n }\n\n public get user(): BaseUser | null {\n return this._user;\n }\n\n public set user(user: BaseUser) {\n this._user = user;\n }\n\n constructor(webSocket: WebSocket, config: NodeWebSocketConfig) {\n const { room } = config;\n\n super(webSocket, config);\n\n this._state = {\n kind: \"user\",\n operator: null,\n presence: null,\n quit: false,\n room,\n seq: { presence: null },\n timers: {\n ping: new Date().getTime(),\n },\n };\n }\n\n public addEventListener<TType extends keyof AbstractEventMap>(\n type: TType,\n handler: AbstractListener<TType>,\n ): void {\n switch (type) {\n case \"close\":\n this.webSocket.on(\"close\", async (code, buffer) => {\n const reason = buffer.toString(\"utf-8\");\n\n await Promise.resolve((handler as AbstractListener<\"close\">)({ code, reason }));\n });\n\n return;\n case \"error\":\n this.webSocket.on(\"error\", async (error) => {\n const message = error.message;\n\n await Promise.resolve(\n (handler as AbstractListener<\"error\">)({ error, message }),\n );\n });\n\n return;\n case \"message\":\n this.webSocket.on(\"message\", async (data) => {\n await Promise.resolve((handler as AbstractListener<\"message\">)({ data }));\n });\n\n return;\n default:\n }\n }\n\n public close(code?: number, reason?: string): void {\n const canClose = [this.CONNECTING, this.OPEN].some(\n (readyState) => readyState === this.readyState,\n );\n\n if (!canClose) return;\n\n this.webSocket.close(code, reason);\n }\n\n public send(message: string | ArrayBuffer | ArrayBufferView): void {\n if (this.readyState !== this.OPEN) return;\n\n this.webSocket.send(message, (error) => {\n if (error) throw error;\n });\n }\n\n public terminate(): void {\n this.webSocket.terminate();\n }\n}\n","import type { IncomingMessage } from \"node:http\";\nimport { Readable } from \"node:stream\";\n\nconst getHeader = (incoming: IncomingMessage, name: string): string | undefined => {\n const value = incoming.headers[name];\n\n if (Array.isArray(value)) return value[0];\n\n return value;\n};\n\nconst inferOrigin = (incoming: IncomingMessage): string => {\n const host =\n getHeader(incoming, \"x-forwarded-host\") ?? getHeader(incoming, \"host\") ?? \"localhost\";\n const forwardedProto = getHeader(incoming, \"x-forwarded-proto\");\n const protocol =\n forwardedProto ??\n ((incoming.socket as { encrypted?: boolean }).encrypted ? \"https\" : \"http\");\n\n return `${protocol}://${host}`;\n};\n\nconst toHeaders = (incoming: IncomingMessage): Headers => {\n const headers = new Headers();\n\n for (const [key, value] of Object.entries(incoming.headers)) {\n if (value == null) continue;\n\n if (Array.isArray(value)) {\n for (const item of value) headers.append(key, item);\n\n continue;\n }\n\n headers.append(key, value);\n }\n\n return headers;\n};\n\nexport type ToRequestOptions = {\n origin?: string;\n};\n\nexport const toRequest = (\n request: Request | IncomingMessage,\n options: ToRequestOptions = {},\n): Request => {\n if (request instanceof Request) return request;\n\n const origin = options.origin ?? inferOrigin(request);\n const url = new URL(request.url ?? \"/\", origin);\n const method = request.method ?? \"GET\";\n const headers = toHeaders(request);\n\n if (method === \"GET\" || method === \"HEAD\") {\n return new Request(url, {\n headers,\n method,\n });\n }\n\n return new Request(url, {\n body: Readable.toWeb(request) as ReadableStream,\n duplex: \"half\",\n headers,\n method,\n });\n};\n","import type {\n AbstractPersistence,\n AbstractPlatformConfig,\n ConvertWebSocketConfig,\n WebSocketSerializedState,\n} from \"@pluv/io\";\nimport { AbstractPlatform } from \"@pluv/io\";\nimport type { Json } from \"@pluv/types\";\nimport crypto from \"node:crypto\";\nimport { TextDecoder } from \"node:util\";\nimport type { WebSocket } from \"ws\";\nimport { NodeWebSocket } from \"./NodeWebSocket\";\nimport type { NodeRegisterInput } from \"./types\";\nimport { toRequest } from \"./utils/toRequest\";\n\nexport type NodePlatformRoomContext<TMeta extends Record<string, Json>> = keyof TMeta extends never\n ? { meta?: undefined }\n : { meta: TMeta };\n\nexport type NodePlatformConfig<TMeta extends Record<string, Json>> = {\n origin?: string;\n persistence?: AbstractPersistence;\n roomContext?: NodePlatformRoomContext<TMeta>;\n};\n\nexport class NodePlatform<TMeta extends Record<string, Json> = {}> extends AbstractPlatform<\n NodeWebSocket,\n NodeRegisterInput,\n NodePlatformRoomContext<TMeta>\n> {\n public readonly id = crypto.randomUUID();\n public readonly _name = \"platformNode\";\n public readonly origin: string | undefined;\n\n constructor(config: NodePlatformConfig<TMeta> = {}) {\n const { origin, roomContext, persistence } = config;\n\n super({\n roomContext,\n ...(persistence ? { persistence } : {}),\n });\n\n this.origin = origin;\n }\n\n public acceptWebSocket(webSocket: NodeWebSocket): Promise<void> {\n return Promise.resolve(undefined);\n }\n\n public convertWebSocket(webSocket: WebSocket, config: ConvertWebSocketConfig): NodeWebSocket {\n const { room } = config;\n\n return new NodeWebSocket(webSocket, {\n persistence: this.persistence,\n platform: this,\n room,\n });\n }\n\n public getLastPing(webSocket: NodeWebSocket): number | null {\n return null;\n }\n\n public getSerializedState(webSocket: WebSocket): WebSocketSerializedState | null {\n return null;\n }\n\n public getSessionId(webSocket: WebSocket): string | null {\n return null;\n }\n\n public getWebSockets(): readonly WebSocket[] {\n return [];\n }\n\n public initialize(config: AbstractPlatformConfig<NodePlatformRoomContext<TMeta>>): this {\n return new NodePlatform({\n origin: this.origin,\n persistence: this.persistence.initialize(config.roomContext),\n roomContext: config.roomContext,\n })._initialize() as this;\n }\n\n public normalizeInitContext(initContext: NodeRegisterInput): NodeRegisterInput {\n return {\n request: toRequest(initContext.request, { origin: this.origin }),\n };\n }\n\n public parseData(data: string | ArrayBuffer): Record<string, any> {\n if (typeof data === \"string\") return JSON.parse(data);\n\n const decoder = new TextDecoder(\"utf8\");\n\n return JSON.parse(decoder.decode(data));\n }\n\n public randomUUID(): string {\n return crypto.randomUUID();\n }\n\n public setSerializedState(\n webSocket: NodeWebSocket,\n state: WebSocketSerializedState,\n ): WebSocketSerializedState {\n webSocket.state = state;\n\n return webSocket.state;\n }\n}\n","import type { Id, Json } from \"@pluv/types\";\nimport type { NodePlatformConfig } from \"./NodePlatform\";\nimport { NodePlatform } from \"./NodePlatform\";\nimport type { InferCallback } from \"./infer\";\n\nexport type PlatformNodeParams<TMeta extends Record<string, Json> = {}> = Id<\n NodePlatformConfig<TMeta> & {\n types?: InferCallback<TMeta>;\n }\n>;\n\nexport const platformNode = <TMeta extends Record<string, Json> = {}>(\n config: PlatformNodeParams<TMeta> = {} as PlatformNodeParams<TMeta>,\n): (() => NodePlatform<TMeta>) => {\n return () => new NodePlatform<TMeta>(config);\n};\n"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@pluv/platform-node",
3
+ "version": "0.0.0-canary-20261027022227",
4
+ "description": "@pluv/io adapter for node.js",
5
+ "author": {
6
+ "email": "david@pluv.io",
7
+ "name": "i3dly",
8
+ "url": "https://github.com/i3dly"
9
+ },
10
+ "license": "MIT",
11
+ "homepage": "https://github.com/pluv-io/pluv",
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "git+https://github.com/pluv-io/pluv.git",
15
+ "directory": "packages/platform-node"
16
+ },
17
+ "type": "module",
18
+ "types": "./dist/index.d.mts",
19
+ "files": [
20
+ "dist"
21
+ ],
22
+ "publishConfig": {
23
+ "access": "public"
24
+ },
25
+ "dependencies": {
26
+ "@pluv/crdt": "^0.0.0-canary-20261027022227",
27
+ "@pluv/io": "^0.0.0-canary-20261027022227",
28
+ "@pluv/types": "^0.0.0-canary-20261027022227",
29
+ "@types/node": "^26.6.5",
30
+ "@types/ws": "^8.18.2",
31
+ "path-to-regexp": "^9.0.0"
32
+ },
33
+ "devDependencies": {
34
+ "@pluv/tsconfig": "^0.0.0-canary-20261027022227",
35
+ "tsdown": "^0.23.2",
36
+ "typescript": "7.1.0-beta",
37
+ "ws": "^8.22.0"
38
+ },
39
+ "peerDependencies": {
40
+ "ws": "^8.0.0"
41
+ },
42
+ "exports": {
43
+ ".": "./dist/index.mjs",
44
+ "./*": "./*"
45
+ },
46
+ "scripts": {
47
+ "build": "tsdown",
48
+ "dev": "tsdown --watch",
49
+ "typecheck": "tsc --noEmit",
50
+ "clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist"
51
+ }
52
+ }