@pluv/client 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
 
2
- > @pluv/client@0.7.0 build /home/runner/work/pluv/pluv/packages/client
2
+ > @pluv/client@0.8.0 build /home/runner/work/pluv/pluv/packages/client
3
3
  > tsup src/index.ts --format esm,cjs --dts
4
4
 
5
5
  CLI Building entry: src/index.ts
@@ -8,10 +8,10 @@
8
8
  CLI Target: es6
9
9
  ESM Build start
10
10
  CJS Build start
11
- ESM dist/index.mjs 34.72 KB
12
- ESM ⚡️ Build success in 138ms
13
- CJS dist/index.js 35.86 KB
14
- CJS ⚡️ Build success in 138ms
11
+ ESM dist/index.mjs 35.24 KB
12
+ ESM ⚡️ Build success in 95ms
13
+ CJS dist/index.js 36.38 KB
14
+ CJS ⚡️ Build success in 96ms
15
15
  DTS Build start
16
- DTS ⚡️ Build success in 5111ms
17
- DTS dist/index.d.ts 11.71 KB
16
+ DTS ⚡️ Build success in 4360ms
17
+ DTS dist/index.d.ts 11.75 KB
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @pluv/client
2
2
 
3
+ ## 0.8.0
4
+
5
+ ### Minor Changes
6
+
7
+ - fde89cf: added defaults to the client to align it with createPluvClient by default
8
+
9
+ ### Patch Changes
10
+
11
+ - 5bbfb98: fix not properly handling unauthorized checks
12
+ - b85a232: bumped dependencies
13
+ - Updated dependencies [b85a232]
14
+ - @pluv/crdt-yjs@0.3.8
15
+ - @pluv/types@0.2.0
16
+
3
17
  ## 0.7.0
4
18
 
5
19
  ### Minor Changes
package/dist/index.d.ts CHANGED
@@ -81,18 +81,18 @@ declare global {
81
81
  };
82
82
  };
83
83
  }
84
- type AuthEndpoint = string | ((room: string) => FetchOptions);
84
+ type AuthEndpoint = string | ((room: string) => string | FetchOptions) | true;
85
85
  type WsEndpoint = string | ((room: string) => string);
