@pluv/platform-pluv 0.0.0-experimental-20250527040415

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.
@@ -0,0 +1,94 @@
1
+ import { BaseUser, AbstractPlatform, JWTEncodeParams, AbstractWebSocket, ConvertWebSocketConfig, WebSocketSerializedState, AbstractPlatformConfig, CreateIOParams, PluvIOAuthorize, InferInitContextType, PluvContext } from '@pluv/io';
2
+ import { MaybePromise, BaseUser as BaseUser$1, Id } from '@pluv/types';
3
+
4
+ interface PluvIOEndpoints {
5
+ createToken: string;
6
+ }
7
+
8
+ type PublicKey = string | (() => MaybePromise<string>);
9
+ type SecretKey = string | (() => MaybePromise<string>);
10
+ type WebhookSecret = string | (() => MaybePromise<string>);
11
+ interface PluvPlatformConfig<TContext extends Record<string, any> = {}> {
12
+ /**
13
+ * @ignore
14
+ * @readonly
15
+ * @deprecated Internal use only. Changes to this will never be marked as breaking.
16
+ */
17
+ _defs?: {
18
+ debug?: boolean;
19
+ endpoints?: PluvIOEndpoints | (() => MaybePromise<PluvIOEndpoints>);
20
+ };
21
+ basePath: string;
22
+ context?: TContext;
23
+ publicKey: PublicKey;
24
+ secretKey: SecretKey;
25
+ webhookSecret?: WebhookSecret;
26
+ }
27
+ declare class PluvPlatform<TContext extends Record<string, any> = {}, TUser extends BaseUser = BaseUser> extends AbstractPlatform<any, {}, {}, {
28
+ authorize: {
29
+ secret: false;
30
+ };
31
+ handleMode: "fetch";
32
+ registrationMode: "attached";
33
+ requireAuth: true;
34
+ listeners: {
35
+ onRoomDeleted: true;
36
+ onRoomMessage: false;
37
+ onStorageUpdated: false;
38
+ onUserConnected: true;
39
+ onUserDisconnected: true;
40
+ };
41
+ router: false;
42
+ }> {
43
+ readonly id: string;
44
+ readonly _config: {
45
+ authorize: {
46
+ secret: false;
47
+ };
48
+ handleMode: "fetch";
49
+ registrationMode: "attached";
50
+ requireAuth: true;
51
+ listeners: {
52
+ onRoomDeleted: true;
53
+ onRoomMessage: false;
54
+ onStorageUpdated: false;
55
+ onUserConnected: true;
56
+ onUserDisconnected: true;
57
+ };
58
+ router: false;
59
+ };
60
+ readonly _name = "platformPluv";
61
+ private readonly _app;
62
+ private readonly _basePath;
63
+ private readonly _context;
64
+ private readonly _debug;
65
+ private readonly _endpoints;
66
+ private _getInitialStorage?;
67
+ private _listeners?;
68
+ private readonly _publicKey;
69
+ private readonly _secretKey;
70
+ private readonly _webhookSecret?;
71
+ _createToken: (params: JWTEncodeParams<any, any>) => Promise<string>;
72
+ constructor(params: PluvPlatformConfig);
73
+ acceptWebSocket(webSocket: AbstractWebSocket): Promise<void>;
74
+ convertWebSocket(webSocket: any, config: ConvertWebSocketConfig): AbstractWebSocket;
75
+ getLastPing(webSocket: AbstractWebSocket): number | null;
76
+ getSerializedState(webSocket: any): WebSocketSerializedState | null;
77
+ getSessionId(webSocket: any): string | null;
78
+ getWebSockets(): readonly any[];
79
+ initialize(config: AbstractPlatformConfig<{}>): this;
80
+ parseData(data: string | ArrayBuffer): Record<string, any>;
81
+ randomUUID(): string;
82
+ setSerializedState(webSocket: AbstractWebSocket, state: WebSocketSerializedState): WebSocketSerializedState;
83
+ validateConfig(config: any): void;
84
+ private _webhooksRouter;
85
+ private _logDebug;
86
+ }
87
+
88
+ type PlatformPluvCreateIOParams<TContext extends Record<string, any> = {}, TUser extends BaseUser$1 = BaseUser$1> = Id<PluvPlatformConfig & Omit<CreateIOParams<PluvPlatform, TContext, TUser>, "authorize" | "context" | "limits" | "platform"> & {
89
+ authorize: PluvIOAuthorize<PluvPlatform, TUser, InferInitContextType<PluvPlatform>>;
90
+ context?: PluvContext<PluvPlatform, TContext>;
91
+ }>;
92
+ declare const platformPluv: <TContext extends Record<string, any> = {}, TUser extends BaseUser$1 = BaseUser$1>(config: PlatformPluvCreateIOParams<TContext, TUser>) => CreateIOParams<PluvPlatform<TContext, TUser>, TContext, TUser>;
93
+
94
+ export { type PlatformPluvCreateIOParams, type PluvIOEndpoints, PluvPlatform, platformPluv };
@@ -0,0 +1,94 @@
1
+ import { BaseUser, AbstractPlatform, JWTEncodeParams, AbstractWebSocket, ConvertWebSocketConfig, WebSocketSerializedState, AbstractPlatformConfig, CreateIOParams, PluvIOAuthorize, InferInitContextType, PluvContext } from '@pluv/io';
2
+ import { MaybePromise, BaseUser as BaseUser$1, Id } from '@pluv/types';
3
+
4
+ interface PluvIOEndpoints {
5
+ createToken: string;
6
+ }
7
+
8
+ type PublicKey = string | (() => MaybePromise<string>);
9
+ type SecretKey = string | (() => MaybePromise<string>);
10
+ type WebhookSecret = string | (() => MaybePromise<string>);
11
+ interface PluvPlatformConfig<TContext extends Record<string, any> = {}> {
12
+ /**
13
+ * @ignore
14
+ * @readonly
15
+ * @deprecated Internal use only. Changes to this will never be marked as breaking.
16
+ */
17
+ _defs?: {
18
+ debug?: boolean;
19
+ endpoints?: PluvIOEndpoints | (() => MaybePromise<PluvIOEndpoints>);
20
+ };
21
+ basePath: string;
22
+ context?: TContext;
23
+ publicKey: PublicKey;
24
+ secretKey: SecretKey;
25
+ webhookSecret?: WebhookSecret;
26
+ }
27
+ declare class PluvPlatform<TContext extends Record<string, any> = {}, TUser extends BaseUser = BaseUser> extends AbstractPlatform<any, {}, {}, {
28
+ authorize: {
29
+ secret: false;
30
+ };
31
+ handleMode: "fetch";
32
+ registrationMode: "attached";
33
+ requireAuth: true;
34
+ listeners: {
35
+ onRoomDeleted: true;
36
+ onRoomMessage: false;
37
+ onStorageUpdated: false;
38
+ onUserConnected: true;
39
+ onUserDisconnected: true;
40
+ };
41
+ router: false;
42
+ }> {
43
+ readonly id: string;
44
+ readonly _config: {
45
+ authorize: {
46
+ secret: false;
47
+ };
48
+ handleMode: "fetch";
49
+ registrationMode: "attached";
50
+ requireAuth: true;
51
+ listeners: {
52
+ onRoomDeleted: true;
53
+ onRoomMessage: false;
54
+ onStorageUpdated: false;
55
+ onUserConnected: true;
56
+ onUserDisconnected: true;
57
+ };
58
+ router: false;
59
+ };
60
+ readonly _name = "platformPluv";
61
+ private readonly _app;
62
+ private readonly _basePath;
63
+ private readonly _context;
64
+ private readonly _debug;
65
+ private readonly _endpoints;
66
+ private _getInitialStorage?;
67
+ private _listeners?;
68
+ private readonly _publicKey;
69
+ private readonly _secretKey;
70
+ private readonly _webhookSecret?;
71
+ _createToken: (params: JWTEncodeParams<any, any>) => Promise<string>;
72
+ constructor(params: PluvPlatformConfig);
73
+ acceptWebSocket(webSocket: AbstractWebSocket): Promise<void>;
74
+ convertWebSocket(webSocket: any, config: ConvertWebSocketConfig): AbstractWebSocket;
75
+ getLastPing(webSocket: AbstractWebSocket): number | null;
76
+ getSerializedState(webSocket: any): WebSocketSerializedState | null;
77
+ getSessionId(webSocket: any): string | null;
78
+ getWebSockets(): readonly any[];
79
+ initialize(config: AbstractPlatformConfig<{}>): this;
80
+ parseData(data: string | ArrayBuffer): Record<string, any>;
81
+ randomUUID(): string;
82
+ setSerializedState(webSocket: AbstractWebSocket, state: WebSocketSerializedState): WebSocketSerializedState;
83
+ validateConfig(config: any): void;
84
+ private _webhooksRouter;
85
+ private _logDebug;
86
+ }
87
+
88
+ type PlatformPluvCreateIOParams<TContext extends Record<string, any> = {}, TUser extends BaseUser$1 = BaseUser$1> = Id<PluvPlatformConfig & Omit<CreateIOParams<PluvPlatform, TContext, TUser>, "authorize" | "context" | "limits" | "platform"> & {
89
+ authorize: PluvIOAuthorize<PluvPlatform, TUser, InferInitContextType<PluvPlatform>>;
90
+ context?: PluvContext<PluvPlatform, TContext>;
91
+ }>;
92
+ declare const platformPluv: <TContext extends Record<string, any> = {}, TUser extends BaseUser$1 = BaseUser$1>(config: PlatformPluvCreateIOParams<TContext, TUser>) => CreateIOParams<PluvPlatform<TContext, TUser>, TContext, TUser>;
93
+
94
+ export { type PlatformPluvCreateIOParams, type PluvIOEndpoints, PluvPlatform, platformPluv };
package/dist/index.js ADDED
@@ -0,0 +1,434 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var __async = (__this, __arguments, generator) => {
30
+ return new Promise((resolve, reject) => {
31
+ var fulfilled = (value) => {
32
+ try {
33
+ step(generator.next(value));
34
+ } catch (e) {
35
+ reject(e);
36
+ }
37
+ };
38
+ var rejected = (value) => {
39
+ try {
40
+ step(generator.throw(value));
41
+ } catch (e) {
42
+ reject(e);
43
+ }
44
+ };
45
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
46
+ step((generator = generator.apply(__this, __arguments)).next());
47
+ });
48
+ };
49
+
50
+ // src/index.ts
51
+ var index_exports = {};
52
+ __export(index_exports, {
53
+ PluvPlatform: () => PluvPlatform,
54
+ platformPluv: () => platformPluv
55
+ });
56
+ module.exports = __toCommonJS(index_exports);
57
+
58
+ // src/PluvPlatform.ts
59
+ var import_io = require("@pluv/io");
60
+ var import_fast_json_stable_stringify = __toESM(require("fast-json-stable-stringify"));
61
+ var import_hono = require("hono");
62
+
63
+ // src/constants.ts
64
+ var SIGNATURE_ALGORITHM = "sha256";
65
+ var SIGNATURE_HEADER = "x-pluv-signature-256";
66
+
67
+ // src/schemas.ts
68
+ var import_zod = require("zod");
69
+ var ZodEventKind = import_zod.z.union([
70
+ import_zod.z.literal("initial-storage"),
71
+ import_zod.z.literal("room-deleted"),
72
+ import_zod.z.literal("user-connected"),
73
+ import_zod.z.literal("user-disconnected")
74
+ ]);
75
+ var ZodEventInitialStorage = import_zod.z.object({
76
+ event: import_zod.z.literal("initial-storage"),
77
+ data: import_zod.z.object({
78
+ room: import_zod.z.string()
79
+ })
80
+ });
81
+ var ZodEventRoomDeleted = import_zod.z.object({
82
+ event: import_zod.z.literal("room-deleted"),
83
+ data: import_zod.z.object({
84
+ room: import_zod.z.string(),
85
+ storage: import_zod.z.string().nullable()
86
+ })
87
+ });
88
+ var ZodEventUserConnected = import_zod.z.object({
89
+ event: import_zod.z.literal("user-connected"),
90
+ data: import_zod.z.object({
91
+ room: import_zod.z.string(),
92
+ storage: import_zod.z.string().nullable(),
93
+ user: import_zod.z.object({
94
+ id: import_zod.z.string()
95
+ }).passthrough()
96
+ })
97
+ });
98
+ var ZodEventUserDisconnected = import_zod.z.object({
99
+ event: import_zod.z.literal("user-disconnected"),
100
+ data: import_zod.z.object({
101
+ room: import_zod.z.string(),
102
+ storage: import_zod.z.string().nullable(),
103
+ user: import_zod.z.object({
104
+ id: import_zod.z.string()
105
+ }).passthrough()
106
+ })
107
+ });
108
+ var ZodEvent = import_zod.z.discriminatedUnion("event", [
109
+ ZodEventInitialStorage,
110
+ ZodEventRoomDeleted,
111
+ ZodEventUserConnected,
112
+ ZodEventUserDisconnected
113
+ ]);
114
+ var ZodInitialStorageResponse = import_zod.z.object({
115
+ event: import_zod.z.literal("initial-storage"),
116
+ room: import_zod.z.string(),
117
+ storage: import_zod.z.string().nullable()
118
+ });
119
+ var ZodRoomDeletedResponse = import_zod.z.object({
120
+ event: import_zod.z.literal("room-deleted"),
121
+ room: import_zod.z.string()
122
+ });
123
+ var ZodUserConnectedResponse = import_zod.z.object({
124
+ event: import_zod.z.literal("user-connected"),
125
+ room: import_zod.z.string()
126
+ });
127
+ var ZodUserDisconnectedResponse = import_zod.z.object({
128
+ event: import_zod.z.literal("user-disconnected"),
129
+ room: import_zod.z.string()
130
+ });
131
+ var ZodEventResponse = import_zod.z.discriminatedUnion("event", [
132
+ ZodInitialStorageResponse,
133
+ ZodRoomDeletedResponse,
134
+ ZodUserConnectedResponse,
135
+ ZodUserDisconnectedResponse
136
+ ]);
137
+
138
+ // src/shared/createErrorResponse.ts
139
+ var createErrorResponse = (c, error, status) => {
140
+ return c.json({ ok: false, error: { message: error.message } }, status);
141
+ };
142
+
143
+ // src/shared/getCrypto.ts
144
+ var getCrypto = () => {
145
+ if (typeof crypto !== "undefined") {
146
+ return crypto;
147
+ }
148
+ if (typeof require === "function") {
149
+ return require("crypto").webcrypto;
150
+ }
151
+ throw new Error("Missing crypto module");
152
+ };
153
+
154
+ // src/shared/createHmac.ts
155
+ var createHmac = (params) => __async(null, null, function* () {
156
+ const { payload, secret } = params;
157
+ if (!payload || !secret) throw new Error("Secret and payload are required to sign payload");
158
+ const encoder = new TextEncoder();
159
+ const keyBytes = encoder.encode(secret);
160
+ const crypto2 = getCrypto();
161
+ const algorithm = { name: "HMAC", hash: { name: "SHA-256" } };
162
+ const extractable = false;
163
+ const key = yield crypto2.subtle.importKey("raw", keyBytes, algorithm, extractable, [
164
+ "sign",
165
+ "verify"
166
+ ]);
167
+ const payloadBytes = encoder.encode(payload);
168
+ const signature = yield crypto2.subtle.sign("HMAC", key, payloadBytes);
169
+ const hmac = Array.from(new Uint8Array(signature)).map((b) => ("0" + b.toString(16)).slice(-2)).join("");
170
+ return { algorithm: "sha256", hmac };
171
+ });
172
+
173
+ // src/shared/createSuccessResponse.ts
174
+ var createSuccessResponse = (c, data, status = 200) => {
175
+ return c.json(
176
+ {
177
+ ok: true,
178
+ data: ZodEventResponse.parse(data)
179
+ },
180
+ status
181
+ );
182
+ };
183
+
184
+ // src/shared/HttpError.ts
185
+ var HttpError = class extends Error {
186
+ constructor(message, status) {
187
+ super(message);
188
+ this.status = status;
189
+ }
190
+ };
191
+
192
+ // src/shared/timingSafeEqual.ts
193
+ var timingSafeEqual = (a, b) => {
194
+ if (a.length !== b.length) return false;
195
+ let result = 0;
196
+ for (let i = 0; i < a.length; i++) {
197
+ result |= a[i] ^ b[i];
198
+ }
199
+ return result === 0;
200
+ };
201
+
202
+ // src/shared/verifyWebhook.ts
203
+ var verifyWebhook = (params) => __async(null, null, function* () {
204
+ const { payload, secret, signature } = params;
205
+ if (!secret || !payload || !signature) {
206
+ throw new Error("Secret, payload and signature are required to verify payload");
207
+ }
208
+ const { hmac } = yield createHmac({ payload, secret });
209
+ if (hmac.length !== signature.length) return false;
210
+ const encoder = new TextEncoder();
211
+ const verificationBytes = encoder.encode(hmac);
212
+ const signatureBytes = encoder.encode(signature);
213
+ if (verificationBytes.length !== signatureBytes.length) return false;
214
+ return timingSafeEqual(verificationBytes, signatureBytes);
215
+ });
216
+
217
+ // src/PluvPlatform.ts
218
+ var PluvPlatform = class extends import_io.AbstractPlatform {
219
+ constructor(params) {
220
+ var _a, _b;
221
+ super();
222
+ this.id = Math.random().toString();
223
+ this._config = {
224
+ authorize: {
225
+ secret: false
226
+ },
227
+ handleMode: "fetch",
228
+ registrationMode: "attached",
229
+ requireAuth: true,
230
+ listeners: {
231
+ onRoomDeleted: true,
232
+ onRoomMessage: false,
233
+ onStorageUpdated: false,
234
+ onUserConnected: true,
235
+ onUserDisconnected: true
236
+ },
237
+ router: false
238
+ };
239
+ this._name = "platformPluv";
240
+ this._createToken = (params) => __async(this, null, function* () {
241
+ var _a, _b;
242
+ const parsed = params.authorize.user.parse(params.user);
243
+ const [endpoints, publicKey, secretKey] = yield Promise.all([
244
+ typeof this._endpoints === "object" ? this._endpoints : this._endpoints(),
245
+ typeof this._publicKey === "string" ? this._publicKey : this._publicKey(),
246
+ typeof this._secretKey === "string" ? this._secretKey : this._secretKey()
247
+ ]);
248
+ this._logDebug({ endpoints, publicKey, secretKey });
249
+ const res = yield fetch(endpoints.createToken, {
250
+ headers: { "content-type": "application/json" },
251
+ method: "post",
252
+ body: JSON.stringify({
253
+ maxAge: (_a = params.maxAge) != null ? _a : null,
254
+ publicKey,
255
+ room: params.room,
256
+ secretKey,
257
+ user: parsed
258
+ })
259
+ }).catch((error) => {
260
+ this._logDebug(error);
261
+ return null;
262
+ });
263
+ this._logDebug({ response: { status: (_b = res == null ? void 0 : res.status) != null ? _b : null } });
264
+ if (!res || !res.ok || res.status !== 200) {
265
+ throw new Error("Authorization failed");
266
+ }
267
+ const token = yield res.text().catch(() => null);
268
+ this._logDebug({ token });
269
+ if (typeof token !== "string") throw new Error("Authorization failed");
270
+ return token;
271
+ });
272
+ this._webhooksRouter = new import_hono.Hono().basePath("/").post("/", (c) => __async(this, null, function* () {
273
+ var _a, _b, _c, _d, _e, _f, _g;
274
+ const [algorithm, signature] = (_b = (_a = c.req.header(SIGNATURE_HEADER)) == null ? void 0 : _a.split("=")) != null ? _b : [];
275
+ try {
276
+ if (!this._webhookSecret) throw new HttpError("Unauthorized", 401);
277
+ if (algorithm !== SIGNATURE_ALGORITHM) throw new HttpError("Unauthorized", 401);
278
+ if (!signature) throw new HttpError("Unauthorized", 401);
279
+ const [payload, webhookSecret] = yield Promise.all([
280
+ c.req.json(),
281
+ typeof this._webhookSecret === "string" ? this._webhookSecret : yield this._webhookSecret()
282
+ ]);
283
+ const verified = yield verifyWebhook({
284
+ payload: (0, import_fast_json_stable_stringify.default)(payload),
285
+ signature,
286
+ secret: webhookSecret
287
+ });
288
+ if (!verified) throw new HttpError("Unauthorized", 401);
289
+ const parsed = ZodEvent.safeParse(payload);
290
+ if (!parsed.success) throw new HttpError("Invalid request", 400);
291
+ const { event, data } = parsed.data;
292
+ const context = this._context;
293
+ switch (event) {
294
+ case "initial-storage": {
295
+ const room = data.room;
296
+ const storage = typeof room === "string" ? (_d = yield (_c = this._getInitialStorage) == null ? void 0 : _c.call(this, { context, room })) != null ? _d : null : null;
297
+ return createSuccessResponse(c, { event, room, storage });
298
+ }
299
+ case "room-deleted": {
300
+ const room = data.room;
301
+ const encodedState = data.storage;
302
+ yield Promise.resolve(
303
+ (_e = this._listeners) == null ? void 0 : _e.onRoomDeleted({ context, encodedState, room })
304
+ );
305
+ return createSuccessResponse(c, { event, room });
306
+ }
307
+ case "user-connected": {
308
+ const room = data.room;
309
+ const encodedState = data.storage;
310
+ const user = data.user;
311
+ yield Promise.resolve(
312
+ (_f = this._listeners) == null ? void 0 : _f.onUserConnected({
313
+ context,
314
+ encodedState,
315
+ platform: this,
316
+ room,
317
+ user
318
+ })
319
+ );
320
+ return createSuccessResponse(c, { event, room });
321
+ }
322
+ case "user-disconnected": {
323
+ const room = data.room;
324
+ const encodedState = data.storage;
325
+ const user = data.user;
326
+ yield Promise.resolve(
327
+ (_g = this._listeners) == null ? void 0 : _g.onUserDisconnected({
328
+ context,
329
+ encodedState,
330
+ platform: this,
331
+ room,
332
+ user
333
+ })
334
+ );
335
+ return createSuccessResponse(c, { event, room });
336
+ }
337
+ default: {
338
+ throw new HttpError("Unknown event", 400);
339
+ }
340
+ }
341
+ } catch (error) {
342
+ const message = error instanceof Error ? error.message : "Unexpected error";
343
+ const status = error instanceof HttpError ? error.status : 500;
344
+ return createErrorResponse(c, { message }, status);
345
+ }
346
+ }));
347
+ const { _defs, basePath, context, publicKey, secretKey, webhookSecret } = params;
348
+ this._basePath = basePath;
349
+ this._context = typeof context === "function" ? context(this._roomContext) : context;
350
+ this._debug = (_a = _defs == null ? void 0 : _defs.debug) != null ? _a : false;
351
+ this._endpoints = (_b = _defs == null ? void 0 : _defs.endpoints) != null ? _b : {
352
+ createToken: "https://rooms.pluv.io/api/room/token"
353
+ };
354
+ this._publicKey = publicKey;
355
+ this._secretKey = secretKey;
356
+ this._webhookSecret = webhookSecret;
357
+ this._app = new import_hono.Hono().basePath(this._basePath).route("/", this._webhooksRouter);
358
+ this._fetch = this._app.fetch;
359
+ }
360
+ acceptWebSocket(webSocket) {
361
+ throw new Error("Not implemented");
362
+ }
363
+ convertWebSocket(webSocket, config) {
364
+ throw new Error("Not implemented");
365
+ }
366
+ getLastPing(webSocket) {
367
+ throw new Error("Not implemented");
368
+ }
369
+ getSerializedState(webSocket) {
370
+ throw new Error("Not implemented");
371
+ }
372
+ getSessionId(webSocket) {
373
+ throw new Error("Not implemented");
374
+ }
375
+ getWebSockets() {
376
+ throw new Error("Not implemented");
377
+ }
378
+ initialize(config) {
379
+ throw new Error("Not implemented");
380
+ }
381
+ parseData(data) {
382
+ throw new Error("Not implemented");
383
+ }
384
+ randomUUID() {
385
+ throw new Error("Not implemented");
386
+ }
387
+ setSerializedState(webSocket, state) {
388
+ throw new Error("Not implemented");
389
+ }
390
+ validateConfig(config) {
391
+ if (!config.authorize)
392
+ throw new Error("Config `authorize` must be provided to `platformPluv`");
393
+ if (!!config.onRoomMessage)
394
+ throw new Error("Config `onRoomMessage` is not supported on `platformPluv`");
395
+ if (!!config.onStorageUpdated)
396
+ throw new Error("Config `onStorageUpdated` is not supported on `platformPluv`");
397
+ this._getInitialStorage = config.getInitialStorage;
398
+ this._listeners = {
399
+ onRoomDeleted: (event) => {
400
+ var _a;
401
+ return (_a = config.onRoomDeleted) == null ? void 0 : _a.call(config, event);
402
+ },
403
+ onUserConnected: (event) => {
404
+ var _a;
405
+ return (_a = config.onUserConnected) == null ? void 0 : _a.call(config, event);
406
+ },
407
+ onUserDisconnected: (event) => {
408
+ var _a;
409
+ return (_a = config.onUserDisconnected) == null ? void 0 : _a.call(config, event);
410
+ }
411
+ };
412
+ }
413
+ _logDebug(...args) {
414
+ if (!this._debug) return;
415
+ console.log("[PLATFORM PLUV]", ...args);
416
+ }
417
+ };
418
+
419
+ // src/platformPluv.ts
420
+ var platformPluv = (config) => {
421
+ const { authorize, context, crdt, debug } = config;
422
+ return {
423
+ authorize,
424
+ context,
425
+ crdt,
426
+ debug,
427
+ platform: () => new PluvPlatform(config)
428
+ };
429
+ };
430
+ // Annotate the CommonJS export names for ESM import in node:
431
+ 0 && (module.exports = {
432
+ PluvPlatform,
433
+ platformPluv
434
+ });