@pluv/io 0.33.0 → 0.34.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/.turbo/turbo-build.log +9 -9
- package/CHANGELOG.md +20 -0
- package/dist/index.d.mts +99 -68
- package/dist/index.d.ts +99 -68
- package/dist/index.js +43 -37
- package/dist/index.mjs +40 -34
- package/package.json +5 -5
- package/src/AbstractPlatform.ts +9 -4
- package/src/IORoom.ts +20 -31
- package/src/PluvIO.ts +30 -13
- package/src/PluvProcedure.ts +12 -11
- package/src/PluvRouter.ts +5 -4
- package/src/PluvServer.ts +54 -30
- package/src/createIO.ts +15 -6
- package/src/index.ts +3 -1
- package/src/types.ts +82 -20
- package/src/version.generated.ts +1 -1
package/dist/index.mjs
CHANGED
|
@@ -182,6 +182,8 @@ var AbstractPlatform = class {
|
|
|
182
182
|
this.persistence = persistence != null ? persistence : new Persistence();
|
|
183
183
|
this.pubSub = pubSub != null ? pubSub : new PubSub();
|
|
184
184
|
}
|
|
185
|
+
validateConfig(config) {
|
|
186
|
+
}
|
|
185
187
|
_initialize() {
|
|
186
188
|
if (this._initialized) throw new Error("Platform is already initialized");
|
|
187
189
|
this._initialized = true;
|
|
@@ -511,7 +513,7 @@ var IORoom = class {
|
|
|
511
513
|
}
|
|
512
514
|
this._sessions.set(pluvWs.sessionId, pluvWs);
|
|
513
515
|
yield this._platform.persistence.addUser(this.id, pluvWs.sessionId, user != null ? user : {});
|
|
514
|
-
if (this._platform.
|
|
516
|
+
if (this._platform._config.registrationMode === "attached") {
|
|
515
517
|
const onClose = this._onClose(pluvWs).bind(this);
|
|
516
518
|
const onMessage = this._onMessage(pluvWs).bind(this);
|
|
517
519
|
pluvWs.addEventListener("close", onClose);
|
|
@@ -548,13 +550,7 @@ var IORoom = class {
|
|
|
548
550
|
this._sessions.delete(pluvWs.sessionId);
|
|
549
551
|
});
|
|
550
552
|
const promises = quitters.map((quitter) => __async(this, null, function* () {
|
|
551
|
-
yield this.
|
|
552
|
-
message: {
|
|
553
|
-
type: "$EXIT",
|
|
554
|
-
data: { sessionId: quitter.sessionId }
|
|
555
|
-
},
|
|
556
|
-
senderId: quitter.sessionId
|
|
557
|
-
});
|
|
553
|
+
yield this._exitWebsocket(quitter);
|
|
558
554
|
}));
|
|
559
555
|
yield Promise.all(promises);
|
|
560
556
|
});
|
|
@@ -582,7 +578,7 @@ var IORoom = class {
|
|
|
582
578
|
});
|
|
583
579
|
}
|
|
584
580
|
_ensureDetached() {
|
|
585
|
-
if (this._platform.
|
|
581
|
+
if (this._platform._config.registrationMode === "detached") return;
|
|
586
582
|
throw new Error("Platform must use detached mode");
|
|
587
583
|
}
|
|
588
584
|
_exitWebsocket(webSocket) {
|
|
@@ -627,6 +623,7 @@ var IORoom = class {
|
|
|
627
623
|
const ioAuthorize = this._getIOAuthorize(options);
|
|
628
624
|
if (!ioAuthorize) return null;
|
|
629
625
|
if (!token) return null;
|
|
626
|
+
if (!ioAuthorize.secret) throw new Error("`authorize` was specified without a valid secret");
|
|
630
627
|
const payload = yield authorize({
|
|
631
628
|
platform: this._platform,
|
|
632
629
|
secret: ioAuthorize.secret
|
|
@@ -753,13 +750,7 @@ var IORoom = class {
|
|
|
753
750
|
this._logDebug(`${colors.blue(`Unregistering connection for room ${this.id}:`)} ${webSocket.sessionId}`);
|
|
754
751
|
this._sessions.delete(webSocket.sessionId);
|
|
755
752
|
this._platform.persistence.deleteUser(this.id, webSocket.sessionId).finally(() => __async(this, null, function* () {
|
|
756
|
-
yield this.
|
|
757
|
-
message: {
|
|
758
|
-
type: "$EXIT",
|
|
759
|
-
data: { sessionId: webSocket.sessionId }
|
|
760
|
-
},
|
|
761
|
-
senderId: webSocket.sessionId
|
|
762
|
-
});
|
|
753
|
+
yield this._exitWebsocket(webSocket);
|
|
763
754
|
const size = this.getSize();
|
|
764
755
|
this._logDebug(`${colors.blue(`Unregistered connection for room ${this.id}:`)} ${webSocket.sessionId}`);
|
|
765
756
|
this._logDebug(`${colors.blue(`Room ${this.id} size:`)} ${size}`);
|
|
@@ -960,7 +951,7 @@ var IORoom = class {
|
|
|
960
951
|
};
|
|
961
952
|
|
|
962
953
|
// src/version.generated.ts
|
|
963
|
-
var version = "0.
|
|
954
|
+
var version = "0.34.1";
|
|
964
955
|
|
|
965
956
|
// src/PluvServer.ts
|
|
966
957
|
var PluvServer = class {
|
|
@@ -1064,14 +1055,11 @@ var PluvServer = class {
|
|
|
1064
1055
|
crdt = noop2,
|
|
1065
1056
|
debug = false,
|
|
1066
1057
|
getInitialStorage,
|
|
1067
|
-
onRoomDeleted,
|
|
1068
|
-
onRoomMessage,
|
|
1069
|
-
onStorageUpdated,
|
|
1070
|
-
onUserConnected,
|
|
1071
|
-
onUserDisconnected,
|
|
1072
1058
|
platform,
|
|
1073
1059
|
router = new PluvRouter({})
|
|
1074
1060
|
} = options;
|
|
1061
|
+
const { onRoomDeleted, onRoomMessage, onStorageUpdated, onUserConnected, onUserDisconnected } = options;
|
|
1062
|
+
platform.validateConfig(options);
|
|
1075
1063
|
this._crdt = crdt;
|
|
1076
1064
|
this._debug = debug;
|
|
1077
1065
|
this._platform = platform;
|
|
@@ -1087,6 +1075,10 @@ var PluvServer = class {
|
|
|
1087
1075
|
onUserDisconnected: (event) => onUserDisconnected == null ? void 0 : onUserDisconnected(event)
|
|
1088
1076
|
};
|
|
1089
1077
|
}
|
|
1078
|
+
get fetch() {
|
|
1079
|
+
if (!this._platform._fetch) throw new Error(`\`${this._platform._name}\` does not support \`fetch\``);
|
|
1080
|
+
return this._platform._fetch;
|
|
1081
|
+
}
|
|
1090
1082
|
/**
|
|
1091
1083
|
* @ignore
|
|
1092
1084
|
* @readonly
|
|
@@ -1106,6 +1098,9 @@ var PluvServer = class {
|
|
|
1106
1098
|
createRoom(room, ...options) {
|
|
1107
1099
|
var _a, _c;
|
|
1108
1100
|
const _b = (_a = options[0]) != null ? _a : {}, { _meta, debug, onDestroy, onMessage } = _b, platformRoomContext = __objRest(_b, ["_meta", "debug", "onDestroy", "onMessage"]);
|
|
1101
|
+
if (this._platform._config.handleMode !== "io") {
|
|
1102
|
+
throw new Error(`\`createRoom' is unsupported for \`${this._platform._name}\``);
|
|
1103
|
+
}
|
|
1109
1104
|
if (!/^[a-z0-9]+[a-z0-9\-_]+[a-z0-9]+$/i.test(room)) throw new Error("Unsupported room name");
|
|
1110
1105
|
const roomContext = platformRoomContext;
|
|
1111
1106
|
const context = typeof this._context === "function" ? this._context(roomContext) : this._context;
|
|
@@ -1140,17 +1135,23 @@ var PluvServer = class {
|
|
|
1140
1135
|
}
|
|
1141
1136
|
createToken(params) {
|
|
1142
1137
|
return __async(this, null, function* () {
|
|
1138
|
+
var _a;
|
|
1143
1139
|
if (!this._authorize) {
|
|
1144
1140
|
throw new Error("IO does not specify authorize during initialization.");
|
|
1145
1141
|
}
|
|
1146
|
-
|
|
1147
|
-
const
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
}).encode(params);
|
|
1142
|
+
if (this._platform._createToken) return yield this._platform._createToken(params);
|
|
1143
|
+
const ioAuthorize = this._getIOAuthorize(params);
|
|
1144
|
+
const secret = (_a = ioAuthorize == null ? void 0 : ioAuthorize.secret) != null ? _a : null;
|
|
1145
|
+
if (!secret) throw new Error("`authorize` was specified without a valid secret");
|
|
1146
|
+
return yield authorize({ platform: this._platform, secret }).encode(params);
|
|
1152
1147
|
});
|
|
1153
1148
|
}
|
|
1149
|
+
_getIOAuthorize(options) {
|
|
1150
|
+
if (typeof this._authorize === "function") {
|
|
1151
|
+
return this._authorize(options);
|
|
1152
|
+
}
|
|
1153
|
+
return this._authorize;
|
|
1154
|
+
}
|
|
1154
1155
|
_getListeners() {
|
|
1155
1156
|
return this._listeners;
|
|
1156
1157
|
}
|
|
@@ -1177,13 +1178,12 @@ var PluvIO = class {
|
|
|
1177
1178
|
}
|
|
1178
1179
|
createToken(params) {
|
|
1179
1180
|
return __async(this, null, function* () {
|
|
1181
|
+
var _a;
|
|
1180
1182
|
if (!this._authorize) throw new Error("IO does not specify authorize during initialization.");
|
|
1181
|
-
const ioAuthorize =
|
|
1182
|
-
const secret = ioAuthorize.secret;
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
secret
|
|
1186
|
-
}).encode(params);
|
|
1183
|
+
const ioAuthorize = this._getIOAuthorize(params);
|
|
1184
|
+
const secret = (_a = ioAuthorize == null ? void 0 : ioAuthorize.secret) != null ? _a : null;
|
|
1185
|
+
if (!secret) throw new Error("`authorize` was specified without a valid secret");
|
|
1186
|
+
return yield authorize({ platform: this._platform, secret }).encode(params);
|
|
1187
1187
|
});
|
|
1188
1188
|
}
|
|
1189
1189
|
mergeRouters(...routers) {
|
|
@@ -1202,6 +1202,12 @@ var PluvIO = class {
|
|
|
1202
1202
|
platform: this._platform
|
|
1203
1203
|
}));
|
|
1204
1204
|
}
|
|
1205
|
+
_getIOAuthorize(options) {
|
|
1206
|
+
if (typeof this._authorize === "function") {
|
|
1207
|
+
return this._authorize(options);
|
|
1208
|
+
}
|
|
1209
|
+
return this._authorize;
|
|
1210
|
+
}
|
|
1205
1211
|
};
|
|
1206
1212
|
|
|
1207
1213
|
// src/createIO.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pluv/io",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.34.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.9.6",
|
|
22
22
|
"kleur": "^4.1.5",
|
|
23
23
|
"wonka": "^6.3.4",
|
|
24
|
-
"@pluv/crdt": "^0.
|
|
25
|
-
"@pluv/types": "^0.
|
|
24
|
+
"@pluv/crdt": "^0.34.1",
|
|
25
|
+
"@pluv/types": "^0.34.1"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"eslint": "^8.57.1",
|
|
29
29
|
"genversion": "^3.2.0",
|
|
30
30
|
"tsup": "^8.3.5",
|
|
31
31
|
"typescript": "^5.7.2",
|
|
32
|
-
"@pluv/tsconfig": "^0.
|
|
33
|
-
"eslint-config-pluv": "^0.
|
|
32
|
+
"@pluv/tsconfig": "^0.34.1",
|
|
33
|
+
"eslint-config-pluv": "^0.34.1"
|
|
34
34
|
},
|
|
35
35
|
"scripts": {
|
|
36
36
|
"build": "pnpm run version && tsup src/index.ts --format esm,cjs --dts",
|
package/src/AbstractPlatform.ts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import type { AbstractPersistence } from "./AbstractPersistence";
|
|
2
2
|
import type { AbstractPubSub } from "./AbstractPubSub";
|
|
3
3
|
import type { AbstractWebSocket, InferWebSocketSource } from "./AbstractWebSocket";
|
|
4
|
+
import type { JWTEncodeParams } from "./authorize";
|
|
4
5
|
import { Persistence } from "./Persistence";
|
|
5
6
|
import { PubSub } from "./PubSub";
|
|
6
|
-
import type { WebSocketSerializedState } from "./types";
|
|
7
|
-
|
|
8
|
-
export type WebSocketRegistrationMode = "attached" | "detached";
|
|
7
|
+
import type { PlatformConfig, WebSocketSerializedState } from "./types";
|
|
9
8
|
|
|
10
9
|
export type InferPlatformWebSocketType<TPlatform extends AbstractPlatform> =
|
|
11
10
|
TPlatform extends AbstractPlatform<infer IAbstractWebSocket> ? IAbstractWebSocket : never;
|
|
@@ -33,6 +32,7 @@ export abstract class AbstractPlatform<
|
|
|
33
32
|
TWebSocket extends AbstractWebSocket = AbstractWebSocket,
|
|
34
33
|
TInitContext extends Record<string, any> = {},
|
|
35
34
|
TRoomContext extends Record<string, any> = {},
|
|
35
|
+
TConfig extends PlatformConfig = PlatformConfig,
|
|
36
36
|
> {
|
|
37
37
|
protected readonly _initContext: TInitContext | undefined;
|
|
38
38
|
protected readonly _roomContext: TRoomContext | undefined;
|
|
@@ -42,7 +42,10 @@ export abstract class AbstractPlatform<
|
|
|
42
42
|
public persistence: AbstractPersistence;
|
|
43
43
|
public pubSub: AbstractPubSub;
|
|
44
44
|
|
|
45
|
-
public
|
|
45
|
+
public readonly _createToken?: (params: JWTEncodeParams<any, any>) => Promise<string>;
|
|
46
|
+
public _fetch?: (req: any) => Promise<any>;
|
|
47
|
+
public abstract readonly _config: TConfig;
|
|
48
|
+
public abstract readonly _name: string;
|
|
46
49
|
|
|
47
50
|
constructor(config: AbstractPlatformConfig<TRoomContext> = {}) {
|
|
48
51
|
const { context, persistence, pubSub } = config;
|
|
@@ -77,6 +80,8 @@ export abstract class AbstractPlatform<
|
|
|
77
80
|
|
|
78
81
|
public abstract setSerializedState(webSocket: AbstractWebSocket, state: WebSocketSerializedState): void;
|
|
79
82
|
|
|
83
|
+
public validateConfig(config: any): void {}
|
|
84
|
+
|
|
80
85
|
protected _initialize(): this {
|
|
81
86
|
if (this._initialized) throw new Error("Platform is already initialized");
|
|
82
87
|
|
package/src/IORoom.ts
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import type { AbstractCrdtDoc, AbstractCrdtDocFactory } from "@pluv/crdt";
|
|
2
2
|
import { noop } from "@pluv/crdt";
|
|
3
3
|
import type {
|
|
4
|
-
BaseIOAuthorize,
|
|
5
4
|
BaseIOEventRecord,
|
|
6
5
|
EventMessage,
|
|
7
|
-
IOAuthorize,
|
|
8
6
|
IOEventMessage,
|
|
9
7
|
IOLike,
|
|
10
8
|
Id,
|
|
@@ -13,7 +11,6 @@ import type {
|
|
|
13
11
|
InferIOAuthorize,
|
|
14
12
|
InferIOAuthorizeUser,
|
|
15
13
|
InferIOInput,
|
|
16
|
-
InputZodLike,
|
|
17
14
|
JsonObject,
|
|
18
15
|
Maybe,
|
|
19
16
|
} from "@pluv/types";
|
|
@@ -24,16 +21,20 @@ import type {
|
|
|
24
21
|
InferPlatformWebSocketSource,
|
|
25
22
|
InferRoomContextType,
|
|
26
23
|
} from "./AbstractPlatform";
|
|
27
|
-
import { AbstractCloseEvent, AbstractErrorEvent, AbstractMessageEvent
|
|
24
|
+
import type { AbstractCloseEvent, AbstractErrorEvent, AbstractMessageEvent } from "./AbstractWebSocket";
|
|
25
|
+
import { AbstractWebSocket } from "./AbstractWebSocket";
|
|
28
26
|
import type { PluvRouter, PluvRouterEventConfig } from "./PluvRouter";
|
|
29
27
|
import { authorize } from "./authorize";
|
|
30
28
|
import { PING_TIMEOUT_MS } from "./constants";
|
|
31
29
|
import type {
|
|
32
30
|
EventResolverContext,
|
|
31
|
+
EventResolverKind,
|
|
33
32
|
IORoomListenerEvent,
|
|
34
33
|
IORoomMessageEvent,
|
|
35
34
|
IOUserConnectedEvent,
|
|
36
35
|
IOUserDisconnectedEvent,
|
|
36
|
+
PluvIOAuthorize,
|
|
37
|
+
ResolvedPluvIOAuthorize,
|
|
37
38
|
WebSocketSession,
|
|
38
39
|
WebSocketType,
|
|
39
40
|
} from "./types";
|
|
@@ -49,7 +50,7 @@ interface BroadcastParams<TIO extends IORoom<any, any, any, any>> {
|
|
|
49
50
|
|
|
50
51
|
export interface IORoomListeners<
|
|
51
52
|
TPlatform extends AbstractPlatform<any>,
|
|
52
|
-
TAuthorize extends
|
|
53
|
+
TAuthorize extends PluvIOAuthorize<TPlatform, any, any, InferInitContextType<TPlatform>>,
|
|
53
54
|
TContext extends Record<string, any>,
|
|
54
55
|
TEvents extends PluvRouterEventConfig<TPlatform, TAuthorize, TContext>,
|
|
55
56
|
> {
|
|
@@ -68,7 +69,7 @@ export type BroadcastProxy<TIO extends IORoom<any, any, any, any>> = (<TEvent ex
|
|
|
68
69
|
|
|
69
70
|
export type IORoomConfig<
|
|
70
71
|
TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>,
|
|
71
|
-
TAuthorize extends
|
|
72
|
+
TAuthorize extends PluvIOAuthorize<TPlatform, any, any, InferInitContextType<TPlatform>> = any,
|
|
72
73
|
TContext extends Record<string, any> = {},
|
|
73
74
|
TEvents extends PluvRouterEventConfig<TPlatform, TAuthorize, TContext> = {},
|
|
74
75
|
> = Partial<IORoomListeners<TPlatform, TAuthorize, TContext, TEvents>> & {
|
|
@@ -92,7 +93,7 @@ export type WebsocketRegisterConfig<TPlatform extends AbstractPlatform<any> = Ab
|
|
|
92
93
|
|
|
93
94
|
export class IORoom<
|
|
94
95
|
TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>,
|
|
95
|
-
TAuthorize extends
|
|
96
|
+
TAuthorize extends PluvIOAuthorize<TPlatform, any, any, InferInitContextType<TPlatform>> = any,
|
|
96
97
|
TContext extends Record<string, any> = {},
|
|
97
98
|
TEvents extends PluvRouterEventConfig<TPlatform, TAuthorize, TContext> = {},
|
|
98
99
|
> implements IOLike<TAuthorize, TEvents>
|
|
@@ -320,7 +321,7 @@ export class IORoom<
|
|
|
320
321
|
|
|
321
322
|
await this._platform.persistence.addUser(this.id, pluvWs.sessionId, user ?? {});
|
|
322
323
|
|
|
323
|
-
if (this._platform.
|
|
324
|
+
if (this._platform._config.registrationMode === "attached") {
|
|
324
325
|
const onClose = this._onClose(pluvWs).bind(this);
|
|
325
326
|
const onMessage = this._onMessage(pluvWs).bind(this);
|
|
326
327
|
|
|
@@ -364,13 +365,7 @@ export class IORoom<
|
|
|
364
365
|
});
|
|
365
366
|
|
|
366
367
|
const promises = quitters.map(async (quitter) => {
|
|
367
|
-
await this.
|
|
368
|
-
message: {
|
|
369
|
-
type: "$EXIT",
|
|
370
|
-
data: { sessionId: quitter.sessionId },
|
|
371
|
-
},
|
|
372
|
-
senderId: quitter.sessionId,
|
|
373
|
-
});
|
|
368
|
+
await this._exitWebsocket(quitter);
|
|
374
369
|
});
|
|
375
370
|
|
|
376
371
|
await Promise.all(promises);
|
|
@@ -400,7 +395,7 @@ export class IORoom<
|
|
|
400
395
|
}
|
|
401
396
|
|
|
402
397
|
private _ensureDetached(): void {
|
|
403
|
-
if (this._platform.
|
|
398
|
+
if (this._platform._config.registrationMode === "detached") return;
|
|
404
399
|
|
|
405
400
|
throw new Error("Platform must use detached mode");
|
|
406
401
|
}
|
|
@@ -456,6 +451,8 @@ export class IORoom<
|
|
|
456
451
|
if (!ioAuthorize) return null as InferIOAuthorizeUser<InferIOAuthorize<this>>;
|
|
457
452
|
if (!token) return null as InferIOAuthorizeUser<InferIOAuthorize<this>>;
|
|
458
453
|
|
|
454
|
+
if (!ioAuthorize.secret) throw new Error("`authorize` was specified without a valid secret");
|
|
455
|
+
|
|
459
456
|
const payload = await authorize({
|
|
460
457
|
platform: this._platform,
|
|
461
458
|
secret: ioAuthorize.secret,
|
|
@@ -494,16 +491,14 @@ export class IORoom<
|
|
|
494
491
|
return doc;
|
|
495
492
|
}
|
|
496
493
|
|
|
497
|
-
private _getIOAuthorize(
|
|
494
|
+
private _getIOAuthorize(
|
|
495
|
+
options: WebsocketRegisterConfig<TPlatform>,
|
|
496
|
+
): ResolvedPluvIOAuthorize<any, any, any> | null {
|
|
498
497
|
if (typeof this._authorize === "function") {
|
|
499
498
|
return this._authorize(options);
|
|
500
499
|
}
|
|
501
500
|
|
|
502
|
-
return this._authorize as
|
|
503
|
-
required: any;
|
|
504
|
-
secret: string;
|
|
505
|
-
user: InputZodLike<any>;
|
|
506
|
-
} | null;
|
|
501
|
+
return this._authorize as ResolvedPluvIOAuthorize<any, any, any> | null;
|
|
507
502
|
}
|
|
508
503
|
|
|
509
504
|
private _getProcedure(
|
|
@@ -619,13 +614,7 @@ export class IORoom<
|
|
|
619
614
|
this._sessions.delete(webSocket.sessionId);
|
|
620
615
|
|
|
621
616
|
this._platform.persistence.deleteUser(this.id, webSocket.sessionId).finally(async () => {
|
|
622
|
-
await this.
|
|
623
|
-
message: {
|
|
624
|
-
type: "$EXIT",
|
|
625
|
-
data: { sessionId: webSocket.sessionId },
|
|
626
|
-
},
|
|
627
|
-
senderId: webSocket.sessionId,
|
|
628
|
-
});
|
|
617
|
+
await this._exitWebsocket(webSocket);
|
|
629
618
|
|
|
630
619
|
const size = this.getSize();
|
|
631
620
|
|
|
@@ -656,7 +645,7 @@ export class IORoom<
|
|
|
656
645
|
]);
|
|
657
646
|
|
|
658
647
|
const doc = await this._doc;
|
|
659
|
-
const eventContext: EventResolverContext<TPlatform, TAuthorize, TContext> = {
|
|
648
|
+
const eventContext: EventResolverContext<EventResolverKind, TPlatform, TAuthorize, TContext> = {
|
|
660
649
|
context: this._context,
|
|
661
650
|
doc,
|
|
662
651
|
room: this.id,
|
|
@@ -841,7 +830,7 @@ export class IORoom<
|
|
|
841
830
|
if (!sender) return;
|
|
842
831
|
|
|
843
832
|
const doc = await this._doc;
|
|
844
|
-
const context: EventResolverContext<TPlatform, TAuthorize, TContext> = {
|
|
833
|
+
const context: EventResolverContext<"sync", TPlatform, TAuthorize, TContext> = {
|
|
845
834
|
context: this._context,
|
|
846
835
|
doc,
|
|
847
836
|
room: this.id,
|
package/src/PluvIO.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AbstractCrdtDocFactory } from "@pluv/crdt";
|
|
2
2
|
import { noop } from "@pluv/crdt";
|
|
3
|
-
import type {
|
|
3
|
+
import type { IOAuthorize, InferIOAuthorizeUser, InputZodLike } from "@pluv/types";
|
|
4
4
|
import type { AbstractPlatform, InferInitContextType } from "./AbstractPlatform";
|
|
5
5
|
import { PluvProcedure } from "./PluvProcedure";
|
|
6
6
|
import type { MergedRouter, PluvRouterEventConfig } from "./PluvRouter";
|
|
@@ -8,24 +8,34 @@ import { PluvRouter } from "./PluvRouter";
|
|
|
8
8
|
import { PluvServer } from "./PluvServer";
|
|
9
9
|
import type { JWTEncodeParams } from "./authorize";
|
|
10
10
|
import { authorize } from "./authorize";
|
|
11
|
-
import type {
|
|
11
|
+
import type {
|
|
12
|
+
CrdtLibraryType,
|
|
13
|
+
GetInitialStorageFn,
|
|
14
|
+
InferPlatformConfig,
|
|
15
|
+
PluvContext,
|
|
16
|
+
PluvIOAuthorize,
|
|
17
|
+
PluvIOListeners,
|
|
18
|
+
ResolvedPluvIOAuthorize,
|
|
19
|
+
} from "./types";
|
|
12
20
|
import { __PLUV_VERSION } from "./version";
|
|
21
|
+
import { WebsocketRegisterConfig } from "./IORoom";
|
|
13
22
|
|
|
14
23
|
export type PluvIOConfig<
|
|
15
24
|
TPlatform extends AbstractPlatform<any>,
|
|
16
25
|
TAuthorize extends IOAuthorize<any, any, InferInitContextType<TPlatform>>,
|
|
17
26
|
TContext extends Record<string, any>,
|
|
18
27
|
> = {
|
|
19
|
-
authorize?: TAuthorize;
|
|
20
28
|
context?: PluvContext<TPlatform, TContext>;
|
|
21
29
|
crdt?: CrdtLibraryType;
|
|
22
30
|
debug?: boolean;
|
|
23
31
|
platform: TPlatform;
|
|
24
|
-
}
|
|
32
|
+
} & (InferPlatformConfig<TPlatform>["requireAuth"] extends true
|
|
33
|
+
? { authorize: TAuthorize }
|
|
34
|
+
: { authorize?: TAuthorize });
|
|
25
35
|
|
|
26
36
|
export type ServerConfig<
|
|
27
37
|
TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>,
|
|
28
|
-
TAuthorize extends
|
|
38
|
+
TAuthorize extends PluvIOAuthorize<TPlatform, any, any, InferInitContextType<TPlatform>> = any,
|
|
29
39
|
TContext extends Record<string, any> = {},
|
|
30
40
|
TEvents extends PluvRouterEventConfig<TPlatform, TAuthorize, TContext> = {},
|
|
31
41
|
> = Partial<PluvIOListeners<TPlatform, TAuthorize, TContext, TEvents>> & {
|
|
@@ -35,7 +45,7 @@ export type ServerConfig<
|
|
|
35
45
|
|
|
36
46
|
export class PluvIO<
|
|
37
47
|
TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>,
|
|
38
|
-
TAuthorize extends
|
|
48
|
+
TAuthorize extends PluvIOAuthorize<TPlatform, any, any, InferInitContextType<TPlatform>> = any,
|
|
39
49
|
TContext extends Record<string, any> = {},
|
|
40
50
|
> {
|
|
41
51
|
public readonly version: string = __PLUV_VERSION as any;
|
|
@@ -64,15 +74,12 @@ export class PluvIO<
|
|
|
64
74
|
public async createToken(params: JWTEncodeParams<InferIOAuthorizeUser<TAuthorize>, TPlatform>): Promise<string> {
|
|
65
75
|
if (!this._authorize) throw new Error("IO does not specify authorize during initialization.");
|
|
66
76
|
|
|
67
|
-
const ioAuthorize =
|
|
68
|
-
|
|
77
|
+
const ioAuthorize = this._getIOAuthorize(params);
|
|
78
|
+
const secret = ioAuthorize?.secret ?? null;
|
|
69
79
|
|
|
70
|
-
|
|
80
|
+
if (!secret) throw new Error("`authorize` was specified without a valid secret");
|
|
71
81
|
|
|
72
|
-
return await authorize({
|
|
73
|
-
platform: this._platform,
|
|
74
|
-
secret,
|
|
75
|
-
}).encode(params);
|
|
82
|
+
return await authorize({ platform: this._platform, secret }).encode(params);
|
|
76
83
|
}
|
|
77
84
|
|
|
78
85
|
public mergeRouters<TRouters extends PluvRouter<TPlatform, TAuthorize, TContext, any>[]>(
|
|
@@ -99,4 +106,14 @@ export class PluvIO<
|
|
|
99
106
|
platform: this._platform,
|
|
100
107
|
});
|
|
101
108
|
}
|
|
109
|
+
|
|
110
|
+
private _getIOAuthorize(
|
|
111
|
+
options: WebsocketRegisterConfig<TPlatform>,
|
|
112
|
+
): ResolvedPluvIOAuthorize<any, any, any> | null {
|
|
113
|
+
if (typeof this._authorize === "function") {
|
|
114
|
+
return this._authorize(options);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return this._authorize as ResolvedPluvIOAuthorize<any, any, any> | null;
|
|
118
|
+
}
|
|
102
119
|
}
|
package/src/PluvProcedure.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { EventRecord, IOAuthorize, InputZodLike, JsonObject, ProcedureLike } from "@pluv/types";
|
|
2
2
|
import type { AbstractPlatform, InferInitContextType } from "./AbstractPlatform";
|
|
3
|
-
import type { EventResolver, MergeEventRecords } from "./types";
|
|
3
|
+
import type { EventResolver, EventResolverKind, MergeEventRecords } from "./types";
|
|
4
4
|
|
|
5
5
|
export interface PluvProcedureConfig<
|
|
6
6
|
TPlatform extends AbstractPlatform<any>,
|
|
@@ -9,10 +9,10 @@ export interface PluvProcedureConfig<
|
|
|
9
9
|
TInput extends JsonObject = {},
|
|
10
10
|
TOutput extends EventRecord<string, any> = {},
|
|
11
11
|
> {
|
|
12
|
-
broadcast?: EventResolver<TPlatform, TAuthorize, TContext, TInput, Partial<TOutput>> | null;
|
|
12
|
+
broadcast?: EventResolver<"broadcast", TPlatform, TAuthorize, TContext, TInput, Partial<TOutput>> | null;
|
|
13
13
|
input?: InputZodLike<TInput>;
|
|
14
|
-
self?: EventResolver<TPlatform, TAuthorize, TContext, TInput, Partial<TOutput>> | null;
|
|
15
|
-
sync?: EventResolver<TPlatform, TAuthorize, TContext, TInput, Partial<TOutput>> | null;
|
|
14
|
+
self?: EventResolver<"self", TPlatform, TAuthorize, TContext, TInput, Partial<TOutput>> | null;
|
|
15
|
+
sync?: EventResolver<"sync", TPlatform, TAuthorize, TContext, TInput, Partial<TOutput>> | null;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
export class PluvProcedure<
|
|
@@ -23,10 +23,11 @@ export class PluvProcedure<
|
|
|
23
23
|
TOutput extends EventRecord<string, any> = {},
|
|
24
24
|
TFilled extends "input" | "broadcast" | "self" | "sync" | "" = "",
|
|
25
25
|
> {
|
|
26
|
-
private _broadcast: EventResolver<TPlatform, TAuthorize, TContext, TInput, Partial<TOutput>> | null =
|
|
26
|
+
private _broadcast: EventResolver<"broadcast", TPlatform, TAuthorize, TContext, TInput, Partial<TOutput>> | null =
|
|
27
|
+
null;
|
|
27
28
|
private _input: InputZodLike<TInput> | null = null;
|
|
28
|
-
private _self: EventResolver<TPlatform, TAuthorize, TContext, TInput, Partial<TOutput>> | null = null;
|
|
29
|
-
private _sync: EventResolver<TPlatform, TAuthorize, TContext, TInput, Partial<TOutput>> | null = null;
|
|
29
|
+
private _self: EventResolver<"self", TPlatform, TAuthorize, TContext, TInput, Partial<TOutput>> | null = null;
|
|
30
|
+
private _sync: EventResolver<"sync", TPlatform, TAuthorize, TContext, TInput, Partial<TOutput>> | null = null;
|
|
30
31
|
|
|
31
32
|
public get config(): ProcedureLike<TInput, TOutput>["config"] {
|
|
32
33
|
return {
|
|
@@ -48,7 +49,7 @@ export class PluvProcedure<
|
|
|
48
49
|
}
|
|
49
50
|
|
|
50
51
|
public broadcast<TResult extends EventRecord<string, any> = {}>(
|
|
51
|
-
resolver: EventResolver<TPlatform, TAuthorize, TContext, TInput, TResult>,
|
|
52
|
+
resolver: EventResolver<"broadcast", TPlatform, TAuthorize, TContext, TInput, TResult>,
|
|
52
53
|
): Omit<
|
|
53
54
|
PluvProcedure<
|
|
54
55
|
TPlatform,
|
|
@@ -84,7 +85,7 @@ export class PluvProcedure<
|
|
|
84
85
|
}
|
|
85
86
|
|
|
86
87
|
public self<TResult extends EventRecord<string, any> = {}>(
|
|
87
|
-
resolver: EventResolver<TPlatform, TAuthorize, TContext, TInput, TResult>,
|
|
88
|
+
resolver: EventResolver<"self", TPlatform, TAuthorize, TContext, TInput, TResult>,
|
|
88
89
|
): Omit<
|
|
89
90
|
PluvProcedure<
|
|
90
91
|
TPlatform,
|
|
@@ -114,7 +115,7 @@ export class PluvProcedure<
|
|
|
114
115
|
}
|
|
115
116
|
|
|
116
117
|
public sync<TResult extends EventRecord<string, any> = {}>(
|
|
117
|
-
resolver: EventResolver<TPlatform, TAuthorize, TContext, TInput, TResult>,
|
|
118
|
+
resolver: EventResolver<"sync", TPlatform, TAuthorize, TContext, TInput, TResult>,
|
|
118
119
|
): Omit<
|
|
119
120
|
PluvProcedure<
|
|
120
121
|
TPlatform,
|
|
@@ -143,7 +144,7 @@ export class PluvProcedure<
|
|
|
143
144
|
});
|
|
144
145
|
}
|
|
145
146
|
|
|
146
|
-
private _resolver(): EventResolver<TPlatform, TAuthorize, TContext, TInput, TOutput> {
|
|
147
|
+
private _resolver(): EventResolver<EventResolverKind, TPlatform, TAuthorize, TContext, TInput, TOutput> {
|
|
147
148
|
return (data, context) => {
|
|
148
149
|
return {
|
|
149
150
|
...this._broadcast?.(data, context),
|
package/src/PluvRouter.ts
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { IORouterLike } from "@pluv/types";
|
|
2
2
|
import type { AbstractPlatform, InferInitContextType } from "./AbstractPlatform";
|
|
3
3
|
import type { PluvProcedure } from "./PluvProcedure";
|
|
4
|
+
import type { PluvIOAuthorize } from "./types";
|
|
4
5
|
|
|
5
6
|
export type PluvRouterEventConfig<
|
|
6
7
|
TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>,
|
|
7
|
-
TAuthorize extends
|
|
8
|
+
TAuthorize extends PluvIOAuthorize<TPlatform, any, any, InferInitContextType<TPlatform>> = any,
|
|
8
9
|
TContext extends Record<string, any> = {},
|
|
9
10
|
> = { [P: string]: Pick<PluvProcedure<TPlatform, TAuthorize, TContext, any, any>, "config"> };
|
|
10
11
|
|
|
11
12
|
export type MergedRouter<
|
|
12
13
|
TRouters extends PluvRouter<TPlatform, TAuthorize, TContext, any>[] = [],
|
|
13
14
|
TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>,
|
|
14
|
-
TAuthorize extends
|
|
15
|
+
TAuthorize extends PluvIOAuthorize<TPlatform, any, any, InferInitContextType<TPlatform>> = any,
|
|
15
16
|
TContext extends Record<string, any> = {},
|
|
16
17
|
TRoot extends TRouters[0]["_defs"]["events"] = {},
|
|
17
18
|
> = TRouters extends [
|
|
@@ -23,7 +24,7 @@ export type MergedRouter<
|
|
|
23
24
|
|
|
24
25
|
export class PluvRouter<
|
|
25
26
|
TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>,
|
|
26
|
-
TAuthorize extends
|
|
27
|
+
TAuthorize extends PluvIOAuthorize<TPlatform, any, any, InferInitContextType<TPlatform>> = any,
|
|
27
28
|
TContext extends Record<string, any> = {},
|
|
28
29
|
TEvents extends PluvRouterEventConfig<TPlatform, TAuthorize, TContext> = {},
|
|
29
30
|
> implements IORouterLike<TEvents>
|