86
- type FetchOptions = string | {
86
+ type FetchOptions = {
87
87
  url: string;
88
88
  options?: RequestInit;
89
89
  };
90
90
  type RoomEndpoints<TIO extends IOLike> = {
91
- wsEndpoint: WsEndpoint;
91
+ wsEndpoint?: WsEndpoint;
92
92
  } & (InferIOAuthorizeRequired<InferIOAuthorize<TIO>> extends true ? {
93
93
  authEndpoint: AuthEndpoint;
94
94
  } : {
95
- authEndpoint?: AuthEndpoint;
95
+ authEndpoint?: undefined;
96
96
  });
97
97
  type PluvRoomDebug<TIO extends IOLike> = Id<{
98
98
  output: readonly (keyof InferIOOutput<TIO>)[];
@@ -144,6 +144,7 @@ declare class PluvRoom<TIO extends IOLike, TPresence extends JsonObject = {}, TS
144
144
  private _detachWindowListeners;
145
145
  private _detachWsListeners;
146
146
  private _getAuthorization;
147
+ private _getAuthFetchOptions;
147
148
  private _getWsEndpoint;
148
149
  private _handleExit;
149
150
  private _handlePresenceUpdatedMessage;
package/dist/index.js CHANGED
@@ -369,10 +369,7 @@ var PluvRoom = class extends AbstractRoom {
369
369
  );
370
370
  };
371
371
  this._debug = debug;
372
- this._endpoints = {
373
- authEndpoint,
374
- wsEndpoint
375
- };
372
+ this._endpoints = { authEndpoint, wsEndpoint };
376
373
  this._listeners = {
377
374
  onAuthorizationFail: (error) => {
378
375
  this._clearTimeout(this._timeouts.reconnect);
@@ -585,24 +582,50 @@ var PluvRoom = class extends AbstractRoom {
585
582
  }
586
583
  _getAuthorization(room) {
587
584
  return __async(this, null, function* () {
588
- if (!this._endpoints.authEndpoint)
585
+ const fetchOptions = this._getAuthFetchOptions(room);
586
+ if (!fetchOptions)
589
587
  return null;
590
- if (typeof this._endpoints.authEndpoint === "string") {
591
- const token2 = yield fetch(this._endpoints.authEndpoint).then((res) => res.text()).then((text2) => text2.trim());
592
- return token2;
588
+ const { url, options } = fetchOptions;
589
+ const res = yield fetch(url, options);
590
+ if (!res.ok || res.status !== 200) {
591
+ throw new Error("Room is unauthorized");
592
+ }
593
+ try {
594
+ return yield res.text().then((text2) => text2.trim());
595
+ } catch (err) {
596
+ throw new Error(
597
+ err instanceof Error ? err.message : "Room is unauthorized"
598
+ );
593
599
  }
594
- const config = this._endpoints.authEndpoint(room);
595
- const endpoint = typeof config === "string" ? config : config.url;
596
- const options = typeof config === "string" ? void 0 : config.options;
597
- const token = yield fetch(endpoint, options).then((res) => res.text()).then((text2) => text2.trim());
598
- return token;
599
600
  });
600
601
  }
602
+ _getAuthFetchOptions(room) {
603
+ if (typeof this._endpoints.authEndpoint === "undefined")
604
+ return null;
605
+ if (this._endpoints.authEndpoint === true) {
606
+ return {
607
+ url: `/api/pluv/authorize?room=${room}`,
608
+ options: {}
609
+ };
610
+ }
611
+ if (typeof this._endpoints.authEndpoint === "string") {
612
+ return {
613
+ url: this._endpoints.authEndpoint,
614
+ options: {}
615
+ };
616
+ }
617
+ const result = this._endpoints.authEndpoint(room);
618
+ return typeof result === "string" ? { url: result, options: {} } : result;
619
+ }
601
620
  _getWsEndpoint(room) {
602
- if (typeof this._endpoints.wsEndpoint === "string") {
603
- return this._endpoints.wsEndpoint;
621
+ switch (typeof this._endpoints.wsEndpoint) {
622
+ case "undefined":
623
+ return `/api/pluv/room/${room}`;
624
+ case "string":
625
+ return this._endpoints.wsEndpoint;
626
+ default:
627
+ return this._endpoints.wsEndpoint(room);
604
628
  }
605
- return this._endpoints.wsEndpoint(room);
606
629
  }
607
630
  _handleExit(message) {
608
631
  const { connectionId } = message;
package/dist/index.mjs CHANGED
@@ -344,10 +344,7 @@ var PluvRoom = class extends AbstractRoom {
344
344
  );
345
345
  };
346
346
  this._debug = debug;
347
- this._endpoints = {
348
- authEndpoint,
349
- wsEndpoint
350
- };
347
+ this._endpoints = { authEndpoint, wsEndpoint };
351
348
  this._listeners = {
352
349
  onAuthorizationFail: (error) => {
353
350
  this._clearTimeout(this._timeouts.reconnect);
@@ -560,24 +557,50 @@ var PluvRoom = class extends AbstractRoom {
560
557
  }
561
558
  _getAuthorization(room) {
562
559
  return __async(this, null, function* () {
563
- if (!this._endpoints.authEndpoint)
560
+ const fetchOptions = this._getAuthFetchOptions(room);
561
+ if (!fetchOptions)
564
562
  return null;
565
- if (typeof this._endpoints.authEndpoint === "string") {
566
- const token2 = yield fetch(this._endpoints.authEndpoint).then((res) => res.text()).then((text2) => text2.trim());
567
- return token2;
563
+ const { url, options } = fetchOptions;
564
+ const res = yield fetch(url, options);
565
+ if (!res.ok || res.status !== 200) {
566
+ throw new Error("Room is unauthorized");
567
+ }
568
+ try {
569
+ return yield res.text().then((text2) => text2.trim());
570
+ } catch (err) {
571
+ throw new Error(
572
+ err instanceof Error ? err.message : "Room is unauthorized"
573
+ );
568
574
  }
569
- const config = this._endpoints.authEndpoint(room);
570
- const endpoint = typeof config === "string" ? config : config.url;
571
- const options = typeof config === "string" ? void 0 : config.options;
572
- const token = yield fetch(endpoint, options).then((res) => res.text()).then((text2) => text2.trim());
573
- return token;
574
575
  });
575
576
  }
577
+ _getAuthFetchOptions(room) {
578
+ if (typeof this._endpoints.authEndpoint === "undefined")
579
+ return null;
580
+ if (this._endpoints.authEndpoint === true) {
581
+ return {
582
+ url: `/api/pluv/authorize?room=${room}`,
583
+ options: {}
584
+ };
585
+ }
586
+ if (typeof this._endpoints.authEndpoint === "string") {
587
+ return {
588
+ url: this._endpoints.authEndpoint,
589
+ options: {}
590
+ };
591
+ }
592
+ const result = this._endpoints.authEndpoint(room);
593
+ return typeof result === "string" ? { url: result, options: {} } : result;
594
+ }
576
595
  _getWsEndpoint(room) {
577
- if (typeof this._endpoints.wsEndpoint === "string") {
578
- return this._endpoints.wsEndpoint;
596
+ switch (typeof this._endpoints.wsEndpoint) {
597
+ case "undefined":
598
+ return `/api/pluv/room/${room}`;
599
+ case "string":
600
+ return this._endpoints.wsEndpoint;
601
+ default:
602
+ return this._endpoints.wsEndpoint(room);
579
603
  }
580
- return this._endpoints.wsEndpoint(room);
581
604
  }
582
605
  _handleExit(message) {
583
606
  const { connectionId } = message;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pluv/client",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "description": "@pluv/io frontend client",
5
5
  "author": "leedavidcs",
6
6
  "license": "MIT",
@@ -18,7 +18,7 @@
18
18
  },
19
19
  "dependencies": {
20
20
  "wonka": "^6.3.2",
21
- "@pluv/crdt-yjs": "^0.3.7",
21
+ "@pluv/crdt-yjs": "^0.3.8",
22
22
  "@pluv/types": "^0.2.0"
23
23
  },
24
24
  "peerDependencies": {
@@ -27,9 +27,9 @@
27
27
  "devDependencies": {
28
28
  "tsup": "^6.7.0",
29
29
  "typescript": "^5.0.4",
30
- "yjs": "^13.6.0",
30
+ "yjs": "^13.6.1",
31
31
  "@pluv/tsconfig": "^0.1.6",
32
- "eslint-config-pluv": "^0.1.11"
32
+ "eslint-config-pluv": "^0.1.12"
33
33
  },
34
34
  "scripts": {
35
35
  "build": "tsup src/index.ts --format esm,cjs --dts",
package/src/PluvClient.ts CHANGED
@@ -5,6 +5,7 @@ import type {
5
5
  RoomEndpoints,
6
6
  PluvRoomOptions,
7
7
  WsEndpoint,
8
+ RoomConfig,
8
9
  } from "./PluvRoom";
9
10
  import { PluvRoom } from "./PluvRoom";
10
11
 
@@ -13,9 +14,9 @@ export type PluvClientOptions<TIO extends IOLike> = RoomEndpoints<TIO> & {
13
14
  };
14
15
 
15
16
  export class PluvClient<TIO extends IOLike = IOLike> {
16
- private _authEndpoint: AuthEndpoint;
17
+ private _authEndpoint: AuthEndpoint | undefined;
17
18
  private _debug: boolean;
18
- private _wsEndpoint: WsEndpoint;
19
+ private _wsEndpoint: WsEndpoint | undefined;
19
20
 
20
21
  private _rooms = new Map<string, PluvRoom<TIO, any, any>>();
21
22
 
@@ -45,7 +46,7 @@ export class PluvClient<TIO extends IOLike = IOLike> {
45
46
  initialStorage: options.initialStorage,
46
47
  onAuthorizationFail: options.onAuthorizationFail,
47
48
  wsEndpoint: this._wsEndpoint,
48
- });
49
+ } as RoomConfig<TIO, TPresence, TStorage>);
49
50
 
50
51
  this._rooms.set(room, newRoom);
51
52
 
package/src/PluvRoom.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { doc, InferYjsSharedTypeJson } from "@pluv/crdt-yjs";
1
+ import { InferYjsSharedTypeJson } from "@pluv/crdt-yjs";
2
2
  import type {
3
3
  BaseIOEventRecord,
4
4
  EventMessage,
@@ -70,21 +70,19 @@ interface TimeoutIds {
70
70
  reconnect: number | null;
71
71
  }
72
72
 
73
- export type AuthEndpoint = string | ((room: string) => FetchOptions);
73
+ export type AuthEndpoint =
74
+ | string
75
+ | ((room: string) => string | FetchOptions)
76
+ | true;
74
77
  export type WsEndpoint = string | ((room: string) => string);
75
78
 
76
- export interface RoomConfigOptions {
77
- authEndpoint?: AuthEndpoint;
78
- wsEndpoint: WsEndpoint;
79
- }
80
-
81
- type FetchOptions = string | { url: string; options?: RequestInit };
79
+ type FetchOptions = { url: string; options?: RequestInit };
82
80
 
83
81
  export type RoomEndpoints<TIO extends IOLike> = {
84
- wsEndpoint: WsEndpoint;
82
+ wsEndpoint?: WsEndpoint;
85
83
  } & (InferIOAuthorizeRequired<InferIOAuthorize<TIO>> extends true
86
84
  ? { authEndpoint: AuthEndpoint }
87
- : { authEndpoint?: AuthEndpoint });
85
+ : { authEndpoint?: undefined });
88
86
 
89
87
  interface InternalListeners {
90
88
  onAuthorizationFail: (error: Error) => void;
@@ -167,12 +165,7 @@ export class PluvRoom<
167
165
 
168
166
  this._debug = debug;
169
167
 
170
- this._endpoints = {
171
- authEndpoint: authEndpoint as
172
- | string
173
- | ((room: string) => FetchOptions),
174
- wsEndpoint,
175
- };
168
+ this._endpoints = { authEndpoint, wsEndpoint } as RoomEndpoints<TIO>;
176
169
 
177
170
  this._listeners = {
178
171
  onAuthorizationFail: (error) => {
@@ -494,33 +487,60 @@ export class PluvRoom<
494
487
  }
495
488
 
496
489
  private async _getAuthorization(room: string): Promise<string | null> {
497
- if (!this._endpoints.authEndpoint) return null;
490
+ const fetchOptions = this._getAuthFetchOptions(room);
498
491
 
499
- if (typeof this._endpoints.authEndpoint === "string") {
500
- const token = await fetch(this._endpoints.authEndpoint)
501
- .then((res) => res.text())
502
- .then((text) => text.trim());
492
+ if (!fetchOptions) return null;
493
+
494
+ const { url, options } = fetchOptions;
495
+
496
+ const res = await fetch(url, options);
497
+
498
+ if (!res.ok || res.status !== 200) {
499
+ throw new Error("Room is unauthorized");
500
+ }
501
+
502
+ try {
503
+ return await res.text().then((text) => text.trim());
504
+ } catch (err) {
505
+ throw new Error(
506
+ err instanceof Error ? err.message : "Room is unauthorized"
507
+ );
508
+ }
509
+ }
503
510
 
504
- return token;
511
+ private _getAuthFetchOptions(room: string): FetchOptions | null {
512
+ if (typeof this._endpoints.authEndpoint === "undefined") return null;
513
+
514
+ if (this._endpoints.authEndpoint === true) {
515
+ return {
516
+ url: `/api/pluv/authorize?room=${room}`,
517
+ options: {},
518
+ };
505
519
  }
506
520
 
507
- const config = this._endpoints.authEndpoint(room);
508
- const endpoint = typeof config === "string" ? config : config.url;
509
- const options = typeof config === "string" ? undefined : config.options;
521
+ if (typeof this._endpoints.authEndpoint === "string") {
522
+ return {
523
+ url: this._endpoints.authEndpoint,
524
+ options: {},
525
+ };
526
+ }
510
527
 
511
- const token = await fetch(endpoint, options)
512
- .then((res) => res.text())
513
- .then((text) => text.trim());
528
+ const result = this._endpoints.authEndpoint(room);
514
529
 
515
- return token;
530
+ return typeof result === "string"
531
+ ? { url: result, options: {} }
532
+ : result;
516
533
  }
517
534
 
518
535
  private _getWsEndpoint(room: string): string {
519
- if (typeof this._endpoints.wsEndpoint === "string") {
520
- return this._endpoints.wsEndpoint;
536
+ switch (typeof this._endpoints.wsEndpoint) {
537
+ case "undefined":
538
+ return `/api/pluv/room/${room}`;
539
+ case "string":
540
+ return this._endpoints.wsEndpoint;
541
+ default:
542
+ return this._endpoints.wsEndpoint(room);
521
543
  }
522
-
523
- return this._endpoints.wsEndpoint(room);
524
544
  }
525
545
 
526
546
  private _handleExit(message: IOEventMessage<TIO>): void {