@pluv/io 2.1.0 → 2.2.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/dist/index.mjs CHANGED
@@ -613,6 +613,7 @@ var IORoom = class {
613
613
  this._listeners.onUserDisconnected({
614
614
  context: this._context,
615
615
  encodedState,
616
+ platform: this._platform,
616
617
  room: this.id,
617
618
  user
618
619
  })
@@ -670,6 +671,7 @@ var IORoom = class {
670
671
  this._listeners.onUserConnected({
671
672
  context: this._context,
672
673
  encodedState,
674
+ platform: this._platform,
673
675
  room: this.id,
674
676
  user,
675
677
  webSocket: pluvWs.webSocket
@@ -833,6 +835,7 @@ var IORoom = class {
833
835
  this._listeners.onDestroy(__spreadProps(__spreadValues({}, "_meta" in this._platform && !!this._platform._meta ? { _meta: this._platform._meta } : {}), {
834
836
  context: this._context,
835
837
  encodedState,
838
+ platform: this._platform,
836
839
  room: this.id
837
840
  }))
838
841
  );
@@ -871,6 +874,7 @@ var IORoom = class {
871
874
  garbageCollect: () => __async(this, null, function* () {
872
875
  yield this.garbageCollect();
873
876
  }),
877
+ platform: this._platform,
874
878
  get presence() {
875
879
  return session.presence;
876
880
  },
@@ -897,6 +901,7 @@ var IORoom = class {
897
901
  context: this._context,
898
902
  encodedState: doc.getEncodedState(),
899
903
  message,
904
+ platform: this._platform,
900
905
  room: this.id,
901
906
  user: session.user,
902
907
  webSocket: session.webSocket.webSocket
@@ -1063,6 +1068,7 @@ var IORoom = class {
1063
1068
  garbageCollect: () => __async(this, null, function* () {
1064
1069
  yield this.garbageCollect();
1065
1070
  }),
1071
+ platform: this._platform,
1066
1072
  get presence() {
1067
1073
  return null;
1068
1074
  },
@@ -1114,14 +1120,56 @@ var pickBy = (obj, by) => {
1114
1120
  };
1115
1121
 
1116
1122
  // src/version.generated.ts
1117
- var version = "2.1.0";
1123
+ var version = "2.2.1";
1118
1124
 
1119
1125
  // src/PluvServer.ts
1120
1126
  var PluvServer = class {
1121
1127
  constructor(options) {
1122
1128
  this.version = version;
1123
- this._authorize = null;
1124
- this._baseRouter = new PluvRouter({
1129
+ this._config = __spreadValues({
1130
+ crdt: noop2,
1131
+ debug: false,
1132
+ router: new PluvRouter({})
1133
+ }, options);
1134
+ const {
1135
+ onRoomDeleted,
1136
+ onRoomMessage,
1137
+ onStorageUpdated,
1138
+ onUserConnected,
1139
+ onUserDisconnected
1140
+ } = options;
1141
+ this._listeners = {
1142
+ onRoomDeleted: (event) => onRoomDeleted == null ? void 0 : onRoomDeleted(event),
1143
+ onRoomMessage: (event) => onRoomMessage == null ? void 0 : onRoomMessage(event),
1144
+ onStorageUpdated: (event) => onStorageUpdated == null ? void 0 : onStorageUpdated(event),
1145
+ onUserConnected: (event) => onUserConnected == null ? void 0 : onUserConnected(event),
1146
+ onUserDisconnected: (event) => onUserDisconnected == null ? void 0 : onUserDisconnected(event)
1147
+ };
1148
+ }
1149
+ get fetch() {
1150
+ const platform = this._config.platform();
1151
+ return (...args) => {
1152
+ if (!platform._fetch)
1153
+ throw new Error(`\`${platform._name}\` does not support \`fetch\``);
1154
+ return platform._fetch(...args);
1155
+ };
1156
+ }
1157
+ /**
1158
+ * @ignore
1159
+ * @readonly
1160
+ * @deprecated Internal use only. Changes to this will never be marked as breaking.
1161
+ */
1162
+ get _defs() {
1163
+ return {
1164
+ authorize: this._config.authorize,
1165
+ context: this._config.context,
1166
+ events: this._router._defs.events,
1167
+ platform: this._config.platform()
1168
+ };
1169
+ }
1170
+ get _baseRouter() {
1171
+ const listeners = this._getListeners();
1172
+ return new PluvRouter({
1125
1173
  $getOthers: this._procedure.sync((data, { room, session, sessions }) => {
1126
1174
  const currentTime = Date.now();
1127
1175
  const others = sessions.filter((wsSession) => {
@@ -1156,46 +1204,54 @@ var PluvServer = class {
1156
1204
  timers: { presence: timers.presence }
1157
1205
  }
1158
1206
  };
1159
- }).self((_0, _1) => __async(this, [_0, _1], function* (data, { context, doc, room, session }) {
1160
- var _a;
1161
- const oldState = yield this._platform.persistence.getStorageState(room);
1207
+ }).self((_0, _1) => __async(this, [_0, _1], function* (data, { context, doc, platform, room, session }) {
1208
+ var _a, _b;
1209
+ const oldState = yield platform.persistence.getStorageState(room);
1162
1210
  const update = data == null ? void 0 : data.update;
1163
1211
  if (!oldState) {
1164
- const loadedState = yield (_a = this._getInitialStorage) == null ? void 0 : _a.call(this, { context, room });
1212
+ const loadedState = yield (_b = (_a = this._config).getInitialStorage) == null ? void 0 : _b.call(_a, {
1213
+ context,
1214
+ room
1215
+ });
1165
1216
  if (!!loadedState) {
1166
1217
  doc.applyEncodedState({ update: loadedState }).getEncodedState();
1167
1218
  }
1168
1219
  }
1169
1220
  if (!doc.isEmpty()) {
1170
1221
  const encodedState2 = doc.getEncodedState();
1171
- return { $storageReceived: { changeKind: "unchanged", state: encodedState2 } };
1222
+ return {
1223
+ $storageReceived: { changeKind: "unchanged", state: encodedState2 }
1224
+ };
1172
1225
  }
1173
1226
  if (!!update) {
1174
1227
  const encodedState2 = doc.applyEncodedState({ update }).getEncodedState();
1175
1228
  const storageSize = new TextEncoder().encode(encodedState2).length;
1176
- if (!!this._limits.storageMaxSize && storageSize > this._limits.storageMaxSize) {
1229
+ if (!!this._config.limits.storageMaxSize && storageSize > this._config.limits.storageMaxSize) {
1177
1230
  throw new Error("Storage has exceeded the size limit");
1178
1231
  }
1179
- yield this._platform.persistence.setStorageState(room, encodedState2).catch((error) => {
1232
+ yield platform.persistence.setStorageState(room, encodedState2).catch((error) => {
1180
1233
  this._logDebug(error);
1181
1234
  });
1182
- this._getListeners().onStorageUpdated({
1235
+ listeners.onStorageUpdated({
1183
1236
  context,
1184
1237
  encodedState: encodedState2,
1238
+ platform,
1185
1239
  room,
1186
1240
  user: session == null ? void 0 : session.user,
1187
1241
  webSocket: session == null ? void 0 : session.webSocket.webSocket
1188
1242
  });
1189
- return { $storageReceived: { changeKind: "initialized", state: encodedState2 } };
1243
+ return {
1244
+ $storageReceived: { changeKind: "initialized", state: encodedState2 }
1245
+ };
1190
1246
  }
1191
1247
  const encodedState = doc.getEncodedState();
1192
1248
  return { $storageReceived: { changeKind: "empty", state: encodedState } };
1193
1249
  })),
1194
- $ping: this._procedure.self((data, { session }) => {
1250
+ $ping: this._procedure.self((data, { platform, session }) => {
1195
1251
  if (!session) return {};
1196
1252
  const currentTime = (/* @__PURE__ */ new Date()).getTime();
1197
1253
  const prevState = session.webSocket.state;
1198
- this._platform.setSerializedState(session.webSocket, __spreadProps(__spreadValues({}, prevState), {
1254
+ platform.setSerializedState(session.webSocket, __spreadProps(__spreadValues({}, prevState), {
1199
1255
  timers: __spreadProps(__spreadValues({}, prevState.timers), {
1200
1256
  ping: currentTime
1201
1257
  })
@@ -1206,10 +1262,13 @@ var PluvServer = class {
1206
1262
  const presence = data == null ? void 0 : data.presence;
1207
1263
  const { session } = context;
1208
1264
  if (!session) return {};
1209
- const cleanedPatch = pickBy(presence != null ? presence : {}, (value) => typeof value !== "undefined");
1265
+ const cleanedPatch = pickBy(
1266
+ presence != null ? presence : {},
1267
+ (value) => typeof value !== "undefined"
1268
+ );
1210
1269
  const updated = Object.assign(/* @__PURE__ */ Object.create(null), session.presence, cleanedPatch);
1211
1270
  const bytes = new TextEncoder().encode(JSON.stringify(updated)).length;
1212
- if (!!this._limits.presenceMaxSize && bytes > this._limits.presenceMaxSize) {
1271
+ if (!!this._config.limits.presenceMaxSize && bytes > this._config.limits.presenceMaxSize) {
1213
1272
  throw new Error(
1214
1273
  `Large presence. Presence must be at most 512 bytes. Current size: ${bytes.toLocaleString()}`
1215
1274
  );
@@ -1222,7 +1281,7 @@ var PluvServer = class {
1222
1281
  }
1223
1282
  };
1224
1283
  }),
1225
- $updateStorage: this._procedure.broadcast((data, { context, doc, room }) => {
1284
+ $updateStorage: this._procedure.broadcast((data, { context, doc, platform, room }) => {
1226
1285
  var _a;
1227
1286
  const origin = data == null ? void 0 : data.origin;
1228
1287
  const update = (_a = data == null ? void 0 : data.update) != null ? _a : null;
@@ -1230,113 +1289,72 @@ var PluvServer = class {
1230
1289
  const updated = update === null ? doc : doc.applyEncodedState({ update });
1231
1290
  const encodedState = updated.getEncodedState();
1232
1291
  const storageSize = new TextEncoder().encode(encodedState).length;
1233
- if (!!this._limits.storageMaxSize && storageSize > this._limits.storageMaxSize) {
1292
+ if (!!this._config.limits.storageMaxSize && storageSize > this._config.limits.storageMaxSize) {
1234
1293
  throw new Error("Storage has exceeded the size limit");
1235
1294
  }
1236
- this._platform.persistence.setStorageState(room, encodedState).then(() => {
1237
- this._getListeners().onStorageUpdated({
1295
+ platform.persistence.setStorageState(room, encodedState).then(() => {
1296
+ listeners.onStorageUpdated({
1238
1297
  context,
1239
1298
  encodedState,
1299
+ platform,
1240
1300
  room
1241
1301
  });
1242
1302
  });
1243
1303
  return { $storageUpdated: { state: encodedState } };
1244
1304
  })
1245
1305
  });
1246
- this._context = {};
1247
- this._getInitialStorage = null;
1248
- const {
1249
- authorize: authorize2,
1250
- context,
1251
- crdt = noop2,
1252
- debug = false,
1253
- getInitialStorage,
1254
- io,
1255
- limits,
1256
- platform,
1257
- router = new PluvRouter({})
1258
- } = options;
1259
- const {
1260
- onRoomDeleted,
1261
- onRoomMessage,
1262
- onStorageUpdated,
1263
- onUserConnected,
1264
- onUserDisconnected
1265
- } = options;
1266
- platform.validateConfig(options);
1267
- this._crdt = crdt;
1268
- this._debug = debug;
1269
- this._io = io;
1270
- this._limits = limits;
1271
- this._platform = platform;
1272
- this._router = router ? PluvRouter.merge(this._baseRouter, router) : this._baseRouter;
1273
- if (authorize2) this._authorize = authorize2;
1274
- if (context) this._context = context;
1275
- if (getInitialStorage) this._getInitialStorage = getInitialStorage;
1276
- this._listeners = {
1277
- onRoomDeleted: (event) => onRoomDeleted == null ? void 0 : onRoomDeleted(event),
1278
- onRoomMessage: (event) => onRoomMessage == null ? void 0 : onRoomMessage(event),
1279
- onStorageUpdated: (event) => onStorageUpdated == null ? void 0 : onStorageUpdated(event),
1280
- onUserConnected: (event) => onUserConnected == null ? void 0 : onUserConnected(event),
1281
- onUserDisconnected: (event) => onUserDisconnected == null ? void 0 : onUserDisconnected(event)
1282
- };
1283
- }
1284
- get fetch() {
1285
- return (...args) => {
1286
- if (!this._platform._fetch)
1287
- throw new Error(`\`${this._platform._name}\` does not support \`fetch\``);
1288
- return this._platform._fetch(...args);
1289
- };
1290
- }
1291
- /**
1292
- * @ignore
1293
- * @readonly
1294
- * @deprecated Internal use only. Changes to this will never be marked as breaking.
1295
- */
1296
- get _defs() {
1297
- return {
1298
- authorize: this._authorize,
1299
- context: this._context,
1300
- events: this._router._defs.events,
1301
- platform: this._platform
1302
- };
1303
1306
  }
1304
1307
  get _procedure() {
1305
1308
  return new PluvProcedure();
1306
1309
  }
1310
+ get _router() {
1311
+ return this._config.router ? PluvRouter.merge(this._baseRouter, this._config.router) : this._baseRouter;
1312
+ }
1307
1313
  createRoom(room, ...options) {
1308
1314
  var _a, _c;
1309
1315
  const _b = (_a = options[0]) != null ? _a : {}, { _meta, debug, onDestroy, onMessage } = _b, platformRoomContext = __objRest(_b, ["_meta", "debug", "onDestroy", "onMessage"]);
1310
- if (this._platform._config.handleMode !== "io") {
1311
- throw new Error(`\`createRoom\` is unsupported for \`${this._platform._name}\``);
1316
+ const platform = this._config.platform();
1317
+ platform.validateConfig(this._config);
1318
+ if (platform._config.handleMode !== "io") {
1319
+ throw new Error(`\`createRoom\` is unsupported for \`${platform._name}\``);
1312
1320
  }
1313
1321
  if (!/^[a-z0-9](?:[a-z0-9-_]*[a-z0-9])?$/i.test(room))
1314
1322
  throw new Error("Unsupported room name");
1315
1323
  const roomContext = platformRoomContext;
1316
- const context = typeof this._context === "function" ? this._context(roomContext) : this._context;
1324
+ const context = typeof this._config.context === "function" ? this._config.context(roomContext) : this._config.context;
1325
+ const listeners = this._getListeners();
1326
+ const logDebug = this._logDebug.bind(this);
1317
1327
  const newRoom = new IORoom(room, __spreadProps(__spreadValues({}, !!_meta ? { _meta } : {}), {
1318
- authorize: (_c = this._authorize) != null ? _c : void 0,
1328
+ authorize: (_c = this._config.authorize) != null ? _c : void 0,
1319
1329
  context,
1320
- crdt: this._crdt,
1321
- debug: debug != null ? debug : this._debug,
1322
- onDestroy: (event) => __async(this, null, function* () {
1323
- this._logDebug(`${colors2.blue("Deleting empty room:")} ${room}`);
1324
- yield Promise.resolve(onDestroy == null ? void 0 : onDestroy(event));
1325
- yield Promise.resolve(this._getListeners().onRoomDeleted(event));
1326
- yield this._platform.persistence.deleteStorageState(room);
1327
- this._logDebug(`${colors2.blue("Deleted room:")} ${room}`);
1328
- }),
1329
- onMessage: (event) => __async(this, null, function* () {
1330
- yield Promise.resolve(onMessage == null ? void 0 : onMessage(event));
1331
- yield Promise.resolve(this._getListeners().onRoomMessage(event));
1332
- }),
1333
- onUserConnected: (event) => __async(this, null, function* () {
1334
- yield Promise.resolve(this._getListeners().onUserConnected(event));
1335
- }),
1336
- onUserDisconnected: (event) => __async(this, null, function* () {
1337
- yield Promise.resolve(this._getListeners().onUserDisconnected(event));
1338
- }),
1339
- platform: this._platform,
1330
+ crdt: this._config.crdt,
1331
+ debug: debug != null ? debug : this._config.debug,
1332
+ onDestroy(event) {
1333
+ return __async(this, null, function* () {
1334
+ logDebug(`${colors2.blue("Deleting empty room:")} ${room}`);
1335
+ yield Promise.resolve(onDestroy == null ? void 0 : onDestroy(event));
1336
+ yield Promise.resolve(listeners.onRoomDeleted(event));
1337
+ yield event.platform.persistence.deleteStorageState(room);
1338
+ logDebug(`${colors2.blue("Deleted room:")} ${room}`);
1339
+ });
1340
+ },
1341
+ onMessage(event) {
1342
+ return __async(this, null, function* () {
1343
+ yield Promise.resolve(onMessage == null ? void 0 : onMessage(event));
1344
+ yield Promise.resolve(listeners.onRoomMessage(event));
1345
+ });
1346
+ },
1347
+ onUserConnected(event) {
1348
+ return __async(this, null, function* () {
1349
+ yield Promise.resolve(listeners.onUserConnected(event));
1350
+ });
1351
+ },
1352
+ onUserDisconnected(event) {
1353
+ return __async(this, null, function* () {
1354
+ yield Promise.resolve(listeners.onUserDisconnected(event));
1355
+ });
1356
+ },
1357
+ platform,
1340
1358
  roomContext,
1341
1359
  router: this._router
1342
1360
  }));
@@ -1345,14 +1363,14 @@ var PluvServer = class {
1345
1363
  }
1346
1364
  createToken(params) {
1347
1365
  return __async(this, null, function* () {
1348
- return yield this._io.createToken(params);
1366
+ return yield this._config.io.createToken(params);
1349
1367
  });
1350
1368
  }
1351
1369
  _getListeners() {
1352
1370
  return this._listeners;
1353
1371
  }
1354
1372
  _logDebug(...data) {
1355
- if (this._debug) console.log(...data);
1373
+ if (this._config.debug) console.log(...data);
1356
1374
  }
1357
1375
  };
1358
1376
 
@@ -1397,10 +1415,13 @@ var PluvIO = class {
1397
1415
  `createToken called with large payload. User must be at most 512 bytes. Current size: ${bytes.toLocaleString()}`
1398
1416
  );
1399
1417
  }
1400
- if (this._platform._createToken) return yield this._platform._createToken(params);
1418
+ const platform = this._platform();
1419
+ if (platform._createToken) {
1420
+ return yield platform._createToken(__spreadProps(__spreadValues({}, params), { authorize: ioAuthorize }));
1421
+ }
1401
1422
  const secret = (_a = ioAuthorize == null ? void 0 : ioAuthorize.secret) != null ? _a : null;
1402
1423
  if (!secret) throw new Error("`authorize` was specified without a valid secret");
1403
- return yield authorize({ platform: this._platform, secret }).encode(
1424
+ return yield authorize({ platform, secret }).encode(
1404
1425
  params
1405
1426
  );
1406
1427
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pluv/io",
3
- "version": "2.1.0",
3
+ "version": "2.2.1",
4
4
  "description": "@pluv/io server-side websocket manager",
5
5
  "author": "leedavidcs",
6
6
  "license": "MIT",
@@ -21,16 +21,16 @@
21
21
  "jose": "^5.10.0",
22
22
  "kleur": "^4.1.5",
23
23
  "wonka": "^6.3.5",
24
- "@pluv/crdt": "^2.1.0",
25
- "@pluv/types": "^2.1.0"
24
+ "@pluv/crdt": "^2.2.1",
25
+ "@pluv/types": "^2.2.1"
26
26
  },
27
27
  "devDependencies": {
28
28
  "eslint": "^9.26.0",
29
29
  "genversion": "^3.2.0",
30
30
  "tsup": "^8.4.0",
31
31
  "typescript": "^5.8.3",
32
- "@pluv/tsconfig": "^2.1.0",
33
- "eslint-config-pluv": "^2.1.0"
32
+ "@pluv/tsconfig": "^2.2.1",
33
+ "eslint-config-pluv": "^2.2.1"
34
34
  },
35
35
  "scripts": {
36
36
  "build": "pnpm run version && tsup src/index.ts --format esm,cjs --dts",
@@ -1,10 +1,11 @@
1
+ import type { Maybe } from "@pluv/types";
1
2
  import type { AbstractPersistence } from "./AbstractPersistence";
2
3
  import type { AbstractPubSub } from "./AbstractPubSub";
3
4
  import type { AbstractWebSocket, InferWebSocketSource } from "./AbstractWebSocket";
4
5
  import type { JWTEncodeParams } from "./authorize";
5
6
  import { Persistence } from "./Persistence";
6
7
  import { PubSub } from "./PubSub";
7
- import type { PlatformConfig, WebSocketSerializedState } from "./types";
8
+ import type { PlatformConfig, ResolvedPluvIOAuthorize, WebSocketSerializedState } from "./types";
8
9
 
9
10
  export type InferPlatformWebSocketType<TPlatform extends AbstractPlatform> =
10
11
  TPlatform extends AbstractPlatform<infer IAbstractWebSocket> ? IAbstractWebSocket : never;
@@ -44,7 +45,11 @@ export abstract class AbstractPlatform<
44
45
  public persistence: AbstractPersistence;
45
46
  public pubSub: AbstractPubSub;
46
47
 
47
- public readonly _createToken?: (params: JWTEncodeParams<any, any>) => Promise<string>;
48
+ public readonly _createToken?: (
49
+ params: JWTEncodeParams<any, any> & {
50
+ authorize: Maybe<ResolvedPluvIOAuthorize<any, any>>;
51
+ },
52
+ ) => Promise<string>;
48
53
  public _fetch?: (...args: any[]) => Promise<any>;
49
54
  public abstract readonly _config: TConfig;
50
55
  public abstract readonly _name: string;
package/src/IORoom.ts CHANGED
@@ -60,7 +60,7 @@ export interface IORoomListeners<
60
60
  TContext extends Record<string, any>,
61
61
  TEvents extends PluvRouterEventConfig<TPlatform, TAuthorize, TContext>,
62
62
  > {
63
- onDestroy: (event: IORoomListenerEvent<TContext>) => void;
63
+ onDestroy: (event: IORoomListenerEvent<TPlatform, TContext>) => void;
64
64
  onMessage: (event: IORoomMessageEvent<TPlatform, TAuthorize, TContext, TEvents>) => void;
65
65
  onUserConnected: (event: IOUserConnectedEvent<TPlatform, TAuthorize, TContext>) => void;
66
66
  onUserDisconnected: (event: IOUserDisconnectedEvent<TPlatform, TAuthorize, TContext>) => void;
@@ -87,7 +87,7 @@ export type IORoomConfig<
87
87
  > = Partial<IORoomListeners<TPlatform, TAuthorize, TContext, TEvents>> & {
88
88
  authorize?: TAuthorize;
89
89
  context: TContext;
90
- crdt?: { doc: (value: any) => AbstractCrdtDocFactory<any> };
90
+ crdt?: { doc: (value: any) => AbstractCrdtDocFactory<any, any> };
91
91
  debug: boolean;
92
92
  platform: TPlatform;
93
93
  roomContext: InferRoomContextType<TPlatform>;
@@ -124,14 +124,14 @@ export class IORoom<
124
124
  {
125
125
  public readonly id: string;
126
126
 
127
- private _doc: Promise<CrdtDocLike<any>>;
127
+ private _doc: Promise<CrdtDocLike<any, any>>;
128
128
  private _lastGarbageCollectMs: number = -1 * (GARBAGE_COLLECT_INTERVAL_MS + 1);
129
129
  private _uninitialize: Promise<() => Promise<void>> | null = null;
130
130
 
131
131
  private readonly _authorize: TAuthorize = null as TAuthorize;
132
132
  private readonly _context: TContext;
133
133
  private readonly _debug: boolean;
134
- private readonly _docFactory: AbstractCrdtDocFactory<any>;
134
+ private readonly _docFactory: AbstractCrdtDocFactory<any, any>;
135
135
  private readonly _listeners: IORoomListeners<TPlatform, TAuthorize, TContext, TEvents>;
136
136
  private readonly _platform: TPlatform;
137
137
  private readonly _router: PluvRouter<TPlatform, TAuthorize, TContext, TEvents>;
@@ -472,6 +472,7 @@ export class IORoom<
472
472
  this._listeners.onUserDisconnected({
473
473
  context: this._context,
474
474
  encodedState,
475
+ platform: this._platform,
475
476
  room: this.id,
476
477
  user,
477
478
  }),
@@ -538,6 +539,7 @@ export class IORoom<
538
539
  this._listeners.onUserConnected({
539
540
  context: this._context,
540
541
  encodedState,
542
+ platform: this._platform,
541
543
  room: this.id,
542
544
  user,
543
545
  webSocket: pluvWs.webSocket,
@@ -626,7 +628,7 @@ export class IORoom<
626
628
  }
627
629
  }
628
630
 
629
- private async _getInitialDoc(): Promise<CrdtDocLike<any>> {
631
+ private async _getInitialDoc(): Promise<CrdtDocLike<any, any>> {
630
632
  const doc = this._docFactory.getEmpty();
631
633
  const encodedState = await this._platform.persistence.getStorageState(this.id);
632
634
 
@@ -769,6 +771,7 @@ export class IORoom<
769
771
  : {}),
770
772
  context: this._context,
771
773
  encodedState,
774
+ platform: this._platform,
772
775
  room: this.id,
773
776
  }),
774
777
  );
@@ -825,6 +828,7 @@ export class IORoom<
825
828
  garbageCollect: async () => {
826
829
  await this.garbageCollect();
827
830
  },
831
+ platform: this._platform,
828
832
  get presence() {
829
833
  return session.presence as JsonObject | null;
830
834
  },
@@ -864,6 +868,7 @@ export class IORoom<
864
868
  InferEventsOutput<TEvents>,
865
869
  keyof InferEventsOutput<TEvents>
866
870
  >,
871
+ platform: this._platform,
867
872
  room: this.id,
868
873
  user: session.user,
869
874
  webSocket: session.webSocket.webSocket,
@@ -1105,6 +1110,7 @@ export class IORoom<
1105
1110
  garbageCollect: async () => {
1106
1111
  await this.garbageCollect();
1107
1112
  },
1113
+ platform: this._platform,
1108
1114
  get presence() {
1109
1115
  return null;
1110
1116
  },
package/src/PluvIO.ts CHANGED
@@ -37,7 +37,7 @@ export type PluvIOConfig<
37
37
  crdt?: CrdtLibraryType;
38
38
  debug?: boolean;
39
39
  limits?: PluvIOLimits;
40
- platform: TPlatform;
40
+ platform: () => TPlatform;
41
41
  };
42
42
 
43
43
  type ResolvedServerConfig<
@@ -90,10 +90,10 @@ export class PluvIO<
90
90
  TPlatform,
91
91
  TContext
92
92
  >;
93
- private readonly _crdt: { doc: (value: any) => AbstractCrdtDocFactory<any> };
93
+ private readonly _crdt: { doc: (value: any) => AbstractCrdtDocFactory<any, any> };
94
94
  private readonly _debug: boolean;
95
95
  private readonly _limits: PluvIOLimits;
96
- private readonly _platform: TPlatform;
96
+ private readonly _platform: () => TPlatform;
97
97
 
98
98
  public get procedure(): PluvProcedure<TPlatform, TAuthorize, TContext, {}, {}> {
99
99
  return new PluvProcedure();
@@ -141,19 +141,23 @@ export class PluvIO<
141
141
  );
142
142
  }
143
143
 
144
+ const platform = this._platform();
145
+
144
146
  /**
145
147
  * !HACK
146
148
  * @description Allow the platform to overwrite this behavior as needed. This is introduced
147
149
  * to support platformPluv
148
150
  * @date December 15, 2024
149
151
  */
150
- if (this._platform._createToken) return await this._platform._createToken(params as any);
152
+ if (platform._createToken) {
153
+ return await platform._createToken({ ...params, authorize: ioAuthorize });
154
+ }
151
155
 
152
156
  const secret = ioAuthorize?.secret ?? null;
153
157
 
154
158
  if (!secret) throw new Error("`authorize` was specified without a valid secret");
155
159
 
156
- return await authorize({ platform: this._platform, secret }).encode(
160
+ return await authorize({ platform, secret }).encode(
157
161
  params as JWTEncodeParams<any, TPlatform>,
158
162
  );
159
163
  }